Developer Guide v8p4
Developer Guide v8p4
M ASCARET
SYSTEM
DeveloperGuide
Version v8p4
December 1, 2022
Contents
1 Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.1 Why a finite element library? 8
3.2 Brief description of B IEF 8
3.3 Fortran 90: reasons for the change 9
9 Hermes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
9.1 Description 133
9.2 User Manual 133
9.2.1 List of functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
9.3 Developer Manual 146
9.3.1 Structure of the module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
9.3.2 Serafin Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
9.3.3 MED format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
9.3.4 How to add a new format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
9.3.5 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
9.3.6 Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
11 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
11.1 Create a work copy 154
11.2 Git commands 155
11.3 Update your branch with the latest version of the main branch 156
11.4 Merge a development into the main branch 156
5
12 CIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
14 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
14.1 The structure 160
14.2 How to compile 161
14.3 How to convert a Word documentation into LaTeX using GrindEQ 161
15 Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
15.1 Description of the dictionary 162
15.2 Description of the dictionary additional file 164
15.3 What DAMOCLES can do for you 165
16 Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
16.1 Structure of Python script 167
16.2 Where to look for examples 169
16.3 How to run a validation 169
16.3.1 Validation on a cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
1. Foreword
This is the latest release of the developer guide to the T ELEMAC -M ASCARET SYSTEM, based
on FORTRAN 2003. It has been written to help the numerous people who have to develop or
to understand the "ins" and "outs" of this system, namely research engineers and technicians
at EDF, students and researchers in universities, research institutes and laboratories, or users
willing to write specific user subroutines. It will probably not meet all the expectations: giving
fully detailed explanations of all the systems would take thousands of pages, and would prob-
ably never be read! With this guide we only hope to establish a closer relationship between
developers, and we shall enhance the guide progressively, as new questions arise. This docu-
ment will be a success if you consider it yours. We thus beg you to report on errors, misprints
and mistakes, and to ask for more explanations on parts that would not be clear enough. It will
be a commitment for us to take into account all your remarks in next releases.
2. Structure of this guide
This guide is made of four main parts and a number of appendices. Chapter 4 should be the
only useful one for developers of programs based on the B IEF library. Chapter 5 give details
on the very structure of B IEF and is a priori meant for B IEF developers themselves. Chapter
7 is about the different program a developer will have to use. Chapter 8 is about the coding
conventions that should be followed when developing in the T ELEMAC -M ASCARET SYSTEM.
3. Introduction
B IEF offers a whole range of subroutines. They include methods for solving advection equa-
tions, diffusion equations, linear system inversion methods with different types of precondi-
tioning. The user is also provided with subroutines for calculating matrices: mass matrices,
diffusion matrices, boundary matrices, etc. B IEF can be used to carry out all the conventional
operations on vectors (norms, dot products, etc.), on the products of one matrix by a vector
or of two matrices. By simply calling a subroutine, the user can calculate the divergence of a
vector, the gradient of a function, and so on. It should be remembered that this description is
not exhaustive and that the content of B IEF will change depending on the requirements of its
users.
The language used is FORTRAN 90 (see explanations below), and, to facilitate the diffusion
of the TELEMAC system, portability is checked on a wide range of hardware, including both
super-computers and workstations, Linux and Windows machines.
• The increasing number of modules based on B IEF meant that it was taking longer and
longer to complete each update. One of the aims of structured programming is to simplify
updating.
• The increasing number of arguments in the subroutines, and changes of arguments in the
user subroutines. This is removed as far as possible by the use of FORTRAN 90 modules.
• To get a safer implementation, with many errors checking done by the compiler itself.
4.1.1 Structures
FORTRAN 77 only recognises integers, real numbers, Boolean and character strings. FOR-
TRAN 90 can be used to create structures. The following is an example of the creation of a
’point’ type structure composed of two real numbers, and a circle structure, composed of a
centre and a radius:
TYPE point
REAL :: x,y
END TYPE
!
TYPE circle
TYPE(point) :: centre
REAL :: radius
END TYPE
It can be observed that the centre is itself a structure of a type previously defined. Once the
structure has been defined, objects of this type can be declared:
TYPE(circle) :: ROND
ROND will be a circle with its centre and radius; the latter are obtained thanks to the % "com-
ponent selector". Thus the radius of ROND will be the real ROND%radius.
4.1.2 Pointers
Pointers are well known in C language, but are notably different in Fortran 90. Pointers in
Fortran 90 may be used as pointers as in C but also as aliases. Unlike C, they are not mere
addresses pointing to somewhere in the computer memory. The target must be defined precisely,
for example, the line:
will define a pointer to a one-dimensional real array, and it will be impossible to have it pointing
to an integer nor even to a 2-dimensional array. This pointer X will have then to be pointed to a
target by the statement:
X => Y
where Y is an already existing one-dimensional real array. Then X can be used as if it were Y,
it is thus an alias.
X can be also directly allocated as a normal array by the statement:
ALLOCATE(X(100))
to have (for example) an array of 100 values. In this case X and its target have the same name.
A well known problem in Fortran 90 is the fact that arrays of pointers do not exist. To overcome
this problem, one has to create a new structure which is itself a pointer, and to declare an array of
this new structure. This is done for blocks, which are lists of pointers to BIEF_OBJ structures.
4.1.3 Modules
Modules are like INCLUDE statements, but are more clever, so that INCLUDE should now
always be avoided. As a matter of fact, modules can be used to define global variables that will
be accessible to all routines. With the following module:
MODULE EXAMPLE
INTEGER EX1,EX2,EX3,EX4
END MODULE EXAMPLE
all the subroutines beginning with the statement: USE EXAMPLE will have access to the same
numbers EX1,...EX4. With INCLUDE statements, it would be only local variables without
link to EX1,... declared in other subroutines.
Modules will thus be used to define global variables that will be accessed via a USE statement.
If only one or several objects must be accessed, the ONLY statement may be used, as in the
example below:
4.1.4 Interfaces
Interfaces are a mean given to the compiler to check arguments of subroutines even if it has no
access to them. For example, the following interface:
INTERFACE
LOGICAL FUNCTION EOF(LUNIT)
INTEGER, INTENT(IN) :: LUNIT
END FUNCTION
END INTERFACE
says that function EOF has one integer argument. INTENT(IN) indicates that argument LU-
NIT is not changed. Interfaces of all B IEF subroutines have been put in a single module called
B IEF. a USE BIEF statement at the beginning of a subroutine will prompt the compiler to
12 Chapter 4. Programming with B IEF
check the arguments and also do some optimisations in view of the INTENT information (which
can be IN, OUT, or INOUT depending on the use of the argument). If a function is declared in
an interface, it must not be declared as an EXTERNAL FUNCTION.
U=V
Such interface operators have not been done in this code , because operations like U=A+B+C
would probably not be optimised and would trigger a number of unnecessary copies.
INTERFACE
SUBROUTINE OS( OP, X , Y , Z , C , IOPT , INFINI , ZERO )
USE BIEF_DEF
INTEGER, INTENT(IN), OPTIONAL :: IOPT
DOUBLE PRECISION, INTENT(IN), OPTIONAL, INFINI, ZERO
TYPE(BIEF_OBJ), INTENT(INOUT), OPTIONAL :: X
TYPE(BIEF_OBJ), INTENT(IN), OPTIONAL :: Y,Z
DOUBLE PRECISION, INTENT(IN), OPTIONAL :: C
CHARACTER(LEN=8), INTENT(IN) :: OP
END SUBROUTINE
END INTERFACE
Or:
Parameters Y,Z and C are used only for specific operations and otherwise are not necessary.
When a parameter is missing and to avoid ambiguity, the parameters must be named, hence the
X=TRA01 in the example above.
Parameters IOPT, INFINI and ZERO stem from the old subroutine OSD and are used only
when a division is implied in the operation asked, for example if OP = ’X=Y/Z ’. These 3
parameters are now optional. When they are present, it is better to name them as is done in the
following line:
4.2 Structures in B IEF 13
The use of optional parameters will enable a better compatibility between different versions
because it will be possible to add a new parameter as an optional one.
Optional arguments will be written between brackets [ ] in argument lists in the rest of the
document.
The notions of VECTOR, MATRIX and BLOCK that were pre-programd in B IEF 6.2 have been
gathered in a single structure called BIEF_OBJ. This will enable what is called "polymor-
phism" in Object-Oriented Languages, i.e. the fact that arguments of subroutines may be of
different types. As a matter of fact, many subroutines in B IEF are able to treat in the same
way vectors or blocks of vectors (see for example OS), matrices or blocks of matrices (see e.g.
SOLVE and DIRICH). Polymorphism is possible in FORTRAN 90 with the use of interfaces,
however it requires the writing of one subroutine per combination of types, and thus leads to
a lot of duplication. The use of a single structure BIEF_OBJ was thus more elegant, the only
drawback being that the misuse of a matrix as a vector, for example, cannot be checked by the
compiler but only by the subroutines dealing with such structures.
Information on the structures can be simply retrieved by the component selector.
We shall also refer to BIEF_OBJ structures as VECTOR, MATRIX or BLOCK, depending on
their use, as is done below:
VECTOR
This may be any vector (a simple array) or a vector defined on the mesh, with values for every
point of the mesh. In the latter case, there is a corresponding discretisation type and numbering
system (global or boundary numbering of nodes or numbering of elements). For example,
a vector defined on all the mesh with a discretisation P0 will be implicitly given according
to the element numbers. In certain conditions, a vector may change discretisation while the
calculations are being carried out.
A vector has a first dimension which corresponds to the number of nodes to which it applies.
There is also a second dimension (for example, the off-diagonal terms of a matrix).
Any vector is in fact an array with 2 dimensions which the user can process as he wishes.
MATRIX
Matrices are also linked to the mesh. Different storage methods are possible. These matrices
can be multiplied by the vectors mentioned above.
14 Chapter 4. Programming with B IEF
BLOCK
A block is a set of structures. This notion has proved of particular importance for:
• Writing general solvers for linear systems, with the possibility of the matrix being a block
of several matrices.
• Using simple orders to group together and process sets of vectors or matrices, for example
the arrays of variables which are advected by the method of characteristics.
• Eliminate the need for certain arrays to follow one another in the memory.
BIEF_MESH structure
This structure includes all information concerning the mesh (connectivity tables, boundary
points, point coordinates, etc.). It replaces a large number of arrays used in releases of B IEF
prior to 3.2
SLVCFG
It stands for "SoLVer ConFiGuration"). This is a simple structure to store all the information
needed by the subroutine SOLVE for solving linear systems (choice of the method, accuracy,
preconditioning, etc.).
POINTER_TO_BIEF_OBJ
!
!====================================================================
!
! STRUCTURE OF POINTER TO A BIEF_OBJ, TO HAVE ARRAYS OF POINTERS
! IN THE BIEF_OBJ STRUCTURE FOR BLOCKS
!
! BIEF VERSION 6.0
!
!====================================================================
!
! THIS IS NECESSARY IN FORTRAN 90 TO HAVE ARRAYS OF POINTERS
! LIKE THE COMPONENT ADR BELOW, WHICH ENABLES TO BUILD BLOCKS
! WHICH ARE ARRAYS OF POINTERS TO BIEF_OBJ STRUCTURES
!
TYPE POINTER_TO_BIEF_OBJ
SEQUENCE
TYPE(BIEF_OBJ), POINTER :: P
END TYPE POINTER_TO_BIEF_OBJ
BIEF_OBJ
TYPE BIEF_OBJ
!
!--------------------------------------------------------------------
!
! HEADER COMMON TO ALL OBJECTS
!
! KEY : ALWAYS 123456 TO CHECK MEMORY OVERWRITING
4.2 Structures in B IEF 15
INTEGER KEY
!
! TYPE: 2: VECTOR, 3: MATRIX, 4: BLOCK
INTEGER TYPE
!
! NAME: FORTRAN NAME OF OBJECT IN 6 CHARACTERS
CHARACTER(LEN=6) NAME
!
!--------------------------------------------------------------------
!
! FOR VECTORS
!
! NAT: NATURE (1:DOUBLE PRECISION 2:INTEGER)
INTEGER NAT
!
! ELM: TYPE OF ELEMENT
INTEGER ELM
!
! DIM1: FIRST DIMENSION OF VECTOR
INTEGER DIM1
!
! MAXDIM1: MAXIMUM SIZE PER DIMENSION
INTEGER MAXDIM1
!
! DIM2: SECOND DIMENSION OF VECTOR
INTEGER DIM2
!
! MAXDIM2: MAXIMUM SECOND DIMENSION OF VECTOR
INTEGER MAXDIM2
!
! DIMDISC: TYPE OF ELEMENT IF VECTOR IS DISCONTINUOUS AT
! THE BORDER BETWEEN ELEMENTS, OR 0 IF NOT
INTEGER DIMDISC
!
! STATUS:
! 0: ANY ARRAY
! 1: VECTOR DEFINED ON A MESH, NO CHANGE OF DISCRETISATION
! 2: VECTOR DEFINED ON A MESH, CHANGE
! OF DISCRETISATION ALLOWED
INTEGER STATUS
!
! TYPR: TYPE OF VECTOR OF REALS
! ’0’ : NIL ’1’ : EQUAL TO 1 ’Q’ : NO SPECIFIC PROPERTY
CHARACTER*1 TYPR
!
! TYPR: TYPE OF VECTOR OF REALS
! ’0’ : NIL ’1’ : EQUAL TO 1 ’Q’ : NO SPECIFIC PROPERTY
CHARACTER*1 TYPI
!
! POINTER TO DOUBLE PRECISION 1-DIMENSION ARRAY
! DATA ARE STORED HERE FOR A DOUBLE PRECISION VECTOR
DOUBLE PRECISION, POINTER,DIMENSION(:)::R
!
! POINTER TO INTEGER 1-DIMENSION ARRAY
! DATA ARE STORED HERE FOR AN INTEGER VECTOR
INTEGER, POINTER,DIMENSION(:)::I
16 Chapter 4. Programming with B IEF
!
!--------------------------------------------------------------------
!
! FOR MATRICES
!
! STO: TYPE OF STORAGE 1: CLASSICAL EBE 3: EDGE-BASED STORAGE
INTEGER STO
!
! ELMLIN: TYPE OF ELEMENT OF LINE
INTEGER ELMLIN
!
! ELMCOL: TYPE OF ELEMENT OF COLON
INTEGER ELMCOL
!
! TYPDIA: TYPE OF DIAGONAL
! ’0’ : NIL ’I’ : IDENTITY ’Q’ : NO SPECIFIC PROPERTY
CHARACTER*1 TYPDIA
!
! TYPEXT: TYPE OF EXTRA-DIAGONAL TERMS
! ’0’ : NIL ’S’ : SYMMETRY ’Q’ : NO SPECIFIC PROPERTY
CHARACTER*1 TYPEXT
!
! POINTER TO A BIEF_OBJ FOR DIAGONAL
TYPE(BIEF_OBJ), POINTER :: D
!
! POINTER TO A BIEF_OBJ FOR EXTRA-DIAGONAL TERMS
TYPE(BIEF_OBJ), POINTER :: X
!
! PRO: TYPE OF MATRIX-VECTOR PRODUCT
INTEGER PRO
!
!--------------------------------------------------------------------
!
! FOR BLOCKS
!
! BLOCKS ARE IN FACT ARRAYS OF POINTERS TO BIEF_OBJ
! STRUCTURES ADR(I)\%P WILL BE THE I-TH BIEF_OBJ OBJECT
!
! N: NUMBER OF OBJECTS IN THE BLOCK
INTEGER N
! MAXBLOCK: MAXIMUM NUMBER OF OBJECTS IN THE BLOCK
INTEGER MAXBLOCK
! ADR: ARRAY OF POINTERS TO OBJECTS (WILL BE OF SIZE MAXBLOCK)
TYPE(POINTER_TO_BIEF_OBJ), POINTER, DIMENSION(:) :: ADR
!
!--------------------------------------------------------------------
!
END TYPE BIEF_OBJ
!
!====================================================================
!
BIEF_MESH
!
!====================================================================
4.2 Structures in B IEF 17
!
! STRUCTURE OF MESH : BIEF_MESH
!
!====================================================================
!
TYPE BIEF_MESH
!
! 1) A HEADER
!
! NAME: NAME OF MESH IN 6 CHARACTERS
CHARACTER(LEN=6) NAME
!
! 2) A SERIES OF INTEGER VALUES (DECLARED AS POINTERS TO ENABLE
! ALIASES)
!
! NELEM: NUMBER OF ELEMENTS IN MESH
INTEGER, POINTER :: NELEM
!
! NELMAX: MAXIMUM NUMBER OF ELEMENTS ENVISAGED
INTEGER, POINTER :: NELMAX
!
! NPTFR: NUMBER OF 1D BOUNDARY NODES, EVEN IN 3D
INTEGER, POINTER :: NPTFR
!
! NPTFRX: NUMBER OF 1D BOUNDARY NODES, EVEN IN 3D
INTEGER, POINTER :: NPTFRX
!
! NELEB: NUMBER OF BOUNDARY ELEMENTS (SEGMENTS IN 2D)
! IN 3D WITH PRISMS:
! number of LATERAL boundary elements for sigma mesh
INTEGER, POINTER :: NELEB
!
! NELEBX: MAXIMUM NELEB
INTEGER, POINTER :: NELEBX
!
! NSEG: NUMBER OF SEGMENTS IN THE MESH
INTEGER, POINTER :: NSEG
!
! DIM: DIMENSION OF DOMAIN (2 OR 3)
INTEGER, POINTER :: DIM
!
! TYPELM: TYPE OF ELEMENT (10 FOR TRIANGLES, 40 FOR PRISMS)
INTEGER, POINTER :: TYPELM
!
! NPOIN: NUMBER OF VERTICES (OR LINEAR NODES) IN THE MESH
INTEGER, POINTER :: NPOIN
!
! NPMAX: MAXIMUM NUMBER OF VERTICES IN THE MESH
INTEGER, POINTER :: NPMAX
!
! MXPTVS: MAXIMUM NUMBER OF POINTS ADJACENT TO 1 POINT
INTEGER, POINTER :: MXPTVS
!
! MXELVS: MAXIMUM NUMBER OF ELEMENTS ADJACENT TO 1 POINT
INTEGER, POINTER :: MXELVS
!
18 Chapter 4. Programming with B IEF
! IF IT IS IN ANOTHER SUB-DOMAIN.
TYPE(BIEF_OBJ), POINTER :: XSEG
!
! YSEG: Y COORDINATE OF FOLLOWING
! OR PRECEDING POINT IN THE BOUNDARY
! IF IT IS IN ANOTHER SUB-DOMAIN.
TYPE(BIEF_OBJ), POINTER :: YSEG
!
! FAC: MULTIPLICATION FACTOR FOR POINTS IN THE BOUNDARY FOR
! DOT PRODUCT.
TYPE(BIEF_OBJ), POINTER :: FAC
!
! FOR PARALLELISM AND NON BLOCKING COMMUNICATION (SEE PARINI.F)
!
! NUMBER OF NEIGHBOURING PROCESSORS (SEEN BY POINTS)
INTEGER , POINTER :: NB_NEIGHB
! FOR ANY NEIGHBOURING PROCESSOR, NUMBER OF POINTS
! SHARED WITH IT
TYPE(BIEF_OBJ), POINTER :: NB_NEIGHB_PT
! RANK OF PROCESSORS WITH WHICH TO COMMUNICATE FOR POINTS
TYPE(BIEF_OBJ), POINTER :: LIST_SEND
! NH_COM(DIM1NHCOM,NB_NEIGHB)
! WITH DIM1NHCOM IS THE MAXIMUM NUMBER OF POINTS SHARED
! WITH ANOTHER PROCESSOR
! (OR SLIGHTLY MORE FOR 16 BYTES ALIGNMENT)
! NH_COM(I,J) IS THE GLOBAL NUMBER IN THE SUB-DOMAIN OF I-TH
! POINT SHARED WITH J-TH NEIGHBOURING PROCESSOR
TYPE(BIEF_OBJ), POINTER :: NH_COM
!
! NUMBER OF NEIGHBOURING PROCESSORS (SEEN BY EDGES)
INTEGER , POINTER :: NB_NEIGHB_SEG
! FOR ANY NEIGHBOURING PROCESSOR, NUMBER OF EDGES
! SHARED WITH IT
TYPE(BIEF_OBJ), POINTER :: NB_NEIGHB_PT_SEG
! RANK OF PROCESSORS WITH WHICH TO COMMUNICATE FOR EDGES
TYPE(BIEF_OBJ), POINTER :: LIST_SEND_SEG
! LIKE NH_COM BUT FOR EDGES
TYPE(BIEF_OBJ), POINTER :: NH_COM_SEG
!
! WILL BE USED AS BUFFER BY MPI IN PARALLEL
!
TYPE(BIEF_OBJ), POINTER :: BUF_SEND
TYPE(BIEF_OBJ), POINTER :: BUF_RECVC
! FOR FINITE VOLUMES AND KINETIC SCHEMES
!
TYPE(BIEF_OBJ), POINTER :: CMI,DPX,DPY
TYPE(BIEF_OBJ), POINTER :: DTHAUT,AIRST
!
END TYPE BIEF_MESH
!
!====================================================================
!
SLVCFG
!
22 Chapter 4. Programming with B IEF
!====================================================================
!
! STRUCTURE OF SOLVER CONFIGURATION
!
!====================================================================
!
TYPE SLVCFG
!
! SLV: CHOICE OF SOLVER
INTEGER SLV
!
! NITMAX: MAXIMUM NUMBER OF ITERATIONS
INTEGER NITMAX
!
! PRECON: TYPE OF PRECONDITIONING
INTEGER PRECON
!
! KRYLOV: DIMENSION OF KRYLOV SPACE FOR GMRES SOLVER
INTEGER KRYLOV
!
! EPS: ACCURACY
DOUBLE PRECISION EPS
!
! ZERO: FOR CHECKING DIVISIONS BY ZERO
DOUBLE PRECISION ZERO
!
! OK: IF PRECISION EPS HAS BEEN REACHED
LOGICAL OK
!
! NIT: NUMBER OF ITERATIONS IF PRECISION REACHED
INTEGER NIT
!
END TYPE SLVCFG
!
!====================================================================
!
BIEF_FILE
!
!====================================================================
!
! STRUCTURE OF FILE
!
!====================================================================
!
TYPE BIEF_FILE
!
! LU: LOGICAL UNIT TO OPEN THE FILE
INTEGER LU
!
! NAME: NAME OF FILE
CHARACTER(LEN=144) NAME
!
! TELNAME: NAME OF FILE IN TEMPORARY DIRECTORY
CHARACTER(LEN=6) TELNAME
4.2 Structures in B IEF 23
!
! FMT: FORMAT (SERAFIN, MED, ETC.)
CHARACTER(LEN=8) FMT
!
! ACTION: READ, WRITE OR READWRITE
CHARACTER(LEN=9) ACTION
!
! BINASC: ASC FOR ASCII OR BIN FOR BINARY
CHARACTER(LEN=3) BINASC
!
! TYPE: KIND OF FILE
CHARACTER(LEN=12) TYPE
!
END TYPE BIEF_FILE
ALMESH prepares the BIEF_MESH structures and fills some of them, for example it will allo-
cate the memory for storing the component IKLE and will read it in the geometry file. However
not all the data structure is ready after exiting ALMESH. This task is carried out by the subroutine
INBIEF which must be called later, when all the necessary data have been logged.
Arguments:
IELM Element with the highest number of degrees of freedom in the mesh.
These data will be used to build specific data structures relevant to every option.
NFIC Logical unit where the geometry file has been opened.
EQUA Equations to solve or call program in 20 characters. Up to now is only used to allocate
specific arrays for Finite volumes if EQUA=’SAINT-VENANT VF’ is used to optimise
memory requirements.
NPMAX Maximum number of vertices in the mesh, in case of adaptive meshing (not imple-
mented yet).
NPTFRX Maximum number of boundary points in the mesh, in case of adaptive meshing (not
implemented yet).
NELMAX Maximum number of elements in the mesh, in case of adaptive meshing (not im-
plemented yet).
I3, I4 When present, it means that the X and Y coordinates of the mesh are in reality X+I3
and Y+I4, I3 and I4 (integers representing a number of metres, have been removed to
minimize truncation errors (see also the Selafin format where these two numbers are
included for a georeferenced post-processing.
IELM Vector discretisation type (or dimension depending on the status, see below)
2 Vector defined on a mesh, with possibility of changing discretisation within the limits
of the memory space.
Syntax:
CALL BIEF_ALLVEC_IN_BLOCK( BLO,N,NAT,NOM,IELM,DIM2,STATUT)
With BIEF_ALLVEC_IN_BLOCK, N vectors with the same characteristics are put directly
into the block BLO. NOM is then only a generic name, for example if NOM is ’T ’, the names
of the vectors will be T1, T2, etc. Only the block BLO must be declared. T2 will be in fact
BLO%ADR(2)%P but can be named also T2 if T2 is declared as a BIEF_OBJ pointer and
pointed to BLO%ADR(2)%P:
TYPE(BIEF_OBJ), POINTER :: T2
T2 => BLO%ADR(2)%P
Matrix: BIEF_ALLMAT
A matrix must be declared previously as a BIEF_OBJ structure. We only deal with matrices of
double precision numbers.
Syntax:
CALL BIEF_ALLMAT( MAT,NOM,IELM1,IELM2,
CFG,TYPDIA,TYPEXT,MESH)
Arguments:
IELM1 Type of discretisation for rows (same convention as for the vectors).
TYPEXT Type of the off-diagonal terms (’0’: zero, ’Q’: any, ’S’: symmetrical)
Block : ALLBLO
A block must be declared previously as a BIEF_OBJ structure.
Syntax:
CALL ALLBLO(BLO,NOM)
Arguments:
In this case, we have an empty shell where we do not specify which objects have been placed in
the block. A block structure can thus be used again. To fill the block, the subroutine ADDBLO
must then be called (see paragraph A.I.4.4). The syntax will be:
CALL ADDBLO(BLOCK,OBJ)
to add a BIEF_OBJ structure OBJ to the block called BLOCK.
A block can be emptied by calling a simple function:
CALL DEALLBLO(BLOCK)
Example
We take here the example of a double precision array called SAMPLE, with one dimension, and
quasi-bubble discretisation. This vector will be then set to a constant value.
TYPE(BIEF_OBJ) :: SAMPLE
CALL BIEF_ALLVEC(1,SAMPLE,’SAMPLE’,12,1,STATUT,MESH)
3. To set the value of the vector to 5.D0 for all points of the mesh, you can then do:
which is equivalent in this case to (but the following would require declaration of integer
I):
DO I=1,SAMPLE%DIM1
SAMPLE%R(I)=5.D0
ENDDO
To understand this loop, remember that R is the component storing the real data of vectors, and
DIM1 the size of the first dimension. However it is not mandatory to remember this if you use
the functions and subroutines designed for operations on structures.
CMPOBJ indicates if the two structures are identical. A check is made to see whether these two
structures are of the same type and, if so, their characteristics are compared:
Operations on vectors
syntax:
SUBROUTINE CHGDIS(VEC,OLDELT,NEWELT,MESH)
CHGDIS changes the discretisation of a vector.
arguments:
A vector can thus go from a linear discretisation to a quasi-bubble discretisation, or the reverse.
In the first case, the missing values are found by linear interpolation, while in the second case
the superfluous values are forgotten. There are certain restrictions on the use of this subroutine:
• a vector cannot be extended if the required memory space is not provided for during
allocation.
• Certain changes are impossible, for obvious reasons: changing a triangle to a quadrilat-
eral, etc.
syntax:
SUBROUTINE CPSTVC(T1,T2)
This subroutine copies a vector structure onto another. If T1 is a vector, T2 then becomes
a vector with the same characteristics. Nevertheless, the memory allocated during allocation
cannot be changed. The only data copied for the moment are:
This subroutine should be used when dealing with temporary all-purpose BIEF_OBJ structures
like T1, T2, etc. in T ELEMAC -2D and S ISYPHE and T3_01, T3_02, etc. in T ELEMAC -3D. As
a matter of fact, these structures may have been changed by a previous use, e.g. they may
have been turned into boundary vectors with a smaller size than a full domain vector, hence
an initialisation like CALL OS(‘X=0 ‘,X=T1) may have a random effect if not secured
previously by specifying what must be T1. Copying the structure of a known object like e.g.
the depth of structure H, will do it. CALL CPSTVC(H,T1) will give T1 the same dimension
and discretisation as the depth.
Operations on matrices
Note : all the operations on vectors may also be applied to the diagonal and the extradiago-
nal terms contained in the matrix structure (respectively M%D and M%X for a matrix M). The
following subroutines only apply to matrices:
syntax:
SUBROUTINE CPSTMT(M1,M2,TRANS)
Copies characteristics of the matrix M1 on to the matrix M2, or of transposed of matrix M1 to
M2 (if optional TRANS argument is set to true).
CPSTMT is similar to CPSTVC, it carries out the following operations:
2. Copies types of diagonal and off-diagonal terms (calls CPSTVC for the diagonal and the
off-diagonal terms).
4. Checks that M2 has enough memory for its new characteristics : sizes of diagonal and
extra-diagonal terms.
syntax:
INTEGER FUNCTION BIEF_DIM1_EXT(IELM1,IELM2,STO,TYPEXT,MESH)
Extra-diagonal terms of matrices are stored in 2-dimensional arrays. DIM1_EXT returns the
first dimension of this array, depending on: arguments:
IELM1 Type of discretisation for rows (same convention as for the vectors).
TYPEXT Type of the off-diagonal terms (’0’: zero, ’Q’: any, ’S’: symmetrical)
syntax:
INTEGER FUNCTION BIEF_DIM2_EXT(IELM1,IELM2,STO,TYPEXT,MESH)
The extra-diagonal terms of matrices are stored in 2-dimensional arrays. DIM2_EXT returns
the second dimension of this array, depending on: arguments:
IELM1 Type of discretisation for rows (same convention as for the vectors).
TYPEXT Type of the off-diagonal terms (’0’: zero, ’Q’: any, ’S’: symmetrical)
Operations on blocks
syntax:
SUBROUTINE ADDBLO(BLOCK,T)
Adds the structure T to the block.
arguments:
BLOCK is a block
T a structure.
B%ADR[3]%P%ADR[2]%P
The only difficulty and common error is to forget the component P which is due to Fortran
obscure reasons.
Possible operations
OP is an operation coded in 8 characters, as for the subroutine OM. N is an internal working
matrix which contains the matrix with the formula requested (see next paragraph). M is the
matrix given by the user and which will be modified according to the operation indicated:
• OP = ’M=N ’ : COPY OF N ON TO M
• OP = ’M=M+N ’ : N IS ADDED TO M
The operations with the form M=M+CN can be carried out through the multiplying factor
XMUL which applies to N.
Available formulae
FORMUL is a string of 16 characters describing the formula. Generally only the first 6 are
used but extra information may be contained in characters 7 to 16. For example, the sixteenth
character is sometimes used to specify the derivatives and may then contain the characters X, Y
or Z.
Available elements
All the possible formulae are given below. However, all the discretisation combinations are not
programd. If a matrix or a given discretisation has not been programd, an error message will
appear to this effect.
In the next part of the text,Ψi is the base corresponding to the element IELM1 (row) and Ψ j
the base corresponding to the element IELM2 (column). The example of dimension 3 is given.
For the other dimensions, some terms would, of course, have to be removed. The beginning of
names of the corresponding subroutines in B IEF is given in brackets. They are complemented
by letters indicating the elements treated. The first letter corresponds to the row and the second
letter to the column. Letter O stands for a linear segment, A for a linear triangle, B for a quasi-
bubble triangle, C for a quadratic triangle, P for a prism, T for a tetrahedron. More specifically F
stands for a vertical linear triangle which is part of the vertical border of a mesh of prisms split
into tetrahedrons. Example : subroutine MT01AA will compute the mass-matrix of a linear
triangle.
FORMUL = ’MATMAS ’
(in library B IEF subroutines with names which start with MT01)
Mass-matrix.
Z
N(i, j) = XMUL Ψi Ψ j dΩ
Ω
FORMUL = ’MATDIF ’
(in library B IEF subroutines with names which start with MT02)
Diffusion matrix with different coefficients according to the directions x, y and z.
In 2 dimensions:
Z
∂ Ψi ∂ Ψ j ∂ Ψi ∂ Ψ j
N(i, j) = XMUL (U +U )dΩ
Ω ∂x ∂x ∂y ∂y
4.3 Building matrices and vectors 31
The case of an isotropic viscosity is given above. But the viscosity may also be tensorial.
In this case U (a BIEF_OBJ structure) must have a second dimension, for example
3 in 2-
Uxx Uxy
dimensional applications. U will has the general following form: U = , but the
Uyx Uyy
tensor is symmetric and Uxy = Uyx.
Elements of the tensor must be stored in U as follows:
• Uxx in U(*,1)
• Uyy in U(*,2)
• Uxy in U(*,3)
Z
∂ Ψi ∂ Ψ j ∂ Ψi ∂ Ψ j ∂ Ψi ∂ Ψ j ∂ Ψi ∂ Ψ j
N(i, j) = XMUL (Uxx +Uyy +Uxy +Uxy )dΩ
Ω ∂x ∂x ∂y ∂y ∂x ∂y ∂y ∂x
When a transversal Kt and longitudinal Kl dispersion are used (case of Elder’s turbulence
model), the formula giving the tensor U is:
∂ F −−→
Z
N(i, j) = XMUL U .grad(Ψi )dΩ
Ψj
Ω ∂x
If FORMUL(16:16) is equal to ’Y’ or ’Z’ instead of ’X’, the derivatives will be obtained ac-
cording to y or z.
U is a vector with the components U, V and W.
FORMUL = ’MATGRA X’
(subroutines with names which start with MT13)
Gradient matrix.
Z
∂Ψj
N(i, j) = XMUL Ψi dΩ
Ω ∂x
If FORMUL(16:16) is equal to ’Y’ or ’Z’ instead of ’X’, the derivatives will be obtained ac-
cording to y or z.
FORMUL = ’MAMURD PSI’ or FORMUL = ’MAMURD2 PSI’
(subroutines with names which start with MT14)
Distribution matrix in case of use of the Multidimensional Upwind Residual Distribution scheme
in 3D. See reference J.-M. et al. [4] for more details.
If FORMUL(14:16) is equal to ’ N’ instead of ’PSI’ the matrix will be assembled.
FORMUL = ’FFBT ’
(subroutines with names which start with MT99)
This is in fact a series of different matrices and the string FORMUL(8:16) is also used for
defining the formula. For example if FORMUL(8:16)=’ 0XX0’, the matrix will be:
∂F ∂Ψj
Z
N(i, j) = XMUL F Ψi dΩ
Ω ∂x ∂x
Explanation: the term in the integral is a product of 4 terms based, for the first 2, on the vector
F, and then on the Basis function called here B and the test function called T.
If the first character is 0, the first term will be F. If the first character is X, the first term will be
∂F ∂F
∂ x . If the first character is Y, the first term will be ∂ y .
Then we proceed to second character and again function F, to third character and function Ψ j ,
to fourth character and function Ψi .
Up to now the combinations 0XX0, 0YY0, XX00, 0X0Y, XY00, YY00, 0Y0X are imple-
mented. The formula FORMUL(8:16)=’00XX+00YY’ is also available. Note that missing
combinations can be obtained because the first two characters can be exchanged. Moreover
exchanging the last two characters gives the transposed matrix of the previous formula.
The existing subroutines building matrices in version 6.2 are the following, their function can
be deduced from the explanations above:
• GRADF(X,Y) X and GRADF(X,Y) Y will consider only the gradient of a function which
does not depend on Z.
FORMUL = ’PRODF ’
(subroutines with names which start with VC14)
Z
∂U 2 ∂V 2 ∂U ∂V 2
V EC(i) = XMUL Ψi F(2( ) + 2( ) +( + ) )dΩ
Ω ∂x ∂y ∂y ∂x
This vector is used in the calculation of the turbulent production with the model k-epsilon.
FORMUL = ’DIVQ ’
(subroutines with names which start with VC15)
Z
V EC(i) = XMUL U )dΩ
Ψi div(FU
Ω
U is a vector with the components U, V and W. K is a vector with the components F, G and H.
FORMUL = ’FLUDIF ’
(subroutines with names which start with VC17)
−−→
Z
V EC(i) = XMUL ΨiU.grad(F).nndΩ
Ω
−−→
Z
V EC(i) = XMUL ΨiU.grad(F)dΩ
Ω
This is specifically for 3D computations with prisms, and unlike VGRADF, the test function Ψi
is here a 2-dimensional test function (no dependency on z). This is used by T ELEMAC -3D in
subroutine WSTARW.
FORMUL = ’HUGRADP ’
(subroutines with names which start with VC19)
−−→
Z
V EC(i) = XMUL U .grad(Ψi )dΩ
FU
Ω
This is used in 2D, mostly for computing fluxes. H in HUGRADP stands for the depth denoted
h, which can be misleading as it does not refer to the function H which is an argument of
subroutine VC19AA. A variant HUGRADP2 exists, in this case the velocity is not only U of
−−→
components (U,V), but U + Ggrad(H). This is a way of treating the gradient of the free surface
elevation as a piecewise constant function, which it is in reality when the depth is linear.
The existing subroutines building vectors in version 6.2 are the following, their function can be
deduced from the explanations above:
4.4 Operations on matrices and vectors 37
Arguments:
X is a vector or a working array which will contain the result of the operation.
Y and Z are vector structures. Y and Z can be dummy arguments if they do not appear in the
operation, but they must be declared as BIEF_OBJ structures. C is a double precision
real number.
X,Y,Z,C,IOPT, INFINI and ZERO are optional, the last 3 are used only when a division is
implied in the operation asked, for example if OP = ’X=Y/Z ’. When they are present, it
is better to name them as is done in the following line:
vectors allocated with a status equal to 1 will trigger an error message if a change of their
discretisation is tried.
The operation OP may be :
• OP = ’X=Y ’ : Y COPIED ON TO X
• OP = ’X=+Y ’ : IDEM
• OP = ’X=-Y ’ : -Y COPIED ON TO X
• OP = ’X=X+Y ’ : Y ADDED TO X
• OP = ’X=CX ’ : X MULTIPLIED BY C
• OP = ’X=CY ’ : CY COPIED ON TO X
• OP = ’X=X+CY ’ : CY ADDED TO X
• OP = ’X=X+C ’ : C ADDED TO X
• OP = ’X=C(Y-Z)’ : X = C*(Y-Z)
Examples:
CALL OV_2(OP,X,2,Y,5,Z,3,C,NPOIN)
thus replaces the former instruction:
CALL OV(OP,X(1,2),Y(1,5),Z(1,3),C,NPOIN)
where X, Y and Z were declared as two-dimensional arrays.
syntax:
SUBROUTINE OVD(OP,X,Y,Z,C,IOPT,INFINI,ZERO,NPOIN)
OVD carries out the same operations as OS (it is called by OS), but directly on double precision
arrays and without consistency checks or structure updating. The argument NPOIN indicates
the number of values on which the operation must be conducted.
syntax:
SUBROUTINE OVD_2(OP,X,DIMX,Y,DIMY,Z,DIMZ,C,DIM1,NPOIN,IOPT,INFINI,ZERO)
OVD_2 is comparable to OVD but acts on 2-dimensional vectors, the second size being DIM1.
OVD_2 will actually call OVD with X(1,DIMX), Y(1,DIMY) and Z(1,DIMZ) as arguments
instead of X, Y and Z.
syntax:
SUBROUTINE OSBD(OP,X,Y,Z,C,MESH)}
The form and the principle are the same as for OS but the array MESH (mesh structure) is given
as a last argument. In this case we have vectors which would be refused by OS because of
lack of consistency. For OSBD, X is defined on the boundaries and Y and Z are vectors defined
on the whole domain. There is thus data retrieval of Y and Z, which requires the presence of
MESH.
The possible operations are as follows:
• OP = ’X=+Y ’: IDEM
SUBROUTINE OSDB(OP,X,Y,Z,C,MESH)
Same principle as for OSBD. Here, X is defined on the entire domain and Y and Z are vectors
defined on the boundaries. Only the X values corresponding to boundary points are filled.
The following operations are possible:
• OP = ’X=Y ’ : Y COPIED ON TO X
• OP = ’X=+Y ’ : IDEM
• OP = ’X=X+Y ’ : Y ADDED TO X
• OP = ’X=CY ’ : CY COPIED ON TO X
• OP = ’X=X+CY ’ : CY ADDED TO X
• OP = ’X=XY ’ : X MULTIPLIED BY Y
syntax:
SUBROUTINE OSDBIF(OP,X,Y,Z,C,INDIC,CRITER,MESH)
Same principle as for OSDB but a test is done. If INDIC(K)=CRITER, the operation OP is done
on index number K of vector X.
The following operations are possible:
• OP = ’X=Y ’ : Y COPIED ON TO X
• OP = ’X=+Y ’ : IDEM
syntax:
SUBROUTINE OVDB(OP,X,Y,Z,C,NBOR,NPTFR)
Same role as OSDB but by giving data from MESH, the general numbering of the boundary
points and the number of boundary points. OVDB does not conduct any check.
• OP = ’M=N ’ : COPY OF N ON TO M
42 Chapter 4. Programming with B IEF
• OP = ’M=M+CN ’ : CN ADDED TO M
• OP = ’M=M+N ’ : N ADDED TO M
When the operation only concerns M, it is advisable to repeat M instead of the argument N. In
all cases N should be a matrix-structure, or it may generate inexplicable crashes.
It is possible that a few of these operations are not yet programd with all the matrix-storage.
syntax:
SUBROUTINE LUMP(DIAG,A,MESH,XMUL)
Returns a vector representing a diagonal matrix DIAG (in fact a BIEF_OBJ structure with a
vector type) containing the sum of the rows of the matrix A. The other arguments are given
below:
• OP = ’X=AY ’ : X = AY
• OP = ’X=X+AY ’ : X = X + AY
• OP = ’X=X-AY ’ : X = X - AY
4.5 Solving linear systems 43
• OP = ’X=X+CAY ’ : X = X + C AY
• OP = ’X=TAY ’ : X = TA Y (TRANSPOSED OF A)
• OP = ’X=X+TAY ’ : X = X + TA Y
• OP = ’X=X-TAY ’ : X = X - TA Y
• OP = ’X=X+CTAY’ : X = X + C TA Y
Optional argument:
LEGO Logical.
If LEGO is equal to .FALSE., the vector X will not be assembled and part of the result (due to
the off-diagonal terms of A) will be contained in the array W of structure MESH. The vector X
will contain only the contribution of the diagonal.
The aim of LEGO=.FALSE. is to save on assemblies during calculations where X is the sum of
several matrix x vector products.
Thus to calculate X = A Y + B Z, the following two calls will be made one after the other:
• OP = ’X=AY ’ : X = AY
• OP = ’X=TAY ’ : X = TA Y (TRANSPOSED OF A)
S System matrix
LIMDIR Boundary conditions type if LIMDIR(K) = KDIR the K th boundary point is a Dirich-
let type point.
• =1 : Normal
• =0 : Masked point
X Solution vector.
A System matrix.
Here is the meaning of options stored in the SLVCFG structure called above CFG:
CFG%KRYLOV Only used by GMRES. The option is the dimension of Krylov’s space (see
ref. J.-M. [2]).
1 Nothing
2 Diagonal preconditioning
3 Block-diagonal preconditioning
5 Diagonal preconditioning with absolute values of diagonal
7 Crout preconditioning
11 Gauss-seidel ebe preconditioning
13 Matrix given by the user
17 Specific to T ELEMAC -3D. Direct solution on verticals are used as preconditioning.
CFG%EPS Relative accuracy requested, or absolute if norm of the right-hand side is less than
1..
TB will be used by SOLVE to find BIEF_OBJ structures with working arrays. The number of
structures to be placed in TB depends on the method chosen. At the time being, the minimum
number of arrays in TB must be:
S*MAX(7,2+2*METHOD%KRYLOV) where S is 1 if the system is made of 1 matrix, 2 for
blocks of 4 matrices (2 unknowns like in ARTEMIS) and 3 for blocks of 9 matrices (3 unknowns
like in T ELEMAC -2D).
4.6 Parallelism
Parallelism consists of using simultaneously a cluster of computers, or a group of processors in
the same computer, to solve a single problem. Using n processors would ideally divide by n the
time necessary to solve the same problem with only one processor. The task would be easy if
the problem could be broken down into sub-tasks, independent of each other. It becomes much
more difficult when each processor needs the results from the others. We will focus hereafter on
parallelism performed with processors having each its own memory, and communicating with
the others via message transmission, this is the case with networks of work stations or PCs and
is known as distributed-memory parallelism.
Many experiments in automatic parallelism, where compilers themselves perform the task of
optimising the program, showed very poor improvement in CPU time. Furthermore, vectorisa-
tion and parallelism appeared to be contradictory. The vectorization requires simple loops to
perform sub-tasks whereas distributed-memory parallelism hands over complex tasks to each
processor so as to optimize communication time and data transmission time. Efficiently vec-
torised software would be naturally poorly parallelised. As an example, the assembly loops
resulting from an EBE matrix-vector product cannot be accelerated by more than a ratio of two
even if we overlook the communication time. This is due to the fact that the results of each
processor have to be assembled. That leads to a new cost which limits drastically the overall
time to be gained. This is known as a granularity problem, the size of the tasks to be paral-
lelised being too small. It is unlikely that progress in the algorithm would help in solving this
theoretical bottleneck. From that, the idea emerges to break up the problem in another way:
not by isolating small tasks but in a kind of geographical way, by decomposing the domain of
computation. This idea of domain decomposition aims to assign onto each processor one part
of the domain over which it would solve the fluid mechanics problem. The implementation is
quite easy in the case of explicit algorithms: each equation is only a function of the variables
46 Chapter 4. Programming with B IEF
related to the nodes in the immediate vicinity, computed at the earlier time step. Each processor
is then in charge of the equations related to a group of nodes, and of the data concerning the
neighbours of these nodes, resulting from the previous time step. This is executed merely by
a partition of the domain, with an overlap of one element, and data transmission at the end of
each time step. In the case of our implicit algorithms, and especially with linear systems solved
on the whole domain, the implementation is more complex, though possible. In fact, we can
guarantee that the results of a parallel computation will be the same as a scalar computation,
except for truncation errors because computations will not be performed in the same order. Par-
allelism (initially implemented on our algorithms by Reinhard Hinkelmann at the University of
Hanover can be limited to the following problems:
• Partitioning the domain into blocks in order to ensure a balance between the processors.
Because the main algorithms are made of loops over the elements and nodes, the parti-
tion will guarantee a balance between the numbers of elements, or similarly between the
number of nodes within each sub-domain.
• Minimizing the number of nodes shared by different sub-domains and for which commu-
nications between processors will be necessary.
We currently use the Metis mesh partitioner, which is available on the web site: http://
glaros.dtc.umn.edu/gkhome/metis/metis/overview.
• An array KNOLG storing the global numbers of the nodes in the whole mesh. The inverse
array, KNOGL, is defined within a loop:
DO I=1,NPOIN
KNOGL(KNOLG(I))=I
ENDDO
4.6 Parallelism 47
• An array NACHB whose dimension is (5,NPTIR), where NPTIR is the number of the
interfacial nodes between the subdomain and the others. These interfacial nodes are num-
bered from 1 to NPTIR. NACHB(1,IR) is the global number of the interfacial node IR.
This array gathers the information to be transmitted to the other processors. The inte-
gers NACHB(2,IR) to NACHB(5,IR) are the numbers of the other subdomains which the
nodes belong to. They may have a -1 value if these sub-domains are less than 4. The
dimension 5 must be increased if a node belongs to more than 5 sub-domains.
Some additional information has to be defined on the actual boundary nodes of a 2-dimensional
domain:
– If ISEG >0: the boundary node just after belongs to another sub-domain, its global
number is ISEG, and its real coordinates are XSEG and YSEG.
– If ISEG <0: the boundary node just before belongs to another sub-domain, its
global number is -ISEG, and its real coordinates are XSEG and YSEG.
– If ISEG = -999999: the node verifies the two conditions above (this pathological
case is not considered by the software).
The latest algorithms designed in Telemac replaced the use of XSEG and YSEG by par-
allel communications, thus these arrays could be removed in a near future.
• The integer array NUMLIQ is a specific numbering of the liquid boundaries, which allows
association of boundary conditions to them, e.g. an imposed discharge. A numbering is
easy to define when the whole domain is known. A possible convention is to start the
numbering of these liquid boundaries (inflow and outflow) from the extreme south-west
node of the domain and proceeding in the anti clock-wise way along the edge. In the case
of a sub-domain for which it is not possible to go over the whole contour, the numbering
must be specified because it cannot be simply recomputed.
• An array INDPU, inverse of NACHB(1,*) helps storing the data received from the other
processors: INDPU(NACHB(1,I))=I. Given the number of an interfacial node, INDPU
sends back its global number within the subdomain.
• An array FAC, providing for each node, the inverse of the number of subdomains to which
it belongs (see the algorithm for dot product hereafter).
• Setting up of the parallel machine, that is, organizing the communication between various
computers or processors,
48 Chapter 4. Programming with B IEF
• Running programs on all the processors (spawn order with PVM). In some cases, one
processor has the function of a master, the others being the slaves. The program is first
run on the master processor, and includes a start order for the slaves. A group name
is given to the computation. Apart from this initialisation step, there is then no more
hierarchy between the processors.
• a message flag.
Transmissions can be made in two ways. Synchronous transmission occurs when waiting for
the receptor to be ready; this avoids a copy into the buffer. Asynchronous transmission occurs
whatever the state of the reception.
Collective communication
Collective communications use simultaneously all the processors. Three types may be distin-
guished:
• broadcast: a processor (generally the master) sends the same data to all the slaves,
• synchronization: refers to a barrier which all processors must reach before going on the
computation,
• conditional transmission: each processor sends a data and receives in return the sum, the
maximum or the minimum of all the data transmitted.
To make the source programs independent of the choice of the communication functions library,
it is worth writing an interface library to deal with all the communications between the proces-
sors. In Telemac this library is called "parallel." When there is no parallelism involved a fake
library "paravoid" is used instead, which does not contain any link to a parallelism library. Only
a few functions are necessary:
P_DSUM(X) sum of all the values of X provided by all the processors. X is a double-precision
real.
P_ISUM(I) sum of all the values of I provided by all the processors. I is an integer.
P_SYNC stops the processors till all of them call this function.
P_DOT = 0.D0
DO I=1,NPOIN
P_DOT=P_DOT+X(I)*Y(I)*FAC(I)
ENDDO
P_DOT=P_DSUM(P_DOT)
On a vector computer, multiplying by FAC(I) does not affect the time of computation. On the
contrary, the call to the P_SUM routine causes a synchronization of the processors.
Matrix × vector product
First, building the matrices and computing the product is done locally, independently of the
other subdomains. The result is a vector without any contribution from the neighbour sub-
domains, on the interfacial nodes. The missing contributions result from the computation of
the vector on the other sub-domains. For example, if the node I belongs to two different sub-
domains, for which we get X(I)=3 and X(I)=5 respectively, the actual value of X(I) would be the
sum 3+5. This can be achieved if processor 1 sends the value 3 to processor 2 and processor 2
sends the value 5 to processor 1. Although it appears simple, this operation is quite complex to
achieve because it can lead to a fatal risk: both processors waiting endlessly for the contribution
of the other before sending their own. We describe hereafter the series of operations required,
known as “blocking communication”. More recently, a non-blocking communication scheme
has been implemented by Pascal Vezolles from IBM Europe. , this second approach consists
of providing MPI with the list of communications to perform, and MPI internal routines will
organise the work of their own algorithms.
Communication of data after a matrix-vector product:
Up to version 5.8:
Generally speaking, we have a number of processors which much send or receive information
to or from the others. The main difficulty is to avoid blocking situations where two proces-
sors would wait to receive information from each other before sending their own, hence the
definition of higher rank and lower rank processors. We have kept the explanations on this
obsolete implementation because it really tackles the problem, while the new implementation
from version 5.9 on only uses the capabilities of the MPI language, namely the non-blocking
communication with subroutines MPI_IRECV and MPI_ISEND.
The transmission is split into 4 different tasks, depending on the rank of the processors:
New data are required for every processor. Each processor prepares its own numbering of
higher rank and lower rank processors as well as a numbering of nodes interfacing with each of
these processors. 4 new arrays IKP, NHP, IKM and NHM are necessary to navigate from one
numbering to another:
• ILMAX is the maximum distance in order between the processor and its neighbours. It
will restrict the size of the loops over these neighbours.
Considering this information, the data transmission for vector V (defined over the whole do-
main) and for processor IPID, is written as follows:
DO I=1,IKP(ILP,2)
ERGBUF(I)=BUF(INDPU(NHP(ILP,I)))
ENDDO
(b) sending
CALL P_WRIT(ERGBUF,8*IKP(ILP,2),IKP(ILP,1),
ABS(IKP(ILP,1)-IPID)
(a) reception
CALL P_READ(ERGBUF,8*IKM(ILM,2),IKM(ILM,1),
ABS(IKM(ILM,1)-IPID)
4.6 Parallelism 51
DO I=1,IKM(ILM,2)
ERGBUF(I)=BUF(INDPU(NHM(ILM,I)))
ENDDO
(b) sending
CALL P_WRIT(ERGBUF,8*IKM(ILM,2),IKM(ILM,1),
ABS(IKM(ILM,1)-IPID)
(a) reception
DO I=1,IKP(ILP,2)
V(NHP(ILP,I))=V(NHP(ILP,I))+ERGBUF(I)
ENDDO
This algorithm can be made more complex to process several vectors at the same time or for
tasks different from summing.
From version 5.9 on:
The implementation is much easier with the MPI subroutines MPI_IRECV and MPI_ISEND
(see subroutine PARACO). Only lists of processors are necessary, regardless of any order in the
communications, the rest is handled by MPI. To achieve this, a number of new data have been
added to the BIEF_MESH structure. They are listed below. Moreover in version 5.9 parallel
communication data linked to segments have been added, which doubles the necessary data.
NB_NEIGHB number of neighbouring processors (seen by points).
LIST_SEND list of neighbouring processors to which data must be sent (seen by points).
LIST_SEND_SEG list of neighbouring processors to which data must be sent (seen by seg-
ments).
52 Chapter 4. Programming with B IEF
There should be also accordingly a LIST_RECEIVE, but it is actually exactly like LIST_SEND,
so it has not been created.
Specific cases
It is worth noting that just a few alterations of the scalar and matrix-vector products are suf-
ficient to solve a linear equation with partial derivatives in shared memory. Furthermore, the
contributions of the interfacial terms can be postponed until the final solving. They would be
necessary before only if real nodal values, dot product, matrix-vector product or final results are
needed. For a linear equation, these operations can be confined to the resolution of the linear
system. Once the tools have been set up to communicate between processors, parallelisation
of fluid mechanics software is quite easy. However, specific cases, arising mainly from non-
linearity have to be considered. The basic idea is to get identical results on vector or parallel
computers, except for truncation errors. Some examples follow:
• Computation of nodal values after projection onto a basis: let us consider the gradient of
−−→
a function f . A mean nodal value of grad( f ) is given by:
−−→
−−→ ∫ grad( f )Ψi dΩ
grad( f )i = Ω
∫ Ω Ψi dΩ
issued from the mean-value theorem. In this case the computation of the general term
−−→
∫ Ω Ψi dΩ has to be completed at the interfaces. The vector including: ∫ Ω grad( f )Ψi dΩ
is unchanged when added to the right-hand side of a linear system (the solver itself will
complete this term). However it must be completed when used to compute another term
such as a turbulent production.
• Any global concept: maximum Courant number, maximum Froude number, etc., have to
be transmitted between processors.
• The method of characteristics: for high values of the Courant number, a characteris-
tic curve may leave a subdomain and enter others. Programming this situation within
the parallel architecture requires a huge number of random transmissions, depending on
the flow. The implementation of this technique in parallel has been achieved by Jacek
Jankowski from BundesAnstalt für Wasserbau in Germany.
4.7 Utilities
A number of tools are offered in B IEF, in the form of functions and subroutines.
4.7 Utilities 53
4.7.1 Functions
All the functions described below facilitate programming and avoid transmission of arguments.
syntax:
INTEGER FUNCTION DIMENS(IELM)
IELM is a type of element. DIMENS returns the dimension corresponding to the element given.
For example, DIMENS(11) = 2.
syntax:
DOUBLE PRECISION FUNCTION DOTS(T1,T2)
T1 and T2 may be two vectors, or two blocks.
For vectors, returns their scalar product. For blocks, returns the sum of the scalar products of
the vectors they contain.
Warning:
Only the first dimension of the vectors is taken into account for the time being.
syntax:
DOUBLE PRECISION FUNCTION BIEF_SUM(T1)
T1 may be a vector, or a block.
For a vector, returns the sum of the vector components. For a block, returns the sum of all the
components of the vectors it contains.
Warning:
Only the first dimension of the vectors is taken into account for the time being.
syntax:
INTEGER FUNCTION TIME_IN_SECONDS()
Returns the time in seconds given by the computer clock. For computing the elapse time of a
job. Beware, this value is sometimes reset to zero by the computer, generally every 24 hours.
CODE is a 20 characters string saying which program calls the subroutine, for example ’ARTEMIS’.
FILES is an array of BIEF_FILE structures containing a description of all files used by the
program.
PEXIT is a logical value. If yes, the call to the subroutine will also trigger an exit from MPI.
All the relevant files, whose names are known through the DECLARATIONS_TELEMAC mod-
ule, are closed by this subroutine.
syntax:
SUBROUTINE CLIP(VEC,XMIN,CLPMIN,XMAX,CLPMAX,NPOIN)
arguments:
syntax:
SUBROUTINE FILTER( VEC,BLDMAT,T1,T2,A,FORMUL,XMUL,F,G,H,U,V,W,MESH,MSK,MASKEL,N)
Filtering operation of the vector VEC. T1 and T2 are working BIEF_OBJ structures. From
XMUL, the arguments are the same as those of MATRIX. A is a matrix which is either given
(if the logical value BLDMAT is false), or constructed according to the formula FORMUL (if
BLDMAT is true). In the latter case, the arguments F, G, H, U, V, W, may be used if they appear
in the formula FORMUL.
VEC is modified N times by FILTER according to the following formula: newV EC = XMUL ∗
A∗V EC
AL
where AL is the diagonal matrix obtained by mass-lumping A, that is by totalling the
terms in each row.
If A is a mass matrix (FORMUL = ’MATMAS ’), a smoothed vector VEC is obtained, with its
integral in the domain (the ’mass’) preserved.
If FORMUL = ’FMATMA ’, a smoothed vector VEC is obtained, with preservation of the
integral of the function F VEC.
syntax:
SUBROUTINE BIEF_OPEN_FILES(CODE,FILES,NFILES,PATH,FLOT,IFLOT,ICODE)
Replaces the old OPEN_FILES, to enable coupled programs to run concurrently even if they
use the same logical units.
The first three arguments are like BIEF_CLOSE_FILES.
PATH is the full name of the path leading to the directory containing the files (or at least the
parameter file).
FLOT is a logical value stating if there is code coupling. In this case the logical units of every
file are dynamically computed and will start at IFLOT+1, IFLOT being the argument after
FLOT.
IFLOT: see explanations on FLOT above.
ICODE is the code number in case of coupling (the calling program will be code 1, the called
program will be code 2).
The basic data for opening the files is stored in the dictionary of each program, namely in the
key-word called SUBMIT. Here is the example for the geometry file in T ELEMAC -2D:
SUBMIT : ’NGEO-READ;T2DGEO;OBLIG;BIN;LIT;SELAFIN-GEOM’
NGEO is no longer used.
READ means that this file will be opened in only read mode.
T2DGEO will be the name of the file in the temporary directory where the case will be run.
T2DGEO is also declared in T ELEMAC -2D as an integer which is the file number. It will be 1
and will not float in case of code coupling.
OBLIG means that the file is mandatory
56 Chapter 4. Programming with B IEF
ICOM is an option.
T
his section is obsolete since v7p1 due to the introduction of hermes. See Chapter
9 for information on Hermes.
The
SELAFIN format is used in 2D and 3D for the results files and for the geometry files. It is given
4.7 Utilities 57
in appendix 3. Several routines are offered for writing or reading such files. Others remain
internal routines in B IEF and will be called directly either by ALMESH or INBIEF.
syntax:
SUBROUTINE ECRGEO(X,Y,NPOIN,NBOR,NFIC,NVAR,TEXTE,VARCLA,
NVARCL,TITRE,SORLEO,NSOR,IKLE,NELEM,
NPTFR,NDP,DATE,TIME,NCSIZE,NPTIR,KNOLG)
arguments:
X,Y are the coordinates of the mesh (equivalent to MESH%X%R and MESH%Y%R)
NBOR is the array MESH%NBOR%I giving the global numbers of boundary points.
NVAR is the number of variables to write in the file (at every time-step)
TEXTE is the 32 characters strings given the names and units of variables (SORLEO, see
below, will say if they must be put in the file).
VARCLA is another array of 32 characters strings used for the so-called clandestine variables
in T ELEMAC -2D, i.e. variables which are in the geometry file and are merely transmitted
to the results file.
SORLEO is an array of logical values saying which variables in the list TEXTE will be put in
the file.
IKLE , NELEM, NPTFR, NDP are the classical components of BIEF_MESH structures : con-
nectivity table, number of elements, number of boundary points and number of points per
element.
DATE and TIME are two arrays of 3 integers giving the year, month, day and hour, minute,
second
NPTIR is the number of interface points with other sub-domains (if NCSIZE greater than 1).
KNOLG is the global number of points in the original mesh (if NCSIZE greater than 1).
syntax:
SUBROUTINE FILPOL(F,C,XSOM,YSOM,NSOM,MESH)
arguments:
FILPOL fills a vector F with a constant C, but only for points of F which are in a given
polynomial in the computational domain.
C is the constant.
XSOM and YSOM are arrays of double precision numbers giving the coordinates of the apices
of the polynomial.
W is a working real (real, not double precision) array of size the number of points in the mesh.
The bottom friction can then be changed with the user subroutine STRCHE.
syntax:
SUBROUTINE LITENR(VARSOR,CLAND,NPRE,STD,HIST,NHIST,NPOIN,
AT, TEXTPR, TEXTLU, NVAR, VARCLA, NVARCL,
TROUVE, ALIRE, W, LISTIN, MAXVAR)
LITENR will read a time record in a selafin file. It assumes that the heading with geometry data
has been read, and that a number of time records may also have been read. Some variables of
the next time record are read by LITENR. As in ECRGEO, the name of variables is in TEXTPR,
but in this list, only the variables given by the logical array ALIRE will be read. The result will
be put in a block called VARSOR. If there are clandestine variables (their number is NVARCL),
their name is given in VARCL and they will be put into the block CLAND. Other arguments
are:
STD binary standard of the file (3 characters STD, IBM or I3E). Obsolescent, use ’STD’.
HIST sometimes an array of real values may be put after the time in the same record.
TEXTLU is a working array of character*32 strings to store the names of variables in the file.
TROUVE is an integer array saying if the variables asked have been found.
W is a working real (real, not double precision) array of size the number of points in the mesh.
syntax:
SUBROUTINE SKIPGEO(NFIC,TITFIC,NPOIN,NVAR,TEXTLU
SKIPGEO reads a SELAFIN file with logical unit NFIC up the time records. It returns the title
of the file: TITFIC, the number of points in the mesh: NPOIN, the number of variables stored:
NVAR, and their names and units: TEXTLU (an array of CHARACTER*32 strings).
VARSOR is a block containing BIEF_OBJ structures with the variables to be printed in the
file.
HIST and NHIST are used to add data in the time record of the Selafin format (HIST will be
the array of the values and NHIST their number)
N is the number of points to be printed (it may be different from the number of degrees of
freedom, as some values are dropped when quasi-bubble or quadratic elements are used).
STD is a 3-character string (meant for binary variants, currently not used)
LISPRD and LEOPRD are the printing periods on listing and file.
SORLEO and SORIMP are logical arrays stating if a variable must be exited or not (same
order as in the block VARSOR).
MAXVAR is the number of variables in the block VARSOR, and the dimension of SORLEO
and SORIMP.
NOMVAR is an array of 32-character strings containing the names (16 characters) and units
(16 characters) of variables.
PTINIG and PTINIL are the time steps (respectively for file and listing) at which will start the
prints. These integers stem from key-words such as NUMBER OF FIRST TIME-STEP
FOR GRAPHIC PRINTOUTS in T ELEMAC -2D and T ELEMAC -3D.
syntax:
SUBROUTINE BIEF_SUITE(VARSOR, CLAND, NUMDE, NPRE, STD,
HIST, NHIST, NPOIN, AT, TEXTPR,
VARCLA, NVARCL, TROUVE, ALIRE,
LISTIN, FIN, MAXVAR, NPLAN, DT)
BIEF_SUITE is used to start a new computation from previous results. The time record to start
with is the last one if FIN=.TRUE., and is NUMDEB if FIN=.FALSE. Otherwise the principle
and arguments are the same as LITENR, see above. For Selafin format BIEF_SUITE is a
combination of SKIPGEO and LITENR.
NPLAN and DT are optional parameters.
If NPLAN is present (case of T ELEMAC -3D with prisms) and if the number of planes is differ-
ent, the data will be interpolated to cope with the number of planes asked, i.e. NPLAN.
If DT is present, the time step of records in the file will be returned. This assumes that there are
at least 2 records in the file, otherwise an error message will be issued.
syntax:
SUBROUTINE BIEF_VALIDA(VARREF, TEXTREF, UREF, REFFORMAT, VARRES,
TEXTRES, URES, RESFORMAT, MAXTAB, NP, IT,
MAXIT, ACOMPARER)
4.7 Utilities 61
BIEF_VALIDA offers an automatic way to compare two SELAFIN files to perform validations
of modifications in a program. A reference file (logical unit UREF) is compared to a result file
(logical unit URES).
VARREF and VARRES are blocks where the variables to read will be put.
TEXTREF and TEXTRES are the names of the variables and give their implicit numbering.
UREF and URES are the logical units of reference file and result file.
REFFORMAT and RESFORMAT are the formats of reference file and result file (i.e. ’SE-
LAFIN ’,’SELAFIND’ or ’MED ’.
MAXTAB is the maximum number of variables.
NP the number of points in the mesh.
IT and MAXIT are respectively the current and the maximum iteration. A comparison is done
only when the last iteration MAXIT is reached and only the last time-step is checked.
ACOMPARER is an integer array saying if a variable must be checked (1) or not (0).
syntax:
SUBROUTINE CREATE_DATASET(FORMAT,NRES,TITLE,MAXVAR,NOMVAR,OUTVAR)
FORMAT: a 8-character string. Possible values are ’SELAFIN ’, ’SELAFIND’ and ’MED ’.
SELAFIN is the classical format in the Telemac system. SELAFIND is the same but with real
numbers saved in double precision (so far not supported by post processors). MED is an EDF
format that is recognised by all tools of the Salome platform.
NRES: the logical unit
In T ELEMAC -2D for example and for the results file, these first two arguments will be:
T2D_FILES(T2DRES)%FMT and T2D_FILES(T2DRES)%LU.
TITLE is the title of the case, in 80 characters.
MAXVAR is the maximum number
This subroutine will only store in the file the information of the title and the names and units of
variables.
syntax:
SUBROUTINE WRITE\_DATA(FORMAT_RES, NRES, MAXVAR, AT,
LT, SORLEO, NOMVAR, VARSOR, N)
Mostly as BIEF_DESIMP, but a lower level. It will not deal with periods and printing on listing.
arguments:
NOMVAR is an array of 32-character strings containing the names (16 characters) and units
(16 characters) of variables.
VARSOR is a block containing BIEF_OBJ structures with the variables to be printed in the
file.
syntax:
62 Chapter 4. Programming with B IEF
arguments:
MARDAT and MARTIM are two arrays of 3 integers containing the date : year, month, day,
and hours, minutes, seconds.
I_ORIG and J_ORIG are the numbers of metres to add to coordinates to get georeferenced
data.
JULTIM returns the time in Julian centuries since the 31 December 1899. The starting time of
a computation is given by YEAR,MONTH,DAY,HOUR,MIN,SEC, and AT (current time in the
computation is added).
syntax:
DOUBLE PRECISION FUNCTION TSLOC(YEAR,MONTH,DAY,HOUR,MIN,SEC,AT)
In two dimensions, solves the advection-diffusion of a tracer, including source terms. Starting
from a tracer FN at time step n, it gives back the tracer F at time step n+1. Refer to source code
for a full list of arguments. The advection may have been done previously by the method of
characteristics, in which case the result is in FTILD, or is done by CVDFTR itself, which may
call other subroutines such as CVTRVF and CVTRVF_POS. Explicit and implicit source terms
may be treated, as well as punctual sources. An argument ICONVF monitors the choice of the
advection scheme.
syntax:
SUBROUTINE CHARAC
4.7 Utilities 63
This is the header subroutine for advection with the method of characteristics. It calls scalar or
parallel variants of this method. The parallel version of the method of characteristics is included
in module STREAMLINE. CHARAC may deal with a single.
Refer to source code for a full list of arguments. FN is the variable to be advected and FTILD
the result. They may be blocks of variables and in this case the argument NOMB is the number
of variables that will be treated.
CORLAT is called by INBIEF when the coordinates are spherical. It allows changing of latitude
and longitude of points.
syntax:
SUBROUTINE CORRXY
CORRXY is called once at the beginning of INBIEF (and before CORLAT). It allows to change
the coordinates of points. Users are free to do any change (for example translations or rotations)
provided that it keeps the topology of the mesh.
A translation in T ELEMAC -2D would be done by adding USE DECLARATIONS_TELEMAC2D
in CORRXY, declaring integer I, and then:
DO I=1,NPOIN
X(I) = X(I) + 100.D0
Y(I) = Y(I) + 200.D0
ENDDO
STRCHE is called once after reading the bottom friction in the geometry file, or after setting it
to a constant value. This subroutine is empty and can be used only with modules containing
global declarations. We give hereafter an example that would work with T ELEMAC -2D:
SUBROUTINE STRCHE
USE BIEF
USE DECLARATIONS_TELEMAC2D
INTEGER I
DO I=1,NPOIN
IF(X(I).GT.5.D0) THEN
CHESTR%R(I) = 35.D0
ELSE
CHESTR%R(I) = 30.D0
ENDIF
ENDDO
RETURN
END
64 Chapter 4. Programming with B IEF
!**********************************************************************
!
USE BIEF
USE DECLARATIONS_TELEMAC
USE DECLARATIONS_TELEMAC2D
USE DECLARATIONS_SISYPHE, ONLY : SIS_FILES
USE INTERFACE_TELEMAC2D
!
IMPLICIT NONE
INTEGER LNG,LU
COMMON/INFO/LNG,LU
!
INTEGER TDEB(8),TFIN(8),NCAR,IFLOT
!
CHARACTER(LEN=24), PARAMETER :: CODE1=’TELEMAC2D ’
CHARACTER(LEN=24), PARAMETER :: CODE2=’SISYPHE ’
!
CHARACTER(LEN=250) PATH
CHARACTER(LEN=144) MOTCAR(300),FILE_DESC(4,300)
!
!======================================================================
!
! INITIALISING FILES (NAMES OF FILES=’ ’ AND LOGICAL UNITS =0)
! GETTING NCSIZE BY CALLING P_INIT
!
CALL BIEF_INIT(CODE1,PATH,NCAR,.TRUE.)
!
! INITIAL TIME FOR COMPUTATION DURATION
!
CALL DATE_AND_TIME(VALUES=TDEB)
!
! PRINTING BANNER ON LISTING
!
IF(LNG.EQ.1) WRITE (LU,100)
IF(LNG.EQ.2) WRITE (LU,101)
WRITE (LU,102)
100 FORMAT(/////,1X,’LISTING DE TELEMAC-2D ’,78(’-’))
101 FORMAT(/////,1X,’LISTING OF TELEMAC-2D ’,78(’-’))
102 FORMAT(/////,
&14X,’ TTTTT EEEEE L EEEEE M M AAAAA CCCCC’,/,
&14X,’ T E L E MM MM A A C ’,/,
&14X,’ T EEE L EEE M M M AAAAA C ’,/,
&14X,’ T E L E M M A A C ’,/,
&14X,’ T EEEEE LLLLL EEEEE M M A A CCCCC’,/,
&14X,’ ’,/,
&14X,’ 2D VERSION 6.0 FORTRAN 90 ’,/,
&14X,’ WITH SEVERAL TRACERS ’,/,
&14X,’ COUPLED WITH SISYPHE INTERNALLY ’,/,
&14X,/////)
!
!-----------------------------------------------------------------------
!
! READING THE STEERING FILE
!
CALL LECDON_TELEMAC2DLECDON_TELEMAC2D(MOTCAR,FILE_DESC,PATH,NCAR)
!
4.8 Designing a new program 67
!-----------------------------------------------------------------------
!
! OPENING FILES FOR TELEMAC2D
!
IFLOT = 0
CALL BIEF_OPEN_FILESBIEF_OPEN_FILES(CODE1,T2D_FILES,44,PATH,NCAR,
& INCLUS(COUPLING,’INTER’),IFLOT,1)
!
!-----------------------------------------------------------------------
!
! MEMORY ALLOCATION
!
CALL POINT_TELEMAC2DPOINT_TELEMAC2D
!
! SAVING COMMON NDS CORRESPONDING TO TELEMAC-2D MESH
!
CALL SAVE_NDS(1)
!
!-----------------------------------------------------------------------
!
! INITIALISING SISYPHE
!
IF(INCLUS(COUPLING,’SISYPHE’)) THEN
!
! FALSE= P_INIT NOT CALLED
CALL BIEF_INIT(CODE2,PATH,NCAR,.FALSE.)
!
IF(LNG.EQ.1) WRITE (LU,103)
IF(LNG.EQ.2) WRITE (LU,104)
WRITE (LU,105)
103 FORMAT(/////,1X,’LISTING DE SISYPHE AVEC COUPLAGE’,78(’-’))
104 FORMAT(/////,1X,’LISTING OF SISYPHE WITH COUPLING’,78(’-’))
105 FORMAT(/////,
& 14X,’ SSSS I SSSS Y Y PPPP H H EEEEE’ ,/,
& 14X,’ S I S Y Y P P H H E ’ ,/,
& 14X,’ SSS I SSS Y PPPP HHHHH EEEE ’,/,
& 14X,’ S I S Y P H H E ’,/,
& 14X,’ SSSS I SSSS Y P H H EEEEE’ ,/,
& 14X,’ ’,/,
& 14X,’ VERSION 6.0 ’,/,
& 14X,’ COUPLED WITH TELEMAC-2D INTERNALLY ’,/,
& 14X,/////)
!
CALL LECDON_SISYPHE(MOTCAR,FILE_DESC,PATH,NCAR,CODE1)
!
CALL BIEF_OPEN_FILESBIEF_OPEN_FILES(CODE2,SIS_FILES,44,PATH,NCAR,
& INCLUS(COUPLING,’SISYPHE’),IFLOT,2)
CALL POINT_SISYPHE
!
! SAVING COMMON NDS CORRESPONDING TO SISYPHE MESH (SO FAR THE SAME !)
!
CALL SAVE_NDS(2)
!
ELSEIF(COUPLING(1:1).EQ.’ ’) THEN
!
! NOTHING TO DO
68 Chapter 4. Programming with B IEF
!
ELSEIF(INCLUS(COUPLING,’DELWAQ’)) THEN
!
! NOTHING TO DO
!
ELSE
! ERREUR
IF(LNG.EQ.1) WRITE (LU,*) ’CAS DE COUPLAGE INCONNU : ’,COUPLING
IF(LNG.EQ.2) WRITE (LU,*) ’UNEXPECTED COUPLING CASE: ’,COUPLING
CALL PLANTE(1)
STOP
ENDIF
!
! RESETTING TELEMAC2D CONFIGURATION
!
CALL CONFIG_CODE(1)
!
!=======================================================================
!
IF(ESTIME.EQ.’ ’) THEN
!
!-----------------------------------------------------------------------
!
! NORMAL MODE: ONE CALL OF TELEMAC2D
!
CALL TELEMAC2D(PASS=-1,ATDEP=0.D0,NITER=0,CODE=’ ’)
!
!-----------------------------------------------------------------------
!
ELSE
!
!-----------------------------------------------------------------------
!
! PARAMETER ESTIMATION MODE : CALLING HOMERE_ADJ_T2D
!
CALL HOMERE_ADJ_T2D
!
ENDIF
!
!=======================================================================
!
! CLOSING FILES
!
CALL BIEF_CLOSE_FILES(CODE1,T2D_FILES,44,.TRUE.)
!
IF(INCLUS(COUPLING,’SISYPHE’)) THEN
CALL CONFIG_CODE(2)
CALL BIEF_CLOSE_FILES(CODE2,SIS_FILES,44,.FALSE.)
ENDIF
!
!-----------------------------------------------------------------------
!
IF(LNG.EQ.1) WRITE (LU,10)
IF(LNG.EQ.2) WRITE (LU,11)
10 FORMAT(1X,///,1X,’FIN NORMALE DU program’,///)
11 FORMAT(1X,///,1X,’CORRECT END OF RUN’,///)
4.8 Designing a new program 69
!
!-----------------------------------------------------------------------
!
! TIME OF END OF COMPUTATION
!
CALL DATE_AND_TIME(VALUES=TFIN)
CALL ELAPSE(TDEB,TFIN)
!
!-----------------------------------------------------------------------
!
STOP
END
Some explanations:
• The statement USE BIEF is given first because the module DECLARATIONS_TELEMAC2D
contains declarations of BIEF_OBJ structures, for example the depth H or the mesh
called MESH.
• The string CODE contains the name of the program and will be used by B IEF sub-
routines such as BIEF_OPEN_FILES to open the relevant files. It implies that the
LECDON_TELEMAC2D subroutine uses also the module DECLARATIONS_TELEMAC
and correctly fills the names of the files.
CHARACTER(LEN=144) MOTCAR(NMAX)
CHARACTER*72 MOTCLE(4,NMAX,2)
INTEGER TROUVE(4,NMAX)
LOGICAL DOC
!
!
..........
!
! INITIALISATIONS FOR CALLING DAMOCLES :
!
DO 10 K=1,NMAX
MOTCAR(K)(1:1)=’ ’
DIMENS(1,K) = 0
DIMENS(2,K) = 0
DIMENS(3,K) = 0
DIMENS(4,K) = 0
10 CONTINUE
! IF YES WILL PRINT ALL DOCUMENTATION IN DICTIONARY
DOC = .FALSE.
!
!-----------------------------------------------------------------------
! OPENING PARAMETER FILE AND DICTIONARY
!-----------------------------------------------------------------------
!
IF(NCAR.GT.0) THEN
!
NOM_DIC=PATH(1:NCAR)//’T2DDICO’
NOM_CAS=PATH(1:NCAR)//’T2DCAS’
!
ELSE
!
NOM_DIC=’T2DDICO’
NOM_CAS=’T2DCAS’
!
ENDIF
!
OPEN(2,FILE=NOM_DIC,FORM=’FORMATTED’,ACTION=’READ’)
OPEN(3,FILE=NOM_CAS,FORM=’FORMATTED’,ACTION=’READ’)
!
!-----------------------------------------------------------------------
!
CALL DAMOCLE( ADRESS , DIMENS , NMAX , DOC , LNG , LU ,
& MOTINT , MOTREA , MOTLOG , MOTCAR , MOTCLE ,
& TROUVE , 2 , 3 , .FALSE. , FILE_DESC )
!
!-----------------------------------------------------------------------
! FERMETURE DES FICHIERS DICTIONNAIRE ET CAS
!-----------------------------------------------------------------------
!
CLOSE(2)
CLOSE(3)
Remark: the names of the steering file and the dictionary, their logical units are here hard-coded.
As they are closed after, logical units 2 and 3 may be re-used.
After calling DAMOCLES, the parameters are in the arrays MOTINT, MOTREA, MOTLOG
and MOTCAR if they are (respectively) integers, double precision numbers, logical values or
4.8 Designing a new program 71
character strings. Their rank in the arrays is given by their index in the dictionary.
For example the turbulence model is in T ELEMAC -2D an integer with rank 7 in the dictionary.
It is initialised as follows:
ITURB = MOTINT( ADRESS(1, 7) )
The size of arrays is given by DIMENS, for example the array of prescribed free surfaces (index
31 of double precision numbers in the dictionary) in T ELEMAC -2D is initialised by:
NCOTE = DIMENS(2,31)
IF(NCOTE.NE.0) THEN
DO K=1,NCOTE
COTE(K) = MOTREA( ADRESS(2,31) + K-1 )
ENDDO
ENDIF
As MOTCAR is declared as an array of CHARACTER(LEN=144) strings, it may be necessary
to take only a part of them, as below:
TITCAS = MOTCAR( ADRESS(4, 1) )(1:72)
Where TITCAS is declared as a CHARACTER(LEN=72) string.
Checking and modifications of key-words should be done only in LECDON.
Allocating memory
This is done in the subroutine called POINT_NAMEOFprogram. We give and comment here-
after parts of POINT_TELEMAC2D:
USE BIEF
USE DECLARATIONS_TELEMAC
USE DECLARATIONS_TELEMAC2D !where all BIEF_OBJ structures are declared
!
!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
!
.
. (Declarations and printing skipped), then:
.
!
! DISCRETISATIONS TYPES
!
! P0 and P1 discretisation
!
IELM0 = 10*(IELMH/10)
IELM1 = IELM0 + 1
!
! P1 Discretisation of boundaries
!
IELB1 = IELBOR(IELM1,1)
! Element with the greatest number of degrees of freedom
IELMX=MAX(IELMU,IELMH,IELMT,IELMK,IELME)
72 Chapter 4. Programming with B IEF
!
! TYPE OF STORAGE AND MATRIX-VECTOR PRODUCT
!
CFG(1) = OPTASS
CFG(2) = PRODUC
!
!=======================================================================
!
! ALLOCATING THE MESH
!
CALL ALMESH(MESH,’MESH ’,IELMX,SPHERI,CFG,T2D_FILES(T2DGEO)%LU,
& EQUA,I3=I3,I4=I4)
! IF ORIGIN COORDINATES IN GEOMETRY FILE AND NOT IN PARAMETER FILE,
! VALUES OF GEOMETRY FILE ARE TAKEN
IF(I3.NE.0.AND.I_ORIG.EQ.0) I_ORIG=I3
IF(I4.NE.0.AND.J_ORIG.EQ.0) J_ORIG=I4
!
! EXAMPLE OF CREATION OF ALIASES
!
IKLE => MESH%IKLE
X => MESH%X%R
Y => MESH%Y%R
NELEM => MESH%NELEM
!
!=======================================================================
!
! EXAMPLE OF ALLOCATION OF A REAL ARRAY
!
CALL BIEF_ALLVEC(1,U,’U ’,IELMU,1,1,MESH)
!
! EXAMPLE OF ALLOCATION OF A BLOCK
!
CALL ALLBLO(UNK,’UNK ’)
! ADDING BIEF_OBJ STRUCTURES IN THE BLOCK UNK
CALL ADDBLO(UNK,DH)
CALL ADDBLO(UNK, U)
CALL ADDBLO(UNK, V)
CALL INBIEF(LIHBOR%I,KLOG,IT1,IT2,IT3,LVMAC,IELMX,
& LAMBD0,SPHERI,MESH,T1,T2,OPTASS,PRODUC,EQUA)
The character string called SUBMIT is used through Damocles by the Fortran program. It is
composed of 6 character strings.
The first string, here T2DRES-READWRITE, is made of:
1. the Fortran integer for storing the file number: T2DRES (which is declared in declara-
tions_telemac2d.f)
2. the argument ACTION in the Fortran Open statement that will be used to open the file.
ACTION may be READ, WRITE, or READWRITE. Here it is READWRITE because
the results file is written, and in case of validation it is read at the end of the computation.
It will be stored into T2D_FILES%ADR(T2DRES)%ACTION
The second string, here T2DRES, is the name of the file as it will appear in the temporary file
where the computation is done.
The third string may be OBLIG (the name of the file must always be given), or FACUL (this
file is not mandatory).
The fourth string (here BIN) says if it is a binary (BIN) or ASCII (ASC) file.
The fifth string is just like the READWRITE statement.
The sixth string gives information on how the file must be treated. ’SELAFIN’ means that the
file is a Selafin format, it will have to be decomposed if parallelism is used. Other possibilities
are:
SELAFIN-GEOM this is the geometry file
PARAL this file will have an extension added to its name, for distinguishing between proces-
sors
See Section 15.1 for a more detailed description of the SUBMIT strings.
The following sequence of subroutines is used for opening, using and closing files:
Note : subroutine INIT_FILES2 in B IEF version 5.9 has been renamed BIEF_INIT from version
6.0 on and has from now on nothing to see with files.
1. Opening files
IFLOT=0
CALL BIEF_OPEN_FILES(CODE,T2D_FILES,44,PATH,NCAR,COUPLAGE,IFLOT,ICODE)
2. Using files
Most operations on files consist on reading and writing, which always uses the logical
unit. Every file has a name in the temporary folder where the program is executed, e.g.
T2DRES. The associated file number is an integer with the same name. The logical unit
of this file is stored into T2D_FILES(T2DRES)%LU. The logical unit of the geometry
file in Sisyphe will be SIS_FILES(SISGEO)%LU.
Sometimes the real name of files in the original is also used, for example to know if it
exists (i.e. has been given in the parameter file). This name is retrieved in the component
NAME. For example the name of the geometry file in Sisyphe will be SIS_FILES(SISGEO)%NAME.
Note that the name of the same file in the temporary folder is SIS_FILES(SISGEO)%TELNAME.
We have in fact:
SIS\_FILES(SISGEO)\%TELNAME=’SISGEO’.
3. Closing files
CALL BIEF\_CLOSE\_FILES(CODE,T2D\_FILES,44,PEXIT)
4.8 Designing a new program 75
This chapter will present a description of the finite elements used, the mesh and the storage
modes for the finite element matrices.
Triangle P1
This is a triangle with linear interpolation. The reference triangle is composed of the coordinate
points (0,0) (0,1) and (1,0). On this reference element, the basis functions have the following
values :
P1(ξ , η) = 1 − ξ − η
P2(ξ , η) = ξ
P3(ξ , η) = η
Quasi-bubble triangle
The Quasi-Bubble element is obtained by adding an additional point to the three vertices of a
triangle. The centre of gravity of the triangle constitutes a natural choice for this fourth point.
The initial element P1 is thus divided into three sub-triangles:
5.1 B IEF data structure 77
By adopting a linear discretisation, the basis functions of the triangle QB (in the sense of finite
element) are the 4 Ψ linear functions defined on the triangle T and confirming:
Ψi (Pj ) = δi j
Quadratic triangle
• Point 1: (0,0)
• Point 2: (1,0)
• Point 3: (0,1)
• Point 4: (1/2,0)
• Point 5: (1/2,1/2)
• Point 6: (0,1/2)
The quadratic interpolation polynoms Pi (x, y), with i = 1...6, are such that Pi (x, y) = ϕi (T −1 (x, y))
where T is the isoparametric transformation that gives the real triangle as a function of the ref-
erence triangle and ϕi are the basis functions in the reference triangle. In practice T −1 is never
built and the computation of integrals is done in the reference triangle.
The 6 quadratic basis ϕi (α, β ) are chosen to ensure the following property:
6
∑ ϕi (α, β ) = 1, ∀(α, β ) ∈ triangle
i=1
Moreover every basis must be equal to 1 on its own point and zero on the five others. This is
verified if we take:
where k and l are the indices of points of the segment where is point i. More precisely:
Remark: on boundaries a point number 3 is added in the middle and the interpolation polynoms
are:
ϕ1 (ξ ) = 2 × (1 − ξ ) × ( 21 − ξ )
ϕ2 (ξ ) = (2 × ξ − 1) × ξ
ϕ3 (ξ ) = 4 × ξ × (1 − ξ )
Quadrilateral Q1
The reference square is comprised of the coordinate points (-1,-1) (1,-1) (1,1) and (-1,1). On
this reference element, the base functions have the following values:
P1(ξ , η) = (1 − ξ − η + ξ η)/4
P2(ξ , η) = (1 + ξ − η − ξ η)/4
P3(ξ , η) = (1 + ξ + η + ξ η)/4
P4(ξ , η) = (1 − ξ + η − ξ η)/4
Tetrahedron
So far real there is no module in the Telemac system which fully uses this element. In T ELEMAC -
3D, tetrahedrons are not accepted.
The reference tetrahedron is comprised of the coordinate points:
(0,0,0) (1,0,0) (0,1,0) (0,0,1). On this reference element, the base functions have the following
values:
Ψ1 = (1 − α − β − γ)
Ψ2 = α
Ψ3 = β
Ψ4 = γ
Prism
This is a prism with 3 vertical rectangular faces, and two triangular faces, one at the bottom and
one at the top, and which are not necessarily horizontal.
(The figures indicate local numbering of the nodes).
80 Chapter 5. Internal structure of B IEF
The basis functions Ψ j corresponding to the nodes j of the reference element are:
1−γ
Ψ1 = (1 − α − β )
2
1−γ
Ψ2 = α
2
1−γ
Ψ3 = β
2
1+γ
Ψ4 = (1 − α − β )
2
1+γ
Ψ5 = α
2
1+γ
Ψ6 = β
2
The basis functions φi on any prism in the ω mesh are obtained by creating the Ψi functions
with the isoparametric transformation F, transforming the reference prism into this prism of any
type.
For a prism in the ω mesh with vertex coordinates (xi,yi,zi), F makes any point M0 with coor-
dinates (α,β ,γ) of the reference element correspond to any point M with coordinates (x,y,z) of
this prism by:
6
x = ∑i=1 xi Ψi (α, β , γ)
y = ∑6i=1 yi Ψi (α, β , γ)
z = ∑6i=1 zi Ψi (α, β , γ)
The Ψi functions which appear in the definition of F are the same as the basis functions defined
on the reference element since the reference element chosen is isoparametric (the interpolation
nodes are also the geometric nodes). In our case, the expressions of F can be simplified since:
x1 = x4 ; y1 = y4
x2 = x5 ; y2 = y5
x3 = x6 ; y3 = y6
(triangle P1, prism P0,...) is linked to a code and includes NDP nodes. (MESH%NDP) On an el-
ement, the nodes are numbered from 1 to NDP. The connection between this element numbering
(local numbering) and the numbering of the mesh nodes from 1 to NPOIN (general numbering)
is made through the connectivity table IKLE (MESH%IKLE). The global number of the node
with the local number ILOC in the element IELEM is IKLE(IELEM, ILOC).
Table 5.1: Elements in B IEF version 6.2 (the T ELEMAC -3D prism is a prism with four vertical
quadrangular sides). Quadrilateral elements are kept for an internal use by T ELEMAC -3D but
no longer maintained.
IELM NDP(IELM)
00 (segment P0 = constant value) 1
01 (segment P1 = linear) 2
10 (triangle P0 = constant value) 1
11 (triangle P1 = linear) 3
12 (quasi-bubble triangle) 4
13 (quadratic element) 6
20 (quadrilateral Q0 = constant value) 1
21 (quadrilateral Q1 = linear) 4
30 (tetrahedron T0 = constant value 1
31 (tetrahedron T1 = linear 4
40 (prism P0 = constant value) 1
41 (prism P1 = linear) 6
50 (tetrahedron T0 from split prism) 1
51 (tetrahedron T1 from split prism) 4
60 (triangle P0 in a lateral boundary 1
of a mesh of prisms split into
tetrahedrons)
61 (triangle P1 in a lateral boundary 3
of a mesh of prisms split into
tetrahedrons)
70 (quadrilateral Q0 in a lateral 1
boundary of a mesh of prisms)
71 (quadrilateral Q1 in a lateral 4
boundary of a mesh of prisms)
80 (triangle P0 in a boundary 1
of a mesh of tetrahedrons)
81 (triangle P1 in a boundary 3
of a mesh of tetrahedrons)
In addition, the boundary points of the mesh must be known. These are numbered from 1 to
NPTFR (MESH%NPTFR). The connection with the general numbering is made through the
table NBOR (MESH%NBOR). NBOR(IPTFR) is the general numbering of the boundary point
IPTFR.
The tables X, Y, Z, IKLE and NBOR are sufficient for defining the mesh. However, it is useful
to have other tables available, which can often facilitate the writing of the algorithms. Thus, is
it very useful to have tables other than NBOR to describe the boundaries. In fact, three types of
numbering can be associated with the boundary of the studied domain. These are the boundary
5.1 B IEF data structure 83
point numbers, the boundary face numbers and the local numbers of the boundary nodes in each
of the boundary faces. To connect them, B IEF uses IKLBOR (BIEF%IKLBOR), a connectivity
table for the boundary faces, NELBOR (MESH%NELBOR) linking the boundary face num-
bers to the element numbers to which they belong, and NULONE (MESH%NULONE), a table
linking the local numbers of the boundary nodes in the boundary faces to the local numbers of
these nodes in the elements to which they belong. The following example illustrates the use of
these tables for a triangular element:
Take a triangle P1 numbered IELEM constructed on the 3 nodes with global numbers NG1,
NG2, NG3. The face defined by the two points NG2 and NG3 is a boundary face with the
number IFAFR. The nodes NG2 and NG3 are boundary nodes with the boundary numbers
IPTFR1 and IPTFR2. The nodes NG1, NG2 and NG3 have the local numbers 1, 2 and 3 in
the triangle. Finally, the nodes IPTFR1 and IPTFR2 have the local numbers 1 and 2 on the
boundary face.
We have:
IKLE(IELEM,1) = NG1
IKLE(IELEM,2) = NG2
IKLE(IELEM,3) = NG3
NBOR(IPTFR1) = NG2
NBOR(IPTFR2) = NG3
NELBOR(IFAFR) = IELEM
IKLBOR(IFAFR,1) = IPTFR1
IKLBOR(IFAFR,2) = IPTFR2
NULONE(IFAFR,1) = 2
NULONE(IFAFR,2) = 3
For certain elements (prisms), the boundary faces are of two types. Thus, the boundary faces
of the prism are triangles or quadrilaterals. A dimension is then added to the tables NELBOR,
IKLBOR and NULONE in order to distinguish the type of face in question.
To know the types of boundary faces (segment P1, triangle P1...) for example to calculate
boundary matrices, a function IELBOR is used. IELBOR(IELM,1) gives the code of the first
type of face of the type IELM element (bottom and top of prisms), IELBOR(IELM,2).gives the
type of vertical sides of boundary prisms, which may be triangles or quadrilaterals depending
84 Chapter 5. Internal structure of B IEF
on the fact that the prisms are split into tetrahedrons or not.
The adaptive mesh is simply specified by dimensioning with the maximum possible number of
NELMAX elements or the maximum possible number of NELBRX boundary elements all the
tables with several dimensions such as IKLE, NULONE...etc.
EBE storage
In a finite element code using iterative resolution methods, a matrix is essentially used to mul-
tiply it by a vector. Other operations with a matrix are less frequent, and, as will be seen in
Chapter IV, these operations can be constructed on the architecture of a matrix-vector product.
The storage mode of a matrix has thus been motivated in order to make its vector product as
effective as possible.
It is well known that it is not necessary to assemble a finite element matrix to multiply it by a
vector. On a mesh of NELEM elements, a matrix M is written as a function of the elementary
matrices Me on each of the elements according to the following:
NELEM
M= ∑ Pe Me Pet
e=1
where Pe is a transfer matrix between the element and the general mesh. Pe is constructed using
the connectivity table. For example, for a triangle P1 with element number IELEM and vertices
with general numbers NG1, NG2 and NG3, MIELEM is a matrix 3*3 and PIELEM is a matrix
NPOIN*3 such that the coefficient of PIELEM situated at the intersection of row I and column
J is 1 if I = IKLE(IELEM,J) and otherwise it is 0.
0 0 0
1 0 0 lineIKLE(IELEM, 1)
. . .
0 1 0 lineIKLE(IELEM, 2)
PIELEME = . . .
. . .
. . .
0 0 1 lineIKLE(IELEM, 3)
0 0 0
If X is a vector, the product M.X becomes:MX = ∑NELEM e=1 (Pe Me Pet )X
which is the same as multiplying Me by the components of X associated with the nodes of the
element e (elementary products), then calculating the sum for all the mesh elements (assembly).
It is of course never necessary to construct the matrix Pe which is no other than the connectivity
table IKLE.
A matrix M can be stored in the form of NELEM matrices Me. For a mesh of triangles P1, this
gives 9*NELEM coefficients. This number can be reduced by retaining only the off-diagonal
terms for each elementary matrix and assembling the diagonal terms as shown below.
Let De and Ee the diagonal and off-diagonal parts of Me (Me = De + Ee ), then:
NELEM NELEM NELEM
MX = ∑ (Pe De Pet )X + ∑ (Pe Ee Pet )X = DX + ∑ (Pe Ee Pet )X
e=1 e=1 e=1
In B IEF, a matrix MAT is therefore stored in two arrays, one being DMAT, containing the
diagonal of the assembled matrix, and the other XMAT, containing the off-diagonal terms of
the elementary matrices. For a matrix constructed on a mesh of triangles P1, all that has to
be stored is 6*NELEM + NPOIN coefficients, which represents a saving in space of about
2.5*NELEM coefficients compared with complete storage of the element matrices.
In addition, by using elementary matrices, it is possible to obtain a vectorisable matrix-vector
product on a vector computer. The loop on the elementary products is vectorisable and the
assembly loop for these elementary products may also be vectorisable provided a few precau-
tions are taken concerning the numbering of the mesh. We shall look in greater detail at the
matrix-vector product and assembly in Chapter IV, which deals with matrix operations.
For storage of off-diagonal elements, the convention adopted in B IEF is as follows. Let us take
the case of an element IELEM constructed on NLOC nodes. An elementary matrix Me includes
in this case NLOC*(NLOC-1) off-diagonal terms Ei,j, situated in row i and column j of Me.
Let:
XMAT(IELEM,1) = E1,2
XMAT(IELEM,2) = E1,3
.........................................
XMAT(IELEM,NLOC-1) = E1,NLOC
.........................................
XMAT(IELEM,NLOC*(NLOC-1)/2) = ENLOC-1,NLOC
For the terms in the upper triangular part of Me. If Me is symmetrical, the array XMAT is
complete. Otherwise, the lower triangular part of Me must also be stored, which is achieved in
the following way:
XMAT(IELEM,NLOC*(NLOC-1)/2 + 1) = E2,1
XMAT(IELEM,NLOC*(NLOC-1)/2 + 2) = E3,1
.........................................
.........................................
XMAT(IELEM,NLOC*(NLOC-1)) = ENLOC,NLOC-1
EDGE-BASED storage
Edge-based storage is a recent technique which enables to store R
a matrix in an optimal and easy
way. The idea is that the element of the matrix, let’s say e.g. Ω Ψi Ψ j dΩ, with i different from
j, is not equal to 0 only if points I and j are linked by a segment of the mesh. Every segment
is thus the best location to store these off-diagonal terms. For a non symmetrical matrix, there
will be two coefficients to store on every segment, for a symmetrical matrix, only one will
be necessary. This can be extended to complex elements such as quasi-bubble by adding the
relevant segments. The data structure to deal with such a storage is very simple:
An array called GLOSEG, equivalent of IKLE for elements, which gives the global numbers
of the two ends of the segment. Its dimension in Fortran is (NSEG,2) where NSEG is the total
number of segments, i.e. for triangles : (3*NELEM+NPTFR)/2.
An array called ELTSEG, with dimensions (NELEM,NS), where NS is the number of segments
in an element.(3 for a triangle). ELTSEG gives for every element the segment numbers of its 3
segments.
An array ORISEG, with dimensions (NELEM,NS). ORISEG gives the orientation of every
segment in an element, i.e. it is equal to 1 if the segment is in counter-clockwise orientation
(from its point 1 to its point 2), and is equal to 2 otherwise.
A matrix storage then consists of:
• A diagonal
XA1 contains the coefficient of point 2 in equation of point 1, and XA2 its symmetrical part,
coefficient of point 1 in equation of point 2.
XA2 is not necessary if the matrix is symmetrical. When the matrix is rectangular, XA2 first
contains the part symmetrical to XA1, then the extra terms, each one corresponding with a
segment and with the same order as the segments.
The matrix thus stored is assembled.
The local numbering of segments in an element is the following:
Linear triangle:
Segment 1 goes from point 1 to point 2 or from point 2 to point 1 (depending of ORISEG)
Segment 2 goes from point 2 to point 3 or from point 3 to point 2 (depending of ORISEG)
Segment 3 goes from point 3 to point 1 or from point 1 to point 3 (depending of ORISEG)
Quasi-bubble triangle:
Segment 1 goes from point 1 to point 2 or from point 2 to point 1 (depending of ORISEG)
Segment 2 goes from point 2 to point 3 or from point 3 to point 2 (depending of ORISEG)
Segment 3 goes from point 3 to point 1 or from point 1 to point 3 (depending of ORISEG)
Segment 4 goes from point 1 to point 4 Segment 5 goes from point 2 to point 4 Segment 6 goes
from point 3 to point 4
Segments 4 to 6 need no value of ORISEG, they always go from a linear point to the quadratic
point. This is used in matrix-vector products algorithms, see subroutine MVSEG.
5.2 Construction of matrices 87
Quadratic triangle:
Segment 1 goes from point 1 to point 2 or from point 2 to point 1 (depending of ORISEG)
Segment 2 goes from point 2 to point 3 or from point 3 to point 2 (depending of ORISEG)
Segment 3 goes from point 3 to point 1 or from point 1 to point 3 (depending of ORISEG)
Segment 4 goes from point 1 to point 4 Segment 5 goes from point 2 to point 5 Segment 6 goes
from point 3 to point 6 Segment 7 goes from point 2 to point 4 Segment 8 goes from point 3
to point 5 Segment 9 goes from point 1 to point 6 Segment 10 goes from point 1 to point 5
Segment 11 goes from point 2 to point 6 Segment 12 goes from point 3 to point 4 Segment 13
goes from point 4 to point 5 Segment 14 goes from point 5 to point 6 Segment 15 goes from
point 6 to point 4
ORISEG is not useful for segments 4 to 15. For segments 4 to 12 the principle is that the first
point is linear (1, 2 or 3) and the second is quadratic (4, 5 or 6). Note that in rectangular linear-
quadratic matrices, segments 13, 14 and 15 will not appear as they link only quadratic points.
This is why they have been put at the end, so that we have no gap in segment numbering for
rectangular matrices.
The total number of segments 4 to 6 is NSEG.
The total number of segments 7 to 9 is NSEG.
The total number of segments 10 to 11 is 3 NELEM
The total number of segments 13 to 15 is 3 NELEM
Quadratic boundary segments have also a local numbering. Point 1 and point 2 are defined as
in lilnear segments, point 3 is in the middle.
Linear prism:
Horizontal segments:
Segment 1 goes from point 1 to point 2 or from point 2 to point 1 (depending of ORISEG)
Segment 2 goes from point 2 to point 3 or from point 3 to point 2 (depending of ORISEG)
Segment 3 goes from point 3 to point 1 or from point 1 to point 3 (depending of ORISEG)
Segment 4 goes from point 4 to point 5 or from point 5 to point 4 (depending of ORISEG)
Segment 5 goes from point 5 to point 6 or from point 6 to point 5 (depending of ORISEG)
Segment 6 goes from point 6 to point 4 or from point 4 to point 6 (depending of ORISEG)
Vertical segments:
Segment 7 goes from point 1 to point 4 Segment 8 goes from point 2 to point 5 Segment 9 goes
from point 3 to point 6
Crossed segments (for their global numbering see subroutine STOSEG41):
Segment 10 goes from point 1 to point 5 Segment 11 goes from point 2 to point 4 Segment 12
goes from point 2 to point 6 Segment 13 goes from point 3 to point 5 Segment 14 goes from
point 3 to point 4 Segment 15 goes from point 1 to point 6
Figure 5.6: Isoparametric transformation (the numbers in the quadrilaterals indicate local num-
bering)
The image by T of each vertex of the reference element thus gives a vertex of the quadrilateral,
which, by identification, provides the coefficients t1, t2, ... of the transformation, as a function
of the coordinates x1,y1 x2,y2 x3,y3 x4,y4 of the vertices:
t1 = (+x1 + x2 + x3 + x4)/4
t2 = (−x1 + x2 + x3 − x4)/4
t3 = (−x1 − x2 + x3 + x4)/4
t4 = (+x1 − x2 + x3 − x4)/4
t10 = (+y1 + y2 + y3 + y4)/4
t20 = (−y1 + y2 + y3 − y4)/4
t30 = (−y1 − y2 + y3 + y4)/4
t40 = (+y1 − y2 + y3 − y4)/4
A base Ψ in the real element corresponds in the reference element to a polynomial P such that
Ψ(x, y) = T (P(ξ , η)).
In our case, there are 4 polynomials associated with the 4 bases of the real element:
P1(ξ , η) = (1 − ξ − η + ξ η)/4
P2(ξ , η) = (1 + ξ − η − ξ η)/4
P3(ξ , η) = (1 + ξ + η + ξ η)/4
P4(ξ , η) = (1 − ξ + η − ξ η)/4
As for the bases Φ, each polynomial has a value of 1 for one vertex of the element and 0 for the
others.
In the reference element, the integral being sought takes the value:
Z Z +1 Z +1
Ψi Ψ j dQ = Pi Pj |J| dξ dη
Q −1 −1
5.2 Construction of matrices 89
where J is the Jacobian of the transformation T , equal to the determinant of the Jacobian matrix:
∂x ∂x
∂ξ ∂η
∂y ∂y
∂ξ ∂η
Let:
J = (t2 + t4 η)(t30 + t40 ξ ) − (t20 + t40 η)(t2 + t4 ξ )
J is assumed to be positive, which is obtained with local numbering of the points which run
along the boundary of the element in the counter-clockwise sense. J is not constant (it is with
linear triangles).
Since J is a polynomial, then we have the integral of a polynomial (of which the term with the
highest degree is in ξ3 η3 ).
This information is sufficient for MAPLE V to successfully carry out the calculation. For
example, for this calculation of a mass matrix, the following can be obtained:
!FORMAL CALCULATION OF A Q1 MASS MATRIX :
MAT(1,1)=(X2*(2.*Y4+Y3)+X3*(Y4-Y2)+X4*(-Y3-2.*Y2))/36.
MAT(1,2)=(X2*(Y4+2.*Y3)+X3*(Y4-2.*Y2)-X4*(Y3+Y2))/72.
MAT(1,3)=(X2*Y3+X3*(Y4-Y2)-X4*Y3)/72.
MAT(1,4)=(X2*(Y4+Y3)+X3*(2.*Y4-Y2)+X4*(-2.*Y3-Y2))/72.
MAT(2,1)=(X2*(Y4+2.*Y3)+X3*(Y4-2.*Y2)-X4*(Y3+Y2))/72.
MAT(2,2)=(3.*X2*Y3+X3*(Y4-3.*Y2)-X4*Y3)/36.
MAT(2,3)=(X2*(-Y4+3.*Y3)+X3*(2.*Y4-3.*Y2)+X4*(-2.*Y3+Y2))/72.
MAT(2,4)=(X2*Y3+X3*(Y4-Y2)-X4*Y3)/72.
MAT(3,1)=(X2*Y3+X3*(Y4-Y2)-X4*Y3)/72.
MAT(3,2)=(X2*(-Y4+3.*Y3)+X3*(2.*Y4-3.*Y2)+X4*(-2.*Y3+Y2))/72.
MAT(3,3)=(X2*(-2.*Y4+3.*Y3)+3.*X3*(Y4-Y2)+X4*(-3.*Y3+2.*Y2 ))/36.
MAT(3,4)=(X2*(-Y4+2.*Y3)+X3*(3.*Y4-2.*Y2)+X4*(-3.*Y3+Y2))/72.
MAT(4,1)=(X2*(Y4+Y3)+X3*(2.*Y4-Y2)+X4*(-2.*Y3-Y2))/72.
MAT(4,2)=(X2*Y3+X3*(Y4-Y2)-X4*Y3)/72.
MAT(4,3)=(X2*(-Y4+2.*Y3)+X3*(3.*Y4-2.*Y2)+X4*(-3.*Y3+Y2))/ 72.
MAT(4,4)=(X2*Y3+X3*(3.*Y4-Y2)-3.*X4*Y3)/36.
On a vector computer, the previous FORTRAN expressions, integrated in a loop on the ele-
ments, are vectorised.
The above demonstration can also be conducted in the same way with any matrix which gives
the integral of a polynomial expression. This is the case of mass matrices, divergence type
matrices. For diffusion matrices, it is the case with linear triangles, not with quadrilaterals.
where the power indices denote the restrictions of the functions on the triangles in question.
The restrictions of the basis function of the Quasi-Bubble element to the sub-triangles are the
basis functions P1 on these sub-triangles. Calculation of each of the integrals I1, I2, and I3 is
thus obtained independently by the method described in a. The sum of these integrals must then
be determined. In addition, the intersection of the supports of the Quasi-Bubble basis functions
is only made rarely on the three sub-triangles and often on a single sub-triangle (off-diagonal
terms). This results in the deletion of one or two of the integrals I1, I2, and I3.
Figure 5.7: Support of quasi-bubble function Ψ1 (shaded) and local numbering within the sub-
triangles.
It can thus be observed that only the function Ψ4 has a support which coincides with the triangle
T.
e.g.: calculation of the term M1,1 :
we have:
M1,2 = m11,2
M1,3 = m32,1
M1,4 = m11,3 + m32,3
M2,1 = m12,1
M2,2 = m12,2 + m21,1
M2,3 = m21,2
M2,4 = m12,3 + m21,3
M3,1 = m31,2
M3,2 = m22,1
M3,3 = m22,2 + m31,1
M3,4 = m22,3 + m31,3
M4,1 = m13,1 + m33,2
M4,2 = m13,2 + m23,1
M4,3 = m23,2 + m33,1
M4,4 = m13,3 + m23,3 + m33,3
c - ϕ and Ψ are of different types:
The elementary matrices of this type are rectangular and include 12 terms. Here, we shall deal
with the case where ϕ is P1 and Ψ Quasi-Bubble; the symmetrical situation results directly
from this.
The following can still be written:
Unlike the situation encountered in b), the restrictions of the functions ϕ to the sub-triangles no
longer correspond to the base functions P1 on these sub-triangles. In fact, what we have is:
ϕi (Pj ) = σi j f or1 ≤ j ≤ 3
and:
1
ϕi (P4 ) = 3
• Diagonal preconditioning
The main algorithm is in fact the product of a matrix and a vector, as it will be seen that all the
others can be reduced to this, or at least be derived from it.
Then in the last section we shall detail the matrix-vector product when using an edge-based
storage.
NELEM
R= ∑ (PeWe )
e=1
Taking the example of the triangle P1, if the components of the vector WIELEM are designated
W1, W2, and W3 , then W1(IELEM) is the vector component at the node with local number 1
of element IELEM, etc.
In FORTRAN, R is defined as follows:
DO IELEM=1,NELEM
R(IKLE(IELEM,1)) = R(IKLE(IELEM,1)) + W1(IELEM)
R(IKLE(IELEM,2)) = R(IKLE(IELEM,2)) + W2(IELEM)
R(IKLE(IELEM,3)) = R(IKLE(IELEM,3)) + W3(IELEM)
ENDDO
94 Chapter 5. Internal structure of B IEF
where IKLE is the connectivity table: IKLE(IELEM,I) is the general number of the Ith local
node of element IELEM.
This loop can be vectorised, as will be seen below.
The assembly loop is, first of all, transformed into three successive loops:
!
DO IELEM=1,NELEM
R(IKLE(IELEM,1))=R(IKLE(IELEM,1))+W1(IELEM)
ENDDO
!
DO IELEM=1,NELEM
R(IKLE(IELEM,2))=R(IKLE(IELEM,2))+W2(IELEM)
ENDDO
!
DO IELEM=1,NELEM
R(IKLE(IELEM,3))=R(IKLE(IELEM,3))+W3(IELEM)
ENDDO
These three loops are not automatically vectorised on a vector computer. Indeed, the principle of
vectorisation is to work in real time on a number of elements of the loop. This number, referred
to as the vector length of the computer, varies from one supercomputer to another. It is 64 or
128 on a Cray YMP and up to 1024 on a Fujitsu. Taking the Cray as an example, a loop running
from 1 to NELEM will be processed in 64-element clusters. Thus, if loop 1 is vectorised on
a Cray computer, the instruction R(IKLE(IELEM,1))= R(IKLE(IELEM,1)) +W1(IELEM) will
be executed simultaneously for elements 1 to 64, 65 to 128 and so on. It is clear, therefore, that
the result can only be correct if each component of vector R is used only once in each cluster
of 64 elements, i.e., if there are not two elements IELEM1 and IELEM2 in the same cluster
such that IKLE(IELEM1,1)=IKLE(IELEM2,1). During compilation, the Cray will detect any
problem of backward dependency and not vectorise the loop.
It is, however, possible to force vectorisation, but in this case it is essential to ensure that the
grid does not contain any backward dependencies. This again shows the advantages of having
split the initial assembly loop into three, as otherwise the condition of non-dependency would
have been more severe and hence more difficult to achieve. It would have been necessary
for IKLE(IELEM1,I) – IKLE(IELEM2,J) for I,J = 1,2,3 for all different elements IELEM1,
IELEM2 contained in each 64-element batch.
With a split assembly loop on the Cray, backward dependencies occur if two different elements
IELEM1 and IELEM2 are such that:
IKLE(IELEM1,I) = IKLE(IELEM2,I)
On a Fujitsu computer or similar, 64 must be replaced by 1024. The set conditions for the grid
are thus more severe.
In order to vectorise the three loops, it is necessary to find a system of numbering the elements
that eliminates any backward dependencies. This leads to a paradoxical situation as such a
numbering system is impossible in theory yet easy to apply in practice. Indeed:
• heuristic algorithms easily find a large number of acceptable numbering systems if the
number of elements is sufficient (in practice sufficiently larger than the vector length, i.e.,
64 for a Cray).
!
DO IELEM=1,NELEM
R(IKLE(IELEM,1))=R(IKLE(IELEM,1))+W1(IELEM)
ENDDO
!
As vector assembly operations are used intensively in the algorithms, the overall amount of time
saved is also appreciable (up to a factor of 3).
The example of quadrilaterals Q1 is discussed below. The matrix M is stored in the form of two
arrays DM(NPOIN) and XM(NELEM,12).
The FORTRAN instructions are as follows:
Contribution of the diagonal: product of D and V (loop that can be expressed in vector form):
DO I=1,NPOIN
R(I) = DM(I) * V(I)
ENDDO
Contribution of off-diagonal terms: products Ee (Pet V ) stored in working arrays W1, W2, W3
and W4. This loop can also be expressed in vector form.
DO IELEM=1,NELEM
General numbers of points for the element (given by the array IKLE)
I1 = IKLE(IELEM,1)
I2 = IKLE(IELEM,2)
I3 = IKLE(IELEM,3)
I4 = IKLE(IELEM,4)
As far as the element is concerned, the results concerning points with different local numbers
are stored separately (for the number 1: W1, etc.)
ENDDO
The vector defined by W1, W2, W3 and W4 is assembled and then added to R, which already
contains the contribution of the diagonal.
This algorithm is very easy to explain. Taking as an example the term XM(IELEM,1), this
is conventionally the term MAT(1,2) for element IELEM. It is thus a part of the coefficient
of point 2 of element IELEM in the equation for point 1 of the same element. The product
XM(IELEM,1)*V(I2) must therefore be added to the result R(I1). This is what happens in loop
2 and the assembly loop via working array W1.
To summarise the method, it may be said that the vectors, and no longer the matrices, are
assembled. In a method involving classical compacting, vectorisation of the product matrix x
vector is broken by an internal loop on the surrounding points.
+ XM(IELEM,11) * V(I4)
It can be seen from the last two examples above that problems of symmetry and transposition
are simply questions of how information is written for non-assembled storage.
DO IELEM=1,NELEM
I1 = IKLE(IELEM,1)
I2 = IKLE(IELEM,2)
I3 = IKLE(IELEM,3)
I4 = IKLE(IELEM,4)
!
XM(IELEM, 1) = XM(IELEM, 1) * V(I2) * V(I1)
XM(IELEM, 2) = XM(IELEM, 2) * V(I3) * V(I1)
XM(IELEM, 3) = XM(IELEM, 3) * V(I4) * V(I1)
XM(IELEM, 7) = XM(IELEM, 7) * V(I1) * V(I2)
XM(IELEM, 4) = XM(IELEM, 4) * V(I3) * V(I2)
XM(IELEM, 5) = XM(IELEM, 5) * V(I4) * V(I2)
XM(IELEM, 8) = XM(IELEM, 8) * V(I1) * V(I3)
XM(IELEM,10) = XM(IELEM,10) * V(I2) * V(I3)
XM(IELEM, 6) = XM(IELEM, 6) * V(I4) * V(I3)
XM(IELEM, 9) = XM(IELEM, 9) * V(I1) * V(I4)
XM(IELEM,11) = XM(IELEM,11) * V(I2) * V(I4)
XM(IELEM,12) = XM(IELEM,12) * V(I3) * V(I4)
ENDDO
In a non-assembled matrix, the row and column for each Dirichlet-type point are thus cancelled,
with the exception of the diagonal terms.
As there is a special array for the matrix diagonal, it is then easy to replace an element on this
5.3 Matrix operations: 99
diagonal by 1 whenever the point in question is of Dirichlet type. Similarly, the set of values
must then be placed in the second members of the linear system.
!
DO 1 IELEM = 1 , NELEM
!
I1 = IKLE(IELEM,1)
I2 = IKLE(IELEM,2)
I3 = IKLE(IELEM,3)
I4 = IKLE(IELEM,4)
!
XM(IELEM, 1) = XM(IELEM, 1) * D(I1)
XM(IELEM, 2) = XM(IELEM, 2) * D(I1)
XM(IELEM, 3) = XM(IELEM, 3) * D(I1)
!
XM(IELEM, 4) = XM(IELEM, 4) * D(I2)
XM(IELEM, 5) = XM(IELEM, 5) * D(I2)
XM(IELEM, 6) = XM(IELEM, 6) * D(I3)
!
XM(IELEM, 7) = XM(IELEM, 7) * D(I2)
XM(IELEM, 8) = XM(IELEM, 8) * D(I3)
XM(IELEM, 9) = XM(IELEM, 9) * D(I4)
!
XM(IELEM,10) = XM(IELEM,10) * D(I3)
XM(IELEM,11) = XM(IELEM,11) * D(I4)
XM(IELEM,12) = XM(IELEM,12) * D(I4)
!
ENDDO
!
The formula for the assembled matrices would be DM(m,n) = D(m) x M(m,n). With XM(IELEM,1)
representing for example part of the term M(I1,I2), it is therefore logically multiplied by D(I1).
For the product MD, it will be multiplied by D(I2):
Product MD:
DO IELEM = 1 , NELEM
!
I1 = IKLE(IELEM,1)
I2 = IKLE(IELEM,2)
I3 = IKLE(IELEM,3)
I4 = IKLE(IELEM,4)
!
100 Chapter 5. Internal structure of B IEF
DO ISEG=1,NSEG
X(GLOSEG(ISEG,1))=
X(GLOSEG(ISEG,1))+XA1(ISEG)*Y(GLOSEG(ISEG,2))
!
X(GLOSEG(ISEG,2))=
X(GLOSEG(ISEG,2))+XA2(ISEG)*Y(GLOSEG(ISEG,1))
ENDDO
For rectangular matrices, all the values of X are not initialised by the diagonal terms, so some
terms in X have to be previously set to 0.
0 or 1 no preconditioning
3 block-diagonal preconditioning
7 Crout preconditioning
The integer METHOD(2) designates an option or alternative of the selected solver. At present,
this is only used for the GMRES method and designates the dimension of the Krylov sub-space.
The various solvers and preconditioning operations will now be described in succession.
X 1 = X 0 − ρ 0d0
Iterations:
rm = rm−1 − ρ m−1 Ad m−1
solution of Cgm = rm
(rm ,gm )
d m = gm + (rm−1 ,gm−1 )
d m−1
(rm ,d m )
ρm = (d m ,Ad m )
X m+1 = X m − ρ m d m
X 1 = X 0 − ρ 0d0
Iterations:
rm = rm−1 − ρ m−1 Ad m−1
gm = gm−1 − ρ m−1 d 0m−1
(Agm ,d 0m−1 ) m−1
d m = gm − (Ad m−1 ,d 0m−1 ) d
m
(Ag ,d 0m−1 )
Ad m = Agm − (Ad m−1 ,d 0m−1 ) Ad
m−1
solution of Cd 0m = Ad m
(Ad m ,gm )
ρ m = (Ad m ,d 0m )
X m+1 = X m − ρ m d m
X 1 = X 0 − ρ 0d0
Iterations:
rm = rm−1 − ρ m−1 Ad m−1
gm = gm−1 − ρ m−1 d 0m−1
solution of t Cg0m = gm
5.4 Solvers and preconditioning operations 103
t 0m t
( Ag , Ag ) 00m
d m =t Ag0m + (t Ag 0m−1 ,t Ag0m−1 ) d
m−1
solution of Cd 0m = Ad m
t 0m ,t Ag0m )
ρ m = ( Ag
(d 0m ,d 0m )
X m+1 = X m − ρ m d m
(gm ,gm )
ρm = (d m ,d m )
X m+1 = X m − ρ m d m
h = k − ρ m Apm
m m
X m+1 = X m − ρ m (hm + km )
gm+1 = gm − ρ m A(hm + km )
(gm+1 ,g0 )
βm = (gm ,g0 )
ρ m+1 = gm+1 + 2β m hm + (β m )2 pm
km+1 = gm+1 + β m .hm
The stop test is the same for all the methods. Iterations continue until EPSI precision specified
by the user is reached after the test:
kA.X m+1 −Bk
kBk ≤ EPSI if kBk ≥ 1.(relative precision)
or
kA.X m+1 − Bk ≤ EPSI if kBk < 1.(relative precision)
2. If A is a diagonal, the Krylov space will degenerate and the method will fail.
M11 M12 X B
M= , X = 1 andB 1
M21 M22 X2 B2
D11 , D12 , D21 , and D22 will be used to designate the respective diagonals of M11 , M12 , M21 , and
M22 .
5.4 Solvers and preconditioning operations 105
D11 D12
The basic idea is to obtain an approximate solution for M using the matrix: M̃ =
D21 D22
√ √
and an LDU decomposition of in the form L D DU. The initial system MX=B is thus changed
√ −1 √ −1 √ √ −1
into: L D M DU DUX = L D B
By expansion, this√ system can also be written as:
√1 L−1 MU −1 √1 DUX = √1D L−1
D D
In this form, the system appears as a diagonal preconditioning of the system AX’ = B’, with a
given preconditioning diagonal D and assuming:
A = L−1 MU −1
X 0 = UX
B0 = L−1 B
Having solved the system, the unknown X can be obtained by the formula X = U −1 X 0 .
The following operations must therefore be carried out in sequence:
D11 D12
1. Calculation of L, D and U by LDU decomposition of M̃ =
D21 D22
2. Calculation of A, X’ and B’
D11 D12
1. LDU decomposition of M̃ =
D21 D22
2. Calculation of A, X’ and B’
The following formulae are used:
−1
I 0 I 0
=
D21 I −D21 I
and:
−1
I D12 I −D12
=
0 I 0 I
I 0 M11 M12 M11 M12
The product is equal to
−D21 I M21 M22 M21 − D21 M11 M22 − D21 M12
As for LDU decomposition, A will be calculated "in situ" by using M.
The following operations are therefore performed first of all:
M21 = M21 − D21 M11 and M22 = M22 − D21 M12
Right-hand multiplication by U −1 is then done by the following operations:
M12 = M12 − M11U12 and M22 = M22 − M21U12
On completion of these operations, the matrix A takes the place of M.
X’ is also calculated in situ by the operation: X1 = X1 + D12 X2 (X2 remains unchanged).
B’ is calculated by the operation: B2 = B2 − D21 B1 (B1 remains unchanged).
4. Calculation of X
This is done by the single operation: X1 = X1 − D12 X2 (X2 remains unchanged).
2. Calculation of A, X’ and B’
2. Calculation of A, X’ and B’
The following formulae are used:
−1
I 0 0 I 0 0 I 0 0
D21 I 0 = 0 I 0 −D21 I 0
D31 D32 I −D31 −D32 I 0 0 I
and
−1
I D12 D13 I −D12 0 I 0 −D13
0 I D23 = 0 I 0 0 I −D23
0 0 I 0 0 I 0 0 I
These two breakdown operations are used to calculate A, bearing in mind that M is multi-
plied on the left by the lower part and on the right by the upper part. In situ modifications
are made to the matrix:
Left-hand multiplication is done by means of the following operations:
M21 is replaced by M21 − D21 M11
M22 is replaced by M22 − D21 M12
M23 is replaced by M23 − D21 M13
M31 is replaced by M31 − D31 M11 − D32 M21
M32 is replaced by M32 − D31 M12 − D32 M22
M33 is replaced by M33 − D31 M13 − D32 M23
Right-hand multiplication is done by means of the following operations:
M12 is replaced by M12 − M11 D12
M22 is replaced by M22 − M21 D12
108 Chapter 5. Internal structure of B IEF
3. Calculation of X
This is done by the operations:
X3 remains unchanged.
X2 = X2 − D23 X3
X1 = X1 − D12 X2 − D13 X3
5.4.4 LU preconditioning
Two matrices L and U (lower and upper) are chosen so that the product LU is close to A. The
choice of L and U of course determines the efficiency of preconditioning and examples will
be given in the following sections. For the moment, L and U will be assumed to have known
values.
In place of the system M X = B, the following equivalent system is solved:
L−1 MU −1UX = L−1 B
This produces:
a new matrix: M 0 = L−1 MU −1
a new unknown vector: X 0 = UX
a new second member: B0 = L−1 B
After solving this system, X is obtained by the formula X = U −1 X 0
When M is symmetrical, it is preferable to choose an LU breakdown in which L and U are
each transposed from the other. In the case of LU = Lt L iterative methods such as that of the
conjugate gradient (see Solvers may be adapted to produce only one inversion by (Lt L)−1 . See
J.-M. [2] on this subject.
• If j=1,n then:
– If i=1,j then:
βi j = ai j − ∑i−1
k=1 αik βk j (if i=1, the summation is 0)
• and
– If i=j+1,n then:
j−1
αi j = β1j j (ai j − ∑k=1 αik βk j ) (if i=1, the summation is 0)
!---------------------------------------------------------------------
! LOOP WITH FORCED VECTORISATION
!---------------------------------------------------------------------
!
!DIR$ IVDEP
DO 10 IELEM = 1 , NELEM
DN(IKLE(IELEM,2)) = DN(IKLE(IELEM,2)) * W2(IELEM)
10 CONTINUE
!
!DIR$ IVDEP
DO 20 IELEM = 1 , NELEM
DN(IKLE(IELEM,3)) = DN(IKLE(IELEM,3)) * W3(IELEM)
20 CONTINUE
!
The loop appearing in the multiplying assembly may be vectorised for the same reasons as in a
conventional assembly. The vector DN is then inverted, as N −1 is the point of interest.
!
! DN INVERSION
!
CALL OV( ’X=1/Y ’ , DN , DN , Z , C , NPOIN )
Inversion of system N.X = B
!-----------------------------------------------------------------------
!
! INITIALISATION: X = RIGHT HAND SIDE
!
CALL OV( ’X=Y ’ , X , B , Z , C , NPOIN )
!
!-----------------------------------------------------------------------
!
! SERIE OF LOWER TRIANGULAR MATRICES INVERSION
!
!DIR$ IVDEP
DO IELEM = 1 , NELEM
!
X(IKLE(IELEM,2)) = (X(IKLE(IELEM,2))
& - XN(IELEM,4) * X(IKLE(IELEM,1)) )
!
X(IKLE(IELEM,3)) = ( X(IKLE(IELEM,3))
& - XN(IELEM,5) * X(IKLE(IELEM,1))
& - XN(IELEM,6) * X(IKLE(IELEM,2)) )
!
30 CONTINUE
!
! MULTIPLICATION BY DN (ALREADY INVERTED)
CALL OV( ’X=XY ’ , X , DN , Z , C , NPOIN )
!
! SERIE OF UPPER TRIANGULAR MATRICES INVERSION
!
!DIR$ IVDEP
112 Chapter 5. Internal structure of B IEF
DO IELEM = NELEM , 1 , -1
!
X(IKLE(IELEM,2)) = ( X(IKLE(IELEM,2))
& - XN(IELEM,3) * X(IKLE(IELEM,3)) )
!
X(IKLE(IELEM,1)) = ( X(IKLE(IELEM,1))
& - XN(IELEM,1) * X(IKLE(IELEM,2))
& - XN(IELEM,2) * X(IKLE(IELEM,3)),)
!
ENDDO
!
!-----------------------------------------------------------------------
!
Loops 1 and 2 cannot normally be vectorised, even with the precautions taken to vectorise the
vector assembly. Indeed, this would require IKLE(IELEM1,I) 6= IKLE(IELEM2,J) for I,J =
1,2,3 for all different elements IELEM1, IELEM2 taken in a cluster of, e.g., 64 elements , and
this condition is only achieved for I=J in the grids used here. Nevertheless, forced vectorisation
may be considered. The result obtained in this way will certainly not be a solution of N.X = B,
but it should not be forgotten that the aim of constructing N was to obtain an approximation of
M, i.e., an approximate solution of M.X = B. It is therefore quite acceptable to take the result
of forced vectorisation for this purpose. In any case, as will be seen below, there is a stop
test at the end of any iterative method, ensuring that a good solution has been obtained. Tests
show that Crout’s preconditioner is particularly effective when it can be applied. For diffusion
matrices, the computation cost can be reduced by 50% in spite of the time spent in constructing
the preconditioner.
In [5] and [6], we analyse and obtain the numerical reproducibility of gouttedo and Nice, two
test cases of the modules T ELEMAC -2D and T OMAWAC, by using the compensation techniques.
To obtain a full reproducibility, i.e. in all openTelemac modules, these techniques have to be
integrated in other computations that differ between the sequential execution and the parallel
one. To facilitate such a task, this chapter aims to be a useful technical document. We start
describing in Section 6.1 the methodology to track the computation of the concerned problem.
This process aims to identify the sources which produce the non-reproducibility. Then, we detail
the modifications introduced in the code. As already mentioned, openTelemac relies on its finite
element library BIEF. This one includes many Fortran 90 subroutines which provide the data
structure, the building and the solving phases of the simulation. Almost all our modifications
have been restricted to these library subroutines. We describe four types of modification: data
structure, algebraic operations, building phase and solving phase. We exhibit and explain the
modified parts highlighting them and commenting on them in the listings proposed along the
chapter.
The users choose between the original computation or a reproducible one, in the test case file
(where all the parameters of the simulation are defined) via the keyword "FINITE ELEMENT
ASSEMBLY" (or "ASSEMBLAGE EN ELEMENTS FINIS" in French). It corresponds to
the Fortran variable MODASS that takes the values 1,2 and 3 respectively for the original, the
integer and the compensated mode. In this chapter we only consider the implementation of the
compensated computation.
6.1 Methodology
We describe how to identify the source of non-reproducibility in a computation sequence. The
strategy is to observe the components of the linear system as the computation is progressing.
For that, we introduce the subroutine glob_vec to observe the reproducibility of a concerned
vector after each computation, see Listing 6.1. This process allows us to detect if a computation
is reproducible or not.
In a parallel simulation, the vectors are distributed over the subdomains where each node has
a local and a global number. In order to compare the component values when the subdomain
number differs, we need to rebuild the global vector, i.e. for the whole domain. For that we
use the structure KNOLG which maps the local number of a component to the global one. This
treatment is realized in lines from 18 to 29.
As detailed in [5] and [6], reproducibility can be observed only after the interface point assem-
114 Chapter 6. How to implement reproducibility in openTelemac
bly (and the compensation), because the interface points are different for one decomposition to
another.
For that, in our observation we identify if the interface point assembly has been already per-
formed in lines 8 and 10 of Listing 6.1. If it is not the case, we call the assembly processing
parcom or parcom_comp, corresponding to the computation mode. (we note that the test are
realized on a copy of the component, line 4). In the compensated mode (MODASS=3), the se-
quential and the parallel cases both benefit from the compensation, lines 44 and 12 respectively
.
ENDIF
OPEN(UNIT=99,FILE=’./’//X%NAME//’VEC_GLOBAL.TXT’)
WRITE(99,*) X%NAME,", NB POINTS:",NPOIN
DO I=1,NPOIN
WRITE(99,*) MESH%T%R(I)
CALL FLUSH(99)
END DO
CLOSE(99)
END IF
In [6], we explain how the rounding errors V%E must be updated for each algebraic operation on
V%R. Every operation on a block or a vector is called by the subroutine os, which only verifies
the structure before calling the subroutine ov. This latter computes the required operation op
on the passed vectors X%R, Y%R, Z%R, for instance it computes X%R = Y%R + Z%R.
In the compensated mode, the new subroutine ov_comp is called, and the passed vectors are
associated with their own error vectors X%E, Y%E, Z%E, to also update them. Listing 6.3 illus-
trates the modified vector add and the Hadamard product, for instance.
All these operations are also applied to the diagonal and the extra-diagonal terms of the EBE ma-
trix structure, respectively stored as vectors in M%D and M%X. The difference is in the sequence
of the calls, which begin by the subroutine om for matrix instead of os for other structures.
In om, the storage and the type of the element are verified to call the subroutine om1111 for
triangular elements and EBE storage. In this subroutine, several tests are verified to then pass
the corresponding component vector of the matrix to the subroutines ov or ov_comp. In the
compensated version, the only modification in om and om1111 is at the subroutine parameter
level to pass the error vectors.
6.4 Modifications in the building phase 117
os om
operations on structure operations on matrix
Triangular
OD
+ EBE
MODASS
AS
S=
3
=1
om1111
= 1
SS
MODASS = 3
DA
MO
ov ov_comp
operations on vectors operations on vectors and their errors
Listing 6.4: The call of the FE assembly under the two modes of the computation in vectos
! Note: VEC is a reference to SVEC%R
IF(MODASS.EQ.1) THEN
CALL ASSVEC(VEC, IKLE, NPT ,NELEM,NELMAX,IELM1,
& T,INIT,LV,MSK,MASKEL,NDP)
ELSEIF(MODASS.EQ.3 ) THEN
CALL ASSVEC(VEC, IKLE, NPT ,NELEM,NELMAX,IELM1,
& T,INIT,LV,MSK,MASKEL,NDP,SVEC%E)
ENDIF
! Implicit modification in PARCOM
IF(ASSPAR) CALL PARCOM(SVEC,2,MESH)
IF(ASSPAR.AND.MODASS.EQ.3) THEN
! The compensation of all the values
DO I = 1 , MESH%NPOIN
VEC(I)= VEC(I)+SVEC%E(I)
ENDDO
ENDIF
1. vectos calls the subroutine assvec that computes the finite element assembly process
corresponding to the computation mode, from line 2 to 8. In the original mode, only the
vector VEC is passed into the assvec call, while in the compensated mode, we also pass
the vector of errors SVEC%E.
IF (MODASS.EQ.1)
& X(IKLE(IELEM,IDP)=X(IKLE(IELEM,IDP)+W(IELEM,IDP)
ELSEIF (MODASS.EQ.3) THEN
CALL 2SUM(X(IKLE(IELEM,IDP)),
& W(IELEM,IDP),X(IKLE(IELEM,IDP)),ERROR)
ERRX(IKLE(IELEM,IDP))=ERRX(IKLE(IELEM,IDP))+ERROR
ENDIF
ENDDO
ENDDO
As shown in Listing 6.5, only the vector VEC is assembled in the original computation
(line 5). In the compensated mode, VEC is assembled by the subroutine 2sum (lines 7
and 8) that also computes the rounding error ERROR for each node IKLE(IELEM,IDP).
The vector SVEC%E accumulates the generated errors ERROR of each node.
2. The second implicit modification in Listing 6.4 (line 10) is the interface node assembly
that is launched by the subroutine parcom. This later calls parcom2, which then calls
paraco twice in the original mode. We recall that the first call is to assemble the sub-
domain contributions and the second is to recover the solution of continuity between the
subdomains by sharing their maximum value (this choice is justified by physical reasons
in [1]).
In the compensated mode, parcom2_comp and paraco_comp replace parcom2 and
paraco, respectively.
The modifications of parcom_comp are the addition of the error component parameter
and the suppression of the second call of paraco which is no more need because our
corrections recover the solution of continuity between the subdomains.
The main modifications occur in paraco_comp and are presented in Listing 6.6. The
Fortran subroutines p_iread, p_iwrit and p_wait_paraco call respectively the
MPI operations: mpi_irecv, mpi_isend and
mpi_waitall. The communication corresponds to a non-blocking receive with a
blocking send. The BIEF_MESH structures, BUF_RECV and BUF_SEND, are declared
in bief_def to receive and send the exchanged data between the subdomains. The as-
sembly of the subdomain contributions is a simple accumulation of these received data,
see Listing 6.6 (line 38).
In the compensated computation, two new structures BUF_RECV_ERR and BUF_SEND_ERR
are added to also exchange the computed errors. Here the assembly is realised with the
2sum subroutine that computes the rounding error ERROR1 of the data accumulation
(line 40) and ERROR2 for the error accumulation (line 42). These two values are added
with the error contributions in each iteration (line 44).
IKA = NB_NEIGHB_PT(IL)
IPA = LIST_SEND(IL)
! Initializes the communication arrays
K = 1
DO J=1,NPLAN
DO I=1,IKA
II=NH_COM(I,IL)
BUF_SEND(K,IL) =V1(II,J)
BUF_SEND_ERR(K,IL) =ERRX(II)
K=K+1
ENDDO
ENDDO
CALL P_IWRIT(BUF_SEND(1,IL),IAN*IKA*NPLAN*8,
& IPA,PARACO_MSG_TAG,SEND_REQ(IL))
CALL P_IWRIT(BUF_SEND_ERR(1,IL),IAN*IKA*NPLAN*8,
& IPA,PARACO_MSG_TAG,SEND_REQ(IL))
ENDDO
! Wait received messages
DO IL=1,NB_NEIGHB
IKA = NB_NEIGHB_PT(IL)
IPA = LIST_SEND(IL)
CALL P_WAIT_PARACO(RECV_REQ(IL),1)
K=1
DO J=1,NPLAN
DO I=1,IKA
II=NH_COM(I,IL)
! Original version: V1(II,J)=V1(II,J)+ BUF_RECV(K,IL)
CALL 2SUM(V1(II,J),BUF_RECV(K,IL)
& ,V1(II,J),ERROR1)
CALL 2SUM(ERRV(II),BUF_RECV_ERR(K,IL)
& ,ERRV(II),ERROR2)
ERROR=ERROR1+ERROR2
ERRV(II)=ERRV(II)+ERROR
K=K+1
ENDDO
ENDDO
ENDDO
3. The latest modification in Listing 6.4, from lines 11 to 16, is the compensation after the
interface point assembly. As detailed in [6], we have to compensate the accumulated
errors to the data. After this step this vector becomes reproducible.
Note 3. This procedure is applied to every vector and EBE matrix. The diagonal M%D%R is a
vector and its accompanying vector error term M%D%E is calculated in a similar way.
Note 4. For the studied gouttedo test case, the other calls of parcom are in the subroutines
propag, masbas2d, matrbl. In the compensation mode, these subroutines apply
the previously modifications (items 2 and 3).
DO I = 1 , NPOIN
P_DOT = P_DOT+X%R(I)*Y%R(I)*IFAC(I)
END DO
where IFAC is the weight used to avoid computing several times the interface nodes. These
partial contributions are summed over all the subdomains to compute the global dot product by
the MPI dynamic reduction in p_dsum.
In the compensated mode, a twice more accurate scalar product is computed. In sequential,
function dot_comp computes such accurate sequential dot product. It accumulates both the
dot product and the generated rounding errors (addition and multiplication) and finally compen-
sates them together.
Note: in Fortran the name of the function is the output of this function.
Listing 6.8: The sequential Dot2 in the subroutine DOT_COMP
6.5 Modifications in the solving phase 121
CALL 2PROD(X(1),Y(1),P,EP)
DO I = 2 , NPOIN
CALL 2PROD(X(I),Y(I),PP,EPP)
CALL 2SUM(P,PP,P,E)
EP=EP+(E+EPP)
END DO
DOT_COMP = P+EP
In the parallel implementation, each subdomain computes its local scalar product and the cor-
responding generated rounding errors, to return a pair [data, error] in subroutine p_dotpair.
Listing 6.11: EBE matrix-vector product: the multiplication of the extra-diagonal elementary
terms and the diagonal terms of the matrix with the corresponding elements of the vector in
mv0303.
! Here Y refers to V%R, DA refers to M%D%R and XA refers to M%X
!Contribution of extra-diagonal terms XA * Y
DO IELEM = 1 , NELEM
W1(IELEM) = XA12(IELEM) * Y(IKLE2(IELEM))
& + XA13(IELEM) * Y(IKLE3(IELEM))
122 Chapter 6. How to implement reproducibility in openTelemac
6.6 Conclusion
In this chapter we detail, with a technical point of view, the modifications we introduced in open-
Telemac to recover the reproducibility of the studied test cases. The first difficulty in this work
was to define and to apply the methodology detailed in Section 6.1 to such a huge code. The sec-
ond difficulty was to identify the sources of non-reproducibility, i.e. where the rounding errors
differ between the sequential and the parallel simulations, and to distinguish their implementa-
tions in (again) this huge code. It was inevitable to manipulate three openTelemac components:
the BIEF library, the parallel library and Telemac-2D module which include respectively 493,
46 and 192 subroutines. The modifications to obtain reproducibility were restricted to about 30
subroutines, mostly in BIEF. We list these modified subroutines at the end of this section.
The first source is the non-deterministic error propagation at the interfaces nodes. We recall
again that this step is implicitly present in several parts of the computation (building and solv-
ing phases). It is sufficient to store and propagate these errors and finally to compensate them
into the computed value after every step of interface node assembly. These corrections are ap-
plied for both the parallel and the sequential simulations to yield the expected reproducibility
between the two execution modes. The second source is the dynamic reduction of the paral-
lel implementation of the dot product in the conjugate gradient iterations. It is corrected by
implementing a dot product that computes about twice the working precision. Here it yields
reproducible results whereas this is not true for very ill-conditioned ones. In this latter case,
more compensated steps can be applied for instance.
We think that these details are important to the continuity of this work. Of course, that this
chapter necessitates a little knowing of openTelemac code. The integration of our modifications
is still in progress and it is expected that this will be available in the next distributed version of
openTelemac. One integration difficulty is that the code was changed, in the meantime of this
work, which requires a careful merge between all these modifications.
vectos.
• Added: ov_comp, dot_comp, p_dot_comp, parcom_comp, parcom2_comp,
paraco_comp,twosum, twoprod.
Parallel library.
• Modified: interface_parallel.
• Added: p_dsum_err.
Telemac-2D module.
Greetings fellow developers of the T ELEMAC -M ASCARET SYSTEM and welcome into the
world of a T ELEMAC -M ASCARET SYSTEM developer. It might be hard at the beginning but
with time you will unravel all of the T ELEMAC -M ASCARET SYSTEM dirty little secrets. The
purpose of this guide is to describe all the steps you may encounter when developing in the
T ELEMAC -M ASCARET SYSTEM. Those steps can be found in the “T ELEMAC -M ASCARET
SYSTEM Software Quality Plan” (Eureka H-P74-2014-02365-EN). They are resumed in Fig
7.1.
Development
1. GitLab issue
2. CHs
3. Discussion
4. Implementation
6. Documentation
no
7. Integration
yes
Full validation
The following sections will describes how to use GitLab, the Git-based integrated platform used
to handle the T ELEMAC -M ASCARET SYSTEM source code as well as the issues and merge
requests, which is available at:
https://gitlab.pam-retd.fr/otm/telemac-mascaret
• Your name
• The T ELEMAC -M ASCARET SYSTEM modules that you will work on.
You will then receive an e-mail to setup your account. More information on this can be found
in the “Git Guide” of the T ELEMAC -M ASCARET SYSTEM.
8. The T ELEMAC -M ASCARET SYSTEM Cod-
ing Conventions
! ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
SUBROUTINE METEO
! ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
!
&(PATMOS, WINDX, WINDY, FUAIR , FVAIR , X, Y, AT , LT , NPOIN , VENT, ATMOS,
& HN, TRA01 , GRAV, ROEAU, NORD, PRIVE )
!
!∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
! TELEMAC2D V6P2 27/07/2012
!∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
!
! brief COMPUTES ATMOSPHERIC PRESSURE AND WIND VELOCITY FIELDS
!+ ( IN GENERAL FROM INPUT DATA FILES ) .
!
! w a r n i n g MUST BE ADAPTED BY USER
!
! h i s t o r y J−M HERVOUET (LNHE)
!+ 02/01/2004
!+ V5P4
!+
!
8.2 Subroutine header 127
! LOCAL DECLARATIONS
!
DOUBLE PRECISION P0 , Z ( 1 )
!
• A file must contain only one program/module/subroutine/function and must have the
same name as that program/module/subroutine/function,
• The extension of the file should be “.f”, or “.F” if it contains preprocessing to control
access to an external library. This is the case for the files of the parallel module.
• All subroutines and functions must conform to the subroutine header given in the previous
paragraph,
• All subroutines and functions must be protected by an IMPLICIT NONE statement. Their
arguments types must be given with their INTENT,
• The order in declarations is free except than some compilers will not accept that an array
has a dimension that has not been declared before, hence:
INTEGER , INTENT ( IN ) : : N
DOUBLE PRECISION , INTENT ( INOUT ) : : DEPTH(N)
is correct and:
DOUBLE PRECISION , INTENT ( INOUT ) : : DEPTH(N)
INTEGER , INTENT ( IN ) : : N
is not correct.
• Error messages: they must be given in French and English, using logical unit LU taken
in COMMON block INFO. LNG = 1 is French, LNG = 2 is English. Parameterising the
listing logical unit is necessary because it is not always 6 in parallel, as the listing of slave
processors does not appear on the screen but is redirected to files.
• Lines must be limited to a size of 72 characters, and only in UPPERCASE. Spaces must
be only one blank, for example, between a CALL and the name of a subroutine. This is
to facilitate research of character string in source code,
• Tabs for indenting are forbidden. The reason is that depending on compilers they repre-
sent a random number of blanks (6, 8, etc.) and that it is not standard Fortran,
• Names of variables: a name of variable should not be that of an intrinsic function, e.g.
do not choose names like MIN, MAX, MOD, etc., though possible in theory this may
create conflicts in some compilers, for example the future Automatic Differentiation Nag
compiler.
8.4 Defensive programming 129
• Functions: intrinsic functions must be declared as such. Use only the generic form of
intrinsic functions, e.g., MAX(1.D0,2.D0) and not DMAX(1.D0,2.D0). It is actually the
generic function MAX that will call the function DMAX in view of your arguments, you
are not supposed to do the job of the compiler.
I F ( OPT . EQ . 1 ) THEN
! here option 1 i s applied
ELSEIF ( OPT . EQ . 2 ) THEN
! here option 2 i s applied
ELSE
! h e r e s o m e t h i n g wrong happened , i t i s d a n g e r o u s t o go f u r t h e r , we s t o p .
I F (LNG . EQ . 1 ) THEN
WRITE ( LU , ∗ ) ’OPT= ’ ,OPT , ’ OPTION INCONNUE DANS LE SOUS−PROGRAMME . . . ’
ENDIF
I F (LNG . EQ . 2 ) THEN
WRITE ( LU , ∗ ) ’OPT= ’ ,OPT , ’ I S AN UNKNOWN OPTION IN SUBROUTINE . . . ’
ENDIF
CALL PLANTE ( 1 )
STOP
ENDIF
A moderate use of modules is thus prescribed (though a number of inner subroutines in BIEF
would deserve inclusion in modules).
8.8 Optimisation
Optimisation is a key point, a badly written subroutine may spoil the efficiency of the whole
program. Optimisation is a science and even an art, but it can be interesting to have a few ideas
or tricks in mind. Here are a few examples:
Example 1: powers
The following loop:
DO I =1 ,NPOIN
X( I ) =Y( I ) ∗ ∗ 2 . D0
ENDDO
is a stupid thing to do and should be replaced by:
DO I =1 ,NPOIN
X( I ) =Y( I ) ∗ ∗ 2
ENDDO
As a matter of fact, Y (I)∗∗2 is a single multiplication, Y (I)∗∗2.D0 is an exponential (exp(2.D0∗
Log(Y ))), it costs a lot, and moreover will crash if Y (I) negative.
Example 2: intensive loops with useless tests
Case 1: the following loop
DO I =1 ,NPOIN
I F ( OPTION . EQ . 1 ) THEN
X( I ) =Y( I ) + 2 . D0
ELSE
X( I ) =Y( I ) +Z ( I )
ENDIF
ENDDO
Should be replaced by:
I F ( OPTION . EQ . 1 ) THEN
DO I =1 ,NPOIN
X( I ) =Y( I ) + 2 . D0
ENDDO
ELSE
DO I =1 ,NPOIN
X( I ) =Y( I ) +Z ( I )
ENDDO
ENDIF
8.9 Parallelism and tidal flats 131
In the first case, the test of OPT ION is done NPOIN times, in the latter it is done once.
Case 2: the following loop
DO I =1 ,NPOIN
I F ( Z ( I ) . NE . 0 . D0 ) X( I ) =X( I ) +Z ( I )
ENDDO
seems a good idea to avoid doing useless additions, but forces a lot of tests and actually spoils
computer time, prefer:
DO I =1 ,NPOIN
X( I ) =X( I ) +Z ( I )
ENDDO
Example 3: strides
Declaring an array as XM(NELEM, 30) or XM(30, NELEM) for storing 30 values per element
is not innocent with respect to optimisation. The principle of Fortran is that in memory the first
index varies first. If you want to sum values number 15 of all elements, the first declaration is
more appropriate. If you want to sum the 30 values of element 1200 the second declaration is
more appropriate. The principle is that the values that are summed should be side by side in the
memory.
DO I =1 ,NPOIN
T2%R ( I ) = (QU%R ( I ) ∗ ∗ 2 +QV%R ( I ) ∗ ∗ 2 ) /HN%R ( I ) ∗ ∗ 2
ENDDO
To be added to the output variables the variable must validate the following points:
• Add the variable in the dictionary for the keywords for graphical and listing outputes.
Add them in both CHOIX and CHOIX1. Also do not forget to add them in AIDE and
AIDE1 as well. The short name of the variable must not exceed 8 characters. The short
name must also be the name of the bief_obj containing the variable.
• Add the variable to the bief_obj varsor (in T ELEMAC -3D varsor is for 2d output varso3
is for 3d output) in point_telemac2d.f.
• Add the variable names and unit in TEXT and TEXTPR in nomvar_telemac2d.f.
Also fill the mnemo with the short name you used in the ditionary. Increase the variable
NVAR_T2D.
9. Hermes
9.1 Description
The aim of this module is to produce generic functions to read/write meshes, data and boundary
conditions in T ELEMAC -M ASCARET SYSTEM regardless of the file format. For that purpose a
new module, called Hermes, was created.
• SELAFIN, T ELEMAC -M ASCARET SYSTEM own format, a binary containing the mesh
and the results information, all the real are in single precision.
• MED, a binary format based on hdf5, format used by the Salome platform. This format re-
quires to install additional libraries and add specific option to the T ELEMAC -M ASCARET
SYSTEM installation therefore it not installed by default.
In order to set the file format, a keyword is defined for every file, for example the keyword for
"geometry file" is "geometry file format".
All the files used for a simulation must be in the same format, this is due to the fact that the same
boundary file is used for all the files and the boundary file is format-dependant. Only SELAFIN
an SELAFIND can coexist as they are using the same format for their boundary file.
s u b r o u t i n e open_mesh ( f f o r m a t , f i l e _ n a m e , f i l e _ i d , openmode , i e r r )
!
! brief o p e n s a mesh f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
! | file_name | − − >| name o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r
134 Chapter 9. Hermes
s u b r o u t i n e close_mesh ( fformat , f i l e _ i d , i e r r )
!
! brief c l o s e s a mesh f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: file_id
integer , i n t e n t ( out ) :: ierr
!
end s u b r o u t i n e
!| fid | − − >| f i l e d e s c r i p t o r
! | date | < − >| t h e d a t e
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , intent ( inout ) : : date (6)
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ m e s h _ n e l e m ( f f o r m a t , f i d , t y p _ e l e m , nelem , i e r r )
!
! brief r e t u r n s t h e number o f e l e m e n t s o f t y p e t y p _ e l e m i n t h e mesh f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_elem | − − >| t y p e o f t h e e l e m e n t
! | nelem | < − >| t h e number o f e l e m e n t s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : typ_elem
integer , i n t e n t ( i n o u t ) : : nelem
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ m e s h _ n d p ( f f o r m a t , f i d , t y p _ e l e m , ndp , i e r r )
!
! brief r e t u r n s t h e number o f p o i n t p e r e l e m e n t o f t y p e t y p _ e l e m
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_elem | − − >| t y p e o f t h e e l e m e n t
! | ndp | < − >| t h e number o f p o i n t p e r e l e m e n t
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : typ_elem
integer , i n t e n t ( i n o u t ) : : ndp
integer , i n t e n t ( out ) : : i e r r
!
136 Chapter 9. Hermes
end s u b r o u t i n e
s u b r o u t i n e g e t _ m e s h _ i k l e ( f f o r m a t , f i d , t y p _ e l e m , i k l e , nelem , ndp , i e r r )
!
! brief returns the connectivity table for
!+ t h e e l e m e n t o f t y p e t y p _ e l e m i n t h e mesh
!+ w i l l do n o t h i n g i f t h e r e a r e no e l e m e n t o f t y p _ e l e m i n t h e mesh
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_elem | − − >| t y p e o f t h e e l e m e n t
!| ikle | < − >| t h e c o n n e c t i v i t y t a b l e
! | nelem | − − >| number o f e l e m e n t s
! | ndp | − − >| number o f p o i n t s p e r e l e m e n t
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : typ_elem
integer , i n t e n t ( in ) : : nelem
integer , i n t e n t ( in ) : : ndp
integer , i n t e n t ( i n o u t ) : : i k l e ( nelem ∗ ndp )
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
! brief r e t u r n s t h e number o f l a y e r s
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | nplan | < − >| t h e number o f l a y e r s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( inout ) : : nplan
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ m e s h _ d i m e n s i o n ( f f o r m a t , f i d , ndim , i e r r )
!
! brief r e t u r n s t h e number o f d i m e n s i o n s o f t h e s p a c e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | ndim | < − >| number o f d i m e n s i o n
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( i n o u t ) : : ndim
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ m e s h _ c o o r d ( f f o r m a t , f i d , jdim , ndim , n p o i n , c o o r d , i e r r )
!
! brief r e t u r n s the c o o r d i n a t e s for the given dimension
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | jdim | − − >| d i m e n s i o n number
! | ndim | − − >| number o f d i m e n s i o n o f t h e mesh
! | npoin | − − >| t o t a l number o f n o d e s
! | coord | < − >| l o c a l t o g l o b a l n u m b e r i n g a r r a y
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) : : f i d , jdim , ndim , n p o i n
138 Chapter 9. Hermes
Boundary functions
s u b r o u t i n e open_bnd ( f f o r m a t , f i l e _ n a m e , f i l e _ i d , openmode , i e r r )
!
! brief opens a boundary f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9.2 User Manual 139
! | fformat | − − >| f o r m a t o f t h e f i l e
! | file_name | − − >| name o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r o f t h e " mesh " f i l e
! | openmode | − − >| one o f t h e f o l l o w i n g v a l u e ’ r e a d ’ , ’ w r i t e ’ , ’ r e a d w r i t e ’
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
c h a r a c t e r ( len =∗) , i n t e n t ( in ) : : file_name
integer , i n t e n t ( in ) :: file_id
c h a r a c t e r ( len =9) , i n t e n t ( in ) : : openmode
integer , i n t e n t ( out ) :: ierr
!
end s u b r o u t i n e
end s u b r o u t i n e
s u b r o u t i n e g e t _ b n d _ n b o r ( f f o r m a t , f i d , t y p _ b n d _ e l e m , n p t f r , nbor , i e r r )
!
! brief r e t u r n s an a r r a y c o n t a i n i n g
!+ t h e a s s o c i a t i o n o f b o u n d a r y n u m b e r i n g t o mesh n u m b e r i n g
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_bnd_elem | − − >| t y p e o f t h e b o u n d a r y e l e m e n t
!| nptfr | − − >| number o f b o u n d a r y p o i n t s
! | nbor | < − >| an a r r a y c o n t a i n i n g t h e n u m b e r i n g i n t h e mesh
!| | | of a l l boundary p o i n t s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) : : fid , n p t f r , typ_bnd_elem
integer , i n t e n t ( i n o u t ) : : nbor ( n p t f r )
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ b n d _ i k l e ( f f o r m a t , f i d , t y p _ b n d _ e l e m , n e l e b d , ndp , i k l e _ b n d , i e r r )
!
! brief r e a d s the c o n n e c t i v i t y of the boundary elements
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_bnd_elem | − − >| t y p e o f t h e b o u n d a r y e l e m e n t s
! | nelebd | − − >| number o f b o u n d a r y e l e m e n t s
! | ndp | − − >| number o f p o i n t s p e r e l e m e n t
! | ikle_bnd | < − >| t h e c o n n e c t i v i t y o f t h e b o u n d a r y e l e m e n t s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
i n t e g e r , i n t e n t ( i n ) : : f i d , t y p _ b n d _ e l e m , n e l e b d , ndp
i n t e g e r , i n t e n t ( i n o u t ) : : i k l e _ b n d ( ndp ∗ n e l e b d )
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | t y p e _ b n d _ e l e m | − − >| t y p e o f t h e b o u n d a r y e l e m e n t s
!| nptfr | < − >| number o f b o u n d a r y p o i n t s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : type_bnd_elem
integer , intent ( inout ) : : nptfr
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ b n d _ n e l e m ( f f o r m a t , f i d , t y p e _ b n d _ e l e m , nelem , i e r r )
!
! brief r e a d s t h e number o f b o u n d a r y e l e m e n t s
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | t y p e _ b n d _ e l e m | − − >| t y p e o f t h e b o u n d a r y e l e m e n t s
! | nelem | < − >| number o f b o u n d a r y e l e m e n t s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : type_bnd_elem
integer , i n t e n t ( i n o u t ) : : nelem
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ b n d _ v a l u e ( f f o r m a t , f i d , t y p _ b n d _ e l e m , n e l e b d , v a l u e , n p t f r , nbor , i e
!
! brief r e t u r n s an a r r a y c o n t a i n i n g t h e b o u n d a r y t y p e f o r e a c h b o u n d a r y p o i
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | typ_bnd_elem | − − >| t y p e o f t h e b o u n d a r y e l e m e n t s
! | nelebd | − − >| number o f b o u n d a r y e l e m e n t s
! | value | < − >| t y p e o f b o u n d a r y f o r e a c h p o i n t
!| nptfr | − − >| number o f b o u n d a r y p o i n t s
! | nbor | − − >| b o u n d a r y t o g l o b a l n u m b e r i n g a r r a y
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
142 Chapter 9. Hermes
Data functions
s u b r o u t i n e g e t _ d a t a _ n v a r ( fformat , f i d , nvar , i e r r )
!
! brief r e t u r n s t h e number o f v a r i a b l e s i n t h e mesh f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | nvar | < − >| number o f v a r i a b l e
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( inout ) : : nvar
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ d a t a _ v a r _ l i s t ( fformat , f i d , nvar , v a r l i s t , u n i t l i s t , i e r r )
!
! brief r e t u r n s a l i s t o f a l l t h e name o f t h e v a r i a b l e s i n t h e mesh f i l e
!+ and a l i s t o f t h e i r u n i t s
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
!| varlist | < − >| l i s t o f v a r i a b l e name
!| untilist | < − >| l i s t o f v a r i a b l e u n i t
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e e x e c u t i o n
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : nvar
c h a r a c t e r ( len =16) , i n t e n t ( inout ) : : v a r l i s t ( nvar )
c h a r a c t e r ( len =16) , i n t e n t ( inout ) : : u n i t l i s t ( nvar )
integer , i n t e n t ( out ) : : i e r r
9.2 User Manual 143
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ d a t a _ t i m e ( ff or ma t , f i d , record , time , i e r r )
!
! brief r e t u r n s the time value of a given time step
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | record | − − >| number o f t h e t i m e s t e p
! | time | < − >| t i m e i n s e c o n d o f t h e t i m e s t e p
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e e x e c u t i o n
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : record
double precision , i n t e n t ( inout ) : : time
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e g e t _ d a t a _ v a l u e ( f f o r m a t , f i d , r e c o r d , var_name , r e s _ v a l u e , n , i e r r )
!
! brief r e t u r n s the value f o r each p o i n t of a given v a r i a b l e
!+ for a given time step
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r
! | record | − − >| t i m e s t e p t o r e a d i n t h e f i l e
144 Chapter 9. Hermes
Writing functions
s u b r o u t i n e s e t _ h e a d e r ( f f o r m a t , f i l e _ i d , t i t l e , n v a r , var_name , i e r r )
!
! brief w r i t e s t h e t i t l e and t h e name and u n i t s o f t h e v a r i a b l e s
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r
!| title | − − >| t i t l e o f t h e mesh
! | nvar | − − >| number o f v a r i a b l e s
! | var_name | − − >| name and u n i t s o f t h e v a r i a b l e s
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: file_id
c h a r a c t e r ( len =80) , i n t e n t ( in ) :: title
integer , i n t e n t ( in ) : : nvar
c h a r a c t e r ( len =32) , i n t e n t ( in ) : : var_name ( n v a r )
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
s u b r o u t i n e set_mesh
( f f o r m a t , f i l e _ i d , mesh_dim , t y p e l m , ndp , n p t f r ,
n p t i r , nelem , n p o i n , i k l e , i p o b o ,
knolg , x , y , nplan , date , time , i e r r , z )
!
! brief w r i t e s t h e mesh g e o m e t r y i n t h e f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
9.2 User Manual 145
!| file_id | − − >| f i l e d e s c r i p t o r
! | mesh_dim | − − >| d i m e n s i o n o f t h e mesh
! | typelm | − − >| t y p e o f t h e mesh e l e m e n t s
! | ndp | − − >| number o f p o i n t s p e r e l e m e n t
!| nptfr | − − >| number o f b o u n d a r y p o i n t
!| nptir | − − >| number o f i n t e r f a c e p o i n t
! | nelem | − − >| number o f e l e m e n t i n t h e mesh
! | npoin | − − >| number o f p o i n t s i n t h e mesh
!| ikle | − − >| c o n n e c t i v i t y a r r a y f o r t h e main e l e m e n t
! | ipobo | − − >| i s a b o u n d a r y p o i n t ? a r r a y
! | knolg | − − >| l o c a l t o g l o b a l n u m b e r i n g a r r a y
!| x | − − >| x c o o r d i n a t e s o f t h e mesh p o i n t s
!| y | − − >| y c o o r d i n a t e s o f t h e mesh p o i n t s
! | nplan | − − >| number o f p l a n e s
! | date | − − >| d a t e o f t h e c r e a t i o n o f t h e mesh
! | time | − − >| t i m e o f t h e c r e a t i o n o f t h e mesh
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
! | z ( o p t i o n a l ) | − − >| z c o o r d i n a t e s o f t h e mesh p o i n t s
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) : : f i l e _ i d , nplan
integer , i n t e n t ( in ) : : date (3)
integer , i n t e n t ( in ) : : time (3)
integer , i n t e n t ( in ) : : mesh_dim
integer , i n t e n t ( in ) : : typelm
integer , i n t e n t ( in ) : : ndp
integer , i n t e n t ( in ) :: nptfr
integer , i n t e n t ( in ) :: nptir
integer , i n t e n t ( in ) : : nelem
integer , i n t e n t ( in ) : : npoin
integer , i n t e n t ( in ) : : i k l e ( nelem ∗ ndp )
integer , i n t e n t ( in ) : : ipobo ( npoin )
integer , i n t e n t ( in ) : : knolg ( npoin )
double precision , i n t e n t ( in ) : : x ( npoin ) , y ( npoin )
integer , i n t e n t ( out ) : : i e r r
double p r e c i s i o n , i n t e n t ( in ) , o p t i o n a l : : z ( npoin )
!
end s u b r o u t i n e
s u b r o u t i n e s e t _ b n d ( f f o r m a t , f i d , t y p e _ b n d _ e l t , n e l e b d , ndp , i k l e , v a l u e , i e r r )
!
! brief w r i t e s t h e b o u n d a r y i n f o r m a t i o n i n t o t h e mesh f i l e
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| fid | − − >| f i l e d e s c r i p t o r
! | type_bnd_elt | − − >| t y p e o f t h e b o u n d a r y e l e m e n t s
! | nelebd | − − >| number o f b o u n d a r y e l e m e n t s
! | ndp | − − >| number o f p o i n t s p e r b o u n d a r y e l e m e n t
146 Chapter 9. Hermes
!| ikle | − − >| c o n n e c t i v i t y a r r a y f o r t h e b o u n d a r y e l e m e n t s
! | value | − − >| v a l u e f o r e a c h b o u n d a r y e l e m e n t
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: fid
integer , i n t e n t ( in ) : : type_bnd_elt
integer , i n t e n t ( in ) : : nelebd
integer , i n t e n t ( in ) : : ndp
integer , i n t e n t ( in ) : : i k l e ( n e l e b d ∗ ndp )
integer , i n t e n t ( in ) : : value ( nelebd )
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
subroutine add_data
( f f o r m a t , f i l e _ i d , var_name , t i m e , r e c o r d ,
f i r s t _ v a r , var_value , n , i e r r )
!
! brief add d a t a i n f o r m a t i o n f o r a g i v e n v a r i a b l e and a g i v e n t i m e on
!+ a l l p o i n t s o f t h e mesh
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | fformat | − − >| f o r m a t o f t h e f i l e
!| file_id | − − >| f i l e d e s c r i p t o r
! | var_name | − − >| name o f t h e v a r i a b l e
! | time | − − >| t i m e o f t h e d a t a
! | record | − − >| t i m e s t e p o f t h e d a t a
!| first_var | − − >| t r u e i f i t i s t h e f i r s t v a r i a b l e o f t h e d a t a s e t
! | var_value | − − >| t h e v a l u e f o r e a c h p o i n t o f t h e mesh
!| n | − − >| s i z e o f v a r _ v a l u e
!| ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
c h a r a c t e r ( len =8) , i n t e n t ( in ) : : fformat
integer , i n t e n t ( in ) :: file_id ,n
c h a r a c t e r ( len =32) , i n t e n t ( in ) : : var_name
double precision , i n t e n t ( in ) : : time
integer , i n t e n t ( in ) : : record
logical , i n t e n t ( in ) :: first_var
double precision , i n t e n t ( in ) : : var_value (n)
integer , i n t e n t ( out ) : : i e r r
!
end s u b r o u t i n e
• The file interface_hermes.f which contains the list of the reading/writing func-
tions.
All the files of the second part look more or less like this:
! ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
SUBROUTINE OPEN_MESH
! ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
!
&(FFORMAT, FILE_NAME , FILE_ID , OPENMODE, IERR )
!
!∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
! HERMES V7P0 01/05/2014
!∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
!
! brief OPENS A MESH FILE
!
! h i s t o r y Y AUDOUIN (LNHE)
!+ 24/03/2014
!+ V7P0
!+
!
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! | FFORMAT | − − >| FORMAT OF THE FILE
! | FILE_NAME | − − >| Name o f t h e f i l e
! | FILE_ID | − − >| F i l e d e s c r i p t o r
! | OPENMODE | − − >| ONE OF THE FOLLOWING VALUE ’READ’ , ’ WRITE ’ , ’ READWRITE’
!| Ierr | < − −| 0 i f no e r r o r d u r i n g t h e o p e n i n g
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!
USE UTILS_SERAFIN
USE UTILS_MED
IMPLICIT NONE
INTEGER LNG, LU
COMMON/ INFO / LNG, LU
!
!+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+
!
CHARACTER(LEN= 8 ) , INTENT ( IN ) : : FFORMAT
CHARACTER(LEN= ∗ ) , INTENT ( IN ) : : FILE_NAME
INTEGER , INTENT ( IN ) : : FILE_ID
CHARACTER(LEN= 9 ) , INTENT ( IN ) : : OPENMODE
INTEGER , INTENT (OUT) : : IERR
!
!+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+−+
!
SELECT CASE (FFORMAT)
148 Chapter 9. Hermes
• NBV1+NBV2 records:
• NELEM, NPOIN, NDP, 1: Number of elements, Number of points, number of points per
element
• IPOBO/KNOLG: array of integer dimension NPOIN, IPOBO contains 0 for the internal
points and it provides a numbering of the boundary points for the others. If the file is
partitioned (i.e. parallel run of the code) instead it is called KNOLG and it contains the
local to global numbering of the mesh points
• X array of real dimension NPOIN, contains the X coordinates of the mesh points
• Y array of real dimension NPOIN, contains the Y coordinates of the mesh points
i n t e g e r : : p o s _ i p o b o ! = p o s _ i k l e + 4 + nelem ∗ ndp ∗ i s + 4
i n t e g e r : : pos_coord != pos_ipobo + 4 + npoin ∗ i s + 4
i n t e g e r : : p o s _ d a t a ! = p o s _ c o o r d + ( 4 + n p o i n ∗ r s + 4 ) ∗ ndim
! computed i n f o r m a t i o n s
i n t e g e r : : s i z e _ d a t a != 4 + npoin ∗ r s + 4
i n t e g e r : : s i z e _ d a t a _ s e t != 4 + r s + 4 + nvar ∗(4 + npoin ∗ r s + 4)
! s t o c k e d q u a n t i t i e s and s m a l l v a r i a b l e s
integer : : ntimestep
i n t e g e r : : npoin
i n t e g e r : : nvar
i n t e g e r : : nelem
i n t e g e r : : ndp
i n t e g e r : : nplan
integer :: nptir
i n t e g e r : : ndim
integer :: typ_elt
character ( len=var_size ) , a l l o c a t a b l e : : v a r _ l i s t ( : )
! boundary i n f o r m a t i o n s
integer : : typ_bnd_elt
integer :: nptfr
integer :: ncli
end t y p e s r f _ i n f o
The RS sets the size of the real value (4 for single precision SELAFIN format, 8 for double
precision SELAFIND format).
3
2 2 2 2 BOUNDARY1
9.3 Developer Manual 151
5 4 4 4 BOUNDARY2
4 5 5 5 BOUNDARY3
• Create the file "utils_format.f" and implement all the functions described in 9.2.1
• Update all the functions generic file to add a new branch to the "if" statement for format
• Add in all the dictionary the option to choose format for the "FORMAT" keywords
• HERMES_RECORD_UNKNOWN_ERR
• HERMES_VAR_UNKNOWN_ERR
• HERMES_FILE_ID_ALREADY_IN_USE_ERR
• HERMES_FILE_NOT_OPENED_ERR
• HERMES_MAX_FILE_ERR
• HERMES_WRONG_ARRAY_SIZE_ERR
• HERMES_MED_NOT_LOADED_ERR
• HERMES_UNKNOWN_ELEMENT_TYPE_ERR
• HERMES_WRONG_ELEMENT_TYPE_ERR
• HERMES_UNKNOWN_GROUP_ERR
• HERMES_WRONG_HDF_FORMAT_ERR
• HERMES_WRONG_MED_FORMAT_ERR
• HERMES_WRONG_MED_VERSION_ERR
• HERMES_WRONG_AXE_ERR
To create a new issue, you must click on “New issue”. This will lead you to the page shown on
Fig 10.1. You will then need to fill the following information:
• Due date: deadline to ensure that the fix or feature is integrated on time.
• Milestone: target version of the code in which the development should be integrated.
• Labels: tags related to the type of the issue (bug, feature or enhancement), the module
which is concerned, the area of the system...
10.2 Modifying an issue 153
Git is the name of the version control software that we use for the T ELEMAC -M ASCARET
SYSTEM . The link https://en.wikipedia.org/wiki/Version_control gives an
explanation on what a version control is. The section below gives you a guide on how to perform
a few actions using Git.
If you are not into command line a few software give you a graphical interface to handle your
repository: gitk, SmartGit...
g i t c l o n e h t t p s : / / g i t l a b . pam−r e t d . f r / otm / t e l e m a c −m a s c a r e t . g i t
Clone a local copy of GitLab’s remote Git repository on your own computer.
11.2 Git commands 155
– Type = "fix #id" ,"feature #id" or "vnv #id" where id is the id of the GitLab issue
– Text = Title of the GitLab issue
• Otherwise:
If the commit contains more than one action, repeat the process on a new line.
g i t push
156 Chapter 11. Git
Push your local commits to GitLab’s remote repository. This will upload all the commits that
you have made on your local repository to the server repository. You should always do an up-
date (−pull command) before doing a push in case someone else has pushed changes before
you. Anyway, if you are not up to date, Git will not allow the push.
11.3 Update your branch with the latest version of the main branch
One of the conditions for validating a development is that it is up to date with the main branch.
In order to ease that step that can be sometimes painful, it is recommended to do that action
weekly. This way you do smaller updates instead of a massive one.
The commands
1. Switch to the main branch
g i t c h e c k o u t mybranch
If a GitLab merge request (MR) has been created (and it should), it is better to merge the branch
from GitLab’s MR interface.
12. CIS
If you want to run the validation of your developments locally, you need to type one of the
following commands:
v a l i d a t e _ t e l e m a c . py −−t a g s module
v a l i d a t e _ t e l e m a c . py −−n c s i z e =3
v a l i d a t e _ t e l e m a c . py
The first one will launch the validation of a specify list of modules (for example "telemac2d",
"tomawac", "artemis"). The second one will launch the validation of the whole system but for
the parallel test cases it will replace the number of processors by 3. The third one will run the
validation on the whole system. The list of authorised modules is:
• telemac2d
• telemac3d
• mascaret
• courlis
• sisyphe
• nestor
• tomawac
• aed
• waqtel
• python2
• python3
• apistudy
• api_mascaret
• coupling
158 Chapter 12. CIS
• postel3d
• stbtel
• khione
• artemis
• gaia
• gotm
• full_valid
• med
• fv
• api
13. Code coverage
This chapter will explain how to run the code coverage of the code using gcov and lcov.
13.2 What to do
You can find all the information for the configuration in systel.edf.cfg with the configuration
gcov.
Then run the following script:
# ! / bin / bash
# F i r s t run t o s e t c o u n t e r t o z e r o
l c o v −− d i r e c t o r y $HOMETEL / b u i l d s / $USETELCFG / l i b −−c a p t u r e \
−− i n i t i a l −−o u t p u t − f i l e $HOMETEL / app . i n f o
# Running t e s t c a s e s
v a l i d a t e _ t e l e m a c . py −k2 −−c l e a n −−b y p a s s
# Gathering data
l c o v −− d i r e c t o r y $HOMETEL / b u i l d s / $USETELCFG / l i b −−c a p t u r e \
−−o u t p u t − f i l e $HOMETEL / app . i n f o
# Generating html output
g e n h t m l −−l e g e n d −− h i g h l i g h t \
−−o u t p u t −d i r e c t o r y $HOMETEL / d o c u m e n t a t i o n / c o d e _ c o v e r a g e \
− t " Telemac−M a s c a r e t V&V c o d e c o v e r a g e " $HOMETEL / app . i n f o
This will build the html display under <root>/documentation/code_coverage. That
display will contains for each folder of the sources directory the percentage of code/functions
used and if you follow through you can even see the file and exactly what line was used.
14. Documentation
This chapter will describe how the documentation is handled in T ELEMAC -M ASCARET SYS -
TEM . All the documentation files are written in LATEXand are using the same Style.
• reference
• theory_guide
• user
• validation
main.tex
graphics
-- image.png
latex
-- file.tex
Where :
• graphics Folder contains all the figures associated with the documentation.
In Misc/TelemacTemplateDoc you can find a template that describes how to write a T ELEMAC -
M ASCARET SYSTEM documentation.
Warning:
The reference documentation is automatically generated from the dictionary of the
module so all the modification must be made in the dictionary file.
Warning:
The validation manual merge all the latex contains in the doc folder of the test
cases.
• All lot of figure will be created as for a weird reason some letter are represented with
pictures. To have the LATEXfile compile I suggest using a dummy picture and copy it to
the according name (it should be image1,image2. . . ).
• All the equations should compile directly but you should reorganise them in the LATEXso
they are more readable.
15. Dictionary
This chapter will describe how the dictionary is used in T ELEMAC -M ASCARET SYSTEM. The
dictionary is the input parameter for the reference documentation, the eficas interface and the
steering file. The module handling the dictionary is called DAMOCLES and can be found under
sources/utils/damocles.
NOM It is the name of the keyword in French. It should be max 72 characters long and between
"’". If the name contains an apostrophe it should be doubled.
NOM1 It is the name of the keyword in English. It should be max 72 characters long and
between "’".
TYPE This is the type of the keyword the T ELEMAC -M ASCARET SYSTEM handles 4 kind of
types:
INDEX This is the index to access that keyword for each type it must be unique. Running
DAMOCLES can give you what indexes are available.
TAILLE Number of values expected for the keyword. If the keyword can have a dynamic
number of values set TAILLE to 2 and add DYNLIST in APPARENCE.
15.1 Description of the dictionary 163
(opt) SUBMIT This text is only for keywords referring to a file. It is a 6 part chain separated
by ";". Here is an example ’T2DBI1-READ;T2DBI1;FACUL;BIN;LIT;SELAFIN’. Each
part gives the following information:
• Name of the file in the temporary folder (6 letters long) - opening access (READ
for read only, WRITE for write only, READWRITE for both).
• Name of the file in the temporary folder (6 letters long).
• Status of the file (FACUL if the file is optional, OBLIG if it is mandatory).
• Type of the file (BIN for binary, ASC for ASCII file).
• Opening access (LIT for read only, ECR, for write only, ECRLIT for both)
• Special treatment to apply for parallelism:
– SELAFIN-GEOM: geometry file will go through partel.
– SELAFIN: mesh file will go through but only the result field will be partitioned
it will use the mesh from the SELAFIN-GEOM file.
– CONLIM: boundary condition file.
– PARAL: file will be copied for each processor.
– SCAL: no copy only the main processor will be able to access it.
– WEIRS, ZONES, SECTIONS: file added to partel with SELAFIN-GEOM.
– CAS: keyword for the steering file.
– DICO: keyword for the dictionary.
– FORTRAN: user fortran.
– DELWAQHYD, DELWAQSEG ...: files for coupling with Delwaq.
DEFAUT French default value of the keyword. It should contains TAILLE values.
DEFAUT1 English default value of the keyword. It should contains TAILLE values.
MNEMO Name of the variable in the code containing the value of the keyword.
(opt) CONTROLE Two integer that define the min and max of the value of the keyword (This
is not used yet).
(opt) CHOIX List of values available for the keyword (in French). If the keyword is a STRING
just put the list of values in the following from ’text1’;’text2’;... You can also use
CHOIX to build a association between the actual value and a string by following this
syntax: ’val1:"text1"’;’val2:"text2"’;... You can have a look at the keywords SOLVER
and VARIABLES FOR GRAPHIC PRINTOUTS for examples. Note that the limitation
to those choices is not made by DAMOCLES when you are running a case, it is only done
by the interface. Text for the value are not allowed to contain apostrophes.
(opt) APPARENCE This is used to give information for the interface on how to enter the
values for the keyword the possible values are:
RUBRIQUE This is used to categorized the keywords. It should contain three values that are
the name of the categories in French.
Warning
The RUBRIQUE cannot have the same name as a keyword.
NIVEAU This is the status of the keyword if 0 the keyword will be considered mandatory in
the interface. Later it will also be used to group keywords for specific studies.
AIDE Text in French describing what the keyword is used for. This text can use LaTeX format.
It will be used to generate the reference documentation.
• The dependencies between keywords (i.e keywords that should appear only if a keyword
has a certain value) and "consigne" text that is to be displayed if the keyword as a certain
value
The first part is a list of blocks for each keyword as they are linked to a keyword. The block for
a dependence must follow that syntax:
n number_of_the_dependence
condition
keyword_on_which_is_the_condition
keyword_1
keyword_2
...
keyword_n
The number_of_dependence will be increased as we add blocks for that keyword. The
condition must follow a couple rules:
• It must use the "eficas form of the keyword" (i.e. Replace " " "’" "-" by "_").
• If the keyword has a CHOIX it must use the text and not the value.
If the condition is on more than one keyword and affect only one keyword set number_of_the_dependencie
to 0 and n to 1.
The block for a "consigne" must follow that syntax:
15.3 What DAMOCLES can do for you 165
1 number_of_the_dependence
condition
keyword_on_which_is_the_condition
Text_in_French
Text_in_English
The number_of_dependence must be negative but still follow the increase (i.e. if its the
third dependence it will be -3). Both the text in French and the one in English must be written
on one line.
Here is an example for the keyword INITIAL CONDITIONS which has 3 dependencies and
one "consigne".
2 1
INITIAL_CONDITIONS == ’CONSTANT ELEVATION’
INITIAL CONDITIONS
INITIAL ELEVATION
2 2
INITIAL_CONDITIONS == ’CONSTANT DEPTH’
INITIAL CONDITIONS
INITIAL DEPTH
2 3
INITIAL_CONDITIONS == ’TPXO SATELLITE ALTIMETRY’
INITIAL CONDITIONS
ASCII DATABASE FOR TIDE
1 -4
INITIAL_CONDITIONS == ’SPECIAL’
INITIAL CONDITIONS
Les conditions initiales sur la hauteur d’’eau doivent etre precisees dans le
The initial conditions with the water depth should be stated in the CONDIN sub
The second part that is at the end of the file begins with the line:
666 666
NAME_OF_RUBRIQUE
STATUS
By default all RUBRIQUE are mandatory here you can change that by setting STATUS to f.
NAME_OF_RUBRIQUE must have the same name as in the dictionary.
All those options are to be combine with the option -m to specify on which module to run the
script by default it is run for all of them except M ASCARET. The first one can also be used to get
information on the dictionary such as the index used, the RUBRIQUE in French and English to
check that we have the same number of each the reordered dictionary will be next to the original
with a 2 added to the name. It also checks that the dictionary is following the rules described
before.
The eficas option is generating all the files needed to run the GUI. All the files are added in the
folder eficas in the source folder of the module.
The latex option is used by doc_telemac.py to compile the reference manual for that mod-
ule.
16. Validation
This chapter explains how to use the Python validation scripts in order to define VnV (Verifica-
tion and Validation) test cases. In particular, this describes what to run and what to do with the
resulting data, such as the comparison of the results with a reference file, an analytical solution,
measured data. . .
"""
Validation script for gouttedo
"""
from vvytel . vnv_study import AbstractVnvStudy
from execution . telemac_cas import TelemacCas , get_dico
from data_manip . extraction . telemac_file import TelemacFile
def _pre(self ):
"""
Defining the studies
"""
pass
168 Chapter 16. Validation
• _init: this is where the rank, tags and other optional parameters must be defined. Only
rank and tags are mandatory.
– rank: defines the importance of the test case. The rule for the rank is described
below.
– tags: the list of modules which will be used by the case. The list of allowed tags can
be found using validate_telemac.py help.
– listing: if set to True, force the -s option on the execution, in order to write the
listing to a file. This is necessary if there is a need to do some post-treatment on the
listing.
– walltime: this can be used to force the value of runcode.py option –walltime. It can
be either a string or a dictionary. Using a string applies the walltime to all the class
studies. To assign a separate walltime to each case, a dictionary must be used, using
the study name as the key and the walltime as the value. Note that this option is
only taken into account on cluster configurations.
• _pre: this is where studies are declared. A study is defined by a steering file and a module.
It can also be given commands using a string that will be executed by the shell.
• _check_results: this is were the results are checked against measurements, analytical
solutions, reference files. . .
• _post: this were the post-treatment is done. We recommand to use functions from the
Postel Python module, but you can use any Python code.
• 0: minimal validation that should last less than an hour and check each module.
Requirements
Running a validation on a cluster requires to have a configuration with the following points:
• The batch submission command must write in a file for each submission the id of the
submission and the case folder, separated by a ’;’.
The procedure below will submit each of the T ELEMAC -M ASCARET studies to the cluster
scheduler. This means that in the best of case your whole validation will be as long as your
longest T ELEMAC -M ASCARET run. The "commands" with the argument hpc=True will be
submetted as well.
Here is an example for a cluster using SLURM (split in several lines for better readability,
however it should be a one-liner):
cp HPC_STDIN ../;
cd ../;
ret=‘ sbatch −−wckey=<project > < HPC_STDIN ‘;
id=‘echo $ret|tr ’ ’ ’\n’|tail −n 1‘;
dir=‘ readlink −f .‘;
echo "$id;$dir" >> <id_log >;
echo $ret
<project> will be replaced by the --project option from validate_telemac.py if
given.
<id_log> will be replaced by the --id-log option from validate_telemac.py if
given, otherwise it we be replaced by ’id.log’.
Here is an extract of what the file containing the id looks like (paths have been shortened to be
easier to find in the documentation):
30346528;.../examples/artemis/G8M/vnv_g8m/vnv_1/eole.intel.dyn
30346529;.../examples/artemis/beach/vnv_beach/vnv_1/eole.intel.dyn
30346531;.../examples/artemis/beach/vnv_beach/vnv_2/eole.intel.dyn
30346534;.../examples/artemis/bj78/vnv_bj78/vnv_1/eole.intel.dyn
30346535;.../examples/artemis/bj78/vnv_bj78/vnv_2/eole.intel.dyn
30346537;.../examples/artemis/bosse/vnv_bosse/vnv_1/eole.intel.dyn
38368703;cmd:.../examples/artemis/bj78/vnv_bj78.py:vnv_1_api
38368704;cmd:.../examples/artemis/bj78/vnv_bj78.py:vnv_2_api
Run commands
The procedure to run is the following:
Replacing:
• hpc_options by the options you would give an HPC T ELEMAC -M ASCARET run on your
cluster (–queue, –nctile, –walltime, –jobname, –project. . . ).
17. Useful stuff
• All the input files you need to run the case, and just the input of the files generated by
a successful run should not be in the GitLab repository. See the table 17.1 below for the
convention for the naming of the files.
• The doc folder which contains the documentation for the test case in LaTeX format (See
other test cases for example).
• The xml file to run the test case (See other test cases for example).
All the Selafin file must have the extension "slf", the steering case the extension "cas".
Table 17.1: Table with contents ranging over several cells horizontally and vertically.
The off-diagonal terms of a matrix A are placed in a two-dimensional array, the first dimension
being NELMAX, the maximum number of elements (the second dimension depends on the type
of matrix and storage). The following conventions are written in the form of rows, such that:
XA(IELEM,01) = XA12
XA(IELEM,1) = XA12
XA(IELEM,2) = XA13
XA(IELEM,3) = XA23
If A is asymmetrical:
XA(IELEM,04) = XA21
XA(IELEM,05) = XA31
XA(IELEM,06) = XA32
174 Chapter 18. Matrix storage conventions
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA14
XA(IELEM,04) = XA21
XA(IELEM,05) = XA23
XA(IELEM,06) = XA24
XA(IELEM,07) = XA31
XA(IELEM,08) = XA32
XA(IELEM,09) = XA34
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA21
XA(IELEM,04) = XA23
XA(IELEM,05) = XA31
XA(IELEM,06) = XA32
XA(IELEM,07) = XA41
XA(IELEM,08) = XA42
XA(IELEM,09) = XA43
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA14
XA(IELEM,04) = XA23
XA(IELEM,05) = XA24
XA(IELEM,06) = XA34
If A is asymmetrical:
XA(IELEM,07) = XA21
XA(IELEM,08) = XA31
XA(IELEM,09) = XA41
18.5 Triangle P1 EBE - Quadratic triangle EBE 175
XA(IELEM,10) = XA32
XA(IELEM,11) = XA42
XA(IELEM,12) = XA43
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA14
XA(IELEM,04) = XA15
XA(IELEM,05) = XA16
XA(IELEM,06) = XA21
XA(IELEM,07) = XA23
XA(IELEM,08) = XA24
XA(IELEM,09) = XA25
XA(IELEM,10) = XA26
XA(IELEM,11) = XA31
XA(IELEM,12) = XA32
XA(IELEM,13) = XA34
XA(IELEM,14) = XA35
XA(IELEM,15) = XA36
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA21
XA(IELEM,04) = XA23
XA(IELEM,05) = XA31
XA(IELEM,06) = XA32
XA(IELEM,07) = XA41
XA(IELEM,08) = XA42
XA(IELEM,09) = XA43
XA(IELEM,10) = XA51
XA(IELEM,11) = XA52
XA(IELEM,12) = XA53
XA(IELEM,13) = XA61
XA(IELEM,14) = XA62
XA(IELEM,15) = XA63
176 Chapter 18. Matrix storage conventions
− 16 17 18 19 20
1 − 21 22 23 24
2 6 − 25 26 27
3 7 10 − 28 29
4 8 11 13 − 30
5 9 12 14 15 −
XA(IELEM,01) = XA12
XA(IELEM,02) = XA13
XA(IELEM,03) = XA14
XA(IELEM,04) = XA15
XA(IELEM,05) = XA16
XA(IELEM,06) = XA23
XA(IELEM,07) = XA24
XA(IELEM,08) = XA25
XA(IELEM,09) = XA26
XA(IELEM,10) = XA34
XA(IELEM,11) = XA35
XA(IELEM,12) = XA36
XA(IELEM,13) = XA45
XA(IELEM,14) = XA46
XA(IELEM,15) = XA56
If A is asymmetrical:
XA(IELEM,16) = XA21
XA(IELEM,17) = XA31
XA(IELEM,18) = XA41
XA(IELEM,19) = XA51
XA(IELEM,20) = XA61
XA(IELEM,21) = XA32
XA(IELEM,22) = XA42
XA(IELEM,23) = XA52
XA(IELEM,24) = XA62
XA(IELEM,25) = XA43
XA(IELEM,26) = XA53
XA(IELEM,27) = XA63
XA(IELEM,28) = XA54
XA(IELEM,29) = XA64
XA(IELEM,30) = XA65
19. The SELAFIN format
Note: historically, this format was called SERAFIN and its file extension was often “.srf”. At
some point in the T ELEMAC -M ASCARET SYSTEM development history, it has been decided to
switch to the MED format. As a joke, SERAFIN was then renamed to SELAFIN, to reflect
French “C’est la fin”, meaning “This is the end” (of the SERAFIN format). However, MED
never replaced SELAFIN, which remains the most widely used of the two formats.
This format can be ‘SELAFIN’, for single precision storage, or ‘SELAFIND’ for double preci-
sion storage. Double precision storage can be used for cleaner restarts, but may not be under-
stood by all post-processors.
All strings in a SELAFIN file must be utf-8 encoded (See for https://en.wikipedia.
org/wiki/UTF-8 for the exact list).
The records are listed below. Records are given in the FORTRAN sense. It means that every
record corresponds to a FORTRAN WRITE:
1 record containing the title of the study (80 characters), The last 8 characters must contain the
format of the file (SELAFIN or SELAFIND)
1 record containing the two integers NBV(1) and NBV(2) (NBV(1) the number of variables,
NBV(2) with the value of 0),
NBV(1) records containing the names and units of each variable (over 32 characters),
1 record containing the integers table IPARAM (10 integers, of which only 4 are currently being
used).
If IPARAM (3) is not 0: the value corresponds to the x-coordinate of the origin in the mesh
If IPARAM (4) is not 0: the value corresponds to the y-coordinate of the origin in the mesh
These coordinates in metres may be used by post-processors to retrieve geo-referenced coordi-
nates, while the coordinates of the mesh are relative to keep more digits.
If IPARAM (7) is not 0: the value corresponds to the number of planes on the vertical (in
prisms.)
If IPARAM (8) is not 0: the value corresponds to the number of boundary points (in parallel).
If IPARAM (9) is not 0: the value corresponds to the number of interface points (in parallel).
if IPARAM (10) = 1: a record containing the computation starting date in 6 integers: year,
month, day, hour, minute, second
178 Bibliography
• NBV(1)+NBV(2) records containing the results arrays for each variable at time T.
[1] J-M. HERVOUET. Hydrodynamics of free surface flows. Modelling with the finite element
method. John Wiley & Sons, Ltd, Paris, 2007.
[2] HERVOUET J.-M. Méthodes itératives pour la solution des systèmes matriciels. Rapport
EDF HE43/93.049/A, 1996.
[3] HERVOUET J.-M. and C. LENORMANT. Symbolic computation of Finite Element matri-
ces with MAPLE V. Rapport EDF HE43/97.048/A, 1997.
[4] JANIN J.-M., HERVOUET J.-M., and MOULIN C. A positive conservative scheme for
scalar advection using the M.U.R.D technique in 3D free-surface flow problems. XIth In-
ternational Conference on Computional methods in water resources, 1996.
[5] Philippe Langlois, Rafife Nheili, and Christophe Denis. Numerical Reproducibility: Fea-
sibility Issues. In NTMS’2015: 7th IFIP International Conference on New Technologies,
Mobility and Security, pages 1–5, Paris, France, July 2015. IEEE, IEEE COMSOC & IFIP
TC6.5 WG. doi: 10.1109/NTMS.2015.7266509.
[6] Philippe Langlois, Rafife Nheili, and Christophe Denis. Recovering numerical reproducibil-
ity in hydrodynamic simulations. In J. Hormigo P. Montuschi, M. Schulte, S. Oberman,
and N. Revol, editors, 23rd IEEE International Symposium on Computer Arithmetic, num-
ber ISBN 978-1-5090-1615-0, pages 63–70. IEEE Computer Society, July 2016. doi:
10.1109/ARITH.2016.27. (Silicon Valley, USA. July 10-13 2016).
[7] METCALF M. and REID J. Fortran 90 explained. Oxford Science Publications, 1990.