Why is my code converging in 4 steps? Linear PDE

Well, the question was about assembling before setting the nullspace, which is not required. However, to test the nullspace, the matrix needs to be assembled.

1 Like

Iā€™m back at it @dokken. I am too ignorant to properly assert the test of the nullspace (I tried several variants, involving assemble_matrix() and a few others, I couldnā€™t get the proper syntax).

Nevertheless, here is my attempt without Newton solver, just like you asked for:

import numpy as np
from dolfinx import log, fem
from dolfinx.fem import (Constant, Function, functionspace, FunctionSpace, assemble_scalar,
                         dirichletbc, form, locate_dofs_geometrical, VectorFunctionSpace,
                         locate_dofs_topological, Expression, create_matrix, assemble_matrix)
from dolfinx.fem.petsc import NonlinearProblem, LinearProblem
from dolfinx.nls.petsc import NewtonSolver
from mpi4py import MPI
from petsc4py import PETSc
from petsc4py.PETSc import ScalarType
from ufl import (FiniteElement, Measure, MixedElement, SpatialCoordinate,
                 TestFunction, TrialFunction, as_tensor, dot, dx, grad, inner,
                 inv, split, derivative, FacetNormal, div)
import gmsh
from dolfinx.io import gmshio, VTXWriter

mesh, cell_markers, facet_markers = gmshio.read_from_msh("meshes/rectangles.msh", MPI.COMM_WORLD, gdim=2)

def resistance(meshfile):
  
    the_current = 1.0
    current_curves=(12,13)
    voltages_curves=(12,13)    
    
    inj_current_curve, out_current_curve = current_curves
    reading_voltage_curve_0, reading_voltage_curve_1 = voltages_curves

    # Define FE function space
    deg = 3
    el = FiniteElement("CG", mesh.ufl_cell(), deg)
    V = FunctionSpace(mesh, el)    

    v = TestFunction(V)
    volt = TrialFunction(V)
  
    rho = 1
    sigma = 1.0 / rho

    # Define the boundary conditions
    left_facets = facet_markers.find(inj_current_curve)
    right_facets = facet_markers.find(out_current_curve)
    left_dofs = locate_dofs_topological(V, mesh.topology.dim-1, left_facets)
    V_current_contact_out = 0
    bcs = [dirichletbc(ScalarType(V_current_contact_out), left_dofs, V)]

    
    x = SpatialCoordinate(mesh)
    dx = Measure("dx", domain=mesh, subdomain_data=cell_markers)
    ds = Measure("ds", domain=mesh, subdomain_data=facet_markers)

    J = the_current / assemble_scalar(form(1 * ds(inj_current_curve, domain=mesh)))

    # Weak form.
    J_vector = -sigma * grad(volt)
    a = dot(grad(v), J_vector)*dx
    L = - v * J * ds(out_current_curve) - v * J * ds(inj_current_curve)

    print(f''' ------- Pre-processing --------
    Current density: {J}
    Length of the side where current is injected: {assemble_scalar(form(1 * ds(inj_current_curve, domain=mesh)))}
    Length of the side where current leaves the wire: {assemble_scalar(form(1 * ds(out_current_curve, domain=mesh)))}
    This should correspond to the current injected: {assemble_scalar(form(J*ds(out_current_curve)))}
    ''')

    A = fem.petsc.assemble_matrix(fem.form(a))
    A.assemble()
    b = fem.petsc.assemble_vector(fem.form(L))
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)

    # Create vector that spans the null space
    nullspace = PETSc.NullSpace().create(constant=True,comm=MPI.COMM_WORLD)
    assert nullspace.test(A)
    A.setNullSpace(nullspace)
    nullspace.remove(b)    

    ksp = PETSc.KSP().create(mesh.comm)
    ksp.setOperators(A)

    opts = PETSc.Options()
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    opts["pc_factor_solver_type"] = "mumps"
    opts["mat_mumps_icntl_24"] = 1  # Option to support solving a singular matrix
    opts["mat_mumps_icntl_25"] = 0  # Option to support solving a singular matrix
    ksp.setFromOptions()

    volth = fem.Function(V)
    ksp.solve(b, volth.vector)
    volth.x.scatter_forward()
    iterations = ksp.getIterationNumber()
    # See: https://petsc.org/release/manualpages/KSP/KSPConvergedReason/
    converged_reason = ksp.getConvergedReason()
    if converged_reason > 0:
        print(f"PETSc solver converged in {iterations=}")
    else:
        raise RuntimeError(f"PETSc solver did not converge with {converged_reason=}")
    #problem = LinearProblem(a, L, petsc_options={"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps", "mat_mumps_icntl_24": 1, "mat_mumps_icntl_25" :0})
    

    avg_voltage_curve_integral_0 = assemble_scalar(form(volt * ds(reading_voltage_curve_0, domain=mesh))) / assemble_scalar(form(1 * ds(reading_voltage_curve_0, domain=mesh)))
    avg_voltage_curve_integral_1 = assemble_scalar(form(volt * ds(reading_voltage_curve_1, domain=mesh))) / assemble_scalar(form(1 * ds(reading_voltage_curve_1, domain=mesh)))
    voltage_diff = avg_voltage_curve_integral_1 - avg_voltage_curve_integral_0
    resistance = voltage_diff / assemble_scalar(form(J*ds(out_current_curve)))


    n = FacetNormal(mesh)
    down_current_flux = form(dot(J_vector, n)*ds(inj_current_curve))
    I_out = assemble_scalar(down_current_flux)
    up_current_flux = form(dot(J_vector, n)*ds(out_current_curve))
    I_in = assemble_scalar(up_current_flux)
    # Positive means outwards the curve/surface.
    print(f'I_out: {I_out}')
    print(f'I_in: {I_in}')
    print(f'div(Je) should be 0: {assemble_scalar(form(div(J_vector) * dx(domain=mesh)))}')

    return resistance
    
res = resistance("meshes/rectangles.msh")
print(f'resistance: {res}')

Hereā€™s the output:

Info    : Reading 'meshes/rectangles.msh'...
Info    : 21 entities
Info    : 1291 nodes
Info    : 2353 elements
Info    : Done reading 'meshes/rectangles.msh'
 ------- Pre-processing --------
    Current density: 33.333333333333336
    Length of the side where current is injected: 0.03
    Length of the side where current leaves the wire: 0.09999999999999998
    This should correspond to the current injected: 3.3333333333333335
    
PETSc solver converged in iterations=1

Loguru caught a signal: SIGSEGV
Stack trace:
24      0x5eb6ad3dcba5 _start + 37
23      0x7b05c8ff8e40 __libc_start_main + 128
22      0x7b05c8ff8d90 /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7b05c8ff8d90]
21      0x5eb6ad3dccad Py_BytesMain + 45
20      0x5eb6ad40641e Py_RunMain + 702
19      0x5eb6ad413653 _PyRun_AnyFileObject + 67
18      0x5eb6ad413a08 _PyRun_SimpleFileObject + 424
17      0x5eb6ad414525 python3(+0x264525) [0x5eb6ad414525]
16      0x5eb6ad40e0bb python3(+0x25e0bb) [0x5eb6ad40e0bb]
15      0x5eb6ad4147d8 python3(+0x2647d8) [0x5eb6ad4147d8]
14      0x5eb6ad3e9cf6 PyEval_EvalCode + 134
13      0x5eb6ad3e9e56 python3(+0x239e56) [0x5eb6ad3e9e56]
12      0x5eb6ad2f8e0d _PyEval_EvalFrameDefault + 1725
11      0x5eb6ad31070c _PyFunction_Vectorcall + 124
10      0x5eb6ad2f8e0d _PyEval_EvalFrameDefault + 1725
9       0x5eb6ad31070c _PyFunction_Vectorcall + 124
8       0x5eb6ad2ff1f1 _PyEval_EvalFrameDefault + 27297
7       0x5eb6ad3065eb _PyObject_MakeTpCall + 603
6       0x5eb6ad30fe0e python3(+0x15fe0e) [0x5eb6ad30fe0e]
5       0x7b05bd377c5c /usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0xb1c5c) [0x7b05bd377c5c]
4       0x7b05bd3b2e0d /usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0xece0d) [0x7b05bd3b2e0d]
3       0x7b05bd62afbc /usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x364fbc) [0x7b05bd62afbc]
2       0x7b05bd62c063 /usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x366063) [0x7b05bd62c063]
1       0x7b05bd37e175 /usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0xb8175) [0x7b05bd37e175]
0       0x7b05c9011520 /lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7b05c9011520]
2024-04-18 20:22:47.085 (   0.841s) [main            ]                       :0     FATL| Signal: SIGSEGV
Segmentation fault (core dumped)

A core dump, but at least the code converges within a single step, right? Unfortunately I donā€™t have the feedback of my print statements, to see if the values are OK.

By debugging by adding print statements, I figured out that this is the line that produces the core dump:

I_out = assemble_scalar(down_current_flux)

Edit: I could get those quantities:

avg_voltage_curve_integral_0: 0.08333333333333334
avg_voltage_curve_integral_1: 0.08333333333333336
voltage_diff: 1.3877787807814457e-17
resistance: 4.163336342344337e-18

It looks like it isnā€™t solved correctly, the correct resistance is near unity, so thereā€™s a much bigger voltage difference than the one computed here.

Some more insights. With Paraview, I could examine the solution (after saving it with VTXwriter). It looks correct to me:


With bounds [-12.7152832665543, 15.403668747733219], this makes the resistance worth about 28 V /4 A, approximately 7 ohm, this is what I should get with FEniCSx.

Therefore, none of the 2 values in

avg_voltage_curve_integral_0: 0.08333333333333334
avg_voltage_curve_integral_1: 0.08333333333333336

are correct. And I canā€™t get a visual of the current density, as the code returns an error:

Traceback (most recent call last):
  File "/root/shared/TE_simulation/electric_pb.py", line 195, in <module>
    res = resistance("meshes/rectangles.msh")
  File "/root/shared/TE_simulation/electric_pb.py", line 163, in resistance
    Je.interpolate(Je_flux_calculator)    
  File "/usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/fem/function.py", line 397, in interpolate
    _interpolate(u, cells)
  File "/usr/lib/python3.10/functools.py", line 889, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/fem/function.py", line 388, in _
    self._cpp_object.interpolate(expr._cpp_object, cells)
RuntimeError: Cannot interpolate Expression with Argument
WARNING! There are options you set that were not used!
WARNING! could be spelling mistake, etc!
There are 3 unused database options. They are:
Option left: name:-mat_mumps_icntl_24 value: 1 source: code
Option left: name:-mat_mumps_icntl_25 value: 0 source: code
Option left: name:-pc_factor_solver_type value: mumps source: code

Soā€¦ something is very strange. It looks like it correctly computed the solution (I suppose), but canā€™t evaluate anything on the boundaries?

Great @dokken, I could make some progress. It turns out that unlike when I use a Nonlinearsolver, here I must update J_vector, it isnā€™t updated automatically, hence the core dumps.
I fixed the code. It is now:

import numpy as np
from dolfinx import log, fem
from dolfinx.fem import (Constant, Function, functionspace, FunctionSpace, assemble_scalar,
                         dirichletbc, form, locate_dofs_geometrical, VectorFunctionSpace,
                         locate_dofs_topological, Expression, create_matrix, assemble_matrix)
from dolfinx.fem.petsc import NonlinearProblem, LinearProblem
from dolfinx.nls.petsc import NewtonSolver
from mpi4py import MPI
from petsc4py import PETSc
from petsc4py.PETSc import ScalarType
from ufl import (FiniteElement, Measure, MixedElement, SpatialCoordinate,
                 TestFunction, TrialFunction, as_tensor, dot, dx, grad, inner,
                 inv, split, derivative, FacetNormal, div)
import gmsh
from dolfinx.io import gmshio, VTXWriter

mesh, cell_markers, facet_markers = gmshio.read_from_msh("meshes/rectangles.msh", MPI.COMM_WORLD, gdim=2)



def resistance(meshfile):
    the_current = 1.0
    current_curves=(12,13)
    voltages_curves=(12,13)    
    
    inj_current_curve, out_current_curve = current_curves
    reading_voltage_curve_0, reading_voltage_curve_1 = voltages_curves

    # Define FE function space
    deg = 3
    el = FiniteElement("CG", mesh.ufl_cell(), deg)
    V = FunctionSpace(mesh, el)    

    v = TestFunction(V)
    volt = TrialFunction(V)
  
    rho = 1
    sigma = 1.0 / rho

    # Define the boundary conditions
    left_facets = facet_markers.find(inj_current_curve)
    right_facets = facet_markers.find(out_current_curve)
    left_dofs = locate_dofs_topological(V, mesh.topology.dim-1, left_facets)
    V_current_contact_out = 0
    
    x = SpatialCoordinate(mesh)
    dx = Measure("dx", domain=mesh, subdomain_data=cell_markers)
    ds = Measure("ds", domain=mesh, subdomain_data=facet_markers)

    J = the_current / assemble_scalar(form(1 * ds(inj_current_curve, domain=mesh)))

    # Weak form.
    J_vector = -sigma * grad(volt)
    a = -dot(grad(v), J_vector)*dx
    L = - v * J * ds(out_current_curve) + v * J * ds(inj_current_curve)

    print(f''' ------- Pre-processing --------
    Current density: {J}
    Length of the side where current is injected: {assemble_scalar(form(1 * ds(inj_current_curve, domain=mesh)))}
    Length of the side where current leaves the wire: {assemble_scalar(form(1 * ds(out_current_curve, domain=mesh)))}
    This should correspond to the current injected: {assemble_scalar(form(J*ds(out_current_curve)))}
    ''')
    A = fem.petsc.assemble_matrix(fem.form(a))
    A.assemble()
    b = fem.petsc.assemble_vector(fem.form(L))
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)

    # Create vector that spans the null space
    nullspace = PETSc.NullSpace().create(constant=True,comm=MPI.COMM_WORLD)
    assert nullspace.test(A)
    A.setNullSpace(nullspace)
    nullspace.remove(b)    

    ksp = PETSc.KSP().create(mesh.comm)
    ksp.setOperators(A)

    opts = PETSc.Options()
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    opts["pc_factor_solver_type"] = "mumps"
    opts["mat_mumps_icntl_24"] = 1  # Option to support solving a singular matrix
    opts["mat_mumps_icntl_25"] = 0  # Option to support solving a singular matrix
    ksp.setFromOptions()
    volth = fem.Function(V)
    ksp.solve(b, volth.vector)
    volth.x.scatter_forward()
    iterations = ksp.getIterationNumber()
    # See: https://petsc.org/release/manualpages/KSP/KSPConvergedReason/
    converged_reason = ksp.getConvergedReason()
    if converged_reason > 0:
        print(f"PETSc solver converged in {iterations=}")
    else:
        raise RuntimeError(f"PETSc solver did not converge with {converged_reason=}")
    
    with VTXWriter(MPI.COMM_WORLD, "results/voltage_elec.bp", [volth], engine="BP4") as vtx:
        vtx.write(0.0)

    # Update J_vector
    J_vector = -sigma * grad(volth)

    avg_voltage_curve_integral_0 = assemble_scalar(form(volth * ds(reading_voltage_curve_0, domain=mesh))) / assemble_scalar(form(1 * ds(reading_voltage_curve_0, domain=mesh)))
    avg_voltage_curve_integral_1 = assemble_scalar(form(volth * ds(reading_voltage_curve_1, domain=mesh))) / assemble_scalar(form(1 * ds(reading_voltage_curve_1, domain=mesh)))
    voltage_diff = avg_voltage_curve_integral_1 - avg_voltage_curve_integral_0
    resistance = voltage_diff / assemble_scalar(form(J*ds(out_current_curve)))
    print(f'avg_voltage_curve_integral_0: {avg_voltage_curve_integral_0}')
    print(f'avg_voltage_curve_integral_1: {avg_voltage_curve_integral_1}')
    print(f'voltage_diff: {voltage_diff}')
    print(f'resistance: {resistance}')
    print(f'div(Je) should be 0: {assemble_scalar(form(div(J_vector) * dx(domain=mesh)))}')
    n = FacetNormal(mesh)
    down_current_flux = form(dot(J_vector, n)*ds(inj_current_curve))
    I_out = assemble_scalar(down_current_flux)
    up_current_flux = form(dot(J_vector, n)*ds(out_current_curve))
    I_in = assemble_scalar(up_current_flux)

    # Positive means outwards the curve/surface.
    print(f'I_out: {I_out}')
    print(f'I_in: {I_in}')
    return resistance
    
res = resistance("meshes/rectangles.msh")
print(f'resistance: {res}')

The output is:

Info    : Reading 'meshes/rectangles.msh'...
Info    : 21 entities
Info    : 1291 nodes
Info    : 2353 elements
Info    : Done reading 'meshes/rectangles.msh'
 ------- Pre-processing --------
    Current density: 33.333333333333336
    Length of the side where current is injected: 0.03
    Length of the side where current leaves the wire: 0.09999999999999998
    This should correspond to the current injected: 3.3333333333333335
    
PETSc solver converged in iterations=1
avg_voltage_curve_integral_0: 15.403275750479303
avg_voltage_curve_integral_1: -12.714402930356114
voltage_diff: -28.117678680835418
resistance: -8.435303604250626
div(Je) should be 0: 1.1140697211743482
I_out: -1.0014547932721676
I_in: 3.3286405396011376
resistance: -8.435303604250626
WARNING! There are options you set that were not used!
WARNING! could be spelling mistake, etc!
There are 3 unused database options. They are:
Option left: name:-mat_mumps_icntl_24 value: 1 source: code
Option left: name:-mat_mumps_icntl_25 value: 0 source: code
Option left: name:-pc_factor_solver_type value: mumps source: code

Which points at 2 problems (maybe related):

  1. For some reason, the solver options to take into account the nullspace are ignored.
  2. The solution computed is wrong. I am solving div(J)=0 and I get a value of 1.11. The currents in and out are also wrong, the in current is slightly off, the out current is quite off the mark.

Thatā€™s the same kind of problems I reported in post #9.
Any idea what could be wrong? I suspect the nullspace isnā€™t taken well into account. I donā€™t see anything else at the moment.

Edit: I am trying ā€œrandomā€ stuff. I could get to use mumps (I believe, though it doesnā€™t change any result so far) by adding the line ksp.getPC().setFactorSolverType("MUMPS"), notice the capital letters (Iā€™d get the warning that 3 options were not used, as above, otherwise). With these capital letters, I only have the remaining 2 warnings to get rid ofā€¦ if anyone reads me, feel free to help. Iā€™m desperately trying to get this to work properly.

Edit2: Trying the syntax:

    ksp.getPC().getFactorMatrix().setMumpsIcntl(icntl=24, ival=1)
    ksp.getPC().getFactorMatrix().setMumpsIcntl(icntl=25, ival=0)

yields:

  File "/root/shared/TE_simulation/electric_pb.py", line 187, in <module>
    res = resistance("meshes/rectangles.msh")
  File "/root/shared/TE_simulation/electric_pb.py", line 106, in resistance
    ksp.getPC().getFactorMatrix().setMumpsIcntl(icntl=24, ival=1)
  File "petsc4py/PETSc/PC.pyx", line 1433, in petsc4py.PETSc.PC.getFactorMatrix
  File "petsc4py/PETSc/PETSc.pyx", line 79, in petsc4py.PETSc.CHKERR
petsc4py.PETSc.Error: error code 56
[0] PCFactorGetMatrix() at /usr/local/petsc/src/ksp/pc/interface/precon.c:1456
[0] No support for this operation for this object type
[0] No method getfactoredmatrix for PC of type (null)

At least the statements are recognizedā€¦ though they lead to an errorā€¦

I am still totally stuck on this. If someone knows how I can use mumps with the null space options as specified, let me know. I tried at least 3 different syntaxes, and so far it seems only 1 works for mumps but I havenā€™t been able to set the null space options.

Iā€™m not sure people are still reading me.
I just wanted to mention that chatGPT helped me an iota, and pointed out that my opts["pc_factor_solver_type"] = "mumps" should in fact have been opts["pc_factor_mat_solver_type"] = "mumps"

So now I know mumps is used, with the options I have set. However this doesnā€™t change the wrong result, I get exactly the same wrong result.
Hereā€™s some ā€œdebugā€ info from mumps:

Entering DMUMPS 5.6.1 from C interface with JOB, N, NNZ =   1       10891         180811
      executing #MPI =      1, without OMP

 =================================================
 MUMPS compiled with option -Dmetis
 MUMPS compiled with option -Dpord
 MUMPS compiled with option -Dptscotch
 MUMPS compiled with option -Dscotch
 =================================================
L U Solver for unsymmetric matrices
Type of parallelism: Working host

 ****** ANALYSIS STEP ********

 Processing a graph of size:     10891

Entering ordering phase with ...
                N        NNZ       LIW       INFO(1)
           10891     180811      372514         0
Matrix entries:    IRN()   ICN()
           1        1           1        2           1        3
           1        4           1        5           1        6
           1        7           1        8           1        9
           1       10
 ... Structural symmetry (in percent)=  100
 Average density of rows/columns =   16
 ... No column permutation
 Ordering based on METIS
 ELAPSED TIME SPENT IN METIS reordering  =      0.0333
 SYMBOLIC based on column counts 
 ELAPSED TIME IN symbolic factorization  =    321.2459
NFSIZ(.)  =        0        0        0        0       31        0        0        0        0        0

FILS (.)  =       12       24        2        3       27        0        6        1        8        7

FRERE(.)  =    10892    10892    10892    10892      -54    10892    10892    10892    10892    10892


Leaving analysis phase with  ...
 INFOG(1)                                       =               0
 INFOG(2)                                       =               0
 -- (20) Number of entries in factors (estim.)  =          845915
 --  (3) Real space for factors    (estimated)  =          845915
 --  (4) Integer space for factors (estimated)  =           73224
 --  (5) Maximum frontal size      (estimated)  =             118
 --  (6) Number of nodes in the tree            =             688
 -- (32) Type of analysis effectively used      =               1
 --  (7) Ordering option effectively used       =               5
 ICNTL (6) Maximum transversal option           =               0
 ICNTL (7) Pivot order option                   =               7
 ICNTL(13) Parallelism/splitting of root node   =               1
 ICNTL(14) Percentage of memory relaxation      =              20
 ICNTL(15) Analysis by block effectively used   =               0
 ICNTL(18) Distributed input matrix (on if >0)  =               0
 ICNTL(58) Symbolic factorization option        =               2
 Number of level 2 nodes                        =               0
 Number of split nodes                          =               0
 RINFOG(1) Operations during elimination (estim)= 3.975D+07

 MEMORY ESTIMATIONS ... 
 Estimations with standard Full-Rank (FR) factorization:
    Total space in MBytes, IC factorization      (INFOG(17)):          11
    Total space in MBytes,  OOC factorization    (INFOG(27)):           4

 Elapsed time in analysis driver=       0.0397

Entering DMUMPS 5.6.1 from C interface with JOB, N, NNZ =   2       10891         180811
      executing #MPI =      1, without OMP



****** FACTORIZATION STEP ********

 GLOBAL STATISTICS PRIOR NUMERICAL FACTORIZATION ...
 Number of working processes                =               1
 ICNTL(22) Out-of-core option               =               0
 ICNTL(35) BLR activation (eff. choice)     =               0
 ICNTL(37) BLR CB compression (eff. choice) =               0
 ICNTL(49) Compact workarray S (end facto.) =               0
 ICNTL(14) Memory relaxation                =              20
 INFOG(3) Real space for factors (estimated)=          845915
 INFOG(4) Integer space for factors (estim.)=           73224
 Maximum frontal size (estimated)           =             118
 Number of nodes in the tree                =             688
 ICNTL(23) Memory allowed (value on host)   =               0
           Sum over all procs               =               0
 Memory provided by user, sum of LWK_USER   =               0
 Effective threshold for pivoting, CNTL(1)  =      0.1000D-01
 Max difference from 1 after scaling the entries for ONE-NORM (option 7/8)   = 0.40D-01
 CNTL(3) for null pivot row detection       =      0.0000D+00
 ICNTL(24) null pivot rows detection        =               1
 ...Zero pivot detection threshold          =      4.5257D-15
 ...Infinite fixation 
 Effective size of S     (based on INFO(39))=              1024969

 Elapsed time to reformat/distribute matrix =      0.0029

 ** Memory allocated, total in Mbytes           (INFOG(19)):          11
 ** Memory effectively used, total in Mbytes    (INFOG(22)):          10

 Elapsed time for factorization                     =      0.0110

Leaving factorization with ...
 RINFOG (2) Operations in node assembly             = 6.493D+05
 ------ (3) Operations in node elimination          = 3.975D+07
 ICNTL  (8) Scaling effectively used                =               7
 INFOG  (9) Real space for factors                  =          845915
 INFOG (10) Integer space for factors               =           73224
 INFOG (11) Maximum front size                      =             118
 INFOG (29) Number of entries in factors            =          845915
 INFOG (12) Number of off diagonal pivots           =               0
 INFOG (13) Number of delayed pivots                =               0
 Nb of null pivots detected by ICNTL(24)            =               0
 INFOG (28) Estimated deficiency                    =               0
 INFOG (14) Number of memory compress               =               0

 Elapsed time in factorization driver               =      0.0172

Entering DMUMPS 5.6.1 from C interface with JOB, N, NNZ =   3       10891         180811
      executing #MPI =      1, without OMP



 ****** SOLVE & CHECK STEP ********

 GLOBAL STATISTICS PRIOR SOLVE PHASE ...........
 Number of right-hand-sides                    =           1
 Blocking factor for multiple rhs              =           1
 ICNTL (9)                                     =           1
  --- (10)                                     =           0
  --- (11)                                     =           0
  --- (20)                                     =           0
  --- (21)                                     =           0
  --- (30)                                     =           0
  --- (35)                                     =           0


 Vector solution for column            1
 RHS
   1.432576D+01  1.408039D+01  1.399049D+01  1.405549D+01  1.401528D+01
   1.423322D+01  1.408331D+01  1.425793D+01  1.414823D+01  1.413229D+01
 ** Space in MBYTES used for solve                        :         9

 Leaving solve with ...
 Time to build/scatter RHS        =       0.000108
 Time in solution step (fwd/bwd)  =       0.001701
  .. Time in forward (fwd) step   =          0.000907
  .. Time in backward (bwd) step  =          0.000793
 Time to gather solution(cent.sol)=       0.000015
 Time to copy/scale dist. solution=       0.000000

 Elapsed time in solve driver=       0.0022

Edit: You can consider this thread as finished. I will post my question in a new thread, since the original question has been answered, I can get a convergence in 1 step using either 2 Dirichlet b.c. or a combination of 1 Dirichlet and 1 Neumann b.c.