How To Solve The Pde Problem On A Mesh With A Freefem++ (Freefemplest) On A Computer Or A Computer (For Freefems)



Similar documents
An Introduction to FreeFem++ UPMC, September 2010 O. Pantz. CMAP, Ecole Polytechnique.

FreeFem++-cs, the FreeFem++ Graphical Interface

Domain decomposition techniques for interfacial discontinuities

Computational Mathematics with Python

Computational Mathematics with Python

Computer Graphics. Geometric Modeling. Page 1. Copyright Gotsman, Elber, Barequet, Karni, Sheffer Computer Science - Technion. An Example.

Introduction to the Finite Element Method

Mean Value Coordinates

MATLAB Basics MATLAB numbers and numeric formats

FreeFem++, a tools to solving complex problem like Bose Einstein Condensate

How High a Degree is High Enough for High Order Finite Elements?

5: Magnitude 6: Convert to Polar 7: Convert to Rectangular

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

SOLUTIONS. f x = 6x 2 6xy 24x, f y = 3x 2 6y. To find the critical points, we solve

Høgskolen i Narvik Sivilingeniørutdanningen STE6237 ELEMENTMETODER. Oppgaver

Variable Base Interface

Linear Threshold Units

Error indicator and mesh adaption, in FreeFem++

Computational Mathematics with Python

Eigenvalues and Eigenvectors

Algebra Unpacked Content For the new Common Core standards that will be effective in all North Carolina schools in the school year.

MPI Hands-On List of the exercises

FEM Software Automation, with a case study on the Stokes Equations

We can display an object on a monitor screen in three different computer-model forms: Wireframe model Surface Model Solid model

CONCEPT-II. Overview of demo examples

Math 241, Exam 1 Information.

Chapter One Introduction to Programming

A QUICK GUIDE TO THE FORMULAS OF MULTIVARIABLE CALCULUS

Gerrit Stols

DATA ANALYSIS II. Matrix Algorithms

Visualization of 2D Domains

Simple C++ Programs. Engineering Problem Solving with C++, Etter/Ingber. Dev-C++ Dev-C++ Windows Friendly Exit. The C++ Programming Language

Trace Layer Import for Printed Circuit Boards Under Icepak

The Clean programming language. Group 25, Jingui Li, Daren Tuzi

GeoGebra. 10 lessons. Gerrit Stols

Plotting: Customizing the Graph

December 4, 2013 MATH 171 BASIC LINEAR ALGEBRA B. KITCHENS

AN INTRODUCTION TO NUMERICAL METHODS AND ANALYSIS

Introduction to the TI-Nspire CX

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

WESTMORELAND COUNTY PUBLIC SCHOOLS Integrated Instructional Pacing Guide and Checklist Computer Math

Glossary of Object Oriented Terms

Computer Graphics CS 543 Lecture 12 (Part 1) Curves. Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

Solving Simultaneous Equations and Matrices

Introduction Our choice Example Problem Final slide :-) Python + FEM. Introduction to SFE. Robert Cimrman

Modern Optimization Methods for Big Data Problems MATH11146 The University of Edinburgh

An Incomplete C++ Primer. University of Wyoming MA 5310

OpenFOAM Optimization Tools

Nonlinear Iterative Partial Least Squares Method

CS3220 Lecture Notes: QR factorization and orthogonal transformations

Examples of Tasks from CCSS Edition Course 3, Unit 5

C++ Language Tutorial

What are the place values to the left of the decimal point and their associated powers of ten?

Inner Product Spaces

This makes sense. t /t 2 dt = 1. t t 2 + 1dt = 2 du = 1 3 u3/2 u=5

Introduction to COMSOL. The Navier-Stokes Equations

Preface of Excel Guide

Math Review. for the Quantitative Reasoning Measure of the GRE revised General Test

Simulation Tools. Python for MATLAB Users I. Claus Führer. Automn Claus Führer Simulation Tools Automn / 65

Basics of I/O Streams and File I/O

Lecture 7 - Meshing. Applied Computational Fluid Dynamics

FreeFem++, 2d, 3d tools for PDE simulation

Mean value theorem, Taylors Theorem, Maxima and Minima.

Engineering Problem Solving and Excel. EGN 1006 Introduction to Engineering

ALLIED PAPER : DISCRETE MATHEMATICS (for B.Sc. Computer Technology & B.Sc. Multimedia and Web Technology)

Numerical Analysis Lecture Notes

GelAnalyzer 2010 User s manual. Contents

Feature Commercial codes In-house codes

Modélisation de problèmes spécifiques avec le logiciel libre FreeFem++

Solution of Linear Systems

FINITE ELEMENT : MATRIX FORMULATION. Georges Cailletaud Ecole des Mines de Paris, Centre des Matériaux UMR CNRS 7633

Excel Guide for Finite Mathematics and Applied Calculus

Higher Education Math Placement

Topography of an Origin Project and Workspace

CATIA V5 Tutorials. Mechanism Design & Animation. Release 18. Nader G. Zamani. University of Windsor. Jonathan M. Weaver. University of Detroit Mercy

DRAFT. Further mathematics. GCE AS and A level subject content

Tutorial: 2D Pipe Junction Using Hexa Meshing

AMATH 352 Lecture 3 MATLAB Tutorial Starting MATLAB Entering Variables

An Additive Neumann-Neumann Method for Mortar Finite Element for 4th Order Problems

Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is

An Introduction to Applied Mathematics: An Iterative Process

Largest Fixed-Aspect, Axis-Aligned Rectangle

Figure 2.1: Center of mass of four points.

1 VECTOR SPACES AND SUBSPACES

The Fourth International DERIVE-TI92/89 Conference Liverpool, U.K., July Derive 5: The Easiest... Just Got Better!

THREE DIMENSIONAL GEOMETRY

CHAPTER 1 Splines and B-splines an Introduction

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Mathematics (MAT) MAT 061 Basic Euclidean Geometry 3 Hours. MAT 051 Pre-Algebra 4 Hours

Introduction to Algebraic Geometry. Bézout s Theorem and Inflection Points

Sources: On the Web: Slides will be available on:

G563 Quantitative Paleontology. SQL databases. An introduction. Department of Geological Sciences Indiana University. (c) 2012, P.

Beginner s Matlab Tutorial

Content. Chapter 4 Functions Basic concepts on real functions 62. Credits 11

NEW YORK STATE TEACHER CERTIFICATION EXAMINATIONS

Introduction to ANSYS

Essential Mathematics for Computer Graphics fast

Solutions for Review Problems

Introduction to Solid Modeling Using SolidWorks 2012 SolidWorks Simulation Tutorial Page 1

SOME EXCEL FORMULAS AND FUNCTIONS

Transcription:

FreeFem++ Manual version 1.42 (Under construction) http://www.freefem.org http://www.ann.jussieu.fr/ hecht/freefem++.htm F. Hecht 1, O. Pironneau 2, Université Pierre et Marie Curie, Laboratoire Jacques-Louis Lions, 175 rue du Chevaleret,PARIS XIII K. Ohtsuka 3, Hiroshima Kokusai Gakuin University, Hiroshima, Japan September 6, 2004 1 mailto:hecht@ann.jussieu.fr 2 mailto:pironneau@ann.jussieu.fr 3 mailto:ohtsuka@barnard.cs.hkg.ac.jp

2

Contents 1 Introduction 7 1.1 History....................................... 8 1.2 The language................................... 8 1.3 Installation.................................... 9 2 Syntax 11 2.1 Data Types.................................... 11 2.1.1 Another Example............................. 11 2.2 List of major types................................ 12 2.3 Globals....................................... 13 2.4 Arithmetic..................................... 14 2.5 Array....................................... 16 2.6 Loops....................................... 17 2.7 Input/Output................................... 17 3 Mesh Generation 19 3.1 Square....................................... 19 3.2 Border....................................... 19 3.3 Movemesh..................................... 21 3.4 Reading and writing a mesh........................... 22 3.5 Triangulate.................................... 23 3.6 Adaptmesh.................................... 23 3.7 Trunc....................................... 26 3.8 splitmesh..................................... 27 3.9 build empty mesh................................. 27 3.10 Get Mesh numbering............................... 28 3.11 Meshing examples................................. 29 4 Finite Elements 31 4.1 Problem and solve................................ 34 4.2 Parameter Description for solve and problem................ 37 4.3 Problem definition................................ 37 4.4 Integrals...................................... 39 4.5 Variational Form, Sparse Matrix, Right Hand Side Vector........... 40 4.6 Eigen value and eigen vector........................... 41 4.7 Plot........................................ 45 4.8 link with gnuplot................................. 46 3

4 CONTENTS 4.9 link with medit.................................. 48 4.10 Convect...................................... 49 5 algorithm 51 5.1 conjugate Gradient................................ 51 5.2 Optimization................................... 52 6 More examples 53 6.1 A tutorial.edp.................................. 53 6.2 Periodic...................................... 55 6.3 Adapt.edp..................................... 56 6.4 adaptindicatorp2.edp............................... 58 6.5 Algo.edp...................................... 60 6.5.1 Non linear conjugate gradient algorithm................ 60 6.5.2 Newton Ralphson algorithm....................... 62 6.6 Stokes and Navier-Stokes............................. 63 6.6.1 Cavity.edp................................. 63 6.6.2 StokesUzawa.edp............................. 66 6.6.3 NSUzawaCahouetChabart.edp...................... 67 6.7 Readmesh.edp................................... 68 6.8 Domain decomposition.............................. 69 6.8.1 Schwarz-overlap.edp........................... 69 6.8.2 Schwarz-no-overlap.edp.......................... 71 6.8.3 Schwarz-gc.edp.............................. 72 6.9 Beam.edp..................................... 74 6.10 Fluidstruct.edp.................................. 75 6.11 Region.edp..................................... 78 6.12 FreeBoundary.edp................................. 80 6.13 nolinear-elas.edp................................. 83 7 Parallel version experimental 89 7.1 Schwarz in parallel................................ 89 8 The Graphic User Interface (FFedit) 91 8.1 Unix version.................................... 91 8.1.1 Installation of Tcl and Tk........................ 91 8.1.2 Description................................ 92 8.1.3 Cygwin version.............................. 94 8.1.4 Installation of Cygwin.......................... 95 8.1.5 Compilation and Installation of FreeFem++ under Cygwin...... 95 8.1.6 Compilation and Installation of tcl8.4.0 and tk8.4.0 under Cygwin.. 96 8.1.7 Use..................................... 99 9 Mesh Files 101 9.1 File mesh data structure............................. 101 9.2 bb File type for Store Solutions......................... 102 9.3 BB File Type for Store Solutions........................ 102 9.4 Metric File..................................... 103

CONTENTS 5 9.5 List of AM FMT, AMDBA Meshes....................... 103 10 Add new finite element 107 10.1 Some notation................................... 107 10.2 Which class of add................................ 108 10.3 How to add.................................... 111 11 Grammar 113 11.1 Keywords..................................... 113 11.2 The bison grammar................................ 113 11.3 The Types of the languages, and cast...................... 117 11.4 All the operators................................. 122 11.5 History of the software.............................. 127

6 CONTENTS

Chapter 1 Introduction A partial differential equation is a relation between a function of several variables and its (partial) derivatives. Many problems in physics, engineering, mathematics and even banking are modeled by one or several partial differential equations. Freefem is a software to solve these equations numerically. As its name says, it is a free software (see copyright for full detail) based on the Finite Element Method. This software runs on all unix OS (with g++ 2.95.2 or better and X11R6), on Window95, 98, 2000, NT, XP, on MacOS 9 and X. Many phenomena involve several different fields. Fluid-structure interactions, Lorenz forces in liquid aluminium and ocean-atmosphere problems are three such systems. These require approximations of different degrees, possibly on different meshes. Some algorithms such as Schwarz domain decomposition method also require data interpolation on different meshes within one program. freefem++ can handle these difficulties, i.e. arbitrary finite element spaces on arbitrary unstructured and adapted meshes. The characteristics of freefem++ are: A large variety of finites elements : linear and quadratic Lagrangian elements, discontinuous P1 and Raviart-Thomas elements, elements of a non-scalar type, mini-element,... Automatic interpolation of data on different meshes to an over mesh. Linear problems description thanks to a formal variational form, with access to the vectors and the matrix if needed. Includes tools to define discontinuous Galerkin formulations (please refer to the following keywords: jump, average, intalledges ) Analytic description of boundaries. specify the intersection points. When two boundaries intersect, the user must Automatic mesh generator, based on the Delaunay-Voronoi algorithm. Inner points density is proportional to the density of points on the boundary [5]. 7

8 CHAPTER 1. INTRODUCTION Metric-based anisotropic mesh adaptation. The metric can be computed automatically from the Hessien of a solution [6]. Solvers : LU, Cholesky, Crout, CG, GMRES, UMFPACK linear solver, eigenvalue and eigenvector computation. Online graphics, C++-like syntax. Many examples: Navier-Stokes, elasticity, Fluid structure, Schwarz s domain decomposition method, Eigen value problem, residual error indicator,... Parallel version using mpi 1.1 History The project has evolved from MacFem, PCfem, written in Pascal. The first C version was freefem 3.4; it offered mesh adaptation on a single mesh. A thorough rewriting in C++ led to freefem+ 1.2.10, which also included interpolation over multiple meshes (functions defined on one mesh can be used on any other mesh). Implementing the interpolation from one unstructured mesh to another was not easy because it had to be fast and nondiffusive; for each point, one had to find the containing triangle. This is one of the basic problems of computational geometry (see Preparata & Shamos[10] for example). Doing it in a minimum number of operations was a challenge. Our implementation was O(n log n) and based on a quadtree. We are now introducing freefem++, an entirely new program written in C++ and based on bison for a more adaptable freefem language. The freefem language allows for a quick specification of any partial differential system of equations. The language syntax of freefem++ is the result of a new design which makes use of the STL [15], templates and bison for its implementation. The outcome is a versatile software in which any new finite element can be included in a few hours; but a recompilation is then necessary. The library of finite elements available in freefem++ will therefore grow with the version number. So far we have linear and quadratic Lagrangian elements, discontinuous P1 and Raviart-Thomas elements. 1.2 The language Basically freefem++ is a compiler. The language it defines is typed, polymorphic and reentrant with macro generation (see 6.13). Every variable must be typed and declared in a statement; each statement separated from the next by a semicolon ;. Here is a simple example solving the Dirichlet problem inside the unit circle. We have chosen xy as the right hand side for the Laplace operator, a second degree finite element method on triangles, and a mesh with 50 points on the boundary. The linear system is solved by a Gauss LU factorisation.

1.3. INSTALLATION 9 border a(t=0,2*pi){x=cos(t); y=sin(t);label=5;}; mesh Th = buildmesh (a(50)); fespace Vh(Th,P2); Vh u,v; func f= x*y; problem laplace(u,v,solver=lu) = int2d(th)(dx(u)*dx(v) + dy(u)*dy(v)) // bilinear part - int2d(th)( f*v) // right hand side + on(5,u=0) ; // Dirichlet boundary condition real cpu=clock(); laplace; plot(u); cout << " CPU = " << clock()-cpu << endl; // SOLVE THE PDE Reserved words are shown in blue. pi, x, y, label, solver are reserved variables. It is allowed (although not advisable) to redefine these variables, so they will not be highlighted again in the following example programs. This example shows some of the characteristics of freefem++ : Boundaries are described analytically (by opposition to CSG). In the case where two boundaries intersect, the user must specify the intersection points in case two boundaries intersect. The domain will be on the left side of the oriented boundary. Automatic mesh generation, based on the Delaunay-Voronoi algorithm. Inner points are generated with a density proportional to the density of points on the boundary (hence a refined mesh is obtained by increasing the number of boundary points). Preprogrammed library of arbitrary degree elements. Every variable is typed. For instance f is a function, specified by the keyword func. Online graphics (see the documentation below for zoom, postscript and other commands). C++-like syntax. 1.3 Installation There are binary packages available for Microsoft Windows and Apple Mac OS. For all other platforms, freefem++ must be compiled and installed from the source archive. This archive is available from http://www.ann.jussieu.fr/ hecht/ftp/freefem/freefem+ +.tgz. To extract files from the compressed archive freefem++.tgz into a directory called freefem++-x.xx (where X.XX is the version number) enter the following commands in a shell window : tar zxvf freefem++.tgz cd freefem++-x.xx

10 CHAPTER 1. INTRODUCTION To compile and install freefem++, just follow the INSTALL and README files. The following programs are produced, depending on the system you are running (Linux, Windows, MacOS) : 1. FreeFem++, standard version, with a graphical interface based on X11, Win32 or MacOS 2. FreeFem++-nw, postscript output only (batch version, no windows) 3. FreeFem++-mpi, parallel version, postscript output only 4. FreeFem++-glx, graphics using OpenGL and X11 5. /Applications/FreeFem++.app, Drag and Drop CoCoa MacOs Application 6. FreeFem++-CoCoa, MacOS Shell script for MacOS OpenGL version (MacOS 10.2 or better) (note: it uses /Applications/FreeFem++.app) As an installation test, go into the directory examples++-tutorial and run freefem++ on the example script LaplaceP1.edp with the command : FreeFem++ LaplaceP1.edp

Chapter 2 Syntax 2.1 Data Types Every variable must be declared together with its type. The language allows the manipulation of basic types : integers (int), reals (real), strings (string), arrays (example: real[int]), bidimensional (2D) finite element meshes (mesh), 2D finite element spaces (fespace), finite element functions (fespace variable), functions (func), arrays of finite element functions (fespace variable[basictype]), linear and bilinear operators, sparse matrices, vectors, etc. For instance : int i,n=20; // i, n Z real pi=4*atan(1.); // pi R(redef ine) real[int] xx(n),yy(n); // two array of size n for (i=0;i<=20;i++) // which can be used in statements such as this { xx[i]= cos(i*pi/10); yy[i]= sin(i*pi/10); } where int, real, complex correspond to the C types long, double, complex<double>. The scope of a variable is the current block (delimited by {...} ) as in C++, except the fespace variable. The variables which are local to a block are destroyed at the end of the block. Type declarations are compulsory in freefem++. This is necessary to prevent many potential programming errors related to type mismatch. A variable name is just an alphanumeric string. The underscore character is not allowed because it will be used as an operator in the future. 2.1.1 Another Example real r= 0.01; mesh Th=square(10,10); // unit square mesh fespace Vh(Th,P1); // P1 lagrange finite element space Vh u = x+ exp(y); 11

12 CHAPTER 2. SYNTAX func f = z * x + r * log(y); plot(u,wait=1); { // new block real r= 2; // not the same r fespace Vh(Th,P1); // error because Vh is a global name } // here r==0.01 Note 1 Notice the use of wait to monitor the time a graph stays on screen (i.e. the time freefem stops before going to the next instruction). 2.2 List of major types bool a C++ true, false value; int long integer; string a C++ string; real double; complex complex<double>; ofstream ofstream to output to a file ifstream ifstream to input from a file real[int] array of reals (integer index); real[int,int] matrix of reals (2 integers indices); real[string] array of reals (string index); string[string] array of string (string index); mesh[int] array of meshes (integer index); func define a function (on one line, without arguments) func f=cos(x)+sin(y);. Please note that the function type is given by the type of the expression. mesh defines a mesh. e.g. mesh Th=buildmesh(circle(10)); fespace to define a new type of finite element space. e.g. the available finite elements are : fespace Vh(Th,P1);. At present, P0 constant discontinuous finite element P1 linear piecewise continuous finite element P2 P 2 piecewise continuous finite element, where P 2 is the set of polynoms of R 2 of degree two, RT0 the Raviart-Thomas finite element, P1nc non-conforming P 1 finite element, P1dc linear piecewise discontinuous finite element P2dc P 2 piecewise discontinuous finite element

2.3. GLOBALS 13 P1b linear piecewise continuous finite element + bubble To define p as a function belonging to fespace Vh : Vh p;. T odefine a as an array of 10 functions from Vh : Vh a[10]; problem defines a pde problem without solving it. solve defines a pde problem and solves it. varf defines a full variational form. matrix defines a sparse matrix. Constant values for the above type can be : true is a constant of type bool, false is a constant of type bool, 123 is an integer, 123. is of type real, 123.e10 is a constant of type real and value 123 10 10. Please note that the syntax of a real number is the same as in C++ or fortran. "abcd" is a constant of type string. There are two escape characters allowed in string constants : \n to insert a newline and \" to insert a ". 2.3 Globals The following names are related to the underlying finite element abstractions : x the x coordinate of the current point (real value) y the y coordinate of the current point (real value) z the z coordinate of the current point (real value), (reserved for future use). label the boundary label number of the current point if it is on a boundary, otherwise 0 (integer value). region a function returning the region number of the current point (x,y,z). Integer value. P current point (R 3 value. P.x, P.y, P.z) N normal vector at the current point (R 3 value, N.x, N.y, N.z). lenedge length of the current edge htriangle size of the current triangle nutriangle integer index of the current triangle

14 CHAPTER 2. SYNTAX nuedge integer index of the current edge in the triangle ntonedge integer: number of triangle contening the current edge (1 or 2). area area of the current triangle cout console ostream cin console istream true bool value false bool value pi realapproximation of π endl the end of line string Here is how to show all types, operators and functions from inside a freefem++ program : dumptable(cout); To run a system command stored in a string (not implemented on Carbon MacOs) : exec("shell command"); 2.4 Arithmetic The available operators are the usual C operators: + - * / \% ˆ & &&! ==!= < > <= >= = += -= *= /= << >> ++ --, with the same meaning as in C++ except for ˆ which is the power operator (with right precedence as in math or in maple), &! are the three boolean operators or, and, not.*./ are array operators (as in matlab or scilab), where is the unary right transposition of an array or a matrix.* is the term by term multiply operator../ is the term by term divide operator. some compound operators: ˆ-1 means solving a linear system (example: b = Aˆ-1 x) * is a transposition followed by a matrix product, i.e. the dot product (example real DotProduct=a *b)

2.4. ARITHMETIC 15 As in C++, there are automatic casts from a type to another. So in some sense we have bool int real complex and if any of these four types is copied into a string, it will be converted into a humanreadable value. Example: basics real x=3.14,y; int i,j; complex c; cout << " x = " << x << "\n"; x = 1;y=2; x=y; i=0;j=1; cout << 1 + 3 << " " << 1/3 << "\n"; cout << 10 ˆ10 << "\n"; cout << 10 ˆ-10 << "\n"; cout << -10ˆ-2+5 << "== 4.99 \n"; cout << 10ˆ-2+5 << "== 5.01 \n"; cout << "------------------ complex ---- \n" ; cout << 10-10i << " \n"; cout << " -1ˆ(1/3) = " << (-1+0i)ˆ(1./3.) << " \n"; cout << " 8ˆ(1/3)= " << (8)ˆ(1./3.) << " \n"; cout << " sqrt(-1) = " << sqrt(-1+0i) << " \n"; cout << " ++i =" << ++i ; cout << " i=" << i << "\n"; cout << " i++ = "<< i++ << "\n"; cout << " i = " << i << "\n"; // ---- string concatenation ---------- string str,str1; str="abc+"; str1="+abcddddd+"; str=str + str1; // string concatenation str = str + 2 ; cout << "str= " << str << "== abc++abcddddd+2;\n"; R3 P; P.x=1; x=p.x; cout <<"P.x = "<< P.x << endl; output displayed on the console: x = 3.14 4 0 1e+10 1e-10 4.99== 4.99 5.01== 5.01 ------------------ complex ---- (10,-10)

16 CHAPTER 2. SYNTAX -1ˆ(1/3) = (0.5,0.866025) 8ˆ(1/3)= 2 sqrt(-1) = (6.12323e-17,1) ++i =1 i=1 i++ = 1 i = 2 str= abc++abcddddd+2== abc++abcddddd+2; P.x = 1 The usual mathematical functions are implemented: sqrt, pow, exp, log, sin, cos, atan, cosh, sinh, tanh, min, max, etc... And usual C++ functions are implemented: exit, assert 2.5 Array There are 2 kinds of arrays: arrays with integer indices and arrays with string indices. In the first case, the size of this array must be known at execution time, and the implementation is done with the KN<> class so all the vector operations of KN<> are implemented. It is also possible to build an array of FE functions with the same syntax. The second case is just a map of the STL 1 [15] so no vector operation is allowed, except for the selection of an item. The transpose operator is (as in MathLab or SciLab), so the way to compute the dot product of two arrays a,b is real ab= a *b. int i; real [int] tab(10), tab1(10); // 2 arrays of 10 reals real [int] tab2; // bug! missing array size tab = 1; // set all array elements to 1 tab[1]=2; cout << tab[1] << " " << tab[9] << " size of tab = " << tab.n << " " << tab.min << " " << tab.max << " " << endl; tab1=tab; tab=tab+tab1; tab=2*tab+tab1*5; tab1=2*tab-tab1*5; tab+=tab; cout << " dot product " << tab *tab << endl; // t tab tab cout << tab << endl; cout << tab[1] << " " << tab[9] << endl; real[string] map; // a dynamic array for (i=0;i<10;i=i+1) { tab[i] = i*i; cout << i << " " << tab[i] << "\n"; }; map["1"]=2.0; map[2]=3.0; // 2 is automatically cast to the string "2" 1 Standard template Library, now part of standard C++

2.6. LOOPS 17 cout << " map[\"1\"] = " << map["1"] << "; "<< endl; cout << " map[2] = " << map[2] << "; "<< endl; string[string] tt; // a array of string 2.6 Loops for and while loops are implemented, with the same semantics as in C++, including keywords break and continue. int i; for (i=0;i<10;i=i+1) cout << i << "\n"; real eps=1; while (eps>1e-5) { eps = eps/2; if( i++ <100) break; cout << eps << endl;} 2.7 Input/Output The syntax of input/output statements is similar to C++ syntax. It uses cout, cin, endl, <<, >>. To write to (resp. read from) a file, declare a new variable ofstream ofile("filename"); or ofstream ofile("filename",append); (resp. ifstream ifile("filename"); ) and use ofile (resp. ifile) as cout (resp. cin). The word append in ofstream ofile("filename",append); means opening a file in append mode. Note 2 The file is closed at the end of the enclosing block, int i; cout << " std-out" << endl; cout << " enter i=? "; cin >> i ; { ofstream f("toto.txt"); f << i << "coucou \n"; }; // file f closed here because variable f is deleted { } { ifstream f("toto.txt"); f >> i; ofstream f("toto.txt",append); // appending data to file "toto.txt" f << i << "coucou \n"; }; // file f closed here because variable f is deleted cout << i << endl;

18 CHAPTER 2. SYNTAX

Chapter 3 Mesh Generation The following keywords are discussed in this section: square, border, buildmesh, movemesh, adaptmesh, readmesh, trunc, triangulate, splitmesh, emptymesh All the examples in this section come from the files mesh.edp and tablefunction.edp. 3.1 Square For easy and simple testing we have included a constructor for rectangles. All other shapes should be handled with border and buildmesh. The following real x0=1.2,x1=1.8; real y0=0,y1=1; int n=5,m=20; mesh Th=square(n,m,[x0+(x1-x0)*x,y0+(y1-y0)*y]); mesh th=square(4,5); plot(th,th,ps="twosquare.eps"); constructs a n m grid in the rectangle [1.2, 1.8] [0, 1] and a 4 5 grid in the unit square [0, 1] 2. Note 3 Boundary labels are numbered 1, 2, 3, 4 for bottom, right, top, left side (before the mapping [x0 + (x1 x0) x, y0 + (y1 y0) y] (the mapping can be non linear). 3.2 Border A domain is defined as being on the left (resp right) of its parameterized boundary (when looking towards increasing values of the parameter) if the sign of the expression that returns the number of vertices on the boundary is positive (resp negative). note: the boundary label must be non-zero if you you want to specify a boundary condition on this border For instance the domain delimited by the unit circle, with a small circular hole inside would be described as: real pi=4*atan(1); 19

20 CHAPTER 3. MESH GENERATION Figure 3.1: The 2 square meshes border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;} border b(t=0,2*pi){ x=0.3+0.3*cos(t); y=0.3*sin(t);label=2;} plot(a(50)+b(+30)) ; // to see a plot of the border mesh mesh Thwithouthole= buildmesh(a(50)+b(+30)); mesh Thwithhole = buildmesh(a(50)+b(-30)); plot(thwithouthole,wait=1,ps="thwithouthole.eps"); // figure 3.2 plot(thwithhole,wait=1,ps="thwithhole.eps"); // figure 3.3 Note 4 The use of ps="filename" generates a postscript file identical to the plot shown on screen. Figure 3.2: mesh without hole Figure 3.3: mesh with hole Note that boundaries can only intersect at their end points.

3.3. MOVEMESH 21 3.3 Movemesh As the two last statements in the example below show, mesh motion is possible. Sometimes the moved mesh is invalid because some triangle becomes reversed (with a negative area). This is why we check the minimum triangle area in the transformed mesh with checkmovemesh before any real transformation. real Pi=atan(1)*4; verbosity=4; border a(t=0,1){x=t;y=0;label=1;}; border b(t=0,0.5){x=1;y=t;label=1;}; border c(t=0,0.5){x=1-t;y=0.5;label=1;}; border d(t=0.5,1){x=0.5;y=t;label=1;}; border e(t=0.5,1){x=1-t;y=1;label=1;}; border f(t=0,1){x=0;y=1-t;label=1;}; func uu= sin(y*pi)/10; func vv= cos(x*pi)/10; mesh Th = buildmesh ( a(6) + b(4) + c(4) +d(4) + e(4) + f(6)); plot(th,wait=1,fill=1,ps="lshape.eps"); // see figure?? real coef=1; real mint0= checkmovemesh(th,[x,y]); // the min triangle area while(1) // find a correct move mesh { real mint=checkmovemesh(th,[x+coef*uu,y+coef*vv]); // the min triangle area if (mint > mint0/5) break ; // if big enough coef=/1.5; } Th=movemesh(Th,[x+coef*uu,y+coef*vv]); plot(th,wait=1,fill=1,ps="movemesh.eps"); // see figure 3.5 Figure 3.4: L-shape Figure 3.5: moved L-shape

22 CHAPTER 3. MESH GENERATION Note 5 Consider a function u defined on a mesh Th. A statement like Th=movemesh(Th... does not change u and so the old mesh still exists. It will be destroyed when no function use it. A statement like u = u redefines u on the new mesh Th with interpolation and therefore destroys the old Th if u was the only function using it. Now, an example of moving mesh, with lagrangian function u defined on the moving mesh. mesh Th=square(10,10); fespace Vh(Th,P1); real t=0; // simple movemesh example // --- // the problem is how to build data without interpolation // so the data u is moving with the mesh as you can see in the plot // --- Vh u=y; for (int i=0;i<4;i++) { t=i*0.1; Vh f= x*t; real minarea=checkmovemesh(th,[x,y+f]); if (minarea >0 ) // movemesh will be ok Th=movemesh(Th,[x,y+f]); cout << " Min area " << minarea << endl; real[int] tmp(u[].u); tmp=u[]; // save the value u=0; // to change the FEspace and mesh associated with u u[]=tmp; // set the value of u without any mesh update plot(th,u,wait=1); }; // In this program, since u is only defined on the last mesh, all the // previous meshes are deleted from memory. // -------- 3.4 Reading and writing a mesh Freefem can read and write files. A mesh file can be read back into freefem++ but the names of the borders are lost. So these borders have to be referenced by the number which corresponds to their order of appearance in the program, unless this number is forced by the keyword label. border floor(t=0,1){ x=t; y=0; label=1;}; // the unit square border right(t=0,1){ x=1; y=t; label=5;}; border ceiling(t=1,0){ x=t; y=1; label=5;}; border left(t=1,0){ x=0; y=t; label=5;}; int n=10; mesh th= buildmesh(floor(n)+right(n)+ceiling(n)+left(n)); savemesh(th,"toto.am_fmt"); // "formatted Marrocco" format savemesh(th,"toto.th"); // "bamg"-type mesh savemesh(th,"toto.msh"); // freefem format

3.5. TRIANGULATE 23 savemesh(th,"toto.nopo"); // modulef format see [7] mesh th2 = readmesh("toto.msh"); // read the mesh There are many mesh file formats available for communication with other tools such as emc2, modulef... The suffix gives the chosen type. More details can be found in the article by F. Hecht bamg : a bidimentional anisotropic mesh generator available from the freefem web page. 3.5 Triangulate freefem++ is able to build a triangulation from a set of points. This triangulation is a Delaunay mesh of the convex hull of the set of points. It can be useful to build a table function. The coordinates of the points and the value of the table function are defined in a separate file which looks like : 0.51387 0.175741 0.636237 0.308652 0.534534 0.746765 0.947628 0.171736 0.899823 0.702231 0.226431 0.800819 0.494773 0.12472 0.580623 0.0838988 0.389647 0.456045 The third column of each line is left untouched by the triangulate command. But you can use this third value to define a table function with rows of the form: x y f(x,y). mesh Thxy=triangulate("xyf"); // build the Delaunay mesh of the convex hull // points are defined by the first 2 columns of file xyf plot(thxy,ps="thxyf.ps"); // (see figure??) fespace Vhxy(Thxy,P1); // create a P1 interpolation Vhxy fxy; // the function // reading the third row to define the function { ifstream file("xyf"); real xx,yy; for(int i=0;i<fxy.n;i++) file >> xx >>yy >> fxy[][i]; // to read third row only. xx and yy are just skipped } plot(fxu,ps="xyf.ps"); // plot the function (see figure??) 3.6 Adaptmesh Mesh adaptation is a very powerful tool which should be used whenever possible. freefem++ uses a variable metric/delaunay automatic meshing algorithm. It takes one or more functions as input (see in the following example) and builds a mesh adapted to the second derivative of the given function.

24 CHAPTER 3. MESH GENERATION verbosity=2; mesh Th=square(10,10,[10*x,5*y]); fespace Vh(Th,P1); Vh u,v,zero; u=0; u=0; zero=0; func f= 1; func g= 0; int i=0; real error=0.1, coef= 0.1ˆ(1./5.); problem Problem1(u,v,solver=CG,init=i,eps=-1.0e-6) = // int2d(th)( dx(u)*dx(v) + dy(u)*dy(v)) + int2d(th) ( v*f ) + on(1,2,3,4,u=g) ; real cpu=clock(); for (i=0;i< 10;i++) { real d = clock(); Problem1; plot(u,zero,wait=1); Th=adaptmesh(Th,u,inquire=1,err=error); cout << " CPU = " << clock()-d << endl; error = error * coef; } ; cout << " CPU = " << clock()-cpu << endl; This method is described in detail in [6]. It has a number of default parameters which can be modified : hmin= Minimum edge size. (val is a double precision value. Its default is related to the size of the domain to be meshed and the precision of the mesh generator). hmax= Maximum edge size. (val is a double precision value. It defaults to the diameter of the domain to be meshed) err= P 1 interpolation error level (0.01 is the default). errg= Relative geometrical error. By default this error is 0.01, and in any case it must be lower than 1/ 2. Meshes created with this option may have some edges smaller than the -hmin argument due to geometrical constraints. nbvx= Maximum number of vertices generated by the mesh generator (9000 is the default). nbsmooth= number of iterations of the smoothing procedure (5 is the default). nbjacoby= number of iterations in a smoothing procedure during the metric construction, 0 means no smoothing (6 is the default).

3.6. ADAPTMESH 25 ratio= ratio for a prescribed smoothing on the metric. If the value is 0 or less than 1.1 no smoothing is done on the metric (1.8 is the default). If ratio > 1.1, the speed of mesh size variations is bounded by log(ratio). Note: As ratio gets closer to 1, the number of generated vertices increases. This may be useful to control the thickness of refined regions near shocks or boundary layers. omega= relaxation parameter for the smoothing procedure (1.0 is the default). iso= If true, forces the metric to be isotropic (false is the default). abserror= If false, the metric is evaluated using the criterium of equi-repartion of relative error (false is the default). In this case the metric is defined by ( 1 M = err coef 2 ) p H (3.1) max(cutoff, η ) otherwise, the metric is evaluated using the criterium of equi-distribution of errors. In this case the metric is defined by ( ) p 1 H M =. (3.2) err coef 2 sup(η) inf (η) cutoff= lower limit for the relative error evaluation (1.0e-6 is the default). verbosity= informational messages level (can be chosen between 0 and ). Also changes the value of the global variable verbosity (obsolete). inquire= To inquire graphicaly about the mesh (false is the default). splitpbedge= If true, splits all internal edges in half with two boundary vertices (true is the default). maxsubdiv= Changes the metric such that the maximum subdivision of a background edge is bound by val (always limited by 10, and 10 is also the default). rescaling= if true, the function with respect to which the mesh is adapted is rescaled to be between 0 and 1 (true is the default). keepbackvertices= if true, tries to keep as many vertices from the original mesh as possible (true is the default). ismetric= if true, the metric is defined explicitly (false is the default). If the 3 functions m 11, m 12, m 22 are given, they directly define a symmetric matrix field whose Hessian is computed to define a metric. If only one function is given, then it represents the isotropic mesh size at every point. power= exponent power of the Hessian used to compute the metric (1 is the default). thetamax= minimum corner angle in degrees (default is 0).

26 CHAPTER 3. MESH GENERATION splitin2= boolean value. If true, splits all triangles of the final mesh into 4 sub-triangles. metric= an array of 3 real arrays to set or get metric data information. The size of these three arrays must be the number of vertices. So if m11,m12,m22 are three P1 finite elements related to the mesh to adapt, you can write: metric=[m11[],m12[],m22[]] (see file convect-apt.edp for a full example) nomeshgeneration= If true, no adapted mesh is generated (useful to compute only a metric). periodic= use: builds an adapted periodic mesh, you can write periodic=[[4,y],[2,y],[1,x] to build a biperiodic mesh of a square. (see periodic finite element spaces 4, and see sphere.edp for a full example) 3.7 Trunc A small operator to create a truncated mesh from a mesh with respect to a boolean function. The two named parameter label= sets the label number of new boundary item (one by default) split= sets the level n of triangle splitting. each triangle is splitted in n n ( one by default). To create the mesh Th3 where alls triangles of a mesh Th are splitted in 3 3, just write: mesh Th3 = trunc(th,1,split=3); The truncmesh.edp example construct all trunc mesh to the support of the basic function of the space Vh (cf. abs(u)>0), split all the triangles in 5 5, and put a label number to 2 on new boundary. mesh Th=square(3,3); fespace Vh(Th,P1); Vh u; int i,n=u.n; u=0; for (i=0;i<n;i++) // all degre of freedom { u[][i]=1; // the basic function i plot(u,wait=1); mesh Sh1=trunc(Th,abs(u)>1.e-10,split=5,label=2); plot(th,sh1,wait=1,ps="trunc"+i+".eps"); // plot the mesh of // the function s support u[][i]=0; // reset }

3.8. SPLITMESH 27 Figure 3.6: mesh of support the function P1 number 0, splitted in 5 5 Figure 3.7: mesh of support the function P1 number 6, splitted in 5 5 3.8 splitmesh A other way to split mesh triangle: { // new stuff 2004 splitmesh (version 1.37) assert(version>=1.37); border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;} plot(th,wait=1,ps="nosplitmesh.eps"); // see figure 3.8 mesh Th=buildmesh(a(20)); plot(th,wait=1); Th=splitmesh(Th,1+5*(square(x-0.5)+y*y)); plot(th,wait=1,ps="splitmesh.eps"); // see figure 3.9 } 3.9 build empty mesh The idea is when you want to defined Finite Element space on boundary you can use a mesh with no internal points (call empty mesh). It is can by useful we you have a Lagrange multiplier definied on the border. So the function emptymesh remove all the internal point of a mesh expect if the point is on internal boundary. { // new stuff 2004 emptymesh (version 1.40) // -- useful to build Multiplicator space // build a mesh without internal point // with the same boundary // ----- assert(version>=1.40); border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;} mesh Th=buildmesh(a(20)); Th=emptymesh(Th); plot(th,wait=1,ps="emptymesh-1.eps"); // see figure 3.10

28 CHAPTER 3. MESH GENERATION Figure 3.8: initial mesh Figure 3.9: all left mesh triangle is split conformaly in int(1+5*(square(x-0.5)+y*y)ˆ2 triangles. } or it is also possible to build a empty mesh of peusdo subregion with emptymesh(th,ssd) with the set of edges of the mesh Th a edge e is in this set if the two adjacent triangles e = t1 t2 and ssd[t 1] ssd[t 2] where ssd defined the peusdo region numbering of triangle. It is an user int[int] array of size the number of triangles. { // new stuff 2004 emptymesh (version 1.40) // -- useful to build Multiplicator space // build a mesh without internal point // of peusdo sub domain // ----- assert(version>=1.40); mesh Th=square(10,10); int[int] ssd(th.nt); for(int i=0;i<ssd.n;i++) // build the peusdo region numbering { int iq=i/2; // because 2 traingle per quad int ix=iq%10; // int iy=iq/10; // ssd[i]= 1 + (ix>=5) + (iy>=5)*2; } Th=emptymesh(Th,ssd); // build emtpy with // all edge e = T 1 T 2 and ssd[t 1] ssd[t 2] plot(th,wait=1,ps="emptymesh-2.eps"); // see figure 3.11 savemesh(th,"emptymesh-2.msh"); } 3.10 Get Mesh numbering { // get mesh information (version 1.37)

3.11. MESHING EXAMPLES 29 The empty mesh with bound- Figure 3.10: ary Figure 3.11: An empty mesh defined from a peusdo region numbering of triangle mesh Th=square(2,2); // get data of the mesh int nbtriangles=th.nt; for (int i=0;i<nbtriangles;i++) for (int j=0; j <3; j++) cout << i << " " << j << " Th[i][j] = " << Th[i][j] << " x = "<< Th[i][j].x << ", y= "<< Th[i][j].y << ", label=" << Th[i][j].label << endl; } the output is: 0 0 Th[i][j] = 0 x = 0, y= 0, label=4 0 1 Th[i][j] = 1 x = 0.5, y= 0, label=1 0 2 Th[i][j] = 4 x = 0.5, y= 0.5, label=0 1 0 Th[i][j] = 0 x = 0, y= 0, label=4 1 1 Th[i][j] = 4 x = 0.5, y= 0.5, label=0 1 2 Th[i][j] = 3 x = 0, y= 0.5, label=4... 5 2 Th[i][j] = 6 x = 0, y= 1, label=4 6 0 Th[i][j] = 4 x = 0.5, y= 0.5, label=0 6 1 Th[i][j] = 5 x = 1, y= 0.5, label=2 6 2 Th[i][j] = 8 x = 1, y= 1, label=3 7 0 Th[i][j] = 4 x = 0.5, y= 0.5, label=0 7 1 Th[i][j] = 8 x = 1, y= 1, label=3 7 2 Th[i][j] = 7 x = 0.5, y= 1, label=3 3.11 Meshing examples Example: 1: The mesh for a corner singularity The domain is an L-shape: border a(t=0,1){x=t;y=0;label=1;};

30 CHAPTER 3. MESH GENERATION border b(t=0,0.5){x=1;y=t;label=1;}; border c(t=0,0.5){x=1-t;y=0.5;label=1;}; border d(t=0.5,1){x=0.5;y=t;label=1;}; border e(t=0.5,1){x=1-t;y=1;label=1;}; border f(t=0,1){x=0;y=1-t;label=1;}; mesh rh = buildmesh (a(6) + b(4) + c(4) +d(4) + e(4) + f(6)); Example: 2: Meshes for domain decompositions To test the domain decomposition algorithms described below we will need 2 overlapping meshes of a single domain. border a(t=0,1){x=t;y=0;}; border a1(t=1,2){x=t;y=0;}; border b(t=0,1){x=2;y=t;}; border c(t=2,0){x=t ;y=1;}; border d(t=1,0){x = 0; y = t;}; border e(t=0, pi/2){ x= cos(t); y = sin(t);}; border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);}; n=4; mesh sh = buildmesh(a(5*n)+a1(5*n)+b(5*n)+c(10*n)+d(5*n)); mesh SH = buildmesh ( e(5*n) + e1(25*n) ); plot(sh,sh); Example: 3: Meshes for fluid-structure interactions Two rectangles touching by a side. border a(t=0,1){x=t;y=0;}; border b(t=0,1){x=1;y=t;}; border c(t=1,0){x=t ;y=1;}; border d(t=1,0){x = 0; y=t;}; border c1(t=0,1){x=t ;y=1;}; border e(t=0,0.2){x=1;y=1+t;}; border f(t=1,0){x=t ;y=1.2;}; border g(t=0.2,0){x=0;y=1+t;}; int n=1; mesh th = buildmesh(a(10*n)+b(10*n)+c(10*n)+d(10*n)); mesh TH = buildmesh ( c1(10*n) + e(5*n) + f(10*n) + g(5*n) ); plot(th,th);

Chapter 4 Finite Elements To use a finite element, one needs to define a finite element space with the keyword fespace (short of finite element space) like fespace IDspace(IDmesh,<IDFE>) ; or with k pair of periodic boundary condition fespace IDspace(IDmesh,<IDFE>, periodic=[[la 1,sa 1],[lb 1,sb 1],... [la k,sa k],[lb k,sb k]]); where IDspace is the name of the space for example Vh, IDmesh is the name of the associated mesh and <IDFE> is a identifier of finite element type, where a pair of periodic boundary condition is defined by [la i,sa i ],[lb i,sb i ]. The int expressions la i and lb i are defined the 2 labels of the piece of the boundary to be equivalence, and the real expressions sa i and sb i a give two common abcissa on the two boundary curve, and two points are identify if the two abcissa are equal. As of today, the known types of finite element are: P0 piecewise constante discontinuous finite element P 0 h = {v L 2 (Ω) ; K T h α K R : v K = α K } (4.1) P1 piecewise linear continuous finite element P1dc piecewise linear discontinuous finite element P 1 h = {v H 1 (Ω) ; K T h v K P 1 } (4.2) P 1dc h = {v L 2 (Ω) ; K T h v K P 1 } (4.3) P1b piecewise linear continuous finite element plus bubble P 1b h = { v H 1 (Ω) ; K T h v K P 1 Span{λ K 0 λ K 1 λ K 2 } } (4.4) where λ K i, i = 0, 1, 2 are the 3 barycentric coordinate functions of the triangle K 31

32 CHAPTER 4. FINITE ELEMENTS P2 piecewise P 2 continuous finite element, P 2 h = {v H 1 (Ω) ; K T h v K P 2 } (4.5) where P 2 is the set of polynomials of R 2 of degrees at most 2. P2dc piecewise P 2 discontinuous finite element, P 2dc h = {v L 2 (Ω) ; K T h v K P 2 } (4.6) RT0 Raviart-Thomas finite element RT 0 h = {v H(div)/ K T h v K (x, y) = α K βk + γ K x y } (4.7) where H(div) is the set of function of L 2 (Ω) with divergence in L 2 (Ω), and where α K, β K, γ K are real numbers. P1nc piecewise linear element continuous at the middle of edge only. To define the finite element spaces X h = {v H 1 (]0, 1[ 2 ) ; K T h v K P 1 } X ph = {v X h ; v( 0. ) = v( 1. ), v(. 0 ) = v(. 1 )} M h = {v H 1 (]0, 1[ 2 ) ; K T h v K P 2 } R h = {v H 1 (]0, 1[ 2 ) 2 ; K T h where T is a mesh 10 10 of the unit square ]0, 1[ 2, the corresponding freefem++ definitions are: v K (x, y) = α K βk + γ K x y } mesh Th=square(10,10); // border label: 1 down, 2 left, 3 up, 4 right fespace Xh(Th,P1); // scalar FE fespace Xph(Th,P1,periodic=[[2,y],[4,y],[1,x],[3,x]]); // bi-periodic FE fespace Mh(Th,P2); // scalar FE fespace Rh(Th,RT0); // vectorial FE so Xh,Mh,Rh are finite element spaces (called FE spaces ). Now to use functions u h, v h X h and p h, q h M h and U h, V h R h one can define the FE function like this Xh uh,vh; Xph uph,vph; Mh ph,qh; Rh [Uxh,Uyh],[Vxh,Vyh]; Xh[int] Uh(10); // array of 10 function in Xh Rh[int] [Wxh,Wyh](10); // array of 10 functions in Rh. The functions U h, V h have two components so we have. U h = Uxh Uyh and V h = V xh V yh

Like in the previous version, freefem+, the finite element functions (type FE functions) are both functions from R 2 to R N with N = 1 for scalar function and arrays of real. To interpolate a function, one writes uh = xˆ2 + yˆ2; // ok uh is scalar FE function [Uxh,Uyh] = [sin(x),cos(y)]; // ok vectorial FE function Uxh = x; // error: impossible to set only 1 component // of a vector FE function. vh = Uxh; // ok Th=square(5,5); vh=vh; // re-interpolates vh on the new mesh square(5,5); vh([x-1/2,y])= xˆ2 + yˆ2; // interpole vh = ((x 1/2) 2 + Y 2 ) 33 To get the value at a point x = 1, y = 2 of the FE function uh, or [Uxh,Uyh],one writes real value; value = uh(2,4); // get value= uh(2,4) value = Uxh(2,4); // get value= Uxh(2,4) // ------ or ------ x=1;y=2; value = uh; // get value= uh(1,2) value = Uxh; // get value= Uxh(1,2) value = Uyh; // get value= Uyh(1,2). To get the value of the array associated to the FE function uh, one writes real value = uh[][0] ; // get the value of degree of freedom 0 real maxdf = uh[].max; // maximum value of degree of freedom int size = uh.n; // the number of degree of freedom real[int] array(uh.n)= uh[]; // copy the array of the function uh Warning for no scalar finite element function [Uxh,Uyh] the two array Uxh[] and Uyh[] are the same array, because the degre of freedom can touch more than one componant. The other way to set a FE function is to solve a problem (see below). Note 6 It is possible to change a mesh to do a convergence test for example, but see what happens in this trivial example. In fact a FE function is three pointers, one pointer to the values, second a pointer to the definition of fespace, third a pointer to the fespace. This fespace can be rebuild if the associated mesh have changed when the FE function is set with operator = or when a problem is solved. mesh Th=square(2,2); fespace Xh(Th,P1); Xh uh,vh; vh= xˆ2+yˆ2; // vh Th = square(5,5); // change the mesh // Xh is unchange uh = xˆ2+yˆ2; // compute on the new Xh // and now uh use the 5x5 mesh // but the fespace of vh is alway the 2x2 mesh plot(vh,ps="onoldmesh.eps"); // figure 4.1 vh = vh; // do a interpolation of vh (old) of 5x5 mesh // to get the new vh on 10x10 mesh. plot(vh,ps="onnewmesh.eps"); // figure 4.2

34 CHAPTER 4. FINITE ELEMENTS Figure 4.1: vh Iso on mesh 2 2 Figure 4.2: vh Iso on mesh 5 5 4.1 Problem and solve For freefem++ a problem must be given in variational form, so a bilinear form, a linear form, and possibly a boundary condition form must be input. For example consider the Dirichlet problem: v = 1 in Ω =]0, 1[ 2, v = 0 on Γ = Ω. The problem can be solved by the finite element method, namely: Find u h V 0h the space of continuous piecewise linear functions on a triangulation of Ω which are zero on the boundary Ω such that u h w h = w h w h V 0h The freefem++ version of the same is Ω mesh Th=square(10,10); fespace Vh(Th,P1); // P1 FE space Vh uh,vh; // unknown and test function. func f=1; // right hand side function func g=0; // boundary condition function Ω solve laplace(uh,vh) = // definion of the problem and solve int2d(th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) // bilinear form + int2d(th)( -f*vh ) // linear form + on(1,2,3,4,uh=g) ; // a lock boundary condition form f=x+y; laplace; // solve again the problem with this new f plot(uh,ps="laplace.eps",value=true); // to see the result (figure 4.3) Note 7 Using the keywork problem in place of solve would define the problem only and not solve it.

4.1. PROBLEM AND SOLVE 35 IsoValue 0.00182747 0.0054824 0.00913734 0.0127923 0.0164472 0.0201021 0.0237571 0.027412 0.0310669 0.0347219 0.0383768 0.0420317 0.0456867 0.0493416 0.0529965 0.0566515 0.0603064 0.0639613 0.0676163 0.0712712 Figure 4.3: Isovalues of the solution A laplacian in mixed finite formulation. mesh Th=square(10,10); fespace Vh(Th,RT0); fespace Ph(Th,P0); Vh [u1,u2],[v1,v2]; Ph p,q; problem laplacemixte([u1,u2,p],[v1,v2,q],solver=lu,eps=1.0e-30) = // int2d(th)( p*q*1e-10+ u1*v1 + u2*v2 + p*(dx(v1)+dy(v2)) + (dx(u1)+dy(u2))*q ) + int2d(th) ( q) + int1d(th)( (v1*n.x +v2*n.y)/-2); // int on gamma laplacemixte; // the problem is now solved plot([u1,u2],coef=0.1,wait=1,ps="laprtuv.eps",value=true); // figure 4.4 plot(p,fill=1,wait=1,ps="lartp.eps",value=true); // figure 4.5 Vec Value 0 0.0168845 0.0337689 0.0506534 0.0675378 0.0844223 0.101307 0.118191 0.135076 0.15196 0.168845 0.185729 0.202613 0.219498 0.236382 0.253267 0.270151 0.287036 0.30392 0.320805 IsoValue -0.502006-0.496373-0.492618-0.488862-0.485107-0.481352-0.477597-0.473842-0.470086-0.466331-0.462576-0.458821-0.455066-0.45131-0.447555-0.4438-0.440045-0.43629-0.432534-0.423146 Figure 4.4: Flux (u 1, u 2 ) Figure 4.5: Isovalue of p

36 CHAPTER 4. FINITE ELEMENTS Note 8 To make programs more readable we stop now using blue color on dx,dy. An other formulation of the Laplace equation with Discontinuous Galerkine formulation with P 2 discontinuous can be write (see LapDC.epd and [17]) // file: LapDG2.edp // solve u = f on Ω and u = g on Γ macro dn(u) (N.x*dx(u)+N.y*dy(u) ) // def the normal derivative mesh Th = square(10,10); // unite square fespace Vh(Th,P2dc); // Discontinous P2 finite element // if pena = 0 => Vh must be P2 otherwise we need some penalisation real pena=0; // a paramater to add penalisation varf Ans(u,v)= int2d(th)(dx(u)*dx(v)+dy(u)*dy(v) ) + intalledges(th)( // loop on all edge of all triangle // the edge are see ntonedge times so we / ntonedge // remark: ntonedge =1 on border edge and =2 on internal // we are in a triange th normal is the exterior normal // def: jump = external - internal value; on border exter value =0 // average = (external + internal value)/2, on border just internal value ( jump(v)*average(dn(u)) - jump(u)*average(dn(v)) + pena*jump(u)*jump(v) ) / ntonedge ) ; func f=1; func g=0; Vh u,v; Xh uu,vv; problem A(u,v,solver=UMFPACK) // = Ans - int2d(th)(f*v) - int1d(th)(g*dn(v) + pena*g*v) ; problem A1(uu,vv,solver=CG) // = int2d(th)(dx(uu)*dx(vv)+dy(uu)*dy(vv)) - int2d(th)(f*vv) + on(1,2,3,4,uu=g); A; // solve DG where ntonedge is the number on triangle which see the current edge, with ntonedge==2 on internal edge and ntonedge==1 on boundary edge, jump give the jump in the direction of the external normal: external minus internal value on internal edges, and minus the internal value average is the half of the external plus internal value on internal edges and the internal value on boundary edges.

4.2. PARAMETER DESCRIPTION FOR SOLVE AND PROBLEM 37 4.2 Parameter Description for solve and problem The parameters are FE function, the number n of qfo is even (n = 2 k), the k first function parameters are unknown, and the k last are test functions. Note 9 If the functions are a part of vectoriel FE then you must give all the functions of the vectorial FE in the same order (see laplacemixte problem for example). Bug: 1 The mixing of fespace with differents periodic boundary condition is not implemented. So all the finite element space use for test or unknow functions in a problem, must have the same type of periodic boundary condition or no periodic boundary condition. No clean message is given and the result is impredictible, Sorry. The named parameters are: solver= LU, CG, Crout,Cholesky,GMRES,UMFPACK... The default solver is LU. The storage mode of the matrix of the underlying linear system depends on the type of solver chosen; for LU the matrix is sky-line non symmetric, for Crout the matrix is sky-line symmetric, for Cholesky the matrix is sky-line symmetric positive definite, for CG the matrix is sparse symmetric positive, and for GMRES or UMFPACK the matrix is just sparse. eps= a real expression. ε sets the stopping test for the iterative methods like CG. Note that if ε is negative then the stopping test is: if it is positive then the stopping test is Ax b < ε Ax b < ε Ax 0 b init= boolean expression, if it is false or 0 the matrix is reconstructed. Note that if the mesh changes the matrix is reconstructed too. precon= name of a function (for example P) to set the precondioner. the function P must be The prototype for func real[int] P(real[int] & xx) ; tgv= Huge value (10 30 ), to lock boundary conditions 4.3 Problem definition Below v is the unknown function and w is the test function. After the = sign, one may find sums of: a name; this is the name given to the variational form (type varf ) for possible reuse.

38 CHAPTER 4. FINITE ELEMENTS the bilinear form term: -) int2d(th)( K*v*w) = K v w T Th T -) int2d(th,1)( K*v*w) = T Th,T Ω 1 T K v w -) int1d(th,2,5)( K*v*w) = T Th -) intalledges(th)( K*v*w) = K v w T Th T -) intalledges(th,1)( K*v*w) = -) a sparse matrix of type matrix the linear form term: -) int1d(th)( K*w) = T Th T K w -) int1d(th,2,5)( K*w) = T Th -) intalledges(th)( f*w) = T Th -) a vector of type real[int] The boundary condition form term : ( T Γ) (Γ 2 Γ 5 ) T Th,T Ω 1 ( T Γ) (Γ 2 Γ 5 ) T f w An on form (for Dirichlet ) : on(1, u = g ) T K w K v w K v w a linear form on Γ (for Neumann ) -int1d(th))( f*w) or -int1d(th,3))( f*w) a bilinear form on Γ or Γ 2 (for Robin ) int1d(th))( K*v*w) or int1d(th,2))( K*v*w). If needed, the different kind of terms in the sum can appear more than once. Remark: the integral mesh and the mesh associated to test function or unkwon function can be different in the case of linear form. Note 10 N.x and N.y are the normal s components. Important: it is not possible to write in the same integral the linear part and the bilinear part such as in int1d(th)( K*v*w - f*w).

4.4. INTEGRALS 39 4.4 Integrals There are three kinds of integrals: surface integral defined with the keyword int2d integrals on curves int1d. integrals on the three edges of all triangles intalledges, remark the edges are see two times generaly (the variable ntonedge give this number). the syntaxe is : keywork(domain_parameters)( function ) where the (domain parameters) given the definition of the domain of integration and the kind of quadrature formulae. The (domain parameters) can be : (Th)??? (Th,1)??? (Th,1,qforder=2)??? (Th,1,qft= qf3pt, qfe= qf2pe)??? where where Th is a mesh. Integrals can be used to define the variational form, or to compute integrals proper. It is possible to choose the order of the integration formula by adding a parameter qforder= to define the order of the Gauss formula, or directly the name of the formula with qft=name in 2d integrals and qfe=name in 1d integrals. The quadrature formulae on triangles are: name (qft=) on order qforder= exact number of quadrature points qf1pt triangle 2 1 1 qf2pt triangle 3 2 3 qf3pt triangle 6 4 7 qf1ptlump triangle 4 3 qf2pt4p1 triangle 2 9 The quadrature formulae on edges are: name (qfe=) on order qforder= exact number of quadrature points qf1pe segment 2 1 1 qf2pe segment 3 2 2 qf3pe segment 6 5 3

40 CHAPTER 4. FINITE ELEMENTS 4.5 Variational Form, Sparse Matrix, Right Hand Side Vector It is possible to define variational forms: mesh Th=square(10,10); fespace Xh(Th,P2),Mh(Th,P1); Xh u1,u2,v1,v2; Mh p,q,ppp; varf bx(u1,q) = int2d(th)( (dx(u1)*q)); varf by(u1,q) = int2d(th)( (dy(u1)*q)); u 1 bx(u 1, q) = Ω h x q u 1 by(u 1, q) = Ω h y q varf a(u1,u2)= int2d(th)( dx(u1)*dx(u2) + dy(u1)*dy(u2) ) + on(1,2,4,u1=0) + on(3,u1=1) ; a(u 1, v 2 ) = u 1. u 2 ; Ω h u 1 = 1 g on Γ 3, u 1 = 0 on Γ 1 Γ 2 Γ 4 where f is defined later. Later variational forms can be used to construct right hand side vectors, matrices associated to them, or to define a new problem; Xh bc1; bc1[] = a(0,xh); // right hand side for boundary condition Xh b; matrix A= a(xh,xh,solver=cg); // the Laplace matrix matrix Bx= bx(xh,mh); // Bx = (Bx ij ) and Bx ij = bx(b x j, bm j ) // where b x j is a basis of Xh, and b m j is a basis of Mh. matrix By= by(xh,mh); // By = (By ij ) and By ij = by(b x j, bm j ) Note 11 The line of the matrix corresponding to test function on the bilinear form. Note 12 The vector bc1[] contains the contribution of the boundary condition u 1 = 1. Here we have three matrices A, Bx, By, and we can solve the problem: find u 1 X h such that a(v 1, u 1 ) = by(v 1, f), v 1 X 0h, u 1 = g, on Γ 1, and u 1 = 0 on Γ 1 Γ 2 Γ 4 with the following line (where f = x, and g = sin(x)) Mh f=x; Xh g=sin(x);

4.6. EIGEN VALUE AND EIGEN VECTOR 41 b[] = Bx *f[]; // b[] += bc1[].*bcx[]; // u1= g on Γ 3 boundary see following remark u1[] = Aˆ-1*b[]; // solve the linear system Note 13 The boundary condition is implemented by penalization and the vector bc1[] contains the contribution of the boundary condition u 1 = 1, so to change the boundary condition, we have just to multiply the vector bc1[] by the value f of the new boundary condition term by term with the operator.*. The StokesUzawa.edp 6.6.2 gives a real example of using all this features. We add automatic expression optimization by default, if this optimization trap you can remove the use of this optimization by writing for example : varf a(u1,u2)= int2d(th,optimize=false)( dx(u1)*dx(u2) + dy(u1)*dy(u2) ) + on(1,2,4,u1=0) + on(3,u1=1) ; 4.6 Eigen value and eigen vector This section depend of your FreeFem++ compilation process (see README arpack), to compile this tools. This tools is available in FreeFem++ if the word eigenvalue appear in line Load:, like: -- FreeFem++ v1.28 (date Thu Dec 26 10:56:34 CET 2002) file : LapEigenValue.edp Load: lg_fem lg_mesh eigenvalue This tools is base on the arpack++ 1 the object-oriented version of ARPACK eigenvalue package [?, arpack] The function EigenValue compute the generalized eigenvalue of Au = λbu where sigma =σ is the shift of the method. The matrix OP is defined with A σb. The return value is the number of converged eigenvalue (can be greater than the number of eigen value nev=) int k=eigenvalue(op,b,nev=, sigma= ); where the matrix OP = A σb with a solver and boundary condition, and the matrix B. sym= the problem is symmetric (all the eigen value are real) nev= the number desired eigenvalues (nev) close to the shift. value= the array to store the real part of the eigenvalues ivalue= the array to store the imag. part of the eigenvalues vector= the array to store the eigenvectors. For real nonsymmetric problems, complex eigenvectors are given as two consecutive vectors, so if eigenvalue k and k + 1 are complex conjugate eigenvalues, the kth vector will contain the real part and the k+1th vector the imaginary part of the corresponding complex conjugate eigenvectors. 1 http://www.caam.rice.edu/software/arpack/

42 CHAPTER 4. FINITE ELEMENTS tol= the relative accuracy to which eigenvalues are to be determined; sigma= the shift value; maxit= the maximum number of iterations allowed; ncv= the number of Arnoldi vectors generated at each iteration of ARPACK. In the first example, we compute the eigenvalue and the eigenvector of the Dirichlet problem on square Ω =]0, π[ 2. The problem is find: λ, and u λ in R H0(Ω) 1 u λ v = λint Ω uv v H0(Ω) 1 Ω The exact eigenvalues are λ n,m = (n 2 + m 2 ), (n, m) N 2 with the associated eigenvectors are u m,n = sin(nx) sin(my). We use the generalized inverse shift mode of the arpack++ library, to find 20 eigenvalue and eigenvector close to the shift value σ = 20. // Computation of the eigen value and eigen vector of the // Dirichlet problem on square ]0, π[ 2 // ---------------------------------------- // we use the inverse shift mode // the shift is given with the real sigma // ------------------------------------- // find λ and u λ H0 1 (Ω) such that: // u λ v = λ u λ v, v H0 1 (Ω) verbosity=10; mesh Th=square(20,20,[pi*x,pi*y]); fespace Vh(Th,P2); Vh u1,u2; Ω Ω real sigma = 20; // value of the shift // OP = A - sigma B ; // the shifted matrix varf op(u1,u2)= int2d(th)( dx(u1)*dx(u2) + dy(u1)*dy(u2) - sigma* u1*u2 ) + on(1,2,3,4,u1=0) ; // Boundary condition varf b([u1],[u2]) = int2d(th)( u1*u2 ) ; // no Boundary condition matrix OP= op(vh,vh,solver=crout,factorize=1); // crout solver because the matrix in not positive matrix B= b(vh,vh,solver=cg,eps=1e-20); // important remark: // the boundary condition is make with exact penalisation: // we put 1e30=tgv on the diagonal term of the lock degre of freedom. // So take dirichlet boundary condition just on a variationnal form // and not on b variationnanl form. // because we solve w = OP 1 B v int nev=20; // number of computed eigen valeu close to sigma

4.6. EIGEN VALUE AND EIGEN VECTOR 43 real[int] ev(nev); // to store the nev eigenvalue Vh[int] ev(nev); // to store the nev eigenvector int k=eigenvalue(op,b,sym=true,sigma=sigma,value=ev,vector=ev, tol=1e-10,maxit=0,ncv=0); // tol= the tolerace // maxit= the maximum iteration see arpack doc. // ncv see arpack doc. http://www.caam.rice.edu/software/arpack/ // the return value is number of converged eigen value. for (int i=0;i<k;i++) { u1=ev[i]; real gg = int2d(th)(dx(u1)*dx(u1) + dy(u1)*dy(u1)); real mm= int2d(th)(u1*u1) ; cout << " ---- " << i<< " " << ev[i]<< " err= " <<int2d(th)(dx(u1)*dx(u1) + dy(u1)*dy(u1) - (ev[i])*u1*u1) << " --- "<<endl; plot(ev[i],cmm="eigen Vector "+i+" valeur =" + ev[i],wait=1,value=1); } The output of this example is: Nb of edges on Mortars = 0 Nb of edges on Boundary = 80, neb = 80 Nb Of Nodes = 1681 Nb of DF = 1681 Real symmetric eigenvalue problem: A*x - B*x*lambda Thanks to ARPACK++ class ARrcSymGenEig Real symmetric eigenvalue problem: A*x - B*x*lambda Shift and invert mode sigma=20 Dimension of the system : 1681 Number of requested eigenvalues : 20 Number of converged eigenvalues : 20 Number of Arnoldi vectors generated: 41 Number of iterations taken : 2 Eigenvalues: lambda[1]: 5.0002 lambda[2]: 8.00074 lambda[3]: 10.0011 lambda[4]: 10.0011 lambda[5]: 13.002 lambda[6]: 13.0039 lambda[7]: 17.0046 lambda[8]: 17.0048 lambda[9]: 18.0083 lambda[10]: 20.0096 lambda[11]: 20.0096

44 CHAPTER 4. FINITE ELEMENTS lambda[12]: 25.014 lambda[13]: 25.0283 lambda[14]: 26.0159 lambda[15]: 26.0159 lambda[16]: 29.0258 lambda[17]: 29.0273 lambda[18]: 32.0449 lambda[19]: 34.049 lambda[20]: 34.0492 ---- 0 5.0002 err= -0.000225891 --- ---- 1 8.00074 err= -0.000787446 --- ---- 2 10.0011 err= -0.00134596 --- ---- 3 10.0011 err= -0.00134619 --- ---- 4 13.002 err= -0.00227747 --- ---- 5 13.0039 err= -0.004179 --- ---- 6 17.0046 err= -0.00623649 --- ---- 7 17.0048 err= -0.00639952 --- ---- 8 18.0083 err= -0.00862954 --- ---- 9 20.0096 err= -0.0110483 --- ---- 10 20.0096 err= -0.0110696 --- ---- 11 25.014 err= -0.0154412 --- ---- 12 25.0283 err= -0.0291014 --- ---- 13 26.0159 err= -0.0218532 --- ---- 14 26.0159 err= -0.0218544 --- ---- 15 29.0258 err= -0.0311961 --- ---- 16 29.0273 err= -0.0326472 --- ---- 17 32.0449 err= -0.0457328 --- ---- 18 34.049 err= -0.0530978 --- ---- 19 34.0492 err= -0.0536275 --- Eigen Vector 11 valeur =25.014 Eigen Vector 12 valeur =25.0283 IsoValue -0.809569-0.724351-0.639134-0.553916-0.468698-0.38348-0.298262-0.213045-0.127827-0.0426089 0.0426089 0.127827 0.213045 0.298262 0.38348 0.468698 0.553916 0.639134 0.724351 0.809569 IsoValue -0.807681-0.722662-0.637643-0.552624-0.467605-0.382586-0.297567-0.212548-0.127529-0.0425095 0.0425095 0.127529 0.212548 0.297567 0.382586 0.467605 0.552624 0.637643 0.722662 0.807681 Figure 4.6: Isovalue of 11th eigenvector Figure 4.7: Isovalue of 12th eigenvector u 4,3 u 3,4 u 4,3 + u 3,4

4.7. PLOT 45 4.7 Plot With the command plot, meshes, isovalues and vector fields can be displayed. The parameters of the plot command can be, meshes, FE functions, arrays of 2 FE functions, arrays of two arrays of double, to plot respectively mesh, isovalue, vector field, or curve defined by the two arrays of double. The named parameter are wait= boolean expression to wait or not (by default no wait). If true we wait for a keyboard up event or mouse event, the character event can be + to zoom in around the mouse cursor, - to zoom out around the mouse cursor, = to restore de initial graphics state, c to decrease the vector arrow coef, C to increase the vector arrow coef, r to refresh the graphic window, f to toggle the filling between isovalues, b to toggle the black and white, g to toggle to grey or color, v to toggle the plotting of value, p to save to a postscript file,? to show all actives keyboard char, to redraw, otherwise we continue. ps= string expression to save the plot on postscript file coef= the vector arrow coef between arrow unit and domain unit. fill= to fill between isovalues. cmm= string expression to write in the graphic window value= to plot the value of isoline and the value of vector arrow. aspectratio= boolean to be sure that the aspect ratio of plot is preserved or not. bb= array of 2 array ( like [[0.1,0.2],[0.5,0.6]]), to set the bounding box and specify a partial view where the box defined by the two corner points [0.1,0.2] and [0.5,0.6]. nbiso= (int) sets the number of isovalues (20 by default) nbarrow= (int) sets the number of colors of arrow values (20 by default) viso= sets the array value of isovalues (an array real[int])

46 CHAPTER 4. FINITE ELEMENTS varrow= sets the array value of color arrows (an array real[int]) bw= (bool) sets or not the plot in black and white color. grey= (bool) sets or not the plot in grey color. For example: real[int] xx(10),yy(10); mesh Th=square(5,5); fespace Vh(Th,P1); Vh uh=x*x+y*y,vh=-yˆ2+xˆ2; int i; // compute a cut for (i=0;i<10;i++) { x=i/10.; y=i/10.; xx[i]=i; yy[i]=uh; // value of uh at point (i/10., i/10.) } plot(th,uh,[uh,vh],value=true,ps="three.eps",wait=true); // figure 4.8 // zoom on box defined by the two corner points [0.1,0.2] and [0.5,0.6] plot(uh,[uh,vh],bb=[[0.1,0.2],[0.5,0.6]], wait=true,grey=1,fill=1,value=1,ps="threeg.eps"); // figure 4.9 plot([xx,yy],ps="likegnu.eps",wait=true); // figure 4.10 IsoValue 0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95 1.05 1.15 1.25 1.35 1.45 1.55 1.65 1.75 1.85 1.95 IsoValue -0.105263 0.0526316 0.157895 0.263158 0.368421 0.473684 0.578947 0.684211 0.789474 0.894737 1 1.10526 1.21053 1.31579 1.42105 1.52632 1.63158 1.73684 1.84211 2.10526 Vec Value 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 Vec Value 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 Figure 4.8: mesh, isovalue, and vector Figure 4.9: and vector inlargement in grey of isovalue, 4.8 link with gnuplot First this work only if gnuplot 2 is installed, and only on unix computer. You just and to the previous example: 2 http://www.gnuplot.info/

4.8. LINK WITH GNUPLOT 47 Figure 4.10: Plots a cut of uh. Note that a refinement of the same can be obtained in combination with gnuplot // file for gnuplot { ofstream gnu("plot.gp"); for (int i=0;i<=n;i++) { gnu << xx[i] << " " << yy[i] << endl; } } // the file plot.gp is close because the variable gnu is delete // to call gnuplot command and wait 5 second (tanks to unix command) // and make postscipt plot exec("echo plot \"plot.gp\" w l \ pause 5 \ set term postscript \ set output \"gnuplot.eps\" \ replot \ quit gnuplot"); 2 "plot.gp" 1.5 1 0.5 0 0 5 10 15 20 Figure 4.11: Plots a cut of uh with gnuplot

48 CHAPTER 4. FINITE ELEMENTS 4.9 link with medit First this work only if medit 3 software is installed. mesh Th=square(10,10,[2*x-1,2*y-1]); fespace Vh(Th,P1); Vh u=2-x*x-y*y; // build square ] 1, 1[ 2 savemesh(th,"mm",[x,y,u*.5]); // save mm.points and mm.faces file // for medit // build a mm.bb file { ofstream file("mm.bb"); file << "2 1 1 "<< u[].n << " 2 \n"; int j; for (j=0;j<u[].n ; j++) file << u[][j] << endl; } // call medit command exec("medit mm"); // clean files on unix OS exec("rm mm.bb mm.faces mm.points"); Figure 4.12: medit plot 3 http://www-rocq.inria.fr/gamma/medit/medit.html