Hello everyone,
I am currently working with a library called QUGaR (GitHub - pantolin/qugar: Quadratures for Unfitted GeometRies), which allows the generation of quadrature rules for immersed problems.
In my formulation, I have a volumetric term that relies on QUGaR, but I also have a penalty term defined on internal facets that I would like to implement in the classical way using ufl.dS.
The issue is that I cannot mix the QUGaR form (a) and the standard FEniCSx form (a2) in a single assembly, so I have to assemble them separately.
Here is how I did it. I was wondering whether I need to call self._A.assemble() after each dolfinx.petsc.assemble, or only once after all the dolfinx.petsc.assemble calls.
_init_
_a = form_custom(
a,
dtype=PETSc.ScalarType, # type: ignore
form_compiler_options=form_compiler_options,
jit_options=jit_options,
)
self._a = typing.cast(CustomForm | list[CustomForm], _a)
self._A = create_matrix(self._a) # type: ignore
_L = form_custom(
L,
dtype=PETSc.ScalarType, # type: ignore
form_compiler_options=form_compiler_options,
jit_options=jit_options,
)
self._L = typing.cast(CustomForm | list[CustomForm], _L)
# Assemble additional FEniCSx bilinear form if provided
self._a2 = None
if a2 is not None:
self._a2 = dolfinx.fem.form(
a2,
dtype=PETSc.ScalarType, # type: ignore
form_compiler_options=form_compiler_options,
jit_options=jit_options,
)
solve
self._A.zeroEntries()
self.A_coeffs = _pack_coefficients(self._a)
dolfinx.fem.petsc.assemble_matrix(self._A, self._a, bcs=self.bcs, coeffs=self.A_coeffs)
if self._a2 is not None:
# Assemble a2 directly into self._A (adds to existing values)
dolfinx.fem.petsc.assemble_matrix(self._A, self._a2, bcs=self.bcs)
# Finalize matrix assembly (only once, after all contributions)
self._A.assemble()
form_custom and _pack_coefficient are fonctions provided by qugar who allow to compute the term for cutted elements.