File: miscAccelerationsAtmosphericDragFromDensityFile.h

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (127 lines) | stat: -rw-r--r-- 4,953 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/***********************************************/
/**
* @file miscAccelerationsAtmosphericDragFromDensityFile.h
*
* @brief Atmospheric drag from denity along orbit.
* @see MiscAccelerations
*
* @author Torsten Mayer-Guerr
* @date 2022-08-13
*
*/
/***********************************************/

#ifndef __GROOPS_MISCACCELERATIONSATMOSPHERICDRAGFROMDENSITYFILE__
#define __GROOPS_MISCACCELERATIONSATMOSPHERICDRAGFROMDENSITYFILE__

// Latex documentation
#ifdef DOCSTRING_MiscAccelerations
static const char *docstringMiscAccelerationsAtmosphericDragFromDensityFile = R"(
\subsection{AtmosphericDragFromDensityFile}\label{miscAccelerationsType:atmosphericDragFromDensityFile}
Atmospheric drag computed from thermospheric density along the orbit
(\configFile{inputfileDensity}{instrument}, MISCVALUE). The \configClass{thermosphere}{thermosphereType}
is used to to compute temperature and wind.
For further details see \configClass{atmosphericDrag}{miscAccelerationsType:atmosphericDrag}.
)";
#endif

/***********************************************/

#include "files/fileInstrument.h"
#include "classes/thermosphere/thermosphere.h"
#include "classes/miscAccelerations/miscAccelerations.h"
#include "classes/miscAccelerations/miscAccelerationsAtmosphericDrag.h"

/***** CLASS ***********************************/

/** @brief Atmospheric drag.
 * @ingroup miscAccelerationsGroup
 * @see MiscAccelerations */
class MiscAccelerationsAtmosphericDragFromDensityFile : public MiscAccelerationsBase
{
  MiscValueArc    density;
  ThermospherePtr thermosphere;
  Bool            useTemperature, useWind;
  Vector3d        omega;
  Double          factor;
  UInt            idx;

public:
  MiscAccelerationsAtmosphericDragFromDensityFile(Config &config);

  Vector3d acceleration(SatelliteModelPtr satellite, const Time &time, const Vector3d &position, const Vector3d &velocity,
                        const Rotary3d &rotSat, const Rotary3d &rotEarth, EphemeridesPtr ephemerides) override;
};

/***********************************************/

inline MiscAccelerationsAtmosphericDragFromDensityFile::MiscAccelerationsAtmosphericDragFromDensityFile(Config &config)
{
  try
  {
    FileName fileNameDensity;
    Double   angleVelocity;

    readConfig(config, "inputfileDensity",    fileNameDensity, Config::MUSTSET, "",    "density along orbit, MISCVALUE (kg/m^3)");
    readConfig(config, "thermosphere",        thermosphere,    Config::MUSTSET, "",    "used to compute temperature and wind");
    readConfig(config, "earthRotation",       angleVelocity,   Config::DEFAULT, "7.29211585531e-5", "[rad/s]");
    readConfig(config, "considerTemperature", useTemperature,  Config::DEFAULT, "1",   "compute drag and lift, otherwise simple drag coefficient is used");
    readConfig(config, "considerWind",        useWind,         Config::DEFAULT, "1",   "");
    readConfig(config, "factor",              factor,          Config::DEFAULT, "1.0", "the result is multiplied by this factor");
    if(isCreateSchema(config)) return;

    density = InstrumentFile::read(fileNameDensity);
    omega = Vector3d(0, 0, angleVelocity);
    idx = 0;
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/

inline Vector3d MiscAccelerationsAtmosphericDragFromDensityFile::acceleration(SatelliteModelPtr satellite, const Time &time,
                                                                              const Vector3d &position, const Vector3d &velocity,
                                                                              const Rotary3d &rotSat, const Rotary3d &rotEarth, EphemeridesPtr /*ephemerides*/)
{
  try
  {
    if(!satellite)
      throw(Exception("No satellite model given"));

    if((time < density.front().time)|| (time > density.back().time))
      throw(Exception("time not given in density file: "+time.dateTimeStr()));

    // find index (interpolations interval)
    if((idx >= density.size()) || (time < density.at(idx).time))
      idx = 0;
    while(time > density.at(idx).time)
      idx++;
    if(time != density.at(idx).time)
      throw(Exception("time not given in density file: "+time.dateTimeStr()));

    Double   densityModel, temperature;
    Vector3d wind;
    thermosphere->state(time, rotEarth.rotate(position), densityModel, temperature, wind);
    if(!useTemperature)
      temperature = 0;
    if(!useWind)
      wind = Vector3d();

    // direction and speed of thermosphere relative to satellite in SRF
    Vector3d direction = rotSat.inverseRotate(rotEarth.inverseRotate(wind) + crossProduct(omega, position) - velocity);
    const Double v = direction.normalize();

    return (factor/satellite->mass) * rotEarth.rotate(rotSat.rotate(MiscAccelerationsAtmosphericDrag::force(satellite, direction, v, density.at(idx).value, temperature)));
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/

#endif