LocalRefinementClass.f90 Source File


Source Code

!
!//////////////////////////////////////////////////////
!
! This class represents the local p-refinement of a mesh
!
!//////////////////////////////////////////////////////
!

Module  LocalRefinement  !

    use FileReadingUtilities, only: getRealArrayFromString, getIntArrayFromString
    use FTValueDictionaryClass
    use SMConstants
    use pAdaptationClass          , only: GetMeshPolynomialOrders

    Implicit None
!     ---------------------
!     Main local refinement type
!     ---------------------

    type LocalRef_t

        real(kind=RP), dimension(:,:), allocatable          :: xlim         ! limits for refinement in x direction
        real(kind=RP), dimension(:,:), allocatable          :: ylim
        real(kind=RP), dimension(:,:), allocatable          :: zlim
        integer, dimension(:), allocatable         :: Nx           ! polynomial order for each selection within the limits in x redirection
        integer, dimension(:), allocatable         :: Ny
        integer, dimension(:), allocatable         :: Nz
        integer, dimension(3)                      :: globalNxyz   ! default polynomial order, outside the limits
        integer                                    :: lenRegions   ! number of regions, it has to be the same for each redirection

        contains
           procedure   :: Construct               => LocalRef_Construct
           procedure   :: Destruct                => LocalRef_Destruct
           procedure   :: getOrderOfPosition

    end type LocalRef_t
!
!////////////////////////////////////////////////////////////////////////
    contains
!////////////////////////////////////////////////////////////////////////
!
    Subroutine  LocalRef_Construct(self, controlVariables)

        IMPLICIT NONE

        class(LocalRef_t)                         :: self
        type(FTValueDictionary), intent(in)     :: controlVariables

        !local variables
        character(len=LINE_LENGTH)              :: NxName, NyName, NzName, limsName
        integer                                 :: lenRegions, lenRegionz, lenRegiony
        real(kind=RP),dimension(:),allocatable  :: tempArray
        integer, allocatable                    :: Nx(:), Ny(:), Nz(:) !temporal variables for getting the default pol orders
        integer                                 :: Nmax
        logical                                 :: hasZ

        !get polynomial orders for all regions in all redirections
        NxName = trim(controlVariables%stringValueForKey("x regions orders",LINE_LENGTH))
        NyName = trim(controlVariables%stringValueForKey("y regions orders",LINE_LENGTH))
        NzName = trim(controlVariables%stringValueForKey("z regions orders",LINE_LENGTH))

        hasZ = NzName .ne. "0"
        self % Nx = getIntArrayFromString(NxName)
        self % Ny = getIntArrayFromString(NyName)
        if (hasZ) self % Nz = getIntArrayFromString(NzName)

        lenRegions = size(self % Nx)
        lenRegiony = size(self % Ny)
        lenRegionz = 0
        if (hasZ) lenRegionz = size(self % Nz)
        ! print *, "lenRegionz: ", lenRegionz

        Allocate (self % xlim(2,lenRegions), self % ylim(2,lenRegions), self % zlim(2,lenRegions) )

        self % lenRegions              = lenRegions

        !get global pol orders
        call GetMeshPolynomialOrders(controlVariables,Nx,Ny,Nz,Nmax)
        self % globalNxyz(1) = Nx(1)
        self % globalNxyz(2) = Ny(1)
        self % globalNxyz(3) = Nz(1)

        !get the limits of the regions for all directions
        allocate (tempArray(2*lenRegions))

        limsName = trim(controlVariables%stringValueForKey("x regions limits",LINE_LENGTH))
        tempArray = getRealArrayFromString(limsName)
        ! convert to a two dimensional array
        self % xlim = reshape(source= tempArray, shape=[2,lenRegions])

        limsName = trim(controlVariables%stringValueForKey("y regions limits",LINE_LENGTH))
        tempArray = getRealArrayFromString(limsName)
        self % ylim = reshape(source= tempArray, shape=[2,lenRegions])

        !check if z arrays are set in control file
        if (lenRegionz .gt. 0) hasZ = .true.
        if (hasZ) then 
            self % Nz = getRealArrayFromString(NzName)
            limsName = trim(controlVariables%stringValueForKey("z regions limits",LINE_LENGTH))
            tempArray = getRealArrayFromString(limsName)
            self % zlim = reshape(source= tempArray, shape=[2,lenRegions])
        else
            ! set default values
            allocate(self % Nz(lenRegions))
            self % Nz = Nz(1)
            self % zlim(1,:) = -10
            self % zlim(2,:) = 10
        end if

        deallocate(tempArray)

!
    End Subroutine LocalRef_Construct 
!
!////////////////////////////////////////////////////////////////////////
!
    Subroutine  LocalRef_Destruct(self)

        class(LocalRef_t), intent(inout) :: self

        if (ALLOCATED(self%xlim)) DEALLOCATE (self%xlim)
        if (ALLOCATED(self%ylim)) DEALLOCATE (self%ylim)
        if (ALLOCATED(self%zlim)) DEALLOCATE (self%zlim)
        if (ALLOCATED(self%Nx)) DEALLOCATE (self%Nx)
        if (ALLOCATED(self%Ny)) DEALLOCATE (self%Ny)
        if (ALLOCATED(self%Nz)) DEALLOCATE (self%Nz)
        self % globalNxyz = 1
        self % lenRegions = 0

    End Subroutine LocalRef_Destruct 
!
!////////////////////////////////////////////////////////////////////////
!
    Subroutine  getOrderOfPosition(self, coordinates, Nx, Ny, Nz)

        implicit none

        class (LocalRef_t)                       :: self
        real(kind=RP), dimension(3,8), intent(in)       :: coordinates
        integer,intent(out)                    :: Nx, Ny, Nz

        !local variables
        integer                                :: i

        ! set default value if the coordinates are not in the limits
        Nx = self % globalNxyz(1)
        Ny = self % globalNxyz(2)
        Nz = self % globalNxyz(3)

        ! search for the coordinates within the limits and set the order of the corresponded one
         associate (cx => coordinates(1,:)); associate (cy => coordinates(2,:)); associate (cz => coordinates(3,:))
            do i = 1, self%lenRegions
                if (all(cx .ge. self%xlim(1,i)) .and. all(cx .le. self%xlim(2,i))) then
                    if (all(cy .ge. self%ylim(1,i)) .and. all(cy .le. self%ylim(2,i))) then
                        if (all(cz .ge. self%zlim(1,i)) .and. all(cz .le. self%zlim(2,i))) then
                            Nx = self % Nx(i)
                            Ny = self % Ny(i)
                            Nz = self % Nz(i)
                            return
                        end if
                    end if
                end if  
            end do  
        end associate; end associate; end associate

    End Subroutine getOrderOfPosition 

End Module  LocalRefinement