This tutorial provides a step by step introduction to setting up a simulation of Maxwell equations in a homogenus media. For the simulation domain we will use a periodic cube.
We assume that you already have read the General Procedure for Running the Testcases and the General Input File Information.
In this tutorial, we will show and examine the input file for the Maxwell
testcase in tutorial/testcase/maxwell/ateles.lua
.
Because this input file is specifically designed for the Maxwell testcase,
it does not make use of all the available options.
A complete input file with all available settings
can be found in the ateles folder ateles/ateles.lua
.
First we give all the general settings for the simulation.
Since we are going to simulate a periodic oscillator using modal
DG
scheme,
we set the name of the simulation to posci_modg
.
We will simulate seconds
and every 10th iteration we get information about the current timestep
printed to the screen during the simulation.
-- global simulation options
simulation_name = 'posci_modg' -- the name of the simualtion
sim_control = {
time_control = {
interval = {iter = 10},
min = 0.0,
max = math.sqrt(2), -- final simulation time
}
}
Further, the solver needs a defined geometry.
In this testcase we use a pre-defined geometry (cube
),
which is just a simple cube with periodic boundaries and no obstacles.
We set the length
of this cube to be 2 meter
and choose a refinementLevel
of 2
(the space is cut into 4 () portions in each dimension). We position
the cube's center to the point x=0, y=0, z=0 by moving it half of it's width to
x-, y- and z-.
-- mesh definitions
cubeLength = 2.0
mesh = {
predefined = 'cube',
origin = {
(-1.0) * cubeLength / 2.0,
(-1.0) * cubeLength / 2.0,
(-1.0) * cubeLength / 2.0
},
length = cubeLength,
refinementLevel = 2
}
It is possible to define global parameters in Lua, which is a convenient way if some parameters are used several times or need to be changed frequently for e.g. a parameter study. Hence, we define some parameters, which will be used below in the function set.
-- some global parameters for the T_{nm} mode testcase
amplX = 1.0 -- the integer number of the mode in x direction
amplY = 1.0 -- the integer number of the mode in y direction
Lua also supports defining functions in the global scope. For this testcase, there exists an analytical solution if . Hence, we define functions which are time and space depended for the temporal angular frequency which is then used in the functions for the electric and magnetic field in each direction. Moreover, we specify a function for the initial condition of the electric field in the z direction.
-- the analytic solution for this testcase is given by the following functions
-- (only correct for epsi = mu = 1):
-- ... definition of temporal angular frequency
w = math.sqrt(amplX^2 + amplY^2)
-- ... E_x = 0.0
function electricX(x, y, z, t)
return 0.0
end
-- ... E_y = 0.0
function electricY(x, y, z, t)
return 0.0 -- math.sin(amplX * math.pi * x) * math.sin(amplY * math.pi * z) * math.cos(w * t)
end
-- ... E_z(x, y, z, t) = sin(amplX \pi x) sin(amplY \pi y) cos(w t)
function electricZ(x, y, z, t)
return math.sin(amplX * math.pi * x) * math.sin(amplY * math.pi * y) * math.cos(w * t)
end
-- ... B_x(x, y, z, t) = -\frac{\pi n}{w} sin(m \pi x) cos(n \pi y) sin(w t)
function magneticX(x, y, z, t)
return (-1.0) * (math.pi * amplY/w) * math.sin(amplX * math.pi * x) * math.cos(amplY * math.pi * y) * math.sin(w * t)
end
-- ... B_y(x, y, z, t) = \frac{\pi m}{w} cos(m \pi x) sin(n \pi y) sin(w t)
function magneticY(x, y, z, t)
return (math.pi * amplX / w) * math.cos(amplX * math.pi * x) * math.sin(amplY * math.pi * y) * math.sin(w * t)
end
-- ... B_z = 0.0
function magneticZ(x, y, z, t)
return 0.0 -- (math.pi * amplX / w) * math.cos(amplX * math.pi * x) * math.sin(amplY * math.pi * z) * math.sin(w * t )
end
Next, the solver requires an initial condition. Since we are considering the Maxwell equations, the electric and magnetic field in each direction has to be defined.
-- initial condition
-- ...initial condition function for electric field (z component)
function ic_electricZ(x, y, z)
return electricZ(x, y, z, 0.0)
end
initial_condition = {
displacement_fieldX = 0.0, -- electric field , x component
displacement_fieldY = 0.0, -- electric field , z component
displacement_fieldZ = ic_electricZ, -- electric field , z component
magnetic_fieldX = 0.0, -- magnetic induction , x component
magnetic_fieldY = 0.0, -- magnetic induction , y component
magnetic_fieldZ = 0.0, -- magnetic induction , z component
}
Of course, we need to define the parameter
for the scheme using the variable scheme
.
The scheme is further split into the spatial and temporal discretization, each
described in a correspondigly named variable.
-- scheme definitions
scheme = {
-- the spatial discretization scheme
spatial = {
name = 'modg', -- we use the modal discontinuous Galerkin scheme
m = 4, -- the maximal polynomial degree for each spatial direction
modg_space = 'Q',
},
-- the temporal discretization scheme
temporal = {
name = 'explicitRungeKutta',
steps = 4,
-- how to control the timestep
control = {
name = 'cfl', -- the name of the timestep control mechanism
cfl = 0.095, -- Courant-Friedrichs-Levy number
}
}
}
For the spatial discretization scheme,
the parameter name
specifies which scheme is used
whereby modg
is the predfined name for modal discontinious Galerkin scheme.
Moreover, the parameter m
defines the maximal polynomial degree
for each spatial direction, while modg_space
defines
which polynomial space (P or Q) is used for the approximation.
Similary, for the temporal discretization scheme
the parameter name
defines which scheme should be used.
Here we use the predefined name explicitRungeKutta
.
To perform the classical four-step
Runge-Kutta scheme,
the parameter steps
is set to 4
.
Since it is an explicit time stepping scheme,
each timestep needs to be controlled.
Therefore, we set the control
variables as above.
In Ateles this is done by the Courant-Friedrichs-Lewy- or CFL-condition.
The parameter cfl
defines the cfl number
which depends on the spatial discretiztion.
Here, we define which system of equations should be solved.
-- equation definitions
equation = {
name = 'maxwell', -- we solve maxwell's equations
material = {
permeability = 'global_maxwell_permeability',
permittivity = 'global_maxwell_permittivity',
conductivity = 'global_maxwell_conductivity'
}
}
Since this is the maxwell testcase,
we define name= 'maxwell'
which is a predefined name in the Ateles solver.
Additionally, for the maxwell equation system,
the magnetic permeability, electric permitivity
and conductivity need to be set.
This is done with a material table.
In this table we are using variables which we define in the next section.
We define the global material for Maxwell. It consists of three different components:
Each is a scalar, so we need three sclars for this equation system. As this is the global fallback material, we define each material to be a neutral term, which in this case is 0.
-- Maxwell material parameters
mu = 1.0 -- the magnetic permeability (vacuum has 4.0 * math.pi * (10.0^(-7.0)))
epsi = 1.0 -- the electric permitivity (vacuum has 8.85418781762 * (10.0^(-12.0)))
conductivity = 0.0
variable = {
-- This is the global material for Maxwell.
-- It consists of three different components,
-- permeability, permittivity, and conductivity, each a scalar,
-- so that we need three scalars for this equation system.
-- As this is the global fallback material, we define each material to be a neutral term,
-- which in this case is 0.
{
name = "global_maxwell_permeability",
ncomponents = 1,
vartype = "st_fun",
st_fun = { const = mu }
},
{
name = "global_maxwell_permittivity",
ncomponents = 1,
vartype = "st_fun",
st_fun = { const = epsi }
},
{
name = "global_maxwell_conductivity",
ncomponents = 1,
vartype = "st_fun",
st_fun = { const = conductivity }
}
}
Finally, we set the parameters for writing restart files.
-- configuration for the restart file
restart = {
---- file to restart from
--read = './restart/posci_modg_lastHeader.lua',
-- folder to write restart data to
write = 'restart/',
-- temporal definition of restart write
time_control = {
min = 0.0,
max = sim_control.time_control.max,
interval = sim_control.time_control.max/5
}
}
When you run the simulation, make sure that you are calling the solver Ateles
from the folder where the configuration file resides. This is
tutorial/testcase/maxwell/ateles.lua
. When calling it from another folder,
you also need to create the restart folder somewhere else, which will cause
some problems later on. First of all you have to take more care when calling
the postprocessing tool in the next step, but it is also easier to recap in
future, when the simulation input and output are stored in the same folder.