Different freeDofs for rows and columns in solver routines

Hello everyone,

in my implementations I sometimes need to impose different dirichlet dofs for test and ansatz spaces. This is e.g. needed for space-time methods.
I can assemble the full matrices by using a bilinear form with

bf = BilinearForm(trialspace=fes_ansatz, testspace=fes_test)

However, when I now want to solve the system, I have to remove some rows for the conditions on the test space and remove some columns + adapt the right hand side for the dirichlet conditions on the ansatz space.
Right now, I do this by converting the matrix to a python matrix and then do it manually. As far as I have seen, the methods exposed by ngsolve only accept one dof mask and I cannot use the built in solvers.
For linear problems the python workaround seems fine, however for nonlinear problems this gets nasty.

Has anyone encountered such a problem before?

Thanks,
Michael

I don’t know of anyone who has done this, but you could use the scipy interface to do this.

here attached a python file for wrappers for some direct solvers to python (pardiso, umfpack, superlu). They should be easy to adapt for 2 pair of freedofs. They rely on some external wrappers for umfpack and pardiso that are pip installable I think.

you’d have to look up the solver documentation how to call them on non square matrices though.

direct_solvers.py (2.6 KB)

Hello Christopher,

thank you! This is approximately how I do it right now.
Do you think, that I can also use such an approach in the Newton routine?

Might there in general be interest in extending existing routines for different dof elimination?

Yes should work. the nonlinearsolvers.NewtonSolver takes a solver argument where you can give the linear solver.

Hi Michael,

An alternative approach is to remove the constrained dofs directly from the spaces. This is very easy for homogeneous boundary conditions. You can do it like that:

fes = H1(mesh, dirichlet="left")
print (fes.ndof)
fesc = Compress(fes, active_dofs=fes.FreeDofs())
print (fesc.ndof)

Joachim

Thank you. I will try this