ITM Grid Service Library: Fortran 90

src/service/itm_grid_subgrid.f90

Go to the documentation of this file.
00001 module itm_grid_subgrid
00002 
00003   !> @author H.-J. Klingshirn
00004 
00005   use itm_types , ITM_R8 => R8, ITM_R4 => R4
00006   use itm_assert
00007   use euitm_schemas ! IGNORE
00008 
00009   use itm_combinations
00010 
00011   use itm_grid_common
00012   use itm_grid_access
00013   use itm_grid_object
00014   use itm_grid_objectlist
00015 
00016   implicit none
00017 
00018 contains
00019 
00020   !> Create a subgrid for a given number of object lists
00021   subroutine createSubGrid( sg, nobjlist, id )
00022     type(type_complexgrid_subgrid), intent(out) :: sg
00023     integer, intent(in) :: nobjlist
00024     character(*), intent(in), optional :: id
00025 
00026 
00027     allocate( sg%list(nobjlist) )
00028 
00029     allocate( sg%id(1) )
00030     if ( present( id ) ) then
00031         ! use given subgrid id
00032         sg % id(1) = id(1:min(len(sg%id(1)), len_trim(id)))
00033     else
00034         sg % id(1) = 'UNSPECIFIED'
00035     end if
00036 
00037   end subroutine createSubGrid
00038 
00039 
00040   !> Convenience routine: create a subgrid for one specific object class
00041   subroutine createSubGridForClass( grid, sg, cls, id )
00042     type(type_complexgrid), intent(in) :: grid
00043     type(type_complexgrid_subgrid), intent(out) :: sg
00044     integer, intent(in) :: cls(gridNSpace(grid))
00045     character(*), intent(in), optional :: id
00046 
00047     call createSubGrid( sg, 1, id )
00048     call createImplicitObjectListForAll( grid, sg%list(1), cls )
00049   end subroutine createSubGridForClass
00050 
00051 
00052   !> Convenience routine: create a subgrid for a list of object classes.
00053   !> @param classes The list of object class. First index: class index, 
00054   !>  second index: space index, i.e. classes(i,:) is the ith object class tuple.
00055   subroutine createSubGridForClasses( grid, sg, classes, id )
00056     type(type_complexgrid), intent(in) :: grid
00057     type(type_complexgrid_subgrid), intent(out) :: sg
00058     integer, intent(in) :: classes(:,:)
00059     character(*), intent(in), optional :: id
00060 
00061     ! internal
00062     integer :: iCls
00063 
00064     call assert(size(classes, 2) == gridNSpace(grid))
00065 
00066     ! Create one implicit object list for every object class
00067     call createSubGrid( sg, size(classes, 1), id )
00068     do iCls = 1, size(classes, 1)
00069         call createImplicitObjectListForAll( grid, sg%list(iCls), classes(iCls, :) )
00070     end do
00071   end subroutine createSubGridForClasses
00072 
00073 
00074   !> Convenience routine: create a subgrid for an explicit object list
00075   subroutine createSubGridForExplicitList( grid, sg, cls, indlist, id )
00076     type(type_complexgrid), intent(in) :: grid
00077     type(type_complexgrid_subgrid), intent(out) :: sg
00078     integer, intent(in) :: cls(gridNSpace(grid))
00079     integer, intent(in) :: indlist(:,:)
00080     character(*), intent(in), optional :: id
00081 
00082     call assert( size(indlist, 2) == gridNSpace(grid) )
00083 
00084     call createSubGrid( sg, 1, id )
00085     call createExplicitObjectList( grid, sg%list(1), cls, indlist )
00086   end subroutine createSubGridForExplicitList
00087 
00088   !> Return number of subgrids in the grid.
00089   integer function gridNSubGrid(grid)
00090     type(type_complexgrid), intent(in) :: grid
00091 
00092     gridNSubGrid = 0
00093     if (associated(grid%subgrids)) &
00094         & gridNSubGrid = size(grid%subgrids)        
00095   end function gridNSubGrid
00096 
00097 
00098   !> Returns the subgrid index for the subgrid with this name
00099   !> If none found, returns GRID_UNDEFINED
00100   integer function gridFindSubGridByName(grid, name) result (sgInd)
00101     type(type_complexgrid), intent(in) :: grid
00102     character(*), intent(in) :: name
00103 
00104     ! internal
00105     integer :: iSg
00106     
00107     do iSg = 1, gridNSubGrid(grid)       
00108         if (.not. associated(grid%subgrids(iSg)%id) ) cycle
00109         if (grid%subgrids(iSg)%id(1)(1:len(name)) == name) then
00110             sgInd = iSg
00111             return
00112         end if
00113     end do
00114 
00115     sgInd = GRID_UNDEFINED
00116   end function gridFindSubGridByName
00117 
00118 
00119   !> Return the number of objects in the subgrid
00120   ! TODO: rename to subGridSize
00121   integer function gridSubGridSize(sg) result( nobj )
00122     type(type_complexgrid_subgrid), intent(in) :: sg    
00123 
00124     ! internal
00125     integer :: ilist
00126 
00127     nobj = 0
00128     do ilist = 1, size(sg%list)
00129         nobj = nobj + objectListSize( sg%list(ilist) )
00130     end do
00131   end function gridSubGridSize
00132 
00133 
00134   !> Return the object with index iobj according to the implicit object ordering of the subgrid  
00135   type(GridObject) function subGridGetObject(sg, iobj) result( obj )
00136     type(type_complexgrid_subgrid), intent(in) :: sg  
00137     integer, intent(in) :: iobj
00138 
00139     ! internal
00140     integer :: ilist, listsize, offset    
00141 
00142     offset = 0
00143     do ilist = 1, size(sg%list)
00144         listsize = objectListSize( sg%list(ilist) )
00145         if ( (offset < iobj) .and. (iobj <= offset + listsize) ) then
00146             obj = objectListGetObject( sg%list(ilist), iobj - offset )
00147             return
00148         end if
00149         offset = offset + listsize
00150     end do
00151 
00152     stop "subGridGetObject: index iobj is out of range"
00153   end function subGridGetObject
00154 
00155 
00156   !> Return the local index of the given object in the subgrid, according to the
00157   !> implicit object ordering of the subgrid
00158   integer function subGridGetIndexForObject(sg, obj) result( index )
00159     type(type_complexgrid_subgrid), intent(in) :: sg  
00160     type(GridObject), intent(in) :: obj
00161 
00162     ! internal
00163     integer :: ilist, listsize, offset, localIndex
00164 
00165     offset = 0
00166     do ilist = 1, size(sg%list)
00167         listsize = objectListSize( sg%list(ilist) )
00168 
00169         localIndex = objectListGetIndexForObject(sg%list(ilist), obj)
00170         if (localIndex /= GRID_UNDEFINED) then
00171             index = offset + localIndex
00172             return
00173         end if
00174 
00175         offset = offset + listsize
00176     end do
00177 
00178     ! didn't find anything
00179     index = GRID_UNDEFINED
00180   end function subGridGetIndexForObject
00181 
00182   
00183   !> Add a default set of subgrids for a grid. One subgrid is added
00184   !> for every dimension for which objects exist in the grid. This subgrid
00185   !> will contain all objects of that dimension in the canonical implicit ordering.
00186   subroutine gridCreateDefaultSubGrids(grid, id)
00187     type(type_complexgrid), intent(inout) :: grid
00188     character(*), intent(in), optional :: id
00189 
00190     ! internal
00191     integer :: iDim, iSg
00192     integer, dimension(gridNSpace(grid)) :: maxCls
00193     integer, allocatable :: classes(:,:)
00194 
00195     character(7), parameter :: genId(0:6) = (/ 'nodes  ', 'edges  ', 'faces  ', 'volumes', 'obj4d  ', 'obj5d  ', 'obj6d  ' /)
00196 
00197     maxCls = gridGetMaxDimClass( grid )
00198     
00199     ! ...set up default subgrids: one subgrid for all objects of a given dimension
00200     allocate(grid%subgrids(classDim(maxCls)+1))
00201 
00202     do iDim = 0, classDim(maxCls)
00203         ! Create subgrid
00204         iSg = idim + 1
00205         call allocate_combinations(gridSpaceNDims(grid), iDim, classes)
00206         if (present(id)) then
00207             call createSubGridForClasses(grid, grid%subgrids(iSg), classes, trim(id//'_'//genId(idim)) )
00208         else
00209             call createSubGridForClasses(grid, grid%subgrids(iSg), classes, trim(genId(idim)) )
00210         end if
00211         deallocate(classes)
00212     end do
00213 
00214   end subroutine gridCreateDefaultSubGrids
00215 
00216 end module itm_grid_subgrid
 All Classes Namespaces Files Functions Variables