Changeset 638
- Timestamp:
- 12/18/17 12:33:31 (6 years ago)
- Location:
- codes/icosagcm/devel/src/unstructured
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/devel/src/unstructured/caldyn_unstructured.F90
r635 r638 2 2 USE ISO_C_BINDING 3 3 USE OMP_LIB 4 #ifdef CPP_USING_XIOS 5 USE xios 6 #endif 4 USE data_unstructured_mod 7 5 IMPLICIT NONE 8 PRIVATE9 6 SAVE 7 8 CONTAINS 9 10 #define INDICES1 ij,l,iq,iedge,edge,ivertex,vertex,ij_left,ij_right 11 #define INDICES2 ij_up,ij_down,itrisk,edge_trisk,kup,kdown 12 #define DECLARE_INDICES INTEGER INDICES1,INDICES2 13 #define PHI_BOT(ij) Phi_bot 14 #define PHI_BOT_VAR 0. 10 15 11 16 #define BINDC_(thename) BIND(C, name=#thename) 12 17 #define BINDC(thename) BINDC_(dynamico_ ## thename) 13 ! 18 14 19 #define DBL REAL(C_DOUBLE) 15 20 #define DOUBLE1(m) DBL, DIMENSION(m) 16 21 #define DOUBLE2(m,n) DBL, DIMENSION(m,n) 17 22 #define DOUBLE3(m,n,p) DBL, DIMENSION(m,n,p) 18 #define INDEX INTEGER(C_INT)19 #define PHI_BOT(ij) Phi_bot20 #define PHI_BOT_VAR 0.21 !22 INTEGER, PARAMETER :: eta_mass=1, eta_lag=2, &23 thermo_theta=1, thermo_entropy=2, thermo_moist=3, thermo_boussinesq=4, &24 caldyn_vert_cons=125 INTEGER(C_INT), BIND(C) :: caldyn_thermo=thermo_theta, caldyn_eta=eta_lag, &26 caldyn_vert_variant=caldyn_vert_cons, nb_threads=027 LOGICAL(C_BOOL), BIND(C) :: hydrostatic=.TRUE., debug_hevi_solver=.TRUE., rigid=.TRUE.28 !29 INDEX, BIND(C) :: llm, nqdyn, edge_num, primal_num, dual_num, &30 max_primal_deg, max_dual_deg, max_trisk_deg31 INDEX, ALLOCATABLE, PRIVATE :: & ! deg(ij) = nb of vertices = nb of edges of primal/dual cell ij32 primal_deg(:), primal_edge(:,:), primal_vertex(:,:), primal_ne(:,:), &33 dual_deg(:), dual_edge(:,:), dual_vertex(:,:), dual_ne(:,:), &34 trisk_deg(:), trisk(:,:), &35 left(:), right(:), up(:), down(:)36 ! left and right are adjacent primal cells37 ! flux is positive when going from left to right38 ! up and down are adjacent dual cells39 ! circulation is positive when going from down to up40 !41 DBL, BIND(C) :: elapsed, g, ptop, cpp, cppv, Rd, Rv, preff, Treff, &42 pbot, Phi_bot, rho_bot43 DBL :: kappa44 DOUBLE1(:), ALLOCATABLE, PRIVATE :: le_de, fv, Av, Ai45 DOUBLE2(:,:), ALLOCATABLE, PRIVATE :: Riv2, wee, ap,bp, mass_bl, mass_dak, mass_dbk46 !47 INTEGER(C_INT), BIND(C) :: comm_icosa48 49 #ifdef CPP_USING_XIOS50 TYPE(xios_context) :: ctx_hdl51 #endif52 53 CONTAINS54 !55 !-------------------------------------- KERNELS --------------------------------------56 !57 !58 #define DECLARE_INDICES INTEGER ij,l,iq,iedge,edge,ivertex,vertex,ij_left,ij_right,ij_up,ij_down,itrisk,edge_trisk,kup,kdown59 23 60 24 #define FIELD_PS DOUBLE1(primal_num) … … 65 29 #define FIELD_THETA DOUBLE3(llm, primal_num, nqdyn) 66 30 #define FIELD_GEOPOT DOUBLE2(llm+1, primal_num) 67 ! 31 68 32 #define HASNAN(field) (ANY(.NOT.ABS(field)<1e20)) 69 !70 SUBROUTINE caldyn_unstructured(tau, mass_col,rhodz,theta_rhodz,u,geopot,w, & ! IN : flow state71 theta,ps,pk,hflux,qv, & ! OUT : diags (except surface geopot : IN)72 dmass_col,drhodz,dtheta_rhodz,du_fast,du_slow, &73 dPhi_fast, dPhi_slow, dW_fast, dW_slow) BINDC(caldyn_unstructured) ! OUT : tendencies74 DBL, VALUE :: tau75 FIELD_MASS :: rhodz, drhodz, pk, berni ! IN, OUT, DIAG76 FIELD_THETA :: theta_rhodz, dtheta_rhodz, theta ! IN, OUT, DIAG77 FIELD_GEOPOT :: wflux, w, geopot, & ! DIAG, INOUT78 dPhi_fast, dPhi_slow, dW_fast, dW_slow ! OUT79 FIELD_U :: u,du_fast,du_slow,hflux,qu ! INOUT,OUT,OUT,DIAG80 FIELD_Z :: qv ! DIAG81 FIELD_PS :: ps,dmass_col,mass_col ! OUT,OUT,IN (if eta_mass) or OUT,UNUSED,UNUSED (if eta_lag)82 DOUBLE2(llm+1, edge_num) :: wwuu83 DBL :: time1,time284 INTEGER :: ij85 33 86 ! CALL CPU_TIME(time1) 87 time1=OMP_GET_WTIME() 34 !----------------------------- Non-Hydrostatic ----------------------------- 88 35 89 IF(hydrostatic) THEN90 91 !$OMP PARALLEL NUM_THREADS(nb_threads)92 !$OMP DO SCHEDULE(STATIC)93 DO ij=1,edge_num94 du_fast(:,ij)=0.95 du_slow(:,ij)=0.96 END DO97 !$OMP END DO98 CALL compute_theta(mass_col,rhodz,theta_rhodz, theta)99 CALL compute_geopot(rhodz,theta, ps,pk,geopot)100 101 CALL compute_caldyn_fast(tau, pk,berni,theta,geopot, du_fast,u)102 103 CALL compute_pvort_only(rhodz,u,qv,qu)104 CALL compute_caldyn_slow_hydro(rhodz,theta,u, berni,hflux,du_slow)105 CALL compute_coriolis(hflux,theta,qu, drhodz,dtheta_rhodz,du_slow)106 IF(caldyn_eta == eta_mass) THEN107 CALL caldyn_vert(drhodz,rhodz,theta,u, dmass_col,wflux,dtheta_rhodz,du_slow,wwuu)108 END IF109 !$OMP END PARALLEL110 111 ELSE ! NH112 DO ij=1,edge_num113 du_fast(:,ij)=0.114 du_slow(:,ij)=0.115 END DO116 DO ij=1,primal_num117 wflux(1,ij)=0.118 wflux(llm+1,ij)=0.119 END DO120 CALL compute_theta(mass_col,rhodz,theta_rhodz, theta)121 CALL compute_caldyn_solver(tau,rhodz,theta,pk,geopot,W,dPhi_fast,dW_fast,du_fast)122 CALL compute_caldyn_fast(tau, pk,berni,theta,geopot, du_fast,u)123 CALL compute_pvort_only(rhodz,u,qv,qu)124 CALL compute_caldyn_slow_NH(u,rhodz,geopot,W, hflux,du_slow,dPhi_slow,dW_slow)125 CALL compute_coriolis(hflux,theta,qu, drhodz,dtheta_rhodz,du_slow)126 IF(caldyn_eta == eta_mass) THEN127 CALL caldyn_vert(drhodz,rhodz,theta,u, dmass_col,wflux,dtheta_rhodz,du_slow,wwuu)128 CALL compute_caldyn_vert_NH(rhodz,geopot,W,wflux, du_slow,dPhi_slow,dW_slow)129 END IF130 END IF131 132 time2=OMP_GET_WTIME()133 ! CALL CPU_TIME(time2)134 elapsed = elapsed + time2-time1135 END SUBROUTINE caldyn_unstructured136 !137 !----------------------------- Non-Hydrostatic -----------------------------138 !139 36 SUBROUTINE compute_NH_geopot(tau,dummy, m_ik, m_il, theta, W_il, Phi_il) 140 37 FIELD_MASS :: m_ik, theta, p_ik, A_ik, C_ik ! IN*2,LOCAL*3 … … 145 42 #include "../kernels_unst/compute_NH_geopot.k90" 146 43 END SUBROUTINE compute_NH_geopot 147 ! 44 148 45 SUBROUTINE compute_caldyn_slow_NH(u,rhodz,Phi,W, hflux,du,dPhi,dW) 149 46 FIELD_U :: u, hflux, du ! IN, OUT, OUT … … 155 52 #include "../kernels_unst/caldyn_slow_NH.k90" 156 53 END SUBROUTINE compute_caldyn_slow_NH 157 ! 54 158 55 SUBROUTINE compute_caldyn_solver(tau,rhodz,theta,pk,geopot,W,dPhi,dW,du) 159 56 DBL, INTENT(IN) :: tau … … 166 63 #include "../kernels_unst/caldyn_solver.k90" 167 64 END SUBROUTINE compute_caldyn_solver 168 ! 65 169 66 SUBROUTINE compute_caldyn_vert_NH(mass,geopot,W,wflux, du,dPhi,dW) 170 67 FIELD_MASS :: mass, eta_dot, wcov, W_etadot … … 175 72 #include "../kernels_unst/caldyn_vert_NH.k90" 176 73 END SUBROUTINE compute_caldyn_vert_NH 177 ! 74 178 75 !----------------------------- Hydrostatic ------------------------------- 179 ! 76 180 77 SUBROUTINE compute_geopot(rhodz,theta,ps,pk,geopot) 181 78 FIELD_MASS :: rhodz,pk ! IN, OUT … … 197 94 #include "../kernels_unst/caldyn_slow_hydro.k90" 198 95 END SUBROUTINE compute_caldyn_slow_hydro 199 ! 96 200 97 !---------------------------------- Generic ------------------------------ 201 ! 98 202 99 SUBROUTINE caldyn_vert(convm,rhodz,theta,u, dmass_col,wflux,dtheta_rhodz,du, wwuu) 203 100 FIELD_PS :: dmass_col … … 214 111 #include "../kernels_unst/caldyn_vert.k90" 215 112 END SUBROUTINE caldyn_vert 216 ! 113 217 114 SUBROUTINE compute_coriolis(hflux,theta,qu, convm,dtheta_rhodz,du) 218 115 FIELD_U :: hflux, Ftheta, qu, du … … 223 120 #include "../kernels_unst/coriolis.k90" 224 121 END SUBROUTINE 225 ! 122 226 123 SUBROUTINE compute_theta(mass_col,rhodz,theta_rhodz, theta) 227 124 FIELD_PS :: mass_col … … 232 129 #include "../kernels_unst/theta.k90" 233 130 END SUBROUTINE 234 ! 131 235 132 SUBROUTINE compute_pvort_only(rhodz,u,qv,qu) 236 133 FIELD_MASS :: rhodz … … 241 138 #include "../kernels_unst/pvort_only.k90" 242 139 END SUBROUTINE compute_pvort_only 243 ! 140 244 141 SUBROUTINE compute_caldyn_fast(tau, pk,berni,theta,geopot, du,u) 245 142 DBL, INTENT(IN) :: tau … … 254 151 255 152 END SUBROUTINE compute_caldyn_fast 256 ! 153 257 154 !----------------------------- Unused ----------------------------- 258 ! 155 259 156 SUBROUTINE gradient(b,grad) BINDC(gradient) 260 157 DOUBLE2(llm,primal_num) :: b … … 273 170 !$OMP END PARALLEL 274 171 END SUBROUTINE 275 !276 !---------------------------- CONTEXT INITIALIZATION --------------------------277 !278 #define ALLOC1(v,n1) IF(ALLOCATED(v)) DEALLOCATE(v) ; ALLOCATE(v(n1))279 #define ALLOC2(v,n1,n2) IF(ALLOCATED(v)) DEALLOCATE(v) ; ALLOCATE(v(n1,n2))280 281 SUBROUTINE init_mesh( &282 primal_deg_, primal_edge_, primal_ne_, &283 dual_deg_, dual_edge_, dual_ne_, dual_vertex_, &284 left_, right_, up_, down_ ,&285 trisk_deg_, trisk_) BINDC(init_mesh)286 INDEX :: primal_deg_(primal_num), primal_edge_(max_primal_deg,primal_num), &287 primal_ne_(max_primal_deg,primal_num), &288 dual_deg_(dual_num), dual_edge_(max_dual_deg,dual_num), &289 dual_ne_(max_dual_deg,dual_num), &290 dual_vertex_(max_dual_deg,dual_num), &291 trisk_deg_(edge_num), trisk_(max_trisk_deg, edge_num)292 INDEX, DIMENSION(edge_num) :: left_, right_, down_, up_293 294 PRINT *, 'init_mesh ...'295 PRINT *, 'Primal mesh : ', primal_num, max_primal_deg296 PRINT *, 'Dual mesh : ', dual_num, max_dual_deg297 PRINT *, 'Edge mesh : ', edge_num, max_trisk_deg298 PRINT *, 'Vertical levels :', llm299 ALLOC1(primal_deg, primal_num)300 ALLOC2(primal_edge, max_primal_deg,primal_num)301 ALLOC2(primal_ne, max_primal_deg,primal_num)302 ALLOC1(dual_deg,dual_num)303 ALLOC2(dual_edge, max_dual_deg,dual_num)304 ALLOC2(dual_ne, max_dual_deg,dual_num)305 ALLOC2(dual_vertex, max_dual_deg,dual_num)306 ALLOC1(trisk_deg, edge_num)307 ALLOC2(trisk, max_trisk_deg, edge_num)308 PRINT *, SHAPE(trisk), edge_num309 ALLOC1(left, edge_num)310 ALLOC1(right, edge_num)311 ALLOC1(up, edge_num)312 ALLOC1(down, edge_num)313 primal_deg(:) = primal_deg_(:)314 primal_edge(:,:) = primal_edge_(:,:)315 primal_ne(:,:) = primal_ne_(:,:)316 dual_deg(:) = dual_deg_(:)317 dual_edge(:,:) = dual_edge_(:,:)318 dual_ne(:,:) = dual_ne_(:,:)319 dual_vertex(:,:) = dual_vertex_(:,:)320 IF(MINVAL(dual_deg)<3) THEN321 STOP 'At least one dual cell has less than 3 vertices'322 END IF323 IF(MINVAL(primal_deg)<3) THEN324 STOP 'At least one primal cell has less than 3 vertices'325 END IF326 left(:)=left_(:)327 right(:)=right_(:)328 down(:)=down_(:)329 up=up_(:)330 trisk_deg(:)=trisk_deg_(:)331 trisk(:,:)=trisk_(:,:)332 PRINT *, MAXVAL(primal_edge), edge_num333 PRINT *, MAXVAL(dual_edge), edge_num334 PRINT *, MAXVAL(dual_vertex), dual_num335 PRINT *, MAXVAL(trisk), edge_num336 PRINT *, MAX(MAXVAL(left),MAXVAL(right)), primal_num337 PRINT *, MAX(MAXVAL(up),MAXVAL(down)), dual_num338 PRINT *, SHAPE(trisk), edge_num339 PRINT *,' ... Done.'340 END SUBROUTINE init_mesh341 342 SUBROUTINE init_metric(Ai_, Av_, fv_, le_de_, Riv2_, wee_) BINDC(init_metric)343 DOUBLE1(primal_num) :: Ai_344 DOUBLE1(dual_num) :: Av_, fv_345 DOUBLE1(edge_num) :: le_de_346 DOUBLE2(max_dual_deg,dual_num) :: Riv2_347 DOUBLE2(max_trisk_deg,edge_num) :: wee_348 PRINT *, 'init_metric ...'349 ALLOC1(Ai,primal_num)350 ALLOC1(Av,dual_num)351 ALLOC1(fv,dual_num)352 ALLOC1(le_de,edge_num)353 ALLOC2(Riv2, max_dual_deg, dual_num)354 ALLOC2(wee, max_trisk_deg, edge_num)355 Ai(:) = Ai_(:)356 Av(:) = Av_(:)357 fv(:) = fv_(:)358 le_de(:) = le_de_(:)359 Riv2(:,:)=Riv2_(:,:)360 wee(:,:) = wee_(:,:)361 PRINT *, MAXVAL(ABS(Ai))362 PRINT *, MAXVAL(ABS(Av))363 PRINT *, MAXVAL(ABS(fv))364 PRINT *, MAXVAL(ABS(le_de))365 PRINT *, MAXVAL(ABS(Riv2))366 PRINT *, MAXVAL(ABS(wee))367 PRINT *, MINVAL(right), MAXVAL(right)368 PRINT *, MINVAL(right), MAXVAL(left)369 PRINT *,' ... Done.'370 IF(nb_threads==0) nb_threads=OMP_GET_MAX_THREADS()371 PRINT *,'OpenMP : max_threads, num_procs, nb_threads', OMP_GET_MAX_THREADS(), omp_get_num_procs(), nb_threads372 373 END SUBROUTINE init_metric374 !375 SUBROUTINE init_params() BINDC(init_params)376 PRINT *, 'Setting physical parameters ...'377 IF(hydrostatic) THEN378 PRINT *, 'Hydrostatic dynamics (HPE)'379 ELSE380 PRINT *, 'Non-hydrostatic dynamics (Euler)'381 END IF382 kappa = Rd/cpp383 PRINT *, 'g = ',g384 PRINT *, 'preff = ',preff385 PRINT *, 'Treff = ',Treff386 PRINT *, 'Rd = ',Rd387 PRINT *, 'cpp = ',cpp388 PRINT *, 'kappa = ',kappa389 PRINT *, '... Done'390 END SUBROUTINE init_params391 !392 SUBROUTINE init_hybrid(bl,dak,dbk) BINDC(init_hybrid)393 DOUBLE2(llm+1, primal_num) :: bl394 DOUBLE2(llm, primal_num) :: dak,dbk395 PRINT *, 'Setting hybrid coefficients ...'396 ALLOC2(mass_bl, llm+1, primal_num)397 ALLOC2(mass_dak, llm, primal_num)398 ALLOC2(mass_dbk, llm, primal_num)399 mass_bl(:,:) = bl(:,:)400 mass_dak(:,:) = dak(:,:)401 mass_dbk(:,:) = dbk(:,:)402 PRINT *, '... Done, llm = ', llm403 END SUBROUTINE Init_hybrid404 405 !---------------------------------------------- XIOS -----------------------------------------406 407 #ifdef CPP_USING_XIOS408 409 SUBROUTINE setup_xios() BINDC(setup_xios)410 ! MPI_INIT / MPI_finalize are assumed to be called BEFORE/AFTER this routine411 ! This is the case when calling from Python after importing mpi4py412 INTEGER :: ierr, mpi_threading_mode413 414 PRINT *, 'Initialize XIOS and obtain our communicator'415 CALL xios_initialize("icosagcm",return_comm=comm_icosa)416 417 PRINT *, 'Initialize our XIOS context'418 419 CALL xios_context_initialize("icosagcm",comm_icosa)420 CALL xios_get_handle("icosagcm",ctx_hdl)421 CALL xios_set_current_context(ctx_hdl)422 ! CALL xios_set_axis_attr("lev",n_glo=llm ,value=lev_value) ;423 ! CALL xios_set_axis_attr("levp1",n_glo=llm+1 ,value=lev_valuep1) ;424 ! CALL xios_set_axis_attr("nq",n_glo=nqtot, value=nq_value) ;425 ! CALL xios_set_domaingroup_attr("i",ni_glo=ncell_tot, ibegin=displ, ni=ncell)426 ! CALL xios_set_domaingroup_attr("i", data_dim=1, type='unstructured' , nvertex=6, i_index=ind_glo)427 ! CALL xios_set_domaingroup_attr("i",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)428 ! CALL xios_set_domain_attr("u",ni_glo=ncell_tot, ibegin=displ, ni=ncell)429 ! CALL xios_set_domain_attr("u", data_dim=1, type='unstructured' , nvertex=2, i_index=ind_glo)430 ! CALL xios_set_domain_attr("u",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)431 ! CALL xios_set_domain_attr("v",ni_glo=ncell_tot, ibegin=displ, ni=ncell)432 ! CALL xios_set_domain_attr("v", data_dim=1, type='unstructured' , nvertex=3)433 ! CALL xios_set_domain_attr("v",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)434 ! CALL xios_set_timestep(dtime)435 ! CALL xios_set_fieldgroup_attr("standard_output", freq_op=itau_out*xios_timestep, freq_offset=(itau_out-1)*xios_timestep)436 ! CALL xios_close_context_definition()437 438 ! PRINT *, 'Read data'439 ! CALL xios_recv_field(name,field)440 441 ! PRINT *,'Write data'442 ! CALL xios_send_field(name,field_tmp)443 444 ! PRINT *, 'Flush to disk, clean up and die'445 ! CALL xios_context_finalize446 END SUBROUTINE setup_xios447 !448 SUBROUTINE call_xios_set_timestep(dt) BINDC(xios_set_timestep)449 DBL, VALUE :: dt450 TYPE(xios_duration) :: dtime451 dtime%second=dt452 CALL xios_set_timestep(dtime)453 END SUBROUTINE call_xios_set_timestep454 455 SUBROUTINE call_xios_update_calendar(step) BINDC(xios_update_calendar)456 INDEX, value :: step457 CALL xios_update_calendar(step)458 END SUBROUTINE call_xios_update_calendar459 460 #endif461 172 462 173 END MODULE caldyn_unstructured_mod
Note: See TracChangeset
for help on using the changeset viewer.