cape.tri: Surface triangulation module

This module provides the utilities for interacting with Cart3D or Plot3D type triangulations, including annotated triangulations (including .triq files). Triangulations can also be read from several other formats, including UH3D, UNV, and AFLR3 surf formats.

The module consists of individual classes that are built off of a base triangulation class TriBase. Methods that are written for the TriBase class apply to all other classes as well.

Some triangulation methods are written in Python/C using the cape._cape module. For some repeated tasks (especially writing triangulations to file), creating a compiled version can lead to significant time savings. These are relatively simple to compile, but fall-back methods are provided using purely Python code in each case. The convention used for this situation is to provide a method like TriBase.WriteFast() for the compiled version and TriBase.WriteSlow() for the Python version.

Base triangulation module

class cape.tri.TriBase(fname=None, c=None, tri=None, uh3d=None, surf=None, unv=None, cgns=None, xml=None, json=None, mixsur=None, uh3dc=None, nNode=None, Nodes=None, nTri=None, Tris=None, nQuad=None, Quads=None, CompID=None)

Cape base triangulation class

This class provides an interface for a basic triangulation without surface data. It can be created either by reading an ASCII file or specifying the data directly.

When no component numbers are specified, the object created will label all triangles 1.

Call:
>>> tri = cape.tri.TriBase(fname=fname, c=None)
>>> tri = cape.tri.TriBase(uh3d=uh3d, c=None)
>>> tri = cape.tri.TriBase(Nodes=Nodes, Tris=Tris, CompID=CompID)
Inputs:
fname: str

Name of triangulation file to read (format based on extension)

tri: str

Name of triangulation file (Cart3D TRI format)

uh3d: str

Name of triangulation file (UH3D format)

c: str

Name of configuration file (e.g. Config.xml)

nNode: int

Number of nodes in triangulation

Nodes: np.ndarray (float), (nNode, 3)

Matrix of x,y,z-coordinates of each node

nTri: int

Number of triangles in triangulation

Tris: np.ndarray (int), (nTri, 3)

Indices of triangle vertex nodes

CompID: np.ndarray (int), (nTri)

Component number for each triangle

Data members:
tri.nNode: int

Number of nodes in triangulation

tri.Nodes: np.ndarray (float), (nNode, 3)

Matrix of x,y,z-coordinates of each node

tri.nTri: int

Number of triangles in triangulation

tri.Tris: np.ndarray (int), (nTri, 3)

Indices of triangle vertex nodes

tri.CompID: np.ndarray (int), (nTri)

Component number for each triangle

Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2014-06-02 @ddalle: Added UH3D reading capability

  • 2015-11-19 @ddalle: Added AFLR3 surface capability

Add(tri)

Add a second triangulation file.

If the new triangulation begins with a component ID less than the maximum component ID of the existing triangulation, the components of the second triangulation are offset. For example, if both triangulations have components 1, 2, and 3; the IDs of the second triangulation, tri2, will be changed to 4, 5, and 6.

No checks are performed, and intersections are not analyzed.

Call:
>>> tri.Add(tri2)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be altered

tri2: cape.tri.Tri

Triangulation instance to be added to the first

Effects:

All nodes and triangles from tri2 are added to tri. As a result, the number of nodes, number of tris, and number of components in tri will all increase.

Versions:
  • 2014-06-12 @ddalle: Version 1.0

  • 2014-10-03 @ddalle: Auto detect CompID overlap

AddRawCompID(tri, warn=False, newnodes=True)

Add a second triangulation to the current one without changing component numbers of either triangulation. No checks are performed, and intersections are not analyzed.

Call:
>>> tri.AddRawCompID(tri2, warn=False, newnodes=True)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be altered

tri2: cape.tri.Tri

Triangulation instance to be added to the first

warn: True | {False}

Whether or not to warn about components in both

newnodes: {True} | False

If False, do not add nodes of second triangulation

Effects:

All nodes and triangles from tri2 are added to tri. As a result, the number of nodes, number of tris, and number of components in tri will all increase.

Versions:
  • 2014-06-12 @ddalle: Version 1.0

  • 2019-06-17 @ddalle: Added newnodes keyword

ApplyConfig(cfg)

Change component IDs to match a configuration file

Any component that is named in tri.Conf and cfg.faces has its component ID changed to match its intended value in cfg, which is an interface to Config.xml files. Note that tri.Conf is only created if the triangulation is read from a UH3D file.

For example, if tri has a component 'Body' that initially has component ID of 4, but the user wants that component ID to instead be 104, then tri.Conf['Body'] will be 4, and cfg.faces['Body'] will be 104. The result of applying this method is that all faces in tri.compID that are labeled with a 4 will get changed to 104.

This process uses a working copy of tri to avoid problems with the order of changing the component numbers.

Call:
>>> tri.ApplyConfig(cfg)
>>> tri.ApplyConfig(fcfg)
Inputs:
tri: cape.tri.Tri

Triangulation instance

cfg: cape.config.Config

Configuration instance

fcfg: str

Name of XML config file

Versions:
  • 2014-11-10 @ddalle: Version 1.0

Copy()

Copy a triangulation and unlink it

Call:
>>> tri2 = tri.Copy()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Outputs:
tri2: cape.tri.Tri

Triangulation with same values as tri but not linked

Versions:
  • 2014-06-12 @ddalle: Version 1.0

ExtractMappedComps(tric, comps=None, **kw)

Map component names from a template tri and write component files

Call:
>>> tris = tri.ExtractMappedComps(tric, comps=[], **kw)
>>> triu = tri.ExtractMappedComps(tric, comps=[], join=True, **kw)
Inputs:
tri: cape.tri.Tri | cape.tri.Triq

Triangulation or annotated triangulation instance

tric: cape.tri.Tri

Triangulation with alternative component labels

comps: list (str)

List of tric faces to write

join: True | {False}

Return a single triangulation with all comps

Outputs:
tris: dict (cape.tri.Tri)

Dictionary of triangulations for each comp in comps

triu: cape.tri.Tri

Single joined triangulation if join is True

Versions:
  • 2016-02-10 @ddalle: Version 1.0

FilterTrisBBox(bbox)

Get the list of Tris in a specified rectangular prism

Call:
>>> K = tri.FilterTrisBBox(bbox)
>>> K = tri.FilterTrisBBox([xmin, xmax, ymin, ymax, zmin, zmax])
Inputs:
tri: cape.tri.Tri

Triangulation instance

bbox: list | np.ndarray

List of minimum and maximum coordinates

Outputs:
K: np.ndarray (int)

List of 1-based tri numbers that intersect BBox

Versions:
  • 2017-02-17 @ddalle: Version 1.0

FindNeighbors(k)

Find the triangles neighboring one triangle

Call:
>>> k0, k1, k2 = tri.FindNeighbors(k)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

k: int > 0

Triangle index [1-based]

Outputs:
K: np.ndarray[int]

Neighboring triangles of k

k0: int >= 0

Triangle index sharing edge 1 of triangle k

k1: int >= 0

Triangle index sharing edge 1 of triangle k

k2: int >= 0

Triangle index sharing edge 1 of triangle k

Versions:
  • 2019-06-20 @ddalle: Version 1.0

FindTriFromEdge(i0, i1)

Find the triangle index from a specified edge

Call:
>>> k = tri.FindTriFromEdge(i0, i1)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

i0: int > 0

Edge start node index [1-based]

i1: int > 0

Edge end node index [1-based]

Outputs:
k: int >= 0

Triangle index containing edge i0 -> i1 [1-based], if no match, returns 0

Versions:
  • 2019-06-20 @ddalle: Version 1.0

GetAreaVectors()

Get the normals and areas of each triangle

Call:
>>> tri.GetAreaVectors()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Effects:
tri.AreaVectors: ndarray, shape=(tri.nTri,)

Area of each triangle is created

tri.Normals: ndarray, shape=(tri.nTri,3)

Unit normal for each triangle is saved

Versions:
  • 2014-06-12 @ddalle: Version 1.0

  • 2016-01-23 @ddalle: Added a check before calculating

GetBasisVectors()

Get a right-handed coordinate basis for all triangles

Call:
>>> tri.GetBasisVectors()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Effects:
tri.e1: np.ndarray (float, shape=(nTri,3))

Unit vector pointing from node 1 to node 2 of each tri

tri.e2: np.ndarray (float, shape=(nTri,3))

Unit vector completing right-handed coordinate system

tri.e3: np.ndarray (float, shape=(nTri,3))

Unit normal of each triangle

Versions:
  • 2017-02-09 @ddalle: Version 1.0

GetCenters()

Get the centroids of each triangle

Call:
>>> tri.GetCenters()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Attributes:
tri.Centers: np.ndarray (float shape=(nTri,3))

Center of each triangle

Versions:
  • 2017-02-09 @ddalle: Version 1.0

GetClosestNode(x)

Get the index of a node closest to a 3D point

Call:
>>> i, L = tri.GetClosestNode(x)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

x: np.ndarray shape=(3,)

Coordinates of a point

Outputs:
i: int

Index of closest node (1-based) to point x

L: float

Value of the distance

Versions:
  • 2016-09-29 @ddalle: Version 1.0

GetCompArea(compID=None, n=None)

Get the total area of a component, or get the total area of a component projected to a plane with a given normal vector.

Call:
>>> A = tri.GetCompArea(compID)
>>> A = tri.GetCompArea(compID, n)
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: {None} | int

Index of the component of which to find the area

n: numpy.ndarray

Unit normal vector to use for projection

Outputs:
A: float

Area of the component

Versions:
  • 2014-06-13 @ddalle: Version 1.0

GetCompAreaVector(compID, n=None)

Get the total area of a component, or get the total area of a component projected to a plane with a given normal vector.

Call:
>>> A = tri.GetCompArea(compID)
>>> A = tri.GetCompArea(compID, n)
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: int

Index of the component of which to find the area

n: numpy.ndarray

Unit normal vector to use for projection

Outputs:
A: float

Area of the component

Versions:
  • 2014-06-13 @ddalle: Version 1.0

GetCompBBox(compID=None, **kwargs)

Find a bounding box based on the coordinates of a specified component or list of components, with an optional buffer or buffers in each direction

Call:
>>> xlim = tri.GetCompBBox(compID, **kwargs)
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: {None} | int | str | list

Component or list of components to use for bounding box; if None return bounding box for entire triangulation

pad: float

Buffer to add in each dimension to min and max coordinates

xpad: float

Buffer to minimum and maximum x-coordinates

ypad: float

Buffer to minimum and maximum y-coordinates

zpad: float

Buffer to minimum and maximum z-coordinates

xp: float

Buffer for the maximum x-coordinate

xm: float

Buffer for the minimum x-coordinate

yp: float

Buffer for the maximum y-coordinate

ym: float

Buffer for the minimum y-coordinate

zp: float

Buffer for the maximum z-coordinate

zm: float

Buffer for the minimum z-coordinate

Outputs:
xlim: numpy.ndarray (float), shape=(6,)

List of xmin, xmax, ymin, ymax, zmin, zmax

Versions:
  • 2014-06-16 @ddalle: Version 1.0

  • 2014-08-03 @ddalle: Changed “buff” –> “pad”

  • 2017-02-08 @ddalle: CompID None gets BBox for full tri

GetCompCentroid(compID)

Get the centroid of a component

Call:
>>> [x, y] = tri.GetCompCentroid(compID)
>>> [x, y, z] = tri.GetCompCentroid(compID)
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: int

Index of the component of which to find the normal

Outputs:
x: float

Coordinate of the centroid

y: float

Coordinate of the centroid

z: float

Coordinate of the centroid

Versions:
  • 2016-03-29 @ddalle: Version 1.0

GetCompID(face=None)

Get components by name or number

Call:
>>> compID = tri.GetCompID()
>>> compID = tri.GetCompID(face)
>>> compID = tri.GetCompID(comp)
>>> compID = tri.GetCompID(comps)
Inputs:
tri: cape.tri.Tri

Triangulation interface

face: str

Component name

comp: int

Component ID

comps: list (int | str)

List of component names or IDs

Outputs:
compID: list (int)

List of component IDs

Versions:
  • 2014-10-12 @ddalle: Version 1.0

  • 2016-03-29 @ddalle: Edited docstring

  • 2017-02-10 @ddalle: Added fallback to tri.Conf

GetCompName(compID)

Get the name of a component by its number

Call:
>>> face = tri.GetCompName(compID)
Inputs:
tri: cape.tri.Tri

Triangulation interface

compID: int

Component ID number

Outputs:
face: {""} | str

Name of so-numbered component, if any

Versions:
  • 2017-03-30 @ddalle: Version 1.0

GetCompNormal(compID)

Get the area-averaged unit normal of a component

Call:
>>> n = tri.GetCompNormal(compID)
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: int

Index of the component of which to find the normal

Outputs:
n: numpy.ndarray shape=(3,)

Area-averaged unit normal

Versions:
  • 2014-06-13 @ddalle: Version 1.0

GetCompProjectedArea(nhat, compID=None, ds=None, **kw)

Get projected area of a component(s)

Call:
>>> L = tri.GetCompProjectedArea(compID, **kw)
Inputs:
nhat: np.ndarray[float]

Projection vector [nx, ny, nz]

compID: {None} | int | str

Component or list of components to use for area projection; if``None`` return projected area for entire triangulation

ds: float

Resolution of projection plane

img: {None} | str

Optional file name for projection figure

Outputs:
A: float

Projected area

Versions:
  • 2020-11-05 @dschauer: Version 1.0

  • 2020-11-13 @ddalle: Version 2.0
    • Vectorized masking of projected plane

    • Driven by triangles instead of grid

  • 2020-11-20 @ddalle: Version 2.1
    • Remove debug hooks

    • Add img for output fig generation

    • Clean up unit vectors and docstring

GetCompScale(compID=None, **kw)

Get diagonal length of bounding box of a component(s)

Call:
>>> L = tri.GetCompScale(compID, **kw)
Inputs:
compID: {None} | int | str | list

Component or list of components to use for bounding box; if None return bounding box for entire triangulation

pad: float

Buffer to add in each dimension to min and max coordinates

kw: dict

Keyword arguments passed to GetCompBBox()

Outputs:
L: nonnegative float

Length of the diagonal of the bounding box

Versions:
  • 2017-02-08 @ddalle: Version 1.0

GetConfCompID(face=None)

Get components by name or number from tri.Conf dictionary

Call:
>>> compID = tri.GetConfCompID()
>>> compID = tri.GetConfCompID(face)
>>> compID = tri.GetConfCompID(comp)
>>> compID = tri.GetConfCompID(comps)
Inputs:
tri: cape.tri.Tri

Triangulation interface

face: str

Component name

comp: int

Component ID

comps: list (int | str)

List of component names or IDs

Outputs:
compID: list (int)

List of component IDs

Versions:
  • 2017-02-10 @ddalle: Version 1.0

GetConfFromConfig()

Create tri.Conf dictionary using tri.config if appropriate

Call:
>>> tri.GetConfFromConfig()
Inputs:
tri: cape.tri.Tri

Triangulation interface

Attributes:
tri.Conf: dict

Dictionary of face names coped from tri.config.faces

Versions:
  • 2017-02-10 @ddalle: Version 1.0

  • 2022-10-27 @ddalle: Version 2.0; only single-component

GetEdgeTable()

Get the list of edges and triangle of origin

Call:
>>> tri.GetEdgeTable()
Inputs:
tri: cape.tri.TriBase

Triangulation instance

Effects:
tri.EdgeTable: np.ndarray, shape=(3*nTri, 3)

Array of node indices defining each edge

Versions:
  • 2019-06-20 @ddalle: Version 1.0

GetEdges()

Get the list of edges

Call:
>>> tri.GetEdges()
Inputs:
tri: cape.tri.TriBase

Triangulation instance

Effects:
tri.Edges: np.ndarray, shape=(3*nTri, 2)

Array of node indices defining each edge

Versions:
  • 2016-09-29 @ddalle: Version 1.0

GetFacesFromQuads(K, nmin=10)

Find components from triangles

Call:
>>> faces = tri.GetFacesFromQuads(K, nmin=10)
Inputs:
tri: cape.tri.Tri

Triangulation instance

K: np.ndarray[int]

Array of quadrilateral indices

nmin: {10} | int > 0

Only return faces with at least nmin triangles

Outputs:
faces: list[str]

List of face names (if available) or numbers

Versions:
  • 2019-05-14 @ddalle: Version 1.0

GetFacesFromTris(K, nmin=10)

Find components from triangles

Call:
>>> faces = tri.GetFacesFromTris(K, nmin=10)
Inputs:
tri: cape.tri.Tri

Triangulation instance

K: np.ndarray[int]

Array of triangle indices

nmin: {10} | int > 0

Only return faces with at least nmin triangles

Outputs:
faces: list[str]

List of face names (if available) or numbers

Versions:
  • 2019-05-14 @ddalle: Version 1.0

GetLengths()

Get the lengths of edges

Call:
>>> tri.GetLengths()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Effects:
tri.Lengths: numpy.ndarray, shape=(tri.nTri,3)

Length of edge of each triangle

Versions:
  • 2015-02-21 @ddalle: Version 1.0

GetNearestTri(x, n=4, **kw)

Get the triangle that is nearest to a point, and the distance

Call:
>>> T = tri.GetNearestTri(x, n=4, **kw)
Inputs:
tri: cape.tri.Tri

Triangulation instance

x: np.ndarray (float, shape=(3,))

Array of x, y, and z coordinates of test point

n: {4} | int

Number of tri components to search

ztol: {0.05} | positive float

Maximum extra projection distance

rztol: {_antol_} | positive float

Maximum relative projection distance

Outputs:
T: dict

Dictionary of match parameters

T[“k1”]: int

Index of triangle nearest to test point

T[“c1”]: int

Component ID of triangle k1

T[“d1”]: float

Distance from triangle k1 to test point

T[“z1”]: float

Projection distance of point to triangle k1

T[“t1”]: float

Tangential distance of point to triangle k1

T[“k2”]: None | int

Index of nearest triangle outside component c1

T[“c2”]: int

Component ID of triangle k2

T[“d2”]: float

Distance from triangle k2 to test point

T[“z2”]: float

Projection distance of point to triangle k2

T[“k3”]: None | int

Index of nearest trioutside components c1 and c2

T[“k4”]: None | int

Index of nearest trioutside components c1, c2, c3

Versions:
  • 2017-02-06 @ddalle: Version 1.0

  • 2017-02-07 @ddalle: Version 1.1; search for 2nd comp

  • 2017-02-08 @ddalle: Version 1.2; 3rd and 4th comp

GetNodeNormals()

Get the area-averaged normals at each node

Call:
>>> tri.GetNodeNormals()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Effects:
tri.NodeNormals: np.ndarray, shape=(tri.nNode,3)

Unit normal at each node averaged from neighboring triangles

Versions:
  • 2016-01-23 @ddalle: Version 1.0

GetNodesFromCompID(compID=None)

Find node indices from face component ID(s)

Call:
>>> i = tri.GetNodesFromCompID(comp)
>>> i = tri.GetNodesFromCompID(comps)
>>> i = tri.GetNodesFromCompID(compID)
Inputs:
tri: cape.tri.Tri

Triangulation instance

comp: str

Name of component

comps: list (int | str)

List of component IDs or names

compID: int

Component number

Outputs:
i: numpy.array (int)

Node indices, 0-based

Versions:
  • 2014-09-27 @ddalle: Version 1.0

GetNormals()

Get the normals and areas of each triangle

Call:
>>> tri.GetNormals()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Effects:
tri.Areas: ndarray, shape=(tri.nTri,)

Area of each triangle is created

tri.Normals: ndarray, shape=(tri.nTri,3)

Unit normal for each triangle is saved

Versions:
  • 2014-06-12 @ddalle: Version 1.0

  • 2016-01-23 @ddalle: Added a check before calculating

GetOutputFileType(**kw)

Determine output file type from keyword inputs

Many of the possible inputs are in conflict. For example, it is possible to use endian="big" and byteorder="little". In the input table below, any value that evaluates as True supersedes all inputs listed below it. For example, if ascii==True, no other inputs have any effect.

If none of the inputs is specified, the function will try to access tri.ext. If that does not exist, the default output is "ascii".

The default byte order is determined from os.sys.byteorder, but this is overridden if the environment variable $F_UFMTENDIAN is "big" or $GFORTRAN_CONVERT_UNIT is "big_endian".

The five possible outputs are described below.

ext

Description

"ascii"

Text file

"r4"

Big-endian, single-precision record

"lr4"

Little-endian, single-precision record

"r8"

Big-endian, double-precision record

"lr8"

Little-endian, double-precision record

"b4"

Big-endian, single-precision

"lb4"

Little-endian, single-precision

"b8"

Big-endian, double-precision

"lb8"

Little-endian, double-precision

Call:
>>> ext = tri.GetOutputFileType(**kw)
Inputs:
fmt: {None} | "ascii" | "b4" | "lb4"

Format specified by text

ascii: True | {False}

Whether or not to use ASCII (text file)

b4: True | {False}

Whether or not to use single-precision big-endian

lb4: True | {False}

Whether or not to use single-precision little-endian

b8: True | {False}

Whether or not to use double-precision big-endian

lb8: True | {False}

Whether or not to use double-precision little-endian

r4: True | {False}

Whether or not to use single-precision big-endian Fortran

lr4: True | {False}

Whether or not to use single-precision little-endian Fortran

r8: True | {False}

Whether or not to use double-precision big-endian Fortran

lr8: True | {False}

Whether or not to use double-precision little-endian Fortran

record, fortran: {True} | False

Whether or not to use Fortran-style record markers

byteorder, endian: "big" | "little" | {None}

Byte order

bytecount: 4 | 8 | {None}

Byte count, 4 for single precision is default

byteswap: True | False | {None}

Use byte order opposite to os.sys.byteorder

bin: True | False | {None}

Force binary output; can be used to get default binary format

dp: True | {False}

Use double-precision (default is single-precision)

sp: True | {False}

Use single-precision (no effect since default is single)

Outputs:
ext: {ascii} | b4 | b8 | lb4 | lb8

File type

Outputs:
  • 2016-10-02 @ddalle: Version 1.0

GetQuadsFromCompID(compID=None)

Find indices of triangles with specified component ID(s)

Call:
>>> k = tri.GetQuadsFromCompID(comp)
>>> k = tri.GetQuadsFromCompID(comps)
>>> k = tri.GetQuadsFromCompID(compID)
Inputs:
tri: cape.tri.Tri

Triangulation instance

comp: str

Name of component

comps: list (int | str)

List of component IDs or names

compID: int

Component number

Outputs:
k: numpy.ndarray (int, shape=(N,))

List of quad indices in requested component(s)

Versions:
  • 2016-04-05 @ddalle: Version 1.0

GetSubTri(i=None)

Get the portion of the triangulation that contains specified component ID(s).

Call:
>>> tri0 = tri.GetSubTri(i=None)
Inputs:
tri: cape.tri.Tri

Triangulation instance

i: int or list (int)

Component ID or list of component IDs

Outputs:
tri0: cape.tri.Tri

Copied triangulation containing only faces with CompID in i

Versions:
  • 2015-01-23 @ddalle: Version 1.0

GetTriFileType(fname)

Get the byte order and precision for a TRI file

The function works by setting attributes of the triangulation

Call:
>>> tri.GetTriFileType(fname)
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: str

Name of file to write

Attributes:
tri.filetype: {'ascii'} | 'binary'

File type

tri.byteorder: 'big' | 'little'

Endianness

tri.precision: 4 | 8

Number of bytes in one entry

Versions:
  • 2016-08-18 @ddalle: Version 1.0

GetTriNodes()

Get the nodal coordinates of each triangle

Call:
>>> tri.GetTriNodes()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Attributes:
tri.TriX: np.ndarray (float shape=(nTri,3))

x-coordinates of each node of each triangle

tri.TriY: np.ndarray (float shape=(nTri,3))

y-coordinates of each node of each triangle

tri.TriZ: np.ndarray (float shape=(nTri,3))

z-coordinates of each node of each triangle

Versions:
  • 2017-12-22 @ddalle: Version 1.0

GetTrisFromCompID(compID=None)

Find indices of triangles with specified component ID(s)

Call:
>>> k = tri.GetTrisFromCompID(comp)
>>> k = tri.GetTrisFromCompID(comps)
>>> k = tri.GetTrisFromCompID(compID)
Inputs:
tri: cape.tri.Tri

Triangulation instance

comp: str

Name of component

comps: list (int | str)

List of component IDs or names

compID: int

Component number

Outputs:
k: numpy.ndarray (int, shape=(N,))

List of triangle indices in requested component(s)

Versions:
  • 2015-01-23 @ddalle: Version 1.0

GetTrisFromNodes(I, skip=1)

Find indices of triangles from node indices

Call:
>>> K = tri.GetTrisFromNodes(I, skip=1)
Inputs:
tri: cape.tri.Tri

Triangulation instance

I: np.ndarray[int]

Array of node indices

skip: {1} | int > 0

Only analyze every skipth node

Outputs:
K: np.ndarray[int]

Array of triangle indices

Versions:
  • 2019-05-14 @ddalle: Version 1.0

MapBCs_AFLR3(compID=None, BCs={}, blds={}, bldel={})

Initialize and map boundary condition indices for AFLR3

Call:
>>> tri.MapBCs_AFLR3(compID=[], BCs={}, blds={}, bldel={})
Inputs:
tri: cape.tri.Tri

Triangulation instance

compID: list (str | int) | None

List of components to preserve order; defaults to BCs.keys()

BCs: dict (str | int)

Dictionary of BC flags for CompIDs or component names

blds: dict (str | int)

Dictionary of BL spacings for CompIDs or component names

bldel: dict (str | int)

Dictionary of BL thicknesses for CompIDs or component names

Versions:
  • 2015-11-19 @ddalle: Version 1.0

  • 2016-04-05 @ddalle: Added BL spacing and thickness

MapBCs_ConfigAFLR3()

Map boundary conditions from "Config.json" file format

Call:
>>> tri.MapBCs_ConfigAFLR3()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Versions:
  • 2016-10-21 @ddalle: Version 1.0

MapCompID(tric, tri0)

Map CompIDs from pre-intersected triangulation to an intersected triangulation. In standard cape terminology, this is a transformation from Components.o.tri to Components.i.tri

Call:
>>> tri.MapCompID(tric, tri0)
Inputs:
tri: cape.tri.Tri

Triangulation interface

tric: cape.tri.Tri

Full CompID breakdown prior to intersection

tri0: cape.tri.Tri

Input triangulation to intersect

Versions:
  • 2015-02-25 @ddalle: Version 1.0

MapSubCompID(tric, compID, kc=None)

Map CompID of each face to the CompID of the nearest face in another triangulation. This is a common step after running intersect.

Call:
>>> tri.MapSubCompID(tric, compID, iA=0, iB=-1)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

tric: cape.tri.TriBase

Triangulation with more desirable CompIDs to be copied

compID: int

Component ID to map from tric

k1: numpy.ndarray (int)

Indices of faces in tric to considerider

Versions:
  • 2015-02-24 @ddalle: Version 1.0

MapTriCompID(tri, **kw)

Map component IDs of a separate triangulation

Call:
>>> tri.MapTriCompID(tric, **kw)
Inputs:
tri: cape.tri.Tri

Triangulation instance

tric: cape.tri.Tri

Triangulation with alternative component labels

compID: {None} | int | str | list

Only consider tris in this component(s)

Versions:
  • 2017-02-09 @ddalle: Version 1.0

ParaviewPlot(fname, i=None, r='x', u='y')

Create a plot of the surface of one component using Paraview

Call:
>>> tri.ParaviewPlot(fname, i=None, r='x', u='y')
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Created file is '%s.png' % fname

i: str or int or list (int)

Component name, ID or list of component IDs

r: str | list (int)

Axis pointing to the right in plot

u: str | list (int)

Axis pointing upward in plot

Versions:
  • 2015-11-22 @ddalle: Version 1.0

Read(fname, n=1)

Read a triangulation file (from .tri or .triq file)

File type is automatically detected and may be any one of the following

  • ASCII

  • Double-precision little-endian Fortran unformatted

  • Single-precision little-endian Fortran unformatted

  • Double-precision big-endian Fortran unformatted

  • Single-precision big-endian Fortran unformatted

Call:
>>> tri.Read(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of triangulation file to read

Versions:
  • 2014-06-02 @ddalle: Version 1.0

ReadASCII(fname, n=1)

Read a triangulation file from an ASCII file

Call:
>>> tri.ReadASCII(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of triangulation file to read

n: {1} | int > 0

Number of iterations included in average (for triq files)

Versions:
  • 2014-06-02 @ddalle: Version 1.0

  • 2016-08-18 @ddalle: Moved from Read() to enable binary

ReadBCs_AFLR3(fname)

Initialize and map boundary condition indices for AFLR3 from file

Call:
>>> tri.ReadBCs_AFLR3(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of boundary condition map file

Versions:
  • 2015-11-19 @ddalle: Version 1.0

  • 2016-04-05 @ddalle: Added BL spacing and thickness

ReadBest(fname)

Read a file using the extension to guess format

Call:
>>> tri.ReadBest(fname)
Inputs:
tri: cape.tri.TriBase

Triangulation or unstructured surface mesh interface

fname: str

Name of file, use the extension to guess format

Versions:
  • 2016-10-21 @ddalle: Version 1.0

ReadCGNS(fname)

Read a surface triangulated (with optional quads) CGNS file

Call:
>>> tri.ReadCGNS(fname)
Inputs:
tri: cape.tri.Tri

Triangulation

fname: str

Name of file to read

Versions:
  • 2018-03-02 @ddalle: Version 1.0

ReadCompID(f)

Read component IDs from a .tri file.

Call:
>>> tri.ReadCompID(f)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: str

Open file handle

Effects:

Reads and creates tri.CompID if not at end of file. Otherwise all components are labeled 1.

Versions:
  • 2014-06-16 @ddalle: Version 1.0

ReadConfig(c)

Read a configuration file using extension to guess type

Call:
>>> tri.ReadConfig(c)
>>> tri.ReadConfig(cfg)
Inputs:
tri: cape.tri.Tri

Triangulation instance

c: str

Configuration file name

cfg: ConfigJSON | ConfigXML

Pre-existing configuration

Versions:
  • 2016-10-21 @ddalle: Version 1.0

  • 2022-03-17 @ddalle: Version 2.0; allow cfg input

ReadConfigJSON(c)

Read a JSON file labeling and grouping of component IDs

Call:
>>> tri.ReadConfigJSON(c)
Inputs:
tri: cape.tri.Tri

Triangulation instance

c: str

Configuration file name

Versions:
  • 2016-10-21 @ddalle: Version 1.0

ReadConfigMIXSUR(c)

Read a mixsur.i file labeling and grouping of component IDs

Call:
>>> tri.ReadConfigMixsur(c)
Inputs:
tri: cape.tri.Tri

Triangulation instance

c: str

Configuration file name

Versions:
  • 2017-04-05 @ddalle: Version 1.0

ReadConfigXML(c, restrict=False)

Read an XML file labeling and grouping of component IDs

Call:
>>> tri.ReadConfigXML(c, restrict=False)
Inputs:
tri: cape.tri.Tri

Triangulation instance

c: str

Configuration file name

restrict: True | {False}

Option to eliminate faces that are not present in triangulation

Versions:
  • 2015-11-19 @ddalle: Version 1.0

ReadNodes(f, nNode)

Read node coordinates from a .tri file.

Call:
>>> tri.ReadNodes(f, nNode)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nNode: int

Number of nodes to read

Effects:
tri.Nodes: np.ndarray (float) (nNode, 3)

Matrix of nodal coordinates

tri.blds: np.ndarray (float) (nNode,)

Vector of initial boundary layer spacings

tri.bldel: np.ndarray (float) (nNode,)

Vector of boundary layer thicknesses

f: file

File remains open

Versions:
  • 2014-06-16 @ddalle: Version 1.0

ReadNodesSurf(f, nNode)

Read node coordinates from an AFLR3 .surf file

Call:
>>> tri.ReadNodesSurf(f, nNode)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nNode: int

Number of tris to read

Effects:
tri.Nodes: np.ndarray (float) (nNode, 3)

Matrix of nodal coordinates

tri.blds: np.ndarray (float) (nNode,)

Vector of initial boundary layer spacings

tri.bldel: np.ndarray (float) (nNode,)

Vector of boundary layer thicknesses

f: file

File remains open

Versions:
  • 2016-04-05 @ddalle: Version 1.0

ReadQ(f, nNode, nq)

Read node states from a .triq file.

Call:
>>> triq.ReadQ(f, nNode, nq)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nNode: int

Number of nodes to read

nq: int

Number of state variables at each node

Effects:

Reads and creates tri.Nodes; file remains open.

Versions:
  • 2015-09-14 @ddalle: Version 1.0

ReadQuadsSurf(f, nQuad)

Read quad node indices, compIDs, and BCs from AFLR3 file

Call:
>>> tri.ReadQuadsSurf(f, nQuad)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nTri: int

Number of tris to read

Effects:
tri.Quads: np.ndarray (int) (nQuad, 4)

Matrix of nodal coordinates

tri.CompIDQuad: np.ndarray (int) (nQuad,)

Vector of component IDs for each quad

tri.BCsQuad: np.ndarray (int) (nQuad,)

Vector of boundary condition flags

f: file

File remains open

Versions:
  • 2016-04-05 @ddalle: Version 1.0

ReadSurf(fname)

Read an AFLR3 surface file

Call:
>>> tri.ReadUH3D(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of triangulation file to read

Versions:
  • 2014-06-02 @ddalle: Version 1.0

  • 2014-10-27 @ddalle: Added draft of reading component names

ReadTriBin(fname, ni=4, nf=4)

Read binary unformatted triangulation file

Call:
>>> tri.ReadTriBin(fname)
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-08-18 @ddalle: Version 1.0

ReadTriQ(fname, n=1)

Read an annotated triangulation file (.triq)

File type is automatically detected and may be any one of the following

  • ASCII

  • Double-precision little-endian Fortran unformatted

  • Single-precision little-endian Fortran unformatted

  • Double-precision big-endian Fortran unformatted

  • Single-precision big-endian Fortran unformatted

Call:
>>> tri.Read(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of triangulation file to read

n: {1} | positive int

Number of snapshots averaged into triq file

Versions:
  • 2017-01-11 @ddalle: Points to ReadTri()

ReadTris(f, nTri)

Read triangle node indices from a .tri file.

Call:
>>> tri.ReadTris(f, nTri)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nTri: int

Number of tris to read

Effects:

Reads and creates tri.Tris; file remains open.

Versions:
  • 2014-06-16 @ddalle: Version 1.0

ReadTrisSurf(f, nTri)

Read triangle node indices, comp IDs, and BCs from AFLR3 file

Call:
>>> tri.ReadTrisSurf(f, nTri)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

f: file

Open file handle

nTri: int

Number of tris to read

Effects:
tri.Tris: np.ndarray (int) (nTri, 3)

Matrix of nodal coordinates

tri.CompID: np.ndarray (int) (nTri,)

Vector of component IDs for each triangle

tri.BCs: np.ndarray (int) (nTri,)

Vector of boundary condition flags

f: file

File remains open

Versions:
  • 2016-04-05 @ddalle: Version 1.0

ReadUH3D(fname)

Read a triangulation file (from *.uh3d)

Call:
>>> tri.ReadUH3D(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of triangulation file to read

Versions:
  • 2014-06-02 @ddalle: Version 1.0

  • 2014-10-27 @ddalle: Added draft of reading component names

ReadUH3DCompIDList(fname)

Read a UH3D-like component list to tri.Conf

Call:
>>> tri.ReadUH3DCompIDList(fname)
>>> tri.ReadUH3DCompIDList(fid)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Name of component list file to read

fid: file

Already opened file handle from which to read component names

Versions:
ReadUnv(fname)

Read an IDEAS format UNV triangulation

Call:
>>> tri.ReadUnv(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

File name

Versions:
  • 2015-12-13 @ddalle: Version 1.0

RemoveSmallTris(smalltri=1e-05, v=False, recurse=True)

Remove any triangles that are below a certain size

Call:
>>> tri.RemoveSmallTris(smalltri=1e-5, v=False, recurse=True)
Inputs:
tri: cape.tri.Tri

Triangulation instance

smalltri: {1e-5} | float > 0

Minimum allowable triangle area

v: True | {False}

Verbosity flag

recurse: {True} | False

Whether or not to remove newly created small tris

Versions:
  • 2017-06-19 @ddalle: Version 1.0

RemoveUnusedNodes(v=False)

Remove any nodes that are not used in any triangles

Call:
>>> tri.RemoveUnusedNodes(v=False)
Inputs:
tri: cape.tri.Tri

Triangulation instance

v: True | {False}

Verbosity flag

Versions:
  • 2017-02-10 @ddalle: Version 1.0

  • 2019-06-18 @ddalle: NO LOOPS

RenumberCompIDs()

Renumber component ID numbers 1 to n

Call:
>>> tri.RenumberCompIDs()
Inputs:
tri: cape.tri.TriBase

Triangulation interface

Versions:
  • 2016-11-09 @ddalle: Version 1.0

RestrictConfigCompID()

Restrict the component IDs in the config to those in tri.CompID

Call:
>>> tri.RestrictConfigCompID()
Inputs:
tri: cape.tri.Tri

Triangulation instance

Versions:
  • 2016-11-05 @ddalle: Version 1.0

Rotate(v1, v2, theta, compID=None)

Rotate the nodes of a triangulation object.

Call:
>>> tri.Rotate(v1, v2, theta)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be rotated

v1: numpy.ndarray, shape = (3,)

Start point of rotation vector

v2: numpy.ndarray, shape = (3,)

End point of rotation vector

theta: float

Rotation angle in degrees

compID: int | str | list

Component ID(s) to which to apply translation

Versions:
  • 2014-05-27 @ddalle: Version 1.0

  • 2014-10-07 @ddalle: Exported functionality to function

Tecplot3View(fname, i=None)

Create a 3-view PNG of a component(s) using TecPlot

Call:
>>> tri.Tecplot3View(fname, i=None)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: str

Created file is '%s.png' % fname

i: str or int or list (int)

Component name, ID or list of component IDs

Versions:
  • 2015-01-23 @ddalle: Version 1.0

TecplotExplode()

Create a 3-view of each available named component in tri.config (read from Config.xml) if available. If not, create a 3-view plot for each CompID, e.g. 1.png, 2.png, etc.

Call:
>>> tri.Tecplot3View(fname, i=None)
Inputs:
tri: cape.tri.Tri

Triangulation instance

Versions:
  • 2015-01-23 @ddalle: Version 1.0

TraceCurve(Y, **kw)

Extract nodes along a piecewise linear curve

Call:
>>> X = tri.TraceCurve(Y, **kw)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

Y: np.ndarray shape=(n,3)

List of points defining piecewise linear curve

dtol: {0.05} | float

Maximum distance from curve as fraction of reference length

atol: {60.0} | float

Maximum dot product between triangle edge and curve segment

Outputs:
X: np.ndarray shape=(m,3)

Sequential list of nodes that trace a curve

Versions:
  • 2016-09-29 @ddalle: Version 1.0

TraceCurve_GetDistance(Y, x, **kw)

Find distance between a generic curve and a point

Call:
>>> d, ds, j = tri.TraceCurve_GetDistance(Y, x, **kw)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

Y: np.ndarray shape=(n,3)

List of points defining piecewise linear curve

x: np.ndarray shape=(3,)

Test point

dtol: {0.05} | float

Maximum distance from curve as fraction of reference length

atol: {60.0} | float

Maximum dot product between triangle edge and curve segment

Outputs:
d: float

Minimum distance from curve to x

ds: float

Total arc length of curve segments before the closest point

j: int

Index of segment in which closest point is located

Versions:
  • 2016-09-29 @ddalle: Version 1.0

TraceCurve_NextNode(icur, Y, jcur, **kw)

Find the next node of the triangulation by following a curve

Call:
>>> inew, jnew = tri.TraceCurve_NextNode(icur, Y, jcur, **kw)
Inputs:
tri: cape.tri.TriBase

Triangulation instance

icur: int

Index (1-based) of current node

Y: np.ndarray shape=(n,3)

List of points defining piecewise linear curve

jcur: int

Number of curve segments to discount from search

dtol: {0.05} | float

Maximum distance from curve as fraction of reference length

atol: {60.0} | float

Maximum dot product between triangle edge and curve segment

Outputs:
inew: int

Index (1-based) of next node along curve

jnew: int

Number of curve segments to discount from next search

Versions:
  • 2016-09-29 @ddalle: Version 1.0

Translate(*a, **kw)

Translate the nodes of a triangulation object

The offset coordinates may be specified as individual inputs or a single vector of three coordinates.

Call:
>>> tri.Translate(dR, compID)
>>> tri.Translate(dx, dy, dz, compID=None)
>>> tri.Translate(dy=dy, compID=None)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

dR: numpy.ndarray | list

List of three coordinates to use for translation

dx: float

x-coordinate offset

dy: float

y-coordinate offset

dz: float

z-coordinate offset

compID: int | str | list

Component ID(s) to which to apply translation

Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2014-10-08 @ddalle: Exported functionality to function

  • 2016-04-08 @ddalle: Redid inputs

Write(fname='Components.i.tri', **kw)

Write triangulation to file using fastest method available

Call:
>>> tri.WriteSlow(fname='Components.i.tri', v=True, **kw)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

v: bool

Whether or not

ascii: True | {False}

Whether or not to use ASCII (text file)

fmt: {None} | "ascii" | "b4" | "lb4"

Format specified by text

b4: True | {False}

Whether or not to use single-precision big-endian

lb4: True | {False}

Whether or not to use single-precision little-endian

b8: True | {False}

Whether or not to use double-precision big-endian

lb8: True | {False}

Whether or not to use double-precision little-endian

r4: True | {False}

Whether or not to use single-precision big-endian Fortran

lr4: True | {False}

Whether or not to use single-precision little-endian Fortran

r8: True | {False}

Whether or not to use double-precision big-endian Fortran

lr8: True | {False}

Whether or not to use double-precision little-endian Fortran

byteorder: "big" | "little" | {None}

Byte order

endian: "big" | "little" | {None}

Byte order

bytecount: 4 | 8 | {None}

Byte count, 4 for single precision is default

byteswap: True | False | {None}

Use byte order opposite to os.sys.byteorder

bin: True | False | {None}

Force binary output; can be used to get default binary format

dp: True | {False}

Use double-precision (default is single-precision)

sp: True | {False}

Use single-precision (no effect since default is single)

Examples:
>>> tri = cape.ReadTri('bJet.i.tri')
>>> tri.Write('bjet2.tri')
Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2015-01-03 @ddalle: Added C capability

  • 2015-02-25 @ddalle: Added status update

  • 2016-10-02 @ddalle: Now checking for binary/ASCII

WriteASCII(fname='Components.i.tri')

Write triangulation to file using fastest method available

Call:
>>> tri.WriteSlow(fname='Components.i.tri', v=True)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

v: bool

Whether or not

Examples:
>>> tri = cape.ReadTri('bJet.i.tri')
>>> tri.Write('bjet2.tri')
Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2015-01-03 @ddalle: Added C capability

  • 2015-02-25 @ddalle: Added status update

  • 2016-10-02 @ddalle: Moved from tri.Write()

WriteCompIDTri(fname='Components.tri')

Write a .tri file with the original components

This provides a component map for the output of intersect. Supplemental surfaces, such as farfield triangles or grid refinement sources, are not written. Specifically, triangles with negative component IDs are not written.

Call:
>>> tri.WriteCompIDTri(fname='Components.c.tri')
Inputs:
tri: cape.tri.TriBase

Triangulation instance

fname: str

Name of .tri file to use for mapping intersected tris

Versions:
  • 2017-05-25 @ddalle: Version 1.0

WriteConfigXML(fname='Config.xml')

Write a Config.xml file specific to this triangulation

Call:
>>> tri.WriteConfigXML(fname="Config.xml")
Inputs:
tri: cape.tri.TriBase

Triangulation interface

fname: {"Config.xml"} | str

Name of GMP configuration file to write

Versions:
  • 2016-11-06 @ddalle: Version 1.0

WriteFarfieldTri(fname='Components.f.tri')

Write a .tri file supplemental surfaces not intersected

This stores the triangles that are excluded from the input to intersect. This would include farfield surfaces, grid refinement boxes, or bodies that are known not to intersect any others.

Call:
>>> tri.WriteFarfieldTri(fname='Components.f.tri')
Inputs:
tri: cape.tri.TriBase

Triangulation instance

fname: str

Name of .tri file to use for mapping intersected tris

Versions:
  • 2017-05-25 @ddalle: Version 1.0

WriteFast(fname='Components.i.tri')

Try using a compiled function to write to file

Call:
>>> tri.WriteFast(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-01-03 @ddalle: Version 1.0

WriteFast_b4(fname='Components.i.tri')

Use compiled C code to write single-precision big-endian tri

Call:
>>> tri.WriteFast_lb4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_b8(fname='Components.i.tri')

Use compiled C code to write double-precision big-endian tri

Call:
>>> tri.WriteFast_b8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_lb4(fname='Components.i.tri')

Use compiled C code to write single-precision little-endian tri

Call:
>>> tri.WriteFast_lb4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_lb8(fname='Components.i.tri')

Use compiled C code to write double-precision little-endian tri

Call:
>>> tri.WriteFast_lb4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_lr4(fname='Components.i.tri')

Use compiled C code to write single-precision little-endian tri

Call:
>>> tri.WriteFast_lr4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_lr8(fname='Components.i.tri')

Use compiled C code to write double-precision little-endian tri

Call:
>>> tri.WriteFast_lr8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_r4(fname='Components.i.tri')

Use compiled C code to write single-precision big-endian tri

Call:
>>> tri.WriteFast_lb4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteFast_r8(fname='Components.i.tri')

Use compiled C code to write double-precision big-endian tri

Call:
>>> tri.WriteFast_r8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteSTL(fname='Components.i.stl', v=False)

Write a triangulation to an STL file

Call:
>>> tri.WriteSTL(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-11-22 @ddalle: Version 1.0

WriteSTLFast(fname='Components.i.stl')

Try using a compiled function to write to file

Call:
>>> tri.WriteFast(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2016-04-08 @ddalle: Version 1.0

WriteSTLSlow(fname='Components.i.stl')

Write a triangulation to an STL file

Call:
>>> tri.WriteSTLSlow(fname='Components.i.stl')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-11-22 @ddalle: Version 1.0

WriteSlow_ASCII(fname='Components.i.tri', nq=None)

Write a triangulation to file

Call:
>>> tri.WriteASCIISlow(fname='Components.i.tri')
>>> tri.WriteASCIISlow(fname='Components.i.tri', nq=None)
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

nq: {None} | int

Number of states, override the value of tri.nq

Examples:
>>> tri = cape.ReadTri('bJet.i.tri')
>>> tri.Write('bjet2.tri')
Versions:
  • 2014-05-23 @ddalle: Version 1.0

WriteSlow_b4(fname='Components.i.tri')

Use compiled code to write single-precision big-endian tri

Call:
>>> tri.WriteSlow_b4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_b8(fname='Components.i.tri')

Use Python code to write double-precision big-endian tri

Call:
>>> tri.WriteSlow_b8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_lb4(fname='Components.i.tri')

Use Python code to write single-precision little-endian tri

Call:
>>> tri.WriteSlow_lb4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_lb8(fname='Components.i.tri')

Use Python code to write double-precision little-endian tri

Call:
>>> tri.WriteSlow_lb8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_lr4(fname='Components.i.tri')

Use Python code to write single-precision little-endian tri

Call:
>>> tri.WriteSlow_lr4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_lr8(fname='Components.i.tri')

Use Python code to write double-precision little-endian tri

Call:
>>> tri.WriteSlow_lr8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_r4(fname='Components.i.tri')

Use compiled code to write single-precision big-endian tri

Call:
>>> tri.WriteSlow_r4(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSlow_r8(fname='Components.i.tri')

Use Python code to write double-precision big-endian tri

Call:
>>> tri.WriteSlow_r8(fname='Components.i.tri')
Inputs:
tri: cape.tri.Tri

Triangultion instance to be translated

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-09-05 @ddalle: Version 1.0

WriteSurf(fname='Components.i.surf')

Write a triangulation to a AFLR3 surface file

Call:
>>> tri.WriteSurf(fname='Components.i.surf')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-11-19 @ddalle: Version 1.0

WriteSurfFast(fname='Components.i.surf')

Try using a compiled function to write to AFLR3 surf file

Call:
>>> tri.WriteSurfFast(fname='Components.i.surf')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-01-03 @ddalle: Version 1.0

WriteSurfSlow(fname='Components.surf')

Write an AFLR3 surf surface mesh file

Call:
>>> tri.WriteSurfSlow(fname='Components.surf')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Versions:
  • 2015-11-19 @ddalle: Version 1.0

  • 2016-04-05 @ddalle: Added quads, blds, and bldel

WriteTri_b4(fname)

Write a triangulation as a big-endian single-precision file

Call:
>>> tri.WriteTri_b4(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_b8(fname)

Write a triangulation as a big-endian double-precision file

Call:
>>> tri.WriteTri_b8(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_lb4(fname)

Write a triangulation as a little-endian single-precision file

Call:
>>> tri.WriteTri_lb4(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_lb8(fname)

Write a triangulation as a little-endian double-precision file

Call:
>>> tri.WriteTri_lb4(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_lr4(fname)

Write a triangulation as a little-endian single-precision file

Call:
>>> tri.WriteTri_lr4(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_lr8(fname)

Write a triangulation as a little-endian double-precision file

Call:
>>> tri.WriteTri_lr8(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_r4(fname)

Write a triangulation as a big-endian single-precision file

Call:
>>> tri.WriteTri_r4(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTri_r8(fname)

Write a triangulation as a big-endian double-precision file

Call:
>>> tri.WriteTri_r8(fname)
Inputs:
tri: cape.tri.Tri

Triangulation instance

fname: {'Components.i.tri'} | str

Name of file to write

Versions:
  • 2016-10-10 @ddalle: Version 1.0

WriteTriq(fname='Components.i.triq', **kw)

Write q-triangulation to file using fastest method available

Call:
>>> triq.WriteTriq(fname='Components.i.triq', **kw)
Inputs:
triq: cape.tri.Triq

Triangulation instance to be written

fname: str

Name of triangulation file to create

v: bool

Whether or not

ascii: True | {False}

Whether or not to use ASCII (text file)

fmt: {None} | "ascii" | "b4" | "lb4"

Format specified by text

b4: True | {False}

Whether or not to use single-precision big-endian

lb4: True | {False}

Whether or not to use single-precision little-endian

b8: True | {False}

Whether or not to use double-precision big-endian

lb8: True | {False}

Whether or not to use double-precision little-endian

byteorder: "big" | "little" | {None}

Byte order

endian: "big" | "little" | {None}

Byte order

bytecount: 4 | 8 | {None}

Byte count, 4 for single precision is default

byteswap: True | False | {None}

Use byte order opposite to os.sys.byteorder

bin: True | False | {None}

Force binary output; can be used to get default binary format

dp: True | {False}

Use double-precision (default is single-precision)

sp: True | {False}

Use single-precision (no effect since default is single)

Examples:
>>> triq = cape.ReadTriq('bJet.i.triq')
>>> triq.Write('bjet2.triq', b4=True)
Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2015-01-03 @ddalle: Added C capability

  • 2015-02-25 @ddalle: Added status update

  • 2015-09-14 @ddalle: Copied from TriBase.WriteTri()

WriteTriqASCII(fname='Components.i.triq', v=True, **kw)

Write q-triangulation to file using fastest method available

Call:
>>> triq.WriteTriqASCII(fname='Components.i.triq', v=True)
Inputs:
triq: cape.tri.Triq

Triangulation instance to be written

fname: str

Name of triangulation file to create

v: bool

Verbosity flag

Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2015-01-03 @ddalle: Added C capability

  • 2015-02-25 @ddalle: Added status update

  • 2015-09-14 @ddalle: Copied from TriBase.WriteTri()

  • 2017-03-29 @ddalle: Moved from WriteTriq()

WriteTriqFast(fname='Components.i.triq')

Write a triangulation file with state to file via Python/C

Call:
>>> triq.WriteTriqFast(fname='Components.i.triq')
Inputs:
triq: cape.tri.Triq

Triangulation instance to be written

fname: str

Name of triangulation file to create

Examples:
>>> triq = cape.ReadTriQ('bJet.i.triq')
>>> triq.Write('bjet2.triq')
Versions:
  • 2015-09-14 @ddalle: Version 1.0

WriteTriqSlow(fname='Components.i.triq')

Write a triangulation file with state to file

Call:
>>> triq.WriteTriqSlow(fname='Components.i.triq')
Inputs:
triq: cape.tri.Triq

Triangulation instance to be written

fname: str

Name of triangulation file to create

Examples:
>>> triq = cape.ReadTriQ('bJet.i.triq')
>>> triq.Write('bjet2.triq')
Versions:
  • 2015-09-14 @ddalle: Version 1.0

WriteUH3D(fname='Components.i.uh3d')

Write a triangulation to a UH3D file

Call:
>>> tri.WriteUH3D(fname='Components.i.uh3d')
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

Examples:
>>> tri = cape.ReadTri('bJet.i.tri')
>>> tri.WriteUH3D('bjet2.uh3d')
Versions:
  • 2015-04-17 @ddalle: Version 1.0

WriteUH3DSlow(fname='Components.i.uh3d', lbls={})

Write a triangulation to a UH3D file

Call:
>>> tri.WriteUH3DSlow(fname='Components.i.uh3d', lbls={})
Inputs:
tri: cape.tri.Tri

Triangulation instance to be translated

fname: str

Name of triangulation file to create

lbls: dict

Optioan dict of names for component IDs, e.g. {1: "body"}

Versions:
  • 2015-04-17 @ddalle: Version 1.0

WriteVolTri(fname='Components.tri')

Write a .tri file with one CompID per break in tri.iTri

This is a necessary step of running intersect because each polyhedron (i.e. water-tight volume) must have a single uniform component ID before running intersect.

Call:
>>> tri.WriteVolTri(fname='Components.c.tri')
Inputs:
tri: cape.tri.TriBase

Triangulation instance

fname: str

Name of .tri file for use as input to intersect

Versions:
  • 2015-02-24 @ddalle: Version 1.0

Plain surface triangulation

class cape.tri.Tri(fname=None, c=None, **kw)

Cape surface mesh interface

This class provides an interface for a basic triangulation without surface data. It can be created either by reading an ASCII file or specifying the data directly.

When no component numbers are specified, the object created will label all triangles 1.

Call:
>>> tri = cape.Tri(fname=fname, c=None)
>>> tri = cape.Tri(surf=surf, c=None)
>>> tri = cape.Tri(uh3d=uh3d, c=None)
>>> tri = cape.Tri(cgns=cgns, c=None)
>>> tri = cape.Tri(unv=unv, c=None)
>>> tri = cape.Tri(nNode=nNode, Nodes=Nodes, **kw)
Inputs:
fname: str

Name of triangulation file to read (Cart3D format)

surf: str

Name of AFLR3 surface file

uh3d: str

Name of triangulation file (UH3D format)

cgns: str

Name of mixed quad/tri file (CGNS format)

unv: str

Name of IDEAS surface triangulation file

c: str

Name of configuration file (usually Config.xml or pyfun.json)

Keyword arguments:

Data members can be defined directly using keyword arguments

Data members:
tri.nNode: int

Number of nodes in triangulation

tri.Nodes: np.ndarray (float), (nNode, 3)

Matrix of x,y,z-coordinates of each node

tri.nTri: int

Number of triangles in triangulation

tri.Tris: np.ndarray (int), (nTri, 3)

Indices of triangle vertex nodes

tri.CompID: np.ndarray (int), (nTri,)

Component number for each triangle

tri.BCs: np.ndarray (int), (nTri,)

Boundary condition flag for each triangle

tri.nQuad: int

Number of quads in surface

tri.Quads: np.ndarray (int), (nQuad, 4)

Indices of quad vertex nodes

tri.CompIDQuad: np.ndarray (int), (nQuad,)

Component number for each quad

tri.BCsQuad: np.ndarray (int), (nQuad,)

Boundary condition flag for each quad

tri.blds: np.ndaray (float), (nNode,)

Boundary layer initial spacing for each node

tri.bldel: np.ndarray (float), (nNode,)

Boundary layer thicknesses for each node

Versions:
  • 2014-05-23 @ddalle: Version 1.0

  • 2016-04-05 @ddalle: Many input formats

Annotated surface triangulation with solution (triq files)

class cape.tri.Triq(fname=None, n=1, nNode=None, Nodes=None, c=None, nTri=None, Tris=None, CompID=None, nq=None, q=None)

Class for surface geometry with solution values at each point

This class is based on the concept of Cart3D triq files, which are also utilized by some Overflow utilities, including overint.

Call:
>>> triq = cape.Triq(fname=fname, c=None)
>>> triq = cape.Triq(Nodes=Nodes, Tris=Tris, CompID=CompID, q=q)
Inputs:
fname: str

Name of triangulation file to read (Cart3D format)

c: str

Name of configuration file (usually Config.xml)

nNode: int

Number of nodes in triangulation

Nodes: np.ndarray (float), (nNode, 3)

Matrix of x,y,z-coordinates of each node

nTri: int

Number of triangles in triangulation

Tris: np.ndarray (int), (nTri, 3)

Indices of triangle vertex nodes

CompID: np.ndarray, (nTri)

Component number for each triangle

nq: int

Number of state variables at each node

q: np.ndarray (float), (nNode, nq)

State vector at each node

Data members:
triq.nNode: int

Number of nodes in triangulation

triq.Nodes: np.ndarray (float), (nNode, 3)

Matrix of x,y,z-coordinates of each node

triq.nTri: int

Number of triangles in triangulation

triq.Tris: np.ndarray (int), (nTri, 3)

Indices of triangle vertex nodes

triq.CompID: np.ndarray (int), (nTri)

Component number for each triangle

triq.nq: int

Number of state variables at each node

triq.q: np.ndarray (float), (nNode, nq)

State vector at each node

triq.n: int

Number of files averaged in this triangulation (used for weight)

GetSkinFriction(comp=None, **kw)

Calculate vectors of pressure, momentum, and viscous forces on tris

Call:
>>> cf_x, cf_y, cf_z = triq.GetSkinFriction(comp=None, **kw)
Inputs:
triq: cape.tri.Triq

Annotated surface triangulation

comp: {None} | str | int | list

Subset component ID or name or list thereof

incm, momentum: True | {False}

Include momentum (flow-through) forces in total

gauge: {True} | False

Calculate gauge forces (True) or absolute (False)

save: True | {False}

Store vectors of forces for each triangle as attributes

xMRP: {0.0} | float

x-coordinate of moment reference point

yMRP: {0.0} | float

y-coordinate of moment reference point

zMRP: {0.0} | float

z-coordinate of moment reference point

MRP: {[xMRP, yMRP, zMRP]} | list (len=3)

Moment reference point

m, mach: {1.0} | float

Freestream Mach number

RefArea, Aref: {1.0} | float

Reference area

RefLength, Lref: {1.0} | float

Reference length (longitudinal)

RefSpan, bref: {Lref} | float

Reference span (for rolling and yawing moments)

Re, Rey: {1.0} | float

Reynolds number per grid unit (units same as triq.Nodes)

gam, gamma: {1.4} | float > 1

Freestream ratio of specific heats

Utilized Attributes:
triq.nNode: int

Number of nodes

triq.q: np.ndarray (float shape=(nNode,*nq*))

Vector of 5, 9, or 13 states on each node

Outputs:
cf_x: np.ndarray

x-component of skin friction coefficient

cf_y: np.ndarray

y-component of skin friction coefficient

cf_z: np.ndarray

z-component of skin friction coefficient

Versions:
  • 2017-04-03 @ddalle: Version 1.0

GetTriForces(comp=None, **kw)

Calculate vectors of pressure, momentum, and viscous forces on tris

Call:
>>> C = triq.GetTriForces(comp=None, **kw)
Inputs:
triq: cape.tri.Triq

Annotated surface triangulation

comp: {None} | str | int | list

Subset component ID or name or list thereof

incm, momentum: True | {False}

Include momentum (flow-through) forces in total

gauge: {True} | False

Calculate gauge forces (True) or absolute (False)

save: True | {False}

Store vectors of forces for each triangle as attributes

xMRP: {0.0} | float

x-coordinate of moment reference point

yMRP: {0.0} | float

y-coordinate of moment reference point

zMRP: {0.0} | float

z-coordinate of moment reference point

MRP: {[xMRP, yMRP, zMRP]} | list (len=3)

Moment reference point

m, mach: {1.0} | float

Freestream Mach number

RefArea, Aref: {1.0} | float

Reference area

RefLength, Lref: {1.0} | float

Reference length (longitudinal)

RefSpan, bref: {Lref} | float

Reference span (for rolling and yawing moments)

Re, Rey: {1.0} | float

Reynolds number per grid unit (units same as triq.Nodes)

gam, gamma: {1.4} | float > 1

Freestream ratio of specific heats

Utilized Attributes:
triq.nNode: int

Number of nodes

triq.q: np.ndarray (float shape=(nNode,*nq*))

Vector of 5, 9, or 13 states on each node

Output Attributes:
triq.Fp: np.ndarray shape=(nTri,3)

Vector of pressure forces on each triangle

triq.Fm: np.ndarray shape=(nTri,3)

Vector of momentum (flow-through) forces on each triangle

triq.Fv: np.ndarray shape=(nTri,3)

Vector of viscous forces on each triangle

Outputs:
C: dict (float)

Dictionary of requested force/moment coefficients

C[“CA”]: float

Overall axial force coefficient

Versions:
  • 2017-02-11 @ddalle: Started

  • 2017-02-15 @ddalle: Version 1.0

InterpSurfPoint(x, **kw)

Interpolate triq.q to the nearest point on the surface

Call:
>>> x0, q = triq.InterpSurfPoint(x, **kw)
Inputs:
triq: cape.tri.Triq

Annotated triangulation interface

x: np.ndarray (float, shape=(3,))

Array of x, y, and z coordinates of test point

k: {None} | int

Pre-specified index of nearest triangle (0-based)

k1: {None} | int

Pre-specified index of nearest triangle (1-based)

z: {None} | float

Pre-specified projection distance of x to tri k1

kw: dict

Keyword arguments passed to Tri.GetNearestTri()

Outputs:
x0: np.ndarray shape=(3,)

Point projected onto the surface

q: np.ndarray shape=(triq.nq,)

Interpolated state from triq.q

Versions:
  • 2017-10-10 @ddalle: Version 1.0

  • 2018-10-12 @serogers: Version 2.0; subtriangles

  • 2022-03-10 @ddalle: Version 2.1; skip GetNearestTri()

WeightedAverage(triq)

Calculate weighted average with a second triangulation

Call:
>>> triq.WeightedAverage(triq2)
Inputs:
triq: cape.tri.Triq

Triangulation instance

triq2: class:cape.tri.Triq

Second triangulation instance

Versions:
  • 2015-09-14 @ddalle: Version 1.0

Write(fname, **kw)

Write a q-triangulation .triq file

Call:
>>> triq.Write(fname, **kw)
Inputs:
triq: cape.tri.Triq

Triangulation instance

fname: str

Name of triangulation file to write

b4: True | {False}

Write single-precision big-endian

Versions:
  • 2015-09-14 @ddalle: Version 1.0