Hello everyone,
Let us consider a vector-valued problem, which weak form of the discrete equations results in the following linear system:

While this system could be solved as a whole, let us consider the case when we partition the global block matrix into "sub-block matrices" as follows:

Now, we can first solve the first sub-block matrix (one can use the Schur complement):

and then solve the second one:


So, how to extract a submatrix from the global block matrix? In my view, there are two approaches:
A) Let us assume we have already constructed the global matrix, and its blocks have been established. The global matrix has a sparsity pattern represented by BlockDSP of the type BlockDynamicSparsityPattern. Now we want to initialize the sub-block matrices, but to do that, we need to have the sparsity patterns for each of the "sub-problems". Let us initialize the "sub-sparsity" pattern for the first sub-block and add non-zeros entries to it based on the global sparsity pattern as follows:where the dofs_per_block_fluid_flow is a vector of DoFs per each block of the first sub-problem (sizes of the blocks M and B), total_dofs_fluid_flow is the total number of DoFs of the first sub-problem.
Thus, we have extracted the sparsity pattern for the first sub-problem, and we can now create the corresponding sub-block matrix:
Finally, we fill matrix_fluid_flow with the corresponding values from the global block matrix as follows:
where matrix is a global block matrix.
Then we use linear solvers to obtain a solution for the first sub-problem, and after that, we do the same extraction/solution procedure for the second sub-problem. Thus, we have solved the two sub-systems separately.
I am sure at this point you notice that iterating through all the entries of the global matrix and its sparsity pattern is quite an expensive operation. It seems like solving sub-systems separately should, in fact, improve the stability and speed, but going through all these for-loops increased the simulation time.
B) The second approach is to never construct the global block matrix and instead create two block matrices based on their sparsity patterns and fill it with the values using separate routines. Unfortunately, this would involve rewriting a lot of the code that I did not write (I am working on the OpenFCST).Hopefully, the above explains my problem well, but please let me know if you need further clarification. I will appreciate any help, and thank you for creating a great FEA library and constantly improving it!
If you are curious, I am trying to solve the linearized formulation (i.e. Newton-Raphson method) of the incompressible Navier-Stokes problem coupled with multiple reaction-diffusion equations.