source: trunk/LMDZ.COMMON/libf/evolution/orbit.F90 @ 4071

Last change on this file since 4071 was 4071, checked in by jbclement, 12 days ago

PEM:

  • Making the computation of ice tendencies more reliable by doing it after 'read_startpem' to know exactly where perennial ice is (no matter if there is a "startpem.nc" or not). Moreover, when there is no "startpem.nc", location of perennial ice depends now on 'watercaptag' and on huge amount of frost. This prevents negative ice tendency while there is no ice which can happen with weird PCM inputs (i.e. 'watercaptag' = F & 'watercap' /= 0 & no "stratpem.nc").
  • Few small safeguards throughout the code.

JBC

File size: 22.2 KB
Line 
1MODULE orbit
2!-----------------------------------------------------------------------
3! NAME
4!     orbit
5! DESCRIPTION
6!     Compute orbital-parameter-based stopping criteria and update
7!     planetary orbit parameters.
8! AUTHORS & DATE
9!     R. Vandemeulebrouck
10!     JB Clement, 2023-2025
11! NOTES
12!
13!-----------------------------------------------------------------------
14
15! DEPENDENCIES
16! ------------
17use numerics, only: dp, di, k4, largest_nb, minieps
18
19! DECLARATION
20! -----------
21implicit none
22
23! PARAMETERS
24! ----------
25! File-related:
26character(15),                       parameter :: orbitfile_name = 'obl_ecc_lsp.asc'
27integer(di),                         protected :: iyear_lask! Index of the line in the file year_obl_lask.asc corresponding to the closest lower year to the current year
28real(dp), dimension(:), allocatable, protected :: year_lask ! Current_year before present from Laskar et al.
29real(dp), dimension(:), allocatable, protected :: obl_lask  ! Obliquity in Laskar's data [deg]
30real(dp), dimension(:), allocatable, protected :: ecc_lask  ! Eccentricity in Laskar's data
31real(dp), dimension(:), allocatable, protected :: lsp_lask  ! Ls perihelie in Laskar's data [deg]
32! Planet-related:
33real(dp),                            protected :: obliquity    ! Planet obliquity [deg]
34real(dp),                            protected :: eccentricity ! Orbit eccentricity
35real(dp),                            protected :: ls_peri      ! Solar longitude of the perihelion [deg]
36real(dp),                            protected :: perihelion   ! Perihelion [Mkm]
37real(dp),                            protected :: semimaj_axis ! Semi-major axis [Mkm]
38real(dp),                            protected :: aphelion     ! Aphelion [Mkm]
39real(dp),                            protected :: date_peri    ! Date of perihelion [sol]
40real(dp),                            protected :: sol_len_s    ! Length of a sol [s]
41real(dp),                            protected :: yr_len_sol   ! Length of a year [sol]
42! Evolution-related:
43logical(k4), protected :: evol_orbit     ! Flag to follow the orbital parameters
44logical(k4), protected :: evol_obl       ! Flag the PEM to follow obliquity
45logical(k4), protected :: evol_ecc       ! Flag the PEM to follow eccenticity
46logical(k4), protected :: evol_lsp       ! Flag the PEM to follow Ls perihelie
47real(dp),    protected :: max_change_obl ! Maximum admissible change for obliquity
48real(dp),    protected :: max_change_ecc ! Maximum admissible change for eccentricity
49real(dp),    protected :: max_change_lsp ! Maximum admissible change for Lsp
50
51contains
52!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53
54!=======================================================================
55SUBROUTINE set_orbit_config(evol_orbit_in,evol_obl_in,evol_ecc_in,evol_lsp_in,max_change_obl_in,max_change_ecc_in,max_change_lsp_in)
56!-----------------------------------------------------------------------
57! NAME
58!     set_orbit_config
59!
60! DESCRIPTION
61!     Setter for 'orbit' configuration parameters.
62!
63! AUTHORS & DATE
64!     JB Clement, 02/2026
65!
66! NOTES
67!
68!-----------------------------------------------------------------------
69
70! DEPENDENCIES
71! ------------
72use utility, only: real2str, bool2str
73use display, only: print_msg
74
75! DECLARATION
76! -----------
77implicit none
78
79! ARGUMENTS
80! ---------
81logical(k4), intent(in) :: evol_orbit_in, evol_obl_in, evol_ecc_in, evol_lsp_in
82real(dp),    intent(in) :: max_change_obl_in, max_change_ecc_in, max_change_lsp_in
83
84! CODE
85! ----
86evol_orbit = evol_orbit_in
87evol_obl = evol_obl_in
88evol_ecc = evol_ecc_in
89evol_lsp = evol_lsp_in
90max_change_obl = max_change_obl_in
91max_change_ecc = max_change_ecc_in
92max_change_lsp = max_change_lsp_in
93call print_msg('evol_orbit     = '//bool2str(evol_orbit))
94call print_msg('evol_obl       = '//bool2str(evol_obl))
95call print_msg('evol_ecc       = '//bool2str(evol_ecc))
96call print_msg('evol_lsp       = '//bool2str(evol_lsp))
97call print_msg('max_change_obl = '//real2str(max_change_obl))
98call print_msg('max_change_ecc = '//real2str(max_change_ecc))
99call print_msg('max_change_lsp = '//real2str(max_change_lsp))
100
101END SUBROUTINE set_orbit_config
102!=======================================================================
103
104!=======================================================================
105SUBROUTINE init_orbit(obliquity_in,perihelion_in,aphelion_in,date_peri_in,yr_len_sol_in,sol_len_s_in)
106!-----------------------------------------------------------------------
107! NAME
108!     init_orbit
109!
110! DESCRIPTION
111!     Initialize orbital characteristics of the planet.
112!
113! AUTHORS & DATE
114!     JB Clement, 12/2025
115!
116! NOTES
117!     Taken from 'iniorbit' in the Mars PCM.
118!-----------------------------------------------------------------------
119
120! DEPENDENCIES
121! ------------
122use maths,   only: pi
123use display, only: print_msg
124use utility, only: real2str
125
126! DECLARATION
127! -----------
128implicit none
129
130! ARGUMENTS
131! ---------
132real(dp), intent(in) :: obliquity_in, perihelion_in, aphelion_in, date_peri_in, yr_len_sol_in, sol_len_s_in
133
134! LOCAL VARIABLES
135! ---------------
136real(dp)    :: zxref, zanom, zz, zx0, zdx
137real(dp)    :: lsp ! Solar longitude of the perihelion [rad]
138integer(di) :: iter
139
140! CODE
141! ----
142! Setters
143obliquity = obliquity_in
144perihelion = perihelion_in
145aphelion = aphelion_in
146date_peri = date_peri_in
147sol_len_s = sol_len_s_in
148yr_len_sol = yr_len_sol_in
149
150! Compute eccentricity and semi-major axis
151eccentricity = (aphelion - perihelion)/(aphelion + perihelion)
152semimaj_axis = 0.5_dp*(aphelion + perihelion)
153
154! Compute mean anomaly zanom
155zz = (yr_len_sol - date_peri)/yr_len_sol
156zanom = 2._dp*pi*(zz - nint(zz))
157zxref = abs(zanom)
158
159! Solve equation zx0 - e*sin(zx0) = zxref for eccentric anomaly zx0 using Newton method
160zx0 = zxref + eccentricity*sin(zxref)
161do iter = 1,100
162    zdx = -(zx0 - eccentricity*sin(zx0) - zxref)/(1._dp - eccentricity*cos(zx0))
163    if (abs(zdx) <= 1.e-12_dp) exit
164    zx0 = zx0 + zdx
165end do
166
167zx0 = zx0 + zdx
168if (zanom < 0.) zx0 = -zx0
169
170! Compute solar longitude of the perihelion
171lsp = -2._dp*atan(sqrt((1._dp + eccentricity)/(1._dp - eccentricity))*tan(zx0/2._dp))
172lsp = modulo(lsp,2._dp*pi)
173ls_peri = lsp*180._dp/pi ! Conversion in degree
174
175call print_msg('Obliquity          [deg] = '//real2str(obliquity))
176call print_msg('Eccentricity       [-]   = '//real2str(eccentricity))
177call print_msg('Ls of perihelion   [deg] = '//real2str(ls_peri))
178call print_msg('Perihelion         [Mkm] = '//real2str(perihelion))
179call print_msg('Aphelion           [Mkm] = '//real2str(aphelion))
180call print_msg('Semi-major axis    [Mkm] = '//real2str(semimaj_axis))
181call print_msg('Date of perihelion [sol] = '//real2str(date_peri))
182call print_msg('Length of a sol    [s]   = '//real2str(sol_len_s))
183call print_msg('Length of a year   [sol] = '//real2str(yr_len_sol))
184
185END SUBROUTINE init_orbit
186!=======================================================================
187
188!=======================================================================
189SUBROUTINE lsp2datep(lsp,datep)
190!-----------------------------------------------------------------------
191! NAME
192!     lsp2datep
193!
194! DESCRIPTION
195!     Initialize orbital data of the planet.
196!
197! AUTHORS & DATE
198!     JB Clement, 12/2025
199!
200! NOTES
201!     Taken from 'lsp2solp' in the Mars PCM.
202!-----------------------------------------------------------------------
203
204! DEPENDENCIES
205! ------------
206use maths, only: pi
207
208! DECLARATION
209! -----------
210implicit none
211
212! ARGUMENTS
213! ---------
214real(dp), intent(in)  :: lsp   ! Ls at perihelion [deg]
215real(dp), intent(out) :: datep ! Date at perihelion [sol]
216
217! LOCAL VARIABLES
218! ---------------
219real(dp) :: zx0 ! Eccentric anomaly at Ls = 0
220
221! CODE
222! ----
223! Compute orbit geometrical parameters
224zx0 = -2._dp*atan(tan(0.5_dp*lsp*pi/180._dp)*sqrt((1._dp - eccentricity)/(1._dp + eccentricity)))
225if (zx0 <= 0._dp) zx0 = zx0 + 2._dp*pi
226
227! Compute sol at perihelion
228datep = yr_len_sol*(1._dp - (zx0 - eccentricity*sin(zx0))/(2._dp*pi))
229
230END SUBROUTINE lsp2datep
231!=======================================================================
232
233!=======================================================================
234SUBROUTINE ini_orbit()
235!-----------------------------------------------------------------------
236! NAME
237!     ini_orbit
238!
239! DESCRIPTION
240!     Initialize the parameters of module 'orbit'.
241!
242! AUTHORS & DATE
243!     R. Vandemeulebrouck
244!     JB Clement, 2023-2025
245!
246! NOTES
247!
248!-----------------------------------------------------------------------
249
250! DEPENDENCIES
251! ------------
252use stoppage, only: stop_clean
253
254! DECLARATION
255! -----------
256implicit none
257
258! LOCAL VARIABLES
259! ---------------
260integer(di) :: n ! Number of lines in the file
261integer(di) :: ierr, funit
262logical(k4) :: here
263
264! CODE
265! ----
266inquire(file = orbitfile_name,exist = here)
267if (.not. here) call stop_clean(__FILE__,__LINE__,'cannot find required file "'//orbitfile_name//'"!',1)
268
269! Get the number of lines for Laskar's orbital file
270open(newunit = funit,file = orbitfile_name,status = 'old',action = 'read',iostat = ierr)
271if (ierr /= 0) call stop_clean(__FILE__,__LINE__,'error opening file "'//orbitfile_name//'"!',ierr)
272n = 0
273do
274    read(funit,*,iostat = ierr)
275    if (ierr /= 0) exit
276    n = n + 1
277end do
278close(funit)
279
280! Allocation of module arrays
281if (.not. allocated(year_lask)) allocate(year_lask(n))
282if (.not. allocated(obl_lask)) allocate(obl_lask(n))
283if (.not. allocated(ecc_lask)) allocate(ecc_lask(n))
284if (.not. allocated(lsp_lask)) allocate(lsp_lask(n))
285
286END SUBROUTINE ini_orbit
287!=======================================================================
288
289!=======================================================================
290SUBROUTINE end_orbit
291!-----------------------------------------------------------------------
292! NAME
293!     end_orbit
294!
295! DESCRIPTION
296!     Deallocate orbital data arrays.
297!
298! AUTHORS & DATE
299!     R. Vandemeulebrouck
300!     JB Clement, 2023-2025
301!
302! NOTES
303!
304!-----------------------------------------------------------------------
305
306! DECLARATION
307! -----------
308implicit none
309
310! CODE
311! ----
312if (allocated(year_lask)) deallocate(year_lask)
313if (allocated(obl_lask)) deallocate(obl_lask)
314if (allocated(ecc_lask)) deallocate(ecc_lask)
315if (allocated(lsp_lask)) deallocate(lsp_lask)
316
317END SUBROUTINE end_orbit
318!=======================================================================
319
320!=======================================================================
321SUBROUTINE read_orbitpm(n_yr_sim)
322!-----------------------------------------------------------------------
323! NAME
324!     read_orbitpm
325!
326! DESCRIPTION
327!     Read Laskar's orbital file and locate index for
328!     closest lower year relative to current simulation year.
329!
330! AUTHORS & DATE
331!     JB Clement, 2023-2025
332!
333! NOTES
334!
335!-----------------------------------------------------------------------
336
337! DEPENDENCIES
338! ------------
339use evolution, only: pem_ini_date, r_plnt2earth_yr
340use stoppage,  only: stop_clean
341use display,   only: print_msg
342use utility,   only: real2str, int2str
343
344! DECLARATION
345! -----------
346implicit none
347
348! ARGUMENTS
349! ---------
350real(dp), intent(in) :: n_yr_sim
351
352! LOCAL VARIABLES
353! ---------------
354integer(di) :: ierr, funit, i, n
355logical(k4) :: here
356real(dp)    :: current_year
357
358! CODE
359! ----
360call print_msg('> Reading "'//orbitfile_name//'"')
361! Compute the current year
362current_year = pem_ini_date + n_yr_sim
363call print_msg('Current year = '//real2str(current_year))
364
365inquire(file = orbitfile_name,exist = here)
366if (.not. here) call stop_clean(__FILE__,__LINE__,'cannot find required file "'//orbitfile_name//'"!',1)
367
368! Read the Laskars's orbital file
369open(newunit = funit,file = orbitfile_name,status = 'old',action = 'read',iostat = ierr)
370if (ierr /= 0) call stop_clean(__FILE__,__LINE__,'error opening file "'//orbitfile_name//'"!',ierr)
371n = size(year_lask,1) ! Number of lines in the file
372iyear_lask = 0 ! Line number for closest lower year relative to current simulation year
373do i = 1,n
374    read(funit,*) year_lask(i), obl_lask(i), ecc_lask(i), lsp_lask(i)
375    year_lask(i) = year_lask(i)*1000._dp/r_plnt2earth_yr ! Conversion from Laskar's kilo Earth years to planetary years
376    if (year_lask(i) > current_year) iyear_lask = i + 1
377end do
378close(funit)
379if (iyear_lask == 0 .or. iyear_lask == n + 1) then
380    call stop_clean(__FILE__,__LINE__,'the current year could not be found in the file "'//orbitfile_name//'".',1)
381else
382    call print_msg('The current year in "'//orbitfile_name//'" is at line '//int2str(iyear_lask)//'.')
383end if
384
385END SUBROUTINE read_orbitpm
386!=======================================================================
387
388!=======================================================================
389SUBROUTINE compute_maxyr_orbit(n_yr_sim,nmax_yr_runorb)
390!-----------------------------------------------------------------------
391! NAME
392!     compute_maxyr_orbit
393!
394! DESCRIPTION
395!     Determine maximum number of years before orbital params change
396!     beyond admissible thresholds.
397!
398! AUTHORS & DATE
399!     R. Vandemeulebrouck
400!     JB Clement, 2023-2025
401!
402! NOTES
403!     Handles Lsp modulo crossings.
404!-----------------------------------------------------------------------
405
406! DEPENDENCIES
407! ------------
408use evolution, only: pem_ini_date
409use display,   only: print_msg
410use utility,   only: real2str
411
412! DECLARATION
413! -----------
414implicit none
415
416! ARGUMENTS
417! ---------
418real(dp), intent(in)  :: n_yr_sim       ! Current year of the simulation
419real(dp), intent(out) :: nmax_yr_runorb ! Maximum number of years of the PEM before orbital parameters change too much
420
421! LOCAL VARIABLES
422! ---------------
423real(dp)                            :: current_year
424real(dp)                            :: max_obl, max_ecc, max_lsp
425real(dp)                            :: min_obl, min_ecc, min_lsp
426real(dp)                            :: nmax_yr_runobl, nmax_yr_runecc, nmax_yr_runlsp ! Maximum year iteration before reaching an inadmissible value of orbit param
427real(dp)                            :: xa, xb, ya, yb
428logical(k4)                         :: found_obl, found_ecc, found_lsp
429real(dp)                            :: lsp_corr ! Lsp corrected if the "modulo is crossed"
430real(dp)                            :: delta
431real(dp), dimension(:), allocatable :: lsplask_unwrap
432integer(di)                         :: i
433
434! CODE
435! ----
436if (.not. evol_orbit) then
437    nmax_yr_runorb = largest_nb ! Default huge value
438    return
439end if
440call print_msg('> Computing the accepted maximum number of years due to orbital parameters')
441current_year = pem_ini_date + n_yr_sim ! We compute the current year
442
443! Unwrap the Lsp changes in Laskar's file
444allocate(lsplask_unwrap(iyear_lask))
445lsplask_unwrap(iyear_lask) = lsp_lask(iyear_lask)
446do i = iyear_lask,2,-1
447    delta = lsp_lask(i - 1) - lsp_lask(i)
448    if (delta > 180._dp) then
449        lsp_corr = lsp_lask(i - 1) - 360._dp
450    else if (delta < -180._dp) then
451        lsp_corr = lsp_lask(i - 1) + 360._dp
452    else
453        lsp_corr = lsp_lask(i - 1)
454    end if
455    lsplask_unwrap(i - 1) = lsplask_unwrap(i) + lsp_corr - lsp_lask(i)
456end do
457
458! Correct the current Lsp according to the unwrapping
459delta = ls_peri - lsplask_unwrap(iyear_lask)
460if (delta > 180._dp) then
461    ls_peri = ls_peri - 360._dp
462else if (delta < -180._dp) then
463    ls_peri = ls_peri + 360._dp
464end if
465
466! Maximum change accepted for orbital parameters
467max_obl = obliquity + max_change_obl
468min_obl = obliquity - max_change_obl
469call print_msg('Obl. (current|accepted min|accepted max): '//real2str(obliquity)//' | '//real2str(min_obl)//real2str(max_obl))
470
471max_ecc = min(eccentricity + max_change_ecc,1. - minieps) ! ecc < 1.
472min_ecc = max(eccentricity - max_change_ecc,0._dp) ! ecc >= 0.
473call print_msg('Ecc. (current|accepted min|accepted max): '//real2str(eccentricity)//' | '//real2str(min_ecc)//' | '//real2str(max_ecc))
474
475max_lsp = ls_peri + max_change_lsp
476min_lsp = ls_peri - max_change_lsp
477call print_msg('Lsp  (current|accepted min|accepted max): '//real2str(ls_peri)//' | '//real2str(min_lsp)//' | '//real2str(max_lsp))
478
479! Initialization
480nmax_yr_runobl = largest_nb ! Default huge value
481nmax_yr_runecc = largest_nb ! Default huge value
482nmax_yr_runlsp =largest_nb ! Default huge value
483found_obl = .false.
484found_ecc = .false.
485found_lsp = .false.
486if (.not. evol_obl) found_obl = .true.
487if (.not. evol_ecc) found_ecc = .true.
488if (.not. evol_lsp) found_lsp = .true.
489
490! The maximum reachable year is found by interpolation according to the maximum admissible change of orbital parameters
491do i = iyear_lask,2,-1
492    xa = year_lask(i)
493    xb = year_lask(i - 1)
494
495    ! Obliquity
496    if (evol_obl .and. .not. found_obl) then
497        ya = obl_lask(i)
498        yb = obl_lask(i - 1)
499        if (yb < min_obl) then ! The minimum accepted is overtaken
500            nmax_yr_runobl = (min_obl - ya)*(xb - xa)/(yb - ya) + xa - current_year
501            found_obl = .true.
502        else if (max_obl < yb) then ! The maximum accepted is overtaken
503            nmax_yr_runobl = (max_obl - ya)*(xb - xa)/(yb - ya) + xa - current_year
504            found_obl = .true.
505        end if
506    end if
507
508    ! Eccentricity
509    if (evol_ecc .and. .not. found_ecc) then
510        ya = ecc_lask(i)
511        yb = ecc_lask(i - 1)
512        if (yb < min_ecc) then ! The minimum accepted is overtaken
513            nmax_yr_runecc = (min_ecc - ya)*(xb - xa)/(yb - ya) + xa - current_year
514            found_ecc = .true.
515        else if (max_ecc < yb) then ! The maximum accepted is overtaken
516            nmax_yr_runecc = (max_ecc - ya)*(xb - xa)/(yb - ya) + xa - current_year
517            found_ecc = .true.
518        end if
519    end if
520
521    ! Lsp
522    if (evol_lsp .and. .not. found_lsp) then
523        ya = lsplask_unwrap(i)
524        yb = lsplask_unwrap(i - 1)
525        if (yb < min_lsp) then ! The minimum accepted is overtaken
526            nmax_yr_runlsp = (min_lsp - ya)*(xb - xa)/(yb - ya) + xa - current_year
527            found_lsp = .true.
528        else if (max_lsp < yb) then ! The maximum accepted is overtaken
529            nmax_yr_runlsp = (max_lsp - ya)*(xb - xa)/(yb - ya) + xa - current_year
530            found_lsp = .true.
531        end if
532    end if
533
534    if (found_obl .and. found_ecc .and. found_lsp) exit ! The loop is left as soon as everything is found
535end do
536
537deallocate(lsplask_unwrap)
538
539if (.not. found_obl) call print_msg('The maximum reachable year for obl. could not be found in "'//orbitfile_name//'".')
540if (.not. found_ecc) call print_msg('The maximum reachable year for ecc. could not be found in "'//orbitfile_name//'".')
541if (.not. found_lsp) call print_msg('The maximum reachable year for Lsp could not be found in "'//orbitfile_name//'".')
542
543call print_msg('Number of years accepted for obl. = '//real2str(nmax_yr_runobl))
544call print_msg('Number of years accepted for ecc. = '//real2str(nmax_yr_runecc))
545call print_msg('Number of years accepted for Lsp  = '//real2str(nmax_yr_runlsp))
546
547nmax_yr_runorb = min(nmax_yr_runobl,nmax_yr_runecc,nmax_yr_runlsp)
548if (nmax_yr_runorb < 1._dp) nmax_yr_runorb = 1._dp ! nmax_yr_runorb should be at least equal to 1
549
550call print_msg('So the max. number of years for the orbital criterion = '//real2str(nmax_yr_runorb))
551
552END SUBROUTINE compute_maxyr_orbit
553!=======================================================================
554
555!=======================================================================
556SUBROUTINE update_orbit(n_yr_sim,n_yr_run)
557!-----------------------------------------------------------------------
558! NAME
559!     update_orbit
560!
561! DESCRIPTION
562!     Update orbital parameters from Laskar values at a new year.
563!
564! AUTHORS & DATE
565!     R. Vandemeulebrouck
566!     JB Clement, 2023-2025
567!
568! NOTES
569!
570!-----------------------------------------------------------------------
571
572use evolution,        only: pem_ini_date
573use call_dayperi_mod, only: call_dayperi
574use stoppage,         only: stop_clean
575use display,          only: print_msg
576use utility,          only: real2str
577
578! DECLARATION
579! -----------
580implicit none
581
582! ARGUMENTS
583! ---------
584real(dp), intent(in) :: n_yr_sim ! Number of simulated years
585real(dp), intent(in) :: n_yr_run ! Number of iterations of the PEM
586
587! LOCAL VARIABLES
588! ---------------
589integer(di) :: i
590real(dp)    :: current_year, old_year, obl_old, ecc_old, lsp_old
591real(dp)    :: xa, xb, ya, yb ! Variables for interpolation
592logical(k4) :: found_year
593
594! CODE
595! ----
596call print_msg('> Updating the orbital parameters for the new year')
597current_year = pem_ini_date + n_yr_sim ! We compute the current year
598old_year = current_year - n_yr_run
599obl_old = obliquity
600ecc_old = eccentricity
601lsp_old = ls_peri
602
603found_year = .false.
604if (current_year < 0._dp) then
605    do i = iyear_lask,2,-1
606        xa = year_lask(i)
607        xb = year_lask(i - 1)
608        if (xa <= current_year .and. current_year < xb) then
609            ! Obliquity
610            if (evol_obl) then
611                ya = obl_lask(i)
612                yb = obl_lask(i - 1)
613                obliquity = (current_year - xa)*(yb - ya)/(xb - xa) + ya
614            end if
615
616            ! Eccentricity
617            if (evol_ecc) then
618                ya = ecc_lask(i)
619                yb = ecc_lask(i - 1)
620                eccentricity = (current_year - xa)*(yb - ya)/(xb - xa) + ya
621            end if
622
623            ! Lsp
624            if (evol_lsp) then
625                ya = lsp_lask(i)
626                yb = lsp_lask(i - 1)
627                if (abs(yb - ya) > 300._dp) then ! If modulo is "crossed" through the interval
628                    if (ya < yb) then ! Lsp should be decreasing
629                        ya = ya + 360._dp
630                    else ! Lsp should be increasing
631                        yb = yb + 360._dp
632                    end if
633                end if
634                ls_peri = modulo((current_year - xa)*(yb - ya)/(xb - xa) + ya,360._dp)
635            end if
636            found_year = .true.
637            exit ! The loop is left as soon as the right interval is found
638        end if
639    end do
640else if (current_year >= 0._dp .and. current_year < 100._dp) then ! For present orbital characteristics
641    if (evol_obl) obliquity = obl_lask(1)
642    if (evol_ecc) eccentricity = ecc_lask(1)
643    if (evol_lsp) ls_peri = lsp_lask(1)
644    found_year = .true.
645end if
646
647if (.not. found_year) call stop_clean(__FILE__,__LINE__,'the new year could not be found in the file "'//orbitfile_name//'".',1)
648
649call lsp2datep(ls_peri,date_peri)
650perihelion = semimaj_axis*(1._dp - eccentricity)
651aphelion = semimaj_axis*(1._dp + eccentricity)
652
653call print_msg('Year (ini|now) = '//real2str(old_year)//' | '//real2str(current_year))
654call print_msg('Obl. (ini|now) = '//real2str(obl_old)//' | '//real2str(obliquity))
655call print_msg('Ecc. (ini|now) = '//real2str(ecc_old)//' | '//real2str(eccentricity))
656call print_msg('Lsp  (ini|now) = '//real2str(lsp_old)//' | '//real2str(ls_peri))
657
658END SUBROUTINE update_orbit
659!=======================================================================
660
661END MODULE orbit
Note: See TracBrowser for help on using the repository browser.