30 use fckit_mpi_module,
only: fckit_mpi_sum,fckit_mpi_min,fckit_mpi_max
36 real(kind_real),
parameter ::
sqrt_r = 0.721_kind_real
38 real(kind_real),
parameter ::
sqrt_rfac = 0.9_kind_real
39 real(kind_real),
parameter ::
sqrt_coef = 0.54_kind_real
40 real(kind_real),
parameter ::
s_inf = 1.0e-2_kind_real
41 real(kind_real),
parameter ::
tol = 1.0e-3_kind_real
48 integer,
allocatable :: bd_to_c1(:)
49 integer,
allocatable :: bd_to_l1(:)
50 real(kind_real),
allocatable :: val(:)
61 character(len=1024) :: name
63 logical :: anisotropic
67 integer,
allocatable :: vbot(:)
68 integer,
allocatable :: vtop(:)
69 integer,
allocatable :: nc2(:)
80 logical,
allocatable :: llev(:)
83 integer,
allocatable :: s_to_c1(:)
84 integer,
allocatable :: s_to_l1(:)
85 integer,
allocatable :: c1_to_c0(:)
86 integer,
allocatable :: l1_to_l0(:)
87 integer,
allocatable :: c0_to_c1(:)
88 integer,
allocatable :: l0_to_l1(:)
89 logical,
allocatable :: mask_c1(:,:)
90 logical,
allocatable :: mask_c2(:,:)
91 integer,
allocatable :: c1l1_to_s(:,:)
92 integer,
allocatable :: c1_to_proc(:)
93 integer,
allocatable :: s_to_proc(:)
100 logical,
allocatable :: lcheck_sa(:)
101 logical,
allocatable :: lcheck_sb(:)
102 logical,
allocatable :: lcheck_sc(:)
103 integer,
allocatable :: c1a_to_c1(:)
104 integer,
allocatable :: c1_to_c1a(:)
105 integer,
allocatable :: c1b_to_c1(:)
106 integer,
allocatable :: c1_to_c1b(:)
107 integer,
allocatable :: c1bl1_to_sb(:,:)
108 integer,
allocatable :: interph_lg(:,:)
109 integer,
allocatable :: interps_lg(:,:)
110 integer,
allocatable :: c1a_to_c0a(:)
111 integer,
allocatable :: sa_to_c0a(:)
112 integer,
allocatable :: sa_to_l0(:)
113 integer,
allocatable :: sa_to_sb(:)
114 integer,
allocatable :: sc_to_sb(:)
115 integer,
allocatable :: sa_to_s(:)
116 integer,
allocatable :: s_to_sa(:)
117 integer,
allocatable :: sb_to_s(:)
118 integer,
allocatable :: s_to_sb(:)
119 integer,
allocatable :: sc_to_s(:)
120 integer,
allocatable :: s_to_sc(:)
121 integer,
allocatable :: sbb_to_s(:)
122 integer,
allocatable :: c1_to_c1bb(:)
123 integer,
allocatable :: c1bb_to_c1(:)
126 real(kind_real) :: rhmax
127 real(kind_real),
allocatable :: rh_c1(:,:)
128 real(kind_real),
allocatable :: rv_c1(:,:)
129 real(kind_real),
allocatable :: h11_c1(:,:)
130 real(kind_real),
allocatable :: h22_c1(:,:)
131 real(kind_real),
allocatable :: h33_c1(:,:)
132 real(kind_real),
allocatable :: h12_c1(:,:)
141 integer,
allocatable :: sc_nor_to_s(:)
142 integer,
allocatable :: s_to_sc_nor(:)
143 integer,
allocatable :: sb_to_sc_nor(:)
161 integer,
allocatable :: sa_to_sc(:)
162 integer,
allocatable :: sb_to_sc(:)
173 integer,
allocatable :: sb_to_c1b(:)
174 integer,
allocatable :: sb_to_l1(:)
177 real(kind_real),
allocatable :: norm(:,:)
180 real(kind_real),
allocatable :: coef_ens(:,:)
181 real(kind_real) :: wgt
239 class(balldata_type),
intent(inout) :: balldata
242 allocate(balldata%bd_to_c1(balldata%nbd))
243 allocate(balldata%bd_to_l1(balldata%nbd))
244 allocate(balldata%val(balldata%nbd))
257 class(balldata_type),
intent(inout) :: balldata
260 if (
allocated(balldata%bd_to_c1))
deallocate(balldata%bd_to_c1)
261 if (
allocated(balldata%bd_to_l1))
deallocate(balldata%bd_to_l1)
262 if (
allocated(balldata%val))
deallocate(balldata%val)
275 class(balldata_type),
intent(inout) :: balldata
276 integer,
intent(in) :: nc1
277 integer,
intent(in) :: nl1
278 real(kind_real),
intent(in) :: val(nc1,nl1)
281 integer :: ibd,ic1,il1
295 balldata%bd_to_c1(ibd) = ic1
296 balldata%bd_to_l1(ibd) = il1
297 balldata%val(ibd) = val(ic1,il1)
313 class(nicas_blk_type),
intent(inout) :: nicas_blk
314 type(nam_type),
target,
intent(in) :: nam
315 type(geom_type),
target,
intent(in) :: geom
318 integer :: il0,il1,its,isbb
321 if (
allocated(nicas_blk%vbot))
deallocate(nicas_blk%vbot)
322 if (
allocated(nicas_blk%vtop))
deallocate(nicas_blk%vtop)
323 if (
allocated(nicas_blk%nc2))
deallocate(nicas_blk%nc2)
324 if (
allocated(nicas_blk%hfull))
then 326 call nicas_blk%hfull(il0)%dealloc
328 deallocate(nicas_blk%hfull)
330 call nicas_blk%vfull%dealloc
331 if (
allocated(nicas_blk%sfull))
then 332 do il1=1,nicas_blk%nl1
333 call nicas_blk%sfull(il1)%dealloc
335 deallocate(nicas_blk%sfull)
337 if (
allocated(nicas_blk%llev))
deallocate(nicas_blk%llev)
338 if (
allocated(nicas_blk%s_to_c1))
deallocate(nicas_blk%s_to_c1)
339 if (
allocated(nicas_blk%s_to_l1))
deallocate(nicas_blk%s_to_l1)
340 if (
allocated(nicas_blk%c1_to_c0))
deallocate(nicas_blk%c1_to_c0)
341 if (
allocated(nicas_blk%l1_to_l0))
deallocate(nicas_blk%l1_to_l0)
342 if (
allocated(nicas_blk%c0_to_c1))
deallocate(nicas_blk%c0_to_c1)
343 if (
allocated(nicas_blk%l0_to_l1))
deallocate(nicas_blk%l0_to_l1)
344 if (
allocated(nicas_blk%mask_c1))
deallocate(nicas_blk%mask_c1)
345 if (
allocated(nicas_blk%mask_c2))
deallocate(nicas_blk%mask_c2)
346 if (
allocated(nicas_blk%c1l1_to_s))
deallocate(nicas_blk%c1l1_to_s)
347 if (
allocated(nicas_blk%c1_to_proc))
deallocate(nicas_blk%c1_to_proc)
348 if (
allocated(nicas_blk%s_to_proc))
deallocate(nicas_blk%s_to_proc)
349 if (
allocated(nicas_blk%lcheck_sa))
deallocate(nicas_blk%lcheck_sa)
350 if (
allocated(nicas_blk%lcheck_sb))
deallocate(nicas_blk%lcheck_sb)
351 if (
allocated(nicas_blk%lcheck_sc))
deallocate(nicas_blk%lcheck_sc)
352 if (
allocated(nicas_blk%c1a_to_c1))
deallocate(nicas_blk%c1a_to_c1)
353 if (
allocated(nicas_blk%c1_to_c1a))
deallocate(nicas_blk%c1_to_c1a)
354 if (
allocated(nicas_blk%c1b_to_c1))
deallocate(nicas_blk%c1b_to_c1)
355 if (
allocated(nicas_blk%c1_to_c1b))
deallocate(nicas_blk%c1_to_c1b)
356 if (
allocated(nicas_blk%c1bl1_to_sb))
deallocate(nicas_blk%c1bl1_to_sb)
357 if (
allocated(nicas_blk%interph_lg))
deallocate(nicas_blk%interph_lg)
358 if (
allocated(nicas_blk%interps_lg))
deallocate(nicas_blk%interps_lg)
359 if (
allocated(nicas_blk%c1a_to_c0a))
deallocate(nicas_blk%c1a_to_c0a)
360 if (
allocated(nicas_blk%sa_to_c0a))
deallocate(nicas_blk%sa_to_c0a)
361 if (
allocated(nicas_blk%sa_to_l0))
deallocate(nicas_blk%sa_to_l0)
362 if (
allocated(nicas_blk%sa_to_sb))
deallocate(nicas_blk%sa_to_sb)
363 if (
allocated(nicas_blk%sc_to_sb))
deallocate(nicas_blk%sc_to_sb)
364 if (
allocated(nicas_blk%sa_to_s))
deallocate(nicas_blk%sa_to_s)
365 if (
allocated(nicas_blk%s_to_sa))
deallocate(nicas_blk%s_to_sa)
366 if (
allocated(nicas_blk%sb_to_s))
deallocate(nicas_blk%sb_to_s)
367 if (
allocated(nicas_blk%s_to_sb))
deallocate(nicas_blk%s_to_sb)
368 if (
allocated(nicas_blk%sc_to_s))
deallocate(nicas_blk%sc_to_s)
369 if (
allocated(nicas_blk%s_to_sc))
deallocate(nicas_blk%s_to_sc)
370 if (
allocated(nicas_blk%sbb_to_s))
deallocate(nicas_blk%sbb_to_s)
371 if (
allocated(nicas_blk%c1_to_c1bb))
deallocate(nicas_blk%c1_to_c1bb)
372 if (
allocated(nicas_blk%c1bb_to_c1))
deallocate(nicas_blk%c1bb_to_c1)
373 if (
allocated(nicas_blk%rh_c1))
deallocate(nicas_blk%rh_c1)
374 if (
allocated(nicas_blk%rv_c1))
deallocate(nicas_blk%rv_c1)
375 if (
allocated(nicas_blk%H11_c1))
deallocate(nicas_blk%H11_c1)
376 if (
allocated(nicas_blk%H22_c1))
deallocate(nicas_blk%H22_c1)
377 if (
allocated(nicas_blk%H33_c1))
deallocate(nicas_blk%H33_c1)
378 if (
allocated(nicas_blk%H12_c1))
deallocate(nicas_blk%H12_c1)
379 if (
allocated(nicas_blk%Hcoef))
then 380 do isbb=1,nicas_blk%nsbb
381 call nicas_blk%Hcoef(isbb)%dealloc
383 deallocate(nicas_blk%Hcoef)
386 if (
allocated(nicas_blk%distnorm))
then 387 do isbb=1,nicas_blk%nsbb
388 call nicas_blk%distnorm(isbb)%dealloc
390 deallocate(nicas_blk%distnorm)
392 if (
allocated(nicas_blk%distnormv))
then 393 do isbb=1,nicas_blk%nsbb
394 call nicas_blk%distnormv(isbb)%dealloc
396 deallocate(nicas_blk%distnormv)
398 if (
allocated(nicas_blk%rfac))
then 399 do isbb=1,nicas_blk%nsbb
400 call nicas_blk%rfac(isbb)%dealloc
402 deallocate(nicas_blk%rfac)
404 if (
allocated(nicas_blk%coef))
then 405 do isbb=1,nicas_blk%nsbb
406 call nicas_blk%coef(isbb)%dealloc
408 deallocate(nicas_blk%coef)
410 if (
allocated(nicas_blk%sc_nor_to_s))
deallocate(nicas_blk%sc_nor_to_s)
411 if (
allocated(nicas_blk%s_to_sc_nor))
deallocate(nicas_blk%s_to_sc_nor)
412 if (
allocated(nicas_blk%sb_to_sc_nor))
deallocate(nicas_blk%sb_to_sc_nor)
413 call nicas_blk%c_nor%dealloc
414 call nicas_blk%kdtree%dealloc
415 if (
allocated(nicas_blk%sa_to_sc))
deallocate(nicas_blk%sa_to_sc)
416 if (
allocated(nicas_blk%sb_to_sc))
deallocate(nicas_blk%sb_to_sc)
417 call nicas_blk%c%dealloc
418 if (
allocated(nicas_blk%h))
then 420 call nicas_blk%h(il0)%dealloc
422 deallocate(nicas_blk%h)
424 call nicas_blk%v%dealloc
425 if (
allocated(nicas_blk%s))
then 426 do il1=1,nicas_blk%nl1
427 call nicas_blk%s(il1)%dealloc
429 deallocate(nicas_blk%s)
431 if (
allocated(nicas_blk%d))
then 434 call nicas_blk%d(il0,its)%dealloc
435 call nicas_blk%dinv(il0,its)%dealloc
438 deallocate(nicas_blk%d)
439 deallocate(nicas_blk%dinv)
441 if (
allocated(nicas_blk%sb_to_c1b))
deallocate(nicas_blk%sb_to_c1b)
442 if (
allocated(nicas_blk%sb_to_l1))
deallocate(nicas_blk%sb_to_l1)
443 if (
allocated(nicas_blk%norm))
deallocate(nicas_blk%norm)
444 if (
allocated(nicas_blk%coef_ens))
deallocate(nicas_blk%coef_ens)
445 if (
allocated(nicas_blk%sb_to_c1b))
deallocate(nicas_blk%sb_to_c1b)
446 call nicas_blk%com_AB%dealloc
447 call nicas_blk%com_AC%dealloc
448 call nicas_blk%com_AD%dealloc
449 call nicas_blk%com_ADinv%dealloc
462 class(nicas_blk_type),
intent(inout) :: nicas_blk
463 type(mpl_type),
intent(inout) :: mpl
464 type(rng_type),
intent(inout) :: rng
465 type(nam_type),
intent(in) :: nam
466 type(geom_type),
intent(in) :: geom
467 type(cmat_blk_type),
intent(in) :: cmat_blk
473 write(mpl%info,
'(a7,a)')
'',
'Compute adaptive sampling' 475 call nicas_blk%compute_sampling(mpl,rng,nam,geom,cmat_blk)
478 write(mpl%info,
'(a7,a)')
'',
'Compute horizontal interpolation data' 480 call nicas_blk%compute_interp_h(mpl,rng,nam,geom)
483 write(mpl%info,
'(a7,a)')
'',
'Compute vertical interpolation data' 485 call nicas_blk%compute_interp_v(geom)
488 write(mpl%info,
'(a7,a)')
'',
'Compute subsampling horizontal interpolation data' 490 call nicas_blk%compute_interp_s(mpl,rng,nam,geom)
493 write(mpl%info,
'(a7,a)')
'',
'Compute MPI distribution, halos A-B' 495 call nicas_blk%compute_mpi_ab(mpl,geom)
498 write(mpl%info,
'(a7,a)')
'',
'Compute convolution data' 500 call nicas_blk%compute_convol(mpl,rng,nam,geom,cmat_blk)
503 write(mpl%info,
'(a7,a)')
'',
'Compute MPI distribution, halo C' 505 call nicas_blk%compute_mpi_c(mpl,geom)
508 write(mpl%info,
'(a7,a)')
'',
'Compute normalization' 510 call nicas_blk%compute_normalization(mpl,nam,geom)
513 write(mpl%info,
'(a7,a,i4)')
'',
'Parameters for processor #',mpl%myproc
514 write(mpl%info,
'(a10,a,i8)')
'',
'nc0 = ',geom%nc0
515 write(mpl%info,
'(a10,a,i8)')
'',
'nc0a = ',geom%nc0a
516 write(mpl%info,
'(a10,a,i8)')
'',
'nl0 = ',geom%nl0
517 write(mpl%info,
'(a10,a,i8)')
'',
'nc1 = ',nicas_blk%nc1
518 write(mpl%info,
'(a10,a,i8)')
'',
'nc1a = ',nicas_blk%nc1a
519 write(mpl%info,
'(a10,a,i8)')
'',
'nc1b = ',nicas_blk%nc1b
520 write(mpl%info,
'(a10,a,i8)')
'',
'nl1 = ',nicas_blk%nl1
521 do il1=1,nicas_blk%nl1
522 write(mpl%info,
'(a10,a,i3,a,i8)')
'',
'nc2(',il1,
') = ',nicas_blk%nc2(il1)
524 write(mpl%info,
'(a10,a,i8)')
'',
'ns = ',nicas_blk%ns
525 write(mpl%info,
'(a10,a,i8)')
'',
'nsa = ',nicas_blk%nsa
526 write(mpl%info,
'(a10,a,i8)')
'',
'nsb = ',nicas_blk%nsb
527 write(mpl%info,
'(a10,a,i8)')
'',
'nsc = ',nicas_blk%nsc
529 write(mpl%info,
'(a10,a,i3,a,i8)')
'',
'h(',il0i,
')%n_s = ',nicas_blk%h(il0i)%n_s
531 write(mpl%info,
'(a10,a,i8)')
'',
'v%n_s = ',nicas_blk%v%n_s
532 do il1=1,nicas_blk%nl1
533 write(mpl%info,
'(a10,a,i3,a,i8)')
'',
's(',il1,
')%n_s = ',nicas_blk%s(il1)%n_s
535 write(mpl%info,
'(a10,a,i8)')
'',
'c%n_s = ',nicas_blk%c%n_s
536 write(mpl%info,
'(a10,a,i8)')
'',
'c_nor%n_s = ',nicas_blk%c_nor%n_s
550 class(nicas_blk_type),
intent(inout) :: nicas_blk
551 type(mpl_type),
intent(inout) :: mpl
552 type(rng_type),
intent(inout) :: rng
553 type(nam_type),
intent(in) :: nam
554 type(geom_type),
intent(in) :: geom
555 type(cmat_blk_type),
intent(in) :: cmat_blk
558 integer :: il0,il0_prev,il1,ic0,ic1,ic2,is,ic0a,iproc
559 integer :: ncid,nc1_id,nl1_id,lon_c1_id,lat_c1_id,mask_c2_id
560 integer,
allocatable :: c2_to_c1(:)
561 real(kind_real) :: rhs_sum(geom%nl0),rhs_avg(geom%nl0),rvs_sum(geom%nl0),rvs_avg(geom%nl0),norm(geom%nl0),distnorm(geom%nc0a)
562 real(kind_real) :: distnormmin,rv,rhs_minavg
563 real(kind_real),
allocatable :: rhs_min(:),rhs_min_glb(:),rhs_c0(:),rhs_c1(:)
564 real(kind_real),
allocatable :: lon_c1(:),lat_c1(:),mask_c2_real(:,:)
566 logical,
allocatable :: mask_hor_c0(:),mask_c1(:)
567 character(len=1024) :: filename
568 character(len=1024) :: subr =
'nicas_blk_compute_sampling' 571 allocate(rhs_min(geom%nc0a))
572 allocate(rhs_min_glb(geom%nc0))
573 allocate(nicas_blk%llev(geom%nl0))
576 if (trim(nam%strategy)==
'specific_multivariate')
call rng%reseed(mpl)
579 norm = 1.0/
real(geom%nc0_mask,kind_real)
580 rhs_sum = sum(cmat_blk%rhs,dim=1,mask=geom%mask_c0a)
581 call mpl%f_comm%allreduce(rhs_sum,rhs_avg,fckit_mpi_sum())
582 rhs_avg = rhs_avg*norm
583 rvs_sum = sum(cmat_blk%rvs,dim=1,mask=geom%mask_c0a)
584 call mpl%f_comm%allreduce(rvs_sum,rvs_avg,fckit_mpi_sum())
585 rvs_avg = rvs_avg*norm
586 write(mpl%info,
'(a10,a)')
'',
'Average support radii (H/V): ' 588 write(mpl%info,
'(a13,a,i3,a,f10.2,a,f10.2,a)')
'',
'Level ',nam%levs(il0),
': '//trim(mpl%aqua),rhs_avg(il0)*
reqkm, &
589 & trim(mpl%black)//
' km / '//trim(mpl%aqua),rvs_avg(il0),trim(mpl%black)//
' '//trim(mpl%vunitchar)
594 norm(1) = 1.0/
real(count(geom%mask_hor_c0),kind_real)
597 ic0 = geom%c0a_to_c0(ic0a)
599 if (geom%mask_c0(ic0,il0))
then 600 rhs_min(ic0a) =
min(cmat_blk%rhs(ic0a,il0),rhs_min(ic0a))
604 call mpl%f_comm%allreduce(sum(rhs_min,mask=geom%mask_hor_c0a),rhs_minavg,fckit_mpi_sum())
605 rhs_minavg = rhs_minavg*norm(1)
606 if (rhs_minavg>0.0)
then 607 nicas_blk%nc1 = floor(2.0*maxval(geom%area)*nam%resol**2/(sqrt(3.0)*rhs_minavg**2))
609 nicas_blk%nc1 = geom%nc0
611 nicas_blk%nc1 =
min(nicas_blk%nc1,geom%nc0)
612 write(mpl%info,
'(a10,a,i8)')
'',
'Estimated nc1 from horizontal support radius: ',nicas_blk%nc1
614 if (nicas_blk%nc1>
nc1max)
then 615 call mpl%warning(
'required nc1 larger than nc1max, resetting to nc1max')
617 write(mpl%info,
'(a10,a,f5.2)')
'',
'Effective horizontal resolution: ',sqrt(
real(nicas_blk%nc1,kind_real)*sqrt(3.0) &
618 & *rhs_minavg**2/(2.0*maxval(geom%area)))
621 if (nicas_blk%nc1<3)
call mpl%abort(
'nicas_blk%nc1 lower than 3')
624 allocate(nicas_blk%c1_to_c0(nicas_blk%nc1))
627 call mpl%loc_to_glb(geom%nc0a,rhs_min,geom%nc0,geom%c0_to_proc,geom%c0_to_c0a,.true.,rhs_min_glb)
630 write(mpl%info,
'(a7,a)',advance=
'no')
'',
'Compute horizontal subset C1: ' 634 allocate(mask_hor_c0(geom%nc0))
635 mask_hor_c0 = geom%mask_hor_c0
639 if (mpl%nproc==1)
call mpl%abort(
'at least 2 MPI tasks required for test_no_point')
641 iproc = geom%c0_to_proc(ic0)
642 if (iproc==mpl%nproc) mask_hor_c0(ic0) = .false.
647 call rng%initialize_sampling(mpl,geom%nc0,geom%lon,geom%lat,mask_hor_c0,rhs_min_glb,nam%ntry,nam%nrep, &
648 & nicas_blk%nc1,nicas_blk%c1_to_c0,fast=nam%fast_sampling)
649 nicas_blk%c1_to_proc = geom%c0_to_proc(nicas_blk%c1_to_c0)
652 allocate(nicas_blk%c0_to_c1(geom%nc0))
653 call msi(nicas_blk%c0_to_c1)
654 do ic1=1,nicas_blk%nc1
655 ic0 = nicas_blk%c1_to_c0(ic1)
656 nicas_blk%c0_to_c1(ic0) = ic1
660 write(mpl%info,
'(a7,a)',advance=
'no')
'',
'Compute vertical subset L1: ' 665 if ((il0==1).or.(il0==geom%nl0))
then 667 nicas_blk%llev(il0) = .true.
672 ic0 = geom%c0a_to_c0(ic0a)
673 if (geom%mask_c0(ic0,il0))
then 674 rv = sqrt(0.5*(cmat_blk%rvs(ic0a,il0)**2+cmat_blk%rvs(ic0a,il0_prev)**2))
675 if (rv>0.0) distnorm(ic0a) = abs(geom%vunit(ic0,il0)-geom%vunit(ic0,il0_prev))/rv
678 call mpl%f_comm%allreduce(minval(distnorm),distnormmin,fckit_mpi_min())
679 nicas_blk%llev(il0) = distnormmin>1.0/nam%resol
683 if (nicas_blk%llev(il0)) il0_prev = il0
685 nicas_blk%nl1 = count(nicas_blk%llev)
686 allocate(nicas_blk%l1_to_l0(nicas_blk%nl1))
689 if (nicas_blk%llev(il0))
then 690 write(mpl%info,
'(i3,a)',advance=
'no') nam%levs(il0),
' ' 693 nicas_blk%l1_to_l0(il1) = il0
696 write(mpl%info,
'(a)')
'' 700 allocate(nicas_blk%vbot(nicas_blk%nc1))
701 allocate(nicas_blk%vtop(nicas_blk%nc1))
703 do ic1=1,nicas_blk%nc1
704 ic0 = nicas_blk%c1_to_c0(ic1)
706 nicas_blk%vtop(ic1) = geom%nl0
707 do il1=1,nicas_blk%nl1
708 il0 = nicas_blk%l1_to_l0(il1)
709 if (.not.inside.and.geom%mask_c0(ic0,il0))
then 711 nicas_blk%vbot(ic1) = il0
714 if (inside.and.(.not.geom%mask_c0(ic0,il0)))
then 716 nicas_blk%vtop(ic1) = il0
720 if (nicas_blk%vbot(ic1)>nicas_blk%vtop(ic1))
call mpl%abort(
'non contiguous mask')
725 allocate(nicas_blk%l0_to_l1(geom%nl0))
726 call msi(nicas_blk%l0_to_l1)
727 do il1=1,nicas_blk%nl1
728 il0 = nicas_blk%l1_to_l0(il1)
729 nicas_blk%l0_to_l1(il0) = il1
733 allocate(nicas_blk%nc2(nicas_blk%nl1))
734 allocate(nicas_blk%mask_c2(nicas_blk%nc1,nicas_blk%nl1))
735 allocate(lon_c1(nicas_blk%nc1))
736 allocate(lat_c1(nicas_blk%nc1))
737 allocate(mask_c1(nicas_blk%nc1))
738 allocate(rhs_c0(geom%nc0))
739 allocate(rhs_c1(nicas_blk%nc1))
742 lon_c1 = geom%lon(nicas_blk%c1_to_c0)
743 lat_c1 = geom%lat(nicas_blk%c1_to_c0)
746 do il1=1,nicas_blk%nl1
747 write(mpl%info,
'(a7,a,i3,a)',advance=
'no')
'',
'Compute horizontal subset C2 (level ',il1,
'): ' 751 mask_c1 = geom%mask_c0(nicas_blk%c1_to_c0,il0)
754 il0 = nicas_blk%l1_to_l0(il1)
755 nicas_blk%nc2(il1) = floor(2.0*geom%area(il0)*nam%resol**2/(sqrt(3.0)*rhs_avg(il0)**2))
756 nicas_blk%nc2(il1) =
min(nicas_blk%nc2(il1),nicas_blk%nc1)
757 nicas_blk%nc2(il1) =
min(nicas_blk%nc2(il1),count(mask_c1))
758 if (nicas_blk%nc2(il1)<3)
call mpl%abort(
'nicas_blk%nc2 lower than 3')
760 if (nicas_blk%nc2(il1)<nicas_blk%nc1)
then 762 allocate(c2_to_c1(nicas_blk%nc2(il1)))
765 call mpl%loc_to_glb(geom%nc0a,cmat_blk%rhs(:,il0),geom%nc0,geom%c0_to_proc,geom%c0_to_c0a,.false.,rhs_c0)
766 rhs_c1 = rhs_c0(nicas_blk%c1_to_c0)
769 call rng%initialize_sampling(mpl,nicas_blk%nc1,lon_c1,lat_c1,mask_c1,rhs_c1,nam%ntry,nam%nrep,nicas_blk%nc2(il1),c2_to_c1, &
770 & fast=nam%fast_sampling)
773 nicas_blk%mask_c2(:,il1) = .false.
774 do ic2=1,nicas_blk%nc2(il1)
776 nicas_blk%mask_c2(ic1,il1) = .true.
783 write(mpl%info,
'(a)')
'use all C1 points' 788 nicas_blk%mask_c2(:,il1) = .true.
793 nicas_blk%ns = sum(nicas_blk%nc2)
796 allocate(nicas_blk%s_to_c1(nicas_blk%ns))
797 allocate(nicas_blk%s_to_l1(nicas_blk%ns))
798 allocate(nicas_blk%s_to_proc(nicas_blk%ns))
800 do il1=1,nicas_blk%nl1
801 do ic1=1,nicas_blk%nc1
802 if (nicas_blk%mask_c2(ic1,il1))
then 804 nicas_blk%s_to_c1(is) = ic1
805 nicas_blk%s_to_l1(is) = il1
806 nicas_blk%s_to_proc(is) = nicas_blk%c1_to_proc(ic1)
812 allocate(nicas_blk%c1l1_to_s(nicas_blk%nc1,nicas_blk%nl1))
813 call msi(nicas_blk%c1l1_to_s)
815 ic1 = nicas_blk%s_to_c1(is)
816 il1 = nicas_blk%s_to_l1(is)
817 nicas_blk%c1l1_to_s(ic1,il1) = is
823 allocate(lon_c1(nicas_blk%nc1))
824 allocate(lat_c1(nicas_blk%nc1))
825 allocate(mask_c2_real(nicas_blk%nc1,nicas_blk%nl1))
828 lon_c1 = geom%lon(nicas_blk%c1_to_c0)*
rad2deg 829 lat_c1 = geom%lat(nicas_blk%c1_to_c0)*
rad2deg 830 call msr(mask_c2_real)
831 do il1=1,nicas_blk%nl1
832 do ic1=1,nicas_blk%nc1
833 if (nicas_blk%mask_c2(ic1,il1)) mask_c2_real(ic1,il1) = 1.0
838 filename = trim(nam%prefix)//
'_'//trim(nicas_blk%name)//
'_grids.nc' 839 call mpl%ncerr(subr,nf90_create(trim(nam%datadir)//
'/'//trim(filename),or(nf90_clobber,nf90_64bit_offset),ncid))
842 call mpl%ncerr(subr,nf90_def_dim(ncid,
'nc1',nicas_blk%nc1,nc1_id))
843 call mpl%ncerr(subr,nf90_def_dim(ncid,
'nl1',nicas_blk%nl1,nl1_id))
846 call mpl%ncerr(subr,nf90_def_var(ncid,
'lon_c1',
ncfloat,(/nc1_id/),lon_c1_id))
847 call mpl%ncerr(subr,nf90_def_var(ncid,
'lat_c1',
ncfloat,(/nc1_id/),lat_c1_id))
848 call mpl%ncerr(subr,nf90_def_var(ncid,
'mask_c2',
ncfloat,(/nc1_id,nl1_id/),mask_c2_id))
849 call mpl%ncerr(subr,nf90_put_att(ncid,mask_c2_id,
'_FillValue',
msvalr))
852 call mpl%ncerr(subr,nf90_enddef(ncid))
855 call mpl%ncerr(subr,nf90_put_var(ncid,lon_c1_id,lon_c1))
856 call mpl%ncerr(subr,nf90_put_var(ncid,lat_c1_id,lat_c1))
857 call mpl%ncerr(subr,nf90_put_var(ncid,mask_c2_id,mask_c2_real))
860 call mpl%ncerr(subr,nf90_close(ncid))
865 deallocate(mask_c2_real)
879 class(nicas_blk_type),
intent(inout) :: nicas_blk
880 type(mpl_type),
intent(inout) :: mpl
881 type(rng_type),
intent(inout) :: rng
882 type(nam_type),
intent(in) :: nam
883 type(geom_type),
intent(in) :: geom
887 type(linop_type) :: hbase
890 allocate(nicas_blk%hfull(geom%nl0i))
894 call nicas_blk%hfull(il0i)%interp(mpl,rng,geom,il0i,nicas_blk%nc1,nicas_blk%c1_to_c0,nam%mask_check, &
895 & nicas_blk%vbot,nicas_blk%vtop,nam%nicas_interp,hbase)
909 class(nicas_blk_type),
intent(inout) :: nicas_blk
910 type(geom_type),
intent(in) :: geom
913 integer :: ic1,ic0,jl0,il0,jl1,il0inf,il0sup
916 nicas_blk%vfull%prefix =
'vfull' 917 nicas_blk%vfull%n_src = nicas_blk%nl1
918 nicas_blk%vfull%n_dst = geom%nl0
921 nicas_blk%vfull%n_s = nicas_blk%nl1
924 if (nicas_blk%llev(jl0))
then 926 do il0=il0inf+1,il0sup-1
927 nicas_blk%vfull%n_s = nicas_blk%vfull%n_s+2
932 call nicas_blk%vfull%alloc(nicas_blk%nc1)
934 do jl1=1,nicas_blk%nl1
935 jl0 = nicas_blk%l1_to_l0(jl1)
936 nicas_blk%vfull%row(jl1) = jl0
937 nicas_blk%vfull%col(jl1) = jl0
938 do ic1=1,nicas_blk%nc1
939 nicas_blk%vfull%Svec(jl1,ic1) = 1.0
943 nicas_blk%vfull%n_s = nicas_blk%nl1
946 if (nicas_blk%llev(jl0))
then 948 do il0=il0inf+1,il0sup-1
949 nicas_blk%vfull%n_s = nicas_blk%vfull%n_s+1
950 nicas_blk%vfull%row(nicas_blk%vfull%n_s) = il0
951 nicas_blk%vfull%col(nicas_blk%vfull%n_s) = il0inf
952 do ic1=1,nicas_blk%nc1
953 ic0 = nicas_blk%c1_to_c0(ic1)
954 nicas_blk%vfull%Svec(nicas_blk%vfull%n_s,ic1) = abs(geom%vunit(ic0,il0sup)-geom%vunit(ic0,il0)) &
955 & /abs(geom%vunit(ic0,il0sup)-geom%vunit(ic0,il0inf))
958 nicas_blk%vfull%n_s = nicas_blk%vfull%n_s+1
959 nicas_blk%vfull%row(nicas_blk%vfull%n_s) = il0
960 nicas_blk%vfull%col(nicas_blk%vfull%n_s) = il0sup
961 do ic1=1,nicas_blk%nc1
962 ic0 = nicas_blk%c1_to_c0(ic1)
963 nicas_blk%vfull%Svec(nicas_blk%vfull%n_s,ic1) = abs(geom%vunit(ic0,il0)-geom%vunit(ic0,il0inf)) &
964 & /abs(geom%vunit(ic0,il0sup)-geom%vunit(ic0,il0inf))
972 nicas_blk%vfull%col = nicas_blk%l0_to_l1(nicas_blk%vfull%col)
975 deallocate(nicas_blk%llev)
988 class(nicas_blk_type),
intent(inout) :: nicas_blk
989 type(mpl_type),
intent(inout) :: mpl
990 type(rng_type),
intent(inout) :: rng
991 type(nam_type),
intent(in) :: nam
992 type(geom_type),
intent(in) :: geom
996 real(kind_real) :: renorm(nicas_blk%nc1)
997 real(kind_real) :: lon_c1(nicas_blk%nc1),lat_c1(nicas_blk%nc1)
998 real(kind_real),
allocatable :: lon_row(:),lat_row(:),lon_col(:),lat_col(:)
999 logical :: mask_src(nicas_blk%nc1),mask_dst(nicas_blk%nc1)
1000 logical,
allocatable :: valid(:)
1001 type(linop_type) :: stmp
1004 allocate(nicas_blk%sfull(nicas_blk%nl1))
1006 do il1=1,nicas_blk%nl1
1008 write(nicas_blk%sfull(il1)%prefix,
'(a,i3.3)')
's_',il1
1009 nicas_blk%sfull(il1)%n_src = nicas_blk%nc1
1010 nicas_blk%sfull(il1)%n_dst = nicas_blk%nc1
1012 if (nicas_blk%nc2(il1)==nicas_blk%nc1)
then 1014 nicas_blk%sfull(il1)%n_s = nicas_blk%nc1
1015 call nicas_blk%sfull(il1)%alloc
1016 do i_s=1,nicas_blk%sfull(il1)%n_s
1017 nicas_blk%sfull(il1)%row(i_s) = i_s
1018 nicas_blk%sfull(il1)%col(i_s) = i_s
1019 nicas_blk%sfull(il1)%S(i_s) = 1.0
1023 lon_c1 = geom%lon(nicas_blk%c1_to_c0)
1024 lat_c1 = geom%lat(nicas_blk%c1_to_c0)
1025 mask_src = nicas_blk%mask_c2(:,il1)
1029 call stmp%interp(mpl,rng,nicas_blk%nc1,lon_c1,lat_c1,mask_src,nicas_blk%nc1,lon_c1,lat_c1,mask_dst,nam%nicas_interp)
1032 allocate(valid(stmp%n_s))
1035 if (nam%mask_check)
then 1036 write(mpl%info,
'(a10,a,i3,a)',advance=
'no')
'',
'Sublevel ',il1,
': ' 1037 call flush(mpl%info)
1040 allocate(lon_row(nicas_blk%nc1))
1041 allocate(lat_row(nicas_blk%nc1))
1042 allocate(lon_col(nicas_blk%nc1))
1043 allocate(lat_col(nicas_blk%nc1))
1046 lon_row = geom%lon(nicas_blk%c1_to_c0)
1047 lat_row = geom%lat(nicas_blk%c1_to_c0)
1048 lon_col = geom%lon(nicas_blk%c1_to_c0)
1049 lat_col = geom%lat(nicas_blk%c1_to_c0)
1052 call stmp%interp_check_mask(mpl,geom,valid,nicas_blk%l1_to_l0(il1),lon_row=lon_row,lat_row=lat_row, &
1053 & lon_col=lon_col,lat_col=lat_col)
1061 write(mpl%info,
'(a10,a,i3)')
'',
'Sublevel ',il1
1062 call flush(mpl%info)
1068 if (valid(i_s)) renorm(stmp%row(i_s)) = renorm(stmp%row(i_s))+stmp%S(i_s)
1072 nicas_blk%sfull(il1)%n_s = count(valid)
1073 call nicas_blk%sfull(il1)%alloc
1074 nicas_blk%sfull(il1)%n_s = 0
1076 if (valid(i_s))
then 1077 nicas_blk%sfull(il1)%n_s = nicas_blk%sfull(il1)%n_s+1
1078 nicas_blk%sfull(il1)%row(nicas_blk%sfull(il1)%n_s) = stmp%row(i_s)
1079 nicas_blk%sfull(il1)%col(nicas_blk%sfull(il1)%n_s) = stmp%col(i_s)
1080 nicas_blk%sfull(il1)%S(nicas_blk%sfull(il1)%n_s) = stmp%S(i_s)/renorm(stmp%row(i_s))
1089 call nicas_blk%sfull(il1)%interp_missing(mpl,nicas_blk%nc1,lon_c1,lat_c1,mask_dst,nam%nicas_interp)
1104 class(nicas_blk_type),
intent(inout) :: nicas_blk
1105 type(mpl_type),
intent(inout) :: mpl
1106 type(geom_type),
intent(in) :: geom
1109 integer :: il0i,ic0,ic0a,iproc,ic1,jc1,ic1a,ic1b,il0,il1,isa,isb,i_s,i_s_loc,is,js,h_n_s_max,s_n_s_max,h_n_s_max_loc,s_n_s_max_loc
1110 integer,
allocatable :: s_to_proc(:),interph_lg(:,:),interps_lg(:,:)
1111 integer,
allocatable :: proc_to_nc1a(:),proc_to_nsa(:)
1112 logical,
allocatable :: lcheck_c1a(:),lcheck_c1b_h(:),lcheck_c1b(:),lcheck_h(:,:),lcheck_s(:,:)
1117 h_n_s_max =
max(h_n_s_max,nicas_blk%hfull(il0i)%n_s)
1120 do il1=1,nicas_blk%nl1
1121 s_n_s_max =
max(s_n_s_max,nicas_blk%sfull(il1)%n_s)
1123 allocate(nicas_blk%h(geom%nl0i))
1124 allocate(nicas_blk%s(nicas_blk%nl1))
1125 allocate(lcheck_c1a(nicas_blk%nc1))
1126 allocate(lcheck_c1b_h(nicas_blk%nc1))
1127 allocate(lcheck_c1b(nicas_blk%nc1))
1128 allocate(nicas_blk%lcheck_sa(nicas_blk%ns))
1129 allocate(nicas_blk%lcheck_sb(nicas_blk%ns))
1130 allocate(lcheck_h(h_n_s_max,geom%nl0i))
1131 allocate(lcheck_s(s_n_s_max,nicas_blk%nl1))
1132 allocate(proc_to_nc1a(mpl%nproc))
1133 allocate(proc_to_nsa(mpl%nproc))
1134 allocate(s_to_proc(nicas_blk%ns))
1139 lcheck_c1a = .false.
1140 do ic1=1,nicas_blk%nc1
1141 ic0 = nicas_blk%c1_to_c0(ic1)
1142 if (geom%c0_to_proc(ic0)==mpl%myproc) lcheck_c1a(ic1) = .true.
1144 nicas_blk%lcheck_sa = .false.
1145 do is=1,nicas_blk%ns
1146 ic1 = nicas_blk%s_to_c1(is)
1147 ic0 = nicas_blk%c1_to_c0(ic1)
1148 if (geom%c0_to_proc(ic0)==mpl%myproc) nicas_blk%lcheck_sa(is) = .true.
1155 lcheck_c1b_h = .false.
1157 do i_s=1,nicas_blk%hfull(il0i)%n_s
1158 ic0 = nicas_blk%hfull(il0i)%row(i_s)
1159 iproc = geom%c0_to_proc(ic0)
1160 if (iproc==mpl%myproc)
then 1161 jc1 = nicas_blk%hfull(il0i)%col(i_s)
1162 lcheck_h(i_s,il0i) = .true.
1163 lcheck_c1b_h(jc1) = .true.
1169 nicas_blk%lcheck_sb = .false.
1171 lcheck_c1b = lcheck_c1b_h
1172 do il1=1,nicas_blk%nl1
1173 do i_s=1,nicas_blk%sfull(il1)%n_s
1174 ic1 = nicas_blk%sfull(il1)%row(i_s)
1175 if (lcheck_c1b_h(ic1))
then 1176 jc1 = nicas_blk%sfull(il1)%col(i_s)
1177 js = nicas_blk%c1l1_to_s(jc1,il1)
1178 lcheck_c1b(jc1) = .true.
1179 nicas_blk%lcheck_sb(js) = .true.
1180 lcheck_s(i_s,il1) = .true.
1186 do is=1,nicas_blk%ns
1187 if (nicas_blk%lcheck_sa(is).and.(.not.nicas_blk%lcheck_sb(is)))
call mpl%abort(
'point in halo A but not in halo B')
1191 nicas_blk%nc1a = count(lcheck_c1a)
1192 call mpl%f_comm%allgather(nicas_blk%nc1a,proc_to_nc1a)
1193 nicas_blk%nsa = count(nicas_blk%lcheck_sa)
1194 call mpl%f_comm%allgather(nicas_blk%nsa,proc_to_nsa)
1196 nicas_blk%h(il0i)%n_s = count(lcheck_h(:,il0i))
1198 nicas_blk%nc1b = count(lcheck_c1b)
1199 nicas_blk%nsb = count(nicas_blk%lcheck_sb)
1200 do il1=1,nicas_blk%nl1
1201 nicas_blk%s(il1)%n_s = count(lcheck_s(:,il1))
1207 allocate(nicas_blk%c1a_to_c1(nicas_blk%nc1a))
1208 allocate(nicas_blk%c1_to_c1a(nicas_blk%nc1))
1210 do ic1=1,nicas_blk%nc1
1211 if (lcheck_c1a(ic1))
then 1213 nicas_blk%c1a_to_c1(ic1a) = ic1
1216 call mpl%glb_to_loc_index(nicas_blk%nc1a,nicas_blk%c1a_to_c1,nicas_blk%nc1,nicas_blk%c1_to_c1a)
1218 allocate(nicas_blk%sa_to_s(nicas_blk%nsa))
1219 allocate(nicas_blk%s_to_sa(nicas_blk%ns))
1221 do is=1,nicas_blk%ns
1222 if (nicas_blk%lcheck_sa(is))
then 1224 nicas_blk%sa_to_s(isa) = is
1227 call mpl%glb_to_loc_index(nicas_blk%nsa,nicas_blk%sa_to_s,nicas_blk%ns,nicas_blk%s_to_sa)
1230 allocate(nicas_blk%c1b_to_c1(nicas_blk%nc1b))
1231 allocate(nicas_blk%c1_to_c1b(nicas_blk%nc1))
1232 call msi(nicas_blk%c1_to_c1b)
1234 do ic1=1,nicas_blk%nc1
1235 if (lcheck_c1b(ic1))
then 1237 nicas_blk%c1b_to_c1(ic1b) = ic1
1238 nicas_blk%c1_to_c1b(ic1) = ic1b
1242 allocate(nicas_blk%sb_to_s(nicas_blk%nsb))
1243 allocate(nicas_blk%s_to_sb(nicas_blk%ns))
1244 call msi(nicas_blk%s_to_sb)
1246 do is=1,nicas_blk%ns
1247 if (nicas_blk%lcheck_sb(is))
then 1249 nicas_blk%sb_to_s(isb) = is
1250 nicas_blk%s_to_sb(is) = isb
1255 allocate(nicas_blk%sa_to_sb(nicas_blk%nsa))
1256 do isa=1,nicas_blk%nsa
1257 is = nicas_blk%sa_to_s(isa)
1258 isb = nicas_blk%s_to_sb(is)
1259 nicas_blk%sa_to_sb(isa) = isb
1265 h_n_s_max_loc =
max(h_n_s_max_loc,nicas_blk%h(il0i)%n_s)
1267 allocate(interph_lg(h_n_s_max_loc,geom%nl0i))
1270 do i_s=1,nicas_blk%hfull(il0i)%n_s
1271 if (lcheck_h(i_s,il0i))
then 1273 interph_lg(i_s_loc,il0i) = i_s
1278 do il1=1,nicas_blk%nl1
1279 s_n_s_max_loc =
max(s_n_s_max_loc,nicas_blk%s(il1)%n_s)
1281 allocate(interps_lg(s_n_s_max_loc,nicas_blk%nl1))
1282 do il1=1,nicas_blk%nl1
1284 do i_s=1,nicas_blk%sfull(il1)%n_s
1285 if (lcheck_s(i_s,il1))
then 1287 interps_lg(i_s_loc,il1) = i_s
1296 write(nicas_blk%h(il0i)%prefix,
'(a,i3.3)')
'h_',il0i
1297 nicas_blk%h(il0i)%n_src = nicas_blk%nc1b
1298 nicas_blk%h(il0i)%n_dst = geom%nc0a
1299 call nicas_blk%h(il0i)%alloc
1300 do i_s_loc=1,nicas_blk%h(il0i)%n_s
1301 i_s = interph_lg(i_s_loc,il0i)
1302 nicas_blk%h(il0i)%row(i_s_loc) = geom%c0_to_c0a(nicas_blk%hfull(il0i)%row(i_s))
1303 nicas_blk%h(il0i)%col(i_s_loc) = nicas_blk%c1_to_c1b(nicas_blk%hfull(il0i)%col(i_s))
1304 nicas_blk%h(il0i)%S(i_s_loc) = nicas_blk%hfull(il0i)%S(i_s)
1306 call nicas_blk%h(il0i)%reorder(mpl)
1310 nicas_blk%v%prefix =
'v' 1311 nicas_blk%v%n_src = nicas_blk%vfull%n_src
1312 nicas_blk%v%n_dst = nicas_blk%vfull%n_dst
1313 nicas_blk%v%n_s = nicas_blk%vfull%n_s
1314 call nicas_blk%v%alloc(nicas_blk%nc1b)
1315 do i_s=1,nicas_blk%v%n_s
1316 nicas_blk%v%row(i_s) = nicas_blk%vfull%row(i_s)
1317 nicas_blk%v%col(i_s) = nicas_blk%vfull%col(i_s)
1318 do ic1b=1,nicas_blk%nc1b
1319 ic1 = nicas_blk%c1b_to_c1(ic1b)
1320 nicas_blk%v%Svec(i_s,ic1b) = nicas_blk%vfull%Svec(i_s,ic1)
1323 call nicas_blk%v%reorder(mpl)
1326 do il1=1,nicas_blk%nl1
1327 write(nicas_blk%s(il1)%prefix,
'(a,i3.3)')
's_',il1
1328 nicas_blk%s(il1)%n_src = nicas_blk%nc1b
1329 nicas_blk%s(il1)%n_dst = nicas_blk%nc1b
1330 call nicas_blk%s(il1)%alloc
1331 do i_s_loc=1,nicas_blk%s(il1)%n_s
1332 i_s = interps_lg(i_s_loc,il1)
1333 nicas_blk%s(il1)%row(i_s_loc) = nicas_blk%c1_to_c1b(nicas_blk%sfull(il1)%row(i_s))
1334 nicas_blk%s(il1)%col(i_s_loc) = nicas_blk%c1_to_c1b(nicas_blk%sfull(il1)%col(i_s))
1335 nicas_blk%s(il1)%S(i_s_loc) = nicas_blk%sfull(il1)%S(i_s)
1337 call nicas_blk%s(il1)%reorder(mpl)
1341 allocate(nicas_blk%c1a_to_c0a(nicas_blk%nc1a))
1342 allocate(nicas_blk%sa_to_c0a(nicas_blk%nsa))
1343 allocate(nicas_blk%sa_to_l0(nicas_blk%nsa))
1344 allocate(nicas_blk%sb_to_c1b(nicas_blk%nsb))
1345 allocate(nicas_blk%sb_to_l1(nicas_blk%nsb))
1346 allocate(nicas_blk%c1bl1_to_sb(nicas_blk%nc1b,nicas_blk%nl1))
1347 call msi(nicas_blk%c1bl1_to_sb)
1348 do ic1a=1,nicas_blk%nc1a
1349 ic1 = nicas_blk%c1a_to_c1(ic1a)
1350 ic0 = nicas_blk%c1_to_c0(ic1)
1351 ic0a = geom%c0_to_c0a(ic0)
1352 nicas_blk%c1a_to_c0a(ic1a) = ic0a
1354 do isa=1,nicas_blk%nsa
1355 is = nicas_blk%sa_to_s(isa)
1356 ic1 = nicas_blk%s_to_c1(is)
1357 ic0 = nicas_blk%c1_to_c0(ic1)
1358 ic0a = geom%c0_to_c0a(ic0)
1359 il1 = nicas_blk%s_to_l1(is)
1360 il0 = nicas_blk%l1_to_l0(il1)
1361 nicas_blk%sa_to_c0a(isa) = ic0a
1362 nicas_blk%sa_to_l0(isa) = il0
1364 do isb=1,nicas_blk%nsb
1365 is = nicas_blk%sb_to_s(isb)
1366 il1 = nicas_blk%s_to_l1(is)
1367 ic1 = nicas_blk%s_to_c1(is)
1368 ic1b = nicas_blk%c1_to_c1b(ic1)
1369 nicas_blk%sb_to_c1b(isb) = ic1b
1370 nicas_blk%sb_to_l1(isb) = il1
1371 nicas_blk%c1bl1_to_sb(ic1b,il1) = isb
1375 s_to_proc = geom%c0_to_proc(nicas_blk%c1_to_c0(nicas_blk%s_to_c1))
1376 call nicas_blk%com_AB%setup(mpl,
'com_AB',nicas_blk%ns,nicas_blk%nsa,nicas_blk%nsb,nicas_blk%sb_to_s,nicas_blk%sa_to_sb, &
1377 & s_to_proc,nicas_blk%s_to_sa)
1390 class(nicas_blk_type),
intent(inout) :: nicas_blk
1391 type(mpl_type),
intent(inout) :: mpl
1392 type(rng_type),
intent(inout) :: rng
1393 type(nam_type),
intent(in) :: nam
1394 type(geom_type),
intent(in) :: geom
1395 type(cmat_blk_type),
intent(in) :: cmat_blk
1398 integer :: n_s_max,ithread,is,ic1,jc1,il1,il0,j,js,isb,ic1b,ic0,ic0a,ic1a,i_s,jc,kc,ks,jbd,jc0,jl0,jl1,ic1bb,isbb
1399 integer :: c_n_s(mpl%nthread)
1400 integer,
allocatable :: nn(:),nn_index(:),inec(:),c_ind(:,:)
1401 real(kind_real) :: distvsq,rvsq
1402 real(kind_real),
allocatable :: lon_c1(:),lat_c1(:),nn_dist(:)
1403 real(kind_real),
allocatable :: rh_c1a(:,:),rv_c1a(:,:),rv_rfac_c1a(:,:),rv_rfac_c1(:,:),rv_coef_c1a(:,:),rv_coef_c1(:,:)
1404 real(kind_real),
allocatable :: H11_c1a(:,:),H22_c1a(:,:),H33_c1a(:,:),H12_c1a(:,:),Hcoef_c1a(:,:),Hcoef_c1(:,:)
1405 real(kind_real),
allocatable :: distnormv(:,:),rfac(:,:),coef(:,:),Hcoef(:,:)
1406 real(kind_real),
allocatable :: c_S(:,:),c_S_conv(:)
1408 logical,
allocatable :: lcheck_c1bb(:)
1409 type(linop_type) :: ctmp,c(mpl%nthread)
1412 associate(ib=>nicas_blk%ib)
1415 nicas_blk%double_fit = cmat_blk%double_fit
1416 nicas_blk%anisotropic = cmat_blk%anisotropic
1419 allocate(lon_c1(nicas_blk%nc1))
1420 allocate(lat_c1(nicas_blk%nc1))
1421 allocate(nicas_blk%mask_c1(nicas_blk%nc1,nicas_blk%nl1))
1422 allocate(lcheck_c1bb(nicas_blk%nc1))
1425 lon_c1 = geom%lon(nicas_blk%c1_to_c0)
1426 lat_c1 = geom%lat(nicas_blk%c1_to_c0)
1427 nicas_blk%mask_c1 = .false.
1428 do is=1,nicas_blk%ns
1429 ic1 = nicas_blk%s_to_c1(is)
1430 il1 = nicas_blk%s_to_l1(is)
1431 nicas_blk%mask_c1(ic1,il1) = .true.
1435 write(mpl%info,
'(a10,a)')
'',
'Compute KD-tree' 1436 call flush(mpl%info)
1437 call nicas_blk%kdtree%create(mpl,nicas_blk%nc1,lon_c1,lat_c1)
1440 call mpl%f_comm%allreduce(maxval(cmat_blk%rh),nicas_blk%rhmax,fckit_mpi_max())
1441 if (nicas_blk%double_fit)
then 1444 nicas_blk%rhmax = nicas_blk%rhmax*
sqrt_r 1449 nicas_blk%nc1bb = nicas_blk%nc1b
1451 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Define extended halo: ' 1452 call flush(mpl%info)
1455 allocate(nn(nicas_blk%nc1b))
1457 do ic1b=1,nicas_blk%nc1b
1459 ic1 = nicas_blk%c1b_to_c1(ic1b)
1460 ic0 = nicas_blk%c1_to_c0(ic1)
1463 call nicas_blk%kdtree%count_nearest_neighbors(geom%lon(ic0),geom%lat(ic0),nicas_blk%rhmax,nn(ic1b))
1467 call mpl%prog_init(nicas_blk%nc1b)
1468 lcheck_c1bb = .false.
1470 do ic1b=1,nicas_blk%nc1b
1472 ic1 = nicas_blk%c1b_to_c1(ic1b)
1473 ic0 = nicas_blk%c1_to_c0(ic1)
1476 allocate(nn_index(nn(ic1b)))
1477 allocate(nn_dist(nn(ic1b)))
1480 call nicas_blk%kdtree%find_nearest_neighbors(geom%lon(ic0),geom%lat(ic0),nn(ic1b),nn_index,nn_dist)
1485 lcheck_c1bb(jc1) = .true.
1489 deallocate(nn_index)
1493 call mpl%prog_print(ic1b)
1495 write(mpl%info,
'(a)')
'100%' 1496 call flush(mpl%info)
1499 nicas_blk%nc1bb = count(lcheck_c1bb)
1500 write(mpl%info,
'(a10,a,i6,a,i6)')
'',
'Halo sizes nc1b / nc1bb: ',nicas_blk%nc1b,
' / ',nicas_blk%nc1bb
1504 allocate(nicas_blk%c1bb_to_c1(nicas_blk%nc1bb))
1505 allocate(nicas_blk%c1_to_c1bb(nicas_blk%nc1))
1509 nicas_blk%c1bb_to_c1 = nicas_blk%c1b_to_c1
1510 nicas_blk%c1_to_c1bb = nicas_blk%c1_to_c1b
1511 nicas_blk%nsbb = nicas_blk%nsb
1514 call msi(nicas_blk%c1_to_c1bb)
1516 do ic1=1,nicas_blk%nc1
1517 if (lcheck_c1bb(ic1))
then 1519 nicas_blk%c1bb_to_c1(ic1bb) = ic1
1520 nicas_blk%c1_to_c1bb(ic1) = ic1bb
1526 do is=1,nicas_blk%ns
1527 ic1 = nicas_blk%s_to_c1(is)
1528 if (lcheck_c1bb(ic1)) nicas_blk%nsbb = nicas_blk%nsbb+1
1530 write(mpl%info,
'(a10,a,i6,a,i6)')
'',
'Halo sizes nsb / nsbb: ',nicas_blk%nsb,
' / ',nicas_blk%nsbb
1534 allocate(nicas_blk%sbb_to_s(nicas_blk%nsbb))
1538 nicas_blk%sbb_to_s = nicas_blk%sb_to_s
1542 do is=1,nicas_blk%ns
1543 ic1 = nicas_blk%s_to_c1(is)
1544 if (lcheck_c1bb(ic1))
then 1546 nicas_blk%sbb_to_s(isbb) = is
1552 write(mpl%info,
'(a10,a)')
'',
'Compute horizontal and vertical parameters' 1553 call flush(mpl%info)
1556 allocate(rh_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1557 allocate(rv_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1558 allocate(nicas_blk%rh_c1(nicas_blk%nc1,nicas_blk%nl1))
1559 allocate(nicas_blk%rv_c1(nicas_blk%nc1,nicas_blk%nl1))
1560 if (nicas_blk%double_fit)
then 1561 allocate(rv_rfac_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1562 allocate(rv_coef_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1563 allocate(rv_rfac_c1(nicas_blk%nc1,nicas_blk%nl1))
1564 allocate(rv_coef_c1(nicas_blk%nc1,nicas_blk%nl1))
1565 allocate(nicas_blk%rfac(nicas_blk%nsbb))
1566 allocate(nicas_blk%coef(nicas_blk%nsbb))
1567 allocate(nicas_blk%distnormv(nicas_blk%nsbb))
1569 if (nicas_blk%anisotropic)
then 1570 allocate(h11_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1571 allocate(h22_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1572 allocate(h33_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1573 allocate(h12_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1574 allocate(hcoef_c1a(nicas_blk%nc1a,nicas_blk%nl1))
1575 allocate(hcoef_c1(nicas_blk%nc1,nicas_blk%nl1))
1576 allocate(nicas_blk%H11_c1(nicas_blk%nc1,nicas_blk%nl1))
1577 allocate(nicas_blk%H22_c1(nicas_blk%nc1,nicas_blk%nl1))
1578 allocate(nicas_blk%H33_c1(nicas_blk%nc1,nicas_blk%nl1))
1579 allocate(nicas_blk%H12_c1(nicas_blk%nc1,nicas_blk%nl1))
1580 allocate(nicas_blk%Hcoef(nicas_blk%nsbb))
1584 write(mpl%info,
'(a13,a)')
'',
'Copy and rescale' 1585 call flush(mpl%info)
1586 do il1=1,nicas_blk%nl1
1587 do ic1a=1,nicas_blk%nc1a
1589 ic0a = nicas_blk%c1a_to_c0a(ic1a)
1590 il0 = nicas_blk%l1_to_l0(il1)
1591 rh_c1a(ic1a,il1) = cmat_blk%rh(ic0a,il0)
1592 rv_c1a(ic1a,il1) = cmat_blk%rv(ic0a,il0)
1593 if (nicas_blk%double_fit)
then 1594 rv_rfac_c1a(ic1a,il1) = cmat_blk%rv_rfac(ic0a,il0)
1595 rv_coef_c1a(ic1a,il1) = cmat_blk%rv_coef(ic0a,il0)
1597 if (nicas_blk%anisotropic)
then 1598 h11_c1a(ic1a,il1) = cmat_blk%H11(ic0a,il0)
1599 h22_c1a(ic1a,il1) = cmat_blk%H22(ic0a,il0)
1600 h33_c1a(ic1a,il1) = cmat_blk%H33(ic0a,il0)
1601 h12_c1a(ic1a,il1) = cmat_blk%H12(ic0a,il0)
1602 hcoef_c1a(ic1a,il1) = cmat_blk%Hcoef(ic0a,il0)
1606 rh_c1a(ic1a,il1) = rh_c1a(ic1a,il1)*
sqrt_r 1607 if (nicas_blk%double_fit)
then 1609 rv_rfac_c1a(ic1a,il1) = rv_rfac_c1a(ic1a,il1)*
sqrt_rfac 1610 rv_coef_c1a(ic1a,il1) = rv_coef_c1a(ic1a,il1)*
sqrt_coef 1612 rv_c1a(ic1a,il1) = rv_c1a(ic1a,il1)*
sqrt_r 1614 if (nicas_blk%anisotropic)
then 1615 h11_c1a(ic1a,il1) = h11_c1a(ic1a,il1)/
sqrt_r**2
1616 h22_c1a(ic1a,il1) = h22_c1a(ic1a,il1)/
sqrt_r**2
1617 h33_c1a(ic1a,il1) = h33_c1a(ic1a,il1)/
sqrt_r**2
1618 h12_c1a(ic1a,il1) = h12_c1a(ic1a,il1)/
sqrt_r**2
1624 write(mpl%info,
'(a13,a)')
'',
'Communication' 1625 call flush(mpl%info)
1626 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,rh_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1628 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,rv_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1630 if (nicas_blk%double_fit)
then 1631 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,rv_rfac_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1633 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,rv_coef_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1636 if (nicas_blk%anisotropic)
then 1637 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,h11_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1639 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,h22_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1641 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,h33_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1643 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,h12_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1645 call mpl%loc_to_glb(nicas_blk%nl1,nicas_blk%nc1a,hcoef_c1a,nicas_blk%nc1,nicas_blk%c1_to_proc,nicas_blk%c1_to_c1a,.true., &
1652 if (nicas_blk%double_fit)
then 1653 deallocate(rv_rfac_c1a)
1654 deallocate(rv_coef_c1a)
1656 if (nicas_blk%anisotropic)
then 1661 deallocate(hcoef_c1a)
1665 allocate(nicas_blk%distnorm(nicas_blk%nsbb))
1668 if (nam%network)
then 1669 call nicas_blk%compute_convol_network(mpl,rng,nam,geom)
1671 call nicas_blk%compute_convol_distance(mpl,geom)
1675 deallocate(nicas_blk%rh_c1)
1676 deallocate(nicas_blk%rv_c1)
1677 if (nicas_blk%anisotropic)
then 1678 deallocate(nicas_blk%H11_c1)
1679 deallocate(nicas_blk%H22_c1)
1680 deallocate(nicas_blk%H33_c1)
1681 deallocate(nicas_blk%H12_c1)
1685 write(mpl%info,
'(a13,a)')
'',
'Compute ball data' 1688 do isbb=1,nicas_blk%nsbb
1690 is = nicas_blk%sbb_to_s(isbb)
1691 ic1 = nicas_blk%s_to_c1(is)
1692 il1 = nicas_blk%s_to_l1(is)
1693 ic0 = nicas_blk%c1_to_c0(ic1)
1694 il0 = nicas_blk%l1_to_l0(il1)
1697 if (nicas_blk%double_fit)
then 1698 allocate(distnormv(nicas_blk%nc1,nicas_blk%nl1))
1699 allocate(rfac(nicas_blk%nc1,nicas_blk%nl1))
1700 allocate(coef(nicas_blk%nc1,nicas_blk%nl1))
1702 if (nicas_blk%anisotropic)
allocate(hcoef(nicas_blk%nc1,nicas_blk%nl1))
1705 if (nicas_blk%double_fit)
then 1710 if (nicas_blk%anisotropic)
call msr(hcoef)
1712 do jbd=1,nicas_blk%distnorm(isbb)%nbd
1714 jc1 = nicas_blk%distnorm(isbb)%bd_to_c1(jbd)
1715 jl1 = nicas_blk%distnorm(isbb)%bd_to_l1(jbd)
1716 jc0 = nicas_blk%c1_to_c0(jc1)
1717 jl0 = nicas_blk%l1_to_l0(jl1)
1719 if (nicas_blk%double_fit)
then 1721 distvsq = (geom%vunit(ic0,il0)-geom%vunit(jc0,jl0))**2
1722 rvsq = 0.5*(nicas_blk%rv_c1(ic1,il1)**2+nicas_blk%rv_c1(jc1,jl1)**2)
1724 distnormv(jc1,jl1) = sqrt(distvsq/rvsq)
1725 elseif (distvsq>0.0)
then 1726 distnormv(jc1,jl1) = 0.5*huge(0.0)
1728 rfac(ic1,il1) = sqrt(rv_rfac_c1(ic1,il1)*rv_rfac_c1(jc1,jl1))
1729 coef(ic1,il1) = sqrt(rv_coef_c1(ic1,il1)*rv_coef_c1(jc1,jl1))
1731 if (nicas_blk%anisotropic) hcoef(ic1,il1) = sqrt(hcoef_c1(ic1,il1)*hcoef_c1(jc1,jl1))
1735 if (nicas_blk%double_fit)
then 1736 call nicas_blk%distnormv(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,distnormv)
1737 call nicas_blk%rfac(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,rfac)
1738 call nicas_blk%coef(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,coef)
1740 if (nicas_blk%anisotropic)
call nicas_blk%Hcoef(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,hcoef)
1743 if (nicas_blk%double_fit)
then 1744 deallocate(distnormv)
1748 if (nicas_blk%anisotropic)
deallocate(hcoef)
1753 if (nicas_blk%double_fit)
then 1754 deallocate(rv_rfac_c1)
1755 deallocate(rv_coef_c1)
1757 if (nicas_blk%anisotropic)
deallocate(hcoef_c1)
1760 call nicas_blk%compute_convol_weights(mpl,nam,geom,ctmp)
1763 do isbb=1,nicas_blk%nsbb
1764 call nicas_blk%distnorm(isbb)%dealloc
1765 if (nicas_blk%double_fit)
then 1766 call nicas_blk%distnormv(isbb)%dealloc
1767 call nicas_blk%rfac(isbb)%dealloc
1768 call nicas_blk%coef(isbb)%dealloc
1770 if (nicas_blk%anisotropic)
call nicas_blk%Hcoef(isbb)%dealloc
1772 deallocate(nicas_blk%distnorm)
1773 if (nicas_blk%double_fit)
then 1774 deallocate(nicas_blk%distnormv)
1775 deallocate(nicas_blk%rfac)
1776 deallocate(nicas_blk%coef)
1778 if (nicas_blk%anisotropic)
deallocate(nicas_blk%Hcoef)
1782 nicas_blk%c = ctmp%copy()
1785 allocate(inec(nicas_blk%ns))
1789 inec(is) = inec(is)+1
1791 allocate(c_ind(maxval(inec),nicas_blk%ns))
1792 allocate(c_s(maxval(inec),nicas_blk%ns))
1799 inec(is) = inec(is)+1
1800 c_ind(inec(is),is) = js
1801 c_s(inec(is),is) = ctmp%S(i_s)
1805 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Second pass: ' 1806 call flush(mpl%info)
1807 call mpl%prog_init(nicas_blk%nsb)
1808 n_s_max = 100*nint(
real(geom%nc0*geom%nl0)/
real(mpl%nthread*mpl%nproc))
1810 do ithread=1,mpl%nthread
1811 c(ithread)%n_s = n_s_max
1812 call c(ithread)%alloc
1813 call msi(c(ithread)%row)
1814 call msi(c(ithread)%col)
1815 call msr(c(ithread)%S)
1820 do isb=1,nicas_blk%nsb
1822 is = nicas_blk%sb_to_s(isb)
1827 allocate(c_s_conv(nicas_blk%ns))
1837 c_s_conv(ks) = c_s_conv(ks)+c_s(jc,is)*c_s(kc,js)
1842 do js=1,nicas_blk%ns
1844 if (nam%mpicom==1)
then 1845 add_op = (nicas_blk%lcheck_sb(js).and.(is<=js)).or.(.not.nicas_blk%lcheck_sb(js))
1846 elseif (nam%mpicom==2)
then 1847 add_op = nicas_blk%lcheck_sa(is).and.((nicas_blk%lcheck_sa(js).and.(is<=js)) &
1848 & .or.(.not.nicas_blk%lcheck_sa(js)))
1850 if (add_op)
call c(ithread)%add_op(c_n_s(ithread),is,js,c_s_conv(js))
1854 deallocate(c_s_conv)
1857 call mpl%prog_print(isb)
1860 write(mpl%info,
'(a)')
'100%' 1861 call flush(mpl%info)
1864 call nicas_blk%c%gather(mpl,c_n_s,c)
1867 do ithread=1,mpl%nthread
1868 call c(ithread)%dealloc
1873 nicas_blk%c%prefix =
'c' 1874 nicas_blk%c_nor%prefix =
'c_nor' 1890 class(nicas_blk_type),
intent(inout) :: nicas_blk
1891 type(mpl_type),
intent(inout) :: mpl
1892 type(rng_type),
intent(inout) :: rng
1893 type(nam_type),
intent(in) :: nam
1894 type(geom_type),
intent(in) :: geom
1897 integer :: net_nnbmax,is,ic0,ic1,il0,jl1,np,np_new,i,j,k,ip,kc1,jc1,il1,dkl1,kl1,jp,isbb,djl1,inr,jc0,jl0
1898 integer,
allocatable :: net_nnb(:),net_inb(:,:),plist(:,:),plist_new(:,:)
1899 real(kind_real) :: distnorm_network,disttest
1900 real(kind_real) :: dnb,dx,dy,dz,disthsq,distvsq,rhsq,rvsq,H11,H22,H33,H12
1901 real(kind_real),
allocatable :: distnorm(:,:),net_dnb(:,:,:,:)
1902 logical :: init,valid_arc,add_to_front
1903 type(mesh_type) :: mesh
1906 allocate(net_nnb(nicas_blk%nc1))
1909 write(mpl%info,
'(a10,a)')
'',
'Create mesh' 1910 call flush(mpl%info)
1911 call mesh%create(mpl,rng,nicas_blk%nc1,geom%lon(nicas_blk%c1_to_c0),geom%lat(nicas_blk%c1_to_c0))
1914 write(mpl%info,
'(a10,a)')
'',
'Count neighbors' 1915 call flush(mpl%info)
1917 do ic1=1,nicas_blk%nc1
1918 inr = mesh%order_inv(ic1)
1921 do while ((i/=mesh%lend(inr)).or.init)
1922 net_nnb(ic1) = net_nnb(ic1)+1
1929 net_nnbmax = maxval(net_nnb)
1930 allocate(net_inb(net_nnbmax,nicas_blk%nc1))
1931 allocate(net_dnb(net_nnbmax,-1:1,nicas_blk%nc1,nicas_blk%nl1))
1934 write(mpl%info,
'(a10,a)')
'',
'Find mesh neighbors' 1935 call flush(mpl%info)
1937 do ic1=1,nicas_blk%nc1
1938 inr = mesh%order_inv(ic1)
1941 do while ((i/=mesh%lend(inr)).or.init)
1942 net_nnb(ic1) = net_nnb(ic1)+1
1943 net_inb(net_nnb(ic1),ic1) = mesh%order(abs(mesh%list(i)))
1950 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Compute mesh edges distances: ' 1951 call flush(mpl%info)
1952 call mpl%prog_init(nicas_blk%nc1)
1956 do ic1=1,nicas_blk%nc1
1959 ic0 = nicas_blk%c1_to_c0(ic1)
1960 jc1 = net_inb(j,ic1)
1961 jc0 = nicas_blk%c1_to_c0(jc1)
1963 if (geom%mask_hor_c0(jc0))
then 1964 if (nicas_blk%anisotropic)
then 1966 dx = geom%lon(jc0)-geom%lon(ic0)
1967 dy = geom%lat(jc0)-geom%lat(ic0)
1968 call lonlatmod(dx,dy)
1969 dx = dx*cos(geom%lat(ic0))
1972 call sphere_dist(geom%lon(ic0),geom%lat(ic0),geom%lon(jc0),geom%lat(jc0),dnb)
1975 do il1=1,nicas_blk%nl1
1977 il0 = nicas_blk%l1_to_l0(il1)
1979 if (nam%mask_check)
call geom%check_arc(il0,geom%lon(ic0),geom%lat(ic0),geom%lon(jc0),geom%lat(jc0),valid_arc)
1984 jl1 =
max(1,
min(il1+djl1,nicas_blk%nl1))
1985 jl0 = nicas_blk%l1_to_l0(jl1)
1987 if (geom%mask_c0(ic0,il0).and.geom%mask_c0(jc0,jl0))
then 1989 if (nicas_blk%anisotropic)
then 1990 dz = geom%vunit(ic0,il0)-geom%vunit(jc0,jl0)
1991 h11 = 0.5*(nicas_blk%H11_c1(ic1,il1)+nicas_blk%H11_c1(jc1,jl1))
1992 h22 = 0.5*(nicas_blk%H22_c1(ic1,il1)+nicas_blk%H22_c1(jc1,jl1))
1993 h33 = 0.5*(nicas_blk%H33_c1(ic1,il1)+nicas_blk%H33_c1(jc1,jl1))
1994 h12 = 0.5*(nicas_blk%H12_c1(ic1,il1)+nicas_blk%H12_c1(jc1,jl1))
1995 net_dnb(j,djl1,ic1,il1) = sqrt(h11*dx**2+h22*dy**2+h33*dz**2+2.0*h12*dx*dy)*gc2gau
1998 distvsq = (geom%vunit(ic0,il0)-geom%vunit(jc0,jl0))**2
1999 rhsq = 0.5*(nicas_blk%rh_c1(ic1,il1)**2+nicas_blk%rh_c1(jc1,jl1)**2)
2000 rvsq = 0.5*(nicas_blk%rv_c1(ic1,il1)**2+nicas_blk%rv_c1(jc1,jl1)**2)
2001 distnorm_network = 0.0
2003 distnorm_network = distnorm_network+disthsq/rhsq
2004 elseif (disthsq>0.0)
then 2005 distnorm_network = distnorm_network+0.5*huge(0.0)
2008 distnorm_network = distnorm_network+distvsq/rvsq
2009 elseif (distvsq>0.0)
then 2010 distnorm_network = distnorm_network+0.5*huge(0.0)
2012 net_dnb(j,djl1,ic1,il1) = sqrt(distnorm_network)
2022 call mpl%prog_print(ic1)
2025 write(mpl%info,
'(a)')
'100%' 2026 call flush(mpl%info)
2029 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Compute distances: ' 2030 call flush(mpl%info)
2031 call mpl%prog_init(nicas_blk%nsbb)
2034 do isbb=1,nicas_blk%nsbb
2036 is = nicas_blk%sbb_to_s(isbb)
2037 ic1 = nicas_blk%s_to_c1(is)
2038 il1 = nicas_blk%s_to_l1(is)
2041 allocate(distnorm(nicas_blk%nc1,nicas_blk%nl1))
2042 allocate(plist(nicas_blk%nc1*nicas_blk%nl1,2))
2043 allocate(plist_new(nicas_blk%nc1*nicas_blk%nl1,2))
2050 distnorm(ic1,il1) = 0.0
2063 kc1 = net_inb(k,jc1)
2065 kl1 =
max(1,
min(jl1+dkl1,nicas_blk%nl1))
2066 if (nicas_blk%mask_c1(kc1,kl1))
then 2067 disttest = distnorm(jc1,jl1)+net_dnb(k,dkl1,jc1,jl1)
2068 if (disttest<1.0)
then 2070 if (disttest<distnorm(kc1,kl1))
then 2072 distnorm(kc1,kl1) = disttest
2075 add_to_front = .true.
2077 if ((plist_new(jp,1)==kc1).and.(plist_new(jp,2)==kl1))
then 2078 add_to_front = .false.
2083 if (add_to_front)
then 2086 plist_new(np_new,1) = kc1
2087 plist_new(np_new,2) = kl1
2098 plist(1:np,:) = plist_new(1:np,:)
2102 do il1=1,nicas_blk%nl1
2103 do ic1=1,nicas_blk%nc1
2104 if (supeq(distnorm(ic1,il1),1.0_kind_real))
call msr(distnorm(ic1,il1))
2107 call nicas_blk%distnorm(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,distnorm)
2110 deallocate(distnorm)
2112 deallocate(plist_new)
2115 call mpl%prog_print(isbb)
2117 write(mpl%info,
'(a)')
'100%' 2118 call flush(mpl%info)
2131 class(nicas_blk_type),
intent(inout) :: nicas_blk
2132 type(mpl_type),
intent(inout) :: mpl
2133 type(geom_type),
intent(in) :: geom
2136 integer :: nnmax,is,ic1,jc1,il1,il0,j,js,ic0,jc0,jl0,jl1
2137 integer :: ic1bb,isbb
2138 integer,
allocatable :: nn(:),nn_index(:,:)
2139 real(kind_real) :: disthsq,distvsq,rhsq,rvsq
2140 real(kind_real) :: dx,dy,dz,H11,H22,H33,H12
2141 real(kind_real),
allocatable :: distnorm(:,:),nn_dist(:,:)
2144 allocate(nn(nicas_blk%nc1bb))
2147 write(mpl%info,
'(a10,a)')
'',
'Count nearest neighbors' 2148 call flush(mpl%info)
2149 do ic1bb=1,nicas_blk%nc1bb
2151 ic1 = nicas_blk%c1bb_to_c1(ic1bb)
2152 ic0 = nicas_blk%c1_to_c0(ic1)
2155 call nicas_blk%kdtree%count_nearest_neighbors(geom%lon(ic0),geom%lat(ic0),nicas_blk%rhmax,nn(ic1bb))
2158 write(mpl%info,
'(a10,a,i6,a,f5.1,a)')
'',
'Number of neighbors to find: ',nnmax,
' (', &
2159 &
real(nnmax,kind_real)/
real(nicas_blk%nc1,kind_real)*100.0,
'%)' 2162 allocate(nn_index(nnmax,nicas_blk%nc1bb))
2163 allocate(nn_dist(nnmax,nicas_blk%nc1bb))
2166 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Find nearest neighbors: ' 2167 call flush(mpl%info)
2168 call mpl%prog_init(nicas_blk%nc1bb)
2169 do ic1bb=1,nicas_blk%nc1bb
2171 ic1 = nicas_blk%c1bb_to_c1(ic1bb)
2172 ic0 = nicas_blk%c1_to_c0(ic1)
2175 call nicas_blk%kdtree%find_nearest_neighbors(geom%lon(ic0),geom%lat(ic0), &
2176 & nn(ic1bb),nn_index(1:nn(ic1bb),ic1bb),nn_dist(1:nn(ic1bb),ic1bb))
2179 call mpl%prog_print(ic1bb)
2181 write(mpl%info,
'(a)')
'100%' 2182 call flush(mpl%info)
2185 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Compute distances: ' 2186 call flush(mpl%info)
2187 call mpl%prog_init(nicas_blk%nsbb)
2190 do isbb=1,nicas_blk%nsbb
2192 is = nicas_blk%sbb_to_s(isbb)
2193 ic1 = nicas_blk%s_to_c1(is)
2194 ic1bb = nicas_blk%c1_to_c1bb(ic1)
2195 ic0 = nicas_blk%c1_to_c0(ic1)
2196 il1 = nicas_blk%s_to_l1(is)
2197 il0 = nicas_blk%l1_to_l0(il1)
2200 allocate(distnorm(nicas_blk%nc1,nicas_blk%nl1))
2207 jc1 = nn_index(j,ic1bb)
2208 do jl1=1,nicas_blk%nl1
2209 if (nicas_blk%mask_c1(jc1,jl1))
then 2210 jc0 = nicas_blk%c1_to_c0(jc1)
2211 jl0 = nicas_blk%l1_to_l0(jl1)
2212 js = nicas_blk%c1l1_to_s(jc1,jl1)
2215 if (nicas_blk%anisotropic)
then 2216 dx = geom%lon(jc0)-geom%lon(ic0)
2217 dy = geom%lat(jc0)-geom%lat(ic0)
2218 call lonlatmod(dx,dy)
2219 dx = dx*cos(geom%lat(ic0))
2220 dz = geom%vunit(ic0,il0)-geom%vunit(jc0,jl0)
2221 h11 = 0.5*(nicas_blk%H11_c1(ic1,il1)+nicas_blk%H11_c1(jc1,jl1))
2222 h22 = 0.5*(nicas_blk%H22_c1(ic1,il1)+nicas_blk%H22_c1(jc1,jl1))
2223 h33 = 0.5*(nicas_blk%H33_c1(ic1,il1)+nicas_blk%H33_c1(jc1,jl1))
2224 h12 = 0.5*(nicas_blk%H12_c1(ic1,il1)+nicas_blk%H12_c1(jc1,jl1))
2225 distnorm(jc1,jl1) = sqrt(h11*dx**2+h22*dy**2+h33*dz**2+2.0*h12*dx*dy)*gc2gau
2227 disthsq = nn_dist(j,ic1bb)**2
2228 distvsq = (geom%vunit(ic0,il0)-geom%vunit(jc0,jl0))**2
2229 rhsq = 0.5*(nicas_blk%rh_c1(ic1,il1)**2+nicas_blk%rh_c1(jc1,jl1)**2)
2230 rvsq = 0.5*(nicas_blk%rv_c1(ic1,il1)**2+nicas_blk%rv_c1(jc1,jl1)**2)
2232 disthsq = disthsq/rhsq
2233 elseif (disthsq>0.0)
then 2234 disthsq = 0.5*huge(0.0)
2237 distvsq = distvsq/rvsq
2238 elseif (distvsq>0.0)
then 2239 distvsq = 0.5*huge(0.0)
2241 distnorm(jc1,jl1) = sqrt(disthsq+distvsq)
2248 do il1=1,nicas_blk%nl1
2249 do ic1=1,nicas_blk%nc1
2250 if (supeq(distnorm(ic1,il1),1.0_kind_real))
call msr(distnorm(ic1,il1))
2253 call nicas_blk%distnorm(isbb)%pack(nicas_blk%nc1,nicas_blk%nl1,distnorm)
2256 deallocate(distnorm)
2259 call mpl%prog_print(isbb)
2262 write(mpl%info,
'(a)')
'100%' 2263 call flush(mpl%info)
2276 class(nicas_blk_type),
intent(inout) :: nicas_blk
2277 type(mpl_type),
intent(inout) :: mpl
2278 type(nam_type),
intent(in) :: nam
2279 type(geom_type),
intent(in) :: geom
2280 type(linop_type),
intent(inout) :: ctmp
2283 integer :: n_s_max,ithread,is,ic1,jc1,il1,jl1,il0,jbd,js,ic0,ic1bb,isbb
2284 integer :: c_n_s(mpl%nthread),c_nor_n_s(mpl%nthread)
2285 real(kind_real) :: disth,S_test
2287 type(linop_type) :: c(mpl%nthread),c_nor(mpl%nthread)
2290 n_s_max = 10*nint(
real(geom%nc0*geom%nl0)/
real(mpl%nthread*mpl%nproc))
2291 do ithread=1,mpl%nthread
2292 c(ithread)%n_s = n_s_max
2293 call c(ithread)%alloc
2294 c_nor(ithread)%n_s = n_s_max
2295 call c_nor(ithread)%alloc
2299 write(mpl%info,
'(a10,a)',advance=
'no')
'',
'Compute weights: ' 2300 call flush(mpl%info)
2301 call mpl%prog_init(nicas_blk%nsbb)
2307 do isbb=1,nicas_blk%nsbb
2309 is = nicas_blk%sbb_to_s(isbb)
2312 ic1 = nicas_blk%s_to_c1(is)
2313 ic1bb = nicas_blk%c1_to_c1bb(ic1)
2314 ic0 = nicas_blk%c1_to_c0(ic1)
2315 il1 = nicas_blk%s_to_l1(is)
2316 il0 = nicas_blk%l1_to_l0(il1)
2319 do jbd=1,nicas_blk%distnorm(isbb)%nbd
2321 jc1 = nicas_blk%distnorm(isbb)%bd_to_c1(jbd)
2322 jl1 = nicas_blk%distnorm(isbb)%bd_to_l1(jbd)
2323 js = nicas_blk%c1l1_to_s(jc1,jl1)
2325 if (nicas_blk%double_fit)
then 2327 disth = sqrt(nicas_blk%distnorm(isbb)%val(jbd)**2-nicas_blk%distnormv(isbb)%val(jbd)**2)
2328 s_test = gc99(mpl,disth)*((1.0+nicas_blk%coef(isbb)%val(jbd))*gc99(mpl,nicas_blk%distnormv(isbb)%val(jbd) &
2329 & /nicas_blk%rfac(isbb)%val(jbd))-nicas_blk%coef(isbb)%val(jbd)*gc99(mpl,nicas_blk%distnormv(isbb)%val(jbd)))
2332 s_test = gc99(mpl,nicas_blk%distnorm(isbb)%val(jbd))
2336 if (abs(s_test)>abs(
s_inf))
then 2340 if (nam%mpicom==1)
then 2341 add_op = (nicas_blk%lcheck_sb(js).and.(is<=js)).or.(.not.nicas_blk%lcheck_sb(js))
2342 elseif (nam%mpicom==2)
then 2343 add_op = nicas_blk%lcheck_sa(is).and.((nicas_blk%lcheck_sa(js).and.(is<=js)) &
2344 & .or.(.not.nicas_blk%lcheck_sa(js)))
2349 if (add_op)
call c(ithread)%add_op(c_n_s(ithread),is,js,s_test)
2352 add_op = nicas_blk%lcheck_sb(is).and.((nicas_blk%lcheck_sb(js).and.(is<=js)).or.(.not.nicas_blk%lcheck_sb(js)))
2353 if (add_op)
call c_nor(ithread)%add_op(c_nor_n_s(ithread),is,js,s_test)
2358 call mpl%prog_print(isbb)
2361 write(mpl%info,
'(a)')
'100%' 2362 call flush(mpl%info)
2365 call ctmp%gather(mpl,c_n_s,c)
2366 call nicas_blk%c_nor%gather(mpl,c_nor_n_s,c_nor)
2369 do ithread=1,mpl%nthread
2370 call c(ithread)%dealloc
2371 call c_nor(ithread)%dealloc
2385 class(nicas_blk_type),
intent(inout) :: nicas_blk
2386 type(mpl_type),
intent(inout) :: mpl
2387 type(geom_type),
intent(in) :: geom
2390 integer :: isa,isb,isc,i_s,is,js
2391 integer,
allocatable :: s_to_proc(:)
2392 logical,
allocatable :: lcheck_sc_nor(:)
2395 allocate(nicas_blk%lcheck_sc(nicas_blk%ns))
2396 allocate(lcheck_sc_nor(nicas_blk%ns))
2397 allocate(s_to_proc(nicas_blk%ns))
2402 nicas_blk%lcheck_sc = nicas_blk%lcheck_sb
2403 do i_s=1,nicas_blk%c%n_s
2404 is = nicas_blk%c%row(i_s)
2405 js = nicas_blk%c%col(i_s)
2406 nicas_blk%lcheck_sc(is) = .true.
2407 nicas_blk%lcheck_sc(js) = .true.
2409 nicas_blk%nsc = count(nicas_blk%lcheck_sc)
2410 lcheck_sc_nor = nicas_blk%lcheck_sb
2411 do i_s=1,nicas_blk%c_nor%n_s
2412 is = nicas_blk%c_nor%row(i_s)
2413 js = nicas_blk%c_nor%col(i_s)
2414 lcheck_sc_nor(is) = .true.
2415 lcheck_sc_nor(js) = .true.
2417 nicas_blk%nsc_nor = count(lcheck_sc_nor)
2420 do is=1,nicas_blk%ns
2421 if (nicas_blk%lcheck_sa(is).and.(.not.nicas_blk%lcheck_sc(is)))
call mpl%abort(
'point in halo A but not in halo C')
2422 if (nicas_blk%lcheck_sb(is).and.(.not.nicas_blk%lcheck_sc(is)))
call mpl%abort(
'point in halo B but not in halo C')
2428 allocate(nicas_blk%sc_to_s(nicas_blk%nsc))
2429 allocate(nicas_blk%s_to_sc(nicas_blk%ns))
2430 call msi(nicas_blk%s_to_sc)
2432 do is=1,nicas_blk%ns
2433 if (nicas_blk%lcheck_sc(is))
then 2435 nicas_blk%sc_to_s(isc) = is
2436 nicas_blk%s_to_sc(is) = isc
2440 allocate(nicas_blk%sc_nor_to_s(nicas_blk%nsc_nor))
2441 allocate(nicas_blk%s_to_sc_nor(nicas_blk%ns))
2442 call msi(nicas_blk%s_to_sc_nor)
2444 do is=1,nicas_blk%ns
2445 if (lcheck_sc_nor(is))
then 2447 nicas_blk%sc_nor_to_s(isc) = is
2448 nicas_blk%s_to_sc_nor(is) = isc
2453 allocate(nicas_blk%sa_to_sc(nicas_blk%nsa))
2454 do isa=1,nicas_blk%nsa
2455 is = nicas_blk%sa_to_s(isa)
2456 isc = nicas_blk%s_to_sc(is)
2457 nicas_blk%sa_to_sc(isa) = isc
2459 allocate(nicas_blk%sb_to_sc(nicas_blk%nsb))
2460 allocate(nicas_blk%sc_to_sb(nicas_blk%nsc))
2461 allocate(nicas_blk%sb_to_sc_nor(nicas_blk%nsb))
2462 call msi(nicas_blk%sc_to_sb)
2463 do isb=1,nicas_blk%nsb
2464 is = nicas_blk%sb_to_s(isb)
2465 isc = nicas_blk%s_to_sc(is)
2466 nicas_blk%sb_to_sc(isb) = isc
2467 nicas_blk%sc_to_sb(isc) = isb
2468 isc = nicas_blk%s_to_sc_nor(is)
2469 nicas_blk%sb_to_sc_nor(isb) = isc
2475 nicas_blk%c%n_src = nicas_blk%nsc
2476 nicas_blk%c%n_dst = nicas_blk%nsc
2477 do i_s=1,nicas_blk%c%n_s
2478 nicas_blk%c%row(i_s) = nicas_blk%s_to_sc(nicas_blk%c%row(i_s))
2479 nicas_blk%c%col(i_s) = nicas_blk%s_to_sc(nicas_blk%c%col(i_s))
2481 call nicas_blk%c%reorder(mpl)
2484 nicas_blk%c_nor%n_src = nicas_blk%nsc
2485 nicas_blk%c_nor%n_dst = nicas_blk%nsc
2486 do i_s=1,nicas_blk%c_nor%n_s
2487 nicas_blk%c_nor%row(i_s) = nicas_blk%s_to_sc_nor(nicas_blk%c_nor%row(i_s))
2488 nicas_blk%c_nor%col(i_s) = nicas_blk%s_to_sc_nor(nicas_blk%c_nor%col(i_s))
2490 call nicas_blk%c_nor%reorder(mpl)
2493 s_to_proc = geom%c0_to_proc(nicas_blk%c1_to_c0(nicas_blk%s_to_c1))
2494 call nicas_blk%com_AC%setup(mpl,
'com_AC',nicas_blk%ns,nicas_blk%nsa,nicas_blk%nsc,nicas_blk%sc_to_s,nicas_blk%sa_to_sc, &
2495 & s_to_proc,nicas_blk%s_to_sa)
2508 class(nicas_blk_type),
intent(inout) :: nicas_blk
2509 type(mpl_type),
intent(inout) :: mpl
2510 type(nam_type),
intent(in) :: nam
2511 type(geom_type),
intent(in) :: geom
2514 integer :: il0i,i_s,ic1,ic1b,jc1b,is,js,isc,jsb,jsc,ic0,ic0a,il0,il1,ih,jv,nlr,ilr,ic,isc_add
2515 integer,
allocatable :: ineh(:,:),inev(:),ines(:,:),inec(:),order(:),isc_list(:)
2516 integer,
allocatable :: h_col(:,:,:),v_col(:,:),s_col(:,:,:),c_ind(:,:)
2517 real(kind_real) :: S_add
2518 real(kind_real),
allocatable :: h_S(:,:,:),v_S(:,:,:),s_S(:,:,:),c_S(:,:)
2519 real(kind_real),
allocatable :: list(:),S_list(:),S_list_tmp(:)
2522 allocate(ineh(geom%nc0a,geom%nl0i))
2525 do i_s=1,nicas_blk%h(il0i)%n_s
2526 ic0a = nicas_blk%h(il0i)%row(i_s)
2527 ineh(ic0a,il0i) = ineh(ic0a,il0i)+1
2530 allocate(h_col(maxval(ineh),geom%nc0a,geom%nl0i))
2531 allocate(h_s(maxval(ineh),geom%nc0a,geom%nl0i))
2536 do i_s=1,nicas_blk%h(il0i)%n_s
2537 ic0a = nicas_blk%h(il0i)%row(i_s)
2538 ineh(ic0a,il0i) = ineh(ic0a,il0i)+1
2539 h_col(ineh(ic0a,il0i),ic0a,il0i) = nicas_blk%h(il0i)%col(i_s)
2540 h_s(ineh(ic0a,il0i),ic0a,il0i) = nicas_blk%h(il0i)%S(i_s)
2545 allocate(inev(geom%nl0))
2547 do i_s=1,nicas_blk%v%n_s
2548 il0 = nicas_blk%v%row(i_s)
2549 inev(il0) = inev(il0)+1
2551 allocate(v_col(maxval(inev),geom%nl0))
2552 allocate(v_s(maxval(inev),nicas_blk%nc1b,geom%nl0))
2556 do i_s=1,nicas_blk%v%n_s
2557 il0 = nicas_blk%v%row(i_s)
2558 inev(il0) = inev(il0)+1
2559 v_col(inev(il0),il0) = nicas_blk%v%col(i_s)
2560 do ic1b=1,nicas_blk%nc1b
2561 v_s(inev(il0),ic1b,il0) = nicas_blk%v%Svec(i_s,ic1b)
2566 allocate(ines(nicas_blk%nc1b,nicas_blk%nl1))
2568 do il1=1,nicas_blk%nl1
2569 do i_s=1,nicas_blk%s(il1)%n_s
2570 ic1b = nicas_blk%s(il1)%row(i_s)
2571 ines(ic1b,il1) = ines(ic1b,il1)+1
2574 allocate(s_col(maxval(ines),nicas_blk%nc1b,nicas_blk%nl1))
2575 allocate(s_s(maxval(ines),nicas_blk%nc1b,nicas_blk%nl1))
2579 do il1=1,nicas_blk%nl1
2580 do i_s=1,nicas_blk%s(il1)%n_s
2581 ic1b = nicas_blk%s(il1)%row(i_s)
2582 ines(ic1b,il1) = ines(ic1b,il1)+1
2583 jc1b = nicas_blk%s(il1)%col(i_s)
2584 jsb = nicas_blk%c1bl1_to_sb(jc1b,il1)
2585 jsc = nicas_blk%sb_to_sc_nor(jsb)
2586 s_col(ines(ic1b,il1),ic1b,il1) = jsc
2587 s_s(ines(ic1b,il1),ic1b,il1) = nicas_blk%s(il1)%S(i_s)
2592 allocate(inec(nicas_blk%nsc_nor))
2594 do i_s=1,nicas_blk%c_nor%n_s
2595 isc = nicas_blk%c_nor%col(i_s)
2596 jsc = nicas_blk%c_nor%row(i_s)
2598 is = nicas_blk%sc_nor_to_s(isc)
2599 inec(isc) = inec(isc)+1
2600 js = nicas_blk%sc_nor_to_s(jsc)
2601 inec(jsc) = inec(jsc)+1
2604 allocate(c_ind(maxval(inec),nicas_blk%nsc_nor))
2605 allocate(c_s(maxval(inec),nicas_blk%nsc_nor))
2609 do i_s=1,nicas_blk%c_nor%n_s
2610 isc = nicas_blk%c_nor%col(i_s)
2611 jsc = nicas_blk%c_nor%row(i_s)
2613 is = nicas_blk%sc_nor_to_s(isc)
2614 inec(isc) = inec(isc)+1
2615 c_ind(inec(isc),isc) = jsc
2616 c_s(inec(isc),isc) = nicas_blk%c_nor%S(i_s)
2617 js = nicas_blk%sc_nor_to_s(jsc)
2618 inec(jsc) = inec(jsc)+1
2619 c_ind(inec(jsc),jsc) = isc
2620 c_s(inec(jsc),jsc) = nicas_blk%c_nor%S(i_s)
2625 do isc=1,nicas_blk%nsc_nor
2627 allocate(order(inec(isc)))
2628 allocate(list(inec(isc)))
2631 list = c_ind(1:inec(isc),isc)
2634 call qsort(inec(isc),list,order)
2637 c_ind(1:inec(isc),isc) = c_ind(order(1:inec(isc)),isc)
2638 c_s(1:inec(isc),isc) = c_s(order(1:inec(isc)),isc)
2646 allocate(nicas_blk%norm(geom%nc0a,geom%nl0))
2647 call msr(nicas_blk%norm)
2651 il0i =
min(il0,geom%nl0i)
2652 write(mpl%info,
'(a10,a,i3,a)',advance=
'no')
'',
'Level ',nam%levs(il0),
': ' 2653 call flush(mpl%info)
2654 call mpl%prog_init(geom%nc0a)
2660 ic0 = geom%c0a_to_c0(ic0a)
2662 if (geom%mask_c0(ic0,il0))
then 2664 allocate(isc_list(ineh(ic0a,il0i)*inev(il0)*maxval(ines)))
2665 allocate(s_list(ineh(ic0a,il0i)*inev(il0)*maxval(ines)))
2666 allocate(s_list_tmp(nicas_blk%nsc_nor))
2674 do ih=1,ineh(ic0a,il0i)
2675 ic1b = h_col(ih,ic0a,il0i)
2676 ic1 = nicas_blk%c1b_to_c1(ic1b)
2679 if ((nicas_blk%l1_to_l0(il1)>=nicas_blk%vbot(ic1)).and.(nicas_blk%l1_to_l0(il1)<=nicas_blk%vtop(ic1)))
then 2680 do is=1,ines(ic1b,il1)
2681 isc_add = s_col(is,ic1b,il1)
2682 s_add = h_s(ih,ic0a,il0i)*v_s(jv,ic1b,il0)*s_s(is,ic1b,il1)
2688 if (isc_add==isc_list(ilr))
exit 2690 if (ilr==nlr+1) nlr = nlr+1
2692 isc_list(ilr) = isc_add
2693 s_list(ilr) = s_list(ilr)+s_add
2703 s_list_tmp(isc) = s_list(ilr)
2711 s_list_tmp(jsc) = s_list_tmp(jsc)+c_s(ic,isc)*s_list(ilr)
2716 nicas_blk%norm(ic0a,il0) = sum(s_list_tmp**2)
2719 nicas_blk%norm(ic0a,il0) = 1.0/sqrt(nicas_blk%norm(ic0a,il0))
2722 call mpl%prog_print(ic0a)
2725 deallocate(isc_list)
2727 deallocate(s_list_tmp)
2731 write(mpl%info,
'(a)')
'100%' 2732 call flush(mpl%info)
2746 class(nicas_blk_type),
intent(inout) :: nicas_blk
2747 type(mpl_type),
intent(inout) :: mpl
2748 type(rng_type),
intent(inout) :: rng
2749 type(nam_type),
intent(in) :: nam
2750 type(geom_type),
intent(in) :: geom
2751 type(cmat_blk_type),
intent(in) :: cmat_blk
2754 integer :: its,il0,ic0,ic0a,i_s,i_s_loc,iproc,jc0
2755 integer :: ic0d,d_n_s_max,d_n_s_max_loc
2756 integer :: ic0dinv,dinv_n_s_max,dinv_n_s_max_loc
2757 integer,
allocatable :: c0d_to_c0(:),c0_to_c0d(:),c0a_to_c0d(:),interpd_lg(:,:,:)
2758 integer,
allocatable :: c0dinv_to_c0(:),c0_to_c0dinv(:),c0a_to_c0dinv(:),interpdinv_lg(:,:,:)
2759 real(kind_real) :: displ_lon(geom%nc0,geom%nl0),displ_lat(geom%nc0,geom%nl0)
2760 logical :: mask_c0(geom%nc0)
2761 logical,
allocatable :: lcheck_c0d(:),lcheck_d(:,:,:)
2762 logical,
allocatable :: lcheck_c0dinv(:),lcheck_dinv(:,:,:)
2763 type(linop_type),
allocatable :: dfull(:,:)
2764 type(linop_type),
allocatable :: dinvfull(:,:)
2766 write(mpl%info,
'(a7,a)')
'',
'Compute advection' 2767 call flush(mpl%info)
2770 allocate(dfull(geom%nl0,2:nam%nts))
2771 allocate(dinvfull(geom%nl0,2:nam%nts))
2778 call mpl%loc_to_glb(geom%nl0,geom%nc0a,cmat_blk%displ_lon(:,:,its),geom%nc0,geom%c0_to_proc,geom%c0_to_c0a,.true.,displ_lon)
2779 call mpl%loc_to_glb(geom%nl0,geom%nc0a,cmat_blk%displ_lat(:,:,its),geom%nc0,geom%c0_to_proc,geom%c0_to_c0a,.true.,displ_lat)
2783 call dfull(il0,its)%interp(mpl,rng,geom%nc0,displ_lon(:,il0),displ_lat(:,il0),mask_c0,geom%nc0,geom%lon,geom%lat,mask_c0, &
2787 call dinvfull(il0,its)%interp(mpl,rng,geom%nc0,geom%lon,geom%lat,mask_c0,geom%nc0,displ_lon(:,il0),displ_lat(:,il0),mask_c0, &
2797 d_n_s_max =
max(d_n_s_max,dfull(il0,its)%n_s)
2798 dinv_n_s_max =
max(dinv_n_s_max,dinvfull(il0,its)%n_s)
2801 allocate(lcheck_c0d(geom%nc0))
2802 allocate(lcheck_c0dinv(geom%nc0))
2803 allocate(lcheck_d(d_n_s_max,geom%nl0,2:nam%nts))
2804 allocate(lcheck_dinv(dinv_n_s_max,geom%nl0,2:nam%nts))
2805 allocate(nicas_blk%d(geom%nl0,2:nam%nts))
2806 allocate(nicas_blk%dinv(geom%nl0,2:nam%nts))
2811 lcheck_c0d = .false.
2812 lcheck_c0dinv = .false.
2814 ic0 = geom%c0a_to_c0(ic0a)
2815 lcheck_c0d(ic0) = .true.
2816 lcheck_c0dinv(ic0) = .true.
2821 lcheck_dinv = .false.
2824 do i_s=1,dfull(il0,its)%n_s
2825 ic0 = dfull(il0,its)%row(i_s)
2826 iproc = geom%c0_to_proc(ic0)
2827 if (iproc==mpl%myproc)
then 2828 jc0 = dfull(il0,its)%col(i_s)
2829 lcheck_d(i_s,il0,its) = .true.
2830 lcheck_c0d(jc0) = .true.
2833 do i_s=1,dinvfull(il0,its)%n_s
2834 ic0 = dinvfull(il0,its)%row(i_s)
2835 iproc = geom%c0_to_proc(ic0)
2836 if (iproc==mpl%myproc)
then 2837 jc0 = dinvfull(il0,its)%col(i_s)
2838 lcheck_dinv(i_s,il0,its) = .true.
2839 lcheck_c0dinv(jc0) = .true.
2848 nicas_blk%d(il0,its)%n_s = count(lcheck_d(:,il0,its))
2849 nicas_blk%dinv(il0,its)%n_s = count(lcheck_dinv(:,il0,its))
2852 nicas_blk%nc0d = count(lcheck_c0d)
2853 nicas_blk%nc0dinv = count(lcheck_c0dinv)
2856 allocate(c0d_to_c0(nicas_blk%nc0d))
2857 allocate(c0dinv_to_c0(nicas_blk%nc0dinv))
2858 allocate(c0_to_c0d(geom%nc0))
2859 allocate(c0_to_c0dinv(geom%nc0))
2861 call msi(c0_to_c0dinv)
2865 if (lcheck_c0d(ic0))
then 2867 c0d_to_c0(ic0d) = ic0
2868 c0_to_c0d(ic0) = ic0d
2870 if (lcheck_c0dinv(ic0))
then 2872 c0dinv_to_c0(ic0dinv) = ic0
2873 c0_to_c0dinv(ic0) = ic0dinv
2878 allocate(c0a_to_c0d(geom%nc0a))
2879 allocate(c0a_to_c0dinv(geom%nc0a))
2881 ic0 = geom%c0a_to_c0(ic0a)
2882 ic0d = c0_to_c0d(ic0)
2883 ic0dinv = c0_to_c0dinv(ic0)
2884 c0a_to_c0d(ic0a) = ic0d
2885 c0a_to_c0dinv(ic0a) = ic0dinv
2890 dinv_n_s_max_loc = 0
2893 d_n_s_max_loc =
max(d_n_s_max_loc,nicas_blk%d(il0,its)%n_s)
2894 dinv_n_s_max_loc =
max(dinv_n_s_max_loc,nicas_blk%dinv(il0,its)%n_s)
2897 allocate(interpd_lg(d_n_s_max_loc,geom%nl0,2:nam%nts))
2898 allocate(interpdinv_lg(dinv_n_s_max_loc,geom%nl0,2:nam%nts))
2902 do i_s=1,dfull(il0,its)%n_s
2903 if (lcheck_d(i_s,il0,its))
then 2905 interpd_lg(i_s_loc,il0,its) = i_s
2909 do i_s=1,dinvfull(il0,its)%n_s
2910 if (lcheck_dinv(i_s,il0,its))
then 2912 interpdinv_lg(i_s_loc,il0,its) = i_s
2921 write(nicas_blk%d(il0,its)%prefix,
'(a,i3.3,a,i2.2)')
'd_',il0,
'_',its
2922 write(nicas_blk%dinv(il0,its)%prefix,
'(a,i3.3,a,i2.2)')
'dinv_',il0,
'_',its
2923 nicas_blk%d(il0,its)%n_src = nicas_blk%nc0d
2924 nicas_blk%dinv(il0,its)%n_src = nicas_blk%nc0dinv
2925 nicas_blk%d(il0,its)%n_dst = geom%nc0a
2926 nicas_blk%dinv(il0,its)%n_dst = geom%nc0a
2927 call nicas_blk%d(il0,its)%alloc
2928 call nicas_blk%dinv(il0,its)%alloc
2929 do i_s_loc=1,nicas_blk%d(il0,its)%n_s
2930 i_s = interpd_lg(i_s_loc,il0,its)
2931 nicas_blk%d(il0,its)%row(i_s_loc) = geom%c0_to_c0a(dfull(il0,its)%row(i_s))
2932 nicas_blk%d(il0,its)%col(i_s_loc) = c0_to_c0d(dfull(il0,its)%col(i_s))
2933 nicas_blk%d(il0,its)%S(i_s_loc) = dfull(il0,its)%S(i_s)
2935 do i_s_loc=1,nicas_blk%dinv(il0,its)%n_s
2936 i_s = interpdinv_lg(i_s_loc,il0,its)
2937 nicas_blk%dinv(il0,its)%row(i_s_loc) = geom%c0_to_c0a(dinvfull(il0,its)%row(i_s))
2938 nicas_blk%dinv(il0,its)%col(i_s_loc) = c0_to_c0dinv(dinvfull(il0,its)%col(i_s))
2939 nicas_blk%dinv(il0,its)%S(i_s_loc) = dinvfull(il0,its)%S(i_s)
2941 call nicas_blk%d(il0,its)%reorder(mpl)
2942 call nicas_blk%dinv(il0,its)%reorder(mpl)
2947 call nicas_blk%com_AD%setup(mpl,
'com_AD',geom%nc0,geom%nc0a,nicas_blk%nc0d,c0d_to_c0,c0a_to_c0d,geom%c0_to_proc,geom%c0_to_c0a)
2948 call nicas_blk%com_ADinv%setup(mpl,
'com_ADinv',geom%nc0,geom%nc0a,nicas_blk%nc0dinv,c0dinv_to_c0,c0a_to_c0dinv, &
2949 & geom%c0_to_proc,geom%c0_to_c0a)
2952 write(mpl%info,
'(a7,a,i4)')
'',
'Parameters for processor #',mpl%myproc
2953 write(mpl%info,
'(a10,a,i8)')
'',
'nc0d = ',nicas_blk%nc0d
2954 write(mpl%info,
'(a10,a,i8)')
'',
'nc0dinv = ',nicas_blk%nc0dinv
2957 write(mpl%info,
'(a10,a,i3,a,i2,a,i8)')
'',
'd(',il0,
',',its,
')%n_s = ',nicas_blk%d(il0,its)%n_s
2958 write(mpl%info,
'(a10,a,i3,a,i2,a,i8)')
'',
'dinv(',il0,
',',its,
')%n_s = ',nicas_blk%dinv(il0,its)%n_s
2961 call flush(mpl%info)
2974 class(nicas_blk_type),
intent(in) :: nicas_blk
2975 type(mpl_type),
intent(in) :: mpl
2976 type(nam_type),
intent(in) :: nam
2977 type(geom_type),
intent(in) :: geom
2978 real(kind_real),
intent(inout) :: fld(geom%nc0a,geom%nl0)
2981 real(kind_real) :: alpha_a(nicas_blk%nsa),alpha_b(nicas_blk%nsb),alpha_c(nicas_blk%nsc)
2984 call nicas_blk%apply_interp_ad(mpl,geom,fld,alpha_b)
2987 if (nam%mpicom==1)
then 2992 alpha_c(nicas_blk%sb_to_sc) = alpha_b
2993 elseif (nam%mpicom==2)
then 2995 call nicas_blk%com_AB%red(mpl,alpha_b,alpha_a)
3001 alpha_c(nicas_blk%sa_to_sc) = alpha_a
3005 call nicas_blk%apply_convol(mpl,alpha_c)
3008 call nicas_blk%com_AC%red(mpl,alpha_c,alpha_a)
3011 call nicas_blk%com_AB%ext(mpl,alpha_a,alpha_b)
3014 call nicas_blk%apply_interp(mpl,geom,alpha_b,fld)
3027 class(nicas_blk_type),
intent(in) :: nicas_blk
3028 type(mpl_type),
intent(in) :: mpl
3029 type(geom_type),
intent(in) :: geom
3030 real(kind_real),
intent(inout) :: fld(geom%nc0a,geom%nl0)
3033 real(kind_real) :: alpha(nicas_blk%nsa)
3036 call nicas_blk%apply_sqrt_ad(mpl,geom,fld,alpha)
3039 call nicas_blk%apply_sqrt(mpl,geom,alpha,fld)
3052 class(nicas_blk_type),
intent(in) :: nicas_blk
3053 type(mpl_type),
intent(in) :: mpl
3054 type(geom_type),
intent(in) :: geom
3055 real(kind_real),
intent(in) :: alpha(nicas_blk%nsa)
3056 real(kind_real),
intent(out) :: fld(geom%nc0a,geom%nl0)
3059 real(kind_real) :: alpha_a(nicas_blk%nsa),alpha_b(nicas_blk%nsb),alpha_c(nicas_blk%nsc)
3065 alpha_c(nicas_blk%sa_to_sc) = alpha
3068 call nicas_blk%apply_convol(mpl,alpha_c)
3071 call nicas_blk%com_AC%red(mpl,alpha_c,alpha_a)
3074 call nicas_blk%com_AB%ext(mpl,alpha_a,alpha_b)
3077 call nicas_blk%apply_interp(mpl,geom,alpha_b,fld)
3090 class(nicas_blk_type),
intent(in) :: nicas_blk
3091 type(mpl_type),
intent(in) :: mpl
3092 type(geom_type),
intent(in) :: geom
3093 real(kind_real),
intent(in) :: fld(geom%nc0a,geom%nl0)
3094 real(kind_real),
intent(out) :: alpha(nicas_blk%nsa)
3097 real(kind_real) :: alpha_b(nicas_blk%nsb),alpha_c(nicas_blk%nsc)
3100 call nicas_blk%apply_interp_ad(mpl,geom,fld,alpha_b)
3103 call nicas_blk%com_AB%red(mpl,alpha_b,alpha)
3109 alpha_c(nicas_blk%sa_to_sc) = alpha
3112 call nicas_blk%apply_convol(mpl,alpha_c)
3115 call nicas_blk%com_AC%red(mpl,alpha_c,alpha)
3128 class(nicas_blk_type),
intent(in) :: nicas_blk
3129 type(mpl_type),
intent(in) :: mpl
3130 type(geom_type),
intent(in) :: geom
3131 real(kind_real),
intent(in) :: alpha(nicas_blk%nsb)
3132 real(kind_real),
intent(out) :: fld(geom%nc0a,geom%nl0)
3135 real(kind_real) :: gamma(nicas_blk%nc1b,nicas_blk%nl1),delta(nicas_blk%nc1b,geom%nl0)
3138 call nicas_blk%apply_interp_s(mpl,alpha,gamma)
3141 call nicas_blk%apply_interp_v(mpl,geom,gamma,delta)
3144 call nicas_blk%apply_interp_h(mpl,geom,delta,fld)
3147 fld = fld*nicas_blk%norm
3160 class(nicas_blk_type),
intent(in) :: nicas_blk
3161 type(mpl_type),
intent(in) :: mpl
3162 type(geom_type),
intent(in) :: geom
3163 real(kind_real),
intent(in) :: fld(geom%nc0a,geom%nl0)
3164 real(kind_real),
intent(out) :: alpha(nicas_blk%nsb)
3167 real(kind_real) :: gamma(nicas_blk%nc1b,nicas_blk%nl1),delta(nicas_blk%nc1b,geom%nl0)
3168 real(kind_real) :: fld_tmp(geom%nc0a,geom%nl0)
3171 fld_tmp = fld*nicas_blk%norm
3174 call nicas_blk%apply_interp_h_ad(mpl,geom,fld_tmp,delta)
3177 call nicas_blk%apply_interp_v_ad(mpl,geom,delta,gamma)
3180 call nicas_blk%apply_interp_s_ad(mpl,gamma,alpha)
3193 class(nicas_blk_type),
intent(in) :: nicas_blk
3194 type(mpl_type),
intent(in) :: mpl
3195 type(geom_type),
intent(in) :: geom
3196 real(kind_real),
intent(in) :: delta(nicas_blk%nc1b,geom%nl0)
3197 real(kind_real),
intent(out) :: fld(geom%nc0a,geom%nl0)
3205 call nicas_blk%h(
min(il0,geom%nl0i))%apply(mpl,delta(:,il0),fld(:,il0),msdst=.false.)
3220 class(nicas_blk_type),
intent(in) :: nicas_blk
3221 type(mpl_type),
intent(in) :: mpl
3222 type(geom_type),
intent(in) :: geom
3223 real(kind_real),
intent(in) :: fld(geom%nc0a,geom%nl0)
3224 real(kind_real),
intent(out) :: delta(nicas_blk%nc1b,geom%nl0)
3231 call nicas_blk%h(
min(il0,geom%nl0i))%apply_ad(mpl,fld(:,il0),delta(:,il0))
3246 class(nicas_blk_type),
intent(in) :: nicas_blk
3247 type(mpl_type),
intent(in) :: mpl
3248 type(geom_type),
intent(in) :: geom
3249 real(kind_real),
intent(in) :: gamma(nicas_blk%nc1b,nicas_blk%nl1)
3250 real(kind_real),
intent(out) :: delta(nicas_blk%nc1b,geom%nl0)
3254 real(kind_real),
allocatable :: gamma_tmp(:),delta_tmp(:)
3258 do ic1b=1,nicas_blk%nc1b
3260 allocate(gamma_tmp(nicas_blk%nl1))
3261 allocate(delta_tmp(geom%nl0))
3264 gamma_tmp = gamma(ic1b,:)
3267 call nicas_blk%v%apply(mpl,gamma_tmp,delta_tmp,ivec=ic1b,msdst=.false.)
3270 delta(ic1b,:) = delta_tmp
3273 deallocate(gamma_tmp)
3274 deallocate(delta_tmp)
3289 class(nicas_blk_type),
intent(in) :: nicas_blk
3290 type(mpl_type),
intent(in) :: mpl
3291 type(geom_type),
intent(in) :: geom
3292 real(kind_real),
intent(in) :: delta(nicas_blk%nc1b,geom%nl0)
3293 real(kind_real),
intent(out) :: gamma(nicas_blk%nc1b,nicas_blk%nl1)
3297 real(kind_real),
allocatable :: gamma_tmp(:),delta_tmp(:)
3301 do ic1b=1,nicas_blk%nc1b
3303 allocate(gamma_tmp(nicas_blk%nl1))
3304 allocate(delta_tmp(geom%nl0))
3307 delta_tmp = delta(ic1b,:)
3310 call nicas_blk%v%apply_ad(mpl,delta_tmp,gamma_tmp,ivec=ic1b)
3313 gamma(ic1b,:) = gamma_tmp
3316 deallocate(gamma_tmp)
3317 deallocate(delta_tmp)
3332 class(nicas_blk_type),
intent(in) :: nicas_blk
3333 type(mpl_type),
intent(in) :: mpl
3334 real(kind_real),
intent(in) :: alpha(nicas_blk%nsb)
3335 real(kind_real),
intent(out) :: gamma(nicas_blk%nc1b,nicas_blk%nl1)
3339 real(kind_real) :: beta(nicas_blk%nc1b,nicas_blk%nl1)
3346 do isb=1,nicas_blk%nsb
3347 beta(nicas_blk%sb_to_c1b(isb),nicas_blk%sb_to_l1(isb)) = alpha(isb)
3353 do il1=1,nicas_blk%nl1
3354 call nicas_blk%s(il1)%apply(mpl,beta(:,il1),gamma(:,il1),msdst=.false.)
3369 class(nicas_blk_type),
intent(in) :: nicas_blk
3370 type(mpl_type),
intent(in) :: mpl
3371 real(kind_real),
intent(in) :: gamma(nicas_blk%nc1b,nicas_blk%nl1)
3372 real(kind_real),
intent(out) :: alpha(nicas_blk%nsb)
3376 real(kind_real) :: beta(nicas_blk%nc1b,nicas_blk%nl1)
3380 do il1=1,nicas_blk%nl1
3381 call nicas_blk%s(il1)%apply_ad(mpl,gamma(:,il1),beta(:,il1))
3387 do isb=1,nicas_blk%nsb
3388 alpha(isb) = beta(nicas_blk%sb_to_c1b(isb),nicas_blk%sb_to_l1(isb))
3403 class(nicas_blk_type),
intent(in) :: nicas_blk
3404 type(mpl_type),
intent(in) :: mpl
3405 real(kind_real),
intent(inout) :: alpha(nicas_blk%nsc)
3408 call nicas_blk%c%apply_sym(mpl,alpha)
3421 class(nicas_blk_type),
intent(in) :: nicas_blk
3422 type(mpl_type),
intent(in) :: mpl
3423 type(nam_type),
target,
intent(in) :: nam
3424 type(geom_type),
target,
intent(in) :: geom
3425 real(kind_real),
intent(inout) :: fld(geom%nc0a,geom%nl0,nam%nv,nam%nts)
3428 integer :: its,iv,il0
3429 real(kind_real) :: fld_d(nicas_blk%nc0d,geom%nl0)
3434 call nicas_blk%com_AD%ext(mpl,geom%nl0,fld(:,:,iv,its),fld_d)
3439 call nicas_blk%d(il0,its)%apply(mpl,fld_d(:,il0),fld(:,il0,iv,its),msdst=.false.)
3456 class(nicas_blk_type),
intent(in) :: nicas_blk
3457 type(mpl_type),
intent(in) :: mpl
3458 type(nam_type),
target,
intent(in) :: nam
3459 type(geom_type),
target,
intent(in) :: geom
3460 real(kind_real),
intent(inout) :: fld(geom%nc0a,geom%nl0,nam%nv,nam%nts)
3463 integer :: its,iv,il0
3464 real(kind_real) :: fld_d(nicas_blk%nc0d,geom%nl0)
3471 call nicas_blk%d(il0,its)%apply_ad(mpl,fld(:,il0,iv,its),fld_d(:,il0))
3476 call nicas_blk%com_AD%red(mpl,geom%nl0,fld_d,fld(:,:,iv,its))
3491 class(nicas_blk_type),
intent(in) :: nicas_blk
3492 type(mpl_type),
intent(in) :: mpl
3493 type(nam_type),
target,
intent(in) :: nam
3494 type(geom_type),
target,
intent(in) :: geom
3495 real(kind_real),
intent(inout) :: fld(geom%nc0a,geom%nl0,nam%nv,nam%nts)
3498 integer :: its,iv,il0
3499 real(kind_real) :: fld_dinv(nicas_blk%nc0dinv,geom%nl0)
3504 call nicas_blk%com_ADinv%ext(mpl,geom%nl0,fld(:,:,iv,its),fld_dinv)
3509 call nicas_blk%dinv(il0,its)%apply(mpl,fld_dinv(:,il0),fld(:,il0,iv,its),msdst=.false.)
3526 class(nicas_blk_type),
intent(in) :: nicas_blk
3527 type(mpl_type),
intent(inout) :: mpl
3528 type(rng_type),
intent(inout) :: rng
3529 type(nam_type),
intent(in) :: nam
3530 type(geom_type),
intent(in) :: geom
3534 real(kind_real) :: sum1,sum2
3535 real(kind_real),
allocatable :: alpha(:),alpha_save(:),alpha1(:),alpha1_save(:),alpha2(:),alpha2_save(:)
3536 real(kind_real),
allocatable :: gamma(:,:),gamma_save(:,:),delta(:,:),delta_save(:,:)
3537 real(kind_real),
allocatable :: fld(:,:),fld_save(:,:),fld1(:,:),fld1_save(:,:),fld2(:,:),fld2_save(:,:)
3540 allocate(alpha(nicas_blk%nsb))
3541 allocate(alpha_save(nicas_blk%nsb))
3542 allocate(gamma(nicas_blk%nc1b,nicas_blk%nl1))
3543 allocate(gamma_save(nicas_blk%nc1b,nicas_blk%nl1))
3544 allocate(delta(nicas_blk%nc1b,geom%nl0))
3545 allocate(delta_save(nicas_blk%nc1b,geom%nl0))
3546 allocate(fld(geom%nc0a,geom%nl0))
3547 allocate(fld_save(geom%nc0a,geom%nl0))
3552 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha_save)
3554 do isb=1,nicas_blk%nsb
3555 call rng%rand_real(0.0_kind_real,1.0_kind_real,gamma_save(nicas_blk%sb_to_c1b(isb),nicas_blk%sb_to_l1(isb)))
3559 call nicas_blk%apply_interp_s(mpl,alpha_save,gamma)
3560 call nicas_blk%apply_interp_s_ad(mpl,gamma_save,alpha)
3563 call mpl%dot_prod(alpha,alpha_save,sum1)
3564 call mpl%dot_prod(gamma,gamma_save,sum2)
3565 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Interpolation adjoint test (subsampling): ', &
3566 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3567 call flush(mpl%info)
3572 call rng%rand_real(0.0_kind_real,1.0_kind_real,gamma_save)
3573 call rng%rand_real(0.0_kind_real,1.0_kind_real,delta_save)
3576 call nicas_blk%apply_interp_v(mpl,geom,gamma_save,delta)
3577 call nicas_blk%apply_interp_v_ad(mpl,geom,delta_save,gamma)
3580 call mpl%dot_prod(gamma,gamma_save,sum1)
3581 call mpl%dot_prod(delta,delta_save,sum2)
3582 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Interpolation adjoint test (vertical): ', &
3583 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3584 call flush(mpl%info)
3589 call rng%rand_real(0.0_kind_real,1.0_kind_real,delta_save)
3590 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld_save)
3593 call nicas_blk%apply_interp_h(mpl,geom,delta_save,fld)
3594 call nicas_blk%apply_interp_h_ad(mpl,geom,fld_save,delta)
3597 call mpl%dot_prod(delta,delta_save,sum1)
3598 call mpl%dot_prod(fld,fld_save,sum2)
3599 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Interpolation adjoint test (horizontal): ', &
3600 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3601 call flush(mpl%info)
3606 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha_save)
3607 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld_save)
3610 call nicas_blk%apply_interp(mpl,geom,alpha_save,fld)
3611 call nicas_blk%apply_interp_ad(mpl,geom,fld_save,alpha)
3614 call mpl%dot_prod(alpha,alpha_save,sum1)
3615 call mpl%dot_prod(fld,fld_save,sum2)
3616 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Interpolation adjoint test (total): ', &
3617 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3618 call flush(mpl%info)
3621 allocate(alpha1(nicas_blk%nsc))
3622 allocate(alpha1_save(nicas_blk%nsc))
3623 allocate(alpha2(nicas_blk%nsc))
3624 allocate(alpha2_save(nicas_blk%nsc))
3627 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha1_save)
3628 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha2_save)
3629 alpha1 = alpha1_save
3630 alpha2 = alpha2_save
3633 call nicas_blk%apply_convol(mpl,alpha1)
3634 call nicas_blk%apply_convol(mpl,alpha2)
3637 call mpl%dot_prod(alpha1,alpha2_save,sum1)
3638 call mpl%dot_prod(alpha2,alpha1_save,sum2)
3639 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Convolution adjoint test: ', &
3640 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3641 call flush(mpl%info)
3645 deallocate(alpha1_save)
3647 deallocate(alpha2_save)
3648 allocate(alpha1(nicas_blk%nsa))
3649 allocate(alpha1_save(nicas_blk%nsb))
3650 allocate(alpha2(nicas_blk%nsb))
3651 allocate(alpha2_save(nicas_blk%nsa))
3654 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha1_save)
3655 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha2_save)
3658 call nicas_blk%com_AB%red(mpl,alpha1_save,alpha1)
3659 call nicas_blk%com_AB%ext(mpl,alpha2_save,alpha2)
3662 call mpl%dot_prod(alpha1,alpha2_save,sum1)
3663 call mpl%dot_prod(alpha2,alpha1_save,sum2)
3664 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Communication AB adjoint test: ', &
3665 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3666 call flush(mpl%info)
3670 deallocate(alpha1_save)
3672 deallocate(alpha2_save)
3673 allocate(alpha1(nicas_blk%nsa))
3674 allocate(alpha1_save(nicas_blk%nsc))
3675 allocate(alpha2(nicas_blk%nsc))
3676 allocate(alpha2_save(nicas_blk%nsa))
3679 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha1_save)
3680 call rng%rand_real(0.0_kind_real,1.0_kind_real,alpha2_save)
3683 call nicas_blk%com_AC%red(mpl,alpha1_save,alpha1)
3684 call nicas_blk%com_AC%ext(mpl,alpha2_save,alpha2)
3687 call mpl%dot_prod(alpha1,alpha2_save,sum1)
3688 call mpl%dot_prod(alpha2,alpha1_save,sum2)
3689 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'Communication AC adjoint test: ', &
3690 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3691 call flush(mpl%info)
3694 allocate(fld1(geom%nc0a,geom%nl0))
3695 allocate(fld2(geom%nc0a,geom%nl0))
3696 allocate(fld1_save(geom%nc0,geom%nl0))
3697 allocate(fld2_save(geom%nc0,geom%nl0))
3700 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld1_save)
3701 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld2_save)
3707 call nicas_blk%apply_from_sqrt(mpl,geom,fld1)
3708 call nicas_blk%apply_from_sqrt(mpl,geom,fld2)
3710 call nicas_blk%apply(mpl,nam,geom,fld1)
3711 call nicas_blk%apply(mpl,nam,geom,fld2)
3715 call mpl%dot_prod(fld1,fld2_save,sum1)
3716 call mpl%dot_prod(fld2,fld1_save,sum2)
3717 write(mpl%info,
'(a7,a,e15.8,a,e15.8,a,e15.8)')
'',
'NICAS adjoint test: ', &
3718 & sum1,
' / ',sum2,
' / ',2.0*abs(sum1-sum2)/abs(sum1+sum2)
3719 call flush(mpl%info)
3732 class(nicas_blk_type),
intent(in) :: nicas_blk
3733 type(mpl_type),
intent(in) :: mpl
3734 type(rng_type),
intent(inout) :: rng
3735 type(nam_type),
intent(in) :: nam
3736 type(geom_type),
intent(in) :: geom
3740 real(kind_real) :: norm,num,den,egvmax,egvmax_prev,egvmin,egvmin_prev
3741 real(kind_real) :: fld(geom%nc0a,geom%nl0),fld_prev(geom%nc0a,geom%nl0)
3744 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld_prev)
3745 call mpl%dot_prod(fld_prev,fld_prev,norm)
3746 fld_prev = fld_prev/norm
3747 egvmax_prev = huge(1.0)
3755 call nicas_blk%apply_from_sqrt(mpl,geom,fld)
3757 call nicas_blk%apply(mpl,nam,geom,fld)
3761 call mpl%dot_prod(fld,fld_prev,num)
3762 call mpl%dot_prod(fld_prev,fld_prev,den)
3766 call mpl%dot_prod(fld,fld,norm)
3770 if (abs(egvmax-egvmax_prev)<
tol)
exit 3775 egvmax_prev = egvmax
3779 call rng%rand_real(0.0_kind_real,1.0_kind_real,fld_prev)
3780 call mpl%dot_prod(fld_prev,fld_prev,norm)
3781 egvmin_prev = huge(1.0)
3782 fld_prev = fld_prev/norm
3783 egvmin_prev = huge(1.0)
3791 call nicas_blk%apply_from_sqrt(mpl,geom,fld)
3793 call nicas_blk%apply(mpl,nam,geom,fld)
3795 fld = fld-egvmax*fld_prev
3798 call mpl%dot_prod(fld,fld_prev,num)
3799 call mpl%dot_prod(fld_prev,fld_prev,den)
3803 call mpl%dot_prod(fld,fld,norm)
3807 if (egvmax+egvmin<-
tol*egvmax)
then 3808 write(mpl%info,
'(a7,a)')
'',
'NICAS is not positive definite' 3809 call flush(mpl%info)
3816 egvmin_prev = egvmin
3820 if (iter==
nitermax+1)
write(mpl%info,
'(a7,a,e15.8,a,i4,a,e15.8)')
'',
'NICAS seems to be positive definite: difference ', &
3821 & egvmax+egvmin,
' after ',
nitermax,
' iterations for a tolerance ',
tol 3822 call flush(mpl%info)
3835 class(nicas_blk_type),
intent(in) :: nicas_blk
3836 type(mpl_type),
intent(inout) :: mpl
3837 type(rng_type),
intent(inout) :: rng
3838 type(nam_type),
intent(inout) :: nam
3839 type(geom_type),
intent(in) :: geom
3840 type(bpar_type),
intent(in) :: bpar
3841 type(io_type),
intent(in) :: io
3842 type(cmat_blk_type),
intent(in) :: cmat_blk
3845 real(kind_real) :: fld(geom%nc0a,geom%nl0),fld_sqrt(geom%nc0a,geom%nl0)
3846 type(nicas_blk_type) :: nicas_blk_other
3849 associate(ib=>nicas_blk%ib)
3852 call rng%rand_real(-1.0_kind_real,1.0_kind_real,fld)
3857 call nicas_blk%apply_from_sqrt(mpl,geom,fld_sqrt)
3859 call nicas_blk%apply(mpl,nam,geom,fld)
3863 nam%lsqrt = .not.nam%lsqrt
3866 call nicas_blk_other%compute_parameters(mpl,rng,nam,geom,cmat_blk)
3870 call nicas_blk_other%apply_from_sqrt(mpl,geom,fld_sqrt)
3873 call nicas_blk_other%apply(mpl,nam,geom,fld)
3877 if (nam%check_dirac)
call nicas_blk_other%test_dirac(mpl,nam,geom,bpar,io)
3880 nam%lsqrt = .not.nam%lsqrt
3883 write(mpl%info,
'(a7,a,f6.1,a)')
'',
'NICAS full / square-root error:',sqrt(sum((fld_sqrt-fld)**2)/sum(fld**2))*100.0,
'%' 3884 call flush(mpl%info)
3900 class(nicas_blk_type),
intent(in) :: nicas_blk
3901 type(mpl_type),
intent(inout) :: mpl
3902 type(nam_type),
intent(in) :: nam
3903 type(geom_type),
intent(in) :: geom
3904 type(bpar_type),
intent(in) :: bpar
3905 type(io_type),
intent(in) :: io
3909 real(kind_real) :: val,valmin_tot,valmax_tot
3910 real(kind_real) :: fld(geom%nc0a,geom%nl0)
3911 character(len=1024) :: suffix,filename
3914 associate(ib=>nicas_blk%ib)
3919 if (geom%iprocdir(idir)==mpl%myproc) fld(geom%ic0adir(idir),geom%il0dir(idir)) = 1.0
3924 call nicas_blk%apply_from_sqrt(mpl,geom,fld)
3926 call nicas_blk%apply(mpl,nam,geom,fld)
3936 filename = trim(nam%prefix)//
'_dirac' 3937 call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//
'_dirac'//trim(suffix),fld)
3940 write(mpl%info,
'(a7,a)')
'',
'Values at dirac points:' 3941 call flush(mpl%info)
3943 if (geom%iprocdir(idir)==mpl%myproc) val = fld(geom%ic0adir(idir),geom%il0dir(idir))
3944 call mpl%f_comm%broadcast(val,geom%iprocdir(idir)-1)
3945 write(mpl%info,
'(a10,f6.1,a,f6.1,a,f10.7)')
'',geom%londir(idir)*rad2deg,
' / ',geom%latdir(idir)*rad2deg,
': ',val
3946 call flush(mpl%info)
3948 write(mpl%info,
'(a7,a)')
'',
'Min - max: ' 3949 call flush(mpl%info)
3951 call mpl%f_comm%allreduce(minval(fld(:,il0),mask=geom%mask_c0a(:,il0)),valmin_tot,fckit_mpi_min())
3952 call mpl%f_comm%allreduce(maxval(fld(:,il0),mask=geom%mask_c0a(:,il0)),valmax_tot,fckit_mpi_max())
3953 write(mpl%info,
'(a10,a,i3,a,f10.7,a,f10.7)')
'',
'Level ',nam%levs(il0),
': ',valmin_tot,
' - ',valmax_tot
3954 call flush(mpl%info)
subroutine nicas_blk_compute_adv(nicas_blk, mpl, rng, nam, geom, cmat_blk)
subroutine nicas_blk_compute_convol_weights(nicas_blk, mpl, nam, geom, ctmp)
subroutine nicas_blk_compute_parameters(nicas_blk, mpl, rng, nam, geom, cmat_blk)
logical, parameter write_grids
subroutine nicas_blk_apply_interp_s_ad(nicas_blk, mpl, gamma, alpha)
subroutine nicas_blk_test_pos_def(nicas_blk, mpl, rng, nam, geom)
subroutine nicas_blk_apply(nicas_blk, mpl, nam, geom, fld)
subroutine nicas_blk_apply_adv(nicas_blk, mpl, nam, geom, fld)
subroutine nicas_blk_apply_interp_ad(nicas_blk, mpl, geom, fld, alpha)
subroutine nicas_blk_apply_interp_s(nicas_blk, mpl, alpha, gamma)
subroutine nicas_blk_apply_sqrt(nicas_blk, mpl, geom, alpha, fld)
subroutine nicas_blk_apply_convol(nicas_blk, mpl, alpha)
real(kind_real), parameter sqrt_r_dble
subroutine nicas_blk_compute_convol_distance(nicas_blk, mpl, geom)
subroutine balldata_alloc(balldata)
subroutine nicas_blk_test_sqrt(nicas_blk, mpl, rng, nam, geom, bpar, io, cmat_blk)
subroutine nicas_blk_test_adjoint(nicas_blk, mpl, rng, nam, geom)
subroutine nicas_blk_compute_interp_h(nicas_blk, mpl, rng, nam, geom)
subroutine nicas_blk_compute_convol(nicas_blk, mpl, rng, nam, geom, cmat_blk)
subroutine nicas_blk_apply_sqrt_ad(nicas_blk, mpl, geom, fld, alpha)
subroutine nicas_blk_dealloc(nicas_blk, nam, geom)
integer, parameter nc1max
real(kind_real), parameter tol
subroutine nicas_blk_compute_interp_s(nicas_blk, mpl, rng, nam, geom)
subroutine nicas_blk_compute_interp_v(nicas_blk, geom)
real(kind_real), parameter sqrt_r
logical, parameter test_no_point
subroutine nicas_blk_compute_convol_network(nicas_blk, mpl, rng, nam, geom)
subroutine nicas_blk_apply_interp(nicas_blk, mpl, geom, alpha, fld)
subroutine nicas_blk_test_dirac(nicas_blk, mpl, nam, geom, bpar, io)
subroutine nicas_blk_apply_interp_h_ad(nicas_blk, mpl, geom, fld, delta)
real(kind=kind_real), parameter req
Earth radius at equator (m)
subroutine nicas_blk_apply_adv_ad(nicas_blk, mpl, nam, geom, fld)
subroutine nicas_blk_compute_mpi_ab(nicas_blk, mpl, geom)
subroutine nicas_blk_apply_adv_inv(nicas_blk, mpl, nam, geom, fld)
subroutine balldata_pack(balldata, nc1, nl1, val)
real(kind_real), parameter sqrt_rfac
subroutine nicas_blk_apply_from_sqrt(nicas_blk, mpl, geom, fld)
subroutine nicas_blk_compute_sampling(nicas_blk, mpl, rng, nam, geom, cmat_blk)
subroutine nicas_blk_apply_interp_h(nicas_blk, mpl, geom, delta, fld)
integer, parameter, public kind_real
subroutine nicas_blk_apply_interp_v_ad(nicas_blk, mpl, geom, delta, gamma)
real(kind_real), parameter sqrt_coef
real(kind_real), parameter s_inf
subroutine nicas_blk_compute_normalization(nicas_blk, mpl, nam, geom)
subroutine nicas_blk_compute_mpi_c(nicas_blk, mpl, geom)
integer, parameter nitermax
subroutine nicas_blk_apply_interp_v(nicas_blk, mpl, geom, gamma, delta)
subroutine balldata_dealloc(balldata)
real(fp), parameter, public pi