20#include "scaleFElib.h"
26 use scale_const,
only: &
29 rplanet => const_radius
36 use openacc,
only: acc_async_sync
56 module procedure :: cubedspherecoordcnv_cs2localorthvec_alpha_0
57 module procedure :: cubedspherecoordcnv_cs2localorthvec_alpha_1
62 module procedure :: cubedspherecoordcnv_localorth2csvec_alpha_0
63 module procedure :: cubedspherecoordcnv_localorth2csvec_alpha_1
87 panelID, alpha, beta, gam, Np, & ! (in)
93 integer,
intent(in) :: panelid
94 integer,
intent(in) :: np
95 real(rp),
intent(in) :: alpha(np)
96 real(rp),
intent(in) :: beta (np)
97 real(rp),
intent(in) :: gam(np)
98 real(rp),
intent(out) :: lon(np)
99 real(rp),
intent(out) :: lat(np)
101 real(rp) :: cartpos(np,3)
102 real(rp) :: geogpos(np,3)
107 select case( panelid )
112 lon(p) = alpha(p) + 0.5_rp * pi * dble(panelid - 1)
113 lat(p) = atan( tan( beta(p) ) * cos( alpha(p) ) )
115 if ( lon(p) < 0.0_rp ) lon(p) = lon(p) + 2.0_rp * pi
121 cartpos(:,1), cartpos(:,2), cartpos(:,3) )
129 lon(p) = geogpos(p,1)
130 lat(p) = geogpos(p,2)
132 if ( alpha(p) < 0.0_rp ) lon(p) = lon(p) + 2.0_rp * pi
137 log_error(
"CubedSphereCoordCnv_CS2LonLatPos",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
148 panelID, alpha, beta, gam, Np, & ! (in)
153 use scale_const,
only: &
157 integer,
intent(in) :: panelid
158 integer,
intent(in) :: np
159 real(rp),
intent(in) :: alpha(np)
160 real(rp),
intent(in) :: beta (np)
161 real(rp),
intent(in) :: gam(np)
162 real(dp),
intent(in) :: vecalpha(np)
163 real(dp),
intent(in) :: vecbeta (np)
164 real(rp),
intent(out) :: veclon(np)
165 real(rp),
intent(out) :: veclat(np)
166 real(rp),
intent(in),
optional :: lat(np)
167 integer,
intent(in),
optional :: gpu_async_id
170 real(rp) :: x ,y, del2
174 real(rp) :: cos_lat(np)
176 integer :: gpu_async_id_
180 if (
present(gpu_async_id))
then
181 gpu_async_id_ = gpu_async_id
183 gpu_async_id_ = acc_async_sync
189 if (
present(lat))
then
193 cos_lat(p) = cos(lat(p))
197 select case( panelid )
199 if (.not.
present(lat))
then
203 cos_lat(p) = cos( atan( tan( beta(p) ) * cos( alpha(p) ) ) )
212 del2 = 1.0_rp + x**2 + y**2
213 radius = rplanet * gam(p)
215 veclon(p) = vecalpha(p) * cos_lat(p) * radius
216 veclat(p) = ( - x * y * vecalpha(p) + ( 1.0_rp + y**2 ) * vecbeta(p) ) &
217 * radius * sqrt( 1.0_rp + x**2 ) / del2
224 log_error(
"CubedSphereCoordCnv_CS2LonLatVec",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
228 select case( panelid )
235 del2 = 1.0_rp + x**2 + y**2
236 radius = s * rplanet * gam(p)
238 if (.not.
present(lat))
then
239 cos_lat(p) = cos( atan( sign(1.0_rp, s) / max( sqrt( x**2 + y**2 ), eps ) ) )
242 veclon(p) = (- y * ( 1.0_rp + x**2 ) * vecalpha(p) + x * ( 1.0_rp + y**2 ) * vecbeta(p) ) &
243 * radius / max( x**2 + y**2, eps ) * cos_lat(p)
244 veclat(p) = (- x * ( 1.0_rp + x**2 ) * vecalpha(p) - y * ( 1.0_rp + y**2 ) * vecbeta(p) ) &
245 * radius / ( del2 * ( max( sqrt( x**2 + y**2 ), eps ) ) )
258 panelID, lon, lat, Np, & ! (in)
262 integer,
intent(in) :: panelid
263 integer,
intent(in) :: np
264 real(rp),
intent(in) :: lon(np)
265 real(rp),
intent(in) :: lat(np)
266 real(rp),
intent(out) ::alpha(np)
267 real(rp),
intent(out) ::beta (np)
279 if ( panelid == 1 )
then
283 if ( lon(p) >= 2.0_rp * pi - 0.25_rp * pi )
then
284 lon_(p) = lon(p) - 2.0_rp * pi
293 if ( lon(p) < 0.0_rp )
then
294 lon_(p) = lon(p) + 2.0_rp * pi
303 alpha(p) = lon_(p) - 0.5_rp * pi * ( dble(panelid) - 1.0_rp )
304 beta(p) = atan( tan(lat(p)) / cos(alpha(p)) )
312 tan_lat = tan(lat(p))
313 alpha(p) = + atan( sin(lon(p)) / tan_lat )
314 beta(p) = - atan( cos(lon(p)) / tan_lat )
322 tan_lat = tan(lat(p))
323 alpha(p) = - atan( sin(lon(p)) / tan_lat )
324 beta(p) = - atan( cos(lon(p)) / tan_lat )
328 log_error(
"CubedSphereCoordCnv_LonLat2CSPos",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
340 panelID, alpha, beta, gam, Np, & ! (in)
347 integer,
intent(in) :: panelid
348 integer,
intent(in) :: np
349 real(rp),
intent(in) :: alpha(np)
350 real(rp),
intent(in) :: beta (np)
351 real(rp),
intent(in) :: gam(np)
352 real(dp),
intent(in) :: veclon(np)
353 real(dp),
intent(in) :: veclat(np)
354 real(dp),
intent(out) :: vecalpha(np)
355 real(dp),
intent(out) :: vecbeta (np)
356 real(rp),
intent(in),
optional :: lat(np)
357 integer,
intent(in),
optional :: gpu_async_id
360 real(rp) :: x ,y, del2
364 real(rp) :: cos_lat(np)
365 real(rp) :: veclon_ov_coslat
367 integer :: gpu_async_id_
371 if (
present(gpu_async_id))
then
372 gpu_async_id_ = gpu_async_id
374 gpu_async_id_ = acc_async_sync
380 if (
present(lat))
then
384 cos_lat(p) = cos(lat(p))
388 select case( panelid )
390 if (.not.
present(lat))
then
394 cos_lat(p) = cos( atan( tan( beta(p) ) * cos( alpha(p) ) ) )
403 del2 = 1.0_rp + x**2 + y**2
404 radius = rplanet * gam(p)
405 veclon_ov_coslat = veclon(p) / cos_lat(p)
407 vecalpha(p) = veclon_ov_coslat / radius
408 vecbeta(p) = ( x * y * veclon_ov_coslat + del2 / sqrt( 1.0_rp + x**2 ) * veclat(p) ) &
409 / ( radius * (1.0_rp + y**2) )
416 log_error(
"CubedSphereCoordCnv_LonLat2CSVec",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
420 select case( panelid )
427 del2 = 1.0_rp + x**2 + y**2
428 radius = s * rplanet * gam(p)
430 if (.not.
present(lat))
then
431 cos_lat(p) = cos( atan( s / sqrt(max(x**2 + y**2, eps)) ) )
433 veclon_ov_coslat = veclon(p) / cos_lat(p)
435 vecalpha(p) = (- y * veclon_ov_coslat - del2 * x / sqrt( max(del2 - 1.0_rp,eps)) * veclat(p)) &
436 / ( radius * ( 1.0_rp + x**2 ) )
437 vecbeta(p) = ( x * veclon_ov_coslat - del2 * y / sqrt( max(del2 - 1.0_rp,eps)) * veclat(p)) &
438 / ( radius * ( 1.0_rp + y**2 ) )
451 panelID, alpha, beta, gam, Np, & ! (in)
455 integer,
intent(in) :: panelid
456 integer,
intent(in) :: np
457 real(rp),
intent(in) :: alpha(np)
458 real(rp),
intent(in) :: beta (np)
459 real(rp),
intent(in) :: gam(np)
460 real(rp),
intent(out) :: x(np)
461 real(rp),
intent(out) :: y(np)
462 real(rp),
intent(out) :: z(np)
465 real(rp) :: x1, x2, fac
476 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
487 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
498 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
509 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
520 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
531 fac = rplanet * gam(p) / sqrt( 1.0_rp + x1**2 + x2**2 )
537 log_error(
"CubedSphereCoordCnv_CS2CartPos",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
548 panelID, alpha, beta, gam, Np, & ! (in)
549 vec_x, vec_y, vec_z, &
554 integer,
intent(in) :: panelid
555 integer,
intent(in) :: np
556 real(rp),
intent(in) :: alpha(np)
557 real(rp),
intent(in) :: beta (np)
558 real(rp),
intent(in) :: gam(np)
559 real(dp),
intent(in) :: vec_x(np)
560 real(dp),
intent(in) :: vec_y(np)
561 real(dp),
intent(in) :: vec_z(np)
562 real(rp),
intent(out) :: vecalpha(np)
563 real(rp),
intent(out) :: vecbeta (np)
566 real(rp) :: x1, x2, fac
567 real(rp) :: r_sec2_alpha, r_sec2_beta
570 select case( panelid )
577 r_sec2_alpha = cos(alpha(p))**2
578 r_sec2_beta = cos(beta(p))**2
579 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
581 vecalpha(p) = fac * r_sec2_alpha * ( - x1 * vec_x(p) + vec_y(p) )
582 vecbeta(p) = fac * r_sec2_beta * ( - x2 * vec_x(p) + vec_z(p) )
590 r_sec2_alpha = cos(alpha(p))**2
591 r_sec2_beta = cos(beta(p))**2
592 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
594 vecalpha(p) = - fac * r_sec2_alpha * ( vec_x(p) + x1 * vec_y(p) )
595 vecbeta(p) = fac * r_sec2_beta * ( - x2 * vec_y(p) + vec_z(p) )
603 r_sec2_alpha = cos(alpha(p))**2
604 r_sec2_beta = cos(beta(p))**2
605 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
607 vecalpha(p) = fac * r_sec2_alpha * ( x1 * vec_x(p) - vec_y(p) )
608 vecbeta(p) = fac * r_sec2_beta * ( x2 * vec_x(p) + vec_z(p) )
616 r_sec2_alpha = cos(alpha(p))**2
617 r_sec2_beta = cos(beta(p))**2
618 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
620 vecalpha(p) = fac * r_sec2_alpha * ( vec_x(p) + x1 * vec_y(p) )
621 vecbeta(p) = fac * r_sec2_beta * ( x2 * vec_y(p) + vec_z(p) )
629 r_sec2_alpha = cos(alpha(p))**2
630 r_sec2_beta = cos(beta(p))**2
631 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
633 vecalpha(p) = fac * r_sec2_alpha * ( vec_y(p) - x1 * vec_z(p) )
634 vecbeta(p) = - fac * r_sec2_beta * ( vec_x(p) + x2 * vec_z(p) )
642 r_sec2_alpha = cos(alpha(p))**2
643 r_sec2_beta = cos(beta(p))**2
644 fac = sqrt( 1.0_rp + x1**2 + x2**2 ) / ( rplanet * gam(p) )
646 vecalpha(p) = fac * r_sec2_alpha * ( vec_y(p) + x1 * vec_z(p) )
647 vecbeta(p) = fac * r_sec2_beta * ( vec_x(p) + x2 * vec_z(p) )
650 log_error(
"CubedSphereCoordCnv_Cart2CSVec",
'(a,i2,a)')
"panelID ", panelid,
" is invalid. Check!"
658 subroutine cubedspherecoordcnv_cs2localorthvec_alpha_0( &
659 alpha, beta, radius, Np, & ! (in)
664 integer,
intent(in) :: Np
665 real(RP),
intent(in) :: alpha(Np)
666 real(RP),
intent(in) :: beta (Np)
667 real(RP),
intent(in) :: radius(Np)
668 real(RP),
intent(inout) :: VecOrth1(Np)
669 real(RP),
intent(inout) :: VecOrth2(Np)
672 real(RP) :: x1, x2, del
682 del = sqrt(1.0_rp + x1**2 + x2**2)
683 fac = radius(p) * sqrt(1.0_rp + x1**2) / del**2
686 vecorth1(p) = fac * del * tmp
687 vecorth2(p) = fac * ( - x1 * x2 * tmp + (1.0_rp + x2**2) * vecorth2(p) )
691 end subroutine cubedspherecoordcnv_cs2localorthvec_alpha_0
694 subroutine cubedspherecoordcnv_cs2localorthvec_alpha_1( &
695 alpha, beta, radius, Np, & ! (in)
701 integer,
intent(in) :: Np
702 real(RP),
intent(in) :: alpha(Np)
703 real(RP),
intent(in) :: beta (Np)
704 real(RP),
intent(in) :: radius(Np)
705 real(RP),
intent(in) :: VecAlpha(Np)
706 real(RP),
intent(in) :: VecBeta (Np)
707 real(RP),
intent(out) :: VecOrth1(Np)
708 real(RP),
intent(out) :: VecOrth2(Np)
716 vecorth1(p) = vecalpha(p)
717 vecorth2(p) = vecbeta(p)
721 call cubedspherecoordcnv_cs2localorthvec_alpha_0( &
722 alpha, beta, radius, np, &
726 end subroutine cubedspherecoordcnv_cs2localorthvec_alpha_1
729 subroutine cubedspherecoordcnv_localorth2csvec_alpha_0( &
730 alpha, beta, radius, Np, & ! (in)
735 integer,
intent(in) :: Np
736 real(RP),
intent(in) :: alpha(Np)
737 real(RP),
intent(in) :: beta (Np)
738 real(RP),
intent(in) :: radius(Np)
739 real(RP),
intent(inout) :: VecAlpha(Np)
740 real(RP),
intent(inout) :: VecBeta (Np)
743 real(RP) :: x1, x2, del
753 del = sqrt(1.0_rp + x1**2 + x2**2)
754 fac = del / ( radius(p) * ( 1.0_rp + x2**2 ) * sqrt( 1.0_rp + x1**2 ) )
757 vecalpha(p) = fac * ( 1.0_rp + x2**2 ) * tmp
758 vecbeta(p) = fac * ( x1 * x2 * tmp + del * vecbeta(p) )
762 end subroutine cubedspherecoordcnv_localorth2csvec_alpha_0
765 subroutine cubedspherecoordcnv_localorth2csvec_alpha_1( &
766 alpha, beta, radius, Np, & ! (in)
767 vecorth1, vecorth2, &
770 integer,
intent(in) :: Np
771 real(RP),
intent(in) :: alpha(Np)
772 real(RP),
intent(in) :: beta (Np)
773 real(RP),
intent(in) :: radius(Np)
774 real(RP),
intent(in) :: VecOrth1(Np)
775 real(RP),
intent(in) :: VecOrth2(Np)
776 real(RP),
intent(out) :: VecAlpha(Np)
777 real(RP),
intent(out) :: VecBeta (Np)
785 vecalpha(p) = vecorth1(p)
786 vecbeta(p) = vecorth2(p)
790 call cubedspherecoordcnv_localorth2csvec_alpha_0( &
791 alpha, beta, radius, np, &
795 end subroutine cubedspherecoordcnv_localorth2csvec_alpha_1
801 alpha, beta, Np, radius, & ! (in)
806 integer,
intent(in) :: np
807 real(rp),
intent(in) :: alpha(np)
808 real(rp),
intent(in) :: beta (np)
809 real(rp),
intent(in) :: radius
810 real(rp),
intent(out) :: g_ij(np,2,2)
811 real(rp),
intent(out) :: gij (np,2,2)
812 real(rp),
intent(out) :: gsqrt(np)
817 real(rp) :: g_ij_(2,2)
818 real(rp) :: gij_ (2,2)
821 real(rp) :: oneplusx2, oneplusy2
831 r2 = 1.0_rp + x**2 + y**2
832 oneplusx2 = 1.0_rp + x**2
833 oneplusy2 = 1.0_rp + y**2
835 fac = oneplusx2 * oneplusy2 * ( radius / r2 )**2
836 g_ij_(1,1) = fac * oneplusx2
837 g_ij_(1,2) = - fac * (x * y)
838 g_ij_(2,1) = - fac * (x * y)
839 g_ij_(2,2) = fac * oneplusy2
840 g_ij(p,:,:) = g_ij_(:,:)
842 gsqrt(p) = radius**2 * oneplusx2 * oneplusy2 / ( r2 * sqrt(r2) )
844 fac = 1.0_rp / gsqrt(p)**2
845 gij_(1,1) = fac * g_ij_(2,2)
846 gij_(1,2) = - fac * g_ij_(1,2)
847 gij_(2,1) = - fac * g_ij_(2,1)
848 gij_(2,2) = fac * g_ij_(1,1)
849 gij(p,:,:) = gij_(:,:)
Module common / Coordinate conversion with cubed-sphere projection.
subroutine, public cubedspherecoordcnv_cs2lonlatpos(panelid, alpha, beta, gam, np, lon, lat)
Calculate longitude and latitude coordinates from local coordinates using the central angles in an eq...
subroutine, public cubedspherecoordcnv_getmetric(alpha, beta, np, radius, g_ij, gij, gsqrt)
Calculate the metrics associated with an equiangular gnomonic cubed-sphere projection to those in lon...
subroutine, public cubedspherecoordcnv_lonlat2csvec(panelid, alpha, beta, gam, np, veclon, veclat, vecalpha, vecbeta, lat, gpu_async_id)
Convert the components of a vector in longitude and latitude coordinates to those in local coordinate...
subroutine, public cubedspherecoordcnv_lonlat2cspos(panelid, lon, lat, np, alpha, beta)
Calculate local coordinates using the central angles in an equiangular gnomonic cubed-sphere projecti...
subroutine, public cubedspherecoordcnv_cart2csvec(panelid, alpha, beta, gam, np, vec_x, vec_y, vec_z, vecalpha, vecbeta)
Convert the components of a vector in local coordinates with an equiangular gnomonic cubed-sphere pro...
subroutine, public cubedspherecoordcnv_cs2lonlatvec(panelid, alpha, beta, gam, np, vecalpha, vecbeta, veclon, veclat, lat, gpu_async_id)
Convert the components of a vector in local coordinates with an equiangular gnomonic cubed-sphere pro...
subroutine, public cubedspherecoordcnv_cs2cartpos(panelid, alpha, beta, gam, np, x, y, z)
Calculate the Cartesian coordinates from local coordinates using the central angles in an equiangular...
Module common / Coordinate conversion with a geographic coordinate.
subroutine, public geographiccoordcnv_orth_to_geo_pos(orth_p, np, geo_p)