5.4 Sensors
Sensors are used for test/analysis correlation and in analysis for models where one wants to post-process partial information. This general objective is supported by the use of SensDof entries. Supported sensor types are
| trans |
translation sensor. |
| triax |
simplified call to generate 3 translation sensors. |
| rel |
relative displacement sensor. |
| general |
general sensor (low level). |
| resultant |
resultant force sensor. |
| strain |
strain or stress sensor. |
5.4.1 Sensor data structure and init commands
SensDof case entries can contain the following fields
| sens.Node |
(optional) node matrix for sensor nodes that are not in the model. |
| sens.Elt |
element description matrix for a wire-frame display of the sensors (typically for test wire-frames). |
| sens.bas |
Coordinate system definitions for sens.Node, see fe_sens basis |
| sens.tdof |
nominally 5 column matrix with rows containing [SensID NodeID nx ny nz] giving a sensor identifier (integer or real), a node identifier (positive integer, if relevant), a direction. More details are given below. |
| sens.DOF |
DOF definition vector for the analysis (finite element model). |
| sens.cta |
is an observation matrix associated with the observation equation {y}=[c]{q} (where q is defined on sens.DOF ). This is built using the fe_case sens command illustrated below. |
| sens.Stack |
cell array with one row per sensor giving 'sens','SensorTag',data |
A .tdof in the form of a DOF definition vector can be transformed to the 5 column format using fe_sens('tdof',DOF).
SensId gives an identifier for each sensor. It should thus be unique and there may be conflicts if it is not.
NodeId specifies a node identifier for the spatial localization of the sensor. If not needed (resultant sensors for example), NodeId can be set for zero. A negative NodeId is used to look for the node position in sens.Node rather than model.Node. Most initalization calls accept the specification of a physical x y z position, a .vert0 field is then defined.
nx ny nz specifies a measurement direction for sensors that need one.
All sensors are generated with the command
fe_case(model,'SensDof <append, combine> Sensor_type',Sensor, data)
Sensor is the case entry name to which sensors will be added. data is a structure, a vector, or a matrix, which describes the sensor to be added. The nature of data depends on Sensor_type as detailed below.
In the default mode ('SensDof' command), new sensors replace any existing ones. In the append mode ('SensDof append'), if a sensor is added with an existing SensID, the SensID of new sensor will changed to a free SensID value. In the combine mode ('SensDof combine'), existing sensor with the same SensID will be replaced by the new one.
Relative displacement sensor or relative force sensor (spring load). Data passed to the command is [NodeID1 NodeID2].
This sensor measures the relative displacement between NodeID1 and NodeID2, along the direction defined from NodeID1 to NodeID2. One can use the command modifier -dof in order to measure along the defined DOF directions (needed of the two nodes are coincident). As many sensors as DOF are then added. For a relative force sensor, on can use the command modifier -coeff to define the associated spring stiffness (sensor value is the product of the relative displacement and the stiffness of the spring).
The following example defines 3 relative displacement sensors (one in the direction of the two nodes, and two others along x and y):
model=demosdt('demo ubeam-pro')
data=[30 372];
model=fe_case(model,'SensDof append rel','output',data);
model=fe_case(model,'SensDof append rel -dof 1 2','output',data);
General sensors are defined by a linear observation equation. This is a low level definition that should be used for sensors that can't be described otherwise. Data passed to the command is a structure with field .cta (observation matrix), .DOF DOF associated to the observation matrix, and possibly .lab giving a label for each row of the observation matrix.
The following example defines a general sensor
model=demosdt('demo ubeam-pro');
Sensor=struct('cta',[1 -1;0 1],'DOF',[8.03; 9.03]);
model=fe_case(model,'SensDof append general','output',Sensor);
Translation sensors can be specified by giving
-
[DOF]
- [DOF, BasID]
- [SensID, NodeID, nx, ny, nz]
- [SensID, x, y, z, nx, ny, nz]
When defining the sensor with only a DOF, or with [DOF, BasID] (BasID is the ID of the basis defined in the .bas field of the model), SensID should not be given. Translation is then the value of this DOF displacement. Otherwise, translation is measured at x y z or at the node NodeID, and along direction nx ny nz (this vector need not be normalized, sensor value is the scalar product of the direction vector and the displacement vector).
Sensor can also be a matrix if all rows are of the same type. Then, one can add a set of sensors with a single call to the fe_case(model,'SensDof <append> trans', Name, Sensor) command.
Following example defines a translation sensor with each possible way:
model=demosdt('demo ubeam-pro')
model=fe_case(model,'SensDof append trans','output',...
[1,0.0,0.5,2.5,0.0,0.0,1.0]);
model=fe_case(model,'SensDof append trans','output',...
[2,8,-1.0,0.0,0.0]);
model=fe_case(model,'SensDof append trans','output',...
[10.03]);
cf=feplot;cf.sel(2)='-output';cf.o(1)={'sel2 ty 7','linewidth',2};
Examples on the definition of test sensors are given in section 4.1.1.
Sens.Stack entries for translation can use the following fields
| .vert0 |
physical position in global coordinates. |
| .ID |
NodeId for physical position. Positive if a model node, negative if SensDof entry node. |
| .match |
cell array describing how the corresponding sensor is matched to the reference model. Columns are ElemF,elt,rstj,StickNode. |
3 translation sensors set can be specified by giving [NodeID].
In fact defining a triax sensor is the same as defining 3 translation sensors, in each of the 3 translation DOF (0.01, 0.02 and 0.03) of a node.
Sensor can also be a vector of NodeID. Then, one can add a set of sensors with a single call to the fe_case(model,'SensDof <append> triax', Name, Sensor) command.
For scanning laser vibrometer tests consider using the fe_sens laser command to define sens.tdof.
Strain sensors can be specified by giving
[SensID, NodeID]
[SensID, x, y, z]
[SensID, NodeID, n1x, n1y, n1z]
[SensID, x, y, z, n1x, n1y, n1z]
[SensID, NodeID, n1x, n1y, n1z, n2x, n2y, n2z]
[SensID, x, y, z, n1x, n1y, n1z, n2x, n2y, n2z]
when no direction is specified 6 sensors are added for stress/strains in the x, y, z, yz, zx, and xy directions (SensId is incremented by steps of 1). With n1x n1y n1z (this vector need not be normalized) on measures the axial strain in this direction. For shear, one specifies a second direction n2x n2y n2z (this vector need not be normalized) (if not given n2 is taken equal to n1). The sensor value is given by {n2}T[
]{n1}.
Sensor can also be a matrix if all rows are of the same type. Then, one can add a set of sensors with a single call to the fe_case(model,'SensDof <append> strain', Name, Sensor) command.
Following example defines a strain sensor with each possible way:
model=demosdt('demo ubeam-pro')
model=fe_case(model,'SensDof append strain','output',...
[4,0.0,0.5,2.5,0.0,0.0,1.0]);
model=fe_case(model,'SensDof append strain','output',...
[6,134,0.5,0.5,0.5]);
model=fe_case(model,'SensDof append strain','output',...
[5,0.0,0.4,1.25,1.0,0.0,0.0,0.0,0.0,1.0]);
model=fe_case(model,'SensDof append strain','output',...
[7,370,0.0,0.0,1.0,0.0,1.0,0.0]);
Stress sensor.
It is the same as the strain sensor. The sensor value is given by {n2}T[
]{n1}.
Following example defines a stress sensor with each possible way:
model=demosdt('demo ubeam-pro')
model=fe_case(model,'SensDof append stress','output',...
[4,0.0,0.5,2.5,0.0,0.0,1.0]);
model=fe_case(model,'SensDof append stress','output',...
[6,134,0.5,0.5,0.5]);
model=fe_case(model,'SensDof append stress','output',...
[5,0.0,0.4,1.25,1.0,0.0,0.0,0.0,0.0,1.0]);
model=fe_case(model,'SensDof append stress','output',...
[7,370,0.0,0.0,1.0,0.0,1.0,0.0]);
Since stress and strains are discontinuous across element boundaries, placing the sensor arbitrarily can generate some inaccuracy. A -stick can be added to the match command to force placement of the sensor and the center of the matching element. This will typically be a more appropriate location to evaluate stresses or strains.
Resultant sensors measure the resultant force on a given surface. They can be specified by giving a structure with fields
| .ID |
sensor ID. |
| .EltSel |
FindElt type string that gives the elements concerning by the resultant. |
| .SurfSel |
FindNode type string that gives the surface where the resultant is computed. |
| .dir |
direction of resultant measurement. This vector need not be normalized (scalar product). |
| .type |
contains the string 'resultant'. |
Following example defines a resultant sensor:
model=demosdt('demo ubeam-pro')
Sensor.ID=1;
Sensor.EltSel='WithNode{z==1.25} & WithNode{z>1.25}';
Sensor.SurfSel='z==1.25';
Sensor.dir=[0.0 0.0 1.0];
Sensor.type='resultant';
model=fe_case(model,'SensDof append resultant','output',Sensor);
Resultant sensors are not yet available for superelements model.
5.4.2 Topology correlation and observation matrix
Sens
The response at sensors is related to the response a DOFs by an observation equation
{
y(
t)}
NS× 1 = [
c]
NS× N {
q(
t)}
N× 1
(5.45)
The fe_case SensDof calls detailed above initalize the sensors but not the topology correlation (element matching) needed to build the observation matrix. This is done using any of the commands detailed below.
After the matching phase, one can build the observation matrix with
SensFull=fe_case(model,'sens',SensDofEntryName)
When using a reduced superelement model, you should use
SensRed=fe_case(model,'sensSE',SensDofEntryName).
The command model=fe_case(model,'sensmatch',Name) builds the observation matrix associated to each sensor of the entry Name, and stores it as a .cta field, and associated .DOF, in the sensor stack. You may omit to provide the name if there is only one sensor set.
This operation requires finding the elements that contain each sensor and the position within the reference element shape so that shape functions can be used to interpolate the response.
The match is performed in an area defined by a length which can be given as a command argument with identifier radius, for example
(fe_case(model,'sensmatch radius1.0',Name)
In certain applications the sensor may not be contained by the element (for example sensor slightly on the exterior of a volume element). You can then define an element selection to help in the matching. For example fe_case(model,'sensmatch radius1.0',Name,'selface') selects the external surface of volumes. The matching on surfaces allows for a normal projection towards the surface, sensors outside the model volume can thus be matched properly. Note that this selection does not yet let you selected implicit elements within a superelement.
Near,Rigid,Arigid
While obsolete compared to the Match strategy, fe_sens rigid,arigid,near implementations have NOT been ported to SDT 6.0 SensDof entry format. This thus documents SDT 5.3 match calls which are still available.
For topology correlation, the sensor configuration must be stored in the sens.tdof field and active FEM DOFs must be declared in sens.DOF. If you do not have your analysis modeshapes yet, you can use sens.DOF=feutil('getdof',sens.DOF). With these fields and a combined test/FEM model you can estimate test node motion from FEM results. Available interpolations are
At each point, you can see which interpolations you are using with
fe_sens('info',sens). Note that when defining test nodes in a local basis, the node selection commands are applied in the global coordinate system.
The interpolations are stored in the sens.cta field. With that information you can predict the response of the FEM model at test nodes. For example
[model,def]=demosdt('demo gartte cor');
model=fe_sens('rigid sensors',model); % link sensors to model
% display sensor wire-frame and animate FEM modes
cf=feplot; cf.model=model; cf.sel='-sensors';
cf.def=def;
fecom(';undefline;scd.5;ch7')
near defines the projection based on a nearest node match.
rigid defines the projection based on a nearest node match but assumes a rigid body link between the DOFs of the FE model and the test DOFs to obtain the DOF definition vector adof describing DOFs used for FEM results.
arigid is a variant of the rigid link that estimates rotations based on translations of other nodes. This interpolation is more accurate than rigid for solid elements (since they don't have rotational DOFs) and shells (since the value of drilling rotations is often poorly related to the physical rotation of a small segment).
Since the nearest nodes is not necessarily the linked to the elements on which the sensor is glued, you may want to ensure that the observation matrices created by these commands only use nodes associated to a subset of elements. You can use FEMNodeSelectors and TestNodeSelectors arguments to force matching in particular node subsets. This is illustrated below in forcing the interpolation of test node 1206 to use FEM nodes in the plane where it is glued.
cf=demosdt('demo gartte cor plot');
fe_sens('near sensors',cf); % initial estimate
%cf=fe_sens('arigid SensDofName',cf,...
% 'TestNodeSelectors','FemEltSelection');
cf=fe_sens('near sensors',cf,'nodeid 1206','withnode {z>.15}');
% modify link to 1206
fecom('showlinks sensors');fecom('textnode',1206)
fe_sens('info',sens)
The generation of loads is less general than that of sensors. As a result it may be convenient to use reciprocity to define a load by generating the collocated sensor. When a sensor is defined, and the topology correlation performed with SensMatch, one can define an actuator from this sensor using
model=fe_case(model,'DofLoad SensDof',Input_Name,'Sens_Name:Sens_Nb') or for model using superelements
model=fe_case(model,'DofLoad SensDofSE',Input_Name,'Sens_Name:Sens_Nb').
Sens_Name is the name of the sensor set entry in the model stack of the translation sensor that defines the actuator, and Sens_Nb is its number in this stack entry.
Input_Name is the name of the actuator entry that will be created in the model stack. It will be a DofLoad entry.
©1991-2007 by SDTools