Compose-3015: Reading Data from Text Files

This tutorial demonstrates how to extract nodal positions from the LS-DYNA input file, truck.key. This file can be found in <install>/tutorials/.

OML contains a set of commands that operate on string data types. You can use a combination of the string tools and file reading commands to read data from arbitrary text files.

Define the Target Variables

  1. Start Compose.
  2. In a new script, type the following commands, adjusting the file path to the appropriate location of the file. The vector nodeListcontains the node ID’s at which to read the x, y, z coordinates. The list is then sorted numerically in ascending order. The matrix nodesInfo is initialized to the appropriate size to contain all the requested data.
    fileName=‘<INSERT_PATH>/truck.key’;
    nodeList = [1, 211, 57, 5];
    nodeList = sort(nodeList);
    nodeInfo = zeros(length(nodeList),3);

Create the General Structure to Read the File

The following code segment opens a file for reading, reads through the file one line at a time until the end of the file, and then closes the file. The body within the while loop, which currently contains only the instruction to read the next line of the file, contains the set of commands to be performed upon each line. The commands to be added are presented in the following steps, but the code segment provided here is general enough to read any file. Add these lines to your script, run the file, and check for the displayed message, indicating a successful completion.
[fid, message] = fopen(fileName, 'r');
line = fgetl(fid);
while ~feof(fid)
  line = fgetl(fid);
end
disp('Finished reading the file')

Add Control Structures to Parse Data Lines

  1. The input file structure contains nodal data in a so-called block format. Blocks of data are indicated by a specific keyword (beginning with the character ‘*’ in LS-DYNA), and the data follows on subsequent lines until another keyword is encountered. Nodal data begins with the keyword *NODE. Within the nodal data block, each line contains the information for a given node: the first eight characters within the line contain the node ID, and next three 16-character groups contain the x-y-z coordinates, respectively. The first logical control to add is to determine if the reader is currently within a *NODE block. For this purpose, a Boolean variable, nodeOn, is created to contain the test of whether the most recently read keyword is *NODE. First, define the variable with a default value of false. Before the while control block, type the command:
    nodeOn = false;
  2. Within the while block and before the read command, add controls to test the status of this Boolean variable. The value of nodeOn begins false. The status is changed to true when the current line contains the text *NODE. See the topic strfind in the Reference Guide for more details on the string find command. For this example, however, it is sufficient to note that the command returns an empty value if the search is unsuccessful.
    if nodeOn == true
        %process node data line
    else
        search = strfind(line,'*NODE')
        if ~isempty(search)
            nodeOn = true;
        end
    end

Process and Store the Requested Nodal Data

  1. When processing data lines that are within the node block, there are three possible cases that must be handled: (1) skip comment lines which are indicated by ‘$’, (2) identify the end of the block if the data on the line is a keyword to indicate the start of a new block, and (3) process a line of node data. Note that case (3) is required when (1) and (2) are false. The following code segment placed within the nodeOn == true block properly handles the three cases above.
    search=strfind(line,’$’);
    if ~isempty(search)
            line = fgetl(fid);
            continue;
    end
    search = strfind(line,'*');
    if ~isempty(search)
        nodeOn = false;
    else
        %proper node line
    End
  2. When processing a node line, the first step is to determine the ID. This information is contained in the first eight characters of the line, which can be extracted using the loop command. Note that this command returns a string, and you need to use the str2num function to force the data type to a number. This ID can then be tested against the requested list of IDs contained in the vector nodeList using the command eq function, which returns a vector of 0’s (false) and 1’s (true) indicating each entry’s equality. Any 1’s in the vector, which can be quickly summed, indicate that the current node ID is requested. Type the following code segment to add this logic to your script:
    node = str2num(line(1:8));
    boolean = eq(nodeList,node);
    if sum(boolean)  > 0
         %store this node’s data
    end
  3. Finally, if the node has a requested ID, the following code can extract the data from the x,y, and z coordinate fields and store them in the matrix nodeInfo. Add the following lines, save your script, and run it. Compare the values stored on nodeInfo to the data within the text file.
    x = str2num(line(9:24));
    y = str2num(line(25:40));
    z = str2num(line(41:56));
    for ix = 1:length(nodeList) 
       if boolean(ix) == 1
             nodeInfo(ix,:) = [ x, y, z];
       end
    end
  4. Please refer to read_txt.txt file in the <installation folder>/tutorials/ for the complete script.