ITM Grid Service Library: Fortran 90

src/examples/itm_grid_example10_solpsdata.f90

Go to the documentation of this file.
00001 program itm_grid_example10_solpsdata
00002   use itm_types         ! ITM standard Fortran data types, e.g. real(R8)
00003   use itm_constants
00004   use euITM_schemas     ! ITM data structure/CPO definitions
00005   use euITM_routines    ! ITM UAL routines
00006   use itm_grid_common   ! ITM grid service library: constant definitions like COORDTYPE_R, COORDTYPE_Z
00007 
00008   use itm_grid_2dpolygon
00009   use itm_grid_subgrid
00010   use itm_grid_structured
00011 
00012   implicit none
00013 
00014   ! parameters
00015   integer, parameter :: NPOINTR = 6 
00016   integer, parameter :: NPOINTZ = 5   
00017   integer, parameter :: SHOTNUM_IN = 63254
00018   integer, parameter :: RUNNUM_IN = 1
00019 
00020   integer, parameter :: SHOTNUM_OUT = SHOTNUM_IN
00021   integer, parameter :: RUNNUM_OUT = RUNNUM_IN + 1
00022 
00023   ! variables
00024   type (type_edge) :: edgecpo_in
00025   type (type_edge), pointer :: edgecpo_out(:)
00026   integer :: idx
00027 
00028   integer :: nodeSg, cellSg
00029 
00030   type(GridObject) ::  cell
00031   type(GridObject),dimension(:),allocatable :: nodes
00032   real(R8), dimension(:,:), allocatable :: coords
00033 
00034   real(R8) :: r(NPOINTR), z(NPOINTZ), nodePolygonIndex(NPOINTR, NPOINTZ), nodeData(NPOINTR, NPOINTZ)
00035   real(R8) :: rmin, rmax, zmin, zmax, p(2)
00036   integer :: rFrom, rTo, zFrom, zTo, iNode, ir, iz, i, iCell, iCellData, iNodeData
00037 
00038   ! === 1. Read CPO ===
00039 
00040   write (*,*) "Example 10: reading from shot ", SHOTNUM_IN, ", run ", RUNNUM_IN
00041   !call euitm_open_env( 'euitm', SHOTNUM_IN, RUNNUM_IN, idx, 'coster', 'aug', '4.09a')
00042   call euitm_open_env( 'euitm', SHOTNUM_IN, RUNNUM_IN, idx, 'klingshi', 'jet', '4.09a')
00043   call euitm_get_slice( idx, "edge", edgecpo_in, 2.5d0, UAL_PREVIOUS_SAMPLE ) 
00044   call euitm_close(idx)
00045 
00046   ! figure out subgrid ids for nodes and cells
00047   nodeSg = gridFindSubgridByName(edgecpo_in%grid, "Nodes")
00048   cellSg = gridFindSubgridByName(edgecpo_in%grid, "Cells")
00049 
00050   ! Find ne entry for cell subgrid
00051   do i = 1, size(edgecpo_in%fluid%ne%value)
00052       if (edgecpo_in%fluid%ne%value(i)%subgrid == cellSg) then
00053           iCellData = i
00054       end if
00055       if (edgecpo_in%fluid%ne%value(i)%subgrid == nodeSg) then
00056           iNodeData = i
00057       end if
00058   end do
00059 
00060   ! === 2. Set up an output CPO with a structured grid ===
00061   allocate(edgecpo_out(1))
00062 
00063   rmin = 2.7_R8
00064   rmax = 2.85_R8
00065   zmin = -1.6_R8
00066   zmax = -1.5_R8
00067 
00068       r = (/ ( rmin + ((rmax - rmin)/(NPOINTR-1)) * i, i=0,NPOINTR-1) /)
00069   z = (/ ( zmin + ((zmax - zmin)/(NPOINTZ-1)) * i, i=0,NPOINTZ-1) /)
00070 
00071   call gridSetupStructuredSep( edgecpo_out(1)%grid, &
00072       & ndim = 2, &
00073       & c1 = COORDTYPE_R, &
00074       & x1 = r, &
00075       & c2 = COORDTYPE_Z, &
00076       & x2 = z,&
00077       & id = '2d_structured' )
00078 
00079   ! === 3. Interpolate data to it ===
00080 
00081   if (.true.) then
00082 
00083   nodeData = 0.0_R8
00084   nodePolygonIndex = 0.0_R8
00085 
00086 
00087   ! Consider every polygon in the grid...
00088   do iCell = 1, gridSubGridSize( edgecpo_in%grid%subgrids(cellSg) )
00089 
00090       ! Get nodes bounding the polygon
00091       cell = subGridGetObject(edgecpo_in%grid%subgrids(cellSg), iCell)
00092       call get2dPolygonNodes( edgecpo_in%grid, cell, nodes )
00093       
00094       !call writeObjectList(nodes)
00095 
00096       ! get the coordinates of the nodes
00097       if (allocated(coords)) deallocate(coords)
00098       allocate( coords(size(nodes), gridNDim(edgecpo_in%grid)) )
00099       do iNode = 1, size(nodes)
00100           !write (*,*) gridNodeCoord( edgecpo_in%grid, nodes(iNode)%ind )
00101           coords(iNode,:) = gridNodeCoord( edgecpo_in%grid, nodes(iNode)%ind )
00102 
00103       end do
00104 
00105       ! find bounding rectangle for the polygon
00106       rmin = minval(coords(:,1))
00107       rmax = maxval(coords(:,1))
00108       zmin = minval(coords(:,2))
00109       zmax = maxval(coords(:,2))
00110 
00111       ! if no overlap with target grid, cycle
00112       if (rmin > r(NPOINTR) .or. rmax < r(1) .or. zmin > z(NPOINTZ) .or. zmax < z(1)) then
00113           cycle
00114       end if
00115 
00116       !write (*,*) "Cell ", icell, ": box ", rmin, rmax, zmin, zmax
00117 
00118 
00119       ! cut away parts outside of the target grid
00120       !if (rmin < r(1)) rmin = r(1)
00121       rmin = max(rmin, r(1))
00122       rmax = min(rmax, r(NPOINTR))
00123       zmin = max(zmin, z(1))
00124       zmax = min(zmax, z(NPOINTZ))
00125       !write (*,*) "Cell ", icell, ": overlap box ", rmin, rmax, zmin, zmax
00126 
00127       ! Find index ranges for candidate points. Extend it a bit to make sure we really cover the polygon
00128       rFrom = max( cellIndex( r, rmin ) - 1, 1 )
00129       rTo = min( cellIndex( r, rmax ) + 1, NPOINTR )
00130  zFrom = max( cellIndex( z, zmin ) - 1, 1 )
00131       zTo = min( cellIndex( z, zmax ) + 1, NPOINTZ )
00132 
00133       !write (*,*) "Cell ", icell, ": grid box ", r(rFrom), r(rTo), z(zFrom), z(zTo), rFrom, rTo, zFrom, zTo
00134 
00135       if (rFrom == 0 .or. rTo == 0 .or. zFrom == 0 .or. zTo == 0) then          
00136           write (*,*) "WARNING: did not find cell index. This should not happen."
00137           write (*,*) rmin, rmax, zmin, zmax
00138           write (*,*) rFrom, rTo, zFrom, zTo
00139           cycle
00140       end if
00141 
00142       ! check for every candidate point whether it's inside the polygon
00143       do ir = rFrom, rTo
00144           do iz = zFrom, zTo
00145               p(1) = r(ir)
00146               p(2) = z(iz)
00147               if ( pointInPolygon( coords, p ) ) then
00148                   if (nodePolygonIndex(ir, iz) > 0.0_R8) then
00149                       write (*,*) "WARNING: found multiple cells matching the same node"
00150                       write (*,*) "Node ", ir, iz, p(1), p(2)
00151                       write (*,*) "Cell: ", iCell
00152                       write (*,*) "Cell x: ", coords(:,1)
00153                       write (*,*) "Cell y: ", coords(:,2)
00154                   else
00155 
00156                       nodePolygonIndex(ir, iz) = iCell
00157 
00158                       ! just take cell value...
00159                       !nodeData(ir, iz) = edgecpo_in%fluid%ne%value(iCellData)%scalar(iCell)
00160 
00161                       ! ...or do arithmetic average of four corner nodes
00162                       nodeData(ir, iz) = 0.0_R8
00163                       do iNode = 1, 4
00164                           nodeData(ir, iz) = nodeData(ir, iz) + &
00165                               & edgecpo_in%fluid%ne%value(iNodeData)%scalar(&
00166                               & subGridGetIndexForObject(edgecpo_in%grid%subgrids(nodeSg), nodes(iNode)) )
00167                       end do
00168                       nodeData(ir, iz) = nodeData(ir, iz) / 4.0_R8
00169 
00170 
00171 
00172                   end if
00173               end if
00174           end do
00175       end do
00176       
00177       deallocate(nodes)
00178   end do
00179 
00180   write (*,*) "Of ", NPOINTZ * NPOINTR, " points, found for ", count(nodeData > 0.0_R8), " a polygon"
00181 
00182   endif
00183 
00184   ! === 4. Write output CPO ===
00185   allocate( edgecpo_out(1)%datainfo%dataprovider(1) )
00186   edgecpo_out(1)%datainfo%dataprovider="IMP3"
00187   allocate( edgecpo_out(1)%codeparam%codename(1) )
00188   edgecpo_out(1)%codeparam%codename(1)="itm_grid_example10"
00189   edgecpo_out(1)%time = edgecpo_in%time
00190 
00191   allocate(edgecpo_out(1)%fluid%ne%value(1))
00192   call gridStructWriteData2d( edgecpo_out(1)%grid, edgecpo_out(1)%fluid%ne%value(1), GRID_STRUCT_NODES, nodeData )
00193   allocate(edgecpo_out(1)%fluid%te%value(1))
00194   call gridStructWriteData2d( edgecpo_out(1)%grid, edgecpo_out(1)%fluid%te%value(1), GRID_STRUCT_NODES, nodePolygonIndex )
00195 
00196 
00197   write (*,*) "Example 10: writing to shot ", SHOTNUM_OUT, ", run ", RUNNUM_OUT
00198   call euitm_create( 'euitm', SHOTNUM_OUT, RUNNUM_OUT, 0, 0, idx )
00199   call euitm_put(idx, "edge", edgecpo_out)
00200   call euitm_close(idx)
00201 
00202 
00203 contains
00204 
00205   integer function cellIndex( x, val )
00206     real(R8), intent(in) :: x(:), val
00207 
00208     ! internal
00209     integer :: i
00210 
00211     do i = 1, size(x) - 2
00212         if (x(i) <= val .and. x(i+1) > val) then
00213             cellIndex = i
00214             return
00215         end if
00216     end do
00217 
00218     ! special treatment for rightmost cell
00219     if (x(size(x)-1) <= val .and. x(size(x)) >= val) then        
00220         cellIndex = size(x)-1
00221     else
00222         ! no cell found
00223         cellIndex = 0
00224     end if
00225 
00226   end function cellIndex
00227 
00228 
00229 
00230 
00231 end program itm_grid_example10_solpsdata
 All Classes Namespaces Files Functions Variables