!# This source file is part of code Pégase.3.0.1 (2019-02-21).
!# Copyright: Michel Fioc (Michel.Fioc@iap.fr), Sorbonne université, 
!# Institut d'astrophysique de Paris/CNRS, France.
!# 
!# Pégase.3.0.1 is governed by the CeCILL license under French law and abides 
!# by the rules of distribution of free software. You can use, modify and/or 
!# redistribute this software under the terms of the CeCILL license as circulated 
!# by CEA, CNRS and INRIA at "http://www.cecill.info". The text of this license
!# is also available in French and in English in directory "doc_dir/" of this
!# code.
!# 
!# As a counterpart to the access to the source code and to the rights to copy,
!# modify and redistribute it granted by the license, users are provided only
!# with a limited warranty, and the software's author, the holder of the
!# economic rights, and the successive licensors have only limited
!# liability. 
!# 
!# The fact that you are presently reading this means that you have had
!# knowledge of the CeCILL license and that you accept its terms.
!#====================================================================== 

module mod_initialization
  
  private
  public :: initialization

contains

!#======================================================================
  
  subroutine initialization(reserv_abund, &
       ISM_abund, galaxy_init_mass, reserv_init_mass_scaled, ISM_init_mass, BHNS_init_mass, &
       WD_init_mass, inert_init_mass, carb_init_abund, sil_init_abund, ISM_elem_init_mass, &
       carb_init_mass, sil_init_mass, abund_sol, elem_sol, Z_sol, dY_over_dZ, &
       SF_warn_present, infall_warn_present, outflow_warn_present, &
       reserv_warn_present)
    
    use mod_constants, only : Y_prim, Z_prim, elem_id
    use mod_loc, only : i_loc
    use mod_scenario
    
    implicit none
    real(CDR), dimension(:, 0:), intent(inout) :: ISM_abund !# ??? `0:` necessary?
    real(CDR), dimension(:,0:), intent(out) :: reserv_abund !# ??? `0:` necessary?
    real(DPR), dimension(:), intent(in) :: abund_sol
    character(len=*), dimension(:), intent(in) :: elem_sol
    real(CDR), intent(in) :: Z_sol, dY_over_dZ    
    real(CDR), intent(out) :: galaxy_init_mass, ISM_init_mass, BHNS_init_mass, WD_init_mass, &
         inert_init_mass, carb_init_abund, sil_init_abund
    real(CDR), dimension(:), intent(out) ::  reserv_init_mass_scaled
    real(CDR), intent(out) :: carb_init_mass, sil_init_mass
    real(CDR), dimension(0:), intent(out) :: ISM_elem_init_mass !# ??? `0:` necessary?
    logical, intent(out) :: SF_warn_present, &
         outflow_warn_present, reserv_warn_present
    logical, dimension(:), intent(out) :: infall_warn_present
!#......................................................................
    real(CDR) :: abund_ratio
    integer ::  i_Z, i_O, i_C, i_Fe, i_He, i_N, i_Ne, i_Mg, i_Si, i_S, i_Ca
    integer :: i_reserv
    integer, parameter :: init_step = 1
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    i_Z = i_loc(elem_id, "Z")
    i_O = i_loc(elem_id, "O")
    i_C = i_loc(elem_id, "C")
    i_Fe = i_loc(elem_id, "Fe")
    i_He = i_loc(elem_id, "He")
    i_N = i_loc(elem_id, "N")
    i_Ne = i_loc(elem_id, "Ne")
    i_Mg = i_loc(elem_id, "Mg")
    i_Si = i_loc(elem_id, "Si")
    i_S = i_loc(elem_id, "S")
    i_Ca = i_loc(elem_id, "Ca")
    
    do i_reserv = 1, max_dim_reserv
       reserv_init_mass_scaled(i_reserv) = reserv_init_mass(i_reserv)
       reserv_abund(i_reserv, i_Z) = reserv_Z(i_reserv)
    end do
    galaxy_init_mass = 1 - sum(reserv_init_mass(:))
    reserv_warn_present = .false.
    if (galaxy_init_mass < 0) then
       galaxy_init_mass = 0
       reserv_init_mass_scaled(:) = reserv_init_mass(:)/sum(reserv_init_mass(:))
       reserv_warn_present = .true.
    endif
    ISM_init_mass = galaxy_init_mass
    ISM_abund(init_step,i_Z) = ISM_init_Z

!# Oxygen.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "16O" .or. elem_sol == "17O" .or. elem_sol == "18O" &
         )/Z_sol
    ISM_abund(init_step,i_O) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_O) = reserv_abund(:,i_Z) * abund_ratio

!# Carbon.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "12C" .or. elem_sol == "13C" .or. elem_sol == "14C" &
         )/Z_sol
    ISM_abund(init_step,i_C) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_C) = reserv_abund(:,i_Z) * abund_ratio

!# Iron.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "54Fe" .or. elem_sol == "56Fe" .or. elem_sol == "57Fe" &
         .or.  elem_sol == "58Fe" &
         )/Z_sol
    ISM_abund(init_step,i_Fe) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_Fe) = reserv_abund(:,i_Z) * abund_ratio

!# Helium.
    ISM_abund(init_step,i_He) = Y_prim + dY_over_dZ*(ISM_abund(init_step,i_Z)-Z_prim)
    reserv_abund(:,i_He) = Y_prim + dY_over_dZ*(reserv_abund(:,i_Z)-Z_prim)

!# Nitrogen.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "14N" .or. elem_sol == "15N" &
         )/Z_sol
    ISM_abund(init_step,i_N) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_N) = reserv_abund(:,i_Z) * abund_ratio

!# Neon.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "20Ne" .or. elem_sol == "21Ne" .or. elem_sol == "22Ne" &
         )/Z_sol
    ISM_abund(init_step,i_Ne) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_Ne) = reserv_abund(:,i_Z) * abund_ratio

!# Magnesium.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "24Mg" .or. elem_sol == "25Mg" .or. elem_sol == "26Mg" &
         )/Z_sol
    ISM_abund(init_step,i_Mg) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_Mg) = reserv_abund(:,i_Z) * abund_ratio

!# Silicon.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "28Si" .or. elem_sol == "29Si" .or. elem_sol == "30Si" &
         )/Z_sol
    ISM_abund(init_step,i_Si) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_Si) = reserv_abund(:,i_Z) * abund_ratio

!# Sulfur.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "32S" .or.  elem_sol == "33S" .or.  elem_sol == "34S" &
         .or.  elem_sol == "36S" &
         )/Z_sol
    ISM_abund(init_step,i_S) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_S) = reserv_abund(:,i_Z) * abund_ratio

!# Calcium.
    abund_ratio = sum(abund_sol, &
         mask = elem_sol == "40Ca" .or. elem_sol == "42Ca" .or. elem_sol == "43Ca" &
         .or. elem_sol == "44Ca" .or. elem_sol == "46Ca" .or. elem_sol == "48Ca" &
         )/Z_sol
    ISM_abund(init_step,i_Ca) = ISM_abund(init_step,i_Z) * abund_ratio
    reserv_abund(:,i_Ca) = reserv_abund(:,i_Z) * abund_ratio

    ISM_elem_init_mass(:) = ISM_init_mass*ISM_abund(init_step,:)
    BHNS_init_mass = 0
    WD_init_mass = 0
    SF_warn_present = .false.
    infall_warn_present(:) = .false.
    outflow_warn_present = .false.
    inert_init_mass = 0

    if (dust_evolution == "Dwek") then
       carb_init_mass = 0
       sil_init_mass = 0
       carb_init_abund = 0
       sil_init_abund = 0
    endif

  end subroutine initialization
  
end module mod_initialization
