Line data Source code
1 :
2 : module efield
3 : !------------------------------------------------------------------------------
4 : ! description: calculates the electric potential for a given year,
5 : ! day of year, UT, F10.7, K_p
6 : ! - low/midlatitudes electric potential is from an empirical model from
7 : ! L.Scherliess ludger@gaim.cass.usu.edu
8 : ! - high latitude electric potential is Heelis
9 : ! - the transition zone is smoothed
10 : ! - output is the horizontal global electric field in magnetic coordinates direction
11 : ! at every magnetic local time grid point expressed in degrees (0 deg-0MLT; 360deg 24 MLT)
12 : !
13 : ! input
14 : ! integer :: iday, ! day number of year
15 : ! iyear ! year
16 : ! real(r8):: ut, ! universal time
17 : ! F10.7, ! solar flux (see ionosphere module)
18 : ! output
19 : ! real(r8) :: &
20 : ! ed1(0:nmlon,0:nmlat), & ! zonal electric field Ed1 [V/m]
21 : ! ed2(0:nmlon,0:nmlat) ! meridional electric field Ed2/sin I_m [V/m]
22 : !
23 : ! notes:
24 : !
25 : ! - !to be done (commented out): input S_a F10.7/ Kp from WACCM and calculate B_z
26 : ! from these inputs
27 : ! - assume regular geomagnetic grid
28 : ! - uses average year 365.24 days/year 30.6001 day/mo s. Weimer
29 : ! - get_tilt works only for iyear >= 1900
30 : ! - fixed parameters: B_z, B_y units nT CHANGE THIS
31 : ! F10.7
32 : ! - we assume that the reference height is 300km for the emperical potential model
33 : ! - as a first approximation the electric field is constant in height
34 : ! WATCH what is the upper boundary condition in WACCM
35 : ! - for all the calculation done here we set the reference height to the same
36 : ! value as in tiegcm (hr=130km)
37 : ! - 12/15/03 input value iseasav : replaced by day -> month and day of month
38 : ! - 12/15/03 S_aM calculated according to Scherliess draft paper and added
39 : ! S_aM(corrected) = 90*(S_aM+1) to get variation in fig 1 Scherliess draft
40 : !
41 : ! Author: A. Maute Dec 2003 am 12/30/03
42 : !------------------------------------------------------------------------------
43 :
44 : use shr_kind_mod, only: r8 => shr_kind_r8
45 : use physconst, only: pi
46 : use cam_abortutils, only: endrun
47 : use cam_logfile, only: iulog
48 : use heelis_mod, only: heelis_flwv32, heelis_update
49 : use solar_parms_data, only: f107d=>solar_parms_f107
50 : use spmd_utils, only: masterproc
51 : use infnan, only: nan, assignment(=)
52 :
53 : implicit none
54 :
55 : public :: efield_init, & ! interface routine
56 : get_efield ! interface routine
57 : public :: ed1, & ! zonal electric field Ed1 [V/m]
58 : ed2, & ! meridional electric field Ed2 [V/m]
59 : potent, & ! electric potential [V]
60 : nmlon, nmlat, & ! dimension of mag. grid
61 : dlatm, dlonm, & ! grid spacing of mag. grid
62 : ylonm, ylatm ! magnetic longitudes/latitudes (deg)
63 :
64 : private
65 :
66 : integer :: &
67 : iday, & ! day number of year
68 : iyear, & ! year
69 : iday_m, & ! day of month
70 : imo ! month
71 : real(r8) :: ut ! universal time
72 :
73 : !------------------------------------------------------------------------------
74 : ! mag. grid dimensions (assumed resolution of 2deg)
75 : !------------------------------------------------------------------------------
76 : integer, parameter :: &
77 : nmlon = 180, & ! mlon
78 : nmlat = 90, & ! mlat
79 : nmlath= nmlat/2 ! mlat/2
80 :
81 : integer, parameter :: &
82 : nmlon1f = nmlon/4, & ! 1 fourth mlon
83 : nmlon2f = nmlon/2, & ! 2 fourths mlon
84 : nmlon3f = 3*nmlon/4 ! 3 fourths mlon
85 :
86 : real(r8) :: &
87 : ylatm(0:nmlat), & ! magnetic latitudes (deg)
88 : ylonm(0:nmlon), & ! magnetic longitudes (deg)
89 : dlonm, & ! delon lon grid spacing
90 : dlatm ! delat lat grid spacing
91 :
92 : !------------------------------------------------------------------------------
93 : ! array on magnetic grid:
94 : !------------------------------------------------------------------------------
95 : real(r8), protected :: &
96 : potent(0:nmlon,0:nmlat), & ! electric potential [V]
97 : ed1(0:nmlon,0:nmlat), & ! zonal electric field Ed1 [V/m]
98 : ed2(0:nmlon,0:nmlat) ! meridional electric field Ed2/sin I_m [V/m]
99 :
100 : real(r8) :: &
101 : day ! iday+ut
102 :
103 : logical, parameter :: iutav=.false. ! .true. means UT-averaging
104 : ! .false. means no UT-averaging
105 : !------------------------------------------------------------------------------
106 : ! boundary for high-lat potential
107 : !------------------------------------------------------------------------------
108 : real(r8), parameter :: bnd_hgh = 44._r8 ! colat. [deg]
109 : integer :: nmlat_hgh
110 :
111 : !------------------------------------------------------------------------------
112 : ! flag for choosing factors for empirical low latitude model
113 : !------------------------------------------------------------------------------
114 : integer, parameter :: iseasav = 0 ! flag for season
115 :
116 : !------------------------------------------------------------------------------
117 : ! constants:
118 : !------------------------------------------------------------------------------
119 : real(r8), parameter :: &
120 : r_e = 6.371e6_r8, & ! radius_earth [m] (same as for apex.F90)
121 : h_r = 130.0e3_r8, & ! reference height [m] (same as for apex.F90)
122 : dy2yr= 365.24_r8 ! day per avg. year
123 :
124 : real(r8) :: &
125 : rtd , & ! radians -> deg
126 : dtr, & ! deg -> radians
127 : sqr2, &
128 : dy2rd, & ! 2*pi/365.24 average year
129 : sinIm_mag(0:nmlat) ! sinIm
130 :
131 : integer :: jmin, jmax ! latitude index for interpolation of
132 : ! northward e-field ed2 at mag. equator
133 :
134 : !------------------------------------------------------------------------------
135 : ! for spherical harmonics
136 : !------------------------------------------------------------------------------
137 : integer, parameter :: &
138 : nm = 19, &
139 : mm = 18, &
140 : nmp = nm + 1, &
141 : mmp = mm + 1
142 :
143 : real(r8) :: r(0:nm,0:mm) ! R_n^m
144 : real(r8) :: pmopmmo(0:mm) ! sqrt(1+1/2m)
145 :
146 : !------------------------------------------------------------------------------
147 : ! index for factors f_m(mlt),f_l(UT),f_-k(d)
148 : !------------------------------------------------------------------------------
149 : integer, parameter :: ni = 1091 ! for n=12 m=-18:18
150 : integer :: imax ! max number of index
151 : integer,dimension(0:ni) :: &
152 : kf, &
153 : lf, &
154 : mf, &
155 : nf, &
156 : jf
157 : real(r8) :: ft(1:3,0:2) ! used for f_-k(season,k)
158 :
159 : real(r8) :: a_klnm(0:ni) ! A_klm
160 : real(r8) :: a_lf(0:ni) ! A_klmn^lf for minimum &
161 : real(r8) :: a_hf(0:ni) ! A_klmn^hf for maximum
162 :
163 : !------------------------------------------------------------------------------
164 : ! high_latitude boundary
165 : !------------------------------------------------------------------------------
166 : real(r8), parameter :: &
167 : lat_sft = 54._r8 ! shift of highlat_bnd to 54 deg
168 : integer :: ilat_sft ! index of shift for high latitude boundary
169 : integer, parameter :: nmax_sin = 2 ! max. wave number to be represented
170 : logical, parameter :: debug =.false.
171 :
172 : real(r8) :: epotential_max = huge(1._r8) ! max cross cap potential kV
173 :
174 : integer :: ip1f(0:nmlon)=-huge(1)
175 : integer :: ip2f(0:nmlon)=-huge(1)
176 : integer :: ip3f(0:nmlon)=-huge(1)
177 :
178 : contains
179 :
180 1536 : subroutine efield_init(efield_lflux_file, efield_hflux_file, efield_potential_max)
181 : !-----------------------------------------------------------------------
182 : ! Purpose: read in and set up coefficients needed for electric field
183 : ! calculation (independent of time & geog. location)
184 : !
185 : ! Method:
186 : !
187 : ! Author: A. Maute Dec 2003 am 12/17/03
188 : !-----------------------------------------------------------------------
189 : character(len=*), intent(in) :: efield_lflux_file
190 : character(len=*), intent(in) :: efield_hflux_file
191 : real(r8), intent(in) :: efield_potential_max ! cross cap electric potential maximum
192 :
193 : integer :: i
194 : real(r8) :: nanval
195 1536 : nanval=nan
196 :
197 25440768 : potent = nanval
198 25440768 : ed1 = nanval
199 25440768 : ed2 = nanval
200 :
201 1536 : call constants ! calculate constants
202 : !-----------------------------------------------------------------------
203 : ! low/midlatitude potential from Scherliess model
204 : !-----------------------------------------------------------------------
205 1536 : call read_acoef (efield_lflux_file, efield_hflux_file) ! read in A_klnm for given S_aM
206 1536 : call index_quiet ! set up index for f_m(mlt),f_l(UT),f_-k(d)
207 1536 : call prep_fk ! set up the constant factors for f_k
208 1536 : call prep_pnm ! set up the constant factors for P_n^m & dP/d phi
209 :
210 1536 : epotential_max = efield_potential_max
211 :
212 279552 : do i = 0,nmlon
213 278016 : ip1f(i) = i + nmlon1f
214 278016 : if( ip1f(i) > nmlon ) then
215 69120 : ip1f(i) = ip1f(i) - nmlon
216 : end if
217 278016 : ip2f(i) = i + nmlon2f
218 278016 : if( ip2f(i) > nmlon ) then
219 138240 : ip2f(i) = ip2f(i) - nmlon
220 : end if
221 278016 : ip3f(i) = i + nmlon3f
222 279552 : if( ip3f(i) > nmlon ) then
223 207360 : ip3f(i) = ip3f(i) - nmlon
224 : end if
225 : end do
226 :
227 1536 : end subroutine efield_init
228 :
229 16128 : subroutine get_efield
230 : !-----------------------------------------------------------------------
231 : ! Purpose: calculates the global electric potential field on the
232 : ! geomagnetic grid (MLT in deg) and derives the electric field
233 : !
234 : ! Method:
235 : !
236 : ! Author: A. Maute Dec 2003 am 12/17/03
237 : !-----------------------------------------------------------------------
238 :
239 : use time_manager, only : get_curr_calday, get_curr_date
240 : use mo_apex, only : geomag_year
241 :
242 : integer :: tod ! time of day [s]
243 : character(len=80) :: errmsg
244 :
245 : !-----------------------------------------------------------------------
246 : ! get current calendar day of year & date components
247 : ! valid at end of current timestep
248 : !-----------------------------------------------------------------------
249 16128 : iday = get_curr_calday() ! day of year
250 16128 : call get_curr_date (iyear,imo,iday_m,tod) ! year, time of day [sec]
251 16128 : iyear = int(geomag_year)
252 :
253 16128 : if( iyear < 1900 ) then
254 0 : write(errmsg,"(/,'>>> get_efield: year < 1900 not possible: year=',i5)") iyear
255 0 : call endrun(errmsg)
256 : end if
257 :
258 16128 : ut = tod/3600._r8 ! UT of day [hour]
259 :
260 : !-----------------------------------------------------------------------
261 : ! ajust S_a
262 : !-----------------------------------------------------------------------
263 16128 : call adj_S_a
264 : !-----------------------------------------------------------------------
265 : ! calculate global electric potential
266 : !-----------------------------------------------------------------------
267 16128 : call GlobalElPotential
268 :
269 : !-----------------------------------------------------------------------
270 : ! calculate derivative of global electric potential
271 : !-----------------------------------------------------------------------
272 16128 : call DerivPotential
273 :
274 16128 : end subroutine get_efield
275 :
276 16128 : subroutine GlobalElPotential
277 : !-----------------------------------------------------------------------
278 : ! Purpose: calculates the global electric potential field on the
279 : ! geomagnetic grid (MLT in deg)
280 : !
281 : ! Method: rewritten code from Luedger Scherliess (11/20/99 LS)
282 : ! routine to calculate the global electric potential in magnetic
283 : ! Apex coordinates (Latitude and MLT).
284 : ! High Latitude Model is Heelis
285 : ! Midlatitude model is Scherliess 1999.
286 : ! Interpolation in a transition region at about 60 degree
287 : ! magnetic apex lat
288 : !
289 : ! Author: A. Maute Dec 2003 am 12/17/03
290 : !-----------------------------------------------------------------------
291 :
292 : !-----------------------------------------------------------------------
293 : ! local variables
294 : !-----------------------------------------------------------------------
295 : integer :: ilon, ilat, idlat
296 : integer :: ihlat_bnd(0:nmlon) ! high latitude boundary
297 : integer :: itrans_width(0:nmlon) ! width of transition zone
298 : real(r8) :: mlat, pot
299 : real(r8) :: pot_midlat(0:nmlon,0:nmlat) ! potential from L. Scherliess model
300 : real(r8) :: pot_highlat(0:nmlon,0:nmlat) ! potential from Heelis
301 : real(r8) :: pot_highlats(0:nmlon,0:nmlat) ! smoothed potential from Heelis
302 : real(r8) :: poten(nmlon+1)
303 : integer,dimension(nmlon) :: iflag
304 : real(r8),dimension(nmlon) :: dlat,dlon,ratio
305 :
306 : !-----------------------------------------------------------------------
307 : ! convert to date and day
308 : !-----------------------------------------------------------------------
309 16128 : day = iday + ut/24._r8
310 :
311 : !-----------------------------------------------------------------------
312 : ! low/mid-latitude electric potential - empirical model Scherliess 1999
313 : !-----------------------------------------------------------------------
314 : !$omp parallel do private(ilat, ilon, mlat, pot)
315 758016 : do ilat = 0,nmlath ! Calculate only for one magn. hemisphere
316 741888 : mlat = ylatm(ilat) ! mag. latitude
317 135039744 : do ilon = 0,nmlon ! lon. loop
318 134281728 : call efield_mid( mlat, ylonm(ilon), pot )
319 134281728 : pot_midlat(ilon,ilat+nmlath) = pot ! SH/NH symmetry
320 269305344 : pot_midlat(ilon,nmlath-ilat) = pot
321 : end do
322 : end do
323 :
324 : !-----------------------------------------------------------------------
325 : ! high-latitude potential from Heelis model
326 : !-----------------------------------------------------------------------
327 16128 : call heelis_update(max_ctpoten=epotential_max)
328 :
329 2919168 : ratio(:) = 1._r8
330 :
331 1483776 : do ilat = 0,nmlat
332 265644288 : iflag(:) = 1
333 265644288 : dlat(:) = (90._r8-ylatm(ilat))*dtr
334 265644288 : dlon(:) = (ylonm(1:nmlon)-180._r8)*dtr
335 :
336 1467648 : if (ylatm(ilat) > 44._r8) then
337 1096704 : call heelis_flwv32(dlat,dlon,ratio,pi,iflag,nmlon,poten(:))
338 : else
339 370944 : poten(:) = 0._r8
340 : endif
341 :
342 265644288 : pot_highlat(1:nmlon,ilat) = poten(1:nmlon) ! volts
343 265644288 : pot_highlat(1:nmlon,nmlat-ilat) = poten(1:nmlon)
344 265644288 : pot_highlats(1:nmlon,ilat) = poten(1:nmlon)
345 265660416 : pot_highlats(1:nmlon,nmlat-ilat) = poten(1:nmlon)
346 :
347 : end do
348 1483776 : pot_highlat(0,:) = pot_highlat(nmlon,:)
349 1483776 : pot_highlats(0,:) = pot_highlats(nmlon,:)
350 :
351 : !-----------------------------------------------------------------------
352 : ! weighted smoothing of high latitude potential
353 : !-----------------------------------------------------------------------
354 16128 : idlat = 2 ! smooth over -2:2 = 5 grid points
355 16128 : call pot_latsmo( pot_highlats, idlat )
356 : !-----------------------------------------------------------------------
357 : ! calculate the height latitude bounday ihl_bnd
358 : ! 1. calculate E field from high-lat potential model
359 : ! boundary is set where the total electric field exceeds
360 : ! 0.015 V/m (corresp. approx. to 300 m/s)
361 : ! 2. moved halfways to 54 deg
362 : ! output : index 0-pole nmlath-equator
363 : !-----------------------------------------------------------------------
364 16128 : potent = pot_highlat ! need efield components (ed1,ed2) to determine ihlat_bnd
365 16128 : call DerivPotential()
366 16128 : call highlat_getbnd( ihlat_bnd )
367 : !-----------------------------------------------------------------------
368 : ! 3. adjust high latitude boundary sinusoidally
369 : ! calculate width of transition zone
370 : !-----------------------------------------------------------------------
371 16128 : call bnd_sinus( ihlat_bnd, itrans_width )
372 : !-----------------------------------------------------------------------
373 : ! 4. ajust high latitude potential to low latitude potential
374 : !-----------------------------------------------------------------------
375 16128 : call highlat_adjust( pot_highlats, pot_highlat, pot_midlat, ihlat_bnd )
376 : !-----------------------------------------------------------------------
377 : ! interpolation of high and low/midlatitude potential in the
378 : ! transition zone and put it into global potent array
379 : !-----------------------------------------------------------------------
380 16128 : call interp_poten( pot_highlats, pot_highlat, pot_midlat, ihlat_bnd, itrans_width)
381 : !-----------------------------------------------------------------------
382 : ! potential weighted smoothing in latitude
383 : !-----------------------------------------------------------------------
384 16128 : idlat = 2 ! smooth over -2:2 = 5 grid points
385 16128 : call pot_latsmo2( potent, idlat )
386 : !-----------------------------------------------------------------------
387 : ! potential smoothing in longitude
388 : !-----------------------------------------------------------------------
389 16128 : idlat = nmlon/48 ! smooth over -idlat:idlat grid points
390 16128 : call pot_lonsmo( potent, idlat )
391 :
392 16128 : end subroutine GlobalElPotential
393 :
394 271482624 : subroutine ff( ph, mt, f )
395 : !-----------------------------------------------------------------------
396 : ! Purpose: calculate F for normalized associated Legendre polynomial P_n^m
397 : ! Ref.: Richmond J.Atm.Ter.Phys. 1974
398 : !
399 : ! Method: f_m(phi) = sqrt(2) sin(m phi) m > 0
400 : ! = 1 m = 0
401 : ! = sqrt(2) cos(m phi) m < 0
402 : !
403 : ! Author: A. Maute Nov 2003 am 11/18/03
404 : !-----------------------------------------------------------------------
405 :
406 : implicit none
407 :
408 : !-----------------------------------------------------------------------
409 : ! dummy arguments
410 : !-----------------------------------------------------------------------
411 : integer,intent(in) :: mt
412 : real(r8),intent(in) :: ph ! geo. longitude of 0SLT (ut*15)
413 : real(r8),intent(out) :: f(-mt:mt)
414 :
415 : !-----------------------------------------------------------------------
416 : ! local variables
417 : !-----------------------------------------------------------------------
418 : integer :: m, mmo
419 : real(r8) :: sp, cp
420 :
421 271482624 : sp = sin( ph/rtd )
422 271482624 : cp = cos( ph/rtd )
423 271482624 : f(0) = 1.e0_r8
424 :
425 271482624 : f(-1) = sqr2*cp
426 271482624 : f(1) = sqr2*sp
427 2691472896 : do m = 2,mt
428 2419990272 : mmo = m - 1
429 2419990272 : f(m) = f(-mmo)*sp + cp*f(mmo)
430 2691472896 : f(-m) = f(-mmo)*cp - sp*f(mmo)
431 : end do
432 :
433 271482624 : end subroutine ff
434 :
435 134281728 : subroutine pnm( ct, p )
436 : !----------------------------------------------------------------------------
437 : ! Purpose: normalized associated Legendre polynomial P_n^m
438 : ! Ref.: Richmond J.Atm.Ter.Phys. 1974
439 : ! Method:
440 : ! P_m^m = sqrt(1+1/2m)*si*P_m-1^m-1 m>0
441 : ! P_n^m = [cos*P_n-1^m - R_n-1^m*P_n-2^m ]/R_n^m n>m>=0
442 : ! dP/d phi = n*cos*P_n^m/sin-(2*n+1)*R_n^m*P_n-1^m/sin n>=m>=0
443 : ! R_n^m = sqrt[ (n^2-m^2)/(4n^2-1) ]
444 : !
445 : ! Author: A. Maute Nov 2003 am 11/18/03
446 : !----------------------------------------------------------------------------
447 :
448 : implicit none
449 :
450 : !-----------------------------------------------------------------------
451 : ! dummy arguments
452 : !-----------------------------------------------------------------------
453 : real(r8), intent(inout) :: ct ! cos(colat)
454 : real(r8), intent(inout) :: p(0:nm,0:mm)
455 :
456 : !-----------------------------------------------------------------------
457 : ! local variables
458 : !-----------------------------------------------------------------------
459 : integer :: mp, m, n
460 : real(r8) :: pm2, st
461 :
462 : ! ct = min( ct,.99_r8 ) ! cos(colat)
463 134281728 : st = sqrt( 1._r8 - ct*ct ) ! sin(colat)
464 :
465 134281728 : p(0,0) = 1._r8
466 2685634560 : do mp = 1,mmp ! m+1=1,mm+1
467 2551352832 : m = mp - 1
468 2551352832 : if( m >= 1 ) then
469 2417071104 : p(m,m) = pmopmmo(m)*p(m-1,m-1)*st
470 : end if
471 : pm2 = 0._r8
472 28199162880 : do n = mp,nm ! n=m+1,N
473 25513528320 : p(n,m) = (ct*p(n-1,m) - r(n-1,m)*pm2)/r(n,m)
474 28064881152 : pm2 = p(n-1,m)
475 : end do
476 : end do
477 :
478 134281728 : end subroutine pnm
479 :
480 1536 : subroutine prep_pnm
481 : !----------------------------------------------------------------------------
482 : ! Purpose: constant factors for normalized associated Legendre polynomial P_n^m
483 : ! Ref.: Richmond J.Atm.Ter.Phys. 1974
484 : !
485 : ! Method:
486 : ! PmoPmmo(m) = sqrt(1+1/2m)
487 : ! R_n^m = sqrt[ (n^2-m^2)/(4n^2-1) ]
488 : !
489 : ! Author: A. Maute Nov 2003 am 11/18/03
490 : !----------------------------------------------------------------------------
491 :
492 : implicit none
493 :
494 : !-----------------------------------------------------------------------
495 : ! local variables
496 : !-----------------------------------------------------------------------
497 : integer :: mp, m, n
498 : real(r8) :: xms, xns, den
499 :
500 30720 : do mp = 1, mmp ! m+1 = 1,mm+1
501 29184 : m = mp - 1
502 29184 : xms = m*m
503 29184 : if( mp /= 1 ) then
504 27648 : pmopmmo(m) = sqrt( 1._r8 + .5_r8/M )
505 : end if
506 351744 : do n = m,nm ! n = m,N
507 321024 : xns = n*n
508 321024 : den = max(4._r8*xns - 1._r8,1._r8)
509 350208 : r(n,m) = sqrt( (xns - xms)/den )
510 : end do
511 : end do
512 :
513 1536 : end subroutine prep_pnm
514 :
515 1536 : subroutine index_quiet
516 : !----------------------------------------------------------------------------
517 : ! Purpose: set up index for factors f_m(mlt),f_l(UT),f_-k(d) to
518 : ! describe the electric potential Phi for the empirical model
519 : !
520 : ! Method:
521 : ! Phi = sum_k sum_l sum_m sum_n [ A_klmn * P_n^m *f_m(mlt)*f_l(UT)*f_-k(d)]
522 : ! - since the electric potential is symmetric about the equator
523 : ! n+m odd terms are set zero resp. not used
524 : ! - in the summation for calculation Phi the index have the following
525 : ! range n=1,12 and m=-n,n, k=0,2 l=-2,2
526 : !
527 : ! Author: A. Maute Nov 2003 am 11/18/03
528 : !----------------------------------------------------------------------------
529 :
530 : implicit none
531 :
532 : !----------------------------------------------------------------------------
533 : ! ... local variables
534 : !----------------------------------------------------------------------------
535 : integer :: i, j, k, l, n, m
536 :
537 1536 : i = 0 ! initialize
538 1536 : j = 1
539 6144 : do k = 2,0,-1
540 29184 : do l = -2,2
541 23040 : if( k == 2 .and. abs(l) == 2 ) then
542 : cycle
543 : end if
544 264192 : do n = 1,12
545 9128448 : do m = -18,18
546 9105408 : if( abs(m) <= n ) then ! |m| < n
547 3354624 : if( (((n-m)/2)*2) == (n-m) ) then ! only n+m even
548 1797120 : if( n-abs(m) <= 9 ) then ! n-|m| <= 9 why?
549 1677312 : kf(i) = 2-k
550 1677312 : lf(i) = l
551 1677312 : nf(i) = n
552 1677312 : mf(i) = m
553 1677312 : jf(i) = j
554 1677312 : i = i + 1 ! counter
555 : end if
556 : end if
557 : end if
558 : end do ! m
559 : end do ! n
560 : end do ! l
561 : end do ! k
562 :
563 1536 : imax = i - 1
564 1536 : if(imax /= ni ) then ! check if imax == ni
565 0 : write(iulog,'(a19,i5,a18,i5)') 'index_quiet: imax= ',imax,' not equal to ni =',ni
566 0 : call endrun('index_quiet ERROR')
567 : end if
568 : if(debug.and.masterproc) write(iulog,*) 'imax=',imax
569 :
570 1536 : end subroutine index_quiet
571 :
572 1536 : subroutine read_acoef (efield_lflux_file, efield_hflux_file)
573 : !----------------------------------------------------------------------------
574 : ! Purpose:
575 : ! 1. read in coefficients A_klmn^lf for solar cycle minimum and
576 : ! A_klmn^hf for maximum
577 : ! 2. adjust S_a (f107d) such that if S_a<80 or S_a > 220 it has reasonable numbers
578 : ! S_aM = [atan{(S_a-65)^2/90^2}-a90]/[a180-a90]
579 : ! a90 = atan [(90-65)/90]^2
580 : ! a180 = atan [(180-65)/90]^2
581 : ! 3. inter/extrapolation of the coefficient to the actual flux which is
582 : ! given by the user
583 : ! A_klmn = S_aM [A_klmn^hf-A_klmn^lf]/90. + 2*A_klmn^lf-A_klmn^hf
584 : !
585 : ! Method:
586 : !
587 : ! Author: A. Maute Nov 2003 am 11/19/03
588 : !----------------------------------------------------------------------------
589 :
590 : use ioFileMod, only : getfil
591 : use units, only : getunit, freeunit
592 : use spmd_utils, only : mpicom, masterprocid, mpicom, mpi_real8
593 :
594 : character(len=*), intent(in) :: efield_lflux_file
595 : character(len=*), intent(in) :: efield_hflux_file
596 :
597 : integer :: ios,unit, ierr
598 : character (len=256):: locfn
599 : character(len=80) :: errmsg
600 :
601 1536 : if (masterproc) then
602 : !----------------------------------------------------------------------------
603 : ! get coefficients file for solar minimum:
604 : !----------------------------------------------------------------------------
605 2 : unit = getunit()
606 2 : call getfil( efield_lflux_file, locfn, 0 )
607 :
608 : !----------------------------------------------------------------------------
609 : ! open datafile with coefficients A_klnm
610 : !----------------------------------------------------------------------------
611 : if (debug) write(iulog,*) 'read_acoef: open file ',trim(locfn),' unit ',unit
612 : open(unit=unit,file=trim(locfn), &
613 2 : status = 'old',iostat = ios)
614 2 : if(ios.gt.0) then
615 0 : write(errmsg,*) 'read_acoef: error in opening coeff_lf file',' unit ',unit
616 0 : call endrun(errmsg)
617 : end if
618 :
619 : !----------------------------------------------------------------------------
620 : ! read datafile with coefficients A_klnm
621 : !----------------------------------------------------------------------------
622 : if (debug) write(iulog,*) 'read_acoef: read file ',trim(locfn),' unit ',unit
623 2 : read(unit,*,iostat = ios) a_lf
624 2 : if(ios.gt.0) then
625 0 : write(errmsg,*) 'read_acoef: error in reading coeff_lf file',' unit ',unit
626 0 : call endrun(errmsg)
627 : end if
628 :
629 : !----------------------------------------------------------------------------
630 : ! close & free unit
631 : !----------------------------------------------------------------------------
632 2 : close(unit)
633 2 : call freeunit(unit)
634 : if (debug) write(iulog,*) 'read_acoef: free unit ',unit
635 :
636 : !----------------------------------------------------------------------------
637 : ! get coefficients file for solar maximum:
638 : !----------------------------------------------------------------------------
639 2 : unit = getunit()
640 2 : call getfil( efield_hflux_file, locfn, 0 )
641 :
642 : !----------------------------------------------------------------------------
643 : ! open datafile with coefficients A_klnm
644 : !----------------------------------------------------------------------------
645 : if (debug) write(iulog,*) 'read_acoef: open file ',trim(locfn),' unit ',unit
646 : open(unit=unit,file=trim(locfn), &
647 2 : status = 'old',iostat = ios)
648 2 : if(ios.gt.0) then
649 0 : write(errmsg,*) 'read_acoef: error in opening coeff_hf file',' unit ',unit
650 0 : call endrun(errmsg)
651 : end if
652 :
653 : !----------------------------------------------------------------------------
654 : ! read datafile with coefficients A_klnm
655 : !----------------------------------------------------------------------------
656 : if (debug) write(iulog,*) 'read_acoef: read file ',trim(locfn)
657 2 : read(unit,*,iostat = ios) a_hf
658 2 : if(ios.gt.0) then
659 0 : write(errmsg,*) 'read_acoef: error in reading coeff_hf file',' unit ',unit
660 0 : call endrun(errmsg)
661 : end if
662 :
663 : !----------------------------------------------------------------------------
664 : ! close & free unit
665 : !----------------------------------------------------------------------------
666 2 : close(unit)
667 2 : call freeunit(unit)
668 : if (debug) write(iulog,*) 'read_acoef: free unit ',unit
669 : endif
670 :
671 1536 : call mpi_bcast (a_lf, ni+1, mpi_real8, masterprocid, mpicom, ierr)
672 1536 : call mpi_bcast (a_hf, ni+1, mpi_real8, masterprocid, mpicom, ierr)
673 :
674 1536 : end subroutine read_acoef
675 :
676 16128 : subroutine adj_S_a
677 : !----------------------------------------------------------------------------
678 : ! adjust S_a -> S_aM eqn.8-11 Scherliess draft
679 : !----------------------------------------------------------------------------
680 :
681 : implicit none
682 :
683 : !----------------------------------------------------------------------------
684 : ! local variables
685 : !----------------------------------------------------------------------------
686 : integer :: i
687 : real(r8) :: x2, y2, a90, a180, S_aM
688 :
689 16128 : x2 = 90._r8*90._r8
690 : y2 = (90._r8 - 65._r8)
691 : y2 = y2*y2
692 16128 : a90 = atan2(y2,x2)
693 : y2 = (180._r8 - 65._r8)
694 16128 : y2 = y2*y2
695 16128 : a180 = atan2(y2,x2)
696 : ! y2 = (S_a-65._r8)
697 16128 : y2 = (f107d - 65._r8)
698 16128 : y2 = y2*y2
699 16128 : S_aM = (atan2(y2,x2) - a90)/(a180 - a90)
700 16128 : S_aM = 90._r8*(1._r8 + S_aM)
701 : if(debug.and.masterproc) write(iulog,*) 'f107d=',f107d,' S_aM =',S_aM
702 :
703 : !----------------------------------------------------------------------------
704 : ! inter/extrapolate to S_a (f107d)
705 : !----------------------------------------------------------------------------
706 17627904 : do i = 0,ni ! eqn.8 Scherliess draft
707 17627904 : a_klnm(i) = S_aM*(a_hf(i) - a_lf(i))/90._r8 + 2._r8*a_lf(i) - a_hf(i)
708 : ! for testing like in original code
709 : ! a_klnm(i)=S_a*(a_hf(i)-a_lf(i))/90.+2.*a_lf(i)-a_hf(i)
710 : ! a_klnm(i)=f107d*(a_hf(i)-a_lf(i))/90.+2.*a_lf(i)-a_hf(i)
711 : end do
712 :
713 16128 : end subroutine adj_S_a
714 :
715 1536 : subroutine constants
716 : !----------------------------------------------------------------------------
717 : ! Purpose: set up constant values (e.g. magnetic grid, convertion
718 : ! constants etc)
719 : !
720 : ! Method:
721 : !
722 : ! Author: A. Maute Nov 2003 am 11/19/03
723 : !----------------------------------------------------------------------------
724 :
725 : !----------------------------------------------------------------------------
726 : ! local variables
727 : !----------------------------------------------------------------------------
728 : integer :: i,j
729 : real(r8) :: fac,lat
730 :
731 1536 : rtd = 180._r8/pi ! radians -> deg
732 1536 : dtr = pi/180._r8 ! deg -> radians
733 1536 : sqr2 = sqrt(2.e0_r8)
734 1536 : dy2rd = 2._r8*pi/dy2yr ! 2*pi/365.24 average year
735 :
736 : !----------------------------------------------------------------------------
737 : ! Set grid deltas:
738 : !----------------------------------------------------------------------------
739 1536 : dlatm = 180._r8/nmlat
740 1536 : dlonm = 360._r8/nmlon
741 :
742 : !----------------------------------------------------------------------------
743 : ! Set magnetic latitude array
744 : !----------------------------------------------------------------------------
745 141312 : do j = 0,nmlat
746 139776 : ylatm(j) = j*dlatm
747 139776 : lat = (ylatm(j) - 90._r8)*dtr
748 139776 : fac = cos(lat) ! sinIm = 2*sin(lam_m)/sqrt[4-3*cos^2(lam_m)]
749 139776 : fac = 4._r8 - 3._r8*fac*fac
750 139776 : fac = 2._r8/sqrt( fac )
751 141312 : sinIm_mag(j) = fac*sin( lat )
752 : end do
753 :
754 : !----------------------------------------------------------------------------
755 : ! Set magnetic longitude array
756 : !----------------------------------------------------------------------------
757 279552 : do i = 0,nmlon
758 279552 : ylonm(i) = i*dlonm
759 : end do
760 :
761 : !----------------------------------------------------------------------------
762 : ! find boundary index for high-lat potential
763 : !----------------------------------------------------------------------------
764 35328 : do j = 0,nmlat
765 35328 : nmlat_hgh = j
766 35328 : if( bnd_hgh <= ylatm(j) ) then
767 : exit
768 : end if
769 : end do
770 :
771 : !----------------------------------------------------------------------------
772 : ! find latitudinal shift
773 : !----------------------------------------------------------------------------
774 43008 : do j = 0,nmlat
775 43008 : ilat_sft = j
776 43008 : if( lat_sft <= ylatm(j) ) then
777 : exit
778 : end if
779 : end do
780 :
781 : !----------------------------------------------------------------------------
782 : ! find index for linear interpolation of ed2 at mag.equator
783 : ! use 12 deg - same as in TIEGCM
784 : !----------------------------------------------------------------------------
785 81408 : do j = 0,nmlat
786 81408 : lat = ylatm(j) - 90._r8
787 81408 : if( lat <= -12._r8 ) then
788 61440 : jmin = j
789 19968 : else if( lat > 12._r8 ) then
790 1536 : jmax = j
791 1536 : exit
792 : end if
793 : end do
794 :
795 1536 : end subroutine constants
796 :
797 1536 : subroutine prep_fk
798 : !----------------------------------------------------------------------------
799 : ! Purpose: set up constants factors for f_-k(day) used for empirical model
800 : ! to calculate the electric potential
801 : !
802 : ! Method:
803 : !
804 : ! Author: A. Maute Nov 2003 am 11/19/03
805 : !----------------------------------------------------------------------------
806 :
807 1536 : ft(1,0) = .75_r8*sqrt( 6.e0_r8 )/pi
808 1536 : ft(1,1) = 2.e0_r8*ft(1,0)
809 1536 : ft(1,2) = 1.e0_r8
810 1536 : ft(2,0) = ft(1,0)
811 1536 : ft(2,1) = -ft(1,1)
812 1536 : ft(2,2) = 1.e0_r8
813 1536 : ft(3,0) = ft(2,1)
814 1536 : ft(3,1) = 0._r8
815 1536 : ft(3,2) = 1.e0_r8
816 :
817 1536 : end subroutine prep_fk
818 :
819 134281728 : subroutine set_fkflfs( fk, fl, fs )
820 : !----------------------------------------------------------------------------
821 : ! Purpose: set f_-k(day) depending on seasonal flag used for empirical model
822 : ! to calculate the electric potential
823 : !
824 : ! Method:
825 : !
826 : ! Author: A. Maute Nov 2003 am 11/20/03
827 : !----------------------------------------------------------------------------
828 :
829 : !----------------------------------------------------------------------------
830 : ! ... dummy arguments
831 : !----------------------------------------------------------------------------
832 : real(r8), intent(out) :: &
833 : fk(0:2), & ! f_-k(day)
834 : fl(-2:2), & ! f_l(ut)
835 : fs(2) ! f_s(f10.7)
836 : !----------------------------------------------------------------------------
837 : ! local variables
838 : !----------------------------------------------------------------------------
839 : integer :: lp
840 : real(r8) :: ang
841 : real(r8) :: lon_ut
842 :
843 : !----------------------------------------------------------------------------
844 : ! f_-k(day)
845 : ! use factors for iseasav == 0 - Scherliess had iseasav as an input parameter
846 : !----------------------------------------------------------------------------
847 134281728 : lp = iseasav
848 : if( iseasav == 0 ) then
849 134281728 : ang = (day + 9._r8)*dy2rd
850 134281728 : fk(0) = sqr2*cos( 2._r8*ang )
851 134281728 : fk(1) = sqr2*cos( ang )
852 134281728 : fk(2) = 1._r8
853 : else if( iseasav >= 1 .and. iseasav <= 3 ) then
854 : fk(0) = ft(lp,0)
855 : fk(1) = ft(lp,1)
856 : fk(2) = ft(lp,2)
857 : else if( iseasav == 4 ) then
858 : fk(0) =0._r8
859 : fk(1) =0._r8
860 : fk(2) =1._r8
861 : end if
862 :
863 : !----------------------------------------------------------------------------
864 : ! f_l(ut)
865 : !----------------------------------------------------------------------------
866 134281728 : lon_ut = 15._r8*ut ! 15.*mlt - xmlon + 69.
867 134281728 : call ff( lon_ut, 2, fl )
868 : if( iutav ) then ! UT-averaging
869 :
870 : ang = fl(0)
871 : fl(:) = 0._r8
872 : fl(0) = ang
873 :
874 : end if
875 :
876 : !----------------------------------------------------------------------------
877 : ! f_s(f10.7) only fs(1) used
878 : !----------------------------------------------------------------------------
879 134281728 : fs(1) = 1._r8
880 : ! fs(2) = S_a
881 134281728 : fs(2) = f107d
882 :
883 134281728 : end subroutine set_fkflfs
884 :
885 134281728 : subroutine efield_mid( mlat, mlon, pot )
886 : !----------------------------------------------------------------------------
887 : ! Purpose: calculate the electric potential for low and
888 : ! midlatitudes from an empirical model (Scherliess 1999)
889 : !
890 : ! Method:
891 : !
892 : ! Author: A. Maute Nov 2003 am 11/20/03
893 : !----------------------------------------------------------------------------
894 :
895 : !----------------------------------------------------------------------------
896 : ! ... dummy arguments
897 : !----------------------------------------------------------------------------
898 : real(r8), intent(in) :: mlat, mlon
899 : real(r8), intent(out) :: pot ! electric potential (V)
900 :
901 : !----------------------------------------------------------------------------
902 : ! local variables
903 : !----------------------------------------------------------------------------
904 : integer :: i, mp, np, nn
905 : real(r8) :: mod_mlat, ct, x
906 : real(r8) :: fk(0:2) ! f_-k(day)
907 : real(r8) :: fl(-2:2) ! f_l(ut)
908 : real(r8) :: fs(2) ! f_s(f10.7)
909 : real(r8) :: f(-18:18)
910 : real(r8) :: p(0:nm,0:mm) ! P_n^m spherical harmonics
911 :
912 134281728 : pot = 0._r8 ! initialize
913 :
914 134281728 : mod_mlat = mlat
915 134281728 : if( abs(mlat) <= 0.5_r8 ) then
916 2919168 : mod_mlat = 0.5_r8 ! avoid geomag.equator
917 : end if
918 :
919 : !----------------------------------------------------------------------------
920 : ! set f_-k, f_l, f_s depending on seasonal flag
921 : !----------------------------------------------------------------------------
922 134281728 : call set_fkflfs( fk, fl, fs )
923 :
924 : !----------------------------------------------------------------------------
925 : ! spherical harmonics
926 : !----------------------------------------------------------------------------
927 134281728 : ct = cos( (90._r8 - mod_mlat)*dtr ) ! magnetic colatitude
928 134281728 : call pnm( ct, p ) ! calculate P_n^m
929 134281728 : call ff( mlon, 18, f ) ! calculate f_m (phi) why 18 if N=12
930 :
931 >14676*10^7 : do i = 0,imax
932 >14663*10^7 : mp = mf(i)
933 >14663*10^7 : np = nf(i)
934 >14663*10^7 : nn = abs(mp) ! P_n^m = P_n^-m
935 >14663*10^7 : x = a_klnm(i)* fl(lf(i)) * fk(kf(i)) * fs(jf(i))
936 >14676*10^7 : pot = pot + x*f(mp)*p(np,nn)
937 : end do
938 :
939 134281728 : end subroutine efield_mid
940 :
941 16128 : subroutine pot_latsmo( pot, idlat ) ! pots == pot_highlats
942 : !----------------------------------------------------------------------------
943 : ! Purpose: smoothing in latitude of potential
944 : !
945 : ! Method: weighted smoothing in latitude
946 : ! assume regular grid spacing
947 : !
948 : ! Author: A. Maute Nov 2003 am 11/20/03
949 : !----------------------------------------------------------------------------
950 :
951 : !----------------------------------------------------------------------------
952 : ! ... dummy arguments
953 : !----------------------------------------------------------------------------
954 : integer, intent(in) :: idlat
955 : real(r8), intent(inout) :: pot(0:nmlon,0:nmlat)
956 :
957 : !----------------------------------------------------------------------------
958 : ! local variables
959 : !----------------------------------------------------------------------------
960 : integer :: ilat, id
961 : real(r8) :: wgt, del
962 32256 : real(r8) :: w(-idlat:idlat)
963 : ! real(r8) :: pot_smo(0:nmlat) ! temp array for smooth. potential
964 32256 : real(r8) :: pot_smo(0:nmlon,0:nmlat_hgh) ! temp array for smooth. potential
965 :
966 : !----------------------------------------------------------------------------
967 : ! weighting factors (regular grid spacing)
968 : !----------------------------------------------------------------------------
969 16128 : wgt = 0._r8
970 96768 : do id = -idlat,idlat
971 80640 : del = abs(id)*dlatm ! delta lat_m
972 80640 : w(id) = 1._r8/(del + 1._r8)
973 96768 : wgt = wgt + w(id)
974 : end do
975 16128 : wgt = 1._r8/wgt
976 :
977 : !$omp parallel do private(ilat)
978 322560 : do ilat = idlat,nmlat_hgh-idlat
979 55786752 : pot_smo(:,ilat) = matmul( pot(:,ilat-idlat:ilat+idlat),w )*wgt
980 : end do
981 :
982 322560 : do ilat = idlat,nmlat_hgh-idlat
983 56077056 : pot(:,ilat) = pot_smo(:,ilat)
984 55786752 : pot(:,nmlat-ilat) = pot_smo(:,ilat)
985 : end do
986 :
987 16128 : end subroutine pot_latsmo
988 :
989 16128 : subroutine pot_latsmo2( pot, idlat )
990 : !----------------------------------------------------------------------------
991 : ! Purpose: smoothing in latitude of potential
992 : !
993 : ! Method: weighted smoothing in latitude
994 : ! assume regular grid spacing
995 : !
996 : ! Author: A. Maute Nov 2003 am 11/20/03
997 : !----------------------------------------------------------------------------
998 :
999 : !----------------------------------------------------------------------------
1000 : ! ... dummy arguments
1001 : !----------------------------------------------------------------------------
1002 : integer, intent(in) :: idlat
1003 : real(r8), intent(inout) :: pot(0:nmlon,0:nmlat)
1004 :
1005 : !----------------------------------------------------------------------------
1006 : ! local variables
1007 : !----------------------------------------------------------------------------
1008 : integer :: ilat, id
1009 : real(r8) :: wgt, del
1010 32256 : real(r8) :: w(-idlat:idlat)
1011 : ! real(r8) :: pot_smo(0:nmlat) ! temp array for smooth. potential
1012 : real(r8) :: pot_smo(0:nmlon,0:nmlath) ! temp array for smooth. potential
1013 :
1014 : !----------------------------------------------------------------------------
1015 : ! weighting factors (regular grid spacing)
1016 : !----------------------------------------------------------------------------
1017 16128 : wgt = 0._r8
1018 96768 : do id = -idlat,idlat
1019 80640 : del = abs(id)*dlatm ! delta lat_m
1020 80640 : w(id) = 1._r8/(del + 1._r8)
1021 96768 : wgt = wgt + w(id)
1022 : end do
1023 16128 : wgt = 1._r8/wgt
1024 :
1025 : ! do ilon = 0,nmlon
1026 : ! do ilat = idlat,nmlath-idlat ! ilat = 5:175
1027 : ! pot_smo(ilat) = 0._r8
1028 : ! do id = -idlat,idlat ! org. was degree now grid points
1029 : ! pot_smo(ilat) = pot_smo(ilat) + w(id)*pot(ilon,ilat+id)
1030 : ! end do
1031 : ! pot_smo(ilat) = pot_smo(ilat)*wgt
1032 : ! end do
1033 : ! pot(ilon,idlat:nmlath-idlat) = pot_smo(idlat:nmlath-idlat) ! copy back into pot
1034 : ! end do
1035 :
1036 : !$omp parallel do private(ilat)
1037 693504 : do ilat = idlat,nmlath-idlat
1038 123298560 : pot_smo(:,ilat) = matmul( pot(:,ilat-idlat:ilat+idlat),w )*wgt
1039 : end do
1040 :
1041 693504 : do ilat = idlat,nmlath-idlat
1042 123975936 : pot(:,ilat) = pot_smo(:,ilat)
1043 : end do
1044 :
1045 16128 : end subroutine pot_latsmo2
1046 :
1047 16128 : subroutine pot_lonsmo( pot, idlon )
1048 : !----------------------------------------------------------------------------
1049 : ! Purpose: smoothing in longitude of potential
1050 : !
1051 : ! Method: weighted smoothing in longitude
1052 : ! assume regular grid spacing
1053 : !
1054 : ! Author: A. Maute Nov 2003 am 11/20/03
1055 : !----------------------------------------------------------------------------
1056 :
1057 : !----------------------------------------------------------------------------
1058 : ! ... dummy arguments
1059 : !----------------------------------------------------------------------------
1060 : integer, intent(in) :: idlon
1061 : real(r8), intent(inout) :: pot(0:nmlon,0:nmlat)
1062 :
1063 : !----------------------------------------------------------------------------
1064 : ! local variables
1065 : !----------------------------------------------------------------------------
1066 : integer :: ilon, ilat, id
1067 : real(r8) :: wgt, del
1068 32256 : real(r8) :: w(-idlon:idlon)
1069 32256 : real(r8) :: tmp(-idlon:nmlon+idlon) ! temp array for smooth. potential
1070 :
1071 : !----------------------------------------------------------------------------
1072 : ! weighting factors (regular grid spacing)
1073 : !----------------------------------------------------------------------------
1074 16128 : wgt = 0._r8
1075 129024 : do id = -idlon,idlon
1076 112896 : del = abs(id)*dlonm ! delta lon_m
1077 112896 : w(id) = 1._r8/(del + 1._r8)
1078 129024 : wgt = wgt + w(id)
1079 : end do
1080 16128 : wgt = 1._r8/wgt
1081 :
1082 : !----------------------------------------------------------------------------
1083 : ! averaging
1084 : !----------------------------------------------------------------------------
1085 : ! do ilon = 0,nmlon
1086 : ! do ilat = 0,nmlath
1087 : ! pot_smo(ilat) = 0._r8
1088 : ! do id = -idlon,idlon ! org. was degree now grid points
1089 : ! iabs = ilon + id
1090 : ! if( iabs > nmlon ) then
1091 : ! iabs = iabs - nmlon ! test if wrap around
1092 : ! end if
1093 : ! if( iabs < 0 ) then
1094 : ! iabs = iabs + nmlon ! test if wrap around
1095 : ! end if
1096 : ! pot_smo(ilat) = pot_smo(ilat) + w(id)*pot(iabs,ilat)
1097 : ! end do
1098 : ! pot_smo(ilat) = pot_smo(ilat)*wgt
1099 : ! pot(ilon,ilat) = pot_smo(ilat) ! copy back into pot
1100 : ! pot(ilon,nmlat-ilat) = pot_smo(ilat) ! copy back into pot
1101 : ! end do
1102 : ! end do
1103 :
1104 : !$omp parallel do private(ilat,ilon,tmp)
1105 758016 : do ilat = 0,nmlath
1106 135023616 : tmp(0:nmlon) = pot(0:nmlon,ilat)
1107 2967552 : tmp(-idlon:-1) = pot(nmlon-idlon:nmlon-1,ilat)
1108 3709440 : tmp(nmlon+1:nmlon+idlon) = pot(1:idlon,ilat)
1109 135039744 : do ilon = 0,nmlon
1110 1074253824 : pot(ilon,ilat) = dot_product( tmp(ilon-idlon:ilon+idlon),w )*wgt
1111 135023616 : pot(ilon,nmlat-ilat) = pot(ilon,ilat)
1112 : end do
1113 : end do
1114 :
1115 16128 : end subroutine pot_lonsmo
1116 :
1117 16128 : subroutine highlat_getbnd( ihlat_bnd )
1118 : !----------------------------------------------------------------------------
1119 : ! Purpose: calculate the height latitude bounday index ihl_bnd
1120 : !
1121 : ! Method:
1122 : ! 1. calculate E field from high-latitude model
1123 : ! boundary is set where the total electric field exceeds
1124 : ! 0.015 V/m (corresp. approx. to 300 m/s)
1125 : ! 2. moved halfways to 54 deg not necessarily equatorwards as in the
1126 : ! original comment from L. Scherliess- or?
1127 : !
1128 : ! Author: A. Maute Nov 2003 am 11/20/03
1129 : !----------------------------------------------------------------------------
1130 :
1131 : !----------------------------------------------------------------------------
1132 : ! ... dummy arguments
1133 : !----------------------------------------------------------------------------
1134 : integer, intent(out) :: ihlat_bnd(0:nmlon)
1135 :
1136 : !----------------------------------------------------------------------------
1137 : ! local variables
1138 : !----------------------------------------------------------------------------
1139 : integer :: ilon, ilat, ilat_sft_rvs
1140 : real(r8) :: e_tot
1141 : real(r8) :: e_max, ef_max
1142 :
1143 : ! first find absolute max E-field magnitude
1144 16128 : e_max = 0._r8
1145 2935296 : do ilon = 0,nmlon
1146 72995328 : do ilat = nmlat_hgh+1,0,-1 ! lat. loop moving torwards pole
1147 70060032 : e_tot = sqrt( ed1(ilon,ilat)**2 + ed2(ilon,ilat)**2 )
1148 72979200 : if (e_tot > e_max) then
1149 677376 : e_max = e_tot
1150 : end if
1151 : end do
1152 : end do
1153 :
1154 : ! Set E-field strength used to find the transition boundary:
1155 : ! when Kp is low the max E-field strength from Heelis is less than 0.015 V/m
1156 : ! for such cases set ef_max to half the max E-field strength
1157 16128 : ef_max = min(0.015_r8,e_max*0.5_r8)
1158 :
1159 16128 : ilat_sft_rvs = nmlath - ilat_sft ! pole =0, equ=90
1160 2935296 : do ilon = 0,nmlon
1161 46480896 : do ilat = nmlat_hgh+1,0,-1 ! lat. loop moving torwards pole
1162 46464768 : e_tot = sqrt( ed1(ilon,ilat)**2 + ed2(ilon,ilat)**2 )
1163 46464768 : if( abs(e_tot) >= ef_max ) then ! e-filed > limit -> boundary
1164 2919168 : ihlat_bnd(ilon) = ilat - (ilat - ilat_sft_rvs)*.5_r8 ! shift boundary to lat_sft (54deg)
1165 2919168 : exit
1166 : end if
1167 : end do
1168 : end do
1169 :
1170 16128 : end subroutine highlat_getbnd
1171 :
1172 16128 : subroutine bnd_sinus( ihlat_bnd, itrans_width )
1173 : !----------------------------------------------------------------------------
1174 : ! Purpose:
1175 : ! 1. adjust high latitude boundary (ihlat_bnd) sinusoidally
1176 : ! 2. width of transition zone from midlatitude potential to high latitude
1177 : ! potential (itrans_width)
1178 : !
1179 : ! Method:
1180 : ! 1.adjust boundary sinusoidally
1181 : ! max. wave number to be represented nmax_sin
1182 : ! RHS(mi) = Sum_phi Sum_(mi=-nmax_sin)^_(mi=nmax_sin) f_mi(phi)*hlat_bnd(phi)
1183 : ! U(mi,mk) = Sum_phi Sum_(mi=-nmax_sin)^_(mi=nmax_sin) f_mi(phi) *
1184 : ! Sum_(mk=-nmax_sin)^_(mk=nmax_sin) f_mk(phi)
1185 : ! single values decomposition of U
1186 : ! solving U*LSG = RHS
1187 : ! calculating hlat_bnd:
1188 : ! hlat_bnd = Sum_(mi=-nmax_sin)^_(mi=nmax_sin) f_mi(phi)*LSG(mi)
1189 : !
1190 : ! 2. width of transition zone from midlatitude potential to high latitude
1191 : ! potential
1192 : ! trans_width(phi)=8.-2.*cos(phi)
1193 : !
1194 : ! Author: A. Maute Nov 2003 am 11/20/03
1195 : !----------------------------------------------------------------------------
1196 :
1197 : external DGESV ! LAPACK routine to solve matrix eq
1198 :
1199 : !----------------------------------------------------------------------------
1200 : ! ... dummy arguments
1201 : !----------------------------------------------------------------------------
1202 : integer, intent(inout) :: ihlat_bnd(0:nmlon) ! loaction of boundary
1203 : integer, intent(out) :: itrans_width(0:nmlon) ! width of transition zone
1204 :
1205 : !----------------------------------------------------------------------------
1206 : ! local variables
1207 : !----------------------------------------------------------------------------
1208 : integer, parameter :: nmax_a = 2*nmax_sin+1 ! absolute array length
1209 : integer, parameter :: ishf = nmax_sin+1
1210 : integer :: ilon, i, i1, j, bnd
1211 : real(r8) :: sum
1212 : real(r8) :: rhs(nmax_a)
1213 : real(r8) :: lsg(nmax_a)
1214 : real(r8) :: u(nmax_a,nmax_a)
1215 : real(r8) :: v(nmax_a,nmax_a)
1216 : real(r8) :: w(nmax_a,nmax_a)
1217 : real(r8) :: f(-nmax_sin:nmax_sin,0:nmlon)
1218 :
1219 : real(r8) :: x(nmax_a)
1220 : integer :: ipiv(nmax_a), info
1221 :
1222 : character(len=120) :: msg
1223 :
1224 : !----------------------------------------------------------------------------
1225 : ! Sinusoidal Boundary calculation
1226 : !----------------------------------------------------------------------------
1227 16128 : rhs(:) = 0._r8
1228 16128 : lsg(:) = 0._r8
1229 16128 : u(:,:) = 0._r8
1230 16128 : v(:,:) = 0._r8
1231 16128 : w(:,:) = 0._r8
1232 16128 : ipiv(:) = 0
1233 :
1234 2935296 : do ilon = 0,nmlon ! long.
1235 2919168 : bnd = nmlath - ihlat_bnd(ilon) ! switch from pole=0 to pole =90
1236 2919168 : call ff( ylonm(ilon), nmax_sin, f(-nmax_sin,ilon) )
1237 17531136 : do i = -nmax_sin,nmax_sin
1238 14595840 : i1 = i + ishf
1239 14595840 : rhs(i1) = rhs(i1) + f(i,ilon) * bnd
1240 : ! if (debug) write(iulog,*) 'rhs ',ilon,i1,bnd,f(i,ilon),rhs(i+ishf)
1241 90494208 : do j = -nmax_sin,nmax_sin
1242 87575040 : u(i1,j+ishf) = u(i1,j+ishf) + f(i,ilon)*f(j,ilon)
1243 : ! if (debug) write(iulog,*) 'u ',ilon,i1,j+ishf,u(i+ishf,j+ishf)
1244 : end do
1245 : end do
1246 : end do
1247 : !
1248 16128 : x(:) = rhs(:)
1249 16128 : call DGESV( nmax_a, 1, u, nmax_a, ipiv, x, nmax_a, info)
1250 16128 : if (info/=0) then
1251 0 : write(msg,'(a,i4)') 'bnd_sinus -- LAPACK DGESV return error code: ',info
1252 0 : if (masterproc) write(iulog,*) trim(msg)
1253 0 : call endrun(trim(msg))
1254 : end if
1255 16128 : lsg(:) = x(:)
1256 : !
1257 2935296 : do ilon = 0,nmlon ! long.
1258 17515008 : sum = dot_product( lsg(-nmax_sin+ishf:nmax_sin+ishf),f(-nmax_sin:nmax_sin,ilon) )
1259 2919168 : ihlat_bnd(ilon) = nmlath - int( sum + .5_r8 ) ! closest point
1260 2935296 : itrans_width(ilon) = int( 8._r8 - 2._r8*cos( ylonm(ilon)*dtr ) + .5_r8 )/dlatm ! 6 to 10 deg.
1261 : end do
1262 : ! if (debug) write(iulog,"('bnd_sinus: ihlat_bnd=',/,(12i6))") ihlat_bnd
1263 : ! if (debug) write(iulog,"('bnd_sinus: itrans_width=',/,(12i6))") itrans_width
1264 :
1265 16128 : end subroutine bnd_sinus
1266 :
1267 16128 : subroutine highlat_adjust( pot_highlats, pot_highlat, pot_midlat, ihlat_bnd )
1268 : !----------------------------------------------------------------------------
1269 : ! Purpose: Adjust mid/low latitude electric potential and high latitude
1270 : ! potential such that there are continous across the mid to high
1271 : ! latitude boundary
1272 : !
1273 : ! Method:
1274 : ! 1. integrate Phi_low/mid(phi,bnd) along the boundary mid to high latitude
1275 : ! 2. integrate Phi_high(phi,bnd) along the boundary mid to high latitude
1276 : ! 3. adjust Phi_high by delta =
1277 : ! Int_phi Phi_high(phi,bnd) d phi/360. - Int_phi Phi_low/mid(phi,bnd) d phi/360.
1278 : !
1279 : ! Author: A. Maute Nov 2003 am 11/21/03
1280 : !----------------------------------------------------------------------------
1281 :
1282 : !----------------------------------------------------------------------------
1283 : ! ... dummy arguments
1284 : !----------------------------------------------------------------------------
1285 : integer, intent(in) :: ihlat_bnd(0:nmlon) ! boundary mid to high latitude
1286 : real(r8), intent(in) :: pot_midlat(0:nmlon,0:nmlat) ! low/mid latitude potentail
1287 : real(r8), intent(inout) :: pot_highlat(0:nmlon,0:nmlat) ! high_lat potential
1288 : real(r8), intent(inout) :: pot_highlats(0:nmlon,0:nmlat) ! high_lat potential! smoothed high_lat potential
1289 :
1290 : !----------------------------------------------------------------------------
1291 : ! local:
1292 : !----------------------------------------------------------------------------
1293 : integer :: ilon, ilat, ilatS, ibnd60, ibnd_hl
1294 : real(r8) :: pot60, pot_hl, del
1295 :
1296 : !----------------------------------------------------------------------------
1297 : ! 1. integrate Phi_low/mid(phi,bnd) along the boundary mid to high latitude
1298 : ! 2. integrate Phi_high(phi,bnd) along the boundary mid to high latitude
1299 : !----------------------------------------------------------------------------
1300 16128 : pot60 = 0._r8
1301 16128 : pot_hl = 0._r8
1302 2919168 : do ilon = 1,nmlon ! long. ! bnd -> eq to pole 0:90
1303 2903040 : ibnd60 = nmlat - ihlat_bnd(ilon) ! 0:180 pole to pole
1304 2903040 : ibnd_hl = ihlat_bnd(ilon) ! colatitude
1305 2903040 : pot60 = pot60 + pot_midlat(ilon,ibnd60)
1306 2919168 : pot_hl = pot_hl + pot_highlats(ilon,ibnd_hl)
1307 : end do
1308 16128 : pot60 = pot60/(nmlon)
1309 16128 : pot_hl = pot_hl/(nmlon)
1310 :
1311 : if (debug.and.masterproc) write(iulog,*) 'Mid-Latitude Boundary Potential =',pot60
1312 : if (debug.and.masterproc) write(iulog,*) 'High-Latitude Boundary Potential=',pot_hl
1313 :
1314 : !----------------------------------------------------------------------------
1315 : ! 3. adjust Phi_high by delta =
1316 : ! Int_phi Phi_high(phi,bnd) d phi/360. - Int_phi Phi_low/mid(phi,bnd) d phi/360.
1317 : !----------------------------------------------------------------------------
1318 16128 : del = pot_hl - pot60
1319 :
1320 : !$omp parallel do private(ilat,ilon,ilats)
1321 387072 : do ilat = 0,nmlat_hgh ! colatitude
1322 370944 : ilats = nmlat - ilat
1323 67527936 : do ilon = 0,nmlon
1324 67140864 : pot_highlat(ilon,ilat) = pot_highlat(ilon,ilat) - del
1325 67140864 : pot_highlat(ilon,ilats) = pot_highlat(ilon,ilats) - del
1326 67140864 : pot_highlats(ilon,ilat) = pot_highlats(ilon,ilat) - del
1327 67511808 : pot_highlats(ilon,ilats) = pot_highlats(ilon,ilats) - del
1328 : end do
1329 : end do
1330 :
1331 16128 : end subroutine highlat_adjust
1332 :
1333 16128 : subroutine interp_poten( pot_highlats, pot_highlat, pot_midlat, &
1334 : ihlat_bnd, itrans_width )
1335 : !----------------------------------------------------------------------------
1336 : ! Purpose: construct a smooth global electric potential field
1337 : !
1338 : ! Method: construct one global potential field
1339 : ! 1. low/mid latitude: |lam| < bnd-trans_width
1340 : ! Phi(phi,lam) = Phi_low(phi,lam)
1341 : ! 2. high latitude: |lam| > bnd+trans_width
1342 : ! Phi(phi,lam) = Phi_hl(phi,lam)
1343 : ! 3. transition zone: bnd-trans_width <= lam <= bnd+trans_width
1344 : ! a. interpolate between high and low/midlatitude potential
1345 : ! Phi*(phi,lam) = 1/15*[ 5/(2*trans_width) * {Phi_low(phi,bnd-trans_width)*
1346 : ! [-lam+bnd+trans_width] + Phi_hl(phi,bnd+trans_width)*
1347 : ! [lam-bnd+trans_width]} + 10/(2*trans_width) {Phi_low(phi,lam)*
1348 : ! [-lam+bnd+trans_width] + Phi_hl(phi,lam)*
1349 : ! [lam-bnd+trans_width]}]
1350 : ! b. Interpolate between just calculated Potential and the high latitude
1351 : ! potential in a 3 degree zone poleward of the boundary:
1352 : ! bnd+trans_width < lam <= bnd+trans_width+ 3 deg
1353 : ! Phi(phi,lam) = 1/3 { [3-(lam-bnd-trans_width)]* Phi*(phi,lam) +
1354 : ! [lam-bnd-trans_width)]* Phi_hl*(phi,lam) }
1355 : !
1356 : ! Author: A. Maute Nov 2003 am 11/21/03
1357 : !----------------------------------------------------------------------------
1358 :
1359 : !----------------------------------------------------------------------------
1360 : ! ... dummy arguments
1361 : !----------------------------------------------------------------------------
1362 : integer, intent(in) :: ihlat_bnd(0:nmlon)
1363 : integer, intent(in) :: itrans_width(0:nmlon)
1364 : real(r8), intent(in) :: pot_highlats(0:nmlon,0:nmlat)
1365 : real(r8), intent(in) :: pot_highlat(0:nmlon,0:nmlat)
1366 : real(r8), intent(in) :: pot_midlat(0:nmlon,0:nmlat)
1367 :
1368 : !----------------------------------------------------------------------------
1369 : ! local variables
1370 : !----------------------------------------------------------------------------
1371 : real(r8), parameter :: fac = 1._r8/3._r8
1372 : integer :: ilon, ilat
1373 : integer :: ibnd, tw, hb1, hb2, lat_ind
1374 : integer :: j1, j2
1375 : real(r8) :: a, b, b1, b2
1376 : real(r8) :: wrk1, wrk2
1377 :
1378 : !$omp parallel do private(ilat,ilon,ibnd,tw)
1379 2935296 : do ilon = 0,nmlon
1380 2919168 : ibnd = ihlat_bnd(ilon) ! high latitude boundary index
1381 2919168 : tw = itrans_width(ilon) ! width of transition zone (index)
1382 : !----------------------------------------------------------------------------
1383 : ! 1. low/mid latitude: |lam| < bnd-trans_width
1384 : ! Phi(phi,lam) = Phi_low(phi,lam)
1385 : !----------------------------------------------------------------------------
1386 86155776 : do ilat = 0,nmlath-(ibnd+tw+1)
1387 83236608 : potent(ilon,nmlath+ilat) = pot_midlat(ilon,nmlath+ilat)
1388 86155776 : potent(ilon,nmlath-ilat) = pot_midlat(ilon,nmlath+ilat)
1389 : end do
1390 : !----------------------------------------------------------------------------
1391 : ! 2. high latitude: |lam| > bnd+trans_width
1392 : ! Phi(phi,lam) = Phi_hl(phi,lam)
1393 : !----------------------------------------------------------------------------
1394 28836864 : do ilat = 0,ibnd-tw-1
1395 25901568 : potent(ilon,ilat) = pot_highlats(ilon,nmlat-ilat)
1396 28820736 : potent(ilon,nmlat-ilat) = pot_highlats(ilon,nmlat-ilat)
1397 : end do
1398 : end do
1399 : !----------------------------------------------------------------------------
1400 : ! 3. transition zone: bnd-trans_width <= lam <= bnd+trans_width
1401 : !----------------------------------------------------------------------------
1402 : ! a. interpolate between high and low/midlatitude potential
1403 : ! update only southern hemisphere (northern hemisphere is copied
1404 : ! after smoothing)
1405 : !----------------------------------------------------------------------------
1406 : !$omp parallel do private(ilat,ilon,ibnd,tw,a,b,b1,b2,hb1,hb2,lat_ind,j1,j2,wrk1,wrk2)
1407 2935296 : do ilon = 0,nmlon
1408 2919168 : ibnd = ihlat_bnd(ilon) ! high latitude boundary index
1409 2919168 : tw = itrans_width(ilon) ! width of transition zone (index)
1410 2919168 : a = 1._r8/(2._r8*tw)
1411 2919168 : b1 = (nmlath - ibnd + tw)*a
1412 2919168 : b2 = (nmlath - ibnd - tw)*a
1413 2919168 : hb1 = nmlath - (ibnd + tw)
1414 2919168 : j1 = nmlath - hb1
1415 2919168 : hb2 = nmlath - (ibnd - tw)
1416 2919168 : j2 = nmlath - hb2
1417 2919168 : wrk1 = pot_midlat(ilon,j1)
1418 2919168 : wrk2 = pot_highlats(ilon,j2)
1419 : ! if(debug.and.masterproc) write(iulog,*) 'pot_all ',ilon,hb1,hb2,nmlath -ibnd,tw
1420 28062720 : do ilat = ibnd-tw,ibnd+tw
1421 25143552 : lat_ind = nmlath - ilat
1422 25143552 : potent(ilon,ilat) = &
1423 : fac*((wrk1 + 2._r8*pot_midlat(ilon,ilat))*(b1 - a*lat_ind) &
1424 25143552 : + (wrk2 + 2._r8*pot_highlats(ilon,ilat))*(a*lat_ind - b2))
1425 28062720 : potent(ilon,nmlat-ilat) = potent(ilon,ilat)
1426 : end do
1427 : !----------------------------------------------------------------------------
1428 : ! b. Interpolate between just calculated Potential and the high latitude
1429 : ! potential in a 3 degree zone poleward of the boundary
1430 : !----------------------------------------------------------------------------
1431 28836864 : do ilat = hb2+1,nmlath
1432 25901568 : a = max( 3._r8/dlatm - (ilat - hb2 - 1),0._r8 )
1433 25901568 : b = 3._r8/dlatm - a
1434 25901568 : potent(ilon,nmlath-ilat) = (a*potent(ilon,nmlath-ilat) &
1435 25901568 : + b*pot_highlat(ilon,nmlath-ilat))/3._r8*dlatm
1436 28820736 : potent(ilon,nmlath+ilat) = potent(ilon,nmlath-ilat)
1437 : end do
1438 : end do
1439 :
1440 16128 : end subroutine interp_poten
1441 :
1442 32256 : subroutine DerivPotential
1443 : !-----------------------------------------------------------------------
1444 : ! Purpose: calulates the electric field [V/m] from the electric potential
1445 : !
1446 : ! Method: Richmond [1995] eqn 5.9-5.10
1447 : ! ed1(:,:) = Ed1 = - 1/[R cos lam_m] d PHI/d phi_m
1448 : ! ed2(:,:) = Ed2 = 1/R d PHI/d lam_m /sin I_m
1449 : ! R = R_e + h_r we assume a reference height of 130 km which is also
1450 : ! used in the TIEGCM code
1451 : !
1452 : ! Author: A. Maute Dec 2003 am 12/16/03
1453 : !-----------------------------------------------------------------------
1454 :
1455 : integer :: i, j
1456 : real(r8) :: coslm, r, fac, wrk
1457 : real(r8) :: wrk1d(0:nmlon)
1458 :
1459 32256 : r = r_e + h_r ! earth radius + reference height [m]
1460 : !-----------------------------------------------------------------------
1461 : ! ed2= Ed2 is the equatorward/downward component of the electric field, at all
1462 : ! geomagnetic grid points (central differencing)
1463 : !-----------------------------------------------------------------------
1464 32256 : fac = .5_r8/(dlatm*dtr*r)
1465 : !$omp parallel do private(j, i, wrk )
1466 1451520 : do j = 1,nmlath-1 ! southern hemisphere
1467 1419264 : wrk = fac/sinIm_mag(j)
1468 258338304 : do i = 0,nmlon
1469 258306048 : ed2(i,j) = (potent(i,j+1) - potent(i,j-1))*wrk
1470 : end do
1471 : end do
1472 :
1473 : !$omp parallel do private(j, i, wrk )
1474 1451520 : do j = nmlath+1,nmlat-1 ! northern hemisphere
1475 1419264 : wrk = fac/sinIm_mag(j)
1476 258338304 : do i = 0,nmlon
1477 258306048 : ed2(i,j) = (potent(i,j+1) - potent(i,j-1))*wrk
1478 : end do
1479 : end do
1480 :
1481 : !-----------------------------------------------------------------------
1482 : ! Interpolate of ed2 between between -12 <= lam_m <= 12 degrees:
1483 : !-----------------------------------------------------------------------
1484 5870592 : wrk1d(:) = ed2(:,jmax) - ed2(:,jmin)
1485 : !$omp parallel do private(j, i, fac)
1486 419328 : do j = jmin+1,jmax-1
1487 387072 : fac = (ylatm(j) - ylatm(jmin))/(ylatm(jmax) - ylatm(jmin))
1488 70479360 : do i = 0,nmlon
1489 70447104 : ed2(i,j) = ed2(i,jmin) + fac*wrk1d(i)
1490 : end do
1491 : end do
1492 :
1493 : !-----------------------------------------------------------------------
1494 : ! ed1= Ed1 is the zonal component of the electric field, at all
1495 : ! geomagnetic grid points (central differencing)
1496 : !-----------------------------------------------------------------------
1497 32256 : fac = .5_r8/(dlonm*dtr*r)
1498 : !$omp parallel do private(j, i, wrk, coslm )
1499 2903040 : do j = 1,nmlat-1
1500 2870784 : coslm = ylatm(j) - 90._r8
1501 2870784 : coslm = cos( coslm*dtr )
1502 2870784 : wrk = fac/coslm
1503 516741120 : do i = 1,nmlon-1
1504 516741120 : ed1(i,j) = -(potent(i+1,j) - potent(i-1,j))*wrk
1505 : end do
1506 2870784 : i = 0
1507 2870784 : ed1(i,j) = -(potent(i+1,j) - potent(nmlon-1,j))*wrk
1508 2903040 : ed1(nmlon,j) = ed1(i,j)
1509 : end do
1510 :
1511 : !-----------------------------------------------------------------------
1512 : ! Poles:
1513 : !-----------------------------------------------------------------------
1514 : !$omp parallel do private(i)
1515 5870592 : do i = 0,nmlon
1516 5838336 : ed1(i,0) = .25_r8*(ed1(i,1) - ed1(ip2f(i),1) + ed2(ip1f(i),1) - ed2(ip3f(i),1))
1517 : ed1(i,nmlat) = .25_r8*(ed1(i,nmlat-1) - ed1(ip2f(i),nmlat-1) &
1518 5838336 : + ed2(ip1f(i),nmlat-1) - ed2(ip3f(i),nmlat-1))
1519 5838336 : ed2(i,0) = .25_r8*(ed2(i,1) - ed2(ip2f(i),1) - ed1(ip1f(i),1) + ed1(ip3f(i),1))
1520 : ed2(i,nmlat) = .25_r8*(ed2(i,nmlat-1) - ed2(ip2f(i),nmlat-1) &
1521 5870592 : - ed1(ip1f(i),nmlat-1) + ed1(ip3f(i),nmlat-1))
1522 : end do
1523 :
1524 32256 : end subroutine DerivPotential
1525 :
1526 : end module efield
|