How to calculate effective stress/strain in a homogenization model

Hi Everyone !
I’m a beginner in Fenics and im trying to calculate then plot the effective strain/stress curve.
i don’t know how i should calculate the sum of strain/stress divided by number of elements.
then plot the curve directly with python.

You can compute the spatial average of a function f via

\bar{f} = \frac{1}{\vert\Omega\vert}\int_\Omega f\,d\Omega\text{ .}

In code, you would do the integrals using the assemble function, e.g.,

from dolfin import *

mesh = UnitIntervalMesh(16)
x = SpatialCoordinate(mesh)
f = x[0]**2
int_f = assemble(f*dx)
volume = assemble(Constant(1)*dx(domain=mesh))
avg_f = int_f/volume

print(avg_f)

Thank you it works perfectly !

This works perfectly fine over the entire domain, but I have a situation where I need to compute the spatial average over each cell of the domain. How do I do this please?

Consider the following:

from dolfin import *
mesh = UnitIntervalMesh(16)
x = SpatialCoordinate(mesh)
f = x[0]**2
V = FunctionSpace(mesh, "DG", 0)
v = TestFunction(V)
int_f = assemble(1/CellVolume(mesh)*f*v*dx)
print(int_f.get_local())

Dr. @dokken I want to compute average of my solution function over each cell (2D) in dolfinx. Can you please suggest how we can compute cell volume in fenicsx or we have any built in function to achieve this. I also wonder why we are introducing DG-0 space to do this. I appreciate your suggestions or help in acheiving this.

Here is an equivalent version for DOLFINx:

from mpi4py import MPI
import dolfinx
import ufl
mesh = dolfinx.mesh.create_unit_interval(MPI.COMM_WORLD, 10)
x = ufl.SpatialCoordinate(mesh)
f = x[0]**2
V = dolfinx.fem.functionspace(mesh, ("DG", 0))
v = ufl.TestFunction(V)
int_f = dolfinx.fem.assemble_vector(dolfinx.fem.form(1/ufl.CellVolume(mesh)*f*v*ufl.dx))
print(int_f.array)

The reason I introduce a DG-0 space is to isolate contributions from each cell (as DG-0 is 1 degree of freedom per cell).

1 Like

Thank you so much dr. @dokken for your response. I have written MWE for 2D case,
I have two more questions on this,

  1. how would I know which contribution is coming from which cell. Is there any correspondence between indices of int_f and cells.
  2. let us suppose I have a solution vector u with 16 degrees of freedom for which I want to calculate avg. value over each cell, would there be any issue while defining dolfinx.fem.form(u*v*dx) as u and v have different dofs.
msh = create_unit_square(MPI.COMM_WORLD,2,2)
x = ufl.SpatialCoordinate(msh)
f = x[0] + x[1]

V = dolfinx.fem.functionspace(msh, ("DG", 0))
# f_vl = fem.Function(V)
# f_exp = dolfinx.fem.Expression(f,V.element.interpolation_points())
# f_vl.interpolate(f_exp)

v = ufl.TestFunction(V)
int_f = dolfinx.fem.assemble_vector(dolfinx.fem.form(1/ufl.CellVolume(msh)*f*v*ufl.dx))
print(int_f.array)

I hope I am not bothering if I sound trivial.

There is a one-to-one correspondence between the cell index in msh and the index in int_f. To indentify cells I would for instance use

num_cells_local = mesh.topology.index_map(mesh.topology.dim).size_local
midpoints = dolfinx.mesh.compute_midpoints(mesh, mesh.topology.dim, np.arange(num_cells_local, dtype=np.int32))

or store the function in a DG-0 function space and then visualize it:

int_f = dolfinx.fem.function(V)
dolfinx.fem.assemble_vector(int_f.x, dolfinx.fem.form(1/ufl.CellVolume(msh)*f*v*ufl.dx))

dr. @dokken thank you for your response. Please let me know if I am reasoning correctly
to resolve my second question, I would define the DG-0 space on the same mesh which comes from my solution vector and then calculate avg. right??

Yes, that is what you would do.

1 Like

Thank you so much, I truly appreciate your grace.