Anda di halaman 1dari 107

Analysis of Structures

Book of Examples
2011

University of Duisburg-Essen
Faculty of Engineering
Department of Civil Engineering
Structural Analysis and Construction

Dr. E. Baeck

2.12.2011
Contents

I Programming with Python 3

1 How to get started with Python 5


1.1 Python, Packages, Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.1 Installing the Kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.2 Installing the ComType Package . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.3 Installing the NumPy Package . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.4 Installing the SciPy Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.5 Installing the PythonWin IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3 Python Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 Basics in Python 13
2.1 Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 Packages and Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.1 Import of a whole Module or Package . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.2 Selective Import of Module Names . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.3 Import with new Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.1 Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.2 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.3 Bit Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.4 Manipulating Bits and Hexadecimal Numbering System . . . . . . . . . . . . . 16
2.3.5 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3.6 Membership Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3.7 Identity Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4 Print and Output Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5 Basic Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.6 Code Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.7 Loop for Repetitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.8 Branches for Decisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.9 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.10 Data Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.10.1 Working with Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.10.2 Working with Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.10.3 Working with Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.11 Random Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

iii
Page iv Analysis of Structures - WS10/11

2.12 Date, Time and Timespan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38


2.13 Working with Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.13.1 Open a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.13.2 Write Data into a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.13.3 Close a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.14 OOP with Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.14.1 Some UML Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.14.2 Implementation of a Time Stack Class . . . . . . . . . . . . . . . . . . . . . . . 43

3 Python Projects 47
3.1 Newton, Step2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2 Profiles, Thin Walled Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.2.1 Implementation of a general Profile Classes . . . . . . . . . . . . . . . . . . . . 51
3.2.2 Implementation of basic Classes for a Thin Walled Model . . . . . . . . . . . . 56
3.2.3 Implementation of a little Profile Database . . . . . . . . . . . . . . . . . . . . 62

II Scripting with Abaqus 65

4 Some Aspects and Introduction 67


4.1 Aspects of the Abaqus GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2 The Abaqus CAE Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3 A Modeling Chain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.4 A little interactive Warm Up Example . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4.1 Create a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4.2 Create a Sketch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4.3 Create a Part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4.4 Create and Assign Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.4.5 Create the Instance, Assign the Part . . . . . . . . . . . . . . . . . . . . . . . . 71
4.4.6 Create a Load Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.4.7 Create Loads and Boundary Conditions . . . . . . . . . . . . . . . . . . . . . . 71
4.4.8 Create the Mesh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.4.9 Create a Job and Submit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

5 Scripts and Examples 73


5.1 3 Trusses Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.2 U Profile Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

III Appendix 95

A Some Theory 97
A.1 Section Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A.1.1 The Area of a Profile Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A.1.2 First Moments of an Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A.1.3 Second Moments of an Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
A.1.4 Center of Mass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

E. Baeck
CONTENTS Page 1

A.1.5 Moments of Inertia with Respect to the Center of Mass . . . . . . . . . . . . . . 99


A.1.6 Main Axis Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

2.12.2011
Page 2 Analysis of Structures - WS10/11

E. Baeck
Part I

Programming with Python

3
1

How to get started with Python

1.1 Python, Packages, Utilities

If we start with Python, we should think about the choice of the Python version. Because we will use
some additional Python packages, we should be sure, that this packages are available for the desired
Python version. In the case of our lecture we will select the Python version 2.6, which is properly stable
and furthermore all the needed add-on packages are available.

To start from the beginning, we have to download the following packages for windows first. It is rec-
ommended to download the windows installer version, if available because this is the easiest kind of
installation. The installation procedure should start with the installation of the kernel package.

• python-2.6.4.msi
The installer of the python kernel system 2.6.

• comtypes-0.6.2.win32.exe
The installer of Windows types, which are necessary to use Windows API-calls.

• numpy-1.4.1-win32-superpack-python2.6.exe
The installer of the NumPy package for numerical programming.

• scipy-0.8.0-win32-superpack-python2.6.exe
The installer of the SciPy package for sientific programming.

• matplotlib-0.99.3.win32-py2.6.exe
The installer of the MatPlotLib package.

• pywin32-214.win32-py2.6.exe
The installer of a little nice Python IDE.

1.1.1 Installing the Kernel

The python kernel should be the first package, which is to install, because this installation sets up the
Python base folder. Within this folder you can find the folder Lib, which contents a lot of libraries and
additional packages and besides that a further sub folder called site-packages. Add ons are copied into
this folder by their installers or by the install Python script.

5
Page 6 Analysis of Structures - WS10/11

The start screen of the Python installer shows the Python version. You can select, whether the setup
should make Python available for all users or not. After clicking next you’ll get within the second form
the possibility to select the base folder of Python. By default Python uses the folder C:\Python26.
We overwrite the default and select the Windows standard program folder as starting folder, so we write
c:\Programme\Python261 .

The figures 1.1 and 1.2 show the input forms installing the Python kernel.

Figure 1.1: Start Screen of the Python Installer and Choice of Base Folder

Figure 1.2: Selection the Features and Starting the Installation

1.1.2 Installing the ComType Package

If you want to use the Python language on a Windows system, it’s recommended to install the ComTypes
package. This package will give you a simple access to the Windows resources. It can be understood as
a wrapper layer, an interface layer for the access to Windows DLL-modules. ComTypes can be a help to
develop a software with a proper Windows look and feel.

The installation of the most Python packages will run very simular to the following installation. The
figures 1.3 show the first and second form of the installation procedure. The first form gives a few
1
The discussed installation was performed on a German system

E. Baeck
1.1. PYTHON, PACKAGES, UTILITIES Page 7

information to the package. The second form is usually used to select the Python version. Each installed
and supported Python version will be listed in the list box of the second form. You can select the desired
Python version and can go on with the installation procedure clicking the next button.

Figure 1.3: Start Screen of the Package Installer and Choice of the installed Python Version

1.1.3 Installing the NumPy Package

NumPy [2] is the fundamental package for scientific computing in Python. It is a Python library that pro-
vides a multidimensional array object, various derived objects (such as masked arrays and matrices), and
an assortment of routines for fast operations on arrays, including mathematical, logical, shape manipula-
tion, sorting, selecting, I/O, discrete Fourier transforms, basic linear algebra, basic statistical operations,
random simulation and much more.

At the core of the NumPy package, is the ndarray object. This encapsulates n-dimensional arrays of
homogeneous data types, with many operations being performed in compiled code for performance.2

The installation runs like the installation of the ComTypes package (see figure 1.4).

Figure 1.4: Start Screen of the Package Installer and Choice of the installed Python Version

1.1.4 Installing the SciPy Package

SciPy [3] is a collection of mathematical algorithms and convenience functions built on the Numpy ex-
tension for Python. It adds significant power to the interactive Python session by exposing the user to
2
For more details see NumPy User Guide available on the http://info.baustatik.uni-due.de

2.12.2011
Page 8 Analysis of Structures - WS10/11

high-level commands and classes for the manipulation and visualization of data. With SciPy, an inter-
active Python session becomes a data-processing and system-prototyping environment rivaling sytems
such as Matlab, IDL, Octave, R-Lab, and SciLab.

The additional power of using SciPy within Python, however, is that a powerful programming language
is also available for use in developing sophisticated programs and specialized applications. Scientific
applications written in SciPy benefit from the development of additional modules in numerous niche’s
of the software landscape by developers across the world. Everything from parallel programming to web
and data-base subroutines and classes have been made available to the Python programmer. All of this
power is available in addition to the mathematical libraries in SciPy.3

The installation runs like the installation of the ComTypes package (see figure 1.5).

Figure 1.5: Start Screen of the Package Installer and Choice of the installed Python Version

1.1.5 Installing the PythonWin IDE

There are lot of IDEs available for the development of Python software. Most of them are commercial.
One very nice IDE especially for large development projects with a lot of python files is called Aptana.
Apatana is a special version of the free Eclipse IDE. For this IDE there is a plugin available, which is
called PyDev. To use this IDE first you have to install the basis version of Aptana and then you should
install the plugin and select the desired Python version, which should be installed before. An example
project within the Aptana is shown in figure 1.6.

PythonWin is very much simpler than Aptana and has the advantage, that really only the feature are
available that are nessesary to get started with small Python programs. The installation runs like the
installation of the ComTypes package (see figure 1.7).

After having installed the PythonWin IDE it’s recommended to set up a link onto the desktop (see figure
1.8).

3
For more details see SciPy Reference Guide available on the http://info.baustatik.uni-due.de

E. Baeck
1.1. PYTHON, PACKAGES, UTILITIES Page 9

Figure 1.6: Aptana IDE

Figure 1.7: Start Screen of the PythonWin IDE Installer and Choice of the installed Python Version

Figure 1.8: Creating a Link to the pythonwin.exe

2.12.2011
Page 10 Analysis of Structures - WS10/11

1.2 Hello World

Like in every computer language there is a Hello World application in Python also possible. We start
dhe PythonWin IDE and create a new file. We save this file as HelloWorld.py. With Ctrl-R the execution
form is shown and the execution mode should be selected (see figure 1.9).

The following available execution modes are available.

• No debugging,
execution without debugging.

• Step-through in the debugger,


the debugger is stated and starts with the first statement.

• Run in the debugger,


the script is started. Execution is only interrupted at the first breakpoint.

• Post-Mortem of unhandled led exceptions,


the debugger is started, if the script crashes with a unhandled exception.

Figure 1.9: Executing the HelloWorld.py Script

If the HelloWorld.py script is executed, the output is written into the Interactive Window, see figure 1.10.

1.3 Python Calculator

One of Python’s advantages is the feature to execute only one statement within the Python shell. The
Python shell within the PythonWin IDE is given by the Interactive Window, see figure 1.10.

If we want to calculate the vertical position of a ball thrown up in the air with an initial velocity v0 after
a time t we get from the Newton’s law
1
y(t) = v0 · t − · g · t2 (1.1)
2

E. Baeck
1.3. PYTHON CALCULATOR Page 11

Figure 1.10: Executing the HelloWorld.py Script and Console Window

So, if we want to calculate the vertical position for an initial velocity v0 = 5m/s after 0,6 seconds, we
can calculate the y(t = 0, 6) with one simple Python call.

>>> print 5*0.6 -0.5*9.81*0.6**2


1.2342
>>>

A second version of the calculation can be performed introducing and using variables as follows. So we
can check every Python command within the Interactive Window.

>>> v0 = 5
>>> g = 9.81
>>> t = 0.6
>>> y = v0*t - 0.5*g*t**2
>>> print y
1.2342
>>>

A third version of our calculation of the ball’s height could be a Python script, which we can load and
executed within the PythonWin IDE. To comment the code we insert some comments, which starts with
the # character. Characters at the right side of the # character are ignored by the Python interpreter.

First small Example

# program for computing the height of a ball thrown up in the air


v0 = 5 # initial velocity
g = 9.81 # acceleration of gravity
t = 0.6 # time
y = v0*t - 0.5*g*t**2 # vertical position
print y # printing the result
End of Coding

2.12.2011
Page 12 Analysis of Structures - WS10/11

E. Baeck
2

Basics in Python

2.1 Reserved Words

We have seen in section 1.3, starting with a Python calculation within the Python shell is very easy. We
can use simple formulas with numbers or we can use symbolic names to make it more readable. In
Python like in other programming languages there are some reserved word, which are used to build up
the language. This words can not be used as variable names.

The reserved words of the Python language are the following.

and del from not while


as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try

If you want to use such a word it’s recommended to extent the name with an underscore, like vor example
break_ instead of break.

2.2 Packages and Modules

A package within Python is a container of software objects, global variables, functions and objects. In C
or Fortran, a package could be termed as library.

Packages should be imported into the Python session or into the Python source file, if external feature
should be used. A typical package import is the import of the mathematical package. This is necessary
if you want to call some basic mathematical functions like trigonometric functions or the square root. If
such a package is not imported, it’s objects, especially it’s functions, are unknown and can not be used.

Packages are like header includes within the C language. In C as well, external functions, whose headers
are not included, are unknown and can not be called.

13
Page 14 Analysis of Structures - WS10/11

2.2.1 Import of a whole Module or Package

A whole package is imported with the statement "import" module. The following example shows
the import of the mathematic package to apply the square root function. With the import statement the
module math will be linked. The square root function sqrt will be then available with the usual dot access
math.sqrt.

>>> import math


>>> math.sqrt(4)
2.0
>>>

2.2.2 Selective Import of Module Names

If we only want to import a symbolic name of a module (package), then we can import in a selective
way. The nex example shows the selective import of the function sqrt from the module math. If we do
this, then the function can be used without the prefixing module name.

>>> from math import sqrt


>>> sqrt(4)
2.0
>>>

2.2.3 Import with new Names

If some names of of module should be imported with new names, the statement as can be used within
the import statement. The following example shows the import of the trigonometric functions sin and
cos with the new names s and c and the constant pi with it’s original name, to calculate the Cartesian
ordinates of a 45◦ point with radius 10.

>>> from math import sin as s, cos as c, pi


>>> r = 10
>>> x = r*c(pi/4)
>>> y = r*s(pi/4)
>>> x
7.0710678118654755
>>> y
7.0710678118654746
>>>

You see, that we change the original name of the trigonometric functions with the as key word. Within
the formulas the functions can be used with it’s new names.

2.3 Operators

We have already seen, that Python also has it’s operators calculation the height of a vertical thrown
ball. Python uses the same precedence as we know form the mathematics. The power operation has the
strongest binding followed by the point operators (products and divisions) followed by the line operators

E. Baeck
2.3. OPERATORS Page 15

(plus and minus). Unary operators will always be applied first. To change the standard precedence of the
operators we use like in mathematics parenthesis to dictate the way a formula should be evaluated.

2.3.1 Unary Operators

Unary operators are working only on one value, therefor unary. In Python there are three unary operators
available.

Operator Comment Example


+ plus operator a = 2 >>> x = +a >>> +2
- minus operator a = 2 >>> x = -a >>> -2
˜ bitwise inversion a = 2 >>> x = ˜a >>> -3

The bitwise inversion shows the internal representation of negative numbers. A negative number is
represented by the so called b-complement of a number. This is the complement, i.e. the bitwise inverted
number plus 1. So we get

−a =∼ a + 1 or ∼ a = −(a + 1) (2.1)

2.3.2 Arithmetic Operators

Python offers the following arithmetic operators. You should be careful with the usage of data types
especially within divisions. If you use integers, the result generally will be truncated.1

Operator Comment Example


+ sum operator x = 2+3 >>> 5
- substraction operator x = 4-2 >>> 2
* product operator x = 2*4 >>> 8
/ division operator x = 9/2 >>> 4
x = 9./2. >>> 4.5
** power operator x = a**2
% modulo operator x = a%2
// integer division operator x = a//2

2.3.3 Bit Operators

Like in C bit operators can be easily be used to manipulate a number’s bits. The following operators are
available2
1
The exception of the power operator all the arithmetic operators are used with the same symbol like in C. In C there is no
power operator available.
2
Python’s bit operators are exactly the some as the C bit operators.

2.12.2011
Page 16 Analysis of Structures - WS10/11

Operator Comment Example


& bitwise AND x = 23 & 13 >>> 5
ˆ bitwise exclusive OR x = 23 ˆ 13 >>> 26
| bitwise OR x = 23 | 13 >>> 31
<< left shift of bits x = 4 << 2 >>> 16
>> right shift of bits x = 4 >> 1 >>> 2

The left shift of a numbers bit by 1 is equal to a multiplication by 2. The right shift by one is the same as
a division by 2. The bitwise AND and OR operator are usually used to set or to clear a number’s bits.

The following example shows how to apply the shift operator. We start with the bit 0, which has the
value 1. Within a for loop (see section 2.7) the bit is shiftet subsequently to the left. So we create the bits
in the range from n to m. After shifting the bit, it’s value is printed into the console window.

List the Bit’s Values

# print the value the bits from bit n to bit m


#
n = 1
m = 10
bit 0 = 1
for i in range(n,m+1):
bit i = bit 0 << i
print "Bit %2d = %6d" % (i,bit i)
End of Coding

2.3.4 Manipulating Bits and Hexadecimal Numbering System

If we want to manipulate a number’s bits it is obvious more clearly to use the hexadecimal representation
of a number as using the elsewhere usual decimal representation. Hexadecimal numbers starts with the
literal 0x3 and uses the digits 0-9 and A-F. F is with 15 the largest digit of the hexadecimal numbering
system. The hexadecimal numbering system has the advantage, that it packs 4 bits of a number into one
hexadecimal digit. So a byte can be represented by 2 hexadecimal digits. If we now be able to translate a
hexadecimal digit into a binary number, then we can see even the bits in the largest number without any
calculation.
In the following example we want to analyze the arbitrary number 27563. The bits are obviously very
hidden using the decimal representation. To get a hexadecimal representation we can simple print the
number using the X formating. We can see that we obviously use two bytes for this number, because wie
get 4 digits (6BAB). Furthermore we can see, that the leading bit is not set, because the largest digit is 6
and the highest bit in a digit has the value 8.

3
A binary number starts with the literal 0b and uses the digits 0 and 1, like 0b1000 = 810 .

E. Baeck
2.3. OPERATORS Page 17

>>> a = 27563
>>> "%X" %a
’6BAB’
>>>

The binary number representation is easily available from the hexadecimal representation, if we know
the binary representation of the hexadecimal digits4 .

616 = 610 = 4 + 2 = 01102


A16 = 1010 = 8 + 2+ = 10102
B16 = 1110 = 8 + 2 + 1 = 10112

So we get assembling the binary digits of 6BAB the following bit sequence.

2756310 = 6BAB16 = 0110|1011|1010|10112 (2.2)

If we now want to set the highest bit of the discussed number, we can use the bitwise OR operator | (see
section 2.3.3). A number with only the highest bit set we can obtain by shifting the first bit to the desired
position within the 2 bytes, i.e. we shift the bit 15 times. Now we can see that we get a hexadecimal
number with only the highest digit non vanishing. Within the digit of 8 the forth bit is set, which is the
highest of a have byte5 .

>>> b = 1
>>> b = b<<15
>>> b
32768
>>> "%X" % b
’8000’

If we now want to set the highest bit of our original number 27563, we simple can overlay it with the last
number 8000.

>>> a = 27563
>>> b = a | (1<<15)
>>> b
60331
>>> "%X" % b
’EBAB’

After having set the highest bit, we see that the decimal number has changed totally. However the
hexadecimal number only changes in the first digit. Instead of 6 we have now E. And E is represented
binary with

E16 = 1410 = 8 + 4 + 2 = 11102

so we get

6033110 = EBAB16 = 1110|1011|1010|10112 (2.3)


4
The index of the example’s numbers represent the base of the numbering system.
5
A half byte is also called nibble.

2.12.2011
Page 18 Analysis of Structures - WS10/11

Comparing the binary result with the binary result of equation 2.2 we see that obiously only the first bit
is set as wanted.

How we can now clear a bit of a number? Clearing a bit of a number uses two steps. First we have to
create the inverse of the filtering number, having set only the desired bit. And within a second step we
use the AND operator & to overlay bitwise the inverse of the filtering number and the number, whose bit
should be cleared. In our example we want to clear the highest bit of the first byte. The filtering number
we get shifting the 1st bit 7 times.

>>> a = 27563
>>> b = a & (˜(1<<7))
>>> b
27435
>>> "%X" % b
’6B2B’

We also notice, that the decimal representation has changed widely after the clearing of the bit on the
contrary to the hexadecimal.

2743510 = EB 2B16 = 1110|1011|0010|10112 (2.4)

2.3.5 Comparison Operators

Boolean operators are used to branch and to make decisions. The comparing operators are identical to
the C comparing operators.6

Operator Comment Example


< less than x = 23 < 13 >>> False
<= less equal x = 23 <= 23 >>> True
> greater x = 23 > 13 >>> True
>= left shift of bits x = 23 >= 23 >>> True
== equal x = 23 == 23 >>> True
<> equal x = 23 <> 13 >>> False
!= non equal x = 23 != 23 >>> False

The result of a boolean expression like above are the boolean values False or True. To combine
comparing expressions the following logical operators can be used.7

Operator Comment Example


and logical and x = 1 < 2 and 2 < 3 >>> True
or logical or x = 1 < 2 or 2 > 3 >>> True
not logical not x = not (1 < 2) >>> False
6
There are two non equal operators available. ! = is the C version and <> is the Basic version.
7
To make expressions clear parenthesis should be used. A term within a parenthesis is evaluated first and it’s result then is
used in further evaluations outside the parenthesis. With parenthesis the order of the evaluation can be set.

E. Baeck
2.4. PRINT AND OUTPUT FORMATS Page 19

The truth table for the AND operator ∧ is given as follows.

True ∧ True = True (2.5)


True ∧ False = False
False ∧ True = False
False ∧ False = False

The truth table for the OR operator ∨ is given as follows.

True ∨ True = True (2.6)


True ∨ False = True
False ∨ True = True
False ∨ False = False

2.3.6 Membership Operators

With the membership operators you can check whether a value or an object is part of sequence of objects.

Operator Comment Example


in is member x = 2 in (1,2,3) >>> True
not in is not a member x = 2 not in (1,2,3) >>> False

2.3.7 Identity Operators

With the identity operators you can check the identity of two objects.

Operator Comment Example


is is identical x = (1,2) >>> y = x >>> x is y >>> True
is not is not identical x = (1,2) >>> y = x >>> x is not y >>> False

2.4 Print and Output Formats

If you want to print data into the console window, you have to think about formating. The formating
sequences are very similar to the formating sequences of the C printf function. The formating is a so
called escape sequence within a string, which is started with the % operator.

The most common formats are the following.

• formating an integer
An integer (independent of the data type) is formated by the escape %d for decimal representation
and %x or %X for hexadecimal representation.

• formating a float
A float is formated by the escapes %f, %e, %E, %g and %G

2.12.2011
Page 20 Analysis of Structures - WS10/11

• formating a string
A string is formated by the escapes %s

A leading number n within a format %nT, with T the type of the format, sets up the width of the output.
The following example shows the formating of an integer in decimal and hexadecimal mode. At the
hexadecimal format a lower x sets lower digit letter, the capital X sets capital digit letters.

>>> "%d,%3d,%6d" % (2,2,2)


’2, 2, 2’
>>> "%x,%3X,%6X" % (31,31,31)
’1f, 1F, 1F’

Formating floats there are two different formats available, the fixed format and the exponential format,
which is also called scientific format. The f format sets a non exponential representation. The e or E
format sets a exponential format. e uses a small e letter, and E uses a capital E letter. The g or G format
sets an optimized representation, i.e. a fixed or an exponential format, depending on the outputs length.
The number after the dot sets the number of digits after the comma for f and e format, it sets the number
of significant digits for the g format.

>>> "%f,%e,%g" % (12.34,12.34,12.34)


’12.340000,1.234000e+01,12.34’
>>> "%.2f,%.2e,%.2g" % (1234567.89,1234567.89,1234567.89)
’1234567.89,1.23e+06,1.2e+06’

2.5 Basic Data Types

Recording to the available data types, Python is very different comparing it with common languages like
C, Fortran and Basic. Most of the languages offers the programmer data types, which are one by one
related to the underlaying hardware.

So for example Fortran and C offer 2 and 4 byte integers on 32 bit operating systems by default8 On a
64 bit operating platform a long integer of 8 bytes will be available. On the other hand there are 4 and 8
byte floats available.

Python however offers on 32 bit platforms a normal integer of 4 bytes, which is directly related to the
hardware, for example 11234, and furthermore a so called long integer, for example 1234L, which is
handled by the Python software. The long integer, which is marked by a succeeding L, is only restricted
by the computers memory, that means that a really incredible number of digits can be considered. Later
we will calculate the factorial of a incredible high number.

Furthermore Python as already mentioned offers only one float data type with 8 bytes. The standardized
4 byte float is not supported, for example 1.23 or 1.23e+2.

Python also supports a complex arithmetic with an complex data type, consisting of two floats for real
and imaginary part of the complex number. The complex unit in Python is called j. Therefor the complex
number 1 + 4i will be represented in Python with 1 + 4j .
8
That means without applying provider depended tricks.

E. Baeck
2.6. CODE BLOCKS Page 21

The last data type used in Python is a string consisting of one or more characters.

The data type of a variable can be determined using the build in function type, as shown in the following
example. Within a first step different variables were created by a simple assignment. The content of the
variable determines the type of the variable, no explicit declaration is needed or available, like in C. After
having created the variables the type of the variables will be determined by subsequent type calls.

To check the data type within a program the following tests can be made.

1. if type(d).__name__ == ’int’
You can check the type with the types __name__ member.

2. if type(d) == int
... or you can check the type with the type class name (discussed later).

>>> a = 2
>>> b = 3L
>>> c = 4.5
>>> d = 6 + 7j
>>> e = "Hello World"
>>> type (a)
<type ’int’>
>>> type (b)
<type ’long’>
>>> type (c)
<type ’float’>
>>> type(d)
<type ’complex’>
>>> type(e)
<type ’str’>

You see, ’int’ is integer, ’long’ is long integer, ’float’ is float, ’complex’ is complex and
’str’ is string data type.

Furthermore there are some sequences in Python available, which combines the mentioned data types in
a more or less sophisticated mode. More about that later.

2.6 Code Blocks

One very imported feature of Python is, that code blocks are bracketed by an unique indent. The most
programming languages uses there specific code parenthesis. There is one opening parenthesis which
starts the code block and there is one closing parenthesis, which closes the code block.
The following example shows a code block in C.

if (a > b)
{
c = a + b
d = a - b
Further Lines of C-Code
}

2.12.2011
Page 22 Analysis of Structures - WS10/11

The following example shows a code block in Fortran77.

if (a .gt. b) then
c = a + b
d = a - b
Further Lines of Fortran-Code
endif

Compared with this in Python the code block is bracketed by indent as follows.

if a > b:
c = a + b
d = a - b
Further Lines of Python-Code
a = b

One statement which uses a code block, in this case an if statement, is closed by a colon. After the colon
an unique indent for the lines of the code block must be used. If not, it will be a syntax error. The code
block is closed, if the last line of the code block is the last line of the whole code, or is closed by a line
of code which is indented like the opening statement. In our example the assignment a=b has the same
indent as the if statement and so this line will be the first line of code outside our code block.

2.7 Loop for Repetitions

Like all programming languages, which make sense, Python also has some implementations of repe-
titions, of loops. Like in C an explicit loop is available - the for loop - as well as an implicit loop is
available - the while loop.

The for loop is controlled by an iterated set. One very common variant is the for loop, which is controlled
by an iteration counter. The iteration counter will be configured by a range object. The range object has
3 parameters9 . The first parameter sets the start value of the iteration counter, the second parameter sets
up the iteration value, which will be the first value that is not performed. The third parameter sets up the
increment.

The following typical example for the usage of an iterative for loop implements the calculation of the
factorial.

n
Y
n! = i (2.7)
i=1

The implementation of the factorial is given below. Note the importance of the indent, see section 2.6.

9
A parameter is a information unit, which is passed to the called object. If more then one parameter is passed, the parameters
are separated by commas.

E. Baeck
2.7. LOOP FOR REPETITIONS Page 23

n = 10 # factorial input
p = 1 # result variable must be initalized by 1
for i in range(2,n+1): # the counter runs from 2 up to n
p *= i # here we perform the product
print "%3d! = %10d" % (n,p) # write the result into the console

>>>... console window ...


10! = 3628800

The second loop type, the while loop is working implicit with a boolean expression, which controls the
break condition. If we want to implement the factorial using the while loop we get the following code.

n = 10 # factorial input
p = 1 # result variable must be initalized by 1
i = 2 # the counter runs from 2 up to n
while i <=n: # loop with break condition
p *= i # perform the product
i += 1 # explicit incrementation
print "%3d! = %10d" % (n,p)

>>>... console window ...


10! = 3628800

The next example shows a nested loop. Very important is the correct code block indent.

for i in range(0,4): # outer loop


for j in range(0,2): # inner loop
print "i:%2d, j:%2d" % (i,j) # print counter variables

>>>... console window ...


i: 0, j: 0
i: 0, j: 1
i: 1, j: 0
i: 1, j: 1
i: 2, j: 0
i: 2, j: 1
i: 3, j: 0
i: 3, j: 1

For the detailed controlling of the loops cycles two statements are available.

• continue
If the continue statement is used a cycle is immediately stopped and the next cycle is started.

• break
If the break statement is used a cycle is immediately stopped and the loop is exited.

The next example shows an application of the continue statement. A loop is performed with the values
0 · · · 4. The cycle with the counter 2 is prematurely canceld.

2.12.2011
Page 24 Analysis of Structures - WS10/11

>>> for i in range(0,5):


... if i == 2: continue
... print "i=%d" % i
...
i=0
i=1
i=3
i=4

One very interesting feature of Python is the long integer arithmetic. So we can calculate incredible large
factorials. Figure 2.1 shows the code in the upper window. The console window shows the result. A
number with a lot of digits and every digit is exact.

Figure 2.1: Calculating the Factorial for a long integer

The next example shows the calculation of the factorial using a float. The float factorial can only be
evaluated up to 170! = 7.25742e+306. In the case of 400! we will get an overflow, because the
exponent exceeds the available memory in 8 bytes (see figure 2.2).

E. Baeck
2.8. BRANCHES FOR DECISIONS Page 25

Figure 2.2: Calculating the Factorial for a float

2.8 Branches for Decisions

Decisions are made by the usage of the if statement. The if statement is defined as follows.

if [boolean expression 1]:


code block 1
elif [boolean expression 2]:
code block 2
elif [boolean expression 3]:
code block 3

...
else
code block else

The calculation of roots of a quadratic equation is a nice and simple example to show the application of
the if statement. The quadratic equation is given by

a · x2 + b · x + c = 0 (2.8)

If we want to solve the quadratic equation, we have to analyze the available cases. A general solution
must handle the following cases.

• constant case
a=b=c=0

• linear case
a = 0, b 6= 0

• quadratic case
a 6= 0

• no solution case
a = b = 0 and c 6= 0

2.12.2011
Page 26 Analysis of Structures - WS10/11

The implementation uses a real arithmetic importing the module math. The solver of the quadratic
equation is implemented in a function called QuadSolve. The function analyzes the different cases and
returns in the constant case only a comment, in the linear case the solution value and a comment. In the
quadratic real case 2 values and a comment were returned and in the complex quadratic case there are 4
return values and a comment. All return values are packed into a tuple. The case can be identified form
the calling program using the function len, which returns the number of items of a tuple. To avoid the
testing for zero, which would produce numerical problems in principle, we set the relative precision to
10−15 . An absolute value less then this relative precision is treated as zero value.

Quadratic Equation Solver

’’’
solution of a quadratic equation
- handling all special cases -
’’’
# import the used functions
from math import fabs as abs, sqrt

def QuadSolve(a,b,c):
p = 1.e-15 # precision of float, is used to
# avoid to test for zero with ==
# case: a=0
if abs(a) < p:

# case: b=0
if abs(b) < p:

# case: c=0
if abs(c) < p:
return ("Infinit number of solutions.",)

# case: c!=0
else:
return ("No solution possible.",)

# case b != 0 (linear case)


else:
x = -c/b
return (x, "Linear case found.")

# case a != 0 (quadratic case)


else:
d = b**2 -4.*a*c

# real case
if d >= 0.:

E. Baeck
2.8. BRANCHES FOR DECISIONS Page 27

s = sqrt(d)
x1 = 1./(2.*a)*(-b +s)
x2 = 1./(2.*a)*(-b -s)
return (x1,x2,"Real case of the quadratic problem.")

# complex case
else:
s = sqrt(-d)
x1r= -b/(2.*a)
x2r= x1r
x1i= s/(2.*a)
x2i=-x1i
return (x1r,x1i,x2r,x2i,"Complex case of the quadratic problem.")

# -------- main program -------------------


# input section
a = 1.
b = 0.
c = 4.

# call of QaudSolve function


result = QuadSolve(a,b,c)

# check the result tuple, to select the found case


values = len(result)
print "%d values found in return" % values

# format the found result case


# no or infinit solution(s)
if values == 1:
print result[0]

# linear case
elif values == 2:
print "x = %f, info: %s" % result # (result[0],result[1])

# real quadratic case


elif values == 3:
print "x1 = %f, x2 = %f, info: %s" % result

# complex quadratic case


elif values == 5:
print "x1 = %f+(%fi), x2= %f+(%f), info: %s" % result
End of Coding

2.12.2011
Page 28 Analysis of Structures - WS10/11

The return values are packed into a tuple (see section 2.10.1). The tuple is used in the set order. So we
can use it for the string format. Reordering is not needed. The output into the console window is the
following for the selected test example.

x1 = -0.000000+(2.000000i), x2= -0.000000+(-2.000000i),


next> info: Complex case of the quadratic problem.

2.9 Functions

A function is a callable type. A function starts with the def command. The parameter list succeeds the
function name and consists of names separated by commas. The return of return values is optional. A
nice example to study cases of a solution and their specific return values is discussed in section 2.8.

def <name> (Parameter list):


Code Block
return <Return Object list>

The following code shows a special version of the abs function. The data type is checked first. Only int,
long or float type are senseful supported. We check the type with the type function. The type function
returns a type object. Within the function we check the object member __name__. If the type is not
supported, a error string is returned. If the type is supported, the return value is return. The calling
program checks the return values type using the object name (int, long and float).

Abs Function with Type Checking

# declaring our version of an abs function


def MyAbs(x):
# process only sensful data types
# here we use the type class member name
# to check the data type
t = type(x). name
if t != ’int’ and t != ’long’ and t != ’float’:
return "Error: Type ’%s’ is not allowed." %t

# if data type ok change sign if necessary


if x < 0.: return -x
return x

# input section
y = -4 # test 1
# y = "hello" # test 2

# function call
z = MyAbs(y)

# get return type

E. Baeck
2.9. FUNCTIONS Page 29

t = type(z)
if t == str: # second version to check the type
print z # print error message
else:
print "Absolute Value of %f = %f" % (y,z) # print result
End of Coding

The following example shows, how to pass a function as


a functions parameter. Within the Newton’s algorithm
a root of an equation should be calculated. So we have
to specify the function of interest. This function can be
considered as an input parameter. This function name
is passed to the derivative calculator and to the newton
main routine. Further we see, that it’s recommended to
use standard parameter, to configure the algorithm. We
introduce the precision parameter e, which sets up the
threshold for a zero compare. Further we need the step
width to calculate the derivative of the function of our
Figure 2.3: Scheme of the Newton Algorithm
interest.

The derivative - it’s called fs in the code - is calculated numerical as follows.


 
0 df h h
f (x ) = ≈ f (x + ) − f (x − ) /h
dx 2 2
(2.9)

The Newton scheme can be described as follows.


f (x )
xi+1 = xi − (2.10)
f 0 (x )

There are three possible situations to handle within the iteration loop.

• The function value is vanishing with respect to our selected precision. The iteration loop will be
broken and the found result is passed back to the caller.

• The slope of the function is vanishing. This situation can not be handled by the simple iteration
scheme. The iteration will be broken with an error message.

• During the iteration each cycle is counted. So the iteration loop will be broken, if the maximum
available iterations are reached. The actual values and an error message is passed bake to the caller.

The code consists of the following functions.

• Myf, the function of our interest.

• fs, the function which calculates the slope of a given function numerically.

2.12.2011
Page 30 Analysis of Structures - WS10/11

• newton, implements the newton scheme.

Implementation of Newtons Algorithm

from math import fabs as abs # import the fabs as abs

# implementation of the function of interest


def Myf(x):
return x**2 +1.

# calculating the derivative


def fs(f,x,h=1.e-6):
h = float(h)
x = float(x)
return (f(x+0.5*h) - f(x-0.5*h))/h

# implementation of a newton algorithm


def newton(f,x0,e=1.e-10,h=1.e-6,imax=100):

error = None # initialize the error code with None

h = float(h) # we need some floats


e = float(e)
x1= float(x0) # x to interate

i = 1 # iteration counter
while True:

f0 = f(x1) # function’s value


if abs(f0) < e:
break

# calculating the derivative


f1 = fs(f,x1,h)
if abs(f1) < e:
error = "*** Error: vanishing derivate!"
break

# available iterations exceeded


if i >= imax:
error = "*** Error: no root found!"
break

# calculating the values for next iteration


x1 -= f0/f1

E. Baeck
2.9. FUNCTIONS Page 31

# increment the iteration counter


i+=1

# return the actual position, the function value


# and the functions slope, the number of performed
# iterations and the error code.
return (x1,f0,f1,i,error)

# the function newton is called with standard parameters


# we pass the function of interest and a supposed start
# position
res = newton(Myf,4.)

# the returned tuple is printed into the console window


print res
End of Coding

2.12.2011
Page 32 Analysis of Structures - WS10/11

2.10 Data Sequences

In Python there are some sequential data types available.

• Strings, a list of characters.

• Tuples are fixed sequences, which are only extensible. The advantage of tuples is the performance.

• Lists are changeable sequences but with lower performance.

2.10.1 Working with Tuples

The following example shows the creation of a tuple. An empty tuple is declared. We extend the tuple
with a one element tuple - note the comma. The second extension extends the tuple with a two element
tuple.

>>> t = () # initialize the tuple


>>> t
()
>>> t += (1,) # append the tuple with a number
>>> t
(1,)
>>> t += (2,3) # append at tuple with a second tuple
>>> t
(1, 2, 3)
>>> t[0] # calling the tuple’s first element
1
>>> t[2] # calling the tuple’s third element
3
>>> t[3] # an error occur, if the index goes out of range
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
IndexError: tuple index out of range
>>> len(t) # the number of elements is given by the len function
3

Note, that tuples are input data for complex string formatings.

>>> "x1 = %8.2f, x2 = %8.3f" % (12.3456,12.3456)


’x1 = 12.35, x2 = 12.346’

With the function tuple() a tuple can be created from an iterable object like string or list.

>>> T =tuple([1.,2.])
>>> T
(1.0, 2.0)
>>> L = list(T)
>>> L
[1.0, 2.0]
>>> T = tuple("Hello World")
>>> T
(’H’, ’e’, ’l’, ’l’, ’o’, ’ ’, ’W’, ’o’, ’r’, ’l’, ’d’)

E. Baeck
2.10. DATA SEQUENCES Page 33

Note, that the data of a list can be converted into a tuple using the function tuple() and reverse into a
list using the function list().

2.10.2 Working with Lists

Lists are more flexible as tuples. Creating and extending lists can be coded like in the case of tuples.
The only difference is, that lists uses in their declaration the [..] parenthesis. So using lists the code
example of the section 2.10.1 can be coded like follows.

>>> L = {] # initialize the list


>>> L
[]
>>> L += [1,] # append the list with a number
>>> L
[1,]
>>> L += [2,3] # append at list with a second list
>>> L
[1, 2, 3]
>>> L[0] # calling the lists first element
1
>>> L[2] # calling the list’s third element
3
>>> len(L) # the number of elements is given by the len function
3

You can read somewhere, that tuples are much more faster than lists. This is surely not valid for every
problem. So it’s recommended to check the performance explicitly before you decide to use tuples or
lists.
The list object offers a wide set of methods. Some of them are discussed in the following table.

Methode Comment Example


append(i) Append an item to the list. Same as += operator. L.append(3)
count(x) Counts the value x in the list. L.count(1.2)
extend(s) Append a list to the list. Same as += operator. L.extend(t)
index(x) Evaluates the lowest index of the value x in the list. L.index(1.2)
insert(i,x) Inserts the object x before the item i. L.insert(2,1.2)
pop() Returns the last item and deletes it from the list. L.pop()
remove(x) Removes the first item with the value x. L.remove(1.2)
reverse() Invert the order of the items of a list. L.reverse()
sort() Sort the items of list in ascending order. L.sort(t)

2.12.2011
Page 34 Analysis of Structures - WS10/11

A very important data object or container class which is used espe-


cially from the compiler to implement function calls is called stack.
A very common error situation is the so-called stack-overflow error.
This error will occur especially, if functions are called recursively. In
this case the return addresses are pushed to the stack to remember the
way back. If an address should be read from the stack, the address is
poped form the stack, which means, that the last value is read and this
Figure 2.4: Stack Operations
last value is removed from the stack.10 A stack is also called LIFO,
i.e. Last In First Out.

Figure 2.5 shows the history of a stack in use.


Onto the empty stack the H is pushed. The the
e, the l and the o are pushed. After that the o is
poped, that means the element is returned to the
caller and removed from the stack. With two fur-
ther pops the elements l and e are removed from
the stack. A further push stores the w on the stack.
After two pops the w and the e are removed. The Figure 2.5: Stack Example
H remains on the stack

Now, how can we implement a stack with basic Python? We simply need a list instance with the two
functions append(), which implements the Push and pop() which implements the Pop of a stack.

2.10.3 Working with Dictionaries

A dictionary is a powerful and very general container, it’s also called map, because a key value is mapped
onto the pointer of the stored item. In Python an instance pointers is stored in a dictionary using an
arbitrary key strings. So a dictionary is like a list container with a more general access. Because the
dictionary commonly hashes the key information onto some smaller index lists, the dictionary commonly
has a better performance as a linked list container. The dictionary therefore is used in the abaqus class
library (we will discuss it later) to store named instances.

A dictionary can be created like a list using curled parenthesis. Each key-value pair is separated by a
comma. The key is separated from the value by a colon.

10
If we save data on a stack, it’s called push data onto the stack. If we take data from the stack, it’s called pop data from the
stack.

E. Baeck
2.11. RANDOM NUMBERS Page 35

>>> myDict = {’first item’:1, ’second item’:2}


>>> print myDict[’second item’]
2
>>>
>>> beatles = {}
>>> beatles[’drums’] = ’Ringo’
>>> beatles[’bass’] = ’Paul’
>>> beatles[’vocal’] = ’John, Paul’
>>> beatles[’guitar’] = ’George, John’
>>> print beatles
{’guitar’: ’George, John’, ’vocal’: ’John, Paul’, ’bass’: ’Paul’,
’drums’: ’Ringo’}
>>>

2.11 Random Numbers

Because a computer is system, which works systematically reproducible, a computer will not be able to
create real random numbers. If we start a program twice with exact the same input values, the result also
will be the same. But with a little trick, we can produce so called pseudo random numbers. If we use
the time as input for the initialization of our random number generator, we will be sure, that it will be
extremely improbable, to get twice the same random number set.

So every programing language has it’s own random number generator. Python offers us a build-in pack-
age, which is called random. Like in C the random number generator is to initialize with a function
seed(). This function uses the computer time information to make varying starting conditions.

The following example will discuss two features of the Python library.

• How can we use the random package to create random numbers or to create a random order of
lists, i.e. shuffle the list’s data.

• How can we create simple 2d diagram plots using the matplotlib package.

The example code consists of three sections.

• At the beginning the lists xPos and yPos are filled with random numbers. This random x and y
values are interpreted as point coordinates. Two subsequent points are joint by a line.

• Within a second step the list’s element are sorted. The result is plotted again. The result is an
increasing function.

• Within the third step the sorted lists are shuffled by the random package. The random order of the
random numbers is plotted again.

Figure 2.6 shows the walk for random points (blue line), for sorted points (red line) and for shuffled
points (green line). The left figure shows the content of the created png file, the right figure shows the
plot within the viewers window.

Random Walk visualized with two Lists of Random Numbers

2.12.2011
Page 36 Analysis of Structures - WS10/11

Figure 2.6: Random, Sorted and Shuffled Walk

import random # import the random package


import pylab # part of matplotlib

# create random ’count’ numbers in the range [lower:upper]


# a list is returned to the caller
def GetRandomNumbers(lower,upper,count):
random.seed() # initialization of random number generator

numbers = []
for i in range(count):
r = lower + (upper-lower)*random.random()
numbers.append(r)
return numbers

# main program ------------------------------


L = -10. # lower bound
U = +10. # upper bound
xN = 100 # number of randoms

# random positions
xPos = GetRandomNumbers(L,U,xN) # ...in x-direction
yPos = GetRandomNumbers(L,U,xN) # ...in y-direction

# creating plot of original random values xPos/yPos


pylab.plot(xPos,yPos,"b")

# sort the random values


xPos.sort()
yPos.sort()

E. Baeck
2.11. RANDOM NUMBERS Page 37

# creating plot of sorted values xPos/yPos


pylab.plot(xPos,yPos,"r")

# create a random order


random.shuffle(xPos)
random.shuffle(yPos)

# creating plot of the shuffeled values xPos/yPos


pylab.plot(xPos,yPos,"g")

# save the plot in a figure using an png-format


pylab.savefig("RandomWalk.png")

# plot a figure in the matplotlib viewer


pylab.show()
End of Coding

2.12.2011
Page 38 Analysis of Structures - WS10/11

2.12 Date, Time and Timespan

Date and time functions in common are very important and therefor Python supports this with a stan-
dard package datetime. Within this package you will find some very simple and powerful objects and
functions.
The package is loaded with the following statement. We load from datetime the subpackage datetime
and set the alias name time. The second line shows, how to get the actual time. The datetime object
contents from the left to the right the year, the month, the day, the hour, the minutes, the seconds and
the microseconds. Because the computer does not support microseconds but milliseconds the measured
milliseconds are multiplied with the factor 1000.

>>> from datetime import datetime as time


>>> time.now()
datetime.datetime(2010, 11, 4, 19, 25, 33, 15000)

To implement some performance checking code it is very useful to have a timespan, which is the dif-
ference of two datetime objects. The timespan object is called timedelta and is as well an object of the
datetime package.
If we now want to check the performance of a code snippet, we will implement the following code.
First we have to import the datetime package. Then we get the actual time and assign this object to the
variable t1. Then the code to check follows. Within a last step we again create a datetime object calling
the time.now() function and assigning the object to the variable t2. If we subtract t1 from t2 we
will get a timedelta object. The timedelta objects contents the number of days, the number of seconds
and the number of microseconds of the time difference.

from datetime import datetime as time


t1 = time.now()
... our code snippet ...
t2 = time.now()
t3 = t2 -t1
print t3
>>> datetime.timedelta(0, 12, 906000)

If we want to have the time difference in seconds, we have to write a little function, which adds all this
time parts in the unit second. If we suppose, that T is a valid timedelta object, we extract the seconds with
the seconds attribute and assign it to our seconds variable. The next part handles the microseconds.
We divide them by 106 and add the part to the seconds variable. The last part calculates the seconds of
the given hours and add this value to our second variable. The value is returned to the caller.

def GetTimeSpanInSeconds(T):
secs = float(T.seconds)
secs += float(T.microseconds)/1.e6
secs += float(t.days)*24.*60.*60.
return secs

One very important application of the timedelta object is the measurement of a program’s performance.
The next example shows how to investigate the performance of the creation of a tuple and the creation of
a list. Here we apply the above discussed function GetTimeSpanInSeconds.

Investigating the Creating Time of Tuples and Lists using a Function Approch

E. Baeck
2.12. DATE, TIME AND TIMESPAN Page 39

# we need the datetime package


from datetime import datetime as time

# calculating the timespan in floats


def GetTimeSpanInSeconds(T):
t = float(T.seconds)
t+= float(T.microseconds)/1.e6
t+= float(T.days)*24.*60.*60
return t

nX = 100000 # number of entities to create


T = () # empty tuple
L = [] # empty list

# create a tuple with nX items


t1 = time.now()
for i in range(nX):
T += (i,)
t2 = time.now()

sT = GetTimeSpanInSeconds(t2-t1) # and calculate the timespan


print "Creation of a tuple with %d items: %.3fs" % (nX,sT)

# create a list with nX items


t1 = time.now()
for i in range(nX):
L += [i,]
t2 = time.now()
sL = GetTimeSpanInSeconds(t2-t1) # and calculate the timespan
print "creation of a list with %d items: %.3fs" % (nX,sL)

# convert the list into a tuple


t1 = time.now()
TL = tuple(L)
t2 = time.now()
sTL= GetTimeSpanInSeconds(t2-t1) # and calculate the timespan
print "Create tuple from list: %.3fs" % sTL

End of Coding

The console output on a one year old double processor notebook is given below. You see that it is very
wasteful to create a tuple with a lot of items concatenating them with a += operator. On the other hand a
list with the some number of items is created in no time. And the conversion of a list into a tuple costs
nothing. So we can resume the the creation of a very large tuple should be done by creating a list and

2.12.2011
Page 40 Analysis of Structures - WS10/11

converting it into a tuple.

c:\CM\Cm-AoS\WS1011\Python>Timecheck1.py
Creation of a tuple with 100000 items: 33.297s
creation of a list with 100000 items: 0.063s
Create tuple from list: 0.000s

2.13 Working with Files

A file is a sequence of bytes written to an external media like a hard disk, a CD or an USB stick. A file’s
bytes are indexed with an integer. So the the fist byte of a file has the index 0 and the second byte the
index 1 and so on. A text file is structured with a line break character \n. If a text line should be read,
the io11 system reads all the bytes up to the next line break.

Python as a lot of functions which are able to handle every situation concerning files. So files can be
created. We can read data from a file or write data into a file. We can close a file. We can delete a file or
change it’s permissions.

2.13.1 Open a File

Within Python a file is an object an has a lot of attributes and methods (see also the next section). The
access to a file is initialized with the file constructor. The file constructor needs the name of the file and
the type of access. The file access type is like C’s access type of the function fopen12 . The type ’r’ is
used to read from a file, the type ’w’ is used to create a new file for writing. An old still existing file
will be deleted. The type ’a’ is used to write appending to an existing or a new file. If we want to read
from and write into a file the type ’w+’ can be used.

f = file(<filename>,<access-type>)
...
... example ...
...
f = file("myfile.txt", "w")

2.13.2 Write Data into a File

The file method write writes a stream of bytes into a file. In contrast to the print function the write method
adds no carriage return to the file. If a line of text should be written, the text should be closed with an \n
character.

f.write(<byte-stream>)
...
... example ...
...
f.write("This is my first line\n")

11
io means input output.
12
The function fopen is C’s classical function to open a file. The return will be a pointer to a FILE structure.

E. Baeck
2.14. OOP WITH CLASSES Page 41

2.13.3 Close a File

After the usage of a file, the file should be closed.

f.close()
...
... example ...
...
f.open("log.txt","a")
f.write("Write a little log line\n")
f.close()

2.14 OOP with Classes

Python is an object orientated programing language13 . Everything within Python is implemented as an


object, even a simple integer number. So what is the concept of a class? A class or an object combines
data, called attributes, with functions, called methods. This can be described by so called UML14

An instance of a class, that is the realization of the class in memory, is created simply by assigning the
class’s name followed by the constructors parameter list to a symbolic name, which than is the pointer or
the reference to this instance. Within the class the self pointer to the actual instance is called self. To
access member attributes or methods of a class the dot notation is used, i.e. <instance>.<member>.
We can remove an instance of a class by calling the del operator (del example). The references
to an instance are handled by the python runtime system. If an instance has lost all it’s references, the
instance is removed from the memory.15

2.14.1 Some UML Diagrams

UML structure diagrams of the emphasize the things that must be present in the system being modeled.
Since structure diagrams represent the structure they are used extensively in documenting the architec-
ture of software systems. In our description of the examples we want to implement we use the Class
Diagram which describes the structure of a system by showing the system’s classes, their attributes, and
the relationships among the classes.

A UML class diagram (see figure 2.7) consists of a rectangular box, which is di- Class Name
vided into three sections. The fist section contents the class’s name. This name attribute 1
attribute 2
is written centered in bold letters. The second section contents the attribute’s method 1
names of the class and the third section contents the method’s names. method 2
Figure 2.7: A UML
Class Diagram

13
Object orientated Programming is often used with the abbreviation OOP.
14
The Unified Modeling Language includes a set of graphic notation techniques to create visual models of software-intensive
systems. The Unified Modeling Language is an international standard see [4], UML 2.3 was formally released in May 2010.
15
This is also called Garbage Collector. In contrast to this in poor C or C++ an once allocated object has to be removed
explicitly from the memory to avoid so called memory leaks, this are blocked parts of the applications memory, which remain
unaccessible until the application is closed.

2.12.2011
Page 42 Analysis of Structures - WS10/11

A UML note diagram (see figure 2.8) consists of a stylized note sheet which is This is only
filled with some information. a simple Note

Figure 2.8: A UML Note


Diagram
This is
Class Name Class 1
attribute 1
attribute 2
method 1 A UML note diagram (see figure 2.9) will be assigned to an
method 2 other component of the diagram scene with a simple line.

Figure 2.9: A UML Note Diagram Assign-


ment
Base Class
attributeB1
attributeB2
methodB1
Figure 2.10 shows how to draw diagrams for inheriting classes. An arrow with methodB2
a white filled arrowhead points from the inheriting class, the special class, to
the inherited class, the base class. The attributes and the methods of the Base
class are now available in the name space of the inheriting class, i.e. the special
class now has the attributes attributB1, attributB2, attributS1 and Special Class
attributeS1
attributS2. attributeS2
methodS1
methodS2
Class 1 Figure 2.10: A UML
List A
* Inheritance Diagram
List B
method 1

1 Figure 2.11 shows a aggregation and a composition.


An aggregation is drawn by a white filled rhombus.
An composition is drawn by a black filled rhombus.
2..* 1..*
Aggregation and compositions describe a container
Class A Class B
attribute A1 attribute B1 or a list of several instances of an object, which are
attribute A2 attribute B2 members of a main class. If for example a profile
method A method B consists of several parts, the parts can be described as
an composition, if a part only exists within a profile.
Figure 2.11: A UML Diagram for a Composition and If a part exists also without a profile, the parts are
an Aggregation
described within the profile with an aggregation.

At the ends of the connecting lines the multiplicities are noted. The multiplicity gives the range of
referenced instances in the form from..to. For the Class A we have 2 up to infinite instances in an
composition, therefor at the end of the line we can not have a multiplicity of zero. In our example
we have exactly one instance of the class 1. On the other hand Class B is referred to Class 1 within
an aggregation. In our example on instance of Class B can be reverenced by an undefined number of
instances of Class 1. This is shown by the * icon. On the other hand the class 1 references at least on
instance of the Class B. Otherwise the number of references is arbitrary. This is also shown by the *
icon.

E. Baeck
2.14. OOP WITH CLASSES Page 43

2.14.2 Implementation of a Time Stack Class

In section 2.12 we have discussed a little program which implements a time checker using a stack con-
tainer. We can implement this problem in a much more clearer version, if we do it in terms of the OOP
approach. The class TimeCheck, which is introduced, encapsulates the time stack list and the log files
name as attributes and the following methods.

• Set reads the actual time with the datetime.now() and pushes it onto the time stack.

• Get reads the actual time with the datetime.now(), pops the the last time object from the stack and
calculates the timespan. The timespan is optionally printed into the console window or into a log
file.

• GetTime calculates the seconds in floats form the passed timedelta object.

The main program, which is used to discuss the class follows the steps of the classical implementation
of the problem discussed in section 2.12. We first create an empty tuple and an empty list. Than we
create the TimeCheck instance16 simple by assigning it’s name to a variable (s = TimeCheck()). To
push a time object onto the stack, we call the class’s member function Set. So, if we want to check the
performance of a code, we first call the Set method and after having executed the code, we call the Get
method. The Get method will print the comment and will return the used seconds of execution time in
floats. The simplest kind of an implementation is the implementation in the file of the main program.
This you can see in the following example.

A UML diagram of the class TimeCheck is given in figure 2.12.

TimeCheck
The class TimeCheck contents
self. log: name of the log file all the data and functions to
self. stack: stack list use a time stack and to get the
self. init (..): contructor time-span information in a proper
self.Set(..): push a time float format. The class is able to
self.GetTime(..): calculate seconds present a formated output of the
self.Get(..): pop a time measured time-spans.

Figure 2.12: UML-Diagram of the TimeCheck Class

OOP Implementation of the Time Checking Problem

’’’
Class to investigate the timespan, to measure the performance
by implementing a time stack container
’’’
# - module - member alias
from datetime import datetime as time # we need the datetime package

class TimeCheck(): # class name

# constructor
16
A physical created object in memory of a class is called instance of a class.

2.12.2011
Page 44 Analysis of Structures - WS10/11

def init (self,log = "timestack.log"):


self. stack = [] # empty list
self. log = log # set the logfile’s name

# set up the actual time and push it onto the stack


def Set(self):
self. stack.append(time.now())

# calculate the timespan in float


def GetTime(self,T):
s = float(T.microseconds)/1.e6 +float(T.seconds) +float(T.days)*24.*60.*60.
return s

# calculate the timespan with a stack object


def Get(self,text = ""):

# get the stack length


items = len(self. stack)

# assert(items > 0) # to assert, that there is a time object


# stored in stack (alternative solution)
if items < 1:
print "*** Error: timestack empty!"
return

tStart = self. stack.pop() # pop the time object from the stack
tEnd = time.now() # get the end time
tDel = self.GetTime(tEnd -tStart) # calculate the timedelta in floats

# we have an maximal indent of 6 columns


indent = 6
space1 = "" # leading characters for level indent
space2 = "" # trailed characters to aling the comment

# set up indent text


for i in range(items-1): space1 += "." # fill in dots
for i in range(indent -items): space2 += " " # fill in white spaces

# print comment if given


if len(text) > 0:
textout = "%s %8.3f%s: %s" % (space1,tDel,space2,text)

# comment to the screen


print textout

E. Baeck
2.14. OOP WITH CLASSES Page 45

# logging the comment


f = file(self. log,"a")
f.write(textout + "\n")
f.close()

return tDel # return the seconds in floats

# application of the TimeCheck class


print ">> Start.."
nX = 50000
T = () # empty tuple
L = [] # empty list

# create the timecheck object


s = TimeCheck()

# check the total performance


s.Set()

# check the performance of the tuples


s.Set()
for i in range(nX): T+= (i,)
s.Get("Creating %d item tuple." % nX)

# check the performance of the list


s.Set()
for i in range(nX): L+= [i]
s.Get("Creating %d item list." % nX)

# check the whole performance


s.Get("total time")
End of Coding

If we run the program, we see that two time stamps are indented with one dot. This timestamps are set
for inner performance measurements, that is the time-stamp for the creation of the tuple and after that
the time-stamp for the the creation of the list. The last time-stamp shows the total execution time and is
created by the first push, i.e. the first Set call and the last pop, i.e. the last Get call.

>> Start..
. 8.282 : Creating 50000 item tuple.
. 0.016 : Creating 50000 item list.
8.329 : total time

2.12.2011
Page 46 Analysis of Structures - WS10/11

E. Baeck
3

Python Projects

3.1 Newton, Step2

We have discussed the newton’s scheme in section 2.9. Within this section the project’s code will be
extended by plot features. The function and it’s derivative as well as the path of iteration will be plotted
using the PyLab package.

The following features are added to the implementation of newton’s scheme.

1. Import the PyLab package.

2. The function GetFunctionValues creates a list of the function values for the plot routine.

3. The function GetFunctionDerivativeValues creates a list of the function’ derivative values for the
plot routine.

4. The function Newton will be extended by two lists, which should store the values of the iteration
path. After each iteration step, the x-value and it’s function value are stored for later drawings.

Newton’s Algorithm, Step 2

import pylab # plot a little (not used in this step)


from math import fabs as abs # import the fabs as abs

# implementation of the function of interest


def Myf(x):
return x**2 -1.

# calculating the derivative


def fs(f,x,h=1.e-6):
h = float(h)
x = float(x)
return (f(x+0.5*h) - f(x-0.5*h))/h

# implementation of a newton algorithm

47
Page 48 Analysis of Structures - WS10/11

def newton(f,x0,e=1.e-10,h=1.e-6,imax=100):

error = None # initialize the error code with None

h = float(h) # we need some floats


e = float(e)
x1= float(x0) # x to interate

xL= [] # list for x-values


yL= [] # list for the function values for x

i = 1 # iteration counter
while True:

f0 = f(x1) # function’s value

xL.append(x1) # save x Value


yL.append(f0) # save the functions value

if abs(f0) < e:
break

# calculating the derivative


f1 = fs(f,x1,h)
if abs(f1) < e:
error = "*** Error: vanishing derivate!"
break

# available iterations exceeded


if i >= imax:
error = "*** Error: no root found!"
break

# calculating the values for next iteration


x1 -= f0/f1

# increment the iteration counter


i+=1

# return the actual position, the function value


# and the functions slope, the number of performed
# iterations and the error code.
# index 0 1 2 3 4 5 6
return (x1,f0,f1,i,error,xL,yL)

E. Baeck
3.1. NEWTON, STEP2 Page 49

# creating a list of function values for a x-list


def GetFunctionValues(xL,f):
yL = []
for x in xL:
y = f(x)
yL.append(y) # yL += [y]

return yL

# create a list of function’ derivative values


def GetFunctionDerivateValues(xL,f):
yL = []
for x in xL:
y = fs(f,x)
yL.append(y)

return yL

# parameters of the problem


xl = -5. # lower bound
xu = 5. # upper bound
xc = 0.5 # increment

# visalization of the function and it’s derivative


# create the x-List
xList = pylab.arange(xl,xu,xc)

# create list of function’s values


yList = GetFunctionValues(xList,Myf)
pylab.plot(xList,yList,’b’)

# create list of function’s derivative values


ysList = GetFunctionDerivateValues(xList,Myf)
pylab.plot(xList,ysList,’g’)

# the function newton is called with standard parameters


# we pass the function of interest and a supposed start
# position
res = newton(Myf,4.)

# the returned tuple is printed into the console window


print "\n> next run"
print "x = %f" % res[0] # last x value

2.12.2011
Page 50 Analysis of Structures - WS10/11

print "f(x) = %f" % res[1] # last f(x) value


print "f’(x) = %f" % res[2] # last f’(x) value
print "i = %d" % res[3] # number of iterations
if res[4] is not None:
print "%s" % res[4] # error message
print "--- end of code ---\n"

# plot the iteration path


pylab.plot(res[5],res[6],’rp’)

# output of plot data


pylab.grid(True) # show grid lines
pylab.savefig("NewtonStep2.png")

# - show plot data


pylab.show()
End of Coding

After the output lists are created the lists are passed to the plot postprocessor by the plot method of
PyLab. After enabling the grid the plot data are written in a graphic file and are visualized in the PyLab
viewer application.

Figure 3.1 shows the iteration path for the equation f (x ) = x 2 − 1 with an starting value of 4 with red
dots.

Figure 3.1: Newton’s Iteration Path

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 51

3.2 Profiles, Thin Walled Approach

In this section we will implement a class hierarchy to model a profile’s data. We will implement logging
into file and screen in a common base class and we will implement the thin walled approach to analyze
and calculate the profile’s section properties.

3.2.1 Implementation of a general Profile Classes

So if we want to develop a software, which is able to calculate the profile’s section properties like it’s
area, moment of inertia and so on, we can consequently split up the problem in general and specific parts.
So we start with the data and the functions of a general object. This data is collected in a class which
we call Base. So if we want to describe a wide range of profile types, then we should think about the
profile’s common features. Every profile has a name and therefore this name is a common feature. This
common features are collected in a general profile class which is called Profiles. If we want to handle a
specific profile type like an U-profile ore a tube profile, we collect the specific type dependent features
in the classes UProfile and TubeProfile.

Base
log: global log file name The class Base contents
count: global instance counter common features which are used
self. init (..): constructor in every class.
self.AppendLog(..): write to log

Profile
self. name: The profile’s name
self. PL: Point container
self. LL: Line container
self. init (..): constructor The class Profile contents
self.List(..): List profiles values all common features of a profile
especially the containers for the
self.AddPoint(..): insert a new Point Points and Lines of shape modell
self.AddLine(..): insert a new Line
self.GetLength(..): distance between to points
self.GetArea(..): calculate profile’s area
self.View(..): views a profile plot

UProfile
self. h: profile’s height
self. w: profile’s with The class UProfile contents
self. t: profile’s thickness the special features of a U-Profile,
self. init (..): constructor especially the geometric parameters.
self.List(..): list profiles values
self.Create(..): create thin walled model

TubeProfile
self. d: profile’s diameter The class TubeProfile contents the
self. t: profile’s thickness special features of a Tube-Profile,
self. init (..): constructor especially the geometric parameters
self.List(..): list profiles values

Figure 3.2: Some UML-Diagrams for the Profile Hierarchy

Figure 3.2 shows in the left column the UML class diagrams, which starts with the name of the class.
The second box contents the classes attributes and the third box contents the classes methods. The right
column contents note diagrams. A note diagram is like a help page which gives some comments and

2.12.2011
Page 52 Analysis of Structures - WS10/11

elucidations.

If we want to develop reusable code, it’s recommended to create a separate file for every class and put
them into a package. A package is a folder with the package’s name. So we introduce a folder called
Profiles. To initialize a package we have to create a file named __init__.py in this folder. If the
package is loaded, the __init__.py is executed.

This file is executed, when the Profile package is loaded.

# This script is executed only once, if the package is loaded.


# So we print a little to show what’s going on
print ">> Package ’Profiles’ is loaded"
End of Coding

In our Profiles class Base we implement the common features of our package classes. The class Base
counts the instances using the global class attribute __count. A common logging method is imple-
mented. So the name of the log file is implemented as a class method (not an instance method) __log.

The method AppendLog is implemented as a general logging function. The actual time is called an
copied as heading for our logging comment. Then the completed logging text is written into the log file
and into the screen.

Base class of all package classes

’’’
Base class for general attributes and methodes of the packages’s classes.
Every class of this package will be derivated from this class
’’’
# we need the datetime for the log’s timestamp
from datetime import datetime as time

class Base:

log = "profiles.log" # standard log file name for all instances


count = 0 # counter for the class’s instances

# - optional we can set up the log’s file name


def init (self,log = ""):
Base. count += 1 # increment the instance counter
if len(log) > 0: Base. log = log

self.AppendLog(">> Instance %d created" % Base. count)

# general logging methode


# - we pass the text to log
def AppendLog(self,text):

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 53

t = time.now() # get actual time


tstamp = "%2.2d.%2.2d.%2.2d|" % (t.hour,t.minute,t.second)
textout = tstamp + text # copy the stamp in front of the comment

f = file(Base. log,"a") # open the log file for appending "a"


f.write(textout + "\n") # write the text into the file with linebreak
f.close() # close the log, to save the data on disc

print textout # write the log to the screen

End of Coding

If we want to use the code of an existing class within a new class, we can inherit this old class and use
it as a base class. That means, that the new class contents also the attributes and the methods of the old
one. A base class is used in the class statement as an argument. A class can inherit more than one class.
Because we implement the new class Profile within the Profiles package, we only have to import the
module base, i.e. the file base.py. From this module we import the class Base. So we can write the
import statement as follows.

from <package>.<module> import <class> as <locale name / alias name>

The class profile now contents common profile features. One of them is the profile’s name. Note,
if we inherit a class from a base class, we have to call the base class’s constructor method. Every
attribute and every method of the base class is now available. A second feature of the Profile class is the
implementation of the thin walled model. Therefore we introduce a line and a point container using the
AList class. With a specific method we insert point and line instances into the container. To calculate the
section values of the created thin walled model we introduce a method to calculate the distance between
to points and a further method to calculate the line’s area, which is given by the product of line length and
line thickness. At least we introduce a little viewing method, which should create a png picture file of the
profile and should optionally start the pylab viewer tool. To be sure, that the environment supports the
Tkinter package1 , which is used by the viewer, we import the package using a try: ... except:
handler.

Profile, a common base class for all profile classes

’’’
General Profile class, derivated from the package’s Base class
’’’
from Base import Base # the profile’s base class
from AList import AList # container for points/lines
from Point import Point # a point class
from Line import Line # a line class

1
We will see later trying to apply our package Profiles in the frame of the Abaqus scripting, that we will get problems,
because the Abaqus environment is not developed with Tkinter.

2.12.2011
Page 54 Analysis of Structures - WS10/11

from math import sqrt as sqrt

class Profile(Base): # Profile inherits Base

def init (self,name): # each profile will have a name


Base. init (self) # call base class contructor
self. name = name # pass the the name of the profile

self. PL = AList() # List of points


self. LL = AList() # Line list

def AddPoint(self,No,y,z):
p = Point(No,y,z) # create a new point
self. PL.Add(No,p) # add the point to list

def AddLine(self,No,nA,nB,t):

# first calculate the line’s length


L = self.GetLength(nA,nB)
l = Line(No,nA,nB,t,L) # create a new line
self. LL.Add(No,l) # add the line to list

def GetLength(self,nA,nB): # calculate distance between points


dy = self. PL[nA]. x[0] - self. PL[nB]. x[0]
dz = self. PL[nA]. x[1] - self. PL[nB]. x[1]
return sqrt(dy*dy + dz*dz)

def GetArea(self): # calculate profile’s area


A = 0.
for line in self. LL: # over the lines
if line is not None: # only for valid objects
A += line. t * line. L
return A # return the area value

def List(self): # print the profile’s data


self.AppendLog(" Name: %s" % self. name)
self.AppendLog(" %d Points" % len(self. PL))
self. PL.List()
self.AppendLog(" %d Lines" % len(self. LL))
self. LL.List()

def View(self,viewer = True):

try: # try to import the pylab


import pylab # import for plottings

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 55

except:
self.AppendLog("*** Error: yplab could not be loaded!")
return

lines = [] # list for the lines to plot

for line in self. LL: # iterate the line container


if line is not None: # only for valid objects
# point nr
x1 = self. PL[line. p[0]]. x[0]
x2 = self. PL[line. p[1]]. x[0]
y1 = self. PL[line. p[0]]. x[1]
y2 = self. PL[line. p[1]]. x[1]
# ---- line -----
# x-List y-List
lines += [ [[x1,x2], [y1,y2]] ]

# plot the list items


for line in lines:
pylab.plot(line[0],line[1],’b’)

# plot point
for line in lines:
pylab.plot(line[0],line[1],’rp’)

# configure the plot layout


pylab.title(self. name)
pylab.axis(’equal’)
pylab.grid(True)

pylab.savefig(self. name + ".png")

if viewer: pylab.show()

End of Coding

If we now want to use the package we have to create a new main program. The main program to show
the usage of our new classes is given below.

Simple test program for the usage of the profile class

# Package |Module Class Alias


from Profiles.Profile import Profile as prof

u100 = prof("U100")

2.12.2011
Page 56 Analysis of Structures - WS10/11

u120 = prof("U120")
End of Coding

A class hierarchy UML diagram is given in figure 3.3.

Base
log: global log file name
count: global instance counter
self. init (..): constructor
self.AppendLog(..): write to log

Profile
self. name: The profile’s name
self. PL: Point container
self. LL: Line container
self. init (..): constructor
self.List(..): List profiles values
self.AddPoint(..): insert a new Point
self.AddLine(..): insert a new Line
self.GetLength(..): distance between to points
self.GetArea(..): calculate profile’s area
self.View(..): views a profile plot

UProfile
self. h: profile’s height
TubeProfile
self. w: profile’s with
self. d: profile’s diameter
self. t: profile’s thickness
self. t: profile’s thickness
self. init (..): constructor
self. init (..): constructor
self.List(..): list profiles values
self.List(..): list profiles values
self.Create(..): create thin walled model

Figure 3.3: Class Hierarchy Diagram of the Profiles Package

3.2.2 Implementation of basic Classes for a Thin Walled Model

The simplest approach to calculate the profile’s cross section values (area, moments of inertia, the center
of mass, etc.) is given by the thin walled model, a one dimension approximation of the profiles geometry.
The profile is described only by points and lines like in the finite element approach. Therefore we
introduce a point as well as a line class (see figure 3.4). To hold the desired point and line information
we implement a slightly modified list class, which should work like an array with a well defined index
access. If we use a standard list class, we will get problems if we want to insert an object at a position
outside the list range. Then a standard list object simply appends this object as a new item at the tail
of the list and we would loose the correct index position. So we implement a new Add method, which
checks the list length and if necessary enlarges the list up to the desired index position.

Figure 3.5 shows the profile class’s UML diagram with the composition of the point and line class. The
UML diagram shows, that thin-walled model consists of minimally 2 points and one line. The code of
the Point class is given below.

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 57

Point
n: point number The class Point contents
x[]: List for point coordinates the coordinates and the number of
self. init (..): constructor a profile’s point.
self.List(..): print point data

Line
n: line number
p[]: List of point numbers The class Line contents
t: line’s thickness the line’s point data and the line’s
L: line’s length thickness.
self. init (..): constructor
self.List(..): print line data

AList
no attributes The class AList is based on a
self. init (..): constructor a list. The Add method adds an object
self.Add(..): Add by index with a given index value.
self.List(..): print instance’s data

Figure 3.4: Some UML-Diagrams for Profile Points and Lines

Profile
self. name: The profile’s name
self. PL: Point container
self. LL: Line container
self. init (..): constructor
1
self.List(..): List profiles values
self.AddPoint(..): insert a new Point
self.AddLine(..): insert a new Line
self.GetLength(..): distance between to points
self.GetArea(..): calculate profile’s area
self.View(..): views a profile plot

1
1..*
Line
2..*
n: line number
Point p[]: List of point numbers
n: point number t: line’s thickness
x[]: List for point coordinates L: line’s length
self. init (..): constructor self. init (..): constructor
self.List(..): print point data self.List(..): print line data

Figure 3.5: UML-Diagram of the Profile Composition

2.12.2011
Page 58 Analysis of Structures - WS10/11

Class of a Profile Point

from Base import Base # the Point class is inherited from the Base

class Point(Base):

def init (self,no,y,z): # The Point is created passing the point number
Base. init (self) # and the coordinates. The constructor of the
# Base class is called.
self. no = no
self. x = [y,z] # the coordinates are stored in the lis

def List(self): # print the point’s data


self.AppendLog(" Point: %3d, y= %10.3f, z= %10.3f" % (self. no,self. x[0],self. x[1]))

End of Coding

The following code shows the code of Line class.

Class of a Profile Line

from Base import Base # Line inherits Base

class Line(Base):

def init (self,No,nA,nB,t,L): # we pass the number, point


# numbers and the thickness
Base. init (self) # first we call the base class’s constructor

self. No = No
self. p = [nA,nB] # the point numbers are store in a list
self. t = t
self. L = L # the line length is calculated according to
# the thin walled approach

def List(self): # the list method calls the base class’s AppendLog
self.AppendLog(" Line: %3d, A= %3d, B= %3d, t= %7.3f" % \
(self. No,self. p[0],self. p[1],self. t))
End of Coding

The following code shows the code of the container class ALast. In a first version the class AList inherits
the content of the class Base. The python buildin container class list is used as an attribute _L. The
access to the container is handled with access methods.

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 59

Code of the class AList Version 1

from Base import Base


# Version 1 of the AList class inheriting

class AList(Base):

def init (self):


Base. init (self) # call the Base constructor
self. L = [] # the list is used as an attribut

def Add(self,No,obj): # adds an object reference with an index


UBound = len(self. L) -1 # get largest valid index
if No > UBound: # if the list is undersized extend
for i in range(UBound+1,No +1): # to the used length
self. L += [None,] # add a new item to the list

self. L[No] = obj # the save the reference


self.AppendLog(">> New Length: %d Items in List" % len(self. L))

# the List method calls the List method of it’s items


# if there is no item, the case is handled with an exception block
def List(self):
iobj = 0 # initialize the object counter
for obj in self. L: # iterate the slots of the list
try: # open the try block
obj.List() # try to list an object
except: # if not possible log it to the log file
self.AppendLog(" Error: No object in slot %d" % iobj)
iobj += 1 # increment the counter

End of Coding

The following code shows the code of the container class ALast. In a second version the class AList
inherits besides the class Base the buildin class list. The advantage comparing this version with the
member implementation of a list is, that the class AList will have exactly the same interface a the buildin
class list.

Code of the class AList Version 2

from Base import Base # the AList class should inherit the Base class

# Version 2 of the AList class inheriting the buildin


# object "list" too
class AList(Base,list):

2.12.2011
Page 60 Analysis of Structures - WS10/11

def init (self):


Base. init (self) # call the Base constructor

def Add(self,No,obj): # adds an object reference with an index


UBound = len(self) -1 # get largest valid index
if No > UBound: # if the list is undersized extend
for i in range(UBound+1,No +1): # to the used length
self += [None,]

self[No] = obj # the save the reference


self.AppendLog(">> New Length: %d Items in List" % len(self))

# the List method calls the List method of it’s items


# if there is no item, the case is handled with an exception block
def List(self):
iobj = 0 # initialize the object counter
for obj in self: # iterate the slots of the list
try: # open the try block
obj.List() # try to list an object
except: # if not possible log it to the log file
self.AppendLog(" Error: No object in slot %d" % iobj)
iobj += 1 # increment the counter
End of Coding

To check the package code, we create an instance of the Point and the Line class. The instances’ data
are printed with their list method. Then a AList instance is created and the Point and Line instances are
inserted into to AList instance. Then the AList’s data are printed.

Within a second step a Profile instance is created. We add two Point instances and one Line instance to
Profile instance and print the Profile instance’s data.

Code for a first Check of the Profile Package

’’’
Test program for Point, Line and AList class
’’’
# -package-module class
from Profiles.Point import Point
from Profiles.Line import Line
from Profiles.AList2 import AList
from Profiles.Profile import Profile

p = Point(1,1.1,2.1) # create a point and


p.List() # list the point’s data

l = Line(2,10,11,2.5) # create a line and

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 61

l.List() # list the line’s data

LA = AList() # create a AList instance

LA.Add(0,p) # save the point at slot 0


LA.Add(3,l) # save the line at slot 1

LA.List() # list the AList’s data


# create a Profile instance
prof = Profile("Test Profile")
prof.AddPoint(0,0.1,0.2) # add a Point to the profile
prof.AddPoint(2,2.1,2.2) # add a 2nd Point to the profile
prof.AddLine(0,0,2,1.5) # add a Line to the profile
prof.List() # list all the stored data

End of Coding

The following output will be written to screen and into a file, if the check script will be executed. The
output shows, that first the package is loaded with the control string of the __init__.py module. If
an instance is created the instance counter is logged.

>> Package ’Profiles’ is loaded


20.21.47|>> Instance 1 created
20.21.47| Point: 1, y= 1.100, z= 2.100
20.21.47|>> Instance 2 created
20.21.47| Line: 2, A= 10, B= 11, t= 2.500
20.21.47|>> Instance 3 created
20.21.47|>> New Length: 1 Items in List
20.21.47|>> New Length: 4 Items in List
20.21.47| Point: 1, y= 1.100, z= 2.100
20.21.47| Error: No object in slot 1
20.21.47| Error: No object in slot 2
20.21.47| Line: 2, A= 10, B= 11, t= 2.500
20.21.47|>> Instance 4 created
20.21.47|>> Instance 5 created
20.21.47|>> Instance 6 created
20.21.47|>> Instance 7 created
20.21.47|>> New Length: 1 Items in List
20.21.47|>> Instance 8 created
20.21.47|>> New Length: 3 Items in List
20.21.47|>> Instance 9 created
20.21.47|>> New Length: 1 Items in List
20.21.47| Name: Test Profile
20.21.47| 3 Points
20.21.47| Point: 0, y= 0.100, z= 0.200
20.21.47| Error: No object in slot 1
20.21.47| Point: 2, y= 2.100, z= 2.200
20.21.47| 1 Lines

2.12.2011
Page 62 Analysis of Structures - WS10/11

To next script implements a little testing environment for the usage of the classes UProfile and Profile
of the Profiles package. A UProfile instance will be created with the data of an U100 profile. The
thin walled model will be created automatically within the constructor of the UProfile instance. Then
the whole data of the profile will be written to the screen and into the log file using the base classes
AppendLog method. Then the area of the profile model will be created and printed. At last using the
View method of the inherited class Profile a picture file is written and the PyLab viewer is started.

Figure 3.6 shows the viewers window as well as the picture file’s content. The blue lines are the center-
lines of the profile parts, i.e. the lines. The red dots are the points of the thin walled model. We see that
height and width are reduced by the thickness values.

Testing Script for the Classes UProfile and Profile

’’’
The test environment implements the creation
of a U100 profile, the listing of it’s data
and the creation of it’s model picture
’’’
# package module class
from Profiles.UProfile import UProfile

# create the instance of an U-Profile


prof = UProfile("U100",100.,50.,6.0,8.5)

# and check it
prof.List()

# calculate the area and print it in cmˆ2


Acm2 = prof.GetArea()/100.
prof.AppendLog(" Area: %10.3f cmˆ2" % Acm2)

# plot and view the profile’s geometry


prof.View()
End of Coding

3.2.3 Implementation of a little Profile Database

To implement a simple profile data base for arbitrary profile instances, we can simply use the Python
buildin object dict 2 and extend it by inheritance with a specific list method (see figure 3.7). The list
iterates the dictionary getting the keys of the stored instances. With the given key we get the instance
pointer from the dictionary. Then we can use the mechanism of the polymorphism and call the instances
specific list method. If there is an error occurring, the try/except error handler will do his job and
executes the except branch code. So we can avoid program crashing due to invalid ore missing pointers.
2
A dictionary is used to store instance pointers with an arbitrary access key.

E. Baeck
3.2. PROFILES, THIN WALLED APPROACH Page 63

Figure 3.6: Picture of an U100 Profile Model

ProfDB
no attributes The class ProfDB is based on a
a dictionary. Profile instances are
self. init (..): constructor are stored like in a database.
self.List(..): print instance’s data

Figure 3.7: UML-Diagram of the Profile Database

The code of the ProfDB class is given below.

Class ProfDB to implement a simple Profile Database

from Base import Base # the ProfDB class should inherit the Base class

# The ProfDB class should store arbitray profile objects in


# a dictionary. Therefore we inherit from the buildin dict object
class ProfDB(Base,dict):

def init (self):


Base. init (self) # call the Base constructor

# the List method calls the List method of it’s items


# if there is no item, the case is handled with an exception block
def List(self):
iobj = 0 # initialize the object counter
for name in self: # iterate the keys of the dictionary
try: # open the try block
self[name].List() # try to list an object
except: # if not possible log it to the log file
self.AppendLog(" Error: No profile key %s found, slot %d" % \
(name,iobj))
iobj += 1 # increment the counter
End of Coding

2.12.2011
Page 64 Analysis of Structures - WS10/11

To check the database class ProfDB we write a little script, which first creates a ProfDB instance. Then
we create a UProfile instance with the values of the U100. This instance is stored in the dictionary using
the key of it’s name U100. Then we create a second UProfile instance with the values of the U140 and
store it as well in the dictionary using it’s name U140 as it’s key. After that we simple call the ProfDB
instance method list. The data of the two profiles are listed on the screen and into the log file. The code
of the testing environment is given below.

Testing code to check the Profile Database Class ProfDB

’’’
This testing example implements a little profile
database. Two U-profiles are created and stored in
the database. Then the whole content of the database
is printed using the AppendLog method of the base class
’’’
# package module class
from Profiles.UProfile import UProfile
from Profiles.ProfDB import ProfDB

# create Profile database


db = ProfDB()

# create the instance of an U-Profile


prof = UProfile("U100",100.,50.,6.0,8.5)

# and save it into the db


db.setdefault("U100",prof)

# create the instance of an U-Profile


prof = UProfile("U140",140.,60.,7.0,10.)

# and save it into the db


db.setdefault("U140",prof)

# print the content of the db


db.List()
End of Coding

E. Baeck
Part II

Scripting with Abaqus

65
4

Some Aspects and Introduction

In this chapter we talk about the Abaqus Student Edition Licence 6.10.. A main aspect will be the
development of Python programs, which should automate the creation of FE models and the subsequent
calculation and preprocessing.

4.1 Aspects of the Abaqus GUI

In this chapter we talk about the Abaqus Student Edition Licence 6.10. GUI1 .

Figure 4.1 shows the Abaqus GUI. A very important item is the combo box to select the module. The
selected module loads the specific menu items. The left window shows the Abaqus object tree. The
bottom window contents an output window for the output messages and the command window for the
Python commands.

Figure 4.1: Abaqus-GUI

1
Graphical User Interface is a window driven program which contents all commands in terms of menu items, buttons, boxes
and so on which are commonly called widgets.

67
Page 68 Analysis of Structures - WS10/11

4.2 The Abaqus CAE Module

The Abaqus/CAE kernel offers several possibilities to build up an FE model.

• The GUI offers interactive functions to create the FE model.

• The Python command window offers the possibility to execute single Python commands.

• The Scripting interface offers the possibility to run Python scripts.

• The GUI offers the possibility to record interactive actions in a Python script format. So we can
record and replay everything we do within the GUI.

The Python interpreter creates the input for the CAE kernel. The CAE kernel creates the input stream for
the Abaqus FE-Module.2

2
The input file for the Abaqus FE-Module is a simple Text file, the classical input file, which can also be written ’by hand’.

E. Baeck
4.3. A MODELING CHAIN Page 69

4.3 A Modeling Chain

Figure 4.2 shows how to create a Finite Element model Create a database
in Abaqus/CAE. It is not possible to create elements and
nodes directly. Element and nodes are only created by Module Sketch
Draw a sketch
the mesh generator, which works an the geometric objects,
which are created drawing a sketch.
Module Part
The only FE model parameter, which are created di- Create a part and
rectly, are the material properties and the section values. assign the sketch

This properties are created within the module Property.


The properties are then assigned to the geometric objects Module Property
Create a properties,
(lines, areas and volumes). materials and sections,
assign them to sketch lines
After having created a sketch the sketch has to be assigned
to a part. If no part exists, a part hast to be created. The
Module Assembly
properties (materials and section data) are assigned to the Create an instance
sketches’ geometric objects. and assign the part to it

To create a mesh, an instance is needed, so an instance has


Module Step
to be created. The part with the sketch are assigned to the
Create a step as
instance for later meshing. container for a load case
Loadcases are modeled in terms of load steps. So a new
step has to be created as a container for loads and bound- Module Load
Create loads and
ary conditions. Loads and boundaries are assigned to the boundary condition within the step
geometric objects of the sketch which were assigned to a
part before. Module Mesh
Set Seeds, elements per length
To create the mesh, the mesh’s control parameters should
select and assign element type
be configured and the element types are to be assigned. mesh the instance
Then the instance can be meshed.

After the mesh is created, the complete model can be as- Module Job
Create a Job and submit
signed to a job. To calculate the results the job has to be
submitted. Figure 4.2: Modeling Chain Diagram

2.12.2011
Page 70 Analysis of Structures - WS10/11

4.4 A little interactive Warm Up Example

In section 4.3 we have discussed the Abaqus modeling chain.


Following this outlines the subsequent example based on [5]
shows how to create and calculate a simple 3 truss system
with a concentrated force. We use the following parameters.

• Lx horizontal length 1000 mm

Ly
• Ly vertical length 1500 mm

• Fx horizontal force -100 kN


Fx
• Fy vertical force -100 kN
Fy

Lx
Figure 4.3: 3 Trusses
4.4.1 Create a Database

Create Model Database


File/Set Working Directory (setup the desired work folder if necessary)

4.4.2 Create a Sketch

Module: Sketch
Sketch => Create => Name: ’Truss-Example’ => Continue
Add=> Point
=> enter coordinates (0,0), (1000,0), (1000,1500), (0,1500)
Add => Line => Connected Line
=> select (0,0) node with mouse, then (1000,0) node,
right click => Cancel
Add => Line
=> Connected Line
=> select (0,0) node with mouse, then (1000,1500) node,
right click => Cancel
Add => Line
=> Connected Line
=> select (0,0) node with mouse, then (0,1500) node,
right click => Cancel
=> Done

4.4.3 Create a Part

Module: Part
Part => Create => Name: ’Part-1’,=> select 2D Planar, Deformable, Wire
=> Continue
Add => Sketch => select ’Truss-Example’ => Done => Done

E. Baeck
4.4. A LITTLE INTERACTIVE WARM UP EXAMPLE Page 71

4.4.4 Create and Assign Properties

Module: Property
Material => Create => Name: ’Steel’, Mechanical, Elasticity, Elastic
=> set Young’s modulus = 210000, Poisson’s ratio = 0.3 => OK

Section => Create => Name: ’Truss-Section’, Beam, Truss => Continue
=> set Material: ’Material-1’,
Cross-sectional area: 2

Assign Section => select all elements by dragging mouse => Done
=> ’Truss-Section’ => OK => Done

4.4.5 Create the Instance, Assign the Part

Module: Assembly
Instance => Create => ’Part-1’ => Independent (mesh on instance) => OK

4.4.6 Create a Load Step

Module: Step
Step => Create => Name: ’Step-1’, Initial, Static, General => Continue
=> accept default settings
=> OK

4.4.7 Create Loads and Boundary Conditions

Module: Load
Load => Create => Name: ’Step-1’, Step: ’Step 1’, Mechanical,
Concentrated Force => Continue => select node at (0,0) => Done
=> set CF1: -10000 set CF2: -10000 => OK

BC => Create => Name: ’BC-1’, Step: ’Step-1’, Mechanical,


Displacement/Rotation => Continue
=> select nodes at (1000,0), (1000,1500) and (0,1500) using SHIFT key
to select multiple nodes => Done => set U1: 0 and U2: 0

4.4.8 Create the Mesh

Module: Mesh
Seed => Edge by Number => select entire truss by dragging mouse
=> Done => Number of elements along edges: 1 => press Enter => Done

Mesh => Element Type => select entire truss by dragging mouse => Done
=> Element Library: Standard,
Geometric Order: Linear: Family: Truss => OK => Done

Mesh => Instance => OK to mesh the part Instance: Yes

2.12.2011
Page 72 Analysis of Structures - WS10/11

4.4.9 Create a Job and Submit

Module: Job
Job => Create => Name: Job-1, Model: Model-1 => Continue
=> Job Type: Full analysis, Run Mode: Background,
Submit Time: Immediately => OK

Job => Submit => ’Job-1’

Job => Manager => Results (enters Module: Visualization)

E. Baeck
5

Scripts and Examples

In this chapter we implement to example scripts, to discuss the automation in Abaqus using the Python
script language.

1. 3 Trusses
The first script gives the implementation of the interactive example, a little 3 trusses system with
one concentrated load. The calculation is performed automatically for a linear analysis.

2. U Profile
The second script gives the implementation of the automated model creation of U Profile using the
thin-walled approach (see also section 3.2 and A.1). The calculation is performed automatically
for a linear analysis and a buckling analysis.

5.1 3 Trusses Script

Within this section the implementation of a script is shown, which automates the example of section
4.4. With the change of the parameter’s values, every system can be calculated with the execution of the
script.

Creating the calculation model we follow our outlines discussed in section 4.3. To avoid problems with
existing project files, we first delete an old database, if exist. Then we set the work directory by the use
of Python’s standard chdir function.1

To get the Python code for the necessary steps, we can simple run the macro recorder and record the
interactive actions. If you do this, then it’s recommended to save the macro file into the work directory
and not into the home directory. The recorded macros are saved into the file abaqusMacros.py.
Note, that the work directory will be set, if the script is executed.

Within the script code the following steps are numbered in the same way.

(1) Create a model


The model is member of the global mdb class. We have to specify the name and the type of the
model. The reference to the created model is saved into the variable myModel for further usage.
1
Note, that on Windows-Systems a path contents backslashes, which in Python are used as escape characters. Therefore if
a backslash is used, we have to duplicate it.

73
Page 74 Analysis of Structures - WS10/11

(2) Create a sketch


The ConstrainedSketch is member of the model class, so we use the before saved model reference
myModel to create the sketch. Initializing a sketch we have to specify the sketch’s name and the
sketch page’s size. The return reference is saved into the variable mySketch.
Within our sketch we draw the lines with the method Line. This is done within a for loop iterating
the tuple containing the endpoint coordinates of the lines.

(3) Create a part


The part class is a member of the model class. We create the part instance specifying it’s name
and it’s type. In this we select the TWO_D_PLANAR type. The return of the constructor is saved
into the variable myPart. The method BaseWire of myPart is used to assign the sketch. Now
we have the geometry to start with the creation of nodes and elements using the Abaqus mesh
generator.2

(4) Create the elements properties


The material class is a member of the model class. A material instance is created specifying the
materials name. Within a second step we assign material properties using the Elastic method of
the material class. A tuple containing the Young’s module and the Poisson ratio is assigned to the
parameter table.
In a second step we create the truss section instance. The TrussSection class is a member of the
model class. The return is saved into the variable mySection.
Within the third step the section, which is also linked to the material, will be assigned to the line
objects of the part. So we have to create a region containing the line objects - in this case called
edges - to perform the assignment. By default the selection is recorded with the parts member
edges method getSequenceFromMask(mask=(’[#7 ]’, ), ). This selection method
is fastest version of selection, but it is also the most cryptic one. If you use this mask, you have to
be sure, that the index of the selected elements does not change and you have to know the selected
objects’ index value. The mask value is created assigning the index values as binary digits. So in
general the mask’s value can be calculated with the following equation.
X
mask = 2i , with i = Objectlabel − 1 for all selected objects (5.1)
i∈Selection

In our case the lines 1, 2 and 3 are selected. So we get

#7 = 716 = 7 = 21−1 + 22−1 + 23−1 = 1 + 2 + 4 (5.2)

After having selected the lines the truss section will be assigned by the part’s method
SectionAssignment. We have to specify the region and the name of the section.

(5) Create an instance


To create the instance, which is needed for meshing, we have to select the rootAssembly object,
which is member of the model class. Because the rootAssembly also is needed later, we assign
it’s reference to the variable root. Within the rootAssembly we create the instance object,
specifying it’s name and the part to assign.
2
Note, that within the GUI nodes and elements can only be created by the mesh generator, i.e. not directly. If the mesh is
created, the node’s and element’s properties can be changed by special system edit methods.

E. Baeck
5.1. 3 TRUSSES SCRIPT Page 75

(6) Create loads and boundary conditions


First we should create a StaticStep class, which is a member of the modul class. The StaticStep
class is a container for loads and boundary conditions.
To create a concentrated load, which is a points load, we have to select first some points, which are
called vertices in Abaqus. The vertices container is a member of the instance class. Vertices also
can be selected with the getSequenceFromMask method, if the label number of the points are
known. The class methode regionToolset.region converts a set of vertices into a region.
The class ConcentratedForce is a member of the model class. We have to specify the loads name.
We have to assign the load to a step and a region and have to set up the load values.
To create boundary conditions we select vertices as well and convert them into a region. Then the
DisplacementBC object, a member of the instance class has to be created like the concentrated
forces specifying it’s name and assigning it to a load step.

(7) Create the mesh


The mesh will be created on the geometric data, in this case the lines of the sketch. So we have
to set up the seeds of the lines, the number of elements, which should be created by the mesh
generator. Like in the case of the section assignment we select all lines using the edges container
of the part object. With #7 we set the mask for our 3 lines. To set the numbers of elements,
we apply the method seedEdgeByNumber of the part class passing the selected edges and the
number of elements to create, in this case one.
Within a second step we select the element type to use in our model with the method elemType of
the class mesh. We select from the standard element library the truss element with the code T2D2.
Then the selected element type is assigned to all elements using the method setElementType
of the part class. As parameters we pass a region, which is created with the mask #7 for all edges
and with an tuple of selected element types.
Within an ultimate step we simple call the method generateMesh of the part class.
Now the mesh is created with all it’s properties and with the method setValues of the standard
viewport instance, which is a member of the session class, we can view the mesh passing the
part instance as displayedObject parameter. If no viewport is explicitly created, the standard
viewport is called Viewport: 1.

(8) Create the job and submit


We set up the jobname and create the job using the standard parameter values. In this case the
job is executed immediately after submission. The return value of the creation step is saved into a
variable for later usage. After the creation of the job, the job is submitted with the job classes’ the
method submit. To automate the analysis of the results two features are available.

– synchronous analysis
In this case the script halts for completion of the calculation. This can be obtained by the
usage of the job classes’ method waitForCompletion. The next commands of the script
are executed after the calculation is completed.
– asynchronous analysis
In this case the script does not halt for completion and the next instructions are executed
immediately. To automate the analysis of the results we have to set up a call back function.
This function is executed automatically after the calculation is done.

2.12.2011
Page 76 Analysis of Structures - WS10/11

In our script we implement a synchronous analysis.

(9) Analysis of the result values


To start with the analysis we have to open the result database first. This can be done by the
openOdb method of the class visualization passing the name of the result database. The return
value is a reference to the data base instance.
To access the result values first we have to select the desired step. The step instance contains a
frame container. The result values are to obtain from the member class fieldOutputs. In our case
we select the displacements with the output variable name U. The stresses can be selected with
the output variable S. The values container of the fieldOutput instance contains a member
elementLabel, which is set, if an element result data set is available. If a node result data set
is available the nodeLabel member is set. The result values are items of the data array.
After the analysis is done, you should not forget to close the database with the close member
function.

Code of the Example 3-Trusses

# copy the next line into the abaqus command window and execute
# execfile("c:\\CM\\Cm-AoS\\WS1011\Abaqus\\3Trusses.py")

from abaqus import *


from abaqusConstants import *
from caeModules import * # this we need for regionToolset

modelname = ’3Trusses’

# delete old database if exists


try:
del mdb.Models[modelname]
print "model ’%s’ deleted." % modelname
except:
print "No model ’%s’ found!" % modelname

import os # os tools
os.chdir(r’c:\\cm\\Cm-AoS\\WS1011\\Abaqus’)

# set up parameters
dx = 1000. # length in x
dy = 1500. # length in z
A = 13.5*100. # U100 area
Fx = -100000. # horzontal load
Fy = -100000. # vertikal load
EMod = 210000. # Young’s module
nue = 0.3 # Poisson’s ratio

E. Baeck
5.1. 3 TRUSSES SCRIPT Page 77

# (1) create a model


myModel = mdb.Model(name=modelname, modelType=STANDARD EXPLICIT)

# (2) create a sketch


mySketch = myModel.ConstrainedSketch(name=’3Truss-Sketch’,
sheetSize=1.1*2*dy)

# - create tuple with coordinates


xyPoint = ( (0,0), (dx,0), (dx,dy), (0,dy) )
# - iterate the tuple and draw lines
for i in range(1,len(xyPoint)):
mySketch.Line(point1=xyPoint[0], point2=xyPoint[i])

# (3) create part


myPart = myModel.Part(name=’Trusse-Part-1’,
dimensionality=TWO D PLANAR, type=DEFORMABLE BODY)

# - assign the sketch


myPart.BaseWire(sketch=mySketch)

# (4) set up properties


# - create material for steel
mySteel = myModel.Material(name = ’Steel’)
mySteel.Elastic(table=( (EMod,nue), ))

# - create truss section


mySection = myModel.TrussSection(name=’Truss-Section’, area=A,
material=’Steel’)

# - assign the section to all lines


alledges = myPart.edges
edges = alledges.getSequenceFromMask(mask=(’[#7 ]’, ), )
region = regionToolset.Region(edges=edges)
myPart.SectionAssignment(region=region, sectionName=’Truss-Section’, offset=0.0
offsetType=MIDDLE SURFACE, offsetField=’’,
thicknessAssignment=FROM SECTION)

# (5) create an instance


root = myModel.rootAssembly
myInst = root.Instance(name=’Trusses-Instance’, part=myPart, dependent=ON)

# (6) create a load step


myModel.StaticStep(name=’First Step’, previous=’Initial’,
description=’Static Load Step’)

2.12.2011
Page 78 Analysis of Structures - WS10/11

# - create loads for the loadstep


v1 = myInst.vertices
verts1 = v1.getSequenceFromMask(mask=(’[#2 ]’, ), )
region = regionToolset.Region(vertices=verts1)
myModel.ConcentratedForce(name=’Load-1’,
createStepName=’First Step’, region=region, cf1=Fx, cf2=Fy,
distributionType=UNIFORM, field=’’, localCsys=None)

# - create boundary conditions for the loadstep


verts1 = v1.getSequenceFromMask(mask=(’[#d ]’, ), )
region = regionToolset.Region(vertices=verts1)
myModel.DisplacementBC(name=’BC-1’,
createStepName=’First Step’, region=region, u1=0.0, u2=0.0, ur3=UNSET,
amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName=’’,
localCsys=None)

# (7) create mesh


# - number of elments / line
e = myPart.edges
pickedEdges = e.getSequenceFromMask(mask=(’[#7 ]’, ), )
myPart.seedEdgeByNumber(edges=pickedEdges, number=1, constraint=FINER)

# - set up the element type


elemType1 = mesh.ElemType(elemCode=T2D2, elemLibrary=STANDARD)
e = myPart.edges
edges = e.getSequenceFromMask(mask=(’[#7 ]’, ), )
Region=(edges, )
myPart.setElementType(regions=Region, elemTypes=(elemType1, ))

# - create the mesh


myPart.generateMesh()

# - show the mesh


session.viewports[’Viewport: 1’].setValues(displayedObject=myPart)

# (8) create a job and submit it


jobname = modelname+’-Job-1’
myJob = mdb.Job(name=jobname, model=modelname,
description=’Calculation of the 3 Trusses System’, type=ANALYSIS,
atTime=None, waitMinutes=0, waitHours=0, queue=None, memory=50,
memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True,
explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, echoPrint=OFF,
modelPrint=OFF, contactPrint=OFF, historyPrint=OFF, userSubroutine=’’,
scratch=’’)

E. Baeck
5.1. 3 TRUSSES SCRIPT Page 79

myJob.submit(consistencyChecking=OFF)

# - note: wait for completion, if the result values should be read form DB
myJob.waitForCompletion()

# (9) analysis of results


# - open the database: odb file
myOdb = visualization.openOdb(jobname+’.odb’)

# - read data from the last frame


frame = myOdb.steps[’First Step’].frames[-1]

# - printing the displacements


data = frame.fieldOutputs[’U’]
n = len(data.values)
print "%d Result records" % n
print ’--no ---ux----- ---uy----’
for value in data.values:
print "%4d %10.5f %10.5f" % (value.nodeLabel,value.data[0],value.data[1])

# - printing the stresses


data = frame.fieldOutputs[’S’]
n = len(data.values)
print "%d Result records" % n
print ’--no --S11-----’
for value in data.values:
print "%4d %10.5f" % (value.elementLabel,value.data[0])

# close the database


myOdb.close()
End of Coding

2.12.2011
Page 80 Analysis of Structures - WS10/11

5.2 U Profile Script

The goal of our next example is, to create a mesh from a 2 dimensional
sketch of an U geometry by extrusion. Figure 5.2 shows an U profile with
it’s parameters [6].
The model of the U profile is created step by step according to the mod-
eling chain diagram (figure 4.2). The created mesh is shown in figure 5.2.
Figure 5.3 shows the load onto the upper flange of the girder. The girder is
supported on both ends at the lower flange’s edges. Additional point sup-
port is needed to avoid longitudinal and transversal movements as well as
rigid body rotations.
Note that the figures are printed automatically after having created the finite
element model. Figure 5.1: U Profile
Within the header section of the script all parameters are defined and ini-
tialized. The script is able to perform optionally a linear or a buckling analysis. This is controlled
by the flag bBuckl. Optionally system plots as well as result plots are created and printed into
png graphic files. This is controlled by the flag bPNGFile.
Within this implementation steps were recorded with the macro recorder and the recorded code
was reduced by the settings of standard parameters which are generally also recorded. Furthermore
we introduce consequently abbreviations for larger instance item accesses. This gives us a more
compact and readable code.

Automated creation and analysis of an U profile system

’’’
the script can be starte like this command
execfile("c:\\Cm\\CM-AoS\\Ws1011\\Abaqus\\UProfile2 1.py")

note: macros are recorded in to the work directory into a


file "abaqusMacros.py"
’’’
from abaqus import *
from abaqusConstants import *
from caeModules import *

import math

# set working folder


import os
os.chdir(r’C:\\CM\\Cm-AoS\\WS1011\\Abaqus’)

# >> for recording coordinate picking


# session.journalOptions.setValues(replayGeometry=COORDINATE)

from Base2 import Base

E. Baeck
5.2. U PROFILE SCRIPT Page 81

prjname = "UProfile2 1"


logname = prjname + ’.log’

Logger = Base(logname)
Logger.reset()
Logger.AppendLog(">> Project: ’%s’" % prjname)

# delete the model, if stil exists


try:
del mdb.models[prjname]
except:
pass

# (2) Create a sketch


# (2.1) - parameter
dH = 100.0 # profile height
dW = 50.0 # profile width
ds = 6.0 # web thickness
dt = 8.5 # flange thickness
dL = 4000. # profile length
EMod = 210000. # Young’s modul
nue = 0.3 # Poisson’s ratio
nSecSeed = 2 # elements on profile section lines
nDepSeed = 140 # elements in length direction
dPressur = 0.1 # pressure load
numEigen = 10 # number of eigenvalues
numIterX = 100 # maximum number of iterations

bBuckl = True # selection of the calculation


# True : buckling
# False: linear calculation
bPNGFile = True # Print png-File
# True : export png file
# False: no png file export

nodepos = {} # dictionary for node positions


nodedis = {} # dictionary for node displacements

# (1) Create a model


Logger.AppendLog("Create model...")
myModel = mdb.Model(name=prjname)

# (2.2) - the sketch


Logger.AppendLog("Create sketch...")

2.12.2011
Page 82 Analysis of Structures - WS10/11

mySketch = myModel.ConstrainedSketch(name=’UProfile-Sketch’, sheetSize=200)

# (2.3) - the points


xyPoints = ( (dW,-dH/2.), (0.,-dH/2.), (0.,dH/2.), (dW,dH/2.) )

# (2.4) - the lines


for i in range(1,len(xyPoints)):
mySketch.Line(point1 = xyPoints[i-1], point2 = xyPoints[i])

# (3) Create a part


Logger.AppendLog("Create part...")
myPart = myModel.Part(name=’UProfile-Part-1’, dimensionality=THREE D, \
type=DEFORMABLE BODY)

# - extrude the lines


myPart.BaseShellExtrude(sketch=mySketch, depth=dL)

# (4) Create a material


Logger.AppendLog("Create material and properties...")
myModel.Material(name=’Steel’,description=’Only Steel’)
myModel.materials[’Steel’].Elastic(table=((EMod, nue),))

# (5) Create a section of a profile


myModel.HomogeneousShellSection(name=’Section-Web’,material=’Steel’, \
thickness=ds)
myModel.HomogeneousShellSection(name=’Section-Flanch’,material=’Steel’, \
thickness=dt)

# (6) Assign the section


# - flanges
faces = myPart.faces.findAt(((dW/2.,-dH/2.,dL/2.),), ((dW/2.,+dH/2.,dL/2.),), )
region = regionToolset.Region(faces=faces)
myPart.SectionAssignment(region=region, sectionName=’Section-Flanch’)
# - web
faces = myPart.faces.findAt(((0.,0.,dL/2.),))
region = regionToolset.Region(faces=faces)
myPart.SectionAssignment(region=region, sectionName=’Section-Web’)

# (7) Create mesh


Logger.AppendLog("Create mesh...")
# - seed an profile lines
pickedEdges = myPart.edges.findAt(((dW/2.,-dH/2.,0.),), ((dW/2.,+dH/2.,0.),), \
((0,0,0),))
myPart.seedEdgeByNumber(edges=pickedEdges, number=nSecSeed)

E. Baeck
5.2. U PROFILE SCRIPT Page 83

# - seed in depth direction


pickedEdges = myPart.edges.findAt(((dW/2.,-dH/2.,dL),), ((dW/2.,+dH/2.,dL),), \
((0,0,dL),))
myPart.seedEdgeByNumber(edges=pickedEdges, number=nSecSeed)

# - seed in depth direction


pickedEdges = myPart.edges.findAt(((dW,-dH/2.,dL/2.),), ((0.,-dH/2.,dL/2.),), \
((0.,+dH/2.,dL/2.),), ((dW,+dH/2.,dL/2.),),)
myPart.seedEdgeByNumber(edges=pickedEdges, number=nDepSeed)

# - assign element type (optional)


elemType1 = mesh.ElemType(elemCode=S4R)
elemType2 = mesh.ElemType(elemCode=S3)
pickedEdges = myPart.faces.findAt(((dW/2.,-dH/2.,dL/2.),), \
((dW/2.,+dH/2.,dL/2.),), ((0.,0.,dL/2.),))
pickedRegions =(faces, )
myPart.setElementType(regions=pickedRegions, elemTypes=(elemType1, elemType2))

# - and mesh it
myMesh = myPart.generateMesh()

# overwrite
nodes = myPart.nodes
n = len(nodes)
Logger.SetTime(False)
Logger.SetScreen(False)
Logger.AppendLog(’\nNumber of mesh nodes: %d’ % n)
Logger.AppendLog(’--no ----x----- ----y----- ----y-----’)
for node in nodes:
nodepos[node.label] = (node.coordinates[0],node.coordinates[1], \
node.coordinates[2])
Logger.AppendLog("%4d %10.3f %10.3f %10.3f" % (node.label, \
node.coordinates[0], node.coordinates[1], \
node.coordinates[2]));
Logger.AppendLog(’--no ----x----- ----y----- ----y-----\n’)
Logger.SetTime(True)
Logger.SetScreen(True)

# (8) Create instance


Logger.AppendLog("Create instance...")
root = myModel.rootAssembly
myInst = root.Instance(name=’UProfile-Instance’, part=myPart, dependent=ON)

# (9a) Buckling analysis step


stepname = ’linear step’

2.12.2011
Page 84 Analysis of Structures - WS10/11

if bBuckl:
stepname = ’buckling step’
Logger.AppendLog("Create step ’%s’..." % stepname)
myModel.BuckleStep(name=stepname, previous=’Initial’,
description=’Bucklung Calculation’,
numEigen=numEigen, vectors=numEigen +8,
maxIterations = numIterX)
else:
# (9b) Linear static calculation step
Logger.AppendLog("Create step ’%s’..." % stepname)
myModel.StaticStep(name=stepname, previous=’Initial’,
description=’UProfile-Step1’)

# (10) Create a pressure


Logger.AppendLog("Create loads...")
side2Faces1 = myInst.faces.findAt(((dW/2.,+dH/2.,dL/2.),))
region = regionToolset.Region(side2Faces=side2Faces1)
myModel.Pressure(name=’TopLoad’, createStepName=stepname,
region=region, magnitude=dPressur)

# (10) Create boundary conditions


# - vertical on both ends
Logger.AppendLog("Create boundary conditions...")
edges1 = myInst.edges.findAt((((dW/2.,-dH/2.,0.)),),((dW/2.,-dH/2.,dL),),)
region = regionToolset.Region(edges=edges1)
myModel.DisplacementBC(name=’BC-1’, createStepName=stepname,
region=region, u1=UNSET, u2=0.0, u3=UNSET, ur1=UNSET, ur2=UNSET,
ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM,
fieldName=’’, localCsys=None)

# - fixed node on end


verts1 = myInst.vertices.findAt((((0.,-dH/2.,0.)),),)
region = regionToolset.Region(vertices=verts1)
myModel.DisplacementBC(name=’BC-2’, createStepName=stepname,
region=region, u1=0.0, u2=0.0, u3=0.0, ur1=UNSET, ur2=UNSET, ur3=UNSET,
amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName=’’,
localCsys=None)

# - fixed in vertical and transversal direction


verts1 = myInst.vertices.findAt((((dW,-dH/2.,0.)),),)
region = regionToolset.Region(vertices=verts1)
myModel.DisplacementBC(name=’BC-3’, createStepName=stepname,
region=region, u1=UNSET, u2=0.0, u3=0.0, ur1=UNSET, ur2=UNSET, ur3=UNSET,
amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName=’’,
localCsys=None)

E. Baeck
5.2. U PROFILE SCRIPT Page 85

# set an abrivation for the viewport pointer


myViewport = session.viewports[’Viewport: 1’]

# - and show the mesh and optionally export as png file


myViewport.setValues(displayedObject=root)
myViewport.assemblyDisplay.setValues(mesh=ON,loads=OFF,bcs=OFF)
if bPNGFile:
myViewport.view.fitView() # fit the plot to the view
pngfile = prjname +"-mesh"
session.printOptions.setValues(vpBackground=ON)
session.printToFile(fileName=pngfile, format=PNG,
canvasObjects=(myViewport, ))

# - and show the part and optionally export as png file


myViewport.setValues(displayedObject=root)
myViewport.assemblyDisplay.setValues(mesh=OFF, loads=ON,bcs=ON)
myViewport.assemblyDisplay.setValues(step=stepname)
if bPNGFile:
myViewport.view.fitView() # fit the plot to the view
pngfile = prjname +"-part"
session.printOptions.setValues(vpBackground=ON)
session.printToFile(fileName=pngfile, format=PNG,
canvasObjects=(myViewport, ))

# (12) Create a Job


jobname = prjname + ’-Job-1’
Logger.AppendLog("Create job ’%s’..." % jobname)
myJob = mdb.Job(name=jobname, model=prjname,
description=’Calculate the UProfile Structure’)

# (12) Submit the Job


Logger.AppendLog("Submit job...")
myJob.submit(consistencyChecking=OFF)
myJob.waitForCompletion()

# setup the result database name


odbname = jobname + ’.odb’ # set database name
mySession = session.openOdb(name=odbname) # set session pointer
# print data into the png file
if bPNGFile:

# Analyzis of the results


if bBuckl:

2.12.2011
Page 86 Analysis of Structures - WS10/11

# over all modes (eigenforms)


for mode in range(1,numEigen+1):
Logger.AppendLog("View buckling mode %d..." % mode)

# create plot
myViewport.setValues(displayedObject=mySession)
myViewport.odbDisplay.setFrame(step=0,frame=mode)
myViewport.odbDisplay.display.setValues(plotState=(
CONTOURS ON DEF, ))
myViewport.view.fitView() # fit the plot to the view

# ... and copy the plot into a png file


pngfile = prjname + ("-mode-%2.2d" % mode)
session.printOptions.setValues(vpBackground=ON)
session.printToFile(fileName=pngfile, format=PNG,
canvasObjects=(myViewport, ))

# linear calculation
else:

# plot mises
Logger.AppendLog("View Results...")
myViewport.setValues(displayedObject=mySession)
myViewport.odbDisplay.display.setValues(plotState=(
CONTOURS ON DEF, ))
myViewport.view.fitView()

# ... and print into png


pngfile = prjname + "-s"
session.printOptions.setValues(vpBackground=ON)
session.printToFile(fileName=pngfile, format=PNG,
canvasObjects=(myViewport, ))

# ... print displacements in U1, U2 and U3


varlist = ("U1","U2","U3")
for var in varlist:
myViewport.odbDisplay.setPrimaryVariable( \
variableLabel=’U’, outputPosition=NODAL, \
refinement=(COMPONENT,var))
myViewport.odbDisplay.display.setValues(plotState=(
CONTOURS ON DEF, ))
myViewport.view.fitView()

pngfile = prjname +"-" + var


session.printOptions.setValues(vpBackground=ON)

E. Baeck
5.2. U PROFILE SCRIPT Page 87

session.printToFile(fileName=pngfile, format=PNG,
canvasObjects=(myViewport, ))

# Printing and analysis of the displacments


Logger.AppendLog("Open database ’%s’..." % odbname)

# open database
myOdb = visualization.openOdb(odbname)

# get number of frames


step = myOdb.steps[stepname]
nFrames = len(step.frames)

# print the displacements of every frame


for nFrame in range(1,nFrames):

# select the displacements


frame = step.frames[nFrame]
data = frame.fieldOutputs[’U’]

Logger.SetTime(False)
Logger.SetScreen(False)

# write a header
Logger.AppendLog("\nData of frame %d" % nFrame)
header = "\n--no ---ux----- ---uy----- ---uz-----|"
header += " ----x----- ----y----- ----z-----"
Logger.AppendLog(header)

# over all nodes and it’s displacements


for value in data.values:
nodedis[value.nodeLabel] = (value.data[0],value.data[1],value.data[2])
Logger.AppendLog("%4d %10.3f %10.3f %10.3f| %10.3f %10.3f %10.3f " % \
(value.nodeLabel,value.data[0],value.data[1],value.data[2], \
nodepos[value.nodeLabel][0], \
nodepos[value.nodeLabel][1], \
nodepos[value.nodeLabel][2],))
Logger.AppendLog(header)

# maximum search
max = [None, None, None]
pos = [None, None, None]

# over all directions


for i in range(3):

2.12.2011
Page 88 Analysis of Structures - WS10/11

# over all nodes


for nodeLabel in nodedis:

# get the node label


disv = nodedis[nodeLabel]

# initialize the max search


if max[i] is None:
max[i] = disv[i]
pos[i] = nodeLabel

# if new max found, save it and it’s node label


else:
if math.fabs(disv[i]) > math.fabs(max[i]):
max[i] = disv[i]
pos[i] = nodeLabel

# enable time stamp and screen output


Logger.SetTime(True)
Logger.SetScreen(True)

Logger.AppendLog("\nmaximum displacement of nodes in frame: %d" % nFrame)

# over all directions


labels = ("x","y","z")
ind = 0
for label in labels:
xyz = nodepos[pos[ind]]
Logger.AppendLog(’ %s: node %3d : %10.3f > %10.3f %10.3f %10.3f’ % \
(label,pos[ind],max[ind],xyz[0],xyz[1],xyz[2]))
ind += 1

# close database to avoid locking


myOdb.close()

# close Logger
Logger.AppendLog("----> end of script")
del Logger
End of Coding

Figure 5.4 shows the resulting Mieses stresses of a linear analysis. Figure 5.5 shows the resulting dis-
placements in 1(x), 2(y) and 3(z) direction of a linear analysis.
The figures 5.6 to 5.15 show the first 10 buckling modes of the girder.

E. Baeck
5.2. U PROFILE SCRIPT Page 89

Figure 5.2: U profile’s mesh

Figure 5.3: U profile’s loads and boundary conditions

Figure 5.4: Mieses stresses of a linear analysis

2.12.2011
Page 90 Analysis of Structures - WS10/11

Figure 5.5: Displacement in 1,2 and 3 direction of a linear analysis

E. Baeck
5.2. U PROFILE SCRIPT Page 91

Figure 5.6: Buckling mode 1

Figure 5.7: Buckling mode 2

Figure 5.8: Buckling mode 3

2.12.2011
Page 92 Analysis of Structures - WS10/11

Figure 5.9: Buckling mode 4

Figure 5.10: Buckling mode 5

Figure 5.11: Buckling mode 6

E. Baeck
5.2. U PROFILE SCRIPT Page 93

Figure 5.12: Buckling mode 7

Figure 5.13: Buckling mode 8

Figure 5.14: Buckling mode 9

2.12.2011
Page 94 Analysis of Structures - WS10/11

Figure 5.15: Buckling mode 10

E. Baeck
Part III

Appendix

95
Appendix A

Some Theory

A.1 Section Properties

Within this chapter the formulas for the section properties of a thin walled model are given.
A thin walled model for a profile section consists of a set of lines which describes the profile section
geometry at the centerline.

A.1.1 The Area of a Profile Section

The Area is approximately the sum of the areas of the lines of the thin walled model.
Z n
X
A= eµ · dA ≈ eµ,i · Li · ti (A.1)
A i=1

with: Li the length of line i


ti the thickness of line i
eµ,i the relative elasticity of line i (1 for only one material)

A.1.2 First Moments of an Area

The first moments of an area are the area integrals given below. The (y,z) values are related to an given
coordinate system.
Z n
X
Sy = eµ · z · dA ≈ eµ,i · z i · Ai
A i=1
Z n
X
Sz = eµ · y · dA ≈ eµ,i · y i · Ai (A.2)
A i=1

with: Ai the area of a line i


yi the y coordinate of the center of line i
zi the z coordinate of the center of line i

97
Page 98 Analysis of Structures - WS10/11

A.1.3 Second Moments of an Area or Moments of Inertia

The moments of inertia can be calculated with the formulas below. If we have a given arbitrary coordinate
system in general we have three values of inertia the Iy , the Iz and the mixed Iyz . If we use the main
coordinate system, the mixed moment of inertia is vanishing, so we use the symbols Iξ and Iη .
Z n
X
eµ · z 2 · dA ≈ (zb,i − za,i )2 /12) + z 2i · Ai
 
Iy = eµ,i ·
A i=1
Z Xn
eµ · y 2 · dA ≈ (yb,i − ya,i )2 /12) + y 2i · Ai
 
Iz = eµ,i ·
A i=1
Z Xn
Iyz = eµ · y · z · dA ≈ eµ,i · (((yb,i − ya,i )(zb,i − za,i )/12) + y i · z i ) · Ai ) (A.3)
A i=1

with: Ai the area of a line i


yi the y coordinate of the center of line i
zi the z coordinate of the center of line i
ya,i the y coordinate of the first point of line i
za,i the z coordinate of the first point of line i
yb,i the y coordinate of the second point of line i
zb,i the z coordinate of the second point of line i

To solve an integral like Iy = A z 2 · dA for a polyline we can split up the integral into the sum of
R

integrals over the polyline segments.


Z n Z
X
2
Iy = z · dA = z 2 · dA (A.4)
A i=1 Ai

To solve an integral for a polyline segment we simple calculate it for the center of mass, because a simple
shift only will give us an additional term, the Steiner term. If we now want to calculate the polyline
integral at the center of mass we rotate the coordinate system by an angle ϕ into the line’s longitudinal
direction, because the transversal dimension, the thickness, is constant and so the respective integral will
be trivial.

E. Baeck
A.1. SECTION PROPERTIES Page 99

Thus we make the following substitution.

(y, z ) ⇒ (η, ξ) (A.5)


z = ξ/cos(ϕ) (A.6)

With this substitution we will get the following integral.


η=+t ξ=+L/2
ξ2
Z Z
Iy,i = · dη · dξ
η=−t ξ=−L/2 cos(ϕ)2
Z ξ=+L/2
ξ2
=t· · dξ
cos(ϕ)2
ξ=−L/2
ξ=+L/2
ξ3 1
=t· ·
3 cos(ϕ)2 ξ=−L/2
L3 1
=t· ·
12 cos(ϕ)2
(zb,i − za,i )2
= · Ai with t · L = Ai (A.7)
12

A.1.4 Center of Mass

The coordinates of the center of mass are calculated with the arithmetic mean. Because the numerator of
the arithmetic mean is identical with the first moment of the area (see section A.1.2) and the denominator
is identical with the area of the profile, which is calculated in section A.1.1 we can use this values.
R
y · dA Sz
yc = AR =
dA A
R A
z · dA Sy
zc = AR = (A.8)
A dA A

A.1.5 Moments of Inertia with Respect to the Center of Mass

If we know the center of mass coordinates given in section A.1.4 we can calculate the moments of inertia
with respect to the center of mass using Steiner’s Theorem as follows.

Iy,c = Iy − zc2 · A
Iz ,c = Iz − yc2 · A
Iyz ,c = Iyz − yc · zc · A (A.9)

2.12.2011
Page 100 Analysis of Structures - WS10/11

A.1.6 Main Axis Transformation

To get the moments of inertia Iξ and Iη we have to transform the moments of inertia into the main
coordinate system. Using this coordinate system the mixed moment of inertia is vanishing.
The main axis transformation is given with equation A.10.1

Idel = Iz ,c − Iy,c
Isum = Iy,c + Iz ,c
q
2 + 4 · I2
Isqr = IDel yz ,c
1 2 · Iyz ,c
ϕ= · arctan( )
2 Idel
1
Iξ = · (Isum + Isqr )
2
1
Iη = · (Isum − Isqr ) (A.10)
2

1
The rotation angle ϕ should be shifted into the intervall [−π/2... + π/2]. To avoid a zero division calculating the rotation
angle ϕ a special version of the atan function should be used, which is able to handle the pole problem. In Python like in C this
function is called atan2(y, x ), which calculates the atan( xy ).

E. Baeck
Bibliography

[1] H.P. Langtangen:


A Primer on Scientific Programming with Python
Springer-Verlag Berlin Heidelberg, 2009
[2] NumPy Community:
NumPy User Guide
Release 1.4.1, April 2010
[3] SciPy Community:
SciPy Reference Guide
Release 0.8.dev, February 2010
[4] ISO/IEC 19501:2005
Information technology – Open Distributed Processing – Unified Modeling Language
(UML) Version 1.4.2
[5] D. G. Taggart
University of Rhode Island, 2009
[6] O. Lueger
Lexikon der Technik, 1904

101
Index

:, 28 area, 97
arithmetic mean, 99
Abaqus as, 14
abaqusMacros, 73
BaseWire, 74 Basic, 20
close, 76 bit’s values , 16
ConstrainedSketch, 74 break, 23
DisplacementBC, 75 buckling analysis, 80
element type buckling modes, 88
T2D2, 75
C, 15, 19, 20, 22
elemType, 75
center of mass, 99
fieldOutputs, 76
chdir, 73
frame, 76
class
generateMesh, 75
AList, 53, 58
getSequenceFromMask, 74
Base, 52
instance, 74
Line, 58
job, 75
Point, 56
material, 74 ProfDB, 64
mesh, 75 Profile, 53
model, 73 Profiles, 51
openOdb, 76 UProfile, 51
part, 74 code blocks, 21
regionToolset, 75 complement, 15
rootAssembly, 74 ComTypes, 6
SectionAssignment, 74 continue, 23
seedEdgeByNumber, 75 cos, 14
session, 75 count, 33
setElementType, 75
StaticStep, 75 datetime, 38
step, 76 day, 38
submit, 75 def, 28
TrussSection, 74 derivative, 29
values, 76 dictionary, 34, 62
vertices, 75
e/E format, 20
viewport, 75
eigenforms, 88
visualization, 76
eigenvalues, 88
waitForCompletion, 75
extend, 33
append, 33
Aptana, 8 f format, 20

102
INDEX Page 103

factorial, 22 Parameters, 28
factorial(170), 24 pi, 14
factorial(400), 24 PNG export, 80
file pop, 33
close, 41 printf, 19
open, 40 push, 34
write, 40 PyDev, 8
Finite Element Model, 69 PyLab, 62
first moment, 97 PythonWin, 10
float, 20
random, 35
for, 22
remove, 33
Fortran, 20
reserved words, 13
g/G format, 20 return, 28
reverse, 33
hour, 38
SciPy, 7
IDE, 8
second, 38
if, 25
second moment, 98
import, 14
Setup, 5
indent, 22
sin, 14
index, 33
site-packages, 5
insert, 33
sort, 33
int, 20
stack, 34
Interactive window, 10
strings, 32
iteration, 29
The Beatles, 35
Lib, 5
timedelta, 38
LIFO, 34
Tkinter, 53
linear analysis, 80
tuple, 32
list, 32, 33
type, 21
long, 20
type checking, 28
main axis, 100
UML, 41
map, 34
aggregation, 42
microsecond, 38
class diagram, 41
minute, 38
composition, 42
moment of inertia, 98
inheritance diagram, 42
month, 38
note diagram, 42
name, 21 note diagram assignment, 42
negative number, 15
version, 5
Newton’s Algorithm, 30
now, 38 while, 22
NumPy, 7
year, 38
OOP, 41

package, 14, 52

2.12.2011

Anda mungkin juga menyukai