19 real(kind_real),
parameter ::
gc2gau = 0.28
20 real(kind_real),
parameter ::
gau2gc = 3.57
21 real(kind_real),
parameter ::
dmin = 1.0e-12_kind_real
22 real(kind_real),
parameter ::
condmax = 1.0e2
23 integer,
parameter ::
m = 0
41 real(kind_real),
intent(inout) :: lon
42 real(kind_real),
intent(inout) :: lat
48 elseif (lat<-0.5*
pi)
then 66 subroutine sphere_dist(lon_i,lat_i,lon_f,lat_f,dist)
71 real(kind_real),
intent(in) :: lon_i
72 real(kind_real),
intent(in) :: lat_i
73 real(kind_real),
intent(in) :: lon_f
74 real(kind_real),
intent(in) :: lat_f
75 real(kind_real),
intent(out) :: dist
80 dist = atan2(sqrt((cos(lat_f)*sin(lon_f-lon_i))**2 &
81 & +(cos(lat_i)*sin(lat_f)-sin(lat_i)*cos(lat_f)*cos(lon_f-lon_i))**2), &
82 & sin(lat_i)*sin(lat_f)+cos(lat_i)*cos(lat_f)*cos(lon_f-lon_i))
93 subroutine reduce_arc(lon_i,lat_i,lon_f,lat_f,maxdist,dist)
98 real(kind_real),
intent(in) :: lon_i
99 real(kind_real),
intent(in) :: lat_i
100 real(kind_real),
intent(inout) :: lon_f
101 real(kind_real),
intent(inout) :: lat_f
102 real(kind_real),
intent(in) :: maxdist
103 real(kind_real),
intent(out) :: dist
106 real(kind_real) :: theta
112 if (dist>maxdist)
then 114 theta = atan2(sin(lon_f-lon_i)*cos(lat_f),cos(lat_i)*sin(lat_f)-sin(lat_i)*cos(lat_f)*cos(lon_f-lon_i))
120 lat_f = asin(sin(lat_i)*cos(dist)+cos(lat_i)*sin(dist)*cos(theta))
121 lon_f = lon_i+atan2(sin(theta)*sin(dist)*cos(lat_i),cos(dist)-sin(lat_i)*sin(lat_f))
135 real(kind_real),
intent(in) :: v1(3)
136 real(kind_real),
intent(in) :: v2(3)
137 real(kind_real),
intent(out) :: vp(3)
143 vp(1) = v1(2)*v2(3)-v1(3)*v2(2)
144 vp(2) = v1(3)*v2(1)-v1(1)*v2(3)
145 vp(3) = v1(1)*v2(2)-v1(2)*v2(1)
162 real(kind_real),
intent(in) :: v1(3)
163 real(kind_real),
intent(in) :: v2(3)
164 real(kind_real),
intent(in) :: v3(3)
165 real(kind_real),
intent(out) :: p
168 real(kind_real) :: vp(3)
171 vp(1) = v1(2)*v2(3)-v1(3)*v2(2)
172 vp(2) = v1(3)*v2(1)-v1(1)*v2(3)
173 vp(3) = v1(1)*v2(2)-v1(2)*v2(1)
184 subroutine add(value,cumul,num,wgt)
189 real(kind_real),
intent(in) ::
value 190 real(kind_real),
intent(inout) :: cumul
191 real(kind_real),
intent(inout) :: num
192 real(kind_real),
intent(in),
optional :: wgt
195 real(kind_real) :: lwgt
199 if (
present(wgt)) lwgt = wgt
203 cumul = cumul+lwgt*
value 213 subroutine divide(value,num)
218 real(kind_real),
intent(inout) ::
value 219 real(kind_real),
intent(in) :: num
222 if (abs(num)>0.0)
then 234 subroutine fit_diag(mpl,nc3,nl0r,nl0,l0rl0_to_l0,disth,distv,rh,rv,fit)
240 integer,
intent(in) :: nc3
241 integer,
intent(in) :: nl0r
242 integer,
intent(in) :: nl0
243 integer,
intent(in) :: l0rl0_to_l0(nl0r,nl0)
244 real(kind_real),
intent(in) :: disth(nc3)
245 real(kind_real),
intent(in) :: distv(nl0,nl0)
246 real(kind_real),
intent(in) :: rh(nl0)
247 real(kind_real),
intent(in) :: rv(nl0)
248 real(kind_real),
intent(out) :: fit(nc3,nl0r,nl0)
251 integer :: jl0r,jl0,il0,kl0r,kl0,jc3,kc3,
ip,jp,np,np_new
252 integer,
allocatable :: plist(:,:),plist_new(:,:)
253 real(kind_real) :: rhsq,rvsq,distnorm,disttest
254 real(kind_real),
allocatable :: dist(:,:)
255 logical :: add_to_front
264 allocate(plist(nc3*nl0r,2))
265 allocate(plist_new(nc3*nl0r,2))
266 allocate(dist(nc3,nl0r))
273 if (l0rl0_to_l0(jl0r,il0)==il0) plist(1,2) = jl0r
276 dist(plist(1,1),plist(1,2)) = 0.0
286 jl0 = l0rl0_to_l0(jl0r,il0)
289 do kc3=
max(jc3-1,1),
min(jc3+1,nc3)
290 do kl0r=
max(jl0r-1,1),
min(jl0r+1,nl0r)
291 kl0 = l0rl0_to_l0(kl0r,il0)
293 rhsq = 0.5*(rh(jl0)**2+rh(kl0)**2)
298 rvsq = 0.5*(rv(jl0)**2+rv(kl0)**2)
304 distnorm = distnorm+(disth(kc3)-disth(jc3))**2/rhsq
305 elseif (kc3/=jc3)
then 306 distnorm = distnorm+0.5*huge(1.0)
309 distnorm = distnorm+distv(kl0,jl0)**2/rvsq
310 elseif (kl0/=jl0)
then 311 distnorm = distnorm+0.5*huge(1.0)
313 disttest = dist(jc3,jl0r)+sqrt(distnorm)
315 if (disttest<1.0)
then 317 if (disttest<dist(kc3,kl0r))
then 319 dist(kc3,kl0r) = disttest
322 add_to_front = .true.
324 if ((plist_new(jp,1)==kc3).and.(plist_new(jp,2)==kl0r))
then 325 add_to_front = .false.
330 if (add_to_front)
then 333 plist_new(np_new,1) = kc3
334 plist_new(np_new,2) = kl0r
344 plist(1:np,:) = plist_new(1:np,:)
350 distnorm = dist(jc3,jl0r)
351 fit(jc3,jl0r,il0) =
gc99(mpl,distnorm)
357 deallocate(plist_new)
368 subroutine fit_diag_dble(mpl,nc3,nl0r,nl0,l0rl0_to_l0,disth,distv,rh,rv,rv_rfac,rv_coef,fit)
374 integer,
intent(in) :: nc3
375 integer,
intent(in) :: nl0r
376 integer,
intent(in) :: nl0
377 integer,
intent(in) :: l0rl0_to_l0(nl0r,nl0)
378 real(kind_real),
intent(in) :: disth(nc3)
379 real(kind_real),
intent(in) :: distv(nl0,nl0)
380 real(kind_real),
intent(in) :: rh(nl0)
381 real(kind_real),
intent(in) :: rv(nl0)
382 real(kind_real),
intent(in) :: rv_rfac(nl0)
383 real(kind_real),
intent(in) :: rv_coef(nl0)
384 real(kind_real),
intent(out) :: fit(nc3,nl0r,nl0)
387 integer :: jl0r,jl0,il0,kl0r,kl0,jc3,kc3,
ip,jp,np,np_new
388 integer,
allocatable :: plist(:,:),plist_new(:,:)
389 real(kind_real) :: rhsq,rvsq,distnorm,disttest,rfac,coef,distnormv,distnormh
390 real(kind_real),
allocatable :: dist(:,:)
391 logical :: add_to_front
400 allocate(plist(nc3*nl0r,2))
401 allocate(plist_new(nc3*nl0r,2))
402 allocate(dist(nc3,nl0r))
409 if (l0rl0_to_l0(jl0r,il0)==il0) plist(1,2) = jl0r
412 dist(plist(1,1),plist(1,2)) = 0.0
422 jl0 = l0rl0_to_l0(jl0r,il0)
425 do kc3=
max(jc3-1,1),
min(jc3+1,nc3)
426 do kl0r=
max(jl0r-1,1),
min(jl0r+1,nl0r)
427 kl0 = l0rl0_to_l0(kl0r,il0)
429 rhsq = 0.5*(rh(jl0)**2+rh(kl0)**2)
434 rvsq = 0.5*(rv(jl0)**2+rv(kl0)**2)
440 distnorm = distnorm+(disth(kc3)-disth(jc3))**2/rhsq
441 elseif (kc3/=jc3)
then 442 distnorm = distnorm+0.5*huge(1.0)
445 distnorm = distnorm+distv(kl0,jl0)**2/rvsq
446 elseif (kl0/=jl0)
then 447 distnorm = distnorm+0.5*huge(1.0)
449 disttest = dist(jc3,jl0r)+sqrt(distnorm)
451 if (disttest<1.0)
then 453 if (disttest<dist(kc3,kl0r))
then 455 dist(kc3,kl0r) = disttest
458 add_to_front = .true.
460 if ((plist_new(jp,1)==kc3).and.(plist_new(jp,2)==kl0r))
then 461 add_to_front = .false.
466 if (add_to_front)
then 469 plist_new(np_new,1) = kc3
470 plist_new(np_new,2) = kl0r
480 plist(1:np,:) = plist_new(1:np,:)
484 jl0 = l0rl0_to_l0(jl0r,il0)
485 distnormv = dist(1,jl0r)
486 if ((abs(rv_rfac(il0))<0.0).or.(abs(rv_rfac(jl0))<0.0))
then 489 rfac = sqrt(rv_rfac(il0)*rv_rfac(jl0))
491 if ((abs(rv_coef(il0))<0.0).or.(abs(rv_coef(jl0))<0.0))
then 494 coef = sqrt(rv_coef(il0)*rv_coef(jl0))
498 distnorm = dist(jc3,jl0r)
499 distnormh = sqrt(distnorm**2-distnormv**2)
500 fit(jc3,jl0r,il0) =
gc99(mpl,distnormh)*((1.0+coef)*
gc99(mpl,distnormv/rfac)-coef*
gc99(mpl,distnormv))
506 deallocate(plist_new)
517 function gc99(mpl,distnorm)
521 real(kind_real),
intent(in) :: distnorm
524 real(kind_real) ::
gc99 527 if (distnorm<0.0)
call mpl%abort(
'negative normalized distance')
530 if (distnorm<0.5)
then 531 gc99 = -8.0*distnorm**5+8.0*distnorm**4+5.0*distnorm**3-20.0/3.0*distnorm**2+1.0
532 else if (distnorm<1.0)
then 533 gc99 = 8.0/3.0*distnorm**5-8.0*distnorm**4+5.0*distnorm**3+20.0/3.0*distnorm**2-10.0*distnorm+4.0-1.0/(3.0*distnorm)
547 subroutine fit_lct(mpl,nc,nl0,dx,dy,dz,dmask,nscales,D,coef,fit)
553 integer,
intent(in) :: nc
554 integer,
intent(in) :: nl0
555 real(kind_real),
intent(in) :: dx(nc,nl0)
556 real(kind_real),
intent(in) :: dy(nc,nl0)
557 real(kind_real),
intent(in) :: dz(nc,nl0)
558 logical,
intent(in) :: dmask(nc,nl0)
559 integer,
intent(in) :: nscales
560 real(kind_real),
intent(in) :: d(4,nscales)
561 real(kind_real),
intent(in) :: coef(nscales)
562 real(kind_real),
intent(out) :: fit(nc,nl0)
565 integer :: jl0,jc3,iscales
566 real(kind_real) :: dcoef(nscales),d11,d22,d33,d12,h11,h22,h33,h12,rsq
573 dcoef = dcoef/sum(dcoef)
584 d12 = sqrt(d11*d22)*
max(-1.0_kind_real+
dmin,
min(d(4,iscales),1.0_kind_real-
dmin))
587 call lct_d2h(mpl,d11,d22,d33,d12,h11,h22,h33,h12)
593 if (dmask(jc3,jl0))
then 595 if (iscales==1) fit(jc3,jl0) = 0.0
598 rsq = h11*dx(jc3,jl0)**2+h22*dy(jc3,jl0)**2+h33*dz(jc3,jl0)**2+2.0*h12*dx(jc3,jl0)*dy(jc3,jl0)
602 if (rsq<40.0) fit(jc3,jl0) = fit(jc3,jl0)+dcoef(iscales)*exp(-0.5*rsq)
605 fit(jc3,jl0) = fit(jc3,jl0)+dcoef(iscales)*
matern(mpl,
m,sqrt(rsq))
619 subroutine lct_d2h(mpl,D11,D22,D33,D12,H11,H22,H33,H12)
625 real(kind_real),
intent(in) :: d11
626 real(kind_real),
intent(in) :: d22
627 real(kind_real),
intent(in) :: d33
628 real(kind_real),
intent(in) :: d12
629 real(kind_real),
intent(out) :: h11
630 real(kind_real),
intent(out) :: h22
631 real(kind_real),
intent(out) :: h33
632 real(kind_real),
intent(out) :: h12
635 real(kind_real) :: det
646 call mpl%abort(
'non-invertible tensor')
665 real(kind_real),
intent(in) :: d1
666 real(kind_real),
intent(in) :: d2
667 real(kind_real),
intent(in) :: nod
668 logical,
intent(out) :: valid
671 real(kind_real) :: det,tr,diff,ev1,ev2
675 det = d1*d2*(1.0-nod**2)
676 diff = 0.25*(d1-d2)**2+d1*d2*nod**2
678 if ((det>0.0).and..not.(diff<0.0))
then 680 ev1 = 0.5*tr+sqrt(diff)
681 ev2 = 0.5*tr-sqrt(diff)
701 real(kind_real) function matern(mpl,M,x)
707 integer,
intent(in) ::
m 708 real(kind_real),
intent(in) :: x
712 real(kind_real) :: xtmp,beta
715 if (
m<2)
call mpl%abort(
'M should be larger than 2')
716 if (mod(
m,2)>0)
call mpl%abort(
'M should be even')
750 integer,
intent(in) :: n
751 real(kind_real),
intent(in) :: a(n,n)
752 real(kind_real),
intent(out) :: u(n,n)
756 real(kind_real),
allocatable :: apack(:),upack(:)
792 subroutine syminv(mpl,n,a,c)
798 integer,
intent(in) :: n
799 real(kind_real),
intent(in) :: a(n,n)
800 real(kind_real),
intent(out) :: c(n,n)
804 real(kind_real),
allocatable :: apack(:),cpack(:)
integer, parameter, public ip
integer, parameter, public kind_real
real(fp), parameter, public pi