I have two question regarding to the efficient implementation of boundary conditions.
To be more specific, I am solving the transport equation:
u_t + u_x +u_y = 0
on the unit square with time-dependent boundary data at the left and bottom boundaries.
The exact solution is
exact_solution = sin(pi(x+y-2t))
I modified the timeDG-skeleton.py file to include the correct boundary condition in each time step:
while t < tend:
....
a += SymbolicBFI ( (bn*IfPos(bn, 0, -u0(t)+u0(t+tau)) * v), BND, skeleton=True)
t += tau
Here a is the DG bilinear form.
While this approach gave me correct result as I wanted, but it is extremely slow, and the time does not scale linearly on the number of iterations.
E.g., in the following sample code, I am using Forward Euler + DGP0,
with cfl = 0.5, elapsted time is 0.11 sec
with cfl = 0.05, elapsted time is 4.3 sec
Then, I commented out the above boundary term, I got back the linear scaling:
with cfl = 0.5, elapsted time is 0.06 sec
with cfl = 0.05, elapsted time is 0.6 sec
My first question is:
Is there a way to impose boundary condition more efficiently? I think I am missing something here....
My second question is:
Is it easy to obtain a mesh with periodic boundary? (ideally, I want a unit square periodic boundary mesh and a unit cube periodic boundary mesh...) :>
If so (and if it's easy), can some of you modify my file in the next post to include periodic boundary?
I need to check order of accuracy of my scheme without worrying about boundary effect...
Many thanks,
Guosheng
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What you do in your script is to define a "bilinear" form and add integrators and in each time step you add another integrator. So when "Apply"ing every integrator will be asked to apply his stuff. So, with increasing number of steps you have an increasing amount of work for every time step. What you would like to have is to (only) use
a += SymbolicBFI ( (bn*IfPos(bn, u, u0) * v), BND, skeleton=True)
before the time loop and you want u0 to evaulate differently for different time stages. You can achieve this with "Parameter"s now (needs recent git-master or the Number-FESpace workaround).
You create a parameter representing your time value:
param_t = Parameter(0.0)
and express your u0 depending on this parameter
u0 = sin(pi*(x+y-2*param_t))
Now whenever Apply(..) (or Assemble()) is called u0 is the CoefficientFunction that evaluates depending on the value of param_t at call-time.
In your case this implies that you don't need to add an Update-version of the boundary values to your list.
In order to update the parameter within the time loop just call
param_t.Set(t)
When I do this update of your script, I get the linear scaling again (see attachment).
Concerning periodic boundaries:
Sorry, I don't have a simple answer to that, but will write down my thoughts on this anyway:
Netgen is capable of representing periodic boundaries and generating meshes with periodically matching boundaries. However, the usage of periodic boundaries is not standard in NGSolve FESpaces or (for DG) the assembly routines. But in the "my_little_ngsolve" project we have an example on how to construct a periodic H1-FESpace, but I assume that you want to have this for DG and thus the skeleton-assembly / skeleton-term-application needs to care about this as well.
If you just want to compute on squares and cubes, it may be possible to just construct the mesh so that connectivities already correspond to a periodic domain, but I never tried this and I am not sure if this would work. So, I have to pass this question to the developers.
Hi guys,
I have two question regarding to the efficient implementation of boundary conditions.
To be more specific, I am solving the transport equation:
u_t + u_x +u_y = 0
on the unit square with time-dependent boundary data at the left and bottom boundaries.
The exact solution is
exact_solution = sin(pi(x+y-2t))
I modified the timeDG-skeleton.py file to include the correct boundary condition in each time step:
Here a is the DG bilinear form.
While this approach gave me correct result as I wanted, but it is extremely slow, and the time does not scale linearly on the number of iterations.
E.g., in the following sample code, I am using Forward Euler + DGP0,
with cfl = 0.5, elapsted time is 0.11 sec
with cfl = 0.05, elapsted time is 4.3 sec
Then, I commented out the above boundary term, I got back the linear scaling:
with cfl = 0.5, elapsted time is 0.06 sec
with cfl = 0.05, elapsted time is 0.6 sec
My first question is:
Is there a way to impose boundary condition more efficiently? I think I am missing something here....
My second question is:
Is it easy to obtain a mesh with periodic boundary? (ideally, I want a unit square periodic boundary mesh and a unit cube periodic boundary mesh...) :>
If so (and if it's easy), can some of you modify my file in the next post to include periodic boundary?
I need to check order of accuracy of my scheme without worrying about boundary effect...
Many thanks,
Guosheng
Here is the code...
Dear Guosheng,
What you do in your script is to define a "bilinear" form and add integrators and in each time step you add another integrator. So when "Apply"ing every integrator will be asked to apply his stuff. So, with increasing number of steps you have an increasing amount of work for every time step. What you would like to have is to (only) use
before the time loop and you want u0 to evaulate differently for different time stages. You can achieve this with "Parameter"s now (needs recent git-master or the Number-FESpace workaround).
You create a parameter representing your time value:
and express your u0 depending on this parameter
Now whenever Apply(..) (or Assemble()) is called u0 is the CoefficientFunction that evaluates depending on the value of param_t at call-time.
In your case this implies that you don't need to add an Update-version of the boundary values to your list.
In order to update the parameter within the time loop just call
When I do this update of your script, I get the linear scaling again (see attachment).
Concerning periodic boundaries:
Sorry, I don't have a simple answer to that, but will write down my thoughts on this anyway:
Netgen is capable of representing periodic boundaries and generating meshes with periodically matching boundaries. However, the usage of periodic boundaries is not standard in NGSolve FESpaces or (for DG) the assembly routines. But in the "my_little_ngsolve" project we have an example on how to construct a periodic H1-FESpace, but I assume that you want to have this for DG and thus the skeleton-assembly / skeleton-term-application needs to care about this as well.
If you just want to compute on squares and cubes, it may be possible to just construct the mesh so that connectivities already correspond to a periodic domain, but I never tried this and I am not sure if this would work. So, I have to pass this question to the developers.
Best,
Christoph
I see. Thanks!
Best,
Guosheng