submodule_bns_fuka_constructor.f90 Source File


This file depends on

sourcefile~~submodule_bns_fuka_constructor.f90~~EfferentGraph sourcefile~submodule_bns_fuka_constructor.f90 submodule_bns_fuka_constructor.f90 sourcefile~module_bns_fuka.f90 module_bns_fuka.f90 sourcefile~submodule_bns_fuka_constructor.f90->sourcefile~module_bns_fuka.f90 sourcefile~module_utility.f90 module_utility.f90 sourcefile~submodule_bns_fuka_constructor.f90->sourcefile~module_utility.f90 sourcefile~module_bns_fuka.f90->sourcefile~module_utility.f90 sourcefile~module_bns_base.f90 module_bns_base.f90 sourcefile~module_bns_fuka.f90->sourcefile~module_bns_base.f90 sourcefile~module_id_base.f90 module_id_base.f90 sourcefile~module_bns_fuka.f90->sourcefile~module_id_base.f90 sourcefile~module_bns_base.f90->sourcefile~module_utility.f90 sourcefile~module_bns_base.f90->sourcefile~module_id_base.f90 sourcefile~module_id_base.f90->sourcefile~module_utility.f90

Contents


Source Code

! File:         submodule_bnsfuka_constructor.f90
! Authors:      Francesco Torsello (FT)
!************************************************************************
! Copyright (C) 2020-2023 Francesco Torsello                            *
!                                                                       *
! This file is part of SPHINCS_ID                                       *
!                                                                       *
! SPHINCS_ID is free software: you can redistribute it and/or modify    *
! it under the terms of the GNU General Public License as published by  *
! the Free Software Foundation, either version 3 of the License, or     *
! (at your option) any later version.                                   *
!                                                                       *
! SPHINCS_ID is distributed in the hope that it will be useful,         *
! but WITHOUT ANY WARRANTY; without even the implied warranty of        *
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
! GNU General Public License for more details.                          *
!                                                                       *
! You should have received a copy of the GNU General Public License     *
! along with SPHINCS_ID. If not, see <https://www.gnu.org/licenses/>.   *
! The copy of the GNU General Public License should be in the file      *
! 'COPYING'.                                                            *
!************************************************************************

SUBMODULE (bns_fuka) constructor

  !*********************************************************
  !
  !# Implementation of the constructor and
  !  destructor of TYPE [[bnsfuka]], and of the
  !  [[bnsfuka]]-member
  !  PROCEDURES that call the C-bound PROCEDURES
  !  constructig and destructing the |fuka|
  !  |bnsexp| object
  !
  !  FT 23.10.2020
  !
  !*********************************************************


  IMPLICIT NONE


  CONTAINS


  !
  !-- Implementation of the constructor of the bns object
  !
  MODULE PROCEDURE construct_bnsfuka

    !****************************************************
    !
    !# Constructs an object of TYPE [[bnsfuka]]
    !
    !  Created:     FT 09.02.2022
    !  Last update: FT 27.05.2022
    !
    !****************************************************

    USE utility,  ONLY: ten, Msun_geo, flag$tpo

    IMPLICIT NONE

    INTEGER, SAVE:: bns_counter= 1

    DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE:: length_scale_pressure


    IF(max$tpo < flag$tpo)THEN
      PRINT *, "** ERROR in MODULE bns_fuka! It must hold max$tpo > flag$tpo,",&
               "where both variables are negative integers. Instead:"
      PRINT *, " * max$tpo=", max$tpo
      PRINT *, " * flag$tpo=", flag$tpo
      PRINT *, " * Stopping..."
      PRINT *
      STOP
    ENDIF

    CALL derived_type% set_n_matter(2)
    CALL derived_type% set_cold_system(.TRUE.)

    derived_type% construction_timer= timer("binary_construction_timer")

    ! Construct |fuka| |bnsexp| object
    CALL derived_type% construct_binary(filename)
    derived_type% filename= filename

    ! Read the properties of the binary system
    CALL read_bns_properties(derived_type)

    ! Assign a unique identifier to the bns_fuka object
    derived_type% bns_identifier= bns_counter
    bns_counter= bns_counter + 1

    ! Do not use the geodesic gauge by default
    CALL derived_type% set_one_lapse (.FALSE.)
    CALL derived_type% set_zero_shift(.FALSE.)

    ! Compute typical length scales of the system using the pressure
    IF( derived_type% get_estimate_length_scale() )THEN

      ALLOCATE( length_scale_pressure(derived_type% get_n_matter()) )
      length_scale_pressure= derived_type% estimate_lengthscale_field( &
                                                get_pressure, &
                                                derived_type% get_n_matter() )

      PRINT *, " * Minimum length scale to resolve on star 1, based on ", &
               "pressure= ", length_scale_pressure(1)*Msun_geo*ten*ten*ten, "m"
      PRINT *, " * Minimum length scale to resolve on star 2, based on ", &
               "pressure= ", length_scale_pressure(1)*Msun_geo*ten*ten*ten, "m"
      PRINT *

    ENDIF

    ! Assign PROCEDURE POINTER to the desired PROCEDURE
    derived_type% finalize_sph_id_ptr => finalize

    CONTAINS

    FUNCTION get_pressure( x, y, z ) RESULT( val )
    !! Returns the value of the pressure at the desired point

      DOUBLE PRECISION, INTENT(IN):: x
      !! \(x\) coordinate of the desired point
      DOUBLE PRECISION, INTENT(IN):: y
      !! \(y\) coordinate of the desired point
      DOUBLE PRECISION, INTENT(IN):: z
      !! \(z\) coordinate of the desired point
      DOUBLE PRECISION:: val
      !! Pressure at \((x,y,z)\)

      val= derived_type% read_pressure( x, y, z )

    END FUNCTION get_pressure


  END PROCEDURE construct_bnsfuka


  MODULE PROCEDURE finalize

    !***********************************************
    !
    !# This SUBROUTINE is curretly just a placeholder.
    !  It could be used, for exmaple, to correct
    !  the ADM momentum at the end of the execution,
    !  or correct for residual eccentricity, etc.
    !
    !  @note Temporary implementation, to avoid warnings
    !        about unused variables.
    !
    !  FT 14.04.2022
    !
    !***********************************************

    IMPLICIT NONE

    pos  = pos
    nlrf = nlrf
    nu   = nu
    pr   = pr
    vel_u= vel_u
    theta= theta
    nstar= nstar
    u    = u

  END PROCEDURE finalize


  MODULE PROCEDURE initialize_id_bnsfuka

    !***********************************************
    !
    !# Initialize the |fuka| |bns| |id|.
    !
    !  - If `flag`= [[utility:flag$sph]], set up the
    !    lattices around the stars for the |bns|
    !    produced with |fuka|.
    !  - If `flag`= [[utility:flag$tpo]], allocate
    !    memory for the hydro grid functions.
    !  - If `flag` > 0, assign its value to [[bnsfuka:l_curr]].
    !  - If [[utility:flag$tpo]] < `flag` < 0,
    !    assign its value to [[bnsfuka:tpo_curr]].
    !
    !  FT 16.09.2022
    !
    !***********************************************

    USE utility,          ONLY: flag$sph, flag$tpo
    USE mesh_refinement,  ONLY: allocate_grid_function

    IMPLICIT NONE

    INTEGER, SAVE:: tpo_counter= 1
    !! Counts how many times the PROCEDURE construct_particles_idase is called

    INTEGER:: i

    CHARACTER(LEN= 3):: cnt_i
    CHARACTER(LEN= :), ALLOCATABLE:: name_mass_density
    CHARACTER(LEN= :), ALLOCATABLE:: name_specific_energy
    CHARACTER(LEN= :), ALLOCATABLE:: name_pressure
    CHARACTER(LEN= :), ALLOCATABLE:: name_v_euler_x
    CHARACTER(LEN= :), ALLOCATABLE:: name_v_euler_y
    CHARACTER(LEN= :), ALLOCATABLE:: name_v_euler_z

    LOGICAL:: wanted_tpo

    IF( PRESENT(switch) )THEN
      IF( switch .EQV. .TRUE. )THEN

        this% tpo$log(tpo_counter)= flag
        this% tpo_curr= tpo_counter

        tpo_counter= tpo_counter + 1

        CALL initialize_id_bnsfuka(this, flag$tpo)

      ENDIF
    ENDIF

    IF( flag /= flag$sph .AND. flag /= flag$tpo .AND. flag < -max$tpo )THEN

      PRINT *, "** ERROR in SUBROUTINE initialize_id_bnsfuka! The INTEGER ", &
               "argument 'flag' should be in the set [1,nlevels], or ", &
               "it should be equal to either flag$sph or flag$tpo, defined ", &
               "in MODULE utility."
      PRINT *, " * Stopping..."
      PRINT *
      STOP

    ENDIF

    IF( flag == flag$sph )THEN

      ! Since Kadath is not thread-safe, we cannot parallelize it using OMP
      ! within SPHINCS_ID. Hence, we chose to make a system call to a program
      ! within Kadath that reads the ID from the FUKA output file and prints it
      ! on a lattice. The ID on the particles will be interplated from this fine
      ! lattice.
      CALL this% set_up_lattices_around_stars()

      IF(ALLOCATED(this% surfaces)) DEALLOCATE(this% surfaces)

      !PRINT *, ALLOCATED(this% surfaces(1)% points)
      !PRINT *, ALLOCATED(this% surfaces(2)% points)

      ! Find the surfaces of the stars and print them to a formatted file
      CALL this% find_print_surfaces()

    ELSEIF( flag >= flag$tpo .AND. flag <= -1 )THEN

      wanted_tpo= .FALSE.
      DO i= 1, max$tpo, 1

        IF(this% tpo$log(i) == flag)THEN

          wanted_tpo= .TRUE.
          this% tpo_curr= i

        ENDIF

      ENDDO

      IF(flag == flag$tpo)THEN

        IF( this% tpo_curr <= 9 ) WRITE( cnt_i, "(I1)" ) this% tpo_curr
        IF( this% tpo_curr >= 10 .AND. flag <= 99 ) WRITE( cnt_i, "(I2)" ) &
          this% tpo_curr
        IF( this% tpo_curr >= 100 .AND. flag <= 999 ) WRITE( cnt_i, "(I3)" ) &
          this% tpo_curr

        !PRINT *
        !PRINT *, "cnt_i=", TRIM(cnt_i)
        !PRINT *

        name_mass_density   = "mass_density_fuka-"//TRIM(cnt_i)
        name_specific_energy= "specific_energy_fuka-"//TRIM(cnt_i)
        name_pressure       = "pressure_fuka-"//TRIM(cnt_i)
        name_v_euler_x      = "v_euler_x_fuka-"//TRIM(cnt_i)
        name_v_euler_y      = "v_euler_y_fuka-"//TRIM(cnt_i)
        name_v_euler_z      = "v_euler_z_fuka-"//TRIM(cnt_i)

        !PRINT *
        !PRINT *, "name_mass_density=", name_mass_density
        !PRINT *

        CALL allocate_grid_function( this% mass_density(this% tpo_curr), &
                                     TRIM(name_mass_density), 1 )
        CALL allocate_grid_function( this% specific_energy(this% tpo_curr), &
                                     TRIM(name_specific_energy), 1 )
        CALL allocate_grid_function( this% pressure(this% tpo_curr), &
                                     TRIM(name_pressure), 1 )
        CALL allocate_grid_function( this% v_euler_x(this% tpo_curr), &
                                     TRIM(name_v_euler_x), 1 )
        CALL allocate_grid_function( this% v_euler_y(this% tpo_curr), &
                                     TRIM(name_v_euler_y), 1 )
        CALL allocate_grid_function( this% v_euler_z(this% tpo_curr), &
                                     TRIM(name_v_euler_z), 1 )

      ELSE

        IF(.NOT.wanted_tpo)THEN
          PRINT *, "** ERROR! Mismatch between bns_fuka and bssn objects!"
          PRINT *, " * This should never happen: there is most likely a bug ", &
                   "in SUBROUTINE initialize_id_bnsfuka, or a bug in the ", &
                   "places where it is called."
          PRINT *, " * Stopping..."
          PRINT *
          STOP
        ENDIF

      ENDIF

    ELSE

      this% l_curr= flag

    ENDIF

  END PROCEDURE initialize_id_bnsfuka


  !
  !-- Implementation of the destructor of the bns object
  !
  MODULE PROCEDURE destruct_bnsfuka

    !***********************************************
    !
    !# Destructs an object of TYPE [[bnsfuka]]
    !
    !  Created:     FT 09.02.2022
    !  Last update: FT 30.06.2022
    !
    !***********************************************

    IMPLICIT NONE

    INTEGER:: i_star

    ! Deallocate memory
    CALL this% deallocate_bnsfuka_memory()
    DO i_star=1, 2, 1
      CALL this% star_lattice(i_star)% deallocate_lattice_memory()
    ENDDO

  END PROCEDURE destruct_bnsfuka


  MODULE PROCEDURE construct_binary

    !***********************************************
    !
    !# Construct the |fuka| |bnsexp| object
    !
    !  Created:     FT 09.02.2022
    !  Last update: FT 27.05.2022
    !
    !***********************************************

    IMPLICIT NONE

    LOGICAL:: exist

#ifdef __INTEL_COMPILER

    IF ( C_ASSOCIATED( this% bns_ptr ) ) THEN

      CALL destruct_bns_fuka( this% bns_ptr )

    ENDIF

#endif

    INQUIRE( FILE= fukafile, EXIST= exist )

    IF( exist )THEN

      CALL this% construction_timer% start_timer()
      this% bns_ptr = construct_bns_fuka( fukafile//C_NULL_CHAR )
      CALL this% construction_timer% stop_timer()

    ELSE

      PRINT *, "** ERROR in SUBROUTINE construct_binary: file ", &
               fukafile, " cannot be found!"
      PRINT *
      STOP

    ENDIF


  END PROCEDURE construct_binary


  MODULE PROCEDURE destruct_binary

    !************************************************
    !
    !# Destructs the |fuka| |bnsexp| object and frees
    !  the pointer [[bnsfuka:bns_ptr]] pointing to it
    !
    !  Created:     FT 09.02.2022
    !  Last update: FT 27.05.2022
    !
    !************************************************

    IMPLICIT NONE


    IF ( C_ASSOCIATED( this% bns_ptr ) ) THEN

      CALL destruct_bns_fuka( this% bns_ptr )
      this% bns_ptr = C_NULL_PTR

    ENDIF

  END PROCEDURE destruct_binary


END SUBMODULE constructor