Calculating the elastic deformation of a sub-region: local integration and how does the Subdomain class behave?

HI everyone,

I need your help on a problem of elasticity and more precisely on a problem of integration on a sub-domain after deformation of the whole geometry.

I would like to describe the deformation of a square sub-domain strictly included in a bigger square (on wich I resolve linear elasticity equations). Thus, I would like to calculate the averaging of certain quantities (stress, strain, displacement etc) coming from this sub-region only.

I have thought about using the Subdomain class but I don’t really understand how it behaves through the deformation i.e
if I locally integrate my quantities with dx(1) (where the intiale subdomain is marked by “1”) following the resolution of the total weak problem, will this result in the correspondence “sub-domain → deformed sub-domain” or simply on the portion corresponding to the undeformed square (which I don’t want)?

Thank you in advance for your answer

PS: creating a physical surface on GMSH for the sub-square may also be possible but as my geometry is a composite, this will result in a double physical label for a single entity and I’m not sure GMSH likes it.

You should probably create a cell marker based on the subdomains before you deform the mesh. In this way, the subdomain marker is linked to the cell index, which is the same after deformation.

1 Like

Yes. As @dokken suggests you need a cell function to save the markers and then you can integrate on the subdomain using the proper label. The cell markers will never change even after extreme deformation. As for GMSH, you either aren’t doing it right or I am not understanding your point. You can have as many subdomains as you want without duplicate labels. Maybe posting a minimal code for your problem and your GMSH domain can clear things up.

1 Like

Hi dokken and nami,

@Dokken: as always, I really appreciate your assistance.
@Nami: Thank you really much for the clarifications made by your message

May I ask you another detail about integration after cell marking ?

So, I mark my cells within my sub-domain ( a subsquare of the unit square) with

mesh = UnitSquareMesh(12,12)

cellmark = CellFunction("bool", mesh)

class Subsquare(SubDomain):
     def inside(self, x, on_boundary):
         return (between(x[1], (0.25, 0.75)) and between(x[0], (0.25, 0.75)))

subsquare = Subsquare()
subsquare.mark(cellmark, True)

Now, what should I use as syntax to integrate on the subdomain in post traitement (after solving my total weak formulation) ? Does I have to use something like dx(cellmark,True) ?

For GMSH: I thought that a cell could only correspond to one physical surface label. So with this small error of appreciation, I didn’t think it was possible to superimpose different labels on the same space position.

1 Like

Please note that you are using an old version of dolfin, as CellFunction is replaced by MeshFunction in the latest release.

I would create an explicit measure,

dxC= Measure("dx", domain=mesh, subdomain_data=cellmark, subdomain_id=True)

And simple assemble with dxC.
A single cell in Gmsh can only have one marker.
It would be best if you could make an illustration of your domain and what markers you would like to use.

1 Like


Thank you really much for your answer: this has allowed me to make good progress.

Concerning GMSH, I consider binary images composed of two phases (black and white). Thus, I have two physical labels for a single image (black=label1 and white=label2).
That’s why I wanted to use fenics to describe my sub-domain because I can’t do it directly on GMSH as I will superimpose the two first label with a new physical surface “label3” (describing the sub-domain).


I’m sorry to bother you again for this problem but it turns out that I can’t make your solution work on a simple example : a full square geometry with a square subdomain.
Here is the minimal example :

from __future__ import print_function
from dolfin import *
from fenics import *

# Create a unit square mesh and declare a new measure  dxC for the [0.25,0.75]x[0.25,0.75] sub-square.

mesh = UnitSquareMesh(50, 50)


cellmark = MeshFunction("bool", mesh, mesh.topology().dim())

class Subsquare(SubDomain):
def inside(self, x, on_boundary):
    return (between(x[1], (0.25, 0.75)) and between(x[0], (0.25, 0.75)))

subsquare = Subsquare()
subsquare.mark(cellmark, True)

dxC = Measure("dx", domain=mesh, subdomain_data=cellmark, subdomain_id=True)

#Test (should give 1 for the two print())
Test = (1/(0.5*0.5))*assemble(Constant(1)*dxC)
Test2 = assemble(Constant(1)*dx(domain=mesh))

And here is the code error :

Thank you in advance for your answer

Change your meshfunction to use size_t. Thus, instead of marking with true and false, mark it with 0 and 1.

So, will the elastic deformation leave my label on my subdomain unchanged with that syntax?

If so, I think I was making a mountain out of a molehill as this was my original syntax (for some reason, I thought it wouldn’t work)

Not sure what you are asking for. A MeshFunction has a static relation to the entities (entity being cell, facet,edge or vertex), and does not change behavior if you use “size_t” or “bool”.


I would like to interpret, in post treatment, the deformation only on the subdomain in red after a total elastic deformation over the entire geometry. For example I would like to calculate only within the red square the average of the displacement or its (symmetrical) gradient.

So I was wondering whether this sub-domain definition is suitable to do this or not.

PS : I know that this syntax works correctly when the physics leaves my geometry unchanged (flow, diffusion etc).

The subdomain (MeshFunction) definition is suitable, as it refers to cells which are not changed (but moved) during the deformation.


Ok, It’s a lot clearer now

Thank you really much for your answers and your time