/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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.propagation.events; import org.orekit.errors.OrekitInternalError; /** Enumerate for {@link EventSlopeFilter filtering events}. * <p>This class is heavily based on the class with the same name from the * Hipparchus library. The changes performed consist in package * name and error handling.</p> * @since 6.0 */ public enum FilterType { /** Constant for triggering only decreasing events. * <p>When this filter is used, the wrapped {@link EventDetector * event detector} {@link * EventDetector#eventOccurred(org.orekit.propagation.SpacecraftState, * boolean) eventOccurred} method will be called <em>only</em> with * its {@code increasing} argument set to false.</p> */ TRIGGER_ONLY_DECREASING_EVENTS { /** {@inheritDoc} */ protected boolean getTriggeredIncreasing() { return false; } /** {@inheritDoc} * <p> * states scheduling for computing h(t,y) as an altered version of g(t, y) * <ul> * <li>0 are triggered events for which a zero is produced (here decreasing events)</li> * <li>X are ignored events for which zero is masked (here increasing events)</li> * </ul> * </p> * <p> * Several expressions are used to compute h, depending on the current state: * <ul> * <li>h = max(+s,-g,+g)</li> * <li>h = +g</li> * <li>h = min(-s,-g,+g)</li> * <li>h = -g</li> * </ul> * where s is a tiny positive value: {@link org.hipparchus.util.Precision#SAFE_MIN}. * </p> */ protected Transformer selectTransformer(final Transformer previous, final double g, final boolean forward) { if (forward) { switch (previous) { case UNINITIALIZED : // we are initializing the first point if (g > 0) { // initialize as if previous root (i.e. backward one) was an ignored increasing event return Transformer.MAX; } else if (g < 0) { // initialize as if previous root (i.e. backward one) was a triggered decreasing event return Transformer.PLUS; } else { // we are exactly at a root, we don't know if it is an increasing // or a decreasing event, we remain in uninitialized state return Transformer.UNINITIALIZED; } case PLUS : if (g >= 0) { // we have crossed the zero line on an ignored increasing event, // we must change the transformer return Transformer.MIN; } else { // we are still in the same status return previous; } case MINUS : if (g >= 0) { // we have crossed the zero line on an ignored increasing event, // we must change the transformer return Transformer.MAX; } else { // we are still in the same status return previous; } case MIN : if (g <= 0) { // we have crossed the zero line on a triggered decreasing event, // we must change the transformer return Transformer.MINUS; } else { // we are still in the same status return previous; } case MAX : if (g <= 0) { // we have crossed the zero line on a triggered decreasing event, // we must change the transformer return Transformer.PLUS; } else { // we are still in the same status return previous; } default : // this should never happen throw new OrekitInternalError(null); } } else { switch (previous) { case UNINITIALIZED : // we are initializing the first point if (g > 0) { // initialize as if previous root (i.e. forward one) was a triggered decreasing event return Transformer.MINUS; } else if (g < 0) { // initialize as if previous root (i.e. forward one) was an ignored increasing event return Transformer.MIN; } else { // we are exactly at a root, we don't know if it is an increasing // or a decreasing event, we remain in uninitialized state return Transformer.UNINITIALIZED; } case PLUS : if (g <= 0) { // we have crossed the zero line on an ignored increasing event, // we must change the transformer return Transformer.MAX; } else { // we are still in the same status return previous; } case MINUS : if (g <= 0) { // we have crossed the zero line on an ignored increasing event, // we must change the transformer return Transformer.MIN; } else { // we are still in the same status return previous; } case MIN : if (g >= 0) { // we have crossed the zero line on a triggered decreasing event, // we must change the transformer return Transformer.PLUS; } else { // we are still in the same status return previous; } case MAX : if (g >= 0) { // we have crossed the zero line on a triggered decreasing event, // we must change the transformer return Transformer.MINUS; } else { // we are still in the same status return previous; } default : // this should never happen throw new OrekitInternalError(null); } } } }, /** Constant for triggering only increasing events. * <p>When this filter is used, the wrapped {@link EventDetector * event detector} {@link * EventDetector#eventOccurred(org.orekit.propagation.SpacecraftState, * boolean) eventOccurred} method will be called <em>only</em> with * its {@code increasing} argument set to true.</p> */ TRIGGER_ONLY_INCREASING_EVENTS { /** {@inheritDoc} */ protected boolean getTriggeredIncreasing() { return true; } /** {@inheritDoc} * <p> * states scheduling for computing h(t,y) as an altered version of g(t, y) * <ul> * <li>0 are triggered events for which a zero is produced (here increasing events)</li> * <li>X are ignored events for which zero is masked (here decreasing events)</li> * </ul> * </p> * <p> * Several expressions are used to compute h, depending on the current state: * <ul> * <li>h = max(+s,-g,+g)</li> * <li>h = +g</li> * <li>h = min(-s,-g,+g)</li> * <li>h = -g</li> * </ul> * where s is a tiny positive value: {@link org.hipparchus.util.Precision#SAFE_MIN}. * </p> */ protected Transformer selectTransformer(final Transformer previous, final double g, final boolean forward) { if (forward) { switch (previous) { case UNINITIALIZED : // we are initializing the first point if (g > 0) { // initialize as if previous root (i.e. backward one) was a triggered increasing event return Transformer.PLUS; } else if (g < 0) { // initialize as if previous root (i.e. backward one) was an ignored decreasing event return Transformer.MIN; } else { // we are exactly at a root, we don't know if it is an increasing // or a decreasing event, we remain in uninitialized state return Transformer.UNINITIALIZED; } case PLUS : if (g <= 0) { // we have crossed the zero line on an ignored decreasing event, // we must change the transformer return Transformer.MAX; } else { // we are still in the same status return previous; } case MINUS : if (g <= 0) { // we have crossed the zero line on an ignored decreasing event, // we must change the transformer return Transformer.MIN; } else { // we are still in the same status return previous; } case MIN : if (g >= 0) { // we have crossed the zero line on a triggered increasing event, // we must change the transformer return Transformer.PLUS; } else { // we are still in the same status return previous; } case MAX : if (g >= 0) { // we have crossed the zero line on a triggered increasing event, // we must change the transformer return Transformer.MINUS; } else { // we are still in the same status return previous; } default : // this should never happen throw new OrekitInternalError(null); } } else { switch (previous) { case UNINITIALIZED : // we are initializing the first point if (g > 0) { // initialize as if previous root (i.e. forward one) was an ignored decreasing event return Transformer.MAX; } else if (g < 0) { // initialize as if previous root (i.e. forward one) was a triggered increasing event return Transformer.MINUS; } else { // we are exactly at a root, we don't know if it is an increasing // or a decreasing event, we remain in uninitialized state return Transformer.UNINITIALIZED; } case PLUS : if (g >= 0) { // we have crossed the zero line on an ignored decreasing event, // we must change the transformer return Transformer.MIN; } else { // we are still in the same status return previous; } case MINUS : if (g >= 0) { // we have crossed the zero line on an ignored decreasing event, // we must change the transformer return Transformer.MAX; } else { // we are still in the same status return previous; } case MIN : if (g <= 0) { // we have crossed the zero line on a triggered increasing event, // we must change the transformer return Transformer.MINUS; } else { // we are still in the same status return previous; } case MAX : if (g <= 0) { // we have crossed the zero line on a triggered increasing event, // we must change the transformer return Transformer.PLUS; } else { // we are still in the same status return previous; } default : // this should never happen throw new OrekitInternalError(null); } } } }; /** Get the increasing status of triggered events. * @return true if triggered events are increasing events */ protected abstract boolean getTriggeredIncreasing(); /** Get next function transformer in the specified direction. * @param previous transformer active on the previous point with respect * to integration direction (may be null if no previous point is known) * @param g current value of the g function * @param forward true if integration goes forward * @return next transformer transformer */ protected abstract Transformer selectTransformer(Transformer previous, double g, boolean forward); }