FE-Project
Loading...
Searching...
No Matches
scale_geographic_coord_cnv.F90
Go to the documentation of this file.
1!> Module common / Coordinate conversion with a geographic coordinate
2!!
3!! @par Description
4!! A module to provide coordinate conversions with a geographic coordinate
5!!
6!! @author Yuta Kawai, Team SCALE
7!!
8#include "scaleFElib.h"
10 !-----------------------------------------------------------------------------
11 !
12 !++ used modules
13 !
14 use scale_const, only: &
15 pi => const_pi, &
16 eps => const_eps
17 use scale_precision
18 use scale_prc
19 use scale_io
20 use scale_prc
21
22 !-----------------------------------------------------------------------------
23 implicit none
24 private
25
26 !-----------------------------------------------------------------------------
27 !
28 !++ Public type & procedure
29 !
32
35
39
40contains
41!OCL SERIAL
42 subroutine geographiccoordcnv_orth_to_geo_pos( orth_p, Np, &
43 geo_p )
44
45 implicit none
46 integer, intent(in) :: np
47 real(rp), intent(in) :: orth_p(np,3)
48 real(rp), intent(out) :: geo_p(np,3)
49
50 integer :: p
51 !---------------------------------------------------------
52
53 !$omp parallel private(p)
54 !$acc parallel present(orth_p, geo_p)
55
56 !$omp do
57 !$acc loop
58 do p=1, np
59 geo_p(p,3) = sqrt( orth_p(p,1)**2 + orth_p(p,2)**2 + orth_p(p,3)**2 )
60 geo_p(p,2) = asin( orth_p(p,3) / geo_p(p,3) )
61 geo_p(p,1) = atan( orth_p(p,2) / orth_p(p,1) )
62 end do
63
64 !$omp do
65 !$acc loop
66 do p=1, np
67 if ( geo_p(p,1) <= 0.0_rp .and. orth_p(p,1) < 0.0_rp ) then
68 geo_p(p,1) = geo_p(p,1) + pi
69 else if ( geo_p(p,1) >= 0.0_rp .and. orth_p(p,1) < 0.0_rp ) then
70 geo_p(p,1) = geo_p(p,1) - pi
71 end if
72 if ( orth_p(p,1) == 0.0_rp .and. orth_p(p,2) == 0.0_rp ) then
73 geo_p(p,1) = 0.0_rp
74 else if ( orth_p(p,1) == 0.0_rp ) then
75 geo_p(p,1) = sign(1.0_rp, orth_p(p,2)) * 0.5_rp * pi
76 end if
77 end do
78
79 !$acc end parallel
80 !$omp end parallel
81
82
83 return
85
86!OCL SERIAL
87 subroutine geographiccoordcnv_geo_to_orth_pos( geo_p, Np, &
88 orth_p )
89
90 implicit none
91 integer, intent(in) :: np
92 real(rp), intent(in) :: geo_p(np,3)
93 real(rp), intent(out) :: orth_p(np,3)
94
95 integer :: p
96 !---------------------------------------------------------
97
98 !$omp parallel do private(p)
99 do p=1, np
100 orth_p(p,1) = geo_p(p,3) * cos(geo_p(p,2)) * cos(geo_p(p,1))
101 orth_p(p,2) = geo_p(p,3) * cos(geo_p(p,2)) * sin(geo_p(p,1))
102 orth_p(p,3) = geo_p(p,3) * sin(geo_p(p,2))
103 end do
104
105 return
107
108!OCL SERIAL
109 subroutine geographiccoordcnv_orth_to_geo_vec( orth_v, geo_p, Np, &
110 geo_v )
111 implicit none
112
113 integer, intent(in) :: np
114 real(rp), intent(in) :: orth_v(np,3)
115 real(rp), intent(in) :: geo_p(np,3)
116 real(rp), intent(out) :: geo_v(np,3)
117
118 integer :: p
119 real(rp) :: sin_geo_p1
120 real(rp) :: cos_geo_p1
121 real(rp) :: sin_geo_p2
122 real(rp) :: cos_geo_p2
123 !---------------------------------------------------------
124
125 !$omp parallel do private(p, cos_geo_p2)
126 do p=1, np
127 sin_geo_p1 = sin(geo_p(p,1))
128 cos_geo_p1 = cos(geo_p(p,1))
129 sin_geo_p2 = sin(geo_p(p,2))
130 cos_geo_p2 = cos(geo_p(p,2))
131
132 geo_v(p,3) = orth_v(p,1) * cos_geo_p2 * cos_geo_p1 &
133 + orth_v(p,2) * cos_geo_p2 * sin_geo_p1 &
134 + orth_v(p,3) * sin_geo_p2
135
136 geo_v(p,2) = - orth_v(p,1) * sin_geo_p2 * cos_geo_p1 &
137 - orth_v(p,2) * sin_geo_p2 * sin_geo_p1 &
138 + orth_v(p,3) * cos_geo_p2
139
140 geo_v(p,1) = - orth_v(p,1) * sin_geo_p1 &
141 + orth_v(p,2) * cos_geo_p1
142 end do
143
144 return
146
147!OCL SERIAL
148 subroutine geographiccoordcnv_geo_to_orth_vec( geo_v, geo_p, Np, &
149 orth_v )
150 implicit none
151
152 integer, intent(in) :: np
153 real(rp), intent(in) :: geo_v(np,3)
154 real(rp), intent(in) :: geo_p(np,3)
155 real(rp), intent(out) :: orth_v(np,3)
156
157 integer :: p
158 real(rp) :: sin_geo_p1
159 real(rp) :: cos_geo_p1
160 real(rp) :: sin_geo_p2
161 real(rp) :: cos_geo_p2
162 !---------------------------------------------------------
163
164 !$omp parallel do private(p, sin_geo_p1, cos_geo_p1, sin_geo_p2, cos_geo_p2)
165 do p=1, np
166 sin_geo_p1 = sin(geo_p(p,1))
167 cos_geo_p1 = cos(geo_p(p,1))
168 sin_geo_p2 = sin(geo_p(p,2))
169 cos_geo_p2 = cos(geo_p(p,2))
170
171 orth_v(p,1) = geo_v(p,3) * cos_geo_p1 * cos_geo_p2 &
172 - geo_v(p,2) * cos_geo_p1 * sin_geo_p2 &
173 - geo_v(p,1) * sin_geo_p1
174
175 orth_v(p,2) = geo_v(p,3) * sin_geo_p1 * cos_geo_p2 &
176 - geo_v(p,2) * sin_geo_p1 * sin_geo_p2 &
177 + geo_v(p,1) * cos_geo_p1
178
179 orth_v(p,3) = geo_v(p,3) * sin_geo_p2 + geo_v(p,2) * cos_geo_p2
180 end do
181
182 return
184
185!OCL SERIAL
186 subroutine geographiccoordcnv_rotatex( pos_vec, angle, &
187 rotated_pos_vec )
188
189 implicit none
190 real(rp), intent(in) :: pos_vec(3)
191 real(rp), intent(in) :: angle
192 real(rp), intent(out) :: rotated_pos_vec(3)
193
194 real(rp) :: sin_angle, cos_angle
195 !---------------------------------------------------------
196
197 sin_angle = sin(angle)
198 cos_angle = cos(angle)
199
200 rotated_pos_vec(1) = pos_vec(1)
201 rotated_pos_vec(2) = cos_angle * pos_vec(2) - sin_angle * pos_vec(3)
202 rotated_pos_vec(3) = sin_angle * pos_vec(2) + cos_angle * pos_vec(3)
203
204 return
205 end subroutine geographiccoordcnv_rotatex
206
207!OCL SERIAL
208 subroutine geographiccoordcnv_rotatey( pos_vec, angle, &
209 rotated_pos_vec )
210
211 implicit none
212 real(rp), intent(in) :: pos_vec(3)
213 real(rp), intent(in) :: angle
214 real(rp), intent(out) :: rotated_pos_vec(3)
215
216 real(rp) :: sin_angle, cos_angle
217 !---------------------------------------------------------
218
219 sin_angle = sin(angle)
220 cos_angle = cos(angle)
221
222 rotated_pos_vec(1) = cos_angle * pos_vec(1) + sin_angle * pos_vec(3)
223 rotated_pos_vec(2) = pos_vec(2)
224 rotated_pos_vec(3) = - sin_angle * pos_vec(1) + cos_angle * pos_vec(3)
225
226 return
227 end subroutine geographiccoordcnv_rotatey
228
229!OCL SERIAL
230 subroutine geographiccoordcnv_rotatez( pos_vec, angle, &
231 rotated_pos_vec )
232
233 implicit none
234 real(rp), intent(in) :: pos_vec(3)
235 real(rp), intent(in) :: angle
236 real(rp), intent(out) :: rotated_pos_vec(3)
237
238 real(rp) :: sin_angle, cos_angle
239 !---------------------------------------------------------
240
241 sin_angle = sin(angle)
242 cos_angle = cos(angle)
243
244 rotated_pos_vec(1) = cos_angle * pos_vec(1) - sin_angle * pos_vec(2)
245 rotated_pos_vec(2) = sin_angle * pos_vec(1) + cos_angle * pos_vec(2)
246 rotated_pos_vec(3) = pos_vec(3)
247
248 return
249 end subroutine geographiccoordcnv_rotatez
250
Module common / Coordinate conversion with a geographic coordinate.
subroutine, public geographiccoordcnv_rotatez(pos_vec, angle, rotated_pos_vec)
subroutine, public geographiccoordcnv_rotatex(pos_vec, angle, rotated_pos_vec)
subroutine, public geographiccoordcnv_orth_to_geo_pos(orth_p, np, geo_p)
subroutine, public geographiccoordcnv_rotatey(pos_vec, angle, rotated_pos_vec)
subroutine, public geographiccoordcnv_geo_to_orth_pos(geo_p, np, orth_p)
subroutine, public geographiccoordcnv_geo_to_orth_vec(geo_v, geo_p, np, orth_v)
subroutine, public geographiccoordcnv_orth_to_geo_vec(orth_v, geo_p, np, geo_v)