ansa scripting

81
A A N N S S A A version 12.1.x Scripting Language A guide to ANSA automation BETA CAE Systems S.A. β

Upload: crisstian

Post on 22-Nov-2014

2.254 views

Category:

Documents


244 download

TRANSCRIPT

Page 1: Ansa Scripting

AANNSSAA version 12.1.x

Scripting LanguageA guide to ANSA automation

BETA CAE Systems S.A.β

Page 2: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 2

Page 3: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 3

Table of Contents

SECTION 1 DESCRIPTION OF THE SCRIPTING LANGUAGE ....................................6 1.1. General ................................................................................................................................................. 6 1.2. Data Types ........................................................................................................................................... 6

1.2.1. User Defined Data Types (structures) ........................................................................................... 7 1.3. Variables............................................................................................................................................... 7

1.3.1. Naming of Variables and Restrictions............................................................................................ 7 1.3.2. Important Notes on Variables ........................................................................................................ 8

1.4. Operators and Basic Calculation....................................................................................................... 8 1.4.1. Expressions and assignments for numeric data types .................................................................. 8 1.4.2. Operator precedence ..................................................................................................................... 9 1.4.3. Important Notes on Operators ..................................................................................................... 10 1.4.4. Numeric intrinsic functions ........................................................................................................... 10 1.4.5. Expressions and assignments for string data types .................................................................... 11 1.4.6. Expressions and assignments for user defined data types (structures) ...................................... 11

1.5. Sets of data: Matrices and maps ..................................................................................................... 12 1.5.1. Matrices........................................................................................................................................ 12 1.5.2. Maps............................................................................................................................................. 15

1.6. Conditional Statements and Branching.......................................................................................... 16 1.6.1. The "if-else" blocks and the logical operators .............................................................................. 16 1.6.2. The switch statement ................................................................................................................... 17 1.6.3. The goto statement ...................................................................................................................... 18

1.7. Loop statements................................................................................................................................ 18 1.7.1. The foreach statement ................................................................................................................. 18 1.7.2. The for statement ......................................................................................................................... 19 1.7.3. The while statement ..................................................................................................................... 19 1.7.4. The do while construct ................................................................................................................. 19 1.7.5. The continue and break statements............................................................................................. 20

1.8. User functions and comments......................................................................................................... 20 1.8.1. Definition ...................................................................................................................................... 21 1.8.2. Argument list and function call ..................................................................................................... 21 1.8.3. Returning data from functions (return, byref call) ........................................................................ 21 1.8.4. Including Files .............................................................................................................................. 22 1.8.5. Scope and lifetime of variables .................................................................................................... 23 1.8.6. Recursive structures .................................................................................................................... 24 1.8.7. Initialization and un-initialization of matrices and variables ......................................................... 25 1.8.8. Use of help text and comments in functions ................................................................................ 25 1.8.9. Session commands for use in Scripting Language...................................................................... 26

SECTION 2 INTERACTING WITH ANSA.....................................................................27 2.1. General ............................................................................................................................................... 27 2.2. Handling Data .................................................................................................................................... 27

2.2.1. Data of element type .................................................................................................................... 27 2.2.2. ANSA cards and entity types ....................................................................................................... 27

2.3. Collecting entities.............................................................................................................................. 28 2.3.1. General......................................................................................................................................... 28 2.3.2. Collecting entities massively from the whole database ............................................................... 29 2.3.3. Collecting entities massively from other entities .......................................................................... 30 2.3.4. Collecting massively visible entities ............................................................................................. 31 2.3.5. Collecting available entity types of specific deck ......................................................................... 31 2.3.6. Get single entities......................................................................................................................... 32 2.3.7. Collecting part and groups from their ids ..................................................................................... 32 2.3.8. Collecting entities according to their name .................................................................................. 32 2.3.9. Collecting all new created/imported entities................................................................................. 33 2.3.10. Collecting a number of files or directories into a list .................................................................. 33 2.3.11. Select files or directories with the aid of the File Manager ........................................................ 34

2.4. Edit, Create and Delete Entities ....................................................................................................... 35 2.4.1. General......................................................................................................................................... 35

Page 4: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 4

2.4.2. Get values from an entity using its Edit card................................................................................ 35 2.4.3. Modifying the card's values.......................................................................................................... 36 2.4.4. Creating new entities.................................................................................................................... 37 2.4.5 Creating parts and groups............................................................................................................. 37 2.4.6 Creating connection entities.......................................................................................................... 37 2.4.7 Editing the characteristics of a connection entity.......................................................................... 38 2.4.8 Realizing connections ................................................................................................................... 39 2.4.9 Getting the entities of connections................................................................................................ 41 2.4.10. Deleting entities.......................................................................................................................... 42

2.5. Creating user defined buttons and custom GUI ............................................................................ 42 2.5.1. General......................................................................................................................................... 42 2.5.2. Creation of user buttons using the AddUserButton function........................................................ 42 2.5.3. Creation of custom GUI................................................................................................................ 43 2.5.4. Setting Cancel and Ok buttons .................................................................................................... 44 2.5.5. Opening and Destroying Windows............................................................................................... 44 2.5.6. Callback functions ........................................................................................................................ 44

2.6. Setting of controls............................................................................................................................. 45 2.6.1. Setting edit fields and check buttons ........................................................................................... 45 2.6.2. Creating and setting up menus and radio buttons ....................................................................... 45 2.6.3 Creating and setting up List Boxes ............................................................................................... 47 2.6.4 Hiding and Showing controls ........................................................................................................ 50

SECTION 3 EXCHANGING DATA: TEXT FILES I/O ...................................................51 3.1 General ................................................................................................................................................ 51 3.2. Unformatted text files........................................................................................................................ 51

3.2.1. Opening and closing files ............................................................................................................. 51 3.2.2. Reading files ................................................................................................................................ 51 3.2.3. Writing files................................................................................................................................... 53

3.3. XML formatted files ........................................................................................................................... 54 3.3.1. Opening xml files.......................................................................................................................... 55 3.3.2. Getting nodes and sub-nodes...................................................................................................... 55 3.3.3. Getting the name of the node ...................................................................................................... 55 3.3.4. Getting attributes and node data.................................................................................................. 56 3.3.5 Writing XML files and setting the base node................................................................................. 56 3.3.6 Creating nodes.............................................................................................................................. 56 3.3.7 Setting attributes and node data ................................................................................................... 57

SECTION 4 SPECIALIZED FUNCTIONS .....................................................................58 4.1 General ................................................................................................................................................ 58 4.2 Description of Specialized functions ............................................................................................... 58

4.2.1 Creating Connectors and GEBs with scripting.............................................................................. 58 4.2.2 Executing specialized script functions from Connection Manager ............................................... 60

SECTION 5 HANDLING SCRIPTS AND ANSA_TRANSL...........................................64 5.1. General ............................................................................................................................................... 64 5.2. Using command window .................................................................................................................. 64

5.2.1 Quick view of auxiliary built in functions........................................................................................ 64 5.2.2 Description of auxiliary built in functions ....................................................................................... 64 5.2.3 Loading scripts .............................................................................................................................. 65 5.2.4 Running scripts ............................................................................................................................. 66

5.3 Using script menu .............................................................................................................................. 67 5.3.1 Script menu interface .................................................................................................................... 67 5.3.2 SCRIPT category .......................................................................................................................... 67 5.3.3 FUNCTION category..................................................................................................................... 68

5.4 Automation through an ANSA_TRANSL file.................................................................................... 69 5.4.1 Location of ANSA_TRANSL file.................................................................................................... 69 5.4.2 How does ANSA interacts with ANSA_TRANSL .......................................................................... 69 5.4.3 Form of ANSA_TRANSL............................................................................................................... 69 5.4.4 What is a global code.................................................................................................................... 70

Page 5: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 5

5.4.5. Importing CAD files ...................................................................................................................... 71 5.4.6. Executing functions without any user interaction (autoexec)....................................................... 75

SECTION 6 SCRIPT EDITOR.......................................................................................76 6.1 Script Editor Layout.......................................................................................................................... 76 6.2 Opening scripts ................................................................................................................................ 76 6.3 Running scripts ................................................................................................................................ 76 6.4 Making use of the immediate tab ..................................................................................................... 77 6.5 Help area.......................................................................................................................................... 77 6.6 Compiled scripts............................................................................................................................... 77 6.7 Making or importing snippets ........................................................................................................... 77 6.8 Debugging scripts ............................................................................................................................ 79

Page 6: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 6

Section 1 Description of the Scripting Language

1.1. General A general description of the scripting language is given below. The description is organized in the following main sections: - Datatypes - Variables - Operators - Conditional Statements - Loop Statements - User Functions - Handling Model Data - GUI Reference

1.2. Data Types The data type determines the kind of data that a variable or a function can hold. Data types include integer or floating point numbers, strings, matrices etc. as well as user defined types. The following paragraphs describe the available data types for writing an ANSA script. Note however that variables used in ANSA scripts, are considered typeless and their type must be explicitly defined only when they are used as arguments of functions (See Section 1.8.2). Integers

my_var = 10;

The integer data type is used by variables that can only have whole numbers as values. Such variables are represented in memory by 32 or 64 bits depending on the machine architecture.

Floating Point

my_var = 112.5;

Values that are not integral are stored as floating point numbers. A floating point variable can be expressed as a decimal number such as 112.5, or with an exponent such as 1.125E2. In the latter case the decimal part is multiplied by the power of 10 after the E symbol. A floating point must contain a decimal point, or an exponent or both. If you write neither, then you have an integer. Floating point numbers are represented in memory by 32 or 64 bits depending on the machine architecture.

Strings

s = "a string"; As string, we declare a series of printable text characters representing human readable stuff. A string value is enclosed in quotes (e.g. "this is a string") and can be assigned to any variable for storage and easy access. String variables are internally represented as arrays of characters.

Elements

This is ANSA - specific data type, representing entities used within the model, for example a shell element or a property or a set. The keyword used to declare such entities is element. Typically, the element data type is used in the declaration of function arguments (See Section 1.8.2).

Page 7: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 7

1.2.1. User Defined Data Types (structures) In many cases, user scripts can be more elegantly and concisely expressed if they can be written in terms of aggregate structures. Such structures can be considered as user defined data types that represent a collection of one or more variables, possibly of different types, grouped together under a single name for convenient handling. The keyword used to declare such collections is struct and the individual variables within the collection are called its members.

1.3. Variables A variable is a named memory location that contains data and can be modified during script execution. For every variable we distinguish its data type and its value: - The data type describes what particular kind of data is stored in a variable, such as an integer number, a string etc. As we saw earlier, the data type must be declared only when a variable is used as an argument of a function; in all other cases a variable is typeless, ie. its type is defined by the way the variable is used. - The value of the data that a variable contains at any point is determined by the instructions of our code and, of course, this value will usually change many times during program execution.

1.3.1. Naming of Variables and Restrictions The name we give to a variable is called an identifier, or more conveniently, a variable name. Variable names can include the letters A-Z (in upper or lower case), the numbers 0-9 and the underscore character. All other characters including the blank space are illegal. A variable name is case sensitive and must begin with a letter or an underscore. Names usually indicate the kind of information that is stored in the variable and must be chosen in a manner that will not confuse the user. The following table lists some valid / invalid variable names:

# Variable Name Validity Reason 1. surface_area Valid -- 2. surface-area Invalid Is considered an operation 3. surface area Invalid Contains blank space 4. SurfaceArea Valid -- 5. _surface_area Valid -- 6. surface@area Invalid Contains reserved characters 7. _1-Surface Valid -- 8. Surface"1" Invalid Contains reserved characters 9. Surface_1 Valid -- 10. Surface/1/ Invalid Contains reserved characters 11. 1Surface Invalid Begins with a number

Although the number of characters in a variable name can be unlimited, it is usually a good programming practice to keep it short. Furthermore, the language reserves some "names" as "keywords". These names are used to represent internal functions and are not allowed to be used as variable or function names. The reserved characters and reserved words for writing an ANSA script are listed below: reserved characters:

=^*/+-%&'"\!(){}[]:;<>,.

reserved words: include, void, int, def, float, char, string, matrix, map pointer, element, struct, byref, if, else, for, do, while, foreach, in, switch, break, continue, goto, case, default, return, static, global, projectfile, defbutton, script, strict, entrypoint

reserved variables: FILENAME, FILEPATH, FLANCH_PROPERTY_ID, PART_COORD_SYS_DX1, PART_COORD_SYS_DX2, PART_COORD_SYS_DX3, PART_COORD_SYS_DY1, PART_COORD_SYS_DY2, PART_COORD_SYS_DY3, PART_COORD_SYS_DZ1, PART_COORD_SYS_DZ2, PART_COORD_SYS_DZ3, PART_COORD_SYS_X, PART_COORD_SYS_Y, PART_COORD_SYS_Z,

Page 8: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 8

PART_ID, PART_MASS, PART_MATERIAL_ID, PART_MATERIAL_NAME, PART_MODEL_NAME, PART_NAME, PART_VERSION, PART_VSC, PART_PROPERTY_ID, PART_PROPERTY_NAME, PART_PROPERTY_THICKNESS, POST_TRANSL_SCRIPT, POST_TRANSL_SCRIPT_ARGS, TRANSLATIONS, SEPARATORS, MAT_REG, SYMMETRY_PART_ID, SYMMETRY_PART_PID_OFFSET

reserved constants: NASTRAN LSDYNA PAMCRASH ABAQUS RADIOSS ANSYS CFD MORPH

1.3.2. Important Notes on Variables Note 1: Typeless Variables When writing ANSA scripts, you should not explicitly define the data type of variables. This is because all variables used in ANSA scripts are considered typeless and will automatically acquire the proper data type depending on their use at the time. For example, in a statement like: my_var = 13; the variable my_var is treated as being of integer type. But, if later on, the same variable is found in another statement like: my_var = "my string"; it will switch from integer to string type. If a user tries to explicitly define the type of a variable, eg. int my_var; then this line will be ignored. Note 2: When to define the Data Type of a Variable The use of typeless variables reduces the total number of variables used in a script, since the same variable can be used in different ways. However, typeless variables can be proven dangerous when they must be passed as arguments to a function, since the function should be aware as to how to treat these variables. Thus, in such cases, the data type of all variables that are communicated to a function must be explicitly declared in the functions' arguments. For example, if var1, var2 and var3 represent integer, float and string variables respectively, they should be declared as: def my_function (int var1, float var2, string var3)

1.4. Operators and Basic Calculation Various data types can be combined, by the appropriate operators, to form expressions. These expressions are evaluated when the script is executed. The results of a calculation can be stored for future use by assigning a value to a variable. This is done by an assignment statement whose general form is: <variable name> = <expression>; where <variable name> is the name of the variable, while <expression> is an expression formed by the combination of variable names using operators. The sets of operators and the rules of how expressions may be written and evaluated are determined by the types of the operands involved. Therefore, the data type is a very critical attribute of any data value.

1.4.1. Expressions and assignments for numeric data types An expression is formed by the combination of variables, constants and operators. Operators are used in order to compute new values out of old ones, and can be of two types: 1. arithmetic operators 2. assignment operators

Page 9: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 9

There are five different arithmetic operators that can occur in numeric expressions. These are:

# Operator Operation 1. + Addition 2. - Subtraction 3. * Multiplication 4. / Division 5. ** Exponentiation

Some examples of arithmetic expressions are: surface_area = width_x * width_y; interior_vol = exterior_vol-width_x * width_y * width_z; hypot2 = a**2 + b**2; However, the meaning of the 2nd and 3rd examples might not be clear. For instance, the 2nd example might be interpreted as interior_vol = (exterior_vol-width_x) * width_y * width_z; or interior_vol = exterior_vol-(width_x * width_y * width_z); The meaning of such expressions is resolved by defining an order of precedence for operators. This precedence will determine the order in which the expression is to be evaluated. The assignment operators are the ones that actually assign a value to a variable. The well known “=“ sign is an assignment operator. For example x = 1; sets x to 1, and a = b; sets a to whatever b's value is. The expression i = i + 1; is a standard programming idiom for increasing a variable's value by 1, while i = i - 1; i = i * 2; i = i / 2; will decrease a variable’s value by 1, multiply and divide it by 2 respectively.

1.4.2. Operator precedence The order of precedence is very much alike what is known from algebra. Thus, exponentiations are carried out first, then multiplications and divisions and finally additions and subtractions. Multiplication and division have equal precedence. When a number of multiplications and divisions are found in sequence, the expression is evaluated from left to right. The same applies for addition and subtraction. Thus, the expression x / y * z ; is understood to be (x / y) * z and not x /(y * z)

Page 10: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 10

It should be noted here that the use of parentheses can force the order of evaluation of certain expressions. Thus, the expression: x /(y * z); will be evaluated exactly as written.

1.4.3. Important Notes on Operators Note 1: Combination of assignment with arithmetic operators The pattern: v = v op value; where v is a variable, op is any of the addition, subtraction, multiplication and division operators +,-,*,/ and value is a constant arithmetic value, can be shortly expressed as: v op = value; where v does not have to be mentioned twice. For example, the expressions i = i + 1; i = i - 1; i = i * 2; i = i / 2; can be equivalently written as: i += 1; i -= 1; i *= 2; i /= 2; Note 2: Increment and decrement operators For the most common cases where we add or subtract the constant value 1 from a variable, ANSA scripting language allows the use of auto-increment or auto-decrement operators. In their simpler form, they look like this: i++; i--; These expressions correspond to the slightly longer: i += 1; i -= 1; and to the fully expanded: i = i + 1; i = i - 1;

1.4.4. Numeric intrinsic functions It is often necessary to evaluate special mathematical functions, such as the square root of a number, the sine or cosine of an angle. The ANSA scripting language incorporates several such intrinsic functions, to enable such functions to be evaluated easily. Some of the most important arithmetic functions are given in the table below.

Page 11: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 11

# intrinsic function Description comment 1. Sqrt(x) calculates the square root of x -- 2. Cos(x) calculates the cosine of x x is given in radians 3. Sin(x) calculates the sine of x x is given in radians 4. Tan(x) calculates the tangent of x x is given in radians 5. Exp(x) calculates e raised to the power or x -- 6. Log(x) calculates the natural algorithm of x -- 7. Asin(x) calculates the arcsine of x -- 8. Acos(x) calculates the arccosine of x -- 9. Atan(x) calculates the arctangent of x result between –pi/2 and +pi/2 10. Abs(x) calculates the absolute value of x --

1.4.5. Expressions and assignments for string data types Characters may be assigned to string variables, using statements similar to those of numeric types: property = "PSHELL"; mat_name = "steel_105"; The operators that can be used to form expressions between string data types are:

# operator operation 1. + string catenation 2. % string catenation

For example, the string variable property = "PSHELL"; can be catenated with the string variable id = "with id 1"; as property_id = property + id; or with the equivalent property_id = property % id; and assign to the property_id variable the value "PSHELL with id 1"

1.4.6. Expressions and assignments for user defined data types (structures) A typical example of a user defined data type can be the point collection: Each point occupies a position in space as dictated by its coordinates and may also have a unique ID to distinguish it from other points. The point coordinates are real numbers and the ID is an integer. These point data can be grouped under the same structure in the following way: struct {int point_id; float x; float y; float z;} point; The above line defines a structure called point whose members are an integer called point_id and three floats for the coordinates x, y, z. Once the structure is defined, it can be used as a regular data type for the declaration of other variables. For example, if we need to declare a point PA in space, we just need to type: point PA; Now, the PA variable can automatically reference the members of the point structure, in other words PA can reference its id and its x, y, z coordinates. The syntax for this reference is struct.member and in this case takes the form:

Page 12: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 12

PA.point_id ...the id of point PA PA.x …x-coordinate of PA PA.y …y-coordinate of PA PA.z …z-coordinate of PA For example, to assign number 13 as the id of point PA type: PA.point_id = 13; and to assign the coordinates of PA type: PA.x = 123.45; PA.y = 321.00; PA.z = 456.78; As an extension to declaring a single point PA that belongs to the structure point, we can declare an array (matrix) of points. For example, to declare an array called pts of 10 points in space using the structure point type: point pts[10]; The reference to the individual variables of the pts array follows the same rules as before. For example, to assign 13 as the id of the 5th point of the pts array, type: pts[5].point_id = 13; and to assign the coordinates of pts[5] type: pts[5].x = 123.45; pts[5].y = 321.00; pts[5].z = 456.78;

1.5. Sets of data: Matrices and maps Most problems that occur in practice require more than simple variables for their definition and solution. Thus, it is often necessary to handle data as sets of similar or different kind objects. Towards this direction comes the definition of matrices and maps.

1.5.1. Matrices

matrix m[10];

A matrix data type provides a way to collect entities under the same storage. As a good programming practice, matrices should be declared so that the program will reserve enough space to store the data. The corresponding keyword for this declaration is matrix. Since matrix members are actually variables, they can hold any type of variable, so a matrix like: m={1, 1.23, "some string", "a", 2, 99.23}; is perfectly valid. Matrix members are accessed with index operators, i.e. m[0] is the first element in a matrix. Indices run from 0 to allocated space -1, i.e. for matrix m[10] they run from 0 to 9. The function MatLen returns the length of matrix m. len = MatLen(m);

Page 13: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 13

Set some data in a matrix: To set some data to a specific position in a matrix: m[3] = 10; To specify all the matrix members at once: m = {10,7,9}; Matrix members can even be other matrices. Thus, a matrix like: m = {{10,7,9}, {5,2,17} {6,12,25}}; would form a 3x3 2 dimension matrix. Retrieve a matrix member value: To retrieve a value of a specific member of a matrix, the user must provide the corresponding index operator: i = m[0]; For the 3x3 2 dimension matrix given above: i = m [1][0]; will assign to i the value of 5. Handling strings as matrices Strings can be treated as matrices and in this way we can isolate any part of them without the use of any built in function. A string has a length equal to the number of characters that comprise it and each one character holds an index. The first character has index 1 and the last has index equal to the string length. str = "Bumber_Front"; The above string has 12 characters where B has index 1, u has index 2……and t has index 12. We can get any part of the string by using the indices of the characters. Here are some examples: str = str(1:6); //This will get the "Bumber" str = str(8:12);//This will get the "Front" str = str(8:8); //This will get the character "F" str = str(7:7); //This will get the character "_" str = str(3:8); //This will get the "mber_F" str = str(5:); //This will ge the "er_Front" str = str(:7); //This will get the "Bumber_" Important Note: The string length can be found using the function Strlen. Matrix expressions: All algebric operations between matrices and constant values are interpreted as operations between each member of the matrix and the constant value. For example the expression: B = 10*A; will result to a matrix B whose members are 10x the corresponding members of A. Addition, subtraction, division and exponetiation operations between matrices should take place only between conformable matrices (i.e. matrices having the same shape). On the other hand, the multiplication operation can take place both between conformable and unconformable matrices. In the former case, the multiplication takes place between each member of the matrices while in the latter case a matrix multiplication takes place. Having two conformable matrices A and B 2x3:

Page 14: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 14

A = {{10,7,9}, {5,2,17}}; B = {{2,1,1}, {1,2,1}}; a multiplication operation: C = A*B; will lead to a matrix C: C = {{20,7,9}, {5,4,17}}; Having two non-conformable matrices A, 2x3 and B 3x1: A = {{10,7,9}, {5,2,17}}; B = {{1}, {2}, {1}}; a multiplication operation: C = A * B; will lead to a matrix C 2x1: C = {{10*1+7*2+9*1}, {5*1+2*2+17*1}}; The following table summarizes the intrinsic functions available for the management of matrices:

# Function Description 1. MatLen(m); returns the length of the matrix m 2. Min(m,no_of_values); returns the min value of the matrix m for the

first no_of_values 3. Max(m,no_of_values); returns the max value of the matrix m for the

first no_of_values 4. CrossProduct(vec1, vec2); returns the CrossProduct of vector 1 and

vector 2 5. DotProduct(vec1, vec2); finds the dot product of vector 1 and vector 2 6. NormalVec(vec) computes a unit normal vector of input vector

'vec' 7. Normalize(vec); normalizes a vector 8. TransposeMatrix(m) transposes m 9. MaxIndex(m,no_of_values); finds the index of the maximum of an array of

no_of_alues 10. MinIndex(m,no_of_values); finds the index of the minimum of an array of

no_of_values

Page 15: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 15

1.5.2. Maps

map m;

A map data type can be seen as an expansion of the matrix, since the indexing is done with arbitrary values. The keyword that specifies this data type is map. A map is characterized by a name and is like a user defined tree-structure, where each node holds a specific value and is referenced by a specific key: (map_name, key, value) Note that to use a map, you need to initialize it first using the command CreateMap: m = CreateMap();

Set some data in a map: When a map is created and initialized, it is originally blank. To set some data to a specific node on a map, use the SetMapNode: SetMapNode(m, key, value); For example, the command SetMapNode(m, 1140, 1) will assign the value 1 to the node holding the key 1140. An equivalent expression would be: m[1140] = 1; The value of a map can be either a string or a number. However, the key can be a string, a number or even another map. Nodes within the same map are sorted according to their key and the corresponding precedence order is: number > map > string For example, node (m,"1140",1) comes after node (m,1140,2), since the former node uses a string-type key and the latter node uses a numeric key. Note that when maps are used as keys, they are sorted according to the number of nodes they have, with larger maps taking precedence over smaller maps. Retrieve a node value: To retrieve a value of a specific node, the user must provide the corresponding nodal key using the GetMapNode function: i = GetMapNode(m, key); For example, for the node (m,"1140",1), the command i = GetMapNode(m,"1140"); will assign to i the value of 1. An equivalent expression would be: i = m[1140] Delete a node: Deletion of a node within a map is achieved using the EraseMapNode command: EraseMapNode(m, key); Iteration through the data in a map: In order to search through the data of a map, the user must first identify the first or the last node of the map using the GetFirstNode or the GetLastNode commands respectively: i = GetFirstNode(m, key, value); i = GetLastNode(m, key, value); Both functions return 1 on success and 0 upon failure (e.g. when the map is not defined or is empty).

Page 16: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 16

Looping through the map is achieved using the GetNextNode and GetPreviousNode commands: i = GetNextNode(m, key, value); i = GetPreviousNode(m, key, value); Destroy the map and release memory: To delete a map, use the DestroyMap: DestroyMap(m); Identify the number of nodes in a map: To identify how many nodes a map contains, use the GetMapEntries: i = GetMapEntries(m); The following table summarizes the intrinsic functions available for the management of maps:

# Function Description 1 m = CreateMap(); initialize map m 2 SetMapNode(m,key,value); assign a value to the node referenced by key 3 GetMapNode(m,key); retrieve the data of the node referenced by key 4 EraseMapNode(m,key); erase the data of the node referenced by key 5 GetFirstNode(m,key,value); return the first node of the map 6 GetNextNode(m,key,value); forward advance to the next node of the map 7 GetLastNode(m,key,value); return the last node of the map 8 GetPreviousNode(m,key,value); backward advance to the next node of the map 9 DestroyMap(m); delete map and release memory 10 GetMapEntries(m); identify how many nodes the map contains

1.6. Conditional Statements and Branching

1.6.1. The "if-else" blocks and the logical operators The if statement is the basic decision statement of a script. Its operation is based on the evaluation of a condition that will yield a result that is either true or false. If the condition is true (i.e. not equal to 0), then the if-block of statements is executed. If the condition is false, then the else-block of statements is executed. The if statement general form is: if (condition) statement; The alternative line of execution is created with else: if (condition) statement; else statement; Since the condition is interpreted as a logical operator, the operators used for its expression are the logical relational operators. Such operators are summarized in the table below:

# Operator Meaning 1. < less than 2. <= less than or equal to 3. > greater than or equal to 4. >= greater than or equal to 5. == equal to 6. != not equal to 7 || Logical OR 8 && Logical AND

Page 17: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 17

Some examples of the use of the if-else blocks follow:

if (a>5) {

b = 0; c = 0;

}

In this case the logical expression a>5 will be evaluated. If it is proved true, then b and c will be assigned zero values. Otherwise, this block of statements will be ignored.

if (a>5) {

b = 0; c = 0;

} else {

b = 1; c = 1;

}

In this case the logical expression a>5 will be evaluated. If it is proved true, then b and c will be assigned zero values. Otherwise, they will be assigned unit values as dictated by the else group of statements.

if (a>5) b = 0;

In this case the logical expression a>5 will be evaluated. If it is proved true, then b will be assigned zero value. Otherwise, this line will be ignored.

if (a>5) {

b = 0; c = 0;

} else if (a<3) {

b = 1; c = 1;

}

In this case the logical expression a>5 will be evaluated. If it is proved true, then b and c will be assigned zero values. Otherwise, the logical expression a<3 will be evaluated. If it is proved true, then b and c will be assigned unit values. If none of the conditions is fulfilled, the whole block of statements will be ignored.

if(a>5 || b==1) c = 1;

In this case a unit value will be assigned to c only if one of the two expressions is true.

if(a>5) && b==1) c = 1;

In this case a unit value will be assigned to c only if both expressions are true.

1.6.2. The switch statement The switch statement is an alternative form of a conditional statement,which allows the definition of multiple possible execution paths. The general form of the statement is: switch (expression) {

case constant1: statement; .... break; case constant2: statement; /* fall through */ case constant3: statement; .... break; .... default: statement; break;

} The switch statement evaluates the value of an expression and branches to one of the case labels. Duplicate labels are not allowed, so only one case will be selected. The expression can evaluate an integer or a string.The case labels can be in any order and must be constants or strings. The default label can be put anywhere in the switch. Note that two case labels cannot have the same value. When ANSA sees a switch statement, it evaluates the expression and then looks for a matching case label. If none is found, the default label is used. If no default is found, the statement does nothing, i.e.:

Page 18: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 18

a = 2; switch (a) {

case 0: Print("a is zero"); break; case 1: Print("a is one"); break; case 2: Print("a is two"); break; /* will fall through default as well */ default: Print("a is not zero"); break;

} The result is: a is two

1.6.3. The goto statement The goto statement is a powerful branching statement. It can be used to create jumps and redirect the execution order of a program. Its general form is: goto < label > where < label > is the label of an executable statement. i.e. some_label: ... if (a>5) goto some_label;

1.7. Loop statements A loop comprises of a block of statements that are executed repetitively. When the end of the loop is reached, the block is repeated from the start of the loop.

1.7.1. The foreach statement The foreach statement allows the iteration over the elements of an array. foreach loops do not maintain any explicit counter. The general form of the statement is: foreach <item> in <array> {

do something to <item> } An example of the statement use is given below: all_properties = {"PSHELL","PCOMP","PBAR","PBEAM","PELAS"}; foreach property in all_properties Print (property); the result is PSHELL PCOMP PBAR PBEAM PELAS

Page 19: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 19

1.7.2. The for statement The for statement introduces an indexed loop, where the number of repetitions is known before the loop is started. The general form of the for statement is: for (initial-statement; condition; iteration-statement) body-statement; The initial-statement initializes the explicit counter, the condition specifies the number of repetitions and the iteration-statement dictates the increment or decrement value of the explicit counter during the loop. for (a=0; a<5; a++) Print (a); the result is 0 1 2 3 4 Important Note: When a foreach or for loop statement affects only one line then it is not necessary to enclose this line in brackets:

One line is affected

for (a=0; a<5; a++) Print (a);

More lines are affected

for (a=0; a<5; a++) {

Print(a); Print(a+1);

}

1.7.3. The while statement The while statement introduces a conditional exit loop. The program executes the specified statements repetitively for as long as the given condition remains true (i.e. not equal to 0). Its general form is: while (condition) body-statement; If operators are to be used for the expression of the condition, these must be of logical relational type (see Section 1.6.1). a = 0; while (a<3) {

Print(a); a++;

} the above result will be something like 0 1 2

1.7.4. The do while construct While the for and while statements check the condition before entering the loop, the do while construct makes the check after every pass of the loop and thus guarantees that at least one pass will take place. Its general form is:

Page 20: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 20

do body-statement; while (condition); In the example below a = 1; do {

Print (a); a++;

} while (a>5); the result is: 1

1.7.5. The continue and break statements The continue and break statements can be used to redirect the execution order of a loop. The break statement allows the termination of a loop regardless of the loop control condition. In other words it can lead to an unconditional branching. A typical example is given below: a = 0; while (a<5) {

Print(a); a++; if ( a == 3) break;

} In this case the result would be: 0 1 2 The continue statement jumps back to the beginning of the loop’s block to begin the next iteration. Thus, it omits a certain block of statements. A typical example is given below: a = 0; while (a<5) {

a++; if ( a == 3) continue; Print(a);

} In this case the result would be: 1 2 4

1.8. User functions and comments User functions allow to group a set of operations into a compact unit that can be easily and repeatedly accessed. The repetitive use of functions saves much time while reduces the chances of error. Each user function is given a name, optionally uses some input parameters (arguments) and returns the results as output parameters. From now on, the term main will be used to denote the function which is called by the user to execute the script.

Page 21: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 21

1.8.1. Definition User functions are defined using the def statement. This statement is followed by the function name. The rest of the code must be enclosed in brackets: A typical function has the form: def main(list of arguments if exist) {

....... Statement .......

}

1.8.2. Argument list and function call Each user-defined function accepts a number of input arguments (<=40). These arguments are passed from the main function as parameters and are used as initial values inside the function that is called. During the declaration of a sub-function it is necessary to define explicitly the type of the input arguments (int, float, string, element etc) Important note 1: A sub-function can be called from a main function or from another sub-function. Important note 2: Variable number of input arguments is not valid. def main() {

mass = 1.1; id = 10; name = "right_door"; search_type = "GRID"; nodes = CollectEntities(NASTRAN,0,search_type,0); fun_to_call1(mass, name, nodes); fun_to_call2(id);

} def fun_to_call1(float mass, string name, matrix nodes) {

...... counter = 100; fun_to_call3(counter) ......

} def fun_to_call2(int id) {

...... } def fun_to_call3(int counter) {

...... }

1.8.3. Returning data from functions (return, byref call) Since the target of each sub - function is to perform a certain task, there must be a way to “notify” the main function that called it for the result of the procedure it performed. The communication between the functions can be achieved through the return command. This command can be used anywhere in the code and is followed by any data. A function that calls another function can store the returned value in an output argument or even can ignore it. Functions that don’t return anything are executed normally and may not use the return command. Equivalent, they can return a dummy value.

Page 22: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 22

Return value

def main() {

a = 100; b = 50; result= substr(a, b); Print(result);

} def substr(int a, int b) {

res = a-b; return res;

}

No return def main() {

a = 100; b = 50; result = substr(a, b); Print(result);

} def substr(int a, int b) {

res = a-b; }

Return dummy value def main() {

a = 100; b = 50; result = substr(a, b); Print(result);

} def substr(int a, int b) {

res = a-b; return 1;

}

Only the data that are passing through the return command are valid for the main function. Important note: If the return command is used in the main function, then the execution of the script is terminated. Another way of exchanging data is through the byref statement. This is very useful in cases where it is important for the user to know the new modified values of any variables that had been passed to a subfunction. def main() {

w = 10; h = 1; rect_area(w, h); Print(w);//The value of w is 20

} def rect_area(byref int w, int h) {

a = w*h; counter = counter +10; w = w+10;

} Important note: The matrices and maps are considered byref by default

1.8.4. Including Files Scripting language enables the collection of several existing functions into a file. This declaration is made with the include statement. Each line like the one below: #include "fullpath to the name of file" is substituted from the contents of the included file (the quotes are necessary). The include statement must be declared in the global section of the script and is the best way of collecting functions. The use of include has 2 major advantages:

i) The files remain short. ii) Assures that no mistake will be made since no cutting or pasting actions are performed.

#include "/home/work/MinToMax.bs" #include "/home/work/FindNear.bs" def my_fun() {

a[0] = 11; a[1] = 10; a[2] = 3;

Page 23: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 23

MinToMax(a);//MinToMax function has been included in the global section FindNear(); //FindNear function has been included in the global section

}

1.8.5. Scope and lifetime of variables A variable's scope is determined by where you declare it. When a variable is declared within a function, then only the code within this function can access or change its value. It is then said that this variable is local to this function. As a result, there is no conflict to have two or more variables of local character sharing the same name in different functions. In contrast to local variables, global variables are valid throughout the program, so they can be accessed and changed by any individual function of the program. global variables must be declared prior to the definition of any function, and are defined using the global keyword. We can define any number and type of global variables. global offset; def main() {

offset = 1; search_type[0] = "SHELL"; shells = CollectEntities(NASTRAN,0,search_type,0); fun1(shells); offset = offset + 10;

} def fun1(matrix shells) {

foreach shell in shells {

GetEntityCardValues(NASTRAN,shell,"EID",eid); eid = GetInt(eid); new_eid = eid+offset;

} } There is also a third type of variable called static. A static variable can be either external or internal and its major difference from the other two is that it can keep its value even if the execution of the script has come to an end. An internal static variable can be defined in a user function and it is valid only for this function while holds its information regardless of the number of times the function will be called. Similar to this, an external static variable is valid throughout the script where it is defined. Consequently, external static variables help us to “hide” the function names and thus avoid possible conflicts.

Example of internal static variable (1) def main() {

static s; if(!IsInitialized(s)) {

//Iniatializing s s = 0;

} else s = s+1; Print("s value from main:"+s); subfun();

} def subfun() {

Print("s value from subfun:"+s); }

Example of external static variable (2) static s; def main() {

if(!IsInitialized(s)) {

s = 1; } else s = s+1; Print("s value from main:"+s); subfun();

} def subfun() {

Print("s value from subfun:"+s); }

Page 24: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 24

In the first example the value of the variable after each execution will be: Execution 1 ---> s from main = 1, s from subfun = <empty> Execution 2 ---> s from main = 2, s from subfun = <empty> Execution 3 ---> s from main = 3, s from subfun = <empty> etc.... while in the second example: Execution 1 ---> s from main = 3, s from subfun = 3 Execution 2 ---> s from main = 2, s from subfun = 2 Execution 3 ---> s from main = 1, s from subfun = 1 etc.... Suppose that we have loaded two scripts that both use a function called “subfun”. In order to avoid a conflict we define each of the common functions as static.

SCRIPT 1 def main1() {

subfun(); } static def subfun() {

Print("value of script 1: 10"); }

SCRIPT 2 def main2() {

subfun(); } static def subfun() {

Print("value of script 2: 20"); }

After the execution of main1 the result is 'value of script 1: 10' After the execution of main2 the result is 'value of script 1: 20'

1.8.6. Recursive structures Recursive structures are supported through scripting language. This means that a function can call itself as many times as needed. Recursive structures in ANSA have been proved very helpful when trying to search into entities that have a hierarchical structure. A common example is the extraction of all ansa files that exist under a directory tree. def main() { filenames = 0; path = "/home/demo/model"; type = "ansa"; parse_tree(filenames,path,type); } def parse_tree(matrix filenames,string path,string type) { f = FileList(path+"/*"+type); no_of_files = MatLen(f); if(f!=0){ foreach file in f{ filenames[i++] = file; Print(file); } } m = DirList(path); if(m!=0) { foreach d in m{ new_path = path+"/"+d; parse_tree(filenames,new_path,type); } } }

Page 25: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 25

Important Note: Only for the recursive structures the elements (pointers) are considered byref.

1.8.7. Initialization and un-initialization of matrices and variables A well-structured algorithm implies that any variables or matrices that change their values during the execution of a script must be first initialized. The initialization is very crucial especially when a variable is used as counter for filling the indices of a matrix. A variable or a matrix are initialized by assigning to them an initial value (zero value is preferred in most of the cases). To release the memory occupied by variables or matrices, the ReleaseVar function can be used to reset them to “un-initialized” state. This function finds application in cases an existing matrix must be refilled with new data. def main() {

//Initialize counter i i = 0; //Initialize matrix m m = 0; //Define matrix data1 data1 ={10,20,30,40}; len = MatLen(data1); for(k=0;k<len;k++) {

m[i++] = data[k]; } ..... statements ..... data2 ={1,2,3,4}; ReleaseVar(m); len = MatLen(data2); for(k=0;k<len;k++) {

m[i++] = data[k]; } ..... statements .....

}

1.8.8. Use of help text and comments in functions The common practice has proven that even the most experienced programmer needs to keep some comments in order the code to be more readable and understandable. In ANSA scripting language there are two ways to add comments. The first is to use the symbol // which is practical in cases where a single-line comment is needed. For commenting-out a number of subsequent lines use the bounds of a /* comment */. def my_fun() {

//Collect the parts search_type[0] = "ANSAPART"; parts = CollectEntities(NASTRAN,0,search_type,1); /*Use each part as a container in order to collect its faces*/ search_type[0] = "FACE"; k = 0; foreach part in parts {

container[0] = part;//The container must be in a matrix form faces[k++] = CollectEntities(NASTRAN,container,search_type,0);

} } A comment line denoted by // symbol can be incorporated in a comment block (/* comment */).

Page 26: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 26

A script function can also have its own help description. This description is a text that must be enclosed between the symbols ## and must be written always prior to the function which describes. ## Name: NcogToSet Description: Function that adds the Ncog nodes of PAMCRASH rbodies to a set ## def NcogToSet() {

statement } The user script help can be accessed in ANSA through the built in command script_help which is invoked from the command line and through the FUNCTION>RUN function of the SCRIPT menu. Further informations and guidelines regarding loading and running scripts will be discussed in Section 5.

1.8.9. Session commands for use in Scripting Language All session commands can be used within the scripting language as well, following this convention regarding the command syntax: - blank spaces and the ">" symbol in session file commands are substituted by an underscore "_" in ANSA Scripting Language. - the ":" at the end of a session file command is substituted by a parenthesis "( )". All numerical arguments (if any) following the ":" symbol should be included into the paranthesis separated by commas. Non-numerical arguments should also appear within quotes. Examples:

SESSION FILE Syntax SCRIPTING LANGUAGE Syntax TOPO>FACEs>ORIENT: TOPO_FACES_ORIENT(); SAVE AS: filename SAVE_AS("filename"); NEW:DISCARD NEW("discard"); MESH>SHELL MESH>FREE: MESH_SHELL_MESH_FREE();

Page 27: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 27

Section 2 Interacting with ANSA

2.1. General The basic idea behind the scripting language is to automate many repetitive and tedious procedures with the minimum user interaction or even to perform specific tasks that are not covered by the standard ANSA gui commands. Some of the tasks that can be performed within scripting language are the following: 1. Reading and writing ASCII files. 2. Extracting any type of information from an already defined model. 3. Selections that take into account any criteria. 4. Assignment of attributes to parts, materials, properties etc. 5. Use of system commands. 6. Building and executing batch mesh sessions. 7. Creating a model hierarchy. 8. Creating user defined windows and buttons. 9. Co-operating with the MORPH tool for controlling an optimization loop. 10. Use of session commands 11. Running automatically (after launching ANSA) a series of functions. 12. Can be called anytime without reopening a file and as many times as the user wants. 13. Communication with the interface (File Manager functions, Pick functions). All these tasks that can affect the model definition, are controlled through a series of functions that interact with the ANSA interface. Before proceeding to the explanation of individual functions, it is important to emphasize in two basic topics: the treatment of ANSA elements and the meaning of ANSA entities and cards.

2.2. Handling Data

2.2.1. Data of element type As mentioned in section 1, one of the data types that are used within scripting language is the element (The user must not confuse it with the elements of ANSA DECKS). Since the scripting language is C-like, we can say that the meaning of this type is similar to the pointer of the C language. An element (or pointer) either includes all the data held by an entity, which most of the times is the information that is included inside an entity card, or the entity itself. Using this element (pointer), we can access the contents of cards or we can even affect an entity (like translating a part or making a property visible). Some entities that do not have cards in GUI like batch mesh sessions, can be also referenced by elements (pointers).

2.2.2. ANSA cards and entity types Most of the entities in ANSA GUI have an entity card that includes all necessary infromations regarding them. The type of each entity is displayed on the card window header, enclosed in brackets. This entity name is of major importance since this is the keyword that must be used in order to collect the entity itself and to have access in its contents. For example, each NASTRAN "shell" has a card with name SHELL and this is the keyword that must be used for dealing with this type of entity. Exceptions to this rule are the ANSA part and ANSA group, which use different keywords. The labels of card fields are also important since they must be used in order to get their values.

Page 28: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 28

The keywords of the entities that either don't have entity cards or the rule described before doesn’t cover them are the following:

# Entity type Description 1 Ansa part ANSAPART 2 Ansa group ANSAGROUP 3 Batch mesh session BATCH_MESH_SESSION 4 Batch mesh group BATCH_MESH_SESSION_GROUP 5 Spotweld Points SpotweldPoint_Type 6 Spotweld Lines SpotweldLine_Type 7 Adhesive Lines AdhesiveLine_Type 8 Adhesive Faces AdhesiveFace_Type 9 Seam Lines SeamLine_Type 10 Gumdrops GumDrop_Type 11 Hemmings Hemming_Type 12 Bolts Bolt_Type 13 Solid facets SOLIDFACET 14 Continuum shell facets TSHELLFACET

Important Note: The keywords for points and geometric curves are "POINT" and "CURVE" respectively. Keep in mind that all connection entities have cards that are actually hidden. This can been seen if the function EditEntity is called. Finally, the deck curves use a variety of keywords that can be found under the help text of the built in function CreateLoadCurve.

2.3. Collecting entities

2.3.1. General The most significant functions for collecting entities are those that displayed in the following table: Common characteristic of these functions is that they return the elements (pointers) of the entities.

Field keywords

Entity keyword

Page 29: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 29

The types of entities that can be collected using these functions are: ELEMENTs (SHELLs, SOLIDs, BEAMs, etc) COORDINATE SYSTEMs CONSTRAINTs LOADs CONDITIONs (intial or boundary) BOXes SETs GRIDs ANSAPARTs ANSAGROUPs CONNECTIONs (all types) POINTs CURVEs PROPERTIEs MATERIALs INCLUDEs CONNECTORs GEBs Important note: The GetEntity function cannot collect ANSAPARTS and ANSAGROUPS of PART MANAGER In any of these functions where the "type" of an entity is required, the first argument is an integer that refers to the DECK for which we require the entity type. These integers are given internally to ANSA and the user needs only to type the corresponding DECK name: NASTRAN LSDYNA PAMCRASH ABAQUS RADIOSS ANSYS Important note: If zero value is given instead of the deck name, then the current deck will be taken into account.

2.3.2. Collecting entities massively from the whole database For collecting massively a type of entity (e.g. SHELL) the appropriate function is the CollectEntities. One of the advantages of this function is that it can be used for finding entities that are used by other entities while it is the only function that can collect visible entities. Its syntax is very flexible and can accept either matrices or single elements (pointers). A variable number of input arguments can be specified as well. Let's see the capabilities of the CollectEntities function with some examples.

# Function Description1 CollectEntities Collect entities massively 2 GetEntity Get a single entity 3 GetFirstEntity Get the first entity according to its id 4 GetNextEntity Get the next entity according to its id 5 GetPartFromModuleId Get PARTs or GROUPs 6 Name2Ents Get entities from their name 7 CollectNewModelEntitiesStart Start collection monitor for new

entities created or imported to the model. 8 ReportNewModelEntities Report entities gathered since the

previous matching call to the CollectNewModelEntitiesStart function

9 CollectNewModelEntitiesEnd End collection monitor for new entities created or imported to the model

10 TypesInCategory Collect types of entites that exist in model

Page 30: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 30

def main() {

/*Define into a matrix the keywords of entities that you want to collect. These keywords are taken from the title of their cards*/ search_type[0] = "PSHELL"; search_type[1] = "PSOLID"; ents = CollectEntities(NASTRAN,0,search_type,0);

}

In this approach the input arguments are matrices. The second argument indicates the search domain and in case the user needs to collect entities from the whole database it must be zero. The output argument is a matrix that contains the elements (pointers) of PSHELLs and PSOLIDs of the database. The definition of the deck must be compatible with the entities that are going to be collected. An approach like the following is not accepted: search_type[0] = "PSHELL"; search_type[1] = "PSOLID"; ents = CollectEntities(PAMCRASH,0,search_type,0); In this case the equivalent keywords for PAMCRASH deck are PART_SHELL and PART_SOLID.

2.3.3. Collecting entities massively from other entities In this case we would like to collect the GRIDs that are used from SHELLs. In scripting language terminology, the matrix of shells is considered as a container and must be given as a second argument in order to prompt the function to search only into the collected shells. A container can be either a matrix or a single element (pointer). def main() {

//Collect first the shells of the whole database search_type[0] = "SHELL"; shells = CollectEntities(NASTRAN,0,search_type,0); //Collect the grids of the shells search_grid[0] = "GRID"; grids = CollectEntities(NASTRAN,shells,search_grid,0);

} Instead of matrices in this case we could have used directly the keyword of the entity (as string). def main() {

//Collect first the shells of the whole database shells = CollectEntities(NASTRAN,0,"SHELL",0); //Collect the grids of the shells grids = CollectEntities(NASTRAN,shells,"GRID",0);

} The third argument that defines the types of entities that we are looking for can be also set to zero. This setting can be used for gathering all the entities that are included into a superior entity. This makes sense in SETs and PARTs. def main() {

//Collect the sets of the database sets = CollectEntities(NASTRAN,0,"SET"); //Collect all the entities that belong to these sets ents = CollectEntities(NASTRAN,sets,0);

} Attention must be given in the meaning of containers. Many entities in ANSA are considered as containers since they include other entities inside them e.g SHELLs include GRIDs. These containers are classified according to their level. For instance, SHELLs are of higher level than GRIDs while PSHELLs are of higher level than SHELLs and GRIDs. So, if we want to search for entities inside a container we

Page 31: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 31

can instruct the CollectEntities to search recursively until the lower level. This is very clear in the following examples. def main() {

pshells = CollectEntities(NASTRAN,0,"PSHELL",0); shells = CollectEntities(NASTRAN,pshells,"SHELL",0); Print(MatLen(shells));

} The last argument of CollectEntities is zero since SHELLs is only one level under PSHELLs. Another equivalent syntax could be: shells = CollectEntities(NASTRAN,pshells,"SHELL","recursive","no"); For finding directly the GRIDs that are used by PSHELLs, we have to invoke the function to search recursively until the lowest level. In this case the last argument takes the value 1. def main() {

pshells = CollectEntities(NASTRAN,0,"PSHELL",0); grids = CollectEntities(NASTRAN,pshells,"GRID",1); Print(MatLen(grids));

} Similarly we could have written: grids = CollectEntities(NASTRAN,pshells,"GRID","recursive","yes"); A matrix that contains entities of specific type cannot be used as container for collecting entities of the same type. This is more clear with the following example: Suppose that we have a matrix that contains elements (pointers) of SHELLs and SOLIDs. In this case the CollectEntities will not work if we define as search type either SHELLs or SOLIDs. It will work only if we search for GRIDs. Important Note: The matrix of elements (pointers) that is returned is not sorted according to the ids of the entities that they reference.

2.3.4. Collecting massively visible entities CollectEntities is the only script function capable of collecting visible entities. def main() {

grids = CollectEntities(NASTRAN,0,"SHELL","filter_visible","yes"); Print(MatLen(grids));

} Important Note: Visible are considered all entities that their visibility is controlled through F12. The only excection are the FACEs

2.3.5. Collecting available entity types of specific deck As we saw in paragraphs 2.3.2, 2.3.4, and 2.3.5, the CollectEntities function needs to know what types of entities to search for. In simple cases where specific types are needed, the user just have to open the respective card and see what string to use as keyword. For more complicated cases where the entities that we search for are not well known or they are too many to open their cards one by one, the use of the function TypesInCategory is more than necessary. The function uses two input arguments which are the name of the deck and a string that defines the searching area. The ouput is a matrix with all supported types. The searching area string can get the following forms: "__MATERIALS__": for getting all available material types of the specified deck "__PROPERTIES__": for getting all available property types of the specified deck "__ELEMENTS__": for getting all available element types of the specified deck "__VISIBLE__": for getting all types of entities of the specified deck, that their visibility can be controlled through the F12 key

Page 32: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 32

"__ALL_ENTITIES__": for getting all supported entities of the specified deck As an example we would like to identify which LSDYNA materials exist in the database. The supported materials in this deck are too many (>100) and therefore the TypesInCatecory will help to identify them very quickly: def MatsOfDynaInModel() {

//Get all supported material types of LSDYNA all_mats = TypesInCategory(LSDYNA,"__MATERIALS__"); /*Collect the database materials using as search matrix the one that the TypesInCategory returned*/ used_mats = CollectEntities(LSDYNA,0,all_mats,0); foreach used_mat in used_mats

Print(GetEntityType(LSDYNA,used_mat)); }

2.3.6. Get single entities For getting only a single element (pointer) of an entity, the functions GetEntity ,GetFirstEnity, GetNextEntity are available. The use of GetEntity presupposes that the type and the id of the entity is known. It returns the element (pointer) of the entity. def GetSingleEnt() {

group = GetEntity(PAMCRASH,"GROUP",100); } In this example we got the element (pointer) of the Pam-Crash GROUP with id 100. Keep in mind that we cannot use this function for collecting ANSAPARTs and ANSAGROUPs. For getting the elements of an entity sorted according to their ids, the GetFirstEnity and GetNextEntity functions must be used. def main() {

i = 0;//Initialize counter i for(ent=GetFirstEntity(NASTRAN,"SHELL");ent;ent=GetNextEntity(NASTRAN,ent)) {

shells[i++] = ent; }

} The entries of the matrix shells are sorted according to the ids of the shells that they reference. The GetFirstEnity can be used alone in case it is known that the database contains only one entity of specific type and with unknown id.

2.3.7. Collecting part and groups from their ids For collecting single ANSAPARTs and ANSAGROUPs that have known ids (Module Ids) the GetPartFromModuleId can be used. Suppose we want to get the elements (pointers) of the PART with Module id "1A" and of the GROUP with module id "100". def main() {

part = GetPartFromModuleId("1A"); group = GetPartFromModuleId("100");

}

2.3.8. Collecting entities according to their name Apart from using ids, names can be also used as searching pattern for collecting any type of entities. The function for this is the Name2Ents. It takes just one argument while it accepts the Perl regular

Page 33: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 33

expressions. It returns a matrix with all the elements whose name fulfils the searching filter. This function is used mosly in combination with the GetEntityType in order to distinguish the type of entities. Suppose that we would like to search in whole database for PSHELLs and PSOLIDs whose name starts with "Default" and to store them in 2 different matrices. def main() {

//Collect entities that satisfy the searching pattern ents = Name2Ents("^Default.*"); //Initialize counters count_pshell = 0; count_psolid = 0; foreach ent in ents {

type = GetEntityType(ent); //Distinguish the type of entity if(type=="PSHELL") pshells[count_pshell++] = ent; if(type=="PSOLID") pshells[count_psolid++] = ent;

} } If no entities are found the function returns nothing. This case can be identified using the "!" operator. ents = Name2Ents("^Default.*"); if(!ents) Print("No entities were found");

2.3.9. Collecting all new created/imported entities During the execution of scripts, there are times where we import files, merge databases or read connection files. All these actions affect significantly the process since the amount of entities in the current database is increased and thus we may need to know exactly which are the new entities. A combination of functions must be used in order to recognize all the changes of the model. First, it is important to set a starting point for collecting anything new. The CollectNewModelEntitiesStart when called starts monitoring all the actions in the database and in case a new entity is identified it is stored in a container, which is declared as output argument. Monitoring stops implicitly when the function CollectNewModelEntitiesEnd is called. The collected entities are accessed through the ReportNewModelEntities, which is used always between the two aforementioned functions. The container is used as input and as result it returns a matrix of the entities. def main() {

container = CollectNewModelEntitiesStart(); InputAbaqus("./"+abaqus_model_name, "nooffset", "nooffset", "nooffset",

"nooffset","", "", "", "", "", "on"); ReadConnections("XML","/home/work/connections.xml"); new_entities = ReportNewModelEntities( container ); CollectNewModelEntitiesEnd(container); foreach new_entity in new_entities {

Print(GetEntityType(ABAQUS, new_entity)); }

}

2.3.10. Collecting a number of files or directories into a list For collecting efficiently a number of files (of specific formats) or directories, the commands FileList and DirList must be used. Actually, these functions return a matrix with all the paths that were identified. Then, these paths can be passed as strings in other functions. Important Note: When it is needed to identify all directory hierarchy it is recommended to use the DirList recursively. A typical example where we can use these functions is when we want to merge a number of ANSA files that exist in many directories: Suppose that all the files exist under 5 directories which are located under a folder named 'my_project'. A simple code should be like the following:

Page 34: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 34

def main() {

//Get the 5 directories and store the paths into the matrix "dirs". dirs = DirList("/home/work/my_project/"); //Loop through the directories foreach dir in dirs {

//Find only the ANSA files that exist under each directory ansa_files = FileList("/home/work/my_project/"+dir, "/*.ansa"); //Loop through the ANSA files foreach file in ansa_files {

//Merge with the default options MERGE(file,"","","","","","","","");

} } //Save in one database SAVE_AS("merged.ansa");

}

2.3.11. Select files or directories with the aid of the File Manager Scripting language interacts directly with the File Manager through the commands SelectOpenDir, SelectSaveDir, SelectOpenFile, SelectSaveFile. This means that these functions open the File Manager and allow the selection or creation of files and directories. This is an elegant way to use file and directory paths in user scripts, since it enables the interactive definition of script parameters. The functions that deal with files return a matrix containing strings that represent the full path to the selected files, while those for directories return a string indicating the full path to the folder. def Selection() {

Print("Select the file for reading"); read_file = SelectOpenFile(0, "csv files (*.csv)"); /*The matrix 'read_file' contains only one entry since the the first argument of 'SelectOpenFile' was 0 */ Print("The file that was selected is: "+read_file[0]); Print("Select the log file for writing the error messages"); save_file = SelectSaveFile(); Print("The file that was selected for writing errors is: "+save_file); Print("Select the directory where the ANSA files are located"); dir = SelectOpenDir(""); Print("The selected directory is: "+dir);

} If nothing is selected it can be identified using the “!” operator. read_file = SelectOpenFile(0, "csv files (*.csv)"); if(!read_file) {

Print("No file was selected"); } or dir = SelectOpenDir(""); if(!dir) {

Print("No directory was selected"); }

Page 35: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 35

2.4. Edit, Create and Delete Entities

2.4.1. General Once the entities have been collected, next step is to edit, modify or delete some of them. The functions that are used very often for this purpose are:

# Function Description 1 GetEntityCardValues Get values from a card 2 SetEntityCardValues Set values to a card 3 CreateEntityVa Creates a new entity 4 CreateConnectionPoint Creates a connection point 5 CreateConnectionLine Create a connection line 6 CreateConnectionFace Create a connection face 7 RealizeConnections Realize connections 8 DeleteEntity Delete an entity 9 NewPart Creates new parts 10 NewGroup Creates new groups

2.4.2. Get values from an entity using its Edit card The only function that enables the access into the fields of an edit card without changing the contents , is the GetEntityCardValues. It always follows functions that had collected a number of entities in a prior step and its arguments are pairs of labels – values. These labels are the keywords of the fields as they appear in the edit card (See section 2.2.2). The definition of the deck and element are mandatory. Let's see how we can get the values of the name, thickness, property id and material id of all the SECTION_SHELL cards of LSDYNA deck:

Page 36: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 36

def GetValues() {

props = CollectEntities(LSDYNA,0,"SECTION_SHELL",0); //Initialize counters count_name = 0; count_thick = 0; count_pid = 0; count_mid = 0; foreach prop in props {

GetEntityCardValues(LSDYNA,prop,"Name",name,"PID",pid,"MID",mid,"T1",t; names[count_name++] = name; thickness[count_thick++] = t; pids[count_pid++] = pid; mids[count_mid++] = mid;

} ..... statement

} It is obvious that the user must be familiar with the labels of each edit card since they must be written exactly as they appear in the cards. The output value of the function is equal to the number of occurrences that were not found due to an improper definition of a keyword. status = GetEntityCardValues(LSDYNA,prop,"Name",name,"PID",pid,"MID",mid,"T",t); The status variable will be 1 since the thickness field label is wrong ("T" instead of "T1"). For avoiding opening and closing cards only for seeing the names of the labels, three global label – keywords have been introduced in v12.1.2. The benefit is that we can extract the entity's id, property and type without knowing the actual name of their labels. Their syntax is the following: __id__ for entity's ID __type__ for entity's ANSA type __prop__ for entity's property id A very common case is when we must extract the id and the property id from a shell. Independently from the deck we can write: status = GetEntityCardValues(LSDYNA,prop,"__id__",id,"__prop__",pid);

2.4.3. Modifying the card's values The contents of a card can be modified with the SetEntityCardValues function, which works similarly to the GetEntityCardValues. Again, a pair of labels – values must be declared. In the following example we will change the id and thickness of a specific property. def SetValues() {

//Get the PART_SHELL property with id 10 prop = GetEntity(PAMCRASH,"PART_SHELL",10); //Set the new values for id and thickness. SetEntityCardValues(PAMCRASH,prop,"IDPRT",1000,"h",1.75);

} If a keyword is given wrong, the function will not work even if all the other keywords had been defined correctly. In this case the function will return the number of wrong occurrences. status = SetEntityCardValues(PAMCRASH,prop,"IDPRT",1000,"h1",1.75); Although the 'IDPRT' is correct, the function will not work because of the 'h1' label and therefore will return status = 1. Important note: The global labels ( __id__ ,__prop__ ,__type__ ) are also valid.

Page 37: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 37

2.4.4. Creating new entities Scripting language can also be used to create new entities like nodes, properties, materials etc. The function that can be used for this purpose is the CreateEntityVa. It is necessary to declare the entity type keyword ( Section 2.2.2 ) and pairs of labels – values. It returns the element of the newly created entity. Suppose that we have a text file with ids and coordinates of grids that we want to create: The form of the file is like the following 82310, 1678.969971 , -710.023010 , 822.325989 82290, 1672.699951 , -710.539978 , 821.093018 ...... def CreateGrids() {

//Open file for reading fd = Fopen("filepath to the grid file","r"); //Read the file while(Read(fd,line)) {

m = TokenizeString(line,",",0); id = GetInt(m[0]); xcoord = GetFloat(m[1]); ycoord = GetFloat(m[2]); zcoord = GetFloat(m[3]); CreateEntityVa(NASTRAN,"GRID","NID",id,"X1",xcoord,"X2",ycoord,"X3",zcoord);

} Fclose(fr);

} During the creation of an entity, all the fields that are necessary for its definition but were not specified by the user (e.g. the id) are automatically filled by ANSA. Important Note: Not all entities of ANSA can be created with the CreateEntityVa.

2.4.5 Creating parts and groups For creating ANSA parts and ANSA groups the functions NewPart and NewGroup must be used. Both accept a name and optionally an id and return the element (pointer) of the newly created part/group. def main() {

//Create a part with name 'door' and id 10 part = NewPart("door","10"); //Create a group with name 'side' and without id group = NewGroup("side","");

}

2.4.6 Creating connection entities For the creation of connection entities (points, lines, faces) the functions CreateConnectionPoint, CreateConnectionLine and CreateConnectionFace can be used. Except from the definition of the type and id, the rest information that is needed to succefsfully define a connection entity, like the position of the point and the parts that will be connected, must be given in a matrix form. Also, the id of the connection can be given explicitly from the user or can be defined from ANSA by giving a zero as second argument. The function returns the element (pointer) of the created connection entity in order to be used later in the realization function. In the example that will follow a spotweld point and a adhesive line will be created:

Page 38: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 38

def CreateCnctEnts {

//create a spotweld point of ID 122 at (2.3, 3.0, -1.0) xyz[0] = 2.3; xyz[1] = 3.0; xyz[2] = -1.0; /* part ids that will be connected*/ part_ids_point[0] = 1; part_ids_point[1] = "bp_416"; part_ids_point[2] = "4"; cnctn_p = CreateConnectionPoint("SpotweldPoint_Type", 122, xyz, 3, part_ids_point, 3); //create an adhesive line of arbitrary ID curves[0] = GetEntity(NASTRAN, "CURVE",15); /* part ids that will be connected*/ part_ids_curve[0] = 2; part_ids_curve[1] = 3; cnctn_c = CreateConnectionLine("AdhesiveLine_Type", 0, curves, 1, part_ids_curve, 2); SetEntityCardValues(NASTRAN,cnctn_c, "W",1);

} As you noticed, the length of each matrix must follow the matrix itself, e.g: xyz, 3 part_ids_point, 3 curves, 1 part_ids_curve, 2 Great attention must be given in the first argument of all three functions since this string indicates the type of the entity that will be created. The correct syntax of it can be found only in the connection section of ANSA.defaults and it can be one of the following: SpotweldPoint_Type Bolt_Type GumDrop_Type SpotweldLine_Type AdhesiveLine_Type SeamLine_Type Hemming_Type AdhesiveFace_Type

2.4.7 Editing the characteristics of a connection entity The basic informations that follow a connection entity like its ID, or the ids and pids of connected parts etc can be exported or edited through the GetEntityCardValues and SetEntityCardValues. The strings for getting all these characteristics are: "ID" for connection id "X" for x coordinate "Y" for y coordinate "Z" for z coordinate "D" for diameter "S" for S "M" for M "W" for W "H" for H "P1" for part/property 1 "P2" for part/property 2 "P3" for part/property 3 "P4" for part/property 4 "Status" for Status "Error Class" for Error class "Name" for name "Comment" for comment

Page 39: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 39

e.g: ... connections = CollectEntities(NASTRAN,0,"SpotweldPoint_Type",0); foreach connection in connections {

GetEntityCardvalues(NASTRAN,connection,"ID",id,"X",x,"Y",y,"Z",z,"P1",p1, "P2",p2,"P3",p3,"P4",p4);

Print("ID "+id+" x:"+x+" y:"+y+" z:"+z); } ... or connections = CollectEntities(NASTRAN,0,"AdhesiveLine_Type",0); foreach connection in connections {

SetEntityCardvalues(NASTRAN,connection,"W",1); } ...

2.4.8 Realizing connections After creating the connection enities, the user have to realize them using the functions RealizeConnection (for one entity) or RealizeConnections (for any number of entities). All the representation characteristics that appear in the GUI are fully supported within these functions using a specific name convention that is taken from ANSA.defaults. The number of input arguments is variable and whatever is not defined takes a default value from ANSA.defaults. As an example, the strings that can be used for spotweld representations are: # Default Page for Spotweld Points # format : RBE2|RBAR|CBAR|CBEAM|CELAS2|RBE2-CELAS1-RBE2| # PASTED NODES|CBUSH|DYNA SPOT WELD|PAM SPOT WELD| # NASTRAN CWELD|PAM PLINK|RBE3-HEXA-RBE3|AUTO SP2| # RBE3-CBUSH-RBE3|SPIDER|RADIOSS WELD| # ABAQUS FASTENER|SPIDER2|RBE3-CELAS1-RBE3| # RBE3-CBAR-RBE3|RBE3-CBEAM-RBE3|PERMAS SPOTWELD # SpotweldPoint_Type = RBE2 while the strings for individual representation settings are: # Connection Manager Values # SpotweldPoint_SPIDER_SearchDist = 5.000000 # SpotweldPoint_SPIDER_RBE2_PinFlags = 123456 # SpotweldPoint_SPIDER_ProjectToPerim = y # SpotweldPoint_SPIDER_PointsAroundHole = 8 # SpotweldPoint_SPIDER_ParallelToPerim = y # SpotweldPoint_SPIDER_PBAR_ID = # SpotweldPoint_SPIDER_KeepSamePID = n # SpotweldPoint_SPIDER_ForceZeroGap = n # SpotweldPoint_SPIDER_DoNotMove = y # SpotweldPoint_SPIDER_DoNotCreateCoord = n # SpotweldPoint_SPIDER_DistanceFromPerimeter = 3.000000 # SpotweldPoint_SPIDER_DiSize_Index = 1 # SpotweldPoint_SPIDER_DiSize = 3.000000 # SpotweldPoint_SPIDER_CreateRBE2 = y # SpotweldPoint_SPIDER_CBAR_PinFlags = 0 # SpotweldPoint_SPIDER2_Zone2_Index = 2 # SpotweldPoint_SPIDER2_Zone2 = 0.000000 # SpotweldPoint_SPIDER2_Zone1_Index = 2 # SpotweldPoint_SPIDER2_Zone1 = 0.250000 # SpotweldPoint_SPIDER2_SearchDist = 5.000000 # SpotweldPoint_SPIDER2_RBE2PinFlags = 1235 # SpotweldPoint_SPIDER2_PointsAroundHole = 8

Page 40: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 40

# SpotweldPoint_SPIDER2_ParallelZones = n # SpotweldPoint_SPIDER2_PBAR_ID = # SpotweldPoint_SPIDER2_ForceZeroGap = n # SpotweldPoint_SPIDER2_DoNotMove = y # SpotweldPoint_SPIDER2_CBARPinFlags = 0 # SpotweldPoint_RBE3-HEXA-RBE3_UseThicknessAsHeight = n # SpotweldPoint_RBE3-HEXA-RBE3_SpecifyHeight = n # SpotweldPoint_RBE3-HEXA-RBE3_SeparateRefCPinflags = n # SpotweldPoint_RBE3-HEXA-RBE3_SearchDist = # SpotweldPoint_RBE3-HEXA-RBE3_RefCPinFlags = 123 # SpotweldPoint_RBE3-HEXA-RBE3_PinFlags = 123 # SpotweldPoint_RBE3-HEXA-RBE3_PSOLID_ID = # SpotweldPoint_RBE3-HEXA-RBE3_Height = # SpotweldPoint_RBE3-HEXA-RBE3_ForceOrthoSolids = n # SpotweldPoint_RBE3-HEXA-RBE3_FailIfAspect = 0.000000 # SpotweldPoint_RBE3-HEXA-RBE3_DoNotMove = y # SpotweldPoint_RBE3-HEXA-RBE3_AreaScaleFactor = 0.000000 ..... # SpotweldPoint_AUTO-SP2_BoxSize = 6.000000 # SpotweldPoint_ABAQUS_FASTENER_UseThicknessToDiameterMap = y # SpotweldPoint_ABAQUS_FASTENER_UseConnector = n # SpotweldPoint_ABAQUS_FASTENER_SearchDist = # SpotweldPoint_ABAQUS_FASTENER_FASTENER_PID = 0 # SpotweldPoint_ABAQUS_FASTENER_CONNECTOR_PID = 0 In the example that will follow we want to realize the spotweld points into NASTRAN WELDs with option ELPAT and specific PWELD id and the adhesive lines in RBE3-HEXA-RBE3 with 2 stripes, specific PSOLID id and the option “Force Ortho Solids” activated. We will use the RealizeConnections which is faster than the RealizeConnection since realizes massively. def RealizeAllCncts() {

//Collect the spotwelds of the database spots = CollectEntities(NASTRAN,0,"SpotweldPoint_Type",0); //Collect the adhesive lines of the database adh_lines = CollectEntities(NASTRAN, 0,"AdhesiveLine_Type",0); //Number of connection points no_spots = MatLen(spots); //Number of adhesive lines no_lines = MatLen(adh_lines); //Realize the spotwelds RealizeConnections(spots,no_spots,"SpotweldPoint_Type","NASTRAN CWELD", "SpotweldPoint_NASTRAN-CWELD_WeldType",2, "SpotweldPoint_NASTRAN-CWELD_SearchDist", 10, "SpotweldPoint_NASTRAN-CWELD_PWELD_ID",1000); //Realize the adhesive lines RealizeConnections(adh_lines,no_lines,"AdhesiveLine_RBE3_HEXA_RBE3_SearchDist",10, "AdhesiveLine_RBE3_HEXA_RBE3_NumOfStripes",2, "AdhesiveLine_RBE3_HEXA_RBE3_ForceOrthoSolids","y", "AdhesiveLine_RBE3_HEXA_RBE3_PSOLID_ID",2000);

} Some notes here are necessary: 1. The order of settings doesn’t affect the final result. 2. The value of a setting must always follow the setting, eg: - "SpotweldPoint_NASTRAN-CWELD_WeldType",2 is correct - 2, "SpotweldPoint_NASTRAN-CWELD_WeldType" is wrong 3. If the name of the representation is omited, then the default will be created like in case of the adhesive line. 4. The only alphanumeric characters that are used are the ‘y’ and ‘n’ indicating yes or no respectively. These arguments must be given as strings, e.g "AdhesiveLine_RBE3_HEXA_RBE3_ForceOrthoSolids","y" 5. Options available in GUI as drop down menus are given with their sequence order, e.g:

Page 41: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 41

"SpotweldPoint_NASTRAN-CWELD_WeldType",2, since "ELPAT" option is second in the drop down menu of connection manager. 6. After the realization, all the settings that were used are passed to connection manager and can be easily viewed.

2.4.9 Getting the entities of connections The elements that paticipate into a connection entity can be retrieved through the functions GetFirstFeRep, GetNextFeRep. The way that we can use them is through a loop that will going to search recursively for all elements. The input for the former one must be always the connection element while for the latter the connection element and the last found entity. Suppose that we have to realize all spotweld points in RBE3-HEXA-RBE3 representation and to print in the text window the ids of RBE3s and HEXAs that belong to each connection point def CheckRBE3_HEXA_RBE3() {

//Collects all Spotwelds. concts = CollectEntities(NASTRAN,0, "SpotweldPoint_Type",0); foreach cnctn in concts {

GetEntityCardValues(NASTRAN,cnctn,"X",x,"Y",y,"Z",z, "P1",p[0],"P2",p[1],"P3",p[2],"P4",p[3], "Status",status,"ID",cid,"Error Class",eclass); i=0; //Initialize j=0;//Initialize if(eclass=="RBE3-HEXA-RBE3") {

//Loops through the Entities of each Spotwelds for(ent=GetFirstFeRep(cnctn);ent;ent=GetNextFeRep(cnctn,ent)) {

type=GetEntityType(NASTRAN,ent); if(type=="RBE3") {

GetEntityCardValues(NASTRAN,ent,"EID",eid); if(i==0) {

no_of_rbe = eid; i = 1;

} else

no_of_rbe=no_of_rbe+","+eid; } if(type=="SOLID") {

Page 42: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 42

GetEntityCardValues(NASTRAN,ent,"EID",eid); if(j==0) {

no_of_solids = eid; j = 1;

} else

no_of_solids = no_of_solids+","+eid; }

} Print("Connection with cid "+cid+" has RBE3s with ids:"+no_of_rbe+" and SOLIDs with ids:"+no_of_solids); no_of_rbe=0; no_of_solids=0;

} }

Print("Done"); } Important note : The GetFirstFeRep, GetNextFeRep functions can be used in all types of connection entities:

2.4.10. Deleting entities Unnessecery entiites can be deleted using the DeleteEntity function. It can delete either a single entity or a number of entities at once. The function accepts a single element (pointer) of an entity or a matrix of elements (pointers). Suppose that all unused nodes must be deleted. def DeleteNodes() {

nodes = CheckFree("all"); DeleteEntity(nodes,0);

} The second argument is a force flag. Use 1 to delete entities and any references to these entities. For example the force flag for deleting PSHELLs properties must be 1 since there are shells that use this property. After the execution of DeleteEntity the property itself and the shells / grids that are associated with it will be deleted. Important Note: To significantly reduce execution time, it is highly recommended to delete entities massively instead one at a time.

2.5. Creating user defined buttons and custom GUI

2.5.1. General ANSA scripting language enables the creation of user defined buttons and fully customized graphical interfaces. The buttons that can be created are similar to the buttons of the GUI and are used to invoke user functions. They are placed always under TOOLS>USER MENU. Additionally, for the management of specific tasks that must be controlled through a number of definitions and actions, it is very useful to create our own custom GUI. This GUI can handle check buttons, radio buttons, menu buttons, lists, tables etc. and can be called anytime during the process like any other script function.

2.5.2. Creation of user buttons using the AddUserButton function The AddUserButton function is used for the creation of buttons. Its syntax needs 3 arguments which are the name of the button, the name of the function that will be called and the button’s position in the USER MENU window. In the following example a button with name "Test Button" will be created and each time it will be pressed the function "test" will be executed. def ButtonTest() {

AddUserButton("Test Button","test",1); }

Page 43: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 43

def test() {

Print("ANSA"); } Once the function "ButtonTest" is called, a button is created under TOOLS>USER MENU.

Important Note: If a zero value is given as third argument, then ANSA will place the button in the first available position.

2.5.3. Creation of custom GUI One of the most advanced capabilities of scripting language is the creation of user-defined graphical user interfaces. A GUI is defined through a series of matrices. The format of each matrix is specific and basically contains information regarding the attributes of controls (caption, position, size), a reference name for handling the control and optionally the name of the function (Callback) that will be called with the control activation. Each control is defined in a separate matrix while all these matrices are parts of a total matrix. A typical syntax of a control matrix is the following: id type x y w h caption reference Callback name {100, "EDIT",10,10,100,100, "Text" , "edittxt", "onEditChange"}; where 'x' and 'y' correspond to control position and 'w' and 'h' are the width and height respectively. The available control types are: 1. EDIT → Creates edit fields 2. RADIO → Creates radio buttons 3. CHECK → Creates check buttons 4. BUTTON → Creates simple and menu buttons 5. LABEL → Creates labels 6. LIST_BOX → Creates lists 7. TABLE → Creates tables 8. LIST_VIEW → Creates list views These matrices compose a total matrix that will be used as basis for the final window description. controls = { { 10,"LABEL", 10, 10, 290, 21, "User defined buttons", "labeltop"}, { 20,"BUTTON", 40, 60, 130, 41, "My Button 1", "button_LT", "LT_btn"}, { 30,"BUTTON", 170, 60, 130, 41, "My Button 2", "button_RT", "RT_btn"}, { 1,"BUTTON", 30, 150, 91, 41, "OK", "okbtn"}, { 2,"BUTTON", 190, 150, 91, 41, "CANCEL", "cancelbtn"} }; Finally, an additional matrix must be created for the overall window. Its definition is different from the control matrix and is like the one below: id x y w h length of total control total control Window name matrix matrix dialog = {100, 0, 0, 330, 208, MatLen( controls ), controls, "Buttons Demo"}; Notice that x and y are set to zero. In this case the window will be placed in a default position.

Page 44: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 44

Since all necessary matrices were created, the function CreateWindow must be called in order to create the window. This function needs a reference name and the window matrix. win = CreateWindow ("Win1", dialog); Important Note: The CreateWindow function creates a window but it doesn't open it.

2.5.4. Setting Cancel and Ok buttons Almost all types of user-defined windows need an OK and a CANCEL button. The functions SetOkButton and SetCancelButton are used in order to give to these special buttons their known characteristics. Their syntax needs the window reference name and the control reference name of each button. SetOkButton ("Win1", "okbtn"); SetCancelButton ("Win1", "cancelbtn");

2.5.5. Opening and Destroying Windows After creating the window and setting the default values of the controls, the user interface is ready to open. The OpenWindow function opens the window using its reference name: res = OpenWindow ("Win1"); The output takes a value that corresponds to the pressed button, thus can be very helpful for any actions that follow its activation. Every code that creates windows must end with the function DestroyWindow. This function destroys a window that was created by a call to CreateWindow. It is used to free the internal memory of the windowing system, when you no longer need the window. DestroyWindow("Win1"); In the end the GUI should look like the following:

2.5.6. Callback functions A callback function is a separate routine that is called every time a control is activated. Its name is defined in a control matrix (See 2.5.4). There are certain arguments required for its definition. In most cases these are the window reference name, the control reference name and the control result. controls = { ... { 20,"BUTTON",40,60,120,41,"My Button 1","button_LT","LT_btn"}, ... } def LT_btn (string window_name, string control_name) {

Print ("Button 1 was pressed"); }

Page 45: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 45

In the above example the callback 'LT_btn' doesn't have a third argument because a BUTTON is a control whose result is taken through the OpenWindow function. Callbacks that are carried from other controls must have 3 arguments. controls = { ... {101, "EDIT", 50,45,310,20, "text", "edittxt","onEditChange"}, ... }; def onEditChange(string window_name, string edt_name, string txt) {

Print("window:"+window_name +", edit_box:"+edt_name +", text:"+txt); }

2.6. Setting of controls The code between the CreateWindow and OpenWindow statements is used for an initial set up of any type of control. Usually, the setting of a control needs additional definitions of matrices, like in cases of menus and tables, but there are also cases where a simple call to a function is enough like in edit fields and check buttons.

2.6.1. Setting edit fields and check buttons An edit field can be set up using the functions StringSet, IntSet, FloatSet, which assign a string, integer and float respectively. All of them take three input arguments, which are the window name, the internal reference name of the control and the value: controls = { {1, "EDIT",50,45,310,20, "text", "ref_name"}, ... } CreateWindow("Win2", dialog); IntSet("Win1", "ref_name", 1); // FloatSet("Win1", "ref_name", 1.34); // StringSet("Win1", "ref_name", "none"); OpenWindow("Win1"); In case none of this function is called, the initial value will be the one defined in the control matrix The function for setting the state of a check box is the SetCheckButton. The first two arguments are the window name and the internal reference name of the control, while the third is an integer that takes zero value for unchecked state and 1 for checked state.

2.6.2. Creating and setting up menus and radio buttons Special attention must be given in the creation of menus and radio buttons since they require some extra definitions. First, both controls are defined in the control matrix as described in 2.5.4. Their types are "RADIO" and "BUTTON" respectively. In this phase it is not allowed to set a Callback function since this will be done later with functions SetRadioGroup and SetMenu. controls = { {10, "LABEL", 10, 10, 290, 21, "Select Deck", "labeltop"}, {20, "RADIO", 20, 50, 160, 30, "NASTRAN", "radio1"}, {30, "RADIO", 20, 90, 160, 30, "ABAQUS", "radio2"}, {40, "RADIO", 20, 130, 160, 30, "PAMCRASH", "radio3"}, {50, "LABEL", 20, 170, 160, 30, "Select Entities","labelbottom"}, {60, "BUTTON", 20, 210, 160, 30, "btn", "btn_lower"}, { 1, "BUTTON", 30, 340, 91, 41, "OK", "okbtn"}, { 2, "BUTTON", 190, 340, 91, 41, "Cancel", "cancelbtn"} };

Page 46: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 46

dialog = {100, 0, 0, 311, 404, MatLen ( controls ), controls, "Demo"}; win = CreateWindow ("Win4", dialog); The above control matrix contains 2 labels, three radio buttons and a menu button. After the creation of the window two group matrices must be defined for radio and menu control. These matrices will contain the available options with the difference that in case of radio buttons the internal reference names must be given while in menus the available options are given directly: radio_group = {"radio1","radio2","radio3"}; menu_group = {"Elements","Nodes"}; In the final step these matrices will be passed to the respective setup functions: SetRadioGroup ("Win4", radio_group, 0, "rgroup_1", "RadioCallback"); SetMenu ("Win4", "btn_lower", "MenuCallback", menu group, 0); The SetRadioGroup requires the window name ("Win4"), the group matrix ("radio_group"), an integer, indicating the active radio button, an internal reference name for the group ("rgroup_1") and the name of callback function ("RadioCallback"). The SetMenu requires similarly the window name ("Win4"), the internal reference name as it is defined in control matrix ("btn_lower"), the name of the callback function, the group matrix ("menu_group") and the active option. Keep in mind that the option number starts always from zero. After setting up the radio buttons and the menu, we must create the callback functions which will allow to recognize any change of the controls. These functions accept the typical three arguments (See 2.5.7) and in their simpler form can be like the following: def MenuCallBack (string window_name, string btn_name, string option) {

if(option=="Elements") Print("Elements option was selected"); if(option=="Nodes") Print("Nodes option was selected"); StringSet (window_name, btn_name, option);

} In this case, the StringSet built in function will change the status of menu. def RadioCallback (string window_name, string group, string option) {

if ( Atoi(option) == 0) Print("NASTRAN option was selected"); if ( Atoi(option) == 1) Print("ABAQUS option was selected"); if ( Atoi(option) == 2) Print("PAMCRASH option was selected");

} After all settings the window must be destroyed. def main() { controls = { {10, "LABEL", 10, 10, 290, 21, "Select Deck", "labeltop"}, {20, "RADIO", 20, 50, 160, 30, "NASTRAN", "radio1"}, {30, "RADIO", 20, 90, 160, 30, "ABAQUS", "radio2"}, {40, "RADIO", 20, 130, 160, 30, "PAMCRASH", "radio3"}, {50, "LABEL", 20, 170, 160, 30, "Select Entities","labelbotton"}, {60, "BUTTON", 20, 210, 160, 30, "btn", "btn_lower"}, { 1, "BUTTON", 30, 340, 91, 41, "OK", "okbtn"}, { 2, "BUTTON", 190, 340, 91, 41, "Cancel", "cancelbtn"} }; dialog = {100, 0, 0, 311, 404, MatLen ( controls ), controls, "Radio Buttons Demo"}; win = CreateWindow ("Win4", dialog); SetOkButton ("Win4", "okbtn");

Page 47: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 47

SetCancelButton ("Win4", "cancelbtn"); radio_group = {"radio1","radio2","radio3"}; SetRadioGroup ("Win4", radio_group, 0, "rgroup_1", "RadioCallback"); menu_group = {"Elements", "Nodes"}; SetMenu ("Win4", "btn_lower", "MenuCallBack", menu_group , 0); res = OpenWindow ("Win4"); DestroyWindow("Win4"); } def MenuCallBack (string window_name, string btn_name, string option) {

if(option=="Elements") Print("Elements option was selected"); if(option=="Nodes") Print("Nodes option was selected"); StringSet (window_name, btn_name, opt);

} def RadioCallback (string window_name, string group, string option) {

if ( Atoi(option) == 0) Print("NASTRAN option was selected"); if ( Atoi(option) == 1) Print("ABAQUS option was selected"); if ( Atoi(option) == 2) Print("PAMCRASH option was selected");

}

2.6.3 Creating and setting up List Boxes A "List Box" is a type of window where a list of items (entries) can be displayed, selected or highlighted. A very simple window, which we will try to create step by step, is the one below:

Like in all scripts related with GUI, we must start from the definition of the control matrix. The control type that must be declared first is the LIST_BOX, while the others will be simple buttons. controls = { {100, "LIST_BOX",10,10,360,230, "", "list1"}, {102, "BUTTON",50,270,80,30, "Modify", "modify", "onModify"}, { 1, "BUTTON",250,270,80,30, "Ok", "okbutton"} }; dialog = {1000, 100,100, 380,320, MatLen(controls), controls, "Window2"}; window = CreateWindow("Window2", dialog); SetOkButton("Window2", "okbutton"); Items (entries) can ne added in a LIST BOX with the AddListBoxItem function. It takes three arguments, which are the window name, the reference name of the list box control (“list 1”) and a string that will be

Page 48: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 48

written in each line. The number of times that this function must be called is equal to the number of lines that we wish to add in the box window. Keep in mind that all functions regarding the LIST BOX accept always the aforementioned first two arguments and thus they are not going to be mentioned again. // add some items in the listbox AddListBoxItem("Window2","list1","item1"); AddListBoxItem("Window2","list1","item2"); AddListBoxItem("Window2","list1","item3"); AddListBoxItem("Window2","list1","item4"); By default, the above definition allows the user to select only one entry from the window. For multiselections, we must call the LBSetMultiSel function, which controls this behavior. The third argument is an integer that its values are zero (multiselection off) or one (multiselection on). // set the listbox to multiselect mode LBSetMultiSel("Window2","list1",1); As it seems from the control matrix, no callback function was set for the LIST BOX control. Callbacks for this type of control can be used in order to identify which items where selected or highlighted in order to perform specific actions. The most important functions in this area are the OnLBIHighlighted and onLBISelected. Except for the first two arguments the name of the callback must be given: // set the event callbacks onLBIHighlighted("Window2","list1", "onHighlight"); onLBISelected("Window2","list1", "onSelect"); The onHighlight and onSelect have the form: static def onHighlight(string window_name, string btn_name, string id) {

Print("Highlight:"+id); } static def onSelect(string window_name, string btn_name, string id) {

Print("Select:"+id); } The third argument is the unique id of the item that was selected/highlighted. Note that the counting starts from zero. For getting the text of the current item we just call the LBCurText function, which takes only the two known arguments. current_text = LBCurText("Window2","list1") Print("current text:"+ current_text); For multiselections the above function returns the string represented from the last selected item. Special attention must be given to the callback onModify of the control matrix that will be used for items modifications: static def onModify(string window_name, string btn_name) {

cur = LBCurrent(window_name, "list1"); res = UserInput("Please type some text", txt); if (res) {

if (cur >= 0) {

SetLBItemText(window_name, "list1", cur, txt); }

} }

Page 49: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 49

Before setting a new value to an item, it must be first recognized by its id. This is made with the LBCurrent function, which returns the unique id of the item. Next, this output is given as third argument in the SetLBItemText . The new text will be given in the forth argument. Finally, for getting all the item texts after a multiselection action, we call the LBSelectedItems function. The selected items are returned in a matrix with their id representation. Selected_items = LBSelectedItems("Window2","list1"); Making a loop in the Selected_items matrix, we get the item texts with the LBItemText. foreach sel_item_id in Selected_items {

Lbitext = LBItemText("Window2", "list1", sel_item_id)); Print("selected item:"+ sel_item_id +", "+ Lbitext);

} The final code is the following: static def onHighlight(string window_name, string btn_name, string id) {

Print("Highlight:"+id); } static def onSelect(string window_name, string btn_name, string id) {

Print("Select:"+id); } static def onModify(string window_name, string btn_name) {

cur = LBCurrent(window_name, "list1"); res = UserInput("Please type some text", txt); if (res) {

if (cur >= 0) {

SetLBItemText(window_name, "list1", cur, txt); }

} } def main() { controls = { {100, "LIST_BOX", 10,10,360,230, "", "list1"}, {102, "BUTTON", 50,270,80,30, "Modify", "modify", "onModify"}, { 1, "BUTTON", 250,270,80,30, "Ok", "okbutton"} }; dialog = {1000, 100,100, 380,320, MatLen(controls), controls, "Window2"}; window = CreateWindow("Window2", dialog); SetOkButton("Window2", "okbutton"); // add some items in the listbox AddListBoxItem("Window2","list1", "item1"); AddListBoxItem("Window2","list1", "item2"); AddListBoxItem("Window2","list1", "item3"); AddListBoxItem("Window2","list1", "item4"); // set the listbox to multiselect mode LBSetMultiSel("Window2","list1",1); // set the event callbacks onLBIHighlighted("Window2","list1", "onHighlight"); onLBISelected("Window2","list1", "onSelect"); res = OpenWindow("Window2");

Page 50: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 50

if (res) {

Print("current text:"+LBCurText("Window2","list1")); Selected_items = LBSelectedItems("Window2","list1"); foreach sel_item_id in Selected_items {

Lbitext = LBItemText("Window2", "list1",sel_item_id)); Print("selected item:"+sel_item_id+", "+ Lbitext);

} } DestroyWindow("Window2"); }

2.6.4 Hiding and Showing controls The visibility of all controls can be handled through the HideControl and ShowControl functions. Their syntax is the same and needs the window name and the reference name of the control. In the example that will follow, the visibility of all buttons is controlled through a callback, which hides or shows the buttons according to the status of a check box. static def onCheckChange(string window_name, string btn_name, string state) {

if (state ==0) {

ShowControl(window_name, "btn_1"); ShowControl(window_name, "btn_2");

} else {

HideControl(window_name, "btn_1"); HideControl(window_name, "btn_2");

} } def main() { controls = { {102, "CHECK" , 50,30,250,20, "hide / show buttons", "check1", "onCheckChange"}, {103, "BUTTON" , 50,75,150,20, "Option 1","btn_1"}, {104, "BUTTON" , 50,100,150,20, "Option 2","btn_2"}, { 1, "BUTTON", 165,160,70,30, "Ok", "okbutton"} }; dialog = {1000, 100,100, 400,210, MatLen(controls), controls, "Hide/Show"}; window = CreateWindow("Hide/Show", dialog); SetOkButton("Hide/Show", "okbutton"); res = OpenWindow("Hide/Show"); DestroyWindow("Hide/Show"); }

Page 51: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 51

Section 3 Exchanging data: Text files I/O

3.1 General ANSA scripting language is capable to handle external formatted and unformatted files. Specifically, ANSA can read and write ASCII unformatted files (txt, csv etc.) while it can also handle formatted XML files. The treatment of such files includes many operations like opening, reading, creating the file itself or browsing through its contents. In this way it is possible to pass any information from a file that contains any data (engineering data, connection information) to an ANSA database. Some basic functions that can be used for these purposes are presented and explained in the following paragraphs.

3.2. Unformatted text files The most important functions for the handling of text files are listed in the following table:

# Function Description

1 Fopen("/home/work/test.txt","w"); Fopen("/home/work/test.txt","r"); Fopen("/home/work/test.txt","a");

Opens a file for writing. Opens a file for reading. Opens a file for appending.

2 Fclose(f); Closes a file. 3 Read(f,line); Reads each line of a fille 4 Write(f,"text to write"); Writes into a file. 5 TokenizeString("1,2,5,20",",",0) Breaks a string into tokens 6 MatchString("10_PID:40",": "); Locates a substring

The last two functions are the most significant string functions. Their use is necessary during the reading of an ASCII file.

3.2.1. Opening and closing files In the most general case of reading a file or appending to it, the language checks if the user has permissions on this file. If everything is ok then it returns an integer which is used later for any action instead of the name of the file. The script functions that are used to open and a close a file are the Fopen and Fclose. def main() {

f = Fopen("home/work/test.csv","r"); //Opens a file for reading ..... Statements ..... Fclose(f);//Closes the file

} Important Note: If you try to open a file for writing or appending to it and the file doesn't exist, then the file is created automatically

3.2.2. Reading files The reading of an ASCII file is made line-by-line, making use of the output integer of the Fopen function. The script function that is used is called Read and most of the times it is used together with a while statement. This is made in order to assure that the file will be read from the beginning to the end. Suppose that the file that we want to read has the following context and we just want to read and print each line.

Page 52: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 52

SUBSTRUCTURE = side MODULE_ID = 100 TITLE = B-PILLAR MODULE_ID = 1000 PID = 20 PIDNAME = MAT1_BP THICKNESS = 0.8 MAT_NAME = Steel X_AXIS = 1,0,0 Y_AXIS = 0,1,0 Z_AXIS = 0,0,1 ORIGIN = 0,0,0 def main() {

f = Fopen("/home/work/test.attr","r"); //Opens the file for reading //Read each line of the file and store it under the variable s while(Read(f,s)) {

Print(s);//Print each line } Fclose(f);//Closes the file

} In almost all cases there is the need to extract specific information from the lines of a text in order to use it accordingly. Usually, the TokenizeString and MatchString functions are enough for getting such information. The TokenizeString splits a string to its contents according to a separator symbol. For example a variable called "line" that indicates a node id and its coordinates, in a comma-separated form, can be split into four different strings. The new strings are stored in a matrix. def main() {

// NID, xcoord ycoord zcoord line = "234,-42.505,-44.245,17.782"; tokens = TokenizeString(line, ",",0); Print("The string line was separated in "+MatLen(tokens)+ "tokens");

} After the execution of the script the function will return a matrix with the tokens. In our example the length of the matrix is 4 and each entry will have the following values: tokens[0] = 234 tokens[1] = -42.505 tokens[2] = -44.245 tokens[3] = 17.782 It is recommended to convert each of the tokens to the appropriate form (float, integer etc.) before any further use. The second argument can host any number of separators: def main() {

// NID, xcoord ycoord zcoord line = "234,-42.505_-44.245:17.782"; tokens = TokenizeString(line, ",_:",0); Print("The string line was separated in "+MatLen(tokens)+"tokens");

} The result will be a matrix with the same entries as before. Some types of separators need the backslash symbol \ for their definition:

Page 53: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 53

For tab separator: TokenizeString(line,"\t",0); For " separator : TokenizeString(line,"\"",0); For \ separator : TokenizeString(line,"\\",0); For blank separator just leave a space: TokenizeString(line, " " ,0); Last argument declares if a blank token will be saved in the output matrix (flag=1) or not (flag=0): def main() {

line = 234,-42.505,,-44.245,17.782 tokens = TokenizeString(line,",",1); Print("The string line was separated in "+MatLen(tokens)+" tokens");

} In this case the number of entries in 'tokens' will be five since the function has used 1 as last input argument. The extra entry will be an empty string. The MatchString is used to identify a specific sub-string within a parent string. It returns an integer indicating the position of the first occurrence of the sub-string. If nothing is found zero is returned. First input argument is the parent string and second argument the sub-string that must be matched. def main() {

parent = "name_roof_pid_100"; pos = MatchString(parent, "pid");

} The 'pos' variable will be 11 since the first occurrence of pid is in the 11th position. A very useful application is demonstrated in the following example were we would like to identify all PSHELL's names that contain the string "Default" and store them in matrix in order to delete them. def SubStitute() {

//Initialize count = 0; pshells = CollectEntities(NASTRAN,0,"PSHELL",0); foreach pshell in pshells {

GetEntityCardValues(NASTRAN,pshell,"Name",name); pos = MatchString(name,"Default"); if(pos) {

to_del[count++]= pshell; }

} DeleteEntity(to_del,1);

}

3.2.3. Writing files The function Write enables the writing in a file. Its only argument is the integer returned by the Fopen function. Every time that the function is called a new line is written. Suppose that we want to write in a ‘csv’ file (comma-separated) the PID, name and thickness of all PSHELL properties of our model. A simple code should be like the following:

Page 54: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 54

def main() {

f = Fopen("home/work/test.csv","w"); //Opens a file for writing //Collect the PSHELLs pshells = CollectEntities(NASTRAN,0,"PSHELL",0); //Write the HEADER Write(f,"PID,Name,Thickness"); //Loop through the PSHELLs foreach pshell in pshells {

GetEntityCardValues(NASTRAN,pshell,"PID",pid,"Nameî,name, "T",thickness);

Write(f,pid+","+name+","+thickness); } Fclose(f);

} For writing more than one lines after each call of Write, use the \n symbol enclosed in quotes.

3.3. XML formatted files The most important functions for the handling of xml files are listed in the following table:

# Function Description 1 XmlOpenBase("/home/script.xml", "scripted"); Opens a XML data base 2 XmlGetNode(base, "VTAElements/");

XmlGetNode(base, root,"VTAElements/"); Fetces a node 3 XmlGetSubNodes(base,node); Fetches the subnodes of a node 4 XmlNodeName(base, sub_param); Gets the name of a node 5 XmlGetStringValue(base,sub_param,"Name",""); Gets the string value of a node 6 XmlGetNodeData(base,node); Gets node's data 7 XmlNewNode(base,"Connection Elements",1);

XmlNewNode(base,node_connection,"Spotwelds",1); Creates new node 8 XmlSetStringValue(base, sub_node, "val","str"); Set a string value to a node 9 XmlSetNodeData(base, sub_node, "some_data"); Sets node's data

For the clarification of the above functions the following xml scheme is going to be used for reading and writing: <Data>

<Connection_Elements> <SpotweldPoints> <Parameter Code = "Connection Name">Spot1</Parameter> <Parameter Code = "xcoord">1.2</Parameter> <Parameter Code = "ycoord">5.0</Parameter> <Parameter Code = "zcoord">3.5</Parameter> <Parameter Code = "comment">"Connect 2 flanges"</Parameter> </SpotweldPoints> <Parts> <PartInfo Code = "Part Name 1">"upper"</PartInfo> <PartInfo Code = "Part Name 2">"lower"</PartInfo> <PartInfo Code = "Prop Id 1">10</PartInfo> <PartInfo Code = "Prop Id 2">20</PartInfo> </Parts> </Connection_Elements>

</Data>

Page 55: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 55

3.3.1. Opening xml files For opening an xml file the XmlOpenBase function must be used. def main() {

base = XmlOpenBase("/home/work/connections.xml", "internal_name"); ...

} The key point in this function is the output value which is of type element (pointer) and indicates the xml database. Almost all the XML functions that are going to be used later will need this element(pointer). The second argument is necessary only when writing XML files where it is used as base node. In case of reading, it can take an arbitrary internal name that will not be used further. When this function points to a non existent file then this file is automatically created.

3.3.2. Getting nodes and sub-nodes For getting the element (pointer) of a node the XmlGetNode must be used. In our example nodes are considered the tags <Data>, <Connection_Elements>, <SpotweldPoints> and <Parts>. The root node in this structure is considered the <Data> and this is the node that must be fetched first. The syntax for getting it is: data = XmlGetNode(base,"Data/"); //For getting the <Data> Since "Data" is the root we can set second argument as blank: node = XmlGetNode(base,""); //This will get the <Data> The output data is a matrix that contains the element (pointer) of ,"Data" The nodes that comes hierarchically just after the root, like the <Connection_Elements>, can be taken if we write: //For getting the <Connection_Elements> connection_elements = XmlGetNode (base,data[0],"Connection_Elements"); Alternatively, after getting a node it is easy to get its sub-nodes using the XmlGetSubNodes. Attention must be given in the function's second argument since it must be taken from the output matrix of the XmlGetNode that was called before. In our example the node <Connection_Elements> is the subnode of <Data> while the nodes <SpotweldPoints>, <Parts> are the subnodes of the <Connection_Elements>. The code that we must use is: data = XmlGetNode(base,"Data/"); //For getting the <Connection_Elements> connection_elements = XmlGetNode (base,data[0],"Connection_Elements"); //For getting the <SpotweldPoints>, <Parts> subnodes = XmlGetSubNodes(base, connection_elements[0]); The output is always a matrix that contains the elements (pointers) of the sub-nodes.

3.3.3. Getting the name of the node In an XML file each node holds a name, which describes most of the times an area of interest. The name can be extracted using the XmlNodeName function. Its syntax is very simple and it needs the base and the node element (pointer). connection_elements = XmlGetNode (base,data[0],"Connection_Elements"); //For getting the <SpotweldPoints>, <Parts> subnodes = XmlGetSubNodes(base, connection_elements[0]); foreach subnode in subnodes {

node_name = XmlNodeName(base,subnode); Print(node_name);

}

Page 56: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 56

In the above example the names 'SpotweldPoints' and 'Parts' are going to be displayed on the screen.

3.3.4. Getting attributes and node data Apart from its name, a node can also have attributes and data that are also important for the process. Let's focus on node <SpotweldPoints> that has the sub-nodes <Parameter> which in turn have the attribute 'Code'. This attribute takes five parameter names ('Connection Name', 'xcoord', 'ycoord', 'zcoord', 'comment'), while each node holds data that is associated with each of these parameters ('Spot1, 1.2, 5, 3.5, Connect 2 flanges'). Two new functions will be introduced for extracting all these information: These are the XmlGetStringValue and the XmlGetNodeData. Their use is demonstrated together with the complete example: def main() { base = XmlOpenBase("/home/work/connections.xml", "internal_name"); data = XmlGetNode(base,"Data/"); connection_elements = XmlGetNode(base,data[0],"Connection_Elements"); sub_nodes = XmlGetSubNodes(base,connection_elements[0]); foreach sub_node in sub_nodes { node_name = XmlNodeName(base,sub_node); if(node_name=="SpotweldPoints") { subs_of_spots = XmlGetSubNodes(base,sub_node); foreach sub_of_spots in subs_of_spots { param_name = XmlGetStringValue(base,sub_of_spots,"Code",""); if(param_name=="Connection Name") connection_name = XmlGetNodeData(base,sub_of_spots); if(param_name=="xcoord") xcoord = XmlGetNodeData(base,sub_of_spots); if(param_name=="ycoord") ycoord = XmlGetNodeData(base,sub_of_spots); if(param_name=="zcoord") zcoord = XmlGetNodeData(base,sub_of_spots); if(param_name=="comment") comment = XmlGetNodeData(base,sub_of_spots); } Print("connection_name:"+connection_name); Print("xcoord:"+xcoord); Print("ycoord:"+ycoord); Print("zcoord:"+zcoord); Print("comment:"+comment); } } } Important Note1: The name of an attribute is necessary for retrieving the attribute values. Important Note2: If the attribute hasn't got a value then a default can be assigned through the forth argument of XmlGetStringValue

3.3.5 Writing XML files and setting the base node In order to create a new XML file, the function XmlOpenBase must be used. The second argument is important since it defines the base node, which in our case is the <Data>. base = XmlOpenBase("/home/jharal/tmp/test.xml","Data");

3.3.6 Creating nodes A new node can be created with the function XmlNewNode. Its syntax accepts either 3 or 4 arguments. Depending on the syntax a node can be created just after the base node (3 arguments) or in any other place (4 arguments). In the latter case an element (pointer) indicating the parent node will be needed. In the following example: node_connection = XmlNewNode(base,"Connection Elements",1);

Page 57: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 57

the node 'Connection Elements' will be placed after the node 'Data' while if you write: node_spot = XmlNewNode(base,node_connection,"SpotweldPoints",1); the node 'SpotweldPoints' will be created after the 'Connection Elements'. It is clear that in this case the output of the previous call was used. Last argument indicates whether the node appears once (1) or more (0). In our example it is 1 since both nodes are written once. On the other hand if we create the node 'Parameter' which appears more than once, then we should write: node_param = XmlNewNode(base,node_spot,"Parameters",0);

3.3.7 Setting attributes and node data Attribute names and attribute parameters are given through the XmlSetStringValue. XmlSetStringValue(base,node_param,"Code","Connection name"); or XmlSetStringValue(base,node_param,"Code","xcoord"); In a similar way the function XmlSetNodeData sets data to a node. XmlSetNodeData(base,node_param,"Spot1"); or XmlSetNodeData(base,node_param,"1.2"); Recapitulating, the final code for writing the whole xml file (See paragraph 3.3) is the following: def main() { base = XmlOpenBase("/home/jharal/tmp/test.xml","Data"); node_connection = XmlNewNode(base,"Connection Elements",1); node_spot = XmlNewNode(base,node_connection,"SpotweldPoints",1); parameter_names_spots = {"Connection name","xcoord","ycoord","zcoord","comment"}; node_data_spots = {"Spot1","1.2","5.0","3.5","Connect 2 flanges"}; for(i=0;i<5;i++) { node_param = XmlNewNode(base,node_spot,"Parameters",0); XmlSetStringValue(base,node_param,"Code",parameter_names_spots[i]); XmlSetNodeData(base,node_param,node_data_spots[i]); } node_parts = XmlNewNode(base,node_connection,"Parts",1); parameter_names_parts = {"Part Name 1","Part Name 2","Prop Id 1","Prop Id 2"}; node_data_parts = {"upper","lower","10","20"}; for(i=0;i<4;i++) { node_param = XmlNewNode(base,node_parts,"Parameters",0); XmlSetStringValue(base,node_param,"Code",parameter_names_parts[i]); XmlSetNodeData(base,node_param,node_data_parts[i]); } XmlCloseBase(base,1); }

Page 58: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 58

Section 4 Specialized Functions

4.1 General Specialized functions in scripting language are actually user functions that have a unique syntax (input and output arguments) and can be called automatically from the program when the user performs specific tasks. Connectors, GEBs ( trims and output requests) and connection manager are basically the fields where these functions can operate. ANSA before executes any specialized function either checks its existence in ANSA.defaults and then executes it (connection manager), or execute it directly (Connectors, GEBs). In all cases, the user has to load the functions prior to execution and therefore it is prefered to put them into an ANSA_TRANSL file.

4.2 Description of Specialized functions During the creation of connectors and GEBs from the GUI, the user must decide between several built in representations and interfaces. These options cover a variety of cases but sometimes the analysis requires a different approach. Therefore, between the available options the user can select to call a script function that will create the desired combination of entities. This function needs to be loaded prior to its call. The program undertakes to feed the function with the correct data. Similarly, during the realization process into the connection manager, user functions can be called in order to assign in the newly created entities specific characteristics. Before any execution, ANSA makes a check in ANSA.defaults file. Specifically, searches the name of the function that must call. These names are stored under variables that indicate the type of the action that will take place. The variable names are four: shell_to_spring_pid = <name of function> It is called in order to assign PROP/SPRING properties to springs. This option is available only when the representation is RADIOSS WELD. Weld_user_field_update = < name of function > It is called in order to update the non editable User field of each connection. thick_spw_diam = <name of function> It is called in order to map the flange thickness with the diameter of the connection. post_realization_fn = <name of function> It is called in order to make any custom changes for each successfully realized connection.

4.2.1 Creating Connectors and GEBs with scripting The interface of connectors and GEBs and the representation of connectors support the option of "UserScript" The "UserScript" interface will execute a user defined function to create any custom interface or representation between the entities identified from the search and the representation/interface entity. This function uses 4 arguments by default:

i. The current Generic Entity: variable of type element (pointer). ii. The entities identified from the search. These entities will be transferred to the script through

a matrix. Each matrix entry is of type element (pointer). iii. The entities given from the representation. These entities will be transferred to the script

through a matrix. Each matrix entry is of type element (pointer). iv. Some user arguments transferred to the function in the form of a string type variable.

Page 59: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 59

In the example shown, the function to be executed is named ‘BarInterface’. This function is defined as follows: BarInterface (element GEB_BC, matrix FromRepr, matrix FromSearch, string args) The matrix ‘FromSearch’ will contain all the nodes that lie in the inner/outer zone of the hole. The matrix ‘FromRepr’ will contain one ‘Spc1’ node, which is by default located at the x, y, z Generic Entity coordinates. Finally, the string args will be the ‘60’ string specified in the ‘func_arguments’ field! Note that the function must return a non-zero value on success and a zero value on failure. After the realization of this generic entity, each node identified from the search will be connected to the ‘Spc1’ node with a ‘CBAR’ element. def BarInterface (element GEB_BC, matrix FromRepr, matrix FromSearch, string diam) {

all_search_nodes = MatLen (FromSearch); radius = Atof(diam)/2; area = 3.14*radius**2; //Get the id of the representation node GetEntityCardValues(NASTRAN,FromRepr[0],"NID",repr_id); //Create a PBAR property new_prop = CreateEntityVa(NASTRAN,"PBAR","A",area); GetEntityCardValues(NASTRAN,new_prop,"PID",property_id); for(i=0;i<all_search_nodes;i++) {

//Get the id of each search node GetEntityCardValues(NASTRAN,FromSearch[i],"NID",src_id); //Create the bar CreateEntityVa(PAMCRASH,"BEAM","N1",repr_id,"N2",src_id, "IPART",property_id,"x1",1);

} return 1;

} Keep in mind that even though the ‘CreateEntityVa’ is invoked, the bars are finally created because of the positive return value. Important Note: The script that contains the function ‘BarInterface’ should be already loaded.

Page 60: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 60

4.2.2 Executing specialized script functions from Connection Manager Weld_user_field_update: Among the available fields of each connection entity, there is one called ‘User’ which is editable only through scripting. This ‘User’ field can be updated only during the realization process and it’s usage can vary according to user needs. A very useful operation of this, is to display the property id for each plink that is created. First, we define in ANSA.defaults the name of the function that must be called just after realization: # Custom function to update User field of a Connection # function format : string Function( element CONNECTION ); # weld_user_field_update = # A function name is assigned to this variable, eg: # weld_user_field_update = UserPlinkProp # This function should have the required syntax, i.e. string Function (element connection) and should return a string The input argument of this function is the element (pointer) of the entity that is going to be created. Having this information it is easy to extract all necessary informations. At the end of the script a string must be returned. A possible use of this function is to display in the ‘User’ field the property id of the newly created plinks: def UserPlinkProp(element connection) {

for(ret = GetFirstFeRep(connection);ret;ret = GetNextFeRep(connection,ret)) {

if(GetEntityType(PAMCRASH,ret)=="PLINK") {

GetEntityCardValues(PAMCRASH,ret,"IPART",ipart); break;

} } return ipart;

}

Page 61: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 61

thick_spw_diam: During the realization of many representations in connection manager (CBEAM, CBAR) the diameter of a newly created entity is taken from a rule that is specified in ANSA,.defaults as following: # Flange Thickness to Spot Weld Diameter Map # format : d1 [,t1 ,d2 [,t2 ,d3 [,....]]] # (where t : Thickness class upper bound # 0 < t(i) < t(i+1) # i < 100 # d : Spot Weld Diameter for it ) thick_spw_diam = 4.00,1.02,5.00,1.78,6.00 In many case this rule is applied only when the option ‘Use Thickness to Diameter Map’ is activated. If the user requires a more complicated rule, then he can specify after ‘thick_spw_diam’ the name of a script function : # thick_spw_diam = AssignDiameter # This function should have the syntax: float Function(float thickness) and should return a diameter The input argument is a thickness value while the returned value is the diameter that will be applied: def AssignDiameter(float thickness) {

if(thickness<=1) diameter = thickness; else if(thickness>1 && thickness<2) diameter = thickness/4; else if(thickness>=2 && thickness<3) diameter = thickness/2; else diameter = thickness*2; return diameter;

} The thickness that is given as input is the one that calculated according to the ANSA.defaults variable ‘spw_diam_mflng’: # Master Flange Election Method # format : INNER|OUTER|MIDDLE|ALL,THINNEST|THICKEST|MEAN spw_diam_mflng = INNER , THINNEST shell_to_spring_pid: The RADIOSS WELD is the only representation that can use the option ‘Use thickness to PID Map’. If this option is activated, then ANSA during realization calls a function that is declared in ANSA.defaults under the variable ‘shell_to_spring_pid’. # Projected shells to Radioss Spring PID mapping function # function format : element Function( matrix Shells ); # where you get a matrix of the projected shells, # and you must return the property to be used by the # springs that will be created. This property can be # either created or selected by the properties list # shell_to_spring_pid = A function name is assigned to this variable eg: # shell_to_spring_pid = DefineSpringId #

Page 62: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 62

This function should have the syntax element Function(matrix shells) and should return the element (pointer) of a property. The input argument is a matrix that contains the projected shells while the output must be the element of the property that is going to be assigned to the newly created radioss springs. The property is created into the function or it can be any existing one. def DefineSpringId(matrix shells) {

len = MatLen(shells); i = 0; foreach shell in shells {

GetEntityCardValues(RADIOSS,shell,"PID",pid); prop = GetEntity(RADIOSS,"PROP/SHELL",pid); GetEntityCardValues(RADIOSS,prop,"THICK",t); thickness[i++] = Atof(t);

} max = Max(thickness,len);Print(max); if(max<=1) ent = CreateEntityVa(RADIOSS,"PROP/SPR_BEAM", "Name","Maximum thickness less than "+max, "PID",500","TYPE","SPR_BEAM 13","MASS",0.5); else ent = CreateEntityVa(RADIOSS,"PROP/SPR_BEAM","Name","Maximum thickness greater than "+max, "PID",1000","TYPE","SPR_BEAM 13","MASS",1); return ent;

} In the above example a different PROP/SPR_BEAM is assigned to each spring according to the thicknesses of the shells that connects. post_realization_fn: If it is necessary to alter the results of some realized connections, after a successful realization, the connection manager is able to call a user-script function, that will allow the user to make the required changes. USAGE: in the ANSA.defaults file, you can see the following variable: # # User connection post realization function # function format : int Function( entity Connection, # matrix XYZ_per_flange, # matrix ProjEnts_per_flange, # matrix heads_per_flange, # matrix bodies_per_flange_pair, # matrix miscellaneous ); # where : # -"Connection" is the connection element that has just been realized # -"XYZ_per_flange" is a matrix of the x,y,z coords of the projection on the flange # -"ProjEnts_per_flange" is a matrix of the entities at the projection # -"heads_per_flange" is a matrix of the entities at head of the connection # -"bodies_per_flange_pair" is a matrix of the entities between the flanges # -"miscellaneous" is a matrix of miscellaneous information, # and information for future use, where # "miscellaneous[0]" is diameter used during realization # return value: 0 if user made changes, connection will report as CUSTOM_FE # 1 if user made changes, connection will report in the usual manner # # the post-realization function is called for each successfully realized connection, # for the user to make any custom changes on its elemens. #

Page 63: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 63

post_realization_fn = A function name is assigned to this variable, eg: # post_realization_fn = PostRealizationCallback # This function should have the required syntax, i.e. int Function( element Connection, matrix XYZ_per_flange, matrix ProjEnts_per_flange, matrix heads_per_flange, matrix bodies_per_flange_pair ); and user should return 1 on success of the application. Possible uses: - users can modify diameters of bars according to their own scheme (like thickness to diameter mapping) - users can set the attributes of a Property of, say, a bar to their own values. - users may delete/add more fe-representations to the connection - users may produce a file output reporting on the quality of the produced elements/holes Following is an example of how to extract the various information from a connection that has just been applied: def PostRealizationCallback( element cnctn, matrix XYZ, matrix ProjEnts, matrix heads, matrix bodies, matrix others ) {

GetEntityCardValues(NASTRAN, cnctn, "__id__", id ); // CONNECTION: Print( "Connection: " + id ); // PROJECTION COORDINATES ON EACH FLANGE: n = MatLen( XYZ ); for( i=0; i<n; i++ ) {

Print( "pt[" + i + "] = {" + XYZ[i][0] + ", " + XYZ[i][1] + ", " + XYZ[i][2] + "}" );

} // PROJECTION ENTITIES ON EACH FLANGE: ( face/shell/node(s) ) n = MatLen( ProjEnts ); for( i=0; i<n; i++ ) {

Print( " Ent[" + i + "]:" ); nents = MatLen( ProjEnts[i] ); for( j=0; j<nents; j++ ) {

ent = ProjEnts[i][j]; GetEntityCardValues( NASTRAN, ent, "__id__", ID, "__type__", TYPE ); Print( "... id = "+ ID + "..."+TYPE );

} } // INTERFACE ENTITIES PRODUCED BY CONNECTION MANAGER, ON EACH FLANGE: nHeads = MatLen(heads); Print( nHeads + " HEADs:" ); for( i=0; i<nHeads; i++ ) {

Print( "-" +i + "> " ); nents = MatLen( heads[i] ); for( j=0; j<nents; j++ ) {

GetEntityCardValues(NASTRAN, heads[i][j], "__id__", ID, "__type__", TYPE ); Print( "... id = "+ ID + "..."+TYPE );

} }

}

Page 64: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 64

Section 5 Handling Scripts and ANSA_TRANSL

5.1. General Basic actions such as loading, parsing or executing user defined functions, can be handled in ANSA with 3 distinct ways which are the command window of GUI, the SCRIPT menu and the SCRIPT EDITOR. In this chapter we will focus on the description of the first two along with other useful functionality. At the end it will be shown another way of automating an ANSA process through the use of the ANSA_TRANSL file.

5.2. Using command window

5.2.1 Quick view of auxiliary built in functions A very quick way to handle scripts is through the command window which is the one that is located in the down left corner of the GUI. If we type in command line the word USER> then ANSA lists all available auxiliary built in functions next to the text window.

Note that after typing the letter ‘U’ ANSA autocompletes to USER>. This behavior is common for all built in commands.

5.2.2 Description of auxiliary built in functions A brief description of the functions listed in text window is given below: load_script Usage: USER>load_script: <full path to the new script> Example: USER>load_script:/home/jharal/work/CombineSets.c Description: Clear all previous loaded scripts and loads the one specified above import_script Usage: USER>import_script: <full path to the new script> Example: USER>import_script:/home/jharal/work/CombineSets.c Description: Append new script in the current active ones list_library Usage: USER>list_library:<name of built in function> or blank Example: USER>list_library: or USER>list_library: Print Description: When the function is not followed by a function name it displays the available built in functions per category. When a function name is given, then the help text of the function is displayed. export_library Usage: USER>export_library: Description: This function is obsolete export_help Usage: USER>export_help: <filename to write>

Page 65: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 65

Example: USER>export_help:/home/jharal/work/help.txt Description: Writes in the specified text file all available built in functions along with their help text unload_function Usage:USER>unload_function: <function name> Example: USER>unload_function: CombineSets Description: Unloads an already loaded function unload_script Usage:USER>unload_script: Example: USER>unload_script: Description: Unloads all loaded functions script_help Usage: USER>script_help: <function name> Example: USER>script_help: CombineSets Description: Displays the help text of a user defined function (See 1.8.7) list_category Usage: USER>list_category: <name of category> Example: USER> list_category: CONNECTION MANAGER FUNCTIONS Description: Displays the built in functions of the specified category list_categories Usage: USER>list_categories: Example: USER> list_categories: Description: Displays all the categories of built in functions

5.2.3 Loading scripts A script is succesfully loaded only when is free of syntax errors. Specifically, before loading anything ANSA parses the script that the user attempts to load and displays in the text window the error line of the code:

In the above example the script “OutputActran.c” has an error in line 19. After all necessary corrections the script is loaded again. This time no errors occured:

If the user try to reload a script that is already loaded and ANSA recognize that no changes have been made to it the message: NOTICE: script file [tmp/OutputActran.c] already loaded will be displayed.

Important Note:If a script has more than one error, then every time it is loaded only the first occurence will be displayed.

Page 66: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 66

Keep in mind that every time a script is loaded then automatically unloads all previous loaded ones.

5.2.4 Running scripts After a script is loaded, all the functions that contains can be viewed in the text window by typing USER> in the command line. Exceptions are those functions that have been declared as static (See Section 1.8.5).

If you wish to run one of the loaded function you should write in command line: USER><function name>:

If function contains input arguments then this is displayed in text window in the form: USER><function name (type of input argument)>

The "MeasureDistance" function accepts two integers as input arguments. These arguments are given in the command line just after the name of the function and have to be separated with a blank space or with comma. All other ways are not recognized and ANSA responds with the message: incompatible number of arguments Finally, all functions that executed via command line display their possible messages in the text window:

Message that was printed from"MeasureDistance"

Error message due to wrong syntax ofinput arguments: 8515;8521

Page 67: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 67

5.3 Using script menu

5.3.1 Script menu interface The SCRIPT button that is located in the main GUI, reveals the script menu:

The menu is splited in three sub-categories: SCRIPT, FUNCTION and EDITOR.

5.3.2 SCRIPT category This category contains five functions that basically control the script files. Let’s see them one by one:

Loads a script. The user is prompt to select a file from the File Manager. All previous loaded scripts are unloaded. Every script that is loaded becomes the default one. This means that

all the functions that holds are ready to run any time.

Imports a script. The user is prompt to select a file from the File Manager. Any function located in an imported script is appended to loaded ones and is ready to run any time.

Adds a script in the database. The user is prompt to select a file from the File Manager. An added script is considered loaded but the functions that holds are not available for running.

Sets a script as default. Selecting this button opens a window where all loaded and added scripts are displayed. The index in front of each path indicates which is the default

sequence. Always, the script with zero index is the default. Select a script from the list and press the "Set as default" button to become the default one. Press then OK to confirm. Important Note: A loaded script takes always zero index while an added script takes the first available index.

Each time a script is set as default, the functions that holds become available. The one that was previously default remains loaded but its functions are not available anymore. Important Note: Imported scripts are not listed in the above window.

Unloads loaded or added scripts. Selecting this button opens the list with all loaded and added scripts of the database. Select the script to unload and confirm with OK. When the

default script is unloaded then as default becomes the script with the next index. Consequently, all the functions of the first one are lost and the functions of the second become available.

LOAD

IMPORT

ADD

DEFAULT

UNLOAD

Page 68: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 68

Functions of imported scripts retain a relationship with the zero index script since they are appended to it. So, if a user unloads the zero index script then the functions of the imported scripts will be lost too. Similarly, if the default status is changed, the functions of the imported script will become unavailable.

5.3.3 FUNCTION category Runs a function. When selecting this button the following window opens:

In the Function list all available functions are displayed. These functions come from the imported scripts and from the default script. In Available modules menu, all the available scripts are displayed while the default one is always active. If another module is selected, then automatically its functions will become available while the previous ones will be unavailable. Other useful buttons are the Load module which acts similarly to SCRIPT>ADD and the Reload module which reloads the active script. Select a function from the list. Its help is displayed in the User function description. If the function needs input arguments, then these must be given in the Type function arguments field in comma separated form.

RUN

Page 69: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 69

Lists in the text window all built in functions

Unloads one or more functions. The functions are listed in the Function list area of previously described window.

5.4 Automation through an ANSA_TRANSL file

5.4.1 Location of ANSA_TRANSL file When ANSA is called to run, it will search for an ANSA_TRANSL file within the locations listed in the following table. The numbers on the left indicate precedence (from lowest to highest): # Location Description 1. ANSA_HOME Directory This is the directory where the environment variable ANSA_HOME is pointing at. 2. User's HOME Directory This is the local home directory of the user. 3. Working Directory This is the directory from which ANSA was called to run. During the attempt to read an ANSA_TRANSL, ANSA will display the following messages in the Text Window: 1. NOTICE script file : [ansa_home directory] 2. NOTICE script file : [user_home directory] 3. NOTICE script file : [current directory] Reading ANSA_TRANSL from [..path where ANSA_TRANSL it was found..]

5.4.2 How does ANSA interacts with ANSA_TRANSL ANSA_TRANSL interacts with ANSA in two ways: (a) when ANSA tries to read a CAD file, and (b) when a user executes a custom script. In the first way, ANSA will read and execute automatically all the commands written within the ANSA_TRANSL global code section. This functionality is very useful in cases where multiple CAD files should be translated into ANSA databases and the property, material, thickness, and other specific characteristics for each part must be assigned to the related fields within ANSA. In the second way, a user can call to run a previously defined function within ANSA_TRANSL. This can be done at any time during the user interaction with ANSA and can affect whatever is currently loaded in ANSA, either geometry or FE-model data. These functions are invoked from the command prompt of the Text Window or from SCRIPT menu (See 5.2.4 and 5.3.3). Important Note: ANSA_TRANSL can be also loaded manually (See 5.2.3 and 5.3.2).

5.4.3 Form of ANSA_TRANSL The general structure of an ANSA_TRANSL contains a global_code section and a user_functions section: The global section is executed while reading cad files (iges, step, vda) or during the translation of catia and unigraphics file. The user section contains a series of user functions written in the normal way (See 1.8.1) and is executed as it was explained in paragraph 5.3. If ANSA find between the ANSA_TRANSL files more than one global code then the last read will be kept. Similarly, if functions with same name are identified, then the last read will overwrite the previous ones.

LIST

UNLOAD

TRANSLATIONS : " "="_"; /* Translate spaces to underscores */ SEPARATORS = "=:,;"; /* Everything that will separate Words or Numbers*/ /* Guess Attributes File Name */ if(i=match_string(FILENAME,".")) { /* Replace Extension with .attr */ attr_filename=FILEPATH%FILENAME(:i-1)%".attr"; } /* Open Log File for Appending */ fd_log=fopen("ANSA_TRANSL.log","a+"); /* Log Attributes File Name */ if(fd_log) i=write(fd_log,"Reading :"%attr_filename); else print("Reading :"%attr_filename); /* Open Attributes File for Reading */ if(attr_filename && attr_fd=fopen(attr_filename,"r")) { /* Log Attributes File Name */ if(fd log) i=write(fd log,"Reading :"%attr filename);

def WeldParts(string dir_path){ weld_file = dir_path+"CONNECTIONS.txt"; f = fopen(weld_file, "r"); while(read(f, line)){ m = tokenize_string(line," ",0); type = m[0]; wid = atoi(m[1]); wx = atof(m[2]); wy = atof(m[3]); wz = atof(m[4]);

part1 = m[5];

global_code section

user_functions section

Page 70: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 70

Important Note: It is recommended the global code and all common user functions to be kept in the ANSA_TRANSL of ANSA installation directory.

5.4.4 What is a global code The global code can contain any script function and is written as any other code with the difference that it must be written always first in the file and without the def statement. The global code is executed only when pure cad files are used and when all the actual entities have been translated into ANSA.

ANSA_TRANSL without global code

def Translation() {

...code... } def ChangePids(element pshell) {

...code... }

ANSA_TRANSL with global code

pshell = GetFirstEntity(NASTRAN,"PSHELL"); ChangePids(pshell); def Translation() {

...code... } def ChangePids(element pshell) {

...code... }

Apart from the built in functions, ANSA_TRANSL global code can use a number of global functions/keywords called registers. These registers cannot be used from user defined functions and their use is very common when attributes like property name, property id, material name etc, must be assigned to the read cad models. Below is the list with all currently supported ANSA registers. ANSA registers Description FILENAME The name of the CAD file currently processed FILEPATH The directory path of the CAD file SEPARATORS Definition of whatever is used to separate words (eg. ,_.) TRANSLATIONS Default character translations (eg. " " = "_" blank space is

translated into an underscore) PART_ID Module ID of current Part PART_NAME The name of the Part as appears in the Part's Manager PART_PROPERTY_ID The Property ID that will be assigned to all entities of the Part PART_PROPERTY_NAME The name of the above property as appears in the PR.LIST PART_PROPERTY_THICKNESS The thickness of the Property PART_MATERIAL_ID The Material ID that will be assigned to all entities of the Part PART_MATERIAL_NAME The name of the above material as appears in the M.LIST PART_COORD_SYS_X X-coordinate of the Origin used for Part's position PART_COORD_SYS_Y Y-coordinate of the Origin used for Part's position PART_COORD_SYS_X Z-coordinate of the Origin used for Part's position PART_COORD_SYS_DX1 X-component of X-axis used for Part's transformation PART_COORD_SYS_DY1 Y-component of X-axis used for Part's transformation PART_COORD_SYS_DZ1 Z-component of X-axis used for Part's transformation PART_COORD_SYS_DX2 X-component of Y-axis used for Part's transformation PART_COORD_SYS_DY2 Y-component of Y-axis used for Part's transformation PART_COORD_SYS_DZ2 Z-component of Y-axis used for Part's transformation PART_COORD_SYS_DX3 X-component of Z-axis used for Part's transformation PART_COORD_SYS_DY3 Y-component of Z-axis used for Part's transformation PART_COORD_SYS_DZ3 Z-component of Z-axis used for Part's transformation POST_TRANSL_SCRIPT Obsolete POST_TRANSL_SCRIPT_ARGS Obsolete FLANCH_PROPERTY_ID Obsolete PART_MODEL_NAME Obsolete SYMMETRY_PART_ID Obsolete SYMMETRY_PART_ID_OFFSET Obsolete

Page 71: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 71

The basic advantage of registers is that they can pass directly a value to an entity without the need to search for the entity. Clearly, this approximation saves a lot of user work, minimize the code and eliminates the possibility of error. For example, if we like to name the property and the material of the model we just assign the respective strings to the registers PART_PROPERTY_NAME and PART_MATERIAL_NAME. PART_PROPERTY_NAME = "panel"; PART_MATERIAL_NAME = "steel"; The same could be made with the use of built in functions: pshell = GetFirstEntity(NASTRAN,"PSHELL"); SetEntityCardValues(NASTRAN,pshell,"Name","panel"); material = GetFirstEntity(NASTRAN,"MAT1"); SetEntityCardValues(NASTRAN,material,"Name","steel"); It is obvious that in the second case the user must write more lines of code and consequently the possibilities of making an error are greater. Important Note: If the cad file has more than one properties, then registers like PART_PROPERTY_NAME, PART_PROPERTY_THICKNESS etc will affect them all.

5.4.5. Importing CAD files Information about a part (like its name, property, material, thickness, position, etc) can reside as comments into the header section of a CAD file in the form of keywords. Using a special ANSA_TRANSL script, these keywords are read and the related information is passed directly into ANSA. In its simpler form, such an ANSA_TRANSL does not have a user_functions section and all the translation process is handled through the global_code section. A cad header can be read with the function GetNextFileLine. The syntax accepts a string argument where each line of the header is going to be stored after a succesful call of the function. Usually it is used together with a while statement. IGES header example MODEL : SPACE MOBILE S 1 PART NUMBER : 1234567 S 2 TITLE : LEFT FLOOR BEAM S 3 PROP ID : 456 S 4 VERSION : A S 5 THICKNESS : 1.5 S 6 MAT ID : 7892 S 7 MAT NAME : St 50 BH S 8 POSITION : L S 9 VERSION : B S 10 THICKNESS : 1.2 S 11 S 12 S 13 1H,,1H;,,57H/usr/people/CAD_data2/STELIOS_TEST/INTERFACES/header.iges,7HG 1 ANSA9.x,3H1.2,32,36,6,306,15,,1.,2,2HMM,1,1.,13H991109.153539,0.001, G 2 10000.,,,9,1,13H991109.153539; G 3 126 1 0 0 0 0 0 000000001D 1 126 0 0 8 0 0 0BSPLINE 1D 2 126,12,2,0,0,0,0,0.,0.,0.,0.25,0.25,0.375,0.375,0.5,0.5,0.75, 1P 1 0.75,0.875,0.875,1.,1.,1.,1.,1.,1.,0.707107,1.,0.707107,1.,1., 1P 2 1.,0.707107,1.,0.707107,1.,406.539,1057.63,-6.75,401.539, 1P 3

HEADER Section

NAME : CH-CBN-OUTER-L PID : 21 THICKNESS: 1.5 MATERIAL : MATS1_STEEL MID : 2 . . . . . . . . . . . . .

CAD File

DATA Section

ANSA_TRANSL

TRANSLATIONS : " "="_"; /* Translate spaces to underscores */ SEPARATORS = "=:,;"; /* Everything that will separate Words or Numbers*/ /* Guess Attributes File Name */ if(i=match_string(FILENAME,".")) { /* Replace Extension with .attr */ attr_filename=FILEPATH%FILENAME(:i-1)%".attr"; } /* Open Log File for Appending */ fd_log=fopen("ANSA_TRANSL.log","a+"); /* Log Attributes File Name */

Header

Page 72: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 72

1057.63,-6.75,396.539,1057.63,-6.75,396.539,1050.88,-6.75, 1P 4 396.539,1050.88,0.,396.539,1050.88,6.75,396.539,1057.63,6.75, 1P 5 401.539,1057.63,6.75,406.539,1057.63,6.75,406.539,1050.88,6.75, 1P 6 406.539,1050.88,0.,406.539,1050.88,-6.75,406.539,1057.63,-6.75, 1P 7 0.5,0.75,0.,0.,0.; 1P 8 S 13G 3D 2P 8 T 1

The above HEADER is easy to be extracted using only the following 2 lines as global code: while(GetNextFileLine(in_line)) Print(in_line); Besides the header section of a CAD file, information about a part can also be given through standard text files, the so called attribute files. In this case, for each CAD file that is opened into ANSA, ANSA_TRANSL will read the corresponding attribute file and retrieve information about the specific part. This information is then assigned to the related fields within ANSA. Suppose that the attribute file has the form: SUBSTRUCTURE = LEFT TITLE = B PILLAR MODULE ID = 999 PID = 100 PROPERTY NAME = B_PILLAR_999 THICKNESS = 0.97 MID = 1000 MATERIAL NAME = MAT1_STEEL ORIGIN = 0.,-100.,0. X_AXIS = 1.,0.,0. Y_AXIS = 0.,1.,0. Z_AXIS = 0.,1.,0. The ANSA_TRANSL that could be used in order to read the attribute file and assign the values to every imported cad file is the following: /*--------------------- GLOBAL CODE -----------------*/ /*---------------------------------------------------*/ /*---Informations are written in ANSA_TRANSL.log-----*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ SEPARATORS = "=:,;"; /* Separator of Words or Numbers*/ if(i = MatchString(FILENAME,".")) {

/* Replace Extension with .attr */ attr_filename=FILEPATH%FILENAME(:i-1)%".attr";

} /* Open Log File for Appending */ fd_log = Fopen("ANSA_TRANSL.log","a+");

Attributes File (TXT File)

NAME : FRONT_DOOR_LT PID : 21 THICKNESS: 1.5 MATERIAL : MATS1_STEEL MID : 2 . . . . . . . . . . . . . keyword_1 . . . . . . . . keyword_2 . . . . . . . .

CAD File

DATA Section

01234567891 . . . 123 . 1 01234567. 01234567. . . 2

ANSA_TRANSL

TRANSLATIONS : " "="_"; /* Translate spaces to underscores */ SEPARATORS = "=:,;"; /* Everything that will separate Words or Numbers*/ /* Guess Attributes File Name */ if(i=match_string(FILENAME,".")) { /* Replace Extension with .attr */ attr_filename=FILEPATH%FILENAME(:i-1)%".attr"; } /* Open Log File for Appending */ fd_log=fopen("ANSA_TRANSL.log","a+"); /* Log Attributes File Name */ if(fd_log) i=write(fd_log,"Reading :"%attr_filename); else print("Reading :"%attr_filename); /* Open Attributes File for Reading */ if(attr_filename && attr_fd=fopen(attr_filename,"r")) {

Page 73: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 73

/* Log Attributes File Name */ if(fd_log)

Write(fd_log,"Reading :"%attr_filename); else

Print("Reading :"%attr_filename); /* Open Attributes File for Reading */ attr_fd = Fopen(attr_filename,"r"); if(attr_filename && attr_fd) {

/* Loop throught all lines in Attributes File */ while(Read(attr_fd,in_line)) {

/* Look for a "SUBSTRUCT = ...." line */ if(MatchString(in_line,"SUBSTRUCT")) {

m = TokenizeString(in_line,"=",0); sub_ass_name = GetString(m[1]); NewGroup(sub_ass_name,0);

} /* Look for a "TITLE = ...." line */ else if(MatchString(in_line,"TITLE")) {

m = TokenizeString(in_line,"=",0); pdm_id = GetString(m[1]);

} /* Look for a "MODULE ID = ...." line */ else if(MatchString(in_line,"MODULE ID")) {

m = TokenizeString(in_line,"=",0); module_id = GetInt(m[1]);

} /* Look for a "PROPERTY NAME = ...." line */ else if(MatchString(in_line,"PROPERTY NAME")) {

m = TokenizeString(in_line,"=",0); property_name = GetString(m[1]);

} /* Look for a "PID = ...." line */ else if(MatchString(in_line,"PID")) {

m = TokenizeString(in_line,"=",0); property_id = GetInt(m[1]);

} /* Look for a "MATERIAL NAME = ...." line */ else if(MatchString(in_line,"MATERIAL NAME")) {

m = TokenizeString(in_line,"=",0); material_name = GetString(m[1]);

} /* Look for a "MID = ...." line */ else if(MatchString(in_line,"MID")) {

m = TokenizeString(in_line,"=",0); material_id = GetInt(m[1]);

} /* Look for a "THICKNESS = ...." line */ else if(MatchString(in_line,"THICKNESS")) {

m = TokenizeString(in_line,"=",0); thickness = GetFloat(m[1]);

} /* Look for an "ORIGIN = ...." line */ else if(MatchString(in_line,"ORIGIN")) {

/* Read X,Y,Z Origin Coordinates */ m = TokenizeString(in_line,"=,",0); PART_COORD_SYS_X = GetFloat(m[1]);

Page 74: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 74

PART_COORD_SYS_Y = GetFloat(m[2]); PART_COORD_SYS_Z = GetFloat(m[3]);

} /* Look for a "X_AXIS = ...." line */ else if(MatchString(in_line,"X_AXIS")) {

/* Read DX,DY,DZ of X Axis Vector */ m = TokenizeString(in_line,"=,",0); PART_COORD_SYS_DX1 = GetFloat(m[1]); PART_COORD_SYS_DY1 = GetFloat(m[2]); PART_COORD_SYS_DZ1 = GetFloat(m[3]);

} /* Look for a "Y_AXIS = ...." line */ else if(MatchString(in_line,"Y_AXIS")) {

/* Read DX,DY,DZ of Y Axis Vector */ m = TokenizeString(in_line,"=,",0); PART_COORD_SYS_DX2 = GetFloat(m[1]); PART_COORD_SYS_DY2 = GetFloat(m[2]); PART_COORD_SYS_DZ2 = GetFloat(m[3]);

} /* Look for a "Z_AXIS = ...." line */ else if(MatchString(in_line,"Z_AXIS")) {

/* Read DX,DY,DZ of Z Axis Vector */ m = TokenizeString(in_line,"=,",0); PART_COORD_SYS_DX3 = GetFloat(m[1]); PART_COORD_SYS_DY3 = GetFloat(m[2]); PART_COORD_SYS_DZ3 = GetFloat(m[3]);

} }

} else { /* Warn user if Attributes File does not Exist */

if(fd_log) Write(fd_log,"Warning : No Attributes File");

else Print("Warning : No Attributes File");

} if(!pdm_id) {

/* Warn user if No PDM data in Attributes File */ if(fd_log)

Write(fd_log,"Warning : NO PDM Id"); else

Print("Warning : NO PDM Id"); } /* Construct PART name to the taste of user */ if(i = MatchSeparators(FILENAME)) {

if(pdm_id) name = FILENAME(:i-1)%"_"%pdm_id; else name = FILENAME(:i-1);

} else {

if(pdm_id) name = FILENAME%"_"%pdm_id; else name = FILENAME;

} /* Finally Assign PART Atributes to ANSA Registers */ PART_NAME = pdm_id; PART_ID = module_id; PART_PROPERTY_ID = property_id;

Page 75: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 75

PART_PROPERTY_NAME = property_name; PART_PROPERTY_THICKNESS = thickness; PART_MATERIAL_ID = material_id; PART_MATERIAL_NAME = material_name; It is clear that the key functions for reading this file is the MatchString and TokenizeString which were discussed in Section 3. Also, the use of registers made the code more compact and easy to read since it was avoided the use of other built in functions which could do the same actions in a more “complicated” way.

5.4.6. Executing functions without any user interaction (autoexec) When ANSA is launched, and the search for an ANSA_TRANSL is finished, ANSA will look for a specialized function called autoexec. This is an optional function that can be located only in an ANSA_TRANSL file and accepts no arguments. If ANSA finds the autoexec function, it will automatically execute any command that is located within, without any further user intervention. Thus, the autoexec can be used to automate any series of command prior to start working with ANSA, for example to define additional user-buttons that will become available to the user as soon as ANSA is launched. In the ANSA_TRANSL that is given below, the autoexec function will instruct ANSA to add a user button titled "my button". When this "my button" is pressed, the "btn_function" is called and, in this case, it will print a "Welcome to ANSA" message. def autoexec() {

AddUserButton("My button", "fun_btn",0); } def fun_btn() {

Print("Welcome to ANSA"); } In order to see the user button and the corresponding message press TOOLS>USER MENU. At the appearing "User Menu" window, press "my button" and the "Welcome to ANSA" message is printed on the Text Window (See section 5.2.4). Important Note: As mentioned, if the autoexec function exist in more than one ANSA_TRANSL files the last one will be executed and all the others will be unloaded. A message then will be displayed in the text window: unloading function: autoexec, in: <path of ANSA_TRANSL that was read before the last one>

Page 76: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 76

Section 6 Script Editor

6.1 Script Editor Layout Script Editor is a fully independent tool, integrated in ANSA, where a user can easily build or test his own scripts. It can be invoked through the SCRIPT>EDITOR>EDIT. The main features of this interface are highlighted and briefly described below.

Main Menu Contains the script editor functions Main Window The area where the code is written or tested Shortcut Keys Buttons for calling the most important edit and debug functions.

The edit functions enable the code modification while the debug functions are used for the identification of syntax or logical errors

Help Output Area

This area has double use. When the Help tab is active it displays the help text of a built in function, while when the Output tab is active it displays any message that is reported from the parser (e.g syntax errors) or from a user script

Dynamic Help List Functions List

This area contains all available built in functions. Additionally, a dynamic help is always displayed whenever a function name is written correctly in the main window

6.2 Opening scripts Every time a new script is imported, a new tab having the name of the script is added next to the

Help tab of main window. There is no restriction regarding how many scripts can be remained opened simultaneously.

6.3 Running scripts

If the script contains a function called main, then every time the F5 button is pressed the script is executed. Otherwise you should go to Project>Run which acts similar to button SCRIPT>FUNCTION>RUN (See Section 5.3.3). If a script has a syntax error then this is reported in the output area.

Main Menu

Main Window

Shortcut Keys

Scripts

Dynamic Help ListFunctions List

Help/Output Area

Page 77: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 77

6.4 Making use of the immediate tab Many times during the development of code there is the need to test a function or a simple line very quickly and with the minimum necessary definitions. Therefore, when the immediate tab is active it is not allowed to have any def statement (See Section 1.8.1) in the code. Consequently, any variable that is written in the global section of the script has no sense. For example in order to test how many spotwelds exist in the database we write: Spots = CollectEntities(NASTRAN,0,"SpotweldPoint_Type"); Print(MatLen(Spots)); Instead of def fun_name() {

Spots = CollectEntities(NASTRAN,0,"SpotweldPoint_Type"); Print(MatLen(Spots));

} Important Note: Scripts made in the immediate environment can be executed normally.

6.5 Help area This area helps the user to find all built in functions either by their category or by their name. A double click on a function displays a help text in the Output Area. Moreover, a Dynamic help tab is always activated every time a function name is written correctly in the main window:

In the above example, the Dynamic help recognized the "CollectEntities" and therefore the necessary parameters were displayed according to their precedence. An arrow on the left of every parameter indicates which argument must be written next. Important Note: Pressing F1 while the cursor is pointing on a built in function name (written in the main window), the respective help text is displayed in the Output Area.

6.6 Compiled scripts For protecting the script code from any external source there is a capability to compile it in a binary format through the Project>Compile. A compiled script can be loaded and run throughout all the normal ways (command line, script menu) while it can be used as an include file too. Furthermore, all the functions that hold can be called from any other script even from uncompiled ones. Important Note: A compiled script cannot be executed through the Script Editor.

6.7 Making or importing snippets Snippets are sections of code or even fully independent functions that can be created or loaded anytime through the editor. The first time a snippet is created, it is saved without any warning in an xml file called snippets.xml. This file is located in the working directory and can hold separately any number of snippets. In this way the user can have a library of functions or code that uses mostly. The easiest way to create a snippet is to mark the code in the main window and then right click to open the context menu.

Page 78: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 78

Pressing the Make snippet option opens the snippet window:

Automatically, the selected code goes to the code section of the window where the user can further edit it. Moreover, a snippet is distinguished from its name and it is stored either in an ANSA or a META snippets list. By default the ANSA tab is active. A snippet can be imported from the Tools>Code snippet option of the main menu. This function opens the previous window where the user can select a snippet from the available list on the left. Selecting it and pressing the Import button, the respective code is inserted into the main window at the cursor position.

Page 79: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 79

6.8 Debugging scripts Scripts can be run in two ways. First, the ‘normal’ run, executes the code directly. Second, is through the debugger which executes the code line by line. In the later case we can pause the execution of a script in order to investigate the status of variables. This is very useful in cases where a script function have logical errors which probably lead to strange results. There are also times that unidentified problematic areas of functions like endless loops or wrong input data result in an infinite execution. All these situations can be traced using the debugger of script editor. Usually, in such cases the first step is to identify the variables that produce the error. If there is no such clue, we select the most important of them. Next, we add them in the watch list which help us to inspect their history during the execution of the script. A variable can be added in the watch list if we right click on it and select the Add watch option.

In the above example the cursor is pointing on variable p and therefore when selecting on the menu that opens the option Add watch: main::p, p is added in the watch list. This list can be displayed pressing the button or through the View>Watch window of the main menu.

This window displays also the variable name, the function where it belongs, its type (local or global) and the current value.

Page 80: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 80

Finally, we must define the lines where the execution of the script will be paused. After each stop we are able to identify in the watch list any change of the variable. Consequently, it is recommended the lines that are selected to be just before or after the variable definition. For letting the editor to distinguish these lines, breakpoints are inserted to them. Having the cursor on a line and pressing the button inserts a breakpoint. On the other hand pressing the button deletes a breakpoint. Whenever a breakpoint is inserted, the respective line is colored red.

For running the function in debug mode the button must be pressed. Alternatively, we can press {Shift+F5} or Project>Debug. Important Note: The name of the function must be "main" Suppose that you would like to trace any changes of matrix p. Insert a breakpoint in line 5 and open the watch window. Press <Shift+F5> to run in debug mode. The execution stops in line 5 and the current status of p is displayed in watch window. From now on every time you press the button or <F10>, the execution continues and stops in each line. Pressing anytime the button , the script runs without stop until the next breakpoint. In our example after the second stop the matrix p changes and now holds the first value which is 20.

Keep pressing or until the execution is finished. Important Note: When the execution stops over a breakpoint the line is colored blue. If the variable that we are looking for is not in the "main" function but in a sub function, the debugger cannot reach it unless we change the way that searches the code. This can be achieved through the buttons and . The first instructs the execution sequence to step into a sub function, while the second to step out of a sub function. Let’s see this with an example:

Page 81: Ansa Scripting

ANSA v.12.1.x Scripting Language

BETA CAE Systems S.A. page 81

Assume we are interested in watching the values of the variable k which is located in sub function foo. For this, we set a breakpoint in a line prior to foo call (line 6) and press <Shift+F5>. The execution stops in this line and from that point we press the button until we get inside foo.

We can return any time to the "main" function pressing .