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: str, tol: float, renumber_nodes: bool = False, neq_max: int = 4, xref: bool = True, node_set: list[NDArrayNint] | None = None, log: SimpleLogger | None = None, debug: bool = True, method: str = 'new', idtype: str = 'int32', fdtype: str = 'float64') tuple[BDF, list[tuple[int, int]]] [source]
helper for bdf_equivalence_nodes
- pyNastran.bdf.mesh_utils.bdf_equivalence._check_for_referenced_nodes(model: BDF, node_set: ndarray[Any, dtype[int64]] | None, nids: ndarray[Any, dtype[int64]], all_nids: ndarray[Any, dtype[int64]], nodes_xyz: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[int64]] | None [source]
helper function for
_eq_nodes_setup
- Parameters:
- nodes_xyz(nnode, 3) float array
the xyz for nids
- pyNastran.bdf.mesh_utils.bdf_equivalence._eq_nodes_build_tree_new(kdt: KDTree, nodes_xyz: NDArrayN3float, nids: NDArrayNint, all_node_set: NDArrayNint, nnodes: int, is_not_node_set: bool, tol: float, log: SimpleLogger, inew=None, node_set=None, neq_max: int = 4, msg: str = '', debug: float = False) list[tuple[int, int]] [source]
- pyNastran.bdf.mesh_utils.bdf_equivalence._eq_nodes_final(nid_pairs: list[tuple[int, int]], model: BDF, tol: float, all_node_set: ndarray[Any, dtype[int64]], debug: bool = False) None [source]
apply nodal equivalencing to model
- pyNastran.bdf.mesh_utils.bdf_equivalence._eq_nodes_setup_node(model: BDF, renumber_nodes: bool = False, idtype: str = 'int32') tuple[ndarray[Any, dtype[int64]], ndarray[Any, dtype[int64]]] [source]
helper function for
_eq_nodes_setup
that doesn’t handle node sets- Returns:
- nids(nnode,) int array
???
- all_nids(nnode,) int array
all the GRID ids
- pyNastran.bdf.mesh_utils.bdf_equivalence._eq_nodes_setup_node_set(model: BDF, node_set: list[ndarray[Any, dtype[int64]]], all_node_set: ndarray[Any, dtype[int64]], renumber_nodes: bool = False, idtype: str = 'int32') tuple[ndarray[Any, dtype[int64]], ndarray[Any, dtype[int64]]] [source]
helper function for
_eq_nodes_setup
that handles node_sets
- pyNastran.bdf.mesh_utils.bdf_equivalence._get_tree(nodes_xyz: ndarray[Any, dtype[float64]], msg: str = '') KDTree [source]
gets the kdtree
- pyNastran.bdf.mesh_utils.bdf_equivalence._get_xyz_cid0(model: BDF, nids: ndarray[Any, dtype[int64]], fdtype: str = 'float32') ndarray[Any, dtype[float64]] [source]
gets xyz_cid0
- pyNastran.bdf.mesh_utils.bdf_equivalence._nodes_xyz_nids_to_nid_pairs(nodes_xyz: NDArrayN3float, nids: NDArrayNint, all_node_set: NDArrayNint, tol: float, log: SimpleLogger, inew: NDArrayNint, node_set: NDArrayNint | None = None, neq_max: int = 4, method: str = 'new', debug: bool = False) list[tuple[int, int]] [source]
Helper for equivalencing
- Returns:
- nid_pairslist[tuple[int, int]]
a series of (nid1, nid2) pairs
- pyNastran.bdf.mesh_utils.bdf_equivalence._nodes_xyz_nids_to_nid_pairs_new(kdt: KDTree, nids: NDArrayNint, all_node_set: NDArrayNint, node_set: NDArrayNint | None, tol: float, log: SimpleLogger) list[tuple[int, int]] [source]
helper function for bdf_equivalence_nodes
- pyNastran.bdf.mesh_utils.bdf_equivalence._simplify_node_set(node_set: list[int] | set[int] | list[ndarray[Any, dtype[int64]]] | None, idtype: str = 'int32') list[ndarray[Any, dtype[int64]]] | None [source]
- accepts multiple forms of the node_set parameter
list[int]
set[int]
int ndarray
list[int ndarray]
- pyNastran.bdf.mesh_utils.bdf_equivalence._update_grid(node1: GRID, node2: GRID) None [source]
helper method for _eq_nodes_final
- pyNastran.bdf.mesh_utils.bdf_equivalence.bdf_equivalence_nodes(bdf_filename: str, bdf_filename_out: str | 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 ..
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._apply_scalar_cards(model: BDF, model2_renumber: BDF) None [source]
apply cards from model2 to model if they don’t exist in model
- pyNastran.bdf.mesh_utils.bdf_merge._assemble_mapper(mappers: list[MAPPER], mapper_0: MAPPER, data_members: list[str], mapper_renumber: MAPPER | None = None) None [source]
Assemble final mappings from all original ids to the ids in the merged and possibly renumbered model.
- Parameters:
- mapperslist[mapper]
- mapperdict[key]value
- key???
???
- value???
???
- mapper_0mapper
- key???
???
- value???
???
- data_memberslist[str]
- list of things to include in the mappers?
- data_members = [
‘coords’, ‘nodes’, ‘elements’, ‘masses’, ‘properties’, ‘properties_mass’, ‘materials’, ‘sets’, ‘rigid_elements’, ‘mpcs’,
]
- mapper_renumberdict[key]: value; default=None
- keystr
a BDF attribute
- valuedict[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, …
}
- Returns:
- mappers_alllist[mappers]
One mapper for each bdf_filename
- pyNastran.bdf.mesh_utils.bdf_merge._dict_key_to_key(dictionary) dict[int, int] [source]
creates a dummy map from the nominal key to the nominal key
- pyNastran.bdf.mesh_utils.bdf_merge._dicts_key_to_key(dictionaries: list[dict[int, Any]]) dict[int, int] [source]
Creates a dummy map from the nominal key to the nominal key for multiple input dictionaries. This is intended for use with:
SPCs, MPCs, Loads
- pyNastran.bdf.mesh_utils.bdf_merge._get_mapper_0(model: BDF) MAPPER [source]
Get the mapper for the first model.
- Parameters:
- modelBDF()
the bdf model object
- Returns:
- mapperdict[key]: value
- keystr
a BDF attribute
- valuedict[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, …
}
- pyNastran.bdf.mesh_utils.bdf_merge._renumber_mapper(mapper_0: MAPPER, mapper_renumber: MAPPER)[source]
Renumbers a mapper
- Parameters:
- mapper_0dict[key]: value
- keystr
a BDF attribute
- valuedict[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, …
}
- mapper_renumber???
???
- Returns:
- mapperdict[map_type]sub_mapper
- map_type???
???
- sub_mapperdict[key]value
- key???
???
- value???
???
- 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: CORDx 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._create_nid_maps(model, starting_id_dict, nid)[source]
builds the nid_maps
- pyNastran.bdf.mesh_utils.bdf_renumber._get_bdf_model(bdf_filename, cards_to_skip=None, log=None, debug=False)[source]
helper method
- pyNastran.bdf.mesh_utils.bdf_renumber._update_case_control(model, mapper)[source]
Updates the case control deck; helper method for
bdf_renumber
.- Parameters:
- modelBDF()
the BDF object
- mapperdict[str] = list[int]
Defines the possible case control header values for each entry (e.g. LOAD)
- pyNastran.bdf.mesh_utils.bdf_renumber._update_case_key(key, elemental_quantities, seti2, eid_map, nid_map)[source]
Updates a Case Control SET card. A set may have an elemental result or a nodal result.
- pyNastran.bdf.mesh_utils.bdf_renumber._update_coords(model, starting_id_dict, cid, cid_map)[source]
updates the coords
- pyNastran.bdf.mesh_utils.bdf_renumber._update_elements(model, starting_id_dict, eid, eid_map, mass_id_map, rigid_elements_map)[source]
updates the elements
- pyNastran.bdf.mesh_utils.bdf_renumber._update_materials(unused_model, starting_id_dict, mid, mid_map, all_materials)[source]
- pyNastran.bdf.mesh_utils.bdf_renumber._update_mpcs(model, starting_id_dict, mpc_id, mpc_map)[source]
updates the mpcs
- pyNastran.bdf.mesh_utils.bdf_renumber._update_nodes(model, starting_id_dict, nid, nid_map)[source]
updates the nodes
- pyNastran.bdf.mesh_utils.bdf_renumber._update_properties(model, starting_id_dict, pid, properties_map, properties_mass_map)[source]
updates the properties
- pyNastran.bdf.mesh_utils.bdf_renumber._update_spcs(model, starting_id_dict, spc_id, spc_map)[source]
updates the spcs
- pyNastran.bdf.mesh_utils.bdf_renumber._write_bdf(model, bdf_filename_out, size=8, is_double=False)[source]
helper method
- pyNastran.bdf.mesh_utils.bdf_renumber.bdf_renumber(bdf_filename: str | BDF | StringIO, bdf_filename_out: str, size=8, is_double=False, starting_id_dict=None, round_ids: bool = False, cards_to_skip: list[str] | None = None, log=None, debug=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.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)[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
- eidslist; (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_aero(model: BDF, xyz_scale: float, time_scale: float, force_scale: float) None [source]
- Converts the aero cards
CAEROx, PAEROx, SPLINEx, AECOMP, AELIST, AEPARM, AESURF
- Supports: AERO, AEROS, CAERO1, CAERO2, TRIM*, MONPNT1, FLUTTER FLFACT-rho/vel
GUST, AESURF, PAERO2
Skips: PAERO1, AESTAT, AESURFS, AECOMP, AELIST Doesn’t support:CAERO3-5, PAERO3-5, SPLINEx, AEPARM, AELINK, AEPRESS, AEFORCE, *probably not done
- pyNastran.bdf.mesh_utils.convert._convert_constraints(model: BDF, xyz_scale: float) None [source]
Converts the spc/mpcs
Supports: SPC1, SPC, SPCAX Implicitly supports: MPC, MPCADD, SPCADD
- pyNastran.bdf.mesh_utils.convert._convert_coordinates(model: BDF, xyz_scale: float) None [source]
Converts the coordinate systems
Supports: CORD1x, CORD2x
- pyNastran.bdf.mesh_utils.convert._convert_dconstr(model: BDF, dconstr: DCONSTR, pressure_scale: float) None [source]
helper for
_convert_optimization
- pyNastran.bdf.mesh_utils.convert._convert_desvars(desvars, scale)[source]
scales the DVPREL/DVCREL/DVMREL DESVAR values
- pyNastran.bdf.mesh_utils.convert._convert_dvcrel1(dvcrel: DVCREL1 | DVCREL2, xyz_scale: float, mass_scale: float) float [source]
helper for
_convert_optimization
- pyNastran.bdf.mesh_utils.convert._convert_dvmrel1(dvmrel, xyz_scale: float, mass_scale: float, force_scale: float, time_scale: float) float [source]
helper for
_convert_optimization
- pyNastran.bdf.mesh_utils.convert._convert_dvprel1(dvprel, xyz_scale: float, mass_scale: float, force_scale: float, time_scale: float) float [source]
helper for
_convert_optimization
- pyNastran.bdf.mesh_utils.convert._convert_elements(model: BDF, xyz_scale: float, time_scale: float, mass_scale: float, force_scale: float) None [source]
Converts the elements
- Supports: CTRIA3, CTRIA6, CTRIAR, CQUAD4, CQUAD8, CQUADR,
CELAS2, CELAS4, CDAMP2, CDAMP4, CBUSH, CONROD, CBAR, CBEAM, GENEL, CONM2, CMASS4
- SkipsCELAS1, CELAS3, CDAMP3, CDAMP5, CCONEAX,
CROD, CTUBE, CVISC, CBUSH1D, CQUAD, CSHEAR, CTRIAX, CTRIAX6, CTETRA, CPENTA, CHEXA, CPYRAM, CMASS1, CMASS3,
NX Skips: CTRAX3, CTRAX6, CPLSTN3, CPLSTN6, CPLSTN4’, CPLSTN8, CQUADX4, CQUADX8 *intentionally
- pyNastran.bdf.mesh_utils.convert._convert_loads(model: BDF, xyz_scale: float, time_scale: float, force_scale: float, temperature_scale: float) None [source]
Converts the loads
- Supports:
dloads: RLOAD1*, TLOAD1*
- loads: FORCE, FORCE1, FORCE2, MOMENT, MOMENT1, MOMENT2
GRAV, ACCEL1, PLOAD, PLOAD1, PLOAD2, PLOAD4, RANDPS
combinations: DLOAD, LOAD
probably not done
- pyNastran.bdf.mesh_utils.convert._convert_materials(model: BDF, xyz_scale: float, mass_scale: float, force_scale: float, temperature_scale: float) None [source]
Converts the materials
Supports: MAT1, MAT2, MAT3, MAT8, MAT9, MAT10, MAT11
- pyNastran.bdf.mesh_utils.convert._convert_nodes(model: BDF, xyz_scale: bool) None [source]
Converts the nodes
Supports: GRID
- pyNastran.bdf.mesh_utils.convert._convert_optimization(model: BDF, xyz_scale: float, mass_scale: float, force_scale: float, time_scale: float) None [source]
Converts the optimization objects
Limited Support: DESVAR, DCONSTR, DVCREL1, DVPREL1
- pyNastran.bdf.mesh_utils.convert._convert_pbar(scales: set[str], prop: PBAR, xyz_scale: float, area_scale: float, area_moi_scale: float, nsm_bar_scale: float) None [source]
converts a PBAR
- pyNastran.bdf.mesh_utils.convert._convert_pbeam(scales: set[str], prop: PBEAM, xyz_scale: float, area_scale: float, area_moi_scale: float, nsm_bar_scale: float) None [source]
converts a PBEAM
- pyNastran.bdf.mesh_utils.convert._convert_pbeam3(scales: set[str], prop: PBEAM3, xyz_scale: float, area_scale: float, area_moi_scale: float, nsm_bar_scale: float) None [source]
converts a PBEAM3
- pyNastran.bdf.mesh_utils.convert._convert_pbush(scales: set[str], prop: PBUSH, velocity_scale: float, mass_scale: float, stiffness_scale: float, log: SimpleLogger) None [source]
- pyNastran.bdf.mesh_utils.convert._convert_pbush1d(model: BDF, scales: set[str], prop: PBUSH1D, xyz_scale: float, area_scale: float, mass_scale: float, damping_scale: float, stiffness_scale: float, spring_tables: set[int], damper_tables: set[int]) None [source]
converts the PBUSH1D
- pyNastran.bdf.mesh_utils.convert._convert_properties(model: BDF, xyz_scale: float, time_scale: float, mass_scale: float, force_scale: float, temperature_scale: float) None [source]
Converts the properties
- Supports: PELAS, PDAMP, PDAMP5, PVISC, PROD, PBAR, PBARL, PBEAM, PBEAML,
PSHELL, PSHEAR, PCOMP, PCOMPG, PELAS, PTUBE, PBUSH, PCONEAX, PGAP, PBUSH1D
Skips : PSOLID, PLSOLID, PLPLANE, PIHEX
Skips are unscaled (intentionally)
Warning
PBUSH1D tables should only be used by PBUSH1D
- pyNastran.bdf.mesh_utils.convert._get_dload_scale(dload, scales: set[str], xyz_scale: float, velocity_scale: float, accel_scale: float, force_scale: float) None [source]
LOAD assumes force
- pyNastran.bdf.mesh_utils.convert._get_pbush1d_tables(prop: PBUSH1D, table_names: tuple[str], tables_set: set[int])[source]
- pyNastran.bdf.mesh_utils.convert._scale_caero(caero, xyz_scale: float, xyz_aefacts: set[int]) None [source]
- pyNastran.bdf.mesh_utils.convert._scale_term(name: str, coeffs: list[float], terms: list[float], scales: list[float]) tuple[float, str] [source]
- pyNastran.bdf.mesh_utils.convert._set_pbush1d_tables(model: BDF, scales: set[str], spring_tables: set[int], damper_tables: set[int], xyz_scale: float, velocity_scale: float, force_scale: float) None [source]
Sets all the TABLEDx required by the PBUSH1D.
Note
Assumes TABLEs are not reused for other cards.
- pyNastran.bdf.mesh_utils.convert._set_wtmass(model: BDF, gravity_scale: float) None [source]
set the PARAM,WTMASS
ft-lbm-s-lbf-psf : 1. / 32.2 in-lbm-s-lbf-psi : 1. / (32.2*12) m-kg-s-N-Pa : 1. mm-Mg-s-N-Mpa : 1. in-slinch-s-lbf-psi : 1. ft-slug-s-lbf-psf : 1. in-slug-s-lbf-psi : 1 / 12.
1 slug * 1 ft/s^2 = 1 lbf 1 slinch * 1 in/s^2 = 1 lbf 1 slinch = 12 slug
F = m*a 386 lbf = 1 slinch * 386 * in/s^2 32 lbf = 1 slug * 32 * ft/s^2 1 N = 1 kg * 9.8 m/s^2
1 lbf = g_scale * 1 slinch * 1 in/s^2 1 lbf = g_scale * 12 slug * 1 in/s^2 –> g_scale = 1/12.
- pyNastran.bdf.mesh_utils.convert._setup_scale_by_terms(scales: list[float], terms: list[str], quiet: bool = False) tuple[float, float, float] [source]
determines the mass, length, time scaling factors
- pyNastran.bdf.mesh_utils.convert._write_scales(log: SimpleLogger, scale_map: dict[str, str], scales: set[str], keys_to_skip={})[source]
- 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, length_to)[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[float], scales: list[float], bdf_filename_out: str | None = None, encoding: str | None = None, log=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._is_bad_quad(eid: int, p1, p2, p3, p4, log: SimpleLogger, max_aspect_ratio: float, min_theta_quad: float, max_theta: float, max_skew: float, max_taper_ratio: float, max_warping: float) bool [source]
identifies if a CQUAD4 has poor quality
- pyNastran.bdf.mesh_utils.delete_bad_elements._is_bad_tri(eid: int, p1, p2, p3, log: SimpleLogger, max_aspect_ratio: float, min_theta_tri: float, max_theta: float, max_skew: float) bool [source]
identifies if a CTRIA3 has poor quality
- 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.
- valuesThe result is
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
export_mcids
Module
- Defines:
nodes, bars = export_mcids(bdf_filename, csv_filename=None)
- pyNastran.bdf.mesh_utils.export_mcids._add_elements(nid: int, eid: int, nodes: list[tuple[int, float, float, float]], bars: list[tuple[int, int, int]], centroid: ndarray, iaxis: ndarray, jaxis: ndarray, export_both_axes: bool, export_xaxis: bool) tuple[int, int] [source]
adds the element data
- pyNastran.bdf.mesh_utils.export_mcids._export_coord_axes(nodes, bars, csv_filename: str)[source]
save the coordinate systems in a csv file
- pyNastran.bdf.mesh_utils.export_mcids._export_quad_mcid(model: BDF, elem, nodes, iply: int, nid: int, eid: int, bars: list[list[int]], export_both_axes: bool, export_xaxis: bool, consider_property_rotation: bool) tuple[int, int] [source]
helper method for
export_mcids
- pyNastran.bdf.mesh_utils.export_mcids._export_quad_mcid_all(model: BDF, elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, nplies: int, nids: dict[int, int], nodes: dict[int, list[ndarray]], bars: dict[int, list[tuple[int, int]]]) None [source]
helper method for
export_mcids
- pyNastran.bdf.mesh_utils.export_mcids._export_tri_mcid_all(model: BDF, elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, nplies: int, nids: dict[int, int], nodes: dict[int, list[ndarray]], bars: dict[int, list[tuple[int, int]]]) None [source]
helper method for
export_mcids
- pyNastran.bdf.mesh_utils.export_mcids._export_tria_mcid(model: BDF, elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, nodes, iply: int, nid: int, eid: int, bars, export_both_axes: bool, export_xaxis: bool, consider_property_rotation: bool) tuple[int, int] [source]
helper method for
export_mcids
- pyNastran.bdf.mesh_utils.export_mcids._export_xaxis(nid: int, nodes: list[ndarray], bars: list[ndarray], centroid: ndarray, iaxis: ndarray) int [source]
- pyNastran.bdf.mesh_utils.export_mcids._load_bdf(bdf_filename: BDF | str, log: SimpleLogger | None = None, debug: bool = True) BDF [source]
- pyNastran.bdf.mesh_utils.export_mcids._make_element_coord_quad(elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, pid_ref, nids, nodes, bars)[source]
- pyNastran.bdf.mesh_utils.export_mcids._make_element_coord_tri(elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, pid_ref, nids, nodes, bars)[source]
- pyNastran.bdf.mesh_utils.export_mcids._rotate_coords(elem: ShellElement, pid_ref, nplies: int, nids: dict[int, int], nodes: dict[int, list[Any]], bars: dict[int, list[Any]], dxyz: float, centroid: np.ndarray, imat: np.ndarray, jmat: np.ndarray, normal: np.ndarray) None [source]
iply Final Label Description ==== =========== =========== -1 0 material coordinate system 0 1 ply 1 1 2 ply 2 2 3 ply 3
#nplies = 3 nids - {-1: 0, 0: 0, 1: 0, 2: 0} nodes = {-1: [], 0: [], 1: [], 2: []} bars = {-1: [], 0: [], 1: [], 2: []}
- pyNastran.bdf.mesh_utils.export_mcids._rotate_mcid(elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, pid_ref: PCOMP | PCOMPG | PSHELL, iply: int, imat: ndarray, jmat: ndarray, normal: ndarray, consider_property_rotation: bool = True) tuple[ndarray, ndarray] [source]
Rotates a material coordinate system. Assumes the element theta/mcid has already been acounted for.
- pyNastran.bdf.mesh_utils.export_mcids._rotate_single_coord(elem: CTRIA3 | CTRIA6 | CQUAD4 | CQUAD8 | CTRIAR | CQUADR, pid_ref, iply: int, nid, eid, nodes, bars, dxyz: float, centroid: ndarray, imat: ndarray, jmat: ndarray, normal: ndarray, export_both_axes: bool, export_xaxis: bool, consider_property_rotation: bool) tuple[int, int] [source]
- 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
- csv_filenamestr; default=None
str : the path to the output csv None : don’t write a CSV
- eidslist[int]
the element ids to consider
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
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.__mirror_elements(model: BDF, mirror_model: BDF, nid_offset: int, eid_offset: int, cid_offset: int, plane: str = 'xz') None [source]
mirrors model.elements
- pyNastran.bdf.mesh_utils.mirror_mesh.__mirror_masses(model: BDF, mirror_model: BDF, nid_offset: int, eid_offset: int) None [source]
mirrors model.masses
- pyNastran.bdf.mesh_utils.mirror_mesh.__mirror_mpcs(model: BDF, mirror_model: BDF, nid_offset: int) None [source]
mirrors model.rigid_elements
- pyNastran.bdf.mesh_utils.mirror_mesh.__mirror_rigid_elements(model: BDF, mirror_model: BDF, nid_offset: int, eid_offset: int) None [source]
mirrors model.rigid_elements
- pyNastran.bdf.mesh_utils.mirror_mesh._asymmetrically_mirror_coords(model: BDF, mirror_model: BDF, cids_nominal_set: set[int], cid_offset: int, plane: str = 'xz') None [source]
leave i the same, flip j, and invert k
TODO: doesn’t handle CORD1x
- pyNastran.bdf.mesh_utils.mirror_mesh._asymmetrically_mirror_coords2(model: BDF, mirror_model: BDF, cids_nominal_set: set[int], cid_offset: int, plane: str = 'xz') None [source]
We’ll invert i, but not j, which will invert k.
This will allow us to mirror material coordinate systems (defined in x). Additionally, we can mirror CGAP coordinate systems (defined in x) as well as some arbitrary y-direction. We’ll try to make y look mirrored.
- pyNastran.bdf.mesh_utils.mirror_mesh._get_cid_offset(model: BDF, use_cid_offset: bool) int [source]
- pyNastran.bdf.mesh_utils.mirror_mesh._get_eid_offset(model: BDF, use_eid_offset: bool) int [source]
- pyNastran.bdf.mesh_utils.mirror_mesh._mirror_aero(model: BDF, mirror_model: BDF, nid_offset: int, plane: str = 'xz') None [source]
Mirrors the aero cards
- Considers:
AEROS
doesn’t consider sideslip
CAERO1
doesn’t consider sideslip
considers Cp
considers lchord/lspan/nchord/nspan
SPLINE1 - handle boxes
SET1 - handle nodes
AELIST - handle boxes
AESURF - only supports names of length 7 or less (appends an M to the name) - handles AELIST - doesn’t handle coords well - doesn’t handle second AESURF
- Doesnt consider:
AERO
AEFORCE
AEPRES
CAERO2/3/4/5
PAERO1/2/3/4/5
AESURFS
- pyNastran.bdf.mesh_utils.mirror_mesh._mirror_elements(model: BDF, mirror_model: BDF, nid_offset: int, use_eid_offset: bool = True, plane: str = 'xz') int [source]
Mirrors the elements
- Parameters:
- modelBDF
the base model
- modelBDF
the mirrored model
- mirror_modelBDF
the mirrored model
- nid_offsetint
the node id offset
- use_eid_offsetbool; default=True
what is this for???
- elements:
- 0dCELAS1, CELAS2, CELAS3, CELAS4, CDAMP1, CDAMP2, CDAMP3, CDAMP4, CDAMP5
CFAST, CBUSH, CBUSH1D
1d: CROD, CONROD, CTUBE, CBAR, CBEAM, CBEAM3 2d : CTRIA3, CQUAD4, CTRIA6, CQUAD8, CQUAD, CTRIAR, CQUADR 3d : ??? missing : CVISC, CTRIAX, CTRIAX6, CQUADX, CQUADX8, CCONEAX
- rigid_elements:
loaded: RBE2, RBE3, RBAR missing: RBAR1
- mass_elements:
loaded: CONM2 missing CONM1, CMASS1, CMASS2, CMASS3, CMASS4
- plotels:
loaded: PLOTEL missing: ???
Notes
Doesn’t handle CBAR/CBEAM offsets Doesn’t handle CBEAM SPOINTs Do I need to invert the solids?
- pyNastran.bdf.mesh_utils.mirror_mesh._mirror_loads(model: BDF, mirror_model: BDF, nid_offset: int = 0, eid_offset: int = 0) None [source]
Mirrors the loads. A mirrored force acts in the same direction.
- Considers:
- PLOAD4
no coordinate systems (assumes cid=0)
FORCE, FORCE1, FORCE2, MOMENT, MOMENT1, MOMENT2
PLOAD, PLOAD2, PLOAD4
TEMP, QVOL, QHBDY, QBDY1, QBDY2, QBDY3
- pyNastran.bdf.mesh_utils.mirror_mesh._mirror_nodes(model: BDF, mirror_model: BDF, plane: str = 'xz') tuple[int, str] [source]
Mirrors the GRIDs
Warning
doesn’t consider coordinate systems; it could, but you’d need 20 new coordinate systems
Warning
doesn’t mirror SPOINTs, EPOINTs
- pyNastran.bdf.mesh_utils.mirror_mesh._mirror_nodes_plane(model: BDF, mirror_model: BDF, plane: ndarray[Any, dtype[float64]], use_nid_offset: bool = True) tuple[int, str] [source]
Mirrors the GRIDs about an arbitrary plane
- Parameters:
- modelBDF
the original geometry
- mirror_modelBDF
the location of the new geometry
- plane(3,3) float ndarray
3 vectors that defines the origin, zaxis and xzplane; same as a CORD2R
- use_nid_offsetbool
should the node offset be applied
- Returns:
- nid_offsetint
the node id offset
- planestr
the sorted plane; ZX -> xz
Warning
doesn’t consider coordinate systems; it could, but you’d need 20 new coordinate systems
Warning
doesn’t mirror SPOINTs, EPOINTs ..
- pyNastran.bdf.mesh_utils.mirror_mesh._plane_to_iy(plane: str) tuple[int, str] [source]
gets the index fo the mirror plane
- pyNastran.bdf.mesh_utils.mirror_mesh.bdf_mirror(bdf_filename: str | BDF, plane: str = 'xz', log=None, debug: bool = True)[source]
Mirrors the model about the symmetry plane
- Parameters:
- bdf_filenamestr / BDF()
str : the bdf filename BDF : the BDF model object
- 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: str | BDF, plane: ndarray[Any, dtype[float64]], 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: str | 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._not_equal_nodes_build_tree(nodes_xyz: ndarray[Any, dtype[float64]], xyz_compare: ndarray[Any, dtype[float64]], tol: float, neq_max: int = 4, msg: str = '') tuple[Any, ndarray, ndarray] [source]
helper function for bdf_equivalence_nodes
- Parameters:
- nodes_xyz(Nnodes, 3) float ndarray
the source points
- xyz_compare(Ncompare, 3) float ndarray
the xyz points to compare to
- tolfloat
the max spherical tolerance
- neq_maxint; default=4
the number of close nodes
- msgstr; default=’’
error message
- Returns:
- kdtKDTree()
the kdtree object
- ieqint ndarray
The indices of nodes_xyz where the nodes in xyz_compare are close??? neq_max = 1:
(N, ) int ndarray
- neq_max > 1:
(N, N) int ndarray
- slotsint ndarray
The indices of nodes_xyz where the nodes in xyz_compare are close??? neq_max = 1:
(N, ) int ndarray
- neq_max > 1:
(N, N) int ndarray
- msgstr; default=’’
error message
- pyNastran.bdf.mesh_utils.find_closest_nodes.find_closest_nodes(nodes_xyz: ndarray[Any, dtype[float64]], nids: ndarray[Any, dtype[int64]], xyz_compare: ndarray[Any, dtype[float64]], neq_max: int = 1, tol: float | None = None, msg: str = '') ndarray[Any, dtype[int64]] [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: ndarray[Any, dtype[float64]], xyz_compare: ndarray[Any, dtype[float64]], 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
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
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._write_shells(bdf_file, model, eid_set, face_map, eid_shell, pid_shell, mid_shell, mids_to_write)[source]
helper method for
_write_skin_solid_faces
- pyNastran.bdf.mesh_utils.free_faces._write_skin_solid_faces(model, skin_filename, face_map, nids_to_write, eids_to_write, mids_to_write, eid_set, eid_shell, pid_shell, mid_shell, write_solids=False, write_shells=True, size=8, is_double=False, encoding=None)[source]
helper method for
write_skin_solid_faces
- Parameters:
- modelBDF()
the BDF object
- skin_filenamestr
the file to write
- face_mapdict[sorted_face]face
sorted_face : list[int, int, int] / list[int, int, int, int] face : list[int, int, int] / list[int, int, int, int]
- nids_to_writelist[int, int, …]
list of node ids to write
- eids_to_writelist[int, int, …]
list of element ids to write
- mids_to_writelist[int, int, …]
list of material ids to write
- eid_setset[int]
is the type right???
- eid_shellint
the next id to use for the shell id
- pid_shellint
the next id to use for the shell property
- mid_shellint
the next id to use for the shell material
- write_solidsbool; default=False
write solid elements that have skinned faces
- write_shellsbool; default=True
write shell elements
- sizeint; default=/8
the field width
- is_doublebool; default=False
double precision flag
- encodingstr; default=None -> system default
the string encoding
- 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
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(model: BDF, nids_used: set[int], cids_used: set[int], pids_used: set[int], pids_mass_used: set[int], mids_used: set[int], spcs_used: set[int], mpcs_used: set[int], pconv_used: set[int], tableht_used: set[int], tableh1_used: set[int], desvars_used: set[int], dresps_used: set[int], 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_desvars: bool = True, remove_optimization: bool = True) None [source]
actually removes the cards
- pyNastran.bdf.mesh_utils.remove_unused._remove_optimization(model: BDF, pids_to_remove: list[int], desvars_to_remove: list[int], dresps_to_remove: list[int]) None [source]
- pyNastran.bdf.mesh_utils.remove_unused._remove_thermal(model: BDF, pconv_used, tableht_used, tableh1_used) None [source]
removes some thermal cards
- pyNastran.bdf.mesh_utils.remove_unused._store_aero(model: BDF, spline_set_nodes: set[int], nids_used: set[int], cids_used: set[int]) None [source]
- pyNastran.bdf.mesh_utils.remove_unused._store_dresp1(model: BDF, ids, nids_used, pids_used, dresps_used)[source]
helper for
remove_unused
- pyNastran.bdf.mesh_utils.remove_unused._store_elements(card_type, model, ids, nids_used, pids_used, mids_used, cids_used)[source]
- pyNastran.bdf.mesh_utils.remove_unused._store_loads(model, unused_card_type, unused_ids, nids_used, eids_used, cids_used)[source]
helper for
remove_unused
- pyNastran.bdf.mesh_utils.remove_unused._store_masses(card_type, model, ids, nids_used, pids_mass_used, cids_used) None [source]
handles masses
- pyNastran.bdf.mesh_utils.remove_unused._store_nsm(model, ids, pids_used)[source]
helper for
remove_unused
- pyNastran.bdf.mesh_utils.remove_unused._store_splines(model: BDF, card_type: str, ids: ndarray, nids_used: set[int], sets_used: set[int], spline_set_nodes: set[int])[source]
- pyNastran.bdf.mesh_utils.remove_unused.remove_unused(bdf_filename: str, 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) BDF [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, pin_flags_filename=None, bdf_filename_out=None, debug=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
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:
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 split_cbars_by_pin_flags IN_BDF_FILENAME [-o OUT_BDF_FILENAME]
- ‘
bdf flutter UNITS [-o OUT_BDF_FILENAME]
- pyNastran.bdf.mesh_utils.utils._apply_float_values_to_dict(data: dict[str, Any], defaults: dict[str, float]) None [source]
- pyNastran.bdf.mesh_utils.utils.cmd_line(argv=None, quiet: bool = False)[source]
command line interface to multiple other command line scripts
- pyNastran.bdf.mesh_utils.utils.cmd_line_bin(argv=None, quiet=False)[source]
bins the model into nbins
- pyNastran.bdf.mesh_utils.utils.cmd_line_convert(argv=None, quiet=False)[source]
command line interface to bdf_merge
- pyNastran.bdf.mesh_utils.utils.cmd_line_delete_bad_shells(argv=None, quiet: bool = False) None [source]
command line interface to
delete_bad_shells
- pyNastran.bdf.mesh_utils.utils.cmd_line_export_mcids(argv=None, quiet=False)[source]
command line interface to export_mcids
- pyNastran.bdf.mesh_utils.utils.cmd_line_filter(argv=None, quiet=False)[source]
command line interface to bdf filter
- pyNastran.bdf.mesh_utils.utils.cmd_line_flip_shell_normals(argv=None, quiet: bool = False)[source]
command line interface to flip_shell_normals
- pyNastran.bdf.mesh_utils.utils.cmd_line_free_faces(argv=None, quiet=False)[source]
command line interface to bdf free_faces
- pyNastran.bdf.mesh_utils.utils.cmd_line_mirror(argv=None, quiet: bool = False)[source]
command line interface to write_bdf_symmetric
- pyNastran.bdf.mesh_utils.utils.cmd_line_remove_unused(argv=None, quiet=False)[source]
command line interface to remove_unused
- pyNastran.bdf.mesh_utils.utils.cmd_line_renumber(argv=None, quiet=False)[source]
command line interface to bdf_renumber