Cactus Tutorial: Example Application: The 3D Scalar Wave Equation

advertisement
Example Application:
3D Scalar Wave Equation
The Cactus Team
Albert Einstein Institute
cactus@cactuscode.org
Scalar Wave Model Problem

Scalar waves in 3D are solutions of the hyperbolic
wave equation
-f,tt + f,xx + f,yy + f,zz = 0

This is an initial value problem, if we give data for f and
its first time derivative at some initial time, the wave
equation tells us how it evolves in the future
time
r
Numerical Method

Numerical solve by discretising on a grid, using explicit
finite differencing (centered, second order)
f n+1i,j,k = 2f ni,j,k - f n-1i,j,k
+ Dt2/Dx2(f ni+1,j,k -2 f ni,j,k + f ni-1,j,k )
+ Dt2/Dy2(f ni,j+1,k -2 f ni,j,k + f ni,j-1,k )
+ Dt2/Dz2(f ni,j,k+1 -2 f ni,j,k + f ni,j,k-1 )
time
r
Numerical Method

Finite grid, so need to apply outer boundary conditions

Main parameters:


grid spacings: Dt, Dx, Dy, Dz, which coords?, which initial data?
Simple problem, analytic solutions, but contains many
features needed for modelling more complex problems
Stand Alone Code: Main.f
c
c
c
c
c
====================================
program WaveToy
====================================
Fortran 77 program for 3D wave equation.
Explicit finite difference method.
====================================
x(i,j,k) = dx*(i-1) + x_origin
y(i,j,k) = dy*(j-1) + y_origin
z(i,j,k) = dz*(k-1) + z_origin
r(i,j,k) = sqrt(x(i,j,k)**2+y(i,j,k)**2+z(i,j,k)**2)
end do
end do
end do
c
Global variables in include file
include "WaveToy.h"
integer i,j,k
c
OPEN OUTPUT FILES
open(unit=11,file=“out.xl”)
open(unit=12,file=“out.yl”)
open(unit=13,file=“out.zl”)
c
SET UP PARAMETERS
nx = 30
[MORE PARAMETERS]
c
SET UP INITIAL DATA
call InitialData
call Output
c
EVOLVING
do iteration = 1, nt
call Evolve
if (mod(iteration,10).eq.0) call Output
end do
c
SET UP COORDINATE SYSTEM AND GRID
x_origin = (0.5 - nx/2)*dx
y_origin = (0.5 - ny/2)*dy
z_origin = (0.5 - nz/2)*dz
do i=1,nx
do j=1,ny
do k=1,nz
stop
end
Standalone Program
Setting up parameters
Setting up grid and coordinate system
Opening output files
Setting up initial data
Performing iteration 10
Performing iteration 20
Performing iteration 30
Performing iteration 40
Performing iteration 50
Performing iteration 60
Performing iteration 70
Performing iteration 80
Performing iteration 90
Performing iteration 100
Done
Wave Equation Program

Developed as single processor 3D program (~1hr)

Should you use Cactus? Not needed for such a simple
program but if you need:


parallelism for more resolution?

to share development with colleagues?

to run on a variety of platforms?

2D/3D output and checkpointing?

to solve an elliptic equation for initial data?

adaptive mesh refinement?, remote monitoring? ….
All can be provided by Cactus
Cactus Flesh Provides

Parameter parser with types, ranges, checking

Scheduling of routines

Make system on many architectures

Dynamic argument lists

Utilities such as program checking test suites
Cactus Thorns Provide

Coordinates


Boundary conditions


(Fixed, flat, radiation,...)
IO


(Cartesian, various domains with symmetries)
(screen, 0D-3D, IsoSurfaces, Jpeg, streaming, configurable)
Driver

(create grid variables, handle storage, communications)
Stand Alone Code: Main.f
c
c
c
c
c
====================================
program WaveToy
====================================
Fortran 77 program for 3D wave equation.
Explicit finite difference method.
====================================
c
Global variables in include file
include "WaveToy.h"
integer i,j,k
Configuation
c
SET UP PARAMETERS
nx = 30
[MORE PARAMETERS]
x(i,j,k) = dx*(i-1) + x_origin
y(i,j,k) = dy*(j-1) + y_origin
z(i,j,k) = dz*(k-1) + z_origin
r(i,j,k) = sqrt(x(i,j,k)**2+y(i,j,k)**2+z(i,j,k)**2)
end do
end do
end do
c
OPEN OUTPUT FILES
open(unit=11,file=“out.xl”)
open(unit=12,file=“out.yl”)
open(unit=13,file=“out.zl”)
c
SET UP INITIAL DATA
call InitialData
call Output
c
EVOLVING
do iteration = 1, nt
call Evolve
if (mod(iteration,10).eq.0) call Output
end do
files
c
SET UP COORDINATE SYSTEM AND GRID
x_origin = (0.5 - nx/2)*dx
y_origin = (0.5 - ny/2)*dy
z_origin = (0.5 - nz/2)*dz
do i=1,nx
do j=1,ny
do k=1,nz
stop
end
CartGrid3D
Output from
parameters
You write
these!!
Converting Your Code ...


Decide on arrangement/thorn structure
Write thorn configuration files








param.ccl, interface.ccl, schedule.ccl
Add Cactus “stuff” to source code
Add source code filenames to make.code.defn
Compile and debug ...
Write a parameter file
Run and debug …
Create a test suite to be sure it keeps working
If you want, make your thorns available to
friends/colleagues/the world
Splitting Into Thorns

Could just write one thorn containing all the routines

Better to split the code in different thorns

IDScalarWave
(Initial data)

WaveToyF77
(Evolving routines)

Make use of Toolkit thorns for Coordinates,
Boundaries, IO.

Why separate thorns?

Easier to develop and share

Better code planning - modularity
Create New Thorns

Checkout Cactus, and in the Cactus home directory type
gmake newthorn

Follow instructions to create a new thorns “WaveToyF77”
and “IDScalarWave” in an arrangement e.g. “Tutorial”

This gives you the thorn structure and the basic files
needed
Thorn Structure
WaveToyF77
schedule.ccl
param.ccl
interface.ccl
README
src
doc
par
make.code.defn
WaveToy.F77
InitSymBound.F77
test
Thorn Configuration Files

Need to decide:

What are the grid variables:
– interface.ccl

What are the parameters:
– param.ccl

In which order should the routines be scheduled:
– schedule.ccl


Do I use grid variables, parameters or scheduling from other thorns?
These configuration files are parsed (Perl) during
compilation, generating code for argument lists, parameters,
program flow, etc.
Thorn Configuration: param.ccl

Parameters: set in a parameter file read and verified at run
time.

Example: How many grid points? What initial data? What to output?

Specify:

data type (real, integer, keyword, boolean, string)

range (nx>0, initial_data is “gaussian wave” or “plane wave”)

description

visability to other thorns (private, restricted, global)

default value

parameters used from other thorns
WaveToyF77: param.ccl
# Parameter definitions for thorn WaveToyF77
private:
Only the evolver needs
to know about the
boundary condition
KEYWORD bound "Type of boundary condition to use"
{
"none”
:: "No boundary condition"
"flat"
:: "Flat boundary condition"
"radiation"
:: "Radiation boundary condition"
"zero"
:: "Zero boundary condition"
} "none"
IDScalarWave: param.ccl
# Parameter definitions for thorn IDScalarWave
shares: grid
USES KEYWORD type
restricted:
KEYWORD initial_data "Type of initial data"
{
"plane"
:: "Plane wave"
"gaussian"
:: "Gaussian wave"
"box"
:: "Box wave"
} "gaussian"
private:
REAL radius "The radius of the gaussian wave"
{
0:* :: “Radius must be positive”
} 0.0
IDScalarWave uses the
parameter type from
CartGrid3D
Other thorns can
use or extend
initial_data
Only for
IDScalarWave
to use
Thorn configuration: interface.ccl

Object orientated concepts:


Implementation, Inherits, Friends
Grid variables

group name (many flesh functions act on groups)

group type (grid array, grid function, grid scalar)

variable type (real, int, complex)

dimension

description

visability to other thorns (private, protected, public)
WaveToyF77: interface.ccl
# Interface definition for WaveToyF77

Implements: describes what this
thorn “does”, WaveToyF77 can
be replaced by any other thorn
which “does” the same thing and
has the same public interface.

Timelevels: finite difference
method is a 3 time level scheme,
phi_n, phi, phi_p. Time levels are
rotated at each iteration.

Scope: grid variables can be
public, protected or private.
implements: wavetoy
public:
cctk_real scalarevolve type = GF
timelevels=3
{
phi
} "The evolved scalar field"
IDScalarWave: interface.ccl
# Interface definition for IDScalarWave

Inherits: what IDScalar wave
takes from other thorns
(implementations)

Needs phi from WaveToyF77
(wavetoy) to fill in initial data

Needs coordinate grid functions
and parameters from CartGrid3D
(grid)
implements: idscalarwave
inherits: wavetoy grid
Thorn Configuration: schedule.ccl

Schedules when the thorn routines are run, and when
storage (and communications) for variables are activated

WaveToyF77 has one base routine, WaveToyF77_Evol

when should it be run?

should it be BEFORE or AFTER any other routine?

what language (Fortran or C) is it written in?

is variable storage or communication needed?

is the variable storage needed just for the routine, or for the whole
run?
Example Scheduling Tree
Startup routines
Cactus: Register banner for Cactus
CartGrid3D: Register GH Extension for GridSymmetry
CartGrid3D: Register coordinates for the Cartesian grid
IOASCII: Startup routine
IOBasic: Startup routine
IOUtil: IOUtil startup routine
PUGH: Startup routine.
WaveToyC: Register banner
Parameter checking routines
CartGrid3D: Check coordinates for CartGrid3D
IDScalarWave: Check parameters
Initialisation
CartGrid3D: Set up spatial 3D Cartesian coordinates on the GH
PUGH: Report on PUGH set up
Time: Set timestep based on speed one Courant condition
WaveToyC: Schedule symmetries
IDScalarWave: Initial data for 3D wave equation
do loop over timesteps
WaveToyC: Evolution of 3D wave equation
t = t+dt
if (analysis)
endif
enddo
CCTK_STARTUP
CCTK_PARAMCHECK
CCTK_INITIAL
CCTK_EVOL
WaveToyF77: schedule.ccl
# Schedule definitions for thorn WaveToy77
STORAGE: scalarevolve
Storage always
assigned
schedule WaveToyF77_Evolution as WaveToy_Evolution at EVOL
{
LANG: Fortran
Synchronize
SYNC: scalarevolve
group on exit
} "Evolution of 3D wave equation”
schedule WaveToyF77_Boundaries as WaveToy_Boundaries at EVOL
AFTER WaveToy_Evolution
{
LANG: Fortran
Function alias
} "Boundaries of 3D wave equation"
IDScalarWave: schedule.ccl
# Schedule definitions for thorn IDScalarWave
schedule IDScalarWave_CheckParameters at CCTK_PARAMCHECK
{
LANG: Fortran
} "Check parameters"
schedule IDScalarWave_InitialData at CCTK_INITIAL
{
Should already be
STORAGE: wavetoy::scalarevolve
on, but make sure
LANG:
Fortran
} "Initial data for 3D wave equation"
WaveToy.F77
dx2i = 1.0/dx2
dy2i = 1.0/dy2
dz2i = 1.0/dz2
#include "cctk.h"
#include "cctk_Parameters.h”
#include "cctk_Arguments.h"
factor = 2*(1-(dt2)*(dx2i+dy2i+dz2i))
subroutine WaveToyF77_Evolution(CCTK_ARGUMENTS)
implicit none
c
c
c Declare variables in argument list
DECLARE_CCTK_ARGUMENTS
INTEGER i,j,k,ierr
CCTK_REAL dx,dy,dz,dt
CCTK_REAL dx2,dy2,dz2,dt2
CCTK_REAL dx2i,dy2i,dz2i
CCTK_REAL factor
c Set up shorthands
c ----------------dx = CCTK_DELTA_SPACE(1)
dy = CCTK_DELTA_SPACE(2)
dz = CCTK_DELTA_SPACE(3)
dt = CCTK_DELTA_TIME
dx2
dy2
dz2
dt2
=
=
=
=
dx*dx
dy*dy
dz*dz
dt*dt
&
&
&
&
Do the evolution
---------------do k = 2, cctk_lsh(3)-1
do j = 2, cctk_lsh(2)-1
do i = 2, cctk_lsh(1)-1
phi_n(i,j,k) = factor*phi(i,j,k) phi_p(i,j,k) + (dt2) *
((phi(i+1,j,k)+phi(i-1,j,k))*dx2i
+(phi(i,j+1,k)+phi(i,j-1,k))*dy2i
+(phi(i,j,k+1)+phi(i,j,k-1))*dz2i)
end do
end do
end do
return
end
WaveToy.F77 (2)
c Apply the outer boundary conditions
subroutine
if (CCTK_EQUALS(bound,"flat")) then
&
WaveToyF77_Boundaries(CCTK_ARGUMENTS)
call BndFlatVN(ir,cctkGH,sw,"wavetoy::phi")
else
if (CCTK_EQUALS(bound,"zero")) then
implicit none
call BndScalarVN(ir,cctkGH,zero,sw,
&
"wavetoy::phi")
DECLARE_CCTK_ARGUMENTS
else
if
(CCTK_Equals(bound,"radiation").eq.1)
then
DECLARE_CCTK_PARAMETERS
call BndRadiativeVN(ir,cctkGH,sw,zero,one,
DECLARE_CCTK_FUNCTIONS
&
"wavetoy::phi”,"wavetoy::phi")
end if
c Local declarations
CCTK_REAL zero,one
if (ierr < 0) then
integer ir
call CCTK_WARN(0,”BCs not applied!!");
integer sw(3)
end if
ierr = -1
return
zero = 0.0
end
one = 1.0
c Set the stencil width
sw(1)=1
sw(2)=1
sw(3)=1
c Apply the symmetry boundary conditions
call
& CartSymGN(ir,cctkGH,"wavetoy::scalarevolve")
Compiling WaveToy Application

Get hold of the additional Cactus thorns needed









CactusBase/CartGrid3D
(sets up the Cartesian grid)
CactusBase/Boundary
(provides standard boundary conditions)
CactusBase/Time
(set the timestep)
CactusPUGH/PUGHSlab
(extract hyperslabs of data from grid arrays)
CactusPUGH/PUGHReduce (reduction operations)
CactusPUGH/PUGH
(the driver, always needed)
CactusBase/IOASCII
(output in 1D ASCII format)
CactusBase/IOBasic
(output scalars (inc. reductions) and to screen)
CactusBase/IOUtil
(all the Cactus IO thorns need this thorn)
Compiling WaveToy Application

Set up a configuration by typing
gmake wave (or gmake wave-config)

Compile the code using
gmake wave

If successful you’ll create exe/cactus_wave
Running Executable

Cactus runs from a parameter
file
> exe/cactus_wave wavetoy.par
ActiveThorns = "idscalarwave time
wavetoyf77 pugh pughreduce cartgrid3d
pughslab ioutil ioascii"
time::dtfac = 0.5
idscalarwave::initial_data = "gaussian"
idscalarwave::sigma = 2.8
idscalarwave::radius = 0
wavetoyf77::bound = "zero"


All thorns you need must be
activated using the ActiveThorns
parameter
Parameters must be qualified
with the implementation or thorn
name, depending on their type
grid::type = "BySpacing"
grid::dxyz = 0.6
driver::global_nx = 30
driver::global_ny = 30
driver::global_nz = 30
cctk_itlast = 100
IOASCII::out1D_every = 10
IOASCII::out1D_vars = "wavetoy::phi "
IOASCII::outinfo_every = 10
IOASCII::outinfo_vars = "wavetoy::phi"
IO::outdir = "StandAlone"
Run Time Output
> mpirun -np 2 exe/cactus_wave wavetoy.par
----------------------------------------------------------------------------10
1
0101
************************
01 1010 10
The Cactus Code V4.0
1010 1101 011
www.cactuscode.org
1001 100101
************************
00010101
100011
(c) Copyright The Authors
0100
GNU Licensed. No Warranty
0101
----------------------------------------------------------------------------Activating thorn Cactus...Success -> active implementation Cactus
Activating thorn iobasic...Success -> active implementation IOBasic
Activating thorn idscalarwave...Success -> active implementation idscalarwave
Activating thorn time...Success -> active implementation time
Activating thorn wavetoyf77...Success -> active implementation wavetoy
Activating thorn pugh...Success -> active implementation driver
Activating thorn pughreduce …Success -> active implementation pughreduce
Activating thorn cartgrid3d...Success -> active implementation grid
Activating thorn ioutil...Success -> active implementation IO
Activating thorn ioascii...Success -> active implementation IOASCII
-----------------------------------------------------------------------------
Run Time Output (2)
Startup routines
CartGrid3D: Register GH Extension for GridSymmetry
CartGrid3D: Register coordinates for the Cartesian grid
PUGH: Startup routine
PUGHReduce: Startup routine
IOUtil: Startup routine
IOASCII: Startup routine
IOBasic: Startup routine
WaveToyF77: Register banner
Parameter checking routines
CartGrid3D: Check coordinates for CartGrid3D
IDScalarWave: Check parameters
Initialisation
CartGrid3D: Set up spatial 3D Cartesian coordinates on the GH
IOASCII: Choose 1D output lines
IOASCII: Choose 2D output planes
PUGH: Report on PUGH set up
Time: Set timestep based on Courant condition
WaveToyF77: Schedule symmetries
IDScalarWave: Initial data for 3D wave equation
Run Time Output (3)
do loop over timesteps
WaveToyF77: Evolution of 3D wave equation
WaveToyF77: Boundaries of 3D wave equation
t = t+dt
if (analysis)
endif
enddo
Termination routines
PUGH: Termination routine
Shutdown routines
--------------------------------------------------------------------------------------------------------------------------------------------------------Driver provided by PUGH
----------------------------------------------------------------------------WaveToyF77: Evolutions of a Scalar Field
----------------------------------------------------------------------------INFO (CartGrid3D): dx=>3.0000000e-01 dy=>3.0000000e-01 dz=>3.0000000e-01
INFO (CartGrid3D): x=>[-0.150, 8.550] y=>[-0.150, 8.550] z=>[-0.150, 8.550]
INFO (PUGH): MPI Evolution on 4 processors
INFO (PUGH): 3-dimensional grid functions
INFO (PUGH):
Size: 30 30 30
INFO (PUGH):
Processor topology: 1 x 2 x 2
INFO (PUGH):
Local load: 7680
[30 x 16 x 16]
INFO (PUGH):
Maximum load skew: 0.000000
Run Time Output (4)
-------------------------------------------it |
| phi
|
|
t
| Min
Max
|
-------------------------------------------0 |
0.000| 0.00000000 | 0.99142726 |
10 |
1.500| -0.14944313 | 0.00005206 |
20 |
3.000| -1.16992203 | 0.00000000 |
30 |
4.500| -0.72347868 | -0.00000002 |
40 |
6.000| -0.41127922 | -0.00000094 |
50 |
7.500| -0.29834817 | -0.00002427 |
60 |
9.000| -0.23577373 | -0.00035044 |
70 |
10.500| -0.19532474 | 0.00000311 |
80 |
12.000| -0.16688911 | 0.00010812 |
90 |
13.500| -0.14582895 | 0.00022987 |
100 |
15.000| -0.12957000 | 0.00033802 |
110 |
16.500| -0.11631732 | 0.00025752 |
120 |
18.000| -0.06945640 | 0.00019346 |
----------------------------------------------------------------------------Done.
If it Doesn’t Work ...







Read the Thorn Writers chapter in the documentation
Remember that the Fortran code is preprocessed, to see the
postprocessed code that is actually compiled, look in
<config>/build/<thorn> (wave/build/WaveToyF77)
Run with a high warning level and read all the warning
messages
Review the parameters for the thorns you are using, they
often have some debugging features (PUGH, enable_all_storage)
Submit bug reports via www.CactusCode.org
Join the relevant mailing lists via www.CactusCode.org
Contact cactusmaint@cactuscode.org
Download