-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose inter-/histopolation matrices in GlobalProjector, add unit tests #347
base: devel
Are you sure you want to change the base?
Conversation
Hi @yguclu, it seems I cannot see why the latest test failed, do you have an idea? Also, did you have time to think about this PR yet? |
Python 3.11 tests passed upon relaunching test, without changes. |
@spossann It seems that the code could be simplified with these steps:
Before making any of these changes, could you please add a parallel test to this PR? |
The function |
Co-authored-by: Yaman Güçlü <yaman.guclu@gmail.com>
…1, this fixes the problem with toarray() which did previously not work for StencilMatrix. Updated indexing in KroneckerStencilMatrix to include shift factors in index calculations. Added back the assert statement in GlobalProjector since the toarray() now works. The kernels still don't work properly for different shifts in the domain and the co-domain, but I believe equivalent changes can be done in the remaining kernels.
- Add compiler flags for GFortran >= 14 on Apple silicon chips - Add unit test in `test_epyccel_flags.py` to check compiler flags passed to `epyccel` - Update GitHub actions used in documentation workflow
NumPy 2.1 deprecates the `newshape` argument of the `reshape` function. Instead, one should use the positional-only argument `shape`. Every call in Psydac has been updated accordingly. This closes #432.
Update `apt` index files with `apt-get update` to avoid download error in CI workflow.
Clarify in the `README.md` file that, although the C backend may be selected for accelerating the kernel files with Pyccel, this is not fully working yet. Hence the Fortran backend (which is the default) is the only one available. A future version of Pyccel will certainly provide a C backend as capable as the Fortran one. See issue #431. Co-authored-by: Martin Campos Pinto <campos@ann.jussieu.fr>
The obsolete property `is_block` was never used in Psydac nor in Struphy, hence we remove it. --------- Co-authored-by: Yaman Güçlü <yaman.guclu@gmail.com>
Fix the indexing in all kernels in `stencil2coo_kernels.py` so that the method `toarray` works for `StencilMatrix` objects in 1D/2D/3D with `shift` larger than 1. The unit tests for `toarray` in `test_stencil_matrix.py` have been parametrized to run with `shift` values of 1 and 2. --------- Co-authored-by: Yaman Güçlü <yaman.guclu@gmail.com>
# TODO: test takes too long in 3D | ||
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
# imat_kronecker_P1 = P1.imat_kronecker | ||
# imat_kronecker_P2 = P2.imat_kronecker | ||
# I1inv = inverse(imat_kronecker_P1, 'gmres', verbose=True) | ||
# I2inv = inverse(imat_kronecker_P2, 'gmres', verbose=True) | ||
|
||
# # build the rhs | ||
# P1.func(fun1, fun2, fun3) | ||
# P2.func(cf1, cf2, cf3) | ||
|
||
# # solve and compare | ||
# u1vec = u1.coeffs | ||
# u1vec_imat = I1inv.solve(P1._rhs) | ||
# assert np.allclose(u1vec.toarray(), u1vec_imat.toarray(), atol=1e-5) | ||
|
||
# u2vec = u2.coeffs | ||
# u2vec_imat = I2inv.solve(P2._rhs) | ||
# assert np.allclose(u2vec.toarray(), u2vec_imat.toarray(), atol=1e-5) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not taking the same approach I suggested in function test_3d_commuting_pro_1
?
# TODO: test takes too long in 3D | ||
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
# imat_kronecker_P2 = P2.imat_kronecker | ||
# imat_kronecker_P3 = P3.imat_kronecker | ||
# I2inv = inverse(imat_kronecker_P2, 'gmres', verbose=True) | ||
# I3inv = inverse(imat_kronecker_P3, 'gmres', verbose=True) | ||
|
||
# # build the rhs | ||
# P2.func(fun1, fun2, fun3) | ||
# P3.func(difun) | ||
|
||
# # solve and compare | ||
# u2vec = u2.coeffs | ||
# u2vec_imat = I2inv.solve(P2._rhs) | ||
# assert np.allclose(u2vec.toarray(), u2vec_imat.toarray(), atol=1e-5) | ||
|
||
# u3vec = u3.coeffs | ||
# u3vec_imat = I3inv.solve(P3._rhs) | ||
# assert np.allclose(u3vec.toarray(), u3vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not taking the same approach I suggested in function test_3d_commuting_pro_1
?
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
imat_kronecker_P0 = P0.imat_kronecker | ||
imat_kronecker_P1 = P1.imat_kronecker | ||
I0inv = inverse(imat_kronecker_P0, 'gmres', verbose=True) | ||
I1inv = inverse(imat_kronecker_P1, 'gmres', verbose=True) | ||
|
||
# build the rhs | ||
P0.func(fun1) | ||
P1.func(D1fun1, D2fun1) | ||
|
||
# solve and compare | ||
u0vec = u0.coeffs | ||
u0vec_imat = I0inv.solve(P0._rhs) | ||
assert np.allclose(u0vec.toarray(), u0vec_imat.toarray(), atol=1e-5) | ||
|
||
u1vec = u1.coeffs | ||
u1vec_imat = I1inv.solve(P1._rhs) | ||
assert np.allclose(u1vec.toarray(), u1vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
imat_kronecker_P0 = P0.imat_kronecker | ||
imat_kronecker_P1 = P1.imat_kronecker | ||
I0inv = inverse(imat_kronecker_P0, 'gmres', verbose=True) | ||
I1inv = inverse(imat_kronecker_P1, 'gmres', verbose=True) | ||
|
||
# build the rhs | ||
P0.func(fun1) | ||
P1.func(D2fun1, D1fun1) | ||
|
||
# solve and compare | ||
u0vec = u0.coeffs | ||
u0vec_imat = I0inv.solve(P0._rhs) | ||
assert np.allclose(u0vec.toarray(), u0vec_imat.toarray(), atol=1e-5) | ||
|
||
u1vec = u1.coeffs | ||
u1vec_imat = I1inv.solve(P1._rhs) | ||
assert np.allclose(u1vec.toarray(), u1vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
imat_kronecker_P2 = P2.imat_kronecker | ||
imat_kronecker_P3 = P3.imat_kronecker | ||
I2inv = inverse(imat_kronecker_P2, 'gmres', verbose=True) | ||
I3inv = inverse(imat_kronecker_P3, 'gmres', verbose=True) | ||
|
||
# build the rhs | ||
P2.func(fun1, fun2) | ||
P3.func(difun) | ||
|
||
# solve and compare | ||
u2vec = u2.coeffs | ||
u2vec_imat = I2inv.solve(P2._rhs) | ||
assert np.allclose(u2vec.toarray(), u2vec_imat.toarray(), atol=1e-5) | ||
|
||
u3vec = u3.coeffs | ||
u3vec_imat = I3inv.solve(P3._rhs) | ||
assert np.allclose(u3vec.toarray(), u3vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
imat_kronecker_P1 = P1.imat_kronecker | ||
imat_kronecker_P2 = P2.imat_kronecker | ||
I1inv = inverse(imat_kronecker_P1, 'gmres', verbose=True) | ||
I2inv = inverse(imat_kronecker_P2, 'gmres', verbose=True) | ||
|
||
# build the rhs | ||
P1.func(fun1, fun2) | ||
P2.func(difun) | ||
|
||
# solve and compare | ||
u1vec = u1.coeffs | ||
u1vec_imat = I1inv.solve(P1._rhs) | ||
assert np.allclose(u1vec.toarray(), u1vec_imat.toarray(), atol=1e-5) | ||
|
||
u2vec = u2.coeffs | ||
u2vec_imat = I2inv.solve(P2._rhs) | ||
assert np.allclose(u2vec.toarray(), u2vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
#-------------------------- | ||
# check BlockLinearOperator | ||
#-------------------------- | ||
# build the solver from the LinearOperator | ||
imat_kronecker_P0 = P0.imat_kronecker | ||
imat_kronecker_P1 = P1.imat_kronecker | ||
I0inv = inverse(imat_kronecker_P0, 'gmres', verbose=True) | ||
I1inv = inverse(imat_kronecker_P1, 'gmres', verbose=True) | ||
|
||
# build the rhs | ||
P0.func(fun1) | ||
P1.func(Dfun1) | ||
|
||
# solve and compare | ||
u0vec = u0.coeffs | ||
u0vec_imat = I0inv.solve(P0._rhs) | ||
assert np.allclose(u0vec.toarray(), u0vec_imat.toarray(), atol=1e-5) | ||
|
||
u1vec = u1.coeffs | ||
u1vec_imat = I1inv.solve(P1._rhs) | ||
assert np.allclose(u1vec.toarray(), u1vec_imat.toarray(), atol=1e-5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
Addresses issue #346.
The inter-/histopolation matrices are now exposed in
GlobalProjector
asKroneckerStencilMatrix
orBlockLinearOperator
(for vector-valued spaces).The unit tests in
feec/tests/test_commuting_projections.py
have been enhanced: they now also test the newLinearOperator
inGlobalProjector.imat_kronecker
by computing its inverse usingGMRES
and comparing to the originalBlockDiagonalSolver
solution. 3D tests are commented out for the moment as they take too long (better solution)?