cape.dkit.dbfm: Specialized force & moment DataKits

This module provides customizations of cape.dkit.rdb that are especially useful for launch vehicle force & moment databases. The force & moment coefficient names follow common missile naming conventions:

Name

Symbol

Description

CA

CA

Axial force

CY

CY

Side force

CN

CN

Normal force

CLL

C

Rolling moment

CLM

Cm

Pitching moment

CLN

Cn

Yawing moment

class cape.dkit.dbfm.DBFM(fname=None, **kw)

Database class for launch vehicle force & moment

Call:
>>> db = dbfm.DBFM(fname=None, **kw)
Inputs:
fname: {None} | str

File name; extension is used to guess data format

csv: {None} | str

Explicit file name for CSVFile read

textdata: {None} | str

Explicit file name for TextDataFile

simplecsv: {None} | str

Explicit file name for CSVSimple

xls: {None} | str

File name for XLSFile

mat: {None} | str

File name for MATFile

Outputs:
db: cape.dkit.dbfm.DBFM

LV force & moment database

Versions:
  • 2020-03-20 @ddalle: First version

create_fm_combo(comps, comp=None, **kw)

Calculate and save combined F & M on several components

Call:
>>> fm = db.create_fm_combo(comps, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with analysis tools

comps: list[str]

List of components to combine

comp: {None} | str

Optional name of output assembled component

Lref: {1.0} | float

Reference length

xMRP: {0.0} | float

Moment reference point x-coordinate

yMRP: {0.0} | float

Moment reference point y-coordinate

zMRP: {0.0} | float

Moment reference point z-coordinate

CompFMCols: dict[dict]

Names for CA, CY, etc. for each comp (defaults to "<comp>.CA", etc.)

CompX: dict[float]

Force application point for each comp

CompY: dict[float]

Force application point for each comp

Compz: dict[float]

Force application point for each comp

FMCols: dict[str]

Names of force & moment columns for output

mask: {None} | np.ndarray

Mask or indices of which cases to include in POD calculation

method: {"trapz"} | "left" | callable

Integration method used to integrate columns

Outputs:
fm: dict[np.ndarray]

Integrated force/moment for each coefficient

fm[coeff]: np.ndarray

Combined coeff for each coeff

Versions:
  • 2020-06-19 @ddalle: First version

create_target_deltafm(db2, **kw)

Evaluate a target force and moment database

Call:
>>> dfm = db.create_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

DeltaCols: {{}} | dict[str]

Names of columns to save deltas as; default takes form of "CA.delta", etc.

SourceCols: {{}} | dict[str]

Columns in db to compare to target

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
dfm: dict[np.ndarray]

Differences between evaluated TargetCols in db2 minus SourceCols looked up from db

Versions:
  • 2020-06-16 @ddalle: First version

create_target_fm(db2, mask=None, **kw)

Evaluate and save a target force and moment database

Call:
>>> fm = db.create_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

TargetSaveCols: {{}} | dict[str]

Names to use when saving evaluated forces; default is "CA.target", etc.

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
fm: dict[np.ndarray]

Evaluated force & moment coefficients from db2 at conditions described by db and I

Versions:
  • 2020-06-15 @ddalle: First version

genr8_fm_combo(comps, **kw)

Calculate combined force & moment on several components

Call:
>>> fm = db.genr8_fm_combo(comps, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with analysis tools

comps: list[str]

List of components to combine

Lref: {1.0} | float

Reference length

xMRP: {0.0} | float

Moment reference point x-coordinate

yMRP: {0.0} | float

Moment reference point y-coordinate

zMRP: {0.0} | float

Moment reference point z-coordinate

CompFMCols: dict[dict]

Names for CA, CY, etc. for each comp (defaults to "<comp>.CA", etc.)

CompX: dict[float]

Force application point for each comp

CompY: dict[float]

Force application point for each comp

Compz: dict[float]

Force application point for each comp

mask: {None} | np.ndarray

Mask or indices of which cases to include in POD calculation

method: {"trapz"} | "left" | callable

Integration method used to integrate columns

Outputs:
fm: dict[np.ndarray]

Integrated force/moment for each coefficient

fm[coeff]: np.ndarray

Combined coeff for each coeff

Versions:
  • 2020-06-19 @ddalle: First version

genr8_target_deltafm(db2, **kw)

Evaluate a target force and moment database

Call:
>>> dfm = db.genr8_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

SourceCols: {{}} | dict[str]

Columns in db to compare to target

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
dfm: dict[np.ndarray]

Differences between evaluated TargetCols in db2 minus SourceCols looked up from db

Versions:
  • 2020-06-16 @ddalle: First version

genr8_target_fm(db2, mask=None, **kw)

Evaluate a target force and moment database

Call:
>>> fm = db.genr8_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
fm: dict[np.ndarray]

Evaluated force & moment coefficients from db2 at conditions described by db and I

Versions:
  • 2020-06-15 @ddalle: First version

make_CLMX()

Build and save evaluators for CLMX cols

Call:
>>> db.make_CLMX()
Inputs:
db: cape.dkit.dbfm.DBFM

LV force & moment database

Versions:
  • 2020-03-26 @ddalle: First version

make_CLNX()

Build and save evaluators for CLNX cols

Call:
>>> db.make_CLNX()
Inputs:
db: cape.dkit.dbfm.DBFM

LV force & moment database

Versions:
  • 2020-03-26 @ddalle: First version

make_UCLMX()

Build and save evaluators for UCLMX cols

Call:
>>> db.make_UCLMX()
Inputs:
db: cape.dkit.dbfm.DBFM

LV force & moment database

Versions:
  • 2020-05-04 @ddalle: First version

make_UCLNX()

Build and save evaluators for UCLNX cols

Call:
>>> db.make_UCLNX()
Inputs:
db: cape.dkit.dbfm.DBFM

LV force & moment database

Versions:
  • 2020-05-04 @ddalle: First version

make_fm_combo(comps, comp=None, **kw)

Get [and calculate] combined F & M on several components

Call:
>>> fm = db.make_fm_combo(comps, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with analysis tools

comps: list[str]

List of components to combine

comp: {None} | str

Optional name of output assembled component

Lref: {1.0} | float

Reference length

xMRP: {0.0} | float

Moment reference point x-coordinate

yMRP: {0.0} | float

Moment reference point y-coordinate

zMRP: {0.0} | float

Moment reference point z-coordinate

CompFMCols: dict[dict]

Names for CA, CY, etc. for each comp (defaults to "<comp>.CA", etc.)

CompX: dict[float]

Force application point for each comp

CompY: dict[float]

Force application point for each comp

Compz: dict[float]

Force application point for each comp

FMCols: dict[str]

Names of force & moment columns for output

mask: {None} | np.ndarray

Mask or indices of which cases to include in POD calculation

method: {"trapz"} | "left" | callable

Integration method used to integrate columns

Outputs:
fm: dict[np.ndarray]

Integrated force/moment for each coefficient

fm[coeff]: np.ndarray

Combined coeff for each coeff

Versions:
  • 2020-06-19 @ddalle: First version

make_target_deltafm(db2, **kw)

Evaluate a target force and moment database

Call:
>>> dfm = db.make_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

DeltaCols: {{}} | dict[str]

Names of columns to save deltas as; default takes form of "CA.delta", etc.

SourceCols: {{}} | dict[str]

Columns in db to compare to target

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
dfm: dict[np.ndarray]

Differences between evaluated TargetCols in db2 minus SourceCols looked up from db

Versions:
  • 2020-06-16 @ddalle: First version

make_target_fm(db2, mask=None, **kw)

Evaluate and save a target force and moment database

Call:
>>> fm = db.make_target_fm(db2, mask, **kw)
Inputs:
db: cape.dkit.dbfm.DBFM

Database with force & moment responses

db2: cape.dkit.dbfm.DBFM

Database with force & moment responses

mask: {None} | np.ndarray

Mask of bool or indices of which cases in db to evaluate; conditions in db used to evaluate db2

TargetCols: {{}} | dict[str]

Name of db2 col for CA, CY, …, CLN

TargetSaveCols: {{}} | dict[str]

Names to use when saving evaluated forces; default is "CA.target", etc.

Translators: {{}} | dict[str]

Alternate names of response arg columns; e.g. if Translators["MACH"] == "mach", that means db2["MACH"] is analogous to db["mach"]

Outputs:
fm: dict[np.ndarray]

Evaluated force & moment coefficients from db2 at conditions described by db and I

Versions:
  • 2020-06-15 @ddalle: First version

cape.dkit.dbfm.convert_alpha(*a, **kw)

Determine angle of attack from kwargs

All keyword args are listed by "Tag". For example, instead of alpha, the user may also use ALPHA, aoa, or any col in AeroDataKit._tagcols[“alpha”].

Call:
>>> alpha = convert_alpha(*a, **kw)
Inputs:
a: tuple

Positional args; discarded here

alpha: float | np.ndarray

Direct alias from _alph_cols

aoap: float | np.ndarray

Total angle of attack [deg]

phip: {0.0} | float | np.ndarray

Vertical-to-wind roll angle [deg]

aoav: float | np.ndarray

Missile-axis angle of attack [deg]

phiv: {0.0} | float | np.ndarray

Missile-axis roll angle [deg]

Outputs:
alpha: None | float | np.ndarray

Angle of attack [deg]

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-19 @ddalle: Using AeroDataKit

cape.dkit.dbfm.convert_aoap(*a, **kw)

Determine total angle of attack from kwargs

All keyword args are listed by "Tag". For example, instead of alpha, the user may also use ALPHA, aoa, or any col in AeroDataKit._tagcols[“alpha”].

Call:
>>> aoap = convert_aoap(*a, **kw)
Inputs:
a: tuple

Positional args; discarded here

aoap: float | np.ndarray

Total angle of attack [deg]

alpha: float | np.ndarray

Angle of attack [deg]

beta: float | np.ndarray

Direct alias from _alph_cols

aoav: float | np.ndarray

Missile-axis angle of attack [deg]

phiv: {0.0} | float | np.ndarray

Missile-axis roll angle [deg]

Outputs:
aoap: float | np.ndarray

Total angle of attack [deg]

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-19 @ddalle: Using AeroDataKit

cape.dkit.dbfm.convert_beta(*a, **kw)

Determine sideslip angle from kwargs

All keyword args are listed by "Tag". For example, instead of alpha, the user may also use ALPHA, aoa, or any col in AeroDataKit._tagcols[“alpha”].

Call:
>>> beta = convert_beta(*a, **kw)
Inputs:
a: tuple

Positional args; discarded here

beta: float | np.ndarray

Direct alias from _alph_cols

aoap: float | np.ndarray

Total angle of attack [deg]

phip: {0.0} | float | np.ndarray

Vertical-to-wind roll angle [deg]

aoav: float | np.ndarray

Missile-axis angle of attack [deg]

phiv: {0.0} | float | np.ndarray

Missile-axis roll angle [deg]

Outputs:
beta: float | np.ndarray

Sideslip angle [deg]

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-19 @ddalle: Using AeroDataKit

cape.dkit.dbfm.convert_phip(*a, **kw)

Determine body-to-wind roll angle from kwargs

All keyword args are listed by "Tag". For example, instead of alpha, the user may also use ALPHA, aoa, or any col in AeroDataKit._tagcols[“alpha”].

Call:
>>> phip = convert_phip(*a, **kw)
Inputs:
a: tuple

Positional args; discarded here

phip: {0.0} | float | np.ndarray

Vertical-to-wind roll angle [deg]

alpha: float | np.ndarray

Angle of attack [deg]

beta: float | np.ndarray

Direct alias from _alph_cols

aoav: float | np.ndarray

Missile-axis angle of attack [deg]

phiv: {0.0} | float | np.ndarray

Missile-axis roll angle [deg]

Outputs:
phip: {0.0} | float | np.ndarray

Vertical-to-wind roll angle [deg]

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-19 @ddalle: Using AeroDataKit

cape.dkit.dbfm.estimate_xCLM(self, DCLM, DCN)

Estimate reference x for UCLM calculations

Call:
>>> xCLM = estimate_xCLM(self, DCLM, DCN)
Inputs:
self: DBFM

Force & moment database with self.xMRP and self.Lref

DCLM: np.ndarray[float]

Deltas between two databases’ CLM values

DCN: np.ndarray[float]

Deltas between two databases’ CN values

Outputs:
xCLM: float

Reference x that minimizes UCLM

Versions:
  • 2019-02-20 @ddalle: First version

  • 2020-05-04 @ddalle: Copied from dkit.fm

cape.dkit.dbfm.estimate_xCLN(self, DCLN, DCY)

Estimate reference x for UCLN calculations

Call:
>>> xCLN = estimate_xCLN(self, DCLN, DCY)
Inputs:
self: DBFM

Force & moment database with self.xMRP and self.Lref

DCLN: np.ndarray[float]

Deltas between two databases’ CLN values

DCY: np.ndarray[float]

Deltas between two databases’ CY values

Outputs:
xCLN: float

Reference x that minimizes UCLN

Versions:
  • 2019-02-20 @ddalle: First version

  • 2020-05-04 @ddalle: Copied from dkit.fm

cape.dkit.dbfm.eval_CLMX(db, col1, col2, *a, **kw)

Evaluate CLM about arbitrary x moment reference point

Call:
>>> CLMX = eval_CLMX(db, col1, col2, *a, **kw)
Inputs:
db: DBFM

Force & moment data kit

col1: "CLM" | str

Name of pitching moment column

col2: "CN" | str

Name of normal force column

a: tuple

Arguments to call db("CLM", *a) [plus xMRP]

kw: dict

Keywords used as alternate definition of a

Outputs:
CLMX: float | np.ndarray

Pitching moment about arbitrary xMRP

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-20 @ddalle: DataKit version

  • 2020-03-25 @ddalle: Added col1, col2 args

cape.dkit.dbfm.eval_CLNX(db, col1, col2, *a, **kw)

Evaluate CLN about arbitrary x moment reference point

Call:
>>> CLNX = eval_CLNX(db, col1, col2, *a, **kw)
Inputs:
db: DBFM

Force & moment data kit

col1: "CLN" | str

Name of yawing moment column

col2: "CY" | str

Name of side force column

a: tuple

Arguments to call FM("CLM", *a) [plus xMRP]

kw: dict

Keywords used as alternate definition of a

Outputs:
CLNX: float | np.ndarray

Pitching moment about arbitrary xMRP

Versions:
  • 2019-02-28 @ddalle: First version

  • 2020-03-20 @ddalle: DataKit version

cape.dkit.dbfm.eval_UCLMX(db, col1, col2, col3, *a, **kw)

Evaluate UCLM about arbitrary x moment reference point

Call:
>>> UCLMX = eval_UCLMX(db, col1, col2, col3, *a, **kw)
Inputs:
db: DBFM

Force & moment data kit

col1: "UCLM" | str

Name of pitching moment uncertainty column

col2: "UCN" | str

Name of normal force uncertainty column

col3: "xCLM" | str

Name of UCLM reference MRP column

a: tuple

Arguments to call FM(col1, *a) [plus xMRP]

kw: dict

Keywords used as alternate definition of a

Outputs:
UCLMX: float | np.ndarray

Pitching moment uncertainty about arbitrary xMRP

Versions:
  • 2019-03-13 @ddalle: First version

  • 2020-03-20 @ddalle: DataKit version

  • 2020-03-26 @ddalle: Added col args

cape.dkit.dbfm.eval_UCLNX(db, col1, col2, col3, *a, **kw)

Evaluate UCLN about arbitrary x moment reference point

Call:
>>> UCLNX = eval_UCLNX(db, col1, col2, col3, *a, **kw)
Inputs:
db: DBFM

Force & moment data kit

col1: "UCLN" | str

Name of yawing moment uncertainty column

col2: "UCY" | str

Name of side force uncertainty column

col3: "xCLN" | str

Name of UCLN reference MRP column

a: tuple

Arguments to call FM(col1, *a) [plus xMRP]

kw: dict

Keywords used as alternate definition of a

Outputs:
UCLNX: float | np.ndarray

Pitching moment uncertainty about arbitrary xMRP

Versions:
  • 2019-03-13 @ddalle: First version

  • 2020-03-20 @ddalle: DataKit version

cape.dkit.dbfm.genr8_fCLMX(col1='CLM', col2='CLN')

Generate an evaluator for CLMX with specified cols

Call:
>>> func = genr8_fCLMX(col1="CLM", col2="CN")
Inputs:
col1: {"CLM"} | str

Name of CLM column to evaluate

col2: {"CN"} | str

Name of CN column to evaluate

Outputs:
func: function

Function to evaluate col1 about arbitrary xMRP

Output Call:
>>> CLMX = func(db, *a, **kw)
Output Args:
db: DBFM

Force and moment data kit

a: tuple[float | np.ndarray]

Args to col1 and col2, plus optional xMRP

kw: dict

Keyword args to col1 and col2, plus optional xMRP

Versions:
  • 2020-03-26 @ddalle: First version

cape.dkit.dbfm.genr8_fCLNX(col1='CLN', col2='CY')

Generate an evaluator for CLNX with specified cols

Call:
>>> func = genr8_fCLNX(col1="CLN", col2="CN")
Inputs:
col1: {"CLN"} | str

Name of yawing moment column

col2: {"CY"} | str

Name of side force column

Outputs:
func: function

Function to evaluate col1 about arbitrary xMRP

Output Call:
>>> CLNX = func(db, *a, **kw)
Output Args:
db: DBFM

Force and moment data kit

a: tuple[float | np.ndarray]

Args to col1 and col2, plus optional xMRP

kw: dict

Keyword args to col1 and col2, plus optional xMRP

Versions:
  • 2020-03-26 @ddalle: First version

cape.dkit.dbfm.genr8_fUCLMX(col1='UCLM', col2='UCN', col3='xCLM')

Generate an evaluator for UCLMX with specified cols

Call:
>>> func = genr8_fUCLMX(col1="UCLM", col2="UCN", col3="xCLM")
Inputs:
col1: "UCLM" | str

Name of pitching moment uncertainty column

col2: "UCN" | str

Name of normal force uncertainty column

col3: "xCLM" | str

Name of UCLM reference MRP column

Outputs:
func: function

Function to evaluate col1 about arbitrary xMRP

Output Call:
>>> UCLMX = func(db, *a, **kw)
Output Args:
db: DBFM

Force and moment data kit

a: tuple[float | np.ndarray]

Args to col1, plus optional xMRP

kw: dict

Keyword args to col1, plus optional xMRP

Versions:
  • 2020-03-26 @ddalle: First version

cape.dkit.dbfm.genr8_fUCLNX(col1='UCLN', col2='UCY', col3='xCLN')

Generate an evaluator for UCLNX with specified cols

Call:
>>> func = genr8_fUCLNX(col1="UCLN", col2="UCY", col3="xCLN")
Inputs:
col1: "UCLN" | str

Name of yawing moment uncertainty column

col2: "UCY" | str

Name of side force uncertainty column

col3: "xCLN" | str

Name of UCLN reference MRP column

Outputs:
func: function

Function to evaluate col1 about arbitrary xMRP

Output Call:
>>> UCLNX = func(db, *a, **kw)
Output Args:
db: DBFM

Force and moment data kit

a: tuple[float | np.ndarray]

Args to col1, plus optional xMRP

kw: dict

Keyword args to col1, plus optional xMRP

Versions:
  • 2020-03-26 @ddalle: First version