1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.events.CylindricalShadowEclipseDetector;
24 import org.orekit.propagation.events.EventDetector;
25 import org.orekit.propagation.events.EventDetectionSettings;
26 import org.orekit.propagation.events.FieldCylindricalShadowEclipseDetector;
27 import org.orekit.propagation.events.FieldEventDetector;
28 import org.orekit.propagation.events.FieldEventDetectionSettings;
29 import org.orekit.propagation.events.handlers.FieldResetDerivativesOnEvent;
30 import org.orekit.propagation.events.handlers.ResetDerivativesOnEvent;
31 import org.orekit.utils.ExtendedPositionProvider;
32
33 import java.util.ArrayList;
34 import java.util.List;
35
36
37
38
39
40
41
42
43
44
45
46 public class CylindricallyShadowedLightFluxModel extends AbstractSolarLightFluxModel {
47
48
49
50
51 private static final double CYLINDRICAL_ECLIPSE_MAX_CHECK = 100;
52
53
54
55
56 private static final double CYLINDRICAL_ECLIPSE_THRESHOLD = 1e-7;
57
58
59
60
61
62
63
64
65
66 public CylindricallyShadowedLightFluxModel(final double kRef, final ExtendedPositionProvider occultedBody,
67 final double occultingBodyRadius, final EventDetectionSettings eventDetectionSettings) {
68 super(kRef, occultedBody, occultingBodyRadius, eventDetectionSettings);
69 }
70
71
72
73
74
75
76
77 public CylindricallyShadowedLightFluxModel(final double kRef, final ExtendedPositionProvider occultedBody,
78 final double occultingBodyRadius) {
79 this(kRef, occultedBody, occultingBodyRadius, getDefaultEclipseDetectionSettings());
80 }
81
82
83
84
85
86
87 public CylindricallyShadowedLightFluxModel(final ExtendedPositionProvider occultedBody,
88 final double occultingBodyRadius) {
89 super(occultedBody, occultingBodyRadius, getDefaultEclipseDetectionSettings());
90 }
91
92
93
94
95
96
97 public static EventDetectionSettings getDefaultEclipseDetectionSettings() {
98 return new EventDetectionSettings(CYLINDRICAL_ECLIPSE_MAX_CHECK, CYLINDRICAL_ECLIPSE_THRESHOLD,
99 EventDetectionSettings.DEFAULT_MAX_ITER);
100 }
101
102
103 @Override
104 protected double getLightingRatio(final Vector3D position, final Vector3D occultedBodyPosition) {
105 final Vector3D occultedBodyDirection = occultedBodyPosition.normalize();
106 final double dotProduct = position.dotProduct(occultedBodyDirection);
107 if (dotProduct < 0.) {
108 final double distanceToCylinderAxis = (position.subtract(occultedBodyDirection.scalarMultiply(dotProduct))).getNorm();
109 if (distanceToCylinderAxis <= getOccultingBodyRadius()) {
110 return 0.;
111 }
112 }
113 return 1.;
114 }
115
116
117 @Override
118 protected <T extends CalculusFieldElement<T>> T getLightingRatio(final FieldVector3D<T> position,
119 final FieldVector3D<T> occultedBodyPosition) {
120 final Field<T> field = position.getX().getField();
121 final FieldVector3D<T> occultedBodyDirection = occultedBodyPosition.normalize();
122 final T dotProduct = position.dotProduct(occultedBodyDirection);
123 if (dotProduct.getReal() < 0.) {
124 final T distanceToCylinderAxis = (position.subtract(occultedBodyDirection.scalarMultiply(dotProduct))).getNorm();
125 if (distanceToCylinderAxis.getReal() <= getOccultingBodyRadius()) {
126 return field.getZero();
127 }
128 }
129 return field.getOne();
130 }
131
132
133
134 @Override
135 public List<EventDetector> getEclipseConditionsDetector() {
136 final List<EventDetector> detectors = new ArrayList<>();
137 detectors.add(createCylindricalShadowEclipseDetector().withDetectionSettings(getEventDetectionSettings()));
138 return detectors;
139 }
140
141
142
143
144
145 private CylindricalShadowEclipseDetector createCylindricalShadowEclipseDetector() {
146 return new CylindricalShadowEclipseDetector(getOccultedBody(), getOccultingBodyRadius(),
147 new ResetDerivativesOnEvent());
148 }
149
150
151 @Override
152 public <T extends CalculusFieldElement<T>> List<FieldEventDetector<T>> getFieldEclipseConditionsDetector(final Field<T> field) {
153 final List<FieldEventDetector<T>> detectors = new ArrayList<>();
154 final FieldEventDetectionSettings<T> detectionSettings = new FieldEventDetectionSettings<>(field, getEventDetectionSettings());
155 detectors.add(createFieldCylindricalShadowEclipseDetector(field).withDetectionSettings(detectionSettings));
156 return detectors;
157 }
158
159
160
161
162
163
164
165 private <T extends CalculusFieldElement<T>> FieldCylindricalShadowEclipseDetector<T> createFieldCylindricalShadowEclipseDetector(final Field<T> field) {
166 final T occultingBodyRadiusAsField = field.getZero().newInstance(getOccultingBodyRadius());
167 return new FieldCylindricalShadowEclipseDetector<>(getOccultedBody(), occultingBodyRadiusAsField,
168 new FieldResetDerivativesOnEvent<>());
169 }
170 }