Remeshing with CASHOCS¶
Problem Formulation¶
In this tutorial, we take a close look at how remeshing works in CASHOCS. To keep this discussion simple, we take a look at the model problem already investigated in Shape Optimization with a Poisson Problem, i.e.,
As before, we use the unit disc \(\Omega = \{ x \in \mathbb{R}^2 \,\mid\, \lvert\lvert x \rvert\rvert_2 < 1 \}\), as initial geometry, and the right-hand side \(f\) is given by
Implementation¶
The complete python code can be found in the file demo_remeshing.py
,
and the corresponding config can be found in config.ini
.
The corresponding mesh files are ./mesh/mesh.geo
and
./mesh/mesh.msh
.
Pre-Processing with GMSH¶
Before we can start with the actual CASHOCS implementation of remeshing, we have to take a closer look at how we can define a geometry with GMSH. For this, .geo files are used.
Hint
A detailed documentation and tutorials regarding the generation of geometries and meshes with GMSH can be found here.
The file ./mesh/mesh.geo
describes our geometry.
Important
Any user defined variables that should be also kept for the remeshing, such as the characteristic lengths, must be lower case, so that CASHOCS can distinguish them from the other GMSH commands. Any user defined variable starting with an upper case letter is not considered for the .geo file created for remeshing and will, thus, probably cause an error.
In our case of the .geo file, the characteristic length is defined as lc
,
and this is used to specify the (local) size of the discretization via so-called
size fields. Note, that this variable is indeed taken into consideration for
the remeshing as it starts with a lower case letter.
The resulting mesh file was created over the command line with the command
gmsh ./mesh/mesh.geo -o ./mesh/mesh.msh -2
Note
For the purpose of this tutorial it is recommended to leave the ./mesh/mesh.msh
file as it is. In particular, carrying out the above command will overwrite
the file and is, thus, not recommended. The command just highlights, how one
would / could use GMSH to define their own geometries and meshes for CASHOCS
or FEniCS.
The resulting file is ./mesh/mesh.msh
.
This .msh file can be converted to the .xdmf format by using cashocs-convert
as follows:
cashocs-convert ./mesh/mesh.msh ./mesh/mesh.xdmf
from the command line.
Hint
As the cashocs-convert merely converts the .msh file to .xdmf, the user may very well use this command.
To ensure that CASHOCS also finds these files, we have to specify them in the file
config.ini
.
For this, we have the following lines
[Mesh]
mesh_file = ./mesh/mesh.xdmf
gmsh_file = ./mesh/mesh.msh
geo_file = ./mesh/mesh.geo
remesh = True
show_gmsh_output = True
With this, we have specified the paths to the mesh files and also enabled the remeshing as well as the verbose output of GMSH to the terminal, as explained in the corresponding documentation of the config files.
Note
Note, that the paths given in the config file can be either absolute or relative. In the latter case, they have to be relative to the location of the CASHOCS script which is used to solve the problem.
With this, we can now focus on the implementation in python.
Initialization¶
The program starts as Shape Optimization with a Poisson Problem, with the following lines
from fenics import *
import cashocs
config = cashocs.load_config('./config.ini')
with which we import FEniCS and CASHOCS, and read the config file. The mesh and all other related objects are created with the command
mesh, subdomains, boundaries, dx, ds, dS = cashocs.import_mesh(config)
Note, that in contrast to Shape Optimization with a Poisson Problem, we cannot use a built-in mesh for this tutorial since remeshing is only available for meshes generated by GMSH.
Important
It is important to note that we have to pass the config as argument to
import_mesh
. The alternative syntax
mesh, subdomains, boundaries, dx, ds, dS = cashocs.import_mesh(./mesh/mesh.xdmf)
is NOT equivalent for remeshing, even though the definition in the config file points to the same object, where the corresponding line reads
mesh_file = ./mesh/mesh.xdmf
Definition of the state system¶
The definition of the state system is now completely analogous to the one in Shape Optimization with a Poisson Problem. Here, we just repeat the code for the sake of completeness
V = FunctionSpace(mesh, 'CG', 1)
u = Function(V)
p = Function(V)
x = SpatialCoordinate(mesh)
f = 2.5*pow(x[0] + 0.4 - pow(x[1], 2), 2) + pow(x[0], 2) + pow(x[1], 2) - 1
e = inner(grad(u), grad(p))*dx - f*p*dx
bcs = DirichletBC(V, Constant(0), boundaries, 1)
The shape optimization problem¶
The definition of the ShapeOptimizationProblem
as well as its solution is now also completely analogous to Shape Optimization with a Poisson Problem,
and is done with the lines
J = u*dx
sop = cashocs.ShapeOptimizationProblem(e, bcs, J, u, p, boundaries, config)
sop.solve()
The results should look like the one of Shape Optimization with a Poisson Problem:
Note
The example for remeshing is somewhat artificial, as the problem does not actually need remeshing. Therefore, the tolerances used in the config file, i.e.,
tol_lower = 0.1
tol_upper = 0.25
are comparatively large. However, this problem still shows all relevant aspects of remeshing in CASHOCS and can, thus, be transferred to “harder” problems that require remeshing.