Changeset 879


Ignore:
Timestamp:
06/04/19 18:03:54 (5 years ago)
Author:
dubos
Message:

devel : introduced derived type to store cell bounds

Location:
codes/icosagcm/devel/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/devel/src/base/field.f90

    r862 r879  
    133133        field(ind)%ndim=3 
    134134        field(ind)%dim3=dim1 
     135        field(ind)%dim4=1 
    135136      ELSE 
    136137        field(ind)%ndim=2 
     138        field(ind)%dim3=1 
     139        field(ind)%dim4=1 
    137140      END IF 
    138141     
  • codes/icosagcm/devel/src/parallel/domain.f90

    r867 r879  
    11MODULE domain_mod 
    22  USE domain_param 
     3  IMPLICIT NONE 
     4  SAVE 
     5 
     6  TYPE t_cellset 
     7     ! derived type containing arrays for lat,lon of center and bounds of cells of primal or dual mesh 
     8     ! this information is needed to write CF-compliant NetCDF files 
     9     ! and by XIOS 
     10     INTEGER :: ncell 
     11     INTEGER, ALLOCATABLE :: ij(:), & ! ij(n) = local index of cell n 
     12          ind_glo(:), &  ! ind_glo(n) = global index of cell n 
     13          sgn(:)         ! sign to apply before writing to disk (velocities) 
     14     REAL, ALLOCATABLE :: lon(:), lat(:), bnds_lon(:,:), bnds_lat(:,:) 
     15  END type t_cellset 
    316 
    417  TYPE t_domain 
     
    6073    INTEGER :: u_pos(6) 
    6174    INTEGER :: z_pos(6) 
    62       
     75 
     76    TYPE(t_cellset), POINTER :: primal_own, dual_own, edge_own, & 
     77         primal_all, dual_all, edge_all ! halo included, used for debug by writefield 
    6378  END TYPE t_domain 
    6479 
    65   INTEGER,SAVE :: ndomain 
    66   INTEGER,SAVE :: ndomain_glo 
     80  TYPE t_mesh 
     81     INTEGER :: ndomain, primal_num, edge_num, dual_num 
     82     TYPE(t_domain), ALLOCATABLE :: domain(:) 
     83     TYPE(t_cellset), ALLOCATABLE :: primal_own(:), dual_own(:), edge_own(:), & 
     84       primal_all(:), dual_all(:), edge_all(:) 
     85  END type t_mesh 
     86 
     87  INTEGER :: ndomain 
     88  INTEGER :: ndomain_glo 
    6789 
    6890  LOGICAL :: swap_needed=.TRUE. ! .FALSE. if a thread always computes on the same domain 
    6991  !$OMP THREADPRIVATE(swap_needed) 
    7092 
    71   TYPE(t_domain),SAVE,ALLOCATABLE,TARGET :: domain(:) 
    72   TYPE(t_domain),SAVE,ALLOCATABLE,TARGET :: domain_glo(:) 
    73  
    74   INTEGER,ALLOCATABLE,SAVE :: domglo_rank(:)  ! size : ndomain_glo : mpi rank assigned to a domain  
    75   INTEGER,ALLOCATABLE,SAVE :: domglo_loc_ind(:) ! size : ndomain_glo : corresponding local indice for a global domain indice 
    76   INTEGER,ALLOCATABLE,SAVE :: domloc_glo_ind(:) ! size : ndomain : corresponding global indice for a local domain indice 
    77  
    78   LOGICAL, ALLOCATABLE, SAVE :: assigned_domain(:) ! size : ndomain : is an omp task is assigned to this domain 
     93  TYPE(t_mesh), TARGET :: mesh_loc, mesh_glo 
     94  TYPE(t_domain), POINTER :: domain(:), domain_glo(:) 
     95 
     96  INTEGER,ALLOCATABLE :: domglo_rank(:)  ! size : ndomain_glo : mpi rank assigned to a domain  
     97  INTEGER,ALLOCATABLE :: domglo_loc_ind(:) ! size : ndomain_glo : corresponding local indice for a global domain indice 
     98  INTEGER,ALLOCATABLE :: domloc_glo_ind(:) ! size : ndomain : corresponding global indice for a local domain indice 
     99 
     100  LOGICAL, ALLOCATABLE :: assigned_domain(:) ! size : ndomain : is an omp task is assigned to this domain 
    79101!$OMP THREADPRIVATE(assigned_domain) 
    80102     
    81103CONTAINS 
     104 
     105  SUBROUTINE allocate_mesh(ndom, mesh) 
     106    INTEGER, INTENT(IN)       :: ndom 
     107    TYPE(t_mesh), TARGET, INTENT(OUT) :: mesh 
     108    INTEGER :: ind 
     109    mesh%ndomain = ndom 
     110    ALLOCATE(mesh%domain(ndom)) 
     111    ALLOCATE(mesh%primal_own(ndom)) 
     112    ALLOCATE(mesh%primal_all(ndom)) 
     113    ALLOCATE(mesh%dual_own(ndom)) 
     114    ALLOCATE(mesh%dual_all(ndom)) 
     115    ALLOCATE(mesh%edge_own(ndom)) 
     116    ALLOCATE(mesh%edge_all(ndom)) 
     117    DO ind=1, ndom 
     118       mesh%domain(ind)%primal_own => mesh%primal_own(ind) 
     119       mesh%domain(ind)%primal_all => mesh%primal_all(ind) 
     120       mesh%domain(ind)%dual_own => mesh%dual_own(ind) 
     121       mesh%domain(ind)%dual_all => mesh%dual_all(ind) 
     122       mesh%domain(ind)%edge_own => mesh%edge_own(ind) 
     123       mesh%domain(ind)%edge_all => mesh%edge_all(ind) 
     124    END DO 
     125  END SUBROUTINE allocate_mesh 
    82126 
    83127  SUBROUTINE create_domain 
     
    85129  USE mpipara 
    86130  USE ioipsl 
    87   IMPLICIT NONE 
    88131  INTEGER :: ind,nf,ni,nj,i,j 
    89132  INTEGER :: quotient, rest 
     
    93136  
    94137    ndomain_glo=nsplit_i*nsplit_j*nb_face 
    95     ALLOCATE(domain_glo(ndomain_glo)) 
     138    CALL allocate_mesh(ndomain_glo, mesh_glo) 
     139    domain_glo => mesh_glo%domain 
    96140    ALLOCATE(domglo_rank(ndomain_glo)) 
    97141    ALLOCATE(domglo_loc_ind(ndomain_glo)) 
     
    178222   
    179223  SUBROUTINE copy_domain(d1,d2) 
    180   IMPLICIT NONE 
    181224  INTEGER :: face 
    182225  TYPE(t_domain),TARGET,INTENT(IN) :: d1 
     
    245288  SUBROUTINE assign_cell 
    246289  USE metric 
    247   IMPLICIT NONE 
    248290    INTEGER :: ind_d,ind,ind2,e,v 
    249291    INTEGER :: nf,nf2 
     
    365407  SUBROUTINE compute_boundary 
    366408  USE spherical_geom_mod 
    367   IMPLICIT NONE 
    368409    INTEGER :: ind_d 
    369410    INTEGER :: i,j,k 
     
    388429  SUBROUTINE set_neighbour_indice 
    389430  USE metric 
    390   IMPLICIT NONE 
    391431    INTEGER :: ind_d 
    392432    TYPE(t_domain),POINTER :: d  
     
    444484  USE mpipara 
    445485  USE grid_param 
    446   IMPLICIT NONE 
    447486    INTEGER :: nb_domain(0:mpi_size-1) 
    448487    INTEGER :: rank, ind,ind_glo 
     
    456495     
    457496    ndomain=nb_domain(mpi_rank) 
    458     ALLOCATE(domain(ndomain)) 
     497     
     498    ! ALLOCATE(domain(ndomain)) 
     499    CALL allocate_mesh(ndomain, mesh_loc) 
     500    domain => mesh_loc%domain 
     501 
    459502    ALLOCATE(domloc_glo_ind(ndomain)) 
    460503     
     
    588631  USE omp_para 
    589632  USE mpipara 
    590   IMPLICIT NONE 
    591633    INTEGER :: nb_domain 
    592634    INTEGER :: rank, ind, i 
     
    629671  SUBROUTINE compute_domain 
    630672    USE grid_param, ONLY : grid_type, grid_unst, grid_ico 
    631     IMPLICIT NONE 
     673    INTEGER :: ind 
    632674    SELECT CASE(grid_type) 
    633675    CASE(grid_unst) 
    634676       ! FIXME temporary, sequential hack 
    635677       ndomain_glo=1 
    636        ALLOCATE(domain_glo(ndomain_glo)) 
     678       CALL allocate_mesh(ndomain_glo, mesh_glo) 
     679       domain_glo => mesh_glo%domain 
    637680       ALLOCATE(domglo_rank(ndomain_glo)) 
    638681       ALLOCATE(domglo_loc_ind(ndomain_glo)) 
     
    641684 
    642685       ndomain=1 
    643        ALLOCATE(domain(ndomain)) 
     686       CALL allocate_mesh(ndomain, mesh_loc) 
     687       domain => mesh_loc%domain 
    644688       ALLOCATE(domloc_glo_ind(ndomain)) 
    645689       ALLOCATE(assigned_domain(ndomain)) 
     
    658702       CALL assign_domain 
    659703    END SELECT 
     704 
     705!    ALLOCATE(primal_cells(ndomain)) 
     706!    ALLOCATE(dual_cells(ndomain)) 
     707!    ALLOCATE(primal_cells_single(ndomain)) 
     708!    ALLOCATE(dual_cells_single(ndomain)) 
     709!    DO ind=1, ndomain 
     710!       domain(ind)%primal_cells => primal_cells(ind) 
     711!       domain(ind)%dual_cells => dual_cells(ind) 
     712!       domain(ind)%primal_cells_single => primal_cells_single(ind) 
     713!       domain(ind)%dual_cells_single => dual_cells_single(ind) 
     714!    END DO 
     715 
    660716  END SUBROUTINE compute_domain 
    661717           
  • codes/icosagcm/devel/src/sphere/geometry.f90

    r863 r879  
    104104  USE field_mod 
    105105  IMPLICIT NONE 
    106    
     106  INTEGER, PARAMETER :: nvertex=6    ! FIXME unstructured 
     107 
    107108    CALL allocate_field(geom%Ai,field_t,type_real,name='Ai') 
    108109 
    109110    CALL allocate_field(geom%xyz_i,field_t,type_real,3) 
    110     CALL allocate_field(geom%lon_i,field_t,type_real) 
    111     CALL allocate_field(geom%lat_i,field_t,type_real) 
     111    CALL allocate_field(geom%lon_i,field_t,type_real, name='lon_i') 
     112    CALL allocate_field(geom%lat_i,field_t,type_real, name='lat_i') 
    112113    CALL allocate_field(geom%elon_i,field_t,type_real,3) 
    113114    CALL allocate_field(geom%elat_i,field_t,type_real,3) 
     
    115116 
    116117    CALL allocate_field(geom%xyz_e,field_u,type_real,3) 
    117     CALL allocate_field(geom%lon_e,field_u,type_real) 
    118     CALL allocate_field(geom%lat_e,field_u,type_real) 
     118    CALL allocate_field(geom%lon_e,field_u,type_real, name='lon_e') 
     119    CALL allocate_field(geom%lat_e,field_u,type_real, name='lat_e') 
    119120    CALL allocate_field(geom%elon_e,field_u,type_real,3) 
    120121    CALL allocate_field(geom%elat_e,field_u,type_real,3) 
     
    123124 
    124125    CALL allocate_field(geom%xyz_v,field_z,type_real,3) 
    125     CALL allocate_field(geom%de,field_u,type_real) 
    126     CALL allocate_field(geom%le,field_u,type_real) 
    127     CALL allocate_field(geom%le_de,field_u,type_real) 
     126    CALL allocate_field(geom%de,field_u,type_real, name='de') 
     127    CALL allocate_field(geom%le,field_u,type_real, name='le') 
     128    CALL allocate_field(geom%le_de,field_u,type_real, name='le_de') 
    128129    CALL allocate_field(geom%bi,field_t,type_real) 
    129     CALL allocate_field(geom%Av,field_z,type_real) 
    130     CALL allocate_field(geom%S1,field_t,type_real,6) 
    131     CALL allocate_field(geom%S2,field_t,type_real,6) 
    132     CALL allocate_field(geom%Riv,field_t,type_real,6) 
    133     CALL allocate_field(geom%Riv2,field_t,type_real,6) 
    134     CALL allocate_field(geom%ne,field_t,type_integer,6) 
    135     CALL allocate_field(geom%Wee,field_u,type_real,5,2) 
     130    CALL allocate_field(geom%Av,field_z,type_real, name='Av') 
     131    CALL allocate_field(geom%S1,field_t,type_real,nvertex) 
     132    CALL allocate_field(geom%S2,field_t,type_real,nvertex) 
     133    CALL allocate_field(geom%Riv,field_t,type_real,nvertex) 
     134    CALL allocate_field(geom%Riv2,field_t,type_real,nvertex) 
     135    CALL allocate_field(geom%ne,field_t,type_integer,nvertex) 
     136    CALL allocate_field(geom%Wee,field_u,type_real,5,2) ! FIXME unstructured 
    136137    CALL allocate_field(geom%bi,field_t,type_real) 
    137     CALL allocate_field(geom%fv,field_z,type_real) 
     138    CALL allocate_field(geom%fv,field_z,type_real, name='fv') 
    138139 
    139140  END SUBROUTINE allocate_geometry 
  • codes/icosagcm/devel/src/unstructured/init_unstructured.f90

    r863 r879  
    22  USE mpipara, ONLY : is_mpi_master 
    33  USE data_unstructured_mod 
    4   USE geometry, ONLY : de 
     4  USE geometry, ONLY : swap_geometry 
    55  IMPLICIT NONE 
    66  SAVE 
     
    128128 
    129129 
     130  SUBROUTINE read_field(id_nc, field) 
     131    USE field_mod, ONLY : t_field, type_integer, type_real 
     132    INTEGER :: id_nc 
     133    TYPE(t_field), POINTER :: field(:), fld 
     134    fld=>field(1) 
     135    SELECT CASE(fld%data_type) 
     136    CASE(type_integer) 
     137       CALL read_from_gridfile(id_nc, 'integer', TRIM(fld%name)) 
     138       SELECT CASE(field(1)%ndim) 
     139       CASE(2) 
     140          fld%ival2d = Idata_read1 
     141       CASE(3) 
     142          fld%ival3d = Idata_read2 
     143       END SELECT 
     144    CASE(type_real) 
     145       CALL read_from_gridfile(id_nc, 'float', TRIM(fld%name)) 
     146       SELECT CASE(field(1)%ndim) 
     147       CASE(2) 
     148          fld%rval2d = Ddata_read1 
     149       CASE(3) 
     150          fld%rval3d = Ddata_read2 
     151       END SELECT 
     152    END SELECT 
     153  END SUBROUTINE read_field 
     154 
    130155  SUBROUTINE read_local_mesh 
    131156    USE field_mod 
    132     USE geometry, ONLY : lon_i, lat_i, lon_e, lat_e, ep_e 
     157    USE geometry, ONLY : geom, lon_i, lat_i, lon_e, lat_e, ep_e 
     158    USE domain_mod, ONLY : domain, domain_glo, t_domain, swap_needed 
    133159    IMPLICIT NONE 
    134160    INTEGER :: ij 
     161    INTEGER, ALLOCATABLE :: cell_ij(:) 
    135162    REAL(rstd), ALLOCATABLE :: angle_e(:) 
    136163    REAL(rstd) :: clon, slon, clat, slat, & ! COS/SIN of lon/lat 
    137164         elon(3), elat(3) ! lon/lat unit vectors 
    138165     
    139     !status = nf90_get_att(id_nc, nf90_global, "primal_num", primal_num) 
    140     !status = nf90_get_att(id_nc, nf90_global, "dual_num", dual_num) 
    141     !status = nf90_get_att(id_nc, nf90_global, "edge_num", edge_num) 
    142     !print *,primal_num,dual_num,edge_num 
    143  
     166    ! if possible data is read into fields allocated in geom(1) using read_field 
     167    CALL read_field(id_nc, geom%Ai) 
     168    CALL read_field(id_nc, geom%Av) 
     169    CALL read_field(id_nc, geom%fv) 
     170    CALL read_field(id_nc, geom%le_de) 
     171    CALL read_field(id_nc, geom%le) 
     172    CALL read_field(id_nc, geom%de) 
     173    CALL read_field(id_nc, geom%lon_i) 
     174    CALL read_field(id_nc, geom%lat_i) 
     175    CALL read_field(id_nc, geom%lon_e) 
     176    CALL read_field(id_nc, geom%lat_e) 
     177 
     178    swap_needed = .TRUE. 
     179    CALL swap_geometry(1) 
     180 
     181    ! cell centers and bounds are read into domain(1)%primal_own 
     182    domain(1)%primal_own%ncell = primal_num 
     183    domain_glo(1)%primal_own%ncell = primal_num 
     184    ALLOCATE(domain(1)%primal_own%lon,     source=lon_i) 
     185    ALLOCATE(domain_glo(1)%primal_own%lon, source=lon_i) 
     186    ALLOCATE(domain(1)%primal_own%lat,     source=lat_i) 
     187    ALLOCATE(domain_glo(1)%primal_own%lat, source=lat_i) 
     188 
     189    CALL read_from_gridfile(id_nc, 'float', 'primal_bounds_lon') 
     190    ALLOCATE(domain(1)%primal_own%bnds_lon,     source=Ddata_read2) 
     191    ALLOCATE(domain_glo(1)%primal_own%bnds_lon, source=Ddata_read2) 
     192    CALL read_from_gridfile(id_nc, 'float', 'primal_bounds_lat') 
     193    ALLOCATE(domain(1)%primal_own%bnds_lat,     source=Ddata_read2) 
     194    ALLOCATE(domain_glo(1)%primal_own%bnds_lat, source=Ddata_read2) 
     195    PRINT *, 'read_local_mesh : primal_num =', primal_num, domain_glo(1)%primal_own%ncell 
     196 
     197    ! other fields are defined only in the case of an unstructured mesh 
     198    ! those fields are read into simple arrays 
    144199    CALL read_from_gridfile(id_nc, 'integer', 'primal_deg') 
    145200    ALLOCATE(primal_deg, source = Idata_read1) 
     
    148203    CALL read_from_gridfile(id_nc, 'integer', 'primal_ne') 
    149204    ALLOCATE(primal_ne, source = Idata_read2) 
     205    CALL read_from_gridfile(id_nc, 'integer', 'primal_vertex')  
     206    ALLOCATE(primal_vertex, source = Idata_read2) 
     207 
    150208    CALL read_from_gridfile(id_nc, 'integer', 'dual_deg') 
    151209    ALLOCATE(dual_deg, source = Idata_read1) 
     
    154212    CALL read_from_gridfile(id_nc, 'integer', 'dual_ne') 
    155213    ALLOCATE(dual_ne, source = Idata_read2) 
    156     CALL read_from_gridfile(id_nc, 'integer', 'primal_vertex')  
    157     ALLOCATE(primal_vertex, source = Idata_read2) 
     214    CALL read_from_gridfile(id_nc, 'integer', 'dual_vertex')  
     215    ALLOCATE(dual_vertex, source = Idata_read2) 
     216 
    158217    CALL read_from_gridfile(id_nc, 'integer', 'left') 
    159218    ALLOCATE(left, source = Idata_read1) 
     
    164223    CALL read_from_gridfile(id_nc, 'integer', 'down') 
    165224    ALLOCATE(down, source = Idata_read1) 
     225    CALL read_from_gridfile(id_nc, 'float', 'angle_e') 
     226    ALLOCATE(angle_e, source = Ddata_read1) 
    166227    CALL read_from_gridfile(id_nc, 'integer', 'trisk_deg') 
    167228    ALLOCATE(trisk_deg, source = Idata_read1) 
    168229    CALL read_from_gridfile(id_nc, 'integer', 'trisk') 
    169230    ALLOCATE(trisk, source = Idata_read2) 
    170     CALL read_from_gridfile(id_nc, 'float', 'Ai') 
    171     ALLOCATE(Ai, source = Ddata_read1) 
    172     CALL read_from_gridfile(id_nc, 'float', 'Av') 
    173     ALLOCATE(Av, source = Ddata_read1) 
    174     CALL read_from_gridfile(id_nc, 'float', 'le_de') 
    175     ALLOCATE(le_de, source = Ddata_read1) 
    176     CALL read_from_gridfile(id_nc, 'float', 'le') 
    177     ALLOCATE(le, source = Ddata_read1) 
    178     CALL read_from_gridfile(id_nc, 'float', 'de') 
    179     ALLOCATE(de, source = Ddata_read1) 
    180231    CALL read_from_gridfile(id_nc, 'float', 'Riv2') 
    181232    ALLOCATE(Riv2, source = Ddata_read2) 
    182233    CALL read_from_gridfile(id_nc, 'float', 'wee') 
    183234    ALLOCATE(wee, source = Ddata_read2) 
    184     CALL read_from_gridfile(id_nc, 'float', 'fv') !  
    185     ALLOCATE(fv, source = Ddata_read1) 
    186     CALL read_from_gridfile(id_nc, 'integer', 'dual_vertex')  
    187     ALLOCATE(dual_vertex, source = Idata_read2) 
    188  
    189     CALL read_from_gridfile(id_nc, 'float', 'lon_i') 
    190     ALLOCATE(lon_i, source = Ddata_read1) 
    191     CALL read_from_gridfile(id_nc, 'float', 'lat_i') 
    192     ALLOCATE(lat_i, source = Ddata_read1) 
    193     CALL read_from_gridfile(id_nc, 'float', 'lon_e') 
    194     ALLOCATE(lon_e, source = Ddata_read1) 
    195     CALL read_from_gridfile(id_nc, 'float', 'lat_e') 
    196     ALLOCATE(lat_e, source = Ddata_read1) 
    197     CALL read_from_gridfile(id_nc, 'float', 'angle_e') 
    198     ALLOCATE(angle_e, source = Ddata_read1) 
    199235 
    200236    CALL free_data_read ! free buffers after reading all data from grid file 
    201237 
    202     edge_num = SIZE(le_de) 
    203     primal_num = SIZE(Ai) 
    204     dual_num = SIZE(Av) 
     238 
     239!    edge_num = SIZE(le_de) 
     240!    primal_num = SIZE(Ai) 
     241!    dual_num = SIZE(Av) 
    205242    max_primal_deg = SIZE(primal_edge,1) 
    206243    max_dual_deg = SIZE(dual_edge,1) 
     
    221258     
    222259    DEALLOCATE(angle_e) 
     260 
     261    ALLOCATE(domain(1)%primal_own%ij(primal_num)) 
     262    domain(1)%primal_own%ij(:) = (/(ij,ij=1,primal_num)/) 
     263    PRINT *, 'read_local_mesh :', SHAPE(domain), primal_num, & 
     264         SHAPE(domain(1)%primal_own%ij) 
     265 
     266    ALLOCATE(cell_ij(dual_num)) 
     267    cell_ij(:) = (/(ij,ij=1,dual_num)/) 
     268    ALLOCATE(domain(1)%dual_own%ij, source=cell_ij) 
     269    DEALLOCATE(cell_ij) 
     270 
     271    CALL swap_geometry(1) 
     272    swap_needed = .FALSE. 
    223273  END SUBROUTINE read_local_mesh 
    224274 
Note: See TracChangeset for help on using the changeset viewer.