3D mesh: periodic boundary conditions and unstructured mesh

Dear Community,

I understand that the faces have to be the same for periodic boundary conditions, but I also would like to use an unstructured mesh. Does anyone know how I can accomplish this? The code below is what does not work at the moment.

// build an unstructured mesh for the cube
// run in terminal with FreeFEM++ unstrucCubeMesh.edp

load "distance"
load "msh3"
load "tetgen"
load "medit"
load "mshmet"
load "iovtk"

include "Cube.idp"

int[int] NN = [10,10,10]; //the number of step in each direction
real [int, int] BB = [[0,1],[0,1],[0,1]]; //the bounding box
int [int, int] LB = [[1,2],[3,4],[5,6]]; //the label of the 6 face left,right, front, back, down, right
mesh3 Th = Cube(NN, BB, LB);

medit("Th", Th);
real L = 1.;
int meshSize = 30.;
real[int] domain = [0, 0, 0, 0, 1];

Th = tetgreconstruction(Th, switch = "raAQ", regionlist = domain, sizeofvolume = (L*1./meshSize)^3/6);

medit("Th", Th);

fespace Vh(Th, P1, periodic = [[5, x, y], [6, x, y]]); // periodic boundary conditions on z = 0, 1

Use Mmg with the parameter requiredTriangle.

Thank you! So this would be instead of tetgen right?

I’ve found this example using mshmet and mmg (laplace-adapt-aniso-3d.edp). Basically all the examples I’m finding with mmg are using mshmet. I’m trying to understand the parameters here, but don’t understand this metric parameter. In the below code I am trying to just understand how things work without solving poisson.


{
load "msh3"
load "tetgen"
load "mshmet"
load "medit"
load "mmg"

int nn  = 6;

int[int] lc=[1,2,2,1,1,2]; //  label numbering

mesh3 Th3=cube(nn,nn,nn,label=lc);
Th3 = trunc(Th3,(x<0.5) | (y < 0.5) | (z < 0.5) ,label=1);

//fespace Vh(Th3,P1);
fespace Mh(Th3,[P1,P1,P1,P1,P1,P1]);
//Vh u,v,usol,h3;
Mh [m11,m21,m22,m31,m32,m33];
//macro Grad(u) [dx(u),dy(u),dz(u)] // EOM

//problem Poisson(u,v,solver=CG) = int3d(Th3)( Grad(u)'*Grad(v) )  // ') for emacs
//  -int3d(Th3)( 1*v ) + on(1,u=0);

real lerr=0.05;
verbosity=4;

//for(int ii=0; ii<4; ii++) //  BUG trap  in interation 3
//{
  ///Poisson;
  //plot(u,wait=1);
  //h3=0;
  [m11,m21,m22,m31,m32,m33]=[0,0,0,0,0,0];
  //cout <<" u min, max = " <<  u[].min << " "<< u[].max << endl;
  //real cc=(u[].max-u[].min);// rescale coefficiant

  real[int] met=mshmet(Th3,hmin=1e-3,hmax=0.2,err=lerr,aniso=1);
  m11[]=met;
//  savemesh(Th3,"oo/Th3.mesh");
//  savesol("oo/Th3.sol",Th3, [m11,m21,m22,m31,m32,m33]);
//  exec("mmg3d_O3 oo/Th3.mesh -sol oo/Th3.sol -hgrad 2.3 -bucket 700 -v 3");
  Th3=mmg3d(Th3,metric=m11[],hgrad=2.3);//("oo/Th3.o.mesh");
  plot(Th3);

  lerr *= 0.6;// change the level of error
  cout << " Th3" << Th3.nv < " " << Th3.nt << endl;
  // u=u;
  //if(ii>3) medit("U-adap-iso-"+ii,Th3,u,wait=1);

cout <<"end Laplace  Adapt aniso 3d. edp " <<endl;

}


You would be using Mmg instead of TetGen indeed. If you do not want to use a metric, you can adapt the mesh with respect to some other quantities, such as a level-set function. There are some more examples in the distribution.

I think there are options to freeze the boundary meshes within tetgen… from some old codes, I think the option for tetgen switch="pqaAAYYQ"does the job… in any case, this should be available in the documentation
hope this helps.

1 Like

Thank you Julien! I was looking around in the documentation, this will help refine my search :slight_smile:

Just for anyone who comes across this, adding the YY to my switch seemed to work, as it seems it is supposed to fix the boundaries to be the same.