Package SatStress :: Module SatStress
[frames] | no frames]

Module SatStress

source code

A framework for calculating the surface stresses at a particular place and time on a satellite resulting from one or more tidal potentials.

1 Input and Output

Because SatStress is a "library" module, it doesn't do a lot of input and output - it's mostly about doing calculations. It does need to read in the specification of a Satellite object though, and it can write the same kind of specification out. To do this, it uses name-value files, and a function called nvf2dict, which creates a Python dictionary (or "associative array").

A name-value file is just a file containing a bunch of name-value pairs, like:

 ORBIT_ECCENTRICITY = 0.0094   # e must be < 0.25

It can also contain comments to enhance human readability (anything following a '#' on a line is ignored, as with the note in the line above).

2 Satellites

Obviously if we want to calculate the stresses on the surface of a satellite, we need to define the satellite, this is what the Satellite object does.

2.1 Specifying a Satellite

In order to specify a satellite, we need:

From a few basic inputs, we can calculate many derived characteristics, such as the satellite's orbital period or the surface gravity.

The internal structure and material properties are specified by a series of concentric spherical shells (layers), each one being homogeneous throughout its extent. Given the densities and thicknesses of the these layers, we can calculate the satellite's overall size, mass, density, etc.

Specifying a tidal forcing may be simple or complex. For instance, the Diurnal forcing depends only on the orbital eccentricity (and other orbital parameters already supplied), and the NSR forcing requires only the addition of the non-synchronous rotation period of the shell. Specifying an arbitrary true polar wander trajectory would be much more complex.

For the moment, becuase we are only including simple forcings, their specifying parameters are read in from the satellite definition file. If more, and more complex forcings are eventually added to the model, their specification will probably be split into a separate input file.

2.2 Internal Structure and Love Numbers

SatStress treats the solid portions of the satellite as viscoelastic Maxwell solids, that respond differently to forcings having different frequencies (ω). Given the a specification of the internal structure and material properties of a satellite as a series of layers, and information about the tidal forcings the body is subject to, it's possible to calculate appropriate Love numbers, which describe how the body responds to a change in the gravitational potential.

Currently the calculation of Love numbers is done by an external program written in Fortran by John Wahr and others, with roots reaching deep into the Dark Ages of computing. As that code (or another Love number code) is more closely integrated with the model, the internal structure of the satellite will become more flexible, but for the moment, we are limited to assuming a 4-layer structure:

3 Stresses

SatStress can calculate the following stress fields:

  1. Diurnal: stresses arising from an eccentric orbit, having a forcing frequency equal to the orbital frequency.
  2. NSR: stresses arising due to the faster-than-synchronous rotation of a floating shell that is decoupled from the satellite's interior by a fluid layer (an ocean).

The expressions defining these stress fields are derived in "Modeling Stresses on Satellites due to Non-Synchronous Rotation and Orbital Eccentricity Using Gravitational Potential Theory" (preprint, 15MB PDF) by Wahr et al. (submitted to Icarus, in March, 2008).

3.1 Stress Fields Live in StressDef Objects

Each of the above stress fields is defined by a similarly named StressDef object. These objects contain the formulae necessary to calculate the surface stress. The expressions for the stresses depend on many parameters which are defined within the Satellite object, and so to create a StressDef object, you need to provide a Satellite object.

There are many formulae which are identical for both the NSR and Diurnal stress fields, and so instead of duplicating them in both classes, they reside in the StressDef base class, from which all StressDef objects inherit many properties.

The main requirement for each StressDef object is that it must define the three components of the stress tensor τ:

3.2 Stress Calculations are Performed by StressCalc Objects

Once you've instantiated a StressDef object, or several of them (one for each stress you want to include), you can compose them together into a StressCalc object, which will actually do calculations at given points on the surface, and given times, and return a 2x2 matrix containing the resulting stress tensor (each component of which is the sum of all of the corresponding components of the stress fields that were used to instantiated the StressCalc object).

This is (hopefully) easier than it sounds. With the following few lines, you can construct a satellite, do a single calculation on its surface, and see what it looks like:

>>> from SatStress.SatStress import *
>>> the_sat = Satellite(open("input/Europa.satellite"))
>>> the_stresses = StressCalc([Diurnal(the_sat), NSR(the_sat)])
>>> Tau = the_stresses.tensor(theta=pi/4.0, phi=pi/3.0, t=10000)
>>> print(Tau)

The test program included in the SatStress distribution shows a slightly more complex example, which should be enough to get you started using the package.

3.3 Extending the Model

Other stress fields can (and hopefully will!), be added easily, so long as they use the same mathematical definition of the membrane stress tensor (τ), as a function of co-latitude (θ) (measured south from the north pole), east-positive longitude (φ), measured from the meridian on the satellite which passes through the point on the satellite directly beneath the parent planet (assuming a synchronously rotating satellite), and time (t), defined as seconds elapsed since pericenter.

This module could also potentially be extended to also calculate the surface strain (ε) and displacement (s) fields, or to calculate the stresses at any point within the satellite.

Classes
  Satellite
An object describing the physical structure and context of a satellite.
  SatLayer
An object describing a uniform material layer within a satellite.
  LoveNum
A container class for the complex Love numbers: h2, k2, and l2.
  StressDef
A base class from which particular tidal stress field objects descend.
  NSR
An object defining the stress field which arises from the non-synchronous rotation (NSR) of a satellite's icy shell.
  Diurnal
An object defining the stress field that arises on a satellite due to an eccentric orbit.
  StressCalc
An object which calculates the stresses on the surface of a Satellite that result from one or more stress fields.
    Exceptions (error handling classes)
  Error
Base class for errors within the SatStress module.
  NameValueFileError
Base class for errors related to NAME=VALUE style input files.
  NameValueFileParseError
Indicates a poorly formatted NAME=VALUE files.
  NameValueFileDuplicateNameError
Indicates multiple copies of the same name in an input file.
  SatelliteParamError
Indicates a problem with the Satellite initialization.
  MissingSatelliteParamError
Indicates a required parameter was not found in the input file.
  InvalidSatelliteParamError
Raised when a required parameter is not found in the input file.
  LargeEccentricityError
Raised when satellite orbital eccentricity is > 0.25
  NegativeNSRPeriodError
Raised if the satellite's NSR period is less than zero
  ExcessiveSatelliteMassError
Raised if the satellite's parent planet is less than 10x as massive as the satellite.
  LoveLayerNumberError
Raised if the number of layers specified in the satellite definition file is incompatible with the Love number code.
  InvalidLoveNumberError
Raised if the Love numbers are found to be suspicious.
  LoveExcessiveDeltaError
Raised when Δ > 10^9 for any of the ice layers, at which point the Love number code becomes unreliable.
  GravitationallyUnstableSatelliteError
Raised if the density of layers is found not to decrease as you move toward the surface from the center of the satellite.
  NonNumberSatelliteParamError
Indicates that a non-numeric value was found for a numerical parameter.
  LowLayerDensityError
Indicates that a layer has been assigned an unrealistically low density.
  LowLayerThicknessError
Indicates that a layer has been given too small of a thickness
  NegativeLayerParamError
Indicates a layer has been given an unphysical material property.
Functions
dict
nvf2dict(nvf, comment='#')
Reads from a file object listing name value pairs, creating and returning a corresponding Python dictionary.
source code
Function Details

nvf2dict(nvf, comment='#')

source code 

Reads from a file object listing name value pairs, creating and returning a corresponding Python dictionary.

The file should contain a series of name value pairs, one per line separated by the '=' character, with names on the left and values on the right. Blank lines are ignored, as are lines beginning with the comment character (assumed to be the pound or hash character '#', unless otherwise specified). End of line comments are also allowed. String values should not be quoted in the file. Names are case sensitive.

Returns a Python dictionary that uses the names as keys and the values as values, and so all Python limitations on what can be used as a dictionary key apply to the name fields.

Leading and trailing whitespace is stripped from all names and values, and all values are returned as strings.

Parameters:
  • nvf (file) - an open file object from which to read the name value pairs
  • comment (str) - character which begins comments
Returns: dict
a dictionary containing the name value pairs read in from nvf.
Raises:
  • NameValueFileParseError - if a non-comment input line does not contain an '=' character, or if a non-comment line has nothing but whitespace preceeding or following the '=' character.
  • NameValueFileDuplicateNameError - if more than one instance of the same name is found in the input file nvf.