Подтвердить что ты не робот

Как предсказать приливы, используя гармонические константы

Я пытаюсь понять, как создать таблицу прогнозирования приливов, используя гармонические константы.

Я использовал гармонические константы из Bridgeport (http://tidesandcurrents.noaa.gov/data_menu.shtml?stn=8467150%20Bridgeport,%20CT&type=Harmonic%20Constituents)

И суммировал приливные компоненты, используя этот питон script -

import math
import time

tidalepoch = 0
epoch = time.mktime(time.gmtime()) - tidalepoch
f = open('bridgeport.txt', 'r')
M_PI = 3.14159
lines = f.readlines()
t = epoch - 24 * 3600
i = -24
while t < epoch:
  height = 0
  for line in lines:
    x = line.split()
    A = float(x[2]) # amplitude
    B = float(x[3]) # phase
    B *=  M_PI / 180.0
    C = float(x[4]) # speed
    C *= M_PI / 648000

    # h = R cost (wt - phi)
    height += A * math.cos(C * t - B)

  print str(i) + " " + str(height + 3.61999)
  i += 1
  t += 3600

Это печатает одну высоту в час для 'today'. Полученные высоты находятся примерно в диапазоне, который я ожидал бы, от -0,5 до 7,5 футов, но не подходят для даты.

Я на правильном пути? Как определить приливную эпоху? В примере Doodsen по википедии (http://en.wikipedia.org/wiki/Arthur_Thomas_Doodson) они использовали 0, чтобы получить результат на 1 сентября 1991 года. Но они имеют разные гармонические значения, чем текущие, и эта дата, похоже, не работает для меня.

Вот содержимое моего файла bridgeport.txt -

1 M2                       3.251 109.6  28.9841042 
2 S2                       0.515 135.9  30.0000000 
3 N2                       0.656  87.6  28.4397295 
4 K1                       0.318 191.6  15.0410686 
5 M4                       0.039 127.4  57.9682084 
6 O1                       0.210 219.5  13.9430356 
7 M6                       0.044 353.9  86.9523127 
8 MK3                      0.023 198.8  44.0251729 
9 S4                       0.000   0.0  60.0000000 
10 MN4                      0.024  97.2  57.4238337 
11 NU2                      0.148  89.8  28.5125831 
12 S6                       0.000   0.0  90.0000000 
13 MU2                      0.000   0.0  27.9682084 
14 2N2                      0.077  65.6  27.8953548 
15 OO1                      0.017 228.7  16.1391017 
16 LAM2                     0.068 131.1  29.4556253 
17 S1                       0.031 175.5  15.0000000 
18 M1                       0.024 264.4  14.4966939 
19 J1                       0.021 237.0  15.5854433 
20 MM                       0.000   0.0   0.5443747 
21 SSA                      0.072  61.2   0.0821373 
22 SA                       0.207 132.0   0.0410686 
23 MSF                      0.000   0.0   1.0158958 
24 MF                       0.000   0.0   1.0980331 
25 RHO                      0.015 258.1  13.4715145 
26 Q1                       0.059 205.7  13.3986609 
27 T2                       0.054 106.4  29.9589333 
28 R2                       0.004 136.9  30.0410667 
29 2Q1                      0.014 238.8  12.8542862 
30 P1                       0.098 204.1  14.9589314 
31 2SM2                     0.000   0.0  31.0158958 
32 M3                       0.012 200.1  43.4761563 
33 L2                       0.162 134.1  29.5284789 
34 2MK3                     0.015 203.7  42.9271398 
35 K2                       0.150 134.7  30.0821373 
36 M8                       0.000   0.0 115.9364166 
37 MS4                      0.000   0.0  58.9841042
4b9b3361

Ответ 1

Если вы используете C, один подход будет заключаться в использовании libTCD http://www.flaterco.com/xtide/libtcd.html для хранения составных данных, что обеспечивает хорошую основу для доступ к данным.

Для выполнения вычислений вам нужно настроить эпоху как начало текущего года. Этот код использует функции libTCD и основан на алгоритмах, используемых в xTide.

TIDE_RECORD record;
int readStatus = read_tide_record(self.stationID, &record);
int epochStartSeconds = staringSecondForYear(year);

for (unsigned constituentNumber=0; constituentNumber<constituentCount; constituentNumber++) {
    float constituentAmplitude = record.amplitude[constituentNumber];
    float nodeFactor = get_node_factor(constituentNumber, year);
    amplitudes[constituentNumber] =  constituentAmplitude * nodeFactor;

    float constituentEpoch =  deg2rad(-record.epoch[constituentNumber]);
    float equilibrium = deg2rad(get_equilibrium(constituentNumber, year));
    phases[constituentNumber] = constituentEpoch + equilibrium;
}

Затем вычислить прилив для смещения с начала года:

- (float)getHeightForTimeSince1970:(long)date {
  //calculate the time to use for this calculation
  int secondsSinceEpoch = date - epochStartSeconds;

  float height = 0;
  for(int i = 0; i < constituentCount; i++) {
    float degreesPerHour = get_speed(i);
    float radiansPerSecond = degreesPerHour * M_PI / 648000.0;
    height += amplitudes[i] * cos(radiansPerSecond * secondsSinceEpoch + phases[i]);
  }

  height += record.datum_offset;
  return height;
}

Ответ 2

National Tidal Datum Epoch не относится к Unix epoch; это показатель величины среднего уровня прилива за этот период. Данные Bridgeport содержат величину и фазу для каждого компонента, а затем дают частоту компонента в последнем столбце. Фаза относительно GMT (GMT - 0 градусов), поэтому укажите время в часах в GMT или смещение в соответствии с часовым поясом. Последний столбец является функцией компонента, а не местоположения, так что столбец одинаковый для любого местоположения. Таким образом, проблема заключается в суммировании синусоид разных частот, таких как анализ Фурье. Полученная функция, скорее всего, не будет иметь 24-часового периода, так как все компоненты имеют разные (не 24-часовой) периоды. Я использовал этот в качестве ссылки.

В приведенном ниже коде я включил некоторые необязательные аргументы для добавления некоторых модификаторов смещения (например, ваш 3.16999, не уверен, откуда это). Я отделил код чтения и анализа от кода вычисления. Возвращенная функция из get_tides содержит измеренные данные в closure. Вам не нужно это делать и вместо этого использовать класс.

from __future__ import division
import math
import time

def get_tides(fn):
    """Read tide data from file, return a function that
    gives tide level for specified hour."""
    with open(fn,'r') as fh:
        lines = fh.readlines()

    measured = []
    for line in lines:
        index,cons,ampl,phase,speed = line.split()
        measured.append(tuple(float(x) for x in (ampl,phase,speed)))

    def find_level(hour,total_offset=0,time_offset=0):
        total = total_offset
        for ampl,phase,speed in measured:
            # you could break out the constituents here
            # to see the individual contributions
            cosarg = speed * (hour + time_offset) + phase
            total += ampl * math.cos(cosarg * math.pi/180) # do rad conversion here
        return total

    return find_level


bridgeport = get_tides('bridgeport.txt')

for hour in range(-24,25,1):
    print("%3sh %7.4f" % (hour,bridgeport(hour,total_offset=3.61999)))

И вывод:

-24h -0.5488
-23h -1.8043
-22h -1.7085
-21h -0.3378
-20h  1.8647
-19h  4.4101
-18h  6.8374
-17h  8.5997
-16h  9.1818
-15h  8.4168
-14h  6.5658
-13h  4.1003
-12h  1.5669
-11h -0.3936
-10h -1.2009
 -9h -0.6705
 -8h  0.9032
 -7h  3.0316
 -6h  5.2485
 -5h  7.0432
 -4h  7.8633
 -3h  7.4000
 -2h  5.8028
 -1h  3.5317
  0h  1.1223
  1h -0.8425
  2h -1.7748
  3h -1.3620
  4h  0.2196
  5h  2.4871
  6h  4.9635
  7h  7.2015
  8h  8.6781
  9h  8.9524
 10h  7.9593
 11h  6.0188
 12h  3.6032
 13h  1.2440
 14h -0.4444
 15h -0.9554
 16h -0.2106
 17h  1.4306
 18h  3.4834
 19h  5.5091
 20h  7.0246
 21h  7.5394
 22h  6.8482
 23h  5.1795
 24h  2.9995

EDIT: Для конкретной даты или времени:

import datetime

epoch = datetime.datetime(1991,9,1,0,0,0)
now = datetime.datetime.utcnow()
hourdiff = (now-epoch).days*24

for hour in range(0,25,1):
    print("%3sh %7.4f" % (hour,bridgeport(hour+hourdiff)))

Ответ 3

Я только что написал небольшую библиотеку Python под названием Pytides для приливного анализа и прогнозирования. Он все еще находится на ранних стадиях, но вы можете достичь того, чего хотите довольно легко, используя его. Я написал пример, как это сделать.

Как отметил Дэйв, причина, по которой ваш метод не работает, заключается в том, что фазы NOAA публикуются относительно равновесных аргументов составляющих, поэтому вам нужно каким-то образом разработать эти аргументы равновесия (я предлагаю, чтобы Pytides делал это для вас!).

Ответ 4

"Фазы находятся в градусах, ссылающихся на GMT" на вашей ссылке, означает, что приемы "Бриджпорт" являются "фазовыми" степенями из-за синхронизации с теоретическими "равновесными" приливами в Гринвичском меридиане.

Вам также понадобятся равновесные приливы как функция времени. Одним из способов было бы скопировать константы из столбца 2010 http://coastalengineeringmanual.tpub.com/Part-II-Chap5/Part-II-Chap50024.htm и использовать 2010-01-01T00: 00: 00 в качестве вашей временной привязки/эпоха/ноль.

Кроме того, существует узловой фактор, который модулирует ряд составляющих в зависимости от узловой прецессии луны.

Вместо копирования из таблицы вы можете редактировать и запускать программу tide_fac.f из http://adcirc.org/home/related-software/adcirc-utility-programs/ для создания набора узловых факторов и равновесные приливные составляющие в выбранном вами времени/времени/ноль.

Здесь выводятся из измененной программы tide_fac.f для создания аргументов фазы узла и равновесия для 2013-01-01T00: 00: 00:

TIDAL FACTORS STARTING:  HR- 0.00,  DAY-  1,  MONTH-  1  YEAR- 2013

FOR A RUN LASTING   365.00 DAYS


CONST   NODE     EQ ARG (ref GM)
NAME   FACTOR    (DEG) 


M2    1.02718     270.21
S2    1.00000       0.00
N2    1.02718      16.12
K1    0.92336      17.70
M4    1.05510     180.42
O1    0.87509     248.94
M6    1.08377      90.63
MK3   0.94846     287.91
S4    1.00000       0.00
MN4   1.05510     286.33
NU2   1.02718      73.02
S6    1.00000       0.00
MU2   1.02718     178.93
2N2   1.02718     122.03
OO1   0.63334     333.60
LAMB  1.02718     287.40
S1    1.00000     180.00
M1    0.00000     159.37
J1    0.89282     275.36
MM    1.09369     254.09
SSA   1.00000     201.62
SA    1.00000     280.81
MSF   1.02718      91.28   
MF    0.74476     312.33
RHO1  0.87509      51.75   
Q1    0.87509     354.85
T2    1.00000       2.35
R2    1.00000     177.65
2Q1   0.87509     100.76
P1    1.00000     349.19
2SM2  1.02718      89.79
M3    1.04114     225.31
L2    0.00000     348.15
2MK3  0.97424     162.72
K2    0.81662     214.58
M8    1.11323       0.84
MS4   1.02718     270.21