1   /* Copyright 2022-2024 Romain Serra
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.forces.radiation;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.orekit.propagation.FieldSpacecraftState;
24  import org.orekit.propagation.SpacecraftState;
25  import org.orekit.propagation.events.EventDetector;
26  import org.orekit.propagation.events.FieldEventDetector;
27  import org.orekit.utils.ParameterDriver;
28  
29  import java.util.List;
30  import java.util.stream.Stream;
31  
32  /**
33   * Class representing a light-induced radiation pressure force, by leveraging on a given flux model.
34   *
35   * <p>
36   *     This class should not be used in addition to {@link SolarRadiationPressure}, which is another way of
37   *     representing the same orbital perturbation.
38   * </p>
39   *
40   * @author Romain Serra
41   * @see LightFluxModel
42   * @see RadiationSensitive
43   * @since 12.1
44   */
45  public class RadiationPressureModel implements RadiationForceModel {
46  
47      /**
48       * Light flux model (including eclipse conditions).
49       */
50      private final LightFluxModel lightFluxModel;
51  
52      /**
53       * Object defining radiation properties defining the acceleration from the pressure.
54       */
55      private final RadiationSensitive radiationSensitive;
56  
57      /**
58       * Constructor.
59       * @param lightFluxModel model for light flux
60       * @param radiationSensitive object defining radiation properties
61       */
62      public RadiationPressureModel(final LightFluxModel lightFluxModel,
63                                    final RadiationSensitive radiationSensitive) {
64          this.lightFluxModel = lightFluxModel;
65          this.radiationSensitive = radiationSensitive;
66      }
67  
68      /**
69       * Getter for radiation sensitive object.
70       * @return radiation sensitive object
71       */
72      public RadiationSensitive getRadiationSensitive() {
73          return radiationSensitive;
74      }
75  
76      /**
77       * Getter for light flux model.
78       * @return flux model
79       */
80      public LightFluxModel getLightFluxModel() {
81          return lightFluxModel;
82      }
83  
84      /** {@inheritDoc} */
85      @Override
86      public boolean dependsOnPositionOnly() {
87          return radiationSensitive instanceof IsotropicRadiationClassicalConvention || radiationSensitive instanceof IsotropicRadiationCNES95Convention || radiationSensitive instanceof IsotropicRadiationSingleCoefficient;
88      }
89  
90      /** {@inheritDoc} */
91      @Override
92      public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
93          final Vector3D fluxVector = lightFluxModel.getLightFluxVector(s);
94          return radiationSensitive.radiationPressureAcceleration(s, fluxVector, parameters);
95      }
96  
97      /** {@inheritDoc} */
98      @Override
99      public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s, final T[] parameters) {
100         final FieldVector3D<T> fluxVector = lightFluxModel.getLightFluxVector(s);
101         return radiationSensitive.radiationPressureAcceleration(s, fluxVector, parameters);
102     }
103 
104     /** {@inheritDoc} */
105     @Override
106     public List<ParameterDriver> getParametersDrivers() {
107         return radiationSensitive.getRadiationParametersDrivers();
108     }
109 
110     /** {@inheritDoc} */
111     @Override
112     public Stream<EventDetector> getEventDetectors() {
113         final List<EventDetector> eventDetectors = lightFluxModel.getEclipseConditionsDetector();
114         return Stream.concat(RadiationForceModel.super.getEventDetectors(), eventDetectors.stream());
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(final Field<T> field) {
120         final List<FieldEventDetector<T>> eventDetectors = lightFluxModel.getFieldEclipseConditionsDetector(field);
121         return Stream.concat(RadiationForceModel.super.getFieldEventDetectors(field), eventDetectors.stream());
122     }
123 }