mesh_utils Package

bdf_equivalence Module

defines:
model = bdf_equivalence_nodes(bdf_filename, bdf_filename_out, tol,

renumber_nodes=False, neq_max=4, xref=True, node_set=None, size=8, is_double=False, remove_collapsed_elements=False, avoid_collapsed_elements=False, crash_on_collapse=False, log=None, debug=True)

pyNastran.bdf.mesh_utils.bdf_equivalence.bdf_equivalence_nodes(bdf_filename: PathLike, bdf_filename_out: PathLike | None, tol: float, renumber_nodes: bool = False, neq_max: int = 4, xref: bool = True, node_set: list[int] | NDArrayNint | None = None, size: int = 8, is_double: bool = False, remove_collapsed_elements: bool = False, avoid_collapsed_elements: bool = False, crash_on_collapse: bool = False, log: SimpleLogger | None = None, debug: bool = True, method: str = 'new') BDF[source]

Equivalences nodes; keeps the lower node id; creates two nodes with the same

Parameters:
bdf_filenamestr / BDF

str : bdf file path BDF : a BDF model that is fully valid (see xref)

bdf_filename_outstr

str: a bdf_filename to write None: don’t write the deck

tolfloat

the spherical tolerance

renumber_nodesbool

should the nodes be renumbered (default=False)

neq_maxint

the number of “close” points (default=4)

xrefbool

does the model need to be cross_referenced (default=True; only applies to model option)

node_setlist[int] / (n, ) ndarray; default=None

the list/array of nodes to consider (not supported with renumber_nodes=True)

sizeint; {8, 16}; default=8

the bdf write precision

is_doublebool; default=False

the field precision to write

remove_collapsed_elementsbool; default=False (unsupported)
True1D/2D/3D elements will not be collapsed;

CELASx/CDAMP/MPC/etc. are not considered

False : no elements will be removed

avoid_collapsed_elementsbool; default=False (unsupported)
Trueonly collapses that don’t break 1D/2D/3D elements will be considered;

CELASx/CDAMP/MPC/etc. are considered

False : element can be collapsed

crash_on_collapsebool; default=False
stop if nodes have been collapsed

False: blindly move on True: rereads the BDF which catches doubled nodes (temporary);

in the future collapse=True won’t need to double read; an alternative is to do Patran’s method of avoiding collapse)

debugbool

bdf debugging

method: str; default=’new’

‘new’: doesn’t require neq_max; new in v1.3 ‘old’: use neq_max; used in v1.2

loglogger(); default=None

bdf logging

Returns:
modelBDF()

The BDF model corresponding to bdf_filename_out

Warning

I doubt SPOINTs/EPOINTs work correctly ..

Warning

xref not fully implemented (assumes cid=0) ..

Todo

node_set still does work on the all the nodes in the big kdtree loop, which is very inefficient

Todo

remove_collapsed_elements is not supported ..

Todo

avoid_collapsed_elements is not supported ..

pyNastran.bdf.mesh_utils.bdf_equivalence.get_all_node_set(node_set: list[Any] | None) Any[source]

bdf_merge Module

defines:
  • bdf_merge(bdf_filenames, bdf_filename_out=None, renumber=True, encoding=None, size=8,

    is_double=False, cards_to_skip=None, log=None, skip_case_control_deck=False)

pyNastran.bdf.mesh_utils.bdf_merge.bdf_merge(bdf_filenames: list[str], bdf_filename_out: str | None = None, renumber: bool = True, encoding: str | None = None, size: int = 8, is_double: bool = False, cards_to_skip: list[str] | None = None, skip_case_control_deck: bool = False, log: SimpleLogger | None = None) tuple[BDF, list[MAPPER]][source]

Merges multiple BDF into one file

Parameters:
bdf_filenameslist[str]

list of bdf filenames

bdf_filename_outstr / None

the output bdf filename (default=None; None -> no writing)

renumberbool

should the bdf be renumbered (default=True)

encodingstr

the unicode encoding (default=None; system default)

sizeint; {8, 16}; default=8

the bdf write precision

is_doublebool; default=False

the field precision to write

cards_to_skiplist[str]; (default=None -> don’t skip any cards)

There are edge cases (e.g. FLUTTER analysis) where things can break due to uncross-referenced cards. You need to disable entire classes of cards in that case (e.g. all aero cards).

skip_case_control_deckbool, optional, defaultFalse

If true, don’t consider the case control deck while merging.

Returns:
modelBDF

Merged model.

mappers_alllist[mapper]
mapperdict[bdf_attribute]old_id_to_new_id_dict

List of mapper dictionaries of original ids to merged

bdf_attributestr

a BDF attribute (e.g., ‘nodes’, ‘elements’)

old_id_to_new_id_dictdict[id_old]id_new

a sub dictionary that is used to map the node/element/etc. ids

mapper = {

‘elements’ : eid_map, ‘nodes’ : nid_map, ‘coords’ : cid_map, …

}

Supports

nodes: GRID coords: Coord elements: CQUAD4, CTRIA3, CTETRA, CPENTA, CHEXA, CELASx, CBAR, CBEAM

CONM1, CONM2, CMASS

properties: PSHELL, PCOMP, PSOLID, PMASS materials: MAT1, MAT8

Todo

doesn’t support SPOINTs/EPOINTs ..

Warning

still very preliminary ..

bdf_renumber Module

defines:
bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False,

starting_id_dict=None, round_ids=False, cards_to_skip=None, log=None, debug=False)

superelement_renumber(bdf_filename, bdf_filename_out=None, size=8, is_double=False,

starting_id_dict=None, cards_to_skip=None, log=None, debug=False)

pyNastran.bdf.mesh_utils.bdf_renumber.bdf_renumber(bdf_filename: PathLike | BDF | StringIO, bdf_filename_out: PathLike, size: int = 8, is_double: bool = False, starting_id_dict: dict[str, int] | None = None, round_ids: bool = False, cards_to_skip: list[str] | None = None, punch: bool = False, log: SimpleLogger | None = None, debug: bool = False) BDF[source]

Renumbers a BDF

Parameters:
bdf_filenamestr / BDF

str : a bdf_filename (string; supported) BDF : a BDF model that has been cross referenced and is fully valid (an equivalenced deck is not valid)

bdf_filename_outstr / None

str : a bdf_filename to write None : don’t write the BDF

sizeint; {8, 16}; default=8

the bdf write precision

is_doublebool; default=False

the field precision to write

starting_id_dictdict, None (default=None)

None : renumber everything starting from 1 dict : {key : starting_id}

keystr

the key (e.g. eid, nid, cid, …)

starting_idint, None

int : the value to start from None : don’t renumber this key

round_idsbool; default=False

Should a rounding up be applied for each variable? This makes it easier to read a deck and verify that it’s been renumbered properly. This only really applies when starting_id_dict is None

cards_to_skiplist[str]; (default=None -> don’t skip any cards)

There are edge cases (e.g. FLUTTER analysis) where things can break due to uncross-referenced cards. You need to disable entire classes of cards in that case (e.g. all aero cards).

Returns:
modelBDF()

a renumbered BDF object corresponding to bdf_filename_out

mapperdict[bdf_attribute]old_id_to_new_id_dict

list of mapper dictionaries of original ids to merged bdf_attribute : str

a BDF attribute (e.g., ‘nodes’, ‘elements’)

old_id_to_new_id_dictdict[id_old]id_new

a sub dictionary that is used to map the node/element/etc. ids

mapper = {

‘elements’ : eid_map, ‘nodes’ : nid_map, ‘coords’ : cid_map, …

}

Todo

bdf_model option for bdf_filename hasn’t been tested ..

Todo

add support for subsets (e.g. renumber only a subset of nodes/elements) ..

Todo

doesn’t support partial renumbering ..

Todo

doesn’t support element material coordinate systems ..

..warning :: spoints might be problematic…check
..warning :: still in development, but it usually brutally crashes

if it’s not supported

..warning :: be careful of card unsupported cards (e.g. ones not read in)
Supports
  • GRIDs - no superelements

  • COORDx

  • elements
    • CELASx/CONROD/CBAR/CBEAM/CQUAD4/CTRIA3/CTETRA/CPENTA/CHEXA

    • RBAR/RBAR1/RBE1/RBE2/RBE3/RSPLINE/RSSCON

  • properties
    • PSHELL/PCOMP/PCOMPG/PSOLID/PSHEAR/PBAR/PBARL PROD/PTUBE/PBEAM

  • mass
    • CMASSx/CONMx/PMASS

  • aero - FLFACT - SPLINEx - FLUTTER

  • partial case control - METHOD/CMETHOD/FREQENCY - LOAD/DLOAD/LSEQ/LOADSET…LOADSET/LSEQ is iffy - SET cards

    • nodes

    • elements

    • SPC/MPC/FLUTTER/FLFACT

  • constraints
    • SPC/SPCADD/SPCAX/SPCD

    • MPC/MPCADD

    • SUPORT/SUPORT1

  • solution control/methods
    • TSTEP/TSTEPNL

    • NLPARM

    • EIGB/EIGC/EIGRL/EIGR

  • sets
    • USET

  • other
    • tables

    • materials

    • loads/dloads

Not Done
  • SPOINT

  • any cards with SPOINTs - DMIG/DMI/DMIJ/DMIJI/DMIK/etc. - CELASx - CDAMPx

  • superelements

  • aero cards - CAEROx - PAEROx

  • thermal cards?

  • optimization cards

  • SETx

  • PARAM,GRDPNT,x; where x>0

  • GRID SEID

  • case control - STATSUB - SUBCASE - global SET cards won’t be renumbered properly

Examples

Renumber Everything; Start from 1

>>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False,
                 round_ids=False)

Renumber Everything; Start Material IDs from 100

>>> starting_id_dict = {
    'mid' : 100,
}
>>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False,
                 starting_ids_dict=starting_ids_dict, round_ids=False)

Only Renumber Material IDs

>>> starting_id_dict = {
    'cid' : None,
    'nid' : None,
    'eid' : None,
    'pid' : None,
    'mid' : 1,
    'spc_id' : None,
    'mpc_id' : None,
    'load_id' : None,
    'dload_id' : None,

‘method_id’ : None, ‘cmethod_id’ : None, ‘spline_id’ : None, ‘table_id’ : None, ‘flfact_id’ : None, ‘flutter_id’ : None, ‘freq_id’ : None, ‘tstep_id’ : None, ‘tstepnl_id’ : None, ‘suport_id’ : None, ‘suport1_id’ : None, ‘tf_id’ : None, ‘set_id’ : None,

} >>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False,

starting_ids_dict=starting_ids_dict, round_ids=False)

pyNastran.bdf.mesh_utils.bdf_renumber.get_renumber_starting_ids_from_model(model: BDF) dict[str, int][source]

Get the starting ids dictionary used for renumbering with ids greater than those in model.

Parameters:
modelBDF

BDF object to get maximum ids from.

Returns:
starting_id_dictdict {strint, …}

Dictionary from id type to starting id.

pyNastran.bdf.mesh_utils.bdf_renumber.get_starting_ids_dict_from_mapper(model, mapper)[source]
pyNastran.bdf.mesh_utils.bdf_renumber.superelement_renumber(bdf_filename: PathLike | BDF, bdf_filename_out=None, size=8, is_double=False, starting_id_dict=None, cards_to_skip=None, log: SimpleLogger | None = None, debug: bool = False)[source]

Renumbers a superelement

Parameters:
bdf_filenamestr / BDF

str : a bdf_filename (string; supported) BDF : a BDF model that has been cross referenced and is fully valid (an equivalenced deck is not valid)

bdf_filename_outstr / None

str : a bdf_filename to write None : don’t write the BDF

sizeint; {8, 16}; default=8

the bdf write precision

is_doublebool; default=False

the field precision to write

starting_id_dictdict, None (default=None)

None : renumber everything starting from 1 dict : {key : starting_id}

keystr

the key (e.g. eid, nid, cid, …)

starting_idint, None

int : the value to start from None : don’t renumber this key

cards_to_skiplist[str]; (default=None -> don’t skip any cards)

There are edge cases (e.g. FLUTTER analysis) where things can break due to uncross-referenced cards. You need to disable entire classes of cards in that case (e.g. all aero cards).

Returns:
modelBDF()

a renumbered BDF object corresponding to bdf_filename_out

collapse_bad_quads Module

defines:
  • convert_bad_quads_to_tris(model, eids_to_check=None, xyz_cid0=None,

    min_edge_length=0.0)

pyNastran.bdf.mesh_utils.collapse_bad_quads.convert_bad_quads_to_tris(model: BDF, eids_to_check: list[int] = None, xyz_cid0: np.ndarray | None = None, min_edge_length: float = 0.0) None[source]

A standard quad is a nice rectangle. If an edge is collapsed, it’s a triangle. Change the element type with an inplace operation. Deletes any line elements created.

Parameters:
modelBDF()

a BDF model that has not had it’s properties/load xref’d, but is valid such that it could

eidslist; (default=None -> all CQUAD4s)

the subset of element ids to check

xyz_cid0(n, 3) ndarray

nodes in cid=0

min_edge_lengthfloat; default=0.0

what is classified as “short”

.. warning:: Don’t cross reference properties/loads
.. todo:: check for bad xref
pyNastran.bdf.mesh_utils.collapse_bad_quads.delete_bad_tris(model: BDF, eids_to_check: list[int] = None, xyz_cid0: np.ndarray | None = None, min_edge_length: float = 0.0) None[source]

If an triangular edge is collapsed, it’s a line and should be deleted.

Parameters:
modelBDF()

a BDF model that has not had it’s properties/load xref’d, but is valid such that it could

eids_to_checklist; (default=None -> all CTRIA3s)

the subset of element ids to check

xyz_cid0(n, 3) ndarray

nodes in cid=0

min_edge_lengthfloat; default=0.0

what is classified as “short”

.. warning:: Don’t cross reference properties/loads
.. todo:: check for bad xref

convert Module

defines:
  • convert(model, units_to, units=None)

pyNastran.bdf.mesh_utils.convert.convert(model: BDF, units_to: list[str], units: list[str] | None = None) None[source]

Converts a model from a set of defined units

Parameters:
modelBDF

cross references the model (default=True)

units_tolist[str]

[length, mass, time] length = {in, ft, m, cm, mm} mass = {g, kg, Mg, lbm, slug, slinch} time = {s}

unitslist[str]

overwrites model.units

pyNastran.bdf.mesh_utils.convert.convert_length(length_from: str, length_to: str) tuple[float, float][source]

Determines the length scale factor

We create a gravity_scale_length for any non-standard unit (ft, m)

pyNastran.bdf.mesh_utils.convert.convert_mass(mass_from: str, mass_to: str, log: SimpleLogger) tuple[float, float, float][source]

determines the mass, weight, gravity scale factor

We apply a gravity_scale_mass for any unit not {kg, slug}. Then we convert to N.

So for SI, if we have kg, we have a base unit, and the length is assumed to be m, so we have a consistent system and gravity_scale_mass is 1.0.

For lbm:

F = m*a 1 lbf = 1 lbm * 1 ft/s^2 32 lbf = 1 slug * 32 ft/s^2 gscale = 1/g F = gscale * m * a 1 lbf = gscale * 1 lbm * 32 ft/s^2 –> gscale = 1/32

For slug:

F = gscale * m * a 32 lbf = gscale * 1 slug * 32 ft/s^2 –> gscale = 1

For slinch:

F = gscale * m * a 386 lbf = gscale * 1 slinch * 12*32 in/s^2 1 slinch = 12 slug 12 in = 1 ft 386 lbf = gscale * 12 slug * 32 ft/s^2 –> gscale = 1

TODO: slinch/slug not validated

pyNastran.bdf.mesh_utils.convert.get_scale_factors(units_from, units_to, log)[source]

[length, mass, time] [in, lb, s]

pyNastran.bdf.mesh_utils.convert.scale_by_terms(bdf_filename: BDF | str, terms: list[str], scales: list[float], bdf_filename_out: str | None = None, encoding: str | None = None, log: SimpleLogger | None = None, debug: bool = True) BDF[source]

Scales a BDF based on factors for 3 of the 6 independent terms

Parameters:
bdf_filenamestr / BDF()

a BDF filename

termslist[str]; length=3

the names {M, L, T, F, P, V, A, rho} mass, length, time, force, pressure, velocity, area, mass_density

scaleslist[float]; length=3

the scaling factors

bdf_filename_outstr; default=None

a BDF filename to write

Returns:
modelBDF()

the scaled BDF

pyNastran.bdf.mesh_utils.convert.scale_model(model: BDF, xyz_scale: float, mass_scale: float, time_scale: float, force_scale: float, gravity_scale: float, convert_nodes: bool = True, convert_elements: bool = True, convert_properties: bool = True, convert_materials: bool = True, convert_aero: bool = True, convert_constraints: bool = True, convert_loads: bool = True, convert_optimization: bool = True)[source]

Performs the model scaling

delete_bad_elements Module

defines:
  • model = delete_bad_shells(model, max_theta=175., max_skew=70., max_aspect_ratio=100.,

    max_taper_ratio=4.0)

  • eids_to_delete = get_bad_shells(model, xyz_cid0, nid_map, max_theta=175., max_skew=70.,

    max_aspect_ratio=100., max_taper_ratio=4.0)

pyNastran.bdf.mesh_utils.delete_bad_elements.delete_bad_shells(model: BDF, min_theta: float = 0.1, max_theta: float = 175.0, max_skew: float = 70.0, max_aspect_ratio: float = 100.0, max_taper_ratio: float = 4.0, max_warping: float = 90.0) BDF[source]

Removes bad CQUAD4/CTRIA3 elements

Parameters:
modelBDF ()

this should be equivalenced

min_thetafloat; default=0.1

the maximum interior angle (degrees)

max_thetafloat; default=175.

the maximum interior angle (degrees)

max_skewfloat; default=70.

the maximum skew angle (degrees)

max_aspect_ratiofloat; default=100.

the max aspect ratio

taper_ratiofloat; default=4.0

the taper ratio; applies to CQUAD4s only

max_warping: float: default=20.0

the maximum warp angle (degrees)

pyNastran.bdf.mesh_utils.delete_bad_elements.element_quality(model, nids=None, xyz_cid0=None, nid_map=None)[source]

Gets various measures of element quality

Parameters:
modelBDF()

a cross-referenced model

nids(nnodes, ) int ndarray; default=None

the nodes of the model in sorted order includes GRID, SPOINT, & EPOINTs

xyz_cid0(nnodes, 3) float ndarray; default=None

the associated global xyz locations

nid_mapdict[nid]->index; default=None

a mapper dictionary

Returns:
qualitydict[name](nelements, ) float ndarray

Various quality metrics names : min_interior_angle, max_interior_angle, dideal_theta,

max_skew_angle, max_aspect_ratio, area_ratio, taper_ratio, min_edge_length

valuesThe result is np.nan if element type does not define

the parameter. For example, CELAS1 doesn’t have an aspect ratio.

Notes

  • pulled from nastran_io.py

pyNastran.bdf.mesh_utils.delete_bad_elements.get_bad_shells(model: BDF, xyz_cid0, nid_map, min_theta: float = 0.1, max_theta: float = 175.0, max_skew: float = 70.0, max_aspect_ratio: float = 100.0, max_taper_ratio: float = 4.0, max_warping: float = 60.0) list[int][source]

Get the bad shell elements

Parameters:
modelBDF()

the model object

xyz_cid0(N, 3) float ndarray

the xyz coordinates in cid=0

nid_mapdict[nid]index
nidint

the node id

indexint

the index of the node id in xyz_cid0

min_thetafloat; default=0.1

the maximum interior angle (degrees)

max_thetafloat; default=175.

the maximum interior angle (degrees)

max_skewfloat; default=70.

the maximum skew angle (degrees)

max_aspect_ratiofloat; default=100.

the max aspect ratio

taper_ratiofloat; default=4.0

the taper ratio; applies to CQUAD4s only

max_warping: float: default=60.0

the maximum warp angle (degrees)

Returns:
eids_failedlist[int]

element ids that fail the criteria

shells with a edge length=0.0 are automatically added
pyNastran.bdf.mesh_utils.delete_bad_elements.get_min_max_theta(faces, all_node_ids, nid_map, xyz_cid0)[source]

get the min/max thetas for CTETRA, CPENTA, CHEXA, CPYRAM

pyNastran.bdf.mesh_utils.delete_bad_elements.get_node_map(model)[source]

gets an nid->inid mapper

pyNastran.bdf.mesh_utils.delete_bad_elements.quad_quality(element, p1, p2, p3, p4)[source]

gets the quality metrics for a quad

pyNastran.bdf.mesh_utils.delete_bad_elements.quad_quality_nastran(p1: ndarray, p2: ndarray, p3: ndarray, p4: ndarray) tuple[float, float, float][source]

Compute CQUAD4 quality metrics using NX Nastran GEOMCHECK definitions.

Parameters:
p1, p2, p3, p4(3,) float ndarray

Corner node coordinates in order.

Returns:
skewfloat

Skew angle in radians (NX: angle between midpoint-joining vectors). Ideal = pi/2. Nastran fails if skew < 30 deg.

taperfloat

Taper ratio (NX: (A_max - Q) / Q). Ideal = 0.0. Nastran fails if taper > 0.5.

warpfloat

Surface warping factor (NX: HH / (D_AC + D_BD)). Ideal = 0.0. Nastran fails if warp > 0.05.

Notes

These formulas match NX Nastran User’s Guide Ch. 15 “User Controlled Element Checks” (Simcenter Nastran 2506).

The existing quad_quality function uses Altair/HyperMesh definitions which differ for taper (average deviation) and warp (angle-based).

pyNastran.bdf.mesh_utils.delete_bad_elements.tri_quality(p1, p2, p3)[source]

gets the quality metrics for a tri

area, max_skew, aspect_ratio, min_theta, max_theta, dideal_theta, min_edge_length

export_mcids Module

Defines:
  • nodes, bars = export_mcids(bdf_filename, csv_filename=None)

pyNastran.bdf.mesh_utils.export_mcids.export_element_cid(bdf_filename: BDF | str, eids: list[int] | None = None, log=None, debug=False)[source]

Exports the element coordinates systems for non-isotropic materials.

Note that for two quads identically oriented/numbered PSHELL quads with theta different between the two, the element cid will be same.

pyNastran.bdf.mesh_utils.export_mcids.export_mcids(bdf_filename: BDF | str, csv_filename: str | None = None, eids: list[int] | None = None, export_xaxis: bool = True, export_yaxis: bool = True, consider_property_rotation: bool = True, iply: int = 0, log=None, debug=False)[source]

Exports the element material coordinates systems for non-isotropic materials.

Parameters:
bdf_filenamestr/BDF

a bdf filename or BDF model

csv_filenamestr; default=None

str : the path to the output csv None : don’t write a CSV

eidslist[int]

the element ids to consider

export_xaxisbool; default=True

export the x-axis

export_yaxisbool; default=True

export the x-axis

consider_property_rotationbool; default=True

rotate the coordinate system

iplyint; default=0

TODO: not validated the ply to consider

pid_to_npliesdict[int pid, int nplies]; default=None -> auto

optional dictionary to speed up analysis

PSHELL

iply location —- ——–

0 mid1 or mid2 1 mid1 2 mid2 3 mid3 4 mid4

PCOMP/PCOMPG

iply location —- ——– 0 layer1 1 layer2

Returns:
nodes(nnodes, 3) float list

the nodes

bars(nbars, 2) int list

the “bars” that represent the x/y axes of the coordinate systems

pyNastran.bdf.mesh_utils.export_mcids.export_mcids_all(bdf_filename: BDF | str, eids: list[int] | None = None, log: SimpleLogger | None = None, debug: bool = False)[source]

Exports the element material coordinates systems for non-isotropic materials.

Note that for two quads identically oriented/numbered PSHELL quads with theta different between the two, the mcid will be different.

Parameters:
bdf_filenamestr/BDF

a bdf filename or BDF model

eidslist[int]

the element ids to consider

#csv_filenamestr; default=None

#str : the path to the output csv #None : don’t write a CSV

PSHELL

iply location —- ——–

0 mid1 or mid2 1 mid1 2 mid2 3 mid3 4 mid4

PCOMP/PCOMPG

iply location —- ——– 0 layer1 1 layer2

Returns:
nodes(nnodes, 3) float list

the nodes

bars(nbars, 2) int list

the “bars” that represent the x/y axes of the coordinate systems

pyNastran.bdf.mesh_utils.export_mcids.get_pid_ref_prop_type(model: BDF, elem) tuple[PCOMP | PCOMPG | PSHELL, str][source]

helper method for export_mcids

pyNastran.bdf.mesh_utils.export_mcids.get_pid_to_nplies(model: BDF) tuple[dict[int, int], int][source]

mirror_mesh Module

This file defines:
  • model, nid_offset, eid_offset = bdf_mirror(bdf_filename, plane=’xz’)

  • model, nid_offset, eid_offset = write_bdf_symmetric(

    bdf_filename, out_filename=None, encoding=None, size=8, is_double=False, enddata=None, close=True, plane=’xz’)

pyNastran.bdf.mesh_utils.mirror_mesh.bdf_mirror(bdf_filename: PathLike | BDF, plane: str = 'xz', log: SimpleLogger | None = None, debug: bool = True) tuple[BDF, int, int][source]

Mirrors the model about the symmetry plane

Parameters:
bdf_filenamestr / BDF()

str : the bdf filename BDF : the BDF model object

logSimpleLogger | None

the logger

debug: bool | str; default=True

debug flag (True=debug, False=warning, info, error)

planestr; {‘xy’, ‘yz’, ‘xz’}; default=’xz’

the plane to mirror about xz : +y/-y yz : +x/-x xy : +z/-z

Returns:
modelBDF()

BDF : the BDF model object

nid_offsetint

the offset node id

eid_offsetint

the offset element id

pyNastran.bdf.mesh_utils.mirror_mesh.bdf_mirror_plane(bdf_filename: PathLike | BDF, plane: NDArray33float, mirror_model=None, log=None, debug: bool = True, use_nid_offset: bool = True)[source]

mirrors a model about an arbitrary plane

pyNastran.bdf.mesh_utils.mirror_mesh.write_bdf_symmetric(bdf_filename: PathLike | BDF, out_filename=None, encoding=None, size: int = 8, is_double: bool = False, enddata: bool | None = None, close: bool = True, plane: str = 'xz', log=None)[source]

Mirrors the model about the symmetry plane

Parameters:
bdf_filenamestr / BDF()

str : the bdf filename BDF : the BDF model object

out_filenamevaries; default=None

str - the name to call the output bdf file - a file object StringIO() - a StringIO object None - pops a dialog

encodingstr; default=None -> system specified encoding

the unicode encoding latin1, and utf8 are generally good options

sizeint; {8, 16}

the field size

is_doublebool; default=False

False : small field True : large field

enddatabool; default=None

bool - enable/disable writing ENDDATA None - depends on input BDF

closebool; default=True

should the output file be closed

planestr; {‘xy’, ‘yz’, ‘xz’}; default=’xz’

the plane to mirror about xz : +y/-y yz : +x/-x xy : +z/-z

Returns:
modelBDF()

BDF : the BDF model object

nid_offsetint

the offset node id

eid_offsetint

the offset element id

Notes

Updates the BDF object to be symmetric
  • see bdf_mirror if you don’t want to write the model

Doesn’t equivalence nodes on the centerline.

Considers
  • nodes : GRID

  • elements, rigid_elements, mass_elements : see _mirror_elements

  • loads : see _mirror_loads

  • aero cards : see _mirror_aero

extract_bodies Module

defines:
  • extract_bodies(bdf_filename)

pyNastran.bdf.mesh_utils.extract_bodies.extract_bodies(bdf_filename, mpc_id=0)[source]

Finds the isolated bodies

Parameters:
bdf_filenamestr/BDF

str : the path the the *.bdf file BDF : a BDF() boject

mpc_idint; default=0

0 : consider all MPCs >0 : use this MPC set not supported

Considers:
  • elements

  • rigid_elements

Doesn’t consider:
  • elements_mass

  • MPC

  • MPCADD

  • DMIx

Doesn’t support:
  • xref

  • duplicate element ids

  • large values

find_closest_nodes Module

defines:
  • nids_close = find_closest_nodes(nodes_xyz, nids, xyz_compare, neq_max, tol)

  • ieq = find_closest_nodes_index(nodes_xyz, xyz_compare, neq_max, tol)

pyNastran.bdf.mesh_utils.find_closest_nodes.find_closest_nodes(nodes_xyz: Any, nids: Any, xyz_compare: Any, neq_max: int = 1, tol: float | None = None, msg: str = '') Any[source]

Finds the closest nodes to an arbitrary set of xyz points

Parameters:
nodes_xyz(Nnodes, 3) float ndarray

the source points (e.g., xyz_cid0)

nids(Nnodes, ) int ndarray

the source node ids (e.g.; nid_cp_cid[:, 0])

xyz_compare(Ncompare, 3) float ndarray

the xyz points to compare to; xyz_to_find

tolfloat; default=None

the max spherical tolerance None : the whole model

neq_maxint; default=1

the number of “close” points

msgstr; default=’’

custom message used for errors

Returns:
nids_close: (Ncompare, ) int ndarray

the close node ids

pyNastran.bdf.mesh_utils.find_closest_nodes.find_closest_nodes_index(nodes_xyz: Any, xyz_compare: Any, neq_max: int, tol: float, msg: str = '')[source]

Finds the closest nodes to an arbitrary set of xyz points

Parameters:
nodes_xyz(Nnodes, 3) float ndarray

the source points

xyz_compare(Ncompare, 3) float ndarray

the xyz points to compare to

neq_maxint

the number of “close” points (default=4)

tolfloat

the max spherical tolerance

msgstr; default=’’

error message

Returns:
slots(Ncompare, ) int ndarray

the indices of the close nodes corresponding to nodes_xyz

pyNastran.bdf.mesh_utils.find_closest_nodes.get_y_mirrored_nodes(model: BDF, nids: np.ndarray, neq_max: int = 10, tol: float = 0.0001) dict[int, int][source]

find the nodes mirrored about the y=0 / xz plane

find_coplanar_elements Module

pyNastran.bdf.mesh_utils.find_coplanar_elements.find_coplanar_triangles(bdf_filename: BDF | str, eids: list[int] | None = None) list[int][source]

Finds coplanar triangles

Parameters:
bdf_filenameBDF/str

BDF: a model str: the path to the bdf input file

eidslist

the element ids to consider

Returns:
coplanar_eidslist[int]

the elements that are coplanar

force_to_pressure Module

pyNastran.bdf.mesh_utils.force_to_pressure.force_to_pressure(bdf_filename: str | PurePath | BDF, bdf_filename_out: str | PurePath | None = None, clear_model: bool = False)[source]

converts FORCE cards to PLOAD4s for a shell model

free_edges Module

defines:

edges = free_edges(model, eids=None) edges = non_paired_edges(model, eids=None)

pyNastran.bdf.mesh_utils.free_edges.free_edges(model: BDF, eids: list[int] | None = None, maps=None) list[tuple[int, int]][source]

Gets the free edges for shell elements. A free edge is an edge that is only connected to 1 shell element.

Parameters:
modelBDF()

the BDF model

eidslist[int]; default=None

a subset of elements to consider

mapslist[…] (default=None -> calculate)
the output from _get_maps(eids, map_names=None,

consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False)

Returns:
edges: list[tuple[int,int]]

list of node ids of each edges

pyNastran.bdf.mesh_utils.free_edges.non_paired_edges(model: BDF, eids: list[int] = None, maps=None) list[tuple[int, int]][source]

Gets the edges not shared by exactly 2 elements. This is useful for identifying rib/spar intersections.

Parameters:
modelBDF()

the BDF model

eidslist[int]; default=None

a subset of elements to consider

mapslist[…] (default=None -> calculate)
the output from _get_maps(eids, map_names=None,

consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False)

Returns:
non_paired_edgeslist[(int nid1, int nid2), …]

the non-paired edges

free_faces Module

defines:
  • get_element_faces(model, element_ids=None)

  • get_solid_skin_faces(model)

  • write_skin_solid_faces(model, skin_filename,

    write_solids=False, write_shells=True, size=8, is_double=False, encoding=None)

pyNastran.bdf.mesh_utils.free_faces.get_element_faces(model: BDF, element_ids: list[int] | None = None) Any[source]

Gets the elements and faces that are skinned from solid elements. This includes internal faces.

Parameters:
modelBDF()

the BDF object

element_idslist[int] / None

skin a subset of element faces default=None -> all elements

Returns:
eid_faces(int, list[(int, int, …)])

value1 : element id value2 : face

pyNastran.bdf.mesh_utils.free_faces.get_solid_skin_faces(model: BDF) Any[source]

Gets the elements and faces that are skinned from solid elements This doesn’t include internal faces.

Parameters:
modelBDF()

the BDF object

Returns:
eid_setdict[tuple(int, int, …)] = list[int]

key : sorted face value : list of element ids with that face

face_mapdict[tuple(int, int, …)] = list[int]

key : sorted face value : unsorted face

pyNastran.bdf.mesh_utils.free_faces.write_skin_solid_faces(model, skin_filename, write_solids=False, write_shells=True, size=8, is_double=False, encoding=None, punch=False, log=None)[source]

Writes the skinned elements

Parameters:
modelBDF() or str

BDF : the BDF object str : bdf_filename and the read_bdf method is called

skin_filenamestr

the file to write

write_solidsbool; default=False

write solid elements that have skinned faces

write_shellsbool; default=False

write shell elements

sizeint; default=8

the field width

is_doublebool; default=False

double precision flag

encodingstr; default=None -> system default

the string encoding

loglogger; default=None

a python logging object

punchbool; default=False

is this a punch file; should be used by the read_bdf if model is a string unused

get_oml Module

defines:
  • eids_oml = get_oml_eids(bdf_filename, eid_start, theta_tol=30.,

    is_symmetric=True, consider_flippped_normals=True)

pyNastran.bdf.mesh_utils.get_oml.get_oml_eids(bdf_filename: str | BDF | PurePath | StringIO, eid_start: int, theta_tol: float = 30.0, is_symmetric: bool = True, consider_flippped_normals: bool = True) tuple[BDF, set[int]][source]

Extracts the OML faces (outer mold line) of a shell model. In other words, find all the shell elements touching the current element without crossing an MPC or rigid element.

Parameters:
bdf_filenamestr or BDF()

the bdf filename

eid_startint

the element to start from

theta_tolfloat; default=30.

the angular tolerance in degrees

is_symmetricbool; default=True

is the y=0 plane considered to be part of the OML

consider_flippped_normalsbool; default=True

if you extracted the free faces from tets, you can get flipped normals this considers a 180 degree error to be 0.0, which will cause other problems

pyNastran.bdf.mesh_utils.get_oml.main()[source]

runs the test problem

remove_unused Module

defines some methods for cleaning up a model
  • model = remove_unused(bdf_filename, remove_nids=True, remove_cids=True,

    remove_pids=True, remove_mids=True)

pyNastran.bdf.mesh_utils.remove_unused.remove_unused(bdf_filename: str | PurePath, remove_nids: bool = True, remove_cids: bool = True, remove_pids: bool = True, remove_mids: bool = True, remove_spcs: bool = True, remove_mpcs: bool = True, remove_optimization: bool = True, reset_type_to_id_map: bool = False) tuple[BDF, dict[str, ndarray]][source]

Takes an uncross-referenced bdf and removes unused data

removes unused:
  • nodes

  • properties

  • materials

  • coords

  • spcs

  • mpcs

cannot be removed:
  • loads

split_cbars_by_pin_flag Module

defines:
  • model, pin_flag_map = split_cbars_by_pin_flag(

    bdf_filename, pin_flags_filename=None, bdf_filename_out=None)

pyNastran.bdf.mesh_utils.split_cbars_by_pin_flag.split_cbars_by_pin_flag(bdf_filename: str | PurePath, pin_flags_filename=None, bdf_filename_out=None, punch: bool = False, debug: bool = False)[source]

Splits bar elements if they have a pin flag. That way you can each side of the element (A/B) a unique color based on the pin flag. This doesn’t split non-pin flagged bars.

Parameters:
bdf_filenamestr; BDF

str : use the read_bdf method BDF : assume it’s a model

pin_flags_filenamestr; default=None

the pin flag file to write this is optional as you may need to define your own map

bdf_filename_outstr; default=None

write the updated deck

debugbool/None; default=True
used to set the logger if no logger is passed in

True: logs debug/info/error messages False: logs info/error messages None: logs error messages

Returns:
modelBDF()

the BDF object

pin_flag_mapdict[eid]pin_flag
eidint

the element id

pin_flagint

the bar pin flag

pyNastran.bdf.mesh_utils.split_cbars_by_pin_flag.write_pin_flag_map(pin_flag_map, pin_flags_filename)[source]

writes the pin flag map

split_elements Module

defines:
  • split_line_elements(bdf_model, eids, neids=2,

    eid_start=1, nid_start=1)

pyNastran.bdf.mesh_utils.split_elements.split_elements(bdf_filename)[source]

unimplemented method for splitting elements

pyNastran.bdf.mesh_utils.split_elements.split_line_elements(bdf_model, eids, neids=2, eid_start=1, nid_start=1)[source]

Splits a set of element ids

Parameters:
eidslist[int]

element ids to split

neidsint; default=5

how many elements should a single bar be split into min=2

eid_startint; default=1

the starting element id

nid_startint; default=1

the starting node id

Returns:
eids_outlist[int]

the list of elements that have been added

eid_endint; default=1

the final element id

nid_endint; default=1

the final node id

A—–*—–B; neids=2
A–*–B; neids=4

utils Module

defines:

bdf merge (IN_BDF_FILENAMES)… [-o OUT_BDF_FILENAME]

bdf equivalence IN_BDF_FILENAME EQ_TOL

bdf renumber IN_BDF_FILENAME [-o OUT_BDF_FILENAME]

bdf mirror IN_BDF_FILENAME [-o OUT_BDF_FILENAME] [–plane PLANE] [–tol TOL]

bdf export_mcids IN_BDF_FILENAME [-o OUT_GEOM_FILENAME]

bdf solid_dof IN_BDF_FILENAME [-o OUT_BDF_FILENAME] [–spc SPC]

bdf split_cbars_by_pin_flags IN_BDF_FILENAME [-o OUT_BDF_FILENAME]

bdf flutter UNITS [-o OUT_BDF_FILENAME]