Module: spacecraftChargingEquilibrium

Executive Summary

The spacecraftChargingEquilibrium module computes spacecraft equilibrium (floating) electric potentials in a plasma environment using two sequential 1-D root solves (by enforcing a zero net current condition on each spacecraft surface). The model includes ambient plasma electron/ion collection, photoelectron emission, and secondary electron emission (SEE), electron backscattering, and electron beam coupling (from one spacecraft to another).

The charging and electron-beam coupling equations used by this module follow Hammerl and Schaub’s coupled spacecraft charging model [Hammerl2024] and the references cited therein as well as the Dr. Lai’s book: “Fundamentals of Spacecraft Charging”. Additional background references on plasma interactions and modeling include [Hippler2001], [DavisMandell2016], [DraineSalpeter1979], and [RomeroCalvo2022].

A Python unit test script is provided to verify expected charging trends for a coupled two-spacecraft case (see User Guide).

Module Assumptions and Limitations

  • Conducting spacecraft and single potential: the theory used assumes each spacecraft is fully conducting and can be described by a single surface potential \(\phi\) (no differential charging).

  • Exactly two spacecraft are required: the coupled electron-beam charging logic is implemented for exactly two spacecraft and assumes:

    • spacecraft index 0 is the servicer

    • spacecraft index 1 is the target

  • Plasma environment input required: the plasma flux/energy grid message must be connected. If not connected, the module logs an error in Reset().

  • Surface areas: the module uses a configurable default exposed area and a configurable sunlit-area fallback. Sunlit area can be provided per spacecraft through input messages or per-spacecraft defaults via setters.

  • Numerical solution: equilibrium potentials are found using a bisection root solver. The bracket range must contain the root for each current balance equation.

Message Connection Descriptions

The following table lists all module input and output messages. The module msg variable name is set by the user from Python. The msg type contains a link to the message structure definition, while the description explains how the message is used.

Module I/O Messages

Msg Variable Name

Msg Type

Description

plasmaFluxInMsg

PlasmaFluxMsgPayload

plasma environment input message containing the energy grid and particle flux distributions used to compute ambient electron/ion collection currents and yield-weighted emission currents

scStateInMsgs

SCStatesMsgPayload

vector of spacecraft state input messages; entries are appended via addSpacecraft()

eBeamInMsgs

ElectronBeamMsgPayload

vector of electron beam parameter input messages (optional). If a spacecraft’s beam message is linked, its gun parameters are read from the message and used in beam-coupled charging terms

voltOutMsgs

VoltMsgPayload

output vector of equilibrium spacecraft potentials (voltage), one per spacecraft

currentsOutMsgs

ScChargingCurrentsMsgPayload

output vector of per-spacecraft current-component breakdowns used in the equilibrium evaluation (ambient, beam, and total terms)

scSunlitAreaInMsgs

ScSunlitFacetAreaMsgPayload

vector of optional sunlit facet area input messages, one per spacecraft. If linked and written, this overrides the configured per-spacecraft default or fallback sunlit area used in charging calculations.

Detailed Module Description

Overview: zero net current equilibrium

The module computes equilibrium potential(s) by requiring the total current to each spacecraft to be zero:

\[I_{\mathrm{tot}}(\phi) = \sum_k I_k(\phi) = 0\]

For the servicer/target problem with electron beam emission and impact, the total currents for the servicer and target are broken down into the terms in the following section and the equilibrium is solved by root-finding these current-balance equations numerically.

A note on implementation style

Hammerl (2024) presents closed-form expressions for Maxwellian environments (e.g., ambient collection currents) and also defines yield-weighted current forms that can be evaluated from an energy distribution. The Basilisk implementation uses the same energy-shifted flux structure but evaluates currents with:

  • linear interpolation of tabulated flux/yield curves

  • trapezoidal integration (trapz()) over a specified energy interval

This approach is intended to mimic the behavior of the analytical model while allowing non-Maxwellian or numerically provided flux distributions.

Ambient collection and emission currents

Plasma electron collection current

The implementation evaluates the plasma electron collection current directly from the tabulated electron flux distribution \(F_e(E)\) using an energy-shifted integral. This is consistent with the flux-transform structure used in yield-weighted current expressions (Eq. (5) in [Hammerl2024]), but here it is applied to the collection current itself.

The current is computed as:

\[I_e(\phi) = -q\,A \int_{E_{\min}}^{E_{\max}} \left(\frac{E}{E-\phi}\right)\,F_e(E-\phi)\,dE\]

where \(A\) is the area exposed to plasma, \(q\) is the elementary charge, and \(F_e(E)\) is the electron flux distribution provided by plasmaFluxInMsg.

Numerical details (as implemented)
  • The integrand used in code is:

    (E/(E - phi)) * getFlux(E - phi, "electron")
    
  • The integration is performed by trapezoidal quadrature (trapz).

  • The integration bounds are chosen to keep the shifted argument \((E-\phi)\) inside the tabulated energy range and to avoid evaluating too close to the singular point:

    • If \(\phi < 0\), bounds are approximately:

      \[E_{\min} \approx 0.1,\quad E_{\max} \approx E_{\mathrm{grid,max}}\]
    • If \(\phi \ge 0\), bounds are shifted upward:

      \[E_{\min} \approx 0.1 + |\phi|,\quad E_{\max} \approx E_{\mathrm{grid,max}} + |\phi|\]

This numerical choice is designed to mimic the potential-shift behavior of the analytical model while remaining stable for arbitrary tabulated flux distributions.

Plasma ion collection current

The ion collection current is computed in the same numerical style using the tabulated ion flux distribution \(F_i(E)\):

\[I_i(\phi) = +q\,A \int_{E_{\min}}^{E_{\max}} \left(\frac{E}{E+\phi}\right)\,F_i(E+\phi)\,dE\]
Numerical details (as implemented)
  • The integrand used in code is:

    (E/(E + phi)) * getFlux(E + phi, "ion")
    
  • The bounds are chosen so that \((E+\phi)\) remains within the tabulated range:

    • If \(\phi > 0\):

      \[E_{\min} \approx 0.1,\quad E_{\max} \approx E_{\mathrm{grid,max}}\]
    • If \(\phi \le 0\):

      \[E_{\min} \approx 0.1 + |\phi|,\quad E_{\max} \approx E_{\mathrm{grid,max}} + |\phi|\]

These bounds mirror the logic in the implementation and help avoid evaluating near \(E+\phi=0\).

Secondary electron emission due to ambient electrons

SEE current due to ambient electrons is computed by weighting the electron flux by the electron SEE yield curve and applying the same energy-shift/Jacobian factor. This corresponds to the yield-weighting structure described in [Hammerl2024] (Eq. (5) and the related discussion), evaluated numerically:

\[I_{\mathrm{SEE,e}}(\phi) = q\,A \int Y_e(E)\left(\frac{E}{E-\phi}\right)\,F_e(E-\phi)\,dE\]

For \(\phi>0\), the emitted secondaries can be recollected, and the implementation applies an exponential suppression factor consistent with the form used in Hammerl (Eq. (3) in [Hammerl2024]):

\[I_{\mathrm{SEE,e}}(\phi>0) = I_{\mathrm{SEE,e}}(\phi)\exp\!\left(-\frac{\phi}{T_{\mathrm{SEE}}}\right)\]

where secondaryElectronTemperature is the model parameter for secondary electron temperature.

Secondary electron emission due to ambient ions

The ion-driven SEE current is evaluated using the tabulated ion yield curve:

\[I_{\mathrm{SEE,i}}(\phi) = q\,A \int Y_i(E)\left(\frac{E}{E+\phi}\right)\,F_i(E+\phi)\,dE\]

and uses the same \(\exp(-\phi/T_{\mathrm{SEE}})\) suppression for \(\phi>0\).

Electron backscattering current due to ambient electrons

Backscattering due to ambient electrons is computed using the backscatter yield curve with the same shifted-flux structure:

\[I_{\mathrm{BS}}(\phi) = q\,A \int Y_{\mathrm{BS}}(E)\left(\frac{E}{E-\phi}\right)\,F_e(E-\phi)\,dE\]

and applies \(\exp(-\phi/T_{\mathrm{BS}})\) suppression for \(\phi>0\), where backscatterElectronTemperature is the corresponding model parameter.

Photoelectric current

The photoelectric current is implemented in a standard piecewise form (Eq. (10) in [Hammerl2024]), with the underlying functional form commonly referenced to spacecraft charging texts such as [Lai2011]:

\[\begin{split}I_{\mathrm{ph}}(\phi) = \begin{cases} j_{\mathrm{ph},0}\,A_{\mathrm{sunlit}}, & \phi \le 0 \\ j_{\mathrm{ph},0}\,A_{\mathrm{sunlit}} \exp\!\left(-\dfrac{\phi}{T_{\mathrm{ph}}}\right), & \phi > 0 \end{cases}\end{split}\]

In code, photoelectronFlux corresponds to \(j_{\mathrm{ph},0}\) and photoelectronTemperature corresponds to \(T_{\mathrm{ph}}\).

Electron beam coupling currents

Effective energy for beam-induced yields

Beam electrons arriving at the target use the effective (landing) energy defined by the potential difference (Eq. (8) in [Hammerl2024]):

\[E_{\mathrm{eff}} = E_{\mathrm{EB}} - \phi_S + \phi_T\]

This value is used when evaluating yield curves for beam-induced SEE and backscattering.

Electron beam current on the target

The target beam current follows Hammerl’s reachability condition and exponential turn-on (Eq. (11) in [Hammerl2024]):

\[\begin{split}I_{\mathrm{EB,T}}(\phi_T,\phi_S) = \begin{cases} -\alpha I_{\mathrm{EB}}\left(1-\exp\!\left(-\dfrac{E_{\mathrm{EB}}-\phi_S+\phi_T}{T_{\mathrm{EB}}}\right)\right), & E_{\mathrm{EB}} > \phi_S-\phi_T \\ 0, & E_{\mathrm{EB}} \le \phi_S-\phi_T \end{cases}\end{split}\]

where \(\alpha\) is modeled as a geometry factor representing the fraction of Ebeam current reaching the target (provided as alphaEB in the message payload, constrained to \([0,1]\) at runtime), and \(T_{\mathrm{EB}}\) is represented by the model parameter beamElectronTemperature.

Electron beam current on the servicer

The servicer beam current uses the corresponding form (Eq. (13) in [Hammerl2024]):

\[\begin{split}I_{\mathrm{EB,S}}(\phi_T,\phi_S) = \begin{cases} I_{\mathrm{EB}}\left(1-\exp\!\left(-\dfrac{E_{\mathrm{EB}}-\phi_S+\phi_T}{T_{\mathrm{EB}}}\right)\right), & E_{\mathrm{EB}} > \phi_S-\phi_T \\ 0, & E_{\mathrm{EB}} \le \phi_S-\phi_T \end{cases}\end{split}\]

Beam-induced SEE and backscattering on the target

Beam-induced SEE and backscattering are implemented by evaluating the yield at \(E_{\mathrm{eff}}\) and scaling by the magnitude of incoming target beam current:

\[I_{\mathrm{SEE,eb}} \approx Y_e(E_{\mathrm{eff}})\,\lvert I_{\mathrm{EB,T}}\rvert,\qquad I_{\mathrm{BS,eb}} \approx Y_{\mathrm{BS}}(E_{\mathrm{eff}})\,\lvert I_{\mathrm{EB,T}}\rvert\]
Implementation note:

Hammerl (2024) includes a recollection factor for emitted secondaries for \(\phi_T \ge 0\) (see Eq. (12) in [Hammerl2024]). The current implementation uses yield-scaling directly; adding an explicit \(\exp(-\phi_T/T_{\mathrm{SEE}})\) factor is straightforward future work if tighter agreement is required.

Servicer/target equilibrium solve workflow

The implementation uses a servicer-first sequential solve that follows the modeling workflow used in this module:

\[I_{\mathrm{tot,S}}(\phi_S;\phi_{T,\mathrm{ref}})=0,\qquad I_{\mathrm{tot,T}}(\phi_T;\phi_S)=0\]

The implementation solves these sequentially:

  1. Solve the servicer equilibrium potential \(\phi_S\) by finding the root of the servicer total-current function, using \(\phi_{T,\mathrm{ref}} = 0\,\mathrm{V}\) in the servicer beam term.

  2. Fix \(\phi_S\) and solve the target equilibrium potential \(\phi_T\) by finding the root of the target total-current function.

  3. Publish the resulting potentials to voltOutMsgs.

This sequential approach keeps the servicer and target solves internally consistent with the implemented current expressions, while the specific numerical details (integration bounds, discretization, and bracketing choices) are selected to be stable for tabulated flux inputs.

Numerical utilities

Linear interpolation (interp)

Fluxes and yields are evaluated at arbitrary energies using linear interpolation over the tabulated energy grid. Negative values resulting from extrapolation are clamped to zero in getFlux() and getYield() to avoid nonphysical contributions.

Trapezoidal integration (trapz)

Current integrals are evaluated using trapezoidal quadrature:

\[\int_a^b f(x)\,dx \approx h\left(\frac{1}{2}f(a)+\sum_{i=1}^{N-1}f(a+i h)+\frac{1}{2}f(b)\right),\quad h = \frac{b-a}{N}\]

The implementation includes checks for finite bounds and non-degenerate intervals.

User Guide

Creating and adding the module

from Basilisk.simulation import spacecraftChargingEquilibrium
from Basilisk.utilities import SimulationBaseClass, macros

sim = SimulationBaseClass.SimBaseClass()
proc = sim.CreateNewProcess("proc")
task = sim.CreateNewTask("task", macros.sec2nano(1.0))
proc.addTask(task)

chg = spacecraftChargingEquilibrium.SpacecraftChargingEquilibrium()
chg.ModelTag = "spacecraftChargingEquilibrium"
sim.AddModelToTask(task.Name, chg)

Connecting the plasma environment

chg.plasmaFluxInMsg.subscribeTo(plasmaMsg)

Adding spacecraft (servicer first, target second)

The coupled-beam logic assumes:

  • scStateInMsgs[0] is the servicer

  • scStateInMsgs[1] is the target

chg.addSpacecraft(scServicer.scStateOutMsg)   # index 0
chg.addSpacecraft(scTarget.scStateOutMsg)     # index 1

Connecting electron beam parameters

Create and publish an ElectronBeamMsgPayload and connect it to the desired spacecraft index. Most coupled runs connect the beam parameters on the servicer (index 0):

from Basilisk.architecture import messaging

beamPayload = messaging.ElectronBeamMsgPayload()
beamPayload.energyEB  = 20000.0   # [eV]
beamPayload.currentEB = 1.0e-6    # [A]
beamPayload.alphaEB   = 1.0       # fraction of Ebeam current reaching the target

beamMsg = messaging.ElectronBeamMsg().write(beamPayload)
chg.eBeamInMsgs[0].subscribeTo(beamMsg)

If the beam message is not linked, the spacecraft is treated as not emitting an electron beam.

Configuring optional model parameters

The module provides setters for configurable defaults and numerical settings:

Default construction values

The table below summarizes the main defaults used at construction time.

Module Default Values

Quantity

Default

How to change

enableDebugPrints

False

setEnableDebugPrints(bool)

Surface area used in current equations

50.264 m^2 (4*pi*r^2 for r = 2 m)

setSurfaceAreaDefault(double)

Sunlit-area fallback

0.0 m^2

setSunlitAreaFallback(double)

Per-spacecraft sunlit-area defaults

unset (NaN sentinel)

setSunlitAreaDefault(index, area) / clearSunlitAreaDefault(index)

Root solve lower/upper bracket

[-4.0e5, 4.0e5] V

setRootSolveBounds(lower, upper)

Servicer solve target reference potential

0.0 V

fixed internal default

Bisection tolerance (servicer / target)

1e-6 V / 1e-8 V

fixed internal defaults

Trapezoidal integration bins

1000

setTrapzBins(int)

Minimum integration energy

0.1 eV

fixed internal default

Photoelectron flux

40e-6 A/m^2

setPhotoelectronFlux(double)

Photoelectron temperature

2.0 eV

setPhotoelectronTemperature(double)

Secondary-electron temperature

5.0 eV

setSecondaryElectronTemperature(double)

Backscatter-electron temperature

5.0 eV

setBackscatterElectronTemperature(double)

Beam-electron temperature

20.0 eV

setBeamElectronTemperature(double)

Electron gun defaults (per spacecraft)

currentEB=0.0 A, energyEB=0.0 eV, alphaEB=1.0

via linked ElectronBeamMsgPayload input

Yield tables (electron, ion, backscatter)

empty vectors at construction

setYieldSEEelectron, setYieldSEEion, setYieldBackscattered

# Optional per-spacecraft sunlit-area defaults [m^2]
chg.setSunlitAreaDefault(0, 12.0)
chg.setSunlitAreaDefault(1, 10.0)

# Optional fallback used only if no message and no per-spacecraft default is provided
chg.setSunlitAreaFallback(0.0)

# Optional bisection brackets [V]
chg.setRootSolveBounds(-4.0e5, 4.0e5)

# Optional environmental model constants (defaults shown)
chg.setPhotoelectronFlux(40e-6)
chg.setPhotoelectronTemperature(2.0)
chg.setSecondaryElectronTemperature(5.0)
chg.setBackscatterElectronTemperature(5.0)
chg.setBeamElectronTemperature(20.0)

# Optional trapezoidal integration resolution
chg.setTrapzBins(1000)

Logging output voltages

servicerVoltRec = chg.voltOutMsgs[0].recorder()
targetVoltRec   = chg.voltOutMsgs[1].recorder()

sim.AddModelToTask(task.Name, servicerVoltRec)
sim.AddModelToTask(task.Name, targetVoltRec)

Logging output current components

servicerCurrRec = chg.currentsOutMsgs[0].recorder()
targetCurrRec   = chg.currentsOutMsgs[1].recorder()

sim.AddModelToTask(task.Name, servicerCurrRec)
sim.AddModelToTask(task.Name, targetCurrRec)

Running the simulation

sim.InitializeSimulation()
sim.ExecuteSimulation()

References

[Hammerl2024] (1,2,3,4,5,6,7,8,9)

Hammerl, J., and Schaub, H., “Coupled Spacecraft Charging Due to Continuous Electron Beam Emission and Impact,” 2024. (Equation numbers referenced in this document correspond to that paper.)

[Lai2011]

Lai, S. T., Fundamentals of Spacecraft Charging, Princeton Univ. Press, Princeton, NJ, 2011.

[Hippler2001]

Hippler, R., Pfau, S., Schmidt, M., and Schoenbach, K. H., Low Temperature Plasma Physics: Fundamental Aspects and Applications, Wiley, Hoboken, NJ, 2001.

[DavisMandell2016]

Davis, V. A., and Mandell, M. J., “NASCAP-2K Version 4.3 Scientific Documentation,” AFRL-RV-PS-TR-2017-0001, 2016.

[DraineSalpeter1979]

Draine, B. T., and Salpeter, E. E., “On the Physics of Dust Grains in Hot Gas,” Astrophysical Journal, Vol. 231, 1979, pp. 77–94.

[RomeroCalvo2022]

Romero-Calvo, Á., Cano-Gómez, G., and Schaub, H., “Simulation and Uncertainty Quantification of Electron Beams in Active Spacecraft Charging Scenarios,” 2022.


class SpacecraftChargingEquilibrium : public SysModel
#include <spacecraftChargingEquilibrium.h>

This module computes coupled equilibrium electric potentials for exactly two spacecraft (servicer index 0 and target index 1).

Public Functions

SpacecraftChargingEquilibrium()

Constructor.

This is the constructor for the module class.

~SpacecraftChargingEquilibrium()

Destructor.

Module Destructor

void Reset(uint64_t CurrentSimNanos) override

Reset module state and validate required inputs.

This method is used to reset the module and checks that required input messages are connected.

Parameters:

CurrentSimNanos – current simulation time in nano-seconds

void UpdateState(uint64_t CurrentSimNanos) override

Update module outputs by solving coupled equilibrium potentials.

This method updates the state of the module

Parameters:

CurrentSimNanos – current simulation time in nano-seconds

void addSpacecraft(Message<SCStatesMsgPayload> *tmpScMsg)

Add one spacecraft state input. Exactly two spacecraft are required.

This method adds a spacecraft to the charging model. Exactly two spacecraft can be added: index 0 = servicer, index 1 = target.

Parameters:

tmpScMsg – spacecraft state message (index 0: servicer, index 1: target)

void setEnableDebugPrints(bool enabled)

Enable or disable verbose debug prints in UpdateState().

bool getEnableDebugPrints() const

Return whether verbose debug prints are enabled.

void setYieldSEEelectron(const Eigen::VectorXd &yieldVector)

Set electron-impact SEE yield table aligned with the plasma energy grid.

void setYieldSEEion(const Eigen::VectorXd &yieldVector)

Set ion-impact SEE yield table aligned with the plasma energy grid.

void setYieldBackscattered(const Eigen::VectorXd &yieldVector)

Set backscatter yield table aligned with the plasma energy grid.

Eigen::VectorXd getYieldSEEelectron() const

Get the configured electron-impact SEE yield table.

Eigen::VectorXd getYieldSEEion() const

Get the configured ion-impact SEE yield table.

Eigen::VectorXd getYieldBackscattered() const

Get the configured backscatter yield table.

void setSunlitAreaDefault(unsigned int spacecraftIndex, double sunlitArea)

Set optional default sunlit area [m^2] for one spacecraft index.

double getSunlitAreaDefault(unsigned int spacecraftIndex) const

Get optional default sunlit area [m^2] for one spacecraft index.

void clearSunlitAreaDefault(unsigned int spacecraftIndex)

Clear optional default sunlit area for one spacecraft index.

void setSunlitAreaFallback(double sunlitArea)

Set fallback sunlit area [m^2] used when message/default are not available.

double getSunlitAreaFallback() const

Get fallback sunlit area [m^2].

void setRootSolveBounds(double lowerBound, double upperBound)

Set lower/upper [V] root-bracket bounds used by bisection solves.

double getRootSolveLowerBound() const

Get lower [V] root-bracket bound used by bisection solves.

double getRootSolveUpperBound() const

Get upper [V] root-bracket bound used by bisection solves.

void setSurfaceAreaDefault(double area)

Set default plasma-exposed spacecraft area [m^2].

double getSurfaceAreaDefault() const

Get default plasma-exposed spacecraft area [m^2].

void setPhotoelectronFlux(double photoelectronFluxIn)

Set nominal photoelectron flux [A/m^2].

double getPhotoelectronFlux() const

Get nominal photoelectron flux [A/m^2].

void setPhotoelectronTemperature(double photoelectronTemperatureIn)

Set photoelectron characteristic energy [eV].

double getPhotoelectronTemperature() const

Get photoelectron characteristic energy [eV].

void setSecondaryElectronTemperature(double secondaryElectronTemperatureIn)

Set secondary-electron characteristic energy [eV].

double getSecondaryElectronTemperature() const

Get secondary-electron characteristic energy [eV].

void setBackscatterElectronTemperature(double backscatterElectronTemperatureIn)

Set backscatter-electron characteristic energy [eV].

double getBackscatterElectronTemperature() const

Get backscatter-electron characteristic energy [eV].

void setBeamElectronTemperature(double beamElectronTemperatureIn)

Set beam electron characteristic energy [eV] for exponential turn-on.

double getBeamElectronTemperature() const

Get beam electron characteristic energy [eV] for exponential turn-on.

void setTrapzBins(int trapzBinsIn)

Set number of trapezoids used by numerical integration.

int getTrapzBins() const

Get number of trapezoids used by numerical integration.

Public Members

std::vector<ReadFunctor<SCStatesMsgPayload>> scStateInMsgs

spacecraft state input messages

ReadFunctor<PlasmaFluxMsgPayload> plasmaFluxInMsg

plasma flux input message

std::vector<ReadFunctor<ElectronBeamMsgPayload>> eBeamInMsgs

optional electron beam parameters

std::vector<ReadFunctor<ScSunlitFacetAreaMsgPayload>> scSunlitAreaInMsgs

optional sunlit area input messages

std::vector<Message<VoltMsgPayload>*> voltOutMsgs

spacecraft equilibrium potential output messages

std::vector<Message<ScChargingCurrentsMsgPayload>*> currentsOutMsgs

spacecraft current-term output messages

BSKLogger bskLogger

Basilisk logging interface.

Private Functions

void readMessages()

Read in the input messages

Returns:

void

bool validateSolveConfiguration()
double electronCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the electron current

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma [m^2]

Returns:

double

double ionCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the ion current

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma [m^2]

Returns:

double

double SEEelectronCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the SEE current due to electrons

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma [m^2]

Returns:

double

double SEEionCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the SEE current due to ions

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma [m^2]

Returns:

double

double backscatteringCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the SEE current due to backscattering

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma [m^2]

Returns:

double

double photoelectricCurrent(double phi, double A)

This function takes in a given potential and area value and calculates the current due to the photoelectric effect

Parameters:
  • phi – double defining value for spacecraft potential

  • A – double defining value for area exposed to plasma

Returns:

double

double electronBeamCurrent(double phiS, double phiT, const std::string &craftType, double EEB, double IEB, double alphaEB)
double SEEelectronBeamCurrent(double phiS, double phiT, double EEB, double IEB, double alphaEB)
double electronBeamBackscattering(double phiS, double phiT, double EEB, double IEB, double alphaEB)
double interp(Eigen::VectorXd &xVector, Eigen::VectorXd &yVector, double x)

This function takes in a given set of discrete data points and an x-value and performs linear interpolation to compute the corresponding y-value.

Parameters:
  • xVector – vector containing the independent variable data points

  • yVector – vector containing the dependent variable data points

  • x – x-value at which the data is linearly interpolated

Returns:

interpolated y-value

double trapz(std::function<double(double)> &f, double a, double b, int N)

This function computes the integral of the passed function using trapezoidal integration

Parameters:
  • f – function to compute the integral of

  • a – lower limit of integration

  • b – upper limit of integration

  • N – number of trapezoids to use

Returns:

double

double getFlux(double E, const std::string &particleType)

This function returns the flux type for a given energy and impacting particle type

Parameters:
  • E – energy of interest [eV]

  • particleType – particle of interest (“electron” or “ion”)

Returns:

double

double getYield(double E, const std::string &yieldType)

This function returns the yield for a given energy and yield type

Parameters:
  • E – energy of interest [eV]

  • yieldType – yield of interest (“electron”, “ion”, “backscattered”)

Returns:

double

Private Members

std::vector<Eigen::Vector3d> r_BN_NList

[m] inertial position vectors for each spacecraft

std::vector<Eigen::MRPd> sigma_BNList

[-] MRP attitude vectors for each spacecraft

Eigen::VectorXd energies

[eV] plasma energy bins

Eigen::VectorXd electronFlux

[cm^-2 s^-1 sr^-2 eV^-1] ambient electron flux spectrum

Eigen::VectorXd ionFlux

[cm^-2 s^-1 sr^-2 eV^-1] ambient ion flux spectrum

unsigned int numSat = 0

number of spacecraft configured through addSpacecraft()

Eigen::VectorXd yieldSEEelectron

[-] electron-impact SEE yield table

Eigen::VectorXd yieldSEEion

[-] ion-impact SEE yield table

Eigen::VectorXd yieldBackscattered

[-] backscatter yield table

std::vector<double> scSunlitAreaDefaults

[m^2] optional per-spacecraft sunlit-area defaults

std::vector<bool> scSunlitAreaWarned

warn-once latch for missing sunlit area

bool enableDebugPrints = false

toggles verbose UpdateState diagnostics

double elementaryCharge = 1.60217663e-19

[C] elementary charge

int trapzBins = 1000

[-] trapezoids used by trapz integration

double minIntegrationEnergy = 0.1

[eV] lower baseline bound used in current integrals

double photoelectronFlux = 40e-6

[A/m^2] photoelectron current density at non-positive potential

double photoelectronTemperature = 2.0

[eV] photoelectron characteristic energy

double secondaryElectronTemperature = 5.0

[eV] secondary-electron emission characteristic energy

double backscatterElectronTemperature = 5.0

[eV] backscatter emission characteristic energy

double beamElectronTemperature = 20.0

[eV] beam turn-on characteristic energy

double defaultSurfaceArea = 50.264

[m^2] default spacecraft plasma-exposed area

double sunlitAreaFallback = 0.0

[m^2] fallback sunlit area when neither message nor default exists

double rootSolveLowerBound = -400000.0

[V] lower bracket for bisection equilibrium solve

double rootSolveUpperBound = 400000.0

[V] upper bracket for bisection equilibrium solve

double servicerSolveAccuracy = 1e-6

[V] bisection tolerance for servicer equilibrium

double targetSolveAccuracy = 1e-8

[V] bisection tolerance for target equilibrium

struct ElectronGunConfig

Public Members

double alphaEB = 1.0

[-] fraction of beam current reaching target

double currentEB = 0.0

[A] beam current magnitude

double energyEB = 0.0

[eV] beam energy

struct ChargingSpacecraftState

Public Members

double A = 0.0

[m^2] plasma-exposed area

double A_sunlit = 0.0

[m^2] sunlit area used for photoelectric current

bool emitsEB = false

true if e-beam message is linked for this spacecraft

ElectronGunConfig electronGun

e-beam configuration for this spacecraft