visualdynamics.core.instrumentation¶
instrumentation
¶
Planning a test's instrumentation from a finite element model.
Where accelerometers can go, and which of those places best measure a chosen set of modes, by Effective Independence (Kammer, "Sensor placement for on-orbit modal identification and correlation of large space structures", Journal of Guidance, Control, and Dynamics 14(2), 1991).
skin splits the model's reachable outside into surfaces, the pieces a
person would name when saying where a sensor may go: a block's six
faces, a cylinder's side, the inside of a box. A solid contributes only
its outer surface, less the faces where it touches another part; a
plate contributes all of it. Neighboring faces belong to one surface
while their normals are within EDGE_ANGLE of each other, so a surface
ends at a sharp edge.
candidates makes the experimental geometry of every place a sensor
can sit on the surfaces kept: one node per candidate, each measured in its own coordinate
system whose +Z is the outward normal of the surface it sits on and
whose +X lies in that surface along the global axis least aligned with
the normal, so it is in the plane of a system axis wherever the
surface allows. A node where surfaces meet at an edge or a corner is a
candidate on each of them, so that a sensor sits flat on one; within a
surface the faces' normals at the node are averaged. A plate's normal
points away from the middle of the model. Beams contribute every node,
measured in the global system. A place nearer than edge_distance to
its surface's edge is not a candidate, since a sensor's base needs flat
ground around the spot it is glued to; an edge here is wherever the
surface ends, at a sharp edge, a free edge, a hole or where parts touch.
local_shapes turns a shape set's translations into each candidate's
own directions, and effective_independence chooses the sensors:
tri-axial accelerometers first, as blocks of three directions at one
place, then uni-axial ones along single directions with the tri-axial
places fixed. Each pass removes, one candidate at a time, the one whose
removal shrinks the determinant of the Fisher information matrix the
least, and while far more candidates remain than are wanted it removes
the weakest tenth at a time.
Classes:
| Name | Description |
|---|---|
Surface |
One surface of the model a sensor can sit on. |
Candidates |
The places a sensor can sit, as an experimental geometry. |
Placement |
The sensors Effective Independence chose. |
Plan |
An instrumentation plan, as the three objects a test is set up |
FewerDirectionsWarning |
The sensors measure fewer directions than there are modes: the |
Functions:
| Name | Description |
|---|---|
skin |
The surfaces of |
default_surfaces |
The surfaces sensors go on unless told otherwise: every one of at |
candidates |
Every place on |
surface_frame |
The axes of a sensor on a surface with this outward normal, rows |
local_shapes |
The modes' translations at each candidate, in its own directions. |
effective_independence |
Choose sensors by Effective Independence, tri-axial first. |
plan |
Plan a test's accelerometers from a finite element model. |
lowest_first |
The positions in |
shortfall |
What a plan for fewer modes than the |
elastic |
The indices of a shape set's modes above 0 Hz: what a plan |
assemble |
The three objects of a plan from what Effective Independence |
Classes¶
Surface
dataclass
¶
Surface(id: int, group: int, kind: str, faces: list[tuple[int, ...]], normals: ndarray, areas: ndarray)
One surface of the model a sensor can sit on.
Attributes:
id: Its number, from 1, in the order of the elements its first
face belongs to: the same for the same geometry every time.
group: The element group it belongs to.
kind: 'solid' for a solid's outside, 'plate' for a plate.
faces: Its faces, each as its corner nodes in order around it.
normals: (faces, 3), each face's outward unit normal.
areas: Each face's area.
Attributes:
| Name | Type | Description |
|---|---|---|
area |
float
|
The surface's whole area. |
Candidates
dataclass
¶
Candidates(geometry: Any, source: ndarray, kind: list[str] = list(), surface: ndarray = (lambda: zeros(0, dtype=int64))())
The places a sensor can sit, as an experimental geometry.
Attributes:
geometry: One node per candidate, each measured in a coordinate
system of its own (node_disp_cs), +Z the outward normal.
source: The finite element node each candidate sits on, in the
order of geometry.node_id. A node where faces meet at an
edge gives more than one candidate, so a candidate's id is
its source node's id only for the first of them.
kind: Per candidate, 'solid', 'plate' or 'line': what it sits on.
surface: Per candidate, the id of the Surface it sits on; 0
for a beam's node.
Attributes:
| Name | Type | Description |
|---|---|---|
frames |
ndarray
|
|
Placement
dataclass
¶
Placement(triaxial: list[int], uniaxial: list[tuple[int, int]], information: ndarray, independence: ndarray, planned: ndarray = (lambda: zeros(0, dtype=int64))())
The sensors Effective Independence chose.
Attributes:
triaxial: Candidate indices given a tri-axial accelerometer.
uniaxial: (candidate index, axis) per uni-axial accelerometer,
the axis 0, 1 or 2 for the candidate's X, Y or Z.
information: The Fisher information matrix of the chosen
directions over the modes planned for, (planned, planned).
independence: Each chosen sensor's share of the information:
for a tri-axial accelerometer the sum over its three
directions of the effective independence, for a uni-axial
one its single value; tri-axial first, in the order above.
They sum to the number of modes planned for.
planned: The modes the sensors were chosen for, as positions in
the modes given: all of them, or, when the sensors measure
fewer directions than there are modes, the lowest that many.
Attributes:
| Name | Type | Description |
|---|---|---|
condition |
float
|
The condition number of the information matrix: how nearly |
Plan
dataclass
¶
Plan(geometry: Any, channels: Any, shapes: Any, placement: Placement)
An instrumentation plan, as the three objects a test is set up from.
Attributes:
geometry: The experimental geometry of the chosen places only,
each measured in its own system (+Z out of the surface).
channels: The channel table: one row per measured direction,
tri-axial accelerometers first, each's three rows sharing a
node and named by its leg (triax_dof).
shapes: The finite element modes at exactly those channels, in
the places' own directions, for correlating the test.
placement: What Effective Independence chose, with the
information matrix and each sensor's share.
FewerDirectionsWarning
¶
Bases: UserWarning
The sensors measure fewer directions than there are modes: the plan is made for the lowest modes only, and the others cannot be told apart by it.
Functions:¶
skin
¶
skin(geometry: Any, *, edge_angle: float = EDGE_ANGLE) -> list[Surface]
The surfaces of geometry a sensor can sit on: the solids'
outside less where parts touch, and the plates, each split at its
sharp edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geometry
|
Geometry
|
The finite element model's geometry. |
required |
edge_angle
|
float
|
Degrees between two neighboring faces' normals beyond which they are on separate surfaces. |
EDGE_ANGLE
|
Returns:
| Type | Description |
|---|---|
list of Surface
|
Numbered from 1, in the order of the elements. |
Source code in src/visualdynamics/core/instrumentation.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | |
default_surfaces
¶
default_surfaces(found: list[Surface]) -> list[int]
The surfaces sensors go on unless told otherwise: every one of at
least SMALL_SURFACE of the whole outside's area. Sensors go on
the significant surfaces of a test article; a small one is most
often a sliver along an edge, a fillet or a hole's bore. When no
surface is that large, all of them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
found
|
list of Surface
|
From |
required |
Returns:
| Type | Description |
|---|---|
list of int
|
Their ids, in order. |
Source code in src/visualdynamics/core/instrumentation.py
candidates
¶
candidates(geometry: Any, groups: Any = None, surfaces: Any = None, *, edge_angle: float = EDGE_ANGLE, found: Any = None, edge_distance: float = 0.0) -> Candidates
Every place on geometry a sensor can be mounted, as an
experimental geometry with a coordinate system per place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geometry
|
Geometry
|
The finite element model's geometry. |
required |
groups
|
sequence of int
|
The element groups sensors may go on. All of them when omitted. A face shared with a group that is not picked is still inside. |
None
|
surfaces
|
sequence of int
|
The surfaces sensors may go on, by |
None
|
edge_angle
|
float
|
Degrees between two neighboring faces' normals beyond which they are on separate surfaces. |
EDGE_ANGLE
|
found
|
list of Surface
|
|
None
|
edge_distance
|
float
|
How near a place may be to its surface's edge, in the geometry's coordinates (meters once its units are defined), measured in a straight line. Nothing is left out at 0. A surface with no edge, such as a whole sphere, keeps every place. |
0
|
Returns:
| Type | Description |
|---|---|
Candidates
|
|
Source code in src/visualdynamics/core/instrumentation.py
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | |
surface_frame
¶
The axes of a sensor on a surface with this outward normal, rows X, Y, Z: Z the normal, X the global axis least aligned with it laid into the surface, Y completing a right-handed set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normal
|
array_like
|
The outward normal; any length. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in src/visualdynamics/core/instrumentation.py
local_shapes
¶
local_shapes(shapes: Any, modes: Any, plan: Candidates, geometry: Any) -> tuple[ndarray, ndarray]
The modes' translations at each candidate, in its own directions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shapes
|
ShapeSet
|
The finite element modes. |
required |
modes
|
sequence of int
|
Which of them, by index. |
required |
plan
|
Candidates
|
Where sensors can go. |
required |
geometry
|
Geometry
|
The finite element geometry the shapes are measured on, whose coordinate systems say which way each DOF points. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
blocks |
ndarray
|
|
measured |
ndarray
|
Per candidate, whether the shapes cover all three translations at its node. A candidate they do not cover cannot be chosen. |
Source code in src/visualdynamics/core/instrumentation.py
effective_independence
¶
effective_independence(blocks: Any, triaxial: int, uniaxial: int = 0, *, axes: Any = (2,), allowed: Any = None, sources: Any = None, lowest: Any = None) -> Placement
Choose sensors by Effective Independence, tri-axial first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blocks
|
array_like
|
|
required |
triaxial
|
int
|
How many tri-axial accelerometers. |
required |
uniaxial
|
int
|
How many uni-axial accelerometers. |
0
|
axes
|
sequence of int
|
Which of a candidate's directions a uni-axial accelerometer may measure: its Z, the surface normal, by default. |
(2,)
|
allowed
|
array_like of bool
|
Per candidate, whether it may be chosen at all. |
None
|
sources
|
array_like of int
|
Per candidate, the node it sits on. A tri-axial accelerometer measures the same three translations whichever face of an edge it is given, so only one candidate per node is offered for them. |
None
|
lowest
|
array_like of int
|
The modes' positions, lowest frequency first: the order in which modes are planned for when the sensors cannot resolve them all. The order given when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
Placement
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When there are no sensors, fewer candidates than sensors, or the chosen directions cannot tell the modes planned for apart. |
Notes
Sensors measuring D directions resolve at most D modes. With fewer
directions than modes, the plan is made for the lowest D
(Placement.planned). The tri-axial pass on its own is held to the
same rule: it chooses for the lowest 3 x triaxial modes, and the
uni-axial pass then chooses for all the modes planned for, with the
tri-axial places fixed. Chosen for more modes than it can resolve,
the tri-axial pass works on a singular information matrix, and the
rounding of the arithmetic decides.
Source code in src/visualdynamics/core/instrumentation.py
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 | |
plan
¶
plan(shapes: Any, geometry: Any, triaxial: int, uniaxial: int = 0, *, modes: Any = None, groups: Any = None, surfaces: Any = None, edge_angle: float | None = None, axes: Any = (2,), edge_distance: float | None = None) -> Plan
Plan a test's accelerometers from a finite element model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shapes
|
ShapeSet
|
The finite element modes. |
required |
geometry
|
Geometry
|
The geometry they are on. |
required |
triaxial
|
int
|
How many tri-axial accelerometers. |
required |
uniaxial
|
int
|
How many uni-axial accelerometers. |
0
|
modes
|
sequence of int
|
The modes to measure, by index. The elastic modes (every one above 0 Hz) when omitted. |
None
|
groups
|
sequence of int
|
The element groups sensors may go on. All when omitted. |
None
|
surfaces
|
sequence of int
|
The surfaces sensors may go on, by |
None
|
edge_angle
|
float
|
Degrees between neighboring faces' normals beyond which they are
on separate surfaces; |
None
|
axes
|
sequence of int
|
The directions a uni-axial accelerometer may measure: 0, 1, 2 for a place's X, Y, Z. Z, the surface normal, by default. |
(2,)
|
edge_distance
|
float
|
How near a sensor may be to its surface's edge, in the
geometry's coordinates. |
None
|
Returns:
| Type | Description |
|---|---|
Plan
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When no mode is chosen, or as |
Source code in src/visualdynamics/core/instrumentation.py
lowest_first
¶
The positions in modes ordered lowest frequency first: the
order in which effective_independence plans for them.
Source code in src/visualdynamics/core/instrumentation.py
shortfall
¶
shortfall(placement: Placement, modes: int) -> str
What a plan for fewer modes than the modes asked for leaves out,
in words; empty when it planned for them all.
Source code in src/visualdynamics/core/instrumentation.py
elastic
¶
The indices of a shape set's modes above 0 Hz: what a plan measures unless told otherwise.
assemble
¶
assemble(shapes: Any, modes: Any, places: Candidates, blocks: Any, placement: Placement) -> Plan
The three objects of a plan from what Effective Independence
chose: the step plan ends with, apart so that a preview can choose
again without finding the places again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shapes
|
ShapeSet
|
The finite element modes. |
required |
modes
|
sequence of int
|
The modes measured, by index, as |
required |
places
|
Candidates
|
Where sensors could go. |
required |
blocks
|
ndarray
|
|
required |
placement
|
Placement
|
What was chosen. |
required |
Returns:
| Type | Description |
|---|---|
Plan
|
|