Hans Petter Langtangen · Svein Linge Finite Diff erence Computing … · Hans Petter Langtangen Lysaker, Norway Svein Linge Process, Energy & Environmental Technology University
Upload
others
View
9
Download
0
Embed Size (px)
344 x 292
429 x 357
514 x 422
599 x 487
Citation preview
Hans Petter Langtangen · Svein Linge
Finite Diff erence Computing with PDEs A Modern Software Approach
Editorial Board
T. J. Barth M. Griebel D. E. Keyes
R. M. Nieminen D. Roose
T. Schlick
Editors
Timothy J. Barth Michael Griebel David E. Keyes Risto M. Nieminen
Dirk Roose Tamar Schlick
More information about this series at
http://www.springer.com/series/5151
AModern Software Approach
Svein Linge Process, Energy & Environmental Technology
University College of Southeast Norway Porsgrunn, Norway
ISSN 1611-0994 Texts in Computational Science and Engineering ISBN
978-3-319-55455-6 ISBN 978-3-319-55456-3 (eBook) DOI
10.1007/978-3-319-55456-3
Library of Congress Control Number: 2017942747
Mathematic Subject Classification (2010): 34, 35, 65, 68
© The Editor(s) (if applicable) and The Author(s) 2017 This book is
an open access publication Open Access This book is distributed
under the terms of the Creative Commons Attribution 4.0 Interna-
tional License (http://creativecommons.org/licenses/by/4.0/),which
permits use, duplication, adaptation, distribution and reproduction
in any medium or format, as long as you give appropriate credit to
the orig- inal author(s) and the source, provide a link to the
Creative Commons license and indicate if changes were made. The
images or other third party material in this book are included in
the work’s Creative Commons li- cense, unless indicated otherwise
in the credit line; if such material is not included in the work’s
Creative Commons license and the respective action is not permitted
by statutory regulation, users will need to obtain permission from
the license holder to duplicate, adapt or reproduce the material.
The use of general descriptive names, registered names, trademarks,
service marks, etc. in this publica- tion does not imply, even in
the absence of a specific statement, that such names are exempt
from the relevant protective laws and regulations and therefore
free for general use. The publisher, the authors and the editors
are safe to assume that the advice and information in this book are
believed to be true and accurate at the date of publication.
Neither the publisher nor the authors or the editors give a
warranty, express or implied, with respect to the material
contained herein or for any errors or omissions that may have been
made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
Printed on acid-free paper
This Springer imprint is published by Springer Nature The
registered company is Springer International Publishing AG The
registered company address is: Gewerbestrasse 11, 6330 Cham,
Switzerland
There are so many excellent books on finite difference methods for
ordinary and partial differential equations that writing yet
another one requires a different view on the topic. The present
book is not so concerned with the traditional academic presentation
of the topic, but is focused at teaching the practitioner how to
obtain reliable computations involving finite difference methods.
This focus is based on a set of learning outcomes:
1. understanding of the ideas behind finite difference methods, 2.
understanding how to transform an algorithm to a well-designed
computer code, 3. understanding how to test (verify) the code, 4.
understanding potential artifacts in simulation results.
Compared to other textbooks, the present one has a particularly
strong emphasis on computer implementation and verification. It
also has a strong emphasis on an intuitive understanding of
constructing finite difference methods. To learn about the
potential non-physical artifacts of various methods, we study exact
solutions of finite difference schemes as these give deeper insight
into the physical behavior of the numerical methods than the
traditional (and more general) asymptotic error analysis. However,
asymptotic results regarding convergence rates, typically trun-
cation errors, are crucial for testing implementations, so an
extensive appendix is devoted to the computation of truncation
errors.
Why finite differences? One may ask why we do finite differences
when finite element and finite volume methods have been developed
to greater generality and sophistication than finite differences
and can cover more problems. The finite ele- ment and finite volume
methods are also the industry standard nowadays. Why not just those
methods? The reason for finite differences is the method’s
simplicity, both from a mathematical and coding perspective.
Especially in academia, where simple model problems are used a lot
for teaching and in research (e.g., for verification of advanced
implementations), there is a constant need to solve the model
problems from scratch with easy-to-verify computer codes. Here,
finite differences are ideal. A simple 1D heat equation can of
course be solved by a finite element package, but a 20-line code
with a difference scheme is just right to the point and provides
an
v
vi Preface
understanding of all details involved in the model and the solution
method. Every- body nowadays has a laptop and the natural method to
attack a 1D heat equation is a simple Python or Matlab program with
a difference scheme. The conclusion goes for other fundamental PDEs
like the wave equation and Poisson equation as long as the geometry
of the domain is a hypercube. The present book contains all the
practical information needed to use the finite difference tool in a
safe way.
Various pedagogical elements are utilized to reach the learning
outcomes, and these are commented upon next.
Simplify, understand, generalize The book’s overall pedagogical
philosophy is the three-step process of first simplifying the
problem to something we can under- stand in detail, and when that
understanding is in place, we can generalize and hopefully address
real-world applications with a sound scientific problem-solving
approach. For example, in the chapter on a particular family of
equations we first simplify the problem in question to a 1D,
constant-coefficient equation with simple boundary conditions. We
learn how to construct a finite difference method, how to implement
it, and how to understand the behavior of the numerical solution.
Then we can generalize to higher dimensions, variable coefficients,
a source term, and more complicated boundary conditions. The
solution of a compound problem is in this way an assembly of
elements that are well understood in simpler settings.
Constructive mathematics This text favors a constructive approach
to mathemat- ics. Instead of a set of definitions followed by
popping up a method, we emphasize how to think about the
construction of a method. The aim is to obtain a good intu- itive
understanding of the mathematical methods.
The text is written in an easy-to-read style much inspired by the
following quote.
Some people think that stiff challenges are the best device to
induce learning, but I am not one of them. The natural way to learn
something is by spending vast amounts of easy, enjoyable time at
it. This goes whether you want to speak German, sight-read at the
piano, type, or do mathematics. Give me the German storybook for
fifth graders that I feel like reading in bed, not Goethe and a
dictionary. The latter will bring rapid progress at first, then
exhaustion and failure to resolve.
The main thing to be said for stiff challenges is that inevitably
we will encounter them, so we had better learn to face them boldly.
Putting them in the curriculum can help teach us to do so. But for
teaching the skill or subject matter itself, they are overrated.
[18, p. 86] Lloyd N. Trefethen, Applied Mathematician, 1955-.
This book assumes some basic knowledge of finite difference
approximations, differential equations, and scientific Python or
MATLAB programming, as often met in an introductory numerical
methods course. Readers without this background may start with the
light companion book “Finite Difference Computing with Expo-
nential Decay Models” [9]. That book will in particular be a useful
resource for the programming parts of the present book. Since the
present book deals with partial differential equations, the reader
is assumed to master multi-variable calculus and linear
algebra.
Fundamental ideas and their associated scientific details are first
introduced in the simplest possible differential equation setting,
often an ordinary differential equation, but in a way that easily
allows reuse in more complex settings with par- tial differential
equations. With this approach, new concepts are introduced with
a
Preface vii
minimum of mathematical details. The text should therefore have a
potential for use early in undergraduate student programs.
All nuts and bolts Many have experienced that “vast amounts of
easy, enjoyable time”, as stated in the quote above, arises when
mathematics is implemented on a computer. The implementation
process triggers understanding, creativity, and curiosity, but many
students find the transition from a mathematical algorithm to a
working code difficult and spend a lot of time on “programming
issues”.
Most books on numerical methods concentrate on the mathematics of
the subject while details on going from the mathematics to a
computer implementation are less in focus. A major purpose of this
text is therefore to help the practitioner by providing all nuts
and bolts necessary for safely going from the mathematics to a
well-designed and well-tested computer code. A significant portion
of the text is consequently devoted to programming details.
Python as programming language While MATLAB enjoys widespread
popular- ity in books on numerical methods, we have chosen to use
the Python programming language. Python is very similar to MATLAB,
but contains a lot of modern soft- ware engineering tools that have
become standard in the software industry and that should be adopted
also for numerical computing projects. Python is at present also
experiencing an exponential growth in popularity within the
scientific computing community. One of the book’s goals is to
present an up-to-date Python eco system for implementing finite
difference methods.
Program verification Program testing, called verification, is a key
topic of the book. Good verification techniques are indispensable
when debugging computer code, but also fundamental for achieving
reliable simulations. Two verification techniques saturate the
book: exact solution of discrete equations (where the ap-
proximation error vanishes) and empirical estimation of convergence
rates in prob- lems with exact (analytical or manufactured)
solutions of the differential equa- tion(s).
Vectorized code Finite difference methods lead to code with loops
over large ar- rays. Such code in plain Python is known to run
slowly. We demonstrate, especially in Appendix C, how to port loops
to fast, compiled code in C or Fortran. However, an alternative is
to vectorize the code to get rid of explicit Python loops, and this
technique is met throughout the book. Vectorization becomes closely
connected to the underlying array library, here numpy, and is often
thought of as a difficult sub- ject by students. Through numerous
examples in different contexts, we hope that the present book
provides a substantial contribution to explaining how algorithms
can be vectorized. Not only will this speed up serial code, but
with a library that can produce parallel code from numpy commands
(such as Numba1), vectorized code can be automatically turned into
parallel code and utilize multi-core processors and GPUs. Also when
creating tailored parallel code for today’s supercomputers, vec-
torization is useful as it emphasizes splitting up an algorithm
into plain and simple
1 http://numba.pydata.org
array operations, where each operation is trivial to parallelize
efficiently, rather than trying to develop a “smart” overall
parallelization strategy.
Analysis via exact solutions of discrete equations Traditional
asymptotic analy- sis of errors is important for verification of
code using convergence rates, but gives a limited understanding of
how and why a correctly implemented numerical method may give
non-physical results. By developing exact solutions, usually based
on Fourier methods, of the discrete equations, one can obtain a
physical understanding of the behavior of a numerical method. This
approach is favored for analysis of methods in this book.
Code-inspired mathematical notation Our primary aim is to have a
clean and easy-to-read computer code, and we want a close
one-to-one relationship between the computer code and mathematical
description of the algorithm. This principle calls for a
mathematical notation that is governed by the natural notation in
the computer code. The unknown is mostly called u, but the meaning
of the symbol u in the mathematical description changes as we go
from the exact solution fulfilling the differential equation to the
symbol u that is naturally used for the associated data structure
in the code.
Limited scope The aim of this book is not to give an overview of a
lot of methods for a wide range of mathematical models. Such
information can be found in numer- ous existing, more advanced
books. The aim is rather to introduce basic concepts and a thorough
understanding of how to think about computing with finite differ-
ence methods. We therefore go in depth with only the most
fundamental methods and equations. However, we have a
multi-disciplinary scope and address the inter- play of
mathematics, numerics, computer science, and physics.
Focus on wave phenomena Most books on finite difference methods, or
books on theory with computer examples, have their emphasis on
diffusion phenomena. Half of this book (Chap. 1, 2, and Appendix C)
is devoted to wave phenomena. Extended material on this topic is
not so easy find in the literature, so the book should be a
valuable contribution in this respect. Wave phenomena is also a
good topic in general for choosing the finite difference method
over other discretization methods since one quickly needs fine
resolution over the entire mesh and uniform meshes are most
natural.
Instead of introducing the finite difference method for diffusion
problems, where one soon ends up with matrix systems, we do the
introduction in a wave phenomena setting where explicit schemes are
most relevant. This slows down the learning curve since we can
introduce a lot of theory for differences and for software aspects
in a context with simple, explicit stencils for updating the
solution.
Independent chapters Most book authors are careful with avoiding
repetitions of material. The chapters in this book, however,
contain some overlap, because we want the chapters to appear
meaningful on their own. Modern publishing technol- ogy makes it
easy to take selected chapters from different books to make a new
book tailored to a specific course. The more a chapter builds on
details in other chapters, the more difficult it is to reuse
chapters in new contexts. Also, most readers find it
Preface ix
convenient that important information is explicitly stated, even if
it was already met in another chapter.
Supplementary materials All program and data files referred to in
this book are available from the book’s primary web site: URL:
http://github.com/hplgit/fdm- book/.
Acknowledgments Professor Kent-Andre Mardal at the University of
Oslo has kindly contributed to enlightening discussions on several
issues. Many students have provided lots of useful feedback on the
exposition and found many errors in the text. Special efforts in
this regard were made by Imran Ali, Shirin Fallahi, Anders
Hafreager, Daniel Alexander Mo Søreide Houshmand, Kristian
Gregorius Hustad, Mathilde Nygaard Kamperud, and Fatemeh Miri. The
collaboration with the Springer team, with Dr. Martin Peters,
Thanh-Ha Le Thi, and their production staff has always been a great
pleasure and a very efficient process.
Finally, want really appreciate the strong push from the COE of
Simula Research Laboratory, Aslak Tveito, for publishing and
financing books in open access format, including this one. We are
grateful for the laboratory’s financial contribution as well as to
the financial contribution from the Department of Process, Energy
and Environmental Technology at the University College of Southeast
Norway.
Oslo, July 2016 Hans Petter Langtangen, Svein Linge
1 Vibration ODEs . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 1 1.1 Finite Difference Discretization . . . . .
. . . . . . . . . . . . . . . . . 1
1.1.1 A Basic Model for Vibrations . . . . . . . . . . . . . . . .
. 1 1.1.2 A Centered Finite Difference Scheme . . . . . . . . . . .
. 2
1.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 4 1.2.1 Making a Solver Function . . . . . . . . . .
. . . . . . . . . . 4 1.2.2 Verification . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . 6 1.2.3 Scaled Model . . . . . . .
. . . . . . . . . . . . . . . . . . . . 10
1.3 Visualization of Long Time Simulations . . . . . . . . . . . .
. . . . 11 1.3.1 Using a Moving Plot Window . . . . . . . . . . . .
. . . . . 11 1.3.2 Making Animations . . . . . . . . . . . . . . .
. . . . . . . . . 13 1.3.3 Using Bokeh to Compare Graphs . . . . .
. . . . . . . . . . 15 1.3.4 Using a Line-by-Line Ascii Plotter . .
. . . . . . . . . . . . 18 1.3.5 Empirical Analysis of the Solution
. . . . . . . . . . . . . . 19
1.4 Analysis of the Numerical Scheme . . . . . . . . . . . . . . .
. . . . . 21 1.4.1 Deriving a Solution of the Numerical Scheme . .
. . . . . 21 1.4.2 The Error in the Numerical Frequency . . . . . .
. . . . . . 22 1.4.3 Empirical Convergence Rates and Adjusted ! . .
. . . . . 24 1.4.4 Exact Discrete Solution . . . . . . . . . . . .
. . . . . . . . . 24 1.4.5 Convergence . . . . . . . . . . . . . .
. . . . . . . . . . . . . . 24 1.4.6 The Global Error . . . . . . .
. . . . . . . . . . . . . . . . . . 25 1.4.7 Stability . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . 26 1.4.8 About
the Accuracy at the Stability Limit . . . . . . . . . . 27
1.5 Alternative Schemes Based on 1st-Order Equations . . . . . . .
. . 29 1.5.1 The Forward Euler Scheme . . . . . . . . . . . . . . .
. . . . 29 1.5.2 The Backward Euler Scheme . . . . . . . . . . . .
. . . . . . 30 1.5.3 The Crank-Nicolson Scheme . . . . . . . . . .
. . . . . . . . 30 1.5.4 Comparison of Schemes . . . . . . . . . .
. . . . . . . . . . . 32 1.5.5 Runge-Kutta Methods . . . . . . . .
. . . . . . . . . . . . . . 33 1.5.6 Analysis of the Forward Euler
Scheme . . . . . . . . . . . . 34
1.6 Energy Considerations . . . . . . . . . . . . . . . . . . . . .
. . . . . . 36 1.6.1 Derivation of the Energy Expression . . . . .
. . . . . . . . 36 1.6.2 An Error Measure Based on Energy . . . . .
. . . . . . . . . 38
xi
xii Contents
1.7 The Euler-Cromer Method . . . . . . . . . . . . . . . . . . . .
. . . . . 40 1.7.1 Forward-Backward Discretization . . . . . . . .
. . . . . . . 40 1.7.2 Equivalence with the Scheme for the
Second-Order ODE 42 1.7.3 Implementation . . . . . . . . . . . . .
. . . . . . . . . . . . . 43 1.7.4 The Störmer-Verlet Algorithm . .
. . . . . . . . . . . . . . . 45
1.8 Staggered Mesh . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 46 1.8.1 The Euler-Cromer Scheme on a Staggered Mesh
. . . . . . 46 1.8.2 Implementation of the Scheme on a Staggered
Mesh . . . 48
1.9 Exercises and Problems . . . . . . . . . . . . . . . . . . . .
. . . . . . 50 1.10 Generalization: Damping, Nonlinearities, and
Excitation . . . . . . 57
1.10.1 A Centered Scheme for Linear Damping . . . . . . . . . . .
57 1.10.2 A Centered Scheme for Quadratic Damping . . . . . . . . .
58 1.10.3 A Forward-Backward Discretization of the Quadratic
Damping Term . . . . . . . . . . . . . . . . . . . . . . . . . . .
59 1.10.4 Implementation . . . . . . . . . . . . . . . . . . . . .
. . . . . 59 1.10.5 Verification . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . 60 1.10.6 Visualization . . . . . . . . . .
. . . . . . . . . . . . . . . . . . 61 1.10.7 User Interface . . .
. . . . . . . . . . . . . . . . . . . . . . . . 62 1.10.8 The
Euler-Cromer Scheme for the Generalized Model . . 63 1.10.9 The
Störmer-Verlet Algorithm for the Generalized Model 64 1.10.10 A
Staggered Euler-Cromer Scheme for a Generalized
Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 64 1.10.11 The PEFRL 4th-Order Accurate Algorithm . . . . . . . .
. 65
1.11 Exercises and Problems . . . . . . . . . . . . . . . . . . . .
. . . . . . 66 1.12 Applications of Vibration Models . . . . . . .
. . . . . . . . . . . . . 67
1.12.1 Oscillating Mass Attached to a Spring . . . . . . . . . . .
. 67 1.12.2 General Mechanical Vibrating System . . . . . . . . . .
. . 69 1.12.3 A Sliding Mass Attached to a Spring . . . . . . . . .
. . . . 70 1.12.4 A Jumping Washing Machine . . . . . . . . . . . .
. . . . . 71 1.12.5 Motion of a Pendulum . . . . . . . . . . . . .
. . . . . . . . . 71 1.12.6 Dynamic Free Body Diagram During
Pendulum Motion . 74 1.12.7 Motion of an Elastic Pendulum . . . . .
. . . . . . . . . . . . 79 1.12.8 Vehicle on a Bumpy Road . . . . .
. . . . . . . . . . . . . . . 83 1.12.9 Bouncing Ball . . . . . . .
. . . . . . . . . . . . . . . . . . . . 85 1.12.10 Two-Body
Gravitational Problem . . . . . . . . . . . . . . . 85 1.12.11
Electric Circuits . . . . . . . . . . . . . . . . . . . . . . . . .
. 88
1.13 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 88
2 Wave Equations . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 93 2.1 Simulation of Waves on a String . . . . .
. . . . . . . . . . . . . . . . 93
2.1.1 Discretizing the Domain . . . . . . . . . . . . . . . . . . .
. . 94 2.1.2 The Discrete Solution . . . . . . . . . . . . . . . .
. . . . . . 94 2.1.3 Fulfilling the Equation at the Mesh Points . .
. . . . . . . . 94 2.1.4 Replacing Derivatives by Finite
Differences . . . . . . . . . 95 2.1.5 Formulating a Recursive
Algorithm . . . . . . . . . . . . . . 96 2.1.6 Sketch of an
Implementation . . . . . . . . . . . . . . . . . . 98
2.2 Verification . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 99 2.2.1 A Slightly Generalized Model Problem . .
. . . . . . . . . 99 2.2.2 Using an Analytical Solution of Physical
Significance . . 99
Contents xiii
2.2.3 Manufactured Solution and Estimation of Convergence Rates . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
100
2.2.4 Constructing an Exact Solution of the Discrete Equations 102
2.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 104
2.3.1 Callback Function for User-Specific Actions . . . . . . . .
104 2.3.2 The Solver Function . . . . . . . . . . . . . . . . . . .
. . . . 105 2.3.3 Verification: Exact Quadratic Solution . . . . .
. . . . . . . 106 2.3.4 Verification: Convergence Rates . . . . . .
. . . . . . . . . . 107 2.3.5 Visualization: Animating the Solution
. . . . . . . . . . . . 108 2.3.6 Running a Case . . . . . . . . .
. . . . . . . . . . . . . . . . . 112 2.3.7 Working with a Scaled
PDE Model . . . . . . . . . . . . . . 113
2.4 Vectorization . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 114 2.4.1 Operations on Slices of Arrays . . . . .
. . . . . . . . . . . . 115 2.4.2 Finite Difference Schemes
Expressed as Slices . . . . . . . 117 2.4.3 Verification . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . 118 2.4.4
Efficiency Measurements . . . . . . . . . . . . . . . . . . . . 119
2.4.5 Remark on the Updating of Arrays . . . . . . . . . . . . . .
121
2.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 122 2.6 Generalization: Reflecting Boundaries . . .
. . . . . . . . . . . . . . 125
2.6.1 Neumann Boundary Condition . . . . . . . . . . . . . . . . .
126 2.6.2 Discretization of Derivatives at the Boundary . . . . . .
. . 126 2.6.3 Implementation of Neumann Conditions . . . . . . . .
. . . 127 2.6.4 Index Set Notation . . . . . . . . . . . . . . . .
. . . . . . . . 128 2.6.5 Verifying the Implementation of Neumann
Conditions . . 130 2.6.6 Alternative Implementation via Ghost Cells
. . . . . . . . . 132
2.7 Generalization: Variable Wave Velocity . . . . . . . . . . . .
. . . . . 135 2.7.1 The Model PDE with a Variable Coefficient . . .
. . . . . . 135 2.7.2 Discretizing the Variable Coefficient . . . .
. . . . . . . . . 136 2.7.3 Computing the Coefficient Between Mesh
Points . . . . . 137 2.7.4 How a Variable Coefficient Affects the
Stability . . . . . . 138 2.7.5 Neumann Condition and a Variable
Coefficient . . . . . . . 138 2.7.6 Implementation of Variable
Coefficients . . . . . . . . . . . 139 2.7.7 A More General PDE
Model with Variable Coefficients . 140 2.7.8 Generalization:
Damping . . . . . . . . . . . . . . . . . . . . 140
2.8 Building a General 1D Wave Equation Solver . . . . . . . . . .
. . . 141 2.8.1 User Action Function as a Class . . . . . . . . . .
. . . . . . 142 2.8.2 Pulse Propagation in Two Media . . . . . . .
. . . . . . . . . 144
2.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 148 2.10 Analysis of the Difference Equations . . .
. . . . . . . . . . . . . . . 155
2.10.1 Properties of the Solution of the Wave Equation . . . . . .
155 2.10.2 More Precise Definition of Fourier Representations . . .
. 157 2.10.3 Stability . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 158 2.10.4 Numerical Dispersion Relation . . . .
. . . . . . . . . . . . . 160 2.10.5 Extending the Analysis to 2D
and 3D . . . . . . . . . . . . . 163
2.11 Finite Difference Methods for 2D and 3D Wave Equations . . . .
. 167 2.11.1 Multi-Dimensional Wave Equations . . . . . . . . . . .
. . . 167 2.11.2 Mesh . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 168 2.11.3 Discretization . . . . . . . . . . .
. . . . . . . . . . . . . . . . 169
xiv Contents
2.12 Implementation . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 171 2.12.1 Scalar Computations . . . . . . . . . . .
. . . . . . . . . . . . 172 2.12.2 Vectorized Computations . . . .
. . . . . . . . . . . . . . . . 174 2.12.3 Verification . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . 176 2.12.4
Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 177
2.13 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 181 2.14 Applications of Wave Equations . . . . .
. . . . . . . . . . . . . . . . 183
2.14.1 Waves on a String . . . . . . . . . . . . . . . . . . . . .
. . . . 183 2.14.2 Elastic Waves in a Rod . . . . . . . . . . . . .
. . . . . . . . . 186 2.14.3 Waves on a Membrane . . . . . . . . .
. . . . . . . . . . . . . 186 2.14.4 The Acoustic Model for Seismic
Waves . . . . . . . . . . . 186 2.14.5 Sound Waves in Liquids and
Gases . . . . . . . . . . . . . . 188 2.14.6 Spherical Waves . . .
. . . . . . . . . . . . . . . . . . . . . . . 189 2.14.7 The Linear
Shallow Water Equations . . . . . . . . . . . . . 190 2.14.8 Waves
in Blood Vessels . . . . . . . . . . . . . . . . . . . . . 192
2.14.9 Electromagnetic Waves . . . . . . . . . . . . . . . . . . .
. . 194
2.15 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 195
3 Diffusion Equations . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 207 3.1 An Explicit Method for the 1D Diffusion
Equation . . . . . . . . . . 208
3.1.1 The Initial-Boundary Value Problem for 1D Diffusion . . 208
3.1.2 Forward Euler Scheme . . . . . . . . . . . . . . . . . . . .
. . 208 3.1.3 Implementation . . . . . . . . . . . . . . . . . . .
. . . . . . . 210 3.1.4 Verification . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . 212 3.1.5 Numerical Experiments . . . .
. . . . . . . . . . . . . . . . . 215
3.2 Implicit Methods for the 1D Diffusion Equation . . . . . . . .
. . . 218 3.2.1 Backward Euler Scheme . . . . . . . . . . . . . . .
. . . . . . 219 3.2.2 Sparse Matrix Implementation . . . . . . . .
. . . . . . . . . 223 3.2.3 Crank-Nicolson Scheme . . . . . . . . .
. . . . . . . . . . . . 224 3.2.4 The Unifying Rule . . . . . . . .
. . . . . . . . . . . . . . . 226 3.2.5 Experiments . . . . . . . .
. . . . . . . . . . . . . . . . . . . . 227 3.2.6 The Laplace and
Poisson Equation . . . . . . . . . . . . . . 227
3.3 Analysis of Schemes for the Diffusion Equation . . . . . . . .
. . . 229 3.3.1 Properties of the Solution . . . . . . . . . . . .
. . . . . . . . 229 3.3.2 Analysis of Discrete Equations . . . . .
. . . . . . . . . . . . 233 3.3.3 Analysis of the Finite Difference
Schemes . . . . . . . . . . 233 3.3.4 Analysis of the Forward Euler
Scheme . . . . . . . . . . . . 234 3.3.5 Analysis of the Backward
Euler Scheme . . . . . . . . . . . 236 3.3.6 Analysis of the
Crank-Nicolson Scheme . . . . . . . . . . . 237 3.3.7 Analysis of
the Leapfrog Scheme . . . . . . . . . . . . . . . 237 3.3.8 Summary
of Accuracy of Amplification Factors . . . . . . 238 3.3.9 Analysis
of the 2D Diffusion Equation . . . . . . . . . . . . 239 3.3.10
Explanation of Numerical Artifacts . . . . . . . . . . . . . .
241
3.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 242 3.5 Diffusion in Heterogeneous Media . . . . .
. . . . . . . . . . . . . . . 245
3.5.1 Discretization . . . . . . . . . . . . . . . . . . . . . . .
. . . . 245 3.5.2 Implementation . . . . . . . . . . . . . . . . .
. . . . . . . . . 246 3.5.3 Stationary Solution . . . . . . . . . .
. . . . . . . . . . . . . . 247
Contents xv
3.5.4 Piecewise Constant Medium . . . . . . . . . . . . . . . . . .
247 3.5.5 Implementation of Diffusion in a Piecewise Constant
Medium . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 248 3.5.6 Axi-Symmetric Diffusion . . . . . . . . . . . . . . . .
. . . . 251 3.5.7 Spherically-Symmetric Diffusion . . . . . . . . .
. . . . . . 252
3.6 Diffusion in 2D . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 254 3.6.1 Discretization . . . . . . . . . . . . .
. . . . . . . . . . . . . . 254 3.6.2 Numbering of Mesh Points
Versus Equations and
Unknowns . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
255 3.6.3 Algorithm for Setting Up the Coefficient Matrix . . . . .
. 259 3.6.4 Implementation with a Dense Coefficient Matrix . . . .
. . 260 3.6.5 Verification: Exact Numerical Solution . . . . . . .
. . . . . 264 3.6.6 Verification: Convergence Rates . . . . . . . .
. . . . . . . . 265 3.6.7 Implementation with a Sparse Coefficient
Matrix . . . . . 266 3.6.8 The Jacobi Iterative Method . . . . . .
. . . . . . . . . . . . 270 3.6.9 Implementation of the Jacobi
Method . . . . . . . . . . . . . 273 3.6.10 Test Problem: Diffusion
of a Sine Hill . . . . . . . . . . . . 274 3.6.11 The Relaxed
Jacobi Method and Its Relation to the
Forward Euler Method . . . . . . . . . . . . . . . . . . . . . .
276 3.6.12 The Gauss-Seidel and SOR Methods . . . . . . . . . . . .
. 277 3.6.13 Scalar Implementation of the SOR Method . . . . . . .
. . 277 3.6.14 Vectorized Implementation of the SOR Method . . . .
. . 278 3.6.15 Direct Versus Iterative Methods . . . . . . . . . .
. . . . . . 282 3.6.16 The Conjugate Gradient Method . . . . . . .
. . . . . . . . . 285 3.6.17 What Is the Recommended Method for
Solving Linear
Systems? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 287 3.7 RandomWalk . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 287
3.7.1 RandomWalk in 1D . . . . . . . . . . . . . . . . . . . . . .
. 288 3.7.2 Statistical Considerations . . . . . . . . . . . . . .
. . . . . . 288 3.7.3 Playing Around with Some Code . . . . . . . .
. . . . . . . 290 3.7.4 Equivalence with Diffusion . . . . . . . .
. . . . . . . . . . . 293 3.7.5 Implementation of Multiple Walks .
. . . . . . . . . . . . . 294 3.7.6 Demonstration of Multiple Walks
. . . . . . . . . . . . . . . 300 3.7.7 Ascii Visualization of 1D
RandomWalk . . . . . . . . . . . 300 3.7.8 RandomWalk as a
Stochastic Equation . . . . . . . . . . . 303 3.7.9 RandomWalk in
2D . . . . . . . . . . . . . . . . . . . . . . . 304 3.7.10
RandomWalk in Any Number of Space Dimensions . . . 305 3.7.11
Multiple Random Walks in Any Number of Space
Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 307 3.8 Applications . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . 308
3.8.1 Diffusion of a Substance . . . . . . . . . . . . . . . . . .
. . . 308 3.8.2 Heat Conduction . . . . . . . . . . . . . . . . . .
. . . . . . . 309 3.8.3 Porous Media Flow . . . . . . . . . . . . .
. . . . . . . . . . . 312 3.8.4 Potential Fluid Flow . . . . . . .
. . . . . . . . . . . . . . . . 312 3.8.5 Streamlines for 2D Fluid
Flow . . . . . . . . . . . . . . . . . 313 3.8.6 The Potential of
an Electric Field . . . . . . . . . . . . . . . 313 3.8.7
Development of Flow Between Two Flat Plates . . . . . . 313 3.8.8
Flow in a Straight Tube . . . . . . . . . . . . . . . . . . . . .
314
xvi Contents
3.8.9 Tribology: Thin Film Fluid Flow . . . . . . . . . . . . . . .
315 3.8.10 Propagation of Electrical Signals in the Brain . . . . .
. . . 316
3.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 316
4 Advection-Dominated Equations . . . . . . . . . . . . . . . . . .
. . . . . 323 4.1 One-Dimensional Time-Dependent Advection
Equations . . . . . . 323
4.1.1 Simplest Scheme: Forward in Time, Centered in Space . . 324
4.1.2 Analysis of the Scheme . . . . . . . . . . . . . . . . . . .
. . 327 4.1.3 Leapfrog in Time, Centered Differences in Space . . .
. . 328 4.1.4 Upwind Differences in Space . . . . . . . . . . . . .
. . . . . 331 4.1.5 Periodic Boundary Conditions . . . . . . . . .
. . . . . . . . 333 4.1.6 Implementation . . . . . . . . . . . . .
. . . . . . . . . . . . . 333 4.1.7 A Crank-Nicolson Discretization
in Time and Centered
Differences in Space . . . . . . . . . . . . . . . . . . . . . . .
337 4.1.8 The Lax-Wendroff Method . . . . . . . . . . . . . . . . .
. . 339 4.1.9 Analysis of Dispersion Relations . . . . . . . . . .
. . . . . 340
4.2 One-Dimensional Stationary Advection-Diffusion Equation . . . .
344 4.2.1 A Simple Model Problem . . . . . . . . . . . . . . . . .
. . . 344 4.2.2 A Centered Finite Difference Scheme . . . . . . . .
. . . . 345 4.2.3 Remedy: Upwind Finite Difference Scheme . . . . .
. . . 347
4.3 Time-dependent Convection-Diffusion Equations . . . . . . . . .
. . 349 4.3.1 Forward in Time, Centered in Space Scheme . . . . . .
. . 349 4.3.2 Forward in Time, Upwind in Space Scheme . . . . . . .
. . 349
4.4 Applications of Advection Equations . . . . . . . . . . . . . .
. . . . 350 4.4.1 Transport of a Substance . . . . . . . . . . . .
. . . . . . . . . 350 4.4.2 Transport of Heat in Fluids . . . . . .
. . . . . . . . . . . . . 350
4.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 351
5 Nonlinear Problems . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 353 5.1 Introduction of Basic Concepts . . . . .
. . . . . . . . . . . . . . . . . 353
5.1.1 Linear Versus Nonlinear Equations . . . . . . . . . . . . . .
353 5.1.2 A Simple Model Problem . . . . . . . . . . . . . . . . .
. . . 354 5.1.3 Linearization by Explicit Time Discretization . . .
. . . . . 355 5.1.4 Exact Solution of Nonlinear Algebraic Equations
. . . . . 356 5.1.5 Linearization . . . . . . . . . . . . . . . . .
. . . . . . . . . . . 357 5.1.6 Picard Iteration . . . . . . . . .
. . . . . . . . . . . . . . . . . 357 5.1.7 Linearization by a
Geometric Mean . . . . . . . . . . . . . . 359 5.1.8 Newton’s
Method . . . . . . . . . . . . . . . . . . . . . . . . . 360 5.1.9
Relaxation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 361 5.1.10 Implementation and Experiments . . . . . . . . . . . .
. . . 362 5.1.11 Generalization to a General Nonlinear ODE . . . .
. . . . . 365 5.1.12 Systems of ODEs . . . . . . . . . . . . . . .
. . . . . . . . . . 367
5.2 Systems of Nonlinear Algebraic Equations . . . . . . . . . . .
. . . . 368 5.2.1 Picard Iteration . . . . . . . . . . . . . . . .
. . . . . . . . . . 369 5.2.2 Newton’s Method . . . . . . . . . . .
. . . . . . . . . . . . . . 369 5.2.3 Stopping Criteria . . . . . .
. . . . . . . . . . . . . . . . . . . 371 5.2.4 Example: A
Nonlinear ODE Model from Epidemiology . 372
Contents xvii
5.3 Linearization at the Differential Equation Level . . . . . . .
. . . . . 373 5.3.1 Explicit Time Integration . . . . . . . . . . .
. . . . . . . . . 373 5.3.2 Backward Euler Scheme and Picard
Iteration . . . . . . . . 374 5.3.3 Backward Euler Scheme and
Newton’s Method . . . . . . 375 5.3.4 Crank-Nicolson Discretization
. . . . . . . . . . . . . . . . . 377
5.4 1D Stationary Nonlinear Differential Equations . . . . . . . .
. . . . 378 5.4.1 Finite Difference Discretization . . . . . . . .
. . . . . . . . 378 5.4.2 Solution of Algebraic Equations . . . . .
. . . . . . . . . . . 379
5.5 Multi-Dimensional Nonlinear PDE Problems . . . . . . . . . . .
. . 384 5.5.1 Finite Difference Discretization . . . . . . . . . .
. . . . . . 384 5.5.2 Continuation Methods . . . . . . . . . . . .
. . . . . . . . . . 386
5.6 Operator Splitting Methods . . . . . . . . . . . . . . . . . .
. . . . . . 387 5.6.1 Ordinary Operator Splitting for ODEs . . . .
. . . . . . . . 387 5.6.2 Strang Splitting for ODEs . . . . . . . .
. . . . . . . . . . . . 388 5.6.3 Example: Logistic Growth . . . .
. . . . . . . . . . . . . . . 388 5.6.4 Reaction-Diffusion Equation
. . . . . . . . . . . . . . . . . . 391 5.6.5 Example:
Reaction-Diffusion with Linear Reaction Term 392 5.6.6 Analysis of
the Splitting Method . . . . . . . . . . . . . . . . 400
5.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 401
A Useful Formulas . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . 409 A.1 Finite Difference Operator Notation . . .
. . . . . . . . . . . . . . . . 409 A.2 Truncation Errors of Finite
Difference Approximations . . . . . . . 410 A.3 Finite Differences
of Exponential Functions . . . . . . . . . . . . . . 411 A.4 Finite
Differences of tn . . . . . . . . . . . . . . . . . . . . . . . . .
. . 411
A.4.1 Software . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . 412
B Truncation Error Analysis . . . . . . . . . . . . . . . . . . . .
. . . . . . . 415 B.1 Overview of Truncation Error Analysis . . . .
. . . . . . . . . . . . . 415
B.1.1 Abstract Problem Setting . . . . . . . . . . . . . . . . . .
. . 415 B.1.2 Error Measures . . . . . . . . . . . . . . . . . . .
. . . . . . . 416
B.2 Truncation Errors in Finite Difference Formulas . . . . . . . .
. . . 417 B.2.1 Example: The Backward Difference for u0.t/ . . . .
. . . . 417 B.2.2 Example: The Forward Difference for u0.t/ . . . .
. . . . . 418 B.2.3 Example: The Central Difference for u0.t/ . . .
. . . . . . 419 B.2.4 Overview of Leading-Order Error Terms in
Finite
Difference Formulas . . . . . . . . . . . . . . . . . . . . . . .
420 B.2.5 Software for Computing Truncation Errors . . . . . . . .
. 421
B.3 Exponential Decay ODEs . . . . . . . . . . . . . . . . . . . .
. . . . . 422 B.3.1 Forward Euler Scheme . . . . . . . . . . . . .
. . . . . . . . . 422 B.3.2 Crank-Nicolson Scheme . . . . . . . . .
. . . . . . . . . . . . 423 B.3.3 The -Rule . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . 424 B.3.4 Using Symbolic Software
. . . . . . . . . . . . . . . . . . . . 424 B.3.5 Empirical
Verification of the Truncation Error . . . . . . . 425 B.3.6
Increasing the Accuracy by Adding Correction Terms . . 430 B.3.7
Extension to Variable Coefficients . . . . . . . . . . . . . . .
432 B.3.8 Exact Solutions of the Finite Difference Equations . . .
. 433 B.3.9 Computing Truncation Errors in Nonlinear Problems . . .
434
xviii Contents
B.4 Vibration ODEs . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 434 B.4.1 Linear Model Without Damping . . . . . . .
. . . . . . . . . 434 B.4.2 Model with Damping and Nonlinearity . .
. . . . . . . . . . 437 B.4.3 Extension to Quadratic Damping . . .
. . . . . . . . . . . . 438 B.4.4 The General Model Formulated as
First-Order ODEs . . . 439
B.5 Wave Equations . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 440 B.5.1 Linear Wave Equation in 1D . . . . . . . .
. . . . . . . . . . 440 B.5.2 Finding Correction Terms . . . . . .
. . . . . . . . . . . . . . 441 B.5.3 Extension to Variable
Coefficients . . . . . . . . . . . . . . . 442 B.5.4 Linear Wave
Equation in 2D/3D . . . . . . . . . . . . . . . . 444
B.6 Diffusion Equations . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . 445 B.6.1 Linear Diffusion Equation in 1D . . . . . .
. . . . . . . . . . 445 B.6.2 Nonlinear Diffusion Equation in 1D .
. . . . . . . . . . . . . 446
B.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 447
C Software Engineering; Wave Equation Model . . . . . . . . . . . .
. . . 451 C.1 A 1D Wave Equation Simulator . . . . . . . . . . . .
. . . . . . . . . 451
C.1.1 Mathematical Model . . . . . . . . . . . . . . . . . . . . .
. . 451 C.1.2 Numerical Discretization . . . . . . . . . . . . . .
. . . . . . 451 C.1.3 A Solver Function . . . . . . . . . . . . . .
. . . . . . . . . . . 452
C.2 Saving Large Arrays in Files . . . . . . . . . . . . . . . . .
. . . . . . 455 C.2.1 Using savez to Store Arrays in Files . . . .
. . . . . . . . . 455 C.2.2 Using joblib to Store Arrays in Files .
. . . . . . . . . . . 457 C.2.3 Using a Hash to Create a File or
Directory Name . . . . . 458
C.3 Software for the 1D Wave Equation . . . . . . . . . . . . . . .
. . . . 459 C.3.1 Making Hash Strings from Input Data . . . . . . .
. . . . . 460 C.3.2 Avoiding Rerunning Previously Run Cases . . . .
. . . . . 460 C.3.3 Verification . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . 461
C.4 Programming the Solver with Classes . . . . . . . . . . . . . .
. . . . 462 C.4.1 Class Parameters . . . . . . . . . . . . . . . .
. . . . . . . . . 463 C.4.2 Class Problem . . . . . . . . . . . . .
. . . . . . . . . . . . . . 465 C.4.3 Class Mesh . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . 465 C.4.4 Class Function .
. . . . . . . . . . . . . . . . . . . . . . . . . . 468 C.4.5 Class
Solver . . . . . . . . . . . . . . . . . . . . . . . . . . . .
471
C.5 Migrating Loops to Cython . . . . . . . . . . . . . . . . . . .
. . . . . 475 C.5.1 Declaring Variables and Annotating the Code . .
. . . . . . 476 C.5.2 Visual Inspection of the C Translation . . .
. . . . . . . . . 478 C.5.3 Building the Extension Module . . . . .
. . . . . . . . . . . 479 C.5.4 Calling the Cython Function from
Python . . . . . . . . . . 480
C.6 Migrating Loops to Fortran . . . . . . . . . . . . . . . . . .
. . . . . . 480 C.6.1 The Fortran Subroutine . . . . . . . . . . .
. . . . . . . . . . 481 C.6.2 Building the Fortran Module with f2py
. . . . . . . . . . . . 482 C.6.3 How to Avoid Array Copying . . .
. . . . . . . . . . . . . . . 483
C.7 Migrating Loops to C via Cython . . . . . . . . . . . . . . . .
. . . . 485 C.7.1 Translating Index Pairs to Single Indices . . . .
. . . . . . . 485 C.7.2 The Complete C Code . . . . . . . . . . . .
. . . . . . . . . . 486 C.7.3 The Cython Interface File . . . . . .
. . . . . . . . . . . . . . 486 C.7.4 Building the Extension Module
. . . . . . . . . . . . . . . . 487
Contents xix
C.8 Migrating Loops to C via f2py . . . . . . . . . . . . . . . . .
. . . . . 488 C.8.1 Migrating Loops to C++ via f2py . . . . . . . .
. . . . . . . 489
C.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . 490
List of Exercises, Problems and Projects
Problem 1.1: Use linear/quadratic functions for verification . . .
. . . . . . . . 50 Exercise 1.2: Show linear growth of the phase
with time . . . . . . . . . . . . . 51 Exercise 1.3: Improve the
accuracy by adjusting the frequency . . . . . . . . . 51 Exercise
1.4: See if adaptive methods improve the phase error . . . . . . .
. . . 52 Exercise 1.5: Use a Taylor polynomial to compute u1 . . .
. . . . . . . . . . . . 52 Problem 1.6: Derive and investigate the
velocity Verlet method . . . . . . . . . 52 Problem 1.7: Find the
minimal resolution of an oscillatory function . . . . . . 52
Exercise 1.8: Visualize the accuracy of finite differences for a
cosine function 53 Exercise 1.9: Verify convergence rates of the
error in energy . . . . . . . . . . . 53 Exercise 1.10: Use
linear/quadratic functions for verification . . . . . . . . . . .
53 Exercise 1.11: Use an exact discrete solution for verification .
. . . . . . . . . . 53 Exercise 1.12: Use analytical solution for
convergence rate tests . . . . . . . . 53 Exercise 1.13:
Investigate the amplitude errors of many solvers . . . . . . . . .
54 Problem 1.14: Minimize memory usage of a simple vibration solver
. . . . . . 54 Problem 1.15: Minimize memory usage of a general
vibration solver . . . . . 56 Exercise 1.16: Implement the
Euler-Cromer scheme for the generalized model 56 Problem 1.17:
Interpret ŒDtDtu
n as a forward-backward difference . . . . . . 56 Exercise 1.18:
Analysis of the Euler-Cromer scheme . . . . . . . . . . . . . . .
56 Exercise 1.19: Implement the solver via classes . . . . . . . .
. . . . . . . . . . . 66 Problem 1.20: Use a backward difference
for the damping term . . . . . . . . . 66 Exercise 1.21: Use the
forward-backward scheme with quadratic damping . . 67 Exercise
1.22: Simulate resonance . . . . . . . . . . . . . . . . . . . . .
. . . . . . 88 Exercise 1.23: Simulate oscillations of a sliding
box . . . . . . . . . . . . . . . . 88 Exercise 1.24: Simulate a
bouncing ball . . . . . . . . . . . . . . . . . . . . . . . 88
Exercise 1.25: Simulate a simple pendulum . . . . . . . . . . . . .
. . . . . . . . 89 Exercise 1.26: Simulate an elastic pendulum . .
. . . . . . . . . . . . . . . . . . . 89 Exercise 1.27: Simulate an
elastic pendulum with air resistance . . . . . . . . . 90 Exercise
1.28: Implement the PEFRL algorithm . . . . . . . . . . . . . . . .
. . 91 Exercise 2.1: Simulate a standing wave . . . . . . . . . . .
. . . . . . . . . . . . . 122 Exercise 2.2: Add storage of solution
in a user action function . . . . . . . . . . 123 Exercise 2.3: Use
a class for the user action function . . . . . . . . . . . . . . .
. 123 Exercise 2.4: Compare several Courant numbers in one movie .
. . . . . . . . . 123 Exercise 2.5: Implementing the solver
function as a generator . . . . . . . . . . 124 Project 2.6:
Calculus with 1D mesh functions . . . . . . . . . . . . . . . . . .
. . 124
xxi
xxii List of Exercises, Problems and Projects
Exercise 2.7: Find the analytical solution to a damped wave
equation . . . . . 148 Problem 2.8: Explore symmetry boundary
conditions . . . . . . . . . . . . . . . 148 Exercise 2.9: Send
pulse waves through a layered medium . . . . . . . . . . . . 148
Exercise 2.10: Explain why numerical noise occurs . . . . . . . . .
. . . . . . . 149 Exercise 2.11: Investigate harmonic averaging in
a 1D model . . . . . . . . . . 149 Problem 2.12: Implement open
boundary conditions . . . . . . . . . . . . . . . . 149 Exercise
2.13: Implement periodic boundary conditions . . . . . . . . . . .
. . . 151 Exercise 2.14: Compare discretizations of a Neumann
condition . . . . . . . . 151 Exercise 2.15: Verification by a
cubic polynomial in space . . . . . . . . . . . . 152 Exercise
2.16: Check that a solution fulfills the discrete model . . . . . .
. . . 181 Project 2.17: Calculus with 2D mesh functions . . . . . .
. . . . . . . . . . . . . 181 Exercise 2.18: Implement Neumann
conditions in 2D . . . . . . . . . . . . . . . 182 Exercise 2.19:
Test the efficiency of compiled loops in 3D . . . . . . . . . . . .
182 Exercise 2.20: Simulate waves on a non-homogeneous string . . .
. . . . . . . 195 Exercise 2.21: Simulate damped waves on a string
. . . . . . . . . . . . . . . . . 195 Exercise 2.22: Simulate
elastic waves in a rod . . . . . . . . . . . . . . . . . . . . 195
Exercise 2.23: Simulate spherical waves . . . . . . . . . . . . . .
. . . . . . . . . 195 Problem 2.24: Earthquake-generated tsunami
over a subsea hill . . . . . . . . . 196 Problem 2.25:
Earthquake-generated tsunami over a 3D hill . . . . . . . . . . .
198 Problem 2.26: Investigate Mayavi for visualization . . . . . .
. . . . . . . . . . . 199 Problem 2.27: Investigate visualization
packages . . . . . . . . . . . . . . . . . . 199 Problem 2.28:
Implement loops in compiled languages . . . . . . . . . . . . . .
199 Exercise 2.29: Simulate seismic waves in 2D . . . . . . . . . .
. . . . . . . . . . 200 Project 2.30: Model 3D acoustic waves in a
room . . . . . . . . . . . . . . . . . 200 Project 2.31: Solve a 1D
transport equation . . . . . . . . . . . . . . . . . . . . . 201
Problem 2.32: General analytical solution of a 1D damped wave
equation . . 204 Problem 2.33: General analytical solution of a 2D
damped wave equation . . 205 Exercise 3.1: Explore symmetry in a 1D
problem . . . . . . . . . . . . . . . . . . 242 Exercise 3.2:
Investigate approximation errors from a ux D 0 boundary
condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . 243 Exercise 3.3: Experiment with open boundary conditions in
1D . . . . . . . . . 243 Exercise 3.4: Simulate a diffused Gaussian
peak in 2D/3D . . . . . . . . . . . . 244 Exercise 3.5: Examine
stability of a diffusion model with a source term . . . . 245
Exercise 3.6: Stabilizing the Crank-Nicolson method by Rannacher
time
stepping . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . 316 Project 3.7: Energy estimates for diffusion problems .
. . . . . . . . . . . . . . . 316 Exercise 3.8: Splitting methods
and preconditioning . . . . . . . . . . . . . . . . 318 Problem
3.9: Oscillating surface temperature of the earth . . . . . . . . .
. . . . 319 Problem 3.10: Oscillating and pulsating flow in tubes .
. . . . . . . . . . . . . . 320 Problem 3.11: Scaling a welding
problem . . . . . . . . . . . . . . . . . . . . . . 320 Exercise
3.12: Implement a Forward Euler scheme for axi-symmetric diffusion
322 Exercise 4.1: Analyze 1D stationary convection-diffusion
problem . . . . . . . 351 Exercise 4.2: Interpret upwind difference
as artificial diffusion . . . . . . . . . 351 Problem 5.1:
Determine if equations are nonlinear or not . . . . . . . . . . . .
. 401 Problem 5.2: Derive and investigate a generalized logistic
model . . . . . . . . 401 Problem 5.3: Experience the behavior of
Newton’s method . . . . . . . . . . . . 402 Exercise 5.4: Compute
the Jacobian of a 2 2 system . . . . . . . . . . . . . . . 402
Problem 5.5: Solve nonlinear equations arising from a vibration ODE
. . . . . 402
List of Exercises, Problems and Projects xxiii
Exercise 5.6: Find the truncation error of arithmetic mean of
products . . . . . 402 Problem 5.7: Newton’s method for linear
problems . . . . . . . . . . . . . . . . 404 Problem 5.8:
Discretize a 1D problem with a nonlinear coefficient . . . . . . .
404 Problem 5.9: Linearize a 1D problem with a nonlinear
coefficient . . . . . . . 404 Problem 5.10: Finite differences for
the 1D Bratu problem . . . . . . . . . . . . 404 Problem 5.11:
Discretize a nonlinear 1D heat conduction PDE by finite
differences . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . 405 Problem 5.12: Differentiate a highly nonlinear term . . .
. . . . . . . . . . . . . 405 Exercise 5.13: Crank-Nicolson for a
nonlinear 3D diffusion equation . . . . . 406 Problem 5.14: Find
the sparsity of the Jacobian . . . . . . . . . . . . . . . . . . .
406 Problem 5.15: Investigate a 1D problem with a continuation
method . . . . . . 406 Exercise B.1: Truncation error of a weighted
mean . . . . . . . . . . . . . . . . . 447 Exercise B.2: Simulate
the error of a weighted mean . . . . . . . . . . . . . . . . 447
Exercise B.3: Verify a truncation error formula . . . . . . . . . .
. . . . . . . . . 447 Problem B.4: Truncation error of the Backward
Euler scheme . . . . . . . . . . 447 Exercise B.5: Empirical
estimation of truncation errors . . . . . . . . . . . . . . 448
Exercise B.6: Correction term for a Backward Euler scheme . . . . .
. . . . . . 448 Problem B.7: Verify the effect of correction terms
. . . . . . . . . . . . . . . . . 448 Problem B.8: Truncation error
of the Crank-Nicolson scheme . . . . . . . . . . 448 Problem B.9:
Truncation error of u0 D f .u; t/ . . . . . . . . . . . . . . . . .
. . 448 Exercise B.10: Truncation error of ŒDtDtu
n . . . . . . . . . . . . . . . . . . . . 449 Exercise B.11:
Investigate the impact of approximating u0.0/ . . . . . . . . . .
449 Problem B.12: Investigate the accuracy of a simplified scheme .
. . . . . . . . 449 Exercise C.1: Explore computational efficiency
of numpy.sum versus built-in
sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . 490 Exercise C.2: Make an improved numpy.savez function . .
. . . . . . . . . . . 490 Exercise C.3: Visualize the impact of the
Courant number . . . . . . . . . . . . 491 Exercise C.4: Visualize
the impact of the resolution . . . . . . . . . . . . . . . .
491
1Vibration ODEs
Vibration problems lead to differential equations with solutions
that oscillate in time, typically in a damped or undamped
sinusoidal fashion. Such solutions put certain demands on the
numerical methods compared to other phenomena whose solutions are
monotone or very smooth. Both the frequency and amplitude of the
oscillations need to be accurately handled by the numerical
schemes. The forthcom- ing text presents a range of different
methods, from classical ones (Runge-Kutta and
midpoint/Crank-Nicolson methods), to more modern and popular
symplectic (ge- ometric) integration schemes (Leapfrog,
Euler-Cromer, and Störmer-Verlet meth- ods), but with a clear
emphasis on the latter. Vibration problems occur throughout
mechanics and physics, but the methods discussed in this text are
also fundamen- tal for constructing successful algorithms for
partial differential equations of wave nature in multiple spatial
dimensions.
1.1 Finite Difference Discretization
Many of the numerical challenges faced when computing oscillatory
solutions to ODEs and PDEs can be captured by the very simple ODE
u00 C u D 0. This ODE is thus chosen as our starting point for
method development, implementation, and analysis.
1.1.1 A Basic Model for Vibrations
The simplest model of a vibrating mechanical system has the
following form:
u00 C !2u D 0; u.0/ D I; u0.0/ D 0; t 2 .0; T : (1.1)
Here, ! and I are given constants. Section 1.12.1 derives (1.1)
from physical prin- ciples and explains what the constants
mean.
The exact solution of (1.1) is
u.t/ D I cos.!t/ : (1.2)
1© The Author(s) 2017 H.P. Langtangen, S. Linge, Finite Difference
Computing with PDEs, Texts in Computational Science and Engineering
16, DOI 10.1007/978-3-319-55456-3_1
2 1 Vibration ODEs
That is, u oscillates with constant amplitude I and angular
frequency !. The corre- sponding period of oscillations (i.e., the
time between two neighboring peaks in the cosine function) is P D
2=!. The number of periods per second is f D !=.2/ and measured in
the unit Hz. Both f and ! are referred to as frequency, but ! is
more precisely named angular frequency, measured in rad/s.
In vibrating mechanical systems modeled by (1.1), u.t/ very often
represents a position or a displacement of a particular point in
the system. The derivative u0.t/ then has the interpretation of
velocity, and u00.t/ is the associated acceleration. The model
(1.1) is not only applicable to vibrating mechanical systems, but
also to oscillations in electrical circuits.
1.1.2 A Centered Finite Difference Scheme
To formulate a finite difference method for the model problem
(1.1), we follow the four steps explained in Section 1.1.2 in
[9].
Step 1: Discretizing the domain The domain is discretized by
introducing a uniformly partitioned time mesh. The points in the
mesh are tn D nt , n D 0; 1; : : : ; Nt , where t D T=Nt is the
constant length of the time steps. We in- troduce a mesh function
un for n D 0; 1; : : : ; Nt , which approximates the exact solution
at the mesh points. (Note that n D 0 is the known initial
condition, so un is identical to the mathematical u at this point.)
The mesh function un will be computed from algebraic equations
derived from the differential equation problem.
Step 2: Fulfilling the equation at discrete time points The ODE is
to be satisfied at each mesh point where the solution must be
found:
u00.tn/C !2u.tn/ D 0; n D 1; : : : ; Nt : (1.3)
Step 3: Replacing derivatives by finite differences The derivative
u00.tn/ is to be replaced by a finite difference approximation. A
common second-order accurate approximation to the second-order
derivative is
u00.tn/ unC1 2un C un1 t2
: (1.4)
unC1 2un C un1 t2
D !2un : (1.5)
We also need to replace the derivative in the initial condition by
a finite dif- ference. Here we choose a centered difference, whose
accuracy is similar to the centered difference we used for
u00:
u1 u1 2t
D 0 : (1.6)
1.1 Finite Difference Discretization 3
Step 4: Formulating a recursive algorithm To formulate the
computational al- gorithm, we assume that we have already computed
un1 and un, such that unC1 is the unknown value to be solved
for:
unC1 D 2un un1 t2!2un : (1.7)
The computational algorithm is simply to apply (1.7) successively
for n D 1; 2; : : : ; Nt 1. This numerical scheme sometimes goes
under the name Störmer’s method, Verlet integration1, or the
Leapfrog method (one should note that Leapfrog is used for many
quite different methods for quite different differential
equations!).
Computing the first step We observe that (1.7) cannot be used for n
D 0 since the computation of u1 then involves the undefined value
u1 at t D t . The discretization of the initial condition then
comes to our rescue: (1.6) implies u1 D u1 and this relation can be
combined with (1.7) for n D 0 to yield a value for u1:
u1 D 2u0 u1 t2!2u0;
which reduces to
u1 D u0 1 2 t2!2u0 : (1.8)
Exercise 1.5 asks you to perform an alternative derivation and also
to generalize the initial condition to u0.0/ D V ¤ 0.
The computational algorithm The steps for solving (1.1)
become
1. u0 D I 2. compute u1 from (1.8) 3. for n D 1; 2; : : : ; Nt 1:
compute unC1 from (1.7)
The algorithm is more precisely expressed directly in Python:
t = linspace(0, T, Nt+1) # mesh points in time dt = t[1] - t[0] #
constant time step u = zeros(Nt+1) # solution
u[0] = I u[1] = u[0] - 0.5*dt**2*w**2*u[0] for n in range(1,
Nt):
u[n+1] = 2*u[n] - u[n-1] - dt**2*w**2*u[n]
Remark on using w for ! in computer code In the code, we use w as
the symbol for !. The reason is that the authors prefer w for
readability and comparison with the mathematical ! instead of the
full word omega as variable name.
1 http://en.wikipedia.org/wiki/Verlet_integration
4 1 Vibration ODEs
Operator notation We may write the scheme using a compact
difference notation listed in Appendix A.1 (see also Section 1.1.8
in [9]). The difference (1.4) has the operator notation
ŒDtDtu
n such that we can write:
ŒDtDtuC !2u D 0n : (1.9)
Note that ŒDtDtu n means applying a central difference with step
t=2 twice:
ŒDt.Dtu/ n D ŒDtu
nC 1 2 ŒDtu
1
t
t2 :
The discretization of initial conditions can in the operator
notation be expressed as
Œu D I 0; ŒD2tu D 00; (1.10)
where the operator ŒD2tu n is defined as
ŒD2tu n D unC1 un1
2t : (1.11)
1.2.1 Making a Solver Function
The algorithm from the previous section is readily translated to a
complete Python function for computing and returning u0; u1; : : :
; uNt and t0; t1; : : : ; tNt , given the input I , !, t , and T
:
import numpy as np import matplotlib.pyplot as plt
def solver(I, w, dt, T): """ Solve u’’ + w**2*u = 0 for t in (0,T],
u(0)=I and u’(0)=0, by a central finite difference method with time
step dt. """ dt = float(dt) Nt = int(round(T/dt)) u =
np.zeros(Nt+1) t = np.linspace(0, Nt*dt, Nt+1)
u[0] = I u[1] = u[0] - 0.5*dt**2*w**2*u[0] for n in range(1,
Nt):
u[n+1] = 2*u[n] - u[n-1] - dt**2*w**2*u[n] return u, t
1.2 Implementation 5
We have imported numpy and matplotlib under the names np and plt,
respec- tively, as this is very common in the Python scientific
computing community and a good programming habit (since we
explicitly see where the different functions come from). An
alternative is to do from numpy import * and a similar “import all”
for Matplotlib to avoid the np and plt prefixes and make the code
as close as possible to MATLAB. (See Section 5.1.4 in [9] for a
discussion of the two types of import in Python.)
A function for plotting the numerical and the exact solution is
also convenient to have:
def u_exact(t, I, w): return I*np.cos(w*t)
def visualize(u, t, I, w): plt.plot(t, u, ’r--o’) t_fine =
np.linspace(0, t[-1], 1001) # very fine mesh for u_e u_e =
u_exact(t_fine, I, w) plt.hold(’on’) plt.plot(t_fine, u_e, ’b-’)
plt.legend([’numerical’, ’exact’], loc=’upper left’)
plt.xlabel(’t’) plt.ylabel(’u’) dt = t[1] - t[0] plt.title(’dt=%g’
% dt) umin = 1.2*u.min(); umax = -umin plt.axis([t[0], t[-1], umin,
umax]) plt.savefig(’tmp1.png’); plt.savefig(’tmp1.pdf’)
A corresponding main program calling these functions to simulate a
given number of periods (num_periods) may take the form
I = 1 w = 2*pi dt = 0.05 num_periods = 5 P = 2*pi/w # one period T
= P*num_periods u, t = solver(I, w, dt, T) visualize(u, t, I, w,
dt)
Adjusting some of the input parameters via the command line can be
handy. Here is a code segment using the ArgumentParser tool in the
argparse module to define option value (–option value) pairs on the
command line:
import argparse parser = argparse.ArgumentParser()
parser.add_argument(’--I’, type=float, default=1.0)
parser.add_argument(’--w’, type=float, default=2*pi)
parser.add_argument(’--dt’, type=float, default=0.05)
parser.add_argument(’--num_periods’, type=int, default=5) a =
parser.parse_args() I, w, dt, num_periods = a.I, a.w, a.dt,
a.num_periods
6 1 Vibration ODEs
Such parsing of the command line is explained in more detail in
Section 5.2.3 in [9].
A typical execution goes like
Terminal
Terminal> python vib_undamped.py --num_periods 20 --dt 0.1
Computing u0 In mechanical vibration applications one is often
interested in com- puting the velocity v.t/ D u0.t/ after u.t/ has
been computed. This can be done by a central difference,
v.tn/ D u0.tn/ vn D unC1 un1 2t
D ŒD2tu n : (1.12)
This formula applies for all inner mesh points, n D 1; : : : ; Nt
1. For n D 0, v.0/ is given by the initial condition on u0.0/, and
for n D Nt we can use a one-sided, backward difference:
vn D ŒDt un D un un1
t :
v = np.zeros_like(u) # or v = np.zeros(len(u)) # Use central
difference for internal points for i in range(1, len(u)-1):
v[i] = (u[i+1] - u[i-1])/(2*dt) # Use initial condition for u’(0)
when i=0 v[0] = 0 # Use backward difference at the final mesh point
v[-1] = (u[-1] - u[-2])/dt
Since the loop is slow for large Nt , we can get rid of the loop by
vectorizing the central difference. The above code segment goes as
follows in its vectorized version (see Problem 1.2 in [9] for
explanation of details):
v = np.zeros_like(u) v[1:-1] = (u[2:] - u[:-2])/(2*dt) # central
difference v[0] = 0 # boundary condition u’(0) v[-1] = (u[-1] -
u[-2])/dt # backward difference
1.2.2 Verification
Manual calculation The simplest type of verification, which is also
instructive for understanding the algorithm, is to compute u1, u2,
and u3 with the aid of a calculator and make a function for
comparing these results with those from the solver function. The
test_three_steps function in the file vib_undamped.py shows the
details of how we use the hand calculations to test the code:
1.2 Implementation 7
def test_three_steps(): from math import pi I = 1; w = 2*pi; dt =
0.1; T = 1 u_by_hand = np.array([1.000000000000000,
0.802607911978213, 0.288358920740053])
u, t = solver(I, w, dt, T) diff = np.abs(u_by_hand - u[:3]).max()
tol = 1E-14 assert diff < tol
This function is a proper test function, compliant with the pytest
and nose testing framework for Python code, because
the function name begins with test_ the function takes no arguments
the test is formulated as a boolean condition and executed by
assert
We shall in this book implement all software verification via such
proper test func- tions, also known as unit testing. See Section
5.3.2 in [9] for more details on how to construct test functions
and utilize nose or pytest for automatic execution of tests. Our
recommendation is to use pytest. With this choice, you can run all
test functions in vib_undamped.py by
Terminal
Terminal> py.test -s -v vib_undamped.py
============================= test session starts ======...
platform linux2 -- Python 2.7.9 -- ... collected 2 items
vib_undamped.py::test_three_steps PASSED
vib_undamped.py::test_convergence_rates PASSED
=========================== 2 passed in 0.19 seconds ===...
Testing very simple polynomial solutions Constructing test problems
where the exact solution is constant or linear helps initial
debugging and verification as one expects any reasonable numerical
method to reproduce such solutions to machine precision.
Second-order accurate methods will often also reproduce a quadratic
solution. Here ŒDtDt t
2n D 2, which is the exact result. A solution u D t2
leads to u00 C !2u D 2 C .!t/2 ¤ 0. We must therefore add a source
in the equation: u00 C !2u D f to allow a solution u D t2 for f D 2
C .!t/2. By simple insertion we can show that the mesh function un
D t2n is also a solution of the discrete equations. Problem 1.1
asks you to carry out all details to show that linear and quadratic
solutions are solutions of the discrete equations. Such results are
very useful for debugging and verification. You are strongly
encouraged to do this problem now!
Checking convergence rates Empirical computation of convergence
rates yields a good method for verification. The method and its
computational details are ex-
8 1 Vibration ODEs
plained in detail in Section 3.1.6 in [9]. Readers not familiar
with the concept should look up this reference before
proceeding.
In the present problem, computing convergence rates means that we
must
perform m simulations, halving the time steps as: ti D 2it0, i D 1;
: : : ;
m 1, and ti is the time step used in simulation i ;
compute the L2 norm of the error, Ei D q ti
PNt1 nD0 .un ue.tn//2 in each
case; estimate the convergence rates ri based on two consecutive
experiments .ti1; Ei1/ and .ti ; Ei /, assuming Ei D C.ti /
r and Ei1 D C.ti1/r , where C is a constant. From these equations
it follows that r D ln.Ei1=Ei /= ln.ti1=ti /. Since this r will
vary with i , we equip it with an index and call it ri1, where i
runs from 1 to m 1.
The computed rates r0; r1; : : : ; rm2 hopefully converge to the
number 2 in the present problem, because theory (from Sect. 1.4)
shows that the error of the numerical method we use behaves like
t2. The convergence of the sequence r0; r1; : : : ; rm2 demands
that the time steps ti are sufficiently small for the error model
Ei D C.ti /r to be valid.
All the implementational details of computing the sequence r0; r1;
: : : ; rm2 ap- pear below.
def convergence_rates(m, solver_function, num_periods=8): """
Return m-1 empirical estimates of the convergence rate based on m
simulations, where the time step is halved for each simulation.
solver_function(I, w, dt, T) solves each problem, where T is based
on simulation for num_periods periods. """ from math import pi w =
0.35; I = 0.3 # just chosen values P = 2*pi/w # period dt = P/30 #
30 time step per period 2*pi/w T = P*num_periods
dt_values = [] E_values = [] for i in range(m):
u, t = solver_function(I, w, dt, T) u_e = u_exact(t, I, w) E =
np.sqrt(dt*np.sum((u_e-u)**2)) dt_values.append(dt)
E_values.append(E) dt = dt/2
r = [np.log(E_values[i-1]/E_values[i])/
np.log(dt_values[i-1]/dt_values[i]) for i in range(1, m, 1)]
return r, E_values, dt_values
The error analysis in Sect. 1.4 is quite detailed and suggests that
r D 2. It is also a intuitively reasonable result, since we used a
second-order accurate finite
1.2 Implementation 9
difference approximation ŒDtDtu n to the ODE and a second-order
accurate finite
difference formula for the initial condition for u0. In the present
problem, when t0 corresponds to 30 time steps per period, the
returned r list has all its values equal to 2.00 (if rounded to two
decimals). This amazingly accurate result means that all ti values
are well into the asymptotic regime where the error model Ei D C.ti
/r is valid.
We can now construct a proper test function that computes
convergence rates and checks that the final (and usually the best)
estimate is sufficiently close to 2. Here, a rough tolerance of 0.1
is enough. Later, we will argue for an improvement by adjusting
omega and include also that case in our test function here. The
unit test goes like
def test_convergence_rates(): r, E, dt = convergence_rates(
m=5, solver_function=solver, num_periods=8) # Accept rate to 1
decimal place tol = 0.1 assert abs(r[-1] - 2.0) < tol # Test
that adjusted w obtains 4th order convergence r, E, dt =
convergence_rates(
m=5, solver_function=solver_adjust_w, num_periods=8) print ’adjust
w rates:’, r assert abs(r[-1] - 4.0) < tol
The complete code appears in the file vib_undamped.py.
Visualizing convergence rates with slope markers Tony S. Yu has
written a script plotslopes.py2 that is very useful to indicate the
slope of a graph, es- pecially a graph like lnE D r lnt C lnC
arising from the model E D Ctr . A copy of the script resides in
the src/vib3 directory. Let us use it to compare the original
method for u00 C !2u D 0 with the same method applied to the equa-
tion with a modified !. We make log-log plots of the error versus t
. For each curve we attach a slope marker using the
slope_marker((x,y), r) function from plotslopes.py, where (x,y) is
the position of the marker and r and the slope (.r; 1/), here (2,1)
and (4,1).
def plot_convergence_rates(): r2, E2, dt2 =
convergence_rates(
m=5, solver_function=solver, num_periods=8) plt.loglog(dt2, E2) r4,
E4, dt4 = convergence_rates(
m=5, solver_function=solver_adjust_w, num_periods=8)
plt.loglog(dt4, E4) plt.legend([’original scheme’, r’adjusted
$\omega$’],
loc=’upper left’) plt.title(’Convergence of finite difference
methods’) from plotslopes import slope_marker slope_marker((dt2[1],
E2[1]), (2,1)) slope_marker((dt4[1], E4[1]), (4,1))
2 http://goo.gl/A4Utm7 3 http://tinyurl.com/nu656p2/vib
Fig. 1.1 Empirical convergence rate curves with special slope
marker
Figure 1.1 displays the two curves with the markers. The match of
the curve slope and the marker slope is excellent.
1.2.3 Scaled Model
It is advantageous to use dimensionless variables in simulations,
because fewer pa- rameters need to be set. The present problem is
made dimensionless by introducing dimensionless variables Nt D t=tc
and Nu D u=uc, where tc and uc are characteristic scales for t and
u, respectively. We refer to Section 2.2.1 in [11] for all details
about this scaling.
The scaled ODE problem reads
uc
t2c
d 2 Nu d Nt2 C uc Nu D 0; uc Nu.0/ D I; uc
tc
d Nu d Nt .0/ D 0 :
A common choice is to take tc as one period of the oscillations, tc
D 2=w, and uc D I . This gives the dimensionless model
d2 Nu d Nt2 C 4
2 Nu D 0; Nu.0/ D 1; Nu0.0/ D 0 : (1.13)
Observe that there are no physical parameters in (1.13)! We can
therefore perform a single numerical simulation Nu.Nt / and
afterwards recover any u.t I!; I / by
u.t I!; I / D uc Nu.t=tc/ D I Nu.!t=.2// : We can easily check this
assertion: the solution of the scaled problem is Nu.Nt / D
cos.2 Nt/. The formula for u in terms of Nu gives u D I cos.!t/,
which is nothing but the solution of the original problem with
dimensions.
1.3 Visualization of Long Time Simulations 11
The scaled model can be run by calling solver(I=1, w=2*pi, dt, T).
Each period is now 1 and T simply counts the number of periods.
Choosing dt as 1./M gives M time steps per period.
1.3 Visualization of Long Time Simulations
Figure 1.2 shows a comparison of the exact and numerical solution
for the scaled model (1.13) with t D 0:1; 0:05. From the plot we
make the following observa- tions:
The numerical solution seems to have correct amplitude. There is an
angular frequency error which is reduced by decreasing the time
step. The total angular frequency error grows with time.
By angular frequency error we mean that the numerical angular
frequency differs from the exact !. This is evident by looking at
the peaks of the numerical solution: these have incorrect positions
compared with the peaks of the exact cosine solution. The effect
can be mathematically expressed by writing the numerical solution
as I cos Q!t , where Q! is not exactly equal to !. Later, we shall
mathematically quantify this numerical angular frequency Q!.
1.3.1 Using aMoving Plot Window
In vibration problems it is often of interest to investigate the
system’s behavior over long time intervals. Errors in the angular
frequency accumulate and become more visible as time grows. We can
investigate long time series by introducing a moving plot window
that can move along with the p most recently computed periods of
the solution. The SciTools4 package contains a convenient tool for
this: MovingPlotWindow. Typing pydoc scitools.MovingPlotWindow
shows a demo and a description of its use. The function below
utilizes the moving plot
Fig. 1.2 Effect of halving the time step
4 https://github.com/hplgit/scitools
12 1 Vibration ODEs
window and is in fact called by the main function in the
vib_undampedmodule if the number of periods in the simulation
exceeds 10.
def visualize_front(u, t, I, w, savefig=False, skip_frames=1): """
Visualize u and the exact solution vs t, using a moving plot window
and continuous drawing of the curves as they evolve in time. Makes
it easy to plot very long time series. Plots are saved to files if
savefig is True. Only each skip_frames-th plot is saved (e.g., if
skip_frame=10, only each 10th plot is saved to file; this is
convenient if plot files corresponding to different time steps are
to be compared). """ import scitools.std as st from
scitools.MovingPlotWindow import MovingPlotWindow from math import
pi
# Remove all old plot files tmp_*.png import glob, os for filename
in glob.glob(’tmp_*.png’):
os.remove(filename)
P = 2*pi/w # one period umin = 1.2*u.min(); umax = -umin dt = t[1]
- t[0] plot_manager = MovingPlotWindow(
window_width=8*P, dt=dt, yaxis=[umin, umax], mode=’continuous
drawing’)
frame_counter = 0 for n in range(1,len(u)):
if plot_manager.plot(n): s = plot_manager.first_index_in_plot
st.plot(t[s:n+1], u[s:n+1], ’r-1’,
t[s:n+1], I*cos(w*t)[s:n+1], ’b-1’, title=’t=%6.3f’ % t[n],
axis=plot_manager.axis(), show=not savefig) # drop window if
savefig
if savefig and n % skip_frames == 0: filename = ’tmp_%04d.png’ %
frame_counter st.savefig(filename) print ’making plot file’,
filename, ’at t=%g’ % t[n] frame_counter += 1
plot_manager.update(n)
We run the scaled problem (the default values for the command-line
arguments –I and –w correspond to the scaled problem) for 40
periods with 20 time steps per period:
Terminal
Terminal> python vib_undamped.py --dt 0.05 --num_periods
40
1.3 Visualization of Long Time Simulations 13
The moving plot window is invoked, and we can follow the numerical
and exact solutions as time progresses. From this demo we see that
the angular frequency error is small in the beginning, and that it
becomes more prominent with time. A new run with t D 0:1 (i.e.,
only 10 time steps per period) clearly shows that the phase errors
become significant even earlier in the time series, deteriorating
the solution further.
1.3.2 Making Animations
Producing standard video formats The visualize_front function
stores all the plots in files whose names are numbered:
tmp_0000.png, tmp_0001.png, tmp_0002.png, and so on. From these
files we may make a movie. The Flash format is popular,
Terminal
Terminal> ffmpeg -r 25 -i tmp_%04d.png -c:v flv movie.flv
The ffmpeg program can be replaced by the avconv program in the
above com- mand if desired (but at the time of this writing it
seems to be more momentum in the ffmpeg project). The -r option
should come first and describes the number of frames per second in
the movie (even if we would like to have slow movies, keep this
number as large as 25, otherwise files are skipped from the movie).
The -i option describes the name of the plot files. Other formats
can be generated by changing the video codec and equipping the
video file with the right extension:
Format Codec and filename Flash -c:v flv movie.flv MP4 -c:v libx264
movie.mp4 WebM -c:v libvpx movie.webm Ogg -c:v libtheora
movie.ogg
The video file can be played by some video player like vlc,
mplayer, gxine, or totem, e.g.,
Terminal
Terminal> vlc movie.webm
A web page can also be used to play the movie. Today’s standard is
to use the HTML5 video tag:
<video autoplay loop controls width=’640’ height=’365’
preload=’none’>
<source src=’movie.webm’ type=’video/webm; codecs="vp8,
vorbis"’> </video>
14 1 Vibration ODEs
Modern browsers do not support all of the video formats. MP4 is
needed to suc- cessfully play the videos on Apple devices that use
the Safari browser. WebM is the preferred format for Chrome, Opera,
Firefox, and Internet Explorer v9+. Flash was a popular format, but
older browsers that required Flash can play MP4. All browsers that
work with Ogg can also work with WebM. This means that to have a
video work in all browsers, the video should be available in the
MP4 and WebM formats. The proper HTML code reads
<video autoplay loop controls width=’640’ height=’365’
preload=’none’>
<source src=’movie.mp4’ type=’video/mp4; codecs="avc1.42E01E,
mp4a.40.2"’>
<source src=’movie.webm’ type=’video/webm; codecs="vp8,
vorbis"’>
</video>
The MP4 format should appear first to ensure that Apple devices
will load the video correctly.
Caution: number the plot files correctly To ensure that the
individual plot frames are shown in correct order, it is im-
portant to number the files with zero-padded numbers (0000, 0001,
0002, etc.). The printf format %04d specifies an integer in a field
of width 4, padded with zeros from the left. A simple Unix wildcard
file specification like tmp_*.png will then list the frames in the
right order. If the numbers in the filenames were not zero-padded,
the frame tmp_11.pngwould appear before tmp_2.png in the
movie.
Playing PNG files in a web browser The scitools movie command can
create a movie player for a set of PNG files such that a web
browser can be used to watch the movie. This interface has the
advantage that the speed of the movie can easily be controlled, a
feature that scientists often appreciate. The command for creating
an HTML with a player for a set of PNG files tmp_*.png goes
like
Terminal
Terminal> scitools movie output_file=vib.html fps=4
tmp_*.png
The fps argument controls the speed of the movie (“frames per
second”). To watch the movie, load the video file vib.html into
some browser, e.g.,
Terminal
1.3 Visualization of Long Time Simulations 15
Click on Start movie to see the result. Moving this movie to some
other place requires moving vib.html and all the PNG files
tmp_*.png:
Terminal
Terminal> mkdir vib_dt0.1 Terminal> mv tmp_*.png vib_dt0.1
Terminal> mv vib.html vib_dt0.1/index.html
Making animated GIF files The convert program from the ImageMagick
soft- ware suite can be used to produce animated GIF files from a
set of PNG files:
Terminal
Terminal> convert -delay 25 tmp_vib*.png tmp_vib.gif
The -delay option needs an argument of the delay between each
frame, measured in 1/100 s, so 4 frames/s here gives 25/100 s
delay. Note, however, that in this particular example with t D 0:05
and 40 periods, making an animated GIF file out of the large number
of PNG files is a very heavy process and not considered feasible.
Animated GIFs are best suited for animations with not so many
frames and where you want to see each frame and play them
slowly.
1.3.3 Using Bokeh to Compare Graphs
Instead of a moving plot frame, one can use tools that allow
panning by the mouse. For example, we can show four periods of
several signals in several plots and then scroll with the mouse
through the rest of the simulation simultaneously in all the plot
windows. The Bokeh5 plotting library offers such tools, but the
plots must be displayed in a web browser. The documentation of
Bokeh is excellent, so here we just show how the library can be
used to compare a set of u curves corresponding to long time
simulations. (By the way, the guidance to correct pronunciation of
Bokeh in the documentation6 and onWikipedia7 is not directly
compatible with a YouTube video8 . . . ).
Imagine we have performed experiments for a set of t values. We
want each curve, together with the exact solution, to appear in a
plot, and then arrange all plots in a grid-like fashion:
5 http://bokeh.pydata.org/en/latest 6
http://bokeh.pydata.org/en/0.10.0/docs/faq.html#how-do-you-pronounce-bokeh
7 https://en.wikipedia.org/wiki/Bokeh 8
https://www.youtube.com/watch?v=OR8HSHevQTM
16 1 Vibration ODEs
Furthermore, we want the axes to couple such that if we move into
the future in one plot, all the other plots follows (note the
displaced t axes!):
A function for creating a Bokeh plot, given a list of u arrays and
corresponding t arrays, is implemented below. The code combines
data from different simulations, described compactly in a list of
strings legends.
1.3 Visualization of Long Time Simulations 17
def bokeh_plot(u, t, legends, I, w, t_range, filename): """ Make
plots for u vs t using the Bokeh library. u and t are lists
(several experiments can be compared). legens contain legend
strings for the various u,t pairs. """ if not isinstance(u,
(list,tuple)):
u = [u] # wrap in list if not isinstance(t, (list,tuple)):
t = [t] # wrap in list if not isinstance(legends,
(list,tuple)):
legends = [legends] # wrap in list
import bokeh.plotting as plt plt.output_file(filename, mode=’cdn’,
title=’Comparison’) # Assume that all t arrays have the same range
t_fine = np.linspace(0, t[0][-1], 1001) # fine mesh for u_e tools =
’pan,wheel_zoom,box_zoom,reset,’\
’save,box_select,lasso_select’ u_range = [-1.2*I, 1.2*I] font_size
= ’8pt’ p = [] # list of plot objects # Make the first figure p_ =
plt.figure(
width=300, plot_height=250, title=legends[0], x_axis_label=’t’,
y_axis_label=’u’, x_range=t_range, y_range=u_range, tools=tools,
title_text_font_size=font_size)
p_.xaxis.axis_label_text_font_size=font_size
p_.yaxis.axis_label_text_font_size=font_size p_.line(t[0], u[0],
line_color=’blue’) # Add exact solution u_e = u_exact(t_fine, I, w)
p_.line(t_fine, u_e, line_color=’red’, line_dash=’4 4’)
p.append(p_) # Make the rest of the figures and attach their axes
to # the first figure’s axes for i in range(1, len(t)):
p_ = plt.figure( width=300, plot_height=250, title=legends[i],
x_axis_label=’t’, y_axis_label=’u’, x_range=p[0].x_range,
y_range=p[0].y_range, tools=tools,
title_text_font_size=font_size)
p_.xaxis.axis_label_text_font_size = font_size
p_.yaxis.axis_label_text_font_size = font_size p_.line(t[i], u[i],
line_color=’blue’) p_.line(t_fine, u_e, line_color=’red’,
line_dash=’4 4’) p.append(p_)
# Arrange all plots in a grid with 3 plots per row grid = [[]] for
i, p_ in enumerate(p):
grid[-1].append(p_) if (i+1) % 3 == 0:
# New row grid.append([])
18 1 Vibration ODEs
A particular example using the bokeh_plot function appears
below.
def demo_bokeh(): """Solve a scaled ODE u’’ + u = 0.""" from math
import pi w = 1.0 # Scaled problem (frequency) P = 2*np.pi/w #
Period num_steps_per_period = [5, 10, 20, 40, 80] T = 40*P #
Simulation time: 40 periods u = [] # List of numerical solutions t
= [] # List of corresponding meshes legends = [] for n in
num_steps_per_period:
dt = P/n u_, t_ = solver(I=1, w=w, dt=dt, T=T) u.append(u_)
t.append(t_) legends.append(’# time steps per period: %d’ %
n)
bokeh_plot(u, t, legends, I=1, w=w, t_range=[0, 4*P],
filename=’tmp.html’)
1.3.4 Using a Line-by-Line Ascii Plotter
Plotting functions vertically, line by line, in the terminal window
using ascii char- acters only is a simple, fast, and convenient
visualization technique for long time series. Note that the time
axis then is positive downwards on the screen, so we can let the
solution be visualized “forever”. The tool
scitools.avplotter.Plotter makes it easy to create such
plots:
def visualize_front_ascii(u, t, I, w, fps=10): """ Plot u and the
exact solution vs t line by line in a terminal window (only using
ascii characters). Makes it easy to plot very long time series. """
from scitools.avplotter import Plotter import time from math import
pi P = 2*pi/w umin = 1.2*u.min(); umax = -umin
p = Plotter(ymin=umin, ymax=umax, width=60, symbols=’+o’) for n in
range(len(u)):
print p.plot(t[n], u[n], I*cos(w*t[n])), \ ’%.1f’ % (t[n]/P)
time.sleep(1/float(fps))
The call p.plot returns a line of text, with the t axis marked and
a symbol + for the first function (u) and o for the second function
(the exact solution). Here we append to this text a time counter
reflecting how many periods the current time point corresponds to.
A typical output (! D 2 , t D 0:05) looks like this:
1.3 Visualization of Long Time Simulations 19
| o+ 14.0 | + o 14.0 | + o 14.1 | + o 14.1 | + o 14.2
+| o 14.2 + | 14.2
o + | 14.6 o + | 14.7
o | + 14.7 | + 14.8 | o + 14.8 | o + 14.9 | o + 14.9 | o+
15.0
1.3.5 Empirical Analysis of the Solution
For oscillating functions like those in Fig. 1.2 we may compute the
amplitude and frequency (or period) empirically. That is, we run
through the discrete solution points .tn; un/ and find all maxima
and minima points. The distance between two consecutive maxima (or
minima) points can be used as estimate of the local period, while
half the difference between the u value at a maximum and a nearby
minimum gives an estimate of the local amplitude.
The local maxima are the points where
un1 < un > unC1; n D 1; : : : ; Nt 1; (1.14)
and the local minima are recognized by
un1 > un < unC1; n D 1; : : : ; Nt 1 : (1.15)
In computer code this becomes
def minmax(t, u): minima = []; maxima = [] for n in range(1,
len(u)-1, 1):
if u[n-1] > u[n] < u[n+1]: minima.append((t[n], u[n]))
if u[n-1] < u[n] > u[n+1]: maxima.append((t[n], u[n]))
return minima, maxima
Note that the two returned objects are lists of tuples.
20 1 Vibration ODEs
Let .ti ; ei /, i
LOAD MORE