3D cube with 1D-Line in the middle

Hello!

I want to create a 3D cube, with labeled line* (or border) in the middle, where the tetraeders or tetrahedralization adapts or uses the vertexes of the 1D-line. Just a 3D cube with a labeled line in it as one mesh and labeled 1D entities.

Is this possible with FreeFEM and its plugins or do I need external Mesh-Generator-Software?

*or helix

I think it is not possible with FreeFem. You could use gmsh. But then the label attached to the 1d curve will be impossible to use within FreeFem.
Instead of the label attached to the 1d curve, within FreeFem you could eventually deal with the list of vertex indices on this curve, and build a 1d meshL, independently of the 3D mesh.

Thank you for your answer, but I don’t understand.

After loading (gmshload) the gmsh-Mesh, I use the line- oder curve vertices from it, to build a meshL?

Greetings

There is no built-in command to build this meshL from the 3d mesh. What you can do is copy by hand the 1d data from the file .mesh and put them to another file, so that you can read it with FreeFem to build the meshL, by adapting to x,y,z components the example of Input Border Data from an External File in FreeFEM++ - #3 by fb77
which has only x,y components.
At the end instead of mesh Th=buildmesh(a(nborder));
you can do meshL ThL=buildmeshL(a(nborder));
Anyway I don’t see what you want to do afterwards, since in FreeFem line integrals cannot be used in variational formulations for 3d finite elements.

I rather meant from kind of vertices-coordinates-array, or similar. But doesn’t matter.

I learned on COMSOL and want to switch to FreeFEM++ now.
There I could have a line or edge helix, which I could use as current source for a 3D magnetic vector-potential field. But as I learned today (if correct), the geometrical approach with an integrated mesh isn’t neccesary.
I just don’t want to use an volumetric current source (or helix or more complex one), because of performance reasons.

Greetings

In order to build a mesh that includes the curve points as vertices you can do as follows

// read a file "mycurve.dat" containing a list of coordinates of points
// These make a curve that will be embedded in a 3d mesh
// The first line of the file "mycurve.dat" must contain the number n of points on the curve
// Then next n lines of "mycurve.dat" must contain the x, y, z coordinates of each point, separated by space


int nbpts;//number of points on the curve
real[int] ptsx;// coordinate x of points
real[int] ptsy;// coordinate y of points
real[int] ptsz;// coordinate z of points
{
 ifstream filepts("mycurve.dat");
 filepts >> nbpts;// read the number of points
 ptsx.resize(nbpts);
 ptsy.resize(nbpts);
 ptsz.resize(nbpts);
 for (int i=0;i< nbpts;i++){
  filepts >> ptsx(i) >> ptsy(i) >> ptsz(i);// read x, y, z coordinates
 }
}

load "msh3"
load "tetgen"

mesh3 Th=cube(2,2,2);// Define the mesh without the curve

real[int] xc(Th.nv),yc(Th.nv),zc(Th.nv);
for (int i=0;i<Th.nv;i++){//save the coordinates of the vertices of the mesh
 xc(i)=Th(i).x;
 yc(i)=Th(i).y;
 zc(i)=Th(i).z;
}

xc.resize(Th.nv+nbpts);
yc.resize(Th.nv+nbpts);
zc.resize(Th.nv+nbpts);
for (int j=0;j<nbpts;j++){//complete the set of vertices with the points of the curve
 xc(Th.nv+j)=ptsx(j);
 yc(Th.nv+j)=ptsy(j);
 zc(Th.nv+j)=ptsz(j);
}

Th=tetgconvexhull(xc,yc,zc);//rebuild the mesh with this extended set of vertices

plot(Th,wait=1);
//savemesh(Th,"Th.mesh");


border a(t=0.,1.;i){ x=(1.-t)*ptsx(i)+t*ptsx(i+1); y=(1.-t)*ptsy(i)+t*ptsy(i+1); z=(1.-t)*ptsz(i)+t*ptsz(i+1);label=1;}
int[int] nsub(nbpts-1);
nsub=1;
meshL ThL=buildmeshL(a(nsub));// build the 1d mesh of the curve
//plot(ThL,wait=1);

int[int] indpts(nbpts);//array giving the indices of the curve points as vertices of the 3d mesh
for (int i=0;i<Th.nv;i++){
 for (int j=0;j<nbpts;j++){
  if ((abs(Th(i).x-ptsx(j))<1.e-8)&&(abs(Th(i).y-ptsy(j))<1.e-8)&&(abs(Th(i).z-ptsz(j))<1.e-8)){
   indpts(j)=Th(i);
  }
 }
}
cout << "indpts " << indpts << endl;

it uses the file mycurve.dat, that I have taken for example

3
.3 0.1 .15
.5 .5 .5
.9 .8 .75

The script also defines the meshL for the curve, and the array indpts of vertices indices of the 3d mesh corresponding to the curve.

About your 3d magnetic problem with source term on a curve, as I said FreeFem cannot do it directly. However, knowing the array indpts you could define the matrix and right-hand side by hand and manage with it (but it may be difficult if the finite element space is too complicate).

Ok. Thank you. I understand.

I figured out to use a square with clean (means quadratic) mesh, which I distort(parallelogram) a little bit and then close it to a zylinder (both via movemesh), so I get helix-like mesh. As closed meshS I can use it with an outer cube in tetg.

But your solution I can use for more complex coils, but with meshL as basis, to get the coordinates for tetgconvexhull. I don’t want to use extern mesh-data. I think FreeFEM++ has enough meshing-potential for abstract but complex(repetitive) entities.
In future I will have more complex coils.

Greetings

Sebastian,
you can also define the curve as a parametric curve instead of using an external file:

load "msh3"
load "tetgen"

mesh3 Th=cube(2,2,2);// Define the mesh without the curve

real[int] xc(Th.nv),yc(Th.nv),zc(Th.nv);
for (int i=0;i<Th.nv;i++){//save the coordinates of the vertices of the mesh
 xc(i)=Th(i).x;
 yc(i)=Th(i).y;
 zc(i)=Th(i).z;
}


border curv(t=0.,1.){x=t+0.1*cos(2.*pi*t);y=t+0.1*sin(2.*pi*t);z=t;}//define a parametric curve
int nbpts=5;//number of points on the curve
meshL ThL=buildmeshL(curv(nbpts-1));// build the 1d mesh of the curve
//plot(ThL,wait=1);

real[int] ptsx(nbpts);// coordinate x of points on the curve
real[int] ptsy(nbpts);// coordinate y of points on the curve
real[int] ptsz(nbpts);// coordinate z of points on the curve
for (int i=0;i<nbpts;i++){
 ptsx(i)=ThL(i).x;
 ptsy(i)=ThL(i).y;
 ptsz(i)=ThL(i).z;
}
cout << "ptsx " << ptsx << endl << " ptsy " << ptsy << endl << " ptsz " << ptsz << endl;

xc.resize(Th.nv+nbpts);
yc.resize(Th.nv+nbpts);
zc.resize(Th.nv+nbpts);
for (int j=0;j<nbpts;j++){//complete the set of vertices with the points of the curve
 xc(Th.nv+j)=ptsx(j);
 yc(Th.nv+j)=ptsy(j);
 zc(Th.nv+j)=ptsz(j);
}
Th=tetgconvexhull(xc,yc,zc);//rebuild the mesh with this extended set of vertices
plot(Th,wait=1);
//savemesh(Th,"Th.mesh");

int[int] indpts(nbpts);//array giving the indices of the curve points as vertices of the 3d mesh
for (int i=0;i<Th.nv;i++){
 for (int j=0;j<nbpts;j++){
  if ((abs(Th(i).x-ptsx(j))<1.e-8)&&(abs(Th(i).y-ptsy(j))<1.e-8)&&(abs(Th(i).z-ptsz(j))<1.e-8)){
   indpts(j)=Th(i);
  }
 }
}
cout << "indpts " << indpts << endl;

Yes, I understood it.
Thank you.

Greetings