MODULE icosa_init_mod

   IMPLICIT NONE
   PRIVATE

   PUBLIC :: icosa_init

CONTAINS

   SUBROUTINE icosa_init
      USE profiling_mod, ONLY: init_profiling
      USE mpipara, ONLY: is_mpi_master, is_mpi_root, mpi_rank, init_mpipara, finalize_mpipara
      USE signature_mod, ONLY: print_signature
      USE trace, ONLY: trace_off, init_trace
      USE xios_mod, ONLY: xios_init
      USE earth_const, ONLY: init_earth_const
      USE init_grid_param_mod, ONLY: init_grid_param
      USE omp_para, ONLY: init_omp_para, switch_omp_no_distrib_level
      USE metric, ONLY: init_metric
      USE domain_mod, ONLY: compute_domain
      USE transfert_mod, ONLY: init_transfert
      USE write_field_mod, ONLY: init_writefield, writefield, close_files
      USE read_metric_mod, ONLY: read_metric
      USE compute_geometry_mod, ONLY: compute_geometry
      USE disvert_mod, ONLY: init_disvert, write_apbp
      USE vertical_interp_mod, ONLY: init_vertical_interp
      USE tracer_icosa_mod, ONLY: init_tracer
      USE geometry, ONLY: geom
      USE time_mod, ONLY: init_time, close_time_counter
      USE etat0_mod, ONLY: init_etat0
      USE caldyn_mod, ONLY: init_caldyn
      USE restart_mod, ONLY: init_restart
      USE output_field_mod, ONLY: output_field_init, output_field_finalize
      USE timeloop_gcm_mod, ONLY: init_timeloop, timeloop
      USE physics_mod, ONLY: init_physics, zero_du_phys
      USE diagflux_mod, ONLY: init_diagflux
      USE grid_param, ONLY: grid_type, grid_ico

      CALL init_profiling
      CALL init_mpipara
      IF (is_mpi_master) CALL print_signature
      CALL trace_off
      CALL xios_init
      CALL init_earth_const
      CALL init_grid_param(is_mpi_master, mpi_rank) ! sets max_primal_deg, etc.
      CALL init_omp_para(is_mpi_master)
      IF (grid_type == grid_ico) CALL init_metric
      CALL compute_domain ! allocates domain_glo(ndomain_glo), domain(ndomain)
      CALL init_transfert

      CALL init_writefield
      CALL init_trace

      !$OMP PARALLEL
      CALL switch_omp_no_distrib_level

      IF (grid_type == grid_ico) CALL read_metric
      CALL compute_geometry

      IF (grid_type == grid_ico) CALL check_total_area

      CALL init_disvert
      CALL init_vertical_interp
      CALL init_tracer

      CALL WriteField("Ai", geom%Ai)

      IF (is_mpi_root) CALL write_apbp
      CALL init_time
      CALL init_etat0
      CALL init_caldyn
      CALL init_restart
      CALL output_field_init
      CALL init_timeloop

      !$OMP END PARALLEL

      CALL init_physics

      !$OMP PARALLEL

      CALL init_diagflux
      CALL zero_du_phys

      CALL timeloop

      CALL switch_omp_no_distrib_level
      !$OMP END PARALLEL

      CALL output_field_finalize
      CALL close_files
      CALL close_time_counter
      CALL finalize_mpipara

   END SUBROUTINE icosa_init

   SUBROUTINE check_total_area
      USE prec, ONLY: rstd
      USE domain_mod, ONLY: ndomain, domain
      USE geometry, ONLY: swap_geometry, Ai, ne
      USE mpipara, ONLY: is_mpi_root
      USE dimensions
      USE field_mod
      USE domain_param
      USE omp_para
      USE icosa

      TYPE(t_field), POINTER, SAVE :: sum_ne(:)
      REAL(rstd), POINTER          :: pt_sum_ne(:)
      INTEGER :: ind, i, j, k, n
      REAL(rstd) :: tot_sum = 0

      CALL allocate_field(sum_ne, field_T, type_real)

      !$OMP BARRIER
      !$OMP MASTER
      DO ind = 1, ndomain

         pt_sum_ne = sum_ne(ind)

         CALL swap_dimensions(ind)
         CALL swap_geometry(ind)

         DO j = jj_begin, jj_end
            DO i = ii_begin, ii_end
               n = (j - 1)*iim + i
               pt_sum_ne(n) = 0
               DO k = 1, 6
                  pt_sum_ne(n) = pt_sum_ne(n) + ne(n, k)
               END DO
               IF (domain(ind)%own(i, j)) tot_sum = tot_sum + Ai(n)
            END DO
         END DO
      END DO

      IF (is_mpi_root) PRINT *, " Diff surf", 1 - tot_sum/(4*Pi*radius*radius)
      !$OMP END MASTER

   END SUBROUTINE check_total_area

   SUBROUTINE force_recompile_unstructured
      USE timestep_unstructured_mod
      USE transport_unstructured_mod
   END SUBROUTINE force_recompile_unstructured

END MODULE icosa_init_mod
