# Memory usage using Assemble

**URL:** <https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445>\
**Category:** Uncategorized\
**Created:** [January 10, 2022, 2:59pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445 "2022-01-10T14:59:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pierre\_Chassagne](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/pierre_chassagne/32/3126_2.png) [@Pierre\_Chassagne](https://fenicsproject.discourse.group/u/Pierre_Chassagne)\
**Post date:** [January 10, 2022, 2:59pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445/1 "2022-01-10T14:59:44Z")

</div>

Hello everyone,

I am a beginner with FEniCS and I’ve tried to use it for couple months to develop a topology optimization based framework for an electromagnetic problem. I currently have a version of my code which works fine, however it seems that I have a problem of memory leak in the function where I compute the FEA and my objective function, at each iteration step. Unfortunately, it keeps my algorithm from reaching convergence…

As pointed out in this discussion : [Is there memory leak in FEniCS and how to fix it? - #3 by bmf](https://fenicsproject.discourse.group/t/is-there-memory-leak-in-fenics-and-how-to-fix-it/1339/3) It seems that the problem comes from the fact that assemble create a new tensor each time it is called, and I call it several times since I am using finite differences to perform my sensitivity analysis. By looking at the assemble() documentation I also saw that I should use the tensor argument to avoid creating a new one each time it is called, like this :

```auto
A = PETScMatrix()
assemble(a, tensor=A)

```

However, doing so makes my jupyter kernel crash without any error. Here is a minimal example which reproduces the error, where bcs are some DC boudary conditions :

```auto
f = interpolate(Constant(1.0e-5), V) # the source term for the PDE for elec
u = TrialFunction(V)
v = TestFunction(V)
s = Function(V)
i = 0
Q = PETScMatrix()
while i <10000 :
    L = f*v*dx # ~= 0
    F = inner(grad(v),-grad(u))*dx
    solve(F == L, s, bcs)
    Q = assemble(s*dx, tensor = Q)
    i +=1

```

Can anyone help me with this problem ?  
Thanks in advance,  
Pierre

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [January 10, 2022, 3:14pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445/2 "2022-01-10T15:14:50Z")

</div>

`s * dx` is a rank 0 form and will be assembled as a scalar. Attempting to assemble it into a matrix is likely causing the error.

---

<div class="post-metadata">

**Author:** ![Pierre\_Chassagne](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/pierre_chassagne/32/3126_2.png) [@Pierre\_Chassagne](https://fenicsproject.discourse.group/u/Pierre_Chassagne)\
**Post date:** [January 10, 2022, 3:27pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445/3 "2022-01-10T15:27:05Z")

</div>

Thank you for your answer, indeed I didn’t even thought about that 😅, however there is a small mistake in my MWE and the result of the assemble should be a scalar for example Q should be define as :  
`Q = assemble(s*s*dx, tensor = Q)`

But I have no idea on how to define a scalar valued tensor, could you help me on this please ?

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [January 10, 2022, 3:29pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445/4 "2022-01-10T15:29:55Z")

</div>

Performance will greatly improve by using preallocation of vectors and matrices.

However, scalars are cheap, there’s little to no reason to preallocate a double precision float for your form. I’d just use `Q = assemble(s*s*dx)` for rank 0 forms.

You can probably eek out a little more performance by preallocating the UFL form though. Symbolic algebra is expensive. E.g.

```auto
# ... do stuff
interesting_form = s * s * dx
# ... do more stuff
for t in time_loop:
    # do time loop things ...
    Q = assemble(interesting_form)

```

Also, a general comment on performance: `solve()` is very expensive if you’re calling it every step in your loop. You’re creating and destroying all the necessary datastructures with each call. Consider `LinearVariationalProblem` or setting up your linear algebra system before the loop.

---

<div class="post-metadata">

**Author:** ![Pierre\_Chassagne](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/pierre_chassagne/32/3126_2.png) [@Pierre\_Chassagne](https://fenicsproject.discourse.group/u/Pierre_Chassagne)\
**Post date:** [January 10, 2022, 3:38pm UTC](https://fenicsproject.discourse.group/t/memory-usage-using-assemble/7445/5 "2022-01-10T15:38:36Z")

</div>

In fact, the problem was coming from the fact that I was unintentionally using the `assemble()` version from dolfin-adjoint and not the one from dolfin, it was therefore keeping a copy at each iteration (and there are a lot of iterations 😁). Now everything seems to be working fine without an excessive memory usage.

Thank you for your help ! And I will have a look at `LinearVariationalProblem` it could indeed help fasten my convergence which is kinda long, thanks for the tips !
