Hello there Fenicsx community,
I would like to know if there is any possible way to update values for Functions
in place without having to obtain a new linear system once I change the values of these functions. Let me provide a bit of more context.
I have the following UFL expression:
self.F = -self.c11*inner(grad(self.m1_fem), grad(self.test_v))*dx + ((1-self.alpha)/(self.alpha)) * inner(self.m1_fem, self.test_v) * ds + ((1-self.alpha) / (self.alpha)) * inner(self.b1, self.test_v) * ds - self.c12 * inner(grad(self.m2_prev), grad(self.test_v))*dx + inner(self.r1, grad(self.test_v))*dx
In this case m1_fem
is a TrialFunction
and test_v
is a TestFunction
. The rest of coefficients/functions appearing in the UFL expression are defined as Functions
in the following way:
self.V = functionspace(domain, ("Lagrange", 2))
self.m1_fem = TrialFunction(self.V)
self.m2_fem = TrialFunction(self.V)
self.test_v = TestFunction(self.V)
self.c11 = dolfinx.fem.Function(self.V)
self.b1 = dolfinx.fem.Function(self.V)
self.c12 = dolfinx.fem.Function(self.V)
self.c22 = dolfinx.fem.Function(self.V)
self.b2 = dolfinx.fem.Function(self.V)
self.m2_prev = dolfinx.fem.Function(self.V)
self.m1_prev = dolfinx.fem.Function(self.V)
self.r12_comp = dolfinx.fem.Function(self.V)
self.r11_comp = dolfinx.fem.Function(self.V)
self.r13_comp = dolfinx.fem.Function(self.V)
self.r22_comp = dolfinx.fem.Function(self.V)
self.r21_comp = dolfinx.fem.Function(self.V)
self.r23_comp = dolfinx.fem.Function(self.V)
self.r1 = as_vector((self.r11_comp, self.r12_comp, self.r13_comp))
self.r2 = as_vector((self.r21_comp, self.r22_comp, self.r23_comp))
I then assign values to all of these Functions
using: (The values are just standard numpy arrays that I compute separately)
self.m2_prev.x.array[:] = self.m2_iter
self.c11.x.array[:] = self.c11_val
self.b1.x.array[:] = self.b_array[:, 0, 0]
self.c12.x.array[:] = self.c1_d_c2_val
self.r11_comp.x.array[:] = self.r11
self.r12_comp.x.array[:] = self.r12
self.r13_comp.x.array[:] = np.zeros(self.r11.shape)
Finally, I assemble the linear system and solve as:
a = lhs(self.F)
L = rhs(self.F)
problem = LinearProblem(a, L, bcs=[], petsc_options={
"ksp_type": "preonly", "pc_type": "lu"})
m1_h = problem.solve()
self.m1_iter = m1_h.x.array
For a single evaluation this works nicely but I was wondering what should I do if I need to solve this system as part of an iterative algorithm. In my case, I need to solve the same problem on each iteration but the important things is that: the value of all of the functions involved in the UFL expression need to be updated (Most of the things that are defined as Functions
).
Is there any way that I can update these values in-place and avoid all of the logic associated to the construction of the sparse matrix? (Something like lazy-operations in where all values are replaced in place in the sparse-matrix logic and the RHS vector).
In advance, thanks a lot for the comments and feedback!!