# DG method with periodic boundary condition

**URL:** https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943
**Category:** General Discussion
**Created:** [May 27, 2025, 12:11pm UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943 "2025-05-27T12:11:05Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 27, 2025, 12:11pm UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/1 "2025-05-27T12:11:05Z")

</div>

I don’t know how to deal with the periodic bcd in DG method.  
I have successfully finished the Dirichlet or Nuemann bcd for Poisson equation with DG method.  
I set the left and right bcd is periodic, and the main difficult is how to deal jump and penalty term on left or right bcd.  
Looking forward to one’s reply and help!

```auto
// solve poisson equation
int MaxIter = 6;
// mesh size [4 * 4], [8 * 8], ... ,[2 ^ (MaxIter + 1), 2 ^ (MaxIter + 1)]
real[int] errL2(MaxIter), errInf(MaxIter), errH1(MaxIter);
real[int] orderL2(MaxIter), orderInf(MaxIter), orderH1(MaxIter);
func rhs = 8 * pi ^ 2 * sin(2 * pi * x) * cos(2 * pi * y);
func uExact = sin(2 * pi * x) * cos(2 * pi * y);
func udxExact = 2 * pi * cos(2 * pi * x) * cos(2 * pi * y);
func udyExact = -2 * pi * sin(2 * pi * x) * sin(2 * pi * y);
func uBcd = 0;
real cpu = clock();
real penalty = 20.0; 
// mesh iteration
for (int i = 0; i < MaxIter; i++){
    mesh Th = square(2 ^ (i + 2), 2 ^ (i + 2));
    fespace Vh(Th, P1dc, periodic = [[2, y], [4, y]]);
    Vh u, v;
    solve Poisson(u, v, solver=UMFPACK) = int2d(Th)(dx(u) * dx(v) + dy(u) * dy(v))
	- intalledges(Th)((1 - nTonEdge) * (mean(dx(u)) * jump(v) * N.x + mean(dy(u)) * jump(v) * N.y
        + mean(dx(v)) * jump(u) * N.x + mean(dy(v)) * jump(u) * N.y) / 2)
	+ intalledges(Th)((1 - nTonEdge) * (penalty / lenEdge * jump(u) * jump(v)) / 2)
    ////////////////////////////////////////////////////////////////////////////////////////////////////
	- intalledges(Th, 4)((mean(dx(u)) * jump(v) * N.x + mean(dy(u)) * jump(v) * N.y
        + mean(dx(v)) * jump(u) * N.x + mean(dy(v)) * jump(u) * N.y))
	+ intalledges(Th, 4)((penalty / lenEdge * jump(u) * jump(v)))
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    - int2d(Th)(rhs * v);
    // error
    errL2[i] = sqrt(int2d(Th)((u - uExact) ^ 2));
    Vh absError = abs(u - uExact);
    errInf[i] = absError[].max;
    Vh udx = dx(u), udy = dy(u);
    errH1[i] = sqrt(int2d(Th)((udx - udxExact) ^ 2) + int2d(Th)((udy - udyExact) ^ 2));
}
for (int i = 1; i < MaxIter; i++){
    orderL2[i] = log(errL2[i - 1] / errL2[i]) / log(2.);
    orderInf[i] = log(errInf[i - 1] / errInf[i]) / log(2.);
    orderH1[i] = log(errH1[i - 1] / errH1[i]) / log(2.);
}
cout << "================OUTPUT===============" << endl;
cout << "CPU time = " << clock() - cpu << endl;
cout << "errors and convergence rates = " << endl;
cout << "h\t L2 error\t order\t\t Inf error\t order\t\t H1_semi error\t order" << endl;
for (int i = 0; i < MaxIter; i++){
    cout << "1/" << 2 ^ (i + 2) << ":\t" 
    << errL2[i] << "\t" << orderL2[i] << "\t\t" 
    << errInf[i] << "\t" << orderInf[i] << "\t\t" 
    << errH1[i] << "\t" << orderH1[i] << "\t" << endl;
}

```

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 1:57am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/2 "2025-05-29T01:57:10Z")

</div>

Dear all  
After a day of trying, I still couldn’t write the correct code. I finally decided to give up this problem, hoping that it could be solved one day

> // solve poisson equation  
> int MaxIter = 1;  
> // mesh size [4 \* 4], [8 \* 8], … ,[2 ^ (MaxIter + 1), 2 ^ (MaxIter + 1)]  
> real[int] errL2(MaxIter), errInf(MaxIter), errH1(MaxIter);  
> real[int] orderL2(MaxIter), orderInf(MaxIter), orderH1(MaxIter);  
> func rhs = 8 \* pi ^ 2 \* sin(2 \* pi \* x) \* cos(2 \* pi \* y);  
> func uExact = sin(2 \* pi \* x) \* cos(2 \* pi \* y);  
> func udxExact = 2 \* pi \* cos(2 \* pi \* x) \* cos(2 \* pi \* y);  
> func udyExact = -2 \* pi \* sin(2 \* pi \* x) \* sin(2 \* pi \* y);  
> func uBcd = 0;  
> // func real[int] Tp(real[int] X) {  
> // real[int] Y(2);  
> // Y[0] = X[0] - 1.0;  
> // Y[1] = X[1];  
> // return Y;  
> // }  
> real cpu = clock();  
> real penalty = 20.0;  
> // mesh iteration  
> for (int i = 0; i \< MaxIter; i++){  
> int n = 2^(i+2);  
> mesh Th = square(2 ^ (i + 2), 2 ^ (i + 2), flags=1);  
> fespace Vh(Th, P1dc, periodic = [[2, y], [4, y]]);  
> Vh u, v;  
> problem Poisson(u, v, solver=UMFPACK) = int2d(Th)(dx(u) \* dx(v) + dy(u) \* dy(v))  
> - intalledges(Th)((1 - nTonEdge) \* (mean(dx(u)) \* jump(v) \* N.x + mean(dy(u)) \* jump(v) \* N.y  
> + mean(dx(v)) \* jump(u) \* N.x + mean(dy(v)) \* jump(u) \* N.y) / 2)  
> + intalledges(Th)((1 - nTonEdge) \* (penalty / lenEdge \* jump(u) \* jump(v)) / 2)  
> //////////////////////////////////////////////////  
> // - int1d(Th, 2)((mean(dx(u)) \* jump(v) \* N.x + mean(dy(u)) \* jump(v) \* N.y  
> // + mean(dx(v)) \* jump(u) \* N.x + mean(dy(v)) \* jump(u) \* N.y))  
> // + int1d(Th, 2)((penalty / lenEdge \* jump(u) \* jump(v)))  
> + int1d(Th, 2)(penalty / lenEdge \* u \* v)  
> - int1d(Th, 2, mapu=[x-1, y])(penalty / lenEdge \* u \* v)  
> - int1d(Th, 2, mapt=[x-1, y])(penalty / lenEdge \* u \* v)  
> + int1d(Th, 4)(penalty / lenEdge \* u \* v)  
> //////////////////////////////////////////////////  
> - int2d(Th)(rhs \* v);
> 
> ```
> Poisson;
> // error
> errL2[i] = sqrt(int2d(Th)((u - uExact) ^ 2));
> Vh absError = abs(u - uExact);
> errInf[i] = absError[].max;
> Vh udx = dx(u), udy = dy(u);
> errH1[i] = sqrt(int2d(Th)((udx - udxExact) ^ 2) + int2d(Th)((udy - udyExact) ^ 2));
> 
> ```
> 
> }  
> for (int i = 1; i \< MaxIter; i++){  
> orderL2[i] = log(errL2[i - 1] / errL2[i]) / log(2.);  
> orderInf[i] = log(errInf[i - 1] / errInf[i]) / log(2.);  
> orderH1[i] = log(errH1[i - 1] / errH1[i]) / log(2.);  
> }  
> cout \<\< “================OUTPUT===============” \<\< endl;  
> cout \<\< "CPU time = " \<\< clock() - cpu \<\< endl;  
> cout \<\< "errors and convergence rates = " \<\< endl;  
> cout \<\< “h\t L2 error\t order\t\t Inf error\t order\t\t H1\_semi error\t order” \<\< endl;  
> for (int i = 0; i \< MaxIter; i++){  
> cout \<\< “1/” \<\< 2 ^ (i + 2) \<\< “:\t”  
> \<\< errL2[i] \<\< “\t” \<\< orderL2[i] \<\< “\t\t”  
> \<\< errInf[i] \<\< “\t” \<\< orderInf[i] \<\< “\t\t”  
> \<\< errH1[i] \<\< “\t” \<\< orderH1[i] \<\< “\t” \<\< endl;  
> }

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 5:40am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/3 "2025-05-29T05:40:13Z")

</div>

Could you please upload your scheme here, along with all the details you intend to implement in the FreeFEM++ code?.

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 6:28am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/4 "2025-05-29T06:28:46Z")

</div>

Thanks for your reply!!

 ![equation](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/6/6b3147866845a089953539906b8ac264f08fed3b.png)

To present the problem more clearly, I uploaded the code of this equation under the Dirichlet and Nuemann boundary conditions.

I think the key challenge lies in integrating along the periodic boundary by treating it as an interior edge.  
[poisson\_dg\_SIPG\_dirichlet.edp](https://community.freefem.org/uploads/short-url/fyfbXzry5W9bhZIF4JI30CpbhlD.edp) (2.2 KB)  
[poisson\_dg\_SIPG\_nuemann.edp](https://community.freefem.org/uploads/short-url/lqzm3103GsiRCclKHpyTjPr13Nn.edp) (2.1 KB)

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 6:37am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/5 "2025-05-29T06:37:31Z")

</div>

Could you please tell me what periodic boundary conditions you want to implement in the code?.

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 6:52am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/6 "2025-05-29T06:52:48Z")

</div>

Thank you so much for your response!  
I want to implement the periodic boundary conditions on the left (4) and right (2) boundaries, i.e., u(0,y)=u(1,y).

`fespace Vh(Th, P1dc, periodic = [[2, y], [4, y]]);`

The upper and lower boundaries I use 0 nuemann.

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 6:54am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/7 "2025-05-29T06:54:43Z")

</div>

[Poisson\_Periodic\_DG\_MI.edp](https://community.freefem.org/uploads/short-url/ouyCtqif3xkdKslUfsjfnJTffUz.edp) (3.5 KB)  
(Can you please arrange the output properly).

I hope results will comes goods. There are some silly errors in codes. I will check it. Can you send me the code by arranging the output properly?.

 ![image](https://canada1.discourse-cdn.com/flex030/uploads/freefem/original/2X/3/303c3c5be75f1a3db809399c08bcc3cd25444dc0.png)  
(Need to write infimum error and H1\_semi error properly format).

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 7:23am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/8 "2025-05-29T07:23:02Z")

</div>

I have modified the layout of the output  
[Poisson\_Periodic\_DG\_MI.edp](https://community.freefem.org/uploads/short-url/w9HUxzcESVKvZxMFYQ8nhmnbE49.edp) (3.1 KB)

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 7:34am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/9 "2025-05-29T07:34:40Z")

</div>

[Poisson\_Periodic\_DG\_MI.edp](https://community.freefem.org/uploads/short-url/dSOtp2F2Rjs3Y3fl0YkJ3Z9W7Rp.edp) (4.6 KB)  
(Increase your penality parameter).

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 7:39am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/10 "2025-05-29T07:39:01Z")

</div>

[Poisson\_Periodic\_DG\_MI(Latest).edp](https://community.freefem.org/uploads/short-url/qpyXFaJ5ouOQJOMQI9YoRLDWoPa.edp) (3.1 KB)  
(Result getting improve if you increase penality parameter)

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 7:46am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/11 "2025-05-29T07:46:08Z")

</div>

Thanks for your reply!  
I observed that under the low penalty parameter, when I set the number of grids to 512 or bigger, the error was not consistent with the theoretical result.  
Is this because the `jump` term was not considered in `int1d(Th, 2)` and `int1d(Th, 4)`?  
Should this part be taken into account?

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 29, 2025, 7:50am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/12 "2025-05-29T07:50:19Z")

</div>

Your intalleges terms are not properly wriiten. I will share a refine version of it to you today.  
Regarding low penality, penality parameter depends on methods.

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 29, 2025, 7:53am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/13 "2025-05-29T07:53:25Z")

</div>

OK! I am extremely grateful for your sharing and correction!

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 30, 2025, 2:11am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/14 "2025-05-30T02:11:13Z")

</div>

Dear Monirul,

I’m very sorry to bother you again, but I’m still having trouble identifying what is wrong with the intalledges terms in my DG implementation.

I would greatly appreciate it if you could share your refined version of the intalledges terms.

Thank you so much for your time and help.

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 30, 2025, 2:31am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/15 "2025-05-30T02:31:53Z")

</div>

Your code is correct but not written in a proper way. If you use definition of macro for the Neumann derivative term inside intalledges term then it will look goods. Okay. I will share you today.

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 30, 2025, 2:45am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/16 "2025-05-30T02:45:45Z")

</div>

Sure, really appreciate it!!!

---

<div class="post-metadata">

### Author: ![Monirul25](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/monirul25/32/3287_2.png) [@Monirul25](https://community.freefem.org/u/Monirul25)
#### Post date: [May 30, 2025, 3:41am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/17 "2025-05-30T03:41:54Z")

</div>

Your formulation are different brother. Macro definition is not working in your formulations.  
I have seen in intalledges term, you are dividing by 2. But it should be divide by nTonEdge although your code gives good results.

---

<div class="post-metadata">

### Author: ![kail](https://avatars.discourse-cdn.com/v4/letter/k/cdc98d/32.png) [@kail](https://community.freefem.org/u/kail)
#### Post date: [May 30, 2025, 4:33am UTC](https://community.freefem.org/t/dg-method-with-periodic-boundary-condition/3943/18 "2025-05-30T04:33:04Z")

</div>

nTonEdge = 2 on the inner edge, so I directly divide by 2.  
Anyway, thanks a lot for your reply!
