SfePy Documentation

SfePy Documentation
SfePy Documentation
Release 2015.1
Robert Cimrman and Contributors
February 26, 2015
CONTENTS
1
Introduction
1
2
Installation
2.1 Platforms . . . . . . . . . . . . . .
2.2 Requirements . . . . . . . . . . . .
2.3 Generic Installation Instructions . .
2.4 Testing . . . . . . . . . . . . . . .
2.5 Debugging . . . . . . . . . . . . .
2.6 Using IPython . . . . . . . . . . .
2.7 Multi-platform Distributions Notes
2.8 Platform-specific Notes . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
4
5
6
6
7
7
Tutorial
3.1 Basic notions . . . . . . . . . . . . .
3.2 Running a simulation . . . . . . . . .
3.3 Example problem description file . .
3.4 Interactive Example: Linear Elasticity
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
12
13
16
User’s Guide
4.1 Running a Simulation . . .
4.2 Visualization of Results . .
4.3 Problem Description File . .
4.4 Building Equations in SfePy
4.5 Term Evaluation . . . . . .
4.6 Solution Postprocessing . .
4.7 Probing . . . . . . . . . . .
4.8 Postprocessing filters . . . .
4.9 Available Solvers . . . . . .
4.10 Isogeometric Analysis . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
25
27
30
42
43
44
45
46
46
47
5
Examples
5.1 Primer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Using Salome with SfePy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
49
72
75
6
Theoretical Background
317
6.1 Notes on solving PDEs by the Finite Element Method . . . . . . . . . . . . . . . . . . . . . . . . . 317
6.2 Implementation of Essential Boundary Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
7
Developer Guide
323
7.1 SfePy Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
3
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
i
7.2
7.3
7.4
7.5
7.6
7.7
7.8
8
Exploring the Code . . . . . . . . .
How to Contribute . . . . . . . . .
How to Regenerate Documentation
How to Implement a New Term . .
How To Make a Release . . . . . .
Working with SfePy source code . .
Module Index . . . . . . . . . . . .
Indices and tables
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
327
328
347
347
352
354
369
661
Bibliography
663
Python Module Index
665
Python Module Index
669
Index
673
ii
CHAPTER
ONE
INTRODUCTION
SfePy (http://sfepy.org) is a software for solving systems of coupled partial differential equations (PDEs) by the finite
element method in 1D, 2D and 3D. It can be viewed both as black-box PDE solver, and as a Python package which
can be used for building custom applications. The word “simple” means that complex FEM problems can be coded
very easily and rapidly.
There is also a preliminary support for the isogeometric analysis, outlined in Isogeometric Analysis.
The code is written almost entirely in Python, with exception of the most time demanding routines - those are written
in C and wrapped by Cython or written directly in Cython.
SfePy is a free software released under the New BSD License. It relies on NumPy and SciPy (an excellent collection
of tools for scientific computations in Python). It is a multi-platform software that should work on Linux, Mac OS X
and Windows.
SfePy was originally developed as a flexible framework to quickly implement and test the mathematical models developed during our various research projects. It has evolved, however, to a rather full-featured (yet small) finite element
code. Many terms have been implemented that can be used to build the PDEs, see Term Overview. SfePy comes also
with a number of examples that can get you started, check Examples and Tutorial. Some more advanced features are
discussed in Primer.
1
SfePy Documentation, Release 2015.1
2
Chapter 1. Introduction
CHAPTER
TWO
INSTALLATION
Table of Contents
• Platforms
• Requirements
• Generic Installation Instructions
– Compilation of C Extension Modules
– Installation
• Testing
– In-place Build
– Installed Build
• Debugging
• Using IPython
• Multi-platform Distributions Notes
– Anaconda
• Platform-specific Notes
– Gentoo
– Archlinux
* Instructions
– Debian
– Ubuntu
* Prerequisites
· Older Versions of Ubuntu
Installing
SfePy
*
– Fedora 8
– Windows Using Python(x,y)
* Steps to Get a Working SfePy on Windows Using Python(x,y)
2.1 Platforms
SfePy is known to work on various flavors of Linux, on Intel Macs and Windows.
2.2 Requirements
Installation prerequisites, required to build SfePy:
• a C compiler suite (for example gcc)
3
SfePy Documentation, Release 2015.1
• Python 2.6 or 2.7
• NumPy
• Cython
Python packages required for using SfePy:
• Pyparsing
• SciPy, preferably with umfpack wrapper, or umfpack scikit
• Matplotlib, for various plots; GTKAgg for live plotting via log.py
• PyTables, for storing results in HDF5 files
• SymPy, for some tests and functions)
• Mayavi, for postproc.py
• Pysparse, for schroedinger.py
• igakit, for script/gen_iga_patch.py - simple IGA domain generator
Other dependencies:
• To be able to (re)generate the documentation: Sphinx, numpydoc, LaTeX, see How to Regenerate Documentation.
• If doxygen is installed, the documentation of data structures and functions can be automatically generated by
running “python setup.py doxygendocs”. Then see “doc/html/index.html”.
• Mesh generation tools use pexpect and gmsh or tetgen.
• IPython is preferred over the regular Python shell for following some parts of primer/tutorial.
On Linux, consult the package manager of your favorite distribution, see Platform-specific Notes.
On Windows a completely free scientific-oriented distributions Python(x,y) and WinPython can be used, but some
missing packages may need to be installed manually. Instructions for installing Python(x,y) can be found in Windows
Using Python(x,y).
Furthermore, free versions of commercial multi-platform scientific Python distributions Enthought Canopy (formerly
Enthought PythonDistribution) and Anaconda (Continuum Analytics) can be used (and recomended), see Multiplatform Distributions Notes.
SfePy can be used without any installation by running the scripts from the top-level directory of the distribution, or
can be installed locally or system-wide.
SfePy should work both with bleeding edge (Git) and last released versions of NumPy and SciPy. Submit an issue at
Issues page in case this does not hold.
2.3 Generic Installation Instructions
Download the latest source release or the development version from SfePy git repository:
git clone git://github.com/sfepy/sfepy.git
See the download page for additional download options.
4
Chapter 2. Installation
SfePy Documentation, Release 2015.1
2.3.1 Compilation of C Extension Modules
In the SfePy top-level directory:
1. Look at site_cfg_template.py and follow the instructions therein. Usually no changes are necessary.
2. Compile the extension modules
(a) for in-place use:
python setup.py build_ext --inplace
(b) for installation:
python setup.py build
We recommend starting with the in-place build.
2.3.2 Installation
(As mentioned above, this step is not required to use SfePy.)
• System-wide (may require root privileges):
python setup.py install
• Local (requires write access to <installation prefix>):
python setup.py install --root=<installation prefix>
If all went well, proceed with Testing.
2.4 Testing
After building in-place or installing SfePy you can check if all the functions are working by running the automated
tests.
2.4.1 In-place Build
In the source directory type:
python run_tests.py
If a particular test fails, please run it in debug mode:
python run_tests.py --debug tests/failing_test_name.py
and report the output to the SfePy mailing list.
On a Linux-based system, the script can be executed directly by:
./run_tests.py
2.4. Testing
5
SfePy Documentation, Release 2015.1
2.4.2 Installed Build
In a directory different from the source directory, run:
python run_tests.py
or (on Linux):
run_tests.py
Note that this command creates a directory called ’output’ in the current directory as well as some other auxiliary
files. Use the in-place build testing if you do not want to care about this.
2.5 Debugging
If something goes wrong, set debug_flags = ’-DDEBUG_FMF’ in site_cfg.py to turn on bound checks in
the low level C functions, and recompile the code:
python setup.py clean
python setup.py build_ext --inplace
Then re-run your code and report the output.
2.6 Using IPython
It is preferable to use (a customized) IPython over the regular Python shell when following Tutorial or Primer. Install
IPython and then customize it as follows:
1. Create a new profile:
ipython profile create sfepy
2. Open the ~/.ipython/profile_sfepy/ipython_config.py file in a text editor and add/edit after
the c = get_config() line the following:
exec_lines = [
’from sfepy.base.base import *’,
’from sfepy.discrete import *’,
’from sfepy.discrete.fem import *’,
’from sfepy.applications import solve_pde’,
’import matplotlib as mpl’,
’mpl.use("WXAgg")’,
’from matplotlib.pyplot import *’,
’from sfepy.postprocess.viewer import Viewer’,
]
c.InteractiveShellApp.exec_lines = exec_lines
c.TerminalIPythonApp.gui = ’wx’
c.TerminalInteractiveShell.colors = ’Linux’ # NoColor, Linux, or LightBG
3. Run the customized IPython shell:
ipython --profile=sfepy
6
Chapter 2. Installation
SfePy Documentation, Release 2015.1
2.7 Multi-platform Distributions Notes
2.7.1 Anaconda
(tested Python 2.7 64-Bit on Ubuntu 14.04 LTS, Windows 8.1 and Mac OS X 10.10)
Download appropriate Anaconda Python 2.7 installer package (valid e-mail address is required, but no further Ads)
and follow install instructions. We recommend to choose user-level install option (no admin privileges required).
Install missing/required packages using built-in conda package manager:
conda install mayavi wxpython
Occasionally, you should check for distribution and/or installed packages updates (there is no built-in automatic update
mechanism available):
conda update conda
conda update anaconda
conda update <package>
See conda help for further information.
2.8 Platform-specific Notes
The following information has been provided by users of the listed platforms and may become obsolete over time. The
generic installation instructions above should work in any case, provided the required dependencies are installed.
2.8.1 Gentoo
emerge -va pytables pyparsing numpy scipy matplotlib ipython mayavi
2.8.2 Archlinux
pacman -S python2-numpy python2-scipy python2-matplotlib ipython2 python2-sympy
yaourt -S python-pytables python2-mayavi
Instructions
Edit Makefile and change all references from python to python2. Edit scripts and change shebangs to point to python2.
2.8.3 Debian
(old instructions, check also Ubuntu below)
apt-get install python-tables python-pyparsing python-matplotlib python-scipy
2.8.4 Ubuntu
(tested on Ubuntu 14.04 LTS and 14.10)
2.7. Multi-platform Distributions Notes
7
SfePy Documentation, Release 2015.1
Prerequisites
First, you have to install the dependencies packages:
sudo aptitude install python-scipy python-matplotlib python-tables python-pyparsing libsuitesparse-de
The same packages work also in Kubuntu 14.10. If aptitude is not installed, install it, or try apt-get install instead.
Older Versions of Ubuntu
(tested on Jaunty Jackalope 9.04 and Lucid Lynx 10.04)
The following is required to get working umfpack. Download and install the umfpack scikits in some local dir. In the
following example it will be installed in $HOME/local:
svn checkout http://svn.scipy.org/svn/scikits/trunk/umfpack
cd umfpack
mkdir -p ${HOME}/local/lib/python2.6/site-packages
python setup.py install --prefix=${HOME}/local
Add to your .bashrc the line:
export PYTHONPATH="${HOME}/local"
then re-open a terminal and if the scikits was installed correctly importing scikits.umfpack in python should give no
error:
python
>>> import scikits.umfpack
>>>
Next Download sympy 6.7 or later. Extract the contents.
cd sympy-0.6.7
python setup.py install –prefix=${HOME}/local
Installing SfePy
Now download the latest SfePy tarball release (or the latest development version).
Uncompress the archive and enter the SfePy dir, then type:
python setup.py build_ext --inplace
after a few minutes the compilation finishes.
Finally you can test SfePy with:
./run_tests.py
If some test fails see Testing section for further details.
2.8.5 Fedora 8
Notes on using umfpack (contributed by David Huard).
entry in numpy site.cfg:
8
Chapter 2. Installation
SfePy Documentation, Release 2015.1
[umfpack]
library_dirs=/usr/lib64
include_dirs = /usr/include/suitesparse
Comment by david.huard, Mar 26, 2008:
Of course, suitesparse and suitesparse-devel must be installed.
2.8.6 Windows Using Python(x,y)
(tested on Windows 7/8.1)
Here we provide instructions for using SfePy on Windows through Python(x,y). We will also use msysgit to install the
umfpack scikit to speed up performance.
This procedure should work in theory for any recent Windows version supported by Python(x,y) and msysgit, but your
milage may vary.
There several steps, but hopefully it is straightforward to follow this procedure. If you have any questions or difficulties
please feel free to ask on the SfePy mailing list (see SfePy web site). Also, if you have any suggestions for improving
or streamlining this process, it would be very beneficial as well!
We assume the installation to be done in C:\ - substitute your path where appropriate.
Steps to Get a Working SfePy on Windows Using Python(x,y)
1. Minimum 4 GB of free disk space is required due to the installed size of python(x,y) and msysgit.
2. Download the latest Python(x,y) windows installer (version 2.7.X.X) and make a Full installation in the default
installation directory.
3. Download the latest pyparsing windows installer (Python version 2.7) and install it in the default installation
directory.
4. Download the latest msysgit windows installer and install it in the default installation directory:
• either get the file that begins with “Git-”, which gives you gitbash - a bash shell in Windows,
• or get the file that begins with “msysGit-fullinstall”.
Below we refer to either gitbash or msys as “shell”.
5. Download the latest umfpackpy zip archive and follow the instructions below:
(a) Extract the umfpackpy_<version>.zip to your convenient location in Hard disk, Lets assume it’s extracted
in C:\. Now there will be two files on the extracted folder, ez_setup.py and scikits.umfpack-5.1.0-py2.7win32.egg.
(b) Start a shell and write the following to go to the extracted folder:
cd /c/umfpackpy_<version>/
(c) Install the UMFPACK library for Python:
ez_setup.py scikits.umfpack-5.1.0-py2.7-win32.egg
6. Either download the latest SfePy tarball and extract it to your convenient location in hard disk, lets assume it’s
extracted in C:\.
Or, if you want to use the latest features and contribute to the development of SfePy, clone the git development
repository
2.8. Platform-specific Notes
9
SfePy Documentation, Release 2015.1
• In shell, type:
cd /c/
git clone git://github.com/sfepy/sfepy.git
Then follow the instructions below:
(a) In shell, go to the extracted folder:
cd /c/sfepy_folder_name/
(b) Compile SfePy C extensions:
python setup.py build_ext --inplace --compiler=mingw32
7. You should now have a working copy of SfePy on Windows. Please help aid SfePy development by running the
built-in tests. Run the run_tests.py in Python IDLE or write the following code in the shell:
./run_tests.py --filter-less
• Report any failures to the SfePy mailing list.
• See Testing for further details.
10
Chapter 2. Installation
CHAPTER
THREE
TUTORIAL
Table of Contents
• Basic notions
– Sneak peek: what is going on under the hood
• Running a simulation
– Invoking SfePy from the command line
– Postprocessing the results
• Example problem description file
• Interactive Example: Linear Elasticity
– Complete Example as a Script
SfePy can be used in two basic ways:
1. a black-box partial differential equation (PDE) solver,
2. a Python package to build custom applications involving solving PDEs by the finite element (FE) method.
This tutorial focuses on the first way and introduces the basic concepts and nomenclature used in the following parts
of the documentation. Check also the Primer which focuses on a particular problem in detail.
Users not familiar with the finite element method should start with the Notes on solving PDEs by the Finite Element
Method.
3.1 Basic notions
The simplest way of using SfePy is to solve a system of PDEs defined in a problem description file, also referred to
as input file. In such a file, the problem is described using several keywords that allow one to define the equations,
variables, finite element approximations, solvers, solution domain and subdomains etc., see Problem Description File
for a full list of those keywords.
The syntax of the problem description file is very simple yet powerful, as the file itself is just a regular Python module
that can be normally imported - no special parsing is necessary. The keywords mentioned above are regular Python
variables (usually of the dict type) with special names.
Below we show:
1. how to solve a problem given by a problem description file, and
2. explain the elements of the file on several examples.
But let us begin with a slight detour...
11
SfePy Documentation, Release 2015.1
3.1.1 Sneak peek: what is going on under the hood
1. A top-level script (usually simple.py, as in this tutorial) reads in an input file.
2. Following the contents of the input file, a Problem instance is created - this is the input file coming to life. Let
us call the instance problem.
• The problem sets up its domain, regions (various sub-domains), fields (the FE approximations), the
equations and the solvers. The equations determine the materials and variables in use - only those are fully
instantiated, so the input file can safely contain definitions of items that are not used actually.
3. Prior to solution, problem.time_update() function has to be called to setup boundary conditions, material parameters and other potentially time-dependent data. This holds also for stationary problems with a single
“time step”.
4. The solution is then obtained by calling problem.solve() function.
5. Finally, the solution can be stored using problem.save_state()
The above last three steps are essentially repeated for each time step. So that is it - using the code a black-box PDE
solver shields the user from having to create the Problem instance by hand. But note that this is possible, and often
necessary when the flexibility of the default solvers is not enough. At the end of the tutorial an example demonstrating
the interactive creation of the problem is shown, see Interactive Example: Linear Elasticity.
Now let us continue with running a simulation.
3.2 Running a simulation
The following commands should be run in the top-level directory of the SfePy source tree after compiling the C
extension files. See Installation for full installation instructions.
3.2.1 Invoking SfePy from the command line
This section introduces the basics of running SfePy on the command line. The $ indicates the command prompt of
your terminal.
• The script simple.py is the most basic starting point in SfePy. It is invoked as follows:
$ ./simple.py examples/diffusion/poisson_short_syntax.py
– examples/diffusion/poisson_short_syntax.py is the SfePy problem description file,
which defines the problem to be solved in terms SfePy can understand
– Running the above command creates the output file cylinder.vtk in the SfePy top-level directory
• SfePy can also be invoked interactively using IPython with custom imports, as described in Using IPython. In
the SfePy top-level directory, run:
$ ipython --profile=sfepy
See Interactive Example: Linear Elasticity for more information.
3.2.2 Postprocessing the results
• The postproc.py script can be used for quick postprocessing and visualization of the SfePy output files. It
requires mayavi2 installed on your system.
12
Chapter 3. Tutorial
SfePy Documentation, Release 2015.1
– As a simple example, try:
$ ./postproc.py cylinder.vtk
– The following interactive 3D window should display:
• The left mouse button by itself orbits the 3D view
• Holding shift and the left mouse button pans the view
• Holding control and the left mouse button rotates about the screen normal axis
• The right mouse button controls the zoom
3.3 Example problem description file
Here we discuss the contents of the examples/diffusion/poisson_short_syntax.py problem description file. For additional examples, see the problem description files in the examples/ directory of SfePy.
The problem at hand is the following:
𝑐∆𝑇 = 𝑓 in Ω,
𝑇 (𝑡) = 𝑇¯(𝑡) on Γ ,
(3.1)
where Γ ⊆ Ω is a subset of the domain Ω boundary. For simplicity, we set 𝑓 ≡ 0, but we still work with the material
constant 𝑐 even though it has no influence on the solution in this case. We also assume zero fluxes over 𝜕Ω ∖ Γ, i.e.
𝜕𝑇
𝜕𝑛 = 0 there. The particular boundary conditions used below are 𝑇 = 2 on the left side of the cylindrical domain
depicted in the previous section and 𝑇 = −2 on the right side.
The first step to do is to write (3.1) in weak formulation (??). The 𝑓 = 0, 𝑔 =
form (??) remains:
∫︁
𝑐 ∇𝑇 · ∇𝑠 = 0, ∀𝑠 ∈ 𝑉0 .
𝜕𝑇
𝜕𝑛
= 0. So only one term in weak
(3.2)
Ω
3.3. Example problem description file
13
SfePy Documentation, Release 2015.1
Comparing the above integral term with the long table in Term Overview, we can see that SfePy contains this term
under name dw_laplace. We are now ready to proceed to the actual problem definition.
Open the examples/diffusion/poisson_short_syntax.py file in your favorite text editor. Note that the
file is a regular python source code.
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
The filename_mesh variable points to the file containing the mesh for the particular problem. SfePy supports a
variety of mesh formats.
materials = {
’coef’: ({’val’ : 1.0},),
}
Here we define just a constant coefficient 𝑐 of the Poisson equation, using the ’values’ attribute. Other possible
attribute is ’function’, for material coefficients computed/obtained at runtime.
Many finite element problems require the definition of material parameters. These can be handled in SfePy with
material variables which associate the material parameters with the corresponding region of the mesh.
regions = {
’Omega’ : ’all’, # or ’cells of group 6’
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
}
Regions assign names to various parts of the finite element mesh. The region names can later be referred to, for
example when specifying portions of the mesh to apply boundary conditions to. Regions can be specified in a variety
of ways, including by element or by node. Here, Omega is the elemental domain over which the PDE is solved and
Gamma_Left and Gamma_Right define surfaces upon which the boundary conditions will be applied.
fields = {
’temperature’: (’real’, 1, ’Omega’, 1)
}
A field is used mainly to define the approximation on a (sub)domain, i.e. to define the discrete spaces 𝑉ℎ , where we
seek the solution.
The Poisson equation can be used to compute e.g. a temperature distribution, so let us call our field ’temperature’.
On the region ’Omega’ it will be approximated using linear finite elements.
A field in a given region defines the finite element approximation. Several variables can use the same field, see below.
variables = {
’t’: (’unknown field’, ’temperature’, 0),
’s’: (’test field’, ’temperature’, ’t’),
}
One field can be used to generate discrete degrees of freedom (DOFs) of several variables. Here the unknown variable
(the temperature) is called ’t’, it’s associated DOF name is ’t.0’ — this will be referred to in the Dirichlet boundary
section (ebc). The corresponding test variable of the weak formulation is called ’s’. Notice that the ’dual’ item
of a test variable must specify the unknown it corresponds to.
For each unknown (or state) variable there has to be a test (or virtual) variable defined, as usual in weak formulation
of PDEs.
ebcs = {
’t1’: (’Gamma_Left’, {’t.0’ : 2.0}),
14
Chapter 3. Tutorial
SfePy Documentation, Release 2015.1
’t2’, (’Gamma_Right’, {’t.0’ : -2.0}),
}
Essential (Dirichlet) boundary conditions can be specified as above.
Boundary conditions place restrictions on the finite element formulation and create a unique solution to the problem.
Here, we specify that a temperature of +2 is applied to the left surface of the mesh and a temperature of -2 is applied
to the right surface.
integrals = {
’i’: 2,
}
Integrals specify which numerical scheme to use. Here we are using a 2nd order quadrature over a 3 dimensional
space.
equations = {
’Temperature’ : """dw_laplace.i.Omega( coef.val, s, t ) = 0"""
}
The equation above directly corresponds to the discrete version of (3.2), namely: Find 𝑡 ∈ 𝑉ℎ , such that
∫︁
𝑠𝑇 (
𝑐 𝐺𝑇 𝐺)𝑡 = 0, ∀𝑠 ∈ 𝑉ℎ0 ,
Ωℎ
where ∇𝑢 ≈ 𝐺𝑢.
The equations block is the heart of the SfePy problem definition file. Here, we are specifying that the Laplacian of
the temperature (in the weak formulation) is 0, where coef.val is a material constant. We are using the i integral
defined previously, over the domain specified by the region Omega.
The above syntax is useful for defining custom integrals with user-defined quadrature points and weights, see Integrals.
The above uniform integration can be more easily achieved by:
equations = {
’Temperature’ : """dw_laplace.2.Omega( coef.val, s, t ) = 0"""
}
The integration order is specified directly in place of the integral name. The integral definition is superfluous in this
case.
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
Here, we specify the linear and nonlinear solver kind and options. The convergence parameters can be adjusted if
necessary, otherwise leave the default.
Even linear problems are solved by a nonlinear solver (KISS rule) - only one iteration is needed and the final rezidual
is obtained for free.
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
3.3. Example problem description file
15
SfePy Documentation, Release 2015.1
The solvers to use are specified in the options block. We can define multiple solvers with different convergence
parameters if necessary.
That’s it! Now it is possible to proceed as described in Invoking SfePy from the command line.
3.4 Interactive Example: Linear Elasticity
This example shows how to use SfePy interactively, but also how to make a custom simulation script. We will use
IPython with custom imports, as described in Using IPython, for the explanation, but regular Python shell would do
as well, provided the proper modules are imported.
We wish to solve the following linear elasticity problem:
−
𝜕𝜎𝑖𝑗 (𝑢)
+ 𝑓𝑖 = 0 in Ω,
𝜕𝑥𝑗
𝑢 = 0 on Γ1 ,
𝑢1 = 𝑢
¯1 on Γ2 ,
(3.3)
𝜕𝑢
𝜕𝑢𝑖
where the stress is defined as 𝜎𝑖𝑗 = 2𝜇𝑒𝑖𝑗 +𝜆𝑒𝑘𝑘 𝛿𝑖𝑗 , 𝜆, 𝜇 are the Lamé’s constants, the strain is 𝑒𝑖𝑗 (𝑢) = 12 ( 𝜕𝑥
+ 𝜕𝑥𝑗𝑖 )
𝑗
and 𝑓 are volume forces. This can be written in general form as 𝜎𝑖𝑗 (𝑢) = 𝐷𝑖𝑗𝑘𝑙 𝑒𝑘𝑙 (𝑢), where in our case 𝐷𝑖𝑗𝑘𝑙 =
𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
In the weak form the equation (3.3) is
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑘𝑙 (𝑢)𝑒𝑖𝑗 (𝑣) +
Ω
𝑓 𝑖 𝑣𝑖 = 0 ,
(3.4)
Ω
where 𝑣 is the test function, and both 𝑢, 𝑣 belong to a suitable function space.
Hint: Whenever you create a new object (e.g. a Mesh instance, see below), try to print it using the print statement - it
will give you insight about the object internals.
The whole example summarized in a script is below in Complete Example as a Script.
In the SfePy top-level directory, run:
$ ipython --profile=sfepy
Read a finite element mesh, that defines the domain Ω.
In [1]: mesh = Mesh.from_file(’meshes/2d/rectangle_tri.mesh’)
Create a domain. The domain allows defining regions or subdomains.
In [2]: domain = FEDomain(’domain’, mesh)
Define the regions - the whole domain Ω, where the solution is sought, and Γ1 , Γ2 , where the boundary conditions will
be applied. As the domain is rectangular, we first get a bounding box to get correct bounds for selecting the boundary
edges.
In
In
In
In
[3]:
[4]:
[5]:
[6]:
...:
...:
In [7]:
...:
...:
min_x, max_x = domain.get_mesh_bounding_box()[:, 0]
eps = 1e-8 * (max_x - min_x)
omega = domain.create_region(’Omega’, ’all’)
gamma1 = domain.create_region(’Gamma1’,
’vertices in x < %.10f’ % (min_x + eps),
’facet’)
gamma2 = domain.create_region(’Gamma2’,
’vertices in x > %.10f’ % (max_x - eps),
’facet’)
Next we define the actual finite element approximation using the Field class.
16
Chapter 3. Tutorial
SfePy Documentation, Release 2015.1
In [8]: field = Field.from_args(’fu’, nm.float64, ’vector’, omega,
...:
space=’H1’, poly_space_base=’lagrange’,
...:
approx_order=2)
Using the field fu, we can define both the unknown variable 𝑢 and the test variable 𝑣.
In [9]: u = FieldVariable(’u’, ’unknown’, field)
In [10]: v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
Before we can define the terms to build the equation of linear elasticity, we have to create also the materials, i.e. define
the (constitutive) parameters. The linear elastic material m will be defined using the two Lamé constants 𝜆 = 1, 𝜇 = 1.
The volume forces will be defined also as a material, as a constant (column) vector [0.02, 0.01]𝑇 .
In [11]: m = Material(’m’, lam=1.0, mu=1.0)
In [12]: f = Material(’f’, val=[[0.02], [0.01]])
One more thing needs to be defined - the numerical quadrature that will be used to integrate each term over its domain.
In [14]: integral = Integral(’i’, order=3)
Now we are ready to define the two terms and build the equations.
In [15]: from sfepy.terms import Term
In [16]: t1 = Term.new(’dw_lin_elastic_iso(m.lam, m.mu, v, u)’,
integral, omega, m=m, v=v, u=u)
In [17]: t2 = Term.new(’dw_volume_lvf(f.val, v)’, integral, omega, f=f, v=v)
In [18]: eq = Equation(’balance’, t1 + t2)
In [19]: eqs = Equations([eq])
The equations have to be completed by boundary conditions. Let us clamp the left edge Γ1 , and shift the right edge
Γ2 in the 𝑥 direction a bit, depending on the 𝑦 coordinate.
In [20]: from sfepy.discrete.conditions import Conditions, EssentialBC
In [21]: fix_u = EssentialBC(’fix_u’, gamma1, {’u.all’ : 0.0})
In [22]: def shift_u_fun(ts, coors, bc=None, problem=None, shift=0.0):
....:
val = shift * coors[:,1]**2
....:
return val
In [23]: bc_fun = Function(’shift_u_fun’, shift_u_fun,
....:
extra_args={’shift’ : 0.01})
In [24]: shift_u = EssentialBC(’shift_u’, gamma2, {’u.0’ : bc_fun})
The last thing to define before building the problem are the solvers. Here we just use a sparse direct SciPy solver
and the SfePy Newton solver with default parameters. We also wish to store the convergence statistics of the Newton
solver. As the problem is linear, it should converge in one iteration.
In
In
In
In
In
[25]:
[26]:
[27]:
[28]:
[29]:
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
ls = ScipyDirect({})
nls_status = IndexedStruct()
nls = Newton({}, lin_solver=ls, status=nls_status)
Now we are ready to create a Problem instance. Note that the step above is not really necessary - the above solvers
are constructed by default. We did them to get the nls_status.
In [30]: pb = Problem(’elasticity’, equations=eqs, nls=nls, ls=ls)
The Problem has several handy methods for debugging. Let us try saving the regions into a VTK file.
In [31]: pb.save_regions_as_groups(’regions’)
3.4. Interactive Example: Linear Elasticity
17
SfePy Documentation, Release 2015.1
And view them.
In [32]: view = Viewer(’regions.vtk’)
In [33]: view()
You should see this:
Finally, we apply the boundary conditions, solve the problem, save and view the results.
In
In
In
In
In
In
[34]:
[35]:
[36]:
[37]:
[38]:
[39]:
pb.time_update(ebcs=Conditions([fix_u, shift_u]))
vec = pb.solve()
print nls_status
pb.save_state(’linear_elasticity.vtk’, vec)
view = Viewer(’linear_elasticity.vtk’)
view()
This is the resulting image:
18
Chapter 3. Tutorial
SfePy Documentation, Release 2015.1
The default view is not very fancy. Let us show the displacements by shifting the mesh. Close the previous window
and do:
In [56]: view(vector_mode=’warp_norm’, rel_scaling=2,
....:
is_scalar_bar=True, is_wireframe=True)
And the result is:
See the docstring of view() and play with its options.
3.4.1 Complete Example as a Script
The source code: linear_elasticity.py. It should be run from the SfePy source directory so that it finds the
mesh file.
3.4. Interactive Example: Linear Elasticity
19
SfePy Documentation, Release 2015.1
1
2
3
#!/usr/bin/env python
from optparse import OptionParser
import numpy as nm
4
5
6
import sys
sys.path.append(’.’)
7
8
9
10
11
12
13
14
15
16
from sfepy.base.base import IndexedStruct
from sfepy.discrete import (FieldVariable, Material, Integral, Function,
Equation, Equations, Problem)
from sfepy.discrete.fem import Mesh, FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import Conditions, EssentialBC
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.postprocess.viewer import Viewer
17
18
19
20
21
22
def shift_u_fun(ts, coors, bc=None, problem=None, shift=0.0):
"""
Define a displacement depending on the y coordinate.
"""
val = shift * coors[:,1]**2
23
return val
24
25
26
27
28
29
usage = """%prog [options]"""
help = {
’show’ : ’show the results figure’,
}
30
31
32
def main():
from sfepy import data_dir
33
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-s’, ’--show’,
action="store_true", dest=’show’,
default=False, help=help[’show’])
options, args = parser.parse_args()
34
35
36
37
38
39
mesh = Mesh.from_file(data_dir + ’/meshes/2d/rectangle_tri.mesh’)
domain = FEDomain(’domain’, mesh)
40
41
42
min_x, max_x = domain.get_mesh_bounding_box()[:,0]
eps = 1e-8 * (max_x - min_x)
omega = domain.create_region(’Omega’, ’all’)
gamma1 = domain.create_region(’Gamma1’,
’vertices in x < %.10f’ % (min_x + eps),
’facet’)
gamma2 = domain.create_region(’Gamma2’,
’vertices in x > %.10f’ % (max_x - eps),
’facet’)
43
44
45
46
47
48
49
50
51
52
field = Field.from_args(’fu’, nm.float64, ’vector’, omega, approx_order=2)
53
54
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
55
56
57
m = Material(’m’, lam=1.0, mu=1.0)
58
20
Chapter 3. Tutorial
SfePy Documentation, Release 2015.1
59
f = Material(’f’, val=[[0.02], [0.01]])
60
61
integral = Integral(’i’, order=3)
62
63
64
65
66
67
t1 = Term.new(’dw_lin_elastic_iso(m.lam, m.mu, v, u)’,
integral, omega, m=m, v=v, u=u)
t2 = Term.new(’dw_volume_lvf(f.val, v)’, integral, omega, f=f, v=v)
eq = Equation(’balance’, t1 + t2)
eqs = Equations([eq])
68
69
fix_u = EssentialBC(’fix_u’, gamma1, {’u.all’ : 0.0})
70
71
72
bc_fun = Function(’shift_u_fun’, shift_u_fun, extra_args={’shift’ : 0.01})
shift_u = EssentialBC(’shift_u’, gamma2, {’u.0’ : bc_fun})
73
74
ls = ScipyDirect({})
75
76
77
nls_status = IndexedStruct()
nls = Newton({}, lin_solver=ls, status=nls_status)
78
79
80
pb = Problem(’elasticity’, equations=eqs, nls=nls, ls=ls)
pb.save_regions_as_groups(’regions’)
81
82
pb.time_update(ebcs=Conditions([fix_u, shift_u]))
83
84
85
vec = pb.solve()
print nls_status
86
87
pb.save_state(’linear_elasticity.vtk’, vec)
88
89
90
91
92
if options.show:
view = Viewer(’linear_elasticity.vtk’)
view(vector_mode=’warp_norm’, rel_scaling=2,
is_scalar_bar=True, is_wireframe=True)
93
94
95
if __name__ == ’__main__’:
main()
3.4. Interactive Example: Linear Elasticity
21
SfePy Documentation, Release 2015.1
22
Chapter 3. Tutorial
CHAPTER
FOUR
USER’S GUIDE
23
SfePy Documentation, Release 2015.1
Table of Contents
• Running a Simulation
– Basic Usage
– Applications
– Stand-Alone Examples
– Running Tests
* Common Tasks
– Computations and Examples
* Common Tasks
• Visualization of Results
• Problem Description File
– Long Syntax
– FE Mesh
– Regions
* Region Definition Syntax
– Fields
– Variables
– Integrals
– Essential Boundary Conditions and Constraints
* Dirichlet Boundary Conditions
* Periodic Boundary Conditions
* Linear Combination Boundary Conditions
– Initial Conditions
– Materials
– Equations and Terms
* Examples
– Configuring Solvers
– Functions
* Defining Material Parameters
* Examples
– Miscellaneous
• Building Equations in SfePy
– Syntax of Terms in Equations
• Term Evaluation
• Solution Postprocessing
• Probing
• Postprocessing filters
• Available Solvers
– Nonlinear Solvers
– Linear Solvers
• Isogeometric Analysis
– Current Implementation
* Domain Description
* Region Selection
– Examples
This manual provides reference documentation to SfePy from a user’s perspective.
24
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
4.1 Running a Simulation
The following should be run in the top-level directory of the SfePy source tree after compiling the C extension files.
See Installation for full installation instructions info. The $ indicates the command prompt of your terminal.
4.1.1 Basic Usage
• $ ./simple.py examples/diffusion/poisson_short_syntax.py
– Creates cylinder.vtk
• $ ./simple.py examples/navier_stokes/stokes.py
– Creates channels_symm944t.vtk
• $ ./run_tests.py
– See Running Tests
4.1.2 Applications
• Phononic Materials
– $ ./phonon.py -p examples/phononic/band_gaps.py
* see examples/phononic/output/
• schroedinger.py
– (order is important below):
1. $ ./schroedinger.py --2d --create-mesh
2. $ ./schroedinger.py --2d --hydrogen
3. $ ./postproc.py mesh.vtk
4.1.3 Stand-Alone Examples
• $ python examples/rs_correctors.py
• $ python examples/compare_elastic_materials.py
• $ python examples/live_plot.py
4.1.4 Running Tests
The tests are run by the run_tests.py script:
4.1. Running a Simulation
25
SfePy Documentation, Release 2015.1
$ ./run_tests.py -h
Usage: run_tests.py [options] [test_filename[ test_filename ...]]
Options:
--version
-h, --help
--print-doc
-d directory,
-o directory,
--debug
--filter-none
--filter-less
--filter-more
show program’s version number and exit
show this help message and exit
print the docstring of this file (howto write new
tests)
--dir=directory
directory with tests [default: tests]
--output=directory
directory for storing test results and temporary files
[default: output-tests]
raise silenced exceptions to see what was wrong
do not filter any messages
filter output (suppress all except test messages)
filter output (suppress all except test result
messages)
Common Tasks
• Run all tests, filter output; result files related to the tests can be found in output-tests directory:
./run_tests.py
./run_tests.py --filter-more
./run_tests.py --filter-less
• Run a particular test file, filter output:
# Test if linear elasticity input file works.
./run_tests.py tests/test_input_le.py
• Debug a failing test:
./run_tests.py tests/test_input_le.py --debug
4.1.5 Computations and Examples
The example problems in the examples directory can be computed by the script simple.py which is in the toplevel directory of the SfePy distribution. If it is run without arguments, a help message is printed:
$ ./simple.py
Usage: simple.py [options] filename_in
Options:
--version
show program’s version number and exit
-h, --help
show this help message and exit
-c "key : value, ...", --conf="key : value, ..."
override problem description file items, written as
python dictionary without surrouding braces
-O "key : value, ...", --options="key : value, ..."
override options item of problem description, written
as python dictionary without surrouding braces
-o filename
basename of output file(s) [default: <basename of
input file>]
--format=format
output file format, one of: {vtk, h5, mesh} [default:
26
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
vtk]
log all messages to specified file (existing file will
be overwritten!)
-q, --quiet
do not print any messages to screen
--save-ebc
save problem state showing EBC (Dirichlet conditions)
--save-regions
save problem regions as meshes
--save-regions-as-groups
save problem regions in a single mesh but mark them by
using different element/node group numbers
--save-field-meshes
save meshes of problem fields (with extra DOF nodes)
--solve-not
do not solve (use in connection with --save-*)
--list=what
list data, what can be one of: {terms}
--log=file
Additional (stand-alone) examples are in the examples/ directory, e.g.:
$ python examples/compare_elastic_materials.py
Parametric study example:
$ ./simple.py examples/diffusion/poisson_parametric_study.py
Common Tasks
• Run a simulation:
./simple.py examples/diffusion/poisson_short_syntax.py
./simple.py examples/diffusion/poisson_short_syntax.py -o some_results # -> produces some_result
• Print available terms:
./simple.py --list=terms
• Run a simulation and also save Dirichlet boundary conditions:
./simple.py --save-ebc examples/diffusion/poisson_short_syntax.py # -> produces an additional .v
4.2 Visualization of Results
The postproc.py script can be used for quick postprocessing and visualization of the SfePy results. It requires
mayavi2 installed on your system. Running postproc.py without arguments produces:
$ ./postproc.py
Usage: postproc.py [options] filename
This is a script for quick Mayavi-based visualizations of finite element
computations results.
Examples
-------The examples assume that run_tests.py has been run successfully and the
resulting data files are present.
- view data in output-tests/test_navier_stokes.vtk
$ python postproc.py output-tests/test_navier_stokes.vtk
$ python postproc.py output-tests/test_navier_stokes.vtk --3d
4.2. Visualization of Results
27
SfePy Documentation, Release 2015.1
- create animation (forces offscreen rendering) from
output-tests/test_time_poisson.*.vtk
$ python postproc.py output-tests/test_time_poisson.*.vtk -a mov
- create animation (forces offscreen rendering) from
output-tests/test_hyperelastic.*.vtk
The range specification for the displacements ’u’ is required, as
output-tests/test_hyperelastic.00.vtk contains only zero
displacements which leads to invisible glyph size.
$ python postproc.py output-tests/test_hyperelastic.*.vtk
--ranges=u,0,0
- same as above, but slower frame rate
$ python postproc.py output-tests/test_hyperelastic.*.vtk
--ranges=u,0,0
Options:
--version
show program’s version number and exit
-h, --help
show this help message and exit
-l, --list-ranges
do not plot, only list names and ranges of all data
-n, --no-show
do not call mlab.show()
--no-offscreen
force no offscreen rendering for --no-show
--3d
3d plot mode
--view=angle,angle[,distance[,focal_point]]
camera azimuth, elevation angles, and optionally also
distance and focal point coordinates (without []) as
in ‘mlab.view()‘ [default: if --3d is True: "45,45",
else: "0,0"]
--roll=angle
camera roll angle [default: 0.0]
--fgcolor=R,G,B
foreground color, that is the color of all text
annotation labels (axes, orientation axes, scalar bar
labels) [default: 0.0,0.0,0.0]
--bgcolor=R,G,B
background color [default: 1.0,1.0,1.0]
--layout=layout
layout for multi-field plots, one of: rowcol, colrow,
row, col [default: rowcol]
--scalar-mode=mode
mode for plotting scalars with --3d, one of:
cut_plane, iso_surface, both [default: iso_surface]
--vector-mode=mode
mode for plotting vectors, one of: arrows, norm,
arrows_norm, warp_norm [default: arrows_norm]
-s scale, --scale-glyphs=scale
relative scaling of glyphs (vector field
visualization) [default: 0.05]
--clamping
glyph clamping mode
--ranges=name1,min1,max1:name2,min2,max2:...
force data ranges [default: automatic from data]
-b, --scalar-bar
show scalar bar for each data
--wireframe
show wireframe of mesh surface for each data
--opacity=opacity
global surface and wireframe opacity in [0.0, 1.0]
[default: 1.0]
--rel-text-width=width
relative text annotation width [default: 0.02]
-w, --watch
watch the results file for changes (single file mode
only)
-o filename, --output=filename
28
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
view image file name [default: ’view.png’]
--output-dir=directory
output directory for saving view images; ignored when
-o option is given, as the directory part of the
filename is taken instead [default: ’.’]
-a <ffmpeg-supported format>, --animation=<ffmpeg-supported format>
if set to a ffmpeg-supported format (e.g. mov, avi,
mpg), ffmpeg is installed and results of multiple time
steps are given, an animation is created in the same
directory as the view images
--ffmpeg-options="<ffmpeg options>"
ffmpeg animation encoding options (enclose in "")
[default: -r 10 -sameq]
-r resolution, --resolution=resolution
image resolution in NxN format [default: shorter axis:
600; depends on layout: for rowcol it is 800x600]
--all
draw all data (normally, node_groups and mat_id are
omitted)
--only-names=list of names
draw only named data
--group-names=name1,...,nameN:...
superimpose plots of data in each group
--subdomains=mat_id_name,threshold_limits,single_color
superimpose surfaces of subdomains over each data;
example value: mat_id,0,None,True
--step=step
set the time step [default: 0]
--anti-aliasing=value
value of anti-aliasing [default: mayavi2 default]
-d ’var_name0,function_name0,par0=val0,par1=val1,...:var_name1,...’, --domain-specific=’var_name0,f
domain specific drawing functions and configurations
As a simple example, try:
$ ./simple.py examples/diffusion/poisson_short_syntax.py
$ ./postproc.py cylinder.vtk
The following window should display:
4.2. Visualization of Results
29
SfePy Documentation, Release 2015.1
The -l switch lists information contained in a results file, e.g.:
$ ./postproc.py -l cylinder.vtk
sfepy: 0: cylinder.vtk
point scalars
"node_groups" (354,) range: 0 0 l2_norm_range: 0.0 0.0
"t" (354,) range: -2.0 2.0 l2_norm_range: 0.0106091 2.0
cell scalars
"mat_id" (1348,) range: 6 6 l2_norm_range: 6.0 6.0
4.3 Problem Description File
Here we discuss the basic items that users have to specify in their input files. For complete examples, see the problem
description files in the examples/ directory of SfePy.
30
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
4.3.1 Long Syntax
Besides the short syntax described below there is (due to history) also a long syntax which is explained in
problem_desc_file_long. The short and long syntax can be mixed together in one description file.
4.3.2 FE Mesh
A FE mesh defining a domain geometry can be stored in several formats:
• legacy VTK (.vtk)
• custom HDF5 file (.h5)
• medit mesh file (.mesh)
• tetgen mesh files (.node, .ele)
• comsol text mesh file (.txt)
• abaqus text mesh file (.inp)
• avs-ucd text mesh file (.inp)
• hypermesh text mesh file (.hmascii)
• hermes3d mesh file (.mesh3d)
• nastran text mesh file (.bdf)
• gambit neutral text mesh file (.neu)
• salome/pythonocc med binary mesh file (.med)
Example:
filename_mesh = ’meshes/3d/cylinder.vtk’
The VTK and HDF5 formats can be used for storing the results. The format can be selected in options, see Miscellaneous.
The following geometry elements are supported:
4.3. Problem Description File
31
SfePy Documentation, Release 2015.1
4.3.3 Regions
Regions serve to select a certain part of the computational domain using topological entities of the FE mesh. They are
used to define the boundary conditions, the domains of terms and materials etc.
Let us denote D the maximal dimension of topological entities. For volume meshes it is also the dimension of space
the domain is embedded in. Then the following topological entities can be defined on the mesh (notation follows
[Logg2012]):
topological entity
vertex
edge
face
facet
cell
dimension
0
1
2
D-1
D
co-dimension
D
D-1
D-2
1
0
If D = 2, faces are not defined and facets are edges. If D = 3, facets are faces.
Following the above definitions, a region can be of different kind:
• cell, facet, face, edge, vertex - entities of higher dimension are not included.
• cell_only, facet_only, face_only, edge_only, vertex_only - only the specified entities are
included, other entities are empty sets, so that set-like operators still work, see below.
• The cell kind is the most general and should be used with volume terms. It is also the default if the kind is not
specified in region definition.
• The facet kind (same as edge in 2D and face in 3D) is to be used with boundary (surface integral) terms.
32
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
• The vertex (same as vertex_only) kind can be used with point-wise defined terms (e.g. point loads).
The kinds allow a clear distinction between regions of different purpose (volume integration domains, surface domains,
etc.) and could be uses to lower memory usage.
A region definition involves topological entity selections combined with set-like operators. The set-like operators can
result in intermediate regions that have the cell kind. The desired kind is set to the final region, removing unneeded
entities. Most entity selectors are defined in terms of vertices and cells - the other entities are computed as needed.
topological entity selection
all
vertices of surface
vertices of group <integer>
vertices of set <str>
vertices in <expr>
vertices by <function>
vertex <id>[, <id>, ...]
vertex in r.<name of another region>
cells of group <integer>
cells by <efunction>
cell <id>[, <id>, ...],
cell (<ig>, <id>)[, (<ig>, <id>), ...]
copy r.<name of another region>
r.<name of another region>
explanation
all entities of the mesh
surface of the mesh
vertices of given group
vertices of a given named vertex set 5
vertices given by an expression 6
vertices given by a function of coordinates 7
vertices given by their ids
any single vertex in the given region
cells of given group
cells given by a function of coordinates 8
cells given by their ids (assumes cell group 0)
cells given by their (group, id) pairs
a copy of the given region
a reference to the given region
topological entity selection footnotes
set-like operator
+v
+e
+f
+s
+c
-v
-e
-f
-s
-c
*v
*e
*f
*s
*c
explanation
vertex union
edge union
face union
facet union
cell union
vertex difference
edge difference
face difference
facet difference
cell difference
vertex intersection
edge intersection
face intersection
facet intersection
cell intersection
1 Only
if mesh format supports reading boundary condition vertices as vertex sets.
is a logical expression like (y <= 0.1) & (x < 0.2). In 2D use x, y, in 3D use x, y and z. & stands for logical and, | stands
for logical or.
3 <function> is a function with signature fun(coors, domain=None), where coors are coordinates of mesh vertices.
4 <efunction> is a function with signature fun(coors, domain=None), where coors are coordinates of mesh cell centroids.
5 Only if mesh format supports reading boundary condition vertices as vertex sets.
6 <expr> is a logical expression like (y <= 0.1) & (x < 0.2). In 2D use x, y, in 3D use x, y and z. & stands for logical and, | stands
for logical or.
7 <function> is a function with signature fun(coors, domain=None), where coors are coordinates of mesh vertices.
8 <efunction> is a function with signature fun(coors, domain=None), where coors are coordinates of mesh cell centroids.
2 <expr>
4.3. Problem Description File
33
SfePy Documentation, Release 2015.1
Region Definition Syntax
Regions are defined by the following Python dictionary:
regions = {
<name> : (<selection>, [<kind>], [<parent>]),
}
or:
regions = {
<name> : <selection>,
}
Example definitions:
regions = {
’Omega’ : ’all’,
’Right’ : (’vertices in (x > 0.99)’, ’facet’),
’Gamma1’ : ("""(cells of group 1 *v cells of group 2)
+v r.Right""", ’facet’, ’Omega’),
}
4.3.4 Fields
Fields correspond to FE spaces:
fields = {
<name> : (<data_type>, <shape>, <region_name>, <approx_order>)
}
where
• <data_type> is a numpy type (float64 or complex128) or ‘real’ or ‘complex’
• <shape> is the number of DOFs per node: 1 or (1,) or ‘scalar’, space dimension (2, or (2,) or 3 or (3,)) or
‘vector’; it can be other
positive integer than just 1, 2, or 3
• <region_name> is the name of region where the field is defined
• <approx_order> is the FE approximation order, e.g. 0, 1, 2, ‘1B’ (1 with bubble)
Example: scalar P1 elements in 2D on a region Omega:
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
The following approximation orders can be used:
• simplex elements: 1, 2, ‘1B’, ‘2B’
• tensor product elements: 0, 1, ‘1B’
Optional bubble function enrichment is marked by ‘B’.
34
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
4.3.5 Variables
Variables use the FE approximation given by the specified field:
variables = {
<name> : (<kind>, <field_name>, <spec>, [<history>])
}
where
• <kind> - ‘unknown field’, ‘test field’ or ‘parameter field’
• <spec> - in case of: primary variable - order in the global vector of unknowns, dual variable - name of
primary variable
• <history> - number of time steps to remember prior to current step
Example:
variables = {
’t’ : (’unknown field’, ’temperature’, 0, 1),
’s’ : (’test field’, ’temperature’, ’t’),
}
4.3.6 Integrals
Define the integral type and quadrature rule. This keyword is optional, as the integration orders can be specified
directly in equations (see below):
integrals = {
<name> : <order>
}
where
• <name> - the integral name - it has to begin with ‘i’!
• <order> - the order of polynomials to integrate, or ‘custom’ for integrals with explicitly given values and
weights
Example:
import numpy as nm
N = 2
integrals = {
’i1’ : 2,
’i2’ : (’custom’, zip(nm.linspace( 1e-10, 0.5, N ),
nm.linspace( 1e-10, 0.5, N )),
[1./N] * N),
}
4.3.7 Essential Boundary Conditions and Constraints
The essential boundary conditions set values of DOFs in some regions, while the constraints constrain or transform
values of DOFs in some regions.
4.3. Problem Description File
35
SfePy Documentation, Release 2015.1
Dirichlet Boundary Conditions
The Dirichlet, or essential, boundary conditions apply in a given region given by its name, and, optionally, in selected
times. The times can be given either using a list of tuples (t0, t1) making the condition active for t0 <= t < t1, or by a
name of a function taking the time argument and returning True or False depending on whether the condition is active
at the given time or not.
Dirichlet (essential) boundary conditions:
ebcs = {
<name> : (<region_name>, [<times_specification>,]
{<dof_specification> : <value>[,
<dof_specification> : <value>, ...]})
}
Example:
ebcs = {
’u1’ : (’Left’, {’u.all’ : 0.0}),
’u2’ : (’Right’, [(0.0, 1.0)], {’u.0’ : 0.1}),
’phi’ : (’Surface’, {’phi.all’ : 0.0}),
}
Periodic Boundary Conditions
The periodic boundary conditions tie DOFs of a single variable in two regions that have matching nodes. Can be used
with functions in sfepy.discrete.fem.periodic.
Periodic boundary conditions:
epbcs = {
<name> : ((<region1_name>, <region2_name>), [<times_specification>,]
{<dof_specification> : <dof_specification>[,
<dof_specification> : <dof_specification>, ...]},
<match_function_name>)
}
Example:
epbcs = {
’up1’ : ((’Left’, ’Right’), {’u.all’ : ’u.all’, ’p.0’ : ’p.0’},
’match_y_line’),
}
Linear Combination Boundary Conditions
The linear combination boundary conditions (LCBCs) are more general than the Dirichlet BCs or periodic BCs. They
can be used to substitute one set of DOFs in a region by another set of DOFs, possibly in another region and of another
variable. The LCBCs can be used only in FEM with nodal (Lagrange) basis.
Available LCBC kinds:
• ’rigid’ - in linear elasticity problems, a region moves as a rigid body;
• ’no_penetration’ - in flow problems, the velocity vector is constrained to the plane tangent to the surface;
• ’normal_direction’ - the velocity vector is constrained to the normal direction;
• ’edge_direction’ - the velocity vector is constrained to the mesh edge direction;
36
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
• ’integral_mean_value’ - all DOFs in a region are summed to a single new DOF;
• ’shifted_periodic’ - generalized periodic BCs that work with two different variables and can have a
non-zero mutual shift.
Only the ’shifted_periodic’ LCBC needs the second region and the DOF mapping function, see below.
Linear combination boundary conditions:
lcbcs = {
’shifted’ : ((’Left’, ’Right’),
{’u1.all’ : ’u2.all’},
’match_y_line’, ’shifted_periodic’,
’get_shift’),
’mean’ : (’Middle’, {’u1.all’ : None}, None, ’integral_mean_value’),
}
4.3.8 Initial Conditions
Initial conditions are applied prior to the boundary conditions - no special care must be used for the boundary dofs:
ics = {
<name> : (<region_name>, {<dof_specification> : <value>[,
<dof_specification> : <value>, ...]},...)
}
Example:
ics = {
’ic’ : (’Omega’, {’T.0’ : 5.0}),
}
4.3.9 Materials
Materials are used to define constitutive parameters (e.g. stiffness, permeability, or viscosity), and other non-field
arguments of terms (e.g. known traction or volume forces). Depending on a particular term, the parameters can be
constants, functions defined over FE mesh nodes, functions defined in the elements, etc.
Example:
material = {
’m’ : ({’val’ : [0.0, -1.0, 0.0]},),
’m2’ : ’get_pars’,
’m3’ : (None, ’get_pars’), # Same as the above line.
}
Example: different material parameters in regions ‘Yc’, ‘Ym’:
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
dim = 3
materials = {
’mat’ : ({’D’ : {
’Ym’: stiffness_from_youngpoisson(dim, 7.0e9, 0.4),
’Yc’: stiffness_from_youngpoisson(dim, 70.0e9, 0.2)}
},),
}
4.3. Problem Description File
37
SfePy Documentation, Release 2015.1
4.3.10 Equations and Terms
Equations can be built by combining terms listed in Term Table.
Examples
• Laplace equation, named integral:
equations = {
’Temperature’ : """dw_laplace.i.Omega( coef.val, s, t ) = 0"""
}
• Laplace equation, simplified integral given by order:
equations = {
’Temperature’ : """dw_laplace.2.Omega( coef.val, s, t ) = 0"""
}
• Laplace equation, automatic integration order (not implemented yet!):
equations = {
’Temperature’ : """dw_laplace.a.Omega( coef.val, s, t ) = 0"""
}
• Navier-Stokes equations:
equations = {
’balance’ :
"""+ dw_div_grad.i2.Omega( fluid.viscosity, v, u )
+ dw_convect.i2.Omega( v, u )
- dw_stokes.i1.Omega( v, p ) = 0""",
’incompressibility’ :
"""dw_stokes.i1.Omega( u, q ) = 0""",
}
4.3.11 Configuring Solvers
In SfePy, a non-linear solver has to be specified even when solving a linear problem. The linear problem is/should be
then solved in one iteration of the nonlinear solver.
Linear and nonlinear solver:
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1}),
}
Solver selection:
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
38
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
4.3.12 Functions
Functions are a way of customizing SfePy behavior. They make it possible to define material properties, boundary
conditions, parametric sweeps, and other items in an arbitrary manner. Functions are normal Python functions declared
in the Problem Definition file, so they can invoke the full power of Python. In order for SfePy to make use of the
functions, they must be declared using the function keyword. See the examples below.
Defining Material Parameters
The functions for defining material parameters can work in two modes, distinguished by the mode argument. The two
modes are ‘qp’ and ‘special’. The first mode is used for usual functions that define parameters in quadrature points
(hence ‘qp’), while the second one can be used for special values like various flags.
The shape and type of data returned in the ‘special’ mode can be arbitrary (depending on the term used). On the other
hand, in the ‘qp’ mode all the data have to be numpy float64 arrays with shape (n_coor, n_row, n_col), where n_coor
is the number of quadrature points given by the coors argument, n_coor = coors.shape[0], and (n_row, n_col) is the
shape of a material parameter in each quadrature point. For example, for scalar parameters, the shape is (n_coor, 1, 1).
Examples
See examples/diffusion/poisson_functions.py for a complete problem description file demonstrating
how to use different kinds of functions.
• functions for defining regions:
def get_circle(coors, domain=None):
r = nm.sqrt(coors[:,0]**2.0 + coors[:,1]**2.0)
return nm.where(r < 0.2)[0]
functions = {
’get_circle’ : (get_circle,),
}
• functions for defining boundary conditions:
def get_p_edge(ts, coors, bc=None, problem=None):
if bc.name == ’p_left’:
return nm.sin(nm.pi * coors[:,1])
else:
return nm.cos(nm.pi * coors[:,1])
functions = {
’get_p_edge’ : (get_p_edge,),
}
ebcs = {
’p’ : (’Gamma’, {’p.0’ : ’get_p_edge’}),
}
The values can be given by a function of time, coordinates and possibly other data, for example:
ebcs = {
’f1’ : (’Gamma1’, {’u.0’ : ’get_ebc_x’}),
’f2’ : (’Gamma2’, {’u.all’ : ’get_ebc_all’}),
}
def get_ebc_x(coors, amplitude):
4.3. Problem Description File
39
SfePy Documentation, Release 2015.1
z = coors[:, 2]
val = amplitude * nm.sin(z * 2.0 * nm.pi)
return val
def get_ebc_all(ts, coors):
x, y, z = coors[:, 0], coors[:, 1], coors[:, 2]
val = ts.step * nm.r_[x, y, z]
return val
functions = {
’get_ebc_x’ : (lambda ts, coors, bc, problem, **kwargs:
get_ebc_x(coors, 5.0),),
’get_ebc_all’ : (lambda ts, coors, bc, problem, **kwargs:
get_ebc_all(ts, coors),),
}
Note that when setting more than one component as in get_ebc_all() above, the function should return a single
one-dimensional vector with all values of the first component, then of the second one etc. concatenated together.
• function for defining usual material parameters:
def get_pars(ts, coors, mode=None, **kwargs):
if mode == ’qp’:
val = coors[:,0]
val.shape = (coors.shape[0], 1, 1)
return {’x_coor’ : val}
functions = {
’get_pars’ : (get_pars,),
}
The keyword arguments contain both additional use-specified arguments, if any, and the following:
equations, term, problem, for cases when the function needs access to the equations, problem, or
term instances that requested the parameters that are being evaluated. The full signature of the function is:
def get_pars(ts, coors, mode=None,
equations=None, term=None, problem=None, **kwargs)
• function for defining special material parameters, with an extra argument:
def get_pars_special(ts, coors, mode=None, extra_arg=None):
if mode == ’special’:
if extra_arg == ’hello!’:
ic = 0
else:
ic = 1
return {(’x_%s’ % ic) : coors[:,ic]}
functions = {
’get_pars1’ : (lambda ts, coors, mode=None, **kwargs:
get_pars_special(ts, coors, mode,
extra_arg=’hello!’),),
}
# Just another way of adding a function, besides ’functions’ keyword.
function_1 = {
’name’ : ’get_pars2’,
’function’ : lambda ts, coors, mode=None, **kwargs:
40
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
get_pars_special(ts, coors, mode, extra_arg=’hi!’),
}
• function combining both kinds of material parameters:
def get_pars_both(ts, coors, mode=None, **kwargs):
out = {}
if mode == ’special’:
out[’flag’] = coors.max() > 1.0
elif mode == ’qp’:
val = coors[:,1]
val.shape = (coors.shape[0], 1, 1)
out[’y_coor’] = val
return out
functions = {
’get_pars_both’ : (get_pars_both,),
}
• function for setting values of a parameter variable:
variable_1 = {
’name’ : ’p’,
’kind’ : ’parameter field’,
’field’ : ’temperature’,
’like’ : None,
’special’ : {’setter’ : ’get_load_variable’},
}
def get_load_variable(ts, coors, region=None):
y = coors[:,1]
val = 5e5 * y
return val
functions = {
’get_load_variable’ : (get_load_variable,)
}
4.3.13 Miscellaneous
The options can be used to select solvers, output file format, output directory, to register functions to be called at
various phases of the solution (the hooks), and for other settings.
Additional options (including solver selection):
options = {
# string, output directory
’output_dir’
: ’output/<output_dir>’,
# ’vtk’ or ’h5’, output file (results) format
’output_format’
: ’h5’,
4.3. Problem Description File
41
SfePy Documentation, Release 2015.1
# string, nonlinear solver name
’nls’ : ’newton’,
# string, linear solver name
’ls’ : ’ls’,
# string, time stepping solver name
’ts’ : ’ts’,
# int, number of time steps when results should be saved (spaced
# regularly from 0 to n_step), or -1 for all time steps
’save_steps’ : -1,
# string, a function to be called after each time step
’step_hook’ : ’<step_hook_function>’,
# string, a function to be called after each time step, used to
# update the results to be saved
’post_process_hook’ : ’<post_process_hook_function>’,
# string, as above, at the end of simulation
’post_process_hook_final’ : ’<post_process_hook_final_function>’,
# string, a function to generate probe instances
’gen_probes’
: ’<gen_probes_function>’,
# string, a function to probe data
’probe_hook’
: ’<probe_hook_function>’,
# string, a function to modify problem definition parameters
’parametric_hook’ : ’<parametric_hook_function>’,
}
• post_process_hook enables computing derived quantities, like stress or strain, from the primary unknown
variables. See the examples in examples/large_deformation/ directory.
• parametric_hook makes it possible to run parametric studies by modifying the problem description programmatically. See examples/diffusion/poisson_parametric_study.py for an example.
• output_dir redirects output files to specified directory
4.4 Building Equations in SfePy
Equations in SfePy are built using terms, which correspond directly to the integral forms of weak formulation of a
problem to be solved. As an example, let us consider the Laplace equation in time interval 𝑡 ∈ [0, 𝑡final ]:
𝜕𝑇
+ 𝑐∆𝑇 = 0 in Ω,
𝜕𝑡
𝑇 (𝑡) = 𝑇¯(𝑡) on Γ .
The weak formulation of (4.1) is: Find 𝑇 ∈ 𝑉 , such that
∫︁
∫︁
𝜕𝑇
𝑠
+
𝑐 ∇𝑇 : ∇𝑠 = 0,
Ω 𝜕𝑡
Ω
(4.1)
∀𝑠 ∈ 𝑉0 ,
(4.2)
where we assume no fluxes over 𝜕Ω ∖ Γ. In the syntax used in SfePy input files, this can be written as:
42
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
dw_volume_dot.i.Omega( s, dT/dt ) + dw_laplace.i.Omega( coef, s, T) = 0
which directly corresponds to the discrete version of (4.2): Find 𝑇 ∈ 𝑉ℎ , such that
∫︁
∫︁
𝜕𝑇
𝑠𝑇 (
𝜑𝑇 𝜑)
+ 𝑠𝑇 (
𝑐 𝐺𝑇 𝐺)𝑇 = 0, ∀𝑠 ∈ 𝑉ℎ0 ,
𝜕𝑡
Ωℎ
Ωℎ
where 𝑢 ≈ 𝜑𝑢, ∇𝑢 ≈ 𝐺𝑢 for 𝑢 ∈ {𝑠, 𝑇 }. The integrals over the discrete domain Ωℎ are approximated by a numerical
quadrature, that is named i in our case.
4.4.1 Syntax of Terms in Equations
The terms in equations are written in form:
<term_name>.<i>.<r>( <arg1>, <arg2>, ... )
where <i> denotes an integral name (i.e. a name of numerical quadrature to use) and <r> marks a region (domain
of the integral). In the following, <virtual> corresponds to a test function, <state> to a unknown function and
<parameter> to a known function arguments.
When solving, the individual terms in equations are evaluated in the ‘weak’ mode. The evaluation modes are described
in the next section.
4.5 Term Evaluation
Terms can be evaluated in two ways:
1. implicitly by using them in equations;
2. explicitly using Problem.evaluate(). This way is mostly used in the postprocessing.
Each term supports one or more evaluation modes:
• ‘weak’ : Assemble (in the finite element sense) either the vector or matrix depending on diff_var argument (the
name of variable to differentiate with respect to) of Term.evaluate(). This mode is usually used implicitly
when building the linear system corresponding to given equations.
• ‘eval’ : The evaluation mode integrates the term (= integral) over a region. The result has the same dimension
as the quantity being integrated. This mode can be used, for example, to compute some global quantities during
postprocessing such as fluxes or total values of extensive quantities (mass, volume, energy, ...).
• ‘el_avg’ : The element average mode results in an array of a quantity averaged in each element of a region. This
is the mode for postprocessing.
• ‘el’ : The element integral value mode results in an array of a quantity integrated over each element of a region.
This mode is supported only by some special terms.
• ‘qp’ : The quadrature points mode results in an array of a quantity interpolated into quadrature points of each
element in a region. This mode is used when further point-wise calculations with the result are needed. The
same element type and number of quadrature points in each element are assumed.
Not all terms support all the modes - consult the documentation of the individual terms. There are, however, certain
naming conventions:
• ‘dw_*’ terms support ‘weak’ mode
• ‘dq_*’ terms support ‘qp’ mode
• ‘d_*’, ‘di_*’ terms support ‘eval’ mode
4.5. Term Evaluation
43
SfePy Documentation, Release 2015.1
• ‘ev_*’ terms support ‘eval’, ‘el_avg’ and ‘qp’ modes
Note that the naming prefixes are due to history when the mode argument to Problem.evaluate() and
Term.evaluate() was not available. Now they are often redundant, but are kept around to indicate the evaluation purpose of each term.
Several examples of using the Problem.evaluate() function are shown below.
4.6 Solution Postprocessing
A solution to equations given in a problem description file is given by the variables of the ‘unknown field’ kind, that
are set in the solution procedure. By default, those are the only values that are stored into a results file. The solution
postprocessing allows computing additional, derived, quantities, based on the primary variables values, as well as any
other quantities to be stored in the results.
Let us illustrate this using several typical examples. Let us assume that the postprocessing function is
called ‘post_process()’, and is added to options as discussed in Miscellaneous, see ‘post_process_hook’ and
‘post_process_hook_final’. Then:
• compute stress and strain given the displacements (variable u):
def post_process(out, problem, state, extend=False):
"""
This will be called after the problem is solved.
Parameters
---------out : dict
The output dictionary, where this function will store
data.
problem : Problem instance
The current Problem instance.
state : State instance
The computed state, containing FE coefficients of all
variables.
extend : bool
The flag indicating whether to extend the output data
domain. It can be ignored if the problem is solved on
domain already.
additional
the unknown
to the whole
the whole
Returns
------out : dict
The updated output dictionary.
"""
from sfepy.base.base import Struct
# Cauchy strain averaged in elements.
strain = problem.evaluate(’ev_cauchy_strain.i.Omega(u)’,
mode=’el_avg’)
out[’cauchy_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain,
dofs=None)
# Cauchy stress averaged in elements.
stress = problem.evaluate(’ev_cauchy_stress.i.Omega(solid.D, u)’,
mode=’el_avg’)
out[’cauchy_stress’] = Struct(name=’output_data’,
44
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
mode=’cell’, data=stress,
dofs=None)
return out
The full example is linear_elasticity-linear_elastic_probes.
• compute diffusion velocity given the pressure:
def post_process(out, pb, state, extend=False):
from sfepy.base.base import Struct
dvel = pb.evaluate(’ev_diffusion_velocity.i.Omega(m.K, p)’,
mode=’el_avg’)
out[’dvel’] = Struct(name=’output_data’,
mode=’cell’, data=dvel, dofs=None)
return out
The full example is biot/biot_npbc.py.
• store values of a non-homogeneous material parameter:
def post_process(out, pb, state, extend=False):
from sfepy.base.base import Struct
mu = pb.evaluate(’ev_integrate_mat.2.Omega(nonlinear.mu, u)’,
mode=’el_avg’, copy_materials=False, verbose=False)
out[’mu’] = Struct(name=’mu’, mode=’cell’, data=mu, dofs=None)
return out
The full example is linear_elasticity/material_nonlinearity.py.
• compute volume of a region (u is any variable defined in the region Omega):
volume = problem.evaluate(’d_volume.2.Omega(u)’)
4.7 Probing
Probing applies interpolation to output the solution along specified paths. There are two ways of probing:
• VTK probes: It is the simple way of probing using the ‘post_process_hook’. It generates matplotlib figures
with the probing results and previews of the mesh with the probe paths. See Primer or linear_elasticity-its2D_5
example.
• SfePy probes: As mentioned in Miscellaneous, it relies on defining two additional functions, namely the
‘gen_probes’ function, that should create the required probes (see sfepy.discrete.probes), and the
‘probe_hook’ function that performs the actual probing of the results for each of the probes. This function can return the probing results, as well as a handle to a corresponding matplotlib figure. See linear_elasticity/its2D_4.py for additional explanation.
Using sfepy.discrete.probes allows correct probing of fields with the approximation order greater than
one, see Interactive Example in Primer or linear_elasticity/its2D_interactive.py for an example of interactive
use.
4.7. Probing
45
SfePy Documentation, Release 2015.1
4.8 Postprocessing filters
The following postprocessing functions based on the VTK filters are available:
• ‘get_vtk_surface’: extract mesh surface
• ‘get_vtk_edges’: extract mesh edges
• ‘get_vtk_by_group’: extract domain by a material ID
• ‘tetrahedralize_vtk_mesh’: 3D cells are converted to tetrahedral meshes, 2D cells to triangles
The following code demonstrates the use of the postprocessing filters:
mesh = problem.domain.mesh
mesh_name = mesh.name[mesh.name.rfind(osp.sep) + 1:]
vtkdata = get_vtk_from_mesh(mesh, out, ’postproc_’)
matrix = get_vtk_by_group(vtkdata, 1, 1)
matrix_surf = get_vtk_surface(matrix)
matrix_surf_tri = tetrahedralize_vtk_mesh(matrix_surf)
write_vtk_to_file(’%s_mat1_surface.vtk’ % mesh_name, matrix_surf_tri)
matrix_edges = get_vtk_edges(matrix)
write_vtk_to_file(’%s_mat1_edges.vtk’ % mesh_name, matrix_edges)
4.9 Available Solvers
This Section describes solvers available in SfePy from user’s perspective. There internal/external solvers include
linear, nonlinear, eigenvalue, optimization and time stepping solvers.
4.9.1 Nonlinear Solvers
Almost every problem, even linear, is solved in SfePy using a nonlinear solver that calls a linear solver in each iteration.
This approach unifies treatment of linear and non-linear problems, and simplifies application of Dirichlet (essential)
boundary conditions, as the linear system computes not a solution, but a solution increment, i.e., it always has zero
boundary conditions.
The following solvers are available:
• ‘nls.newton’: Newton solver with backtracking line-search - this is the default solver, that is used for almost all
examples.
• ‘nls.oseen’:
Oseen problem solver
navier_stokes/stabilized_navier_stokes.py).
tailored
for
stabilized
Navier-Stokes
equations
(see
• ‘nls.scipy_broyden_like’: interface to Broyden and Anderson solvers from scipy.optimize.
• ‘nls.semismooth_newton’: Semismooth Newton method for contact/friction problems.
4.9.2 Linear Solvers
A good linear solver is key to solving efficiently stationary as well as transient PDEs with implicit time-stepping. The
following solvers are available:
46
Chapter 4. User’s Guide
SfePy Documentation, Release 2015.1
• ‘ls.scipy_direct’: direct solver from SciPy - this is the default solver for all examples. It is strongly recommended
to install umfpack and its SciPy wrappers to get good performance.
• ‘ls.scipy_iterative’: Interface to SciPy iterative solvers.
• ‘ls.pyamg’: Interface to PyAMG solvers.
• ‘ls.petsc’: Interface to Krylov subspace solvers of PETSc.
• ‘ls.petsc_parallel’: Interface to Krylov subspace solvers of PETSc able to run in parallel by storing the system
to disk and running a separate script via mpiexec.
• ‘ls.schur_complement’: Schur complement problem solver.
4.10 Isogeometric Analysis
Isogeometric analysis (IGA) is a recently developed computational approach that allows using the NURBS-based
domain description from CAD design tools also for approximation purposes similar to the finite element method.
The implementation is SfePy is based on Bezier extraction of NURBS as developed in 9 . This approach allows reusing
the existing finite element assembling routines, as still the evaluation of weak forms occurs locally in “elements” and
the local contributions are then assembled to the global system.
4.10.1 Current Implementation
The IGA code is still very preliminary and some crucial components are missing. The current implementation is also
very slow, as it is in pure Python.
The following already works:
• single patch tensor product domain support in 2D and 3D
• region selection based on topological Bezier mesh, see below
• Dirichlet boundary conditions using projections for non-constant values
• both scalar and vector volume terms work
• term integration over the whole domain as well as a volume subdomain
• simple linearization (output file generation) based on sampling the results with uniform parametric vectors
• basic domain generation with script/gen_iga_patch.py based on ‘igakit‘_
The following is not implemented yet:
• tests
• theoretical convergence rate verification
• fast basis evaluation
• surface terms
• other boundary conditions
• evaluation in arbitrary point in the physical domain
• proper (adaptive) linearization for post-processing
• support for multiple NURBS patches
9
Michael J. Borden, Michael A. Scott, John A. Evans, Thomas J. R. Hughes: Isogeometric finite element data structures based on Bezier
extraction of NURBS, Institute for Computational Engineering and Sciences, The University of Texas at Austin, Austin, Texas, March 2010.
4.10. Isogeometric Analysis
47
SfePy Documentation, Release 2015.1
Domain Description
The domain description is in custom HDF5-based files with .iga extension. Such a file contains:
• NURBS patch data (knots, degrees, control points and weights). Those can either be generated using igakit,
created manually or imported from other tools.
• Bezier extraction operators and corresponding DOF connectivity (computed by SfePy).
• Bezier mesh control points, weights and connectivity (computed by SfePy).
The Bezier mesh is used to create a topological Bezier mesh - a subset of the Bezier mesh containing the Bezier
element corner vertices only. Those vertices are interpolatory (are on the exact geometry) and so can be used for
region selections.
Region Selection
The domain description files contain vertex sets for regions corresponding to the patch sides, named ’xiIJ’, where
I is the parametric axis (0, 1, or 2) and J is 0 or 1 for the beginning and end of the axis knot span. Other regions can
be defined in the usual way, using the topological Bezier mesh entities.
4.10.2 Examples
The examples demonstrating the use of IGA in SfePy are:
• diffusion/poisson_iga.py
• linear_elasticity/linear_elastic_iga.py
• navier_stokes/navier_stokes2d_iga.py
Their problem description files are almost the same as their FEM equivalents, with the following differences:
• There is filename_domain instead of filename_mesh.
• Fields are defined as follows:
fields =
’t1’
’t2’
’t3’
}
{
: (’real’, 1, ’Omega’, None, ’H1’, ’iga’),
: (’real’, 1, ’Omega’, ’iga’, ’H1’, ’iga’),
: (’real’, 1, ’Omega’, ’iga+%d’, ’H1’, ’iga’),
The approximation order in the first definition is None as it is given by the NURBS degrees in the domain
description. The second definition is equivalent to the first one. The third definition, where %d should be a nonnegative integer, illustrates how to increase the field’s NURBS degrees (while keeping the continuity) w.r.t. the
domain NURBS description. It is applied in the navier_stokes/navier_stokes2d_iga.py example to the velocity
field.
48
Chapter 4. User’s Guide
CHAPTER
FIVE
EXAMPLES
This section contains domain-specific tutorials as well as the automatically generated list of the standard examples that
come with SfePy.
5.1 Primer
Table of Contents
• Introduction
– Problem statement
• Meshing
• Problem description
• Running SfePy
• Post-processing
– Running SfePy in interactive mode
– Generating output at element nodes
• Probing
• Interactive Example
A beginner’s tutorial highlighting the basics of SfePy.
5.1.1 Introduction
This primer presents a step-by-step walk-through of the process to solve a simple mechanics problem. The typical
process to solve a problem using SfePy is followed: a model is meshed, a problem definition file is drafted, SfePy is
run to solve the problem and finally the results of the analysis are visualised.
Problem statement
A popular test to measure the tensile strength of concrete or asphalt materials is the indirect tensile strength (ITS) test
pictured below. In this test a cylindrical specimen is loaded across its diameter to failure. The test is usually run by
loading the specimen at a constant deformation rate of 50 mm/minute (say) and measuring the load response. When
the tensile stress that develops in the specimen under loading exceeds its tensile strength then the specimen will fail.
To model this problem using finite elements the indirect tensile test can be simplified to represent a diametrically point
loaded disk as shown in the schematic.
49
SfePy Documentation, Release 2015.1
The tensile and compressive stresses that develop in the specimen as a result of the point loads P are a function of the
diameter (D) and thickness (t) of the cylindrical specimen. At the centre of the specimen, the compressive stress is 3
times the tensile stress and the analytical formulation for these are, respectively:
𝜎𝑡 =
2𝑃
𝜋𝑡𝐷
(5.1)
𝜎𝑐 =
6𝑃
𝜋𝑡𝐷
(5.2)
These solutions may be approximated using finite element methods. To solve this problem using SfePy the first step is
meshing a suitable model.
5.1.2 Meshing
Assuming plane strain conditions, the indirect tensile test may be modelled using a 2-D finite element mesh. Furthermore, the geometry of the model is symmetrical about the x- and y-axes passing through the centre of the circle.
To take advantage of this symmetry only one quarter of the 2-D model will be meshed and boundary conditions will
be established to indicate this symmetry. The meshing program Gmsh is used here to very quickly mesh the model.
Follow these steps to model the ITS:
1. The ITS specimen has a diameter of 150 mm. Using Gmsh add three new points (geometry elementary entities)
at the following coordinates: (0.0 0.0), (75.0,0.0) and (0.0,75.0).
2. Next add two straight lines connecting the points.
3. Next add a Circle arc connecting two of the points to form the quarter circle segment.
4. Still under Geometry add a ruled surface.
5. With the geometry of the model defined, add a mesh by clicking on the 2D button under the Mesh functions.
The figures that follow show the various stages in the model process.
50
Chapter 5. Examples
SfePy Documentation, Release 2015.1
That’s the meshing done. Save the mesh in a format that SfePy recognizes. For now use the medit .mesh format e.g.
its2D.mesh.
Hint: Check the drop down in the Save As dialog for the different formats that Gmsh can save to.
If you open the its2D.mesh file using a text editor you’ll notice that Gmsh saves the mesh in a 3-D format and includes
some extra geometry items that should be deleted. Reformatted the mesh file to a 2-D format and delete the Edges
block. Note that when you do this the file cannot be reopened by Gmsh so it is always a good idea to also save your
meshes in Gmsh’s native format as well (Shift-Ctrl-S). Click here to download the reformatted mesh file that will be
used in the tutorial.
5.1. Primer
51
SfePy Documentation, Release 2015.1
You’ll notice that the mesh contains 55 vertices (nodes) and 83 triangle elements. The mesh file provides the coordinates of the nodes and the element connectivity. It is important to note that node and element numbering in SfePy start
at 0 and not 1 as is the case in Gmsh and some other meshing programs.
To view .mesh files you can use a demo of medit. After loading your mesh file with medit you can see the node and
element numbering by pressing P and F respectively. The numbering in medit starts at 1 as shown. Thus the node
at the center of the model in SfePy numbering is 0, and elements 76 and 77 are connected to this node. Node and
element numbers can also be viewed in Gmsh - under the mesh option under the Visibility tab enable the node and
surface labels. Note that the surface labels as numbered in Gmsh follow on from the line numbering. So to get the
corresponding element number in SfePy you’ll need to subtract the number of lines in the Gmsh file + 1. Confused
yet? Luckily, SfePy provides some useful mesh functions to indicate which elements are connected to which nodes.
Nodes and elements can also be identified by defining regions, which is addressed later.
Another open source python option to view .mesh files is the appropriately named Python Mesh Viewer.
The next step in the process is coding the SfePy problem definition file.
5.1.3 Problem description
The programming of the problem description file is well documented in the SfePy User’s Guide. The problem description file used in the tutorial follows:
1
2
r"""
Diametrically point loaded 2-D disk. See :ref:‘sec-primer‘.
3
4
Find :math:‘\ul{u}‘ such that:
5
6
7
8
9
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
10
11
where
12
13
14
15
16
17
18
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from sfepy.mechanics.matcoefs import lame_from_youngpoisson
52
Chapter 5. Examples
SfePy Documentation, Release 2015.1
19
20
from sfepy.discrete.fem.utils import refine_mesh
from sfepy import data_dir
21
22
23
# Fix the mesh file name if you run this file outside the SfePy directory.
filename_mesh = data_dir + ’/meshes/2d/its2D.mesh’
24
25
26
refinement_level = 0
filename_mesh = refine_mesh(filename_mesh, refinement_level)
27
28
output_dir = ’.’ # set this to a valid directory you have write access to
29
30
31
young = 2000.0 # Young’s modulus [MPa]
poisson = 0.4 # Poisson’s ratio
32
33
34
35
options = {
’output_dir’ : output_dir,
}
36
37
38
39
40
41
42
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Bottom’ : (’vertices in (y < 0.001)’, ’facet’),
’Top’ : (’vertex 2’, ’vertex’),
}
43
44
45
46
47
48
49
50
materials = {
’Asphalt’ : ({
’lam’ : lame_from_youngpoisson(young, poisson)[0],
’mu’ : lame_from_youngpoisson(young, poisson)[1],
},),
’Load’ : ({’.val’ : [0.0, -1000.0]},),
}
51
52
53
54
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
55
56
57
58
59
60
equations = {
’balance_of_forces’ :
"""dw_lin_elastic_iso.2.Omega(Asphalt.lam, Asphalt.mu, v, u )
= dw_point_load.0.Top(Load.val, v)""",
}
61
62
63
64
65
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
66
67
68
69
70
ebcs = {
’XSym’ : (’Bottom’, {’u.1’ : 0.0}),
’YSym’ : (’Left’, {’u.0’ : 0.0}),
}
71
72
73
74
75
76
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-6,
5.1. Primer
53
SfePy Documentation, Release 2015.1
}),
77
78
}
Download and open the file in your favourite python editor. Note that you may wish to change the location of the
output directory to somewhere on your drive. You may also need to edit the mesh file name. For the analysis we
will assume that the material of the test specimen is linear elastic and isotropic. We define two material constants i.e.
Young’s modulus and Poisson’s ratio. The material is assumed to be asphalt concrete having a Young’s modulus of
2,000 MPa and a Poisson’s ration of 0.4.
Note: Be consistent in your choice and use of units. In the tutorial we are using Newton (N), millimeters (mm) and
megaPascal (MPa). The sfepy.mechanics.units module might help you in determining which derived units correspond
to given basic units.
The following block of code defines regions on your mesh:
1
2
3
4
5
6
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Bottom’ : (’vertices in (y < 0.001)’, ’facet’),
’Top’ : (’vertex 2’, ’vertex’),
}
Four regions are defined:
1. Omega: all the elements in the mesh
2. Left: the y-axis
3. Bottom: the x-axis
4. Top: the topmost node. This is where the load is applied.
Having defined the regions these can be used in other parts of your code. For example, in the definition of the boundary
conditions:
1
2
3
4
ebcs = {
’XSym’ : (’Bottom’, {’u.1’ : 0.0}),
’YSym’ : (’Left’, {’u.0’ : 0.0}),
}
Now the power of the regions entity becomes apparent. To ensure symmetry about the x-axis, the vertical or ydisplacement of the nodes in the Bottom region are prevented or set to zero. Similarly, for symmetry about the y-axis,
any horizontal or displacement in the x-direction of the nodes in the Left region or y-axis is prevented.
The load is specified in terms of the ‘Load’ material as follows:
1
2
3
4
5
6
7
materials = {
’Asphalt’ : ({
’lam’ : lame_from_youngpoisson(young, poisson)[0],
’mu’ : lame_from_youngpoisson(young, poisson)[1],
},),
’Load’ : ({’.val’ : [0.0, -1000.0]},),
}
Note the dot in ‘.val’ - this denotes a special material value, i.e., a value that is not to be evaluated in quadrature points.
The load is then applied in equations using the ‘dw_point_load.0.Top(Load.val, v)’ term in the topmost node (region
Top).
We provided the material constants in terms of Young’s modulus and Poisson’s ratio, but the linear elastic isotropic
equation used requires as input Lamé’s parameters. The lame_from_youngpoisson() function is thus used for conversion. Note that to use this function it was necessary to import the function into the code, which was done up
front:
54
Chapter 5. Examples
SfePy Documentation, Release 2015.1
from sfepy.mechanics.matcoefs import lame_from_youngpoisson
Hint: Check out the sfepy.mechanics.matcoefs module for other useful material related functions.
That’s it - we are now ready to solve the problem.
5.1.4 Running SfePy
One option to solve the problem is to run the SfePy simple.py script from the command shell:
$ ./simple.py its2D_1.py
Note: For the purpose of this tutorial it is assumed that the problem definition file (its2D_1.py) is in the same directory
as the simple.py script. If you have the its2D_1.py file in another directory then make sure you include the path to this
file as well.
SfePy solves the problem and outputs the solution to the output path (output_dir) provided in the script. The output
file will be in the vtk format by default if this is not explicitly specified and the name of the output file will be the same
as that used for the mesh file except with the vtk extension i.e. its2D.vtk.
The vtk format is an ascii format. Open the file using a text editor. You’ll notice that the output file includes separate
sections:
• POINTS (these are the model nodes)
• CELLS (the model element connectivity)
• VECTORS (the node displacements in the x-, y- and z- directions.
SfePy includes a script (postproc.py) to quickly view the solution. To run this script you need to have Mayavi installed.
From the command line issue the following (with the correct paths):
$ ./postproc.py its2D.vtk
The postproc.py script generates the image shown below, which shows by default the displacements in the model as
arrows and their magnitude as color scale. Cool, but we are more interested in the stresses. To get these we need to
modify the problem description file and do some post-processing.
5.1.5 Post-processing
SfePy provides functions to calculate stresses and strains. We’ll include a function to calculate these and update the
problem material definition and options to call this function as a post_process_hook. Save this file as its2D_2.py.
5.1. Primer
55
SfePy Documentation, Release 2015.1
1
2
3
r"""
Diametrically point loaded 2-D disk with postprocessing. See
:ref:‘sec-primer‘.
4
5
Find :math:‘\ul{u}‘ such that:
6
7
8
9
10
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
11
12
where
13
14
15
16
17
18
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
19
20
from its2D_1 import *
21
22
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
23
24
25
26
27
28
def stress_strain(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
29
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
stress = ev(’ev_cauchy_stress.2.Omega(Asphalt.D, u)’, mode=’el_avg’)
30
31
32
33
out[’cauchy_strain’] = Struct(name=’output_data’, mode=’cell’,
data=strain, dofs=None)
out[’cauchy_stress’] = Struct(name=’output_data’, mode=’cell’,
data=stress, dofs=None)
34
35
36
37
38
return out
39
40
41
42
43
asphalt = materials[’Asphalt’][0]
asphalt.update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
options.update({’post_process_hook’ : ’stress_strain’,})
The updated file imports all of the previous definitions in its2D_1.py. The stress function (de_cauchy_stress) requires
as input the stiffness tensor - thus it was necessary to update the materials accordingly. The problem options were also
updated to call the stress_strain function as a post_process_hook.
Run SfePy to solve the updated problem and view the solution (assuring the correct paths):
$ ./simple.py its2D_2.py
$ ./postproc.py its2D.vtk -b
In addition to the node displacements, the vtk output shown below now also includes the stresses and strains averaged
in the elements:
56
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Remember the objective was to determine the stresses at the centre of the specimen under a load P. The solution as
currently derived is expressed in terms of a global displacement vector (u). The global (residual) force vector (f) is a
function of the global displacement vector and the global stiffness matrix (K) as: f = Ku. Let’s determine the force
vector interactively.
Running SfePy in interactive mode
In addition to solving problems using the simple.py script you can also run SfePy interactively. We will use IPython
with custom imports, as described in Using IPython. In the SfePy top-level directory:
$ ipython --profile=sfepy
Once the customized ipython shell loads up, issue the following command:
In [1]: pb, state = solve_pde(’its2D_2.py’)
The problem is solved and the problem definition and solution are provided in the pb and state variables, respectively.
The solution, or in this case, the global displacement vector (u), contains the x- and y-displacements at the nodes in
the 2D model:
1
In [2]: u = state()
2
3
4
5
6
In [3]: u
Out[3]:
array([ 0.
, 0.
, 0.37376671, ..., -0.19923848,
0.08820237, -0.11201528])
7
8
9
In [4]: u.shape
Out[4]: (110,)
10
11
In [5]: u.shape = (55, 2)
12
13
14
15
16
17
18
19
20
21
In [6]: u
Out[6]:
array([[ 0.
,
[ 0.37376671,
[ 0.
,
...,
[ 0.08716448,
[ 0.27741356,
[ 0.08820237,
5.1. Primer
0.
],
0.
],
-1.65318152],
-0.23069047],
-0.19923848],
-0.11201528]])
57
SfePy Documentation, Release 2015.1
Note: We have used the fact, that the state vector contains only one variable (u). In general, the following can be used:
1
In [7]: u = state.get_parts()[’u’]
2
3
4
5
6
7
8
9
10
11
In [8]: u
Out[8]:
array([[ 0.
,
[ 0.37376671,
[ 0.
,
...,
[ 0.08716448,
[ 0.27741356,
[ 0.08820237,
0.
],
0.
],
-1.65318152],
-0.23069047],
-0.19923848],
-0.11201528]])
Both state() and state.get_parts() return a view of the DOF vector, that is why in Out[8] the vector is reshaped according to Out[6].
From the above it can be seen that u holds the displacements at the 55 nodes in the model and that the displacement at
node 2 (on which the load is applied) is (0, -1.65318152). The global stiffness matrix is saved in pb as a sparse matrix:
1
In [9]: K = pb.mtx_a
2
3
4
5
6
In [10]: K
Out[10]:
<94x94 sparse matrix of type ’<type ’numpy.float64’>’
with 1070 stored elements in Compressed Sparse Row format>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
In [11]: print K
(0, 0)
2443.95959851
(0, 7)
-2110.99917491
(0, 14)
-332.960423597
(0, 15)
1428.57142857
(1, 1)
2443.95959852
(1, 13)
-2110.99917492
(1, 32)
1428.57142857
(1, 33)
-332.960423596
(2, 2)
4048.78343529
(2, 3)
-1354.87004384
(2, 52)
-609.367453538
(2, 53)
-1869.0018791
(2, 92)
-357.41672785
(2, 93)
1510.24654193
(3, 2)
-1354.87004384
(3, 3)
4121.03202907
(3, 4)
-1696.54911732
(3, 48)
76.2400806561
(3, 49)
-1669.59247304
(3, 52)
-1145.85294856
(3, 53)
2062.13955556
(4, 3)
-1696.54911732
(4, 4)
4410.17902905
(4, 5)
-1872.87344838
(4, 42)
-130.515009576
:
:
(91, 81)
-1610.0550578
(91, 86)
-199.343680224
(91, 87)
-2330.41406097
(91, 90)
-575.80373408
(91, 91)
7853.23899229
58
Chapter 5. Examples
SfePy Documentation, Release 2015.1
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(92,
(92,
(92,
(92,
(92,
(92,
(92,
(92,
(92,
(92,
(93,
(93,
(93,
(93,
(93,
(93,
(93,
(93,
(93,
(93,
2)
8)
50)
51)
52)
53)
88)
89)
92)
93)
2)
8)
50)
51)
52)
53)
88)
89)
92)
93)
-357.41672785
1735.59411191
-464.976034459
-1761.31189004
-3300.45367361
1574.59387937
-250.325600254
1334.11823335
9219.18643706
-2607.52659081
1510.24654193
-657.361661955
-1761.31189004
54.1134516246
1574.59387937
-315.793227627
1334.11823335
-4348.13351285
-2607.52659081
9821.16012014
60
61
62
In [12]: K.shape
Out[12]: (94, 94)
One would expect the shape of the global stiffness matrix (K) to be (110,110) i.e. to have the same number of rows
and columns as u. This matrix has been reduced by the fixed degrees of freedom imposed by the boundary conditions
set at the nodes on symmetry axes. To restore the matrix, temporarily remove the imposed boundary conditions:
In [13]: pb.remove_bcs()
Now we can calculate the force vector (f):
1
In [14]: f = pb.evaluator.eval_residual(u)
2
3
4
In [15]: f.shape
Out[15]: (110,)
5
6
7
8
9
In [16]: f
Out[16]:
array([ -4.73618436e+01,
-2.06057393e-13,
1.42752386e+02,
2.13162821e-14,
1.56921124e-13, ...,
-2.84217094e-14])
Remember to restore the original boundary conditions previously removed in step [13]:
In [17]: pb.time_update()
To view the residual force vector, we can save it to a vtk file. This requires creating a state and set its DOF vector to f
as follows:
1
In [18]: state = pb.create_state()
2
3
In [19]: state.set_full(f)
4
5
In [20]: out = state.create_output_dict()
6
7
In [21]: pb.save_state(’file.vtk’, out=out)
Running the postproc.py script on file.vtk displays the average nodal forces as shown below.
5.1. Primer
59
SfePy Documentation, Release 2015.1
The forces in the x- and y-directions at node 2 are:
1
In [22]: f.shape = (55, 2)
2
3
4
In [23]: f[2]
Out[23]: array([
6.20373272e+02,
-1.13686838e-13])
Great, we have an almost zero residual vertical load or force apparent at node 2 i.e. -1.13686838e-13 Newton. Let us
now check the stress at node 0, the centre of the specimen.
Generating output at element nodes
Previously we had calculated the stresses in the model but these were averaged from those calculated at Gauss quadrature points within the elements. It is possible to provide custom integrals to allow the calculation of stresses with the
Gauss quadrature points at the element nodes. This will provide us a more accurate estimate of the stress at the centre
of the specimen located at node 0. The code below outlines one way to achieve this.
1
2
3
r"""
Diametrically point loaded 2-D disk with nodal stress calculation. See
:ref:‘sec-primer‘.
4
5
Find :math:‘\ul{u}‘ such that:
6
7
8
9
10
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
11
12
where
13
14
15
16
17
18
19
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from its2D_1 import *
20
21
22
23
24
25
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.discrete.fem.geometry_element import geometry_data
from sfepy.discrete import FieldVariable
from sfepy.discrete.fem import Field
import numpy as nm
60
Chapter 5. Examples
SfePy Documentation, Release 2015.1
26
27
28
gdata = geometry_data[’2_3’]
nc = len(gdata.coors)
29
30
31
32
33
def nodal_stress(out, pb, state, extend=False, integrals=None):
’’’
Calculate stresses at nodal points.
’’’
34
35
36
37
# Point load.
mat = pb.get_materials()[’Load’]
P = 2.0 * mat.get_data(’special’, None, ’val’)[1]
38
39
40
# Calculate nodal stress.
pb.time_update()
41
42
if integrals is None: integrals = pb.get_integrals()
43
44
45
46
47
48
49
50
stress = pb.evaluate(’ev_cauchy_stress.ivn.Omega(Asphalt.D, u)’, mode=’qp’,
integrals=integrals)
sfield = Field.from_args(’stress’, nm.float64, (3,),
pb.domain.regions[’Omega’])
svar = FieldVariable(’sigma’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
svar.set_data_from_qp(stress, integrals[’ivn’])
51
52
53
54
55
56
57
58
59
60
61
62
63
print ’\n==================================================================’
print ’Given load = %.2f N’ % -P
print ’\nAnalytical solution’
print ’===================’
print ’Horizontal tensile stress = %.5e MPa/mm’ % (-2.*P/(nm.pi*150.))
print ’Vertical compressive stress = %.5e MPa/mm’ % (-6.*P/(nm.pi*150.))
print ’\nFEM solution’
print ’============’
print ’Horizontal tensile stress = %.5e MPa/mm’ % (svar()[0][0])
print ’Vertical compressive stress = %.5e MPa/mm’ % (-svar()[0][1])
print ’==================================================================’
return out
64
65
66
67
asphalt = materials[’Asphalt’][0]
asphalt.update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
options.update({’post_process_hook’ : ’nodal_stress’,})
68
69
70
71
integrals = {
’ivn’ : (’custom’, gdata.coors, [gdata.volume / nc] * nc),
}
The output:
1
2
==================================================================
Given load = 2000.00 N
3
4
5
6
7
Analytical solution
===================
Horizontal tensile stress = 8.48826e+00 MPa/mm
Vertical compressive stress = 2.54648e+01 MPa/mm
8
9
10
FEM solution
============
5.1. Primer
61
SfePy Documentation, Release 2015.1
11
12
13
Horizontal tensile stress = 7.57220e+00 MPa/mm
Vertical compressive stress = 2.58660e+01 MPa/mm
==================================================================
Not bad for such a coarse mesh! Re-running the problem using a finer mesh provides a more accurate solution:
1
2
==================================================================
Given load = 2000.00 N
3
4
5
6
7
Analytical solution
===================
Horizontal tensile stress = 8.48826e+00 MPa/mm
Vertical compressive stress = 2.54648e+01 MPa/mm
8
9
10
11
12
FEM solution
============
Horizontal tensile stress = 8.50042e+00 MPa/mm
Vertical compressive stress = 2.54300e+01 MPa/mm
To see how the FEM solution approaches the analytical one, try to play with the uniform mesh refinement level in the
Problem description file, namely lines 25, 26:
refinement_level = 0
filename_mesh = refine_mesh(filename_mesh, refinement_level)
The above computation could also be done in the customized ipython shell:
1
In [23]: from sfepy.discrete.fem.geometry_element import geometry_data
2
3
4
5
6
In [24]: gdata = geometry_data[’2_3’]
In [25]: nc = len(gdata.coors)
In [26]: ivn = Integral(’ivn’, order=-1,
....:
coors=gdata.coors, weights=[gdata.volume / nc] * nc)
7
8
In [27]: pb, state = solve_pde(’examples/linear_elasticity/its2D_2.py’)
9
10
11
12
13
14
15
In [28]:
....:
In [29]:
In [30]:
....:
In [31]:
stress = pb.evaluate(’ev_cauchy_stress.ivn.Omega(Asphalt.D,u)’,
mode=’qp’, integrals=Integrals([ivn]))
sfield = Field(’stress’, nm.float64, (3,), pb.domain.regions[’Omega’])
svar = FieldVariable(’sigma’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
svar.set_data_from_qp(stress, ivn)
16
17
18
19
20
In [32]: print ’Horizontal tensile stress = %.5e MPa/mm’ % (svar()[0][0])
Horizontal tensile stress = 7.57220e+00 MPa/mm
In [33]: print ’Vertical compressive stress = %.5e MPa/mm’ % (-svar()[0][1])
Vertical compressive stress = 2.58660e+01 MPa/mm
21
22
23
24
25
In [34]:
In [35]:
In [36]:
Out[36]:
mat = pb.get_materials()[’Load’]
P = 2.0 * mat.get_data(’special’, None, ’val’)[1]
P
-2000.0
26
27
28
29
30
In [37]: print ’Horizontal tensile stress = %.5e MPa/mm’ % (-2.*P/(nm.pi*150.))
Horizontal tensile stress = 8.48826e+00 MPa/mm
In [38]: print ’Vertical compressive stress = %.5e MPa/mm’ % (-6.*P/(nm.pi*150.))
Vertical compressive stress = 2.54648e+01 MPa/mm
To wrap this tutorial up let’s explore SfePy‘s probing functions.
62
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.1.6 Probing
As a bonus for sticking to the end of this tutorial see the following problem definition file that provides
SfePy functions to quickly and neatly probe the solution.
1
2
3
r"""
Diametrically point loaded 2-D disk with postprocessing and probes. See
:ref:‘sec-primer‘.
4
5
Find :math:‘\ul{u}‘ such that:
6
7
8
9
10
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
11
12
where
13
14
15
16
17
18
19
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from its2D_1 import *
20
21
22
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.postprocess.probes_vtk import Probe
23
24
import os
25
26
27
28
29
30
31
32
def stress_strain(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
33
34
35
36
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
stress = ev(’ev_cauchy_stress.2.Omega(Asphalt.D, u)’, mode=’el_avg’)
37
38
39
40
41
out[’cauchy_strain’] = Struct(name=’output_data’, mode=’cell’,
data=strain, dofs=None)
out[’cauchy_stress’] = Struct(name=’output_data’, mode=’cell’,
data=stress, dofs=None)
42
43
probe = Probe(out, pb.domain.mesh, probe_view=True)
44
45
46
47
ps0 = [[0.0, 0.0, 0.0], [ 0.0, 0.0, 0.0]]
ps1 = [[75.0, 0.0, 0.0], [ 0.0, 75.0, 0.0]]
n_point = 10
48
49
50
51
52
53
54
labels = [’%s -> %s’ % (p0, p1) for p0, p1 in zip(ps0, ps1)]
probes = []
for ip in xrange(len(ps0)):
p0, p1 = ps0[ip], ps1[ip]
probes.append(’line%d’ % ip)
probe.add_line_probe(’line%d’ % ip, p0, p1, n_point)
5.1. Primer
63
SfePy Documentation, Release 2015.1
55
for ip, label in zip(probes, labels):
fig = plt.figure()
plt.clf()
fig.subplots_adjust(hspace=0.4)
plt.subplot(311)
pars, vals = probe(ip, ’u’)
for ic in range(vals.shape[1] - 1):
plt.plot(pars, vals[:,ic], label=r’$u_{%d}$’ % (ic + 1),
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’displacements’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=10))
56
57
58
59
60
61
62
63
64
65
66
67
68
sym_indices = [0, 4, 1]
sym_labels = [’11’, ’22’, ’12’]
69
70
71
plt.subplot(312)
pars, vals = probe(ip, ’cauchy_strain’)
for ii, ic in enumerate(sym_indices):
plt.plot(pars, vals[:,ic], label=r’$e_{%s}$’ % sym_labels[ii],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy strain’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=8))
72
73
74
75
76
77
78
79
80
plt.subplot(313)
pars, vals = probe(ip, ’cauchy_stress’)
for ii, ic in enumerate(sym_indices):
plt.plot(pars, vals[:,ic], label=r’$\sigma_{%s}$’ % sym_labels[ii],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy stress’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=8))
81
82
83
84
85
86
87
88
89
opts = pb.conf.options
filename_results = os.path.join(opts.get(’output_dir’),
’its2D_probe_%s.png’ % ip)
90
91
92
93
fig.savefig(filename_results)
94
95
return out
96
97
98
materials[’Asphalt’][0].update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
99
100
101
102
options.update({
’post_process_hook’ : ’stress_strain’,
})
Probing applies interpolation to output the solution along specified paths. For the tutorial, line probing is done along
the x- and y-axes of the model.
Run SfePy to solve the problem and apply the probes:
$ ./simple.py its2D_5.py
The probing function will generate the following figures that show the displacements, normal stresses and strains as
well as shear stresses and strains along the probe paths. Note that you need matplotlib installed to run this example.
64
Chapter 5. Examples
SfePy Documentation, Release 2015.1
The probing function also generates previews of the mesh with the probe paths.
5.1. Primer
65
SfePy Documentation, Release 2015.1
5.1.7 Interactive Example
SfePy can be used also interactively by constructing directly the classes that corresponds to the keywords in the
problem description files. The following listing shows a script with the same (and more) functionality as the above
examples:
1
2
3
4
#!/usr/bin/env python
"""
Diametrically point loaded 2-D disk, using commands for interactive use. See
:ref:‘sec-primer‘.
5
6
7
The script combines the functionality of all the ‘‘its2D_?.py‘‘ examples and
allows setting various simulation parameters, namely:
8
9
10
11
- material parameters
- displacement field approximation order
- uniform mesh refinement level
12
13
14
15
16
The example shows also how to probe the results as in
:ref:‘linear_elasticity-its2D_4‘, and how to display the results using Mayavi.
Using :mod:‘sfepy.discrete.probes‘ allows correct probing of fields with the
approximation order greater than one.
17
18
19
In the SfePy top-level directory the following command can be used to get usage
information::
20
21
python examples/linear_elasticity/its2D_interactive.py -h
22
23
24
Notes
-----
25
26
27
28
29
30
31
The ‘‘--probe‘‘ and ‘‘--show‘‘ options work simultaneously only if Mayavi and
Matplotlib use the same backend type (for example wx).
"""
import sys
sys.path.append(’.’)
from optparse import OptionParser
32
33
34
import numpy as nm
import matplotlib.pyplot as plt
35
36
37
from sfepy.base.base import assert_, output, ordered_iteritems, IndexedStruct
from sfepy.discrete import (FieldVariable, Material, Integral, Integrals,
66
Chapter 5. Examples
SfePy Documentation, Release 2015.1
38
39
40
41
42
43
44
45
46
47
from
from
from
from
from
from
from
from
from
Equation, Equations, Problem)
sfepy.discrete.fem import Mesh, FEDomain, Field
sfepy.terms import Term
sfepy.discrete.conditions import Conditions, EssentialBC
sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
sfepy.solvers.ls import ScipyDirect
sfepy.solvers.nls import Newton
sfepy.discrete.fem.geometry_element import geometry_data
sfepy.discrete.probes import LineProbe
sfepy.discrete.projections import make_l2_projection_data
48
49
50
from its2D_2 import stress_strain
from its2D_3 import nodal_stress
51
52
53
54
55
56
57
58
59
60
61
def project_by_component(tensor, tensor_qp, component, order):
"""
Wrapper around make_l2_projection_data() for non-scalar fields.
"""
aux = []
for ic in range(3):
make_l2_projection_data(component, tensor_qp[..., ic, :].copy(),
order=order)
aux.append(component())
tensor.set_data(nm.array(aux).T.ravel())
62
63
64
65
def gen_lines(problem):
"""
Define two line probes.
66
67
68
69
70
71
Additional probes can be added by appending to ‘ps0‘ (start points) and
‘ps1‘ (end points) lists.
"""
ps0 = [[0.0, 0.0], [0.0, 0.0]]
ps1 = [[75.0, 0.0], [0.0, 75.0]]
72
73
74
# Use enough points for higher order approximations.
n_point = 1000
75
76
77
78
79
80
labels = [’%s -> %s’ % (p0, p1) for p0, p1 in zip(ps0, ps1)]
probes = []
for ip in xrange(len(ps0)):
p0, p1 = ps0[ip], ps1[ip]
probes.append(LineProbe(p0, p1, n_point))
81
82
return probes, labels
83
84
85
86
87
88
def probe_retults(u, strain, stress, probe, label):
"""
Probe the results using the given probe and plot the probed values.
"""
results = {}
89
90
91
92
93
94
95
pars, vals = probe(u)
results[’u’] = (pars, vals)
pars, vals = probe(strain)
results[’cauchy_strain’] = (pars, vals)
pars, vals = probe(stress)
results[’cauchy_stress’] = (pars, vals)
5.1. Primer
67
SfePy Documentation, Release 2015.1
96
fig = plt.figure()
plt.clf()
fig.subplots_adjust(hspace=0.4)
plt.subplot(311)
pars, vals = results[’u’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$u_{%d}$’ % (ic + 1),
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’displacements’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
97
98
99
100
101
102
103
104
105
106
107
108
sym_indices = [’11’, ’22’, ’12’]
109
110
plt.subplot(312)
pars, vals = results[’cauchy_strain’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$e_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy strain’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
111
112
113
114
115
116
117
118
119
plt.subplot(313)
pars, vals = results[’cauchy_stress’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$\sigma_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy stress’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
120
121
122
123
124
125
126
127
128
return fig, results
129
130
131
usage = ’%prog [options]\n’ + __doc__.rstrip()
132
133
134
135
136
137
138
139
140
141
142
helps = {
’young’ : "the Young’s modulus [default: %default]",
’poisson’ : "the Poisson’s ratio [default: %default]",
’load’ : "the vertical load value (negative means compression)"
" [default: %default]",
’order’ : ’displacement field approximation order [default: %default]’,
’refine’ : ’uniform mesh refinement level [default: %default]’,
’probe’ : ’probe the results’,
’show’ : ’show the results figure’,
}
143
144
145
def main():
from sfepy import data_dir
146
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’--young’, metavar=’float’, type=float,
action=’store’, dest=’young’,
default=2000.0, help=helps[’young’])
parser.add_option(’--poisson’, metavar=’float’, type=float,
action=’store’, dest=’poisson’,
default=0.4, help=helps[’poisson’])
147
148
149
150
151
152
153
68
Chapter 5. Examples
SfePy Documentation, Release 2015.1
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
parser.add_option(’--load’, metavar=’float’, type=float,
action=’store’, dest=’load’,
default=-1000.0, help=helps[’load’])
parser.add_option(’--order’, metavar=’int’, type=int,
action=’store’, dest=’order’,
default=1, help=helps[’order’])
parser.add_option(’-r’, ’--refine’, metavar=’int’, type=int,
action=’store’, dest=’refine’,
default=0, help=helps[’refine’])
parser.add_option(’-s’, ’--show’,
action="store_true", dest=’show’,
default=False, help=helps[’show’])
parser.add_option(’-p’, ’--probe’,
action="store_true", dest=’probe’,
default=False, help=helps[’probe’])
options, args = parser.parse_args()
170
171
172
173
174
assert_((0.0 < options.poisson < 0.5),
"Poisson’s ratio must be in ]0, 0.5[!")
assert_((0 < options.order),
’displacement approximation order must be at least 1!’)
175
176
177
178
179
180
output(’using values:’)
output(" Young’s modulus:", options.young)
output(" Poisson’s ratio:", options.poisson)
output(’ vertical load:’, options.load)
output(’uniform mesh refinement level:’, options.refine)
181
182
183
184
# Build the problem definition.
mesh = Mesh.from_file(data_dir + ’/meshes/2d/its2D.mesh’)
domain = FEDomain(’domain’, mesh)
185
186
187
188
189
190
191
if options.refine > 0:
for ii in xrange(options.refine):
output(’refine %d...’ % ii)
domain = domain.refine()
output(’... %d nodes %d elements’
% (domain.shape.n_nod, domain.shape.n_el))
192
193
194
195
196
197
198
omega = domain.create_region(’Omega’, ’all’)
left = domain.create_region(’Left’,
’vertices in x < 0.001’, ’facet’)
bottom = domain.create_region(’Bottom’,
’vertices in y < 0.001’, ’facet’)
top = domain.create_region(’Top’, ’vertex 2’, ’vertex’)
199
200
201
field = Field.from_args(’fu’, nm.float64, ’vector’, omega,
approx_order=options.order)
202
203
204
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
205
206
D = stiffness_from_youngpoisson(2, options.young, options.poisson)
207
208
209
asphalt = Material(’Asphalt’, D=D)
load = Material(’Load’, values={’.val’ : [0.0, options.load]})
210
211
integral = Integral(’i’, order=2*options.order)
5.1. Primer
69
SfePy Documentation, Release 2015.1
integral0 = Integral(’i’, order=0)
212
213
t1 = Term.new(’dw_lin_elastic(Asphalt.D, v, u)’,
integral, omega, Asphalt=asphalt, v=v, u=u)
t2 = Term.new(’dw_point_load(Load.val, v)’,
integral0, top, Load=load, v=v)
eq = Equation(’balance’, t1 - t2)
eqs = Equations([eq])
214
215
216
217
218
219
220
xsym = EssentialBC(’XSym’, bottom, {’u.1’ : 0.0})
ysym = EssentialBC(’YSym’, left, {’u.0’ : 0.0})
221
222
223
ls = ScipyDirect({})
224
225
nls_status = IndexedStruct()
nls = Newton({}, lin_solver=ls, status=nls_status)
226
227
228
pb = Problem(’elasticity’, equations=eqs, nls=nls, ls=ls)
229
230
pb.time_update(ebcs=Conditions([xsym, ysym]))
231
232
# Solve the problem.
state = pb.solve()
output(nls_status)
233
234
235
236
# Postprocess the solution.
out = state.create_output_dict()
out = stress_strain(out, pb, state, extend=True)
pb.save_state(’its2D_interactive.vtk’, out=out)
237
238
239
240
241
gdata = geometry_data[’2_3’]
nc = len(gdata.coors)
242
243
244
integral_vn = Integral(’ivn’, coors=gdata.coors,
weights=[gdata.volume / nc] * nc)
245
246
247
nodal_stress(out, pb, state, integrals=Integrals([integral_vn]))
248
249
if options.probe:
# Probe the solution.
probes, labels = gen_lines(pb)
250
251
252
253
sfield = Field.from_args(’sym_tensor’, nm.float64, 3, omega,
approx_order=options.order - 1)
stress = FieldVariable(’stress’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
strain = FieldVariable(’strain’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
254
255
256
257
258
259
260
cfield = Field.from_args(’component’, nm.float64, 1, omega,
approx_order=options.order - 1)
component = FieldVariable(’component’, ’parameter’, cfield,
primary_var_name=’(set-to-None)’)
261
262
263
264
265
ev = pb.evaluate
order = 2 * (options.order - 1)
strain_qp = ev(’ev_cauchy_strain.%d.Omega(u)’ % order, mode=’qp’)
stress_qp = ev(’ev_cauchy_stress.%d.Omega(Asphalt.D, u)’ % order,
266
267
268
269
70
Chapter 5. Examples
SfePy Documentation, Release 2015.1
mode=’qp’)
270
271
project_by_component(strain, strain_qp, component, order)
project_by_component(stress, stress_qp, component, order)
272
273
274
all_results = []
for ii, probe in enumerate(probes):
fig, results = probe_retults(u, strain, stress, probe, labels[ii])
275
276
277
278
fig.savefig(’its2D_interactive_probe_%d.png’ % ii)
all_results.append(results)
279
280
281
for ii, results in enumerate(all_results):
output(’probe %d:’ % ii)
output.level += 2
for key, res in ordered_iteritems(results):
output(key + ’:’)
val = res[1]
output(’ min: %+.2e, mean: %+.2e, max: %+.2e’
% (val.min(), val.mean(), val.max()))
output.level -= 2
282
283
284
285
286
287
288
289
290
291
292
293
294
295
if options.show:
# Show the solution. If the approximation order is greater than 1, the
# extra DOFs are simply thrown away.
from sfepy.postprocess.viewer import Viewer
296
view = Viewer(’its2D_interactive.vtk’)
view(vector_mode=’warp_norm’, rel_scaling=1,
is_scalar_bar=True, is_wireframe=True)
297
298
299
300
301
302
if __name__ == ’__main__’:
main()
The script can be run from the SfePy top-level directory, assuming the in-place build, as follows:
python examples/linear_elasticity/its2D_interactive.py
The script allows setting several parameters that influence the solution, see:
python examples/linear_elasticity/its2D_interactive.py -h
for the complete list. Besides the material parameters, a uniform mesh refinement level and the displacement field
approximation order can be specified. The script demonstrates how to
• project a derived quantity, that is evaluated in quadrature points (e.g. a strain or stress), into a field variable;
• probe the solution defined in the field variables.
Using sfepy.discrete.probes allows correct probing of fields with the approximation order greater than one.
The end.
5.1. Primer
71
SfePy Documentation, Release 2015.1
5.2 Using Salome with SfePy
5.2.1 Introduction
Salome is a powerful open-source tool for generating meshes for numerical simulation and post processing the results.
This is a short tutorial on using Salome as a preprocessor for preparing meshes for use with SfePy.
Tutorial prerequisites
This tutorial assumes that you have a working copy of Salome. It is possible to build Salome from source code.
Fortunately, for the less brave, many pre-compiled binaries for different platforms are available at the Salome download
page. Registration for a free account may be required to download from the preceding site.
In addition, this tutorial assumes you have a working copy of SfePy with MED read support. See the Installation for
help. Note that it is not actually necessary to “install” SfePy; one may run the code from the source directory (see
notation below) after compilation of the C extension modules (again, see the installation notes if you are confused).
Note on notation used in this tutorial
We are using the following notations:
• <sfepy_root>: the root directory of the SfePy source code
• <work_dir>: the working directory where you plan to save your files
5.2.2 Step 1: Using Salome
Salome has its own set of tutorials and community resources. It is suggested you look around on Salome web site to
familiarize yourself with the available resources.
This tutorial follows the EDF Exercise 1 available from the Salome Tutorial Site. Go ahead and complete this tutorial
now. We will use the result from there in the following.
This is the mesh you should end up with:
72
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.2.3 Step 2: Exporting mesh from Salome
In the Salome MESH module, right click on the mesh object Mesh_Partition_Hexa you created in the Salome
EDF Exercise 1 Tutorial and click Export to MED file. Save the file as Mesh_Partition_Hexa.med in
your working directory <work_dir>.
5.2.4 Step 3: Copy SfePy project description files
In this tutorial, we will assume that we need to solve a linear elasticity problem on the mesh generated by Salome.
Since the Salome mesh looks a bit like a fish, we will try to simulate the fish waving its tail.
Copy the file <sfepy_root>/examples/linear_elasticity/linear_elastic.py to <work_dir>.
Use your favorite python editor to load this file. We will customize this file for our purposes.
5.2.5 Step 4: Modify linear_elastic.py
Mesh specification
The first thing we have to do is tell SfePy to use our new mesh. Change the line
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
to
filename_mesh = ’Mesh_Partition_Hexa.med’
Region specification
Next, we have to define sensible Regions for the mesh. We will apply a displacement to the Tail and keep the Top and
Bottom of the fish fixed. Change the lines
5.2. Using Salome with SfePy
73
SfePy Documentation, Release 2015.1
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
’SomewhereTop’ : (’vertices in (z > 0.017) & (x > 0.03) & (x < 0.07)’, ’vertex’),
}
to
regions = {
’Omega’ : ’all’,
’Tail’ : (’vertices in (x < -94)’, ’facet’),
’TopFixed’ : (’vertices in (z > 9.999) & (x > 54)’, ’facet’),
’BotFixed’ : (’vertices in (z < 0.001) & (x > 54)’, ’facet’),
}
Field specification
The Salome mesh uses hexahedral linear order elements; in SfePy notation these are called 3_8, see User’s Guide.
Just keep the lines
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
Boundary condition specifications
In this section, we tell SfePy to fix the top and bottom parts of the “head” of the fish and move the tail 10 units to the
side (z direction).
Change the lines
ebcs = {
’Fixed’ : (’Left’, {’u.all’ : 0.0}),
’Displaced’ : (’Right’, {’u.0’ : 0.01, ’u.[1,2]’ : 0.0}),
’PerturbedSurface’ : (’SomewhereTop’, {’u.2’ : 0.005}),
}
to
ebcs = {
’TopFixed’ : (’TopFixed’, {’u.all’ : 0.0}),
’BotFixed’ : (’BotFixed’, {’u.all’ : 0.0}),
’Displaced’ : (’Tail’, {’u.2’ : 10, ’u.[0,1]’ : 0.0}),
}
5.2.6 Step 5: Run SfePy
Save your changes to linear_elastic.py. Now it’s time to run the SfePy calculation. In your <work_dir> in
your terminal type:
./simple.py linear_elastic.py
This will run the SfePy calculation. Some progress information is printed to your screen and the residual (a measure
of the convergence of the solution) is printed for each iteration of the solver. The solver terminates when this residual
74
Chapter 5. Examples
SfePy Documentation, Release 2015.1
is less than a certain value. It should only take 1 iteration since we are solving a linear problem. The results will be
saved to Mesh_Partition_Hexa.vtk.
Now we can view the results of our work. In your terminal, type:
./postproc.py --wireframe --vector-mode=warp_norm -s 2 Mesh_Partition_Hexa.vtk
You should get the following plot. The undeformed mesh is displayed with a wireframe for comparison. Notice how
the fish is bending its tail in response to the applied displacement.
Now you should be able to use meshes created in Salome with SfePy!
5.3 Examples
5.3.1 acoustics
acoustics/acoustics.py
Description
Acoustic pressure distribution.
This example shows how to solve a problem in complex numbers, note the ‘accoustic_pressure’ field definition.
Find 𝑝 such that:
2
∫︁
∇𝑞 · ∇𝑝 − 𝑤
𝑐
Ω
5.3. Examples
2
∫︁
∫︁
𝑞𝑝 − 𝑖𝑤𝑐
Ω
2
∫︁
𝑞𝑝 = 𝑖𝑤𝑐 𝜌𝑣𝑛
Γ𝑜𝑢𝑡
𝑞,
∀𝑞 .
Γ𝑖𝑛
75
SfePy Documentation, Release 2015.1
source code
r"""
Acoustic pressure distribution.
This example shows how to solve a problem in complex numbers, note the
’accoustic_pressure’ field definition.
Find :math:‘p‘ such that:
.. math::
c^2 \int_{\Omega} \nabla q \cdot \nabla p
- w^2 \int_{\Omega} q p
- i w c \int_{\Gamma_{out}} q p
= i w c^2 \rho v_n \int_{\Gamma_{in}} q
\;, \quad \forall q \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/2d/special/two_rectangles.mesh’
v_n
w =
c =
rho
= 1.0 # m/s
1000.0
343.0 # m/s
= 1.55 # kg/m^3
options = {
76
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’nls’ : ’newton’,
’ls’ : ’ls’,
}
materials = {
’one’ : ({’one’ : 1.0},),
}
regions = {
’Omega’ : ’all’,
’Gamma_in’ : (’vertices in (x < 0.01)’, ’facet’),
’Gamma_out’ : (’vertices in (x > 0.99)’, ’facet’),
}
fields = {
’accoustic_pressure’ : (’complex’, 1, ’Omega’, 1),
}
variables = {
’p’
: (’unknown field’, ’accoustic_pressure’, 0),
’q’
: (’test field’,
’accoustic_pressure’, ’p’),
}
ebcs = {
}
integrals = {
’i’ : 2,
}
equations = {
’Acoustic pressure’ :
"""%s * dw_laplace.i.Omega( one.one, q, p )
- %s * dw_volume_dot.i.Omega( q, p )
- %s * dw_surface_dot.i.Gamma_out( q, p )
= %s * dw_surface_integrate.i.Gamma_in( q )"""
% (c*c, w*w, 1j*w*c, 1j*w*c*c*rho*v_n)
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-1,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-1, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
})
}
5.3. Examples
77
SfePy Documentation, Release 2015.1
acoustics/acoustics3d.py
Description
Acoustic pressure distribution in 3D.
Two Laplace equations, one in Ω1 , other in Ω2 , connected on the interface region Γ12 using traces of variables.
Find two complex acoustic pressures 𝑝1 , 𝑝2 such that:
∫︁
∫︁
𝑘 2 𝑞𝑝 −
∇𝑞 · ∇𝑝
Ω
∫︁
∫︁
∫︁ Ω
−𝑖𝑤/𝑐
𝑞𝑝 + 𝑖𝑤𝜌/𝑍
𝑞(𝑝2 − 𝑝1 ) + 𝑖𝑤𝜌/𝑍
𝑞(𝑝1 − 𝑝2 )
Γ𝑜𝑢𝑡
Γ2
Γ
∫︁ 1
= 𝑖𝑤𝜌
𝑣𝑛 𝑞 , ∀𝑞 .
Γ𝑖𝑛
78
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Acoustic pressure distribution in 3D.
Two Laplace equations, one in :math:‘\Omega_1‘, other in
:math:‘\Omega_2‘, connected on the interface region :math:‘\Gamma_{12}‘
using traces of variables.
Find two complex acoustic pressures :math:‘p_1‘, :math:‘p_2‘ such that:
.. math::
\int_{\Omega} k^2 q p - \int_{\Omega} \nabla q \cdot \nabla p \\
- i w/c \int_{\Gamma_{out}} q p
+ i w \rho/Z \int_{\Gamma_2} q (p_2 - p_1)
+ i w \rho/Z \int_{\Gamma_1} q (p_1 - p_2) \\
= i w \rho \int_{\Gamma_{in}} v_n q
\;, \quad \forall q \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/acoustics_mesh3d.mesh’
freq = 1200
v_n = 1.0 # m/s
c = 343.0 # m/s
5.3. Examples
79
SfePy Documentation, Release 2015.1
rho = 1.55 # kg/m^3
R = 1000
w = 2.0 * freq
k1 = w / c
rhoc1 = rho * c
coef_k = ((1.0
+ 1j
coef_r = ((1.0
+ 1j
+
*
+
*
0.1472 *
(-0.1734
0.0855 *
(-0.0765
(freq /
* (freq
(freq /
* (freq
R)**(-0.577))
/ R)**(-0.595)))
R)**(-0.754))
/ R)**(-0.732)))
k2 = k1 * coef_k
rhoc2 = rhoc1 * coef_r
# perforation geometry parameters
tw = 0.9e-3
dh = 2.49e-3
por = 0.08
# acoustic impedance
Z = rho * c / por * (0.006 + 1j * k1 * (tw + 0.375 * dh
* (1 + rhoc2/rhoc1 * k2/k1)))
regions = {
’Omega’ : ’all’,
’Omega_1’ : ’cells of group 1’,
’Omega_2’ : ’cells of group 2’,
’Gamma_12’ : (’r.Omega_1 *v r.Omega_2’, ’facet’),
’Gamma_12_1’ : (’copy r.Gamma_12’, ’facet’, ’Omega_1’),
’Gamma_12_2’ : (’copy r.Gamma_12’, ’facet’, ’Omega_2’),
’Gamma_in’ : (’vertices in (z < 0.001)’, ’facet’),
’Gamma_out’ : (’vertices in (z > 0.157)’, ’facet’),
}
materials = {
}
fields = {
’accoustic_pressure_1’ : (’complex’, ’scalar’, ’Omega_1’, 1),
’accoustic_pressure_2’ : (’complex’, ’scalar’, ’Omega_2’, 1),
}
variables = {
’p_1’
: (’unknown field’,
’q_1’
: (’test field’,
’p_2’
: (’unknown field’,
’q_2’
: (’test field’,
}
’accoustic_pressure_1’),
’accoustic_pressure_1’, ’p_1’),
’accoustic_pressure_2’),
’accoustic_pressure_2’, ’p_2’),
ebcs = {
}
integrals = {
’i’ : 2,
}
equations = {
80
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’Acoustic pressure’ :
"""%s * dw_volume_dot.i.Omega_1(q_1, p_1)
+ %s * dw_volume_dot.i.Omega_2(q_2, p_2)
- dw_laplace.i.Omega_1(q_1, p_1)
- dw_laplace.i.Omega_2(q_2, p_2)
- %s * dw_surface_dot.i.Gamma_out(q_1, p_1)
+ %s * dw_jump.i.Gamma_12_1(q_1, p_1, tr(p_2))
+ %s * dw_jump.i.Gamma_12_2(q_2, p_2, tr(p_1))
= %s * dw_surface_integrate.i.Gamma_in(q_1)"""
% (k1*k1, k2*k2,
1j*k1,
1j*k1*rhoc1 / Z, 1j*k2*rhoc2 / Z,
1j*k1*rhoc1 * v_n)
}
options = {
’nls’: ’newton’,
’ls’: ’ls’,
’file_per_var’: True,
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-1,
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
})
}
acoustics/vibro_acoustic3d.py
Description
Vibro-acoustic problem
3D acoustic domain with 2D perforated deforming interface.
Master problem: defined in 3D acoustic domain (vibro_acoustic3d.py)
Slave subproblem: 2D perforated interface (vibro_acoustic3d_mid.py)
Master 3D problem - find 𝑝 (acoustic pressure) and 𝑔 (transversal acoustic velocity) such that:
∫︁
∫︁
∫︁
∫︁
∫︁
∫︁
2
2
2
+
−
𝑐
∇𝑞 · ∇𝑝 − 𝜔
𝑞𝑝 + 𝑖𝜔𝑐
𝑞𝑝 + 𝑖𝜔𝑐
𝑞𝑝 − 𝑖𝜔𝑐
(𝑞 − 𝑞 )𝑔 = 2𝑖𝜔𝑐
𝑞 𝑝¯ ,
Ω
Ω
Γ𝑖𝑛
Γ𝑖𝑛
∫︁
∫︁ Γ𝑜𝑢𝑡
∫︁ Γ0
−𝑖𝜔
𝑓 (𝑝+ − 𝑝− ) − 𝜔 2
𝐹 𝑓 𝑔 + 𝜔2
𝐶𝑓 𝑤 = 0 , ∀𝑓 ,
Γ0
5.3. Examples
Γ0
∀𝑞 ,
Γ0
81
SfePy Documentation, Release 2015.1
Slave 2D subproblem - find 𝑤 (plate deflection) and 𝜃 (rotation) such that:
∫︁
∫︁
∫︁
∫︁
2
2
𝜔
𝐶𝑧𝑔 − 𝜔
𝑆𝑧𝑤 +
∇𝑧 · 𝐺 · ∇𝑤 −
𝜃 · 𝐺 · ∇𝑧 = 0 , ∀𝑧 ,
Γ0
Γ0
Γ0
∫︁
∫︁
∫︁
∫︁ Γ0
2
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝜈)𝑒𝑘𝑙 (𝜃) −
𝜈 · 𝐺 · ∇𝑤 +
𝜈 · 𝐺 · 𝜃 = 0 , ∀𝜈 ,
−𝜔
𝑅𝜈 ·𝜃 +
Γ0
82
Γ0
Γ0
Γ0
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.3. Examples
83
SfePy Documentation, Release 2015.1
84
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Vibro-acoustic problem
3D acoustic domain with 2D perforated deforming interface.
*Master problem*: defined in 3D acoustic domain (‘‘vibro_acoustic3d.py‘‘)
*Slave subproblem*: 2D perforated interface (‘‘vibro_acoustic3d_mid.py‘‘)
Master 3D problem - find :math:‘p‘ (acoustic pressure)
and :math:‘g‘ (transversal acoustic velocity) such that:
.. math::
c^2 \int_{\Omega} \nabla q \cdot \nabla p
- \omega^2 \int_{\Omega} q p
+ i \omega c \int_{\Gamma_{in}} q p
+ i \omega c \int_{\Gamma_{out}} q p
- i \omega c^2 \int_{\Gamma_0} (q^+ - q^-) g
= 2i \omega c \int_{\Gamma_{in}} q \bar{p}
\;, \quad \forall q \;,
+
=
i \omega \int_{\Gamma_0} f (p^+ - p^-)
\omega^2 \int_{\Gamma_0} F f g
\omega^2 \int_{\Gamma_0} C f w
0
5.3. Examples
85
SfePy Documentation, Release 2015.1
\;, \quad \forall f \;,
Slave 2D subproblem - find :math:‘w‘ (plate deflection)
and :math:‘\ul{\theta}‘ (rotation) such that:
.. math::
\omega^2 \int_{\Gamma_0} C z g
- \omega^2 \int_{\Gamma_0} S z w
+ \int_{\Gamma_0} \nabla z \cdot \ull{G} \cdot \nabla w
- \int_{\Gamma_0} \ul{\theta} \cdot \ull{G} \cdot \nabla z
= 0
\;, \quad \forall z \;,
- \omega^2 \int_{\Gamma_0}
+ \int_{\Gamma_0} D_{ijkl}
- \int_{\Gamma_0} \ul{\nu}
+ \int_{\Gamma_0} \ul{\nu}
= 0
\;, \quad \forall \ul{\nu}
R\, \ul{\nu} \cdot \ul{\theta}
e_{ij}(\ul{\nu}) e_{kl}(\ul{\theta})
\cdot \ull{G} \cdot \nabla w
\cdot \ull{G} \cdot \ul{\theta}
\;,
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/acoustic_wg.vtk’
sound_speed = 343.0
wave_num = 5.5
p_inc = 300
c = sound_speed
c2 = c**2
w = wave_num * c
w2 = w**2
wc = w * c
wc2 = w * c2
regions = {
’Omega1’: ’cells of group 1’,
’Omega2’: ’cells of group 2’,
’GammaIn’: (’vertices of group 1’, ’face’),
’GammaOut’: (’vertices of group 2’, ’face’),
’Gamma_aux’: (’r.Omega1 *v r.Omega2’, ’face’),
’Gamma0_1’: (’copy r.Gamma_aux’, ’face’, ’Omega1’),
’Gamma0_2’: (’copy r.Gamma_aux’, ’face’, ’Omega2’),
’aux_Left’: (’vertices in (x < 0.001)’, ’face’),
’aux_Right’: (’vertices in (x > 0.299)’, ’face’),
’Gamma0_1_Left’: (’r.Gamma0_1 *v r.aux_Left’, ’edge’),
’Gamma0_1_Right’: (’r.Gamma0_1 *v r.aux_Right’, ’edge’),
}
fields = {
’pressure1’: (’complex’, ’scalar’, ’Omega1’, 1),
’pressure2’: (’complex’, ’scalar’, ’Omega2’, 1),
’tvelocity’: (’complex’, ’scalar’, ’Gamma0_1’, 1),
’deflection’: (’complex’, ’scalar’, ’Gamma0_1’, 1),
}
variables = {
’p1’: (’unknown field’, ’pressure1’, 0),
’q1’: (’test field’, ’pressure1’, ’p1’),
86
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’p2’: (’unknown field’, ’pressure2’, 1),
’q2’: (’test field’, ’pressure2’, ’p2’),
’g0’: (’unknown field’, ’tvelocity’, 2),
’f0’: (’test field’, ’tvelocity’, ’g0’),
’w’: (’unknown field’, ’deflection’, 3),
’z’: (’test field’, ’deflection’, ’w’),
}
ebcs = {
’fixed_l’: (’Gamma0_1_Left’, {’w.0’: 0.0}),
’fixed_r’: (’Gamma0_1_Right’, {’w.0’: 0.0}),
}
options = {
’file_per_var’: True,
}
functions = {
}
materials = {
’ac’ : ({’F’: -2.064e+00, ’c’: -1.064e+00}, ),
}
equations = {
’eq_1’ : """
%e * dw_laplace.5.Omega1(q1, p1)
+ %e * dw_laplace.5.Omega2(q2, p2)
- %e * dw_volume_dot.5.Omega1(q1, p1)
- %e * dw_volume_dot.5.Omega2(q2, p2)
+ %s * dw_surface_dot.5.GammaIn(q1, p1)
+ %s * dw_surface_dot.5.GammaOut(q2, p2)
- %s * dw_surface_dot.5.Gamma0_1(q1, g0)
+ %s * dw_surface_dot.5.Gamma0_2(q2, tr(g0))
= %s * dw_surface_integrate.5.GammaIn(q1)"""\
% (c2, c2, w2, w2,
1j * wc, 1j * wc,
1j * wc2, 1j * wc2,
2j * wc * p_inc),
’eq_2’ : """
- %s * dw_surface_dot.5.Gamma0_1(f0, p1)
+ %s * dw_surface_dot.5.Gamma0_1(f0, tr(p2))
- %e * dw_surface_dot.5.Gamma0_1(ac.F, f0, g0)
+ %e * dw_surface_dot.5.Gamma0_1(ac.c, f0, w)
= 0"""\
% (1j * w, 1j * w, w2, w2),
}
solvers = {
’ls’: (’ls.cm_pb’,
{’others’: [data_dir
+ ’/examples/acoustics/vibro_acoustic3d_mid.py’],
’coupling_variables’: [’g0’, ’w’],
}),
’nls’: (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-6,
’eps_r’ : 1e-6,
5.3. Examples
87
SfePy Documentation, Release 2015.1
})
}
5.3.2 biot
biot/biot.py
Description
Biot problem - deformable porous medium.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) −
𝑝 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) = 0 , ∀𝑣 ,
Ω
Ω
∫︁
∫︁
𝑞 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑢) +
𝐾𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 = 0 , ∀𝑞 ,
Ω
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
88
Chapter 5. Examples
SfePy Documentation, Release 2015.1
r"""
Biot problem - deformable porous medium.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} p\ \alpha_{ij} e_{ij}(\ul{v})
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \alpha_{ij} e_{ij}(\ul{u})
+ \int_{\Omega} K_{ij} \nabla_i q \nabla_j p
= 0
\;, \quad \forall q \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
import numpy as nm
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cube_medium_hexa.mesh’
regions = {
’Omega’ : ’all’,
’Bottom’ : (’vertices in (z < -0.4999999)’, ’facet’),
’Top’ : (’vertices in (z > 0.4999999)’, ’facet’),
’Left’ : (’vertices in (x < -0.4999999)’, ’facet’),
}
field_1 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : (3,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
field_2 = {
’name’ : ’pressure’,
’dtype’ : nm.float64,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
variables = {
’u’
: (’unknown field’,
’v’
: (’test field’,
’p’
: (’unknown field’,
’q’
: (’test field’,
}
5.3. Examples
’displacement’, 0),
’displacement’, ’u’),
’pressure’, 1),
’pressure’, ’p’),
89
SfePy Documentation, Release 2015.1
ebcs = {
’fix_u’ : (’Bottom’, {’u.all’ : 0.0}),
’load_u’ : (’Top’, {’u.2’ : 0.2}),
’load_p’ : (’Left’, {’p.all’ : 1.0}),
}
material_1 = {
’name’ : ’m’,
’values’ : {
’lam’ : 1.7,
’mu’ : 0.3,
’alpha’ : nm.array( [[0.132], [0.132], [0.132],
[0.092], [0.092], [0.092]],
dtype = nm.float64 ),
’K’ : nm.array( [[2.0, 0.2, 0.0], [0.2, 1.0, 0.0], [0.0, 0.0, 0.5]],
dtype = nm.float64 ),
}
}
integral_1 = {
’name’ : ’i1’,
’order’ : 1,
}
integral_2 = {
’name’ : ’i2’,
’order’ : 2,
}
equations = {
’eq_1’ :
"""dw_lin_elastic_iso.i2.Omega( m.lam, m.mu, v, u )
- dw_biot.i1.Omega( m.alpha, v, p )
= 0""",
’eq_2’ :
"""dw_biot.i1.Omega( m.alpha, u, q ) + dw_diffusion.i1.Omega( m.K, q, p )
= 0""",
}
solver_0 = {
’name’ : ’ls_d’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
90
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’delta’
: 1e-6,
}
biot/biot_npbc.py
Description
Biot problem - deformable porous medium with the no-penetration boundary condition on a boundary region.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) −
𝑝 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) = 0 , ∀𝑣 ,
Ω
Ω
∫︁
∫︁
𝑞 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑢) +
𝐾𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 = 0 , ∀𝑞 ,
Ω
Ω
𝑢 · 𝑛 = 0 on Γ𝑤𝑎𝑙𝑙𝑠 ,
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
r"""
Biot problem - deformable porous medium with the no-penetration boundary
condition on a boundary region.
5.3. Examples
91
SfePy Documentation, Release 2015.1
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} p\ \alpha_{ij} e_{ij}(\ul{v})
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \alpha_{ij} e_{ij}(\ul{u})
+ \int_{\Omega} K_{ij} \nabla_i q \nabla_j p
= 0
\;, \quad \forall q \;,
\ul{u} \cdot \ul{n} = 0 \mbox{ on } \Gamma_{walls} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
import os
import numpy as nm
from sfepy.linalg import get_coors_in_tube
from sfepy.mechanics.matcoefs import stiffness_from_lame
def define():
from sfepy import data_dir
filename = data_dir + ’/meshes/3d/cylinder.mesh’
output_dir = ’output’
return define_input(filename, output_dir)
def cinc_simple(coors, mode):
axis = nm.array([1, 0, 0], nm.float64)
if mode == 0: # In
centre = nm.array([0.0, 0.0, 0.0], nm.float64)
radius = 0.019
length = 0.00002
elif mode == 1: # Out
centre = nm.array([0.1, 0.0, 0.0], nm.float64)
radius = 0.019
length = 0.00002
elif mode == 2: # Rigid
centre = nm.array([0.05, 0.0, 0.0], nm.float64)
radius = 0.015
length = 0.03
else:
raise ValueError(’unknown mode %s!’ % mode)
return get_coors_in_tube(coors,
centre, axis, -1, radius, length)
def define_regions(filename):
if filename.find(’simple.mesh’):
dim = 3
92
Chapter 5. Examples
SfePy Documentation, Release 2015.1
regions = {
’Omega’ : ’all’,
’Walls’ : (’vertices of surface -v (r.Outlet +f r.Inlet)’, ’facet’),
’Inlet’ : (’vertices by cinc_simple0’, ’facet’),
’Outlet’ : (’vertices by cinc_simple1’, ’facet’),
’Rigid’ : ’vertices by cinc_simple2’,
}
else:
raise ValueError(’unknown mesh %s!’ % filename)
return regions, dim
def get_pars(ts, coor, mode, output_dir=’.’, **kwargs):
if mode == ’qp’:
n_nod, dim = coor.shape
sym = (dim + 1) * dim / 2
out = {}
out[’D’] = nm.tile(stiffness_from_lame(dim, lam=1.7, mu=0.3),
(coor.shape[0], 1, 1))
aa = nm.zeros((sym, 1), dtype=nm.float64)
aa[:dim] = 0.132
aa[dim:sym] = 0.092
out[’alpha’] = nm.tile(aa, (coor.shape[0], 1, 1))
perm = nm.eye(dim, dtype=nm.float64)
out[’K’] = nm.tile(perm, (coor.shape[0], 1, 1))
return out
def post_process(out, pb, state, extend=False):
from sfepy.base.base import Struct
dvel = pb.evaluate(’ev_diffusion_velocity.i.Omega( m.K, p )’,
mode=’el_avg’)
out[’dvel’] = Struct(name=’output_data’,
mode=’cell’, data=dvel, dofs=None)
stress = pb.evaluate(’ev_cauchy_stress.i.Omega( m.D, u )’,
mode=’el_avg’)
out[’cauchy_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
return out
def define_input(filename, output_dir):
filename_mesh = filename
options = {
’output_dir’ : output_dir,
’output_format’ : ’vtk’,
’post_process_hook’ : ’post_process’,
’ls’ : ’ls’,
’nls’ : ’newton’,
}
5.3. Examples
93
SfePy Documentation, Release 2015.1
functions = {
’cinc_simple0’ : (lambda coors, domain:
cinc_simple(coors, 0),),
’cinc_simple1’ : (lambda coors, domain:
cinc_simple(coors, 1),),
’cinc_simple2’ : (lambda coors, domain:
cinc_simple(coors, 2),),
’get_pars’ : (lambda ts, coors, mode=None, **kwargs:
get_pars(ts, coors, mode,
output_dir=output_dir, **kwargs),),
}
regions, dim = define_regions(filename_mesh)
field_1 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : dim,
’region’ : ’Omega’,
’approx_order’ : 1,
}
field_2 = {
’name’ : ’pressure’,
’dtype’ : nm.float64,
’shape’ : 1,
’region’ : ’Omega’,
’approx_order’ : 1,
}
variables = {
’u’
: (’unknown field’,
’v’
: (’test field’,
’p’
: (’unknown field’,
’q’
: (’test field’,
}
’displacement’, 0),
’displacement’, ’u’),
’pressure’, 1),
’pressure’, ’p’),
ebcs = {
’inlet’ : (’Inlet’, {’p.0’ : 1.0, ’u.all’ : 0.0}),
’outlet’ : (’Outlet’, {’p.0’ : -1.0}),
}
lcbcs = {
’rigid’ : (’Outlet’, {’u.all’ : None}, None, ’rigid’),
’no_penetration’ : (’Walls’, {’u.all’ : None}, None,
’no_penetration’, None),
}
material_1 = {
’name’ : ’m’,
’function’ : ’get_pars’,
}
integral_1 = {
’name’ : ’i’,
’order’ : 2,
}
equations = {
’eq_1’ :
94
Chapter 5. Examples
SfePy Documentation, Release 2015.1
"""dw_lin_elastic.i.Omega( m.D, v, u )
- dw_biot.i.Omega( m.alpha, v, p )
= 0""",
’eq_2’ :
"""dw_biot.i.Omega( m.alpha, u, q )
+ dw_diffusion.i.Omega( m.K, q, p )
= 0""",
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’, # Direct solver.
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
}
return locals()
biot/biot_npbc_lagrange.py
Description
Biot problem - deformable porous medium with the no-penetration boundary condition on a boundary region enforced
using Lagrange multipliers.
The non-penetration condition is enforced weakly using the Lagrange multiplier 𝜆. There is also a rigid body movement constraint imposed on the Γ𝑜𝑢𝑡𝑙𝑒𝑡 region using the linear combination boundary conditions.
Find 𝑢, 𝑝 and 𝜆 such that:
∫︁
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) −
𝑝 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) +
𝜆𝑛 · 𝑣 = 0 ,
Ω
Ω
Γ𝑤𝑎𝑙𝑙𝑠
∫︁
∫︁
𝑞 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑢) +
𝐾𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 = 0 , ∀𝑞 ,
Ω
Ω
∫︁
ˆ · 𝑢 = 0 , ∀𝜆
ˆ,
𝜆𝑛
∀𝑣 ,
Γ𝑤𝑎𝑙𝑙𝑠
𝑢 · 𝑛 = 0 on Γ𝑤𝑎𝑙𝑙𝑠 ,
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
5.3. Examples
95
SfePy Documentation, Release 2015.1
source code
r"""
Biot problem - deformable porous medium with the no-penetration boundary
condition on a boundary region enforced using Lagrange multipliers.
The non-penetration condition is enforced weakly using the Lagrange
multiplier :math:‘\lambda‘. There is also a rigid body movement
constraint imposed on the :math:‘\Gamma_{outlet}‘ region using the
linear combination boundary conditions.
Find :math:‘\ul{u}‘, :math:‘p‘ and :math:‘\lambda‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} p\ \alpha_{ij} e_{ij}(\ul{v})
+ \int_{\Gamma_{walls}} \lambda \ul{n} \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \alpha_{ij} e_{ij}(\ul{u})
+ \int_{\Omega} K_{ij} \nabla_i q \nabla_j p
= 0
\;, \quad \forall q \;,
\int_{\Gamma_{walls}} \hat\lambda \ul{n} \cdot \ul{u}
= 0
96
Chapter 5. Examples
SfePy Documentation, Release 2015.1
\;, \quad \forall \hat\lambda \;,
\ul{u} \cdot \ul{n} = 0 \mbox{ on } \Gamma_{walls} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from biot_npbc import cinc_simple, define_regions, get_pars
def define():
from sfepy import data_dir
filename = data_dir + ’/meshes/3d/cylinder.mesh’
output_dir = ’output’
return define_input(filename, output_dir)
def post_process(out, pb, state, extend=False):
from sfepy.base.base import Struct
dvel = pb.evaluate(’ev_diffusion_velocity.2.Omega( m.K, p )’,
mode=’el_avg’)
out[’dvel’] = Struct(name=’output_data’, var_name=’p’,
mode=’cell’, data=dvel, dofs=None)
stress = pb.evaluate(’ev_cauchy_stress.2.Omega( m.D, u )’,
mode=’el_avg’)
out[’cauchy_stress’] = Struct(name=’output_data’, var_name=’u’,
mode=’cell’, data=stress, dofs=None)
return out
def define_input(filename, output_dir):
filename_mesh = filename
options = {
’output_dir’ : output_dir,
’output_format’ : ’vtk’,
’post_process_hook’ : ’post_process’,
## ’file_per_var’ : True,
’ls’ : ’ls’,
’nls’ : ’newton’,
}
functions = {
’cinc_simple0’ : (lambda coors, domain:
cinc_simple(coors, 0),),
’cinc_simple1’ : (lambda coors, domain:
cinc_simple(coors, 1),),
’cinc_simple2’ : (lambda coors, domain:
cinc_simple(coors, 2),),
’get_pars’ : (lambda ts, coors, mode=None, **kwargs:
get_pars(ts, coors, mode,
output_dir=output_dir, **kwargs),),
}
5.3. Examples
97
SfePy Documentation, Release 2015.1
regions, dim = define_regions(filename_mesh)
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
’pressure’: (’real’, ’scalar’, ’Omega’, 1),
’multiplier’: (’real’, ’scalar’, ’Walls’, 1),
}
variables = {
’u’ : (’unknown field’,
’v’ : (’test field’,
’p’ : (’unknown field’,
’q’ : (’test field’,
’ul’ : (’unknown field’,
’vl’ : (’test field’,
}
’displacement’, 0),
’displacement’, ’u’),
’pressure’, 1),
’pressure’, ’p’),
’multiplier’, 2),
’multiplier’, ’ul’),
ebcs = {
’inlet’ : (’Inlet’, {’p.0’ : 1.0, ’u.all’ : 0.0}),
’outlet’ : (’Outlet’, {’p.0’ : -1.0}),
}
lcbcs = {
’rigid’ : (’Outlet’, {’u.all’ : None}, None, ’rigid’),
}
materials = {
’m’ : ’get_pars’,
}
equations = {
’eq_1’ :
"""dw_lin_elastic.2.Omega( m.D, v, u )
- dw_biot.2.Omega( m.alpha, v, p )
+ dw_non_penetration.2.Walls( v, ul )
= 0""",
’eq_2’ :
"""dw_biot.2.Omega( m.alpha, u, q )
+ dw_diffusion.2.Omega( m.K, q, p )
= 0""",
’eq_3’ :
"""dw_non_penetration.2.Walls( u, vl )
= 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {}),
}
return locals()
98
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.3.3 diffusion
diffusion/cube.py
Description
Laplace equation (e.g. temperature distribution) on a cube geometry with different boundary condition values on the
cube sides. This example was used to create the SfePy logo.
Find 𝑇 such that:
∫︁
𝑐∇𝑠 · ∇𝑇 = 0 ,
∀𝑠 .
Ω
source code
r"""
Laplace equation (e.g. temperature distribution) on a cube geometry with
different boundary condition values on the cube sides. This example was
used to create the SfePy logo.
Find :math:‘T‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla T
= 0
\;, \quad \forall s \;.
"""
5.3. Examples
99
SfePy Documentation, Release 2015.1
from sfepy import data_dir
#filename_mesh = data_dir + ’/meshes/3d/cube_big_tetra.mesh’
filename_mesh = data_dir + ’/meshes/3d/cube_medium_hexa.mesh’
############# Laplace.
material_1 = {
’name’ : ’coef’,
’values’ : {’val’ : 1.0},
}
field_1 = {
’name’ : ’temperature’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
if filename_mesh.find(’cube_medium_hexa.mesh’) >= 0:
region_1000 = {
’name’ : ’Omega’,
’select’ : ’cells of group 0’,
}
integral_1 = {
’name’ : ’i’,
’order’ : 1,
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
elif filename_mesh.find(’cube_big_tetra.mesh’) >= 0:
region_1000 = {
’name’ : ’Omega’,
’select’ : ’cells of group 6’,
}
integral_1 = {
’name’ : ’i’,
’quadrature’ : ’custom’,
’vals’
: [[1./3., 1./3., 1./3.]],
’weights’ : [0.5]
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_iterative’,
’method’ : ’cg’,
’i_max’
: 1000,
’eps_r’
: 1e-12,
}
variable_1 = {
’name’ : ’T’,
’kind’ : ’unknown field’,
’field’ : ’temperature’,
100
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’order’ : 0, # order in the global vector of unknowns
}
variable_2 = {
’name’ : ’s’,
’kind’ : ’test field’,
’field’ : ’temperature’,
’dual’ : ’T’,
}
region_0 = {
’name’ : ’Surface’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_1 = {
’name’ : ’Bottom’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_2 = {
’name’ : ’Top’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_03 = {
’name’ : ’Left’,
’select’ : ’vertices
’kind’ : ’facet’,
}
ebc_1 = {
’name’ :
’region’
’dofs’ :
}
ebc_4 = {
’name’ :
’region’
’dofs’ :
}
ebc_3 = {
’name’ :
’region’
’dofs’ :
}
ebc_2 = {
’name’ :
’region’
’dofs’ :
}
of surface’,
in (z < -0.4999999)’,
in (z > 0.4999999)’,
in (x < -0.4999999)’,
’T0’,
: ’Surface’,
{’T.0’ : -3.0},
’T1’,
: ’Top’,
{’T.0’ : 1.0},
’T2’,
: ’Bottom’,
{’T.0’ : -1.0},
’T3’,
: ’Left’,
{’T.0’ : 2.0},
equations = {
’nice_equation’ : """dw_laplace.i.Omega( coef.val, s, T ) = 0""",
}
solver_1 = {
’name’ : ’newton’,
5.3. Examples
101
SfePy Documentation, Release 2015.1
’kind’ : ’nls.newton’,
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
}
diffusion/laplace_1d.py
Description
Laplace equation in 1D with a variable coefficient.
Because the mesh is trivial in 1D, it is generated by mesh_hook(), and registered using UserMeshIO.
Find 𝑡 such that:
∫︁
𝑐(𝑥)
Ω
d𝑠 d𝑡
=0,
d𝑥 d𝑥
∀𝑠 ,
where the coefficient 𝑐(𝑥) = 0.1 + sin(2𝜋𝑥)2 is computed in get_coef().
View the results using:
$ ./postproc.py -b -d’t,plot_warp_scalar,rel_scaling=1’ --wireframe --view=-90,90,1.5,0,0,0 --roll=0
102
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Laplace equation in 1D with a variable coefficient.
Because the mesh is trivial in 1D, it is generated by :func:‘mesh_hook()‘, and
registered using :class:‘UserMeshIO <sfepy.discrete.fem.meshio.UserMeshIO>‘.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c(x) \tdiff{s}{x} \tdiff{t}{x}
= 0
\;, \quad \forall s \;,
where the coefficient :math:‘c(x) = 0.1 + \sin(2 \pi x)^2‘ is computed in
:func:‘get_coef()‘.
View the results using::
$ ./postproc.py -b -d’t,plot_warp_scalar,rel_scaling=1’ --wireframe --view=-90,90,1.5,0,0,0 --roll=
"""
import numpy as nm
from sfepy.discrete.fem import Mesh
from sfepy.discrete.fem.meshio import UserMeshIO
def mesh_hook(mesh, mode):
5.3. Examples
103
SfePy Documentation, Release 2015.1
"""
Generate the 1D mesh.
"""
if mode == ’read’:
n_nod = 101
coors = nm.linspace(0.0, 1.0, n_nod).reshape((n_nod, 1))
conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2))
mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32)
descs = [’1_2’] * n_nod
mesh = Mesh.from_data(’laplace_1d’, coors, None,
[conn], [mat_ids], descs)
return mesh
elif mode == ’write’:
pass
def get_coef(ts, coors, mode=None, **kwargs):
if mode == ’qp’:
x = coors[:, 0]
val = 0.1 + nm.sin(2 * nm.pi * x)**2
val.shape = (coors.shape[0], 1, 1)
return {’val’ : val}
filename_mesh = UserMeshIO(mesh_hook)
materials = {
’coef’ : ’get_coef’,
}
functions = {
’get_coef’ : (get_coef,),
}
regions = {
’Omega’ : ’all’,
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.99999)’, ’facet’),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’t’),
}
ebcs = {
’t1’ : (’Gamma_Left’, {’t.0’ : 0.3}),
’t2’ : (’Gamma_Right’, {’t.0’ : -0.3}),
}
integrals = {
104
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’i’ : 2,
}
equations = {
’Temperature’ : """dw_laplace.i.Omega(coef.val, s, t) = 0"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
diffusion/laplace_coupling_lcbcs.py
Description
Two Laplace equations with multiple linear combination constraints.
The two equations are coupled by a periodic-like boundary condition constraint with a shift, given as a nonhomogeneous linear combination boundary condition.
Find 𝑢 such that:
∫︁
∇𝑣1 · ∇𝑢1 = 0 ,
∀𝑣1 ,
∇𝑣2 · ∇𝑢2 = 0 ,
∀𝑣2 ,
∫︁Ω1
Ω2
𝑢1 = 0 on Γ𝑏𝑜𝑡𝑡𝑜𝑚 ,
𝑢2 = 1 on Γ𝑡𝑜𝑝 ,
¯1 ∩ Ω
¯2
𝑢1 (𝑥) = 𝑢2 (𝑥) + 𝑎(𝑥) for 𝑥 ∈ Γ = Ω
𝑢1 (𝑥) = 𝑢1 (𝑦) + 𝑏(𝑦) for 𝑥 ∈ Γ𝑙𝑒𝑓 𝑡 , 𝑦 ∈ Γ𝑟𝑖𝑔ℎ𝑡 , 𝑦 = 𝑃 (𝑥) ,
𝑢1 = 𝑐11 in Ω𝑚11 ⊂ Ω1 ,
𝑢1 = 𝑐12 in Ω𝑚12 ⊂ Ω1 ,
𝑢2 = 𝑐2 in Ω𝑚2 ⊂ Ω2 ,
where 𝑎(𝑥), 𝑏(𝑦) are given functions (shifts), 𝑃 is the periodic coordinate mapping and 𝑐11 , 𝑐12 and 𝑐2 are unknown
constant values - the unknown DOFs in Ω𝑚11 , Ω𝑚12 and Ω𝑚2 are replaced by the integral mean values.
View the results using:
$ ./postproc.py square_quad.vtk -b --wireframe -d’u1,plot_warp_scalar,rel_scaling=1:u2,plot_warp_scal
5.3. Examples
105
SfePy Documentation, Release 2015.1
source code
r"""
Two Laplace equations with multiple linear combination constraints.
The two equations are coupled by a periodic-like boundary condition constraint
with a shift, given as a non-homogeneous linear combination boundary condition.
Find :math:‘u‘ such that:
.. math::
\int_{\Omega_1} \nabla v_1 \cdot \nabla u_1
= 0
\;, \quad \forall v_1 \;,
\int_{\Omega_2} \nabla v_2 \cdot \nabla u_2
= 0
\;, \quad \forall v_2 \;,
u_1 = 0 \mbox{ on } \Gamma_{bottom} \;,
u_2 = 1 \mbox{ on } \Gamma_{top} \;,
u_1(\ul{x}) = u_2(\ul{x}) + a(\ul{x}) \mbox{ for }
\ul{x} \in \Gamma = \bar\Omega_1 \cap \bar\Omega_2
u_1(\ul{x}) = u_1(\ul{y}) + b(\ul{y}) \mbox{ for }
106
Chapter 5. Examples
SfePy Documentation, Release 2015.1
\ul{x} \in \Gamma_{left}, \ul{y} \in \Gamma_{right}, \ul{y} = P(\ul{x}) \;,
u_1 = c_{11} \mbox{ in } \Omega_{m11} \subset \Omega_1 \;,
u_1 = c_{12} \mbox{ in } \Omega_{m12} \subset \Omega_1 \;,
u_2 = c_2 \mbox{ in } \Omega_{m2} \subset \Omega_2 \;,
where :math:‘a(\ul{x})‘, :math:‘b(\ul{y})‘ are given functions (shifts),
:math:‘P‘ is the periodic coordinate mapping and :math:‘c_{11}‘, :math:‘c_{12}‘
and :math:‘c_2‘ are unknown constant values - the unknown DOFs in
:math:‘\Omega_{m11}‘, :math:‘\Omega_{m12}‘ and :math:‘\Omega_{m2}‘ are replaced
by the integral mean values.
View the results using::
$ ./postproc.py square_quad.vtk -b --wireframe -d’u1,plot_warp_scalar,rel_scaling=1:u2,plot_warp_sc
"""
import numpy as nm
import sfepy.discrete.fem.periodic as per
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/2d/square_quad.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
def get_shift1(ts, coors, region):
val = 0.1 * coors[:, 0]
return val
def get_shift2(ts, coors, region):
val = nm.empty_like(coors[:, 1])
val.fill(0.3)
return val
functions = {
’get_shift1’ :
’get_shift2’ :
’match_y_line’
’match_x_line’
}
(get_shift1,),
(get_shift2,),
: (per.match_y_line,),
: (per.match_x_line,),
fields = {
’scalar1’: (’real’, 1, ’Omega1’, 1),
’scalar2’: (’real’, 1, ’Omega2’, 1),
}
materials = {
}
variables = {
’u1’ : (’unknown field’, ’scalar1’, 0),
5.3. Examples
107
SfePy Documentation, Release 2015.1
’v1’ : (’test field’, ’scalar1’, ’u1’),
’u2’ : (’unknown field’, ’scalar2’, 1),
’v2’ : (’test field’, ’scalar2’, ’u2’),
}
regions = {
’Omega1’ : ’cells of group 1’,
’Omega2’ : ’cells of group 2’,
’Omega_m1’ : ’r.Omega1 -v (r.Gamma +s vertices of surface)’,
’Omega_m11’ : ’r.Omega_m1 *v vertices in (x < 0)’,
’Omega_m12’ : ’r.Omega_m1 *v vertices in (x > 0)’,
’Omega_m2’ : ’r.Omega2 -v (r.Gamma +s vertices of surface)’,
’Left’ : (’vertices in (x < -0.499)’, ’facet’),
’Right’ : (’vertices in (x > 0.499)’, ’facet’),
’Bottom’ : (’vertices in ((y < -0.499))’, ’facet’),
’Top’ : (’vertices in ((y > 0.499))’, ’facet’),
’Gamma’ : (’r.Omega1 *v r.Omega2 -v vertices of surface’, ’facet’),
’Gamma1’ : (’copy r.Gamma’, ’facet’, ’Omega1’),
’Gamma2’ : (’copy r.Gamma’, ’facet’, ’Omega2’),
}
ebcs = {
’fix1’ : (’Top’, {’u2.all’ : 1.0}),
’fix2’ : (’Bottom’, {’u1.all’ : 0.0}),
}
lcbcs = {
’shifted1’ : ((’Gamma1’, ’Gamma2’),
{’u1.all’ : ’u2.all’},
’match_x_line’, ’shifted_periodic’,
’get_shift1’),
’shifted2’ : ((’Left’, ’Right’),
{’u1.all’ : ’u1.all’},
’match_y_line’, ’shifted_periodic’,
’get_shift2’),
’mean11’ : (’Omega_m11’, {’u1.all’ : None}, None, ’integral_mean_value’),
’mean12’ : (’Omega_m12’, {’u1.all’ : None}, None, ’integral_mean_value’),
’mean2’ : (’Omega_m2’, {’u2.all’ : None}, None, ’integral_mean_value’),
}
integrals = {
’i1’ : 2,
}
equations = {
’eq1’ : """
dw_laplace.i1.Omega1(v1, u1) = 0
""",
’eq2’ : """
dw_laplace.i1.Omega2(v2, u2) = 0
""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
108
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}),
}
diffusion/laplace_time_ebcs.py
Description
Example explaining how to change Dirichlet boundary conditions depending on time. It is shown on the stationary
Laplace equation for temperature, so there is no dynamics, only the conditions change with time.
Five time steps are solved on a cube domain, with the temperature fixed to zero on the bottom face, and set to other
values on the left, right and top faces in different time steps.
Find 𝑡 such that:
∫︁
𝑐∇𝑠 · ∇𝑡 = 0 ,
∀𝑠 .
Ω
source code
r"""
Example explaining how to change Dirichlet boundary conditions depending
on time. It is shown on the stationary Laplace equation for temperature,
so there is no dynamics, only the conditions change with time.
Five time steps are solved on a cube domain, with the temperature fixed
to zero on the bottom face, and set to other values on the left, right
5.3. Examples
109
SfePy Documentation, Release 2015.1
and top faces in different time steps.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= 0
\;, \quad \forall s \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cube_medium_tetra.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -0.499)’, ’facet’),
’Right’ : (’vertices in (x > 0.499)’, ’facet’),
’Bottom’ : (’vertices in (z < -0.499)’, ’facet’),
’Top’ : (’vertices in (z > 0.499)’, ’facet’),
}
materials = {
’one’ : ({’val’ : 1.0},),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’t’
: (’unknown field’, ’temperature’, 0),
’s’
: (’test field’,
’temperature’, ’t’),
}
ebcs = {
’fixed’ : (’Bottom’, {’t.all’ : 0}),
’t_t02’ : (’Left’, [(-0.5, 0.5), (2.5, 3.5)], {’t.all’ : 1.0}),
’t_t1’ : (’Right’, [(0.5, 1.5)], {’t.all’ : 2.0}),
’t_t4’ : (’Top’, ’is_ebc’, {’t.all’ : 3.0}),
}
def is_ebc(ts):
if ts.step in (2, 4):
return True
else:
return False
functions = {
’is_ebc’ : (is_ebc,),
}
110
Chapter 5. Examples
SfePy Documentation, Release 2015.1
equations = {
’eq’ : """dw_laplace.2.Omega( one.val, s, t ) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
’ts’ : (’ts.simple’, {
’t0’
: 0.0,
’t1’
: 4.0,
’dt’
: None,
’n_step’ : 5, # has precedence over dt!
’quasistatic’ : True,
}),
}
diffusion/poisson.py
Description
Laplace equation using the long syntax of keywords.
See the tutorial section Example problem description file for a detailed explanation.
sion/poisson_short_syntax.py for the short syntax version.
See diffu-
Find 𝑡 such that:
∫︁
𝑐∇𝑠 · ∇𝑡 = 0 ,
∀𝑠 .
Ω
5.3. Examples
111
SfePy Documentation, Release 2015.1
source code
r"""
Laplace equation using the long syntax of keywords.
See the tutorial section :ref:‘poisson-example-tutorial‘ for a detailed
explanation. See :ref:‘diffusion-poisson_short_syntax‘ for the short syntax
version.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= 0
\;, \quad \forall s \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
material_2 = {
’name’ : ’coef’,
’values’ : {’val’ : 1.0},
}
region_1000 = {
’name’ : ’Omega’,
112
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’select’ : ’cells of group 6’,
}
region_03 = {
’name’ : ’Gamma_Left’,
’select’ : ’vertices in (x < 0.00001)’,
’kind’ : ’facet’,
}
region_4 = {
’name’ : ’Gamma_Right’,
’select’ : ’vertices in (x > 0.099999)’,
’kind’ : ’facet’,
}
field_1 = {
’name’ : ’temperature’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
variable_1 = {
’name’ : ’t’,
’kind’ : ’unknown field’,
’field’ : ’temperature’,
’order’ : 0, # order in the global vector of unknowns
}
variable_2 = {
’name’ : ’s’,
’kind’ : ’test field’,
’field’ : ’temperature’,
’dual’ : ’t’,
}
ebc_1 = {
’name’ : ’t1’,
’region’ : ’Gamma_Left’,
’dofs’ : {’t.0’ : 2.0},
}
ebc_2 = {
’name’ : ’t2’,
’region’ : ’Gamma_Right’,
’dofs’ : {’t.0’ : -2.0},
}
integral_1 = {
’name’ : ’i’,
’order’ : 2,
}
equations = {
’Temperature’ : """dw_laplace.i.Omega( coef.val, s, t ) = 0"""
}
5.3. Examples
113
SfePy Documentation, Release 2015.1
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
’method’ : ’auto’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
diffusion/poisson_field_dependent_material.py
Description
Laplace equation with a field-dependent material parameter.
Find 𝑇 (𝑡) for 𝑡 ∈ [0, 𝑡final ] such that:
∫︁
𝑐(𝑇 )∇𝑠 · ∇𝑇 = 0 ,
∀𝑠 .
Ω
where 𝑐(𝑇 ) is the 𝑇 dependent diffusion coefficient. Each iteration calculates 𝑇 and adjusts 𝑐(𝑇 ).
114
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Laplace equation with a field-dependent material parameter.
Find :math:‘T(t)‘ for :math:‘t \in [0, t_{\rm final}]‘ such that:
.. math::
\int_{\Omega} c(T) \nabla s \cdot \nabla T
= 0
\;, \quad \forall s \;.
where :math:‘c(T)‘ is the :math:‘T‘ dependent diffusion coefficient.
Each iteration calculates :math:‘T‘ and adjusts :math:‘c(T)‘.
"""
from sfepy import data_dir
from sfepy.base.base import output
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
t0 = 0.0
t1 = 0.1
n_step = 11
def get_conductivity(ts, coors, problem, equations=None, mode=None, **kwargs):
"""
Calculates the conductivity as 2+10*T and returns it.
5.3. Examples
115
SfePy Documentation, Release 2015.1
This relation results in larger T gradients where T is small.
"""
if mode == ’qp’:
# T-field values in quadrature points coordinates given by integral i
# - they are the same as in ‘coors‘ argument.
T_values = problem.evaluate(’ev_volume_integrate.i.Omega(T)’,
mode=’qp’, verbose=False)
val = 2 + 10 * (T_values + 2)
output(’conductivity: min:’, val.min(), ’max:’, val.max())
val.shape = (val.shape[0] * val.shape[1], 1, 1)
return {’val’ : val}
materials = {
’coef’ : ’get_conductivity’,
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’T’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’T’),
}
regions = {
’Omega’ : ’all’,
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
}
ebcs = {
’T1’ : (’Gamma_Left’, {’T.0’ : 2.0}),
’T2’ : (’Gamma_Right’, {’T.0’ : -2.0}),
}
functions = {
’get_conductivity’ : (get_conductivity,),
}
ics = {
’ic’ : (’Omega’, {’T.0’ : 0.0}),
}
integrals = {
’i’ : 1,
}
equations = {
’Temperature’ : """dw_laplace.i.Omega( coef.val, s, T ) = 0"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
116
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’eps_a’ : 1e-10,
’eps_r’ : 1.0,
}),
’ts’ : (’ts.simple’, {
’t0’ : t0,
’t1’ : t1,
’dt’ : None,
’n_step’ : n_step, # has precedence over dt!
’quasistatic’ : True,
}),
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
}
diffusion/poisson_functions.py
Description
Poisson equation with source term.
Find 𝑢 such that:
∫︁
∫︁
∫︁
𝑐∇𝑣 · ∇𝑢 = −
Ω
𝑏𝑣 = −
Ω𝐿
𝑓 𝑣𝑝 ,
∀𝑣 ,
Ω𝐿
where 𝑏(𝑥) = 𝑓 (𝑥)𝑝(𝑥), 𝑝 is a given FE field and 𝑓 is a given general function of space.
This example demonstrates use of functions for defining material parameters, regions, parameter variables or boundary
conditions. Notably, it demonstrates the following:
1. How to define a material parameter by an arbitrary function - see the function get_pars() that evaluates 𝑓 (𝑥)
in quadrature points.
2. How to define a known function that belongs to a given FE space (field) - this function, 𝑝(𝑥), is defined in a FE
sense by its nodal values only - see the function get_load_variable().
In order to define the load 𝑏(𝑥) directly,
dw_volume_integrate.
5.3. Examples
the term dw_volume_dot should be replaced by
117
SfePy Documentation, Release 2015.1
source code
r"""
Poisson equation with source term.
Find :math:‘u‘ such that:
.. math::
\int_{\Omega} c \nabla v \cdot \nabla u
= - \int_{\Omega_L} b v = - \int_{\Omega_L} f v p
\;, \quad \forall v \;,
where :math:‘b(x) = f(x) p(x)‘, :math:‘p‘ is a given FE field and :math:‘f‘ is
a given general function of space.
This example demonstrates use of functions for defining material parameters,
regions, parameter variables or boundary conditions. Notably, it demonstrates
the following:
1. How to define a material parameter by an arbitrary function - see the
function :func:‘get_pars()‘ that evaluates :math:‘f(x)‘ in quadrature
points.
2. How to define a known function that belongs to a given FE space (field) this function, :math:‘p(x)‘, is defined in a FE sense by its nodal values
only - see the function :func:‘get_load_variable()‘.
In order to define the load :math:‘b(x)‘ directly, the term ‘‘dw_volume_dot‘‘
118
Chapter 5. Examples
SfePy Documentation, Release 2015.1
should be replaced by ‘‘dw_volume_integrate‘‘.
"""
import numpy as nm
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
materials = {
’m’ : ({’c’ : 1.0},),
’load’ : ’get_pars’,
}
regions = {
’Omega’ : ’all’,
’Omega_L’ : ’vertices by get_middle_ball’,
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
’velocity’ : (’real’, ’vector’, ’Omega’, 1),
}
variables
’u’ :
’v’ :
’p’ :
= {
(’unknown field’, ’temperature’, 0),
(’test field’,
’temperature’, ’u’),
(’parameter field’, ’temperature’,
{’setter’ : ’get_load_variable’}),
’w’ : (’parameter field’, ’velocity’,
{’setter’ : ’get_convective_velocity’}),
}
ebcs = {
’u1’ : (’Gamma_Left’, {’u.0’ : ’get_ebc’}),
’u2’ : (’Gamma_Right’, {’u.0’ : -2.0}),
}
integrals = {
’i’ : 1,
}
equations = {
’Laplace equation’ :
"""dw_laplace.i.Omega( m.c, v, u )
- dw_convect_v_grad_s.i.Omega( v, w, u )
= - dw_volume_dot.i.Omega_L( load.f, v, p )"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
5.3. Examples
119
SfePy Documentation, Release 2015.1
’eps_a’
: 1e-10,
}),
}
def get_pars(ts, coors, mode=None, **kwargs):
"""
Evaluate the coefficient ‘load.f‘ in quadrature points ‘coors‘ using a
function of space.
For scalar parameters, the shape has to be set to ‘(coors.shape[0], 1, 1)‘.
"""
if mode == ’qp’:
x = coors[:, 0]
val = 55.0 * (x - 0.05)
val.shape = (coors.shape[0], 1, 1)
return {’f’ : val}
def get_middle_ball(coors, domain=None):
"""
Get the :math:‘\Omega_L‘ region as a function of mesh coordinates.
"""
x, y, z = coors[:, 0], coors[:, 1], coors[:, 2]
r1 = nm.sqrt((x - 0.025)**2.0 + y**2.0 + z**2)
r2 = nm.sqrt((x - 0.075)**2.0 + y**2.0 + z**2)
flag = nm.where((r1 < 2.3e-2) | (r2 < 2.3e-2))[0]
return flag
def get_load_variable(ts, coors, region=None):
"""
Define nodal values of ’p’ in the nodal coordinates ‘coors‘.
"""
y = coors[:,1]
val = 5e5 * y
return val
def get_convective_velocity(ts, coors, region=None):
"""
Define nodal values of ’w’ in the nodal coordinates ‘coors‘.
"""
val = 100.0 * nm.ones_like(coors)
return val
def get_ebc(coors, amplitude):
"""
Define the essential boundary conditions as a function of coordinates
‘coors‘ of region nodes.
"""
z = coors[:, 2]
val = amplitude * nm.sin(z * 2.0 * nm.pi)
return val
functions = {
120
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’get_pars’ : (get_pars,),
’get_load_variable’ : (get_load_variable,),
’get_convective_velocity’ : (get_convective_velocity,),
’get_middle_ball’ : (get_middle_ball,),
’get_ebc’ : (lambda ts, coor, bc, problem, **kwargs: get_ebc(coor, 5.0),),
}
diffusion/poisson_iga.py
Description
Poisson equation solved in a single patch NURBS domain using the isogeometric analysis (IGA) approach.
Find 𝑡 such that:
∫︁
∫︁
𝑐∇𝑠 · ∇𝑡 =
Ω
𝑓𝑠 ,
∀𝑠 .
Ω0
Try setting the Dirichlet boundary condition (ebcs) on various sides of the domain (’Gamma1’, ..., ’Gamma4’).
View the results using:
$ ./postproc.py patch2d.vtk --wireframe -b
$ ./postproc.py patch2d.vtk --wireframe -b -d’t,plot_warp_scalar,rel_scaling=1’
source code
5.3. Examples
121
SfePy Documentation, Release 2015.1
r"""
Poisson equation solved in a single patch NURBS domain using the isogeometric
analysis (IGA) approach.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= \int_{\Omega_0} f s
\;, \quad \forall s \;.
Try setting the Dirichlet boundary condition (ebcs) on various sides of the
domain (‘‘’Gamma1’‘‘, ..., ‘‘’Gamma4’‘‘).
View the results using::
$ ./postproc.py patch2d.vtk --wireframe -b
$ ./postproc.py patch2d.vtk --wireframe -b -d’t,plot_warp_scalar,rel_scaling=1’
"""
from sfepy import data_dir
filename_domain = data_dir + ’/meshes/iga/patch2d.iga’
materials = {
’m’ : ({’c’ : 1.0, ’f’ : -10.0},),
}
regions = {
’Omega’ : ’all’,
’Omega_0’ : ’vertices
’Gamma1’ : (’vertices
’Gamma2’ : (’vertices
’Gamma3’ : (’vertices
’Gamma4’ : (’vertices
}
in
of
of
of
of
(x > 1.5)’,
set xi00’, ’facet’),
set xi01’, ’facet’),
set xi10’, ’facet’),
set xi11’, ’facet’),
fields = {
’temperature’ : (’real’, 1, ’Omega’, None, ’H1’, ’iga’),
}
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’t’),
}
ebcs = {
’t1’ : (’Gamma3’, {’t.0’ : 2.0}),
’t2’ : (’Gamma4’, {’t.0’ : -2.0}),
}
integrals = {
’i’ : 3,
}
equations = {
’Temperature’ : """dw_laplace.i.Omega(m.c, s, t)
= dw_volume_lvf.i.Omega_0(m.f, s)"""
}
122
Chapter 5. Examples
SfePy Documentation, Release 2015.1
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
diffusion/poisson_neumann.py
Description
Poisson equation with Neumann boundary conditions on a part of the boundary.
Find 𝑡 such that:
∫︁
∫︁
𝑐∇𝑠 · ∇𝑡 =
Ω
𝑠𝑔 ,
∀𝑠 ,
Γ𝑁
where 𝑔 is the given flux, 𝑔 = ∇𝑇 · 𝑛. See the tutorial section Strong form of Poisson’s equation and its integration
for a detailed explanation.
5.3. Examples
123
SfePy Documentation, Release 2015.1
source code
r"""
Poisson equation with Neumann boundary conditions on a part of the boundary.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= \int_{\Gamma_N} s g
\;, \quad \forall s \;,
where :math:‘g‘ is the given flux, :math:‘g = \nabla T \cdot \ul{n}‘. See the
tutorial section :ref:‘poisson-weak-form-tutorial‘ for a detailed explanation.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
materials = {
’flux’ : ({’val’ : -50.0},),
’coef’ : ({’val’ : 2.0},),
}
regions = {
’Omega’ : ’all’, # or ’cells of group 6’
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
’Gamma_N’ : (’vertices of surface -f (r.Gamma_Left +v r.Gamma_Right)’,
’facet’),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’t’),
}
ebcs = {
’t1’ : (’Gamma_Left’, {’t.0’ : 2.0}),
’t2’ : (’Gamma_Right’, {’t.0’ : -2.0}),
}
equations = {
’Temperature’ : """
dw_laplace.2.Omega(coef.val, s, t)
= dw_surface_integrate.2.Gamma_N(flux.val, s)
"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-10,
}),
124
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
diffusion/poisson_parametric_study.py
Description
Poisson equation.
This example demonstrates parametric study capabilities of Application classes. In particular (written in the strong
form):
𝑐∆𝑡 = 𝑓 in Ω,
𝑡 = 2 on Γ1 , 𝑡 = −2 on Γ2 , 𝑓 = 1 in Ω1 , 𝑓 = 0 otherwise,
where Ω is a square domain, Ω1 ∈ Ω is a circular domain.
Now let’s see what happens if Ω1 diameter changes.
Run:
$ ./simple.py <this file>
and then look in ‘output/r_omega1’ directory, try for example:
$ ./postproc.py output/r_omega1/circles_in_square*.vtk
Remark: this simple case could be achieved also by defining Ω1 by a time-dependent function and solve the static
problem as a time-dependent problem. However, the approach below is much more general.
Find 𝑡 such that:
∫︁
𝑐∇𝑠 · ∇𝑡 = 0 ,
∀𝑠 .
Ω
source code
r"""
Poisson equation.
This example demonstrates parametric study capabilities of Application
classes. In particular (written in the strong form):
.. math::
c \Delta t = f \mbox{ in } \Omega,
t
t
f
f
=
=
=
=
2 \mbox{ on } \Gamma_1 \;,
-2 \mbox{ on } \Gamma_2 \;,
1 \mbox{ in } \Omega_1 \;,
0 \mbox{ otherwise,}
where :math:‘\Omega‘ is a square domain, :math:‘\Omega_1 \in \Omega‘ is
a circular domain.
Now let’s see what happens if :math:‘\Omega_1‘ diameter changes.
5.3. Examples
125
SfePy Documentation, Release 2015.1
Run::
$ ./simple.py <this file>
and then look in ’output/r_omega1’ directory, try for example::
$ ./postproc.py output/r_omega1/circles_in_square*.vtk
Remark: this simple case could be achieved also by defining
:math:‘\Omega_1‘ by a time-dependent function and solve the static
problem as a time-dependent problem. However, the approach below is much
more general.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= 0
\;, \quad \forall s \;.
"""
import os
import numpy as nm
from sfepy import data_dir
from sfepy.base.base import output
# Mesh.
filename_mesh = data_dir + ’/meshes/2d/special/circles_in_square.vtk’
# Options. The value of ’parametric_hook’ is the function that does the
# parametric study.
options = {
’nls’ : ’newton’, # Nonlinear solver
’ls’ : ’ls’, # Linear solver
’parametric_hook’ : ’vary_omega1_size’,
’output_dir’ : ’output/r_omega1’,
}
# Domain and subdomains.
default_diameter = 0.25
regions = {
’Omega’ : ’all’,
’Gamma_1’ : (’vertices in (x < -0.999)’, ’facet’),
’Gamma_2’ : (’vertices in (x > 0.999)’, ’facet’),
’Omega_1’ : ’vertices by select_circ’,
}
# FE field defines the FE approximation: 2_3_P1 = 2D, P1 on triangles.
field_1 = {
’name’ : ’temperature’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
# Unknown and test functions (FE sense).
126
Chapter 5. Examples
SfePy Documentation, Release 2015.1
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’, ’temperature’, ’t’),
}
# Dirichlet boundary conditions.
ebcs = {
’t1’ : (’Gamma_1’, {’t.0’ : 2.0}),
’t2’ : (’Gamma_2’, {’t.0’ : -2.0}),
}
# Material coefficient c and source term value f.
material_1 = {
’name’ : ’coef’,
’values’ : {
’val’ : 1.0,
}
}
material_2 = {
’name’ : ’source’,
’values’ : {
’val’ : 10.0,
}
}
# Numerical quadrature and the equation.
integral_1 = {
’name’ : ’i’,
’order’ : 2,
}
equations = {
’Poisson’ : """dw_laplace.i.Omega( coef.val, s, t )
= dw_volume_lvf.i.Omega_1( source.val, s )"""
}
# Solvers.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
}
5.3. Examples
127
SfePy Documentation, Release 2015.1
functions = {
’select_circ’: (lambda coors, domain=None:
select_circ(coors[:,0], coors[:,1], 0, default_diameter),),
}
# Functions.
def select_circ( x, y, z, diameter ):
"""Select circular subdomain of a given diameter."""
r = nm.sqrt( x**2 + y**2 )
out = nm.where(r < diameter)[0]
n = out.shape[0]
if n <= 3:
raise ValueError( ’too few vertices selected! (%d)’ % n )
return out
def vary_omega1_size( problem ):
"""Vary size of \Omega1. Saves also the regions into options[’output_dir’].
Input:
problem: Problem instance
Return:
a generator object:
1. creates new (modified) problem
2. yields the new (modified) problem and output container
3. use the output container for some logging
4. yields None (to signal next iteration to Application)
"""
from sfepy.discrete import Problem
from sfepy.solvers.ts import get_print_info
output.prefix = ’vary_omega1_size:’
diameters = nm.linspace( 0.1, 0.6, 7 ) + 0.001
ofn_trunk, output_format = problem.ofn_trunk, problem.output_format
output_dir = problem.output_dir
join = os.path.join
conf = problem.conf
cf = conf.get_raw( ’functions’ )
n_digit, aux, d_format = get_print_info( len( diameters ) + 1 )
for ii, diameter in enumerate( diameters ):
output( ’iteration %d: diameter %3.2f’ % (ii, diameter) )
cf[’select_circ’] = (lambda coors, domain=None:
select_circ(coors[:,0], coors[:,1], 0, diameter),)
conf.edit(’functions’, cf)
problem = Problem.from_conf(conf)
problem.save_regions( join( output_dir, (’regions_’ + d_format) % ii ),
[’Omega_1’] )
region = problem.domain.regions[’Omega_1’]
if not region.has_cells():
raise ValueError(’region %s has no cells!’ % region.name)
ofn_trunk = ofn_trunk + ’_’ + (d_format % ii)
128
Chapter 5. Examples
SfePy Documentation, Release 2015.1
problem.setup_output(output_filename_trunk=ofn_trunk,
output_dir=output_dir,
output_format=output_format)
out = []
yield problem, out
out_problem, state = out[-1]
filename = join( output_dir,
(’log_%s.txt’ % d_format) % ii )
fd = open( filename, ’w’ )
log_item = ’$r(\Omega_1)$: %f\n’ % diameter
fd.write( log_item )
fd.write( ’solution:\n’ )
nm.savetxt(fd, state())
fd.close()
yield None
diffusion/poisson_periodic_boundary_condition.py
Description
Transient Laplace equation with a localized power source and periodic boundary conditions.
This example is using a mesh generated by gmsh. Both the .geo script used by gmsh to generate the file and the .mesh
file can be found in meshes.
The mesh is suitable for periodic boundary conditions. It consists of a cylinder enclosed by a box in the x and y
directions.
The cylinder will act as a power source.
The transient Laplace equation will be solved in time interval 𝑡 ∈ [0, 𝑡final ].
Find 𝑇 (𝑡) for 𝑡 ∈ [0, 𝑡final ] such that:
∫︁
𝑐𝑠
Ω
5.3. Examples
𝜕𝑇
+
𝜕𝑡
∫︁
∫︁
𝜎2 ∇𝑠 · ∇𝑇 =
Ω
𝑃3 𝑇 ,
∀𝑠 .
Ω2
129
SfePy Documentation, Release 2015.1
source code
r"""
Transient Laplace equation with a localized power source and
periodic boundary conditions.
This example is using a mesh generated by gmsh. Both the
.geo script used by gmsh to generate the file and the .mesh
file can be found in meshes.
The mesh is suitable for periodic boundary conditions. It consists
of a cylinder enclosed by a box in the x and y directions.
The cylinder will act as a power source.
The transient Laplace equation will be solved in time interval
:math:‘t \in [0, t_{\rm final}]‘.
Find :math:‘T(t)‘ for :math:‘t \in [0, t_{\rm final}]‘ such that:
.. math::
\int_{\Omega}c s \pdiff{T}{t}
+ \int_{\Omega} \sigma_2 \nabla s \cdot \nabla T
= \int_{\Omega_2} P_3 T
\;, \quad \forall s \;.
"""
130
Chapter 5. Examples
SfePy Documentation, Release 2015.1
from sfepy import data_dir
import numpy as nm
import sfepy.discrete.fem.periodic as per
filename_mesh = data_dir + ’/meshes/3d/cylinder_in_box.mesh’
t0 = 0.0
t1 = 1.
n_step = 11
power_per_volume =1.e2 # Heating power per volume of the cylinder
capacity_cylinder = 1. # Heat capacity of cylinder
capacity_fill = 1. # Heat capacity of filling material
conductivity_cylinder = 1. # Heat conductivity of cylinder
conductivity_fill = 1. # Heat conductivity of filling material
def cylinder_material_func(ts, coors, problem, mode=None, **kwargs):
"""
Returns the thermal conductivity, the thermal mass, and the power of the
material in the cylinder.
"""
if mode == ’qp’:
shape = (coors.shape[0], 1, 1)
power = nm.empty(shape, dtype=nm.float64)
if ts.step < 5:
# The power is turned on in the first 5 steps only.
power.fill(power_per_volume)
else:
power.fill(0.0)
conductivity = nm.ones(shape) * conductivity_cylinder
capacity = nm.ones(shape) * capacity_cylinder
return {’power’ : power, ’capacity’ : capacity,
’conductivity’ : conductivity}
materials = {
’cylinder’ : ’cylinder_material_func’,
’fill’ : ({’capacity’ : capacity_fill,
’conductivity’ : conductivity_fill,},),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’T’ : (’unknown field’, ’temperature’, 1, 1),
’s’ : (’test field’, ’temperature’, ’T’),
}
regions = {
’Omega’ : ’all’,
’cylinder’ : ’cells of group 444’,
’fill’ : ’cells of group 555’,
’Gamma_Left’ : (’vertices in (x < -2.4999)’, ’facet’),
’y+’ : (’vertices in (y >2.4999)’, ’facet’),
5.3. Examples
131
SfePy Documentation, Release 2015.1
’y-’ : (’vertices in (y <-2.4999)’, ’facet’),
’z+’ : (’vertices in (z >0.4999)’, ’facet’),
’z-’ : (’vertices in (z <-0.4999)’, ’facet’),
}
ebcs = {
’T1’ : (’Gamma_Left’, {’T.0’ : 0.0}),
}
# The matching functions link the elements on each side with that on the
# opposing side.
functions = {
’cylinder_material_func’ : (cylinder_material_func,),
"match_y_plane" : (per.match_y_plane,),
"match_z_plane" : (per.match_z_plane,),
}
epbcs = {
# In the y-direction
’periodic_y’ : ([’y+’, ’y-’], {’T.0’
# and in the z-direction. Due to the
# boundary condition is actually not
’periodic_z’ : ([’z+’, ’z-’], {’T.0’
}
: ’T.0’}, ’match_y_plane’),
symmetry of the problem, this periodic
necessary, but we include it anyway.
: ’T.0’}, ’match_z_plane’),
ics = {
’ic’ : (’Omega’, {’T.0’ : 0.0}),
}
integrals = {
’i’ : 1,
}
equations = {
’Temperature’ :
"""dw_volume_dot.i.cylinder( cylinder.capacity, ds/dt, dT/dt )
dw_volume_dot.i.fill( fill.capacity, ds/dt, dT/dt )
dw_laplace.i.cylinder( cylinder.conductivity, s, T )
dw_laplace.i.fill( fill.conductivity, s, T )
= dw_volume_integrate.i.cylinder( cylinder.power, s )"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-10,
’eps_r’ : 1.0,
}),
’ts’ : (’ts.simple’, {
’t0’ : t0,
’t1’ : t1,
’dt’ : None,
’n_step’ : n_step, # has precedence over dt!
’quasistatic’ : False,
}),
}
132
Chapter 5. Examples
SfePy Documentation, Release 2015.1
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’output_dir’ : ’output’,
’save_steps’ : -1,
}
diffusion/poisson_short_syntax.py
Description
Laplace equation using the short syntax of keywords.
See diffusion/poisson.py for the long syntax version.
Find 𝑡 such that:
∫︁
𝑐∇𝑠 · ∇𝑡 = 0 ,
∀𝑠 .
Ω
source code
r"""
Laplace equation using the short syntax of keywords.
See :ref:‘diffusion-poisson‘ for the long syntax version.
5.3. Examples
133
SfePy Documentation, Release 2015.1
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= 0
\;, \quad \forall s \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
materials = {
’coef’ : ({’val’ : 1.0},),
}
regions = {
’Omega’ : ’all’, # or ’cells of group 6’
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’t’),
}
ebcs = {
’t1’ : (’Gamma_Left’, {’t.0’ : 2.0}),
’t2’ : (’Gamma_Right’, {’t.0’ : -2.0}),
}
integrals = {
’i’ : 2,
}
equations = {
’Temperature’ : """dw_laplace.i.Omega( coef.val, s, t ) = 0"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
134
Chapter 5. Examples
SfePy Documentation, Release 2015.1
diffusion/sinbc.py
Description
Laplace equation with Dirichlet boundary conditions given by a sine function and constants.
Find 𝑡 such that:
∫︁
𝑐∇𝑠 · ∇𝑡 = 0 ,
∀𝑠 .
Ω
This example demonstrates how to use a hierarchical basis approximation - it uses the fifth order Lobatto polynomial
space for the solution. The adaptive linearization is applied in order to save viewable results, see both the options
keyword and the post_process() function that computes the solution gradient. Use the following commands to
view the results (assuming default output directory and names):
$ ./postproc.py -b -d’t,plot_warp_scalar,rel_scaling=1’ 2_4_2_refined_t.vtk --wireframe
$ ./postproc.py -b 2_4_2_refined_grad.vtk
The sfepy.discrete.fem.meshio.UserMeshIO class is used to refine the original two-element mesh before
the actual solution.
5.3. Examples
135
SfePy Documentation, Release 2015.1
source code
r"""
Laplace equation with Dirichlet boundary conditions given by a sine function
and constants.
Find :math:‘t‘ such that:
.. math::
\int_{\Omega} c \nabla s \cdot \nabla t
= 0
\;, \quad \forall s \;.
This example demonstrates how to use a hierarchical basis approximation - it
uses the fifth order Lobatto polynomial space for the solution. The adaptive
linearization is applied in order to save viewable results, see both the
options keyword and the ‘‘post_process()‘‘ function that computes the solution
gradient. Use the following commands to view the results (assuming default
output directory and names)::
$ ./postproc.py -b -d’t,plot_warp_scalar,rel_scaling=1’ 2_4_2_refined_t.vtk --wireframe
$ ./postproc.py -b 2_4_2_refined_grad.vtk
The :class:‘sfepy.discrete.fem.meshio.UserMeshIO‘ class is used to refine the original
two-element mesh before the actual solution.
"""
import numpy as nm
136
Chapter 5. Examples
SfePy Documentation, Release 2015.1
from sfepy import data_dir
from
from
from
from
sfepy.base.base import output
sfepy.discrete.fem import Mesh, FEDomain
sfepy.discrete.fem.meshio import UserMeshIO, MeshIO
sfepy.homogenization.utils import define_box_regions
base_mesh = data_dir + ’/meshes/elements/2_4_2.mesh’
def mesh_hook(mesh, mode):
"""
Load and refine a mesh here.
"""
if mode == ’read’:
mesh = Mesh.from_file(base_mesh)
domain = FEDomain(mesh.name, mesh)
for ii in range(3):
output(’refine %d...’ % ii)
domain = domain.refine()
output(’... %d nodes %d elements’
% (domain.shape.n_nod, domain.shape.n_el))
domain.mesh.name = ’2_4_2_refined’
return domain.mesh
elif mode == ’write’:
pass
def post_process(out, pb, state, extend=False):
"""
Calculate gradient of the solution.
"""
from sfepy.discrete.fem.fields_base import create_expression_output
aux = create_expression_output(’ev_grad.ie.Elements( t )’,
’grad’, ’temperature’,
pb.fields, pb.get_materials(),
pb.get_variables(), functions=pb.functions,
mode=’qp’, verbose=False,
min_level=0, max_level=5, eps=1e-3)
out.update(aux)
return out
filename_mesh = UserMeshIO(mesh_hook)
# Get the mesh bounding box.
io = MeshIO.any_from_filename(base_mesh)
bbox, dim = io.read_bounding_box(ret_dim=True)
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’post_process_hook’ : ’post_process’,
’linearization’ : {
’kind’ : ’adaptive’,
’min_level’ : 0, # Min. refinement level to achieve everywhere.
5.3. Examples
137
SfePy Documentation, Release 2015.1
’max_level’ : 5, # Max. refinement level.
’eps’ : 1e-3, # Relative error tolerance.
},
}
materials = {
’coef’ : ({’val’ : 1.0},),
}
regions = {
’Omega’ : ’all’,
}
regions.update(define_box_regions(dim, bbox[0], bbox[1], 1e-5))
fields = {
’temperature’ : (’real’, 1, ’Omega’, 5, ’H1’, ’lobatto’),
# Compare with the Lagrange basis.
## ’temperature’ : (’real’, 1, ’Omega’, 5, ’H1’, ’lagrange’),
}
variables = {
’t’ : (’unknown field’, ’temperature’, 0),
’s’ : (’test field’,
’temperature’, ’t’),
}
amplitude = 1.0
def ebc_sin(ts, coor, **kwargs):
x0 = 0.5 * (coor[:, 1].min() + coor[:, 1].max())
val = amplitude * nm.sin( (coor[:, 1] - x0) * 2. * nm.pi )
return val
ebcs = {
’t1’ : (’Left’, {’t.0’ : ’ebc_sin’}),
’t2’ : (’Right’, {’t.0’ : -0.5}),
’t3’ : (’Top’, {’t.0’ : 1.0}),
}
functions = {
’ebc_sin’ : (ebc_sin,),
}
equations = {
’Temperature’ : """dw_laplace.10.Omega( coef.val, s, t ) = 0"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
diffusion/time_poisson.py
Description
138
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Transient Laplace equation with non-constant initial conditions given by a function.
Find 𝑇 (𝑡) for 𝑡 ∈ [0, 𝑡final ] such that:
∫︁
𝑠
Ω
𝜕𝑇
+
𝜕𝑡
∫︁
𝑐∇𝑠 · ∇𝑇 = 0 ,
∀𝑠 .
Ω
source code
r"""
Transient Laplace equation with non-constant initial conditions given by a
function.
Find :math:‘T(t)‘ for :math:‘t \in [0, t_{\rm final}]‘ such that:
.. math::
\int_{\Omega} s \pdiff{T}{t}
+ \int_{\Omega} c \nabla s \cdot \nabla T
= 0
\;, \quad \forall s \;.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
t0 = 0.0
t1 = 0.1
n_step = 11
5.3. Examples
139
SfePy Documentation, Release 2015.1
material_2 =
’name’ :
’values’
’kind’ :
}
{
’coef’,
: {’val’ : 0.01},
’stationary’, # ’stationary’ or ’time-dependent’
field_1 = {
’name’ : ’temperature’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
variable_1 = {
’name’ : ’T’,
’kind’ : ’unknown field’,
’field’ : ’temperature’,
’order’ : 0,
’history’ : 1,
}
variable_2 = {
’name’ : ’s’,
’kind’ : ’test field’,
’field’ : ’temperature’,
’dual’ : ’T’,
}
regions = {
’Omega’ : ’all’,
’Gamma_Left’ : (’vertices in (x < 0.00001)’, ’facet’),
’Gamma_Right’ : (’vertices in (x > 0.099999)’, ’facet’),
}
ebcs = {
’T1’: (’Gamma_Left’, {’T.0’ : 2.0}),
’T2’: (’Gamma_Right’, {’T.0’ : -2.0}),
}
def get_ic(coor, ic):
"""Non-constant initial condition."""
import numpy as nm
# Normalize x coordinate.
mi, ma = coor[:,0].min(), coor[:,0].max()
nx = (coor[:,0] - mi) / (ma - mi)
return nm.where( (nx > 0.25) & (nx < 0.75 ), 8.0 * (nx - 0.5), 0.0 )
functions = {
’get_ic’ : (get_ic,),
}
ics = {
’ic’ : (’Omega’, {’T.0’ : ’get_ic’}),
}
integral_1 = {
’name’ : ’i’,
’order’ : 1,
140
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}
equations = {
’Temperature’ :
"""dw_volume_dot.i.Omega( s, dT/dt )
+ dw_laplace.i.Omega( coef.val, s, T ) = 0"""
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
’presolve’ : True,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
’is_linear’ : True,
}
solver_2 = {
’name’ : ’ts’,
’kind’ : ’ts.simple’,
’t0’
: t0,
’t1’
: t1,
’dt’
: None,
’n_step’ : n_step, # has precedence over dt!
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
}
5.3.4 homogenization
homogenization/linear_homogenization.py
Description
missing description!
5.3. Examples
141
SfePy Documentation, Release 2015.1
source code
# 04.08.2009
#!
#! Homogenization: Linear Elasticity
#! =================================
#$ \centerline{Example input file, \today}
#! Homogenization of heterogeneous linear elastic material
import sfepy.discrete.fem.periodic as per
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.homogenization.utils import define_box_regions
import sfepy.homogenization.coefs_base as cb
from sfepy import data_dir
from sfepy.base.base import Struct
from sfepy.homogenization.recovery import compute_micro_u, compute_stress_strain_u, compute_mac_stres
def recovery_le( pb, corrs, macro ):
out = {}
dim = corrs[’corrs_le’][’u_00’].shape[1]
mic_u = - compute_micro_u( corrs[’corrs_le’], macro[’strain’], ’u’, dim )
out[’u_mic’] = Struct( name = ’output_data’,
mode = ’vertex’, data = mic_u,
var_name = ’u’, dofs = None )
stress_Y, strain_Y = compute_stress_strain_u( pb, ’i’, ’Y’, ’mat.D’, ’u’, mic_u )
stress_Y += compute_mac_stress_part( pb, ’i’, ’Y’, ’mat.D’, ’u’, macro[’strain’] )
strain = macro[’strain’] + strain_Y
out[’cauchy_strain’] = Struct( name
mode
dofs
out[’cauchy_stress’] = Struct( name
mode
dofs
return out
=
=
=
=
=
=
’output_data’,
’cell’, data = strain,
None )
’output_data’,
’cell’, data = stress_Y,
None )
#! Mesh
#! ---filename_mesh = data_dir + ’/meshes/3d/matrix_fiber.mesh’
dim = 3
region_lbn = (0, 0, 0)
region_rtf = (1, 1, 1)
#! Regions
#! ------#! Regions, edges, ...
regions = {
’Y’ : ’all’,
’Ym’ : ’cells of group 1’,
’Yc’ : ’cells of group 2’,
}
regions.update( define_box_regions( dim, region_lbn, region_rtf ) )
#! Materials
#! ---------
142
Chapter 5. Examples
SfePy Documentation, Release 2015.1
materials = {
’mat’ : ({’D’ : {’Ym’: stiffness_from_youngpoisson(dim, 7.0e9, 0.4),
’Yc’: stiffness_from_youngpoisson(dim, 70.0e9, 0.2)}},),
}
#! Fields
#! -----#! Scalar field for corrector basis functions.
fields = {
’corrector’ : (’real’, dim, ’Y’, 1),
}
#! Variables
#! --------#! Unknown and corresponding test variables. Parameter fields
#! used for evaluation of homogenized coefficients.
variables = {
’u’
: (’unknown field’, ’corrector’, 0),
’v’
: (’test field’, ’corrector’, ’u’),
’Pi’
: (’parameter field’, ’corrector’, ’u’),
’Pi1’ : (’parameter field’, ’corrector’, ’(set-to-None)’),
’Pi2’ : (’parameter field’, ’corrector’, ’(set-to-None)’),
}
#! Functions
functions = {
’match_x_plane’ : (per.match_x_plane,),
’match_y_plane’ : (per.match_y_plane,),
’match_z_plane’ : (per.match_z_plane,),
}
#! Boundary Conditions
#! ------------------#! Fixed nodes.
ebcs = {
’fixed_u’ : (’Corners’, {’u.all’ : 0.0}),
}
if dim == 3:
epbcs = {
’periodic_x’ : ([’Left’, ’Right’], {’u.all’ : ’u.all’}, ’match_x_plane’),
’periodic_y’ : ([’Near’, ’Far’], {’u.all’ : ’u.all’}, ’match_y_plane’),
’periodic_z’ : ([’Top’, ’Bottom’], {’u.all’ : ’u.all’}, ’match_z_plane’),
}
else:
epbcs = {
’periodic_x’ : ([’Left’, ’Right’], {’u.all’ : ’u.all’}, ’match_x_plane’),
’periodic_y’ : ([’Bottom’, ’Top’], {’u.all’ : ’u.all’}, ’match_y_plane’),
}
all_periodic = [’periodic_%s’ % ii for ii in [’x’, ’y’, ’z’][:dim] ]
#! Integrals
#! --------#! Define the integral type Volume/Surface and quadrature rule.
integrals = {
’i’ : 2,
}
#! Options
#! ------#! Various problem-specific options.
options = {
’coefs’ : ’coefs’,
’requirements’ : ’requirements’,
’ls’ : ’ls’, # linear solver to use
5.3. Examples
143
SfePy Documentation, Release 2015.1
’volume’ : { ’variables’ : [’u’],
’expression’ : ’d_volume.i.Y( u )’ },
’output_dir’ : ’output’,
’coefs_filename’ : ’coefs_le’,
’recovery_hook’ : ’recovery_le’,
}
#! Equations
#! --------#! Equations for corrector functions.
equation_corrs = {
’balance_of_forces’ :
"""dw_lin_elastic.i.Y(mat.D, v, u ) =
- dw_lin_elastic.i.Y(mat.D, v, Pi )"""
}
#! Expressions for homogenized linear elastic coefficients.
expr_coefs = """dw_lin_elastic.i.Y(mat.D, Pi1, Pi2 )"""
#! Coefficients
#! -----------#! Definition of homogenized acoustic coefficients.
def set_elastic(variables, ir, ic, mode, pis, corrs_rs):
mode2var = {’row’ : ’Pi1’, ’col’ : ’Pi2’}
val = pis.states[ir, ic][’u’] + corrs_rs.states[ir, ic][’u’]
variables[mode2var[mode]].set_data(val)
coefs = {
’D’ : {
’requires’ : [’pis’, ’corrs_rs’],
’expression’ : expr_coefs,
’set_variables’ : set_elastic,
’class’ : cb.CoefSymSym,
},
’filenames’ : {},
}
requirements = {
’pis’ : {
’variables’ : [’u’],
’class’ : cb.ShapeDimDim,
},
’corrs_rs’ : {
’requires’ : [’pis’],
’ebcs’ : [’fixed_u’],
’epbcs’ : all_periodic,
’equations’ : equation_corrs,
’set_variables’ : [(’Pi’, ’pis’, ’u’)],
’class’ : cb.CorrDimDim,
’save_name’ : ’corrs_le’,
’dump_variables’ : [’u’],
},
}
#! Solvers
#! ------#! Define linear and nonlinear solver.
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
144
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’i_max’ : 1,
’eps_a’ : 1e-4,
})
}
homogenization/linear_homogenization_postproc.py
Description
This example shows how to use the VTK postprocessing functions.
source code
"""
This example shows how to use the VTK postprocessing functions.
"""
import os.path as osp
from linear_homogenization import *
from sfepy.postprocess.utils_vtk import get_vtk_from_mesh,\
get_vtk_by_group, get_vtk_surface, get_vtk_edges, write_vtk_to_file,\
tetrahedralize_vtk_mesh
options.update({
’post_process_hook’ : ’post_process’,
})
def post_process(out, problem, state, extend=False):
mesh = problem.domain.mesh
mesh_name = mesh.name[mesh.name.rfind(osp.sep) + 1:]
vtkdata = get_vtk_from_mesh(mesh, out, ’postproc_’)
matrix = get_vtk_by_group(vtkdata, 1, 1)
matrix_surf = get_vtk_surface(matrix)
matrix_surf_tri = tetrahedralize_vtk_mesh(matrix_surf)
write_vtk_to_file(’%s_mat1_surface.vtk’ % mesh_name, matrix_surf_tri)
matrix_edges = get_vtk_edges(matrix)
write_vtk_to_file(’%s_mat1_edges.vtk’ % mesh_name, matrix_edges)
return out
homogenization/linear_homogenization_up.py
Description
missing description!
source code
# mixed formulation
# 07.08.2009
#!
#! Homogenization: Linear Elasticity
5.3. Examples
145
SfePy Documentation, Release 2015.1
#! =================================
#$ \centerline{Example input file, \today}
#! Homogenization of heterogeneous linear elastic material - mixed formulation
import numpy as nm
import sfepy.discrete.fem.periodic as per
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson_mixed, bulk_from_youngpoisson
from sfepy.homogenization.utils import define_box_regions, get_box_volume
import sfepy.homogenization.coefs_base as cb
from sfepy import data_dir
from sfepy.base.base import Struct
from sfepy.homogenization.recovery import compute_micro_u, compute_stress_strain_u, compute_mac_stres
def recovery_le( pb, corrs, macro ):
out =
dim =
mic_u
mic_p
{}
corrs[’corrs_le’][’u_00’].shape[1]
= - compute_micro_u( corrs[’corrs_le’], macro[’strain’], ’u’, dim )
= - compute_micro_u( corrs[’corrs_le’], macro[’strain’], ’p’, dim )
out[’u_mic’] = Struct( name = ’output_data’,
mode = ’vertex’, data = mic_u,
var_name = ’u’, dofs = None )
out[’p_mic’] = Struct( name = ’output_data’,
mode = ’cell’, data = mic_p[:,nm.newaxis,
:,nm.newaxis],
var_name = ’p’, dofs = None )
stress_Y, strain_Y = compute_stress_strain_u( pb, ’i’, ’Y’, ’mat.D’, ’u’, mic_u )
stress_Y += compute_mac_stress_part( pb, ’i’, ’Y’, ’mat.D’, ’u’, macro[’strain’] )
add_stress_p( stress_Y, pb, ’i’, ’Y’, ’p’, mic_p )
strain = macro[’strain’] + strain_Y
out[’cauchy_strain’] = Struct( name
mode
dofs
out[’cauchy_stress’] = Struct( name
mode
dofs
return out
=
=
=
=
=
=
’output_data’,
’cell’, data = strain,
None )
’output_data’,
’cell’, data = stress_Y,
None )
#! Mesh
#! ---dim = 3
filename_mesh = data_dir + ’/meshes/3d/matrix_fiber.mesh’
region_lbn = (0, 0, 0)
region_rtf = (1, 1, 1)
#! Regions
#! ------#! Regions, edges, ...
regions = {
’Y’ : ’all’,
’Ym’ : ’cells of group 1’,
’Yc’ : ’cells of group 2’,
}
146
Chapter 5. Examples
SfePy Documentation, Release 2015.1
regions.update( define_box_regions( dim, region_lbn, region_rtf ) )
#! Materials
#! --------materials = {
’mat’ : ({’D’ : {’Ym’: stiffness_from_youngpoisson_mixed(dim, 7.0e9, 0.4),
’Yc’: stiffness_from_youngpoisson_mixed(dim, 70.0e9, 0.2)},
’gamma’: {’Ym’: 1.0/bulk_from_youngpoisson(7.0e9, 0.4),
’Yc’: 1.0/bulk_from_youngpoisson(70.0e9, 0.2)}},),
}
#! Fields
#! -----#! Scalar field for corrector basis functions.
fields = {
’corrector_u’ : (’real’, dim, ’Y’, 1),
’corrector_p’ : (’real’, 1, ’Y’, 0),
}
#! Variables
#! --------#! Unknown and corresponding test variables. Parameter fields
#! used for evaluation of homogenized coefficients.
variables = {
’u’
: (’unknown field’, ’corrector_u’),
’v’
: (’test field’, ’corrector_u’, ’u’),
’p’
: (’unknown field’, ’corrector_p’),
’q’
: (’test field’, ’corrector_p’, ’p’),
’Pi’
: (’parameter field’, ’corrector_u’, ’u’),
’Pi1u’ : (’parameter field’, ’corrector_u’, ’(set-to-None)’),
’Pi2u’ : (’parameter field’, ’corrector_u’, ’(set-to-None)’),
’Pi1p’ : (’parameter field’, ’corrector_p’, ’(set-to-None)’),
’Pi2p’ : (’parameter field’, ’corrector_p’, ’(set-to-None)’),
}
#! Functions
functions = {
’match_x_plane’ : (per.match_x_plane,),
’match_y_plane’ : (per.match_y_plane,),
’match_z_plane’ : (per.match_z_plane,),
}
#! Boundary Conditions
#! ------------------#! Fixed nodes.
ebcs = {
’fixed_u’ : (’Corners’, {’u.all’ : 0.0}),
}
if dim == 3:
epbcs = {
’periodic_x’ : ([’Left’, ’Right’], {’u.all’ : ’u.all’}, ’match_x_plane’),
’periodic_y’ : ([’Near’, ’Far’], {’u.all’ : ’u.all’}, ’match_y_plane’),
’periodic_z’ : ([’Top’, ’Bottom’], {’u.all’ : ’u.all’}, ’match_z_plane’),
}
else:
epbcs = {
’periodic_x’ : ([’Left’, ’Right’], {’u.all’ : ’u.all’}, ’match_x_plane’),
’periodic_y’ : ([’Bottom’, ’Top’], {’u.all’ : ’u.all’}, ’match_y_plane’),
}
all_periodic = [’periodic_%s’ % ii for ii in [’x’, ’y’, ’z’][:dim] ]
#! Integrals
#! --------#! Define the integral type Volume/Surface and quadrature rule.
5.3. Examples
147
SfePy Documentation, Release 2015.1
integrals = {
’i’ : 2,
}
#! Options
#! ------#! Various problem-specific options.
options = {
’coefs’ : ’coefs’,
’requirements’ : ’requirements’,
’ls’ : ’ls’, # linear solver to use
’volume’ : { #’variables’ : [’u’],
#’expression’ : ’d_volume.i.Y( u )’,
’value’ : get_box_volume( dim, region_lbn, region_rtf ),
},
’output_dir’ : ’output’,
’coefs_filename’ : ’coefs_le_up’,
’recovery_hook’ : ’recovery_le’,
}
#! Equations
#! --------#! Equations for corrector functions.
equation_corrs = {
’balance_of_forces’ :
""" dw_lin_elastic.i.Y( mat.D, v, u )
- dw_stokes.i.Y( v, p ) =
- dw_lin_elastic.i.Y( mat.D, v, Pi )""",
’pressure constraint’ :
"""- dw_stokes.i.Y( u, q )
- dw_volume_dot.i.Y( mat.gamma, q, p ) =
+ dw_stokes.i.Y( Pi, q )""",
}
#! Expressions for homogenized linear elastic coefficients.
expr_coefs = {
’Q1’ : """dw_lin_elastic.i.Y( mat.D, Pi1u, Pi2u )""",
’Q2’ : """dw_volume_dot.i.Y( mat.gamma, Pi1p, Pi2p )""",
}
#! Coefficients
#! -----------#! Definition of homogenized acoustic coefficients.
def set_elastic_u(variables, ir, ic, mode, pis, corrs_rs):
mode2var = {’row’ : ’Pi1u’, ’col’ : ’Pi2u’}
val = pis.states[ir, ic][’u’] + corrs_rs.states[ir, ic][’u’]
variables[mode2var[mode]].set_data(val)
coefs = {
’elastic_u’ : {
’requires’ : [’pis’, ’corrs_rs’],
’expression’ : expr_coefs[’Q1’],
’set_variables’ : set_elastic_u,
’class’ : cb.CoefSymSym,
},
’elastic_p’ : {
’requires’ : [’corrs_rs’],
’expression’ : expr_coefs[’Q2’],
’set_variables’ : [(’Pi1p’, ’corrs_rs’, ’p’), (’Pi2p’, ’corrs_rs’, ’p’)],
’class’ : cb.CoefSymSym,
148
Chapter 5. Examples
SfePy Documentation, Release 2015.1
},
’D’ : {
’requires’ : [’c.elastic_u’, ’c.elastic_p’],
’class’ : cb.CoefSum,
},
’filenames’ : {},
}
requirements = {
’pis’ : {
’variables’ : [’u’],
’class’ : cb.ShapeDimDim,
},
’corrs_rs’ : {
’requires’ : [’pis’],
’ebcs’ : [’fixed_u’],
’epbcs’ : all_periodic,
’equations’ : equation_corrs,
’set_variables’ : [(’Pi’, ’pis’, ’u’)],
’class’ : cb.CorrDimDim,
’save_name’ : ’corrs_le’,
’dump_variables’ : [’u’, ’p’],
’is_linear’ : True,
},
}
#! Solvers
#! ------#! Define linear and nonlinear solver.
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-4,
})
}
homogenization/perfusion_micro.py
Description
Homogenization of the Darcy flow in a thin porous layer. The reference cell is composed of the matrix representing
the dual porosity and of two disconnected channels representing the primary porosity, see paper [1].
[1] http://seth.asc.tuwien.ac.at/proc12/full_paper/Contribution183.pdf
source code
r"""
Homogenization of the Darcy flow in a thin porous layer.
The reference cell is composed of the matrix representing the dual porosity
and of two disconnected channels representing the primary porosity,
see paper [1].
[1] http://seth.asc.tuwien.ac.at/proc12/full_paper/Contribution183.pdf
"""
from sfepy.discrete.fem.periodic import match_x_plane, match_y_plane
import sfepy.homogenization.coefs_base as cb
5.3. Examples
149
SfePy Documentation, Release 2015.1
import numpy as nm
from sfepy import data_dir
def get_mats(pk, ph, pe, dim):
m1 = nm.eye(dim,
m1[-1,-1] = pk /
m2 = nm.eye(dim,
m2[-1,-1] = pk /
dtype=nm.float64) * pk
ph
dtype=nm.float64) * pk
ph ** 2
return m1, m2
def recovery_perf(pb, corrs, macro):
from sfepy.homogenization.recovery import compute_p_from_macro
from sfepy.base.base import Struct
slev = ’’
micro_coors = pb.domain.mesh.coors
micro_nnod = pb.domain.mesh.n_nod
centre_Y = nm.sum(pb.domain.mesh.coors, axis=0) / micro_nnod
nodes_Y = {}
channels = {}
for k in macro.iterkeys():
if ’press’ in k:
channels[k[-1]] = 1
channels = channels.keys()
varnames = [’pM’]
for ch in channels:
nodes_Y[ch] = pb.domain.regions[’Y’ + ch].vertices
varnames.append(’p’ + ch)
pvars = pb.create_variables(varnames)
press = {}
# matrix
press[’M’] = \
corrs[’corrs_%s_gamma_p’ % pb_def[’name’]][’pM’] * macro[’g_p’] + \
corrs[’corrs_%s_gamma_m’ % pb_def[’name’]][’pM’] * macro[’g_m’]
out = {}
# channels
for ch in channels:
press_mac = macro[’press’ + ch][0,0]
press_mac_grad = macro[’pressg’ + ch]
nnod = corrs[’corrs_%s_pi%s’ % (pb_def[’name’], ch)]\
[’p%s_0’ % ch].shape[0]
press_mic = nm.zeros( (nnod,1) )
for key, val in \
corrs[’corrs_%s_pi%s’ % (pb_def[’name’], ch)].iteritems():
kk = int( key[-1] )
150
Chapter 5. Examples
SfePy Documentation, Release 2015.1
press_mic += val * press_mac_grad[kk,0]
for key in corrs.iterkeys():
if (’_gamma_’ + ch in key):
kk = int(key[-1]) - 1
press_mic += corrs[key][’p’ + ch] * macro[’g’ + ch][kk]
press_mic += \
compute_p_from_macro(press_mac_grad[nm.newaxis,nm.newaxis,:,:],
micro_coors[nodes_Y[ch]], 0,
centre=centre_Y, extdim=-1).reshape((nnod,1))
press[ch] = press_mac + eps0 * press_mic
out[slev + ’p’ + ch] = Struct(name=’output_data’,
mode=’vertex’,
data=press[ch],
var_name=’p’ + ch,
dofs=None)
pvars[’p’ + ch].set_data(press_mic)
dvel = pb.evaluate(’ev_diffusion_velocity.iV.Y%s(mat1%s.k, p%s)’\
% (ch, ch, ch),
var_dict = {’p’ + ch: pvars[’p’ + ch]},
mode=’el_avg’)
out[slev + ’w’ + ch] = Struct(name=’output_data’,
mode=’cell’,
data=dvel,
var_name=’w’ + ch,
dofs=None)
press[’M’] += corrs[’corrs_%s_eta%s’ % (pb_def[’name’], ch)][’pM’]\
* press_mac
pvars[’pM’].set_data(press[’M’])
dvel = pb.evaluate(’%e * ev_diffusion_velocity.iV.YM(mat1M.k, pM)’ % eps0,
var_dict = {’pM’: pvars[’pM’]}, mode=’el_avg’)
out[slev + ’pM’] = Struct(name=’output_data’,
mode=’vertex’,
dat =press[’M’],
var_name=’pM’,
dofs=None)
out[slev + ’wM’] = Struct(name=’output_data’,
mode=’cell’,
data=dvel,
var_name=’wM’,
dofs=None )
return out
geoms = {
’2_4’: [’2_4_Q1’, ’2’, 5],
’3_8’: [’3_8_Q1’, ’4’, 5],
’3_4’: [’3_4_P1’, ’3’, 3],
}
5.3. Examples
151
SfePy Documentation, Release 2015.1
pb_def = {
’name’: ’3d_2ch’,
’mesh_filename’: data_dir + ’/meshes/3d/perfusion_micro3d.mesh’,
’dim’: 3,
’geom’: geoms[’3_4’],
’eps0’: 1.0e-2,
’param_h’: 1.0,
’param_kappa_m’: 0.1,
’matrix_mat_el_grp’: 3,
’channels’: {
’A’: {
’mat_el_grp’: 1,
’fix_nd_grp’: (4, 1),
’io_nd_grp’: [ 1, 2, 3 ],
’param_kappa_ch’: 1.0,
},
’B’: {
’mat_el_grp’: 2,
’fix_nd_grp’: (14, 11),
’io_nd_grp’: [ 11, 12, 13 ],
’param_kappa_ch’: 2.0,
},
},
}
filename_mesh = pb_def[’mesh_filename’]
eps0 = pb_def[’eps0’]
param_h = pb_def[’param_h’]
# integrals
integrals = {
’iV’ : 2,
’iS’ : 2,
}
functions = {
’match_x_plane’: (match_x_plane,),
’match_y_plane’: (match_y_plane,),
}
aux = []
for ch, val in pb_def[’channels’].iteritems():
aux.append( ’r.bYM’ + ch )
# basic regions
regions = {
’Y’: ’all’,
’YM’: ’cells of group %d’ % pb_def[’matrix_mat_el_grp’],
# periodic boundaries
’Pl’: (’vertices in (x < 0.001)’, ’facet’),
’Pr’: (’vertices in (x > 0.999)’, ’facet’),
’PlYM’: (’r.Pl *v r.YM’, ’facet’),
’PrYM’: (’r.Pr *v r.YM’, ’facet’),
’bYMp’: (’r.bYp *v r.YM’, ’facet’, ’YM’),
’bYMm’: (’r.bYm *v r.YM’, ’facet’, ’YM’),
’bYMpm’: (’r.bYMp +v r.bYMm’, ’facet’, ’YM’),
}
152
Chapter 5. Examples
SfePy Documentation, Release 2015.1
# matrix/channel boundaries
regions.update({
’bYMchs’: (’ +v ’.join(aux), ’facet’, ’YM’),
’YMmchs’: ’r.YM -v r.bYMchs’,
})
# boundary conditions Gamma+/ebcs = {
’gamma_pm_bYMchs’: (’bYMchs’, {’pM.0’: 0.0}),
’gamma_pm_YMmchs’: (’YMmchs’, {’pM.0’: 1.0}),
}
# periodic boundary conditions - matrix, X-direction
epbcs = {’periodic_xYM’: ([’PlYM’, ’PrYM’], {’pM.0’: ’pM.0’}, ’match_x_plane’)}
lcbcs = {}
all_periodicYM = [’periodic_%sYM’ % ii for ii in [’x’, ’y’][:pb_def[’dim’]-1] ]
all_periodicY = {}
if pb_def[’dim’] == 2:
regions.update( {
’bYm’: (’vertices in (y < 0.001)’, ’facet’),
’bYp’: (’vertices in (y > 0.999)’, ’facet’),
} )
if pb_def[’dim’] == 3:
regions.update( {
’Pn’: (’vertices in (y < 0.001)’, ’facet’),
’Pf’: (’vertices in (y > 0.999)’, ’facet’),
’PnYM’: (’r.Pn *v r.YM’, ’facet’),
’PfYM’: (’r.Pf *v r.YM’, ’facet’),
’bYm’: (’vertices in (z < 0.001)’, ’facet’),
’bYp’: (’vertices in (z > 0.999)’, ’facet’),
} )
# periodic boundary conditions - matrix, Y-direction
epbcs.update( {
’periodic_yYM’: ([’PnYM’, ’PfYM’], {’pM.0’: ’pM.0’}, ’match_y_plane’),
} )
reg_io = {}
ebcs_eta = {}
ebcs_gamma = {}
# generate regions, ebcs, epbcs
for ch, val in pb_def[’channels’].iteritems():
all_periodicY[ch] = [’periodic_%sY%s’ % (ii, ch)\
for ii in [’x’, ’y’][:pb_def[’dim’]-1] ]
# channels: YA, fixedYA, bYMA (matrix/channel boundaries)
regions.update( {
’Y’ + ch: ’cells of group %d’ % val[’mat_el_grp’],
’bYM’ + ch: (’r.YM *v r.Y’ + ch, ’facet’, ’YM’),
’PlY’ + ch: (’r.Pl *v r.Y’ + ch, ’facet’),
’PrY’ + ch: (’r.Pr *v r.Y’ + ch, ’facet’),
} )
if ’fix_nd_grp’ in val:
regions.update({
5.3. Examples
153
SfePy Documentation, Release 2015.1
’fixedY’ + ch: (’vertices of group %d’ % val[’fix_nd_grp’][0],
’vertex’),
})
ebcs_eta[ch] = []
for ch2, val2 in pb_def[’channels’].iteritems():
aux = ’eta%s_bYM%s’ % (ch, ch2)
if ch2 == ch:
ebcs.update( {aux: (’bYM’ + ch2, {’pM.0’: 1.0})} )
else:
ebcs.update( {aux: (’bYM’ + ch2, {’pM.0’: 0.0})} )
ebcs_eta[ch].append(aux)
# boundary conditions
# periodic boundary conditions - channels, X-direction
epbcs.update({
’periodic_xY’ + ch: ([’PlY’ + ch, ’PrY’ + ch],
{’p%s.0’ % ch: ’p%s.0’ % ch},
’match_x_plane’),
})
if pb_def[’dim’] == 3:
regions.update({
’PnY’ + ch: (’r.Pn *v r.Y’ + ch, ’facet’),
’PfY’ + ch: (’r.Pf *v r.Y’ + ch, ’facet’),
})
# periodic boundary conditions - channels, Y-direction
epbcs.update({
’periodic_yY’ + ch: ([’PnY’ + ch, ’PfY’ + ch],
{’p%s.0’ % ch: ’p%s.0’ % ch},
’match_y_plane’),
})
reg_io[ch] = []
aux_bY = []
# channel: inputs/outputs
for i_io in range( len( val[’io_nd_grp’] ) ):
io = ’%s_%d’ % (ch, i_io+1)
# regions
aux = val[’io_nd_grp’][i_io]
if ’fix_nd_grp’ in val and val[’fix_nd_grp’][1] == aux:
regions.update( {
’bY%s’ % io : (’vertices of group %d +v r.fixedY%s’ % (aux, ch),
’facet’, ’Y%s’ % ch),
} )
else:
regions.update( {
’bY%s’ % io : (’vertices of group %d’ % aux,
’facet’, ’Y%s’ % ch),
} )
aux_bY.append(’r.bY%s’ % io)
reg_io[ch].append(’bY%s’ % io)
regions.update({
’bY’ + ch : (’ +v ’.join(aux_bY), ’facet’, ’Y’ + ch),
154
Chapter 5. Examples
SfePy Documentation, Release 2015.1
})
# channel: inputs/outputs
for i_io in range( len( val[’io_nd_grp’] ) ):
io = ’%s_%d’ % (ch, i_io + 1)
ion = ’%s_n%d’ % (ch, i_io + 1)
regions.update({
’bY%s’ % ion: (’r.bY%s -v r.bY%s’ % (ch, io), ’facet’, ’Y%s’ % ch),
})
# boundary conditions
aux = ’fix_p%s_bY%s’ % (ch, ion)
ebcs.update({
aux: (’bY%s’ % ion, {’p%s.0’ % ch: 0.0}),
})
lcbcs.update({
’imv’ + ch: (’Y’ + ch, {’ls%s.all’ % ch: None}, None,
’integral_mean_value’)
})
###########################################################################
# materials, fields, variables, integrals
matk1, matk2 = get_mats(pb_def[’param_kappa_m’], param_h, eps0, pb_def[’dim’])
materials = {
’mat1M’: ({’k’: matk1},),
’mat2M’: ({’k’: matk2},),
}
fields = {
’corrector_M’: (’real’, ’scalar’, ’YM’, 1),
’vel_M’: (’real’, ’vector’, ’YM’, 1),
’vol_all’: (’real’, ’scalar’, ’Y’, 1),
}
variables = {
’pM’: (’unknown field’, ’corrector_M’),
’qM’: (’test field’, ’corrector_M’, ’pM’),
’Pi_M’: (’parameter field’, ’corrector_M’, ’(set-to-None)’),
’corr_M’: (’parameter field’, ’corrector_M’, ’(set-to-None)’),
’corr1_M’: (’parameter field’, ’corrector_M’, ’(set-to-None)’),
’corr2_M’: (’parameter field’, ’corrector_M’, ’(set-to-None)’),
’wM’: (’parameter field’, ’vel_M’, ’(set-to-None)’),
’vol_all’: (’parameter field’, ’vol_all’, ’(set-to-None)’),
}
# generate regions for channel inputs/outputs
for ch, val in pb_def[’channels’].iteritems():
matk1, matk2 = get_mats(val[’param_kappa_ch’],
eps0, pb_def[’dim’])
materials.update({
’mat1’ + ch: ({’k’: matk1},),
’mat2’ + ch: ({’k’: matk2},),
})
5.3. Examples
param_h,
155
SfePy Documentation, Release 2015.1
fields.update({
’corrector_’ + ch: (’real’, ’scalar’, ’Y’ + ch, 1),
’vel_’ + ch: (’real’, ’vector’, ’Y’ + ch, 1),
})
variables.update({
’p’ + ch: (’unknown field’, ’corrector_’ + ch),
’q’ + ch: (’test field’, ’corrector_’ + ch, ’p’ + ch),
’Pi_’ + ch: (’parameter field’, ’corrector_’ + ch, ’(set-to-None)’),
’corr1_’ + ch: (’parameter field’, ’corrector_’ + ch, ’(set-to-None)’),
’corr2_’ + ch: (’parameter field’, ’corrector_’ + ch, ’(set-to-None)’),
’w’ + ch: (’unknown field’, ’vel_’ + ch),
# lagrange mutltipliers - integral mean value
’ls’ + ch: (’unknown field’, ’corrector_’ + ch),
’lv’ + ch: (’test field’, ’corrector_’ + ch, ’ls’ + ch),
})
###########################################################################
options = {
’coefs’: ’coefs’,
’requirements’: ’requirements’,
’ls’: ’ls’, # linear solver to use
’volumes’: {
’total’: {
’variables’: [’vol_all’],
’expression’: """d_volume.iV.Y(vol_all)""",
},
’one’: {
’value’: 1.0,
}
},
’output_dir’: ’./output’,
’file_per_var’: True,
’coefs_filename’: ’coefs_perf_’ + pb_def[’name’],
’coefs_info’: {’eps0’: eps0},
’recovery_hook’: ’recovery_perf’,
}
for ipm in [’p’, ’m’]:
options[’volumes’].update({
’bYM’ + ipm: {
’variables’: [’pM’],
’expression’: "d_surface.iS.bYM%s(pM)" % ipm,
},
’bY’ + ipm: {
’variables’: [’vol_all’],
’expression’: "d_surface.iS.bY%s(vol_all)" % ipm,
}
})
for ch in reg_io.iterkeys():
for ireg in reg_io[ch]:
options[’volumes’].update({
ireg: {
’variables’: [’p’ + ch],
’expression’: "d_surface.iS.%s(p%s)" % (ireg, ch),
}
156
Chapter 5. Examples
SfePy Documentation, Release 2015.1
})
###########################################################################
# equations, correctors, coefficients
coefs = {
’vol_bYMpm’: {
’regions’: [’bYMp’, ’bYMm’],
’expression’: ’d_surface.iS.%s(pM)’,
’class’: cb.VolumeFractions,
},
’filenames’: {},
}
# requirements for perfusion homog. coefficients
requirements = {
’corrs_one_YM’: {
’variable’: [’pM’],
’ebcs’: [’gamma_pm_YMmchs’, ’gamma_pm_bYMchs’],
’epbcs’: [],
’save_name’: ’corrs_one_YM’,
’class’: cb.CorrSetBCS,
’dump_variables’: [’pM’],
},
}
for ipm in [’p’, ’m’]:
requirements.update({
’corrs_gamma_’ + ipm: {
’requires’: [],
’ebcs’: [’gamma_pm_bYMchs’],
’epbcs’: all_periodicYM,
’equations’: {
’eq_gamma_pm’: """dw_diffusion.iV.YM(mat2M.k, qM, pM) =
%e * dw_surface_integrate.iS.bYM%s(qM)"""\
% (1.0/param_h, ipm),
},
’class’: cb.CorrOne,
’save_name’: ’corrs_%s_gamma_%s’ % (pb_def[’name’], ipm),
’dump_variables’: [’pM’],
},
})
for ipm2 in [’p’, ’m’]:
coefs.update({
’H’ + ipm + ipm2: { # test+
’requires’: [’corrs_gamma_’ + ipm],
’set_variables’: [(’corr_M’, ’corrs_gamma_’ + ipm, ’pM’)],
’expression’: ’ev_surface_integrate.iS.bYM%s(corr_M)’ % ipm2,
’set_volume’: ’bYp’,
’class’: cb.CoefOne,
},
})
def get_channel(keys, bn):
for ii in keys:
if bn in ii:
return ii[(ii.rfind(bn) + len(bn)):]
5.3. Examples
157
SfePy Documentation, Release 2015.1
return None
def set_corrpis(variables, ir, ic, mode, **kwargs):
ch = get_channel(kwargs.keys(), ’pis_’)
pis = kwargs[’pis_’ + ch]
corrs_pi = kwargs[’corrs_pi’ + ch]
if mode == ’row’:
val = pis.states[ir][’p’ + ch] + corrs_pi.states[ir][’p’ + ch]
variables[’corr1_’ + ch].set_data(val)
elif mode == ’col’:
val = pis.states[ic][’p’ + ch] + corrs_pi.states[ic][’p’ + ch]
variables[’corr2_’ + ch].set_data(val)
def set_corr_S(variables, ir, **kwargs):
ch = get_channel(kwargs.keys(), ’pis_’)
io = get_channel(kwargs.keys(), ’corrs_gamma_’)
pis = kwargs[’pis_’ + ch]
corrs_gamma = kwargs[’corrs_gamma_’ + io]
pi = pis.states[ir][’p’ + ch]
val = corrs_gamma.state[’p’ + ch]
variables[’corr1_’ + ch].set_data(pi)
variables[’corr2_’ + ch].set_data(val)
def set_corr_cc(variables, ir, **kwargs):
ch = get_channel(kwargs.keys(), ’pis_’)
pis = kwargs[’pis_’ + ch]
corrs_pi = kwargs[’corrs_pi’ + ch]
pi = pis.states[ir][’p’ + ch]
pi = pi - nm.mean(pi)
val = pi + corrs_pi.states[ir][’p’ + ch]
variables[’corr1_’ + ch].set_data(val)
for ch, val in pb_def[’channels’].iteritems():
coefs.update({
’G’ + ch: { # test+
’requires’: [’corrs_one’ + ch, ’corrs_eta’ + ch],
’set_variables’: [(’corr1_M’, ’corrs_one’ + ch, ’pM’),
(’corr2_M’, ’corrs_eta’ + ch, ’pM’)],
’expression’: ’dw_diffusion.iV.YM(mat2M.k, corr1_M, corr2_M)’,
’class’: cb.CoefOne,
},
’K’ + ch: { # test+
’requires’: [’pis_’ + ch, ’corrs_pi’ + ch],
’set_variables’: set_corrpis,
’expression’: ’dw_diffusion.iV.Y%s(mat2%s.k, corr1_%s, corr2_%s)’\
% ((ch,) * 4),
’dim’: pb_def[’dim’] - 1,
’class’: cb.CoefDimDim,
},
})
requirements.update({
’pis_’ + ch: {
158
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’variables’: [’p’ + ch],
’class’: cb.ShapeDim,
},
’corrs_one’ + ch: {
’variable’: [’pM’],
’ebcs’: ebcs_eta[ch],
’epbcs’: [],
’save_name’: ’corrs_%s_one%s’ % (pb_def[’name’], ch),
’dump_variables’: [’pM’],
’class’: cb.CorrSetBCS,
},
’corrs_eta’ + ch: {
’ebcs’: ebcs_eta[ch],
’epbcs’: all_periodicYM,
’equations’: {
’eq_eta’: ’dw_diffusion.iV.YM(mat2M.k, qM, pM) = 0’,
},
’class’: cb.CorrOne,
’save_name’: ’corrs_%s_eta%s’ % (pb_def[’name’], ch),
’dump_variables’: [’pM’],
},
’corrs_pi’ + ch: {
’requires’: [’pis_’ + ch],
’set_variables’: [(’Pi_’ + ch, ’pis_’ + ch, ’p’ + ch)],
’ebcs’: [],
’epbcs’: all_periodicY[ch],
’lcbcs’: [’imv’ + ch],
’equations’: {
’eq_pi’: """dw_diffusion.iV.Y%s(mat2%s.k, q%s, p%s)
+ dw_volume_dot.iV.Y%s(q%s, ls%s)
= - dw_diffusion.iV.Y%s(mat2%s.k, q%s, Pi_%s)"""\
% ((ch,) * 11),
’eq_imv’: ’dw_volume_dot.iV.Y%s(lv%s, p%s) = 0’ % ((ch,) * 3),
},
’dim’: pb_def[’dim’] - 1,
’class’: cb.CorrDim,
’save_name’: ’corrs_%s_pi%s’ % (pb_def[’name’], ch),
’dump_variables’: [’p’ + ch],
},
})
for ipm in [’p’, ’m’]:
coefs.update({
’E’ + ipm + ch: { # test+
’requires’: [’corrs_eta’ + ch],
’set_variables’: [(’corr_M’, ’corrs_eta’ + ch, ’pM’)],
’expression’: ’ev_surface_integrate.iS.bYM%s(corr_M)’ % ipm,
’set_volume’: ’bYp’,
’class’: cb.CoefOne,
},
’F’ + ipm + ch: { # test+
’requires’: [’corrs_one’ + ch, ’corrs_gamma_’ + ipm],
’set_variables’: [(’corr1_M’, ’corrs_one’ + ch, ’pM’),
(’corr2_M’, ’corrs_gamma_’ + ipm, ’pM’)],
’expression’: """dw_diffusion.iV.YM(mat2M.k, corr1_M, corr2_M)
- %e * ev_surface_integrate.iS.bYM%s(corr1_M)"""\
% (1.0/param_h, ipm),
’class’: cb.CoefOne,
5.3. Examples
159
SfePy Documentation, Release 2015.1
},
})
for i_io in range(len(val[’io_nd_grp’])):
io = ’%s_%d’ % (ch, i_io + 1)
coefs.update({
’S’ + io: { # [Rohan1] (4.28), test+
’requires’: [’corrs_gamma_’ + io, ’pis_’ + ch],
’set_variables’: set_corr_S,
’expression’: ’dw_diffusion.iV.Y%s(mat2%s.k,corr1_%s,corr2_%s)’\
% ((ch,) * 4),
’dim’: pb_def[’dim’] - 1,
’class’: cb.CoefDim,
},
’P’ + io: { # test+
’requires’: [’pis_’ + ch, ’corrs_pi’ + ch],
’set_variables’: set_corr_cc,
’expression’: ’ev_surface_integrate.iS.bY%s(corr1_%s)’\
% (io, ch),
’set_volume’: ’bYp’,
’dim’: pb_def[’dim’] - 1,
’class’: cb.CoefDim,
},
’S_test’ + io: {
’requires’: [’corrs_pi’ + ch],
’set_variables’: [(’corr1_’ + ch, ’corrs_pi’ + ch, ’p’ + ch)],
’expression’: ’%e * ev_surface_integrate.iS.bY%s(corr1_%s)’\
% (1.0 / param_h, io, ch),
’dim’: pb_def[’dim’] - 1,
’class’: cb.CoefDim,
},
})
requirements.update({
’corrs_gamma_’ + io: {
’requires’: [],
’variables’: [’p’ + ch, ’q’ + ch],
’ebcs’: [],
’epbcs’: all_periodicY[ch],
’lcbcs’: [’imv’ + ch],
’equations’: {
’eq_gamma’: """dw_diffusion.iV.Y%s(mat2%s.k, q%s, p%s)
+ dw_volume_dot.iV.Y%s(q%s, ls%s)
= %e * dw_surface_integrate.iS.bY%s(q%s)"""\
% ((ch,) * 7 + (1.0/param_h, io, ch)),
’eq_imv’: ’dw_volume_dot.iV.Y%s(lv%s, p%s) = 0’\
% ((ch,) * 3),
},
’class’: cb.CorrOne,
’save_name’: ’corrs_%s_gamma_%s’ % (pb_def[’name’], io),
’dump_variables’: [’p’ + ch],
},
})
for i_io2 in range(len(val[’io_nd_grp’])):
io2 = ’%s_%d’ % (ch, i_io2 + 1)
io12 = ’%s_%d’ % (io, i_io2 + 1)
160
Chapter 5. Examples
SfePy Documentation, Release 2015.1
coefs.update({
’R’ + io12: { # test+
’requires’: [’corrs_gamma_’ + io2],
’set_variables’: [(’corr1_’ + ch, ’corrs_gamma_’ + io2,
’p’ + ch)],
’expression’: ’ev_surface_integrate.iS.bY%s(corr1_%s)’\
% (io, ch),
’set_volume’: ’bYp’,
’class’: cb.CoefOne,
},
})
###########################################################################
# solver, fe
solvers = {
’ls’: (’ls.scipy_direct’, {}),
’newton’: (’nls.newton’, {
’i_max’: 1,
})
}
fe = {
’chunk_size’: 1000
}
# [Rohan1] Rohan E.: HOMOGENIZATION OF THE DARCY FLOW IN A DOUBLE-POROUS LAYER
5.3.5 large_deformation
large_deformation/active_fibres.py
Description
Nearly incompressible hyperelastic material model with active fibres.
Large deformation is described using the total Lagrangian formulation. Models of this kind can be used in biomechanics to model biological tissues, e.g. muscles.
Find 𝑢 such that:
∫︁ (︁
)︁
𝑆 eff (𝑢) + 𝐾(𝐽 − 1) 𝐽𝐶 −1 : 𝛿𝐸(𝑣) d𝑉 = 0 ,
∀𝑣 ,
Ω(0)
where
𝐹
𝐽
𝐶
𝐸(𝑢)
𝜕𝑥𝑖
deformation gradient 𝐹𝑖𝑗 = 𝜕𝑋
𝑗
det(𝐹 )
right Cauchy-Green deformation tensor 𝐶 = 𝐹 𝑇 𝐹
𝜕𝑢
𝜕𝑢𝑖
𝑚 𝜕𝑢𝑚
Green strain tensor 𝐸𝑖𝑗 = 12 ( 𝜕𝑥
+ 𝜕𝑥𝑗𝑖 + 𝜕𝑢
𝜕𝑥𝑖 𝜕𝑥𝑗 )
𝑗
𝑆 eff (𝑢)
effective second Piola-Kirchhoff stress tensor
5.3. Examples
161
SfePy Documentation, Release 2015.1
The effective stress 𝑆 eff (𝑢) incorporates also the effects of the active fibres in two preferential directions:
2
2
𝑆 eff (𝑢) = 𝜇𝐽 − 3 (𝐼 −
∑︁
1
tr(𝐶)𝐶 −1 ) +
𝜏 𝑘 𝜔𝑘 .
3
𝑘=1
The first term is the neo-Hookean term and the sum add contributions of the two fibre systems. The tensors 𝜔 𝑘 = 𝑑𝑘 𝑑𝑘
are defined by the fibre system direction vectors 𝑑𝑘 (unit).
For the one-dimensional tensions 𝜏 𝑘 holds simply (𝑘 omitted):
{︂
}︂
𝜖 − 𝜀opt 2
𝜏 = 𝐴𝑓max exp −(
) ,𝜖=𝐸 :𝜔.
𝑠
source code
# -*- coding: utf-8 -*r"""
Nearly incompressible hyperelastic material model with active fibres.
Large deformation is described using the total Lagrangian formulation.
Models of this kind can be used in biomechanics to model biological
tissues, e.g. muscles.
Find :math:‘\ul{u}‘ such that:
.. math::
\intl{\Omega\suz}{} \left( \ull{S}\eff(\ul{u})
162
Chapter 5. Examples
SfePy Documentation, Release 2015.1
+ K(J-1)\; J \ull{C}^{-1} \right) : \delta \ull{E}(\ul{v}) \difd{V}
= 0
\;, \quad \forall \ul{v} \;,
where
.. list-table::
:widths: 20 80
* * * * -
:math:‘\ull{F}‘
deformation gradient :math:‘F_{ij} = \pdiff{x_i}{X_j}‘
:math:‘J‘
:math:‘\det(F)‘
:math:‘\ull{C}‘
right Cauchy-Green deformation tensor :math:‘C = F^T F‘
:math:‘\ull{E}(\ul{u})‘
Green strain tensor :math:‘E_{ij} = \frac{1}{2}(\pdiff{u_i}{x_j} +
\pdiff{u_j}{x_i} + \pdiff{u_m}{x_i}\pdiff{u_m}{x_j})‘
* - :math:‘\ull{S}\eff(\ul{u})‘
- effective second Piola-Kirchhoff stress tensor
The effective stress :math:‘\ull{S}\eff(\ul{u})‘ incorporates also the
effects of the active fibres in two preferential directions:
.. math::
\ull{S}\eff(\ul{u}) = \mu J^{-\frac{2}{3}}(\ull{I}
- \frac{1}{3}\tr(\ull{C}) \ull{C}^{-1})
+ \sum_{k=1}^2 \tau^k \ull{\omega}^k
\;.
The first term is the neo-Hookean term and the sum add contributions of
the two fibre systems. The tensors :math:‘\ull{\omega}^k =
\ul{d}^k\ul{d}^k‘ are defined by the fibre system direction vectors
:math:‘\ul{d}^k‘ (unit).
For the one-dimensional tensions :math:‘\tau^k‘ holds simply (:math:‘^k‘
omitted):
.. math::
\tau = A f_{\rm max} \exp{\left\{-(\frac{\epsilon - \varepsilon_{\rm
opt}}{s})^2\right\}} \mbox{ , } \epsilon = \ull{E} : \ull{\omega}
\;.
"""
import numpy as nm
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
vf_matrix = 0.5
vf_fibres1 = 0.2
vf_fibres2 = 0.3
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
5.3. Examples
163
SfePy Documentation, Release 2015.1
’post_process_hook’ : ’stress_strain’,
}
fields = {
’displacement’: (nm.float64, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’K’ : vf_matrix * 1e3, # bulk modulus
’mu’ : vf_matrix * 20e0, # shear modulus of neoHookean term
},),
’f1’ : ’get_pars_fibres1’,
’f2’ : ’get_pars_fibres2’,
}
def get_pars_fibres(ts, coors, mode=None, which=0, vf=1.0, **kwargs):
"""
Parameters
---------ts : TimeStepper
Time stepping info.
coors : array_like
The physical domain coordinates where the parameters shound be defined.
mode : ’qp’ or ’special’
Call mode.
which : int
Fibre system id.
vf : float
Fibre system volume fraction.
"""
if mode != ’qp’: return
fmax = 10.0
eps_opt = 0.01
s = 1.0
tt = ts.nt * 2.0 * nm.pi
if which == 0: # system 1
fdir = nm.array([1.0, 0.0, 0.0], dtype=nm.float64)
act = 0.5 * (1.0 + nm.sin(tt - (0.5 * nm.pi)))
elif which == 1: # system 2
fdir = nm.array([0.0, 1.0, 0.0], dtype=nm.float64)
act = 0.5 * (1.0 + nm.sin(tt + (0.5 * nm.pi)))
else:
raise ValueError(’unknown fibre system! (%d)’ % which)
fdir.shape = (3, 1)
fdir /= nm.linalg.norm(fdir)
print act
shape = (coors.shape[0], 1, 1)
out = {
164
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’fmax’ : vf * nm.tile(fmax, shape),
’eps_opt’ : nm.tile(eps_opt, shape),
’s’ : nm.tile(s, shape),
’fdir’ : nm.tile(fdir, shape),
’act’ : nm.tile(act, shape),
}
return out
functions = {
’get_pars_fibres1’ : (lambda ts, coors, mode=None, **kwargs:
get_pars_fibres(ts, coors, mode=mode, which=0,
vf=vf_fibres1, **kwargs),),
’get_pars_fibres2’ : (lambda ts, coors, mode=None, **kwargs:
get_pars_fibres(ts, coors, mode=mode, which=1,
vf=vf_fibres2, **kwargs),),
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
##
# Dirichlet BC.
ebcs = {
’l’ : (’Left’, {’u.all’ : 0.0}),
}
##
# Balance of forces.
integral_1 = {
’name’ : ’i’,
’order’ : 1,
}
equations = {
’balance’
: """dw_tl_he_neohook.i.Omega( solid.mu, v, u )
+ dw_tl_bulk_penalty.i.Omega( solid.K, v, u )
+ dw_tl_fib_a.i.Omega( f1.fmax, f1.eps_opt, f1.s, f1.fdir, f1.act,
v, u )
+ dw_tl_fib_a.i.Omega( f2.fmax, f2.eps_opt, f2.s, f2.fdir, f2.act,
v, u )
= 0""",
}
def stress_strain(out, problem, state, extend=False):
from sfepy.base.base import Struct, debug
ev = problem.evaluate
strain = ev(’dw_tl_he_neohook.i.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’strain’)
5.3. Examples
165
SfePy Documentation, Release 2015.1
out[’green_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain, dofs=None)
stress = ev(’dw_tl_he_neohook.i.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’neohook_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None )
stress = ev(’dw_tl_bulk_penalty.i.Omega( solid.K, v, u )’,
mode=’el_avg’, term_mode= ’stress’)
out[’bulk_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
return out
##
# Solvers etc.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
:
’eps_a’
:
’eps_r’
:
’macheps’
:
’lin_red’
:
’ls_red’
:
’ls_red_warp’:
’ls_on’
:
’ls_min’
:
’check’
:
’delta’
:
7,
1e-10,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
0.1,
0.001,
1.1,
1e-5,
0,
1e-6,
}
solver_2 = {
’name’ : ’ts’,
’kind’ : ’ts.simple’,
’t0’
: 0,
’t1’
: 1,
’dt’
: None,
’n_step’ : 21, # has precedence over dt!
}
large_deformation/hyperelastic.py
Description
Nearly incompressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the total Lagrangian formulation. Models of this kind can be used to model e.g.
rubber or some biological materials.
166
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Find 𝑢 such that:
∫︁ (︁
)︁
𝑆 eff (𝑢) + 𝐾(𝐽 − 1) 𝐽𝐶 −1 : 𝛿𝐸(𝑣) d𝑉 = 0 ,
∀𝑣 ,
Ω(0)
where
𝐹
𝐽
𝐶
𝐸(𝑢)
𝜕𝑥𝑖
deformation gradient 𝐹𝑖𝑗 = 𝜕𝑋
𝑗
det(𝐹 )
right Cauchy-Green deformation tensor 𝐶 = 𝐹 𝑇 𝐹
𝜕𝑢
𝜕𝑢𝑖
𝑚 𝜕𝑢𝑚
+ 𝜕𝑥𝑗𝑖 + 𝜕𝑢
Green strain tensor 𝐸𝑖𝑗 = 12 ( 𝜕𝑥
𝜕𝑥𝑖 𝜕𝑥𝑗 )
𝑗
𝑆 eff (𝑢)
effective second Piola-Kirchhoff stress tensor
The effective stress 𝑆 eff (𝑢) is given by:
2
𝑆 eff (𝑢) = 𝜇𝐽 − 3 (𝐼 −
4
1
2
tr(𝐶)𝐶 −1 ) + 𝜅𝐽 − 3 (tr(𝐶𝐼 − 𝐶 − ((tr 𝐶)2 − tr (𝐶 2 ))𝐶 −1 ) .
3
6
source code
# -*- coding: utf-8 -*r"""
Nearly incompressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the total Lagrangian formulation.
Models of this kind can be used to model e.g. rubber or some biological
5.3. Examples
167
SfePy Documentation, Release 2015.1
materials.
Find :math:‘\ul{u}‘ such that:
.. math::
\intl{\Omega\suz}{} \left( \ull{S}\eff(\ul{u})
+ K(J-1)\; J \ull{C}^{-1} \right) : \delta \ull{E}(\ul{v}) \difd{V}
= 0
\;, \quad \forall \ul{v} \;,
where
.. list-table::
:widths: 20 80
* * * * -
:math:‘\ull{F}‘
deformation gradient :math:‘F_{ij} = \pdiff{x_i}{X_j}‘
:math:‘J‘
:math:‘\det(F)‘
:math:‘\ull{C}‘
right Cauchy-Green deformation tensor :math:‘C = F^T F‘
:math:‘\ull{E}(\ul{u})‘
Green strain tensor :math:‘E_{ij} = \frac{1}{2}(\pdiff{u_i}{x_j} +
\pdiff{u_j}{x_i} + \pdiff{u_m}{x_i}\pdiff{u_m}{x_j})‘
* - :math:‘\ull{S}\eff(\ul{u})‘
- effective second Piola-Kirchhoff stress tensor
The effective stress :math:‘\ull{S}\eff(\ul{u})‘ is given by:
.. math::
\ull{S}\eff(\ul{u}) = \mu J^{-\frac{2}{3}}(\ull{I}
- \frac{1}{3}\tr(\ull{C}) \ull{C}^{-1})
+ \kappa J^{-\frac{4}{3}} (\tr(\ull{C}\ull{I} - \ull{C}
- \frac{2}{6}((\tr{\ull{C}})^2 - \tr{(\ull{C}^2)})\ull{C}^{-1})
\;.
"""
import numpy as nm
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
’post_process_hook’ : ’stress_strain’,
}
field_1 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : 3,
’region’ : ’Omega’,
’approx_order’ : 1,
}
168
Chapter 5. Examples
SfePy Documentation, Release 2015.1
material_1 = {
’name’ : ’solid’,
’values’ : {
’K’ : 1e3, # bulk modulus
’mu’ : 20e0, # shear modulus of neoHookean term
’kappa’ : 10e0, # shear modulus of Mooney-Rivlin term
}
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
##
# Dirichlet BC + related functions.
ebcs = {
’l’ : (’Left’, {’u.all’ : 0.0}),
’r’ : (’Right’, {’u.0’ : 0.0, ’u.[1,2]’ : ’rotate_yz’}),
}
centre = nm.array( [0, 0], dtype = nm.float64 )
def rotate_yz(ts, coor, **kwargs):
from sfepy.linalg import rotation_matrix2d
vec = coor[:,1:3] - centre
angle = 10.0 * ts.step
print ’angle:’, angle
mtx = rotation_matrix2d( angle )
vec_rotated = nm.dot( vec, mtx )
displacement = vec_rotated - vec
return displacement.T.flat
functions = {
’rotate_yz’ : (rotate_yz,),
}
def stress_strain( out, problem, state, extend = False ):
from sfepy.base.base import Struct, debug
ev = problem.evaluate
strain = ev(’dw_tl_he_neohook.i.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’strain’)
out[’green_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain, dofs=None)
stress = ev(’dw_tl_he_neohook.i.Omega( solid.mu, v, u )’,
5.3. Examples
169
SfePy Documentation, Release 2015.1
mode=’el_avg’, term_mode=’stress’)
out[’neohook_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_tl_he_mooney_rivlin.i.Omega( solid.kappa, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’mooney_rivlin_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_tl_bulk_penalty.i.Omega( solid.K, v, u )’,
mode=’el_avg’, term_mode= ’stress’)
out[’bulk_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
return out
##
# Balance of forces.
integral_1 = {
’name’ : ’i’,
’order’ : 1,
}
equations = {
’balance’ : """dw_tl_he_neohook.i.Omega( solid.mu, v, u )
+ dw_tl_he_mooney_rivlin.i.Omega( solid.kappa, v, u )
+ dw_tl_bulk_penalty.i.Omega( solid.K, v, u )
= 0""",
}
##
# Solvers etc.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
:
’eps_a’
:
’eps_r’
:
’macheps’
:
’lin_red’
:
’ls_red’
:
’ls_red_warp’:
’ls_on’
:
’ls_min’
:
’check’
:
’delta’
:
5,
1e-10,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
0.1,
0.001,
1.1,
1e-5,
0,
1e-6,
}
solver_2 = {
’name’ : ’ts’,
’kind’ : ’ts.simple’,
’t0’
170
: 0,
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’t1’
: 1,
’dt’
: None,
’n_step’ : 11, # has precedence over dt!
}
large_deformation/hyperelastic_ul.py
Description
Nearly incompressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the updated Lagrangian formulation. Models of this kind can be used to model
e.g. rubber or some biological materials.
source code
# -*- coding: utf-8 -*r"""
Nearly incompressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the updated Lagrangian formulation.
Models of this kind can be used to model e.g. rubber or some biological
materials.
"""
import numpy as nm
from sfepy import data_dir
5.3. Examples
171
SfePy Documentation, Release 2015.1
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
options = {
’nls’: ’newton’,
’ls’: ’ls’,
’ts’: ’ts’,
’ulf’: True,
’mesh_update_variables’: [’u’],
’output_dir’: ’output’,
’post_process_hook’: ’stress_strain’,
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’: ({’K’: 1e3, # bulk modulus
’mu’: 20e0, # shear modulus of neoHookean term
’kappa’: 10e0, # shear modulus of Mooney-Rivlin term
},),
}
variables = {
’u’: (’unknown field’, ’displacement’, 0),
’v’: (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
##
# Dirichlet BC + related functions.
ebcs = {
’l’ : (’Left’, {’u.all’ : 0.0}),
’r’ : (’Right’, {’u.0’ : 0.0, ’u.[1,2]’ : ’rotate_yz’}),
}
centre = nm.array( [0, 0], dtype = nm.float64 )
def rotate_yz(ts, coor, **kwargs):
from sfepy.linalg import rotation_matrix2d
vec = coor[:,1:3] - centre
angle = 10.0 * ts.step
print ’angle:’, angle
mtx = rotation_matrix2d( angle )
vec_rotated = nm.dot( vec, mtx )
displacement = vec_rotated - vec
return displacement.T.flat
172
Chapter 5. Examples
SfePy Documentation, Release 2015.1
functions = {
’rotate_yz’ : (rotate_yz,),
}
def stress_strain( out, problem, state, extend = False ):
from sfepy.base.base import Struct
ev = problem.evaluate
strain = ev(’dw_ul_he_neohook.3.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’strain’)
out[’green_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain, dofs=None)
stress = ev(’dw_ul_he_neohook.3.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’neohook_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_ul_he_mooney_rivlin.3.Omega( solid.kappa, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’mooney_rivlin_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_ul_bulk_penalty.3.Omega( solid.K, v, u )’,
mode=’el_avg’, term_mode= ’stress’)
out[’bulk_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
return out
equations = {
’balance’: """dw_ul_he_neohook.3.Omega( solid.mu, v, u )
+ dw_ul_he_mooney_rivlin.3.Omega(solid.kappa, v, u)
+ dw_ul_bulk_penalty.3.Omega( solid.K, v, u )
= 0""",
}
##
# Solvers etc.
solvers = {
’ls’: (’ls.scipy_direct’, {}),
’newton’: (’nls.newton’, {
’i_max’: 25,
’eps_a’: 1e-8,
’eps_r’: 1.0,
’macheps’: 1e-16,
’lin_red’: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’: 0.1,
’ls_red_warp’: 0.001,
’ls_on’: 1.1,
’ls_min’: 1e-5,
’check’: 0,
’delta’: 1e-6,
}),
’ts’: (’ts.simple’, {
’t0’: 0,
’t1’: 1,
’dt’: None,
5.3. Examples
173
SfePy Documentation, Release 2015.1
’n_step’: 11, # has precedence over dt!
}),
}
large_deformation/hyperelastic_ul_up.py
Description
Compressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the updated Lagrangian formulation. Incompressibility is treated by mixed
displacement-pressure formulation. Models of this kind can be used to model e.g. rubber or some biological materials.
source code
# -*- coding: utf-8 -*r"""
Compressible Mooney-Rivlin hyperelastic material model.
Large deformation is described using the updated Lagrangian formulation.
Incompressibility is treated by mixed displacement-pressure formulation.
Models of this kind can be used to model e.g. rubber or some biological
materials.
"""
import numpy as nm
from sfepy import data_dir
174
Chapter 5. Examples
SfePy Documentation, Release 2015.1
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
options = {
’nls’: ’newton’,
’ls’: ’ls’,
’ts’: ’ts’,
’ulf’: True,
’mesh_update_variables’: [’u’],
’output_dir’: ’output’,
’post_process_hook’: ’stress_strain’,
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
’pressure’: (’real’, ’scalar’, ’Omega’, 0),
}
materials = {
’solid’: ({’iK’: 1.0 / 1e3, # bulk modulus
’mu’: 20e0, # shear modulus of neoHookean term
’kappa’: 10e0, # shear modulus of Mooney-Rivlin term
},),
}
variables = {
’u’: (’unknown field’, ’displacement’, 0),
’v’: (’test field’, ’displacement’, ’u’),
’p’: (’unknown field’, ’pressure’, 1),
’q’: (’test field’, ’pressure’, ’p’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
##
# Dirichlet BC + related functions.
ebcs = {
’l’ : (’Left’, {’u.all’ : 0.0}),
’r’ : (’Right’, {’u.0’ : 0.0, ’u.[1,2]’ : ’rotate_yz’}),
}
centre = nm.array( [0, 0], dtype = nm.float64 )
def rotate_yz(ts, coor, **kwargs):
from sfepy.linalg import rotation_matrix2d
vec = coor[:,1:3] - centre
angle = 10.0 * ts.step
print ’angle:’, angle
mtx = rotation_matrix2d( angle )
vec_rotated = nm.dot( vec, mtx )
displacement = vec_rotated - vec
5.3. Examples
175
SfePy Documentation, Release 2015.1
return displacement.T.flat
functions = {
’rotate_yz’ : (rotate_yz,),
}
def stress_strain( out, problem, state, extend = False ):
from sfepy.base.base import Struct
ev = problem.evaluate
strain = ev(’dw_ul_he_neohook.3.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’strain’)
out[’green_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain, dofs=None)
stress = ev(’dw_ul_he_neohook.3.Omega( solid.mu, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’neohook_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_ul_he_mooney_rivlin.3.Omega( solid.kappa, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’mooney_rivlin_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
stress = ev(’dw_ul_bulk_pressure.3.Omega( v, u, p )’,
mode=’el_avg’, term_mode= ’stress’)
out[’bulk_stress’] = Struct(name=’output_data’,
mode=’cell’, data=stress, dofs=None)
return out
equations = {
’balance’: """dw_ul_he_neohook.3.Omega( solid.mu, v, u )
+ dw_ul_he_mooney_rivlin.3.Omega(solid.kappa, v, u)
+ dw_ul_bulk_pressure.3.Omega( v, u, p ) = 0""",
’volume’: """dw_ul_volume.3.Omega( q, u )
+ dw_ul_compressible.3.Omega( solid.iK, q, p, u ) = 0"""
}
##
# Solvers etc.
solvers = {
’ls’: (’ls.scipy_direct’, {}),
’newton’: (’nls.newton’, {
’i_max’: 25,
’eps_a’: 1e-8,
’eps_r’: 1.0,
’macheps’: 1e-16,
’lin_red’: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’: 0.1,
’ls_red_warp’: 0.001,
’ls_on’: 1.1,
’ls_min’: 1e-5,
’check’: 0,
’delta’: 1e-6,
}),
’ts’: (’ts.simple’, {
176
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’t0’: 0,
’t1’: 1,
’dt’: None,
’n_step’: 11, # has precedence over dt!
}),
}
large_deformation/perfusion_tl.py
Description
Porous nearly incompressible hyperelastic material with fluid perfusion.
Large deformation is described using the total Lagrangian formulation. Models of this kind can be used in biomechanics to model biological tissues, e.g. muscles.
Find 𝑢 such that:
(equilibrium equation with boundary tractions)
∫︁ (︁
∫︁
)︁
𝜈 · 𝐹 −1 · 𝜎 · 𝑣𝐽 d𝑆 = 0 ,
𝑆 eff − 𝑝𝐽𝐶 −1 : 𝛿𝐸(𝑣) d𝑉 +
∀𝑣 ,
(0)
Γ0
Ω(0)
(mass balance equation (perfusion))
∫︁
∫︁
𝑞𝐽(𝑢) +
Ω(0)
𝐾(𝑢(𝑛−1) ) :
𝜕𝑞 𝜕𝑝
=
𝜕𝑋 𝜕𝑋
∫︁
𝑞𝐽(𝑢(𝑛−1) ) ,
∀𝑞 ,
Ω(0)
Ω(0)
where
𝐹
𝐽
𝐶
𝐸(𝑢)
𝜕𝑥𝑖
deformation gradient 𝐹𝑖𝑗 = 𝜕𝑋
𝑗
det(𝐹 )
right Cauchy-Green deformation tensor 𝐶 = 𝐹 𝑇 𝐹
𝜕𝑢
𝜕𝑢𝑖
𝑚 𝜕𝑢𝑚
+ 𝜕𝑥𝑗𝑖 + 𝜕𝑢
Green strain tensor 𝐸𝑖𝑗 = 12 ( 𝜕𝑥
𝜕𝑥𝑖 𝜕𝑥𝑗 )
𝑗
𝑆 eff (𝑢)
effective second Piola-Kirchhoff stress tensor
The effective (neo-Hookean) stress 𝑆 eff (𝑢) is given by:
2
𝑆 eff (𝑢) = 𝜇𝐽 − 3 (𝐼 −
1
tr(𝐶)𝐶 −1 ) .
3
The linearized deformation-dependent permeability is defined as 𝐾(𝑢) = 𝐽𝐹 −1 𝑘𝑓 (𝐽)𝐹 −𝑇 , where 𝑢 relates to the
(︁ (︁
)︁)︁2
previous time step (𝑛 − 1) and 𝑓 (𝐽) = max 0, 1 + (𝐽−1)
expresses the dependence on volume compres𝑁𝑓
sion/expansion.
5.3. Examples
177
SfePy Documentation, Release 2015.1
source code
# -*- coding: utf-8 -*r"""
Porous nearly incompressible hyperelastic material with fluid perfusion.
Large deformation is described using the total Lagrangian formulation.
Models of this kind can be used in biomechanics to model biological
tissues, e.g. muscles.
Find :math:‘\ul{u}‘ such that:
(equilibrium equation with boundary tractions)
.. math::
\intl{\Omega\suz}{} \left( \ull{S}\eff - p J \ull{C}^{-1}
\right) : \delta \ull{E}(\ul{v}) \difd{V}
+ \intl{\Gamma_0\suz}{} \ul{\nu} \cdot \ull{F}^{-1} \cdot \ull{\sigma}
\cdot \ul{v} J \difd{S}
= 0
\;, \quad \forall \ul{v} \;,
(mass balance equation (perfusion))
.. math::
\intl{\Omega\suz}{} q J(\ul{u})
+ \intl{\Omega\suz}{} \ull{K}(\ul{u}\sunm) : \pdiff{q}{X} \pdiff{p}{X}
178
Chapter 5. Examples
SfePy Documentation, Release 2015.1
= \intl{\Omega\suz}{} q J(\ul{u}\sunm)
\;, \quad \forall q \;,
where
.. list-table::
:widths: 20 80
* * * * -
:math:‘\ull{F}‘
deformation gradient :math:‘F_{ij} = \pdiff{x_i}{X_j}‘
:math:‘J‘
:math:‘\det(F)‘
:math:‘\ull{C}‘
right Cauchy-Green deformation tensor :math:‘C = F^T F‘
:math:‘\ull{E}(\ul{u})‘
Green strain tensor :math:‘E_{ij} = \frac{1}{2}(\pdiff{u_i}{x_j} +
\pdiff{u_j}{x_i} + \pdiff{u_m}{x_i}\pdiff{u_m}{x_j})‘
* - :math:‘\ull{S}\eff(\ul{u})‘
- effective second Piola-Kirchhoff stress tensor
The effective (neo-Hookean) stress :math:‘\ull{S}\eff(\ul{u})‘ is given
by:
.. math::
\ull{S}\eff(\ul{u}) = \mu J^{-\frac{2}{3}}(\ull{I}
- \frac{1}{3}\tr(\ull{C}) \ull{C}^{-1})
\;.
The linearized deformation-dependent permeability is defined as
:math:‘\ull{K}(\ul{u}) = J \ull{F}^{-1} \ull{k} f(J) \ull{F}^{-T}‘,
where :math:‘\ul{u}‘ relates to the previous time step :math:‘(n-1)‘ and
:math:‘f(J) = \max\left(0, \left(1 + \frac{(J 1)}{N_f}\right)\right)^2‘ expresses the dependence on volume
compression/expansion.
"""
import numpy as nm
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
# Time-stepping parameters.
t0 = 0.0
t1 = 1.0
n_step = 21
from sfepy.solvers.ts import TimeStepper
ts = TimeStepper(t0, t1, None, n_step)
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
’post_process_hook’ : ’post_process’,
}
5.3. Examples
179
SfePy Documentation, Release 2015.1
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
’pressure’
: (’real’, 1, ’Omega’, 1),
}
materials = {
# Perfused solid.
’ps’ : ({
’mu’ : 20e0, # shear modulus of neoHookean term
’k’ : ts.dt * nm.eye(3, dtype=nm.float64), # reference permeability
’N_f’ : 1.0, # reference porosity
},),
# Surface pressure traction.
’traction’ : ’get_traction’,
}
variables
’u’ :
’v’ :
’p’ :
’q’ :
}
= {
(’unknown field’, ’displacement’, 0, 1),
(’test field’, ’displacement’, ’u’),
(’unknown field’, ’pressure’, 1),
(’test field’, ’pressure’, ’p’),
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
##
# Dirichlet BC.
ebcs = {
’l’ : (’Left’, {’u.all’ : 0.0, ’p.0’ : ’get_pressure’}),
}
##
# Balance of forces.
integrals = {
’i1’ : 1,
’i2’ : 2,
}
equations = {
’force_balance’
: """dw_tl_he_neohook.i1.Omega( ps.mu, v, u )
+ dw_tl_bulk_pressure.i1.Omega( v, u, p )
+ dw_tl_surface_traction.i2.Right( traction.pressure, v, u )
= 0""",
’mass_balance’
: """dw_tl_volume.i1.Omega( q, u )
+ dw_tl_diffusion.i1.Omega( ps.k, ps.N_f, q, p, u[-1])
= dw_tl_volume.i1.Omega( q, u[-1] )"""
}
def post_process(out, problem, state, extend=False):
from sfepy.base.base import Struct, debug
val = problem.evaluate(’dw_tl_he_neohook.i1.Omega( ps.mu, v, u )’,
180
Chapter 5. Examples
SfePy Documentation, Release 2015.1
mode=’el_avg’, term_mode=’strain’)
out[’green_strain’] = Struct(name=’output_data’,
mode=’cell’, data=val, dofs=None)
val = problem.evaluate(’dw_tl_he_neohook.i1.Omega( ps.mu, v, u )’,
mode=’el_avg’, term_mode=’stress’)
out[’neohook_stress’] = Struct(name=’output_data’,
mode=’cell’, data=val, dofs=None)
val = problem.evaluate(’dw_tl_bulk_pressure.i1.Omega( v, u, p )’,
mode=’el_avg’, term_mode=’stress’)
out[’bulk_pressure’] = Struct(name=’output_data’,
mode=’cell’, data=val, dofs=None)
val = problem.evaluate(’dw_tl_diffusion.i1.Omega( ps.k, ps.N_f, q, p, u[-1] )’,
mode=’el_avg’, term_mode=’diffusion_velocity’)
out[’diffusion_velocity’] = Struct(name=’output_data’,
mode=’cell’, data=val, dofs=None)
return out
##
# Solvers etc.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
:
’eps_a’
:
’eps_r’
:
’macheps’
:
’lin_red’
:
’ls_red’
:
’ls_red_warp’:
’ls_on’
:
’ls_min’
:
’check’
:
’delta’
:
7,
1e-10,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
0.1,
0.001,
1.1,
1e-5,
0,
1e-6,
}
solver_2 = {
’name’ : ’ts’,
’kind’ : ’ts.simple’,
’t0’
: t0,
’t1’
: t1,
’dt’
: None,
’n_step’ : n_step, # has precedence over dt!
}
##
# Functions.
def get_traction(ts, coors, mode=None):
5.3. Examples
181
SfePy Documentation, Release 2015.1
"""
Pressure traction.
Parameters
---------ts : TimeStepper
Time stepping info.
coors : array_like
The physical domain coordinates where the parameters shound be defined.
mode : ’qp’ or ’special’
Call mode.
"""
if mode != ’qp’: return
tt = ts.nt * 2.0 * nm.pi
dim = coors.shape[1]
val = 0.05 * nm.sin(tt) * nm.eye(dim, dtype=nm.float64)
val[1,0] = val[0,1] = 0.5 * val[0,0]
shape = (coors.shape[0], 1, 1)
out = {
’pressure’ : nm.tile(val, shape),
}
return out
def get_pressure(ts, coor, **kwargs):
"""Internal pressure Dirichlet boundary condition."""
tt = ts.nt * 2.0 * nm.pi
val = nm.zeros((coor.shape[0],), dtype=nm.float64)
val[:] = 1e-2 * nm.sin(tt)
return val
functions = {
’get_traction’ : (lambda ts, coors, mode=None, **kwargs:
get_traction(ts, coors, mode=mode),),
’get_pressure’ : (get_pressure,),
}
5.3.6 linear_elasticity
linear_elasticity/elastic_contact_planes.py
Description
Elastic contact planes simulating an indentation test.
Four contact planes bounded by polygons (triangles in this case) form a very rigid pyramid shape simulating an
indentor.
182
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) +
Ω
4 ∫︁
∑︁
𝑖=1
𝑣 · 𝑓 𝑖 (𝑑(𝑢))𝑛𝑖 = 0 ,
Γ𝑖
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
Notes
Even though the material is linear elastic and small deformations are used, the problem is highly nonlinear due to
contacts with the planes.
Checking the tangent matrix by finite differences by setting ‘check’ in ‘nls’ solver configuration to nonzero is rather
tricky - the active contact points must not change during the test. This can be ensured by a sufficient initial penetration
and large enough contact boundary polygons (hard!), or by tweaking the dw_contact_plane term to mask points only
by undeformed coordinates.
source code
r"""
Elastic contact planes simulating an indentation test.
Four contact planes bounded by polygons (triangles in this case) form a very
rigid pyramid shape simulating an indentor.
5.3. Examples
183
SfePy Documentation, Release 2015.1
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
+ \sum_{i=1}^4 \int_{\Gamma_i} \ul{v} \cdot f^i(d(\ul{u})) \ul{n^i}
= 0 \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl} + \delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
Notes
----Even though the material is linear elastic and small deformations are used, the
problem is highly nonlinear due to contacts with the planes.
Checking the tangent matrix by finite differences by setting ’check’ in ’nls’
solver configuration to nonzero is rather tricky - the active contact points
must not change during the test. This can be ensured by a sufficient initial
penetration and large enough contact boundary polygons (hard!), or by tweaking
the dw_contact_plane term to mask points only by undeformed coordinates.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cube_medium_hexa.mesh’
k = 1e5 # Elastic plane stiffness for positive penetration.
f0 = 1e2 # Force at zero penetration.
dn = 0.2 # x or y component magnitude of normals.
ds = 0.25 # Boundary polygon size in horizontal directions.
az = 0.4 # Anchor z coordinate.
options = {
’ts’ : ’ts’,
’nls’ : ’newton’,
’ls’ : ’lsd’,
’output_format’: ’vtk’,
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’lam’ : 5.769,
’mu’ : 3.846,
},),
’cp0’ : ({
’f’ : [k, f0],
’.n’ : [dn, 0.0, 1.0],
’.a’ : [0.0, 0.0, az],
’.bs’ : [[0.0, 0.0, az],
184
Chapter 5. Examples
SfePy Documentation, Release 2015.1
[-ds, -ds, az],
[-ds, ds, az]],
},),
’cp1’ : ({
’f’ : [k, f0],
’.n’ : [-dn, 0.0, 1.0],
’.a’ : [0.0, 0.0, az],
’.bs’ : [[0.0, 0.0, az],
[ds, -ds, az],
[ds, ds, az]],
},),
’cp2’ : ({
’f’ : [k, f0],
’.n’ : [0.0, dn, 1.0],
’.a’ : [0.0, 0.0, az],
’.bs’ : [[0.0, 0.0, az],
[-ds, -ds, az],
[ds, -ds, az]],
},),
’cp3’ : ({
’f’ : [k, f0],
’.n’ : [0.0, -dn, 1.0],
’.a’ : [0.0, 0.0, az],
’.bs’ : [[0.0, 0.0, az],
[-ds, ds, az],
[ds, ds, az]],
},),
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Bottom’ : (’vertices in (z < -0.499)’, ’facet’),
’Top’ : (’vertices in (z > 0.499)’, ’facet’),
}
ebcs = {
’fixed’ : (’Bottom’, {’u.all’ : 0.0}),
}
equations = {
’elasticity’ :
"""dw_lin_elastic_iso.2.Omega(solid.lam, solid.mu, v, u)
+ dw_contact_plane.2.Top(cp0.f, cp0.n, cp0.a, cp0.bs, v,
+ dw_contact_plane.2.Top(cp1.f, cp1.n, cp1.a, cp1.bs, v,
+ dw_contact_plane.2.Top(cp2.f, cp2.n, cp2.a, cp2.bs, v,
+ dw_contact_plane.2.Top(cp3.f, cp3.n, cp3.a, cp3.bs, v,
= 0""",
}
u)
u)
u)
u)
solvers = {
’lsd’ : (’ls.scipy_direct’, {}),
’lsi’ : (’ls.petsc’, {
’method’ : ’cg’,
5.3. Examples
185
SfePy Documentation, Release 2015.1
’eps_r’ : 1e-8,
’i_max’ : 3000,
}),
’newton’ : (’nls.newton’, {
’i_max’ : 10,
’eps_a’ : 1e-10,
’check’ : 0,
’delta’ : 1e-6,
}),
}
def main():
import os
import numpy as nm
import matplotlib.pyplot as plt
from sfepy.discrete.fem import MeshIO
import sfepy.linalg as la
from sfepy.mechanics.contact_bodies import (ContactPlane, plot_polygon,
plot_points)
conf_dir = os.path.dirname(__file__)
io = MeshIO.any_from_filename(filename_mesh, prefix_dir=conf_dir)
bb = io.read_bounding_box()
outline = [vv for vv in la.combine(zip(*bb))]
ax = plot_points(None, nm.array(outline), ’r*’)
for name in [’cp%d’ % ii for ii in range(4)]:
cpc = materials[name][0]
cp = ContactPlane(cpc[’.a’], cpc[’.n’], cpc[’.bs’])
v1, v2 = la.get_perpendiculars(cp.normal)
ax = plot_polygon(ax, cp.bounds)
ax = plot_polygon(ax, nm.r_[cp.anchor[None,
cp.anchor[None,
ax = plot_polygon(ax, nm.r_[cp.anchor[None,
cp.anchor[None,
ax = plot_polygon(ax, nm.r_[cp.anchor[None,
cp.anchor[None,
:],
:] + cp.normal[None, :]])
:],
:] + v1])
:],
:] + v2])
plt.show()
if __name__ == ’__main__’:
main()
linear_elasticity/elastic_contact_sphere.py
Description
Elastic contact sphere simulating an indentation test.
Find 𝑢 such that:
∫︁
∫︁
𝑣 · 𝑓 (𝑑(𝑢))𝑛(𝑢) = 0 ,
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) +
Ω
186
Γ
Chapter 5. Examples
SfePy Documentation, Release 2015.1
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
Notes
Even though the material is linear elastic and small deformations are used, the problem is highly nonlinear due to
contacts with the sphere. See also elastic_contact_planes.py example.
source code
r"""
Elastic contact sphere simulating an indentation test.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
+ \int_{\Gamma} \ul{v} \cdot f(d(\ul{u})) \ul{n}(\ul{u})
= 0 \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl} + \delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
5.3. Examples
187
SfePy Documentation, Release 2015.1
Notes
----Even though the material is linear elastic and small deformations are used, the
problem is highly nonlinear due to contacts with the sphere. See also
elastic_contact_planes.py example.
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cube_medium_hexa.mesh’
k = 1e5 # Elastic sphere stiffness for positive penetration.
f0 = 1e-2 # Force at zero penetration.
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’output_format’: ’vtk’,
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’lam’ : 5.769,
’mu’ : 3.846,
},),
’cs’ : ({
’f’ : [k, f0],
’.c’ : [0.0, 0.0, 1.2],
’.r’ : 0.8,
},),
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Bottom’ : (’vertices in (z < -0.499)’, ’facet’),
’Top’ : (’vertices in (z > 0.499)’, ’facet’),
}
ebcs = {
’fixed’ : (’Bottom’, {’u.all’ : 0.0}),
}
equations = {
’elasticity’ :
"""dw_lin_elastic_iso.2.Omega(solid.lam, solid.mu, v, u)
+ dw_contact_sphere.2.Top(cs.f, cs.c, cs.r, v, u)
= 0""",
}
188
Chapter 5. Examples
SfePy Documentation, Release 2015.1
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 20,
’eps_a’ : 1e-1,
’ls_on’ : 2.0,
’check’ : 0,
’delta’ : 1e-6,
}),
}
def main():
import os
import numpy as nm
import matplotlib.pyplot as plt
from sfepy.discrete.fem import MeshIO
import sfepy.linalg as la
from sfepy.mechanics.contact_bodies import ContactSphere, plot_points
conf_dir = os.path.dirname(__file__)
io = MeshIO.any_from_filename(filename_mesh, prefix_dir=conf_dir)
bb = io.read_bounding_box()
outline = [vv for vv in la.combine(zip(*bb))]
ax = plot_points(None, nm.array(outline), ’r*’)
csc = materials[’cs’][0]
cs = ContactSphere(csc[’.c’], csc[’.r’])
pps = (bb[1] - bb[0]) * nm.random.rand(5000, 3) + bb[0]
mask = cs.mask_points(pps, 0.0)
ax = plot_points(ax, cs.centre[None, :], ’b*’, ms=30)
ax = plot_points(ax, pps[mask], ’kv’)
ax = plot_points(ax, pps[~mask], ’r.’)
plt.show()
if __name__ == ’__main__’:
main()
linear_elasticity/elastic_shifted_periodic.py
Description
Linear elasticity with linear combination constraints and periodic boundary conditions.
The linear combination constraints are used to apply periodic boundary conditions with a shift in the second axis
direction.
5.3. Examples
189
SfePy Documentation, Release 2015.1
Find 𝑢 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = −
Ω
𝑣·𝜎·𝑛,
∀𝑣 ,
Γ𝑏𝑜𝑡𝑡𝑜𝑚
𝑢 = 0 on Γ𝑙𝑒𝑓 𝑡 ,
𝑢1 = 𝑢2 = 0 on Γ𝑟𝑖𝑔ℎ𝑡 ,
𝑢(𝑥) = 𝑢(𝑦) for 𝑥 ∈ Γ𝑏𝑜𝑡𝑡𝑜𝑚 , 𝑦 ∈ Γ𝑡𝑜𝑝 , 𝑦 = 𝑃1 (𝑥) ,
𝑢(𝑥) = 𝑢(𝑦) + 𝑎(𝑦) for 𝑥 ∈ Γ𝑛𝑒𝑎𝑟 , 𝑦 ∈ Γ𝑓 𝑎𝑟 , 𝑦 = 𝑃2 (𝑥) ,
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 ,
and the traction 𝜎 · 𝑛 = 𝑝¯𝐼 · 𝑛 is given in terms of traction pressure 𝑝¯. The function 𝑎(𝑦) is given (the shift), 𝑃1 and
𝑃2 are the periodic coordinate mappings.
View the results using:
$ ./postproc.py block.vtk --wireframe -b --only-names=u -d’u,plot_displacements,rel_scaling=1,color_k
source code
r"""
Linear elasticity with linear combination constraints and periodic boundary
conditions.
The linear combination constraints are used to apply periodic boundary
190
Chapter 5. Examples
SfePy Documentation, Release 2015.1
conditions with a shift in the second axis direction.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= - \int_{\Gamma_{bottom}} \ul{v} \cdot \ull{\sigma} \cdot \ul{n}
\;, \quad \forall \ul{v} \;,
\ul{u} = 0 \mbox{ on } \Gamma_{left} \;,
u_1 = u_2 = 0 \mbox{ on } \Gamma_{right} \;,
\ul{u}(\ul{x}) = \ul{u}(\ul{y}) \mbox{ for }
\ul{x} \in \Gamma_{bottom}, \ul{y} \in \Gamma_{top},
\ul{y} = P_1(\ul{x}) \;,
\ul{u}(\ul{x}) = \ul{u}(\ul{y}) + a(\ul{y}) \mbox{ for }
\ul{x} \in \Gamma_{near}, \ul{y} \in \Gamma_{far},
\ul{y} = P_2(\ul{x}) \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;,
and the traction :math:‘\ull{\sigma} \cdot \ul{n} = \bar{p} \ull{I} \cdot
\ul{n}‘ is given in terms of traction pressure :math:‘\bar{p}‘. The function
:math:‘a(\ul{y})‘ is given (the shift), :math:‘P_1‘ and :math:‘P_2‘ are the
periodic coordinate mappings.
View the results using::
$ ./postproc.py block.vtk --wireframe -b --only-names=u -d’u,plot_displacements,rel_scaling=1,color
"""
import numpy as nm
from sfepy.mechanics.matcoefs import stiffness_from_lame
from sfepy.mechanics.tensors import get_von_mises_stress
import sfepy.discrete.fem.periodic as per
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’post_process_hook’ : ’post_process’
}
def post_process(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
5.3. Examples
191
SfePy Documentation, Release 2015.1
ev = pb.evaluate
stress = ev(’ev_cauchy_stress.2.Omega(solid.D, u)’, mode=’el_avg’)
vms = get_von_mises_stress(stress.squeeze())
vms.shape = (vms.shape[0], 1, 1, 1)
out[’von_mises_stress’] = Struct(name=’output_data’, mode=’cell’,
data=vms, dofs=None)
return out
def linear_tension(ts, coor, mode=None, **kwargs):
if mode == ’qp’:
val = 0.1 * nm.sin(coor[:, 0] / 10.)
return {’val’ : val.reshape((coor.shape[0], 1, 1))}
def get_shift(ts, coors, region=None):
val = nm.zeros_like(coors, dtype=nm.float64)
val[:, 1] = 0.1 * coors[:, 0]
return val.T
functions = {
’get_shift’ : (get_shift,),
’linear_tension’ : (linear_tension,),
’match_y_plane’ : (per.match_y_plane,),
’match_z_plane’ : (per.match_z_plane,),
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=5.769, mu=3.846),
},),
’load’ : (None, ’linear_tension’)
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
’Right’ : (’vertices in (x > 4.99)’, ’facet’),
’Bottom’ : (’vertices in (z < -0.99)’, ’facet’),
’Top’ : (’vertices in (z > 0.99)’, ’facet’),
’Near’ : (’vertices in (y < -0.99)’, ’facet’),
’Far’ : (’vertices in (y > 0.99)’, ’facet’),
}
ebcs = {
’fix1’ : (’Left’, {’u.all’ : 0.0}),
’fix2’ : (’Right’, {’u.[1,2]’ : 0.0}),
192
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}
epbcs = {
’periodic’ : ([’Bottom’, ’Top’], {’u.all’ : ’u.all’}, ’match_z_plane’),
}
lcbcs = {
’shifted’ : ((’Near’, ’Far’),
{’u.all’ : ’u.all’},
’match_y_plane’, ’shifted_periodic’,
’get_shift’),
}
equations = {
’elasticity’ : """
dw_lin_elastic.2.Omega(solid.D, v, u)
= -dw_surface_ltr.2.Bottom(load.val, v)
""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
linear_elasticity/its2D_1.py
Description
Diametrically point loaded 2-D disk. See Primer.
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
5.3. Examples
193
SfePy Documentation, Release 2015.1
source code
r"""
Diametrically point loaded 2-D disk. See :ref:‘sec-primer‘.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from sfepy.mechanics.matcoefs import lame_from_youngpoisson
from sfepy.discrete.fem.utils import refine_mesh
from sfepy import data_dir
# Fix the mesh file name if you run this file outside the SfePy directory.
filename_mesh = data_dir + ’/meshes/2d/its2D.mesh’
refinement_level = 0
194
Chapter 5. Examples
SfePy Documentation, Release 2015.1
filename_mesh = refine_mesh(filename_mesh, refinement_level)
output_dir = ’.’ # set this to a valid directory you have write access to
young = 2000.0 # Young’s modulus [MPa]
poisson = 0.4 # Poisson’s ratio
options = {
’output_dir’ : output_dir,
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Bottom’ : (’vertices in (y < 0.001)’, ’facet’),
’Top’ : (’vertex 2’, ’vertex’),
}
materials = {
’Asphalt’ : ({
’lam’ : lame_from_youngpoisson(young, poisson)[0],
’mu’ : lame_from_youngpoisson(young, poisson)[1],
},),
’Load’ : ({’.val’ : [0.0, -1000.0]},),
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
equations = {
’balance_of_forces’ :
"""dw_lin_elastic_iso.2.Omega(Asphalt.lam, Asphalt.mu, v, u )
= dw_point_load.0.Top(Load.val, v)""",
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
ebcs = {
’XSym’ : (’Bottom’, {’u.1’ : 0.0}),
’YSym’ : (’Left’, {’u.0’ : 0.0}),
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-6,
}),
}
linear_elasticity/its2D_2.py
Description
5.3. Examples
195
SfePy Documentation, Release 2015.1
Diametrically point loaded 2-D disk with postprocessing. See Primer.
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
r"""
Diametrically point loaded 2-D disk with postprocessing. See
:ref:‘sec-primer‘.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
196
Chapter 5. Examples
SfePy Documentation, Release 2015.1
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from its2D_1 import *
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
def stress_strain(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
stress = ev(’ev_cauchy_stress.2.Omega(Asphalt.D, u)’, mode=’el_avg’)
out[’cauchy_strain’] = Struct(name=’output_data’, mode=’cell’,
data=strain, dofs=None)
out[’cauchy_stress’] = Struct(name=’output_data’, mode=’cell’,
data=stress, dofs=None)
return out
asphalt = materials[’Asphalt’][0]
asphalt.update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
options.update({’post_process_hook’ : ’stress_strain’,})
linear_elasticity/its2D_3.py
Description
Diametrically point loaded 2-D disk with nodal stress calculation. See Primer.
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
5.3. Examples
197
SfePy Documentation, Release 2015.1
source code
r"""
Diametrically point loaded 2-D disk with nodal stress calculation. See
:ref:‘sec-primer‘.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from its2D_1 import *
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.discrete.fem.geometry_element import geometry_data
from sfepy.discrete import FieldVariable
from sfepy.discrete.fem import Field
import numpy as nm
198
Chapter 5. Examples
SfePy Documentation, Release 2015.1
gdata = geometry_data[’2_3’]
nc = len(gdata.coors)
def nodal_stress(out, pb, state, extend=False, integrals=None):
’’’
Calculate stresses at nodal points.
’’’
# Point load.
mat = pb.get_materials()[’Load’]
P = 2.0 * mat.get_data(’special’, None, ’val’)[1]
# Calculate nodal stress.
pb.time_update()
if integrals is None: integrals = pb.get_integrals()
stress = pb.evaluate(’ev_cauchy_stress.ivn.Omega(Asphalt.D, u)’, mode=’qp’,
integrals=integrals)
sfield = Field.from_args(’stress’, nm.float64, (3,),
pb.domain.regions[’Omega’])
svar = FieldVariable(’sigma’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
svar.set_data_from_qp(stress, integrals[’ivn’])
print ’\n==================================================================’
print ’Given load = %.2f N’ % -P
print ’\nAnalytical solution’
print ’===================’
print ’Horizontal tensile stress = %.5e MPa/mm’ % (-2.*P/(nm.pi*150.))
print ’Vertical compressive stress = %.5e MPa/mm’ % (-6.*P/(nm.pi*150.))
print ’\nFEM solution’
print ’============’
print ’Horizontal tensile stress = %.5e MPa/mm’ % (svar()[0][0])
print ’Vertical compressive stress = %.5e MPa/mm’ % (-svar()[0][1])
print ’==================================================================’
return out
asphalt = materials[’Asphalt’][0]
asphalt.update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
options.update({’post_process_hook’ : ’nodal_stress’,})
integrals = {
’ivn’ : (’custom’, gdata.coors, [gdata.volume / nc] * nc),
}
linear_elasticity/its2D_4.py
Description
Diametrically point loaded 2-D disk with postprocessing and probes. See Primer.
Use it as follows (assumes running from the sfepy directory; on Windows, you may need to prefix all the commands
with “python ” and remove ”./”):
1. solve the problem:
5.3. Examples
199
SfePy Documentation, Release 2015.1
./simple.py examples/linear_elasticity/its2D_4.py
2. optionally, view the results:
./postproc.py its2D.h5 -b
3. optionally, convert results to VTK, and view again:
./extractor.py -d its2D.h5
./postproc.py its2D.vtk -b
4. probe the data:
./probe.py examples/linear_elasticity/its2D_4.py its2D.h5
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
r"""
Diametrically point loaded 2-D disk with postprocessing and probes. See
200
Chapter 5. Examples
SfePy Documentation, Release 2015.1
:ref:‘sec-primer‘.
Use it as follows (assumes running from the sfepy directory; on Windows, you
may need to prefix all the commands with "python " and remove "./"):
1. solve the problem::
./simple.py examples/linear_elasticity/its2D_4.py
2. optionally, view the results::
./postproc.py its2D.h5 -b
3. optionally, convert results to VTK, and view again::
./extractor.py -d its2D.h5
./postproc.py its2D.vtk -b
4. probe the data::
./probe.py examples/linear_elasticity/its2D_4.py its2D.h5
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from its2D_1 import *
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
def stress_strain(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
stress = ev(’ev_cauchy_stress.2.Omega(Asphalt.D, u)’, mode=’el_avg’)
out[’cauchy_strain’] = Struct(name=’output_data’, mode=’cell’,
data=strain, dofs=None)
out[’cauchy_stress’] = Struct(name=’output_data’, mode=’cell’,
data=stress, dofs=None)
return out
def gen_lines(problem):
5.3. Examples
201
SfePy Documentation, Release 2015.1
from sfepy.discrete.probes import LineProbe
ps0 = [[0.0, 0.0], [ 0.0, 0.0]]
ps1 = [[75.0, 0.0], [ 0.0, 75.0]]
# Use adaptive probe with 10 inital points.
n_point = -10
labels = [’%s -> %s’ % (p0, p1) for p0, p1 in zip(ps0, ps1)]
probes = []
for ip in xrange(len(ps0)):
p0, p1 = ps0[ip], ps1[ip]
probes.append(LineProbe(p0, p1, n_point))
return probes, labels
def probe_hook(data, probe, label, problem):
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
def get_it(name, var_name):
var = problem.create_variables([var_name])[var_name]
var.set_data(data[name].data)
pars, vals = probe(var)
vals = vals.squeeze()
return pars, vals
results = {}
results[’u’] = get_it(’u’, ’u’)
results[’cauchy_strain’] = get_it(’cauchy_strain’, ’s’)
results[’cauchy_stress’] = get_it(’cauchy_stress’, ’s’)
fig = plt.figure()
plt.clf()
fig.subplots_adjust(hspace=0.4)
plt.subplot(311)
pars, vals = results[’u’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$u_{%d}$’ % (ic + 1),
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’displacements’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=10))
sym_indices = [’11’, ’22’, ’12’]
plt.subplot(312)
pars, vals = results[’cauchy_strain’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$e_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy strain’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=8))
plt.subplot(313)
pars, vals = results[’cauchy_stress’]
202
Chapter 5. Examples
SfePy Documentation, Release 2015.1
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$\sigma_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy stress’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, prop=fm.FontProperties(size=8))
return plt.gcf(), results
materials[’Asphalt’][0].update({’D’ : stiffness_from_youngpoisson(2, young, poisson)})
# Update fields and variables to be able to use probes for tensors.
fields.update({
’sym_tensor’: (’real’, 3, ’Omega’, 0),
})
variables.update({
’s’ : (’parameter field’, ’sym_tensor’, None),
})
options.update({
’output_format’
’post_process_hook’
’gen_probes’
’probe_hook’
})
:
:
:
:
’h5’, # VTK reader cannot read cell data yet for probing
’stress_strain’,
’gen_lines’,
’probe_hook’,
linear_elasticity/its2D_interactive.py
Description
Diametrically point loaded 2-D disk, using commands for interactive use. See Primer.
The script combines the functionality of all the its2D_?.py examples and allows setting various simulation parameters, namely:
• material parameters
• displacement field approximation order
• uniform mesh refinement level
The example shows also how to probe the results as in linear_elasticity/its2D_4.py, and how to display the results
using Mayavi. Using sfepy.discrete.probes allows correct probing of fields with the approximation order
greater than one.
In the SfePy top-level directory the following command can be used to get usage information:
python examples/linear_elasticity/its2D_interactive.py -h
Notes
The --probe and --show options work simultaneously only if Mayavi and Matplotlib use the same backend type
(for example wx).
source code
5.3. Examples
203
SfePy Documentation, Release 2015.1
#!/usr/bin/env python
"""
Diametrically point loaded 2-D disk, using commands for interactive use. See
:ref:‘sec-primer‘.
The script combines the functionality of all the ‘‘its2D_?.py‘‘ examples and
allows setting various simulation parameters, namely:
- material parameters
- displacement field approximation order
- uniform mesh refinement level
The example shows also how to probe the results as in
:ref:‘linear_elasticity-its2D_4‘, and how to display the results using Mayavi.
Using :mod:‘sfepy.discrete.probes‘ allows correct probing of fields with the
approximation order greater than one.
In the SfePy top-level directory the following command can be used to get usage
information::
python examples/linear_elasticity/its2D_interactive.py -h
Notes
----The ‘‘--probe‘‘ and ‘‘--show‘‘ options work simultaneously only if Mayavi and
Matplotlib use the same backend type (for example wx).
"""
import sys
sys.path.append(’.’)
from optparse import OptionParser
import numpy as nm
import matplotlib.pyplot as plt
from sfepy.base.base import assert_, output, ordered_iteritems, IndexedStruct
from sfepy.discrete import (FieldVariable, Material, Integral, Integrals,
Equation, Equations, Problem)
from sfepy.discrete.fem import Mesh, FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import Conditions, EssentialBC
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.discrete.fem.geometry_element import geometry_data
from sfepy.discrete.probes import LineProbe
from sfepy.discrete.projections import make_l2_projection_data
from its2D_2 import stress_strain
from its2D_3 import nodal_stress
def project_by_component(tensor, tensor_qp, component, order):
"""
Wrapper around make_l2_projection_data() for non-scalar fields.
"""
aux = []
for ic in range(3):
make_l2_projection_data(component, tensor_qp[..., ic, :].copy(),
204
Chapter 5. Examples
SfePy Documentation, Release 2015.1
order=order)
aux.append(component())
tensor.set_data(nm.array(aux).T.ravel())
def gen_lines(problem):
"""
Define two line probes.
Additional probes can be added by appending to ‘ps0‘ (start points) and
‘ps1‘ (end points) lists.
"""
ps0 = [[0.0, 0.0], [0.0, 0.0]]
ps1 = [[75.0, 0.0], [0.0, 75.0]]
# Use enough points for higher order approximations.
n_point = 1000
labels = [’%s -> %s’ % (p0, p1) for p0, p1 in zip(ps0, ps1)]
probes = []
for ip in xrange(len(ps0)):
p0, p1 = ps0[ip], ps1[ip]
probes.append(LineProbe(p0, p1, n_point))
return probes, labels
def probe_retults(u, strain, stress, probe, label):
"""
Probe the results using the given probe and plot the probed values.
"""
results = {}
pars, vals = probe(u)
results[’u’] = (pars, vals)
pars, vals = probe(strain)
results[’cauchy_strain’] = (pars, vals)
pars, vals = probe(stress)
results[’cauchy_stress’] = (pars, vals)
fig = plt.figure()
plt.clf()
fig.subplots_adjust(hspace=0.4)
plt.subplot(311)
pars, vals = results[’u’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$u_{%d}$’ % (ic + 1),
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’displacements’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
sym_indices = [’11’, ’22’, ’12’]
plt.subplot(312)
pars, vals = results[’cauchy_strain’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$e_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy strain’)
5.3. Examples
205
SfePy Documentation, Release 2015.1
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
plt.subplot(313)
pars, vals = results[’cauchy_stress’]
for ic in range(vals.shape[1]):
plt.plot(pars, vals[:,ic], label=r’$\sigma_{%s}$’ % sym_indices[ic],
lw=1, ls=’-’, marker=’+’, ms=3)
plt.ylabel(’Cauchy stress’)
plt.xlabel(’probe %s’ % label, fontsize=8)
plt.legend(loc=’best’, fontsize=10)
return fig, results
usage = ’%prog [options]\n’ + __doc__.rstrip()
helps = {
’young’ : "the Young’s modulus [default: %default]",
’poisson’ : "the Poisson’s ratio [default: %default]",
’load’ : "the vertical load value (negative means compression)"
" [default: %default]",
’order’ : ’displacement field approximation order [default: %default]’,
’refine’ : ’uniform mesh refinement level [default: %default]’,
’probe’ : ’probe the results’,
’show’ : ’show the results figure’,
}
def main():
from sfepy import data_dir
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’--young’, metavar=’float’, type=float,
action=’store’, dest=’young’,
default=2000.0, help=helps[’young’])
parser.add_option(’--poisson’, metavar=’float’, type=float,
action=’store’, dest=’poisson’,
default=0.4, help=helps[’poisson’])
parser.add_option(’--load’, metavar=’float’, type=float,
action=’store’, dest=’load’,
default=-1000.0, help=helps[’load’])
parser.add_option(’--order’, metavar=’int’, type=int,
action=’store’, dest=’order’,
default=1, help=helps[’order’])
parser.add_option(’-r’, ’--refine’, metavar=’int’, type=int,
action=’store’, dest=’refine’,
default=0, help=helps[’refine’])
parser.add_option(’-s’, ’--show’,
action="store_true", dest=’show’,
default=False, help=helps[’show’])
parser.add_option(’-p’, ’--probe’,
action="store_true", dest=’probe’,
default=False, help=helps[’probe’])
options, args = parser.parse_args()
assert_((0.0 < options.poisson < 0.5),
"Poisson’s ratio must be in ]0, 0.5[!")
assert_((0 < options.order),
’displacement approximation order must be at least 1!’)
206
Chapter 5. Examples
SfePy Documentation, Release 2015.1
output(’using values:’)
output(" Young’s modulus:", options.young)
output(" Poisson’s ratio:", options.poisson)
output(’ vertical load:’, options.load)
output(’uniform mesh refinement level:’, options.refine)
# Build the problem definition.
mesh = Mesh.from_file(data_dir + ’/meshes/2d/its2D.mesh’)
domain = FEDomain(’domain’, mesh)
if options.refine > 0:
for ii in xrange(options.refine):
output(’refine %d...’ % ii)
domain = domain.refine()
output(’... %d nodes %d elements’
% (domain.shape.n_nod, domain.shape.n_el))
omega = domain.create_region(’Omega’, ’all’)
left = domain.create_region(’Left’,
’vertices in x < 0.001’, ’facet’)
bottom = domain.create_region(’Bottom’,
’vertices in y < 0.001’, ’facet’)
top = domain.create_region(’Top’, ’vertex 2’, ’vertex’)
field = Field.from_args(’fu’, nm.float64, ’vector’, omega,
approx_order=options.order)
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
D = stiffness_from_youngpoisson(2, options.young, options.poisson)
asphalt = Material(’Asphalt’, D=D)
load = Material(’Load’, values={’.val’ : [0.0, options.load]})
integral = Integral(’i’, order=2*options.order)
integral0 = Integral(’i’, order=0)
t1 = Term.new(’dw_lin_elastic(Asphalt.D, v, u)’,
integral, omega, Asphalt=asphalt, v=v, u=u)
t2 = Term.new(’dw_point_load(Load.val, v)’,
integral0, top, Load=load, v=v)
eq = Equation(’balance’, t1 - t2)
eqs = Equations([eq])
xsym = EssentialBC(’XSym’, bottom, {’u.1’ : 0.0})
ysym = EssentialBC(’YSym’, left, {’u.0’ : 0.0})
ls = ScipyDirect({})
nls_status = IndexedStruct()
nls = Newton({}, lin_solver=ls, status=nls_status)
pb = Problem(’elasticity’, equations=eqs, nls=nls, ls=ls)
pb.time_update(ebcs=Conditions([xsym, ysym]))
# Solve the problem.
5.3. Examples
207
SfePy Documentation, Release 2015.1
state = pb.solve()
output(nls_status)
# Postprocess the solution.
out = state.create_output_dict()
out = stress_strain(out, pb, state, extend=True)
pb.save_state(’its2D_interactive.vtk’, out=out)
gdata = geometry_data[’2_3’]
nc = len(gdata.coors)
integral_vn = Integral(’ivn’, coors=gdata.coors,
weights=[gdata.volume / nc] * nc)
nodal_stress(out, pb, state, integrals=Integrals([integral_vn]))
if options.probe:
# Probe the solution.
probes, labels = gen_lines(pb)
sfield = Field.from_args(’sym_tensor’, nm.float64, 3, omega,
approx_order=options.order - 1)
stress = FieldVariable(’stress’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
strain = FieldVariable(’strain’, ’parameter’, sfield,
primary_var_name=’(set-to-None)’)
cfield = Field.from_args(’component’, nm.float64, 1, omega,
approx_order=options.order - 1)
component = FieldVariable(’component’, ’parameter’, cfield,
primary_var_name=’(set-to-None)’)
ev = pb.evaluate
order = 2 * (options.order - 1)
strain_qp = ev(’ev_cauchy_strain.%d.Omega(u)’ % order, mode=’qp’)
stress_qp = ev(’ev_cauchy_stress.%d.Omega(Asphalt.D, u)’ % order,
mode=’qp’)
project_by_component(strain, strain_qp, component, order)
project_by_component(stress, stress_qp, component, order)
all_results = []
for ii, probe in enumerate(probes):
fig, results = probe_retults(u, strain, stress, probe, labels[ii])
fig.savefig(’its2D_interactive_probe_%d.png’ % ii)
all_results.append(results)
for ii, results in enumerate(all_results):
output(’probe %d:’ % ii)
output.level += 2
for key, res in ordered_iteritems(results):
output(key + ’:’)
val = res[1]
output(’ min: %+.2e, mean: %+.2e, max: %+.2e’
% (val.min(), val.mean(), val.max()))
output.level -= 2
208
Chapter 5. Examples
SfePy Documentation, Release 2015.1
if options.show:
# Show the solution. If the approximation order is greater than 1, the
# extra DOFs are simply thrown away.
from sfepy.postprocess.viewer import Viewer
view = Viewer(’its2D_interactive.vtk’)
view(vector_mode=’warp_norm’, rel_scaling=1,
is_scalar_bar=True, is_wireframe=True)
if __name__ == ’__main__’:
main()
linear_elasticity/linear_elastic.py
Description
Linear elasticity with given displacements.
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
This example models a cylinder that is fixed at one end while the second end has a specified displacement of 0.01
in the x direction (this boundary condition is named ’Displaced’). There is also a specified displacement of
0.005 in the z direction for points in the region labeled ’SomewhereTop’. This boundary condition is named
’PerturbedSurface’. The region ’SomewhereTop’ is specified as those vertices for which:
(z > 0.017) & (x > 0.03) & (x <
0.07)
The displacement field (three DOFs/node) in the ’Omega region’ is approximated using P1 (four-node tetrahedral) finite elements. The material is linear elastic and its properties are specified as Lamé parameters 𝜆 and 𝜇 (see
http://en.wikipedia.org/wiki/Lam%C3%A9_parameters)
The output is the displacement for each vertex, saved by default to cylinder.vtk. View the results using:
$ ./postproc.py cylinder.vtk --wireframe -b --only-names=u -d’u,plot_displacements,rel_scaling=1’
5.3. Examples
209
SfePy Documentation, Release 2015.1
source code
# -*- coding: utf-8 -*r"""
Linear elasticity with given displacements.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
This example models a cylinder that is fixed at one end while the second end
has a specified displacement of 0.01 in the x direction (this boundary
condition is named ‘‘’Displaced’‘‘). There is also a specified displacement of
0.005 in the z direction for points in the region labeled
‘‘’SomewhereTop’‘‘. This boundary condition is named
‘‘’PerturbedSurface’‘‘. The region ‘‘’SomewhereTop’‘‘ is specified as those
vertices for which::
210
Chapter 5. Examples
SfePy Documentation, Release 2015.1
(z > 0.017) & (x > 0.03) & (x <
0.07)
The displacement field (three DOFs/node) in the ‘‘’Omega region’‘‘ is
approximated using P1 (four-node tetrahedral) finite elements. The material is
linear elastic and its properties are specified as Lamé parameters
:math:‘\lambda‘ and :math:‘\mu‘ (see
http://en.wikipedia.org/wiki/Lam%C3%A9_parameters)
The output is the displacement for each vertex, saved by default to
cylinder.vtk. View the results using::
$ ./postproc.py cylinder.vtk --wireframe -b --only-names=u -d’u,plot_displacements,rel_scaling=1’
"""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
’SomewhereTop’ : (’vertices in (z > 0.017) & (x > 0.03) & (x < 0.07)’,
’vertex’),
}
materials = {
’solid’ : ({’lam’ : 1e1, ’mu’ : 1e0},),
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
integrals = {
’i’ : 1,
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
ebcs = {
’Fixed’ : (’Left’, {’u.all’ : 0.0}),
’Displaced’ : (’Right’, {’u.0’ : 0.01, ’u.[1,2]’ : 0.0}),
’PerturbedSurface’ : (’SomewhereTop’, {’u.2’ : 0.005}),
}
equations = {
’balance_of_forces’ :
"""dw_lin_elastic_iso.i.Omega(solid.lam, solid.mu, v, u) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
5.3. Examples
211
SfePy Documentation, Release 2015.1
}),
}
linear_elasticity/linear_elastic_damping.py
Description
Time-dependent linear elasticity with a simple damping.
Find 𝑢 such that:
∫︁
𝑐𝑣·
Ω
𝜕𝑢
+
𝜕𝑡
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
r"""
Time-dependent linear elasticity with a simple damping.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} c\ \ul{v} \cdot \pdiff{\ul{u}}{t}
212
Chapter 5. Examples
SfePy Documentation, Release 2015.1
+ \int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
from copy import deepcopy
import numpy as nm
from linear_elastic import \
filename_mesh, materials, regions, fields, ebcs, \
integrals, solvers
def print_times(problem, state):
print nm.array(problem.ts.times)
options = {
’ts’ : ’ts’,
’save_steps’ : -1,
’post_process_hook_final’ : print_times,
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0, 1),
’v’ : (’test field’, ’displacement’, ’u’),
}
# Put density to ’solid’.
materials = deepcopy(materials)
materials[’solid’][0].update({’c’ : 1000.0})
# Moving the PerturbedSurface region.
ebcs = deepcopy(ebcs)
ebcs[’PerturbedSurface’][1].update({’u.0’ : ’ebc_sin’})
def ebc_sin(ts, coors, **kwargs):
val = 0.01 * nm.sin(2.0*nm.pi*ts.nt)
return nm.tile(val, (coors.shape[0],))
equations = {
’balance_of_forces in time’ :
"""dw_volume_dot.i.Omega( solid.c, v, du/dt )
+ dw_lin_elastic_iso.i.Omega( solid.lam, solid.mu, v, u ) = 0""",
}
solvers = deepcopy(solvers) # Do not spoil linear_elastic.py namespace in tests.
solvers.update({
’ts’ : (’ts.adaptive’, {
’t0’ : 0.0,
’t1’ : 1.0,
’dt’ : None,
’n_step’ : 101,
5.3. Examples
213
SfePy Documentation, Release 2015.1
’adapt_fun’ : ’adapt_time_step’,
}),
})
def adapt_time_step(ts, status, adt, problem):
if ts.time > 0.5:
ts.set_time_step(0.1)
return True
ls = solvers[’ls’]
ls[1].update({’presolve’ : True})
functions = {
’ebc_sin’ : (ebc_sin,),
’adapt_time_step’ : (adapt_time_step,),
}
linear_elasticity/linear_elastic_iga.py
Description
Linear elasticity solved in a single patch NURBS domain using the isogeometric analysis (IGA) approach.
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 ,
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
The domain geometry was created by:
$ ./script/gen_iga_patch.py -d [1,0.5,0.1] -s [11,5,3] --degrees [2,2,2] -o meshes/iga/block3d.iga
View the results using:
$ ./postproc.py block3d.vtk --wireframe -b
$ ./postproc.py block3d.vtk --wireframe -b -d ’u,plot_displacements,rel_scaling=1e0’
214
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Linear elasticity solved in a single patch NURBS domain using the isogeometric
analysis (IGA) approach.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
The domain geometry was created by::
$ ./script/gen_iga_patch.py -d [1,0.5,0.1] -s [11,5,3] --degrees [2,2,2] -o meshes/iga/block3d.iga
View the results using::
$ ./postproc.py block3d.vtk --wireframe -b
5.3. Examples
215
SfePy Documentation, Release 2015.1
$ ./postproc.py block3d.vtk --wireframe -b -d ’u,plot_displacements,rel_scaling=1e0’
"""
from sfepy.mechanics.matcoefs import stiffness_from_lame
from sfepy import data_dir
filename_domain = data_dir + ’/meshes/iga/block3d.iga’
regions = {
’Omega’ : ’all’,
’Gamma1’ : (’vertices of set xi00’, ’facet’),
’Gamma2’ : (’vertices of set xi01’, ’facet’),
}
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=5.769, mu=3.846),
},),
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, None, ’H1’, ’iga’),
}
integrals = {
’i’ : 3,
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
ebcs = {
’u1’ : (’Gamma1’, {’u.all’ : 0.0}),
’u2’ : (’Gamma2’, {’u.0’ : 0.1, ’u.[1,2]’ : ’get_ebcs’}),
}
def get_ebcs(ts, coors, **kwargs):
import numpy as nm
aux = nm.empty_like(coors[:, 1:])
aux[:, 0] = 0.1 * coors[:, 1]
aux[:, 1] = -0.05 + 0.03 * nm.sin(coors[:, 1] * 5 * nm.pi)
return aux.T.flat
functions = {
’get_ebcs’ : (get_ebcs,),
}
equations = {
’balance_of_forces’ : """dw_lin_elastic.i.Omega(solid.D, v, u) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
216
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’eps_a’
: 1e-10,
}),
}
linear_elasticity/linear_elastic_tractions.py
Description
Linear elasticity with pressure traction load on a surface and constrained to one-dimensional motion.
Find 𝑢 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = −
Ω
𝑣·𝜎·𝑛,
∀𝑣 ,
Γ𝑟𝑖𝑔ℎ𝑡
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
and 𝜎 · 𝑛 = 𝑝¯𝐼 · 𝑛 with given traction pressure 𝑝¯.
source code
r"""
Linear elasticity with pressure traction load on a surface and constrained to
one-dimensional motion.
5.3. Examples
217
SfePy Documentation, Release 2015.1
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= - \int_{\Gamma_{right}} \ul{v} \cdot \ull{\sigma} \cdot \ul{n}
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
and :math:‘\ull{\sigma} \cdot \ul{n} = \bar{p} \ull{I} \cdot \ul{n}‘
with given traction pressure :math:‘\bar{p}‘.
"""
import numpy as nm
def linear_tension(ts, coor, mode=None, **kwargs):
if mode == ’qp’:
val = nm.tile(1.0, (coor.shape[0], 1, 1))
return {’val’ : val}
def define():
"""Define the problem to solve."""
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
}
functions = {
’linear_tension’ : (linear_tension,),
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’lam’ : 5.769,
’mu’ : 3.846,
},),
’load’ : (None, ’linear_tension’)
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
218
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
’Right’ : (’vertices in (x > 4.99)’, ’facet’),
}
ebcs = {
’fixb’ : (’Left’, {’u.all’ : 0.0}),
’fixt’ : (’Right’, {’u.[1,2]’ : 0.0}),
}
##
# Balance of forces.
equations = {
’elasticity’ :
"""dw_lin_elastic_iso.2.Omega( solid.lam, solid.mu, v, u )
= - dw_surface_ltr.2.Right( load.val, v )""",
}
##
# Solvers etc.
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{ ’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
# Linear system error < (eps_a * lin_red).
’lin_red’
: 1e-2,
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
})
}
return locals()
linear_elasticity/linear_elastic_up.py
Description
Nearly incompressible linear elasticity in mixed displacement-pressure formulation with comments.
Find 𝑢, 𝑝 such that:
∫︁
Ω
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) −
𝑝 ∇ · 𝑣 = 0 , ∀𝑣 ,
∫︁
∫︁ Ω
−
𝑞∇·𝑢−
𝛾𝑞𝑝 = 0 , ∀𝑞 .
Ω
5.3. Examples
Ω
219
SfePy Documentation, Release 2015.1
source code
r"""
Nearly incompressible linear elasticity in mixed displacement-pressure
formulation with comments.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} p\ \nabla \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
- \int_{\Omega} q\ \nabla \cdot \ul{u}
- \int_{\Omega} \gamma q p
= 0
\;, \quad \forall q \;.
"""
#!
#! Linear Elasticity
#! =================
#$ \centerline{Example input file, \today}
#! This file models a cylinder that is fixed at one end while the
#! second end has a specified displacement of 0.02 in the x direction
#! (this boundary condition is named PerturbedSurface).
220
Chapter 5. Examples
SfePy Documentation, Release 2015.1
#! The output is the displacement for each node, saved by default to
#! simple_out.vtk. The material is linear elastic.
from sfepy import data_dir
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson_mixed, bulk_from_youngpoisson
#! Mesh
#! ---dim = 3
approx_u = ’3_4_P1’
approx_p = ’3_4_P0’
order = 2
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
#! Regions
#! ------#! Whole domain ’Omega’, left and right ends.
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
#! Materials
#! --------#! The linear elastic material model is used.
materials = {
’solid’ : ({’D’ : stiffness_from_youngpoisson_mixed(dim, 0.7e9, 0.4),
’gamma’ : 1.0/bulk_from_youngpoisson(0.7e9, 0.4)},),
}
#! Fields
#! -----#! A field is used to define the approximation on a (sub)domain
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
’pressure’ : (’real’, ’scalar’, ’Omega’, 0),
}
#! Integrals
#! --------#! Define the integral type Volume/Surface and quadrature rule.
integrals = {
’i’ : order,
}
#! Variables
#! --------#! Define displacement and pressure fields and corresponding fields
#! for test variables.
variables = {
’u’ : (’unknown field’, ’displacement’),
’v’ : (’test field’, ’displacement’, ’u’),
’p’ : (’unknown field’, ’pressure’),
’q’ : (’test field’, ’pressure’, ’p’),
}
#! Boundary Conditions
#! ------------------#! The left end of the cylinder is fixed (all DOFs are zero) and
#! the ’right’ end has non-zero displacements only in the x direction.
ebcs = {
’Fixed’ : (’Left’, {’u.all’ : 0.0}),
5.3. Examples
221
SfePy Documentation, Release 2015.1
’PerturbedSurface’ : (’Right’, {’u.0’ : 0.02, ’u.1’ : 0.0}),
}
#! Equations
#! --------#! The weak formulation of the linear elastic problem.
equations = {
’balance_of_forces’ :
""" dw_lin_elastic.i.Omega( solid.D, v, u )
- dw_stokes.i.Omega( v, p )
= 0 """,
’pressure constraint’ :
"""- dw_stokes.i.Omega( u, q )
- dw_volume_dot.i.Omega( solid.gamma, q, p )
= 0""",
}
#! Solvers
#! ------#! Define linear and nonlinear solver.
#! Even linear problems are solved by a nonlinear solver - only one
#! iteration is needed and the final rezidual is obtained for free.
solvers = {
’ls’ : (’ls.schur_complement’, {
’keep’: [’p’],
’eliminate’: [’u’],
}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-2,
’eps_r’
: 1e-10,
}),
}
#! Options
#! ------#! Various problem-specific options.
options = {
’output_dir’ : ’./output’,
’absolute_mesh_path’ : True,
}
linear_elasticity/linear_viscoelastic.py
Description
Linear viscoelasticity with pressure traction load on a surface and constrained to one-dimensional motion.
The fading memory terms require an unloaded initial configuration, so the load starts in the second time step. The load
is then held for the first half of the total time interval, and released afterwards.
This example uses exponential fading memory kernel ℋ𝑖𝑗𝑘𝑙 (𝑡) = ℋ𝑖𝑗𝑘𝑙 (0)𝑒−𝑑𝑡 with decay 𝑑. Two equation kinds
are supported - ‘th’ and ‘eth’. In ‘th’ mode the tabulated kernel is linearly interpolated to required times using
interp_conv_mat(). In ‘eth’ mode, the computation is exact for exponential kernels.
222
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Find 𝑢 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢)
]︂
𝑡
𝜕𝑢
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 ( (𝜏 )) d𝜏 𝑒𝑖𝑗 (𝑣)
𝜕𝜏
0
∫︁
=−
𝑣 · 𝜎 · 𝑛 , ∀𝑣 ,
Ω
∫︁ [︂∫︁
+
Ω
Γ𝑟𝑖𝑔ℎ𝑡
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 ,
ℋ𝑖𝑗𝑘𝑙 (0) has the same structure as 𝐷𝑖𝑗𝑘𝑙 and 𝜎 · 𝑛 = 𝑝¯𝐼 · 𝑛 with given traction pressure 𝑝¯.
Notes
Because this example is run also as a test, it uses by default very few time steps. Try changing that.
Visualization
The output file is assumed to be ‘block.h5’ in the working directory. Change it appropriately for your situation.
Deforming mesh Try to play with the following:
$ ./postproc.py block.h5 -b --only-names=u -d ’u,plot_displacements,rel_scaling=1e0,opacity=1.0,color
Use:
$ ./postproc.py -l block.h5
to see names and kinds of variables.
Time history plots Run the following:
$ python examples/linear_elasticity/linear_viscoelastic.py -h
$ python examples/linear_elasticity/linear_viscoelastic.py block.h5
Try comparing ‘th’ and ‘eth’ versions, e.g., for n_step = 201, and f_n_step = 51. There is a visible notch on viscous
stress curves in the ‘th’ mode, as the fading memory kernel is cut off before it goes close enough to zero.
5.3. Examples
223
SfePy Documentation, Release 2015.1
source code
r"""
Linear viscoelasticity with pressure traction load on a surface and constrained
to one-dimensional motion.
The fading memory terms require an unloaded initial configuration, so the load
starts in the second time step. The load is then held for the first half of the
total time interval, and released afterwards.
This example uses exponential fading memory kernel
:math:‘\Hcal_{ijkl}(t) = \Hcal_{ijkl}(0) e^{-d t}‘ with decay
:math:‘d‘. Two equation kinds are supported - ’th’ and ’eth’. In ’th’
mode the tabulated kernel is linearly interpolated to required times
using :func:‘interp_conv_mat()‘. In ’eth’ mode, the computation is exact
for exponential kernels.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u}) \\
+ \int_{\Omega} \left [\int_0^t
\Hcal_{ijkl}(t-\tau)\,e_{kl}(\pdiff{\ul{u}}{\tau}(\tau)) \difd{\tau}
\right]\,e_{ij}(\ul{v}) \\
= - \int_{\Gamma_{right}} \ul{v} \cdot \ull{\sigma} \cdot \ul{n}
\;, \quad \forall \ul{v} \;,
224
Chapter 5. Examples
SfePy Documentation, Release 2015.1
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;,
:math:‘\Hcal_{ijkl}(0)‘ has the same structure as :math:‘D_{ijkl}‘ and
:math:‘\ull{\sigma} \cdot \ul{n} = \bar{p} \ull{I} \cdot \ul{n}‘ with
given traction pressure :math:‘\bar{p}‘.
Notes
----Because this example is run also as a test, it uses by default very few time
steps. Try changing that.
Visualization
------------The output file is assumed to be ’block.h5’ in the working directory. Change it
appropriately for your situation.
Deforming mesh
^^^^^^^^^^^^^^
Try to play with the following::
$ ./postproc.py block.h5 -b --only-names=u -d ’u,plot_displacements,rel_scaling=1e0,opacity=1.0,c
Use::
$ ./postproc.py -l block.h5
to see names and kinds of variables.
Time history plots
^^^^^^^^^^^^^^^^^^
Run the following::
$ python examples/linear_elasticity/linear_viscoelastic.py -h
$ python examples/linear_elasticity/linear_viscoelastic.py block.h5
Try comparing ’th’ and ’eth’ versions, e.g., for n_step = 201, and f_n_step =
51. There is a visible notch on viscous stress curves in the ’th’ mode, as the
fading memory kernel is cut off before it goes close enough to zero.
"""
import numpy as nm
from
from
from
from
sfepy.base.base import output
sfepy.mechanics.matcoefs import stiffness_from_lame
sfepy.homogenization.utils import interp_conv_mat
sfepy import data_dir
def linear_tension(ts, coors, mode=None, verbose=True, **kwargs):
if mode == ’qp’:
val = 1.0 * ((ts.step > 0) and (ts.nt <= 0.5))
5.3. Examples
225
SfePy Documentation, Release 2015.1
if verbose:
output(’load:’, val)
val = nm.tile(val, (coors.shape[0], 1, 1))
return {’val’ : val}
def get_exp_fading_kernel(coef0, decay, times):
val = coef0[None, ...] * nm.exp(-decay * times[:, None, None])
return val
def get_th_pars(ts, coors, mode=None, times=None, kernel=None, **kwargs):
out = {}
if mode == ’special’:
out[’H’] = interp_conv_mat(kernel, ts, times)
elif mode == ’qp’:
out[’H0’] = kernel[0]
out[’Hd’] = kernel[1, 0, 0] / kernel[0, 0, 0]
for key, val in out.iteritems():
out[key] = nm.tile(val, (coors.shape[0], 1, 1))
return out
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
## Configure below. ##
# Time stepping times.
t0 = 0.0
t1 = 20.0
n_step = 21
# Fading memory times.
f_t0 = 0.0
f_t1 = 5.0
f_n_step = 6
decay = 0.8
mode = ’eth’
## Configure above. ##
times = nm.linspace(f_t0, f_t1, f_n_step)
kernel = get_exp_fading_kernel(stiffness_from_lame(3, lam=1.0, mu=1.0),
decay, times)
dt = (t1 - t0) / (n_step - 1)
fading_memory_length = min(int((f_t1 - f_t0) / dt) + 1, n_step)
output(’fading memory length:’, fading_memory_length)
def post_process(out, pb, state, extend=False):
"""
Calculate and output strain and stress for given displacements.
"""
from sfepy.base.base import Struct
226
Chapter 5. Examples
SfePy Documentation, Release 2015.1
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
out[’cauchy_strain’] = Struct(name=’output_data’, mode=’cell’,
data=strain, dofs=None)
estress = ev(’ev_cauchy_stress.2.Omega(solid.D, u)’, mode=’el_avg’)
out[’cauchy_stress’] = Struct(name=’output_data’, mode=’cell’,
data=estress, dofs=None)
ts = pb.get_timestepper()
if mode == ’th’:
vstress = ev(’ev_cauchy_stress_th.2.Omega(ts, th.H, du/dt)’,
ts=ts, mode=’el_avg’)
out[’viscous_stress’] = Struct(name=’output_data’, mode=’cell’,
data=vstress, dofs=None)
else:
# The eth terms require ’preserve_caches=True’ in order to have correct
# fading memory history.
vstress = ev(’ev_cauchy_stress_eth.2.Omega(ts, th.H0, th.Hd, du/dt)’,
ts=ts, mode=’el_avg’, preserve_caches=True)
out[’viscous_stress’] = Struct(name=’output_data’, mode=’cell’,
data=vstress, dofs=None)
out[’total_stress’] = Struct(name=’output_data’, mode=’cell’,
data=estress + vstress, dofs=None)
return out
options = {
’ts’ : ’ts’,
’nls’ : ’newton’,
’ls’ : ’ls’,
’output_format’
: ’h5’,
’post_process_hook’ : ’post_process’,
}
functions = {
’linear_tension’ : (linear_tension,),
’get_pars’ : (lambda ts, coors, mode=None, **kwargs:
get_th_pars(ts, coors, mode, times=times, kernel=kernel,
**kwargs),),
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
}
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=5.769, mu=3.846),
},),
’th’ : ’get_pars’,
’load’ : ’linear_tension’,
}
variables = {
5.3. Examples
227
SfePy Documentation, Release 2015.1
’u’ : (’unknown field’, ’displacement’, 0, fading_memory_length),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
’Right’ : (’vertices in (x > 4.99)’, ’facet’),
}
ebcs = {
’fixb’ : (’Left’, {’u.all’ : 0.0}),
’fixt’ : (’Right’, {’u.[1,2]’ : 0.0}),
}
if mode == ’th’:
# General form with tabulated kernel.
equations = {
’elasticity’ :
"""dw_lin_elastic.2.Omega( solid.D, v, u )
+ dw_lin_elastic_th.2.Omega( ts, th.H, v, du/dt )
= - dw_surface_ltr.2.Right( load.val, v )""",
}
else:
# Fast form that is exact for exponential kernels.
equations = {
’elasticity’ :
"""dw_lin_elastic.2.Omega( solid.D, v, u )
+ dw_lin_elastic_eth.2.Omega( ts, th.H0, th.Hd, v, du/dt )
= - dw_surface_ltr.2.Right( load.val, v )""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-10,
}),
’ts’ : (’ts.simple’, {
’t0’ : t0,
’t1’ : t1,
’dt’ : None,
’n_step’ : n_step,
’quasistatic’ : True,
}),
}
def main():
"""
Plot the load, displacement, strain and stresses w.r.t. time.
"""
from optparse import OptionParser
import matplotlib.pyplot as plt
import sfepy.postprocess.time_history as th
usage = """%prog <output file in HDF5 format>"""
228
Chapter 5. Examples
SfePy Documentation, Release 2015.1
msgs = {’node’ : ’plot displacements in given node [default: %default]’,
’element’ : ’plot tensors in given element [default: %default]’,}
parser = OptionParser(usage=usage)
parser.add_option(’-n’, ’--node’, type=int, metavar=’ii’,
action=’store’, dest=’node’,
default=512, help=msgs[’node’])
parser.add_option(’-e’, ’--element’, type=int, metavar=’ii’,
action=’store’, dest=’element’,
default=299, help=msgs[’element’])
options, args = parser.parse_args()
if len(args) == 1:
filename = args[0]
else:
parser.print_help()
return
tensor_names = [’cauchy_strain’,
’cauchy_stress’, ’viscous_stress’, ’total_stress’]
extract = (’u n %d, ’ % options.node) \
+ ’, ’.join(’%s e %d’ % (name, options.element)
for name in tensor_names)
ths, ts = th.extract_time_history(filename, extract)
load = [linear_tension(ts, nm.array([0]),
mode=’qp’, verbose=False)[’val’].squeeze()
for ii in ts]
load = nm.array(load)
normalized_kernel = kernel[:, 0, 0] / kernel[0, 0, 0]
plt.figure(1, figsize=(8, 10))
plt.subplots_adjust(hspace=0.3,
top=0.95, bottom=0.05, left=0.07, right=0.95)
plt.subplot(311)
plt.plot(times, normalized_kernel, lw=3)
plt.title(’fading memory decay’)
plt.xlabel(’time’)
plt.subplot(312)
plt.plot(ts.times, load, lw=3)
plt.title(’load’)
plt.xlabel(’time’)
displacements = ths[’u’][options.node]
plt.subplot(313)
plt.plot(ts.times, displacements, lw=3)
plt.title(’displacement components, node %d’ % options.node)
plt.xlabel(’time’)
plt.figure(2, figsize=(8, 10))
plt.subplots_adjust(hspace=0.35,
top=0.95, bottom=0.05, left=0.07, right=0.95)
5.3. Examples
229
SfePy Documentation, Release 2015.1
for ii, tensor_name in enumerate(tensor_names):
tensor = ths[tensor_name][options.element]
plt.subplot(411 + ii)
plt.plot(ts.times, tensor, lw=3)
plt.title(’%s components, element %d’ % (tensor_name, options.element))
plt.xlabel(’time’)
plt.show()
if __name__ == ’__main__’:
main()
linear_elasticity/material_nonlinearity.py
Description
Example demonstrating how a linear elastic term can be used to solve an elasticity problem with a material nonlinearity.
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) = 0 , ∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
230
Chapter 5. Examples
SfePy Documentation, Release 2015.1
# -*- coding: utf-8 -*r"""
Example demonstrating how a linear elastic term can be used to solve an
elasticity problem with a material nonlinearity.
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
import numpy as nm
from sfepy.linalg import norm_l2_along_axis
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
def post_process(out, pb, state, extend=False):
from sfepy.base.base import Struct
mu = pb.evaluate(’ev_integrate_mat.2.Omega(nonlinear.mu, u)’,
mode=’el_avg’, copy_materials=False, verbose=False)
out[’mu’] = Struct(name=’mu’, mode=’cell’, data=mu, dofs=None)
strain = pb.evaluate(’ev_cauchy_strain.2.Omega(u)’, mode=’el_avg’)
out[’strain’] = Struct(name=’strain’, mode=’cell’, data=strain, dofs=None)
return out
strains = [None]
def get_pars(ts, coors, mode=’qp’,
equations=None, term=None, problem=None, **kwargs):
"""
The material nonlinearity function - the Lamé coefficient ‘mu‘
depends on the strain.
"""
if mode != ’qp’: return
val = nm.empty((coors.shape[0], 1, 1), dtype=nm.float64)
val.fill(1e0)
order = term.integral.order
uvar = equations.variables[’u’]
strain = problem.evaluate(’ev_cauchy_strain.%d.Omega(u)’ % order,
u=uvar, mode=’qp’)
if ts.step > 0:
strain0 = strains[-1]
else:
5.3. Examples
231
SfePy Documentation, Release 2015.1
strain0 = strain
dstrain = (strain - strain0) / ts.dt
dstrain.shape = (strain.shape[0] * strain.shape[1], strain.shape[2])
norm = norm_l2_along_axis(dstrain)
val += norm[:, None, None]
# Store history.
strains[0] = strain
return {’mu’ : val}
def pull(ts, coors, **kwargs):
val = nm.empty_like(coors[:,0])
val.fill(0.01 * ts.step)
return val
functions = {
’get_pars’ : (get_pars,),
’pull’ : (pull,),
}
options = {
’ts’ : ’ts’,
’output_format’ : ’h5’,
’save_steps’ : -1,
’post_process_hook’ : ’post_process’,
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < 0.001)’, ’facet’),
’Right’ : (’vertices in (x > 0.099)’, ’facet’),
}
materials = {
’linear’ : ({’lam’ : 1e1},),
’nonlinear’ : ’get_pars’,
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
ebcs = {
’Fixed’ : (’Left’, {’u.all’ : 0.0}),
’Displaced’ : (’Right’, {’u.0’ : ’pull’, ’u.[1,2]’ : 0.0}),
}
232
Chapter 5. Examples
SfePy Documentation, Release 2015.1
equations = {
’balance_of_forces in time’ :
"""dw_lin_elastic_iso.2.Omega(linear.lam, nonlinear.mu, v, u) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
}),
’ts’ : (’ts.simple’,
{’t0’ : 0.0,
’t1’ : 1.0,
’dt’ : None,
’n_step’ : 5,
’quasistatic’ : True,
}),
}
linear_elasticity/prestress_fibres.py
Description
Linear elasticity with a given prestress in one subdomain and a (pre)strain fibre reinforcement in the other.
Find 𝑢 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) +
Ω
∫︁
𝜎𝑖𝑗 𝑒𝑖𝑗 (𝑣) +
Ω1
Ω2
𝑓
𝐷𝑖𝑗𝑘𝑙
𝑒𝑖𝑗 (𝑣) (𝑑𝑘 𝑑𝑙 ) = 0 ,
∀𝑣 ,
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
𝑓
The stiffness of fibres 𝐷𝑖𝑗𝑘𝑙
is defined analogously, 𝑑 is the unit fibre direction vector and 𝜎𝑖𝑗 is the prestress.
Visualization
Use the following to see the deformed structure with 10x magnified displacements:
5.3. Examples
233
SfePy Documentation, Release 2015.1
$ ./postproc.py block.vtk -b --vector-mode=warp_norm -s 1 --wireframe
source code
r"""
Linear elasticity with a given prestress in one subdomain and a (pre)strain
fibre reinforcement in the other.
Find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
+ \int_{\Omega_1} \sigma_{ij} e_{ij}(\ul{v})
+ \int_{\Omega_2} D^f_{ijkl} e_{ij}(\ul{v}) \left(d_k d_l\right)
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
The stiffness of fibres :math:‘D^f_{ijkl}‘ is defined analogously,
:math:‘\ul{d}‘ is the unit fibre direction vector and :math:‘\sigma_{ij}‘ is
the prestress.
234
Chapter 5. Examples
SfePy Documentation, Release 2015.1
Visualization
------------Use the following to see the deformed structure with 10x magnified
displacements::
$ ./postproc.py block.vtk -b --vector-mode=warp_norm -s 1 --wireframe
"""
import numpy as nm
from sfepy.mechanics.matcoefs import stiffness_from_lame
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
’Omega1’ : ’vertices in (x < 0.001)’,
’Omega2’ : ’vertices in (x > -0.001)’,
}
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=1e2, mu=1e1),
’prestress’ : 0.1 * nm.array([[1.0], [1.0], [1.0],
[0.5], [0.5], [0.5]],
dtype=nm.float64),
’DF’ : stiffness_from_lame(3, lam=8e0, mu=8e-1),
’nu’ : nm.array([[-0.5], [0.0], [0.5]], dtype=nm.float64),
},),
}
fields = {
’displacement’: (’real’, ’vector’, ’Omega’, 1),
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
ebcs = {
’Fixed’ : (’Left’, {’u.all’ : 0.0}),
}
equations = {
’balance_of_forces’ :
"""dw_lin_elastic.2.Omega( solid.D, v, u )
+ dw_lin_prestress.2.Omega1( solid.prestress, v )
+ dw_lin_strain_fib.2.Omega2( solid.DF, solid.nu, v )
= 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-10,
5.3. Examples
235
SfePy Documentation, Release 2015.1
}),
}
5.3.7 miscellaneous
miscellaneous/compare_scalar_terms.py
Description
Example without a physical relevance comparing new and old-style terms with scalar variables.
Find 𝑝 (new style terms), 𝑟 (old_style terms) such that:
∫︁
∫︁
𝑐𝛿𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 +
𝑞𝑝 = 0 ,
∫︁Ω
∫︁Ω
𝑠𝑟 = 0 ,
𝑐𝛿𝑖𝑗 ∇𝑖 𝑠∇𝑗 𝑟 +
Ω
∀𝑞 ,
∀𝑠 .
Ω
The same values of 𝑝, 𝑟 should be obtained.
source code
r"""
Example without a physical relevance comparing new and old-style terms
with scalar variables.
Find :math:‘p‘ (new style terms), :math:‘r‘ (old_style terms) such that:
236
Chapter 5. Examples
SfePy Documentation, Release 2015.1
.. math::
\int_{\Omega} c \delta_{ij} \nabla_i q \nabla_j p
+ \int_{\Omega} q p
= 0
\;, \quad \forall q \;,
\int_{\Omega} c \delta_{ij} \nabla_i s \nabla_j r
+ \int_{\Omega} s r
= 0
\;, \quad \forall s \;.
The same values of :math:‘p‘, :math:‘r‘ should be obtained.
"""
import os
import numpy as nm
from sfepy import data_dir
from sfepy.discrete.fem import MeshIO
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
#filename_mesh = data_dir + ’/meshes/3d/cube_big_tetra.mesh’
conf_dir = os.path.dirname(__file__)
io = MeshIO.any_from_filename(filename_mesh, prefix_dir=conf_dir)
bbox = io.read_bounding_box()
dd = bbox[1] - bbox[0]
xmin, ymin, zmin = bbox[0, :] + 1e-4 * dd
xmax, ymax, zmax = bbox[1, :] - 1e-4 * dd
def post_process(out, pb, state, extend=False):
for vn in [’p’, ’r’]:
try:
dd = pb.evaluate(’dw_new_diffusion.2.Omega(m.c, %s, %s)’
% (vn, vn), verbose=False)
print ’dw_new_diffusion’, vn, dd
dd = pb.evaluate(’dw_diffusion.2.Omega(m.c, %s, %s)’
% (vn, vn), verbose=False)
print ’dw_diffusion’, vn, dd
mass = pb.evaluate(’dw_new_mass.2.Omega(%s, %s)’
% (vn, vn), verbose=False)
print ’dw_new_mass’, vn, mass
mass = pb.evaluate(’dw_new_mass_scalar.2.Omega(%s, %s)’
% (vn, vn), verbose=False)
print ’dw_new_mass_scalar’, vn, mass
mass = pb.evaluate(’dw_volume_dot.2.Omega(%s, %s)’
% (vn, vn), verbose=False)
print ’dw_volume_dot’, vn, mass
except:
pass
5.3. Examples
237
SfePy Documentation, Release 2015.1
return out
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’post_process_hook’ : ’post_process’,
}
materials = {
’m’ : ({’c’ : 0.0001 * nm.eye(3)},),
}
regions = {
’Omega’ : ’all’,
’Gamma_Left’ : (’vertices in (x < %f)’ % xmin, ’facet’),
’Gamma_Right’ : (’vertices in (x > %f)’ % xmax, ’facet’),
}
fields = {
’temperature’ : (’real’, 1, ’Omega’, 2),
}
variables
’p’ :
’q’ :
’r’ :
’s’ :
}
ebcs = {
’p1’
’p2’
’r1’
’r2’
}
:
:
:
:
= {
(’unknown field’,
(’test field’,
(’unknown field’,
(’test field’,
’temperature’,
’temperature’,
’temperature’,
’temperature’,
0),
’p’),
1),
’r’),
(’Gamma_Left’, {’p.0’ : 2.0}),
(’Gamma_Right’, {’p.0’ : -2.0}),
(’Gamma_Left’, {’r.0’ : 2.0}),
(’Gamma_Right’, {’r.0’ : -2.0}),
equations = {
’new equation’ :
"""dw_new_diffusion.2.Omega(m.c, q, p)
+ dw_new_mass.2.Omega(q, p)
= 0""",
’equation’ :
"""dw_diffusion.2.Omega(m.c, s, r)
+ dw_volume_dot.2.Omega(s, r)
= 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
238
Chapter 5. Examples
SfePy Documentation, Release 2015.1
miscellaneous/compare_vector_terms.py
Description
Example without a physical relevance comparing new and old-style terms with vector variables.
Find 𝑢 (new style terms), 𝑟 (old_style terms) such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢)
𝑣·𝑢=0,
Ω
Ω
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑠)𝑒𝑘𝑙 (𝑟)
𝑠·𝑟 =0,
Ω
∀𝑣 ,
∀𝑠 .
Ω
The same values of 𝑢, 𝑟 should be obtained.
source code
r"""
Example without a physical relevance comparing new and old-style terms
with vector variables.
Find :math:‘\ul{u}‘ (new style terms), :math:‘\ul{r}‘ (old_style terms)
such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
\int_{\Omega}\ul{v} \cdot \ul{u}
= 0
\;, \quad \forall \ul{v} \;,
5.3. Examples
239
SfePy Documentation, Release 2015.1
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{s}) e_{kl}(\ul{r})
\int_{\Omega}\ul{s} \cdot \ul{r}
= 0
\;, \quad \forall \ul{s} \;.
The same values of :math:‘\ul{u}‘, :math:‘\ul{r}‘ should be obtained.
"""
import os
from sfepy import data_dir
from sfepy.discrete.fem import MeshIO
from sfepy.mechanics.matcoefs import stiffness_from_lame
filename_mesh = data_dir + ’/meshes/3d/cylinder.mesh’
#filename_mesh = data_dir + ’/meshes/3d/cube_medium_hexa.mesh’
conf_dir = os.path.dirname(__file__)
io = MeshIO.any_from_filename(filename_mesh, prefix_dir=conf_dir)
bbox = io.read_bounding_box()
dd = bbox[1] - bbox[0]
xmin, ymin, zmin = bbox[0, :] + 1e-4 * dd
xmax, ymax, zmax = bbox[1, :] - 1e-4 * dd
def post_process(out, pb, state, extend=False):
for vn in [’u’, ’r’]:
try:
val = pb.evaluate(’dw_new_mass.2.Omega(%s, %s)’
% (vn, vn), verbose=False)
print ’dw_new_mass’, vn, val
val = pb.evaluate(’dw_new_lin_elastic.2.Omega(m.D, %s, %s)’
% (vn, vn), verbose=False)
print ’dw_new_lin_elastic’, vn, val
val = pb.evaluate(’dw_lin_elastic.2.Omega(m.D, %s, %s)’
% (vn, vn), verbose=False)
print ’dw_lin_elastic’, vn, val
except:
pass
return out
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’post_process_hook’ : ’post_process’,
}
materials = {
’m’ : ({’D’ : stiffness_from_lame(3, lam=0.0007, mu=0.0003),
’one’ : 1.0},),
}
regions = {
240
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’Omega’ : ’all’,
’Gamma_Left’ : (’vertices in (x < %f)’ % xmin, ’facet’),
’Gamma_Right’ : (’vertices in (x > %f)’ % xmax, ’facet’),
}
fields = {
’displacements’ : (’real’, ’vector’, ’Omega’, 1),
}
variables
’u’ :
’v’ :
’r’ :
’s’ :
}
= {
(’unknown field’,
(’test field’,
(’unknown field’,
(’test field’,
’displacements’,
’displacements’,
’displacements’,
’displacements’,
0),
’u’),
1),
’r’),
ebcs = {
’u1’ : (’Gamma_Left’, {’u.all’ : 0.0}),
’u2’ : (’Gamma_Right’, {’u.0’ : 0.1 * (xmax
’u.1’ : 0.1 * (ymax
’r1’ : (’Gamma_Left’, {’r.all’ : 0.0}),
’r2’ : (’Gamma_Right’, {’r.0’ : 0.1 * (xmax
’r.1’ : 0.1 * (ymax
}
- xmin),
- ymin)}),
- xmin),
- ymin)}),
equations = {
’new equation’ :
"""dw_new_lin_elastic.2.Omega(m.D, v, u)
+ dw_new_mass.2.Omega(v, u)
= 0""",
’equation’ :
"""dw_lin_elastic.2.Omega(m.D, s, r)
+ dw_volume_dot.2.Omega(m.one, s, r)
= 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’,
{’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
5.3.8 navier_stokes
navier_stokes/navier_stokes.py
Description
Navier-Stokes equations for incompressible fluid flow.
5.3. Examples
241
SfePy Documentation, Release 2015.1
Find 𝑢, 𝑝 such that:
∫︁
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 +
Ω
((𝑢 · ∇)𝑢) · 𝑣 −
∫︁Ω
𝑝∇·𝑣 =0,
∀𝑣 ,
Ω
𝑞∇·𝑢=0,
∀𝑞 .
Ω
source code
r"""
Navier-Stokes equations for incompressible fluid flow.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} \nu\ \nabla \ul{v} : \nabla \ul{u}
+ \int_{\Omega} ((\ul{u} \cdot \nabla) \ul{u}) \cdot \ul{v}
- \int_{\Omega} p\ \nabla \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \nabla \cdot \ul{u}
= 0
\;, \quad \forall q \;.
"""
from sfepy import data_dir
242
Chapter 5. Examples
SfePy Documentation, Release 2015.1
filename_mesh = data_dir + ’/meshes/3d/elbow2.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’post_process_hook’ : ’verify_incompressibility’,
# Options for saving higher-order variables.
# Possible kinds:
#
’strip’ ... just remove extra DOFs (ignores other linearization
#
options)
#
’adaptive’ ... adaptively refine linear element mesh.
’linearization’ : {
’kind’ : ’strip’,
’min_level’ : 1, # Min. refinement level to achieve everywhere.
’max_level’ : 2, # Max. refinement level.
’eps’ : 1e-1, # Relative error tolerance.
},
}
field_1 = {
’name’ : ’3_velocity’,
’dtype’ : ’real’,
’shape’ : (3,),
’region’ : ’Omega’,
’approx_order’ : ’1B’,
}
field_2 = {
’name’ : ’pressure’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
# Can use logical operations ’&’ (and), ’|’ (or).
region_1000 = {
’name’ : ’Omega’,
’select’ : ’cells of group 6’,
}
region_0 = {
’name’ :
’select’
’kind’ :
}
region_1 = {
’name’ :
’select’
’kind’ :
}
region_2 = {
’name’ :
’select’
’kind’ :
}
5.3. Examples
’Walls’,
: ’vertices of surface -v (r.Outlet +v r.Inlet)’,
’facet’,
’Inlet’,
: ’vertices by cinc0’, # In
’facet’,
’Outlet’,
: ’vertices by cinc1’, # Out
’facet’,
243
SfePy Documentation, Release 2015.1
ebc_1 = {
’name’ :
’region’
’dofs’ :
}
ebc_2 = {
’name’ :
’region’
’dofs’ :
}
’Walls’,
: ’Walls’,
{’u.all’ : 0.0},
’Inlet’,
: ’Inlet’,
{’u.1’ : 1.0, ’u.[0,2]’ : 0.0},
material_1 = {
’name’ : ’fluid’,
’values’ : {
’viscosity’ : 1.25e-3,
’density’ : 1e0,
},
}
variable_1 = {
’name’ : ’u’,
’kind’ : ’unknown field’,
’field’ : ’3_velocity’,
’order’ : 0,
}
variable_2 = {
’name’ : ’v’,
’kind’ : ’test field’,
’field’ : ’3_velocity’,
’dual’ : ’u’,
}
variable_3 = {
’name’ : ’p’,
’kind’ : ’unknown field’,
’field’ : ’pressure’,
’order’ : 1,
}
variable_4 = {
’name’ : ’q’,
’kind’ : ’test field’,
’field’ : ’pressure’,
’dual’ : ’p’,
}
variable_5 = {
’name’ : ’pp’,
’kind’ : ’parameter field’,
’field’ : ’pressure’,
’like’ : ’p’,
}
integral_1 = {
’name’ : ’i1’,
’order’ : 2,
}
integral_2 = {
’name’ : ’i2’,
’order’ : 3,
}
244
Chapter 5. Examples
SfePy Documentation, Release 2015.1
##
# Stationary Navier-Stokes equations.
equations = {
’balance’ :
"""+ dw_div_grad.i2.Omega( fluid.viscosity, v, u )
+ dw_convect.i2.Omega( v, u )
- dw_stokes.i1.Omega( v, p ) = 0""",
’incompressibility’ :
"""dw_stokes.i1.Omega( u, q ) = 0""",
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 5,
’eps_a’
: 1e-8,
’eps_r’
: 1.0,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 0.99999,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
}
def verify_incompressibility( out, problem, state, extend = False ):
"""This hook is normally used for post-processing (additional results can
be inserted into ‘out‘ dictionary), but here we just verify the weak
incompressibility condition."""
from sfepy.base.base import nm, output, assert_
vv = problem.get_variables()
one = nm.ones( (vv[’p’].field.n_nod,), dtype = nm.float64 )
vv[’p’].set_data(one)
zero = problem.evaluate(’dw_stokes.i1.Omega( u, p )’, p=one, u=vv[’u’]())
output(’div( u ) = %.3e’ % zero)
assert_(abs(zero) < 1e-14)
return out
##
# Functions.
import os.path as op
import sys
sys.path.append(data_dir) # Make installed example work.
import examples.navier_stokes.utils as utils
cinc_name = ’cinc_’ + op.splitext(op.basename(filename_mesh))[0]
5.3. Examples
245
SfePy Documentation, Release 2015.1
cinc = getattr(utils, cinc_name)
functions = {
’cinc0’ : (lambda coors, domain=None: cinc(coors, 0),),
’cinc1’ : (lambda coors, domain=None: cinc(coors, 1),),
}
navier_stokes/navier_stokes2d.py
Description
Navier-Stokes equations for incompressible fluid flow in 2D.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 +
Ω
((𝑢 · ∇)𝑢) · 𝑣 −
∫︁Ω
𝑝∇·𝑣 =0,
∀𝑣 ,
Ω
𝑞∇·𝑢=0,
∀𝑞 .
Ω
The mesh is created by gen_block_mesh() function.
View the results using:
$ ./postproc.py user_block.vtk -b
source code
246
Chapter 5. Examples
SfePy Documentation, Release 2015.1
# -*- coding: utf-8 -*r"""
Navier-Stokes equations for incompressible fluid flow in 2D.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} \nu\ \nabla \ul{v} : \nabla \ul{u}
+ \int_{\Omega} ((\ul{u} \cdot \nabla) \ul{u}) \cdot \ul{v}
- \int_{\Omega} p\ \nabla \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \nabla \cdot \ul{u}
= 0
\;, \quad \forall q \;.
The mesh is created by ‘‘gen_block_mesh()‘‘ function.
View the results using::
$ ./postproc.py user_block.vtk -b
"""
from sfepy.discrete.fem.meshio import UserMeshIO
from sfepy.mesh.mesh_generators import gen_block_mesh
# Mesh dimensions.
dims = [0.1, 0.1]
# Mesh resolution: increase to improve accuracy.
shape = [51, 51]
def mesh_hook(mesh, mode):
"""
Generate the block mesh.
"""
if mode == ’read’:
mesh = gen_block_mesh(dims, shape, [0, 0], name=’user_block’,
verbose=False)
return mesh
elif mode == ’write’:
pass
filename_mesh = UserMeshIO(mesh_hook)
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -0.0499)’, ’facet’),
’Right’ : (’vertices in (x > 0.0499)’, ’facet’),
’Bottom’ : (’vertices in (y < -0.0499)’, ’facet’),
’Top’ : (’vertices in (y > 0.0499)’, ’facet’),
’Walls’ : (’r.Left +v r.Right +v r.Bottom’, ’facet’),
}
materials = {
’fluid’ : ({’viscosity’ : 1.00e-2},),
}
5.3. Examples
247
SfePy Documentation, Release 2015.1
fields = {
’velocity’: (’real’, ’vector’, ’Omega’, 2),
’pressure’: (’real’, ’scalar’, ’Omega’, 1),
}
variables
’u’ :
’v’ :
’p’ :
’q’ :
}
= {
(’unknown field’, ’velocity’, 0),
(’test field’, ’velocity’, ’u’),
(’unknown field’, ’pressure’, 1),
(’test field’, ’pressure’, ’p’),
ebcs = {
’1_Walls’ : (’Walls’, {’u.all’ : 0.0}),
’0_Driven’ : (’Top’, {’u.0’ : 1.0, ’u.1’ : 0.0}),
’Pressure’ : (’Bottom’, {’p.0’ : 0.0}),
}
integrals = {
’i’ : 4,
}
equations = {
’balance’ :
"""+ dw_div_grad.i.Omega(fluid.viscosity, v, u)
+ dw_convect.i.Omega(v, u)
- dw_stokes.i.Omega(v, p) = 0""",
’incompressibility’ :
"""dw_stokes.i.Omega(u, q) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 15,
’eps_a’
: 1e-10,
’eps_r’
: 1.0,
}),
}
navier_stokes/navier_stokes2d_iga.py
Description
Navier-Stokes equations for incompressible fluid flow in 2D solved in a single patch NURBS domain using the isogeometric analysis (IGA) approach.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 +
Ω
((𝑢 · ∇)𝑢) · 𝑣 −
∫︁Ω
𝑝∇·𝑣 =0,
∀𝑣 ,
Ω
𝑞∇·𝑢=0,
∀𝑞 .
Ω
The domain geometry was created by:
248
Chapter 5. Examples
SfePy Documentation, Release 2015.1
$ ./script/gen_iga_patch.py -2 -d 0.1,0.1 -s 10,10 -o meshes/iga/block2d.iga
View the results using:
$ ./postproc.py block2d.vtk -b
source code
# -*- coding: utf-8 -*r"""
Navier-Stokes equations for incompressible fluid flow in 2D solved in a single
patch NURBS domain using the isogeometric analysis (IGA) approach.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} \nu\ \nabla \ul{v} : \nabla \ul{u}
+ \int_{\Omega} ((\ul{u} \cdot \nabla) \ul{u}) \cdot \ul{v}
- \int_{\Omega} p\ \nabla \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} q\ \nabla \cdot \ul{u}
= 0
\;, \quad \forall q \;.
The domain geometry was created by::
5.3. Examples
249
SfePy Documentation, Release 2015.1
$ ./script/gen_iga_patch.py -2 -d 0.1,0.1 -s 10,10 -o meshes/iga/block2d.iga
View the results using::
$ ./postproc.py block2d.vtk -b
"""
from sfepy import data_dir
filename_domain = data_dir + ’/meshes/iga/block2d.iga’
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices of set xi00’, ’facet’),
’Right’ : (’vertices of set xi01’, ’facet’),
’Bottom’ : (’vertices of set xi10’, ’facet’),
’Top’ : (’vertices of set xi11’, ’facet’),
’Walls’ : (’r.Left +v r.Right +v r.Bottom’, ’facet’),
}
materials = {
’fluid’ : ({’viscosity’ : 1.00e-2},),
}
fields = {
’velocity’: (’real’, ’vector’, ’Omega’, ’iga+1’, ’H1’, ’iga’),
’pressure’: (’real’, ’scalar’, ’Omega’, ’iga’, ’H1’, ’iga’),
}
variables
’u’ :
’v’ :
’p’ :
’q’ :
}
= {
(’unknown field’, ’velocity’, 0),
(’test field’, ’velocity’, ’u’),
(’unknown field’, ’pressure’, 1),
(’test field’, ’pressure’, ’p’),
ebcs = {
’1_Walls’ : (’Walls’, {’u.all’ : 0.0}),
’0_Driven’ : (’Top’, {’u.0’ : 1.0, ’u.1’ : 0.0}),
’Pressure’ : (’Bottom’, {’p.0’ : 0.0}),
}
integrals = {
’i’ : 6,
}
equations = {
’balance’ :
"""+ dw_div_grad.i.Omega(fluid.viscosity, v, u)
+ dw_convect.i.Omega(v, u)
- dw_stokes.i.Omega(v, p) = 0""",
’incompressibility’ :
"""dw_stokes.i.Omega(u, q) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
250
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’i_max’
’eps_a’
’eps_r’
: 15,
: 1e-10,
: 1.0,
}),
}
navier_stokes/stabilized_navier_stokes.py
Description
Stabilized Navier-Stokes problem with grad-div, SUPG and PSPG stabilization solved by a custom Oseen solver.
The stabilization terms are described in [1].
[1] G. Matthies and G. Lube. On streamline-diffusion methods of inf-sup stable discretisations of the generalised
Oseen problem. Number 2007-02 in Preprint Series of Institut fuer Numerische und Angewandte Mathematik, GeorgAugust-Universitaet Goettingen, 2007.
Find 𝑢, 𝑝 such that:
∫︀
∫︀
∫︀
𝜈∫︀ ∇𝑣 : ∇𝑢 Ω ((𝑏 · ∇)𝑢) · 𝑣 − Ω 𝑝 ∇ · 𝑣
+𝛾∑︀Ω (∇ · ∫︀𝑢) · (∇ · 𝑣)
+ 𝐾∈ℐℎ ∫︀𝑇𝐾 𝛿𝐾 ((𝑏 · ∇)𝑢) · ((𝑏 · ∇)𝑣)
∑︀
+ 𝐾∈ℐℎ 𝑇𝐾 𝛿𝐾 ∇𝑝 · ((𝑏 · ∇)𝑣) = 0 , ∀𝑣 ,
∫︀
𝑞 ∇ · 𝑢 ∫︀
Ω∑︀
+ 𝐾∈ℐℎ ∫︀𝑇𝐾 𝜏𝐾 ((𝑏 · ∇)𝑢) · ∇𝑞
∑︀
+ 𝐾∈ℐℎ 𝑇𝐾 𝜏𝐾 ∇𝑝 · ∇𝑞 = 0 , ∀𝑞 .
Ω
5.3. Examples
251
SfePy Documentation, Release 2015.1
source code
r"""
Stabilized Navier-Stokes problem with grad-div, SUPG and PSPG stabilization
solved by a custom Oseen solver.
The stabilization terms are described in [1].
[1] G. Matthies and G. Lube. On streamline-diffusion methods of inf-sup stable
discretisations of the generalised Oseen problem. Number 2007-02 in Preprint
Series of Institut fuer Numerische und Angewandte Mathematik,
Georg-August-Universitaet Goettingen, 2007.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\begin{array}{l}
\int_{\Omega} \nu\ \nabla \ul{v} : \nabla \ul{u}
\int_{\Omega} ((\ul{b} \cdot \nabla) \ul{u}) \cdot \ul{v}
- \int_{\Omega} p\ \nabla \cdot \ul{v} \\
+ \gamma \int_{\Omega} (\nabla\cdot\ul{u}) \cdot (\nabla\cdot\ul{v}) \\
+ \sum_{K \in \Ical_h}\int_{T_K} \delta_K\ ((\ul{b} \cdot \nabla)
\ul{u})\cdot ((\ul{b} \cdot \nabla) \ul{v}) \\
+ \sum_{K \in \Ical_h}\int_{T_K} \delta_K\ \nabla p\cdot ((\ul{b} \cdot
\nabla) \ul{v})
= 0
\;, \quad \forall \ul{v} \;,
252
Chapter 5. Examples
SfePy Documentation, Release 2015.1
\end{array}
\begin{array}{l}
\int_{\Omega} q\ \nabla \cdot \ul{u} \\
+ \sum_{K \in \Ical_h}\int_{T_K} \tau_K\ ((\ul{b} \cdot \nabla) \ul{u})
\cdot \nabla q \\
+ \sum_{K \in \Ical_h}\int_{T_K} \tau_K\ \nabla p \cdot \nabla q
= 0
\;, \quad \forall q \;.
\end{array}
"""
from sfepy.solvers.oseen import StabilizationFunction
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/3d/elbow2.mesh’
options = {
’solution’ : ’steady’,
’nls’ : ’oseen’,
’ls’ : ’ls’,
}
regions = {
’Omega’ : ’all’,
’Walls’ : (’vertices of surface -v (r.Outlet +v r.Inlet)’, ’facet’),
’Inlet’ : (’vertices by cinc0’, ’facet’),
’Outlet’ : (’vertices by cinc1’, ’facet’),
}
fields = {
’velocity’ : (’real’, 3, ’Omega’, 1),
’pressure’ : (’real’, 1, ’Omega’, 1),
}
variables
’u’
’v’
’b’
’p’
’q’
}
=
:
:
:
:
:
{
(’unknown field’,
(’test field’,
(’parameter field’,
(’unknown field’,
(’test field’,
’velocity’,
’velocity’,
’velocity’,
’pressure’,
’pressure’,
0),
’u’),
’u’),
1),
’p’),
ebcs = {
’Walls_velocity’ : (’Walls’, {’u.all’ : 0.0}),
’Inlet_velocity’ : (’Inlet’, {’u.1’ : 1.0, ’u.[0,2]’ : 0.0}),
}
materials = {
’fluid’ : ({’viscosity’ : 1.25e-5,
’density’ : 1e0},),
’stabil’ : ’stabil’,
}
integrals = {
’i1’ : 2,
’i2’ : 3,
}
5.3. Examples
253
SfePy Documentation, Release 2015.1
##
# Stationary Navier-Stokes equations with grad-div, SUPG and PSPG stabilization.
equations = {
’balance’ :
""" dw_div_grad.i2.Omega( fluid.viscosity, v, u )
+ dw_lin_convect.i2.Omega( v, b, u )
- dw_stokes.i1.Omega( v, p )
+ dw_st_grad_div.i1.Omega( stabil.gamma, v, u )
+ dw_st_supg_c.i1.Omega( stabil.delta, v, b, u )
+ dw_st_supg_p.i1.Omega( stabil.delta, v, b, p )
= 0""",
’incompressibility’ :
""" dw_stokes.i1.Omega( u, q )
+ dw_st_pspg_c.i1.Omega( stabil.tau, q, b, u )
+ dw_st_pspg_p.i1.Omega( stabil.tau, q, p )
= 0""",
}
solver_1 = {
’name’ : ’oseen’,
’kind’ : ’nls.oseen’,
’stabil_mat’ : ’stabil’,
’adimensionalize’ : False,
’check_navier_stokes_rezidual’ : False,
’i_max’
’eps_a’
’eps_r’
’macheps’
’lin_red’
:
:
:
:
:
10,
1e-8,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
# Uncomment the following to get a convergence log.
## ’log’
: {’text’ : ’oseen_log.txt’,
##
’plot’ : ’oseen_log.png’},
}
solver_2 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
##
# Functions.
import os.path as op
import sys
sys.path.append(data_dir) # Make installed example work.
import examples.navier_stokes.utils as utils
cinc_name = ’cinc_’ + op.splitext(op.basename(filename_mesh))[0]
cinc = getattr(utils, cinc_name)
name_map = {’p’ : ’p’, ’q’ : ’q’, ’u’ : ’u’, ’b’ : ’b’, ’v’ : ’v’,
’fluid’ : ’fluid’, ’omega’ : ’omega’, ’i1’ : ’i1’, ’i2’ : ’i2’,
’viscosity’ : ’viscosity’, ’velocity’ : ’velocity’,
’gamma’ : ’gamma’, ’delta’ : ’delta’, ’tau’ : ’tau’}
254
Chapter 5. Examples
SfePy Documentation, Release 2015.1
functions = {
’cinc0’ : (lambda coors, domain=None: cinc(coors, 0),),
’cinc1’ : (lambda coors, domain=None: cinc(coors, 1),),
’stabil’ : (StabilizationFunction(name_map),),
}
navier_stokes/stokes.py
Description
Stokes equations for incompressible fluid flow.
This example demonstrates fields defined on subdomains as well as use of periodic boundary conditions.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 −
𝑝∇·𝑣 =0,
𝑌1 ∪𝑌2
𝑌1 ∪𝑌2
∫︁
𝑞 ∇ · 𝑢 = 0 , ∀𝑞 .
∀𝑣 ,
𝑌1 ∪𝑌2
source code
r"""
Stokes equations for incompressible fluid flow.
5.3. Examples
255
SfePy Documentation, Release 2015.1
This example demonstrates fields defined on subdomains as well as use of
periodic boundary conditions.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{Y_1 \cup Y_2} \nu\ \nabla \ul{v} : \nabla \ul{u}
- \int_{Y_1 \cup Y_2} p\ \nabla \cdot \ul{v}
= 0
\;, \quad \forall \ul{v} \;,
\int_{Y_1 \cup Y_2} q\ \nabla \cdot \ul{u}
= 0
\;, \quad \forall q \;.
"""
from sfepy import data_dir
from sfepy.discrete.fem.periodic import match_y_line
filename_mesh = data_dir + ’/meshes/2d/special/channels_symm944t.mesh’
if filename_mesh.find( ’symm’ ):
region_1 = {
’name’ : ’Y1’,
’select’ : """cells of group 3""",
}
region_2 = {
’name’ : ’Y2’,
’select’ : """cells of group 4 +c cells of group 6
+c cells of group 8""",
}
region_4 = {
’name’ : ’Y1Y2’,
’select’ : """r.Y1 +c r.Y2""",
}
region_5 = {
’name’ : ’Walls’,
’select’ : """r.EBCGamma1 +v r.EBCGamma2""",
’kind’ : ’facet’,
}
region_310 = {
’name’ : ’EBCGamma1’,
’select’ : """(cells of group 1 *v cells of group 3)
+v
(cells of group 2 *v cells of group 3)
""",
’kind’ : ’facet’,
}
region_320 = {
’name’ : ’EBCGamma2’,
’select’ : """(cells of group 5 *v cells of group 4)
+v
(cells of group 1 *v cells of group 4)
+v
(cells of group 7 *v cells of group 6)
+v
(cells of group 2 *v cells of group 6)
+v
(cells of group 9 *v cells of group 8)
256
Chapter 5. Examples
SfePy Documentation, Release 2015.1
+v
(cells of group 2 *v cells of group 8)
""",
’kind’ : ’facet’,
}
w2 = 0.499
# Sides.
region_20 = {
’name’ : ’Left’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_21 = {
’name’ : ’Right’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_22 = {
’name’ : ’Bottom’,
’select’ : ’vertices
’kind’ : ’facet’,
}
region_23 = {
’name’ : ’Top’,
’select’ : ’vertices
’kind’ : ’facet’,
}
in (x < %.3f)’ % -w2,
in (x > %.3f)’ % w2,
in (y < %.3f)’ % -w2,
in (y > %.3f)’ % w2,
field_1 = {
’name’ : ’2_velocity’,
’dtype’ : ’real’,
’shape’ : (2,),
’region’ : ’Y1Y2’,
’approx_order’ : 2,
}
field_2 = {
’name’ : ’pressure’,
’dtype’ : ’real’,
’shape’ : (1,),
’region’ : ’Y1Y2’,
’approx_order’ : 1,
}
variable_1 = {
’name’ : ’u’,
’kind’ : ’unknown field’,
’field’ : ’2_velocity’,
’order’ : 0,
}
variable_2 = {
’name’ : ’v’,
’kind’ : ’test field’,
’field’ : ’2_velocity’,
’dual’ : ’u’,
}
5.3. Examples
257
SfePy Documentation, Release 2015.1
variable_3 = {
’name’ : ’p’,
’kind’ : ’unknown field’,
’field’ : ’pressure’,
’order’ : 1,
}
variable_4 = {
’name’ : ’q’,
’kind’ : ’test field’,
’field’ : ’pressure’,
’dual’ : ’p’,
}
integral_1 = {
’name’ : ’i’,
’order’ : 2,
}
equations = {
’balance’ :
"""dw_div_grad.i.Y1Y2( fluid.viscosity, v, u )
- dw_stokes.i.Y1Y2( v, p ) = 0""",
’incompressibility’ :
"""dw_stokes.i.Y1Y2( u, q ) = 0""",
}
material_1 = {
’name’ : ’fluid’,
’values’ : {
’viscosity’ : 1.0,
’density’ : 1e0,
},
}
ebc_1 = {
’name’ :
’region’
’dofs’ :
}
ebc_2 = {
’name’ :
’region’
’dofs’ :
}
ebc_10 = {
’name’ :
’region’
’dofs’ :
}
’walls’,
: ’Walls’,
{’u.all’ : 0.0},
’top_velocity’,
: ’Top’,
{’u.1’ : -1.0, ’u.0’ : 0.0},
’bottom_pressure’,
: ’Bottom’,
{’p.0’ : 0.0},
epbc_1 = {
’name’ : ’u_rl’,
’region’ : [’Left’, ’Right’],
’dofs’ : {’u.all’ : ’u.all’, ’p.0’ : ’p.0’},
’match’ : ’match_y_line’,
}
functions = {
258
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’match_y_line’ : (match_y_line,),
}
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 2,
’eps_a’
: 1e-8,
’eps_r’
: 1e-2,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 1.1,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
}
save_format = ’hdf5’ # ’hdf5’ or ’vtk’
navier_stokes/stokes_slip_bc.py
Description
Incompressible Stokes flow with Navier (slip) boundary conditions, flow driven by a moving wall and a small diffusion
for stabilization.
This example demonstrates the use of no-penetration boundary conditions as well as edge direction boundary conditions together with Navier or slip boundary conditions.
Find 𝑢, 𝑝 such that:
∫︁
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 −
Ω
∫︁
𝑝∇·𝑣+
Ω
∫︁
Ω
𝛽𝑣 · (𝑢 − 𝑢𝑑 ) +
𝛽𝑣 · 𝑢 = 0 ,
Γ2
∫︁
𝜇∇𝑞 · ∇𝑝 +
𝑞 ∇ · 𝑢 = 0 , ∀𝑞 ,
∀𝑣 ,
Γ1
Ω
where 𝜈 is the fluid viscosity, 𝛽 is the slip coefficient, 𝜇 is the (small) numerical diffusion coefficient, Γ1 is the top
wall that moves with the given driving velocity 𝑢𝑑 and Γ2 are the remaining walls. The Navier conditions are in effect
on both Γ1 , Γ2 and are expressed by the corresponding integrals in the equations above.
The no-penetration boundary conditions are applied on Γ1 , Γ2 , except the vertices of the block edges, where the edge
direction boundary conditions are applied. Optionally, Dirichlet boundary conditions can be applied on the inlet, see
the code below.
The mesh is created by gen_block_mesh() function - try different mesh dimensions and resolutions below. For
large meshes use the ’ls_i’ linear solver - PETSc + petsc4py is needed in that case.
5.3. Examples
259
SfePy Documentation, Release 2015.1
source code
r"""
Incompressible Stokes flow with Navier (slip) boundary conditions, flow driven
by a moving wall and a small diffusion for stabilization.
This example demonstrates the use of ‘no-penetration‘ boundary conditions as
well as ‘edge direction‘ boundary conditions together with Navier or slip
boundary conditions.
Find :math:‘\ul{u}‘, :math:‘p‘ such that:
.. math::
\int_{\Omega} \nu\ \nabla \ul{v} : \nabla \ul{u}
- \int_{\Omega} p\ \nabla \cdot \ul{v}
+ \int_{\Gamma_1} \beta \ul{v} \cdot (\ul{u} - \ul{u}_d)
+ \int_{\Gamma_2} \beta \ul{v} \cdot \ul{u}
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} \mu \nabla q \cdot \nabla p
+ \int_{\Omega} q\ \nabla \cdot \ul{u}
= 0
\;, \quad \forall q \;,
where :math:‘\nu‘ is the fluid viscosity, :math:‘\beta‘ is the slip
coefficient, :math:‘\mu‘ is the (small) numerical diffusion coefficient,
260
Chapter 5. Examples
SfePy Documentation, Release 2015.1
:math:‘\Gamma_1‘ is the top wall that moves with the given driving velocity
:math:‘\ul{u}_d‘ and :math:‘\Gamma_2‘ are the remaining walls. The Navier
conditions are in effect on both :math:‘\Gamma_1‘, :math:‘\Gamma_2‘ and are
expressed by the corresponding integrals in the equations above.
The ‘no-penetration‘ boundary conditions are applied on :math:‘\Gamma_1‘,
:math:‘\Gamma_2‘, except the vertices of the block edges, where the ‘edge
direction‘ boundary conditions are applied. Optionally, Dirichlet boundary
conditions can be applied on the inlet, see the code below.
The mesh is created by ‘‘gen_block_mesh()‘‘ function - try different mesh
dimensions and resolutions below. For large meshes use the ‘‘’ls_i’‘‘ linear
solver - PETSc + petsc4py is needed in that case.
"""
import numpy as nm
from sfepy.discrete.fem.meshio import UserMeshIO
from sfepy.mesh.mesh_generators import gen_block_mesh
from sfepy.homogenization.utils import define_box_regions
# Mesh dimensions.
dims = nm.array([3, 1, 0.5])
# Mesh resolution: increase to improve accuracy.
shape = [11, 15, 15]
def mesh_hook(mesh, mode):
"""
Generate the block mesh.
"""
if mode == ’read’:
mesh = gen_block_mesh(dims, shape, [0, 0, 0], name=’user_block’,
verbose=False)
return mesh
elif mode == ’write’:
pass
filename_mesh = UserMeshIO(mesh_hook)
regions = define_box_regions(3, 0.5 * dims)
regions.update({
’Omega’ : ’all’,
’Edges_v’ : ("""(r.Near *v r.Bottom) +v
(r.Bottom *v r.Far) +v
(r.Far *v r.Top) +v
(r.Top *v r.Near)""", ’edge’),
’Gamma1_f’ : (’copy r.Top’, ’face’),
’Gamma2_f’ : (’r.Near +v r.Bottom +v r.Far’, ’face’),
’Gamma_f’ : (’r.Gamma1_f +v r.Gamma2_f’, ’face’),
’Gamma_v’ : (’r.Gamma_f -v r.Edges_v’, ’face’),
’Inlet_f’ : (’r.Left -v r.Gamma_f’, ’face’),
})
fields = {
’velocity’ : (’real’, 3, ’Omega’, 1),
’pressure’ : (’real’, 1, ’Omega’, 1),
}
5.3. Examples
261
SfePy Documentation, Release 2015.1
def get_u_d(ts, coors, region=None):
"""
Given stator velocity.
"""
out = nm.zeros_like(coors)
out[:] = [1.0, 1.0, 0.0]
return out
functions = {
’get_u_d’ : (get_u_d,),
}
variables
’u’ :
’v’ :
’u_d’
= {
(’unknown field’, ’velocity’, 0),
(’test field’,
’velocity’, ’u’),
: (’parameter field’, ’velocity’,
{’setter’ : ’get_u_d’}),
’p’ : (’unknown field’, ’pressure’, 1),
’q’ : (’test field’,
’pressure’, ’p’),
}
# Try setting the inlet velocity by un-commenting the ebcs.
ebcs = {
## ’inlet’ : (’Inlet_f’, {’u.0’ : 1.0, ’u.[1, 2]’ : 0.0}),
}
lcbcs = {
’walls’ : (’Gamma_v’, {’u.all’ : None}, None, ’no_penetration’,
’normals_Gamma.vtk’),
’edges’ : (’Edges_v’, [(-0.5, 1.5)], {’u.all’ : None}, None,
’edge_direction’, ’edges_Edges.vtk’),
}
materials = {
’m’ : ({
’nu’ : 1e-3,
’beta’ : 1e-2,
’mu’ : 1e-10,
},),
}
equations = {
’balance’ :
"""dw_div_grad.5.Omega(m.nu, v, u)
- dw_stokes.5.Omega(v, p)
+ dw_surface_dot.5.Gamma1_f(m.beta, v, u)
+ dw_surface_dot.5.Gamma2_f(m.beta, v, u)
=
+ dw_surface_dot.5.Gamma1_f(m.beta, v, u_d)""",
’incompressibility’ :
"""dw_laplace.5.Omega(m.mu, q, p)
+ dw_stokes.5.Omega(u, q) = 0""",
}
solvers = {
’ls_d’ : (’ls.scipy_direct’, {}),
## ’ls_i’ : (’ls.petsc’, {
262
Chapter 5. Examples
SfePy Documentation, Release 2015.1
##
’method’ : ’bcgsl’, # ksp_type
##
’precond’ : ’ilu’, # pc_type
##
’eps_a’ : 0.0, # abstol
##
’eps_r’ : 1e-12, # rtol
##
’eps_d’ : 1e10, # Divergence tolerance.
##
’i_max’ : 2500, # maxits
## }),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’
: 1e-10,
}),
}
options = {
’nls’ : ’newton’,
’ls’ : ’ls_d’,
}
navier_stokes/utils.py
Description
missing description!
source code
##
# Functions.
import numpy as nm
from sfepy.linalg import get_coors_in_tube
# last revision: 01.08.2007
def cinc_cylinder(coors, mode):
axis = nm.array([1, 0, 0], nm.float64)
if mode == 0: # In
centre = nm.array([-0.00001, 0.0, 0.0], nm.float64)
radius = 0.019
length = 0.00002
elif mode == 1: # Out
centre = nm.array([0.09999, 0.0, 0.0], nm.float64)
radius = 0.019
length = 0.00002
else:
centre = nm.array([0.05, 0.0, 0.0], nm.float64)
radius = 0.012
length = 0.04
return get_coors_in_tube(coors, centre, axis, -1.0, radius, length)
def cinc_elbow2(coors, mode):
if mode == 0: # In
centre = nm.array([0.0, -0.00001, 0.0], nm.float64)
else: # Out
centre = nm.array([0.2, -0.00001, 0.0], nm.float64)
axis = nm.array([0, 1, 0], nm.float64)
radius = 0.029
5.3. Examples
263
SfePy Documentation, Release 2015.1
length = 0.00002
return get_coors_in_tube(coors, centre, axis, -1.0, radius, length)
5.3.9 phononic
phononic/band_gaps.py
Description
Acoustic band gaps in a strongly heterogeneous elastic body, detected using homogenization techniques.
A reference periodic cell contains two domains: the stiff matrix 𝑌𝑚 and the soft (but heavy) inclusion 𝑌𝑐 .
source code
"""
Acoustic band gaps in a strongly heterogeneous elastic body, detected using
homogenization techniques.
A reference periodic cell contains two domains: the stiff matrix :math:‘Y_m‘
and the soft (but heavy) inclusion :math:‘Y_c‘.
"""
from sfepy import data_dir
from sfepy.base.base import Struct
from sfepy.base.ioutils import InDir
from sfepy.homogenization.coefficients import Coefficients
from band_gaps_conf import BandGapsConf, get_pars, clip_sqrt, normalize
clip_sqrt, normalize # Make pyflakes happy...
incwd = InDir(__file__)
filename = data_dir + ’/meshes/2d/special/circle_in_square.mesh’
output_dir = incwd(’output/band_gaps’)
# aluminium, in 1e+10 Pa
D_m = get_pars(2, 5.898, 2.681)
density_m = 0.2799 # in 1e4 kg/m3
# epoxy, in 1e+10 Pa
D_c = get_pars(2, 0.1798, 0.148)
density_c = 0.1142 # in 1e4 kg/m3
mat_pars = Coefficients(D_m=D_m, density_m=density_m,
D_c=D_c, density_c=density_c)
region_selects = Struct(matrix=’cells of group 1’,
inclusion=’cells of group 2’)
corrs_save_names = {’evp’ : ’evp’, ’corrs_rs’ : ’corrs_rs’}
options = {
’plot_transform_angle’ : None,
’plot_transform_wave’ : (’clip_sqrt’, (0, 30)),
’plot_transform’ : (’normalize’, (-2, 2)),
264
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’fig_name’ : ’band_gaps’,
’fig_name_angle’ : ’band_gaps_angle’,
’fig_name_wave’ : ’band_gaps_wave’,
’fig_suffix’ : ’.pdf’,
’coefs_filename’ : ’coefs.txt’,
’incident_wave_dir’ : [1.0, 1.0],
’plot_options’ : {
’show’ : True,
’legend’ : True,
},
’plot_labels’ : {
’band_gaps’ : {
’resonance’ : r’$\lambda^r$’,
’masked’ : r’masked $\lambda^r$’,
’eig_min’ : r’min eig($M$)’,
’eig_max’ : r’max eig($M$)’,
’x_axis’ : r’$\sqrt{\lambda}$, $\omega$’,
’y_axis’ : r’eigenvalues of mass matrix $M$’,
},
},
’plot_rsc’ : {
’params’ : {’axes.labelsize’: ’x-large’,
’text.fontsize’: ’large’,
’legend.fontsize’: ’large’,
’legend.loc’: 1,
’xtick.labelsize’: ’large’,
’ytick.labelsize’: ’large’,
’text.usetex’: True},
},
}
evp_options = {
’eigensolver’ : ’eig.sgscipy’,
’save_eig_vectors’ : (12, 0),
’scale_epsilon’ : 1.0,
’elasticity_contrast’ : 1.0,
}
eigenmomenta_options = {
# eigenmomentum threshold,
’threshold’ : 1e-2,
# eigenmomentum threshold is relative w.r.t. largest one,
’threshold_is_relative’ : True,
}
band_gaps_options = {
’eig_range’ : (0, 30), # -> freq_range
# = sqrt(eigs[slice(*eig_range)][[0, -1]])
’freq_margins’ : (10, 10), # % of freq_range
’freq_eps’ : 1e-12, # frequency
’zezo_eps’ : 1e-12, # zero finding
’freq_step’ : 0.0001, # % of freq_range
’log_save_name’ : ’band_gaps.log’,
}
5.3. Examples
265
SfePy Documentation, Release 2015.1
conf = BandGapsConf(filename, 1, region_selects, mat_pars, options,
evp_options, eigenmomenta_options, band_gaps_options,
corrs_save_names=corrs_save_names, incwd=incwd,
output_dir=output_dir)
define = lambda: conf.conf.to_dict()
phononic/band_gaps_conf.py
Description
Configuration classes for acoustic band gaps in a strongly heterogeneous elastic body.
source code
"""
Configuration classes for acoustic band gaps in a strongly heterogeneous
elastic body.
"""
import numpy as nm
from sfepy.base.base import get_default, import_file, Struct
from sfepy.base.conf import ProblemConf
from sfepy.discrete.fem import MeshIO
import sfepy.discrete.fem.periodic as per
from sfepy.mechanics.matcoefs import stiffness_from_lame, TransformToPlane
from sfepy.homogenization.utils import define_box_regions, get_lattice_volume
import sfepy.homogenization.coefs_base as cb
import sfepy.homogenization.coefs_phononic as cp
def get_pars(dim, lam, mu):
c = stiffness_from_lame(3, lam, mu)
if dim == 2:
tr = TransformToPlane()
try:
c = tr.tensor_plane_stress(c3=c)
except:
sym = (dim + 1) * dim / 2
c = nm.zeros((sym, sym), dtype=nm.float64)
return c
def set_coef_d(variables, ir, ic, mode, pis, corrs_rs):
mode2var = {’row’ : ’u1_m’, ’col’ : ’u2_m’}
val = pis.states[ir, ic][’u_m’] + corrs_rs.states[ir, ic][’u_m’]
variables[mode2var[mode]].set_data(val)
class BandGapsConf(Struct):
"""
Configuration class for acoustic band gaps in a strongly heterogeneous
elastic body.
"""
def __init__(self, filename, approx, region_selects, mat_pars, options,
evp_options, eigenmomenta_options, band_gaps_options,
266
Chapter 5. Examples
SfePy Documentation, Release 2015.1
coefs_save_name=’coefs’,
corrs_save_names=None,
incwd=None,
output_dir=None, **kwargs):
Struct.__init__(self, approx=approx, region_selects=region_selects,
mat_pars=mat_pars, options=options,
evp_options=evp_options,
eigenmomenta_options=eigenmomenta_options,
band_gaps_options=band_gaps_options,
**kwargs)
self.incwd = get_default(incwd, lambda x: x)
self.conf = Struct()
self.conf.filename_mesh = self.incwd(filename)
output_dir = get_default(output_dir, self.incwd(’output’))
default = {’evp’ : ’evp’, ’corrs_rs’ : ’corrs_rs’}
self.corrs_save_names = get_default(corrs_save_names,
default)
io = MeshIO.any_from_filename(self.conf.filename_mesh)
self.bbox, self.dim = io.read_bounding_box(ret_dim=True)
rpc_axes = nm.eye(self.dim, dtype=nm.float64) \
* (self.bbox[1] - self.bbox[0])
self.conf.options = options
self.conf.options.update({
’output_dir’ : output_dir,
’volume’ : {
’value’ : get_lattice_volume(rpc_axes),
},
’coefs’ : ’coefs’,
’requirements’ : ’requirements’,
’coefs_filename’ : coefs_save_name,
})
self.conf.mat_pars = mat_pars
self.conf.solvers = self.define_solvers()
self.conf.regions = self.define_regions()
self.conf.materials = self.define_materials()
self.conf.fields = self.define_fields()
self.conf.variables = self.define_variables()
(self.conf.ebcs, self.conf.epbcs,
self.conf.lcbcs, self.all_periodic) = self.define_bcs()
self.conf.functions = self.define_functions()
self.conf.integrals = self.define_integrals()
self.equations, self.expr_coefs = self.define_equations()
self.conf.coefs = self.define_coefs()
self.conf.requirements = self.define_requirements()
def __call__(self):
return ProblemConf.from_dict(self.conf.__dict__,
5.3. Examples
267
SfePy Documentation, Release 2015.1
import_file(__file__))
def define_solvers(self):
solvers = {
’ls_d’ : (’ls.scipy_direct’, {}),
’ls_i’ : (’ls.scipy_iterative’, {
’method’ : ’cg’,
’i_max’
: 1000,
’eps_a’
: 1e-12,
}),
’newton’ : (’nls.newton’, {
’i_max’ : 1,
’eps_a’ : 1e-4,
}),
}
return solvers
def define_regions(self):
regions = {
’Y’ : ’all’,
’Y_m’ : self.region_selects.matrix,
’Y_c’ : self.region_selects.inclusion,
’Gamma_mc’: (’r.Y_m *v r.Y_c’, ’facet’),
}
regions.update(define_box_regions(self.dim,
self.bbox[0], self.bbox[1], 1e-5))
return regions
def define_materials(self):
materials = {
’m’ : ({
’D_m’ : self.mat_pars.D_m,
’density_m’ : self.mat_pars.density_m,
’D_c’ : self.mat_pars.D_c,
’density_c’ : self.mat_pars.density_c,
}, None, None, {’special_constant’ : True}),
}
return materials
def define_fields(self):
fields = {
’vector_Y_m’ : (’real’, self.dim, ’Y_m’, self.approx),
’vector_Y_c’ : (’real’, self.dim, ’Y_c’, self.approx),
’scalar_Y’ : (’real’, 1, ’Y’, 1),
}
return fields
def define_variables(self):
variables = {
’u_m’ : (’unknown field’, ’vector_Y_m’),
’v_m’ : (’test field’, ’vector_Y_m’, ’u_m’),
’Pi’
: (’parameter field’, ’vector_Y_m’, ’(set-to-None)’),
’u1_m’
: (’parameter field’, ’vector_Y_m’, ’(set-to-None)’),
’u2_m’
: (’parameter field’, ’vector_Y_m’, ’(set-to-None)’),
268
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’u_c’ : (’unknown field’, ’vector_Y_c’),
’v_c’ : (’test field’, ’vector_Y_c’, ’u_c’),
’aux’
: (’parameter field’, ’scalar_Y’, ’(set-to-None)’),
}
return variables
def define_bcs(self):
ebcs = {
’fixed_corners’ : (’Corners’, {’u_m.all’ : 0.0}),
’fixed_gamma_mc’ : (’Gamma_mc’, {’u_c.all’ : 0.0}),
}
epbcs = {}
all_periodic = []
for vn in [’u_m’]:
val = {’%s.all’ % vn : ’%s.all’ % vn}
epbcs.update({
’periodic_%s_x’ % vn : ([’Left’, ’Right’], val,
’match_y_line’),
’periodic_%s_y’ % vn : ([’Top’, ’Bottom’], val,
’match_x_line’),
})
all_periodic.extend([’periodic_%s_x’ % vn, ’periodic_%s_y’ % vn])
lcbcs = {}
return ebcs, epbcs, lcbcs, all_periodic
def define_functions(self):
functions = {
’match_x_line’ : (per.match_x_line,),
’match_y_line’ : (per.match_y_line,),
}
return functions
def define_integrals(self):
integrals = {
’i’ : 2,
}
return integrals
def define_equations(self):
equations = {}
equations[’corrs_rs’] = {
’balance_of_forces’ :
"""dw_lin_elastic.i.Y_m( m.D_m, v_m, u_m )
= - dw_lin_elastic.i.Y_m( m.D_m, v_m, Pi )""",
}
equations[’evp’] = {
’lhs’ : """dw_lin_elastic.i.Y_c( m.D_c, v_c, u_c )""",
’rhs’ : """dw_volume_dot.i.Y_c( m.density_c, v_c, u_c )""",
}
expr_coefs = {
5.3. Examples
269
SfePy Documentation, Release 2015.1
’D’ : """dw_lin_elastic.i.Y_m( m.D_m, u1_m, u2_m )""",
’VF’ : """d_volume.i.%s(aux)""",
’ema’ : """ev_volume_integrate.i.Y_c( m.density_c, u_c )""",
}
return equations, expr_coefs
def define_coefs(self):
from copy import copy
ema_options = copy(self.eigenmomenta_options)
ema_options.update({’var_name’ : ’u_c’})
coefs = {
# Basic.
’VF’ : {
’regions’ : [’Y_m’, ’Y_c’],
’expression’ : self.expr_coefs[’VF’],
’class’ : cb.VolumeFractions,
},
’dv_info’ : {
’requires’ : [’c.VF’],
’region_to_material’ : {’Y_m’ : (’m’, ’density_m’),
’Y_c’ : (’m’, ’density_c’),},
’class’ : cp.DensityVolumeInfo,
},
’eigenmomenta’ : {
’requires’ : [’evp’, ’c.dv_info’],
’expression’ : self.expr_coefs[’ema’],
’options’ : ema_options,
’class’ : cp.Eigenmomenta,
},
’M’ : {
’requires’ : [’evp’, ’c.dv_info’, ’c.eigenmomenta’],
’class’ : cp.AcousticMassTensor,
},
’band_gaps’ : {
’requires’ : [’evp’, ’c.eigenmomenta’, ’c.M’],
’options’ : self.band_gaps_options,
’class’ : cp.BandGaps,
},
# Dispersion.
’D’ : {
’requires’ : [’pis’, ’corrs_rs’],
’expression’ : self.expr_coefs[’D’],
’set_variables’ : set_coef_d,
’class’ : cb.CoefSymSym,
},
’Gamma’ : {
’requires’ : [’c.D’],
’options’ : {
’mode’ : ’simple’,
’incident_wave_dir’ : None,
},
’class’ : cp.ChristoffelAcousticTensor,
},
270
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’dispersion’ : {
’requires’ : [’evp’, ’c.eigenmomenta’, ’c.M’, ’c.Gamma’],
’options’ : self.band_gaps_options,
’class’ : cp.BandGaps,
},
’polarization_angles’ : {
’requires’ : [’c.dispersion’],
’options’ : {
’incident_wave_dir’ : None,
},
’class’ : cp.PolarizationAngles,
},
# Phase velocity.
’phase_velocity’ : {
’requires’ : [’c.dv_info’, ’c.Gamma’],
’options’ : {
’eigensolver’ : ’eig.sgscipy’,
},
’class’ : cp.PhaseVelocity,
},
’filenames’ : {},
}
return coefs
def define_requirements(self):
requirements = {
# Basic.
’evp’ : {
’ebcs’ : [’fixed_gamma_mc’],
’epbcs’ : None,
’equations’ : self.equations[’evp’],
’save_name’ : self.corrs_save_names[’evp’],
’dump_variables’ : [’u_c’],
’options’ : self.evp_options,
’class’ : cp.SimpleEVP,
},
# Dispersion.
’pis’ : {
’variables’ : [’u_m’],
’class’ : cb.ShapeDimDim,
},
’corrs_rs’ : {
’requires’ : [’pis’],
’ebcs’ : [’fixed_corners’],
’epbcs’ : self.all_periodic,
’equations’ : self.equations[’corrs_rs’],
’set_variables’ : [(’Pi’, ’pis’, ’u_m’)],
’save_name’ : self.corrs_save_names[’corrs_rs’],
’dump_variables’ : [’u_m’],
’is_linear’ : True,
’class’ : cb.CorrDimDim,
},
}
return requirements
5.3. Examples
271
SfePy Documentation, Release 2015.1
class BandGapsRigidConf(BandGapsConf):
"""
Configuration class for acoustic band gaps in a strongly heterogeneous
elastic body with rigid inclusions.
"""
def define_regions(self):
regions = BandGapsConf.define_regions(self)
regions[’Y_cr’] = regions[’Y_c’]
regions.update({
’Y_r’ : ’vertices by select_yr’,
’Y_c’ : ’r.Y_cr -c r.Y_r’,
})
return regions
def define_materials(self):
materials = BandGapsConf.define_materials(self)
materials[’m’][0].update({
’D_r’ : self.mat_pars.D_r,
’density_r’ : self.mat_pars.density_r,
})
return materials
def define_fields(self):
fields = {
’vector_Y_cr’ : (’real’, self.dim, ’Y_cr’, self.approx),
’scalar_Y’ : (’real’, 1, ’Y’, 1),
}
return fields
def define_variables(self):
variables = {
’u’ : (’unknown field’, ’vector_Y_cr’),
’v’ : (’test field’, ’vector_Y_cr’, ’u’),
’aux’
: (’parameter field’, ’scalar_Y’, ’(set-to-None)’),
}
return variables
def define_bcs(self):
ebcs = {
’fixed_gamma_mc’ : (’Gamma_mc’, {’u.all’ : 0.0}),
}
lcbcs ={
’rigid’ : (’Y_r’,{’u.all’ : None}, None, ’rigid’),
}
return ebcs, {}, lcbcs, []
def define_functions(self):
functions = BandGapsConf.define_functions(self)
functions.update({
’select_yr’ : (self.select_yr,),
})
return functions
272
Chapter 5. Examples
SfePy Documentation, Release 2015.1
def define_equations(self):
equations = {}
# dw_lin_elastic.i.Y_r( m.D_r, v, u ) should have no effect!
equations[’evp’] = {
’lhs’ : """dw_lin_elastic.i.Y_c( m.D_c, v, u )
+ dw_lin_elastic.i.Y_r( m.D_r, v, u )""",
’rhs’ : """dw_volume_dot.i.Y_c( m.density_c, v, u )
+ dw_volume_dot.i.Y_r( m.density_r, v, u )""",
}
expr_coefs = {
’VF’ : """d_volume.i.%s(aux)""",
’ema’ : """ev_volume_integrate.i.Y_c( m.density_c, u )
+ ev_volume_integrate.i.Y_r( m.density_r, u )""",
}
return equations, expr_coefs
def define_coefs(self):
from copy import copy
ema_options = copy(self.eigenmomenta_options)
ema_options.update({’var_name’ : ’u’})
coefs = {
# Basic.
’VF’ : {
’regions’ : [’Y_m’, ’Y_cr’, ’Y_c’, ’Y_r’],
’expression’ : self.expr_coefs[’VF’],
’class’ : cb.VolumeFractions,
},
’dv_info’ : {
’requires’ : [’c.VF’],
’region_to_material’ : {’Y_m’ : (’m’, ’density_m’),
’Y_c’ : (’m’, ’density_c’),
’Y_r’ : (’m’, ’density_r’),},
’class’ : cp.DensityVolumeInfo,
},
’eigenmomenta’ : {
’requires’ : [’evp’, ’c.dv_info’],
’expression’ : self.expr_coefs[’ema’],
’options’ : ema_options,
’class’ : cp.Eigenmomenta,
},
’M’ : {
’requires’ : [’evp’, ’c.dv_info’, ’c.eigenmomenta’],
’class’ : cp.AcousticMassTensor,
},
’band_gaps’ : {
’requires’ : [’evp’, ’c.eigenmomenta’, ’c.M’],
’options’ : self.band_gaps_options,
’class’ : cp.BandGaps,
},
’filenames’ : {},
}
5.3. Examples
273
SfePy Documentation, Release 2015.1
return coefs
def define_requirements(self):
requirements = {
# Basic.
’evp’ : {
’ebcs’ : [’fixed_gamma_mc’],
’epbcs’ : None,
’lcbcs’ : [’rigid’],
’equations’ : self.equations[’evp’],
’save_name’ : self.corrs_save_names[’evp’],
’dump_variables’ : [’u’],
’options’ : self.evp_options,
’class’ : cp.SimpleEVP,
},
}
return requirements
def clip(data, plot_range):
return nm.clip(data, *plot_range)
def clip_sqrt(data, plot_range):
return nm.clip(nm.sqrt(data), *plot_range)
def normalize(data, plot_range):
aux = nm.arctan(data)
return clip(aux, plot_range)
phononic/band_gaps_rigid.py
Description
Acoustic band gaps in a strongly heterogeneous elastic body with a rigid inclusion, detected using homogenization
techniques.
A reference periodic cell contains three domains: the stiff matrix 𝑌𝑚 and the soft inclusion 𝑌𝑐 enclosing the rigid
heavy sub-inclusion 𝑌𝑟 .
source code
"""
Acoustic band gaps in a strongly heterogeneous elastic body with a rigid
inclusion, detected using homogenization techniques.
A reference periodic cell contains three domains: the stiff matrix :math:‘Y_m‘
and the soft inclusion :math:‘Y_c‘ enclosing the rigid heavy sub-inclusion
:math:‘Y_r‘.
"""
import numpy as nm
from
from
from
from
from
from
274
sfepy import data_dir
sfepy.base.base import Struct
sfepy.base.ioutils import InDir
sfepy.discrete.fem import extend_cell_data
sfepy.linalg import norm_l2_along_axis
sfepy.homogenization.coefficients import Coefficients
Chapter 5. Examples
SfePy Documentation, Release 2015.1
from band_gaps_conf import BandGapsRigidConf, get_pars, normalize
normalize # Make pyflakes happy...
incwd = InDir(__file__)
dim = 2
if dim == 3:
filename = data_dir + ’/meshes/3d/special/cube_sphere.mesh’
else:
filename = data_dir + ’/meshes/2d/special/circle_in_square.mesh’
output_dir = incwd(’output/band_gaps_rigid’)
# Rigid inclusion diameter.
yr_diameter = 0.125
# aluminium, in 1e+10 Pa
D_m = get_pars(dim, 5.898, 2.681)
density_m = 0.2799 # in 1e4 kg/m3
# epoxy, in 1e+10 Pa
D_c = get_pars(dim, 0.1798, 0.148)
density_c = 0.1142 # in 1e4 kg/m3
# lead, in 1e+10 Pa, does not matter
D_r = get_pars(dim, 4.074, 0.5556)
density_r = 1.1340 # in 1e4 kg/m3
mat_pars = Coefficients(D_m=D_m, density_m=density_m,
D_c=D_c, density_c=density_c,
D_r=D_r, density_r=density_r)
region_selects = Struct(matrix=’cells of group 1’,
inclusion=’cells of group 2’)
corrs_save_names = {’evp’ : ’evp’}
evp_options = {
’eigensolver’ : ’eig.sgscipy’,
’save_eig_vectors’ : (12, 0),
’scale_epsilon’ : 1.0,
’elasticity_contrast’ : 1.0,
}
eigenmomenta_options = {
# eigenmomentum threshold,
’threshold’ : 1e-1,
# eigenmomentum threshold is relative w.r.t. largest one,
’threshold_is_relative’ : True,
}
band_gaps_options = {
’fixed_freq_range’ : (0., 35.), # overrides eig_range!
5.3. Examples
275
SfePy Documentation, Release 2015.1
’freq_eps’ : 1e-12, # frequency
’zezo_eps’ : 1e-12, # zero finding
’freq_step’ : 0.01, # % of freq_range
’log_save_name’ : ’band_gaps.log’,
}
options = {
’post_process_hook’ : ’post_process’,
’plot_transform’ : (’normalize’, (-2, 2)),
’fig_name’ : ’band_gaps’,
’fig_suffix’ : ’.pdf’,
’coefs_filename’ : ’coefs.txt’,
’plot_options’ : {
’show’ : True, # Show figure.
’legend’ : True, # Show legend.
},
}
def select_yr_circ(coors, diameter=None):
r = norm_l2_along_axis(coors)
out = nm.where(r < diameter)[0]
if out.shape[0] <= 3:
raise ValueError(’too few nodes selected! (%d)’ % out.shape[0])
return out
def _select_yr_circ(coors, domain=None, diameter=None):
return select_yr_circ(coors, diameter=yr_diameter)
def post_process(out, problem, mtx_phi):
var = problem.get_variables()[’u’]
for key in out.keys():
ii = int(key[1:])
vec = mtx_phi[:,ii].copy()
var.set_data(vec)
strain = problem.evaluate(’ev_cauchy_strain.i.Y_c(u)’, u=var,
verbose=False, mode=’el_avg’)
strain = extend_cell_data(strain, problem.domain, ’Y_c’)
out[’strain%03d’ % ii] = Struct(name=’output_data’,
mode=’cell’, data=strain,
dofs=None)
return out
conf = BandGapsRigidConf(filename, 1, region_selects, mat_pars, options,
evp_options, eigenmomenta_options, band_gaps_options,
corrs_save_names=corrs_save_names, incwd=incwd,
output_dir=output_dir, select_yr=_select_yr_circ)
define = lambda: conf.conf.to_dict()
276
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.3.10 piezo_elasticity
piezo_elasticity/piezo.py
Description
Piezo-elasticity problem - linear elastic material with piezoelectric effects.
Find 𝑢, 𝜑 such that:
−𝜔 2
∫︁
𝑌
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) −
𝑔𝑘𝑖𝑗 𝑒𝑖𝑗 (𝑣)∇𝑘 𝜑 = 0 ,
𝜌𝑣·𝑢+
𝑌
𝑌2
∫︁
∫︁
𝐾𝑖𝑗 ∇𝑖 𝜓∇𝑗 𝜑 = 0 , ∀𝜓 ,
𝑔𝑘𝑖𝑗 𝑒𝑖𝑗 (𝑢)∇𝑘 𝜓 +
𝑌2
∀𝑣 ,
𝑌
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 .
source code
r"""
Piezo-elasticity problem - linear elastic material with piezoelectric
effects.
Find :math:‘\ul{u}‘, :math:‘\phi‘ such that:
5.3. Examples
277
SfePy Documentation, Release 2015.1
.. math::
- \omega^2 \int_{Y} \rho\ \ul{v} \cdot \ul{u}
+ \int_{Y} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{Y_2} g_{kij}\ e_{ij}(\ul{v}) \nabla_k \phi
= 0
\;, \quad \forall \ul{v} \;,
\int_{Y_2} g_{kij}\ e_{ij}(\ul{u}) \nabla_k \psi
+ \int_{Y} K_{ij} \nabla_i \psi \nabla_j \phi
= 0
\;, \quad \forall \psi \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;.
"""
import os
import numpy as nm
from sfepy import data_dir
from sfepy.discrete.fem import MeshIO
filename_mesh = data_dir + ’/meshes/2d/special/circle_in_square.mesh’
## filename_mesh = data_dir + ’/meshes/2d/special/circle_in_square_small.mesh’
## filename_mesh = data_dir + ’/meshes/3d/special/cube_sphere.mesh’
## filename_mesh = data_dir + ’/meshes/2d/special/cube_cylinder.mesh’
omega = 1
omega_squared = omega**2
conf_dir = os.path.dirname(__file__)
io = MeshIO.any_from_filename(filename_mesh, prefix_dir=conf_dir)
bbox, dim = io.read_bounding_box( ret_dim = True )
geom = {3 : ’3_4’, 2 : ’2_3’}[dim]
x_left, x_right = bbox[:,0]
regions = {
’Y’ : ’all’,
’Y1’ : ’cells of group 1’,
’Y2’ : ’cells of group 2’,
’Y2_Surface’: (’r.Y1 *v r.Y2’, ’facet’),
’Left’ : (’vertices in (x < %f)’ % (x_left + 1e-3), ’facet’),
’Right’ : (’vertices in (x > %f)’ % (x_right - 1e-3), ’facet’),
}
material_2 = {
’name’ : ’inclusion’,
# epoxy
’function’ : ’get_inclusion_pars’,
}
def get_inclusion_pars(ts, coor, mode=None, **kwargs):
278
Chapter 5. Examples
SfePy Documentation, Release 2015.1
"""TODO: implement proper 3D -> 2D transformation of constitutive
matrices."""
if mode == ’qp’:
n_nod, dim = coor.shape
sym = (dim + 1) * dim / 2
dielectric = nm.eye( dim, dtype = nm.float64 )
# !!!
coupling = nm.ones( (dim, sym), dtype = nm.float64 )
#
coupling[0,1] = 0.2
out = {
# Lame coefficients in 1e+10 Pa.
’lam’ : 0.1798,
’mu’ : 0.148,
# dielectric tensor
’dielectric’ : dielectric,
# piezoelectric coupling
’coupling’ : coupling,
’density’ : 0.1142, # in 1e4 kg/m3
}
for key, val in out.iteritems():
out[key] = nm.tile(val, (coor.shape[0], 1, 1))
return out
functions = {
’get_inclusion_pars’ : (get_inclusion_pars,),
}
field_0 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : dim,
’region’ : ’Y’,
’approx_order’ : 1,
}
field_2 = {
’name’ : ’potential’,
’dtype’ : nm.float64,
’shape’ : (1,),
’region’ : ’Y’,
’approx_order’ : 1,
}
variables
’u’ :
’v’ :
’phi’
’psi’
}
= {
(’unknown field’, ’displacement’, 0),
(’test field’, ’displacement’, ’u’),
: (’unknown field’, ’potential’, 1),
: (’test field’, ’potential’, ’phi’),
ebcs = {
’u1’ : (’Left’, {’u.all’ : 0.0}),
’u2’ : (’Right’, {’u.0’ : 0.1}),
’phi’ : (’Y2_Surface’, {’phi.all’ : 0.0}),
}
5.3. Examples
279
SfePy Documentation, Release 2015.1
integral_1 = {
’name’ : ’i’,
’order’ : 2,
}
equations = {
’1’ : """- %f * dw_volume_dot.i.Y( inclusion.density, v, u )
+ dw_lin_elastic_iso.i.Y( inclusion.lam, inclusion.mu, v, u )
- dw_piezo_coupling.i.Y2( inclusion.coupling, v, phi )
= 0""" % omega_squared,
’2’ : """dw_piezo_coupling.i.Y2( inclusion.coupling, u, psi )
+ dw_diffusion.i.Y( inclusion.dielectric, psi, phi )
= 0""",
}
##
# Solvers etc.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
:
’eps_a’
:
’eps_r’
:
’macheps’
:
’lin_red’
:
’ls_red’
:
’ls_red_warp’:
’ls_on’
:
’ls_min’
:
’check’
:
’delta’
:
1,
1e-10,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
0.1,
0.001,
1.1,
1e-5,
0,
1e-6,
}
5.3.11 quantum
quantum/boron.py
Description
missing description!
source code
from sfepy.linalg import norm_l2_along_axis
from quantum_common import common
def fun_v(ts, coor, mode=None, **kwargs):
if not mode == ’qp’: return
out = {}
280
Chapter 5. Examples
SfePy Documentation, Release 2015.1
C = 0.5
r = norm_l2_along_axis(coor, axis=1)
V = - C * 5.0 / r
V.shape = (V.shape[0], 1, 1)
out[’V’] = V
return out
def define(n_eigs=10, tau=-15):
l = common(fun_v, n_eigs=n_eigs, tau=tau)
return l
quantum/hydrogen.py
Description
missing description!
source code
from sfepy.linalg import norm_l2_along_axis
from quantum_common import common
def fun_v(ts, coor, mode=None, **kwargs):
if not mode == ’qp’: return
out = {}
C = 0.5
r = norm_l2_along_axis(coor, axis=1)
V = - C * 1.0 / r
V.shape = (V.shape[0], 1, 1)
out[’V’] = V
return out
def define(n_eigs=5, tau=-1.0):
l = common(fun_v, n_eigs=n_eigs, tau=tau)
return l
quantum/oscillator.py
Description
missing description!
source code
from sfepy.linalg import norm_l2_along_axis
from quantum_common import common
def fun_v(ts, coor, mode=None, **kwargs):
if not mode == ’qp’: return
out = {}
5.3. Examples
281
SfePy Documentation, Release 2015.1
C = 0.5
val = C * norm_l2_along_axis(coor, axis=1, squared=True)
val.shape = (val.shape[0], 1, 1)
out[’V’] = val
return out
def define(n_eigs=20, tau=0.0):
l = common(fun_v, n_eigs=n_eigs, tau=tau)
return l
quantum/quantum_common.py
Description
Common code for basic electronic structure examples.
Notes
The same code should work also with a 3D (box) mesh, but a very fine mesh would be required. Also in the 2D case,
finer mesh and/or higher approximation order means higher accuracy.
Try changing C, F and L parameters in square.geo and regenerate the mesh using gmsh:
$ gmsh -2 -format mesh meshes/quantum/square.geo -o meshes/quantum/square.mesh
$ ./script/convert_mesh.py meshes/quantum/square.mesh meshes/quantum/aux.vtk
$ ./script/convert_mesh.py meshes/quantum/aux.vtk meshes/quantum/square.mesh
The script/convert_mesh.py calls make the mesh 2D, as gmsh does not save planar medit meshes.
Also try changing approximation order (‘approx_order’) of the field below, as well as the integral order (should be two
times the approximation order).
source code
"""
Common code for basic electronic structure examples.
Notes
----The same code should work also with a 3D (box) mesh, but a very fine mesh would
be required. Also in the 2D case, finer mesh and/or higher approximation order
means higher accuracy.
Try changing C, F and L parameters in square.geo and regenerate the mesh using
gmsh::
$ gmsh -2 -format mesh meshes/quantum/square.geo -o meshes/quantum/square.mesh
$ ./script/convert_mesh.py meshes/quantum/square.mesh meshes/quantum/aux.vtk
$ ./script/convert_mesh.py meshes/quantum/aux.vtk meshes/quantum/square.mesh
The ‘‘script/convert_mesh.py‘‘ calls make the mesh 2D, as gmsh does not save
planar medit meshes.
Also try changing approximation order (’approx_order’) of the field below, as
well as the integral order (should be two times the approximation order).
282
Chapter 5. Examples
SfePy Documentation, Release 2015.1
"""
from sfepy import data_dir
def common(fun_v, n_eigs=5, tau=0.0):
filename_mesh = data_dir + ’/meshes/quantum/square.mesh’
options = {
’save_eig_vectors’ : None,
’n_eigs’ : n_eigs,
’eigen_solver’ : ’eigen1’,
}
region_1000 = {
’name’ : ’Omega’,
’select’ : ’all’,
}
region_2 = {
’name’ : ’Surface’,
’select’ : ’vertices of surface’,
’kind’ : ’facet’,
}
functions = {
’fun_v’ : (fun_v,),
}
material_1 = {
’name’ : ’m’,
’values’ : {
’val’ : 0.5,
},
}
material_2 = {
’name’ : ’mat_v’,
’function’ : ’fun_v’,
}
field_0 = {
’name’ : ’field_Psi’,
’dtype’ : ’real’,
’shape’ : ’scalar’,
’region’ : ’Omega’,
’approx_order’ : 2,
}
integral_1 = {
’name’ : ’i’,
’order’ : 4,
}
variable_1 = {
’name’ : ’Psi’,
’kind’ : ’unknown field’,
’field’ : ’field_Psi’,
5.3. Examples
283
SfePy Documentation, Release 2015.1
’order’ : 0,
}
variable_2 = {
’name’ : ’v’,
’kind’ : ’test field’,
’field’ : ’field_Psi’,
’dual’ : ’Psi’,
}
variable_3 = {
’name’ : ’V’,
’kind’ : ’parameter field’,
’field’ : ’field_Psi’,
’like’ : ’Psi’,
}
ebc_1 = {
’name’ : ’ZeroSurface’,
’region’ : ’Surface’,
’dofs’ : {’Psi.0’ : 0.0},
}
equations = {
’lhs’ : """ dw_laplace.i.Omega( m.val, v, Psi )
+ dw_volume_dot.i.Omega( mat_v.V, v, Psi )""",
’rhs’ : """dw_volume_dot.i.Omega( v, Psi )""",
}
solver_2 = {
’name’ : ’eigen1’,
’kind’ : ’eig.pysparse’,
’tau’ : tau,
’eps_a’ : 1e-10,
’i_max’ : 150,
’method’ : ’qmrs’,
’verbosity’ : 0,
’strategy’ : 1,
}
return locals()
quantum/well.py
Description
missing description!
source code
from quantum_common import common
def fun_v(ts, coor, mode=None, **kwargs):
from numpy import zeros_like
if not mode == ’qp’: return
out = {}
val = zeros_like(coor[:,0])
284
Chapter 5. Examples
SfePy Documentation, Release 2015.1
val.shape = (val.shape[0], 1, 1)
out[’V’] = val
return out
def define(n_eigs=10, tau=0.0):
l = common(fun_v, n_eigs=n_eigs, tau=tau)
return l
5.3.12 standalone/elastic_materials
standalone/elastic_materials/compare_elastic_materials.py
Description
Compare various elastic materials w.r.t. uniaxial tension/compression test.
Requires Matplotlib.
source code
"""
Compare various elastic materials w.r.t. uniaxial tension/compression test.
Requires Matplotlib.
"""
from optparse import OptionParser
import sys
sys.path.append( ’.’ )
import numpy as nm
def define():
"""Define the problem to solve."""
filename_mesh = ’el3.mesh’
options = {
’nls’ : ’newton’,
’ls’ : ’ls’,
’ts’ : ’ts’,
’save_steps’ : -1,
}
functions = {
’linear_tension’ : (linear_tension,),
’linear_compression’ : (linear_compression,),
’empty’ : (lambda ts, coor, mode, region, ig: None,),
}
field_1 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : (3,),
’region’ : ’Omega’,
’approx_order’ : 1,
}
5.3. Examples
285
SfePy Documentation, Release 2015.1
# Coefficients are chosen so that the tangent stiffness is the same for all
# material for zero strains.
# Young modulus = 10 kPa, Poisson’s ratio = 0.3
material_1 = {
’name’ : ’solid’,
’values’ : {
’K’ : 8.333, # bulk modulus
’mu_nh’ : 3.846, # shear modulus of neoHookean term
’mu_mr’ : 1.923, # shear modulus of Mooney-Rivlin term
’kappa’ : 1.923, # second modulus of Mooney-Rivlin term
’lam’ : 5.769, # Lame coefficients for LE term
’mu_le’ : 3.846,
}
}
material_2 = {
’name’ : ’load’,
’function’ : ’empty’
}
variables = {
’u’ : (’unknown field’, ’displacement’, 0),
’v’ : (’test field’, ’displacement’, ’u’),
}
regions = {
’Omega’ : ’all’,
’Bottom’ : (’vertices in (z < 0.1)’, ’facet’),
’Top’ : (’vertices in (z > 2.9)’, ’facet’),
}
ebcs = {
’fixb’ : (’Bottom’, {’u.all’ : 0.0}),
’fixt’ : (’Top’, {’u.[0,1]’ : 0.0}),
}
##
# Balance of forces.
integral_1 = {
’name’ : ’i’,
’order’ : 1,
}
integral_3 = {
’name’ : ’isurf’,
’order’ : 2,
}
equations = {
’linear’ : """dw_lin_elastic_iso.i.Omega( solid.lam, solid.mu_le, v, u )
= dw_surface_ltr.isurf.Top( load.val, v )""",
’neoHookean’ : """dw_tl_he_neohook.i.Omega( solid.mu_nh, v, u )
+ dw_tl_bulk_penalty.i.Omega( solid.K, v, u )
= dw_surface_ltr.isurf.Top( load.val, v )""",
’Mooney-Rivlin’ : """dw_tl_he_neohook.i.Omega( solid.mu_mr, v, u )
+ dw_tl_he_mooney_rivlin.i.Omega( solid.kappa, v, u )
+ dw_tl_bulk_penalty.i.Omega( solid.K, v, u )
= dw_surface_ltr.isurf.Top( load.val, v )""",
}
286
Chapter 5. Examples
SfePy Documentation, Release 2015.1
##
# Solvers etc.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’,
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
:
’eps_a’
:
’eps_r’
:
’macheps’
:
’lin_red’
:
’ls_red’
:
’ls_red_warp’:
’ls_on’
:
’ls_min’
:
’check’
:
’delta’
:
’problem’
:
5,
1e-10,
1.0,
1e-16,
1e-2, # Linear system error < (eps_a * lin_red).
0.1,
0.001,
1.1,
1e-5,
0,
1e-6,
’nonlinear’, # ’nonlinear’ or ’linear’ (ignore i_max)
}
solver_2 = {
’name’ : ’ts’,
’kind’ : ’ts.simple’,
’t0’
: 0,
’t1’
: 1,
’dt’
: None,
’n_step’ : 101, # has precedence over dt!
}
return locals()
##
# Pressure tractions.
def linear_tension(ts, coor, mode=None, **kwargs):
if mode == ’qp’:
val = nm.tile(0.1 * ts.step, (coor.shape[0], 1, 1))
return {’val’ : val}
def linear_compression(ts, coor, mode=None, **kwargs):
if mode == ’qp’:
val = nm.tile(-0.1 * ts.step, (coor.shape[0], 1, 1))
return {’val’ : val}
def store_top_u( displacements ):
"""Function _store() will be called at the end of each loading step. Top
displacements will be stored into ‘displacements‘."""
def _store( problem, ts, state ):
top = problem.domain.regions[’Top’]
top_u = problem.get_variables()[’u’].get_state_in_region( top )
displacements.append( nm.mean( top_u[:,-1] ) )
5.3. Examples
287
SfePy Documentation, Release 2015.1
return _store
def solve_branch(problem, branch_function):
displacements = {}
for key, eq in problem.conf.equations.iteritems():
problem.set_equations( {key : eq} )
load = problem.get_materials()[’load’]
load.set_function(branch_function)
time_solver = problem.get_time_solver()
out = []
time_solver(save_results=False, step_hook=store_top_u(out))
displacements[key] = nm.array(out, dtype=nm.float64)
return displacements
usage = """%prog [options]"""
helps = {
’no_plot’ : ’do not show plot window’,
}
def main():
from sfepy.base.conf import ProblemConf, get_standard_keywords
from sfepy.discrete import Problem
from sfepy.base.plotutils import plt
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-n’, ’--no-plot’,
action="store_true", dest=’no_plot’,
default=False, help=helps[’no_plot’])
options, args = parser.parse_args()
required, other = get_standard_keywords()
# Use this file as the input file.
conf = ProblemConf.from_file( __file__, required, other )
# Create problem instance, but do not set equations.
problem = Problem.from_conf(conf, init_equations=False)
# Solve the problem. Output is ignored, results stored by using the
# step_hook.
u_t = solve_branch(problem, linear_tension)
u_c = solve_branch(problem, linear_compression)
# Get pressure load by calling linear_*() for each time step.
ts = problem.get_timestepper()
load_t = nm.array([linear_tension(ts, nm.array([[0.0]]), ’qp’)[’val’]
for aux in ts.iter_from( 0 )],
dtype=nm.float64).squeeze()
load_c = nm.array([linear_compression(ts, nm.array([[0.0]]), ’qp’)[’val’]
for aux in ts.iter_from( 0 )],
dtype=nm.float64).squeeze()
# Join the branches.
displacements = {}
for key in u_t.keys():
288
Chapter 5. Examples
SfePy Documentation, Release 2015.1
displacements[key] = nm.r_[u_c[key][::-1], u_t[key]]
load = nm.r_[load_c[::-1], load_t]
if plt is None:
print ’matplotlib cannot be imported, printing raw data!’
print displacements
print load
else:
legend = []
for key, val in displacements.iteritems():
plt.plot( load, val )
legend.append( key )
plt.legend( legend, loc = 2 )
plt.xlabel( ’tension [kPa]’ )
plt.ylabel( ’displacement [mm]’ )
plt.grid( True )
plt.gcf().savefig( ’pressure_displacement.png’ )
if not options.no_plot:
plt.show()
if __name__ == ’__main__’:
main()
5.3.13 standalone/homogenized_elasticity
standalone/homogenized_elasticity/rs_correctors.py
Description
missing description!
source code
# c: 05.05.2008, r: 05.05.2008
from optparse import OptionParser
import sys
sys.path.append( ’.’ )
import numpy as nm
import sfepy.discrete.fem.periodic as per
from sfepy.homogenization.utils import define_box_regions
# c: 05.05.2008, r: 05.05.2008
def define_regions( filename ):
"""Define various subdomain for a given mesh file. This function is called
below."""
regions = {}
dim = 2
regions[’Y’] = ’all’
eog = ’cells of group %d’
5.3. Examples
289
SfePy Documentation, Release 2015.1
if filename.find( ’osteonT1’ ) >= 0:
mat_ids = [11, 39, 6, 8, 27, 28, 9, 2, 4, 14, 12, 17, 45, 28, 15]
regions[’Ym’] = ’ +c ’.join( (eog % im) for im in mat_ids )
wx = 0.865
wy = 0.499
regions[’Yc’] = ’r.Y -c r.Ym’
# Sides and corners.
regions.update( define_box_regions( 2, (wx, wy) ) )
return dim, regions, mat_ids
def get_pars(ts, coor, mode=None, term=None, group_indx=None,
mat_ids = [], **kwargs):
"""Define material parameters:
$D_ijkl$ (elasticity),
in a given region."""
if mode == ’qp’:
dim = coor.shape[1]
sym = (dim + 1) * dim / 2
m2i = term.region.domain.mat_ids_to_i_gs
matrix_igs = [m2i[im] for im in mat_ids]
out = {}
# in 1e+10 [Pa]
lam = 1.7
mu = 0.3
o = nm.array( [1.] * dim + [0.] * (sym - dim), dtype = nm.float64 )
oot = nm.outer( o, o )
out[’D’] = lam * oot + mu * nm.diag( o + 1.0 )
for key, val in out.iteritems():
out[key] = nm.tile(val, (coor.shape[0], 1, 1))
for ig, indx in group_indx.iteritems():
if ig not in matrix_igs: # channels
out[’D’][indx] *= 1e-1
return out
##
# Mesh file.
filename_mesh = ’meshes/osteonT1_11.mesh’
##
# Define regions (subdomains, boundaries) - $Y$, $Y_i$, ...
# depending on a mesh used.
dim, regions, mat_ids = define_regions( filename_mesh )
functions = {
’get_pars’ : (lambda ts, coors, **kwargs:
get_pars(ts, coors, mat_ids=mat_ids, **kwargs),),
’match_x_plane’ : (per.match_x_plane,),
’match_y_plane’ : (per.match_y_plane,),
’match_z_plane’ : (per.match_z_plane,),
290
Chapter 5. Examples
SfePy Documentation, Release 2015.1
’match_x_line’ : (per.match_x_line,),
’match_y_line’ : (per.match_y_line,),
}
##
# Define fields: ’displacement’ in $Y$,
# ’pressure_m’ in $Y_m$.
field_1 = {
’name’ : ’displacement’,
’dtype’ : nm.float64,
’shape’ : dim,
’region’ : ’Y’,
’approx_order’ : 1,
}
##
# Define corrector variables: unknown displaements: uc, test: vc
# displacement-like variables: Pi, Pi1, Pi2
variables = {
’uc’
: (’unknown field’,
’displacement’, 0),
’vc’
: (’test field’,
’displacement’, ’uc’),
’Pi’
: (’parameter field’, ’displacement’, ’uc’),
’Pi1’
: (’parameter field’, ’displacement’, None),
’Pi2’
: (’parameter field’, ’displacement’, None),
}
##
# Periodic boundary conditions.
if dim == 3:
epbc_10 = {
’name’ : ’periodic_x’,
’region’ : [’Left’, ’Right’],
’dofs’ : {’uc.all’ : ’uc.all’},
’match’ : ’match_x_plane’,
}
epbc_11 = {
’name’ : ’periodic_y’,
’region’ : [’Near’, ’Far’],
’dofs’ : {’uc.all’ : ’uc.all’},
’match’ : ’match_y_plane’,
}
epbc_12 = {
’name’ : ’periodic_z’,
’region’ : [’Top’, ’Bottom’],
’dofs’ : {’uc.all’ : ’uc.all’},
’match’ : ’match_z_plane’,
}
else:
epbc_10 = {
’name’ : ’periodic_x’,
’region’ : [’Left’, ’Right’],
’dofs’ : {’uc.all’ : ’uc.all’},
’match’ : ’match_y_line’,
}
epbc_11 = {
’name’ : ’periodic_y’,
’region’ : [’Top’, ’Bottom’],
’dofs’ : {’uc.all’ : ’uc.all’},
5.3. Examples
291
SfePy Documentation, Release 2015.1
’match’ : ’match_x_line’,
}
##
# Dirichlet boundary conditions.
ebcs = {
’fixed_u’ : (’Corners’, {’uc.all’ : 0.0}),
}
##
# Material defining constitutive parameters of the microproblem.
material_1 = {
’name’ : ’m’,
’function’ : ’get_pars’,
}
##
# Numerical quadratures for volume (i3 - order 3) integral terms.
integral_1 = {
’name’ : ’i3’,
’order’ : 3,
}
##
# Homogenized coefficients to compute.
def set_elastic(variables, ir, ic, mode, pis, corrs_rs):
mode2var = {’row’ : ’Pi1’, ’col’ : ’Pi2’}
val = pis.states[ir, ic][’uc’] + corrs_rs.states[ir, ic][’uc’]
variables[mode2var[mode]].set_data(val)
coefs = {
’E’ : {
’requires’ : [’pis’, ’corrs_rs’],
’expression’ : ’dw_lin_elastic.i3.Y( m.D, Pi1, Pi2 )’,
’set_variables’ : set_elastic,
},
}
all_periodic = [’periodic_%s’ % ii for ii in [’x’, ’y’, ’z’][:dim] ]
requirements = {
’pis’ : {
’variables’ : [’uc’],
},
##
# Steady state correctors $\bar{\omega}^{rs}$.
’corrs_rs’ : {
’requires’ : [’pis’],
’save_variables’ : [’uc’],
’ebcs’ : [’fixed_u’],
’epbcs’ : all_periodic,
’equations’ : {’eq’ : """dw_lin_elastic.i3.Y( m.D, vc, uc )
= - dw_lin_elastic.i3.Y( m.D, vc, Pi )"""},
’set_variables’ : [(’Pi’, ’pis’, ’uc’)],
’save_name’ : ’corrs_elastic’,
’is_linear’ : True,
},
292
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}
##
# Solvers.
solver_0 = {
’name’ : ’ls’,
’kind’ : ’ls.scipy_direct’, # Direct solver.
}
solver_1 = {
’name’ : ’newton’,
’kind’ : ’nls.newton’,
’i_max’
: 2,
’eps_a’
: 1e-8,
’eps_r’
: 1e-2,
’macheps’
: 1e-16,
’lin_red’
: 1e-2, # Linear system error < (eps_a * lin_red).
’ls_red’
: 0.1,
’ls_red_warp’ : 0.001,
’ls_on’
: 0.99999,
’ls_min’
: 1e-5,
’check’
: 0,
’delta’
: 1e-6,
’problem’
: ’nonlinear’, # ’nonlinear’ or ’linear’ (ignore i_max)
}
############################################
# Mini-application below, computing the homogenized elastic coefficients.
usage = """%prog [options]"""
help = {
’no_pauses’ : ’do not make pauses’,
}
##
# c: 05.05.2008, r: 28.11.2008
def main():
import os
from sfepy.base.base import spause, output
from sfepy.base.conf import ProblemConf, get_standard_keywords
from sfepy.discrete import Problem
import sfepy.homogenization.coefs_base as cb
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-n’, ’--no-pauses’,
action="store_true", dest=’no_pauses’,
default=False, help=help[’no_pauses’])
options, args = parser.parse_args()
if options.no_pauses:
def spause(*args):
output(*args)
nm.set_printoptions( precision = 3 )
spause( r""">>>
First, this file will be read in place of an input
(problem description) file.
5.3. Examples
293
SfePy Documentation, Release 2015.1
Press ’q’ to quit the example, press any other key to continue...""" )
required, other = get_standard_keywords()
required.remove( ’equations’ )
# Use this file as the input file.
conf = ProblemConf.from_file( __file__, required, other )
print conf.to_dict().keys()
spause( r""">>>
...the read input as a dict (keys only for brevity).
[’q’/other key to quit/continue...]""" )
spause( r""">>>
Now the input will be used to create a Problem instance.
[’q’/other key to quit/continue...]""" )
problem = Problem.from_conf(conf, init_equations=False)
# The homogenization mini-apps need the output_dir.
output_dir = os.path.join(os.path.split(__file__)[0], ’output’)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
problem.output_dir = output_dir
print problem
spause( r""">>>
...the Problem instance.
[’q’/other key to quit/continue...]""" )
spause( r""">>>
The homogenized elastic coefficient $E_{ijkl}$ is expressed
using $\Pi$ operators, computed now. In fact, those operators are permuted
coordinates of the mesh nodes.
[’q’/other key to quit/continue...]""" )
req = conf.requirements[’pis’]
mini_app = cb.ShapeDimDim( ’pis’, problem, req )
pis = mini_app()
print pis
spause( r""">>>
...the $\Pi$ operators.
[’q’/other key to quit/continue...]""" )
spause( r""">>>
Next, $E_{ijkl}$ needs so called steady state correctors $\bar{\omega}^{rs}$,
computed now.
[’q’/other key to quit/continue...]""" )
req = conf.requirements[’corrs_rs’]
save_name = req.get( ’save_name’, ’’ )
name = os.path.join( output_dir, save_name )
mini_app = cb.CorrDimDim(’steady rs correctors’, problem, req)
mini_app.setup_output(save_format=’vtk’,
file_per_var=False)
corrs_rs = mini_app( data = {’pis’: pis} )
print corrs_rs
spause( r""">>>
...the $\bar{\omega}^{rs}$ correctors.
The results are saved in: %s.%s
Try to display them with:
294
Chapter 5. Examples
SfePy Documentation, Release 2015.1
python postproc.py %s.%s
[’q’/other key to quit/continue...]""" % (2 * (name, problem.output_format)) )
spause( r""">>>
Then the volume of the domain is needed.
[’q’/other key to quit/continue...]""" )
volume = problem.evaluate(’d_volume.i3.Y( uc )’)
print volume
spause( r""">>>
...the volume.
[’q’/other key to quit/continue...]""" )
spause( r""">>>
Finally, $E_{ijkl}$ can be computed.
[’q’/other key to quit/continue...]""" )
mini_app = cb.CoefSymSym(’homogenized elastic tensor’,
problem, conf.coefs[’E’])
c_e = mini_app(volume, data={’pis’: pis, ’corrs_rs’ : corrs_rs})
print r""">>>
The homogenized elastic coefficient $E_{ijkl}$, symmetric storage
with rows, columns in 11, 22, 12 ordering:"""
print c_e
if __name__ == ’__main__’:
main()
5.3.14 standalone/interactive
standalone/interactive/laplace_shifted_periodic.py
Description
Laplace equation with shifted periodic BCs.
Display using:
./postproc.py laplace_shifted_periodic.vtk --wireframe -b -d’u,plot_warp_scalar,rel_scaling=1’
or use the –show option.
source code
#!/usr/bin/env python
"""
Laplace equation with shifted periodic BCs.
Display using::
./postproc.py laplace_shifted_periodic.vtk --wireframe -b -d’u,plot_warp_scalar,rel_scaling=1’
or use the --show option.
"""
import sys
sys.path.append(’.’)
from optparse import OptionParser
import numpy as nm
5.3. Examples
295
SfePy Documentation, Release 2015.1
from sfepy.base.base import output
from sfepy.discrete import (FieldVariable, Integral, Equation, Equations,
Function, Problem)
from sfepy.discrete.fem import FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import (Conditions, EssentialBC,
LinearCombinationBC)
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.mesh.mesh_generators import gen_block_mesh
import sfepy.discrete.fem.periodic as per
def run(domain, order):
omega = domain.create_region(’Omega’, ’all’)
bbox = domain.get_mesh_bounding_box()
min_x, max_x = bbox[:, 0]
min_y, max_y = bbox[:, 1]
eps = 1e-8 * (max_x - min_x)
gamma1 = domain.create_region(’Gamma1’,
’vertices in (x < %.10f)’
’facet’)
gamma2 = domain.create_region(’Gamma2’,
’vertices in (x > %.10f)’
’facet’)
gamma3 = domain.create_region(’Gamma3’,
’vertices in y < %.10f’ %
’facet’)
gamma4 = domain.create_region(’Gamma4’,
’vertices in y > %.10f’ %
’facet’)
% (min_x + eps),
% (max_x - eps),
(min_y + eps),
(max_y - eps),
field = Field.from_args(’fu’, nm.float64, 1, omega, approx_order=order)
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
integral = Integral(’i’, order=2*order)
t1 = Term.new(’dw_laplace(v, u)’,
integral, omega, v=v, u=u)
eq = Equation(’eq’, t1)
eqs = Equations([eq])
fix1 = EssentialBC(’fix1’, gamma1, {’u.0’ : 0.4})
fix2 = EssentialBC(’fix2’, gamma2, {’u.0’ : 0.0})
def get_shift(ts, coors, region):
return nm.ones_like(coors[:, 0])
dof_map_fun = Function(’dof_map_fun’, per.match_x_line)
shift_fun = Function(’shift_fun’, get_shift)
sper = LinearCombinationBC(’sper’, [gamma3, gamma4], {’u.0’ : ’u.0’},
dof_map_fun, ’shifted_periodic’,
arguments=(shift_fun,))
ls = ScipyDirect({})
296
Chapter 5. Examples
SfePy Documentation, Release 2015.1
pb = Problem(’laplace’, equations=eqs, auto_solvers=None)
pb.time_update(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper]))
ev = pb.get_evaluator()
nls = Newton({}, lin_solver=ls,
fun=ev.eval_residual, fun_grad=ev.eval_tangent_matrix)
pb.set_solvers_instances(ls, nls)
state = pb.solve()
return pb, state
usage = ’%prog [options]\n’ + __doc__.rstrip()
helps = {
’dims’ :
’dimensions of the block [default: %default]’,
’centre’ :
’centre of the block [default: %default]’,
’shape’ :
’numbers of vertices along each axis [default: %default]’,
’show’ : ’show the results figure’,
}
def main():
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-d’, ’--dims’, metavar=’dims’,
action=’store’, dest=’dims’,
default=’[1.0, 1.0]’, help=helps[’dims’])
parser.add_option(’-c’, ’--centre’, metavar=’centre’,
action=’store’, dest=’centre’,
default=’[0.0, 0.0]’, help=helps[’centre’])
parser.add_option(’-s’, ’--shape’, metavar=’shape’,
action=’store’, dest=’shape’,
default=’[11, 11]’, help=helps[’shape’])
parser.add_option(’’, ’--show’,
action="store_true", dest=’show’,
default=False, help=helps[’show’])
(options, args) = parser.parse_args()
dims = nm.array(eval(options.dims), dtype=nm.float64)
centre = nm.array(eval(options.centre), dtype=nm.float64)
shape = nm.array(eval(options.shape), dtype=nm.int32)
output(’dimensions:’, dims)
output(’centre:
’, centre)
output(’shape:
’, shape)
mesh = gen_block_mesh(dims, shape, centre, name=’block-fem’)
fe_domain = FEDomain(’domain’, mesh)
pb, state = run(fe_domain, 1)
pb.save_state(’laplace_shifted_periodic.vtk’, state)
if options.show:
from sfepy.postprocess.viewer import Viewer
5.3. Examples
297
SfePy Documentation, Release 2015.1
from sfepy.postprocess.domain_specific import DomainSpecificPlot
view = Viewer(’laplace_shifted_periodic.vtk’)
view(rel_scaling=1,
domain_specific={’u’ : DomainSpecificPlot(’plot_warp_scalar’,
[’rel_scaling=1’])},
is_scalar_bar=True, is_wireframe=True,
opacity=0.3)
if __name__ == ’__main__’:
main()
standalone/interactive/linear_elasticity.py
Description
missing description!
source code
#!/usr/bin/env python
from optparse import OptionParser
import numpy as nm
import sys
sys.path.append(’.’)
from sfepy.base.base import IndexedStruct
from sfepy.discrete import (FieldVariable, Material, Integral, Function,
Equation, Equations, Problem)
from sfepy.discrete.fem import Mesh, FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import Conditions, EssentialBC
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.postprocess.viewer import Viewer
def shift_u_fun(ts, coors, bc=None, problem=None, shift=0.0):
"""
Define a displacement depending on the y coordinate.
"""
val = shift * coors[:,1]**2
return val
usage = """%prog [options]"""
help = {
’show’ : ’show the results figure’,
}
def main():
from sfepy import data_dir
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-s’, ’--show’,
action="store_true", dest=’show’,
default=False, help=help[’show’])
options, args = parser.parse_args()
298
Chapter 5. Examples
SfePy Documentation, Release 2015.1
mesh = Mesh.from_file(data_dir + ’/meshes/2d/rectangle_tri.mesh’)
domain = FEDomain(’domain’, mesh)
min_x, max_x = domain.get_mesh_bounding_box()[:,0]
eps = 1e-8 * (max_x - min_x)
omega = domain.create_region(’Omega’, ’all’)
gamma1 = domain.create_region(’Gamma1’,
’vertices in x < %.10f’ % (min_x + eps),
’facet’)
gamma2 = domain.create_region(’Gamma2’,
’vertices in x > %.10f’ % (max_x - eps),
’facet’)
field = Field.from_args(’fu’, nm.float64, ’vector’, omega, approx_order=2)
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
m = Material(’m’, lam=1.0, mu=1.0)
f = Material(’f’, val=[[0.02], [0.01]])
integral = Integral(’i’, order=3)
t1 = Term.new(’dw_lin_elastic_iso(m.lam, m.mu, v, u)’,
integral, omega, m=m, v=v, u=u)
t2 = Term.new(’dw_volume_lvf(f.val, v)’, integral, omega, f=f, v=v)
eq = Equation(’balance’, t1 + t2)
eqs = Equations([eq])
fix_u = EssentialBC(’fix_u’, gamma1, {’u.all’ : 0.0})
bc_fun = Function(’shift_u_fun’, shift_u_fun, extra_args={’shift’ : 0.01})
shift_u = EssentialBC(’shift_u’, gamma2, {’u.0’ : bc_fun})
ls = ScipyDirect({})
nls_status = IndexedStruct()
nls = Newton({}, lin_solver=ls, status=nls_status)
pb = Problem(’elasticity’, equations=eqs, nls=nls, ls=ls)
pb.save_regions_as_groups(’regions’)
pb.time_update(ebcs=Conditions([fix_u, shift_u]))
vec = pb.solve()
print nls_status
pb.save_state(’linear_elasticity.vtk’, vec)
if options.show:
view = Viewer(’linear_elasticity.vtk’)
view(vector_mode=’warp_norm’, rel_scaling=2,
is_scalar_bar=True, is_wireframe=True)
if __name__ == ’__main__’:
main()
5.3. Examples
299
SfePy Documentation, Release 2015.1
standalone/interactive/modal_analysis.py
Description
Modal analysis of a linear elastic block in 2D or 3D.
The dimension of the problem is determined by the length of the vector in --dims option.
The default material properties correspond to aluminium in the following units:
• length: m
• mass: kg
• stiffness / stress: Pa
• density: kg / m^3
Examples
• Run with the default arguments, show results (color = strain):
python examples/standalone/interactive/modal_analysis.py --show
• Clamp bottom surface of the domain, show 9 eigen-shapes:
python examples/standalone/interactive/modal_analysis.py -b clamped -n 9 --show
• Increase mesh resolution:
python examples/standalone/interactive/modal_analysis.py -s 31,31 -n 9 --show
• Use 3D domain:
python examples/standalone/interactive/modal_analysis.py -d 1,1,1 -c 0,0,0 -s 8,8,8 --show
• Change the eigenvalue problem solver to LOBPCG:
python examples/standalone/interactive/modal_analysis.py --solver="eig.scipy_lobpcg,i_max:100,la
See sfepy.solvers.eigen for available solvers.
source code
#!/usr/bin/env python
"""
Modal analysis of a linear elastic block in 2D or 3D.
The dimension of the problem is determined by the length of the vector
in ‘‘--dims‘‘ option.
The default material properties correspond to aluminium in the following units:
-
length: m
mass: kg
stiffness / stress: Pa
density: kg / m^3
Examples
-------- Run with the default arguments, show results (color = strain)::
300
Chapter 5. Examples
SfePy Documentation, Release 2015.1
python examples/standalone/interactive/modal_analysis.py --show
- Clamp bottom surface of the domain, show 9 eigen-shapes::
python examples/standalone/interactive/modal_analysis.py -b clamped -n 9 --show
- Increase mesh resolution::
python examples/standalone/interactive/modal_analysis.py -s 31,31 -n 9 --show
- Use 3D domain::
python examples/standalone/interactive/modal_analysis.py -d 1,1,1 -c 0,0,0 -s 8,8,8 --show
- Change the eigenvalue problem solver to LOBPCG::
python examples/standalone/interactive/modal_analysis.py --solver="eig.scipy_lobpcg,i_max:100,lar
See :mod:‘sfepy.solvers.eigen‘ for available solvers.
"""
import sys
sys.path.append(’.’)
from optparse import OptionParser
import numpy as nm
import scipy.sparse.linalg as sla
from sfepy.base.base import assert_, output, Struct
from sfepy.discrete import (FieldVariable, Material, Integral, Integrals,
Equation, Equations, Problem)
from sfepy.discrete.fem import FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import Conditions, EssentialBC
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.mesh.mesh_generators import gen_block_mesh
from sfepy.solvers import Solver
usage = ’%prog [options]\n’ + __doc__.rstrip()
helps = {
’dims’ :
’dimensions of the block [default: %default]’,
’centre’ :
’centre of the block [default: %default]’,
’shape’ :
’numbers of vertices along each axis [default: %default]’,
’bc_kind’ :
’kind of Dirichlet boundary conditions on the bottom surface, one of:’
’ free, clamped [default: %default]’,
’young’ : "the Young’s modulus [default: %default]",
’poisson’ : "the Poisson’s ratio [default: %default]",
’density’ : "the material density [default: %default]",
’order’ : ’displacement field approximation order [default: %default]’,
’n_eigs’ : ’the number of eigenvalues to compute [default: %default]’,
’solver’ : ’the eigenvalue problem solver to use. It should be given’
’ as a comma-separated list: solver_kind,option0:value0,option1:value1,...’
’ [default: %default]’,
’show’ : ’show the results figure’,
5.3. Examples
301
SfePy Documentation, Release 2015.1
}
def main():
parser = OptionParser(usage=usage, version=’%prog’)
parser.add_option(’-d’, ’--dims’, metavar=’dims’,
action=’store’, dest=’dims’,
default=’[1.0, 1.0]’, help=helps[’dims’])
parser.add_option(’-c’, ’--centre’, metavar=’centre’,
action=’store’, dest=’centre’,
default=’[0.0, 0.0]’, help=helps[’centre’])
parser.add_option(’-s’, ’--shape’, metavar=’shape’,
action=’store’, dest=’shape’,
default=’[11, 11]’, help=helps[’shape’])
parser.add_option(’-b’, ’--bc-kind’, metavar=’kind’,
action=’store’, dest=’bc_kind’,
choices=[’free’, ’clamped’],
default=’free’, help=helps[’bc_kind’])
parser.add_option(’--young’, metavar=’float’, type=float,
action=’store’, dest=’young’,
default=6.80e+10, help=helps[’young’])
parser.add_option(’--poisson’, metavar=’float’, type=float,
action=’store’, dest=’poisson’,
default=0.36, help=helps[’poisson’])
parser.add_option(’--density’, metavar=’float’, type=float,
action=’store’, dest=’density’,
default=2700.0, help=helps[’density’])
parser.add_option(’--order’, metavar=’int’, type=int,
action=’store’, dest=’order’,
default=1, help=helps[’order’])
parser.add_option(’-n’, ’--n-eigs’, metavar=’int’, type=int,
action=’store’, dest=’n_eigs’,
default=6, help=helps[’order’])
parser.add_option(’’, ’--solver’, metavar=’solver’,
action=’store’, dest=’solver’,
default="eig.scipy,method:’eigh’,tol:1e-5,maxiter:1000",
help=helps[’solver’])
parser.add_option(’’, ’--show’,
action="store_true", dest=’show’,
default=False, help=helps[’show’])
options, args = parser.parse_args()
assert_((0.0 < options.poisson < 0.5),
"Poisson’s ratio must be in ]0, 0.5[!")
assert_((0 < options.order),
’displacement approximation order must be at least 1!’)
dims = nm.array(eval(options.dims), dtype=nm.float64)
dim = len(dims)
centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]
aux = options.solver.split(’,’)
kwargs = {}
for option in aux[1:]:
key, val = option.split(’:’)
kwargs[key.strip()] = eval(val)
eig_conf = Struct(name=’evp’, kind=aux[0], **kwargs)
302
Chapter 5. Examples
SfePy Documentation, Release 2015.1
output(’dimensions:’, dims)
output(’centre:
’, centre)
output(’shape:
’, shape)
output(’using values:’)
output(" Young’s modulus:", options.young)
output(" Poisson’s ratio:", options.poisson)
output(’ density:’, options.density)
output(’requested %d eigenvalues’ % options.n_eigs)
output(’using eigenvalue problem solver:’, eig_conf.kind)
output.level += 1
for key, val in kwargs.iteritems():
output(’%s: %r’ % (key, val))
output.level -= 1
eig_solver = Solver.any_from_conf(eig_conf)
# Build the problem definition.
mesh = gen_block_mesh(dims, shape, centre, name=’mesh’)
domain = FEDomain(’domain’, mesh)
bbox = domain.get_mesh_bounding_box()
min_y, max_y = bbox[:, 1]
eps = 1e-8 * (max_y - min_y)
omega = domain.create_region(’Omega’, ’all’)
bottom = domain.create_region(’Bottom’,
’vertices in (y < %.10f)’ % (min_y + eps),
’facet’)
field = Field.from_args(’fu’, nm.float64, ’vector’, omega,
approx_order=options.order)
u = FieldVariable(’u’, ’unknown’, field)
v = FieldVariable(’v’, ’test’, field, primary_var_name=’u’)
mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)
m = Material(’m’, D=mtx_d, rho=options.density)
integral = Integral(’i’, order=2*options.order)
t1 = Term.new(’dw_lin_elastic(m.D, v, u)’, integral, omega, m=m, v=v, u=u)
t2 = Term.new(’dw_volume_dot(m.rho, v, u)’, integral, omega, m=m, v=v, u=u)
eq1 = Equation(’stiffness’, t1)
eq2 = Equation(’mass’, t2)
lhs_eqs = Equations([eq1, eq2])
pb = Problem(’modal’, equations=lhs_eqs)
if options.bc_kind == ’free’:
pb.time_update()
n_rbm = dim * (dim + 1) / 2
else:
fixed_b = EssentialBC(’FixedB’, bottom, {’u.all’ : 0.0})
pb.time_update(ebcs=Conditions([fixed_b]))
n_rbm = 0
pb.update_materials()
5.3. Examples
303
SfePy Documentation, Release 2015.1
# Assemble stiffness and mass matrices.
mtx_k = eq1.evaluate(mode=’weak’, dw_mode=’matrix’, asm_obj=pb.mtx_a)
mtx_m = mtx_k.copy()
mtx_m.data[:] = 0.0
mtx_m = eq2.evaluate(mode=’weak’, dw_mode=’matrix’, asm_obj=mtx_m)
try:
eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm,
eigenvectors=True)
except sla.ArpackNoConvergence as ee:
eigs = ee.eigenvalues
svecs = ee.eigenvectors
output(’only %d eigenvalues converged!’ % len(eigs))
output(’%d eigenvalues converged (%d ignored as rigid body modes)’ %
(len(eigs), n_rbm))
eigs = eigs[n_rbm:]
svecs = svecs[:, n_rbm:]
output(’eigenvalues:’, eigs)
output(’eigen-frequencies:’, nm.sqrt(eigs))
# Make full eigenvectors (add DOFs fixed by boundary conditions).
variables = pb.get_variables()
vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]),
dtype=nm.float64)
for ii in xrange(svecs.shape[1]):
vecs[:, ii] = variables.make_full_vec(svecs[:, ii])
# Save the eigenvectors.
out = {}
state = pb.create_state()
for ii in xrange(eigs.shape[0]):
state.set_full(vecs[:, ii])
aux = state.create_output_dict()
strain = pb.evaluate(’ev_cauchy_strain.i.Omega(u)’,
integrals=Integrals([integral]),
mode=’el_avg’, verbose=False)
out[’u%03d’ % ii] = aux.popitem()[1]
out[’strain%03d’ % ii] = Struct(mode=’cell’, data=strain)
pb.save_state(’eigenshapes.vtk’, out=out)
pb.save_regions_as_groups(’regions’)
if len(eigs) and options.show:
# Show the solution. If the approximation order is greater than 1, the
# extra DOFs are simply thrown away.
from sfepy.postprocess.viewer import Viewer
from sfepy.postprocess.domain_specific import DomainSpecificPlot
scaling = 0.05 * dims.max() / nm.abs(vecs).max()
ds = {}
for ii in xrange(eigs.shape[0]):
pd = DomainSpecificPlot(’plot_displacements’,
304
Chapter 5. Examples
SfePy Documentation, Release 2015.1
[’rel_scaling=%s’ % scaling,
’color_kind="tensors"’,
’color_name="strain%03d"’ % ii])
ds[’u%03d’ % ii] = pd
view = Viewer(’eigenshapes.vtk’)
view(domain_specific=ds, only_names=sorted(ds.keys()),
is_scalar_bar=False, is_wireframe=True)
if __name__ == ’__main__’:
main()
5.3.15 standalone/live_plot
standalone/live_plot/live_plot.py
Description
missing description!
source code
import os
import sys
sys.path.append( ’.’ )
import numpy as nm
from sfepy.base.base import output, pause
from sfepy.base.log import Log
def main():
cwd = os.path.split(os.path.join(os.getcwd(), __file__))[0]
log = Log(([’sin(x)’, ’cos(x)’], [’exp(x)’]),
yscales=[’linear’, ’log’],
xlabels=[’angle’, None], ylabels=[None, ’a function’],
log_filename=os.path.join(cwd, ’live_plot.log’))
log2 = Log([[’x^3’]],
yscales=[’linear’],
xlabels=[’x’], ylabels=[’a cubic function’],
log_filename=os.path.join(cwd, ’live_plot2.log’))
added = 0
for x in nm.linspace(0, 4.0 * nm.pi, 200):
output(’x: ’, x)
if x < (2.0 * nm.pi):
log(nm.sin(x), nm.cos(x), nm.exp(x), x = [x, None])
else:
if added:
log(nm.sin(x), nm.cos(x), nm.exp(x), x**2,
x=[x, None, x])
else:
log.plot_vlines(color=’r’, linewidth=2)
log.add_group([’x^2’], ’linear’, ’new x’, ’square’,
5.3. Examples
305
SfePy Documentation, Release 2015.1
formats=[’%+g’])
added += 1
if (added == 20) or (added == 50):
log.plot_vlines([2], color=’g’, linewidth=2)
log2(x*x*x, x=[x])
print log
print log2
pause()
log(finished=True)
log2(finished=True)
if __name__ == ’__main__’:
main()
5.3.16 standalone/thermal_electric
standalone/thermal_electric/thermal_electric.py
Description
First solve the stationary electric conduction problem. Then use its results to solve the evolutionary heat conduction
problem.
Run this example as on a command line:
$ python <path_to_this_file>/thermal_electric.py
source code
#!/usr/bin/env python
"""
First solve the stationary electric conduction problem. Then use its
results to solve the evolutionary heat conduction problem.
Run this example as on a command line::
$ python <path_to_this_file>/thermal_electric.py
"""
import sys
sys.path.append( ’.’ )
import os
from sfepy import data_dir
filename_mesh = data_dir + ’/meshes/2d/special/circle_in_square.mesh’
# Time stepping for the heat conduction problem.
t0 = 0.0
t1 = 0.5
n_step = 11
# Material parameters.
specific_heat = 1.2
306
Chapter 5. Examples
SfePy Documentation, Release 2015.1
##########
cwd = os.path.split(os.path.join(os.getcwd(), __file__))[0]
options = {
’absolute_mesh_path’ : True,
’output_dir’ : os.path.join(cwd, ’output’)
}
regions = {
’Omega’ : ’all’,
’Omega1’ : ’cells of group 1’,
’Omega2’ : ’cells of group 2’,
’Omega2_Surface’: (’r.Omega1 *v r.Omega2’, ’facet’),
’Left’ : (’vertices in (x < %f)’ % -0.4999, ’facet’),
’Right’ : (’vertices in (x > %f)’ % 0.4999, ’facet’),
}
materials = {
’m’ : ({
’thermal_conductivity’ : 2.0,
’electric_conductivity’ : 1.5,
},),
}
# The fields use the same approximation, so a single field could be used
# instead.
fields = {
’temperature’: (’real’, 1, ’Omega’, 1),
’potential’ : (’real’, 1, ’Omega’, 1),
}
variables = {
’T’ : (’unknown field’, ’temperature’, 0, 1),
’s’ : (’test field’, ’temperature’, ’T’),
’phi’ : (’unknown field’, ’potential’, 1),
’psi’ : (’test field’, ’potential’, ’phi’),
’phi_known’ : (’parameter field’, ’potential’, ’(set-to-None)’),
}
ics = {
’ic’ : (’Omega’, {’T.0’ : 0.0}),
}
ebcs = {
’left’ : (’Left’, {’T.0’ : 0.0, ’phi.0’ : 0.0}),
’right’ : (’Right’, {’T.0’ : 2.0, ’phi.0’ : 0.0}),
’inside’ : (’Omega2_Surface’, {’phi.0’ : ’set_electric_bc’}),
}
def set_electric_bc(coor):
y = coor[:,1]
ymin, ymax = y.min(), y.max()
val = 2.0 * (((y - ymin) / (ymax - ymin)) - 0.5)
return val
functions = {
’set_electric_bc’ : (lambda ts, coor, bc, problem, **kwargs:
5.3. Examples
307
SfePy Documentation, Release 2015.1
set_electric_bc(coor),),
}
equations = {
’2’ : """%.12e * dw_volume_dot.2.Omega( s, dT/dt )
+ dw_laplace.2.Omega( m.thermal_conductivity, s, T )
= dw_electric_source.2.Omega( m.electric_conductivity,
s, phi_known ) """ % specific_heat,
’1’ : """dw_laplace.2.Omega( m.electric_conductivity, psi, phi ) = 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
’problem’
: ’nonlinear’,
}),
’ts’ : (’ts.simple’, {
’t0’
: t0,
’t1’
: t1,
’dt’
: None,
’n_step’ : n_step, # has precedence over dt!
}),
}
def main():
from sfepy.base.base import output
from sfepy.base.conf import ProblemConf, get_standard_keywords
from sfepy.discrete import Problem
output.prefix = ’therel:’
required, other = get_standard_keywords()
conf = ProblemConf.from_file(__file__, required, other)
problem = Problem.from_conf(conf, init_equations=False)
# Setup output directory according to options above.
problem.setup_default_output()
# First solve the stationary electric conduction problem.
problem.set_equations({’eq’ : conf.equations[’1’]})
problem.time_update()
state_el = problem.solve()
problem.save_state(problem.get_output_name(suffix = ’el’), state_el)
# Then solve the evolutionary heat conduction problem, using state_el.
problem.set_equations({’eq’ : conf.equations[’2’]})
phi_var = problem.get_variables()[’phi_known’]
phi_var.set_data(state_el())
time_solver = problem.get_time_solver()
time_solver()
output(’results saved in %s’ % problem.get_output_name(suffix = ’*’))
if __name__ == ’__main__’:
main()
308
Chapter 5. Examples
SfePy Documentation, Release 2015.1
5.3.17 thermo_elasticity
thermo_elasticity/thermo_elasticity.py
Description
Thermo-elasticity with a given temperature distribution.
Uses dw_biot term with an isotropic coefficient for thermo-elastic coupling.
For given body temperature 𝑇 and background temperature 𝑇0 find 𝑢 such that:
∫︁
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) − (𝑇 − 𝑇0 ) 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) = 0 ,
Ω
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 ,
𝛼𝑖𝑗 = (3𝜆 + 2𝜇)𝛼𝛿𝑖𝑗
and 𝛼 is the thermal expansion coefficient.
source code
r"""
Thermo-elasticity with a given temperature distribution.
Uses ‘dw_biot‘ term with an isotropic coefficient for thermo-elastic coupling.
5.3. Examples
309
SfePy Documentation, Release 2015.1
For given body temperature :math:‘T‘ and background temperature
:math:‘T_0‘ find :math:‘\ul{u}‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} (T - T_0)\ \alpha_{ij} e_{ij}(\ul{v})
= 0
\;, \quad \forall \ul{v} \;,
where
.. math::
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;, \\
\alpha_{ij} = (3 \lambda + 2 \mu) \alpha \delta_{ij}
and :math:‘\alpha‘ is the thermal expansion coefficient.
"""
import numpy as np
from
from
from
from
sfepy.base.base import Struct
sfepy.mechanics.matcoefs import stiffness_from_lame
sfepy.mechanics.tensors import get_von_mises_stress
sfepy import data_dir
# Material parameters.
lam = 10.0
mu = 5.0
thermal_expandability = 1.25e-5
T0 = 20.0 # Background temperature.
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
def get_temperature_load(ts, coors, region=None):
"""
Temperature load depends on the ‘x‘ coordinate.
"""
x = coors[:, 0]
return (x - x.min())**2 - T0
def post_process(out, pb, state, extend=False):
"""
Compute derived quantities: strain, stresses. Store also the loading
temperature.
"""
ev = pb.evaluate
strain = ev(’ev_cauchy_strain.2.Omega( u )’, mode=’el_avg’)
out[’cauchy_strain’] = Struct(name=’output_data’,
mode=’cell’, data=strain,
dofs=None)
e_stress = ev(’ev_cauchy_stress.2.Omega( solid.D, u )’, mode=’el_avg’)
out[’elastic_stress’] = Struct(name=’output_data’,
mode=’cell’, data=e_stress,
dofs=None)
310
Chapter 5. Examples
SfePy Documentation, Release 2015.1
t_stress = ev(’ev_biot_stress.2.Omega( solid.alpha, T )’, mode=’el_avg’)
out[’thermal_stress’] = Struct(name=’output_data’,
mode=’cell’, data=t_stress,
dofs=None)
out[’total_stress’] = Struct(name=’output_data’,
mode=’cell’, data=e_stress + t_stress,
dofs=None)
out[’von_mises_stress’] = aux = out[’total_stress’].copy()
vms = get_von_mises_stress(aux.data.squeeze())
vms.shape = (vms.shape[0], 1, 1, 1)
out[’von_mises_stress’].data = vms
val = pb.get_variables()[’T’]()
val.shape = (val.shape[0], 1)
out[’T’] = Struct(name=’output_data’,
mode=’vertex’, data=val + T0,
dofs=None)
return out
options = {
’post_process_hook’ : ’post_process’,
’nls’ : ’newton’,
’ls’ : ’ls’,
}
functions = {
’get_temperature_load’ : (get_temperature_load,),
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
’temperature’: (’real’, 1, ’Omega’, 1),
}
variables
’u’ :
’v’ :
’T’ :
= {
(’unknown field’, ’displacement’, 0),
(’test field’, ’displacement’, ’u’),
(’parameter field’, ’temperature’,
{’setter’ : ’get_temperature_load’}),
}
ebcs = {
’fix_u’ : (’Left’, {’u.all’ : 0.0}),
}
eye_sym = np.array([[1], [1], [1], [0], [0], [0]], dtype=np.float64)
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=lam, mu=mu),
’alpha’ : (3.0 * lam + 2.0 * mu) * thermal_expandability * eye_sym
5.3. Examples
311
SfePy Documentation, Release 2015.1
},),
}
equations = {
’balance_of_forces’ :
"""dw_lin_elastic.2.Omega( solid.D, v, u )
- dw_biot.2.Omega( solid.alpha, v, T )
= 0""",
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
}
thermo_elasticity/thermo_elasticity_ess.py
Description
Thermo-elasticity with a computed temperature demonstrating equation sequence solver.
Uses dw_biot term with an isotropic coefficient for thermo-elastic coupling.
The equation sequence solver (’ess’ in solvers) automatically solves first the temperature distribution and then
the elasticity problem with the already computed temperature.
Find 𝑢, 𝑇 such that:
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) − (𝑇 − 𝑇0 ) 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) = 0 ,
Ω
Ω
∫︁
∇𝑠 · ∇𝑇 = 0 , ∀𝑠 .
∫︁
∀𝑣 ,
Ω
where
𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙 ,
𝛼𝑖𝑗 = (3𝜆 + 2𝜇)𝛼𝛿𝑖𝑗 ,
𝑇0 is the background temperature and 𝛼 is the thermal expansion coefficient.
Notes
The gallery image was produced by (plus proper view settings):
./postproc.py block.vtk -d’u,plot_displacements,rel_scaling=1000,color_kind="scalars",color_name="T"’
312
Chapter 5. Examples
SfePy Documentation, Release 2015.1
source code
r"""
Thermo-elasticity with a computed temperature demonstrating equation sequence
solver.
Uses ‘dw_biot‘ term with an isotropic coefficient for thermo-elastic coupling.
The equation sequence solver (‘‘’ess’‘‘ in ‘‘solvers‘‘) automatically solves
first the temperature distribution and then the elasticity problem with the
already computed temperature.
Find :math:‘\ul{u}‘, :math:‘T‘ such that:
.. math::
\int_{\Omega} D_{ijkl}\ e_{ij}(\ul{v}) e_{kl}(\ul{u})
- \int_{\Omega} (T - T_0)\ \alpha_{ij} e_{ij}(\ul{v})
= 0
\;, \quad \forall \ul{v} \;,
\int_{\Omega} \nabla s \cdot \nabla T
= 0
\;, \quad \forall s \;.
where
.. math::
5.3. Examples
313
SfePy Documentation, Release 2015.1
D_{ijkl} = \mu (\delta_{ik} \delta_{jl}+\delta_{il} \delta_{jk}) +
\lambda \ \delta_{ij} \delta_{kl}
\;, \\
\alpha_{ij} = (3 \lambda + 2 \mu) \alpha \delta_{ij} \;,
:math:‘T_0‘ is the background temperature and :math:‘\alpha‘ is the thermal
expansion coefficient.
Notes
----The gallery image was produced by (plus proper view settings)::
./postproc.py block.vtk -d’u,plot_displacements,rel_scaling=1000,color_kind="scalars",color_name=
"""
import numpy as np
from sfepy.mechanics.matcoefs import stiffness_from_lame
from sfepy import data_dir
# Material parameters.
lam = 10.0
mu = 5.0
thermal_expandability = 1.25e-5
T0 = 20.0 # Background temperature.
filename_mesh = data_dir + ’/meshes/3d/block.mesh’
options = {
’ts’ : ’ess’,
’nls’ : ’newton’,
’ls’ : ’ls’,
}
regions = {
’Omega’ : ’all’,
’Left’ : (’vertices in (x < -4.99)’, ’facet’),
’Right’ : (’vertices in (x > 4.99)’, ’facet’),
’Bottom’ : (’vertices in (z < -0.99)’, ’facet’),
}
fields = {
’displacement’: (’real’, 3, ’Omega’, 1),
’temperature’: (’real’, 1, ’Omega’, 1),
}
variables
’u’ :
’v’ :
’T’ :
’s’ :
}
ebcs = {
’u0’
’t0’
’t2’
’t1’
314
:
:
:
:
= {
(’unknown field’, ’displacement’, 0),
(’test field’, ’displacement’, ’u’),
(’unknown field’, ’temperature’, 1),
(’test field’, ’temperature’, ’T’),
(’Left’, {’u.all’ : 0.0}),
(’Left’, {’T.0’ : 20.0}),
(’Bottom’, {’T.0’ : 0.0}),
(’Right’, {’T.0’ : 30.0}),
Chapter 5. Examples
SfePy Documentation, Release 2015.1
}
eye_sym = np.array([[1], [1], [1], [0], [0], [0]], dtype=np.float64)
materials = {
’solid’ : ({
’D’ : stiffness_from_lame(3, lam=lam, mu=mu),
’alpha’ : (3.0 * lam + 2.0 * mu) * thermal_expandability * eye_sym
},),
}
equations = {
’balance_of_forces’ : """
+ dw_lin_elastic.2.Omega(solid.D, v, u)
- dw_biot.2.Omega(solid.alpha, v, T)
= 0
""",
’temperature’ : """
+ dw_laplace.1.Omega(s, T)
= 0
"""
}
solvers = {
’ls’ : (’ls.scipy_direct’, {}),
’newton’ : (’nls.newton’, {
’i_max’
: 1,
’eps_a’
: 1e-10,
}),
’ess’ : (’ts.equation_sequence’, {}),
}
5.3. Examples
315
SfePy Documentation, Release 2015.1
316
Chapter 5. Examples
CHAPTER
SIX
THEORETICAL BACKGROUND
This part introduces parts the theoretical mathematical background necessary to use SfePy effectively. It also discusses
some implementation choices done in SfePy.
Contents:
6.1 Notes on solving PDEs by the Finite Element Method
The Finite Element Method (FEM) is the numerical method for solving Partial Differential Equations (PDEs). FEM
was developed in the middle of XX. century and now it is widely used in different areas of science and engineering,
including mechanical and structural design, biomedicine, electrical and power design, fluid dynamics and other. FEM
is based on a very elegant mathematical theory of weak solution of PDEs. In this section we will briefly discuss basic
ideas underlying FEM.
6.1.1 Strong form of Poisson’s equation and its integration
Let us start our discussion about FEM with the strong form of Poisson’s equation
∆𝑇 = 𝑓 (𝑥),
𝑇 = 𝑢(𝑥),
∇𝑇 · n = 𝑔(𝑥),
𝑥 ∈ Ω,
(6.1)
𝑥 ∈ Γ𝐷 ,
(6.2)
𝑥 ∈ Γ𝑁 ,
(6.3)
where Ω ⊂ R𝑛 is the solution domain with the boundary 𝜕Ω, Γ𝐷 is the part of the boundary where Dirichlet boundary
conditions are given, Γ𝑁 is the part of the boundary where Neumann boundary conditions are given, 𝑇 (𝑥) is the
unknown function to be found, 𝑓 (𝑥), 𝑢(𝑥), 𝑔(𝑥) are known functions.
FEM is based on a weak formulation. The weak form of the equation (6.1) is
∫︁
(∆𝑇 − 𝑓 ) · 𝑠 dΩ = 0,
Ω
where 𝑠 is a test function. Integrating this equation by parts
∫︁
∫︁
∫︁
0 = (∆𝑇 − 𝑓 ) · 𝑠 dΩ = ∇ · (∇𝑇 ) · 𝑠 dΩ −
𝑓 · 𝑠 dΩ =
Ω
Ω
Ω
317
SfePy Documentation, Release 2015.1
∫︁
=−
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ +
Ω
∇ · (∇𝑇 · 𝑠) dΩ −
Ω
and applying Gauss theorem we obtain:
∫︁
0 = − ∇𝑇 · ∇𝑠 dΩ +
Ω
∫︁
∫︁
𝑠 · (∇𝑇 · n) dΓ −
Γ𝐷 ∪Γ𝑁
Ω
𝑓 · 𝑠 dΩ
𝑓 · 𝑠 dΩ
Ω
or
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ =
∫︁
𝑠 · (∇𝑇 · n) dΓ −
Γ𝐷 ∪Γ𝑁
Ω
𝑓 · 𝑠 dΩ.
Ω
The surface integral term can be split into two integrals, one over the Dirichlet part of the surface and second over the
Neumann part
∫︁
∫︁
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ =
𝑠 · (∇𝑇 · n) dΓ +
𝑠 · (∇𝑇 · n) dΓ − 𝑓 · 𝑠 dΩ.
(6.4)
Ω
Γ𝐷
Γ𝑁
Ω
The equation (6.4) is the initial weak form of the Poisson’s problem (6.1)–(6.3). But we can not work with it without
applying the boundary conditions. So it is time to talk about the boundary conditions.
Dirichlet Boundary Conditions
On the Dirichlet part of the surface we have two restrictions. One is the Dirichlet boundary conditions 𝑇 (𝑥) = 𝑢(𝑥)
as they are, and the second is the integral term over Γ𝐷 in equation (6.4). To be consistent we have to use only the
Dirichlet conditions and avoid the integral term. To implement this we can take the function 𝑇 ∈ 𝑉 (Ω) and the test
function 𝑠 ∈ 𝑉0 (Ω), where
𝑉 (Ω) = {𝑓 (𝑥) ∈ 𝐻 1 (Ω)},
𝑉0 (Ω) = {𝑓 (𝑥) ∈ 𝐻 1 (Ω); 𝑓 (𝑥) = 0, 𝑥 ∈ Γ𝐷 }.
In other words the unknown function 𝑇 must be continuous together with its gradient in the domain. In contrast the
test function 𝑠 must be also continuous together with its gradient in the domain but it should be zero on the surface
Γ𝐷 .
With this requirement the integral term over Dirichlet part of the surface is vanishing and the weak form of the Poisson
equation for 𝑇 ∈ 𝑉 (Ω) and 𝑠 ∈ 𝑉0 (Ω) becomes
∫︁
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ =
𝑠 · (∇𝑇 · n) dΓ − 𝑓 · 𝑠 dΩ,
Ω
Γ𝑁
Ω
𝑇 (𝑥) = 𝑢(𝑥),
𝑥 ∈ Γ𝐷 .
That is why Dirichlet conditions in FEM terminology are called Essential Boundary Conditions. These conditions
are not a part of the weak form and they are used as they are.
Neumann Boundary Conditions
The Neumann boundary conditions correspond to the known flux 𝑔(𝑥) = ∇𝑇 · n. The integral term over the Neumann
surface in the equation (6.4) contains exactly the same flux. So we can use the known function 𝑔(𝑥) in the integral
term:
∫︁
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ =
𝑔 · 𝑠 dΓ − 𝑓 · 𝑠 dΩ,
Ω
318
Γ𝑁
Ω
Chapter 6. Theoretical Background
SfePy Documentation, Release 2015.1
where test function 𝑠 also belongs to the space 𝑉0 .
That is why Neumann conditions in FEM terminology are called Natural Boundary Conditions. These conditions
are a part of weak form terms.
6.1.2 The weak form of the Poisson’s equation
Now we can write the resulting weak form for the Poisson’s problem (6.1)–(6.3). For any test function 𝑠 ∈ 𝑉0 (Ω) find
𝑇 ∈ 𝑉 (Ω) such that
∫︁
∫︁
∇𝑇 · ∇𝑠 dΩ =
Ω
∫︁
𝑔 · 𝑠 dΓ −
Γ𝑁
𝑇 (𝑥) = 𝑢(𝑥),
𝑓 · 𝑠 dΩ,
and
Ω
(6.5)
𝑥 ∈ Γ𝐷 .
6.1.3 Discussion of discretization and meshing
It is planned to have an example of the discretization based on the Poisson’s equation weak form (6.5). For now, please
refer to the wikipedia page Finite Element Method for a basic description of the disretization and meshing.
6.1.4 Numerical solution of the problem
To solve numerically given problem based on the weak form (6.5) we have to go through 5 steps:
1. Define geometry of the domain Ω and surfaces Γ𝐷 and Γ𝑁 .
2. Define the known functions 𝑓 , 𝑢 and 𝑔.
3. Define the unknown function 𝑇 and the test functions 𝑠.
4. Define essential boundary conditions (Dirichlet conditions) 𝑇 (𝑥) = 𝑢(𝑥), 𝑥 ∈ Γ𝐷 .
∫︀
5. Define equation and natural boundary conditions (Neumann conditions) as the set of all integral terms ∇𝑇 ·
Ω
∫︀
∫︀
∇𝑠 dΩ,
𝑔 · 𝑠 dΓ, 𝑓 · 𝑠 dΩ.
Γ𝑁
Ω
6.2 Implementation of Essential Boundary Conditions
The essential boundary conditions can be applied in several ways. Here we describe the implementation used in SfePy.
6.2.1 Motivation
Let us solve a linear system 𝐴𝑥 = 𝑏 with 𝑛 × 𝑛 matrix 𝐴 with 𝑛𝑓 values in the 𝑥 vector known. The known values can
be for example EBC values on a boundary, if 𝐴 comes from a PDE discretization. If we put the known fixed values
into a vector 𝑥𝑓 , that has the same size as 𝑥, and has zeros in positions that are not fixed, we can easily construct a
𝑛 × 𝑛𝑟 matrix 𝑇 that maps the reduced vector 𝑥𝑟 of size 𝑛𝑟 = 𝑛 − 𝑛𝑓 , where the fixed values are removed, to the full
vector 𝑥:
𝑥 = 𝑇 𝑥𝑟 + 𝑥𝑓 .
6.2. Implementation of Essential Boundary Conditions
319
SfePy Documentation, Release 2015.1
With that the reduced linear system with a 𝑛𝑟 × 𝑛𝑟 can be formed:
𝑇 𝑇 𝐴𝑇 𝑥𝑟 = 𝑇 𝑇 (𝑏 − 𝐴𝑥𝑓 )
that can be solved by a linear solver. We can see, that the (non-zero) known values are now on the right-hand side of
the linear system. When the known values are all zero, we have simply
𝑇 𝑇 𝐴𝑇 𝑥𝑟 = 𝑇 𝑇 𝑏 ,
which is convenient, as it allows simply throwing away the A and b entries corresponding to the known values already
during the finite element assembling.
6.2.2 Implementation
All PDEs in SfePy are solved in a uniform way as a system of non-linear equations
𝑓 (𝑢) = 0 ,
where 𝑓 is the nonlinear function and 𝑢 the vector of unknown DOFs. This system is solved iteratively by the Newton
method
𝑢𝑛𝑒𝑤 = 𝑢𝑜𝑙𝑑 − (
d𝑓 −1
) 𝑓 (𝑢𝑜𝑙𝑑 )
d𝑢𝑜𝑙𝑑
until a convergence criterion is met. Each iteration involves solution of the system of linear equations
𝐾∆𝑢 = 𝑟 ,
where the tangent matrix 𝐾 and the residual 𝑟 are
d𝑓
,
d𝑢𝑜𝑙𝑑
𝑟 ≡ 𝑓 (𝑢𝑜𝑙𝑑 ) .
𝐾≡
Then
𝑢𝑛𝑒𝑤 = 𝑢𝑜𝑙𝑑 − ∆𝑢 .
If the initial (old) vector 𝑢𝑜𝑙𝑑 contains the values of EBCs at correct positions, the increment ∆𝑢 is zero at those
positions. This allows us to assemble directly the reduced matrix 𝑇 𝑇 𝐾𝑇 , the right-hand side 𝑇 𝑇 𝑟, and ignore the
values of EBCs during assembling. The EBCs are satisfied automatically by applying them to the initial guess 𝑢0 , that
is given to the Newton solver.
Linear Problems
For linear problems we have
𝑓 (𝑢) ≡ 𝐴𝑢 − 𝑏 = 0 ,
d𝑓
=𝐴,
d𝑢
and so the Newton method converges in a single iteration:
𝑢𝑛𝑒𝑤 = 𝑢𝑜𝑙𝑑 − 𝐴−1 (𝐴𝑢𝑜𝑙𝑑 − 𝑏) = 𝐴−1 𝑏 .
320
Chapter 6. Theoretical Background
SfePy Documentation, Release 2015.1
Evaluation of Residual and Tangent Matrix
The evaluation of the residual 𝑓 as well as the tangent matrix 𝐾 within the Newton solver proceeds in the following
steps:
• The EBCs are applied to the full DOF vector 𝑢.
• The reduced vector 𝑢𝑟 is passed to the Newton solver.
• Newton iteration loop:
– Evaluation of 𝑓𝑟 or 𝐾𝑟 :
1. 𝑢 is reconstructed from 𝑢𝑟 ;
2. local element contributions are evaluated using 𝑢;
3. local element contributions are assembled into 𝑓𝑟 or 𝐾𝑟 - values corresponding to fixed DOF positions
are thrown away.
– The reduced system 𝐾𝑟 ∆𝑢𝑟 = 𝑟𝑟 is solved.
– Solution is updated: 𝑢𝑟 ← 𝑢𝑟 − ∆𝑢𝑟 .
– The loop is terminated if a stopping condition is satisfied, the solver returns the final 𝑢𝑟 .
• The final 𝑢 is reconstructed from 𝑢𝑟 .
6.2. Implementation of Essential Boundary Conditions
321
SfePy Documentation, Release 2015.1
322
Chapter 6. Theoretical Background
CHAPTER
SEVEN
DEVELOPER GUIDE
323
SfePy Documentation, Release 2015.1
Table of Contents
• SfePy Directory Structure
• Exploring the Code
• How to Contribute
– Reporting problems
– Making changes
– Coding style
– Contributing changes
* Without git
* With git
* Notes on commits and patches
* Docstring standard
• How to Regenerate Documentation
• How to Implement a New Term
– Notes on terminology
– Introduction
– Evaluation modes
– Basic attributes
* Argument types
* Integration kinds
* function()
* get_fargs()
– Additional attributes
* Argument shapes
* Geometries
– Example
– Concluding remarks
• How To Make a Release
• Working with SfePy source code
• Module Index
– Main scripts
– Utility scripts
– sfepy package
– sfepy.applications package
– sfepy.base package
– sfepy.discrete package
* sfepy.discrete.common sub-package
* sfepy.discrete.fem sub-package
* sfepy.discrete.iga sub-package
– sfepy.homogenization package
– sfepy.linalg package
– sfepy.mechanics package
– sfepy.mesh package
– sfepy.optimize package
– sfepy.physics package
– sfepy.postprocess package
– sfepy.solvers package
– sfepy.terms package
This section purports to document the SfePy internals. It is mainly useful for those who wish to contribute to the
development of SfePy and understand the inner workings of the code.
324
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
7.1 SfePy Directory Structure
Here we list and describe the directories that are in the main sfepy directory.
Table 7.1: Top directory structure.
name
build/
doc/
examples/
meshes/
output/
output-tests/
script/
sfepy/
tests/
tmp/
description
directory created by the build process (generated)
source files of this documentation
example problem description files
finite element mesh files in various formats shared by the examples
default output directory for storing results of the examples
output directory for tests
various small scripts (simple mesh generators, mesh format convertors etc.)
the source code
the tests run by run_tests.py
directory for temporary files (generated)
New users/developers (after going through the Tutorial) should explore the examples/ directory. For developers, the
principal directory is sfepy/, which has the following contents:
7.1. SfePy Directory Structure
325
SfePy Documentation, Release 2015.1
Table 7.2: sfepy/ directory structure.
name
applications/
base/
discrete/
mesh/
homogenization/
linalg/
mechanics/
optimize/
description
top level application classes (e.g.
PDESolverApp that implements
all that simple.py script does)
common utilities and classes used by
most of the other modules
general classes and modules for describing a discrete problem, taking
care of boundary conditions, degrees
of freedom, approximations, variables, equations, meshes, regions,
quadratures, etc.
Discretization-specific classes are in
subdirectories:
• common/ - common parent
classes for discretizationspecific classes
• fem/ - finite element specific
classes
• iga/ - isogeometric analysis
specific classes
some utilities to interface with tetgen
and triangle mesh generators
the homogenization engine and supporting modules - highly specialized
code, one of the reasons of SfePy existence
linear algebra functions not covered
by NumPy and SciPy
modules for (continuum) mechanics:
elastic constant conversions, tensor,
units utilities, etc.
modules for shape optimization
based on free-form deformation
physics/
small utilities for quantum physics
(schroedinger.py)
postprocess/
Mayavi-based post-processing modules (postproc.py)
interface classes to various internal/external solvers (linear, nonlinear, eigenvalue, optimization, time
stepping)
implementation of the terms (weak
formulation integrals), see Term
Overview
solvers/
terms/
field-specific
•
•
•
•
The directories in the “field-specific” column are mostly interesting for specialists working in the respective fields.
The fem/ is the heart of the code, while the terms/ contains the particular integral forms usable to build equations new term writers should look there.
326
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
7.2 Exploring the Code
It is convenient to install IPython (see also Using IPython) to have the tab completion available. Moreover, all SfePy
classes can be easily examined by printing them:
1
In [1]: from sfepy.discrete.fem import Mesh
2
3
4
5
In [2]: mesh = Mesh.from_file(’meshes/2d/rectangle_tri.mesh’)
sfepy: reading mesh [line2, tri3, quad4, tetra4, hexa8] (meshes/2d/rectangle_tri.mesh)...
sfepy: ...done in 0.00 s
6
7
8
In [3]: mesh
Out[3]: Mesh:meshes/2d/rectangle_tri
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
In [4]: print mesh
Mesh:meshes/2d/rectangle_tri
conns:
list: [array([[ 59,
0, 60],
[ 60,
0,
2],
[ 11, 32, 64],
...,
[254, 250, 251],
[251, 256, 257],
[257, 254, 251]], dtype=int32)]
coors:
(258, 2) array of float64
descs:
list: [’2_3’]
dim:
2
dims:
list: [2]
el_offsets:
(2,) array of int64
io:
None
mat_ids:
list: [array([3, 3, 3, ..., 3, 3, 3], dtype=int32)]
n_e_ps:
(1,) array of int64
n_el:
454
n_els:
(1,) array of int64
n_nod:
258
name:
meshes/2d/rectangle_tri
ngroups:
(258,) array of float64
nodal_bcs:
dict with keys: []
setup_done:
0
We recommend going through the interactive example in the tutorial Interactive Example: Linear Elasticity in this
way, printing all the variables.
Another useful tool is the debug() function, that can be used as follows:
7.2. Exploring the Code
327
SfePy Documentation, Release 2015.1
from sfepy.base.base import debug; debug()
Try to use it in the examples with user defined functions to explore their parameters etc. It works best with IPython
installed, as then the tab completion is available also when debugging.
7.3 How to Contribute
Read this section if you wish to contribute some work to the SfePy project. Contributions can be made in a variety of
forms, not just code. Reporting bugs and contributing to the documentation, tutorials, and examples is in great need!
Below we describe
1. where to report or find current problems, issues, and suggestions of particular topics for additional development
2. what to do to apply changes/fixes
3. what to do after you made your changes/fixes
7.3.1 Reporting problems
Reporting a bug is the first way in which to contribute to an open source project
Short version: go to the main SfePy and follow the links given there.
When you encounter a problem, try searching that site first - an answer may already be posted in the SfePy mailing
list (to which we suggest you subscribe...), or the problem might have been added to the SfePy issues web page. As is
true in any open source project, doing your homework by searching for existing known problems greatly reduces the
burden on the developers by eliminating duplicate issues. If you find your problem already exists in the issue tracker,
feel free to gather more information and append it to the issue. In case the problem is not there, create a new issue
with proper labels for the issue type and priority, and/or ask us using the mailing list.
Note A google account (e.g., gmail account) is needed to join the mailing list and post comments to issues. It is,
however, not needed to create a new issue.
Note When reporting a problem, try to provide as much information as possible concerning the version of SfePy, the
OS / Linux distribution, and the versions of Python, NumPy and SciPy, and other prerequisites.
Our persisting all star top priority issues include:
• missing docstrings in many functions/classes/modules
• incomplete documentation
• lowering the barrier for new users
– e.g., through generation of additional tutorial material
So if you are a new user, please let us know what difficulties you have with this documentation. We greatly welcome
a variety of contributions not limited to code only.
7.3.2 Making changes
This step is simple, just keep in mind to use the latest development version of the code from the SfePy git repository
page.
We use git to track source code, documentation, examples, and other files related to the project.
328
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
It is not necessary to learn git in order to contribute to SfePy but we strongly suggest you do so as soon as possible it is an extremely useful tool not just for writing code, but also for tracking revisions of articles, Ph.D. theses, books,
... it will also look well in your CV :-) It is also much easier for us to integrate changes that are in form of a nice git
patch than in another form.
Having said that, to download the latest snapshot, do either (with git):
• git clone git://github.com/sfepy/sfepy.git
or (without git):
• use the SfePy tarball link
Then make the changes as you wish, following our Coding style.
Note Do not be afraid to experiment - git works with your local copy of the repository, so it is not possible to damage
the master repository. It is always possible to re-clone a fresh copy, in case you do something that is really bad.
7.3.3 Coding style
All the code in SfePy should try to adhere to python style guidelines, see PEP-0008.
There are some additional recommendations:
• Prefer whole words to abbreviations in public APIs - there is completion after all. If some abbreviation is needed
(really too long name), try to make it as comprehensible as possible. Also check the code for similar names try to name things consistently with the existing code. Examples:
– yes: equation, transform_variables(), filename
– rather not: eq, transvar(), fname
• Functions
have
usually
form
<action>_<subject>()
e.g.:
save_data(),
transform_variables(), do not use data_save(), variable_transform() etc.
• Variables like V, c, A, b, x should be tolerated only locally when expressing mathematical ideas.
Really minor recommendations:
• Avoid single letter names, if you can:
– not even for loop variables - use e.g. ir, ic, ... instead of i, j for rows and columns
– not even in generators, as they “leak” (this is fixed in Python 3.x)
These are recommendations only, we will not refuse code just on the ground that it uses slightly different formatting,
as long as it follows the PEP.
Note: some old parts of the code might not follow the PEP, yet. We fix them progressively as we update the code.
7.3.4 Contributing changes
Even if you do not use git, try to follow the spirit of Notes on commits and patches
Without git
Without using git, send the modified files to the SfePy mailing list or attach them using gist to the corresponding issue
at the Issues web page. Do not forget to describe the changes properly.
7.3. How to Contribute
329
SfePy Documentation, Release 2015.1
With git
Contents:
Introduction
These pages describe a git and github workflow for the SfePy project.
There are several different workflows here, for different ways of working with SfePy.
This is not a comprehensive git reference, it’s just a workflow for our own project. It’s tailored to the github hosting
service. You may well find better or quicker ways of getting stuff done with git, but these should get you started.
For general resources for learning git, see git resources.
Install git
Overview
Debian / Ubuntu
Fedora
Windows
OS X
sudo apt-get install git-core
sudo yum install git-core
Download and install msysGit
Use the git-osx-installer
In detail See the git page for the most recent information.
Have a look at the github install help pages available from github help
There are good instructions here: http://book.git-scm.com/2_installing_git.html
Following the latest source
These are the instructions if you just want to follow the latest SfePy source, but you don’t need to do any development
for now.
The steps are:
• Install git
• get local copy of the SfePy github git repository
• update local copy from time to time
Get the local copy of the code From the command line:
git clone git://github.com/sfepy/sfepy.git
You now have a copy of the code tree in the new sfepy directory.
Updating the code From time to time you may want to pull down the latest code. Do this with:
cd sfepy
git pull
The tree in sfepy will now have the latest changes from the initial repository.
330
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Making a patch
You’ve discovered a bug or something else you want to change in SfePy .. — excellent!
You’ve worked out a way to fix it — even better!
You want to tell us about it — best of all!
The easiest way is to make a patch or set of patches. Here we explain how. Making a patch is the simplest and
quickest, but if you’re going to be doing anything more than simple quick things, please consider following the Git for
development model instead.
Making patches
Overview
# tell git who you are
git config --global user.email [email protected]
git config --global user.name "Your Name Comes Here"
# get the repository if you don’t have it
git clone git://github.com/sfepy/sfepy.git
# make a branch for your patching
cd sfepy
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
# hack, hack, hack
# Tell git about any new files you’ve made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am ’BF - added tests for Funny bug’
# hack hack, hack
git commit -am ’BF - added fix for Funny bug’
# make the patch files
git format-patch -M -C master
Then, send the generated patch files to the SfePy mailing list — where we will thank you warmly.
In detail
1. Tell git who you are so it can label the commits you’ve made:
git config --global user.email [email protected]
git config --global user.name "Your Name Comes Here"
2. If you don’t already have one, clone a copy of the SfePy repository:
git clone git://github.com/sfepy/sfepy.git
cd sfepy
3. Make a ‘feature branch’. This will be where you work on your bug fix. It’s nice and safe and leaves you with
access to an unmodified copy of the code in the main branch:
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
4. Do some edits, and commit them as you go:
7.3. How to Contribute
331
SfePy Documentation, Release 2015.1
# hack, hack, hack
# Tell git about any new files you’ve made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am ’BF - added tests for Funny bug’
# hack hack, hack
git commit -am ’BF - added fix for Funny bug’
Note the -am options to commit. The m flag just signals that you’re going to type a message on the command
line. The a flag — you can just take on faith — or see why the -a flag?.
5. When you have finished, check you have committed all your changes:
git status
6. Finally, make your commits into patches. You want all the commits since you branched from the master
branch:
git format-patch -M -C master
You will now have several files named for the commits:
0001-BF-added-tests-for-Funny-bug.patch
0002-BF-added-fix-for-Funny-bug.patch
Send these files to the SfePy mailing list.
When you are done, to switch back to the main copy of the code, just return to the master branch:
git checkout master
Moving from patching to development If you find you have done some patches, and you have one or more feature
branches, you will probably want to switch to development mode. You can do this with the repository you have.
Fork the SfePy repository on github — Making your own copy (fork) of SfePy. Then:
# checkout and refresh master branch from main repo
git checkout master
git pull origin master
# rename pointer to main repository to ’upstream’
git remote rename origin upstream
# point your repo to default read / write to your fork on github
git remote add origin [email protected]:your-user-name/sfepy.git
# push up any branches you’ve made and want to keep
git push origin the-fix-im-thinking-of
Then you can, if you want, follow the Development workflow.
Git for development
Contents:
Making your own copy (fork) of SfePy You need to do this only once. The instructions here are very similar to the
instructions at http://help.github.com/forking/ — please see that page for more detail. We’re repeating some of it here
just to give the specifics for the SfePy project, and to suggest some default names.
332
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Set up and configure a github account If you don’t have a github account, go to the github page, and make one.
You then need to configure your account to allow write access — see the Generating SSH keys help on github
help.
Create your own forked copy of SfePy
1. Log into your github account.
2. Go to the SfePy github home at SfePy github.
3. Click on the fork button:
Now, after a short pause and some ‘Hardcore forking action’, you should find yourself at the home page for your
own forked copy of SfePy.
Set up your fork First you follow the instructions for Making your own copy (fork) of SfePy.
Overview
git clone [email protected]:your-user-name/sfepy.git
cd sfepy
git remote add upstream git://github.com/sfepy/sfepy.git
In detail
Clone your fork
1. Clone your fork to the local computer with git clone [email protected]:your-user-name/sfepy.git
2. Investigate. Change directory to your new repo: cd sfepy. Then git branch -a to show you all
branches. You’ll get something like:
* master
remotes/origin/master
This tells you that you are currently on the master branch, and that you also have a remote connection to
origin/master. What remote repository is remote/origin? Try git remote -v to see the URLs
for the remote. They will point to your github fork.
Now you want to connect to the upstream SfePy github repository, so you can merge in changes from trunk.
Linking your repository to the upstream repo
cd sfepy
git remote add upstream git://github.com/sfepy/sfepy.git
7.3. How to Contribute
333
SfePy Documentation, Release 2015.1
upstream here is just the arbitrary name we’re using to refer to the main SfePy repository at SfePy github.
Note that we’ve used git:// for the URL rather than [email protected] The git:// URL is read only. This means we that we
can’t accidentally (or deliberately) write to the upstream repo, and we are only going to use it to merge into our own
code.
Just for your own satisfaction, show yourself that you now have a new ‘remote’, with git remote -v show,
giving you something like:
upstream
upstream
origin
origin
git://github.com/sfepy/sfepy.git (fetch)
git://github.com/sfepy/sfepy.git (push)
[email protected]:your-user-name/sfepy.git (fetch)
[email protected]:your-user-name/sfepy.git (push)
Configure git
Overview Your personal git configurations are saved in the .gitconfig file in your home directory.
Here is an example .gitconfig file:
[user]
name = Your Name
email = [email protected]
[alias]
ci = commit -a
co = checkout
st = status
stat = status
br = branch
wdiff = diff --color-words
[core]
editor = vim
[merge]
summary = true
You can edit this file directly or you can use the git config --global command:
git
git
git
git
git
git
git
git
git
git
config
config
config
config
config
config
config
config
config
config
--global
--global
--global
--global
--global
--global
--global
--global
--global
--global
user.name "Your Name"
user.email [email protected]
alias.ci "commit -a"
alias.co checkout
alias.st "status -a"
alias.stat "status -a"
alias.br branch
alias.wdiff "diff --color-words"
core.editor vim
merge.summary true
To set up on another computer, you can copy your ~/.gitconfig file, or run the commands above.
In detail
334
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
user.name and user.email It is good practice to tell git who you are, for labeling any changes you make to the code.
The simplest way to do this is from the command line:
git config --global user.name "Your Name"
git config --global user.email [email protected]
This will write the settings into your git configuration file, which should now contain a user section with your name
and email:
[user]
name = Your Name
email = [email protected]
Of course you’ll need to replace Your Name and [email protected] with your actual name and
email address.
Aliases You might well benefit from some aliases to common commands.
For example, you might well want to be able to shorten git checkout to git co. Or you may want to alias git
diff --color-words (which gives a nicely formatted output of the diff) to git wdiff
The following git config --global commands:
git
git
git
git
git
git
config
config
config
config
config
config
--global
--global
--global
--global
--global
--global
alias.ci "commit -a"
alias.co checkout
alias.st "status -a"
alias.stat "status -a"
alias.br branch
alias.wdiff "diff --color-words"
will create an alias section in your .gitconfig file with contents like this:
[alias]
ci = commit -a
co = checkout
st = status -a
stat = status -a
br = branch
wdiff = diff --color-words
Editor You may also want to make sure that your editor of choice is used
git config --global core.editor vim
Merging To enforce summaries when doing merges (~/.gitconfig file again):
[merge]
log = true
Or from the command line:
git config --global merge.log true
Fancy log output This is a very nice alias to get a fancy log output; it should go in the alias section of your
.gitconfig file:
7.3. How to Contribute
335
SfePy Documentation, Release 2015.1
lg = log --graph --pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%
You use the alias with:
git lg
and it gives graph / text output something like this (but with color!):
* 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Mat
d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks
*
|\
| * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo]
|/
* a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran W
* 68f6752 - Initial implimentation of AxisIndexer - uses ’index_by’ which needs to be changed to a ca
376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst]
*
|\
| * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst]
| * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst]
| * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 wee
| * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst]
| *
956fbab - Merge remote-tracking branch ’upstream/master’ (3 weeks ago) [Jonathan Terhorst]
| |\
| |/
Thanks to Yury V. Zaytsev for posting it.
Development workflow You already have your own forked copy of the SfePy repository, by following Making your
own copy (fork) of SfePy. You have Set up your fork. You have configured git by following Configure git. Now you
are ready for some real work.
Workflow summary In what follows we’ll refer to the upstream SfePy master branch, as “trunk”.
• Don’t use your master branch for anything. Consider deleting it.
• When you are starting a new set of changes, fetch any changes from trunk, and start a new feature branch from
that.
• Make a new branch for each separable set of changes — “one task, one branch” (ipython git workflow).
• Name your branch for the purpose of the changes - e.g.
refactor-database-code.
bugfix-for-issue-14 or
• If you can possibly avoid it, avoid merging trunk or any other branches into your feature branch while you are
working.
• If you do find yourself merging from trunk, consider Rebasing on trunk
• Ask on the SfePy mailing list if you get stuck.
• Ask for code review!
This way of working helps to keep work well organized, with readable history. This in turn makes it easier for project
maintainers (that might be you) to see what you’ve done, and why you did it.
See linux git workflow and ipython git workflow for some explanation.
Consider deleting your master branch It may sound strange, but deleting your own master branch can help
reduce confusion about which branch you are on. See deleting master on github for details.
336
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Update the mirror of trunk First make sure you have done Linking your repository to the upstream repo.
From time to time you should fetch the upstream (trunk) changes from github:
git fetch upstream
This will pull down any commits you don’t have, and set the remote branches to point to the right commit. For
example, ‘trunk’ is the branch referred to by (remote/branchname) upstream/master - and if there have been
commits since you last checked, upstream/master will change after you do the fetch.
Make a new feature branch When you are ready to make some changes to the code, you should start a new branch.
Branches that are for a collection of related edits are often called ‘feature branches’.
Making an new branch for each set of related changes will make it easier for someone reviewing your branch to see
what you are doing.
Choose an informative name for the branch to remind yourself and the rest of us what the changes in the branch are
for. For example add-ability-to-fly, or buxfix-for-issue-42.
# Update the mirror of trunk
git fetch upstream
# Make new feature branch starting at current trunk
git branch my-new-feature upstream/master
git checkout my-new-feature
Generally, you will want to keep your feature branches on your public github fork of SfePy. To do this, you git push
this new branch up to your github repo. Generally (if you followed the instructions in these pages, and by default), git
will have a link to your github repo, called origin. You push up to your own repo on github with:
git push origin my-new-feature
In git >= 1.7 you can ensure that the link is correctly set by using the --set-upstream option:
git push --set-upstream origin my-new-feature
From now on git will know that my-new-feature is related to the my-new-feature branch in the github repo.
The editing workflow
Overview
# hack hack
git add my_new_file
git commit -am ’NF - some message’
git push
In more detail
1. Make some changes
2. See which files have changed with git status (see git status). You’ll see a listing like this one:
# On branch ny-new-feature
# Changed but not updated:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:
README
7.3. How to Contribute
337
SfePy Documentation, Release 2015.1
#
# Untracked files:
#
(use "git add <file>..." to include in what will be committed)
#
# INSTALL
no changes added to commit (use "git add" and/or "git commit -a")
3. Check what the actual changes are with git diff (git diff).
4. Add any new files to version control git add new_file_name (see git add).
5. To commit all modified files into the local copy of your repo„ do git commit -am ’A commit
message’. Note the -am options to commit. The m flag just signals that you’re going to type a message
on the command line. The a flag — you can just take on faith — or see why the -a flag? — and the helpful
use-case description in the tangled working copy problem. The git commit manual page might also be useful.
6. To push the changes up to your forked repo on github, do a git push (see git push).
Ask for your changes to be reviewed or merged When you are ready to ask for someone to review your code and
consider a merge:
1. Go to the URL of your forked repo, say http://github.com/your-user-name/sfepy.
2. Use the ‘Switch Branches’ dropdown menu near the top left of the page to select the branch with your changes:
3. Click on the ‘Pull request’ button:
Enter a title for the set of changes, and some explanation of what you’ve done. Say if there is anything you’d
like particular attention for - like a complicated change or some code you are not happy with.
If you don’t think your request is ready to be merged, just say so in your pull request message. This is still a
good way of getting some preliminary code review.
Some other things you might want to do
338
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Delete a branch on github
git checkout master
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
git push origin :my-unwanted-branch
(Note the colon : before test-branch. See also: http://github.com/guides/remove-a-remote-branch
Several people sharing a single repository If you want to work on some stuff with other people, where you are all
committing into the same repository, or even the same branch, then just share it via github.
First fork SfePy into your account, as from Making your own copy (fork) of SfePy.
Then, go to your forked repository github page, say http://github.com/your-user-name/sfepy
Click on the ‘Admin’ button, and add anyone else to the repo as a collaborator:
Now all those people can do:
git clone [email protected]:your-user-name/sfepy.git
Remember that links starting with [email protected] use the ssh protocol and are read-write; links starting with git:// are
read-only.
Your collaborators can then commit directly into that repo with the usual:
git commit -am ’ENH - much better code’
git push origin master # pushes directly into your repo
Explore your repository To see a graphical representation of the repository branches and commits:
gitk --all
To see a linear list of commits for this branch:
git log
You can also look at the network graph visualizer for your github repo.
Finally the Fancy log output lg alias will give you a reasonable text-based graph of the repository.
Rebasing on trunk Let’s say you thought of some work you’d like to do. You Update the mirror of trunk and Make
a new feature branch called cool-feature. At this stage trunk is at some commit, let’s call it E. Now you make
some new commits on your cool-feature branch, let’s call them A, B, C. Maybe your changes take a while, or
you come back to them after a while. In the meantime, trunk has progressed from commit E to commit (say) G:
7.3. How to Contribute
339
SfePy Documentation, Release 2015.1
A---B---C cool-feature
/
D---E---F---G trunk
At this stage you consider merging trunk into your feature branch, and you remember that this here page sternly
advises you not to do that, because the history will get messy. Most of the time you can just ask for a review, and not
worry that trunk has got a little ahead. But sometimes, the changes in trunk might affect your changes, and you need
to harmonize them. In this situation you may prefer to do a rebase.
rebase takes your changes (A, B, C) and replays them as if they had been made to the current state of trunk. In other
words, in this case, it takes the changes represented by A, B, C and replays them on top of G. After the rebase, your
history will look like this:
A’--B’--C’ cool-feature
/
D---E---F---G trunk
See rebase without tears for more detail.
To do a rebase on trunk:
# Update the mirror of trunk
git fetch upstream
# go to the feature branch
git checkout cool-feature
# make a backup in case you mess up
git branch tmp cool-feature
# rebase cool-feature onto trunk
git rebase --onto upstream/master upstream/master cool-feature
In this situation, where you are already on branch cool-feature, the last command can be written more succinctly
as:
git rebase upstream/master
When all looks good you can delete your backup branch:
git branch -D tmp
If it doesn’t look good you may need to have a look at Recovering from mess-ups.
If you have made changes to files that have also changed in trunk, this may generate merge conflicts that you need
to resolve - see the git rebase man page for some instructions at the end of the “Description” section. There is some
related help on merging in the git user manual - see resolving a merge.
Recovering from mess-ups Sometimes, you mess up merges or rebases. Luckily, in git it is relatively straightforward to recover from such mistakes.
If you mess up during a rebase:
git rebase --abort
If you notice you messed up after the rebase:
# reset branch back to the saved point
git reset --hard tmp
If you forgot to make a backup branch:
340
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
# look at the reflog of the branch
git reflog show cool-feature
8630830 [email protected]{0}: commit: BUG: io: close file handles immediately
278dd2a [email protected]{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a [email protected]{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...
# reset the branch to where it was before the botched rebase
git reset --hard [email protected]{2}
Rewriting commit history
Note: Do this only for your own feature branches.
There’s an embarassing typo in a commit you made? Or perhaps the you made several false starts you would like the
posterity not to see.
This can be done via interactive rebasing.
Suppose that the commit history looks like this:
git log
eadc391
a815645
2dec1ac
13d7934
6ad92e5
29001ed
...
--oneline
Fix some remaining bugs
Modify it so that it works
Fix a few bugs + disable
First implementation
* masked is now an instance of a new object, MaskedConstant
Add pre-nep for a copule of structured_array_extensions.
and 6ad92e5 is the last commit in the cool-feature branch. Suppose we want to make the following changes:
• Rewrite the commit message for 13d7934 to something more sensible.
• Combine the commits 2dec1ac, a815645, eadc391 into a single one.
We do as follows:
# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5
This will open an editor with the following text in it:
pick
pick
pick
pick
13d7934
2dec1ac
a815645
eadc391
First implementation
Fix a few bugs + disable
Modify it so that it works
Fix some remaining bugs
# Rebase 6ad92e5..eadc391 onto 6ad92e5
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit’s log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
7.3. How to Contribute
341
SfePy Documentation, Release 2015.1
# However, if you remove everything, the rebase will be aborted.
#
To achieve what we want, we will make the following changes to it:
r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs
This means that (i) we want to edit the commit message for 13d7934, and (ii) collapse the last three commits into
one. Now we save and quit the editor.
Git will then immediately bring up an editor for editing the commit message. After revising it, we get the output:
[detached HEAD 721fc64] FOO: First implementation
2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.
and the history looks now like this:
0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant
If it went wrong, recovery is again possible as explained above.
Maintainer workflow This page is for maintainers — those of us who merge our own or other peoples’ changes
into the upstream repository.
Being as how you’re a maintainer, you are completely on top of the basic stuff in Development workflow.
The instructions in Linking your repository to the upstream repo add a remote that has read-only access to the upstream
repo. Being a maintainer, you’ve got read-write access.
It’s good to have your upstream remote have a scary name, to remind you that it’s a read-write remote:
git remote add upstream-rw [email protected]:sfepy/sfepy.git
git fetch upstream-rw
Integrating changes Let’s say you have some changes that need to go into trunk (upstream-rw/master).
The changes are in some branch that you are currently on. For example, you are looking at someone’s changes like
this:
git
git
git
git
remote add someone git://github.com/someone/sfepy.git
fetch someone
branch cool-feature --track someone/cool-feature
checkout cool-feature
So now you are on the branch with the changes to be incorporated upstream. The rest of this section assumes you are
on this branch.
A few commits If there are only a few commits, consider rebasing to upstream:
342
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
# Fetch upstream changes
git fetch upstream-rw
# rebase
git rebase upstream-rw/master
Remember that, if you do a rebase, and push that, you’ll have to close any github pull requests manually, because
github will not be able to detect the changes have already been merged.
A long series of commits If there are a longer series of related commits, consider a merge instead:
git fetch upstream-rw
git merge --no-ff upstream-rw/master
The merge will be detected by github, and should close any related pull requests automatically.
Note the --no-ff above. This forces git to make a merge commit, rather than doing a fast-forward, so that these
set of commits branch off trunk then rejoin the main history with a merge, rather than appearing to have been made
directly on top of trunk.
Check the history Now, in either case, you should check that the history is sensible and you have the right commits:
git log --oneline --graph
git log -p upstream-rw/master..
The first line above just shows the history in a compact way, with a text representation of the history graph. The
second line shows the log of commits excluding those that can be reached from trunk (upstream-rw/master),
and including those that can be reached from current HEAD (implied with the .. at the end). So, it shows the commits
unique to this branch compared to trunk. The -p option shows the diff for these commits in patch form.
Push to trunk
git push upstream-rw my-new-feature:master
This pushes the my-new-feature branch in this repository to the master branch in the upstream-rw repository.
git resources
Tutorials and summaries
• github help has an excellent series of how-to guides.
• learn.github has an excellent series of tutorials
• The pro git book is a good in-depth book on git.
• A git cheat sheet is a page giving summaries of common commands.
• The git user manual
• The git tutorial
• The git community book
• git ready — a nice series of tutorials
• git casts — video snippets giving git how-tos.
• git magic — extended introduction with intermediate detail
7.3. How to Contribute
343
SfePy Documentation, Release 2015.1
• The git parable is an easy read explaining the concepts behind git.
• git foundation expands on the git parable.
• Fernando Perez’ git page — Fernando’s git page — many links and tips
• A good but technical page on git concepts
• git svn crash course: git for those of us used to subversion
Advanced git workflow There are many ways of working with git; here are some posts on the rules of thumb that
other projects have come up with:
• Linus Torvalds on git management
• Linus Torvalds on linux git workflow . Summary; use the git tools to make the history of your edits as clean as
possible; merge from upstream edits as little as possible in branches where you are doing active development.
Manual pages online You can get these on your own machine with (e.g) git help push or (same thing) git
push --help, but, for convenience, here are the online manual pages for some common commands:
• git add
• git branch
• git checkout
• git clone
• git commit
• git config
• git diff
• git log
• git pull
• git push
• git remote
• git status
Note: This section will get quickly get you started using git and github. For more in-depth reading about how these
tools work with the SfePy source code and the general git development, read Working with SfePy source code, which
was adapted from Matthew Brett’s excellent gitwash git tutorial.
With git there are some additional options for how to send changes to SfePy. Before listing them, let us describe a
typical development session and the related git commands:
1. Either clone a fresh copy by:
git clone git://github.com/sfepy/sfepy.git
or update your local repository:
1
2
# look for changes at origin
git fetch origin
3
4
5
# difference between local and origin master branch
git diff master origin/master
6
344
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
7
8
# apply the changes to local master branch
git pull origin master
2. Introduce yourself to git and make (optionally) some handy aliases either in .gitconfig in your home directory (global setting for all your git projects), or directly in .git/config in the repository:
1
2
3
[user]
email = [email protected]
name = Name Surname
4
5
6
7
[color]
ui = auto
interactive = true
8
9
10
11
12
13
[alias]
ci =
di =
st =
co =
commit
diff --color-words
status
checkout
3. Change some file(s), and review the changes:
1
2
# text diff
git diff
3
4
5
# use GUI to visualize of project history (all branches)
gitk --all
4. Create one or more commits:
1
2
3
4
# schedule some of the changed files for the next commit
git add file1 file2 ...
# an editor will pop up where you should describe the commit
git commit
5. The commit(s) now reflect changes, but only in your local git repository. Then you must somehow allow others
to see them. This can be done, for example, by sending a patch (or through the other option below). So create
the patch(es):
# create patches for, e.g., the last two commits
git format-patch HEAD~2
6. Send the patch(es) to the SfePy mailing list or attach them to the corresponding issue at the Issues web page.
7. If the patches are fine, they will appear in the master repository. Then synchronize your repository with the
master:
• either clone a fresh copy
• or use the fetch, pull, merge or rebase commands. This may require a deeper git-fu in case of conflicts.
For beginners, it is advisable to clone always a fresh copy if they see a conflict.
There is another option than submitting patches, however, useful when you wish to get feedback on a larger set of
changes. This option is to publish your repository using Github and let the other developers know about it - follow the
instructions in Git for development of Working with SfePy source code.
Notes on commits and patches
• Follow our Coding style.
7.3. How to Contribute
345
SfePy Documentation, Release 2015.1
• Do not use lines longer than 79 characters (exception: tables of values, e.g., quadratures).
• Write descriptive docstrings in correct style, see Docstring standard.
• There should be one patch for one topic - do not mix unrelated things in one patch. For example, when you add
a new function, then notice a typo in docstring in a nearby function and correct it, create two patches: one fixing
the docstring, the other adding the new function.
• The commit message and description should clearly state what the patch does. Try to follow the style of other
commit messages. Some interesting notes can be found at tbaggery.com, namely that the commit message is
better to be written in the present tense: “fix bug” and not “fixed bug”.
Docstring standard
We use sphinx with the numpydoc extension to generate this documentation. Refer to the sphinx site for the possible
markup constructs.
Basically (with a little tweak), we try to follow the NumPy/SciPy docstring standard as described in NumPy documentation guide. See also the complete docstring example. It is exaggerated a bit to show all the possibilities. Use your
common sense here - the docstring should be sufficient for a new user to use the documented object. A good way to
remember the format is to type:
In [1]: import numpy as nm
In [2]: nm.sin?
in ipython. The little tweak mentioned above is the starting newline:
1
2
3
def function(arg1, arg2):
"""
This is a function.
4
Parameters
---------arg1 : array
The coordinates of ...
arg2 : int
The dimension ...
5
6
7
8
9
10
11
Returns
------out : array
The resulting array of shape ....
"""
12
13
14
15
16
It seems visually better than:
1
2
def function(arg1, arg2):
"""This is a function.
3
Parameters
---------arg1 : array
The coordinates of ...
arg2 : int
The dimension ...
4
5
6
7
8
9
10
Returns
------out : array
11
12
13
346
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The resulting array of shape ....
14
15
"""
When using LATEX in a docstring, use a raw string:
1
2
3
4
5
def function():
r"""
This is a function with :math:‘\mbox{\LaTeX}‘ math:
:math:‘\frac{1}{\pi}‘.
"""
to prevent Python from interpreting and consuming the backslashes in common escape sequences like ‘\n’, ‘\f’ etc.
7.4 How to Regenerate Documentation
The following steps summarize how to regenerate this documentation.
1. Install sphinx and numpydoc. Do not forget to set the path to numpydoc in site_cfg.py if it is not installed
in a standard location for Python packages on your platform. A recent LATEX distribution is required, too, for
example TeX Live. Depending on your OS/platform, it can be in the form of one or several packages.
2. Edit the rst files in doc/ directory using your favorite text editor - the ReST format is really simple, so nothing
fancy is needed. Follow the existing files in doc/ ; for reference also check reStructuredText Primer, Sphinx
Markup Constructs and docutils reStructuredText.
• When adding a new Python module, add a corresponding documentation file into doc/src/sfepy/<path>,
where <path> should reflect the location of the module in sfepy/.
• Figures belong to doc/images; subdirectories can be used.
3. (Re)generate the documentation (assuming GNU make is installed):
cd doc
make html
4. View it (substitute your favorite browser):
firefox _build/html/index.html
7.5 How to Implement a New Term
tentative documentation
Warning Implementing a new term usually involves C. As Cython is now supported by our build system, it should not
be that difficult. Python-only terms are possible as well.
7.5.1 Notes on terminology
Volume refers to the whole domain (in space of dimension 𝑑), while surface to a subdomain of dimension 𝑑 − 1, for
example a part of the domain boundary. So in 3D problems volume = volume, surface = surface, while in 2D volume
= area, surface = curve.
7.4. How to Regenerate Documentation
347
SfePy Documentation, Release 2015.1
7.5.2 Introduction
A term in SfePy usually corresponds to a single integral term in (weak) integral formulation of an equation. Both
volume and surface integrals are supported. There are three types of arguments a term can have:
• variables, i.e. the unknown, test or parameter variables declared by the variables keyword, see Problem Description File,
• materials, corresponding to material and other parameters (functions) that are known, declared by the materials
keyword,
• user data - anything, but user is responsible for passing them to the evaluation functions.
Terms come in two flavors:
• standard terms are subclasses of sfepy.terms.terms.Term
• new terms are subclasses of sfepy.terms.terms_new.NewTerm
As new terms are now not much more than a highly experimental proof of concept, we will focus on the standard
terms here.
The purpose of a standard term class is to implement a (vectorized) function that assembles the term contribution
to residual/matrix and/or evaluates the term integral in a group of elements simultaneously. Most such functions are
currently implemented in C, but some terms are pure Python, vectorized using NumPy. A term with a C function needs
to be able to extract the real data from its arguments and then pass those data to the C function.
7.5.3 Evaluation modes
A term can support several evaluation modes, as described in Term Evaluation.
7.5.4 Basic attributes
A term class should inherit from sfepy.terms.terms.Term base class. The simplest possible term with volume
integration and ‘weak’ evaluation mode needs to have the following attributes and methods:
• docstring (not really required per se, but we require it);
• name attribute - the name to be used in equations;
• arg_types attribute - the types of arguments the term accepts;
• integration attribute, optional - the kind of integral the term implements, one of ‘volume’ (the default, if not
given), ‘surface’ or ‘surface_extra’;
• function() static method - the assembling function;
• get_fargs() method - the method that takes term arguments and converts them to arguments for function().
Argument types
The argument types can be (“[_*]” denotes an optional suffix):
• ‘material[_*]’ for a material parameter, i.e. any function that can be can evaluated in quadrature points and that
is not a variable;
• ‘opt_material[_*]’ for an optional material parameter, that can be left out - there can be only one in a term and
it must be the first argument;
• ‘virtual’ for a virtual (test) variable (no value defined), ‘weak’ evaluation mode;
348
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
• ‘state[_*]’ for state (unknown) variables (have value), ‘weak’ evaluation mode;
• ‘parameter[_*]’ for parameter variables (have known value), any evaluation mode.
Only one ‘virtual’ variable is allowed in a term.
Integration kinds
The integration kinds have the following meaning:
• ‘volume’ for volume integral over a region that contains elements; uses volume element connectivity for assembling;
• ‘surface’ for surface integral over a region that contains faces; uses surface face connectivity for assembling;
• ‘surface_extra’ for surface integral over a region that contains faces; uses volume element connectivity for
assembling - this is needed if full gradients of a variable are required on the boundary.
function()
The function() static method has always the following arguments:
out, *args
where out is the already preallocated output array (change it in place!) and *args are any other arguments the function
requires. These function arguments have to be provided by the get_fargs() method. The function returns zero status
on success, nonzero on failure.
The out array has shape (n_el, 1, n_row, n_col), where n_el is the number of elements in a group and n_row, n_col are
matrix dimensions of the value on a single element.
get_fargs()
The get_fargs() method has always the same structure of arguments:
• positional arguments corresponding to arg_types attribute:
– example for a typical weak term:
* for:
arg_types = (’material’, ’virtual’, ’state’)
the positional arguments are:
material, virtual, state
• keyword arguments common to all terms:
mode=None, term_mode=None, diff_var=None, **kwargs
here:
– mode is the actual evaluation mode, default is ‘eval’;
– term_mode is an optional term sub-mode influencing what the term should return (example:
dw_tl_he_neohook term has ‘strain’ and ‘stress’ evaluation sub-modes);
7.5. How to Implement a New Term
349
SfePy Documentation, Release 2015.1
– diff_var is taken into account in the ‘weak’ evaluation mode. It is either None (residual mode) or a name
of variable with respect to differentiate to (matrix mode);
– **kwargs are any other arguments that the term supports.
The get_fargs() method returns arguments for function().
7.5.5 Additional attributes
These attributes are used mostly in connection with the tests/test_term_call_modes.py test for automatic testing of
term calls.
• arg_shapes attribute - the possible shapes of term arguments;
• geometries attribute - the list of reference element geometries that the term supports;
• mode attribute - the default evaluation mode.
Argument shapes
The argument shapes are specified using a dict of the following form:
arg_shapes = {’material’ : ’D, D’, ’virtual’ : (1, ’state’),
’state’ : 1, ’parameter_1’ : 1, ’parameter_2’ : 1}
The keys are the argument types listed in the arg_types attribute, for example:
arg_types = ((’material’, ’virtual’, ’state’),
(’material’, ’parameter_1’, ’parameter_2’))
The values are the shapes containing either integers, or ‘D’ (for space dimension) or ‘S’ (symmetric storage size
corresponding to the space dimension). For materials, the shape is a string ‘nr, nc’ or a single value, denoting a
special-valued term, or None denoting an optional material that is left out. For state and parameter variables, the shape
is a single value. For virtual variables, the shape is a tuple of a single shape value and a name of the corresponding
state variable; the name can be None.
When several alternatives are possible, a list of dicts can be used. For convenience, only the shapes of arguments that
change w.r.t. a previous dict need to be included, as the values of the other shapes are taken from the previous dict.
For example, the following corresponds to a case, where an optional material has either the shape (1, 1) in each point,
or is left out:
1
2
3
arg_types = (’opt_material’, ’parameter’)
arg_shapes = [{’opt_material’ : ’1, 1’, ’parameter’ : 1},
{’opt_material’ : None}]
Geometries
The default that most terms use is a list of all the geometries:
geometries = [’2_3’, ’2_4’, ’3_4’, ’3_8’]
In that case, the attribute needs not to be define explicitly.
350
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
7.5.6 Example
Let us now discuss the implementation of a simple weak term dw_volume_integrate defined as
weight (material parameter) and 𝑞 is a virtual variable. This term is implemented as follows:
1
2
3
4
∫︀
Ω
𝑐𝑞, where 𝑐 is a
class IntegrateVolumeOperatorTerm(Term):
r"""
Volume integral of a test function weighted by a scalar function
:math:‘c‘.
5
6
:Definition:
7
8
9
.. math::
\int_\Omega q \mbox{ or } \int_\Omega c q
10
11
12
13
14
15
16
17
18
:Arguments:
- material : :math:‘c‘ (optional)
- virtual : :math:‘q‘
"""
name = ’dw_volume_integrate’
arg_types = (’opt_material’, ’virtual’)
arg_shapes = [{’opt_material’ : ’1, 1’, ’virtual’ : (1, None)},
{’opt_material’ : None}]
19
20
21
22
23
24
25
26
27
28
@staticmethod
def function(out, material, bf, geo):
bf_t = nm.tile(bf.transpose((0, 1, 3, 2)), (out.shape[0], 1, 1, 1))
bf_t = nm.ascontiguousarray(bf_t)
if material is not None:
status = geo.integrate(out, material * bf_t)
else:
status = geo.integrate(out, bf_t)
return status
29
30
31
32
33
def get_fargs(self, material, virtual,
mode=None, term_mode=None, diff_var=None, **kwargs):
assert_(virtual.n_components == 1)
geo, _ = self.get_mapping(virtual)
34
35
return material, geo.bf, geo
• lines 2-14: the docstring - always write one!
• line 15: the name of the term, that can be referred to in equations;
• line 16: the argument types - here the term takes a single material parameter, and a virtual variable;
• lines 17-18: the possible argument shapes
• lines 20-28: the term function
– its arguments are:
* the output array out, already having the required shape,
* the material coefficient (array) mat evaluated in physical quadrature points of all elements of an element group,
* a base function (array) bf evaluated in the quadrature points of a reference element and
* a reference element (geometry) mapping geo.
7.5. How to Implement a New Term
351
SfePy Documentation, Release 2015.1
– line 22: transpose the base function and tile it so that is has the correct shape - it is repeated for each
element;
– line 23: ensure C contiguous order;
– lines 24-27: perform numerical integration in C - geo.integrate() requires the C contiguous order;
– line 28: return the status.
• lines 30-35: prepare arguments for the function above:
– line 32: verify that the variable is scalar, as our implementation does not support vectors;
– line 33: get reference element mapping corresponding to the virtual variable;
– line 35: return the arguments for the function.
7.5.7 Concluding remarks
This is just a very basic introduction to the topic of new term implementation. Do not hesitate to ask the SfePy mailing
list, and look at the source code of the already implemented terms.
7.6 How To Make a Release
7.6.1 Release Tasks
A few notes on what to do during a release.
Things to check before a release
1. synchronize module documentation (dry run):
$ ./script/sync_module_docs.py doc/src/ . -n
2. regenerate gallery page and examples:
$ script/gen_gallery.py -l ../doc-devel
$ rm -rf doc/examples/
$ cp -a gallery/examples/ doc/
3. create temporary/testing tarball:
$ python setup.py sdist
4. check in-place build:
$ # unpack the tarball
$ # cd into
$ python setup.py build_ext --inplace
$ ./test_install.py
5. check that documentation can be built:
$ # copy site_cfg.py
$ python setup.py htmldocs
$ firefox doc/_build/html/index.html
352
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
or use:
$ cd doc/
$ make html
$ firefox _build/html/index.html
try also:
$ # copy gallery/images
$ python setup.py pdfdocs
6. check installed build:
$
$
$
$
python setup.py install --root=<some path>
cd
run_tests.py
rm -r output/
then remove the installed files so that they do not interfere with the local build
7. create final tarball
• update doc/release_notes.rst
• update doc/news.rst, doc/archived_news.rst
• change version number (sfepy/version.py) so that previous release tarball is not overwritten!
• set is_release = True in site_cfg.py
• update pdfdocs:
$ python setup.py pdfdocs
• create tarball:
$ python setup.py sdist
Useful Git commands
• log
git log --pretty=format:"%s%n%b%n" release_2009.1..HEAD
• who has contributed since <date>:
git log --after=<date> | grep Author | sort | uniq
git log release_2012.1..HEAD | grep Author | sort -k3 | uniq
git shortlog -s -n release_2012.3..HEAD
git rev-list --committer="Name Surname" --since=6.months.ago HEAD | wc
git rev-list --author="Name Surname" --since=6.months.ago HEAD | wc
# ?no-merges
• misc:
git archive --format=tar HEAD | gzip > name.tar.gz
7.6. How To Make a Release
353
SfePy Documentation, Release 2015.1
Web update and file uploading
• upload the tarball to http://sfepy.org/doc-devel/downloads.html
• publish development docs also as new release docs
• send announcement to
– [email protected],
[email protected]
[email protected],
[email protected],
python-announce-
7.7 Working with SfePy source code
This section was adapted from Matthew Brett’s excellent gitwash git tutorial. It complements the above sections and
details several aspects of working with Git and Github.
It can be updated by running:
$ curl -O https://raw.github.com/matthew-brett/gitwash/master/gitwash_dumper.py
$ python gitwash_dumper.py doc/dev SfePy --repo-name=sfepy --github-user=sfepy --project-url=http://s
in the SfePy source directory. Do not forget to delete the section title in doc/dev/gitwash/index.rst, as it is already here.
Contents:
7.7.1 Introduction
These pages describe a git and github workflow for the SfePy project.
There are several different workflows here, for different ways of working with SfePy.
This is not a comprehensive git reference, it’s just a workflow for our own project. It’s tailored to the github hosting
service. You may well find better or quicker ways of getting stuff done with git, but these should get you started.
For general resources for learning git, see git resources.
7.7.2 Install git
Overview
Debian / Ubuntu
Fedora
Windows
OS X
sudo apt-get install git-core
sudo yum install git-core
Download and install msysGit
Use the git-osx-installer
In detail
See the git page for the most recent information.
Have a look at the github install help pages available from github help
There are good instructions here: http://book.git-scm.com/2_installing_git.html
354
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
7.7.3 Following the latest source
These are the instructions if you just want to follow the latest SfePy source, but you don’t need to do any development
for now.
The steps are:
• Install git
• get local copy of the SfePy github git repository
• update local copy from time to time
Get the local copy of the code
From the command line:
git clone git://github.com/sfepy/sfepy.git
You now have a copy of the code tree in the new sfepy directory.
Updating the code
From time to time you may want to pull down the latest code. Do this with:
cd sfepy
git pull
The tree in sfepy will now have the latest changes from the initial repository.
7.7.4 Making a patch
You’ve discovered a bug or something else you want to change in SfePy .. — excellent!
You’ve worked out a way to fix it — even better!
You want to tell us about it — best of all!
The easiest way is to make a patch or set of patches. Here we explain how. Making a patch is the simplest and
quickest, but if you’re going to be doing anything more than simple quick things, please consider following the Git for
development model instead.
Making patches
Overview
# tell git who you are
git config --global user.email [email protected]
git config --global user.name "Your Name Comes Here"
# get the repository if you don’t have it
git clone git://github.com/sfepy/sfepy.git
# make a branch for your patching
cd sfepy
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
# hack, hack, hack
7.7. Working with SfePy source code
355
SfePy Documentation, Release 2015.1
# Tell git about any new files you’ve made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am ’BF - added tests for Funny bug’
# hack hack, hack
git commit -am ’BF - added fix for Funny bug’
# make the patch files
git format-patch -M -C master
Then, send the generated patch files to the SfePy mailing list — where we will thank you warmly.
In detail
1. Tell git who you are so it can label the commits you’ve made:
git config --global user.email [email protected]
git config --global user.name "Your Name Comes Here"
2. If you don’t already have one, clone a copy of the SfePy repository:
git clone git://github.com/sfepy/sfepy.git
cd sfepy
3. Make a ‘feature branch’. This will be where you work on your bug fix. It’s nice and safe and leaves you with
access to an unmodified copy of the code in the main branch:
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
4. Do some edits, and commit them as you go:
# hack, hack, hack
# Tell git about any new files you’ve made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am ’BF - added tests for Funny bug’
# hack hack, hack
git commit -am ’BF - added fix for Funny bug’
Note the -am options to commit. The m flag just signals that you’re going to type a message on the command
line. The a flag — you can just take on faith — or see why the -a flag?.
5. When you have finished, check you have committed all your changes:
git status
6. Finally, make your commits into patches. You want all the commits since you branched from the master
branch:
git format-patch -M -C master
You will now have several files named for the commits:
0001-BF-added-tests-for-Funny-bug.patch
0002-BF-added-fix-for-Funny-bug.patch
Send these files to the SfePy mailing list.
When you are done, to switch back to the main copy of the code, just return to the master branch:
356
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
git checkout master
Moving from patching to development
If you find you have done some patches, and you have one or more feature branches, you will probably want to switch
to development mode. You can do this with the repository you have.
Fork the SfePy repository on github — Making your own copy (fork) of SfePy. Then:
# checkout and refresh master branch from main repo
git checkout master
git pull origin master
# rename pointer to main repository to ’upstream’
git remote rename origin upstream
# point your repo to default read / write to your fork on github
git remote add origin [email protected]:your-user-name/sfepy.git
# push up any branches you’ve made and want to keep
git push origin the-fix-im-thinking-of
Then you can, if you want, follow the Development workflow.
7.7.5 Git for development
Contents:
Making your own copy (fork) of SfePy
You need to do this only once.
The instructions here are very similar to the instructions at
http://help.github.com/forking/ — please see that page for more detail. We’re repeating some of it here just to give the
specifics for the SfePy project, and to suggest some default names.
Set up and configure a github account
If you don’t have a github account, go to the github page, and make one.
You then need to configure your account to allow write access — see the Generating SSH keys help on github
help.
Create your own forked copy of SfePy
1. Log into your github account.
2. Go to the SfePy github home at SfePy github.
3. Click on the fork button:
7.7. Working with SfePy source code
357
SfePy Documentation, Release 2015.1
Now, after a short pause and some ‘Hardcore forking action’, you should find yourself at the home page for your
own forked copy of SfePy.
Set up your fork
First you follow the instructions for Making your own copy (fork) of SfePy.
Overview
git clone [email protected]:your-user-name/sfepy.git
cd sfepy
git remote add upstream git://github.com/sfepy/sfepy.git
In detail
Clone your fork
1. Clone your fork to the local computer with git clone [email protected]:your-user-name/sfepy.git
2. Investigate. Change directory to your new repo: cd sfepy. Then git branch -a to show you all
branches. You’ll get something like:
* master
remotes/origin/master
This tells you that you are currently on the master branch, and that you also have a remote connection to
origin/master. What remote repository is remote/origin? Try git remote -v to see the URLs
for the remote. They will point to your github fork.
Now you want to connect to the upstream SfePy github repository, so you can merge in changes from trunk.
Linking your repository to the upstream repo
cd sfepy
git remote add upstream git://github.com/sfepy/sfepy.git
upstream here is just the arbitrary name we’re using to refer to the main SfePy repository at SfePy github.
Note that we’ve used git:// for the URL rather than [email protected] The git:// URL is read only. This means we that we
can’t accidentally (or deliberately) write to the upstream repo, and we are only going to use it to merge into our own
code.
Just for your own satisfaction, show yourself that you now have a new ‘remote’, with git remote -v show,
giving you something like:
upstream
upstream
origin
origin
git://github.com/sfepy/sfepy.git (fetch)
git://github.com/sfepy/sfepy.git (push)
[email protected]:your-user-name/sfepy.git (fetch)
[email protected]:your-user-name/sfepy.git (push)
Configure git
Overview
Your personal git configurations are saved in the .gitconfig file in your home directory.
358
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Here is an example .gitconfig file:
[user]
name = Your Name
email = [email protected]
[alias]
ci = commit -a
co = checkout
st = status
stat = status
br = branch
wdiff = diff --color-words
[core]
editor = vim
[merge]
summary = true
You can edit this file directly or you can use the git config --global command:
git
git
git
git
git
git
git
git
git
git
config
config
config
config
config
config
config
config
config
config
--global
--global
--global
--global
--global
--global
--global
--global
--global
--global
user.name "Your Name"
user.email [email protected]
alias.ci "commit -a"
alias.co checkout
alias.st "status -a"
alias.stat "status -a"
alias.br branch
alias.wdiff "diff --color-words"
core.editor vim
merge.summary true
To set up on another computer, you can copy your ~/.gitconfig file, or run the commands above.
In detail
user.name and user.email It is good practice to tell git who you are, for labeling any changes you make to the code.
The simplest way to do this is from the command line:
git config --global user.name "Your Name"
git config --global user.email [email protected]
This will write the settings into your git configuration file, which should now contain a user section with your name
and email:
[user]
name = Your Name
email = [email protected]
Of course you’ll need to replace Your Name and [email protected] with your actual name and
email address.
Aliases You might well benefit from some aliases to common commands.
For example, you might well want to be able to shorten git checkout to git co. Or you may want to alias git
diff --color-words (which gives a nicely formatted output of the diff) to git wdiff
7.7. Working with SfePy source code
359
SfePy Documentation, Release 2015.1
The following git config --global commands:
git
git
git
git
git
git
config
config
config
config
config
config
--global
--global
--global
--global
--global
--global
alias.ci "commit -a"
alias.co checkout
alias.st "status -a"
alias.stat "status -a"
alias.br branch
alias.wdiff "diff --color-words"
will create an alias section in your .gitconfig file with contents like this:
[alias]
ci = commit -a
co = checkout
st = status -a
stat = status -a
br = branch
wdiff = diff --color-words
Editor You may also want to make sure that your editor of choice is used
git config --global core.editor vim
Merging To enforce summaries when doing merges (~/.gitconfig file again):
[merge]
log = true
Or from the command line:
git config --global merge.log true
Fancy log output This is a very nice alias to get a fancy log output; it should go in the alias section of your
.gitconfig file:
lg = log --graph --pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%
You use the alias with:
git lg
and it gives graph / text output something like this (but with color!):
* 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Mat
d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks
*
|\
| * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo]
|/
* a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran W
* 68f6752 - Initial implimentation of AxisIndexer - uses ’index_by’ which needs to be changed to a ca
376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst]
*
|\
| * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst]
| * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst]
| * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 wee
| * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst]
| *
956fbab - Merge remote-tracking branch ’upstream/master’ (3 weeks ago) [Jonathan Terhorst]
360
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
| |\
| |/
Thanks to Yury V. Zaytsev for posting it.
Development workflow
You already have your own forked copy of the SfePy repository, by following Making your own copy (fork) of SfePy.
You have Set up your fork. You have configured git by following Configure git. Now you are ready for some real
work.
Workflow summary
In what follows we’ll refer to the upstream SfePy master branch, as “trunk”.
• Don’t use your master branch for anything. Consider deleting it.
• When you are starting a new set of changes, fetch any changes from trunk, and start a new feature branch from
that.
• Make a new branch for each separable set of changes — “one task, one branch” (ipython git workflow).
• Name your branch for the purpose of the changes - e.g.
refactor-database-code.
bugfix-for-issue-14 or
• If you can possibly avoid it, avoid merging trunk or any other branches into your feature branch while you are
working.
• If you do find yourself merging from trunk, consider Rebasing on trunk
• Ask on the SfePy mailing list if you get stuck.
• Ask for code review!
This way of working helps to keep work well organized, with readable history. This in turn makes it easier for project
maintainers (that might be you) to see what you’ve done, and why you did it.
See linux git workflow and ipython git workflow for some explanation.
Consider deleting your master branch
It may sound strange, but deleting your own master branch can help reduce confusion about which branch you are
on. See deleting master on github for details.
Update the mirror of trunk
First make sure you have done Linking your repository to the upstream repo.
From time to time you should fetch the upstream (trunk) changes from github:
git fetch upstream
This will pull down any commits you don’t have, and set the remote branches to point to the right commit. For
example, ‘trunk’ is the branch referred to by (remote/branchname) upstream/master - and if there have been
commits since you last checked, upstream/master will change after you do the fetch.
7.7. Working with SfePy source code
361
SfePy Documentation, Release 2015.1
Make a new feature branch
When you are ready to make some changes to the code, you should start a new branch. Branches that are for a
collection of related edits are often called ‘feature branches’.
Making an new branch for each set of related changes will make it easier for someone reviewing your branch to see
what you are doing.
Choose an informative name for the branch to remind yourself and the rest of us what the changes in the branch are
for. For example add-ability-to-fly, or buxfix-for-issue-42.
# Update the mirror of trunk
git fetch upstream
# Make new feature branch starting at current trunk
git branch my-new-feature upstream/master
git checkout my-new-feature
Generally, you will want to keep your feature branches on your public github fork of SfePy. To do this, you git push
this new branch up to your github repo. Generally (if you followed the instructions in these pages, and by default), git
will have a link to your github repo, called origin. You push up to your own repo on github with:
git push origin my-new-feature
In git >= 1.7 you can ensure that the link is correctly set by using the --set-upstream option:
git push --set-upstream origin my-new-feature
From now on git will know that my-new-feature is related to the my-new-feature branch in the github repo.
The editing workflow
Overview
# hack hack
git add my_new_file
git commit -am ’NF - some message’
git push
In more detail
1. Make some changes
2. See which files have changed with git status (see git status). You’ll see a listing like this one:
# On branch ny-new-feature
# Changed but not updated:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:
README
#
# Untracked files:
#
(use "git add <file>..." to include in what will be committed)
#
# INSTALL
no changes added to commit (use "git add" and/or "git commit -a")
3. Check what the actual changes are with git diff (git diff).
362
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
4. Add any new files to version control git add new_file_name (see git add).
5. To commit all modified files into the local copy of your repo„ do git commit -am ’A commit
message’. Note the -am options to commit. The m flag just signals that you’re going to type a message
on the command line. The a flag — you can just take on faith — or see why the -a flag? — and the helpful
use-case description in the tangled working copy problem. The git commit manual page might also be useful.
6. To push the changes up to your forked repo on github, do a git push (see git push).
Ask for your changes to be reviewed or merged
When you are ready to ask for someone to review your code and consider a merge:
1. Go to the URL of your forked repo, say http://github.com/your-user-name/sfepy.
2. Use the ‘Switch Branches’ dropdown menu near the top left of the page to select the branch with your changes:
3. Click on the ‘Pull request’ button:
Enter a title for the set of changes, and some explanation of what you’ve done. Say if there is anything you’d
like particular attention for - like a complicated change or some code you are not happy with.
If you don’t think your request is ready to be merged, just say so in your pull request message. This is still a
good way of getting some preliminary code review.
Some other things you might want to do
Delete a branch on github
git checkout master
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
git push origin :my-unwanted-branch
(Note the colon : before test-branch. See also: http://github.com/guides/remove-a-remote-branch
7.7. Working with SfePy source code
363
SfePy Documentation, Release 2015.1
Several people sharing a single repository If you want to work on some stuff with other people, where you are all
committing into the same repository, or even the same branch, then just share it via github.
First fork SfePy into your account, as from Making your own copy (fork) of SfePy.
Then, go to your forked repository github page, say http://github.com/your-user-name/sfepy
Click on the ‘Admin’ button, and add anyone else to the repo as a collaborator:
Now all those people can do:
git clone [email protected]:your-user-name/sfepy.git
Remember that links starting with [email protected] use the ssh protocol and are read-write; links starting with git:// are
read-only.
Your collaborators can then commit directly into that repo with the usual:
git commit -am ’ENH - much better code’
git push origin master # pushes directly into your repo
Explore your repository To see a graphical representation of the repository branches and commits:
gitk --all
To see a linear list of commits for this branch:
git log
You can also look at the network graph visualizer for your github repo.
Finally the Fancy log output lg alias will give you a reasonable text-based graph of the repository.
Rebasing on trunk Let’s say you thought of some work you’d like to do. You Update the mirror of trunk and Make
a new feature branch called cool-feature. At this stage trunk is at some commit, let’s call it E. Now you make
some new commits on your cool-feature branch, let’s call them A, B, C. Maybe your changes take a while, or
you come back to them after a while. In the meantime, trunk has progressed from commit E to commit (say) G:
A---B---C cool-feature
/
D---E---F---G trunk
At this stage you consider merging trunk into your feature branch, and you remember that this here page sternly
advises you not to do that, because the history will get messy. Most of the time you can just ask for a review, and not
worry that trunk has got a little ahead. But sometimes, the changes in trunk might affect your changes, and you need
to harmonize them. In this situation you may prefer to do a rebase.
rebase takes your changes (A, B, C) and replays them as if they had been made to the current state of trunk. In other
words, in this case, it takes the changes represented by A, B, C and replays them on top of G. After the rebase, your
history will look like this:
364
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
A’--B’--C’ cool-feature
/
D---E---F---G trunk
See rebase without tears for more detail.
To do a rebase on trunk:
# Update the mirror of trunk
git fetch upstream
# go to the feature branch
git checkout cool-feature
# make a backup in case you mess up
git branch tmp cool-feature
# rebase cool-feature onto trunk
git rebase --onto upstream/master upstream/master cool-feature
In this situation, where you are already on branch cool-feature, the last command can be written more succinctly
as:
git rebase upstream/master
When all looks good you can delete your backup branch:
git branch -D tmp
If it doesn’t look good you may need to have a look at Recovering from mess-ups.
If you have made changes to files that have also changed in trunk, this may generate merge conflicts that you need
to resolve - see the git rebase man page for some instructions at the end of the “Description” section. There is some
related help on merging in the git user manual - see resolving a merge.
Recovering from mess-ups Sometimes, you mess up merges or rebases. Luckily, in git it is relatively straightforward to recover from such mistakes.
If you mess up during a rebase:
git rebase --abort
If you notice you messed up after the rebase:
# reset branch back to the saved point
git reset --hard tmp
If you forgot to make a backup branch:
# look at the reflog of the branch
git reflog show cool-feature
8630830 [email protected]{0}: commit: BUG: io: close file handles immediately
278dd2a [email protected]{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a [email protected]{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...
# reset the branch to where it was before the botched rebase
git reset --hard [email protected]{2}
Rewriting commit history
Note: Do this only for your own feature branches.
7.7. Working with SfePy source code
365
SfePy Documentation, Release 2015.1
There’s an embarassing typo in a commit you made? Or perhaps the you made several false starts you would like the
posterity not to see.
This can be done via interactive rebasing.
Suppose that the commit history looks like this:
git log
eadc391
a815645
2dec1ac
13d7934
6ad92e5
29001ed
...
--oneline
Fix some remaining bugs
Modify it so that it works
Fix a few bugs + disable
First implementation
* masked is now an instance of a new object, MaskedConstant
Add pre-nep for a copule of structured_array_extensions.
and 6ad92e5 is the last commit in the cool-feature branch. Suppose we want to make the following changes:
• Rewrite the commit message for 13d7934 to something more sensible.
• Combine the commits 2dec1ac, a815645, eadc391 into a single one.
We do as follows:
# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5
This will open an editor with the following text in it:
pick
pick
pick
pick
#
#
#
#
#
#
#
#
#
#
#
#
13d7934
2dec1ac
a815645
eadc391
First implementation
Fix a few bugs + disable
Modify it so that it works
Fix some remaining bugs
Rebase 6ad92e5..eadc391 onto 6ad92e5
Commands:
p, pick = use commit
r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit’s log message
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
To achieve what we want, we will make the following changes to it:
r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs
This means that (i) we want to edit the commit message for 13d7934, and (ii) collapse the last three commits into
one. Now we save and quit the editor.
Git will then immediately bring up an editor for editing the commit message. After revising it, we get the output:
366
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
[detached HEAD 721fc64] FOO: First implementation
2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.
and the history looks now like this:
0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant
If it went wrong, recovery is again possible as explained above.
Maintainer workflow
This page is for maintainers — those of us who merge our own or other peoples’ changes into the upstream repository.
Being as how you’re a maintainer, you are completely on top of the basic stuff in Development workflow.
The instructions in Linking your repository to the upstream repo add a remote that has read-only access to the upstream
repo. Being a maintainer, you’ve got read-write access.
It’s good to have your upstream remote have a scary name, to remind you that it’s a read-write remote:
git remote add upstream-rw [email protected]:sfepy/sfepy.git
git fetch upstream-rw
Integrating changes
Let’s say you have some changes that need to go into trunk (upstream-rw/master).
The changes are in some branch that you are currently on. For example, you are looking at someone’s changes like
this:
git
git
git
git
remote add someone git://github.com/someone/sfepy.git
fetch someone
branch cool-feature --track someone/cool-feature
checkout cool-feature
So now you are on the branch with the changes to be incorporated upstream. The rest of this section assumes you are
on this branch.
A few commits If there are only a few commits, consider rebasing to upstream:
# Fetch upstream changes
git fetch upstream-rw
# rebase
git rebase upstream-rw/master
Remember that, if you do a rebase, and push that, you’ll have to close any github pull requests manually, because
github will not be able to detect the changes have already been merged.
7.7. Working with SfePy source code
367
SfePy Documentation, Release 2015.1
A long series of commits If there are a longer series of related commits, consider a merge instead:
git fetch upstream-rw
git merge --no-ff upstream-rw/master
The merge will be detected by github, and should close any related pull requests automatically.
Note the --no-ff above. This forces git to make a merge commit, rather than doing a fast-forward, so that these
set of commits branch off trunk then rejoin the main history with a merge, rather than appearing to have been made
directly on top of trunk.
Check the history Now, in either case, you should check that the history is sensible and you have the right commits:
git log --oneline --graph
git log -p upstream-rw/master..
The first line above just shows the history in a compact way, with a text representation of the history graph. The
second line shows the log of commits excluding those that can be reached from trunk (upstream-rw/master),
and including those that can be reached from current HEAD (implied with the .. at the end). So, it shows the commits
unique to this branch compared to trunk. The -p option shows the diff for these commits in patch form.
Push to trunk
git push upstream-rw my-new-feature:master
This pushes the my-new-feature branch in this repository to the master branch in the upstream-rw repository.
7.7.6 git resources
Tutorials and summaries
• github help has an excellent series of how-to guides.
• learn.github has an excellent series of tutorials
• The pro git book is a good in-depth book on git.
• A git cheat sheet is a page giving summaries of common commands.
• The git user manual
• The git tutorial
• The git community book
• git ready — a nice series of tutorials
• git casts — video snippets giving git how-tos.
• git magic — extended introduction with intermediate detail
• The git parable is an easy read explaining the concepts behind git.
• git foundation expands on the git parable.
• Fernando Perez’ git page — Fernando’s git page — many links and tips
• A good but technical page on git concepts
• git svn crash course: git for those of us used to subversion
368
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Advanced git workflow
There are many ways of working with git; here are some posts on the rules of thumb that other projects have come up
with:
• Linus Torvalds on git management
• Linus Torvalds on linux git workflow . Summary; use the git tools to make the history of your edits as clean as
possible; merge from upstream edits as little as possible in branches where you are doing active development.
Manual pages online
You can get these on your own machine with (e.g) git help push or (same thing) git push --help, but, for
convenience, here are the online manual pages for some common commands:
• git add
• git branch
• git checkout
• git clone
• git commit
• git config
• git diff
• git log
• git pull
• git push
• git remote
• git status
7.8 Module Index
7.8.1 Main scripts
extractor.py script
Examples
$ ./extractor.py -e “p e 0 1999” bone.h5 $ ./extractor.py -e “p e 0 1999” bone.h5 -a $ ./extractor.py -e “p e 0 1999”
bone.h5 -o extracted.h5 $ ./extractor.py -e “p e 0 1999” bone.h5 -o extracted.h5 -a
extractor.create_problem(filename)
extractor.main()
extractor.parse_linearization(linearization)
7.8. Module Index
369
SfePy Documentation, Release 2015.1
homogen.py script
homogen.main()
phonon.py script
phonon.main()
postproc.py script
This is a script for quick Mayavi-based visualizations of finite element computations results.
Examples
The examples assume that run_tests.py has been run successfully and the resulting data files are present.
• view data in output-tests/test_navier_stokes.vtk
$ python postproc.py output-tests/test_navier_stokes.vtk
tests/test_navier_stokes.vtk –3d
$
python
postproc.py
output-
• save a snapshot image and exit
$ python postproc.py output-tests/test_poisson.vtk -o image.png -n
• save a snapshot image without off-screen rendering and exit
$ python postproc.py output-tests/test_poisson.vtk -o image.png -n –no-offscreen
• create animation (forces offscreen rendering) from output-tests/test_time_poisson.*.vtk
$ python postproc.py output-tests/test_time_poisson.*.vtk -a mov
• create animation (forces offscreen rendering) from output-tests/test_hyperelastic.*.vtk
The range specification for the displacements ‘u’ is required, as output-tests/test_hyperelastic.00.vtk
contains only zero displacements which leads to invisible glyph size.
$ python postproc.py output-tests/test_hyperelastic.*.vtk –ranges=u,0,0.02 -a mov
• same as above, but slower frame rate
$ python postproc.py output-tests/test_hyperelastic_TL.*.vtk –ranges=u,0,0.02 -a mov –ffmpegoptions=”-r 2 -sameq”
postproc.main()
postproc.parse_domain_specific(option, opt, value, parser)
postproc.parse_group_names(option, opt, value, parser)
postproc.parse_opacity(option, opt, value, parser)
postproc.parse_ranges(option, opt, value, parser)
postproc.parse_resolution(option, opt, value, parser)
postproc.parse_subdomains(option, opt, value, parser)
postproc.parse_view(option, opt, value, parser)
postproc.view_file(filename, filter_names, options, view=None)
370
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
probe.py script
Probe finite element solutions in points defined by various geometrical probes.
Generation mode
Probe the data in the results file corresponding to the problem defined in the input file. The input file options must
contain ‘gen_probes’ and ‘probe_hook’ keys, pointing to proper functions accessible from the input file scope.
For each probe returned by gen_probes() a data plot figure and a text file with the data plotted are saved, see the options
below.
Generation options
-o, –auto-dir, –same-dir, -f, –only-names, -s
Postprocessing mode
Read a previously probed data from the probe text file, re-plot them, and integrate them along the probe.
Postprocessing options
–postprocess, –radial, –only-names
Notes
For extremely thin hexahedral elements the Newton’s iteration for finding the reference element coordinates might
converge to a spurious solution outside of the element. To obtain some values even in this case, try increasing the
–close-limit option value.
probe.generate_probes(filename_input, filename_results, options, conf=None,
probes=None, labels=None, probe_hooks=None)
Generate probe figures and data files.
problem=None,
probe.integrate_along_line(x, y, is_radial=False)
Integrate numerically (trapezoidal rule) a function 𝑦 = 𝑦(𝑥).
If is_radial is True, multiply each 𝑦 by 4𝜋𝑥2 .
probe.main()
probe.postprocess(filename_input, filename_results, options)
Postprocess probe data files - replot, integrate data.
run_tests.py script
Notes on writing new test files:
A test file can contain anything, but usually it is similar to a regular input file (defining a test problem), with a
mandatory Test class. This class holds all the test_* functions, as well as the from_conf(), which serves to initialize
the test (conf is in fact the test file itself, options are command-line options).
7.8. Module Index
371
SfePy Documentation, Release 2015.1
All variables defined in a test file are collected in ‘conf’ variable passed to a Test.__init__(). For example, ‘input_name’
in test_input_*.py files is accessible as ‘conf.input_name’. This is usefull if the test class is defined outside the test
file, as the classes in tests_basic.py are.
The test_* functions are collected automatically by run_tests.py, with one exception: if a certain order of their evaluation is required, a class attribute ‘test’ of the Test class with a list of the test function names should be defined
(example: test_meshio.py).
class run_tests.OutputFilter(allowed_lines)
start()
stop()
write(msg)
run_tests.get_dir(default)
run_tests.main()
run_tests.run_test(conf_name, options)
run_tests.wrap_run_tests(options)
schroedinger.py script
Solver for basic electronic structure problems.
Examples
Compute the 2D predefined problems:
$
$
$
$
./schroedinger.py
./schroedinger.py
./schroedinger.py
./schroedinger.py
--well
--oscillator
--hydrogen
--boron
See examples/quantum/ directory for the problem description files corresponding to the above examples.
schroedinger.fix_path(filename)
schroedinger.main()
shaper.py script
shaper.main()
shaper.solve_adjoint(conf, options, dpb, state_dp, data)
Solve the adjoint (linear) problem.
shaper.solve_direct(conf, options)
Solve the direct (nonlinear) problem.
shaper.solve_generic_direct(conf, options)
shaper.solve_navier_stokes(conf, options)
shaper.solve_optimize(conf, options)
shaper.solve_stokes(dpb, equations_stokes, nls_conf )
372
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
simple.py script
Solve partial differential equations given in a SfePy problem definition file.
Example problem definition files can be found in examples/ directory of the SfePy top-level directory. This script
works with all the examples except those in examples/standalone/.
Both normal and parametric study runs are supported. A parametric study allows repeated runs for varying some of
the simulation parameters - see examples/diffusion/poisson_parametric_study.py file.
simple.main()
simple.print_solvers()
simple.print_terms()
7.8.2 Utility scripts
build_helpers.py script
Build helpers for setup.py.
Includes package dependency checks and monkey-patch to numpy.distutils to work with Cython.
Notes
The original version of this file was adapted from NiPy project [1].
[1] http://nipy.sourceforge.net/
class build_helpers.Clean(dist)
Distutils Command class to clean, enhanced to clean also files generated during python setup.py build_ext –
inplace.
run()
class build_helpers.DoxygenDocs(dist)
description = ‘generate docs by Doxygen’
run()
class build_helpers.NoOptionsDocs(dist)
finalize_options()
initialize_options()
user_options = [(‘None’, None, ‘this command has no options’)]
class build_helpers.SphinxHTMLDocs(dist)
description = ‘generate html docs by Sphinx’
run()
class build_helpers.SphinxPDFDocs(dist)
7.8. Module Index
373
SfePy Documentation, Release 2015.1
description = ‘generate pdf docs by Sphinx’
run()
build_helpers.generate_a_pyrex_source(self, base, ext_name, source, extension)
Monkey patch for numpy build_src.build_src method
Uses Cython instead of Pyrex.
build_helpers.get_sphinx_make_command()
build_helpers.have_good_cython()
build_helpers.package_check(pkg_name, version=None, optional=False, checker=<class distutils.version.LooseVersion at 0x2ab8ffcb6390>, version_getter=None,
messages=None)
Check if package pkg_name is present, and correct version
Parameters pkg_name : str or sequence of str
name of package as imported into python. Alternative names (e.g. for different versions)
may be given in a list.
version : {None, str}, optional
minimum version of the package that we require. If None, we don’t check the version.
Default is None
optional : {False, True}, optional
If False, raise error for absent package or wrong version; otherwise warn
checker : callable, optional
callable with which to return comparable thing from version string.
distutils.version.LooseVersion
Default is
version_getter : {None, callable}:
Callable that takes pkg_name as argument, and returns the package version string - as
in:
‘‘version = version_getter(pkg_name)‘‘
If None, equivalent to:
mod = __import__(pkg_name); version = mod.__version__‘‘
messages : None or dict, optional
dictionary giving output messages
build_helpers.recursive_glob(top_dir, pattern)
Utility function working like glob.glob(), but working recursively and returning generator.
Parameters topdir : str
The top-level directory.
pattern : str or list of str
The pattern or list of patterns to match.
374
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
test_install.py script
Simple script for testing various SfePy functionality, examples not covered by tests, and running the tests.
The script just runs the commands specified in its main() using the subprocess module, captures the output and compares one or more key words to the expected ones.
The output of failed commands is saved to ‘test_install.log’ file.
test_install.check_output(cmd)
Run the specified command and capture its outputs.
Returns out : tuple
The (stdout, stderr) output tuple.
test_install.main()
test_install.report(out, name, line, item, value, eps=None, return_item=False)
Check that item at line of the output string out is equal to value. If not, print the output.
script/blockgen.py script
Block mesh generator.
blockgen.main()
script/convert_mesh.py script
Convert a mesh file from one SfePy-supported format to another.
Examples:
$
$
$
$
./script/convert_mesh.py
./script/convert_mesh.py
./script/convert_mesh.py
./script/convert_mesh.py
meshes/3d/cylinder.mesh
meshes/3d/cylinder.mesh
meshes/3d/cylinder.mesh
meshes/3d/cylinder.mesh
new.vtk
new.vtk -s2.5
new.vtk -s0.5,2,1
new.vtk -s0.5,2,1 -c 0
convert_mesh.main()
script/cylindergen.py script
cylindergen.main()
script/edit_identifiers.py script
Convert mixedCase identifiers to under_scores.
edit_identifiers.cw2us(x)
edit_identifiers.edit(line)
edit_identifiers.main()
edit_identifiers.match_candidate()
match(string[, pos[, endpos]]) –> match object or None. Matches zero or more characters at the beginning of
the string
edit_identifiers.mc2us(x)
7.8. Module Index
375
SfePy Documentation, Release 2015.1
edit_identifiers.split_on(token, chars)
edit_identifiers.us2cw(x)
edit_identifiers.us2mc(x)
script/eval_ns_forms.py script
Operators present in the FE discretization of (adjoint) Navier-Stokes terms.
eval_ns_forms.create_scalar(name, n_ep)
eval_ns_forms.create_scalar_base(name, n_ep)
eval_ns_forms.create_scalar_base_grad(name, phic, dim)
eval_ns_forms.create_scalar_var_data(name, phi, g, u)
eval_ns_forms.create_u_operator(u, transpose=False)
eval_ns_forms.create_vector(name, n_ep, dim)
ordering is DOF-by-DOF
eval_ns_forms.create_vector_base(name, phic, dim)
eval_ns_forms.create_vector_base_grad(name, gc, transpose=False)
eval_ns_forms.create_vector_var_data(name, phi, vindx, g, gt, vgindx, u)
eval_ns_forms.grad_vector_to_matrix(name, gv)
eval_ns_forms.main()
eval_ns_forms.substitute_continuous(expr, names, u, phi)
script/eval_tl_forms.py script
Operators present in the FE discretization of hyperelastic terms in the total Lagrangian formulation.
eval_tl_forms.main()
script/extract_surface.py script
Given a mesh file, this script extracts its surface and prints it to stdout in form of a list where each row is [element, face,
component]. A component corresponds to a contiguous surface region - for example, a cubical mesh with a spherical
hole has two surface components. Two surface faces sharing a single node belong to one component.
With ‘-m’ option, a mesh of the surface is created and saved in ‘<original path>/surf_<original mesh file name>.mesh’.
extract_surface.get_surface_faces(domain)
extract_surface.main()
extract_surface.surface_components(gr_s, surf_faces)
Determine surface components given surface mesh connectivity graph.
extract_surface.surface_graph(surf_faces, n_nod)
376
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
script/gen_gallery.py script
Generate the images and rst files for gallery of SfePy examples.
The following steps need to be made to regenerate the documentation with the updated example files:
1. Generate the files:
• for sfepy.org deployment:
$ ./script/gen_gallery.py -l ../doc-devel
• for local test build run from ./:
$ ./script/gen_gallery.py -l doc/_build/html/
2. remove doc/examples/:
$ rm -rf doc/examples/
3. copy gallery/examples/ to doc/:
$ cp -a gallery/examples/ doc/
4. regenerate the documentation:
$ python setup.py htmldocs
Additional steps for sfepy.org deployment:
• copy doc/_build/html/ to <sfepy.org>/doc-devel/
• copy gallery/gallery.html and gallery/images/ to <sfepy.org>/
gen_gallery.generate_gallery_html(examples_dir, output_filename, gallery_dir, rst_dir, thumbnails_dir, dir_map, link_prefix)
Generate the gallery html file with thumbnail images and links to examples.
Parameters output_filename : str
The output html file name.
gallery_dir : str
The top level directory of gallery files.
rst_dir : str
The full path to rst files of examples within gallery_dir.
thumbnails_dir : str
The full path to thumbnail images within gallery_dir.
dir_map : dict
The directory mapping returned by generate_rst_files()
link_prefix : str, optional
The prefix to prepend to links to individual pages of examples.
gen_gallery.generate_images(images_dir, examples_dir)
Generate images from results of running examples found in examples_dir directory.
The generated images are stored to images_dir,
7.8. Module Index
377
SfePy Documentation, Release 2015.1
gen_gallery.generate_rst_files(rst_dir, examples_dir, images_dir)
Generate Sphinx rst files for examples in examples_dir with images in images_dir and put them into rst_dir.
Returns dir_map : dict
The directory mapping of examples and corresponding rst files.
gen_gallery.generate_thumbnails(thumbnails_dir, images_dir, scale=0.3)
Generate thumbnails into thumbnails_dir corresponding to images in images_dir.
gen_gallery.main()
script/gen_iga_patch.py script
Generate a single IGA patch block in 2D or 3D of given degrees and continuity using igakit.
The grid has equally-spaced knot vectors.
gen_iga_patch.main()
script/gen_lobatto1d_c.py script
Generate lobatto1d.c and lobatto1h.c files.
gen_lobatto1d_c.append_declarations(out, cpolys, comment, cvar_name, shift=0)
gen_lobatto1d_c.append_lists(out, names, length)
gen_lobatto1d_c.append_polys(out, cpolys, comment, cvar_name, var_name=’x’, shift=0)
gen_lobatto1d_c.gen_lobatto(max_order)
gen_lobatto1d_c.main()
gen_lobatto1d_c.plot_polys(fig, polys, var_name=’x’)
script/gen_mesh_prev.py script
Mesh Preview Generator.
Examples
$ ./script/gen_mesh_prev.py meshes/2d/
gen_mesh_prev.gen_shot(vtk_filename, png_filename)
Generate PNG image of the FE mesh.
Parameters vtk_filename : str
The input mesh filename (file in VTK format).
png_filename : str
The name of the output PNG file.
gen_mesh_prev.main()
378
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
script/gen_term_table.py script
Generate the table of all terms for the sphinx documentation.
gen_term_table.create_parser(slist, current_section)
gen_term_table.format_next(text, new_text, pos, can_newline, width, ispaces)
gen_term_table.gen_term_table(app)
gen_term_table.main()
gen_term_table.set_section(sec)
gen_term_table.setup(app)
gen_term_table.to_list(slist, sec)
gen_term_table.typeset(filename)
Utility function called by sphinx.
gen_term_table.typeset_term_syntax(term_class)
gen_term_table.typeset_term_table(fd, table)
Terms are sorted by name without the d*_ prefix.
gen_term_table.typeset_to_indent(txt, indent0, indent, width)
script/plot_condition_numbers.py script
Plot conditions numbers w.r.t. polynomial approximation order of reference element matrices for various FE polynomial spaces (bases).
plot_condition_numbers.main()
script/plot_logs.py script
Plot logs of variables saved in a text file by sfepy.base.log.Log class.
The plot should be almost the same as the plot that would be generated by the Log directly.
plot_logs.main()
plot_logs.parse_rc(option, opt, value, parser)
script/plot_mesh.py script
Plot mesh connectivities, facet orientations, global and local DOF ids etc.
plot_mesh.main()
script/plot_quadratures.py script
Plot quadrature points for the given geometry and integration order.
plot_quadratures.main()
7.8. Module Index
379
SfePy Documentation, Release 2015.1
script/plot_times.py script
Plot time steps, times of time steps and time deltas in a HDF5 results file.
plot_times.main()
script/save_basis.py script
Save polynomial basis on reference elements or on a mesh for visualization into a given output directory.
save_basis.get_dofs(dofs, n_total)
save_basis.main()
save_basis.save_basis_on_mesh(mesh, options, output_dir, lin, permutations=None, suffix=’‘)
script/show_authors.py script
show_authors.main()
script/show_terms_use.py script
Show terms use in problem description files in the given directory.
show_terms_use.main()
script/sync_module_docs.py script
Synchronize the documentation files in a given directory doc_dir with the actual state of the SfePy sources in
top_dir. Missing files are created, files with no corresponding source file are removed, other files are left untouched.
Notes
The developer guide needs to be edited manually to reflect the changes.
sync_module_docs.main()
script/tile_periodic_mesh.py script
tile_periodic_mesh.main()
tile_periodic_mesh.parse_repeat(option, opt, value, parser)
7.8.3 sfepy package
sfepy.config module
class sfepy.config.Config
compile_flags()
debug_flags()
380
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
is_release()
link_flags()
numpydoc_path()
python_include()
python_version()
system()
tetgen_path()
sfepy.config.has_attr(obj, attr)
sfepy.version module
sfepy.version.get_basic_info(version=‘2015.1’)
Return SfePy installation directory information. Append current git commit hash to version.
7.8.4 sfepy.applications package
sfepy.applications.application module
class sfepy.applications.application.Application(conf, options, output_prefix, **kwargs)
Base class for applications.
Subclasses should implement: __init__(), call().
Automates parametric studies, see parametrize().
call_basic(**kwargs)
call_parametrized(**kwargs)
parametrize(parametric_hook)
Add parametric_hook, set __call__() to call_parametrized().
restore()
Remove parametric_hook, restore __call__() to call_basic().
setup_options()
sfepy.applications.pde_solver_app module
class sfepy.applications.pde_solver_app.PDESolverApp(conf,
options,
output_prefix,
init_equations=True, **kwargs)
call(nls_status=None)
load_dict(filename)
Utility function to load a dictionary data from a HDF5 file filename.
static process_options(options)
Application options setup. Sets default values for missing non-compulsory options.
save_dict(filename, data)
Utility function to save a dictionary data to a HDF5 file filename.
setup_options()
7.8. Module Index
381
SfePy Documentation, Release 2015.1
setup_output_info(problem, options)
Modifies both problem and options!
sfepy.applications.pde_solver_app.assign_standard_hooks(obj, get, conf )
Set standard hook function attributes from conf to obj using the get function.
sfepy.applications.pde_solver_app.save_only(conf, save_names, problem=None)
Save information available prior to setting equations and solving them.
sfepy.applications.pde_solver_app.solve_pde(conf,
options=None,
**app_options)
Solve a system of partial differential equations (PDEs).
nls_status=None,
This function is a convenience wrapper that creates and runs an instance of PDESolverApp.
Parameters conf : str or ProblemConf instance
Either the name of the problem description file defining the PDEs, or directly the ProblemConf instance.
options : options
The command-line options.
nls_status : dict-like
The object for storing the nonlinear solver return status.
app_options : kwargs
The keyword arguments that can override application-specific options.
7.8.5 sfepy.base package
sfepy.base.base module
sfepy.base.base.debug(frame=None, frames_back=1)
Start debugger on line where it is called, roughly equivalent to:
import pdb; pdb.set_trace()
First, this function tries to start an IPython-enabled debugger using the IPython API.
When this fails, the plain old pdb is used instead.
With IPython, one can say in what frame the debugger can stop.
class sfepy.base.base.Container(objs=None, **kwargs)
append(obj)
as_dict()
Return stored objects in a dictionary with object names as keys.
extend(objs)
Extend the container items by the sequence objs.
get(ii, default=None, msg_if_none=None)
Get an item from Container - a wrapper around Container.__getitem__() with defaults and custom error
message.
Parameters ii : int or str
382
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The index or name of the item.
default : any, optional
The default value returned in case the item ii does not exist.
msg_if_none : str, optional
If not None, and if default is None and the item ii does not exist, raise ValueError with
this message.
get_names()
has_key(ii)
insert(ii, obj)
iteritems()
iterkeys()
itervalues()
print_names()
remove_name(name)
update(objs=None)
class sfepy.base.base.IndexedStruct(**kwargs)
class sfepy.base.base.OneTypeList(item_class, seq=None)
find(name, ret_indx=False)
get_names()
print_names()
class sfepy.base.base.Output(prefix, filename=None, quiet=False, combined=False, append=False,
**kwargs)
Factory class providing output (print) functions. All SfePy printing should be accomplished by this class.
Examples
>>> from sfepy.base.base import Output
>>> output = Output(’sfepy:’)
>>> output(1, 2, 3, ’hello’)
sfepy: 1 2 3 hello
>>> output.prefix = ’my_cool_app:’
>>> output(1, 2, 3, ’hello’)
my_cool_app: 1 2 3 hello
get_output_function()
get_output_prefix()
prefix
set_output(filename=None, quiet=False, combined=False, append=False)
Set the output mode.
If quiet is True, no messages are printed to screen. If simultaneously filename is not None, the messages
are logged into the specified file.
7.8. Module Index
383
SfePy Documentation, Release 2015.1
If quiet is False, more combinations are possible. If filename is None, output is to screen only, otherwise
it is to the specified file. Moreover, if combined is True, both the ways are used.
Parameters filename : str or file object
Print messages into the specified file.
quiet : bool
Do not print anything to screen.
combined : bool
Print both on screen and into the specified file.
append : bool
Append to an existing file instead of overwriting it. Use with filename.
set_output_prefix(prefix)
class sfepy.base.base.Struct(**kwargs)
copy(deep=False, name=None)
Make a (deep) copy of self.
Parameters:
deep [bool] Make a deep copy.
name [str] Name of the copy, with default self.name + ‘_copy’.
get(key, default=None, msg_if_none=None)
A dict-like get() for Struct attributes.
set_default(key, default=None)
Behaves like dict.setdefault().
str_all()
str_class()
As __str__(), but for class attributes.
to_dict()
update(other, **kwargs)
A dict-like update for Struct attributes.
sfepy.base.base.as_float_or_complex(val)
Try to cast val to Python float, and if this fails, to Python complex type.
sfepy.base.base.assert_(condition, msg=’assertion failed!’)
sfepy.base.base.check_names(names1, names2, msg)
Check if all names in names1 are in names2, otherwise raise IndexError with the provided message msg.
sfepy.base.base.configure_output(options)
Configure the standard :function:‘output()‘ function using output_log_name and output_screen attributes of
options.
Parameters options : Struct or dict
The options with output_screen and output_log_name items. Defaults are provided if
missing.
384
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.base.base.debug(frame=None, frames_back=1)
Start debugger on line where it is called, roughly equivalent to:
import pdb; pdb.set_trace()
First, this function tries to start an IPython-enabled debugger using the IPython API.
When this fails, the plain old pdb is used instead.
With IPython, one can say in what frame the debugger can stop.
sfepy.base.base.dict_extend(d1, d2)
sfepy.base.base.dict_from_keys_init(keys, seq_class=None)
sfepy.base.base.dict_to_array(adict)
Convert a dictionary of nD arrays of the same shapes with non-negative integer keys to a single (n+1)D array.
sfepy.base.base.dict_to_struct(*args, **kwargs)
Convert a dict instance to a Struct instance.
sfepy.base.base.edit_dict_strings(str_dict, old, new, recur=False)
Replace substrings old with new in string values of dictionary str_dict. Both old and new can be lists of the
same length - items in old are replaced by items in new with the same index.
Parameters str_dict : dict
The dictionary with string values or tuples containing strings.
old : str or list of str
The old substring or list of substrings.
new : str or list of str
The new substring or list of substrings.
recur : bool
If True, edit tuple values recursively.
Returns new_dict : dict
The dictionary with edited strings.
sfepy.base.base.edit_tuple_strings(str_tuple, old, new, recur=False)
Replace substrings old with new in items of tuple str_tuple. Non-string items are just copied to the new tuple.
Parameters str_tuple : tuple
The tuple with string values.
old : str
The old substring.
new : str
The new substring.
recur : bool
If True, edit items that are tuples recursively.
Returns new_tuple : tuple
The tuple with edited strings.
7.8. Module Index
385
SfePy Documentation, Release 2015.1
sfepy.base.base.find_subclasses(context, classes, omit_unnamed=False, name_attr=’name’)
Find subclasses of the given classes in the given context.
Examples
>>> solver_table = find_subclasses(vars().items(),
[LinearSolver, NonlinearSolver,
TimeSteppingSolver, EigenvalueSolver,
OptimizationSolver])
sfepy.base.base.get_arguments(omit=None)
Get a calling function’s arguments.
Returns:
args [dict] The calling function’s arguments.
sfepy.base.base.get_debug()
Utility function providing debug() function.
sfepy.base.base.get_default(arg, default, msg_if_none=None)
sfepy.base.base.get_default_attr(obj, attr, default, msg_if_none=None)
sfepy.base.base.get_subdict(adict, keys)
Get a sub-dictionary of adict with given keys.
sfepy.base.base.import_file(filename, package_name=None, can_reload=True)
Import a file as a module. The module is explicitly reloaded to prevent undesirable interactions.
sfepy.base.base.insert_as_static_method(cls, name, function)
sfepy.base.base.insert_method(instance, function)
sfepy.base.base.insert_static_method(cls, function)
sfepy.base.base.invert_dict(d, is_val_tuple=False, unique=True)
Invert a dictionary by making its values keys and vice versa.
Parameters d : dict
The input dictionary.
is_val_tuple : bool
If True, the d values are tuples and new keys are the tuple items.
unique : bool
If True, the d values are unique and so the mapping is one to one. If False, the d values
(possibly) repeat, so the inverted dictionary will have as items lists of corresponding
keys.
Returns di : dict
The inverted dictionary.
sfepy.base.base.is_derived_class(cls, parent)
sfepy.base.base.is_sequence(var)
sfepy.base.base.iter_dict_of_lists(dol, return_keys=False)
386
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.base.base.load_classes(filenames, classes, package_name=None, ignore_errors=False,
name_attr=’name’)
For each filename in filenames, load all subclasses of classes listed.
sfepy.base.base.mark_time(times, msg=None)
Time measurement utility.
Measures times of execution between subsequent calls using time.clock(). The time is printed if the msg argument is not None.
Examples
>>> times = []
>>> mark_time(times)
... do something
>>> mark_time(times, ’elapsed’)
elapsed 0.1
... do something else
>>> mark_time(times, ’elapsed again’)
elapsed again 0.05
>>> times
[0.10000000000000001, 0.050000000000000003]
sfepy.base.base.ordered_iteritems(adict)
sfepy.base.base.pause(msg=None)
Prints the line number and waits for a keypress.
If you press: “q” ............. it will call sys.exit() any other key ... it will continue execution of the program
This is useful for debugging.
sfepy.base.base.print_structs(objs)
Print Struct instances in a container, works recursively. Debugging utility function.
sfepy.base.base.python_shell()
sfepy.base.base.remap_dict(d, map)
Utility function to remap state dict keys according to var_map.
sfepy.base.base.select_by_names(objs_all, names, replace=None, simple=True)
sfepy.base.base.set_defaults(dict_, defaults)
sfepy.base.base.spause(msg=None)
Waits for a keypress.
If you press: “q” ............. it will call sys.exit() any other key ... it will continue execution of the program
This is useful for debugging. This function is called from pause().
sfepy.base.base.try_imports(imports, fail_msg=None)
Try import statements until one succeeds.
Parameters imports : list
The list of import statements.
fail_msg : str
If not None and no statement succeeds, a ValueError is raised with the given message,
appended to all failed messages.
Returns locals : dict
7.8. Module Index
387
SfePy Documentation, Release 2015.1
The dictionary of imported modules.
sfepy.base.base.update_dict_recursively(dst,
src,
tuples_too=False,
write_by_none=True)
Update dst dictionary recursively using items in src dictionary.
over-
Parameters dst : dict
The destination dictionary.
src : dict
The source dictionary.
tuples_too : bool
If True, recurse also into dictionaries that are members of tuples.
overwrite_by_none : bool
If False, do not overwrite destination dictionary values by None.
Returns dst : dict
The destination dictionary.
sfepy.base.base.use_method_with_name(instance, method, new_name)
sfepy.base.compat module
This module contains functions that have different names or behavior depending on NumPy and Scipy versions.
sfepy.base.compat.in1d(ar1, ar2, assume_unique=False, invert=False)
Test whether each element of a 1-D array is also present in a second array.
Returns a boolean array the same length as ar1 that is True where an element of ar1 is in ar2 and False otherwise.
Parameters ar1 : (M,) array_like
Input array.
ar2 : array_like
The values against which to test each value of ar1.
assume_unique : bool, optional
If True, the input arrays are both assumed to be unique, which can speed up the calculation. Default is False.
invert : bool, optional
If True, the values in the returned array are inverted (that is, False where an element of ar1 is in ar2 and True otherwise). Default is False. np.in1d(a, b,
invert=True) is equivalent to (but is faster than) np.invert(in1d(a, b)).
New in version 1.8.0.
Returns in1d : (M,) ndarray, bool
The values ar1[in1d] are in ar2.
See also:
numpy.lib.arraysetops Module with a number of other functions for performing set operations on arrays.
388
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
in1d can be considered as an element-wise function version of the python keyword in, for 1-D sequences.
in1d(a, b) is roughly equivalent to np.array([item in b for item in a]).
New in version 1.4.0.
Examples
>>> test = np.array([0, 1, 2, 5, 0])
>>> states = [0, 2]
>>> mask = np.in1d(test, states)
>>> mask
array([ True, False, True, False, True], dtype=bool)
>>> test[mask]
array([0, 2, 0])
>>> mask = np.in1d(test, states, invert=True)
>>> mask
array([False, True, False, True, False], dtype=bool)
>>> test[mask]
array([1, 5])
sfepy.base.compat.unique(ar, return_index=False, return_inverse=False)
Find the unique elements of an array.
Returns the sorted unique elements of an array. There are two optional outputs in addition to the unique elements:
the indices of the input array that give the unique values, and the indices of the unique array that reconstruct the
input array.
Parameters ar : array_like
Input array. This will be flattened if it is not already 1-D.
return_index : bool, optional
If True, also return the indices of ar that result in the unique array.
return_inverse : bool, optional
If True, also return the indices of the unique array that can be used to reconstruct ar.
Returns unique : ndarray
The sorted unique values.
unique_indices : ndarray, optional
The indices of the first occurrences of the unique values in the (flattened) original array.
Only provided if return_index is True.
unique_inverse : ndarray, optional
The indices to reconstruct the (flattened) original array from the unique array. Only
provided if return_inverse is True.
See also:
numpy.lib.arraysetops Module with a number of other functions for performing set operations on arrays.
7.8. Module Index
389
SfePy Documentation, Release 2015.1
Examples
>>> np.unique([1, 1, 2, 2, 3, 3])
array([1, 2, 3])
>>> a = np.array([[1, 1], [2, 3]])
>>> np.unique(a)
array([1, 2, 3])
Return the indices of the original array that give the unique values:
>>> a = np.array([’a’, ’b’, ’b’, ’c’, ’a’])
>>> u, indices = np.unique(a, return_index=True)
>>> u
array([’a’, ’b’, ’c’],
dtype=’|S1’)
>>> indices
array([0, 1, 3])
>>> a[indices]
array([’a’, ’b’, ’c’],
dtype=’|S1’)
Reconstruct the input array from the unique values:
>>> a = np.array([1, 2, 6, 4, 2, 3, 2])
>>> u, indices = np.unique(a, return_inverse=True)
>>> u
array([1, 2, 3, 4, 6])
>>> indices
array([0, 1, 4, 3, 1, 2, 1])
>>> u[indices]
array([1, 2, 6, 4, 2, 3, 2])
sfepy.base.conf module
Problem description file handling.
Notes
Short syntax: key is suffixed with ‘__<number>’ to prevent collisions with long syntax keys -> both cases can be used
in a single input.
class sfepy.base.conf.ProblemConf(define_dict, funmod=None, filename=None, required=None,
other=None, verbose=True, override=None, setup=True)
Problem configuration, corresponding to an input (problem description file). It validates the input using lists
of required and other keywords that have to/can appear in the input. Default keyword lists can be obtained by
sfepy.base.conf.get_standard_keywords().
ProblemConf instance is used to construct a Problem instance via Problem.from_conf(conf).
add_missing(conf )
Add missing values from another problem configuration.
Missing keys/values are added also to values that are dictionaries.
Parameters conf : ProblemConf instance
The other configuration.
390
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
edit(key, newval)
static from_dict(dict_, funmod, required=None, other=None, verbose=True, override=None,
setup=True)
static from_file(filename, required=None, other=None, verbose=True, define_args=None, override=None, setup=True)
Loads the problem definition from a file.
The filename can either contain plain definitions, or it can contain the define() function, in which case it
will be called to return the input definitions.
The job of the define() function is to return a dictionary of parameters. How the dictionary is constructed
is not our business, but the usual way is to simply have a function define() along these lines in the input
file:
def define():
options = {
’save_eig_vectors’ : None,
’eigen_solver’ : ’eigen1’,
}
region_2 = {
’name’ : ’Surface’,
’select’ : ’nodes of surface’,
}
return locals()
Optionally, the define() function can accept additional arguments that should be defined using the define_args tuple or dictionary.
static from_file_and_options(filename, options, required=None, other=None, verbose=True, define_args=None, setup=True)
Utility function, a wrapper around ProblemConf.from_file() with possible override taken from options.
static from_module(module, required=None,
setup=True)
other=None,
verbose=True,
override=None,
get_function(name)
Get a function object given its name.
It can be either in ProblemConf.funmod, or a ProblemConf attribute directly.
Parameters name : str or function or None
The function name or directly the function.
Returns fun : function or None
The required function, or None if name was None.
get_item_by_name(key, item_name)
Return item with name item_name in configuration group given by key.
get_raw(key=None)
setup(define_dict=None, funmod=None, filename=None, required=None, other=None)
transform_input()
transform_input_trivial()
Trivial input transformations.
update_conf(conf )
Update configuration by values in another problem configuration.
Values that are dictionaries are updated in-place by dict.update().
7.8. Module Index
391
SfePy Documentation, Release 2015.1
Parameters conf : ProblemConf instance
The other configuration.
validate(required=None, other=None)
sfepy.base.conf.dict_from_options(options)
Return a dictionary that can be used to construct/override a ProblemConf instance based on options.
See --conf and --options options of the simple.py script.
sfepy.base.conf.dict_from_string(string)
Parse string and return a dictionary that can be used to construct/override a ProblemConf instance.
sfepy.base.conf.get_standard_keywords()
sfepy.base.conf.transform_conditions(adict, prefix)
sfepy.base.conf.transform_ebcs(adict)
sfepy.base.conf.transform_epbcs(adict)
sfepy.base.conf.transform_fields(adict)
sfepy.base.conf.transform_functions(adict)
sfepy.base.conf.transform_ics(adict)
sfepy.base.conf.transform_integrals(adict)
sfepy.base.conf.transform_lcbcs(adict)
sfepy.base.conf.transform_materials(adict)
sfepy.base.conf.transform_regions(adict)
sfepy.base.conf.transform_solvers(adict)
sfepy.base.conf.transform_to_i_struct_1(adict)
sfepy.base.conf.transform_to_struct_01(adict)
sfepy.base.conf.transform_to_struct_1(adict)
sfepy.base.conf.transform_to_struct_10(adict)
sfepy.base.conf.transform_variables(adict)
sfepy.base.conf.tuple_to_conf(name, vals, order)
Convert a configuration tuple vals into a Struct named name, with attribute names given in and ordered by order.
Items in order at indices outside the length of vals are ignored.
sfepy.base.getch module
getch()-like unbuffered character reading from stdin on both Windows and Unix
_Getch classes inspired by Danny Yoo, iskeydown() based on code by Zachary Pincus.
sfepy.base.goptions module
Various global options/parameters.
392
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
Inspired by rcParams of matplotlib.
class sfepy.base.goptions.ValidatedDict
A dictionary object including validation.
default = False
key = ‘check_term_finiteness’
keys()
Return sorted list of keys.
validate = {‘verbose’: <function validate_bool at 0x2ab8ffc8d230>, ‘check_term_finiteness’: <function validate_bool at
validator(val)
Convert b to a boolean or raise a ValueError.
values()
Return values in order of sorted keys.
sfepy.base.goptions.validate_bool(val)
Convert b to a boolean or raise a ValueError.
sfepy.base.ioutils module
class sfepy.base.ioutils.InDir(filename)
Store the directory name a file is in, and prepend this name to other files.
Examples
>>> indir = InDir(’output/file1’)
>>> print indir(’file2’)
sfepy.base.ioutils.edit_filename(filename, prefix=’‘, suffix=’‘, new_ext=None)
Edit a file name by add a prefix, inserting a suffix in front of a file name extension or replacing the extension.
Parameters filename : str
The file name.
prefix : str
The prefix to be added.
suffix : str
The suffix to be inserted.
new_ext : str, optional
If not None, it replaces the original file name extension.
Returns new_filename : str
The new file name.
sfepy.base.ioutils.ensure_path(filename)
Check if path to filename exists and if not, create the necessary intermediate directories.
7.8. Module Index
393
SfePy Documentation, Release 2015.1
sfepy.base.ioutils.get_print_info(n_step, fill=None)
Returns the max. number of digits in range(n_step) and the corresponding format string.
Examples:
>>>
(2,
>>>
(1,
>>>
(2,
>>>
(3,
>>>
(3,
get_print_info(11)
’%2d’)
get_print_info(8)
’%1d’)
get_print_info(100)
’%2d’)
get_print_info(101)
’%3d’)
get_print_info(101, fill=’0’)
’%03d’)
sfepy.base.ioutils.get_trunk(filename)
sfepy.base.ioutils.locate_files(pattern, root_dir=’.’)
Locate all files matching fiven filename pattern in and below supplied root directory.
sfepy.base.ioutils.read_array(fd, n_row, n_col, dtype)
Read a NumPy array of shape (n_row, n_col) from the given file object and cast it to type dtype. If n_col is
None, determine the number of columns automatically.
sfepy.base.ioutils.read_dict_hdf5(filename, level=0, group=None, fd=None)
sfepy.base.ioutils.read_list(fd, n_item, dtype)
sfepy.base.ioutils.read_sparse_matrix_hdf5(filename, output_format=None)
sfepy.base.ioutils.read_token(fd)
Read a single token (sequence of non-whitespace characters) from the given file object.
Notes
Consumes the first whitespace character after the token.
sfepy.base.ioutils.remove_files(root_dir)
Remove all files and directories in supplied root directory.
sfepy.base.ioutils.skip_read_line(fd, no_eof=False)
Read the first non-empty line (if any) from the given file object. Return an empty string at EOF, if no_eof is
False. If it is True, raise the EOFError instead.
sfepy.base.ioutils.write_dict_hdf5(filename, adict, level=0, group=None, fd=None)
sfepy.base.ioutils.write_sparse_matrix_hdf5(filename, mtx, name=’a sparse matrix’)
Assume CSR/CSC.
sfepy.base.log module
class sfepy.base.log.Log(data_names=None,
xlabels=None,
ylabels=None,
yscales=None,
is_plot=True, aggregate=200, log_filename=None, formats=None)
Log data and (optionally) plot them in the second process via LogPlotter.
add_group(names, yscale=None, xlabel=None, ylabel=None, formats=None)
Add a new data group. Notify the plotting process if it is already running.
count = -1
394
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
static from_conf(conf, data_names)
Parameters data_names : list of lists of str
The data names grouped by subplots: [[name1, name2, ...], [name3, name4, ...], ...],
where name<n> are strings to display in (sub)plot legends.
get_log_name()
iter_names(igs=None)
plot_data(igs)
plot_vlines(igs=None, **kwargs)
Plot vertical lines in axes given by igs at current x locations to mark some events.
terminate()
sfepy.base.log.get_logging_conf(conf, log_name=’log’)
Check for a log configuration (‘log’ attribute by default) in conf. Supply default values if necessary.
Parameters conf : Struct
The configuration object.
log_name : str, optional
The name of the log configuration attribute in conf.
Returns log : dict
The dictionary {‘plot’ : <figure_file>, ‘text’ : <text_log_file>}. One or both values can
be None.
sfepy.base.log.name_to_key(name, ii)
sfepy.base.log.plot_log(fig_num, log, info, xticks=None, yticks=None)
Plot log data returned by read_log() into a specified figure.
Parameters fig_num : int
The figure number.
log : dict
The log with data names as keys and (xs, ys, vlines) as values.
info : dict
The log plot configuration with subplot numbers as keys.
xticks : list of arrays, optional
The list of x-axis ticks (array or None) for each subplot.
yticks : list of arrays, optional
The list of y-axis ticks (array or None) for each subplot.
sfepy.base.log.read_log(filename)
Read data saved by Log into a text file.
Parameters filename : str
The name of a text log file.
Returns log : dict
The log with data names as keys and (xs, ys, vlines) as values.
7.8. Module Index
395
SfePy Documentation, Release 2015.1
info : dict
The log plot configuration with subplot numbers as keys.
sfepy.base.log_plotter module
Plotting class to be used by Log.
class sfepy.base.log_plotter.LogPlotter(aggregate=100)
LogPlotter to be used by sfepy.base.log.Log.
make_axes()
output = Output
poll_draw()
process_command(command)
terminate()
sfepy.base.mem_usage module
Memory usage functions.
sfepy.base.mem_usage.get_mem_usage(obj, usage=None, name=None, traversal_order=None,
level=0)
Get lower bound of memory usage of an object.
Takes into account strings, numpy arrays and scipy CSR sparse matrices, descends into sequences, mappings
and objects.
Parameters obj : any object
The object to be measured.
usage : dict
The dict with memory usage records, serving also as a cache of already traversed objects.
name : str
The name to be given to the object in its record.
traversal_order : list, internal
The traversal order of the object.
level : int, internal
The recurrence level.
Returns usage : int
The object’s lower bound of memory usage.
sfepy.base.mem_usage.print_mem_usage(usage,
order_by=’usage’,
print_key=False)
Print memory usage dictionary.
direction=’up’,
Parameters usage : dict
The dict with memory usage records.
396
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
order_by : ‘usage’, ‘name’, ‘kind’, ‘nrefs’, ‘traversal_order’, or ‘level’
The sorting field name.
direction : ‘up’ or ‘down’
The sorting direction.
print_key : bool
If True, print also the record key (object’s id).
sfepy.base.parse_conf module
Create pyparsing grammar for problem configuration and options.
sfepy.base.parse_conf.create_bnf(allow_tuple=False, free_word=False)
sfepy.base.parse_conf.cvt_array_index(toks)
sfepy.base.parse_conf.cvt_int(toks)
sfepy.base.parse_conf.cvt_none(toks)
sfepy.base.parse_conf.cvt_real(toks)
sfepy.base.parse_conf.get_standard_type_defs(word=W:(abcd...))
Return dict of the pyparsing base lexical elements.
The compound types (tuple, list, dict) can contain compound types or simple types such as integers, floats and
words.
Parameters word : lexical element
A custom lexical element for word.
Returns defs : dict
The dictionary with the following items:
• tuple: (..., ..., ...)
• list: [..., ...., ...]
• dict: {...:..., ...:..., ....} or {...=..., ...=..., ....}
• list_item: any of preceding compound types or simple types
sfepy.base.parse_conf.list_dict(word=W:(abcd...))
Return the pyparsing lexical element, that parses a string either as a list or as a dictionary.
Parameters word : lexical element
A custom lexical element for word.
Returns ld : lexical element
The returned lexical element parses a string in the form ..., ..., ... or
key1:..., key2=..., key3: ... where ... is a list_item from
get_standard_type_defs() and interprets it as a list or a dictionary.
sfepy.base.parse_conf.list_of(element, *elements)
Return lexical element that parses a list of items. The items can be a one or several lexical elements. For
example, result of list_of(real, integer) parses list of real or integer numbers.
7.8. Module Index
397
SfePy Documentation, Release 2015.1
sfepy.base.plotutils module
sfepy.base.plotutils.font_size(size)
sfepy.base.plotutils.iplot(*args, **kwargs)
sfepy.base.plotutils.plot_matrix_diff(mtx1, mtx2, delta, legend, mode)
sfepy.base.plotutils.print_matrix_diff(title, legend, mtx1, mtx2, mtx_da, mtx_dr, iis)
sfepy.base.plotutils.set_axes_font_size(ax, size)
sfepy.base.plotutils.spy(mtx, eps=None, color=’b’, **kwargs)
Show sparsity structure of a scipy.sparse matrix.
sfepy.base.plotutils.spy_and_show(mtx, **kwargs)
sfepy.base.reader module
class sfepy.base.reader.Reader(directory)
Reads and executes a Python file as a script with execfile(), storing its locals. Then sets the __dict__ of a new
instance of obj_class to the stored locals.
Example:
>>> class A:
>>>
pass
>>> read = Reader( ’.’ )
>>> instance_of_a = read( A, ’file.py’ )
It is equivalent to:
>>> mod = __import__( ’file’ )
>>> instance_of_a = A()
>>> instance_of_a.__dict__.update( mod.__dict__ )
The first way does not create the ‘file.pyc’...
sfepy.base.resolve_deps module
Functions for resolving dependencies.
sfepy.base.resolve_deps.get_nums(deps)
Get number of prerequisite names for each name in dependencies.
sfepy.base.resolve_deps.remove_known(deps, known)
Remove known names from dependencies.
sfepy.base.resolve_deps.resolve(deps)
Resolve dependencies among equations so that smaller blocks are solved first.
The dependencies are given in terms of variable names.
Parameters deps : dict
The dependencies as a dictionary with names as keys and sets of prerequisite names as
values.
Returns order : list
The list of blocks in the order of solving. Each block is a list of names.
398
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.base.resolve_deps.solvable(deps, names)
Return True if names form a solvable block, i.e. the set of names equals to the set of their prerequisites.
sfepy.base.resolve_deps.try_block(deps, num)
Return generator of lists of solvable blocks of the length num.
sfepy.base.testing module
class sfepy.base.testing.TestCommon(**kwargs)
static compare_vectors(vec1, vec2, allowed_error=1e-08,
norm=None)
static eval_coor_expression(expression, coor)
label1=’vec1’,
label2=’vec2’,
get_number()
static report(*argc)
All tests should print via this function.
run(debug=False)
static xfail(test_method)
Decorator that allows a test to fail.
7.8.6 sfepy.discrete package
This package implements various PDE discretization schemes (FEM or IGA).
sfepy.discrete.conditions module
The Dirichlet, periodic and linear combination boundary condition classes, as well as the initial condition class.
class sfepy.discrete.conditions.Condition(name, **kwargs)
Common boundary condition methods.
canonize_dof_names(dofs)
Canonize the DOF names using the full list of DOFs of a variable.
Assumes single condition instance.
iter_single()
Create a single condition instance for each item in self.dofs and yield it.
class sfepy.discrete.conditions.Conditions(objs=None, **kwargs)
Container for various conditions.
canonize_dof_names(dofs)
Canonize the DOF names using the full list of DOFs of a variable.
static from_conf(conf, regions)
group_by_variables(groups=None)
Group boundary conditions of each variable. Each condition is a group is a single condition.
Parameters groups : dict, optional
If present, update the groups dictionary.
Returns out : dict
7.8. Module Index
399
SfePy Documentation, Release 2015.1
The dictionary with variable names as keys and lists of single condition instances as
values.
sort()
Sort boundary conditions by their key.
zero_dofs()
Set all boundary condition values to zero, if applicable.
class sfepy.discrete.conditions.EssentialBC(name, region, dofs, key=’‘, times=None)
Essential boundary condidion.
Parameters name : str
The boundary condition name.
region : Region instance
The region where the boundary condition is applied.
dofs : dict
The boundary condition specification defining the constrained DOFs and their values.
key : str, optional
The sorting key.
times : list or str, optional
The list of time intervals or a function returning True at time steps, when the condition
applies.
zero_dofs()
Set all essential boundary condition values to zero.
class sfepy.discrete.conditions.InitialCondition(name, region, dofs, key=’‘)
Initial condidion.
Parameters name : str
The initial condition name.
region : Region instance
The region where the initial condition is applied.
dofs : dict
The initial condition specification defining the constrained DOFs and their values.
key : str, optional
The sorting key.
class sfepy.discrete.conditions.LinearCombinationBC(name, regions, dofs, dof_map_fun,
kind, key=’‘, times=None, arguments=None)
Linear combination boundary condidion.
Parameters name : str
The boundary condition name.
regions : list of two Region instances
The constrained (master) DOFs region and the new (slave) DOFs region. The latter can
be None if new DOFs are not field variable DOFs.
400
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
dofs : dict
The boundary condition specification defining the constrained DOFs and the new DOFs
(can be None).
dof_map_fun : str
The name of function for mapping the constrained DOFs to new DOFs (can be None).
kind : str
The linear combination condition kind.
key : str, optional
The sorting key.
times : list or str, optional
The list of time intervals or a function returning True at time steps, when the condition
applies.
arguments: tuple, optional :
Additional arguments, depending on the condition kind.
canonize_dof_names(dofs0, dofs1=None)
Canonize the DOF names using the full list of DOFs of a variable.
Assumes single condition instance.
get_var_names()
Get names of variables corresponding to the constrained and new DOFs.
class sfepy.discrete.conditions.PeriodicBC(name, regions, dofs, match, key=’‘, times=None)
Periodic boundary condidion.
Parameters name : str
The boundary condition name.
regions : list of two Region instances
The master region and the slave region where the DOFs should match.
dofs : dict
The boundary condition specification defining the DOFs in the master region and the
corresponding DOFs in the slave region.
match : str
The name of function for matching corresponding nodes in the two regions.
key : str, optional
The sorting key.
times : list or str, optional
The list of time intervals or a function returning True at time steps, when the condition
applies.
canonize_dof_names(dofs)
Canonize the DOF names using the full list of DOFs of a variable.
Assumes single condition instance.
7.8. Module Index
401
SfePy Documentation, Release 2015.1
sfepy.discrete.conditions.get_condition_value(val, functions, kind, name)
Check a boundary/initial condition value type and return the value or corresponding function.
sfepy.discrete.equations module
Classes of equations composed of terms.
class sfepy.discrete.equations.Equation(name, terms)
collect_conn_info(conn_info)
collect_materials()
Collect materials present in the terms of the equation.
collect_variables()
Collect variables present in the terms of the equation.
Ensures that corresponding primary variables of test/parameter variables are always in the list, even if they
are not directly used in the terms.
evaluate(mode=’eval’, dw_mode=’vector’, term_mode=None, asm_obj=None)
Parameters mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode.
static from_desc(name, desc, variables, regions, materials, integrals, user=None)
class sfepy.discrete.equations.Equations(equations)
advance(ts)
apply_ebc(vec, force_values=None)
Apply essential (Dirichlet) boundary conditions to a state vector.
apply_ic(vec, force_values=None)
Apply initial conditions to a state vector.
collect_conn_info()
Collect connectivity information as defined by the equations.
collect_materials()
Collect materials present in the terms of all equations.
collect_variables()
Collect variables present in the terms of all equations.
create_matrix_graph(any_dof_conn=False, rdcs=None, cdcs=None, shape=None, verbose=True)
Create tangent matrix graph, i.e. preallocate and initialize the sparse storage needed for the tangent matrix.
Order of DOF connectivities is not important.
Parameters any_dof_conn : bool
By default, only volume DOF connectivities are used, with the exception of trace surface
DOF connectivities. If True, any kind of DOF connectivities is allowed.
rdcs, cdcs : arrays, optional
Additional row and column DOF connectivities, corresponding to the variables used in
the equations.
402
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
shape : tuple, optional
The required shape, if it is different from the shape determined by the equations variables. This may be needed if additional row and column DOF connectivities are passed
in.
verbose : bool
If False, reduce verbosity.
Returns matrix : csr_matrix
The matrix graph in the form of a CSR matrix with preallocated structure and zero data.
create_state_vector()
create_stripped_state_vector()
create_subequations(var_names, known_var_names=None)
Create sub-equations containing only terms with the given virtual variables.
Parameters var_names : list
The list of names of virtual variables.
known_var_names : list
The list of names of (already) known state variables.
Returns subequations : Equations instance
The sub-equations.
eval_residuals(state, by_blocks=False, names=None)
Evaluate (assemble) residual vectors.
Parameters state : array
The vector of DOF values. Note that it is needed only in nonlinear terms.
by_blocks : bool
If True, return the individual blocks composing the whole residual vector. Each equation
should then correspond to one required block and should be named as ‘block_name,
test_variable_name, unknown_variable_name’.
names : list of str, optional
Optionally, select only blocks with the given names, if by_blocks is True.
Returns out : array or dict of array
The assembled residual vector. If by_blocks is True, a dictionary is returned instead,
with keys given by block_name part of the individual equation names.
eval_tangent_matrices(state, tangent_matrix, by_blocks=False, names=None)
Evaluate (assemble) tangent matrices.
Parameters state : array
The vector of DOF values. Note that it is needed only in nonlinear terms.
tangent_matrix : csr_matrix
The preallocated CSR matrix with zero data.
by_blocks : bool
7.8. Module Index
403
SfePy Documentation, Release 2015.1
If True, return the individual blocks composing the whole matrix. Each equation
should then correspond to one required block and should be named as ‘block_name,
test_variable_name, unknown_variable_name’.
names : list of str, optional
Optionally, select only blocks with the given names, if by_blocks is True.
Returns out : csr_matrix or dict of csr_matrix
The assembled matrix. If by_blocks is True, a dictionary is returned instead, with keys
given by block_name part of the individual equation names.
evaluate(names=None, mode=’eval’, dw_mode=’vector’, term_mode=None, asm_obj=None)
Evaluate the equations.
Parameters mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode.
names : str or sequence of str, optional
Evaluate only equations of the given name(s).
Returns out : dict or result
The evaluation result. In ‘weak’ mode it is the asm_obj. Otherwise, it is a dict of results
with equation names as keys or a single result for a single equation.
static from_conf(conf, variables, regions, materials, integrals, user=None, verbose=True)
get_domain()
get_graph_conns(any_dof_conn=False, rdcs=None, cdcs=None)
Get DOF connectivities needed for creating tangent matrix graph.
Parameters any_dof_conn : bool
By default, only volume DOF connectivities are used, with the exception of trace surface
DOF connectivities. If True, any kind of DOF connectivities is allowed.
rdcs, cdcs : arrays, optional
Additional row and column DOF connectivities, corresponding to the variables used in
the equations.
Returns rdcs, cdcs : arrays
The row and column DOF connectivities defining the matrix graph blocks.
get_lcbc_operator()
get_state_parts(vec=None)
Return parts of a state vector corresponding to individual state variables.
Parameters vec : array, optional
The state vector. If not given, then the data stored in the variables are returned instead.
Returns out : dict
The dictionary of the state parts.
get_variable(name)
get_variable_dependencies()
For each virtual variable get names of state/parameter variables that are present in terms with that virtual
variable.
404
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The virtual variables define the actual equations and their dependencies define the variables needed to
evaluate the equations.
Returns deps : dict
The dependencies as a dictionary with virtual variable names as keys and sets of
state/parameter variables as values.
get_variable_names()
Return the list of names of all variables used in equations.
init_time(ts)
invalidate_term_caches()
Invalidate evaluate caches of variables present in equations.
make_full_vec(svec, force_value=None)
Make a full DOF vector satisfying E(P)BCs from a reduced DOF vector.
print_terms()
Print names of equations and their terms.
reset_materials()
Clear material data so that next materials.time_update() is performed even for stationary materials.
set_data(data, step=0, ignore_unknown=False)
Set data (vectors of DOF values) of variables.
Parameters data : array
The dictionary of {variable_name : data vector}.
step : int, optional
The time history step, 0 (default) = current.
ignore_unknown : bool, optional
Ignore unknown variable names if data is a dict.
set_variables_from_state(vec, step=0)
Set data (vectors of DOF values) of variables.
Parameters data : array
The state vector.
step : int
The time history step, 0 (default) = current.
setup_initial_conditions(ics, functions)
state_to_output(vec, fill_value=None, var_info=None, extend=True)
strip_state_vector(vec, follow_epbc=False)
Strip a full vector by removing EBC dofs.
Notes
If ‘follow_epbc’ is True, values of EPBC master dofs are not simply thrown away, but added to the corresponding slave dofs, just like when assembling. For vectors with state (unknown) variables it should be
set to False, for assembled vectors it should be set to True.
7.8. Module Index
405
SfePy Documentation, Release 2015.1
time_update(ts, ebcs=None, epbcs=None, lcbcs=None, functions=None, problem=None, verbose=True)
Update the equations for current time step.
The update involves creating the mapping of active DOFs from/to all DOFs for all state variables, the setup
of linear combination boundary conditions operators and the setup of active DOF connectivities.
Parameters ts : TimeStepper instance
The time stepper.
ebcs : Conditions instance, optional
The essential (Dirichlet) boundary conditions.
epbcs : Conditions instance, optional
The periodic boundary conditions.
lcbcs : Conditions instance, optional
The linear combination boundary conditions.
functions : Functions instance, optional
The user functions for boundary conditions, materials, etc.
problem : Problem instance, optional
The problem that can be passed to user functions as a context.
verbose : bool
If False, reduce verbosity.
Returns graph_changed : bool
The flag set to True if the current time step set of active boundary conditions differs
from the set of the previous time step.
time_update_materials(ts, mode=’normal’, problem=None, verbose=True)
Update data materials for current time and possibly also state.
Parameters ts : TimeStepper instance
The time stepper.
mode : ‘normal’, ‘update’ or ‘force’
The update mode, see sfepy.discrete.materials.Material.time_update().
problem : Problem instance, optional
The problem that can be passed to user functions as a context.
verbose : bool
If False, reduce verbosity.
sfepy.discrete.equations.get_expression_arg_names(expression, strip_dots=True)
Parse expression and return set of all argument names. For arguments with attribute-like syntax (e.g. materials),
if strip_dots is True, only base argument names are returned.
sfepy.discrete.equations.parse_definition(equation_def )
Parse equation definition string to create term description list.
406
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.evaluate module
class sfepy.discrete.evaluate.BasicEvaluator(problem, matrix_hook=None)
eval_residual(vec, is_full=False)
eval_tangent_matrix(vec, mtx=None, is_full=False)
make_full_vec(vec)
new_ulf_iteration(nls, vec, it, err, err0)
class sfepy.discrete.evaluate.Evaluator(**kwargs)
class sfepy.discrete.evaluate.LCBCEvaluator(problem, matrix_hook=None)
eval_residual(vec, is_full=False)
eval_tangent_matrix(vec, mtx=None, is_full=False)
sfepy.discrete.evaluate.assemble_by_blocks(conf_equations, problem, ebcs=None, epbcs=None, dw_mode=’matrix’)
Instead of a global matrix, return its building blocks as defined in conf_equations. The name and row/column
variables of each block have to be encoded in the equation’s name, as in:
conf_equations = {
’A,v,u’ : "dw_lin_elastic_iso.i1.Y2( inclusion.lame, v, u )",
}
Notes
ebcs, epbcs must be either lists of BC names, or BC configuration dictionaries.
sfepy.discrete.evaluate.create_evaluable(expression, fields, materials, variables, integrals,
regions=None,
ebcs=None,
epbcs=None,
lcbcs=None,
ts=None,
functions=None,
auto_init=False, mode=’eval’, extra_args=None,
verbose=True, kwargs=None)
Create evaluable object (equations and corresponding variables) from the expression string.
Parameters expression : str
The expression to evaluate.
fields : dict
The dictionary of fields used in variables.
materials : Materials instance
The materials used in the expression.
variables : Variables instance
The variables used in the expression.
integrals : Integrals instance
The integrals to be used.
regions : Region instance or list of Region instances
7.8. Module Index
407
SfePy Documentation, Release 2015.1
The region(s) to be used. If not given, the regions defined within the fields domain are
used.
ebcs : Conditions instance, optional
The essential (Dirichlet) boundary conditions for ‘weak’ mode.
epbcs : Conditions instance, optional
The periodic boundary conditions for ‘weak’ mode.
lcbcs : Conditions instance, optional
The linear combination boundary conditions for ‘weak’ mode.
ts : TimeStepper instance, optional
The time stepper.
functions : Functions instance, optional
The user functions for boundary conditions, materials etc.
auto_init : bool
Set values of all variables to all zeros.
mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode - ‘weak’ means the finite element assembling, ‘qp’ requests the
values in quadrature points, ‘el_avg’ element averages and ‘eval’ means integration over
each term region.
extra_args : dict, optional
Extra arguments to be passed to terms in the expression.
verbose : bool
If False, reduce verbosity.
kwargs : dict, optional
The variables (dictionary of (variable name) : (Variable instance)) to be used in the
expression.
Returns equation : Equation instance
The equation that is ready to be evaluated.
variables : Variables instance
The variables used in the equation.
sfepy.discrete.evaluate.eval_equations(equations,
variables,
names=None,
preserve_caches=False,
mode=’eval’,
dw_mode=’vector’,
term_mode=None,
verbose=True)
Evaluate the equations.
Parameters equations : Equations instance
The equations returned by create_evaluable().
variables : Variables instance
The variables returned by create_evaluable().
names : str or sequence of str, optional
408
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Evaluate only equations of the given name(s).
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode - ‘weak’ means the finite element assembling, ‘qp’ requests the
values in quadrature points, ‘el_avg’ element averages and ‘eval’ means integration over
each term region.
dw_mode : ‘vector’ or ‘matrix’
The assembling mode for ‘weak’ evaluation mode.
term_mode : str
The term call mode - some terms support different call modes and depending on the call
mode different values are returned.
verbose : bool
If False, reduce verbosity.
Returns out : dict or result
The evaluation result. In ‘weak’ mode it is the vector or sparse matrix, depending on
dw_mode. Otherwise, it is a dict of results with equation names as keys or a single result
for a single equation.
sfepy.discrete.evaluate.eval_in_els_and_qp(expression, ig, iels, coors, fields, materials,
variables, functions=None, mode=’eval’,
term_mode=None, extra_args=None, verbose=True, kwargs=None)
Evaluate an expression in given elements and points.
Parameters expression : str
The expression to evaluate.
fields : dict
The dictionary of fields used in variables.
materials : Materials instance
The materials used in the expression.
variables : Variables instance
The variables used in the expression.
functions : Functions instance, optional
The user functions for materials etc.
mode : one of ‘eval’, ‘el_avg’, ‘qp’
The evaluation mode - ‘qp’ requests the values in quadrature points, ‘el_avg’ element
averages and ‘eval’ means integration over each term region.
term_mode : str
The term call mode - some terms support different call modes and depending on the call
mode different values are returned.
extra_args : dict, optional
7.8. Module Index
409
SfePy Documentation, Release 2015.1
Extra arguments to be passed to terms in the expression.
verbose : bool
If False, reduce verbosity.
kwargs : dict, optional
The variables (dictionary of (variable name) : (Variable instance)) to be used in the
expression.
Returns out : array
The result of the evaluation.
sfepy.discrete.evaluate_variable module
sfepy.discrete.evaluate_variable.eval_complex(vec, conn, geo, mode, shape, bf=None)
Evaluate basic derived quantities of a complex variable given its DOF vector, connectivity and reference mapping.
sfepy.discrete.evaluate_variable.eval_real(vec, conn, geo, mode, shape, bf=None)
Evaluate basic derived quantities of a real variable given its DOF vector, connectivity and reference mapping.
sfepy.discrete.functions module
class sfepy.discrete.functions.ConstantFunction(values)
Function with constant values.
class sfepy.discrete.functions.ConstantFunctionByRegion(values)
Function with constant values in regions.
class sfepy.discrete.functions.Function(name, function, is_constant=False, extra_args=None)
Base class for user-defined functions.
set_extra_args(**extra_args)
set_function(function, is_constant=False)
class sfepy.discrete.functions.Functions(objs=None, **kwargs)
Container to hold all user-defined functions.
static from_conf(conf )
sfepy.discrete.integrals module
Classes for accessing quadrature points and weights for various reference element geometries.
class sfepy.discrete.integrals.Integral(name, order=1, coors=None, weights=None,
bounds=None, tp_fix=1.0, weight_fix=1.0, symmetric=False)
Wrapper class around quadratures.
get_qp(geometry)
Get quadrature point coordinates and corresponding weights for given geometry. For built-in quadratures,
the integration order is given by self.order.
Parameters geometry : str
The geometry key describing the integration domain,
sfepy.discrete.quadratures.quadrature_tables.
410
see the keys of
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Returns coors : array
The coordinates of quadrature points.
weights: array :
The quadrature weights.
integrate(function, order=1, geometry=‘1_2’)
Integrate numerically a given scalar function.
Parameters function : callable(coors)
The function of space coordinates to integrate.
order : int, optional
The integration order. For tensor product geometries, this is the 1D (line) order.
geometry : str
The geometry key describing the integration domain. Default is ‘1_2’, i.e. a line integral
in [0, 1]. For other values see the keys of sfepy.discrete.quadratures.quadrature_tables.
Returns val : float
The value of the integral.
class sfepy.discrete.integrals.Integrals(objs=None, **kwargs)
Container for instances of Integral.
static from_conf(conf )
get(name)
Return existing or new integral.
Parameters name : str
The name can either be a non-negative integer, a string representation of a non-negative
integer (the integral order) or ‘a’ (automatic order) or a string beginning with ‘i’ (existing custom integral name).
sfepy.discrete.mass_operator module
class sfepy.discrete.mass_operator.MassOperator(problem, options)
Encapsulation of action and inverse action of a mass matrix operator 𝑀 .
action(vec)
Action of mass matrix operator on a vector: 𝑀 𝑥.
inverse_action(vec)
Inverse action of mass matrix operator on a vector: 𝑀 −1 𝑥.
sfepy.discrete.materials module
class sfepy.discrete.materials.Material(name, kind=’time-dependent’, function=None, values=None, flags=None, **kwargs)
A class holding constitutive and other material parameters.
Example input:
7.8. Module Index
411
SfePy Documentation, Release 2015.1
material_2 = {
’name’ : ’m’,
’values’ : {’E’ : 1.0},
}
Material parameters are passed to terms using the dot notation, i.e. ‘m.E’ in our example case.
static from_conf(conf, functions)
Construct Material instance from configuration.
get_constant_data(name)
Get constant data by name.
get_data(key, ig, name)
name can be a dict - then a Struct instance with data as attributes named as the dict keys is returned.
get_keys(region_name=None)
Get all data keys.
Parameters region_name : str
If not None, only keys with this region are returned.
iter_terms(equations, only_new=True)
Iterate terms for which the material data should be evaluated.
reduce_on_datas(reduce_fun, init=0.0)
For non-special values only!
reset()
Clear all data created by a call to time_update(), set self.mode to None.
set_all_data(datas)
Use the provided data, set mode to ‘user’.
set_data(key, ig, qps, data, indx)
Set the material data in quadrature points.
Parameters key : tuple
The (region_name, integral_name) data key.
ig : int
The element group id.
qps : Struct
Information about the quadrature points.
data : dict
The material data. Changes the shape of data!
indx : array
The indices of quadrature points in the group ig.
set_data_from_variable(var, name, equations)
set_extra_args(**extra_args)
Extra arguments passed tu the material function.
set_function(function)
412
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
time_update(ts, equations, mode=’normal’, problem=None)
Evaluate material parameters in physical quadrature points.
Parameters ts : TimeStepper instance
The time stepper.
equations : Equations instance
The equations using the materials.
mode : ‘normal’, ‘update’ or ‘force’
The update mode. In ‘force’ mode, self.datas is cleared and all updates are redone.
In ‘update’ mode, existing data are preserved and new can be added. The ‘normal’
mode depends on other attributes: for stationary (self.kind == ’stationary’)
materials and materials in ‘user’ mode, nothing is done if self.datas is not empty.
For time-dependent materials (self.kind == ’time-dependent’, the default)
that are not constant, i.e., are given by a user function, ‘normal’ mode behaves like
‘force’ mode. For constant materials it behaves like ‘update’ mode - existing data are
reused.
problem : Problem instance, optional
The problem that can be passed to user functions as a context.
update_data(key, ts, equations, term, problem=None)
Update the material parameters in quadrature points.
Parameters key : tuple
The (region_name, integral_name) data key.
ts : TimeStepper
The time stepper.
equations : Equations
The equations for which the update occurs.
term : Term
The term for which the update occurs.
problem : Problem, optional
The problem definition for which the update occurs.
update_special_constant_data(equations=None, problem=None)
Update the special constant material parameters.
Parameters equations : Equations
The equations for which the update occurs.
problem : Problem, optional
The problem definition for which the update occurs.
update_special_data(ts, equations, problem=None)
Update the special material parameters.
Parameters ts : TimeStepper
The time stepper.
equations : Equations
7.8. Module Index
413
SfePy Documentation, Release 2015.1
The equations for which the update occurs.
problem : Problem, optional
The problem definition for which the update occurs.
class sfepy.discrete.materials.Materials(objs=None, **kwargs)
static from_conf(conf, functions, wanted=None)
Construct Materials instance from configuration.
reset()
Clear material data so that next materials.time_update() is performed even for stationary materials.
semideep_copy(reset=True)
Copy materials, while external data (e.g. region) remain shared.
time_update(ts, equations, mode=’normal’, problem=None, verbose=True)
Update material parameters for given time, problem, and equations.
Parameters ts : TimeStepper instance
The time stepper.
equations : Equations instance
The equations using the materials.
mode : ‘normal’, ‘update’ or ‘force’
The update mode, see Material.time_update().
problem : Problem instance, optional
The problem that can be passed to user functions as a context.
verbose : bool
If False, reduce verbosity.
sfepy.discrete.parse_equations module
class sfepy.discrete.parse_equations.TermParse
sfepy.discrete.parse_equations.collect_term(term_descs, lc)
sfepy.discrete.parse_equations.create_bnf(term_descs)
term_descs .. list of TermParse objects (sign, term_name, term_arg_names), where sign can be real or complex
multiplier
sfepy.discrete.parse_equations.rhs(lc)
sfepy.discrete.parse_regions module
Grammar for selecting regions of a domain.
Regions serve for selection of certain parts of the computational domain represented as a finite element mesh. They
are used to define the boundary conditions, the domains of terms and materials etc.
414
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
History: pre-git versions already from from 13.06.2006.
sfepy.discrete.parse_regions.create_bnf(stack)
sfepy.discrete.parse_regions.join_tokens(str, loc, toks)
sfepy.discrete.parse_regions.print_leaf(level, op)
sfepy.discrete.parse_regions.print_op(level, op, item1, item2)
sfepy.discrete.parse_regions.print_stack(stack)
sfepy.discrete.parse_regions.replace(what, keep=False)
sfepy.discrete.parse_regions.replace_with_region(what, r_index)
sfepy.discrete.parse_regions.to_stack(stack)
sfepy.discrete.parse_regions.visit_stack(stack, op_visitor, leaf_visitor)
sfepy.discrete.probes module
Classes for probing values of Variables, for example, along a line.
class sfepy.discrete.probes.CircleProbe(centre,
normal,
share_geometry=True)
Probe variables along a circle.
radius,
n_point,
If n_point is positive, that number of evenly spaced points is used. If n_point is None or non-positive, an adaptive
refinement based on element diameters is used and the number of points and their spacing are determined
automatically. If it is negative, -n_point is used as an initial guess.
get_points(refine_flag=None)
Get the probe points.
Returns pars : array_like
The independent coordinate of the probe.
points : array_like
The probe points, parametrized by pars.
is_cyclic = True
report()
Report the probe parameters.
class sfepy.discrete.probes.IntegralProbe(name, problem, expressions, labels)
Evaluate integral expressions.
class sfepy.discrete.probes.LineProbe(p0, p1, n_point, share_geometry=True)
Probe variables along a line.
If n_point is positive, that number of evenly spaced points is used. If n_point is None or non-positive, an adaptive
refinement based on element diameters is used and the number of points and their spacing are determined
automatically. If it is negative, -n_point is used as an initial guess.
get_points(refine_flag=None)
Get the probe points.
Returns pars : array_like
7.8. Module Index
415
SfePy Documentation, Release 2015.1
The independent coordinate of the probe.
points : array_like
The probe points, parametrized by pars.
report()
Report the probe parameters.
class sfepy.discrete.probes.PointsProbe(points, share_geometry=True)
Probe variables in given points.
get_points(refine_flag=None)
Get the probe points.
Returns pars : array_like
The independent coordinate of the probe.
points : array_like
The probe points, parametrized by pars.
refine_points(variable, points, cache)
No refinement for this probe.
report()
Report the probe parameters.
class sfepy.discrete.probes.Probe(name, share_geometry=True, n_point=None, **kwargs)
Base class for all point probes. Enforces two points minimum.
cache = Struct:probe_shared_evaluate_cache
is_cyclic = False
probe(variable)
Probe the given variable.
Parameters variable : Variable instance
The variable to be sampled along the probe.
static refine_pars(pars, refine_flag, cyclic_val=None)
Refine the probe parametrization based on the refine_flag.
refine_points(variable, points, cells)
Mark intervals between points for a refinement, based on element sizes at those points. Assumes the points
to be ordered.
Returns refine_flag : bool array
True at places corresponding to intervals between subsequent points that need to be
refined.
report()
Report the probe parameters.
reset_refinement()
Reset the probe refinement state.
set_n_point(n_point)
Set the number of probe points.
Parameters n_point : int
416
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The (fixed) number of probe points, when positive. When non-positive, the number of
points is adaptively increased starting from -n_point, until the neighboring point distance is less than the diameter of the elements enclosing the points. When None, it is
set to -10.
set_options(close_limit=None, size_hint=None)
Set the probe options.
Parameters close_limit : float
The maximum limit distance of a point from the closest element allowed for extrapolation.
size_hint : float
Element size hint for the refinement of probe parametrization.
class sfepy.discrete.probes.RayProbe(p0,
dirvec,
p_fun,
n_point,
both_dirs,
share_geometry=True)
Probe variables along a ray. The points are parametrized by a function of radial coordinates from a given point
in a given direction.
gen_points(sign)
Generate the probe points and their parametrization.
get_points(refine_flag=None)
Get the probe points.
Returns pars : array_like
The independent coordinate of the probe.
points : array_like
The probe points, parametrized by pars.
refine_points(variable, points, cache)
No refinement for this probe.
report()
Report the probe parameters.
sfepy.discrete.probes.get_data_name(fd)
Try to read next data name in file fd.
Returns name : str
The data name.
nc : int
The number of data columns.
sfepy.discrete.probes.read_header(fd)
Read the probe data header from file descriptor fd.
Returns header : Struct instance
The probe data header.
sfepy.discrete.probes.read_results(filename, only_names=None)
Read probing results from a file.
Parameters filename : str or file object
The probe results file name.
7.8. Module Index
417
SfePy Documentation, Release 2015.1
Returns header : Struct instance
The probe data header.
results : dict
The dictionary of probing results. Keys are data names, values are the probed values.
sfepy.discrete.probes.write_results(filename, probe, results)
Write probing results into a file.
Parameters filename : str or file object
The output file name.
probe : Probe subclass instance
The probe used to obtain the results.
results : dict
The dictionary of probing results. Keys are data names, values are the probed values.
sfepy.discrete.problem module
class sfepy.discrete.problem.Problem(name, conf=None, functions=None, domain=None,
fields=None,
equations=None,
auto_conf=True,
nls=None, ls=None, ts=None, auto_solvers=True)
Problem definition, the top-level class holding all data necessary to solve a problem.
It can be constructed from a ProblemConf instance using Problem.from_conf() or directly from a problem
description file using Problem.from_conf_file()
For interactive use, the constructor requires only the equations, nls and ls keyword arguments.
advance(ts=None)
clear_equations()
copy(name=None)
Make a copy of Problem.
create_evaluable(expression, try_equations=True, auto_init=False, preserve_caches=False,
copy_materials=True, integrals=None, ebcs=None, epbcs=None, lcbcs=None,
ts=None, functions=None, mode=’eval’, var_dict=None, strip_variables=True,
extra_args=None, verbose=True, **kwargs)
Create evaluable object (equations and corresponding variables) from the expression string. Convenience
function calling create_evaluable() with defaults provided by the Problem instance self.
The evaluable can be repeatedly evaluated by calling eval_equations(), e.g. for different values of
variables.
Parameters expression : str
The expression to evaluate.
try_equations : bool
Try to get variables from self.equations. If this fails, variables can either be provided in
var_dict, as keyword arguments, or are created automatically according to the expression.
auto_init : bool
Set values of all variables to all zeros.
418
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
copy_materials : bool
Work with a copy of self.equations.materials instead of reusing them. Safe but can be
slow.
integrals : Integrals instance, optional
The integrals to be used. Automatically created as needed if not given.
ebcs : Conditions instance, optional
The essential (Dirichlet) boundary conditions for ‘weak’ mode. If not given, self.ebcs
are used.
epbcs : Conditions instance, optional
The periodic boundary conditions for ‘weak’ mode. If not given, self.epbcs are used.
lcbcs : Conditions instance, optional
The linear combination boundary conditions for ‘weak’ mode. If not given, self.lcbcs
are used.
ts : TimeStepper instance, optional
The time stepper. If not given, self.ts is used.
functions : Functions instance, optional
The user functions for boundary conditions, materials etc. If not given, self.functions
are used.
mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode - ‘weak’ means the finite element assembling, ‘qp’ requests the
values in quadrature points, ‘el_avg’ element averages and ‘eval’ means integration over
each term region.
var_dict : dict, optional
The variables (dictionary of (variable name) : (Variable instance)) to be used in the
expression. Use this if the name of a variable conflicts with one of the parameters of
this method.
strip_variables : bool
If False, the variables in var_dict or kwargs not present in the expression are added to
the actual variables as a context.
extra_args : dict, optional
Extra arguments to be passed to terms in the expression.
verbose : bool
If False, reduce verbosity.
**kwargs : keyword arguments
Additional variables can be passed as keyword arguments, see var_dict.
Returns equations : Equations instance
The equations that can be evaluated.
7.8. Module Index
419
SfePy Documentation, Release 2015.1
variables : Variables instance
The corresponding variables. Set their values and use eval_equations().
Examples
problem is Problem instance.
>>> out = problem.create_evaluable(’dq_state_in_volume_qp.i1.Omega(u)’)
>>> equations, variables = out
vec is a vector of coefficients compatible with the field of ‘u’ - let’s use all ones.
>>> vec = nm.ones((variables[’u’].n_dof,), dtype=nm.float64)
>>> variables[’u’].set_data(vec)
>>> vec_qp = eval_equations(equations, variables, mode=’qp’)
Try another vector:
>>> vec = 3 * nm.ones((variables[’u’].n_dof,), dtype=nm.float64)
>>> variables[’u’].set_data(vec)
>>> vec_qp = eval_equations(equations, variables, mode=’qp’)
create_materials(mat_names=None)
Create materials with names in mat_names. Their definitions have to be present in self.conf.materials.
Notes
This method does not change self.equations, so it should not have any side effects.
create_state()
create_subproblem(var_names, known_var_names)
Create a sub-problem with equations containing only terms with the given virtual variables.
Parameters var_names : list
The list of names of virtual variables.
known_var_names : list
The list of names of (already) known state variables.
Returns subpb : Problem instance
The sub-problem.
create_variables(var_names=None)
Create variables with names in var_names. Their definitions have to be present in self.conf.variables.
Notes
This method does not change self.equations, so it should not have any side effects.
eval_equations(names=None,
preserve_caches=False,
mode=’eval’,
dw_mode=’vector’,
term_mode=None, verbose=True)
Evaluate (some of) the problem’s equations, convenience wrapper of eval_equations().
Parameters names : str or sequence of str, optional
420
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Evaluate only equations of the given name(s).
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
mode : one of ‘eval’, ‘el_avg’, ‘qp’, ‘weak’
The evaluation mode - ‘weak’ means the finite element assembling, ‘qp’ requests the
values in quadrature points, ‘el_avg’ element averages and ‘eval’ means integration over
each term region.
dw_mode : ‘vector’ or ‘matrix’
The assembling mode for ‘weak’ evaluation mode.
term_mode : str
The term call mode - some terms support different call modes and depending on the call
mode different values are returned.
verbose : bool
If False, reduce verbosity.
Returns out : dict or result
The evaluation result. In ‘weak’ mode it is the vector or sparse matrix, depending on
dw_mode. Otherwise, it is a dict of results with equation names as keys or a single result
for a single equation.
evaluate(expression,
try_equations=True,
auto_init=False,
preserve_caches=False,
copy_materials=True, integrals=None, ebcs=None, epbcs=None, lcbcs=None, ts=None,
functions=None, mode=’eval’, dw_mode=’vector’, term_mode=None, var_dict=None,
strip_variables=True, ret_variables=False, verbose=True, extra_args=None, **kwargs)
Evaluate an expression, convenience wrapper of Problem.create_evaluable() and
eval_equations().
Parameters dw_mode : ‘vector’ or ‘matrix’
The assembling mode for ‘weak’ evaluation mode.
term_mode : str
The term call mode - some terms support different call modes and depending on the call
mode different values are returned.
ret_variables : bool
If True, return the variables that were created to evaluate the expression.
other : arguments
See docstrings of Problem.create_evaluable().
Returns out : array
The result of the evaluation.
variables : Variables instance
The variables that were created to evaluate the expression.
ret_variables is True.
Only provided if
static from_conf(conf, init_fields=True, init_equations=True, init_solvers=True)
static from_conf_file(conf_filename,
required=None,
other=None,
init_equations=True, init_solvers=True)
7.8. Module Index
init_fields=True,
421
SfePy Documentation, Release 2015.1
get_default_ts(t0=None, t1=None, dt=None, n_step=None, step=None)
get_dim(get_sym=False)
Returns mesh dimension, symmetric tensor dimension (if get_sym is True).
get_evaluator(reuse=False)
Either create a new Evaluator instance (reuse == False), or return an existing instance, created in a preceding call to Problem.init_solvers().
get_integrals(names=None)
Get integrals, initialized from problem configuration if available.
Parameters names : list, optional
If given, only the named integrals are returned.
Returns integrals : Integrals instance
The requested integrals.
get_materials()
get_mesh_coors()
get_output_name(suffix=None, extra=None, mode=None)
Return default output file name, based on the output directory, output format, step suffix and mode. If
present, the extra string is put just before the output format suffix.
get_solver_conf(name)
get_solvers()
get_time_solver(ts_conf=None, **kwargs)
Create and return a TimeSteppingSolver instance.
Notes
Also sets self.ts attribute.
get_timestepper()
get_variables(auto_create=False)
init_solvers(nls_status=None, ls_conf=None, nls_conf=None, mtx=None, presolve=False)
Create and initialize solvers.
init_time(ts)
init_variables(state)
Initialize variables with history.
is_linear()
refine_uniformly(level)
Refine the mesh uniformly level-times.
Notes
This operation resets almost everything (fields, equations, ...) - it is roughly equivalent to creating a new
Problem instance with the refined mesh.
remove_bcs()
Convenience function to remove boundary conditions.
422
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
reset()
save_ebc(filename, ebcs=None, epbcs=None, force=True, default=0.0)
Save essential boundary conditions as state variables.
Parameters filename : str
The output file name.
ebcs : Conditions instance, optional
The essential (Dirichlet) boundary conditions. If not given, self.conf.ebcs are used.
epbcs : Conditions instance, optional
The periodic boundary conditions. If not given, self.conf.epbcs are used.
force : bool
If True, sequential nonzero values are forced to individual ebcs so that the conditions
are visible even when zero.
default : float
The default constant value of state vector.
save_field_meshes(filename_trunk)
save_regions(filename_trunk, region_names=None)
Save regions as meshes.
Parameters filename_trunk : str
The output filename without suffix.
region_names : list, optional
If given, only the listed regions are saved.
save_regions_as_groups(filename_trunk, region_names=None)
Save regions in a single mesh but mark them by using different element/node group numbers.
See Domain.save_regions_as_groups() for more details.
Parameters filename_trunk : str
The output filename without suffix.
region_names : list, optional
If given, only the listed regions are saved.
save_state(filename, state=None, out=None, fill_value=None, post_process_hook=None, linearization=None, file_per_var=False, **kwargs)
Parameters file_per_var : bool or None
If True, data of each variable are stored in a separate file. If None, it is set to the
application option value.
linearization : Struct or None
The linearization configuration for higher order approximations. If its kind is ‘adaptive’,
file_per_var is assumed True.
select_bcs(ebc_names=None, epbc_names=None, lcbc_names=None, create_matrix=False)
select_materials(material_names, only_conf=False)
select_variables(variable_names, only_conf=False)
7.8. Module Index
423
SfePy Documentation, Release 2015.1
set_bcs(ebcs=None, epbcs=None, lcbcs=None)
Update boundary conditions.
set_equations(conf_equations=None, user=None, keep_solvers=False, make_virtual=False)
Set equations of the problem using the equations problem description entry.
Fields and Regions have to be already set.
set_equations_instance(equations, keep_solvers=False)
Set equations of the problem to equations.
set_fields(conf_fields=None)
set_linear(is_linear)
set_materials(conf_materials=None)
Set definition of materials.
set_mesh_coors(coors, update_fields=False, actual=False, clear_all=True)
Set mesh coordinates.
Parameters coors : array
The new coordinates.
update_fields : bool
If True, update also coordinates of fields.
actual : bool
If True, update the actual configuration coordinates, otherwise the undeformed configuration ones.
set_output_dir(output_dir=None)
Set the directory for output files.
The directory is created if it does not exist.
set_regions(conf_regions=None, conf_materials=None, functions=None)
set_solvers(conf_solvers=None, options=None)
Choose which solvers should be used. If solvers are not set in options, use first suitable in conf_solvers.
set_solvers_instances(ls=None, nls=None)
Set the instances of linear and nonlinear solvers that will be used in Problem.solve() call.
set_variables(conf_variables=None)
Set definition of variables.
setup_default_output(conf=None, options=None)
Provide default values to Problem.setup_output() from conf.options and options.
setup_hooks(options=None)
Setup various hooks (user-defined functions), as given in options.
Supported hooks:
•matrix_hook
–check/modify tangent matrix in each nonlinear solver iteration
•nls_iter_hook
–called prior to every iteration of nonlinear solver, if the solver supports that
–takes the Problem instance (self ) as the first argument
424
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
setup_ic(conf_ics=None, functions=None)
setup_output(output_filename_trunk=None,
output_dir=None,
output_format=None,
float_format=None, file_per_var=None, linearization=None)
Sets output options to given values, or uses the defaults for each argument that is None.
solve(state0=None, nls_status=None, ls_conf=None,
var_data=None)
Solve self.equations in current time step.
nls_conf=None,
force_values=None,
Parameters var_data : dict
A dictionary of {variable_name : data vector} used to initialize parameter variables.
time_update(ts=None,
ebcs=None,
ate_matrix=False)
epbcs=None,
lcbcs=None,
functions=None,
cre-
update_equations(ts=None, ebcs=None, epbcs=None, lcbcs=None, functions=None, create_matrix=False)
Update equations for current time step.
The tangent matrix graph is automatically recomputed if the set of active essential or periodic boundary
conditions changed w.r.t. the previous time step.
Parameters ts : TimeStepper instance, optional
The time stepper. If not given, self.ts is used.
ebcs : Conditions instance, optional
The essential (Dirichlet) boundary conditions. If not given, self.ebcs are used.
epbcs : Conditions instance, optional
The periodic boundary conditions. If not given, self.epbcs are used.
lcbcs : Conditions instance, optional
The linear combination boundary conditions. If not given, self.lcbcs are used.
functions : Functions instance, optional
The user functions for boundary conditions, materials, etc. If not given, self.functions
are used.
update_materials(ts=None, mode=’normal’, verbose=True)
Update materials used in equations.
Parameters ts : TimeStepper instance
The time stepper.
mode : ‘normal’, ‘update’ or ‘force’
The update mode, see Material.time_update().
verbose : bool
If False, reduce verbosity.
update_time_stepper(ts)
sfepy.discrete.projections module
Construct projections between FE spaces.
7.8. Module Index
425
SfePy Documentation, Release 2015.1
sfepy.discrete.projections.create_mass_matrix(field)
Create scalar mass matrix corresponding to the given field.
Returns mtx : csr_matrix
The mass matrix in CSR format.
sfepy.discrete.projections.make_h1_projection_data(target, eval_data)
Project scalar data given by a material-like eval_data() function to a scalar target field variable using the 𝐻 1 dot
product.
sfepy.discrete.projections.make_l2_projection(target, source, ls=None)
Project a scalar source field variable to a scalar target field variable using the 𝐿2 dot product.
sfepy.discrete.projections.make_l2_projection_data(target, eval_data, order=None,
ls=None)
Project scalar data to a scalar target field variable using the 𝐿2 dot product.
Parameters target : FieldVariable instance
The target variable.
eval_data : callable or array
Either a material-like function eval_data(), or an array of values in quadrature points
that has to be reshapable to the shape required by order.
order : int, optional
The quadrature order. If not given, it is set to 2 * target.field.approx_order.
sfepy.discrete.quadratures module
quadrature_tables are organized as follows:
quadrature_tables = {
’<geometry1>’ : {
order1 : QuadraturePoints(args1),
order2 : QuadraturePoints(args2),
...
},
’<geometry2>’ : {
order1 : QuadraturePoints(args1),
order2 : QuadraturePoints(args2),
...
},
...
}
Note The order for quadratures on tensor product domains (‘2_4’, ‘3_8’ geometries) in case of composite Gauss
quadratures (products of 1D quadratures) holds for each component separately, so the actual polynomial order may be
much higher (up to order * dimension).
Naming conventions in problem description files:
‘<family>_<order>_<dimension>‘
Integral ‘family’ is just an arbitrary name given by user.
Low order quadrature coordinates and weights copied from The Finite Element Method Displayed by Gouri Dhatt and
Gilbert Touzat, Wiley-Interscience Production, 1984.
426
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The line integral (geometry ‘1_2’) coordinates and weights are from Abramowitz, M. and Stegun, I.A., Handbook
of Mathematical Functions, Dover Publications, New York, 1972. The triangle (geometry ‘2_3’) coordinates and
weights are from Dunavant, D.A., High Degree Efficient Symmetrical Gaussian Quadrature Rules for the Triangle,
Int. J. Num. Meth. Eng., 21 (1985) pp 1129-1148 - only rules with points inside the reference triangle are used. The
actual values were copied from PHAML (http://math.nist.gov/phaml/), see also Mitchell, W.F., PHAML User’s Guide,
NISTIR 7374, 2006.
Quadrature rules for the quadrilateral (geometry ‘2_4’) and hexahedron (geometry ‘3_8’) of order higher than 5 are
computed as the tensor product of the line (geometry ‘1_2’) rules.
Quadrature rules for the triangle (geometry ‘2_3’) and tetrahedron (geometry ‘3_4’) of order higher than 19 and 6, respectively follow A. Grundmann and H.M. Moeller, Invariant integration formulas for the n-simplex by combinatorial
methods, SIAM J. Numer. Anal. 15 (1978), 282–290. The generating function was adapted from pytools/hegde codes
(http://mathema.tician.de/software/hedge) by Andreas Kloeckner.
class sfepy.discrete.quadratures.QuadraturePoints(data, coors=None, weights=None,
bounds=None,
tp_fix=1.0,
weight_fix=1.0, symmetric=False)
Representation of a set of quadrature points.
Parameters data : array_like
The array of shape (n_point, dim + 1) of quadrature point coordinates (first dim
columns) and weights (the last column).
coors : array_like, optional
Optionally, instead of using data, the coordinates and weights can be provided separately - data are then ignored.
weights : array_like, optional
Optionally, instead of using data, the coordinates and weights can be provided separately - data are then ignored.
bounds : (float, float), optional
The coordinates and weights should correspond to a reference element in [0, 1] x dim.
Provide the correct bounds if this is not the case.
tp_fix : float, optional
The value that is used to multiply the tensor product element volume (= 1.0) to get the
correct volume.
weight_fix : float, optional
The value that is used to multiply the weights to get the correct values.
symmetric : bool
If True, the integral is 1D and the given coordinates and weights are symmetric w.r.t.
the centre of bounds; only the non-negative coordinates are given.
static from_table(geometry, order)
Create a new QuadraturePoints instance, given reference element geometry name and polynomial
order. For tensor product geometries, the polynomial order is the 1D (line) order.
sfepy.discrete.quadratures.get_actual_order(geometry, order)
Return the actual integration order for given geometry.
Parameters geometry : str
The geometry key describing the integration domain, see the keys of quadrature_tables.
7.8. Module Index
427
SfePy Documentation, Release 2015.1
Returns order : int
If order is in quadrature tables it is this value. Otherwise it is the closest higher order. If
no higher order is available, a warning is printed and the highest available order is used.
sfepy.discrete.simplex_cubature module
Generate simplex quadrature points. Code taken and adapted from pytools/hedge by Andreas Kloeckner.
sfepy.discrete.simplex_cubature.factorial(n)
sfepy.discrete.simplex_cubature.generate_decreasing_nonnegative_tuples_summing_to(n,
length,
min=0,
max=None)
sfepy.discrete.simplex_cubature.generate_permutations(original)
Generate all permutations of the list ‘original’.
Nicked from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252178
sfepy.discrete.simplex_cubature.generate_unique_permutations(original)
Generate all unique permutations of the list ‘original’.
sfepy.discrete.simplex_cubature.get_simplex_cubature(order, dimension)
Cubature on an M{n}-simplex.
cf. A. Grundmann and H.M. Moeller, Invariant integration formulas for the n-simplex by combinatorial methods,
SIAM J. Numer. Anal. 15 (1978), 282–290.
This cubature rule has both negative and positive weights. It is exact for polynomials up to order 2𝑠 + 1, where
𝑠 is given as order. The integration domain is the unit simplex
∑︁
𝑇𝑛 := {(𝑥1 , . . . , 𝑥𝑛 ) : 𝑥𝑖 ≥ −1,
𝑥𝑖 ≤ −1}
𝑖
sfepy.discrete.simplex_cubature.wandering_element(length, wanderer=1, landscape=0)
sfepy.discrete.state module
Module for handling state variables.
class sfepy.discrete.state.State(variables, vec=None, preserve_caches=False)
Class holding/manipulating the state variables and corresponding DOF vectors.
Manipulating the state class changes the underlying variables, and hence also the corresponding equations/terms
(if any).
Notes
This class allows working with LCBC conditions in time-dependent problems, as it keeps track of the
reduced DOF vector that cannot be reconstructed from the full DOF vector by using the usual variables.strip_state_vector().
apply_ebc(force_values=None)
Apply essential (Dirichlet) boundary conditions to the state.
apply_ic(force_values=None)
Apply initial conditions to the state.
428
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
copy(deep=False, preserve_caches=False)
Copy the state. By default, the new state contains the same variables, and creates new DOF vectors. If
deep is True, also the DOF vectors are copied.
Parameters deep : bool
If True, make a copy of the DOF vectors.
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
create_output_dict(fill_value=None, var_info=None, extend=True, linearization=None)
Transforms state to an output dictionary, that can be passed as ‘out’ kwarg to Mesh.write().
Then the dictionary entries are formed by components of the state vector corresponding to unknown variables according to kind of linearization given by linearization.
Examples
>>> out = state.create_output_dict()
>>> problem.save_state(’file.vtk’, out=out)
fill(value)
Fill the DOF vector with given value.
static from_variables(variables)
Create a State instance for the given variables.
The DOF vector is created using the DOF data in variables.
Parameters variables : Variables instance
The variables.
get_parts()
Return parts of the DOF vector corresponding to individual state variables.
Returns out : dict
The dictionary of the DOF vector parts.
get_reduced(follow_epbc=False)
Get the reduced DOF vector, with EBC and PBC DOFs removed.
get_weighted_norm(vec, weights=None, return_weights=False)
Return the weighted norm of DOF vector vec.
By default, each component of vec is weighted by the 1/norm of the corresponding state part, or 1 if the
norm is zero. Alternatively, the weights can be provided explicitly using weights argument.
Parameters vec : array
The DOF vector corresponding to the variables.
weights : dict, optional
If given, the weights are used instead of the norms of the state parts. Keys of the dictionary must be equal to the names of variables comprising the DOF vector.
return_weights: bool :
If True, return also the used weights.
Returns norm : float
7.8. Module Index
429
SfePy Documentation, Release 2015.1
The weighted norm.
weights : dict, optional
If return_weights is True, the used weights.
Examples
>>> err = state0.get_weighted_norm(state() - state0())
has_ebc()
Test whether the essential (Dirichlet) boundary conditions have been applied to the DOF vector.
init_history()
Initialize variables with history.
set_full(vec, var_name=None, force=False)
Set the full DOF vector (including EBC and PBC DOFs). If var_name is given, set only the DOF subvector corresponding to the given variable. If force is True, setting variables with LCBC DOFs is allowed.
set_parts(parts, force=False)
Set parts of the DOF vector corresponding to individual state variables.
Parameters parts : dict
The dictionary of the DOF vector parts.
set_reduced(r_vec, preserve_caches=False)
Set the reduced DOF vector, with EBC and PBC DOFs removed.
Parameters r_vec : array
The reduced DOF vector corresponding to the variables.
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
sfepy.discrete.variables module
Classes of variables for equations/terms.
class sfepy.discrete.variables.CloseNodesIterator(field,
create_mesh=True,
create_graph=True, strategy=None)
get_permutation(strategy=None)
next()
test_permutations(strategy=’rcm’)
class sfepy.discrete.variables.FieldVariable(name, kind, field,
mary_var_name=None,
flags=None, **kwargs)
A finite element field variable.
order=None, prispecial=None,
field .. field description of variable (borrowed)
apply_ebc(vec, offset=0, force_values=None)
Apply essential (Dirichlet) and periodic boundary conditions to vector vec, starting at offset.
430
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
apply_ic(vec, offset=0, force_values=None)
Apply initial conditions conditions to vector vec, starting at offset.
clear_bases()
Clear base functions, base function gradients and element data dimensions.
clear_current_group()
Clear current group data.
clear_evaluate_cache()
Clear current evaluate cache.
create_output(vec=None, key=None, extend=True, fill_value=None, linearization=None)
Convert the DOF vector to a dictionary of output data usable by Mesh.write().
Parameters vec : array, optional
An alternative DOF vector to be used instead of the variable DOF vector.
key : str, optional
The key to be used in the output dictionary instead of the variable name.
extend : bool
Extend the DOF values to cover the whole domain.
fill_value : float or complex
The value used to fill the missing DOF values if extend is True.
linearization : Struct or None
The linearization configuration for higher order approximations.
equation_mapping(bcs, var_di, ts, functions, problem=None, warn=False)
Create the mapping of active DOFs from/to all DOFs.
Sets n_adof.
Returns active_bcs : set
The set of boundary conditions active in the current time.
evaluate(ig,
mode=’val’,
region=None,
integral=None,
integration=None,
step=0,
time_derivative=None, is_trace=False, dt=None, bf=None)
Evaluate various quantities related to the variable according to mode in quadrature points defined by integral.
The evaluated data are cached in the variable instance in evaluate_cache attribute.
Parameters ig : int
The element group index.
mode : one of ‘val’, ‘grad’, ‘div’, ‘cauchy_strain’
The evaluation mode.
region : Region instance, optional
The region where the evaluation occurs. If None, the underlying field region is used.
integral : Integral instance, optional
The integral defining quadrature points in which the evaluation occurs. If None, the first
order volume integral is created. Must not be None for surface integrations.
integration : one of ‘volume’, ‘plate’, ‘surface’, ‘surface_extra’
7.8. Module Index
431
SfePy Documentation, Release 2015.1
The term integration type. If None, it is derived from integral.
step : int, default 0
The time step (0 means current, -1 previous, ...).
derivative : None or ‘dt’
If not None, return time derivative of the data, approximated by the backward finite
difference.
is_trace : bool, default False
Indicate evaluation of trace of the variable on a boundary region.
dt : float, optional
The time step to be used if derivative is ‘dt’. If None, the dt attribute of the variable is
used.
bf : Base function, optional
The base function to be used in ‘val’ mode.
Returns out : array
The 4-dimensional array of shape (n_el, n_qp, n_row, n_col) with the requested data,
where n_row, n_col depend on mode.
evaluate_at(coors,
strategy=’kdtree’,
close_limit=0.1,
cache=None,
ret_cells=False,
ret_status=False, ret_ref_coors=False, verbose=True)
Evaluate the variable in the given physical coordinates.
Convenience wrapper around
Field.evaluate_at(), see its docstring for more details.
get_approximation(ig)
get_component_indices()
Return indices of variable components according to current term evaluation mode.
Returns indx : list of tuples
The list of (ii, slice(ii, ii + 1)) of the variable components. The first item is the index itself, the second item is a convenience slice to index components of material parameters.
get_data_shape(ig, integral, integration=’volume’, region_name=None)
Get element data dimensions for given approximation.
Parameters ig : int
The element group index.
integral : Integral instance
The integral describing used numerical quadrature.
integration : ‘volume’, ‘plate’, ‘surface’, ‘surface_extra’ or ‘point’
The term integration type.
region_name : str
The name of surface region, required when shape_kind is ‘surface’.
Returns data_shape : 5 ints
The (n_el, n_qp, dim, n_en, n_comp) for volume shape kind, (n_fa, n_qp, dim, n_fn,
n_comp) for surface shape kind and (n_nod, 0, 0, 1, n_comp) for point shape kind.
432
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
•n_el, n_fa = number of elements/facets
•n_qp = number of quadrature points per element/facet
•dim = spatial dimension
•n_en, n_fn = number of element/facet nodes
•n_comp = number of variable components in a point/node
•n_nod = number of element nodes
get_dof_conn(dc_type, ig, is_trace=False)
Get active dof connectivity of a variable.
Notes
The primary and dual variables must have the same Region.
get_dof_info(active=False)
get_element_diameters(cells, mode, square=False)
Get diameters of selected elements.
get_element_zeros()
Return array of zeros with correct shape and type for term evaluation.
get_field()
get_full(r_vec, r_offset=0, force_value=None, vec=None, offset=0)
Get the full DOF vector satisfying E(P)BCs from a reduced DOF vector.
Notes
The reduced vector starts in r_vec at r_offset. Passing a force_value overrides the EBC values. Optionally,
vec argument can be provided to store the full vector (in place) starting at offset.
get_interp_coors(strategy=’interpolation’, interp_term=None)
Get the physical coordinates to interpolate into, based on the strategy used.
get_mapping(ig, region, integral, integration, get_saved=False, return_key=False)
Get the reference element mapping of the underlying field.
See also:
sfepy.discrete.fem.fields.Field.get_mapping
get_reduced(vec, offset=0, follow_epbc=False)
Get the reduced DOF vector, with EBC and PBC DOFs removed.
Notes
The full vector starts in vec at offset. If ‘follow_epbc’ is True, values of EPBC master DOFs are not simply
thrown away, but added to the corresponding slave DOFs, just like when assembling. For vectors with
state (unknown) variables it should be set to False, for assembled vectors it should be set to True.
get_state_in_region(region, igs=None, reshape=True, step=0)
7.8. Module Index
433
SfePy Documentation, Release 2015.1
grad(ic=None, ider=None)
Return base function gradient (space elements) values in quadrature points.
Parameters ic : int, optional
The index of variable component.
ider : int, optional
The spatial derivative index. If not given, the whole gradient is returned.
grad_qp(ic=None, ider=None)
Return variable gradient evaluated in quadrature points.
Parameters ic : int, optional
The index of variable component.
ider : int, optional
The spatial derivative index. If not given, the whole gradient is returned.
has_same_mesh(other)
Returns flag : int
The flag can be either ‘different’ (different meshes), ‘deformed’ (slightly deformed
same mesh), or ‘same’ (same).
invalidate_evaluate_cache(step=0)
Invalidate variable data in evaluate cache for time step given by step (0 is current, -1 previous, ...).
This should be done, for example, prior to every nonlinear solver iteration.
iter_dofs()
Iterate over element DOFs (DOF by DOF).
save_as_mesh(filename)
Save the field mesh and the variable values into a file for visualization. Only the vertex values are stored.
set_current_group(geo_key, ig)
Set current group data, initialize current DOF counter to None.
The current group data are the approximation, element data dimensions, base functions and base function
gradients.
set_data_from_qp(data_qp, integral, step=0)
Set DOFs of variable using values in quadrature points corresponding to the given integral.
set_from_mesh_vertices(data)
Set the variable using values at the mesh vertices.
set_from_other(other, strategy=’projection’, search_strategy=’kdtree’, ordering_strategy=’rcm’,
close_limit=0.1)
Set the variable using another variable. Undefined values (e.g. outside the other mesh) are set to
numpy.nan, or extrapolated.
Parameters strategy : ‘projection’ or ‘interpolation’
The strategy to set the values: the L^2 orthogonal projection, or a direct interpolation to
the nodes (nodal elements only!)
434
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
If the other variable uses the same field mesh, the coefficients are set directly.
If the other variable uses the same field mesh, only deformed slightly, it is advisable to provide directly
the node ids as a hint where to start searching for a containing element; the order of nodes does not matter
then.
Otherwise (large deformation, unrelated meshes, ...) there are basically two ways: a) query each node (its
coordinates) using a KDTree of the other nodes - this completely disregards the connectivity information;
b) iterate the mesh nodes so that the subsequent ones are close to each other - then also the elements of
the other mesh should be close to each other: the previous one can be used as a start for the directional
neighbour element crawling to the target point.
Not sure which way is faster, depends on implementation efficiency and the particular meshes.
setup_bases(geo_key, ig, geo, integral, shape_kind=’volume’)
Setup and cache base functions and base function gradients for given geometry. Also cache element data
dimensions.
setup_initial_conditions(ics, di, functions, warn=False)
Setup of initial conditions.
time_update(ts, functions)
Store time step, set variable data for variables with the setter function.
val(ic=None)
Return base function values in quadrature points.
Parameters ic : int, optional
The index of variable component.
val_qp(ic=None)
Return variable evaluated in quadrature points.
Parameters ic : int, optional
The index of variable component.
class sfepy.discrete.variables.Variable(name, kind, order=None, primary_var_name=None,
special=None, flags=None, **kwargs)
advance(ts)
Advance in time the DOF state history. A copy of the DOF vector is made to prevent history modification.
static from_conf(key, conf, fields)
get_dual()
Get the dual variable.
Returns var : Variable instance
The primary variable for non-state variables, or the dual variable for state variables.
get_initial_condition()
get_primary()
Get the corresponding primary variable.
Returns var : Variable instance
The primary variable, or self for state variables or if primary_var_name is None, or
None if no other variables are defined.
7.8. Module Index
435
SfePy Documentation, Release 2015.1
get_primary_name()
init_data(step=0)
Initialize the dof vector data of time step step to zeros.
init_history()
Initialize data of variables with history.
is_complex()
is_finite(step=0, derivative=None, dt=None)
is_kind(kind)
is_parameter()
is_real()
is_state()
is_state_or_parameter()
is_virtual()
static reset()
set_constant(val)
Set the variable to a constant value.
set_data(data=None, indx=None, step=0, preserve_caches=False)
Set data (vector of DOF values) of the variable.
Parameters data : array
The vector of DOF values.
indx : int, optional
If given, data[indx] is used.
step : int, optional
The time history step, 0 (default) = current.
preserve_caches : bool
If True, do not invalidate evaluate caches of the variable.
time_update(ts, functions)
Implemented in subclasses.
class sfepy.discrete.variables.Variables(variables=None)
Container holding instances of Variable.
advance(ts)
apply_ebc(vec, force_values=None)
Apply essential (Dirichlet) and periodic boundary conditions defined for the state variables to vector vec.
apply_ic(vec, force_values=None)
Apply initial conditions defined for the state variables to vector vec.
check_vector_size(vec, stripped=False)
Check whether the shape of the DOF vector corresponds to the total number of DOFs of the state variables.
Parameters vec : array
The vector of DOF values.
436
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
stripped : bool
If True, the size of the DOF vector should be reduced, i.e. without DOFs fixed by
boundary conditions.
create_state_vector()
create_stripped_state_vector()
equation_mapping(ebcs, epbcs, ts, functions, problem=None)
Create the mapping of active DOFs from/to all DOFs for all state variables.
Returns active_bcs : set
The set of boundary conditions active in the current time.
static from_conf(conf, fields)
This method resets the variable counters for automatic order!
get_dual_names()
Get names of pairs of dual variables.
Returns duals : dict
The dual names as virtual name : state name pairs.
get_indx(var_name, stripped=False, allow_dual=False)
get_lcbc_operator()
get_matrix_shape()
get_state_part_view(state, var_name, stripped=False)
get_state_parts(vec=None)
Return parts of a state vector corresponding to individual state variables.
Parameters vec : array, optional
The state vector. If not given, then the data stored in the variables are returned instead.
Returns out : dict
The dictionary of the state parts.
has_ebc(vec, force_values=None)
has_virtuals()
init_history()
iter_state(ordered=True)
link_duals()
Link state variables with corresponding virtual variables, and assign link to self to each variable instance.
Usually, when solving a PDE in the weak form, each state variable has a corresponding virtual variable.
make_full_vec(svec, force_value=None)
Make a full DOF vector satisfying E(P)BCs from a reduced DOF vector.
Parameters svec : array
The reduced DOF vector.
force_value : float, optional
Passing a force_value overrides the EBC values.
7.8. Module Index
437
SfePy Documentation, Release 2015.1
Returns vec : array
The full DOF vector.
set_adof_conns(adof_conns)
Set all active DOF connectivities to self as well as relevant sub-dicts to the individual variables.
set_data(data, step=0, ignore_unknown=False, preserve_caches=False)
Set data (vectors of DOF values) of variables.
Parameters data : array
The state vector or dictionary of {variable_name : data vector}.
step : int, optional
The time history step, 0 (default) = current.
ignore_unknown : bool, optional
Ignore unknown variable names if data is a dict.
preserve_caches : bool
If True, do not invalidate evaluate caches of variables.
set_data_from_state(var_names, state, var_names_state)
Set variables with names in var_names from state variables with names in var_names_state using DOF
values in the state vector state.
set_state_part(state, part, var_name, stripped=False)
setup_dof_info(make_virtual=False)
Setup global DOF information.
setup_dtype()
Setup data types of state variables - all have to be of the same data type, one of nm.float64 or
nm.complex128.
setup_initial_conditions(ics, functions)
setup_lcbc_operators(lcbcs, ts=None, functions=None)
Prepare linear combination BC operator matrix and right-hand side vector.
setup_ordering()
Setup ordering of variables.
state_to_output(vec, fill_value=None, var_info=None, extend=True, linearization=None)
Convert a state vector to a dictionary of output data usable by Mesh.write().
strip_state_vector(vec, follow_epbc=False)
Get the reduced DOF vector, with EBC and PBC DOFs removed.
Notes
If ‘follow_epbc’ is True, values of EPBC master dofs are not simply thrown away, but added to the corresponding slave dofs, just like when assembling. For vectors with state (unknown) variables it should be
set to False, for assembled vectors it should be set to True.
time_update(ts, functions, verbose=True)
sfepy.discrete.variables.create_adof_conn(eq, conn, dpn, offset)
Given a node connectivity, number of DOFs per node and equation mapping, create the active dof connectivity.
438
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Locally (in a connectivity row), the DOFs are stored DOF-by-DOF (u_0 in all local nodes, u_1 in all local nodes,
...).
Globally (in a state vector), the DOFs are stored node-by-node (u_0, u_1, ..., u_X in node 0, u_0, u_1, ..., u_X
in node 1, ...).
sfepy.discrete.variables.create_adof_conns(conn_info, var_indx=None, verbose=True)
Create active DOF connectivities for all variables referenced in conn_info.
If a variable has not the equation mapping, a trivial mapping is assumed and connectivity with all DOFs active
is created.
DOF connectivity key is a tuple (primary variable name, region name, type, ig,
is_trace flag).
sfepy.discrete.common sub-package
Common lower-level code and parent classes for FEM and IGA.
sfepy.discrete.common.dof_info module
Classes holding information on global DOFs and mapping of all DOFs - equations (active DOFs).
Helper functions for the equation mapping.
class sfepy.discrete.common.dof_info.DofInfo(name)
Global DOF information, i.e. ordering of DOFs of the state (unknown) variables in the global state vector.
append_raw(name, n_dof )
Append raw DOFs.
Parameters name : str
The name of variable the DOFs correspond to.
n_dof : int
The number of DOFs.
append_variable(var, active=False)
Append DOFs of the given variable.
Parameters var : Variable instance
The variable to append.
active : bool, optional
When True, only active (non-constrained) DOFs are considered.
get_info(var_name)
Return information on DOFs of the given variable.
Parameters var_name : str
The name of the variable.
get_n_dof_total()
Return the total number of DOFs of all state variables.
get_subset_info(var_names)
Return global DOF information for selected variables only. Silently ignores non-existing variable names.
7.8. Module Index
439
SfePy Documentation, Release 2015.1
Parameters var_names : list
The names of the selected variables.
update(name, n_dof )
Set the number of DOFs of the given variable.
Parameters name : str
The name of variable the DOFs correspond to.
n_dof : int
The number of DOFs.
class sfepy.discrete.common.dof_info.EquationMap(name, dof_names, var_di)
Map all DOFs to equations for active DOFs.
get_operator()
Get the matrix operator 𝑅 corresponding to the equation mapping, such that the restricted matrix 𝐴𝑟 can
be obtained from the full matrix 𝐴 by 𝐴𝑟 = 𝑅𝑇 𝐴𝑅. All the matrices are w.r.t. a single variables that uses
this mapping.
Returns mtx : coo_matrix
The matrix 𝑅.
map_equations(bcs, field, ts, functions, problem=None, warn=False)
Create the mapping of active DOFs from/to all DOFs.
Parameters bcs : Conditions instance
The Dirichlet or periodic boundary conditions (single condition instances). The dof
names in the conditions must already be canonized.
field : Field instance
The field of the variable holding the DOFs.
ts : TimeStepper instance
The time stepper.
functions : Functions instance
The registered functions.
problem : Problem instance, optional
The problem that can be passed to user functions as a context.
warn : bool, optional
If True, warn about BC on non-existent nodes.
Returns active_bcs : set
The set of boundary conditions active in the current time.
Notes
•Periodic bc: master and slave DOFs must belong to the same field (variables can differ, though).
sfepy.discrete.common.dof_info.expand_nodes_to_dofs(nods, n_dof_per_node)
Expand DOF node indices into DOFs given a constant number of DOFs per node.
440
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.common.dof_info.expand_nodes_to_equations(nods,
dof_names,
all_dof_names)
Expand vector of node indices to equations (DOF indices) based on the DOF-per-node count.
DOF names must be already canonized.
sfepy.discrete.common.dof_info.group_chains(chain_list)
Group EPBC chains.
sfepy.discrete.common.dof_info.is_active_bc(bc, ts=None, functions=None)
Check whether the given boundary condition is active in the current time.
Returns active : bool
True if the condition bc is active.
sfepy.discrete.common.dof_info.resolve_chains(master_slave, chains)
Resolve EPBC chains - e.g. in corner nodes.
sfepy.discrete.common.domain module
class sfepy.discrete.common.domain.Domain(name, mesh=None, nurbs=None, bmesh=None, regions=None, verbose=False)
create_region(name, select, kind=’cell’, parent=None, check_parents=True, functions=None,
add_to_regions=True)
Region factory constructor. Append the new region to self.regions list.
create_regions(region_defs, functions=None)
get_centroids(dim)
Return the coordinates of centroids of mesh entities with dimension dim.
has_faces()
reset_regions()
Reset the list of regions associated with the domain.
save_regions(filename, region_names=None)
Save regions as individual meshes.
Parameters filename : str
The output filename.
region_names : list, optional
If given, only the listed regions are saved.
save_regions_as_groups(filename, region_names=None)
Save regions in a single mesh but mark them by using different element/node group numbers.
If regions overlap, the result is undetermined, with exception of the whole domain region, which is marked
by group id 0.
Region masks are also saved as scalar point data for output formats that support this.
Parameters filename : str
The output filename.
region_names : list, optional
If given, only the listed regions are saved.
7.8. Module Index
441
SfePy Documentation, Release 2015.1
sfepy.discrete.common.domain.region_leaf(domain, regions, rdef, functions)
Create/setup a region instance according to rdef.
sfepy.discrete.common.domain.region_op(level, op_code, item1, item2)
sfepy.discrete.common.fields module
class sfepy.discrete.common.fields.Field(**kwargs)
Base class for fields.
clear_mappings(clear_all=False)
Clear current reference mappings.
static from_args(name,
dtype,
shape,
region,
approx_order=1,
poly_space_base=’lagrange’)
Create a Field subclass instance corresponding to a given space.
space=’H1’,
Parameters name : str
The field name.
dtype : numpy.dtype
The field data type: float64 or complex128.
shape : int/tuple/str
The field shape: 1 or (1,) or ‘scalar’, space dimension (2, or (2,) or 3 or (3,)) or ‘vector’,
or a tuple. The field shape determines the shape of the FE base functions and is related
to the number of components of variables and to the DOF per node count, depending on
the field kind.
region : Region
The region where the field is defined.
approx_order : int/str
The FE approximation order, e.g. 0, 1, 2, ‘1B’ (1 with bubble).
space : str
The function space name.
poly_space_base : str
The name of polynomial space base.
Notes
Assumes one cell type for the whole region!
static from_conf(conf, regions)
Create a Field subclass instance based on the configuration.
get_dofs_in_region(region, merge=False, clean=False, warn=False, igs=None)
Return indices of DOFs that belong to the given region.
get_mapping(ig, region, integral, integration, get_saved=False, return_key=False)
For given region, integral and integration type, get a reference mapping, i.e. jacobians, element volumes and base function derivatives for Volume-type geometries, and jacobians, normals and base function
derivatives for Surface-type geometries corresponding to the field approximation.
442
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The mappings are cached in the field instance in mappings attribute. The mappings can be saved to
mappings0 using Field.save_mappings. The saved mapping can be retrieved by passing get_saved=True.
If the required (saved) mapping is not in cache, a new one is created.
Returns geo : CMapping instance
The reference mapping.
mapping : VolumeMapping or SurfaceMapping instance
The mapping.
key : tuple
The key of the mapping in mappings or mappings0.
save_mappings()
Save current reference mappings to mappings0 attribute.
sfepy.discrete.common.fields.fields_from_conf(conf, regions)
sfepy.discrete.common.fields.parse_approx_order(approx_order)
Parse the uniform approximation order value (str or int).
sfepy.discrete.common.fields.parse_shape(shape, dim)
sfepy.discrete.common.fields.setup_extra_data(conn_info)
Setup extra data required for non-volume integration.
sfepy.discrete.common.mappings module
Reference-physical domain mappings.
class sfepy.discrete.common.mappings.Mapping(**kwargs)
Base class for mappings.
static from_args(region, kind=’v’, ig=None)
Create mapping from reference to physical entities in a given region, given the integration kind (‘v’ or ‘s’).
This mapping can be used to compute the physical quadrature points.
Parameters region : Region instance
The region defining the entities.
kind : ‘v’ or ‘s’
The kind of the entities: ‘v’ - cells, ‘s’ - facets.
ig : int, optional
The group index.
Returns mapping : VolumeMapping or SurfaceMapping instance
The requested mapping.
class sfepy.discrete.common.mappings.PhysicalQPs(igs, n_total=0, is_uniform=True)
Physical quadrature points in a region.
get_merged_values()
get_shape(rshape, ig=None)
Get shape from raveled shape.
7.8. Module Index
443
SfePy Documentation, Release 2015.1
sfepy.discrete.common.mappings.get_jacobian(field, integral,
tion=’volume’)
Get the jacobian of reference mapping corresponding to field.
region=None,
integra-
Parameters field : Field instance
The field defining the reference mapping.
integral : Integral instance
The integral defining quadrature points.
region : Region instance, optional
If given, use the given region instead of field region.
integration : one of (‘volume’, ‘surface’, ‘surface_extra’)
The integration type.
Returns jac : array
The jacobian merged for all element groups.
See also:
get_mapping_data
Notes
Assumes the same element geometry in all element groups of the field!
sfepy.discrete.common.mappings.get_mapping_data(name, field, integral, region=None, integration=’volume’)
General helper function for accessing reference mapping data.
Get data attribute name from reference mapping corresponding to field in region in quadrature points of the
given integral and integration type.
Parameters name : str
The reference mapping attribute name.
field : Field instance
The field defining the reference mapping.
integral : Integral instance
The integral defining quadrature points.
region : Region instance, optional
If given, use the given region instead of field region.
integration : one of (‘volume’, ‘surface’, ‘surface_extra’)
The integration type.
Returns data : array
The required data merged for all element groups.
444
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
Assumes the same element geometry in all element groups of the field!
sfepy.discrete.common.mappings.get_normals(field, integral, region)
Get the normals of element faces in region.
Parameters field : Field instance
The field defining the reference mapping.
integral : Integral instance
The integral defining quadrature points.
region : Region instance
The given of the element faces.
Returns normals : array
The normals merged for all element groups.
See also:
get_mapping_data
Notes
Assumes the same element geometry in all element groups of the field!
sfepy.discrete.common.mappings.get_physical_qps(region, integral, map_kind=None)
Get physical quadrature points corresponding to the given region and integral.
sfepy.discrete.common.region module
class sfepy.discrete.common.region.Region(name, definition, domain, parse_def, kind=’cell’,
parent=None)
Region defines a subset of a FE domain.
Region kinds:
•cell_only, facet_only, face_only, edge_only, vertex_only - only the specified entities are included, others
are empty sets (so that the operators are still defined)
•cell, facet, face, edge, vertex - entities of higher dimension are not included
The ‘cell’ kind is the most general and it is the default.
Region set-like operators: + (union), - (difference), * (intersection), followed by one of (‘v’, ‘e’, ‘f’, ‘c’, and
‘s’) for vertices, edges, faces, cells, and facets.
Notes
Functions depending on ig are adapters for current code that should be removed after new assembling is done.
Created: 31.10.2005
cells
7.8. Module Index
445
SfePy Documentation, Release 2015.1
contains(other)
Return True in the region contains the other region.
The check is performed using entities corresponding to the other region kind.
copy()
Vertices-based copy.
delete_zero_faces(eps=1e-14)
edges
eval_op_cells(other, op)
eval_op_edges(other, op)
eval_op_faces(other, op)
eval_op_facets(other, op)
eval_op_vertices(other, op)
faces
facets
finalize()
Initialize the entities corresponding to the region kind and regenerate all already existing (accessed) entities
of lower topological dimension from the kind entities.
static from_cells(cells, domain, name=’region’, kind=’cell’, parent=None)
Create a new region containing given cells.
Parameters cells : array
The array of cells.
domain : Domain instance
The domain containing the facets.
name : str, optional
The name of the region.
kind : str, optional
The kind of the region.
parent : str, optional
The name of the parent region.
Returns obj : Region instance
The new region.
static from_facets(facets, domain, name=’region’, kind=’facet’, parent=None)
Create a new region containing given facets.
Parameters facets : array
The array with indices to unique facets.
domain : Domain instance
The domain containing the facets.
name : str, optional
446
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The name of the region.
kind : str, optional
The kind of the region.
parent : str, optional
The name of the parent region.
Returns obj : Region instance
The new region.
static from_vertices(vertices, domain, name=’region’, kind=’cell’)
Create a new region containing given vertices.
Parameters vertices : array
The array of vertices.
domain : Domain instance
The domain containing the vertices.
name : str, optional
The name of the region.
kind : str, optional
The kind of the region.
Returns obj : Region instance
The new region.
get_cell_offsets()
get_cells(ig, true_cells_only=True, offset=True)
Get cells of the region.
Raises ValueError if true_cells_only is True and the region kind does not allow cells (e.g. surface integration region). For true_cells_only equal to False, cells incident to facets are returned if the region itself
contains no cells.
If offset is True, the cell group offset is subtracted from the cell ids.
get_charfun(by_cell=False, val_by_id=False)
Return the characteristic function of the region as a vector of values defined either in the mesh vertices
(by_cell == False) or cells. The values are either 1 (val_by_id == False) or sequential id + 1.
get_edge_graph()
Return the graph of region edges as a sparse matrix having uid(k) + 1 at (i, j) if vertex[i] is connected with
vertex[j] by the edge k.
Degenerate edges are ignored.
get_edges(ig)
get_entities(dim, ig=None)
Return mesh entities of dimension dim, and optionally with the cell group ig.
get_faces(ig)
get_facet_indices(ig, offset=True, force_ig=True)
Return an array (per group) of (iel, ifa) for each facet. A facet can be in 1 (surface) or 2 (inner) cells.
7.8. Module Index
447
SfePy Documentation, Release 2015.1
If offset is True, the cell group offset is subtracted from the cell ids.
If force_ig is True, only the cells with the given ig are used.
get_facets(ig)
Return either region vertices (in 1D), edges (in 2D) or faces (in 3D).
get_mirror_region()
get_n_cells(ig=None, is_surface=False)
Get number of region cells.
Parameters ig : int, optional
The group index. If None, counts from all groups are added together.
is_surface : bool
If True, number of edges or faces according to domain dimension is returned instead.
Returns n_cells : int
The number of cells.
get_vertices(ig)
get_vertices_of_cells()
Return all vertices, that are in some cell of the region.
has_cells()
igs
Cell group indices according to region kind.
iter_cells()
light_copy(name, parse_def )
set_kind(kind)
set_kind_tdim()
setup_from_highest(dim, allow_lower=True)
Setup entities of topological dimension dim using the available entities of the highest topological dimension.
setup_from_vertices(dim)
Setup entities of topological dimension dim using the region vertices.
setup_mirror_region()
Find the corresponding mirror region, set up element mapping.
update_shape()
Update shape of each group according to region vertices, edges, faces and cells.
vertices
sfepy.discrete.common.region.are_disjoint(r1, r2)
Check if the regions r1 and r2 are disjoint.
Uses vertices for the check - *_only regions not allowed.
sfepy.discrete.common.region.get_dependency_graph(region_defs)
Return a dependency graph and a name-sort name mapping for given region definitions.
sfepy.discrete.common.region.get_parents(selector)
Given a region selector, return names of regions it is based on.
448
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.common.region.sort_by_dependency(graph)
sfepy.discrete.fem sub-package
sfepy.discrete.fem.domain module
Computational domain, consisting of the mesh and regions.
class sfepy.discrete.fem.domain.FEDomain(name, mesh, verbose=False, **kwargs)
Domain is divided into groups, whose purpose is to have homogeneous data shapes.
clear_surface_groups()
Remove surface group data.
create_surface_group(region)
Create a new surface group corresponding to region if it does not exist yet.
Notes
Surface
groups
define
surface
facet
connectivity
sfepy.discrete.fem.mappings.SurfaceMapping.
that
is
needed
for
fix_element_orientation()
Ensure element nodes ordering giving positive element volume.
The groups with elements of lower dimension than the space dimension are skipped.
get_cell_offsets()
get_diameter()
Return the diameter of the domain.
Notes
The diameter corresponds to the Friedrichs constant.
get_element_diameters(ig, cells, vg, mode, square=True)
get_evaluate_cache(cache=None, share_geometry=False)
Get the evaluate cache for Variable.evaluate_at().
Parameters cache : Struct instance, optional
Optionally, use the provided instance to store the cache data.
share_geometry : bool
Set to True to indicate that all the probes will work on the same domain. Certain data
are then computed only for the first probe and cached.
Returns cache : Struct instance
The evaluate cache.
get_mesh_bounding_box()
Return the bounding box of the underlying mesh.
Returns bbox : ndarray (2, dim)
The bounding box with min. values in the first row and max. values in the second row.
7.8. Module Index
449
SfePy Documentation, Release 2015.1
get_mesh_coors(actual=False)
Return the coordinates of the underlying mesh vertices.
iter_groups(igs=None)
refine()
Uniformly refine the domain mesh.
Returns domain : FEDomain instance
The new domain with the refined mesh.
Notes
Works only for meshes with single element type! Does not preserve node groups!
setup_groups()
sfepy.discrete.fem.extmods._fmfield module
sfepy.discrete.fem.extmods._geommech module
Low level functions.
sfepy.discrete.fem.extmods._geommech.geme_mulAVSB3py()
sfepy.discrete.fem.extmods.assemble module
Low level finite element assembling functions.
sfepy.discrete.fem.extmods.assemble.assemble_matrix()
sfepy.discrete.fem.extmods.assemble.assemble_matrix_complex()
sfepy.discrete.fem.extmods.assemble.assemble_vector()
sfepy.discrete.fem.extmods.assemble.assemble_vector_complex()
sfepy.discrete.fem.extmods.bases module
Polynomial base functions and related utilities.
sfepy.discrete.fem.extmods.bases.eval_lagrange_simplex()
Evaluate Lagrange base polynomials in given points on simplex domain.
Parameters coors : array
The coordinates of the points, shape (n_coor, dim).
mtx_i : array
The inverse of simplex coordinates matrix, shape (dim + 1, dim + 1).
nodes : array
The description of finite element nodes, shape (n_nod, dim + 1).
order : int
The polynomial order.
450
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
diff : bool
If True, return base function derivatives.
eps : float
The tolerance for snapping out-of-simplex point back to the simplex.
check_errors : bool
If True, raise ValueError if a barycentric coordinate is outside the snap interval [-eps, 1
+ eps].
Returns out : array
The evaluated base functions, shape (n_coor, 1 or dim, n_nod).
sfepy.discrete.fem.extmods.bases.eval_lagrange_tensor_product()
Evaluate Lagrange base polynomials in given points on tensor product domain.
Parameters coors : array
The coordinates of the points, shape (n_coor, dim).
mtx_i : array
The inverse of 1D simplex coordinates matrix, shape (2, 2).
nodes : array
The description of finite element nodes, shape (n_nod, 2 * dim).
order : int
The polynomial order.
diff : bool
If True, return base function derivatives.
eps : float
The tolerance for snapping out-of-simplex point back to the simplex.
check_errors : bool
If True, raise ValueError if a barycentric coordinate is outside the snap interval [-eps, 1
+ eps].
Returns out : array
The evaluated base functions, shape (n_coor, 1 or dim, n_nod).
sfepy.discrete.fem.extmods.bases.evaluate_in_rc()
Evaluate source field DOF values in the given reference element coordinates using the given interpolation.
1.Evaluate base functions in the reference coordinates.
2.Interpolate source values using the base functions.
Interpolation uses field approximation connectivity.
sfepy.discrete.fem.extmods.bases.find_ref_coors()
Find reference element coordinates corresponding to physical coordinates coors.
This function works only with a geometry mesh (order 1 connectivity), not a field mesh! The polynomial space
arguments have to correspond to that.
Returns ref_coors : array
7.8. Module Index
451
SfePy Documentation, Release 2015.1
The reference coordinates.
cells : array
The array of (ig, iel) corresponding to the reference coordinates.
status : array
The status array: 0 is success, 1 means the point is extrapolated within close_limit, 2
extrapolated outside close_limit and 3 extrapolated with no extrapolation allowed.
sfepy.discrete.fem.extmods.bases.get_barycentric_coors()
Get barycentric (area in 2D, volume in 3D) coordinates of points.
Parameters coors : array
The coordinates of the points, shape (n_coor, dim).
mtx_i : array
The inverse of simplex coordinates matrix, shape (dim + 1, dim + 1).
eps : float
The tolerance for snapping out-of-simplex point back to the simplex.
check_errors : bool
If True, raise ValueError if a barycentric coordinate is outside the snap interval [-eps, 1
+ eps].
Returns bc : array
The barycentric coordinates, shape (n_coor, dim + 1). Then reference element coordinates xi = dot(bc, ref_coors).
sfepy.discrete.fem.extmods.cmesh module
C Mesh data structures and functions.
class sfepy.discrete.fem.extmods.cmesh.CConnectivity
Notes
The memory is allocated/freed in C - this class just wraps NumPy arrays around that data without copying.
cprint()
indices
n_incident
num
offset
offsets
class sfepy.discrete.fem.extmods.cmesh.CMesh
cell_groups
cell_types
452
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
conns
coors
cprint()
dim
edge_oris
entities
face_oris
facet_oris
free_connectivity()
static from_mesh()
Fill data from a Python mesh.
get_cell_conn()
get_centroids()
Return the coordinates of centroids of mesh entities with dimension dim.
get_complete()
Get entities of dimension dim that are completely given by entities of dimension dent listed in entities.
get_conn()
get_conn_as_graph()
Get d1 -> d2 connectivity as a sparse matrix graph (values = ones).
For safety, creates a copy of the connectivity arrays. The connectivity is created if necessary.
get_from_cell_group()
Get entities of dimension dim that are contained in cells of group ig and are listed in entities. If entities is
None, all entities are used.
Adapter function to be removed after new assembling is done.
get_igs()
Get cell groups of incident to entities of dimension dim.
Adapter function to be removed after new assembling is done.
get_incident()
Get non-unique entities indices of dimension dim that are contained in entities of dimension dent listed in
entities. As each of entities can be in several entities of dimension dent, offsets array is returned optionally.
get_local_entities()
get_local_ids()
Get local ids of non-unique entities incident of dimension dim (with given offsets per entities) incident to
entities of dimension dent, see mesh_get_incident(), with respect to entities.
get_orientations()
Get orientations of entities of dimension dim. Alternatively, co-dimension can be specified using codim
argument.
get_surface_facets()
Get facets (edges in 2D, faces in 3D) on the mesh surface.
key_to_index
n_coor
7.8. Module Index
453
SfePy Documentation, Release 2015.1
n_el
num
set_local_entities()
setup_connectivity()
setup_entities()
Set up mesh edge (2D and 3D) and face connectivities (3D only) as well as their orientations.
tdim
sfepy.discrete.fem.extmods.cmesh.cmem_statistics()
sfepy.discrete.fem.extmods.cmesh.create_mesh_graph()
Create sparse (CSR) graph corresponding to given row and column connectivities.
Parameters n_row : int
The number of row connectivity nodes.
n_col : int
The number of column connectivity nodes.
n_gr : int
The number of element groups.
rconns : list of arrays
The list of length n_gr of row connectivities.
cconns : list of arrays
The list of length n_gr of column connectivities.
Returns nnz : int
The number of graph nonzeros.
prow : array
The array of CSR row pointers.
icol : array
The array of CSR column indices.
sfepy.discrete.fem.extmods.cmesh.get_cmem_usage()
sfepy.discrete.fem.extmods.cmesh.graph_components()
Determine connected compoments of a compressed sparse graph.
Returns n_comp : int
The number of components.
flag : array
The flag marking for each node its component.
sfepy.discrete.fem.extmods.cmesh.orient_elements()
Swap element nodes so that its volume is positive.
454
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.extmods.lobatto_bases module
Interface to Lobatto bases.
sfepy.discrete.fem.extmods.lobatto_bases.eval_lobatto1d()
Evaluate 1D Lobatto functions of the given order in given points.
sfepy.discrete.fem.extmods.lobatto_bases.eval_lobatto_tensor_product()
Evaluate tensor product Lobatto functions of the given order in given points.
Base functions are addressed using the nodes array with rows corresponding to individual functions and columns
to 1D indices (= orders when >= 1) into lobatto[] and d_lobatto[] lists for each axis.
sfepy.discrete.fem.extmods.mappings module
Low level reference mapping functionality.
class sfepy.discrete.fem.extmods.mappings.CMapping
alloc_extra_data()
bf
bfg
cprint()
describe()
Describe the element geometry - compute the reference element mapping.
det
dim
evaluate_bfbgm()
Evaluate volume base function gradients in surface quadrature points.
get_element_diameters()
Compute diameters of selected elements.
integral
integrate()
Integrate arr over the domain of the mapping into out.
mode
mtx_t
n_el
n_ep
n_qp
normal
ps
qp
shape
volume
7.8. Module Index
455
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.facets module
Helper functions related to mesh facets and Lagrange FE approximation.
Line: ori - iter:
0 - iter0 1 - iter1
Triangle: ori - iter:
0 - iter21 1 - iter12 3 - iter02 4 - iter20 6 - iter10 7 - iter01
Possible couples:
1, 4, 7 <-> 0, 3, 6
Square: ori - iter:
0 - iter10x01y 7 - iter10y01x
11 - iter01y01x 30 - iter01x10y 33 - iter10x10y 52 - iter01y10x 56 - iter10y10x 63 - iter01x01y
Possible couples:
7, 33, 52, 63 <-> 0, 11, 30, 56
sfepy.discrete.fem.facets.build_orientation_map(n_fp)
The keys are binary masks of the lexicographical ordering of facet vertices. A bit i set to one means v[i] <
v[i+1].
The values are [original_order, permutation], where permutation can be used to sort facet vertices lexicographically. Hence permuted_facet = facet[permutation].
sfepy.discrete.fem.facets.get_facet_dof_permutations(n_fp, igs, order)
Prepare DOF permutation vector for each possible facet orientation.
sfepy.discrete.fem.facets.iter0(num)
sfepy.discrete.fem.facets.iter01(num)
sfepy.discrete.fem.facets.iter01x01y(num)
sfepy.discrete.fem.facets.iter01x10y(num)
sfepy.discrete.fem.facets.iter01y01x(num)
sfepy.discrete.fem.facets.iter01y10x(num)
sfepy.discrete.fem.facets.iter02(num)
sfepy.discrete.fem.facets.iter1(num)
sfepy.discrete.fem.facets.iter10(num)
sfepy.discrete.fem.facets.iter10x01y(num)
sfepy.discrete.fem.facets.iter10x10y(num)
sfepy.discrete.fem.facets.iter10y01x(num)
sfepy.discrete.fem.facets.iter10y10x(num)
sfepy.discrete.fem.facets.iter12(num)
sfepy.discrete.fem.facets.iter20(num)
sfepy.discrete.fem.facets.iter21(num)
sfepy.discrete.fem.facets.make_line_matrix(order)
456
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.facets.make_square_matrix(order)
sfepy.discrete.fem.facets.make_triangle_matrix(order)
sfepy.discrete.fem.fe_surface module
class sfepy.discrete.fem.fe_surface.FESurface(name, region, efaces, volume_econn, ig)
Description of a surface of a finite element domain.
get_connectivity(local=False, is_trace=False)
Return the surface element connectivity.
Parameters local : bool
If True, return local connectivity w.r.t. surface nodes, otherwise return global connectivity w.r.t. all mesh nodes.
is_trace : bool
If True, return mirror connectivity according to local.
setup_mirror_connectivity(region)
Setup mirror surface connectivity required to integrate over a mirror region.
1.Get orientation of the faces: a) for elements in group ig -> ooris (own) b) for elements in group mig
-> moris (mirror)
2.orientation -> permutation.
sfepy.discrete.fem.fea module
class sfepy.discrete.fem.fea.Approximation(name, interp, region, ig, is_surface=False)
clear_qp_base()
Remove cached quadrature points and base functions.
create_bqp(region_name, integral)
describe_geometry(field, gtype, region, integral, return_mapping=False)
Compute jacobians, element volumes and base function derivatives for Volume-type geometries (volume
mappings), and jacobians, normals and base function derivatives for Surface-type geometries (surface
mappings).
Notes
•volume mappings can be defined on a part of an element group, although the field has to be defined
always on the whole group.
•surface mappings are defined on the surface region
•surface mappings require field order to be > 0
eval_extra_coor(coors, mesh_coors)
Compute coordinates of extra nodes.
get_base(key, derivative, integral, iels=None, from_geometry=False, base_only=True)
7.8. Module Index
457
SfePy Documentation, Release 2015.1
get_connectivity(region, integration, is_trace=False)
Return the DOF connectivity for the given geometry type.
Parameters region : Region instance
The region, used to index surface and volume connectivities.
integration : one of (‘volume’, ‘plate’, ‘surface’, ‘surface_extra’)
The term integration type.
get_poly_space(key, from_geometry=False)
Get the polynomial space.
Parameters key : ‘v’ or ‘s?’
The key denoting volume or surface.
from_geometry : bool
If True, return the polynomial space for affine geometrical interpolation.
Returns ps : PolySpace instance
The polynomial space.
get_qp(key, integral)
Get quadrature points and weights corresponding to the given key and integral. The key is ‘v’ or ‘s#’,
where # is the number of face vertices.
setup_point_data(field, region)
setup_surface_data(region)
nodes[leconn] == econn
class sfepy.discrete.fem.fea.DiscontinuousApproximation(name, interp, region,
is_surface=False)
ig,
eval_extra_coor(coors, mesh_coors)
Compute coordinates of extra nodes. For discontinuous approximations, all nodes are treated as extra.
class sfepy.discrete.fem.fea.Interpolant(name, gel, space=’H1’, base=’lagrange’, approx_order=1, force_bubble=False)
A simple wrapper around PolySpace.
describe_nodes()
get_geom_poly_space(key)
get_n_nodes()
class sfepy.discrete.fem.fea.SurfaceApproximation(name, interp, region, ig)
get_qp(key, integral)
Get quadrature points and weights corresponding to the given key and integral. The key is ‘s#’, where # is
the number of face vertices.
class sfepy.discrete.fem.fea.SurfaceInterpolant(name, gel, space=’H1’, base=’lagrange’,
approx_order=1, force_bubble=False)
Like Interpolant, but for use with SurfaceField and SurfaceApproximation.
get_geom_poly_space(key)
sfepy.discrete.fem.fea.eval_nodal_coors(coors,
mesh_coors,
region,
poly_space,
geom_poly_space, econn, ig, only_extra=True)
Compute coordinates of nodes corresponding to poly_space, given mesh coordinates and geom_poly_space.
458
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.fea.set_mesh_coors(domain, fields, coors, update_fields=False, actual=False, clear_all=True)
sfepy.discrete.fem.fields_base module
Notes Important attributes of continuous (order > 0) Field and SurfaceField instances:
• vertex_remap : econn[:, :n_vertex] = vertex_remap[conn]
• vertex_remap_i : conn = vertex_remap_i[econn[:, :n_vertex]]
where conn is the mesh vertex connectivity, econn is the region-local field connectivity.
class sfepy.discrete.fem.fields_base.FEField(name, dtype, shape, region, approx_order=1)
Base class for finite element fields.
Notes
•Region can span over several groups -> different Aproximation instances
•interps and hence node_descs are per region (must have single geometry!)
•no two interps can be in a same group -> no two aps (with different regions) can be in a same group -> aps
can be uniquely indexed with ig
Field shape information:
•shape - the shape of the base functions in a point
•n_components - the number of DOFs per FE node
•val_shape - the shape of field value (the product of DOFs and base functions) in a point
create_mapping(ig, region, integral, integration)
Create a new reference mapping.
create_mesh(extra_nodes=True)
Create a mesh from the field region, optionally including the field extra nodes.
create_output(dofs, var_name, dof_names=None, key=None, extend=True, fill_value=None, linearization=None)
Convert the DOFs corresponding to the field to a dictionary of output data usable by Mesh.write().
Parameters dofs : array, shape (n_nod, n_component)
The array of DOFs reshaped so that each column corresponds to one component.
var_name : str
The variable name corresponding to dofs.
dof_names : tuple of str
The names of DOF components.
key : str, optional
The key to be used in the output dictionary instead of the variable name.
extend : bool
Extend the DOF values to cover the whole domain.
fill_value : float or complex
7.8. Module Index
459
SfePy Documentation, Release 2015.1
The value used to fill the missing DOF values if extend is True.
linearization : Struct or None
The linearization configuration for higher order approximations.
Returns out : dict
The output dictionary.
extend_dofs(dofs, fill_value=None)
Extend DOFs to the whole domain using the fill_value, or the smallest value in dofs if fill_value is None.
get_coor(nods=None)
Get coordinates of the field nodes.
Parameters nods : array, optional
The indices of the required nodes. If not given, the coordinates of all the nodes are
returned.
get_data_shape(ig, integral, integration=’volume’, region_name=None)
Get element data dimensions.
Parameters ig : int
The element group index.
integral : Integral instance
The integral describing used numerical quadrature.
integration : ‘volume’, ‘plate’, ‘surface’, ‘surface_extra’ or ‘point’
The term integration type.
region_name : str
The name of surface region, required when shape_kind is ‘surface’.
Returns data_shape : 4 ints
The (n_el, n_qp, dim, n_en) for volume shape kind, (n_fa, n_qp, dim, n_fn) for surface
shape kind and (n_nod, 0, 0, 1) for point shape kind.
Notes
•n_el, n_fa = number of elements/facets
•n_qp = number of quadrature points per element/facet
•dim = spatial dimension
•n_en, n_fn = number of element/facet nodes
•n_nod = number of element nodes
get_dofs_in_region_group(region, ig, merge=True)
Return indices of DOFs that belong to the given region and group.
get_output_approx_order()
Get the approximation order used in the output file.
460
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
get_true_order()
Get the true approximation order depending on the reference element geometry.
For example, for P1 (linear) approximation the true order is 1, while for Q1 (bilinear) approximation in
2D the true order is 2.
get_vertices()
Return indices of vertices belonging to the field region.
interp_to_qp(dofs)
Interpolate DOFs into quadrature points.
The quadrature order is given by the field approximation order.
Parameters dofs : array
The array of DOF values of shape (n_nod, n_component).
Returns data_qp : array
The values interpolated into the quadrature points.
integral : Integral
The corresponding integral defining the quadrature points.
is_higher_order()
Return True, if the field’s approximation order is greater than one.
linearize(dofs, min_level=0, max_level=1, eps=0.0001)
Linearize the solution for post-processing.
Parameters dofs : array, shape (n_nod, n_component)
The array of DOFs reshaped so that each column corresponds to one component.
min_level : int
The minimum required level of mesh refinement.
max_level : int
The maximum level of mesh refinement.
eps : float
The relative tolerance parameter of mesh adaptivity.
Returns mesh : Mesh instance
The adapted, nonconforming, mesh.
vdofs : array
The DOFs defined in vertices of mesh.
levels : array of ints
The refinement level used for each element group.
remove_extra_dofs(dofs)
Remove DOFs defined in higher order nodes (order > 1).
setup_coors(coors=None)
Setup coordinates of field nodes.
class sfepy.discrete.fem.fields_base.H1Mixin(**kwargs)
Methods of fields specific to H1 space.
7.8. Module Index
461
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.fields_base.SurfaceField(name, dtype, shape, region,
prox_order=1)
Finite element field base class over surface (element dimension is one less than space dimension).
ap-
average_qp_to_vertices(data_qp, integral)
Average data given in quadrature points in region elements into region vertices.
∑︁
∑︁
∑︁ ∫︁
∑︁
𝑢𝑛 =
(𝑢𝑒,𝑎𝑣𝑔 * 𝑎𝑟𝑒𝑎𝑒 )/
𝑎𝑟𝑒𝑎𝑒 =
𝑢/
𝑎𝑟𝑒𝑎𝑒
𝑒
𝑒
𝑒
𝑎𝑟𝑒𝑎𝑒
get_econn(conn_type, region, ig, is_trace=False, integration=None)
Get extended connectivity of the given type in the given region.
setup_extra_data(geometry, info, is_trace)
class sfepy.discrete.fem.fields_base.VolumeField(name, dtype, shape, region,
prox_order=1)
Finite element field base class over volume elements (element dimension equals space dimension).
ap-
average_qp_to_vertices(data_qp, integral)
Average data given in quadrature points in region elements into region vertices.
∑︁
∑︁
∑︁ ∫︁
∑︁
𝑢𝑛 =
(𝑢𝑒,𝑎𝑣𝑔 * 𝑣𝑜𝑙𝑢𝑚𝑒𝑒 )/
𝑣𝑜𝑙𝑢𝑚𝑒𝑒 =
𝑢/
𝑣𝑜𝑙𝑢𝑚𝑒𝑒
𝑒
𝑒
𝑒
𝑣𝑜𝑙𝑢𝑚𝑒𝑒
get_econn(conn_type, region, ig, is_trace=False, integration=None)
Get extended connectivity of the given type in the given region.
setup_extra_data(geometry, info, is_trace)
sfepy.discrete.fem.fields_base.create_expression_output(expression, name, primary_field_name, fields,
materials, variables, functions=None, mode=’eval’,
term_mode=None,
extra_args=None,
verbose=True, kwargs=None,
min_level=0,
max_level=1,
eps=0.0001)
Create output mesh and data for the expression using the adaptive linearizer.
Parameters expression : str
The expression to evaluate.
name : str
The name of the data.
primary_field_name : str
The name of field that defines the element groups and polynomial spaces.
fields : dict
The dictionary of fields used in variables.
materials : Materials instance
The materials used in the expression.
variables : Variables instance
462
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The variables used in the expression.
functions : Functions instance, optional
The user functions for materials etc.
mode : one of ‘eval’, ‘el_avg’, ‘qp’
The evaluation mode - ‘qp’ requests the values in quadrature points, ‘el_avg’ element
averages and ‘eval’ means integration over each term region.
term_mode : str
The term call mode - some terms support different call modes and depending on the call
mode different values are returned.
extra_args : dict, optional
Extra arguments to be passed to terms in the expression.
verbose : bool
If False, reduce verbosity.
kwargs : dict, optional
The variables (dictionary of (variable name) : (Variable instance)) to be used in the
expression.
min_level : int
The minimum required level of mesh refinement.
max_level : int
The maximum level of mesh refinement.
eps : float
The relative tolerance parameter of mesh adaptivity.
Returns out : dict
The output dictionary.
sfepy.discrete.fem.fields_base.get_eval_expression(expression, ig, fields, materials, variables, functions=None,
mode=’eval’, term_mode=None,
extra_args=None, verbose=True,
kwargs=None)
Get the function for evaluating an expression given a list of elements, and reference element coordinates.
sfepy.discrete.fem.fields_hierarchic module
class sfepy.discrete.fem.fields_hierarchic.H1HierarchicVolumeField(name, dtype,
shape,
region,
approx_order=1)
evaluate_at(coors, source_vals, strategy=’kdtree’, close_limit=0.1, cache=None, ret_cells=False,
ret_status=False, ret_ref_coors=False, verbose=True)
Evaluate source DOF values corresponding to the field in the given coordinates using the field interpolation.
Parameters coors : array
7.8. Module Index
463
SfePy Documentation, Release 2015.1
The coordinates the source values should be interpolated into.
source_vals : array
The source DOF values corresponding to the field.
strategy : str, optional
The strategy for finding the elements that contain the coordinates. Only ‘kdtree’ is
supported for the moment.
close_limit : float, optional
The maximum limit distance of a point from the closest element allowed for extrapolation.
cache : Struct, optional
To speed up a sequence of evaluations, the field mesh, the inverse connectivity of
the field mesh and the KDTree instance can be cached as cache.mesh, cache.offsets,
cache.iconn and cache.kdtree. Optionally, the cache can also contain the reference element coordinates as cache.ref_coors, cache.cells and cache.status, if the evaluation
occurs in the same coordinates repeatedly. In that case the KDTree related data are
ignored.
ret_cells : bool, optional
If True, return also the cell indices the coordinates are in.
ret_status : bool, optional
If True, return also the status for each point: 0 is success, 1 is extrapolation within
close_limit, 2 is extrapolation outside close_limit, 3 is failure.
ret_ref_coors : bool, optional
If True, return also the found reference element coordinates.
verbose : bool
If False, reduce verbosity.
Returns vals : array
The interpolated values.
cells : array
The cell indices, if ret_cells or ret_status are True.
status : array
The status, if ret_status is True.
family_name = ‘volume_H1_lobatto’
set_dofs(fun=0.0, region=None, dpn=None, warn=None)
Set the values of given DOFs using a function of space coordinates or value fun.
sfepy.discrete.fem.fields_nodal module
Notes Important attributes of continuous (order > 0) Field and SurfaceField instances:
• vertex_remap : econn[:, :n_vertex] = vertex_remap[conn]
• vertex_remap_i : conn = vertex_remap_i[econn[:, :n_vertex]]
464
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
where conn is the mesh vertex connectivity, econn is the region-local field connectivity.
class sfepy.discrete.fem.fields_nodal.H1DiscontinuousField(name, dtype, shape, region, approx_order=1)
average_to_vertices(dofs)
Average DOFs of the discontinuous field into the field region vertices.
extend_dofs(dofs, fill_value=None)
Extend DOFs to the whole domain using the fill_value, or the smallest value in dofs if fill_value is None.
family_name = ‘volume_H1_lagrange_discontinuous’
remove_extra_dofs(dofs)
Remove DOFs defined in higher order nodes (order > 1).
class sfepy.discrete.fem.fields_nodal.H1NodalMixin(**kwargs)
evaluate_at(coors, source_vals, strategy=’kdtree’, close_limit=0.1, cache=None, ret_cells=False,
ret_status=False, ret_ref_coors=False, verbose=True)
Evaluate source DOF values corresponding to the field in the given coordinates using the field interpolation.
Parameters coors : array
The coordinates the source values should be interpolated into.
source_vals : array
The source DOF values corresponding to the field.
strategy : str, optional
The strategy for finding the elements that contain the coordinates. Only ‘kdtree’ is
supported for the moment.
close_limit : float, optional
The maximum limit distance of a point from the closest element allowed for extrapolation.
cache : Struct, optional
To speed up a sequence of evaluations, the field mesh, the inverse connectivity of
the field mesh and the KDTree instance can be cached as cache.mesh, cache.offsets,
cache.iconn and cache.kdtree. Optionally, the cache can also contain the reference element coordinates as cache.ref_coors, cache.cells and cache.status, if the evaluation
occurs in the same coordinates repeatedly. In that case the KDTree related data are
ignored.
ret_cells : bool, optional
If True, return also the cell indices the coordinates are in.
ret_status : bool, optional
If True, return also the status for each point: 0 is success, 1 is extrapolation within
close_limit, 2 is extrapolation outside close_limit, 3 is failure.
ret_ref_coors : bool, optional
If True, return also the found reference element coordinates.
verbose : bool
7.8. Module Index
465
SfePy Documentation, Release 2015.1
If False, reduce verbosity.
Returns vals : array
The interpolated values.
cells : array
The cell indices, if ret_cells or ret_status are True.
status : array
The status, if ret_status is True.
set_dofs(fun=0.0, region=None, dpn=None, warn=None)
Set the values of DOFs in a given region using a function of space coordinates or value fun.
class sfepy.discrete.fem.fields_nodal.H1NodalSurfaceField(name, dtype, shape, region,
approx_order=1)
A field defined on a surface region.
family_name = ‘surface_H1_lagrange’
interp_v_vals_to_n_vals(vec)
Interpolate a function defined by vertex DOF values using the FE surface geometry base (P1 or Q1) into
the extra nodes, i.e. define the extra DOF values.
class sfepy.discrete.fem.fields_nodal.H1NodalVolumeField(name, dtype, shape, region,
approx_order=1)
family_name = ‘volume_H1_lagrange’
interp_v_vals_to_n_vals(vec)
Interpolate a function defined by vertex DOF values using the FE geometry base (P1 or Q1) into the extra
nodes, i.e. define the extra DOF values.
sfepy.discrete.fem.geometry_element module
GeometryElement describes the geometric entities of a finite element mesh.
Notes
• geometry_data: surface facets are assumed to be of the same kind for each geometry element - wedges or
pyramides are not supported.
• the orientation is a tuple: (root1, vertices of direction vectors, swap from, swap to, root2, ...)
class sfepy.discrete.fem.geometry_element.GeometryElement(name)
The geometric entities of a finite element mesh.
create_surface_facet()
Create a GeometryElement instance corresponding to this instance surface facet.
get_conn_permutations()
Get all possible connectivity permutations corresponding to different spatial orientations of the geometry
element.
get_edges_per_face()
Return the indices into self.edges per face.
466
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
get_grid(n_nod)
Get a grid of n_nod interpolation points, including the geometry element vertices. The number of points
must correspond to a valid number of FE nodes for each geometry.
get_interpolation_name()
Get the name of corresponding linear interpolant.
get_surface_entities()
Return self.vertices in 1D, self.edges in 2D and self.faces in 3D.
sfepy.discrete.fem.geometry_element.create_geometry_elements(names=None)
Utility function to create GeometryElement instances.
Parameters names : str, optional
The names of the entity, one of the keys in geometry_data dictionary. If None, all keys
of geometry_data are used.
Returns gels : dict
The dictionary of geometry elements with names as keys.
sfepy.discrete.fem.geometry_element.setup_orientation(vecs_tuple)
sfepy.discrete.fem.global_interp module
Global interpolation functions.
sfepy.discrete.fem.global_interp.get_ref_coors(field,
coors,
strategy=’kdtree’,
close_limit=0.1, cache=None, verbose=True)
Get reference element coordinates and elements corresponding to given physical coordinates.
Parameters field : Field instance
The field defining the approximation.
coors : array
The physical coordinates.
strategy : str, optional
The strategy for finding the elements that contain the coordinates. Only ‘kdtree’ is
supported for the moment.
close_limit : float, optional
The maximum limit distance of a point from the closest element allowed for extrapolation.
cache : Struct, optional
To speed up a sequence of evaluations, the field mesh, the inverse connectivity of
the field mesh and the KDTree instance can be cached as cache.mesh, cache.offsets,
cache.iconn and cache.kdtree. Optionally, the cache can also contain the reference element coordinates as cache.ref_coors, cache.cells and cache.status, if the evaluation
occurs in the same coordinates repeatedly. In that case the KDTree related data are
ignored.
verbose : bool
If False, reduce verbosity.
7.8. Module Index
467
SfePy Documentation, Release 2015.1
Returns ref_coors : array
The reference coordinates.
cells : array
The cell indices corresponding to the reference coordinates.
status : array
The status: 0 is success, 1 is extrapolation within close_limit, 2 is extrapolation outside
close_limit, 3 is failure.
sfepy.discrete.fem.history module
class sfepy.discrete.fem.history.Histories(objs=None, **kwargs)
static from_file_hdf5(filename, var_names)
TODO: do not read entire file, provide data on demand.
class sfepy.discrete.fem.history.History(name, th=None, steps=None, times=None)
append(item, step, time)
static from_sequence(seq, name)
sfepy.discrete.fem.lcbc_operators module
Operators for enforcing linear combination boundary conditions in nodal FEM setting.
class sfepy.discrete.fem.lcbc_operators.EdgeDirectionOperator(name,
regions,
dof_names,
dof_map_fun,
filename,
variables,
ts=None,
functions=None)
Transformation matrix operator for edges direction LCBCs.
The substitution (in 3D) is:
[𝑢1 , 𝑢2 , 𝑢3 ]𝑇 = [𝑑1 , 𝑑2 , 𝑑3 ]𝑇 𝑤,
where 𝑑 is an edge direction vector averaged into a node. The new DOF is 𝑤.
get_vectors(nodes, region, field, filename=None)
kind = ‘edge_direction’
class sfepy.discrete.fem.lcbc_operators.IntegralMeanValueOperator(name, regions,
dof_names,
dof_map_fun,
variables,
ts=None, functions=None)
Transformation matrix operator for integral mean value LCBCs. All node DOFs are sumed to the new one.
kind = ‘integral_mean_value’
468
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.lcbc_operators.LCBCOperator(name,
regions,
dof_names,
dof_map_fun, variables, functions=None)
Base class for LCBC operators.
setup()
class sfepy.discrete.fem.lcbc_operators.LCBCOperators(name,
variables,
tions=None)
Container holding instances of LCBCOperator subclasses for a single variable.
func-
add_from_bc(bc, ts)
Create a new LCBC operator described by bc, and add it to the container.
Parameters bc : LinearCombinationBC instance
The LCBC condition description.
ts : TimeStepper instance
The time stepper.
append(op)
finalize()
Call this after all LCBCs of the variable have been added.
Initializes the global column indices and DOF counts.
make_global_operator(adi, new_only=False)
Assemble all LCBC operators into a single matrix.
Parameters adi : DofInfo
The active DOF information.
new_only : bool
If True, the operator columns will contain only new DOFs.
Returns mtx_lc : csr_matrix
The global LCBC operator in the form of a CSR matrix.
rhs_lc : array
The right-hand side for non-homogeneous LCBCs.
lcdi : DofInfo
The global active LCBC-constrained DOF information.
class sfepy.discrete.fem.lcbc_operators.MRLCBCOperator(name, regions, dof_names,
dof_map_fun, variables, functions=None)
Base class for model-reduction type LCBC operators.
setup()
treat_pbcs(dofs, master)
Treat dofs with periodic BC.
7.8. Module Index
469
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.lcbc_operators.NoPenetrationOperator(name,
regions,
dof_names,
dof_map_fun,
filename,
variables,
ts=None,
functions=None)
Transformation matrix operator for no-penetration LCBCs.
kind = ‘no_penetration’
class sfepy.discrete.fem.lcbc_operators.NormalDirectionOperator(name,
regions,
dof_names,
dof_map_fun,
filename,
variables, ts=None,
functions=None)
Transformation matrix operator for normal direction LCBCs.
The substitution (in 3D) is:
[𝑢1 , 𝑢2 , 𝑢3 ]𝑇 = [𝑛1 , 𝑛2 , 𝑛3 ]𝑇 𝑤
The new DOF is 𝑤.
get_vectors(nodes, region, field, filename=None)
kind = ‘normal_direction’
class sfepy.discrete.fem.lcbc_operators.RigidOperator(name,
regions,
dof_names,
dof_map_fun,
variables,
ts=None, functions=None)
Transformation matrix operator for rigid LCBCs.
kind = ‘rigid’
class sfepy.discrete.fem.lcbc_operators.ShiftedPeriodicOperator(name,
regions,
dof_names,
dof_map_fun,
shift_fun,
variables, ts, functions)
Transformation matrix operator shifted periodic boundary conditions.
kind = ‘shifted_periodic’
sfepy.discrete.fem.linearizer module
Linearization of higher order solutions for the purposes of visualization.
sfepy.discrete.fem.linearizer.create_output(eval_dofs, eval_coors, n_el, ps, min_level=0,
max_level=2, eps=0.0001)
Create mesh with linear elements that approximates DOFs returned by eval_dofs() corresponding to a higher
order approximation with a relative precision given by eps. The DOFs are evaluated in physical coordinates
returned by eval_coors().
sfepy.discrete.fem.linearizer.get_eval_coors(coors, conn, ps)
Get default function for evaluating physical coordinates given a list of elements and reference element coordinates.
sfepy.discrete.fem.linearizer.get_eval_dofs(dofs, dof_conn, ps, ori=None)
Get default function for evaluating field DOFs given a list of elements and reference element coordinates.
470
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.mappings module
Finite element reference mappings.
class sfepy.discrete.fem.mappings.FEMapping(coors, conn, poly_space=None, gel=None, order=1)
Base class for finite element mappings.
get_base(coors, diff=False)
Get base functions or their gradient evaluated in given coordinates.
get_geometry()
Return reference element geometry as a GeometryElement instance.
get_physical_qps(qp_coors)
Get physical quadrature points corresponding to given reference element quadrature points.
Returns qps : array
The physical quadrature points ordered element by element, i.e. with shape (n_el, n_qp,
dim).
class sfepy.discrete.fem.mappings.SurfaceMapping(coors,
conn,
poly_space=None,
gel=None, order=1)
Mapping from reference domain to physical domain of the space dimension higher by one.
get_mapping(qp_coors, weights, poly_space=None, mode=’surface’)
Get the mapping for given quadrature points, weights, and polynomial space.
Returns cmap : CMapping instance
The surface mapping.
class sfepy.discrete.fem.mappings.VolumeMapping(coors,
conn,
gel=None, order=1)
Mapping from reference domain to physical domain of the same space dimension.
poly_space=None,
get_mapping(qp_coors, weights, poly_space=None, ori=None)
Get the mapping for given quadrature points, weights, and polynomial space.
Returns cmap : CMapping instance
The volume mapping.
sfepy.discrete.fem.mesh module
class sfepy.discrete.fem.mesh.Mesh(name=’mesh’, filename=None, prefix_dir=None, **kwargs)
Contains the FEM mesh together with all utilities related to it.
Input and output is handled by the MeshIO class and subclasses. The Mesh class only contains the real mesh nodes, connectivity, regions, plus methods for doing operations on this mesh.
Example of creating and working with a mesh:
In [1]: from sfepy.discrete.fem import Mesh
In [2]: m = Mesh.from_file("meshes/3d/cylinder.vtk")
sfepy: reading mesh (meshes/3d/cylinder.vtk)...
sfepy: ...done in 0.04 s
In [3]: m.coors
Out[3]:
array([[ 1.00000000e-01,
7.8. Module Index
2.00000000e-02,
-1.22460635e-18],
471
SfePy Documentation, Release 2015.1
[ 1.00000000e-01,
[ 1.00000000e-01,
...,
[ 8.00298527e-02,
[ 7.02544004e-02,
[ 3.19633596e-02,
1.80193774e-02,
1.24697960e-02,
8.67767478e-03],
1.56366296e-02],
5.21598617e-03,
3.61610291e-04,
-1.00335972e-02,
-9.77772215e-05],
-1.16903153e-04],
9.60460305e-03]])
In [4]: m.ngroups
Out[4]: array([0, 0, 0, ..., 0, 0, 0])
In [5]: m.conns
Out[5]:
[array([[ 28, 60, 45, 29],
[ 28, 60, 57, 45],
[ 28, 57, 27, 45],
...,
[353, 343, 260, 296],
[353, 139, 181, 140],
[353, 295, 139, 140]])]
In [6]: m.mat_ids
Out[6]: [array([6, 6, 6, ..., 6, 6, 6])]
In [7]: m.descs
Out[7]: [’3_4’]
In [8]: m
Out[8]: Mesh:meshes/3d/cylinder
In [9]: print m
Mesh:meshes/3d/cylinder
conns:
[array([[ 28, 60, 45, 29],
[ 28, 60, 57, 45],
[ 28, 57, 27, 45],
...,
[353, 343, 260, 296],
[353, 139, 181, 140],
[353, 295, 139, 140]])]
coors:
[[ 1.00000000e-01
2.00000000e-02
[ 1.00000000e-01
1.80193774e-02
[ 1.00000000e-01
1.24697960e-02
...,
[ 8.00298527e-02
5.21598617e-03
[ 7.02544004e-02
3.61610291e-04
[ 3.19633596e-02 -1.00335972e-02
descs:
[’3_4’]
dim:
3
el_offsets:
[
0 1348]
io:
None
mat_ids:
[array([6, 6, 6, ..., 6, 6, 6])]
n_e_ps:
472
-1.22460635e-18]
8.67767478e-03]
1.56366296e-02]
-9.77772215e-05]
-1.16903153e-04]
9.60460305e-03]]
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
[4]
n_el:
1348
n_els:
[1348]
n_nod:
354
name:
meshes/3d/cylinder
ngroups:
[0 0 0 ..., 0 0 0]
setup_done:
0
The Mesh().coors is an array of node coordinates and Mesh().conns is the list of elements of each type (see
Mesh().desc), so for example if you want to know the coordinates of the nodes of the fifth finite element of the
type 3_4 do:
In [10]: m.descs
Out[10]: [’3_4’]
So now you know that the finite elements of the type 3_4 are in a.conns[0]:
In [11]: m.coors[m.conns[0][4]]
Out[11]:
array([[ 1.00000000e-01,
1.80193774e-02,
[ 1.00000000e-01,
1.32888539e-02,
[ 1.00000000e-01,
2.00000000e-02,
[ 9.22857574e-02,
1.95180454e-02,
-8.67767478e-03],
-4.35893200e-04],
-1.22460635e-18],
-4.36416134e-03]])
The element ids are of the form “<dimension>_<number of nodes>”, i.e.:
•2_2 ... line
•2_3 ... triangle
•2_4 ... quadrangle
•3_2 ... line
•3_4 ... tetrahedron
•3_8 ... hexahedron
copy(name=None)
Make a deep copy of self.
Parameters name : str
Name of the copied mesh.
create_conn_graph(verbose=True)
Create a graph of mesh connectivity.
Returns graph : csr_matrix
The mesh connectivity graph as a SciPy CSR matrix.
explode_groups(eps, return_emap=False)
Explode the mesh element groups by eps, i.e. split group interface nodes and shrink each group towards
its centre by eps.
Parameters eps : float in [0.0, 1.0]
7.8. Module Index
473
SfePy Documentation, Release 2015.1
The group shrinking factor.
return_emap : bool, optional
If True, also return the mapping against original mesh coordinates that result in the
exploded mesh coordinates. The mapping can be used to map mesh vertex data to the
exploded mesh vertices.
Returns mesh : Mesh
The new mesh with exploded groups.
emap : spmatrix, optional
The maping for exploding vertex values. Only provided if return_emap is True.
static from_data(name, coors, ngroups, conns, mat_ids, descs, igs=None, nodal_bcs=None)
Create a mesh from mesh data.
static from_file(filename=None, io=’auto’, prefix_dir=None, omit_facets=False)
Read a mesh from a file.
Parameters filename : string or function or MeshIO instance or Mesh instance
The name of file to read the mesh from. For convenience, a mesh creation function or a
MeshIO instance or directly a Mesh instance can be passed in place of the file name.
io : *MeshIO instance
Passing *MeshIO instance has precedence over filename.
prefix_dir : str
If not None, the filename is relative to that directory.
omit_facets : bool
If True, do not read cells of lower dimension than the space dimension (faces and/or
edges). Only some MeshIO subclasses support this!
static from_region(region, mesh_in, save_edges=False,
is_surface=False)
Create a mesh corresponding to a given region.
save_faces=False,
localize=False,
static from_surface(surf_faces, mesh_in)
Create a mesh given a set of surface faces and the original mesh.
get_bounding_box()
get_element_coors(ig=None)
Get the coordinates of vertices elements in group ig.
Parameters ig : int, optional
The element group. If None, the coordinates for all groups are returned, filled with zeros
at places of missing vertices, i.e. where elements having less then the full number of
vertices (n_ep_max) are.
Returns coors : array
The coordinates in an array of shape (n_el, n_ep_max, dim).
localize(inod)
Strips nodes not in inod and remaps connectivities. Omits elements where remap[conn] contains -1...
transform_coors(mtx_t, ref_coors=None)
Transform coordinates of the mesh by the given transformation matrix.
474
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Parameters mtx_t : array
The transformation matrix T (2D array). It is applied depending on its shape:
• (dim, dim): x = T * x
• (dim, dim + 1): x = T[:, :-1] * x + T[:, -1]
ref_coors : array, optional
Alternative coordinates to use for the transformation instead of the mesh coordinates,
with the same shape as self.coors.
write(filename=None, io=None, coors=None, igs=None, out=None, float_format=None, **kwargs)
Write mesh + optional results in out to a file.
Parameters filename : str, optional
The file name. If None, the mesh name is used instead.
io : MeshIO instance or ‘auto’, optional
Passing ‘auto’ respects the extension of filename.
coors : array, optional
The coordinates that can be used instead of the mesh coordinates.
igs : array_like, optional
Passing a list of group ids selects only those groups for writing.
out : dict, optional
The output data attached to the mesh vertices and/or cells.
float_format : str, optional
The format string used to print floats in case of a text file format.
**kwargs : dict, optional
Additional arguments that can be passed to the MeshIO instance.
sfepy.discrete.fem.mesh.find_map(x1, x2, eps=1e-08, allow_double=False, join=True)
Find a mapping between common coordinates in x1 and x2, such that x1[cmap[:,0]] == x2[cmap[:,1]]
sfepy.discrete.fem.mesh.fix_double_nodes(coor, ngroups, conns, eps)
Detect and attempt fixing double nodes in a mesh.
The double nodes are nodes having the same coordinates w.r.t. precision given by eps.
sfepy.discrete.fem.mesh.get_min_edge_size(coor, conns)
Get the smallest edge length.
sfepy.discrete.fem.mesh.get_min_vertex_distance(coor, guess)
Can miss the minimum, but is enough for our purposes.
sfepy.discrete.fem.mesh.get_min_vertex_distance_naive(coor)
sfepy.discrete.fem.mesh.make_inverse_connectivity(conns, n_nod, ret_offsets=True)
For each mesh node referenced in the connectivity conns, make a list of elements it belongs to.
sfepy.discrete.fem.mesh.make_mesh(coor, ngroups, conns, mesh_in)
Create a mesh reusing mat_ids and descs of mesh_in.
sfepy.discrete.fem.mesh.make_point_cells(indx, dim)
7.8. Module Index
475
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.mesh.merge_mesh(x1, ngroups1, conns1, mat_ids1, x2, ngroups2, conns2,
mat_ids2, cmap, eps=1e-08)
Merge two meshes in common coordinates found in x1, x2.
Notes
Assumes the same number and kind of element groups in both meshes!
sfepy.discrete.fem.meshio module
class sfepy.discrete.fem.meshio.ANSYSCDBMeshIO(filename, **kwargs)
format = ‘ansys_cdb’
static guess(filename)
static make_format(format)
read(mesh, **kwargs)
read_bounding_box()
read_dimension(ret_fd=False)
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.AVSUCDMeshIO(filename, **kwargs)
format = ‘avs_ucd’
static guess(filename)
read(mesh, **kwargs)
read_dimension()
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.AbaqusMeshIO(filename, **kwargs)
format = ‘abaqus’
static guess(filename)
read(mesh, **kwargs)
read_dimension()
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.BDFMeshIO(filename, **kwargs)
format = ‘nastran’
static format_str(str, idx, n=8)
read(mesh, **kwargs)
read_dimension(ret_fd=False)
write(filename, mesh, out=None, **kwargs)
476
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.meshio.ComsolMeshIO(filename, **kwargs)
format = ‘comsol’
read(mesh, **kwargs)
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.HDF5MeshIO(filename, **kwargs)
ch = ‘\xfe’
format = ‘hdf5’
read(mesh, **kwargs)
read_bounding_box(ret_fd=False, ret_dim=False)
read_data(step, filename=None)
read_data_header(dname, step=0, filename=None)
read_last_step(filename=None)
read_time_history(node_name, indx, filename=None)
read_time_stepper(filename=None)
read_times(filename=None)
Read true time step data from individual time steps.
Returns steps : array
The time steps.
times : array
The times of the time steps.
nts : array
The normalized times of the time steps, in [0, 1].
read_variables_time_history(var_names, ts, filename=None)
string = <module ‘string’ from ‘/usr/lib/python2.7/string.pyc’>
write(filename, mesh, out=None, ts=None, **kwargs)
class sfepy.discrete.fem.meshio.HypermeshAsciiMeshIO(filename, **kwargs)
format = ‘hmascii’
read(mesh, **kwargs)
read_dimension()
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.MEDMeshIO(filename, **kwargs)
format = ‘med’
read(mesh, **kwargs)
7.8. Module Index
477
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.meshio.MeditMeshIO(filename, **kwargs)
format = ‘medit’
read(mesh, omit_facets=False, **kwargs)
read_bounding_box(ret_fd=False, ret_dim=False)
read_dimension(ret_fd=False)
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.Mesh3DMeshIO(filename, **kwargs)
format = ‘mesh3d’
read(mesh, **kwargs)
read_dimension()
class sfepy.discrete.fem.meshio.MeshIO(filename, **kwargs)
The abstract class for importing and exporting meshes.
Read the docstring of the Mesh() class. Basically all you need to do is to implement the read() method:
def read(self, mesh, **kwargs):
nodes = ...
conns = ...
mat_ids = ...
descs = ...
mesh._set_data(nodes, conns, mat_ids, descs)
return mesh
See the Mesh class’ docstring how the nodes, conns, mat_ids and descs should look like. You just need to read
them from your specific format from disk.
To write a mesh to disk, just implement the write() method and use the information from the mesh instance (e.g.
nodes, conns, mat_ids and descs) to construct your specific format.
The methods read_dimension(), read_bounding_box() should be implemented in subclasses, as it is often possible to get that kind of information without reading the whole mesh file.
Optionally, subclasses can implement read_data() to read also computation results. This concerns mainly the
subclasses with implemented write() supporting the ‘out’ kwarg.
The default implementation od read_last_step() just returns 0. It should be reimplemented in subclasses capable
of storing several steps.
static any_from_filename(filename, prefix_dir=None)
Create a MeshIO instance according to the kind of filename.
Parameters filename : str, function or MeshIO subclass instance
The name of the mesh file. It can be also a user-supplied function accepting two arguments: mesh, mode, where mesh is a Mesh instance and mode is one of ‘read’,’write’,
or a MeshIO subclass instance.
prefix_dir : str
The directory name to prepend to filename.
Returns io : MeshIO subclass instance
The MeshIO subclass instance corresponding to the kind of filename.
478
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
call_msg = ‘called an abstract MeshIO instance!’
static for_format(filename, format=None, writable=False, prefix_dir=None)
Create a MeshIO instance for file filename with forced format.
Parameters filename : str
The name of the mesh file.
format : str
One of supported formats. If None, MeshIO.any_from_filename() is called
instead.
writable : bool
If True, verify that the mesh format is writable.
prefix_dir : str
The directory name to prepend to filename.
Returns io : MeshIO subclass instance
The MeshIO subclass instance corresponding to the format.
format = None
get_filename_trunk()
get_vector_format(dim)
read(mesh, omit_facets=False, **kwargs)
read_bounding_box(ret_fd=False, ret_dim=False)
read_data(step, filename=None)
read_dimension(ret_fd=False)
read_last_step()
The default implementation: just return 0 as the last step.
read_times(filename=None)
Read true time step data from individual time steps.
Returns steps : array
The time steps.
times : array
The times of the time steps.
nts : array
The normalized times of the time steps, in [0, 1].
Notes
The default implementation returns empty arrays.
set_float_format(format=None)
write(filename, mesh, **kwargs)
7.8. Module Index
479
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.meshio.NEUMeshIO(filename, **kwargs)
format = ‘gambit’
read(mesh, **kwargs)
read_dimension(ret_fd=False)
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.TetgenMeshIO(filename, **kwargs)
format = ‘tetgen’
static getele(fele)
Reads t.1.ele, returns a list of elements.
Example:
>>> elements, regions = self.getele("t.1.ele")
>>> elements
[(20, 154, 122, 258), (86, 186, 134, 238), (15, 309, 170, 310), (146,
229, 145, 285), (206, 207, 125, 211), (99, 193, 39, 194), (185, 197,
158, 225), (53, 76, 74, 6), (19, 138, 129, 313), (23, 60, 47, 96),
(119, 321, 1, 329), (188, 296, 122, 322), (30, 255, 177, 256), ...]
>>> regions
{100: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 7, ...],
...}
static getnodes(fnods)
Reads t.1.nodes, returns a list of nodes.
Example:
>>> self.getnodes("t.1.node")
[(0.0, 0.0, 0.0), (4.0, 0.0, 0.0), (0.0, 4.0, 0.0), (-4.0, 0.0, 0.0),
(0.0, 0.0, 4.0), (0.0, -4.0, 0.0), (0.0, -0.0, -4.0), (-2.0, 0.0,
-2.0), (-2.0, 2.0, 0.0), (0.0, 2.0, -2.0), (0.0, -2.0, -2.0), (2.0,
0.0, -2.0), (2.0, 2.0, 0.0), ... ]
read(mesh, **kwargs)
read_bounding_box()
read_dimension()
write(filename, mesh, out=None, **kwargs)
class sfepy.discrete.fem.meshio.UserMeshIO(filename, **kwargs)
Special MeshIO subclass that enables reading and writing a mesh using a user-supplied function.
format = ‘function’
get_filename_trunk()
read(mesh, *args, **kwargs)
write(filename, mesh, *args, **kwargs)
480
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.meshio.VTKMeshIO(filename, **kwargs)
format = ‘vtk’
get_dimension(coors)
read(mesh, **kwargs)
read_bounding_box(ret_fd=False, ret_dim=False)
read_coors(ret_fd=False)
read_data(step, filename=None)
Point data only!
read_dimension(ret_fd=False)
write(filename, mesh, out=None, ts=None, **kwargs)
sfepy.discrete.fem.meshio.convert_complex_output(out_in)
Convert complex values in the output dictionary out_in to pairs of real and imaginary parts.
sfepy.discrete.fem.meshio.guess_format(filename, ext, formats, io_table)
Guess the format of filename, candidates are in formats.
sfepy.discrete.fem.meshio.join_conn_groups(conns, descs, mat_ids, concat=False)
Join groups of the same element type.
sfepy.discrete.fem.meshio.mesh_from_groups(mesh, ids, coors, ngroups, tris, mat_tris,
quads, mat_quads, tetras, mat_tetras, hexas,
mat_hexas, remap=None)
sfepy.discrete.fem.meshio.output_writable_meshes()
sfepy.discrete.fem.meshio.sort_by_mat_id(conns_in)
Sort by mat_id within a group, preserve order.
sfepy.discrete.fem.meshio.sort_by_mat_id2(conns_in, mat_ids_in)
Sort by mat_id within a group, preserve order.
sfepy.discrete.fem.meshio.split_by_mat_id(conns_in, mat_ids_in, descs_in)
Notes
conns_in must be sorted by mat_id within a group!
sfepy.discrete.fem.meshio.write_bb(fd, array, dtype)
sfepy.discrete.fem.periodic module
sfepy.discrete.fem.periodic.match_coors(coors1, coors2)
Match coordinates coors1 with coors2.
sfepy.discrete.fem.periodic.match_grid_line(coor1, coor2, which)
Match coordinates coor1 with coor2 along the axis which.
sfepy.discrete.fem.periodic.match_grid_plane(coor1, coor2, which)
Match coordinates coor1 with coor2 along the plane with normal axis which.
sfepy.discrete.fem.periodic.match_x_line(coor1, coor2)
sfepy.discrete.fem.periodic.match_x_plane(coor1, coor2)
7.8. Module Index
481
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.periodic.match_y_line(coor1, coor2)
sfepy.discrete.fem.periodic.match_y_plane(coor1, coor2)
sfepy.discrete.fem.periodic.match_z_line(coor1, coor2)
sfepy.discrete.fem.periodic.match_z_plane(coor1, coor2)
sfepy.discrete.fem.periodic.set_accuracy(eps)
sfepy.discrete.fem.poly_spaces module
class sfepy.discrete.fem.poly_spaces.LagrangeNodes(**kwargs)
Helper class for defining nodes of Lagrange elements.
static append_bubbles(nodes, nts, iseq, nt, order)
static append_edges(nodes, nts, iseq, nt, edges, order)
static append_faces(nodes, nts, iseq, nt, faces, order)
static append_tp_bubbles(nodes, nts, iseq, nt, ao)
static append_tp_edges(nodes, nts, iseq, nt, edges, ao)
static append_tp_faces(nodes, nts, iseq, nt, faces, ao)
class sfepy.discrete.fem.poly_spaces.LagrangeSimplexBPolySpace(name, geometry, order)
Lagrange polynomial space with forced bubble function on a simplex domain.
name = ‘lagrange_simplex_bubble’
class sfepy.discrete.fem.poly_spaces.LagrangeSimplexPolySpace(name, geometry, order)
Lagrange polynomial space on a simplex domain.
name = ‘lagrange_simplex’
class sfepy.discrete.fem.poly_spaces.LagrangeTensorProductPolySpace(name, geometry,
order)
Lagrange polynomial space on a tensor product domain.
get_mtx_i()
name = ‘lagrange_tensor_product’
class sfepy.discrete.fem.poly_spaces.LobattoTensorProductPolySpace(name, geometry, order)
Hierarchical polynomial space using Lobatto functions.
Each row of the nodes attribute defines indices of Lobatto functions that need to be multiplied together to
evaluate the corresponding shape function. This defines the ordering of basis functions on the reference element.
name = ‘lobatto_tensor_product’
class sfepy.discrete.fem.poly_spaces.NodeDescription(node_types, nodes)
Describe FE nodes defined on different parts of a reference element.
has_extra_nodes()
Return True if the element has some edge, face or bubble nodes.
482
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.discrete.fem.poly_spaces.PolySpace(name, geometry, order)
Abstract polynomial space class.
static any_from_args(name, geometry, order, base=’lagrange’, force_bubble=False)
Construct a particular polynomial space classes according to the arguments passed in.
describe_nodes()
eval_base(coors, diff=False, ori=None, force_axis=False, suppress_errors=False, eps=1e-15)
Evaluate the basis in points given by coordinates. The real work is done in _eval_base() implemented in
subclasses.
Parameters coors : array_like
The coordinates of points where the basis is evaluated. See Notes.
diff : bool
If True, return the first derivative.
ori : array_like, optional
Optional orientation of element facets for per element basis.
force_axis : bool
If True, force the resulting array shape to have one more axis even when ori is None.
suppress_errors : bool
If True, do not report points outside the reference domain.
eps : float
Accuracy for comparing coordinates.
Returns base : array
The basis (shape (n_coor, 1, n_base)) or its derivative (shape (n_coor, dim, n_base))
evaluated in the given points. An additional axis is pre-pended of length n_cell, if ori is
given, or of length 1, if force_axis is True.
Notes
If coors.ndim == 3, several point sets are assumed, with equal number of points in each of them. This is
the case, for example, of the values of the volume base functions on the element facets. The indexing (of
bf_b(g)) is then (ifa,iqp,:,n_ep), so that the facet can be set in C using FMF_SetCell.
get_mtx_i()
keys = {(1, 2): ‘simplex’, (3, 4): ‘simplex’, (3, 8): ‘tensor_product’, (2, 3): ‘simplex’, (2, 4): ‘tensor_product’}
static suggest_name(geometry, order, base=’lagrange’, force_bubble=False)
Suggest the polynomial space name given its constructor parameters.
sfepy.discrete.fem.refine module
Basic uniform mesh refinement functions.
sfepy.discrete.fem.refine.refine_2_3(mesh_in, cmesh)
Refines mesh out of triangles by cutting cutting each edge in half and making 4 new finer triangles out of one
coarser one.
7.8. Module Index
483
SfePy Documentation, Release 2015.1
sfepy.discrete.fem.refine.refine_2_4(mesh_in, cmesh)
Refines mesh out of quadrilaterals by cutting cutting each edge in half and making 4 new finer quadrilaterals out
of one coarser one.
sfepy.discrete.fem.refine.refine_3_4(mesh_in, cmesh)
Refines tetrahedra by cutting each edge in half and making 8 new finer tetrahedra out of one coarser one. Old
nodal coordinates come first in coors, then the new ones. The new tetrahedra are similar to the old one, no
degeneration is supposed to occur as at most 3 congruence classes of tetrahedra appear, even when re-applied
iteratively (provided that conns are not modified between two applications - ordering of vertices in tetrahedra
matters not only for positivity of volumes).
References:
•Juergen Bey: Simplicial grid refinement: on Freudenthal s algorithm and the optimal number of congruence classes, Numer.Math. 85 (2000), no. 1, 1–29, or
•Juergen Bey: Tetrahedral grid refinement, Computing 55 (1995), no.
http://citeseer.ist.psu.edu/bey95tetrahedral.html
4, 355–378, or
sfepy.discrete.fem.refine.refine_3_8(mesh_in, cmesh)
Refines hexahedral mesh by cutting cutting each edge in half and making 8 new finer hexahedrons out of one
coarser one.
sfepy.discrete.fem.refine.refine_reference(geometry, level)
Refine reference element given by geometry.
Notes
The error edges must be generated in the order of the connectivity of the previous (lower) level.
sfepy.discrete.fem.utils module
sfepy.discrete.fem.utils.compute_nodal_edge_dirs(nodes,
region,
field,
return_imap=False)
Nodal edge directions are computed by simple averaging of direction vectors of edges a node is contained in.
Edges are assumed to be straight and a node must be on a single edge (a border node) or shared by exactly two
edges.
sfepy.discrete.fem.utils.compute_nodal_normals(nodes,
region,
field,
return_imap=False)
Nodal normals are computed by simple averaging of element normals of elements every node is contained in.
sfepy.discrete.fem.utils.extend_cell_data(data,
domain,
rname,
val=None,
is_surface=False, average_surface=True)
Extend cell data defined in a region to the whole domain.
Parameters data : array
The data defined in the region.
domain : FEDomain instance
The FE domain.
rname : str
The region name.
val : float, optional
484
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The value for filling cells not covered by the region. If not given, the smallest value in
data is used.
is_surface : bool
If True, the data are defined on a surface region. In that case the values are averaged or
summed into the cells containing the region surface faces (a cell can have several faces
of the surface), see average_surface.
average_surface : bool
If True, the data defined on a surface region are averaged, otherwise the data are
summed.
Returns edata : array
The data extended to all domain elements.
sfepy.discrete.fem.utils.get_edge_paths(graph, mask)
Get all edge paths in a graph with non-masked vertices. The mask is updated.
sfepy.discrete.fem.utils.get_min_value(dofs)
Get a reasonable minimal value of DOFs suitable for extending over a whole domain.
sfepy.discrete.fem.utils.invert_remap(remap)
Return the inverse of remap, i.e. a mapping from a sub-range indices to a full range, see prepare_remap().
sfepy.discrete.fem.utils.prepare_remap(indices, n_full)
Prepare vector for remapping range [0, n_full] to its subset given by indices.
sfepy.discrete.fem.utils.prepare_translate(old_indices, new_indices)
Prepare vector for translating old_indices to new_indices.
Returns translate : array
The translation vector. Then new_ar = translate[old_ar].
sfepy.discrete.fem.utils.refine_mesh(filename, level)
Uniformly refine level-times a mesh given by filename.
The refined mesh is saved to a file with name constructed from base name of filename and level-times appended
‘_r’ suffix.
Parameters filename : str
The mesh file name.
level : int
The refinement level.
sfepy.discrete.iga sub-package
sfepy.discrete.iga.domain module
Computational domain for isogeometric analysis.
class sfepy.discrete.iga.domain.IGDomain(name, nurbs, bmesh, regions=None, **kwargs)
Bezier extraction based NURBS domain for isogeometric analysis.
static from_file(filename)
filename [str] The name of the IGA domain file.
7.8. Module Index
485
SfePy Documentation, Release 2015.1
class sfepy.discrete.iga.domain.NurbsPatch(knots, degrees, cps, weights, cs, conn)
Single NURBS patch data.
elevate(times=0)
Elevate the patch degrees several times by one.
Returns nurbs : NurbsPatch instance
Either self if times is zero, or a new instance.
evaluate(field, u=None, v=None, w=None)
Igakit-like interface for NURBS evaluation.
sfepy.discrete.iga.domain_generators module
IGA domain generators.
sfepy.discrete.iga.domain_generators.create_from_igakit(inurbs, verbose=False)
Create IGDomain data from a given igakit NURBS object.
Parameters inurbs : igakit.nurbs.NURBS instance
The igakit NURBS object.
Returns nurbs : NurbsPatch instance
The NURBS data. The igakit NURBS object is stored as nurbs attribute.
bmesh : Struct instance
The Bezier mesh data.
regions : dict
The patch surface regions.
sfepy.discrete.iga.domain_generators.gen_patch_block_domain(dims, shape, centre,
degrees,
continuity=None,
cp_mode=’greville’,
name=’block’,
verbose=True)
Generate a single IGA patch block in 2D or 3D of given degrees and continuity using igakit.
Parameters dims : array of D floats
Dimensions of the block.
shape : array of D ints
Numbers of unique knot values along each axis.
centre : array of D floats
Centre of the block.
degrees : array of D floats
NURBS degrees along each axis.
continuity : array of D ints, optional
NURBS continuity along each axis. If None, degrees-1 is used.
cp_mode : ‘greville’ or ‘uniform’
486
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The control points mode. The default ‘greville’ results in a uniform Bezier mesh, while
the ‘uniform’ mode results in a uniform grid of control points a finer Bezier mesh inside
the block and a coarser Bezier mesh near the block boundary.
name : string
Domain name.
verbose : bool
If True, report progress of the domain generation.
Returns nurbs : NurbsPatch instance
The NURBS data. The igakit NURBS object is stored as nurbs attribute.
bmesh : Struct instance
The Bezier mesh data.
regions : dict
The patch surface regions.
sfepy.discrete.iga.extmods.igac module
sfepy.discrete.iga.extmods.igac.eval_bernstein_basis()
sfepy.discrete.iga.extmods.igac.eval_in_tp_coors()
Evaluate a field variable (if given) or the NURBS geometry in the given tensor-product reference coordinates.
The field variable is defined by its DOFs - the coefficients of the NURBS basis.
Parameters variable : array
The DOF values of the variable with n_c components, shape (:, n_c).
indices : list of arrays
The indices of knot spans for each axis, defining the Bezier element numbers.
ref_coors : list of arrays
The reference coordinates in [0, 1] for each knot span for each axis, defining the reference coordinates in the Bezier elements given by indices.
control_points : array
The NURBS control points.
weights : array
The NURBS weights.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
Returns out : array
7.8. Module Index
487
SfePy Documentation, Release 2015.1
The field variable values or NURBS geometry coordinates for the given reference coordinates.
sfepy.discrete.iga.extmods.igac.eval_mapping_data_in_qp()
Evaluate data required for the isogeometric domain reference mapping in the given quadrature points. The
quadrature points are the same for all Bezier elements and should correspond to the Bernstein basis degree.
Parameters qps : array
The quadrature points coordinates with components in [0, 1] reference element domain.
control_points : array
The NURBS control points.
weights : array
The NURBS weights.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
cells : array, optional
If given, use only the given Bezier elements.
Returns bfs : array
The NURBS shape functions in the physical quadrature points of all elements.
bfgs : array
The NURBS shape functions derivatives w.r.t. the physical coordinates in the physical
quadrature points of all elements.
dets : array
The Jacobians of the mapping to the unit reference element in the physical quadrature
points of all elements.
sfepy.discrete.iga.extmods.igac.eval_variable_in_qp()
Evaluate a field variable in the given quadrature points. The quadrature points are the same for all Bezier
elements and should correspond to the Bernstein basis degree. The field variable is defined by its DOFs - the
coefficients of the NURBS basis.
Parameters variable : array
The DOF values of the variable with n_c components, shape (:, n_c).
qps : array
The quadrature points coordinates with components in [0, 1] reference element domain.
control_points : array
The NURBS control points.
weights : array
The NURBS weights.
488
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
cells : array, optional
If given, use only the given Bezier elements.
Returns coors : array
The physical coordinates of the quadrature points of all elements.
vals : array
The field variable values in the physical quadrature points.
dets : array
The Jacobians of the mapping to the unit reference element in the physical quadrature
points.
sfepy.discrete.iga.extmods.igac.is_nurbs()
Return True if some weights are not one.
sfepy.discrete.iga.fields module
Fields for isogeometric analysis.
class sfepy.discrete.iga.fields.IGField(name, dtype, shape, region, approx_order=None,
**kwargs)
Bezier extraction based NURBS field for isogeometric analysis.
Notes
The field has to cover the whole IGA domain. The field’s NURBS basis can have higher degree than the domain
NURBS basis.
create_mapping(ig, region, integral, integration)
Create a new reference mapping.
create_output(dofs, var_name, dof_names=None, key=None, **kwargs)
Convert the DOFs corresponding to the field to a dictionary of output data usable by Mesh.write().
Parameters dofs : array, shape (n_nod, n_component)
The array of DOFs reshaped so that each column corresponds to one component.
var_name : str
The variable name corresponding to dofs.
dof_names : tuple of str
The names of DOF components.
key : str, optional
7.8. Module Index
489
SfePy Documentation, Release 2015.1
The key to be used in the output dictionary instead of the variable name.
Returns out : dict
The output dictionary.
family_name = ‘volume_H1_iga’
get_data_shape(ig, integral, integration=’volume’, region_name=None)
Get element data dimensions.
Parameters ig : int
The element group index.
integral : Integral instance
The integral describing used numerical quadrature.
integration : ‘volume’, ‘plate’, ‘surface’, ‘surface_extra’ or ‘point’
The term integration type.
region_name : str
The name of surface region, required when shape_kind is ‘surface’.
Returns data_shape : 4 ints
The (n_el, n_qp, dim, n_en) for volume shape kind.
Notes
•n_el = number of elements
•n_qp = number of quadrature points per element/facet
•dim = spatial dimension
•n_en = number of element nodes
get_dofs_in_region_group(region, ig, merge=True)
Return indices of DOFs that belong to the given region and group.
Notes
ig, merge are not used.
get_econn(conn_type, region, ig, is_trace=False, integration=None)
Get DOF connectivity of the given type in the given region.
get_true_order()
is_higher_order()
Return True, if the field’s approximation order is greater than one.
set_dofs(fun=0.0, region=None, dpn=None, warn=None)
Set the values of DOFs given by the region using a function of space coordinates or value fun.
If fun is a function, the l2 projection that is global for all region facets is used to set the DOFs.
If dpn > 1, and fun is a function, it has to return the values DOF-by-DOF, i.e. a single one-dimensional
vector with all values of the first component, then of the second one etc. concatenated together.
490
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Parameters fun : float or array of length dpn or callable
The DOF values.
region : Region
The region containing the DOFs.
dpn : int, optional
The DOF-per-node count. If not given, the number of field components is used.
warn : str, optional
The warning message printed when the region selects no DOFs.
Returns nods : array, shape (n_dof,)
The field DOFs (or node indices) given by the region.
vals : array, shape (dpn, n_dof)
The values of the DOFs, DOF-by-DOF when raveled in C (row-major) order.
setup_extra_data(geometry, info, is_trace)
sfepy.discrete.iga.fields.parse_approx_order(approx_order)
sfepy.discrete.iga.iga module
Isogeometric analysis utilities.
Notes The functions compute_bezier_extraction_1d() and eval_nurbs_basis_tp() implement
the algorithms described in [1].
[1] Michael J. Borden, Michael A. Scott, John A. Evans, Thomas J. R. Hughes: Isogeometric finite element data
structures based on Bezier extraction of NURBS, Institute for Computational Engineering and Sciences, The
University of Texas at Austin, Austin, Texas, March 2010.
sfepy.discrete.iga.iga.combine_bezier_extraction(cs)
For a nD B-spline parametric domain, combine the 1D element extraction operators in each parametric dimension into a single operator for each nD element.
Parameters cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
Returns ccs : list of 2D arrays
The combined element extraction operators.
sfepy.discrete.iga.iga.compute_bezier_control(control_points,
bconn)
Compute the control points and weights of the Bezier mesh.
weights,
ccs,
conn,
Parameters control_points : array
The NURBS control points.
weights : array
The NURBS weights.
ccs : list of 2D arrays
The combined element extraction operators.
7.8. Module Index
491
SfePy Documentation, Release 2015.1
conn : array
The connectivity of the global NURBS basis.
bconn : array
The connectivity of the Bezier basis.
Returns bezier_control_points : array
The control points of the Bezier mesh.
bezier_weights : array
The weights of the Bezier mesh.
sfepy.discrete.iga.iga.compute_bezier_extraction(knots, degrees)
Compute local (element) Bezier extraction operators for a nD B-spline parametric domain.
Parameters knots : sequence of array or array
The knot vectors.
degrees : sequence of ints or int
Polynomial degrees in each parametric dimension.
Returns cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
sfepy.discrete.iga.iga.compute_bezier_extraction_1d(knots, degree)
Compute local (element) Bezier extraction operators for a 1D B-spline parametric domain.
Parameters knots : array
The knot vector.
degree : int
The curve degree.
Returns cs : array of 2D arrays (3D array)
The element extraction operators.
sfepy.discrete.iga.iga.create_boundary_qp(coors, dim)
Create boundary quadrature points from the surface quadrature points.
Uses the Bezier element tensor product structure.
Parameters coors : array, shape (n_qp, d)
The coordinates of the surface quadrature points.
dim : int
The topological dimension.
Returns bcoors : array, shape (n_qp, d + 1)
The coordinates of the boundary quadrature points.
sfepy.discrete.iga.iga.create_connectivity(n_els, knots, degrees)
Create connectivity arrays of nD Bezier elements.
Parameters n_els : sequence of ints
The number of elements in each parametric dimension.
492
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
knots : sequence of array or array
The knot vectors.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
Returns conn : array
The connectivity of the global NURBS basis.
bconn : array
The connectivity of the Bezier basis.
sfepy.discrete.iga.iga.create_connectivity_1d(n_el, knots, degree)
Create connectivity arrays of 1D Bezier elements.
Parameters n_el : int
The number of elements.
knots : array
The knot vector.
degree : int
The basis degree.
Returns conn : array
The connectivity of the global NURBS basis.
bconn : array
The connectivity of the Bezier basis.
sfepy.discrete.iga.iga.eval_bernstein_basis(x, degree)
Evaluate the Bernstein polynomial basis of the given degree, and its derivatives, in a point x in [0, 1].
Parameters x : float
The point in [0, 1].
degree : int
The basis degree.
Returns funs : array
The degree + 1 values of the Bernstein polynomial basis.
ders : array
The degree + 1 values of the Bernstein polynomial basis derivatives.
sfepy.discrete.iga.iga.eval_mapping_data_in_qp(qps, control_points, weights, degrees, cs,
conn, cells=None)
Evaluate data required for the isogeometric domain reference mapping in the given quadrature points. The
quadrature points are the same for all Bezier elements and should correspond to the Bernstein basis degree.
Parameters qps : array
The quadrature points coordinates with components in [0, 1] reference element domain.
control_points : array
The NURBS control points.
7.8. Module Index
493
SfePy Documentation, Release 2015.1
weights : array
The NURBS weights.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
cells : array, optional
If given, use only the given Bezier elements.
Returns bfs : array
The NURBS shape functions in the physical quadrature points of all elements.
bfgs : array
The NURBS shape functions derivatives w.r.t. the physical coordinates in the physical
quadrature points of all elements.
dets : array
The Jacobians of the mapping to the unit reference element in the physical quadrature
points of all elements.
sfepy.discrete.iga.iga.eval_nurbs_basis_tp(qp, ie, control_points, weights, degrees, cs,
conn)
Evaluate the tensor-product NURBS shape functions in a quadrature point for a given Bezier element.
Parameters qp : array
The quadrature point coordinates with components in [0, 1] reference element domain.
ie : int
The Bezier element index.
control_points : array
The NURBS control points.
weights : array
The NURBS weights.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
Returns R : array
The NURBS shape functions.
dR_dx : array
494
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The NURBS shape functions derivatives w.r.t. the physical coordinates.
det : array
The Jacobian of the mapping to the unit reference element.
sfepy.discrete.iga.iga.eval_variable_in_qp(variable, qps, control_points, weights, degrees,
cs, conn, cells=None)
Evaluate a field variable in the given quadrature points. The quadrature points are the same for all Bezier
elements and should correspond to the Bernstein basis degree. The field variable is defined by its DOFs - the
coefficients of the NURBS basis.
Parameters variable : array
The DOF values of the variable with n_c components, shape (:, n_c).
qps : array
The quadrature points coordinates with components in [0, 1] reference element domain.
control_points : array
The NURBS control points.
weights : array
The NURBS weights.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
cs : list of lists of 2D arrays
The element extraction operators in each parametric dimension.
conn : array
The connectivity of the global NURBS basis.
cells : array, optional
If given, use only the given Bezier elements.
Returns coors : array
The physical coordinates of the quadrature points of all elements.
vals : array
The field variable values in the physical quadrature points.
dets : array
The Jacobians of the mapping to the unit reference element in the physical quadrature
points.
sfepy.discrete.iga.iga.get_bezier_element_entities(degrees)
Get faces and edges of a Bezier mesh element in terms of indices into the element’s connectivity (reference
Bezier element entities).
Parameters degrees : sequence of ints or int
Polynomial degrees in each parametric dimension.
Returns faces : list of arrays
The indices for each face or None if not 3D.
edges : list of arrays
7.8. Module Index
495
SfePy Documentation, Release 2015.1
The indices for each edge or None if not at least 2D.
vertices : list of arrays
The indices for each vertex.
Notes
The ordering of faces and edges has to be the same as in sfepy.discrete.fem.geometry_element.geometry_data.
sfepy.discrete.iga.iga.get_bezier_topology(bconn, degrees)
Get a topology connectivity corresponding to the Bezier mesh connectivity.
In the referenced Bezier control points the Bezier mesh is interpolatory.
Parameters bconn : array
The connectivity of the Bezier basis.
degrees : sequence of ints or int
The basis degrees in each parametric dimension.
Returns tconn : array
The topology connectivity (corner nodes, or vertices, of Bezier elements) with vertex
ordering suitable for a FE mesh.
sfepy.discrete.iga.iga.get_facet_axes(dim)
For each reference Bezier element facet return the facet axes followed by the remaining (perpendicular) axis, as
well as the remaining axis coordinate of the facet.
Parameters dim : int
The topological dimension.
Returns axes : array
The axes of the reference element facets.
coors : array
The remaining coordinate of the reference element facets.
sfepy.discrete.iga.iga.get_patch_box_regions(n_els, degrees)
Get box regions of Bezier topological mesh in terms of element corner vertices of Bezier mesh.
Parameters n_els : sequence of ints
The number of elements in each parametric dimension.
degrees : sequence of ints or int
Polynomial degrees in each parametric dimension.
Returns regions : dict
The Bezier mesh vertices of box regions.
sfepy.discrete.iga.iga.get_raveled_index(indices, shape)
Get a global raveled index corresponding to nD indices into an array of the given shape.
sfepy.discrete.iga.iga.get_surface_degrees(degrees)
Get degrees of the NURBS patch surfaces.
Parameters degrees : sequence of ints or int
496
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Polynomial degrees in each parametric dimension.
Returns sdegrees : list of arrays
The degrees of the patch surfaces, in the order of the reference Bezier element facets.
sfepy.discrete.iga.iga.get_unraveled_indices(index, shape)
Get nD indices into an array of the given shape corresponding to a global raveled index.
sfepy.discrete.iga.iga.tensor_product(a, b)
Compute tensor product of two 2D arrays with possibly different shapes. The result has the form:
c = [[a00 b, a01 b, ...],
[a10 b, a11 b, ...],
...
...
]
sfepy.discrete.iga.io module
IO for NURBS and Bezier extraction data.
sfepy.discrete.iga.io.read_iga_data(filename)
Read IGA-related data from a HDF5 file using pytables.
sfepy.discrete.iga.io.write_iga_data(filename, knots, degrees, control_points, weights,
cs, conn, bezier_control_points, bezier_weights,
bezier_conn, regions)
Write IGA-related data into a HDF5 file using pytables.
sfepy.discrete.iga.mappings module
Reference mappings for isogeometric analysis.
class sfepy.discrete.iga.mappings.IGMapping(domain, cells, nurbs=None)
Reference mapping for isogeometric analysis based on Bezier extraction.
Parameters domain : IGDomain instance
The mapping domain.
cells : array
The mapping region cells. (All domain cells required.)
nurbs : NurbsPatch instance, optional
If given, the nurbs is used instead of domain.nurbs. The nurbs has to be obtained by
degree elevation of domain.nurbs.
get_geometry()
Return reference element geometry as a GeometryElement instance.
get_mapping(qp_coors, weights)
Get the mapping for given quadrature points and weights.
Returns cmap : CMapping instance
The reference mapping.
7.8. Module Index
497
SfePy Documentation, Release 2015.1
Notes
Does not set total volume of the C mapping structure!
get_physical_qps(qp_coors)
Get physical quadrature points corresponding to given reference Bezier element quadrature points.
Returns qps : array
The physical quadrature points ordered element by element, i.e. with shape (n_el, n_qp,
dim).
sfepy.discrete.iga.plot_nurbs module
sfepy.discrete.iga.plot_nurbs.plot_bezier_mesh(ax, control_points, conn, degrees, label=False)
Plot the Bezier mesh of a NURBS given by its control points and connectivity.
sfepy.discrete.iga.plot_nurbs.plot_bezier_nurbs_basis_1d(ax,
control_points,
weights, degrees, cs,
conn, n_points=20)
Plot a 1D NURBS basis using the Bezier extraction and local Bernstein basis.
sfepy.discrete.iga.plot_nurbs.plot_control_mesh(ax, control_points, label=False)
Plot the control mesh of a NURBS given by its control points.
sfepy.discrete.iga.plot_nurbs.plot_iso_lines(ax, nurbs, color=’b’, n_points=100)
Plot the NURBS object using iso-lines in Greville abscissae coordinates.
sfepy.discrete.iga.plot_nurbs.plot_nurbs_basis_1d(ax,
nurbs,
n_points=100,
x_axis=’parametric’,
legend=False)
Plot a 1D NURBS basis.
sfepy.discrete.iga.plot_nurbs.plot_parametric_mesh(ax, knots)
Plot the parametric mesh of a NURBS given by its knots.
sfepy.discrete.iga.utils module
Utility functions based on igakit.
sfepy.discrete.iga.utils.create_linear_fe_mesh(nurbs, pars=None)
Convert a NURBS object into a nD-linear tensor product FE mesh.
Parameters nurbs : igakit.nurbs.NURBS instance
The NURBS object.
pars : sequence of array, optional
The values of parameters in each parametric dimension. If not given, the values are set
so that the resulting mesh has the same number of vertices as the number of control
points/basis functions of the NURBS object.
Returns coors : array
The coordinates of mesh vertices.
conn : array
The vertex connectivity array.
498
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
desc : str
The cell kind.
sfepy.discrete.iga.utils.create_mesh_and_output(nurbs, pars=None, **kwargs)
Create a nD-linear tensor product FE mesh using create_linear_fe_mesh(), evaluate field variables
given as keyword arguments in the mesh vertices and create a dictionary of output data usable by Mesh.write().
Parameters nurbs : igakit.nurbs.NURBS instance
The NURBS object.
pars : sequence of array, optional
The values of parameters in each parametric dimension. If not given, the values are set
so that the resulting mesh has the same number of vertices as the number of control
points/basis functions of the NURBS object.
**kwargs : kwargs
The field variables as keyword arguments. Their names serve as keys in the output
dictionary.
Returns mesh : Mesh instance
The finite element mesh.
out : dict
The output dictionary.
sfepy.discrete.iga.utils.save_basis(nurbs, pars)
Save a NURBS object basis on a FE mesh corresponding to the given parametrization in VTK files.
Parameters nurbs : igakit.nurbs.NURBS instance
The NURBS object.
pars : sequence of array, optional
The values of parameters in each parametric dimension.
7.8.7 sfepy.homogenization package
sfepy.homogenization.band_gaps_app module
class sfepy.homogenization.band_gaps_app.AcousticBandGapsApp(conf, options, output_prefix, **kwargs)
Application for computing acoustic band gaps.
call()
Construct and call the homogenization engine accoring to options.
plot_band_gaps(coefs)
plot_dispersion(coefs)
static process_options(options)
Application options setup. Sets default values for missing non-compulsory options.
static process_options_pv(options)
Application options setup for phase velocity computation. Sets default values for missing non-compulsory
options.
setup_options()
7.8. Module Index
499
SfePy Documentation, Release 2015.1
sfepy.homogenization.band_gaps_app.plot_eigs(fig_num, plot_rsc, plot_labels, valid,
freq_range,
plot_range,
show=False,
clear=False, new_axes=False)
Plot resonance/eigen-frequencies.
valid must correspond to freq_range
resonances : red masked resonances: dotted red
sfepy.homogenization.band_gaps_app.plot_gap(ax, ii, f0, f1, kind, kind_desc, gmin, gmax,
plot_range, plot_rsc)
Plot a single band gap as a rectangle.
sfepy.homogenization.band_gaps_app.plot_gaps(fig_num, plot_rsc, gaps, kinds, freq_range,
plot_range, show=False, clear=False,
new_axes=False)
Plot band gaps as rectangles.
sfepy.homogenization.band_gaps_app.plot_logs(fig_num,
plot_rsc,
plot_labels,
freqs,
logs,
valid,
freq_range,
plot_range,
draw_eigs=True,
show_legend=True,
show=False,
clear=False, new_axes=False)
Plot logs of min/middle/max eigs of a mass matrix.
sfepy.homogenization.band_gaps_app.transform_plot_data(datas,
conf )
plot_transform,
sfepy.homogenization.band_gaps_app.try_set_defaults(obj, attr, defaults, recur=False)
sfepy.homogenization.coefficients module
class sfepy.homogenization.coefficients.Coefficients(**kwargs)
Class for storing (homogenized) material coefficients.
static from_file_hdf5(filename)
to_file_hdf5(filename)
to_file_latex(filename, names, format=’%.2e’, cdot=False, filter=None)
Save the coefficients to a file in LaTeX format.
Parameters filename : str
The name of the output file.
names : dict
Mapping of attribute names to LaTeX names.
format : str
Format string for numbers.
cdot : bool
For ‘%.e’ formats only. If True, replace ‘e’ by LaTeX ‘cdot 10^{exponent}’ format.
filter : int
For ‘%.e’ formats only. Typeset as 0, if exponent is less than filter.
to_file_txt(filename, names, format)
to_latex(attr_name, dim, style=’table’, format=’%f’, step=None)
500
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.homogenization.coefs_base module
class sfepy.homogenization.coefs_base.CoefDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CoefDimDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CoefDimSym(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CoefDummy(name, problem, kwargs)
Dummy class serving for computing and returning its requirements.
class sfepy.homogenization.coefs_base.CoefEval(name, problem, kwargs)
Evaluate expression.
class sfepy.homogenization.coefs_base.CoefExprPar(name, problem, kwargs)
The coefficient which expression can be parametrized via ‘expr_pars’, the dimension is given by the number of
parameters.
Example:
‘expression’: ‘dw_surface_ndot.5.Ys(mat_norm.k%d, corr1)’, ‘expr_pars’: [ii for ii in range(dim)],
‘class’: cb.CoefExprPar,
static set_variables_default(variables, ir, set_var, data)
class sfepy.homogenization.coefs_base.CoefFMOne(name, problem, kwargs)
Fading memory scalar coefficients.
class sfepy.homogenization.coefs_base.CoefFMSym(name, problem, kwargs)
Fading memory sym coefficients.
class sfepy.homogenization.coefs_base.CoefFMSymSym(name, problem, kwargs)
Fading memory sym x sym coefficients.
class sfepy.homogenization.coefs_base.CoefN(name, problem, kwargs)
static set_variables_default(variables, ir, set_var, data)
class sfepy.homogenization.coefs_base.CoefNN(name, problem, kwargs)
static set_variables_default(variables, ir, ic, mode, set_var, data)
class sfepy.homogenization.coefs_base.CoefNone(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CoefOne(name, problem, kwargs)
static set_variables_default(variables, set_var, data)
class sfepy.homogenization.coefs_base.CoefSum(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CoefSym(name, problem, kwargs)
static set_variables_default(variables, ir, ic, mode, set_var, data)
class sfepy.homogenization.coefs_base.CoefSymSym(name, problem, kwargs)
static set_variables_default(variables, ir, ic, mode, set_var, data)
class sfepy.homogenization.coefs_base.CopyData(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CorrDim(name, problem, kwargs)
7.8. Module Index
501
SfePy Documentation, Release 2015.1
class sfepy.homogenization.coefs_base.CorrDimDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CorrEqPar(name, problem, kwargs)
The corrector which equation can be parametrized via ‘eq_pars’, the dimension is given by the number of
parameters.
Example:
‘equations’: ‘dw_diffusion.5.Y(mat.k, q, p) = dw_surface_integrate.5.%s(q)’,
‘eq_pars’: (‘bYMp’, ‘bYMm’), ‘class’: cb.CorrEqPar,
class sfepy.homogenization.coefs_base.CorrMiniApp(name, problem, kwargs)
get_dump_name()
get_dump_name_base()
get_output(corr_sol, is_dump=False, extend=True, variables=None)
get_save_name()
get_save_name_base()
save(state, problem, variables=None)
setup_output(save_format=None,
file_per_var=None)
Instance attributes have precedence!
dump_format=None,
post_process_hook=None,
class sfepy.homogenization.coefs_base.CorrN(name, problem, kwargs)
static set_variables_default(variables, ir, set_var, data)
class sfepy.homogenization.coefs_base.CorrNN(name, problem, kwargs)
__init__() kwargs: {
‘ebcs’ : [], ‘epbcs’ : [], ‘equations’ : {}, ‘set_variables’ : None,
},
static set_variables_default(variables, ir, ic, set_var, data)
class sfepy.homogenization.coefs_base.CorrOne(name, problem, kwargs)
static set_variables_default(variables, set_var, data)
class sfepy.homogenization.coefs_base.CorrSetBCS(name, problem, kwargs)
class sfepy.homogenization.coefs_base.CorrSolution(**kwargs)
Class for holding solutions of corrector problems.
iter_solutions()
class sfepy.homogenization.coefs_base.MiniAppBase(name, problem, kwargs)
static any_from_conf(name, problem, kwargs)
init_solvers(problem)
Setup solvers. Use local options if these are defined, otherwise use the global ones.
For linear problems, assemble the matrix and try to presolve the linear system.
502
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
process_options()
Setup application-specific options.
Subclasses should implement this method as needed.
Returns app_options : Struct instance
The application options.
class sfepy.homogenization.coefs_base.OnesDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.PressureEigenvalueProblem(name, problem,
kwargs)
Pressure eigenvalue problem solver for time-dependent correctors.
presolve(mtx)
Prepare A^{-1} B^T for the Schur complement.
solve_pressure_eigenproblem(mtx, eig_problem=None, n_eigs=0, check=False)
G = B*AI*BT or B*AI*BT+D
class sfepy.homogenization.coefs_base.ShapeDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.ShapeDimDim(name, problem, kwargs)
class sfepy.homogenization.coefs_base.TCorrectorsViaPressureEVP(name, problem,
kwargs)
Time correctors via the pressure eigenvalue problem.
compute_correctors(evp, sign, state0, ts, dump_name, save_name, problem=None, vec_g=None)
save(dump_name, save_name, vec_u, vec_p, vec_dp, ts, problem)
1.saves raw correctors into hdf5 files (filename)
2.saves correctors transformed to output for visualization
setup_equations(equations, problem=None)
Set equations, update boundary conditions and materials.
verify_correctors(sign, state0, filename, problem=None)
class sfepy.homogenization.coefs_base.TSTimes(name, problem, kwargs)
Coefficient-like class, returns times of the time stepper.
class sfepy.homogenization.coefs_base.VolumeFractions(name, problem, kwargs)
Coefficient-like class, returns volume fractions of given regions within the whole domain.
sfepy.homogenization.coefs_elastic module
class sfepy.homogenization.coefs_elastic.CorrectorsPermeability(name, problem,
kwargs)
class sfepy.homogenization.coefs_elastic.GBarCoef(name, problem, kwargs)
Asymptotic Barenblatt coefficient.
data = [p^{infty}]
Note:
solving “dw_diffusion.i1.Y3( m.K, qc, pc ) = 0” solve, in fact “C p^{infty} = hat{C} hat{pi}” with the result
“hat{p^{infty}}”, where the rhs comes from E(P)BC. - it is preferable to computing directly by “hat{p^{infty}}
= hat{C^-1 strip(hat{C} hat{pi})}”, as it checks explicitly the rezidual.
7.8. Module Index
503
SfePy Documentation, Release 2015.1
class sfepy.homogenization.coefs_elastic.GPlusCoef(name, problem, kwargs)
get_filename(data)
class sfepy.homogenization.coefs_elastic.PressureRHSVector(name, problem, kwargs)
class sfepy.homogenization.coefs_elastic.RBiotCoef(name, problem, kwargs)
Homogenized fading memory Biot-like coefficient.
get_filename(data, ir, ic)
get_variables(problem, io, step, data, mode)
class sfepy.homogenization.coefs_elastic.TCorrectorsPressureViaPressureEVP(name,
problem,
kwargs)
get_dump_name_base()
get_save_name_base()
class sfepy.homogenization.coefs_elastic.TCorrectorsRSViaPressureEVP(name,
problem,
kwargs)
get_dump_name_base()
get_save_name_base()
sfepy.homogenization.coefs_elastic.eval_boundary_diff_vel_grad(problem,
uc,
pc,
equation,
region_name,
pi=None)
sfepy.homogenization.coefs_perfusion module
class sfepy.homogenization.coefs_perfusion.CoefRegion(name, problem, kwargs)
get_variables(problem, ir, data)
class sfepy.homogenization.coefs_perfusion.CorrRegion(name, problem, kwargs)
get_variables(ir, data)
sfepy.homogenization.coefs_phononic module
class sfepy.homogenization.coefs_phononic.AcousticMassLiquidTensor(name, problem, kwargs)
get_coefs(freq)
Get frequency-dependent coefficients.
class sfepy.homogenization.coefs_phononic.AcousticMassTensor(name,
kwargs)
The acoustic mass tensor for a given frequency.
problem,
Returns self : AcousticMassTensor instance
504
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
This class instance whose evaluate() method computes for a given frequency the required tensor.
Notes
eigenmomenta, eigs should contain only valid resonances.
evaluate(freq)
get_coefs(freq)
Get frequency-dependent coefficients.
to_file_txt = None
class sfepy.homogenization.coefs_phononic.AppliedLoadTensor(name, problem, kwargs)
The applied load tensor for a given frequency.
Returns self : AppliedLoadTensor instance
This class instance whose evaluate() method computes for a given frequency the required tensor.
Notes
eigenmomenta, ueigenmomenta, eigs should contain only valid resonances.
evaluate(freq)
to_file_txt = None
class sfepy.homogenization.coefs_phononic.BandGaps(name, problem, kwargs)
Band gaps detection.
Parameters eigensolver : str
The name of the eigensolver for mass matrix eigenvalues.
eig_range : (int, int)
The eigenvalues range (squared frequency) to consider.
freq_margins : (float, float)
Margins in percents of initial frequency range given by eig_range by which the range is
increased.
fixed_freq_range : (float, float)
The frequency range to consider. Has precedence over eig_range and freq_margins.
freq_step : float
The frequency step for tracing, in percent of the frequency range.
freq_eps : float
The frequency difference smaller than freq_eps is considered zero.
zero_eps : float
The tolerance for finding zeros of mass matrix eigenvalues.
detect_fun : callable
The function for detecting the band gaps. Default is detect_band_gaps().
7.8. Module Index
505
SfePy Documentation, Release 2015.1
log_save_name : str
If not None, the band gaps log is to be saved under the given name.
fix_eig_range(n_eigs)
process_options()
static save_log(filename, float_format, bg)
Save band gaps, valid flags and eigenfrequencies.
static to_file_txt(fd, float_format, bg)
class sfepy.homogenization.coefs_phononic.ChristoffelAcousticTensor(name,
problem,
kwargs)
process_options()
class sfepy.homogenization.coefs_phononic.DensityVolumeInfo(name, problem, kwargs)
Determine densities of regions specified in region_to_material, and compute average density based on region
volumes.
static to_file_txt(fd, float_format, dv_info)
class sfepy.homogenization.coefs_phononic.Eigenmomenta(name, problem, kwargs)
Eigenmomenta corresponding to eigenvectors.
Parameters var_name : str
The name of the variable used in the integral.
threshold : float
The threshold under which an eigenmomentum is considered zero.
threshold_is_relative : bool
If True, the threshold is relative w.r.t. max. norm of eigenmomenta.
transform : callable, optional
Optional function for transforming the eigenvectors before computing the eigenmomenta.
Returns eigenmomenta : Struct
The resulting eigenmomenta. An eigenmomentum above threshold is marked by the
attribute ‘valid’ set to True.
process_options()
class sfepy.homogenization.coefs_phononic.PhaseVelocity(name, problem, kwargs)
Compute phase velocity.
process_options()
class sfepy.homogenization.coefs_phononic.PolarizationAngles(name,
problem,
kwargs)
Compute polarization angles, i.e., angles between incident wave direction and wave vectors. Vector length does
not matter - eigenvectors are used directly.
process_options()
class sfepy.homogenization.coefs_phononic.SchurEVP(name, problem, kwargs)
Schur complement eigenvalue problem.
506
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
post_process(eigs, mtx_s_phi, mtx_dib, problem)
prepare_matrices(problem)
A = K + B^T D^{-1} B
class sfepy.homogenization.coefs_phononic.SimpleEVP(name, problem, kwargs)
Simple eigenvalue problem.
post_process(eigs, mtx_s_phi, data, problem)
prepare_matrices(problem)
process_options()
save(eigs, mtx_phi, problem)
sfepy.homogenization.coefs_phononic.compute_cat_dim_dim(coef, iw_dir)
Christoffel acoustic tensor part of dielectric tensor dimension.
sfepy.homogenization.coefs_phononic.compute_cat_dim_sym(coef, iw_dir)
Christoffel acoustic tensor part of piezo-coupling tensor dimension.
sfepy.homogenization.coefs_phononic.compute_cat_sym_sym(coef, iw_dir)
Christoffel acoustic tensor (part) of elasticity tensor dimension.
sfepy.homogenization.coefs_phononic.compute_eigenmomenta(em_equation, var_name,
problem,
eig_vectors,
transform=None)
Compute the eigenmomenta corresponding to given eigenvectors.
sfepy.homogenization.coefs_phononic.cut_freq_range(freq_range,
eigs,
valid,
freq_margins,
eig_range,
fixed_freq_range, freq_eps)
Cut off masked resonance frequencies. Margins are preserved, like no resonances were cut.
Returns freq_range : array
The new range of frequencies.
freq_range_margins : array
The range of frequencies with prepended/appended margins equal to fixed_freq_range
if it is not None.
sfepy.homogenization.coefs_phononic.describe_gaps(gaps)
sfepy.homogenization.coefs_phononic.detect_band_gaps(mass,
freq_info,
opts,
gap_kind=’normal’,
mtx_b=None)
Detect band gaps given solution to eigenproblem (eigs, eig_vectors). Only valid resonance frequencies (e.i.
those for which corresponding eigenmomenta are above a given threshold) are taken into account.
Notes
•make freq_eps relative to ]f0, f1[ size?
sfepy.homogenization.coefs_phononic.find_zero(f0, f1, callback, freq_eps, zero_eps, mode)
For f in ]f0, f1[ find frequency f for which either the smallest (mode = 0) or the largest (mode = 1) eigenvalue of
problem P given by callback is zero.
Returns flag : 0, 1, or 2
The flag, see Notes below.
7.8. Module Index
507
SfePy Documentation, Release 2015.1
frequency : float
The found frequency.
eigenvalue : float
The eigenvalue corresponding to the found frequency.
Notes
Meaning of the return value combinations:
mode
0, 1
0
0
1
1
flag
0
1
2
1
2
meaning
eigenvalue -> 0 for f in ]f0, f1[
f -> f1, smallest eigenvalue < 0
f -> f0, smallest eigenvalue > 0 and -> -infty
f -> f1, largest eigenvalue < 0 and -> +infty
f -> f0, largest eigenvalue > 0
sfepy.homogenization.coefs_phononic.get_callback(mass,
method,
mode=’trace’)
Return callback to solve band gaps or dispersion eigenproblem P.
mtx_b=None,
Notes
Find zero callbacks return: eigenvalues
Trace callbacks return: (eigenvalues,)
or (eigenvalues, eigenvectors) (in full (dispoersion) mode)
If mtx_b is None, the problem P is M w = lambda w,
otherwise it is omega^2 M w = eta B w
sfepy.homogenization.coefs_phononic.get_log_freqs(f0, f1, df, freq_eps, n_point_min,
n_point_max)
Get logging frequencies.
The frequencies get denser towards the interval boundaries.
sfepy.homogenization.coefs_phononic.get_ranges(freq_range, eigs)
Get an eigenvalue range slice and a corresponding initial frequency range within a given frequency range.
sfepy.homogenization.coefs_phononic.split_chunks(indx)
Split index vector to chunks of consecutive numbers.
sfepy.homogenization.convolutions module
class sfepy.homogenization.convolutions.ConvolutionKernel(name,
times,
kernel,
decay=None,
exp_coefs=None,
exp_decay=None)
The convolution kernel with exponential synchronous decay approximation approximating the original kernel
represented by the array 𝑐[𝑖], 𝑖 = 0, 1, . . ..
𝑐0 ≡ 𝑐[0] , 𝑐𝑒0 ≡ 𝑐0 𝑐𝑒0 ,
𝑐(𝑡) ≈ 𝑐0 𝑑(𝑡) ≈ 𝑐0 𝑒(𝑡) = 𝑐𝑒0 𝑒𝑛 (𝑡) ,
508
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
where 𝑑(0) = 𝑒𝑛 (0) = 1, 𝑑 is the synchronous decay and 𝑒 its exponential approximation, 𝑒 = 𝑐𝑒0 𝑒𝑥𝑝(−𝑐𝑒1 𝑡).
diff_dt(use_exp=False)
The derivative of the kernel w.r.t. time.
get_exp()
Get the exponential synchronous decay kernel approximation.
get_full()
Get the original (full) kernel.
int_dt(use_exp=False)
The integral of the kernel in time.
sfepy.homogenization.convolutions.approximate_exponential(x, y)
Approximate 𝑦 = 𝑓 (𝑥) by 𝑦𝑎 = 𝑐1 𝑒𝑥𝑝(−𝑐2 𝑥).
Initial guess is given by assuming y has already the required exponential form.
sfepy.homogenization.convolutions.compute_mean_decay(coef )
Compute mean decay approximation of a non-scalar fading memory coefficient.
sfepy.homogenization.convolutions.eval_exponential(coefs, x)
sfepy.homogenization.convolutions.fit_exponential(x, y, return_coefs=False)
Evaluate 𝑦 = 𝑓 (𝑥) after approximating 𝑓 by an exponential.
sfepy.homogenization.engine module
class sfepy.homogenization.engine.HomogenizationEngine(problem,
options,
app_options=None,
volume=None,
output_prefix=’he:’, **kwargs)
call(ret_all=False)
compute_requirements(requirements, dependencies, store)
static process_options(options)
setup_options(app_options=None)
sfepy.homogenization.engine.insert_sub_reqs(reqs, levels, req_info)
Recursively build all requirements in correct order.
sfepy.homogenization.homogen_app module
class sfepy.homogenization.homogen_app.HomogenizationApp(conf, options, output_prefix,
**kwargs)
call(verbose=False, ret_all=None)
Call the homogenization engine and compute the homogenized coefficients.
Parameters verbose : bool
If True, print the computed coefficients.
ret_all : bool or None
If not None, it can be used to override the ‘return_all’ option. If True, also the dependencies are returned.
7.8. Module Index
509
SfePy Documentation, Release 2015.1
Returns coefs : Coefficients instance
The homogenized coefficients.
dependencies : dict
The dependencies, if ret_all is True.
static process_options(options)
Application options setup. Sets default values for missing non-compulsory options.
setup_options()
class sfepy.homogenization.homogen_app.Volume(name, problem, kwargs)
sfepy.homogenization.homogen_app.get_volume_from_options(options, problem)
sfepy.homogenization.micmac module
sfepy.homogenization.micmac.get_correctors_from_file(coefs_filename=’coefs.h5’,
dump_names=None)
sfepy.homogenization.micmac.get_homog_coefs_linear(ts,
coor,
mode,
micro_filename=None,
regenerate=False, coefs_filename=None)
sfepy.homogenization.recovery module
sfepy.homogenization.recovery.add_strain_rs(corrs_rs, strain, vu, dim, iel, out=None)
sfepy.homogenization.recovery.add_stress_p(out, pb, integral, region, vp, data)
sfepy.homogenization.recovery.combine_scalar_grad(corrs,
grad,
shift_coors=None)
vn,
ii,
𝜂𝑘 𝜕𝑘𝑥 𝑝
or
(𝑦𝑘 + 𝜂𝑘 )𝜕𝑘𝑥 𝑝
sfepy.homogenization.recovery.compute_mac_stress_part(pb, integral, region, material,
vu, mac_strain)
sfepy.homogenization.recovery.compute_micro_u(corrs, strain, vu, dim, out=None)
Micro displacements.
𝑢1 = 𝜒𝑖𝑗 𝑒𝑥𝑖𝑗 (𝑢0 )
sfepy.homogenization.recovery.compute_p_corr_steady(corrs_pressure, pressure, vp, iel)
𝜋
̃︀𝑃 𝑝
sfepy.homogenization.recovery.compute_p_corr_time(corrs_rs, dstrains, corrs_pressure,
pressures, vdp, dim, iel, ts)
∫︁
∫︁
𝑡
∑︁ 𝑡 d
d
d 𝑃
𝜋
̃︀𝑖𝑗 (𝑡 − 𝑠) 𝑒𝑖𝑗 (𝑢(𝑠)) 𝑑𝑠 +
𝜋
̃︀ (𝑡 − 𝑠) 𝑝(𝑠) 𝑑𝑠
d𝑡
d𝑠
d𝑡
0
0
𝑖𝑗
510
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.homogenization.recovery.compute_p_from_macro(p_grad, coor, iel, centre=None,
extdim=0)
Macro-induced pressure.
𝜕𝑗𝑥 𝑝 (𝑦𝑗 − 𝑦𝑗𝑐 )
sfepy.homogenization.recovery.compute_stress_strain_u(pb, integral, region, material,
vu, data)
sfepy.homogenization.recovery.compute_u_corr_steady(corrs_rs, strain, vu, dim, iel)
∑︁
𝜔 𝑖𝑗 𝑒𝑖𝑗 (𝑢)
𝑖𝑗
Notes
•iel = element number
sfepy.homogenization.recovery.compute_u_corr_time(corrs_rs, dstrains, corrs_pressure,
pressures, vu, dim, iel, ts)
]︂
[︂∫︁
∫︁
𝑡
𝑡
∑︁
d
̃︀ 𝑃 (𝑡 − 𝑠) 𝑝(𝑠) 𝑑𝑠
𝜔
𝜔 𝑖𝑗 (𝑡 − 𝑠) 𝑒𝑖𝑗 (𝑢(𝑠)) 𝑑𝑠 +
d𝑠
0
0
𝑖𝑗
sfepy.homogenization.recovery.compute_u_from_macro(strain, coor, iel, centre=None)
Macro-induced displacements.
𝑒𝑥𝑖𝑗 (𝑢) (𝑦𝑗 − 𝑦𝑗𝑐 )
sfepy.homogenization.recovery.convolve_field_scalar(fvars, pvars, iel, ts)
∫︁ 𝑡
𝑓 (𝑡 − 𝑠)𝑝(𝑠)𝑑𝑠
0
Notes
•t is given by step
•f: fvars scalar field variables, defined in a micro domain, have shape [step][fmf dims]
•p: pvars scalar point variables, a scalar in a point of macro-domain, FMField style have shape [n_step][var
dims]
sfepy.homogenization.recovery.convolve_field_sym_tensor(fvars, pvars, var_name,
dim, iel, ts)
∫︁ 𝑡
𝑓 𝑖𝑗 (𝑡 − 𝑠)𝑝𝑖𝑗 (𝑠)𝑑𝑠
0
7.8. Module Index
511
SfePy Documentation, Release 2015.1
Notes
•t is given by step
•f: fvars field variables, defined in a micro domain, have shape [step][fmf dims]
•p: pvars sym. tensor point variables, a scalar in a point of macro-domain, FMField style, have shape [dim,
dim][var_name][n_step][var dims]
sfepy.homogenization.recovery.get_output_suffix(ig, iel, ts, naming_scheme, format, output_format)
sfepy.homogenization.recovery.recover_bones(problem, micro_problem, region, eps0,
ts, strain, dstrains, p_grad, pressures,
corrs_permeability, corrs_rs, corrs_time_rs,
corrs_pressure,
corrs_time_pressure,
var_names, naming_scheme=’step_iel’)
Notes
•note that
𝜋
̃︀𝑃
is in corrs_pressure -> from time correctors only ‘u’, ‘dp’ are needed.
sfepy.homogenization.recovery.recover_micro_hook(micro_filename,
region,
naming_scheme=’step_iel’,
ery_file_tag=’‘)
macro,
recov-
sfepy.homogenization.recovery.recover_paraflow(problem, micro_problem, region, ts,
strain, dstrains, pressures1, pressures2,
corrs_rs, corrs_time_rs, corrs_alpha1,
corrs_time_alpha1,
corrs_alpha2,
corrs_time_alpha2, var_names, naming_scheme=’step_iel’)
sfepy.homogenization.recovery.save_recovery_region(mac_pb, rname, filename=None)
sfepy.homogenization.utils module
sfepy.homogenization.utils.build_op_pi(var, ir, ic)
Pi_i^{rs} = y_s delta_{ir} for r = ir, s = ic.
sfepy.homogenization.utils.coor_to_sym(ir, ic, dim)
sfepy.homogenization.utils.create_pis(problem, var_name)
Pi_i^{rs} = y_s delta_{ir}, ul{y} in Y coordinates.
sfepy.homogenization.utils.create_scalar_pis(problem, var_name)
Pi^k = y_k, ul{y} in Y coordinates.
sfepy.homogenization.utils.define_box_regions(dim,
lbn,
kind=’facet’)
Define sides and corner regions for a box aligned with coordinate axes.
rtf=None,
eps=0.001,
Parameters dim : int
Space dimension
512
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
lbn : tuple
Left bottom near point coordinates if rtf is not None. If rtf is None, lbn are the (positive)
distances from the origin.
rtf : tuple
Right top far point coordinates.
eps : float
A parameter, that should be smaller than the smallest mesh node distance.
kind : bool, optional
The region kind.
Returns regions : dict
The box regions.
sfepy.homogenization.utils.get_box_volume(dim, lbn, rtf=None)
Volume of a box aligned with coordinate axes.
Parameters:
dim [int] Space dimension
lbn [tuple] Left bottom near point coordinates if rtf is not None. If rtf is None, lbn are the (positive) distances
from the origin.
rtf [tuple] Right top far point coordinates.
Returns:
volume [float] The box volume.
sfepy.homogenization.utils.get_lattice_volume(axes)
Volume of a periodic cell in a rectangular 3D (or 2D) lattice.
Parameters axes : array
The array with the periodic cell axes 𝑎1 , . . . , 𝑎3 as rows.
Returns volume : float
The periodic cell volume 𝑉 = (𝑎1 × 𝑎2 ) · 𝑎3 . In 2D 𝑉 = |(𝑎1 × 𝑎2 )| with zeros as the
third components of vectors 𝑎1 , 𝑎2 .
sfepy.homogenization.utils.get_volume(problem, field_name, region_name, quad_order=1)
Get volume of a given region using integration defined by a given field. Both the region and the field have to be
defined in problem.
sfepy.homogenization.utils.integrate_in_time(coef, ts, scheme=’forward’)
Forward difference or trapezoidal rule. ‘ts’ can be anything with ‘times’ attribute.
sfepy.homogenization.utils.interp_conv_mat(mat, ts, tdiff )
sfepy.homogenization.utils.iter_sym(dim)
sfepy.homogenization.utils.set_nonlin_states(variables, nl_state, problem)
Setup reference state for nonlinear homogenization
Parameters variables : dict
All problem variables
7.8. Module Index
513
SfePy Documentation, Release 2015.1
nl_state : reference state
problem : problem description
7.8.8 sfepy.linalg package
sfepy.linalg.check_derivatives module
Utilities for checking derivatives of functions.
sfepy.linalg.check_derivatives.check_fx(x0, fx, fx_args, dfx, dfx_args=None, delta=1e-05)
Check derivatives of a (vectorized) scalar function of a scalar variable.
sfepy.linalg.check_derivatives.check_vfvx(x0, fx, fx_args, dfx, dfx_args=None, delta=1e05)
Check derivatives of a (vectorized) vector or scalar function of a vector variable.
sfepy.linalg.eigen module
sfepy.linalg.eigen.arpack_eigs(mtx, nev=1, which=’SM’)
Calculate several eigenvalues and corresponding eigenvectors of a matrix using ARPACK from SciPy. The
eigenvalues are sorted in ascending order.
sfepy.linalg.eigen.cg_eigs(mtx, rhs=None, precond=None, i_max=None, eps_r=1e-10,
shift=None, select_indices=None, verbose=False, report_step=10)
Make several iterations of the conjugate gradients and estimate so the eigenvalues of a (sparse SPD) matrix
(Lanczos algorithm).
Parameters mtx : spmatrix or array
The sparse matrix 𝐴.
precond : spmatrix or array, optional
The preconditioner matrix. Any object that can be multiplied by vector can be passed.
i_max : int
The maximum number of the Lanczos algorithm iterations.
eps_r : float
The relative stopping tolerance.
shift : float, optional
Eigenvalue shift for non-SPD matrices.
|𝑠ℎ𝑖𝑓 𝑡|||𝐴||∞ .
If negative, the shift is computed as
select_indices : (min, max), optional
If given, computed only the eigenvalues with indices min <= i <= max.
verbose : bool
Verbosity control.
report_step : int
If verbose is True, report in every report_step-th step.
Returns vec : array
The approximate solution to the linear system.
514
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
n_it : int
The number of CG iterations used.
norm_rs : array
Convergence history of residual norms.
eigs : array
The approximate eigenvalues sorted in ascending order.
sfepy.linalg.eigen.sym_tri_eigen(diags, select_indices=None)
Compute eigenvalues of a symmetric tridiagonal matrix using scipy.linalg.eigvals_banded().
sfepy.linalg.geometry module
sfepy.linalg.geometry.barycentric_coors(coors, s_coors)
Get barycentric (area in 2D, volume in 3D) coordinates of points with coordinates coors w.r.t. the simplex given
by s_coors.
Returns bc : array
The barycentric coordinates.
ref_coors).
Then reference element coordinates xi = dot(bc.T,
sfepy.linalg.geometry.flag_points_in_polygon2d(polygon, coors)
Test if points are in a 2D polygon.
Parameters polygon : array, (:, 2)
The polygon coordinates.
coors: array, (:, 2) :
The coordinates of points.
Returns flag : bool array
The flag that is True for points that are in the polygon.
Notes
This is a semi-vectorized version of [1].
[1] PNPOLY - Point Inclusion in Polygon Test, W. Randolph Franklin (WRF)
sfepy.linalg.geometry.get_coors_in_ball(coors, centre, radius, inside=True)
Return indices of coordinates inside or outside a ball given by centre and radius.
Notes
All float comparisons are done using <= or >= operators, i.e. the points on the boundaries are taken into
account.
sfepy.linalg.geometry.get_coors_in_tube(coors, centre, axis, radius_in, radius_out, length,
inside_radii=True)
Return indices of coordinates inside a tube given by centre, axis vector, inner and outer radii and length.
Parameters inside_radii : bool, optional
If False, select points outside the radii, but within the tube length.
7.8. Module Index
515
SfePy Documentation, Release 2015.1
Notes
All float comparisons are done using <= or >= operators, i.e. the points on the boundaries are taken into
account.
sfepy.linalg.geometry.get_face_areas(faces, coors)
Get areas of planar convex faces in 2D and 3D.
Parameters faces : array, shape (n, m)
The indices of n faces with m vertices into coors.
coors : array
The coordinates of face vertices.
Returns areas : array
The areas of the faces.
sfepy.linalg.geometry.get_perpendiculars(vec)
For a given vector, get a unit vector perpendicular to it in 2D, or get two mutually perpendicular unit vectors
perpendicular to it in 3D.
sfepy.linalg.geometry.get_simplex_circumcentres(coors, force_inside_eps=None)
Compute the circumcentres of n_s simplices in 1D, 2D and 3D.
Parameters coors : array
The coordinates of the simplices with n_v vertices given in an array of shape (n_s, n_v,
dim), where dim is the space dimension and 2 <= n_v <= (dim + 1).
force_inside_eps : float, optional
If not None, move the circumcentres that are outside of their simplices or closer to their
boundary then force_inside_eps so that they are inside the simplices at the distance
given by force_inside_eps. It is ignored for edges.
Returns centres : array
The circumcentre coordinates as an array of shape (n_s, dim).
sfepy.linalg.geometry.get_simplex_volumes(cells, coors)
Get volumes of simplices in nD.
Parameters cells : array, shape (n, d)
The indices of n simplices with d vertices into coors.
coors : array
The coordinates of simplex vertices.
Returns volumes : array
The volumes of the simplices.
sfepy.linalg.geometry.inverse_element_mapping(coors, e_coors, eval_base, ref_coors, suppress_errors=False)
Given spatial element coordinates, find the inverse mapping for points with coordinats X = X(xi), i.e. xi = xi(X).
Returns xi : array
The reference element coordinates.
516
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.linalg.geometry.make_axis_rotation_matrix(direction, angle)
Create a rotation matrix 𝑅 corresponding to the rotation around a general axis 𝑑 by a specified angle 𝛼.
𝑅 = 𝑑𝑑𝑇 + cos(𝛼)(𝐼 − 𝑑𝑑𝑇 ) + sin(𝛼) skew(𝑑)
Parameters direction : array
The rotation axis direction vector 𝑑.
angle : float
The rotation angle 𝛼.
Returns mtx : array
The rotation matrix 𝑅.
Notes
The matrix follows the right hand rule: if the right hand thumb points along the axis vector 𝑑 the fingers show
the positive angle rotation direction.
Examples
Make transformation matrix for rotation of coordinate system by 90 degrees around ‘z’ axis.
>>> mtx = make_axis_rotation_matrix([0., 0., 1.], nm.pi/2)
>>> mtx
array([[ 0., 1., 0.],
[-1., 0., 0.],
[ 0., 0., 1.]])
Coordinates of vector [1, 0, 0]𝑇 w.r.t. the original system in the rotated system. (Or rotation of the vector by -90
degrees in the original system.)
>>> nm.dot(mtx, [1., 0., 0.])
>>> array([ 0., -1., 0.])
Coordinates of vector [1, 0, 0]𝑇 w.r.t. the rotated system in the original system. (Or rotation of the vector by +90
degrees in the original system.)
>>> nm.dot(mtx.T, [1., 0., 0.])
>>> array([ 0., 1., 0.])
sfepy.linalg.geometry.points_in_simplex(coors, s_coors, eps=1e-08)
Test if points with coordinates coors are in the simplex given by s_coors.
sfepy.linalg.geometry.rotation_matrix2d(angle)
Construct a 2D (plane) rotation matrix corresponding to angle.
sfepy.linalg.geometry.transform_bar_to_space_coors(bar_coors, coors)
Transform barycentric coordinates bar_coors within simplices with vertex coordinates coors to space coordinates.
sfepy.linalg.sparse module
Some sparse matrix utilities missing in scipy.
7.8. Module Index
517
SfePy Documentation, Release 2015.1
sfepy.linalg.sparse.compose_sparse(blocks, row_sizes=None, col_sizes=None)
Compose sparse matrices into a global sparse matrix.
Parameters blocks : sequence of sequences
The sequence of sequences of equal lengths - the individual sparse matrix blocks. The
integer 0 can be used to mark an all-zero block, if its size can be determined from the
other blocks.
row_sizes : sequence, optional
The required row sizes of the blocks. It can be either a sequence of non-negative integers, or a sequence of slices with non-negative limits. In any case the sizes have to be
compatible with the true block sizes. This allows to extend the matrix shape as needed
and to specify sizes of all-zero blocks.
col_sizes : sequence, optional
The required column sizes of the blocks. See row_sizes.
Returns mtx : coo_matrix
The sparse matrix (COO format) composed from the given blocks.
Examples
Stokes-like problem matrix.
>>>
>>>
>>>
>>>
>>>
[[1
[0
[1
import scipy.sparse as sp
A = sp.csr_matrix([[1, 0], [0, 1]])
B = sp.coo_matrix([[1, 1]])
K = compose_sparse([[A, B.T], [B, 0]])
print K.todense()
0 1]
1 1]
1 0]]
sfepy.linalg.sparse.infinity_norm(mtx)
Infinity norm of a sparse matrix (maximum absolute row sum).
Parameters mtx : spmatrix or array
The sparse matrix.
Returns norm : float
Infinity norm of the matrix.
See also:
scipy.linalg.norm dense matrix norms
Notes
•This serves as an upper bound on spectral radius.
•CSR and CSC avoid copying indices and indptr arrays.
•inspired by PyAMG
518
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.linalg.sparse.insert_sparse_to_csr(mtx1, mtx2, irs, ics)
Insert a sparse matrix mtx2 into a CSR sparse matrix mtx1 at rows irs and columns ics. The submatrix
mtx1[irs,ics] must already be preallocated and have the same structure as mtx2.
sfepy.linalg.sparse.save_sparse_txt(filename, mtx, fmt=’%d %d %f\n’)
Save a CSR/CSC sparse matrix into a text file
sfepy.linalg.utils module
class sfepy.linalg.utils.MatrixAction(**kwargs)
static from_array(arr)
static from_function(fun, expected_shape, dtype)
to_array()
sfepy.linalg.utils.apply_to_sequence(seq, fun, ndim, out_item_shape)
Applies function fun() to each item of the sequence seq. An item corresponds to the last ndim dimensions of
seq.
Parameters seq : array
The sequence array with shape (n_1, ..., n_r, m_1, ..., m_{ndim}).
fun : function
The function taking an array argument of shape of length ndim.
ndim : int
The number of dimensions of an item in seq.
out_item_shape : tuple
The shape an output item.
Returns out : array
The resulting array of shape (n_1, ..., n_r) + out_item_shape. The out_item_shape must
be compatible with the fun.
sfepy.linalg.utils.argsort_rows(seq)
Returns an index array that sorts the sequence seq. Works along rows if seq is two-dimensional.
sfepy.linalg.utils.assemble1d(ar_out, indx, ar_in)
Perform ar_out[indx] += ar_in, where items of ar_in corresponding to duplicate indices in indx are summed
together.
sfepy.linalg.utils.combine(seqs)
Same as cycle, but with general sequences.
Example:
In [19]: c = combine( [[’a’, ‘x’], [’b’, ‘c’], [’dd’]] )
In [20]: list(c) Out[20]: [[’a’, ‘b’, ‘dd’], [’a’, ‘c’, ‘dd’], [’x’, ‘b’, ‘dd’], [’x’, ‘c’, ‘dd’]]
sfepy.linalg.utils.cycle(bounds)
Cycles through all combinations of bounds, returns a generator.
More specifically, let bounds=[a, b, c, ...], so cycle returns all combinations of lists [0<=i<a, 0<=j<b, 0<=k<c,
...] for all i,j,k,...
7.8. Module Index
519
SfePy Documentation, Release 2015.1
Examples: In [9]: list(cycle([3, 2])) Out[9]: [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]
In [14]: list(cycle([3, 4])) [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]
sfepy.linalg.utils.dets_fast(a)
Fast determinant calculation of 3-dimensional array.
Parameters a : array
The input array with shape (m, n, n).
Returns out : array
The output array with shape (m,): out[i] = det(a[i, :, :]).
sfepy.linalg.utils.dot_sequences(mtx, vec, mode=’AB’)
Computes dot product for each pair of items in the two sequences.
Equivalent to
>>> out = nm.empty((vec.shape[0], mtx.shape[1], vec.shape[2]),
>>>
dtype=vec.dtype)
>>> for ir in range(mtx.shape[0]):
>>>
out[ir] = nm.dot(mtx[ir], vec[ir])
Parameters mtx : array
The array of matrices with shape (n_item, m, n).
vec : array
The array of vectors with shape (n_item, a) or matrices with shape (n_item, a, b).
mode : one of ‘AB’, ‘ATB’, ‘ABT’, ‘ATBT’
The mode of the dot product - the corresponding axes are dotted together:
‘AB’ : a = n ‘ATB’ : a = m ‘ABT’ : b = n (*) ‘ATBT’ : b = m (*)
(*) The ‘BT’ part is ignored for the vector second argument.
Returns out : array
The resulting array.
Notes
Uses numpy.core.umath_tests.matrix_multiply() if available, which is much faster than the default implementation.
The default implementation uses numpy.sum() and element-wise multiplication. For r-D arrays (n_1, ..., n_r,
?, ?) the arrays are first reshaped to (n_1 * ... * n_r, ?, ?), then the dot is performed, and finally the shape is
restored to (n_1, ..., n_r, ?, ?).
sfepy.linalg.utils.insert_strided_axis(ar, axis, length)
Insert a new axis of given length into an array using numpy stride tricks, i.e. no copy is made.
Parameters ar : array
The input array.
axis : int
The axis before which the new axis will be inserted.
520
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
length : int
The length of the inserted axis.
Returns out : array
The output array sharing data with ar.
Examples
>>> import numpy as nm
>>> from sfepy.linalg import insert_strided_axis
>>> ar = nm.random.rand(2, 1, 2)
>>> ar
array([[[ 0.18905119, 0.44552425]],
[[ 0.78593989, 0.71852473]]])
>>> ar.shape
(2, 1, 2)
>>> ar2 = insert_strided_axis(ar, 1, 3)
>>> ar2
array([[[[ 0.18905119, 0.44552425]],
[[ 0.18905119, 0.44552425]],
[[ 0.18905119, 0.44552425]]],
[[[ 0.78593989, 0.71852473]],
[[ 0.78593989, 0.71852473]],
[[ 0.78593989, 0.71852473]]]])
>>> ar2.shape
(2, 3, 1, 2)
sfepy.linalg.utils.map_permutations(seq1, seq2, check_same_items=False)
Returns an index array imap such that seq1[imap] == seq2, if both sequences have the same items - this is not
checked by default!
In other words, finds the indices of items of seq2 in seq1.
sfepy.linalg.utils.mini_newton(fun, x0, dfun, i_max=100, eps=1e-08)
sfepy.linalg.utils.norm_l2_along_axis(ar, axis=1, n_item=None, squared=False)
Compute l2 norm of rows (axis=1) or columns (axis=0) of a 2D array.
n_item ... use only the first n_item columns/rows squared ... if True, return the norm squared
sfepy.linalg.utils.normalize_vectors(vecs, eps=1e-08)
Normalize an array of vectors in place.
Parameters vecs : array
The 2D array of vectors in rows.
eps : float
The tolerance for considering a vector to have zero norm. Such vectors are left unchanged.
7.8. Module Index
521
SfePy Documentation, Release 2015.1
sfepy.linalg.utils.permutations(seq)
sfepy.linalg.utils.print_array_info(ar)
Print array shape and other basic information.
sfepy.linalg.utils.split_range(n_item, step)
sfepy.linalg.utils.unique_rows(ar, return_index=False, return_inverse=False)
Return unique rows of a two-dimensional array ar. The arguments follow numpy.unique().
sfepy.linalg.extmods.crcm module
sfepy.linalg.extmods.crcm.permute_in_place()
Permute a graph (= CSR sparse matrix with boolean values) in place, given a permuation vector.
sfepy.linalg.extmods.crcm.rcm()
Generate the reversed Cuthil-McKee permutation for a CSR matrix.
7.8.9 sfepy.mechanics package
sfepy.mechanics.contact_bodies module
class sfepy.mechanics.contact_bodies.ContactPlane(anchor, normal, bounds)
get_distance(points)
mask_points(points)
class sfepy.mechanics.contact_bodies.ContactSphere(centre, radius)
get_distance(points)
Get the penetration distance and normals of points w.r.t. the sphere surface.
Returns d : array
The penetration distance.
normals : array
The normals from the points to the sphere centre.
mask_points(points, eps)
sfepy.mechanics.contact_bodies.plot_points(ax, points, marker, **kwargs)
sfepy.mechanics.contact_bodies.plot_polygon(ax, polygon)
sfepy.mechanics.elastic_constants module
sfepy.mechanics.matcoefs module
Conversion of material parameters and other utilities.
class sfepy.mechanics.matcoefs.ElasticConstants(young=None, poisson=None, bulk=None,
lam=None, mu=None, p_wave=None,
_regenerate_relations=False)
Conversion formulas for various groups of elastic constants. The elastic constants supported are:
522
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
•𝐸 : Young’s modulus
•𝜈 : Poisson’s ratio
•𝐾 : bulk modulus
•𝜆 : Lamé’s first parameter
•𝜇, 𝐺 : shear modulus, Lamé’s second parameter
•𝑀 : P-wave modulus, longitudinal wave modulus
The elastic constants are referred to by the following keyword arguments: young, poisson, bulk, lam, mu,
p_wave.
Exactly two of them must be provided to the __init__() method.
Examples
•basic usage:
>>> from sfepy.mechanics.matcoefs import ElasticConstants
>>> ec = ElasticConstants(lam=1.0, mu=1.5)
>>> ec.young
3.6000000000000001
>>> ec.poisson
0.20000000000000001
>>> ec.bulk
2.0
>>> ec.p_wave
4.0
>>> ec.get([’bulk’, ’lam’, ’mu’, ’young’, ’poisson’, ’p_wave’])
[2.0, 1.0, 1.5, 3.6000000000000001, 0.20000000000000001, 4.0]
•reinitialize existing instance:
>>> ec.init(p_wave=4.0, bulk=2.0)
>>> ec.get([’bulk’, ’lam’, ’mu’, ’young’, ’poisson’, ’p_wave’])
[2.0, 1.0, 1.5, 3.6000000000000001, 0.20000000000000001, 4.0]
get(names)
Get the named elastic constants.
init(young=None, poisson=None, bulk=None, lam=None, mu=None, p_wave=None)
Set exactly two of the elastic constants, and compute the remaining. (Re)-initializes the existing instance
of ElasticConstants.
class sfepy.mechanics.matcoefs.TransformToPlane(iplane=None)
Transformations of constitutive law coefficients of 3D problems to 2D.
tensor_plane_stress(c3=None, d3=None, b3=None)
Transforms all coefficients of the piezoelectric constitutive law from 3D to plane stress problem in 2D:
strain/stress ordering: 11 22 33 12 13 23. If d3 is None, uses only the stiffness tensor c3.
Parameters c3 : array
The stiffness tensor.
d3 : array
The dielectric tensor.
7.8. Module Index
523
SfePy Documentation, Release 2015.1
b3 : array
The piezoelectric coupling tensor.
sfepy.mechanics.matcoefs.bulk_from_lame(lam, mu)
Compute bulk modulus from Lamé parameters.
2
𝛾 =𝜆+ 𝜇
3
sfepy.mechanics.matcoefs.bulk_from_youngpoisson(young, poisson, plane=’strain’)
Compute bulk modulus corresponding to Young’s modulus and Poisson’s ratio.
sfepy.mechanics.matcoefs.lame_from_youngpoisson(young, poisson, plane=’strain’)
Compute Lamé parameters from Young’s modulus and Poisson’s ratio.
The relationship between Lamé parameters and Young’s modulus, Poisson’s ratio (see [1],[2]):
𝜆=
𝜈𝐸
,
(1 + 𝜈)(1 − 2𝜈)
𝜇=
𝐸
2(1 + 𝜈)
The plain stress hypothesis:
¯=
𝜆
2𝜆𝜇
𝜆 + 2𝜇
[1] I.S. Sokolnikoff: Mathematical Theory of Elasticity. New York, 1956.
[2] T.J.R. Hughes: The Finite Element Method, Linear Static and Dynamic Finite Element Analysis. New
Jersey, 1987.
sfepy.mechanics.matcoefs.stiffness_from_lame(dim, lam, mu)
Compute stiffness tensor corresponding to Lamé parameters.
⎡
⎤
𝜆 + 2𝜇
𝜆
0
𝜆 + 2𝜇 0 ⎦
𝐷(2𝐷) = ⎣ 𝜆
0
0
𝜇
𝐷(3𝐷)
⎤
⎡
𝜆 + 2𝜇
𝜆
𝜆
0 0 0
⎢ 𝜆
𝜆 + 2𝜇
𝜆
0 0 0⎥
⎥
⎢
⎢ 𝜆
𝜆
𝜆 + 2𝜇 0 0 0 ⎥
⎥
⎢
=⎢
0
0
𝜇 0 0⎥
⎥
⎢ 0
⎣ 0
0
0
0 𝜇 0⎦
0
0
0
0 0 𝜇
sfepy.mechanics.matcoefs.stiffness_from_lame_mixed(dim, lam, mu)
Compute stiffness tensor corresponding to Lamé parameters for mixed formulation.
⎡
⎤
̃︀ + 2𝜇
̃︀
𝜆
𝜆
0
̃︀
̃︀ + 2𝜇 0 ⎦
𝐷(2𝐷) = ⎣ 𝜆
𝜆
0
0
𝜇
𝐷(3𝐷)
524
⎡̃︀
⎤
̃︀
̃︀
𝜆 + 2𝜇
𝜆
𝜆
0 0 0
⎢ 𝜆
̃︀
̃︀ + 2𝜇
̃︀
𝜆
𝜆
0 0 0⎥
⎢
⎥
⎢ 𝜆
⎥
̃︀
̃︀
̃︀
𝜆
𝜆
+
2𝜇
0
0
0
⎢
⎥
=⎢
0
0
𝜇 0 0⎥
⎢ 0
⎥
⎣ 0
0
0
0 𝜇 0⎦
0
0
0
0 0 𝜇
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
where
̃︀ = − 2 𝜇
𝜆
3
sfepy.mechanics.matcoefs.stiffness_from_youngpoisson(dim,
young,
plane=’strain’)
Compute stiffness tensor corresponding to Young’s modulus and Poisson’s ratio.
poisson,
sfepy.mechanics.matcoefs.stiffness_from_youngpoisson_mixed(dim, young, poisson,
plane=’strain’)
Compute stiffness tensor corresponding to Young’s modulus and Poisson’s ratio for mixed formulation.
sfepy.mechanics.membranes module
sfepy.mechanics.membranes.create_mapping(coors, gel, order)
Create mapping from transformed (in x-y plane) element faces to reference element faces.
Parameters coors : array
The transformed coordinates of element nodes, shape (n_el, n_ep, dim). The function
verifies that the all z components are zero.
gel : GeometryElement instance
The geometry element corresponding to the faces.
order : int
The polynomial order of the mapping.
Returns mapping : VolumeMapping instance
The reference element face mapping.
sfepy.mechanics.membranes.create_transformation_matrix(coors)
Create a transposed coordinate transformation matrix, that transforms 3D coordinates of element face nodes so
that the transformed nodes are in the x-y plane. The rotation is performed w.r.t. the first node of each face.
Parameters coors : array
The coordinates of element nodes, shape (n_el, n_ep, dim).
Returns mtx_t : array
The transposed transformation matrix 𝑇 , i.e. 𝑋𝑖𝑛𝑝𝑙𝑎𝑛𝑒 = 𝑇 𝑇 𝑋3𝐷 .
Notes
𝑇 = [𝑡1 , 𝑡2 , 𝑛], where 𝑡1 , 𝑡2 , are unit in-plane (column) vectors and 𝑛 is the unit normal vector, all mutually
orthonormal.
sfepy.mechanics.membranes.describe_deformation(el_disps, bfg)
Describe deformation of a thin incompressible 2D membrane in 3D space, composed of flat finite element faces.
The coordinate system of each element (face), i.e. the membrane mid-surface, should coincide with the x, y axes
of the x-y plane.
Parameters el_disps : array
The displacements of element nodes, shape (n_el, n_ep, dim).
bfg : array
7.8. Module Index
525
SfePy Documentation, Release 2015.1
The in-plane base function gradients, shape (n_el, n_qp, dim-1, n_ep).
Returns mtx_c ; array :
The in-plane right Cauchy-Green deformation tensor 𝐶𝑖𝑗 , 𝑖, 𝑗 = 1, 2.
c33 : array
The component 𝐶33 computed from the incompressibility condition.
mtx_b : array
The discrete Green strain variation operator.
sfepy.mechanics.membranes.describe_geometry(ig, field, region, integral)
Describe membrane geometry in a given region.
Parameters ig : int
The element group index.
field : Field instance
The field defining the FE approximation.
region : Region instance
The surface region to describe.
integral : Integral instance
The integral defining the quadrature points.
Returns mtx_t : array
The transposed transformation matrix 𝑇 , see create_transformation_matrix().
membrane_geo : CMapping instance
The mapping from transformed elements to a reference elements.
sfepy.mechanics.membranes.get_green_strain_sym3d(mtx_c, c33)
Get the 3D Green strain tensor in symmetric storage.
Parameters mtx_c ; array :
The in-plane right Cauchy-Green deformation tensor 𝐶𝑖𝑗 , 𝑖, 𝑗 = 1, 2, shape (n_el, n_qp,
dim-1, dim-1).
c33 : array
The component 𝐶33 computed from the incompressibility condition, shape (n_el, n_qp).
Returns mtx_e : array
The membrane Green strain 𝐸𝑖𝑗 = 21 (𝐶𝑖𝑗 ) − 𝛿𝑖𝑗 , symmetric storage: items (11, 22, 33,
12, 13, 23), shape (n_el, n_qp, sym, 1).
sfepy.mechanics.membranes.get_invariants(mtx_c, c33)
Get the first and second invariants of the right Cauchy-Green deformation tensor describing deformation of an
incompressible membrane.
Parameters mtx_c ; array :
The in-plane right Cauchy-Green deformation tensor 𝐶𝑖𝑗 , 𝑖, 𝑗 = 1, 2, shape (n_el, n_qp,
dim-1, dim-1).
c33 : array
526
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The component 𝐶33 computed from the incompressibility condition, shape (n_el, n_qp).
Returns i1 : array
The first invariant of 𝐶𝑖𝑗 .
i2 : array
The second invariant of 𝐶𝑖𝑗 .
sfepy.mechanics.membranes.get_tangent_stress_matrix(stress, bfg)
Get the tangent stress matrix of a thin incompressible 2D membrane in 3D space, given a stress.
Parameters stress : array
The components 11, 22, 12 of the second Piola-Kirchhoff stress tensor, shape (n_el,
n_qp, 3, 1).
bfg : array
The in-plane base function gradients, shape (n_el, n_qp, dim-1, n_ep).
Returns mtx : array
The tangent stress matrix, shape (n_el, n_qp, dim*n_ep, dim*n_ep).
sfepy.mechanics.membranes.transform_asm_matrices(out, mtx_t)
Transform matrix assembling contributions to global coordinate system, one node at a time.
Parameters out : array
The array of matrices, transformed in-place.
mtx_t : array
The transposed transformation matrix 𝑇 , see create_transformation_matrix().
sfepy.mechanics.membranes.transform_asm_vectors(out, mtx_t)
Transform vector assembling contributions to global coordinate system, one node at a time.
Parameters out : array
The array of vectors, transformed in-place.
mtx_t : array
The transposed transformation matrix 𝑇 , see create_transformation_matrix().
sfepy.mechanics.tensors module
Functions to compute some tensor-related quantities usual in continuum mechanics.
class sfepy.mechanics.tensors.StressTransform(def_grad, jacobian=None)
Encapsulates functions to convert various stress tensors in the symmetric storage given the deformation state.
get_cauchy_from_2pk(stress_in)
Get the Cauchy stress given the second Piola-Kirchhoff stress.
𝜎𝑖𝑗 = 𝐽 −1 𝐹𝑖𝑘 𝑆𝑘𝑙 𝐹𝑗𝑙
sfepy.mechanics.tensors.dim2sym(dim)
Given the space dimension, return the symmetric storage size.
sfepy.mechanics.tensors.get_deviator(tensor, sym_storage=True)
The deviatoric part (deviator) of a tensor.
7.8. Module Index
527
SfePy Documentation, Release 2015.1
sfepy.mechanics.tensors.get_full_indices(dim)
The indices for converting the symmetric storage to the full storage.
sfepy.mechanics.tensors.get_non_diagonal_indices(dim)
The non_diagonal indices for the full vector storage.
sfepy.mechanics.tensors.get_sym_indices(dim)
The indices for converting the full storage to the symmetric storage.
sfepy.mechanics.tensors.get_t4_from_t2s(t2s)
Get the full 4D tensor with major/minor symmetries from its 2D matrix representation.
Parameters t2s : array
The symmetrically-stored tensor of shape (S, S), where S it the symmetric storage size.
Returns t4 : array
The full 4D tensor of shape (D, D, D, D), where D is the space dimension.
sfepy.mechanics.tensors.get_trace(tensor, sym_storage=True)
The trace of a tensor.
sfepy.mechanics.tensors.get_volumetric_tensor(tensor, sym_storage=True)
The volumetric part of a tensor.
sfepy.mechanics.tensors.get_von_mises_stress(stress, sym_storage=True)
Given a symmetric stress tensor, compute the von Mises stress (also known as Equivalent tensile stress).
Notes
√︂
𝜎𝑉 =
2 + 𝜎2 + 𝜎2 )
(𝜎11 − 𝜎22 )2 + (𝜎22 − 𝜎33 )2 + (𝜎11 − 𝜎33 )2 + 6(𝜎12
13
23
2
sfepy.mechanics.tensors.prepare_cylindrical_transform(coors, origin, mode=’axes’)
Prepare matrices for transforming tensors into cylindrical coordinates with the axis ‘z’ in a given origin.
Parameters coors : array
The Cartesian coordinates.
origin : array of length 3
The origin.
mode : ‘axes’ or ‘data’
In ‘axes’ (default) mode the matrix transforms data to different coordinate system, while
in ‘data’ mode the matrix transforms the data in the same coordinate system and is
transpose of the matrix in the ‘axes’ mode.
Returns mtx : array
The array of transformation matrices for each coordinate in coors.
sfepy.mechanics.tensors.sym2dim(sym)
Given the symmetric storage size, return the space dimension.
528
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Notes
This function works for any space dimension.
sfepy.mechanics.tensors.transform_data(data, coors=None, mode=’cylindrical’, mtx=None)
Transform vector or tensor data components between orthogonal coordinate systems in 3D using transformation
matrix 𝑀 , that should express rotation of the original coordinate system to the new system denoted by ∙′ below.
For vectors:
𝑣′ = 𝑀 · 𝑣
For second order tensors:
𝑡′ = 𝑀 · 𝑡 · 𝑀 𝑇
or
𝑡′𝑖𝑗
= 𝑀𝑖𝑝 𝑀𝑗𝑞 𝑡𝑝𝑞
For fourth order tensors:
𝑡′𝑖𝑗𝑘𝑙 = 𝑀𝑖𝑝 𝑀𝑗𝑞 𝑀𝑘𝑟 𝑀𝑙𝑠 𝑡𝑝𝑞𝑟𝑠
Parameters data : array, shape (num, n_r) or (num, n_r, n_c)
The vectors (n_r is 3) or tensors (symmetric storage, n_r is 6, n_c, if available, is 1 or
6) to be transformed.
coors : array
The Cartesian coordinates of the data. Not needed when mtx argument is given.
mode : one of [’cylindrical’]
The requested coordinate system. Not needed when mtx argument is given.
mtx : array
The array of transformation matrices 𝑀 for each data row.
Returns new_data : array
The transformed data.
sfepy.mechanics.units module
Some utilities for work with units of physical quantities.
class sfepy.mechanics.units.Quantity(name, unit_set)
A physical quantity in a given set of basic units.
Examples
Construct the stress quantity:
>>> from sfepy.mechanics.units import Unit, Quantity
>>> units = [’m’, ’s’, ’kg’, ’C’]
>>> unit_set = [Unit(key) for key in units]
>>> q1 = Quantity(’stress’, unit_set)
>>> q1()
’1.0 Pa’
7.8. Module Index
529
SfePy Documentation, Release 2015.1
Show its unit using various prefixes:
>>> q1(’m’)
’1000.0 mPa’
>>> q1(’’)
’1.0 Pa’
>>> q1(’k’)
’0.001 kPa’
>>> q1(’M’)
’1e-06 MPa’
Construct the stress quantity in another unit set:
>>> units = [’mm’, ’s’, ’kg’, ’C’]
>>> unit_set = [Unit(key) for key in units]
>>> q2 = Quantity(’stress’, unit_set)
>>> q2()
’1.0 kPa’
Show its unit using various prefixes:
>>> q2(’m’)
’1000000.0 mPa’
>>> q2(’’)
’1000.0 Pa’
>>> q2(’k’)
’1.0 kPa’
>>> q2(’M’)
’0.001 MPa’
class sfepy.mechanics.units.Unit(name)
A unit of a physical quantity. The prefix and coefficient of the unit are determined from to its name.
Examples
Construct some units:
>>> from sfepy.mechanics.units import Unit
>>> unit = Unit(’mm’)
>>> print unit
Unit:mm
coef:
0.001
name:
mm
prefix:
m
prefix_length:
1
unit:
m
>>> unit = Unit(’kg’)
>>> print unit
Unit:kg
coef:
1000.0
name:
kg
prefix:
530
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
k
prefix_length:
1
unit:
g
Get prefixes for a coefficient:
>>> Unit.get_prefix(100.0)
(’d’, 10.0)
>>> Unit.get_prefix(100.0, omit=(’d’,))
(’k’, 0.10000000000000001)
static get_prefix(coef, bias=0.1, omit=())
Get the prefix and numerical multiplier corresponding to a numerical coefficient, omitting prefixes in omit
tuple.
sfepy.mechanics.units.get_consistent_unit_set(length=None, time=None, mass=None,
temperature=None)
Given a set of basic units, return a consistent set of derived units for quantities listed in the units_of_quantities
dictionary.
7.8.10 sfepy.mesh package
sfepy.mesh.geom_tools module
class sfepy.mesh.geom_tools.geometry(dim=3)
The geometry is given by a sets of points (d0), lines (d1), surfaces (d2) and volumes (d3). A lines are constructed
from 2 points, a surface from any number of lines, a volume from any number of surfaces.
Physical volumes are contruted from any number of volumes.
The self.d0, self.d1, self.d2 and self.d3 are dictionaries holding a map
geometry element number -> instance of point,line,surface of volume
Examples
To get all the points which define a surface 5, use:
self.d2[5].getpoints()
This would give you a list [..] of point() instances.
addline(n, l)
l=[p1,p2]
addlines(ls, off=1)
ls=[l1, l2, ...]
addphysicalsurface(n, surfacelist)
surfacelist=[s1,s2,s3,...]
addphysicalvolume(n, volumelist)
volumelist=[v1,v2,v3,...]
addpoint(n, p)
p=[x,y,z]
7.8. Module Index
531
SfePy Documentation, Release 2015.1
addpoints(ps, off=1)
ps=[p1, p2, ...]
addsurface(n, s, is_hole=False)
s=[l1,l2,l3,...]
addsurfaces(ss, off=1)
s=[s1,s2,s3,...]
addvolume(n, v)
v=[s1,s2,s3,...]
addvolumes(vs, off=1)
v=[v1,v2,v3,...]
static from_gmsh_file(filename)
Import geometry - Gmsh geometry format.
Parameters filename : string
file name
Returns geo : geometry
geometry description
getBCnum(snum)
leaveonlyphysicalsurfaces()
leaveonlyphysicalvolumes()
printinfo(verbose=False)
splitlines(ls, n)
to_poly_file(filename)
Export geometry to poly format (tetgen and triangle geometry format).
Parameters geo : geometry
geometry description
filename : string
file name
class sfepy.mesh.geom_tools.geomobject
getn()
class sfepy.mesh.geom_tools.line(g, n, l)
getpoints()
class sfepy.mesh.geom_tools.physicalsurface(g, n, s)
getsurfaces()
class sfepy.mesh.geom_tools.physicalvolume(g, n, v)
getvolumes()
532
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.mesh.geom_tools.point(g, n, p)
getstr()
getxyz()
class sfepy.mesh.geom_tools.surface(g, n, s, is_hole=False)
getcenterpoint()
getholepoints()
getinsidepoint()
getlines()
getpoints()
separate(s)
class sfepy.mesh.geom_tools.volume(g, n, v)
getinsidepoint()
getsurfaces()
sfepy.mesh.mesh_generators module
sfepy.mesh.mesh_generators.gen_block_mesh(dims, shape, centre, mat_id=0, name=’block’,
coors=None, verbose=True)
Generate a 2D or 3D block mesh. The dimension is determined by the lenght of the shape argument.
Parameters dims : array of 2 or 3 floats
Dimensions of the block.
shape : array of 2 or 3 ints
Shape (counts of nodes in x, y, z) of the block mesh.
centre : array of 2 or 3 floats
Centre of the block.
mat_id : int, optional
The material id of all elements.
name : string
Mesh name.
verbose : bool
If True, show progress of the mesh generation.
Returns mesh : Mesh instance
sfepy.mesh.mesh_generators.gen_cylinder_mesh(dims,
shape,
centre,
axis=’x’,
force_hollow=False,
is_open=False,
open_angle=0.0,
non_uniform=False,
name=’cylinder’, verbose=True)
Generate a cylindrical mesh along an axis. Its cross-section can be ellipsoidal.
7.8. Module Index
533
SfePy Documentation, Release 2015.1
Parameters dims : array of 5 floats
Dimensions of the cylinder: inner surface semi-axes a1, b1, outer surface semi-axes a2,
b2, length.
shape : array of 3 ints
Shape (counts of nodes in radial, circumferential and longitudinal directions) of the
cylinder mesh.
centre : array of 3 floats
Centre of the cylinder.
axis: one of ‘x’, ‘y’, ‘z’ :
The axis of the cylinder.
force_hollow : boolean
Force hollow mesh even if inner radii a1 = b1 = 0.
is_open : boolean
Generate an open cylinder segment.
open_angle : float
Opening angle in radians.
non_uniform : boolean
If True, space the mesh nodes in radial direction so that the element volumes are (approximately) the same, making thus the elements towards the outer surface thinner.
name : string
Mesh name.
verbose : bool
If True, show progress of the mesh generation.
Returns mesh : Mesh instance
sfepy.mesh.mesh_generators.gen_extended_block_mesh(b_dims,
b_shape,
e_dims,
e_shape,
centre,
grading_fun=None, name=None)
Generate a 3D mesh with a central block and (coarse) extending side meshes.
The resulting mesh is again a block. Each of the components has a different material id.
Parameters b_dims : array of 3 floats
The dimensions of the central block.
b_shape : array of 3 ints
The shape (counts of nodes in x, y, z) of the central block mesh.
e_dims : array of 3 floats
The dimensions of the complete block (central block + extensions).
e_shape : int
The count of nodes of extending blocks in the direction from the central block.
centre : array of 3 floats
534
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The centre of the mesh.
grading_fun : callable, optional
A function of 𝑥 ∈ [0, 1] that can be used to shift nodes in the extension axis directions
to allow smooth grading of element sizes from the centre. The default function is 𝑥 * *𝑝
with 𝑝 determined so that the element sizes next to the central block have the size of the
shortest edge of the central block.
name : string, optional
The mesh name.
Returns mesh : Mesh instance
sfepy.mesh.mesh_generators.gen_mesh_from_goem(geo, a=None, quadratic=False, verbose=True,
refine=False,
polyfilename=’./meshgen.poly’,
out=’mesh’,
**kwargs)
Runs mesh generator - tetgen for 3D or triangle for 2D meshes.
Parameters geo : geometry
geometry description
a : int, optional
a maximum area/volume constraint
quadratic : bool, optional
set True for quadratic elements
verbose : bool, optional
detailed information
refine : bool, optional
refines mesh
Returns mesh : Mesh instance
triangular or tetrahedral mesh
sfepy.mesh.mesh_generators.gen_mesh_from_poly(filename, verbose=True)
Import mesh generated by tetgen or triangle.
Parameters filename : string
file name
Returns mesh : Mesh instance
triangular or tetrahedral mesh
sfepy.mesh.mesh_generators.gen_mesh_from_string(mesh_name, mesh_dir)
sfepy.mesh.mesh_generators.gen_mesh_from_voxels(voxels, dims, etype=’q’)
Generate FE mesh from voxels (volumetric data).
Parameters voxels : array
Voxel matrix, 1=material.
dims : array
Size of one voxel.
7.8. Module Index
535
SfePy Documentation, Release 2015.1
etype : integer, optional
‘q’ - quadrilateral or hexahedral elements ‘t’ - triangular or tetrahedral elements
Returns :
——- :
mesh : Mesh instance
Finite element mesh.
sfepy.mesh.mesh_generators.gen_misc_mesh(mesh_dir, force_create, kind, args, suffix=’.mesh’, verbose=False)
Create sphere or cube mesh according to kind in the given directory if it does not exist and return path to it.
sfepy.mesh.mesh_generators.gen_tiled_mesh(mesh, grid=None,
ret_ndmap=False)
Generate a new mesh by repeating a given periodic element along each axis.
scale=1.0,
eps=1e-06,
Parameters mesh : Mesh instance
The input periodic FE mesh.
grid : array
Number of repetition along each axis.
scale : float, optional
Scaling factor.
eps : float, optional
Tolerance for boundary detection.
ret_ndmap : bool, optional
If True, return global node map.
Returns mesh_out : Mesh instance
FE mesh.
ndmap : array
Maps: actual node id –> node id in the reference cell.
sfepy.mesh.mesh_generators.get_tensor_product_conn(shape)
Generate vertex connectivity for cells of a tensor-product mesh of the given shape.
Parameters shape : array of 2 or 3 ints
Shape (counts of nodes in x, y, z) of the mesh.
Returns conn : array
The vertex connectivity array.
desc : str
The cell kind.
sfepy.mesh.mesh_generators.main()
sfepy.mesh.mesh_generators.tiled_mesh1d(conns, coors, ngrps, idim, n_rep, bb, eps=1e-06,
ndmap=False)
536
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.mesh.mesh_tools module
sfepy.mesh.mesh_tools.elems_q2t(el)
sfepy.mesh.mesh_tools.smooth_mesh(mesh, n_iter=4, lam=0.6307, mu=-0.6347, weights=None,
bconstr=True, volume_corr=False)
FE mesh smoothing.
Based on:
[1] Steven K. Boyd, Ralph Muller, Smooth surface meshing for automated finite element model generation
from 3D image data, Journal of Biomechanics, Volume 39, Issue 7, 2006, Pages 1287-1295, ISSN 0021-9290,
10.1016/j.jbiomech.2005.03.006. (http://www.sciencedirect.com/science/article/pii/S0021929005001442)
Parameters mesh : mesh
FE mesh.
n_iter : integer, optional
Number of iteration steps.
lam : float, optional
Smoothing factor, see [1].
mu : float, optional
Unshrinking factor, see [1].
weights : array, optional
Edge weights, see [1].
bconstr: logical, optional :
Boundary constraints, if True only surface smoothing performed.
volume_corr: logical, optional :
Correct volume after smoothing process.
Returns coors : array
Coordinates of mesh nodes.
sfepy.mesh.splinebox module
class sfepy.mesh.splinebox.SplineBox(bbox, coors, name=’spbox’, **kwargs)
B-spline geometry parametrization. Geometry can be modified by moving spline control points.
change_shape(cpoint, val)
Change shape of spline parametrization.
Parameters cpoint : list
The indices of the spline control point.
val : array
Displacement.
static create_spb(bbox, coors, degree=3, nsg=None)
dvelocity(cpoint, dirvec)
Evaluate derivative of spline in a given control point and direction.
7.8. Module Index
537
SfePy Documentation, Release 2015.1
Parameters cpoint : list
The indices of the spline control point.
dir : array
The directional vector.
Returns dvel : array
The design velocity field.
evaluate(cp_coors=None)
Evaluate SplineBox.
Returns coors : array
The coordinates corresponding to the actual spline control points position.
cp_coors : array
If is not None, use as control points cooardinates.
get_control_points(init=False)
Get spline control points coordinates.
Returns cpt_coors : array
The coordinates of the spline control points.
init : bool
If True, return initial state.
get_coors_shape()
Get the shape of the coordinates.
set_control_points(cpt_coors, add=False)
Set spline control points position.
Parameters cpt_coors : array
The coordinates of the spline control points.
add : bool
If True, coors += cpt_coors
write_vtk(filename)
Write the SplineBox shape to the VTK file.
Parameters filename : str
The VTK file name.
7.8.11 sfepy.optimize package
sfepy.optimize.free_form_def module
class sfepy.optimize.free_form_def.DesignVariables(**kwargs)
normalize_null_space_base(magnitude=1.0)
renumber_by_boxes(sp_boxes)
538
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.optimize.free_form_def.SplineBox(**kwargs)
class sfepy.optimize.free_form_def.SplineBoxes(**kwargs)
create_mesh_from_control_points()
interp_coordinates()
interp_mesh_velocity(shape, dsg_vars, idsg)
set_control_points(dsg_vars=None)
sfepy.optimize.free_form_def.interp_box_coordinates(spb, cxyz=None)
sfepy.optimize.free_form_def.read_dsg_vars_hdf5(filename)
sfepy.optimize.free_form_def.read_spline_box_hdf5(filename)
sfepy.optimize.shape_optim module
class sfepy.optimize.shape_optim.ShapeOptimFlowCase(**kwargs)
check_custom_sensitivity(term_desc, idsg, delta, dp_var_data, state_ap)
check_sensitivity(idsgs, delta, dp_var_data, state_ap)
create_evaluables()
static from_conf(conf, dpb, apb)
generate_mesh_velocity(shape, idsgs=None)
obj_fun(state_dp)
Objective function evaluation for given direct problem state.
sensitivity(dp_var_data, state_ap, select=None)
Sensitivity of objective function evaluation for given direct and adjoint problem states.
sfepy.optimize.shape_optim.obj_fun(design, shape_opt, opts)
The objective function evaluation.
sfepy.optimize.shape_optim.obj_fun_grad(design, shape_opt, opts)
The objective function gradient evaluation.
sfepy.optimize.shape_optim.solve_problem_for_design(problem, design, shape_opt,
opts,
var_data=None,
use_cache=True,
is_mesh_update=True)
use_cache == True means direct problem...
sfepy.optimize.shape_optim.test_terms(idsgs, delta, shape_opt, dp_var_data, state_ap)
Test individual shape derivative terms.
sfepy.optimize.shape_optim.update_mesh(shape_opt, pb, design)
7.8.12 sfepy.physics package
sfepy.physics.potentials module
Classes for constructing potentials of atoms and molecules.
7.8. Module Index
539
SfePy Documentation, Release 2015.1
class sfepy.physics.potentials.CompoundPotential(objs=None)
Sum of several potentials.
append(obj)
insert(ii, obj)
update_expression()
class sfepy.physics.potentials.Potential(name, function, centre=None, dim=3, args=None)
Single spherically symmetric potential.
get_charge(coors, eps=1e-06)
Get charge corresponding to the potential by numerically applying Laplacian in spherical coordinates.
get_distance(coors)
Get the distance of points with coordinates coors of the potential centre.
class sfepy.physics.potentials.PotentialBase(**kwargs)
Base class for potentials.
sfepy.physics.schroedinger_app module
class sfepy.physics.schroedinger_app.SchroedingerApp(conf,
options,
**kwargs)
Base application for electronic structure calculations.
output_prefix,
Subclasses should typically override solve_eigen_problem() method.
This class allows solving only simple single electron problems, e.g. well, oscillator, hydrogen atom and boron
atom with 1 electron.
call()
make_full(mtx_s_phi)
static process_options(options)
Application options setup. Sets default values for missing non-compulsory options.
Options:
save_eig_vectors [(from_largest, from_smallest) or None] If None, save all.
save_results(eigs, mtx_phi, out=None, mesh_results_name=None, eig_results_name=None)
setup_options()
setup_output()
Setup various file names for the output directory given by self.problem.output_dir.
solve_eigen_problem()
sfepy.physics.schroedinger_app.guess_n_eigs(n_electron, n_eigs=None)
Guess the number of eigenvalues (energies) to compute so that the smearing iteration converges. Passing n_eigs
overrides the guess.
7.8.13 sfepy.postprocess package
sfepy.postprocess.dataset_manager module
Code to help with managing a TVTK data set in Pythonic ways.
540
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.postprocess.dataset_manager.DatasetManager
activate(name, category=’point’)
Make the specified array the active one.
add_array(array, name, category=’point’)
Add an array to the dataset to specified category (‘point’ or ‘cell’).
remove_array(name, category=’point’)
Remove an array by its name and optional category (point and cell). Returns the removed array.
rename_array(name1, name2, category=’point’)
Rename a particular array from name1 to name2.
update()
Update the dataset when the arrays are changed.
sfepy.postprocess.dataset_manager.get_all_attributes(obj)
Gets the scalar, vector and tensor attributes that are available in the given VTK data object.
sfepy.postprocess.dataset_manager.get_array_type(arr)
Returns if the array is a scalar (‘scalars’), vector (‘vectors’) or tensor (‘tensors’). It looks at the number of
components to decide. If it has a wierd number of components it returns the empty string.
sfepy.postprocess.dataset_manager.get_attribute_list(data)
Gets scalar, vector and tensor information from the given data (either cell or point data).
sfepy.postprocess.domain_specific module
Domain-specific plot functions.
All the plot functions accept the following parameters:
• source : Mayavi source
• ctp : Mayavi cell-to-point filter
• position : (x, y, z)
• family : ‘point’ or ‘cell’
• kind : ‘scalars’, ‘vectors’ or ‘tensors’
• name : name of a variable
All the plot functions return: - kind : ‘scalars’, ‘vectors’ or ‘tensors’ - name : name of a variable - active : Mayavi
module
class sfepy.postprocess.domain_specific.DomainSpecificPlot(fun_name, args)
Class holding domain-specific plot function and its parameters.
sfepy.postprocess.domain_specific.plot_displacements(source,
ctp,
bbox,
position,
family,
kind,
name,
rel_scaling=1.0,
color_kind=None,
color_name=None,
opacity=1.0)
Show displacements by displaying a colormap given by quantity color_name on the deformed mesh.
Parameters rel_scaling : float
The relative scaling of displacements.
7.8. Module Index
541
SfePy Documentation, Release 2015.1
color_kind : str, optional
The kind of data determining the colormap.
color_name : str, optional
The name of data determining the colormap.
opacity : float
The surface plot opacity.
sfepy.postprocess.domain_specific.plot_velocity(source,
ctp,
bbox,
position,
family,
kind,
name,
seed=’sphere’,
type=’ribbon’,
integration_direction=’both’,
seed_scale=1.0, seed_resolution=20,
widget_enabled=True,
color_kind=None, color_name=None,
opacity=1.0, **kwargs)
Show velocity field by displaying streamlines and optionally a surface plot given by quantity color_name.
Parameters seed : one of (‘sphere’, ‘point’, ‘line’, ‘plane’)
The streamline seed name.
type : one of (‘line’, ‘ribbon’, ‘tube’)
The streamline seed line type.
integration_direction : one of (‘forward’, ‘backward’, ‘both’)
The stream tracer integration direction.
seed_scale : float
The seed size scale.
seed_resolution : int
The number of seed points in a direction (depends on seed).
widget_enabled : bool
It True, the seed widget is visible and can be interacted with.
color_kind : str, optional
The kind of data determining the colormap.
color_name : str, optional
The name of data determining the colormap.
opacity : float
The surface plot opacity.
**kwargs : dict
Additional keyword arguments for attributes of streamline.seed.widget.
sfepy.postprocess.domain_specific.plot_warp_scalar(source, ctp, bbox, position, family,
kind, name, rel_scaling=1.0,
color_kind=None,
color_name=None, opacity=1.0)
Show a 2D scalar field by displaying a colormap given by quantity color_name on the deformed mesh deformed
by the scalar in the third dimension.
542
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Parameters rel_scaling : float
The relative scaling of scalar warp.
color_kind : str, optional
The kind of data determining the colormap.
color_name : str, optional
The name of data determining the colormap.
opacity : float
The surface plot opacity.
sfepy.postprocess.plot_cmesh module
Functions to visualize the CMesh geometry and topology.
sfepy.postprocess.plot_cmesh.label_global_entities(ax, cmesh, edim, color=’b’, fontsize=10, show=False)
Label mesh topology entities using global ids.
sfepy.postprocess.plot_cmesh.label_local_entities(ax, cmesh, edim, color=’b’, fontsize=10, show=False)
Label mesh topology entities using cell-local ids.
sfepy.postprocess.plot_cmesh.plot_entities(ax, cmesh, edim,
show=False)
Plot mesh topology entities using scatter plot.
color=’b’,
size=10,
sfepy.postprocess.plot_cmesh.plot_wireframe(ax, cmesh, color=’k’, show=False)
Plot a finite element mesh as a wireframe using edges connectivity.
sfepy.postprocess.plot_dofs module
Functions to visualize the mesh connectivity with global and local DOF numberings.
sfepy.postprocess.plot_dofs.plot_global_dofs(ax, coors, econn, show=False)
Plot global DOF numbers given in an extended connectivity.
The DOF numbers are plotted for each element, so on common facets they are plotted several times - this can
be used to check the consistency of the global DOF connectivity.
sfepy.postprocess.plot_dofs.plot_local_dofs(ax, coors, econn, show=False)
Plot local DOF numbers corresponding to an extended connectivity.
sfepy.postprocess.plot_dofs.plot_mesh(ax, coors, conn, edges, show=False)
Plot a finite element mesh as a wireframe.
sfepy.postprocess.plot_dofs.plot_nodes(ax, coors, econn, ref_nodes, dofs, show=False)
Plot Lagrange reference element nodes corresponding to global DOF numbers given in an extended connectivity.
sfepy.postprocess.plot_dofs.plot_points(ax,
coors,
vals=None,
point_size=20,
show_colorbar=False, show=False)
Plot points with given coordinates, optionally colored using vals values.
7.8. Module Index
543
SfePy Documentation, Release 2015.1
sfepy.postprocess.plot_facets module
Functions to visualize the geometry elements and numbering and orientation of their facets (edges and faces).
The standard geometry elements can be plotted by running:
$ python sfepy/postprocess/plot_facets.py
sfepy.postprocess.plot_facets.draw_arrow(ax, coors, angle=20.0, length=0.3, **kwargs)
Draw a line ended with an arrow head, in 2D or 3D.
sfepy.postprocess.plot_facets.plot_edges(ax, gel, length, show=False)
Plot edges of a geometry element as numbered arrows.
sfepy.postprocess.plot_facets.plot_faces(ax, gel, radius, n_point, show=False)
Plot faces of a 3D geometry element as numbered oriented arcs. An arc centre corresponds to the first node of a
face. It points from the first edge towards the last edge of the face.
sfepy.postprocess.plot_facets.plot_geometry(ax, gel, show=False)
Plot a geometry element as a wireframe.
sfepy.postprocess.plot_quadrature module
Functions to visualize quadrature points in reference elements.
sfepy.postprocess.plot_quadrature.plot_quadrature(ax,
geometry,
order,
min_radius=10, max_radius=50,
show_colorbar=False,
show=False)
Plot quadrature points for the given geometry and integration order.
The points are plotted as circles/spheres with radii given by quadrature weights - the weights are mapped to
[min_radius, max_radius] interval.
sfepy.postprocess.plot_quadrature.plot_weighted_points(ax,
coors,
weights,
min_radius=10,
max_radius=50,
show_colorbar=False,
show=False)
Plot points with given coordinates as circles/spheres with radii given by weights.
sfepy.postprocess.probes_vtk module
Classes for probing values of Variables, for example, along a line, using PyVTK library
class sfepy.postprocess.probes_vtk.Probe(data, mesh, **kwargs)
Probe class.
add_circle_probe(name, centre, normal, radius, n_point)
Create the ray (line) probe - VTK object.
Parameters name : str
The probe name.
centre : array
The coordinates of the circle center point.
normal : array
544
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The normal vector perpendicular to the circle plane.
radius : float
The radius of the circle.
n_point : int
The number of probe points.
add_line_probe(name, p0, p1, n_point)
Create the line probe - VTK object.
Parameters name : str
The probe name.
p0 : array_like
The coordinates of the start point.
p1 : array_like
The coordinates of the end point.
n_point : int
The number of probe points.
add_ray_probe(name, p0, dirvec, p_fun, n_point)
Create the ray (line) probe - VTK object.
Parameters name : str
The probe name.
p0 : array
The coordinates of the start point.
dirvec : array
The probe direction vector.
p_fun : function
The function returning the probe parametrization along the dirvec direction.
n_point : int
The number of probe points.
gen_mesh_probe_png(probe, png_filename)
Generate PNG image of the FE mesh.
Parameters probe : VTK objectstr
The probe, VTKPolyData or VTKSource.
png_filename : str
The name of the output PNG file.
new_vtk_polyline(points, closed=False)
Create the VTKPolyData object and store the line data.
Parameters points : array
The line points.
7.8. Module Index
545
SfePy Documentation, Release 2015.1
Returns vtkpd : VTK object
VTKPolyData with the polyline.
sfepy.postprocess.sources module
class sfepy.postprocess.sources.FileSource(filename, watch=False, offscreen=True)
General file source.
file_changed()
get_mat_id(mat_id_name=’mat_id’)
Get material ID numbers of the underlying mesh elements.
get_step_time(step=None, time=None)
Set current step and time to the values closest greater or equal to either step or time. Return the found
values.
get_ts_info()
poll_file()
Check the source file’s time stamp and notify the self.notify_obj in case it changed. Subclasses should
implement the file_changed() method.
reset()
Reset.
setup_mat_id(mat_id_name=’mat_id’, single_color=False)
setup_notification(obj, attr)
The attribute ‘attr’ of the object ‘obj’ will be set to True when the source file is watched and changes.
class sfepy.postprocess.sources.GenericFileSource(*args, **kwargs)
File source usable with any format supported by MeshIO classes.
add_data_to_dataset(dataset, data)
Add point and cell data to the dataset.
create_dataset()
Create a tvtk.UnstructuredGrid dataset from the Mesh instance of the file source.
create_source()
Create a VTK source from data in a SfePy-supported file.
Notes
All data need to be set here, otherwise time stepping will not work properly - data added by user later will
be thrown away on time step change.
file_changed()
get_bounding_box()
get_mat_id(mat_id_name=’mat_id’)
Get material ID numbers of the underlying mesh elements.
read_common(filename)
set_filename(filename, vis_source)
546
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.postprocess.sources.GenericSequenceFileSource(*args, **kwargs)
File source usable with any format supported by MeshIO classes, with exception of HDF5 (.h5), for file sequences.
create_source()
Create a VTK source from data in a SfePy-supported file.
read_common(filename)
set_filename(filename, vis_source)
class sfepy.postprocess.sources.VTKFileSource(filename, watch=False, offscreen=True)
A thin wrapper around mlab.pipeline.open().
create_source()
Create a VTK file source
get_bounding_box()
set_filename(filename, vis_source)
class sfepy.postprocess.sources.VTKSequenceFileSource(*args, **kwargs)
A thin wrapper around mlab.pipeline.open() for VTK file sequences.
create_source()
Create a VTK file source
set_filename(filename, vis_source)
sfepy.postprocess.sources.create_file_source(filename, watch=False, offscreen=True)
Factory function to create a file source corresponding to the given file format.
sfepy.postprocess.time_history module
sfepy.postprocess.time_history.average_vertex_var_in_cells(ths_in)
Average histories in the element nodes for each nodal variable originally requested in elements.
sfepy.postprocess.time_history.dump_to_vtk(filename,
output_filename_trunk=None,
step0=0, steps=None, fields=None, linearization=None)
Dump a multi-time-step results file into a sequence of VTK files.
sfepy.postprocess.time_history.extract_time_history(filename, extract, verbose=True)
Extract time history of a variable from a multi-time-step results file.
Parameters filename : str
The name of file to extract from.
extract : str
The description of what to extract in a string of comma-separated description items. A
description item consists of: name of the variable to extract, mode (‘e’ for elements, ‘n’
for nodes), ids of the nodes or elements (given by the mode). Example: ‘u n 10 15, p e
0’ means variable ‘u’ in nodes 10, 15 and variable ‘p’ in element 0.
verbose : bool
Verbosity control.
Returns ths : dict
The time histories in a dict with variable names as keys. If a nodal variable is requested
in elements, its value is a dict of histories in the element nodes.
7.8. Module Index
547
SfePy Documentation, Release 2015.1
ts : TimeStepper instance
The time stepping information.
sfepy.postprocess.time_history.extract_times(filename)
Read true time step data from individual time steps.
Returns steps : array
The time steps.
times : array
The times of the time steps.
nts : array
The normalized times of the time steps, in [0, 1].
dts : array
The true time deltas.
sfepy.postprocess.time_history.guess_time_units(times)
Given a vector of times in seconds, return suitable time units and new vector of times suitable for plotting.
Parameters times : array
The vector of times in seconds.
Returns new_times : array
The vector of times in units.
units : str
The time units.
sfepy.postprocess.time_history.save_time_history(ths, ts, filename_out)
Save time history and time-stepping information in a HDF5 file.
sfepy.postprocess.utils module
sfepy.postprocess.utils.get_data_ranges(obj, return_only=False, use_names=None, filter_names=None)
Collect and print information on ranges of data in a dataset.
Parameters obj : a mayavi pipeline object
The object to probe for data.
return_only : boolean
If True, do not print the information, just return it to the caller.
use_names : list of strings
Consider only data with names in the list.
filter_names : list of strings
Consider only data with names not in the list.
Returns ranges : dict
The requested data ranges.
548
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.postprocess.utils_vtk module
Postprocessing utils based on VTK library
sfepy.postprocess.utils_vtk.get_vtk_by_group(vtkdata,
group_upper=None)
Get submesh by material group id.
group_lower,
Parameters vtkdata : VTK object
Mesh, scalar, vector and tensor data.
group_lower : int
The lower material id.
group_lower : int
The Upper material id.
Returns slection : VTK object
Mesh, scalar, vector and tensor data.
sfepy.postprocess.utils_vtk.get_vtk_edges(vtkdata)
Get mesh edges.
Parameters vtkdata : VTK object
Mesh, scalar, vector and tensor data.
Returns edges : VTK object
Mesh, scalar, vector and tensor data.
sfepy.postprocess.utils_vtk.get_vtk_from_file(filename)
Read VTK file.
Parameters filename : str
Name of the VTK file.
Returns vtkdata : VTK object
Mesh, scalar, vector and tensor data.
sfepy.postprocess.utils_vtk.get_vtk_from_mesh(mesh, data, prefix=’‘)
sfepy.postprocess.utils_vtk.get_vtk_surface(vtkdata)
Get mesh surface.
Parameters vtkdata : VTK object
Mesh, scalar, vector and tensor data.
Returns surface : VTK object
Mesh, scalar, vector and tensor data.
sfepy.postprocess.utils_vtk.tetrahedralize_vtk_mesh(vtkdata)
3D cells are converted to tetrahedral meshes, 2D cells to triangles.
Parameters vtkdata : VTK object
Mesh, scalar, vector and tensor data.
Returns tetra : VTK object
Mesh, scalar, vector and tensor data.
7.8. Module Index
549
SfePy Documentation, Release 2015.1
sfepy.postprocess.utils_vtk.write_vtk_to_file(filename, vtkdata)
Write VTK file.
Parameters filename : str
Name of the VTK file.
vtkdata : VTK object
Mesh, scalar, vector and tensor data.
sfepy.postprocess.viewer module
class sfepy.postprocess.viewer.ClosingHandler
object_button_quit_changed(info)
class sfepy.postprocess.viewer.ReloadSource
class sfepy.postprocess.viewer.SetStep
init_seq_selection(name, new)
is_adjust = False
step = None
time = None
class sfepy.postprocess.viewer.Viewer(filename, watch=False, ffmpeg_options=None,
put_dir=’.’, offscreen=False)
Class to automate visualization of various data using Mayavi.
out-
It can use any format that mlab.pipeline.open() handles, e.g. a VTK format. After opening a data file, all data
(point, cell, scalars, vectors, tensors) are plotted in a grid layout.
Parameters:
watch [bool] If True, watch the file for changes and update the mayavi pipeline automatically.
ffmpeg_options [str] The ffmpeg animation encoding options.
output_dir [str] The output directory, where view snapshots will be saved.
Examples:
>>> view = Viewer(’file.vtk’)
>>> view() # view with default parameters
>>> view(layout=’col’) # use column layout
build_mlab_pipeline(file_source=None,
is_3d=False,
layout=’rowcol’,
scalar_mode=’iso_surface’,
vector_mode=’arrows_norm’,
rel_scaling=None, clamping=False, ranges=None, is_scalar_bar=False,
is_wireframe=False,
opacity=None,
subdomains_args=None,
rel_text_width=None,
filter_names=None,
group_names=None,
only_names=None, domain_specific=None, **kwargs)
Sets self.source, self.is_3d_data
call_empty(*args, **kwargs)
550
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
call_mlab(scene=None, show=True, is_3d=False, view=None, roll=None, fgcolor=(0.0, 0.0,
0.0), bgcolor=(1.0, 1.0, 1.0), layout=’rowcol’, scalar_mode=’iso_surface’, vector_mode=’arrows_norm’,
rel_scaling=None,
clamping=False,
ranges=None,
is_scalar_bar=False, is_wireframe=False, opacity=None, subdomains_args=None,
rel_text_width=None, fig_filename=’view.png’, resolution=None, filter_names=None,
only_names=None, group_names=None, step=None, time=None, anti_aliasing=None,
domain_specific=None)
By default, all data (point, cell, scalars, vectors, tensors) are plotted in a grid layout, except data named
‘node_groups’, ‘mat_id’ which are usually not interesting.
Parameters show : bool
Call mlab.show().
is_3d : bool
If True, use scalar cut planes instead of surface for certain datasets. Also sets 3D view
mode.
view : tuple
Azimuth, elevation angles, distance and focal point as in mlab.view().
roll : float
Roll angle tuple as in mlab.roll().
fgcolor : tuple of floats (R, G, B)
The foreground color, that is the color of all text annotation labels (axes, orientation
axes, scalar bar labels).
bgcolor : tuple of floats (R, G, B)
The background color.
layout : str
Grid layout for placing the datasets. Possible values are: ‘row’, ‘col’, ‘rowcol’, ‘colrow’.
scalar_mode : str
Mode for plotting scalars and tensor magnitudes, one of ‘cut_plane’, ‘iso_surface’,
‘both’.
vector_mode : str
Mode for plotting vectors, one of ‘arrows’, ‘norm’, ‘arrows_norm’, ‘warp_norm’.
rel_scaling : float
Relative scaling of glyphs for vector datasets.
clamping : bool
Clamping for vector datasets.
ranges : dict
List of data ranges in the form {name : (min, max), ...}.
is_scalar_bar : bool
If True, show a scalar bar for each data.
is_wireframe : bool
7.8. Module Index
551
SfePy Documentation, Release 2015.1
If True, show a wireframe of mesh surface bar for each data.
opacity : float
Global surface and wireframe opacity setting in [0.0, 1.0],
subdomains_args : tuple
Tuple
of
(mat_id_name,
threshold_limits,
add_subdomains_surface(), or None.
single_color),
see
rel_text_width : float
Relative text width.
fig_filename : str
File name for saving the resulting scene figure.
resolution : tuple
Scene and figure resolution. If None, it is set automatically according to the layout.
filter_names : list of strings
Omit the listed datasets. If None, it is initialized to [’node_groups’, ‘mat_id’]. Pass []
if you need no filtering.
only_names : list of strings
Draw only the listed datasets. If None, it is initialized all names besides those in filter_names.
group_names : list of tuples
List of data names in the form [(name1, ..., nameN), (...)]. Plots of data named in each
group are superimposed. Repetitions of names are possible.
step : int, optional
If not None, the time step to display. The closest higher step is used if the desired one
is not available. Has precedence over time.
time : float, optional
If not None, the time of the time step to display. The closest higher time is used if the
desired one is not available.
anti_aliasing : int
Value of anti-aliasing.
domain_specific : dict
Domain-specific drawing functions and configurations.
encode_animation(filename, format, ffmpeg_options=None)
get_animation_info(filename, add_output_dir=True, last_step=None)
get_data_names(source=None, detailed=False)
get_size_hint(layout, resolution=None)
render_scene(scene, options)
Render the scene, preferably after it has been activated.
reset_view()
552
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
save_animation(filename, steps=None, times=None)
Animate the current scene view for the selected time steps or times and save a snapshot of each view.
save_image(filename)
Save a snapshot of the current scene.
set_source_filename(filename)
show_scalar_bars(scalar_bars)
class sfepy.postprocess.viewer.ViewerGUI(fgcolor=(0.0, 0.0, 0.0), bgcolor=(1.0, 1.0, 1.0),
**traits)
sfepy.postprocess.viewer.add_glyphs(obj,
position,
bbox,
rel_scaling=None,
scale_factor=’auto’, clamping=False, color=None)
sfepy.postprocess.viewer.add_iso_surface(obj, position, contours=10, opacity=1.0)
sfepy.postprocess.viewer.add_scalar_cut_plane(obj, position, normal, opacity=1.0)
sfepy.postprocess.viewer.add_subdomains_surface(obj, position, mat_id_name=’mat_id’,
threshold_limits=(None,
None),
**kwargs)
sfepy.postprocess.viewer.add_surf(obj, position, opacity=1.0)
sfepy.postprocess.viewer.add_text(obj, position, text, width=None, color=(0, 0, 0))
sfepy.postprocess.viewer.add_vector_cut_plane(obj,
position,
normal,
bbox,
rel_scaling=None, scale_factor=’auto’,
clamping=False, opacity=1.0)
sfepy.postprocess.viewer.get_glyphs_scale_factor(rng, rel_scaling, bbox)
sfepy.postprocess.viewer.get_opacities(opacity)
Provide defaults for all supported opacity settings.
sfepy.postprocess.viewer.get_position_counts(n_data, layout)
sfepy.postprocess.viewer.make_animation(filename, view, roll, anim_format, options,
steps=None, times=None, reuse_viewer=None)
7.8.14 sfepy.solvers package
sfepy.solvers.eigen module
class sfepy.solvers.eigen.LOBPCGEigenvalueSolver(conf, **kwargs)
SciPy-based LOBPCG solver for sparse symmetric problems.
Kind: ‘eig.scipy_lobpcg’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters i_max : int (default: 20)
The maximum number of iterations.
eps_a : float
The absolute tolerance for the convergence.
largest : bool (default: True)
If True, solve for the largest eigenvalues, otherwise the smallest.
7.8. Module Index
553
SfePy Documentation, Release 2015.1
precond : {dense matrix, sparse matrix, LinearOperator}
The preconditioner.
name = ‘eig.scipy_lobpcg’
class sfepy.solvers.eigen.PysparseEigenvalueSolver(conf, **kwargs)
Pysparse-based eigenvalue solver for sparse symmetric problems.
Kind: ‘eig.pysparse’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters i_max : int (default: 100)
The maximum number of iterations.
eps_a : float (default: 1e-05)
The absolute tolerance for the convergence.
tau : float (default: 0.0)
The target value.
method : {‘cgs’, ‘qmrs’} (default: ‘qmrs’)
The linear iterative solver supported by pysparse.
verbosity : int (default: 0)
The pysparse verbosity level.
strategy : {0, 1} (default: 1)
The shifting and sorting strategy of JDSYM: strategy=0 enables the default JDSYM
algorithm, strategy=1 enables JDSYM to avoid convergence to eigenvalues smaller than
tau.
name = ‘eig.pysparse’
class sfepy.solvers.eigen.ScipyEigenvalueSolver(conf, **kwargs)
SciPy-based solver for both dense and sparse problems (if n_eigs is given).
Kind: ‘eig.scipy’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘eig’, ‘eigh’} (default: ‘eig’)
The method for solving general or symmetric eigenvalue problems: for dense problems eig() or eigh() are used, for sparse problems (if n_eigs is given) eigs() or
eigsh() are used.
*:*
Additional parameters supported by the method.
name = ‘eig.scipy’
class sfepy.solvers.eigen.ScipySGEigenvalueSolver(conf, **kwargs)
SciPy-based solver for dense symmetric problems.
Kind: ‘eig.sgscipy’
554
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
For common configuration parameters, see Solver.
Specific configuration parameters:
name = ‘eig.sgscipy’
sfepy.solvers.eigen.eig(mtx_a,
mtx_b=None,
n_eigs=None,
eigenvectors=True,
turn_time=None, method=’eig.scipy’, **ckwargs)
Utility function that constructs an eigenvalue solver given by method, calls it and returns solution.
re-
sfepy.solvers.eigen.standard_call(call)
Decorator handling argument preparation and timing for eigensolvers.
sfepy.solvers.ls module
class sfepy.solvers.ls.MultiProblem(conf, problem, **kwargs)
Conjugate multiple problems.
Allows to define conjugate multiple problems.
Kind: ‘ls.cm_pb’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘auto’, ‘umfpack’, ‘superlu’} (default: ‘auto’)
The actual solver to use.
presolve : bool (default: False)
If True, pre-factorize the matrix.
warn : bool (default: True)
If True, allow warnings.
others : list
The list of auxiliary problem definition files.
coupling_variables : list
The list of coupling variables.
name = ‘ls.cm_pb’
sparse_submat(Ad, Ar, Ac, gr, gc, S)
A[gr,gc] = S
class sfepy.solvers.ls.PETScKrylovSolver(conf, **kwargs)
PETSc Krylov subspace solver.
The solver and preconditioner types are set upon the solver object creation. Tolerances can be overriden when
called by passing a conf object.
Convergence is reached when rnorm < max(eps_r * rnorm_0, eps_a), where, in PETSc, rnorm is by default the
norm of preconditioned residual.
Kind: ‘ls.petsc’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : str (default: ‘cg’)
7.8. Module Index
555
SfePy Documentation, Release 2015.1
The actual solver to use.
precond : str (default: ‘icc’)
The preconditioner.
precond_side : {‘left’, ‘right’, ‘symmetric’, None}
The preconditioner side.
i_max : int (default: 100)
The maximum number of iterations.
eps_a : float (default: 1e-08)
The absolute tolerance for the residual.
eps_r : float (default: 1e-08)
The relative tolerance for the residual.
eps_d : float (default: 100000.0)
The divergence tolerance for the residual.
name = ‘ls.petsc’
set_matrix(mtx)
class sfepy.solvers.ls.PETScParallelKrylovSolver(conf, **kwargs)
PETSc Krylov subspace solver able to run in parallel by storing the system to disk and running a separate script
via mpiexec.
The solver and preconditioner types are set upon the solver object creation. Tolerances can be overriden when
called by passing a conf object.
Convergence is reached when rnorm < max(eps_r * rnorm_0, eps_a), where, in PETSc, rnorm is by default the
norm of preconditioned residual.
Kind: ‘ls.petsc_parallel’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : str (default: ‘cg’)
The actual solver to use.
precond : str (default: ‘icc’)
The preconditioner.
precond_side : {‘left’, ‘right’, ‘symmetric’, None}
The preconditioner side.
i_max : int (default: 100)
The maximum number of iterations.
eps_a : float (default: 1e-08)
The absolute tolerance for the residual.
eps_r : float (default: 1e-08)
The relative tolerance for the residual.
556
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
eps_d : float (default: 100000.0)
The divergence tolerance for the residual.
log_dir : str (default: ‘.’)
The directory for storing logs.
n_proc : int (default: 1)
The number of processes.
sub_precond : str (default: ‘icc’)
The preconditioner for matrix blocks.
name = ‘ls.petsc_parallel’
class sfepy.solvers.ls.PyAMGSolver(conf, **kwargs)
Interface to PyAMG solvers.
Kind: ‘ls.pyamg’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : str (default: ‘smoothed_aggregation_solver’)
The actual solver to use.
accel : str
The accelerator.
i_max : int (default: 100)
The maximum number of iterations.
eps_r : float (default: 1e-08)
The relative tolerance for the residual.
name = ‘ls.pyamg’
class sfepy.solvers.ls.SchurComplement(conf, **kwargs)
Schur complement.
Solution of the linear system
[︂
𝐴
𝐶
𝐵
𝐷
]︂ [︂
]︂ [︂
]︂
𝑢
𝑓
·
=
𝑣
𝑔
is obtained by solving the following equation:
(𝐷 − 𝐶𝐴−1 𝐵) · 𝑣 = 𝑔 − 𝐶𝐴−1 𝑓
variable(s) 𝑢 are specified in “eliminate” list, variable(s) 𝑣 are specified in “keep” list,
See: http://en.wikipedia.org/wiki/Schur_complement
Kind: ‘ls.schur_complement’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘auto’, ‘umfpack’, ‘superlu’} (default: ‘auto’)
The actual solver to use.
7.8. Module Index
557
SfePy Documentation, Release 2015.1
presolve : bool (default: False)
If True, pre-factorize the matrix.
warn : bool (default: True)
If True, allow warnings.
eliminate : list
The list of variables to eliminate.
keep : list
The list of variables to keep.
name = ‘ls.schur_complement’
static schur_fun(res, mtx, rhs, nn)
class sfepy.solvers.ls.SchurGeneralized(conf, problem, **kwargs)
Generalized Schur complement.
Defines the matrix blocks and calls user defined function.
Kind: ‘ls.schur_generalized’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘auto’, ‘umfpack’, ‘superlu’} (default: ‘auto’)
The actual solver to use.
presolve : bool (default: False)
If True, pre-factorize the matrix.
warn : bool (default: True)
If True, allow warnings.
blocks : dict
The description of blocks: {block_name1 :
...}.
[variable_name1, ...],
function : callable
The user defined function.
name = ‘ls.schur_generalized’
class sfepy.solvers.ls.ScipyDirect(conf, **kwargs)
Direct sparse solver from SciPy.
Kind: ‘ls.scipy_direct’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘auto’, ‘umfpack’, ‘superlu’} (default: ‘auto’)
The actual solver to use.
presolve : bool (default: False)
If True, pre-factorize the matrix.
558
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
warn : bool (default: True)
If True, allow warnings.
name = ‘ls.scipy_direct’
class sfepy.solvers.ls.ScipyIterative(conf, **kwargs)
Interface to SciPy iterative solvers.
The eps_r tolerance is both absolute and relative - the solvers stop when either the relative or the absolute
residual is below it.
A preconditioner can be anything that the SciPy solvers accept (sparse matrix, dense matrix, LinearOperator).
Kind: ‘ls.scipy_iterative’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : str (default: ‘cg’)
The actual solver to use.
precond : {sparse matrix, dense matrix, LinearOperator}
The preconditioner.
callback : function
User-supplied function to call after each iteration. It is called as callback(xk), where xk
is the current solution vector.
i_max : int (default: 100)
The maximum number of iterations.
eps_r : float (default: 1e-08)
The relative or absolute tolerance for the residual.
name = ‘ls.scipy_iterative’
sfepy.solvers.ls.solve(mtx, rhs, solver_class=None, solver_conf=None)
Solve the linear system with the matrix mtx and the right-hand side rhs.
Convenience wrapper around the linear solver classes below.
sfepy.solvers.ls.standard_call(call)
Decorator handling argument preparation and timing for linear solvers.
sfepy.solvers.nls module
Nonlinear solvers.
class sfepy.solvers.nls.Newton(conf, **kwargs)
Solves a nonlinear system 𝑓 (𝑥) = 0 using the Newton method with backtracking line-search, starting with an
initial guess 𝑥0 .
Kind: ‘nls.newton’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters i_max : int (default: 1)
7.8. Module Index
559
SfePy Documentation, Release 2015.1
The maximum number of iterations.
eps_a : float (default: 1e-10)
The absolute tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||.
eps_r : float (default: 1.0)
The relative tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥0 )||.
eps_mode : ‘and’ or ‘or’ (default: ‘and’)
The logical operator to use for combining the absolute and relative tolerances.
macheps : float (default: 2.2204460492503131e-16)
The float considered to be machine “zero”.
lin_red : float (default: 1.0)
The linear system solution error should be smaller than (eps_a * lin_red), otherwise a
warning is printed.
lin_precision : float or None
If not None, the linear system solution tolerances are set in each nonlinear iteration
relative to the current residual norm by the lin_precision factor. Ignored for direct linear
solvers.
ls_on : float (default: 0.99999)
Start the backtracking line-search by reducing the step, if ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥𝑖−1 )|| is larger
than ls_on.
ls_red : 0.0 < float < 1.0 (default: 0.1)
The step reduction factor in case of correct residual assembling.
ls_red_warp : 0.0 < float < 1.0 (default: 0.001)
The step reduction factor in case of failed residual assembling (e.g. the “warp violation”
error caused by a negative volume element resulting from too large deformations).
ls_min : 0.0 < float < 1.0 (default: 1e-05)
The minimum step reduction factor.
give_up_warp : bool (default: False)
If True, abort on the “warp violation” error.
check : 0, 1 or 2 (default: 0)
If >= 1, check the tangent matrix using finite differences. If 2, plot the resulting sparsity
patterns.
delta : float (default: 1e-06)
If check >= 1, the finite difference matrix is taken as 𝐴𝑖𝑗 =
𝑓𝑖 (𝑥𝑗 +𝛿)−𝑓𝑖 (𝑥𝑗 −𝛿)
.
2𝛿
log : dict or None
If not None, log the convergence according to the configuration in the following form:
{’text’ : ’log.txt’, ’plot’ : ’log.pdf’}. Each of the dict items
can be None.
is_linear : bool (default: False)
If True, the problem is considered to be linear.
560
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
__call__(vec_x0, conf=None, fun=None, fun_grad=None, lin_solver=None, iter_hook=None, status=None)
Nonlinear system solver call.
Solves a nonlinear system 𝑓 (𝑥) = 0 using the Newton method with backtracking line-search, starting with
an initial guess 𝑥0 .
Parameters vec_x0 : array
The initial guess vector 𝑥0 .
conf : Struct instance, optional
The solver configuration parameters,
fun : function, optional
The function 𝑓 (𝑥) whose zero is sought - the residual.
fun_grad : function, optional
The gradient of 𝑓 (𝑥) - the tangent matrix.
lin_solver : LinearSolver instance, optional
The linear solver for each nonlinear iteration.
iter_hook : function, optional
User-supplied function to call before each iteration.
status : dict-like, optional
The user-supplied object to hold convergence statistics.
Notes
•The optional parameters except iter_hook and status need to be given either here or upon Newton
construction.
•Setting conf.is_linear == True means a pre-assembled and possibly pre-solved matrix. This is mostly
useful for linear time-dependent problems.
__init__(conf, **kwargs)
__metaclass__
alias of SolverMeta
__module__ = ‘sfepy.solvers.nls’
name = ‘nls.newton’
class sfepy.solvers.nls.ScipyBroyden(conf, **kwargs)
Interface to Broyden and Anderson solvers from scipy.optimize.
Kind: ‘nls.scipy_broyden_like’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : str (default: ‘anderson’)
The name of the solver in scipy.optimize.
i_max : int (default: 10)
7.8. Module Index
561
SfePy Documentation, Release 2015.1
The maximum number of iterations.
alpha : float (default: 0.9)
See scipy.optimize.
M : float (default: 5)
See scipy.optimize.
f_tol : float (default: 1e-06)
See scipy.optimize.
w0 : float (default: 0.1)
See scipy.optimize.
__call__(vec_x0, conf=None, fun=None, fun_grad=None, lin_solver=None, iter_hook=None, status=None)
__init__(conf, **kwargs)
__metaclass__
alias of SolverMeta
__module__ = ‘sfepy.solvers.nls’
name = ‘nls.scipy_broyden_like’
set_method(conf )
sfepy.solvers.nls.check_tangent_matrix(conf, vec_x0, fun, fun_grad)
Verify the correctness of the tangent matrix as computed by fun_grad() by comparing it with its finite difference
approximation evaluated by repeatedly calling fun() with vec_x0 items perturbed by a small delta.
sfepy.solvers.nls.conv_test(conf, it, err, err0)
Nonlinear solver convergence test.
Parameters conf : Struct instance
The nonlinear solver configuration.
it : int
The current iteration.
err : float
The current iteration error.
err0 : float
The initial error.
Returns status : int
The convergence status: -1 = no convergence (yet), 0 = solver converged - tolerances
were met, 1 = max. number of iterations reached.
sfepy.solvers.optimize module
class sfepy.solvers.optimize.FMinSteepestDescent(conf, **kwargs)
Steepest descent optimization solver.
Kind: ‘opt.fmin_sd’
562
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters i_max : int (default: 10)
The maximum number of iterations.
eps_rd : float (default: 1e-05)
The relative delta of the objective function.
eps_of : float (default: 0.0001)
The tolerance for the objective function.
eps_ofg : float (default: 1e-08)
The tolerance for the objective function gradient.
norm : numpy norm (default: inf)
The norm to be used.
ls : bool (default: True)
If True, use a line-search.
ls_method : {‘backtracking’, ‘full’} (default: ‘backtracking’)
The line-search method.
ls_on : float (default: 0.99999)
Start the backtracking line-search by reducing the step, if ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥𝑖−1 )|| is larger
than ls_on.
ls0 : 0.0 < float < 1.0 (default: 1.0)
The initial step.
ls_red : 0.0 < float < 1.0 (default: 0.5)
The step reduction factor in case of correct residual assembling.
ls_red_warp : 0.0 < float < 1.0 (default: 0.1)
The step reduction factor in case of failed residual assembling (e.g. the “warp violation”
error caused by a negative volume element resulting from too large deformations).
ls_min : 0.0 < float < 1.0 (default: 1e-05)
The minimum step reduction factor.
check : 0, 1 or 2 (default: 0)
If >= 1, check the tangent matrix using finite differences. If 2, plot the resulting sparsity
patterns.
delta : float (default: 1e-06)
If check >= 1, the finite difference matrix is taken as 𝐴𝑖𝑗 =
𝑓𝑖 (𝑥𝑗 +𝛿)−𝑓𝑖 (𝑥𝑗 −𝛿)
.
2𝛿
output : function
If given, use it instead of output() function.
yscales : list of str (default: [’linear’, ‘log’, ‘log’, ‘linear’])
The list of four convergence log subplot scales.
7.8. Module Index
563
SfePy Documentation, Release 2015.1
log : dict or None
If not None, log the convergence according to the configuration in the following form:
{’text’ : ’log.txt’, ’plot’ : ’log.pdf’}. Each of the dict items
can be None.
name = ‘opt.fmin_sd’
class sfepy.solvers.optimize.ScipyFMinSolver(conf, **kwargs)
Interface to SciPy optimization solvers scipy.optimize.fmin_*.
Kind: ‘nls.scipy_fmin_like’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters method : {‘fmin’, ‘fmin_bfgs’, ‘fmin_cg’, ‘fmin_cobyla’, ‘fmin_l_bfgs_b’,
‘fmin_ncg’, ‘fmin_powell’, ‘fmin_slsqp’, ‘fmin_tnc’} (default: ‘fmin’)
The actual optimization method to use.
i_max : int (default: 10)
The maximum number of iterations.
*:*
Additional parameters supported by the method.
name = ‘nls.scipy_fmin_like’
set_method(conf )
sfepy.solvers.optimize.check_gradient(xit, aofg, fn_of, delta, check)
sfepy.solvers.optimize.conv_test(conf, it, of, of0, ofg_norm=None)
Returns flag : int
• -1 ... continue
• 0 ... small OF -> stop
• 1 ... i_max reached -> stop
• 2 ... small OFG -> stop
• 3 ... small relative decrase of OF
sfepy.solvers.optimize.wrap_function(function, args)
sfepy.solvers.oseen module
class sfepy.solvers.oseen.Oseen(conf, problem, **kwargs)
The Oseen solver for Navier-Stokes equations.
Kind: ‘nls.oseen’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters stabil_mat : str
The name of stabilization material.
adimensionalize : bool (default: False)
564
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
If True, adimensionalize the problem (not implemented!).
check_navier_stokes_rezidual : bool (default: False)
If True, check the Navier-Stokes rezidual after the nonlinear loop.
i_max : int (default: 1)
The maximum number of iterations.
eps_a : float (default: 1e-10)
The absolute tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||.
eps_r : float (default: 1.0)
The relative tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥0 )||.
macheps : float (default: 2.2204460492503131e-16)
The float considered to be machine “zero”.
lin_red : float (default: 1.0)
The linear system solution error should be smaller than (eps_a * lin_red), otherwise a
warning is printed.
lin_precision : float or None
If not None, the linear system solution tolerances are set in each nonlinear iteration
relative to the current residual norm by the lin_precision factor. Ignored for direct linear
solvers.
name = ‘nls.oseen’
class sfepy.solvers.oseen.StabilizationFunction(name_map, gamma=None, delta=None,
tau=None, tau_red=1.0, tau_mul=1.0,
delta_mul=1.0, gamma_mul=1.0, diameter_mode=’max’)
Definition of stabilization material function for the Oseen solver.
Notes
•tau_red <= 1.0; if tau is None: tau = tau_red * delta
•diameter mode: ‘edge’: longest edge ‘volume’: volume-based, ‘max’: max. of previous
get_maps()
Get the maps of names and indices of variables in state vector.
setup(problem)
Setup common problem-dependent data.
sfepy.solvers.oseen.are_close(a, b, rtol=0.2, atol=1e-08)
sfepy.solvers.oseen.scale_matrix(mtx, indx, factor)
sfepy.solvers.petsc_worker module
PETSc solver worker process.
sfepy.solvers.petsc_worker.solve()
7.8. Module Index
565
SfePy Documentation, Release 2015.1
sfepy.solvers.semismooth_newton module
class sfepy.solvers.semismooth_newton.SemismoothNewton(conf, **kwargs)
The semi-smooth Newton method for solving problems of the following structure:
𝐹 (𝑦) = 0
𝐴(𝑦) ≥ 0 , 𝐵(𝑦) ≥ 0 , ⟨𝐴(𝑦), 𝐵(𝑦)⟩ = 0
The function 𝐹 (𝑦) represents the smooth part of the problem.
Regular step: 𝑦 ← 𝑦 − 𝐽(𝑦)−1 Φ(𝑦)
Steepest descent step: 𝑦 ← 𝑦 − 𝛽𝐽(𝑦)Φ(𝑦)
Although fun_smooth_grad() computes the gradient of the smooth part only, it should return the global
matrix, where the non-smooth part is uninitialized, but pre-allocated.
Kind: ‘nls.semismooth_newton’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters semismooth : bool (default: True)
If True, use the semi-smooth algorithm. Otherwise a non-smooth equation is assumed
(use a brute force).
i_max : int (default: 1)
The maximum number of iterations.
eps_a : float (default: 1e-10)
The absolute tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||.
eps_r : float (default: 1.0)
The relative tolerance for the residual, i.e. ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥0 )||.
macheps : float (default: 2.2204460492503131e-16)
The float considered to be machine “zero”.
lin_red : float (default: 1.0)
The linear system solution error should be smaller than (eps_a * lin_red), otherwise a
warning is printed.
ls_on : float (default: 0.99999)
Start the backtracking line-search by reducing the step, if ||𝑓 (𝑥𝑖 )||/||𝑓 (𝑥𝑖−1 )|| is larger
than ls_on.
ls_red : 0.0 < float < 1.0 (default: 0.1)
The step reduction factor in case of correct residual assembling.
ls_red_warp : 0.0 < float < 1.0 (default: 0.001)
The step reduction factor in case of failed residual assembling (e.g. the “warp violation”
error caused by a negative volume element resulting from too large deformations).
ls_min : 0.0 < float < 1.0 (default: 1e-05)
The minimum step reduction factor.
566
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
compute_jacobian(vec_x, fun_smooth_grad, fun_a_grad, fun_b_grad, vec_smooth_r, vec_a_r,
vec_b_r)
name = ‘nls.semismooth_newton’
sfepy.solvers.solvers module
Base (abstract) solver classes.
class sfepy.solvers.solvers.EigenvalueSolver(conf,
mtx_a=None,
mtx_b=None,
n_eigs=None,
eigenvectors=None,
status=None)
Abstract eigenvalue solver class.
class sfepy.solvers.solvers.LinearSolver(conf, mtx=None, status=None, **kwargs)
Abstract linear solver class.
get_tolerance()
Return tuple (eps_a, eps_r) of absolute and relative tolerance settings. Either value can be None, meaning
that the solver does not use that setting.
class sfepy.solvers.solvers.NonlinearSolver(conf,
fun=None,
fun_grad=None,
lin_solver=None,
iter_hook=None,
status=None, **kwargs)
Abstract nonlinear solver class.
class sfepy.solvers.solvers.OptimizationSolver(conf, obj_fun=None, obj_fun_grad=None,
status=None, obj_args=None, **kwargs)
Abstract optimization solver class.
class sfepy.solvers.solvers.Solver(conf=None, **kwargs)
Base class for all solver kinds. Takes care of processing of common configuration options.
The factory method any_from_conf() can be used to create an instance of any subclass.
The subclasses have to reimplement __init__() and __call__().
All solvers use the following configuration parameters:
Parameters name : str
The name referred to in problem description options.
kind : str
The solver kind, as given by the name class attribute of the Solver subclasses.
verbose : bool (default: False)
If True, the solver can print more information about the solution.
static any_from_conf(conf, **kwargs)
Create an instance of a solver class according to the configuration.
build_solver_kwargs(conf )
Build the kwargs dict for the underlying solver function using the extra options (marked by ‘*’ in
_parameters) in conf. The declared parameters are omitted.
classmethod process_conf(conf, kwargs)
Process configuration parameters.
class sfepy.solvers.solvers.SolverMeta
Metaclass for solver classes that automatically adds configuration parameters to the solver class docstring from
the _parameters class attribute.
7.8. Module Index
567
SfePy Documentation, Release 2015.1
class sfepy.solvers.solvers.TimeSteppingSolver(conf, **kwargs)
Abstract time stepping solver class.
sfepy.solvers.solvers.format_next(text, new_text, pos, can_newline, width, ispaces)
sfepy.solvers.solvers.make_get_conf(conf, kwargs)
sfepy.solvers.solvers.make_option_docstring(name, kind, default, required, doc)
sfepy.solvers.solvers.typeset_to_indent(txt, indent, width)
sfepy.solvers.ts module
class sfepy.solvers.ts.TimeStepper(t0,
t1,
dt=None,
is_quasistatic=False)
Time stepper class.
n_step=None,
step=None,
static from_conf(conf )
iter_from(step)
normalize_time()
set_from_data(t0, t1, dt=None, n_step=None, step=None)
set_from_ts(ts, step=None)
set_step(step=0, nt=0.0)
class sfepy.solvers.ts.VariableTimeStepper(t0, t1, dt=None, n_step=None, step=None,
is_quasistatic=False)
Time stepper class with a variable time step.
static from_conf(conf )
get_default_time_step()
set_from_data(t0, t1, dt=None, n_step=None, step=None)
set_from_ts(ts, step=None)
set_n_digit_from_min_dt(dt)
set_step(step=0, nt=0.0)
set_time_step(dt, update_time=False)
sfepy.solvers.ts.get_print_info(n_step)
sfepy.solvers.ts_solvers module
Time stepping solvers.
class sfepy.solvers.ts_solvers.AdaptiveTimeSteppingSolver(conf, **kwargs)
Implicit time stepping solver with an adaptive time step.
Either the built-in or user supplied function can be used to adapt the time step.
Kind: ‘ts.adaptive’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters t0 : float (default: 0.0)
568
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
The initial time.
t1 : float (default: 1.0)
The final time.
dt : float
The time step. Used if n_step is not given.
n_step : int (default: 10)
The number of time steps. Has precedence over dt.
quasistatic : bool (default: False)
If True, assume a quasistatic time-stepping. Then the non-linear solver is invoked also
for the initial time.
adapt_fun : callable(ts, status, adt, problem)
If given, use this function to set the time step in ts. The function return value is a bool
- if True, the adaptivity loop should stop. The other parameters below are collected in
adt, status is the nonlinear solver status and problem is the Problem instance.
dt_red_factor : float (default: 0.2)
The time step reduction factor.
dt_red_max : float (default: 0.001)
The maximum time step reduction factor.
dt_inc_factor : float (default: 1.25)
The time step increase factor.
dt_inc_on_iter : int (default: 4)
Increase the time step if the nonlinear solver converged in less than this amount of
iterations for dt_inc_wait consecutive time steps.
dt_inc_wait : int (default: 5)
The number of consecutive time steps, see dt_inc_on_iter.
name = ‘ts.adaptive’
solve_step(ts, state0, nls_status=None)
Solve a single time step.
class sfepy.solvers.ts_solvers.EquationSequenceSolver(conf, **kwargs)
Solver for stationary problems with an equation sequence.
Kind: ‘ts.equation_sequence’
For common configuration parameters, see Solver.
Specific configuration parameters:
name = ‘ts.equation_sequence’
class sfepy.solvers.ts_solvers.ExplicitTimeSteppingSolver(conf, **kwargs)
Explicit time stepping solver with a fixed time step.
Kind: ‘ts.explicit’
For common configuration parameters, see Solver.
7.8. Module Index
569
SfePy Documentation, Release 2015.1
Specific configuration parameters:
Parameters t0 : float (default: 0.0)
The initial time.
t1 : float (default: 1.0)
The final time.
dt : float
The time step. Used if n_step is not given.
n_step : int (default: 10)
The number of time steps. Has precedence over dt.
quasistatic : bool (default: False)
If True, assume a quasistatic time-stepping. Then the non-linear solver is invoked also
for the initial time.
mass : term
The term for assembling the mass matrix.
lump : bool (default: False)
If True, use the lumped mass matrix.
name = ‘ts.explicit’
solve_step(ts, state0, nls_status=None)
Solve a single time step.
class sfepy.solvers.ts_solvers.SimpleTimeSteppingSolver(conf, **kwargs)
Implicit time stepping solver with a fixed time step.
Kind: ‘ts.simple’
For common configuration parameters, see Solver.
Specific configuration parameters:
Parameters t0 : float (default: 0.0)
The initial time.
t1 : float (default: 1.0)
The final time.
dt : float
The time step. Used if n_step is not given.
n_step : int (default: 10)
The number of time steps. Has precedence over dt.
quasistatic : bool (default: False)
If True, assume a quasistatic time-stepping. Then the non-linear solver is invoked also
for the initial time.
name = ‘ts.simple’
solve_step(ts, state0, nls_status=None)
Solve a single time step.
570
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
class sfepy.solvers.ts_solvers.StationarySolver(conf, **kwargs)
Solver for stationary problems without time stepping.
This class is provided to have a unified interface of the time stepping solvers also for stationary problems.
Kind: ‘ts.stationary’
For common configuration parameters, see Solver.
Specific configuration parameters:
name = ‘ts.stationary’
sfepy.solvers.ts_solvers.adapt_time_step(ts, status, adt, problem=None)
Adapt the time step of ts according to the exit status of the nonlinear solver.
The time step dt is reduced, if the nonlinear solver did not converge. If it converged in less then a specified number of iterations for several time steps, the time step is increased. This is governed by the following parameters:
•red_factor : time step reduction factor
•red_max : maximum time step reduction factor
•inc_factor : time step increase factor
•inc_on_iter : increase time step if the nonlinear solver converged in less than this amount of iterations...
•inc_wait : ...for this number of consecutive time steps
Parameters ts : VariableTimeStepper instance
The time stepper.
status : IndexedStruct instance
The nonlinear solver exit status.
adt : Struct instance
The adaptivity parameters of the time solver:
problem : Problem instance, optional
This canbe used in user-defined adaptivity functions. Not used here.
Returns is_break : bool
If True, the adaptivity loop should stop.
sfepy.solvers.ts_solvers.get_initial_state(problem)
Create a zero state vector and apply initial conditions.
sfepy.solvers.ts_solvers.get_min_dt(adt)
sfepy.solvers.ts_solvers.make_explicit_step(ts, state0, problem, mass, nls_status=None)
Make a step of an explicit time stepping solver.
sfepy.solvers.ts_solvers.make_implicit_step(ts, state0, problem, nls_status=None)
Make a step of an implicit time stepping solver.
sfepy.solvers.ts_solvers.prepare_matrix(problem, state)
Pre-assemble tangent system matrix.
sfepy.solvers.ts_solvers.prepare_save_data(ts, conf )
Given a time stepper configuration, return a list of time steps when the state should be saved.
sfepy.solvers.ts_solvers.replace_virtuals(deps, pairs)
7.8. Module Index
571
SfePy Documentation, Release 2015.1
7.8.15 sfepy.terms package
Term Overview
Term Syntax
In general, the syntax of a term call is:
<term name>.<i>.<r>( <arg1>, <arg2>, ...
),
where <i> denotes an integral name (i.e. a name of numerical quadrature to use) and <r> marks a region (domain of
the integral).
The following notation is used:
Table 7.3: Notation.
symbol
Ω
Γ
𝑑
𝑡
𝑦
𝑦
𝑛
𝑞, 𝑠
𝑝, 𝑟
𝑝¯
𝑣
𝑤, 𝑢
𝑏
𝑒(𝑢)
𝐹
𝐽
𝐶
𝐸(𝑢)
𝑆
𝑓
𝑓
𝜌
𝜈
𝑐
𝛿𝑖𝑗 , 𝐼
tr ∙
dev ∙
𝑇𝐾 ∈ 𝒯ℎ
𝐾 ← ℐℎ
meaning
volume (sub)domain
surface (sub)domain
dimension of space
time
any function
any vector function
unit outward normal
scalar test function
scalar unknown or parameter function
scalar parameter function
vector test function
vector unknown or parameter function
vector parameter function
Cauchy strain tensor ( 12 ((∇𝑢) + (∇𝑢)𝑇 ))
𝜕𝑥𝑖
deformation gradient 𝐹𝑖𝑗 = 𝜕𝑋
𝑗
det(𝐹 )
right Cauchy-Green deformation tensor 𝐶 = 𝐹 𝑇 𝐹
𝜕𝑢
𝜕𝑢𝑖
𝑚 𝜕𝑢𝑚
Green strain tensor 𝐸𝑖𝑗 = 12 ( 𝜕𝑥
+ 𝜕𝑥𝑗𝑖 + 𝜕𝑢
𝜕𝑥𝑖 𝜕𝑥𝑗 )
𝑗
second Piola-Kirchhoff stress tensor
vector volume forces
scalar volume force (source)
density
kinematic viscosity
any constant
Kronecker delta, identity matrix
∑︀𝑑
trace of a second order tensor ( 𝑖=1 ∙𝑖𝑖 )
deviator of a second order tensor (∙ − 𝑑1 tr ∙)
𝐾-th element of triangulation (= mesh) 𝒯ℎ of domain Ω
𝐾 is assigned values from {0, 1, . . . , 𝑁ℎ − 1} ≡ ℐℎ in ascending order
The suffix “0 ” denotes a quantity related to a previous time step.
Term names are (usually) prefixed according to the following conventions:
572
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.4: Term name prefixes.
prefix
dw
d
di
dq
ev
meaning
discrete
weak
discrete
discrete
integrated
discrete
quadrature
evaluate
evaluation
modes
‘weak’
‘eval’
‘eval’
‘qp’
‘eval’,
‘el_avg’,
‘qp’
meaning
terms having a virtual (test) argument and zero or more unknown arguments,
used for FE assembling
terms having all arguments known, the result is the scalar value of the integral
like ‘d’ but the result is not a scalar (e.g. a vector)
terms having all arguments known, the result are the values in quadrature
points of elements
terms having all arguments known and supporting all evaluation modes except
‘weak’ (no virtual variables in arguments, no FE assembling)
Term Table
Below we list all the terms available in an automatically generated table. The first column lists the name, the second
column the argument lists and the third column the mathematical definition of each term.
The notation <virtual> corresponds to a test function, <state> to a unknown function and <parameter> to a
known function. By <material> we denote material (constitutive) parameters, or, in general, any given function of
space and time that parameterizes a term, for example a given traction force vector.
Table 7.5: Table of all terms.
name/class
dw_adj_convect1
AdjConvect1Term
arguments
<virtual>,
<state>,
<parameter>
definition
∫︁
((𝑣 · ∇)𝑢) · 𝑤
Ω
dw_adj_convect2
AdjConvect2Term
<virtual>,
<state>,
<parameter>
∫︁
((𝑢 · ∇)𝑣) · 𝑤
Ω
dw_adj_div_grad
AdjDivGradTerm
dw_bc_newton
BCNewtonTerm
<material_1>,
<material_2>,
<virtual>,
<parameter>
<material_1>,
<material_2>,
<virtual>,
<state>
𝑤𝛿𝑢 Ψ(𝑢) ∘ 𝑣
∫︁
𝛼𝑞(𝑝 − 𝑝outer )
Γ
Continued on next page
7.8. Module Index
573
SfePy Documentation, Release 2015.1
name/class
dw_biot
BiotTerm
dw_biot_eth
BiotETHTerm
ev_biot_stress
BiotStressTerm
Table 7.5 – continued from previous page
arguments
definition
<material>,
∫︁
∫︁
<virtual>,
<state>
𝑝 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) ,
𝑞 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑢)
Ω
Ω
<material>,
<state>,
<virtual>
<material>,
<parameter_v>,
<parameter_s>
<ts>,
]︁
<material_0>,
∫︀ [︁∫︀ 𝑡
𝛼 (𝑡 − 𝜏 ) 𝑝(𝜏 )) d𝜏 𝑒𝑖𝑗 (𝑣) ,
<material_1>,
Ω [︁ 0 𝑖𝑗
]︁
∫︀ ∫︀ 𝑡
<virtual>,
𝛼
(𝑡
−
𝜏
)𝑒
(𝑢(𝜏
))
d𝜏
𝑞
𝑖𝑗
𝑘𝑙
Ω
0
<state>
<ts>,
<material_0>,
<material_1>,
<state>,
<virtual>
<material>,
∫︁
<parameter>
−
𝛼𝑖𝑗 𝑝¯
Ω
∫︁
∫︁
vector for 𝐾 ← ℐℎ : −
1
𝛼𝑖𝑗 𝑝¯/
𝑇𝐾
𝑇𝐾
−𝛼𝑖𝑗 𝑝¯|𝑞𝑝
dw_biot_th
BiotTHTerm
ev_cauchy_strain
CauchyStrainTerm
<ts>,
<material>,
<virtual>,
<state>
<ts>,
<material>,
<state>,
<virtual>
<parameter>
]︁
∫︀ [︁∫︀ 𝑡
𝛼
(𝑡
−
𝜏
)
𝑝(𝜏
))
d𝜏
𝑒𝑖𝑗 (𝑣) ,
𝑖𝑗
Ω
0
]︁
∫︀ [︁∫︀ 𝑡
𝛼 (𝑡 − 𝜏 )𝑒𝑘𝑙 (𝑢(𝜏 )) d𝜏 𝑞
Ω
0 𝑖𝑗
∫︁
𝑒(𝑤)
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑒(𝑤)/
𝑇𝐾
1
𝑇𝐾
𝑒(𝑤)|𝑞𝑝
Continued on next page
574
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
ev_cauchy_strain_s
<parameter>
∫︁
CauchyStrainSTerm
𝑒(𝑤)
Γ
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑒(𝑤)/
𝑇𝐾
1
𝑇𝐾
𝑒(𝑤)|𝑞𝑝
ev_cauchy_stress
CauchyStressTerm
<material>,
<parameter>
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑘𝑙 (𝑤)
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑘𝑙 (𝑤)/
𝑇𝐾
1
𝑇𝐾
𝐷𝑖𝑗𝑘𝑙 𝑒𝑘𝑙 (𝑤)|𝑞𝑝
ev_cauchy_stress_eth
<ts>,
CauchyStressETHTerm
<material_0>,
<material_1>,
<parameter>
∫︁ ∫︁
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏
Ω
0
∫︁
∫︁
𝑡
vector for 𝐾 ← ℐℎ :
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 /
𝑇𝐾
∫︁
∫︁
1
𝑇𝐾
0
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 |𝑞𝑝
0
ev_cauchy_stress_th
<ts>,
CauchyStressTHTerm<material>,
<parameter>
∫︁ ∫︁
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏
Ω
0
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 /
𝑇𝐾
∫︁
𝑡
0
1
𝑇𝐾
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 |𝑞𝑝
0
Continued on next page
7.8. Module Index
575
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
arguments
definition
<material_f>,
∫︁
<material_n>,
<material_a>,
𝑣 · 𝑓 (𝑑(𝑢))𝑛
Γ
<material_b>,
<virtual>,
<state>
dw_contact_sphere
<material_f>,
∫︁
ContactSphereTerm <material_c>,
<material_r>,
𝑣 · 𝑓 (𝑑(𝑢))𝑛(𝑢)
Γ
<virtual>,
<state>
dw_convect
<virtual>,
∫︁
ConvectTerm
<state>
((𝑢 · ∇)𝑢) · 𝑣
name/class
dw_contact_plane
ContactPlaneTerm
Ω
dw_convect_v_grad_s
<virtual>,
ConvectVGradSTerm <state_v>,
<state_s>
∫︁
𝑞(𝑢 · ∇𝑝)
Ω
ev_def_grad
<parameter>
DeformationGradientTerm
𝜕𝑥
𝜕𝑢
|𝑞𝑝 = 𝐼 +
|𝑞𝑝 ,
𝜕𝑋
𝜕𝑋
𝑥 = 𝑋 + 𝑢 , 𝐽 = det (𝐹 )
𝐹 =
dw_diffusion
DiffusionTerm
<material>,
<virtual>,
<state>
<material>,
<parameter_1>,
<parameter_2>
dw_diffusion_coupling <material>,
DiffusionCoupling <virtual>,
<state>
<material>,
<state>,
<virtual>
<material>,
<parameter_1>,
<parameter_2>
dw_diffusion_r
<material>,
DiffusionRTerm
<virtual>
∫︁
∫︁
𝐾𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 ,
Ω
𝐾𝑖𝑗 ∇𝑖 𝑝¯∇𝑗 𝑟
Ω
∫︁
𝑝𝐾𝑗 ∇𝑗 𝑞
Ω
∫︁
𝐾𝑗 ∇𝑗 𝑞
Ω
Continued on next page
576
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
name/class
d_diffusion_sa
DiffusionSATerm
Table 7.5 – continued from previous page
arguments
definition
<material>,
∫︁
<parameter_q>,
<parameter_p>,
[(div 𝒱)𝐾𝑖𝑗 ∇𝑖 𝑞 ∇𝑗 𝑝 − 𝐾𝑖𝑗 (∇𝑗 𝒱∇𝑞)∇𝑖 𝑝 − 𝐾𝑖𝑗 ∇𝑗 𝑞(∇𝑖 𝒱∇𝑝)]
Ω
<parameter_v>
ev_diffusion_velocity
<material>,
DiffusionVelocityTerm
<parameter>
∫︁
−
𝐾𝑖𝑗 ∇𝑗 𝑝¯
Ω
∫︁
∫︁
vector for 𝐾 ← ℐℎ : −
𝐾𝑖𝑗 ∇𝑗 𝑝¯/
𝑇𝐾
1
𝑇𝐾
−𝐾𝑖𝑗 ∇𝑗 𝑝¯
dw_div
DivOperatorTerm
<opt_material>,
<virtual>
∫︁
∫︁
∇ · 𝑣 or
Ω
ev_div
DivTerm
𝑐∇ · 𝑣
Ω
<parameter>
∫︁
∇·𝑢
Ω
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
∇ · 𝑢/
𝑇𝐾
1
𝑇𝐾
(∇ · 𝑢)|𝑞𝑝
dw_div_grad
DivGradTerm
<opt_material>,
<virtual>,
<state>
<opt_material>,
<parameter_1>,
<parameter_2>
dw_electric_source
<material>,
ElectricSourceTerm<virtual>,
<parameter>
∫︁
∫︁
𝜈 ∇𝑣 : ∇𝑢 ,
𝜈 ∇𝑢 : ∇𝑤
Ω
Ω
∫︁
∫︁
∇𝑣 : ∇𝑢 ,
∇𝑢 : ∇𝑤
Ω
Ω
∫︁
𝑐𝑠(∇𝜑)2
Ω
Continued on next page
7.8. Module Index
577
SfePy Documentation, Release 2015.1
name/class
ev_grad
GradTerm
Table 7.5 – continued from previous page
arguments
definition
<parameter>
∫︁
∫︁
∇𝑝 or
∇𝑤
Ω
Ω
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
∇𝑝/
∇𝑤/
1 or
𝑇𝐾
∫︁
∫︁
𝑇𝐾
1
𝑇𝐾
𝑇𝐾
(∇𝑝)|𝑞𝑝 or ∇𝑤|𝑞𝑝
ev_integrate_mat
IntegrateMatTerm
<material>,
<parameter>
∫︁
𝑚
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑚/
𝑇𝐾
1
𝑇𝐾
𝑚|𝑞𝑝
dw_jump
SurfaceJumpTerm
<opt_material>,
<virtual>,
<state_1>,
<state_2>
dw_laplace
LaplaceTerm
<opt_material>,
<virtual>,
<state>
<opt_material>,
<parameter_1>,
<parameter_2>
dw_lin_convect
<virtual>,
LinearConvectTerm <parameter>,
<state>
∫︁
𝑐 𝑞(𝑝1 − 𝑝2 )
Γ
∫︁
∫︁
𝑐∇𝑞 · ∇𝑝 ,
Ω
𝑐∇¯
𝑝 · ∇𝑟
Ω
∫︁
((𝑏 · ∇)𝑢) · 𝑣
Ω
((𝑏 · ∇)𝑢)|𝑞𝑝
dw_lin_elastic
<material>,
LinearElasticTerm <virtual>,
<state>
<material>,
<parameter_1>,
<parameter_2>
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢)
Ω
Continued on next page
578
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_lin_elastic_eth
<ts>,
LinearElasticETHTerm
<material_0>,
]︂
∫︁ [︂∫︁ 𝑡
<material_1>,
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑢(𝜏 )) d𝜏 𝑒𝑖𝑗 (𝑣)
0
Ω
<virtual>,
<state>
dw_lin_elastic_iso
<material_1>,
∫︁
LinearElasticIsotropicTerm
<material_2>,
<virtual>,
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢) with 𝐷𝑖𝑗𝑘𝑙 = 𝜇(𝛿𝑖𝑘 𝛿𝑗𝑙 + 𝛿𝑖𝑙 𝛿𝑗𝑘 ) + 𝜆 𝛿𝑖𝑗 𝛿𝑘𝑙
Ω
<state>
dw_lin_elastic_th
<ts>,
LinearElasticTHTerm
<material>,
<virtual>,
<state>
∫︁ [︂∫︁
Ω
𝑡
]︂
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑢(𝜏 )) d𝜏 𝑒𝑖𝑗 (𝑣)
0
dw_lin_prestress
<material>,
LinearPrestressTerm
<virtual>
<material>,
<parameter>
dw_lin_strain_fib
<material_1>,
LinearStrainFiberTerm
<material_2>,
<virtual>
∫︁
𝜎𝑖𝑗 𝑒𝑖𝑗 (𝑣)
Ω
∫︁
𝐷𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣) (𝑑𝑘 𝑑𝑙 )
Ω
dw_new_diffusion
NewDiffusionTerm
<material>,
<virtual>,
<state>
dw_new_lin_elastic
<material>,
NewLinearElasticTerm
<virtual>,
<state>
dw_new_mass
<virtual>,
NewMassTerm
<state>
dw_new_mass_scalar
<virtual>,
NewMassScalarTerm <state>
dw_non_penetration
<opt_material>,
NonPenetrationTerm<virtual>,
<state>
<opt_material>,
<state>,
<virtual>
d_of_ns_surf_min_d_press<material_1>,
NSOFSurfMinDPressTerm
<material_2>,
<parameter>
∫︁
∫︁
ˆ ·𝑢
𝑐𝜆𝑛 · 𝑣 ,
𝑐𝜆𝑛
Γ
∫︁
∫︁
ˆ ·𝑢
𝜆𝑛 · 𝑣 ,
𝜆𝑛
Γ
Γ
Γ
(︂∫︁
)︂
𝑏𝑝𝑟𝑒𝑠𝑠
∫︁
𝑝−
𝛿Ψ(𝑝) = 𝛿
Γ𝑖𝑛
Γ𝑜𝑢𝑡
Continued on next page
7.8. Module Index
579
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_of_ns_surf_min_d_press_diff
<material>,
NSOFSurfMinDPressDiffTerm
<virtual>
𝑤𝛿𝑝 Ψ(𝑝) ∘ 𝑞
dw_piezo_coupling
<material>,
PiezoCouplingTerm <virtual>,
<state>
<material>,
<state>,
<virtual>
<material>,
<parameter_v>,
<parameter_s>
dw_point_load
<material>,
ConcentratedPointLoadTerm
<virtual>
∫︁
∫︁
𝑔𝑘𝑖𝑗 𝑒𝑖𝑗 (𝑣)∇𝑘 𝑝 ,
Ω
𝑖
𝑓 𝑖 = 𝑓¯
dw_point_lspring
<material>,
LinearPointSpringTerm
<virtual>,
<state>
𝑔𝑘𝑖𝑗 𝑒𝑖𝑗 (𝑢)∇𝑘 𝑞
Ω
𝑓 𝑖 = −𝑘𝑢𝑖
dw_s_dot_grad_i_s
<material>,
ScalarDotGradIScalarTerm
<virtual>,
<state>
∀ FE node 𝑖 in a region
∀ FE node 𝑖 in a region
𝑍𝑖 =
∫︁
𝑞∇𝑖 𝑝
Ω
d_sd_convect
SDConvectTerm
<parameter_u>,
<parameter_w>,
<parameter_mesh_velocity>
∫︁
[𝑢𝑘
Ω𝐷
d_sd_div
SDDivTerm
<parameter_u>,
<parameter_p>,
<parameter_mesh_velocity>
∫︁
𝑝[(∇ · 𝑤)(∇ · 𝒱) −
Ω𝐷
d_sd_div_grad
SDDivGradTerm
580
𝜕𝑢𝑖
𝜕𝒱𝑗 𝜕𝑢𝑖
𝑤𝑖 (∇ · 𝒱) − 𝑢𝑘
𝑤𝑖 ]
𝜕𝑥𝑘
𝜕𝑥𝑘 𝜕𝑥𝑗
𝜕𝒱𝑘 𝜕𝑤𝑖
]
𝜕𝑥𝑖 𝜕𝑥𝑘
<material_1>,
∫︁
<material_2>,
𝜕𝑢𝑖 𝜕𝑤𝑖
𝜕𝒱𝑗 𝜕𝑢𝑖 𝜕𝑤𝑖
𝜕𝑢𝑖 𝜕𝒱𝑙 𝜕𝑤𝑖
<parameter_u>,
𝑤𝜈
[
(∇ · 𝒱) −
−
]
𝜕𝑥
𝜕𝑥
𝜕𝑥
𝜕𝑥
𝜕𝑥
𝜕𝑥
𝑘
𝑘
𝑘
𝑗
𝑘
𝑘 𝜕𝑥𝑘 𝜕𝑥𝑘
Ω𝐷
<parameter_w>,
<parameter_mesh_velocity>
Continued on next page
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
d_sd_lin_elastic
<material>,
∫︁
SDLinearElasticTerm
<parameter_w>,
ˆ 𝑖𝑗𝑘𝑙 𝑒𝑖𝑗 (𝑣)𝑒𝑘𝑙 (𝑢)
<parameter_u>,
𝐷
Ω
<parameter_mesh_velocity>
ˆ 𝑖𝑗𝑘𝑙 = 𝐷𝑖𝑗𝑘𝑙 (∇ · 𝒱) − 𝐷𝑖𝑗𝑘𝑞 𝜕𝒱𝑙 − 𝐷𝑖𝑞𝑘𝑙 𝜕𝒱𝑗
𝐷
𝜕𝑥𝑞
𝜕𝑥𝑞
d_sd_st_grad_div
<material>,
∫︁
SDGradDivStabilizationTerm
<parameter_u>,
𝜕𝑢𝑖 𝜕𝒱𝑘
𝜕𝑤𝑖 𝜕𝒱𝑘
<parameter_w>,
𝛾
[(∇ · 𝑢)(∇ · 𝑤)(∇ · 𝒱) −
(∇ · 𝑤) − (∇ · 𝑢)
]
𝜕𝑥
𝜕𝑥
𝜕𝑥
𝑘
𝑖
𝑘 𝜕𝑥𝑖
Ω𝐷
<parameter_mesh_velocity>
d_sd_st_pspg_c
<material>,
SDPSPGCStabilizationTerm
<parameter_b>,
∑︁ ∫︁
<parameter_u>,
𝛿𝐾
<parameter_r>,
𝐾∈ℐℎ 𝑇𝐾
<parameter_mesh_velocity>
d_sd_st_pspg_p
<material>,
SDPSPGPStabilizationTerm
<parameter_r>,
∑︁ ∫︁
<parameter_p>,
𝜏𝐾
<parameter_mesh_velocity>
𝐾∈ℐℎ 𝑇𝐾
[
𝜕𝑟 𝜕𝒱𝑘
𝜕𝑟
𝜕𝑢𝑖
𝜕𝑟
(𝑏 · ∇𝑢𝑖 )(∇ · 𝒱) −
(𝑏 · ∇𝑢𝑖 ) −
(𝑏 · ∇𝒱𝑘 )
]
𝜕𝑥𝑖
𝜕𝑥𝑘 𝜕𝑥𝑖
𝜕𝑥𝑘
𝜕𝑥𝑘
𝜕𝑟
𝜕𝑝
(∇𝒱𝑘 · ∇𝑝) − (∇𝑟 · ∇𝒱𝑘 )
]
𝜕𝑥𝑘
𝜕𝑥𝑘
[(∇𝑟 · ∇𝑝)(∇ · 𝒱) −
d_sd_st_supg_c
<material>,
SDSUPGCStabilizationTerm
<parameter_b>,
∑︁ ∫︁
𝜕𝑢𝑘
<parameter_u>,
𝛿𝐾 [(𝑏 · ∇𝑢𝑘 )(𝑏 · ∇𝑤𝑘 )(∇ · 𝒱) − (𝑏 · ∇𝒱𝑖 )
(𝑏 · ∇𝑤𝑘 ) − (𝑢 · ∇𝑢𝑘
𝜕𝑥𝑖
<parameter_w>,
𝐾∈ℐℎ 𝑇𝐾
<parameter_mesh_velocity>
d_sd_surface_integrate <parameter>,
∫︁
SDSufaceIntegrateTerm
<parameter_mesh_velocity>
𝑝∇ · 𝒱
Γ
d_sd_volume_dot
SDDotVolumeTerm
<parameter_1>,
<parameter_2>,
<parameter_mesh_velocity>
∫︁
∫︁
𝑝𝑞(∇ · 𝒱) ,
Ω𝐷
dw_st_adj1_supg_p
<material>,
SUPGPAdj1StabilizationTerm
<virtual>,
<state>,
<parameter>
dw_st_adj2_supg_p
<material>,
SUPGPAdj2StabilizationTerm
<virtual>,
<parameter>,
<state>
(𝑢 · 𝑤)(∇ · 𝒱)
Ω𝐷
∑︁ ∫︁
𝐾∈ℐℎ
𝛿𝐾 ∇𝑝(𝑣 · ∇𝑤)
𝑇𝐾
∑︁ ∫︁
𝐾∈ℐℎ
𝜏𝐾 ∇𝑟(𝑣 · ∇𝑢)
𝑇𝐾
Continued on next page
7.8. Module Index
581
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_st_adj_supg_c
<material>,
SUPGCAdjStabilizationTerm
<virtual>,
∑︁ ∫︁
<parameter>,
𝛿𝐾 [((𝑣 · ∇)𝑢)((𝑢 · ∇)𝑤) + ((𝑢 · ∇)𝑢)((𝑣 · ∇)𝑤)]
<state>
𝐾∈ℐℎ 𝑇𝐾
dw_st_grad_div
<material>,
GradDivStabilizationTerm
<virtual>,
<state>
∫︁
(∇ · 𝑢) · (∇ · 𝑣)
𝛾
Ω
dw_st_pspg_c
<material>,
PSPGCStabilizationTerm
<virtual>,
<parameter>,
<state>
∑︁ ∫︁
𝐾∈ℐℎ
dw_st_pspg_p
<opt_material>,
PSPGPStabilizationTerm
<virtual>,
<state>
<opt_material>,
<parameter_1>,
<parameter_2>
dw_st_supg_c
<material>,
SUPGCStabilizationTerm
<virtual>,
<parameter>,
<state>
∑︁ ∫︁
𝐾∈ℐℎ
∑︁ ∫︁
<opt_material>,
<virtual>,
<state>
<opt_material>,
<state>,
<virtual>
<opt_material>,
<parameter_v>,
<parameter_s>
d_sum_vals
<parameter>
SumNodalValuesTerm
d_surface
<parameter>
SurfaceTerm
𝛿𝐾 ((𝑏 · ∇)𝑢) · ((𝑏 · ∇)𝑣)
∑︁ ∫︁
𝐾∈ℐℎ
∫︁
𝛿𝐾 ∇𝑝 · ((𝑏 · ∇)𝑣)
𝑇𝐾
∫︁
𝑝∇·𝑣,
Ω
𝜏𝐾 ∇𝑝 · ∇𝑞
𝑇𝐾
𝑇𝐾
𝐾∈ℐℎ
dw_st_supg_p
<material>,
SUPGPStabilizationTerm
<virtual>,
<parameter>,
<state>
dw_stokes
StokesTerm
𝜏𝐾 ((𝑏 · ∇)𝑢) · ∇𝑞
𝑇𝐾
∫︁
𝑞 ∇ · 𝑢 or
∫︁
𝑐𝑝∇·𝑣,
Ω
Ω
𝑐𝑞∇·𝑢
Ω
∫︁
1
Γ
Continued on next page
582
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_surface_dot
<opt_material>,
∫︁
∫︁
∫︁
∫︁
∫︁
∫︁
∫︁
DotProductSurfaceTerm
<virtual>,
<state>
𝑞𝑝 ,
𝑣 · 𝑛𝑝 ,
𝑞𝑛 · 𝑢 ,
𝑝𝑟 ,
𝑤 · 𝑛𝑝
𝑣·𝑢,
𝑢·𝑤,
Γ
Γ
Γ
Γ
<opt_material>,
∫︁
∫︁Γ
∫︁Γ
∫︁ Γ
<parameter_1>,
𝑐𝑝𝑟 ,
𝑐𝑢 · 𝑤
𝑐𝑞𝑝 ,
𝑐𝑣 · 𝑢 ,
<parameter_2>
Γ
Γ
Γ
∫︁
∫︁ Γ
𝑣·𝑀 ·𝑢,
𝑢·𝑀 ·𝑤
Γ
d_surface_flux
SurfaceFluxTerm
<material>,
<parameter>
Γ
∫︁
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯
Γ
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯ /
𝑇𝐾
1
𝑇𝐾
∫︁
vector for 𝐾 ← ℐℎ :
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯
𝑇𝐾
dw_surface_flux
<opt_material>,
SurfaceFluxOperatorTerm
<virtual>,
<state>
∫︁
𝑞𝑛 · 𝐾 · ∇𝑝
Γ
dw_surface_integrate
<opt_material>,
IntegrateSurfaceOperatorTerm
<virtual>
∫︁
∫︁
𝑞 or
𝑐𝑞
Γ
ev_surface_integrate
<opt_material>,
IntegrateSurfaceTerm
<parameter>
Γ
∫︁
∫︁
∫︁
𝑦,
∫︁ Γ
∫︁
𝑐𝑦 ,
Γ
Γ
𝑐𝑦 · 𝑛 flux
𝑐𝑦 ,
Γ
𝑦·𝑛
𝑦,
∫︁Γ
Γ
∫︁
∫︁
∫︁
∫︁
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
𝑦/
1,
𝑦/
1,
(𝑦 · 𝑛)/
1
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
∫︁
∫︁
∫︁
∫︁
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
𝑐𝑦/
1,
𝑐𝑦/
1,
(𝑐𝑦 · 𝑛)/
1
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑦|𝑞𝑝 , 𝑦|𝑞𝑝 , (𝑦 · 𝑛)|𝑞𝑝 flux
𝑐𝑦|𝑞𝑝 , 𝑐𝑦|𝑞𝑝 , (𝑐𝑦 · 𝑛)|𝑞𝑝 flux
Continued on next page
7.8. Module Index
583
𝑇𝐾
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_surface_laplace
<material>,
∫︁
SurfaceLaplaceLayerTerm
<virtual>,
<state>
𝑐𝜕𝛼 𝑞 𝜕𝛼 𝑝, 𝛼 = 1, . . . , 𝑁 − 1
Γ
<material>,
<parameter_2>,
<parameter_1>
dw_surface_lcouple
<material>,
∫︁
∫︁
∫︁
SurfaceCoupleLayerTerm
<virtual>,
<state>
𝑐𝑞 𝜕𝛼 𝑝, 𝑐𝜕𝛼 𝑝 𝑞, 𝑐𝜕𝛼 𝑟 𝑠, 𝛼 = 1, . . . , 𝑁 − 1
Γ
Γ
Γ
<material>,
<state>,
<virtual>
<material>,
<parameter_1>,
<parameter_2>
dw_surface_ltr
<opt_material>,
∫︁
∫︁
LinearTractionTerm<virtual>
<opt_material>,
𝑣 · 𝜎 · 𝑛, 𝑣 · 𝑛,
Γ
Γ
<parameter>
di_surface_moment
<parameter>,
SurfaceMomentTerm <shift>
∫︁
𝑛(𝑥 − 𝑥0 )
Γ
dw_surface_ndot
<material>,
SufaceNormalDotTerm
<virtual>
<material>,
<parameter>
dw_tl_bulk_active
BulkActiveTLTerm
∫︁
𝑞𝑐 · 𝑛
Γ
<material>,
<virtual>,
<state>
∫︁
𝑆𝑖𝑗 (𝑢)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
dw_tl_bulk_penalty
<material>,
BulkPenaltyTLTerm <virtual>,
<state>
∫︁
𝑆𝑖𝑗 (𝑢)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
dw_tl_bulk_pressure
<virtual>,
BulkPressureTLTerm<state>,
<state_p>
∫︁
𝑆𝑖𝑗 (𝑝)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
dw_tl_diffusion
DiffusionTLTerm
<material_1>,
<material_2>,
<virtual>,
<state>,
<parameter>
∫︁
Ω
𝐾(𝑢(𝑛−1) ) :
𝜕𝑞 𝜕𝑝
𝜕𝑋 𝜕𝑋
Continued on next page
584
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_tl_fib_a
<material_1>,
∫︁
FibresActiveTLTerm<material_2>,
<material_3>,
𝑆𝑖𝑗 (𝑢)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
<material_4>,
<material_5>,
<virtual>,
<state>
dw_tl_he_mooney_rivlin <material>,
∫︁
MooneyRivlinTLTerm<virtual>,
<state>
𝑆𝑖𝑗 (𝑢)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
dw_tl_he_neohook
NeoHookeanTLTerm
<material>,
<virtual>,
<state>
∫︁
𝑆𝑖𝑗 (𝑢)𝛿𝐸𝑖𝑗 (𝑢; 𝑣)
Ω
dw_tl_membrane
TLMembraneTerm
<material_a1>,
<material_a2>,
<material_h0>,
<virtual>,
<state>
d_tl_surface_flux
<material_1>,
SurfaceFluxTLTerm <material_2>,
<parameter_1>,
<parameter_2>
∫︁
𝜈 · 𝐾(𝑢(𝑛−1) )
Γ
dw_tl_surface_traction <opt_material>,
SurfaceTractionTLTerm
<virtual>,
<state>
∫︁
𝜕𝑝
𝜕𝑋
𝜈 · 𝐹 −1 · 𝜎 · 𝑣𝐽
Γ
dw_tl_volume
VolumeTLTerm
<virtual>,
<state>
∫︀
𝑞𝐽(𝑢)
Ω
∫︀
volume mode: vector for 𝐾 ← ℐℎ : 𝑇𝐾 ∫︀𝐽(𝑢)
∫︀
rel_volume mode: vector for 𝐾 ← ℐℎ : 𝑇𝐾 𝐽(𝑢)/ 𝑇𝐾 1
d_tl_volume_surface
<parameter>
VolumeSurfaceTLTerm
∫︁
1/𝐷
𝜈 · 𝐹 −1 · 𝑥𝐽
Γ
dw_ul_bulk_penalty
<material>,
BulkPenaltyULTerm <virtual>,
<state>
∫︁
ℒ𝜏𝑖𝑗 (𝑢)𝑒𝑖𝑗 (𝛿𝑣)/𝐽
Ω
Continued on next page
7.8. Module Index
585
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_ul_bulk_pressure
<virtual>,
∫︁
BulkPressureULTerm<state>,
<state_p>
ℒ𝜏𝑖𝑗 (𝑢)𝑒𝑖𝑗 (𝛿𝑣)/𝐽
Ω
dw_ul_compressible
<material>,
CompressibilityULTerm
<virtual>,
<state>,
<parameter_u>
∫︀
1
𝛾𝑝 𝑞
Ω
dw_ul_he_mooney_rivlin <material>,
MooneyRivlinULTerm<virtual>,
<state>
∫︁
ℒ𝜏𝑖𝑗 (𝑢)𝑒𝑖𝑗 (𝛿𝑣)/𝐽
Ω
dw_ul_he_neohook
NeoHookeanULTerm
<material>,
<virtual>,
<state>
∫︁
ℒ𝜏𝑖𝑗 (𝑢)𝑒𝑖𝑗 (𝛿𝑣)/𝐽
Ω
dw_ul_volume
VolumeULTerm
<virtual>,
<state>
dw_v_dot_grad_s
<opt_material>,
VectorDotGradScalarTerm
<virtual>,
<state>
<opt_material>,
<state>,
<virtual>
<opt_material>,
<parameter_v>,
<parameter_s>
d_volume
<parameter>
VolumeTerm
∫︀
𝑞𝐽(𝑢)
Ω
∫︀
volume mode: vector for 𝐾 ← ℐℎ : 𝑇𝐾 ∫︀𝐽(𝑢)
∫︀
rel_volume mode: vector for 𝐾 ← ℐℎ : 𝑇𝐾 𝐽(𝑢)/ 𝑇𝐾 1
∫︁
∫︁
𝑣 · ∇𝑝 ,
𝑢 · ∇𝑞
∫︁ Ω
∫︁ Ω
𝑐𝑣 · ∇𝑝 ,
𝑐𝑢 · ∇𝑞
Ω
∫︁ Ω
∫︁
𝑢 · 𝑀 · ∇𝑞
𝑣 · 𝑀 · ∇𝑝 ,
Ω
Ω
∫︁
1
Ω
dw_volume_dot
<opt_material>,
DotProductVolumeTerm
<virtual>,
<state>
<opt_material>,
<parameter_1>,
<parameter_2>
∫︁
∫︁
∫︁
∫︁
𝑞𝑝 ,
𝑣·𝑢,
𝑝𝑟 ,
𝑢·𝑤
Ω
Ω
Ω
Ω
∫︁
∫︁
∫︁
∫︁
𝑐𝑞𝑝 ,
𝑐𝑣 · 𝑢 ,
𝑐𝑝𝑟 ,
𝑐𝑢 · 𝑤
Ω
Ω
Ω
∫︁
∫︁ Ω
𝑣·𝑀 ·𝑢,
𝑢·𝑀 ·𝑤
Ω
Ω
Continued on next page
586
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Table 7.5 – continued from previous page
name/class
arguments
definition
dw_volume_dot_w_scalar_eth
<ts>,
DotSProductVolumeOperatorWETHTerm
<material_0>,
]︂
∫︁ [︂∫︁ 𝑡
<material_1>,
𝒢(𝑡 − 𝜏 )𝑝(𝜏 ) d𝜏 𝑞
0
Ω
<virtual>,
<state>
dw_volume_dot_w_scalar_th
<ts>,
DotSProductVolumeOperatorWTHTerm
<material>,
]︂
∫︁ [︂∫︁ 𝑡
<virtual>,
𝒢(𝑡 − 𝜏 )𝑝(𝜏 ) d𝜏 𝑞
0
Ω
<state>
ev_volume_integrate
<opt_material>,
IntegrateVolumeTerm
<parameter>
∫︁
∫︁
𝑦,
𝑦
∫︁ Ω ∫︁ Ω
𝑐𝑦 ,
𝑐𝑦
Ω
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑦/
∫︁
𝑐𝑦/
𝑇𝐾
∫︁
1,
∫︁
1,
𝑇𝐾
𝑇𝐾
𝑇𝐾
∫︁
𝑦/
𝑇𝐾
𝑇𝐾
1
𝑇𝐾
∫︁
𝑐𝑦/
1
𝑇𝐾
𝑦|𝑞𝑝 , 𝑦|𝑞𝑝
𝑐𝑦|𝑞𝑝 , 𝑐𝑦|𝑞𝑝
dw_volume_integrate
<opt_material>,
IntegrateVolumeOperatorTerm
<virtual>
∫︁
∫︁
𝑞 or
𝑐𝑞
Ω
dw_volume_lvf
<material>,
LinearVolumeForceTerm
<virtual>
Ω
∫︁
∫︁
𝑓 · 𝑣 or
Ω
d_volume_surface
<parameter>
VolumeSurfaceTerm
𝑓𝑞
Ω
∫︁
𝑥·𝑛
1/𝐷
Γ
sfepy.terms.terms module
class sfepy.terms.terms.CharacteristicFunction(region)
get_local_chunk()
set_current_group(ig)
7.8. Module Index
587
SfePy Documentation, Release 2015.1
class sfepy.terms.terms.ConnInfo(**kwargs)
get_region(can_trace=True)
get_region_name(can_trace=True)
iter_igs()
class sfepy.terms.terms.Term(name, arg_str, integral, region, **kwargs)
advance(ts)
Advance to the next time step. Implemented in subclasses.
arg_shapes = {}
arg_types = ()
assemble_to(asm_obj, val, iels, mode=’vector’, diff_var=None)
assign_args(variables, materials, user=None)
Check term argument existence in variables, materials, user data and assign the arguments to terms. Also
check compatibility of field and term subdomain lists (igs).
call_function(out, fargs)
call_get_fargs(args, kwargs)
check_args()
Common checking to all terms.
Check compatibility of field and term subdomain lists (igs).
check_shapes(*args, **kwargs)
Default implementation of function to check term argument shapes at run-time.
classify_args()
Classify types of the term arguments and find matching call signature.
A state variable can be in place of a parameter variable and vice versa.
eval_complex(shape, fargs, mode=’eval’, term_mode=None, diff_var=None, **kwargs)
eval_real(shape, fargs, mode=’eval’, term_mode=None, diff_var=None, **kwargs)
evaluate(mode=’eval’, diff_var=None, standalone=True, ret_status=False, **kwargs)
Evaluate the term.
Parameters mode : ‘eval’ (default), or ‘weak’
The term evaluation mode.
Returns val : float or array
In ‘eval’ mode, the term returns a single value (the integral, it does not need to be a
scalar), while in ‘weak’ mode it returns an array for each element.
status : int, optional
The flag indicating evaluation success (0) or failure (nonzero). Only provided if
ret_status is True.
iels : array of ints, optional
The local elements indices in ‘weak’ mode. Only provided in non-‘eval’ modes.
static from_desc(constructor, desc, region, integrals=None)
588
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
geometries = [‘1_2’, ‘2_3’, ‘2_4’, ‘3_4’, ‘3_8’]
get(variable, quantity_name, bf=None, integration=None, step=None, time_derivative=None)
Get the named quantity related to the variable.
Notes
This is a convenience wrapper of Variable.evaluate() that initializes the arguments using the term data.
get_approximation(variable, get_saved=False)
Return approximation corresponding to variable. Also return the corresponding geometry (actual or saved,
according to get_saved).
get_arg_name(arg_type, full=False, join=None)
Get the name of the argument specified by arg_type.
Parameters arg_type : str
The argument type string.
full : bool
If True, return the full name. For example, if the name of a variable argument is ‘u’ and
its time derivative is requested, the full name is ‘du/dt’.
join : str, optional
Optionally, the material argument name tuple can be joined to a single string using the
join string.
Returns name : str
The argument name.
get_args(arg_types=None, **kwargs)
Return arguments by type as specified in arg_types (or self.ats). Arguments in **kwargs can override the
ones assigned at the term construction - this is useful for passing user data.
get_args_by_name(arg_names)
Return arguments by name.
get_assembling_cells(shape=None)
Return the assembling cell indices into a DOF connectivity.
get_conn_info()
get_conn_key()
The key to be used in DOF connectivity information.
get_current_group()
get_data_shape(variable)
Get data shape information from variable.
Notes
This is a convenience wrapper of FieldVariable.get_data_shape() that initializes the arguments using the
term data.
get_dof_conn_type()
get_geometry_types()
7.8. Module Index
589
SfePy Documentation, Release 2015.1
Returns out : dict
The required geometry types for each variable argument.
get_kwargs(keys, **kwargs)
Extract arguments from **kwargs listed in keys (default is None).
get_mapping(variable, get_saved=False, return_key=False)
Get the reference mapping from a variable.
Notes
This is a convenience wrapper of Field.get_mapping() that initializes the arguments using the term data.
get_material_names()
get_materials(join=False)
get_parameter_names()
get_parameter_variables()
get_physical_qps()
Get physical quadrature points corresponding to the term region and integral.
get_qp_key()
Return a key identifying uniquely the term quadrature points.
get_region()
get_state_names()
If variables are given, return only true unknowns whose data are of the current time step (0).
get_state_variables(unknown_only=False)
get_user_names()
get_variable_names()
get_variables(as_list=True)
get_vector(variable)
Get the vector stored in variable according to self.arg_steps and self.arg_derivatives. Supports only the
backward difference w.r.t. time.
get_virtual_name()
get_virtual_variable()
igs()
integration = ‘volume’
iter_groups()
name = ‘’
static new(name, integral, region, **kwargs)
set_arg_types()
set_current_group(ig)
set_integral(integral)
Set the term integral.
590
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
setup()
setup_args(**kwargs)
setup_formal_args()
setup_integration()
standalone_setup()
time_update(ts)
class sfepy.terms.terms.Terms(objs=None)
append(obj)
assign_args(variables, materials, user=None)
Assign all term arguments.
static from_desc(term_descs, regions, integrals=None)
Create terms, assign each term its region.
get_material_names()
get_user_names()
get_variable_names()
insert(ii, obj)
set_current_group(ig)
setup()
update_expression()
sfepy.terms.terms.create_arg_parser()
sfepy.terms.terms.get_arg_kinds(arg_types)
Translate arg_types of a Term to a canonical form.
Parameters arg_types : tuple of strings
The term argument types, as given in the arg_types attribute.
Returns arg_kinds : list of strings
The argument kinds - one of ‘virtual_variable’, ‘state_variable’, ‘parameter_variable’,
‘opt_material’, ‘user’.
sfepy.terms.terms.get_shape_kind(integration)
Get data shape kind for given integration type.
sfepy.terms.terms.split_complex_args(args)
Split complex arguments to real and imaginary parts.
Returns newargs : dictionary
Dictionary with lists corresponding to args such that each argument of
numpy.complex128 data type is split to its real and imaginary part. The output
depends on the number of complex arguments in ‘args’:
• 0: list (key ‘r’) identical to input one
• 1: two lists with keys ‘r’, ‘i’ corresponding to real and imaginary parts
• 2: output dictionary contains four lists:
7.8. Module Index
591
SfePy Documentation, Release 2015.1
– ‘r’ - real(arg1), real(arg2)
– ‘i’ - imag(arg1), imag(arg2)
– ‘ri’ - real(arg1), imag(arg2)
– ‘ir’ - imag(arg1), real(arg2)
sfepy.terms.terms.vector_chunk_generator(total_size, chunk_size, shape_in, zero=False,
set_shape=True, dtype=<type ‘numpy.float64’>)
sfepy.terms.terms_acoustic module
class sfepy.terms.terms_acoustic.DiffusionSATerm(name,
arg_str,
**kwargs)
Diffusion sensitivity analysis term.
integral,
region,
Definition
∫︁
[(div 𝒱)𝐾𝑖𝑗 ∇𝑖 𝑞 ∇𝑗 𝑝 − 𝐾𝑖𝑗 (∇𝑗 𝒱∇𝑞)∇𝑖 𝑝 − 𝐾𝑖𝑗 ∇𝑗 𝑞(∇𝑖 𝒱∇𝑝)]
Ω
Call signature
d_diffusion_sa
(material, parameter_q, parameter_p, parameter_v)
Arguments
• material: 𝐾𝑖𝑗
• parameter_q: 𝑞
• parameter_p: 𝑝
• parameter_v: 𝒱
arg_shapes = {‘parameter_q’: 1, ‘material’: ‘D, D’, ‘parameter_v’: ‘D’, ‘parameter_p’: 1}
arg_types = (‘material’, ‘parameter_q’, ‘parameter_p’, ‘parameter_v’)
function()
get_eval_shape(mat, parameter_q, parameter_p, parameter_v, mode=None, term_mode=None,
diff_var=None, **kwargs)
get_fargs(mat, parameter_q, parameter_p,
diff_var=None, **kwargs)
parameter_v,
mode=None,
term_mode=None,
name = ‘d_diffusion_sa’
class sfepy.terms.terms_acoustic.SurfaceCoupleLayerTerm(name, arg_str, integral, region, **kwargs)
Acoustic ‘layer’ term - derivatives in surface directions.
Definition
∫︁
∫︁
𝑐𝑞 𝜕𝛼 𝑝,
Γ
∫︁
𝑐𝜕𝛼 𝑟 𝑠, 𝛼 = 1, . . . , 𝑁 − 1
𝑐𝜕𝛼 𝑝 𝑞,
Γ
Γ
Call signature
dw_surface_lcouple
592
(material, virtual, state)
(material, state, virtual)
(material, parameter_1, parameter_2)
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Arguments 1
• material: 𝑐
• virtual: 𝑞
• state: 𝑝
Arguments 2
• material: 𝑐
• virtual: 𝑞
• state: 𝑝
Arguments 3
• material: 𝑐
• parameter_1: 𝑠
• parameter_2: 𝑟
arg_shapes = {‘parameter_2’: 1, ‘state’: 1, ‘material’: ‘1, 1’, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’)}
arg_types = ((‘material’, ‘virtual’, ‘state’), (‘material’, ‘state’, ‘virtual’), (‘material’, ‘parameter_1’, ‘parameter_2’))
geometries = [‘2_3’, ‘2_4’]
get_eval_shape(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
modes = (‘bv_ns’, ‘nv_bs’, ‘eval’)
name = ‘dw_surface_lcouple’
set_arg_types()
class sfepy.terms.terms_acoustic.SurfaceLaplaceLayerTerm(name, arg_str, integral, region, **kwargs)
Acoustic ‘layer’ term - derivatives in surface directions.
Definition
∫︁
𝑐𝜕𝛼 𝑞 𝜕𝛼 𝑝, 𝛼 = 1, . . . , 𝑁 − 1
Γ
Call signature
dw_surface_laplace
(material, virtual, state)
(material, parameter_2, parameter_1)
Arguments 1
• material: 𝑐
• virtual: 𝑞
• state: 𝑝
Arguments 2
• material: 𝑐
7.8. Module Index
593
SfePy Documentation, Release 2015.1
• parameter_1: 𝑞
• parameter_2: 𝑝
arg_shapes = {‘parameter_2’: 1, ‘state’: 1, ‘material’: ‘1, 1’, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’)}
arg_types = [(‘material’, ‘virtual’, ‘state’), (‘material’, ‘parameter_2’, ‘parameter_1’)]
geometries = [‘2_3’, ‘2_4’]
get_eval_shape(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
modes = (‘weak’, ‘eval’)
name = ‘dw_surface_laplace’
set_arg_types()
sfepy.terms.terms_adj_navier_stokes module
class sfepy.terms.terms_adj_navier_stokes.AdjConvect1Term(name, arg_str, integral, region, **kwargs)
The first adjoint term to nonlinear convective term dw_convect.
Definition
∫︁
((𝑣 · ∇)𝑢) · 𝑤
Ω
Call signature
dw_adj_convect1
(virtual, state, parameter)
Arguments
• virtual : 𝑣
• state : 𝑤
• parameter : 𝑢
arg_shapes = {‘state’: ‘D’, ‘parameter’: ‘D’, ‘virtual’: (‘D’, ‘state’)}
arg_types = (‘virtual’, ‘state’, ‘parameter’)
function()
get_fargs(virtual, state, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_adj_convect1’
class sfepy.terms.terms_adj_navier_stokes.AdjConvect2Term(name, arg_str, integral, region, **kwargs)
The second adjoint term to nonlinear convective term dw_convect.
Definition
∫︁
((𝑢 · ∇)𝑣) · 𝑤
Ω
594
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Call signature
dw_adj_convect2
(virtual, state, parameter)
Arguments
• virtual : 𝑣
• state : 𝑤
• parameter : 𝑢
arg_shapes = {‘state’: ‘D’, ‘parameter’: ‘D’, ‘virtual’: (‘D’, ‘state’)}
arg_types = (‘virtual’, ‘state’, ‘parameter’)
function()
get_fargs(virtual, state, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_adj_convect2’
class sfepy.terms.terms_adj_navier_stokes.AdjDivGradTerm(name, arg_str, integral, region, **kwargs)
∫︀
Gateaux differential of Ψ(𝑢) = Ω 𝜈 ∇𝑣 : ∇𝑢 w.r.t. 𝑢 in the direction 𝑣 or adjoint term to dw_div_grad.
Definition
𝑤𝛿𝑢 Ψ(𝑢) ∘ 𝑣
Call signature
dw_adj_div_grad
(material_1, material_2, virtual, parameter)
Arguments
• material_1 : 𝑤 (weight)
• material_2 : 𝜈 (viscosity)
• virtual : 𝑣
• state : 𝑢
arg_shapes = {‘material_1’: ‘1, 1’, ‘material_2’: ‘1, 1’, ‘parameter’: ‘D’, ‘virtual’: (‘D’, None)}
arg_types = (‘material_1’, ‘material_2’, ‘virtual’, ‘parameter’)
function()
get_fargs(mat1, mat2, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_adj_div_grad’
class sfepy.terms.terms_adj_navier_stokes.NSOFMinGradTerm(name, arg_str, integral, region, **kwargs)
Call signature
d_of_ns_min_grad
(material_1, material_2, parameter)
arg_shapes = {‘material_1’: ‘1, 1’, ‘material_2’: ‘1, 1’, ‘parameter’: 1}
arg_types = (‘material_1’, ‘material_2’, ‘parameter’)
function()
7.8. Module Index
595
SfePy Documentation, Release 2015.1
get_eval_shape(weight, mat,
**kwargs)
parameter,
mode=None,
term_mode=None,
diff_var=None,
get_fargs(weight, mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_of_ns_min_grad’
class sfepy.terms.terms_adj_navier_stokes.NSOFSurfMinDPressDiffTerm(name,
arg_str,
integral,
region,
**kwargs)
Gateaux differential of Ψ(𝑝) w.r.t. 𝑝 in the direction 𝑞.
Definition
𝑤𝛿𝑝 Ψ(𝑝) ∘ 𝑞
Call signature
dw_of_ns_surf_min_d_press_diff
(material, virtual)
Arguments
• material : 𝑤 (weight)
• virtual : 𝑞
arg_shapes = {‘material’: 1, ‘virtual’: (1, None)}
arg_types = (‘material’, ‘virtual’)
get_fargs(weight, virtual, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_of_ns_surf_min_d_press_diff’
class sfepy.terms.terms_adj_navier_stokes.NSOFSurfMinDPressTerm(name,
arg_str,
integral, region,
**kwargs)
Sensitivity of Ψ(𝑝).
Definition
(︂∫︁
∫︁
𝑝−
𝛿Ψ(𝑝) = 𝛿
Γ𝑖𝑛
)︂
𝑏𝑝𝑟𝑒𝑠𝑠
Γ𝑜𝑢𝑡
Call signature
d_of_ns_surf_min_d_press
(material_1, material_2, parameter)
Arguments
• material_1 : 𝑤 (weight)
• material_2 : 𝑏𝑝𝑟𝑒𝑠𝑠 (given pressure)
• parameter : 𝑝
arg_shapes = {‘material_1’: 1, ‘material_2’: 1, ‘parameter’: 1}
arg_types = (‘material_1’, ‘material_2’, ‘parameter’)
function()
596
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
get_eval_shape(weight, bpress, parameter, mode=None, term_mode=None, diff_var=None,
**kwargs)
get_fargs(weight, bpress, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
name = ‘d_of_ns_surf_min_d_press’
class sfepy.terms.terms_adj_navier_stokes.SDConvectTerm(name, arg_str, integral, region, **kwargs)
Sensitivity (shape derivative) of convective term dw_convect.
Supports the following term modes: 1 (sensitivity) or 0 (original term value).
Definition
∫︁
[𝑢𝑘
Ω𝐷
𝜕𝒱𝑗 𝜕𝑢𝑖
𝜕𝑢𝑖
𝑤𝑖 (∇ · 𝒱) − 𝑢𝑘
𝑤𝑖 ]
𝜕𝑥𝑘
𝜕𝑥𝑘 𝜕𝑥𝑗
Call signature
d_sd_convect
(parameter_u, parameter_w, parameter_mesh_velocity)
Arguments
• parameter_u : 𝑢
• parameter_w : 𝑤
• parameter_mesh_velocity : 𝒱
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_w’: ‘D’, ‘parameter_u’: ‘D’}
arg_types = (‘parameter_u’, ‘parameter_w’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(par_u, par_w,
**kwargs)
par_mv,
mode=None,
term_mode=None,
diff_var=None,
get_fargs(par_u, par_w, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sd_convect’
class sfepy.terms.terms_adj_navier_stokes.SDDivGradTerm(name, arg_str, integral, region, **kwargs)
Sensitivity (shape derivative) of diffusion term dw_div_grad.
Supports the following term modes: 1 (sensitivity) or 0 (original term value).
Definition
∫︁
𝑤𝜈
[
Ω𝐷
𝜕𝑢𝑖 𝜕𝑤𝑖
𝜕𝒱𝑗 𝜕𝑢𝑖 𝜕𝑤𝑖
𝜕𝑢𝑖 𝜕𝒱𝑙 𝜕𝑤𝑖
(∇ · 𝒱) −
−
]
𝜕𝑥𝑘 𝜕𝑥𝑘
𝜕𝑥𝑘 𝜕𝑥𝑗 𝜕𝑥𝑘
𝜕𝑥𝑘 𝜕𝑥𝑘 𝜕𝑥𝑘
Call signature
d_sd_div_grad (material_1, material_2, parameter_u, parameter_w,
parameter_mesh_velocity)
Arguments
• material_1 : 𝑤 (weight)
• material_2 : 𝜈 (viscosity)
7.8. Module Index
597
SfePy Documentation, Release 2015.1
• parameter_u : 𝑢
• parameter_w : 𝑤
• parameter_mesh_velocity : 𝒱
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘material_1’: ‘1, 1’, ‘material_2’: ‘1, 1’, ‘parameter_w’: ‘D’, ‘paramete
arg_types = (‘material_1’, ‘material_2’, ‘parameter_u’, ‘parameter_w’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(mat1, mat2, par_u, par_w,
diff_var=None, **kwargs)
par_mv,
mode=None,
term_mode=None,
get_fargs(mat1, mat2, par_u, par_w, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
name = ‘d_sd_div_grad’
class sfepy.terms.terms_adj_navier_stokes.SDDivTerm(name, arg_str, integral, region,
**kwargs)
Sensitivity (shape derivative) of Stokes term dw_stokes in ‘div’ mode.
Supports the following term modes: 1 (sensitivity) or 0 (original term value).
Definition
∫︁
𝑝[(∇ · 𝑤)(∇ · 𝒱) −
Ω𝐷
𝜕𝒱𝑘 𝜕𝑤𝑖
]
𝜕𝑥𝑖 𝜕𝑥𝑘
Call signature
d_sd_div
(parameter_u, parameter_p, parameter_mesh_velocity)
Arguments
• parameter_u : 𝑢
• parameter_p : 𝑝
• parameter_mesh_velocity : 𝒱
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_p’: 1, ‘parameter_u’: ‘D’}
arg_types = (‘parameter_u’, ‘parameter_p’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(par_u, par_p, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(par_u, par_p, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sd_div’
class sfepy.terms.terms_adj_navier_stokes.SDDotVolumeTerm(name, arg_str, integral, region, **kwargs)
Sensitivity (shape derivative) of dot product of scalars or vectors.
Definition
∫︁
∫︁
𝑝𝑞(∇ · 𝒱) ,
Ω𝐷
(𝑢 · 𝑤)(∇ · 𝒱)
Ω𝐷
Call signature
598
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
d_sd_volume_dot
(parameter_1, parameter_2, parameter_mesh_velocity)
Arguments
• parameter_1 : 𝑝 or 𝑢
• parameter_2 : 𝑞 or 𝑤
• parameter_mesh_velocity : 𝒱
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_2’: ‘D’, ‘parameter_1’: ‘D’}
arg_types = (‘parameter_1’, ‘parameter_2’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(par1, par2, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(par1, par2, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sd_volume_dot’
class sfepy.terms.terms_adj_navier_stokes.SDGradDivStabilizationTerm(name,
arg_str,
integral,
region,
**kwargs)
Sensitivity (shape derivative) of stabilization term dw_st_grad_div.
Definition
∫︁
[(∇ · 𝑢)(∇ · 𝑤)(∇ · 𝒱) −
𝛾
Ω𝐷
𝜕𝑢𝑖 𝜕𝒱𝑘
𝜕𝑤𝑖 𝜕𝒱𝑘
(∇ · 𝑤) − (∇ · 𝑢)
]
𝜕𝑥𝑘 𝜕𝑥𝑖
𝜕𝑥𝑘 𝜕𝑥𝑖
Call signature
d_sd_st_grad_div (material, parameter_u, parameter_w,
parameter_mesh_velocity)
Arguments
• material : 𝛾
• parameter_u : 𝑢
• parameter_w : 𝑤
• parameter_mesh_velocity : 𝒱
• mode : 1 (sensitivity) or 0 (original term value)
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘material’: ‘1, 1’, ‘parameter_w’: ‘D’, ‘parameter_u’: ‘D’}
arg_types = (‘material’, ‘parameter_u’, ‘parameter_w’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(mat, par_u, par_w, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
get_fargs(mat, par_u, par_w, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sd_st_grad_div’
7.8. Module Index
599
SfePy Documentation, Release 2015.1
class sfepy.terms.terms_adj_navier_stokes.SDPSPGCStabilizationTerm(name,
arg_str, integral, region,
**kwargs)
Sensitivity (shape derivative) of stabilization terms dw_st_supg_p or dw_st_pspg_c.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝛿𝐾 [
𝑇𝐾
𝜕𝑟 𝜕𝒱𝑘
𝜕𝑟
𝜕𝑢𝑖
𝜕𝑟
(𝑏 · ∇𝑢𝑖 )(∇ · 𝒱) −
(𝑏 · ∇𝑢𝑖 ) −
(𝑏 · ∇𝒱𝑘 )
]
𝜕𝑥𝑖
𝜕𝑥𝑘 𝜕𝑥𝑖
𝜕𝑥𝑘
𝜕𝑥𝑘
Call signature
d_sd_st_pspg_c(material, parameter_b, parameter_u, parameter_r,
parameter_mesh_velocity)
Arguments
• material : 𝛿𝐾
• parameter_b : 𝑏
• parameter_u : 𝑢
• parameter_r : 𝑟
• parameter_mesh_velocity : 𝒱
• mode : 1 (sensitivity) or 0 (original term value)
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_b’: ‘D’, ‘material’: ‘1, 1’, ‘parameter_u’: ‘D’, ‘parameter_
arg_types = (‘material’, ‘parameter_b’, ‘parameter_u’, ‘parameter_r’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(mat, par_b, par_u, par_r, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
get_fargs(mat, par_b, par_u, par_r, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
name = ‘d_sd_st_pspg_c’
class sfepy.terms.terms_adj_navier_stokes.SDPSPGPStabilizationTerm(name,
arg_str, integral, region,
**kwargs)
Sensitivity (shape derivative) of stabilization term dw_st_pspg_p.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝑇𝐾
𝜏𝐾 [(∇𝑟 · ∇𝑝)(∇ · 𝒱) −
𝜕𝑟
𝜕𝑝
(∇𝒱𝑘 · ∇𝑝) − (∇𝑟 · ∇𝒱𝑘 )
]
𝜕𝑥𝑘
𝜕𝑥𝑘
Call signature
d_sd_st_pspg_p
(material, parameter_r, parameter_p,
parameter_mesh_velocity)
Arguments
• material : 𝜏𝐾
600
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
• parameter_r : 𝑟
• parameter_p : 𝑝
• parameter_mesh_velocity : 𝒱
• mode : 1 (sensitivity) or 0 (original term value)
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_r’: 1, ‘material’: ‘1, 1’, ‘parameter_p’: 1}
arg_types = (‘material’, ‘parameter_r’, ‘parameter_p’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(mat, par_r, par_p, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
get_fargs(mat, par_r, par_p, par_mv, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sd_st_pspg_p’
class sfepy.terms.terms_adj_navier_stokes.SDSUPGCStabilizationTerm(name,
arg_str, integral, region,
**kwargs)
Sensitivity (shape derivative) of stabilization term dw_st_supg_c.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝛿𝐾 [(𝑏 · ∇𝑢𝑘 )(𝑏 · ∇𝑤𝑘 )(∇ · 𝒱) − (𝑏 · ∇𝒱𝑖 )
𝑇𝐾
𝜕𝑢𝑘
𝜕𝑤𝑘
(𝑏 · ∇𝑤𝑘 ) − (𝑢 · ∇𝑢𝑘 )(𝑏 · ∇𝒱𝑖 )
]
𝜕𝑥𝑖
𝜕𝑥𝑖
Call signature
d_sd_st_supg_c(material, parameter_b, parameter_u, parameter_w,
parameter_mesh_velocity)
Arguments
• material : 𝛿𝐾
• parameter_b : 𝑏
• parameter_u : 𝑢
• parameter_w : 𝑤
• parameter_mesh_velocity : 𝒱
• mode : 1 (sensitivity) or 0 (original term value)
arg_shapes = {‘parameter_mesh_velocity’: ‘D’, ‘parameter_b’: ‘D’, ‘material’: ‘1, 1’, ‘parameter_w’: ‘D’, ‘parameter
arg_types = (‘material’, ‘parameter_b’, ‘parameter_u’, ‘parameter_w’, ‘parameter_mesh_velocity’)
function()
get_eval_shape(mat, par_b, par_u, par_w,
diff_var=None, **kwargs)
par_mv,
mode=None,
term_mode=None,
get_fargs(mat, par_b, par_u, par_w, par_mv, mode=None, term_mode=None, diff_var=None,
**kwargs)
name = ‘d_sd_st_supg_c’
7.8. Module Index
601
SfePy Documentation, Release 2015.1
class sfepy.terms.terms_adj_navier_stokes.SUPGCAdjStabilizationTerm(name,
arg_str,
integral,
region,
**kwargs)
Adjoint term to SUPG stabilization term dw_st_supg_c.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝛿𝐾 [((𝑣 · ∇)𝑢)((𝑢 · ∇)𝑤) + ((𝑢 · ∇)𝑢)((𝑣 · ∇)𝑤)]
𝑇𝐾
Call signature
dw_st_adj_supg_c
(material, virtual, parameter, state)
Arguments
• material : 𝛿𝐾
• virtual : 𝑣
• state : 𝑤
• parameter : 𝑢
arg_shapes = {‘state’: ‘D’, ‘material’: ‘1, 1’, ‘parameter’: ‘D’, ‘virtual’: (‘D’, ‘state’)}
arg_types = (‘material’, ‘virtual’, ‘parameter’, ‘state’)
function()
get_fargs(mat, virtual, state, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_st_adj_supg_c’
class sfepy.terms.terms_adj_navier_stokes.SUPGPAdj1StabilizationTerm(name,
arg_str,
integral,
region,
**kwargs)
The first adjoint term to SUPG stabilization term dw_st_supg_p.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝛿𝐾 ∇𝑝(𝑣 · ∇𝑤)
𝑇𝐾
Call signature
dw_st_adj1_supg_p
(material, virtual, state, parameter)
Arguments
• material : 𝛿𝐾
• virtual : 𝑣
• state : 𝑤
• parameter : 𝑝
arg_shapes = {‘state’: ‘D’, ‘material’: ‘1, 1’, ‘parameter’: 1, ‘virtual’: (‘D’, ‘state’)}
602
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
arg_types = (‘material’, ‘virtual’, ‘state’, ‘parameter’)
function()
get_fargs(mat, virtual, state, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_st_adj1_supg_p’
class sfepy.terms.terms_adj_navier_stokes.SUPGPAdj2StabilizationTerm(name,
arg_str,
integral,
region,
**kwargs)
The second adjoint term to SUPG stabilization term dw_st_supg_p as well as adjoint term to PSPG stabilization
term dw_st_pspg_c.
Definition
∑︁ ∫︁
𝐾∈ℐℎ
𝜏𝐾 ∇𝑟(𝑣 · ∇𝑢)
𝑇𝐾
Call signature
dw_st_adj2_supg_p
(material, virtual, parameter, state)
Arguments
• material : 𝜏𝐾
• virtual : 𝑣
• parameter : 𝑢
• state : 𝑟
arg_shapes = {‘state’: 1, ‘material’: ‘1, 1’, ‘parameter’: ‘D’, ‘virtual’: (‘D’, ‘state’)}
arg_types = (‘material’, ‘virtual’, ‘parameter’, ‘state’)
function()
get_fargs(mat, virtual, parameter, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_st_adj2_supg_p’
sfepy.terms.terms_adj_navier_stokes.grad_as_vector(grad)
sfepy.terms.terms_basic module
class sfepy.terms.terms_basic.IntegrateMatTerm(name, arg_str, integral, region, **kwargs)
Evaluate material parameter 𝑚 in a volume/surface region.
Depending on evaluation mode, integrate a material parameter over a volume/surface region (‘eval’), average it
in elements/faces (‘el_avg’) or interpolate it into volume/surface quadrature points (‘qp’).
Uses reference mapping of 𝑦 variable.
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
7.8. Module Index
603
SfePy Documentation, Release 2015.1
∫︁
𝑚
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑚/
𝑇𝐾
1
𝑇𝐾
𝑚|𝑞𝑝
Call signature
ev_integrate_mat
(material, parameter)
Arguments
• material : 𝑚 (can have up to two dimensions)
• parameter : 𝑦
arg_shapes = [{‘material’: ‘1, 1’, ‘parameter’: 1}, {‘material’: ‘D, D’}, {‘material’: ‘S, S’}, {‘material’: ‘D, S’}]
arg_types = (‘material’, ‘parameter’)
static function(out, mat, geo, fmode)
get_eval_shape(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_integrate_mat’
class sfepy.terms.terms_basic.IntegrateSurfaceOperatorTerm(name, arg_str, integral,
region, **kwargs)
Surface integral of a test function weighted by a scalar function 𝑐.
Definition
∫︁
∫︁
𝑞 or
Γ
𝑐𝑞
Γ
Call signature
dw_surface_integrate
(opt_material, virtual)
Arguments
• material : 𝑐 (optional)
• virtual : 𝑞
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘virtual’: (1, None)}, {‘opt_material’: None}]
arg_types = (‘opt_material’, ‘virtual’)
integration = ‘surface’
name = ‘dw_surface_integrate’
class sfepy.terms.terms_basic.IntegrateSurfaceTerm(name, arg_str,
**kwargs)
Evaluate (weighted) variable in a surface region.
integral,
region,
Depending on evaluation mode, integrate a variable over a surface region (‘eval’), average it in element faces
(‘el_avg’) or interpolate it into surface quadrature points (‘qp’). For vector variables, setting term_mode to ‘flux’
leads to computing corresponding fluxes for the three modes instead.
604
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
∫︁
∫︁
∫︁
𝑦,
∫︁ Γ
∫︁
𝑐𝑦 ,
Γ
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
𝑦/
𝑇𝐾
∫︁
∫︁
vector for 𝐾 ← ℐℎ :
𝑐𝑦/
𝑇𝐾
Γ
∫︁Γ
𝑐𝑦 · 𝑛 flux
𝑐𝑦 ,
Γ
𝑦·𝑛
𝑦,
Γ
∫︁
∫︁
1,
∫︁
1,
𝑦/
∫︁
𝑐𝑦/
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
1,
∫︁
1,
𝑇𝐾
𝑇𝐾
∫︁
∫︁
(𝑦 · 𝑛)/
𝑇𝐾
𝑇𝐾
1
𝑇𝐾
∫︁
(𝑐𝑦 · 𝑛)/
1
𝑇𝐾
𝑦|𝑞𝑝 , 𝑦|𝑞𝑝 , (𝑦 · 𝑛)|𝑞𝑝 flux
𝑐𝑦|𝑞𝑝 , 𝑐𝑦|𝑞𝑝 , (𝑐𝑦 · 𝑛)|𝑞𝑝 flux
Call signature
ev_surface_integrate
(opt_material, parameter)
Arguments
• material : 𝑐 (optional)
• parameter : 𝑦 or 𝑦
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘parameter’: 1}, {‘opt_material’: None}, {‘opt_material’: ‘1, 1’, ‘parameter’: ‘D’
arg_types = (‘opt_material’, ‘parameter’)
static function(out, val_qp, sg, fmode)
get_eval_shape(material, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(material, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
name = ‘ev_surface_integrate’
class sfepy.terms.terms_basic.IntegrateVolumeOperatorTerm(name, arg_str, integral, region, **kwargs)
Volume integral of a test function weighted by a scalar function 𝑐.
Definition
∫︁
∫︁
𝑞 or
Ω
𝑐𝑞
Ω
Call signature
dw_volume_integrate
(opt_material, virtual)
Arguments
• material : 𝑐 (optional)
• virtual : 𝑞
7.8. Module Index
605
SfePy Documentation, Release 2015.1
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘virtual’: (1, None)}, {‘opt_material’: None}]
arg_types = (‘opt_material’, ‘virtual’)
static function(out, material, bf, geo)
get_fargs(material, virtual, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_volume_integrate’
class sfepy.terms.terms_basic.IntegrateVolumeTerm(name, arg_str,
**kwargs)
Evaluate (weighted) variable in a volume region.
integral,
region,
Depending on evaluation mode, integrate a variable over a volume region (‘eval’), average it in elements
(‘el_avg’) or interpolate it into volume quadrature points (‘qp’).
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
∫︁
∫︁
𝑦,
𝑦
∫︁ Ω ∫︁ Ω
𝑐𝑦 ,
𝑐𝑦
Ω
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
∫︁
∫︁
𝑦/
1,
𝑦/
1
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
∫︁
∫︁
∫︁
𝑐𝑦/
1,
𝑐𝑦/
1
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑇𝐾
𝑦|𝑞𝑝 , 𝑦|𝑞𝑝
𝑐𝑦|𝑞𝑝 , 𝑐𝑦|𝑞𝑝
Call signature
ev_volume_integrate
(opt_material, parameter)
Arguments
• material : 𝑐 (optional)
• parameter : 𝑦 or 𝑦
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘parameter’: 1}, {‘opt_material’: None}, {‘opt_material’: ‘1, 1’, ‘parameter’: ‘D’
arg_types = (‘opt_material’, ‘parameter’)
static function(out, val_qp, vg, fmode)
get_eval_shape(material, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(material, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_volume_integrate’
class sfepy.terms.terms_basic.SumNodalValuesTerm(name,
arg_str,
**kwargs)
Sum nodal values.
integral,
region,
Call signature
606
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
d_sum_vals
(parameter)
Arguments
• parameter : 𝑝 or 𝑢
arg_shapes = [{‘parameter’: 1}, {‘parameter’: ‘D’}]
arg_types = (‘parameter’,)
static function(out, vec)
get_eval_shape(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_sum_vals’
class sfepy.terms.terms_basic.SurfaceMomentTerm(name, arg_str, integral, region, **kwargs)
Surface integral of the outer product of the unit outward normal 𝑛 and the coordinate 𝑥 shifted by 𝑥0
Definition
∫︁
𝑛(𝑥 − 𝑥0 )
Γ
Call signature
di_surface_moment
(parameter, shift)
Arguments
• parameter : any variable
• shift : 𝑥0
arg_types = (‘parameter’, ‘shift’)
function()
get_eval_shape(parameter, shift, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(parameter, shift, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
name = ‘di_surface_moment’
class sfepy.terms.terms_basic.SurfaceTerm(name, arg_str, integral, region, **kwargs)
Surface of a domain. Uses approximation of the parameter variable.
Definition
∫︁
1
Γ
Call signature
d_surface
(parameter)
Arguments
• parameter : any variable
arg_shapes = {‘parameter’: 1}
7.8. Module Index
607
SfePy Documentation, Release 2015.1
arg_types = (‘parameter’,)
integration = ‘surface’
name = ‘d_surface’
class sfepy.terms.terms_basic.VolumeSurfaceTerm(name, arg_str, integral, region, **kwargs)
Volume of a 𝐷-dimensional domain, using a surface integral. Uses approximation of the parameter variable.
Definition
∫︁
𝑥·𝑛
1/𝐷
Γ
Call signature
d_volume_surface
(parameter)
Arguments
• parameter : any variable
arg_shapes = {‘parameter’: 1}
arg_types = (‘parameter’,)
function()
get_eval_shape(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
name = ‘d_volume_surface’
class sfepy.terms.terms_basic.VolumeTerm(name, arg_str, integral, region, **kwargs)
Volume of a domain. Uses approximation of the parameter variable.
Definition
∫︁
1
Ω
Call signature
d_volume
(parameter)
Arguments
• parameter : any variable
arg_shapes = {‘parameter’: 1}
arg_types = (‘parameter’,)
static function(out, geo)
get_eval_shape(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘d_volume’
608
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
sfepy.terms.terms_biot module
class sfepy.terms.terms_biot.BiotETHTerm(name, arg_str, integral, region, **kwargs)
This term has the same definition as dw_biot_th, but assumes an exponential approximation of the convolution
kernel resulting in much higher efficiency. Can use derivatives.
Definition
]︁
∫︀ [︁∫︀ 𝑡
𝛼
(𝑡
−
𝜏
)
𝑝(𝜏
))
d𝜏
𝑒𝑖𝑗 (𝑣) ,
𝑖𝑗
Ω
0
]︁
∫︀ [︁∫︀ 𝑡
))
d𝜏
𝑞
𝛼
(𝑡
−
𝜏
)𝑒
(𝑢(𝜏
𝑘𝑙
Ω
0 𝑖𝑗
Call signature
dw_biot_eth
(ts, material_0, material_1, virtual, state)
(ts, material_0, material_1, state, virtual)
Arguments 1
• ts : TimeStepper instance
• material_0 : 𝛼𝑖𝑗 (0)
• material_1 : exp(−𝜆∆𝑡) (decay at 𝑡1 )
• virtual : 𝑣
• state : 𝑝
Arguments 2
• ts : TimeStepper instance
• material_0 : 𝛼𝑖𝑗 (0)
• material_1 : exp(−𝜆∆𝑡) (decay at 𝑡1 )
• state : 𝑢
• virtual : 𝑞
arg_shapes = {}
arg_types = ((‘ts’, ‘material_0’, ‘material_1’, ‘virtual’, ‘state’), (‘ts’, ‘material_0’, ‘material_1’, ‘state’, ‘virtual’))
get_fargs(ts, mat0, mat1, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘grad’, ‘div’)
name = ‘dw_biot_eth’
class sfepy.terms.terms_biot.BiotStressTerm(name, arg_str, integral, region, **kwargs)
Evaluate Biot stress tensor.
It is given in the usual vector form exploiting symmetry: in 3D it has 6 components with the indices ordered as
[11, 22, 33, 12, 13, 23], in 2D it has 3 components with the indices ordered as [11, 22, 12].
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
∫︁
−
𝛼𝑖𝑗 𝑝¯
Ω
7.8. Module Index
609
SfePy Documentation, Release 2015.1
∫︁
vector for 𝐾 ← ℐℎ : −
∫︁
𝛼𝑖𝑗 𝑝¯/
𝑇𝐾
1
𝑇𝐾
−𝛼𝑖𝑗 𝑝¯|𝑞𝑝
Call signature
ev_biot_stress
(material, parameter)
Arguments
• material : 𝛼𝑖𝑗
• parameter : 𝑝¯
arg_shapes = {‘material’: ‘S, 1’, ‘parameter’: 1}
arg_types = (‘material’, ‘parameter’)
static function(out, val_qp, mat, vg, fmode)
get_fargs(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_biot_stress’
class sfepy.terms.terms_biot.BiotTHTerm(name, arg_str, integral, region, **kwargs)
Fading memory Biot term. Can use derivatives.
Definition
]︁
∫︀ [︁∫︀ 𝑡
𝛼
(𝑡
−
𝜏
)
𝑝(𝜏
))
d𝜏
𝑒𝑖𝑗 (𝑣) ,
𝑖𝑗
Ω
0
]︁
∫︀ [︁∫︀ 𝑡
𝛼
(𝑡
−
𝜏
)𝑒
(𝑢(𝜏
))
d𝜏
𝑞
𝑘𝑙
Ω
0 𝑖𝑗
Call signature
dw_biot_th
(ts, material, virtual, state)
(ts, material, state, virtual)
Arguments 1
• ts : TimeStepper instance
• material : 𝛼𝑖𝑗 (𝜏 )
• virtual : 𝑣
• state : 𝑝
Arguments 2
• ts : TimeStepper instance
• material : 𝛼𝑖𝑗 (𝜏 )
• state : 𝑢
• virtual : 𝑞
arg_shapes = {}
arg_types = ((‘ts’, ‘material’, ‘virtual’, ‘state’), (‘ts’, ‘material’, ‘state’, ‘virtual’))
get_fargs(ts, mats, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
610
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
modes = (‘grad’, ‘div’)
name = ‘dw_biot_th’
class sfepy.terms.terms_biot.BiotTerm(name, arg_str, integral, region, **kwargs)
Biot coupling term with 𝛼𝑖𝑗 given in vector form exploiting symmetry: in 3D it has the indices ordered as
[11, 22, 33, 12, 13, 23], in 2D it has the indices ordered as [11, 22, 12]. Corresponds to weak forms of Biot
gradient and divergence terms. Can be evaluated. Can use derivatives.
Definition
∫︁
∫︁
𝑞 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑢)
𝑝 𝛼𝑖𝑗 𝑒𝑖𝑗 (𝑣) ,
Ω
Ω
Call signature
dw_biot
(material, virtual, state)
(material, state, virtual)
(material, parameter_v, parameter_s)
Arguments 1
• material : 𝛼𝑖𝑗
• virtual : 𝑣
• state : 𝑝
Arguments 2
• material : 𝛼𝑖𝑗
• state : 𝑢
• virtual : 𝑞
Arguments 3
• material : 𝛼𝑖𝑗
• parameter_v : 𝑢
• parameter_s : 𝑝
arg_shapes = {‘state/grad’: 1, ‘state/div’: ‘D’, ‘material’: ‘S, 1’, ‘virtual/grad’: (‘D’, None), ‘parameter_s’: 1, ‘paramet
arg_types = ((‘material’, ‘virtual’, ‘state’), (‘material’, ‘state’, ‘virtual’), (‘material’, ‘parameter_v’, ‘parameter_s’))
get_eval_shape(mat, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘grad’, ‘div’, ‘eval’)
name = ‘dw_biot’
set_arg_types()
sfepy.terms.terms_constraints module
class sfepy.terms.terms_constraints.NonPenetrationTerm(name, arg_str, integral, region,
**kwargs)
Non-penetration condition in the weak sense.
Definition
7.8. Module Index
611
SfePy Documentation, Release 2015.1
∫︁
∫︁
ˆ ·𝑢
𝑐𝜆𝑛 · 𝑣 ,
𝑐𝜆𝑛
Γ
Γ
∫︁
∫︁
ˆ ·𝑢
𝜆𝑛 · 𝑣 ,
𝜆𝑛
Γ
Γ
Call signature
dw_non_penetration
(opt_material, virtual, state)
(opt_material, state, virtual)
Arguments 1
• material : 𝑐 (optional)
• virtual : 𝑣
• state : 𝜆
Arguments 2
• material : 𝑐 (optional)
• state : 𝑢
ˆ
• virtual : 𝜆
arg_shapes = [{‘virtual/grad’: (‘D’, None), ‘opt_material’: ‘1, 1’, ‘state/grad’: 1, ‘state/div’: ‘D’, ‘virtual/div’: (1, None
arg_types = ((‘opt_material’, ‘virtual’, ‘state’), (‘opt_material’, ‘state’, ‘virtual’))
static function(out, val_qp, ebf, bf, mat, sg, diff_var, mode)
ebf belongs to vector variable, bf to scalar variable.
get_fargs(mat, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface’
modes = (‘grad’, ‘div’)
name = ‘dw_non_penetration’
sfepy.terms.terms_diffusion module
class sfepy.terms.terms_diffusion.ConvectVGradSTerm(name, arg_str, integral, region,
**kwargs)
Scalar gradient term with convective velocity.
Definition
∫︁
𝑞(𝑢 · ∇𝑝)
Ω
Call signature
dw_convect_v_grad_s
(virtual, state_v, state_s)
Arguments
• virtual : 𝑞
• state_v : 𝑢
• state_s : 𝑝
612
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
arg_shapes = [{‘state_s’: 1, ‘virtual’: (1, ‘state_s’), ‘state_v’: ‘D’}]
arg_types = (‘virtual’, ‘state_v’, ‘state_s’)
function()
get_fargs(virtual, state_v, state_s, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_convect_v_grad_s’
class sfepy.terms.terms_diffusion.DiffusionCoupling(name, arg_str, integral, region,
**kwargs)
Diffusion copupling term with material parameter 𝐾𝑗 .
Definition
∫︁
𝑝𝐾𝑗 ∇𝑗 𝑞
Ω
Call signature
dw_diffusion_coupling
(material, virtual, state)
(material, state, virtual)
(material, parameter_1, parameter_2)
Arguments
• material : 𝐾𝑗
• virtual : 𝑞
• state : 𝑝
arg_shapes = {‘parameter_2’: 1, ‘state’: 1, ‘material’: ‘D, 1’, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’)}
arg_types = ((‘material’, ‘virtual’, ‘state’), (‘material’, ‘state’, ‘virtual’), (‘material’, ‘parameter_1’, ‘parameter_2’))
static d_fun(out, mat, val, grad, vg)
static dw_fun(out, val, mat, bf, vg, fmode)
get_eval_shape(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘weak0’, ‘weak1’, ‘eval’)
name = ‘dw_diffusion_coupling’
set_arg_types()
class sfepy.terms.terms_diffusion.DiffusionRTerm(name,
arg_str,
**kwargs)
Diffusion-like term with material parameter 𝐾𝑗 (to use on the right-hand side).
integral,
region,
Definition
∫︁
𝐾𝑗 ∇𝑗 𝑞
Ω
Call signature
dw_diffusion_r
(material, virtual)
Arguments
7.8. Module Index
613
SfePy Documentation, Release 2015.1
• material : 𝐾𝑗
• virtual : 𝑞
arg_shapes = {‘material’: ‘D, 1’, ‘virtual’: (1, None)}
arg_types = (‘material’, ‘virtual’)
function()
get_fargs(mat, virtual, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_diffusion_r’
class sfepy.terms.terms_diffusion.DiffusionTerm(name, arg_str, integral, region, **kwargs)
General diffusion term with permeability 𝐾𝑖𝑗 . Can be evaluated. Can use derivatives.
Definition
∫︁
∫︁
𝐾𝑖𝑗 ∇𝑖 𝑝¯∇𝑗 𝑟
𝐾𝑖𝑗 ∇𝑖 𝑞∇𝑗 𝑝 ,
Ω
Ω
Call signature
dw_diffusion
(material, virtual, state)
(material, parameter_1, parameter_2)
Arguments 1
• material : 𝐾𝑖𝑗
• virtual : 𝑞
• state : 𝑝
Arguments 2
• material : 𝐾𝑖𝑗
• parameter_1 : 𝑝¯
• parameter_2 : 𝑟
arg_shapes = {‘parameter_2’: 1, ‘state’: 1, ‘material’: ‘D, D’, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’)}
arg_types = ((‘material’, ‘virtual’, ‘state’), (‘material’, ‘parameter_1’, ‘parameter_2’))
get_eval_shape(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘weak’, ‘eval’)
name = ‘dw_diffusion’
set_arg_types()
symbolic = {‘map’: {‘K’: ‘material’, ‘u’: ‘state’}, ‘expression’: ‘div( K * grad( u ) )’}
class sfepy.terms.terms_diffusion.DiffusionVelocityTerm(name, arg_str, integral, region, **kwargs)
Evaluate diffusion velocity.
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
614
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
∫︁
−
𝐾𝑖𝑗 ∇𝑗 𝑝¯
Ω
∫︁
∫︁
vector for 𝐾 ← ℐℎ : −
𝐾𝑖𝑗 ∇𝑗 𝑝¯/
𝑇𝐾
1
𝑇𝐾
−𝐾𝑖𝑗 ∇𝑗 𝑝¯
Call signature
ev_diffusion_velocity
(material, parameter)
Arguments
• material : 𝐾𝑖𝑗
• parameter : 𝑝¯
arg_shapes = {‘material’: ‘D, D’, ‘parameter’: 1}
arg_types = (‘material’, ‘parameter’)
static function(out, grad, mat, vg, fmode)
get_eval_shape(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_diffusion_velocity’
class sfepy.terms.terms_diffusion.LaplaceTerm(name, arg_str, integral, region, **kwargs)
Laplace term with 𝑐 coefficient. Can be evaluated. Can use derivatives.
Definition
∫︁
∫︁
𝑐∇𝑞 · ∇𝑝 ,
Ω
𝑐∇¯
𝑝 · ∇𝑟
Ω
Call signature
dw_laplace
(opt_material, virtual, state)
(opt_material, parameter_1, parameter_2)
Arguments 1
• material : 𝑐
• virtual : 𝑞
• state : 𝑝
Arguments 2
• material : 𝑐
• parameter_1 : 𝑝¯
• parameter_2 : 𝑟
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘state’: 1, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’), ‘parameter_2’: 1}, {‘opt_mater
arg_types = ((‘opt_material’, ‘virtual’, ‘state’), (‘opt_material’, ‘parameter_1’, ‘parameter_2’))
7.8. Module Index
615
SfePy Documentation, Release 2015.1
modes = (‘weak’, ‘eval’)
name = ‘dw_laplace’
set_arg_types()
symbolic = {‘map’: {‘c’: ‘opt_material’, ‘u’: ‘state’}, ‘expression’: ‘c * div( grad( u ) )’}
class sfepy.terms.terms_diffusion.SurfaceFluxOperatorTerm(name, arg_str, integral, region, **kwargs)
Surface flux operator term.
Definition
∫︁
𝑞𝑛 · 𝐾 · ∇𝑝
Γ
Call signature
dw_surface_flux
(opt_material, virtual, state)
Arguments
• material : 𝐾
• virtual : 𝑞
• state : 𝑝
arg_shapes = [{‘opt_material’: ‘D, D’, ‘state’: 1, ‘virtual’: (1, ‘state’)}, {‘opt_material’: None}]
arg_types = (‘opt_material’, ‘virtual’, ‘state’)
function()
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface_extra’
name = ‘dw_surface_flux’
class sfepy.terms.terms_diffusion.SurfaceFluxTerm(name, arg_str,
**kwargs)
Surface flux term.
integral,
region,
Supports ‘eval’, ‘el_avg’ and ‘el’ evaluation modes.
Definition
∫︁
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯
Γ
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯ /
𝑇𝐾
1
𝑇𝐾
∫︁
vector for 𝐾 ← ℐℎ :
𝑛 · 𝐾𝑖𝑗 ∇𝑗 𝑝¯
𝑇𝐾
Call signature
d_surface_flux
(material, parameter)
Arguments
616
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
• material: 𝐾
• parameter: 𝑝¯,
arg_shapes = {‘material’: ‘D, D’, ‘parameter’: 1}
arg_types = (‘material’, ‘parameter’)
function()
get_eval_shape(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
integration = ‘surface_extra’
name = ‘d_surface_flux’
sfepy.terms.terms_dot module
class sfepy.terms.terms_dot.BCNewtonTerm(name, arg_str, integral, region, **kwargs)
Newton boundary condition term.
Definition
∫︁
𝛼𝑞(𝑝 − 𝑝outer )
Γ
Call signature
dw_bc_newton
(material_1, material_2, virtual, state)
Arguments
• material_1 : 𝛼
• material_2 : 𝑝outer
• virtual : 𝑞
• state : 𝑝
arg_shapes = {‘material_1’: ‘1, 1’, ‘material_2’: ‘1, 1’, ‘state’: 1, ‘virtual’: (1, ‘state’)}
arg_types = (‘material_1’, ‘material_2’, ‘virtual’, ‘state’)
check_shapes(alpha, p_outer, virtual, state)
get_fargs(alpha, p_outer, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
mode = ‘weak’
name = ‘dw_bc_newton’
class sfepy.terms.terms_dot.DotProductSurfaceTerm(name, arg_str,
**kwargs)
Surface 𝐿2 (Γ) dot product for both scalar and vector fields.
integral,
region,
Definition
7.8. Module Index
617
SfePy Documentation, Release 2015.1
∫︁
∫︁
Γ
∫︁
∫︁
𝑣·𝑢,
𝑞𝑝 ,
Γ
𝑣 · 𝑛𝑝 ,
Γ
∫︁
∫︁
∫︁
𝑞𝑛 · 𝑢 ,
𝑝𝑟 ,
𝑤 · 𝑛𝑝
𝑢·𝑤,
Γ
∫︁Γ
∫︁ Γ
∫︁
∫︁Γ
𝑐𝑞𝑝 ,
𝑐𝑣 · 𝑢 ,
𝑐𝑝𝑟 ,
𝑐𝑢 · 𝑤
Γ
Γ
Γ
∫︁ Γ
∫︁
𝑢·𝑀 ·𝑤
𝑣·𝑀 ·𝑢,
Γ
Γ
Call signature
dw_surface_dot
(opt_material, virtual, state)
(opt_material, parameter_1, parameter_2)
Arguments 1
• material : 𝑐 or 𝑀 (optional)
• virtual : 𝑞 or 𝑣
• state : 𝑝 or 𝑢
Arguments 2
• material : 𝑐 or 𝑀 (optional)
• parameter_1 : 𝑝 or 𝑢
• parameter_2 : 𝑟 or 𝑤
arg_types = ((‘opt_material’, ‘virtual’, ‘state’), (‘opt_material’, ‘parameter_1’, ‘parameter_2’))
integration = ‘surface’
modes = (‘weak’, ‘eval’)
name = ‘dw_surface_dot’
class sfepy.terms.terms_dot.DotProductVolumeTerm(name,
arg_str,
integral,
region,
**kwargs)
Volume 𝐿2 (Ω) weighted dot product for both scalar and vector fields. Can be evaluated. Can use derivatives.
Definition
∫︁
∫︁
∫︁
∫︁
𝑞𝑝 ,
𝑣·𝑢,
𝑝𝑟 ,
𝑢·𝑤
∫︁ Ω
∫︁ Ω
∫︁ Ω
𝑐𝑞𝑝 ,
𝑐𝑣 · 𝑢 ,
𝑐𝑝𝑟 ,
𝑐𝑢 · 𝑤
Ω
Ω
Ω
Ω
∫︁
∫︁
𝑣·𝑀 ·𝑢,
𝑢·𝑀 ·𝑤
Ω
∫︁
Ω
Ω
Call signature
dw_volume_dot
(opt_material, virtual, state)
(opt_material, parameter_1, parameter_2)
Arguments 1
• material : 𝑐 or 𝑀 (optional)
• virtual : 𝑞 or 𝑣
• state : 𝑝 or 𝑢
Arguments 2
618
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
• material : 𝑐 or 𝑀 (optional)
• parameter_1 : 𝑝 or 𝑢
• parameter_2 : 𝑟 or 𝑤
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘state’: 1, ‘parameter_1’: 1, ‘virtual’: (1, ‘state’), ‘parameter_2’: 1}, {‘opt_mater
arg_types = ((‘opt_material’, ‘virtual’, ‘state’), (‘opt_material’, ‘parameter_1’, ‘parameter_2’))
check_shapes(mat, virtual, state)
static d_dot(out, mat, val1_qp, val2_qp, geo)
static dw_dot(out, mat, val_qp, vgeo, sgeo, fun, fmode)
get_eval_shape(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(mat, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘weak’, ‘eval’)
name = ‘dw_volume_dot’
set_arg_types()
class sfepy.terms.terms_dot.DotSProductVolumeOperatorWETHTerm(name,
arg_str,
integral,
region,
**kwargs)
Fading memory volume 𝐿2 (Ω) weighted dot product for scalar fields. This term has the same definition as
dw_volume_dot_w_scalar_th, but assumes an exponential approximation of the convolution kernel resulting in
much higher efficiency. Can use derivatives.
Definition
∫︁ [︂∫︁
Ω
𝑡
]︂
𝒢(𝑡 − 𝜏 )𝑝(𝜏 ) d𝜏 𝑞
0
Call signature
dw_volume_dot_w_scalar_eth
(ts, material_0, material_1, virtual, state)
Arguments
• ts : TimeStepper instance
• material_0 : 𝒢(0)
• material_1 : exp(−𝜆∆𝑡) (decay at 𝑡1 )
• virtual : 𝑞
• state : 𝑝
arg_types = (‘ts’, ‘material_0’, ‘material_1’, ‘virtual’, ‘state’)
function()
get_fargs(ts, mat0, mat1, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_volume_dot_w_scalar_eth’
class sfepy.terms.terms_dot.DotSProductVolumeOperatorWTHTerm(name,
integral,
**kwargs)
Fading memory volume 𝐿2 (Ω) weighted dot product for scalar fields. Can use derivatives.
7.8. Module Index
arg_str,
region,
619
SfePy Documentation, Release 2015.1
Definition
𝑡
∫︁ [︂∫︁
Ω
]︂
𝒢(𝑡 − 𝜏 )𝑝(𝜏 ) d𝜏 𝑞
0
Call signature
dw_volume_dot_w_scalar_th
(ts, material, virtual, state)
Arguments
• ts : TimeStepper instance
• material : 𝒢(𝜏 )
• virtual : 𝑞
• state : 𝑝
arg_types = (‘ts’, ‘material’, ‘virtual’, ‘state’)
function()
get_fargs(ts, mats, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_volume_dot_w_scalar_th’
class sfepy.terms.terms_dot.ScalarDotGradIScalarTerm(name, arg_str, integral, region,
**kwargs)
Dot product of a scalar and the 𝑖-th component of gradient of a scalar. The index should be given as a ‘special_constant’ material parameter.
Definition
𝑖
∫︁
𝑍 =
𝑞∇𝑖 𝑝
Ω
Call signature
dw_s_dot_grad_i_s
(material, virtual, state)
Arguments
• material : 𝑖
• virtual : 𝑞
• state : 𝑝
arg_shapes = {‘state’: 1, ‘material’: ‘1, 1’, ‘virtual’: (1, ‘state’)}
arg_types = (‘material’, ‘virtual’, ‘state’)
static dw_fun(out, bf, vg, grad, idx, fmode)
get_fargs(material, virtual, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘dw_s_dot_grad_i_s’
set_arg_types()
class sfepy.terms.terms_dot.VectorDotGradScalarTerm(name, arg_str, integral, region,
**kwargs)
Volume dot product of a vector and a gradient of scalar. Can be evaluated.
620
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
Definition
∫︁
∫︁
𝑣 · ∇𝑝 ,
𝑢 · ∇𝑞
∫︁ Ω
𝑐𝑢 · ∇𝑞
𝑐𝑣 · ∇𝑝 ,
Ω
Ω
∫︁
∫︁
𝑣 · 𝑀 · ∇𝑝 ,
𝑢 · 𝑀 · ∇𝑞
Ω
∫︁
Ω
Ω
Call signature
dw_v_dot_grad_s
(opt_material, virtual, state)
(opt_material, state, virtual)
(opt_material, parameter_v, parameter_s)
Arguments 1
• material : 𝑐 or 𝑀 (optional)
• virtual : 𝑣
• state : 𝑝
Arguments 2
• material : 𝑐 or 𝑀 (optional)
• state : 𝑢
• virtual : 𝑞
Arguments 3
• material : 𝑐 or 𝑀 (optional)
• parameter_v : 𝑢
• parameter_s : 𝑝
arg_shapes = [{‘opt_material’: ‘1, 1’, ‘state/s_weak’: ‘D’, ‘parameter_s’: 1, ‘virtual/v_weak’: (‘D’, None), ‘virtual/s_we
arg_types = ((‘opt_material’, ‘virtual’, ‘state’), (‘opt_material’, ‘state’, ‘virtual’), (‘opt_material’, ‘parameter_v’, ‘para
check_shapes(coef, vvar, svar)
get_eval_shape(coef, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(coef, vvar, svar, mode=None, term_mode=None, diff_var=None, **kwargs)
modes = (‘v_weak’, ‘s_weak’, ‘eval’)
name = ‘dw_v_dot_grad_s’
set_arg_types()
sfepy.terms.terms_elastic module
class sfepy.terms.terms_elastic.CauchyStrainSTerm(name, arg_str,
**kwargs)
Evaluate Cauchy strain tensor on a surface region.
integral,
region,
See CauchyStrainTerm.
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
7.8. Module Index
621
SfePy Documentation, Release 2015.1
Definition
∫︁
𝑒(𝑤)
Γ
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑒(𝑤)/
𝑇𝐾
1
𝑇𝐾
𝑒(𝑤)|𝑞𝑝
Call signature
ev_cauchy_strain_s
(parameter)
Arguments
• parameter : 𝑤
arg_types = (‘parameter’,)
integration = ‘surface_extra’
name = ‘ev_cauchy_strain_s’
class sfepy.terms.terms_elastic.CauchyStrainTerm(name,
arg_str,
**kwargs)
Evaluate Cauchy strain tensor.
integral,
region,
It is given in the usual vector form exploiting symmetry: in 3D it has 6 components with the indices ordered
as [11, 22, 33, 12, 13, 23], in 2D it has 3 components with the indices ordered as [11, 22, 12]. The last three
(non-diagonal) components are doubled so that it is energetically conjugate to the Cauchy stress tensor with the
same storage.
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
∫︁
𝑒(𝑤)
Ω
∫︁
vector for 𝐾 ← ℐℎ :
∫︁
𝑒(𝑤)/
𝑇𝐾
1
𝑇𝐾
𝑒(𝑤)|𝑞𝑝
Call signature
ev_cauchy_strain
(parameter)
Arguments
• parameter : 𝑤
arg_shapes = {‘parameter’: ‘D’}
arg_types = (‘parameter’,)
static function(out, strain, vg, fmode)
622
Chapter 7. Developer Guide
SfePy Documentation, Release 2015.1
get_eval_shape(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_cauchy_strain’
class sfepy.terms.terms_elastic.CauchyStressETHTerm(name, arg_str, integral, region,
**kwargs)
Evaluate fading memory Cauchy stress tensor.
It is given in the usual vector form exploiting symmetry: in 3D it has 6 components with the indices ordered as
[11, 22, 33, 12, 13, 23], in 2D it has 3 components with the indices ordered as [11, 22, 12].
Assumes an exponential approximation of the convolution kernel resulting in much higher efficiency.
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
∫︁ ∫︁
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏
Ω
0
∫︁
∫︁
𝑡
vector for 𝐾 ← ℐℎ :
𝑇𝐾
∫︁
∫︁
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 /
0
1
𝑇𝐾
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 |𝑞𝑝
0
Call signature
ev_cauchy_stress_eth
(ts, material_0, material_1, parameter)
Arguments
• ts : TimeStepper instance
• material_0 : ℋ𝑖𝑗𝑘𝑙 (0)
• material_1 : exp(−𝜆∆𝑡) (decay at 𝑡1 )
• parameter : 𝑤
arg_shapes = {}
arg_types = (‘ts’, ‘material_0’, ‘material_1’, ‘parameter’)
get_eval_shape(ts, mat0, mat1, parameter, mode=None, term_mode=None, diff_var=None,
**kwargs)
get_fargs(ts, mat0, mat1, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_cauchy_stress_eth’
class sfepy.terms.terms_elastic.CauchyStressTHTerm(name, arg_str,
**kwargs)
Evaluate fading memory Cauchy stress tensor.
integral,
region,
It is given in the usual vector form exploiting symmetry: in 3D it has 6 components with the indices ordered as
[11, 22, 33, 12, 13, 23], in 2D it has 3 components with the indices ordered as [11, 22, 12].
Supports ‘eval’, ‘el_avg’ and ‘qp’ evaluation modes.
Definition
7.8. Module Index
623
SfePy Documentation, Release 2015.1
∫︁ ∫︁
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏
Ω
0
∫︁
𝑡
∫︁
vector for 𝐾 ← ℐℎ :
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 /
0
𝑇𝐾
∫︁
∫︁
1
𝑇𝐾
𝑡
ℋ𝑖𝑗𝑘𝑙 (𝑡 − 𝜏 ) 𝑒𝑘𝑙 (𝑤(𝜏 )) d𝜏 |𝑞𝑝
0
Call signature
ev_cauchy_stress_th
(ts, material, parameter)
Arguments
• ts : TimeStepper instance
• material : ℋ𝑖𝑗𝑘𝑙 (𝜏 )
• parameter : 𝑤
arg_shapes = {}
arg_types = (‘ts’, ‘material’, ‘parameter’)
get_eval_shape(ts, mats, parameter, mode=None, term_mode=None, diff_var=None, **kwargs)
get_fargs(ts, mats, state, mode=None, term_mode=None, diff_var=None, **kwargs)
name = ‘ev_cauchy_stress_th’
class sfepy.terms.terms_elastic.CauchyStressTerm(name,
arg_str,
**kwargs)
Evaluate Cauchy stress tensor.
integral,
region,
It is given in the usual vector form exploiting symmetry: in 3D it has 6 components with the indices ordered as
[11, 22,