isce3 0.25.0
Loading...
Searching...
No Matches
InterpolateOrbit.icc
1#ifndef ISCE_CORE_DETAIL_INTERPOLATEORBIT_ICC
2#error "InterpolateOrbit.icc is an implementation detail of InterpolateOrbit.h"
3#endif
4
5#include <algorithm>
6#include <limits>
7
8namespace isce3 { namespace core { namespace detail {
9
10NVCC_HD_WARNING_DISABLE
11template<class Orbit>
12CUDA_HOSTDEV
13inline
14isce3::error::ErrorCode
15interpolateOrbitHermite(Vec3 * position, Vec3 * velocity, const Orbit & orbit, double t)
16{
17 // find index of the first state vector to use to form the interpolant
18 int idx = orbit.time().search(t) - 2;
19 idx = std::min(std::max(idx, 0), orbit.size() - 4);
20
21 double f1[4];
22 PRAGMA_UNROLL
23 for (int i = 0; i < 4; ++i) {
24 f1[i] = t - orbit.time(idx + i);
25 }
26
27 double f0[4];
28 PRAGMA_UNROLL
29 for (int i = 0; i < 4; ++i) {
30 double sum = 0.;
31 PRAGMA_UNROLL
32 for (int j = 0; j < 4; ++j) {
33 if (j == i) { continue; }
34 sum += 1. / (orbit.time(idx + i) - orbit.time(idx + j));
35 }
36 f0[i] = 1. - 2. * sum * (t - orbit.time(idx + i));
37 }
38
39 double h[4];
40 PRAGMA_UNROLL
41 for (int i = 0; i < 4; ++i) {
42 h[i] = 1.;
43 PRAGMA_UNROLL
44 for (int j = 0; j < 4; ++j) {
45 if (j == i) { continue; }
46 h[i] *= (t - orbit.time(idx + j)) / (orbit.time(idx + i) - orbit.time(idx + j));
47 }
48 }
49
50 // get interpolated position
51 if (position) {
52 Vec3 pos(0., 0., 0.);
53 PRAGMA_UNROLL
54 for (int i = 0; i < 4; ++i) {
55 pos += h[i] * h[i] * (orbit.position(idx + i) * f0[i] + orbit.velocity(idx + i) * f1[i]);
56 }
57 *position = pos;
58 }
59
60 // if only interpolating position, we can finish here
61 if (!velocity) {
62 return isce3::error::ErrorCode::Success;
63 }
64
65 double hdot[4];
66 PRAGMA_UNROLL
67 for (int i = 0; i < 4; ++i) {
68 hdot[i] = 0.;
69 PRAGMA_UNROLL
70 for (int j = 0; j < 4; ++j) {
71 if (j == i) { continue; }
72 double prod = 1. / (orbit.time(idx + i) - orbit.time(idx + j));
73 PRAGMA_UNROLL
74 for (int k = 0; k < 4; ++k) {
75 if (k == i || k == j) { continue; }
76 prod *= (t - orbit.time(idx + k)) / (orbit.time(idx + i) - orbit.time(idx + k));
77 }
78 hdot[i] += prod;
79 }
80 }
81
82 double g1[4];
83 PRAGMA_UNROLL
84 for (int i = 0; i < 4; ++i) {
85 g1[i] = h[i] + 2. * hdot[i] * (t - orbit.time(idx + i));
86 }
87
88 double g0[4];
89 PRAGMA_UNROLL
90 for (int i = 0; i < 4; ++i) {
91 double sum = 0.;
92 PRAGMA_UNROLL
93 for (int j = 0; j < 4; ++j) {
94 if (j == i) { continue; }
95 sum += 1. / (orbit.time(idx + i) - orbit.time(idx + j));
96 }
97 g0[i] = 2. * (f0[i] * hdot[i] - sum * h[i]);
98 }
99
100 // get interpolated velocity
101 Vec3 vel(0., 0., 0.);
102 PRAGMA_UNROLL
103 for (int i = 0; i < 4; ++i) {
104 vel += h[i] * (orbit.position(idx + i) * g0[i] + orbit.velocity(idx + i) * g1[i]);
105 }
106 *velocity = vel;
107
108 return isce3::error::ErrorCode::Success;
109}
110
111NVCC_HD_WARNING_DISABLE
112template<class Orbit>
113CUDA_HOSTDEV
114inline
115isce3::error::ErrorCode
116interpolateOrbitLegendre(Vec3 * position, Vec3 * velocity, const Orbit & orbit, double t)
117{
118 // find index of the first state vector to use to form the interpolant
119 int idx = orbit.time().search(t) - 5;
120 idx = std::min(std::max(idx, 0), orbit.size() - 9);
121
122 double trel = 8. * (t - orbit.time(idx)) / (orbit.time(idx + 8) - orbit.time(idx));
123
124 double teller = 1.;
125 PRAGMA_UNROLL
126 for (int i = 0; i < 9; ++i) {
127 teller *= trel - i;
128 }
129
130 if (teller == 0.) {
131 int i = trel;
132 if (position) { *position = orbit.position(idx + i); }
133 if (velocity) { *velocity = orbit.velocity(idx + i); }
134 return isce3::error::ErrorCode::Success;
135 }
136
137 constexpr static double noemer[9] =
138 { 40320.0, -5040.0, 1440.0,
139 -720.0, 576.0, -720.0,
140 1440.0, -5040.0, 40320.0 };
141
142 Vec3 pos(0., 0., 0.);
143 Vec3 vel(0., 0., 0.);
144 PRAGMA_UNROLL
145 for (int i = 0; i < 9; ++i) {
146 double coeff = (teller / noemer[i]) / (trel - i);
147 pos += coeff * orbit.position(idx + i);
148 vel += coeff * orbit.velocity(idx + i);
149 }
150
151 if (position) { *position = pos; }
152 if (velocity) { *velocity = vel; }
153
154 return isce3::error::ErrorCode::Success;
155}
156
157template<class Orbit>
158CUDA_HOSTDEV
159inline
160isce3::error::ErrorCode
161interpolateOrbit(Vec3 * position,
162 Vec3 * velocity,
163 const Orbit & orbit,
164 double t,
165 OrbitInterpBorderMode border_mode)
166{
167 // make sure we have enough state vectors to form the interpolant
168 if (orbit.size() < minStateVecs(orbit.interpMethod())) {
169 return isce3::error::ErrorCode::OrbitInterpSizeError;
170 }
171
172 // check if interpolation time is outside orbit domain
173 if (t < orbit.startTime() || t > orbit.endTime()) {
174 if (border_mode == OrbitInterpBorderMode::FillNaN) {
175 constexpr static double nan = std::numeric_limits<double>::quiet_NaN();
176 if (position) { *position = {nan, nan, nan}; }
177 if (velocity) { *velocity = {nan, nan, nan}; }
178 }
179 if (border_mode != OrbitInterpBorderMode::Extrapolate) {
180 return isce3::error::ErrorCode::OrbitInterpDomainError;
181 }
182 }
183
184 // interpolate
185 switch (orbit.interpMethod()) {
186 case OrbitInterpMethod::Hermite :
187 return interpolateOrbitHermite(position, velocity, orbit, t);
188 case OrbitInterpMethod::Legendre :
189 return interpolateOrbitLegendre(position, velocity, orbit, t);
190 default :
191 return isce3::error::ErrorCode::OrbitInterpUnknownMethod;
192 }
193}
194
195}}}
const Linspace< double > & time() const
Get state vector times relative to reference epoch (s)
Definition Orbit.h:157
const std::vector< Vec3 > & velocity() const
Get state vector velocities in ECEF coordinates (m/s)
Definition Orbit.h:163
const std::vector< Vec3 > & position() const
Get state vector positions in ECEF coordinates (m)
Definition Orbit.h:160
double startTime() const
Time of first state vector relative to reference epoch (s)
Definition Orbit.h:128
double endTime() const
Time of last state vector relative to reference epoch (s)
Definition Orbit.h:134
OrbitInterpMethod interpMethod() const
Interpolation method.
Definition Orbit.h:116
int size() const
Number of state vectors in orbit.
Definition Orbit.h:154
CUDA_HOSTDEV constexpr int search(U) const
Return the position where the specified value would be inserted in the sequence in order to maintain ...
Definition Linspace.icc:77
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5

Generated for ISCE3.0 by doxygen 1.13.2.