function [UffDataSets, Info, errmsg] = readuff(varargin)
%READUFF Reads UFF (Universal File Format) files of types:
% 151, 15, 55, 58, 82, 164, 2411, 2412 and also the hybrid one, 58b
%
% Works in Matlab/Octave.
%
% Usage:
% [UffDataSets, Info, errmsg] = readuff(fileName, 'InfoOnly') Extract only the
% basic information from the file. UffDataSets will be returned
% empty in this case.
%
% [UffDataSets, Info, errmsg] = readuff(fileName) Extract the basic
% information from the file as well as the whole file
% contents - see the description for the UffDataSets
% below.
%
% [UffDataSets, Info, errmsg] = readuff(fileName, recs) Extract only the
% records and their information requested by the recs
% array - the array of indices, e.g., recs=[1 3 10]. If
% empty, all the records are considered.
%
% [UffDataSets, Info, errmsg] = readuff(..., recs, dsTypes) Extract only the
% records that meet the criterria of the dsTypes where
% dsTypes is an array of data-set types that are to be
% read - actually, this is another filter in addition to
% the recs one; e.g. dsTypes = [58 55]
% [UffDataSets, Info, errmsg] = readuff(..., ..., ..., 0) Does not show
% any warning messages.
%
% The ouput values are:
% - UffDataSets: an array of structures; each structure holds one data set
% (the data set between -1 and -1; Each structure,
% UffDataSets{i}, has the fields
% .dsType
% .binary
% and some additional field which are data-set dependant
% and are
% as follows:
% #58 - for measurement data - function at dof (58):
% .d1 (description 1) .d2 (description 2) .date
% .ID_4 .ID_5 .functionType (see notes)
% .loadCaseId .measData .refEntName
% .refDir .refNode .rspDir
% .rspEntName .rspNode .x (time or frequency)
% .dx (abscissa spacing) .abscUnitsLabel
% .ordinateNumUnitsLabel .ordinateDenumUnitsLabel
% .zUnitsLabel .zAxisValue
% .abscLengthUnitsExponent.abscForceUnitsExponent
% .abscTempUnitsExponent
% .abscAxisLabel .ordinateLengthUnitsExponent
% .ordinateForceUnitsExponent .ordinateTempUnitsExponent
% .ordinateAxisLabel
%
% #58b - for measurement data - the same as 58 but the data
% is written in binary format
%
% #15 - coordinate data (15) (Grid points):
% .nodeN .defCS .dispCS
% .color .x .y
% .z
%
% #2411 - coordinate data (2411) (Grid points):
% .nodeN .defCS .dispCS
% .color .x .y
% .z
%
% #2412 - element data (2412):
% .ElementLabel .FEDescriptor .PhysicalProp
% .MaterialProp .ElementColour .NumNodes
% .Elements
%
% #82 - display Sequence data (82):
% .traceNum .nNodes .color
% .ID .lines
%
% #151 - header data (151):
% .modelName .description .dbApp
% .dateCreated .timeCreated .dbVersion
% .dbLastSaveDate .dbLastSaveTime .uffApp
%
% #164 - units (164):
% .unitsCode .unitsDescription .tempMode (1=absoulute, 2=relative)
% Unit factors for converting universal file units to SI. To convert from
% universal file units to SI divide by the appropriate factor listed below:
% .facLength .facForce .facTemp
% .facTempOffset
%
% #55 - data at nodes (55):
% /Common fields:/
% .analysisType .dataCharacter = 1 .r1
% .r2 .r3 .responseType
% .r4 .r5 .r6
% /Normal modes specific fields (analysisType = 2)/
% .modeNum .modeFreq .modeMass
% .mode_v_damping_ratio .mode_h_damping_ratio
% /...or, for complex modes specific fields (analysisType = 3 or 7)/
% .modeNum .eigVal .modalA
% .modalB
% /...or, for frequency response specific fields (analysisType = 5)/
% .freqNum .freq
%
% - Info: (optional) structure with the following fields:
% .dsTypes - an array of data-set types read
% .binary - an array of 1s (binary format) and 0s (ascii format)
% .nDataSets - number of data sets found
% .errcode - an array of error codes for each data
% set; 0 = no error otherwise an error occured in data
% set read - see errmsg
% .errmsg - error messages (cell array of strings) for each
% data set - empty if no error occured at specific data set
% .nErrors - number of errors found (unsupported
% datasets, error reading data set,...)
% .errorMsgs - all the error messages (empty if no error is found)
% - errmsg: (optional) general (overall), file-based error
% messages - to enable reading of uncorrupted data for
% example,...
%
%
% NOTES: r1..r6 are response vectors with node numbers in ROWS and
% direction in COLUMN (r1=x, r2=y,...,r6=rz).
%
% functionType can be one of the following:
% 0 - General or Unknown
% 1 - Time Response
% 2 - Auto Spectrum
% 3 - Cross Spectrum
% 4 - Frequency Response Function
% 5 - Transmissibility
% 6 - Coherence
% 7 - Auto Correlation
% 8 - Cross Correlation
% 9 - Power Spectral Density (PSD)
% 10 - Energy Spectral Density (ESD)
% 11 - Probability Density Function
% 12 - Spectrum
% 13 - Cumulative Frequency Distribution
% 14 - Peaks Valley
% 15 - Stress/Cycles
% 16 - Strain/Cycles
% 17 - Orbit
% 18 - Mode Indicator Function
% 19 - Force Pattern
% 20 - Partial Power
% 21 - Partial Coherence
% 22 - Eigenvalue
% 23 - Eigenvector
% 24 - Shock Response Spectrum
% 25 - Finite Impulse Response Filter
% 26 - Multiple Coherence
% 27 - Order Function
%
% analysisType can be one of the following:
% 0: Unknown
% 1: Static
% 2: (supported) Normal Mode
% 3: (supported) Complex eigenvalue first order
% 4: Transient
% 5: (supported) Frequency Response
% 6: Buckling
% 7: (supported) Complex eigenvalue second order
%
% dataCharacter can be one of the following:
% 0: Unknown
% 1: Scalar
% 2: 3 DOF Global Translation Vector
% 3: 6 DOF Global Translation & Rotation Vector
% 4: Symmetric Global Tensor
%
% unitsCode can be one of the following:
% 1 - SI: Meter (newton)
% 2 - BG: Foot (pound f)
% 3 - MG: Meter (kilogram f)
% 4 - BA: Foot (poundal)
% 5 - MM: mm (milli newton)
% 6 - CM: cm (centi newton)
% 7 - IN: Inch (pound f)
% 8 - GM: mm (kilogram f)
%
% functionType as well as other parameters are described in
% Test_Universal_File_Formats.pdf
%
% Examples:
% [Data, Info, errmsg] = readuff('test.unv', 'InfoOnly');
% Extracts only the information on the content of the test.unv.
% [Data, Info, errmsg] = readuff('test.unv', [1 3 10]);
% Reads the 1st, 3rd and 10th data-set from the test.unv, while
% [Data, Info, errmsg] = readuff('test.unv', [1 3 10], [55, 58]);
% Reads the 1st, 3rd and 10th data-set from the test.unv, but,
% only those sets whose type is either 55 or 58.
% [Data, Info, errmsg] = readuff('test.unv');
% Reads the whole file content - all the data-sets.
%
% See also: WRITEUFF
%
% SOURCES: [1] Bryce Gardner's read_uff obtained from the internet
% [2] http://www.sdrl.uc.edu/uff/SDRChelp/LANG/English/unv_ug/book.htm
%
%
% First release on 30.05.2004
% (c) Primoz Cermelj, Slovenia
% Contact: primoz.cermelj@gmail.com
% Download location: http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6395&objectType=file
%
% Version: 1.1.1
% Last revision: 27.05.2013
%
% Contributors
% - Ben Cazzolato: added 2411 and 2412 datasets.
%
% Bug reports, questions, etc. can be sent to the e-mail given above.
%--------------------------------------------------------------------------
%----------------
% READUFF history
%----------------
%
% [1.1.1] 27.05.2013
% - FIX: fixed data reading in extract58: extra zero values not read anymore
% [1.1.0] 27.02.2013
% - FIX: data-set 151 fields unified (readuff and writeuff)
% [1.0.9] 18.02.2013
% - FIX: readuff(fileName, recs) reading mode works now
% [1.0.6-1.0.8] 30.08.2010
% - FIX: in thecase of inconsistency in 58b data sets (extra bytes of data
% present), extra bytes at the end willbe skipped.
% - FIX: regular expressions are now used to detect data-set blocks - more
% robust
% - FIX: more robust start/end block detection
% - FIX: minor changes
% [v.1.0.1-1.0.5] 12.03.2008-08.11.2008
% - NEW: some restrictions relaxed when reading the data-set 58
% - NEW: some additional checking for badly formatted data-set id line
% - NEW: some additional warning/error messages displayed for the 58b set
% - FIX: uint8=>char instead of char=>char in fread fixes a problem on
% some Linux systems
% - FIX: minor bug removed (related to the extracted abscissa values for
% the 58, complex case of data)
% [v.1.0.0] 10.03.2008
% - NEW: datasets 2411 and 2412 added
% [v.0.9.9b1-5] 08.01.2008
% - NEW: additional checking when reading 58b data
% - NEW: additional filter added - dsTypes
% - FIX: minor bug removed concerning the finding of the " -1" tags
% - FIX: previously, when reading data-set 58b, some data-sets were
% skipped; this bug is now removed
% - NEW: new functionality to read only a portion of file and to extract
% the information only
% [v.0.9.7-v.0.9.8b7] 28.02.2006
% - FIX: a bug reading even abscissa data from the 58 set removed
% - NEW: uneven abscissa data-reading is now supported
% - FIX: removing leading and trailing spaces from the strings read
% - NEW: hybrid binary-58 format (58b) is now supported
% - NEW: binary field was added to UffDataSets structures
% [v.0.9.7] 24.05.2005
% - NEW: dsType field was added to UffDataSets structures
% [v.0.9.6b4] 11.05.2005
% - FIX: Matlab version down to 5.3 is now supported
% - FIX: Some minor bugs removed
% - NEW: Speed improvement; reading is much faster now
%
%----------------
global show_warning
error(nargchk(1, 4, nargin));
%--------------
% Default outputs
%--------------
show_warning = 1;
UffDataSets = [];
Info.errcode = [];
Info.nDataSets = 0;
Info.dsTypes = [];
Info.binary = [];
Info.errmsg = [];
Info.nErrors = 0;
errmsg = [];
%--------------
% Handle input parameters
%--------------
recs = [];
dsTypes = [];
fileName = varargin{1};
readMode = 1; % 0=info only, 1=read all, 2=read filtered data-sets
if nargin > 1
if isnumeric(varargin{2}) || isempty(varargin{2})
recs = varargin{2};
readMode = 2;
elseif strcmpi(varargin{2}, 'infoonly')
readMode = 0;
else
error('Unknown request in the second parameter');
end
end
if nargin > 2
if isnumeric(varargin{3}) || isempty(varargin{3})
dsTypes = varargin{3};
readMode = 2;
else
error('Unknown request in the third parameter');
end
end
if nargin > 3
if isnumeric(varargin{4}) && varargin{4} == 0
show_warning = 0;
end
end
%--------------
% Some variables
%--------------
errN = 0; % current global error number (data-set number independent)
%--------------
% Read the whole file data into an array of characters
%--------------
try
fid = fopen(fileName, 'r');
if fid == -1,
errN = errN + 1;
errmsg{errN,1} = ['could not open file: ' fileName];
disp(errmsg{errN});
return
end
FILE_DATA = (fread(fid, 'uint8=>char')).';
catch
errN = errN + 1;
errmsg{errN,1} = ['error reading file contents: ' lasterr];
disp(errmsg{errN});
% Close the file
fclose(fid);
return
end
% Close the file
err = fclose(fid);
if err == -1
errN = errN + 1;
errmsg{errN,1} = 'error while closing file';
disp(errmsg{errN});
end
%--------------
% Find all valid blocks, data between -1 and -1; pointers to blocks of
% data; include the first -1 but exclude the last -1;
% the first -1 will be skipped further later on in get_block_prop
%--------------
% ind = strfind(FILE_DATA, ' -1');
ind = regexpi(FILE_DATA, '(?<=^|[\r\n])( -1 *)(?:$|[\r\n])');
data_len = length(FILE_DATA);
for ii=length(ind):-1:1
if ind(ii) == data_len
continue
end
if ~isspace(FILE_DATA(ind(ii)+6))
ind(ii) = [];
end
end
nBlocks = floor(length(ind)/2);
if nBlocks < 1
errN = errN + 1;
errmsg{errN,1} = 'No valid blocks found';
disp(errmsg{errN});
return
elseif rem(length(ind), 2)
errN = errN + 1;
errmsg{errN,1} = 'Uneven (odd) -1 tags found (one -1 tag too many). Check your file.';
disp(errmsg{errN});
return
end
blocks = zeros(nBlocks, 2);
blocks(:,1) = ind(1:2:2*nBlocks)';
blocks(:,2) = ind(2:2:2*nBlocks)'-1;
%=============================
% MAIN FILE LOOP - go through all the blocks and extract data from each
% block according to the data type
%=============================
dataSetN = 0; % counts VALID data-sets (including non-supported ones)
if isempty(recs)
recs = 1:nBlocks;
end
try
if readMode==2
readScope = recs;
if max(recs) > nBlocks
error('Max block number to be read is too high (%d)', max(recs));
end
else
readScope = 1:nBlocks;
end
for ii=readScope
% Skips the first -1, detects the data-set type and any possible
% properties (e.g., for 58b there are some additional fields in the data-set
% id record), and also returns blockLines - pointers to start and
% end offsets of lines of the data-set-block data
[data_set_type, DataSetProp, blockLines, errMessage] = ...
get_block_prop(ii, blocks(ii,1), blocks(ii,2), FILE_DATA);
if ~isempty(errMessage)
errN = errN + 1;
errmsg{errN,1} = errMessage;
continue
end
if readMode~=0
% First check if dataSetN meets the filter
if ~isempty(dsTypes)
if isempty(find(dsTypes==data_set_type))
continue
end
end
dataSetN = dataSetN + 1;
ds_errmsg = [];
% Now, read the record
if data_set_type == 58 % Function at nodal dof
[ds_data,ds_errmsg] = extract58(fileName, FILE_DATA, blockLines, DataSetProp, ii);
elseif data_set_type == 15 % Coordinate data
[ds_data,ds_errmsg] = extract15(FILE_DATA, blockLines);
elseif data_set_type == 2411 % Node Coordinate data
[ds_data,ds_errmsg] = extract2411(FILE_DATA, blockLines);
elseif data_set_type == 2412 % Element data
[ds_data,ds_errmsg] = extract2412(FILE_DATA, blockLines);
elseif data_set_type == 151 % Header data
[ds_data,ds_errmsg] = extract151(FILE_DATA, blockLines);
elseif data_set_type == 164 % Units data
[ds_data,ds_errmsg] = extract164(FILE_DATA, blockLines);
elseif data_set_type == 82 % Display sequence data
[ds_data,ds_errmsg] = extract82(FILE_DATA, blockLines);
elseif data_set_type == 55 % Modal data file
[ds_data,ds_errmsg] = extract55(FILE_DATA, blockLines);
else
ds_data = [];
ds_errmsg = ['unknown data-set (' num2str(data_set_type) ') found in ' num2str(ii) '-th data-set '];
end
UffDataSets{dataSetN} = ds_data;
UffDataSets{dataSetN}.dsType = data_set_type;
UffDataSets{dataSetN}.binary = DataSetProp.binary;
end
Info.errmsg{dataSetN} = ds_errmsg;
Info.dsTypes(dataSetN) = data_set_type;
Info.binary(dataSetN) = DataSetProp.binary;
if isempty(ds_errmsg)
Info.errcode(dataSetN) = 0;
else
Info.errcode(dataSetN) = 1;
end
end
catch
errN = errN + 1;
errmsg{errN,1} = lasterr;
end
%=============================
% END OF MAIN FILE LOOP
%=============================
Info.nErrors = length(find(Info.errcode));
Info.nDataSets = dataSetN;
Info.errorMsgs = Info.errmsg(find(Info.errcode));
if ~isempty(errmsg)
for ii=1:length(errmsg)
disp(errmsg{ii});
end
end
%==========================================================================
% SUBFUNCTIONS SECTION
%==========================================================================
%--------------------------------------------------------------------------
function [dataSet, DataSetProp, blockLines, errMessage] = get_block_prop(ds_num, so, eo, FILE_DATA)
% Extract block-data lines' pointers (start and end for each line) and also
% returns the data-set number identified along with any additional
% parameters such as in the case of 58b data-set. so points to the first -1 tag
% (designated by o): o___-1 while eo points to the end -1 tag: o___-1.
% blockLInes are start and end offsets of each line in the current data-set
% starting from the line right after the data-set id line.
% Empty lines are skipped.
% Scans for block data and returns lines' pointers (start and end offsets
% in a 2-column matrix).
dataSet = [];
DataSetProp = [];
blockLines = [];
errMessage = [];
try
% For a two-column matrix of start and end indices designating the
% start and end for each line of the data set
blockData = FILE_DATA(so:eo);
dataLen = length(blockData);
lineBreaks = blockData==sprintf('\n') | blockData==sprintf('\r');
lineBreaksInd = find(lineBreaks);
toInd = zeros(length(lineBreaksInd)+1, 1);
fromInd = zeros(length(lineBreaksInd)+1, 1);
toInd(1:length(lineBreaksInd)) = lineBreaksInd-1;
if lineBreaksInd(end) < dataLen
toInd(length(lineBreaksInd)+1) = dataLen;
end
toInd = toInd(toInd>0);
indToRemove = find(lineBreaks(toInd)==1);
toInd(indToRemove) = [];
if lineBreaksInd(1) > 1
fromInd(1) = 1;
fromInd(2:length(lineBreaksInd)+1) = lineBreaksInd+1;
else
fromInd(1:length(lineBreaksInd)) = lineBreaksInd+1;
end
if lineBreaksInd(end) == dataLen
fromInd(length(lineBreaksInd)+1) = 0;
end
fromInd = fromInd(fromInd>0 & fromInd<=dataLen);
indToRemove = find(lineBreaks(fromInd)==1);
fromInd(indToRemove) = [];
blockLines = [fromInd toInd];
% The data-set line; get the data-set number
dataSetLine = blockData(blockLines(2,1):blockLines(2,2));
if isempty(dataSetLine) || length(dataSetLine) < 6
warning('Badly formatted data-set id for data-set # %d', ds_num);
dataSet = sscanf(dataSetLine, '%i', 1);
else
dataSet = sscanf(dataSetLine(1:6), '%i', 1);
end
if isempty(dataSet)
errMessage = 'no valid data-set type found';
return
end
% Get the format
if length(dataSetLine) < 7
format = '';
else
format = sscanf(dataSetLine(7), '%c', 1);
end
if strcmpi(format, 'b')
DataSetProp.binary = 1;
DataSetProp.byteOrdering = sscanf(dataSetLine(8:13),'%i',1);
DataSetProp.fpFormat = sscanf(dataSetLine(14:19),'%i',1);
DataSetProp.nAsciiLines = sscanf(dataSetLine(20:31),'%i',1);
DataSetProp.nBytes = sscanf(dataSetLine(32:43),'%i',1);
DataSetProp.d1 = sscanf(dataSetLine(44:49),'%i',1);
DataSetProp.d2 = sscanf(dataSetLine(50:55),'%i',1);
DataSetProp.d3 = sscanf(dataSetLine(56:67),'%i',1);
DataSetProp.d4 = sscanf(dataSetLine(68:end),'%i',1);
else
DataSetProp.binary = 0;
end
% Global blockLines (with respect to FILE_DATA)
blockLines = blockLines(3:end,:) + so - 1;
if size(blockLines,1) < 2
errMessage = 'empty data block found';
return
end
catch
errMessage = ['error while reading the header info at data set #: ' num2str(ds_num) ' (' lasterr ')'];
return
end
%--------------------------------------------------------------------------
function [UFF, errMessage] = extract58(fileName, DATA, blockLines, DataSetProp, setn)
% #58 - Extract data-set type 58 data
global show_warning
UFF = [];
UFF.measData = [];
errMessage = [];
lineN = 1;
nLines = size(blockLines, 1);
try
% Line 1
UFF.d1 = strim(sscanf(DATA(blockLines(1,1):blockLines(1,2)), '%c', 80));
lineN = lineN + 1;
% Line 2
UFF.d2 = strim(sscanf(DATA(blockLines(2,1):blockLines(2,2)), '%c', 80));
lineN = lineN + 1;
% Line 3
UFF.date = strim(sscanf(DATA(blockLines(3,1):blockLines(3,2)), '%c', 80));
lineN = lineN + 1;
% Line 4
UFF.ID_4 = strim(sscanf(DATA(blockLines(4,1):blockLines(4,2)), '%c', 80));
lineN = lineN + 1;
% Line 5
UFF.ID_5 = strim(sscanf(DATA(blockLines(5,1):blockLines(5,2)), '%c', 80));
lineN = lineN + 1;
% Line 6
tmpLine = DATA(blockLines(6,1):blockLines(6,2));
tmpLine = [tmpLine repmat(' ', 1, 80-length(tmpLine))];
UFF.functionType = sscanf(tmpLine(1:5), '%i', 1);
tmp = sscanf(tmpLine(6:15),'%i', 1);
tmp = sscanf(tmpLine(16:20),'%i', 1);
UFF.loadCaseId = sscanf(tmpLine(21:30), '%i', 1);
UFF.rspEntName = sscanf(tmpLine(32:41), '%c');
UFF.rspNode = sscanf(tmpLine(42:51), '%i', 1);
UFF.rspDir = sscanf(tmpLine(52:55), '%i', 1);
UFF.refEntName = sscanf(tmpLine(57:66), '%c');
UFF.refNode = sscanf(tmpLine(67:76),'%i', 1);
UFF.refDir = sscanf(tmpLine(77:80),'%i', 1);
lineN = lineN + 1;
% Line 7; data form
tmpLine = DATA(blockLines(7,1):blockLines(7,2));
tmpLine = [tmpLine repmat(' ', 1, 80-length(tmpLine))];
ordDataType = sscanf(tmpLine(1:10), '%i', 1);
numpt = sscanf(tmpLine(11:20),'%i', 1); % # of points if even spacing or # of pairs if uneven spacing
spacingType = sscanf(tmpLine(21:30), '%i', 1);
UFF.xmin = sscanf(tmpLine(31:43), '%g', 1);
UFF.dx = sscanf(tmpLine(44:56), '%g', 1);
UFF.zAxisValue = sscanf(tmpLine(57:69), '%g', 1);
lineN = lineN + 1;
% Line 8; abscissa data characteristics
tmpLine = DATA(blockLines(8,1):blockLines(8,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.abscDataChar = sscanf(tmpLine(1:10),'%i',1);
UFF.abscLengthUnitsExponent = sscanf(tmpLine(11:15),'%i',1);
UFF.abscForceUnitsExponent = sscanf(tmpLine(16:20),'%i',1);
UFF.abscTempUnitsExponent = sscanf(tmpLine(21:25),'%i',1);
UFF.abscAxisLabel = sscanf(tmpLine(27:46),'%c');
UFF.abscUnitsLabel = sscanf(tmpLine(48:end),'%c');
lineN = lineN + 1;
% Line 9; Ordinate (or ordinate numerator) Data Characteristics
tmpLine = DATA(blockLines(9,1):blockLines(9,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.ordDataChar = sscanf(tmpLine(1:10),'%i',1);
UFF.ordinateLengthUnitsExponent = sscanf(tmpLine(11:15),'%i',1);
UFF.ordinateForceUnitsExponent = sscanf(tmpLine(16:20),'%i',1);
UFF.ordinateTempUnitsExponent = sscanf(tmpLine(21:25),'%i',1);
UFF.ordinateAxisLabel = sscanf(tmpLine(27:46),'%c');
UFF.ordinateNumUnitsLabel = sscanf(tmpLine(48:end),'%c');
lineN = lineN + 1;
% Line 10; Ordinate Denominator Data Characteristics
tmpLine = DATA(blockLines(10,1):blockLines(10,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
ordDenominatorDataType = sscanf(tmpLine(1:10),'%i',1);
tmp = sscanf(tmpLine(11:15),'%i',1);
tmp = sscanf(tmpLine(16:20),'%i',1);
tmp = sscanf(tmpLine(21:25),'%i',1);
temp = sscanf(tmpLine(27:46),'%c');
UFF.ordinateDenumUnitsLabel = sscanf(tmpLine(48:end),'%c');
lineN = lineN + 1;
% Line 11; Z-axis Data Characteristics
tmpLine = DATA(blockLines(11,1):blockLines(11,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
tmp = sscanf(tmpLine(1:10),'%i',1);
tmp = sscanf(tmpLine(11:15),'%i',1);
tmp = sscanf(tmpLine(16:20),'%i',1);
tmp = sscanf(tmpLine(21:25),'%i',1);
temp = sscanf(tmpLine(27:46),'%c');
UFF.zUnitsLabel = sscanf(tmpLine(48:end),'%c');
lineN = lineN + 1;
% Line 12 ...; Data Values
if DataSetProp.binary
%-------
% BINARY
%-------
if DataSetProp.byteOrdering == 1; format = 'l'; else format = 'b'; end;
if (ordDataType==2 || ordDataType==5)
prec = 'float32'; % single precision
numLen = 4;
else
prec = 'double'; % double precision
numLen = 8;
end
fid = fopen(fileName,'r',format);
if fid == -1
errMessage = ['could not reopen file for binary data reading: ' fileName];
return
end
% It was observed that some programs write some inconsistent values
% to the header concerning the number of data and/or bytes the data
% is to occupy. In case such incosistency is found, the max number
% will be used and a warning displayed.
% According to the UFF documentation, in the case of uneven
% abscissa, the abscissa is always stored as real, single
% precision.
complexOrd = (ordDataType == 5 | ordDataType == 6);
if spacingType == 0 % uneven
n_ord_vals_to_read = (DataSetProp.nBytes - numpt*4)/numLen;
else % even
n_ord_vals_to_read = DataSetProp.nBytes/numLen;
end
n_ord_vals_to_read = n_ord_vals_to_read/(1+complexOrd);
n_act_bytes = blockLines(end, 2) - blockLines(12,1) + 1;
skipbytes = n_act_bytes - DataSetProp.nBytes;
if skipbytes < 0
errMessage = ['Badly formated binary uff file (' fileName '): '...
'not enough bytes of data according to the bytes '...
'specified in the header of the set #' num2str(setn)];
return
end
if numpt ~= n_ord_vals_to_read && show_warning
warning(['Badly formated binary uff file (%s) at set #%d: the number of bytes '...
'specified does not match the specified number of '...
'values; only the data corresponding to the number '...
'of bytes will be read.'], fileName, setn);
end
if skipbytes > 0 && show_warning
warning(['Badly formated binary uff file (%s) at set #%d: the size of the data '...
'is greater than the number of bytes specified; extra '...
'extra bytes at the end will be skipped.'], fileName, setn);
end
% status = fseek(fid, blockLines(12,1)-1+skipbytes, 'bof');
status = fseek(fid, blockLines(12,1)-1, 'bof');
if status
errMessage = ['could not start reading binary data from ' fileName...
' at set #' num2str(setn)];
return
end
n_ord_vals_to_read = max(numpt, n_ord_vals_to_read)*(1+complexOrd);
try
if spacingType == 0 % uneven spacing
absc_values = fread(fid, numpt, 'float32', numLen*(1+complexOrd*1));
fseek(fid, blockLines(12,1)-1+4+skipbytes, 'bof');
values = fread(fid, n_ord_vals_to_read, prec, 4);
if complexOrd
values = [absc_values; reshape(values, 2, numpt)];
values = reshape(values, numpt*3, 1);
else
values = [absc_values; reshape(values, 1, numpt)];
values = reshape(values, numpt*2, 1);
end
else
values = fread(fid, n_ord_vals_to_read, prec);
end
catch
errMessage = ['error while reading binary data from ' fileName];
return
end
fclose(fid);
else
%------
% ASCII
%------
values = sscanf(DATA(blockLines(12,1):blockLines(end,2)),'%g');
end
% Abscissa and ordinate values
if (ordDataType == 2 || ordDataType == 4) % non-complex ordinate data
if spacingType == 0 % uneven abscissa
UFF.x = values(1:2:2*numpt-1);
UFF.measData = values(2:2:2*numpt);
else % even abscissa
UFF.measData = values(1:numpt);
nVal = length(UFF.measData);
UFF.x = UFF.xmin : UFF.dx : UFF.xmin + (nVal-1)*UFF.dx;
end
elseif (ordDataType == 5 || ordDataType == 6) % complex ordinate data
if spacingType == 0 % uneven abscissa
UFF.measData = values(2:3:3*numpt-1) + j*values(3:3:3*numpt);
UFF.x = values(1:3:3*numpt-2);
else % even abscissa
UFF.measData = values(1:2:2*numpt-1) + j*values(2:2:2*numpt);
nVal = length(UFF.measData);
UFF.x = UFF.xmin : UFF.dx : UFF.xmin + (nVal-1)*UFF.dx;
end
else
errMessage = ['error reading measurement data at:' num2str(lineN)];
return
end
catch
errMessage = ['error reading measurement data: ' lasterr];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract151(DATA,blockLines)
% #151 - Extract data-set type 151 data
UFF = [];
errMessage = [];
lineN = 1;
nLines = size(blockLines,1);
try
% Line 1
UFF.modelName = strim(sscanf(DATA(blockLines(1,1):blockLines(1,2)),'%c',80));
lineN = lineN + 1;
% Line 2
UFF.description = strim(sscanf(DATA(blockLines(2,1):blockLines(2,2)),'%c',80));
lineN = lineN + 1;
% Line 3
UFF.dbApp = strim(sscanf(DATA(blockLines(3,1):blockLines(3,2)),'%c',80));
lineN = lineN + 1;
% Line 4
tmpLine = DATA(blockLines(4,1):blockLines(4,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.dateCreated = sscanf(tmpLine(1:10),'%c');
UFF.timeCreated = sscanf(tmpLine(11:20),'%c');
UFF.dbVersion = sscanf(tmpLine(21:30),'%i',10);
lineN = lineN + 1;
% Line 5
tmpLine = DATA(blockLines(5,1):blockLines(5,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.dateSaved = sscanf(tmpLine(1:10),'%c');
UFF.timeSaved = sscanf(tmpLine(11:20),'%c');
lineN = lineN + 1;
% Line 6
UFF.uffApp = strim(sscanf(DATA(blockLines(6,1):blockLines(6,2)),'%c',80));
catch
errMessage = ['error reading header data at line ' num2str(lineN) ' relatively to current data-set'];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract164(DATA,blockLines)
% #164 - Extract data-set type 164 data
UFF = [];
errMessage = [];
lineN = 1;
nLines = size(blockLines,1);
try
% Line 1
tmpLine = DATA(blockLines(1,1):blockLines(1,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.unitsCode = sscanf(tmpLine(1:10),'%i');
UFF.unitsDescription = strim(sscanf(tmpLine(11:31),'%c'));
UFF.tempMode = sscanf(tmpLine(32:41),'%i');
lineN = lineN + 1;
% Line 2
tmpLine = DATA(blockLines(2,1):blockLines(2,2));
tmpLine = lower([tmpLine repmat(' ',1,80-length(tmpLine))]);
tmpLine = strrep(tmpLine,'d-','e-');
tmpLine = strrep(tmpLine,'d+','e+');
UFF.facLength = sscanf(tmpLine(1:25),'%f');
UFF.facForce = sscanf(tmpLine(26:50),'%f');
UFF.facTemp = sscanf(tmpLine(51:75),'%f');
lineN = lineN + 1;
% Line 3
tmpLine = DATA(blockLines(3,1):blockLines(3,2));
tmpLine = lower([tmpLine repmat(' ',1,80-length(tmpLine))]);
tmpLine = strrep(tmpLine,'d-','e-');
tmpLine = strrep(tmpLine,'d+','e+');
UFF.facTempOffset = sscanf(tmpLine(1:25),'%f');
catch
errMessage = ['error reading units data at line' num2str(lineN) ' relatively to current data-set: ' lasterr];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract15(DATA,blockLines)
% #15 - Extract data-set type 15 data
UFF = [];
errMessage = [];
nLines = size(blockLines,1);
try
values = sscanf(DATA(blockLines(1,1):blockLines(end,2)),'%g');
nVals = length(values);
nNodes = round(nVals/7);
values = reshape(values,7,nNodes).';
%
UFF.nodeN = round(values(:,1));
UFF.defCS = round(values(:,2));
UFF.dispCS = round(values(:,3));
UFF.color = round(values(:,4));
UFF.x = values(:,5);
UFF.y = values(:,6);
UFF.z = values(:,7);
catch
errMessage = ['error reading coordinate data: ' lasterr];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract82(DATA,blockLines)
% #82 - Extract display sequence data-set type 82 data
UFF = [];
errMessage = [];
lineN = 1;
nLines = size(blockLines,1);
try
% Line 1
tmpLine = DATA(blockLines(1,1):blockLines(1,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.traceNum = sscanf(tmpLine(1:10),'%i',1);
UFF.nNodes = sscanf(tmpLine(11:20),'%i',1);
UFF.color = sscanf(tmpLine(21:30),'%i',1);
lineN = lineN + 1;
% Line 2
UFF.ID = strim(sscanf(DATA(blockLines(2,1):blockLines(2,2)),'%c'));
lineN = lineN + 1;
% Line 3
UFF.lines = sscanf(DATA(blockLines(3,1):blockLines(end,2)),'%g');
catch
errMessage = ['error reading trace-line data at line' num2str(lineN) ' relatively to current data-set: ' lasterr];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract55(DATA,blockLines)
% #55 - Extract modal data-set type 55 data
UFF = [];
errMessage = [];
lineN = 1;
nLines = size(blockLines,1);
errN = 0;
try
% Line 1
UFF.d1 = strim(sscanf(DATA(blockLines(1,1):blockLines(1,2)),'%c',80));
lineN = lineN + 1;
% Line 2
UFF.d2 = strim(sscanf(DATA(blockLines(2,1):blockLines(2,2)),'%c',80));
lineN = lineN + 1;
% Line 3
UFF.date = strim(sscanf(DATA(blockLines(3,1):blockLines(3,2)),'%c',80));
lineN = lineN + 1;
% Line 4
UFF.IDs = strim(sscanf(DATA(blockLines(4,1):blockLines(4,2)),'%c',80));
% Line 5
temp = sscanf(DATA(blockLines(5,1):blockLines(5,2)),'%c');
lineN = lineN + 1;
% Line 6
tmpLine = DATA(blockLines(6,1):blockLines(6,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
UFF.modelType = sscanf(tmpLine(1:10),'%i',1);
lineN = lineN + 1;
if UFF.modelType ~=1,
errMessage = ['not structural model type (line: ' num2str(lineN) ' relatively to current data-set)'];
return
end
UFF.analysisType = sscanf(tmpLine(11:20),'%i',1);
UFF.dataCharacter = sscanf(tmpLine(21:30),'%i',1);
UFF.responseType = sscanf(tmpLine(31:40),'%i',1);
UFF.dataType = sscanf(tmpLine(41:50),'%i',1);
num_data_per_pt = sscanf(tmpLine(51:60),'%c');
% Read records 7 and 8 which are analysis-type dependent
if UFF.analysisType == 2 % Normal Mode
% Line 7
tmpLine = DATA(blockLines(7,1):blockLines(7,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
two = sscanf(tmpLine(1:10),'%i',1);
lineN = lineN + 1;
if two ~= 2,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
four = sscanf(tmpLine(11:20),'%i',1);
if four ~= 4,
errMessage = ['unexpected value at line: ' num2str(lineN) ' relatively to current data-set'];
return
end
tmp = sscanf(tmpLine(21:30),'%i',1);
UFF.modeNum = sscanf(tmpLine(31:40),'%i',1);
% Line 8
tmpLine = DATA(blockLines(8,1):blockLines(8,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
UFF.modeFreq = sscanf(tmpLine(1:13),'%g',1);
UFF.modeMass = sscanf(tmpLine(14:26),'%g',1);
UFF.mode_v_damping_ratio = sscanf(tmpLine(27:39),'%g',1);
UFF.mode_h_damping_ratio = sscanf(tmpLine(40:52),'%g',1);
elseif UFF.analysisType == 3, % Complex Eigenvalue, First Order (Displacement)
% Line 7
tmpLine = DATA(blockLines(7,1):blockLines(7,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
two = sscanf(tmpLine(1:10),'%i',1);
if two ~= 2,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
six = sscanf(tmpLine(11:20),'%i',1);
if six ~= 6,
errMessage = ['unexpected value at line: ' num2str(lineN) ' relatively to current data-set'];
return
end
tmp = sscanf(tmpLine(21:30),'%i',1);
UFF.modeNum = sscanf(tmpLine(31:40),'%i',1);
% Line 8
tmpLine = DATA(blockLines(8,1):blockLines(8,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
real_part = sscanf(tmpLine(1:13),'%g',1);
imaginary_part = sscanf(tmpLine(14:26),'%g',1);
UFF.eigVal = real_part + j * imaginary_part;
real_part = sscanf(tmpLine(27:39),'%g',1);
imaginary_part = sscanf(tmpLine(40:52),'%g',1);
UFF.modalA = real_part + j * imaginary_part;
real_part = sscanf(tmpLine(53:65),'%g',1);
imaginary_part = sscanf(tmpLine(66:78),'%g',1);
UFF.modalB = real_part + j * imaginary_part;
elseif UFF.analysisType == 5, % Frequency Response
% Line 7
tmpLine = DATA(blockLines(7,1):blockLines(7,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
two = sscanf(tmpLine(1:10),'%i',1);
if two ~= 2,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
one = sscanf(tmpLine(11:20),'%i',1);
if one ~= 1,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
tmp = sscanf(tmpLine(21:30),'%i',1);
UFF.freqNum = sscanf(tmpLine(31:40),'%i',1);
% Line 8
tmpLine = DATA(blockLines(8,1):blockLines(8,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
UFF.freq = sscanf(tmpLine(1:13),'%g',1); % in Hz
elseif UFF.analysisType == 7 % Complex Eigenvalue, Second Order (Velocity)
% Line 7
tmpLine = DATA(blockLines(7,1):blockLines(7,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
two = sscanf(tmpLine(1:10),'%i',1);
if two ~= 2,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
six = sscanf(tmpLine(11:20),'%i',1);
if six ~= 6,
errMessage = ['unexpected value at line ' num2str(lineN) ' relatively to current data-set'];
return
end
tmp = sscanf(tmpLine(21:30),'%i',1);
UFF.modeNum = sscanf(tmpLine(31:40),'%i',1);
% Line 8
tmpLine = DATA(blockLines(8,1):blockLines(8,2));
tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
lineN = lineN + 1;
real_part = sscanf(tmpLine(1:13),'%g',1);
imaginary_part = sscanf(tmpLine(14:26),'%g',1);
UFF.eigVal = real_part + j * imaginary_part;
real_part = sscanf(tmpLine(27:39),'%g',1);
imaginary_part = sscanf(tmpLine(40:52),'%g',1);
UFF.modalA = real_part + j * imaginary_part;
real_part = sscanf(tmpLine(53:65),'%g',1);
imaginary_part = sscanf(tmpLine(66:78),'%g',1);
UFF.modalB = real_part + j * imaginary_part;
else
errMessage = ['analysis type is not supported at line ' num2str(lineN) ' relatively to current data-set'];
return
end
% Read response data by x,y,...components into r1..r6
ii = 0;
nnodes = floor((nLines-9)/2)+1;
r1 = zeros(nnodes,1);
r2 = r1;
r3 = r1;
r4 = r1;
r5 = r1;
r6 = r1;
nodeNum = r1;
for lne = 9:2:nLines-1,
ii = ii + 1;
%========
% line = 9; % line 9 type of line
%========
lineRead = lne;
tmpLine = DATA(blockLines(lineRead,1):blockLines(lineRead,2));
nodeNum(ii) = sscanf(tmpLine(1:10),'%i',1);
lineN = lineN + 1;
%========
% line = 10; % line 9 type of line
%========
lineRead = lne + 1;
lineN = lineN + 1;
tmpLine = DATA(blockLines(lineRead,1):blockLines(lineRead,2));
% tmpLine = [tmpLine repmat(' ',1,80-length(tmpLine))];
if UFF.dataType == 2, % real data
r1(ii) = sscanf(tmpLine(1:13),'%g',1);
r2(ii) = sscanf(tmpLine(14:26),'%g',1);
r3(ii) = sscanf(tmpLine(27:39),'%g',1);
if num_data_per_pt == 6,
r4(ii) = sscanf(tmpLine(40:52),'%g',1);
r5(ii) = sscanf(tmpLine(53:65),'%g',1);
r6(ii) = sscanf(tmpLine(66:78),'%g',1);
end
elseif UFF.dataType == 5, % complex data
p1 = sscanf(tmpLine(1:13),'%g',1);
p2 = sscanf(tmpLine(14:26),'%g',1);
r1(ii) = p1 + j * p2;
p3 = sscanf(tmpLine(27:39),'%g',1);
p4 = sscanf(tmpLine(40:52),'%g',1);
r2(ii) = p3 + j * p4;
p5 = sscanf(tmpLine(53:65),'%g',1);
p6 = sscanf(tmpLine(66:78),'%g',1);
r3(ii) = p5 + j * p6;
if num_data_per_pt == 6,
errMessage = ['not setup to handle six coordinate of complex data at line ' num2str(lineN) ' relatively to current data-set'];
return
end
else
errMessage = ['what kind of data type was that at line ' num2str(lineN) ' relatively to current data-set?'];
return
end
end
UFF.r1 = r1;
UFF.r2 = r2;
UFF.r3 = r3;
UFF.r4 = r4;
UFF.r5 = r5;
UFF.r6 = r6;
UFF.nodeNum = nodeNum;
catch
errMessage = ['error reading modal data: ' lasterr];
return
end
%--------------------------------------------------------------------------
function outstr = strim(str)
% Removes leading and trailing spaces (spaces, tabs, endlines,...)
% from the str string.
if isnumeric(str);
outstr = str;
return
end
ind = find( ~isspace(str) ); % indices of the non-space characters in the str
if isempty(ind)
outstr = [];
else
outstr = str( ind(1):ind(end) );
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract2411(DATA,blockLines)
% #2411 - Extract data-set type 2411 data
% Added by Ben Cazzolato, 10/3/2008
%
% Universal Dataset Number 2411
% by zopeown last modified 2007-05-02 06:56
%
% Name: Nodes - Double Precision
% Status: Current
% Owner: Simulation
% Revision Date: 23-OCT-1992
% ----------------------------------------------------------------------------
%
% Record 1: FORMAT(4I10)
% Field 1 -- node label
% Field 2 -- export coordinate system number
% Field 3 -- displacement coordinate system number
% Field 4 -- color
% Record 2: FORMAT(1P3D25.16)
% Fields 1-3 -- node coordinates in the part coordinate
% system
%
% Records 1 and 2 are repeated for each node in the model.
%
% Example:
%
% -1
% 2411
% 121 1 1 11
% 5.0000000000000000D+00 1.0000000000000000D+00 0.0000000000000000D+00
% 122 1 1 11
% 6.0000000000000000D+00 1.0000000000000000D+00 0.0000000000000000D+00
% -1
%
% ----------------------------------------------------------------------------
UFF = [];
errMessage = [];
nLines = size(blockLines,1);
try
values = sscanf(DATA(blockLines(1,1):blockLines(end,2)),'%g');
nVals = length(values);
nNodes = round(nVals/7);
values = reshape(values,7,nNodes).';
%
UFF.nodeN = round(values(:,1));
UFF.defCS = round(values(:,2));
UFF.dispCS = round(values(:,3));
UFF.color = round(values(:,4));
UFF.x = values(:,5);
UFF.y = values(:,6);
UFF.z = values(:,7);
catch
errMessage = ['error reading coordinate data: ' lasterr];
return
end
%--------------------------------------------------------------------------
function [UFF,errMessage] = extract2412(DATA,blockLines)
% #2412 - Extract display sequence data-set type 82 data
% Added by Ben Cazzolato, 10/3/2008
%
% Universal Dataset Number 2412
% by zopeown last modified 2007-05-02 06:56
%
% Name: Elements
% Status: Current
% Owner: Simulation
% Revision Date: 14-AUG-1992
% -----------------------------------------------------------------------
%
% Record 1: FORMAT(6I10)
% Field 1 -- element label
% Field 2 -- fe descriptor id
% Field 3 -- physical property table number
% Field 4 -- material property table number
% Field 5 -- color
% Field 6 -- number of nodes on element
%
% Record 2: *** FOR NON-BEAM ELEMENTS ***
% FORMAT(8I10)
% Fields 1-n -- node labels defining element
%
% Record 2: *** FOR BEAM ELEMENTS ONLY ***
% FORMAT(3I10)
% Field 1 -- beam orientation node number
% Field 2 -- beam fore-end cross section number
% Field 3 -- beam aft-end cross section number
%
% Record 3: *** FOR BEAM ELEMENTS ONLY ***
% FORMAT(8I10)
% Fields 1-n -- node labels defining element
%
% Records 1 and 2 are repeated for each non-beam element in the model.
% Records 1 - 3 are repeated for each beam element in the model.
%
% Example:
%
% -1
% 2412
% 1 11 1 5380 7 2
% 0 1 1
% 1 2
% 2 21 2 5380 7 2
% 0 1 1
% 3 4
% 3 22 3 5380 7 2
% 0 1 2
% 5 6
% 6 91 6 5380 7 3
% 11 18 12
% 9 95 6 5380 7 8
% 22 25 29 30 31 26 24 23
% 14 136 8 0 7 2
% 53 54
% 36 116 16 5380 7 20
% 152 159 168 167 166 158 150 151
% 154 170 169 153 157 161 173 172
% 171 160 155 156
% -1
%
% FE Descriptor Id definitions
% ____________________________
%
% 11 Rod
% 21 Linear beam
% 22 Tapered beam
% 23 Curved beam
% 24 Parabolic beam
% 31 Straight pipe
% 32 Curved pipe
% 41 Plane Stress Linear Triangle
% 42 Plane Stress Parabolic Triangle
% 43 Plane Stress Cubic Triangle
% 44 Plane Stress Linear Quadrilateral
% 45 Plane Stress Parabolic Quadrilateral
% 46 Plane Strain Cubic Quadrilateral
% 51 Plane Strain Linear Triangle
% 52 Plane Strain Parabolic Triangle
% 53 Plane Strain Cubic Triangle
% 54 Plane Strain Linear Quadrilateral
% 55 Plane Strain Parabolic Quadrilateral
% 56 Plane Strain Cubic Quadrilateral
% 61 Plate Linear Triangle
% 62 Plate Parabolic Triangle
% 63 Plate Cubic Triangle
% 64 Plate Linear Quadrilateral
% 65 Plate Parabolic Quadrilateral
% 66 Plate Cubic Quadrilateral
% 71 Membrane Linear Quadrilateral
% 72 Membrane Parabolic Triangle
% 73 Membrane Cubic Triangle
% 74 Membrane Linear Triangle
% 75 Membrane Parabolic Quadrilateral
% 76 Membrane Cubic Quadrilateral
% 81 Axisymetric Solid Linear Triangle
% 82 Axisymetric Solid Parabolic Triangle
% 84 Axisymetric Solid Linear Quadrilateral
% 85 Axisymetric Solid Parabolic Quadrilateral
% 91 Thin Shell Linear Triangle
% 92 Thin Shell Parabolic Triangle
% 93 Thin Shell Cubic Triangle
% 94 Thin Shell Linear Quadrilateral
% 95 Thin Shell Parabolic Quadrilateral
% 96 Thin Shell Cubic Quadrilateral
% 101 Thick Shell Linear Wedge
% 102 Thick Shell Parabolic Wedge
% 103 Thick Shell Cubic Wedge
% 104 Thick Shell Linear Brick
% 105 Thick Shell Parabolic Brick
% 106 Thick Shell Cubic Brick
% 111 Solid Linear Tetrahedron
% 112 Solid Linear Wedge
% 113 Solid Parabolic Wedge
% 114 Solid Cubic Wedge
% 115 Solid Linear Brick
% 116 Solid Parabolic Brick
% 117 Solid Cubic Brick
% 118 Solid Parabolic Tetrahedron
% 121 Rigid Bar
% 122 Rigid Element
% 136 Node To Node Translational Spring
% 137 Node To Node Rotational Spring
% 138 Node To Ground Translational Spring
% 139 Node To Ground Rotational Spring
% 141 Node To Node Damper
% 142 Node To Gound Damper
% 151 Node To Node Gap
% 152 Node To Ground Gap
% 161 Lumped Mass
% 171 Axisymetric Linear Shell
% 172 Axisymetric Parabolic Shell
% 181 Constraint
% 191 Plastic Cold Runner
% 192 Plastic Hot Runner
% 193 Plastic Water Line
% 194 Plastic Fountain
% 195 Plastic Baffle
% 196 Plastic Rod Heater
% 201 Linear node-to-node interface
% 202 Linear edge-to-edge interface
% 203 Parabolic edge-to-edge interface
% 204 Linear face-to-face interface
% 208 Parabolic face-to-face interface
% 212 Linear axisymmetric interface
% 213 Parabolic axisymmetric interface
% 221 Linear rigid surface
% 222 Parabolic rigid surface
% 231 Axisymetric linear rigid surface
% 232 Axisymentric parabolic rigid surface
%
% ------------------------------------------------------------------------------
% Define all "beam like" elements since these have a different structure
beam_like = [11,21:24,31:32,121:122];
Largest_Num_Nodes = 20; % This is used to zero pad the data if different element types present
UFF = [];
errMessage = [];
% Initialise matrices containing field types
ElementLabel = [];
FEDescriptor = [];
PhysicalProp = [];
MaterialProp = [];
ElementColour = [];
NumNodes = [];
Element = [];
try
values = sscanf(DATA(blockLines(1,1):blockLines(end,2)),'%g');
nVals = length(values);
data_remaining = 1;
while data_remaining
ElementLabel = [ElementLabel;round(values(1))];
FEDescriptor = [FEDescriptor;round(values(2))];
PhysicalProp = [PhysicalProp;round(values(3))];
MaterialProp = [MaterialProp;round(values(4))];
ElementColour = [ElementColour;round(values(5))];
NumNodes = [NumNodes;round(values(6))];
% Check for beam elements
if sum(round(values(2))==beam_like)
% Beam Element
%disp('Beam Elements')
Element = [Element;[[round(values(7:6+3+round(values(6))))]',NaN*zeros(1,Largest_Num_Nodes-3-round(values(6)))]];
values = values(7+3+round(values(6)):end); % Remove the element from the table
else
% Not Beam Element
Element = [Element;[[round(values(7:6+round(values(6))))]',NaN*zeros(1,Largest_Num_Nodes-round(values(6)))]];
values = values(7+round(values(6)):end); % Remove the element from the table
end
if isempty(values) % Check if any data remaining
data_remaining=0;
end
end
UFF.ElementLabel = ElementLabel;
UFF.FEDescriptor = FEDescriptor;
UFF.PhysicalProp = PhysicalProp;
UFF.MaterialProp = MaterialProp;
UFF.ElementColour = ElementColour;
UFF.NumNodes = NumNodes;
% Strip unnecessary columns from element matrix
temp = find(sum(~isnan(Element))>0);
UFF.Element = Element(:,temp);
catch
errMessage = ['error reading trace-line data at line' num2str(lineN) ' relatively to current data-set: ' lasterr];
return
end