// Edit By: Li Yunfei // 20161208: 初次编写 // 20170104: 使用Orbitbase中的常数 /// <summary> /// 中心天体J2项摄动力(含中心引力,惯性系中计算,含岁差章动),右函数采用SphericalHarmonicGravity模型 /// <para>**缺省单位:m,m/s</para> /// <para>**Mu,J2,Re默认采用缺省值</para> /// </summary> /// <param name="position">PropagationNewtonianPoint,单位:m,m/s</param> /// <param name="centralBody"></param> /// <param name="gravitationalParameter">引力常数GM(m^3/s^2)</param> /// <param name="j2UnnormalizedValue">J2</param> /// <param name="referenceDistance">Re(m)</param> public static SphericalHarmonicGravity GetJ2Gravity(PropagationNewtonianPoint position, CentralBody centralBody, double gravitationalParameter = OrbitBase.EarthMu, double j2UnnormalizedValue = OrbitBase.EarthJ2, double referenceDistance = OrbitBase.EarthRe) { // 中心天体的J2项引力摄动(含中心引力,中心天体的惯性系中计算),含岁差章动 SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(); gravity.TargetPoint = position.IntegrationPoint; //* Will represent the position during propagation // 单位一致性检查 if (gravitationalParameter > 1e10 && (referenceDistance < 1e6 || position.InitialPosition.Magnitude < 1e6)) { throw new Exception("单位不一致Gm/Re/position!"); } if (gravitationalParameter < 1e10 && (referenceDistance > 1e6 || position.InitialPosition.Magnitude > 1e6)) { throw new Exception("单位不一致Gm/Re/position!"); } double[][] coe = new double[3][]; coe[0] = new double[1]; coe[1] = new double[2]; coe[2] = new double[3]; SphericalHarmonicGravityModel gravityModel = new SphericalHarmonicGravityModel("WGS84", centralBody.Name, gravitationalParameter, referenceDistance, new double[] { 1.0, 0.0, j2UnnormalizedValue }, coe, coe, false, false); int degree = 2; int order = 0; bool includeTwoBodyForce = true; gravity.GravityField = new SphericalHarmonicGravityField(gravityModel, degree, order, includeTwoBodyForce, SphericalHarmonicsTideType.None); return(gravity); }
/// <summary> /// J2积分器(惯性系中计算,含岁差章动),右函数采用SphericalHarmonicGravity模型 /// <para>积分变量仅位置、速度</para> /// <para>给position仅添加J2项右函数</para> /// <para>RKF7(8)数值积分器,缺省绝对和相对精度皆为1e-13</para> /// <para>Epoch属性需手动赋值</para> /// </summary> /// <param name="position">PropagationNewtonianPoint,单位:m,m/s</param> /// <param name="centralBody"></param> /// <param name="gravitationalParameter">引力常数GM(m^3/s^2)</param> /// <param name="j2UnnormalizedValue">J2</param> /// <param name="referenceDistance">Re(m)</param> /// <param name="absTolerance">RKF7(8)的绝对精度</param> /// <param name="relRolerance">RKF7(8)的相对精度</param> public PropagatorDefinitionJ2(PropagationNewtonianPoint position, CentralBody centralBody, double gravitationalParameter = 3.986004418e14, double j2UnnormalizedValue = 0.001082629989052, double referenceDistance = 6378137.0, double absTolerance = 1e-13, double relRolerance = 1e-13) { // 中心天体的J2项引力摄动(含中心引力,中心天体的惯性系中计算),含岁差章动 SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(); gravity.TargetPoint = position.IntegrationPoint; //* Will represent the position during propagation double[][] coe = new double[3][]; coe[0] = new double[1]; coe[1] = new double[2]; coe[2] = new double[3]; SphericalHarmonicGravityModel gravityModel = new SphericalHarmonicGravityModel("WGS84", centralBody.Name, gravitationalParameter, referenceDistance, new double[] { 1.0, 0.0, j2UnnormalizedValue }, coe, coe, false, false); int degree = 2; int order = 0; bool includeTwoBodyForce = true; gravity.GravityField = new SphericalHarmonicGravityField(gravityModel, degree, order, includeTwoBodyForce, SphericalHarmonicsTideType.None); // 添加右函数 position.AppliedForces.Clear(); position.AppliedForces.Add(gravity); // 积分变量 this.IntegrationElements.Add(position); // RKF7(8)数值积分器 RungeKuttaFehlberg78Integrator integrator = new RungeKuttaFehlberg78Integrator(); integrator.AbsoluteTolerance = absTolerance; integrator.RelativeTolerance = relRolerance; integrator.InitialStepSize = 60.0; integrator.StepSizeBehavior = KindOfStepSize.Relative; integrator.MaximumStepSize = 200.0; integrator.MinimumStepSize = 1.0; //* This is STK's default and truncates each step to 3 decimal places integrator.StepTruncationOrder = -3; this.Integrator = integrator; }
/// <summary> /// This will configure the entered point with all of the force models as entered in the GUI. /// </summary> /// <param name="point">The point to add the force models too.</param> /// <param name="area">The Scalar representing the area that the SRP and Drag model will see.</param> public void SetForceModelsOnPoint(PropagationNewtonianPoint point, Scalar area) { point.AppliedForces.Clear(); if (m_useSRP.Checked) { SimpleSolarRadiationForce srp = new SimpleSolarRadiationForce(point.IntegrationPoint, double.Parse(m_reflectivity.Text), area); if (m_shadowModel.SelectedItem.ToString() == DUALCONE) { srp.OccultationFactor = new ScalarOccultationDualCone(CentralBodiesFacet.GetFromContext().Sun, point.IntegrationPoint); } else if (m_shadowModel.SelectedItem.ToString() == CYLINDRICAL) { srp.OccultationFactor = new ScalarOccultationCylindrical(CentralBodiesFacet.GetFromContext().Sun, point.IntegrationPoint); } foreach (string id in m_eclipsingBodies.CheckedItems) { srp.OccultationFactor.OccludingBodies.Add(CentralBodiesFacet.GetFromContext().GetByName(id)); } point.AppliedForces.Add(srp); } if (m_useDrag.Checked) { ScalarAtmosphericDensity density = null; SolarGeophysicalData geoData = new ConstantSolarGeophysicalData(double.Parse(m_averageSolarFlux.Text), double.Parse(m_solarFlux.Text), double.Parse(m_kp.Text)); if (m_densityModel.SelectedItem.ToString() == JR) { density = new ScalarDensityJacchiaRoberts(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS86) { density = new ScalarDensityMsis86(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS90) { density = new ScalarDensityMsis90(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS2000) { density = new ScalarDensityMsis2000(point.IntegrationPoint, geoData); } AtmosphericDragForce atmo = new AtmosphericDragForce(density, new ScalarFixed(double.Parse(m_dragCoeff.Text)), area); point.AppliedForces.Add(atmo); } ThirdBodyGravity thirdGravity = new ThirdBodyGravity(point.IntegrationPoint); foreach (string item in m_thirdBodies.CheckedItems) { if (item == EARTH || item == SUN || item == MOON) { thirdGravity.AddThirdBody(item, CentralBodiesFacet.GetFromContext().GetByName(item).CenterOfMassPoint, m_gravConstants[item]); } else { thirdGravity.AddThirdBody(item, m_jplInfo.GetCenterOfMassPoint(m_nameToJplMapping[item]), m_gravConstants[item]); } } thirdGravity.CentralBody = CentralBodiesFacet.GetFromContext().GetByName(m_primaryCB.SelectedItem.ToString()); if (thirdGravity.ThirdBodies.Count > 0) { point.AppliedForces.Add(thirdGravity); } // Primary gravity string primaryCB = m_primaryCB.SelectedItem.ToString(); if (m_twoBody.Checked) { TwoBodyGravity gravity = new TwoBodyGravity(point.IntegrationPoint, CentralBodiesFacet.GetFromContext().GetByName(primaryCB), m_gravConstants[primaryCB]); point.AppliedForces.Add(gravity); } else { SphericalHarmonicsTideType tideType = SphericalHarmonicsTideType.None; if (m_tides.SelectedItem.ToString() == NOTIDES) { tideType = SphericalHarmonicsTideType.None; } else if (m_tides.SelectedItem.ToString() == PERMANENTTIDES) { tideType = SphericalHarmonicsTideType.PermanentTideOnly; } int order = int.Parse(m_order.Text); int degree = int.Parse(m_degree.Text); SphericalHarmonicGravityModel model = SphericalHarmonicGravityModel.ReadFrom(m_gravFile.Text); SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(point.IntegrationPoint, new SphericalHarmonicGravityField(model, degree, order, true, tideType)); point.AppliedForces.Add(gravity); if (gravity.GravityField.CentralBody.Name != primaryCB) { throw new InvalidDataException("The central body you have selected does not match the central body in the gravity file."); } } if (primaryCB == EARTH) { point.IntegrationFrame = CentralBodiesFacet.GetFromContext().Earth.InternationalCelestialReferenceFrame; } else if (primaryCB == MOON) { point.IntegrationFrame = CentralBodiesFacet.GetFromContext().Moon.InertialFrame; } }