Previously, the code was only able to handle one neighbor for each ghost layer patch. However, for the full wavelet transformation several neighbors on different levels for the same patch will be needed. A new neighbor formulation enables the coexistence of neighbors on different levels. For all 56 possible patches in 3D we have now 3x56 possible neighbor relations. 2D and 3D codes have been merged to avoid confusion of neighbor codes. Taken from the code, the neighbor formulations are now constructed the following way:
As one can see, sides have 4 possible codes for the 4 possible configurations of blocks on finer level, edges have 2 and corners 1 possible configurations. 2D codes onlz have X- and Y-side with 2 configurations and the X-Y edges with 1 configuration each.
With the change in code formulation the concerning code to compute the boundaries has been revisited and greatly simplified. It should hopefully be clear enough now.
Full wavelet transformation - adapt_tree_cvs
The full wavelet transformation on all levels has been implemented. It works by doing the following steps:
Initialize the full grid from the leaf-layer down to level JMin. New blocks are marked as empty with the refinement flag.
Do the full wavelet decomposition. We work downwards from the leaf-layer. Along the way, interior blocks (blocks which are neither leaf-blocks nor root-blocks on level JMin) can only be decomposed if they have correctly synched blocks from all neighbors on the same level. This way we avoid the need of any coarse extension on blocks besides the leaf-layer blocks. It also effectively creates an iterative decomposition algorithm that starts on the leaf-layer and for later steps mostly works level-wise down to JMin due to restrictions of blocks waiting for their medium-lvl neighbors. Luckily, as the grid information is already present, only synching block values and lgt-data is needed for each step.
Adaption of grid is done only once after the full wavelet transformation was completed. With this, mask and norm information is only computed once. All unsignificant blocks can then be deleted
Full wavelet reconstruction is applied, we work level-wise from lowest layer to the leaf-layer and update the SC of all daughters along the way, afterwards all non-leaf blocks are deleted as they are currently not used for further steps
This algorithm has the following benefits:
Algorithm structure is clear and separated, each step can be found in sub-functions in the code and individually adapted
Decluttering the wavelet decomposition into three steps (grid creation, decomposition and grid adaption) greatly reduces the amount of grid information that need to be updated, in total, the active lists and neighbor formulations are only computed twice!
With the full wavelet decomposition we have more control over the CE and can eradicate it for interior blocks which are passed along the way (blocks which are not leaf-blocks but also will not be leaf-blocks after adaption, so which are only needed temporarily)
The full wavelet reconstruction reduces the block minimum by removing all restrictions previously introduced from the CE. This means 12 for CDF42, 16 for CDF44 and CDF62 are again possible. CDF66 with minimal block size of 24 was the minimal block size for CDF62 before!
Image denoising
The iterative algorithm by Azzalini was implemented in order to compute image denoising. This was introduced as a new step after full wavelet decomposition and before the grid adaption. Possible, CVS iterative algorithm will be introduced here as well but is not yet tested. A new post-processing tool (wabbit-post --denoise) deploys the denoising algorithm on wabbit files of uniform grid to be denoised and a test was added to check the results. Tests show that the denoising algorithm works quite well for the bi-orthogonal wavelets.
Miscellaneous changes
Cosmetic changes to output so they are a bit more beautiful. I work with this stuff daily so some more lines or aligning of output brightens my day
merged some 2D / 3D formulations into one single code to reduce amount of redundant code
option to dump block values and neighbor infos which are usefull for debugging when I don't want to drag everything into paraview
some refinement flag magic, I hope this doesn't get out of hand yet on why I use which flag where
Reformulated neighboring codes
Previously, the code was only able to handle one neighbor for each ghost layer patch. However, for the full wavelet transformation several neighbors on different levels for the same patch will be needed. A new neighbor formulation enables the coexistence of neighbors on different levels. For all 56 possible patches in 3D we have now 3x56 possible neighbor relations. 2D and 3D codes have been merged to avoid confusion of neighbor codes. Taken from the code, the neighbor formulations are now constructed the following way:
As one can see, sides have 4 possible codes for the 4 possible configurations of blocks on finer level, edges have 2 and corners 1 possible configurations. 2D codes onlz have X- and Y-side with 2 configurations and the X-Y edges with 1 configuration each.
With the change in code formulation the concerning code to compute the boundaries has been revisited and greatly simplified. It should hopefully be clear enough now.
Full wavelet transformation -
adapt_tree_cvs
The full wavelet transformation on all levels has been implemented. It works by doing the following steps:
JMin
. New blocks are marked as empty with the refinement flag.JMin
) can only be decomposed if they have correctly synched blocks from all neighbors on the same level. This way we avoid the need of any coarse extension on blocks besides the leaf-layer blocks. It also effectively creates an iterative decomposition algorithm that starts on the leaf-layer and for later steps mostly works level-wise down toJMin
due to restrictions of blocks waiting for their medium-lvl neighbors. Luckily, as the grid information is already present, only synching block values and lgt-data is needed for each step.This algorithm has the following benefits:
Image denoising
The iterative algorithm by Azzalini was implemented in order to compute image denoising. This was introduced as a new step after full wavelet decomposition and before the grid adaption. Possible, CVS iterative algorithm will be introduced here as well but is not yet tested. A new post-processing tool (wabbit-post --denoise) deploys the denoising algorithm on wabbit files of uniform grid to be denoised and a test was added to check the results. Tests show that the denoising algorithm works quite well for the bi-orthogonal wavelets.
Miscellaneous changes