Mode shapes describe the amplitude of motion at various locations in a structure. In conjunction with modal frequencies, damping, and scale factor (such as modal mass), mode shapes allow the structural dynamic response to be described by a modal model.
There is a special ADF type for mode shapes. It has the extension .ash. Similar to functions and time histories, the shape records contain more than just the raw shape data. Additional data attributes are stored with the shapes, including modal parameters. The data attributes describe the data type of the shape data (for unit conversion), the frequency, damping, and modal mass of the mode, as well as node numbers associated with the shape coefficients.
IMAT+FEA utilizes the imat_shp data type for nodal result data imported from NASTRAN and Abaqus files. In these cases not all of the attributes available in the imat_shp object are applicable, but using this data type offers consistency and convenience within MATLAB.
The IMAT toolbox includes a data class (imat_shp) for mode shapes and other nodal result types. Assuming you have already worked with functions in IMAT, you will find that shapes are treated in a similar way. An imat_shp variable contains both the shape data (i.e., the shape coefficients) and various numeric and string attributes.
An important feature of an imat_shp is that it includes shape coefficients for all degrees of freedom for each node. In case the shape coefficient was not calculated or is not defined (e.g., for a uniaxial or biaxial measurement), a zero value is filled in for that degree of freedom. The shape record retains no memory of which degrees of freedom were measured and which were filled in. Also, all coordinate signs are positive in a shape record (the sign correction is made when the shape is created.)
To see the true contents of a shape variable, you can use the set function:
>> set(imat_shp)
IDLine1: [ char string length 80 ]
IDLine2: [ char string length 80 ]
IDLine3: [ char string length 80 ]
IDLine4: [ char string length 80 ]
IDLine5: [ char string length 80 ]
AbscissaAxisLab: [ char string length 20 ]
AbscissaUnitsLab: [ char string length 20 ]
OrdinateAxisLab: [ char string length 20 ]
OrdinateUnitsLab: [ char string length 20 ]
CreateDate: [ char string length 20 ]
ModifyDate: [ char string length 20 ]
OwnerName: [ char string length 16 ]
Frequency: [ real value ]
Damping: [ real value ]
ModalMassReal: [ real value ]
ModalMassImag: [ real value ]
...
OrdDenTypeQual: [ Translation | Rotation ]
OrdDenExpLength: [ integer value ]
OrdDenExpForce: [ integer value ]
OrdDenExpTemp: [ integer value ]
OrdDenExpTime: [ integer value ]
>>
The specific meaning of each attribute can be found in the reference section. In general, you will have access to the shape coefficients, the node labels, and three types of attributes:
You will see later how to examine and modify the function values and data attributes.
Just as for functions, multiple shapes can be arrayed in a single imat_shp variable. Most often, you will work with a "column vector" of shapes (number of modes by 1), corresponding to multiple modes of the same structure (either analytically generated or extracted from test data). The various elements of a shape array need not be compatible, but most operations work most effectively when they are.
If you can think of a use for multidimensional arrays of shapes, IMAT will happily work with them.
To create an imat_shp from scratch, you use the imat_shp constructor:
>> s=imat_shp(3); % Creates 3x1 column vector of shapes
>> s=imat_shp(2,3); % Creates 2x3 matrix of shapes
The shapes created in this way will have the default attributes, which normally means they will have zero frequency and damping, and no shape coefficients defined. After you create a shape, you will want to set its attributes and data values. Click here to see how to do this.
It is common to have a matrix of shape coefficients associated with a list of coordinates. For example, you may use a set of frequency response functions measured at various response coordinates to determine mode shape coefficients at those coordinates. A convenient way to build a shape with those coefficients is the build_shape function. This function essentially does the same operation that I-deas does when it converts shape information at coordinates into a shape record.
There are three ways to get shape data from other software packges into MATLAB.
You can directly read the contents of a shape ADF (filename *.ash) using the readadf function. This function accepts an optional filename argument of the file to read. If the filename is omitted or contains wildcards, then the user will be prompted for the file to read. Here is an example:
>> s=readadf('testdata.ash')
ADF Name: /users/imatdemo/testdata.ash
Units : <7> IN
Begin processing...
5 records processed...
End processing...
s =
5x1 IMAT Shape with the following attributes:
Row Frequency Damping NumberNodes
--- ------------------- ------------------- -------------------
1 5.92815 0.0229441 10
2 9.56484 0.00663818 10
3 11.3931 0.0271432 10
4 83.2349 0.0362356 10
5 106.677 0.0130822 10
>>
It is important to note that by convention, shape coefficients in the ASH file are assumed to be in the local (displacement) coordinate system. When importing shapes from an ASH file not created by IMAT, the .CSType property will be set to 'Displacement'. IMAT does use an unsupported location in the ADF record header to store the .CSType property, so this property will round-trip in IMAT. However, other software that supports the ASH format will not recognize this property and may overwrite it.
The IMAT toolbox allows you to read a wide variety of universal files. Universal files are generally ASCII text files that can be read and written by a number of software packages.
It is important to note that by convention, shape coefficients in a universal file are assumed to be in the global (basic) coordinate system. The .CSType property will be set to 'Basic' on import from a universal file. Since there is no location in the universal file dataset 55 format to store this IMAT-specific property, it will not round-trip through a universal file.
To read a test or analytical shape universal file into MATLAB, use the readunv function in the IMAT toolbox. The calling sequence is the same as for readadf. You can provide a filename argument, or call readunv with a wildcard or no argument to interactively select the file to read.
When transferring universal files between platforms, be sure to use an ASCII (text) file transfer protocol so that carriage returns get converted properly.
The IMAT+FEA extended functionality allows you to read nodal field data from steps in an Abaqus ODB file using readodb. These functions will be imported as imat_shp. The Abaqus field attributes will be mapped as best as possible into the imat_shp attributes.
Similar to importing, you have two options for exporting shapes.
You can directly write one or more imat_shp variables into a shape ADF using the writeadf function. This function takes a filename argument and one or more imat_shp arguments. If the filename contains wildcards, then the user will be prompted for the file to write. Here is an example:
>> writeadf('testdata.ash',s)
ADF Name: /users/imatdemo/testdata.ash
Units : <7> IN
Begin processing...
s processed (5 records)...
End processing...
>>
If the specified ADF already exists, the new records will be appended after any existing records in the file.
It is important to note that by convention, shape coefficients in the ASH file are assumed to be in the local (displacement) coordinate system. IMAT does use an unsupported location in the ADF record header to store the .CSType property, so this property will round-trip in IMAT. However, other software that supports the ASH format will not recognize this property and may overwrite it.
You can create a shape universal file (dataset 55) using the writeunv function in the IMAT toolbox. The arguments to writeunv are the same as for writeadf. The first argument is a filename, which can be a wildcard. The remaining arguments are one or more imat_shp variables to be written to the universal file.
It is important to note that by convention, shape coefficients in a universal file are assumed to be in the global (basic) coordinate system. IMAT will not perform coordinate transformations on export, so if the shape coefficients in your imat_shp are not in the global coordinate system, you will need to transform them first with xform. Otherwise, you will need to remember that the shape coefficients in your universal file will be interpreted as being in the global coordinate system on import and must be relabeled manually.
If you copy the universal file between platforms, you should be sure to use an ASCII file transfer protocol so that carriage returns get converted properly.
IMAT offers two methods for you to examine or modify the contents of an imat_shp.
The simplest way to get information about a shape is with the syntax s.attrib, where s is the name of the variable, and attrib is the name of the attribute you want. The possible attribute names are listed in the reference section of this document, or you can get a listing with the set function. Here are some examples:
>> s.frequency
ans =
5.9281
9.5648
11.3931
83.2349
106.6768
>> s.referencecoord
ans =
'1X+'
'3Z-'
'1X+'
'3Z-'
'1X+'
>>
These examples illustrate that numeric attributes like Frequency are returned in a numeric array the same size as s. String-valued attributes like ReferenceCoord as well as list attributes are returned either as a character string (if s is a single shape) or in a cell array of strings if s is a vector or array of shapes. (For more information on cell arrays and cell arrays of strings, consult the MATLAB documentation.)
Data attributes return a single numeric or string value for each element of a shape array. The node and shape "attributes", on the other hand, each return an array of values for each element of the shape array. When you ask for the node attribute (node labels of the shape coefficients), you will get a multidimensional array whose first dimension corresponds to the number of nodes, and whose remaining dimensions match the size of the imat_shp array. For the example we've been following above, the statement
n=s.node
will set n to a 10x5 numeric array, since all of the elements of s have 10 nodes. The first column of n is the list of node labels for s(1), and so on. If s had been a 5x3 array of shapes, then n would have been a 10x5x3 multidimensional numeric array.
The same thing happens when you access the shape attribute (the actual shape coefficients): an extra dimension is added as the first dimension of the result. The row dimension of the shape coefficient matrix is equal to the number of nodes times the number of degrees of freedom per node (either 3 or 6). The DOFType attribute determines whether the shape has 3 or 6 degrees of freedom per node. If a shape is 3DOF, then the first three rows of the shape are the X, Y, and Z coefficients for the first node, followed by 3 values for the second node, and so on. For 6DOF shapes, there are six values per node.
If not all of the shapes have the same number of nodes or degrees of freedom, IMAT sets the first dimension of the result (node or shape) to the largest of any of the shapes in the array. For those shapes with less data than the maximum, the extra elements are filled with NaN (i.e., "not a number") values.
An alternative way to access shape information is with get. In general, the expression get(s,'attrib') is equivalent to the expression s.attrib as discussed above. However, the get function also allows you to extract multiple attributes in one call. Here's an example:
>> r=get(s,'frequency','damping','referencecoord')
r =
Frequency: [5x1 double]
ReferenceCoord: {5x1 cell}
Damping: [5x1 double]
>>
When you ask for multiple attributes, get returns a structure with field names equal to the attributes you selected. The value in each field is the value of the corresponding attribute, as discussed above. If you do not specify any attributes at all, then get will return all of the data attributes. After a call to get, you can refer to the individual returned values by name, provided you use the proper combination of upper and lower case to refer to the fields:
>> r.ReferenceCoord
ans =
'1X+'
'3Z-'
'1X+'
'3Z-'
'1X+'
>>
To change an attribute of a shape, you use the syntax s.attrib=value. Numeric attributes should be set to a numeric array with dimension matching s. String-valued attributes and list attributes should be set to a cell array of strings, and the cell array should be the same dimension as s. The node and shape attributes should have an extra first dimension as discussed above.
A special case is made for times when you want to set all shapes in an imat_shp array to have the same attribute. In this case, you can set the value to be a scalar numeric value or a simple character string. The same value will then be applied to all of the shapes in the array. If you set the node or shape attribute to a single column vector, then the same vector is used for all elements of s.
Here are some examples of attribute manipulations:
>> t=imat_ctrace('1x','2x','3x-') % Measurement coordinates
t =
'1X+'
'2X+'
'3X-'
>> x=[1.15 -3.21 ; -0.75 -1.18 ; -2.03 5.03 ]; % Shape coefficients for 2 modes
>> s=build_shape(t,x) % Build an imat_shp w/ 2 modes
s =
2x1 IMAT Shape with the following attributes:
Row Frequency Damping NumberNodes
--- ------------------- ------------------- -------------------
1 1 0 3
2 1 0 3
>> s.node % Here are the node values
ans =
1 1
2 2
3 3
>> s.shape % Here are the shape values
ans =
1.1500 -3.2100
0 0
0 0
-0.7500 -1.1800
0 0
0 0
-2.0300 5.0300
0 0
0 0
>> s.frequency=[6.83 ; 12.05]; s.modalmassreal=1; s.damping=[0.014 0.008] % Now set other attributes
s =
2x1 IMAT Shape with the following attributes:
2x1 IMAT Shape with the following attributes:
Row Frequency Damping NumberNodes
--- ------------------- ------------------- -------------------
1 6.83 0.014 3
2 12.05 0.008 3
The set function is an alternative way to change attributes or function data. The syntax is s2=set(s,'attrib',value,...). You can set one or many attributes. The result s2 is a duplicate of s, with the exception of the attributes you specify. set also accepts a structure, like the one that get returns.
There are times when it is necessary to extract mode shape coefficients at a subset of the nodes in a model. For example, you may have computed mode shapes for a full model, but you only need to display the mode shapes in a subset of the full model, often referred to as a "display model". To accomplish this partitioning operation, you create a numeric vector n which contains the nodes you want to keep. The statement
s_part=s{n}
creates an imat_shp variable s_part which contains mode shape information only for the nodes listed in n. For examples, if s contains shape coefficients for nodes 101, 103, 105, and 107, then
s{ [101 105] }
is an imat_shp variable with shape coefficients only for nodes 101 and 105. The partitioning operation applies to all modes contained in s.
The partition method also partitions mode shapes.
IMAT provides a very useful syntax for accessing shape coefficients based on coordinates. If s is an imat_shp object and t is an imat_ctrace object, then the expression
s{t}
creates a matrix of shape coefficients, with as many rows as there are coordinates in t, and as many columns as there are modes in s. Alternatively, a list of coordinates can be entered in the braces. For example, if s contained 5 modes, the expression
s{'105x','101y-','102z'}
creates a 3x5 numeric array. The first row contains the five shape coefficients for coordinate 105X, the second row contains the (negative) shape coefficients for coordinate 101Y, and the third row contains the shape coefficients for coordinate 102Z. Note that an error results if any of the specified coordinates is not present in any of the modes in s.
You may also modify shape coefficients using this syntax. The command
s{t}=x
sets the shape coefficients specified by the coordinate trace t to the values in the numeric matrix x. The matrix x should have as many rows as there are coordinates in t, and as many columns as there are shapes in s. Note that this syntax can only be used to modify existing coordinates in a mode shape. If the specified coordinates do not already exist in the shape variable, then an error will result.
The build_shape function provides a convenient way to create an imat_shp object from a matrix of shape coefficients at given coordinates.
Another powerful selection method makes use of "filters". A filter (in this context) refers to a set of selection criteria referencing the shape data attributes. For a more complete discussion of filters, click here.
To use a filter to select shapes, you use the syntax s{filter}. The filter in braces can either be an imat_filt variable (which allows for fairly complicated filter criteria), or can be a simple filter expression using 3 inputs. Here are some examples of both types of expressions:
>> t = s{'shapetype', '=', 'real'};
>> z1 = imat_filt(imat_shp,'shapetye', '=', 'complex');
>> z2 = imat_filt(imat_shp,'doftype', '=', '3dof');
>> t = s{z1&z2};
The first example selects all shapes that have real normal shape coefficients. The second example selects shapes with complex shape coefficients that are 3 DOF per node.
You can perform any MATLAB operation on an imat_shp simply by extracting its shape coefficients into a numeric array, performing the desired operation, and creating a new imat_shp with the resulting coefficients. However, some operations can be performed directly on imat_shp objects, using methods built into IMAT. Here is a summary of the available operations:
Unary Operations | |
+s | Unary plus (leaves s unchanged) |
-s | Unary minus (negate the shape coefficients of s) |
real(s) | Take real part of the shape coefficients of s |
imag(s) | Take imaginary part of the shape coefficients of s |
conj(s) | Take complex conjugate of the shape coefficients of s |
abs(s) | Take absolute value of the shape coefficients of s (or modulus if s is complex) |
phase(s) | Return phase angle of complex shape coefficients in radians |
phased(s) | Return phase angle of complex shape coefficients in degrees |
Binary Operations | |
s+scalar, s-scalar | Add, subtract scalar value to all shape coefficients |
s.*scalar, s./scalar, s.\scalar |
Multiply or divide shape coefficients by scalar value |
s+t, s-t | Add or subtract two shapes. Operation is performed on shape coefficients only if node numbers match between s and t. |
s.*t, s./t, s.\t | Termwise multiply or divide two shapes. Operation is performed termwise only if nodes of s and t match. |
A*s, A\s, s/A | Multiply (or divide) matrix A times shape s. The matrix operation is performed at all shape coefficients. The number of rows in the shape s should equal the number of columns of A, and all functions in s should have the same number of nodes and DOF. |
The matrix multiply operations are the most confusing, because of the extra dimension on the shape coefficients. Matrix multiplication operates on the vector of shapes, and is repeated at each shape coefficient. Suppose s is a 2x1 imat_shp, and A is 3x2. Then the statement t=A*s creates a 3x1 imat_shp whose attributes match s(1), and whose shape coefficients are
s(1).shape = A(1,1)*s(1).shape + A(1,2)*s(2).shape
s(2).shape = A(2,1)*s(1).shape + A(2,2)*s(2).shape
s(3).shape = A(3,1)*s(1).shape + A(3,2)*s(2).shape
The multiplication by A is done for each shape coefficient. This type of operation is very useful for cases where one set of shapes can be constructed as a linear combination of another set of shapes. Note that you may need to set the ordinate data type and other data attributes on the result of such an operation.