Changeset 3989 for trunk/LMDZ.COMMON/libf/evolution/orbit.F90
- Timestamp:
- Dec 11, 2025, 12:56:05 PM (5 weeks ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/evolution/orbit.F90
r3988 r3989 1 MODULE orbit _param_criterion_mod1 MODULE orbit 2 2 3 3 !======================================================================= … … 11 11 implicit none 12 12 13 real, dimension(:), allocatable :: year_lask ! year before present from Laskar et al. 14 real, dimension(:), allocatable :: obl_lask ! obliquity [deg] 15 real, dimension(:), allocatable :: ecc_lask ! eccentricity 16 real, dimension(:), allocatable :: lsp_lask ! ls perihelie [deg] 17 integer :: iyear_lask ! Index of the line in the file year_obl_lask.asc corresponding to the closest lower year to the current year 18 13 19 !======================================================================= 14 20 contains 15 21 !======================================================================= 16 22 17 SUBROUTINE orbit_param_criterion(i_myear,n_myear_leg) 23 SUBROUTINE read_orbitpm(Year) 24 25 use evolution, only: convert_years 26 27 implicit none 28 29 real, intent(in) :: Year ! Martian year of the simulation 30 31 integer :: n ! number of lines in Laskar files 32 integer :: ierr, i 33 34 n = 0 35 open(1,file = 'obl_ecc_lsp.asc',status = 'old',action = 'read') 36 do 37 read(1,*,iostat = ierr) 38 if (ierr /= 0) exit 39 n = n + 1 40 enddo 41 close(1) 42 allocate(year_lask(n),obl_lask(n),ecc_lask(n),lsp_lask(n)) 43 44 iyear_lask = 0 45 do i = 1,size(year_lask,1) 46 read(1,*) year_lask(i), obl_lask(i), ecc_lask(i), lsp_lask(i) 47 year_lask(i) = year_lask(i)*1000./convert_years ! Conversion from Laskar's kilo Earth years to PEM Martian years 48 if (year_lask(i) > Year) iyear_lask = i + 1 49 enddo 50 close(1) 51 if (iyear_lask == 0 .or. iyear_lask == size(year_lask,1) + 1) then 52 error stop 'The current year could not be found in the file "obl_ecc_lsp.asc".' 53 else 54 write(*,*) 'The current year in the "obl_ecc_lsp.asc" file is at line:', iyear_lask 55 endif 56 57 END SUBROUTINE read_orbitpm 58 59 !======================================================================= 60 61 SUBROUTINE end_orbit 62 63 implicit none 64 65 if (allocated(year_lask)) deallocate(year_lask) 66 if (allocated(obl_lask)) deallocate(obl_lask) 67 if (allocated(ecc_lask)) deallocate(ecc_lask) 68 if (allocated(lsp_lask)) deallocate(lsp_lask) 69 70 END SUBROUTINE end_orbit 71 !======================================================================= 72 73 SUBROUTINE orbit_param_criterion(i_myear,nyears_maxorb) 18 74 19 75 #ifdef CPP_IOIPSL … … 25 81 use planete_h, only: e_elips, obliquit, lsperi 26 82 use phys_constants, only: pi 27 use time_evol_mod, only: year_bp_ini, var_obl, var_ecc, var_lsp, convert_years 28 use lask_param_mod, only: yearlask, obllask, ecclask, lsplask, ini_lask_param_mod, last_ilask 83 use evolution, only: year_bp_ini, var_obl, var_ecc, var_lsp, convert_years 29 84 30 85 implicit none … … 38 93 ! Output Variables 39 94 !-------------------------------------------------------- 40 real, intent(out) :: n _myear_leg! Maximum number of iteration of the PEM before orb changes too much95 real, intent(out) :: nyears_maxorb ! Maximum number of iteration of the PEM before orb changes too much 41 96 42 97 !-------------------------------------------------------- … … 48 103 real :: max_obl, max_ecc, max_lsp ! Maximum value of orbit param given the admissible change 49 104 real :: min_obl, min_ecc, min_lsp ! Minimum value of orbit param given the admissible change 50 real :: max_obl_iter, max_ecc_iter, max_lsp_iter! Maximum year iteration before reaching an inadmissible value of orbit param51 integer :: i lask! Loop variable105 real :: nyears_maxobl, nyears_maxecc, nyears_maxlsp ! Maximum year iteration before reaching an inadmissible value of orbit param 106 integer :: i ! Loop variable 52 107 real :: xa, xb, ya, yb ! Variables for interpolation 53 108 logical :: found_obl, found_ecc, found_lsp ! Flag variables for orbital parameters … … 62 117 Lsp = lsperi*180./pi ! We convert in degree 63 118 64 call ini_lask_param_mod() ! Allocation of variables119 call read_orbitpm(Year) ! Allocation of variables 65 120 66 121 write(*,*) 'orbit_param_criterion, Current year =', Year … … 69 124 write(*,*) 'orbit_param_criterion, Current Lsp =', Lsp 70 125 71 ! We read the file 72 open(73,file = 'obl_ecc_lsp.asc',status = 'old',action = 'read') 73 last_ilask = 0 74 do ilask = 1,size(yearlask,1) 75 read(73,*) yearlask(ilask), obllask(ilask), ecclask(ilask), lsplask(ilask) 76 yearlask(ilask) = yearlask(ilask)*1000./convert_years ! Conversion from Laskar's kilo Earth years to PEM Martian years 77 if (yearlask(ilask) > Year) last_ilask = ilask + 1 126 ! Unwrap the Lsp changes in Laskar's file 127 allocate(lsplask_unwrap(iyear_lask)) 128 lsplask_unwrap(iyear_lask) = lsp_lask(iyear_lask) 129 do i = iyear_lask,2,-1 130 delta = lsp_lask(i - 1) - lsp_lask(i) 131 if (delta > 180.) then 132 lsp_corr = lsp_lask(i - 1) - 360. 133 else if (delta < -180.) then 134 lsp_corr = lsp_lask(i - 1) + 360. 135 else 136 lsp_corr = lsp_lask(i - 1) 137 endif 138 lsplask_unwrap(i - 1) = lsplask_unwrap(i) + lsp_corr - lsp_lask(i) 78 139 enddo 79 close(73)80 if (last_ilask == 0 .or. last_ilask == size(yearlask,1) + 1) then81 error stop 'The current year could not be found in the file "obl_ecc_lsp.asc".'82 else83 write(*,*) 'The current year in the "obl_ecc_lsp.asc" file is at line:', last_ilask84 endif85 86 ! Unwrap the Lsp changes in Laskar's file87 allocate(lsplask_unwrap(last_ilask))88 lsplask_unwrap(last_ilask) = lsplask(last_ilask)89 do ilask = last_ilask,2,-190 delta = lsplask(ilask - 1) - lsplask(ilask)91 if (delta > 180.) then92 lsp_corr = lsplask(ilask - 1) - 360.93 else if (delta < -180.) then94 lsp_corr = lsplask(ilask - 1) + 360.95 else96 lsp_corr = lsplask(ilask - 1)97 endif98 lsplask_unwrap(ilask - 1) = lsplask_unwrap(ilask) + lsp_corr - lsplask(ilask)99 enddo100 140 101 141 ! Correct the current Lsp according to the unwrapping 102 delta = Lsp - lsplask_unwrap( last_ilask)142 delta = Lsp - lsplask_unwrap(iyear_lask) 103 143 if (delta > 180.) then 104 144 Lsp = Lsp - 360. … … 133 173 ! If we do not want some orb parameter to change, they should not be a stopping criterion, 134 174 ! So the number of iteration corresponding is set to maximum 135 max_obl_iter= 1000000.136 max_ecc_iter= 1000000.137 max_lsp_iter= 1000000.175 nyears_maxobl = 1000000. 176 nyears_maxecc = 1000000. 177 nyears_maxlsp = 1000000. 138 178 139 179 ! The maximum reachable year is found by interpolation according to the maximum admissible change of orbital parameters … … 145 185 if (.not. var_lsp) found_lsp = .true. 146 186 147 do i lask = last_ilask,2,-1148 xa = year lask(ilask)149 xb = year lask(ilask- 1)187 do i = iyear_lask,2,-1 188 xa = year_lask(i) 189 xb = year_lask(i - 1) 150 190 151 191 ! Obliquity 152 192 if (var_obl .and. .not. found_obl) then 153 ya = obl lask(ilask)154 yb = obl lask(ilask- 1)193 ya = obl_lask(i) 194 yb = obl_lask(i - 1) 155 195 if (yb < min_obl) then ! The minimum accepted is overtaken 156 max_obl_iter= (min_obl - ya)*(xb - xa)/(yb - ya) + xa - Year196 nyears_maxobl = (min_obl - ya)*(xb - xa)/(yb - ya) + xa - Year 157 197 found_obl = .true. 158 198 else if (max_obl < yb) then ! The maximum accepted is overtaken 159 max_obl_iter= (max_obl - ya)*(xb - xa)/(yb - ya) + xa - Year199 nyears_maxobl = (max_obl - ya)*(xb - xa)/(yb - ya) + xa - Year 160 200 found_obl = .true. 161 201 endif … … 164 204 ! Eccentricity 165 205 if (var_ecc .and. .not. found_ecc) then 166 ya = ecc lask(ilask)167 yb = ecc lask(ilask- 1)206 ya = ecc_lask(i) 207 yb = ecc_lask(i - 1) 168 208 if (yb < min_ecc) then ! The minimum accepted is overtaken 169 max_ecc_iter= (min_ecc - ya)*(xb - xa)/(yb - ya) + xa - Year209 nyears_maxecc = (min_ecc - ya)*(xb - xa)/(yb - ya) + xa - Year 170 210 found_ecc = .true. 171 211 else if (max_ecc < yb) then ! The maximum accepted is overtaken 172 max_ecc_iter= (max_ecc - ya)*(xb - xa)/(yb - ya) + xa - Year212 nyears_maxecc = (max_ecc - ya)*(xb - xa)/(yb - ya) + xa - Year 173 213 found_ecc = .true. 174 214 endif … … 177 217 ! Lsp 178 218 if (var_lsp .and. .not. found_lsp) then 179 ya = lsplask_unwrap(i lask)180 yb = lsplask_unwrap(i lask- 1)219 ya = lsplask_unwrap(i) 220 yb = lsplask_unwrap(i - 1) 181 221 if (yb < min_lsp) then ! The minimum accepted is overtaken 182 max_lsp_iter= (min_lsp - ya)*(xb - xa)/(yb - ya) + xa - Year222 nyears_maxlsp = (min_lsp - ya)*(xb - xa)/(yb - ya) + xa - Year 183 223 found_lsp = .true. 184 224 else if (max_lsp < yb) then ! The maximum accepted is overtaken 185 max_lsp_iter= (max_lsp - ya)*(xb - xa)/(yb - ya) + xa - Year225 nyears_maxlsp = (max_lsp - ya)*(xb - xa)/(yb - ya) + xa - Year 186 226 found_lsp = .true. 187 227 endif … … 197 237 if (.not. found_lsp) write(*,*) 'The maximum reachable year for Lsp could not be found in the file "obl_ecc_lsp.asc".' 198 238 199 write(*,*) 'Max. number of iterations for the obl. parameter =', max_obl_iter200 write(*,*) 'Max. number of iterations for the ecc. parameter =', max_ecc_iter201 write(*,*) 'Max. number of iterations for the Lsp parameter =', max_lsp_iter202 203 n _myear_leg = min(max_obl_iter,max_ecc_iter,max_lsp_iter)204 if (n _myear_leg < 1.) n_myear_leg = 1. ! n_myear_legshould be at least equal to 1205 write(*,*) 'So the max. number of iterations for the orbital criteria =', n_myear_leg239 write(*,*) 'Max. number of years for the obl. parameter =', nyears_maxobl 240 write(*,*) 'Max. number of years for the ecc. parameter =', nyears_maxecc 241 write(*,*) 'Max. number of years for the Lsp parameter =', nyears_maxlsp 242 243 nyears_maxorb = min(nyears_maxobl,nyears_maxecc,nyears_maxlsp) 244 if (nyears_maxorb < 1.) nyears_maxorb = 1. ! nyears_maxorb should be at least equal to 1 245 write(*,*) 'So the max. number of years for the orbital criteria =', nyears_maxorb 206 246 207 247 END SUBROUTINE orbit_param_criterion 208 248 209 249 !*********************************************************************** 210 211 END MODULE orbit_param_criterion_mod 212 250 ! Purpose: Recompute orbit parameters based on values by Laskar et al. 251 SUBROUTINE set_new_orbitpm(i_myear,i_myear_leg) 252 253 use evolution, only: year_bp_ini, var_obl, var_ecc, var_lsp 254 use phys_constants, only: pi 255 use planete_h, only: e_elips, obliquit, lsperi, periheli, aphelie, p_elips, peri_day, year_day 256 use call_dayperi_mod, only: call_dayperi 257 258 implicit none 259 260 !-------------------------------------------------------- 261 ! Input Variables 262 !-------------------------------------------------------- 263 real, intent(in) :: i_myear ! Number of simulated Martian years 264 real, intent(in) :: i_myear_leg ! Number of iterations of the PEM 265 266 !-------------------------------------------------------- 267 ! Output Variables 268 !-------------------------------------------------------- 269 270 !-------------------------------------------------------- 271 ! Local variables 272 !-------------------------------------------------------- 273 real :: Year ! Year of the simulation 274 real :: Lsp ! Ls perihelion 275 integer :: i ! Loop variable 276 real :: halfaxe ! Million of km 277 real :: unitastr 278 real :: xa, xb, ya, yb ! Variables for interpolation 279 logical :: found_year ! Flag variable 280 281 ! ********************************************************************** 282 ! 0. Initializations 283 ! ********************************************************************** 284 Year = year_bp_ini + i_myear ! We compute the current year 285 Lsp = lsperi*180./pi ! We convert in degree 286 287 write(*,*) 'set_new_orbitpm, Old year =', Year - i_myear_leg 288 write(*,*) 'set_new_orbitpm, Old obl. =', obliquit 289 write(*,*) 'set_new_orbitpm, Old ecc. =', e_elips 290 write(*,*) 'set_new_orbitpm, Old Lsp =', Lsp 291 write(*,*) 'set_new_orbitpm, New year =', Year 292 293 found_year = .false. 294 if (Year < 0.) then 295 do i = iyear_lask,2,-1 296 xa = year_lask(i) 297 xb = year_lask(i - 1) 298 if (xa <= Year .and. Year < xb) then 299 ! Obliquity 300 if (var_obl) then 301 ya = obl_lask(i) 302 yb = obl_lask(i - 1) 303 obliquit = (Year - xa)*(yb - ya)/(xb - xa) + ya 304 endif 305 306 ! Eccentricity 307 if (var_ecc) then 308 ya = ecc_lask(i) 309 yb = ecc_lask(i - 1) 310 e_elips = (Year - xa)*(yb - ya)/(xb - xa) + ya 311 endif 312 313 ! Lsp 314 if (var_lsp) then 315 ya = lsp_lask(i) 316 yb = lsp_lask(i - 1) 317 if (abs(yb - ya) > 300.) then ! If modulo is "crossed" through the interval 318 if (ya < yb) then ! Lsp should be decreasing 319 ya = ya + 360. 320 else ! Lsp should be increasing 321 yb = yb + 360. 322 endif 323 endif 324 Lsp = modulo((Year - xa)*(yb - ya)/(xb - xa) + ya,360.) 325 endif 326 found_year = .true. 327 exit ! The loop is left as soon as the right interval is found 328 endif 329 enddo 330 else if (Year >= 0 .and. Year < 100.) then ! For present orbital characteristics 331 if (var_obl) obliquit = 25.19 332 if (var_ecc) e_elips = 0.0934 333 if (var_lsp) Lsp = 251. 334 found_year = .true. 335 endif 336 337 if (.not. found_year) error stop 'The new year could not be found in the file "obl_ecc_lsp.asc".' 338 339 write(*,*) 'set_new_orbitpm, New obl. =', obliquit 340 write(*,*) 'set_new_orbitpm, New ecc. =', e_elips 341 write(*,*) 'set_new_orbitpm, New Lsp =', Lsp 342 343 halfaxe = 227.94 344 Lsp = Lsp*pi/180. 345 periheli = halfaxe*(1 - e_elips) 346 aphelie = halfaxe*(1 + e_elips) 347 unitastr = 149.597927 348 p_elips = 0.5*(periheli + aphelie)*(1. - e_elips*e_elips)/unitastr 349 350 call call_dayperi(Lsp,e_elips,peri_day,year_day) 351 352 call end_orbit() 353 354 END SUBROUTINE set_new_orbitpm 355 356 END MODULE orbit 357
Note: See TracChangeset
for help on using the changeset viewer.
