source: dynamico_lmdz/simple_physics/phyparam/physics/astronomy.F90

Last change on this file was 4233, checked in by dubos, 5 years ago

simple_physics : enforce F2003 strictly

File size: 5.1 KB
Line 
1MODULE astronomy
2
3#include "use_logging.h"
4
5  IMPLICIT NONE
6  SAVE
7
8  REAL :: aphelie, periheli, year_day, peri_day, obliquit, &
9       timeperi, e_elips,p_elips
10  REAL, PARAMETER :: unitastr=149.597927, & ! millions of km
11       pi=2.*ASIN(1.)
12
13CONTAINS
14
15  SUBROUTINE solarlong(pday,psollong)
16    REAL, INTENT(IN) :: pday               ! jour de l annee (le jour 0 correspondant a l equinoxe)
17    REAL, INTENT(OUT) :: psollong          ! solar longitude
18    LOGICAL, PARAMETER ::  lwrite=.TRUE.
19
20    ! Local:
21    ! ------
22    REAL zanom,xref,zx0,zdx,zteta,zz
23    INTEGER iter
24
25    !--------------------------------------------------------
26    ! calcul de l angle polaire et de la distance au soleil :
27    ! -------------------------------------------------------
28
29    !  calcul de l zanomalie moyenne
30
31    zz=(pday-peri_day)/year_day
32    zanom=2.*pi*(zz-nint(zz))
33    xref=abs(zanom)
34
35    !  resolution de l equation horaire  zx0 - e * sin (zx0) = xref
36    !  methode de Newton
37
38    zx0=xref+e_elips*sin(xref)
39    DO iter=1,10
40       zdx=-(zx0-e_elips*sin(zx0)-xref)/(1.-e_elips*cos(zx0))
41       zx0=zx0+zdx
42    END DO
43    zx0=zx0+zdx
44    if(zanom.lt.0.) zx0=-zx0
45
46    ! zteta est la longitude solaire
47
48    zteta=2.*atan(sqrt((1.+e_elips)/(1.-e_elips))*tan(zx0/2.))
49
50    psollong=zteta-timeperi
51
52    IF(psollong.LT.0.) psollong=psollong+2.*pi
53    IF(psollong.GT.2.*pi) psollong=psollong-2.*pi
54    !-----------------------------------------------------------------------
55    !   sorties eventuelles:
56    !   ---------------------
57
58    IF (lwrite) THEN
59       WRITELOG(*,*) 'day of the year  :',pday
60       WRITELOG(*,*) 'solar longitude : ',psollong
61       LOG_DBG('solarlong')
62    ENDIF
63
64  END SUBROUTINE solarlong
65
66  SUBROUTINE iniorbit
67    !=======================================================================
68    !
69    !   Auteur:
70    !   -------
71    !     Frederic Hourdin      22 Fevrier 1991
72    !
73    !   Objet:
74    !   ------
75    !    Initialisation du sous programme orbite qui calcule
76    !    a une date donnee de l annee de duree year_day commencant
77    !    a l equinoxe de printemps et dont le perihelie se situe
78    !    a la date peri_day, la distance au soleil et la declinaison.
79    !
80    !   Interface:
81    !   ----------
82    !   - initialise certaines variables de ce module
83    !   - Doit etre appele avant d utiliser orbite.
84    !
85    !   Arguments:
86    !   ----------
87    !
88    !   Input:
89    !   ------
90    !   aphelie       \   aphelie et perihelie de l orbite
91    !   periheli      /   en millions de kilometres.
92    !
93    !=======================================================================
94
95    !-----------------------------------------------------------------------
96
97    !   Local:
98    !   ------
99    REAL zxref,zanom,zz,zx0,zdx
100    INTEGER iter
101
102    !-----------------------------------------------------------------------
103
104    WRITELOG(*,*) 'Perihelie en Mkm  ',periheli
105    WRITELOG(*,*) 'Aphelise  en Mkm  ',aphelie
106    WRITELOG(*,*) 'obliquite en degres  :',obliquit
107
108    e_elips=(aphelie-periheli)/(periheli+aphelie)
109    p_elips=0.5*(periheli+aphelie)*(1-e_elips*e_elips)/unitastr
110
111    WRITELOG(*,*) 'e_elips',e_elips
112    WRITELOG(*,*) 'p_elips',p_elips
113
114    !-----------------------------------------------------------------------
115    ! calcul de l angle polaire et de la distance au soleil :
116    ! -------------------------------------------------------
117
118    !  calcul de l zanomalie moyenne
119
120    zz=(year_day-peri_day)/year_day
121    zanom=2.*pi*(zz-nint(zz))
122    zxref=abs(zanom)
123    WRITELOG(*,*) 'zanom  ',zanom
124
125    !  resolution de l equation horaire  zx0 - e * sin (zx0) = zxref
126    !  methode de Newton
127
128    zx0=zxref+e_elips*sin(zxref)
129    DO  iter=1,100
130       zdx=-(zx0-e_elips*sin(zx0)-zxref)/(1.-e_elips*cos(zx0))
131       zx0=zx0+zdx
132    END DO
133
134    zx0=zx0+zdx
135    if(zanom.lt.0.) zx0=-zx0
136    WRITELOG(*,*) 'zx0   ',zx0
137
138    ! zteta est la longitude solaire
139
140    timeperi=2.*atan(sqrt((1.+e_elips)/(1.-e_elips))*tan(zx0/2.))
141    WRITELOG(*,*) 'longitude solaire du perihelie timeperi = ',timeperi
142
143    LOG_INFO('iniorbit')
144
145  END SUBROUTINE iniorbit
146
147  PURE SUBROUTINE orbite(pls,pdist_sol,pdecli)
148    !=======================================================================
149    !
150    !   Objet:
151    !   ------
152    !
153    !   Distance from sun and declimation as a function of the solar
154    !   longitude Ls
155    !
156    !   Arguments:
157    !   ----------
158    !
159    !   Input:
160    !   ------
161    !   pls          Ls
162    !
163    !   Output:
164    !   -------
165    !   pdist_sol     Distance Sun-Planet in UA
166    !   pdecli        declinaison ( en radians )
167    !
168    !=======================================================================
169    !-----------------------------------------------------------------------
170    !   Declarations:
171    !   -------------
172
173    ! arguments:
174    ! ----------
175
176    REAL, INTENT(IN) :: pls
177    REAL, INTENT(OUT) :: pdist_sol,pdecli
178
179    !-----------------------------------------------------------------------
180
181    ! Distance Sun-Planet
182
183    pdist_sol=p_elips/(1.+e_elips*cos(pls+timeperi))
184
185    ! Solar declination
186
187    pdecli= asin (sin(pls)*sin(obliquit*pi/180.))
188
189  END SUBROUTINE orbite
190
191END MODULE astronomy
Note: See TracBrowser for help on using the repository browser.