Running one of the existing block coupled solvers (in this case pUCoupledFoam
) in parallel and using the block matrix AMG generates the following error message:
[1] --> FOAM FATAL ERROR: [1] fineInterface must be of processor type and either processorBlockLduInterfaceField<Type> or processorFvPatchField<Type> [1] [1] [1] From function processorBlockGAMGInterfaceField<Type> Constructor [1] in file lnInclude/processorBlockGAMGInterfaceField.C at line 61. [1]
The AMG solver has been run successfully in parallel early on in the development. In the early versions there were cases allowing the processorBlockGAMAGInterfaceField
to be constructed from type processorFvPatchField
. This has been removed, likely due to that the blockLduMatrices
is directly under foam
(wanting to remove dependencies on finiteVolume
, i.e. no includes from finiteVolume
).
The problem arises when a new level is created in the BlockMatrixAgglomeration
, and more specifically from BlockGAMGInterfaceField
in which the type of the interface field is asked for (via interfaceFieldType()
).
When arriving (via New::
) in processorBlockGAMGInterfaceField
the type of the interface is not actually an processorBlockLduInterfaceField
, but an processorLduInterfaceField
(or a processorFvPatchField
.
Looking at the implementation it is seen that:
processorBlockLduInterfaceField
is an abstract classprocessorBlockGAMGLduInterfaceField
inherits processorBlockLduInterfaceField
processorBlockGAMGLduInterfaceField
also inherits BlockGAMGInterfaceField
The point of having a separate processer interface field for the block matrix is that the processorBlockGAMGInterfaceField
need to be templated in the initInterfaceMatrixUpdate
and updateInterfaceMatrix
.
In first version of the processorBlockGAMGLduInterfaceField
there was a check allowing a the type to be a processorFvPatchField
(which it will also likely be for the first level). Since this else if
case was removed (in order to get rid of dependencies on finiteVolume
as discussed above), no case can be fulfilled and there will be the given error message.
It should be noted that processorFvPatchField
inherits the processorLduInterfaceField
and the coupledFvPatchField
. Thus, the incoming field is actually a processorLduInterfaceField
an additional type check on this will reintroduce the older check, but only using dependencies from foam
:
else if (isA<processorLduInterfaceField>(fineInterfaceField)) { const processorLduInterfaceField& p = refCast<const processorLduInterfaceField >(fineInterfaceField); doTransform_ = p.doTransform(); rank_ = p.rank(); }
Searching the code for all occurrences of the processorBlockLduInterfaceField
it is seen that the only actual occurrence is inside processorBlockGAMGInterfaceField
. Likely the reason for this single apperance is that it is not needed anywhere else in the code. For all other types of processor boundaries the existing processor boundaries are transferred to the BlockLduMatrix
and re-used inside the block matrix. However for the coarsening inside the agglomeration, the processor fields will be based on a BlockLduMatrix
not on the original processor boundaries for the original equations.
Adding the proposed code segment solves the problem, and allows the pUCoupledFoam
to run with correct results on the backwardFacingStep
tutorials.