FEniCS / dolfinx

Next generation FEniCS problem solving environment
https://fenicsproject.org
GNU Lesser General Public License v3.0
742 stars 178 forks source link

Use `enabled_coefficients` to restrict packing of coefficients #3260

Closed jorgensd closed 3 months ago

jorgensd commented 3 months ago

Pack only entities used in integral type: MWE:

from mpi4py import MPI
import dolfinx
import ufl

mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 50, 50, 50)
V = dolfinx.fem.functionspace(mesh, ("Lagrange", 3))
N = 50
us = [dolfinx.fem.Function(V) for _ in range(N)]
for i,u in enumerate(us):
    u.x.array[:] = i + 1
    u.name=f"u_{i}"

volume_form = us[0] * ufl.dx
surface_form = sum(us[i] * ufl.ds for i in range(N))

combined_form = volume_form + surface_form
compiled_form = dolfinx.fem.form(combined_form)

import time
start = time.perf_counter()
coeffs = dolfinx.fem.assemble.pack_coefficients(compiled_form._cpp_object)
end =time.perf_counter()
print(f"{dolfinx.common.git_commit_hash=} {end-start=:.5e}")
print(coeffs[(dolfinx.fem.IntegralType.cell, -1)])

On the main branch, all coefficients are packed for the cell integral, even if only the first coefficient is used in that integral. Runtime on this branch:

dolfinx.common.git_commit_hash='002e1fa9360995f9c71414a683e7ce618d6101e9' end-start=1.70250e+00

on main

dolfinx.common.git_commit_hash='64e35310085683f4f61804e70b8b58b9bb8653ae' end-start=2.89335e+00

It would also resolve #3256 and simplify some logic in: #3224

jorgensd commented 3 months ago

Running the test above in serial on my system: Main:

dolfinx.common.git_commit_hash='90e4fee36c2f5d1254ceec4638fd4194cc8be7da' end-start=2.90846e+01

This PR

dolfinx.common.git_commit_hash='9f19213e8b4d6e586601dd8d1ce40b37da948aa1' end-start=6.47885e+00