Still, how can I tell which one I have in a mesh so I can read it appropriately?
This is a user defined function. In the thread mentioned earlier, the components of this function are used separate. So I found it easier to make it a function. Why/What do I need to differently?
I do not see how in this comment is presented how to read the named boundaries from gmsh to fenics. I expected to have something reading the name boundaries and then using something like bcu_noslip = DirichletBC(V, Constant((0, 0)), mf, inflow) in order to apply the BC. Also, what do cpp, MeshFunctionSizet do?
Not sure what you mean by this. As that tutorial explains, if you do not use recombine, your mesh will consist of triangles when you call
gmsh.model.mesh.generate(2)
and tetrahedrons if you use
gmsh.model.mesh.generate(3)
As far as I can tell, you are referring to:
from dolfinx.mesh import create_mesh
from mpi4py import MPI
mesh = create_mesh(MPI.COMM_WORLD, cells, x, ufl_domain)
As I said earlier, if you are using fenics/dolfin, you should stop following the tutorial after
gmsh.write("mesh3D.msh")
cpp.MeshFunctionSizet creates the MeshFunction you can use in your snippet. Dolfin does not read in strings, so inflow has to be the integer you tagged your boundary with.
def create_mesh(mesh, cell_type): cells = numpy.vstack([cell.data for cell in mesh.cells if cell.type==cell_type]) data = numpy.hstack([mesh.cell_data_dict["gmsh:physical"][key] for key in mesh.cell_data_dict["gmsh:physical"].keys() if key==cell_type]) mesh = meshio.Mesh(points=mesh.points, cells={cell_type: cells}, cell_data={"name_to_read":[data]}) return mesh
So in order to get the inlet from the gmsh file should I write something like:
mvc = MeshValueCollection("size_t", mesh, 2)
with XDMFFile("mf.xdmf") as infile:
infile.read(mvc, "name_to_read")
mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)
bcu_noslip = DiriclhetBC(V, Constant((0,0)),mf,3)
where 3 is chosen as this boundary has defined 3rd on gmsh?
There is still no documentation to explain what these commands and their arguments are so I still don’t know what the MeshValueCollection does and what are the input both for that and the MeshFunctionSize correspond to.
I also get this error:
mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)
AttributeError: module 'mshr.cpp' has no attribute 'mesh'
I have imported the mesh in fenics now correctly, thank you for your help.
In the weak formulation, I need dx and ds. When I was generating the mesh using fenics functions, these two were computed “automatically” (I think so at least, don’t know how to say it). Do I need to compute them separately here?
Thank you!
P.S.: I saw the updated tutorials and the new tutorial for dolfin-x on your webpage. Should I move to dolfin-x? I thought that wasn’t supporting fenics.
Any measure, dx or ds In dolfin tried to extract the domain (the mesh) from the arguments in the form. If you want to make a measure with a given mesh, you can do the following:
V = FunctionSpace(mesh, "CG", 1)
u = interpolate(Expression("x[0]", degree=1), V)
dx_C = Measure("dx", domain=mesh)
print(assemble(u*dx_C), assemble(u*dx))
Note that the standard measure dx and dx_C gives the same result. A custom measure (dx_C) should be used whenever you are integrating over a subset of a volume/surface, by supplying the keyword argument: subdomain_id=meshfunction_for_entity, subdomain_id=value_in_mesh_function.
I would not suggest moving to dolfin-X just yet. Dolfin-x is the current development version of dolfin (no active development or bug fixing in the traditional dolfin/fenics).
However, as it is under development, the user interface might change rapidly.
The tutorial I’ve added on my webpage is a work in progress, which I update every time the interface of dolfin-x changes.