Back to OASIS3-MCT home

The models use mod_oasis and call the routines of the psmile. The routines of the psmile are sorted out below as they are called by the models.

In oasis3-mct/lib/psmile/src :

mod_oasis:  Main module of the psmile in OASIS3-MCT.
Called by the models to be able to use the routines allowing communication
with the other models of the coupling.
module mod_oasis
! !USES:
  USE mod_oasis_kinds  ,ONLY: ip_single_p
  USE mod_oasis_kinds  ,ONLY: ip_double_p
  USE mod_oasis_kinds  ,ONLY: ip_realwp_p
  USE mod_oasis_kinds  ,ONLY: ll_single
  USE mod_oasis_kinds  ,ONLY: ip_i2_p
  USE mod_oasis_kinds  ,ONLY: ip_i4_p
  USE mod_oasis_kinds  ,ONLY: ip_i8_p
  USE mod_oasis_kinds  ,ONLY: ip_intwp_p
  USE mod_oasis_parameters
  USE mod_oasis_method ,ONLY: oasis_init_comp   
  USE mod_oasis_method ,ONLY: oasis_terminate
  USE mod_oasis_method ,ONLY: oasis_get_localcomm
  USE mod_oasis_method ,ONLY: oasis_set_couplcomm
  USE mod_oasis_method ,ONLY: oasis_create_couplcomm
  USE mod_oasis_method ,ONLY: oasis_get_intracomm
  USE mod_oasis_method ,ONLY: oasis_get_intercomm
  USE mod_oasis_method ,ONLY: oasis_set_debug    
  USE mod_oasis_method ,ONLY: oasis_get_debug    
  USE mod_oasis_method ,ONLY: oasis_enddef       
  USE mod_oasis_part   ,ONLY: oasis_def_partition  
  USE mod_oasis_var    ,ONLY: oasis_def_var      
  USE mod_oasis_getput_interface ,ONLY: oasis_get
  USE mod_oasis_getput_interface ,ONLY: oasis_put  
  USE mod_oasis_grid   ,ONLY: oasis_start_grids_writing
  USE mod_oasis_grid   ,ONLY: oasis_write_grid
  USE mod_oasis_grid   ,ONLY: oasis_write_angle
  USE mod_oasis_grid   ,ONLY: oasis_write_corner       
  USE mod_oasis_grid   ,ONLY: oasis_write_mask         
  USE mod_oasis_grid   ,ONLY: oasis_write_area         
  USE mod_oasis_grid   ,ONLY: oasis_terminate_grids_writing  
  USE mod_oasis_sys    ,ONLY: oasis_abort      

  IMPLICIT NONE

!===============================================================================
end module mod_oasis

oasis_init_comp (in mod_oasis_method): (mynummod,cdnam,kinfo)

=> oasis_data_zero()
=> call MPI_Initialized
=> call MPI_Comm_Size(mpi_comm_global,mpi_size_global,mpi_err)
=> call MPI_Comm_Rank(mpi_comm_global,mpi_rank_global,mpi_err)
=> oasis_unitsetmin(1024)
if (mpi_rank_global == 0) then
=> oasis_unitget (iu)   ! for the namcouple informations nout
=> oasis_namcouple_init()
=> oasis_unitget(nulin)  ! To open file namcouple
=> inipar_alloc()
=> parse
=> alloc()
=> inipar()
=> parse
=> oasis_unitfree(nulin)
=> oasis_unitsetmin(maxunit) ! Maxunit : max of unit used by all the models read in the namcouple
=> dealloc()
endif
=> call oasis_mpi_barrier(mpi_comm_global)
if (mpi_rank_global /= 0) then
=> oasis_namcouple_init()
endif
OASIS_debug = namlogprt
mvar = mvar + oasis_string_listGetNum(namsrcfld(n))   ! number of line of coupling fields read in the namcouple
mtimer = 7*mvar+30
=> call MPI_COMM_SPLIT (MPI_COMM_WORLD,icolor,ikey,mpi_comm_local,mpi_err) ! to get the mpi_comm_local of each model
=> call MPI_Comm_Size(mpi_comm_global,mpi_size_global,mpi_err)
=> call MPI_Comm_Rank(mpi_comm_global,mpi_rank_global,mpi_err)
=> call MPI_Comm_Size(mpi_comm_local,mpi_size_local,mpi_err)
=> call MPI_Comm_Rank(mpi_comm_local,mpi_rank_local,mpi_err)
mpi_root_local = 0
=> oasis_unitget(iu)  ! for the debug files
=> oasis_mpi_bcast
=> oasis_debug_enter
=> oasis_timer_init (trim(cdnam), trim(cdnam)//'.timers', mpi_comm_local)
=> oasis_timer_start('total after init')
=> oasis_debug_exit


oasis_get_localcomm (in mod_oasis_method):
oasis_start_grids_writing (in mod_oasis_grid):
oasis_write_grid (inmod_oasis_grid):
oasis_write_corner (in mod_oasis_grid):
oasis_write_area (in mod_oasis_grid):
oasis_write_mask (in mod_oasis_grid):
oasis_terminate_grids_writing (in mod_oasis_grid):


oasis_def_partition (in mod_oasis_part): (id_part, kparal, kinfo, ig_size)
definition of the global structure prism_part (mpart) of type (prism_part_type) !  mpart=100 hard coded in the module
=> oasis_debug_enter(subname)
=> oasis_timer_start('map definition')
kparal(CLIM_Strategy) -> start(n), length(n)
if (mpi_comm_local /= MPI_COMM_NULL) then
if (present(ig_size)) then
=> mct_gsmap_init(prism_part(prism_npart)%gsmap,start,length,mpi_root_local, mpi_comm_local,compid,numel=nsegs,gsize=ig_size)
else
=> mct_gsmap_init(prism_part(prism_npart)%gsmap,start,length,mpi_root_local, mpi_comm_local,compid,numel=nsegs)
endif
prism_part(prism_npart)%gsize = mct_gsmap_gsize(prism_part(prism_npart)%gsmap)
else
prism_part(prism_npart)%gsize = -1
endif
prism_part(prism_npart)%nx = -1
prism_part(prism_npart)%ny = -1
=> oasis_timer_stop('map definition')


oasis_def_var (in mod_oasis_var):

definition of the number of the variable prism_nvar (= id_nports)
definition of the global structure prism_var (mvar) of type (prism_var_type)
=> oasis_debug_enter(subname)
=> oasis_debug_exit(subname)


oasis_enddef (in mod_oasis_method): 

=> oasis_debug_enter
=> oasis_write2files ! To write files grids.nc, masks.nc and areas.nc
=> oasis_mpi_barrier
=> mct_world_init (prism_nmodels,mpi_comm_global,mpi_comm_local,compid)
=> oasis_coupler_setup () ! definition of global variables prism_mapper (type prism_mapper_type), prism_coupler (type prism_coupler_type)
=> oasis_debug_enter(subname)
=> oasis_timer_start('cpl_setup')
=> oasis_debug_note(subname//' set defaults for datatypes')
prism_coupler(nc)%aVon(:) = .false.
=> oasis_debug_note(subname//' share var info between models')
=> oasis_mpi_bcast(mynvar,mpi_comm_global,'mynvar',model_root(n))
=> oasis_mpi_bcast(myvar,mpi_comm_global,'myvar',model_root(n))
=> oasis_mpi_bcast(myops,mpi_comm_global,'myops',model_root(n))
=> oasis_debug_note(subname//' compare vars and namcouple')
=> oasis_debug_note(subname//' setup couplers')
=> oasis_mpi_barrier(mpi_comm_global)
=> oasis_debug_note(subname//' initialize coupling datatypes')
initialize avect1
=> mct_avect_init(prism_coupler(nc)%avect1,rList=trim(prism_coupler(nc)%fldlist),lsize=lsize)
=> mct_avect_zero(prism_coupler(nc)%avect1)
prism_coupler(nc)%aVon(1) = .true.
Mapping file :
if (prism_mapper(mapID)%init) then   ! mapper already initialized
else  ! read/generate mapping file
inquire(file=trim(prism_mapper(mapID)%file),exist=exists)
if (.not.exists) then   ! Create the file with SCRIP : the files areas.nc, grids.nc and masks.nc must be accessible
=> oasis_coupler_genmap(mapID,namID)
=> oasis_io_read_field_from_root : read the files areas.nc, grids.nc and masks.nc
=> grid_init
=> scrip : defined in oasis3-mct/lib/scrip/src
endif
=> oasis_mpi_bcast(gsize,mpi_comm_local,subname//' gsize')
=> oasis_part_create(part2,'1d',gsize,nx,ny,gridname)
=> oasis_timer_start('cpl_smatrd')
!-------------------------------
! smatreaddnc allocates sMati to nwgts
! then instantiate an sMatP for each set of wgts
! to support higher order mapping
!-------------------------------
=> oasis_coupler_smatreaddnc (sMati,prism_part(spart)%gsmap,prism_part(dpart)%gsmap,&  
                                                        trim(cstring),trim(prism_mapper(mapID)%file),mpi_rank_local,mpi_comm_local, nwgts)
=> mct_sMatP_Init(prism_mapper(mapID)%sMatP(n), sMati(n), prism_part(spart)%gsmap, prism_part(dpart)%gsmap, 0, mpi_comm_local, compid)
=> mct_sMat_Clean(sMati(n))
=> oasis_timer_stop('cpl_smatrd')
endif  ! generation of remapping file
if (.not.prism_mapper(mapID)%AVred .and. prism_coupler(nc)%conserv /= ip_cnone) then
=>
mct_avect_init(prism_mapper(mapID)%av_ms,iList='mask',rList='area',lsize=lsize)
        => mct_avect_zero(prism_mapper(mapID)%av_ms)
=> oasis_io_read_avfld('masks.nc',prism_mapper(mapID)%av_ms, prism_part(spart)%gsmap,'mask',trim(gridname)//'.msk',fldtype='int')
=> oasis_io_read_avfld('areas.nc',prism_mapper(mapID)%av_ms, prism_part(spart)%gsmap,'area',trim(gridname)//'.srf',fldtype='real')
=> mct_avect_init(prism_mapper(mapID)%av_md,iList='mask',rList='area',lsize=lsize)
=> mct_avect_zero(prism_mapper(mapID)%av_md)
=> oasis_io_read_avfld('masks.nc',prism_mapper(mapID)%av_md, prism_part(dpart)%gsmap,'mask',trim(gridname)//'.msk',fldtype='int')
=> oasis_io_read_avfld('areas.nc',prism_mapper(mapID)%av_md, prism_part(dpart)%gsmap,'area',trim(gridname)//'.srf',fldtype='real')
endif
initialize avect1m
=> mct_avect_init(prism_coupler(nc)%avect1m,rList=trim(prism_coupler(nc)%fldlist),lsize=lsize)
=> mct_avect_zero(prism_coupler(nc)%avect1m)
if (prism_coupler(nc)%sndrcv) then
=> mct_router_init(prism_coupler(nc)%comp,prism_part(rpart)%gsmap, mpi_comm_local,prism_router(prism_coupler(nc)%routerID)%router)
endif
=> oasis_coupler_print(nc)
=> oasis_timer_stop('cpl_setup')
=> oasis_debug_exit(subname)
=> oasis_advance_init (lkinfo) : read the restart fields and the loctrans fields if necessary
=> oasis_debug_enter(subname)
=> oasis_timer_start ('advance_init')
=> oasis_debug_note(subname//' loop over cplid')
Loop cplid = 1,prism_ncoupler
if (getput == PRISM_PUT .and. lag > 0) then  (reading of the restart file)
=> oasis_debug_note(subname//' check for lag restart')
=> mct_aVect_init (avtmp,rlist=prism_coupler(cplid)%fldlist,lsize=lsize)
=> oasis_io_read_avfile(trim(rstfile),avtmp,prism_part(partid)%gsmap)
=> mct_aVect_init(avtmp2,rlist=prism_coupler(cplid)%fldlist,lsize=lsize)
=> oasis_io_read_avfile(trim(rstfile),avtmp2,prism_part(partid)%gsmap, abort=.false.,nampre='av2_',didread=a2on)
...
=> mct_aVect_init(avtmp5,rlist=prism_coupler(cplid)%fldlist,lsize=lsize)
=> oasis_io_read_avfile(trim(rstfile),avtmp5,prism_part(partid)%gsmap, abort=.false.,nampre='av5_',didread=a5on)
=> oasis_advance_run(OASIS_Out,varid,msec,array,kinfo,readrest=.true., &
               a2on=a2on,array2=array2,a3on=a3on,array3=array3, &
               a4on=a4on,array4=array4,a5on=a5on,array5=array5)        !!! see description below in oasis_put/get
array2 allocated and given a value only if a2on=.true. , etc ...
=> mct_avect_clean(avtmp) + deallocation array
=> if a2on=.true. then mct_avect_clean(avtmp2) + deallocation array2
...
=> if a5on=.true. then mct_avect_clean(avtmp5) + deallocation array5
endif
if (getput == PRISM_PUT .and. prism_coupler(cplid)%trans /= ip_instant) then  (reading of the restart LOCTRANS file)
=> oasis_debug_note(subname//' check for loctrans restart')
=> oasis_io_read_array(rstfile,iarray=prism_coupler(cplid)%avcnt, ivarname=trim(vstring),abort=.false.) ! read the number of counts
=> oasis_io_read_avfile(rstfile,prism_coupler(cplid)%avect1, prism_part(partid)%gsmap,abort=.false.,nampre=trim(vstring)) ! read the loctrans restart
=> mct_aVect_init(prism_coupler(cplid)%aVect2,prism_coupler(cplid)%aVect1,lsize)
=> mct_aVect_zero(prism_coupler(cplid)%aVect2)
=> oasis_io_read_avfile(rstfile,prism_coupler(cplid)%avect2,prism_part(partid)%gsmap,abort=.false.,nampre=trim(vstring),&
                                          didread=prism_coupler(cplid)%aVon(2))
if (.not. prism_coupler(cplid)%aVon(2)) then  call mct_aVect_clean(prism_coupler(cplid)%avect2)
...
=> mct_aVect_init(prism_coupler(cplid)%aVect5,prism_coupler(cplid)%aVect1,lsize)
=> mct_aVect_zero(prism_coupler(cplid)%aVect5)
=> oasis_io_read_avfile(rstfile,prism_coupler(cplid)%avect5,prism_part(partid)%gsmap,abort=.false.,nampre=trim(vstring),&
                                          didread=prism_coupler(cplid)%aVon(5))
if (.not. prism_coupler(cplid)%aVon(5)) then  call mct_aVect_clean(prism_coupler(cplid)%avect5)
endif
end Loop
=> oasis_timer_stop ('advance_init')
=> oasis_debug_exit(subname)
=> oasis_debug_exit(subname)

oasis_put:  == oasis_put (id_port_id,kstep,wr_field,kinfo)
=> oasis_advance_run (PRISM_Out,nfld,kstep,array,kinfo)
if (getput == PRISM_PUT .and. lag > 0) then
=> oasis_timer_start (tstring)
=> oasis_io_write_avfile(rstfile,prism_coupler(cplid)%avect1,prism_part(partid)%gsmap,nx,ny)
=> oasis_timer_stop (tstring)
endif
if (sndrcv) then
if (getput == PRISM_PUT) then
if (snddiag) then
=> oasis_advance_avdiag(prism_coupler(cplid)%avect1,mpi_comm_local)
endif
if (mapid > 0) then
=> oasis_timer_start(tstring)
=> mct_avect_zero(prism_coupler(cplid)%avect2)
=> oasis_advance_map(prism_coupler(cplid)%avect1,prism_coupler(cplid)%avect2,prism_mapper(mapid),conserv)
=> oasis_timer_stop(tstring)
=> oasis_timer_start(tstring)
=> mct_waitsend(prism_router(rouid)%router)
=> mct_isend(prism_coupler(cplid)%avect2,prism_router(rouid)%router,tag)
=> oasis_timer_stop(tstring)
else !mapid
=> oasis_timer_start(tstring)
=> mct_waitsend(prism_router(rouid)%router)
=> mct_isend(prism_coupler(cplid)%avect1,prism_router(rouid)%router,tag)
=> oasis_timer_stop(tstring)
endif
endif
endif
if (output) then
=> oasis_timer_start(tstring)
=> oasis_io_write_avfbf(prism_coupler(cplid)%avect1,prism_part(partid)%gsmap,nx,ny,msec,fstring)
=> oasis_timer_stop(tstring)
endif

oasis_get: == oasis_get (id_port_id,kstep,rd_field,kinfo)
=> oasis_advance_run (PRISM_In,nfld,kstep,array,kinfo)

oasis_terminate:
=> oasis_debug_enter
=> oasis_timer_stop('total after init') ! In file *timer*, give the total time without initialisation (ie reading namcouple ...)
=> oasis_timer_print()
=> oasis_mpi_barrier(mpi_comm_global)
=> oasis_debug_exit