PiecewiseSphericalHarmonics.java
/* Copyright 2002-2022 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.forces.gravity.potential;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.SinCos;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.TimeSpanMap;
/** Piecewise gravity fields with time-dependent models in each interval.
* @author Luc Maisonobe
* @since 11.1
*/
class PiecewiseSphericalHarmonics implements RawSphericalHarmonicsProvider {
/** Constant part of the field. */
private final ConstantSphericalHarmonics constant;
/** Reference dates. */
private final AbsoluteDate[] references;
/** Pulsations (rad/s). */
private final double[] pulsations;
/** Piecewise parts. */
private final TimeSpanMap<PiecewisePart> pieces;
/** Maximum supported degree. */
private final int maxDegree;
/** Maximum supported order. */
private final int maxOrder;
/** Simple constructor.
* @param constant constant part of the field
* @param references references dates
* @param pulsations pulsations (rad/s)
* @param pieces piecewise parts
*/
PiecewiseSphericalHarmonics(final ConstantSphericalHarmonics constant,
final AbsoluteDate[] references, final double[] pulsations,
final TimeSpanMap<PiecewisePart> pieces) {
this.constant = constant;
this.references = references.clone();
this.pulsations = pulsations.clone();
this.pieces = pieces;
// get limits
int d = constant.getMaxDegree();
int o = constant.getMaxOrder();
for (TimeSpanMap.Span<PiecewisePart> span = pieces.getFirstSpan(); span != null; span = span.next()) {
final PiecewisePart piece = span.getData();
if (piece != null) {
d = FastMath.max(d, piece.getMaxDegree());
o = FastMath.max(o, piece.getMaxOrder());
}
}
this.maxDegree = d;
this.maxOrder = o;
}
/** Get the constant part of the field.
* @return constant part of the field
*/
public ConstantSphericalHarmonics getConstant() {
return constant;
}
/** {@inheritDoc} */
public int getMaxDegree() {
return maxDegree;
}
/** {@inheritDoc} */
public int getMaxOrder() {
return maxOrder;
}
/** {@inheritDoc} */
public double getMu() {
return constant.getMu();
}
/** {@inheritDoc} */
public double getAe() {
return constant.getAe();
}
/** {@inheritDoc} */
public AbsoluteDate getReferenceDate() {
AbsoluteDate last = AbsoluteDate.PAST_INFINITY;
for (final AbsoluteDate date : references) {
if (date.isAfter(last)) {
last = date;
}
}
return last;
}
/** {@inheritDoc} */
@Deprecated
public double getOffset(final AbsoluteDate date) {
return date.durationFrom(references[0]);
}
/** {@inheritDoc} */
public TideSystem getTideSystem() {
return constant.getTideSystem();
}
/** Get the raw spherical harmonic coefficients on a specific date.
* @param date to evaluate the spherical harmonics
* @return the raw spherical harmonics on {@code date}.
*/
public RawSphericalHarmonics onDate(final AbsoluteDate date) {
// raw (constant) harmonics
final RawSphericalHarmonics raw = constant.onDate(date);
// select part of the piecewise model that is active at specified date
final PiecewisePart piece = pieces.get(date);
// pre-compute canonical functions
final double[] offsets = new double[references.length];
final SinCos[][] sinCos = new SinCos[references.length][pulsations.length];
for (int i = 0; i < references.length; ++i) {
final double offset = date.durationFrom(references[i]);
offsets[i] = offset;
for (int j = 0; j < pulsations.length; ++j) {
sinCos[i][j] = FastMath.sinCos(offset * pulsations[j]);
}
}
return new RawSphericalHarmonics() {
@Override
public AbsoluteDate getDate() {
return date;
}
/** {@inheritDoc} */
public double getRawCnm(final int n, final int m) {
return raw.getRawCnm(n, m) + piece.computeCnm(n, m, offsets, sinCos);
}
/** {@inheritDoc} */
public double getRawSnm(final int n, final int m) {
return raw.getRawSnm(n, m) + piece.computeSnm(n, m, offsets, sinCos);
}
};
}
}