immersed_m.f90 Source File


This file depends on

sourcefile~~immersed_m.f90~~EfferentGraph sourcefile~immersed_m.f90 immersed_m.f90 sourcefile~equilibrium_m.f90 equilibrium_m.f90 sourcefile~immersed_m.f90->sourcefile~equilibrium_m.f90 sourcefile~list_operations_m.f90 list_operations_m.f90 sourcefile~immersed_m.f90->sourcefile~list_operations_m.f90 sourcefile~mesh_cart_m.f90 mesh_cart_m.f90 sourcefile~immersed_m.f90->sourcefile~mesh_cart_m.f90 sourcefile~precision_m.f90 precision_m.f90 sourcefile~immersed_m.f90->sourcefile~precision_m.f90 sourcefile~equilibrium_m.f90->sourcefile~precision_m.f90 sourcefile~list_operations_m.f90->sourcefile~precision_m.f90 sourcefile~screen_io_m.f90 screen_io_m.f90 sourcefile~list_operations_m.f90->sourcefile~screen_io_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~equilibrium_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~precision_m.f90 sourcefile~comm_handling_m.f90 comm_handling_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~comm_handling_m.f90 sourcefile~descriptors_m.f90 descriptors_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~descriptors_m.f90 sourcefile~error_handling_m.f90 error_handling_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~error_handling_m.f90 sourcefile~slab_equilibrium.f90 slab_equilibrium.f90 sourcefile~mesh_cart_m.f90->sourcefile~slab_equilibrium.f90 sourcefile~status_codes_m.f90 status_codes_m.f90 sourcefile~mesh_cart_m.f90->sourcefile~status_codes_m.f90 sourcefile~descriptors_m.f90->sourcefile~screen_io_m.f90 sourcefile~error_handling_m.f90->sourcefile~precision_m.f90 sourcefile~error_handling_m.f90->sourcefile~comm_handling_m.f90 sourcefile~error_handling_m.f90->sourcefile~screen_io_m.f90 sourcefile~error_handling_m.f90->sourcefile~status_codes_m.f90 sourcefile~screen_io_m.f90->sourcefile~precision_m.f90 sourcefile~slab_equilibrium.f90->sourcefile~equilibrium_m.f90 sourcefile~slab_equilibrium.f90->sourcefile~precision_m.f90 sourcefile~slab_equilibrium.f90->sourcefile~descriptors_m.f90 sourcefile~slab_equilibrium.f90->sourcefile~screen_io_m.f90 sourcefile~params_equi_slab_m.f90 params_equi_slab_m.f90 sourcefile~slab_equilibrium.f90->sourcefile~params_equi_slab_m.f90 sourcefile~params_equi_slab_m.f90->sourcefile~precision_m.f90 sourcefile~params_equi_slab_m.f90->sourcefile~error_handling_m.f90 sourcefile~params_equi_slab_m.f90->sourcefile~screen_io_m.f90 sourcefile~params_equi_slab_m.f90->sourcefile~status_codes_m.f90

Files dependent on this one

sourcefile~~immersed_m.f90~~AfferentGraph sourcefile~immersed_m.f90 immersed_m.f90 sourcefile~immersed_factory_m.f90 immersed_factory_m.f90 sourcefile~immersed_factory_m.f90->sourcefile~immersed_m.f90 sourcefile~immersed_rho_m.f90 immersed_rho_m.f90 sourcefile~immersed_factory_m.f90->sourcefile~immersed_rho_m.f90 sourcefile~immersed_trace_m.f90 immersed_trace_m.f90 sourcefile~immersed_factory_m.f90->sourcefile~immersed_trace_m.f90 sourcefile~immersed_vessel_m.f90 immersed_vessel_m.f90 sourcefile~immersed_factory_m.f90->sourcefile~immersed_vessel_m.f90 sourcefile~immersed_netcdf_s.f90 immersed_netcdf_s.f90 sourcefile~immersed_netcdf_s.f90->sourcefile~immersed_m.f90 sourcefile~immersed_rho_m.f90->sourcefile~immersed_m.f90 sourcefile~immersed_trace_m.f90->sourcefile~immersed_m.f90 sourcefile~immersed_vessel_m.f90->sourcefile~immersed_m.f90

Source Code

module immersed_m
    !! Abstract immersed boundary module to set boundary conditions at targets
    use precision_m, only : FP, FP_EPS
    use equilibrium_m, only : equilibrium_t
    use mesh_cart_m, only : mesh_cart_t
    use list_operations_m, only : unique_tuples
    implicit none
    
    type, public, abstract :: immersed_t
        !! Abstract immersed boundary type
        real(FP), public, allocatable, dimension(:) :: charfun
        !! Characteristic function of immersed boundary,
        !! commonly referred chi
        real(FP), public, allocatable, dimension(:) :: dirindfun
        !! Function indicating direction of magnetic field 
        !! (towards/away from target), commonly referred xi
        integer, public, allocatable, dimension(:) :: inds
        !! Mesh indices which lie in immersed boundary region
        integer, public :: n_inds
        !! Size of inds
        integer, public, allocatable, dimension(:) :: adj_inds
        !! Mesh indices, which are adjacent to the immersed boundary region
        integer, public :: n_adj_inds
        !! Size of adj_inds
    contains
        procedure(init), public, deferred :: init
        procedure(display), public, deferred :: display
        procedure, public :: build_inds
        procedure, public :: build_adj_inds
        procedure, public :: write_netcdf => write_netcdf_immersed
        procedure, public :: read_netcdf => read_netcdf_immersed
    end type

    abstract interface
    
        subroutine init(self, equi, mesh, filename)
            !! Initialises the immersed boundary fields charfun and dirind,
            !! depending on specialised implementation
            import :: immersed_t
            import :: equilibrium_t
            import :: mesh_cart_t
            class(immersed_t), intent(inout) :: self
            !! Instance of type
            class(equilibrium_t), intent(inout) :: equi
            !! Equilibrium
            type(mesh_cart_t), intent(in) :: mesh
            !! Mesh
            character(len=*), intent(in), optional :: filename
            !! Filename, where to read parameters from, 
            !! if not provided default parameters will be used
        end subroutine

        subroutine display(self)
            !! Writes basic information of immersed boundary to stdout
            import :: immersed_t
            class(immersed_t), intent(in) :: self
            !! Instance of type
        end subroutine

    end interface

    interface

        module subroutine write_netcdf_immersed(self, fgid)
            !! Writes immersed boundary data to NetCDF id
            class(immersed_t), intent(in) :: self
            !! Instance of class
            integer, intent(in) :: fgid
            !! NetCDF file or group id
        end subroutine

        module subroutine read_netcdf_immersed(self, fgid)
            !! Reads immersed boundary data from NetCDF id
            class(immersed_t), intent(inout) :: self
            !! Instance of class
            integer, intent(in) :: fgid
            !! NetCDF file or group id
        end subroutine

    end interface

contains

        subroutine build_inds(self, mesh)
            !! Computes inds.
            !! The construction is common to all derived immersed types
            class(immersed_t), intent(inout) :: self
            !! Instance of type
            type(mesh_cart_t), intent(in) :: mesh
            !! Mesh

            integer :: l, ic

            ! Find mesh indices that have a finite immersed value
            self%n_inds = count(self%charfun > FP_EPS)
            allocate(self%inds(self%n_inds))
            ic  = 0
            do l = 1, mesh%get_n_points()
                if (self%charfun(l) > FP_EPS) then
                    ic = ic + 1
                    self%inds(ic) = l
                endif
            enddo

        end subroutine

        subroutine build_adj_inds(self, mesh)
            !! Computes adj_inds.
            !! The construction is common to all derived immersed types
            class(immersed_t), intent(inout) :: self
            !! Instance of type
            type(mesh_cart_t), intent(in) :: mesh
            !! Mesh

            integer :: l, ic, k, ln, fill_it
            integer, allocatable, dimension(:) :: wrk

            integer, parameter, dimension(4) :: ing = [0, -1, 1, 0]
            integer, parameter, dimension(4) :: jng = [-1, 0, 0, 1]
            
            ! Find mesh points, that have a direct neighbour to the immersed
            ! region
            do fill_it = 1, 2
                ! fill_it = 1: Determines size and allocates wrk
                ! fill_it = 2: Fills wrk
                ic = 0
                mloop: do l = 1, mesh%get_n_points()
                    if (self%charfun(l) > FP_EPS) cycle mloop
                    do k = 1, 4
                        ln = mesh%get_index_neighbor(ing(k), jng(k), l)
                        if (ln == 0) cycle mloop
                        if (self%charfun(ln) > FP_EPS) then
                            ic = ic + 1
                            if (fill_it == 2) then
                                wrk(ic) = l
                            endif
                            cycle mloop
                        endif
                    enddo
                enddo mloop
                if (fill_it == 1) then
                    self%n_adj_inds = ic
                    allocate(wrk(self%n_adj_inds))
                endif
            enddo

            ! wrk may contain duplicate entries, unique them into adj_inds
            call unique_tuples(1, self%n_adj_inds, wrk)
            allocate(self%adj_inds(self%n_adj_inds))
            do ic = 1, self%n_adj_inds
                self%adj_inds(ic) = wrk(ic)
            enddo
            deallocate(wrk)

        end subroutine

end module