General Purpose Geodetic Library
SgOceanLoad.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 
24 #include <math.h>
25 
26 
27 #include <SgLogger.h>
28 #include <SgOceanLoad.h>
29 #include <SgTaskConfig.h>
30 #include <SgVlbiStationInfo.h>
31 
32 
33 /*=======================================================================================================
34 *
35 * METHODS:
36 *
37 *======================================================================================================*/
38 //
39 // static first:
40 const QString SgOceanLoad::className()
41 {
42  return "SgOceanLoad";
43 };
44 
45 
46 
47 //
49 {
50  cfg_ = cfg;
51  for (int i=0; i<11; i++)
52  angle[i] = 0.0;
53 };
54 
55 
56 
57 // A destructor:
59 {
60 };
61 
62 
63 
64 //
65 void SgOceanLoad::calcArgs(const SgMJD& time)
66 {
67  //
68  // Ernst W. Schwiderski, U.S. Naval Surface Weapons Center
69  // "Atlas of Ocean Tidal Charts and Maps, Part I: The Semidiurnal Principal Lunar Tide M2"
70  // Marine Geodesy, Volume 6, Number 3-4
71  // page 226:
72  int nD; // D = day number of year Y(D = I for January 1)
73  double t; // t = universal standard time of day D (in sec)
74  double h0; // mean longitude of the sun relative to Greenwich
75  // midnight of day D (in deg)
76  double s0; // mean longitude of the moon relative to Greenwich
77  // midnight of day D (in deg)
78  double p0; // lunar perigee, from page 254
79  double dT, dT2, dT3;
80 
81  nD = time.calcDayOfYear();
82  dT = (27392.500528 + 1.0000000356*nD)/36525.0;
83  dT2 = dT*dT;
84  dT3 = dT2*dT;
85  t = time.getTime()*86400.0;
86 
87  h0 = 279.69668 + 36000.768930485*dT2 + 3.03e-4*dT3; // the second term is corrected according to
88  // the recent IERS Conventions
89 //h0 = 279.69668 + 36000.768925485*dT2 + 3.03e-4*dT3;
90  //
91  s0 = 270.434358 + 481267.88314137*dT - 0.001133*dT2 + 1.9e-6*dT3;
92  //
93  p0 = 334.329653 + 4069.0340329577*dT - 0.010325*dT2 - 1.2e-5*dT3; // the second term is corrected
94  // according to the recent IERS
95  // Conventions
96 //p0 = 334.329653 + 4069.0340329575*dT - 0.010325*dT2 - 1.2e-5*dT3;
97  //
98  // convert to radians:
99  h0 *= DEG2RAD;
100  s0 *= DEG2RAD;
101  p0 *= DEG2RAD;
102  //
103  for (int k=0; k<11; k++)
104  {
105  angle[k] = freq[k]*t +
106  argNumbers[0][k]*h0 + argNumbers[1][k]*s0 + argNumbers[2][k]*p0 + argNumbers[3][k]*2.0*M_PI;
107  angle[k] = fmod(angle[k], 2.0*M_PI);
108  if (angle[k]<0.0)
109  angle[k] = angle[k] + 2.0*M_PI;
110  };
111 };
112 
113 
114 
115 //
117 {
118  clear();
119  if (!stnInfo)
120  {
122  ": calcDisplacement(): stnInfo is NULL");
123  return *this;
124  };
125 
126  /*
127  IERS Technical Note 21,
128  IERS Conventions (1996)
129  page 53 says:
130  " A shorter form of (2) is obtained if the summation considers only the tidal
131  species of Table 7.1 and corrections for the modulating effect of the lunar node.
132  Then,
133 
134  \Delta c = \Sum ( f_j*A_cj*cos(omega_j*t + hi_j + u_j - Phi_cj) ), (4)
135 
136  where f_j and u_j depend on longitude of lunar node according to Table 26 of
137  Doodson (1928)."
138  */
139  double fS1N, fC1N, fS2N, fC2N, fS3N, fC3N;
140  double f[11], u[11], fTmp=0.0;
141  double dt = (t - tEphem)/36525.0;
142  double dt2 = dt*dt;
143  double dt3 = dt2*dt;
144  double dt4 = dt2*dt2;
145  fTmp = 125.04455501*3600.0 - 6962890.5431*dt + 7.4722*dt2 + 0.007702*dt3 - 0.00005939*dt4;
146  fTmp = fmod(fTmp*SEC2RAD, 2.0*M_PI);
147 
148  for (int i=0; i<11; i++)
149  {
150  f[i] = 1.0;
151  u[i] = 0.0;
152  };
153 
154  sincos ( fTmp, &fS1N, &fC1N);
155  sincos (2.0*fTmp, &fS2N, &fC2N);
156  sincos (3.0*fTmp, &fS3N, &fC3N);
157 
158  f[ 0] = 1.0004 - 0.0373*fC1N + 0.0002*fC2N ;
159  f[ 3] = 1.0241 + 0.2863*fC1N + 0.0083*fC2N - 0.0015*fC3N;
160  f[ 4] = 1.0060 + 0.1150*fC1N - 0.0088*fC2N + 0.0006*fC3N;
161  f[ 5] = 1.0089 + 0.1871*fC1N - 0.0147*fC2N + 0.0014*fC3N;
162  f[ 8] = 1.0429 + 0.4135*fC1N - 0.0040*fC2N ;
163  f[ 9] = 1.0000 - 0.1300*fC1N + 0.0013*fC2N ;
164 
165  u[ 0] = ( - 2.14 *fS1N )*DEG2RAD;
166  u[ 3] = ( -17.74 *fS1N + 0.68 *fS2N - 0.04 *fS3N)*DEG2RAD;
167  u[ 4] = ( - 8.86 *fS1N + 0.68 *fS2N - 0.07 *fS3N)*DEG2RAD;
168  u[ 5] = ( 10.80 *fS1N - 1.34 *fS2N + 0.19 *fS3N)*DEG2RAD;
169  u[ 8] = ( -23.74 *fS1N + 2.68 *fS2N - 0.38 *fS3N)*DEG2RAD;
170 
171  /*
172  "The astronomical arguments needed in (4) can be computed with subroutune ARG below."
173  */
174  calcArgs(t);
175 
176  // summation:
177  for (int i=0; i<3; i++)
178  for (int j=0; j<11; j++)
179  vec[i] += f[j]*stnInfo->getOLoadAmplitude(j,i)*cos(angle[j] + u[j] - stnInfo->getOLoadPhase(j,i));
180 
181  //make it in VEN:
182  vec[1] *= -1.0;
183  vec[2] *= -1.0;
184  return *this;
185 };
186 
187 
188 
189 /*=======================================================================================================
190 *
191 * FRIENDS:
192 *
193 *======================================================================================================*/
194 //
195 
196 
197 
198 /*=====================================================================================================*/
199 //
200 // aux functions:
201 //
202 
203 
204 // i/o:
205 
206 
207 /*=====================================================================================================*/
208 //
209 // constants:
210 //
211 /*=====================================================================================================*/
212 const double SgOceanLoad::freq[11]= // frequencies of the tides, rad per sec:
213 {
214  1.40519e-4, 1.45444e-4, 1.37880e-4, 1.45842e-4, 0.72921e-4,
215  0.67598e-4, 0.72523e-4, 0.64959e-4, 0.53234e-5, 0.26392e-5, 0.03982e-5
216 };
217 
218 
219 const double SgOceanLoad::argNumbers[4][11]=
220 {
221  { 2.0, 0.0, 2.0, 2.0, 1.0 , 1.0 ,-1.0 , 1.0 , 0.0, 0.0, 2.0},
222  { -2.0, 0.0,-3.0, 0.0, 0.0 ,-2.0 , 0.0 ,-3.0 , 2.0, 1.0, 0.0},
223  { 0.0, 0.0, 1.0, 0.0, 0.0 , 0.0 , 0.0 , 1.0 , 0.0,-1.0, 0.0},
224  { 0.0, 0.0, 0.0, 0.0, 0.25,-0.25,-0.25,-0.25, 0.0, 0.0, 0.0}
225 };
226 
227 const SgMJD SgOceanLoad::_1975(1975, 1, 0);
228 
229 
230 
231 
232 
233 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tEphem(51544.5)
#define SEC2RAD
radians to arc seconds:
Definition: SgMathSupport.h:61
#define DEG2RAD
degrees to seconds:
Definition: SgMathSupport.h:49
double vec[3]
An array of 3 elements, stores elements of a vector.
Definition: Sg3dVector.h:51
void clear()
Definition: Sg3dVector.h:120
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ DISPLACEMENT
Definition: SgLogger.h:86
Definition: SgMJD.h:59
double getTime() const
Definition: SgMJD.h:455
int calcDayOfYear() const
Definition: SgMJD.cpp:238
const SgTaskConfig * cfg_
Definition: SgOceanLoad.h:91
static const SgMJD _1975
Definition: SgOceanLoad.h:87
static const double argNumbers[4][11]
Definition: SgOceanLoad.h:86
double angle[11]
Definition: SgOceanLoad.h:88
void calcArgs(const SgMJD &)
Definition: SgOceanLoad.cpp:65
static const QString className()
Definition: SgOceanLoad.cpp:40
const Sg3dVector & calcDisplacement(const SgVlbiStationInfo *, const SgMJD &)
static const double freq[11]
Definition: SgOceanLoad.h:85
SgOceanLoad(const SgTaskConfig *)
Definition: SgOceanLoad.cpp:48
double getOLoadPhase(int iWave, int iCoord) const
double getOLoadAmplitude(int iWave, int iCoord) const