{"diffoscope-json-version": 1, "source1": "/srv/reproducible-results/rbuild-debian/r-b-build.9jBarTQk/b1/dune-istl_2.9.0-2_armhf.changes", "source2": "/srv/reproducible-results/rbuild-debian/r-b-build.9jBarTQk/b2/dune-istl_2.9.0-2_armhf.changes", "unified_diff": null, "details": [{"source1": "Files", "source2": "Files", "unified_diff": "@@ -1,3 +1,3 @@\n \n 86455f7c93963ec6720d6b93999b5ca5 210164 libdevel optional libdune-istl-dev_2.9.0-2_armhf.deb\n- c8f40c50027f67a8cc4ac5a6d167d952 3373484 doc optional libdune-istl-doc_2.9.0-2_all.deb\n+ c8c70cdc0820c8c8f25b61724db8b015 3374200 doc optional libdune-istl-doc_2.9.0-2_all.deb\n"}, {"source1": "libdune-istl-doc_2.9.0-2_all.deb", "source2": "libdune-istl-doc_2.9.0-2_all.deb", "unified_diff": null, "details": [{"source1": "file list", "source2": "file list", "unified_diff": "@@ -1,3 +1,3 @@\n -rw-r--r-- 0 0 0 4 2023-01-12 16:57:44.000000 debian-binary\n--rw-r--r-- 0 0 0 25816 2023-01-12 16:57:44.000000 control.tar.xz\n--rw-r--r-- 0 0 0 3347476 2023-01-12 16:57:44.000000 data.tar.xz\n+-rw-r--r-- 0 0 0 25784 2023-01-12 16:57:44.000000 control.tar.xz\n+-rw-r--r-- 0 0 0 3348224 2023-01-12 16:57:44.000000 data.tar.xz\n"}, {"source1": "control.tar.xz", "source2": "control.tar.xz", "unified_diff": null, "details": [{"source1": "control.tar", "source2": "control.tar", "unified_diff": null, "details": [{"source1": "./md5sums", "source2": "./md5sums", "unified_diff": null, "details": [{"source1": "./md5sums", "source2": "./md5sums", "comments": ["Files differ"], "unified_diff": null}]}]}]}, {"source1": "data.tar.xz", "source2": "data.tar.xz", "unified_diff": null, "details": [{"source1": "data.tar", "source2": "data.tar", "unified_diff": null, "details": [{"source1": "file list", "source2": "file list", "unified_diff": "@@ -5,162 +5,162 @@\n drwxr-xr-x 0 root (0) root (0) 0 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/\n -rw-r--r-- 0 root (0) root (0) 854 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/changelog.Debian.gz\n -rw-r--r-- 0 root (0) root (0) 3688 2022-10-20 18:22:18.000000 ./usr/share/doc/libdune-istl-doc/changelog.gz\n -rw-r--r-- 0 root (0) root (0) 3254 2023-01-12 15:07:31.000000 ./usr/share/doc/libdune-istl-doc/copyright\n drwxr-xr-x 0 root (0) root (0) 0 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/\n -rw-r--r-- 0 root (0) root (0) 2871 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00002.html\n -rw-r--r-- 0 root (0) root (0) 2869 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00005.html\n--rw-r--r-- 0 root (0) root (0) 7717 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00008.html\n--rw-r--r-- 0 root (0) root (0) 33570 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00008_source.html\n--rw-r--r-- 0 root (0) root (0) 7837 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00011.html\n--rw-r--r-- 0 root (0) root (0) 40522 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00011_source.html\n--rw-r--r-- 0 root (0) root (0) 8323 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00014.html\n--rw-r--r-- 0 root (0) root (0) 71590 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00014_source.html\n--rw-r--r-- 0 root (0) root (0) 12963 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00017.html\n--rw-r--r-- 0 root (0) root (0) 126398 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00017_source.html\n--rw-r--r-- 0 root (0) root (0) 4495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00020.html\n--rw-r--r-- 0 root (0) root (0) 22574 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00020_source.html\n--rw-r--r-- 0 root (0) root (0) 7494 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00023.html\n--rw-r--r-- 0 root (0) root (0) 212945 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00023_source.html\n--rw-r--r-- 0 root (0) root (0) 12891 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00026.html\n--rw-r--r-- 0 root (0) root (0) 180591 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00026_source.html\n--rw-r--r-- 0 root (0) root (0) 3194 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00029.html\n--rw-r--r-- 0 root (0) root (0) 58130 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00029_source.html\n--rw-r--r-- 0 root (0) root (0) 6385 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00032.html\n--rw-r--r-- 0 root (0) root (0) 33148 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00032_source.html\n--rw-r--r-- 0 root (0) root (0) 5746 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00035.html\n--rw-r--r-- 0 root (0) root (0) 161570 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00035_source.html\n--rw-r--r-- 0 root (0) root (0) 5262 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00038.html\n--rw-r--r-- 0 root (0) root (0) 164128 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00038_source.html\n--rw-r--r-- 0 root (0) root (0) 9883 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00041.html\n--rw-r--r-- 0 root (0) root (0) 105495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00041_source.html\n--rw-r--r-- 0 root (0) root (0) 42515 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00044.html\n--rw-r--r-- 0 root (0) root (0) 248391 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00044_source.html\n--rw-r--r-- 0 root (0) root (0) 4767 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00047.html\n--rw-r--r-- 0 root (0) root (0) 8949 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00047_source.html\n--rw-r--r-- 0 root (0) root (0) 4372 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00050.html\n--rw-r--r-- 0 root (0) root (0) 55436 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00050_source.html\n--rw-r--r-- 0 root (0) root (0) 11724 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00053.html\n--rw-r--r-- 0 root (0) root (0) 20544 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00053_source.html\n--rw-r--r-- 0 root (0) root (0) 16188 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00056.html\n--rw-r--r-- 0 root (0) root (0) 312739 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00056_source.html\n--rw-r--r-- 0 root (0) root (0) 9041 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00059.html\n--rw-r--r-- 0 root (0) root (0) 72205 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00059_source.html\n--rw-r--r-- 0 root (0) root (0) 9759 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00062.html\n--rw-r--r-- 0 root (0) root (0) 11519 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00062_source.html\n--rw-r--r-- 0 root (0) root (0) 7405 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00065.html\n--rw-r--r-- 0 root (0) root (0) 16983 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00065_source.html\n--rw-r--r-- 0 root (0) root (0) 9064 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00068.html\n--rw-r--r-- 0 root (0) root (0) 118492 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00068_source.html\n--rw-r--r-- 0 root (0) root (0) 14364 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00071.html\n--rw-r--r-- 0 root (0) root (0) 146862 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00071_source.html\n--rw-r--r-- 0 root (0) root (0) 5387 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00074.html\n--rw-r--r-- 0 root (0) root (0) 35953 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00074_source.html\n--rw-r--r-- 0 root (0) root (0) 4601 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00077.html\n--rw-r--r-- 0 root (0) root (0) 14443 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00077_source.html\n--rw-r--r-- 0 root (0) root (0) 11282 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00080.html\n--rw-r--r-- 0 root (0) root (0) 114734 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00080_source.html\n--rw-r--r-- 0 root (0) root (0) 4187 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00083.html\n--rw-r--r-- 0 root (0) root (0) 17914 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00083_source.html\n--rw-r--r-- 0 root (0) root (0) 6744 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00086.html\n--rw-r--r-- 0 root (0) root (0) 13325 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00086_source.html\n--rw-r--r-- 0 root (0) root (0) 7370 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00089.html\n--rw-r--r-- 0 root (0) root (0) 141502 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00089_source.html\n--rw-r--r-- 0 root (0) root (0) 12633 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00092.html\n--rw-r--r-- 0 root (0) root (0) 301011 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00092_source.html\n+-rw-r--r-- 0 root (0) root (0) 17714 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00008.html\n+-rw-r--r-- 0 root (0) root (0) 124353 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00008_source.html\n+-rw-r--r-- 0 root (0) root (0) 6168 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00011.html\n+-rw-r--r-- 0 root (0) root (0) 131059 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00011_source.html\n+-rw-r--r-- 0 root (0) root (0) 5387 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00014.html\n+-rw-r--r-- 0 root (0) root (0) 35953 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00014_source.html\n+-rw-r--r-- 0 root (0) root (0) 10253 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00017.html\n+-rw-r--r-- 0 root (0) root (0) 145593 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00017_source.html\n+-rw-r--r-- 0 root (0) root (0) 9352 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00020.html\n+-rw-r--r-- 0 root (0) root (0) 40477 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00020_source.html\n+-rw-r--r-- 0 root (0) root (0) 5861 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00023.html\n+-rw-r--r-- 0 root (0) root (0) 110641 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00023_source.html\n+-rw-r--r-- 0 root (0) root (0) 4767 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00026.html\n+-rw-r--r-- 0 root (0) root (0) 8949 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00026_source.html\n+-rw-r--r-- 0 root (0) root (0) 11724 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00029.html\n+-rw-r--r-- 0 root (0) root (0) 20544 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00029_source.html\n+-rw-r--r-- 0 root (0) root (0) 7405 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00032.html\n+-rw-r--r-- 0 root (0) root (0) 16983 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00032_source.html\n+-rw-r--r-- 0 root (0) root (0) 9759 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00035.html\n+-rw-r--r-- 0 root (0) root (0) 11519 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00035_source.html\n+-rw-r--r-- 0 root (0) root (0) 6613 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00038.html\n+-rw-r--r-- 0 root (0) root (0) 73107 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00038_source.html\n+-rw-r--r-- 0 root (0) root (0) 8906 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00041.html\n+-rw-r--r-- 0 root (0) root (0) 122084 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00041_source.html\n+-rw-r--r-- 0 root (0) root (0) 4346 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00044.html\n+-rw-r--r-- 0 root (0) root (0) 60032 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00044_source.html\n+-rw-r--r-- 0 root (0) root (0) 9064 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00047.html\n+-rw-r--r-- 0 root (0) root (0) 118492 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00047_source.html\n+-rw-r--r-- 0 root (0) root (0) 7837 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00050.html\n+-rw-r--r-- 0 root (0) root (0) 40522 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00050_source.html\n+-rw-r--r-- 0 root (0) root (0) 9541 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00053.html\n+-rw-r--r-- 0 root (0) root (0) 129330 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00053_source.html\n+-rw-r--r-- 0 root (0) root (0) 9883 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00056.html\n+-rw-r--r-- 0 root (0) root (0) 105495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00056_source.html\n+-rw-r--r-- 0 root (0) root (0) 8323 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00059.html\n+-rw-r--r-- 0 root (0) root (0) 71590 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00059_source.html\n+-rw-r--r-- 0 root (0) root (0) 12963 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00062.html\n+-rw-r--r-- 0 root (0) root (0) 126398 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00062_source.html\n+-rw-r--r-- 0 root (0) root (0) 8348 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00065.html\n+-rw-r--r-- 0 root (0) root (0) 75580 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00065_source.html\n+-rw-r--r-- 0 root (0) root (0) 7494 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00068.html\n+-rw-r--r-- 0 root (0) root (0) 212945 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00068_source.html\n+-rw-r--r-- 0 root (0) root (0) 6952 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00071.html\n+-rw-r--r-- 0 root (0) root (0) 57377 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00071_source.html\n+-rw-r--r-- 0 root (0) root (0) 42515 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00074.html\n+-rw-r--r-- 0 root (0) root (0) 248391 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00074_source.html\n+-rw-r--r-- 0 root (0) root (0) 8708 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00077.html\n+-rw-r--r-- 0 root (0) root (0) 404869 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00077_source.html\n+-rw-r--r-- 0 root (0) root (0) 6385 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00080.html\n+-rw-r--r-- 0 root (0) root (0) 33148 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00080_source.html\n+-rw-r--r-- 0 root (0) root (0) 7470 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00083.html\n+-rw-r--r-- 0 root (0) root (0) 59304 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00083_source.html\n+-rw-r--r-- 0 root (0) root (0) 4372 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00086.html\n+-rw-r--r-- 0 root (0) root (0) 55436 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00086_source.html\n+-rw-r--r-- 0 root (0) root (0) 19165 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00089.html\n+-rw-r--r-- 0 root (0) root (0) 291433 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00089_source.html\n+-rw-r--r-- 0 root (0) root (0) 5414 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00092.html\n+-rw-r--r-- 0 root (0) root (0) 43871 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00092_source.html\n -rw-r--r-- 0 root (0) root (0) 8236 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00095.html\n -rw-r--r-- 0 root (0) root (0) 34613 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00095_source.html\n--rw-r--r-- 0 root (0) root (0) 13401 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00098.html\n--rw-r--r-- 0 root (0) root (0) 345595 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00098_source.html\n--rw-r--r-- 0 root (0) root (0) 15424 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00101.html\n--rw-r--r-- 0 root (0) root (0) 405954 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00101_source.html\n--rw-r--r-- 0 root (0) root (0) 9232 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00104.html\n--rw-r--r-- 0 root (0) root (0) 130202 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00104_source.html\n--rw-r--r-- 0 root (0) root (0) 7704 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00107.html\n--rw-r--r-- 0 root (0) root (0) 64146 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00107_source.html\n--rw-r--r-- 0 root (0) root (0) 6365 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00110.html\n--rw-r--r-- 0 root (0) root (0) 66163 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00110_source.html\n--rw-r--r-- 0 root (0) root (0) 7323 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00113.html\n--rw-r--r-- 0 root (0) root (0) 96885 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00113_source.html\n--rw-r--r-- 0 root (0) root (0) 9211 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00116.html\n--rw-r--r-- 0 root (0) root (0) 46061 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00116_source.html\n--rw-r--r-- 0 root (0) root (0) 5594 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00119.html\n--rw-r--r-- 0 root (0) root (0) 20046 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00119_source.html\n--rw-r--r-- 0 root (0) root (0) 4988 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00122.html\n--rw-r--r-- 0 root (0) root (0) 21374 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00122_source.html\n--rw-r--r-- 0 root (0) root (0) 9153 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00125.html\n--rw-r--r-- 0 root (0) root (0) 238440 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00125_source.html\n--rw-r--r-- 0 root (0) root (0) 6468 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00128.html\n--rw-r--r-- 0 root (0) root (0) 51068 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00128_source.html\n--rw-r--r-- 0 root (0) root (0) 5199 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00131.html\n--rw-r--r-- 0 root (0) root (0) 28331 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00131_source.html\n--rw-r--r-- 0 root (0) root (0) 8531 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00134.html\n--rw-r--r-- 0 root (0) root (0) 65614 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00134_source.html\n--rw-r--r-- 0 root (0) root (0) 7057 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00137.html\n--rw-r--r-- 0 root (0) root (0) 73254 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00137_source.html\n--rw-r--r-- 0 root (0) root (0) 7942 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00140.html\n--rw-r--r-- 0 root (0) root (0) 123684 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00140_source.html\n--rw-r--r-- 0 root (0) root (0) 5481 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00143.html\n--rw-r--r-- 0 root (0) root (0) 29849 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00143_source.html\n--rw-r--r-- 0 root (0) root (0) 6205 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00146.html\n--rw-r--r-- 0 root (0) root (0) 64117 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00146_source.html\n--rw-r--r-- 0 root (0) root (0) 5239 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00149.html\n--rw-r--r-- 0 root (0) root (0) 13971 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00149_source.html\n--rw-r--r-- 0 root (0) root (0) 18574 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00152.html\n--rw-r--r-- 0 root (0) root (0) 201844 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00152_source.html\n--rw-r--r-- 0 root (0) root (0) 6151 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00155.html\n--rw-r--r-- 0 root (0) root (0) 16557 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00155_source.html\n--rw-r--r-- 0 root (0) root (0) 10462 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00158.html\n--rw-r--r-- 0 root (0) root (0) 184301 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00158_source.html\n--rw-r--r-- 0 root (0) root (0) 8890 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00161.html\n--rw-r--r-- 0 root (0) root (0) 84479 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00161_source.html\n--rw-r--r-- 0 root (0) root (0) 9352 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00164.html\n--rw-r--r-- 0 root (0) root (0) 40477 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00164_source.html\n--rw-r--r-- 0 root (0) root (0) 11679 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00167.html\n--rw-r--r-- 0 root (0) root (0) 78033 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00167_source.html\n--rw-r--r-- 0 root (0) root (0) 6615 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00170.html\n--rw-r--r-- 0 root (0) root (0) 10800 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00170_source.html\n--rw-r--r-- 0 root (0) root (0) 8348 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00173.html\n--rw-r--r-- 0 root (0) root (0) 75580 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00173_source.html\n--rw-r--r-- 0 root (0) root (0) 6952 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00176.html\n--rw-r--r-- 0 root (0) root (0) 57377 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00176_source.html\n--rw-r--r-- 0 root (0) root (0) 7470 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00179.html\n--rw-r--r-- 0 root (0) root (0) 59304 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00179_source.html\n--rw-r--r-- 0 root (0) root (0) 15027 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00182.html\n--rw-r--r-- 0 root (0) root (0) 47248 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00182_source.html\n--rw-r--r-- 0 root (0) root (0) 5861 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00185.html\n--rw-r--r-- 0 root (0) root (0) 110641 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00185_source.html\n--rw-r--r-- 0 root (0) root (0) 4495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00188.html\n--rw-r--r-- 0 root (0) root (0) 23724 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00188_source.html\n--rw-r--r-- 0 root (0) root (0) 4738 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00191.html\n--rw-r--r-- 0 root (0) root (0) 13670 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00191_source.html\n--rw-r--r-- 0 root (0) root (0) 8906 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00194.html\n--rw-r--r-- 0 root (0) root (0) 122084 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00194_source.html\n--rw-r--r-- 0 root (0) root (0) 8708 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00197.html\n--rw-r--r-- 0 root (0) root (0) 404869 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00197_source.html\n--rw-r--r-- 0 root (0) root (0) 5414 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00200.html\n--rw-r--r-- 0 root (0) root (0) 43871 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00200_source.html\n--rw-r--r-- 0 root (0) root (0) 6178 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00203.html\n--rw-r--r-- 0 root (0) root (0) 42555 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00203_source.html\n--rw-r--r-- 0 root (0) root (0) 10253 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00206.html\n--rw-r--r-- 0 root (0) root (0) 145593 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00206_source.html\n--rw-r--r-- 0 root (0) root (0) 19165 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00209.html\n--rw-r--r-- 0 root (0) root (0) 291433 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00209_source.html\n--rw-r--r-- 0 root (0) root (0) 6613 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00212.html\n--rw-r--r-- 0 root (0) root (0) 73107 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00212_source.html\n--rw-r--r-- 0 root (0) root (0) 9541 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00215.html\n--rw-r--r-- 0 root (0) root (0) 129330 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00215_source.html\n--rw-r--r-- 0 root (0) root (0) 6168 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00218.html\n--rw-r--r-- 0 root (0) root (0) 131059 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00218_source.html\n--rw-r--r-- 0 root (0) root (0) 17714 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00221.html\n--rw-r--r-- 0 root (0) root (0) 124353 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00221_source.html\n--rw-r--r-- 0 root (0) root (0) 33507 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00224.html\n--rw-r--r-- 0 root (0) root (0) 140189 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00224_source.html\n--rw-r--r-- 0 root (0) root (0) 4346 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00227.html\n--rw-r--r-- 0 root (0) root (0) 60032 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00227_source.html\n+-rw-r--r-- 0 root (0) root (0) 11282 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00098.html\n+-rw-r--r-- 0 root (0) root (0) 114734 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00098_source.html\n+-rw-r--r-- 0 root (0) root (0) 12891 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00101.html\n+-rw-r--r-- 0 root (0) root (0) 180591 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00101_source.html\n+-rw-r--r-- 0 root (0) root (0) 3194 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00104.html\n+-rw-r--r-- 0 root (0) root (0) 58130 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00104_source.html\n+-rw-r--r-- 0 root (0) root (0) 4187 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00107.html\n+-rw-r--r-- 0 root (0) root (0) 17914 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00107_source.html\n+-rw-r--r-- 0 root (0) root (0) 12633 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00110.html\n+-rw-r--r-- 0 root (0) root (0) 301011 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00110_source.html\n+-rw-r--r-- 0 root (0) root (0) 6744 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00113.html\n+-rw-r--r-- 0 root (0) root (0) 13325 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00113_source.html\n+-rw-r--r-- 0 root (0) root (0) 4601 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00116.html\n+-rw-r--r-- 0 root (0) root (0) 14443 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00116_source.html\n+-rw-r--r-- 0 root (0) root (0) 9041 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00119.html\n+-rw-r--r-- 0 root (0) root (0) 72205 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00119_source.html\n+-rw-r--r-- 0 root (0) root (0) 7370 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00122.html\n+-rw-r--r-- 0 root (0) root (0) 141502 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00122_source.html\n+-rw-r--r-- 0 root (0) root (0) 6178 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00125.html\n+-rw-r--r-- 0 root (0) root (0) 42555 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00125_source.html\n+-rw-r--r-- 0 root (0) root (0) 6615 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00128.html\n+-rw-r--r-- 0 root (0) root (0) 10800 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00128_source.html\n+-rw-r--r-- 0 root (0) root (0) 15424 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00131.html\n+-rw-r--r-- 0 root (0) root (0) 405954 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00131_source.html\n+-rw-r--r-- 0 root (0) root (0) 13401 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00134.html\n+-rw-r--r-- 0 root (0) root (0) 345595 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00134_source.html\n+-rw-r--r-- 0 root (0) root (0) 7942 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00137.html\n+-rw-r--r-- 0 root (0) root (0) 123684 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00137_source.html\n+-rw-r--r-- 0 root (0) root (0) 6365 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00140.html\n+-rw-r--r-- 0 root (0) root (0) 66163 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00140_source.html\n+-rw-r--r-- 0 root (0) root (0) 8890 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00143.html\n+-rw-r--r-- 0 root (0) root (0) 84479 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00143_source.html\n+-rw-r--r-- 0 root (0) root (0) 6468 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00146.html\n+-rw-r--r-- 0 root (0) root (0) 51068 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00146_source.html\n+-rw-r--r-- 0 root (0) root (0) 4988 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00149.html\n+-rw-r--r-- 0 root (0) root (0) 21374 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00149_source.html\n+-rw-r--r-- 0 root (0) root (0) 7323 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00152.html\n+-rw-r--r-- 0 root (0) root (0) 96885 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00152_source.html\n+-rw-r--r-- 0 root (0) root (0) 5199 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00155.html\n+-rw-r--r-- 0 root (0) root (0) 28331 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00155_source.html\n+-rw-r--r-- 0 root (0) root (0) 7057 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00158.html\n+-rw-r--r-- 0 root (0) root (0) 73254 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00158_source.html\n+-rw-r--r-- 0 root (0) root (0) 10462 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00161.html\n+-rw-r--r-- 0 root (0) root (0) 184301 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00161_source.html\n+-rw-r--r-- 0 root (0) root (0) 5481 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00164.html\n+-rw-r--r-- 0 root (0) root (0) 29849 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00164_source.html\n+-rw-r--r-- 0 root (0) root (0) 5594 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00167.html\n+-rw-r--r-- 0 root (0) root (0) 20046 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00167_source.html\n+-rw-r--r-- 0 root (0) root (0) 5239 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00170.html\n+-rw-r--r-- 0 root (0) root (0) 13971 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00170_source.html\n+-rw-r--r-- 0 root (0) root (0) 6151 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00173.html\n+-rw-r--r-- 0 root (0) root (0) 16557 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00173_source.html\n+-rw-r--r-- 0 root (0) root (0) 9211 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00176.html\n+-rw-r--r-- 0 root (0) root (0) 46061 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00176_source.html\n+-rw-r--r-- 0 root (0) root (0) 18574 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00179.html\n+-rw-r--r-- 0 root (0) root (0) 201844 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00179_source.html\n+-rw-r--r-- 0 root (0) root (0) 9232 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00182.html\n+-rw-r--r-- 0 root (0) root (0) 130202 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00182_source.html\n+-rw-r--r-- 0 root (0) root (0) 8531 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00185.html\n+-rw-r--r-- 0 root (0) root (0) 65614 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00185_source.html\n+-rw-r--r-- 0 root (0) root (0) 9153 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00188.html\n+-rw-r--r-- 0 root (0) root (0) 238440 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00188_source.html\n+-rw-r--r-- 0 root (0) root (0) 7704 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00191.html\n+-rw-r--r-- 0 root (0) root (0) 64146 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00191_source.html\n+-rw-r--r-- 0 root (0) root (0) 6205 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00194.html\n+-rw-r--r-- 0 root (0) root (0) 64117 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00194_source.html\n+-rw-r--r-- 0 root (0) root (0) 16188 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00197.html\n+-rw-r--r-- 0 root (0) root (0) 312739 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00197_source.html\n+-rw-r--r-- 0 root (0) root (0) 5262 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00200.html\n+-rw-r--r-- 0 root (0) root (0) 164128 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00200_source.html\n+-rw-r--r-- 0 root (0) root (0) 5746 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00203.html\n+-rw-r--r-- 0 root (0) root (0) 161570 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00203_source.html\n+-rw-r--r-- 0 root (0) root (0) 4495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00206.html\n+-rw-r--r-- 0 root (0) root (0) 23724 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00206_source.html\n+-rw-r--r-- 0 root (0) root (0) 33507 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00209.html\n+-rw-r--r-- 0 root (0) root (0) 140189 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00209_source.html\n+-rw-r--r-- 0 root (0) root (0) 7717 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00212.html\n+-rw-r--r-- 0 root (0) root (0) 33570 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00212_source.html\n+-rw-r--r-- 0 root (0) root (0) 15027 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00215.html\n+-rw-r--r-- 0 root (0) root (0) 47248 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00215_source.html\n+-rw-r--r-- 0 root (0) root (0) 11679 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00218.html\n+-rw-r--r-- 0 root (0) root (0) 78033 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00218_source.html\n+-rw-r--r-- 0 root (0) root (0) 14364 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00221.html\n+-rw-r--r-- 0 root (0) root (0) 146862 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00221_source.html\n+-rw-r--r-- 0 root (0) root (0) 4738 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00224.html\n+-rw-r--r-- 0 root (0) root (0) 13670 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00224_source.html\n+-rw-r--r-- 0 root (0) root (0) 4495 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00227.html\n+-rw-r--r-- 0 root (0) root (0) 22574 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00227_source.html\n -rw-r--r-- 0 root (0) root (0) 5348 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00230.html\n -rw-r--r-- 0 root (0) root (0) 3247 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00231.html\n -rw-r--r-- 0 root (0) root (0) 3556 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00232.html\n -rw-r--r-- 0 root (0) root (0) 273229 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00233.html\n -rw-r--r-- 0 root (0) root (0) 19915 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00233.png\n -rw-r--r-- 0 root (0) root (0) 30741 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00234.html\n -rw-r--r-- 0 root (0) root (0) 17263 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/a00234.png\n@@ -1089,15 +1089,15 @@\n -rw-r--r-- 0 root (0) root (0) 4054 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dir_5e69be5995c9f5d42bf491ae6f29600e.html\n -rw-r--r-- 0 root (0) root (0) 1480 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dir_5e69be5995c9f5d42bf491ae6f29600e_dep.png\n -rw-r--r-- 0 root (0) root (0) 13524 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dir_667edbdb0a8210232217f5e7df6d52d4.html\n -rw-r--r-- 0 root (0) root (0) 2009 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dir_667edbdb0a8210232217f5e7df6d52d4_dep.png\n -rw-r--r-- 0 root (0) root (0) 3472 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dir_e68e8157741866f444e17edd764ebbae.html\n -rw-r--r-- 0 root (0) root (0) 746 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/doc.png\n -rw-r--r-- 0 root (0) root (0) 33676 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/doxygen.css\n--rw-r--r-- 0 root (0) root (0) 181946 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dune-istl.tag.gz\n+-rw-r--r-- 0 root (0) root (0) 181955 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dune-istl.tag.gz\n -rw-r--r-- 0 root (0) root (0) 4452 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/dynsections.js\n -rw-r--r-- 0 root (0) root (0) 28348 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/files.html\n -rw-r--r-- 0 root (0) root (0) 616 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/folderclosed.png\n -rw-r--r-- 0 root (0) root (0) 597 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/folderopen.png\n -rw-r--r-- 0 root (0) root (0) 2678 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/form_0.png\n -rw-r--r-- 0 root (0) root (0) 2659 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/form_1.png\n -rw-r--r-- 0 root (0) root (0) 2843 2023-01-12 16:57:44.000000 ./usr/share/doc/libdune-istl-doc/doxygen/form_10.png\n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00008.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00008.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: blocklevel.hh File Reference\n+dune-istl: io.hh File Reference\n \n \n \n \n \n \n \n@@ -63,56 +63,107 @@\n
\n \n
\n \n
\n
\n+Classes |\n Namespaces |\n Functions
\n-
blocklevel.hh File Reference
\n+
\n
\n
\n \n-

Helper functions for determining the vector/matrix block level. \n+

Some generic functions for pretty printing vectors and matrices. \n More...

\n-
#include <algorithm>
\n-#include <type_traits>
\n-#include <dune/common/indices.hh>
\n-#include <dune/common/typetraits.hh>
\n+
#include <cmath>
\n+#include <complex>
\n+#include <limits>
\n+#include <ios>
\n+#include <iomanip>
\n+#include <fstream>
\n+#include <string>
\n+#include "matrixutils.hh"
\n+#include "istlexception.hh"
\n+#include <dune/common/fvector.hh>
\n+#include <dune/common/fmatrix.hh>
\n #include <dune/common/hybridutilities.hh>
\n+#include <dune/common/reservedvector.hh>
\n+#include <dune/istl/bcrsmatrix.hh>
\n+#include <dune/istl/blocklevel.hh>
\n
\n

Go to the source code of this file.

\n \n+\n+\n+\n+\n+

\n+Classes

struct  Dune::DefaultSVGMatrixOptions
 Default options class to write SVG matrices. More...
 
\n \n \n \n

\n Namespaces

namespace  Dune
 
\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

\n Functions

template<typename T >
constexpr std::size_t Dune::maxBlockLevel ()
 Determine the maximum block level of a possibly nested vector/matrix type. More...
 
template<typename T >
constexpr std::size_t Dune::minBlockLevel ()
 Determine the minimum block level of a possibly nested vector/matrix type. More...
 
template<typename T >
constexpr bool Dune::hasUniqueBlockLevel ()
 Determine if a vector/matrix has a uniquely determinable block level. More...
 
template<typename T >
constexpr std::size_t Dune::blockLevel ()
 Determine the block level of a possibly nested vector/matrix type. More...
 
template<class V >
void Dune::recursive_printvector (std::ostream &s, const V &v, std::string rowtext, int &counter, int columns, int width)
 Recursively print a vector. More...
 
template<class V >
void Dune::printvector (std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
 Print an ISTL vector. More...
 
void Dune::fill_row (std::ostream &s, int m, int width, int precision)
 Print a row of zeros for a non-existing block. More...
 
template<class K >
void Dune::print_row (std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
 Print one row of a matrix, specialization for number types. More...
 
template<class M >
void Dune::print_row (std::ostream &s, const M &A, typename M::size_type I, typename M::size_type J, typename M::size_type therow, int width, int precision, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
 Print one row of a matrix. More...
 
template<class M >
void Dune::printmatrix (std::ostream &s, const M &A, std::string title, std::string rowtext, int width=10, int precision=2)
 Print a generic block matrix. More...
 
template<class B , int n, int m, class A >
void Dune::printSparseMatrix (std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3, int precision=2)
 Prints a BCRSMatrix with fixed sized blocks. More...
 
template<class FieldType >
void Dune::writeMatrixToMatlabHelper (const FieldType &value, int rowOffset, int colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber< FieldType >::value > *sfinae=nullptr)
 Helper method for the writeMatrixToMatlab routine. More...
 
template<class MatrixType >
void Dune::writeMatrixToMatlabHelper (const MatrixType &matrix, int externalRowOffset, int externalColOffset, std::ostream &s, typename std::enable_if_t<!Dune::IsNumber< MatrixType >::value > *sfinae=nullptr)
 Helper method for the writeMatrixToMatlab routine. More...
 
template<class MatrixType >
void Dune::writeMatrixToMatlab (const MatrixType &matrix, const std::string &filename, int outputPrecision=18)
 Writes sparse matrix in a Matlab-readable format. More...
 
template<class V >
void Dune::writeVectorToMatlabHelper (const V &v, std::ostream &stream)
 
template<class VectorType >
void Dune::writeVectorToMatlab (const VectorType &vector, const std::string &filename, int outputPrecision=18)
 Writes vectors in a Matlab-readable format. More...
 
template<class Mat , class SVGOptions = DefaultSVGMatrixOptions>
void Dune::writeSVGMatrix (const Mat &mat, std::ostream &out, SVGOptions opts={})
 Writes the visualization of matrix in the SVG format. More...
 
\n

Detailed Description

\n-

Helper functions for determining the vector/matrix block level.

\n+

Some generic functions for pretty printing vectors and matrices.

\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,45 +4,110 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Namespaces | Functions\n-blocklevel.hh File Reference\n-Helper functions for determining the vector/matrix block level. More...\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+io.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes \u00bb\n+IO_for_matrices_and_vectors.\n+Some generic functions for pretty printing vectors and matrices. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"matrixutils.hh\"\n+#include \"istlexception.hh\"\n+#include \n+#include \n #include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n+ Classes\n+struct \u00a0Dune::DefaultSVGMatrixOptions\n+\u00a0 Default options class to write SVG matrices. More...\n+\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n Functions\n-template\n-constexpr std::size_t\u00a0Dune::maxBlockLevel ()\n-\u00a0 Determine the maximum block level of a possibly nested\n- vector/matrix type. More...\n-\u00a0\n-template\n-constexpr std::size_t\u00a0Dune::minBlockLevel ()\n-\u00a0 Determine the minimum block level of a possibly nested\n- vector/matrix type. More...\n-\u00a0\n-template\n- constexpr bool\u00a0Dune::hasUniqueBlockLevel ()\n-\u00a0 Determine if a vector/matrix has a uniquely determinable\n- block level. More...\n-\u00a0\n-template\n-constexpr std::size_t\u00a0Dune::blockLevel ()\n-\u00a0 Determine the block level of a possibly nested vector/\n- matrix type. More...\n+template\n+void\u00a0Dune::recursive_printvector (std::ostream &s, const V &v, std::string\n+ rowtext, int &counter, int columns, int width)\n+\u00a0 Recursively print a vector. More...\n+\u00a0\n+template\n+void\u00a0Dune::printvector (std::ostream &s, const V &v, std::string title, std::\n+ string rowtext, int columns=1, int width=10, int precision=2)\n+\u00a0 Print an ISTL vector. More...\n+\u00a0\n+void\u00a0Dune::fill_row (std::ostream &s, int m, int width, int precision)\n+\u00a0 Print a row of zeros for a non-existing block. More...\n+\u00a0\n+template\n+void\u00a0Dune::print_row (std::ostream &s, const K &value, typename FieldMatrix<\n+ K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J,\n+ typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int\n+ precision, typename std::enable_if_t< Dune::IsNumber< K >::value >\n+ *sfinae=nullptr)\n+\u00a0 Print one row of a matrix, specialization for number types. More...\n+\u00a0\n+template\n+void\u00a0Dune::print_row (std::ostream &s, const M &A, typename M::size_type I,\n+ typename M::size_type J, typename M::size_type therow, int width, int\n+ precision, typename std::enable_if_t::value >\n+ *sfinae=nullptr)\n+\u00a0 Print one row of a matrix. More...\n+\u00a0\n+template\n+void\u00a0Dune::printmatrix (std::ostream &s, const M &A, std::string title, std::\n+ string rowtext, int width=10, int precision=2)\n+\u00a0 Print a generic block matrix. More...\n+\u00a0\n+template\n+void\u00a0Dune::printSparseMatrix (std::ostream &s, const BCRSMatrix< FieldMatrix<\n+ B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3,\n+ int precision=2)\n+\u00a0 Prints a BCRSMatrix with fixed sized blocks. More...\n+\u00a0\n+template\n+void\u00a0Dune::writeMatrixToMatlabHelper (const FieldType &value, int rowOffset,\n+ int colOffset, std::ostream &s, typename std::enable_if_t< Dune::\n+ IsNumber< FieldType >::value > *sfinae=nullptr)\n+\u00a0 Helper method for the writeMatrixToMatlab routine. More...\n+\u00a0\n+template\n+void\u00a0Dune::writeMatrixToMatlabHelper (const MatrixType &matrix, int\n+ externalRowOffset, int externalColOffset, std::ostream &s, typename std::\n+ enable_if_t::value > *sfinae=nullptr)\n+\u00a0 Helper method for the writeMatrixToMatlab routine. More...\n+\u00a0\n+template\n+void\u00a0Dune::writeMatrixToMatlab (const MatrixType &matrix, const std::string\n+ &filename, int outputPrecision=18)\n+\u00a0 Writes sparse matrix in a Matlab-readable format. More...\n+\u00a0\n+template\n+void\u00a0Dune::writeVectorToMatlabHelper (const V &v, std::ostream &stream)\n+\u00a0\n+template\n+void\u00a0Dune::writeVectorToMatlab (const VectorType &vector, const std::string\n+ &filename, int outputPrecision=18)\n+\u00a0 Writes vectors in a Matlab-readable format. More...\n+\u00a0\n+template\n+void\u00a0Dune::writeSVGMatrix (const Mat &mat, std::ostream &out, SVGOptions opts=\n+ {})\n+\u00a0 Writes the visualization of matrix in the SVG format. More...\n \u00a0\n ***** Detailed Description *****\n-Helper functions for determining the vector/matrix block level.\n+Some generic functions for pretty printing vectors and matrices.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00008_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00008_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: blocklevel.hh Source File\n+dune-istl: io.hh Source File\n \n \n \n \n \n \n \n@@ -62,195 +62,677 @@\n \n
\n \n
\n
\n
\n-
blocklevel.hh
\n+
io.hh
\n
\n
\n Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
\n
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
\n
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
\n
4// vi: set et ts=4 sw=2 sts=2:
\n-
5
\n-
6#ifndef DUNE_ISTL_BLOCKLEVEL_HH
\n-
7#define DUNE_ISTL_BLOCKLEVEL_HH
\n-
8
\n-
9#include <algorithm>
\n-
10#include <type_traits>
\n-
11
\n-
12#include <dune/common/indices.hh>
\n-
13#include <dune/common/typetraits.hh>
\n-
14#include <dune/common/hybridutilities.hh>
\n+
5#ifndef DUNE_ISTL_IO_HH
\n+
6#define DUNE_ISTL_IO_HH
\n+
7
\n+
8#include <cmath>
\n+
9#include <complex>
\n+
10#include <limits>
\n+
11#include <ios>
\n+
12#include <iomanip>
\n+
13#include <fstream>
\n+
14#include <string>
\n
15
\n-
21// forward declaration
\n-
22namespace Dune {
\n-
23template<typename... Args>
\n-
24class MultiTypeBlockVector;
\n-
25template<typename FirstRow, typename... Args>
\n-
26class MultiTypeBlockMatrix;
\n-
27} // end namespace Dune
\n-
28
\n-
29namespace Dune { namespace Impl {
\n-
30
\n-
31// forward declaration
\n-
32template<typename T> struct MaxBlockLevel;
\n-
33template<typename T> struct MinBlockLevel;
\n-
34
\n-
36template<typename M, template<typename B> typename BlockLevel, typename Op>
\n-
37constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)
\n-
38{
\n-
39 // inialize with zeroth diagonal block
\n-
40 using namespace Dune::Indices;
\n-
41 using Block00 = typename std::decay_t<decltype(std::declval<M>()[_0][_0])>;
\n-
42 std::size_t blockLevel = BlockLevel<Block00>::value() + 1;
\n-
43 // iterate over all blocks to determine min/max block level
\n-
44 using namespace Dune::Hybrid;
\n-
45 forEach(integralRange(index_constant<M::N()>()), [&](auto&& i) {
\n-
46 using namespace Dune::Hybrid; // needed for icc, see issue #31
\n-
47 forEach(integralRange(index_constant<M::M()>()), [&](auto&& j) {
\n-
48 using Block = typename std::decay_t<decltype(std::declval<M>()[i][j])>;
\n-
49 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
\n-
50 });
\n-
51 });
\n-
52 return blockLevel;
\n-
53}
\n-
54
\n-
56template<typename V, template<typename B> typename BlockLevel, typename Op>
\n-
57constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)
\n-
58{
\n-
59 // inialize with zeroth block
\n-
60 using namespace Dune::Indices;
\n-
61 using Block0 = typename std::decay_t<decltype(std::declval<V>()[_0])>;
\n-
62 std::size_t blockLevel = BlockLevel<Block0>::value() + 1;
\n-
63 // iterate over all blocks to determine min/max block level
\n-
64 using namespace Dune::Hybrid;
\n-
65 forEach(integralRange(index_constant<V::size()>()), [&](auto&& i) {
\n-
66 using Block = typename std::decay_t<decltype(std::declval<V>()[i])>;
\n-
67 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
\n-
68 });
\n-
69 return blockLevel;
\n-
70}
\n-
71
\n-
72template<typename T>
\n-
73struct MaxBlockLevel
\n-
74{
\n-
75 static constexpr std::size_t value(){
\n-
76 if constexpr (IsNumber<T>::value)
\n-
77 return 0;
\n-
78 else
\n-
79 return MaxBlockLevel<typename T::block_type>::value() + 1;
\n-
80 }
\n-
81};
\n-
82
\n-
83template<typename T>
\n-
84struct MinBlockLevel
\n-
85{
\n-
86 // the default implementation assumes minBlockLevel == maxBlockLevel
\n-
87 static constexpr std::size_t value()
\n-
88 { return MaxBlockLevel<T>::value(); }
\n-
89};
\n-
90
\n-
91// max block level for MultiTypeBlockMatrix
\n-
92template<typename FirstRow, typename... Args>
\n-
93struct MaxBlockLevel<Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
\n-
94{
\n-
95 static constexpr std::size_t value()
\n-
96 {
\n-
97 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
\n-
98 constexpr auto max = [](const auto& a, const auto& b){ return std::max(a,b); };
\n-
99 return blockLevelMultiTypeBlockMatrix<M, MaxBlockLevel>(max);
\n-
100 }
\n-
101};
\n-
102
\n-
103// min block level for MultiTypeBlockMatrix
\n-
104template<typename FirstRow, typename... Args>
\n-
105struct MinBlockLevel<Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
\n-
106{
\n-
107 static constexpr std::size_t value()
\n-
108 {
\n-
109 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
\n-
110 constexpr auto min = [](const auto& a, const auto& b){ return std::min(a,b); };
\n-
111 return blockLevelMultiTypeBlockMatrix<M, MinBlockLevel>(min);
\n-
112 }
\n-
113};
\n+
16#include "matrixutils.hh"
\n+
17#include "istlexception.hh"
\n+
18#include <dune/common/fvector.hh>
\n+
19#include <dune/common/fmatrix.hh>
\n+
20#include <dune/common/hybridutilities.hh>
\n+
21#include <dune/common/reservedvector.hh>
\n+
22
\n+\n+\n+
25
\n+
26namespace Dune {
\n+
27
\n+
40 //
\n+
41 // pretty printing of vectors
\n+
42 //
\n+
43
\n+
51 template<class V>
\n+
52 void recursive_printvector (std::ostream& s, const V& v, std::string rowtext,
\n+
53 int& counter, int columns, int width)
\n+
54 {
\n+
55 if constexpr (IsNumber<V>())
\n+
56 {
\n+
57 // Print one number
\n+
58 if (counter%columns==0)
\n+
59 {
\n+
60 s << rowtext; // start a new row
\n+
61 s << " "; // space in front of each entry
\n+
62 s.width(4); // set width for counter
\n+
63 s << counter; // number of first entry in a line
\n+
64 }
\n+
65 s << " "; // space in front of each entry
\n+
66 s.width(width); // set width for each entry anew
\n+
67 s << v; // yeah, the number !
\n+
68 counter++; // increment the counter
\n+
69 if (counter%columns==0)
\n+
70 s << std::endl; // start a new line
\n+
71 }
\n+
72 else
\n+
73 {
\n+
74 // Recursively print a vector
\n+
75 for (const auto& entry : v)
\n+
76 recursive_printvector(s,entry,rowtext,counter,columns,width);
\n+
77 }
\n+
78 }
\n+
79
\n+
80
\n+
88 template<class V>
\n+
89 void printvector (std::ostream& s, const V& v, std::string title,
\n+
90 std::string rowtext, int columns=1, int width=10,
\n+
91 int precision=2)
\n+
92 {
\n+
93 // count the numbers printed to make columns
\n+
94 int counter=0;
\n+
95
\n+
96 // remember old flags
\n+
97 std::ios_base::fmtflags oldflags = s.flags();
\n+
98
\n+
99 // set the output format
\n+
100 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
\n+
101 int oldprec = s.precision();
\n+
102 s.precision(precision);
\n+
103
\n+
104 // print title
\n+
105 s << title << " [blocks=" << v.N() << ",dimension=" << v.dim() << "]"
\n+
106 << std::endl;
\n+
107
\n+
108 // print data from all blocks
\n+
109 recursive_printvector(s,v,rowtext,counter,columns,width);
\n+
110
\n+
111 // check if new line is required
\n+
112 if (counter%columns!=0)
\n+
113 s << std::endl;
\n
114
\n-
115// max block level for MultiTypeBlockVector
\n-
116template<typename... Args>
\n-
117struct MaxBlockLevel<Dune::MultiTypeBlockVector<Args...>>
\n-
118{
\n-
119 static constexpr std::size_t value()
\n-
120 {
\n-
121 using V = MultiTypeBlockVector<Args...>;
\n-
122 constexpr auto max = [](const auto& a, const auto& b){ return std::max(a,b); };
\n-
123 return blockLevelMultiTypeBlockVector<V, MaxBlockLevel>(max);
\n-
124 }
\n-
125};
\n-
126
\n-
127// min block level for MultiTypeBlockVector
\n-
128template<typename... Args>
\n-
129struct MinBlockLevel<Dune::MultiTypeBlockVector<Args...>>
\n-
130{
\n-
131 static constexpr std::size_t value()
\n-
132 {
\n-
133 using V = MultiTypeBlockVector<Args...>;
\n-
134 constexpr auto min = [](const auto& a, const auto& b){ return std::min(a,b); };
\n-
135 return blockLevelMultiTypeBlockVector<V, MinBlockLevel>(min);
\n-
136 }
\n-
137};
\n-
138
\n-
139// special case: empty MultiTypeBlockVector
\n-
140template<>
\n-
141struct MaxBlockLevel<Dune::MultiTypeBlockVector<>>
\n-
142{
\n-
143 static constexpr std::size_t value()
\n-
144 { return 0; };
\n-
145};
\n-
146
\n-
147// special case: empty MultiTypeBlockVector
\n-
148template<>
\n-
149struct MinBlockLevel<Dune::MultiTypeBlockVector<>>
\n-
150{
\n-
151 static constexpr std::size_t value()
\n-
152 { return 0; };
\n-
153};
\n-
154
\n-
155}} // end namespace Dune::Impl
\n-
156
\n-
157namespace Dune {
\n-
158
\n-
160template<typename T>
\n-
161constexpr std::size_t maxBlockLevel()
\n-
162{ return Impl::MaxBlockLevel<T>::value(); }
\n+
115 // reset the output format
\n+
116 s.flags(oldflags);
\n+
117 s.precision(oldprec);
\n+
118 }
\n+
119
\n+
120
\n+
122 //
\n+
123 // pretty printing of matrices
\n+
124 //
\n+
125
\n+
133 inline void fill_row (std::ostream& s, int m, int width, [[maybe_unused]] int precision)
\n+
134 {
\n+
135 for (int j=0; j<m; j++)
\n+
136 {
\n+
137 s << " "; // space in front of each entry
\n+
138 s.width(width); // set width for each entry anew
\n+
139 s << "."; // yeah, the number !
\n+
140 }
\n+
141 }
\n+
142
\n+
150 template<class K>
\n+
151 void print_row (std::ostream& s, const K& value,
\n+
152 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type I,
\n+
153 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type J,
\n+
154 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type therow,
\n+
155 int width,
\n+
156 [[maybe_unused]] int precision,
\n+
157 typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr)
\n+
158 {
\n+
159 s << " "; // space in front of each entry
\n+
160 s.width(width); // set width for each entry anew
\n+
161 s << value;
\n+
162 }
\n
163
\n-
165template<typename T>
\n-
166constexpr std::size_t minBlockLevel()
\n-
167{ return Impl::MinBlockLevel<T>::value(); }
\n-
168
\n-
170template<typename T>
\n-
171constexpr bool hasUniqueBlockLevel()
\n-
172{ return maxBlockLevel<T>() == minBlockLevel<T>(); }
\n-
173
\n-
175template<typename T>
\n-
176constexpr std::size_t blockLevel()
\n-
177{
\n-
178 static_assert(hasUniqueBlockLevel<T>(), "Block level cannot be uniquely determined!");
\n-
179 return Impl::MaxBlockLevel<T>::value();
\n-
180}
\n-
181
\n-
182} // end namespace Dune
\n-
183
\n-
184#endif
\n+
171 template<class M>
\n+
172 void print_row (std::ostream& s, const M& A, typename M::size_type I,
\n+
173 typename M::size_type J, typename M::size_type therow,
\n+
174 int width, int precision,
\n+
175 typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
\n+
176 {
\n+
177 typename M::size_type i0=I;
\n+
178 for (typename M::size_type i=0; i<A.N(); i++)
\n+
179 {
\n+
180 if (therow>=i0 && therow<i0+MatrixDimension<M>::rowdim(A,i))
\n+
181 {
\n+
182 // the row is in this block row !
\n+
183 typename M::size_type j0=J;
\n+
184 for (typename M::size_type j=0; j<A.M(); j++)
\n+
185 {
\n+
186 // find this block
\n+
187 typename M::ConstColIterator it = A[i].find(j);
\n+
188
\n+
189 // print row or filler
\n+
190 if (it!=A[i].end())
\n+
191 print_row(s,*it,i0,j0,therow,width,precision);
\n+
192 else
\n+
193 fill_row(s,MatrixDimension<M>::coldim(A,j),width,precision);
\n+
194
\n+
195 // advance columns
\n+\n+
197 }
\n+
198 }
\n+
199 // advance rows
\n+\n+
201 }
\n+
202 }
\n+
203
\n+
212 template<class M>
\n+
213 void printmatrix (std::ostream& s, const M& A, std::string title,
\n+
214 std::string rowtext, int width=10, int precision=2)
\n+
215 {
\n+
216
\n+
217 // remember old flags
\n+
218 std::ios_base::fmtflags oldflags = s.flags();
\n+
219
\n+
220 // set the output format
\n+
221 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
\n+
222 int oldprec = s.precision();
\n+
223 s.precision(precision);
\n+
224
\n+
225 // print title
\n+
226 s << title
\n+
227 << " [n=" << A.N()
\n+
228 << ",m=" << A.M()
\n+
229 << ",rowdim=" << MatrixDimension<M>::rowdim(A)
\n+
230 << ",coldim=" << MatrixDimension<M>::coldim(A)
\n+
231 << "]" << std::endl;
\n+
232
\n+
233 // print all rows
\n+
234 for (typename M::size_type i=0; i<MatrixDimension<M>::rowdim(A); i++)
\n+
235 {
\n+
236 s << rowtext; // start a new row
\n+
237 s << " "; // space in front of each entry
\n+
238 s.width(4); // set width for counter
\n+
239 s << i; // number of first entry in a line
\n+
240 print_row(s,A,0,0,i,width,precision); // generic print
\n+
241 s << std::endl; // start a new line
\n+
242 }
\n+
243
\n+
244 // reset the output format
\n+
245 s.flags(oldflags);
\n+
246 s.precision(oldprec);
\n+
247 }
\n+
248
\n+
270 template<class B, int n, int m, class A>
\n+
271 void printSparseMatrix(std::ostream& s,
\n+\n+
273 std::string title, std::string rowtext,
\n+
274 int width=3, int precision=2)
\n+
275 {
\n+\n+
277 // remember old flags
\n+
278 std::ios_base::fmtflags oldflags = s.flags();
\n+
279 // set the output format
\n+
280 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
\n+
281 int oldprec = s.precision();
\n+
282 s.precision(precision);
\n+
283 // print title
\n+
284 s << title
\n+
285 << " [n=" << mat.N()
\n+
286 << ",m=" << mat.M()
\n+
287 << ",rowdim=" << MatrixDimension<Matrix>::rowdim(mat)
\n+
288 << ",coldim=" << MatrixDimension<Matrix>::coldim(mat)
\n+
289 << "]" << std::endl;
\n+
290
\n+
291 typedef typename Matrix::ConstRowIterator Row;
\n+
292
\n+
293 for(Row row=mat.begin(); row != mat.end(); ++row) {
\n+
294 int skipcols=0;
\n+
295 bool reachedEnd=false;
\n+
296
\n+
297 while(!reachedEnd) {
\n+
298 for(int innerrow=0; innerrow<n; ++innerrow) {
\n+
299 int count=0;
\n+
300 typedef typename Matrix::ConstColIterator Col;
\n+
301 Col col=row->begin();
\n+
302 for(; col != row->end(); ++col,++count) {
\n+
303 if(count<skipcols)
\n+
304 continue;
\n+
305 if(count>=skipcols+width)
\n+
306 break;
\n+
307 if(innerrow==0) {
\n+
308 if(count==skipcols) {
\n+
309 s << rowtext; // start a new row
\n+
310 s << " "; // space in front of each entry
\n+
311 s.width(4); // set width for counter
\n+
312 s << row.index()<<": "; // number of first entry in a line
\n+
313 }
\n+
314 s.width(4);
\n+
315 s<<col.index()<<": |";
\n+
316 } else {
\n+
317 if(count==skipcols) {
\n+
318 for(typename std::string::size_type i=0; i < rowtext.length(); i++)
\n+
319 s<<" ";
\n+
320 s<<" ";
\n+
321 }
\n+
322 s<<" |";
\n+
323 }
\n+
324 for(int innercol=0; innercol < m; ++innercol) {
\n+
325 s.width(9);
\n+
326 s<<(*col)[innerrow][innercol]<<" ";
\n+
327 }
\n+
328
\n+
329 s<<"|";
\n+
330 }
\n+
331 if(innerrow==n-1 && col==row->end())
\n+
332 reachedEnd = true;
\n+
333 else
\n+
334 s << std::endl;
\n+
335 }
\n+
336 skipcols += width;
\n+
337 s << std::endl;
\n+
338 }
\n+
339 s << std::endl;
\n+
340 }
\n+
341
\n+
342 // reset the output format
\n+
343 s.flags(oldflags);
\n+
344 s.precision(oldprec);
\n+
345 }
\n+
346
\n+
347 namespace
\n+
348 {
\n+
349 template<typename T>
\n+
350 struct MatlabPODWriter
\n+
351 {
\n+
352 static std::ostream& write(const T& t, std::ostream& s)
\n+
353 {
\n+
354 s << t;
\n+
355 return s;
\n+
356 }
\n+
357 };
\n+
358 template<typename T>
\n+
359 struct MatlabPODWriter<std::complex<T> >
\n+
360 {
\n+
361 static std::ostream& write(const std::complex<T>& t, std::ostream& s)
\n+
362 {
\n+
363 s << t.real() << " " << t.imag();
\n+
364 return s;
\n+
365 }
\n+
366 };
\n+
367 } // anonymous namespace
\n+
368
\n+
378 template <class FieldType>
\n+
379 void writeMatrixToMatlabHelper(const FieldType& value,
\n+
380 int rowOffset, int colOffset,
\n+
381 std::ostream& s,
\n+
382 typename std::enable_if_t<Dune::IsNumber<FieldType>::value>* sfinae = nullptr)
\n+
383 {
\n+
384 //+1 for Matlab numbering
\n+
385 s << rowOffset + 1 << " " << colOffset + 1 << " ";
\n+
386 MatlabPODWriter<FieldType>::write(value, s)<< std::endl;
\n+
387 }
\n+
388
\n+
396 template <class MatrixType>
\n+
397 void writeMatrixToMatlabHelper(const MatrixType& matrix,
\n+
398 int externalRowOffset, int externalColOffset,
\n+
399 std::ostream& s,
\n+
400 typename std::enable_if_t<!Dune::IsNumber<MatrixType>::value>* sfinae = nullptr)
\n+
401 {
\n+
402 // Precompute the accumulated sizes of the columns
\n+
403 std::vector<typename MatrixType::size_type> colOffset(matrix.M());
\n+
404 if (colOffset.size() > 0)
\n+
405 colOffset[0] = 0;
\n+
406
\n+
407 for (typename MatrixType::size_type i=0; i<matrix.M()-1; i++)
\n+
408 colOffset[i+1] = colOffset[i] +
\n+\n+
410
\n+
411 typename MatrixType::size_type rowOffset = 0;
\n+
412
\n+
413 // Loop over all matrix rows
\n+
414 for (typename MatrixType::size_type rowIdx=0; rowIdx<matrix.N(); rowIdx++)
\n+
415 {
\n+
416 auto cIt = matrix[rowIdx].begin();
\n+
417 auto cEndIt = matrix[rowIdx].end();
\n+
418
\n+
419 // Loop over all columns in this row
\n+
420 for (; cIt!=cEndIt; ++cIt)
\n+\n+
422 externalRowOffset+rowOffset,
\n+
423 externalColOffset + colOffset[cIt.index()],
\n+
424 s);
\n+
425
\n+
426 rowOffset += MatrixDimension<MatrixType>::rowdim(matrix, rowIdx);
\n+
427 }
\n+
428
\n+
429 }
\n+
430
\n+
450 template <class MatrixType>
\n+
451 void writeMatrixToMatlab(const MatrixType& matrix,
\n+
452 const std::string& filename, int outputPrecision = 18)
\n+
453 {
\n+
454 std::ofstream outStream(filename.c_str());
\n+
455 int oldPrecision = outStream.precision();
\n+
456 outStream.precision(outputPrecision);
\n+
457
\n+
458 writeMatrixToMatlabHelper(matrix, 0, 0, outStream);
\n+
459 outStream.precision(oldPrecision);
\n+
460 }
\n+
461
\n+
462 // Recursively write vector entries to a stream
\n+
463 template<class V>
\n+
464 void writeVectorToMatlabHelper (const V& v, std::ostream& stream)
\n+
465 {
\n+
466 if constexpr (IsNumber<V>()) {
\n+
467 stream << v << std::endl;
\n+
468 } else {
\n+
469 for (const auto& entry : v)
\n+
470 writeVectorToMatlabHelper(entry, stream);
\n+
471 }
\n+
472 }
\n+
473
\n+
491 template <class VectorType>
\n+
492 void writeVectorToMatlab(const VectorType& vector,
\n+
493 const std::string& filename, int outputPrecision = 18)
\n+
494 {
\n+
495 std::ofstream outStream(filename.c_str());
\n+
496 int oldPrecision = outStream.precision();
\n+
497 outStream.precision(outputPrecision);
\n+
498
\n+
499 writeVectorToMatlabHelper(vector, outStream);
\n+
500 outStream.precision(oldPrecision);
\n+
501 }
\n+
502
\n+
503 namespace Impl {
\n+
504
\n+
506 struct NullStream {
\n+
507 template <class Any>
\n+
508 friend NullStream &operator<<(NullStream &dev0, Any &&) {
\n+
509 return dev0;
\n+
510 }
\n+
511 };
\n+
512
\n+
514 // svg shall be closed with a group and an svg. i.e. "</g></svg>"
\n+
515 template <class Stream, class SVGMatrixOptions>
\n+
516 void writeSVGMatrixHeader(Stream &out, const SVGMatrixOptions &opts,
\n+
517 std::pair<std::size_t, size_t> offsets) {
\n+
518 auto [col_offset, row_offset] = offsets;
\n+
519 double width = opts.width;
\n+
520 double height = opts.height;
\n+
521 // if empty, we try to figure out a sensible value of width and height
\n+
522 if (opts.width == 0 and opts.height == 0)
\n+
523 width = height = 500;
\n+
524 if (opts.width == 0)
\n+
525 width = opts.height * (double(col_offset) / row_offset);
\n+
526 if (opts.height == 0)
\n+
527 height = opts.width * (double(row_offset) / col_offset);
\n+
528
\n+
529 // scale group w.r.t final offsets
\n+
530 double scale_width = width / col_offset;
\n+
531 double scale_height = height / row_offset;
\n+
532
\n+
533 // write the header text
\n+
534 out << "<svg xmlns='http://www.w3.org/2000/svg' width='" << std::ceil(width)
\n+
535 << "' height='" << std::ceil(height) << "' version='1.1'>\\n"
\n+
536 << "<style>\\n"
\n+
537 << opts.style << "</style>\\n"
\n+
538 << "<g transform='scale(" << scale_width << " " << scale_height
\n+
539 << ")'>\\n";
\n+
540 }
\n+
541
\n+
543 template <class Mat, class Stream, class SVGMatrixOptions,
\n+
544 class RowPrefix, class ColPrefix>
\n+
545 std::pair<std::size_t, size_t>
\n+
546 writeSVGMatrix(const Mat &mat, Stream &out, SVGMatrixOptions opts,
\n+
547 RowPrefix row_prefix, ColPrefix col_prefix) {
\n+
548 // get values to fill the offests
\n+
549 const auto& block_size = opts.block_size;
\n+
550 const auto& interspace = opts.interspace;
\n+
551
\n+
552 const std::size_t rows = mat.N();
\n+
553 const std::size_t cols = mat.M();
\n+
554
\n+
555 // disable header write for recursive calls
\n+
556 const bool write_header = opts.write_header;
\n+
557 opts.write_header = false;
\n+
558
\n+
559 // counter of offsets for every block
\n+
560 std::size_t row_offset = interspace;
\n+
561 std::size_t col_offset = interspace;
\n+
562
\n+
563 // lambda helper: for-each value
\n+
564 auto for_each_entry = [&mat](const auto &call_back) {
\n+
565 for (auto row_it = mat.begin(); row_it != mat.end(); ++row_it) {
\n+
566 for (auto col_it = row_it->begin(); col_it != row_it->end(); ++col_it) {
\n+
567 call_back(row_it.index(), col_it.index(), *col_it);
\n+
568 }
\n+
569 }
\n+
570 };
\n+
571
\n+
572 // accumulate content in another stream so that we write in correct order
\n+
573 std::stringstream ss;
\n+
574
\n+
575 // we need to append current row and col values to the prefixes
\n+
576 row_prefix.push_back(0);
\n+
577 col_prefix.push_back(0);
\n+
578
\n+
579 // do we need to write nested matrix blocks?
\n+
580 if constexpr (Dune::blockLevel<typename Mat::block_type>() == 0) {
\n+
581 // simple case: write svg block content to stream for each value
\n+
582 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
\n+
583 std::size_t x_off = interspace + col * (interspace + block_size);
\n+
584 std::size_t y_off = interspace + row * (interspace + block_size);
\n+
585 row_prefix.back() = row;
\n+
586 col_prefix.back() = col;
\n+
587 opts.writeSVGBlock(ss, row_prefix, col_prefix, val,
\n+
588 {x_off, y_off, block_size, block_size});
\n+
589 });
\n+
590 col_offset += cols * (block_size + interspace);
\n+
591 row_offset += rows * (block_size + interspace);
\n+
592 } else {
\n+
593 // before we write anything, we need to calculate the
\n+
594 // offset for every {row,col} index
\n+
595 const auto null_offset = std::numeric_limits<std::size_t>::max();
\n+
596 std::vector<std::size_t> col_offsets(cols + 1, null_offset);
\n+
597 std::vector<std::size_t> row_offsets(rows + 1, null_offset);
\n+
598 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
\n+
599 NullStream dev0;
\n+
600 // get size of sub-block
\n+
601 auto sub_size =
\n+
602 writeSVGMatrix(val, dev0, opts, row_prefix, col_prefix);
\n+
603
\n+
604 // if we didn't see col size before
\n+
605 if (col_offsets[col + 1] == null_offset) // write it in the offset vector
\n+
606 col_offsets[col + 1] = sub_size.first;
\n+
607
\n+
608 // repeat proces for row sizes
\n+
609 if (row_offsets[row + 1] == null_offset)
\n+
610 row_offsets[row + 1] = sub_size.second;
\n+
611 });
\n+
612
\n+
613 // if some rows/cols were not visited, make an educated guess with the minimum offset
\n+
614 auto min_row_offset = *std::min_element(begin(row_offsets), end(row_offsets));
\n+
615 std::replace(begin(row_offsets), end(row_offsets), null_offset, min_row_offset);
\n+
616 auto min_col_offset = *std::min_element(begin(col_offsets), end(col_offsets));
\n+
617 std::replace(begin(col_offsets), end(col_offsets), null_offset, min_col_offset);
\n+
618
\n+
619 // we have sizes for every block: to get offsets we make a partial sum
\n+
620 col_offsets[0] = interspace;
\n+
621 row_offsets[0] = interspace;
\n+
622 for (std::size_t i = 1; i < col_offsets.size(); i++)
\n+
623 col_offsets[i] += col_offsets[i - 1] + interspace;
\n+
624 for (std::size_t i = 1; i < row_offsets.size(); i++)
\n+
625 row_offsets[i] += row_offsets[i - 1] + interspace;
\n+
626
\n+
627 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
\n+
628 // calculate svg view from offsets
\n+
629 std::size_t width =
\n+
630 col_offsets[col + 1] - col_offsets[col] - interspace;
\n+
631 std::size_t height =
\n+
632 row_offsets[row + 1] - row_offsets[row] - interspace;
\n+
633 row_prefix.back() = row;
\n+
634 col_prefix.back() = col;
\n+
635 // content of the sub-block has origin at {0,0}: shift it to the correct place
\n+
636 ss << "<svg x='" << col_offsets[col] << "' y='" << row_offsets[row]
\n+
637 << "' width='" << width << "' height='" << height << "'>\\n";
\n+
638 // write a nested svg with the contents of the sub-block
\n+
639 writeSVGMatrix(val, ss, opts, row_prefix, col_prefix);
\n+
640 ss << "</svg>\\n";
\n+
641 });
\n+
642 col_offset = col_offsets.back();
\n+
643 row_offset = row_offsets.back();
\n+
644 }
\n+
645
\n+
646 // write content in order!
\n+
647 // (i) if required, first header
\n+
648 if (write_header)
\n+
649 writeSVGMatrixHeader(out, opts, {col_offset, row_offset});
\n+
650
\n+
651 col_prefix.pop_back();
\n+
652 row_prefix.pop_back();
\n+
653 // (ii) an svg block for this level
\n+
654 opts.writeSVGBlock(out, row_prefix, col_prefix, mat,
\n+
655 {0, 0, col_offset, row_offset});
\n+
656 // (iii) the content of the matrix
\n+
657 out << ss.str();
\n+
658 // (iv) if required, close the header
\n+
659 if (write_header)
\n+
660 out << "</g>\\n</svg>\\n";
\n+
661
\n+
662 // return the total required for this block
\n+
663 return {col_offset, row_offset};
\n+
664 }
\n+
665 } // namespace Impl
\n+
666
\n+
667
\n+\n+
676 std::size_t block_size = 10;
\n+
678 std::size_t interspace = 5;
\n+
680 std::size_t width = 500;
\n+
682 std::size_t height = 0;
\n+
684 bool write_header = true;
\n+
686 std::string style = " .matrix-block {\\n"
\n+
687 " fill: cornflowerblue;\\n"
\n+
688 " fill-opacity: 0.4;\\n"
\n+
689 " stroke-width: 2;\\n"
\n+
690 " stroke: black;\\n"
\n+
691 " stroke-opacity: 0.5;\\n"
\n+
692 " }\\n"
\n+
693 " .matrix-block:hover {\\n"
\n+
694 " fill: lightcoral;\\n"
\n+
695 " fill-opacity: 0.4;\\n"
\n+
696 " stroke-opacity: 1;\\n"
\n+
697 " }\\n";
\n+
698
\n+
710 std::function<std::string(const double&)> color_fill;
\n+
711
\n+
717 template <class RowPrefix, class ColPrefix>
\n+
718 std::string blockStyleClass(const RowPrefix &row_prefix,
\n+
719 const ColPrefix &col_prefix) const {
\n+
720 // here, you can potentially give a different style to each block
\n+
721 return "matrix-block";
\n+
722 }
\n+
723
\n+
725 bool write_block_title = true;
\n+
726
\n+
732 template <class Stream, class RowPrefix, class ColPrefix, class Block>
\n+
733 void writeBlockTitle(Stream& out, const RowPrefix &row_prefix,
\n+
734 const ColPrefix &col_prefix,
\n+
735 const Block &block) const {
\n+
736 if (this->write_block_title) {
\n+
737 out << "<title>";
\n+
738 assert(row_prefix.size() == col_prefix.size());
\n+
739 for (std::size_t i = 0; i < row_prefix.size(); ++i)
\n+
740 out << "[" << row_prefix[i] << ", "<< col_prefix[i] << "]";
\n+
741 if constexpr (Dune::blockLevel<Block>() == 0)
\n+
742 out << ": " << block;
\n+
743 out << "</title>\\n";
\n+
744 }
\n+
745 }
\n+
746
\n+
768 template <class Stream, class RowPrefix, class ColPrefix, class Block>
\n+
769 void writeSVGBlock(Stream &out,
\n+
770 const RowPrefix &row_prefix,
\n+
771 const ColPrefix &col_prefix, const Block block,
\n+
772 const std::array<std::size_t, 4> &svg_box) const {
\n+
773 // get bounding box values
\n+
774 auto &[x_off, y_off, width, height] = svg_box;
\n+
775 // get style class
\n+
776 std::string block_class = this->blockStyleClass(row_prefix, col_prefix);
\n+
777 // write a rectangle on the bounding box
\n+
778 out << "<rect class='" << block_class << "' x='" << x_off << "' y='"
\n+
779 << y_off << "' width='" << width << "' height='" << height << "'";
\n+
780 if constexpr (Dune::blockLevel<Block>() == 0 and std::is_convertible<Block,double>{})
\n+
781 if (color_fill)
\n+
782 out << " style='fill-opacity: 1;fill:" << color_fill(double(block)) << "'";
\n+
783
\n+
784 out << ">\\n";
\n+
785 // give the rectangle a title (in html this shows info about the block)
\n+
786 this->writeBlockTitle(out,row_prefix, col_prefix, block);
\n+
787 // close rectangle
\n+
788 out << "</rect>\\n";
\n+
789 }
\n+
790 };
\n+
791
\n+
806 template <class Mat, class SVGOptions = DefaultSVGMatrixOptions>
\n+
807 void writeSVGMatrix(const Mat &mat, std::ostream &out,
\n+
808 SVGOptions opts = {}) {
\n+
809 // We need a vector that can fit all the multi-indices for rows and colums
\n+
810 using IndexPrefix = Dune::ReservedVector<std::size_t, blockLevel<Mat>()>;
\n+
811 // Call overload for Mat type
\n+
812 Impl::writeSVGMatrix(mat, out, opts, IndexPrefix{}, IndexPrefix{});
\n+
813 }
\n+
814
\n+
817} // namespace Dune
\n+
818
\n+
819#endif
\n+
Some handy generic functions for ISTL matrices.
\n+
Implementation of the BCRSMatrix class.
\n+\n+
Helper functions for determining the vector/matrix block level.
\n+
Col col
Definition: matrixmatrix.hh:351
\n+
Matrix & mat
Definition: matrixmatrix.hh:347
\n+
void writeSVGMatrix(const Mat &mat, std::ostream &out, SVGOptions opts={})
Writes the visualization of matrix in the SVG format.
Definition: io.hh:807
\n+
void writeMatrixToMatlab(const MatrixType &matrix, const std::string &filename, int outputPrecision=18)
Writes sparse matrix in a Matlab-readable format.
Definition: io.hh:451
\n+
void print_row(std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
Print one row of a matrix, specialization for number types.
Definition: io.hh:151
\n+
void printmatrix(std::ostream &s, const M &A, std::string title, std::string rowtext, int width=10, int precision=2)
Print a generic block matrix.
Definition: io.hh:213
\n+
void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
Print an ISTL vector.
Definition: io.hh:89
\n+
void writeMatrixToMatlabHelper(const FieldType &value, int rowOffset, int colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber< FieldType >::value > *sfinae=nullptr)
Helper method for the writeMatrixToMatlab routine.
Definition: io.hh:379
\n+
void writeVectorToMatlabHelper(const V &v, std::ostream &stream)
Definition: io.hh:464
\n+
void writeVectorToMatlab(const VectorType &vector, const std::string &filename, int outputPrecision=18)
Writes vectors in a Matlab-readable format.
Definition: io.hh:492
\n+
void recursive_printvector(std::ostream &s, const V &v, std::string rowtext, int &counter, int columns, int width)
Recursively print a vector.
Definition: io.hh:52
\n+
void printSparseMatrix(std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3, int precision=2)
Prints a BCRSMatrix with fixed sized blocks.
Definition: io.hh:271
\n+
void fill_row(std::ostream &s, int m, int width, int precision)
Print a row of zeros for a non-existing block.
Definition: io.hh:133
\n+
STL namespace.
\n
Definition: allocator.hh:11
\n-
constexpr bool hasUniqueBlockLevel()
Determine if a vector/matrix has a uniquely determinable block level.
Definition: blocklevel.hh:171
\n-
constexpr std::size_t maxBlockLevel()
Determine the maximum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:161
\n-
constexpr std::size_t blockLevel()
Determine the block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:176
\n-
constexpr std::size_t minBlockLevel()
Determine the minimum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:166
\n+
std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
Send BlockVector to an output stream.
Definition: bvector.hh:590
\n+
Definition: matrixutils.hh:211
\n+
static auto coldim(const M &A)
Definition: matrixutils.hh:219
\n+
static auto rowdim(const M &A)
Definition: matrixutils.hh:214
\n+
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:466
\n+
Default options class to write SVG matrices.
Definition: io.hh:674
\n+
std::string style
CSS style block to write in header.
Definition: io.hh:686
\n+
std::size_t width
Final width size (pixels) of the SVG header. If 0, size is automatic.
Definition: io.hh:680
\n+
std::function< std::string(const double &)> color_fill
Color fill for default options.
Definition: io.hh:710
\n+
std::size_t block_size
size (pixels) of the deepst block/value of the matrix
Definition: io.hh:676
\n+
void writeSVGBlock(Stream &out, const RowPrefix &row_prefix, const ColPrefix &col_prefix, const Block block, const std::array< std::size_t, 4 > &svg_box) const
Write an SVG object for a given block/value in the matrix.
Definition: io.hh:769
\n+
void writeBlockTitle(Stream &out, const RowPrefix &row_prefix, const ColPrefix &col_prefix, const Block &block) const
Helper function writes a title for a given block and prefix.
Definition: io.hh:733
\n+
std::size_t interspace
size (pixels) of the interspace between blocks
Definition: io.hh:678
\n+
bool write_block_title
(Helper) Whether to write a title on the rectangle value
Definition: io.hh:725
\n+
std::size_t height
Final height size (pixels) of the SVG header. If 0, size is automatic.
Definition: io.hh:682
\n+
bool write_header
Whether to write the SVG header.
Definition: io.hh:684
\n+
std::string blockStyleClass(const RowPrefix &row_prefix, const ColPrefix &col_prefix) const
Helper function that returns an style class for a given prefix.
Definition: io.hh:718
\n+
ConstIterator class for sequential access.
Definition: matrix.hh:404
\n+
A generic dynamic dense matrix.
Definition: matrix.hh:561
\n+
RowIterator end()
Get iterator to one beyond last row.
Definition: matrix.hh:620
\n+
RowIterator begin()
Get iterator to first row.
Definition: matrix.hh:614
\n+
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition: matrix.hh:589
\n+
size_type M() const
Return the number of columns.
Definition: matrix.hh:700
\n+
size_type N() const
Return the number of rows.
Definition: matrix.hh:695
\n+
Definition: matrixutils.hh:27
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,209 +4,808 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-blocklevel.hh\n+io.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5\n- 6#ifndef DUNE_ISTL_BLOCKLEVEL_HH\n- 7#define DUNE_ISTL_BLOCKLEVEL_HH\n- 8\n- 9#include \n- 10#include \n- 11\n- 12#include \n- 13#include \n- 14#include \n+ 5#ifndef DUNE_ISTL_IO_HH\n+ 6#define DUNE_ISTL_IO_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n 15\n- 21// forward declaration\n- 22namespace Dune {\n- 23template\n- 24class MultiTypeBlockVector;\n- 25template\n- 26class MultiTypeBlockMatrix;\n- 27} // end namespace Dune\n- 28\n- 29namespace Dune { namespace Impl {\n- 30\n- 31// forward declaration\n- 32template struct MaxBlockLevel;\n- 33template struct MinBlockLevel;\n- 34\n- 36template typename BlockLevel, typename Op>\n- 37constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)\n- 38{\n- 39 // inialize with zeroth diagonal block\n- 40 using namespace Dune::Indices;\n- 41 using Block00 = typename std::decay_t()[_0][_0])>;\n- 42 std::size_t blockLevel = BlockLevel::value() + 1;\n- 43 // iterate over all blocks to determine min/max block level\n- 44 using namespace Dune::Hybrid;\n- 45 forEach(integralRange(index_constant()), [&](auto&& i) {\n- 46 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 47 forEach(integralRange(index_constant()), [&](auto&& j) {\n- 48 using Block = typename std::decay_t()[i][j])>;\n- 49 blockLevel = op(blockLevel, BlockLevel::value() + 1);\n- 50 });\n- 51 });\n- 52 return blockLevel;\n- 53}\n- 54\n- 56template typename BlockLevel, typename Op>\n- 57constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)\n- 58{\n- 59 // inialize with zeroth block\n- 60 using namespace Dune::Indices;\n- 61 using Block0 = typename std::decay_t()[_0])>;\n- 62 std::size_t blockLevel = BlockLevel::value() + 1;\n- 63 // iterate over all blocks to determine min/max block level\n- 64 using namespace Dune::Hybrid;\n- 65 forEach(integralRange(index_constant()), [&](auto&& i) {\n- 66 using Block = typename std::decay_t()[i])>;\n- 67 blockLevel = op(blockLevel, BlockLevel::value() + 1);\n- 68 });\n- 69 return blockLevel;\n- 70}\n- 71\n- 72template\n- 73struct MaxBlockLevel\n- 74{\n- 75 static constexpr std::size_t value(){\n- 76 if constexpr (IsNumber::value)\n- 77 return 0;\n- 78 else\n- 79 return MaxBlockLevel::value() + 1;\n- 80 }\n- 81};\n- 82\n- 83template\n- 84struct MinBlockLevel\n- 85{\n- 86 // the default implementation assumes minBlockLevel == maxBlockLevel\n- 87 static constexpr std::size_t value()\n- 88 { return MaxBlockLevel::value(); }\n- 89};\n- 90\n- 91// max block level for MultiTypeBlockMatrix\n- 92template\n- 93struct MaxBlockLevel>\n- 94{\n- 95 static constexpr std::size_t value()\n- 96 {\n- 97 using M = MultiTypeBlockMatrix;\n- 98 constexpr auto max = [](const auto& a, const auto& b){ return std::max\n-(a,b); };\n- 99 return blockLevelMultiTypeBlockMatrix(max);\n- 100 }\n- 101};\n- 102\n- 103// min block level for MultiTypeBlockMatrix\n- 104template\n- 105struct MinBlockLevel>\n- 106{\n- 107 static constexpr std::size_t value()\n- 108 {\n- 109 using M = MultiTypeBlockMatrix;\n- 110 constexpr auto min = [](const auto& a, const auto& b){ return std::min\n-(a,b); };\n- 111 return blockLevelMultiTypeBlockMatrix(min);\n- 112 }\n- 113};\n+ 16#include \"matrixutils.hh\"\n+ 17#include \"istlexception.hh\"\n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22\n+ 23#include \n+ 24#include \n+ 25\n+ 26namespace Dune {\n+ 27\n+ 40 //\n+ 41 // pretty printing of vectors\n+ 42 //\n+ 43\n+ 51 template\n+52 void recursive_printvector (std::ostream& s, const V& v, std::string\n+rowtext,\n+ 53 int& counter, int columns, int width)\n+ 54 {\n+ 55 if constexpr (IsNumber())\n+ 56 {\n+ 57 // Print one number\n+ 58 if (counter%columns==0)\n+ 59 {\n+ 60 s << rowtext; // start a new row\n+ 61 s << \" \"; // space in front of each entry\n+ 62 s.width(4); // set width for counter\n+ 63 s << counter; // number of first entry in a line\n+ 64 }\n+ 65 s << \" \"; // space in front of each entry\n+ 66 s.width(width); // set width for each entry anew\n+ 67 s << v; // yeah, the number !\n+ 68 counter++; // increment the counter\n+ 69 if (counter%columns==0)\n+ 70 s << std::endl; // start a new line\n+ 71 }\n+ 72 else\n+ 73 {\n+ 74 // Recursively print a vector\n+ 75 for (const auto& entry : v)\n+ 76 recursive_printvector(s,entry,rowtext,counter,columns,width);\n+ 77 }\n+ 78 }\n+ 79\n+ 80\n+ 88 template\n+89 void printvector (std::ostream& s, const V& v, std::string title,\n+ 90 std::string rowtext, int columns=1, int width=10,\n+ 91 int precision=2)\n+ 92 {\n+ 93 // count the numbers printed to make columns\n+ 94 int counter=0;\n+ 95\n+ 96 // remember old flags\n+ 97 std::ios_base::fmtflags oldflags = s.flags();\n+ 98\n+ 99 // set the output format\n+ 100 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n+ 101 int oldprec = s.precision();\n+ 102 s.precision(precision);\n+ 103\n+ 104 // print title\n+ 105 s << title << \" [blocks=\" << v.N() << \",dimension=\" << v.dim() << \"]\"\n+ 106 << std::endl;\n+ 107\n+ 108 // print data from all blocks\n+ 109 recursive_printvector(s,v,rowtext,counter,columns,width);\n+ 110\n+ 111 // check if new line is required\n+ 112 if (counter%columns!=0)\n+ 113 s << std::endl;\n 114\n- 115// max block level for MultiTypeBlockVector\n- 116template\n- 117struct MaxBlockLevel>\n- 118{\n- 119 static constexpr std::size_t value()\n- 120 {\n- 121 using V = MultiTypeBlockVector;\n- 122 constexpr auto max = [](const auto& a, const auto& b){ return std::max\n-(a,b); };\n- 123 return blockLevelMultiTypeBlockVector(max);\n- 124 }\n- 125};\n- 126\n- 127// min block level for MultiTypeBlockVector\n- 128template\n- 129struct MinBlockLevel>\n- 130{\n- 131 static constexpr std::size_t value()\n- 132 {\n- 133 using V = MultiTypeBlockVector;\n- 134 constexpr auto min = [](const auto& a, const auto& b){ return std::min\n-(a,b); };\n- 135 return blockLevelMultiTypeBlockVector(min);\n- 136 }\n- 137};\n- 138\n- 139// special case: empty MultiTypeBlockVector\n- 140template<>\n- 141struct MaxBlockLevel>\n- 142{\n- 143 static constexpr std::size_t value()\n- 144 { return 0; };\n- 145};\n- 146\n- 147// special case: empty MultiTypeBlockVector\n- 148template<>\n- 149struct MinBlockLevel>\n- 150{\n- 151 static constexpr std::size_t value()\n- 152 { return 0; };\n- 153};\n- 154\n- 155}} // end namespace Dune::Impl\n- 156\n- 157namespace Dune {\n- 158\n- 160template\n-161constexpr std::size_t maxBlockLevel()\n- 162{ return Impl::MaxBlockLevel::value(); }\n+ 115 // reset the output format\n+ 116 s.flags(oldflags);\n+ 117 s.precision(oldprec);\n+ 118 }\n+ 119\n+ 120\n+ 122 //\n+ 123 // pretty printing of matrices\n+ 124 //\n+ 125\n+133 inline void fill_row (std::ostream& s, int m, int width, [[maybe_unused]]\n+int precision)\n+ 134 {\n+ 135 for (int j=0; j\n+151 void print_row (std::ostream& s, const K& value,\n+ 152 [[maybe_unused]] typename FieldMatrix::size_type I,\n+ 153 [[maybe_unused]] typename FieldMatrix::size_type J,\n+ 154 [[maybe_unused]] typename FieldMatrix::size_type therow,\n+ 155 int width,\n+ 156 [[maybe_unused]] int precision,\n+ 157 typename std::enable_if_t::value>* sfinae = nullptr)\n+ 158 {\n+ 159 s << \" \"; // space in front of each entry\n+ 160 s.width(width); // set width for each entry anew\n+ 161 s << value;\n+ 162 }\n 163\n- 165template\n-166constexpr std::size_t minBlockLevel()\n- 167{ return Impl::MinBlockLevel::value(); }\n- 168\n- 170template\n-171constexpr bool hasUniqueBlockLevel()\n- 172{ return maxBlockLevel() == minBlockLevel(); }\n- 173\n- 175template\n-176constexpr std::size_t blockLevel()\n- 177{\n- 178 static_assert(hasUniqueBlockLevel(), \"Block level cannot be uniquely\n-determined!\");\n- 179 return Impl::MaxBlockLevel::value();\n- 180}\n- 181\n- 182} // end namespace Dune\n- 183\n- 184#endif\n+ 171 template\n+172 void print_row (std::ostream& s, const M& A, typename M::size_type I,\n+ 173 typename M::size_type J, typename M::size_type therow,\n+ 174 int width, int precision,\n+ 175 typename std::enable_if_t::value>* sfinae = nullptr)\n+ 176 {\n+ 177 typename M::size_type i0=I;\n+ 178 for (typename M::size_type i=0; i=i0 && therow::rowdim(A,i))\n+ 181 {\n+ 182 // the row is in this block row !\n+ 183 typename M::size_type j0=J;\n+ 184 for (typename M::size_type j=0; j::coldim(A,j),width,precision);\n+ 194\n+ 195 // advance columns\n+ 196 j0 += MatrixDimension::coldim(A,j);\n+ 197 }\n+ 198 }\n+ 199 // advance rows\n+ 200 i0 += MatrixDimension::rowdim(A,i);\n+ 201 }\n+ 202 }\n+ 203\n+ 212 template\n+213 void printmatrix (std::ostream& s, const M& A, std::string title,\n+ 214 std::string rowtext, int width=10, int precision=2)\n+ 215 {\n+ 216\n+ 217 // remember old flags\n+ 218 std::ios_base::fmtflags oldflags = s.flags();\n+ 219\n+ 220 // set the output format\n+ 221 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n+ 222 int oldprec = s.precision();\n+ 223 s.precision(precision);\n+ 224\n+ 225 // print title\n+ 226 s << title\n+ 227 << \" [n=\" << A.N()\n+ 228 << \",m=\" << A.M()\n+ 229 << \",rowdim=\" << MatrixDimension::rowdim(A)\n+ 230 << \",coldim=\" << MatrixDimension::coldim(A)\n+ 231 << \"]\" << std::endl;\n+ 232\n+ 233 // print all rows\n+ 234 for (typename M::size_type i=0; i::rowdim(A); i++)\n+ 235 {\n+ 236 s << rowtext; // start a new row\n+ 237 s << \" \"; // space in front of each entry\n+ 238 s.width(4); // set width for counter\n+ 239 s << i; // number of first entry in a line\n+ 240 print_row(s,A,0,0,i,width,precision); // generic print\n+ 241 s << std::endl; // start a new line\n+ 242 }\n+ 243\n+ 244 // reset the output format\n+ 245 s.flags(oldflags);\n+ 246 s.precision(oldprec);\n+ 247 }\n+ 248\n+ 270 template\n+271 void printSparseMatrix(std::ostream& s,\n+ 272 const BCRSMatrix,A>& mat,\n+ 273 std::string title, std::string rowtext,\n+ 274 int width=3, int precision=2)\n+ 275 {\n+ 276 typedef BCRSMatrix,A> Matrix;\n+ 277 // remember old flags\n+ 278 std::ios_base::fmtflags oldflags = s.flags();\n+ 279 // set the output format\n+ 280 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n+ 281 int oldprec = s.precision();\n+ 282 s.precision(precision);\n+ 283 // print title\n+ 284 s << title\n+ 285 << \" [n=\" << mat.N()\n+ 286 << \",m=\" << mat.M()\n+ 287 << \",rowdim=\" << MatrixDimension::rowdim(mat)\n+ 288 << \",coldim=\" << MatrixDimension::coldim(mat)\n+ 289 << \"]\" << std::endl;\n+ 290\n+ 291 typedef typename Matrix::ConstRowIterator Row;\n+ 292\n+ 293 for(Row row=mat.begin(); row != mat.end(); ++row) {\n+ 294 int skipcols=0;\n+ 295 bool reachedEnd=false;\n+ 296\n+ 297 while(!reachedEnd) {\n+ 298 for(int innerrow=0; innerrowbegin();\n+ 302 for(; col != row->end(); ++col,++count) {\n+ 303 if(count=skipcols+width)\n+ 306 break;\n+ 307 if(innerrow==0) {\n+ 308 if(count==skipcols) {\n+ 309 s << rowtext; // start a new row\n+ 310 s << \" \"; // space in front of each entry\n+ 311 s.width(4); // set width for counter\n+ 312 s << row.index()<<\": \"; // number of first entry in a line\n+ 313 }\n+ 314 s.width(4);\n+ 315 s<end())\n+ 332 reachedEnd = true;\n+ 333 else\n+ 334 s << std::endl;\n+ 335 }\n+ 336 skipcols += width;\n+ 337 s << std::endl;\n+ 338 }\n+ 339 s << std::endl;\n+ 340 }\n+ 341\n+ 342 // reset the output format\n+ 343 s.flags(oldflags);\n+ 344 s.precision(oldprec);\n+ 345 }\n+ 346\n+ 347 namespace\n+ 348 {\n+ 349 template\n+ 350 struct MatlabPODWriter\n+ 351 {\n+ 352 static std::ostream& write(const T& t, std::ostream& s)\n+ 353 {\n+ 354 s << t;\n+ 355 return s;\n+ 356 }\n+ 357 };\n+ 358 template\n+ 359 struct MatlabPODWriter >\n+ 360 {\n+ 361 static std::ostream& write(const std::complex& t, std::ostream& s)\n+ 362 {\n+ 363 s << t.real() << \" \" << t.imag();\n+ 364 return s;\n+ 365 }\n+ 366 };\n+ 367 } // anonymous namespace\n+ 368\n+ 378 template \n+379 void writeMatrixToMatlabHelper(const FieldType& value,\n+ 380 int rowOffset, int colOffset,\n+ 381 std::ostream& s,\n+ 382 typename std::enable_if_t::value>* sfinae =\n+nullptr)\n+ 383 {\n+ 384 //+1 for Matlab numbering\n+ 385 s << rowOffset + 1 << \" \" << colOffset + 1 << \" \";\n+ 386 MatlabPODWriter::write(value, s)<< std::endl;\n+ 387 }\n+ 388\n+ 396 template \n+397 void writeMatrixToMatlabHelper(const MatrixType& matrix,\n+ 398 int externalRowOffset, int externalColOffset,\n+ 399 std::ostream& s,\n+ 400 typename std::enable_if_t::value>* sfinae =\n+nullptr)\n+ 401 {\n+ 402 // Precompute the accumulated sizes of the columns\n+ 403 std::vector colOffset(matrix.M());\n+ 404 if (colOffset.size() > 0)\n+ 405 colOffset[0] = 0;\n+ 406\n+ 407 for (typename MatrixType::size_type i=0; i::coldim(matrix,i);\n+ 410\n+ 411 typename MatrixType::size_type rowOffset = 0;\n+ 412\n+ 413 // Loop over all matrix rows\n+ 414 for (typename MatrixType::size_type rowIdx=0; rowIdx::rowdim(matrix, rowIdx);\n+ 427 }\n+ 428\n+ 429 }\n+ 430\n+ 450 template \n+451 void writeMatrixToMatlab(const MatrixType& matrix,\n+ 452 const std::string& filename, int outputPrecision = 18)\n+ 453 {\n+ 454 std::ofstream outStream(filename.c_str());\n+ 455 int oldPrecision = outStream.precision();\n+ 456 outStream.precision(outputPrecision);\n+ 457\n+ 458 writeMatrixToMatlabHelper(matrix, 0, 0, outStream);\n+ 459 outStream.precision(oldPrecision);\n+ 460 }\n+ 461\n+ 462 // Recursively write vector entries to a stream\n+ 463 template\n+464 void writeVectorToMatlabHelper (const V& v, std::ostream& stream)\n+ 465 {\n+ 466 if constexpr (IsNumber()) {\n+ 467 stream << v << std::endl;\n+ 468 } else {\n+ 469 for (const auto& entry : v)\n+ 470 writeVectorToMatlabHelper(entry, stream);\n+ 471 }\n+ 472 }\n+ 473\n+ 491 template \n+492 void writeVectorToMatlab(const VectorType& vector,\n+ 493 const std::string& filename, int outputPrecision = 18)\n+ 494 {\n+ 495 std::ofstream outStream(filename.c_str());\n+ 496 int oldPrecision = outStream.precision();\n+ 497 outStream.precision(outputPrecision);\n+ 498\n+ 499 writeVectorToMatlabHelper(vector, outStream);\n+ 500 outStream.precision(oldPrecision);\n+ 501 }\n+ 502\n+ 503 namespace Impl {\n+ 504\n+ 506 struct NullStream {\n+ 507 template \n+ 508 friend NullStream &operator<<(NullStream &dev0, Any &&) {\n+ 509 return dev0;\n+ 510 }\n+ 511 };\n+ 512\n+ 514 // svg shall be closed with a group and an svg. i.e. \"\"\n+ 515 template \n+ 516 void writeSVGMatrixHeader(Stream &out, const SVGMatrixOptions &opts,\n+ 517 std::pair offsets) {\n+ 518 auto [col_offset, row_offset] = offsets;\n+ 519 double width = opts.width;\n+ 520 double height = opts.height;\n+ 521 // if empty, we try to figure out a sensible value of width and height\n+ 522 if (opts.width == 0 and opts.height == 0)\n+ 523 width = height = 500;\n+ 524 if (opts.width == 0)\n+ 525 width = opts.height * (double(col_offset) / row_offset);\n+ 526 if (opts.height == 0)\n+ 527 height = opts.width * (double(row_offset) / col_offset);\n+ 528\n+ 529 // scale group w.r.t final offsets\n+ 530 double scale_width = width / col_offset;\n+ 531 double scale_height = height / row_offset;\n+ 532\n+ 533 // write the header text\n+ 534 out << \"\\n\"\n+ 536 << \"\\n\"\n+ 538 << \"\\n\";\n+ 540 }\n+ 541\n+ 543 template \n+ 545 std::pair\n+ 546 writeSVGMatrix(const Mat &mat, Stream &out, SVGMatrixOptions opts,\n+ 547 RowPrefix row_prefix, ColPrefix col_prefix) {\n+ 548 // get values to fill the offests\n+ 549 const auto& block_size = opts.block_size;\n+ 550 const auto& interspace = opts.interspace;\n+ 551\n+ 552 const std::size_t rows = mat.N();\n+ 553 const std::size_t cols = mat.M();\n+ 554\n+ 555 // disable header write for recursive calls\n+ 556 const bool write_header = opts.write_header;\n+ 557 opts.write_header = false;\n+ 558\n+ 559 // counter of offsets for every block\n+ 560 std::size_t row_offset = interspace;\n+ 561 std::size_t col_offset = interspace;\n+ 562\n+ 563 // lambda helper: for-each value\n+ 564 auto for_each_entry = [&mat](const auto &call_back) {\n+ 565 for (auto row_it = mat.begin(); row_it != mat.end(); ++row_it) {\n+ 566 for (auto col_it = row_it->begin(); col_it != row_it->end(); ++col_it) {\n+ 567 call_back(row_it.index(), col_it.index(), *col_it);\n+ 568 }\n+ 569 }\n+ 570 };\n+ 571\n+ 572 // accumulate content in another stream so that we write in correct order\n+ 573 std::stringstream ss;\n+ 574\n+ 575 // we need to append current row and col values to the prefixes\n+ 576 row_prefix.push_back(0);\n+ 577 col_prefix.push_back(0);\n+ 578\n+ 579 // do we need to write nested matrix blocks?\n+ 580 if constexpr (Dune::blockLevel() == 0) {\n+ 581 // simple case: write svg block content to stream for each value\n+ 582 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n+ 583 std::size_t x_off = interspace + col * (interspace + block_size);\n+ 584 std::size_t y_off = interspace + row * (interspace + block_size);\n+ 585 row_prefix.back() = row;\n+ 586 col_prefix.back() = col;\n+ 587 opts.writeSVGBlock(ss, row_prefix, col_prefix, val,\n+ 588 {x_off, y_off, block_size, block_size});\n+ 589 });\n+ 590 col_offset += cols * (block_size + interspace);\n+ 591 row_offset += rows * (block_size + interspace);\n+ 592 } else {\n+ 593 // before we write anything, we need to calculate the\n+ 594 // offset for every {row,col} index\n+ 595 const auto null_offset = std::numeric_limits::max();\n+ 596 std::vector col_offsets(cols + 1, null_offset);\n+ 597 std::vector row_offsets(rows + 1, null_offset);\n+ 598 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n+ 599 NullStream dev0;\n+ 600 // get size of sub-block\n+ 601 auto sub_size =\n+ 602 writeSVGMatrix(val, dev0, opts, row_prefix, col_prefix);\n+ 603\n+ 604 // if we didn't see col size before\n+ 605 if (col_offsets[col + 1] == null_offset) // write it in the offset vector\n+ 606 col_offsets[col + 1] = sub_size.first;\n+ 607\n+ 608 // repeat proces for row sizes\n+ 609 if (row_offsets[row + 1] == null_offset)\n+ 610 row_offsets[row + 1] = sub_size.second;\n+ 611 });\n+ 612\n+ 613 // if some rows/cols were not visited, make an educated guess with the\n+minimum offset\n+ 614 auto min_row_offset = *std::min_element(begin(row_offsets), end\n+(row_offsets));\n+ 615 std::replace(begin(row_offsets), end(row_offsets), null_offset,\n+min_row_offset);\n+ 616 auto min_col_offset = *std::min_element(begin(col_offsets), end\n+(col_offsets));\n+ 617 std::replace(begin(col_offsets), end(col_offsets), null_offset,\n+min_col_offset);\n+ 618\n+ 619 // we have sizes for every block: to get offsets we make a partial sum\n+ 620 col_offsets[0] = interspace;\n+ 621 row_offsets[0] = interspace;\n+ 622 for (std::size_t i = 1; i < col_offsets.size(); i++)\n+ 623 col_offsets[i] += col_offsets[i - 1] + interspace;\n+ 624 for (std::size_t i = 1; i < row_offsets.size(); i++)\n+ 625 row_offsets[i] += row_offsets[i - 1] + interspace;\n+ 626\n+ 627 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n+ 628 // calculate svg view from offsets\n+ 629 std::size_t width =\n+ 630 col_offsets[col + 1] - col_offsets[col] - interspace;\n+ 631 std::size_t height =\n+ 632 row_offsets[row + 1] - row_offsets[row] - interspace;\n+ 633 row_prefix.back() = row;\n+ 634 col_prefix.back() = col;\n+ 635 // content of the sub-block has origin at {0,0}: shift it to the correct\n+place\n+ 636 ss << \"\\n\";\n+ 638 // write a nested svg with the contents of the sub-block\n+ 639 writeSVGMatrix(val, ss, opts, row_prefix, col_prefix);\n+ 640 ss << \"\\n\";\n+ 641 });\n+ 642 col_offset = col_offsets.back();\n+ 643 row_offset = row_offsets.back();\n+ 644 }\n+ 645\n+ 646 // write content in order!\n+ 647 // (i) if required, first header\n+ 648 if (write_header)\n+ 649 writeSVGMatrixHeader(out, opts, {col_offset, row_offset});\n+ 650\n+ 651 col_prefix.pop_back();\n+ 652 row_prefix.pop_back();\n+ 653 // (ii) an svg block for this level\n+ 654 opts.writeSVGBlock(out, row_prefix, col_prefix, mat,\n+ 655 {0, 0, col_offset, row_offset});\n+ 656 // (iii) the content of the matrix\n+ 657 out << ss.str();\n+ 658 // (iv) if required, close the header\n+ 659 if (write_header)\n+ 660 out << \"\\n\\n\";\n+ 661\n+ 662 // return the total required for this block\n+ 663 return {col_offset, row_offset};\n+ 664 }\n+ 665 } // namespace Impl\n+ 666\n+ 667\n+674 struct DefaultSVGMatrixOptions {\n+676 std::size_t block_size = 10;\n+678 std::size_t interspace = 5;\n+680 std::size_t width = 500;\n+682 std::size_t height = 0;\n+684 bool write_header = true;\n+686 std::string style = \" .matrix-block {\\n\"\n+ 687 \" fill: cornflowerblue;\\n\"\n+ 688 \" fill-opacity: 0.4;\\n\"\n+ 689 \" stroke-width: 2;\\n\"\n+ 690 \" stroke: black;\\n\"\n+ 691 \" stroke-opacity: 0.5;\\n\"\n+ 692 \" }\\n\"\n+ 693 \" .matrix-block:hover {\\n\"\n+ 694 \" fill: lightcoral;\\n\"\n+ 695 \" fill-opacity: 0.4;\\n\"\n+ 696 \" stroke-opacity: 1;\\n\"\n+ 697 \" }\\n\";\n+ 698\n+710 std::function color_fill;\n+ 711\n+ 717 template \n+718 std::string blockStyleClass(const RowPrefix &row_prefix,\n+ 719 const ColPrefix &col_prefix) const {\n+ 720 // here, you can potentially give a different style to each block\n+ 721 return \"matrix-block\";\n+ 722 }\n+ 723\n+725 bool write_block_title = true;\n+ 726\n+ 732 template \n+733 void writeBlockTitle(Stream& out, const RowPrefix &row_prefix,\n+ 734 const ColPrefix &col_prefix,\n+ 735 const Block &block) const {\n+ 736 if (this->write_block_title) {\n+ 737 out << \"\";\n+ 738 assert(row_prefix.size() == col_prefix.size());\n+ 739 for (std::size_t i = 0; i < row_prefix.size(); ++i)\n+ 740 out << \"[\" << row_prefix[i] << \", \"<< col_prefix[i] << \"]\";\n+ 741 if constexpr (Dune::blockLevel<Block>() == 0)\n+ 742 out << \": \" << block;\n+ 743 out << \"\\n\";\n+ 744 }\n+ 745 }\n+ 746\n+ 768 template \n+769 void writeSVGBlock(Stream &out,\n+ 770 const RowPrefix &row_prefix,\n+ 771 const ColPrefix &col_prefix, const Block block,\n+ 772 const std::array &svg_box) const {\n+ 773 // get bounding box values\n+ 774 auto &[x_off, y_off, width, height] = svg_box;\n+ 775 // get style class\n+ 776 std::string block_class = this->blockStyleClass(row_prefix, col_prefix);\n+ 777 // write a rectangle on the bounding box\n+ 778 out << \"() == 0 and std::\n+is_convertible{})\n+ 781 if (color_fill)\n+ 782 out << \" style='fill-opacity: 1;fill:\" << color_fill(double(block)) <<\n+\"'\";\n+ 783\n+ 784 out << \">\\n\";\n+ 785 // give the rectangle a title (in html this shows info about the block)\n+ 786 this->writeBlockTitle(out,row_prefix, col_prefix, block);\n+ 787 // close rectangle\n+ 788 out << \"\\n\";\n+ 789 }\n+ 790 };\n+ 791\n+ 806 template \n+807 void writeSVGMatrix(const Mat &mat, std::ostream &out,\n+ 808 SVGOptions opts = {}) {\n+ 809 // We need a vector that can fit all the multi-indices for rows and colums\n+ 810 using IndexPrefix = Dune::ReservedVector()>;\n+ 811 // Call overload for Mat type\n+ 812 Impl::writeSVGMatrix(mat, out, opts, IndexPrefix{}, IndexPrefix{});\n+ 813 }\n+ 814\n+ 817} // namespace Dune\n+ 818\n+ 819#endif\n+matrixutils.hh\n+Some handy generic functions for ISTL matrices.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+istlexception.hh\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::writeSVGMatrix\n+void writeSVGMatrix(const Mat &mat, std::ostream &out, SVGOptions opts={})\n+Writes the visualization of matrix in the SVG format.\n+Definition: io.hh:807\n+Dune::writeMatrixToMatlab\n+void writeMatrixToMatlab(const MatrixType &matrix, const std::string &filename,\n+int outputPrecision=18)\n+Writes sparse matrix in a Matlab-readable format.\n+Definition: io.hh:451\n+Dune::print_row\n+void print_row(std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1\n+>::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename\n+FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename\n+std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n+Print one row of a matrix, specialization for number types.\n+Definition: io.hh:151\n+Dune::printmatrix\n+void printmatrix(std::ostream &s, const M &A, std::string title, std::string\n+rowtext, int width=10, int precision=2)\n+Print a generic block matrix.\n+Definition: io.hh:213\n+Dune::printvector\n+void printvector(std::ostream &s, const V &v, std::string title, std::string\n+rowtext, int columns=1, int width=10, int precision=2)\n+Print an ISTL vector.\n+Definition: io.hh:89\n+Dune::writeMatrixToMatlabHelper\n+void writeMatrixToMatlabHelper(const FieldType &value, int rowOffset, int\n+colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber<\n+FieldType >::value > *sfinae=nullptr)\n+Helper method for the writeMatrixToMatlab routine.\n+Definition: io.hh:379\n+Dune::writeVectorToMatlabHelper\n+void writeVectorToMatlabHelper(const V &v, std::ostream &stream)\n+Definition: io.hh:464\n+Dune::writeVectorToMatlab\n+void writeVectorToMatlab(const VectorType &vector, const std::string &filename,\n+int outputPrecision=18)\n+Writes vectors in a Matlab-readable format.\n+Definition: io.hh:492\n+Dune::recursive_printvector\n+void recursive_printvector(std::ostream &s, const V &v, std::string rowtext,\n+int &counter, int columns, int width)\n+Recursively print a vector.\n+Definition: io.hh:52\n+Dune::printSparseMatrix\n+void printSparseMatrix(std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m\n+>, A > &mat, std::string title, std::string rowtext, int width=3, int\n+precision=2)\n+Prints a BCRSMatrix with fixed sized blocks.\n+Definition: io.hh:271\n+Dune::fill_row\n+void fill_row(std::ostream &s, int m, int width, int precision)\n+Print a row of zeros for a non-existing block.\n+Definition: io.hh:133\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::hasUniqueBlockLevel\n-constexpr bool hasUniqueBlockLevel()\n-Determine if a vector/matrix has a uniquely determinable block level.\n-Definition: blocklevel.hh:171\n-Dune::maxBlockLevel\n-constexpr std::size_t maxBlockLevel()\n-Determine the maximum block level of a possibly nested vector/matrix type.\n-Definition: blocklevel.hh:161\n-Dune::blockLevel\n-constexpr std::size_t blockLevel()\n-Determine the block level of a possibly nested vector/matrix type.\n-Definition: blocklevel.hh:176\n-Dune::minBlockLevel\n-constexpr std::size_t minBlockLevel()\n-Determine the minimum block level of a possibly nested vector/matrix type.\n-Definition: blocklevel.hh:166\n+Dune::operator<<\n+std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n+Send BlockVector to an output stream.\n+Definition: bvector.hh:590\n+Dune::MatrixDimension\n+Definition: matrixutils.hh:211\n+Dune::MatrixDimension::coldim\n+static auto coldim(const M &A)\n+Definition: matrixutils.hh:219\n+Dune::MatrixDimension::rowdim\n+static auto rowdim(const M &A)\n+Definition: matrixutils.hh:214\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::DefaultSVGMatrixOptions\n+Default options class to write SVG matrices.\n+Definition: io.hh:674\n+Dune::DefaultSVGMatrixOptions::style\n+std::string style\n+CSS style block to write in header.\n+Definition: io.hh:686\n+Dune::DefaultSVGMatrixOptions::width\n+std::size_t width\n+Final width size (pixels) of the SVG header. If 0, size is automatic.\n+Definition: io.hh:680\n+Dune::DefaultSVGMatrixOptions::color_fill\n+std::function< std::string(const double &)> color_fill\n+Color fill for default options.\n+Definition: io.hh:710\n+Dune::DefaultSVGMatrixOptions::block_size\n+std::size_t block_size\n+size (pixels) of the deepst block/value of the matrix\n+Definition: io.hh:676\n+Dune::DefaultSVGMatrixOptions::writeSVGBlock\n+void writeSVGBlock(Stream &out, const RowPrefix &row_prefix, const ColPrefix\n+&col_prefix, const Block block, const std::array< std::size_t, 4 > &svg_box)\n+const\n+Write an SVG object for a given block/value in the matrix.\n+Definition: io.hh:769\n+Dune::DefaultSVGMatrixOptions::writeBlockTitle\n+void writeBlockTitle(Stream &out, const RowPrefix &row_prefix, const ColPrefix\n+&col_prefix, const Block &block) const\n+Helper function writes a title for a given block and prefix.\n+Definition: io.hh:733\n+Dune::DefaultSVGMatrixOptions::interspace\n+std::size_t interspace\n+size (pixels) of the interspace between blocks\n+Definition: io.hh:678\n+Dune::DefaultSVGMatrixOptions::write_block_title\n+bool write_block_title\n+(Helper) Whether to write a title on the rectangle value\n+Definition: io.hh:725\n+Dune::DefaultSVGMatrixOptions::height\n+std::size_t height\n+Final height size (pixels) of the SVG header. If 0, size is automatic.\n+Definition: io.hh:682\n+Dune::DefaultSVGMatrixOptions::write_header\n+bool write_header\n+Whether to write the SVG header.\n+Definition: io.hh:684\n+Dune::DefaultSVGMatrixOptions::blockStyleClass\n+std::string blockStyleClass(const RowPrefix &row_prefix, const ColPrefix\n+&col_prefix) const\n+Helper function that returns an style class for a given prefix.\n+Definition: io.hh:718\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator\n+ConstIterator class for sequential access.\n+Definition: matrix.hh:404\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::end\n+RowIterator end()\n+Get iterator to one beyond last row.\n+Definition: matrix.hh:620\n+Dune::Matrix::begin\n+RowIterator begin()\n+Get iterator to first row.\n+Definition: matrix.hh:614\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::M\n+size_type M() const\n+Return the number of columns.\n+Definition: matrix.hh:700\n+Dune::Matrix::N\n+size_type N() const\n+Return the number of rows.\n+Definition: matrix.hh:695\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00011.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00011.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ildl.hh File Reference\n+dune-istl: vbvector.hh File Reference\n \n \n \n \n \n \n \n@@ -63,55 +63,53 @@\n
\n \n
\n
\n
\n
\n-Namespaces |\n-Functions
\n-
ildl.hh File Reference
\n+Classes |\n+Namespaces
\n+
vbvector.hh File Reference
\n \n
\n \n-

Incomplete LDL decomposition. \n+

??? \n More...

\n-
#include <dune/common/scalarvectorview.hh>
\n-#include <dune/common/scalarmatrixview.hh>
\n-#include "ilu.hh"
\n+
#include <cmath>
\n+#include <complex>
\n+#include <iostream>
\n+#include <iterator>
\n+#include <memory>
\n+#include <dune/common/iteratorfacades.hh>
\n+#include "istlexception.hh"
\n+#include "bvector.hh"
\n+#include <dune/istl/blocklevel.hh>
\n
\n

Go to the source code of this file.

\n \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

\n+Classes

class  Dune::VariableBlockVector< B, A >
 A Vector of blocks with different blocksizes. More...
 
class  Dune::VariableBlockVector< B, A >::CreateIterator
 Iterator class for sequential creation of blocks. More...
 
class  Dune::VariableBlockVector< B, A >::RealIterator< T, R >
 Iterator class for sequential access. More...
 
\n \n \n \n-

\n Namespaces

namespace  Dune
 
\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

\n-Functions

template<class K , int m, int n>
static void Dune::bildl_subtractBCT (const FieldMatrix< K, m, n > &B, const FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)
 
template<class K >
static void Dune::bildl_subtractBCT (const K &B, const K &CT, K &A, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
 
template<class Matrix >
static void Dune::bildl_subtractBCT (const Matrix &B, const Matrix &CT, Matrix &A, typename std::enable_if_t<!Dune::IsNumber< Matrix >::value > *sfinae=nullptr)
 
template<class Matrix >
void Dune::bildl_decompose (Matrix &A)
 compute ILDL decomposition of a symmetric matrix A More...
 
template<class Matrix , class X , class Y >
void Dune::bildl_backsolve (const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
 
\n

Detailed Description

\n-

Incomplete LDL decomposition.

\n-
Author
Martin Nolte
\n+

???

\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,46 +4,38 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Namespaces | Functions\n-ildl.hh File Reference\n-Incomplete LDL decomposition. More...\n-#include \n-#include \n-#include \"ilu.hh\"\n+Classes | Namespaces\n+vbvector.hh File Reference\n+??? More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"istlexception.hh\"\n+#include \"bvector.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n- Namespaces\n-namespace \u00a0Dune\n-\u00a0\n- Functions\n-template\n-static void\u00a0Dune::bildl_subtractBCT (const FieldMatrix< K, m, n > &B, const\n- FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)\n+ Classes\n+class \u00a0Dune::VariableBlockVector<_B,_A_>\n+\u00a0 A Vector of blocks with different blocksizes. More...\n \u00a0\n-template\n-static void\u00a0Dune::bildl_subtractBCT (const K &B, const K &CT, K &A, typename\n- std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n+class \u00a0Dune::VariableBlockVector<_B,_A_>::CreateIterator\n+\u00a0 Iterator class for sequential creation of blocks. More...\n \u00a0\n-template\n-static void\u00a0Dune::bildl_subtractBCT (const Matrix &B, const Matrix &CT, Matrix\n- &A, typename std::enable_if_t::value >\n- *sfinae=nullptr)\n+class \u00a0Dune::VariableBlockVector<_B,_A_>::RealIterator<_T,_R_>\n+\u00a0 Iterator class for sequential access. More...\n \u00a0\n-template\n- void\u00a0Dune::bildl_decompose (Matrix &A)\n-\u00a0 compute ILDL decomposition of a symmetric matrix A More...\n-\u00a0\n-template\n- void\u00a0Dune::bildl_backsolve (const Matrix &A, X &v, const Y &d, bool\n- isLowerTriangular=false)\n+ Namespaces\n+namespace \u00a0Dune\n \u00a0\n ***** Detailed Description *****\n-Incomplete LDL decomposition.\n- Author\n- Martin Nolte\n+???\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00011_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00011_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ildl.hh Source File\n+dune-istl: vbvector.hh Source File\n \n \n \n \n \n \n \n@@ -62,237 +62,760 @@\n \n
\n \n
\n
\n
\n-
ildl.hh
\n+
vbvector.hh
\n
\n
\n Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
\n
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
\n-
3#ifndef DUNE_ISTL_ILDL_HH
\n-
4#define DUNE_ISTL_ILDL_HH
\n-
5
\n-
6#include <dune/common/scalarvectorview.hh>
\n-
7#include <dune/common/scalarmatrixview.hh>
\n-
8#include "ilu.hh"
\n-
9
\n-
17namespace Dune
\n-
18{
\n+
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
\n+
4// vi: set et ts=4 sw=2 sts=2:
\n+
5#ifndef DUNE_ISTL_VBVECTOR_HH
\n+
6#define DUNE_ISTL_VBVECTOR_HH
\n+
7
\n+
8#include <cmath>
\n+
9#include <complex>
\n+
10#include <iostream>
\n+
11#include <iterator>
\n+
12#include <memory>
\n+
13
\n+
14#include <dune/common/iteratorfacades.hh>
\n+
15#include "istlexception.hh"
\n+
16#include "bvector.hh"
\n+
17
\n+\n
19
\n-
20 // bildl_subtractBCT
\n-
21 // -----------------
\n-
22
\n-
23 template< class K, int m, int n >
\n-\n-
25 {
\n-
26 for( int i = 0; i < m; ++i )
\n-
27 {
\n-
28 for( int j = 0; j < n; ++j )
\n-
29 {
\n-
30 for( int k = 0; k < n; ++k )
\n-
31 A[ i ][ j ] -= B[ i ][ k ] * CT[ j ][ k ];
\n-
32 }
\n-
33 }
\n-
34 }
\n-
35
\n-
36 template< class K >
\n-
37 inline static void bildl_subtractBCT ( const K &B, const K &CT, K &A,
\n-
38 typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr )
\n-
39 {
\n-
40 A -= B * CT;
\n-
41 }
\n-
42
\n-
43 template< class Matrix >
\n-
44 inline static void bildl_subtractBCT ( const Matrix &B, const Matrix &CT, Matrix &A,
\n-
45 typename std::enable_if_t<!Dune::IsNumber<Matrix>::value>* sfinae = nullptr )
\n+
24namespace Dune {
\n+
25
\n+
41 template<class B, class A=std::allocator<B> >
\n+
42 class VariableBlockVector : public Imp::block_vector_unmanaged<B,A>
\n+
43 // this derivation gives us all the blas level 1 and norms
\n+
44 // on the large array. However, access operators have to be
\n+
45 // overwritten.
\n
46 {
\n-
47 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
\n-
48 {
\n-
49 auto &&A_i = *i;
\n-
50 auto &&B_i = B[ i.index() ];
\n-
51 const auto ikend = B_i.end();
\n-
52 for( auto j = A_i.begin(), jend = A_i.end(); j != jend; ++j )
\n-
53 {
\n-
54 auto &&A_ij = *j;
\n-
55 auto &&CT_j = CT[ j.index() ];
\n-
56 const auto jkend = CT_j.end();
\n-
57 for( auto ik = B_i.begin(), jk = CT_j.begin(); (ik != ikend) && (jk != jkend); )
\n-
58 {
\n-
59 if( ik.index() == jk.index() )
\n-
60 {
\n-
61 bildl_subtractBCT( *ik, *jk, A_ij );
\n-
62 ++ik; ++jk;
\n-
63 }
\n-
64 else if( ik.index() < jk.index() )
\n-
65 ++ik;
\n-
66 else
\n-
67 ++jk;
\n-
68 }
\n-
69 }
\n-
70 }
\n-
71 }
\n-
72
\n-
73
\n+
47 // just a shorthand
\n+
48 typedef Imp::BlockVectorWindow<B,A> window_type;
\n+
49
\n+
50 public:
\n+
51
\n+
52 //===== type definitions and constants
\n+
53
\n+
55 using field_type = typename Imp::BlockTraits<B>::field_type;
\n+
56
\n+
58 typedef A allocator_type;
\n+
59
\n+
64 typedef window_type& reference;
\n+
65
\n+
70 typedef const window_type& const_reference;
\n+
71
\n+
73 typedef typename A::size_type size_type;
\n
74
\n-
75 // bildl_decompose
\n-
76 // ---------------
\n-
77
\n-
87 template< class Matrix >
\n-
88 inline void bildl_decompose ( Matrix &A )
\n-
89 {
\n-
90 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
\n-
91 {
\n-
92 auto &&A_i = *i;
\n+\n+
81
\n+\n+
85
\n+
89 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
\n+
90 static constexpr auto blocklevel = blockLevel<B>()+2;
\n+
91
\n+
92 //===== constructors and such
\n
93
\n-
94 auto ij = A_i.begin();
\n-
95 for( ; ij.index() < i.index(); ++ij )
\n-
96 {
\n-
97 auto &&A_ij = *ij;
\n-
98 auto &&A_j = A[ ij.index() ];
\n-
99
\n-
100 // store L_ij Dj in A_ij (note: for k < i: A_kj = L_kj)
\n-
101 // L_ij Dj = A_ij - \\sum_{k < j} (L_ik D_k) L_jk^T
\n-
102 auto ik = A_i.begin();
\n-
103 auto jk = A_j.begin();
\n-
104 while( (ik != ij) && (jk.index() < ij.index()) )
\n-
105 {
\n-
106 if( ik.index() == jk.index() )
\n-
107 {
\n-
108 bildl_subtractBCT(*ik, *jk, A_ij);
\n-
109 ++ik; ++jk;
\n-
110 }
\n-
111 else if( ik.index() < jk.index() )
\n-
112 ++ik;
\n-
113 else
\n-
114 ++jk;
\n-
115 }
\n+
97 VariableBlockVector () : Imp::block_vector_unmanaged<B,A>()
\n+
98 {
\n+
99 // nothing is known ...
\n+
100 nblocks = 0;
\n+
101 block = nullptr;
\n+
102 initialized = false;
\n+
103 }
\n+
104
\n+
108 explicit VariableBlockVector (size_type _nblocks) : Imp::block_vector_unmanaged<B,A>()
\n+
109 {
\n+
110 // we can allocate the windows now
\n+
111 nblocks = _nblocks;
\n+
112 if (nblocks>0)
\n+
113 {
\n+
114 block = windowAllocator_.allocate(nblocks);
\n+
115 new (block) window_type[nblocks];
\n
116 }
\n-
117
\n-
118 if( ij.index() != i.index() )
\n-
119 DUNE_THROW( ISTLError, "diagonal entry missing" );
\n-
120
\n-
121 // update diagonal and multiply A_ij by D_j^{-1}
\n-
122 auto &&A_ii = *ij;
\n-
123 for( auto ik = A_i.begin(); ik != ij; ++ik )
\n-
124 {
\n-
125 auto &&A_ik = *ik;
\n-
126 const auto &A_k = A[ ik.index() ];
\n+
117 else
\n+
118 {
\n+
119 nblocks = 0;
\n+
120 block = nullptr;
\n+
121 }
\n+
122
\n+
123 // Note: memory in base class still not allocated
\n+
124 // the vector not usable
\n+
125 initialized = false;
\n+
126 }
\n
127
\n-
128 auto B = A_ik;
\n-
129 Impl::asMatrix(A_ik).rightmultiply( Impl::asMatrix(*A_k.find( ik.index() )) );
\n-
130 bildl_subtractBCT( B, A_ik, A_ii );
\n-
131 }
\n-
132 try
\n-
133 {
\n-
134 Impl::asMatrix(A_ii).invert();
\n-
135 }
\n-
136 catch( const Dune::FMatrixError &e )
\n-
137 {
\n-
138 DUNE_THROW( MatrixBlockError, "ILDL failed to invert matrix block A[" << i.index() << "][" << ij.index() << "]" << e.what(); th__ex.r = i.index(); th__ex.c = ij.index() );
\n-
139 }
\n-
140 }
\n-
141 }
\n-
142
\n-
143
\n-
144
\n-
145 // bildl_backsolve
\n-
146 // ---------------
\n-
147
\n-
148 template< class Matrix, class X, class Y >
\n-
149 inline void bildl_backsolve ( const Matrix &A, X &v, const Y &d, bool isLowerTriangular = false )
\n-
150 {
\n-
151 // solve L v = d, note: Lii = I
\n-
152 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
\n-
153 {
\n-
154 const auto &A_i = *i;
\n-
155 v[ i.index() ] = d[ i.index() ];
\n-
156 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )
\n-
157 {
\n-
158 auto&& vi = Impl::asVector( v[ i.index() ] );
\n-
159 Impl::asMatrix(*ij).mmv(Impl::asVector( v[ ij.index() ] ), vi);
\n+
134 VariableBlockVector (size_type _nblocks, size_type m) : Imp::block_vector_unmanaged<B,A>()
\n+
135 {
\n+
136 // and we can allocate the big array in the base class
\n+
137 this->n = _nblocks*m;
\n+
138 if (this->n>0)
\n+
139 {
\n+
140 this->p = allocator_.allocate(this->n);
\n+
141 new (this->p)B[this->n];
\n+
142 }
\n+
143 else
\n+
144 {
\n+
145 this->n = 0;
\n+
146 this->p = nullptr;
\n+
147 }
\n+
148
\n+
149 // we can allocate the windows now
\n+
150 nblocks = _nblocks;
\n+
151 if (nblocks>0)
\n+
152 {
\n+
153 // allocate and construct the windows
\n+
154 block = windowAllocator_.allocate(nblocks);
\n+
155 new (block) window_type[nblocks];
\n+
156
\n+
157 // set the windows into the big array
\n+
158 for (size_type i=0; i<nblocks; ++i)
\n+
159 block[i].set(m,this->p+(i*m));
\n
160 }
\n-
161 }
\n-
162
\n-
163 // solve D w = v, note: diagonal stores Dii^{-1}
\n-
164 if( isLowerTriangular )
\n-
165 {
\n-
166 // The matrix is lower triangular, so the diagonal entry is the
\n-
167 // last one in each row.
\n-
168 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
\n-
169 {
\n-
170 const auto &A_i = *i;
\n-
171 const auto ii = A_i.beforeEnd();
\n-
172 assert( ii.index() == i.index() );
\n-
173 // We need to be careful here: Directly using
\n-
174 // auto rhs = Impl::asVector(v[ i.index() ]);
\n-
175 // is not OK in case this is a proxy. Hence
\n-
176 // we first have to copy the value. Notice that
\n-
177 // this is still not OK, if the vector type itself returns
\n-
178 // proxy references.
\n-
179 auto rhsValue = v[ i.index() ];
\n-
180 auto&& rhs = Impl::asVector(rhsValue);
\n-
181 auto&& vi = Impl::asVector( v[ i.index() ] );
\n-
182 Impl::asMatrix(*ii).mv(rhs, vi);
\n-
183 }
\n-
184 }
\n-
185 else
\n-
186 {
\n-
187 // Without assumptions on the sparsity pattern we have to search
\n-
188 // for the diagonal entry in each row.
\n-
189 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
\n-
190 {
\n-
191 const auto &A_i = *i;
\n-
192 const auto ii = A_i.find( i.index() );
\n-
193 assert( ii.index() == i.index() );
\n-
194 // We need to be careful here: Directly using
\n-
195 // auto rhs = Impl::asVector(v[ i.index() ]);
\n-
196 // is not OK in case this is a proxy. Hence
\n-
197 // we first have to copy the value. Notice that
\n-
198 // this is still not OK, if the vector type itself returns
\n-
199 // proxy references.
\n-
200 auto rhsValue = v[ i.index() ];
\n-
201 auto&& rhs = Impl::asVector(rhsValue);
\n-
202 auto&& vi = Impl::asVector( v[ i.index() ] );
\n-
203 Impl::asMatrix(*ii).mv(rhs, vi);
\n-
204 }
\n-
205 }
\n-
206
\n-
207 // solve L^T v = w, note: only L is stored
\n-
208 // note: we perform the operation column-wise from right to left
\n-
209 for( auto i = A.beforeEnd(), iend = A.beforeBegin(); i != iend; --i )
\n-
210 {
\n-
211 const auto &A_i = *i;
\n-
212 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )
\n-
213 {
\n-
214 auto&& vij = Impl::asVector( v[ ij.index() ] );
\n-
215 Impl::asMatrix(*ij).mmtv(Impl::asVector( v[ i.index() ] ), vij);
\n-
216 }
\n-
217 }
\n-
218 }
\n-
219
\n-
220} // namespace Dune
\n-
221
\n-
222#endif // #ifndef DUNE_ISTL_ILDL_HH
\n-
The incomplete LU factorization kernels.
\n+
161 else
\n+
162 {
\n+
163 nblocks = 0;
\n+
164 block = nullptr;
\n+
165 }
\n+
166
\n+
167 // and the vector is usable
\n+
168 initialized = true;
\n+
169 }
\n+
170
\n+\n+
173 {
\n+
174 // allocate the big array in the base class
\n+
175 this->n = a.n;
\n+
176 if (this->n>0)
\n+
177 {
\n+
178 // allocate and construct objects
\n+
179 this->p = allocator_.allocate(this->n);
\n+
180 new (this->p)B[this->n];
\n+
181
\n+
182 // copy data
\n+
183 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
\n+
184 }
\n+
185 else
\n+
186 {
\n+
187 this->n = 0;
\n+
188 this->p = nullptr;
\n+
189 }
\n+
190
\n+
191 // we can allocate the windows now
\n+
192 nblocks = a.nblocks;
\n+
193 if (nblocks>0)
\n+
194 {
\n+
195 // alloc
\n+
196 block = windowAllocator_.allocate(nblocks);
\n+
197 new (block) window_type[nblocks];
\n+
198
\n+
199 // and we must set the windows
\n+
200 block[0].set(a.block[0].getsize(),this->p); // first block
\n+
201 for (size_type i=1; i<nblocks; ++i) // and the rest
\n+
202 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
\n+
203 }
\n+
204 else
\n+
205 {
\n+
206 nblocks = 0;
\n+
207 block = nullptr;
\n+
208 }
\n+
209
\n+
210 // and we have a usable vector
\n+
211 initialized = true;
\n+
212 }
\n+
213
\n+\n+
216 {
\n+
217 if (this->n>0) {
\n+
218 size_type i=this->n;
\n+
219 while (i)
\n+
220 this->p[--i].~B();
\n+
221 allocator_.deallocate(this->p,this->n);
\n+
222 }
\n+
223 if (nblocks>0) {
\n+
224 size_type i=nblocks;
\n+
225 while (i)
\n+
226 block[--i].~window_type();
\n+
227 windowAllocator_.deallocate(block,nblocks);
\n+
228 }
\n+
229
\n+
230 }
\n+
231
\n+
232
\n+
234 void resize (size_type _nblocks)
\n+
235 {
\n+
236 // deconstruct objects and deallocate memory if necessary
\n+
237 if (this->n>0) {
\n+
238 size_type i=this->n;
\n+
239 while (i)
\n+
240 this->p[--i].~B();
\n+
241 allocator_.deallocate(this->p,this->n);
\n+
242 }
\n+
243 if (nblocks>0) {
\n+
244 size_type i=nblocks;
\n+
245 while (i)
\n+
246 block[--i].~window_type();
\n+
247 windowAllocator_.deallocate(block,nblocks);
\n+
248 }
\n+
249 this->n = 0;
\n+
250 this->p = nullptr;
\n+
251
\n+
252 // we can allocate the windows now
\n+
253 nblocks = _nblocks;
\n+
254 if (nblocks>0)
\n+
255 {
\n+
256 block = windowAllocator_.allocate(nblocks);
\n+
257 new (block) window_type[nblocks];
\n+
258 }
\n+
259 else
\n+
260 {
\n+
261 nblocks = 0;
\n+
262 block = nullptr;
\n+
263 }
\n+
264
\n+
265 // and the vector not fully usable
\n+
266 initialized = false;
\n+
267 }
\n+
268
\n+
270 void resize (size_type _nblocks, size_type m)
\n+
271 {
\n+
272 // deconstruct objects and deallocate memory if necessary
\n+
273 if (this->n>0) {
\n+
274 size_type i=this->n;
\n+
275 while (i)
\n+
276 this->p[--i].~B();
\n+
277 allocator_.deallocate(this->p,this->n);
\n+
278 }
\n+
279 if (nblocks>0) {
\n+
280 size_type i=nblocks;
\n+
281 while (i)
\n+
282 block[--i].~window_type();
\n+
283 windowAllocator_.deallocate(block,nblocks);
\n+
284 }
\n+
285
\n+
286 // and we can allocate the big array in the base class
\n+
287 this->n = _nblocks*m;
\n+
288 if (this->n>0)
\n+
289 {
\n+
290 this->p = allocator_.allocate(this->n);
\n+
291 new (this->p)B[this->n];
\n+
292 }
\n+
293 else
\n+
294 {
\n+
295 this->n = 0;
\n+
296 this->p = nullptr;
\n+
297 }
\n+
298
\n+
299 // we can allocate the windows now
\n+
300 nblocks = _nblocks;
\n+
301 if (nblocks>0)
\n+
302 {
\n+
303 // allocate and construct objects
\n+
304 block = windowAllocator_.allocate(nblocks);
\n+
305 new (block) window_type[nblocks];
\n+
306
\n+
307 // set the windows into the big array
\n+
308 for (size_type i=0; i<nblocks; ++i)
\n+
309 block[i].set(m,this->p+(i*m));
\n+
310 }
\n+
311 else
\n+
312 {
\n+
313 nblocks = 0;
\n+
314 block = nullptr;
\n+
315 }
\n+
316
\n+
317 // and the vector is usable
\n+
318 initialized = true;
\n+
319 }
\n+
320
\n+\n+
323 {
\n+
324 if (&a!=this) // check if this and a are different objects
\n+
325 {
\n+
326 // reallocate arrays if necessary
\n+
327 // Note: still the block sizes may vary !
\n+
328 if (this->n!=a.n || nblocks!=a.nblocks)
\n+
329 {
\n+
330 // deconstruct objects and deallocate memory if necessary
\n+
331 if (this->n>0) {
\n+
332 size_type i=this->n;
\n+
333 while (i)
\n+
334 this->p[--i].~B();
\n+
335 allocator_.deallocate(this->p,this->n);
\n+
336 }
\n+
337 if (nblocks>0) {
\n+
338 size_type i=nblocks;
\n+
339 while (i)
\n+
340 block[--i].~window_type();
\n+
341 windowAllocator_.deallocate(block,nblocks);
\n+
342 }
\n+
343
\n+
344 // allocate the big array in the base class
\n+
345 this->n = a.n;
\n+
346 if (this->n>0)
\n+
347 {
\n+
348 // allocate and construct objects
\n+
349 this->p = allocator_.allocate(this->n);
\n+
350 new (this->p)B[this->n];
\n+
351 }
\n+
352 else
\n+
353 {
\n+
354 this->n = 0;
\n+
355 this->p = nullptr;
\n+
356 }
\n+
357
\n+
358 // we can allocate the windows now
\n+
359 nblocks = a.nblocks;
\n+
360 if (nblocks>0)
\n+
361 {
\n+
362 // alloc
\n+
363 block = windowAllocator_.allocate(nblocks);
\n+
364 new (block) window_type[nblocks];
\n+
365 }
\n+
366 else
\n+
367 {
\n+
368 nblocks = 0;
\n+
369 block = nullptr;
\n+
370 }
\n+
371 }
\n+
372
\n+
373 // copy block structure, might be different although
\n+
374 // sizes are the same !
\n+
375 if (nblocks>0)
\n+
376 {
\n+
377 block[0].set(a.block[0].getsize(),this->p); // first block
\n+
378 for (size_type i=1; i<nblocks; ++i) // and the rest
\n+
379 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
\n+
380 }
\n+
381
\n+
382 // and copy the data
\n+
383 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
\n+
384 }
\n+
385
\n+
386 // and we have a usable vector
\n+
387 initialized = true;
\n+
388
\n+
389 return *this; // Gebe Referenz zurueck damit a=b=c; klappt
\n+
390 }
\n+
391
\n+
392
\n+
393 //===== assignment from scalar
\n+
394
\n+\n+
397 {
\n+
398 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
\n+
399 return *this;
\n+
400 }
\n+
401
\n+
402
\n+
403 //===== the creation interface
\n+
404
\n+
405 class CreateIterator;
\n+
406
\n+
407#ifndef DOXYGEN
\n+
408
\n+
409 // The window_type does not hand out a reference to its size,
\n+
410 // so in order to provide a valid iterator, we need a workaround
\n+
411 // to make assignment possible. This proxy enables just that by
\n+
412 // implicitly converting to the stored size for read access and
\n+
413 // tunneling assignment to the accessor method of the window.
\n+
414 struct SizeProxy
\n+
415 {
\n+
416
\n+
417 operator size_type() const
\n+
418 {
\n+
419 return target->getsize();
\n+
420 }
\n+
421
\n+
422 SizeProxy& operator=(size_type size)
\n+
423 {
\n+
424 target->setsize(size);
\n+
425 return *this;
\n+
426 }
\n+
427
\n+
428 private:
\n+
429
\n+
430 friend class CreateIterator;
\n+
431
\n+
432 SizeProxy(window_type& t)
\n+
433 : target(&t)
\n+
434 {}
\n+
435
\n+
436 window_type* target;
\n+
437 };
\n+
438
\n+
439#endif // DOXYGEN
\n+
440
\n+\n+
443 {
\n+
444 public:
\n+
446 using iterator_category = std::output_iterator_tag;
\n+
447
\n+\n+
450
\n+
457 using difference_type = void;
\n+
458
\n+\n+
461
\n+
463 using reference = SizeProxy;
\n+
464
\n+
466 CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
\n+
467 v(_v),
\n+
468 i(_i),
\n+
469 isEnd(_isEnd) {}
\n+
470
\n+\n+
472 // When the iterator gets destructed, we allocate the memory
\n+
473 // for the VariableBlockVector if
\n+
474 // 1. the current iterator was not created as enditerator
\n+
475 // 2. we're at the last block
\n+
476 // 3. the vector hasn't been initialized earlier
\n+
477 if (not isEnd && i==v.nblocks && not v.initialized)
\n+
478 v.allocate();
\n+
479 }
\n+
480
\n+\n+
483 {
\n+
484 // go to next block
\n+
485 ++i;
\n+
486
\n+
487 return *this;
\n+
488 }
\n+
489
\n+\n+
492 {
\n+
493 CreateIterator tmp(*this);
\n+
494 this->operator++();
\n+
495 return tmp;
\n+
496 }
\n+
497
\n+
499 bool operator!= (const CreateIterator& it) const
\n+
500 {
\n+
501 return (i!=it.i) || (&v!=&it.v);
\n+
502 }
\n+
503
\n+
505 bool operator== (const CreateIterator& it) const
\n+
506 {
\n+
507 return (i==it.i) && (&v==&it.v);
\n+
508 }
\n+
509
\n+\n+
512 {
\n+
513 return i;
\n+
514 }
\n+
515
\n+\n+
518 {
\n+
519 v.block[i].setsize(_k);
\n+
520 }
\n+
521
\n+
523#ifdef DOXYGEN
\n+
524 size_type&
\n+
525#else
\n+
526 SizeProxy
\n+
527#endif
\n+\n+
529 {
\n+
530 return {v.block[i]};
\n+
531 }
\n+
532
\n+
533 private:
\n+
534 VariableBlockVector& v; // my vector
\n+
535 size_type i; // current block to be defined
\n+
536 const bool isEnd; // flag if this object was created as the end iterator.
\n+
537 };
\n+
538
\n+
539 // CreateIterator wants to set all the arrays ...
\n+
540 friend class CreateIterator;
\n+
541
\n+\n+
544 {
\n+
545#ifdef DUNE_ISTL_WITH_CHECKING
\n+
546 if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
\n+
547#endif
\n+
548 return CreateIterator(*this,0, false);
\n+
549 }
\n+
550
\n+\n+
553 {
\n+
554 return CreateIterator(*this,nblocks, true);
\n+
555 }
\n+
556
\n+
557
\n+
558 //===== access to components
\n+
559 // has to be overwritten from base class because it must
\n+
560 // return access to the windows
\n+
561
\n+
563 window_type& operator[] (size_type i)
\n+
564 {
\n+
565#ifdef DUNE_ISTL_WITH_CHECKING
\n+
566 if (i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
\n+
567#endif
\n+
568 return block[i];
\n+
569 }
\n+
570
\n+
572 const window_type& operator[] (size_type i) const
\n+
573 {
\n+
574#ifdef DUNE_ISTL_WITH_CHECKING
\n+
575 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
\n+
576#endif
\n+
577 return block[i];
\n+
578 }
\n+
579
\n+
581 template <class T, class R>
\n+\n+
583 : public RandomAccessIteratorFacade<RealIterator<T,R>, T, R>
\n+
584 {
\n+
585 public:
\n+\n+
588 {
\n+
589 p = nullptr;
\n+
590 i = 0;
\n+
591 }
\n+
592
\n+
594 RealIterator (window_type* _p, size_type _i)
\n+
595 : p(_p), i(_i)
\n+
596 {}
\n+
597
\n+\n+
600 {
\n+
601 ++i;
\n+
602 }
\n+
603
\n+\n+
606 {
\n+
607 --i;
\n+
608 }
\n+
609
\n+
611 bool equals (const RealIterator& it) const
\n+
612 {
\n+
613 return (p+i)==(it.p+it.i);
\n+
614 }
\n+
615
\n+
617 window_type& dereference () const
\n+
618 {
\n+
619 return p[i];
\n+
620 }
\n+
621
\n+
622 void advance(std::ptrdiff_t d)
\n+
623 {
\n+
624 i+=d;
\n+
625 }
\n+
626
\n+
627 std::ptrdiff_t distanceTo(const RealIterator& o) const
\n+
628 {
\n+
629 return o.i-i;
\n+
630 }
\n+
631
\n+
632 // Needed for operator[] of the iterator
\n+
633 window_type& elementAt (std::ptrdiff_t offset) const
\n+
634 {
\n+
635 return p[i+offset];
\n+
636 }
\n+
637
\n+\n+
640 {
\n+
641 return i;
\n+
642 }
\n+
643
\n+
644 private:
\n+
645 window_type* p;
\n+
646 size_type i;
\n+
647 };
\n+
648
\n+\n+
650
\n+\n+
653 {
\n+
654 return Iterator(block,0);
\n+
655 }
\n+
656
\n+\n+
659 {
\n+
660 return Iterator(block,nblocks);
\n+
661 }
\n+
662
\n+\n+
666 {
\n+
667 return Iterator(block,nblocks-1);
\n+
668 }
\n+
669
\n+\n+
673 {
\n+
674 return Iterator(block,-1);
\n+
675 }
\n+
676
\n+\n+
679
\n+\n+
682
\n+\n+
685
\n+\n+
688 {
\n+
689 return ConstIterator(block,0);
\n+
690 }
\n+
691
\n+\n+
694 {
\n+
695 return ConstIterator(block,nblocks);
\n+
696 }
\n+
697
\n+\n+
701 {
\n+
702 return ConstIterator(block,nblocks-1);
\n+
703 }
\n+
704
\n+\n+
707 {
\n+
708 return ConstIterator(block,-1);
\n+
709 }
\n+
710
\n+\n+
713 {
\n+
714 return Iterator(block,std::min(i,nblocks));
\n+
715 }
\n+
716
\n+\n+
719 {
\n+
720 return ConstIterator(block,std::min(i,nblocks));
\n+
721 }
\n+
722
\n+
723 //===== sizes
\n+
724
\n+
726 size_type N () const
\n+
727 {
\n+
728 return nblocks;
\n+
729 }
\n+
730
\n+\n+
736 {
\n+
737 return nblocks;
\n+
738 }
\n+
739
\n+
740
\n+
741 private:
\n+
742
\n+
743 void allocate() {
\n+
744 if (this->initialized)
\n+
745 DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
\n+
746
\n+
747 // calculate space needed:
\n+
748 this->n=0;
\n+
749 for(size_type i = 0; i < nblocks; i++) {
\n+
750 this->n += block[i].size();
\n+
751 }
\n+
752
\n+
753 // now we can allocate the big array in the base class of v
\n+
754 if (this->n>0)
\n+
755 {
\n+
756 // allocate and construct objects
\n+
757 this->p = allocator_.allocate(this->n);
\n+
758 new (this->p)B[this->n];
\n+
759 }
\n+
760 else
\n+
761 {
\n+
762 this->p = nullptr;
\n+
763 }
\n+
764
\n+
765 // and we set the window pointers
\n+
766 this->block[0].setptr(this->p); // pointer to first block
\n+
767 for (size_type j=1; j<nblocks; ++j) // and the rest
\n+
768 block[j].setptr(block[j-1].getptr()+block[j-1].getsize());
\n+
769
\n+
770 // and the vector is ready
\n+
771 this->initialized = true;
\n+
772 }
\n+
773
\n+
774 size_type nblocks; // number of blocks in vector
\n+
775 window_type* block; // array of blocks pointing to the array in the base class
\n+
776 bool initialized; // true if vector has been initialized
\n+
777
\n+
778 A allocator_;
\n+
779
\n+
780 typename std::allocator_traits<A>::template rebind_alloc<window_type> windowAllocator_;
\n+
781 };
\n+
782
\n+
783
\n+
784
\n+
787} // end namespace
\n+
788
\n+
789#endif
\n+
This file implements a vector space as a tensor product of a given vector space. The number of compon...
\n+\n+
Helper functions for determining the vector/matrix block level.
\n
Definition: allocator.hh:11
\n-
void bildl_decompose(Matrix &A)
compute ILDL decomposition of a symmetric matrix A
Definition: ildl.hh:88
\n-
void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
Definition: ildl.hh:149
\n-
static void bildl_subtractBCT(const FieldMatrix< K, m, n > &B, const FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)
Definition: ildl.hh:24
\n+
A vector of blocks with memory management.
Definition: bvector.hh:395
\n
derive error class from the base class in common
Definition: istlexception.hh:19
\n-
Error when performing an operation on a matrix block.
Definition: istlexception.hh:52
\n-
int r
Definition: istlexception.hh:54
\n-
A generic dynamic dense matrix.
Definition: matrix.hh:561
\n-
RowIterator beforeBegin()
Definition: matrix.hh:634
\n-
RowIterator beforeEnd()
Definition: matrix.hh:627
\n-
RowIterator end()
Get iterator to one beyond last row.
Definition: matrix.hh:620
\n-
RowIterator begin()
Get iterator to first row.
Definition: matrix.hh:614
\n-
Definition: matrixutils.hh:27
\n+
A Vector of blocks with different blocksizes.
Definition: vbvector.hh:46
\n+
RealIterator< value_type, window_type & > Iterator
Definition: vbvector.hh:649
\n+
VariableBlockVector()
Definition: vbvector.hh:97
\n+
friend class CreateIterator
Definition: vbvector.hh:540
\n+
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition: vbvector.hh:55
\n+
A allocator_type
export the allocator type
Definition: vbvector.hh:58
\n+
VariableBlockVector(size_type _nblocks, size_type m)
Definition: vbvector.hh:134
\n+
size_type size() const
Definition: vbvector.hh:735
\n+
size_type N() const
number of blocks in the vector (are of variable size here)
Definition: vbvector.hh:726
\n+
VariableBlockVector(const VariableBlockVector &a)
copy constructor, has copy semantics
Definition: vbvector.hh:172
\n+
VariableBlockVector(size_type _nblocks)
Definition: vbvector.hh:108
\n+
~VariableBlockVector()
free dynamic memory
Definition: vbvector.hh:215
\n+
window_type & operator[](size_type i)
random access to blocks
Definition: vbvector.hh:563
\n+
CreateIterator createend()
get create iterator pointing to one after the last block
Definition: vbvector.hh:552
\n+
Iterator beforeBegin() const
Definition: vbvector.hh:672
\n+
CreateIterator createbegin()
get initial create iterator
Definition: vbvector.hh:543
\n+
VariableBlockVector & operator=(const VariableBlockVector &a)
assignment
Definition: vbvector.hh:322
\n+
static constexpr auto blocklevel
Definition: vbvector.hh:90
\n+
ConstIterator rend() const
end ConstIterator
Definition: vbvector.hh:706
\n+
A::size_type size_type
The size type for the index access.
Definition: vbvector.hh:73
\n+
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition: vbvector.hh:718
\n+
ConstIterator beforeEnd() const
Definition: vbvector.hh:700
\n+
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition: vbvector.hh:712
\n+
const window_type & const_reference
Export type used for const references to container entries.
Definition: vbvector.hh:70
\n+
RealIterator< const value_type, const window_type & > ConstIterator
Const iterator.
Definition: vbvector.hh:681
\n+
Iterator end()
end Iterator
Definition: vbvector.hh:658
\n+
ConstIterator begin() const
begin ConstIterator
Definition: vbvector.hh:687
\n+
BlockVector< B, A > value_type
Type of the elements of the outer vector, i.e., dynamic vectors of B.
Definition: vbvector.hh:80
\n+
ConstIterator end() const
end ConstIterator
Definition: vbvector.hh:693
\n+
BlockVector< B, A > block_type
Same as value_type, here for historical reasons.
Definition: vbvector.hh:84
\n+
void resize(size_type _nblocks, size_type m)
same effect as constructor with same argument
Definition: vbvector.hh:270
\n+
window_type & reference
Export type used for references to container entries.
Definition: vbvector.hh:64
\n+
void resize(size_type _nblocks)
same effect as constructor with same argument
Definition: vbvector.hh:234
\n+
Iterator beforeEnd()
Definition: vbvector.hh:665
\n+
Iterator begin()
begin Iterator
Definition: vbvector.hh:652
\n+
Iterator class for sequential creation of blocks.
Definition: vbvector.hh:443
\n+
bool operator==(const CreateIterator &it) const
equality
Definition: vbvector.hh:505
\n+
size_type index() const
dereferencing
Definition: vbvector.hh:511
\n+
SizeProxy reference
reference type
Definition: vbvector.hh:463
\n+
size_type * pointer
pointer type
Definition: vbvector.hh:460
\n+
bool operator!=(const CreateIterator &it) const
inequality
Definition: vbvector.hh:499
\n+
~CreateIterator()
Definition: vbvector.hh:471
\n+
size_type value_type
value type
Definition: vbvector.hh:449
\n+
CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)
constructor
Definition: vbvector.hh:466
\n+
void setblocksize(size_type _k)
set size of current block
Definition: vbvector.hh:517
\n+
size_type & operator*()
Access size of current block.
Definition: vbvector.hh:528
\n+
std::output_iterator_tag iterator_category
iterator category
Definition: vbvector.hh:446
\n+
CreateIterator & operator++()
prefix increment
Definition: vbvector.hh:482
\n+
void difference_type
difference type (unused)
Definition: vbvector.hh:457
\n+
Iterator class for sequential access.
Definition: vbvector.hh:584
\n+
RealIterator(window_type *_p, size_type _i)
constructor
Definition: vbvector.hh:594
\n+
bool equals(const RealIterator &it) const
equality
Definition: vbvector.hh:611
\n+
size_type index() const
Return the index of the entry this iterator is pointing to.
Definition: vbvector.hh:639
\n+
window_type & elementAt(std::ptrdiff_t offset) const
Definition: vbvector.hh:633
\n+
void decrement()
prefix decrement
Definition: vbvector.hh:605
\n+
void advance(std::ptrdiff_t d)
Definition: vbvector.hh:622
\n+
void increment()
prefix increment
Definition: vbvector.hh:599
\n+
RealIterator()
constructor, no arguments
Definition: vbvector.hh:587
\n+
std::ptrdiff_t distanceTo(const RealIterator &o) const
Definition: vbvector.hh:627
\n+
window_type & dereference() const
dereferencing
Definition: vbvector.hh:617
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,271 +4,936 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-ildl.hh\n+vbvector.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3#ifndef DUNE_ISTL_ILDL_HH\n- 4#define DUNE_ISTL_ILDL_HH\n- 5\n- 6#include \n- 7#include \n- 8#include \"ilu.hh\"\n- 9\n- 17namespace Dune\n- 18{\n+ 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n+ 4// vi: set et ts=4 sw=2 sts=2:\n+ 5#ifndef DUNE_ISTL_VBVECTOR_HH\n+ 6#define DUNE_ISTL_VBVECTOR_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \n+ 15#include \"istlexception.hh\"\n+ 16#include \"bvector.hh\"\n+ 17\n+ 18#include \n 19\n- 20 // bildl_subtractBCT\n- 21 // -----------------\n- 22\n- 23 template< class K, int m, int n >\n-24 inline static void bildl_subtractBCT ( const FieldMatrix<_K,_m,_n_> &B,\n-const FieldMatrix<_K,_m,_n_> &CT, FieldMatrix<_K,_m,_n_> &A )\n- 25 {\n- 26 for( int i = 0; i < m; ++i )\n- 27 {\n- 28 for( int j = 0; j < n; ++j )\n- 29 {\n- 30 for( int k = 0; k < n; ++k )\n- 31 A[ i ][ j ] -= B[ i ][ k ] * CT[ j ][ k ];\n- 32 }\n- 33 }\n- 34 }\n- 35\n- 36 template< class K >\n-37 inline static void bildl_subtractBCT ( const K &B, const K &CT, K &A,\n- 38 typename std::enable_if_t::value>* sfinae = nullptr )\n- 39 {\n- 40 A -= B * CT;\n- 41 }\n- 42\n- 43 template< class Matrix >\n-44 inline static void bildl_subtractBCT ( const Matrix &B, const Matrix &CT,\n-Matrix &A,\n- 45 typename std::enable_if_t::value>* sfinae = nullptr\n-)\n+ 24namespace Dune {\n+ 25\n+ 41 template >\n+42 class VariableBlockVector : public Imp::block_vector_unmanaged\n+ 43 // this derivation gives us all the blas level 1 and norms\n+ 44 // on the large array. However, access operators have to be\n+ 45 // overwritten.\n 46 {\n- 47 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 48 {\n- 49 auto &&A_i = *i;\n- 50 auto &&B_i = B[ i.index() ];\n- 51 const auto ikend = B_i.end();\n- 52 for( auto j = A_i.begin(), jend = A_i.end(); j != jend; ++j )\n- 53 {\n- 54 auto &&A_ij = *j;\n- 55 auto &&CT_j = CT[ j.index() ];\n- 56 const auto jkend = CT_j.end();\n- 57 for( auto ik = B_i.begin(), jk = CT_j.begin(); (ik != ikend) && (jk !=\n-jkend); )\n- 58 {\n- 59 if( ik.index() == jk.index() )\n- 60 {\n- 61 bildl_subtractBCT( *ik, *jk, A_ij );\n- 62 ++ik; ++jk;\n- 63 }\n- 64 else if( ik.index() < jk.index() )\n- 65 ++ik;\n- 66 else\n- 67 ++jk;\n- 68 }\n- 69 }\n- 70 }\n- 71 }\n- 72\n- 73\n+ 47 // just a shorthand\n+ 48 typedef Imp::BlockVectorWindow window_type;\n+ 49\n+ 50 public:\n+ 51\n+ 52 //===== type definitions and constants\n+ 53\n+55 using field_type = typename Imp::BlockTraits::field_type;\n+ 56\n+58 typedef A allocator_type;\n+ 59\n+64 typedef window_type& reference;\n+ 65\n+70 typedef const window_type& const_reference;\n+ 71\n+73 typedef typename A::size_type size_type;\n 74\n- 75 // bildl_decompose\n- 76 // ---------------\n- 77\n- 87 template< class Matrix >\n-88 inline void bildl_decompose ( Matrix &A )\n- 89 {\n- 90 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 91 {\n- 92 auto &&A_i = *i;\n+80 typedef BlockVector value_type;\n+ 81\n+84 typedef BlockVector block_type;\n+ 85\n+ 89 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+90 static constexpr auto blocklevel = blockLevel()+2;\n+ 91\n+ 92 //===== constructors and such\n 93\n- 94 auto ij = A_i.begin();\n- 95 for( ; ij.index() < i.index(); ++ij )\n- 96 {\n- 97 auto &&A_ij = *ij;\n- 98 auto &&A_j = A[ ij.index() ];\n- 99\n- 100 // store L_ij Dj in A_ij (note: for k < i: A_kj = L_kj)\n- 101 // L_ij Dj = A_ij - \\sum_{k < j} (L_ik D_k) L_jk^T\n- 102 auto ik = A_i.begin();\n- 103 auto jk = A_j.begin();\n- 104 while( (ik != ij) && (jk.index() < ij.index()) )\n- 105 {\n- 106 if( ik.index() == jk.index() )\n- 107 {\n- 108 bildl_subtractBCT(*ik, *jk, A_ij);\n- 109 ++ik; ++jk;\n- 110 }\n- 111 else if( ik.index() < jk.index() )\n- 112 ++ik;\n- 113 else\n- 114 ++jk;\n- 115 }\n+97 VariableBlockVector () : Imp::block_vector_unmanaged()\n+ 98 {\n+ 99 // nothing is known ...\n+ 100 nblocks = 0;\n+ 101 block = nullptr;\n+ 102 initialized = false;\n+ 103 }\n+ 104\n+108 explicit VariableBlockVector (size_type _nblocks) : Imp::\n+block_vector_unmanaged()\n+ 109 {\n+ 110 // we can allocate the windows now\n+ 111 nblocks = _nblocks;\n+ 112 if (nblocks>0)\n+ 113 {\n+ 114 block = windowAllocator_.allocate(nblocks);\n+ 115 new (block) window_type[nblocks];\n 116 }\n- 117\n- 118 if( ij.index() != i.index() )\n- 119 DUNE_THROW( ISTLError, \"diagonal entry missing\" );\n- 120\n- 121 // update diagonal and multiply A_ij by D_j^{-1}\n- 122 auto &&A_ii = *ij;\n- 123 for( auto ik = A_i.begin(); ik != ij; ++ik )\n- 124 {\n- 125 auto &&A_ik = *ik;\n- 126 const auto &A_k = A[ ik.index() ];\n+ 117 else\n+ 118 {\n+ 119 nblocks = 0;\n+ 120 block = nullptr;\n+ 121 }\n+ 122\n+ 123 // Note: memory in base class still not allocated\n+ 124 // the vector not usable\n+ 125 initialized = false;\n+ 126 }\n 127\n- 128 auto B = A_ik;\n- 129 Impl::asMatrix(A_ik).rightmultiply( Impl::asMatrix(*A_k.find( ik.index()\n-)) );\n- 130 bildl_subtractBCT( B, A_ik, A_ii );\n- 131 }\n- 132 try\n- 133 {\n- 134 Impl::asMatrix(A_ii).invert();\n- 135 }\n- 136 catch( const Dune::FMatrixError &e )\n- 137 {\n- 138 DUNE_THROW( MatrixBlockError, \"ILDL failed to invert matrix block A[\" <<\n-i.index() << \"][\" << ij.index() << \"]\" << e.what(); th__ex.r = i.index();\n-th__ex.c = ij.index() );\n- 139 }\n- 140 }\n- 141 }\n- 142\n- 143\n- 144\n- 145 // bildl_backsolve\n- 146 // ---------------\n- 147\n- 148 template< class Matrix, class X, class Y >\n-149 inline void bildl_backsolve ( const Matrix &A, X &v, const Y &d, bool\n-isLowerTriangular = false )\n- 150 {\n- 151 // solve L v = d, note: Lii = I\n- 152 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 153 {\n- 154 const auto &A_i = *i;\n- 155 v[ i.index() ] = d[ i.index() ];\n- 156 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )\n- 157 {\n- 158 auto&& vi = Impl::asVector( v[ i.index() ] );\n- 159 Impl::asMatrix(*ij).mmv(Impl::asVector( v[ ij.index() ] ), vi);\n+134 VariableBlockVector (size_type _nblocks, size_type m) : Imp::\n+block_vector_unmanaged()\n+ 135 {\n+ 136 // and we can allocate the big array in the base class\n+ 137 this->n = _nblocks*m;\n+ 138 if (this->n>0)\n+ 139 {\n+ 140 this->p = allocator_.allocate(this->n);\n+ 141 new (this->p)B[this->n];\n+ 142 }\n+ 143 else\n+ 144 {\n+ 145 this->n = 0;\n+ 146 this->p = nullptr;\n+ 147 }\n+ 148\n+ 149 // we can allocate the windows now\n+ 150 nblocks = _nblocks;\n+ 151 if (nblocks>0)\n+ 152 {\n+ 153 // allocate and construct the windows\n+ 154 block = windowAllocator_.allocate(nblocks);\n+ 155 new (block) window_type[nblocks];\n+ 156\n+ 157 // set the windows into the big array\n+ 158 for (size_type i=0; ip+(i*m));\n 160 }\n- 161 }\n- 162\n- 163 // solve D w = v, note: diagonal stores Dii^{-1}\n- 164 if( isLowerTriangular )\n- 165 {\n- 166 // The matrix is lower triangular, so the diagonal entry is the\n- 167 // last one in each row.\n- 168 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 169 {\n- 170 const auto &A_i = *i;\n- 171 const auto ii = A_i.beforeEnd();\n- 172 assert( ii.index() == i.index() );\n- 173 // We need to be careful here: Directly using\n- 174 // auto rhs = Impl::asVector(v[ i.index() ]);\n- 175 // is not OK in case this is a proxy. Hence\n- 176 // we first have to copy the value. Notice that\n- 177 // this is still not OK, if the vector type itself returns\n- 178 // proxy references.\n- 179 auto rhsValue = v[ i.index() ];\n- 180 auto&& rhs = Impl::asVector(rhsValue);\n- 181 auto&& vi = Impl::asVector( v[ i.index() ] );\n- 182 Impl::asMatrix(*ii).mv(rhs, vi);\n- 183 }\n+ 161 else\n+ 162 {\n+ 163 nblocks = 0;\n+ 164 block = nullptr;\n+ 165 }\n+ 166\n+ 167 // and the vector is usable\n+ 168 initialized = true;\n+ 169 }\n+ 170\n+172 VariableBlockVector (const VariableBlockVector& a)\n+ 173 {\n+ 174 // allocate the big array in the base class\n+ 175 this->n = a.n;\n+ 176 if (this->n>0)\n+ 177 {\n+ 178 // allocate and construct objects\n+ 179 this->p = allocator_.allocate(this->n);\n+ 180 new (this->p)B[this->n];\n+ 181\n+ 182 // copy data\n+ 183 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n 184 }\n 185 else\n 186 {\n- 187 // Without assumptions on the sparsity pattern we have to search\n- 188 // for the diagonal entry in each row.\n- 189 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 190 {\n- 191 const auto &A_i = *i;\n- 192 const auto ii = A_i.find( i.index() );\n- 193 assert( ii.index() == i.index() );\n- 194 // We need to be careful here: Directly using\n- 195 // auto rhs = Impl::asVector(v[ i.index() ]);\n- 196 // is not OK in case this is a proxy. Hence\n- 197 // we first have to copy the value. Notice that\n- 198 // this is still not OK, if the vector type itself returns\n- 199 // proxy references.\n- 200 auto rhsValue = v[ i.index() ];\n- 201 auto&& rhs = Impl::asVector(rhsValue);\n- 202 auto&& vi = Impl::asVector( v[ i.index() ] );\n- 203 Impl::asMatrix(*ii).mv(rhs, vi);\n- 204 }\n- 205 }\n- 206\n- 207 // solve L^T v = w, note: only L is stored\n- 208 // note: we perform the operation column-wise from right to left\n- 209 for( auto i = A.beforeEnd(), iend = A.beforeBegin(); i != iend; --i )\n- 210 {\n- 211 const auto &A_i = *i;\n- 212 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )\n- 213 {\n- 214 auto&& vij = Impl::asVector( v[ ij.index() ] );\n- 215 Impl::asMatrix(*ij).mmtv(Impl::asVector( v[ i.index() ] ), vij);\n- 216 }\n- 217 }\n- 218 }\n- 219\n- 220} // namespace Dune\n- 221\n- 222#endif // #ifndef DUNE_ISTL_ILDL_HH\n-ilu.hh\n-The incomplete LU factorization kernels.\n+ 187 this->n = 0;\n+ 188 this->p = nullptr;\n+ 189 }\n+ 190\n+ 191 // we can allocate the windows now\n+ 192 nblocks = a.nblocks;\n+ 193 if (nblocks>0)\n+ 194 {\n+ 195 // alloc\n+ 196 block = windowAllocator_.allocate(nblocks);\n+ 197 new (block) window_type[nblocks];\n+ 198\n+ 199 // and we must set the windows\n+ 200 block[0].set(a.block[0].getsize(),this->p); // first block\n+ 201 for (size_type i=1; in>0) {\n+ 218 size_type i=this->n;\n+ 219 while (i)\n+ 220 this->p[--i].~B();\n+ 221 allocator_.deallocate(this->p,this->n);\n+ 222 }\n+ 223 if (nblocks>0) {\n+ 224 size_type i=nblocks;\n+ 225 while (i)\n+ 226 block[--i].~window_type();\n+ 227 windowAllocator_.deallocate(block,nblocks);\n+ 228 }\n+ 229\n+ 230 }\n+ 231\n+ 232\n+234 void resize (size_type _nblocks)\n+ 235 {\n+ 236 // deconstruct objects and deallocate memory if necessary\n+ 237 if (this->n>0) {\n+ 238 size_type i=this->n;\n+ 239 while (i)\n+ 240 this->p[--i].~B();\n+ 241 allocator_.deallocate(this->p,this->n);\n+ 242 }\n+ 243 if (nblocks>0) {\n+ 244 size_type i=nblocks;\n+ 245 while (i)\n+ 246 block[--i].~window_type();\n+ 247 windowAllocator_.deallocate(block,nblocks);\n+ 248 }\n+ 249 this->n = 0;\n+ 250 this->p = nullptr;\n+ 251\n+ 252 // we can allocate the windows now\n+ 253 nblocks = _nblocks;\n+ 254 if (nblocks>0)\n+ 255 {\n+ 256 block = windowAllocator_.allocate(nblocks);\n+ 257 new (block) window_type[nblocks];\n+ 258 }\n+ 259 else\n+ 260 {\n+ 261 nblocks = 0;\n+ 262 block = nullptr;\n+ 263 }\n+ 264\n+ 265 // and the vector not fully usable\n+ 266 initialized = false;\n+ 267 }\n+ 268\n+270 void resize (size_type _nblocks, size_type m)\n+ 271 {\n+ 272 // deconstruct objects and deallocate memory if necessary\n+ 273 if (this->n>0) {\n+ 274 size_type i=this->n;\n+ 275 while (i)\n+ 276 this->p[--i].~B();\n+ 277 allocator_.deallocate(this->p,this->n);\n+ 278 }\n+ 279 if (nblocks>0) {\n+ 280 size_type i=nblocks;\n+ 281 while (i)\n+ 282 block[--i].~window_type();\n+ 283 windowAllocator_.deallocate(block,nblocks);\n+ 284 }\n+ 285\n+ 286 // and we can allocate the big array in the base class\n+ 287 this->n = _nblocks*m;\n+ 288 if (this->n>0)\n+ 289 {\n+ 290 this->p = allocator_.allocate(this->n);\n+ 291 new (this->p)B[this->n];\n+ 292 }\n+ 293 else\n+ 294 {\n+ 295 this->n = 0;\n+ 296 this->p = nullptr;\n+ 297 }\n+ 298\n+ 299 // we can allocate the windows now\n+ 300 nblocks = _nblocks;\n+ 301 if (nblocks>0)\n+ 302 {\n+ 303 // allocate and construct objects\n+ 304 block = windowAllocator_.allocate(nblocks);\n+ 305 new (block) window_type[nblocks];\n+ 306\n+ 307 // set the windows into the big array\n+ 308 for (size_type i=0; ip+(i*m));\n+ 310 }\n+ 311 else\n+ 312 {\n+ 313 nblocks = 0;\n+ 314 block = nullptr;\n+ 315 }\n+ 316\n+ 317 // and the vector is usable\n+ 318 initialized = true;\n+ 319 }\n+ 320\n+322 VariableBlockVector& operator=(const VariableBlockVector& a)\n+ 323 {\n+ 324 if (&a!=this) // check if this and a are different objects\n+ 325 {\n+ 326 // reallocate arrays if necessary\n+ 327 // Note: still the block sizes may vary !\n+ 328 if (this->n!=a.n || nblocks!=a.nblocks)\n+ 329 {\n+ 330 // deconstruct objects and deallocate memory if necessary\n+ 331 if (this->n>0) {\n+ 332 size_type i=this->n;\n+ 333 while (i)\n+ 334 this->p[--i].~B();\n+ 335 allocator_.deallocate(this->p,this->n);\n+ 336 }\n+ 337 if (nblocks>0) {\n+ 338 size_type i=nblocks;\n+ 339 while (i)\n+ 340 block[--i].~window_type();\n+ 341 windowAllocator_.deallocate(block,nblocks);\n+ 342 }\n+ 343\n+ 344 // allocate the big array in the base class\n+ 345 this->n = a.n;\n+ 346 if (this->n>0)\n+ 347 {\n+ 348 // allocate and construct objects\n+ 349 this->p = allocator_.allocate(this->n);\n+ 350 new (this->p)B[this->n];\n+ 351 }\n+ 352 else\n+ 353 {\n+ 354 this->n = 0;\n+ 355 this->p = nullptr;\n+ 356 }\n+ 357\n+ 358 // we can allocate the windows now\n+ 359 nblocks = a.nblocks;\n+ 360 if (nblocks>0)\n+ 361 {\n+ 362 // alloc\n+ 363 block = windowAllocator_.allocate(nblocks);\n+ 364 new (block) window_type[nblocks];\n+ 365 }\n+ 366 else\n+ 367 {\n+ 368 nblocks = 0;\n+ 369 block = nullptr;\n+ 370 }\n+ 371 }\n+ 372\n+ 373 // copy block structure, might be different although\n+ 374 // sizes are the same !\n+ 375 if (nblocks>0)\n+ 376 {\n+ 377 block[0].set(a.block[0].getsize(),this->p); // first block\n+ 378 for (size_type i=1; in; i++) this->p[i]=a.p[i];\n+ 384 }\n+ 385\n+ 386 // and we have a usable vector\n+ 387 initialized = true;\n+ 388\n+ 389 return *this; // Gebe Referenz zurueck damit a=b=c; klappt\n+ 390 }\n+ 391\n+ 392\n+ 393 //===== assignment from scalar\n+ 394\n+396 VariableBlockVector& operator=(const field_type& k)\n+ 397 {\n+ 398 (static_cast&>(*this)) = k;\n+ 399 return *this;\n+ 400 }\n+ 401\n+ 402\n+ 403 //===== the creation interface\n+ 404\n+ 405 class CreateIterator;\n+ 406\n+ 407#ifndef DOXYGEN\n+ 408\n+ 409 // The window_type does not hand out a reference to its size,\n+ 410 // so in order to provide a valid iterator, we need a workaround\n+ 411 // to make assignment possible. This proxy enables just that by\n+ 412 // implicitly converting to the stored size for read access and\n+ 413 // tunneling assignment to the accessor method of the window.\n+ 414 struct SizeProxy\n+ 415 {\n+ 416\n+ 417 operator size_type() const\n+ 418 {\n+ 419 return target->getsize();\n+ 420 }\n+ 421\n+ 422 SizeProxy& operator=(size_type size)\n+ 423 {\n+ 424 target->setsize(size);\n+ 425 return *this;\n+ 426 }\n+ 427\n+ 428 private:\n+ 429\n+ 430 friend class CreateIterator;\n+ 431\n+ 432 SizeProxy(window_type& t)\n+ 433 : target(&t)\n+ 434 {}\n+ 435\n+ 436 window_type* target;\n+ 437 };\n+ 438\n+ 439#endif // DOXYGEN\n+ 440\n+442 class CreateIterator\n+ 443 {\n+ 444 public:\n+446 using iterator_category = std::output_iterator_tag;\n+ 447\n+449 using value_type = size_type;\n+ 450\n+457 using difference_type = void;\n+ 458\n+460 using pointer = size_type*;\n+ 461\n+463 using reference = SizeProxy;\n+ 464\n+466 CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :\n+ 467 v(_v),\n+ 468 i(_i),\n+ 469 isEnd(_isEnd) {}\n+ 470\n+471 ~CreateIterator() {\n+ 472 // When the iterator gets destructed, we allocate the memory\n+ 473 // for the VariableBlockVector if\n+ 474 // 1. the current iterator was not created as enditerator\n+ 475 // 2. we're at the last block\n+ 476 // 3. the vector hasn't been initialized earlier\n+ 477 if (not isEnd && i==v.nblocks && not v.initialized)\n+ 478 v.allocate();\n+ 479 }\n+ 480\n+482 CreateIterator& operator++()\n+ 483 {\n+ 484 // go to next block\n+ 485 ++i;\n+ 486\n+ 487 return *this;\n+ 488 }\n+ 489\n+491 CreateIterator operator++(int)\n+ 492 {\n+ 493 CreateIterator tmp(*this);\n+ 494 this->operator++();\n+ 495 return tmp;\n+ 496 }\n+ 497\n+499 bool operator!=(const CreateIterator& it) const\n+ 500 {\n+ 501 return (i!=it.i) || (&v!=&it.v);\n+ 502 }\n+ 503\n+505 bool operator==(const CreateIterator& it) const\n+ 506 {\n+ 507 return (i==it.i) && (&v==&it.v);\n+ 508 }\n+ 509\n+511 size_type index () const\n+ 512 {\n+ 513 return i;\n+ 514 }\n+ 515\n+517 void setblocksize (size_type _k)\n+ 518 {\n+ 519 v.block[i].setsize(_k);\n+ 520 }\n+ 521\n+ 523#ifdef DOXYGEN\n+ 524 size_type&\n+ 525#else\n+ 526 SizeProxy\n+ 527#endif\n+528 operator*()\n+ 529 {\n+ 530 return {v.block[i]};\n+ 531 }\n+ 532\n+ 533 private:\n+ 534 VariableBlockVector& v; // my vector\n+ 535 size_type i; // current block to be defined\n+ 536 const bool isEnd; // flag if this object was created as the end iterator.\n+ 537 };\n+ 538\n+ 539 // CreateIterator wants to set all the arrays ...\n+540 friend class CreateIterator;\n+ 541\n+543 CreateIterator createbegin ()\n+ 544 {\n+ 545#ifdef DUNE_ISTL_WITH_CHECKING\n+ 546 if (initialized) DUNE_THROW(ISTLError,\"no CreateIterator in initialized\n+state\");\n+ 547#endif\n+ 548 return CreateIterator(*this,0, false);\n+ 549 }\n+ 550\n+552 CreateIterator createend ()\n+ 553 {\n+ 554 return CreateIterator(*this,nblocks, true);\n+ 555 }\n+ 556\n+ 557\n+ 558 //===== access to components\n+ 559 // has to be overwritten from base class because it must\n+ 560 // return access to the windows\n+ 561\n+563 window_type& operator[](size_type i)\n+ 564 {\n+ 565#ifdef DUNE_ISTL_WITH_CHECKING\n+ 566 if (i>=nblocks) DUNE_THROW(ISTLError,\"index out of range\");\n+ 567#endif\n+ 568 return block[i];\n+ 569 }\n+ 570\n+572 const window_type& operator[](size_type i) const\n+ 573 {\n+ 574#ifdef DUNE_ISTL_WITH_CHECKING\n+ 575 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,\"index out of range\");\n+ 576#endif\n+ 577 return block[i];\n+ 578 }\n+ 579\n+ 581 template \n+582 class RealIterator\n+ 583 : public RandomAccessIteratorFacade, T, R>\n+ 584 {\n+ 585 public:\n+587 RealIterator ()\n+ 588 {\n+ 589 p = nullptr;\n+ 590 i = 0;\n+ 591 }\n+ 592\n+594 RealIterator (window_type* _p, size_type _i)\n+ 595 : p(_p), i(_i)\n+ 596 {}\n+ 597\n+599 void increment()\n+ 600 {\n+ 601 ++i;\n+ 602 }\n+ 603\n+605 void decrement()\n+ 606 {\n+ 607 --i;\n+ 608 }\n+ 609\n+611 bool equals (const RealIterator& it) const\n+ 612 {\n+ 613 return (p+i)==(it.p+it.i);\n+ 614 }\n+ 615\n+617 window_type& dereference () const\n+ 618 {\n+ 619 return p[i];\n+ 620 }\n+ 621\n+622 void advance(std::ptrdiff_t d)\n+ 623 {\n+ 624 i+=d;\n+ 625 }\n+ 626\n+627 std::ptrdiff_t distanceTo(const RealIterator& o) const\n+ 628 {\n+ 629 return o.i-i;\n+ 630 }\n+ 631\n+ 632 // Needed for operator[] of the iterator\n+633 window_type& elementAt (std::ptrdiff_t offset) const\n+ 634 {\n+ 635 return p[i+offset];\n+ 636 }\n+ 637\n+639 size_type index() const\n+ 640 {\n+ 641 return i;\n+ 642 }\n+ 643\n+ 644 private:\n+ 645 window_type* p;\n+ 646 size_type i;\n+ 647 };\n+ 648\n+649 using Iterator = RealIterator;\n+ 650\n+652 Iterator begin ()\n+ 653 {\n+ 654 return Iterator(block,0);\n+ 655 }\n+ 656\n+658 Iterator end ()\n+ 659 {\n+ 660 return Iterator(block,nblocks);\n+ 661 }\n+ 662\n+665 Iterator beforeEnd ()\n+ 666 {\n+ 667 return Iterator(block,nblocks-1);\n+ 668 }\n+ 669\n+672 Iterator beforeBegin () const\n+ 673 {\n+ 674 return Iterator(block,-1);\n+ 675 }\n+ 676\n+678 using iterator = Iterator;\n+ 679\n+681 using ConstIterator = RealIterator;\n+ 682\n+684 using const_iterator = ConstIterator;\n+ 685\n+687 ConstIterator begin () const\n+ 688 {\n+ 689 return ConstIterator(block,0);\n+ 690 }\n+ 691\n+693 ConstIterator end () const\n+ 694 {\n+ 695 return ConstIterator(block,nblocks);\n+ 696 }\n+ 697\n+700 ConstIterator beforeEnd() const\n+ 701 {\n+ 702 return ConstIterator(block,nblocks-1);\n+ 703 }\n+ 704\n+706 ConstIterator rend () const\n+ 707 {\n+ 708 return ConstIterator(block,-1);\n+ 709 }\n+ 710\n+712 Iterator find (size_type i)\n+ 713 {\n+ 714 return Iterator(block,std::min(i,nblocks));\n+ 715 }\n+ 716\n+718 ConstIterator find (size_type i) const\n+ 719 {\n+ 720 return ConstIterator(block,std::min(i,nblocks));\n+ 721 }\n+ 722\n+ 723 //===== sizes\n+ 724\n+726 size_type N () const\n+ 727 {\n+ 728 return nblocks;\n+ 729 }\n+ 730\n+735 size_type size () const\n+ 736 {\n+ 737 return nblocks;\n+ 738 }\n+ 739\n+ 740\n+ 741 private:\n+ 742\n+ 743 void allocate() {\n+ 744 if (this->initialized)\n+ 745 DUNE_THROW(ISTLError, \"Attempt to re-allocate already initialized\n+VariableBlockVector\");\n+ 746\n+ 747 // calculate space needed:\n+ 748 this->n=0;\n+ 749 for(size_type i = 0; i < nblocks; i++) {\n+ 750 this->n += block[i].size();\n+ 751 }\n+ 752\n+ 753 // now we can allocate the big array in the base class of v\n+ 754 if (this->n>0)\n+ 755 {\n+ 756 // allocate and construct objects\n+ 757 this->p = allocator_.allocate(this->n);\n+ 758 new (this->p)B[this->n];\n+ 759 }\n+ 760 else\n+ 761 {\n+ 762 this->p = nullptr;\n+ 763 }\n+ 764\n+ 765 // and we set the window pointers\n+ 766 this->block[0].setptr(this->p); // pointer to first block\n+ 767 for (size_type j=1; jinitialized = true;\n+ 772 }\n+ 773\n+ 774 size_type nblocks; // number of blocks in vector\n+ 775 window_type* block; // array of blocks pointing to the array in the base\n+class\n+ 776 bool initialized; // true if vector has been initialized\n+ 777\n+ 778 A allocator_;\n+ 779\n+ 780 typename std::allocator_traits::template rebind_alloc\n+windowAllocator_;\n+ 781 };\n+ 782\n+ 783\n+ 784\n+ 787} // end namespace\n+ 788\n+ 789#endif\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+istlexception.hh\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n Dune\n Definition: allocator.hh:11\n-Dune::bildl_decompose\n-void bildl_decompose(Matrix &A)\n-compute ILDL decomposition of a symmetric matrix A\n-Definition: ildl.hh:88\n-Dune::bildl_backsolve\n-void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool\n-isLowerTriangular=false)\n-Definition: ildl.hh:149\n-Dune::bildl_subtractBCT\n-static void bildl_subtractBCT(const FieldMatrix< K, m, n > &B, const\n-FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)\n-Definition: ildl.hh:24\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n Dune::ISTLError\n derive error class from the base class in common\n Definition: istlexception.hh:19\n-Dune::MatrixBlockError\n-Error when performing an operation on a matrix block.\n-Definition: istlexception.hh:52\n-Dune::MatrixBlockError::r\n-int r\n-Definition: istlexception.hh:54\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::beforeBegin\n-RowIterator beforeBegin()\n-Definition: matrix.hh:634\n-Dune::Matrix::beforeEnd\n-RowIterator beforeEnd()\n-Definition: matrix.hh:627\n-Dune::Matrix::end\n-RowIterator end()\n-Get iterator to one beyond last row.\n-Definition: matrix.hh:620\n-Dune::Matrix::begin\n-RowIterator begin()\n-Get iterator to first row.\n-Definition: matrix.hh:614\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n+Dune::VariableBlockVector\n+A Vector of blocks with different blocksizes.\n+Definition: vbvector.hh:46\n+Dune::VariableBlockVector::Iterator\n+RealIterator< value_type, window_type & > Iterator\n+Definition: vbvector.hh:649\n+Dune::VariableBlockVector::VariableBlockVector\n+VariableBlockVector()\n+Definition: vbvector.hh:97\n+Dune::VariableBlockVector::CreateIterator\n+friend class CreateIterator\n+Definition: vbvector.hh:540\n+Dune::VariableBlockVector::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: vbvector.hh:55\n+Dune::VariableBlockVector::allocator_type\n+A allocator_type\n+export the allocator type\n+Definition: vbvector.hh:58\n+Dune::VariableBlockVector::VariableBlockVector\n+VariableBlockVector(size_type _nblocks, size_type m)\n+Definition: vbvector.hh:134\n+Dune::VariableBlockVector::size\n+size_type size() const\n+Definition: vbvector.hh:735\n+Dune::VariableBlockVector::N\n+size_type N() const\n+number of blocks in the vector (are of variable size here)\n+Definition: vbvector.hh:726\n+Dune::VariableBlockVector::VariableBlockVector\n+VariableBlockVector(const VariableBlockVector &a)\n+copy constructor, has copy semantics\n+Definition: vbvector.hh:172\n+Dune::VariableBlockVector::VariableBlockVector\n+VariableBlockVector(size_type _nblocks)\n+Definition: vbvector.hh:108\n+Dune::VariableBlockVector::~VariableBlockVector\n+~VariableBlockVector()\n+free dynamic memory\n+Definition: vbvector.hh:215\n+Dune::VariableBlockVector::operator[]\n+window_type & operator[](size_type i)\n+random access to blocks\n+Definition: vbvector.hh:563\n+Dune::VariableBlockVector::createend\n+CreateIterator createend()\n+get create iterator pointing to one after the last block\n+Definition: vbvector.hh:552\n+Dune::VariableBlockVector::beforeBegin\n+Iterator beforeBegin() const\n+Definition: vbvector.hh:672\n+Dune::VariableBlockVector::createbegin\n+CreateIterator createbegin()\n+get initial create iterator\n+Definition: vbvector.hh:543\n+Dune::VariableBlockVector::operator=\n+VariableBlockVector & operator=(const VariableBlockVector &a)\n+assignment\n+Definition: vbvector.hh:322\n+Dune::VariableBlockVector::blocklevel\n+static constexpr auto blocklevel\n+Definition: vbvector.hh:90\n+Dune::VariableBlockVector::rend\n+ConstIterator rend() const\n+end ConstIterator\n+Definition: vbvector.hh:706\n+Dune::VariableBlockVector::size_type\n+A::size_type size_type\n+The size type for the index access.\n+Definition: vbvector.hh:73\n+Dune::VariableBlockVector::find\n+ConstIterator find(size_type i) const\n+random access returning iterator (end if not contained)\n+Definition: vbvector.hh:718\n+Dune::VariableBlockVector::beforeEnd\n+ConstIterator beforeEnd() const\n+Definition: vbvector.hh:700\n+Dune::VariableBlockVector::find\n+Iterator find(size_type i)\n+random access returning iterator (end if not contained)\n+Definition: vbvector.hh:712\n+Dune::VariableBlockVector::const_reference\n+const window_type & const_reference\n+Export type used for const references to container entries.\n+Definition: vbvector.hh:70\n+Dune::VariableBlockVector::ConstIterator\n+RealIterator< const value_type, const window_type & > ConstIterator\n+Const iterator.\n+Definition: vbvector.hh:681\n+Dune::VariableBlockVector::end\n+Iterator end()\n+end Iterator\n+Definition: vbvector.hh:658\n+Dune::VariableBlockVector::begin\n+ConstIterator begin() const\n+begin ConstIterator\n+Definition: vbvector.hh:687\n+Dune::VariableBlockVector::value_type\n+BlockVector< B, A > value_type\n+Type of the elements of the outer vector, i.e., dynamic vectors of B.\n+Definition: vbvector.hh:80\n+Dune::VariableBlockVector::end\n+ConstIterator end() const\n+end ConstIterator\n+Definition: vbvector.hh:693\n+Dune::VariableBlockVector::block_type\n+BlockVector< B, A > block_type\n+Same as value_type, here for historical reasons.\n+Definition: vbvector.hh:84\n+Dune::VariableBlockVector::resize\n+void resize(size_type _nblocks, size_type m)\n+same effect as constructor with same argument\n+Definition: vbvector.hh:270\n+Dune::VariableBlockVector::reference\n+window_type & reference\n+Export type used for references to container entries.\n+Definition: vbvector.hh:64\n+Dune::VariableBlockVector::resize\n+void resize(size_type _nblocks)\n+same effect as constructor with same argument\n+Definition: vbvector.hh:234\n+Dune::VariableBlockVector::beforeEnd\n+Iterator beforeEnd()\n+Definition: vbvector.hh:665\n+Dune::VariableBlockVector::begin\n+Iterator begin()\n+begin Iterator\n+Definition: vbvector.hh:652\n+Dune::VariableBlockVector::CreateIterator\n+Iterator class for sequential creation of blocks.\n+Definition: vbvector.hh:443\n+Dune::VariableBlockVector::CreateIterator::operator==\n+bool operator==(const CreateIterator &it) const\n+equality\n+Definition: vbvector.hh:505\n+Dune::VariableBlockVector::CreateIterator::index\n+size_type index() const\n+dereferencing\n+Definition: vbvector.hh:511\n+Dune::VariableBlockVector::CreateIterator::reference\n+SizeProxy reference\n+reference type\n+Definition: vbvector.hh:463\n+Dune::VariableBlockVector::CreateIterator::pointer\n+size_type * pointer\n+pointer type\n+Definition: vbvector.hh:460\n+Dune::VariableBlockVector::CreateIterator::operator!=\n+bool operator!=(const CreateIterator &it) const\n+inequality\n+Definition: vbvector.hh:499\n+Dune::VariableBlockVector::CreateIterator::~CreateIterator\n+~CreateIterator()\n+Definition: vbvector.hh:471\n+Dune::VariableBlockVector::CreateIterator::value_type\n+size_type value_type\n+value type\n+Definition: vbvector.hh:449\n+Dune::VariableBlockVector::CreateIterator::CreateIterator\n+CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)\n+constructor\n+Definition: vbvector.hh:466\n+Dune::VariableBlockVector::CreateIterator::setblocksize\n+void setblocksize(size_type _k)\n+set size of current block\n+Definition: vbvector.hh:517\n+Dune::VariableBlockVector::CreateIterator::operator*\n+size_type & operator*()\n+Access size of current block.\n+Definition: vbvector.hh:528\n+Dune::VariableBlockVector::CreateIterator::iterator_category\n+std::output_iterator_tag iterator_category\n+iterator category\n+Definition: vbvector.hh:446\n+Dune::VariableBlockVector::CreateIterator::operator++\n+CreateIterator & operator++()\n+prefix increment\n+Definition: vbvector.hh:482\n+Dune::VariableBlockVector::CreateIterator::difference_type\n+void difference_type\n+difference type (unused)\n+Definition: vbvector.hh:457\n+Dune::VariableBlockVector::RealIterator\n+Iterator class for sequential access.\n+Definition: vbvector.hh:584\n+Dune::VariableBlockVector::RealIterator::RealIterator\n+RealIterator(window_type *_p, size_type _i)\n+constructor\n+Definition: vbvector.hh:594\n+Dune::VariableBlockVector::RealIterator::equals\n+bool equals(const RealIterator &it) const\n+equality\n+Definition: vbvector.hh:611\n+Dune::VariableBlockVector::RealIterator::index\n+size_type index() const\n+Return the index of the entry this iterator is pointing to.\n+Definition: vbvector.hh:639\n+Dune::VariableBlockVector::RealIterator::elementAt\n+window_type & elementAt(std::ptrdiff_t offset) const\n+Definition: vbvector.hh:633\n+Dune::VariableBlockVector::RealIterator::decrement\n+void decrement()\n+prefix decrement\n+Definition: vbvector.hh:605\n+Dune::VariableBlockVector::RealIterator::advance\n+void advance(std::ptrdiff_t d)\n+Definition: vbvector.hh:622\n+Dune::VariableBlockVector::RealIterator::increment\n+void increment()\n+prefix increment\n+Definition: vbvector.hh:599\n+Dune::VariableBlockVector::RealIterator::RealIterator\n+RealIterator()\n+constructor, no arguments\n+Definition: vbvector.hh:587\n+Dune::VariableBlockVector::RealIterator::distanceTo\n+std::ptrdiff_t distanceTo(const RealIterator &o) const\n+Definition: vbvector.hh:627\n+Dune::VariableBlockVector::RealIterator::dereference\n+window_type & dereference() const\n+dereferencing\n+Definition: vbvector.hh:617\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00014.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00014.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: spqr.hh File Reference\n+dune-istl: bdmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -64,65 +64,45 @@\n \n
\n \n \n+
bdmatrix.hh File Reference
\n \n
\n \n-

Class for using SPQR with ISTL matrices. \n+

Implementation of the BDMatrix class. \n More...

\n-
#include <complex>
\n-#include <type_traits>
\n-#include <SuiteSparseQR.hpp>
\n-#include <dune/common/exceptions.hh>
\n-#include <dune/istl/bccsmatrixinitializer.hh>
\n-#include <dune/istl/solvers.hh>
\n-#include <dune/istl/solvertype.hh>
\n-#include <dune/istl/solverfactory.hh>
\n+
#include <memory>
\n+#include <dune/common/rangeutilities.hh>
\n+#include <dune/common/scalarmatrixview.hh>
\n+#include <dune/istl/bcrsmatrix.hh>
\n+#include <dune/istl/blocklevel.hh>
\n
\n

Go to the source code of this file.

\n \n \n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

\n Classes

class  Dune::SPQR< Matrix >
 Use the SPQR package to directly solve linear systems – empty default class. More...
class  Dune::BDMatrix< B, A >
 A block-diagonal matrix. More...
 
class  Dune::SPQR< BCRSMatrix< FieldMatrix< T, n, m >, A > >
 The SPQR direct sparse solver for matrices of type BCRSMatrix. More...
 
struct  Dune::IsDirectSolver< SPQR< BCRSMatrix< T, A > > >
 
struct  Dune::StoresColumnCompressed< SPQR< BCRSMatrix< T, A > > >
 
struct  Dune::SPQRCreator
 
struct  Dune::SPQRCreator::isValidBlock< class >
 
struct  Dune::SPQRCreator::isValidBlock< FieldVector< double, 1 > >
struct  Dune::FieldTraits< BDMatrix< B, A > >
 
\n \n \n \n-

\n Namespaces

namespace  Dune
 
\n-\n-\n-\n

\n-Functions

 Dune::DUNE_REGISTER_DIRECT_SOLVER ("spqr", Dune::SPQRCreator())
 
\n

Detailed Description

\n-

Class for using SPQR with ISTL matrices.

\n-
Author
Marco Agnese, Andrea Sacconi
\n+

Implementation of the BDMatrix class.

\n+
Author
Oliver Sander
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,58 +4,32 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-spqr.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL)\n-Class for using SPQR with ISTL matrices. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+bdmatrix.hh File Reference\n+Implementation of the BDMatrix class. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class\n- \u00a0Dune::SPQR<_Matrix_>\n-\u00a0 Use the SPQR package to directly solve linear systems \u2013 empty default class.\n- More...\n+ class \u00a0Dune::BDMatrix<_B,_A_>\n+\u00a0 A block-diagonal matrix. More...\n \u00a0\n- class\n- \u00a0Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n-\u00a0 The SPQR direct sparse solver for matrices of type BCRSMatrix. More...\n-\u00a0\n-struct\n- \u00a0Dune::IsDirectSolver<_SPQR<_BCRSMatrix<_T,_A_>_>_>\n-\u00a0\n-struct\n- \u00a0Dune::StoresColumnCompressed<_SPQR<_BCRSMatrix<_T,_A_>_>_>\n-\u00a0\n-struct\n- \u00a0Dune::SPQRCreator\n-\u00a0\n-struct\n- \u00a0Dune::SPQRCreator::isValidBlock<_class_>\n-\u00a0\n-struct\n- \u00a0Dune::SPQRCreator::isValidBlock<_FieldVector<_double,_1_>_>\n+struct \u00a0Dune::FieldTraits<_BDMatrix<_B,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"spqr\", Dune::SPQRCreator())\n-\u00a0\n ***** Detailed Description *****\n-Class for using SPQR with ISTL matrices.\n+Implementation of the BDMatrix class.\n Author\n- Marco Agnese, Andrea Sacconi\n+ Oliver Sander\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00014_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00014_source.html", "has_internal_linenos": true, "unified_diff": "@@ -21,4455 +21,2228 @@\n 00000140: 6f6e 7465 6e74 3d22 446f 7879 6765 6e20 ontent=\"Doxygen \n 00000150: 312e 392e 3422 2f3e 0a3c 6d65 7461 206e 1.9.4\"/>..<\n 000001a0: 7469 746c 653e 6475 6e65 2d69 7374 6c3a title>dune-istl:\n-000001b0: 2073 7071 722e 6868 2053 6f75 7263 6520 spqr.hh Source \n-000001c0: 4669 6c65 3c2f 7469 746c 653e 0a3c 6c69 File...<\n-00000240: 7363 7269 7074 2074 7970 653d 2274 6578 script type=\"tex\n-00000250: 742f 6a61 7661 7363 7269 7074 2220 7372 t/javascript\" sr\n-00000260: 633d 2264 796e 7365 6374 696f 6e73 2e6a c=\"dynsections.j\n-00000270: 7322 3e3c 2f73 6372 6970 743e 0a3c 6c69 s\">..<\n-000002c0: 7363 7269 7074 2074 7970 653d 2274 6578 script type=\"tex\n-000002d0: 742f 6a61 7661 7363 7269 7074 2220 7372 t/javascript\" sr\n-000002e0: 633d 2273 6561 7263 682f 7365 6172 6368 c=\"search/search\n-000002f0: 6461 7461 2e6a 7322 3e3c 2f73 6372 6970 data.js\">..<\n-000005f0: 7363 7269 7074 2074 7970 653d 2274 6578 script type=\"tex\n-00000600: 742f 6a61 7661 7363 7269 7074 2220 7372 t/javascript\" sr\n-00000610: 633d 226d 656e 7564 6174 612e 6a73 223e c=\"menudata.js\">\n-00000620: 3c2f 7363 7269 7074 3e0a 3c73 6372 6970 .\n-00000660: 0a3c 7363 7269 7074 2074 7970 653d 2274 .\n+00000280: 0a3c 6c69 6e6b 2068 7265 663d 2273 6561 .....
..\n+000007c0: 3c64 6976 2069 643d 224d 5365 6172 6368
....
.
bdmatri\n+00000ac0: 782e 6868 3c2f 6469 763e 3c2f 6469 763e x.hh
\n+00000ad0: 0a3c 2f64 6976 3e3c 212d 2d68 6561 6465 .
.
.Go to the docu\n+00000b20: 6d65 6e74 6174 696f 6e20 6f66 2074 6869 mentation of thi\n+00000b30: 7320 6669 6c65 2e3c 2f61 3e3c 6469 7620 s file.
\n+00000b80: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 1// SP\n+00000bc0: 4458 2d46 696c 6543 6f70 7972 6967 6874 DX-FileCopyright\n+00000bd0: 5465 7874 3a20 436f 7079 7269 6768 7420 Text: Copyright \n+00000be0: 2843 2920 4455 4e45 2050 726f 6a65 6374 (C) DUNE Project\n+00000bf0: 2063 6f6e 7472 6962 7574 6f72 732c 2073 contributors, s\n+00000c00: 6565 2066 696c 6520 4c49 4345 4e53 452e ee file LICENSE.\n+00000c10: 6d64 2069 6e20 6d6f 6475 6c65 2072 6f6f md in module roo\n+00000c20: 743c 2f73 7061 6e3e 3c2f 6469 763e 0a3c t
.<\n+00000c30: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00000c40: 3e3c 6120 6964 3d22 6c30 3030 3032 2220 > 2// SPDX\n+00000ca0: 2d4c 6963 656e 7365 2d49 6465 6e74 6966 -License-Identif\n+00000cb0: 6965 723a 204c 6963 656e 7365 5265 662d ier: LicenseRef-\n+00000cc0: 4750 4c2d 322e 302d 6f6e 6c79 2d77 6974 GPL-2.0-only-wit\n+00000cd0: 682d 4455 4e45 2d65 7863 6570 7469 6f6e h-DUNE-exception\n+00000ce0: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
.\n+00000d00: 3c61 2069 643d 226c 3030 3030 3322 206e 3// -*- t\n+00000d60: 6162 2d77 6964 7468 3a20 343b 2069 6e64 ab-width: 4; ind\n+00000d70: 656e 742d 7461 6273 2d6d 6f64 653a 206e ent-tabs-mode: n\n+00000d80: 696c 3b20 632d 6261 7369 632d 6f66 6673 il; c-basic-offs\n+00000d90: 6574 3a20 3220 2d2a 2d3c 2f73 7061 6e3e et: 2 -*-\n+00000da0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00000df0: 2020 2034 3c2f 7370 616e 3e3c 7370 616e 4// vi: set et t\n+00000e20: 733d 3420 7377 3d32 2073 7473 3d32 3a3c s=4 sw=2 sts=2:<\n+00000e30: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
.<\n+00000e50: 6120 6964 3d22 6c30 3030 3035 2220 6e61 a id=\"l00005\" na\n+00000e60: 6d65 3d22 6c30 3030 3035 223e 3c2f 613e me=\"l00005\">\n+00000e70: 3c73 7061 6e20 636c 6173 733d 226c 696e 5#ifn\n+00000eb0: 6465 6620 4455 4e45 5f49 5354 4c5f 4244 def DUNE_ISTL_BD\n+00000ec0: 4d41 5452 4958 5f48 483c 2f73 7061 6e3e MATRIX_HH\n+00000ed0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00000f20: 2020 2036 3c2f 7370 616e 3e3c 7370 616e 6#define DU\n+00000f50: 4e45 5f49 5354 4c5f 4244 4d41 5452 4958 NE_ISTL_BDMATRIX\n+00000f60: 5f48 483c 2f73 7061 6e3e 3c2f 6469 763e _HH
\n+00000f70: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00000fe0: 6120 6964 3d22 6c30 3030 3038 2220 6e61 a id=\"l00008\" na\n+00000ff0: 6d65 3d22 6c30 3030 3038 223e 3c2f 613e me=\"l00008\">\n+00001000: 3c73 7061 6e20 636c 6173 733d 226c 696e 8#inc\n+00001040: 6c75 6465 2026 6c74 3b6d 656d 6f72 7926 lude <memory&\n+00001050: 6774 3b3c 2f73 7061 6e3e 3c2f 6469 763e gt;
\n+00001060: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+000010d0: 6120 6964 3d22 6c30 3030 3130 2220 6e61 a id=\"l00010\" na\n+000010e0: 6d65 3d22 6c30 3030 3130 223e 3c2f 613e me=\"l00010\">\n+000010f0: 3c73 7061 6e20 636c 6173 733d 226c 696e 10#inc\n+00001130: 6c75 6465 2026 6c74 3b64 756e 652f 636f lude <dune/co\n+00001140: 6d6d 6f6e 2f72 616e 6765 7574 696c 6974 mmon/rangeutilit\n+00001150: 6965 732e 6868 2667 743b 3c2f 7370 616e ies.hh>
.
\n+000011b0: 2020 2031 313c 2f73 7061 6e3e 3c73 7061 11#include \n+000011e0: 266c 743b 6475 6e65 2f63 6f6d 6d6f 6e2f <dune/common/\n+000011f0: 7363 616c 6172 6d61 7472 6978 7669 6577 scalarmatrixview\n+00001200: 2e68 6826 6774 3b3c 2f73 7061 6e3e 3c2f .hh>.
\n+00001260: 3132 3c2f 7370 616e 3e20 3c2f 6469 763e 12
\n+00001270: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n+000012a0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 13\n+000012e0: 2369 6e63 6c75 6465 2026 6c74 3b3c 6120 #include <\n+00001310: 6475 6e65 2f69 7374 6c2f 6263 7273 6d61 dune/istl/bcrsma\n+00001320: 7472 6978 2e68 683c 2f61 3e26 6774 3b3c trix.hh><\n+00001330: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
.<\n+00001350: 6120 6964 3d22 6c30 3030 3134 2220 6e61 a id=\"l00014\" na\n+00001360: 6d65 3d22 6c30 3030 3134 223e 3c2f 613e me=\"l00014\">\n+00001370: 3c73 7061 6e20 636c 6173 733d 226c 696e 14#inc\n+000013b0: 6c75 6465 2026 6c74 3b3c 6120 636c 6173 lude <dune\n+000013e0: 2f69 7374 6c2f 626c 6f63 6b6c 6576 656c /istl/blocklevel\n+000013f0: 2e68 683c 2f61 3e26 6774 3b3c 2f73 7061 .hh>
.
15 .
\n+000014b0: 3231 3c2f 7370 616e 3e3c 7370 616e 2063 21n\n+000014d0: 616d 6573 7061 6365 203c 2f73 7061 6e3e amespace \n+000014e0: 3c61 2063 6c61 7373 3d22 636f 6465 2068 \n+00001510: 4475 6e65 3c2f 613e 207b 3c2f 6469 763e Dune {
\n 00001520: 0a3c 6469 7620 636c 6173 733d 226c 696e ..
19#includ\n-00001660: 6520 266c 743b 3c61 2063 6c61 7373 3d22 e <dune/is\n-00001690: 746c 2f73 6f6c 7665 7274 7970 652e 6868 tl/solvertype.hh\n-000016a0: 3c2f 613e 2667 743b 3c2f 7370 616e 3e3c ><\n-000016b0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00001700: 2032 303c 2f73 7061 6e3e 3c73 7061 6e20 20#include &l\n-00001730: 743b 3c61 2063 6c61 7373 3d22 636f 6465 t;dune/istl/s\n-00001760: 6f6c 7665 7266 6163 746f 7279 2e68 683c olverfactory.hh<\n-00001770: 2f61 3e26 6774 3b3c 2f73 7061 6e3e 3c2f /a>>.
\n-000017d0: 3231 3c2f 7370 616e 3e20 3c2f 6469 763e 21
\n-000017e0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-000018b0: 6120 6964 3d22 6c30 3030 3334 2220 6e61 a id=\"l00034\" na\n-000018c0: 6d65 3d22 6c30 3030 3334 223e 3c2f 613e me=\"l00034\">\n-000018d0: 3c73 7061 6e20 636c 6173 733d 226c 696e 34 // forw\n-00001910: 6172 6420 6465 636c 6172 6174 696f 6e73 ard declarations\n-00001920: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
.\n-00001940: 3c61 2069 643d 226c 3030 3033 3522 206e 35 templa\n-000019a0: 7465 3c2f 7370 616e 3e26 6c74 3b3c 7370 te<class \n-000019d0: 4d2c 203c 7370 616e 2063 6c61 7373 3d22 M, class T, c\n-00001a10: 6c61 7373 3c2f 7370 616e 3e20 544d 2c20 lass TM, \n-00001a20: 3c73 7061 6e20 636c 6173 733d 226b 6579 class TD, cla\n-00001a60: 7373 3c2f 7370 616e 3e20 5441 2667 743b ss TA>\n-00001a70: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00001ac0: 2020 3336 3c2f 7370 616e 3e20 203c 7370 36 class \n-00001af0: 5365 714f 7665 726c 6170 7069 6e67 5363 SeqOverlappingSc\n-00001b00: 6877 6172 7a3b 3c2f 6469 763e 0a3c 6469 hwarz;
.<\n-00001b20: 6120 6964 3d22 6c30 3030 3337 2220 6e61 a id=\"l00037\" na\n-00001b30: 6d65 3d22 6c30 3030 3337 223e 3c2f 613e me=\"l00037\">\n-00001b40: 3c73 7061 6e20 636c 6173 733d 226c 696e 37
.
38 <\n-00001bc0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00001bd0: 6f72 6422 3e74 656d 706c 6174 653c 2f73 ord\">template<cl\n-00001c00: 6173 733c 2f73 7061 6e3e 2054 2c20 3c73 ass T, bool tag>.
39<\n-00001c90: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> st\n-00001cb0: 7275 6374 203c 2f73 7061 6e3e 5365 714f ruct SeqO\n-00001cc0: 7665 726c 6170 7069 6e67 5363 6877 6172 verlappingSchwar\n-00001cd0: 7a41 7373 656d 626c 6572 4865 6c70 6572 zAssemblerHelper\n-00001ce0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-00001d30: 2020 2034 303c 2f73 7061 6e3e 203c 2f64 40 .
4\n-00001d90: 363c 2f73 7061 6e3e 2020 3c73 7061 6e20 6 \n-00001db0: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-00001dc0: 6c74 3b3c 7370 616e 2063 6c61 7373 3d22 lt;class Matrix>\n-00001df0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n-00001e40: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-00001e50: 7265 663d 2261 3032 3830 382e 6874 6d6c ref=\"a02808.html\n-00001e60: 223e 2020 2034 373c 2f61 3e3c 2f73 7061 \"> 47 class \n-00001e90: 3c2f 7370 616e 3e3c 6120 636c 6173 733d SPQR..
\n-00002100: 3c61 2063 6c61 7373 3d22 6c69 6e65 2220 64 class\n-00002150: 203c 2f73 7061 6e3e 3c61 2063 6c61 7373 SPQR<\n-00002190: 3c61 2063 6c61 7373 3d22 636f 6465 2068 BCRS\n-000021c0: 4d61 7472 6978 3c2f 613e 266c 743b 3c61 Matrix<FieldM\n-00002200: 6174 7269 783c 2f61 3e26 6c74 3b54 2c6e atrix<T,n\n-00002210: 2c6d 2667 743b 2c41 2026 6774 3b20 2667 ,m>,A > &g\n-00002220: 743b 3c2f 6469 763e 0a3c 6469 7620 636c t;
.
65 \n-00002280: 203a 203c 7370 616e 2063 6c61 7373 3d22 : public<\n-000022a0: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> InverseOperat\n-000022e0: 6f72 3c2f 613e 266c 743b 426c 6f63 6b56 or<BlockV\n-000022f0: 6563 746f 7226 6c74 3b46 6965 6c64 5665 ector<FieldVe\n-00002300: 6374 6f72 266c 743b 542c 6d26 6774 3b2c ctor<T,m>,\n-00002310: 2074 7970 656e 616d 6520 7374 643a 3a61 typename std::a\n-00002320: 6c6c 6f63 6174 6f72 5f74 7261 6974 7326 llocator_traits&\n-00002330: 6c74 3b41 2667 743b 3a3a 7465 6d70 6c61 lt;A>::templa\n-00002340: 7465 2072 6562 696e 645f 616c 6c6f 6326 te rebind_alloc&\n-00002350: 6c74 3b46 6965 6c64 5665 6374 6f72 266c lt;FieldVector&l\n-00002360: 743b 542c 6d26 6774 3b20 2667 743b 2026 t;T,m> > &\n-00002370: 6774 3b2c 3c2f 6469 763e 0a3c 6469 7620 gt;,
.
66 \n-000023d0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-000023e0: 2020 2020 2020 2020 2020 2020 426c 6f63 Bloc\n-000023f0: 6b56 6563 746f 7226 6c74 3b46 6965 6c64 kVector<Field\n-00002400: 5665 6374 6f72 266c 743b 542c 6e26 6774 Vector<T,n>\n-00002410: 3b2c 2074 7970 656e 616d 6520 7374 643a ;, typename std:\n-00002420: 3a61 6c6c 6f63 6174 6f72 5f74 7261 6974 :allocator_trait\n-00002430: 7326 6c74 3b41 2667 743b 3a3a 7465 6d70 s<A>::temp\n-00002440: 6c61 7465 2072 6562 696e 645f 616c 6c6f late rebind_allo\n-00002450: 6326 6c74 3b46 6965 6c64 5665 6374 6f72 c<FieldVector\n-00002460: 266c 743b 542c 6e26 6774 3b20 2667 743b <T,n> >\n-00002470: 2026 6774 3b20 2667 743b 3c2f 6469 763e > >
\n-00002480: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-000024e0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000024f0: 3e3c 6120 6964 3d22 6c30 3030 3638 2220 > 68 pub\n-00002550: 6c69 633c 2f73 7061 6e3e 3a3c 2f64 6976 lic:...
<\n-00002880: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-00002890: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n-000028a0: 2367 6137 6463 3833 6137 3131 3066 3731 #ga7dc83a7110f71\n-000028b0: 3466 3862 3566 3333 3766 3863 6337 3734 4f8b5f337f8cc774\n-000028c0: 6236 3222 3e20 2020 3733 3c2f 613e 3c2f b62\"> 73 t\n-000028f0: 7970 6564 6566 3c2f 7370 616e 3e20 4953 ypedef IS\n-00002900: 544c 3a3a 496d 706c 3a3a 4243 4353 4d61 TL::Impl::BCCSMa\n-00002910: 7472 6978 266c 743b 542c 696e 7426 6774 trix<T,int>\n-00002920: 3b20 3c61 2063 6c61 7373 3d22 636f 6465 ; SPQRMatrix;
.
75\n-00002a20: 3c2f 7370 616e 3e20 2020 203c 7370 616e typedef \n-00002a50: 4953 544c 3a3a 496d 706c 3a3a 4243 4353 ISTL::Impl::BCCS\n-00002a60: 4d61 7472 6978 496e 6974 6961 6c69 7a65 MatrixInitialize\n-00002a70: 7226 6c74 3b42 4352 534d 6174 7269 7826 r<BCRSMatrix&\n-00002a80: 6c74 3b46 6965 6c64 4d61 7472 6978 266c lt;FieldMatrix&l\n-00002a90: 743b 542c 6e2c 6d26 6774 3b2c 4126 6774 t;T,n,m>,A>\n-00002aa0: 3b2c 203c 7370 616e 2063 6c61 7373 3d22 ;, int\n-00002ac0: 3c2f 7370 616e 3e26 6774 3b20 3c61 2063 > Mat\n-00002b20: 7269 7849 6e69 7469 616c 697a 6572 3c2f rixInitializer;
.
77 typedef\n-00002c00: 203c 6120 636c 6173 733d 2263 6f64 6520 Dun\n-00002c30: 653a 3a42 6c6f 636b 5665 6374 6f72 266c e::BlockVector&l\n-00002c40: 743b 4669 656c 6456 6563 746f 7226 6c74 t;FieldVector<\n-00002c50: 3b54 2c6d 2667 743b 3c2f 613e 2c20 3c73 ;T,m>, typename std::allocat\n-00002c90: 6f72 5f74 7261 6974 7326 6c74 3b41 2667 or_traits<A&g\n-00002ca0: 743b 3a3a 7465 6d70 6c61 7465 2072 6562 t;::template reb\n-00002cb0: 696e 645f 616c 6c6f 6326 6c74 3b46 6965 ind_alloc<Fie\n-00002cc0: 6c64 5665 6374 6f72 266c 743b 542c 6d26 ldVector<T,m&\n-00002cd0: 6774 3b20 2667 743b 2026 6774 3b20 3c61 gt; > > d\n-00002d30: 6f6d 6169 6e5f 7479 7065 3c2f 613e 3b3c omain_type;<\n-00002d40: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
79 ty\n-00002e00: 7065 6465 663c 2f73 7061 6e3e 203c 6120 pedef Dune::B\n-00002e40: 6c6f 636b 5665 6374 6f72 266c 743b 4669 lockVector<Fi\n-00002e50: 656c 6456 6563 746f 7226 6c74 3b54 2c6e eldVector<T,n\n-00002e60: 2667 743b 3c2f 613e 2c20 3c73 7061 6e20 >, \n-00002e80: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n-00002e90: 7374 643a 3a61 6c6c 6f63 6174 6f72 5f74 std::allocator_t\n-00002ea0: 7261 6974 7326 6c74 3b41 2667 743b 3a3a raits<A>::\n-00002eb0: 7465 6d70 6c61 7465 2072 6562 696e 645f template rebind_\n-00002ec0: 616c 6c6f 6326 6c74 3b46 6965 6c64 5665 alloc<FieldVe\n-00002ed0: 6374 6f72 266c 743b 542c 6e26 6774 3b20 ctor<T,n> \n-00002ee0: 2667 743b 2026 6774 3b20 3c61 2063 6c61 > > range\n-00002f40: 5f74 7970 653c 2f61 3e3b 3c2f 6469 763e _type;
\n-00002f50: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00002fc0: 6120 6964 3d22 6c30 3030 3832 2220 6e61 a id=\"l00082\" na\n-00002fd0: 6d65 3d22 6c30 3030 3832 223e 3c2f 613e me=\"l00082\">\n-00002fe0: 3c73 7061 6e20 636c 6173 733d 226c 696e 82\n-00003040: 3c2f 613e 3c2f 7370 616e 3e20 2020 203c <\n-00003050: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00003060: 6f72 6422 3e76 6972 7475 616c 3c2f 7370 ord\">virtual SolverCa\n-000030d0: 7465 676f 7279 3a3a 4361 7465 676f 7279 tegory::Category\n-000030e0: 3c2f 613e 203c 6120 636c 6173 733d 2263 category<\n-00003140: 2f61 3e28 293c 7370 616e 2063 6c61 7373 /a>() cons\n-00003160: 743c 2f73 7061 6e3e 3c2f 6469 763e 0a3c t
.<\n-00003170: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00003180: 3e3c 6120 6964 3d22 6c30 3030 3833 2220 > 83 {
.<\n-00003220: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00003230: 6e6f 223e 2020 2038 343c 2f73 7061 6e3e no\"> 84\n-00003240: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-00003260: 7265 7475 726e 3c2f 7370 616e 3e20 536f return So\n-00003270: 6c76 6572 4361 7465 676f 7279 3a3a 4361 lverCategory::Ca\n-00003280: 7465 676f 7279 3a3a 7365 7175 656e 7469 tegory::sequenti\n-00003290: 616c 3b3c 2f64 6976 3e0a 3c64 6976 2063 al;
.
85 \n-000032f0: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
.
86 <\n-00003350: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
95 SPQR(const Matrix&\n-000034b0: 3b20 6d61 7472 6978 2c20 3c73 7061 6e20 ; matrix, int v\n-000034e0: 6572 626f 7365 3d30 2920 3a20 6d61 7472 erbose=0) : matr\n-000034f0: 6978 4973 4c6f 6164 6564 5f28 6661 6c73 ixIsLoaded_(fals\n-00003500: 6529 2c20 7665 7262 6f73 655f 2876 6572 e), verbose_(ver\n-00003510: 626f 7365 293c 2f64 6976 3e0a 3c64 6976 bose)
.<\n-00003550: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00003560: 6e6f 223e 2020 2039 363c 2f73 7061 6e3e no\"> 96\n-00003570: 2020 2020 7b3c 2f64 6976 3e0a 3c64 6976 {
.<\n-000035b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000035c0: 6e6f 223e 2020 2039 373c 2f73 7061 6e3e no\"> 97\n-000035d0: 2020 2020 2020 3c73 7061 6e20 636c 6173 //ch\n-000035f0: 6563 6b20 7768 6574 6865 7220 5420 6973 eck whether T is\n-00003600: 2061 2073 7570 706f 7274 6564 2074 7970 a supported typ\n-00003610: 653c 2f73 7061 6e3e 3c2f 6469 763e 0a3c e
.<\n-00003620: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00003630: 3e3c 6120 6964 3d22 6c30 3030 3938 2220 > 98 s\n-00003690: 7461 7469 635f 6173 7365 7274 3c2f 7370 tatic_assert((std::is_sam\n-000036b0: 6526 6c74 3b54 2c64 6f75 626c 6526 6774 e<T,double>\n-000036c0: 3b3a 3a76 616c 7565 2920 7c7c 2028 7374 ;::value) || (st\n-000036d0: 643a 3a69 735f 7361 6d65 266c 743b 542c d::is_same<T,\n-000036e0: 7374 643a 3a63 6f6d 706c 6578 266c 743b std::complex<\n-000036f0: 646f 7562 6c65 2667 743b 2026 6774 3b3a double> >:\n-00003700: 3a76 616c 7565 292c 3c2f 6469 763e 0a3c :value),.<\n-00003710: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00003720: 3e3c 6120 6964 3d22 6c30 3030 3939 2220 > 99 \n-00003770: 2020 2020 2020 203c 7370 616e 2063 6c61 "Unsuppo\n-000037a0: 7274 6564 2054 7970 6520 696e 2053 5051 rted Type in SPQ\n-000037b0: 5220 286f 6e6c 7920 646f 7562 6c65 2061 R (only double a\n-000037c0: 6e64 2073 7464 3a3a 636f 6d70 6c65 7826 nd std::complex&\n-000037d0: 6c74 3b64 6f75 626c 6526 6774 3b20 7375 lt;double> su\n-000037e0: 7070 6f72 7465 6429 2671 756f 743b 3c2f pported)");.\n-00003810: 3c61 2069 643d 226c 3030 3130 3022 206e 100 cc_ = new c\n-00003880: 686f 6c6d 6f64 5f63 6f6d 6d6f 6e28 293b holmod_common();\n-00003890: 3c2f 6469 763e 0a3c 6469 7620 636c 6173 .
\n-000038e0: 2031 3031 3c2f 7370 616e 3e20 2020 2020 101 \n-000038f0: 2063 686f 6c6d 6f64 5f6c 5f73 7461 7274 cholmod_l_start\n-00003900: 2863 635f 293b 3c2f 6469 763e 0a3c 6469 (cc_);
.<\n-00003920: 6120 6964 3d22 6c30 3031 3032 2220 6e61 a id=\"l00102\" na\n-00003930: 6d65 3d22 6c30 3031 3032 223e 3c2f 613e me=\"l00102\">\n-00003940: 3c73 7061 6e20 636c 6173 733d 226c 696e 102 setMatrix\n-00003970: 286d 6174 7269 7829 3b3c 2f64 6976 3e0a (matrix);.\n-00003980: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-000039e0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00003a70: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00003a80: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 113<\n-00003ad0: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c61 /a> \n-00003b30: 5350 5152 3c2f 613e 283c 7370 616e 2063 SPQR(c\n-00003b50: 6f6e 7374 3c2f 7370 616e 3e20 3c61 2063 onst Matrix& matrix, \n-00003ba0: 3c73 7061 6e20 636c 6173 733d 226b 6579 int verbose, bool) : matrixIsL\n-00003c00: 6f61 6465 645f 2866 616c 7365 292c 2076 oaded_(false), v\n-00003c10: 6572 626f 7365 5f28 7665 7262 6f73 6529 erbose_(verbose)\n-00003c20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173 .
\n-00003c70: 2031 3134 3c2f 7370 616e 3e20 2020 207b 114 {\n-00003c80: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00003cd0: 2031 3135 3c2f 7370 616e 3e20 2020 2020 115 \n-00003ce0: 203c 7370 616e 2063 6c61 7373 3d22 636f //check w\n-00003d00: 6865 7468 6572 2054 2069 7320 6120 7375 hether T is a su\n-00003d10: 7070 6f72 7465 6420 7479 7065 3c2f 7370 pported type
.
116 \n-00003d80: 2020 2020 3c73 7061 6e20 636c 6173 733d static\n-00003da0: 5f61 7373 6572 743c 2f73 7061 6e3e 2828 _assert((\n-00003db0: 7374 643a 3a69 735f 7361 6d65 266c 743b std::is_same<\n-00003dc0: 542c 646f 7562 6c65 2667 743b 3a3a 7661 T,double>::va\n-00003dd0: 6c75 6529 207c 7c20 2873 7464 3a3a 6973 lue) || (std::is\n-00003de0: 5f73 616d 6526 6c74 3b54 2c73 7464 3a3a _same<T,std::\n-00003df0: 636f 6d70 6c65 7826 6c74 3b64 6f75 626c complex<doubl\n-00003e00: 6526 6774 3b20 2667 743b 3a3a 7661 6c75 e> >::valu\n-00003e10: 6529 2c3c 2f64 6976 3e0a 3c64 6976 2063 e),
.
117 \n-00003e70: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00003e80: 2020 3c73 7061 6e20 636c 6173 733d 2273 &q\n-00003ea0: 756f 743b 556e 7375 7070 6f72 7465 6420 uot;Unsupported \n-00003eb0: 5479 7065 2069 6e20 5350 5152 2028 6f6e Type in SPQR (on\n-00003ec0: 6c79 2064 6f75 626c 6520 616e 6420 7374 ly double and st\n-00003ed0: 643a 3a63 6f6d 706c 6578 266c 743b 646f d::complex<do\n-00003ee0: 7562 6c65 2667 743b 2073 7570 706f 7274 uble> support\n-00003ef0: 6564 2926 7175 6f74 3b3c 2f73 7061 6e3e ed)"\n-00003f00: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
.
118 \n-00003f60: 2020 2063 635f 203d 203c 7370 616e 2063 cc_ = n\n-00003f80: 6577 3c2f 7370 616e 3e20 6368 6f6c 6d6f ew cholmo\n-00003f90: 645f 636f 6d6d 6f6e 2829 3b3c 2f64 6976 d_common();.
119<\n-00003ff0: 2f73 7061 6e3e 2020 2020 2020 6368 6f6c /span> chol\n-00004000: 6d6f 645f 6c5f 7374 6172 7428 6363 5f29 mod_l_start(cc_)\n-00004010: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-00004060: 2020 3132 303c 2f73 7061 6e3e 2020 2020 120 \n-00004070: 2020 7365 744d 6174 7269 7828 6d61 7472 setMatrix(matr\n-00004080: 6978 293b 3c2f 6469 763e 0a3c 6469 7620 ix);
.
121 \n-000040e0: 2020 207d 3c2f 6469 763e 0a3c 6469 7620 }
.
122 \n-00004140: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n-00004190: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-000041a0: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n-000041b0: 2367 6162 3962 6664 6435 3531 3334 3765 #gab9bfdd551347e\n-000041c0: 6336 3064 6432 3265 6461 3533 3532 3933 c60dd22eda535293\n-000041d0: 6536 3322 3e20 2031 3332 3c2f 613e 3c2f e63\"> 132 SPQR<\n-00004240: 2f61 3e28 3c73 7061 6e20 636c 6173 733d /a>(const<\n-00004260: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> Matrix&am\n-000042a0: 703b 206d 6174 7269 782c 203c 7370 616e p; matrix, const Pa\n-000042d0: 7261 6d65 7465 7254 7265 6526 616d 703b rameterTree&\n-000042e0: 2063 6f6e 6669 6729 3c2f 6469 763e 0a3c config)
.<\n-000042f0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00004300: 3e3c 6120 6964 3d22 6c30 3031 3333 2220 > 133 : SPQR(\n-00004380: 6d61 7472 6978 2c20 636f 6e66 6967 2e3c matrix, config.<\n-00004390: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-000043a0: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n-000043b0: 2261 3030 3234 392e 6874 6d6c 2361 3334 \"a00249.html#a34\n-000043c0: 6637 3563 3538 6536 3536 3832 3362 3538 f75c58e656823b58\n-000043d0: 6533 6166 3137 6330 3966 6230 3365 223e e3af17c09fb03e\">\n-000043e0: 6765 743c 2f61 3e26 6c74 3b69 6e74 2667 get<int&g\n-000043f0: 743b 283c 7370 616e 2063 6c61 7373 3d22 t;(&\n-00004410: 7175 6f74 3b76 6572 626f 7365 2671 756f quot;verbose&quo\n-00004420: 743b 3c2f 7370 616e 3e2c 2030 2929 3c2f t;, 0)).
1\n-00004480: 3334 3c2f 7370 616e 3e20 2020 207b 7d3c 34 {}<\n-00004490: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000044e0: 3133 353c 2f73 7061 6e3e 203c 2f64 6976 135 .
\n-00004580: 2020 3133 373c 2f61 3e3c 2f73 7061 6e3e 137\n-00004590: 2020 2020 3c61 2063 6c61 7373 3d22 636f SPQR()\n-000045f0: 203a 206d 6174 7269 7849 734c 6f61 6465 : matrixIsLoade\n-00004600: 645f 2866 616c 7365 292c 2076 6572 626f d_(false), verbo\n-00004610: 7365 5f28 3029 3c2f 6469 763e 0a3c 6469 se_(0)
.<\n-00004630: 6120 6964 3d22 6c30 3031 3338 2220 6e61 a id=\"l00138\" na\n-00004640: 6d65 3d22 6c30 3031 3338 223e 3c2f 613e me=\"l00138\">\n-00004650: 3c73 7061 6e20 636c 6173 733d 226c 696e 138 {
.<\n-00004690: 6120 6964 3d22 6c30 3031 3339 2220 6e61 a id=\"l00139\" na\n-000046a0: 6d65 3d22 6c30 3031 3339 223e 3c2f 613e me=\"l00139\">\n-000046b0: 3c73 7061 6e20 636c 6173 733d 226c 696e 139 //c\n-000046f0: 6865 636b 2077 6865 7468 6572 2054 2069 heck whether T i\n-00004700: 7320 6120 7375 7070 6f72 7465 6420 7479 s a supported ty\n-00004710: 7065 3c2f 7370 616e 3e3c 2f64 6976 3e0a pe
.\n-00004720: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-00004810: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00004900: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00004910: 3e3c 6120 6964 3d22 6c30 3031 3432 2220 > 142 cc_ = <\n-00004960: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00004970: 6f72 6422 3e6e 6577 3c2f 7370 616e 3e20 ord\">new \n-00004980: 6368 6f6c 6d6f 645f 636f 6d6d 6f6e 2829 cholmod_common()\n-00004990: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-000049e0: 2020 3134 333c 2f73 7061 6e3e 2020 2020 143 \n-000049f0: 2020 6368 6f6c 6d6f 645f 6c5f 7374 6172 cholmod_l_star\n-00004a00: 7428 6363 5f29 3b3c 2f64 6976 3e0a 3c64 t(cc_);
.\n-00004a20: 3c61 2069 643d 226c 3030 3134 3422 206e 144 }.\n-00004a80: 3c61 2069 643d 226c 3030 3134 3522 206e 145 .
147 virtual\n-00004b90: 203c 6120 636c 6173 733d 2263 6f64 6520 ~SPQR().
1\n-00004c40: 3438 3c2f 7370 616e 3e20 2020 207b 3c2f 48 {.
1\n-00004ca0: 3439 3c2f 7370 616e 3e20 2020 2020 203c 49 <\n-00004cb0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00004cc0: 6f72 6466 6c6f 7722 3e69 663c 2f73 7061 ordflow\">if ((spqrMatrix_\n-00004ce0: 2e4e 2829 202b 2073 7071 724d 6174 7269 .N() + spqrMatri\n-00004cf0: 785f 2e4d 2829 2026 6774 3b20 3029 207c x_.M() > 0) |\n-00004d00: 7c20 6d61 7472 6978 4973 4c6f 6164 6564 | matrixIsLoaded\n-00004d10: 5f29 3c2f 6469 763e 0a3c 6469 7620 636c _)
.
150 \n-00004d70: 2020 2020 2066 7265 6528 293b 3c2f 6469 free();.
151\n-00004dd0: 3c2f 7370 616e 3e20 2020 2020 2063 686f cho\n-00004de0: 6c6d 6f64 5f6c 5f66 696e 6973 6828 6363 lmod_l_finish(cc\n-00004df0: 5f29 3b3c 2f64 6976 3e0a 3c64 6976 2063 _);
.
152 \n-00004e50: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
.
153 <\n-00004eb0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
155 vi\n-00004f70: 7274 7561 6c3c 2f73 7061 6e3e 203c 7370 rtual void apply(<\n-00005000: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00005010: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n-00005020: 3132 3434 2e68 746d 6c22 3e64 6f6d 6169 1244.html\">domai\n-00005030: 6e5f 7479 7065 3c2f 613e 2661 6d70 3b20 n_type& \n-00005040: 782c 203c 6120 636c 6173 733d 2263 6f64 x, r\n-00005070: 616e 6765 5f74 7970 653c 2f61 3e26 616d ange_type&am\n-00005080: 703b 2062 2c20 3c61 2063 6c61 7373 3d22 p; b, InverseOperat\n-000050c0: 6f72 5265 7375 6c74 3c2f 613e 2661 6d70 orResult&\n-000050d0: 3b20 7265 7329 3c2f 6469 763e 0a3c 6469 ; res)
.<\n-000050f0: 6120 6964 3d22 6c30 3031 3536 2220 6e61 a id=\"l00156\" na\n-00005100: 6d65 3d22 6c30 3031 3536 223e 3c2f 613e me=\"l00156\">\n-00005110: 3c73 7061 6e20 636c 6173 733d 226c 696e 156 {
.<\n-00005150: 6120 6964 3d22 6c30 3031 3537 2220 6e61 a id=\"l00157\" na\n-00005160: 6d65 3d22 6c30 3031 3537 223e 3c2f 613e me=\"l00157\">\n-00005170: 3c73 7061 6e20 636c 6173 733d 226c 696e 157 con\n-000051b0: 7374 3c2f 7370 616e 3e20 7374 643a 3a73 st std::s\n-000051c0: 697a 655f 7420 6e75 6d52 6f77 7328 7370 ize_t numRows(sp\n-000051d0: 7172 4d61 7472 6978 5f2e 4e28 2929 3b3c qrMatrix_.N());<\n-000051e0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00005230: 3135 383c 2f73 7061 6e3e 2020 2020 2020 158 \n-00005240: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // fill B<\n-00005260: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
.<\n-00005280: 6120 6964 3d22 6c30 3031 3539 2220 6e61 a id=\"l00159\" na\n-00005290: 6d65 3d22 6c30 3031 3539 223e 3c2f 613e me=\"l00159\">\n-000052a0: 3c73 7061 6e20 636c 6173 733d 226c 696e 159 for(std:\n-000052f0: 3a73 697a 655f 7420 6b20 3d20 303b 206b :size_t k = 0; k\n-00005300: 2021 3d20 6e75 6d52 6f77 732f 6e3b 202b != numRows/n; +\n-00005310: 2b6b 293c 2f64 6976 3e0a 3c64 6976 2063 +k)
.
160 \n-00005370: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-00005390: 666f 723c 2f73 7061 6e3e 2028 3c73 7061 for (int\n-000053c0: 206c 203d 2030 3b20 6c20 266c 743b 206e l = 0; l < n\n-000053d0: 3b20 2b2b 6c29 3c2f 6469 763e 0a3c 6469 ; ++l)
.<\n-000053f0: 6120 6964 3d22 6c30 3031 3631 2220 6e61 a id=\"l00161\" na\n-00005400: 6d65 3d22 6c30 3031 3631 223e 3c2f 613e me=\"l00161\">\n-00005410: 3c73 7061 6e20 636c 6173 733d 226c 696e 161 (static_cast<\n-00005460: 3b3c 2f73 7061 6e3e 542a 3c73 7061 6e20 ;T*\n-00005480: 2667 743b 3c2f 7370 616e 3e28 425f 2d26 >(B_-&\n-00005490: 6774 3b78 2929 5b6e 2a6b 2b6c 5d20 3d20 gt;x))[n*k+l] = \n-000054a0: 625b 6b5d 5b6c 5d3b 3c2f 6469 763e 0a3c b[k][l];
.<\n-000054b0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000054c0: 3e3c 6120 6964 3d22 6c30 3031 3632 2220 > 162
.
163 \n-00005560: 2020 2020 2063 686f 6c6d 6f64 5f64 656e cholmod_den\n-00005570: 7365 2a20 4254 656d 7020 3d20 425f 3b3c se* BTemp = B_;<\n-00005580: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000055d0: 3136 343c 2f73 7061 6e3e 2020 2020 2020 164 \n-000055e0: 425f 203d 2053 7569 7465 5370 6172 7365 B_ = SuiteSparse\n-000055f0: 5152 5f71 6d75 6c74 266c 743b 5426 6774 QR_qmult<T>\n-00005600: 3b28 302c 2073 7071 7266 6163 746f 7269 ;(0, spqrfactori\n-00005610: 7a61 7469 6f6e 5f2c 2042 5f2c 2063 635f zation_, B_, cc_\n-00005620: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
.
165 \n-00005680: 2020 2063 686f 6c6d 6f64 5f64 656e 7365 cholmod_dense\n-00005690: 2a20 5820 3d20 5375 6974 6553 7061 7273 * X = SuiteSpars\n-000056a0: 6551 525f 736f 6c76 6526 6c74 3b54 2667 eQR_solve<T&g\n-000056b0: 743b 2831 2c20 7370 7172 6661 6374 6f72 t;(1, spqrfactor\n-000056c0: 697a 6174 696f 6e5f 2c20 425f 2c20 6363 ization_, B_, cc\n-000056d0: 5f29 3b3c 2f64 6976 3e0a 3c64 6976 2063 _);
.
166 \n-00005730: 2020 2020 6368 6f6c 6d6f 645f 6c5f 6672 cholmod_l_fr\n-00005740: 6565 5f64 656e 7365 2826 616d 703b 4254 ee_dense(&BT\n-00005750: 656d 702c 2063 635f 293b 3c2f 6469 763e emp, cc_);
\n-00005760: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-000057d0: 6120 6964 3d22 6c30 3031 3638 2220 6e61 a id=\"l00168\" na\n-000057e0: 6d65 3d22 6c30 3031 3638 223e 3c2f 613e me=\"l00168\">\n-000057f0: 3c73 7061 6e20 636c 6173 733d 226c 696e 168 con\n-00005830: 7374 3c2f 7370 616e 3e20 7374 643a 3a73 st std::s\n-00005840: 697a 655f 7420 6e75 6d43 6f6c 7328 7370 ize_t numCols(sp\n-00005850: 7172 4d61 7472 6978 5f2e 4d28 2929 3b3c qrMatrix_.M());<\n-00005860: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000058b0: 3136 393c 2f73 7061 6e3e 2020 2020 2020 169 \n-000058c0: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // fill x<\n-000058e0: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
.<\n-00005900: 6120 6964 3d22 6c30 3031 3730 2220 6e61 a id=\"l00170\" na\n-00005910: 6d65 3d22 6c30 3031 3730 223e 3c2f 613e me=\"l00170\">\n-00005920: 3c73 7061 6e20 636c 6173 733d 226c 696e 170 for(std:\n-00005970: 3a73 697a 655f 7420 6b20 3d20 303b 206b :size_t k = 0; k\n-00005980: 2021 3d20 6e75 6d43 6f6c 732f 6d3b 202b != numCols/m; +\n-00005990: 2b6b 293c 2f64 6976 3e0a 3c64 6976 2063 +k)
.
171 \n-000059f0: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-00005a10: 666f 723c 2f73 7061 6e3e 2028 3c73 7061 for (int\n-00005a40: 206c 203d 2030 3b20 6c20 266c 743b 206d l = 0; l < m\n-00005a50: 3b20 2b2b 6c29 3c2f 6469 763e 0a3c 6469 ; ++l)
.<\n-00005a70: 6120 6964 3d22 6c30 3031 3732 2220 6e61 a id=\"l00172\" na\n-00005a80: 6d65 3d22 6c30 3031 3732 223e 3c2f 613e me=\"l00172\">\n-00005a90: 3c73 7061 6e20 636c 6173 733d 226c 696e 172 x[k][\n-00005ac0: 6c5d 203d 2028 3c73 7061 6e20 636c 6173 l] = (stat\n-00005ae0: 6963 5f63 6173 7426 6c74 3b3c 2f73 7061 ic_cast<T*>(X->x))[\n-00005b20: 6d2a 6b2b 6c5d 3b3c 2f64 6976 3e0a 3c64 m*k+l];.\n-00005b40: 3c61 2069 643d 226c 3030 3137 3322 206e 173 .
174 \n-00005be0: 2020 2020 6368 6f6c 6d6f 645f 6c5f 6672 cholmod_l_fr\n-00005bf0: 6565 5f64 656e 7365 2826 616d 703b 582c ee_dense(&X,\n-00005c00: 2063 635f 293b 3c2f 6469 763e 0a3c 6469 cc_);
.<\n-00005c20: 6120 6964 3d22 6c30 3031 3735 2220 6e61 a id=\"l00175\" na\n-00005c30: 6d65 3d22 6c30 3031 3735 223e 3c2f 613e me=\"l00175\">\n-00005c40: 3c73 7061 6e20 636c 6173 733d 226c 696e 175 // \n-00005c80: 7468 6973 2069 7320 6120 6469 7265 6374 this is a direct\n-00005c90: 2073 6f6c 7665 723c 2f73 7061 6e3e 3c2f solver.
1\n-00005cf0: 3736 3c2f 7370 616e 3e20 2020 2020 2072 76 r\n-00005d00: 6573 2e3c 6120 636c 6173 733d 2263 6f64 es.iterations = 1;
.\n-00005d80: 3c61 2069 643d 226c 3030 3137 3722 206e 177 res.con\n-00005e20: 7665 7267 6564 3c2f 613e 203d 203c 7370 verged = true
;<\n-00005e50: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00005ea0: 3137 383c 2f73 7061 6e3e 2020 2020 2020 178 \n-00005eb0: 3c73 7061 6e20 636c 6173 733d 226b 6579 if(verbose_ >\n-00005ee0: 3b20 3029 3c2f 6469 763e 0a3c 6469 7620 ; 0)
.
179 \n-00005f40: 2020 2020 207b 3c2f 6469 763e 0a3c 6469 {
.<\n-00005f60: 6120 6964 3d22 6c30 3031 3830 2220 6e61 a id=\"l00180\" na\n-00005f70: 6d65 3d22 6c30 3031 3830 223e 3c2f 613e me=\"l00180\">\n-00005f80: 3c73 7061 6e20 636c 6173 733d 226c 696e 180 std::co\n-00005fb0: 7574 266c 743b 266c 743b 7374 643a 3a65 ut<<std::e\n-00005fc0: 6e64 6c26 6c74 3b26 6c74 3b3c 7370 616e ndl<<"Sol\n-00005ff0: 7669 6e67 2077 6974 6820 5375 6974 6553 ving with SuiteS\n-00006000: 7061 7273 6551 5226 7175 6f74 3b3c 2f73 parseQR"<<std:\n-00006020: 3a65 6e64 6c3b 3c2f 6469 763e 0a3c 6469 :endl;.<\n-00006040: 6120 6964 3d22 6c30 3031 3831 2220 6e61 a id=\"l00181\" na\n-00006050: 6d65 3d22 6c30 3031 3831 223e 3c2f 613e me=\"l00181\">\n-00006060: 3c73 7061 6e20 636c 6173 733d 226c 696e 181 std::co\n-00006090: 7574 266c 743b 266c 743b 3c73 7061 6e20 ut<<"Flop\n-000060c0: 7320 5461 6b65 6e3a 2026 7175 6f74 3b3c s Taken: "<\n-000060d0: 2f73 7061 6e3e 266c 743b 266c 743b 6363 /span><<cc\n-000060e0: 5f2d 2667 743b 5350 5152 5f66 6c6f 7063 _->SPQR_flopc\n-000060f0: 6f75 6e74 266c 743b 266c 743b 7374 643a ount<<std:\n-00006100: 3a65 6e64 6c3b 3c2f 6469 763e 0a3c 6469 :endl;.<\n-00006120: 6120 6964 3d22 6c30 3031 3832 2220 6e61 a id=\"l00182\" na\n-00006130: 6d65 3d22 6c30 3031 3832 223e 3c2f 613e me=\"l00182\">\n-00006140: 3c73 7061 6e20 636c 6173 733d 226c 696e 182 std::co\n-00006170: 7574 266c 743b 266c 743b 3c73 7061 6e20 ut<<"Anal\n-000061a0: 7973 6973 2054 696d 653a 2026 7175 6f74 ysis Time: "\n-000061b0: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n-000061c0: 6363 5f2d 2667 743b 5350 5152 5f61 6e61 cc_->SPQR_ana\n-000061d0: 6c79 7a65 5f74 696d 6526 6c74 3b26 6c74 lyze_time<<\n-000061e0: 3b3c 7370 616e 2063 6c61 7373 3d22 7374 ;&qu\n-00006200: 6f74 3b20 7326 7175 6f74 3b3c 2f73 7061 ot; s"<<std::e\n-00006220: 6e64 6c3b 3c2f 6469 763e 0a3c 6469 7620 ndl;.
183 \n-00006280: 2020 2020 2020 2073 7464 3a3a 636f 7574 std::cout\n-00006290: 266c 743b 266c 743b 3c73 7061 6e20 636c <<"Factor\n-000062c0: 697a 6520 5469 6d65 3a20 2671 756f 743b ize Time: "\n-000062d0: 3c2f 7370 616e 3e26 6c74 3b26 6c74 3b63 <<c\n-000062e0: 635f 2d26 6774 3b53 5051 525f 6661 6374 c_->SPQR_fact\n-000062f0: 6f72 697a 655f 7469 6d65 266c 743b 266c orize_time<&l\n-00006300: 743b 3c73 7061 6e20 636c 6173 733d 2273 t;&q\n-00006320: 756f 743b 2073 2671 756f 743b 3c2f 7370 uot; s"<<std::\n-00006340: 656e 646c 3b3c 2f64 6976 3e0a 3c64 6976 endl;
.<\n-00006380: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00006390: 6e6f 223e 2020 3138 343c 2f73 7061 6e3e no\"> 184
\n-000063a0: 2020 2020 2020 2020 7374 643a 3a63 6f75 std::cou\n-000063b0: 7426 6c74 3b26 6c74 3b3c 7370 616e 2063 t<<"Backs\n-000063e0: 6f6c 7665 2054 696d 653a 2026 7175 6f74 olve Time: "\n-000063f0: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n-00006400: 6363 5f2d 2667 743b 5350 5152 5f73 6f6c cc_->SPQR_sol\n-00006410: 7665 5f74 696d 6526 6c74 3b26 6c74 3b3c ve_time<<<\n-00006420: 7370 616e 2063 6c61 7373 3d22 7374 7269 span class=\"stri\n-00006430: 6e67 6c69 7465 7261 6c22 3e26 7175 6f74 ngliteral\">"\n-00006440: 3b20 7326 7175 6f74 3b3c 2f73 7061 6e3e ; s"
\n-00006450: 266c 743b 266c 743b 7374 643a 3a65 6e64 <<std::end\n-00006460: 6c3b 3c2f 6469 763e 0a3c 6469 7620 636c l;.
185 \n-000064c0: 2020 2020 2073 7464 3a3a 636f 7574 266c std::cout&l\n-000064d0: 743b 266c 743b 3c73 7061 6e20 636c 6173 t;<"Peak Mem\n-00006500: 6f72 7920 5573 6167 653a 2026 7175 6f74 ory Usage: "\n-00006510: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n-00006520: 6363 5f2d 2667 743b 6d65 6d6f 7279 5f75 cc_->memory_u\n-00006530: 7361 6765 266c 743b 266c 743b 3c73 7061 sage<<" b\n-00006560: 7974 6573 2671 756f 743b 3c2f 7370 616e ytes"<<std::en\n-00006580: 646c 3b3c 2f64 6976 3e0a 3c64 6976 2063 dl;
.
186 \n-000065e0: 2020 2020 2020 7374 643a 3a63 6f75 7426 std::cout&\n-000065f0: 6c74 3b26 6c74 3b3c 7370 616e 2063 6c61 lt;<"Rank Es\n-00006620: 7469 6d61 7465 3a20 2671 756f 743b 3c2f timate: "<<cc_\n-00006640: 2d26 6774 3b53 5051 525f 6973 7461 745b ->SPQR_istat[\n-00006650: 345d 266c 743b 266c 743b 7374 643a 3a65 4]<<std::e\n-00006660: 6e64 6c26 6c74 3b26 6c74 3b73 7464 3a3a ndl<<std::\n-00006670: 656e 646c 3b3c 2f64 6976 3e0a 3c64 6976 endl;
.<\n-000066b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000066c0: 6e6f 223e 2020 3138 373c 2f73 7061 6e3e no\"> 187
\n-000066d0: 2020 2020 2020 7d3c 2f64 6976 3e0a 3c64 }.\n-000066f0: 3c61 2069 643d 226c 3030 3138 3822 206e 188 }.\n-00006750: 3c61 2069 643d 226c 3030 3138 3922 206e 189 .
191 virtual\n-00006860: 203c 7370 616e 2063 6c61 7373 3d22 6b65 void<\n-00006880: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> apply (\n-00006910: 646f 6d61 696e 5f74 7970 653c 2f61 3e26 domain_type&\n-00006920: 616d 703b 2078 2c20 3c61 2063 6c61 7373 amp; x, range_type& b, [[may\n-00006970: 6265 5f75 6e75 7365 645d 5d20 3c73 7061 be_unused]] double reduction, <\n-000069b0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-000069c0: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n-000069d0: 3032 3730 302e 6874 6d6c 223e 496e 7665 02700.html\">Inve\n-000069e0: 7273 654f 7065 7261 746f 7252 6573 756c rseOperatorResul\n-000069f0: 743c 2f61 3e26 616d 703b 2072 6573 293c t& res)<\n-00006a00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00006a50: 3139 323c 2f73 7061 6e3e 2020 2020 7b3c 192 {<\n-00006a60: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00006ab0: 3139 333c 2f73 7061 6e3e 2020 2020 2020 193 \n-00006ac0: 6170 706c 7928 782c 2062 2c20 7265 7329 apply(x, b, res)\n-00006ad0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-00006b20: 2020 3139 343c 2f73 7061 6e3e 2020 2020 194 \n-00006b30: 7d3c 2f64 6976 3e0a 3c64 6976 2063 6c61 }
.
\n-00006b80: 2020 3139 353c 2f73 7061 6e3e 203c 2f64 195 .
196 \n-00006c50: 766f 6964 3c2f 7370 616e 3e20 3c61 2063 void se\n-00006cb0: 744f 7074 696f 6e3c 2f61 3e28 5b5b 6d61 tOption([[ma\n-00006cc0: 7962 655f 756e 7573 6564 5d5d 203c 7370 ybe_unused]] unsigned<\n-00006cf0: 2f73 7061 6e3e 203c 7370 616e 2063 6c61 /span> int opti\n-00006d20: 6f6e 2c20 5b5b 6d61 7962 655f 756e 7573 on, [[maybe_unus\n-00006d30: 6564 5d5d 203c 7370 616e 2063 6c61 7373 ed]] d\n-00006d50: 6f75 626c 653c 2f73 7061 6e3e 2076 616c ouble val\n-00006d60: 7565 293c 2f64 6976 3e0a 3c64 6976 2063 ue)
.
197 \n-00006dc0: 2020 7b7d 3c2f 6469 763e 0a3c 6469 7620 {}
.
198 \n-00006e20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n-00006e70: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-00006e80: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n-00006e90: 2367 6134 3065 6332 6233 6561 3136 6231 #ga40ec2b3ea16b1\n-00006ea0: 6532 3134 6433 3862 3536 3666 3464 3037 e214d38b566f4d07\n-00006eb0: 6366 3022 3e20 2032 3030 3c2f 613e 3c2f cf0\"> 200 void <\n-00006ef0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00006f00: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n-00006f10: 2261 3030 3233 332e 6874 6d6c 2367 6134 \"a00233.html#ga4\n-00006f20: 3065 6332 6233 6561 3136 6231 6532 3134 0ec2b3ea16b1e214\n-00006f30: 6433 3862 3536 3666 3464 3037 6366 3022 d38b566f4d07cf0\"\n-00006f40: 3e73 6574 4d61 7472 6978 3c2f 613e 283c >setMatrix(<\n-00006f50: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00006f60: 6f72 6422 3e63 6f6e 7374 3c2f 7370 616e ord\">const Ma\n-00006fa0: 7472 6978 3c2f 613e 2661 6d70 3b20 6d61 trix& ma\n-00006fb0: 7472 6978 293c 2f64 6976 3e0a 3c64 6976 trix)
.<\n-00006ff0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00007000: 6e6f 223e 2020 3230 313c 2f73 7061 6e3e no\"> 201\n-00007010: 2020 2020 7b3c 2f64 6976 3e0a 3c64 6976 {
.<\n-00007050: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00007060: 6e6f 223e 2020 3230 323c 2f73 7061 6e3e no\"> 202\n-00007070: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-00007090: 6966 3c2f 7370 616e 3e20 2828 7370 7172 if ((spqr\n-000070a0: 4d61 7472 6978 5f2e 4e28 2920 2b20 7370 Matrix_.N() + sp\n-000070b0: 7172 4d61 7472 6978 5f2e 4d28 2920 2667 qrMatrix_.M() &g\n-000070c0: 743b 2030 2920 7c7c 206d 6174 7269 7849 t; 0) || matrixI\n-000070d0: 734c 6f61 6465 645f 293c 2f64 6976 3e0a sLoaded_)
.\n-000070e0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
204 <\n-000071a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000071f0: 3230 353c 2f73 7061 6e3e 2020 2020 2020 205 \n-00007200: 3c73 7061 6e20 636c 6173 733d 226b 6579 if (spqrMatrix_\n-00007230: 2e4e 2829 202b 2073 7071 724d 6174 7269 .N() + spqrMatri\n-00007240: 785f 2e4d 2829 202b 2073 7071 724d 6174 x_.M() + spqrMat\n-00007250: 7269 785f 2e6e 6f6e 7a65 726f 6573 2829 rix_.nonzeroes()\n-00007260: 2021 3d20 3029 3c2f 6469 763e 0a3c 6469 != 0)
.<\n-00007280: 6120 6964 3d22 6c30 3032 3036 2220 6e61 a id=\"l00206\" na\n-00007290: 6d65 3d22 6c30 3032 3036 223e 3c2f 613e me=\"l00206\">\n-000072a0: 3c73 7061 6e20 636c 6173 733d 226c 696e 206 spqrMat\n-000072d0: 7269 785f 2e66 7265 6528 293b 3c2f 6469 rix_.free();.
207\n-00007330: 3c2f 7370 616e 3e20 2020 2020 2073 7071 spq\n-00007340: 724d 6174 7269 785f 2e73 6574 5369 7a65 rMatrix_.setSize\n-00007350: 283c 6120 636c 6173 733d 2263 6f64 6520 (Ma\n-00007380: 7472 6978 4469 6d65 6e73 696f 6e26 6c74 trixDimension<\n-00007390: 3b4d 6174 7269 7826 6774 3b3a 3a72 6f77 ;Matrix>::row\n-000073a0: 6469 6d3c 2f61 3e28 6d61 7472 6978 292c dim(matrix),\n-000073b0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00007400: 2032 3038 3c2f 7370 616e 3e20 2020 2020 208 \n-00007410: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00007420: 2020 2020 203c 6120 636c 6173 733d 2263 MatrixDimensio\n-00007460: 6e26 6c74 3b4d 6174 7269 7826 6774 3b3a n<Matrix>:\n-00007470: 3a63 6f6c 6469 6d3c 2f61 3e28 6d61 7472 :coldim(matr\n-00007480: 6978 2929 3b3c 2f64 6976 3e0a 3c64 6976 ix));
.<\n-000074c0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000074d0: 6e6f 223e 2020 3230 393c 2f73 7061 6e3e no\"> 209
\n-000074e0: 2020 2020 2020 4953 544c 3a3a 496d 706c ISTL::Impl\n-000074f0: 3a3a 4243 4353 4d61 7472 6978 496e 6974 ::BCCSMatrixInit\n-00007500: 6961 6c69 7a65 7226 6c74 3b4d 6174 7269 ializer<Matri\n-00007510: 782c 2069 6e74 2667 743b 2069 6e69 7469 x, int> initi\n-00007520: 616c 697a 6572 2873 7071 724d 6174 7269 alizer(spqrMatri\n-00007530: 785f 293b 3c2f 6469 763e 0a3c 6469 7620 x_);
.
210 \n-00007590: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-000075e0: 2032 3131 3c2f 7370 616e 3e20 2020 2020 211 \n-000075f0: 2063 6f70 7954 6f42 4343 534d 6174 7269 copyToBCCSMatri\n-00007600: 7828 696e 6974 6961 6c69 7a65 722c 206d x(initializer, m\n-00007610: 6174 7269 7829 3b3c 2f64 6976 3e0a 3c64 atrix);
.\n-00007630: 3c61 2069 643d 226c 3030 3231 3222 206e 212
.
213 \n-000076d0: 2020 2020 6465 636f 6d70 6f73 6528 293b decompose();\n-000076e0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00007730: 2032 3134 3c2f 7370 616e 3e20 2020 207d 214 }\n-00007740: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00007790: 2032 3135 3c2f 7370 616e 3e20 3c2f 6469 215 .
216\n-000077f0: 3c2f 7370 616e 3e20 2020 203c 7370 616e template\n-00007820: 266c 743b 3c73 7061 6e20 636c 6173 733d <class<\n-00007840: 2f73 7061 6e3e 2053 2667 743b 3c2f 6469 /span> S>.
217 v\n-00007910: 6f69 643c 2f73 7061 6e3e 203c 6120 636c oid set\n-00007970: 5375 624d 6174 7269 783c 2f61 3e28 3c73 SubMatrix(const\n-000079a0: 203c 6120 636c 6173 733d 2263 6f64 6520 Mat\n-000079d0: 7269 783c 2f61 3e26 616d 703b 206d 6174 rix& mat\n-000079e0: 7269 782c 203c 7370 616e 2063 6c61 7373 rix, const\n-00007a00: 3c2f 7370 616e 3e20 5326 616d 703b 2072 S& r\n-00007a10: 6f77 496e 6465 7853 6574 293c 2f64 6976 owIndexSet).
218<\n-00007a70: 2f73 7061 6e3e 2020 2020 7b3c 2f64 6976 /span> {.
219<\n-00007ad0: 2f73 7061 6e3e 2020 2020 2020 3c73 7061 /span> if \n-00007b00: 2828 7370 7172 4d61 7472 6978 5f2e 4e28 ((spqrMatrix_.N(\n-00007b10: 2920 2b20 7370 7172 4d61 7472 6978 5f2e ) + spqrMatrix_.\n-00007b20: 4d28 2920 2667 743b 2030 2920 7c7c 206d M() > 0) || m\n-00007b30: 6174 7269 7849 734c 6f61 6465 645f 293c atrixIsLoaded_)<\n-00007b40: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00007b90: 3232 303c 2f73 7061 6e3e 2020 2020 2020 220 \n-00007ba0: 2020 6672 6565 2829 3b3c 2f64 6976 3e0a free();
.\n-00007bb0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00007c40: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00007c50: 6e6f 223e 2020 3232 323c 2f73 7061 6e3e no\"> 222\n-00007c60: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-00007c80: 6966 3c2f 7370 616e 3e20 2873 7071 724d if (spqrM\n-00007c90: 6174 7269 785f 2e4e 2829 202b 2073 7071 atrix_.N() + spq\n-00007ca0: 724d 6174 7269 785f 2e4d 2829 202b 2073 rMatrix_.M() + s\n-00007cb0: 7071 724d 6174 7269 785f 2e6e 6f6e 7a65 pqrMatrix_.nonze\n-00007cc0: 726f 6573 2829 2021 3d20 3029 3c2f 6469 roes() != 0).
223\n-00007d20: 3c2f 7370 616e 3e20 2020 2020 2020 2073 s\n-00007d30: 7071 724d 6174 7269 785f 2e66 7265 6528 pqrMatrix_.free(\n-00007d40: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
.
224 .
2\n-00007df0: 3235 3c2f 7370 616e 3e20 2020 2020 2073 25 s\n-00007e00: 7071 724d 6174 7269 785f 2e73 6574 5369 pqrMatrix_.setSi\n-00007e10: 7a65 2872 6f77 496e 6465 7853 6574 2e73 ze(rowIndexSet.s\n-00007e20: 697a 6528 292a 3c61 2063 6c61 7373 3d22 ize()*MatrixDimensi\n-00007e60: 6f6e 266c 743b 4d61 7472 6978 2667 743b on<Matrix>\n-00007e70: 3a3a 726f 7764 696d 3c2f 613e 286d 6174 ::rowdim(mat\n-00007e80: 7269 7829 202f 206d 6174 7269 782e 3c61 rix) / matrix.N\n-00007ee0: 3c2f 613e 2829 2c3c 2f64 6976 3e0a 3c64 (),
.\n-00007f00: 3c61 2069 643d 226c 3030 3232 3622 206e 226 \n-00007f50: 2020 2020 2020 2020 2020 2020 726f 7749 rowI\n-00007f60: 6e64 6578 5365 742e 7369 7a65 2829 2a3c ndexSet.size()*<\n-00007f70: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00007f80: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n-00007f90: 3031 3133 362e 6874 6d6c 223e 4d61 7472 01136.html\">Matr\n-00007fa0: 6978 4469 6d65 6e73 696f 6e26 6c74 3b4d ixDimension<M\n-00007fb0: 6174 7269 7826 6774 3b3a 3a63 6f6c 6469 atrix>::coldi\n-00007fc0: 6d3c 2f61 3e28 6d61 7472 6978 2920 2f20 m(matrix) / \n-00007fd0: 6d61 7472 6978 2e3c 6120 636c 6173 733d matrix.M())\n-00008030: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-00008080: 2020 3232 373c 2f73 7061 6e3e 2020 2020 227 \n-00008090: 2020 4953 544c 3a3a 496d 706c 3a3a 4243 ISTL::Impl::BC\n-000080a0: 4353 4d61 7472 6978 496e 6974 6961 6c69 CSMatrixInitiali\n-000080b0: 7a65 7226 6c74 3b4d 6174 7269 782c 2069 zer<Matrix, i\n-000080c0: 6e74 2667 743b 2069 6e69 7469 616c 697a nt> initializ\n-000080d0: 6572 2873 7071 724d 6174 7269 785f 293b er(spqrMatrix_);\n-000080e0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00008130: 2032 3238 3c2f 7370 616e 3e20 3c2f 6469 228 .
229\n-00008190: 3c2f 7370 616e 3e20 2020 2020 2063 6f70 cop\n-000081a0: 7954 6f42 4343 534d 6174 7269 7828 696e yToBCCSMatrix(in\n-000081b0: 6974 6961 6c69 7a65 722c 2049 5354 4c3a itializer, ISTL:\n-000081c0: 3a49 6d70 6c3a 3a4d 6174 7269 7852 6f77 :Impl::MatrixRow\n-000081d0: 5375 6273 6574 266c 743b 3c61 2063 6c61 Subset<Matrix\n-00008210: 2c73 7464 3a3a 7365 7426 6c74 3b73 7464 ,std::set<std\n-00008220: 3a3a 7369 7a65 5f74 2667 743b 2026 6774 ::size_t> >\n-00008230: 3b28 6d61 7472 6978 2c72 6f77 496e 6465 ;(matrix,rowInde\n-00008240: 7853 6574 2929 3b3c 2f64 6976 3e0a 3c64 xSet));
.\n-00008260: 3c61 2069 643d 226c 3030 3233 3022 206e 230
.
231 \n-00008300: 2020 2020 6465 636f 6d70 6f73 6528 293b decompose();\n-00008310: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00008360: 2032 3332 3c2f 7370 616e 3e20 2020 207d 232 }\n-00008370: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-000083c0: 2032 3333 3c2f 7370 616e 3e20 3c2f 6469 233 .
238 inlin\n-00008490: 653c 2f73 7061 6e3e 203c 7370 616e 2063 e void <\n-000084c0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-000084d0: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n-000084e0: 2261 3030 3233 332e 6874 6d6c 2367 6137 \"a00233.html#ga7\n-000084f0: 3463 6537 6232 3139 3634 3763 3736 3838 4ce7b219647c7688\n-00008500: 3061 3631 3533 3731 6335 3763 3137 3322 0a615371c57c173\"\n-00008510: 3e73 6574 5665 7262 6f73 6974 793c 2f61 >setVerbosity(int<\n-00008540: 2f73 7061 6e3e 2076 293c 2f64 6976 3e0a /span> v)
.\n-00008550: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-000085b0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00008650: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00008660: 6e6f 223e 2020 3234 313c 2f73 7061 6e3e no\"> 241\n-00008670: 2020 2020 7d3c 2f64 6976 3e0a 3c64 6976 }
.<\n-000086b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000086c0: 6e6f 223e 2020 3234 323c 2f73 7061 6e3e no\"> 242\n-000086d0: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
.
\n-00008720: 3c61 2063 6c61 7373 3d22 6c69 6e65 2220 247<\n-00008770: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n-00008790: 696e 6c69 6e65 3c2f 7370 616e 3e20 5375 inline Su\n-000087a0: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n-000087b0: 6f72 697a 6174 696f 6e26 6c74 3b54 2667 orization<T&g\n-000087c0: 743b 2a20 3c61 2063 6c61 7373 3d22 636f t;* getFactori\n-00008820: 7a61 7469 6f6e 3c2f 613e 2829 3c2f 6469 zation().
248\n-00008880: 3c2f 7370 616e 3e20 2020 207b 3c2f 6469 {.
249\n-000088e0: 3c2f 7370 616e 3e20 2020 2020 203c 7370 return spqrfactori\n-00008920: 7a61 7469 6f6e 5f3b 3c2f 6469 763e 0a3c zation_;
.<\n-00008930: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00008940: 3e3c 6120 6964 3d22 6c30 3032 3530 2220 > 250 }
.<\n-00008990: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000089a0: 3e3c 6120 6964 3d22 6c30 3032 3531 2220 > 251
.
256 inline\n-00008ab0: 203c 6120 636c 6173 733d 2263 6f64 6520 SPQRMatrix\n-00008b10: 2661 6d70 3b20 3c61 2063 6c61 7373 3d22 & getInter\n-00008b70: 6e61 6c4d 6174 7269 783c 2f61 3e28 293c nalMatrix()<\n-00008b80: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00008bd0: 3235 373c 2f73 7061 6e3e 2020 2020 7b3c 257 {<\n-00008be0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-00008c30: 3235 383c 2f73 7061 6e3e 2020 2020 2020 258 \n-00008c40: 3c73 7061 6e20 636c 6173 733d 226b 6579 return\n-00008c60: 3c2f 7370 616e 3e20 7370 7172 4d61 7472 spqrMatr\n-00008c70: 6978 5f3b 3c2f 6469 763e 0a3c 6469 7620 ix_;
.
259 \n-00008cd0: 2020 207d 3c2f 6469 763e 0a3c 6469 7620 }
.
260 \n-00008d30: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n-00008d80: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-00008d90: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n-00008da0: 2367 6139 3237 3966 6633 3139 3530 3134 #ga9279ff3195014\n-00008db0: 3136 6338 6165 6630 3462 6565 6562 3362 16c8aef04beeeb3b\n-00008dc0: 3366 3922 3e20 2032 3635 3c2f 613e 3c2f 3f9\"> 265 void <\n-00008e00: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00008e10: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n-00008e20: 2261 3030 3233 332e 6874 6d6c 2367 6139 \"a00233.html#ga9\n-00008e30: 3237 3966 6633 3139 3530 3134 3136 6338 279ff319501416c8\n-00008e40: 6165 6630 3462 6565 6562 3362 3366 3922 aef04beeeb3b3f9\"\n-00008e50: 3e66 7265 653c 2f61 3e28 293c 2f64 6976 >free().
266<\n-00008eb0: 2f73 7061 6e3e 2020 2020 7b3c 2f64 6976 /span> {.
267<\n-00008f10: 2f73 7061 6e3e 2020 2020 2020 6368 6f6c /span> chol\n-00008f20: 6d6f 645f 6c5f 6672 6565 5f73 7061 7273 mod_l_free_spars\n-00008f30: 6528 2661 6d70 3b41 5f2c 2063 635f 293b e(&A_, cc_);\n-00008f40: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-00008f90: 2032 3638 3c2f 7370 616e 3e20 2020 2020 268 \n-00008fa0: 2063 686f 6c6d 6f64 5f6c 5f66 7265 655f cholmod_l_free_\n-00008fb0: 6465 6e73 6528 2661 6d70 3b42 5f2c 2063 dense(&B_, c\n-00008fc0: 635f 293b 3c2f 6469 763e 0a3c 6469 7620 c_);
.
269 \n-00009020: 2020 2020 2053 7569 7465 5370 6172 7365 SuiteSparse\n-00009030: 5152 5f66 7265 6526 6c74 3b54 2667 743b QR_free<T>\n-00009040: 2826 616d 703b 7370 7172 6661 6374 6f72 (&spqrfactor\n-00009050: 697a 6174 696f 6e5f 2c20 6363 5f29 3b3c ization_, cc_);<\n-00009060: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000090b0: 3237 303c 2f73 7061 6e3e 2020 2020 2020 270 \n-000090c0: 7370 7172 4d61 7472 6978 5f2e 6672 6565 spqrMatrix_.free\n-000090d0: 2829 3b3c 2f64 6976 3e0a 3c64 6976 2063 ();
.
271 \n-00009130: 2020 2020 6d61 7472 6978 4973 4c6f 6164 matrixIsLoad\n-00009140: 6564 5f20 3d20 3c73 7061 6e20 636c 6173 ed_ = fals\n-00009160: 653c 2f73 7061 6e3e 3b3c 2f64 6976 3e0a e;
.\n-00009170: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-000091d0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00009260: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00009270: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 275<\n-000092c0: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c73 /a> inline const c\n-00009330: 6861 723c 2f73 7061 6e3e 2a20 3c61 2063 har* na\n-00009390: 6d65 3c2f 613e 2829 3c2f 6469 763e 0a3c me()
.<\n-000093a0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000093b0: 3e3c 6120 6964 3d22 6c30 3032 3736 2220 > 276 {
.<\n-00009400: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00009410: 3e3c 6120 6964 3d22 6c30 3032 3737 2220 > 277 return\n-00009480: 203c 7370 616e 2063 6c61 7373 3d22 7374 &qu\n-000094a0: 6f74 3b53 5051 5226 7175 6f74 3b3c 2f73 ot;SPQR";
.<\n-000094f0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00009500: 6e6f 223e 2020 3237 383c 2f73 7061 6e3e no\"> 278\n-00009510: 2020 2020 7d3c 2f64 6976 3e0a 3c64 6976 }
.<\n-00009550: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00009560: 6e6f 223e 2020 3237 393c 2f73 7061 6e3e no\"> 279\n-00009570: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
.
\n-000095c0: 2020 3238 303c 2f73 7061 6e3e 2020 2020 280 \n-000095d0: 3c73 7061 6e20 636c 6173 733d 226b 6579 private:
.<\n-00009630: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00009640: 6e6f 223e 2020 3238 313c 2f73 7061 6e3e no\"> 281
\n-00009650: 2020 2020 3c73 7061 6e20 636c 6173 733d templa\n-00009670: 7465 3c2f 7370 616e 3e26 6c74 3b3c 7370 te<class \n-000096a0: 4d2c 3c73 7061 6e20 636c 6173 733d 226b M,class X, cl\n-000096e0: 6173 733c 2f73 7061 6e3e 2054 4d2c 203c ass TM, <\n-000096f0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00009700: 6f72 6422 3e63 6c61 7373 3c2f 7370 616e ord\">class TD, clas\n-00009730: 733c 2f73 7061 6e3e 2054 3126 6774 3b3c s T1><\n-00009740: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
282 fr\n-00009800: 6965 6e64 3c2f 7370 616e 3e20 3c73 7061 iend class <\n-00009830: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00009840: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n-00009850: 3134 3132 2e68 746d 6c22 3e53 6571 4f76 1412.html\">SeqOv\n-00009860: 6572 6c61 7070 696e 6753 6368 7761 727a erlappingSchwarz\n-00009870: 3c2f 613e 3b3c 2f64 6976 3e0a 3c64 6976 ;
.<\n-000098b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000098c0: 6e6f 223e 2020 3238 333c 2f73 7061 6e3e no\"> 283
\n-000098d0: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
.
\n-00009920: 2020 3238 343c 2f73 7061 6e3e 2020 2020 284 \n-00009930: 3c73 7061 6e20 636c 6173 733d 226b 6579 friend struct\n-00009970: 203c 2f73 7061 6e3e 3c61 2063 6c61 7373 SeqOverlapp\n-000099b0: 696e 6753 6368 7761 727a 4173 7365 6d62 ingSchwarzAssemb\n-000099c0: 6c65 7248 656c 7065 723c 2f61 3e26 6c74 lerHelper<\n-000099d0: 3b3c 6120 636c 6173 733d 2263 6f64 6520 ;SPQ\n-00009a00: 523c 2f61 3e26 6c74 3b3c 6120 636c 6173 R<Matrix&\n-00009a40: 6774 3b2c 7472 7565 2667 743b 3b3c 2f64 gt;,true>;.
28\n-00009aa0: 353c 2f73 7061 6e3e 203c 2f64 6976 3e0a 5
.\n-00009ab0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-00009b40: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-00009ba0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
\n-00009c90: 2032 3930 3c2f 7370 616e 3e20 2020 2020 290 \n-00009ca0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 const std::size_t \n-00009cd0: 6e63 6f6c 7328 7370 7172 4d61 7472 6978 ncols(spqrMatrix\n-00009ce0: 5f2e 4d28 2929 3b3c 2f64 6976 3e0a 3c64 _.M());
.\n-00009d00: 3c61 2069 643d 226c 3030 3239 3122 206e 291 co\n-00009d60: 6e73 743c 2f73 7061 6e3e 2073 7464 3a3a nst std::\n-00009d70: 7369 7a65 5f74 206e 6e7a 2873 7071 724d size_t nnz(spqrM\n-00009d80: 6174 7269 785f 2e67 6574 436f 6c53 7461 atrix_.getColSta\n-00009d90: 7274 2829 5b6e 636f 6c73 5d29 3b3c 2f64 rt()[ncols]);.
29\n-00009df0: 323c 2f73 7061 6e3e 203c 2f64 6976 3e0a 2
.\n-00009e00: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n-00009e30: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 293 \n-00009e70: 2f2f 2069 6e69 7469 616c 6973 6520 7468 // initialise th\n-00009e80: 6520 6d61 7472 6978 2041 2028 736f 7274 e matrix A (sort\n-00009e90: 6564 2c20 7061 636b 6564 2c20 756e 7379 ed, packed, unsy\n-00009ea0: 6d6d 6574 7269 632c 2072 6561 6c20 656e mmetric, real en\n-00009eb0: 7472 6965 7329 3c2f 7370 616e 3e3c 2f64 tries).
29\n-00009f10: 343c 2f73 7061 6e3e 2020 2020 2020 415f 4 A_\n-00009f20: 203d 2063 686f 6c6d 6f64 5f6c 5f61 6c6c = cholmod_l_all\n-00009f30: 6f63 6174 655f 7370 6172 7365 286e 726f ocate_sparse(nro\n-00009f40: 7773 2c20 6e63 6f6c 732c 206e 6e7a 2c20 ws, ncols, nnz, \n-00009f50: 312c 2031 2c20 302c 2031 2c20 6363 5f29 1, 1, 0, 1, cc_)\n-00009f60: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-00009fb0: 2020 3239 353c 2f73 7061 6e3e 203c 2f64 295 .
29\n-0000a010: 363c 2f73 7061 6e3e 2020 2020 2020 3c73 6 // copy all \n-0000a040: 7468 6520 656e 7472 6965 7320 6f66 2041 the entries of A\n-0000a050: 702c 2041 692c 2041 783c 2f73 7061 6e3e p, Ai, Ax\n-0000a060: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000a0b0: 2032 3937 3c2f 7370 616e 3e20 2020 2020 297 \n-0000a0c0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 for(std::size_\n-0000a0f0: 7420 6b20 3d20 303b 206b 2021 3d20 286e t k = 0; k != (n\n-0000a100: 636f 6c73 2b31 293b 202b 2b6b 293c 2f64 cols+1); ++k).
29\n-0000a160: 383c 2f73 7061 6e3e 2020 2020 2020 2020 8 \n-0000a170: 283c 7370 616e 2063 6c61 7373 3d22 6b65 (static_ca\n-0000a190: 7374 266c 743b 3c2f 7370 616e 3e3c 7370 st<long int\n-0000a1e0: 3c2f 7370 616e 3e20 2a3c 7370 616e 2063 *&\n-0000a200: 6774 3b3c 2f73 7061 6e3e 2841 5f2d 2667 gt;(A_-&g\n-0000a210: 743b 7029 295b 6b5d 203d 2073 7071 724d t;p))[k] = spqrM\n-0000a220: 6174 7269 785f 2e67 6574 436f 6c53 7461 atrix_.getColSta\n-0000a230: 7274 2829 5b6b 5d3b 3c2f 6469 763e 0a3c rt()[k];
.<\n-0000a240: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000a250: 3e3c 6120 6964 3d22 6c30 3032 3939 2220 > 299
.
300 \n-0000a2f0: 2020 2020 203c 7370 616e 2063 6c61 7373 f\n-0000a310: 6f72 3c2f 7370 616e 3e28 7374 643a 3a73 or(std::s\n-0000a320: 697a 655f 7420 6b20 3d20 303b 206b 2021 ize_t k = 0; k !\n-0000a330: 3d20 6e6e 7a3b 202b 2b6b 293c 2f64 6976 = nnz; ++k).
301<\n-0000a390: 2f73 7061 6e3e 2020 2020 2020 7b3c 2f64 /span> {.
30\n-0000a3f0: 323c 2f73 7061 6e3e 2020 2020 2020 2020 2 \n-0000a400: 283c 7370 616e 2063 6c61 7373 3d22 6b65 (static_ca\n-0000a420: 7374 266c 743b 3c2f 7370 616e 3e3c 7370 st<long int\n-0000a470: 3c2f 7370 616e 3e2a 3c73 7061 6e20 636c *&g\n-0000a490: 743b 3c2f 7370 616e 3e28 415f 2d26 6774 t;(A_->\n-0000a4a0: 3b69 2929 5b6b 5d20 3d20 7370 7172 4d61 ;i))[k] = spqrMa\n-0000a4b0: 7472 6978 5f2e 6765 7452 6f77 496e 6465 trix_.getRowInde\n-0000a4c0: 7828 295b 6b5d 3b3c 2f64 6976 3e0a 3c64 x()[k];
.\n-0000a4e0: 3c61 2069 643d 226c 3030 3330 3322 206e 303 (static_cast<\n-0000a550: 3c2f 7370 616e 3e54 2a3c 7370 616e 2063 T*&\n-0000a570: 6774 3b3c 2f73 7061 6e3e 2841 5f2d 2667 gt;(A_-&g\n-0000a580: 743b 7829 295b 6b5d 203d 2073 7071 724d t;x))[k] = spqrM\n-0000a590: 6174 7269 785f 2e67 6574 5661 6c75 6573 atrix_.getValues\n-0000a5a0: 2829 5b6b 5d3b 3c2f 6469 763e 0a3c 6469 ()[k];
.<\n-0000a5c0: 6120 6964 3d22 6c30 3033 3034 2220 6e61 a id=\"l00304\" na\n-0000a5d0: 6d65 3d22 6c30 3033 3034 223e 3c2f 613e me=\"l00304\">\n-0000a5e0: 3c73 7061 6e20 636c 6173 733d 226c 696e 304 }
.<\n-0000a610: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000a620: 3e3c 6120 6964 3d22 6c30 3033 3035 2220 > 305
.
306 \n-0000a6c0: 2020 2020 203c 7370 616e 2063 6c61 7373 // in\n-0000a6e0: 6974 6961 6c69 7365 2074 6865 2076 6563 itialise the vec\n-0000a6f0: 746f 7220 423c 2f73 7061 6e3e 3c2f 6469 tor B.
307\n-0000a750: 3c2f 7370 616e 3e20 2020 2020 2042 5f20 B_ \n-0000a760: 3d20 6368 6f6c 6d6f 645f 6c5f 616c 6c6f = cholmod_l_allo\n-0000a770: 6361 7465 5f64 656e 7365 286e 726f 7773 cate_dense(nrows\n-0000a780: 2c20 312c 206e 726f 7773 2c20 415f 2d26 , 1, nrows, A_-&\n-0000a790: 6774 3b78 7479 7065 2c20 6363 5f29 3b3c gt;xtype, cc_);<\n-0000a7a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-0000a7f0: 3330 383c 2f73 7061 6e3e 2020 2020 2020 308 \n-0000a800: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // compute\n-0000a820: 2066 6163 746f 7269 7a61 7469 6f6e 206f factorization o\n-0000a830: 6620 413c 2f73 7061 6e3e 3c2f 6469 763e f A
\n-0000a840: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n-0000a870: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 309 spqrf\n-0000a8a0: 6163 746f 7269 7a61 7469 6f6e 5f3d 5375 actorization_=Su\n-0000a8b0: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n-0000a8c0: 6f72 697a 6526 6c74 3b54 2667 743b 2853 orize<T>(S\n-0000a8d0: 5051 525f 4f52 4445 5249 4e47 5f44 4546 PQR_ORDERING_DEF\n-0000a8e0: 4155 4c54 2c53 5051 525f 4445 4641 554c AULT,SPQR_DEFAUL\n-0000a8f0: 545f 544f 4c2c 415f 2c63 635f 293b 3c2f T_TOL,A_,cc_);.
3\n-0000a950: 3130 3c2f 7370 616e 3e20 2020 207d 3c2f 10 }.
3\n-0000a9b0: 3131 3c2f 7370 616e 3e20 3c2f 6469 763e 11
\n-0000a9c0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n-0000a9f0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 312 SPQRMat\n-0000aa20: 7269 7820 7370 7172 4d61 7472 6978 5f3b rix spqrMatrix_;\n-0000aa30: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000aa80: 2033 3133 3c2f 7370 616e 3e20 2020 203c 313 <\n-0000aa90: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000aaa0: 6f72 6474 7970 6522 3e62 6f6f 6c3c 2f73 ordtype\">bool matrixIsLoa\n-0000aac0: 6465 645f 3b3c 2f64 6976 3e0a 3c64 6976 ded_;
.<\n-0000ab00: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000ab10: 6e6f 223e 2020 3331 343c 2f73 7061 6e3e no\"> 314\n-0000ab20: 2020 2020 3c73 7061 6e20 636c 6173 733d in\n-0000ab40: 743c 2f73 7061 6e3e 2076 6572 626f 7365 t verbose\n-0000ab50: 5f3b 3c2f 6469 763e 0a3c 6469 7620 636c _;
.
315 \n-0000abb0: 2063 686f 6c6d 6f64 5f63 6f6d 6d6f 6e2a cholmod_common*\n-0000abc0: 2063 635f 3b3c 2f64 6976 3e0a 3c64 6976 cc_;
.<\n-0000ac00: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000ac10: 6e6f 223e 2020 3331 363c 2f73 7061 6e3e no\"> 316
\n-0000ac20: 2020 2020 6368 6f6c 6d6f 645f 7370 6172 cholmod_spar\n-0000ac30: 7365 2a20 415f 3b3c 2f64 6976 3e0a 3c64 se* A_;
.\n-0000ac50: 3c61 2069 643d 226c 3030 3331 3722 206e 317 cholmod_de\n-0000aca0: 6e73 652a 2042 5f3b 3c2f 6469 763e 0a3c nse* B_;
.<\n-0000acb0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000acc0: 3e3c 6120 6964 3d22 6c30 3033 3138 2220 > 318 SuiteSpar\n-0000ad10: 7365 5152 5f66 6163 746f 7269 7a61 7469 seQR_factorizati\n-0000ad20: 6f6e 266c 743b 5426 6774 3b2a 2073 7071 on<T>* spq\n-0000ad30: 7266 6163 746f 7269 7a61 7469 6f6e 5f3b rfactorization_;\n-0000ad40: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000ad90: 2033 3139 3c2f 7370 616e 3e20 207d 3b3c 319 };<\n-0000ada0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-0000adf0: 3332 303c 2f73 7061 6e3e 203c 2f64 6976 320 .
321<\n-0000ae50: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> te\n-0000ae70: 6d70 6c61 7465 3c2f 7370 616e 3e26 6c74 mplate<\n-0000ae80: 3b3c 7370 616e 2063 6c61 7373 3d22 6b65 ;typename<\n-0000aea0: 2f73 7061 6e3e 2054 2c20 3c73 7061 6e20 /span> T, \n-0000aec0: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n-0000aed0: 4126 6774 3b3c 2f64 6976 3e0a 3c64 6976 A>
.<\n-0000af10: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000af20: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 322\n-0000af50: 3c2f 7370 616e 3e20 203c 7370 616e 2063 s\n-0000af70: 7472 7563 7420 3c2f 7370 616e 3e3c 6120 truct IsDire\n-0000afb0: 6374 536f 6c76 6572 3c2f 613e 266c 743b ctSolver<\n-0000afc0: 3c61 2063 6c61 7373 3d22 636f 6465 2068 SPQR\n-0000aff0: 3c2f 613e 266c 743b 3c61 2063 6c61 7373 <BCRSMatrix<T,A> &g\n-0000b040: 743b 2026 6774 3b3c 2f64 6976 3e0a 3c64 t; >
.\n-0000b060: 3c61 2069 643d 226c 3030 3332 3322 206e 323 {
.<\n-0000b0e0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000b0f0: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 32\n-0000b160: 343c 2f61 3e3c 2f73 7061 6e3e 2020 2020 4 \n-0000b170: 3c73 7061 6e20 636c 6173 733d 226b 6579 enum {value \n-0000b210: 3d20 3c73 7061 6e20 636c 6173 733d 226b = true};
.<\n-0000b270: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000b280: 6e6f 223e 2020 3332 353c 2f73 7061 6e3e no\"> 325
\n-0000b290: 2020 7d3b 3c2f 6469 763e 0a3c 6469 7620 };
.
326 \n-0000b2f0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000b340: 2033 3237 3c2f 7370 616e 3e20 203c 7370 327 template<type\n-0000b390: 6e61 6d65 3c2f 7370 616e 3e20 542c 203c name T, <\n-0000b3a0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000b3b0: 6f72 6422 3e74 7970 656e 616d 653c 2f73 ord\">typename A>
\n-0000b3d0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..
329 \n-0000b5a0: 207b 3c2f 6469 763e 0a3c 6469 7620 636c {
.
330 enum {\n-0000b690: 3c61 2063 6c61 7373 3d22 636f 6465 2068 value = <\n-0000b710: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000b720: 6f72 6422 3e74 7275 653c 2f73 7061 6e3e ord\">true\n-0000b730: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
.
331 }\n-0000b790: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n-0000b7e0: 2020 3333 323c 2f73 7061 6e3e 203c 2f64 332 .
\n-0000b860: 2033 3333 3c2f 613e 3c2f 7370 616e 3e20 333 \n-0000b870: 203c 7370 616e 2063 6c61 7373 3d22 6b65 struct SPQRCreator {
.
334 t\n-0000b970: 656d 706c 6174 653c 2f73 7061 6e3e 266c emplate&l\n-0000b980: 743b 3c73 7061 6e20 636c 6173 733d 226b t;class> s\n-0000b9c0: 7472 7563 7420 3c2f 7370 616e 3e3c 6120 truct isVali\n-0000ba00: 6442 6c6f 636b 3c2f 613e 203a 2073 7464 dBlock : std\n-0000ba10: 3a3a 6661 6c73 655f 7479 7065 7b7d 3b3c ::false_type{};<\n-0000ba20: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-0000ba70: 3333 353c 2f73 7061 6e3e 203c 2f64 6976 335 .
336<\n-0000bad0: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n-0000baf0: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-0000bb00: 6c74 3b3c 7370 616e 2063 6c61 7373 3d22 lt;typenam\n-0000bb20: 653c 2f73 7061 6e3e 2054 4c2c 203c 7370 e TL, typename M>
.<\n-0000bb60: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000bb70: 3e3c 6120 6964 3d22 6c30 3033 3337 2220 > 337 std::shar\n-0000bbc0: 6564 5f70 7472 266c 743b 4475 6e65 3a3a ed_ptr<Dune::\n-0000bbd0: 496e 7665 7273 654f 7065 7261 746f 7226 InverseOperator&\n-0000bbe0: 6c74 3b74 7970 656e 616d 6520 4475 6e65 lt;typename Dune\n-0000bbf0: 3a3a 5479 7065 4c69 7374 456c 656d 656e ::TypeListElemen\n-0000bc00: 7426 6c74 3b31 2c20 544c 2667 743b 3a3a t<1, TL>::\n-0000bc10: 7479 7065 2c3c 2f64 6976 3e0a 3c64 6976 type,
.<\n-0000bc50: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000bc60: 6e6f 223e 2020 3333 383c 2f73 7061 6e3e no\"> 338
\n-0000bc70: 2020 2020 2020 2020 2020 2020 2020 2020 \n-0000bc80: 2020 2020 2020 2020 2020 2020 2020 2020 \n-0000bc90: 2020 2020 2020 2020 2020 3c73 7061 6e20 \n-0000bcb0: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n-0000bcc0: 4475 6e65 3a3a 5479 7065 4c69 7374 456c Dune::TypeListEl\n-0000bcd0: 656d 656e 7426 6c74 3b32 2c20 544c 2667 ement<2, TL&g\n-0000bce0: 743b 3a3a 7479 7065 2667 743b 2667 743b t;::type>>\n-0000bcf0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n-0000bd40: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-0000bd50: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n-0000bd60: 2367 6136 3838 3461 3639 3066 3366 6164 #ga6884a690f3fad\n-0000bd70: 6439 6235 6538 6465 6633 3433 3335 3435 d9b5e8def3433545\n-0000bd80: 3966 3122 3e20 2033 3339 3c2f 613e 3c2f 9f1\"> 339 opera\n-0000bdf0: 746f 7228 2920 3c2f 613e 2854 4c20 3c73 tor() (TL /*tl*/, const M& m\n-0000bea0: 6174 3c2f 613e 2c20 3c73 7061 6e20 636c at, co\n-0000bec0: 6e73 743c 2f73 7061 6e3e 2044 756e 653a nst Dune:\n-0000bed0: 3a50 6172 616d 6574 6572 5472 6565 2661 :ParameterTree&a\n-0000bee0: 6d70 3b20 636f 6e66 6967 2c3c 2f64 6976 mp; config,.
340<\n-0000bf40: 2f73 7061 6e3e 2020 2020 2020 7374 643a /span> std:\n-0000bf50: 3a65 6e61 626c 655f 6966 5f74 266c 743b :enable_if_t<\n-0000bf60: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000bfb0: 2033 3431 3c2f 7370 616e 3e20 2020 2020 341 \n-0000bfc0: 2020 2020 2020 2020 2020 203c 6120 636c isValidB\n-0000c000: 6c6f 636b 3c2f 613e 266c 743b 3c73 7061 lock<typename Dune::TypeList\n-0000c040: 456c 656d 656e 7426 6c74 3b31 2c20 544c Element<1, TL\n-0000c050: 2667 743b 3a3a 7479 7065 3a3a 626c 6f63 >::type::bloc\n-0000c060: 6b5f 7479 7065 2667 743b 3a3a 7661 6c75 k_type>::valu\n-0000c070: 652c 3c73 7061 6e20 636c 6173 733d 226b e,int<\n-0000c090: 2f73 7061 6e3e 2667 743b 203d 2030 293c /span>> = 0)<\n-0000c0a0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000c0b0: 6f72 6422 3e20 636f 6e73 743c 2f73 7061 ord\"> const
.
342 {<\n-0000c140: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-0000c190: 3334 333c 2f73 7061 6e3e 2020 2020 2020 343 \n-0000c1a0: 3c73 7061 6e20 636c 6173 733d 226b 6579 int verbose = c\n-0000c1d0: 6f6e 6669 672e 6765 7428 3c73 7061 6e20 onfig.get("verb\n-0000c200: 6f73 6526 7175 6f74 3b3c 2f73 7061 6e3e ose"\n-0000c210: 2c20 3029 3b3c 2f64 6976 3e0a 3c64 6976 , 0);
.<\n-0000c250: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000c260: 6e6f 223e 2020 3334 343c 2f73 7061 6e3e no\"> 344\n-0000c270: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-0000c290: 7265 7475 726e 3c2f 7370 616e 3e20 7374 return st\n-0000c2a0: 643a 3a6d 616b 655f 7368 6172 6564 266c d::make_shared&l\n-0000c2b0: 743b 4475 6e65 3a3a 5350 5152 266c 743b t;Dune::SPQR<\n-0000c2c0: 4d26 6774 3b26 6774 3b28 3c61 2063 6c61 M>>(mat<\n-0000c320: 2f61 3e2c 7665 7262 6f73 6529 3b3c 2f64 /a>,verbose);.
34\n-0000c380: 353c 2f73 7061 6e3e 2020 2020 7d3c 2f64 5 }.
34\n-0000c3e0: 363c 2f73 7061 6e3e 203c 2f64 6976 3e0a 6
.\n-0000c3f0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n-0000c420: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 347 //\n-0000c460: 2073 6563 6f6e 6420 7665 7273 696f 6e20 second version \n-0000c470: 7769 7468 2053 4649 4e41 4520 746f 2076 with SFINAE to v\n-0000c480: 616c 6964 6174 6520 7468 6520 7465 6d70 alidate the temp\n-0000c490: 6c61 7465 2070 6172 616d 6574 6572 7320 late parameters \n-0000c4a0: 6f66 2053 5051 523c 2f73 7061 6e3e 3c2f of SPQR.
3\n-0000c500: 3438 3c2f 7370 616e 3e20 2020 203c 7370 48 template<type\n-0000c550: 6e61 6d65 3c2f 7370 616e 3e20 544c 2c20 name TL, \n-0000c560: 3c73 7061 6e20 636c 6173 733d 226b 6579 typename M>.
349<\n-0000c5e0: 2f73 7061 6e3e 2020 2020 7374 643a 3a73 /span> std::s\n-0000c5f0: 6861 7265 645f 7074 7226 6c74 3b44 756e hared_ptr<Dun\n-0000c600: 653a 3a49 6e76 6572 7365 4f70 6572 6174 e::InverseOperat\n-0000c610: 6f72 266c 743b 7479 7065 6e61 6d65 2044 or<typename D\n-0000c620: 756e 653a 3a54 7970 654c 6973 7445 6c65 une::TypeListEle\n-0000c630: 6d65 6e74 266c 743b 312c 2054 4c26 6774 ment<1, TL>\n-0000c640: 3b3a 3a74 7970 652c 3c2f 6469 763e 0a3c ;::type,
.<\n-0000c650: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000c660: 3e3c 6120 6964 3d22 6c30 3033 3530 2220 > 350 \n-0000c6b0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-0000c6c0: 2020 2020 2020 2020 2020 2020 203c 7370 typename Dune::TypeLis\n-0000c700: 7445 6c65 6d65 6e74 266c 743b 322c 2054 tElement<2, T\n-0000c710: 4c26 6774 3b3a 3a74 7970 6526 6774 3b26 L>::type>&\n-0000c720: 6774 3b3c 2f64 6976 3e0a 3c64 6976 2063 gt;
.
351 op\n-0000c820: 6572 6174 6f72 2829 203c 2f61 3e28 544c erator() (TL\n-0000c830: 203c 7370 616e 2063 6c61 7373 3d22 636f /*tl*/, cons\n-0000c870: 743c 2f73 7061 6e3e 204d 2661 6d70 3b20 t M& \n-0000c880: 3c73 7061 6e20 636c 6173 733d 2263 6f6d /*mat*/, cons\n-0000c8c0: 743c 2f73 7061 6e3e 2044 756e 653a 3a50 t Dune::P\n-0000c8d0: 6172 616d 6574 6572 5472 6565 2661 6d70 arameterTree&\n-0000c8e0: 3b20 3c73 7061 6e20 636c 6173 733d 2263 ; /*config\n-0000c900: 2a2f 3c2f 7370 616e 3e2c 3c2f 6469 763e */,
\n-0000c910: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n-0000c940: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 352 std::\n-0000c970: 656e 6162 6c65 5f69 665f 7426 6c74 3b21 enable_if_t<!\n-0000c980: 3c61 2063 6c61 7373 3d22 636f 6465 2068 isV\n-0000c9b0: 616c 6964 426c 6f63 6b3c 2f61 3e26 6c74 alidBlock<\n-0000c9c0: 3b3c 7370 616e 2063 6c61 7373 3d22 6b65 ;typename<\n-0000c9e0: 2f73 7061 6e3e 2044 756e 653a 3a54 7970 /span> Dune::Typ\n-0000c9f0: 654c 6973 7445 6c65 6d65 6e74 266c 743b eListElement<\n-0000ca00: 312c 2054 4c26 6774 3b3a 3a74 7970 653a 1, TL>::type:\n-0000ca10: 3a62 6c6f 636b 5f74 7970 6526 6774 3b3a :block_type>:\n-0000ca20: 3a76 616c 7565 2c3c 7370 616e 2063 6c61 :value,int> \n-0000ca50: 3d20 3029 3c73 7061 6e20 636c 6173 733d = 0) const\n-0000ca70: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
.\n-0000ca90: 3c61 2069 643d 226c 3030 3335 3322 206e 353 {
.
354 \n-0000cb50: 2020 2020 2044 554e 455f 5448 524f 5728 DUNE_THROW(\n-0000cb60: 3c61 2063 6c61 7373 3d22 636f 6465 2068 Unsu\n-0000cb90: 7070 6f72 7465 6454 7970 653c 2f61 3e2c pportedType,\n-0000cba0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n-0000cbf0: 2033 3535 3c2f 7370 616e 3e20 2020 2020 355 \n-0000cc00: 2020 203c 7370 616e 2063 6c61 7373 3d22 &\n-0000cc20: 7175 6f74 3b55 6e73 7570 706f 7274 6564 quot;Unsupported\n-0000cc30: 2054 7970 6520 696e 2053 5051 5220 286f Type in SPQR (o\n-0000cc40: 6e6c 7920 646f 7562 6c65 2061 6e64 2073 nly double and s\n-0000cc50: 7464 3a3a 636f 6d70 6c65 7826 6c74 3b64 td::complex<d\n-0000cc60: 6f75 626c 6526 6774 3b20 7375 7070 6f72 ouble> suppor\n-0000cc70: 7465 6429 2671 756f 743b 3c2f 7370 616e ted)");
.
356 \n-0000cce0: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
.
357 \n-0000cd40: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
..\n-0000cea0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n-0000ced0: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 359 // s\n-0000cf10: 7464 3a3a 636f 6d70 6c65 7820 6973 2074 td::complex is t\n-0000cf20: 656d 706f 7261 7279 2064 6973 6162 6c65 emporary disable\n-0000cf30: 642c 2062 6563 6175 7365 2069 7420 6661 d, because it fa\n-0000cf40: 696c 7320 6966 206c 6962 632b 2b20 6973 ils if libc++ is\n-0000cf50: 2075 7365 643c 2f73 7061 6e3e 3c2f 6469 used.
360\n-0000cfb0: 3c2f 7370 616e 3e20 203c 7370 616e 2063 /\n-0000cfd0: 2f74 656d 706c 6174 6526 6c74 3b26 6774 /template<>\n-0000cfe0: 3b20 7374 7275 6374 2053 5051 5243 7265 ; struct SPQRCre\n-0000cff0: 6174 6f72 3a3a 6973 5661 6c69 644d 6174 ator::isValidMat\n-0000d000: 7269 7842 6c6f 636b 266c 743b 4669 656c rixBlock<Fiel\n-0000d010: 644d 6174 7269 7826 6c74 3b73 7464 3a3a dMatrix<std::\n-0000d020: 636f 6d70 6c65 7826 6c74 3b64 6f75 626c complex<doubl\n-0000d030: 6526 6774 3b2c 312c 3126 6774 3b26 6774 e>,1,1>>\n-0000d040: 3b20 3a20 7374 643a 3a74 7275 655f 7479 ; : std::true_ty\n-0000d050: 7065 7b7d 3b3c 2f73 7061 6e3e 3c2f 6469 pe{};..
\n-0000d240: 2033 3632 3c2f 7370 616e 3e20 3c2f 6469 362 .
363\n-0000d2a0: 3c2f 7370 616e 3e7d 203c 7370 616e 2063 } /\n-0000d2c0: 2f20 656e 6420 6e61 6d65 7370 6163 6520 / end namespace \n-0000d2d0: 4475 6e65 3c2f 7370 616e 3e3c 2f64 6976 Dune.
364<\n-0000d330: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
.\n-0000d350: 3c61 2069 643d 226c 3030 3336 3522 206e 365
.
366#endif \n-0000d410: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 //H\n-0000d430: 4156 455f 5355 4954 4553 5041 5253 455f AVE_SUITESPARSE_\n-0000d440: 5350 5152 3c2f 7370 616e 3e3c 2f64 6976 SPQR.
367<\n-0000d4a0: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#endif <\n-0000d4d0: 7370 616e 2063 6c61 7373 3d22 636f 6d6d span class=\"comm\n-0000d4e0: 656e 7422 3e2f 2f44 554e 455f 4953 544c ent\">//DUNE_ISTL\n-0000d4f0: 5f53 5051 525f 4848 3c2f 7370 616e 3e3c _SPQR_HH<\n-0000d500: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
Tem\n-0000d580: 706c 6174 6573 2063 6861 7261 6374 6572 plates character\n-0000d590: 697a 696e 6720 7468 6520 7479 7065 206f izing the type o\n-0000d5a0: 6620 6120 736f 6c76 6572 2e3c 2f64 6976 f a solver.
.
<\n-0000d5f0: 6120 6872 6566 3d22 6130 3030 3536 2e68 a href=\"a00056.h\n-0000d600: 746d 6c22 3e73 6f6c 7665 7273 2e68 683c tml\">solvers.hh<\n-0000d610: 2f61 3e3c 2f64 6976 3e3c 6469 7620 636c /a>
Impl\n-0000d630: 656d 656e 7461 7469 6f6e 7320 6f66 2074 ementations of t\n-0000d640: 6865 2069 6e76 6572 7365 206f 7065 7261 he inverse opera\n-0000d650: 746f 7220 696e 7465 7266 6163 652e 3c2f tor interface.
..
\n-0000d710: 3c61 2068 7265 663d 2261 3030 3232 372e bccsmatrix\n-0000d730: 696e 6974 6961 6c69 7a65 722e 6868 3c2f initializer.hh
.<\n-0000d750: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000d760: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n-0000d770: 5f67 6130 6339 3334 6263 6233 3535 3736 _ga0c934bcb35576\n-0000d780: 3838 3661 3366 3737 3134 6431 3062 3330 886a3f7714d10b30\n-0000d790: 3834 3122 3e3c 6469 7620 636c 6173 733d 841\">
vi\n-0000d850: 7274 7561 6c20 7e53 5051 5228 293c 2f64 rtual ~SPQR()
Destructor\n-0000d880: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
Def\n-0000d8a0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n-0000d8b0: 722e 6868 3a31 3437 3c2f 6469 763e 3c2f r.hh:147
.
<\n-0000d920: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n-0000d930: 746d 6c23 6761 3234 6637 3563 6262 3335 tml#ga24f75cbb35\n-0000d940: 3433 3036 3732 6239 3738 3962 6536 3236 430672b9789be626\n-0000d950: 3663 3539 6532 223e 4475 6e65 3a3a 5350 6c59e2\">Dune::SP\n-0000d960: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n-0000d970: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n-0000d980: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n-0000d990: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n-0000d9a0: 3a53 5051 523c 2f61 3e3c 2f64 6976 3e3c :SPQR
<\n-0000d9b0: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n-0000d9c0: 6922 3e53 5051 5228 636f 6e73 7420 4d61 i\">SPQR(const Ma\n-0000d9d0: 7472 6978 2026 616d 703b 6d61 7472 6978 trix &matrix\n-0000d9e0: 2c20 696e 7420 7665 7262 6f73 652c 2062 , int verbose, b\n-0000d9f0: 6f6f 6c29 3c2f 6469 763e 3c64 6976 2063 ool)
Con\n-0000da10: 7374 7275 6374 6f72 2066 6f72 2063 6f6d structor for com\n-0000da20: 7061 7469 6269 6c69 7479 2077 6974 6820 patibility with \n-0000da30: 5375 7065 724c 5520 7374 616e 6461 7264 SuperLU standard\n-0000da40: 2063 6f6e 7374 7275 6374 6f72 2e3c 2f64 constructor.
Definit\n-0000da70: 696f 6e3a 3c2f 623e 2073 7071 722e 6868 ion: spqr.hh\n-0000da80: 3a31 3133 3c2f 6469 763e 3c2f 6469 763e :113
\n-0000da90: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
<\n-0000db80: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n-0000db90: 6922 3e76 6972 7475 616c 2053 6f6c 7665 i\">virtual Solve\n-0000dba0: 7243 6174 6567 6f72 793a 3a43 6174 6567 rCategory::Categ\n-0000dbb0: 6f72 7920 6361 7465 676f 7279 2829 2063 ory category() c\n-0000dbc0: 6f6e 7374 3c2f 6469 763e 3c64 6976 2063 onst
Cat\n-0000dbe0: 6567 6f72 7920 6f66 2074 6865 2073 6f6c egory of the sol\n-0000dbf0: 7665 7220 2873 6565 2053 6f6c 7665 7243 ver (see SolverC\n-0000dc00: 6174 6567 6f72 793a 3a43 6174 6567 6f72 ategory::Categor\n-0000dc10: 7929 3c2f 6469 763e 3c64 6976 2063 6c61 y)
De\n-0000dc30: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n-0000dc40: 7172 2e68 683a 3832 3c2f 6469 763e 3c2f qr.hh:82
.
<\n-0000dcb0: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n-0000dcc0: 746d 6c23 6761 3332 6330 6433 3532 6532 tml#ga32c0d352e2\n-0000dcd0: 6239 3564 3038 3836 3162 6633 3833 3139 b95d08861bf38319\n-0000dce0: 6230 3537 6165 223e 4475 6e65 3a3a 5350 b057ae\">Dune::SP\n-0000dcf0: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n-0000dd00: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n-0000dd10: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n-0000dd20: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n-0000dd30: 3a67 6574 496e 7465 726e 616c 4d61 7472 :getInternalMatr\n-0000dd40: 6978 3c2f 613e 3c2f 6469 763e 3c64 6976 ix
\n-0000dd60: 5350 5152 4d61 7472 6978 2026 616d 703b SPQRMatrix &\n-0000dd70: 2067 6574 496e 7465 726e 616c 4d61 7472 getInternalMatr\n-0000dd80: 6978 2829 3c2f 6469 763e 3c64 6976 2063 ix()
Ret\n-0000dda0: 7572 6e20 7468 6520 636f 6c75 6d6e 2063 urn the column c\n-0000ddb0: 6f70 7072 6573 7365 6420 6d61 7472 6978 oppressed matrix\n-0000ddc0: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
Def\n-0000dde0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n-0000ddf0: 722e 6868 3a32 3536 3c2f 6469 763e 3c2f r.hh:256
.
<\n-0000de60: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n-0000de70: 746d 6c23 6761 3430 6563 3262 3365 6131 tml#ga40ec2b3ea1\n-0000de80: 3662 3165 3231 3464 3338 6235 3636 6634 6b1e214d38b566f4\n-0000de90: 6430 3763 6630 223e 4475 6e65 3a3a 5350 d07cf0\">Dune::SP\n-0000dea0: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n-0000deb0: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n-0000dec0: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n-0000ded0: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n-0000dee0: 3a73 6574 4d61 7472 6978 3c2f 613e 3c2f :setMatrix
void set\n-0000df10: 4d61 7472 6978 2863 6f6e 7374 204d 6174 Matrix(const Mat\n-0000df20: 7269 7820 2661 6d70 3b6d 6174 7269 7829 rix &matrix)\n-0000df30: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
Initial\n-0000df50: 697a 6520 6461 7461 2066 726f 6d20 6769 ize data from gi\n-0000df60: 7665 6e20 6d61 7472 6978 2e3c 2f64 6976 ven matrix.
Definitio\n-0000df90: 6e3a 3c2f 623e 2073 7071 722e 6868 3a32 n: spqr.hh:2\n-0000dfa0: 3030 3c2f 6469 763e 3c2f 6469 763e 0a3c 00
.<\n-0000dfb0: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000dfc0: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n-0000dfd0: 5f67 6134 6162 3461 3166 3431 3935 3532 _ga4ab4a1f419552\n-0000dfe0: 3332 3864 3539 3437 3237 3632 3765 3639 328d594727627e69\n-0000dff0: 3663 6222 3e3c 6469 7620 636c 6173 733d 6cb\">DUNE_REGISTER_D\n-0000e090: 4952 4543 545f 534f 4c56 4552 2826 7175 IRECT_SOLVER(&qu\n-0000e0a0: 6f74 3b6c 646c 2671 756f 743b 2c20 4475 ot;ldl", Du\n-0000e0b0: 6e65 3a3a 4c44 4c43 7265 6174 6f72 2829 ne::LDLCreator()\n-0000e0c0: 293c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 )
.
Dune::SPQR< \n-0000e170: 4243 5253 4d61 7472 6978 266c 743b 2046 BCRSMatrix< F\n-0000e180: 6965 6c64 4d61 7472 6978 266c 743b 2054 ieldMatrix< T\n-0000e190: 2c20 6e2c 206d 2026 6774 3b2c 2041 2026 , n, m >, A &\n-0000e1a0: 6774 3b20 2667 743b 3a3a 4d61 7472 6978 gt; >::Matrix\n-0000e1b0: 496e 6974 6961 6c69 7a65 723c 2f61 3e3c Initializer<\n-0000e1c0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
ISTL::I\n-0000e1e0: 6d70 6c3a 3a42 4343 534d 6174 7269 7849 mpl::BCCSMatrixI\n-0000e1f0: 6e69 7469 616c 697a 6572 266c 743b 2042 nitializer< B\n-0000e200: 4352 534d 6174 7269 7826 6c74 3b20 4669 CRSMatrix< Fi\n-0000e210: 656c 644d 6174 7269 7826 6c74 3b20 542c eldMatrix< T,\n-0000e220: 206e 2c20 6d20 2667 743b 2c20 4120 2667 n, m >, A &g\n-0000e230: 743b 2c20 696e 7420 2667 743b 204d 6174 t;, int > Mat\n-0000e240: 7269 7849 6e69 7469 616c 697a 6572 3c2f rixInitializer
Type of a\n-0000e270: 6e20 6173 736f 6369 6174 6564 2069 6e69 n associated ini\n-0000e280: 7469 616c 697a 6572 2063 6c61 7373 2e3c tializer class.<\n-0000e290: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Defin\n-0000e2b0: 6974 696f 6e3a 3c2f 623e 2073 7071 722e ition: spqr.\n-0000e2c0: 6868 3a37 353c 2f64 6976 3e3c 2f64 6976 hh:75
.D\n-0000e3f0: 6566 6175 6c74 2063 6f6e 7374 7275 6374 efault construct\n-0000e400: 6f72 2e3c 2f64 6976 3e3c 6469 7620 636c or.
D\n-0000e420: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n-0000e430: 7071 722e 6868 3a31 3337 3c2f 6469 763e pqr.hh:137
\n-0000e440: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
Dune::\n-0000e4e0: 5350 5152 4372 6561 746f 723a 3a6f 7065 SPQRCreator::ope\n-0000e4f0: 7261 746f 7228 293c 2f61 3e3c 2f64 6976 rator()
std::shared\n-0000e520: 5f70 7472 266c 743b 2044 756e 653a 3a49 _ptr< Dune::I\n-0000e530: 6e76 6572 7365 4f70 6572 6174 6f72 266c nverseOperator&l\n-0000e540: 743b 2074 7970 656e 616d 6520 4475 6e65 t; typename Dune\n-0000e550: 3a3a 5479 7065 4c69 7374 456c 656d 656e ::TypeListElemen\n-0000e560: 7426 6c74 3b20 312c 2054 4c20 2667 743b t< 1, TL >\n-0000e570: 3a3a 7479 7065 2c20 7479 7065 6e61 6d65 ::type, typename\n-0000e580: 2044 756e 653a 3a54 7970 654c 6973 7445 Dune::TypeListE\n-0000e590: 6c65 6d65 6e74 266c 743b 2032 2c20 544c lement< 2, TL\n-0000e5a0: 2026 6774 3b3a 3a74 7970 6520 2667 743b >::type >\n-0000e5b0: 2026 6774 3b20 6f70 6572 6174 6f72 2829 > operator()\n-0000e5c0: 2854 4c2c 2063 6f6e 7374 204d 2026 616d (TL, const M &am\n-0000e5d0: 703b 6d61 742c 2063 6f6e 7374 2044 756e p;mat, const Dun\n-0000e5e0: 653a 3a50 6172 616d 6574 6572 5472 6565 e::ParameterTree\n-0000e5f0: 2026 616d 703b 636f 6e66 6967 2c20 7374 &config, st\n-0000e600: 643a 3a65 6e61 626c 655f 6966 5f74 266c d::enable_if_t&l\n-0000e610: 743b 2069 7356 616c 6964 426c 6f63 6b26 t; isValidBlock&\n-0000e620: 6c74 3b20 7479 7065 6e61 6d65 2044 756e lt; typename Dun\n-0000e630: 653a 3a54 7970 654c 6973 7445 6c65 6d65 e::TypeListEleme\n-0000e640: 6e74 266c 743b 2031 2c20 544c 2026 6774 nt< 1, TL >\n-0000e650: 3b3a 3a74 7970 653a 3a62 6c6f 636b 5f74 ;::type::block_t\n-0000e660: 7970 6520 2667 743b 3a3a 7661 6c75 652c ype >::value,\n-0000e670: 2069 6e74 2026 6774 3b3d 3029 2063 6f6e int >=0) con\n-0000e680: 7374 3c2f 6469 763e 3c64 6976 2063 6c61 st
De\n-0000e6a0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n-0000e6b0: 7172 2e68 683a 3333 393c 2f64 6976 3e3c qr.hh:339
<\n-0000e6c0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n-0000e7b0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
const char *\n-0000e7d0: 206e 616d 6528 293c 2f64 6976 3e3c 6469 name()
\n-0000e7f0: 4765 7420 6d65 7468 6f64 206e 616d 652e Get method name.\n-0000e800: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
Defi\n-0000e820: 6e69 7469 6f6e 3a3c 2f62 3e20 7370 7172 nition: spqr\n-0000e830: 2e68 683a 3237 353c 2f64 6976 3e3c 2f64 .hh:275
.
Dune::SPQ\n-0000e8e0: 5226 6c74 3b20 4243 5253 4d61 7472 6978 R< BCRSMatrix\n-0000e8f0: 266c 743b 2046 6965 6c64 4d61 7472 6978 < FieldMatrix\n-0000e900: 266c 743b 2054 2c20 6e2c 206d 2026 6774 < T, n, m >\n-0000e910: 3b2c 2041 2026 6774 3b20 2667 743b 3a3a ;, A > >::\n-0000e920: 6765 7446 6163 746f 7269 7a61 7469 6f6e getFactorization\n-0000e930: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
Su\n-0000e950: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n-0000e960: 6f72 697a 6174 696f 6e26 6c74 3b20 5420 orization< T \n-0000e970: 2667 743b 202a 2067 6574 4661 6374 6f72 > * getFactor\n-0000e980: 697a 6174 696f 6e28 293c 2f64 6976 3e3c ization()
<\n-0000e990: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n-0000e9a0: 223e 5265 7475 726e 2074 6865 206d 6174 \">Return the mat\n-0000e9b0: 7269 7820 6661 6374 6f72 697a 6174 696f rix factorizatio\n-0000e9c0: 6e2e 3c2f 6469 763e 3c64 6976 2063 6c61 n.
De\n-0000e9e0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n-0000e9f0: 7172 2e68 683a 3234 373c 2f64 6976 3e3c qr.hh:247
<\n-0000ea00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>..
IST\n-0000ecb0: 4c3a 3a49 6d70 6c3a 3a42 4343 534d 6174 L::Impl::BCCSMat\n-0000ecc0: 7269 7826 6c74 3b20 542c 2069 6e74 2026 rix< T, int &\n-0000ecd0: 6774 3b20 5350 5152 4d61 7472 6978 3c2f gt; SPQRMatrix
The corre\n-0000ed00: 7370 6f6e 6469 6e67 2053 7570 6572 4c55 sponding SuperLU\n-0000ed10: 204d 6174 7269 7820 7479 7065 2e3c 2f64 Matrix type.
Definit\n-0000ed40: 696f 6e3a 3c2f 623e 2073 7071 722e 6868 ion: spqr.hh\n-0000ed50: 3a37 333c 2f64 6976 3e3c 2f64 6976 3e0a :73
.\n-0000ed60: 3c64 6976 2063 6c61 7373 3d22 7474 6322
v\n-0000ee60: 6972 7475 616c 2076 6f69 6420 6170 706c irtual void appl\n-0000ee70: 7928 646f 6d61 696e 5f74 7970 6520 2661 y(domain_type &a\n-0000ee80: 6d70 3b78 2c20 7261 6e67 655f 7479 7065 mp;x, range_type\n-0000ee90: 2026 616d 703b 622c 2064 6f75 626c 6520 &b, double \n-0000eea0: 7265 6475 6374 696f 6e2c 2049 6e76 6572 reduction, Inver\n-0000eeb0: 7365 4f70 6572 6174 6f72 5265 7375 6c74 seOperatorResult\n-0000eec0: 2026 616d 703b 7265 7329 3c2f 6469 763e &res)
\n-0000eed0: 3c64 6976 2063 6c61 7373 3d22 7474 646f
apply inverse\n-0000eef0: 206f 7065 7261 746f 722c 2077 6974 6820 operator, with \n-0000ef00: 6769 7665 6e20 636f 6e76 6572 6765 6e63 given convergenc\n-0000ef10: 6520 6372 6974 6572 6961 2e3c 2f64 6976 e criteria.
Definitio\n-0000ef40: 6e3a 3c2f 623e 2073 7071 722e 6868 3a31 n: spqr.hh:1\n-0000ef50: 3931 3c2f 6469 763e 3c2f 6469 763e 0a3c 91
.<\n-0000ef60: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000ef70: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n-0000ef80: 5f67 6139 3237 3966 6633 3139 3530 3134 _ga9279ff3195014\n-0000ef90: 3136 6338 6165 6630 3462 6565 6562 3362 16c8aef04beeeb3b\n-0000efa0: 3366 3922 3e3c 6469 7620 636c 6173 733d 3f9\">Free allocated \n-0000f090: 7370 6163 652e 3c2f 6469 763e 3c64 6976 space.
<\n-0000f0b0: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:265
.
\n-0000f120: 3c64 6976 2063 6c61 7373 3d22 7474 6e61
Dun\n-0000f170: 653a 3a53 5051 5226 6c74 3b20 4243 5253 e::SPQR< BCRS\n-0000f180: 4d61 7472 6978 266c 743b 2046 6965 6c64 Matrix< Field\n-0000f190: 4d61 7472 6978 266c 743b 2054 2c20 6e2c Matrix< T, n,\n-0000f1a0: 206d 2026 6774 3b2c 2041 2026 6774 3b20 m >, A > \n-0000f1b0: 2667 743b 3a3a 5350 5152 3c2f 613e 3c2f >::SPQR
SPQR(con\n-0000f1e0: 7374 204d 6174 7269 7820 2661 6d70 3b6d st Matrix &m\n-0000f1f0: 6174 7269 782c 2063 6f6e 7374 2050 6172 atrix, const Par\n-0000f200: 616d 6574 6572 5472 6565 2026 616d 703b ameterTree &\n-0000f210: 636f 6e66 6967 293c 2f64 6976 3e3c 6469 config)
\n-0000f230: 436f 6e73 7472 7563 7473 2074 6865 2053 Constructs the S\n-0000f240: 5051 5220 736f 6c76 6572 2e3c 2f64 6976 PQR solver.
Definitio\n-0000f270: 6e3a 3c2f 623e 2073 7071 722e 6868 3a31 n: spqr.hh:1\n-0000f280: 3332 3c2f 6469 763e 3c2f 6469 763e 0a3c 32
.<\n-0000f290: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000f2a0: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n-0000f2b0: 5f67 6163 3735 6364 3761 3564 3336 3436 _gac75cd7a5d3646\n-0000f2c0: 6638 3537 3330 6637 3435 6432 3466 3665 f85730f745d24f6e\n-0000f2d0: 6561 3122 3e3c 6469 7620 636c 6173 733d ea1\"><\n-0000f380: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n-0000f390: 6922 3e44 756e 653a 3a42 6c6f 636b 5665 i\">Dune::BlockVe\n-0000f3a0: 6374 6f72 266c 743b 2046 6965 6c64 5665 ctor< FieldVe\n-0000f3b0: 6374 6f72 266c 743b 2054 2c20 6e20 2667 ctor< T, n &g\n-0000f3c0: 743b 2c20 7479 7065 6e61 6d65 2073 7464 t;, typename std\n-0000f3d0: 3a3a 616c 6c6f 6361 746f 725f 7472 6169 ::allocator_trai\n-0000f3e0: 7473 266c 743b 2041 2026 6774 3b3a 3a74 ts< A >::t\n-0000f3f0: 656d 706c 6174 6520 7265 6269 6e64 5f61 emplate rebind_a\n-0000f400: 6c6c 6f63 266c 743b 2046 6965 6c64 5665 lloc< FieldVe\n-0000f410: 6374 6f72 266c 743b 2054 2c20 6e20 2667 ctor< T, n &g\n-0000f420: 743b 2026 6774 3b20 2667 743b 2072 616e t; > > ran\n-0000f430: 6765 5f74 7970 653c 2f64 6976 3e3c 6469 ge_type
\n-0000f450: 5468 6520 7479 7065 206f 6620 7468 6520 The type of the \n-0000f460: 7261 6e67 6520 6f66 2074 6865 2073 6f6c range of the sol\n-0000f470: 7665 722e 3c2f 6469 763e 3c64 6976 2063 ver.
\n-0000f490: 4465 6669 6e69 7469 6f6e 3a3c 2f62 3e20 Definition: \n-0000f4a0: 7370 7172 2e68 683a 3739 3c2f 6469 763e spqr.hh:79
\n-0000f4b0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.<\n-0000f640: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n-0000f870: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
\n-0000f970: 7669 7274 7561 6c20 766f 6964 2061 7070 virtual void app\n-0000f980: 6c79 2864 6f6d 6169 6e5f 7479 7065 2026 ly(domain_type &\n-0000f990: 616d 703b 782c 2072 616e 6765 5f74 7970 amp;x, range_typ\n-0000f9a0: 6520 2661 6d70 3b62 2c20 496e 7665 7273 e &b, Invers\n-0000f9b0: 654f 7065 7261 746f 7252 6573 756c 7420 eOperatorResult \n-0000f9c0: 2661 6d70 3b72 6573 293c 2f64 6976 3e3c &res)
<\n-0000f9d0: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n-0000f9e0: 223e 4170 706c 7920 696e 7665 7273 6520 \">Apply inverse \n-0000f9f0: 6f70 6572 6174 6f72 2c2e 3c2f 6469 763e operator,.
\n-0000fa00: 3c64 6976 2063 6c61 7373 3d22 7474 6465
Definition\n-0000fa20: 3a3c 2f62 3e20 7370 7172 2e68 683a 3135 : spqr.hh:15\n-0000fa30: 353c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 5
.void setOption(\n-0000fb50: 756e 7369 676e 6564 2069 6e74 206f 7074 unsigned int opt\n-0000fb60: 696f 6e2c 2064 6f75 626c 6520 7661 6c75 ion, double valu\n-0000fb70: 6529 3c2f 6469 763e 3c64 6976 2063 6c61 e)
De\n-0000fb90: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n-0000fba0: 7172 2e68 683a 3139 363c 2f64 6976 3e3c qr.hh:196
<\n-0000fbb0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n-0000fca0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
SPQR(const M\n-0000fcc0: 6174 7269 7820 2661 6d70 3b6d 6174 7269 atrix &matri\n-0000fcd0: 782c 2069 6e74 2076 6572 626f 7365 3d30 x, int verbose=0\n-0000fce0: 293c 2f64 6976 3e3c 6469 7620 636c 6173 )
Constr\n-0000fd00: 7563 7420 6120 736f 6c76 6572 206f 626a uct a solver obj\n-0000fd10: 6563 7420 6672 6f6d 2061 2042 4352 534d ect from a BCRSM\n-0000fd20: 6174 7269 782e 3c2f 6469 763e 3c64 6976 atrix.
<\n-0000fd40: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:95
.
<\n-0000fdb0: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n-0000fdc0: 6522 3e3c 6120 6872 6566 3d22 6130 3032 e\">mat<\n-0000fe00: 2f61 3e3c 2f64 6976 3e3c 6469 7620 636c /a>
Mat\n-0000fe20: 7269 7820 2661 6d70 3b20 6d61 743c 2f64 rix & mat
Definit\n-0000fe50: 696f 6e3a 3c2f 623e 206d 6174 7269 786d ion: matrixm\n-0000fe60: 6174 7269 782e 6868 3a33 3437 3c2f 6469 atrix.hh:347
.
\n-0000feb0: 3c61 2068 7265 663d 2261 3030 3234 392e Dune
Defini\n-0000fef0: 7469 6f6e 3a3c 2f62 3e20 616c 6c6f 6361 tion: alloca\n-0000ff00: 746f 722e 6868 3a31 313c 2f64 6976 3e3c tor.hh:11
<\n-0000ff10: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
<\n-0000ff70: 6120 6872 6566 3d22 6130 3032 3439 2e68 a href=\"a00249.h\n-0000ff80: 746d 6c23 6133 3466 3735 6335 3865 3635 tml#a34f75c58e65\n-0000ff90: 3638 3233 6235 3865 3361 6631 3763 3039 6823b58e3af17c09\n-0000ffa0: 6662 3033 6522 3e44 756e 653a 3a67 6574 fb03e\">Dune::get\n-0000ffb0: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
Pr\n-0000ffd0: 6f70 6572 7479 4d61 7054 7970 6553 656c opertyMapTypeSel\n-0000ffe0: 6563 746f 7226 6c74 3b20 416d 673a 3a56 ector< Amg::V\n-0000fff0: 6572 7465 7856 6973 6974 6564 5461 672c ertexVisitedTag,\n-00010000: 2041 6d67 3a3a 5072 6f70 6572 7469 6573 Amg::Properties\n-00010010: 4772 6170 6826 6c74 3b20 472c 2041 6d67 Graph< G, Amg\n-00010020: 3a3a 5665 7274 6578 5072 6f70 6572 7469 ::VertexProperti\n-00010030: 6573 2c20 4550 2c20 564d 2c20 454d 2026 es, EP, VM, EM &\n-00010040: 6774 3b20 2667 743b 3a3a 5479 7065 2067 gt; >::Type g\n-00010050: 6574 2863 6f6e 7374 2041 6d67 3a3a 5665 et(const Amg::Ve\n-00010060: 7274 6578 5669 7369 7465 6454 6167 2026 rtexVisitedTag &\n-00010070: 616d 703b 7461 672c 2041 6d67 3a3a 5072 amp;tag, Amg::Pr\n-00010080: 6f70 6572 7469 6573 4772 6170 6826 6c74 opertiesGraph<\n-00010090: 3b20 472c 2041 6d67 3a3a 5665 7274 6578 ; G, Amg::Vertex\n-000100a0: 5072 6f70 6572 7469 6573 2c20 4550 2c20 Properties, EP, \n-000100b0: 564d 2c20 454d 2026 6774 3b20 2661 6d70 VM, EM > &\n-000100c0: 3b67 7261 7068 293c 2f64 6976 3e3c 6469 ;graph)
\n-000100e0: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: dependency.hh\n-00010100: 3a32 3933 3c2f 6469 763e 3c2f 6469 763e :293
\n-00010110: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
\n-00010190: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: matrixutils.h\n-000101b0: 683a 3231 313c 2f64 6976 3e3c 2f64 6976 h:211
.
A sp\n-00010240: 6172 7365 2062 6c6f 636b 206d 6174 7269 arse block matri\n-00010250: 7820 7769 7468 2063 6f6d 7072 6573 7365 x with compresse\n-00010260: 6420 726f 7720 7374 6f72 6167 652e 3c2f d row storage.
Defini\n-00010290: 7469 6f6e 3a3c 2f62 3e20 6263 7273 6d61 tion: bcrsma\n-000102a0: 7472 6978 2e68 683a 3436 363c 2f64 6976 trix.hh:466
.
Dune::B\n-00010350: 4352 534d 6174 7269 783a 3a4d 3c2f 613e CRSMatrix::M\n-00010360: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
size_t\n-00010380: 7970 6520 4d28 2920 636f 6e73 743c 2f64 ype M() const
number of \n-000103b0: 636f 6c75 6d6e 7320 2863 6f75 6e74 6564 columns (counted\n-000103c0: 2069 6e20 626c 6f63 6b73 293c 2f64 6976 in blocks)
Definitio\n-000103f0: 6e3a 3c2f 623e 2062 6372 736d 6174 7269 n: bcrsmatri\n-00010400: 782e 6868 3a31 3937 383c 2f64 6976 3e3c x.hh:1978
<\n-00010410: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
<\n-00010470: 6120 6872 6566 3d22 6130 3131 3532 2e68 a href=\"a01152.h\n-00010480: 746d 6c23 6165 3634 3063 3466 6335 6139 tml#ae640c4fc5a9\n-00010490: 3334 3362 3838 3336 6233 3037 3333 6239 343b8836b30733b9\n-000104a0: 3866 3962 3422 3e44 756e 653a 3a42 4352 8f9b4\">Dune::BCR\n-000104b0: 534d 6174 7269 783a 3a4e 3c2f 613e 3c2f SMatrix::N
size_typ\n-000104e0: 6520 4e28 2920 636f 6e73 743c 2f64 6976 e N() const
number of ro\n-00010510: 7773 2028 636f 756e 7465 6420 696e 2062 ws (counted in b\n-00010520: 6c6f 636b 7329 3c2f 6469 763e 3c64 6976 locks)
<\n-00010540: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: bcrsmatrix.hh:\n-00010560: 3139 3732 3c2f 6469 763e 3c2f 6469 763e 1972
\n-00010570: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
.\n-00010680: 3c64 6976 2063 6c61 7373 3d22 7474 6e61 <\n-000106d0: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n-000106e0: 223e 5365 7175 656e 7469 616c 206f 7665 \">Sequential ove\n-000106f0: 726c 6170 7069 6e67 2053 6368 7761 727a rlapping Schwarz\n-00010700: 2070 7265 636f 6e64 6974 696f 6e65 722e preconditioner.\n-00010710: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
Defi\n-00010730: 6e69 7469 6f6e 3a3c 2f62 3e20 6f76 6572 nition: over\n-00010740: 6c61 7070 696e 6773 6368 7761 727a 2e68 lappingschwarz.h\n-00010750: 683a 3735 353c 2f64 6976 3e3c 2f64 6976 h:755
.
D\n-000107b0: 756e 653a 3a53 6571 4f76 6572 6c61 7070 une::SeqOverlapp\n-000107c0: 696e 6753 6368 7761 727a 4173 7365 6d62 ingSchwarzAssemb\n-000107d0: 6c65 7248 656c 7065 723c 2f61 3e3c 2f64 lerHelper
Definit\n-00010800: 696f 6e3a 3c2f 623e 206f 7665 726c 6170 ion: overlap\n-00010810: 7069 6e67 7363 6877 6172 7a2e 6868 3a36 pingschwarz.hh:6\n-00010820: 3934 3c2f 6469 763e 3c2f 6469 763e 0a3c 94
.<\n-00010830: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-00010840: 6964 3d22 6161 3031 3733 325f 6874 6d6c id=\"aa01732_html\n-00010850: 223e 3c64 6976 2063 6c61 7373 3d22 7474 \">.\n-00010960: 5374 6174 6973 7469 6373 2061 626f 7574 Statistics about\n-00010970: 2074 6865 2061 7070 6c69 6361 7469 6f6e the application\n-00010980: 206f 6620 616e 2069 6e76 6572 7365 206f of an inverse o\n-00010990: 7065 7261 746f 722e 3c2f 6469 763e 3c64 perator.
Definition:<\n-000109c0: 2f62 3e20 736f 6c76 6572 2e68 683a 3438 /b> solver.hh:48\n-000109d0: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
.<\n-00010aa0: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n-00010ab0: 6922 3e69 6e74 2069 7465 7261 7469 6f6e i\">int iteration\n-00010ac0: 733c 2f64 6976 3e3c 6469 7620 636c 6173 s
Number\n-00010ae0: 206f 6620 6974 6572 6174 696f 6e73 2e3c of iterations.<\n-00010af0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Defin\n-00010b10: 6974 696f 6e3a 3c2f 623e 2073 6f6c 7665 ition: solve\n-00010b20: 722e 6868 3a36 373c 2f64 6976 3e3c 2f64 r.hh:67
.
Dune::Inver\n-00010bd0: 7365 4f70 6572 6174 6f72 5265 7375 6c74 seOperatorResult\n-00010be0: 3a3a 636f 6e76 6572 6765 643c 2f61 3e3c ::converged<\n-00010bf0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
bool co\n-00010c10: 6e76 6572 6765 643c 2f64 6976 3e3c 6469 nverged
\n-00010c30: 5472 7565 2069 6620 636f 6e76 6572 6765 True if converge\n-00010c40: 6e63 6520 6372 6974 6572 696f 6e20 6861 nce criterion ha\n-00010c50: 7320 6265 656e 206d 6574 2e3c 2f64 6976 s been met.
Definitio\n-00010c80: 6e3a 3c2f 623e 2073 6f6c 7665 722e 6868 n: solver.hh\n-00010c90: 3a37 333c 2f64 6976 3e3c 2f64 6976 3e0a :73
.\n-00010ca0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
A\n-00010d20: 6273 7472 6163 7420 6261 7365 2063 6c61 bstract base cla\n-00010d30: 7373 2066 6f72 2061 6c6c 2073 6f6c 7665 ss for all solve\n-00010d40: 7273 2e3c 2f64 6976 3e3c 6469 7620 636c rs.
D\n-00010d60: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n-00010d70: 6f6c 7665 722e 6868 3a39 393c 2f64 6976 olver.hh:99
.
Dune::S\n-00010e20: 6f6c 7665 7243 6174 6567 6f72 793a 3a43 olverCategory::C\n-00010e30: 6174 6567 6f72 793c 2f61 3e3c 2f64 6976 ategory
Category
Definit\n-00010e80: 696f 6e3a 3c2f 623e 2073 6f6c 7665 7263 ion: solverc\n-00010e90: 6174 6567 6f72 792e 6868 3a32 333c 2f64 ategory.hh:23
.
Dune::Uns\n-00010f00: 7570 706f 7274 6564 5479 7065 3c2f 613e upportedType\n-00010f10: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
Defi\n-00010f30: 6e69 7469 6f6e 3a3c 2f62 3e20 736f 6c76 nition: solv\n-00010f40: 6572 7265 6769 7374 7279 2e68 683a 3737 erregistry.hh:77\n-00010f50: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
.\n-00010f80: 3c64 6976 2063 6c61 7373 3d22 7474 6e61 .
Du\n-000110e0: 6e65 3a3a 4973 4469 7265 6374 536f 6c76 ne::IsDirectSolv\n-000110f0: 6572 3a3a 7661 6c75 653c 2f61 3e3c 2f64 er::value
@ value
Whether t\n-00011140: 6869 7320 6973 2061 2064 6972 6563 7420 his is a direct \n-00011150: 736f 6c76 6572 2e3c 2f64 6976 3e3c 6469 solver.
\n-00011170: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: solvertype.hh\n-00011190: 3a32 343c 2f64 6976 3e3c 2f64 6976 3e0a :24
.\n-000111a0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
Dun\n-000111f0: 653a 3a53 746f 7265 7343 6f6c 756d 6e43 e::StoresColumnC\n-00011200: 6f6d 7072 6573 7365 643c 2f61 3e3c 2f64 ompressed
Definit\n-00011230: 696f 6e3a 3c2f 623e 2073 6f6c 7665 7274 ion: solvert\n-00011240: 7970 652e 6868 3a33 303c 2f64 6976 3e3c ype.hh:30
<\n-00011250: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n-000112d0: 3c61 2068 7265 663d 2261 3032 3830 342e Dune::S\n-00011330: 746f 7265 7343 6f6c 756d 6e43 6f6d 7072 toresColumnCompr\n-00011340: 6573 7365 643a 3a76 616c 7565 3c2f 613e essed::value\n-00011350: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
@ valu\n-00011370: 653c 2f64 6976 3e3c 6469 7620 636c 6173 e
whethe\n-00011390: 7220 7468 6520 736f 6c76 6572 2069 6e74 r the solver int\n-000113a0: 6572 6e61 6c6c 7920 7573 6573 2063 6f6c ernally uses col\n-000113b0: 756d 6e20 636f 6d70 7265 7373 6564 2073 umn compressed s\n-000113c0: 746f 7261 6765 3c2f 6469 763e 3c64 6976 torage
<\n-000113e0: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: solvertype.hh:\n-00011400: 3336 3c2f 6469 763e 3c2f 6469 763e 0a3c 36
.<\n-00011410: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-00011420: 6964 3d22 6161 3032 3830 385f 6874 6d6c id=\"aa02808_html\n-00011430: 223e 3c64 6976 2063 6c61 7373 3d22 7474 \">\n-00011470: 3c64 6976 2063 6c61 7373 3d22 7474 646f
Use the SPQR \n-00011490: 7061 636b 6167 6520 746f 2064 6972 6563 package to direc\n-000114a0: 746c 7920 736f 6c76 6520 6c69 6e65 6172 tly solve linear\n-000114b0: 2073 7973 7465 6d73 20e2 8093 2065 6d70 systems ... emp\n-000114c0: 7479 2064 6566 6175 6c74 2063 6c61 7373 ty default class\n-000114d0: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
Def\n-000114f0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n-00011500: 722e 6868 3a34 383c 2f64 6976 3e3c 2f64 r.hh:48
.
<\n-00011590: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:333
.\n-00011630: 3c64 6976 2063 6c61 7373 3d22 7474 6465
Definition\n-00011650: 3a3c 2f62 3e20 7370 7172 2e68 683a 3333 : spqr.hh:33\n-00011660: 343c 2f64 6976 3e3c 2f64 6976 3e0a 3c2f 4
.
..
.Gene\n-000116f0: 7261 7465 6420 6279 2623 3136 303b 3c61 rated by \"do\n-00011770: 1.9\n-00011780: 2e34 0a3c 2f73 6d61 6c6c 3e3c 2f61 6464 .4....\n+00001560: 226c 696e 656e 6f22 3e20 2020 3331 3c2f \"lineno\"> 31 tem\n+00001590: 706c 6174 653c 2f73 7061 6e3e 2026 6c74 plate <\n+000015a0: 3b3c 7370 616e 2063 6c61 7373 3d22 6b65 ;class B, cla\n+000015e0: 7373 3c2f 7370 616e 3e20 413d 7374 643a ss A=std:\n+000015f0: 3a61 6c6c 6f63 6174 6f72 266c 743b 4226 :allocator<B&\n+00001600: 6774 3b20 2667 743b 3c2f 6469 763e 0a3c gt; >
.<\n+00001610: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00001620: 3e3c 6120 6964 3d22 6c30 3030 3332 2220 > 32<\n+00001680: 2f61 3e3c 2f73 7061 6e3e 2020 3c73 7061 /a> class <\n+000016b0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+000016c0: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n+000016d0: 3131 3638 2e68 746d 6c22 3e42 444d 6174 1168.html\">BDMat\n+000016e0: 7269 783c 2f61 3e20 3a20 3c73 7061 6e20 rix : \n+00001700: 7075 626c 6963 3c2f 7370 616e 3e20 3c61 public BCRSMa\n+00001740: 7472 6978 3c2f 613e 266c 743b 422c 4126 trix<B,A&\n+00001750: 6774 3b3c 2f64 6976 3e0a 3c64 6976 2063 gt;
.
33 \n+000017b0: 7b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 {
.
\n+00001800: 2020 2033 343c 2f73 7061 6e3e 2020 3c73 34 public:
.
35 .
\n+000018e0: 3336 3c2f 7370 616e 3e20 2020 203c 7370 36 //===== type \n+00001910: 6465 6669 6e69 7469 6f6e 7320 616e 6420 definitions and \n+00001920: 636f 6e73 7461 6e74 733c 2f73 7061 6e3e constants\n+00001930: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00001980: 2020 3337 3c2f 7370 616e 3e20 3c2f 6469 37 .
\n+00001a20: 2020 2033 393c 2f61 3e3c 2f73 7061 6e3e 39\n+00001a30: 2020 2020 3c73 7061 6e20 636c 6173 733d using \n+00001a50: 3c2f 7370 616e 3e3c 6120 636c 6173 733d field_typ\n+00001ab0: 653c 2f61 3e20 3d20 3c73 7061 6e20 636c e = ty\n+00001ad0: 7065 6e61 6d65 3c2f 7370 616e 3e20 496d pename Im\n+00001ae0: 703a 3a42 6c6f 636b 5472 6169 7473 266c p::BlockTraits&l\n+00001af0: 743b 4226 6774 3b3a 3a66 6965 6c64 5f74 t;B>::field_t\n+00001b00: 7970 653b 3c2f 6469 763e 0a3c 6469 7620 ype;
.
40 \n+00001b60: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n+00001bb0: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+00001bc0: 7265 663d 2261 3031 3136 382e 6874 6d6c ref=\"a01168.html\n+00001bd0: 2361 3337 3331 3536 3731 6135 6463 3131 #a37315671a5dc11\n+00001be0: 3932 3530 6234 3334 6462 6534 3763 6533 9250b434dbe47ce3\n+00001bf0: 3837 223e 2020 2034 323c 2f61 3e3c 2f73 87\"> 42 ty\n+00001c20: 7065 6465 663c 2f73 7061 6e3e 2042 203c pedef B <\n+00001c30: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00001c40: 5f74 7970 6564 6566 2220 6872 6566 3d22 _typedef\" href=\"\n+00001c50: 6130 3131 3638 2e68 746d 6c23 6133 3733 a01168.html#a373\n+00001c60: 3135 3637 3161 3564 6331 3139 3235 3062 15671a5dc119250b\n+00001c70: 3433 3464 6265 3437 6365 3338 3722 3e62 434dbe47ce387\">b\n+00001c80: 6c6f 636b 5f74 7970 653c 2f61 3e3b 3c2f lock_type;.
\n+00001ce0: 3433 3c2f 7370 616e 3e20 3c2f 6469 763e 43
\n+00001cf0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n+00001d20: 3c2f 613e 3c73 7061 6e20 636c 6173 733d \n+00001d80: 2034 353c 2f61 3e3c 2f73 7061 6e3e 2020 45 \n+00001d90: 2020 3c73 7061 6e20 636c 6173 733d 226b typedef<\n+00001db0: 2f73 7061 6e3e 2041 203c 6120 636c 6173 /span> A allocat\n+00001e10: 6f72 5f74 7970 653c 2f61 3e3b 3c2f 6469 or_type;.
46\n+00001e70: 3c2f 7370 616e 3e20 3c2f 6469 763e 0a3c
.<\n+00001e80: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00001e90: 3e3c 6120 6964 3d22 6c30 3030 3438 2220 > 48 //t\n+00001ef0: 7970 6564 6566 2042 4352 534d 6174 7269 ypedef BCRSMatri\n+00001f00: 7826 6c74 3b42 2c41 2667 743b 3a3a 726f x<B,A>::ro\n+00001f10: 775f 7479 7065 2072 6f77 5f74 7970 653b w_type row_type;\n+00001f20: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
.\n+00001f40: 3c61 2069 643d 226c 3030 3034 3922 206e 49
.
51\n+00002020: 3c2f 7370 616e 3e20 2020 203c 7370 616e typedef \n+00002050: 3c73 7061 6e20 636c 6173 733d 226b 6579 typename A::size_ty\n+00002080: 7065 203c 6120 636c 6173 733d 2263 6f64 pe size_type\n+000020e0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n+00002130: 2020 2035 323c 2f73 7061 6e3e 203c 2f64 52 .
5\n+00002190: 343c 2f73 7061 6e3e 2020 2020 5b5b 6465 4 [[de\n+000021a0: 7072 6563 6174 6564 283c 7370 616e 2063 precated("Use f\n+000021d0: 7265 6520 6675 6e63 7469 6f6e 2062 6c6f ree function blo\n+000021e0: 636b 4c65 7665 6c28 292e 2057 696c 6c20 ckLevel(). Will \n+000021f0: 6265 2072 656d 6f76 6564 2061 6674 6572 be removed after\n+00002200: 2032 2e38 2e26 7175 6f74 3b3c 2f73 7061 2.8.")]]
.<\n+00002250: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00002260: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 55 static\n+000022e0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 constexpr\n+00002300: 3c2f 7370 616e 3e20 3c73 7061 6e20 636c unsigned int<\n+00002350: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> blocklev\n+000023b0: 656c 3c2f 613e 203d 2062 6c6f 636b 4c65 el = blockLe\n+000023c0: 7665 6c26 6c74 3b42 2667 743b 2829 2b31 vel<B>()+1\n+000023d0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n+00002420: 2020 2035 363c 2f73 7061 6e3e 203c 2f64 56 ..
\n+000025d0: 2020 2035 393c 2f73 7061 6e3e 203c 2f64 59 .
60 expli\n+000026a0: 6369 743c 2f73 7061 6e3e 203c 6120 636c cit BDMa\n+00002700: 7472 6978 3c2f 613e 283c 7370 616e 2063 trix(int si\n+00002730: 7a65 293c 2f64 6976 3e0a 3c64 6976 2063 ze)
.
61 \n+00002790: 2020 2020 3a20 3c61 2063 6c61 7373 3d22 : BCRSMatrix\n+000027d0: 266c 743b 422c 4126 6774 3b28 7369 7a65 <B,A>(size\n+000027e0: 2c20 7369 7a65 2c20 3c61 2063 6c61 7373 , size, BCRSMatrix<B,A>::<\n+00002830: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00002840: 5f65 6e75 6d76 616c 7565 2220 6872 6566 _enumvalue\" href\n+00002850: 3d22 6130 3131 3532 2e68 746d 6c23 6136 =\"a01152.html#a6\n+00002860: 6630 3961 3463 3430 3865 3134 3432 3864 f09a4c408e14428d\n+00002870: 3361 3632 6164 3030 6365 6163 3965 6361 3a62ad00ceac9eca\n+00002880: 6430 3566 3730 6238 6532 3836 6432 3361 d05f70b8e286d23a\n+00002890: 6265 6536 3339 6138 6435 3035 3532 6533 bee639a8d50552e3\n+000028a0: 223e 7261 6e64 6f6d 3c2f 613e 2920 7b3c \">random) {<\n+000028b0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00002900: 2036 323c 2f73 7061 6e3e 203c 2f64 6976 62 .
63<\n+00002960: 2f73 7061 6e3e 2020 2020 2020 3c73 7061 /span> for\n+00002990: 2028 3c73 7061 6e20 636c 6173 733d 226b (int<\n+000029b0: 2f73 7061 6e3e 2069 3d30 3b20 6926 6c74 /span> i=0; i<\n+000029c0: 3b73 697a 653b 2069 2b2b 293c 2f64 6976 ;size; i++).
64<\n+00002a20: 2f73 7061 6e3e 2020 2020 2020 2020 7468 /span> th\n+00002a30: 6973 2d26 6774 3b3c 6120 636c 6173 733d is->BCRSMatrix<\n+00002a70: 3b42 2c41 2667 743b 3a3a 7365 7472 6f77 ;B,A>::setrow\n+00002a80: 7369 7a65 3c2f 613e 2869 2c20 3129 3b3c size(i, 1);<\n+00002a90: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00002ae0: 2036 353c 2f73 7061 6e3e 203c 2f64 6976 65 .
66<\n+00002b40: 2f73 7061 6e3e 2020 2020 2020 7468 6973 /span> this\n+00002b50: 2d26 6774 3b3c 6120 636c 6173 733d 2263 ->BCRSMatrix\n+00002bb0: 266c 743b 422c 4126 6774 3b3a 3a65 6e64 <B,A>::end\n+00002bc0: 726f 7773 697a 6573 3c2f 613e 2829 3b3c rowsizes();<\n+00002bd0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00002c20: 2036 373c 2f73 7061 6e3e 203c 2f64 6976 67 .
68<\n+00002c80: 2f73 7061 6e3e 2020 2020 2020 3c73 7061 /span> for\n+00002cb0: 2028 3c73 7061 6e20 636c 6173 733d 226b (int<\n+00002cd0: 2f73 7061 6e3e 2069 3d30 3b20 6926 6c74 /span> i=0; i<\n+00002ce0: 3b73 697a 653b 2069 2b2b 293c 2f64 6976 ;size; i++).
69<\n+00002d40: 2f73 7061 6e3e 2020 2020 2020 2020 7468 /span> th\n+00002d50: 6973 2d26 6774 3b3c 6120 636c 6173 733d is->BCRSMatrix<\n+00002d90: 3b42 2c41 2667 743b 3a3a 6164 6469 6e64 ;B,A>::addind\n+00002da0: 6578 3c2f 613e 2869 2c20 6929 3b3c 2f64 ex(i, i);.
7\n+00002e00: 303c 2f73 7061 6e3e 203c 2f64 6976 3e0a 0
.\n+00002e10: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n+00002e40: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 71 this-&\n+00002e70: 6774 3b3c 6120 636c 6173 733d 2263 6f64 gt;BCRSMatrix&l\n+00002ed0: 743b 422c 4126 6774 3b3a 3a65 6e64 696e t;B,A>::endin\n+00002ee0: 6469 6365 733c 2f61 3e28 293b 3c2f 6469 dices();.
72\n+00002f40: 3c2f 7370 616e 3e20 3c2f 6469 763e 0a3c
.<\n+00002f50: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00002f60: 3e3c 6120 6964 3d22 6c30 3030 3733 2220 > 73 }
.<\n+00002fb0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00002fc0: 3e3c 6120 6964 3d22 6c30 3030 3734 2220 > 74
.
76 BDM\n+00003100: 6174 7269 783c 2f61 3e20 2873 7464 3a3a atrix (std::\n+00003110: 696e 6974 6961 6c69 7a65 725f 6c69 7374 initializer_list\n+00003120: 266c 743b 4226 6774 3b20 3c73 7061 6e20 <B> \n+00003140: 636f 6e73 743c 2f73 7061 6e3e 2026 616d const &am\n+00003150: 703b 6c69 7374 293c 2f64 6976 3e0a 3c64 p;list)
.\n+00003170: 3c61 2069 643d 226c 3030 3037 3722 206e 77 : BDMatrix\n+000031f0: 286c 6973 742e 7369 7a65 2829 293c 2f64 (list.size()).
7\n+00003250: 383c 2f73 7061 6e3e 2020 2020 7b3c 2f64 8 {.
7\n+000032b0: 393c 2f73 7061 6e3e 2020 2020 2020 3c73 9 size_t i=0;
\n+000032f0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
\n+00003320: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 80 for \n+00003370: 283c 7370 616e 2063 6c61 7373 3d22 6b65 (auto it = list.beg\n+000033a0: 696e 2829 3b20 6974 2021 3d20 6c69 7374 in(); it != list\n+000033b0: 2e65 6e64 2829 3b20 2b2b 6974 2c20 2b2b .end(); ++it, ++\n+000033c0: 6929 3c2f 6469 763e 0a3c 6469 7620 636c i)
.
81 \n+00003420: 2020 2020 2028 2a74 6869 7329 5b69 5d5b (*this)[i][\n+00003430: 695d 203d 202a 6974 3b3c 2f64 6976 3e0a i] = *it;
.\n+00003440: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+000034a0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00003530: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00003540: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 85 void setSize(\n+00003620: 3c61 2063 6c61 7373 3d22 636f 6465 2068 \n+00003670: 7369 7a65 5f74 7970 653c 2f61 3e20 7369 size_type si\n+00003680: 7a65 293c 2f64 6976 3e0a 3c64 6976 2063 ze)
.
86 \n+000036e0: 2020 7b3c 2f64 6976 3e0a 3c64 6976 2063 {
.
87 \n+00003740: 2020 2020 7468 6973 2d26 6774 3b3c 6120 this->BC\n+000037a0: 5253 4d61 7472 6978 266c 743b 422c 4126 RSMatrix<B,A&\n+000037b0: 6774 3b3a 3a73 6574 5369 7a65 3c2f 613e gt;::setSize\n+000037c0: 2873 697a 652c 2020 203c 7370 616e 2063 (size, /\n+000037e0: 2f20 726f 7773 3c2f 7370 616e 3e3c 2f64 / rows.
8\n+00003840: 383c 2f73 7061 6e3e 2020 2020 2020 2020 8 \n+00003850: 2020 2020 2020 2020 2020 2020 2020 2020 \n+00003860: 2020 2020 2020 2020 2020 2020 2073 697a siz\n+00003870: 652c 2020 203c 7370 616e 2063 6c61 7373 e, // co\n+00003890: 6c75 6d6e 733c 2f73 7061 6e3e 3c2f 6469 lumns.
89\n+000038f0: 3c2f 7370 616e 3e20 2020 2020 2020 2020 \n+00003900: 2020 2020 2020 2020 2020 2020 2020 2020 \n+00003910: 2020 2020 2020 2020 2020 2020 7369 7a65 size\n+00003920: 293b 2020 3c73 7061 6e20 636c 6173 733d ); // non\n+00003940: 7a65 726f 733c 2f73 7061 6e3e 3c2f 6469 zeros.
90\n+000039a0: 3c2f 7370 616e 3e20 3c2f 6469 763e 0a3c
.<\n+000039b0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+000039c0: 3e3c 6120 6964 3d22 6c30 3030 3931 2220 > 91 for (<\n+00003a30: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00003a40: 6f72 6422 3e61 7574 6f3c 2f73 7061 6e3e ord\">auto\n+00003a50: 2069 203a 2072 616e 6765 2873 697a 6529 i : range(size)\n+00003a60: 293c 2f64 6976 3e0a 3c64 6976 2063 6c61 )
.\n+00003b50: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00003bc0: 6120 6964 3d22 6c30 3030 3934 2220 6e61 a id=\"l00094\" na\n+00003bd0: 6d65 3d22 6c30 3030 3934 223e 3c2f 613e me=\"l00094\">\n+00003be0: 3c73 7061 6e20 636c 6173 733d 226c 696e 94 this->\n+00003c10: 3c61 2063 6c61 7373 3d22 636f 6465 2068 BCRSMatrix<B\n+00003c70: 2c41 2667 743b 3a3a 656e 6472 6f77 7369 ,A>::endrowsi\n+00003c80: 7a65 733c 2f61 3e28 293b 3c2f 6469 763e zes();
\n+00003c90: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00003d00: 6120 6964 3d22 6c30 3030 3936 2220 6e61 a id=\"l00096\" na\n+00003d10: 6d65 3d22 6c30 3030 3936 223e 3c2f 613e me=\"l00096\">\n+00003d20: 3c73 7061 6e20 636c 6173 733d 226c 696e 96 for (auto i\n+00003d90: 203a 2072 616e 6765 2873 697a 6529 293c : range(size))<\n+00003da0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00003df0: 2039 373c 2f73 7061 6e3e 2020 2020 2020 97 \n+00003e00: 2020 7468 6973 2d26 6774 3b3c 6120 636c this->BCRS\n+00003e60: 4d61 7472 6978 266c 743b 422c 4126 6774 Matrix<B,A>\n+00003e70: 3b3a 3a61 6464 696e 6465 783c 2f61 3e28 ;::addindex(\n+00003e80: 692c 2069 293b 3c2f 6469 763e 0a3c 6469 i, i);
.<\n+00003ea0: 6120 6964 3d22 6c30 3030 3938 2220 6e61 a id=\"l00098\" na\n+00003eb0: 6d65 3d22 6c30 3030 3938 223e 3c2f 613e me=\"l00098\">\n+00003ec0: 3c73 7061 6e20 636c 6173 733d 226c 696e 98
..<\n+00004000: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00004010: 6e6f 223e 2020 3130 303c 2f73 7061 6e3e no\"> 100
\n+00004020: 2020 2020 7d3c 2f64 6976 3e0a 3c64 6976 }
.<\n+00004060: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00004070: 6e6f 223e 2020 3130 313c 2f73 7061 6e3e no\"> 101\n+00004080: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
.
\n+000040d0: 3c61 2063 6c61 7373 3d22 6c69 6e65 2220 103 BDMatrix& operator\n+000041c0: 3d20 3c2f 613e 283c 7370 616e 2063 6c61 = (con\n+000041e0: 7374 3c2f 7370 616e 3e20 3c61 2063 6c61 st BDMatrix& other) {\n+00004230: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00004280: 2031 3034 3c2f 7370 616e 3e20 2020 2020 104 \n+00004290: 2074 6869 732d 2667 743b 3c61 2063 6c61 this->BCRSM\n+000042f0: 6174 7269 7826 6c74 3b42 2c41 2667 743b atrix<B,A>\n+00004300: 3a3a 6f70 6572 6174 6f72 3d3c 2f61 3e28 ::operator=(\n+00004310: 6f74 6865 7229 3b3c 2f64 6976 3e0a 3c64 other);
.\n+00004330: 3c61 2069 643d 226c 3030 3130 3522 206e 105 return \n+000043a0: 2a3c 7370 616e 2063 6c61 7373 3d22 6b65 *this;
.
106 \n+00004420: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
.
107 <\n+00004480: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
109 BDMatrix&\n+00004560: 616d 703b 203c 6120 636c 6173 733d 2263 amp; operator= \n+000045c0: 3c2f 613e 283c 7370 616e 2063 6c61 7373 (const\n+000045e0: 3c2f 7370 616e 3e20 3c61 2063 6c61 7373 field_ty\n+00004640: 7065 3c2f 613e 2661 6d70 3b20 6b29 207b pe& k) {\n+00004650: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+000046a0: 2031 3130 3c2f 7370 616e 3e20 2020 2020 110 \n+000046b0: 2074 6869 732d 2667 743b 3c61 2063 6c61 this->BCRSM\n+00004710: 6174 7269 7826 6c74 3b42 2c41 2667 743b atrix<B,A>\n+00004720: 3a3a 6f70 6572 6174 6f72 3d3c 2f61 3e28 ::operator=(\n+00004730: 6b29 3b3c 2f64 6976 3e0a 3c64 6976 2063 k);
.
111 \n+00004790: 2020 2020 3c73 7061 6e20 636c 6173 733d re\n+000047b0: 7475 726e 3c2f 7370 616e 3e20 2a3c 7370 turn *this;<\n+000047e0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00004830: 3131 323c 2f73 7061 6e3e 2020 2020 7d3c 112 }<\n+00004840: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00004890: 3131 333c 2f73 7061 6e3e 203c 2f64 6976 113 .
119<\n+000048f0: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n+00004910: 7465 6d70 6c61 7465 3c2f 7370 616e 3e20 template \n+00004920: 266c 743b 3c73 7061 6e20 636c 6173 733d <class<\n+00004940: 2f73 7061 6e3e 2056 2667 743b 3c2f 6469 /span> V>.
\n+000049e0: 2020 3132 303c 2f61 3e3c 2f73 7061 6e3e 120\n+000049f0: 2020 2020 3c73 7061 6e20 636c 6173 733d vo\n+00004a10: 6964 3c2f 7370 616e 3e20 3c61 2063 6c61 id solve\n+00004a70: 3c2f 613e 2028 5626 616d 703b 2078 2c20 (V& x, \n+00004a80: 3c73 7061 6e20 636c 6173 733d 226b 6579 const V& rhs) const {
.
121 \n+00004b30: 2020 2020 3c73 7061 6e20 636c 6173 733d fo\n+00004b50: 723c 2f73 7061 6e3e 2028 3c61 2063 6c61 r (size_t\n+00004bb0: 7970 653c 2f61 3e20 693d 303b 2069 266c ype i=0; i&l\n+00004bc0: 743b 7468 6973 2d26 6774 3b3c 6120 636c t;this->N(); i++)
.\n+00004c30: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n+00004c60: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 122 {.
123<\n+00004ce0: 2f73 7061 6e3e 2020 2020 2020 2020 3c73 /span> auto&\n+00004d10: 616d 703b 2661 6d70 3b20 7876 203d 2049 amp;& xv = I\n+00004d20: 6d70 6c3a 3a61 7356 6563 746f 7228 785b mpl::asVector(x[\n+00004d30: 695d 293b 3c2f 6469 763e 0a3c 6469 7620 i]);
.
124 \n+00004d90: 2020 2020 2020 203c 7370 616e 2063 6c61 aut\n+00004db0: 6f3c 2f73 7061 6e3e 2661 6d70 3b26 616d o&&am\n+00004dc0: 703b 2072 6873 7620 3d20 496d 706c 3a3a p; rhsv = Impl::\n+00004dd0: 6173 5665 6374 6f72 2872 6873 5b69 5d29 asVector(rhs[i])\n+00004de0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n+00004e30: 2020 3132 353c 2f73 7061 6e3e 2020 2020 125 \n+00004e40: 2020 2020 496d 706c 3a3a 6173 4d61 7472 Impl::asMatr\n+00004e50: 6978 2828 2a3c 7370 616e 2063 6c61 7373 ix((*this<\n+00004e70: 2f73 7061 6e3e 295b 695d 5b69 5d29 2e73 /span>)[i][i]).s\n+00004e80: 6f6c 7665 2878 762c 7268 7376 293b 3c2f olve(xv,rhsv);.
1\n+00004ee0: 3236 3c2f 7370 616e 3e20 2020 2020 207d 26 }\n+00004ef0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00004f40: 2031 3237 3c2f 7370 616e 3e20 2020 207d 127 }\n+00004f50: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00004fa0: 2031 3238 3c2f 7370 616e 3e20 3c2f 6469 128 .
\n+00005040: 2020 3133 303c 2f61 3e3c 2f73 7061 6e3e 130\n+00005050: 2020 2020 3c73 7061 6e20 636c 6173 733d vo\n+00005070: 6964 3c2f 7370 616e 3e20 3c61 2063 6c61 id inver\n+000050d0: 743c 2f61 3e28 2920 7b3c 2f64 6976 3e0a t() {
.\n+000050e0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
<\n+00005110: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 131 for (\n+00005160: 3c61 2063 6c61 7373 3d22 636f 6465 2068 \n+000051b0: 7369 7a65 5f74 7970 653c 2f61 3e20 693d size_type i=\n+000051c0: 303b 2069 266c 743b 7468 6973 2d26 6774 0; i<this->\n+000051d0: 3b3c 6120 636c 6173 733d 2263 6f64 6520 ;N(); i++)<\n+00005230: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00005280: 3133 323c 2f73 7061 6e3e 2020 2020 2020 132 \n+00005290: 2020 496d 706c 3a3a 6173 4d61 7472 6978 Impl::asMatrix\n+000052a0: 2828 2a3c 7370 616e 2063 6c61 7373 3d22 ((*this)[i][i]).in\n+00005320: 7665 7274 3c2f 613e 2829 3b3c 2f64 6976 vert();.
133<\n+00005380: 2f73 7061 6e3e 2020 2020 7d3c 2f64 6976 /span> }.
134<\n+000053e0: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
.\n+00005400: 3c61 2069 643d 226c 3030 3133 3522 206e 135 privat\n+00005460: 653c 2f73 7061 6e3e 3a3c 2f64 6976 3e0a e:
.\n+00005470: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00005500: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00005510: 6e6f 223e 2020 3133 373c 2f73 7061 6e3e no\"> 137
\n+00005520: 2020 2020 3c73 7061 6e20 636c 6173 733d // ///\n+00005540: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005550: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005560: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005570: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005580: 2f2f 2f2f 2f2f 2f2f 2f3c 2f73 7061 6e3e /////////\n+00005590: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+000055e0: 2031 3338 3c2f 7370 616e 3e20 2020 203c 138 <\n+000055f0: 7370 616e 2063 6c61 7373 3d22 636f 6d6d span class=\"comm\n+00005600: 656e 7422 3e2f 2f20 2020 5468 6520 666f ent\">// The fo\n+00005610: 6c6c 6f77 696e 6720 6d65 7468 6f64 7320 llowing methods \n+00005620: 6672 6f6d 2074 6865 2062 6173 6520 636c from the base cl\n+00005630: 6173 7320 7368 6f75 6c64 206e 6f77 2061 ass should now a\n+00005640: 6374 7561 6c6c 7920 6265 2063 616c 6c65 ctually be calle\n+00005650: 643c 2f73 7061 6e3e 3c2f 6469 763e 0a3c d
.<\n+00005660: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00005670: 3e3c 6120 6964 3d22 6c30 3031 3339 2220 > 139 // \n+000056d0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+000056e0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+000056f0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005700: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////\n+00005710: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 3c2f 7370 ////////////
.
140 <\n+00005780: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+000057d0: 3134 313c 2f73 7061 6e3e 2020 2020 3c73 141 // createbeg\n+00005800: 696e 2061 6e64 2063 7265 6174 6565 6e64 in and createend\n+00005810: 2073 686f 756c 6420 6265 2069 6e20 7468 should be in th\n+00005820: 6572 652c 2074 6f6f 2c20 6275 7420 4920 ere, too, but I \n+00005830: 6361 6e26 2333 393b 7420 6765 7420 6974 can't get it\n+00005840: 2074 6f20 636f 6d70 696c 653c 2f73 7061 to compile
.
142 \n+000058b0: 203c 7370 616e 2063 6c61 7373 3d22 636f // BC\n+000058d0: 5253 4d61 7472 6978 266c 743b 422c 4126 RSMatrix<B,A&\n+000058e0: 6774 3b3a 3a43 7265 6174 6549 7465 7261 gt;::CreateItera\n+000058f0: 746f 7220 6372 6561 7465 6265 6769 6e20 tor createbegin \n+00005900: 2829 207b 7d3c 2f73 7061 6e3e 3c2f 6469 () {}.
143\n+00005960: 3c2f 7370 616e 3e20 2020 203c 7370 616e // BCRSMatr\n+00005990: 6978 266c 743b 422c 4126 6774 3b3a 3a43 ix<B,A>::C\n+000059a0: 7265 6174 6549 7465 7261 746f 7220 6372 reateIterator cr\n+000059b0: 6561 7465 656e 6420 2829 207b 7d3c 2f73 eateend () {}
.
144 \n+00005a20: 2020 203c 7370 616e 2063 6c61 7373 3d22 voi\n+00005a40: 643c 2f73 7061 6e3e 2073 6574 726f 7773 d setrows\n+00005a50: 697a 6520 283c 6120 636c 6173 733d 2263 ize (size_type i, size_type<\n+00005b10: 2f61 3e20 7329 207b 7d3c 2f64 6976 3e0a /a> s) {}
.\n+00005b20: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
146 \n+00005c70: 2020 3c73 7061 6e20 636c 6173 733d 226b void\n+00005c90: 3c2f 7370 616e 3e20 656e 6472 6f77 7369 endrowsi\n+00005ca0: 7a65 7320 2829 207b 7d3c 2f64 6976 3e0a zes () {}
.\n+00005cb0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00005e70: 6120 6964 3d22 6c30 3031 3438 2220 6e61 a id=\"l00148\" na\n+00005e80: 6d65 3d22 6c30 3031 3438 223e 3c2f 613e me=\"l00148\">\n+00005e90: 3c73 7061 6e20 636c 6173 733d 226c 696e 148 v\n+00005ed0: 6f69 643c 2f73 7061 6e3e 2065 6e64 696e oid endin\n+00005ee0: 6469 6365 7320 2829 207b 7d3c 2f64 6976 dices () {}.
149<\n+00005f40: 2f73 7061 6e3e 2020 7d3b 3c2f 6469 763e /span> };
\n+00005f50: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00005fc0: 6120 6964 3d22 6c30 3031 3531 2220 6e61 a id=\"l00151\" na\n+00005fd0: 6d65 3d22 6c30 3031 3531 223e 3c2f 613e me=\"l00151\">\n+00005fe0: 3c73 7061 6e20 636c 6173 733d 226c 696e 151 templat\n+00006020: 653c 2f73 7061 6e3e 266c 743b 3c73 7061 e<typename B, typen\n+00006070: 616d 653c 2f73 7061 6e3e 2041 2667 743b ame A>\n+00006080: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
<\n+000060d0: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+000060e0: 7265 663d 2261 3031 3137 322e 6874 6d6c ref=\"a01172.html\n+000060f0: 223e 2020 3135 323c 2f61 3e3c 2f73 7061 \"> 152 struct\n+00006120: 203c 2f73 7061 6e3e 4669 656c 6454 7261 FieldTra\n+00006130: 6974 7326 6c74 3b20 3c61 2063 6c61 7373 its< BDMatrix\n+00006170: 266c 743b 422c 2041 2667 743b 2026 6774 <B, A> >\n+00006180: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
.
\n+000061d0: 2020 3135 333c 2f73 7061 6e3e 2020 7b3c 153 {<\n+000061e0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>..<\n+000063c0: 6120 6964 3d22 6c30 3031 3535 2220 6e61 a id=\"l00155\" na\n+000063d0: 6d65 3d22 6c30 3031 3535 223e 3c2f 613e me=\"l00155\">\n+000063e0: 3c73 7061 6e20 636c 6173 733d 226c 696e 155<\n+00006440: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c73 /a> using real_type =\n+000064d0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 typename<\n+000064f0: 2f73 7061 6e3e 2046 6965 6c64 5472 6169 /span> FieldTrai\n+00006500: 7473 266c 743b 6669 656c 645f 7479 7065 ts<field_type\n+00006510: 2667 743b 3a3a 7265 616c 5f74 7970 653b >::real_type;\n+00006520: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
\n+00006570: 2031 3536 3c2f 7370 616e 3e20 207d 3b3c 156 };<\n+00006580: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+000065d0: 3135 393c 2f73 7061 6e3e 7d20 203c 7370 159} // end namesp\n+00006600: 6163 6520 4475 6e65 3c2f 7370 616e 3e3c ace Dune<\n+00006610: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
\n+00006660: 3136 303c 2f73 7061 6e3e 203c 2f64 6976 160 .
161<\n+000066c0: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#endif..\n+000067a0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
blo\n+000067f0: 636b 6c65 7665 6c2e 6868 3c2f 613e 3c2f cklevel.hh
Helper fu\n+00006820: 6e63 7469 6f6e 7320 666f 7220 6465 7465 nctions for dete\n+00006830: 726d 696e 696e 6720 7468 6520 7665 6374 rmining the vect\n+00006840: 6f72 2f6d 6174 7269 7820 626c 6f63 6b20 or/matrix block \n+00006850: 6c65 7665 6c2e 3c2f 6469 763e 3c2f 6469 level.
.
col
Col col
Defini\n+00006940: 7469 6f6e 3a3c 2f62 3e20 6d61 7472 6978 tion: matrix\n+00006950: 6d61 7472 6978 2e68 683a 3335 313c 2f64 matrix.hh:351
.
Dune<\n+000069c0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Defin\n+000069e0: 6974 696f 6e3a 3c2f 623e 2061 6c6c 6f63 ition: alloc\n+000069f0: 6174 6f72 2e68 683a 3131 3c2f 6469 763e ator.hh:11
\n+00006a00: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
Dune::BCRSMa\n+00006a60: 7472 6978 3c2f 613e 3c2f 6469 763e 3c64 trix
A sparse block \n+00006a90: 6d61 7472 6978 2077 6974 6820 636f 6d70 matrix with comp\n+00006aa0: 7265 7373 6564 2072 6f77 2073 746f 7261 ressed row stora\n+00006ab0: 6765 2e3c 2f64 6976 3e3c 6469 7620 636c ge.
D\n+00006ad0: 6566 696e 6974 696f 6e3a 3c2f 623e 2062 efinition: b\n+00006ae0: 6372 736d 6174 7269 782e 6868 3a34 3636 crsmatrix.hh:466\n+00006af0: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
.
Du\n+00006b90: 6e65 3a3a 4243 5253 4d61 7472 6978 3a3a ne::BCRSMatrix::\n+00006ba0: 656e 6472 6f77 7369 7a65 733c 2f61 3e3c endrowsizes<\n+00006bb0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
void en\n+00006bd0: 6472 6f77 7369 7a65 7328 293c 2f64 6976 drowsizes()
indicate tha\n+00006c00: 7420 7369 7a65 206f 6620 616c 6c20 726f t size of all ro\n+00006c10: 7773 2069 7320 6465 6669 6e65 643c 2f64 ws is defined
Definit\n+00006c40: 696f 6e3a 3c2f 623e 2062 6372 736d 6174 ion: bcrsmat\n+00006c50: 7269 782e 6868 3a31 3134 393c 2f64 6976 rix.hh:1149
.<\n+00006d20: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+00006d30: 6922 3e76 6f69 6420 7365 7472 6f77 7369 i\">void setrowsi\n+00006d40: 7a65 2873 697a 655f 7479 7065 2069 2c20 ze(size_type i, \n+00006d50: 7369 7a65 5f74 7970 6520 7329 3c2f 6469 size_type s)
Set number \n+00006d80: 6f66 2069 6e64 6963 6573 2069 6e20 726f of indices in ro\n+00006d90: 7720 6920 746f 2073 2e3c 2f64 6976 3e3c w i to s.
<\n+00006da0: 6469 7620 636c 6173 733d 2274 7464 6566 div class=\"ttdef\n+00006db0: 223e 3c62 3e44 6566 696e 6974 696f 6e3a \">Definition:\n+00006dc0: 3c2f 623e 2062 6372 736d 6174 7269 782e bcrsmatrix.\n+00006dd0: 6868 3a31 3131 373c 2f64 6976 3e3c 2f64 hh:1117
.
Dune::BCR\n+00006ec0: 534d 6174 7269 7826 6c74 3b20 422c 2073 SMatrix< B, s\n+00006ed0: 7464 3a3a 616c 6c6f 6361 746f 7226 6c74 td::allocator<\n+00006ee0: 3b20 4220 2667 743b 2026 6774 3b3a 3a72 ; B > >::r\n+00006ef0: 616e 646f 6d3c 2f61 3e3c 2f64 6976 3e3c andom
<\n+00006f00: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+00006f10: 6922 3e40 2072 616e 646f 6d3c 2f64 6976 i\">@ random
Build entrie\n+00006f40: 7320 7261 6e64 6f6d 6c79 2e3c 2f64 6976 s randomly.
Definitio\n+00006f70: 6e3a 3c2f 623e 2062 6372 736d 6174 7269 n: bcrsmatri\n+00006f80: 782e 6868 3a35 3330 3c2f 6469 763e 3c2f x.hh:530
.
Dune::BCRS\n+00007030: 4d61 7472 6978 3a3a 6164 6469 6e64 6578 Matrix::addindex\n+00007040: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
vo\n+00007060: 6964 2061 6464 696e 6465 7828 7369 7a65 id addindex(size\n+00007070: 5f74 7970 6520 726f 772c 2073 697a 655f _type row, size_\n+00007080: 7479 7065 2063 6f6c 293c 2f64 6976 3e3c type col)
<\n+00007090: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n+000070a0: 223e 6164 6420 696e 6465 7820 2872 6f77 \">add index (row\n+000070b0: 2c63 6f6c 2920 746f 2074 6865 206d 6174 ,col) to the mat\n+000070c0: 7269 783c 2f64 6976 3e3c 6469 7620 636c rix
D\n+000070e0: 6566 696e 6974 696f 6e3a 3c2f 623e 2062 efinition: b\n+000070f0: 6372 736d 6174 7269 782e 6868 3a31 3139 crsmatrix.hh:119\n+00007100: 313c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 1
.
D\n+000071a0: 756e 653a 3a42 4352 534d 6174 7269 783a une::BCRSMatrix:\n+000071b0: 3a65 6e64 696e 6469 6365 733c 2f61 3e3c :endindices<\n+000071c0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
void en\n+000071e0: 6469 6e64 6963 6573 2829 3c2f 6469 763e dindices()
\n+000071f0: 3c64 6976 2063 6c61 7373 3d22 7474 646f
indicate that\n+00007210: 2061 6c6c 2069 6e64 6963 6573 2061 7265 all indices are\n+00007220: 2064 6566 696e 6564 2c20 6368 6563 6b20 defined, check \n+00007230: 636f 6e73 6973 7465 6e63 793c 2f64 6976 consistency
Definitio\n+00007260: 6e3a 3c2f 623e 2062 6372 736d 6174 7269 n: bcrsmatri\n+00007270: 782e 6868 3a31 3234 383c 2f64 6976 3e3c x.hh:1248
<\n+00007280: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
<\n+000072e0: 6120 6872 6566 3d22 6130 3131 3532 2e68 a href=\"a01152.h\n+000072f0: 746d 6c23 6165 3634 3063 3466 6335 6139 tml#ae640c4fc5a9\n+00007300: 3334 3362 3838 3336 6233 3037 3333 6239 343b8836b30733b9\n+00007310: 3866 3962 3422 3e44 756e 653a 3a42 4352 8f9b4\">Dune::BCR\n+00007320: 534d 6174 7269 7826 6c74 3b20 422c 2073 SMatrix< B, s\n+00007330: 7464 3a3a 616c 6c6f 6361 746f 7226 6c74 td::allocator<\n+00007340: 3b20 4220 2667 743b 2026 6774 3b3a 3a4e ; B > >::N\n+00007350: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
si\n+00007370: 7a65 5f74 7970 6520 4e28 2920 636f 6e73 ze_type N() cons\n+00007380: 743c 2f64 6976 3e3c 6469 7620 636c 6173 t
number\n+000073a0: 206f 6620 726f 7773 2028 636f 756e 7465 of rows (counte\n+000073b0: 6420 696e 2062 6c6f 636b 7329 3c2f 6469 d in blocks)
Definiti\n+000073e0: 6f6e 3a3c 2f62 3e20 6263 7273 6d61 7472 on: bcrsmatr\n+000073f0: 6978 2e68 683a 3139 3732 3c2f 6469 763e ix.hh:1972
\n+00007400: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
.
v\n+000074d0: 6f69 6420 7365 7453 697a 6528 7369 7a65 oid setSize(size\n+000074e0: 5f74 7970 6520 726f 7773 2c20 7369 7a65 _type rows, size\n+000074f0: 5f74 7970 6520 636f 6c75 6d6e 732c 2073 _type columns, s\n+00007500: 697a 655f 7479 7065 206e 6e7a 3d30 293c ize_type nnz=0)<\n+00007510: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Set the \n+00007530: 7369 7a65 206f 6620 7468 6520 6d61 7472 size of the matr\n+00007540: 6978 2e3c 2f64 6976 3e3c 6469 7620 636c ix.
D\n+00007560: 6566 696e 6974 696f 6e3a 3c2f 623e 2062 efinition: b\n+00007570: 6372 736d 6174 7269 782e 6868 3a38 3631 crsmatrix.hh:861\n+00007580: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
.
Du\n+00007620: 6e65 3a3a 4243 5253 4d61 7472 6978 3a3a ne::BCRSMatrix::\n+00007630: 6f70 6572 6174 6f72 3d3c 2f61 3e3c 2f64 operator=
BCRSMatri\n+00007660: 7820 2661 6d70 3b20 6f70 6572 6174 6f72 x & operator\n+00007670: 3d28 636f 6e73 7420 4243 5253 4d61 7472 =(const BCRSMatr\n+00007680: 6978 2026 616d 703b 4d61 7429 3c2f 6469 ix &Mat)
assignment<\n+000076b0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Defin\n+000076d0: 6974 696f 6e3a 3c2f 623e 2062 6372 736d ition: bcrsm\n+000076e0: 6174 7269 782e 6868 3a39 3131 3c2f 6469 atrix.hh:911
.
\n+00007730: 3c61 2068 7265 663d 2261 3031 3136 382e Dune::BDMa\n+00007750: 7472 6978 3c2f 613e 3c2f 6469 763e 3c64 trix
A block-diagona\n+00007780: 6c20 6d61 7472 6978 2e3c 2f64 6976 3e3c l matrix.
<\n+00007790: 6469 7620 636c 6173 733d 2274 7464 6566 div class=\"ttdef\n+000077a0: 223e 3c62 3e44 6566 696e 6974 696f 6e3a \">Definition:\n+000077b0: 3c2f 623e 2062 646d 6174 7269 782e 6868 bdmatrix.hh\n+000077c0: 3a33 333c 2f64 6976 3e3c 2f64 6976 3e0a :33
.\n+000077d0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
Dune::BDMatrix:\n+00007870: 3a66 6965 6c64 5f74 7970 653c 2f61 3e3c :field_type<\n+00007880: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
typenam\n+000078a0: 6520 496d 703a 3a42 6c6f 636b 5472 6169 e Imp::BlockTrai\n+000078b0: 7473 266c 743b 2042 2026 6774 3b3a 3a66 ts< B >::f\n+000078c0: 6965 6c64 5f74 7970 6520 6669 656c 645f ield_type field_\n+000078d0: 7479 7065 3c2f 6469 763e 3c64 6976 2063 type
exp\n+000078f0: 6f72 7420 7468 6520 7479 7065 2072 6570 ort the type rep\n+00007900: 7265 7365 6e74 696e 6720 7468 6520 6669 resenting the fi\n+00007910: 656c 643c 2f64 6976 3e3c 6469 7620 636c eld
D\n+00007930: 6566 696e 6974 696f 6e3a 3c2f 623e 2062 efinition: b\n+00007940: 646d 6174 7269 782e 6868 3a33 393c 2f64 dmatrix.hh:39
.
<\n+000079a0: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n+000079b0: 6522 3e3c 6120 6872 6566 3d22 6130 3131 e\">Dune:\n+000079f0: 3a42 444d 6174 7269 783a 3a73 697a 655f :BDMatrix::size_\n+00007a00: 7479 7065 3c2f 613e 3c2f 6469 763e 3c64 type
A::size_type s\n+00007a30: 697a 655f 7479 7065 3c2f 6469 763e 3c64 ize_type
implement row_t\n+00007a60: 7970 6520 7769 7468 2063 6f6d 7072 6573 ype with compres\n+00007a70: 7365 6420 7665 6374 6f72 3c2f 6469 763e sed vector
\n+00007a80: 3c64 6976 2063 6c61 7373 3d22 7474 6465
Definition\n+00007aa0: 3a3c 2f62 3e20 6264 6d61 7472 6978 2e68 : bdmatrix.h\n+00007ab0: 683a 3531 3c2f 6469 763e 3c2f 6469 763e h:51
\n+00007ac0: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
Dune::BDMatrix\n+00007b60: 3a3a 4244 4d61 7472 6978 3c2f 613e 3c2f ::BDMatrix
BDMatrix\n+00007b90: 2829 3c2f 6469 763e 3c64 6976 2063 6c61 ()
Defau\n+00007bb0: 6c74 2063 6f6e 7374 7275 6374 6f72 2e3c lt constructor.<\n+00007bc0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
Defin\n+00007be0: 6974 696f 6e3a 3c2f 623e 2062 646d 6174 ition: bdmat\n+00007bf0: 7269 782e 6868 3a35 383c 2f64 6976 3e3c rix.hh:58
<\n+00007c00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
<\n+00007c60: 6120 6872 6566 3d22 6130 3131 3638 2e68 a href=\"a01168.h\n+00007c70: 746d 6c23 6132 3934 3765 3131 6136 3239 tml#a2947e11a629\n+00007c80: 6365 6233 3565 6536 3439 6636 6233 3938 ceb35ee649f6b398\n+00007c90: 6564 6135 3822 3e44 756e 653a 3a42 444d eda58\">Dune::BDM\n+00007ca0: 6174 7269 783a 3a42 444d 6174 7269 783c atrix::BDMatrix<\n+00007cb0: 2f61 3e3c 2f64 6976 3e3c 6469 7620 636c /a>
BDM\n+00007cd0: 6174 7269 7828 7374 643a 3a69 6e69 7469 atrix(std::initi\n+00007ce0: 616c 697a 6572 5f6c 6973 7426 6c74 3b20 alizer_list< \n+00007cf0: 4220 2667 743b 2063 6f6e 7374 2026 616d B > const &am\n+00007d00: 703b 6c69 7374 293c 2f64 6976 3e3c 6469 p;list)
\n+00007d20: 436f 6e73 7472 7563 7420 6672 6f6d 2061 Construct from a\n+00007d30: 2073 7464 3a3a 696e 6974 6961 6c69 7a65 std::initialize\n+00007d40: 725f 6c69 7374 2e3c 2f64 6976 3e3c 6469 r_list.
\n+00007d60: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: bdmatrix.hh:7\n+00007d80: 363c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 6
.
D\n+00007e20: 756e 653a 3a42 444d 6174 7269 783a 3a62 une::BDMatrix::b\n+00007e30: 6c6f 636b 5f74 7970 653c 2f61 3e3c 2f64 lock_type
B block_t\n+00007e60: 7970 653c 2f64 6976 3e3c 6469 7620 636c ype
expo\n+00007e80: 7274 2074 6865 2074 7970 6520 7265 7072 rt the type repr\n+00007e90: 6573 656e 7469 6e67 2074 6865 2063 6f6d esenting the com\n+00007ea0: 706f 6e65 6e74 733c 2f64 6976 3e3c 6469 ponents
\n+00007ec0: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: bdmatrix.hh:4\n+00007ee0: 323c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 2
.void solve(V &\n+00007fc0: 616d 703b 782c 2063 6f6e 7374 2056 2026 amp;x, const V &\n+00007fd0: 616d 703b 7268 7329 2063 6f6e 7374 3c2f amp;rhs) const
Solve the\n+00008000: 2073 7973 7465 6d20 4178 3d62 2069 6e20 system Ax=b in \n+00008010: 4f28 6e29 2074 696d 652e 3c2f 6469 763e O(n) time.
\n+00008020: 3c64 6976 2063 6c61 7373 3d22 7474 6465
Definition\n+00008040: 3a3c 2f62 3e20 6264 6d61 7472 6978 2e68 : bdmatrix.h\n+00008050: 683a 3132 303c 2f64 6976 3e3c 2f64 6976 h:120
.
A\n+00008130: 2061 6c6c 6f63 6174 6f72 5f74 7970 653c allocator_type<\n+00008140: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
export t\n+00008160: 6865 2061 6c6c 6f63 6174 6f72 2074 7970 he allocator typ\n+00008170: 653c 2f64 6976 3e3c 6469 7620 636c 6173 e
Def\n+00008190: 696e 6974 696f 6e3a 3c2f 623e 2062 646d inition: bdm\n+000081a0: 6174 7269 782e 6868 3a34 353c 2f64 6976 atrix.hh:45
.
B\n+00008280: 444d 6174 7269 7828 696e 7420 7369 7a65 DMatrix(int size\n+00008290: 293c 2f64 6976 3e3c 6469 7620 636c 6173 )
Def\n+000082b0: 696e 6974 696f 6e3a 3c2f 623e 2062 646d inition: bdm\n+000082c0: 6174 7269 782e 6868 3a36 303c 2f64 6976 atrix.hh:60
.\n+000083a0: 4244 4d61 7472 6978 2026 616d 703b 206f BDMatrix & o\n+000083b0: 7065 7261 746f 723d 2863 6f6e 7374 2042 perator=(const B\n+000083c0: 444d 6174 7269 7820 2661 6d70 3b6f 7468 DMatrix &oth\n+000083d0: 6572 293c 2f64 6976 3e3c 6469 7620 636c er)
assi\n+000083f0: 676e 6d65 6e74 3c2f 6469 763e 3c64 6976 gnment
<\n+00008410: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: bdmatrix.hh:10\n+00008430: 333c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 3
.
D\n+000084d0: 756e 653a 3a42 444d 6174 7269 783a 3a62 une::BDMatrix::b\n+000084e0: 6c6f 636b 6c65 7665 6c3c 2f61 3e3c 2f64 locklevel
static co\n+00008510: 6e73 7465 7870 7220 756e 7369 676e 6564 nstexpr unsigned\n+00008520: 2069 6e74 2062 6c6f 636b 6c65 7665 6c3c int blocklevel<\n+00008530: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
incremen\n+00008550: 7420 626c 6f63 6b20 6c65 7665 6c20 636f t block level co\n+00008560: 756e 7465 723c 2f64 6976 3e3c 6469 7620 unter
Definition:\n+00008590: 2062 646d 6174 7269 782e 6868 3a35 353c bdmatrix.hh:55<\n+000085a0: 2f64 6976 3e3c 2f64 6976 3e0a 3c64 6976 /div>
.void setSize(s\n+00008680: 697a 655f 7479 7065 2073 697a 6529 3c2f ize_type size)
Resize th\n+000086b0: 6520 6d61 7472 6978 2e20 496e 7661 6c69 e matrix. Invali\n+000086c0: 6461 7465 7320 7468 6520 636f 6e74 656e dates the conten\n+000086d0: 7421 3c2f 6469 763e 3c64 6976 2063 6c61 t!
De\n+000086f0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 6264 finition: bd\n+00008700: 6d61 7472 6978 2e68 683a 3835 3c2f 6469 matrix.hh:85
.
vo\n+000087e0: 6964 2069 6e76 6572 7428 293c 2f64 6976 id invert()
Inverts the \n+00008810: 6d61 7472 6978 2e3c 2f64 6976 3e3c 6469 matrix.
\n+00008830: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: bdmatrix.hh:1\n+00008850: 3330 3c2f 6469 763e 3c2f 6469 763e 0a3c 30
.<\n+00008860: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+00008870: 6964 3d22 6161 3031 3137 325f 6874 6d6c id=\"aa01172_html\n+00008880: 5f61 3665 3033 3466 3538 6535 3938 6462 _a6e034f58e598db\n+00008890: 6561 6437 3237 6264 6235 6566 3363 3863 ead727bdb5ef3c8c\n+000088a0: 3633 223e 3c64 6976 2063 6c61 7373 3d22 63\">.\n+00008aa0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
typename Fie\n+00008ac0: 6c64 5472 6169 7473 266c 743b 2066 6965 ldTraits< fie\n+00008ad0: 6c64 5f74 7970 6520 2667 743b 3a3a 7265 ld_type >::re\n+00008ae0: 616c 5f74 7970 6520 7265 616c 5f74 7970 al_type real_typ\n+00008af0: 653c 2f64 6976 3e3c 6469 7620 636c 6173 e
Def\n+00008b10: 696e 6974 696f 6e3a 3c2f 623e 2062 646d inition: bdm\n+00008b20: 6174 7269 782e 6868 3a31 3535 3c2f 6469 atrix.hh:155
.
<\n+00008b40: 212d 2d20 6672 6167 6d65 6e74 202d 2d3e !-- fragment -->\n+00008b50: 3c2f 6469 763e 3c21 2d2d 2063 6f6e 7465
.\n \n
\n \n-

Some handy generic functions for ISTL matrices. \n+

Classes for using SuperLU with ISTL matrices. \n More...

\n-
#include <set>
\n-#include <vector>
\n-#include <limits>
\n-#include <dune/common/typetraits.hh>
\n+
#include "superlufunctions.hh"
\n+#include "solvers.hh"
\n+#include "supermatrix.hh"
\n+#include <algorithm>
\n+#include <functional>
\n+#include "bcrsmatrix.hh"
\n+#include "bvector.hh"
\n+#include "istlexception.hh"
\n #include <dune/common/fmatrix.hh>
\n-#include <dune/common/dynmatrix.hh>
\n-#include <dune/common/diagonalmatrix.hh>
\n-#include <dune/common/scalarmatrixview.hh>
\n-#include <dune/istl/scaledidmatrix.hh>
\n-#include "istlexception.hh"
\n+#include <dune/common/fvector.hh>
\n+#include <dune/common/stdstreams.hh>
\n+#include <dune/istl/solvertype.hh>
\n+#include <dune/istl/solverfactory.hh>
\n
\n

Go to the source code of this file.

\n \n \n-\n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

\n Classes

struct  Dune::CheckIfDiagonalPresent< Matrix, blocklevel, l >
 Check whether the a matrix has diagonal values on blocklevel recursion levels. More...
struct  Dune::SuperLUSolveChooser< T >
 
struct  Dune::CheckIfDiagonalPresent< Matrix, 0, l >
struct  Dune::SuperLUDenseMatChooser< T >
 
struct  Dune::CheckIfDiagonalPresent< MultiTypeBlockMatrix< T1, Args... >, blocklevel, l >
struct  Dune::SuperLUQueryChooser< T >
 
struct  Dune::MatrixDimension< M >
struct  Dune::QuerySpaceChooser< T >
 
struct  Dune::MatrixDimension< Matrix< B, TA > >
class  Dune::SuperLU< M >
 SuperLu Solver. More...
 
struct  Dune::MatrixDimension< BCRSMatrix< B, TA > >
struct  Dune::IsDirectSolver< SuperLU< BCRSMatrix< T, A > > >
 
struct  Dune::MatrixDimension< BCRSMatrix< FieldMatrix< B, n, m >, TA > >
struct  Dune::StoresColumnCompressed< SuperLU< BCRSMatrix< T, A > > >
 
struct  Dune::MatrixDimension< FieldMatrix< K, n, m > >
struct  Dune::SuperLUCreator
 
struct  Dune::MatrixDimension< Dune::DynamicMatrix< T > >
struct  Dune::SuperLUCreator::isValidBlock< class >
 
struct  Dune::MatrixDimension< Matrix< FieldMatrix< K, n, m >, TA > >
struct  Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< double, k > >
 
struct  Dune::MatrixDimension< DiagonalMatrix< K, n > >
struct  Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< std::complex< double >, k > >
 
struct  Dune::MatrixDimension< ScaledIdentityMatrix< K, n > >
struct  Dune::SuperLUCreator::isValidBlock< double >
 
struct  Dune::IsMatrix< T >
 Test whether a type is an ISTL Matrix. More...
 
struct  Dune::IsMatrix< DenseMatrix< T > >
 
struct  Dune::IsMatrix< BCRSMatrix< T, A > >
 
struct  Dune::PointerCompare< T >
struct  Dune::SuperLUCreator::isValidBlock< std::complex< double > >
 
\n \n \n \n

\n Namespaces

namespace  Dune
 
\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n

\n Functions

template<class M >
auto Dune::countNonZeros (const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
 Get the number of nonzero fields in the matrix. More...
 
template<class M >
auto Dune::countNonZeros (const M &matrix, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
 
template<class M , class C >
void Dune::printGlobalSparseMatrix (const M &mat, C &ooc, std::ostream &os)
 
 Dune::DUNE_REGISTER_DIRECT_SOLVER ("superlu", SuperLUCreator())
 
\n

Detailed Description

\n-

Some handy generic functions for ISTL matrices.

\n+

Classes for using SuperLU with ISTL matrices.

\n
Author
Markus Blatt
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,81 +5,66 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n Classes | Namespaces | Functions\n-matrixutils.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes\n-Some handy generic functions for ISTL matrices. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+superlu.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL)\n+Classes for using SuperLU with ISTL matrices. More...\n+#include \"superlufunctions.hh\"\n+#include \"solvers.hh\"\n+#include \"supermatrix.hh\"\n+#include \n+#include \n+#include \"bcrsmatrix.hh\"\n+#include \"bvector.hh\"\n #include \"istlexception.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::CheckIfDiagonalPresent<_Matrix,_blocklevel,_l_>\n-\u00a0 Check whether the a matrix has diagonal values on blocklevel recursion\n- levels. More...\n-\u00a0\n-struct \u00a0Dune::CheckIfDiagonalPresent<_Matrix,_0,_l_>\n+struct \u00a0Dune::SuperLUSolveChooser<_T_>\n \u00a0\n-struct \u00a0Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,\n- blocklevel,_l_>\n+struct \u00a0Dune::SuperLUDenseMatChooser<_T_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_M_>\n+struct \u00a0Dune::SuperLUQueryChooser<_T_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_Matrix<_B,_TA_>_>\n+struct \u00a0Dune::QuerySpaceChooser<_T_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>\n+ class \u00a0Dune::SuperLU<_M_>\n+\u00a0 SuperLu Solver. More...\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>\n+struct \u00a0Dune::IsDirectSolver<_SuperLU<_BCRSMatrix<_T,_A_>_>_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>\n+struct \u00a0Dune::StoresColumnCompressed<_SuperLU<_BCRSMatrix<_T,_A_>_>_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>\n+struct \u00a0Dune::SuperLUCreator\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>\n+struct \u00a0Dune::SuperLUCreator::isValidBlock<_class_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>\n+struct \u00a0Dune::SuperLUCreator::isValidBlock<_Dune::FieldVector<_double,_k_>_>\n \u00a0\n-struct \u00a0Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>\n+struct \u00a0Dune::SuperLUCreator::isValidBlock<_Dune::FieldVector<_std::complex<\n+ double_>,_k_>_>\n \u00a0\n-struct \u00a0Dune::IsMatrix<_T_>\n-\u00a0 Test whether a type is an ISTL Matrix. More...\n+struct \u00a0Dune::SuperLUCreator::isValidBlock<_double_>\n \u00a0\n-struct \u00a0Dune::IsMatrix<_DenseMatrix<_T_>_>\n-\u00a0\n-struct \u00a0Dune::IsMatrix<_BCRSMatrix<_T,_A_>_>\n-\u00a0\n-struct \u00a0Dune::PointerCompare<_T_>\n+struct \u00a0Dune::SuperLUCreator::isValidBlock<_std::complex<_double_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n Functions\n-template\n-auto\u00a0Dune::countNonZeros (const M &, typename std::enable_if_t< Dune::\n- IsNumber< M >::value > *sfinae=nullptr)\n-\u00a0 Get the number of nonzero fields in the matrix. More...\n-\u00a0\n-template\n-auto\u00a0Dune::countNonZeros (const M &matrix, typename std::enable_if_t::value > *sfinae=nullptr)\n-\u00a0\n-template\n-void\u00a0Dune::printGlobalSparseMatrix (const M &mat, C &ooc, std::ostream &os)\n+\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"superlu\", SuperLUCreator())\n \u00a0\n ***** Detailed Description *****\n-Some handy generic functions for ISTL matrices.\n+Classes for using SuperLU with ISTL matrices.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00017_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00017_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixutils.hh Source File\n+dune-istl: superlu.hh Source File\n \n \n \n \n \n \n \n@@ -62,603 +62,786 @@\n \n
\n \n
\n
\n
\n-
matrixutils.hh
\n+
superlu.hh
\n
\n
\n Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
\n
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
\n
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
\n
4// vi: set et ts=4 sw=2 sts=2:
\n-
5#ifndef DUNE_ISTL_MATRIXUTILS_HH
\n-
6#define DUNE_ISTL_MATRIXUTILS_HH
\n+
5#ifndef DUNE_ISTL_SUPERLU_HH
\n+
6#define DUNE_ISTL_SUPERLU_HH
\n
7
\n-
8#include <set>
\n-
9#include <vector>
\n-
10#include <limits>
\n-
11#include <dune/common/typetraits.hh>
\n-
12#include <dune/common/fmatrix.hh>
\n-
13#include <dune/common/dynmatrix.hh>
\n-
14#include <dune/common/diagonalmatrix.hh>
\n-
15#include <dune/common/scalarmatrixview.hh>
\n-\n-
17#include "istlexception.hh"
\n-
18
\n-
19namespace Dune
\n-
20{
\n-
21
\n-
22#ifndef DOYXGEN
\n-
23 template<typename B, typename A>
\n-
24 class BCRSMatrix;
\n-
25
\n-
26 template<typename K, int n, int m>
\n-\n-
28
\n-
29 template<class T, class A>
\n-
30 class Matrix;
\n-
31#endif
\n-
32
\n-
46 template<class Matrix, std::size_t blocklevel, std::size_t l=blocklevel>
\n-\n-
48 {
\n-
53 static void check([[maybe_unused]] const Matrix& mat)
\n-
54 {
\n-
55#ifdef DUNE_ISTL_WITH_CHECKING
\n-
56 typedef typename Matrix::ConstRowIterator Row;
\n-
57 typedef typename Matrix::ConstColIterator Entry;
\n-
58 for(Row row = mat.begin(); row!=mat.end(); ++row) {
\n-
59 Entry diagonal = row->find(row.index());
\n-
60 if(diagonal==row->end())
\n-
61 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
\n-
62 <<" at block recursion level "<<l-blocklevel);
\n-
63 else{
\n-
64 auto m = Impl::asMatrix(*diagonal);
\n-
65 CheckIfDiagonalPresent<decltype(m),blocklevel-1,l>::check(m);
\n-
66 }
\n-
67 }
\n-
68#endif
\n-
69 }
\n-
70 };
\n-
71
\n-
72 template<class Matrix, std::size_t l>
\n-\n-
74 {
\n-
75 static void check(const Matrix& mat)
\n-
76 {
\n-
77 typedef typename Matrix::ConstRowIterator Row;
\n-
78 for(Row row = mat.begin(); row!=mat.end(); ++row) {
\n-
79 if(row->find(row.index())==row->end())
\n-
80 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
\n-
81 <<" at block recursion level "<<l);
\n-
82 }
\n-
83 }
\n-
84 };
\n-
85
\n-
86 template<typename FirstRow, typename... Args>
\n-
87 class MultiTypeBlockMatrix;
\n-
88
\n-
89 template<std::size_t blocklevel, std::size_t l, typename T1, typename... Args>
\n-\n-
91 blocklevel,l>
\n+
8#if HAVE_SUPERLU
\n+
9
\n+
10#include "superlufunctions.hh"
\n+
11#include "solvers.hh"
\n+
12#include "supermatrix.hh"
\n+
13#include <algorithm>
\n+
14#include <functional>
\n+
15#include "bcrsmatrix.hh"
\n+
16#include "bvector.hh"
\n+
17#include "istlexception.hh"
\n+
18#include <dune/common/fmatrix.hh>
\n+
19#include <dune/common/fvector.hh>
\n+
20#include <dune/common/stdstreams.hh>
\n+\n+\n+
23
\n+
24namespace Dune
\n+
25{
\n+
26
\n+
37 template<class M, class T, class TM, class TD, class TA>
\n+
38 class SeqOverlappingSchwarz;
\n+
39
\n+
40 template<class T, bool tag>
\n+
41 struct SeqOverlappingSchwarzAssemblerHelper;
\n+
42
\n+
43 template<class T>
\n+\n+
45 {};
\n+
46
\n+
47 template<class T>
\n+\n+
49 {};
\n+
50
\n+
51 template<class T>
\n+\n+
53 {};
\n+
54
\n+
55 template<class T>
\n+\n+
57 {};
\n+
58
\n+
59#if __has_include("slu_sdefs.h")
\n+
60 template<>
\n+
61 struct SuperLUDenseMatChooser<float>
\n+
62 {
\n+
63 static void create(SuperMatrix *mat, int n, int m, float *dat, int n1,
\n+
64 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
\n+
65 {
\n+
66 sCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
\n+
67
\n+
68 }
\n+
69
\n+
70 static void destroy(SuperMatrix*)
\n+
71 {}
\n+
72
\n+
73 };
\n+
74 template<>
\n+
75 struct SuperLUSolveChooser<float>
\n+
76 {
\n+
77 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
\n+
78 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
\n+
79 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
\n+
80 float *rpg, float *rcond, float *ferr, float *berr,
\n+
81 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
\n+
82 {
\n+
83 GlobalLU_t gLU;
\n+
84 sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
\n+
85 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
\n+
86 &gLU, memusage, stat, info);
\n+
87 }
\n+
88 };
\n+
89
\n+
90 template<>
\n+
91 struct QuerySpaceChooser<float>
\n
92 {
\n-
93 typedef MultiTypeBlockMatrix<T1,Args...> Matrix;
\n-
94
\n-
99 static void check(const Matrix& /* mat */)
\n-
100 {
\n-
101#ifdef DUNE_ISTL_WITH_CHECKING
\n-
102 // TODO Implement check
\n-
103#endif
\n-
104 }
\n-
105 };
\n-
106
\n-
118 template<class M>
\n-
119 inline auto countNonZeros(const M&,
\n-
120 [[maybe_unused]] typename std::enable_if_t<Dune::IsNumber<M>::value>* sfinae = nullptr)
\n-
121 {
\n-
122 return 1;
\n-
123 }
\n-
124
\n-
125 template<class M>
\n-
126 inline auto countNonZeros(const M& matrix,
\n-
127 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
\n-
128 {
\n-
129 typename M::size_type nonZeros = 0;
\n-
130 for(auto&& row : matrix)
\n-
131 for(auto&& entry : row)
\n-
132 nonZeros += countNonZeros(entry);
\n-
133 return nonZeros;
\n-
134 }
\n-
135
\n-
136 /*
\n-
137 template<class M>
\n-
138 struct ProcessOnFieldsOfMatrix
\n-
139 */
\n-
140
\n-
142 namespace
\n-
143 {
\n-
144 struct CompPair {
\n-
145 template<class G,class M>
\n-
146 bool operator()(const std::pair<G,M>& p1, const std::pair<G,M>& p2) const
\n-
147 {
\n-
148 return p1.first<p2.first;
\n-
149 }
\n-
150 };
\n-
151
\n-
152 }
\n-
153 template<class M, class C>
\n-
154 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)
\n-
155 {
\n-
156 typedef typename C::ParallelIndexSet::const_iterator IIter;
\n-
157 typedef typename C::OwnerSet OwnerSet;
\n-
158 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;
\n-
159
\n-
160 GlobalIndex gmax=0;
\n-
161
\n-
162 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
\n-
163 idx!=eidx; ++idx)
\n-
164 gmax=std::max(gmax,idx->global());
\n-
165
\n-
166 gmax=ooc.communicator().max(gmax);
\n-
167 ooc.buildGlobalLookup();
\n-
168
\n-
169 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
\n-
170 idx!=eidx; ++idx) {
\n-
171 if(OwnerSet::contains(idx->local().attribute()))
\n-
172 {
\n-
173 typedef typename M::block_type Block;
\n-
174
\n-
175 std::set<std::pair<GlobalIndex,Block>,CompPair> entries;
\n-
176
\n-
177 // sort rows
\n-
178 typedef typename M::ConstColIterator CIter;
\n-
179 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();
\n-
180 c!=cend; ++c) {
\n-
181 const typename C::ParallelIndexSet::IndexPair* pair
\n-
182 =ooc.globalLookup().pair(c.index());
\n-
183 assert(pair);
\n-
184 entries.insert(std::make_pair(pair->global(), *c));
\n-
185 }
\n-
186
\n-
187 //wait until its the rows turn.
\n-
188 GlobalIndex rowidx = idx->global();
\n-
189 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
\n-
190 while(cur!=rowidx)
\n-
191 cur=ooc.communicator().min(rowidx);
\n-
192
\n-
193 // print rows
\n-
194 typedef typename std::set<std::pair<GlobalIndex,Block>,CompPair>::iterator SIter;
\n-
195 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)
\n-
196 os<<idx->global()<<" "<<s->first<<" "<<s->second<<std::endl;
\n+
93 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
\n+
94 {
\n+
95 sQuerySpace(L,U,memusage);
\n+
96 }
\n+
97 };
\n+
98
\n+
99#endif
\n+
100
\n+
101#if __has_include("slu_ddefs.h")
\n+
102
\n+
103 template<>
\n+
104 struct SuperLUDenseMatChooser<double>
\n+
105 {
\n+
106 static void create(SuperMatrix *mat, int n, int m, double *dat, int n1,
\n+
107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
\n+
108 {
\n+
109 dCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
\n+
110
\n+
111 }
\n+
112
\n+
113 static void destroy(SuperMatrix * /* mat */)
\n+
114 {}
\n+
115 };
\n+
116 template<>
\n+
117 struct SuperLUSolveChooser<double>
\n+
118 {
\n+
119 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
\n+
120 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
\n+
121 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
\n+
122 double *rpg, double *rcond, double *ferr, double *berr,
\n+
123 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
\n+
124 {
\n+
125 GlobalLU_t gLU;
\n+
126 dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
\n+
127 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
\n+
128 &gLU, memusage, stat, info);
\n+
129 }
\n+
130 };
\n+
131
\n+
132 template<>
\n+
133 struct QuerySpaceChooser<double>
\n+
134 {
\n+
135 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
\n+
136 {
\n+
137 dQuerySpace(L,U,memusage);
\n+
138 }
\n+
139 };
\n+
140#endif
\n+
141
\n+
142#if __has_include("slu_zdefs.h")
\n+
143 template<>
\n+
144 struct SuperLUDenseMatChooser<std::complex<double> >
\n+
145 {
\n+
146 static void create(SuperMatrix *mat, int n, int m, std::complex<double> *dat, int n1,
\n+
147 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
\n+
148 {
\n+
149 zCreate_Dense_Matrix(mat, n, m, reinterpret_cast<doublecomplex*>(dat), n1, stype, dtype, mtype);
\n+
150
\n+
151 }
\n+
152
\n+
153 static void destroy(SuperMatrix*)
\n+
154 {}
\n+
155 };
\n+
156
\n+
157 template<>
\n+
158 struct SuperLUSolveChooser<std::complex<double> >
\n+
159 {
\n+
160 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
\n+
161 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
\n+
162 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
\n+
163 double *rpg, double *rcond, double *ferr, double *berr,
\n+
164 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
\n+
165 {
\n+
166 GlobalLU_t gLU;
\n+
167 zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
\n+
168 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
\n+
169 &gLU, memusage, stat, info);
\n+
170 }
\n+
171 };
\n+
172
\n+
173 template<>
\n+
174 struct QuerySpaceChooser<std::complex<double> >
\n+
175 {
\n+
176 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
\n+
177 {
\n+
178 zQuerySpace(L,U,memusage);
\n+
179 }
\n+
180 };
\n+
181#endif
\n+
182
\n+
183#if __has_include("slu_cdefs.h")
\n+
184 template<>
\n+
185 struct SuperLUDenseMatChooser<std::complex<float> >
\n+
186 {
\n+
187 static void create(SuperMatrix *mat, int n, int m, std::complex<float> *dat, int n1,
\n+
188 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
\n+
189 {
\n+
190 cCreate_Dense_Matrix(mat, n, m, reinterpret_cast< ::complex*>(dat), n1, stype, dtype, mtype);
\n+
191
\n+
192 }
\n+
193
\n+
194 static void destroy(SuperMatrix* /* mat */)
\n+
195 {}
\n+
196 };
\n
197
\n-
198
\n-
199 }
\n-
200 }
\n-
201
\n-
202 ooc.freeGlobalLookup();
\n-
203 // Wait until everybody is finished
\n-
204 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
\n-
205 while(cur!=ooc.communicator().min(cur)) ;
\n-
206 }
\n-
207
\n-
208 // Default implementation for scalar types
\n-
209 template<typename M>
\n-\n-
211 {
\n-
212 static_assert(IsNumber<M>::value, "MatrixDimension is not implemented for this type!");
\n+
198 template<>
\n+
199 struct SuperLUSolveChooser<std::complex<float> >
\n+
200 {
\n+
201 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
\n+
202 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
\n+
203 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
\n+
204 float *rpg, float *rcond, float *ferr, float *berr,
\n+
205 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
\n+
206 {
\n+
207 GlobalLU_t gLU;
\n+
208 cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
\n+
209 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
\n+
210 &gLU, memusage, stat, info);
\n+
211 }
\n+
212 };
\n
213
\n-
214 static auto rowdim(const M& A)
\n-
215 {
\n-
216 return 1;
\n-
217 }
\n-
218
\n-
219 static auto coldim(const M& A)
\n-
220 {
\n-
221 return 1;
\n-
222 }
\n-
223 };
\n-
224
\n-
225 // Default implementation for scalar types
\n-
226 template<typename B, typename TA>
\n-
227 struct MatrixDimension<Matrix<B,TA> >
\n-
228 {
\n-\n-\n-
231
\n-\n-
233 {
\n-\n-
235 }
\n-
236
\n-\n-
238 {
\n-\n-
240 }
\n-
241
\n-
242 static size_type rowdim (const Matrix<B,TA>& A)
\n-
243 {
\n-
244 size_type nn=0;
\n-
245 for (size_type i=0; i<A.N(); i++)
\n-
246 nn += rowdim(A,i);
\n-
247 return nn;
\n-
248 }
\n-
249
\n-
250 static size_type coldim (const Matrix<B,TA>& A)
\n-
251 {
\n-
252 size_type nn=0;
\n-
253 for (size_type i=0; i<A.M(); i++)
\n-
254 nn += coldim(A,i);
\n-
255 return nn;
\n-
256 }
\n-
257 };
\n-
258
\n-
259
\n-
260 template<typename B, typename TA>
\n-\n-
262 {
\n-\n-\n-
265 typedef typename Matrix::size_type size_type;
\n-
266
\n-
267 static size_type rowdim (const Matrix& A, size_type i)
\n-
268 {
\n-
269 const B* row = A.r[i].getptr();
\n-
270 if(row)
\n-\n-
272 else
\n-
273 return 0;
\n-
274 }
\n-
275
\n-
276 static size_type coldim (const Matrix& A, size_type c)
\n-
277 {
\n-
278 // find an entry in column c
\n-
279 if (A.nnz_ > 0)
\n-
280 {
\n-
281 for (size_type k=0; k<A.nnz_; k++) {
\n-
282 if (A.j_.get()[k] == c) {
\n-\n-
284 }
\n-
285 }
\n-
286 }
\n-
287 else
\n-
288 {
\n-
289 for (size_type i=0; i<A.N(); i++)
\n-
290 {
\n-
291 size_type* j = A.r[i].getindexptr();
\n-
292 B* a = A.r[i].getptr();
\n-
293 for (size_type k=0; k<A.r[i].getsize(); k++)
\n-
294 if (j[k]==c) {
\n-\n-
296 }
\n-
297 }
\n-
298 }
\n-
299
\n-
300 // not found
\n-
301 return 0;
\n-
302 }
\n-
303
\n-
304 static size_type rowdim (const Matrix& A){
\n-
305 size_type nn=0;
\n-
306 for (size_type i=0; i<A.N(); i++)
\n-
307 nn += rowdim(A,i);
\n-
308 return nn;
\n-
309 }
\n-
310
\n-
311 static size_type coldim (const Matrix& A){
\n-
312 typedef typename Matrix::ConstRowIterator ConstRowIterator;
\n-
313 typedef typename Matrix::ConstColIterator ConstColIterator;
\n-
314
\n-
315 // The following code has a complexity of nnz, and
\n-
316 // typically a very small constant.
\n-
317 //
\n-
318 std::vector<size_type> coldims(A.M(),
\n-
319 std::numeric_limits<size_type>::max());
\n-
320
\n-
321 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)
\n-
322 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)
\n-
323 // only compute blocksizes we don't already have
\n-
324 if (coldims[col.index()]==std::numeric_limits<size_type>::max())
\n-
325 coldims[col.index()] = MatrixDimension<block_type>::coldim(*col);
\n-
326
\n-
327 size_type sum = 0;
\n-
328 for (typename std::vector<size_type>::iterator it=coldims.begin();
\n-
329 it!=coldims.end(); ++it)
\n-
330 // skip rows for which no coldim could be determined
\n-
331 if ((*it)>=0)
\n-
332 sum += *it;
\n+
214 template<>
\n+
215 struct QuerySpaceChooser<std::complex<float> >
\n+
216 {
\n+
217 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
\n+
218 {
\n+
219 cQuerySpace(L,U,memusage);
\n+
220 }
\n+
221 };
\n+
222#endif
\n+
223
\n+
224 namespace Impl
\n+
225 {
\n+
226 template<class M>
\n+
227 struct SuperLUVectorChooser
\n+
228 {};
\n+
229
\n+
230 template<typename T, typename A, int n, int m>
\n+
231 struct SuperLUVectorChooser<BCRSMatrix<FieldMatrix<T,n,m>,A > >
\n+
232 {
\n+
234 using domain_type = BlockVector<
\n+
235 FieldVector<T,m>,
\n+
236 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,m> > >;
\n+
238 using range_type = BlockVector<
\n+
239 FieldVector<T,n>,
\n+
240 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,n> > >;
\n+
241 };
\n+
242
\n+
243 template<typename T, typename A>
\n+
244 struct SuperLUVectorChooser<BCRSMatrix<T,A> >
\n+
245 {
\n+
247 using domain_type = BlockVector<T, A>;
\n+
249 using range_type = BlockVector<T, A>;
\n+
250 };
\n+
251 }
\n+
252
\n+
266 template<typename M>
\n+\n+
268 : public InverseOperator<
\n+
269 typename Impl::SuperLUVectorChooser<M>::domain_type,
\n+
270 typename Impl::SuperLUVectorChooser<M>::range_type >
\n+
271 {
\n+
272 using T = typename M::field_type;
\n+
273 public:
\n+
275 using Matrix = M;
\n+
276 using matrix_type = M;
\n+\n+\n+
282 using domain_type = typename Impl::SuperLUVectorChooser<M>::domain_type;
\n+
284 using range_type = typename Impl::SuperLUVectorChooser<M>::range_type;
\n+
285
\n+\n+
288 {
\n+
289 return SolverCategory::Category::sequential;
\n+
290 }
\n+
291
\n+
306 explicit SuperLU(const Matrix& mat, bool verbose=false,
\n+
307 bool reusevector=true);
\n+
308
\n+
309
\n+
320 SuperLU(const Matrix& mat, const ParameterTree& config)
\n+
321 : SuperLU(mat, config.get<bool>("verbose", false), config.get<bool>("reuseVector", true))
\n+
322 {}
\n+
323
\n+
330 SuperLU();
\n+
331
\n+
332 ~SuperLU();
\n
333
\n-
334 return sum;
\n-
335 }
\n-
336 };
\n-
337
\n+\n
338
\n-
339 template<typename B, int n, int m, typename TA>
\n-\n-
341 {
\n-\n-
343 typedef typename Matrix::size_type size_type;
\n-
344
\n-
345 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)
\n-
346 {
\n-
347 return n;
\n-
348 }
\n-
349
\n-
350 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)
\n-
351 {
\n-
352 return m;
\n-
353 }
\n+
342 void apply (domain_type& x, range_type& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
\n+
343 {
\n+
344 apply(x,b,res);
\n+
345 }
\n+
346
\n+
350 void apply(T* x, T* b);
\n+
351
\n+
353 void setMatrix(const Matrix& mat);
\n
354
\n-
355 static size_type rowdim (const Matrix& A) {
\n-
356 return A.N()*n;
\n-
357 }
\n-
358
\n-
359 static size_type coldim (const Matrix& A) {
\n-
360 return A.M()*m;
\n-
361 }
\n-
362 };
\n-
363
\n-
364 template<typename K, int n, int m>
\n-\n-
366 {
\n-\n-
368 typedef typename Matrix::size_type size_type;
\n-
369
\n-
370 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
\n-
371 {
\n-
372 return 1;
\n-
373 }
\n-
374
\n-
375 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
\n-
376 {
\n-
377 return 1;
\n-
378 }
\n-
379
\n-
380 static size_type rowdim(const Matrix& /*A*/)
\n-
381 {
\n-
382 return n;
\n-
383 }
\n-
384
\n-
385 static size_type coldim(const Matrix& /*A*/)
\n-
386 {
\n-
387 return m;
\n-
388 }
\n-
389 };
\n-
390
\n-
391 template <class T>
\n-
392 struct MatrixDimension<Dune::DynamicMatrix<T> >
\n-
393 {
\n-
394 typedef Dune::DynamicMatrix<T> MatrixType;
\n-
395 typedef typename MatrixType::size_type size_type;
\n-
396
\n-
397 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)
\n-
398 {
\n-
399 return 1;
\n-
400 }
\n+
355 typename SuperLUMatrix::size_type nnz() const
\n+
356 {
\n+
357 return mat.nonzeroes();
\n+
358 }
\n+
359
\n+
360 template<class S>
\n+
361 void setSubMatrix(const Matrix& mat, const S& rowIndexSet);
\n+
362
\n+
363 void setVerbosity(bool v);
\n+
364
\n+
369 void free();
\n+
370
\n+
371 const char* name() { return "SuperLU"; }
\n+
372 private:
\n+
373 template<class Mat,class X, class TM, class TD, class T1>
\n+\n+\n+
376
\n+
377 SuperLUMatrix& getInternalMatrix() { return mat; }
\n+
378
\n+
380 void decompose();
\n+
381
\n+\n+
383 SuperMatrix L, U, B, X;
\n+
384 int *perm_c, *perm_r, *etree;
\n+
385 typename GetSuperLUType<T>::float_type *R, *C;
\n+
386 T *bstore;
\n+
387 superlu_options_t options;
\n+
388 char equed;
\n+
389 void *work;
\n+
390 int lwork;
\n+
391 bool first, verbose, reusevector;
\n+
392 };
\n+
393
\n+
394 template<typename M>
\n+\n+\n+
397 {
\n+
398 if(mat.N()+mat.M()>0)
\n+
399 free();
\n+
400 }
\n
401
\n-
402 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)
\n-
403 {
\n-
404 return 1;
\n-
405 }
\n-
406
\n-
407 static size_type rowdim(const MatrixType& A)
\n-
408 {
\n-
409 return A.N();
\n-
410 }
\n-
411
\n-
412 static size_type coldim(const MatrixType& A)
\n-
413 {
\n-
414 return A.M();
\n-
415 }
\n-
416 };
\n-
417
\n-
418 template<typename K, int n, int m, typename TA>
\n-
419 struct MatrixDimension<Matrix<FieldMatrix<K,n,m>, TA> >
\n-
420 {
\n-\n-\n-
423
\n-
424 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)
\n-
425 {
\n-
426 return n;
\n-
427 }
\n-
428
\n-
429 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)
\n-
430 {
\n-
431 return m;
\n-
432 }
\n-
433
\n-
434 static size_type rowdim(const ThisMatrix& A)
\n-
435 {
\n-
436 return A.N()*n;
\n-
437 }
\n-
438
\n-
439 static size_type coldim(const ThisMatrix& A)
\n-
440 {
\n-
441 return A.M()*m;
\n-
442 }
\n-
443 };
\n-
444
\n-
445 template<typename K, int n>
\n-
446 struct MatrixDimension<DiagonalMatrix<K,n> >
\n-
447 {
\n-
448 typedef DiagonalMatrix<K,n> Matrix;
\n-
449 typedef typename Matrix::size_type size_type;
\n-
450
\n-
451 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
\n-
452 {
\n-
453 return 1;
\n-
454 }
\n-
455
\n-
456 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
\n-
457 {
\n-
458 return 1;
\n-
459 }
\n-
460
\n-
461 static size_type rowdim(const Matrix& /*A*/)
\n-
462 {
\n-
463 return n;
\n-
464 }
\n-
465
\n-
466 static size_type coldim(const Matrix& /*A*/)
\n-
467 {
\n-
468 return n;
\n-
469 }
\n-
470 };
\n-
471
\n-
472 template<typename K, int n>
\n-\n-
474 {
\n-\n-
476 typedef typename Matrix::size_type size_type;
\n-
477
\n-
478 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
\n-
479 {
\n-
480 return 1;
\n-
481 }
\n-
482
\n-
483 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
\n-
484 {
\n-
485 return 1;
\n-
486 }
\n-
487
\n-
488 static size_type rowdim(const Matrix& /*A*/)
\n-
489 {
\n-
490 return n;
\n-
491 }
\n-
492
\n-
493 static size_type coldim(const Matrix& /*A*/)
\n-
494 {
\n-
495 return n;
\n-
496 }
\n-
497 };
\n-
498
\n-
502 template<typename T>
\n-
503 struct IsMatrix
\n-
504 {
\n-
505 enum {
\n-
509 value = false
\n-
510 };
\n-
511 };
\n+
402 template<typename M>
\n+\n+
404 {
\n+
405 delete[] perm_c;
\n+
406 delete[] perm_r;
\n+
407 delete[] etree;
\n+
408 delete[] R;
\n+
409 delete[] C;
\n+
410 if(lwork>=0) {
\n+
411 Destroy_SuperNode_Matrix(&L);
\n+
412 Destroy_CompCol_Matrix(&U);
\n+
413 }
\n+
414 lwork=0;
\n+
415 if(!first && reusevector) {
\n+
416 SUPERLU_FREE(B.Store);
\n+
417 SUPERLU_FREE(X.Store);
\n+
418 }
\n+
419 mat.free();
\n+
420 }
\n+
421
\n+
422 template<typename M>
\n+\n+
424 ::SuperLU(const Matrix& mat_, bool verbose_, bool reusevector_)
\n+
425 : work(0), lwork(0), first(true), verbose(verbose_),
\n+
426 reusevector(reusevector_)
\n+
427 {
\n+
428 setMatrix(mat_);
\n+
429
\n+
430 }
\n+
431 template<typename M>
\n+\n+
433 : work(0), lwork(0),verbose(false),
\n+
434 reusevector(false)
\n+
435 {}
\n+
436 template<typename M>
\n+\n+
438 {
\n+
439 verbose=v;
\n+
440 }
\n+
441
\n+
442 template<typename M>
\n+\n+
444 {
\n+
445 if(mat.N()+mat.M()>0) {
\n+
446 free();
\n+
447 }
\n+
448 lwork=0;
\n+
449 work=0;
\n+
450 //a=&mat_;
\n+
451 mat=mat_;
\n+
452 decompose();
\n+
453 }
\n+
454
\n+
455 template<typename M>
\n+
456 template<class S>
\n+\n+
458 const S& mrs)
\n+
459 {
\n+
460 if(mat.N()+mat.M()>0) {
\n+
461 free();
\n+
462 }
\n+
463 lwork=0;
\n+
464 work=0;
\n+
465 //a=&mat_;
\n+
466 mat.setMatrix(mat_,mrs);
\n+
467 decompose();
\n+
468 }
\n+
469
\n+
470 template<typename M>
\n+\n+
472 {
\n+
473
\n+
474 first = true;
\n+
475 perm_c = new int[mat.M()];
\n+
476 perm_r = new int[mat.N()];
\n+
477 etree = new int[mat.M()];
\n+
478 R = new typename GetSuperLUType<T>::float_type[mat.N()];
\n+
479 C = new typename GetSuperLUType<T>::float_type[mat.M()];
\n+
480
\n+
481 set_default_options(&options);
\n+
482 // Do the factorization
\n+
483 B.ncol=0;
\n+
484 B.Stype=SLU_DN;
\n+\n+
486 B.Mtype= SLU_GE;
\n+
487 DNformat fakeFormat;
\n+
488 fakeFormat.lda=mat.N();
\n+
489 B.Store=&fakeFormat;
\n+
490 X.Stype=SLU_DN;
\n+\n+
492 X.Mtype= SLU_GE;
\n+
493 X.ncol=0;
\n+
494 X.Store=&fakeFormat;
\n+
495
\n+
496 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr=1e10;
\n+
497 int info;
\n+
498 mem_usage_t memusage;
\n+
499 SuperLUStat_t stat;
\n+
500
\n+
501 StatInit(&stat);
\n+
502 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
\n+
503 &L, &U, work, lwork, &B, &X, &rpg, &rcond, &ferr,
\n+
504 &berr, &memusage, &stat, &info);
\n+
505
\n+
506 if(verbose) {
\n+
507 dinfo<<"LU factorization: dgssvx() returns info "<< info<<std::endl;
\n+
508
\n+
509 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
\n+
510
\n+
511 if ( info == 0 || info == nSuperLUCol+1 ) {
\n
512
\n-
513 template<typename T>
\n-
514 struct IsMatrix<DenseMatrix<T> >
\n-
515 {
\n-
516 enum {
\n-
520 value = true
\n-
521 };
\n-
522 };
\n-
523
\n-
524
\n-
525 template<typename T, typename A>
\n-
526 struct IsMatrix<BCRSMatrix<T,A> >
\n-
527 {
\n-
528 enum {
\n-
532 value = true
\n-
533 };
\n-
534 };
\n-
535
\n-
536 template<typename T>
\n-\n-
538 {
\n-
539 bool operator()(const T* l, const T* r)
\n-
540 {
\n-
541 return *l < *r;
\n-
542 }
\n-
543 };
\n-
544
\n-
545}
\n-
546#endif
\n-\n-
This file implements a quadratic matrix of fixed size which is a multiple of the identity.
\n-
Col col
Definition: matrixmatrix.hh:351
\n+
513 if ( options.PivotGrowth )
\n+
514 dinfo<<"Recip. pivot growth = "<<rpg<<std::endl;
\n+
515 if ( options.ConditionNumber )
\n+
516 dinfo<<"Recip. condition number = %e\\n"<< rcond<<std::endl;
\n+
517 SCformat* Lstore = (SCformat *) L.Store;
\n+
518 NCformat* Ustore = (NCformat *) U.Store;
\n+
519 dinfo<<"No of nonzeros in factor L = "<< Lstore->nnz<<std::endl;
\n+
520 dinfo<<"No of nonzeros in factor U = "<< Ustore->nnz<<std::endl;
\n+
521 dinfo<<"No of nonzeros in L+U = "<< Lstore->nnz + Ustore->nnz - nSuperLUCol<<std::endl;
\n+
522 QuerySpaceChooser<T>::querySpace(&L, &U, &memusage);
\n+
523 dinfo<<"L\\\\U MB "<<memusage.for_lu/1e6<<" \\ttotal MB needed "<<memusage.total_needed/1e6
\n+
524 <<" \\texpansions ";
\n+
525 std::cout<<stat.expansions<<std::endl;
\n+
526
\n+
527 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
\n+
528 dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<std::endl;
\n+
529 }
\n+
530 if ( options.PrintStat ) StatPrint(&stat);
\n+
531 }
\n+
532 StatFree(&stat);
\n+
533 /*
\n+
534 NCformat* Ustore = (NCformat *) U.Store;
\n+
535 int k=0;
\n+
536 dPrint_CompCol_Matrix("U", &U);
\n+
537 for(int i=0; i < U.ncol; ++i, ++k){
\n+
538 std::cout<<i<<": ";
\n+
539 for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
\n+
540 //if(Ustore->rowind[c]==i)
\n+
541 std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
\n+
542 if(k==0){
\n+
543 //
\n+
544 k=-1;
\n+
545 }std::cout<<std::endl;
\n+
546 }
\n+
547 dPrint_SuperNode_Matrix("L", &L);
\n+
548 for(int i=0; i < U.ncol; ++i, ++k){
\n+
549 std::cout<<i<<": ";
\n+
550 for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
\n+
551 //if(Ustore->rowind[c]==i)
\n+
552 std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
\n+
553 if(k==0){
\n+
554 //
\n+
555 k=-1;
\n+
556 }std::cout<<std::endl;
\n+
557 } */
\n+
558 options.Fact = FACTORED;
\n+
559 }
\n+
560
\n+
561 template<typename M>
\n+
562 void SuperLU<M>
\n+\n+
564 {
\n+
565 if (mat.N() != b.dim())
\n+
566 DUNE_THROW(ISTLError, "Size of right-hand-side vector b does not match the number of matrix rows!");
\n+
567 if (mat.M() != x.dim())
\n+
568 DUNE_THROW(ISTLError, "Size of solution vector x does not match the number of matrix columns!");
\n+
569 if (mat.M()+mat.N()==0)
\n+
570 DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
\n+
571
\n+
572 SuperMatrix* mB = &B;
\n+
573 SuperMatrix* mX = &X;
\n+
574 SuperMatrix rB, rX;
\n+
575 if (reusevector) {
\n+
576 if(first) {
\n+
577 SuperLUDenseMatChooser<T>::create(&B, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
578 SuperLUDenseMatChooser<T>::create(&X, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
579 first=false;
\n+
580 }else{
\n+
581 ((DNformat*)B.Store)->nzval=&b[0];
\n+
582 ((DNformat*)X.Store)->nzval=&x[0];
\n+
583 }
\n+
584 } else {
\n+
585 SuperLUDenseMatChooser<T>::create(&rB, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
586 SuperLUDenseMatChooser<T>::create(&rX, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
587 mB = &rB;
\n+
588 mX = &rX;
\n+
589 }
\n+
590 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
\n+
591 int info;
\n+
592 mem_usage_t memusage;
\n+
593 SuperLUStat_t stat;
\n+
594 /* Initialize the statistics variables. */
\n+
595 StatInit(&stat);
\n+
596 /*
\n+
597 range_type d=b;
\n+
598 a->usmv(-1, x, d);
\n+
599
\n+
600 double def0=d.two_norm();
\n+
601 */
\n+
602 options.IterRefine=SLU_DOUBLE;
\n+
603
\n+
604 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
\n+
605 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
\n+
606 &memusage, &stat, &info);
\n+
607
\n+
608 res.iterations=1;
\n+
609
\n+
610 /*
\n+
611 if(options.Equil==YES)
\n+
612 // undo scaling of right hand side
\n+
613 std::transform(reinterpret_cast<T*>(&b[0]),reinterpret_cast<T*>(&b[0])+mat.M(),
\n+
614 C, reinterpret_cast<T*>(&d[0]), std::divides<T>());
\n+
615 else
\n+
616 d=b;
\n+
617 a->usmv(-1, x, d);
\n+
618 res.reduction=d.two_norm()/def0;
\n+
619 res.conv_rate = res.reduction;
\n+
620 res.converged=(res.reduction<1e-10||d.two_norm()<1e-18);
\n+
621 */
\n+
622 res.converged=true;
\n+
623
\n+
624 if(verbose) {
\n+
625
\n+
626 dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
\n+
627
\n+
628 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
\n+
629
\n+
630 if ( info == 0 || info == nSuperLUCol+1 ) {
\n+
631
\n+
632 if ( options.IterRefine ) {
\n+
633 std::cout<<"Iterative Refinement: steps="
\n+
634 <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
\n+
635 }else
\n+
636 std::cout<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
\n+
637 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
\n+
638 std::cout<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
\n+
639 }
\n+
640
\n+
641 if ( options.PrintStat ) StatPrint(&stat);
\n+
642 }
\n+
643 StatFree(&stat);
\n+
644 if (!reusevector) {
\n+
645 SUPERLU_FREE(rB.Store);
\n+
646 SUPERLU_FREE(rX.Store);
\n+
647 }
\n+
648 }
\n+
649
\n+
650 template<typename M>
\n+
651 void SuperLU<M>
\n+
652 ::apply(T* x, T* b)
\n+
653 {
\n+
654 if(mat.N()+mat.M()==0)
\n+
655 DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
\n+
656
\n+
657 SuperMatrix* mB = &B;
\n+
658 SuperMatrix* mX = &X;
\n+
659 SuperMatrix rB, rX;
\n+
660 if (reusevector) {
\n+
661 if(first) {
\n+
662 SuperLUDenseMatChooser<T>::create(&B, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
663 SuperLUDenseMatChooser<T>::create(&X, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
664 first=false;
\n+
665 }else{
\n+
666 ((DNformat*) B.Store)->nzval=b;
\n+
667 ((DNformat*)X.Store)->nzval=x;
\n+
668 }
\n+
669 } else {
\n+
670 SuperLUDenseMatChooser<T>::create(&rB, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
671 SuperLUDenseMatChooser<T>::create(&rX, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
\n+
672 mB = &rB;
\n+
673 mX = &rX;
\n+
674 }
\n+
675
\n+
676 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
\n+
677 int info;
\n+
678 mem_usage_t memusage;
\n+
679 SuperLUStat_t stat;
\n+
680 /* Initialize the statistics variables. */
\n+
681 StatInit(&stat);
\n+
682
\n+
683 options.IterRefine=SLU_DOUBLE;
\n+
684
\n+
685 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
\n+
686 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
\n+
687 &memusage, &stat, &info);
\n+
688
\n+
689 if(verbose) {
\n+
690 dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
\n+
691
\n+
692 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
\n+
693
\n+
694 if ( info == 0 || info == nSuperLUCol+1 ) { // Factorization has succeeded
\n+
695
\n+
696 if ( options.IterRefine ) {
\n+
697 dinfo<<"Iterative Refinement: steps="
\n+
698 <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
\n+
699 }else
\n+
700 dinfo<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
\n+
701 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
\n+
702 dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
\n+
703 }
\n+
704 if ( options.PrintStat ) StatPrint(&stat);
\n+
705 }
\n+
706
\n+
707 StatFree(&stat);
\n+
708 if (!reusevector) {
\n+
709 SUPERLU_FREE(rB.Store);
\n+
710 SUPERLU_FREE(rX.Store);
\n+
711 }
\n+
712 }
\n+
715 template<typename T, typename A>
\n+\n+
717 {
\n+
718 enum { value=true};
\n+
719 };
\n+
720
\n+
721 template<typename T, typename A>
\n+\n+
723 {
\n+
724 enum { value = true };
\n+
725 };
\n+
726
\n+\n+
728 template<class> struct isValidBlock : std::false_type{};
\n+
729 template<int k> struct isValidBlock<Dune::FieldVector<double,k>> : std::true_type{};
\n+
730 template<int k> struct isValidBlock<Dune::FieldVector<std::complex<double>,k>> : std::true_type{};
\n+
731 template<typename TL, typename M>
\n+
732 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
\n+
733 typename Dune::TypeListElement<2, TL>::type>>
\n+
734 operator() (TL /*tl*/, const M& mat, const Dune::ParameterTree& config,
\n+
735 std::enable_if_t<isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
\n+
736 {
\n+
737 int verbose = config.get("verbose", 0);
\n+
738 return std::make_shared<Dune::SuperLU<M>>(mat,verbose);
\n+
739 }
\n+
740
\n+
741 // second version with SFINAE to validate the template parameters of SuperLU
\n+
742 template<typename TL, typename M>
\n+
743 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
\n+
744 typename Dune::TypeListElement<2, TL>::type>>
\n+
745 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
\n+
746 std::enable_if_t<!isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
\n+
747 {
\n+
748 DUNE_THROW(UnsupportedType,
\n+
749 "Unsupported Type in SuperLU (only double and std::complex<double> supported)");
\n+
750 }
\n+
751 };
\n+
752 template<> struct SuperLUCreator::isValidBlock<double> : std::true_type{};
\n+
753 template<> struct SuperLUCreator::isValidBlock<std::complex<double>> : std::true_type{};
\n+
754
\n+\n+
756} // end namespace DUNE
\n+
757
\n+
758// undefine macros from SuperLU's slu_util.h
\n+
759#undef FIRSTCOL_OF_SNODE
\n+
760#undef NO_MARKER
\n+
761#undef NUM_TEMPV
\n+
762#undef USER_ABORT
\n+
763#undef USER_MALLOC
\n+
764#undef SUPERLU_MALLOC
\n+
765#undef USER_FREE
\n+
766#undef SUPERLU_FREE
\n+
767#undef CHECK_MALLOC
\n+
768#undef SUPERLU_MAX
\n+
769#undef SUPERLU_MIN
\n+
770#undef L_SUB_START
\n+
771#undef L_SUB
\n+
772#undef L_NZ_START
\n+
773#undef L_FST_SUPC
\n+
774#undef U_NZ_START
\n+
775#undef U_SUB
\n+
776#undef TRUE
\n+
777#undef FALSE
\n+
778#undef EMPTY
\n+
779#undef NODROP
\n+
780#undef DROP_BASIC
\n+
781#undef DROP_PROWS
\n+
782#undef DROP_COLUMN
\n+
783#undef DROP_AREA
\n+
784#undef DROP_SECONDARY
\n+
785#undef DROP_DYNAMIC
\n+
786#undef DROP_INTERP
\n+
787#undef MILU_ALPHA
\n+
788
\n+
789#endif // HAVE_SUPERLU
\n+
790#endif // DUNE_SUPERLU_HH
\n+
Templates characterizing the type of a solver.
\n+
Implementation of the BCRSMatrix class.
\n+\n+
This file implements a vector space as a tensor product of a given vector space. The number of compon...
\n+\n+
Implementations of the inverse operator interface.
\n+\n+\n+
void setSubMatrix(const Matrix &mat, const S &rowIndexSet)
Definition: superlu.hh:457
\n+
void apply(domain_type &x, range_type &b, InverseOperatorResult &res)
Apply inverse operator,.
Definition: superlu.hh:563
\n+
DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
\n+
void setVerbosity(bool v)
Definition: superlu.hh:437
\n+
void free()
free allocated space.
Definition: superlu.hh:403
\n+
~SuperLU()
Definition: superlu.hh:396
\n+
SuperLU()
Empty default constructor.
Definition: superlu.hh:432
\n+
void setMatrix(const Matrix &mat)
Initialize data from given matrix.
Definition: superlu.hh:443
\n
Matrix & mat
Definition: matrixmatrix.hh:347
\n-
auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
Get the number of nonzero fields in the matrix.
Definition: matrixutils.hh:119
\n+
STL namespace.
\n
Definition: allocator.hh:11
\n-
void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)
Definition: matrixutils.hh:154
\n-
Definition: matrixutils.hh:211
\n-
static auto coldim(const M &A)
Definition: matrixutils.hh:219
\n-
static auto rowdim(const M &A)
Definition: matrixutils.hh:214
\n+
PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
Definition: dependency.hh:293
\n
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:466
\n-
A::size_type size_type
The type for the index access and the size.
Definition: bcrsmatrix.hh:500
\n-
row_type::ConstIterator ConstColIterator
Const iterator to the entries of a row.
Definition: bcrsmatrix.hh:741
\n-
B block_type
export the type representing the components
Definition: bcrsmatrix.hh:491
\n-
Iterator access to matrix rows
Definition: bcrsmatrix.hh:579
\n-
A Matrix class to support different block types.
Definition: multitypeblockmatrix.hh:46
\n
derive error class from the base class in common
Definition: istlexception.hh:19
\n-
ConstIterator class for sequential access.
Definition: matrix.hh:404
\n+
Sequential overlapping Schwarz preconditioner.
Definition: overlappingschwarz.hh:755
\n+
Definition: overlappingschwarz.hh:694
\n
A generic dynamic dense matrix.
Definition: matrix.hh:561
\n-
A::size_type size_type
Type for indices and sizes.
Definition: matrix.hh:577
\n-
RowIterator end()
Get iterator to one beyond last row.
Definition: matrix.hh:620
\n-
RowIterator begin()
Get iterator to first row.
Definition: matrix.hh:614
\n-
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition: matrix.hh:589
\n-
T block_type
Export the type representing the components.
Definition: matrix.hh:568
\n-
Definition: matrixutils.hh:27
\n-
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition: matrixutils.hh:48
\n-
static void check(const Matrix &mat)
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition: matrixutils.hh:53
\n-
static void check(const Matrix &mat)
Definition: matrixutils.hh:75
\n-
static void check(const Matrix &)
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition: matrixutils.hh:99
\n-
MultiTypeBlockMatrix< T1, Args... > Matrix
Definition: matrixutils.hh:93
\n-
static size_type rowdim(const Matrix< B, TA > &A, size_type i)
Definition: matrixutils.hh:232
\n-
static size_type coldim(const Matrix< B, TA > &A)
Definition: matrixutils.hh:250
\n-
static size_type rowdim(const Matrix< B, TA > &A)
Definition: matrixutils.hh:242
\n-
typename Matrix< B, TA >::size_type size_type
Definition: matrixutils.hh:230
\n-
static size_type coldim(const Matrix< B, TA > &A, size_type c)
Definition: matrixutils.hh:237
\n-
typename Matrix< B, TA >::block_type block_type
Definition: matrixutils.hh:229
\n-
BCRSMatrix< B, TA > Matrix
Definition: matrixutils.hh:263
\n-
static size_type coldim(const Matrix &A)
Definition: matrixutils.hh:311
\n-
Matrix::block_type block_type
Definition: matrixutils.hh:264
\n-
static size_type coldim(const Matrix &A, size_type c)
Definition: matrixutils.hh:276
\n-
Matrix::size_type size_type
Definition: matrixutils.hh:265
\n-
static size_type rowdim(const Matrix &A, size_type i)
Definition: matrixutils.hh:267
\n-
static size_type rowdim(const Matrix &A)
Definition: matrixutils.hh:304
\n-
static size_type coldim(const Matrix &A)
Definition: matrixutils.hh:359
\n-
static size_type rowdim(const Matrix &, size_type)
Definition: matrixutils.hh:345
\n-
static size_type rowdim(const Matrix &A)
Definition: matrixutils.hh:355
\n-
Matrix::size_type size_type
Definition: matrixutils.hh:343
\n-
BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix
Definition: matrixutils.hh:342
\n-
static size_type coldim(const Matrix &, size_type)
Definition: matrixutils.hh:350
\n-
static size_type rowdim(const Matrix &, size_type)
Definition: matrixutils.hh:370
\n-
static size_type coldim(const Matrix &)
Definition: matrixutils.hh:385
\n-
Matrix::size_type size_type
Definition: matrixutils.hh:368
\n-
FieldMatrix< K, n, m > Matrix
Definition: matrixutils.hh:367
\n-
static size_type coldim(const Matrix &, size_type)
Definition: matrixutils.hh:375
\n-
static size_type rowdim(const Matrix &)
Definition: matrixutils.hh:380
\n-
static size_type coldim(const MatrixType &A)
Definition: matrixutils.hh:412
\n-
static size_type rowdim(const MatrixType &A)
Definition: matrixutils.hh:407
\n-
static size_type rowdim(const MatrixType &, size_type)
Definition: matrixutils.hh:397
\n-
MatrixType::size_type size_type
Definition: matrixutils.hh:395
\n-
static size_type coldim(const MatrixType &, size_type)
Definition: matrixutils.hh:402
\n-
Dune::DynamicMatrix< T > MatrixType
Definition: matrixutils.hh:394
\n-
static size_type coldim(const ThisMatrix &A)
Definition: matrixutils.hh:439
\n-
static size_type rowdim(const ThisMatrix &A)
Definition: matrixutils.hh:434
\n-
Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix
Definition: matrixutils.hh:421
\n-
static size_type coldim(const ThisMatrix &, size_type)
Definition: matrixutils.hh:429
\n-
static size_type rowdim(const ThisMatrix &, size_type)
Definition: matrixutils.hh:424
\n-
ThisMatrix::size_type size_type
Definition: matrixutils.hh:422
\n-
static size_type coldim(const Matrix &, size_type)
Definition: matrixutils.hh:456
\n-
Matrix::size_type size_type
Definition: matrixutils.hh:449
\n-
static size_type coldim(const Matrix &)
Definition: matrixutils.hh:466
\n-
static size_type rowdim(const Matrix &)
Definition: matrixutils.hh:461
\n-
DiagonalMatrix< K, n > Matrix
Definition: matrixutils.hh:448
\n-
static size_type rowdim(const Matrix &, size_type)
Definition: matrixutils.hh:451
\n-
static size_type coldim(const Matrix &)
Definition: matrixutils.hh:493
\n-
static size_type rowdim(const Matrix &, size_type)
Definition: matrixutils.hh:478
\n-
static size_type coldim(const Matrix &, size_type)
Definition: matrixutils.hh:483
\n-
Matrix::size_type size_type
Definition: matrixutils.hh:476
\n-
ScaledIdentityMatrix< K, n > Matrix
Definition: matrixutils.hh:475
\n-
static size_type rowdim(const Matrix &)
Definition: matrixutils.hh:488
\n-
Test whether a type is an ISTL Matrix.
Definition: matrixutils.hh:504
\n-
@ value
True if T is an ISTL matrix.
Definition: matrixutils.hh:509
\n-
Definition: matrixutils.hh:538
\n-
bool operator()(const T *l, const T *r)
Definition: matrixutils.hh:539
\n-
A multiple of the identity matrix of static size.
Definition: scaledidmatrix.hh:30
\n-
std::size_t size_type
The type used for the index access and size operations.
Definition: scaledidmatrix.hh:43
\n+
size_type M() const
Return the number of columns.
Definition: matrix.hh:700
\n+
size_type N() const
Return the number of rows.
Definition: matrix.hh:695
\n+
Statistics about the application of an inverse operator.
Definition: solver.hh:48
\n+
int iterations
Number of iterations.
Definition: solver.hh:67
\n+
bool converged
True if convergence criterion has been met.
Definition: solver.hh:73
\n+
Abstract base class for all solvers.
Definition: solver.hh:99
\n+
Category
Definition: solvercategory.hh:23
\n+
Definition: solverregistry.hh:77
\n+
Definition: solvertype.hh:16
\n+
@ value
Whether this is a direct solver.
Definition: solvertype.hh:24
\n+
Definition: solvertype.hh:30
\n+
@ value
whether the solver internally uses column compressed storage
Definition: solvertype.hh:36
\n+
Definition: superlu.hh:45
\n+
Definition: superlu.hh:49
\n+
Definition: superlu.hh:53
\n+
Definition: superlu.hh:57
\n+
SuperLu Solver.
Definition: superlu.hh:271
\n+
SuperLUMatrix::size_type nnz() const
Definition: superlu.hh:355
\n+
void apply(domain_type &x, range_type &b, double reduction, InverseOperatorResult &res)
apply inverse operator, with given convergence criteria.
Definition: superlu.hh:342
\n+
typename Impl::SuperLUVectorChooser< M >::range_type range_type
The type of the range of the solver.
Definition: superlu.hh:284
\n+
M matrix_type
Definition: superlu.hh:276
\n+
SuperMatrixInitializer< Matrix > MatrixInitializer
Type of an associated initializer class.
Definition: superlu.hh:280
\n+
M Matrix
The matrix type.
Definition: superlu.hh:275
\n+
typename Impl::SuperLUVectorChooser< M >::domain_type domain_type
The type of the domain of the solver.
Definition: superlu.hh:282
\n+
const char * name()
Definition: superlu.hh:371
\n+
virtual SolverCategory::Category category() const
Category of the solver (see SolverCategory::Category)
Definition: superlu.hh:287
\n+
Dune::SuperLUMatrix< Matrix > SuperLUMatrix
The corresponding SuperLU Matrix type.
Definition: superlu.hh:278
\n+
SuperLU(const Matrix &mat, const ParameterTree &config)
Constructs the SuperLU solver.
Definition: superlu.hh:320
\n+
Definition: superlu.hh:727
\n+
std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
Definition: superlu.hh:734
\n+
Definition: superlu.hh:728
\n+
Definition: supermatrix.hh:132
\n+\n+
Definition: supermatrix.hh:179
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,784 +4,944 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrixutils.hh\n+superlu.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIXUTILS_HH\n- 6#define DUNE_ISTL_MATRIXUTILS_HH\n+ 5#ifndef DUNE_ISTL_SUPERLU_HH\n+ 6#define DUNE_ISTL_SUPERLU_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n+ 8#if HAVE_SUPERLU\n+ 9\n+ 10#include \"superlufunctions.hh\"\n+ 11#include \"solvers.hh\"\n+ 12#include \"supermatrix.hh\"\n+ 13#include \n+ 14#include \n+ 15#include \"bcrsmatrix.hh\"\n+ 16#include \"bvector.hh\"\n 17#include \"istlexception.hh\"\n- 18\n- 19namespace Dune\n- 20{\n- 21\n- 22#ifndef DOYXGEN\n- 23 template\n- 24 class BCRSMatrix;\n- 25\n- 26 template\n-27 class FieldMatrix;\n- 28\n- 29 template\n- 30 class Matrix;\n- 31#endif\n- 32\n- 46 template\n-47 struct CheckIfDiagonalPresent\n- 48 {\n-53 static void check([[maybe_unused]] const Matrix& mat)\n- 54 {\n- 55#ifdef DUNE_ISTL_WITH_CHECKING\n- 56 typedef typename Matrix::ConstRowIterator Row;\n- 57 typedef typename Matrix::ConstColIterator Entry;\n- 58 for(Row row = mat.begin(); row!=mat.end(); ++row) {\n- 59 Entry diagonal = row->find(row.index());\n- 60 if(diagonal==row->end())\n- 61 DUNE_THROW(ISTLError, \"Missing diagonal value in row \"<::check(m);\n- 66 }\n- 67 }\n- 68#endif\n- 69 }\n- 70 };\n- 71\n- 72 template\n-73 struct CheckIfDiagonalPresent\n- 74 {\n-75 static void check(const Matrix& mat)\n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23\n+ 24namespace Dune\n+ 25{\n+ 26\n+ 37 template\n+ 38 class SeqOverlappingSchwarz;\n+ 39\n+ 40 template\n+ 41 struct SeqOverlappingSchwarzAssemblerHelper;\n+ 42\n+ 43 template\n+44 struct SuperLUSolveChooser\n+ 45 {};\n+ 46\n+ 47 template\n+48 struct SuperLUDenseMatChooser\n+ 49 {};\n+ 50\n+ 51 template\n+52 struct SuperLUQueryChooser\n+ 53 {};\n+ 54\n+ 55 template\n+56 struct QuerySpaceChooser\n+ 57 {};\n+ 58\n+ 59#if __has_include(\"slu_sdefs.h\")\n+ 60 template<>\n+ 61 struct SuperLUDenseMatChooser\n+ 62 {\n+ 63 static void create(SuperMatrix *mat, int n, int m, float *dat, int n1,\n+ 64 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 65 {\n+ 66 sCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);\n+ 67\n+ 68 }\n+ 69\n+ 70 static void destroy(SuperMatrix*)\n+ 71 {}\n+ 72\n+ 73 };\n+ 74 template<>\n+ 75 struct SuperLUSolveChooser\n 76 {\n- 77 typedef typename Matrix::ConstRowIterator Row;\n- 78 for(Row row = mat.begin(); row!=mat.end(); ++row) {\n- 79 if(row->find(row.index())==row->end())\n- 80 DUNE_THROW(ISTLError, \"Missing diagonal value in row \"<\n- 87 class MultiTypeBlockMatrix;\n- 88\n- 89 template\n-90 struct CheckIfDiagonalPresent,\n- 91 blocklevel,l>\n+ 77 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n+*perm_c, int *perm_r, int *etree,\n+ 78 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,\n+ 79 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n+ 80 float *rpg, float *rcond, float *ferr, float *berr,\n+ 81 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n+ 82 {\n+ 83 GlobalLU_t gLU;\n+ 84 sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n+ 85 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n+ 86 &gLU, memusage, stat, info);\n+ 87 }\n+ 88 };\n+ 89\n+ 90 template<>\n+ 91 struct QuerySpaceChooser\n 92 {\n-93 typedef MultiTypeBlockMatrix Matrix;\n- 94\n-99 static void check(const Matrix& /* mat */)\n- 100 {\n- 101#ifdef DUNE_ISTL_WITH_CHECKING\n- 102 // TODO Implement check\n- 103#endif\n- 104 }\n- 105 };\n- 106\n- 118 template\n-119 inline auto countNonZeros(const M&,\n- 120 [[maybe_unused]] typename std::enable_if_t::value>*\n-sfinae = nullptr)\n- 121 {\n- 122 return 1;\n- 123 }\n- 124\n- 125 template\n-126 inline auto countNonZeros(const M& matrix,\n- 127 [[maybe_unused]] typename std::enable_if_t::value>*\n-sfinae = nullptr)\n- 128 {\n- 129 typename M::size_type nonZeros = 0;\n- 130 for(auto&& row : matrix)\n- 131 for(auto&& entry : row)\n- 132 nonZeros += countNonZeros(entry);\n- 133 return nonZeros;\n- 134 }\n- 135\n- 136 /*\n- 137 template\n- 138 struct ProcessOnFieldsOfMatrix\n- 139 */\n- 140\n- 142 namespace\n- 143 {\n- 144 struct CompPair {\n- 145 template\n- 146 bool operator()(const std::pair& p1, const std::pair& p2) const\n- 147 {\n- 148 return p1.first\n-154 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)\n- 155 {\n- 156 typedef typename C::ParallelIndexSet::const_iterator IIter;\n- 157 typedef typename C::OwnerSet OwnerSet;\n- 158 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;\n- 159\n- 160 GlobalIndex gmax=0;\n- 161\n- 162 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();\n- 163 idx!=eidx; ++idx)\n- 164 gmax=std::max(gmax,idx->global());\n- 165\n- 166 gmax=ooc.communicator().max(gmax);\n- 167 ooc.buildGlobalLookup();\n- 168\n- 169 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();\n- 170 idx!=eidx; ++idx) {\n- 171 if(OwnerSet::contains(idx->local().attribute()))\n- 172 {\n- 173 typedef typename M::block_type Block;\n- 174\n- 175 std::set,CompPair> entries;\n- 176\n- 177 // sort rows\n- 178 typedef typename M::ConstColIterator CIter;\n- 179 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();\n- 180 c!=cend; ++c) {\n- 181 const typename C::ParallelIndexSet::IndexPair* pair\n- 182 =ooc.globalLookup().pair(c.index());\n- 183 assert(pair);\n- 184 entries.insert(std::make_pair(pair->global(), *c));\n- 185 }\n- 186\n- 187 //wait until its the rows turn.\n- 188 GlobalIndex rowidx = idx->global();\n- 189 GlobalIndex cur=std::numeric_limits::max();\n- 190 while(cur!=rowidx)\n- 191 cur=ooc.communicator().min(rowidx);\n- 192\n- 193 // print rows\n- 194 typedef typename std::set,CompPair>::iterator\n-SIter;\n- 195 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)\n- 196 os<global()<<\" \"<first<<\" \"<second<\n+ 104 struct SuperLUDenseMatChooser\n+ 105 {\n+ 106 static void create(SuperMatrix *mat, int n, int m, double *dat, int n1,\n+ 107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 108 {\n+ 109 dCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);\n+ 110\n+ 111 }\n+ 112\n+ 113 static void destroy(SuperMatrix * /* mat */)\n+ 114 {}\n+ 115 };\n+ 116 template<>\n+ 117 struct SuperLUSolveChooser\n+ 118 {\n+ 119 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n+*perm_c, int *perm_r, int *etree,\n+ 120 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,\n+ 121 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n+ 122 double *rpg, double *rcond, double *ferr, double *berr,\n+ 123 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n+ 124 {\n+ 125 GlobalLU_t gLU;\n+ 126 dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n+ 127 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n+ 128 &gLU, memusage, stat, info);\n+ 129 }\n+ 130 };\n+ 131\n+ 132 template<>\n+ 133 struct QuerySpaceChooser\n+ 134 {\n+ 135 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n+memusage)\n+ 136 {\n+ 137 dQuerySpace(L,U,memusage);\n+ 138 }\n+ 139 };\n+ 140#endif\n+ 141\n+ 142#if __has_include(\"slu_zdefs.h\")\n+ 143 template<>\n+ 144 struct SuperLUDenseMatChooser >\n+ 145 {\n+ 146 static void create(SuperMatrix *mat, int n, int m, std::complex\n+*dat, int n1,\n+ 147 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 148 {\n+ 149 zCreate_Dense_Matrix(mat, n, m, reinterpret_cast(dat), n1,\n+stype, dtype, mtype);\n+ 150\n+ 151 }\n+ 152\n+ 153 static void destroy(SuperMatrix*)\n+ 154 {}\n+ 155 };\n+ 156\n+ 157 template<>\n+ 158 struct SuperLUSolveChooser >\n+ 159 {\n+ 160 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n+*perm_c, int *perm_r, int *etree,\n+ 161 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,\n+ 162 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n+ 163 double *rpg, double *rcond, double *ferr, double *berr,\n+ 164 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n+ 165 {\n+ 166 GlobalLU_t gLU;\n+ 167 zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n+ 168 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n+ 169 &gLU, memusage, stat, info);\n+ 170 }\n+ 171 };\n+ 172\n+ 173 template<>\n+ 174 struct QuerySpaceChooser >\n+ 175 {\n+ 176 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n+memusage)\n+ 177 {\n+ 178 zQuerySpace(L,U,memusage);\n+ 179 }\n+ 180 };\n+ 181#endif\n+ 182\n+ 183#if __has_include(\"slu_cdefs.h\")\n+ 184 template<>\n+ 185 struct SuperLUDenseMatChooser >\n+ 186 {\n+ 187 static void create(SuperMatrix *mat, int n, int m, std::complex\n+*dat, int n1,\n+ 188 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 189 {\n+ 190 cCreate_Dense_Matrix(mat, n, m, reinterpret_cast< ::complex*>(dat), n1,\n+stype, dtype, mtype);\n+ 191\n+ 192 }\n+ 193\n+ 194 static void destroy(SuperMatrix* /* mat */)\n+ 195 {}\n+ 196 };\n 197\n- 198\n- 199 }\n- 200 }\n- 201\n- 202 ooc.freeGlobalLookup();\n- 203 // Wait until everybody is finished\n- 204 GlobalIndex cur=std::numeric_limits::max();\n- 205 while(cur!=ooc.communicator().min(cur)) ;\n- 206 }\n- 207\n- 208 // Default implementation for scalar types\n- 209 template\n-210 struct MatrixDimension\n- 211 {\n- 212 static_assert(IsNumber::value, \"MatrixDimension is not implemented for\n-this type!\");\n+ 198 template<>\n+ 199 struct SuperLUSolveChooser >\n+ 200 {\n+ 201 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n+*perm_c, int *perm_r, int *etree,\n+ 202 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,\n+ 203 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n+ 204 float *rpg, float *rcond, float *ferr, float *berr,\n+ 205 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n+ 206 {\n+ 207 GlobalLU_t gLU;\n+ 208 cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n+ 209 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n+ 210 &gLU, memusage, stat, info);\n+ 211 }\n+ 212 };\n 213\n-214 static auto rowdim(const M& A)\n- 215 {\n- 216 return 1;\n- 217 }\n- 218\n-219 static auto coldim(const M& A)\n- 220 {\n- 221 return 1;\n- 222 }\n- 223 };\n- 224\n- 225 // Default implementation for scalar types\n- 226 template\n-227 struct MatrixDimension >\n- 228 {\n-229 using block_type = typename Matrix::block_type;\n-230 using size_type = typename Matrix::size_type;\n- 231\n-232 static size_type rowdim (const Matrix& A, size_type i)\n- 233 {\n- 234 return MatrixDimension::rowdim(A[i][0]);\n- 235 }\n- 236\n-237 static size_type coldim (const Matrix& A, size_type c)\n- 238 {\n- 239 return MatrixDimension::coldim(A[0][c]);\n- 240 }\n- 241\n-242 static size_type rowdim (const Matrix& A)\n- 243 {\n- 244 size_type nn=0;\n- 245 for (size_type i=0; i& A)\n- 251 {\n- 252 size_type nn=0;\n- 253 for (size_type i=0; i\n-261 struct MatrixDimension >\n- 262 {\n-263 typedef BCRSMatrix Matrix;\n-264 typedef typename Matrix::block_type block_type;\n-265 typedef typename Matrix::size_type size_type;\n- 266\n-267 static size_type rowdim (const Matrix& A, size_type i)\n- 268 {\n- 269 const B* row = A.r[i].getptr();\n- 270 if(row)\n- 271 return MatrixDimension::rowdim(*row);\n- 272 else\n- 273 return 0;\n- 274 }\n- 275\n-276 static size_type coldim (const Matrix& A, size_type c)\n- 277 {\n- 278 // find an entry in column c\n- 279 if (A.nnz_ > 0)\n- 280 {\n- 281 for (size_type k=0; k::coldim(A.a[k]);\n- 284 }\n- 285 }\n- 286 }\n- 287 else\n+ 214 template<>\n+ 215 struct QuerySpaceChooser >\n+ 216 {\n+ 217 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n+memusage)\n+ 218 {\n+ 219 cQuerySpace(L,U,memusage);\n+ 220 }\n+ 221 };\n+ 222#endif\n+ 223\n+ 224 namespace Impl\n+ 225 {\n+ 226 template\n+ 227 struct SuperLUVectorChooser\n+ 228 {};\n+ 229\n+ 230 template\n+ 231 struct SuperLUVectorChooser,A > >\n+ 232 {\n+ 234 using domain_type = BlockVector<\n+ 235 FieldVector,\n+ 236 typename std::allocator_traits::template rebind_alloc\n+> >;\n+ 238 using range_type = BlockVector<\n+ 239 FieldVector,\n+ 240 typename std::allocator_traits::template rebind_alloc\n+> >;\n+ 241 };\n+ 242\n+ 243 template\n+ 244 struct SuperLUVectorChooser >\n+ 245 {\n+ 247 using domain_type = BlockVector;\n+ 249 using range_type = BlockVector;\n+ 250 };\n+ 251 }\n+ 252\n+ 266 template\n+267 class SuperLU\n+ 268 : public InverseOperator<\n+ 269 typename Impl::SuperLUVectorChooser::domain_type,\n+ 270 typename Impl::SuperLUVectorChooser::range_type >\n+ 271 {\n+ 272 using T = typename M::field_type;\n+ 273 public:\n+275 using Matrix = M;\n+276 using matrix_type = M;\n+278 typedef Dune::SuperLUMatrix SuperLUMatrix;\n+280 typedef SuperMatrixInitializer MatrixInitializer;\n+282 using domain_type = typename Impl::SuperLUVectorChooser::domain_type;\n+284 using range_type = typename Impl::SuperLUVectorChooser::range_type;\n+ 285\n+287 virtual SolverCategory::Category category() const\n 288 {\n- 289 for (size_type i=0; i::coldim(a[k]);\n- 296 }\n- 297 }\n- 298 }\n- 299\n- 300 // not found\n- 301 return 0;\n- 302 }\n- 303\n-304 static size_type rowdim (const Matrix& A){\n- 305 size_type nn=0;\n- 306 for (size_type i=0; i coldims(A.M(),\n- 319 std::numeric_limits::max());\n- 320\n- 321 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)\n- 322 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)\n- 323 // only compute blocksizes we don't already have\n- 324 if (coldims[col.index()]==std::numeric_limits::max())\n- 325 coldims[col.index()] = MatrixDimension::coldim(*col);\n- 326\n- 327 size_type sum = 0;\n- 328 for (typename std::vector::iterator it=coldims.begin();\n- 329 it!=coldims.end(); ++it)\n- 330 // skip rows for which no coldim could be determined\n- 331 if ((*it)>=0)\n- 332 sum += *it;\n+ 289 return SolverCategory::Category::sequential;\n+ 290 }\n+ 291\n+ 306 explicit SuperLU(const Matrix& mat, bool verbose=false,\n+ 307 bool reusevector=true);\n+ 308\n+ 309\n+320 SuperLU(const Matrix& mat, const ParameterTree& config)\n+ 321 : SuperLU(mat, config.get(\"verbose\", false), config.get\n+(\"reuseVector\", true))\n+ 322 {}\n+ 323\n+ 330 SuperLU();\n+ 331\n+ 332 ~SuperLU();\n 333\n- 334 return sum;\n- 335 }\n- 336 };\n- 337\n+ 337 void apply(domain_type& x, range_type& b, InverseOperatorResult& res);\n 338\n- 339 template\n-340 struct MatrixDimension ,TA> >\n- 341 {\n-342 typedef BCRSMatrix ,TA> Matrix;\n-343 typedef typename Matrix::size_type size_type;\n- 344\n-345 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)\n- 346 {\n- 347 return n;\n- 348 }\n- 349\n-350 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)\n- 351 {\n- 352 return m;\n- 353 }\n+342 void apply (domain_type& x, range_type& b, [[maybe_unused]] double\n+reduction, InverseOperatorResult& res)\n+ 343 {\n+ 344 apply(x,b,res);\n+ 345 }\n+ 346\n+ 350 void apply(T* x, T* b);\n+ 351\n+ 353 void setMatrix(const Matrix& mat);\n 354\n-355 static size_type rowdim (const Matrix& A) {\n- 356 return A.N()*n;\n- 357 }\n- 358\n-359 static size_type coldim (const Matrix& A) {\n- 360 return A.M()*m;\n- 361 }\n- 362 };\n- 363\n- 364 template\n-365 struct MatrixDimension >\n- 366 {\n-367 typedef FieldMatrix Matrix;\n-368 typedef typename Matrix::size_type size_type;\n- 369\n-370 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n- 371 {\n- 372 return 1;\n- 373 }\n- 374\n-375 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n- 376 {\n- 377 return 1;\n- 378 }\n- 379\n-380 static size_type rowdim(const Matrix& /*A*/)\n- 381 {\n- 382 return n;\n- 383 }\n- 384\n-385 static size_type coldim(const Matrix& /*A*/)\n- 386 {\n- 387 return m;\n- 388 }\n- 389 };\n- 390\n- 391 template \n-392 struct MatrixDimension >\n- 393 {\n-394 typedef Dune::DynamicMatrix MatrixType;\n-395 typedef typename MatrixType::size_type size_type;\n- 396\n-397 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)\n- 398 {\n- 399 return 1;\n+355 typename SuperLUMatrix::size_type nnz() const\n+ 356 {\n+ 357 return mat.nonzeroes();\n+ 358 }\n+ 359\n+ 360 template\n+ 361 void setSubMatrix(const Matrix& mat, const S& rowIndexSet);\n+ 362\n+ 363 void setVerbosity(bool v);\n+ 364\n+ 369 void free();\n+ 370\n+371 const char* name() { return \"SuperLU\"; }\n+ 372 private:\n+ 373 template\n+374 friend class SeqOverlappingSchwarz;\n+ 375 friend struct SeqOverlappingSchwarzAssemblerHelper,true>;\n+ 376\n+ 377 SuperLUMatrix& getInternalMatrix() { return mat; }\n+ 378\n+ 380 void decompose();\n+ 381\n+ 382 SuperLUMatrix mat;\n+ 383 SuperMatrix L, U, B, X;\n+ 384 int *perm_c, *perm_r, *etree;\n+ 385 typename GetSuperLUType::float_type *R, *C;\n+ 386 T *bstore;\n+ 387 superlu_options_t options;\n+ 388 char equed;\n+ 389 void *work;\n+ 390 int lwork;\n+ 391 bool first, verbose, reusevector;\n+ 392 };\n+ 393\n+ 394 template\n+ 395 SuperLU\n+396::~SuperLU()\n+ 397 {\n+ 398 if(mat.N()+mat.M()>0)\n+ 399 free();\n 400 }\n 401\n-402 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)\n- 403 {\n- 404 return 1;\n- 405 }\n- 406\n-407 static size_type rowdim(const MatrixType& A)\n- 408 {\n- 409 return A.N();\n- 410 }\n- 411\n-412 static size_type coldim(const MatrixType& A)\n- 413 {\n- 414 return A.M();\n- 415 }\n- 416 };\n- 417\n- 418 template\n-419 struct MatrixDimension, TA> >\n- 420 {\n-421 typedef Matrix, TA> ThisMatrix;\n-422 typedef typename ThisMatrix::size_type size_type;\n- 423\n-424 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)\n- 425 {\n- 426 return n;\n- 427 }\n- 428\n-429 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)\n- 430 {\n- 431 return m;\n- 432 }\n- 433\n-434 static size_type rowdim(const ThisMatrix& A)\n- 435 {\n- 436 return A.N()*n;\n- 437 }\n- 438\n-439 static size_type coldim(const ThisMatrix& A)\n- 440 {\n- 441 return A.M()*m;\n- 442 }\n- 443 };\n- 444\n- 445 template\n-446 struct MatrixDimension >\n- 447 {\n-448 typedef DiagonalMatrix Matrix;\n-449 typedef typename Matrix::size_type size_type;\n- 450\n-451 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n- 452 {\n- 453 return 1;\n- 454 }\n- 455\n-456 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n- 457 {\n- 458 return 1;\n- 459 }\n- 460\n-461 static size_type rowdim(const Matrix& /*A*/)\n- 462 {\n- 463 return n;\n- 464 }\n- 465\n-466 static size_type coldim(const Matrix& /*A*/)\n- 467 {\n- 468 return n;\n- 469 }\n- 470 };\n- 471\n- 472 template\n-473 struct MatrixDimension >\n- 474 {\n-475 typedef ScaledIdentityMatrix Matrix;\n-476 typedef typename Matrix::size_type size_type;\n- 477\n-478 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n- 479 {\n- 480 return 1;\n- 481 }\n- 482\n-483 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n- 484 {\n- 485 return 1;\n- 486 }\n- 487\n-488 static size_type rowdim(const Matrix& /*A*/)\n- 489 {\n- 490 return n;\n- 491 }\n- 492\n-493 static size_type coldim(const Matrix& /*A*/)\n- 494 {\n- 495 return n;\n- 496 }\n- 497 };\n- 498\n- 502 template\n-503 struct IsMatrix\n- 504 {\n- 505 enum {\n- 509 value = false\n-510 };\n- 511 };\n+ 402 template\n+403 void SuperLU::free()\n+ 404 {\n+ 405 delete[] perm_c;\n+ 406 delete[] perm_r;\n+ 407 delete[] etree;\n+ 408 delete[] R;\n+ 409 delete[] C;\n+ 410 if(lwork>=0) {\n+ 411 Destroy_SuperNode_Matrix(&L);\n+ 412 Destroy_CompCol_Matrix(&U);\n+ 413 }\n+ 414 lwork=0;\n+ 415 if(!first && reusevector) {\n+ 416 SUPERLU_FREE(B.Store);\n+ 417 SUPERLU_FREE(X.Store);\n+ 418 }\n+ 419 mat.free();\n+ 420 }\n+ 421\n+ 422 template\n+ 423 SuperLU\n+424::SuperLU(const Matrix& mat_, bool verbose_, bool reusevector_)\n+ 425 : work(0), lwork(0), first(true), verbose(verbose_),\n+ 426 reusevector(reusevector_)\n+ 427 {\n+ 428 setMatrix(mat_);\n+ 429\n+ 430 }\n+ 431 template\n+432 SuperLU::SuperLU()\n+ 433 : work(0), lwork(0),verbose(false),\n+ 434 reusevector(false)\n+ 435 {}\n+ 436 template\n+437 void SuperLU::setVerbosity(bool v)\n+ 438 {\n+ 439 verbose=v;\n+ 440 }\n+ 441\n+ 442 template\n+443 void SuperLU::setMatrix(const Matrix& mat_)\n+ 444 {\n+ 445 if(mat.N()+mat.M()>0) {\n+ 446 free();\n+ 447 }\n+ 448 lwork=0;\n+ 449 work=0;\n+ 450 //a=&mat_;\n+ 451 mat=mat_;\n+ 452 decompose();\n+ 453 }\n+ 454\n+ 455 template\n+ 456 template\n+457 void SuperLU::setSubMatrix(const Matrix& mat_,\n+ 458 const S& mrs)\n+ 459 {\n+ 460 if(mat.N()+mat.M()>0) {\n+ 461 free();\n+ 462 }\n+ 463 lwork=0;\n+ 464 work=0;\n+ 465 //a=&mat_;\n+ 466 mat.setMatrix(mat_,mrs);\n+ 467 decompose();\n+ 468 }\n+ 469\n+ 470 template\n+ 471 void SuperLU::decompose()\n+ 472 {\n+ 473\n+ 474 first = true;\n+ 475 perm_c = new int[mat.M()];\n+ 476 perm_r = new int[mat.N()];\n+ 477 etree = new int[mat.M()];\n+ 478 R = new typename GetSuperLUType::float_type[mat.N()];\n+ 479 C = new typename GetSuperLUType::float_type[mat.M()];\n+ 480\n+ 481 set_default_options(&options);\n+ 482 // Do the factorization\n+ 483 B.ncol=0;\n+ 484 B.Stype=SLU_DN;\n+ 485 B.Dtype=GetSuperLUType::type;\n+ 486 B.Mtype= SLU_GE;\n+ 487 DNformat fakeFormat;\n+ 488 fakeFormat.lda=mat.N();\n+ 489 B.Store=&fakeFormat;\n+ 490 X.Stype=SLU_DN;\n+ 491 X.Dtype=GetSuperLUType::type;\n+ 492 X.Mtype= SLU_GE;\n+ 493 X.ncol=0;\n+ 494 X.Store=&fakeFormat;\n+ 495\n+ 496 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr=1e10;\n+ 497 int info;\n+ 498 mem_usage_t memusage;\n+ 499 SuperLUStat_t stat;\n+ 500\n+ 501 StatInit(&stat);\n+ 502 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n+perm_c, perm_r, etree, &equed, R, C,\n+ 503 &L, &U, work, lwork, &B, &X, &rpg, &rcond, &ferr,\n+ 504 &berr, &memusage, &stat, &info);\n+ 505\n+ 506 if(verbose) {\n+ 507 dinfo<<\"LU factorization: dgssvx() returns info \"<< info<(mat).ncol;\n+ 510\n+ 511 if ( info == 0 || info == nSuperLUCol+1 ) {\n 512\n- 513 template\n-514 struct IsMatrix >\n- 515 {\n- 516 enum {\n- 520 value = true\n-521 };\n- 522 };\n- 523\n- 524\n- 525 template\n-526 struct IsMatrix >\n- 527 {\n- 528 enum {\n- 532 value = true\n-533 };\n- 534 };\n- 535\n- 536 template\n-537 struct PointerCompare\n- 538 {\n-539 bool operator()(const T* l, const T* r)\n- 540 {\n- 541 return *l < *r;\n- 542 }\n- 543 };\n- 544\n- 545}\n- 546#endif\n+ 513 if ( options.PivotGrowth )\n+ 514 dinfo<<\"Recip. pivot growth = \"<nnz<nnz<nnz + Ustore->nnz -\n+nSuperLUCol<::querySpace(&L, &U, &memusage);\n+ 523 dinfo<<\"L\\\\U MB \"< 0 && lwork == -1 ) { // Memory allocation failed\n+ 528 dinfo<<\"** Estimated memory: \"<< info - nSuperLUCol<colptr[i]; c < Ustore->colptr[i+1]; ++c)\n+ 540 //if(Ustore->rowind[c]==i)\n+ 541 std::cout<rowind[c]<<\"->\"<<((double*)Ustore->nzval)[c]<<\" \";\n+ 542 if(k==0){\n+ 543 //\n+ 544 k=-1;\n+ 545 }std::cout<colptr[i]; c < Ustore->colptr[i+1]; ++c)\n+ 551 //if(Ustore->rowind[c]==i)\n+ 552 std::cout<rowind[c]<<\"->\"<<((double*)Ustore->nzval)[c]<<\" \";\n+ 553 if(k==0){\n+ 554 //\n+ 555 k=-1;\n+ 556 }std::cout<\n+ 562 void SuperLU\n+563::apply(domain_type& x, range_type& b, InverseOperatorResult& res)\n+ 564 {\n+ 565 if (mat.N() != b.dim())\n+ 566 DUNE_THROW(ISTLError, \"Size of right-hand-side vector b does not match the\n+number of matrix rows!\");\n+ 567 if (mat.M() != x.dim())\n+ 568 DUNE_THROW(ISTLError, \"Size of solution vector x does not match the number\n+of matrix columns!\");\n+ 569 if (mat.M()+mat.N()==0)\n+ 570 DUNE_THROW(ISTLError, \"Matrix of SuperLU is null!\");\n+ 571\n+ 572 SuperMatrix* mB = &B;\n+ 573 SuperMatrix* mX = &X;\n+ 574 SuperMatrix rB, rX;\n+ 575 if (reusevector) {\n+ 576 if(first) {\n+ 577 SuperLUDenseMatChooser::create(&B, (int)mat.N(), 1,\n+reinterpret_cast(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n+SLU_GE);\n+ 578 SuperLUDenseMatChooser::create(&X, (int)mat.N(), 1,\n+reinterpret_cast(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n+SLU_GE);\n+ 579 first=false;\n+ 580 }else{\n+ 581 ((DNformat*)B.Store)->nzval=&b[0];\n+ 582 ((DNformat*)X.Store)->nzval=&x[0];\n+ 583 }\n+ 584 } else {\n+ 585 SuperLUDenseMatChooser::create(&rB, (int)mat.N(), 1,\n+reinterpret_cast(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n+SLU_GE);\n+ 586 SuperLUDenseMatChooser::create(&rX, (int)mat.N(), 1,\n+reinterpret_cast(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n+SLU_GE);\n+ 587 mB = &rB;\n+ 588 mX = &rX;\n+ 589 }\n+ 590 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr;\n+ 591 int info;\n+ 592 mem_usage_t memusage;\n+ 593 SuperLUStat_t stat;\n+ 594 /* Initialize the statistics variables. */\n+ 595 StatInit(&stat);\n+ 596 /*\n+ 597 range_type d=b;\n+ 598 a->usmv(-1, x, d);\n+ 599\n+ 600 double def0=d.two_norm();\n+ 601 */\n+ 602 options.IterRefine=SLU_DOUBLE;\n+ 603\n+ 604 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n+perm_c, perm_r, etree, &equed, R, C,\n+ 605 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,\n+ 606 &memusage, &stat, &info);\n+ 607\n+ 608 res.iterations=1;\n+ 609\n+ 610 /*\n+ 611 if(options.Equil==YES)\n+ 612 // undo scaling of right hand side\n+ 613 std::transform(reinterpret_cast(&b[0]),reinterpret_cast(&b\n+[0])+mat.M(),\n+ 614 C, reinterpret_cast(&d[0]), std::divides());\n+ 615 else\n+ 616 d=b;\n+ 617 a->usmv(-1, x, d);\n+ 618 res.reduction=d.two_norm()/def0;\n+ 619 res.conv_rate = res.reduction;\n+ 620 res.converged=(res.reduction<1e-10||d.two_norm()<1e-18);\n+ 621 */\n+ 622 res.converged=true;\n+ 623\n+ 624 if(verbose) {\n+ 625\n+ 626 dinfo<<\"Triangular solve: dgssvx() returns info \"<< info<(mat).ncol;\n+ 629\n+ 630 if ( info == 0 || info == nSuperLUCol+1 ) {\n+ 631\n+ 632 if ( options.IterRefine ) {\n+ 633 std::cout<<\"Iterative Refinement: steps=\"\n+ 634 < 0 && lwork == -1 ) { // Memory allocation failed\n+ 638 std::cout<<\"** Estimated memory: \"<< info - nSuperLUCol<<\" bytes\"<\n+ 651 void SuperLU\n+652::apply(T* x, T* b)\n+ 653 {\n+ 654 if(mat.N()+mat.M()==0)\n+ 655 DUNE_THROW(ISTLError, \"Matrix of SuperLU is null!\");\n+ 656\n+ 657 SuperMatrix* mB = &B;\n+ 658 SuperMatrix* mX = &X;\n+ 659 SuperMatrix rB, rX;\n+ 660 if (reusevector) {\n+ 661 if(first) {\n+ 662 SuperLUDenseMatChooser::create(&B, mat.N(), 1, b, mat.N(), SLU_DN,\n+GetSuperLUType::type, SLU_GE);\n+ 663 SuperLUDenseMatChooser::create(&X, mat.N(), 1, x, mat.N(), SLU_DN,\n+GetSuperLUType::type, SLU_GE);\n+ 664 first=false;\n+ 665 }else{\n+ 666 ((DNformat*) B.Store)->nzval=b;\n+ 667 ((DNformat*)X.Store)->nzval=x;\n+ 668 }\n+ 669 } else {\n+ 670 SuperLUDenseMatChooser::create(&rB, mat.N(), 1, b, mat.N(), SLU_DN,\n+GetSuperLUType::type, SLU_GE);\n+ 671 SuperLUDenseMatChooser::create(&rX, mat.N(), 1, x, mat.N(), SLU_DN,\n+GetSuperLUType::type, SLU_GE);\n+ 672 mB = &rB;\n+ 673 mX = &rX;\n+ 674 }\n+ 675\n+ 676 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr;\n+ 677 int info;\n+ 678 mem_usage_t memusage;\n+ 679 SuperLUStat_t stat;\n+ 680 /* Initialize the statistics variables. */\n+ 681 StatInit(&stat);\n+ 682\n+ 683 options.IterRefine=SLU_DOUBLE;\n+ 684\n+ 685 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n+perm_c, perm_r, etree, &equed, R, C,\n+ 686 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,\n+ 687 &memusage, &stat, &info);\n+ 688\n+ 689 if(verbose) {\n+ 690 dinfo<<\"Triangular solve: dgssvx() returns info \"<< info<(mat).ncol;\n+ 693\n+ 694 if ( info == 0 || info == nSuperLUCol+1 ) { // Factorization has succeeded\n+ 695\n+ 696 if ( options.IterRefine ) {\n+ 697 dinfo<<\"Iterative Refinement: steps=\"\n+ 698 < 0 && lwork == -1 ) { // Memory allocation failed\n+ 702 dinfo<<\"** Estimated memory: \"<< info - nSuperLUCol<<\" bytes\"<\n+716 struct IsDirectSolver > >\n+ 717 {\n+718 enum { value=true};\n+ 719 };\n+ 720\n+ 721 template\n+722 struct StoresColumnCompressed > >\n+ 723 {\n+724 enum { value = true };\n+ 725 };\n+ 726\n+727 struct SuperLUCreator {\n+728 template struct isValidBlock : std::false_type{};\n+729 template struct isValidBlock> : std::\n+true_type{};\n+730 template struct isValidBlock,k>> : std::true_type{};\n+ 731 template\n+ 732 std::shared_ptr::type,\n+ 733 typename Dune::TypeListElement<2, TL>::type>>\n+734 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& config,\n+ 735 std::enable_if_t::\n+type::block_type>::value,int> = 0) const\n+ 736 {\n+ 737 int verbose = config.get(\"verbose\", 0);\n+ 738 return std::make_shared>(mat,verbose);\n+ 739 }\n+ 740\n+ 741 // second version with SFINAE to validate the template parameters of\n+SuperLU\n+ 742 template\n+ 743 std::shared_ptr::type,\n+ 744 typename Dune::TypeListElement<2, TL>::type>>\n+745 operator()(TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n+*config*/,\n+ 746 std::enable_if_t::\n+type::block_type>::value,int> = 0) const\n+ 747 {\n+ 748 DUNE_THROW(UnsupportedType,\n+ 749 \"Unsupported Type in SuperLU (only double and std::complex\n+supported)\");\n+ 750 }\n+ 751 };\n+752 template<> struct SuperLUCreator::isValidBlock : std::true_type{};\n+753 template<> struct SuperLUCreator::isValidBlock> :\n+std::true_type{};\n+ 754\n+755 DUNE_REGISTER_DIRECT_SOLVER(\"superlu\", SuperLUCreator());\n+ 756} // end namespace DUNE\n+ 757\n+ 758// undefine macros from SuperLU's slu_util.h\n+ 759#undef FIRSTCOL_OF_SNODE\n+ 760#undef NO_MARKER\n+ 761#undef NUM_TEMPV\n+ 762#undef USER_ABORT\n+ 763#undef USER_MALLOC\n+ 764#undef SUPERLU_MALLOC\n+ 765#undef USER_FREE\n+ 766#undef SUPERLU_FREE\n+ 767#undef CHECK_MALLOC\n+ 768#undef SUPERLU_MAX\n+ 769#undef SUPERLU_MIN\n+ 770#undef L_SUB_START\n+ 771#undef L_SUB\n+ 772#undef L_NZ_START\n+ 773#undef L_FST_SUPC\n+ 774#undef U_NZ_START\n+ 775#undef U_SUB\n+ 776#undef TRUE\n+ 777#undef FALSE\n+ 778#undef EMPTY\n+ 779#undef NODROP\n+ 780#undef DROP_BASIC\n+ 781#undef DROP_PROWS\n+ 782#undef DROP_COLUMN\n+ 783#undef DROP_AREA\n+ 784#undef DROP_SECONDARY\n+ 785#undef DROP_DYNAMIC\n+ 786#undef DROP_INTERP\n+ 787#undef MILU_ALPHA\n+ 788\n+ 789#endif // HAVE_SUPERLU\n+ 790#endif // DUNE_SUPERLU_HH\n+solvertype.hh\n+Templates characterizing the type of a solver.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+supermatrix.hh\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n istlexception.hh\n-scaledidmatrix.hh\n-This file implements a quadratic matrix of fixed size which is a multiple of\n-the identity.\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+solvers.hh\n+Implementations of the inverse operator interface.\n+solverfactory.hh\n+superlufunctions.hh\n+Dune::SuperLU::setSubMatrix\n+void setSubMatrix(const Matrix &mat, const S &rowIndexSet)\n+Definition: superlu.hh:457\n+Dune::SuperLU::apply\n+void apply(domain_type &x, range_type &b, InverseOperatorResult &res)\n+Apply inverse operator,.\n+Definition: superlu.hh:563\n+Dune::DUNE_REGISTER_DIRECT_SOLVER\n+DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n+Dune::SuperLU::setVerbosity\n+void setVerbosity(bool v)\n+Definition: superlu.hh:437\n+Dune::SuperLU::free\n+void free()\n+free allocated space.\n+Definition: superlu.hh:403\n+Dune::SuperLU::~SuperLU\n+~SuperLU()\n+Definition: superlu.hh:396\n+Dune::SuperLU::SuperLU\n+SuperLU()\n+Empty default constructor.\n+Definition: superlu.hh:432\n+Dune::SuperLU::setMatrix\n+void setMatrix(const Matrix &mat)\n+Initialize data from given matrix.\n+Definition: superlu.hh:443\n mat\n Matrix & mat\n Definition: matrixmatrix.hh:347\n-Dune::countNonZeros\n-auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n-value > *sfinae=nullptr)\n-Get the number of nonzero fields in the matrix.\n-Definition: matrixutils.hh:119\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::printGlobalSparseMatrix\n-void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)\n-Definition: matrixutils.hh:154\n-Dune::MatrixDimension\n-Definition: matrixutils.hh:211\n-Dune::MatrixDimension::coldim\n-static auto coldim(const M &A)\n-Definition: matrixutils.hh:219\n-Dune::MatrixDimension::rowdim\n-static auto rowdim(const M &A)\n-Definition: matrixutils.hh:214\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n-Dune::BCRSMatrix::ConstColIterator\n-row_type::ConstIterator ConstColIterator\n-Const iterator to the entries of a row.\n-Definition: bcrsmatrix.hh:741\n-Dune::BCRSMatrix::block_type\n-B block_type\n-export the type representing the components\n-Definition: bcrsmatrix.hh:491\n-Dune::BCRSMatrix::RealRowIterator\n-Iterator access to matrix rows\n-Definition: bcrsmatrix.hh:579\n-Dune::MultiTypeBlockMatrix\n-A Matrix class to support different block types.\n-Definition: multitypeblockmatrix.hh:46\n Dune::ISTLError\n derive error class from the base class in common\n Definition: istlexception.hh:19\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator\n-ConstIterator class for sequential access.\n-Definition: matrix.hh:404\n+Dune::SeqOverlappingSchwarz\n+Sequential overlapping Schwarz preconditioner.\n+Definition: overlappingschwarz.hh:755\n+Dune::SeqOverlappingSchwarzAssemblerHelper\n+Definition: overlappingschwarz.hh:694\n Dune::Matrix\n A generic dynamic dense matrix.\n Definition: matrix.hh:561\n-Dune::Matrix::size_type\n-A::size_type size_type\n-Type for indices and sizes.\n-Definition: matrix.hh:577\n-Dune::Matrix::end\n-RowIterator end()\n-Get iterator to one beyond last row.\n-Definition: matrix.hh:620\n-Dune::Matrix::begin\n-RowIterator begin()\n-Get iterator to first row.\n-Definition: matrix.hh:614\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n-Dune::Matrix::block_type\n-T block_type\n-Export the type representing the components.\n-Definition: matrix.hh:568\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n-Dune::CheckIfDiagonalPresent\n-Check whether the a matrix has diagonal values on blocklevel recursion levels.\n-Definition: matrixutils.hh:48\n-Dune::CheckIfDiagonalPresent::check\n-static void check(const Matrix &mat)\n-Check whether the a matrix has diagonal values on blocklevel recursion levels.\n-Definition: matrixutils.hh:53\n-Dune::CheckIfDiagonalPresent<_Matrix,_0,_l_>::check\n-static void check(const Matrix &mat)\n-Definition: matrixutils.hh:75\n-Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,_blocklevel,\n-l_>::check\n-static void check(const Matrix &)\n-Check whether the a matrix has diagonal values on blocklevel recursion levels.\n-Definition: matrixutils.hh:99\n-Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,_blocklevel,\n-l_>::Matrix\n-MultiTypeBlockMatrix< T1, Args... > Matrix\n-Definition: matrixutils.hh:93\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix< B, TA > &A, size_type i)\n-Definition: matrixutils.hh:232\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::coldim\n-static size_type coldim(const Matrix< B, TA > &A)\n-Definition: matrixutils.hh:250\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix< B, TA > &A)\n-Definition: matrixutils.hh:242\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::size_type\n-typename Matrix< B, TA >::size_type size_type\n-Definition: matrixutils.hh:230\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::coldim\n-static size_type coldim(const Matrix< B, TA > &A, size_type c)\n-Definition: matrixutils.hh:237\n-Dune::MatrixDimension<_Matrix<_B,_TA_>_>::block_type\n-typename Matrix< B, TA >::block_type block_type\n-Definition: matrixutils.hh:229\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::Matrix\n-BCRSMatrix< B, TA > Matrix\n-Definition: matrixutils.hh:263\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::coldim\n-static size_type coldim(const Matrix &A)\n-Definition: matrixutils.hh:311\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::block_type\n-Matrix::block_type block_type\n-Definition: matrixutils.hh:264\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::coldim\n-static size_type coldim(const Matrix &A, size_type c)\n-Definition: matrixutils.hh:276\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixutils.hh:265\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix &A, size_type i)\n-Definition: matrixutils.hh:267\n-Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix &A)\n-Definition: matrixutils.hh:304\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::coldim\n-static size_type coldim(const Matrix &A)\n-Definition: matrixutils.hh:359\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix &, size_type)\n-Definition: matrixutils.hh:345\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::rowdim\n-static size_type rowdim(const Matrix &A)\n-Definition: matrixutils.hh:355\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixutils.hh:343\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::Matrix\n-BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix\n-Definition: matrixutils.hh:342\n-Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::coldim\n-static size_type coldim(const Matrix &, size_type)\n-Definition: matrixutils.hh:350\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::rowdim\n-static size_type rowdim(const Matrix &, size_type)\n-Definition: matrixutils.hh:370\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::coldim\n-static size_type coldim(const Matrix &)\n-Definition: matrixutils.hh:385\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixutils.hh:368\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::Matrix\n-FieldMatrix< K, n, m > Matrix\n-Definition: matrixutils.hh:367\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::coldim\n-static size_type coldim(const Matrix &, size_type)\n-Definition: matrixutils.hh:375\n-Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::rowdim\n-static size_type rowdim(const Matrix &)\n-Definition: matrixutils.hh:380\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::coldim\n-static size_type coldim(const MatrixType &A)\n-Definition: matrixutils.hh:412\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::rowdim\n-static size_type rowdim(const MatrixType &A)\n-Definition: matrixutils.hh:407\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::rowdim\n-static size_type rowdim(const MatrixType &, size_type)\n-Definition: matrixutils.hh:397\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::size_type\n-MatrixType::size_type size_type\n-Definition: matrixutils.hh:395\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::coldim\n-static size_type coldim(const MatrixType &, size_type)\n-Definition: matrixutils.hh:402\n-Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::MatrixType\n-Dune::DynamicMatrix< T > MatrixType\n-Definition: matrixutils.hh:394\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::coldim\n-static size_type coldim(const ThisMatrix &A)\n-Definition: matrixutils.hh:439\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::rowdim\n-static size_type rowdim(const ThisMatrix &A)\n-Definition: matrixutils.hh:434\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::ThisMatrix\n-Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix\n-Definition: matrixutils.hh:421\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::coldim\n-static size_type coldim(const ThisMatrix &, size_type)\n-Definition: matrixutils.hh:429\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::rowdim\n-static size_type rowdim(const ThisMatrix &, size_type)\n-Definition: matrixutils.hh:424\n-Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::size_type\n-ThisMatrix::size_type size_type\n-Definition: matrixutils.hh:422\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::coldim\n-static size_type coldim(const Matrix &, size_type)\n-Definition: matrixutils.hh:456\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixutils.hh:449\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::coldim\n-static size_type coldim(const Matrix &)\n-Definition: matrixutils.hh:466\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::rowdim\n-static size_type rowdim(const Matrix &)\n-Definition: matrixutils.hh:461\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::Matrix\n-DiagonalMatrix< K, n > Matrix\n-Definition: matrixutils.hh:448\n-Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::rowdim\n-static size_type rowdim(const Matrix &, size_type)\n-Definition: matrixutils.hh:451\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::coldim\n-static size_type coldim(const Matrix &)\n-Definition: matrixutils.hh:493\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::rowdim\n-static size_type rowdim(const Matrix &, size_type)\n-Definition: matrixutils.hh:478\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::coldim\n-static size_type coldim(const Matrix &, size_type)\n-Definition: matrixutils.hh:483\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixutils.hh:476\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::Matrix\n-ScaledIdentityMatrix< K, n > Matrix\n-Definition: matrixutils.hh:475\n-Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::rowdim\n-static size_type rowdim(const Matrix &)\n-Definition: matrixutils.hh:488\n-Dune::IsMatrix\n-Test whether a type is an ISTL Matrix.\n-Definition: matrixutils.hh:504\n-Dune::IsMatrix::value\n+Dune::Matrix::M\n+size_type M() const\n+Return the number of columns.\n+Definition: matrix.hh:700\n+Dune::Matrix::N\n+size_type N() const\n+Return the number of rows.\n+Definition: matrix.hh:695\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperatorResult::iterations\n+int iterations\n+Number of iterations.\n+Definition: solver.hh:67\n+Dune::InverseOperatorResult::converged\n+bool converged\n+True if convergence criterion has been met.\n+Definition: solver.hh:73\n+Dune::InverseOperator\n+Abstract base class for all solvers.\n+Definition: solver.hh:99\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::UnsupportedType\n+Definition: solverregistry.hh:77\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n+Dune::IsDirectSolver::value\n @ value\n-True if T is an ISTL matrix.\n-Definition: matrixutils.hh:509\n-Dune::PointerCompare\n-Definition: matrixutils.hh:538\n-Dune::PointerCompare::operator()\n-bool operator()(const T *l, const T *r)\n-Definition: matrixutils.hh:539\n-Dune::ScaledIdentityMatrix\n-A multiple of the identity matrix of static size.\n-Definition: scaledidmatrix.hh:30\n-Dune::ScaledIdentityMatrix::size_type\n-std::size_t size_type\n-The type used for the index access and size operations.\n-Definition: scaledidmatrix.hh:43\n+Whether this is a direct solver.\n+Definition: solvertype.hh:24\n+Dune::StoresColumnCompressed\n+Definition: solvertype.hh:30\n+Dune::StoresColumnCompressed::value\n+@ value\n+whether the solver internally uses column compressed storage\n+Definition: solvertype.hh:36\n+Dune::SuperLUSolveChooser\n+Definition: superlu.hh:45\n+Dune::SuperLUDenseMatChooser\n+Definition: superlu.hh:49\n+Dune::SuperLUQueryChooser\n+Definition: superlu.hh:53\n+Dune::QuerySpaceChooser\n+Definition: superlu.hh:57\n+Dune::SuperLU\n+SuperLu Solver.\n+Definition: superlu.hh:271\n+Dune::SuperLU::nnz\n+SuperLUMatrix::size_type nnz() const\n+Definition: superlu.hh:355\n+Dune::SuperLU::apply\n+void apply(domain_type &x, range_type &b, double reduction,\n+InverseOperatorResult &res)\n+apply inverse operator, with given convergence criteria.\n+Definition: superlu.hh:342\n+Dune::SuperLU::range_type\n+typename Impl::SuperLUVectorChooser< M >::range_type range_type\n+The type of the range of the solver.\n+Definition: superlu.hh:284\n+Dune::SuperLU::matrix_type\n+M matrix_type\n+Definition: superlu.hh:276\n+Dune::SuperLU::MatrixInitializer\n+SuperMatrixInitializer< Matrix > MatrixInitializer\n+Type of an associated initializer class.\n+Definition: superlu.hh:280\n+Dune::SuperLU::Matrix\n+M Matrix\n+The matrix type.\n+Definition: superlu.hh:275\n+Dune::SuperLU::domain_type\n+typename Impl::SuperLUVectorChooser< M >::domain_type domain_type\n+The type of the domain of the solver.\n+Definition: superlu.hh:282\n+Dune::SuperLU::name\n+const char * name()\n+Definition: superlu.hh:371\n+Dune::SuperLU::category\n+virtual SolverCategory::Category category() const\n+Category of the solver (see SolverCategory::Category)\n+Definition: superlu.hh:287\n+Dune::SuperLU::SuperLUMatrix\n+Dune::SuperLUMatrix< Matrix > SuperLUMatrix\n+The corresponding SuperLU Matrix type.\n+Definition: superlu.hh:278\n+Dune::SuperLU::SuperLU\n+SuperLU(const Matrix &mat, const ParameterTree &config)\n+Constructs the SuperLU solver.\n+Definition: superlu.hh:320\n+Dune::SuperLUCreator\n+Definition: superlu.hh:727\n+Dune::SuperLUCreator::operator()\n+std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL\n+>::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const\n+M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock<\n+typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0)\n+const\n+Definition: superlu.hh:734\n+Dune::SuperLUCreator::isValidBlock\n+Definition: superlu.hh:728\n+Dune::GetSuperLUType\n+Definition: supermatrix.hh:132\n+Dune::SuperLUMatrix<_Matrix_>\n+Dune::SuperMatrixInitializer\n+Definition: supermatrix.hh:179\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00020.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00020.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: superlufunctions.hh File Reference\n+dune-istl: scalarproducts.hh File Reference\n \n \n \n \n \n \n \n@@ -63,43 +63,72 @@\n \n
\n
\n
\n-Macros
\n-
superlufunctions.hh File Reference
\n+Classes |\n+Namespaces |\n+Functions
\n+ \n
\n
\n-
#include "supermatrix.h"
\n-#include "slu_util.h"
\n+\n+

Define base class for scalar product and norm. \n+More...

\n+
#include <cmath>
\n+#include <complex>
\n+#include <iostream>
\n+#include <iomanip>
\n+#include <string>
\n+#include <memory>
\n+#include <dune/common/exceptions.hh>
\n+#include <dune/common/shared_ptr.hh>
\n+#include "bvector.hh"
\n+#include "solvercategory.hh"
\n
\n

Go to the source code of this file.

\n \n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

\n-Macros

#define int_t   SUPERLU_INT_TYPE
 

\n+Classes

class  Dune::ScalarProduct< X >
 Base class for scalar product and norm computation. More...
 
class  Dune::ParallelScalarProduct< X, C >
 Scalar product for overlapping Schwarz methods. More...
 
class  Dune::SeqScalarProduct< X >
 Default implementation for the scalar case. More...
 
class  Dune::NonoverlappingSchwarzScalarProduct< X, C >
 Nonoverlapping Scalar Product with communication object. More...
 
class  Dune::OverlappingSchwarzScalarProduct< X, C >
 Scalar product for overlapping Schwarz methods. More...
 
\n+\n+\n+\n+

\n+Namespaces

namespace  Dune
 
\n+\n+\n+\n+\n+\n+\n+\n+\n

\n+Functions

template<class X , class Comm >
std::shared_ptr< ScalarProduct< X > > Dune::makeScalarProduct (std::shared_ptr< const Comm > comm, SolverCategory::Category category)
 Choose the approriate scalar product for a solver category. More...
 
template<class X , class Comm >
std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const Comm &comm, SolverCategory::Category category)
 
\n-

Macro Definition Documentation

\n-\n-

◆ int_t

\n-\n-
\n-
\n- \n- \n- \n- \n-
#define int_t   SUPERLU_INT_TYPE
\n-
\n-\n-
\n-
\n-
\n+

Detailed Description

\n+

Define base class for scalar product and norm.

\n+

These classes have to be implemented differently for different data partitioning strategies. Default implementations for the sequential case are provided.

\n+
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,21 +4,62 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Macros\n-superlufunctions.hh File Reference\n-#include \"supermatrix.h\"\n-#include \"slu_util.h\"\n+Classes | Namespaces | Functions\n+scalarproducts.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Scalar_products\n+Define base class for scalar product and norm. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"bvector.hh\"\n+#include \"solvercategory.hh\"\n Go_to_the_source_code_of_this_file.\n- Macros\n-#define\u00a0int_t\u00a0\u00a0\u00a0SUPERLU_INT_TYPE\n+ Classes\n+class \u00a0Dune::ScalarProduct<_X_>\n+\u00a0 Base class for scalar product and norm computation. More...\n \u00a0\n-***** Macro Definition Documentation *****\n-***** \u25c6\u00a0int_t *****\n-#define int_t\u00a0\u00a0\u00a0SUPERLU_INT_TYPE\n+class \u00a0Dune::ParallelScalarProduct<_X,_C_>\n+\u00a0 Scalar product for overlapping Schwarz methods. More...\n+\u00a0\n+class \u00a0Dune::SeqScalarProduct<_X_>\n+\u00a0 Default implementation for the scalar case. More...\n+\u00a0\n+class \u00a0Dune::NonoverlappingSchwarzScalarProduct<_X,_C_>\n+\u00a0 Nonoverlapping Scalar Product with communication object. More...\n+\u00a0\n+class \u00a0Dune::OverlappingSchwarzScalarProduct<_X,_C_>\n+\u00a0 Scalar product for overlapping Schwarz methods. More...\n+\u00a0\n+ Namespaces\n+namespace \u00a0Dune\n+\u00a0\n+ Functions\n+template\n+std::shared_ptr< ScalarProduct< X > >\u00a0Dune::makeScalarProduct (std::\n+ shared_ptr< const Comm > comm,\n+ SolverCategory::Category category)\n+\u00a0 Choose the approriate scalar product for\n+ a solver category. More...\n+\u00a0\n+template\n+std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const Comm\n+ &comm, SolverCategory::Category\n+ category)\n+\u00a0\n+***** Detailed Description *****\n+Define base class for scalar product and norm.\n+These classes have to be implemented differently for different data\n+partitioning strategies. Default implementations for the sequential case are\n+provided.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00020_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00020_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: superlufunctions.hh Source File\n+dune-istl: scalarproducts.hh Source File\n \n \n \n \n \n \n \n@@ -62,130 +62,186 @@\n \n
\n \n
\n
\n
\n-
superlufunctions.hh
\n+
scalarproducts.hh
\n
\n
\n Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
\n
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
\n
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
\n
4// vi: set et ts=4 sw=2 sts=2:
\n-
5#ifndef DUNE_ISTL_SUPERLUFUNCTIONS_HH
\n-
6#define DUNE_ISTL_SUPERLUFUNCTIONS_HH
\n-
7#if HAVE_SUPERLU
\n-
8
\n-
9
\n-
10#define int_t SUPERLU_INT_TYPE
\n-
11#include "supermatrix.h"
\n-
12#include "slu_util.h"
\n-
13#undef int_t
\n+
5#ifndef DUNE_ISTL_SCALARPRODUCTS_HH
\n+
6#define DUNE_ISTL_SCALARPRODUCTS_HH
\n+
7
\n+
8#include <cmath>
\n+
9#include <complex>
\n+
10#include <iostream>
\n+
11#include <iomanip>
\n+
12#include <string>
\n+
13#include <memory>
\n
14
\n-
15#if __has_include("slu_sdefs.h")
\n-
16extern "C" {
\n-
17 extern void
\n-
18 sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
\n-
19 char *, float *, float *, SuperMatrix *, SuperMatrix *,
\n-
20 void *, int, SuperMatrix *, SuperMatrix *,
\n-
21 float *, float *, float *, float *,
\n-
22 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
\n-
23
\n-
24 extern void
\n-
25 sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int,
\n-
26 Stype_t, Dtype_t, Mtype_t);
\n-
27 extern void
\n-
28 sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *,
\n-
29 int *, int *, Stype_t, Dtype_t, Mtype_t);
\n-
30 extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
\n-
31
\n-
32 extern void sPrint_CompCol_Matrix(char *, SuperMatrix *);
\n-
33}
\n-
34#endif
\n-
35
\n-
36#if __has_include("slu_ddefs.h")
\n-
37extern "C" {
\n-
38 extern void
\n-
39 dgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
\n-
40 char *, double *, double *, SuperMatrix *, SuperMatrix *,
\n-
41 void *, int, SuperMatrix *, SuperMatrix *,
\n-
42 double *, double *, double *, double *,
\n-
43 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
\n-
44
\n-
45 extern void
\n-
46 dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *,
\n-
47 int *, int *, Stype_t, Dtype_t, Mtype_t);
\n-
48
\n-
49 extern void
\n-
50 dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int,
\n-
51 Stype_t, Dtype_t, Mtype_t);
\n-
52
\n-
53 extern int dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
\n-
54
\n-
55 extern void dPrint_CompCol_Matrix(char *, SuperMatrix *);
\n-
56}
\n-
57#endif
\n+
15#include <dune/common/exceptions.hh>
\n+
16#include <dune/common/shared_ptr.hh>
\n+
17
\n+
18#include "bvector.hh"
\n+
19#include "solvercategory.hh"
\n+
20
\n+
21
\n+
22namespace Dune {
\n+
51 template<class X>
\n+\n+
53 public:
\n+
55 typedef X domain_type;
\n+
56 typedef typename X::field_type field_type;
\n+
57 typedef typename FieldTraits<field_type>::real_type real_type;
\n
58
\n-
59#if __has_include("slu_cdefs.h")
\n-
60#include "slu_scomplex.h"
\n-
61
\n-
62extern "C" {
\n-
63 extern void
\n-
64 cgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
\n-
65 char *, float *, float *, SuperMatrix *, SuperMatrix *,
\n-
66 void *, int, SuperMatrix *, SuperMatrix *,
\n-
67 float *, float *, float *, float *,
\n-
68 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
\n-
69
\n-
70
\n-
71 extern void
\n-
72 cCreate_Dense_Matrix(SuperMatrix *, int, int, ::complex *, int,
\n-
73 Stype_t, Dtype_t, Mtype_t);
\n-
74
\n+
63 virtual field_type dot (const X& x, const X& y) const
\n+
64 {
\n+
65 return x.dot(y);
\n+
66 }
\n+
67
\n+
71 virtual real_type norm (const X& x) const
\n+
72 {
\n+
73 return x.two_norm();
\n+
74 }
\n
75
\n-
76 extern void
\n-
77 cCreate_CompCol_Matrix(SuperMatrix *, int, int, int, ::complex *,
\n-
78 int *, int *, Stype_t, Dtype_t, Mtype_t);
\n-
79
\n-
80 extern int cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
\n+\n+
78 {
\n+\n+
80 }
\n
81
\n-
82 extern void cPrint_CompCol_Matrix(char *, SuperMatrix *);
\n-
83}
\n-
84#endif
\n+
83 virtual ~ScalarProduct () {}
\n+
84 };
\n
85
\n-
86#if __has_include("slu_zdefs.h")
\n-
87#include "slu_dcomplex.h"
\n-
88extern "C" {
\n-
89 extern void
\n-
90 zgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
\n-
91 char *, double *, double *, SuperMatrix *, SuperMatrix *,
\n-
92 void *, int, SuperMatrix *, SuperMatrix *,
\n-
93 double *, double *, double *, double *,
\n-
94 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
\n-
95
\n-
96
\n-
97 extern void
\n-
98 zCreate_CompCol_Matrix(SuperMatrix *, int, int, int, doublecomplex *,
\n-
99 int *, int *, Stype_t, Dtype_t, Mtype_t);
\n-
100
\n-
101 extern void
\n-
102 zCreate_Dense_Matrix(SuperMatrix *, int, int, doublecomplex *, int,
\n-
103 Stype_t, Dtype_t, Mtype_t);
\n-
104
\n-
105 extern int zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
\n-
106
\n-
107 extern void zPrint_CompCol_Matrix(char *, SuperMatrix *);
\n-
108}
\n-
109#endif
\n-
110
\n-
111
\n-
112#endif
\n-
113#endif
\n+
97 template<class X, class C>
\n+\n+
99 {
\n+
100 public:
\n+
105 typedef X domain_type;
\n+
107 typedef typename X::field_type field_type;
\n+
108 typedef typename FieldTraits<field_type>::real_type real_type;
\n+\n+
114
\n+
120 ParallelScalarProduct (std::shared_ptr<const communication_type> com, SolverCategory::Category cat)
\n+
121 : _communication(com), _category(cat)
\n+
122 {}
\n+
123
\n+\n+
131 : ParallelScalarProduct(stackobject_to_shared_ptr(com), cat)
\n+
132 {}
\n+
133
\n+
134
\n+
139 virtual field_type dot (const X& x, const X& y) const override
\n+
140 {
\n+
141 field_type result(0);
\n+
142 _communication->dot(x,y,result); // explicitly loop and apply masking
\n+
143 return result;
\n+
144 }
\n+
145
\n+
149 virtual real_type norm (const X& x) const override
\n+
150 {
\n+
151 return _communication->norm(x);
\n+
152 }
\n+
153
\n+
155 virtual SolverCategory::Category category() const override
\n+
156 {
\n+
157 return _category;
\n+
158 }
\n+
159
\n+
160 private:
\n+
161 std::shared_ptr<const communication_type> _communication;
\n+
162 SolverCategory::Category _category;
\n+
163 };
\n+
164
\n+
166 template<class X>
\n+\n+
168 {
\n+
169 using ScalarProduct<X>::ScalarProduct;
\n+
170 };
\n+
171
\n+
177 template<class X, class C>
\n+\n+
179 {
\n+
180 public:
\n+
181 NonoverlappingSchwarzScalarProduct (std::shared_ptr<const C> comm) :
\n+
182 ParallelScalarProduct<X,C>(comm,SolverCategory::nonoverlapping) {}
\n+
183
\n+\n+
185 ParallelScalarProduct<X,C>(comm,SolverCategory::nonoverlapping) {}
\n+
186 };
\n+
187
\n+
199 template<class X, class C>
\n+\n+
201 {
\n+
202 public:
\n+
203 OverlappingSchwarzScalarProduct (std::shared_ptr<const C> comm) :
\n+
204 ParallelScalarProduct<X,C>(comm, SolverCategory::overlapping) {}
\n+
205
\n+\n+
207 ParallelScalarProduct<X,C>(comm,SolverCategory::overlapping) {}
\n+
208 };
\n+
209
\n+
223 template<class X, class Comm>
\n+
224 std::shared_ptr<ScalarProduct<X>> makeScalarProduct(std::shared_ptr<const Comm> comm, SolverCategory::Category category)
\n+
225 {
\n+
226 switch(category)
\n+
227 {
\n+\n+
229 return
\n+
230 std::make_shared<ScalarProduct<X>>();
\n+
231 default:
\n+
232 return
\n+
233 std::make_shared<ParallelScalarProduct<X,Comm>>(comm,category);
\n+
234 }
\n+
235 }
\n+
236
\n+
241 template<class X, class Comm>
\n+
242 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const Comm& comm, SolverCategory::Category category)
\n+
243 { return makeScalarProduct<X>(stackobject_to_shared_ptr(comm), category); }
\n+
244
\n+
245} // end namespace Dune
\n+
246
\n+
247#endif
\n+
This file implements a vector space as a tensor product of a given vector space. The number of compon...
\n+\n+
Definition: allocator.hh:11
\n+
std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm, SolverCategory::Category category)
Definition: scalarproducts.hh:242
\n+
std::shared_ptr< ScalarProduct< X > > makeScalarProduct(std::shared_ptr< const Comm > comm, SolverCategory::Category category)
Choose the approriate scalar product for a solver category.
Definition: scalarproducts.hh:224
\n+
Base class for scalar product and norm computation.
Definition: scalarproducts.hh:52
\n+
virtual field_type dot(const X &x, const X &y) const
Dot product of two vectors. It is assumed that the vectors are consistent on the interior+border part...
Definition: scalarproducts.hh:63
\n+
virtual SolverCategory::Category category() const
Category of the scalar product (see SolverCategory::Category)
Definition: scalarproducts.hh:77
\n+
X::field_type field_type
Definition: scalarproducts.hh:56
\n+
X domain_type
export types, they come from the derived class
Definition: scalarproducts.hh:55
\n+
virtual ~ScalarProduct()
every abstract base class has a virtual destructor
Definition: scalarproducts.hh:83
\n+
FieldTraits< field_type >::real_type real_type
Definition: scalarproducts.hh:57
\n+
virtual real_type norm(const X &x) const
Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
Definition: scalarproducts.hh:71
\n+
Scalar product for overlapping Schwarz methods.
Definition: scalarproducts.hh:99
\n+
virtual field_type dot(const X &x, const X &y) const override
Dot product of two vectors. It is assumed that the vectors are consistent on the interior+border part...
Definition: scalarproducts.hh:139
\n+
virtual SolverCategory::Category category() const override
Category of the scalar product (see SolverCategory::Category)
Definition: scalarproducts.hh:155
\n+
FieldTraits< field_type >::real_type real_type
Definition: scalarproducts.hh:108
\n+
C communication_type
The type of the communication object.
Definition: scalarproducts.hh:113
\n+
ParallelScalarProduct(const communication_type &com, SolverCategory::Category cat)
Definition: scalarproducts.hh:130
\n+
X domain_type
The type of the vector to compute the scalar product on.
Definition: scalarproducts.hh:105
\n+
ParallelScalarProduct(std::shared_ptr< const communication_type > com, SolverCategory::Category cat)
Definition: scalarproducts.hh:120
\n+
X::field_type field_type
The field type used by the vector type domain_type.
Definition: scalarproducts.hh:107
\n+
virtual real_type norm(const X &x) const override
Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
Definition: scalarproducts.hh:149
\n+
Default implementation for the scalar case.
Definition: scalarproducts.hh:168
\n+
Nonoverlapping Scalar Product with communication object.
Definition: scalarproducts.hh:179
\n+
NonoverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)
Definition: scalarproducts.hh:181
\n+
NonoverlappingSchwarzScalarProduct(const C &comm)
Definition: scalarproducts.hh:184
\n+
Scalar product for overlapping Schwarz methods.
Definition: scalarproducts.hh:201
\n+
OverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)
Definition: scalarproducts.hh:203
\n+
OverlappingSchwarzScalarProduct(const C &comm)
Definition: scalarproducts.hh:206
\n+
Categories for the solvers.
Definition: solvercategory.hh:22
\n+
Category
Definition: solvercategory.hh:23
\n+
@ sequential
Category for sequential solvers.
Definition: solvercategory.hh:25
\n
\n \n
\n Generated by \"doxygen\"/ 1.9.4\n
\n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,126 +4,272 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-superlufunctions.hh\n+scalarproducts.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SUPERLUFUNCTIONS_HH\n- 6#define DUNE_ISTL_SUPERLUFUNCTIONS_HH\n- 7#if HAVE_SUPERLU\n- 8\n- 9\n-10#define int_t SUPERLU_INT_TYPE\n- 11#include \"supermatrix.h\"\n- 12#include \"slu_util.h\"\n- 13#undef int_t\n+ 5#ifndef DUNE_ISTL_SCALARPRODUCTS_HH\n+ 6#define DUNE_ISTL_SCALARPRODUCTS_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n 14\n- 15#if __has_include(\"slu_sdefs.h\")\n- 16extern \"C\" {\n- 17 extern void\n- 18 sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n- 19 char *, float *, float *, SuperMatrix *, SuperMatrix *,\n- 20 void *, int, SuperMatrix *, SuperMatrix *,\n- 21 float *, float *, float *, float *,\n- 22 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n- 23\n- 24 extern void\n- 25 sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int,\n- 26 Stype_t, Dtype_t, Mtype_t);\n- 27 extern void\n- 28 sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *,\n- 29 int *, int *, Stype_t, Dtype_t, Mtype_t);\n- 30 extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n- 31\n- 32 extern void sPrint_CompCol_Matrix(char *, SuperMatrix *);\n- 33}\n- 34#endif\n- 35\n- 36#if __has_include(\"slu_ddefs.h\")\n- 37extern \"C\" {\n- 38 extern void\n- 39 dgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n- 40 char *, double *, double *, SuperMatrix *, SuperMatrix *,\n- 41 void *, int, SuperMatrix *, SuperMatrix *,\n- 42 double *, double *, double *, double *,\n- 43 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n- 44\n- 45 extern void\n- 46 dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *,\n- 47 int *, int *, Stype_t, Dtype_t, Mtype_t);\n- 48\n- 49 extern void\n- 50 dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int,\n- 51 Stype_t, Dtype_t, Mtype_t);\n- 52\n- 53 extern int dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n- 54\n- 55 extern void dPrint_CompCol_Matrix(char *, SuperMatrix *);\n- 56}\n- 57#endif\n+ 15#include \n+ 16#include \n+ 17\n+ 18#include \"bvector.hh\"\n+ 19#include \"solvercategory.hh\"\n+ 20\n+ 21\n+ 22namespace Dune {\n+ 51 template\n+52 class ScalarProduct {\n+ 53 public:\n+55 typedef X domain_type;\n+56 typedef typename X::field_type field_type;\n+57 typedef typename FieldTraits::real_type real_type;\n 58\n- 59#if __has_include(\"slu_cdefs.h\")\n- 60#include \"slu_scomplex.h\"\n- 61\n- 62extern \"C\" {\n- 63 extern void\n- 64 cgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n- 65 char *, float *, float *, SuperMatrix *, SuperMatrix *,\n- 66 void *, int, SuperMatrix *, SuperMatrix *,\n- 67 float *, float *, float *, float *,\n- 68 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n- 69\n- 70\n- 71 extern void\n- 72 cCreate_Dense_Matrix(SuperMatrix *, int, int, ::complex *, int,\n- 73 Stype_t, Dtype_t, Mtype_t);\n- 74\n+63 virtual field_type dot (const X& x, const X& y) const\n+ 64 {\n+ 65 return x.dot(y);\n+ 66 }\n+ 67\n+71 virtual real_type norm (const X& x) const\n+ 72 {\n+ 73 return x.two_norm();\n+ 74 }\n 75\n- 76 extern void\n- 77 cCreate_CompCol_Matrix(SuperMatrix *, int, int, int, ::complex *,\n- 78 int *, int *, Stype_t, Dtype_t, Mtype_t);\n- 79\n- 80 extern int cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n+77 virtual SolverCategory::Category category() const\n+ 78 {\n+ 79 return SolverCategory::sequential;\n+ 80 }\n 81\n- 82 extern void cPrint_CompCol_Matrix(char *, SuperMatrix *);\n- 83}\n- 84#endif\n+83 virtual ~ScalarProduct () {}\n+ 84 };\n 85\n- 86#if __has_include(\"slu_zdefs.h\")\n- 87#include \"slu_dcomplex.h\"\n- 88extern \"C\" {\n- 89 extern void\n- 90 zgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n- 91 char *, double *, double *, SuperMatrix *, SuperMatrix *,\n- 92 void *, int, SuperMatrix *, SuperMatrix *,\n- 93 double *, double *, double *, double *,\n- 94 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n- 95\n- 96\n- 97 extern void\n- 98 zCreate_CompCol_Matrix(SuperMatrix *, int, int, int, doublecomplex *,\n- 99 int *, int *, Stype_t, Dtype_t, Mtype_t);\n- 100\n- 101 extern void\n- 102 zCreate_Dense_Matrix(SuperMatrix *, int, int, doublecomplex *, int,\n- 103 Stype_t, Dtype_t, Mtype_t);\n- 104\n- 105 extern int zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n- 106\n- 107 extern void zPrint_CompCol_Matrix(char *, SuperMatrix *);\n- 108}\n- 109#endif\n- 110\n- 111\n- 112#endif\n- 113#endif\n+ 97 template\n+98 class ParallelScalarProduct : public ScalarProduct\n+ 99 {\n+ 100 public:\n+105 typedef X domain_type;\n+107 typedef typename X::field_type field_type;\n+108 typedef typename FieldTraits::real_type real_type;\n+113 typedef C communication_type;\n+ 114\n+120 ParallelScalarProduct (std::shared_ptr com,\n+SolverCategory::Category cat)\n+ 121 : _communication(com), _category(cat)\n+ 122 {}\n+ 123\n+130 ParallelScalarProduct (const communication_type& com, SolverCategory::\n+Category cat)\n+ 131 : ParallelScalarProduct(stackobject_to_shared_ptr(com), cat)\n+ 132 {}\n+ 133\n+ 134\n+139 virtual field_type dot (const X& x, const X& y) const override\n+ 140 {\n+ 141 field_type result(0);\n+ 142 _communication->dot(x,y,result); // explicitly loop and apply masking\n+ 143 return result;\n+ 144 }\n+ 145\n+149 virtual real_type norm (const X& x) const override\n+ 150 {\n+ 151 return _communication->norm(x);\n+ 152 }\n+ 153\n+155 virtual SolverCategory::Category category() const override\n+ 156 {\n+ 157 return _category;\n+ 158 }\n+ 159\n+ 160 private:\n+ 161 std::shared_ptr _communication;\n+ 162 SolverCategory::Category _category;\n+ 163 };\n+ 164\n+ 166 template\n+167 class SeqScalarProduct : public ScalarProduct\n+ 168 {\n+ 169 using ScalarProduct::ScalarProduct;\n+ 170 };\n+ 171\n+ 177 template\n+178 class NonoverlappingSchwarzScalarProduct : public\n+ParallelScalarProduct\n+ 179 {\n+ 180 public:\n+181 NonoverlappingSchwarzScalarProduct (std::shared_ptr comm) :\n+ 182 ParallelScalarProduct(comm,SolverCategory::nonoverlapping) {}\n+ 183\n+184 NonoverlappingSchwarzScalarProduct (const C& comm) :\n+ 185 ParallelScalarProduct(comm,SolverCategory::nonoverlapping) {}\n+ 186 };\n+ 187\n+ 199 template\n+200 class OverlappingSchwarzScalarProduct : public ParallelScalarProduct\n+ 201 {\n+ 202 public:\n+203 OverlappingSchwarzScalarProduct (std::shared_ptr comm) :\n+ 204 ParallelScalarProduct(comm, SolverCategory::overlapping) {}\n+ 205\n+206 OverlappingSchwarzScalarProduct (const C& comm) :\n+ 207 ParallelScalarProduct(comm,SolverCategory::overlapping) {}\n+ 208 };\n+ 209\n+ 223 template\n+224 std::shared_ptr> makeScalarProduct(std::shared_ptr comm, SolverCategory::Category category)\n+ 225 {\n+ 226 switch(category)\n+ 227 {\n+ 228 case SolverCategory::sequential:\n+ 229 return\n+ 230 std::make_shared>();\n+ 231 default:\n+ 232 return\n+ 233 std::make_shared>(comm,category);\n+ 234 }\n+ 235 }\n+ 236\n+ 241 template\n+242 std::shared_ptr> createScalarProduct(const Comm& comm,\n+SolverCategory::Category category)\n+ 243 { return makeScalarProduct(stackobject_to_shared_ptr(comm), category);\n+}\n+ 244\n+ 245} // end namespace Dune\n+ 246\n+ 247#endif\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+solvercategory.hh\n+Dune\n+Definition: allocator.hh:11\n+Dune::createScalarProduct\n+std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm,\n+SolverCategory::Category category)\n+Definition: scalarproducts.hh:242\n+Dune::makeScalarProduct\n+std::shared_ptr< ScalarProduct< X > > makeScalarProduct(std::shared_ptr< const\n+Comm > comm, SolverCategory::Category category)\n+Choose the approriate scalar product for a solver category.\n+Definition: scalarproducts.hh:224\n+Dune::ScalarProduct\n+Base class for scalar product and norm computation.\n+Definition: scalarproducts.hh:52\n+Dune::ScalarProduct::dot\n+virtual field_type dot(const X &x, const X &y) const\n+Dot product of two vectors. It is assumed that the vectors are consistent on\n+the interior+border part...\n+Definition: scalarproducts.hh:63\n+Dune::ScalarProduct::category\n+virtual SolverCategory::Category category() const\n+Category of the scalar product (see SolverCategory::Category)\n+Definition: scalarproducts.hh:77\n+Dune::ScalarProduct::field_type\n+X::field_type field_type\n+Definition: scalarproducts.hh:56\n+Dune::ScalarProduct::domain_type\n+X domain_type\n+export types, they come from the derived class\n+Definition: scalarproducts.hh:55\n+Dune::ScalarProduct::~ScalarProduct\n+virtual ~ScalarProduct()\n+every abstract base class has a virtual destructor\n+Definition: scalarproducts.hh:83\n+Dune::ScalarProduct::real_type\n+FieldTraits< field_type >::real_type real_type\n+Definition: scalarproducts.hh:57\n+Dune::ScalarProduct::norm\n+virtual real_type norm(const X &x) const\n+Norm of a right-hand side vector. The vector must be consistent on the\n+interior+border partition.\n+Definition: scalarproducts.hh:71\n+Dune::ParallelScalarProduct\n+Scalar product for overlapping Schwarz methods.\n+Definition: scalarproducts.hh:99\n+Dune::ParallelScalarProduct::dot\n+virtual field_type dot(const X &x, const X &y) const override\n+Dot product of two vectors. It is assumed that the vectors are consistent on\n+the interior+border part...\n+Definition: scalarproducts.hh:139\n+Dune::ParallelScalarProduct::category\n+virtual SolverCategory::Category category() const override\n+Category of the scalar product (see SolverCategory::Category)\n+Definition: scalarproducts.hh:155\n+Dune::ParallelScalarProduct::real_type\n+FieldTraits< field_type >::real_type real_type\n+Definition: scalarproducts.hh:108\n+Dune::ParallelScalarProduct::communication_type\n+C communication_type\n+The type of the communication object.\n+Definition: scalarproducts.hh:113\n+Dune::ParallelScalarProduct::ParallelScalarProduct\n+ParallelScalarProduct(const communication_type &com, SolverCategory::Category\n+cat)\n+Definition: scalarproducts.hh:130\n+Dune::ParallelScalarProduct::domain_type\n+X domain_type\n+The type of the vector to compute the scalar product on.\n+Definition: scalarproducts.hh:105\n+Dune::ParallelScalarProduct::ParallelScalarProduct\n+ParallelScalarProduct(std::shared_ptr< const communication_type > com,\n+SolverCategory::Category cat)\n+Definition: scalarproducts.hh:120\n+Dune::ParallelScalarProduct::field_type\n+X::field_type field_type\n+The field type used by the vector type domain_type.\n+Definition: scalarproducts.hh:107\n+Dune::ParallelScalarProduct::norm\n+virtual real_type norm(const X &x) const override\n+Norm of a right-hand side vector. The vector must be consistent on the\n+interior+border partition.\n+Definition: scalarproducts.hh:149\n+Dune::SeqScalarProduct\n+Default implementation for the scalar case.\n+Definition: scalarproducts.hh:168\n+Dune::NonoverlappingSchwarzScalarProduct\n+Nonoverlapping Scalar Product with communication object.\n+Definition: scalarproducts.hh:179\n+Dune::NonoverlappingSchwarzScalarProduct::NonoverlappingSchwarzScalarProduct\n+NonoverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)\n+Definition: scalarproducts.hh:181\n+Dune::NonoverlappingSchwarzScalarProduct::NonoverlappingSchwarzScalarProduct\n+NonoverlappingSchwarzScalarProduct(const C &comm)\n+Definition: scalarproducts.hh:184\n+Dune::OverlappingSchwarzScalarProduct\n+Scalar product for overlapping Schwarz methods.\n+Definition: scalarproducts.hh:201\n+Dune::OverlappingSchwarzScalarProduct::OverlappingSchwarzScalarProduct\n+OverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)\n+Definition: scalarproducts.hh:203\n+Dune::OverlappingSchwarzScalarProduct::OverlappingSchwarzScalarProduct\n+OverlappingSchwarzScalarProduct(const C &comm)\n+Definition: scalarproducts.hh:206\n+Dune::SolverCategory\n+Categories for the solvers.\n+Definition: solvercategory.hh:22\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00023.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00023.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrix.hh File Reference\n+dune-istl: scaledidmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -65,58 +65,48 @@\n
  • dune
  • istl
  • \n
    \n
    \n
    \n \n-
    matrix.hh File Reference
    \n+
    scaledidmatrix.hh File Reference
    \n
    \n
    \n \n-

    A dynamic dense block matrix class. \n+

    This file implements a quadratic matrix of fixed size which is a multiple of the identity. \n More...

    \n
    #include <cmath>
    \n-#include <memory>
    \n+#include <cstddef>
    \n+#include <complex>
    \n+#include <iostream>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/diagonalmatrix.hh>
    \n #include <dune/common/ftraits.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/istl/bvector.hh>
    \n-#include <dune/istl/istlexception.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::MatrixImp::DenseMatrixBase< B, A >
     A Vector of blocks with different blocksizes. More...
    class  Dune::ScaledIdentityMatrix< K, n >
     A multiple of the identity matrix of static size. More...
     
    class  Dune::MatrixImp::DenseMatrixBase< B, A >::Iterator
     Iterator class for sequential access. More...
    struct  Dune::DenseMatrixAssigner< DenseMatrix, ScaledIdentityMatrix< field, N > >
     
    class  Dune::MatrixImp::DenseMatrixBase< B, A >::ConstIterator
     ConstIterator class for sequential access. More...
     
    class  Dune::Matrix< T, A >
     A generic dynamic dense matrix. More...
     
    struct  Dune::FieldTraits< Matrix< T, A > >
    struct  Dune::FieldTraits< ScaledIdentityMatrix< K, n > >
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::MatrixImp
     
    \n

    Detailed Description

    \n-

    A dynamic dense block matrix class.

    \n+

    This file implements a quadratic matrix of fixed size which is a multiple of the identity.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,44 +5,37 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n Classes | Namespaces\n-matrix.hh File Reference\n-A dynamic dense block matrix class. More...\n+scaledidmatrix.hh File Reference\n+This file implements a quadratic matrix of fixed size which is a multiple of\n+the identity. More...\n #include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>\n-\u00a0 A Vector of blocks with different blocksizes. More...\n+ class \u00a0Dune::ScaledIdentityMatrix<_K,_n_>\n+\u00a0 A multiple of the identity matrix of static size. More...\n \u00a0\n- class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>::Iterator\n-\u00a0 Iterator class for sequential access. More...\n+struct \u00a0Dune::DenseMatrixAssigner<_DenseMatrix,_ScaledIdentityMatrix<_field,_N\n+ >_>\n \u00a0\n- class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>::ConstIterator\n-\u00a0 ConstIterator class for sequential access. More...\n-\u00a0\n- class \u00a0Dune::Matrix<_T,_A_>\n-\u00a0 A generic dynamic dense matrix. More...\n-\u00a0\n-struct \u00a0Dune::FieldTraits<_Matrix<_T,_A_>_>\n+struct \u00a0Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::MatrixImp\n-\u00a0\n ***** Detailed Description *****\n-A dynamic dense block matrix class.\n+This file implements a quadratic matrix of fixed size which is a multiple of\n+the identity.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00023_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00023_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrix.hh Source File\n+dune-istl: scaledidmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -62,1070 +62,520 @@\n \n
    \n \n
    \n
    \n
    \n-
    matrix.hh
    \n+
    scaledidmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MATRIX_HH
    \n-
    6#define DUNE_ISTL_MATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_SCALEDIDMATRIX_HH
    \n+
    6#define DUNE_ISTL_SCALEDIDMATRIX_HH
    \n
    7
    \n-
    12#include <cmath>
    \n-
    13#include <memory>
    \n-
    14
    \n-
    15#include <dune/common/ftraits.hh>
    \n-
    16#include <dune/common/typetraits.hh>
    \n-
    17#include <dune/common/scalarvectorview.hh>
    \n-
    18#include <dune/common/scalarmatrixview.hh>
    \n-
    19
    \n-
    20#include <dune/istl/bvector.hh>
    \n-\n-\n-
    23
    \n-
    24namespace Dune {
    \n-
    25
    \n-
    26namespace MatrixImp
    \n-
    27{
    \n-
    39 template<class B, class A=std::allocator<B> >
    \n-
    40 class DenseMatrixBase : public Imp::block_vector_unmanaged<B,A>
    \n-
    41 // this derivation gives us all the blas level 1 and norms
    \n-
    42 // on the large array. However, access operators have to be
    \n-
    43 // overwritten.
    \n-
    44 {
    \n-
    45 public:
    \n-
    46
    \n-
    47 //===== type definitions and constants
    \n+
    14#include <cmath>
    \n+
    15#include <cstddef>
    \n+
    16#include <complex>
    \n+
    17#include <iostream>
    \n+
    18#include <dune/common/exceptions.hh>
    \n+
    19#include <dune/common/fmatrix.hh>
    \n+
    20#include <dune/common/diagonalmatrix.hh>
    \n+
    21#include <dune/common/ftraits.hh>
    \n+
    22
    \n+
    23namespace Dune {
    \n+
    24
    \n+
    28 template<class K, int n>
    \n+\n+
    30 {
    \n+
    31 typedef DiagonalMatrixWrapper< ScaledIdentityMatrix<K,n> > WrapperType;
    \n+
    32
    \n+
    33 public:
    \n+
    34 //===== type definitions and constants
    \n+
    35
    \n+
    37 typedef K field_type;
    \n+
    38
    \n+
    40 typedef K block_type;
    \n+
    41
    \n+
    43 typedef std::size_t size_type;
    \n+
    44
    \n+
    46 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    47 static constexpr std::size_t blocklevel = 1;
    \n
    48
    \n-
    50 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    51
    \n-
    53 typedef A allocator_type;
    \n+
    50 typedef DiagonalRowVector<K,n> row_type;
    \n+\n+
    52 typedef DiagonalRowVectorConst<K,n> const_row_type;
    \n+\n
    54
    \n-
    56 typedef typename A::size_type size_type;
    \n-
    57
    \n-\n-
    64
    \n-\n-
    68
    \n-
    69 // just a shorthand
    \n-
    70 typedef Imp::BlockVectorWindow<B,A> window_type;
    \n-
    71
    \n-\n+
    56 enum {
    \n+
    58 rows = n,
    \n+
    60 cols = n
    \n+
    61 };
    \n+
    62
    \n+
    63 //===== constructors
    \n+\n+
    67
    \n+\n+
    71 : p_(k)
    \n+
    72 {}
    \n
    73
    \n-\n-
    75
    \n-
    76
    \n-
    77 //===== constructors and such
    \n-
    78
    \n-
    82 DenseMatrixBase () : Imp::block_vector_unmanaged<B,A>()
    \n-
    83 {
    \n-
    84 // nothing is known ...
    \n-
    85 rows_ = 0;
    \n-
    86 columns_ = 0;
    \n-
    87 }
    \n-
    88
    \n-
    95 DenseMatrixBase (size_type rows, size_type columns) : Imp::block_vector_unmanaged<B,A>()
    \n-
    96 {
    \n-
    97 // and we can allocate the big array in the base class
    \n-
    98 this->n = rows*columns;
    \n-
    99 columns_ = columns;
    \n-
    100 if (this->n>0)
    \n-
    101 {
    \n-
    102 this->p = allocator_.allocate(this->n);
    \n-
    103 new (this->p)B[this->n];
    \n-
    104 }
    \n-
    105 else
    \n-
    106 {
    \n-
    107 this->n = 0;
    \n-
    108 this->p = 0;
    \n-
    109 }
    \n-
    110
    \n-
    111 // we can allocate the windows now
    \n-
    112 rows_ = rows;
    \n-
    113 }
    \n-
    114
    \n-\n-
    117 {
    \n-
    118 // allocate the big array in the base class
    \n-
    119 this->n = a.n;
    \n-
    120 columns_ = a.columns_;
    \n-
    121 if (this->n>0)
    \n-
    122 {
    \n-
    123 // allocate and construct objects
    \n-
    124 this->p = allocator_.allocate(this->n);
    \n-
    125 new (this->p)B[this->n];
    \n-
    126
    \n-
    127 // copy data
    \n-
    128 for (size_type i=0; i<this->n; i++)
    \n-
    129 this->p[i]=a.p[i];
    \n-
    130 }
    \n-
    131 else
    \n-
    132 {
    \n-
    133 this->n = 0;
    \n-
    134 this->p = nullptr;
    \n-
    135 }
    \n-
    136
    \n-
    137 // we can allocate the windows now
    \n-
    138 rows_ = a.rows_;
    \n-
    139 }
    \n-
    140
    \n-\n-
    143 {
    \n-
    144 if (this->n>0) {
    \n-
    145 size_type i=this->n;
    \n-
    146 while (i)
    \n-
    147 this->p[--i].~B();
    \n-
    148 allocator_.deallocate(this->p,this->n);
    \n-
    149 }
    \n+
    74 //===== assignment from scalar
    \n+\n+
    76 {
    \n+
    77 p_ = k;
    \n+
    78 return *this;
    \n+
    79 }
    \n+
    80
    \n+
    81 // check if matrix is identical to other matrix (not only identical values)
    \n+
    82 bool identical(const ScaledIdentityMatrix<K,n>& other) const
    \n+
    83 {
    \n+
    84 return (this==&other);
    \n+
    85 }
    \n+
    86
    \n+
    87 //===== iterator interface to rows of the matrix
    \n+
    89 typedef ContainerWrapperIterator<const WrapperType, reference, reference> Iterator;
    \n+\n+\n+
    95 typedef typename row_type::Iterator ColIterator;
    \n+
    96
    \n+\n+
    99 {
    \n+
    100 return Iterator(WrapperType(this),0);
    \n+
    101 }
    \n+
    102
    \n+\n+
    105 {
    \n+
    106 return Iterator(WrapperType(this),n);
    \n+
    107 }
    \n+
    108
    \n+\n+
    112 {
    \n+
    113 return Iterator(WrapperType(this),n-1);
    \n+
    114 }
    \n+
    115
    \n+\n+
    119 {
    \n+
    120 return Iterator(WrapperType(this),-1);
    \n+
    121 }
    \n+
    122
    \n+
    123
    \n+
    125 typedef ContainerWrapperIterator<const WrapperType, const_reference, const_reference> ConstIterator;
    \n+\n+\n+
    131 typedef typename const_row_type::ConstIterator ConstColIterator;
    \n+
    132
    \n+\n+
    135 {
    \n+
    136 return ConstIterator(WrapperType(this),0);
    \n+
    137 }
    \n+
    138
    \n+\n+
    141 {
    \n+
    142 return ConstIterator(WrapperType(this),n);
    \n+
    143 }
    \n+
    144
    \n+\n+
    148 {
    \n+
    149 return ConstIterator(WrapperType(this),n-1);
    \n
    150 }
    \n
    151
    \n-
    153 void resize (size_type rows, size_type columns)
    \n-
    154 {
    \n-
    155 // deconstruct objects and deallocate memory if necessary
    \n-
    156 if (this->n>0) {
    \n-
    157 size_type i=this->n;
    \n-
    158 while (i)
    \n-
    159 this->p[--i].~B();
    \n-
    160 allocator_.deallocate(this->p,this->n);
    \n-
    161 }
    \n-
    162
    \n-
    163 // and we can allocate the big array in the base class
    \n-
    164 this->n = rows*columns;
    \n-
    165 if (this->n>0)
    \n-
    166 {
    \n-
    167 this->p = allocator_.allocate(this->n);
    \n-
    168 new (this->p)B[this->n];
    \n-
    169 }
    \n-
    170 else
    \n-
    171 {
    \n-
    172 this->n = 0;
    \n-
    173 this->p = nullptr;
    \n-
    174 }
    \n-
    175
    \n-
    176 // we can allocate the windows now
    \n-
    177 rows_ = rows;
    \n-
    178 columns_ = columns;
    \n-
    179 }
    \n-
    180
    \n-\n-
    183 {
    \n-
    184 if (&a!=this) // check if this and a are different objects
    \n-
    185 {
    \n-
    186 columns_ = a.columns_;
    \n-
    187 // reallocate arrays if necessary
    \n-
    188 // Note: still the block sizes may vary !
    \n-
    189 if (this->n!=a.n || rows_!=a.rows_)
    \n-
    190 {
    \n-
    191 // deconstruct objects and deallocate memory if necessary
    \n-
    192 if (this->n>0) {
    \n-
    193 size_type i=this->n;
    \n-
    194 while (i)
    \n-
    195 this->p[--i].~B();
    \n-
    196 allocator_.deallocate(this->p,this->n);
    \n-
    197 }
    \n-
    198
    \n-
    199 // allocate the big array in the base class
    \n-
    200 this->n = a.n;
    \n-
    201 if (this->n>0)
    \n-
    202 {
    \n-
    203 // allocate and construct objects
    \n-
    204 this->p = allocator_.allocate(this->n);
    \n-
    205 new (this->p)B[this->n];
    \n-
    206 }
    \n-
    207 else
    \n-
    208 {
    \n-
    209 this->n = 0;
    \n-
    210 this->p = nullptr;
    \n-
    211 }
    \n-
    212
    \n-
    213 // Copy number of rows
    \n-
    214 rows_ = a.rows_;
    \n-
    215 }
    \n-
    216
    \n-
    217 // and copy the data
    \n-
    218 for (size_type i=0; i<this->n; i++)
    \n-
    219 this->p[i]=a.p[i];
    \n-
    220 }
    \n+\n+
    155 {
    \n+
    156 return ConstIterator(WrapperType(this),-1);
    \n+
    157 }
    \n+
    158
    \n+
    159 //===== vector space arithmetic
    \n+
    160
    \n+\n+
    163 {
    \n+
    164 p_ += y.p_;
    \n+
    165 return *this;
    \n+
    166 }
    \n+
    167
    \n+\n+
    170 {
    \n+
    171 p_ -= y.p_;
    \n+
    172 return *this;
    \n+
    173 }
    \n+
    174
    \n+\n+
    177 {
    \n+
    178 p_ += k;
    \n+
    179 return *this;
    \n+
    180 }
    \n+
    181
    \n+\n+
    184 {
    \n+
    185 p_ -= k;
    \n+
    186 return *this;
    \n+
    187 }
    \n+\n+
    190 {
    \n+
    191 p_ *= k;
    \n+
    192 return *this;
    \n+
    193 }
    \n+
    194
    \n+\n+
    197 {
    \n+
    198 p_ /= k;
    \n+
    199 return *this;
    \n+
    200 }
    \n+
    201
    \n+
    202 //===== binary operators
    \n+
    203
    \n+
    205 template <class Scalar,
    \n+
    206 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
    \n+
    207 friend auto operator* ( const ScaledIdentityMatrix& matrix, Scalar scalar)
    \n+
    208 {
    \n+\n+
    210 }
    \n+
    211
    \n+
    213 template <class Scalar,
    \n+
    214 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
    \n+
    215 friend auto operator* (Scalar scalar, const ScaledIdentityMatrix& matrix)
    \n+
    216 {
    \n+\n+
    218 }
    \n+
    219
    \n+
    220 //===== comparison ops
    \n
    221
    \n-
    222 return *this;
    \n-
    223 }
    \n-
    224
    \n-
    225
    \n-
    226 //===== assignment from scalar
    \n+
    223 bool operator==(const ScaledIdentityMatrix& other) const
    \n+
    224 {
    \n+
    225 return p_==other.scalar();
    \n+
    226 }
    \n
    227
    \n-\n-
    230 {
    \n-
    231 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n-
    232 return *this;
    \n-
    233 }
    \n-
    234
    \n+
    229 bool operator!=(const ScaledIdentityMatrix& other) const
    \n+
    230 {
    \n+
    231 return p_!=other.scalar();
    \n+
    232 }
    \n+
    233
    \n+
    234 //===== linear maps
    \n
    235
    \n-
    236 //===== access to components
    \n-
    237 // has to be overwritten from base class because it must
    \n-
    238 // return access to the windows
    \n-
    239
    \n-\n-
    242 {
    \n-
    243#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    244 if (i>=rows_) DUNE_THROW(ISTLError,"index out of range");
    \n-
    245#endif
    \n-
    246 return window_type(this->p + i*columns_, columns_);
    \n-
    247 }
    \n-
    248
    \n-\n+
    237 template<class X, class Y>
    \n+
    238 void mv (const X& x, Y& y) const
    \n+
    239 {
    \n+
    240#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    241 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    242 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    243#endif
    \n+
    244 for (size_type i=0; i<n; ++i)
    \n+
    245 y[i] = p_ * x[i];
    \n+
    246 }
    \n+
    247
    \n+
    249 template<class X, class Y>
    \n+
    250 void mtv (const X& x, Y& y) const
    \n
    251 {
    \n-
    252#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    253 if (i<0 || i>=rows_) DUNE_THROW(ISTLError,"index out of range");
    \n-
    254#endif
    \n-
    255 return window_type(this->p + i*columns_, columns_);
    \n-
    256 }
    \n-
    257
    \n-
    258 // forward declaration
    \n-
    259 class ConstIterator;
    \n-
    260
    \n-\n-
    263 {
    \n-
    264 public:
    \n-\n-
    267 : window_(nullptr,0)
    \n-
    268 {
    \n-
    269 i = 0;
    \n-
    270 }
    \n-
    271
    \n-
    272 Iterator (Iterator& other) = default;
    \n-
    273 Iterator (Iterator&& other) = default;
    \n-
    274
    \n-
    276 Iterator (B* data, size_type columns, size_type _i)
    \n-
    277 : i(_i),
    \n-
    278 window_(data + _i*columns, columns)
    \n-
    279 {}
    \n-
    280
    \n-\n-
    283 {
    \n-
    284 i = other.i;
    \n-
    285 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n-
    286 window_.set(other.window_.getsize(),other.window_.getptr());
    \n-
    287 return *this;
    \n-
    288 }
    \n-
    289
    \n-\n-
    292 {
    \n-
    293 i = other.i;
    \n-
    294 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n-
    295 window_.set(other.window_.getsize(),other.window_.getptr());
    \n-
    296 return *this;
    \n-
    297 }
    \n-
    298
    \n-\n-
    301 {
    \n-
    302 ++i;
    \n-
    303 window_.setptr(window_.getptr()+window_.getsize());
    \n-
    304 return *this;
    \n-
    305 }
    \n-
    306
    \n-\n-
    309 {
    \n-
    310 --i;
    \n-
    311 window_.setptr(window_.getptr()-window_.getsize());
    \n-
    312 return *this;
    \n-
    313 }
    \n+
    252 mv(x, y);
    \n+
    253 }
    \n+
    254
    \n+
    256 template<class X, class Y>
    \n+
    257 void umv (const X& x, Y& y) const
    \n+
    258 {
    \n+
    259#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    260 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    261 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    262#endif
    \n+
    263 for (size_type i=0; i<n; ++i)
    \n+
    264 y[i] += p_ * x[i];
    \n+
    265 }
    \n+
    266
    \n+
    268 template<class X, class Y>
    \n+
    269 void umtv (const X& x, Y& y) const
    \n+
    270 {
    \n+
    271#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    272 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    273 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    274#endif
    \n+
    275 for (size_type i=0; i<n; ++i)
    \n+
    276 y[i] += p_ * x[i];
    \n+
    277 }
    \n+
    278
    \n+
    280 template<class X, class Y>
    \n+
    281 void umhv (const X& x, Y& y) const
    \n+
    282 {
    \n+
    283#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    284 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    285 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    286#endif
    \n+
    287 for (size_type i=0; i<n; i++)
    \n+
    288 y[i] += conjugateComplex(p_)*x[i];
    \n+
    289 }
    \n+
    290
    \n+
    292 template<class X, class Y>
    \n+
    293 void mmv (const X& x, Y& y) const
    \n+
    294 {
    \n+
    295#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    296 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    297 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    298#endif
    \n+
    299 for (size_type i=0; i<n; ++i)
    \n+
    300 y[i] -= p_ * x[i];
    \n+
    301 }
    \n+
    302
    \n+
    304 template<class X, class Y>
    \n+
    305 void mmtv (const X& x, Y& y) const
    \n+
    306 {
    \n+
    307#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    308 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    309 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    310#endif
    \n+
    311 for (size_type i=0; i<n; ++i)
    \n+
    312 y[i] -= p_ * x[i];
    \n+
    313 }
    \n
    314
    \n-
    316 bool operator== (const Iterator& it) const
    \n-
    317 {
    \n-
    318 return window_.getptr() == it.window_.getptr();
    \n-
    319 }
    \n-
    320
    \n-
    322 bool operator!= (const Iterator& it) const
    \n-
    323 {
    \n-
    324 return window_.getptr() != it.window_.getptr();
    \n-
    325 }
    \n+
    316 template<class X, class Y>
    \n+
    317 void mmhv (const X& x, Y& y) const
    \n+
    318 {
    \n+
    319#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    320 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    321 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    322#endif
    \n+
    323 for (size_type i=0; i<n; i++)
    \n+
    324 y[i] -= conjugateComplex(p_)*x[i];
    \n+
    325 }
    \n
    326
    \n-
    328 bool operator== (const ConstIterator& it) const
    \n-
    329 {
    \n-
    330 return window_.getptr() == it.window_.getptr();
    \n-
    331 }
    \n-
    332
    \n-
    334 bool operator!= (const ConstIterator& it) const
    \n-
    335 {
    \n-
    336 return window_.getptr() != it.window_.getptr();
    \n-
    337 }
    \n+
    328 template<class X, class Y>
    \n+
    329 void usmv (const K& alpha, const X& x, Y& y) const
    \n+
    330 {
    \n+
    331#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    332 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    333 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    334#endif
    \n+
    335 for (size_type i=0; i<n; i++)
    \n+
    336 y[i] += alpha * p_ * x[i];
    \n+
    337 }
    \n
    338
    \n-\n-
    341 {
    \n-
    342 return window_;
    \n-
    343 }
    \n-
    344
    \n-\n-
    347 {
    \n-
    348 return &window_;
    \n-
    349 }
    \n+
    340 template<class X, class Y>
    \n+
    341 void usmtv (const K& alpha, const X& x, Y& y) const
    \n+
    342 {
    \n+
    343#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    344 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    345 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    346#endif
    \n+
    347 for (size_type i=0; i<n; i++)
    \n+
    348 y[i] += alpha * p_ * x[i];
    \n+
    349 }
    \n
    350
    \n-
    351 // return index corresponding to pointer
    \n-\n-
    353 {
    \n-
    354 return i;
    \n-
    355 }
    \n-
    356
    \n-
    357 friend class ConstIterator;
    \n-
    358
    \n-
    359 private:
    \n-
    360 size_type i;
    \n-
    361 mutable window_type window_;
    \n-
    362 };
    \n-
    363
    \n-\n-
    366 {
    \n-
    367 return Iterator(this->p, columns_, 0);
    \n-
    368 }
    \n-
    369
    \n-\n-
    372 {
    \n-
    373 return Iterator(this->p, columns_, rows_);
    \n-
    374 }
    \n-
    375
    \n-\n-
    379 {
    \n-
    380 return Iterator(this->p, columns_, rows_-1);
    \n+
    352 template<class X, class Y>
    \n+
    353 void usmhv (const K& alpha, const X& x, Y& y) const
    \n+
    354 {
    \n+
    355#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    356 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    357 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n+
    358#endif
    \n+
    359 for (size_type i=0; i<n; i++)
    \n+
    360 y[i] += alpha * conjugateComplex(p_) * x[i];
    \n+
    361 }
    \n+
    362
    \n+
    363 //===== norms
    \n+
    364
    \n+
    366 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n+
    367 {
    \n+
    368 return fvmeta::sqrt(n*p_*p_);
    \n+
    369 }
    \n+
    370
    \n+
    372 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n+
    373 {
    \n+
    374 return n*p_*p_;
    \n+
    375 }
    \n+
    376
    \n+
    378 typename FieldTraits<field_type>::real_type infinity_norm () const
    \n+
    379 {
    \n+
    380 return std::abs(p_);
    \n
    381 }
    \n
    382
    \n-\n-
    386 {
    \n-
    387 return Iterator(this->p, columns_, -1);
    \n-
    388 }
    \n-
    389
    \n-\n-
    392 {
    \n-
    393 return Iterator(this->p, columns_, std::min(i,rows_));
    \n-
    394 }
    \n-
    395
    \n-\n-
    398 {
    \n-
    399 return ConstIterator(this->p, columns_, std::min(i,rows_));
    \n-
    400 }
    \n-
    401
    \n-\n-
    404 {
    \n-
    405 public:
    \n-\n-
    408 : window_(nullptr,0)
    \n-
    409 {
    \n-
    410 i = 0;
    \n-
    411 }
    \n-
    412
    \n-
    414 ConstIterator (const B* data, size_type columns, size_type _i)
    \n-
    415 : i(_i),
    \n-
    416 window_(const_cast<B*>(data + _i * columns), columns)
    \n-
    417 {}
    \n-
    418
    \n-\n-
    421 : i(it.i), window_(it.window_.getptr(),it.window_.getsize())
    \n-
    422 {}
    \n-
    423
    \n-\n-
    425 {
    \n-
    426 i = other.i;
    \n-
    427 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n-
    428 window_.set(other.window_.getsize(),other.window_.getptr());
    \n-
    429 return *this;
    \n-
    430 }
    \n-
    431
    \n-\n-
    433 {
    \n-
    434 i = other.i;
    \n-
    435 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n-
    436 window_.set(other.window_.getsize(),other.window_.getptr());
    \n-
    437 return *this;
    \n-
    438 }
    \n+
    384 typename FieldTraits<field_type>::real_type infinity_norm_real () const
    \n+
    385 {
    \n+
    386 return fvmeta::absreal(p_);
    \n+
    387 }
    \n+
    388
    \n+
    389 //===== solve
    \n+
    390
    \n+
    393 template<class V>
    \n+
    394 void solve (V& x, const V& b) const
    \n+
    395 {
    \n+
    396 for (int i=0; i<n; i++)
    \n+
    397 x[i] = b[i]/p_;
    \n+
    398 }
    \n+
    399
    \n+
    402 void invert()
    \n+
    403 {
    \n+
    404 p_ = 1/p_;
    \n+
    405 }
    \n+
    406
    \n+
    408 K determinant () const {
    \n+
    409 return std::pow(p_,n);
    \n+
    410 }
    \n+
    411
    \n+
    412 //===== sizes
    \n+
    413
    \n+
    415 size_type N () const
    \n+
    416 {
    \n+
    417 return n;
    \n+
    418 }
    \n+
    419
    \n+
    421 size_type M () const
    \n+
    422 {
    \n+
    423 return n;
    \n+
    424 }
    \n+
    425
    \n+
    426 //===== query
    \n+
    427
    \n+
    429 bool exists (size_type i, size_type j) const
    \n+
    430 {
    \n+
    431#ifdef DUNE_FMatrix_WITH_CHECKING
    \n+
    432 if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
    \n+
    433 if (j<0 || j>=n) DUNE_THROW(FMatrixError,"column index out of range");
    \n+
    434#endif
    \n+
    435 return i==j;
    \n+
    436 }
    \n+
    437
    \n+
    438 //===== conversion operator
    \n
    439
    \n-\n-
    442 {
    \n-
    443 ++i;
    \n-
    444 window_.setptr(window_.getptr()+window_.getsize());
    \n-
    445 return *this;
    \n-
    446 }
    \n-
    447
    \n-\n-
    450 {
    \n-
    451 --i;
    \n-
    452 window_.setptr(window_.getptr()-window_.getsize());
    \n-
    453 return *this;
    \n-
    454 }
    \n-
    455
    \n-
    457 bool operator== (const ConstIterator& it) const
    \n-
    458 {
    \n-
    459 return window_.getptr() == it.window_.getptr();
    \n-
    460 }
    \n-
    461
    \n-
    463 bool operator!= (const ConstIterator& it) const
    \n-
    464 {
    \n-
    465 return window_.getptr() != it.window_.getptr();
    \n-
    466 }
    \n-
    467
    \n-
    469 bool operator== (const Iterator& it) const
    \n-
    470 {
    \n-
    471 return window_.getptr() == it.window_.getptr();
    \n-
    472 }
    \n-
    473
    \n-
    475 bool operator!= (const Iterator& it) const
    \n-
    476 {
    \n-
    477 return window_.getptr() != it.window_.getptr();
    \n-
    478 }
    \n-
    479
    \n-
    481 const window_type& operator* () const
    \n-
    482 {
    \n-
    483 return window_;
    \n-
    484 }
    \n-
    485
    \n-\n-
    488 {
    \n-
    489 return &window_;
    \n-
    490 }
    \n-
    491
    \n-
    492 // return index corresponding to pointer
    \n-\n-
    494 {
    \n-
    495 return i;
    \n-
    496 }
    \n-
    497
    \n-
    498 friend class Iterator;
    \n-
    499
    \n-
    500 private:
    \n-
    501 size_type i;
    \n-
    502 mutable window_type window_;
    \n-
    503 };
    \n-
    504
    \n-\n-
    507
    \n-\n-
    510
    \n-\n-
    513 {
    \n-
    514 return ConstIterator(this->p, columns_, 0);
    \n-
    515 }
    \n-
    516
    \n-\n-
    519 {
    \n-
    520 return ConstIterator(this->p, columns_, rows_);
    \n-
    521 }
    \n-
    522
    \n-\n-
    526 {
    \n-
    527 return ConstIterator(this->p, columns_, rows_-1);
    \n-
    528 }
    \n-
    529
    \n-\n-
    532 {
    \n-
    533 return ConstIterator(this->p, columns_, -1);
    \n-
    534 }
    \n-
    535
    \n-
    536 //===== sizes
    \n-
    537
    \n-
    539 size_type N () const
    \n-
    540 {
    \n-
    541 return rows_;
    \n-
    542 }
    \n-
    543
    \n-
    544
    \n-
    545 private:
    \n-
    546 size_type rows_; // number of matrix rows
    \n-
    547 size_type columns_; // number of matrix columns
    \n-
    548
    \n-
    549 A allocator_;
    \n-
    550 };
    \n-
    551
    \n-
    552} // namespace MatrixImp
    \n-
    553
    \n-
    559 template<class T, class A=std::allocator<T> >
    \n-
    560 class Matrix
    \n-
    561 {
    \n-
    562 public:
    \n-
    563
    \n-
    565 using field_type = typename Imp::BlockTraits<T>::field_type;
    \n-
    566
    \n-
    568 typedef T block_type;
    \n-
    569
    \n-
    571 typedef A allocator_type;
    \n-
    572
    \n-\n-
    575
    \n-
    577 typedef typename A::size_type size_type;
    \n-
    578
    \n-\n-
    581
    \n-
    583 typedef typename row_type::iterator ColIterator;
    \n-
    584
    \n-\n-
    587
    \n-
    589 typedef typename row_type::const_iterator ConstColIterator;
    \n-
    590
    \n-
    592 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    593 static constexpr auto blocklevel = blockLevel<T>()+1;
    \n-
    594
    \n-
    596 Matrix() : data_(0,0), cols_(0)
    \n-
    597 {}
    \n-
    598
    \n-
    601 Matrix(size_type rows, size_type cols) : data_(rows,cols), cols_(cols)
    \n-
    602 {}
    \n-
    603
    \n-
    608 void setSize(size_type rows, size_type cols) {
    \n-
    609 data_.resize(rows,cols);
    \n-
    610 cols_ = cols;
    \n-
    611 }
    \n-
    612
    \n-\n-
    615 {
    \n-
    616 return data_.begin();
    \n-
    617 }
    \n-
    618
    \n-\n-
    621 {
    \n-
    622 return data_.end();
    \n-
    623 }
    \n-
    624
    \n-\n-
    628 {
    \n-
    629 return data_.beforeEnd();
    \n-
    630 }
    \n-
    631
    \n-\n-
    635 {
    \n-
    636 return data_.beforeBegin();
    \n-
    637 }
    \n-
    638
    \n-\n-
    641 {
    \n-
    642 return data_.begin();
    \n-
    643 }
    \n-
    644
    \n-\n-
    647 {
    \n-
    648 return data_.end();
    \n-
    649 }
    \n-
    650
    \n-\n-
    654 {
    \n-
    655 return data_.beforeEnd();
    \n-
    656 }
    \n-
    657
    \n-\n-
    661 {
    \n-
    662 return data_.beforeBegin();
    \n-
    663 }
    \n-
    664
    \n-\n-
    667 {
    \n-
    668 data_ = t;
    \n-
    669 return *this;
    \n-
    670 }
    \n-
    671
    \n-\n-
    674#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    675 if (row<0)
    \n-
    676 DUNE_THROW(ISTLError, "Can't access negative rows!");
    \n-
    677 if (row>=N())
    \n-
    678 DUNE_THROW(ISTLError, "Row index out of range!");
    \n-
    679#endif
    \n-
    680 return data_[row];
    \n-
    681 }
    \n-
    682
    \n-
    684 const row_type operator[](size_type row) const {
    \n-
    685#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    686 if (row<0)
    \n-
    687 DUNE_THROW(ISTLError, "Can't access negative rows!");
    \n-
    688 if (row>=N())
    \n-
    689 DUNE_THROW(ISTLError, "Row index out of range!");
    \n-
    690#endif
    \n-
    691 return data_[row];
    \n-
    692 }
    \n-
    693
    \n-
    695 size_type N() const {
    \n-
    696 return data_.N();
    \n-
    697 }
    \n-
    698
    \n-
    700 size_type M() const {
    \n-
    701 return cols_;
    \n-
    702 }
    \n-
    703
    \n-\n-
    706 data_ *= scalar;
    \n-
    707 return (*this);
    \n-
    708 }
    \n-
    709
    \n-\n-
    712 data_ /= scalar;
    \n-
    713 return (*this);
    \n-
    714 }
    \n-
    715
    \n-\n-
    722#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    723 if(N()!=b.N() || M() != b.M())
    \n-
    724 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n-
    725#endif
    \n-
    726 data_ += b.data_;
    \n-
    727 return (*this);
    \n-
    728 }
    \n-
    729
    \n-\n-
    736#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    737 if(N()!=b.N() || M() != b.M())
    \n-
    738 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n-
    739#endif
    \n-
    740 data_ -= b.data_;
    \n-
    741 return (*this);
    \n-
    742 }
    \n-
    743
    \n-\n-
    746 Matrix out(M(), N());
    \n-
    747 for (size_type i=0; i<N(); i++)
    \n-
    748 for (size_type j=0; j<M(); j++)
    \n-
    749 out[j][i] = (*this)[i][j];
    \n-
    750
    \n-
    751 return out;
    \n-
    752 }
    \n-
    753
    \n-
    755 friend Matrix<T> operator*(const Matrix<T>& m1, const Matrix<T>& m2) {
    \n-
    756 Matrix<T> out(m1.N(), m2.M());
    \n-
    757 out = 0;
    \n-
    758
    \n-
    759 for (size_type i=0; i<out.N(); i++ ) {
    \n-
    760 for ( size_type j=0; j<out.M(); j++ )
    \n-
    761 for (size_type k=0; k<m1.M(); k++)
    \n-
    762 out[i][j] += m1[i][k]*m2[k][j];
    \n-
    763 }
    \n-
    764
    \n-
    765 return out;
    \n-
    766 }
    \n-
    767
    \n-
    769 template <class X, class Y>
    \n-
    770 friend Y operator*(const Matrix<T>& m, const X& vec) {
    \n-
    771#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    772 if (m.M()!=vec.size())
    \n-
    773 DUNE_THROW(ISTLError, "Vector size doesn't match the number of matrix columns!");
    \n-
    774#endif
    \n-
    775 Y out(m.N());
    \n-
    776 out = 0;
    \n-
    777
    \n-
    778 for (size_type i=0; i<out.size(); i++ ) {
    \n-
    779 for ( size_type j=0; j<vec.size(); j++ )
    \n-
    780 out[i] += m[i][j]*vec[j];
    \n-
    781 }
    \n-
    782
    \n-
    783 return out;
    \n-
    784 }
    \n-
    785
    \n-
    787 template <class X, class Y>
    \n-
    788 void mv(const X& x, Y& y) const
    \n-
    789 {
    \n-
    790#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    791 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    792 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    793#endif
    \n-
    794 for (size_type i=0; i<data_.N(); i++) {
    \n-
    795 y[i]=0;
    \n-
    796 for (size_type j=0; j<cols_; j++)
    \n-
    797 {
    \n-
    798 auto&& xj = Impl::asVector(x[j]);
    \n-
    799 auto&& yi = Impl::asVector(y[i]);
    \n-
    800 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
    \n-
    801 }
    \n-
    802 }
    \n-
    803 }
    \n-
    804
    \n-
    806 template<class X, class Y>
    \n-
    807 void mtv (const X& x, Y& y) const
    \n-
    808 {
    \n-
    809#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    810 if (x.N()!=N()) DUNE_THROW(ISTLError,"index out of range");
    \n-
    811 if (y.N()!=M()) DUNE_THROW(ISTLError,"index out of range");
    \n-
    812#endif
    \n-
    813 for(size_type i=0; i<y.N(); ++i)
    \n-
    814 y[i]=0;
    \n-
    815 umtv(x,y);
    \n-
    816 }
    \n-
    817
    \n-
    819 template <class X, class Y>
    \n-
    820 void umv(const X& x, Y& y) const
    \n-
    821 {
    \n-
    822#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    823 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    824 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    825#endif
    \n-
    826 for (size_type i=0; i<data_.N(); i++)
    \n-
    827 for (size_type j=0; j<cols_; j++)
    \n-
    828 {
    \n-
    829 auto&& xj = Impl::asVector(x[j]);
    \n-
    830 auto&& yi = Impl::asVector(y[i]);
    \n-
    831 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
    \n-
    832 }
    \n-
    833 }
    \n-
    834
    \n-
    836 template<class X, class Y>
    \n-
    837 void mmv (const X& x, Y& y) const
    \n-
    838 {
    \n-
    839#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    840 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    841 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    842#endif
    \n-
    843 for (size_type i=0; i<data_.N(); i++)
    \n-
    844 for (size_type j=0; j<cols_; j++)
    \n-
    845 {
    \n-
    846 auto&& xj = Impl::asVector(x[j]);
    \n-
    847 auto&& yi = Impl::asVector(y[i]);
    \n-
    848 Impl::asMatrix((*this)[i][j]).mmv(xj, yi);
    \n-
    849 }
    \n-
    850 }
    \n-
    851
    \n-
    853 template <class X, class Y>
    \n-
    854 void usmv(const field_type& alpha, const X& x, Y& y) const
    \n-
    855 {
    \n-
    856#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    857 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    858 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    859#endif
    \n-
    860 for (size_type i=0; i<data_.N(); i++)
    \n-
    861 for (size_type j=0; j<cols_; j++)
    \n-
    862 {
    \n-
    863 auto&& xj = Impl::asVector(x[j]);
    \n-
    864 auto&& yi = Impl::asVector(y[i]);
    \n-
    865 Impl::asMatrix((*this)[i][j]).usmv(alpha, xj, yi);
    \n-
    866 }
    \n-
    867 }
    \n-
    868
    \n-
    870 template<class X, class Y>
    \n-
    871 void umtv (const X& x, Y& y) const
    \n-
    872 {
    \n-
    873#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    874 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    875 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    876#endif
    \n-
    877 for (size_type i=0; i<data_.N(); i++)
    \n-
    878 for (size_type j=0; j<cols_; j++)
    \n-
    879 {
    \n-
    880 auto&& xi = Impl::asVector(x[i]);
    \n-
    881 auto&& yj = Impl::asVector(y[j]);
    \n-
    882 Impl::asMatrix((*this)[i][j]).umtv(xi, yj);
    \n-
    883 }
    \n-
    884 }
    \n-
    885
    \n-
    887 template<class X, class Y>
    \n-
    888 void mmtv (const X& x, Y& y) const
    \n-
    889 {
    \n-
    890#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    891 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    892 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    893#endif
    \n-
    894 for (size_type i=0; i<data_.N(); i++)
    \n-
    895 for (size_type j=0; j<cols_; j++)
    \n-
    896 {
    \n-
    897 auto&& xi = Impl::asVector(x[i]);
    \n-
    898 auto&& yj = Impl::asVector(y[j]);
    \n-
    899 Impl::asMatrix((*this)[i][j]).mmtv(xi, yj);
    \n-
    900 }
    \n-
    901 }
    \n-
    902
    \n-
    904 template<class X, class Y>
    \n-
    905 void usmtv (const field_type& alpha, const X& x, Y& y) const
    \n-
    906 {
    \n-
    907#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    908 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    909 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    910#endif
    \n-
    911 for (size_type i=0; i<data_.N(); i++)
    \n-
    912 for (size_type j=0; j<cols_; j++)
    \n-
    913 {
    \n-
    914 auto&& xi = Impl::asVector(x[i]);
    \n-
    915 auto&& yj = Impl::asVector(y[j]);
    \n-
    916 Impl::asMatrix((*this)[i][j]).usmtv(alpha, xi, yj);
    \n-
    917 }
    \n-
    918 }
    \n-
    919
    \n-
    921 template<class X, class Y>
    \n-
    922 void umhv (const X& x, Y& y) const
    \n-
    923 {
    \n-
    924#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    925 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    926 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    927#endif
    \n-
    928 for (size_type i=0; i<data_.N(); i++)
    \n-
    929 for (size_type j=0; j<cols_; j++)
    \n-
    930 {
    \n-
    931 auto&& xi = Impl::asVector(x[i]);
    \n-
    932 auto&& yj = Impl::asVector(y[j]);
    \n-
    933 Impl::asMatrix((*this)[i][j]).umhv(xi,yj);
    \n-
    934 }
    \n-
    935 }
    \n-
    936
    \n-
    938 template<class X, class Y>
    \n-
    939 void mmhv (const X& x, Y& y) const
    \n-
    940 {
    \n-
    941#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    942 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    943 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    944#endif
    \n-
    945 for (size_type i=0; i<data_.N(); i++)
    \n-
    946 for (size_type j=0; j<cols_; j++)
    \n-
    947 {
    \n-
    948 auto&& xi = Impl::asVector(x[i]);
    \n-
    949 auto&& yj = Impl::asVector(y[j]);
    \n-
    950 Impl::asMatrix((*this)[i][j]).mmhv(xi,yj);
    \n-
    951 }
    \n-
    952 }
    \n-
    953
    \n-
    955 template<class X, class Y>
    \n-
    956 void usmhv (const field_type& alpha, const X& x, Y& y) const
    \n-
    957 {
    \n-
    958#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    959 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    960 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n-
    961#endif
    \n-
    962 for (size_type i=0; i<data_.N(); i++)
    \n-
    963 for (size_type j=0; j<cols_; j++)
    \n-
    964 {
    \n-
    965 auto&& xi = Impl::asVector(x[i]);
    \n-
    966 auto&& yj = Impl::asVector(y[j]);
    \n-
    967 Impl::asMatrix((*this)[i][j]).usmhv(alpha,xi,yj);
    \n-
    968 }
    \n-
    969 }
    \n-
    970
    \n-
    971 //===== norms
    \n-
    972
    \n-
    974 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n-
    975 {
    \n-
    976 return std::sqrt(frobenius_norm2());
    \n-
    977 }
    \n-
    978
    \n-
    980 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n-
    981 {
    \n-
    982 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    983 for (size_type i=0; i<this->N(); i++)
    \n-
    984 for (size_type j=0; j<this->M(); j++)
    \n-
    985 sum += Impl::asMatrix(data_[i][j]).frobenius_norm2();
    \n-
    986 return sum;
    \n-
    987 }
    \n-
    988
    \n-
    990 template <typename ft = field_type,
    \n-
    991 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    992 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    993 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    994 using std::max;
    \n-
    995
    \n-
    996 real_type norm = 0;
    \n-
    997 for (auto const &x : *this) {
    \n-
    998 real_type sum = 0;
    \n-
    999 for (auto const &y : x)
    \n-
    1000 sum += Impl::asMatrix(y).infinity_norm();
    \n-
    1001 norm = max(sum, norm);
    \n-
    1002 isNaN += sum;
    \n-
    1003 }
    \n-
    1004
    \n-
    1005 return norm;
    \n-
    1006 }
    \n-
    1007
    \n-
    1009 template <typename ft = field_type,
    \n-
    1010 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    1011 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    1012 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1013 using std::max;
    \n-
    1014
    \n-
    1015 real_type norm = 0;
    \n-
    1016 for (auto const &x : *this) {
    \n-
    1017 real_type sum = 0;
    \n-
    1018 for (auto const &y : x)
    \n-
    1019 sum += Impl::asMatrix(y).infinity_norm_real();
    \n-
    1020 norm = max(sum, norm);
    \n-
    1021 }
    \n-
    1022 return norm;
    \n-
    1023 }
    \n-
    1024
    \n-
    1026 template <typename ft = field_type,
    \n-
    1027 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    1028 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    1029 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1030 using std::max;
    \n-
    1031
    \n-
    1032 real_type norm = 0;
    \n-
    1033 real_type isNaN = 1;
    \n-
    1034 for (auto const &x : *this) {
    \n-
    1035 real_type sum = 0;
    \n-
    1036 for (auto const &y : x)
    \n-
    1037 sum += Impl::asMatrix(y).infinity_norm();
    \n-
    1038 norm = max(sum, norm);
    \n-
    1039 isNaN += sum;
    \n-
    1040 }
    \n-
    1041
    \n-
    1042 return norm * (isNaN / isNaN);
    \n-
    1043 }
    \n-
    1044
    \n-
    1046 template <typename ft = field_type,
    \n-
    1047 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    1048 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    1049 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1050 using std::max;
    \n-
    1051
    \n-
    1052 real_type norm = 0;
    \n-
    1053 real_type isNaN = 1;
    \n-
    1054 for (auto const &x : *this) {
    \n-
    1055 real_type sum = 0;
    \n-
    1056 for (auto const &y : x)
    \n-
    1057 sum += Impl::asMatrix(y).infinity_norm_real();
    \n-
    1058 norm = max(sum, norm);
    \n-
    1059 isNaN += sum;
    \n-
    1060 }
    \n-
    1061
    \n-
    1062 return norm * (isNaN / isNaN);
    \n-
    1063 }
    \n-
    1064
    \n-
    1065 //===== query
    \n-
    1066
    \n-
    1068 bool exists ([[maybe_unused]] size_type i, [[maybe_unused]] size_type j) const
    \n-
    1069 {
    \n-
    1070#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1071 if (i<0 || i>=N()) DUNE_THROW(ISTLError,"row index out of range");
    \n-
    1072 if (j<0 || i>=M()) DUNE_THROW(ISTLError,"column index out of range");
    \n-
    1073#endif
    \n-
    1074 return true;
    \n-
    1075 }
    \n-
    1076
    \n-
    1077 protected:
    \n-
    1078
    \n-\n-
    1082
    \n-\n-
    1089 };
    \n-
    1090
    \n-
    1091 template<class T, class A>
    \n-
    1092 struct FieldTraits< Matrix<T, A> >
    \n-
    1093 {
    \n-\n-
    1095 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    1096 };
    \n-
    1097
    \n-
    1099} // end namespace Dune
    \n-
    1100
    \n-
    1101#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n+
    441 friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
    \n+
    442 {
    \n+
    443 for (size_type i=0; i<n; i++) {
    \n+
    444 for (size_type j=0; j<n; j++)
    \n+
    445 s << ((i==j) ? a.p_ : 0) << " ";
    \n+
    446 s << std::endl;
    \n+
    447 }
    \n+
    448 return s;
    \n+
    449 }
    \n+
    450
    \n+\n+
    453 {
    \n+
    454 return reference(const_cast<K*>(&p_), i);
    \n+
    455 }
    \n+
    456
    \n+\n+
    459 {
    \n+
    460 return const_reference(const_cast<K*>(&p_), i);
    \n+
    461 }
    \n+
    462
    \n+
    464 const K& diagonal(size_type /*i*/) const
    \n+
    465 {
    \n+
    466 return p_;
    \n+
    467 }
    \n+
    468
    \n+\n+
    471 {
    \n+
    472 return p_;
    \n+
    473 }
    \n+
    474
    \n+
    477 const K& scalar() const
    \n+
    478 {
    \n+
    479 return p_;
    \n+
    480 }
    \n+
    481
    \n+\n+
    485 {
    \n+
    486 return p_;
    \n+
    487 }
    \n+
    488
    \n+
    489 private:
    \n+
    490 // the data, very simply a single number
    \n+
    491 K p_;
    \n+
    492
    \n+
    493 };
    \n+
    494
    \n+
    495 template <class DenseMatrix, class field, int N>
    \n+
    496 struct DenseMatrixAssigner<DenseMatrix, ScaledIdentityMatrix<field, N>> {
    \n+
    497 static void apply(DenseMatrix& denseMatrix,
    \n+\n+
    499 assert(denseMatrix.M() == N);
    \n+
    500 assert(denseMatrix.N() == N);
    \n+
    501 denseMatrix = field(0);
    \n+
    502 for (int i = 0; i < N; ++i)
    \n+
    503 denseMatrix[i][i] = rhs.scalar();
    \n+
    504 }
    \n+
    505 };
    \n+
    506
    \n+
    507 template<class K, int n>
    \n+
    508 struct FieldTraits< ScaledIdentityMatrix<K, n> >
    \n+
    509 {
    \n+\n+
    511 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    512 };
    \n+
    513
    \n+
    514} // end namespace
    \n+
    515
    \n+
    516#endif
    \n
    Definition: allocator.hh:11
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    A Vector of blocks with different blocksizes.
    Definition: matrix.hh:44
    \n-
    Imp::BlockVectorWindow< B, A > window_type
    Definition: matrix.hh:70
    \n-
    BlockVector< B, A > block_type
    Same as value_type, here for historical reasons.
    Definition: matrix.hh:67
    \n-
    DenseMatrixBase & operator=(const DenseMatrixBase &a)
    assignment
    Definition: matrix.hh:182
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: matrix.hh:50
    \n-
    Iterator beforeBegin() const
    Definition: matrix.hh:385
    \n-
    void resize(size_type rows, size_type columns)
    same effect as constructor with same argument
    Definition: matrix.hh:153
    \n-
    const window_type const_reference
    Definition: matrix.hh:74
    \n-
    DenseMatrixBase(size_type rows, size_type columns)
    Definition: matrix.hh:95
    \n-
    Iterator end()
    end Iterator
    Definition: matrix.hh:371
    \n-
    reference operator[](size_type i)
    random access to blocks
    Definition: matrix.hh:241
    \n-
    BlockVector< B, A > value_type
    Type of the elements of the outer vector, i.e., dynamic vectors of B.
    Definition: matrix.hh:63
    \n-
    Iterator find(size_type i)
    random access returning iterator (end if not contained)
    Definition: matrix.hh:391
    \n-
    size_type N() const
    number of blocks in the vector (are of variable size here)
    Definition: matrix.hh:539
    \n-
    ConstIterator beforeEnd() const
    Definition: matrix.hh:525
    \n-
    ConstIterator end() const
    end ConstIterator
    Definition: matrix.hh:518
    \n-
    window_type reference
    Definition: matrix.hh:72
    \n-
    ConstIterator rend() const
    end ConstIterator
    Definition: matrix.hh:531
    \n-
    Iterator beforeEnd()
    Definition: matrix.hh:378
    \n-
    ConstIterator begin() const
    begin ConstIterator
    Definition: matrix.hh:512
    \n-
    A allocator_type
    export the allocator type
    Definition: matrix.hh:53
    \n-
    DenseMatrixBase()
    Definition: matrix.hh:82
    \n-
    ConstIterator find(size_type i) const
    random access returning iterator (end if not contained)
    Definition: matrix.hh:397
    \n-
    A::size_type size_type
    The size type for the index access.
    Definition: matrix.hh:56
    \n-
    ~DenseMatrixBase()
    free dynamic memory
    Definition: matrix.hh:142
    \n-
    Iterator begin()
    begin Iterator
    Definition: matrix.hh:365
    \n-
    DenseMatrixBase(const DenseMatrixBase &a)
    copy constructor, has copy semantics
    Definition: matrix.hh:116
    \n-
    Iterator class for sequential access.
    Definition: matrix.hh:263
    \n-
    Iterator & operator--()
    prefix decrement
    Definition: matrix.hh:308
    \n-
    size_type index() const
    Definition: matrix.hh:352
    \n-\n-\n-
    bool operator!=(const Iterator &it) const
    inequality
    Definition: matrix.hh:322
    \n-
    Iterator & operator=(Iterator &&other)
    Move assignment.
    Definition: matrix.hh:282
    \n-
    Iterator & operator++()
    prefix increment
    Definition: matrix.hh:300
    \n-
    Iterator()
    constructor, no arguments
    Definition: matrix.hh:266
    \n-
    window_type & operator*() const
    dereferencing
    Definition: matrix.hh:340
    \n-
    bool operator==(const Iterator &it) const
    equality
    Definition: matrix.hh:316
    \n-
    Iterator & operator=(Iterator &other)
    Copy assignment.
    Definition: matrix.hh:291
    \n-
    Iterator(B *data, size_type columns, size_type _i)
    constructor
    Definition: matrix.hh:276
    \n-
    window_type * operator->() const
    arrow
    Definition: matrix.hh:346
    \n-
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n-
    const window_type * operator->() const
    arrow
    Definition: matrix.hh:487
    \n-
    const window_type & operator*() const
    dereferencing
    Definition: matrix.hh:481
    \n-
    ConstIterator & operator++()
    prefix increment
    Definition: matrix.hh:441
    \n-
    ConstIterator(const B *data, size_type columns, size_type _i)
    constructor from pointer
    Definition: matrix.hh:414
    \n-
    ConstIterator & operator--()
    prefix decrement
    Definition: matrix.hh:449
    \n-
    ConstIterator(const Iterator &it)
    constructor from non_const iterator
    Definition: matrix.hh:420
    \n-
    bool operator!=(const ConstIterator &it) const
    inequality
    Definition: matrix.hh:463
    \n-
    ConstIterator()
    constructor
    Definition: matrix.hh:407
    \n-
    bool operator==(const ConstIterator &it) const
    equality
    Definition: matrix.hh:457
    \n-
    size_type index() const
    Definition: matrix.hh:493
    \n-
    ConstIterator & operator=(Iterator &&other)
    Definition: matrix.hh:424
    \n-
    ConstIterator & operator=(Iterator &other)
    Definition: matrix.hh:432
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    size_type cols_
    Number of columns of the matrix.
    Definition: matrix.hh:1088
    \n-
    FieldTraits< ft >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: matrix.hh:992
    \n-
    A allocator_type
    Export the allocator.
    Definition: matrix.hh:571
    \n-
    FieldTraits< ft >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: matrix.hh:1011
    \n-
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: matrix.hh:956
    \n-
    void usmv(const field_type &alpha, const X &x, Y &y) const
    Definition: matrix.hh:854
    \n-
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n-
    MatrixImp::DenseMatrixBase< T, A > data_
    Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.
    Definition: matrix.hh:1081
    \n-
    Matrix transpose() const
    Return the transpose of the matrix.
    Definition: matrix.hh:745
    \n-
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: matrix.hh:807
    \n-
    void umv(const X &x, Y &y) const
    y += A x
    Definition: matrix.hh:820
    \n-
    void mv(const X &x, Y &y) const
    y = A x
    Definition: matrix.hh:788
    \n-
    MatrixImp::DenseMatrixBase< T, A >::ConstIterator ConstRowIterator
    Const iterator over the matrix rows.
    Definition: matrix.hh:586
    \n-
    void setSize(size_type rows, size_type cols)
    Change the matrix size.
    Definition: matrix.hh:608
    \n-
    RowIterator beforeBegin()
    Definition: matrix.hh:634
    \n-
    RowIterator beforeEnd()
    Definition: matrix.hh:627
    \n-
    Matrix()
    Create empty matrix.
    Definition: matrix.hh:596
    \n-
    Matrix & operator-=(const Matrix &b)
    Subtract the entries of another matrix from this one.
    Definition: matrix.hh:735
    \n-
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: matrix.hh:980
    \n-
    row_type::iterator ColIterator
    Iterator for the entries of each row.
    Definition: matrix.hh:583
    \n-
    ConstRowIterator beforeEnd() const
    Definition: matrix.hh:653
    \n-
    Matrix & operator=(const field_type &t)
    Assignment from scalar.
    Definition: matrix.hh:666
    \n-
    RowIterator end()
    Get iterator to one beyond last row.
    Definition: matrix.hh:620
    \n-
    const row_type operator[](size_type row) const
    The const index operator.
    Definition: matrix.hh:684
    \n-
    ConstRowIterator end() const
    Get const iterator to one beyond last row.
    Definition: matrix.hh:646
    \n-
    friend Y operator*(const Matrix< T > &m, const X &vec)
    Generic matrix-vector multiplication.
    Definition: matrix.hh:770
    \n-
    Matrix< T > & operator*=(const field_type &scalar)
    Multiplication with a scalar.
    Definition: matrix.hh:705
    \n-
    row_type operator[](size_type row)
    The index operator.
    Definition: matrix.hh:673
    \n-
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: matrix.hh:837
    \n-
    Matrix & operator+=(const Matrix &b)
    Add the entries of another matrix to this one.
    Definition: matrix.hh:721
    \n-
    ConstRowIterator begin() const
    Get const iterator to first row.
    Definition: matrix.hh:640
    \n-
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: matrix.hh:939
    \n-
    RowIterator begin()
    Get iterator to first row.
    Definition: matrix.hh:614
    \n-
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n-
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n-
    static constexpr auto blocklevel
    The number of nesting levels the matrix contains.
    Definition: matrix.hh:593
    \n-
    size_type M() const
    Return the number of columns.
    Definition: matrix.hh:700
    \n-
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n-
    bool exists(size_type i, size_type j) const
    return true if (i,j) is in pattern
    Definition: matrix.hh:1068
    \n-
    Matrix< T > & operator/=(const field_type &scalar)
    Division by a scalar.
    Definition: matrix.hh:711
    \n-
    friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)
    Generic matrix multiplication.
    Definition: matrix.hh:755
    \n-
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: matrix.hh:871
    \n-
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: matrix.hh:888
    \n-
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n-
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: matrix.hh:974
    \n-
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: matrix.hh:905
    \n-
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: matrix.hh:922
    \n-
    size_type N() const
    Return the number of rows.
    Definition: matrix.hh:695
    \n-
    ConstRowIterator beforeBegin() const
    Definition: matrix.hh:660
    \n-
    Matrix(size_type rows, size_type cols)
    Create uninitialized matrix of size rows x cols.
    Definition: matrix.hh:601
    \n-
    MatrixImp::DenseMatrixBase< T, A >::Iterator RowIterator
    Iterator over the matrix rows.
    Definition: matrix.hh:580
    \n-
    typename Matrix< T, A >::field_type field_type
    Definition: matrix.hh:1094
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: matrix.hh:1095
    \n+
    A multiple of the identity matrix of static size.
    Definition: scaledidmatrix.hh:30
    \n+
    void usmhv(const K &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: scaledidmatrix.hh:353
    \n+
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: scaledidmatrix.hh:305
    \n+
    ScaledIdentityMatrix & operator-=(const ScaledIdentityMatrix &y)
    vector space subtraction
    Definition: scaledidmatrix.hh:169
    \n+
    const_row_type::ConstIterator ConstColIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:131
    \n+
    ConstIterator end() const
    end iterator
    Definition: scaledidmatrix.hh:140
    \n+
    Iterator beforeBegin()
    Definition: scaledidmatrix.hh:118
    \n+
    bool operator!=(const ScaledIdentityMatrix &other) const
    incomparison operator
    Definition: scaledidmatrix.hh:229
    \n+
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: scaledidmatrix.hh:293
    \n+
    std::size_t size_type
    The type used for the index access and size operations.
    Definition: scaledidmatrix.hh:43
    \n+
    void usmv(const K &alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: scaledidmatrix.hh:329
    \n+
    row_type::Iterator ColIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:95
    \n+
    const_row_type const_reference
    Definition: scaledidmatrix.hh:53
    \n+
    void mv(const X &x, Y &y) const
    y = A x
    Definition: scaledidmatrix.hh:238
    \n+
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: scaledidmatrix.hh:269
    \n+
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: scaledidmatrix.hh:281
    \n+
    DiagonalRowVector< K, n > row_type
    Each row is implemented by a field vector.
    Definition: scaledidmatrix.hh:50
    \n+
    ContainerWrapperIterator< const WrapperType, reference, reference > Iterator
    Iterator class for sequential access.
    Definition: scaledidmatrix.hh:89
    \n+
    Iterator beforeEnd()
    Definition: scaledidmatrix.hh:111
    \n+
    K determinant() const
    calculates the determinant of this matrix
    Definition: scaledidmatrix.hh:408
    \n+
    K field_type
    export the type representing the field
    Definition: scaledidmatrix.hh:37
    \n+
    void usmtv(const K &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: scaledidmatrix.hh:341
    \n+
    Iterator end()
    end iterator
    Definition: scaledidmatrix.hh:104
    \n+
    Iterator iterator
    typedef for stl compliant access
    Definition: scaledidmatrix.hh:91
    \n+
    const K & scalar() const
    Get const reference to the scalar diagonal value.
    Definition: scaledidmatrix.hh:477
    \n+
    void umv(const X &x, Y &y) const
    y += A x
    Definition: scaledidmatrix.hh:257
    \n+
    static constexpr std::size_t blocklevel
    We are at the leaf of the block recursion.
    Definition: scaledidmatrix.hh:47
    \n+
    const K & diagonal(size_type) const
    Get const reference to diagonal entry.
    Definition: scaledidmatrix.hh:464
    \n+
    @ rows
    The number of rows.
    Definition: scaledidmatrix.hh:58
    \n+
    @ cols
    The number of columns.
    Definition: scaledidmatrix.hh:60
    \n+
    ScaledIdentityMatrix & operator=(const K &k)
    Definition: scaledidmatrix.hh:75
    \n+
    ContainerWrapperIterator< const WrapperType, const_reference, const_reference > ConstIterator
    Iterator class for sequential access.
    Definition: scaledidmatrix.hh:125
    \n+
    K & diagonal(size_type)
    Get reference to diagonal entry.
    Definition: scaledidmatrix.hh:470
    \n+
    void solve(V &x, const V &b) const
    Solve system A x = b.
    Definition: scaledidmatrix.hh:394
    \n+
    bool exists(size_type i, size_type j) const
    return true when (i,j) is in pattern
    Definition: scaledidmatrix.hh:429
    \n+
    Iterator RowIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:93
    \n+
    ConstIterator const_iterator
    typedef for stl compliant access
    Definition: scaledidmatrix.hh:127
    \n+
    ScaledIdentityMatrix()
    Default constructor.
    Definition: scaledidmatrix.hh:66
    \n+
    bool operator==(const ScaledIdentityMatrix &other) const
    comparison operator
    Definition: scaledidmatrix.hh:223
    \n+
    ConstIterator beforeBegin() const
    Definition: scaledidmatrix.hh:154
    \n+
    ScaledIdentityMatrix & operator/=(const K &k)
    vector space division by scalar
    Definition: scaledidmatrix.hh:196
    \n+
    friend std::ostream & operator<<(std::ostream &s, const ScaledIdentityMatrix< K, n > &a)
    Sends the matrix to an output stream.
    Definition: scaledidmatrix.hh:441
    \n+
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: scaledidmatrix.hh:372
    \n+
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: scaledidmatrix.hh:366
    \n+
    FieldTraits< field_type >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: scaledidmatrix.hh:378
    \n+
    ConstIterator ConstRowIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:129
    \n+
    ConstIterator beforeEnd() const
    Definition: scaledidmatrix.hh:147
    \n+
    size_type M() const
    number of blocks in column direction
    Definition: scaledidmatrix.hh:421
    \n+
    const_reference operator[](size_type i) const
    Return const_reference object as row replacement.
    Definition: scaledidmatrix.hh:458
    \n+
    ScaledIdentityMatrix(const K &k)
    Constructor initializing the whole matrix with a scalar.
    Definition: scaledidmatrix.hh:70
    \n+
    friend auto operator*(const ScaledIdentityMatrix &matrix, Scalar scalar)
    vector space multiplication with scalar
    Definition: scaledidmatrix.hh:207
    \n+
    FieldTraits< field_type >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: scaledidmatrix.hh:384
    \n+
    ScaledIdentityMatrix & operator*=(const K &k)
    vector space multiplication with scalar
    Definition: scaledidmatrix.hh:189
    \n+
    bool identical(const ScaledIdentityMatrix< K, n > &other) const
    Definition: scaledidmatrix.hh:82
    \n+
    void invert()
    Compute inverse.
    Definition: scaledidmatrix.hh:402
    \n+
    Iterator begin()
    begin iterator
    Definition: scaledidmatrix.hh:98
    \n+
    K & scalar()
    Get reference to the scalar diagonal value.
    Definition: scaledidmatrix.hh:484
    \n+
    row_type reference
    Definition: scaledidmatrix.hh:51
    \n+
    K block_type
    export the type representing the components
    Definition: scaledidmatrix.hh:40
    \n+
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: scaledidmatrix.hh:317
    \n+
    ScaledIdentityMatrix & operator+=(const ScaledIdentityMatrix &y)
    vector space addition
    Definition: scaledidmatrix.hh:162
    \n+
    DiagonalRowVectorConst< K, n > const_row_type
    Definition: scaledidmatrix.hh:52
    \n+
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: scaledidmatrix.hh:250
    \n+
    reference operator[](size_type i)
    Return reference object as row replacement.
    Definition: scaledidmatrix.hh:452
    \n+
    ConstIterator begin() const
    begin iterator
    Definition: scaledidmatrix.hh:134
    \n+
    size_type N() const
    number of blocks in row direction
    Definition: scaledidmatrix.hh:415
    \n+
    static void apply(DenseMatrix &denseMatrix, ScaledIdentityMatrix< field, N > const &rhs)
    Definition: scaledidmatrix.hh:497
    \n+
    typename ScaledIdentityMatrix< K, n >::field_type field_type
    Definition: scaledidmatrix.hh:510
    \n+
    typename FieldTraits< field_type >::real_type real_type
    Definition: scaledidmatrix.hh:511
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1380 +4,721 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrix.hh\n+scaledidmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIX_HH\n- 6#define DUNE_ISTL_MATRIX_HH\n+ 5#ifndef DUNE_ISTL_SCALEDIDMATRIX_HH\n+ 6#define DUNE_ISTL_SCALEDIDMATRIX_HH\n 7\n- 12#include \n- 13#include \n- 14\n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19\n- 20#include \n- 21#include \n- 22#include \n- 23\n- 24namespace Dune {\n- 25\n-26namespace MatrixImp\n- 27{\n- 39 template >\n-40 class DenseMatrixBase : public Imp::block_vector_unmanaged\n- 41 // this derivation gives us all the blas level 1 and norms\n- 42 // on the large array. However, access operators have to be\n- 43 // overwritten.\n- 44 {\n- 45 public:\n- 46\n- 47 //===== type definitions and constants\n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22\n+ 23namespace Dune {\n+ 24\n+ 28 template\n+29 class ScaledIdentityMatrix\n+ 30 {\n+ 31 typedef DiagonalMatrixWrapper< ScaledIdentityMatrix > WrapperType;\n+ 32\n+ 33 public:\n+ 34 //===== type definitions and constants\n+ 35\n+37 typedef K field_type;\n+ 38\n+40 typedef K block_type;\n+ 41\n+43 typedef std::size_t size_type;\n+ 44\n+ 46 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+47 static constexpr std::size_t blocklevel = 1;\n 48\n-50 using field_type = typename Imp::BlockTraits::field_type;\n- 51\n-53 typedef A allocator_type;\n+50 typedef DiagonalRowVector row_type;\n+51 typedef row_type reference;\n+52 typedef DiagonalRowVectorConst const_row_type;\n+53 typedef const_row_type const_reference;\n 54\n-56 typedef typename A::size_type size_type;\n- 57\n-63 typedef BlockVector value_type;\n- 64\n-67 typedef BlockVector block_type;\n- 68\n- 69 // just a shorthand\n-70 typedef Imp::BlockVectorWindow window_type;\n- 71\n-72 typedef window_type reference;\n+ 56 enum {\n+58 rows = n,\n+ 60 cols = n\n+61 };\n+ 62\n+ 63 //===== constructors\n+66 ScaledIdentityMatrix () {}\n+ 67\n+70 ScaledIdentityMatrix (const K& k)\n+ 71 : p_(k)\n+ 72 {}\n 73\n-74 typedef const window_type const_reference;\n- 75\n- 76\n- 77 //===== constructors and such\n- 78\n-82 DenseMatrixBase () : Imp::block_vector_unmanaged()\n+ 74 //===== assignment from scalar\n+75 ScaledIdentityMatrix& operator=(const K& k)\n+ 76 {\n+ 77 p_ = k;\n+ 78 return *this;\n+ 79 }\n+ 80\n+ 81 // check if matrix is identical to other matrix (not only identical values)\n+82 bool identical(const ScaledIdentityMatrix& other) const\n 83 {\n- 84 // nothing is known ...\n- 85 rows_ = 0;\n- 86 columns_ = 0;\n- 87 }\n- 88\n-95 DenseMatrixBase (size_type rows, size_type columns) : Imp::\n-block_vector_unmanaged()\n- 96 {\n- 97 // and we can allocate the big array in the base class\n- 98 this->n = rows*columns;\n- 99 columns_ = columns;\n- 100 if (this->n>0)\n- 101 {\n- 102 this->p = allocator_.allocate(this->n);\n- 103 new (this->p)B[this->n];\n- 104 }\n- 105 else\n- 106 {\n- 107 this->n = 0;\n- 108 this->p = 0;\n- 109 }\n- 110\n- 111 // we can allocate the windows now\n- 112 rows_ = rows;\n- 113 }\n- 114\n-116 DenseMatrixBase (const DenseMatrixBase& a)\n- 117 {\n- 118 // allocate the big array in the base class\n- 119 this->n = a.n;\n- 120 columns_ = a.columns_;\n- 121 if (this->n>0)\n- 122 {\n- 123 // allocate and construct objects\n- 124 this->p = allocator_.allocate(this->n);\n- 125 new (this->p)B[this->n];\n- 126\n- 127 // copy data\n- 128 for (size_type i=0; in; i++)\n- 129 this->p[i]=a.p[i];\n- 130 }\n- 131 else\n- 132 {\n- 133 this->n = 0;\n- 134 this->p = nullptr;\n- 135 }\n- 136\n- 137 // we can allocate the windows now\n- 138 rows_ = a.rows_;\n- 139 }\n- 140\n-142 ~DenseMatrixBase ()\n- 143 {\n- 144 if (this->n>0) {\n- 145 size_type i=this->n;\n- 146 while (i)\n- 147 this->p[--i].~B();\n- 148 allocator_.deallocate(this->p,this->n);\n- 149 }\n+ 84 return (this==&other);\n+ 85 }\n+ 86\n+ 87 //===== iterator interface to rows of the matrix\n+89 typedef ContainerWrapperIterator\n+Iterator;\n+91 typedef Iterator iterator;\n+93 typedef Iterator RowIterator;\n+95 typedef typename row_type::Iterator ColIterator;\n+ 96\n+98 Iterator begin ()\n+ 99 {\n+ 100 return Iterator(WrapperType(this),0);\n+ 101 }\n+ 102\n+104 Iterator end ()\n+ 105 {\n+ 106 return Iterator(WrapperType(this),n);\n+ 107 }\n+ 108\n+111 Iterator beforeEnd ()\n+ 112 {\n+ 113 return Iterator(WrapperType(this),n-1);\n+ 114 }\n+ 115\n+118 Iterator beforeBegin ()\n+ 119 {\n+ 120 return Iterator(WrapperType(this),-1);\n+ 121 }\n+ 122\n+ 123\n+125 typedef ContainerWrapperIterator ConstIterator;\n+127 typedef ConstIterator const_iterator;\n+129 typedef ConstIterator ConstRowIterator;\n+131 typedef typename const_row_type::ConstIterator ConstColIterator;\n+ 132\n+134 ConstIterator begin () const\n+ 135 {\n+ 136 return ConstIterator(WrapperType(this),0);\n+ 137 }\n+ 138\n+140 ConstIterator end () const\n+ 141 {\n+ 142 return ConstIterator(WrapperType(this),n);\n+ 143 }\n+ 144\n+147 ConstIterator beforeEnd() const\n+ 148 {\n+ 149 return ConstIterator(WrapperType(this),n-1);\n 150 }\n 151\n-153 void resize (size_type rows, size_type columns)\n- 154 {\n- 155 // deconstruct objects and deallocate memory if necessary\n- 156 if (this->n>0) {\n- 157 size_type i=this->n;\n- 158 while (i)\n- 159 this->p[--i].~B();\n- 160 allocator_.deallocate(this->p,this->n);\n- 161 }\n- 162\n- 163 // and we can allocate the big array in the base class\n- 164 this->n = rows*columns;\n- 165 if (this->n>0)\n- 166 {\n- 167 this->p = allocator_.allocate(this->n);\n- 168 new (this->p)B[this->n];\n- 169 }\n- 170 else\n- 171 {\n- 172 this->n = 0;\n- 173 this->p = nullptr;\n- 174 }\n- 175\n- 176 // we can allocate the windows now\n- 177 rows_ = rows;\n- 178 columns_ = columns;\n- 179 }\n- 180\n-182 DenseMatrixBase& operator=(const DenseMatrixBase& a)\n- 183 {\n- 184 if (&a!=this) // check if this and a are different objects\n- 185 {\n- 186 columns_ = a.columns_;\n- 187 // reallocate arrays if necessary\n- 188 // Note: still the block sizes may vary !\n- 189 if (this->n!=a.n || rows_!=a.rows_)\n+154 ConstIterator beforeBegin () const\n+ 155 {\n+ 156 return ConstIterator(WrapperType(this),-1);\n+ 157 }\n+ 158\n+ 159 //===== vector space arithmetic\n+ 160\n+162 ScaledIdentityMatrix& operator+=(const ScaledIdentityMatrix& y)\n+ 163 {\n+ 164 p_ += y.p_;\n+ 165 return *this;\n+ 166 }\n+ 167\n+169 ScaledIdentityMatrix& operator-=(const ScaledIdentityMatrix& y)\n+ 170 {\n+ 171 p_ -= y.p_;\n+ 172 return *this;\n+ 173 }\n+ 174\n+176 ScaledIdentityMatrix& operator+=(const K& k)\n+ 177 {\n+ 178 p_ += k;\n+ 179 return *this;\n+ 180 }\n+ 181\n+183 ScaledIdentityMatrix& operator-=(const K& k)\n+ 184 {\n+ 185 p_ -= k;\n+ 186 return *this;\n+ 187 }\n+189 ScaledIdentityMatrix& operator*=(const K& k)\n 190 {\n- 191 // deconstruct objects and deallocate memory if necessary\n- 192 if (this->n>0) {\n- 193 size_type i=this->n;\n- 194 while (i)\n- 195 this->p[--i].~B();\n- 196 allocator_.deallocate(this->p,this->n);\n- 197 }\n- 198\n- 199 // allocate the big array in the base class\n- 200 this->n = a.n;\n- 201 if (this->n>0)\n- 202 {\n- 203 // allocate and construct objects\n- 204 this->p = allocator_.allocate(this->n);\n- 205 new (this->p)B[this->n];\n- 206 }\n- 207 else\n+ 191 p_ *= k;\n+ 192 return *this;\n+ 193 }\n+ 194\n+196 ScaledIdentityMatrix& operator/=(const K& k)\n+ 197 {\n+ 198 p_ /= k;\n+ 199 return *this;\n+ 200 }\n+ 201\n+ 202 //===== binary operators\n+ 203\n+ 205 template ::value, int> = 0>\n+207 friend auto operator*( const ScaledIdentityMatrix& matrix, Scalar scalar)\n 208 {\n- 209 this->n = 0;\n- 210 this->p = nullptr;\n- 211 }\n- 212\n- 213 // Copy number of rows\n- 214 rows_ = a.rows_;\n- 215 }\n- 216\n- 217 // and copy the data\n- 218 for (size_type i=0; in; i++)\n- 219 this->p[i]=a.p[i];\n- 220 }\n+ 209 return ScaledIdentityMatrix::\n+PromotedType, n>{matrix.scalar()*scalar};\n+ 210 }\n+ 211\n+ 213 template ::value, int> = 0>\n+215 friend auto operator*(Scalar scalar, const ScaledIdentityMatrix& matrix)\n+ 216 {\n+ 217 return ScaledIdentityMatrix::\n+PromotedType, n>{scalar*matrix.scalar()};\n+ 218 }\n+ 219\n+ 220 //===== comparison ops\n 221\n- 222 return *this;\n- 223 }\n- 224\n- 225\n- 226 //===== assignment from scalar\n+223 bool operator==(const ScaledIdentityMatrix& other) const\n+ 224 {\n+ 225 return p_==other.scalar();\n+ 226 }\n 227\n-229 DenseMatrixBase& operator=(const field_type& k)\n+229 bool operator!=(const ScaledIdentityMatrix& other) const\n 230 {\n- 231 (static_cast&>(*this)) = k;\n- 232 return *this;\n- 233 }\n- 234\n+ 231 return p_!=other.scalar();\n+ 232 }\n+ 233\n+ 234 //===== linear maps\n 235\n- 236 //===== access to components\n- 237 // has to be overwritten from base class because it must\n- 238 // return access to the windows\n- 239\n-241 reference operator[](size_type i)\n- 242 {\n- 243#ifdef DUNE_ISTL_WITH_CHECKING\n- 244 if (i>=rows_) DUNE_THROW(ISTLError,\"index out of range\");\n- 245#endif\n- 246 return window_type(this->p + i*columns_, columns_);\n- 247 }\n- 248\n-250 const_reference operator[](size_type i) const\n+ 237 template\n+238 void mv (const X& x, Y& y) const\n+ 239 {\n+ 240#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 241 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 242 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 243#endif\n+ 244 for (size_type i=0; i\n+250 void mtv (const X& x, Y& y) const\n 251 {\n- 252#ifdef DUNE_ISTL_WITH_CHECKING\n- 253 if (i<0 || i>=rows_) DUNE_THROW(ISTLError,\"index out of range\");\n- 254#endif\n- 255 return window_type(this->p + i*columns_, columns_);\n- 256 }\n- 257\n- 258 // forward declaration\n- 259 class ConstIterator;\n- 260\n-262 class Iterator\n- 263 {\n- 264 public:\n-266 Iterator ()\n- 267 : window_(nullptr,0)\n- 268 {\n- 269 i = 0;\n- 270 }\n- 271\n-272 Iterator (Iterator& other) = default;\n-273 Iterator (Iterator&& other) = default;\n- 274\n-276 Iterator (B* data, size_type columns, size_type _i)\n- 277 : i(_i),\n- 278 window_(data + _i*columns, columns)\n- 279 {}\n- 280\n-282 Iterator& operator=(Iterator&& other)\n- 283 {\n- 284 i = other.i;\n- 285 // Do NOT use window_.operator=, because that copies the window content,\n-not just the window!\n- 286 window_.set(other.window_.getsize(),other.window_.getptr());\n- 287 return *this;\n- 288 }\n- 289\n-291 Iterator& operator=(Iterator& other)\n- 292 {\n- 293 i = other.i;\n- 294 // Do NOT use window_.operator=, because that copies the window content,\n-not just the window!\n- 295 window_.set(other.window_.getsize(),other.window_.getptr());\n- 296 return *this;\n- 297 }\n- 298\n-300 Iterator& operator++()\n- 301 {\n- 302 ++i;\n- 303 window_.setptr(window_.getptr()+window_.getsize());\n- 304 return *this;\n- 305 }\n- 306\n-308 Iterator& operator--()\n- 309 {\n- 310 --i;\n- 311 window_.setptr(window_.getptr()-window_.getsize());\n- 312 return *this;\n+ 252 mv(x, y);\n+ 253 }\n+ 254\n+ 256 template\n+257 void umv (const X& x, Y& y) const\n+ 258 {\n+ 259#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 260 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 261 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 262#endif\n+ 263 for (size_type i=0; i\n+269 void umtv (const X& x, Y& y) const\n+ 270 {\n+ 271#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 272 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 273 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 274#endif\n+ 275 for (size_type i=0; i\n+281 void umhv (const X& x, Y& y) const\n+ 282 {\n+ 283#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 284 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 285 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 286#endif\n+ 287 for (size_type i=0; i\n+293 void mmv (const X& x, Y& y) const\n+ 294 {\n+ 295#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 296 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 297 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 298#endif\n+ 299 for (size_type i=0; i\n+305 void mmtv (const X& x, Y& y) const\n+ 306 {\n+ 307#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 308 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 309 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 310#endif\n+ 311 for (size_type i=0; i\n+317 void mmhv (const X& x, Y& y) const\n+ 318 {\n+ 319#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 320 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 321 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 322#endif\n+ 323 for (size_type i=0; i\n+329 void usmv (const K& alpha, const X& x, Y& y) const\n+ 330 {\n+ 331#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 332 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 333 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 334#endif\n+ 335 for (size_type i=0; i() const\n- 347 {\n- 348 return &window_;\n+ 340 template\n+341 void usmtv (const K& alpha, const X& x, Y& y) const\n+ 342 {\n+ 343#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 344 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 345 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 346#endif\n+ 347 for (size_type i=0; ip, columns_, 0);\n- 368 }\n- 369\n-371 Iterator end ()\n- 372 {\n- 373 return Iterator(this->p, columns_, rows_);\n- 374 }\n- 375\n-378 Iterator beforeEnd ()\n+ 352 template\n+353 void usmhv (const K& alpha, const X& x, Y& y) const\n+ 354 {\n+ 355#ifdef DUNE_FMatrix_WITH_CHECKING\n+ 356 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 357 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n+ 358#endif\n+ 359 for (size_type i=0; i::real_type frobenius_norm () const\n+ 367 {\n+ 368 return fvmeta::sqrt(n*p_*p_);\n+ 369 }\n+ 370\n+372 typename FieldTraits::real_type frobenius_norm2 () const\n+ 373 {\n+ 374 return n*p_*p_;\n+ 375 }\n+ 376\n+378 typename FieldTraits::real_type infinity_norm () const\n 379 {\n- 380 return Iterator(this->p, columns_, rows_-1);\n+ 380 return std::abs(p_);\n 381 }\n 382\n-385 Iterator beforeBegin () const\n- 386 {\n- 387 return Iterator(this->p, columns_, -1);\n- 388 }\n- 389\n-391 Iterator find (size_type i)\n- 392 {\n- 393 return Iterator(this->p, columns_, std::min(i,rows_));\n- 394 }\n- 395\n-397 ConstIterator find (size_type i) const\n- 398 {\n- 399 return ConstIterator(this->p, columns_, std::min(i,rows_));\n- 400 }\n- 401\n-403 class ConstIterator\n- 404 {\n- 405 public:\n-407 ConstIterator ()\n- 408 : window_(nullptr,0)\n- 409 {\n- 410 i = 0;\n- 411 }\n- 412\n-414 ConstIterator (const B* data, size_type columns, size_type _i)\n- 415 : i(_i),\n- 416 window_(const_cast(data + _i * columns), columns)\n- 417 {}\n- 418\n-420 ConstIterator (const Iterator& it)\n- 421 : i(it.i), window_(it.window_.getptr(),it.window_.getsize())\n- 422 {}\n- 423\n-424 ConstIterator& operator=(Iterator&& other)\n- 425 {\n- 426 i = other.i;\n- 427 // Do NOT use window_.operator=, because that copies the window content,\n-not just the window!\n- 428 window_.set(other.window_.getsize(),other.window_.getptr());\n- 429 return *this;\n- 430 }\n- 431\n-432 ConstIterator& operator=(Iterator& other)\n- 433 {\n- 434 i = other.i;\n- 435 // Do NOT use window_.operator=, because that copies the window content,\n-not just the window!\n- 436 window_.set(other.window_.getsize(),other.window_.getptr());\n- 437 return *this;\n- 438 }\n+384 typename FieldTraits::real_type infinity_norm_real () const\n+ 385 {\n+ 386 return fvmeta::absreal(p_);\n+ 387 }\n+ 388\n+ 389 //===== solve\n+ 390\n+ 393 template\n+394 void solve (V& x, const V& b) const\n+ 395 {\n+ 396 for (int i=0; i=n) DUNE_THROW(FMatrixError,\"row index out of range\");\n+ 433 if (j<0 || j>=n) DUNE_THROW(FMatrixError,\"column index out of range\");\n+ 434#endif\n+ 435 return i==j;\n+ 436 }\n+ 437\n+ 438 //===== conversion operator\n 439\n-441 ConstIterator& operator++()\n+441 friend std::ostream& operator<<(std::ostream& s, const\n+ScaledIdentityMatrix& a)\n 442 {\n- 443 ++i;\n- 444 window_.setptr(window_.getptr()+window_.getsize());\n- 445 return *this;\n- 446 }\n- 447\n-449 ConstIterator& operator--()\n- 450 {\n- 451 --i;\n- 452 window_.setptr(window_.getptr()-window_.getsize());\n- 453 return *this;\n- 454 }\n- 455\n-457 bool operator==(const ConstIterator& it) const\n- 458 {\n- 459 return window_.getptr() == it.window_.getptr();\n- 460 }\n- 461\n-463 bool operator!=(const ConstIterator& it) const\n- 464 {\n- 465 return window_.getptr() != it.window_.getptr();\n- 466 }\n- 467\n-469 bool operator==(const Iterator& it) const\n- 470 {\n- 471 return window_.getptr() == it.window_.getptr();\n- 472 }\n- 473\n-475 bool operator!=(const Iterator& it) const\n- 476 {\n- 477 return window_.getptr() != it.window_.getptr();\n- 478 }\n- 479\n-481 const window_type& operator*() const\n- 482 {\n- 483 return window_;\n- 484 }\n- 485\n-487 const window_type* operator->() const\n- 488 {\n- 489 return &window_;\n- 490 }\n- 491\n- 492 // return index corresponding to pointer\n-493 size_type index () const\n- 494 {\n- 495 return i;\n- 496 }\n- 497\n-498 friend class Iterator;\n- 499\n- 500 private:\n- 501 size_type i;\n- 502 mutable window_type window_;\n- 503 };\n- 504\n-506 using iterator = Iterator;\n- 507\n-509 using const_iterator = ConstIterator;\n- 510\n-512 ConstIterator begin () const\n- 513 {\n- 514 return ConstIterator(this->p, columns_, 0);\n- 515 }\n- 516\n-518 ConstIterator end () const\n- 519 {\n- 520 return ConstIterator(this->p, columns_, rows_);\n- 521 }\n- 522\n-525 ConstIterator beforeEnd() const\n- 526 {\n- 527 return ConstIterator(this->p, columns_, rows_-1);\n- 528 }\n- 529\n-531 ConstIterator rend () const\n- 532 {\n- 533 return ConstIterator(this->p, columns_, -1);\n- 534 }\n- 535\n- 536 //===== sizes\n- 537\n-539 size_type N () const\n- 540 {\n- 541 return rows_;\n- 542 }\n- 543\n- 544\n- 545 private:\n- 546 size_type rows_; // number of matrix rows\n- 547 size_type columns_; // number of matrix columns\n- 548\n- 549 A allocator_;\n- 550 };\n- 551\n- 552} // namespace MatrixImp\n- 553\n- 559 template >\n-560 class Matrix\n- 561 {\n- 562 public:\n- 563\n-565 using field_type = typename Imp::BlockTraits::field_type;\n- 566\n-568 typedef T block_type;\n- 569\n-571 typedef A allocator_type;\n- 572\n-574 typedef typename MatrixImp::DenseMatrixBase::window_type row_type;\n- 575\n-577 typedef typename A::size_type size_type;\n- 578\n-580 typedef typename MatrixImp::DenseMatrixBase::Iterator RowIterator;\n- 581\n-583 typedef typename row_type::iterator ColIterator;\n- 584\n-586 typedef typename MatrixImp::DenseMatrixBase::ConstIterator\n-ConstRowIterator;\n- 587\n-589 typedef typename row_type::const_iterator ConstColIterator;\n- 590\n- 592 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-593 static constexpr auto blocklevel = blockLevel()+1;\n- 594\n-596 Matrix() : data_(0,0), cols_(0)\n- 597 {}\n- 598\n-601 Matrix(size_type rows, size_type cols) : data_(rows,cols), cols_(cols)\n- 602 {}\n- 603\n-608 void setSize(size_type rows, size_type cols) {\n- 609 data_.resize(rows,cols);\n- 610 cols_ = cols;\n- 611 }\n- 612\n-614 RowIterator begin()\n- 615 {\n- 616 return data_.begin();\n- 617 }\n- 618\n-620 RowIterator end()\n- 621 {\n- 622 return data_.end();\n- 623 }\n- 624\n-627 RowIterator beforeEnd ()\n- 628 {\n- 629 return data_.beforeEnd();\n- 630 }\n- 631\n-634 RowIterator beforeBegin ()\n- 635 {\n- 636 return data_.beforeBegin();\n- 637 }\n- 638\n-640 ConstRowIterator begin() const\n- 641 {\n- 642 return data_.begin();\n- 643 }\n- 644\n-646 ConstRowIterator end() const\n- 647 {\n- 648 return data_.end();\n- 649 }\n- 650\n-653 ConstRowIterator beforeEnd() const\n- 654 {\n- 655 return data_.beforeEnd();\n- 656 }\n- 657\n-660 ConstRowIterator beforeBegin () const\n- 661 {\n- 662 return data_.beforeBegin();\n- 663 }\n- 664\n-666 Matrix& operator=(const field_type& t)\n- 667 {\n- 668 data_ = t;\n- 669 return *this;\n- 670 }\n- 671\n-673 row_type operator[](size_type row) {\n- 674#ifdef DUNE_ISTL_WITH_CHECKING\n- 675 if (row<0)\n- 676 DUNE_THROW(ISTLError, \"Can't access negative rows!\");\n- 677 if (row>=N())\n- 678 DUNE_THROW(ISTLError, \"Row index out of range!\");\n- 679#endif\n- 680 return data_[row];\n- 681 }\n- 682\n-684 const row_type operator[](size_type row) const {\n- 685#ifdef DUNE_ISTL_WITH_CHECKING\n- 686 if (row<0)\n- 687 DUNE_THROW(ISTLError, \"Can't access negative rows!\");\n- 688 if (row>=N())\n- 689 DUNE_THROW(ISTLError, \"Row index out of range!\");\n- 690#endif\n- 691 return data_[row];\n- 692 }\n- 693\n-695 size_type N() const {\n- 696 return data_.N();\n- 697 }\n- 698\n-700 size_type M() const {\n- 701 return cols_;\n- 702 }\n- 703\n-705 Matrix& operator*=(const field_type& scalar) {\n- 706 data_ *= scalar;\n- 707 return (*this);\n- 708 }\n- 709\n-711 Matrix& operator/=(const field_type& scalar) {\n- 712 data_ /= scalar;\n- 713 return (*this);\n- 714 }\n- 715\n-721 Matrix& operator+=(const Matrix& b) {\n- 722#ifdef DUNE_ISTL_WITH_CHECKING\n- 723 if(N()!=b.N() || M() != b.M())\n- 724 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n- 725#endif\n- 726 data_ += b.data_;\n- 727 return (*this);\n- 728 }\n- 729\n-735 Matrix& operator-=(const Matrix& b) {\n- 736#ifdef DUNE_ISTL_WITH_CHECKING\n- 737 if(N()!=b.N() || M() != b.M())\n- 738 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n- 739#endif\n- 740 data_ -= b.data_;\n- 741 return (*this);\n- 742 }\n- 743\n-745 Matrix transpose() const {\n- 746 Matrix out(M(), N());\n- 747 for (size_type i=0; i operator*(const Matrix& m1, const Matrix& m2) {\n- 756 Matrix out(m1.N(), m2.M());\n- 757 out = 0;\n- 758\n- 759 for (size_type i=0; i\n-770 friend Y operator*(const Matrix& m, const X& vec) {\n- 771#ifdef DUNE_ISTL_WITH_CHECKING\n- 772 if (m.M()!=vec.size())\n- 773 DUNE_THROW(ISTLError, \"Vector size doesn't match the number of matrix\n-columns!\");\n- 774#endif\n- 775 Y out(m.N());\n- 776 out = 0;\n- 777\n- 778 for (size_type i=0; i\n-788 void mv(const X& x, Y& y) const\n- 789 {\n- 790#ifdef DUNE_ISTL_WITH_CHECKING\n- 791 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 792 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 793#endif\n- 794 for (size_type i=0; i\n-807 void mtv (const X& x, Y& y) const\n- 808 {\n- 809#ifdef DUNE_ISTL_WITH_CHECKING\n- 810 if (x.N()!=N()) DUNE_THROW(ISTLError,\"index out of range\");\n- 811 if (y.N()!=M()) DUNE_THROW(ISTLError,\"index out of range\");\n- 812#endif\n- 813 for(size_type i=0; i\n-820 void umv(const X& x, Y& y) const\n- 821 {\n- 822#ifdef DUNE_ISTL_WITH_CHECKING\n- 823 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 824 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 825#endif\n- 826 for (size_type i=0; i\n-837 void mmv (const X& x, Y& y) const\n- 838 {\n- 839#ifdef DUNE_ISTL_WITH_CHECKING\n- 840 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 841 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 842#endif\n- 843 for (size_type i=0; i\n-854 void usmv(const field_type& alpha, const X& x, Y& y) const\n- 855 {\n- 856#ifdef DUNE_ISTL_WITH_CHECKING\n- 857 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 858 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 859#endif\n- 860 for (size_type i=0; i\n-871 void umtv (const X& x, Y& y) const\n- 872 {\n- 873#ifdef DUNE_ISTL_WITH_CHECKING\n- 874 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 875 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 876#endif\n- 877 for (size_type i=0; i\n-888 void mmtv (const X& x, Y& y) const\n- 889 {\n- 890#ifdef DUNE_ISTL_WITH_CHECKING\n- 891 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 892 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 893#endif\n- 894 for (size_type i=0; i\n-905 void usmtv (const field_type& alpha, const X& x, Y& y) const\n- 906 {\n- 907#ifdef DUNE_ISTL_WITH_CHECKING\n- 908 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 909 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 910#endif\n- 911 for (size_type i=0; i\n-922 void umhv (const X& x, Y& y) const\n- 923 {\n- 924#ifdef DUNE_ISTL_WITH_CHECKING\n- 925 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 926 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 927#endif\n- 928 for (size_type i=0; i\n-939 void mmhv (const X& x, Y& y) const\n- 940 {\n- 941#ifdef DUNE_ISTL_WITH_CHECKING\n- 942 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 943 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 944#endif\n- 945 for (size_type i=0; i\n-956 void usmhv (const field_type& alpha, const X& x, Y& y) const\n- 957 {\n- 958#ifdef DUNE_ISTL_WITH_CHECKING\n- 959 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 960 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n- 961#endif\n- 962 for (size_type i=0; i::real_type frobenius_norm () const\n- 975 {\n- 976 return std::sqrt(frobenius_norm2());\n- 977 }\n- 978\n-980 typename FieldTraits::real_type frobenius_norm2 () const\n- 981 {\n- 982 typename FieldTraits::real_type sum=0;\n- 983 for (size_type i=0; iN(); i++)\n- 984 for (size_type j=0; jM(); j++)\n- 985 sum += Impl::asMatrix(data_[i][j]).frobenius_norm2();\n- 986 return sum;\n- 987 }\n- 988\n- 990 template ::value, int>::type = 0>\n-992 typename FieldTraits::real_type infinity_norm() const {\n- 993 using real_type = typename FieldTraits::real_type;\n- 994 using std::max;\n- 995\n- 996 real_type norm = 0;\n- 997 for (auto const &x : *this) {\n- 998 real_type sum = 0;\n- 999 for (auto const &y : x)\n- 1000 sum += Impl::asMatrix(y).infinity_norm();\n- 1001 norm = max(sum, norm);\n- 1002 isNaN += sum;\n- 1003 }\n- 1004\n- 1005 return norm;\n- 1006 }\n- 1007\n- 1009 template ::value, int>::type = 0>\n-1011 typename FieldTraits::real_type infinity_norm_real() const {\n- 1012 using real_type = typename FieldTraits::real_type;\n- 1013 using std::max;\n- 1014\n- 1015 real_type norm = 0;\n- 1016 for (auto const &x : *this) {\n- 1017 real_type sum = 0;\n- 1018 for (auto const &y : x)\n- 1019 sum += Impl::asMatrix(y).infinity_norm_real();\n- 1020 norm = max(sum, norm);\n- 1021 }\n- 1022 return norm;\n- 1023 }\n- 1024\n- 1026 template ::value, int>::type = 0>\n-1028 typename FieldTraits::real_type infinity_norm() const {\n- 1029 using real_type = typename FieldTraits::real_type;\n- 1030 using std::max;\n- 1031\n- 1032 real_type norm = 0;\n- 1033 real_type isNaN = 1;\n- 1034 for (auto const &x : *this) {\n- 1035 real_type sum = 0;\n- 1036 for (auto const &y : x)\n- 1037 sum += Impl::asMatrix(y).infinity_norm();\n- 1038 norm = max(sum, norm);\n- 1039 isNaN += sum;\n- 1040 }\n- 1041\n- 1042 return norm * (isNaN / isNaN);\n- 1043 }\n- 1044\n- 1046 template ::value, int>::type = 0>\n-1048 typename FieldTraits::real_type infinity_norm_real() const {\n- 1049 using real_type = typename FieldTraits::real_type;\n- 1050 using std::max;\n- 1051\n- 1052 real_type norm = 0;\n- 1053 real_type isNaN = 1;\n- 1054 for (auto const &x : *this) {\n- 1055 real_type sum = 0;\n- 1056 for (auto const &y : x)\n- 1057 sum += Impl::asMatrix(y).infinity_norm_real();\n- 1058 norm = max(sum, norm);\n- 1059 isNaN += sum;\n- 1060 }\n- 1061\n- 1062 return norm * (isNaN / isNaN);\n- 1063 }\n- 1064\n- 1065 //===== query\n- 1066\n-1068 bool exists ([[maybe_unused]] size_type i, [[maybe_unused]] size_type j)\n-const\n- 1069 {\n- 1070#ifdef DUNE_ISTL_WITH_CHECKING\n- 1071 if (i<0 || i>=N()) DUNE_THROW(ISTLError,\"row index out of range\");\n- 1072 if (j<0 || i>=M()) DUNE_THROW(ISTLError,\"column index out of range\");\n- 1073#endif\n- 1074 return true;\n- 1075 }\n- 1076\n- 1077 protected:\n- 1078\n-1081 MatrixImp::DenseMatrixBase data_;\n- 1082\n-1088 size_type cols_;\n- 1089 };\n- 1090\n- 1091 template\n-1092 struct FieldTraits< Matrix >\n- 1093 {\n-1094 using field_type = typename Matrix::field_type;\n-1095 using real_type = typename FieldTraits::real_type;\n- 1096 };\n- 1097\n- 1099} // end namespace Dune\n- 1100\n- 1101#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-istlexception.hh\n+ 443 for (size_type i=0; i(&p_), i);\n+ 455 }\n+ 456\n+458 const_reference operator[](size_type i) const\n+ 459 {\n+ 460 return const_reference(const_cast(&p_), i);\n+ 461 }\n+ 462\n+464 const K& diagonal(size_type /*i*/) const\n+ 465 {\n+ 466 return p_;\n+ 467 }\n+ 468\n+470 K& diagonal(size_type /*i*/)\n+ 471 {\n+ 472 return p_;\n+ 473 }\n+ 474\n+477 const K& scalar() const\n+ 478 {\n+ 479 return p_;\n+ 480 }\n+ 481\n+484 K& scalar()\n+ 485 {\n+ 486 return p_;\n+ 487 }\n+ 488\n+ 489 private:\n+ 490 // the data, very simply a single number\n+ 491 K p_;\n+ 492\n+ 493 };\n+ 494\n+ 495 template \n+496 struct DenseMatrixAssigner> {\n+497 static void apply(DenseMatrix& denseMatrix,\n+ 498 ScaledIdentityMatrix const& rhs) {\n+ 499 assert(denseMatrix.M() == N);\n+ 500 assert(denseMatrix.N() == N);\n+ 501 denseMatrix = field(0);\n+ 502 for (int i = 0; i < N; ++i)\n+ 503 denseMatrix[i][i] = rhs.scalar();\n+ 504 }\n+ 505 };\n+ 506\n+ 507 template\n+508 struct FieldTraits< ScaledIdentityMatrix >\n+ 509 {\n+510 using field_type = typename ScaledIdentityMatrix::field_type;\n+511 using real_type = typename FieldTraits::real_type;\n+ 512 };\n+ 513\n+ 514} // end namespace\n+ 515\n+ 516#endif\n Dune\n Definition: allocator.hh:11\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::MatrixImp::DenseMatrixBase\n-A Vector of blocks with different blocksizes.\n-Definition: matrix.hh:44\n-Dune::MatrixImp::DenseMatrixBase::window_type\n-Imp::BlockVectorWindow< B, A > window_type\n-Definition: matrix.hh:70\n-Dune::MatrixImp::DenseMatrixBase::block_type\n-BlockVector< B, A > block_type\n-Same as value_type, here for historical reasons.\n-Definition: matrix.hh:67\n-Dune::MatrixImp::DenseMatrixBase::operator=\n-DenseMatrixBase & operator=(const DenseMatrixBase &a)\n-assignment\n-Definition: matrix.hh:182\n-Dune::MatrixImp::DenseMatrixBase::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: matrix.hh:50\n-Dune::MatrixImp::DenseMatrixBase::beforeBegin\n-Iterator beforeBegin() const\n-Definition: matrix.hh:385\n-Dune::MatrixImp::DenseMatrixBase::resize\n-void resize(size_type rows, size_type columns)\n-same effect as constructor with same argument\n-Definition: matrix.hh:153\n-Dune::MatrixImp::DenseMatrixBase::const_reference\n-const window_type const_reference\n-Definition: matrix.hh:74\n-Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n-DenseMatrixBase(size_type rows, size_type columns)\n-Definition: matrix.hh:95\n-Dune::MatrixImp::DenseMatrixBase::end\n-Iterator end()\n-end Iterator\n-Definition: matrix.hh:371\n-Dune::MatrixImp::DenseMatrixBase::operator[]\n-reference operator[](size_type i)\n-random access to blocks\n-Definition: matrix.hh:241\n-Dune::MatrixImp::DenseMatrixBase::value_type\n-BlockVector< B, A > value_type\n-Type of the elements of the outer vector, i.e., dynamic vectors of B.\n-Definition: matrix.hh:63\n-Dune::MatrixImp::DenseMatrixBase::find\n-Iterator find(size_type i)\n-random access returning iterator (end if not contained)\n-Definition: matrix.hh:391\n-Dune::MatrixImp::DenseMatrixBase::N\n-size_type N() const\n-number of blocks in the vector (are of variable size here)\n-Definition: matrix.hh:539\n-Dune::MatrixImp::DenseMatrixBase::beforeEnd\n-ConstIterator beforeEnd() const\n-Definition: matrix.hh:525\n-Dune::MatrixImp::DenseMatrixBase::end\n+Dune::ScaledIdentityMatrix\n+A multiple of the identity matrix of static size.\n+Definition: scaledidmatrix.hh:30\n+Dune::ScaledIdentityMatrix::usmhv\n+void usmhv(const K &alpha, const X &x, Y &y) const\n+y += alpha A^H x\n+Definition: scaledidmatrix.hh:353\n+Dune::ScaledIdentityMatrix::mmtv\n+void mmtv(const X &x, Y &y) const\n+y -= A^T x\n+Definition: scaledidmatrix.hh:305\n+Dune::ScaledIdentityMatrix::operator-=\n+ScaledIdentityMatrix & operator-=(const ScaledIdentityMatrix &y)\n+vector space subtraction\n+Definition: scaledidmatrix.hh:169\n+Dune::ScaledIdentityMatrix::ConstColIterator\n+const_row_type::ConstIterator ConstColIterator\n+rename the iterators for easier access\n+Definition: scaledidmatrix.hh:131\n+Dune::ScaledIdentityMatrix::end\n ConstIterator end() const\n-end ConstIterator\n-Definition: matrix.hh:518\n-Dune::MatrixImp::DenseMatrixBase::reference\n-window_type reference\n-Definition: matrix.hh:72\n-Dune::MatrixImp::DenseMatrixBase::rend\n-ConstIterator rend() const\n-end ConstIterator\n-Definition: matrix.hh:531\n-Dune::MatrixImp::DenseMatrixBase::beforeEnd\n-Iterator beforeEnd()\n-Definition: matrix.hh:378\n-Dune::MatrixImp::DenseMatrixBase::begin\n-ConstIterator begin() const\n-begin ConstIterator\n-Definition: matrix.hh:512\n-Dune::MatrixImp::DenseMatrixBase::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: matrix.hh:53\n-Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n-DenseMatrixBase()\n-Definition: matrix.hh:82\n-Dune::MatrixImp::DenseMatrixBase::find\n-ConstIterator find(size_type i) const\n-random access returning iterator (end if not contained)\n-Definition: matrix.hh:397\n-Dune::MatrixImp::DenseMatrixBase::size_type\n-A::size_type size_type\n-The size type for the index access.\n-Definition: matrix.hh:56\n-Dune::MatrixImp::DenseMatrixBase::~DenseMatrixBase\n-~DenseMatrixBase()\n-free dynamic memory\n-Definition: matrix.hh:142\n-Dune::MatrixImp::DenseMatrixBase::begin\n-Iterator begin()\n-begin Iterator\n-Definition: matrix.hh:365\n-Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n-DenseMatrixBase(const DenseMatrixBase &a)\n-copy constructor, has copy semantics\n-Definition: matrix.hh:116\n-Dune::MatrixImp::DenseMatrixBase::Iterator\n+end iterator\n+Definition: scaledidmatrix.hh:140\n+Dune::ScaledIdentityMatrix::beforeBegin\n+Iterator beforeBegin()\n+Definition: scaledidmatrix.hh:118\n+Dune::ScaledIdentityMatrix::operator!=\n+bool operator!=(const ScaledIdentityMatrix &other) const\n+incomparison operator\n+Definition: scaledidmatrix.hh:229\n+Dune::ScaledIdentityMatrix::mmv\n+void mmv(const X &x, Y &y) const\n+y -= A x\n+Definition: scaledidmatrix.hh:293\n+Dune::ScaledIdentityMatrix::size_type\n+std::size_t size_type\n+The type used for the index access and size operations.\n+Definition: scaledidmatrix.hh:43\n+Dune::ScaledIdentityMatrix::usmv\n+void usmv(const K &alpha, const X &x, Y &y) const\n+y += alpha A x\n+Definition: scaledidmatrix.hh:329\n+Dune::ScaledIdentityMatrix::ColIterator\n+row_type::Iterator ColIterator\n+rename the iterators for easier access\n+Definition: scaledidmatrix.hh:95\n+Dune::ScaledIdentityMatrix::const_reference\n+const_row_type const_reference\n+Definition: scaledidmatrix.hh:53\n+Dune::ScaledIdentityMatrix::mv\n+void mv(const X &x, Y &y) const\n+y = A x\n+Definition: scaledidmatrix.hh:238\n+Dune::ScaledIdentityMatrix::umtv\n+void umtv(const X &x, Y &y) const\n+y += A^T x\n+Definition: scaledidmatrix.hh:269\n+Dune::ScaledIdentityMatrix::umhv\n+void umhv(const X &x, Y &y) const\n+y += A^H x\n+Definition: scaledidmatrix.hh:281\n+Dune::ScaledIdentityMatrix::row_type\n+DiagonalRowVector< K, n > row_type\n+Each row is implemented by a field vector.\n+Definition: scaledidmatrix.hh:50\n+Dune::ScaledIdentityMatrix::Iterator\n+ContainerWrapperIterator< const WrapperType, reference, reference > Iterator\n Iterator class for sequential access.\n-Definition: matrix.hh:263\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator--\n-Iterator & operator--()\n-prefix decrement\n-Definition: matrix.hh:308\n-Dune::MatrixImp::DenseMatrixBase::Iterator::index\n-size_type index() const\n-Definition: matrix.hh:352\n-Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n-Iterator(Iterator &other)=default\n-Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n-Iterator(Iterator &&other)=default\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator!=\n-bool operator!=(const Iterator &it) const\n-inequality\n-Definition: matrix.hh:322\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator=\n-Iterator & operator=(Iterator &&other)\n-Move assignment.\n-Definition: matrix.hh:282\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator++\n-Iterator & operator++()\n-prefix increment\n-Definition: matrix.hh:300\n-Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n-Iterator()\n-constructor, no arguments\n-Definition: matrix.hh:266\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator*\n-window_type & operator*() const\n-dereferencing\n-Definition: matrix.hh:340\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator==\n-bool operator==(const Iterator &it) const\n-equality\n-Definition: matrix.hh:316\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator=\n-Iterator & operator=(Iterator &other)\n-Copy assignment.\n-Definition: matrix.hh:291\n-Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n-Iterator(B *data, size_type columns, size_type _i)\n-constructor\n-Definition: matrix.hh:276\n-Dune::MatrixImp::DenseMatrixBase::Iterator::operator->\n-window_type * operator->() const\n-arrow\n-Definition: matrix.hh:346\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator\n-ConstIterator class for sequential access.\n-Definition: matrix.hh:404\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator->\n-const window_type * operator->() const\n-arrow\n-Definition: matrix.hh:487\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator*\n-const window_type & operator*() const\n-dereferencing\n-Definition: matrix.hh:481\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator++\n-ConstIterator & operator++()\n-prefix increment\n-Definition: matrix.hh:441\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n-ConstIterator(const B *data, size_type columns, size_type _i)\n-constructor from pointer\n-Definition: matrix.hh:414\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator--\n-ConstIterator & operator--()\n-prefix decrement\n-Definition: matrix.hh:449\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n-ConstIterator(const Iterator &it)\n-constructor from non_const iterator\n-Definition: matrix.hh:420\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator!=\n-bool operator!=(const ConstIterator &it) const\n-inequality\n-Definition: matrix.hh:463\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n-ConstIterator()\n-constructor\n-Definition: matrix.hh:407\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator==\n-bool operator==(const ConstIterator &it) const\n-equality\n-Definition: matrix.hh:457\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::index\n-size_type index() const\n-Definition: matrix.hh:493\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator=\n-ConstIterator & operator=(Iterator &&other)\n-Definition: matrix.hh:424\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator=\n-ConstIterator & operator=(Iterator &other)\n-Definition: matrix.hh:432\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::cols_\n-size_type cols_\n-Number of columns of the matrix.\n-Definition: matrix.hh:1088\n-Dune::Matrix::infinity_norm\n-FieldTraits< ft >::real_type infinity_norm() const\n-infinity norm (row sum norm, how to generalize for blocks?)\n-Definition: matrix.hh:992\n-Dune::Matrix::allocator_type\n-A allocator_type\n-Export the allocator.\n-Definition: matrix.hh:571\n-Dune::Matrix::infinity_norm_real\n-FieldTraits< ft >::real_type infinity_norm_real() const\n-simplified infinity norm (uses Manhattan norm for complex values)\n-Definition: matrix.hh:1011\n-Dune::Matrix::usmhv\n-void usmhv(const field_type &alpha, const X &x, Y &y) const\n-y += alpha A^H x\n-Definition: matrix.hh:956\n-Dune::Matrix::usmv\n-void usmv(const field_type &alpha, const X &x, Y &y) const\n-Definition: matrix.hh:854\n-Dune::Matrix::size_type\n-A::size_type size_type\n-Type for indices and sizes.\n-Definition: matrix.hh:577\n-Dune::Matrix::data_\n-MatrixImp::DenseMatrixBase< T, A > data_\n-Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.\n-Definition: matrix.hh:1081\n-Dune::Matrix::transpose\n-Matrix transpose() const\n-Return the transpose of the matrix.\n-Definition: matrix.hh:745\n-Dune::Matrix::mtv\n-void mtv(const X &x, Y &y) const\n-y = A^T x\n-Definition: matrix.hh:807\n-Dune::Matrix::umv\n+Definition: scaledidmatrix.hh:89\n+Dune::ScaledIdentityMatrix::beforeEnd\n+Iterator beforeEnd()\n+Definition: scaledidmatrix.hh:111\n+Dune::ScaledIdentityMatrix::determinant\n+K determinant() const\n+calculates the determinant of this matrix\n+Definition: scaledidmatrix.hh:408\n+Dune::ScaledIdentityMatrix::field_type\n+K field_type\n+export the type representing the field\n+Definition: scaledidmatrix.hh:37\n+Dune::ScaledIdentityMatrix::usmtv\n+void usmtv(const K &alpha, const X &x, Y &y) const\n+y += alpha A^T x\n+Definition: scaledidmatrix.hh:341\n+Dune::ScaledIdentityMatrix::end\n+Iterator end()\n+end iterator\n+Definition: scaledidmatrix.hh:104\n+Dune::ScaledIdentityMatrix::iterator\n+Iterator iterator\n+typedef for stl compliant access\n+Definition: scaledidmatrix.hh:91\n+Dune::ScaledIdentityMatrix::scalar\n+const K & scalar() const\n+Get const reference to the scalar diagonal value.\n+Definition: scaledidmatrix.hh:477\n+Dune::ScaledIdentityMatrix::umv\n void umv(const X &x, Y &y) const\n y += A x\n-Definition: matrix.hh:820\n-Dune::Matrix::mv\n-void mv(const X &x, Y &y) const\n-y = A x\n-Definition: matrix.hh:788\n-Dune::Matrix::ConstRowIterator\n-MatrixImp::DenseMatrixBase< T, A >::ConstIterator ConstRowIterator\n-Const iterator over the matrix rows.\n-Definition: matrix.hh:586\n-Dune::Matrix::setSize\n-void setSize(size_type rows, size_type cols)\n-Change the matrix size.\n-Definition: matrix.hh:608\n-Dune::Matrix::beforeBegin\n-RowIterator beforeBegin()\n-Definition: matrix.hh:634\n-Dune::Matrix::beforeEnd\n-RowIterator beforeEnd()\n-Definition: matrix.hh:627\n-Dune::Matrix::Matrix\n-Matrix()\n-Create empty matrix.\n-Definition: matrix.hh:596\n-Dune::Matrix::operator-=\n-Matrix & operator-=(const Matrix &b)\n-Subtract the entries of another matrix from this one.\n-Definition: matrix.hh:735\n-Dune::Matrix::frobenius_norm2\n+Definition: scaledidmatrix.hh:257\n+Dune::ScaledIdentityMatrix::blocklevel\n+static constexpr std::size_t blocklevel\n+We are at the leaf of the block recursion.\n+Definition: scaledidmatrix.hh:47\n+Dune::ScaledIdentityMatrix::diagonal\n+const K & diagonal(size_type) const\n+Get const reference to diagonal entry.\n+Definition: scaledidmatrix.hh:464\n+Dune::ScaledIdentityMatrix::rows\n+@ rows\n+The number of rows.\n+Definition: scaledidmatrix.hh:58\n+Dune::ScaledIdentityMatrix::cols\n+@ cols\n+The number of columns.\n+Definition: scaledidmatrix.hh:60\n+Dune::ScaledIdentityMatrix::operator=\n+ScaledIdentityMatrix & operator=(const K &k)\n+Definition: scaledidmatrix.hh:75\n+Dune::ScaledIdentityMatrix::ConstIterator\n+ContainerWrapperIterator< const WrapperType, const_reference, const_reference >\n+ConstIterator\n+Iterator class for sequential access.\n+Definition: scaledidmatrix.hh:125\n+Dune::ScaledIdentityMatrix::diagonal\n+K & diagonal(size_type)\n+Get reference to diagonal entry.\n+Definition: scaledidmatrix.hh:470\n+Dune::ScaledIdentityMatrix::solve\n+void solve(V &x, const V &b) const\n+Solve system A x = b.\n+Definition: scaledidmatrix.hh:394\n+Dune::ScaledIdentityMatrix::exists\n+bool exists(size_type i, size_type j) const\n+return true when (i,j) is in pattern\n+Definition: scaledidmatrix.hh:429\n+Dune::ScaledIdentityMatrix::RowIterator\n+Iterator RowIterator\n+rename the iterators for easier access\n+Definition: scaledidmatrix.hh:93\n+Dune::ScaledIdentityMatrix::const_iterator\n+ConstIterator const_iterator\n+typedef for stl compliant access\n+Definition: scaledidmatrix.hh:127\n+Dune::ScaledIdentityMatrix::ScaledIdentityMatrix\n+ScaledIdentityMatrix()\n+Default constructor.\n+Definition: scaledidmatrix.hh:66\n+Dune::ScaledIdentityMatrix::operator==\n+bool operator==(const ScaledIdentityMatrix &other) const\n+comparison operator\n+Definition: scaledidmatrix.hh:223\n+Dune::ScaledIdentityMatrix::beforeBegin\n+ConstIterator beforeBegin() const\n+Definition: scaledidmatrix.hh:154\n+Dune::ScaledIdentityMatrix::operator/=\n+ScaledIdentityMatrix & operator/=(const K &k)\n+vector space division by scalar\n+Definition: scaledidmatrix.hh:196\n+Dune::ScaledIdentityMatrix::operator<<\n+friend std::ostream & operator<<(std::ostream &s, const ScaledIdentityMatrix<\n+K, n > &a)\n+Sends the matrix to an output stream.\n+Definition: scaledidmatrix.hh:441\n+Dune::ScaledIdentityMatrix::frobenius_norm2\n FieldTraits< field_type >::real_type frobenius_norm2() const\n square of frobenius norm, need for block recursion\n-Definition: matrix.hh:980\n-Dune::Matrix::ColIterator\n-row_type::iterator ColIterator\n-Iterator for the entries of each row.\n-Definition: matrix.hh:583\n-Dune::Matrix::beforeEnd\n-ConstRowIterator beforeEnd() const\n-Definition: matrix.hh:653\n-Dune::Matrix::operator=\n-Matrix & operator=(const field_type &t)\n-Assignment from scalar.\n-Definition: matrix.hh:666\n-Dune::Matrix::end\n-RowIterator end()\n-Get iterator to one beyond last row.\n-Definition: matrix.hh:620\n-Dune::Matrix::operator[]\n-const row_type operator[](size_type row) const\n-The const index operator.\n-Definition: matrix.hh:684\n-Dune::Matrix::end\n-ConstRowIterator end() const\n-Get const iterator to one beyond last row.\n-Definition: matrix.hh:646\n-Dune::Matrix::operator*\n-friend Y operator*(const Matrix< T > &m, const X &vec)\n-Generic matrix-vector multiplication.\n-Definition: matrix.hh:770\n-Dune::Matrix::operator*=\n-Matrix< T > & operator*=(const field_type &scalar)\n-Multiplication with a scalar.\n-Definition: matrix.hh:705\n-Dune::Matrix::operator[]\n-row_type operator[](size_type row)\n-The index operator.\n-Definition: matrix.hh:673\n-Dune::Matrix::mmv\n-void mmv(const X &x, Y &y) const\n-y -= A x\n-Definition: matrix.hh:837\n-Dune::Matrix::operator+=\n-Matrix & operator+=(const Matrix &b)\n-Add the entries of another matrix to this one.\n-Definition: matrix.hh:721\n-Dune::Matrix::begin\n-ConstRowIterator begin() const\n-Get const iterator to first row.\n-Definition: matrix.hh:640\n-Dune::Matrix::mmhv\n-void mmhv(const X &x, Y &y) const\n-y -= A^H x\n-Definition: matrix.hh:939\n-Dune::Matrix::begin\n-RowIterator begin()\n-Get iterator to first row.\n-Definition: matrix.hh:614\n-Dune::Matrix::field_type\n-typename Imp::BlockTraits< T >::field_type field_type\n-Export the type representing the underlying field.\n-Definition: matrix.hh:565\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n-Dune::Matrix::blocklevel\n-static constexpr auto blocklevel\n-The number of nesting levels the matrix contains.\n-Definition: matrix.hh:593\n-Dune::Matrix::M\n-size_type M() const\n-Return the number of columns.\n-Definition: matrix.hh:700\n-Dune::Matrix::block_type\n-T block_type\n-Export the type representing the components.\n-Definition: matrix.hh:568\n-Dune::Matrix::exists\n-bool exists(size_type i, size_type j) const\n-return true if (i,j) is in pattern\n-Definition: matrix.hh:1068\n-Dune::Matrix::operator/=\n-Matrix< T > & operator/=(const field_type &scalar)\n-Division by a scalar.\n-Definition: matrix.hh:711\n-Dune::Matrix::operator*\n-friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)\n-Generic matrix multiplication.\n-Definition: matrix.hh:755\n-Dune::Matrix::umtv\n-void umtv(const X &x, Y &y) const\n-y += A^T x\n-Definition: matrix.hh:871\n-Dune::Matrix::mmtv\n-void mmtv(const X &x, Y &y) const\n-y -= A^T x\n-Definition: matrix.hh:888\n-Dune::Matrix::row_type\n-MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n-The type implementing a matrix row.\n-Definition: matrix.hh:574\n-Dune::Matrix::frobenius_norm\n+Definition: scaledidmatrix.hh:372\n+Dune::ScaledIdentityMatrix::frobenius_norm\n FieldTraits< field_type >::real_type frobenius_norm() const\n frobenius norm: sqrt(sum over squared values of entries)\n-Definition: matrix.hh:974\n-Dune::Matrix::usmtv\n-void usmtv(const field_type &alpha, const X &x, Y &y) const\n-y += alpha A^T x\n-Definition: matrix.hh:905\n-Dune::Matrix::umhv\n-void umhv(const X &x, Y &y) const\n-y += A^H x\n-Definition: matrix.hh:922\n-Dune::Matrix::N\n+Definition: scaledidmatrix.hh:366\n+Dune::ScaledIdentityMatrix::infinity_norm\n+FieldTraits< field_type >::real_type infinity_norm() const\n+infinity norm (row sum norm, how to generalize for blocks?)\n+Definition: scaledidmatrix.hh:378\n+Dune::ScaledIdentityMatrix::ConstRowIterator\n+ConstIterator ConstRowIterator\n+rename the iterators for easier access\n+Definition: scaledidmatrix.hh:129\n+Dune::ScaledIdentityMatrix::beforeEnd\n+ConstIterator beforeEnd() const\n+Definition: scaledidmatrix.hh:147\n+Dune::ScaledIdentityMatrix::M\n+size_type M() const\n+number of blocks in column direction\n+Definition: scaledidmatrix.hh:421\n+Dune::ScaledIdentityMatrix::operator[]\n+const_reference operator[](size_type i) const\n+Return const_reference object as row replacement.\n+Definition: scaledidmatrix.hh:458\n+Dune::ScaledIdentityMatrix::ScaledIdentityMatrix\n+ScaledIdentityMatrix(const K &k)\n+Constructor initializing the whole matrix with a scalar.\n+Definition: scaledidmatrix.hh:70\n+Dune::ScaledIdentityMatrix::operator*\n+friend auto operator*(const ScaledIdentityMatrix &matrix, Scalar scalar)\n+vector space multiplication with scalar\n+Definition: scaledidmatrix.hh:207\n+Dune::ScaledIdentityMatrix::infinity_norm_real\n+FieldTraits< field_type >::real_type infinity_norm_real() const\n+simplified infinity norm (uses Manhattan norm for complex values)\n+Definition: scaledidmatrix.hh:384\n+Dune::ScaledIdentityMatrix::operator*=\n+ScaledIdentityMatrix & operator*=(const K &k)\n+vector space multiplication with scalar\n+Definition: scaledidmatrix.hh:189\n+Dune::ScaledIdentityMatrix::identical\n+bool identical(const ScaledIdentityMatrix< K, n > &other) const\n+Definition: scaledidmatrix.hh:82\n+Dune::ScaledIdentityMatrix::invert\n+void invert()\n+Compute inverse.\n+Definition: scaledidmatrix.hh:402\n+Dune::ScaledIdentityMatrix::begin\n+Iterator begin()\n+begin iterator\n+Definition: scaledidmatrix.hh:98\n+Dune::ScaledIdentityMatrix::scalar\n+K & scalar()\n+Get reference to the scalar diagonal value.\n+Definition: scaledidmatrix.hh:484\n+Dune::ScaledIdentityMatrix::reference\n+row_type reference\n+Definition: scaledidmatrix.hh:51\n+Dune::ScaledIdentityMatrix::block_type\n+K block_type\n+export the type representing the components\n+Definition: scaledidmatrix.hh:40\n+Dune::ScaledIdentityMatrix::mmhv\n+void mmhv(const X &x, Y &y) const\n+y -= A^H x\n+Definition: scaledidmatrix.hh:317\n+Dune::ScaledIdentityMatrix::operator+=\n+ScaledIdentityMatrix & operator+=(const ScaledIdentityMatrix &y)\n+vector space addition\n+Definition: scaledidmatrix.hh:162\n+Dune::ScaledIdentityMatrix::const_row_type\n+DiagonalRowVectorConst< K, n > const_row_type\n+Definition: scaledidmatrix.hh:52\n+Dune::ScaledIdentityMatrix::mtv\n+void mtv(const X &x, Y &y) const\n+y = A^T x\n+Definition: scaledidmatrix.hh:250\n+Dune::ScaledIdentityMatrix::operator[]\n+reference operator[](size_type i)\n+Return reference object as row replacement.\n+Definition: scaledidmatrix.hh:452\n+Dune::ScaledIdentityMatrix::begin\n+ConstIterator begin() const\n+begin iterator\n+Definition: scaledidmatrix.hh:134\n+Dune::ScaledIdentityMatrix::N\n size_type N() const\n-Return the number of rows.\n-Definition: matrix.hh:695\n-Dune::Matrix::beforeBegin\n-ConstRowIterator beforeBegin() const\n-Definition: matrix.hh:660\n-Dune::Matrix::Matrix\n-Matrix(size_type rows, size_type cols)\n-Create uninitialized matrix of size rows x cols.\n-Definition: matrix.hh:601\n-Dune::Matrix::RowIterator\n-MatrixImp::DenseMatrixBase< T, A >::Iterator RowIterator\n-Iterator over the matrix rows.\n-Definition: matrix.hh:580\n-Dune::FieldTraits<_Matrix<_T,_A_>_>::field_type\n-typename Matrix< T, A >::field_type field_type\n-Definition: matrix.hh:1094\n-Dune::FieldTraits<_Matrix<_T,_A_>_>::real_type\n+number of blocks in row direction\n+Definition: scaledidmatrix.hh:415\n+Dune::DenseMatrixAssigner<_DenseMatrix,_ScaledIdentityMatrix<_field,_N_>_>::\n+apply\n+static void apply(DenseMatrix &denseMatrix, ScaledIdentityMatrix< field, N >\n+const &rhs)\n+Definition: scaledidmatrix.hh:497\n+Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>::field_type\n+typename ScaledIdentityMatrix< K, n >::field_type field_type\n+Definition: scaledidmatrix.hh:510\n+Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>::real_type\n typename FieldTraits< field_type >::real_type real_type\n-Definition: matrix.hh:1095\n+Definition: scaledidmatrix.hh:511\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00026.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00026.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixredistribute.hh File Reference\n+dune-istl: solvertype.hh File Reference\n \n \n \n \n \n \n \n@@ -64,86 +64,38 @@\n \n
    \n
    \n
    \n \n-
    matrixredistribute.hh File Reference
    \n+Namespaces
    \n+
    solvertype.hh File Reference
    \n
    \n
    \n \n-

    Functionality for redistributing a sparse matrix. \n+

    Templates characterizing the type of a solver. \n More...

    \n-
    #include <memory>
    \n-#include "repartition.hh"
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/parallel/indexset.hh>
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n-#include <dune/istl/paamg/pinfo.hh>
    \n-
    \n+\n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::RedistributeInformation< T >
     
    class  Dune::RedistributeInformation< OwnerOverlapCopyCommunication< T, T1 > >
     
    struct  Dune::CommMatrixRowSize< M, RI >
     Utility class to communicate and set the row sizes of a redistributed matrix. More...
     
    struct  Dune::CommMatrixSparsityPattern< M, I >
     Utility class to communicate and build the sparsity pattern of a redistributed matrix. More...
     
    struct  Dune::CommPolicy< CommMatrixSparsityPattern< M, I > >
    struct  Dune::IsDirectSolver< Solver >
     
    struct  Dune::CommMatrixRow< M, I >
     Utility class for comunicating the matrix entries. More...
     
    struct  Dune::CommPolicy< CommMatrixRow< M, I > >
     
    struct  Dune::MatrixRowSizeGatherScatter< M, I, RI >
     
    struct  Dune::MatrixCopyRowSizeGatherScatter< M, I, RI >
     
    struct  Dune::MatrixSparsityPatternGatherScatter< M, I >
     
    struct  Dune::MatrixRowGatherScatter< M, I >
    struct  Dune::StoresColumnCompressed< Solver >
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<typename M , typename C >
    void Dune::redistributeSparsityPattern (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     
    template<typename M , typename C >
    void Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     
    template<typename M , typename C >
    void Dune::redistributeMatrix (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     Redistribute a matrix according to given domain decompositions. More...
     
    template<typename M >
    void Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, Dune::Amg::SequentialInformation &origComm, Dune::Amg::SequentialInformation &newComm, RedistributeInformation< Dune::Amg::SequentialInformation > &ri)
     
    template<typename M >
    void Dune::redistributeMatrix (M &origMatrix, M &newMatrix, Dune::Amg::SequentialInformation &origComm, Dune::Amg::SequentialInformation &newComm, RedistributeInformation< Dune::Amg::SequentialInformation > &ri)
     
    \n

    Detailed Description

    \n-

    Functionality for redistributing a sparse matrix.

    \n-
    Author
    Markus Blatt
    \n+

    Templates characterizing the type of a solver.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,82 +4,24 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-matrixredistribute.hh File Reference\n-Functionality for redistributing a sparse matrix. More...\n-#include \n-#include \"repartition.hh\"\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+solvertype.hh File Reference\n+Templates characterizing the type of a solver. More...\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::RedistributeInformation<_T_>\n+struct \u00a0Dune::IsDirectSolver<_Solver_>\n \u00a0\n- class \u00a0Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>\n- >\n-\u00a0\n-struct \u00a0Dune::CommMatrixRowSize<_M,_RI_>\n-\u00a0 Utility class to communicate and set the row sizes of a redistributed\n- matrix. More...\n-\u00a0\n-struct \u00a0Dune::CommMatrixSparsityPattern<_M,_I_>\n-\u00a0 Utility class to communicate and build the sparsity pattern of a\n- redistributed matrix. More...\n-\u00a0\n-struct \u00a0Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>\n-\u00a0\n-struct \u00a0Dune::CommMatrixRow<_M,_I_>\n-\u00a0 Utility class for comunicating the matrix entries. More...\n-\u00a0\n-struct \u00a0Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixRowSizeGatherScatter<_M,_I,_RI_>\n-\u00a0\n-struct \u00a0Dune::MatrixCopyRowSizeGatherScatter<_M,_I,_RI_>\n-\u00a0\n-struct \u00a0Dune::MatrixSparsityPatternGatherScatter<_M,_I_>\n-\u00a0\n-struct \u00a0Dune::MatrixRowGatherScatter<_M,_I_>\n+struct \u00a0Dune::StoresColumnCompressed<_Solver_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-template\n-void\u00a0Dune::redistributeSparsityPattern (M &origMatrix, M &newMatrix, C\n- &origComm, C &newComm, RedistributeInformation< C > &ri)\n-\u00a0\n-template\n-void\u00a0Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, C\n- &origComm, C &newComm, RedistributeInformation< C > &ri)\n-\u00a0\n-template\n-void\u00a0Dune::redistributeMatrix (M &origMatrix, M &newMatrix, C &origComm, C\n- &newComm, RedistributeInformation< C > &ri)\n-\u00a0 Redistribute a matrix according to given domain decompositions. More...\n-\u00a0\n-template\n-void\u00a0Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, Dune::Amg::\n- SequentialInformation &origComm, Dune::Amg::SequentialInformation\n- &newComm, RedistributeInformation< Dune::Amg::SequentialInformation >\n- &ri)\n-\u00a0\n-template\n-void\u00a0Dune::redistributeMatrix (M &origMatrix, M &newMatrix, Dune::Amg::\n- SequentialInformation &origComm, Dune::Amg::SequentialInformation\n- &newComm, RedistributeInformation< Dune::Amg::SequentialInformation >\n- &ri)\n-\u00a0\n ***** Detailed Description *****\n-Functionality for redistributing a sparse matrix.\n- Author\n- Markus Blatt\n+Templates characterizing the type of a solver.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00026_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00026_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixredistribute.hh Source File\n+dune-istl: solvertype.hh Source File\n \n \n \n \n \n \n \n@@ -62,868 +62,50 @@\n \n
    \n \n
    \n
    \n
    \n-
    matrixredistribute.hh
    \n+
    solvertype.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MATRIXREDISTRIBUTE_HH
    \n-
    6#define DUNE_ISTL_MATRIXREDISTRIBUTE_HH
    \n-
    7#include <memory>
    \n-
    8#include "repartition.hh"
    \n-
    9#include <dune/common/exceptions.hh>
    \n-
    10#include <dune/common/parallel/indexset.hh>
    \n-\n-\n-
    18namespace Dune
    \n-
    19{
    \n-
    20 template<typename T>
    \n-\n-
    22 {
    \n-
    23 bool isSetup() const
    \n-
    24 {
    \n-
    25 return false;
    \n-
    26 }
    \n-
    27 template<class D>
    \n-
    28 void redistribute([[maybe_unused]] const D& from, [[maybe_unused]] D& to) const
    \n-
    29 {}
    \n-
    30
    \n-
    31 template<class D>
    \n-
    32 void redistributeBackward([[maybe_unused]] D& from, [[maybe_unused]]const D& to) const
    \n-
    33 {}
    \n-
    34
    \n-\n-
    36 {}
    \n-
    37
    \n-
    38 void setNoRows([[maybe_unused]] std::size_t size)
    \n-
    39 {}
    \n-
    40
    \n-
    41 void setNoCopyRows([[maybe_unused]] std::size_t size)
    \n-
    42 {}
    \n-
    43
    \n-
    44 void setNoBackwardsCopyRows([[maybe_unused]] std::size_t size)
    \n-
    45 {}
    \n-
    46
    \n-
    47 std::size_t getRowSize([[maybe_unused]] std::size_t index) const
    \n-
    48 {
    \n-
    49 return -1;
    \n-
    50 }
    \n-
    51
    \n-
    52 std::size_t getCopyRowSize([[maybe_unused]] std::size_t index) const
    \n-
    53 {
    \n-
    54 return -1;
    \n-
    55 }
    \n-
    56
    \n-
    57 std::size_t getBackwardsCopyRowSize([[maybe_unused]] std::size_t index) const
    \n-
    58 {
    \n-
    59 return -1;
    \n-
    60 }
    \n-
    61
    \n-
    62 };
    \n-
    63
    \n-
    64#if HAVE_MPI
    \n-
    65 template<typename T, typename T1>
    \n-\n-
    67 {
    \n-
    68 public:
    \n-\n-
    70
    \n-\n-
    72 : interface(), setup_(false)
    \n-
    73 {}
    \n-
    74
    \n-\n-
    76 {
    \n-
    77 return interface;
    \n-
    78 }
    \n-
    79 template<typename IS>
    \n-
    80 void checkInterface(const IS& source,
    \n-
    81 const IS& target, MPI_Comm comm)
    \n-
    82 {
    \n-
    83 auto ri = std::make_unique<RemoteIndices<IS> >(source, target, comm);
    \n-
    84 ri->template rebuild<true>();
    \n-
    85 Interface inf;
    \n-\n-
    87 int rank;
    \n-
    88 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n-
    89 inf.free();
    \n-
    90 inf.build(*ri, flags, flags);
    \n-
    91
    \n-
    92
    \n-
    93#ifdef DEBUG_REPART
    \n-
    94 if(inf!=interface) {
    \n-
    95
    \n-
    96 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n-
    97 if(rank==0)
    \n-
    98 std::cout<<"Interfaces do not match!"<<std::endl;
    \n-
    99 std::cout<<rank<<": redist interface new :"<<inf<<std::endl;
    \n-
    100 std::cout<<rank<<": redist interface :"<<interface<<std::endl;
    \n-
    101
    \n-
    102 throw "autsch!";
    \n-
    103 }
    \n-
    104#endif
    \n-
    105 }
    \n-
    106 void setSetup()
    \n-
    107 {
    \n-
    108 setup_=true;
    \n-
    109 interface.strip();
    \n-
    110 }
    \n-
    111
    \n-\n-
    113 {
    \n-
    114 setup_=false;
    \n-
    115 }
    \n-
    116
    \n-
    117 template<class GatherScatter, class D>
    \n-
    118 void redistribute(const D& from, D& to) const
    \n-
    119 {
    \n-
    120 BufferedCommunicator communicator;
    \n-
    121 communicator.template build<D>(from,to, interface);
    \n-
    122 communicator.template forward<GatherScatter>(from, to);
    \n-
    123 communicator.free();
    \n-
    124 }
    \n-
    125 template<class GatherScatter, class D>
    \n-
    126 void redistributeBackward(D& from, const D& to) const
    \n-
    127 {
    \n-
    128
    \n-
    129 BufferedCommunicator communicator;
    \n-
    130 communicator.template build<D>(from,to, interface);
    \n-
    131 communicator.template backward<GatherScatter>(from, to);
    \n-
    132 communicator.free();
    \n-
    133 }
    \n-
    134
    \n-
    135 template<class D>
    \n-
    136 void redistribute(const D& from, D& to) const
    \n-
    137 {
    \n-
    138 redistribute<CopyGatherScatter<D> >(from,to);
    \n-
    139 }
    \n-
    140 template<class D>
    \n-
    141 void redistributeBackward(D& from, const D& to) const
    \n-
    142 {
    \n-
    143 redistributeBackward<CopyGatherScatter<D> >(from,to);
    \n-
    144 }
    \n-
    145 bool isSetup() const
    \n-
    146 {
    \n-
    147 return setup_;
    \n-
    148 }
    \n-
    149
    \n-
    150 void reserve(std::size_t size)
    \n-
    151 {}
    \n-
    152
    \n-
    153 std::size_t& getRowSize(std::size_t index)
    \n-
    154 {
    \n-
    155 return rowSize[index];
    \n-
    156 }
    \n-
    157
    \n-
    158 std::size_t getRowSize(std::size_t index) const
    \n-
    159 {
    \n-
    160 return rowSize[index];
    \n-
    161 }
    \n-
    162
    \n-
    163 std::size_t& getCopyRowSize(std::size_t index)
    \n-
    164 {
    \n-
    165 return copyrowSize[index];
    \n-
    166 }
    \n-
    167
    \n-
    168 std::size_t getCopyRowSize(std::size_t index) const
    \n-
    169 {
    \n-
    170 return copyrowSize[index];
    \n-
    171 }
    \n-
    172
    \n-
    173 std::size_t& getBackwardsCopyRowSize(std::size_t index)
    \n-
    174 {
    \n-
    175 return backwardscopyrowSize[index];
    \n-
    176 }
    \n-
    177
    \n-
    178 std::size_t getBackwardsCopyRowSize(std::size_t index) const
    \n-
    179 {
    \n-
    180 return backwardscopyrowSize[index];
    \n-
    181 }
    \n-
    182
    \n-
    183 void setNoRows(std::size_t rows)
    \n-
    184 {
    \n-
    185 rowSize.resize(rows, 0);
    \n-
    186 }
    \n-
    187
    \n-
    188 void setNoCopyRows(std::size_t rows)
    \n-
    189 {
    \n-
    190 copyrowSize.resize(rows, 0);
    \n-
    191 }
    \n-
    192
    \n-
    193 void setNoBackwardsCopyRows(std::size_t rows)
    \n-
    194 {
    \n-
    195 backwardscopyrowSize.resize(rows, 0);
    \n-
    196 }
    \n-
    197
    \n-
    198 private:
    \n-
    199 std::vector<std::size_t> rowSize;
    \n-
    200 std::vector<std::size_t> copyrowSize;
    \n-
    201 std::vector<std::size_t> backwardscopyrowSize;
    \n-
    202 RedistributeInterface interface;
    \n-
    203 bool setup_;
    \n-
    204 };
    \n-
    205
    \n-
    214 template<class M, class RI>
    \n-\n-
    216 {
    \n-
    217 // Make the default communication policy work.
    \n-
    218 typedef typename M::size_type value_type;
    \n-
    219 typedef typename M::size_type size_type;
    \n-
    220
    \n-
    226 CommMatrixRowSize(const M& m_, RI& rowsize_)
    \n-
    227 : matrix(m_), rowsize(rowsize_)
    \n-
    228 {}
    \n-
    229 const M& matrix;
    \n-\n-
    231
    \n-
    232 };
    \n-
    233
    \n-
    234
    \n-
    243 template<class M, class I>
    \n-\n-
    245 {
    \n-
    246 typedef typename M::size_type size_type;
    \n-
    247
    \n-
    254 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_)
    \n-
    255 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()
    \n-
    256 {}
    \n-
    257
    \n-
    265 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_,
    \n-
    266 const std::vector<typename M::size_type>& rowsize_)
    \n-
    267 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), sparsity(aggidxset_.size()), rowsize(&rowsize_)
    \n-
    268 {}
    \n-
    269
    \n-\n-
    277 {
    \n-
    278 // insert diagonal to overlap rows
    \n-
    279 typedef typename Dune::GlobalLookupIndexSet<I>::const_iterator IIter;
    \n-\n-
    281 std::size_t nnz=0;
    \n-
    282#ifdef DEBUG_REPART
    \n-
    283 int rank;
    \n-
    284
    \n-
    285 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n-
    286#endif
    \n-
    287 for(IIter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i) {
    \n-
    288 if(!OwnerSet::contains(i->local().attribute())) {
    \n-
    289#ifdef DEBUG_REPART
    \n-
    290 std::cout<<rank<<" Inserting diagonal for"<<i->local()<<std::endl;
    \n-
    291#endif
    \n-
    292 sparsity[i->local()].insert(i->local());
    \n-
    293 }
    \n-
    294
    \n-
    295 nnz+=sparsity[i->local()].size();
    \n-
    296 }
    \n-
    297 assert( aggidxset.size()==sparsity.size());
    \n-
    298
    \n-
    299 if(nnz>0) {
    \n-
    300 m.setSize(aggidxset.size(), aggidxset.size(), nnz);
    \n-
    301 m.setBuildMode(M::row_wise);
    \n-
    302 typename M::CreateIterator citer=m.createbegin();
    \n-
    303#ifdef DEBUG_REPART
    \n-
    304 std::size_t idx=0;
    \n-
    305 bool correct=true;
    \n-
    306 Dune::GlobalLookupIndexSet<I> global(aggidxset);
    \n-
    307#endif
    \n-
    308 typedef typename std::vector<std::set<size_type> >::const_iterator Iter;
    \n-
    309 for(Iter i=sparsity.begin(), end=sparsity.end(); i!=end; ++i, ++citer)
    \n-
    310 {
    \n-
    311 typedef typename std::set<size_type>::const_iterator SIter;
    \n-
    312 for(SIter si=i->begin(), send=i->end(); si!=send; ++si)
    \n-
    313 citer.insert(*si);
    \n-
    314#ifdef DEBUG_REPART
    \n-
    315 if(i->find(idx)==i->end()) {
    \n-
    316 const typename I::IndexPair* gi=global.pair(idx);
    \n-
    317 assert(gi);
    \n-
    318 std::cout<<rank<<": row "<<idx<<" is missing a diagonal entry! global="<<gi->global()<<" attr="<<gi->local().attribute()<<" "<<
    \n-
    319 OwnerSet::contains(gi->local().attribute())<<
    \n-
    320 " row size="<<i->size()<<std::endl;
    \n-
    321 correct=false;
    \n-
    322 }
    \n-
    323 ++idx;
    \n-
    324#endif
    \n-
    325 }
    \n-
    326#ifdef DEBUG_REPART
    \n-
    327 if(!correct)
    \n-
    328 throw "bla";
    \n-
    329#endif
    \n-
    330 }
    \n-
    331 }
    \n-
    332
    \n-
    340 void completeSparsityPattern(std::vector<std::set<size_type> > add_sparsity)
    \n-
    341 {
    \n-
    342 for (unsigned int i = 0; i != sparsity.size(); ++i) {
    \n-
    343 if (add_sparsity[i].size() != 0) {
    \n-
    344 typedef std::set<size_type> Set;
    \n-
    345 Set tmp_set;
    \n-
    346 std::insert_iterator<Set> tmp_insert (tmp_set, tmp_set.begin());
    \n-
    347 std::set_union(add_sparsity[i].begin(), add_sparsity[i].end(),
    \n-
    348 sparsity[i].begin(), sparsity[i].end(), tmp_insert);
    \n-
    349 sparsity[i].swap(tmp_set);
    \n-
    350 }
    \n-
    351 }
    \n-
    352 }
    \n-
    353
    \n-
    354 const M& matrix;
    \n-
    355 typedef Dune::GlobalLookupIndexSet<I> LookupIndexSet;
    \n-
    356 const Dune::GlobalLookupIndexSet<I>& idxset;
    \n-
    357 const I& aggidxset;
    \n-
    358 std::vector<std::set<size_type> > sparsity;
    \n-
    359 const std::vector<size_type>* rowsize;
    \n-
    360 };
    \n-
    361
    \n-
    362 template<class M, class I>
    \n-
    363 struct CommPolicy<CommMatrixSparsityPattern<M,I> >
    \n-
    364 {
    \n-\n-
    366
    \n-
    371 typedef typename I::GlobalIndex IndexedType;
    \n-
    372
    \n-
    374 typedef VariableSize IndexedTypeFlag;
    \n-
    375
    \n-
    376 static typename M::size_type getSize(const Type& t, std::size_t i)
    \n-
    377 {
    \n-
    378 if(!t.rowsize)
    \n-
    379 return t.matrix[i].size();
    \n-
    380 else
    \n-
    381 {
    \n-
    382 assert((*t.rowsize)[i]>0);
    \n-
    383 return (*t.rowsize)[i];
    \n-
    384 }
    \n-
    385 }
    \n-
    386 };
    \n-
    387
    \n-
    394 template<class M, class I>
    \n-\n-
    396 {
    \n-
    405 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_)
    \n-
    406 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()
    \n-
    407 {}
    \n-
    408
    \n-
    412 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_,
    \n-
    413 std::vector<size_t>& rowsize_)
    \n-
    414 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize(&rowsize_)
    \n-
    415 {}
    \n-\n-
    422 {
    \n-
    423 typedef typename Dune::GlobalLookupIndexSet<I>::const_iterator Iter;
    \n-\n-
    425
    \n-
    426 for(Iter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i)
    \n-
    427 if(!OwnerSet::contains(i->local().attribute())) {
    \n-
    428 // Set to Dirchlet
    \n-
    429 typedef typename M::ColIterator CIter;
    \n-
    430 for(CIter c=matrix[i->local()].begin(), cend= matrix[i->local()].end();
    \n-
    431 c!= cend; ++c)
    \n-
    432 {
    \n-
    433 *c=0;
    \n-
    434 if(c.index()==i->local()) {
    \n-
    435 auto setDiagonal = [](auto&& scalarOrMatrix, const auto& value) {
    \n-
    436 auto&& matrixView = Dune::Impl::asMatrix(scalarOrMatrix);
    \n-
    437 for (auto rowIt = matrixView.begin(); rowIt != matrixView.end(); ++rowIt)
    \n-
    438 (*rowIt)[rowIt.index()] = value;
    \n-
    439 };
    \n-
    440 setDiagonal(*c, 1);
    \n-
    441 }
    \n-
    442 }
    \n-
    443 }
    \n-
    444 }
    \n-\n-
    448 const Dune::GlobalLookupIndexSet<I>& idxset;
    \n-
    450 const I& aggidxset;
    \n-
    452 std::vector<size_t>* rowsize; // row sizes differ from sender side in overlap!
    \n-
    453 };
    \n-
    454
    \n-
    455 template<class M, class I>
    \n-
    456 struct CommPolicy<CommMatrixRow<M,I> >
    \n-
    457 {
    \n-\n-
    459
    \n-
    464 typedef std::pair<typename I::GlobalIndex,typename M::block_type> IndexedType;
    \n-
    465
    \n-
    467 typedef VariableSize IndexedTypeFlag;
    \n-
    468
    \n-
    469 static std::size_t getSize(const Type& t, std::size_t i)
    \n-
    470 {
    \n-
    471 if(!t.rowsize)
    \n-
    472 return t.matrix[i].size();
    \n-
    473 else
    \n-
    474 {
    \n-
    475 assert((*t.rowsize)[i]>0);
    \n-
    476 return (*t.rowsize)[i];
    \n-
    477 }
    \n-
    478 }
    \n-
    479 };
    \n-
    480
    \n-
    481 template<class M, class I, class RI>
    \n-\n-
    483 {
    \n-\n-
    485
    \n-
    486 static const typename M::size_type gather(const Container& cont, std::size_t i)
    \n-
    487 {
    \n-
    488 return cont.matrix[i].size();
    \n-
    489 }
    \n-
    490 static void scatter(Container& cont, const typename M::size_type& rowsize, std::size_t i)
    \n-
    491 {
    \n-
    492 assert(rowsize);
    \n-
    493 cont.rowsize.getRowSize(i)=rowsize;
    \n-
    494 }
    \n-
    495
    \n-
    496 };
    \n-
    497
    \n-
    498 template<class M, class I, class RI>
    \n-\n-
    500 {
    \n-\n-
    502
    \n-
    503 static const typename M::size_type gather(const Container& cont, std::size_t i)
    \n-
    504 {
    \n-
    505 return cont.matrix[i].size();
    \n-
    506 }
    \n-
    507 static void scatter(Container& cont, const typename M::size_type& rowsize, std::size_t i)
    \n-
    508 {
    \n-
    509 assert(rowsize);
    \n-
    510 if (rowsize > cont.rowsize.getCopyRowSize(i))
    \n-
    511 cont.rowsize.getCopyRowSize(i)=rowsize;
    \n-
    512 }
    \n-
    513
    \n-
    514 };
    \n-
    515
    \n-
    516 template<class M, class I>
    \n-\n-
    518 {
    \n-
    519 typedef typename I::GlobalIndex GlobalIndex;
    \n-\n-
    521 typedef typename M::ConstColIterator ColIter;
    \n-
    522
    \n-
    523 static ColIter col;
    \n-\n-
    525
    \n-
    526 static const GlobalIndex& gather(const Container& cont, std::size_t i, std::size_t j)
    \n-
    527 {
    \n-
    528 if(j==0)
    \n-
    529 col=cont.matrix[i].begin();
    \n-
    530 else if (col!=cont.matrix[i].end())
    \n-
    531 ++col;
    \n-
    532
    \n-
    533 //copy communication: different row sizes for copy rows with the same global index
    \n-
    534 //are possible. If all values of current matrix row are sent, send
    \n-
    535 //std::numeric_limits<GlobalIndex>::max()
    \n-
    536 //and receiver will ignore it.
    \n-
    537 if (col==cont.matrix[i].end()) {
    \n-
    538 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n-
    539 return numlimits;
    \n-
    540 }
    \n-
    541 else {
    \n-
    542 const typename I::IndexPair* index=cont.idxset.pair(col.index());
    \n-
    543 assert(index);
    \n-
    544 // Only send index if col is no ghost
    \n-
    545 if ( index->local().attribute() != 2)
    \n-
    546 return index->global();
    \n-
    547 else {
    \n-
    548 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n-
    549 return numlimits;
    \n-
    550 }
    \n-
    551 }
    \n-
    552 }
    \n-
    553 static void scatter(Container& cont, const GlobalIndex& gi, std::size_t i, [[maybe_unused]] std::size_t j)
    \n-
    554 {
    \n-
    555 try{
    \n-
    556 if (gi != std::numeric_limits<GlobalIndex>::max()) {
    \n-
    557 const typename I::IndexPair& ip=cont.aggidxset.at(gi);
    \n-
    558 assert(ip.global()==gi);
    \n-
    559 std::size_t column = ip.local();
    \n-
    560 cont.sparsity[i].insert(column);
    \n-
    561
    \n-\n-
    563 if(!OwnerSet::contains(ip.local().attribute()))
    \n-
    564 // preserve symmetry for overlap
    \n-
    565 cont.sparsity[column].insert(i);
    \n-
    566 }
    \n-
    567 }
    \n-
    568 catch(const Dune::RangeError&) {
    \n-
    569 // Entry not present in the new index set. Ignore!
    \n-
    570#ifdef DEBUG_REPART
    \n-
    571 typedef typename Container::LookupIndexSet GlobalLookup;
    \n-
    572 typedef typename GlobalLookup::IndexPair IndexPair;
    \n-\n-
    574
    \n-
    575 GlobalLookup lookup(cont.aggidxset);
    \n-
    576 const IndexPair* pi=lookup.pair(i);
    \n-
    577 assert(pi);
    \n-
    578 if(OwnerSet::contains(pi->local().attribute())) {
    \n-
    579 int rank;
    \n-
    580 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    \n-
    581 std::cout<<rank<<cont.aggidxset<<std::endl;
    \n-
    582 std::cout<<rank<<": row "<<i<<" (global="<<gi <<") not in index set for owner index "<<pi->global()<<std::endl;
    \n-
    583 throw;
    \n-
    584 }
    \n-
    585#endif
    \n-
    586 }
    \n-
    587 }
    \n-
    588
    \n-
    589 };
    \n-
    590 template<class M, class I>
    \n-\n-
    592
    \n-
    593 template<class M, class I>
    \n-\n-
    595
    \n-
    596
    \n-
    597 template<class M, class I>
    \n-\n-
    599 {
    \n-
    600 typedef typename I::GlobalIndex GlobalIndex;
    \n-\n-
    602 typedef typename M::ConstColIterator ColIter;
    \n-
    603 typedef typename std::pair<GlobalIndex,typename M::block_type> Data;
    \n-
    604 static ColIter col;
    \n-\n-\n-
    607
    \n-
    608 static const Data& gather(const Container& cont, std::size_t i, std::size_t j)
    \n-
    609 {
    \n-
    610 if(j==0)
    \n-
    611 col=cont.matrix[i].begin();
    \n-
    612 else if (col!=cont.matrix[i].end())
    \n-
    613 ++col;
    \n-
    614 // copy communication: different row sizes for copy rows with the same global index
    \n-
    615 // are possible. If all values of current matrix row are sent, send
    \n-
    616 // std::numeric_limits<GlobalIndex>::max()
    \n-
    617 // and receiver will ignore it.
    \n-
    618 if (col==cont.matrix[i].end()) {
    \n-
    619 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n-\n-
    621 return datastore;
    \n-
    622 }
    \n-
    623 else {
    \n-
    624 // convert local column index to global index
    \n-
    625 const typename I::IndexPair* index=cont.idxset.pair(col.index());
    \n-
    626 assert(index);
    \n-
    627 // Store the data to prevent reference to temporary
    \n-
    628 // Only send index if col is no ghost
    \n-
    629 if ( index->local().attribute() != 2)
    \n-
    630 datastore = Data(index->global(),*col);
    \n-
    631 else {
    \n-
    632 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n-\n-
    634 }
    \n-
    635 return datastore;
    \n-
    636 }
    \n-
    637 }
    \n-
    638 static void scatter(Container& cont, const Data& data, std::size_t i, [[maybe_unused]] std::size_t j)
    \n-
    639 {
    \n-
    640 try{
    \n-
    641 if (data.first != std::numeric_limits<GlobalIndex>::max()) {
    \n-
    642 typename M::size_type column=cont.aggidxset.at(data.first).local();
    \n-
    643 cont.matrix[i][column]=data.second;
    \n-
    644 }
    \n-
    645 }
    \n-
    646 catch(const Dune::RangeError&) {
    \n-
    647 // This an overlap row and might therefore lack some entries!
    \n-
    648 }
    \n-
    649
    \n-
    650 }
    \n-
    651 };
    \n-
    652
    \n-
    653 template<class M, class I>
    \n-\n-
    655
    \n-
    656 template<class M, class I>
    \n-\n-
    658
    \n-
    659 template<class M, class I>
    \n-\n-
    661
    \n-
    662 template<typename M, typename C>
    \n-
    663 void redistributeSparsityPattern(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n-\n-
    665 {
    \n-
    666 typename C::CopySet copyflags;
    \n-
    667 typename C::OwnerSet ownerflags;
    \n-
    668 typedef typename C::ParallelIndexSet IndexSet;
    \n-\n-
    670 std::vector<typename M::size_type> rowsize(newComm.indexSet().size(), 0);
    \n-
    671 std::vector<typename M::size_type> copyrowsize(newComm.indexSet().size(), 0);
    \n-
    672 std::vector<typename M::size_type> backwardscopyrowsize(origComm.indexSet().size(), 0);
    \n-
    673
    \n-
    674 // get owner rowsizes
    \n-
    675 CommMatrixRowSize<M,RI> commRowSize(origMatrix, ri);
    \n-
    676 ri.template redistribute<MatrixRowSizeGatherScatter<M,IndexSet,RI> >(commRowSize,commRowSize);
    \n-
    677
    \n-
    678 origComm.buildGlobalLookup();
    \n-
    679
    \n-
    680 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n-
    681 rowsize[i] = ri.getRowSize(i);
    \n-
    682 }
    \n-
    683 // get sparsity pattern from owner rows
    \n-\n-
    685 origsp(origMatrix, origComm.globalLookup(), newComm.indexSet());
    \n-\n-
    687 newsp(origMatrix, origComm.globalLookup(), newComm.indexSet(), rowsize);
    \n-
    688
    \n-
    689 ri.template redistribute<MatrixSparsityPatternGatherScatter<M,IndexSet> >(origsp,newsp);
    \n-
    690
    \n-
    691 // build copy to owner interface to get missing matrix values for novlp case
    \n-\n-
    693 RemoteIndices<IndexSet> *ris = new RemoteIndices<IndexSet>(origComm.indexSet(),
    \n-
    694 newComm.indexSet(),
    \n-
    695 origComm.communicator());
    \n-
    696 ris->template rebuild<true>();
    \n-
    697
    \n-
    698 ri.getInterface().free();
    \n-
    699 ri.getInterface().build(*ris,copyflags,ownerflags);
    \n-
    700
    \n-
    701 // get copy rowsizes
    \n-
    702 CommMatrixRowSize<M,RI> commRowSize_copy(origMatrix, ri);
    \n-
    703 ri.template redistribute<MatrixCopyRowSizeGatherScatter<M,IndexSet,RI> >(commRowSize_copy,
    \n-
    704 commRowSize_copy);
    \n-
    705
    \n-
    706 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n-
    707 copyrowsize[i] = ri.getCopyRowSize(i);
    \n-
    708 }
    \n-
    709 //get copy rowsizes for sender
    \n-
    710 ri.redistributeBackward(backwardscopyrowsize,copyrowsize);
    \n-
    711 for (std::size_t i=0; i < origComm.indexSet().size(); i++) {
    \n-
    712 ri.getBackwardsCopyRowSize(i) = backwardscopyrowsize[i];
    \n-
    713 }
    \n-
    714
    \n-
    715 // get sparsity pattern from copy rows
    \n-
    716 CommMatrixSparsityPattern<M,IndexSet> origsp_copy(origMatrix,
    \n-
    717 origComm.globalLookup(),
    \n-
    718 newComm.indexSet(),
    \n-
    719 backwardscopyrowsize);
    \n-
    720 CommMatrixSparsityPattern<M,IndexSet> newsp_copy(origMatrix, origComm.globalLookup(),
    \n-
    721 newComm.indexSet(), copyrowsize);
    \n-
    722 ri.template redistribute<MatrixSparsityPatternGatherScatter<M,IndexSet> >(origsp_copy,
    \n-
    723 newsp_copy);
    \n-
    724
    \n-
    725 newsp.completeSparsityPattern(newsp_copy.sparsity);
    \n-
    726 newsp.storeSparsityPattern(newMatrix);
    \n-
    727 }
    \n-
    728 else
    \n-
    729 newsp.storeSparsityPattern(newMatrix);
    \n-
    730
    \n-
    731#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    732 // Check for symmetry
    \n-
    733 int ret=0;
    \n-
    734 typedef typename M::ConstRowIterator RIter;
    \n-
    735 for(RIter row=newMatrix.begin(), rend=newMatrix.end(); row != rend; ++row) {
    \n-
    736 typedef typename M::ConstColIterator CIter;
    \n-
    737 for(CIter col=row->begin(), cend=row->end(); col!=cend; ++col)
    \n-
    738 {
    \n-
    739 try{
    \n-
    740 newMatrix[col.index()][row.index()];
    \n-
    741 }catch(const Dune::ISTLError&) {
    \n-
    742 std::cerr<<newComm.communicator().rank()<<": entry ("
    \n-
    743 <<col.index()<<","<<row.index()<<") missing! for symmetry!"<<std::endl;
    \n-
    744 ret=1;
    \n-
    745
    \n-
    746 }
    \n-
    747
    \n-
    748 }
    \n-
    749 }
    \n-
    750
    \n-
    751 if(ret)
    \n-
    752 DUNE_THROW(ISTLError, "Matrix not symmetric!");
    \n-
    753#endif
    \n-
    754 }
    \n-
    755
    \n-
    756 template<typename M, typename C>
    \n-
    757 void redistributeMatrixEntries(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n-\n-
    759 {
    \n-
    760 typedef typename C::ParallelIndexSet IndexSet;
    \n-
    761 typename C::OwnerSet ownerflags;
    \n-
    762 std::vector<typename M::size_type> rowsize(newComm.indexSet().size(), 0);
    \n-
    763 std::vector<typename M::size_type> copyrowsize(newComm.indexSet().size(), 0);
    \n-
    764 std::vector<typename M::size_type> backwardscopyrowsize(origComm.indexSet().size(), 0);
    \n-
    765
    \n-
    766 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n-
    767 rowsize[i] = ri.getRowSize(i);
    \n-\n-
    769 copyrowsize[i] = ri.getCopyRowSize(i);
    \n-
    770 }
    \n-
    771 }
    \n-
    772
    \n-
    773 for (std::size_t i=0; i < origComm.indexSet().size(); i++)
    \n-\n-
    775 backwardscopyrowsize[i] = ri.getBackwardsCopyRowSize(i);
    \n-
    776
    \n-
    777
    \n-\n-
    779 // fill sparsity pattern from copy rows
    \n-
    780 CommMatrixRow<M,IndexSet> origrow_copy(origMatrix, origComm.globalLookup(),
    \n-
    781 newComm.indexSet(), backwardscopyrowsize);
    \n-
    782 CommMatrixRow<M,IndexSet> newrow_copy(newMatrix, origComm.globalLookup(),
    \n-
    783 newComm.indexSet(),copyrowsize);
    \n-
    784 ri.template redistribute<MatrixRowGatherScatter<M,IndexSet> >(origrow_copy,
    \n-
    785 newrow_copy);
    \n-
    786 ri.getInterface().free();
    \n-
    787 RemoteIndices<IndexSet> *ris = new RemoteIndices<IndexSet>(origComm.indexSet(),
    \n-
    788 newComm.indexSet(),
    \n-
    789 origComm.communicator());
    \n-
    790 ris->template rebuild<true>();
    \n-
    791 ri.getInterface().build(*ris,ownerflags,ownerflags);
    \n-
    792 }
    \n-
    793
    \n-\n-
    795 origrow(origMatrix, origComm.globalLookup(), newComm.indexSet());
    \n-\n-
    797 newrow(newMatrix, origComm.globalLookup(), newComm.indexSet(),rowsize);
    \n-
    798 ri.template redistribute<MatrixRowGatherScatter<M,IndexSet> >(origrow,newrow);
    \n-
    799 if (SolverCategory::category(origComm) != static_cast<int>(SolverCategory::nonoverlapping))
    \n-\n-
    801 }
    \n-
    802
    \n-
    819 template<typename M, typename C>
    \n-
    820 void redistributeMatrix(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n-\n-
    822 {
    \n-
    823 ri.setNoRows(newComm.indexSet().size());
    \n-
    824 ri.setNoCopyRows(newComm.indexSet().size());
    \n-
    825 ri.setNoBackwardsCopyRows(origComm.indexSet().size());
    \n-
    826 redistributeSparsityPattern(origMatrix, newMatrix, origComm, newComm, ri);
    \n-
    827 redistributeMatrixEntries(origMatrix, newMatrix, origComm, newComm, ri);
    \n-
    828 }
    \n-
    829#endif
    \n-
    830
    \n-
    831template<typename M>
    \n-
    832 void redistributeMatrixEntries(M& origMatrix, M& newMatrix,
    \n-\n-\n-\n-
    836 {
    \n-
    837 DUNE_THROW(InvalidStateException, "Trying to redistribute in sequential program!");
    \n-
    838 }
    \n-
    839 template<typename M>
    \n-
    840 void redistributeMatrix(M& origMatrix, M& newMatrix,
    \n-\n-\n-\n-
    844 {
    \n-
    845 DUNE_THROW(InvalidStateException, "Trying to redistribute in sequential program!");
    \n-
    846 }
    \n-
    847}
    \n-
    848#endif
    \n-
    Functionality for redistributing a parallel index set using graph partitioning.
    \n-\n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    5#ifndef DUNE_ISTL_SOLVERTYPE_HH
    \n+
    6#define DUNE_ISTL_SOLVERTYPE_HH
    \n+
    7
    \n+
    12namespace Dune
    \n+
    13{
    \n+
    14 template<typename Solver>
    \n+\n+
    16 {
    \n+
    17 enum
    \n+
    18 {
    \n+
    24 value =false
    \n+
    25 };
    \n+
    26 };
    \n+
    27
    \n+
    28 template<typename Solver>
    \n+\n+
    30 {
    \n+
    31 enum
    \n+
    32 {
    \n+
    36 value = false
    \n+
    37 };
    \n+
    38 };
    \n+
    39} // end namespace Dune
    \n+
    40#endif
    \n
    Definition: allocator.hh:11
    \n-
    void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:757
    \n-
    void redistributeSparsityPattern(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:663
    \n-
    void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Redistribute a matrix according to given domain decompositions.
    Definition: matrixredistribute.hh:820
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Definition: matrixredistribute.hh:22
    \n-
    void setNoBackwardsCopyRows(std::size_t size)
    Definition: matrixredistribute.hh:44
    \n-
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:28
    \n-
    void resetSetup()
    Definition: matrixredistribute.hh:35
    \n-
    void setNoCopyRows(std::size_t size)
    Definition: matrixredistribute.hh:41
    \n-
    bool isSetup() const
    Definition: matrixredistribute.hh:23
    \n-
    void setNoRows(std::size_t size)
    Definition: matrixredistribute.hh:38
    \n-
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:32
    \n-
    std::size_t getBackwardsCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:57
    \n-
    std::size_t getRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:47
    \n-
    std::size_t getCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:52
    \n-
    std::size_t getRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:158
    \n-
    std::size_t & getBackwardsCopyRowSize(std::size_t index)
    Definition: matrixredistribute.hh:173
    \n-
    RedistributeInterface & getInterface()
    Definition: matrixredistribute.hh:75
    \n-
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:136
    \n-
    void setNoBackwardsCopyRows(std::size_t rows)
    Definition: matrixredistribute.hh:193
    \n-
    std::size_t & getCopyRowSize(std::size_t index)
    Definition: matrixredistribute.hh:163
    \n-\n-
    std::size_t getCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:168
    \n-
    void setNoRows(std::size_t rows)
    Definition: matrixredistribute.hh:183
    \n-
    void reserve(std::size_t size)
    Definition: matrixredistribute.hh:150
    \n-
    OwnerOverlapCopyCommunication< T, T1 > Comm
    Definition: matrixredistribute.hh:69
    \n-
    void setNoCopyRows(std::size_t rows)
    Definition: matrixredistribute.hh:188
    \n-
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:141
    \n-\n-
    std::size_t getBackwardsCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:178
    \n-
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:118
    \n-\n-
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:126
    \n-
    void checkInterface(const IS &source, const IS &target, MPI_Comm comm)
    Definition: matrixredistribute.hh:80
    \n-
    bool isSetup() const
    Definition: matrixredistribute.hh:145
    \n-
    std::size_t & getRowSize(std::size_t index)
    Definition: matrixredistribute.hh:153
    \n-
    Utility class to communicate and set the row sizes of a redistributed matrix.
    Definition: matrixredistribute.hh:216
    \n-
    M::size_type size_type
    Definition: matrixredistribute.hh:219
    \n-
    M::size_type value_type
    Definition: matrixredistribute.hh:218
    \n-
    RI & rowsize
    Definition: matrixredistribute.hh:230
    \n-
    const M & matrix
    Definition: matrixredistribute.hh:229
    \n-
    CommMatrixRowSize(const M &m_, RI &rowsize_)
    Constructor.
    Definition: matrixredistribute.hh:226
    \n-
    Utility class to communicate and build the sparsity pattern of a redistributed matrix.
    Definition: matrixredistribute.hh:245
    \n-
    M::size_type size_type
    Definition: matrixredistribute.hh:246
    \n-
    const Dune::GlobalLookupIndexSet< I > & idxset
    Definition: matrixredistribute.hh:356
    \n-
    void storeSparsityPattern(M &m)
    Creates and stores the sparsity pattern of the redistributed matrix.
    Definition: matrixredistribute.hh:276
    \n-
    const I & aggidxset
    Definition: matrixredistribute.hh:357
    \n-
    const std::vector< size_type > * rowsize
    Definition: matrixredistribute.hh:359
    \n-
    void completeSparsityPattern(std::vector< std::set< size_type > > add_sparsity)
    Completes the sparsity pattern of the redistributed matrix with data from copy rows for the novlp cas...
    Definition: matrixredistribute.hh:340
    \n-
    CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_)
    Constructor for the original side.
    Definition: matrixredistribute.hh:254
    \n-
    const M & matrix
    Definition: matrixredistribute.hh:354
    \n-
    CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_, const std::vector< typename M::size_type > &rowsize_)
    Constructor for the redistruted side.
    Definition: matrixredistribute.hh:265
    \n-
    std::vector< std::set< size_type > > sparsity
    Definition: matrixredistribute.hh:358
    \n-
    Dune::GlobalLookupIndexSet< I > LookupIndexSet
    Definition: matrixredistribute.hh:355
    \n-
    static M::size_type getSize(const Type &t, std::size_t i)
    Definition: matrixredistribute.hh:376
    \n-
    CommMatrixSparsityPattern< M, I > Type
    Definition: matrixredistribute.hh:365
    \n-
    I::GlobalIndex IndexedType
    The indexed type we send. This is the global index indentitfying the column.
    Definition: matrixredistribute.hh:371
    \n-
    VariableSize IndexedTypeFlag
    Each row varies in size.
    Definition: matrixredistribute.hh:374
    \n-
    Utility class for comunicating the matrix entries.
    Definition: matrixredistribute.hh:396
    \n-
    std::vector< size_t > * rowsize
    row size information for the receiving side.
    Definition: matrixredistribute.hh:452
    \n-
    M & matrix
    The matrix to communicate the values of.
    Definition: matrixredistribute.hh:446
    \n-
    CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_, std::vector< size_t > &rowsize_)
    Constructor.
    Definition: matrixredistribute.hh:412
    \n-
    const Dune::GlobalLookupIndexSet< I > & idxset
    Index set for the original matrix.
    Definition: matrixredistribute.hh:448
    \n-
    void setOverlapRowsToDirichlet()
    Sets the non-owner rows correctly as Dirichlet boundaries.
    Definition: matrixredistribute.hh:421
    \n-
    const I & aggidxset
    Index set for the redistributed matrix.
    Definition: matrixredistribute.hh:450
    \n-
    CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_)
    Constructor.
    Definition: matrixredistribute.hh:405
    \n-
    std::pair< typename I::GlobalIndex, typename M::block_type > IndexedType
    The indexed type we send. This is the pair of global index indentitfying the column and the value its...
    Definition: matrixredistribute.hh:464
    \n-
    CommMatrixRow< M, I > Type
    Definition: matrixredistribute.hh:458
    \n-
    static std::size_t getSize(const Type &t, std::size_t i)
    Definition: matrixredistribute.hh:469
    \n-
    VariableSize IndexedTypeFlag
    Each row varies in size.
    Definition: matrixredistribute.hh:467
    \n-
    Definition: matrixredistribute.hh:483
    \n-
    static void scatter(Container &cont, const typename M::size_type &rowsize, std::size_t i)
    Definition: matrixredistribute.hh:490
    \n-
    static const M::size_type gather(const Container &cont, std::size_t i)
    Definition: matrixredistribute.hh:486
    \n-
    CommMatrixRowSize< M, RI > Container
    Definition: matrixredistribute.hh:484
    \n-
    Definition: matrixredistribute.hh:500
    \n-
    static const M::size_type gather(const Container &cont, std::size_t i)
    Definition: matrixredistribute.hh:503
    \n-
    static void scatter(Container &cont, const typename M::size_type &rowsize, std::size_t i)
    Definition: matrixredistribute.hh:507
    \n-
    CommMatrixRowSize< M, RI > Container
    Definition: matrixredistribute.hh:501
    \n-
    Definition: matrixredistribute.hh:518
    \n-
    M::ConstColIterator ColIter
    Definition: matrixredistribute.hh:521
    \n-
    static void scatter(Container &cont, const GlobalIndex &gi, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:553
    \n-
    CommMatrixSparsityPattern< M, I > Container
    Definition: matrixredistribute.hh:520
    \n-
    static GlobalIndex numlimits
    Definition: matrixredistribute.hh:524
    \n-
    static ColIter col
    Definition: matrixredistribute.hh:523
    \n-
    I::GlobalIndex GlobalIndex
    Definition: matrixredistribute.hh:519
    \n-
    static const GlobalIndex & gather(const Container &cont, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:526
    \n-
    Definition: matrixredistribute.hh:599
    \n-
    I::GlobalIndex GlobalIndex
    Definition: matrixredistribute.hh:600
    \n-
    static Data datastore
    Definition: matrixredistribute.hh:605
    \n-
    static GlobalIndex numlimits
    Definition: matrixredistribute.hh:606
    \n-
    M::ConstColIterator ColIter
    Definition: matrixredistribute.hh:602
    \n-
    static const Data & gather(const Container &cont, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:608
    \n-
    std::pair< GlobalIndex, typename M::block_type > Data
    Definition: matrixredistribute.hh:603
    \n-
    static void scatter(Container &cont, const Data &data, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:638
    \n-
    static ColIter col
    Definition: matrixredistribute.hh:604
    \n-
    CommMatrixRow< M, I > Container
    Definition: matrixredistribute.hh:601
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet
    Definition: owneroverlapcopy.hh:194
    \n-
    Definition: pinfo.hh:28
    \n-
    Definition: repartition.hh:260
    \n-
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    Definition: solvertype.hh:16
    \n+
    @ value
    Whether this is a direct solver.
    Definition: solvertype.hh:24
    \n+
    Definition: solvertype.hh:30
    \n+
    @ value
    whether the solver internally uses column compressed storage
    Definition: solvertype.hh:36
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1180 +4,55 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrixredistribute.hh\n+solvertype.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIXREDISTRIBUTE_HH\n- 6#define DUNE_ISTL_MATRIXREDISTRIBUTE_HH\n- 7#include \n- 8#include \"repartition.hh\"\n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 18namespace Dune\n- 19{\n- 20 template\n-21 struct RedistributeInformation\n- 22 {\n-23 bool isSetup() const\n- 24 {\n- 25 return false;\n- 26 }\n- 27 template\n-28 void redistribute([[maybe_unused]] const D& from, [[maybe_unused]] D& to)\n-const\n- 29 {}\n- 30\n- 31 template\n-32 void redistributeBackward([[maybe_unused]] D& from, [[maybe_unused]]const D&\n-to) const\n- 33 {}\n- 34\n-35 void resetSetup()\n- 36 {}\n- 37\n-38 void setNoRows([[maybe_unused]] std::size_t size)\n- 39 {}\n- 40\n-41 void setNoCopyRows([[maybe_unused]] std::size_t size)\n- 42 {}\n- 43\n-44 void setNoBackwardsCopyRows([[maybe_unused]] std::size_t size)\n- 45 {}\n- 46\n-47 std::size_t getRowSize([[maybe_unused]] std::size_t index) const\n- 48 {\n- 49 return -1;\n- 50 }\n- 51\n-52 std::size_t getCopyRowSize([[maybe_unused]] std::size_t index) const\n- 53 {\n- 54 return -1;\n- 55 }\n- 56\n-57 std::size_t getBackwardsCopyRowSize([[maybe_unused]] std::size_t index)\n-const\n- 58 {\n- 59 return -1;\n- 60 }\n- 61\n- 62 };\n- 63\n- 64#if HAVE_MPI\n- 65 template\n-66 class RedistributeInformation >\n- 67 {\n- 68 public:\n-69 typedef OwnerOverlapCopyCommunication Comm;\n- 70\n-71 RedistributeInformation()\n- 72 : interface(), setup_(false)\n- 73 {}\n- 74\n-75 RedistributeInterface& getInterface()\n- 76 {\n- 77 return interface;\n- 78 }\n- 79 template\n-80 void checkInterface(const IS& source,\n- 81 const IS& target, MPI_Comm comm)\n- 82 {\n- 83 auto ri = std::make_unique >(source, target, comm);\n- 84 ri->template rebuild();\n- 85 Interface inf;\n- 86 typename OwnerOverlapCopyCommunication::OwnerSet flags;\n- 87 int rank;\n- 88 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n- 89 inf.free();\n- 90 inf.build(*ri, flags, flags);\n- 91\n- 92\n- 93#ifdef DEBUG_REPART\n- 94 if(inf!=interface) {\n- 95\n- 96 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n- 97 if(rank==0)\n- 98 std::cout<<\"Interfaces do not match!\"<\n-118 void redistribute(const D& from, D& to) const\n- 119 {\n- 120 BufferedCommunicator communicator;\n- 121 communicator.template build(from,to, interface);\n- 122 communicator.template forward(from, to);\n- 123 communicator.free();\n- 124 }\n- 125 template\n-126 void redistributeBackward(D& from, const D& to) const\n- 127 {\n- 128\n- 129 BufferedCommunicator communicator;\n- 130 communicator.template build(from,to, interface);\n- 131 communicator.template backward(from, to);\n- 132 communicator.free();\n- 133 }\n- 134\n- 135 template\n-136 void redistribute(const D& from, D& to) const\n- 137 {\n- 138 redistribute >(from,to);\n- 139 }\n- 140 template\n-141 void redistributeBackward(D& from, const D& to) const\n- 142 {\n- 143 redistributeBackward >(from,to);\n- 144 }\n-145 bool isSetup() const\n- 146 {\n- 147 return setup_;\n- 148 }\n- 149\n-150 void reserve(std::size_t size)\n- 151 {}\n- 152\n-153 std::size_t& getRowSize(std::size_t index)\n- 154 {\n- 155 return rowSize[index];\n- 156 }\n- 157\n-158 std::size_t getRowSize(std::size_t index) const\n- 159 {\n- 160 return rowSize[index];\n- 161 }\n- 162\n-163 std::size_t& getCopyRowSize(std::size_t index)\n- 164 {\n- 165 return copyrowSize[index];\n- 166 }\n- 167\n-168 std::size_t getCopyRowSize(std::size_t index) const\n- 169 {\n- 170 return copyrowSize[index];\n- 171 }\n- 172\n-173 std::size_t& getBackwardsCopyRowSize(std::size_t index)\n- 174 {\n- 175 return backwardscopyrowSize[index];\n- 176 }\n- 177\n-178 std::size_t getBackwardsCopyRowSize(std::size_t index) const\n- 179 {\n- 180 return backwardscopyrowSize[index];\n- 181 }\n- 182\n-183 void setNoRows(std::size_t rows)\n- 184 {\n- 185 rowSize.resize(rows, 0);\n- 186 }\n- 187\n-188 void setNoCopyRows(std::size_t rows)\n- 189 {\n- 190 copyrowSize.resize(rows, 0);\n- 191 }\n- 192\n-193 void setNoBackwardsCopyRows(std::size_t rows)\n- 194 {\n- 195 backwardscopyrowSize.resize(rows, 0);\n- 196 }\n- 197\n- 198 private:\n- 199 std::vector rowSize;\n- 200 std::vector copyrowSize;\n- 201 std::vector backwardscopyrowSize;\n- 202 RedistributeInterface interface;\n- 203 bool setup_;\n- 204 };\n- 205\n- 214 template\n-215 struct CommMatrixRowSize\n- 216 {\n- 217 // Make the default communication policy work.\n-218 typedef typename M::size_type value_type;\n-219 typedef typename M::size_type size_type;\n- 220\n-226 CommMatrixRowSize(const M& m_, RI& rowsize_)\n- 227 : matrix(m_), rowsize(rowsize_)\n- 228 {}\n-229 const M& matrix;\n-230 RI& rowsize;\n- 231\n- 232 };\n- 233\n- 234\n- 243 template\n-244 struct CommMatrixSparsityPattern\n- 245 {\n-246 typedef typename M::size_type size_type;\n- 247\n-254 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet&\n-idxset_, const I& aggidxset_)\n- 255 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()\n- 256 {}\n- 257\n-265 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet&\n-idxset_, const I& aggidxset_,\n- 266 const std::vector& rowsize_)\n- 267 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), sparsity\n-(aggidxset_.size()), rowsize(&rowsize_)\n- 268 {}\n- 269\n-276 void storeSparsityPattern(M& m)\n- 277 {\n- 278 // insert diagonal to overlap rows\n- 279 typedef typename Dune::GlobalLookupIndexSet::const_iterator IIter;\n- 280 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n-OwnerSet;\n- 281 std::size_t nnz=0;\n- 282#ifdef DEBUG_REPART\n- 283 int rank;\n- 284\n- 285 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n- 286#endif\n- 287 for(IIter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i) {\n- 288 if(!OwnerSet::contains(i->local().attribute())) {\n- 289#ifdef DEBUG_REPART\n- 290 std::cout<local()<local()].insert(i->local());\n- 293 }\n- 294\n- 295 nnz+=sparsity[i->local()].size();\n- 296 }\n- 297 assert( aggidxset.size()==sparsity.size());\n- 298\n- 299 if(nnz>0) {\n- 300 m.setSize(aggidxset.size(), aggidxset.size(), nnz);\n- 301 m.setBuildMode(M::row_wise);\n- 302 typename M::CreateIterator citer=m.createbegin();\n- 303#ifdef DEBUG_REPART\n- 304 std::size_t idx=0;\n- 305 bool correct=true;\n- 306 Dune::GlobalLookupIndexSet global(aggidxset);\n- 307#endif\n- 308 typedef typename std::vector >::const_iterator Iter;\n- 309 for(Iter i=sparsity.begin(), end=sparsity.end(); i!=end; ++i, ++citer)\n- 310 {\n- 311 typedef typename std::set::const_iterator SIter;\n- 312 for(SIter si=i->begin(), send=i->end(); si!=send; ++si)\n- 313 citer.insert(*si);\n- 314#ifdef DEBUG_REPART\n- 315 if(i->find(idx)==i->end()) {\n- 316 const typename I::IndexPair* gi=global.pair(idx);\n- 317 assert(gi);\n- 318 std::cout<global()<<\" attr=\"<local().attribute()<<\" \"<<\n- 319 OwnerSet::contains(gi->local().attribute())<<\n- 320 \" row size=\"<size()< >\n-add_sparsity)\n- 341 {\n- 342 for (unsigned int i = 0; i != sparsity.size(); ++i) {\n- 343 if (add_sparsity[i].size() != 0) {\n- 344 typedef std::set Set;\n- 345 Set tmp_set;\n- 346 std::insert_iterator tmp_insert (tmp_set, tmp_set.begin());\n- 347 std::set_union(add_sparsity[i].begin(), add_sparsity[i].end(),\n- 348 sparsity[i].begin(), sparsity[i].end(), tmp_insert);\n- 349 sparsity[i].swap(tmp_set);\n- 350 }\n- 351 }\n- 352 }\n- 353\n-354 const M& matrix;\n-355 typedef Dune::GlobalLookupIndexSet LookupIndexSet;\n-356 const Dune::GlobalLookupIndexSet& idxset;\n-357 const I& aggidxset;\n-358 std::vector > sparsity;\n-359 const std::vector* rowsize;\n- 360 };\n- 361\n- 362 template\n-363 struct CommPolicy >\n- 364 {\n-365 typedef CommMatrixSparsityPattern Type;\n- 366\n-371 typedef typename I::GlobalIndex IndexedType;\n- 372\n-374 typedef VariableSize IndexedTypeFlag;\n- 375\n-376 static typename M::size_type getSize(const Type& t, std::size_t i)\n- 377 {\n- 378 if(!t.rowsize)\n- 379 return t.matrix[i].size();\n- 380 else\n- 381 {\n- 382 assert((*t.rowsize)[i]>0);\n- 383 return (*t.rowsize)[i];\n- 384 }\n- 385 }\n- 386 };\n- 387\n- 394 template\n-395 struct CommMatrixRow\n- 396 {\n-405 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet& idxset_, const I&\n-aggidxset_)\n- 406 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()\n- 407 {}\n- 408\n-412 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet& idxset_, const I&\n-aggidxset_,\n- 413 std::vector& rowsize_)\n- 414 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize(&rowsize_)\n- 415 {}\n-421 void setOverlapRowsToDirichlet()\n- 422 {\n- 423 typedef typename Dune::GlobalLookupIndexSet::const_iterator Iter;\n- 424 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n-OwnerSet;\n- 425\n- 426 for(Iter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i)\n- 427 if(!OwnerSet::contains(i->local().attribute())) {\n- 428 // Set to Dirchlet\n- 429 typedef typename M::ColIterator CIter;\n- 430 for(CIter c=matrix[i->local()].begin(), cend= matrix[i->local()].end();\n- 431 c!= cend; ++c)\n- 432 {\n- 433 *c=0;\n- 434 if(c.index()==i->local()) {\n- 435 auto setDiagonal = [](auto&& scalarOrMatrix, const auto& value) {\n- 436 auto&& matrixView = Dune::Impl::asMatrix(scalarOrMatrix);\n- 437 for (auto rowIt = matrixView.begin(); rowIt != matrixView.end(); ++rowIt)\n- 438 (*rowIt)[rowIt.index()] = value;\n- 439 };\n- 440 setDiagonal(*c, 1);\n- 441 }\n- 442 }\n- 443 }\n- 444 }\n-446 M& matrix;\n-448 const Dune::GlobalLookupIndexSet& idxset;\n-450 const I& aggidxset;\n-452 std::vector* rowsize; // row sizes differ from sender side in\n-overlap!\n- 453 };\n- 454\n- 455 template\n-456 struct CommPolicy >\n- 457 {\n-458 typedef CommMatrixRow Type;\n- 459\n-464 typedef std::pair\n-IndexedType;\n- 465\n-467 typedef VariableSize IndexedTypeFlag;\n- 468\n-469 static std::size_t getSize(const Type& t, std::size_t i)\n- 470 {\n- 471 if(!t.rowsize)\n- 472 return t.matrix[i].size();\n- 473 else\n- 474 {\n- 475 assert((*t.rowsize)[i]>0);\n- 476 return (*t.rowsize)[i];\n- 477 }\n- 478 }\n- 479 };\n- 480\n- 481 template\n-482 struct MatrixRowSizeGatherScatter\n- 483 {\n-484 typedef CommMatrixRowSize Container;\n- 485\n-486 static const typename M::size_type gather(const Container& cont, std::\n-size_t i)\n- 487 {\n- 488 return cont.matrix[i].size();\n- 489 }\n-490 static void scatter(Container& cont, const typename M::size_type& rowsize,\n-std::size_t i)\n- 491 {\n- 492 assert(rowsize);\n- 493 cont.rowsize.getRowSize(i)=rowsize;\n- 494 }\n- 495\n- 496 };\n- 497\n- 498 template\n-499 struct MatrixCopyRowSizeGatherScatter\n- 500 {\n-501 typedef CommMatrixRowSize Container;\n- 502\n-503 static const typename M::size_type gather(const Container& cont, std::\n-size_t i)\n- 504 {\n- 505 return cont.matrix[i].size();\n- 506 }\n-507 static void scatter(Container& cont, const typename M::size_type& rowsize,\n-std::size_t i)\n- 508 {\n- 509 assert(rowsize);\n- 510 if (rowsize > cont.rowsize.getCopyRowSize(i))\n- 511 cont.rowsize.getCopyRowSize(i)=rowsize;\n- 512 }\n- 513\n- 514 };\n- 515\n- 516 template\n-517 struct MatrixSparsityPatternGatherScatter\n- 518 {\n-519 typedef typename I::GlobalIndex GlobalIndex;\n-520 typedef CommMatrixSparsityPattern Container;\n-521 typedef typename M::ConstColIterator ColIter;\n- 522\n-523 static ColIter col;\n-524 static GlobalIndex numlimits;\n- 525\n-526 static const GlobalIndex& gather(const Container& cont, std::size_t i,\n-std::size_t j)\n- 527 {\n- 528 if(j==0)\n- 529 col=cont.matrix[i].begin();\n- 530 else if (col!=cont.matrix[i].end())\n- 531 ++col;\n- 532\n- 533 //copy communication: different row sizes for copy rows with the same\n-global index\n- 534 //are possible. If all values of current matrix row are sent, send\n- 535 //std::numeric_limits::max()\n- 536 //and receiver will ignore it.\n- 537 if (col==cont.matrix[i].end()) {\n- 538 numlimits = std::numeric_limits::max();\n- 539 return numlimits;\n- 540 }\n- 541 else {\n- 542 const typename I::IndexPair* index=cont.idxset.pair(col.index());\n- 543 assert(index);\n- 544 // Only send index if col is no ghost\n- 545 if ( index->local().attribute() != 2)\n- 546 return index->global();\n- 547 else {\n- 548 numlimits = std::numeric_limits::max();\n- 549 return numlimits;\n- 550 }\n- 551 }\n- 552 }\n-553 static void scatter(Container& cont, const GlobalIndex& gi, std::size_t i,\n-[[maybe_unused]] std::size_t j)\n- 554 {\n- 555 try{\n- 556 if (gi != std::numeric_limits::max()) {\n- 557 const typename I::IndexPair& ip=cont.aggidxset.at(gi);\n- 558 assert(ip.global()==gi);\n- 559 std::size_t column = ip.local();\n- 560 cont.sparsity[i].insert(column);\n- 561\n- 562 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n-OwnerSet;\n- 563 if(!OwnerSet::contains(ip.local().attribute()))\n- 564 // preserve symmetry for overlap\n- 565 cont.sparsity[column].insert(i);\n- 566 }\n- 567 }\n- 568 catch(const Dune::RangeError&) {\n- 569 // Entry not present in the new index set. Ignore!\n- 570#ifdef DEBUG_REPART\n- 571 typedef typename Container::LookupIndexSet GlobalLookup;\n- 572 typedef typename GlobalLookup::IndexPair IndexPair;\n- 573 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n-OwnerSet;\n- 574\n- 575 GlobalLookup lookup(cont.aggidxset);\n- 576 const IndexPair* pi=lookup.pair(i);\n- 577 assert(pi);\n- 578 if(OwnerSet::contains(pi->local().attribute())) {\n- 579 int rank;\n- 580 MPI_Comm_rank(MPI_COMM_WORLD,&rank);\n- 581 std::cout<global()<\n- 591 typename MatrixSparsityPatternGatherScatter::ColIter\n-MatrixSparsityPatternGatherScatter::col;\n- 592\n- 593 template\n- 594 typename MatrixSparsityPatternGatherScatter::GlobalIndex\n-MatrixSparsityPatternGatherScatter::numlimits;\n- 595\n- 596\n- 597 template\n-598 struct MatrixRowGatherScatter\n- 599 {\n-600 typedef typename I::GlobalIndex GlobalIndex;\n-601 typedef CommMatrixRow Container;\n-602 typedef typename M::ConstColIterator ColIter;\n-603 typedef typename std::pair Data;\n-604 static ColIter col;\n-605 static Data datastore;\n-606 static GlobalIndex numlimits;\n- 607\n-608 static const Data& gather(const Container& cont, std::size_t i, std::size_t\n-j)\n- 609 {\n- 610 if(j==0)\n- 611 col=cont.matrix[i].begin();\n- 612 else if (col!=cont.matrix[i].end())\n- 613 ++col;\n- 614 // copy communication: different row sizes for copy rows with the same\n-global index\n- 615 // are possible. If all values of current matrix row are sent, send\n- 616 // std::numeric_limits::max()\n- 617 // and receiver will ignore it.\n- 618 if (col==cont.matrix[i].end()) {\n- 619 numlimits = std::numeric_limits::max();\n- 620 datastore = Data(numlimits,*col);\n- 621 return datastore;\n- 622 }\n- 623 else {\n- 624 // convert local column index to global index\n- 625 const typename I::IndexPair* index=cont.idxset.pair(col.index());\n- 626 assert(index);\n- 627 // Store the data to prevent reference to temporary\n- 628 // Only send index if col is no ghost\n- 629 if ( index->local().attribute() != 2)\n- 630 datastore = Data(index->global(),*col);\n- 631 else {\n- 632 numlimits = std::numeric_limits::max();\n- 633 datastore = Data(numlimits,*col);\n- 634 }\n- 635 return datastore;\n- 636 }\n- 637 }\n-638 static void scatter(Container& cont, const Data& data, std::size_t i, [\n-[maybe_unused]] std::size_t j)\n- 639 {\n- 640 try{\n- 641 if (data.first != std::numeric_limits::max()) {\n- 642 typename M::size_type column=cont.aggidxset.at(data.first).local();\n- 643 cont.matrix[i][column]=data.second;\n- 644 }\n- 645 }\n- 646 catch(const Dune::RangeError&) {\n- 647 // This an overlap row and might therefore lack some entries!\n- 648 }\n- 649\n- 650 }\n- 651 };\n- 652\n- 653 template\n- 654 typename MatrixRowGatherScatter::ColIter\n-MatrixRowGatherScatter::col;\n- 655\n- 656 template\n- 657 typename MatrixRowGatherScatter::Data MatrixRowGatherScatter::\n-datastore;\n- 658\n- 659 template\n- 660 typename MatrixRowGatherScatter::GlobalIndex\n-MatrixRowGatherScatter::numlimits;\n- 661\n- 662 template\n-663 void redistributeSparsityPattern(M& origMatrix, M& newMatrix, C& origComm,\n-C& newComm,\n- 664 RedistributeInformation& ri)\n- 665 {\n- 666 typename C::CopySet copyflags;\n- 667 typename C::OwnerSet ownerflags;\n- 668 typedef typename C::ParallelIndexSet IndexSet;\n- 669 typedef RedistributeInformation RI;\n- 670 std::vector rowsize(newComm.indexSet().size(), 0);\n- 671 std::vector copyrowsize(newComm.indexSet().size(),\n-0);\n- 672 std::vector backwardscopyrowsize(origComm.indexSet\n-().size(), 0);\n- 673\n- 674 // get owner rowsizes\n- 675 CommMatrixRowSize commRowSize(origMatrix, ri);\n- 676 ri.template redistribute >\n-(commRowSize,commRowSize);\n- 677\n- 678 origComm.buildGlobalLookup();\n- 679\n- 680 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n- 681 rowsize[i] = ri.getRowSize(i);\n- 682 }\n- 683 // get sparsity pattern from owner rows\n- 684 CommMatrixSparsityPattern\n- 685 origsp(origMatrix, origComm.globalLookup(), newComm.indexSet());\n- 686 CommMatrixSparsityPattern\n- 687 newsp(origMatrix, origComm.globalLookup(), newComm.indexSet(), rowsize);\n- 688\n- 689 ri.template redistribute >\n-(origsp,newsp);\n- 690\n- 691 // build copy to owner interface to get missing matrix values for novlp\n-case\n- 692 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n-{\n- 693 RemoteIndices *ris = new RemoteIndices\n-(origComm.indexSet(),\n- 694 newComm.indexSet(),\n- 695 origComm.communicator());\n- 696 ris->template rebuild();\n- 697\n- 698 ri.getInterface().free();\n- 699 ri.getInterface().build(*ris,copyflags,ownerflags);\n- 700\n- 701 // get copy rowsizes\n- 702 CommMatrixRowSize commRowSize_copy(origMatrix, ri);\n- 703 ri.template redistribute >\n-(commRowSize_copy,\n- 704 commRowSize_copy);\n- 705\n- 706 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n- 707 copyrowsize[i] = ri.getCopyRowSize(i);\n- 708 }\n- 709 //get copy rowsizes for sender\n- 710 ri.redistributeBackward(backwardscopyrowsize,copyrowsize);\n- 711 for (std::size_t i=0; i < origComm.indexSet().size(); i++) {\n- 712 ri.getBackwardsCopyRowSize(i) = backwardscopyrowsize[i];\n- 713 }\n- 714\n- 715 // get sparsity pattern from copy rows\n- 716 CommMatrixSparsityPattern origsp_copy(origMatrix,\n- 717 origComm.globalLookup(),\n- 718 newComm.indexSet(),\n- 719 backwardscopyrowsize);\n- 720 CommMatrixSparsityPattern newsp_copy(origMatrix,\n-origComm.globalLookup(),\n- 721 newComm.indexSet(), copyrowsize);\n- 722 ri.template redistribute >\n-(origsp_copy,\n- 723 newsp_copy);\n- 724\n- 725 newsp.completeSparsityPattern(newsp_copy.sparsity);\n- 726 newsp.storeSparsityPattern(newMatrix);\n- 727 }\n- 728 else\n- 729 newsp.storeSparsityPattern(newMatrix);\n- 730\n- 731#ifdef DUNE_ISTL_WITH_CHECKING\n- 732 // Check for symmetry\n- 733 int ret=0;\n- 734 typedef typename M::ConstRowIterator RIter;\n- 735 for(RIter row=newMatrix.begin(), rend=newMatrix.end(); row != rend; ++row)\n-{\n- 736 typedef typename M::ConstColIterator CIter;\n- 737 for(CIter col=row->begin(), cend=row->end(); col!=cend; ++col)\n- 738 {\n- 739 try{\n- 740 newMatrix[col.index()][row.index()];\n- 741 }catch(const Dune::ISTLError&) {\n- 742 std::cerr<\n-757 void redistributeMatrixEntries(M& origMatrix, M& newMatrix, C& origComm, C&\n-newComm,\n- 758 RedistributeInformation& ri)\n- 759 {\n- 760 typedef typename C::ParallelIndexSet IndexSet;\n- 761 typename C::OwnerSet ownerflags;\n- 762 std::vector rowsize(newComm.indexSet().size(), 0);\n- 763 std::vector copyrowsize(newComm.indexSet().size(),\n-0);\n- 764 std::vector backwardscopyrowsize(origComm.indexSet\n-().size(), 0);\n- 765\n- 766 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n- 767 rowsize[i] = ri.getRowSize(i);\n- 768 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n-{\n- 769 copyrowsize[i] = ri.getCopyRowSize(i);\n- 770 }\n- 771 }\n- 772\n- 773 for (std::size_t i=0; i < origComm.indexSet().size(); i++)\n- 774 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n- 775 backwardscopyrowsize[i] = ri.getBackwardsCopyRowSize(i);\n- 776\n- 777\n- 778 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n-{\n- 779 // fill sparsity pattern from copy rows\n- 780 CommMatrixRow origrow_copy(origMatrix, origComm.globalLookup\n-(),\n- 781 newComm.indexSet(), backwardscopyrowsize);\n- 782 CommMatrixRow newrow_copy(newMatrix, origComm.globalLookup(),\n- 783 newComm.indexSet(),copyrowsize);\n- 784 ri.template redistribute >\n-(origrow_copy,\n- 785 newrow_copy);\n- 786 ri.getInterface().free();\n- 787 RemoteIndices *ris = new RemoteIndices\n-(origComm.indexSet(),\n- 788 newComm.indexSet(),\n- 789 origComm.communicator());\n- 790 ris->template rebuild();\n- 791 ri.getInterface().build(*ris,ownerflags,ownerflags);\n- 792 }\n- 793\n- 794 CommMatrixRow\n- 795 origrow(origMatrix, origComm.globalLookup(), newComm.indexSet());\n- 796 CommMatrixRow\n- 797 newrow(newMatrix, origComm.globalLookup(), newComm.indexSet(),rowsize);\n- 798 ri.template redistribute >\n-(origrow,newrow);\n- 799 if (SolverCategory::category(origComm) != static_cast\n-(SolverCategory::nonoverlapping))\n- 800 newrow.setOverlapRowsToDirichlet();\n- 801 }\n- 802\n- 819 template\n-820 void redistributeMatrix(M& origMatrix, M& newMatrix, C& origComm, C&\n-newComm,\n- 821 RedistributeInformation& ri)\n- 822 {\n- 823 ri.setNoRows(newComm.indexSet().size());\n- 824 ri.setNoCopyRows(newComm.indexSet().size());\n- 825 ri.setNoBackwardsCopyRows(origComm.indexSet().size());\n- 826 redistributeSparsityPattern(origMatrix, newMatrix, origComm, newComm, ri);\n- 827 redistributeMatrixEntries(origMatrix, newMatrix, origComm, newComm, ri);\n- 828 }\n- 829#endif\n- 830\n- 831template\n-832 void redistributeMatrixEntries(M& origMatrix, M& newMatrix,\n- 833 Dune::Amg::SequentialInformation& origComm,\n- 834 Dune::Amg::SequentialInformation& newComm,\n- 835 RedistributeInformation& ri)\n- 836 {\n- 837 DUNE_THROW(InvalidStateException, \"Trying to redistribute in sequential\n-program!\");\n- 838 }\n- 839 template\n-840 void redistributeMatrix(M& origMatrix, M& newMatrix,\n- 841 Dune::Amg::SequentialInformation& origComm,\n- 842 Dune::Amg::SequentialInformation& newComm,\n- 843 RedistributeInformation& ri)\n- 844 {\n- 845 DUNE_THROW(InvalidStateException, \"Trying to redistribute in sequential\n-program!\");\n- 846 }\n- 847}\n- 848#endif\n-repartition.hh\n-Functionality for redistributing a parallel index set using graph partitioning.\n-pinfo.hh\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+ 5#ifndef DUNE_ISTL_SOLVERTYPE_HH\n+ 6#define DUNE_ISTL_SOLVERTYPE_HH\n+ 7\n+ 12namespace Dune\n+ 13{\n+ 14 template\n+15 struct IsDirectSolver\n+ 16 {\n+ 17 enum\n+ 18 {\n+ 24 value =false\n+25 };\n+ 26 };\n+ 27\n+ 28 template\n+29 struct StoresColumnCompressed\n+ 30 {\n+ 31 enum\n+ 32 {\n+ 36 value = false\n+37 };\n+ 38 };\n+ 39} // end namespace Dune\n+ 40#endif\n Dune\n Definition: allocator.hh:11\n-Dune::redistributeMatrixEntries\n-void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C\n-&newComm, RedistributeInformation< C > &ri)\n-Definition: matrixredistribute.hh:757\n-Dune::redistributeSparsityPattern\n-void redistributeSparsityPattern(M &origMatrix, M &newMatrix, C &origComm, C\n-&newComm, RedistributeInformation< C > &ri)\n-Definition: matrixredistribute.hh:663\n-Dune::redistributeMatrix\n-void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm,\n-RedistributeInformation< C > &ri)\n-Redistribute a matrix according to given domain decompositions.\n-Definition: matrixredistribute.hh:820\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::RedistributeInformation\n-Definition: matrixredistribute.hh:22\n-Dune::RedistributeInformation::setNoBackwardsCopyRows\n-void setNoBackwardsCopyRows(std::size_t size)\n-Definition: matrixredistribute.hh:44\n-Dune::RedistributeInformation::redistribute\n-void redistribute(const D &from, D &to) const\n-Definition: matrixredistribute.hh:28\n-Dune::RedistributeInformation::resetSetup\n-void resetSetup()\n-Definition: matrixredistribute.hh:35\n-Dune::RedistributeInformation::setNoCopyRows\n-void setNoCopyRows(std::size_t size)\n-Definition: matrixredistribute.hh:41\n-Dune::RedistributeInformation::isSetup\n-bool isSetup() const\n-Definition: matrixredistribute.hh:23\n-Dune::RedistributeInformation::setNoRows\n-void setNoRows(std::size_t size)\n-Definition: matrixredistribute.hh:38\n-Dune::RedistributeInformation::redistributeBackward\n-void redistributeBackward(D &from, const D &to) const\n-Definition: matrixredistribute.hh:32\n-Dune::RedistributeInformation::getBackwardsCopyRowSize\n-std::size_t getBackwardsCopyRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:57\n-Dune::RedistributeInformation::getRowSize\n-std::size_t getRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:47\n-Dune::RedistributeInformation::getCopyRowSize\n-std::size_t getCopyRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:52\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getRowSize\n-std::size_t getRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:158\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getBackwardsCopyRowSize\n-std::size_t & getBackwardsCopyRowSize(std::size_t index)\n-Definition: matrixredistribute.hh:173\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getInterface\n-RedistributeInterface & getInterface()\n-Definition: matrixredistribute.hh:75\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-redistribute\n-void redistribute(const D &from, D &to) const\n-Definition: matrixredistribute.hh:136\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-setNoBackwardsCopyRows\n-void setNoBackwardsCopyRows(std::size_t rows)\n-Definition: matrixredistribute.hh:193\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getCopyRowSize\n-std::size_t & getCopyRowSize(std::size_t index)\n-Definition: matrixredistribute.hh:163\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-RedistributeInformation\n-RedistributeInformation()\n-Definition: matrixredistribute.hh:71\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getCopyRowSize\n-std::size_t getCopyRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:168\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-setNoRows\n-void setNoRows(std::size_t rows)\n-Definition: matrixredistribute.hh:183\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-reserve\n-void reserve(std::size_t size)\n-Definition: matrixredistribute.hh:150\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::Comm\n-OwnerOverlapCopyCommunication< T, T1 > Comm\n-Definition: matrixredistribute.hh:69\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-setNoCopyRows\n-void setNoCopyRows(std::size_t rows)\n-Definition: matrixredistribute.hh:188\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-redistributeBackward\n-void redistributeBackward(D &from, const D &to) const\n-Definition: matrixredistribute.hh:141\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-setSetup\n-void setSetup()\n-Definition: matrixredistribute.hh:106\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getBackwardsCopyRowSize\n-std::size_t getBackwardsCopyRowSize(std::size_t index) const\n-Definition: matrixredistribute.hh:178\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-redistribute\n-void redistribute(const D &from, D &to) const\n-Definition: matrixredistribute.hh:118\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-resetSetup\n-void resetSetup()\n-Definition: matrixredistribute.hh:112\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-redistributeBackward\n-void redistributeBackward(D &from, const D &to) const\n-Definition: matrixredistribute.hh:126\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-checkInterface\n-void checkInterface(const IS &source, const IS &target, MPI_Comm comm)\n-Definition: matrixredistribute.hh:80\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-isSetup\n-bool isSetup() const\n-Definition: matrixredistribute.hh:145\n-Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n-getRowSize\n-std::size_t & getRowSize(std::size_t index)\n-Definition: matrixredistribute.hh:153\n-Dune::CommMatrixRowSize\n-Utility class to communicate and set the row sizes of a redistributed matrix.\n-Definition: matrixredistribute.hh:216\n-Dune::CommMatrixRowSize::size_type\n-M::size_type size_type\n-Definition: matrixredistribute.hh:219\n-Dune::CommMatrixRowSize::value_type\n-M::size_type value_type\n-Definition: matrixredistribute.hh:218\n-Dune::CommMatrixRowSize::rowsize\n-RI & rowsize\n-Definition: matrixredistribute.hh:230\n-Dune::CommMatrixRowSize::matrix\n-const M & matrix\n-Definition: matrixredistribute.hh:229\n-Dune::CommMatrixRowSize::CommMatrixRowSize\n-CommMatrixRowSize(const M &m_, RI &rowsize_)\n-Constructor.\n-Definition: matrixredistribute.hh:226\n-Dune::CommMatrixSparsityPattern\n-Utility class to communicate and build the sparsity pattern of a redistributed\n-matrix.\n-Definition: matrixredistribute.hh:245\n-Dune::CommMatrixSparsityPattern::size_type\n-M::size_type size_type\n-Definition: matrixredistribute.hh:246\n-Dune::CommMatrixSparsityPattern::idxset\n-const Dune::GlobalLookupIndexSet< I > & idxset\n-Definition: matrixredistribute.hh:356\n-Dune::CommMatrixSparsityPattern::storeSparsityPattern\n-void storeSparsityPattern(M &m)\n-Creates and stores the sparsity pattern of the redistributed matrix.\n-Definition: matrixredistribute.hh:276\n-Dune::CommMatrixSparsityPattern::aggidxset\n-const I & aggidxset\n-Definition: matrixredistribute.hh:357\n-Dune::CommMatrixSparsityPattern::rowsize\n-const std::vector< size_type > * rowsize\n-Definition: matrixredistribute.hh:359\n-Dune::CommMatrixSparsityPattern::completeSparsityPattern\n-void completeSparsityPattern(std::vector< std::set< size_type > > add_sparsity)\n-Completes the sparsity pattern of the redistributed matrix with data from copy\n-rows for the novlp cas...\n-Definition: matrixredistribute.hh:340\n-Dune::CommMatrixSparsityPattern::CommMatrixSparsityPattern\n-CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I >\n-&idxset_, const I &aggidxset_)\n-Constructor for the original side.\n-Definition: matrixredistribute.hh:254\n-Dune::CommMatrixSparsityPattern::matrix\n-const M & matrix\n-Definition: matrixredistribute.hh:354\n-Dune::CommMatrixSparsityPattern::CommMatrixSparsityPattern\n-CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I >\n-&idxset_, const I &aggidxset_, const std::vector< typename M::size_type >\n-&rowsize_)\n-Constructor for the redistruted side.\n-Definition: matrixredistribute.hh:265\n-Dune::CommMatrixSparsityPattern::sparsity\n-std::vector< std::set< size_type > > sparsity\n-Definition: matrixredistribute.hh:358\n-Dune::CommMatrixSparsityPattern::LookupIndexSet\n-Dune::GlobalLookupIndexSet< I > LookupIndexSet\n-Definition: matrixredistribute.hh:355\n-Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::getSize\n-static M::size_type getSize(const Type &t, std::size_t i)\n-Definition: matrixredistribute.hh:376\n-Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::Type\n-CommMatrixSparsityPattern< M, I > Type\n-Definition: matrixredistribute.hh:365\n-Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::IndexedType\n-I::GlobalIndex IndexedType\n-The indexed type we send. This is the global index indentitfying the column.\n-Definition: matrixredistribute.hh:371\n-Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::IndexedTypeFlag\n-VariableSize IndexedTypeFlag\n-Each row varies in size.\n-Definition: matrixredistribute.hh:374\n-Dune::CommMatrixRow\n-Utility class for comunicating the matrix entries.\n-Definition: matrixredistribute.hh:396\n-Dune::CommMatrixRow::rowsize\n-std::vector< size_t > * rowsize\n-row size information for the receiving side.\n-Definition: matrixredistribute.hh:452\n-Dune::CommMatrixRow::matrix\n-M & matrix\n-The matrix to communicate the values of.\n-Definition: matrixredistribute.hh:446\n-Dune::CommMatrixRow::CommMatrixRow\n-CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I\n-&aggidxset_, std::vector< size_t > &rowsize_)\n-Constructor.\n-Definition: matrixredistribute.hh:412\n-Dune::CommMatrixRow::idxset\n-const Dune::GlobalLookupIndexSet< I > & idxset\n-Index set for the original matrix.\n-Definition: matrixredistribute.hh:448\n-Dune::CommMatrixRow::setOverlapRowsToDirichlet\n-void setOverlapRowsToDirichlet()\n-Sets the non-owner rows correctly as Dirichlet boundaries.\n-Definition: matrixredistribute.hh:421\n-Dune::CommMatrixRow::aggidxset\n-const I & aggidxset\n-Index set for the redistributed matrix.\n-Definition: matrixredistribute.hh:450\n-Dune::CommMatrixRow::CommMatrixRow\n-CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I\n-&aggidxset_)\n-Constructor.\n-Definition: matrixredistribute.hh:405\n-Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::IndexedType\n-std::pair< typename I::GlobalIndex, typename M::block_type > IndexedType\n-The indexed type we send. This is the pair of global index indentitfying the\n-column and the value its...\n-Definition: matrixredistribute.hh:464\n-Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::Type\n-CommMatrixRow< M, I > Type\n-Definition: matrixredistribute.hh:458\n-Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::getSize\n-static std::size_t getSize(const Type &t, std::size_t i)\n-Definition: matrixredistribute.hh:469\n-Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::IndexedTypeFlag\n-VariableSize IndexedTypeFlag\n-Each row varies in size.\n-Definition: matrixredistribute.hh:467\n-Dune::MatrixRowSizeGatherScatter\n-Definition: matrixredistribute.hh:483\n-Dune::MatrixRowSizeGatherScatter::scatter\n-static void scatter(Container &cont, const typename M::size_type &rowsize,\n-std::size_t i)\n-Definition: matrixredistribute.hh:490\n-Dune::MatrixRowSizeGatherScatter::gather\n-static const M::size_type gather(const Container &cont, std::size_t i)\n-Definition: matrixredistribute.hh:486\n-Dune::MatrixRowSizeGatherScatter::Container\n-CommMatrixRowSize< M, RI > Container\n-Definition: matrixredistribute.hh:484\n-Dune::MatrixCopyRowSizeGatherScatter\n-Definition: matrixredistribute.hh:500\n-Dune::MatrixCopyRowSizeGatherScatter::gather\n-static const M::size_type gather(const Container &cont, std::size_t i)\n-Definition: matrixredistribute.hh:503\n-Dune::MatrixCopyRowSizeGatherScatter::scatter\n-static void scatter(Container &cont, const typename M::size_type &rowsize,\n-std::size_t i)\n-Definition: matrixredistribute.hh:507\n-Dune::MatrixCopyRowSizeGatherScatter::Container\n-CommMatrixRowSize< M, RI > Container\n-Definition: matrixredistribute.hh:501\n-Dune::MatrixSparsityPatternGatherScatter\n-Definition: matrixredistribute.hh:518\n-Dune::MatrixSparsityPatternGatherScatter::ColIter\n-M::ConstColIterator ColIter\n-Definition: matrixredistribute.hh:521\n-Dune::MatrixSparsityPatternGatherScatter::scatter\n-static void scatter(Container &cont, const GlobalIndex &gi, std::size_t i,\n-std::size_t j)\n-Definition: matrixredistribute.hh:553\n-Dune::MatrixSparsityPatternGatherScatter::Container\n-CommMatrixSparsityPattern< M, I > Container\n-Definition: matrixredistribute.hh:520\n-Dune::MatrixSparsityPatternGatherScatter::numlimits\n-static GlobalIndex numlimits\n-Definition: matrixredistribute.hh:524\n-Dune::MatrixSparsityPatternGatherScatter::col\n-static ColIter col\n-Definition: matrixredistribute.hh:523\n-Dune::MatrixSparsityPatternGatherScatter::GlobalIndex\n-I::GlobalIndex GlobalIndex\n-Definition: matrixredistribute.hh:519\n-Dune::MatrixSparsityPatternGatherScatter::gather\n-static const GlobalIndex & gather(const Container &cont, std::size_t i, std::\n-size_t j)\n-Definition: matrixredistribute.hh:526\n-Dune::MatrixRowGatherScatter\n-Definition: matrixredistribute.hh:599\n-Dune::MatrixRowGatherScatter::GlobalIndex\n-I::GlobalIndex GlobalIndex\n-Definition: matrixredistribute.hh:600\n-Dune::MatrixRowGatherScatter::datastore\n-static Data datastore\n-Definition: matrixredistribute.hh:605\n-Dune::MatrixRowGatherScatter::numlimits\n-static GlobalIndex numlimits\n-Definition: matrixredistribute.hh:606\n-Dune::MatrixRowGatherScatter::ColIter\n-M::ConstColIterator ColIter\n-Definition: matrixredistribute.hh:602\n-Dune::MatrixRowGatherScatter::gather\n-static const Data & gather(const Container &cont, std::size_t i, std::size_t j)\n-Definition: matrixredistribute.hh:608\n-Dune::MatrixRowGatherScatter::Data\n-std::pair< GlobalIndex, typename M::block_type > Data\n-Definition: matrixredistribute.hh:603\n-Dune::MatrixRowGatherScatter::scatter\n-static void scatter(Container &cont, const Data &data, std::size_t i, std::\n-size_t j)\n-Definition: matrixredistribute.hh:638\n-Dune::MatrixRowGatherScatter::col\n-static ColIter col\n-Definition: matrixredistribute.hh:604\n-Dune::MatrixRowGatherScatter::Container\n-CommMatrixRow< M, I > Container\n-Definition: matrixredistribute.hh:601\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::OwnerSet\n-EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet\n-Definition: owneroverlapcopy.hh:194\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::RedistributeInterface\n-Definition: repartition.hh:260\n-Dune::SolverCategory::nonoverlapping\n-@ nonoverlapping\n-Category for non-overlapping solvers.\n-Definition: solvercategory.hh:27\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n+Dune::IsDirectSolver::value\n+@ value\n+Whether this is a direct solver.\n+Definition: solvertype.hh:24\n+Dune::StoresColumnCompressed\n+Definition: solvertype.hh:30\n+Dune::StoresColumnCompressed::value\n+@ value\n+whether the solver internally uses column compressed storage\n+Definition: solvertype.hh:36\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00029.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00029.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: cholmod.hh File Reference\n+dune-istl: solverregistry.hh File Reference\n \n \n \n \n \n \n \n@@ -62,19 +62,146 @@\n \n
    \n \n
    \n
    \n
    \n-
    cholmod.hh File Reference
    \n+ \n+
    solverregistry.hh File Reference
    \n
    \n
    \n-\n+\n

    Go to the source code of this file.

    \n+\n+\n+\n+\n+\n+\n+

    \n+Classes

    class  Dune::UnsupportedType
     
    class  Dune::InvalidSolverFactoryConfiguration
     
    \n+\n+\n+\n+

    \n+Namespaces

    namespace  Dune
     
    \n+\n+\n+\n+\n+\n+\n+\n+

    \n+Macros

    #define DUNE_REGISTER_DIRECT_SOLVER(name, ...)    DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
     
    #define DUNE_REGISTER_PRECONDITIONER(name, ...)    DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
     
    #define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...)    DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Functions

    template<template< class, class, class, int >class Preconditioner, int blockLevel = 1>
    auto Dune::defaultPreconditionerBlockLevelCreator ()
     
    template<template< class, class, class >class Preconditioner>
    auto Dune::defaultPreconditionerCreator ()
     
    template<template< class... >class Solver>
    auto Dune::defaultIterativeSolverCreator ()
     
    \n+

    Macro Definition Documentation

    \n+\n+

    ◆ DUNE_REGISTER_DIRECT_SOLVER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_REGISTER_DIRECT_SOLVER( name,
     ... 
    )    DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
    \n+
    \n+\n+
    \n+
    \n+\n+

    ◆ DUNE_REGISTER_ITERATIVE_SOLVER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_REGISTER_ITERATIVE_SOLVER( name,
     ... 
    )    DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
    \n+
    \n+\n+
    \n+
    \n+\n+

    ◆ DUNE_REGISTER_PRECONDITIONER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_REGISTER_PRECONDITIONER( name,
     ... 
    )    DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
    \n+
    \n+\n+
    \n+
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,12 +4,64 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-cholmod.hh File Reference\n+Classes | Namespaces | Macros | Functions\n+solverregistry.hh File Reference\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n+ Classes\n+class \u00a0Dune::UnsupportedType\n+\u00a0\n+class \u00a0Dune::InvalidSolverFactoryConfiguration\n+\u00a0\n+ Namespaces\n+namespace \u00a0Dune\n+\u00a0\n+ Macros\n+#define\u00a0DUNE_REGISTER_DIRECT_SOLVER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(DirectSolverTag,\n+ name, __VA_ARGS__)\n+\u00a0\n+#define\u00a0DUNE_REGISTER_PRECONDITIONER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(PreconditionerTag,\n+ name, __VA_ARGS__)\n+\u00a0\n+#define\u00a0DUNE_REGISTER_ITERATIVE_SOLVER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT\n+ (IterativeSolverTag, name, __VA_ARGS__)\n+\u00a0\n+ Functions\n+templateclass Preconditioner, int\n+blockLevel = 1>\n+auto\u00a0Dune::defaultPreconditionerBlockLevelCreator ()\n+\u00a0\n+templateclass Preconditioner>\n+auto\u00a0Dune::defaultPreconditionerCreator ()\n+\u00a0\n+templateclass Solver>\n+auto\u00a0Dune::defaultIterativeSolverCreator ()\n+\u00a0\n+***** Macro Definition Documentation *****\n+***** \u25c6\u00a0DUNE_REGISTER_DIRECT_SOLVER *****\n+#define ( \u00a0name,\n+DUNE_REGISTER_DIRECT_SOLVER\n+ \u00a0...\u00a0\n+ ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(DirectSolverTag, name,\n+ __VA_ARGS__)\n+***** \u25c6\u00a0DUNE_REGISTER_ITERATIVE_SOLVER *****\n+#define ( \u00a0name,\n+DUNE_REGISTER_ITERATIVE_SOLVER\n+ \u00a0...\u00a0\n+ ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(IterativeSolverTag, name,\n+ __VA_ARGS__)\n+***** \u25c6\u00a0DUNE_REGISTER_PRECONDITIONER *****\n+#define ( \u00a0name,\n+DUNE_REGISTER_PRECONDITIONER\n+ \u00a0...\u00a0\n+ ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(PreconditionerTag, name,\n+ __VA_ARGS__)\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00029_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00029_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: cholmod.hh Source File\n+dune-istl: solverregistry.hh Source File\n \n \n \n \n \n \n \n@@ -62,379 +62,106 @@\n \n
    \n \n
    \n
    \n
    \n-
    cholmod.hh
    \n+
    solverregistry.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3#pragma once
    \n-
    4
    \n-
    5#if HAVE_SUITESPARSE_CHOLMOD
    \n-
    6
    \n-
    7#include <dune/common/fmatrix.hh>
    \n-
    8#include <dune/common/fvector.hh>
    \n-\n-
    10#include <dune/istl/bvector.hh>
    \n-
    11#include<dune/istl/solver.hh>
    \n-\n-
    13#include <dune/istl/foreach.hh>
    \n-
    14
    \n-
    15#include <vector>
    \n-
    16#include <memory>
    \n-
    17
    \n-
    18#include <cholmod.h>
    \n-
    19
    \n-
    20namespace Dune {
    \n+
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n+
    4// vi: set et ts=4 sw=2 sts=2:
    \n+
    5
    \n+
    6#ifndef DUNE_ISTL_SOLVERREGISTRY_HH
    \n+
    7#define DUNE_ISTL_SOLVERREGISTRY_HH
    \n+
    8
    \n+\n+\n+
    11#include <dune/istl/solver.hh>
    \n+
    12
    \n+
    13#define DUNE_REGISTER_DIRECT_SOLVER(name, ...) \\
    \n+
    14 DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
    \n+
    15
    \n+
    16#define DUNE_REGISTER_PRECONDITIONER(name, ...) \\
    \n+
    17 DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
    \n+
    18
    \n+
    19#define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...) \\
    \n+
    20 DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
    \n
    21
    \n-
    22namespace Impl{
    \n-
    23
    \n-
    32 struct NoIgnore
    \n-
    33 {
    \n-
    34 const NoIgnore& operator[](std::size_t) const { return *this; }
    \n-
    35 explicit operator bool() const { return false; }
    \n-
    36 static constexpr std::size_t size() { return 0; }
    \n-
    37
    \n-
    38 };
    \n-
    39
    \n-
    40
    \n-
    41 template<class BlockedVector, class FlatVector>
    \n-
    42 void copyToFlatVector(const BlockedVector& blockedVector, FlatVector& flatVector)
    \n-
    43 {
    \n-
    44 // traverse the vector once just to compute the size
    \n-
    45 std::size_t len = flatVectorForEach(blockedVector, [&](auto&&, auto...){});
    \n-
    46 flatVector.resize(len);
    \n-
    47
    \n-
    48 flatVectorForEach(blockedVector, [&](auto&& entry, auto offset){
    \n-
    49 flatVector[offset] = entry;
    \n-
    50 });
    \n-
    51 }
    \n-
    52
    \n-
    53 // special (dummy) case for NoIgnore
    \n-
    54 template<class FlatVector>
    \n-
    55 void copyToFlatVector(const NoIgnore&, FlatVector&)
    \n-
    56 {
    \n-
    57 // just do nothing
    \n-
    58 return;
    \n-
    59 }
    \n-
    60
    \n-
    61 template<class FlatVector, class BlockedVector>
    \n-
    62 void copyToBlockedVector(const FlatVector& flatVector, BlockedVector& blockedVector)
    \n-
    63 {
    \n-
    64 flatVectorForEach(blockedVector, [&](auto& entry, auto offset){
    \n-
    65 entry = flatVector[offset];
    \n-
    66 });
    \n-
    67 }
    \n-
    68
    \n-
    69
    \n-
    70} //namespace Impl
    \n-
    71
    \n-
    76template<class Vector>
    \n-
    77class Cholmod : public InverseOperator<Vector, Vector>
    \n-
    78{
    \n-
    79public:
    \n-
    80
    \n-
    86 Cholmod()
    \n-
    87 {
    \n-
    88 cholmod_start(&c_);
    \n-
    89 }
    \n-
    90
    \n-
    96 ~Cholmod()
    \n-
    97 {
    \n-
    98 if (L_)
    \n-
    99 cholmod_free_factor(&L_, &c_);
    \n-
    100 cholmod_finish(&c_);
    \n-
    101 }
    \n-
    102
    \n-
    103 // forbid copying to avoid freeing memory twice
    \n-
    104 Cholmod(const Cholmod&) = delete;
    \n-
    105 Cholmod& operator=(const Cholmod&) = delete;
    \n-
    106
    \n-
    107
    \n-
    110 void apply (Vector& x, Vector& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n-
    111 {
    \n-
    112 apply(x,b,res);
    \n-
    113 }
    \n-
    114
    \n-
    120 void apply(Vector& x, Vector& b, InverseOperatorResult& res)
    \n-
    121 {
    \n-
    122 // do nothing if N=0
    \n-
    123 if ( nIsZero_ )
    \n-
    124 {
    \n-
    125 return;
    \n-
    126 }
    \n-
    127
    \n-
    128 if (x.size() != b.size())
    \n-
    129 DUNE_THROW(Exception, "Error in apply(): sizes of x and b do not match!");
    \n-
    130
    \n-
    131 // cast to double array
    \n-
    132 auto b2 = std::make_unique<double[]>(L_->n);
    \n-
    133 auto x2 = std::make_unique<double[]>(L_->n);
    \n-
    134
    \n-
    135 // copy to cholmod
    \n-
    136 auto bp = b2.get();
    \n-
    137
    \n-
    138 flatVectorForEach(b, [&](auto&& entry, auto&& flatIndex){
    \n-
    139 if ( subIndices_.empty() )
    \n-
    140 bp[ flatIndex ] = entry;
    \n-
    141 else
    \n-
    142 if( subIndices_[ flatIndex ] != std::numeric_limits<std::size_t>::max() )
    \n-
    143 bp[ subIndices_[ flatIndex ] ] = entry;
    \n-
    144 });
    \n-
    145
    \n-
    146 // create a cholmod dense object
    \n-
    147 auto b3 = make_cholmod_dense(cholmod_allocate_dense(L_->n, 1, L_->n, CHOLMOD_REAL, &c_), &c_);
    \n-
    148 // cast because void-ptr
    \n-
    149 auto b4 = static_cast<double*>(b3->x);
    \n-
    150 std::copy(b2.get(), b2.get() + L_->n, b4);
    \n-
    151
    \n-
    152 // solve for a cholmod x object
    \n-
    153 auto x3 = make_cholmod_dense(cholmod_solve(CHOLMOD_A, L_, b3.get(), &c_), &c_);
    \n-
    154 // cast because void-ptr
    \n-
    155 auto xp = static_cast<double*>(x3->x);
    \n-
    156
    \n-
    157 // copy into x
    \n-
    158 flatVectorForEach(x, [&](auto&& entry, auto&& flatIndex){
    \n-
    159 if ( subIndices_.empty() )
    \n-
    160 entry = xp[ flatIndex ];
    \n-
    161 else
    \n-
    162 if( subIndices_[ flatIndex ] != std::numeric_limits<std::size_t>::max() )
    \n-
    163 entry = xp[ subIndices_[ flatIndex ] ];
    \n-
    164 });
    \n-
    165
    \n-
    166 // statistics for a direct solver
    \n-
    167 res.iterations = 1;
    \n-
    168 res.converged = true;
    \n-
    169 }
    \n-
    170
    \n-
    171
    \n-
    177 template<class Matrix>
    \n-
    178 void setMatrix(const Matrix& matrix)
    \n-
    179 {
    \n-
    180 const Impl::NoIgnore* noIgnore = nullptr;
    \n-
    181 setMatrix(matrix, noIgnore);
    \n-
    182 }
    \n-
    183
    \n-
    198 template<class Matrix, class Ignore>
    \n-
    199 void setMatrix(const Matrix& matrix, const Ignore* ignore)
    \n-
    200 {
    \n-
    201 // count the number of entries and diagonal entries
    \n-
    202 int nonZeros = 0;
    \n-
    203 int numberOfIgnoredDofs = 0;
    \n-
    204
    \n-
    205
    \n-
    206 auto [flatRows,flatCols] = flatMatrixForEach( matrix, [&](auto&& /*entry*/, auto&& flatRowIndex, auto&& flatColIndex){
    \n-
    207 if( flatRowIndex <= flatColIndex )
    \n-
    208 nonZeros++;
    \n-
    209 });
    \n-
    210
    \n-
    211 std::vector<bool> flatIgnore;
    \n-
    212
    \n-
    213 if ( ignore )
    \n-
    214 {
    \n-
    215 Impl::copyToFlatVector(*ignore,flatIgnore);
    \n-
    216 numberOfIgnoredDofs = std::count(flatIgnore.begin(),flatIgnore.end(),true);
    \n-
    217 }
    \n-
    218
    \n-
    219 // Total number of rows
    \n-
    220 int N = flatRows - numberOfIgnoredDofs;
    \n-
    221
    \n-
    222 nIsZero_ = (N <= 0);
    \n-
    223
    \n-
    224 if ( nIsZero_ )
    \n-
    225 {
    \n-
    226 return;
    \n-
    227 }
    \n-
    228
    \n-
    229 /*
    \n-
    230 * CHOLMOD uses compressed-column sparse matrices, but for symmetric
    \n-
    231 * matrices this is the same as the compressed-row sparse matrix used
    \n-
    232 * by DUNE. So we can just store M\u1d40 instead of M (as M = M\u1d40).
    \n-
    233 */
    \n-
    234 const auto deleter = [c = &this->c_](auto* p) {
    \n-
    235 cholmod_free_sparse(&p, c);
    \n-
    236 };
    \n-
    237 auto M = std::unique_ptr<cholmod_sparse, decltype(deleter)>(
    \n-
    238 cholmod_allocate_sparse(N, // # rows
    \n-
    239 N, // # cols
    \n-
    240 nonZeros, // # of nonzeroes
    \n-
    241 1, // indices are sorted ( 1 = true)
    \n-
    242 1, // matrix is "packed" ( 1 = true)
    \n-
    243 -1, // stype of matrix ( -1 = consider the lower part only )
    \n-
    244 CHOLMOD_REAL, // xtype of matrix ( CHOLMOD_REAL = single array, no complex numbers)
    \n-
    245 &c_ // cholmod_common ptr
    \n-
    246 ), deleter);
    \n-
    247
    \n-
    248 // copy the data of BCRS matrix to Cholmod Sparse matrix
    \n-
    249 int* Ap = static_cast<int*>(M->p);
    \n-
    250 int* Ai = static_cast<int*>(M->i);
    \n-
    251 double* Ax = static_cast<double*>(M->x);
    \n-
    252
    \n-
    253
    \n-
    254 if ( ignore )
    \n-
    255 {
    \n-
    256 // init the mapping
    \n-
    257 subIndices_.resize(flatRows,std::numeric_limits<std::size_t>::max());
    \n-
    258
    \n-
    259 std::size_t subIndexCounter = 0;
    \n-
    260
    \n-
    261 for ( std::size_t i=0; i<flatRows; i++ )
    \n-
    262 {
    \n-
    263 if ( not flatIgnore[ i ] )
    \n-
    264 {
    \n-
    265 subIndices_[ i ] = subIndexCounter++;
    \n-
    266 }
    \n-
    267 }
    \n-
    268 }
    \n-
    269
    \n-
    270 // at first, we need to compute the row starts "Ap"
    \n-
    271 // therefore, we count all (not ignored) entries in each row and in the end we accumulate everything
    \n-
    272 flatMatrixForEach(matrix, [&](auto&& /*entry*/, auto&& flatRowIndex, auto&& flatColIndex){
    \n-
    273
    \n-
    274 // stop if ignored
    \n-
    275 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
    \n-
    276 return;
    \n-
    277
    \n-
    278 // stop if in lower half
    \n-
    279 if ( flatRowIndex > flatColIndex )
    \n-
    280 return;
    \n-
    281
    \n-
    282 // ok, count the entry
    \n-
    283 auto idx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
    \n-
    284 Ap[idx+1]++;
    \n-
    285
    \n-
    286 });
    \n-
    287
    \n-
    288 // now accumulate
    \n-
    289 Ap[0] = 0;
    \n-
    290 for ( int i=0; i<N; i++ )
    \n-
    291 {
    \n-
    292 Ap[i+1] += Ap[i];
    \n-
    293 }
    \n-
    294
    \n-
    295 // we need a compressed row position counter
    \n-
    296 std::vector<std::size_t> rowPosition(N,0);
    \n-
    297
    \n-
    298 // now we can set the entries
    \n-
    299 flatMatrixForEach(matrix, [&](auto&& entry, auto&& flatRowIndex, auto&& flatColIndex){
    \n-
    300
    \n-
    301 // stop if ignored
    \n-
    302 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
    \n-
    303 return;
    \n-
    304
    \n-
    305 // stop if in lower half
    \n-
    306 if ( flatRowIndex > flatColIndex )
    \n-
    307 return;
    \n-
    308
    \n-
    309 // ok, set the entry
    \n-
    310 auto rowIdx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
    \n-
    311 auto colIdx = ignore ? subIndices_[flatColIndex] : flatColIndex;
    \n-
    312 auto rowStart = Ap[rowIdx];
    \n-
    313 auto rowPos = rowPosition[rowIdx];
    \n-
    314 Ai[ rowStart + rowPos ] = colIdx;
    \n-
    315 Ax[ rowStart + rowPos ] = entry;
    \n-
    316 rowPosition[rowIdx]++;
    \n-
    317
    \n-
    318 });
    \n-
    319
    \n-
    320 // Now analyse the pattern and optimal row order
    \n-
    321 L_ = cholmod_analyze(M.get(), &c_);
    \n-
    322
    \n-
    323 // Do the factorization (this may take some time)
    \n-
    324 cholmod_factorize(M.get(), L_, &c_);
    \n-
    325 }
    \n-
    326
    \n-
    327 virtual SolverCategory::Category category() const
    \n-
    328 {
    \n-
    329 return SolverCategory::Category::sequential;
    \n-
    330 }
    \n-
    331
    \n-
    337 cholmod_common& cholmodCommonObject()
    \n-
    338 {
    \n-
    339 return c_;
    \n-
    340 }
    \n-
    341
    \n-
    347 cholmod_factor& cholmodFactor()
    \n-
    348 {
    \n-
    349 return *L_;
    \n-
    350 }
    \n-
    351
    \n-
    357 const cholmod_factor& cholmodFactor() const
    \n-
    358 {
    \n-
    359 return *L_;
    \n-
    360 }
    \n-
    361private:
    \n-
    362
    \n-
    363 // create a std::unique_ptr to a cholmod_dense object with a deleter
    \n-
    364 // that calls the appropriate cholmod cleanup routine
    \n-
    365 auto make_cholmod_dense(cholmod_dense* x, cholmod_common* c)
    \n-
    366 {
    \n-
    367 const auto deleter = [c](auto* p) {
    \n-
    368 cholmod_free_dense(&p, c);
    \n-
    369 };
    \n-
    370 return std::unique_ptr<cholmod_dense, decltype(deleter)>(x, deleter);
    \n-
    371 }
    \n-
    372
    \n-
    373 cholmod_common c_;
    \n-
    374 cholmod_factor* L_ = nullptr;
    \n-
    375
    \n-
    376 // indicator for a 0x0 problem (due to ignore dof's)
    \n-
    377 bool nIsZero_ = false;
    \n-
    378
    \n-
    379 // vector mapping all indices in flat order to the not ignored indices
    \n-
    380 std::vector<std::size_t> subIndices_;
    \n-
    381};
    \n-
    382
    \n-
    383 struct CholmodCreator{
    \n-
    384 template<class F> struct isValidBlock : std::false_type{};
    \n-
    385 template<int k> struct isValidBlock<FieldVector<double,k>> : std::true_type{};
    \n-
    386 template<int k> struct isValidBlock<FieldVector<float,k>> : std::true_type{};
    \n-
    387
    \n-
    388 template<class TL, typename M>
    \n-
    389 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    390 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    391 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& /*config*/,
    \n-
    392 std::enable_if_t<isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    393 {
    \n-
    394 using D = typename Dune::TypeListElement<1, TL>::type;
    \n-
    395 auto solver = std::make_shared<Dune::Cholmod<D>>();
    \n-
    396 solver->setMatrix(mat);
    \n-
    397 return solver;
    \n-
    398 }
    \n-
    399
    \n-
    400 // second version with SFINAE to validate the template parameters of Cholmod
    \n-
    401 template<typename TL, typename M>
    \n-
    402 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    403 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    404 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n-
    405 std::enable_if_t<!isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    406 {
    \n-
    407 DUNE_THROW(UnsupportedType, "Unsupported Type in Cholmod");
    \n-
    408 }
    \n-
    409 };
    \n-
    410 DUNE_REGISTER_DIRECT_SOLVER("cholmod", Dune::CholmodCreator());
    \n-
    411
    \n-
    412} /* namespace Dune */
    \n-
    413
    \n-
    414#endif // HAVE_SUITESPARSE_CHOLMOD
    \n-
    Define general, extensible interface for inverse operators.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n-\n-
    Implementation of the BCRSMatrix class.
    \n-
    DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    22namespace Dune{
    \n+
    27 namespace {
    \n+
    28 struct DirectSolverTag {};
    \n+
    29 struct PreconditionerTag {};
    \n+
    30 struct IterativeSolverTag {};
    \n+
    31 }
    \n+
    32 template<template<class,class,class,int>class Preconditioner, int blockLevel=1>
    \n+\n+
    34 return [](auto typeList, const auto& matrix, const Dune::ParameterTree& config)
    \n+
    35 {
    \n+
    36 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n+
    37 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n+
    38 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;
    \n+
    39 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
    \n+
    40 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(matrix, config);
    \n+
    41 return preconditioner;
    \n+
    42 };
    \n+
    43 }
    \n+
    44
    \n+
    45 template<template<class,class,class>class Preconditioner>
    \n+\n+
    47 return [](auto typeList, const auto& matrix, const Dune::ParameterTree& config)
    \n+
    48 {
    \n+
    49 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n+
    50 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n+
    51 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;
    \n+
    52 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
    \n+
    53 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(matrix, config);
    \n+
    54 return preconditioner;
    \n+
    55 };
    \n+
    56 }
    \n+
    57
    \n+
    58 template<template<class...>class Solver>
    \n+\n+
    60 return [](auto typeList,
    \n+
    61 const auto& linearOperator,
    \n+
    62 const auto& scalarProduct,
    \n+
    63 const auto& preconditioner,
    \n+
    64 const Dune::ParameterTree& config)
    \n+
    65 {
    \n+
    66 using Domain = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n+
    67 using Range = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n+
    68 std::shared_ptr<Dune::InverseOperator<Domain, Range>> solver
    \n+
    69 = std::make_shared<Solver<Domain>>(linearOperator, scalarProduct, preconditioner, config);
    \n+
    70 return solver;
    \n+
    71 };
    \n+
    72 }
    \n+
    73
    \n+
    74 /* This exception is thrown, when the requested solver is in the factory but
    \n+
    75 cannot be instantiated for the required template parameters
    \n+
    76 */
    \n+
    77 class UnsupportedType : public NotImplemented {};
    \n+
    78
    \n+
    79 class InvalidSolverFactoryConfiguration : public InvalidStateException{};
    \n+
    80} // end namespace Dune
    \n+
    81
    \n+
    82#endif // DUNE_ISTL_SOLVERREGISTRY_HH
    \n+\n+
    Define general, extensible interface for inverse operators.
    \n+\n+
    auto defaultIterativeSolverCreator()
    Definition: solverregistry.hh:59
    \n+
    auto defaultPreconditionerBlockLevelCreator()
    Definition: solverregistry.hh:33
    \n+
    auto defaultPreconditionerCreator()
    Definition: solverregistry.hh:46
    \n
    Definition: allocator.hh:11
    \n-
    std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f, std::size_t rowOffset=0, std::size_t colOffset=0)
    Traverse a blocked matrix and call a functor at each scalar entry.
    Definition: foreach.hh:132
    \n-
    std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)
    Traverse a blocked vector and call a functor at each scalar entry.
    Definition: foreach.hh:95
    \n-
    Category
    Definition: solvercategory.hh:23
    \n+
    constexpr std::size_t blockLevel()
    Determine the block level of a possibly nested vector/matrix type.
    Definition: blocklevel.hh:176
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    Definition: solverregistry.hh:77
    \n+
    Definition: solverregistry.hh:79
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-utf-8\n+us-ascii\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,411 +4,123 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-cholmod.hh\n+solverregistry.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3#pragma once\n- 4\n- 5#if HAVE_SUITESPARSE_CHOLMOD\n- 6\n- 7#include \n- 8#include \n- 9#include \n- 10#include \n- 11#include\n- 12#include \n- 13#include \n- 14\n- 15#include \n- 16#include \n- 17\n- 18#include \n- 19\n- 20namespace Dune {\n+ 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n+ 4// vi: set et ts=4 sw=2 sts=2:\n+ 5\n+ 6#ifndef DUNE_ISTL_SOLVERREGISTRY_HH\n+ 7#define DUNE_ISTL_SOLVERREGISTRY_HH\n+ 8\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12\n+13#define DUNE_REGISTER_DIRECT_SOLVER(name, ...) \\\n+ 14 DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)\n+ 15\n+16#define DUNE_REGISTER_PRECONDITIONER(name, ...) \\\n+ 17 DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)\n+ 18\n+19#define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...) \\\n+ 20 DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)\n 21\n- 22namespace Impl{\n- 23\n- 32 struct NoIgnore\n- 33 {\n- 34 const NoIgnore& operator[](std::size_t) const { return *this; }\n- 35 explicit operator bool() const { return false; }\n- 36 static constexpr std::size_t size() { return 0; }\n- 37\n- 38 };\n- 39\n- 40\n- 41 template\n- 42 void copyToFlatVector(const BlockedVector& blockedVector, FlatVector&\n-flatVector)\n- 43 {\n- 44 // traverse the vector once just to compute the size\n- 45 std::size_t len = flatVectorForEach(blockedVector, [&](auto&&, auto...){});\n- 46 flatVector.resize(len);\n- 47\n- 48 flatVectorForEach(blockedVector, [&](auto&& entry, auto offset){\n- 49 flatVector[offset] = entry;\n- 50 });\n- 51 }\n- 52\n- 53 // special (dummy) case for NoIgnore\n- 54 template\n- 55 void copyToFlatVector(const NoIgnore&, FlatVector&)\n- 56 {\n- 57 // just do nothing\n- 58 return;\n- 59 }\n- 60\n- 61 template\n- 62 void copyToBlockedVector(const FlatVector& flatVector, BlockedVector&\n-blockedVector)\n- 63 {\n- 64 flatVectorForEach(blockedVector, [&](auto& entry, auto offset){\n- 65 entry = flatVector[offset];\n- 66 });\n- 67 }\n- 68\n- 69\n- 70} //namespace Impl\n- 71\n- 76template\n- 77class Cholmod : public InverseOperator\n- 78{\n- 79public:\n- 80\n- 86 Cholmod()\n- 87 {\n- 88 cholmod_start(&c_);\n- 89 }\n- 90\n- 96 ~Cholmod()\n- 97 {\n- 98 if (L_)\n- 99 cholmod_free_factor(&L_, &c_);\n- 100 cholmod_finish(&c_);\n- 101 }\n- 102\n- 103 // forbid copying to avoid freeing memory twice\n- 104 Cholmod(const Cholmod&) = delete;\n- 105 Cholmod& operator=(const Cholmod&) = delete;\n- 106\n- 107\n- 110 void apply (Vector& x, Vector& b, [[maybe_unused]] double reduction,\n-InverseOperatorResult& res)\n- 111 {\n- 112 apply(x,b,res);\n- 113 }\n- 114\n- 120 void apply(Vector& x, Vector& b, InverseOperatorResult& res)\n- 121 {\n- 122 // do nothing if N=0\n- 123 if ( nIsZero_ )\n- 124 {\n- 125 return;\n- 126 }\n- 127\n- 128 if (x.size() != b.size())\n- 129 DUNE_THROW(Exception, \"Error in apply(): sizes of x and b do not match!\");\n- 130\n- 131 // cast to double array\n- 132 auto b2 = std::make_unique(L_->n);\n- 133 auto x2 = std::make_unique(L_->n);\n- 134\n- 135 // copy to cholmod\n- 136 auto bp = b2.get();\n- 137\n- 138 flatVectorForEach(b, [&](auto&& entry, auto&& flatIndex){\n- 139 if ( subIndices_.empty() )\n- 140 bp[ flatIndex ] = entry;\n- 141 else\n- 142 if( subIndices_[ flatIndex ] != std::numeric_limits::max() )\n- 143 bp[ subIndices_[ flatIndex ] ] = entry;\n- 144 });\n- 145\n- 146 // create a cholmod dense object\n- 147 auto b3 = make_cholmod_dense(cholmod_allocate_dense(L_->n, 1, L_->n,\n-CHOLMOD_REAL, &c_), &c_);\n- 148 // cast because void-ptr\n- 149 auto b4 = static_cast(b3->x);\n- 150 std::copy(b2.get(), b2.get() + L_->n, b4);\n- 151\n- 152 // solve for a cholmod x object\n- 153 auto x3 = make_cholmod_dense(cholmod_solve(CHOLMOD_A, L_, b3.get(), &c_),\n-&c_);\n- 154 // cast because void-ptr\n- 155 auto xp = static_cast(x3->x);\n- 156\n- 157 // copy into x\n- 158 flatVectorForEach(x, [&](auto&& entry, auto&& flatIndex){\n- 159 if ( subIndices_.empty() )\n- 160 entry = xp[ flatIndex ];\n- 161 else\n- 162 if( subIndices_[ flatIndex ] != std::numeric_limits::max() )\n- 163 entry = xp[ subIndices_[ flatIndex ] ];\n- 164 });\n- 165\n- 166 // statistics for a direct solver\n- 167 res.iterations = 1;\n- 168 res.converged = true;\n- 169 }\n- 170\n- 171\n- 177 template\n- 178 void setMatrix(const Matrix& matrix)\n- 179 {\n- 180 const Impl::NoIgnore* noIgnore = nullptr;\n- 181 setMatrix(matrix, noIgnore);\n- 182 }\n- 183\n- 198 template\n- 199 void setMatrix(const Matrix& matrix, const Ignore* ignore)\n- 200 {\n- 201 // count the number of entries and diagonal entries\n- 202 int nonZeros = 0;\n- 203 int numberOfIgnoredDofs = 0;\n- 204\n- 205\n- 206 auto [flatRows,flatCols] = flatMatrixForEach( matrix, [&](auto&& /\n-*entry*/, auto&& flatRowIndex, auto&& flatColIndex){\n- 207 if( flatRowIndex <= flatColIndex )\n- 208 nonZeros++;\n- 209 });\n- 210\n- 211 std::vector flatIgnore;\n- 212\n- 213 if ( ignore )\n- 214 {\n- 215 Impl::copyToFlatVector(*ignore,flatIgnore);\n- 216 numberOfIgnoredDofs = std::count(flatIgnore.begin(),flatIgnore.end\n-(),true);\n- 217 }\n- 218\n- 219 // Total number of rows\n- 220 int N = flatRows - numberOfIgnoredDofs;\n- 221\n- 222 nIsZero_ = (N <= 0);\n- 223\n- 224 if ( nIsZero_ )\n- 225 {\n- 226 return;\n- 227 }\n- 228\n- 229 /*\n- 230 * CHOLMOD uses compressed-column sparse matrices, but for symmetric\n- 231 * matrices this is the same as the compressed-row sparse matrix used\n- 232 * by DUNE. So we can just store M\u1d40 instead of M (as M = M\u1d40).\n- 233 */\n- 234 const auto deleter = [c = &this->c_](auto* p) {\n- 235 cholmod_free_sparse(&p, c);\n- 236 };\n- 237 auto M = std::unique_ptr(\n- 238 cholmod_allocate_sparse(N, // # rows\n- 239 N, // # cols\n- 240 nonZeros, // # of nonzeroes\n- 241 1, // indices are sorted ( 1 = true)\n- 242 1, // matrix is \"packed\" ( 1 = true)\n- 243 -1, // stype of matrix ( -1 = consider the lower part only )\n- 244 CHOLMOD_REAL, // xtype of matrix ( CHOLMOD_REAL = single array, no complex\n-numbers)\n- 245 &c_ // cholmod_common ptr\n- 246 ), deleter);\n- 247\n- 248 // copy the data of BCRS matrix to Cholmod Sparse matrix\n- 249 int* Ap = static_cast(M->p);\n- 250 int* Ai = static_cast(M->i);\n- 251 double* Ax = static_cast(M->x);\n- 252\n- 253\n- 254 if ( ignore )\n- 255 {\n- 256 // init the mapping\n- 257 subIndices_.resize(flatRows,std::numeric_limits::max());\n- 258\n- 259 std::size_t subIndexCounter = 0;\n- 260\n- 261 for ( std::size_t i=0; i flatColIndex )\n- 280 return;\n- 281\n- 282 // ok, count the entry\n- 283 auto idx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;\n- 284 Ap[idx+1]++;\n- 285\n- 286 });\n- 287\n- 288 // now accumulate\n- 289 Ap[0] = 0;\n- 290 for ( int i=0; i rowPosition(N,0);\n- 297\n- 298 // now we can set the entries\n- 299 flatMatrixForEach(matrix, [&](auto&& entry, auto&& flatRowIndex, auto&&\n-flatColIndex){\n- 300\n- 301 // stop if ignored\n- 302 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )\n- 303 return;\n- 304\n- 305 // stop if in lower half\n- 306 if ( flatRowIndex > flatColIndex )\n- 307 return;\n- 308\n- 309 // ok, set the entry\n- 310 auto rowIdx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;\n- 311 auto colIdx = ignore ? subIndices_[flatColIndex] : flatColIndex;\n- 312 auto rowStart = Ap[rowIdx];\n- 313 auto rowPos = rowPosition[rowIdx];\n- 314 Ai[ rowStart + rowPos ] = colIdx;\n- 315 Ax[ rowStart + rowPos ] = entry;\n- 316 rowPosition[rowIdx]++;\n- 317\n- 318 });\n- 319\n- 320 // Now analyse the pattern and optimal row order\n- 321 L_ = cholmod_analyze(M.get(), &c_);\n- 322\n- 323 // Do the factorization (this may take some time)\n- 324 cholmod_factorize(M.get(), L_, &c_);\n- 325 }\n- 326\n- 327 virtual SolverCategory::Category category() const\n- 328 {\n- 329 return SolverCategory::Category::sequential;\n- 330 }\n- 331\n- 337 cholmod_common& cholmodCommonObject()\n- 338 {\n- 339 return c_;\n- 340 }\n- 341\n- 347 cholmod_factor& cholmodFactor()\n- 348 {\n- 349 return *L_;\n- 350 }\n- 351\n- 357 const cholmod_factor& cholmodFactor() const\n- 358 {\n- 359 return *L_;\n- 360 }\n- 361private:\n- 362\n- 363 // create a std::unique_ptr to a cholmod_dense object with a deleter\n- 364 // that calls the appropriate cholmod cleanup routine\n- 365 auto make_cholmod_dense(cholmod_dense* x, cholmod_common* c)\n- 366 {\n- 367 const auto deleter = [c](auto* p) {\n- 368 cholmod_free_dense(&p, c);\n- 369 };\n- 370 return std::unique_ptr(x, deleter);\n- 371 }\n- 372\n- 373 cholmod_common c_;\n- 374 cholmod_factor* L_ = nullptr;\n- 375\n- 376 // indicator for a 0x0 problem (due to ignore dof's)\n- 377 bool nIsZero_ = false;\n- 378\n- 379 // vector mapping all indices in flat order to the not ignored indices\n- 380 std::vector subIndices_;\n- 381};\n- 382\n- 383 struct CholmodCreator{\n- 384 template struct isValidBlock : std::false_type{};\n- 385 template struct isValidBlock> : std::\n-true_type{};\n- 386 template struct isValidBlock> : std::true_type\n-{};\n- 387\n- 388 template\n- 389 std::shared_ptr::type,\n- 390 typename Dune::TypeListElement<2, TL>::type>>\n- 391 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& /*config*/,\n- 392 std::enable_if_t::\n-type::block_type>::value,int> = 0) const\n- 393 {\n- 394 using D = typename Dune::TypeListElement<1, TL>::type;\n- 395 auto solver = std::make_shared>();\n- 396 solver->setMatrix(mat);\n- 397 return solver;\n- 398 }\n- 399\n- 400 // second version with SFINAE to validate the template parameters of\n-Cholmod\n- 401 template\n- 402 std::shared_ptr::type,\n- 403 typename Dune::TypeListElement<2, TL>::type>>\n- 404 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n-*config*/,\n- 405 std::enable_if_t::\n-type::block_type>::value,int> = 0) const\n- 406 {\n- 407 DUNE_THROW(UnsupportedType, \"Unsupported Type in Cholmod\");\n- 408 }\n- 409 };\n- 410 DUNE_REGISTER_DIRECT_SOLVER(\"cholmod\", Dune::CholmodCreator());\n- 411\n- 412} /* namespace Dune */\n- 413\n- 414#endif // HAVE_SUITESPARSE_CHOLMOD\n+ 22namespace Dune{\n+ 27 namespace {\n+ 28 struct DirectSolverTag {};\n+ 29 struct PreconditionerTag {};\n+ 30 struct IterativeSolverTag {};\n+ 31 }\n+ 32 templateclass Preconditioner, int\n+blockLevel=1>\n+33 auto defaultPreconditionerBlockLevelCreator(){\n+ 34 return [](auto typeList, const auto& matrix, const Dune::ParameterTree&\n+config)\n+ 35 {\n+ 36 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n+ 37 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n+ 38 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;\n+ 39 std::shared_ptr> preconditioner\n+ 40 = std::make_shared>\n+(matrix, config);\n+ 41 return preconditioner;\n+ 42 };\n+ 43 }\n+ 44\n+ 45 templateclass Preconditioner>\n+46 auto defaultPreconditionerCreator(){\n+ 47 return [](auto typeList, const auto& matrix, const Dune::ParameterTree&\n+config)\n+ 48 {\n+ 49 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n+ 50 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n+ 51 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;\n+ 52 std::shared_ptr> preconditioner\n+ 53 = std::make_shared>(matrix, config);\n+ 54 return preconditioner;\n+ 55 };\n+ 56 }\n+ 57\n+ 58 templateclass Solver>\n+59 auto defaultIterativeSolverCreator(){\n+ 60 return [](auto typeList,\n+ 61 const auto& linearOperator,\n+ 62 const auto& scalarProduct,\n+ 63 const auto& preconditioner,\n+ 64 const Dune::ParameterTree& config)\n+ 65 {\n+ 66 using Domain = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n+ 67 using Range = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n+ 68 std::shared_ptr> solver\n+ 69 = std::make_shared>(linearOperator, scalarProduct,\n+preconditioner, config);\n+ 70 return solver;\n+ 71 };\n+ 72 }\n+ 73\n+ 74 /* This exception is thrown, when the requested solver is in the factory\n+but\n+ 75 cannot be instantiated for the required template parameters\n+ 76 */\n+77 class UnsupportedType : public NotImplemented {};\n+ 78\n+79 class InvalidSolverFactoryConfiguration : public InvalidStateException{};\n+ 80} // end namespace Dune\n+ 81\n+ 82#endif // DUNE_ISTL_SOLVERREGISTRY_HH\n+registry.hh\n solver.hh\n Define general, extensible interface for inverse operators.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-foreach.hh\n-solverfactory.hh\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-Dune::DUNE_REGISTER_DIRECT_SOLVER\n-DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n+preconditioner.hh\n+Dune::defaultIterativeSolverCreator\n+auto defaultIterativeSolverCreator()\n+Definition: solverregistry.hh:59\n+Dune::defaultPreconditionerBlockLevelCreator\n+auto defaultPreconditionerBlockLevelCreator()\n+Definition: solverregistry.hh:33\n+Dune::defaultPreconditionerCreator\n+auto defaultPreconditionerCreator()\n+Definition: solverregistry.hh:46\n Dune\n Definition: allocator.hh:11\n-Dune::flatMatrixForEach\n-std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f,\n-std::size_t rowOffset=0, std::size_t colOffset=0)\n-Traverse a blocked matrix and call a functor at each scalar entry.\n-Definition: foreach.hh:132\n-Dune::flatVectorForEach\n-std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)\n-Traverse a blocked vector and call a functor at each scalar entry.\n-Definition: foreach.hh:95\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n+Dune::blockLevel\n+constexpr std::size_t blockLevel()\n+Determine the block level of a possibly nested vector/matrix type.\n+Definition: blocklevel.hh:176\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::UnsupportedType\n+Definition: solverregistry.hh:77\n+Dune::InvalidSolverFactoryConfiguration\n+Definition: solverregistry.hh:79\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00032.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00032.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: operators.hh File Reference\n+dune-istl: registry.hh File Reference\n \n \n \n \n \n \n \n@@ -58,57 +58,94 @@\n \n
    \n \n \n
    \n \n+
    registry.hh File Reference
    \n
    \n
    \n-\n-

    Define general, extensible interface for operators. The available implementation wraps a matrix. \n-More...

    \n-
    #include <cmath>
    \n-#include <complex>
    \n+
    #include <cstddef>
    \n #include <iostream>
    \n-#include <iomanip>
    \n+#include <memory>
    \n #include <string>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/shared_ptr.hh>
    \n-#include "solvercategory.hh"
    \n+#include <utility>
    \n+#include "counter.hh"
    \n+#include <dune/common/typelist.hh>
    \n+#include <dune/common/hybridutilities.hh>
    \n+#include <dune/common/parameterizedobject.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    class  Dune::LinearOperator< X, Y >
     A linear operator. More...
     
    class  Dune::AssembledLinearOperator< M, X, Y >
     A linear operator exporting itself in matrix form. More...
     
    class  Dune::MatrixAdapter< M, X, Y >
     Adapter to turn a matrix into a linear operator. More...
     
    \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n

    \n+Macros

    #define DUNE_REGISTRY_PUT(Tag, id, ...)
     
    \n-

    Detailed Description

    \n-

    Define general, extensible interface for operators. The available implementation wraps a matrix.

    \n-
    \n+

    Macro Definition Documentation

    \n+\n+

    ◆ DUNE_REGISTRY_PUT

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_REGISTRY_PUT( Tag,
     id,
     ... 
    )
    \n+
    \n+Value:
    namespace { \\
    \n+
    template<> \\
    \n+
    struct Registry<Tag, DUNE_GET_COUNTER(Tag)> \\
    \n+
    { \\
    \n+
    static auto getCreator() \\
    \n+
    { \\
    \n+
    return __VA_ARGS__; \\
    \n+
    } \\
    \n+
    static std::string name() { return id; } \\
    \n+
    }; \\
    \n+
    } \\
    \n+
    DUNE_INC_COUNTER(Tag)
    \n+
    #define DUNE_GET_COUNTER(Tag)
    Definition: counter.hh:17
    \n+
    \n+
    \n+
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,41 +4,51 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-operators.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Operator\n-concept\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix. More...\n-#include \n-#include \n+ * common\n+Namespaces | Macros\n+registry.hh File Reference\n+#include \n #include \n-#include \n+#include \n #include \n-#include \n-#include \n-#include \"solvercategory.hh\"\n+#include \n+#include \"counter.hh\"\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n- Classes\n-class \u00a0Dune::LinearOperator<_X,_Y_>\n-\u00a0 A linear operator. More...\n-\u00a0\n-class \u00a0Dune::AssembledLinearOperator<_M,_X,_Y_>\n-\u00a0 A linear operator exporting itself in matrix form. More...\n-\u00a0\n-class \u00a0Dune::MatrixAdapter<_M,_X,_Y_>\n-\u00a0 Adapter to turn a matrix into a linear operator. More...\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-***** Detailed Description *****\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n+ Macros\n+#define\u00a0DUNE_REGISTRY_PUT(Tag, id, ...)\n+\u00a0\n+***** Macro Definition Documentation *****\n+***** \u25c6\u00a0DUNE_REGISTRY_PUT *****\n+#define DUNE_REGISTRY_PUT ( \u00a0Tag,\n+ \u00a0id,\n+ \u00a0...\u00a0\n+ )\n+Value:\n+namespace { \\\n+template<> \\\n+struct Registry \\\n+{ \\\n+static auto getCreator() \\\n+{ \\\n+return __VA_ARGS__; \\\n+} \\\n+static std::string name() { return id; } \\\n+}; \\\n+} \\\n+DUNE_INC_COUNTER(Tag)\n+DUNE_GET_COUNTER\n+#define DUNE_GET_COUNTER(Tag)\n+Definition: counter.hh:17\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00032_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00032_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: operators.hh Source File\n+dune-istl: registry.hh Source File\n \n \n \n \n \n \n \n@@ -58,160 +58,104 @@\n \n
    \n \n \n
    \n
    \n-
    operators.hh
    \n+
    registry.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n-
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_OPERATORS_HH
    \n-
    6#define DUNE_ISTL_OPERATORS_HH
    \n-
    7
    \n-
    8#include <cmath>
    \n-
    9#include <complex>
    \n-
    10#include <iostream>
    \n-
    11#include <iomanip>
    \n-
    12#include <string>
    \n+
    3#ifndef DUNE_ISTL_COMMON_REGISTRY_HH
    \n+
    4#define DUNE_ISTL_COMMON_REGISTRY_HH
    \n+
    5
    \n+
    6#include <cstddef>
    \n+
    7#include <iostream>
    \n+
    8#include <memory>
    \n+
    9#include <string>
    \n+
    10#include <utility>
    \n+
    11
    \n+
    12#include "counter.hh"
    \n
    13
    \n-
    14#include <dune/common/exceptions.hh>
    \n-
    15#include <dune/common/shared_ptr.hh>
    \n-
    16
    \n-
    17#include "solvercategory.hh"
    \n-
    18
    \n-
    19
    \n-
    20namespace Dune {
    \n-
    21
    \n-
    44 //=====================================================================
    \n-
    45 // Abstract operator interface
    \n-
    46 //=====================================================================
    \n-
    47
    \n-
    48
    \n-
    66 template<class X, class Y>
    \n-\n-
    68 public:
    \n-
    70 typedef X domain_type;
    \n-
    72 typedef Y range_type;
    \n-
    74 typedef typename X::field_type field_type;
    \n-
    75
    \n-
    80 virtual void apply (const X& x, Y& y) const = 0;
    \n-
    81
    \n-
    83 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const = 0;
    \n-
    84
    \n-
    86 virtual ~LinearOperator () {}
    \n-
    87
    \n-\n-
    90#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n-
    91 {
    \n-
    92 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n-
    93 };
    \n-
    94#else
    \n-
    95 = 0;
    \n-
    96#endif
    \n-
    97 };
    \n-
    98
    \n-
    99
    \n-
    108 template<class M, class X, class Y>
    \n-\n-
    110 public:
    \n-
    112 typedef M matrix_type;
    \n-
    113 typedef X domain_type;
    \n-
    114 typedef Y range_type;
    \n-
    115 typedef typename X::field_type field_type;
    \n-
    116
    \n-
    118 virtual const M& getmat () const = 0;
    \n-
    119
    \n-\n-
    122 };
    \n-
    123
    \n-
    124
    \n-
    125
    \n-
    126 //=====================================================================
    \n-
    127 // Implementation for ISTL-matrix based operator
    \n-
    128 //=====================================================================
    \n-
    129
    \n-
    135 template<class M, class X, class Y>
    \n-\n-
    137 {
    \n-
    138 public:
    \n-
    140 typedef M matrix_type;
    \n-
    141 typedef X domain_type;
    \n-
    142 typedef Y range_type;
    \n-
    143 typedef typename X::field_type field_type;
    \n-
    144
    \n-
    146 explicit MatrixAdapter (const M& A) : _A_(stackobject_to_shared_ptr(A)) {}
    \n-
    147
    \n-
    149 explicit MatrixAdapter (std::shared_ptr<const M> A) : _A_(A) {}
    \n-
    150
    \n-
    152 void apply (const X& x, Y& y) const override
    \n-
    153 {
    \n-
    154 _A_->mv(x,y);
    \n-
    155 }
    \n-
    156
    \n-
    158 void applyscaleadd (field_type alpha, const X& x, Y& y) const override
    \n-
    159 {
    \n-
    160 _A_->usmv(alpha,x,y);
    \n-
    161 }
    \n-
    162
    \n-
    164 const M& getmat () const override
    \n-
    165 {
    \n-
    166 return *_A_;
    \n-
    167 }
    \n-
    168
    \n-\n-
    171 {
    \n-\n-
    173 }
    \n-
    174
    \n-
    175 private:
    \n-
    176 const std::shared_ptr<const M> _A_;
    \n-
    177 };
    \n-
    178
    \n-
    181} // end namespace
    \n-
    182
    \n-
    183#endif
    \n-\n+
    14#include <dune/common/typelist.hh>
    \n+
    15#include <dune/common/hybridutilities.hh>
    \n+
    16#include <dune/common/parameterizedobject.hh>
    \n+
    17
    \n+
    18#define DUNE_REGISTRY_PUT(Tag, id, ...) \\
    \n+
    19 namespace { \\
    \n+
    20 template<> \\
    \n+
    21 struct Registry<Tag, DUNE_GET_COUNTER(Tag)> \\
    \n+
    22 { \\
    \n+
    23 static auto getCreator() \\
    \n+
    24 { \\
    \n+
    25 return __VA_ARGS__; \\
    \n+
    26 } \\
    \n+
    27 static std::string name() { return id; } \\
    \n+
    28 }; \\
    \n+
    29 } \\
    \n+
    30 DUNE_INC_COUNTER(Tag)
    \n+
    31
    \n+
    32
    \n+
    33namespace Dune {
    \n+
    34 namespace {
    \n+
    35 template<class Tag, std::size_t index>
    \n+
    36 struct Registry;
    \n+
    37 }
    \n+
    38
    \n+
    39 namespace {
    \n+
    40 template<template<class> class Base, class V, class Tag, typename... Args>
    \n+
    41 auto registryGet(Tag , std::string name, Args... args)
    \n+
    42 {
    \n+
    43 constexpr auto count = DUNE_GET_COUNTER(Tag);
    \n+
    44 std::shared_ptr<Base<V> > result;
    \n+
    45 Dune::Hybrid::forEach(std::make_index_sequence<count>{},
    \n+
    46 [&](auto index) {
    \n+
    47 using Reg = Registry<Tag, index>;
    \n+
    48 if(!result && Reg::name() == name) {
    \n+
    49 result = Reg::getCreator()(Dune::MetaType<V>{}, args...);
    \n+
    50 }
    \n+
    51 });
    \n+
    52 return result;
    \n+
    53 }
    \n+
    54
    \n+
    55 /*
    \n+
    56 Register all creators from the registry in the Parameterizedobjectfactory An
    \n+
    57 object of V is passed in the creator ans should be used to determine the
    \n+
    58 template arguments.
    \n+
    59 */
    \n+
    60 template<class V, class Type, class Tag, class... Args>
    \n+
    61 int addRegistryToFactory(Dune::ParameterizedObjectFactory<Type(Args...), std::string>& factory,
    \n+
    62 Tag){
    \n+
    63 constexpr auto count = DUNE_GET_COUNTER(Tag);
    \n+
    64 Dune::Hybrid::forEach(std::make_index_sequence<count>{},
    \n+
    65 [&](auto index) {
    \n+
    66 // we first get the generic lambda
    \n+
    67 // and later specialize it with given parameters.
    \n+
    68 // doing all at once lead to an ICE woth g++-6
    \n+
    69 using Reg = Registry<Tag, index>;
    \n+
    70 auto genericcreator = Reg::getCreator();
    \n+
    71 factory.define(Reg::name(), [genericcreator](Args... args){
    \n+
    72 return genericcreator(V{}, args...);
    \n+
    73 });
    \n+
    74 });
    \n+
    75 return count;
    \n+
    76 }
    \n+
    77 } // end anonymous namespace
    \n+
    78} // end namespace Dune
    \n+
    79
    \n+
    80#endif // DUNE_ISTL_COMMON_REGISTRY_HH
    \n+\n+
    #define DUNE_GET_COUNTER(Tag)
    Definition: counter.hh:17
    \n
    Definition: allocator.hh:11
    \n-
    A linear operator.
    Definition: operators.hh:67
    \n-
    virtual ~LinearOperator()
    every abstract base class has a virtual destructor
    Definition: operators.hh:86
    \n-
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n-
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const =0
    apply operator to x, scale and add:
    \n-
    virtual SolverCategory::Category category() const =0
    Category of the linear operator (see SolverCategory::Category)
    \n-
    Y range_type
    The type of the range of the operator.
    Definition: operators.hh:72
    \n-
    virtual void apply(const X &x, Y &y) const =0
    apply operator to x: The input vector is consistent and the output must also be consistent on the in...
    \n-
    X domain_type
    The type of the domain of the operator.
    Definition: operators.hh:70
    \n-
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n-
    virtual const M & getmat() const =0
    get matrix via *
    \n-
    X domain_type
    Definition: operators.hh:113
    \n-
    X::field_type field_type
    Definition: operators.hh:115
    \n-
    Y range_type
    Definition: operators.hh:114
    \n-
    M matrix_type
    export types, usually they come from the derived class
    Definition: operators.hh:112
    \n-
    virtual ~AssembledLinearOperator()
    every abstract base class has a virtual destructor
    Definition: operators.hh:121
    \n-
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n-
    MatrixAdapter(std::shared_ptr< const M > A)
    constructor: store an std::shared_ptr to a matrix
    Definition: operators.hh:149
    \n-
    MatrixAdapter(const M &A)
    constructor: just store a reference to a matrix
    Definition: operators.hh:146
    \n-
    void applyscaleadd(field_type alpha, const X &x, Y &y) const override
    apply operator to x, scale and add:
    Definition: operators.hh:158
    \n-
    Y range_type
    Definition: operators.hh:142
    \n-
    X domain_type
    Definition: operators.hh:141
    \n-
    X::field_type field_type
    Definition: operators.hh:143
    \n-
    const M & getmat() const override
    get matrix via *
    Definition: operators.hh:164
    \n-
    SolverCategory::Category category() const override
    Category of the solver (see SolverCategory::Category)
    Definition: operators.hh:170
    \n-
    void apply(const X &x, Y &y) const override
    apply operator to x:
    Definition: operators.hh:152
    \n-
    M matrix_type
    export types
    Definition: operators.hh:140
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,225 +4,102 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-operators.hh\n+ * common\n+registry.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n- 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_OPERATORS_HH\n- 6#define DUNE_ISTL_OPERATORS_HH\n- 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n+ 3#ifndef DUNE_ISTL_COMMON_REGISTRY_HH\n+ 4#define DUNE_ISTL_COMMON_REGISTRY_HH\n+ 5\n+ 6#include \n+ 7#include \n+ 8#include \n+ 9#include \n+ 10#include \n+ 11\n+ 12#include \"counter.hh\"\n 13\n- 14#include \n- 15#include \n- 16\n- 17#include \"solvercategory.hh\"\n- 18\n- 19\n- 20namespace Dune {\n- 21\n- 44 //=====================================================================\n- 45 // Abstract operator interface\n- 46 //=====================================================================\n- 47\n- 48\n- 66 template\n-67 class LinearOperator {\n- 68 public:\n-70 typedef X domain_type;\n-72 typedef Y range_type;\n-74 typedef typename X::field_type field_type;\n- 75\n-80 virtual void apply (const X& x, Y& y) const = 0;\n- 81\n-83 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const = 0;\n- 84\n-86 virtual ~LinearOperator () {}\n- 87\n-89 virtual SolverCategory::Category category() const\n- 90#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n- 91 {\n- 92 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n-method in a derived classes, in the future this method will pure virtual.\");\n- 93 };\n- 94#else\n- 95 = 0;\n- 96#endif\n- 97 };\n- 98\n- 99\n- 108 template\n-109 class AssembledLinearOperator : public LinearOperator {\n- 110 public:\n-112 typedef M matrix_type;\n-113 typedef X domain_type;\n-114 typedef Y range_type;\n-115 typedef typename X::field_type field_type;\n- 116\n-118 virtual const M& getmat () const = 0;\n- 119\n-121 virtual ~AssembledLinearOperator () {}\n- 122 };\n- 123\n- 124\n- 125\n- 126 //=====================================================================\n- 127 // Implementation for ISTL-matrix based operator\n- 128 //=====================================================================\n- 129\n- 135 template\n-136 class MatrixAdapter : public AssembledLinearOperator\n- 137 {\n- 138 public:\n-140 typedef M matrix_type;\n-141 typedef X domain_type;\n-142 typedef Y range_type;\n-143 typedef typename X::field_type field_type;\n- 144\n-146 explicit MatrixAdapter (const M& A) : _A_(stackobject_to_shared_ptr(A)) {}\n- 147\n-149 explicit MatrixAdapter (std::shared_ptr A) : _A_(A) {}\n- 150\n-152 void apply (const X& x, Y& y) const override\n- 153 {\n- 154 _A_->mv(x,y);\n- 155 }\n- 156\n-158 void applyscaleadd (field_type alpha, const X& x, Y& y) const override\n- 159 {\n- 160 _A_->usmv(alpha,x,y);\n- 161 }\n- 162\n-164 const M& getmat () const override\n- 165 {\n- 166 return *_A_;\n- 167 }\n- 168\n-170 SolverCategory::Category category() const override\n- 171 {\n- 172 return SolverCategory::sequential;\n- 173 }\n- 174\n- 175 private:\n- 176 const std::shared_ptr _A_;\n- 177 };\n- 178\n- 181} // end namespace\n- 182\n- 183#endif\n-solvercategory.hh\n+ 14#include \n+ 15#include \n+ 16#include \n+ 17\n+18#define DUNE_REGISTRY_PUT(Tag, id, ...) \\\n+ 19 namespace { \\\n+ 20 template<> \\\n+ 21 struct Registry \\\n+ 22 { \\\n+ 23 static auto getCreator() \\\n+ 24 { \\\n+ 25 return __VA_ARGS__; \\\n+ 26 } \\\n+ 27 static std::string name() { return id; } \\\n+ 28 }; \\\n+ 29 } \\\n+ 30 DUNE_INC_COUNTER(Tag)\n+ 31\n+ 32\n+ 33namespace Dune {\n+ 34 namespace {\n+ 35 template\n+ 36 struct Registry;\n+ 37 }\n+ 38\n+ 39 namespace {\n+ 40 template class Base, class V, class Tag, typename... Args>\n+ 41 auto registryGet(Tag , std::string name, Args... args)\n+ 42 {\n+ 43 constexpr auto count = DUNE_GET_COUNTER(Tag);\n+ 44 std::shared_ptr > result;\n+ 45 Dune::Hybrid::forEach(std::make_index_sequence{},\n+ 46 [&](auto index) {\n+ 47 using Reg = Registry;\n+ 48 if(!result && Reg::name() == name) {\n+ 49 result = Reg::getCreator()(Dune::MetaType{}, args...);\n+ 50 }\n+ 51 });\n+ 52 return result;\n+ 53 }\n+ 54\n+ 55 /*\n+ 56 Register all creators from the registry in the Parameterizedobjectfactory\n+An\n+ 57 object of V is passed in the creator ans should be used to determine the\n+ 58 template arguments.\n+ 59 */\n+ 60 template\n+ 61 int addRegistryToFactory(Dune::ParameterizedObjectFactory& factory,\n+ 62 Tag){\n+ 63 constexpr auto count = DUNE_GET_COUNTER(Tag);\n+ 64 Dune::Hybrid::forEach(std::make_index_sequence{},\n+ 65 [&](auto index) {\n+ 66 // we first get the generic lambda\n+ 67 // and later specialize it with given parameters.\n+ 68 // doing all at once lead to an ICE woth g++-6\n+ 69 using Reg = Registry;\n+ 70 auto genericcreator = Reg::getCreator();\n+ 71 factory.define(Reg::name(), [genericcreator](Args... args){\n+ 72 return genericcreator(V{}, args...);\n+ 73 });\n+ 74 });\n+ 75 return count;\n+ 76 }\n+ 77 } // end anonymous namespace\n+ 78} // end namespace Dune\n+ 79\n+ 80#endif // DUNE_ISTL_COMMON_REGISTRY_HH\n+counter.hh\n+DUNE_GET_COUNTER\n+#define DUNE_GET_COUNTER(Tag)\n+Definition: counter.hh:17\n Dune\n Definition: allocator.hh:11\n-Dune::LinearOperator\n-A linear operator.\n-Definition: operators.hh:67\n-Dune::LinearOperator::~LinearOperator\n-virtual ~LinearOperator()\n-every abstract base class has a virtual destructor\n-Definition: operators.hh:86\n-Dune::LinearOperator::field_type\n-X::field_type field_type\n-The field type of the operator.\n-Definition: operators.hh:74\n-Dune::LinearOperator::applyscaleadd\n-virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const =0\n-apply operator to x, scale and add:\n-Dune::LinearOperator::category\n-virtual SolverCategory::Category category() const =0\n-Category of the linear operator (see SolverCategory::Category)\n-Dune::LinearOperator::range_type\n-Y range_type\n-The type of the range of the operator.\n-Definition: operators.hh:72\n-Dune::LinearOperator::apply\n-virtual void apply(const X &x, Y &y) const =0\n-apply operator to x: The input vector is consistent and the output must also be\n-consistent on the in...\n-Dune::LinearOperator::domain_type\n-X domain_type\n-The type of the domain of the operator.\n-Definition: operators.hh:70\n-Dune::AssembledLinearOperator\n-A linear operator exporting itself in matrix form.\n-Definition: operators.hh:109\n-Dune::AssembledLinearOperator::getmat\n-virtual const M & getmat() const =0\n-get matrix via *\n-Dune::AssembledLinearOperator::domain_type\n-X domain_type\n-Definition: operators.hh:113\n-Dune::AssembledLinearOperator::field_type\n-X::field_type field_type\n-Definition: operators.hh:115\n-Dune::AssembledLinearOperator::range_type\n-Y range_type\n-Definition: operators.hh:114\n-Dune::AssembledLinearOperator::matrix_type\n-M matrix_type\n-export types, usually they come from the derived class\n-Definition: operators.hh:112\n-Dune::AssembledLinearOperator::~AssembledLinearOperator\n-virtual ~AssembledLinearOperator()\n-every abstract base class has a virtual destructor\n-Definition: operators.hh:121\n-Dune::MatrixAdapter\n-Adapter to turn a matrix into a linear operator.\n-Definition: operators.hh:137\n-Dune::MatrixAdapter::MatrixAdapter\n-MatrixAdapter(std::shared_ptr< const M > A)\n-constructor: store an std::shared_ptr to a matrix\n-Definition: operators.hh:149\n-Dune::MatrixAdapter::MatrixAdapter\n-MatrixAdapter(const M &A)\n-constructor: just store a reference to a matrix\n-Definition: operators.hh:146\n-Dune::MatrixAdapter::applyscaleadd\n-void applyscaleadd(field_type alpha, const X &x, Y &y) const override\n-apply operator to x, scale and add:\n-Definition: operators.hh:158\n-Dune::MatrixAdapter::range_type\n-Y range_type\n-Definition: operators.hh:142\n-Dune::MatrixAdapter::domain_type\n-X domain_type\n-Definition: operators.hh:141\n-Dune::MatrixAdapter::field_type\n-X::field_type field_type\n-Definition: operators.hh:143\n-Dune::MatrixAdapter::getmat\n-const M & getmat() const override\n-get matrix via *\n-Definition: operators.hh:164\n-Dune::MatrixAdapter::category\n-SolverCategory::Category category() const override\n-Category of the solver (see SolverCategory::Category)\n-Definition: operators.hh:170\n-Dune::MatrixAdapter::apply\n-void apply(const X &x, Y &y) const override\n-apply operator to x:\n-Definition: operators.hh:152\n-Dune::MatrixAdapter::matrix_type\n-M matrix_type\n-export types\n-Definition: operators.hh:140\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00035.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00035.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: poweriteration.hh File Reference\n+dune-istl: counter.hh File Reference\n \n \n \n \n \n \n \n@@ -58,55 +58,125 @@\n \n
    \n \n \n
    \n
    \n \n-
    poweriteration.hh File Reference
    \n+Namespaces |\n+Macros |\n+Variables
    \n+
    counter.hh File Reference
    \n
    \n
    \n-
    #include <cstddef>
    \n-#include <cmath>
    \n-#include <type_traits>
    \n+
    #include <cassert>
    \n+#include <typeinfo>
    \n #include <iostream>
    \n-#include <limits>
    \n-#include <ios>
    \n-#include <iomanip>
    \n #include <memory>
    \n-#include <string>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n-#include <dune/istl/operators.hh>
    \n-#include <dune/istl/solvercategory.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n-#include <dune/istl/istlexception.hh>
    \n-#include <dune/istl/io.hh>
    \n-#include <dune/istl/solvers.hh>
    \n+#include <tuple>
    \n+#include <utility>
    \n+#include <dune/common/typeutilities.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-

    \n-Classes

    class  Dune::PowerIteration_Algorithms< BCRSMatrix, BlockVector >
     Iterative eigenvalue algorithms based on power iteration. More...
     
    \n \n \n \n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::CounterImpl
     
    \n+\n+\n+\n+\n+\n+

    \n+Macros

    #define DUNE_GET_COUNTER(Tag)    (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
     
    #define DUNE_INC_COUNTER(Tag)
     
    \n+\n+\n+\n+

    \n+Variables

    constexpr std::size_t maxcount = 100
     
    \n+

    Macro Definition Documentation

    \n+\n+

    ◆ DUNE_GET_COUNTER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_GET_COUNTER( Tag)    (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
    \n+
    \n+\n+
    \n+
    \n+\n+

    ◆ DUNE_INC_COUNTER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+
    #define DUNE_INC_COUNTER( Tag)
    \n+
    \n+Value:
    namespace { \\
    \n+
    namespace CounterImpl { \\
    \n+
    constexpr std::size_t \\
    \n+
    counterFunc(Dune::PriorityTag<DUNE_GET_COUNTER(Tag)+1> p, Tag, ADLTag) \\
    \n+
    { \\
    \n+
    return p.value; \\
    \n+
    } \\
    \n+
    } \\
    \n+
    } \\
    \n+
    static_assert(true, "unfudge indentation")
    \n+
    #define DUNE_GET_COUNTER(Tag)
    Definition: counter.hh:17
    \n+
    \n+
    \n+
    \n+

    Variable Documentation

    \n+\n+

    ◆ maxcount

    \n+\n+
    \n+
    \n+\n+ \n+ \n+ \n+ \n
    \n+ \n+ \n+ \n+ \n+
    constexpr std::size_t maxcount = 100
    \n+
    \n+constexpr
    \n+
    \n+\n+
    \n+
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,38 +4,58 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * eigenvalue\n-Classes | Namespaces\n-poweriteration.hh File Reference\n-#include \n-#include \n-#include \n+ * common\n+Namespaces | Macros | Variables\n+counter.hh File Reference\n+#include \n+#include \n #include \n-#include \n-#include \n-#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n- Classes\n-class \u00a0Dune::PowerIteration_Algorithms<_BCRSMatrix,_BlockVector_>\n-\u00a0 Iterative eigenvalue algorithms based on power iteration. More...\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::CounterImpl\n+\u00a0\n+ Macros\n+#define\u00a0DUNE_GET_COUNTER(Tag)\u00a0\u00a0\u00a0 (counterFunc(Dune::PriorityTag{}, Tag{},\n+ Dune::CounterImpl::ADLTag{}))\n+\u00a0\n+#define\u00a0DUNE_INC_COUNTER(Tag)\n+\u00a0\n+ Variables\n+constexpr std::size_t\u00a0maxcount = 100\n+\u00a0\n+***** Macro Definition Documentation *****\n+***** \u25c6\u00a0DUNE_GET_COUNTER *****\n+#define ( \u00a0Tag ) \u00a0\u00a0\u00a0 (counterFunc(Dune::PriorityTag{}, Tag{}, Dune::CounterImpl::\n+DUNE_GET_COUNTER ADLTag{}))\n+***** \u25c6\u00a0DUNE_INC_COUNTER *****\n+#define DUNE_INC_COUNTER ( \u00a0Tag )\n+Value:\n+namespace { \\\n+namespace CounterImpl { \\\n+constexpr std::size_t \\\n+counterFunc(Dune::PriorityTag p, Tag, ADLTag) \\\n+{ \\\n+return p.value; \\\n+} \\\n+} \\\n+} \\\n+static_assert(true, \"unfudge indentation\")\n+DUNE_GET_COUNTER\n+#define DUNE_GET_COUNTER(Tag)\n+Definition: counter.hh:17\n+***** Variable Documentation *****\n+***** \u25c6\u00a0maxcount *****\n+constexpr std::size_t maxcount = 100 constexpr\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00035_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00035_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: poweriteration.hh Source File\n+dune-istl: counter.hh Source File\n \n \n \n \n \n \n \n@@ -58,853 +58,71 @@\n \n
    \n \n \n
    \n
    \n-
    poweriteration.hh
    \n+
    counter.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n-
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n-
    6#define DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n-
    7
    \n-
    8#include <cstddef> // provides std::size_t
    \n-
    9#include <cmath> // provides std::sqrt, std::abs
    \n-
    10
    \n-
    11#include <type_traits> // provides std::is_same
    \n-
    12#include <iostream> // provides std::cout, std::endl
    \n-
    13#include <limits> // provides std::numeric_limits
    \n-
    14#include <ios> // provides std::left, std::ios::left
    \n-
    15#include <iomanip> // provides std::setw, std::resetiosflags
    \n-
    16#include <memory> // provides std::unique_ptr
    \n-
    17#include <string> // provides std::string
    \n-
    18
    \n-
    19#include <dune/common/exceptions.hh> // provides DUNE_THROW(...)
    \n-
    20
    \n-
    21#include <dune/istl/blocklevel.hh> // provides Dune::blockLevel
    \n-
    22#include <dune/istl/operators.hh> // provides Dune::LinearOperator
    \n-
    23#include <dune/istl/solvercategory.hh> // provides Dune::SolverCategory::sequential
    \n-
    24#include <dune/istl/solvertype.hh> // provides Dune::IsDirectSolver
    \n-
    25#include <dune/istl/operators.hh> // provides Dune::MatrixAdapter
    \n-
    26#include <dune/istl/istlexception.hh> // provides Dune::ISTLError
    \n-
    27#include <dune/istl/io.hh> // provides Dune::printvector(...)
    \n-
    28#include <dune/istl/solvers.hh> // provides Dune::InverseOperatorResult
    \n-
    29
    \n-
    30namespace Dune
    \n-
    31{
    \n-
    32
    \n-
    37 namespace Impl {
    \n-
    45 template <class X, class Y = X>
    \n-
    46 class ScalingLinearOperator : public Dune::LinearOperator<X,Y>
    \n-
    47 {
    \n-
    48 public:
    \n-
    49 typedef X domain_type;
    \n-
    50 typedef Y range_type;
    \n-
    51 typedef typename X::field_type field_type;
    \n-
    52
    \n-
    53 ScalingLinearOperator (field_type immutable_scaling,
    \n-
    54 const field_type& mutable_scaling)
    \n-
    55 : immutable_scaling_(immutable_scaling),
    \n-
    56 mutable_scaling_(mutable_scaling)
    \n-
    57 {}
    \n-
    58
    \n-
    59 virtual void apply (const X& x, Y& y) const
    \n-
    60 {
    \n-
    61 y = x;
    \n-
    62 y *= immutable_scaling_*mutable_scaling_;
    \n-
    63 }
    \n-
    64
    \n-
    65 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n-
    66 {
    \n-
    67 X temp(x);
    \n-
    68 temp *= immutable_scaling_*mutable_scaling_;
    \n-
    69 y.axpy(alpha,temp);
    \n-
    70 }
    \n-
    71
    \n-\n-
    74 {
    \n-\n-
    76 }
    \n-
    77
    \n-
    78 protected:
    \n-
    79 const field_type immutable_scaling_;
    \n-
    80 const field_type& mutable_scaling_;
    \n-
    81 };
    \n-
    82
    \n-
    83
    \n-
    92 template <class OP1, class OP2>
    \n-
    93 class LinearOperatorSum
    \n-
    94 : public Dune::LinearOperator<typename OP1::domain_type,
    \n-
    95 typename OP1::range_type>
    \n-
    96 {
    \n-
    97 public:
    \n-
    98 typedef typename OP1::domain_type domain_type;
    \n-
    99 typedef typename OP1::range_type range_type;
    \n-
    100 typedef typename domain_type::field_type field_type;
    \n-
    101
    \n-
    102 LinearOperatorSum (const OP1& op1, const OP2& op2)
    \n-
    103 : op1_(op1), op2_(op2)
    \n-
    104 {
    \n-
    105 static_assert(std::is_same<typename OP2::domain_type,domain_type>::value,
    \n-
    106 "Domain type of both operators doesn't match!");
    \n-
    107 static_assert(std::is_same<typename OP2::range_type,range_type>::value,
    \n-
    108 "Range type of both operators doesn't match!");
    \n-
    109 }
    \n-
    110
    \n-
    111 virtual void apply (const domain_type& x, range_type& y) const
    \n-
    112 {
    \n-
    113 op1_.apply(x,y);
    \n-
    114 op2_.applyscaleadd(1.0,x,y);
    \n-
    115 }
    \n-
    116
    \n-
    117 virtual void applyscaleadd (field_type alpha,
    \n-
    118 const domain_type& x, range_type& y) const
    \n-
    119 {
    \n-
    120 range_type temp(y);
    \n-
    121 op1_.apply(x,temp);
    \n-
    122 op2_.applyscaleadd(1.0,x,temp);
    \n-
    123 y.axpy(alpha,temp);
    \n-
    124 }
    \n-
    125
    \n-
    127 virtual SolverCategory::Category category() const
    \n-
    128 {
    \n-\n-
    130 }
    \n-
    131
    \n-
    132 protected:
    \n-
    133 const OP1& op1_;
    \n-
    134 const OP2& op2_;
    \n-
    135 };
    \n-
    136 } // end namespace Impl
    \n-
    137
    \n-
    174 template <typename BCRSMatrix, typename BlockVector>
    \n-\n-
    176 {
    \n-
    177 protected:
    \n-
    178 // Type definitions for type of iteration operator (m_ - mu_*I)
    \n-\n-\n-
    181 typedef Impl::ScalingLinearOperator<BlockVector> ScalingOperator;
    \n-
    182 typedef Impl::LinearOperatorSum<MatrixOperator,ScalingOperator> OperatorSum;
    \n-
    183
    \n-
    184 public:
    \n-\n-
    187
    \n-\n-
    190
    \n-
    191 public:
    \n-\n-
    207 const unsigned int nIterationsMax = 1000,
    \n-
    208 const unsigned int verbosity_level = 0)
    \n-
    209 : m_(m), nIterationsMax_(nIterationsMax),
    \n-
    210 verbosity_level_(verbosity_level),
    \n-
    211 mu_(0.0),
    \n-\n-
    213 scalingOperator_(-1.0,mu_),
    \n-\n-
    215 nIterations_(0),
    \n-
    216 title_(" PowerIteration_Algorithms: "),
    \n-
    217 blank_(title_.length(),' ')
    \n-
    218 {
    \n-
    219 // assert that BCRSMatrix type has blocklevel 2
    \n-
    220 static_assert
    \n-
    221 (blockLevel<BCRSMatrix>() == 2,
    \n-
    222 "Only BCRSMatrices with blocklevel 2 are supported.");
    \n-
    223
    \n-
    224 // assert that BCRSMatrix type has square blocks
    \n-
    225 static_assert
    \n-
    226 (BCRSMatrix::block_type::rows == BCRSMatrix::block_type::cols,
    \n-
    227 "Only BCRSMatrices with square blocks are supported.");
    \n-
    228
    \n-
    229 // assert that m_ is square
    \n-
    230 const int nrows = m_.M() * BCRSMatrix::block_type::rows;
    \n-
    231 const int ncols = m_.N() * BCRSMatrix::block_type::cols;
    \n-
    232 if (nrows != ncols)
    \n-
    233 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n-
    234 << nrows << "x" << ncols << ").");
    \n-
    235 }
    \n-
    236
    \n-\n-
    241
    \n-\n-\n-
    247
    \n-
    260 inline void applyPowerIteration (const Real& epsilon,
    \n-
    261 BlockVector& x, Real& lambda) const
    \n-
    262 {
    \n-
    263 // print verbosity information
    \n-
    264 if (verbosity_level_ > 0)
    \n-
    265 std::cout << title_
    \n-
    266 << "Performing power iteration approximating "
    \n-
    267 << "the dominant eigenvalue." << std::endl;
    \n-
    268
    \n-
    269 // allocate memory for auxiliary variables
    \n-
    270 BlockVector y(x);
    \n-
    271 BlockVector temp(x);
    \n-
    272
    \n-
    273 // perform power iteration
    \n-
    274 x *= (1.0 / x.two_norm());
    \n-
    275 m_.mv(x,y);
    \n-
    276 Real r_norm = std::numeric_limits<Real>::max();
    \n-
    277 nIterations_ = 0;
    \n-
    278 while (r_norm > epsilon)
    \n-
    279 {
    \n-
    280 // update and check number of iterations
    \n-\n-
    282 DUNE_THROW(Dune::ISTLError,"Power iteration did not converge "
    \n-
    283 << "in " << nIterationsMax_ << " iterations "
    \n-
    284 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n-
    285 << epsilon << ").");
    \n-
    286
    \n-
    287 // do one iteration of the power iteration algorithm
    \n-
    288 // (use that y = m_ * x)
    \n-
    289 x = y;
    \n-
    290 x *= (1.0 / y.two_norm());
    \n-
    291
    \n-
    292 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n-
    293 m_.mv(x,y);
    \n-
    294 lambda = x * y;
    \n-
    295
    \n-
    296 // get norm of residual (use that y = m_ * x)
    \n-
    297 temp = y;
    \n-
    298 temp.axpy(-lambda,x);
    \n-
    299 r_norm = temp.two_norm();
    \n-
    300
    \n-
    301 // print verbosity information
    \n-
    302 if (verbosity_level_ > 1)
    \n-
    303 std::cout << blank_ << std::left
    \n-
    304 << "iteration " << std::setw(3) << nIterations_
    \n-
    305 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n-
    306 << "): \u03bb = " << lambda << std::endl
    \n-
    307 << std::resetiosflags(std::ios::left);
    \n-
    308 }
    \n-
    309
    \n-
    310 // print verbosity information
    \n-
    311 if (verbosity_level_ > 0)
    \n-
    312 {
    \n-
    313 std::cout << blank_ << "Result ("
    \n-
    314 << "#iterations = " << nIterations_ << ", "
    \n-
    315 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    316 << "\u03bb = " << lambda << std::endl;
    \n-
    317 if (verbosity_level_ > 2)
    \n-
    318 {
    \n-
    319 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    320 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    321 }
    \n-
    322 }
    \n-
    323 }
    \n-
    324
    \n-
    353 template <typename ISTLLinearSolver,
    \n-
    354 bool avoidLinSolverCrime = false>
    \n-
    355 inline void applyInverseIteration (const Real& epsilon,
    \n-
    356 ISTLLinearSolver& solver,
    \n-
    357 BlockVector& x, Real& lambda) const
    \n-
    358 {
    \n-
    359 constexpr Real gamma = 0.0;
    \n-
    360 applyInverseIteration(gamma,epsilon,solver,x,lambda);
    \n-
    361 }
    \n-
    362
    \n-
    392 template <typename ISTLLinearSolver,
    \n-
    393 bool avoidLinSolverCrime = false>
    \n-
    394 inline void applyInverseIteration (const Real& gamma,
    \n-
    395 const Real& epsilon,
    \n-
    396 ISTLLinearSolver& solver,
    \n-
    397 BlockVector& x, Real& lambda) const
    \n-
    398 {
    \n-
    399 // print verbosity information
    \n-
    400 if (verbosity_level_ > 0)
    \n-
    401 {
    \n-
    402 std::cout << title_;
    \n-
    403 if (gamma == 0.0)
    \n-
    404 std::cout << "Performing inverse iteration approximating "
    \n-
    405 << "the least dominant eigenvalue." << std::endl;
    \n-
    406 else
    \n-
    407 std::cout << "Performing inverse iteration with shift "
    \n-
    408 << "gamma = " << gamma << " approximating the "
    \n-
    409 << "eigenvalue closest to gamma." << std::endl;
    \n-
    410 }
    \n-
    411
    \n-
    412 // initialize iteration operator,
    \n-
    413 // initialize iteration matrix when needed
    \n-
    414 updateShiftMu(gamma,solver);
    \n-
    415
    \n-
    416 // allocate memory for linear solver statistics
    \n-
    417 Dune::InverseOperatorResult solver_statistics;
    \n-
    418
    \n-
    419 // allocate memory for auxiliary variables
    \n-
    420 BlockVector y(x);
    \n-
    421 Real y_norm;
    \n-
    422 BlockVector temp(x);
    \n-
    423
    \n-
    424 // perform inverse iteration with shift
    \n-
    425 x *= (1.0 / x.two_norm());
    \n-
    426 Real r_norm = std::numeric_limits<Real>::max();
    \n-
    427 nIterations_ = 0;
    \n-
    428 while (r_norm > epsilon)
    \n-
    429 {
    \n-
    430 // update and check number of iterations
    \n-\n-
    432 DUNE_THROW(Dune::ISTLError,"Inverse iteration "
    \n-
    433 << (gamma != 0.0 ? "with shift " : "") << "did not "
    \n-
    434 << "converge in " << nIterationsMax_ << " iterations "
    \n-
    435 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n-
    436 << epsilon << ").");
    \n-
    437
    \n-
    438 // do one iteration of the inverse iteration with shift algorithm,
    \n-
    439 // part 1: solve (m_ - gamma*I) * y = x for y
    \n-
    440 // (protect x from being changed)
    \n-
    441 temp = x;
    \n-
    442 solver.apply(y,temp,solver_statistics);
    \n-
    443
    \n-
    444 // get norm of y
    \n-
    445 y_norm = y.two_norm();
    \n-
    446
    \n-
    447 // compile time switch between accuracy and efficiency
    \n-
    448 if (avoidLinSolverCrime)
    \n-
    449 {
    \n-
    450 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n-
    451 // (use that x_new = y / y_norm)
    \n-
    452 m_.mv(y,temp);
    \n-
    453 lambda = (y * temp) / (y_norm * y_norm);
    \n-
    454
    \n-
    455 // get norm of residual
    \n-
    456 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)
    \n-
    457 temp.axpy(-lambda,y);
    \n-
    458 r_norm = temp.two_norm() / y_norm;
    \n-
    459 }
    \n-
    460 else
    \n-
    461 {
    \n-
    462 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n-
    463 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)
    \n-
    464 lambda = gamma + (y * x) / (y_norm * y_norm);
    \n-
    465
    \n-
    466 // get norm of residual
    \n-
    467 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)
    \n-
    468 temp = x; temp.axpy(gamma-lambda,y);
    \n-
    469 r_norm = temp.two_norm() / y_norm;
    \n-
    470 }
    \n-
    471
    \n-
    472 // do one iteration of the inverse iteration with shift algorithm,
    \n-
    473 // part 2: update x
    \n-
    474 x = y;
    \n-
    475 x *= (1.0 / y_norm);
    \n-
    476
    \n-
    477 // print verbosity information
    \n-
    478 if (verbosity_level_ > 1)
    \n-
    479 std::cout << blank_ << std::left
    \n-
    480 << "iteration " << std::setw(3) << nIterations_
    \n-
    481 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n-
    482 << "): \u03bb = " << lambda << std::endl
    \n-
    483 << std::resetiosflags(std::ios::left);
    \n-
    484 }
    \n-
    485
    \n-
    486 // print verbosity information
    \n-
    487 if (verbosity_level_ > 0)
    \n-
    488 {
    \n-
    489 std::cout << blank_ << "Result ("
    \n-
    490 << "#iterations = " << nIterations_ << ", "
    \n-
    491 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    492 << "\u03bb = " << lambda << std::endl;
    \n-
    493 if (verbosity_level_ > 2)
    \n-
    494 {
    \n-
    495 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    496 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    497 }
    \n-
    498 }
    \n-
    499 }
    \n-
    500
    \n-
    531 template <typename ISTLLinearSolver,
    \n-
    532 bool avoidLinSolverCrime = false>
    \n-
    533 inline void applyRayleighQuotientIteration (const Real& epsilon,
    \n-
    534 ISTLLinearSolver& solver,
    \n-
    535 BlockVector& x, Real& lambda) const
    \n-
    536 {
    \n-
    537 // print verbosity information
    \n-
    538 if (verbosity_level_ > 0)
    \n-
    539 std::cout << title_
    \n-
    540 << "Performing Rayleigh quotient iteration for "
    \n-
    541 << "estimated eigenvalue " << lambda << "." << std::endl;
    \n-
    542
    \n-
    543 // allocate memory for linear solver statistics
    \n-
    544 Dune::InverseOperatorResult solver_statistics;
    \n-
    545
    \n-
    546 // allocate memory for auxiliary variables
    \n-
    547 BlockVector y(x);
    \n-
    548 Real y_norm;
    \n-
    549 Real lambda_update;
    \n-
    550 BlockVector temp(x);
    \n-
    551
    \n-
    552 // perform Rayleigh quotient iteration
    \n-
    553 x *= (1.0 / x.two_norm());
    \n-
    554 Real r_norm = std::numeric_limits<Real>::max();
    \n-
    555 nIterations_ = 0;
    \n-
    556 while (r_norm > epsilon)
    \n-
    557 {
    \n-
    558 // update and check number of iterations
    \n-\n-
    560 DUNE_THROW(Dune::ISTLError,"Rayleigh quotient iteration did not "
    \n-
    561 << "converge in " << nIterationsMax_ << " iterations "
    \n-
    562 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n-
    563 << epsilon << ").");
    \n-
    564
    \n-
    565 // update iteration operator,
    \n-
    566 // update iteration matrix when needed
    \n-
    567 updateShiftMu(lambda,solver);
    \n-
    568
    \n-
    569 // do one iteration of the Rayleigh quotient iteration algorithm,
    \n-
    570 // part 1: solve (m_ - lambda*I) * y = x for y
    \n-
    571 // (protect x from being changed)
    \n-
    572 temp = x;
    \n-
    573 solver.apply(y,temp,solver_statistics);
    \n-
    574
    \n-
    575 // get norm of y
    \n-
    576 y_norm = y.two_norm();
    \n-
    577
    \n-
    578 // compile time switch between accuracy and efficiency
    \n-
    579 if (avoidLinSolverCrime)
    \n-
    580 {
    \n-
    581 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n-
    582 // (use that x_new = y / y_norm)
    \n-
    583 m_.mv(y,temp);
    \n-
    584 lambda = (y * temp) / (y_norm * y_norm);
    \n-
    585
    \n-
    586 // get norm of residual
    \n-
    587 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)
    \n-
    588 temp.axpy(-lambda,y);
    \n-
    589 r_norm = temp.two_norm() / y_norm;
    \n-
    590 }
    \n-
    591 else
    \n-
    592 {
    \n-
    593 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n-
    594 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)
    \n-
    595 lambda_update = (y * x) / (y_norm * y_norm);
    \n-
    596 lambda += lambda_update;
    \n-
    597
    \n-
    598 // get norm of residual
    \n-
    599 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)
    \n-
    600 temp = x; temp.axpy(-lambda_update,y);
    \n-
    601 r_norm = temp.two_norm() / y_norm;
    \n-
    602 }
    \n-
    603
    \n-
    604 // do one iteration of the Rayleigh quotient iteration algorithm,
    \n-
    605 // part 2: update x
    \n-
    606 x = y;
    \n-
    607 x *= (1.0 / y_norm);
    \n-
    608
    \n-
    609 // print verbosity information
    \n-
    610 if (verbosity_level_ > 1)
    \n-
    611 std::cout << blank_ << std::left
    \n-
    612 << "iteration " << std::setw(3) << nIterations_
    \n-
    613 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n-
    614 << "): \u03bb = " << lambda << std::endl
    \n-
    615 << std::resetiosflags(std::ios::left);
    \n-
    616 }
    \n-
    617
    \n-
    618 // print verbosity information
    \n-
    619 if (verbosity_level_ > 0)
    \n-
    620 {
    \n-
    621 std::cout << blank_ << "Result ("
    \n-
    622 << "#iterations = " << nIterations_ << ", "
    \n-
    623 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    624 << "\u03bb = " << lambda << std::endl;
    \n-
    625 if (verbosity_level_ > 2)
    \n-
    626 {
    \n-
    627 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    628 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    629 }
    \n-
    630 }
    \n-
    631 }
    \n-
    632
    \n-
    689 template <typename ISTLLinearSolver,
    \n-
    690 bool avoidLinSolverCrime = false>
    \n-
    691 inline void applyTLIMEIteration (const Real& gamma, const Real& eta,
    \n-
    692 const Real& epsilon,
    \n-
    693 ISTLLinearSolver& solver,
    \n-
    694 const Real& delta, const std::size_t& m,
    \n-
    695 bool& extrnl,
    \n-
    696 BlockVector& x, Real& lambda) const
    \n-
    697 {
    \n-
    698 // use same variable names as in [Szyld, 1988]
    \n-
    699 BlockVector& x_s = x;
    \n-
    700 Real& mu_s = lambda;
    \n-
    701
    \n-
    702 // print verbosity information
    \n-
    703 if (verbosity_level_ > 0)
    \n-
    704 std::cout << title_
    \n-
    705 << "Performing TLIME iteration for "
    \n-
    706 << "estimated eigenvalue in the "
    \n-
    707 << "interval (" << gamma - eta << ","
    \n-
    708 << gamma + eta << ")." << std::endl;
    \n-
    709
    \n-
    710 // allocate memory for linear solver statistics
    \n-
    711 Dune::InverseOperatorResult solver_statistics;
    \n-
    712
    \n-
    713 // allocate memory for auxiliary variables
    \n-
    714 bool doRQI;
    \n-
    715 Real mu;
    \n-
    716 BlockVector y(x_s);
    \n-
    717 Real omega;
    \n-
    718 Real mu_s_old;
    \n-
    719 Real mu_s_update;
    \n-
    720 BlockVector temp(x_s);
    \n-
    721 Real q_norm, r_norm;
    \n-
    722
    \n-
    723 // perform TLIME iteration
    \n-
    724 x_s *= (1.0 / x_s.two_norm());
    \n-
    725 extrnl = true;
    \n-
    726 doRQI = false;
    \n-
    727 r_norm = std::numeric_limits<Real>::max();
    \n-
    728 nIterations_ = 0;
    \n-
    729 while (r_norm > epsilon)
    \n-
    730 {
    \n-
    731 // update and check number of iterations
    \n-\n-
    733 DUNE_THROW(Dune::ISTLError,"TLIME iteration did not "
    \n-
    734 << "converge in " << nIterationsMax_
    \n-
    735 << " iterations (\u2551residual\u2551_2 = " << r_norm
    \n-
    736 << ", epsilon = " << epsilon << ").");
    \n-
    737
    \n-
    738 // set shift for next iteration according to inverse iteration
    \n-
    739 // with shift (II) resp. Rayleigh quotient iteration (RQI)
    \n-
    740 if (doRQI)
    \n-
    741 mu = mu_s;
    \n-
    742 else
    \n-
    743 mu = gamma;
    \n-
    744
    \n-
    745 // update II/RQI iteration operator,
    \n-
    746 // update II/RQI iteration matrix when needed
    \n-
    747 updateShiftMu(mu,solver);
    \n-
    748
    \n-
    749 // do one iteration of the II/RQI algorithm,
    \n-
    750 // part 1: solve (m_ - mu*I) * y = x for y
    \n-
    751 temp = x_s;
    \n-
    752 solver.apply(y,temp,solver_statistics);
    \n-
    753
    \n-
    754 // do one iteration of the II/RQI algorithm,
    \n-
    755 // part 2: compute omega
    \n-
    756 omega = (1.0 / y.two_norm());
    \n-
    757
    \n-
    758 // backup the old Rayleigh quotient
    \n-
    759 mu_s_old = mu_s;
    \n-
    760
    \n-
    761 // compile time switch between accuracy and efficiency
    \n-
    762 if (avoidLinSolverCrime)
    \n-
    763 {
    \n-
    764 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue
    \n-
    765 // (use that x_new = y * omega)
    \n-
    766 m_.mv(y,temp);
    \n-
    767 mu_s = (y * temp) * (omega * omega);
    \n-
    768
    \n-
    769 // get norm of "the residual with respect to the shift used by II",
    \n-
    770 // use normal representation of q
    \n-
    771 // (use that x_new = y * omega, use that temp = m_ * y)
    \n-
    772 temp.axpy(-gamma,y);
    \n-
    773 q_norm = temp.two_norm() * omega;
    \n-
    774
    \n-
    775 // get norm of "the residual with respect to the Rayleigh quotient"
    \n-
    776 r_norm = q_norm*q_norm - (gamma-mu_s)*(gamma-mu_s);
    \n-
    777 // prevent that truncation errors invalidate the norm
    \n-
    778 // (we don't want to calculate sqrt of a negative number)
    \n-
    779 if (r_norm >= 0)
    \n-
    780 {
    \n-
    781 // use relation between the norms of r and q for efficiency
    \n-
    782 r_norm = std::sqrt(r_norm);
    \n-
    783 }
    \n-
    784 else
    \n-
    785 {
    \n-
    786 // use relation between r and q
    \n-
    787 // (use that x_new = y * omega, use that temp = (m_ - gamma*I) * y = q / omega)
    \n-
    788 temp.axpy(gamma-mu_s,y);
    \n-
    789 r_norm = temp.two_norm() * omega;
    \n-
    790 }
    \n-
    791 }
    \n-
    792 else
    \n-
    793 {
    \n-
    794 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue
    \n-
    795 if (!doRQI)
    \n-
    796 {
    \n-
    797 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y = x_s)
    \n-
    798 mu_s = gamma + (y * x_s) * (omega * omega);
    \n-
    799 }
    \n-
    800 else
    \n-
    801 {
    \n-
    802 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) * y = x_s)
    \n-
    803 mu_s_update = (y * x_s) * (omega * omega);
    \n-
    804 mu_s += mu_s_update;
    \n-
    805 }
    \n-
    806
    \n-
    807 // get norm of "the residual with respect to the shift used by II"
    \n-
    808 if (!doRQI)
    \n-
    809 {
    \n-
    810 // use special representation of q in the II case
    \n-
    811 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y = x_s)
    \n-
    812 q_norm = omega;
    \n-
    813 }
    \n-
    814 else
    \n-
    815 {
    \n-
    816 // use special representation of q in the RQI case
    \n-
    817 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) * y = x_s)
    \n-
    818 temp = x_s; temp.axpy(mu_s-gamma,y);
    \n-
    819 q_norm = temp.two_norm() * omega;
    \n-
    820 }
    \n-
    821
    \n-
    822 // get norm of "the residual with respect to the Rayleigh quotient"
    \n-
    823 // don't use efficient relation between the norms of r and q, as
    \n-
    824 // this relation seems to yield a less accurate r_norm in the case
    \n-
    825 // where linear solver crime is admitted
    \n-
    826 if (!doRQI)
    \n-
    827 {
    \n-
    828 // (use that x_new = y * omega and use that (m_ - gamma*I) * y = x_s)
    \n-
    829 temp = x_s; temp.axpy(gamma-lambda,y);
    \n-
    830 r_norm = temp.two_norm() * omega;
    \n-
    831 }
    \n-
    832 else
    \n-
    833 {
    \n-
    834 // (use that x_new = y * omega and use that (m_ - mu_s_old*I) * y = x_s)
    \n-
    835 temp = x_s; temp.axpy(-mu_s_update,y);
    \n-
    836 r_norm = temp.two_norm() * omega;
    \n-
    837 }
    \n-
    838 }
    \n-
    839
    \n-
    840 // do one iteration of the II/RQI algorithm,
    \n-
    841 // part 3: update x
    \n-
    842 x_s = y; x_s *= omega;
    \n-
    843
    \n-
    844 // // for relative residual norm mode, scale with mu_s^{-1}
    \n-
    845 // r_norm /= std::abs(mu_s);
    \n-
    846
    \n-
    847 // print verbosity information
    \n-
    848 if (verbosity_level_ > 1)
    \n-
    849 std::cout << blank_ << "iteration "
    \n-
    850 << std::left << std::setw(3) << nIterations_
    \n-
    851 << " (" << (doRQI ? "RQI," : "II, ")
    \n-
    852 << " " << (doRQI ? "\u2014>" : " ") << " "
    \n-
    853 << "\u2551r\u2551_2 = " << std::setw(11) << r_norm
    \n-
    854 << ", " << (doRQI ? " " : "\u2014>") << " "
    \n-
    855 << "\u2551q\u2551_2 = " << std::setw(11) << q_norm
    \n-
    856 << "): \u03bb = " << lambda << std::endl
    \n-
    857 << std::resetiosflags(std::ios::left);
    \n-
    858
    \n-
    859 // check if the eigenvalue closest to gamma lies in J
    \n-
    860 if (!doRQI && q_norm < eta)
    \n-
    861 {
    \n-
    862 // J is not free of eigenvalues
    \n-
    863 extrnl = false;
    \n-
    864
    \n-
    865 // by theory we know now that mu_s also lies in J
    \n-
    866 assert(std::abs(mu_s-gamma) < eta);
    \n-
    867
    \n-
    868 // switch to RQI
    \n-
    869 doRQI = true;
    \n-
    870 }
    \n-
    871
    \n-
    872 // revert to II if J is not free of eigenvalues but
    \n-
    873 // at some point mu_s falls back again outside J
    \n-
    874 if (!extrnl && doRQI && std::abs(mu_s-gamma) >= eta)
    \n-
    875 doRQI = false;
    \n-
    876
    \n-
    877 // if eigenvalue closest to gamma does not lie in J use RQI
    \n-
    878 // solely to accelerate the convergence to this eigenvalue
    \n-
    879 // when II has become stationary
    \n-
    880 if (extrnl && !doRQI)
    \n-
    881 {
    \n-
    882 // switch to RQI if the relative change of the Rayleigh
    \n-
    883 // quotient indicates that II has become stationary
    \n-
    884 if (nIterations_ >= m &&
    \n-
    885 std::abs(mu_s - mu_s_old) / std::abs(mu_s) < delta)
    \n-
    886 doRQI = true;
    \n-
    887 }
    \n-
    888 }
    \n-
    889
    \n-
    890 // // compute final residual and lambda again (paranoia....)
    \n-
    891 // m_.mv(x_s,temp);
    \n-
    892 // mu_s = x_s * temp;
    \n-
    893 // temp.axpy(-mu_s,x_s);
    \n-
    894 // r_norm = temp.two_norm();
    \n-
    895 // // r_norm /= std::abs(mu_s);
    \n-
    896
    \n-
    897 // print verbosity information
    \n-
    898 if (verbosity_level_ > 0)
    \n-
    899 {
    \n-
    900 if (extrnl)
    \n-
    901 std::cout << blank_ << "Interval "
    \n-
    902 << "(" << gamma - eta << "," << gamma + eta
    \n-
    903 << ") is free of eigenvalues, approximating "
    \n-
    904 << "the closest eigenvalue." << std::endl;
    \n-
    905 std::cout << blank_ << "Result ("
    \n-
    906 << "#iterations = " << nIterations_ << ", "
    \n-
    907 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    908 << "\u03bb = " << lambda << std::endl;
    \n-
    909 if (verbosity_level_ > 2)
    \n-
    910 {
    \n-
    911 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    912 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    913 }
    \n-
    914 }
    \n-
    915 }
    \n-
    916
    \n-\n-
    926 {
    \n-
    927 // return iteration operator
    \n-
    928 return itOperator_;
    \n-
    929 }
    \n-
    930
    \n-
    945 inline const BCRSMatrix& getIterationMatrix () const
    \n-
    946 {
    \n-
    947 // create iteration matrix on demand
    \n-
    948 if (!itMatrix_)
    \n-
    949 itMatrix_ = std::make_unique<BCRSMatrix>(m_);
    \n-
    950
    \n-
    951 // return iteration matrix
    \n-
    952 return *itMatrix_;
    \n-
    953 }
    \n-
    954
    \n-
    959 inline unsigned int getIterationCount () const
    \n-
    960 {
    \n-
    961 if (nIterations_ == 0)
    \n-
    962 DUNE_THROW(Dune::ISTLError,"No algorithm applied, yet.");
    \n-
    963
    \n-
    964 return nIterations_;
    \n-
    965 }
    \n-
    966
    \n-
    967 protected:
    \n-
    982 template <typename ISTLLinearSolver>
    \n-
    983 inline void updateShiftMu (const Real& mu,
    \n-
    984 ISTLLinearSolver& solver) const
    \n-
    985 {
    \n-
    986 // do nothing if new shift equals the old one
    \n-
    987 if (mu == mu_) return;
    \n-
    988
    \n-
    989 // update shift mu_, i.e. update iteration operator
    \n-
    990 mu_ = mu;
    \n-
    991
    \n-
    992 // update iteration matrix when needed
    \n-
    993 if (itMatrix_)
    \n-
    994 {
    \n-
    995 // iterate over entries in iteration matrix diagonal
    \n-
    996 constexpr int rowBlockSize = BCRSMatrix::block_type::rows;
    \n-
    997 constexpr int colBlockSize = BCRSMatrix::block_type::cols;
    \n-
    998 for (typename BCRSMatrix::size_type i = 0;
    \n-
    999 i < itMatrix_->M()*rowBlockSize; ++i)
    \n-
    1000 {
    \n-
    1001 // access m_[i,i] where i is the flat index of a row/column
    \n-
    1002 const Real& m_entry = m_
    \n-
    1003 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];
    \n-
    1004 // access *itMatrix[i,i] where i is the flat index of a row/column
    \n-
    1005 Real& entry = (*itMatrix_)
    \n-
    1006 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];
    \n-
    1007 // change current entry in iteration matrix diagonal
    \n-
    1008 entry = m_entry - mu_;
    \n-
    1009 }
    \n-
    1010 // notify linear solver about change of the iteration matrix object
    \n-\n-
    1012 (solver,*itMatrix_);
    \n-
    1013 }
    \n-
    1014 }
    \n-
    1015
    \n-
    1016 protected:
    \n-
    1017 // parameters related to iterative eigenvalue algorithms
    \n-\n-
    1019 const unsigned int nIterationsMax_;
    \n-
    1020
    \n-
    1021 // verbosity setting
    \n-
    1022 const unsigned int verbosity_level_;
    \n-
    1023
    \n-
    1024 // shift mu_ used by iteration operator/matrix (m_ - mu_*I)
    \n-
    1025 mutable Real mu_;
    \n-
    1026
    \n-
    1027 // iteration operator (m_ - mu_*I), passing shift mu_ by reference
    \n-\n-\n-\n-
    1031
    \n-
    1032 // iteration matrix (m_ - mu_*I), provided on demand when needed
    \n-
    1033 // (e.g. for preconditioning)
    \n-
    1034 mutable std::unique_ptr<BCRSMatrix> itMatrix_;
    \n-
    1035
    \n-
    1036 // memory for storing temporary variables (mutable as they shall
    \n-
    1037 // just be effectless auxiliary variables of the const apply*(...)
    \n-
    1038 // methods)
    \n-
    1039 mutable unsigned int nIterations_;
    \n-
    1040
    \n-
    1041 // constants for printing verbosity information
    \n-
    1042 const std::string title_;
    \n-
    1043 const std::string blank_;
    \n-
    1044 };
    \n-
    1045
    \n-
    1048} // namespace Dune
    \n-
    1049
    \n-
    1050#endif // DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Templates characterizing the type of a solver.
    \n-
    Implementations of the inverse operator interface.
    \n-\n-\n-
    Some generic functions for pretty printing vectors and matrices.
    \n-
    void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
    Print an ISTL vector.
    Definition: io.hh:89
    \n+
    3#ifndef DUNE_ISTL_COMMON_COUNTER_HH
    \n+
    4#define DUNE_ISTL_COMMON_COUNTER_HH
    \n+
    5
    \n+
    6#include <cassert>
    \n+
    7#include <typeinfo>
    \n+
    8#include <iostream>
    \n+
    9#include <memory>
    \n+
    10#include <tuple>
    \n+
    11#include <utility>
    \n+
    12
    \n+
    13#include <dune/common/typeutilities.hh>
    \n+
    14
    \n+
    15constexpr std::size_t maxcount = 100;
    \n+
    16
    \n+
    17#define DUNE_GET_COUNTER(Tag) \\
    \n+
    18 (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
    \n+
    19
    \n+
    20#define DUNE_INC_COUNTER(Tag) \\
    \n+
    21 namespace { \\
    \n+
    22 namespace CounterImpl { \\
    \n+
    23 constexpr std::size_t \\
    \n+
    24 counterFunc(Dune::PriorityTag<DUNE_GET_COUNTER(Tag)+1> p, Tag, ADLTag) \\
    \n+
    25 { \\
    \n+
    26 return p.value; \\
    \n+
    27 } \\
    \n+
    28 } \\
    \n+
    29 } \\
    \n+
    30 static_assert(true, "unfudge indentation")
    \n+
    31
    \n+
    32namespace Dune {
    \n+
    33 namespace {
    \n+
    34
    \n+
    35 namespace CounterImpl {
    \n+
    36
    \n+
    37 struct ADLTag {};
    \n+
    38
    \n+
    39 template<class Tag>
    \n+
    40 constexpr std::size_t counterFunc(Dune::PriorityTag<0>, Tag, ADLTag)
    \n+
    41 {
    \n+
    42 return 0;
    \n+
    43 }
    \n+
    44
    \n+
    45 } // end namespace CounterImpl
    \n+
    46 } // end empty namespace
    \n+
    47} // end namespace Dune
    \n+
    48#endif // DUNE_ISTL_COMMON_COUNTER_HH
    \n+
    constexpr std::size_t maxcount
    Definition: counter.hh:15
    \n
    Definition: allocator.hh:11
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n-
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n-
    void mv(const X &x, Y &y) const
    y = A x
    Definition: bcrsmatrix.hh:1612
    \n-
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n-
    Iterative eigenvalue algorithms based on power iteration.
    Definition: poweriteration.hh:176
    \n-
    std::unique_ptr< BCRSMatrix > itMatrix_
    Definition: poweriteration.hh:1034
    \n-
    PowerIteration_Algorithms(const PowerIteration_Algorithms &)=delete
    \n-
    Impl::ScalingLinearOperator< BlockVector > ScalingOperator
    Definition: poweriteration.hh:181
    \n-
    const std::string blank_
    Definition: poweriteration.hh:1043
    \n-
    Impl::LinearOperatorSum< MatrixOperator, ScalingOperator > OperatorSum
    Definition: poweriteration.hh:182
    \n-
    Dune::MatrixAdapter< BCRSMatrix, BlockVector, BlockVector > MatrixOperator
    Definition: poweriteration.hh:180
    \n-
    void applyInverseIteration(const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the inverse iteration algorithm to compute an approximation lambda of the least dominant (i....
    Definition: poweriteration.hh:355
    \n-
    void applyTLIMEIteration(const Real &gamma, const Real &eta, const Real &epsilon, ISTLLinearSolver &solver, const Real &delta, const std::size_t &m, bool &extrnl, BlockVector &x, Real &lambda) const
    Perform the "two-level iterative method for eigenvalue calculations (TLIME)" iteration algorit...
    Definition: poweriteration.hh:691
    \n-
    IterationOperator & getIterationOperator()
    Return the iteration operator (m_ - mu_*I).
    Definition: poweriteration.hh:925
    \n-
    OperatorSum itOperator_
    Definition: poweriteration.hh:1030
    \n-
    const BCRSMatrix & m_
    Definition: poweriteration.hh:1018
    \n-
    PowerIteration_Algorithms(const BCRSMatrix &m, const unsigned int nIterationsMax=1000, const unsigned int verbosity_level=0)
    Construct from required parameters.
    Definition: poweriteration.hh:206
    \n-
    const unsigned int nIterationsMax_
    Definition: poweriteration.hh:1019
    \n-
    void applyPowerIteration(const Real &epsilon, BlockVector &x, Real &lambda) const
    Perform the power iteration algorithm to compute an approximation lambda of the dominant (i....
    Definition: poweriteration.hh:260
    \n-
    OperatorSum IterationOperator
    Type of iteration operator (m_ - mu_*I)
    Definition: poweriteration.hh:189
    \n-
    void applyRayleighQuotientIteration(const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the Rayleigh quotient iteration algorithm to compute an approximation lambda of an eigenvalue...
    Definition: poweriteration.hh:533
    \n-
    void applyInverseIteration(const Real &gamma, const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the inverse iteration with shift algorithm to compute an approximation lambda of the eigenval...
    Definition: poweriteration.hh:394
    \n-
    const ScalingOperator scalingOperator_
    Definition: poweriteration.hh:1029
    \n-
    void updateShiftMu(const Real &mu, ISTLLinearSolver &solver) const
    Update shift mu_, i.e. update iteration operator/matrix (m_ - mu_*I).
    Definition: poweriteration.hh:983
    \n-
    PowerIteration_Algorithms & operator=(const PowerIteration_Algorithms &)=delete
    \n-
    unsigned int getIterationCount() const
    Return the number of iterations in last application of an algorithm.
    Definition: poweriteration.hh:959
    \n-
    const MatrixOperator matrixOperator_
    Definition: poweriteration.hh:1028
    \n-
    const BCRSMatrix & getIterationMatrix() const
    Return the iteration matrix (m_ - mu_*I), provided on demand when needed (e.g. for direct solvers or ...
    Definition: poweriteration.hh:945
    \n-
    unsigned int nIterations_
    Definition: poweriteration.hh:1039
    \n-
    const unsigned int verbosity_level_
    Definition: poweriteration.hh:1022
    \n-
    const std::string title_
    Definition: poweriteration.hh:1042
    \n-
    BlockVector::field_type Real
    Type of underlying field.
    Definition: poweriteration.hh:186
    \n-
    Real mu_
    Definition: poweriteration.hh:1025
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    A linear operator.
    Definition: operators.hh:67
    \n-
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n-
    virtual void applyscaleadd(field_type alpha, const X &x, X &y) const=0
    apply operator to x, scale and add:
    \n-
    virtual SolverCategory::Category category() const=0
    Category of the linear operator (see SolverCategory::Category)
    \n-
    X range_type
    The type of the range of the operator.
    Definition: operators.hh:72
    \n-
    virtual void apply(const X &x, X &y) const=0
    apply operator to x: The input vector is consistent and the output must also be consistent on the in...
    \n-
    X domain_type
    The type of the domain of the operator.
    Definition: operators.hh:70
    \n-
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:524
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-utf-8\n+us-ascii\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,995 +4,68 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * eigenvalue\n-poweriteration.hh\n+ * common\n+counter.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n- 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n- 6#define DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n- 7\n- 8#include // provides std::size_t\n- 9#include // provides std::sqrt, std::abs\n- 10\n- 11#include // provides std::is_same\n- 12#include // provides std::cout, std::endl\n- 13#include // provides std::numeric_limits\n- 14#include // provides std::left, std::ios::left\n- 15#include // provides std::setw, std::resetiosflags\n- 16#include // provides std::unique_ptr\n- 17#include // provides std::string\n- 18\n- 19#include // provides DUNE_THROW(...)\n- 20\n- 21#include // provides Dune::blockLevel\n- 22#include // provides Dune::LinearOperator\n- 23#include // provides Dune::SolverCategory::\n-sequential\n- 24#include // provides Dune::IsDirectSolver\n- 25#include // provides Dune::MatrixAdapter\n- 26#include // provides Dune::ISTLError\n- 27#include // provides Dune::printvector(...)\n- 28#include // provides Dune::InverseOperatorResult\n- 29\n- 30namespace Dune\n- 31{\n- 32\n- 37 namespace Impl {\n- 45 template \n- 46 class ScalingLinearOperator : public Dune::LinearOperator\n- 47 {\n- 48 public:\n- 49 typedef X domain_type;\n- 50 typedef Y range_type;\n- 51 typedef typename X::field_type field_type;\n- 52\n- 53 ScalingLinearOperator (field_type immutable_scaling,\n- 54 const field_type& mutable_scaling)\n- 55 : immutable_scaling_(immutable_scaling),\n- 56 mutable_scaling_(mutable_scaling)\n- 57 {}\n- 58\n- 59 virtual void apply (const X& x, Y& y) const\n- 60 {\n- 61 y = x;\n- 62 y *= immutable_scaling_*mutable_scaling_;\n- 63 }\n- 64\n- 65 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n- 66 {\n- 67 X temp(x);\n- 68 temp *= immutable_scaling_*mutable_scaling_;\n- 69 y.axpy(alpha,temp);\n- 70 }\n- 71\n- 73 virtual SolverCategory::Category category() const\n- 74 {\n- 75 return SolverCategory::sequential;\n- 76 }\n- 77\n- 78 protected:\n- 79 const field_type immutable_scaling_;\n- 80 const field_type& mutable_scaling_;\n- 81 };\n- 82\n- 83\n- 92 template \n- 93 class LinearOperatorSum\n- 94 : public Dune::LinearOperator\n- 96 {\n- 97 public:\n- 98 typedef typename OP1::domain_type domain_type;\n- 99 typedef typename OP1::range_type range_type;\n- 100 typedef typename domain_type::field_type field_type;\n- 101\n- 102 LinearOperatorSum (const OP1& op1, const OP2& op2)\n- 103 : op1_(op1), op2_(op2)\n- 104 {\n- 105 static_assert(std::is_same::value,\n- 106 \"Domain type of both operators doesn't match!\");\n- 107 static_assert(std::is_same::value,\n- 108 \"Range type of both operators doesn't match!\");\n- 109 }\n- 110\n- 111 virtual void apply (const domain_type& x, range_type& y) const\n- 112 {\n- 113 op1_.apply(x,y);\n- 114 op2_.applyscaleadd(1.0,x,y);\n- 115 }\n- 116\n- 117 virtual void applyscaleadd (field_type alpha,\n- 118 const domain_type& x, range_type& y) const\n- 119 {\n- 120 range_type temp(y);\n- 121 op1_.apply(x,temp);\n- 122 op2_.applyscaleadd(1.0,x,temp);\n- 123 y.axpy(alpha,temp);\n- 124 }\n- 125\n- 127 virtual SolverCategory::Category category() const\n- 128 {\n- 129 return SolverCategory::sequential;\n- 130 }\n- 131\n- 132 protected:\n- 133 const OP1& op1_;\n- 134 const OP2& op2_;\n- 135 };\n- 136 } // end namespace Impl\n- 137\n- 174 template \n-175 class PowerIteration_Algorithms\n- 176 {\n- 177 protected:\n- 178 // Type definitions for type of iteration operator (m_ - mu_*I)\n- 179 typedef typename Dune::MatrixAdapter\n-180 MatrixOperator;\n-181 typedef Impl::ScalingLinearOperator ScalingOperator;\n-182 typedef Impl::LinearOperatorSum\n-OperatorSum;\n- 183\n- 184 public:\n-186 typedef typename BlockVector::field_type Real;\n- 187\n-189 typedef OperatorSum IterationOperator;\n- 190\n- 191 public:\n-206 PowerIteration_Algorithms (const BCRSMatrix& m,\n- 207 const unsigned int nIterationsMax = 1000,\n- 208 const unsigned int verbosity_level = 0)\n- 209 : m_(m), nIterationsMax_(nIterationsMax),\n- 210 verbosity_level_(verbosity_level),\n- 211 mu_(0.0),\n- 212 matrixOperator_(m_),\n- 213 scalingOperator_(-1.0,mu_),\n- 214 itOperator_(matrixOperator_,scalingOperator_),\n- 215 nIterations_(0),\n- 216 title_(\" PowerIteration_Algorithms: \"),\n- 217 blank_(title_.length(),' ')\n- 218 {\n- 219 // assert that BCRSMatrix type has blocklevel 2\n- 220 static_assert\n- 221 (blockLevel() == 2,\n- 222 \"Only BCRSMatrices with blocklevel 2 are supported.\");\n- 223\n- 224 // assert that BCRSMatrix type has square blocks\n- 225 static_assert\n- 226 (BCRSMatrix::block_type::rows == BCRSMatrix::block_type::cols,\n- 227 \"Only BCRSMatrices with square blocks are supported.\");\n- 228\n- 229 // assert that m_ is square\n- 230 const int nrows = m_.M() * BCRSMatrix::block_type::rows;\n- 231 const int ncols = m_.N() * BCRSMatrix::block_type::cols;\n- 232 if (nrows != ncols)\n- 233 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n- 234 << nrows << \"x\" << ncols << \").\");\n- 235 }\n- 236\n-240 PowerIteration_Algorithms (const PowerIteration_Algorithms&) = delete;\n- 241\n- 245 PowerIteration_Algorithms&\n-246 operator=(const PowerIteration_Algorithms&) = delete;\n- 247\n-260 inline void applyPowerIteration (const Real& epsilon,\n- 261 BlockVector& x, Real& lambda) const\n- 262 {\n- 263 // print verbosity information\n- 264 if (verbosity_level_ > 0)\n- 265 std::cout << title_\n- 266 << \"Performing power iteration approximating \"\n- 267 << \"the dominant eigenvalue.\" << std::endl;\n- 268\n- 269 // allocate memory for auxiliary variables\n- 270 BlockVector y(x);\n- 271 BlockVector temp(x);\n- 272\n- 273 // perform power iteration\n- 274 x *= (1.0 / x.two_norm());\n- 275 m_.mv(x,y);\n- 276 Real r_norm = std::numeric_limits::max();\n- 277 nIterations_ = 0;\n- 278 while (r_norm > epsilon)\n- 279 {\n- 280 // update and check number of iterations\n- 281 if (++nIterations_ > nIterationsMax_)\n- 282 DUNE_THROW(Dune::ISTLError,\"Power iteration did not converge \"\n- 283 << \"in \" << nIterationsMax_ << \" iterations \"\n- 284 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n- 285 << epsilon << \").\");\n- 286\n- 287 // do one iteration of the power iteration algorithm\n- 288 // (use that y = m_ * x)\n- 289 x = y;\n- 290 x *= (1.0 / y.two_norm());\n- 291\n- 292 // get approximated eigenvalue lambda via the Rayleigh quotient\n- 293 m_.mv(x,y);\n- 294 lambda = x * y;\n- 295\n- 296 // get norm of residual (use that y = m_ * x)\n- 297 temp = y;\n- 298 temp.axpy(-lambda,x);\n- 299 r_norm = temp.two_norm();\n- 300\n- 301 // print verbosity information\n- 302 if (verbosity_level_ > 1)\n- 303 std::cout << blank_ << std::left\n- 304 << \"iteration \" << std::setw(3) << nIterations_\n- 305 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n- 306 << \"): \u03bb = \" << lambda << std::endl\n- 307 << std::resetiosflags(std::ios::left);\n- 308 }\n- 309\n- 310 // print verbosity information\n- 311 if (verbosity_level_ > 0)\n- 312 {\n- 313 std::cout << blank_ << \"Result (\"\n- 314 << \"#iterations = \" << nIterations_ << \", \"\n- 315 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 316 << \"\u03bb = \" << lambda << std::endl;\n- 317 if (verbosity_level_ > 2)\n- 318 {\n- 319 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 320 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 321 }\n- 322 }\n- 323 }\n- 324\n- 353 template \n-355 inline void applyInverseIteration (const Real& epsilon,\n- 356 ISTLLinearSolver& solver,\n- 357 BlockVector& x, Real& lambda) const\n- 358 {\n- 359 constexpr Real gamma = 0.0;\n- 360 applyInverseIteration(gamma,epsilon,solver,x,lambda);\n- 361 }\n- 362\n- 392 template \n-394 inline void applyInverseIteration (const Real& gamma,\n- 395 const Real& epsilon,\n- 396 ISTLLinearSolver& solver,\n- 397 BlockVector& x, Real& lambda) const\n- 398 {\n- 399 // print verbosity information\n- 400 if (verbosity_level_ > 0)\n- 401 {\n- 402 std::cout << title_;\n- 403 if (gamma == 0.0)\n- 404 std::cout << \"Performing inverse iteration approximating \"\n- 405 << \"the least dominant eigenvalue.\" << std::endl;\n- 406 else\n- 407 std::cout << \"Performing inverse iteration with shift \"\n- 408 << \"gamma = \" << gamma << \" approximating the \"\n- 409 << \"eigenvalue closest to gamma.\" << std::endl;\n- 410 }\n- 411\n- 412 // initialize iteration operator,\n- 413 // initialize iteration matrix when needed\n- 414 updateShiftMu(gamma,solver);\n- 415\n- 416 // allocate memory for linear solver statistics\n- 417 Dune::InverseOperatorResult solver_statistics;\n- 418\n- 419 // allocate memory for auxiliary variables\n- 420 BlockVector y(x);\n- 421 Real y_norm;\n- 422 BlockVector temp(x);\n- 423\n- 424 // perform inverse iteration with shift\n- 425 x *= (1.0 / x.two_norm());\n- 426 Real r_norm = std::numeric_limits::max();\n- 427 nIterations_ = 0;\n- 428 while (r_norm > epsilon)\n- 429 {\n- 430 // update and check number of iterations\n- 431 if (++nIterations_ > nIterationsMax_)\n- 432 DUNE_THROW(Dune::ISTLError,\"Inverse iteration \"\n- 433 << (gamma != 0.0 ? \"with shift \" : \"\") << \"did not \"\n- 434 << \"converge in \" << nIterationsMax_ << \" iterations \"\n- 435 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n- 436 << epsilon << \").\");\n- 437\n- 438 // do one iteration of the inverse iteration with shift algorithm,\n- 439 // part 1: solve (m_ - gamma*I) * y = x for y\n- 440 // (protect x from being changed)\n- 441 temp = x;\n- 442 solver.apply(y,temp,solver_statistics);\n- 443\n- 444 // get norm of y\n- 445 y_norm = y.two_norm();\n- 446\n- 447 // compile time switch between accuracy and efficiency\n- 448 if (avoidLinSolverCrime)\n- 449 {\n- 450 // get approximated eigenvalue lambda via the Rayleigh quotient\n- 451 // (use that x_new = y / y_norm)\n- 452 m_.mv(y,temp);\n- 453 lambda = (y * temp) / (y_norm * y_norm);\n- 454\n- 455 // get norm of residual\n- 456 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)\n- 457 temp.axpy(-lambda,y);\n- 458 r_norm = temp.two_norm() / y_norm;\n- 459 }\n- 460 else\n- 461 {\n- 462 // get approximated eigenvalue lambda via the Rayleigh quotient\n- 463 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)\n- 464 lambda = gamma + (y * x) / (y_norm * y_norm);\n- 465\n- 466 // get norm of residual\n- 467 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)\n- 468 temp = x; temp.axpy(gamma-lambda,y);\n- 469 r_norm = temp.two_norm() / y_norm;\n- 470 }\n- 471\n- 472 // do one iteration of the inverse iteration with shift algorithm,\n- 473 // part 2: update x\n- 474 x = y;\n- 475 x *= (1.0 / y_norm);\n- 476\n- 477 // print verbosity information\n- 478 if (verbosity_level_ > 1)\n- 479 std::cout << blank_ << std::left\n- 480 << \"iteration \" << std::setw(3) << nIterations_\n- 481 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n- 482 << \"): \u03bb = \" << lambda << std::endl\n- 483 << std::resetiosflags(std::ios::left);\n- 484 }\n- 485\n- 486 // print verbosity information\n- 487 if (verbosity_level_ > 0)\n- 488 {\n- 489 std::cout << blank_ << \"Result (\"\n- 490 << \"#iterations = \" << nIterations_ << \", \"\n- 491 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 492 << \"\u03bb = \" << lambda << std::endl;\n- 493 if (verbosity_level_ > 2)\n- 494 {\n- 495 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 496 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 497 }\n- 498 }\n- 499 }\n- 500\n- 531 template \n-533 inline void applyRayleighQuotientIteration (const Real& epsilon,\n- 534 ISTLLinearSolver& solver,\n- 535 BlockVector& x, Real& lambda) const\n- 536 {\n- 537 // print verbosity information\n- 538 if (verbosity_level_ > 0)\n- 539 std::cout << title_\n- 540 << \"Performing Rayleigh quotient iteration for \"\n- 541 << \"estimated eigenvalue \" << lambda << \".\" << std::endl;\n- 542\n- 543 // allocate memory for linear solver statistics\n- 544 Dune::InverseOperatorResult solver_statistics;\n- 545\n- 546 // allocate memory for auxiliary variables\n- 547 BlockVector y(x);\n- 548 Real y_norm;\n- 549 Real lambda_update;\n- 550 BlockVector temp(x);\n- 551\n- 552 // perform Rayleigh quotient iteration\n- 553 x *= (1.0 / x.two_norm());\n- 554 Real r_norm = std::numeric_limits::max();\n- 555 nIterations_ = 0;\n- 556 while (r_norm > epsilon)\n- 557 {\n- 558 // update and check number of iterations\n- 559 if (++nIterations_ > nIterationsMax_)\n- 560 DUNE_THROW(Dune::ISTLError,\"Rayleigh quotient iteration did not \"\n- 561 << \"converge in \" << nIterationsMax_ << \" iterations \"\n- 562 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n- 563 << epsilon << \").\");\n- 564\n- 565 // update iteration operator,\n- 566 // update iteration matrix when needed\n- 567 updateShiftMu(lambda,solver);\n- 568\n- 569 // do one iteration of the Rayleigh quotient iteration algorithm,\n- 570 // part 1: solve (m_ - lambda*I) * y = x for y\n- 571 // (protect x from being changed)\n- 572 temp = x;\n- 573 solver.apply(y,temp,solver_statistics);\n- 574\n- 575 // get norm of y\n- 576 y_norm = y.two_norm();\n- 577\n- 578 // compile time switch between accuracy and efficiency\n- 579 if (avoidLinSolverCrime)\n- 580 {\n- 581 // get approximated eigenvalue lambda via the Rayleigh quotient\n- 582 // (use that x_new = y / y_norm)\n- 583 m_.mv(y,temp);\n- 584 lambda = (y * temp) / (y_norm * y_norm);\n- 585\n- 586 // get norm of residual\n- 587 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)\n- 588 temp.axpy(-lambda,y);\n- 589 r_norm = temp.two_norm() / y_norm;\n- 590 }\n- 591 else\n- 592 {\n- 593 // get approximated eigenvalue lambda via the Rayleigh quotient\n- 594 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)\n- 595 lambda_update = (y * x) / (y_norm * y_norm);\n- 596 lambda += lambda_update;\n- 597\n- 598 // get norm of residual\n- 599 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)\n- 600 temp = x; temp.axpy(-lambda_update,y);\n- 601 r_norm = temp.two_norm() / y_norm;\n- 602 }\n- 603\n- 604 // do one iteration of the Rayleigh quotient iteration algorithm,\n- 605 // part 2: update x\n- 606 x = y;\n- 607 x *= (1.0 / y_norm);\n- 608\n- 609 // print verbosity information\n- 610 if (verbosity_level_ > 1)\n- 611 std::cout << blank_ << std::left\n- 612 << \"iteration \" << std::setw(3) << nIterations_\n- 613 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n- 614 << \"): \u03bb = \" << lambda << std::endl\n- 615 << std::resetiosflags(std::ios::left);\n- 616 }\n- 617\n- 618 // print verbosity information\n- 619 if (verbosity_level_ > 0)\n- 620 {\n- 621 std::cout << blank_ << \"Result (\"\n- 622 << \"#iterations = \" << nIterations_ << \", \"\n- 623 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 624 << \"\u03bb = \" << lambda << std::endl;\n- 625 if (verbosity_level_ > 2)\n- 626 {\n- 627 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 628 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 629 }\n- 630 }\n- 631 }\n- 632\n- 689 template \n-691 inline void applyTLIMEIteration (const Real& gamma, const Real& eta,\n- 692 const Real& epsilon,\n- 693 ISTLLinearSolver& solver,\n- 694 const Real& delta, const std::size_t& m,\n- 695 bool& extrnl,\n- 696 BlockVector& x, Real& lambda) const\n- 697 {\n- 698 // use same variable names as in [Szyld, 1988]\n- 699 BlockVector& x_s = x;\n- 700 Real& mu_s = lambda;\n- 701\n- 702 // print verbosity information\n- 703 if (verbosity_level_ > 0)\n- 704 std::cout << title_\n- 705 << \"Performing TLIME iteration for \"\n- 706 << \"estimated eigenvalue in the \"\n- 707 << \"interval (\" << gamma - eta << \",\"\n- 708 << gamma + eta << \").\" << std::endl;\n- 709\n- 710 // allocate memory for linear solver statistics\n- 711 Dune::InverseOperatorResult solver_statistics;\n- 712\n- 713 // allocate memory for auxiliary variables\n- 714 bool doRQI;\n- 715 Real mu;\n- 716 BlockVector y(x_s);\n- 717 Real omega;\n- 718 Real mu_s_old;\n- 719 Real mu_s_update;\n- 720 BlockVector temp(x_s);\n- 721 Real q_norm, r_norm;\n- 722\n- 723 // perform TLIME iteration\n- 724 x_s *= (1.0 / x_s.two_norm());\n- 725 extrnl = true;\n- 726 doRQI = false;\n- 727 r_norm = std::numeric_limits::max();\n- 728 nIterations_ = 0;\n- 729 while (r_norm > epsilon)\n- 730 {\n- 731 // update and check number of iterations\n- 732 if (++nIterations_ > nIterationsMax_)\n- 733 DUNE_THROW(Dune::ISTLError,\"TLIME iteration did not \"\n- 734 << \"converge in \" << nIterationsMax_\n- 735 << \" iterations (\u2551residual\u2551_2 = \" << r_norm\n- 736 << \", epsilon = \" << epsilon << \").\");\n- 737\n- 738 // set shift for next iteration according to inverse iteration\n- 739 // with shift (II) resp. Rayleigh quotient iteration (RQI)\n- 740 if (doRQI)\n- 741 mu = mu_s;\n- 742 else\n- 743 mu = gamma;\n- 744\n- 745 // update II/RQI iteration operator,\n- 746 // update II/RQI iteration matrix when needed\n- 747 updateShiftMu(mu,solver);\n- 748\n- 749 // do one iteration of the II/RQI algorithm,\n- 750 // part 1: solve (m_ - mu*I) * y = x for y\n- 751 temp = x_s;\n- 752 solver.apply(y,temp,solver_statistics);\n- 753\n- 754 // do one iteration of the II/RQI algorithm,\n- 755 // part 2: compute omega\n- 756 omega = (1.0 / y.two_norm());\n- 757\n- 758 // backup the old Rayleigh quotient\n- 759 mu_s_old = mu_s;\n- 760\n- 761 // compile time switch between accuracy and efficiency\n- 762 if (avoidLinSolverCrime)\n- 763 {\n- 764 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue\n- 765 // (use that x_new = y * omega)\n- 766 m_.mv(y,temp);\n- 767 mu_s = (y * temp) * (omega * omega);\n- 768\n- 769 // get norm of \"the residual with respect to the shift used by II\",\n- 770 // use normal representation of q\n- 771 // (use that x_new = y * omega, use that temp = m_ * y)\n- 772 temp.axpy(-gamma,y);\n- 773 q_norm = temp.two_norm() * omega;\n- 774\n- 775 // get norm of \"the residual with respect to the Rayleigh quotient\"\n- 776 r_norm = q_norm*q_norm - (gamma-mu_s)*(gamma-mu_s);\n- 777 // prevent that truncation errors invalidate the norm\n- 778 // (we don't want to calculate sqrt of a negative number)\n- 779 if (r_norm >= 0)\n- 780 {\n- 781 // use relation between the norms of r and q for efficiency\n- 782 r_norm = std::sqrt(r_norm);\n- 783 }\n- 784 else\n- 785 {\n- 786 // use relation between r and q\n- 787 // (use that x_new = y * omega, use that temp = (m_ - gamma*I) * y = q /\n-omega)\n- 788 temp.axpy(gamma-mu_s,y);\n- 789 r_norm = temp.two_norm() * omega;\n- 790 }\n- 791 }\n- 792 else\n- 793 {\n- 794 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue\n- 795 if (!doRQI)\n- 796 {\n- 797 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y =\n-x_s)\n- 798 mu_s = gamma + (y * x_s) * (omega * omega);\n- 799 }\n- 800 else\n- 801 {\n- 802 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) *\n-y = x_s)\n- 803 mu_s_update = (y * x_s) * (omega * omega);\n- 804 mu_s += mu_s_update;\n- 805 }\n- 806\n- 807 // get norm of \"the residual with respect to the shift used by II\"\n- 808 if (!doRQI)\n- 809 {\n- 810 // use special representation of q in the II case\n- 811 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y =\n-x_s)\n- 812 q_norm = omega;\n- 813 }\n- 814 else\n- 815 {\n- 816 // use special representation of q in the RQI case\n- 817 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) *\n-y = x_s)\n- 818 temp = x_s; temp.axpy(mu_s-gamma,y);\n- 819 q_norm = temp.two_norm() * omega;\n- 820 }\n- 821\n- 822 // get norm of \"the residual with respect to the Rayleigh quotient\"\n- 823 // don't use efficient relation between the norms of r and q, as\n- 824 // this relation seems to yield a less accurate r_norm in the case\n- 825 // where linear solver crime is admitted\n- 826 if (!doRQI)\n- 827 {\n- 828 // (use that x_new = y * omega and use that (m_ - gamma*I) * y = x_s)\n- 829 temp = x_s; temp.axpy(gamma-lambda,y);\n- 830 r_norm = temp.two_norm() * omega;\n- 831 }\n- 832 else\n- 833 {\n- 834 // (use that x_new = y * omega and use that (m_ - mu_s_old*I) * y = x_s)\n- 835 temp = x_s; temp.axpy(-mu_s_update,y);\n- 836 r_norm = temp.two_norm() * omega;\n- 837 }\n- 838 }\n- 839\n- 840 // do one iteration of the II/RQI algorithm,\n- 841 // part 3: update x\n- 842 x_s = y; x_s *= omega;\n- 843\n- 844 // // for relative residual norm mode, scale with mu_s^{-1}\n- 845 // r_norm /= std::abs(mu_s);\n- 846\n- 847 // print verbosity information\n- 848 if (verbosity_level_ > 1)\n- 849 std::cout << blank_ << \"iteration \"\n- 850 << std::left << std::setw(3) << nIterations_\n- 851 << \" (\" << (doRQI ? \"RQI,\" : \"II, \")\n- 852 << \" \" << (doRQI ? \"\u2014>\" : \" \") << \" \"\n- 853 << \"\u2551r\u2551_2 = \" << std::setw(11) << r_norm\n- 854 << \", \" << (doRQI ? \" \" : \"\u2014>\") << \" \"\n- 855 << \"\u2551q\u2551_2 = \" << std::setw(11) << q_norm\n- 856 << \"): \u03bb = \" << lambda << std::endl\n- 857 << std::resetiosflags(std::ios::left);\n- 858\n- 859 // check if the eigenvalue closest to gamma lies in J\n- 860 if (!doRQI && q_norm < eta)\n- 861 {\n- 862 // J is not free of eigenvalues\n- 863 extrnl = false;\n- 864\n- 865 // by theory we know now that mu_s also lies in J\n- 866 assert(std::abs(mu_s-gamma) < eta);\n- 867\n- 868 // switch to RQI\n- 869 doRQI = true;\n- 870 }\n- 871\n- 872 // revert to II if J is not free of eigenvalues but\n- 873 // at some point mu_s falls back again outside J\n- 874 if (!extrnl && doRQI && std::abs(mu_s-gamma) >= eta)\n- 875 doRQI = false;\n- 876\n- 877 // if eigenvalue closest to gamma does not lie in J use RQI\n- 878 // solely to accelerate the convergence to this eigenvalue\n- 879 // when II has become stationary\n- 880 if (extrnl && !doRQI)\n- 881 {\n- 882 // switch to RQI if the relative change of the Rayleigh\n- 883 // quotient indicates that II has become stationary\n- 884 if (nIterations_ >= m &&\n- 885 std::abs(mu_s - mu_s_old) / std::abs(mu_s) < delta)\n- 886 doRQI = true;\n- 887 }\n- 888 }\n- 889\n- 890 // // compute final residual and lambda again (paranoia....)\n- 891 // m_.mv(x_s,temp);\n- 892 // mu_s = x_s * temp;\n- 893 // temp.axpy(-mu_s,x_s);\n- 894 // r_norm = temp.two_norm();\n- 895 // // r_norm /= std::abs(mu_s);\n- 896\n- 897 // print verbosity information\n- 898 if (verbosity_level_ > 0)\n- 899 {\n- 900 if (extrnl)\n- 901 std::cout << blank_ << \"Interval \"\n- 902 << \"(\" << gamma - eta << \",\" << gamma + eta\n- 903 << \") is free of eigenvalues, approximating \"\n- 904 << \"the closest eigenvalue.\" << std::endl;\n- 905 std::cout << blank_ << \"Result (\"\n- 906 << \"#iterations = \" << nIterations_ << \", \"\n- 907 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 908 << \"\u03bb = \" << lambda << std::endl;\n- 909 if (verbosity_level_ > 2)\n- 910 {\n- 911 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 912 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 913 }\n- 914 }\n- 915 }\n- 916\n-925 inline IterationOperator& getIterationOperator ()\n- 926 {\n- 927 // return iteration operator\n- 928 return itOperator_;\n- 929 }\n- 930\n-945 inline const BCRSMatrix& getIterationMatrix () const\n- 946 {\n- 947 // create iteration matrix on demand\n- 948 if (!itMatrix_)\n- 949 itMatrix_ = std::make_unique(m_);\n- 950\n- 951 // return iteration matrix\n- 952 return *itMatrix_;\n- 953 }\n- 954\n-959 inline unsigned int getIterationCount () const\n- 960 {\n- 961 if (nIterations_ == 0)\n- 962 DUNE_THROW(Dune::ISTLError,\"No algorithm applied, yet.\");\n- 963\n- 964 return nIterations_;\n- 965 }\n- 966\n- 967 protected:\n- 982 template \n-983 inline void updateShiftMu (const Real& mu,\n- 984 ISTLLinearSolver& solver) const\n- 985 {\n- 986 // do nothing if new shift equals the old one\n- 987 if (mu == mu_) return;\n- 988\n- 989 // update shift mu_, i.e. update iteration operator\n- 990 mu_ = mu;\n- 991\n- 992 // update iteration matrix when needed\n- 993 if (itMatrix_)\n- 994 {\n- 995 // iterate over entries in iteration matrix diagonal\n- 996 constexpr int rowBlockSize = BCRSMatrix::block_type::rows;\n- 997 constexpr int colBlockSize = BCRSMatrix::block_type::cols;\n- 998 for (typename BCRSMatrix::size_type i = 0;\n- 999 i < itMatrix_->M()*rowBlockSize; ++i)\n- 1000 {\n- 1001 // access m_[i,i] where i is the flat index of a row/column\n- 1002 const Real& m_entry = m_\n- 1003 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];\n- 1004 // access *itMatrix[i,i] where i is the flat index of a row/column\n- 1005 Real& entry = (*itMatrix_)\n- 1006 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];\n- 1007 // change current entry in iteration matrix diagonal\n- 1008 entry = m_entry - mu_;\n- 1009 }\n- 1010 // notify linear solver about change of the iteration matrix object\n- 1011 SolverHelper::setMatrix\n- 1012 (solver,*itMatrix_);\n- 1013 }\n- 1014 }\n- 1015\n- 1016 protected:\n- 1017 // parameters related to iterative eigenvalue algorithms\n-1018 const BCRSMatrix& m_;\n-1019 const unsigned int nIterationsMax_;\n- 1020\n- 1021 // verbosity setting\n-1022 const unsigned int verbosity_level_;\n- 1023\n- 1024 // shift mu_ used by iteration operator/matrix (m_ - mu_*I)\n-1025 mutable Real mu_;\n- 1026\n- 1027 // iteration operator (m_ - mu_*I), passing shift mu_ by reference\n-1028 const MatrixOperator matrixOperator_;\n-1029 const ScalingOperator scalingOperator_;\n-1030 OperatorSum itOperator_;\n- 1031\n- 1032 // iteration matrix (m_ - mu_*I), provided on demand when needed\n- 1033 // (e.g. for preconditioning)\n-1034 mutable std::unique_ptr itMatrix_;\n- 1035\n- 1036 // memory for storing temporary variables (mutable as they shall\n- 1037 // just be effectless auxiliary variables of the const apply*(...)\n- 1038 // methods)\n-1039 mutable unsigned int nIterations_;\n- 1040\n- 1041 // constants for printing verbosity information\n-1042 const std::string title_;\n-1043 const std::string blank_;\n- 1044 };\n- 1045\n- 1048} // namespace Dune\n- 1049\n- 1050#endif // DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-istlexception.hh\n-solvercategory.hh\n-io.hh\n-Some generic functions for pretty printing vectors and matrices.\n-Dune::printvector\n-void printvector(std::ostream &s, const V &v, std::string title, std::string\n-rowtext, int columns=1, int width=10, int precision=2)\n-Print an ISTL vector.\n-Definition: io.hh:89\n+ 3#ifndef DUNE_ISTL_COMMON_COUNTER_HH\n+ 4#define DUNE_ISTL_COMMON_COUNTER_HH\n+ 5\n+ 6#include \n+ 7#include \n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12\n+ 13#include \n+ 14\n+15constexpr std::size_t maxcount = 100;\n+ 16\n+17#define DUNE_GET_COUNTER(Tag) \\\n+ 18 (counterFunc(Dune::PriorityTag{}, Tag{}, Dune::CounterImpl::\n+ADLTag{}))\n+ 19\n+20#define DUNE_INC_COUNTER(Tag) \\\n+ 21 namespace { \\\n+ 22 namespace CounterImpl { \\\n+ 23 constexpr std::size_t \\\n+ 24 counterFunc(Dune::PriorityTag p, Tag, ADLTag) \\\n+ 25 { \\\n+ 26 return p.value; \\\n+ 27 } \\\n+ 28 } \\\n+ 29 } \\\n+ 30 static_assert(true, \"unfudge indentation\")\n+ 31\n+ 32namespace Dune {\n+ 33 namespace {\n+ 34\n+35 namespace CounterImpl {\n+ 36\n+ 37 struct ADLTag {};\n+ 38\n+ 39 template\n+ 40 constexpr std::size_t counterFunc(Dune::PriorityTag<0>, Tag, ADLTag)\n+ 41 {\n+ 42 return 0;\n+ 43 }\n+ 44\n+ 45 } // end namespace CounterImpl\n+ 46 } // end empty namespace\n+ 47} // end namespace Dune\n+ 48#endif // DUNE_ISTL_COMMON_COUNTER_HH\n+maxcount\n+constexpr std::size_t maxcount\n+Definition: counter.hh:15\n Dune\n Definition: allocator.hh:11\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n-Dune::BCRSMatrix::M\n-size_type M() const\n-number of columns (counted in blocks)\n-Definition: bcrsmatrix.hh:1978\n-Dune::BCRSMatrix::mv\n-void mv(const X &x, Y &y) const\n-y = A x\n-Definition: bcrsmatrix.hh:1612\n-Dune::BCRSMatrix::N\n-size_type N() const\n-number of rows (counted in blocks)\n-Definition: bcrsmatrix.hh:1972\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::BlockVector::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bvector.hh:401\n-Dune::PowerIteration_Algorithms\n-Iterative eigenvalue algorithms based on power iteration.\n-Definition: poweriteration.hh:176\n-Dune::PowerIteration_Algorithms::itMatrix_\n-std::unique_ptr< BCRSMatrix > itMatrix_\n-Definition: poweriteration.hh:1034\n-Dune::PowerIteration_Algorithms::PowerIteration_Algorithms\n-PowerIteration_Algorithms(const PowerIteration_Algorithms &)=delete\n-Dune::PowerIteration_Algorithms::ScalingOperator\n-Impl::ScalingLinearOperator< BlockVector > ScalingOperator\n-Definition: poweriteration.hh:181\n-Dune::PowerIteration_Algorithms::blank_\n-const std::string blank_\n-Definition: poweriteration.hh:1043\n-Dune::PowerIteration_Algorithms::OperatorSum\n-Impl::LinearOperatorSum< MatrixOperator, ScalingOperator > OperatorSum\n-Definition: poweriteration.hh:182\n-Dune::PowerIteration_Algorithms::MatrixOperator\n-Dune::MatrixAdapter< BCRSMatrix, BlockVector, BlockVector > MatrixOperator\n-Definition: poweriteration.hh:180\n-Dune::PowerIteration_Algorithms::applyInverseIteration\n-void applyInverseIteration(const Real &epsilon, ISTLLinearSolver &solver,\n-BlockVector &x, Real &lambda) const\n-Perform the inverse iteration algorithm to compute an approximation lambda of\n-the least dominant (i....\n-Definition: poweriteration.hh:355\n-Dune::PowerIteration_Algorithms::applyTLIMEIteration\n-void applyTLIMEIteration(const Real &gamma, const Real &eta, const Real\n-&epsilon, ISTLLinearSolver &solver, const Real &delta, const std::size_t &m,\n-bool &extrnl, BlockVector &x, Real &lambda) const\n-Perform the \"two-level iterative method for eigenvalue calculations (TLIME)\"\n-iteration algorit...\n-Definition: poweriteration.hh:691\n-Dune::PowerIteration_Algorithms::getIterationOperator\n-IterationOperator & getIterationOperator()\n-Return the iteration operator (m_ - mu_*I).\n-Definition: poweriteration.hh:925\n-Dune::PowerIteration_Algorithms::itOperator_\n-OperatorSum itOperator_\n-Definition: poweriteration.hh:1030\n-Dune::PowerIteration_Algorithms::m_\n-const BCRSMatrix & m_\n-Definition: poweriteration.hh:1018\n-Dune::PowerIteration_Algorithms::PowerIteration_Algorithms\n-PowerIteration_Algorithms(const BCRSMatrix &m, const unsigned int\n-nIterationsMax=1000, const unsigned int verbosity_level=0)\n-Construct from required parameters.\n-Definition: poweriteration.hh:206\n-Dune::PowerIteration_Algorithms::nIterationsMax_\n-const unsigned int nIterationsMax_\n-Definition: poweriteration.hh:1019\n-Dune::PowerIteration_Algorithms::applyPowerIteration\n-void applyPowerIteration(const Real &epsilon, BlockVector &x, Real &lambda)\n-const\n-Perform the power iteration algorithm to compute an approximation lambda of the\n-dominant (i....\n-Definition: poweriteration.hh:260\n-Dune::PowerIteration_Algorithms::IterationOperator\n-OperatorSum IterationOperator\n-Type of iteration operator (m_ - mu_*I)\n-Definition: poweriteration.hh:189\n-Dune::PowerIteration_Algorithms::applyRayleighQuotientIteration\n-void applyRayleighQuotientIteration(const Real &epsilon, ISTLLinearSolver\n-&solver, BlockVector &x, Real &lambda) const\n-Perform the Rayleigh quotient iteration algorithm to compute an approximation\n-lambda of an eigenvalue...\n-Definition: poweriteration.hh:533\n-Dune::PowerIteration_Algorithms::applyInverseIteration\n-void applyInverseIteration(const Real &gamma, const Real &epsilon,\n-ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const\n-Perform the inverse iteration with shift algorithm to compute an approximation\n-lambda of the eigenval...\n-Definition: poweriteration.hh:394\n-Dune::PowerIteration_Algorithms::scalingOperator_\n-const ScalingOperator scalingOperator_\n-Definition: poweriteration.hh:1029\n-Dune::PowerIteration_Algorithms::updateShiftMu\n-void updateShiftMu(const Real &mu, ISTLLinearSolver &solver) const\n-Update shift mu_, i.e. update iteration operator/matrix (m_ - mu_*I).\n-Definition: poweriteration.hh:983\n-Dune::PowerIteration_Algorithms::operator=\n-PowerIteration_Algorithms & operator=(const PowerIteration_Algorithms &)=delete\n-Dune::PowerIteration_Algorithms::getIterationCount\n-unsigned int getIterationCount() const\n-Return the number of iterations in last application of an algorithm.\n-Definition: poweriteration.hh:959\n-Dune::PowerIteration_Algorithms::matrixOperator_\n-const MatrixOperator matrixOperator_\n-Definition: poweriteration.hh:1028\n-Dune::PowerIteration_Algorithms::getIterationMatrix\n-const BCRSMatrix & getIterationMatrix() const\n-Return the iteration matrix (m_ - mu_*I), provided on demand when needed (e.g.\n-for direct solvers or ...\n-Definition: poweriteration.hh:945\n-Dune::PowerIteration_Algorithms::nIterations_\n-unsigned int nIterations_\n-Definition: poweriteration.hh:1039\n-Dune::PowerIteration_Algorithms::verbosity_level_\n-const unsigned int verbosity_level_\n-Definition: poweriteration.hh:1022\n-Dune::PowerIteration_Algorithms::title_\n-const std::string title_\n-Definition: poweriteration.hh:1042\n-Dune::PowerIteration_Algorithms::Real\n-BlockVector::field_type Real\n-Type of underlying field.\n-Definition: poweriteration.hh:186\n-Dune::PowerIteration_Algorithms::mu_\n-Real mu_\n-Definition: poweriteration.hh:1025\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::LinearOperator\n-A linear operator.\n-Definition: operators.hh:67\n-Dune::LinearOperator<_X,_X_>::field_type\n-X::field_type field_type\n-The field type of the operator.\n-Definition: operators.hh:74\n-Dune::LinearOperator<_X,_X_>::applyscaleadd\n-virtual void applyscaleadd(field_type alpha, const X &x, X &y) const=0\n-apply operator to x, scale and add:\n-Dune::LinearOperator<_X,_X_>::category\n-virtual SolverCategory::Category category() const=0\n-Category of the linear operator (see SolverCategory::Category)\n-Dune::LinearOperator<_X,_X_>::range_type\n-X range_type\n-The type of the range of the operator.\n-Definition: operators.hh:72\n-Dune::LinearOperator<_X,_X_>::apply\n-virtual void apply(const X &x, X &y) const=0\n-apply operator to x: The input vector is consistent and the output must also be\n-consistent on the in...\n-Dune::LinearOperator<_X,_X_>::domain_type\n-X domain_type\n-The type of the domain of the operator.\n-Definition: operators.hh:70\n-Dune::MatrixAdapter\n-Adapter to turn a matrix into a linear operator.\n-Definition: operators.hh:137\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::SolverHelper::setMatrix\n-static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n-Definition: solver.hh:524\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00038.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00038.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: arpackpp.hh File Reference\n+dune-istl: novlpschwarz.hh File Reference\n \n \n \n \n \n \n \n@@ -58,47 +58,60 @@\n \n
    \n \n \n
    \n
    \n \n-
    arpackpp.hh File Reference
    \n+
    novlpschwarz.hh File Reference
    \n
    \n
    \n-
    #include <cmath>
    \n-#include <iostream>
    \n-#include <string>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n-#include <dune/istl/bvector.hh>
    \n-#include <dune/istl/istlexception.hh>
    \n-#include <dune/istl/io.hh>
    \n-#include "arssym.h"
    \n+
    #include <iostream>
    \n+#include <fstream>
    \n+#include <vector>
    \n+#include <sstream>
    \n+#include <cmath>
    \n+#include <dune/common/timer.hh>
    \n+#include <dune/common/hybridutilities.hh>
    \n+#include "io.hh"
    \n+#include "bvector.hh"
    \n+#include "vbvector.hh"
    \n+#include "bcrsmatrix.hh"
    \n+#include "gsetc.hh"
    \n+#include "ilu.hh"
    \n+#include "operators.hh"
    \n+#include "solvers.hh"
    \n+#include "preconditioners.hh"
    \n+#include "scalarproducts.hh"
    \n+#include "owneroverlapcopy.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::ArPackPlusPlus_Algorithms< BCRSMatrix, BlockVector >
     Wrapper to use a range of ARPACK++ eigenvalue solvers. More...
    class  Dune::NonoverlappingSchwarzOperator< M, X, Y, C >
     A nonoverlapping operator with communication object. More...
     
    class  Dune::NonoverlappingBlockPreconditioner< C, P >
     Nonoverlapping parallel preconditioner. More...
     
    \n \n \n \n+\n+\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,31 +4,43 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * eigenvalue\n Classes | Namespaces\n-arpackpp.hh File Reference\n-#include \n+novlpschwarz.hh File Reference\n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"arssym.h\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"io.hh\"\n+#include \"bvector.hh\"\n+#include \"vbvector.hh\"\n+#include \"bcrsmatrix.hh\"\n+#include \"gsetc.hh\"\n+#include \"ilu.hh\"\n+#include \"operators.hh\"\n+#include \"solvers.hh\"\n+#include \"preconditioners.hh\"\n+#include \"scalarproducts.hh\"\n+#include \"owneroverlapcopy.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::ArPackPlusPlus_Algorithms<_BCRSMatrix,_BlockVector_>\n-\u00a0 Wrapper to use a range of ARPACK++ eigenvalue solvers. More...\n+class \u00a0Dune::NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>\n+\u00a0 A nonoverlapping operator with communication object. More...\n+\u00a0\n+class \u00a0Dune::NonoverlappingBlockPreconditioner<_C,_P_>\n+\u00a0 Nonoverlapping parallel preconditioner. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::Amg\n+\u00a0\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00038_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00038_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: arpackpp.hh Source File\n+dune-istl: novlpschwarz.hh Source File\n \n \n \n \n \n \n \n@@ -58,863 +58,350 @@\n \n
    \n \n \n
    \n
    \n-
    arpackpp.hh
    \n+
    novlpschwarz.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n-
    6#define DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n+
    5#ifndef DUNE_ISTL_NOVLPSCHWARZ_HH
    \n+
    6#define DUNE_ISTL_NOVLPSCHWARZ_HH
    \n
    7
    \n-
    8#if HAVE_ARPACKPP || defined DOXYGEN
    \n-
    9
    \n-
    10#include <cmath> // provides std::abs, std::pow, std::sqrt
    \n-
    11
    \n-
    12#include <iostream> // provides std::cout, std::endl
    \n-
    13#include <string> // provides std::string
    \n+
    8#include <iostream> // for input/output to shell
    \n+
    9#include <fstream> // for input/output to files
    \n+
    10#include <vector> // STL vector class
    \n+
    11#include <sstream>
    \n+
    12
    \n+
    13#include <cmath> // Yes, we do some math here
    \n
    14
    \n-
    15#include <dune/common/fvector.hh> // provides Dune::FieldVector
    \n-
    16#include <dune/common/exceptions.hh> // provides DUNE_THROW(...)
    \n-
    17
    \n-
    18#include <dune/istl/blocklevel.hh> // provides Dune::blockLevel
    \n-
    19#include <dune/istl/bvector.hh> // provides Dune::BlockVector
    \n-
    20#include <dune/istl/istlexception.hh> // provides Dune::ISTLError
    \n-
    21#include <dune/istl/io.hh> // provides Dune::printvector(...)
    \n-
    22
    \n-
    23#ifdef Status
    \n-
    24#undef Status // prevent preprocessor from damaging the ARPACK++
    \n-
    25 // code when "X11/Xlib.h" is included (the latter
    \n-
    26 // defines Status as "#define Status int" and
    \n-
    27 // ARPACK++ provides a class with a method called
    \n-
    28 // Status)
    \n-
    29#endif
    \n-
    30#include "arssym.h" // provides ARSymStdEig
    \n+
    15#include <dune/common/timer.hh>
    \n+
    16
    \n+
    17#include <dune/common/hybridutilities.hh>
    \n+
    18
    \n+
    19#include "io.hh"
    \n+
    20#include "bvector.hh"
    \n+
    21#include "vbvector.hh"
    \n+
    22#include "bcrsmatrix.hh"
    \n+
    23#include "io.hh"
    \n+
    24#include "gsetc.hh"
    \n+
    25#include "ilu.hh"
    \n+
    26#include "operators.hh"
    \n+
    27#include "solvers.hh"
    \n+
    28#include "preconditioners.hh"
    \n+
    29#include "scalarproducts.hh"
    \n+
    30#include "owneroverlapcopy.hh"
    \n
    31
    \n-
    32namespace Dune
    \n-
    33{
    \n-
    34
    \n-
    39 namespace Impl {
    \n-
    55 template <class BCRSMatrix>
    \n-
    56 class ArPackPlusPlus_BCRSMatrixWrapper
    \n-
    57 {
    \n-
    58 public:
    \n-
    60 typedef typename BCRSMatrix::field_type Real;
    \n-
    61
    \n-
    62 public:
    \n-
    64 ArPackPlusPlus_BCRSMatrixWrapper (const BCRSMatrix& A)
    \n-
    65 : A_(A),
    \n-
    66 m_(A_.M() * mBlock), n_(A_.N() * nBlock)
    \n-
    67 {
    \n-
    68 // assert that BCRSMatrix type has blocklevel 2
    \n-
    69 static_assert
    \n-
    70 (blockLevel<BCRSMatrix>() == 2,
    \n-
    71 "Only BCRSMatrices with blocklevel 2 are supported.");
    \n-
    72
    \n-
    73 // allocate memory for auxiliary block vector objects
    \n-
    74 // which are compatible to matrix rows / columns
    \n-
    75 domainBlockVector.resize(A_.N());
    \n-
    76 rangeBlockVector.resize(A_.M());
    \n-
    77 }
    \n-
    78
    \n-
    80 inline void multMv (Real* v, Real* w)
    \n-
    81 {
    \n-
    82 // get vector v as an object of appropriate type
    \n-
    83 arrayToDomainBlockVector(v,domainBlockVector);
    \n+
    32namespace Dune {
    \n+
    33
    \n+
    59 template<class M, class X, class Y, class C>
    \n+\n+
    61 {
    \n+
    62 public:
    \n+
    64 typedef M matrix_type;
    \n+
    66 typedef X domain_type;
    \n+
    68 typedef Y range_type;
    \n+
    70 typedef typename X::field_type field_type;
    \n+\n+
    73
    \n+
    74 typedef typename C::PIS PIS;
    \n+
    75 typedef typename C::RI RI;
    \n+
    76 typedef typename RI::RemoteIndexList RIL;
    \n+
    77 typedef typename RI::const_iterator RIIterator;
    \n+
    78 typedef typename RIL::const_iterator RILIterator;
    \n+
    79 typedef typename M::ConstColIterator ColIterator;
    \n+
    80 typedef typename M::ConstRowIterator RowIterator;
    \n+
    81 typedef std::multimap<int,int> MM;
    \n+
    82 typedef std::multimap<int,std::pair<int,RILIterator> > RIMap;
    \n+
    83 typedef typename RIMap::iterator RIMapit;
    \n
    84
    \n-
    85 // perform matrix-vector product
    \n-
    86 A_.mv(domainBlockVector,rangeBlockVector);
    \n-
    87
    \n-
    88 // get vector w from object of appropriate type
    \n-
    89 rangeBlockVectorToArray(rangeBlockVector,w);
    \n-
    90 };
    \n-
    91
    \n-
    93 inline void multMtMv (Real* v, Real* w)
    \n-
    94 {
    \n-
    95 // get vector v as an object of appropriate type
    \n-
    96 arrayToDomainBlockVector(v,domainBlockVector);
    \n-
    97
    \n-
    98 // perform matrix-vector product
    \n-
    99 A_.mv(domainBlockVector,rangeBlockVector);
    \n-
    100 A_.mtv(rangeBlockVector,domainBlockVector);
    \n-
    101
    \n-
    102 // get vector w from object of appropriate type
    \n-
    103 domainBlockVectorToArray(domainBlockVector,w);
    \n-
    104 };
    \n-
    105
    \n-
    107 inline void multMMtv (Real* v, Real* w)
    \n-
    108 {
    \n-
    109 // get vector v as an object of appropriate type
    \n-
    110 arrayToRangeBlockVector(v,rangeBlockVector);
    \n-
    111
    \n-
    112 // perform matrix-vector product
    \n-
    113 A_.mtv(rangeBlockVector,domainBlockVector);
    \n-
    114 A_.mv(domainBlockVector,rangeBlockVector);
    \n-
    115
    \n-
    116 // get vector w from object of appropriate type
    \n-
    117 rangeBlockVectorToArray(rangeBlockVector,w);
    \n-
    118 };
    \n+\n+
    93 : _A_(stackobject_to_shared_ptr(A)), communication(com), buildcomm(true)
    \n+
    94 {}
    \n+
    95
    \n+
    96 NonoverlappingSchwarzOperator (std::shared_ptr<const matrix_type> A, const communication_type& com)
    \n+
    97 : _A_(A), communication(com), buildcomm(true)
    \n+
    98 {}
    \n+
    99
    \n+
    101 virtual void apply (const X& x, Y& y) const
    \n+
    102 {
    \n+
    103 y = 0;
    \n+
    104 novlp_op_apply(x,y,1);
    \n+
    105 communication.addOwnerCopyToOwnerCopy(y,y);
    \n+
    106 }
    \n+
    107
    \n+
    109 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n+
    110 {
    \n+
    111 // only apply communication to alpha*A*x to make it consistent,
    \n+
    112 // y already has to be consistent.
    \n+
    113 Y y1(y);
    \n+
    114 y = 0;
    \n+
    115 novlp_op_apply(x,y,alpha);
    \n+
    116 communication.addOwnerCopyToOwnerCopy(y,y);
    \n+
    117 y += y1;
    \n+
    118 }
    \n
    119
    \n-
    121 inline int nrows () const { return m_; }
    \n-
    122
    \n-
    124 inline int ncols () const { return n_; }
    \n+
    121 virtual const matrix_type& getmat () const
    \n+
    122 {
    \n+
    123 return *_A_;
    \n+
    124 }
    \n
    125
    \n-
    126 protected:
    \n-
    127 // Number of rows and columns in each block of the matrix
    \n-
    128 constexpr static int mBlock = BCRSMatrix::block_type::rows;
    \n-
    129 constexpr static int nBlock = BCRSMatrix::block_type::cols;
    \n-
    130
    \n-
    131 // Type of vectors in the domain of the linear map associated with
    \n-
    132 // the matrix, i.e. block vectors compatible to matrix rows
    \n-
    133 constexpr static int dbvBlockSize = nBlock;
    \n-
    134 typedef Dune::FieldVector<Real,dbvBlockSize> DomainBlockVectorBlock;
    \n-
    135 typedef Dune::BlockVector<DomainBlockVectorBlock> DomainBlockVector;
    \n+
    126 void novlp_op_apply (const X& x, Y& y, field_type alpha) const
    \n+
    127 {
    \n+
    128 //get index sets
    \n+
    129 const PIS& pis=communication.indexSet();
    \n+
    130 const RI& ri = communication.remoteIndices();
    \n+
    131
    \n+
    132 // at the beginning make a multimap "bordercontribution".
    \n+
    133 // process has i and j as border dofs but is not the owner
    \n+
    134 // => only contribute to Ax if i,j is in bordercontribution
    \n+
    135 if (buildcomm == true) {
    \n
    136
    \n-
    137 // Type of vectors in the range of the linear map associated with
    \n-
    138 // the matrix, i.e. block vectors compatible to matrix columns
    \n-
    139 constexpr static int rbvBlockSize = mBlock;
    \n-
    140 typedef Dune::FieldVector<Real,rbvBlockSize> RangeBlockVectorBlock;
    \n-
    141 typedef Dune::BlockVector<RangeBlockVectorBlock> RangeBlockVector;
    \n-
    142
    \n-
    143 // Types for vector index access
    \n-
    144 typedef typename DomainBlockVector::size_type dbv_size_type;
    \n-
    145 typedef typename RangeBlockVector::size_type rbv_size_type;
    \n-
    146 typedef typename DomainBlockVectorBlock::size_type dbvb_size_type;
    \n-
    147 typedef typename RangeBlockVectorBlock::size_type rbvb_size_type;
    \n+
    137 // set up mask vector
    \n+
    138 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size())) {
    \n+
    139 mask.resize(x.size());
    \n+
    140 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n+
    141 mask[i] = 1;
    \n+
    142 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n+
    143 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
    \n+
    144 mask[i->local().local()] = 0;
    \n+
    145 else if (i->local().attribute()==OwnerOverlapCopyAttributeSet::overlap)
    \n+
    146 mask[i->local().local()] = 2;
    \n+
    147 }
    \n
    148
    \n-
    149 // Get vector v from a block vector object which is compatible to
    \n-
    150 // matrix rows
    \n-
    151 static inline void
    \n-
    152 domainBlockVectorToArray (const DomainBlockVector& dbv, Real* v)
    \n-
    153 {
    \n-
    154 for (dbv_size_type block = 0; block < dbv.N(); ++block)
    \n-
    155 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
    \n-
    156 v[block*dbvBlockSize + iBlock] = dbv[block][iBlock];
    \n-
    157 }
    \n-
    158
    \n-
    159 // Get vector v from a block vector object which is compatible to
    \n-
    160 // matrix columns
    \n-
    161 static inline void
    \n-
    162 rangeBlockVectorToArray (const RangeBlockVector& rbv, Real* v)
    \n-
    163 {
    \n-
    164 for (rbv_size_type block = 0; block < rbv.N(); ++block)
    \n-
    165 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
    \n-
    166 v[block*rbvBlockSize + iBlock] = rbv[block][iBlock];
    \n-
    167 }
    \n-
    168
    \n-
    169 public:
    \n-
    172 static inline void arrayToDomainBlockVector (const Real* v,
    \n-
    173 DomainBlockVector& dbv)
    \n-
    174 {
    \n-
    175 for (dbv_size_type block = 0; block < dbv.N(); ++block)
    \n-
    176 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
    \n-
    177 dbv[block][iBlock] = v[block*dbvBlockSize + iBlock];
    \n-
    178 }
    \n-
    179
    \n-
    182 static inline void arrayToRangeBlockVector (const Real* v,
    \n-
    183 RangeBlockVector& rbv)
    \n-
    184 {
    \n-
    185 for (rbv_size_type block = 0; block < rbv.N(); ++block)
    \n-
    186 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
    \n-
    187 rbv[block][iBlock] = v[block*rbvBlockSize + iBlock];
    \n-
    188 }
    \n-
    189
    \n-
    190 protected:
    \n-
    191 // The DUNE-ISTL BCRSMatrix
    \n-
    192 const BCRSMatrix& A_;
    \n-
    193
    \n-
    194 // Number of rows and columns in the matrix
    \n-
    195 const int m_, n_;
    \n-
    196
    \n-
    197 // Auxiliary block vector objects which are
    \n-
    198 // compatible to matrix rows / columns
    \n-
    199 mutable DomainBlockVector domainBlockVector;
    \n-
    200 mutable RangeBlockVector rangeBlockVector;
    \n-
    201 };
    \n-
    202 } // end namespace Impl
    \n-
    203
    \n-
    243 template <typename BCRSMatrix, typename BlockVector>
    \n-\n-
    245 {
    \n-
    246 public:
    \n-\n-
    248
    \n-
    249 public:
    \n-\n-
    269 const unsigned int nIterationsMax = 100000,
    \n-
    270 const unsigned int verbosity_level = 0)
    \n-
    271 : m_(m), nIterationsMax_(nIterationsMax),
    \n-
    272 verbosity_level_(verbosity_level),
    \n-
    273 nIterations_(0),
    \n-
    274 title_(" ArPackPlusPlus_Algorithms: "),
    \n-
    275 blank_(title_.length(),' ')
    \n-
    276 {}
    \n-
    277
    \n-
    289 inline void computeSymMaxMagnitude (const Real& epsilon,
    \n-
    290 BlockVector& x, Real& lambda) const
    \n-
    291 {
    \n-
    292 // print verbosity information
    \n-
    293 if (verbosity_level_ > 0)
    \n-
    294 std::cout << title_ << "Computing an approximation of "
    \n-
    295 << "the dominant eigenvalue of a matrix which "
    \n-
    296 << "is assumed to be symmetric." << std::endl;
    \n-
    297
    \n-
    298 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    299 // and to perform the product A*v (LU decomposition is not used)
    \n-
    300 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    301 WrappedMatrix A(m_);
    \n-
    302
    \n-
    303 // get number of rows and columns in A
    \n-
    304 const int nrows = A.nrows();
    \n-
    305 const int ncols = A.ncols();
    \n-
    306
    \n-
    307 // assert that A is square
    \n-
    308 if (nrows != ncols)
    \n-
    309 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n-
    310 << nrows << "x" << ncols << ").");
    \n-
    311
    \n-
    312 // allocate memory for variables, set parameters
    \n-
    313 const int nev = 1; // Number of eigenvalues to compute
    \n-
    314 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    315 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    316 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    317 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n-
    318 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    319 int nconv; // Number of converged eigenvalues
    \n-
    320
    \n-
    321 // define what we need: eigenvalues with largest magnitude
    \n-
    322 char which[] = "LM";
    \n-
    323 ARSymStdEig<Real,WrappedMatrix>
    \n-
    324 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n-
    325
    \n-
    326 // set ARPACK verbosity mode if requested
    \n-
    327 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    328
    \n-
    329 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n-
    330 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    331
    \n-
    332 // obtain approximated dominant eigenvalue of A
    \n-
    333 lambda = ev[nev-1];
    \n-
    334
    \n-
    335 // obtain associated approximated eigenvector of A
    \n-
    336 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n-
    337 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n-
    338
    \n-
    339 // obtain number of Arnoldi update iterations actually taken
    \n-
    340 nIterations_ = dprob.GetIter();
    \n-
    341
    \n-
    342 // compute residual norm
    \n-
    343 BlockVector r(x);
    \n-
    344 Real* Ax_raw = new Real[nrows];
    \n-
    345 A.multMv(x_raw,Ax_raw);
    \n-
    346 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
    \n-
    347 r.axpy(-lambda,x);
    \n-
    348 const Real r_norm = r.two_norm();
    \n-
    349
    \n-
    350 // print verbosity information
    \n-
    351 if (verbosity_level_ > 0)
    \n-
    352 {
    \n-
    353 if (verbosity_level_ > 1)
    \n-
    354 {
    \n-
    355 // print some information about the problem
    \n-
    356 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n-
    357 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n-
    358 << "StdEig:" << std::endl;
    \n-
    359 std::cout << blank_ << " converged eigenvalues of A: "
    \n-
    360 << nconv << " / " << nev << std::endl;
    \n-
    361 std::cout << blank_ << " dominant eigenvalue of A: "
    \n-
    362 << lambda << std::endl;
    \n-
    363 }
    \n-
    364 std::cout << blank_ << "Result ("
    \n-
    365 << "#iterations = " << nIterations_ << ", "
    \n-
    366 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    367 << "\u03bb = " << lambda << std::endl;
    \n-
    368 if (verbosity_level_ > 2)
    \n-
    369 {
    \n-
    370 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    371 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    372 }
    \n-
    373 }
    \n-
    374
    \n-
    375 // free dynamically allocated memory
    \n-
    376 delete[] Ax_raw;
    \n-
    377 delete[] ev;
    \n-
    378 }
    \n-
    379
    \n-
    391 inline void computeSymMinMagnitude (const Real& epsilon,
    \n-
    392 BlockVector& x, Real& lambda) const
    \n-
    393 {
    \n-
    394 // print verbosity information
    \n-
    395 if (verbosity_level_ > 0)
    \n-
    396 std::cout << title_ << "Computing an approximation of the "
    \n-
    397 << "least dominant eigenvalue of a matrix which "
    \n-
    398 << "is assumed to be symmetric." << std::endl;
    \n-
    399
    \n-
    400 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    401 // and to perform the product A*v (LU decomposition is not used)
    \n-
    402 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    403 WrappedMatrix A(m_);
    \n-
    404
    \n-
    405 // get number of rows and columns in A
    \n-
    406 const int nrows = A.nrows();
    \n-
    407 const int ncols = A.ncols();
    \n-
    408
    \n-
    409 // assert that A is square
    \n-
    410 if (nrows != ncols)
    \n-
    411 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n-
    412 << nrows << "x" << ncols << ").");
    \n-
    413
    \n-
    414 // allocate memory for variables, set parameters
    \n-
    415 const int nev = 1; // Number of eigenvalues to compute
    \n-
    416 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    417 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    418 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    419 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n-
    420 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    421 int nconv; // Number of converged eigenvalues
    \n-
    422
    \n-
    423 // define what we need: eigenvalues with smallest magnitude
    \n-
    424 char which[] = "SM";
    \n-
    425 ARSymStdEig<Real,WrappedMatrix>
    \n-
    426 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n-
    427
    \n-
    428 // set ARPACK verbosity mode if requested
    \n-
    429 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    430
    \n-
    431 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n-
    432 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    433
    \n-
    434 // obtain approximated least dominant eigenvalue of A
    \n-
    435 lambda = ev[nev-1];
    \n-
    436
    \n-
    437 // obtain associated approximated eigenvector of A
    \n-
    438 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n-
    439 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n-
    440
    \n-
    441 // obtain number of Arnoldi update iterations actually taken
    \n-
    442 nIterations_ = dprob.GetIter();
    \n-
    443
    \n-
    444 // compute residual norm
    \n-
    445 BlockVector r(x);
    \n-
    446 Real* Ax_raw = new Real[nrows];
    \n-
    447 A.multMv(x_raw,Ax_raw);
    \n-
    448 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
    \n-
    449 r.axpy(-lambda,x);
    \n-
    450 const Real r_norm = r.two_norm();
    \n-
    451
    \n-
    452 // print verbosity information
    \n-
    453 if (verbosity_level_ > 0)
    \n-
    454 {
    \n-
    455 if (verbosity_level_ > 1)
    \n-
    456 {
    \n-
    457 // print some information about the problem
    \n-
    458 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n-
    459 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n-
    460 << "StdEig:" << std::endl;
    \n-
    461 std::cout << blank_ << " converged eigenvalues of A: "
    \n-
    462 << nconv << " / " << nev << std::endl;
    \n-
    463 std::cout << blank_ << " least dominant eigenvalue of A: "
    \n-
    464 << lambda << std::endl;
    \n-
    465 }
    \n-
    466 std::cout << blank_ << "Result ("
    \n-
    467 << "#iterations = " << nIterations_ << ", "
    \n-
    468 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    469 << "\u03bb = " << lambda << std::endl;
    \n-
    470 if (verbosity_level_ > 2)
    \n-
    471 {
    \n-
    472 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n-
    473 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    474 }
    \n-
    475 }
    \n-
    476
    \n-
    477 // free dynamically allocated memory
    \n-
    478 delete[] Ax_raw;
    \n-
    479 delete[] ev;
    \n-
    480 }
    \n-
    481
    \n-
    493 inline void computeSymCond2 (const Real& epsilon, Real& cond_2) const
    \n-
    494 {
    \n-
    495 // print verbosity information
    \n-
    496 if (verbosity_level_ > 0)
    \n-
    497 std::cout << title_ << "Computing an approximation of the "
    \n-
    498 << "spectral condition number of a matrix which "
    \n-
    499 << "is assumed to be symmetric." << std::endl;
    \n-
    500
    \n-
    501 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    502 // and to perform the product A*v (LU decomposition is not used)
    \n-
    503 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    504 WrappedMatrix A(m_);
    \n-
    505
    \n-
    506 // get number of rows and columns in A
    \n-
    507 const int nrows = A.nrows();
    \n-
    508 const int ncols = A.ncols();
    \n-
    509
    \n-
    510 // assert that A is square
    \n-
    511 if (nrows != ncols)
    \n-
    512 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n-
    513 << nrows << "x" << ncols << ").");
    \n-
    514
    \n-
    515 // allocate memory for variables, set parameters
    \n-
    516 const int nev = 2; // Number of eigenvalues to compute
    \n-
    517 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    518 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    519 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    520 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n-
    521 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    522 int nconv; // Number of converged eigenvalues
    \n-
    523
    \n-
    524 // define what we need: eigenvalues from both ends of the spectrum
    \n-
    525 char which[] = "BE";
    \n-
    526 ARSymStdEig<Real,WrappedMatrix>
    \n-
    527 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n-
    528
    \n-
    529 // set ARPACK verbosity mode if requested
    \n-
    530 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    531
    \n-
    532 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n-
    533 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    534
    \n-
    535 // obtain approximated dominant and least dominant eigenvalue of A
    \n-
    536 const Real& lambda_max = ev[nev-1];
    \n-
    537 const Real& lambda_min = ev[0];
    \n-
    538
    \n-
    539 // obtain associated approximated eigenvectors of A
    \n-
    540 Real* x_max_raw = dprob.RawEigenvector(nev-1);
    \n-
    541 Real* x_min_raw = dprob.RawEigenvector(0);
    \n-
    542
    \n-
    543 // obtain approximated spectral condition number of A
    \n-
    544 cond_2 = std::abs(lambda_max / lambda_min);
    \n-
    545
    \n-
    546 // obtain number of Arnoldi update iterations actually taken
    \n-
    547 nIterations_ = dprob.GetIter();
    \n-
    548
    \n-
    549 // compute each residual norm
    \n-
    550 Real* Ax_max_raw = new Real[nrows];
    \n-
    551 Real* Ax_min_raw = new Real[nrows];
    \n-
    552 A.multMv(x_max_raw,Ax_max_raw);
    \n-
    553 A.multMv(x_min_raw,Ax_min_raw);
    \n-
    554 Real r_max_norm = 0.0;
    \n-
    555 Real r_min_norm = 0.0;
    \n-
    556 for (int i = 0; i < nrows; ++i)
    \n-
    557 {
    \n-
    558 r_max_norm += std::pow(Ax_max_raw[i] - lambda_max * x_max_raw[i],2);
    \n-
    559 r_min_norm += std::pow(Ax_min_raw[i] - lambda_min * x_min_raw[i],2);
    \n-
    560 }
    \n-
    561 r_max_norm = std::sqrt(r_max_norm);
    \n-
    562 r_min_norm = std::sqrt(r_min_norm);
    \n-
    563
    \n-
    564 // print verbosity information
    \n-
    565 if (verbosity_level_ > 0)
    \n-
    566 {
    \n-
    567 if (verbosity_level_ > 1)
    \n-
    568 {
    \n-
    569 // print some information about the problem
    \n-
    570 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n-
    571 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n-
    572 << "StdEig:" << std::endl;
    \n-
    573 std::cout << blank_ << " converged eigenvalues of A: "
    \n-
    574 << nconv << " / " << nev << std::endl;
    \n-
    575 std::cout << blank_ << " dominant eigenvalue of A: "
    \n-
    576 << lambda_max << std::endl;
    \n-
    577 std::cout << blank_ << " least dominant eigenvalue of A: "
    \n-
    578 << lambda_min << std::endl;
    \n-
    579 std::cout << blank_ << " spectral condition number of A: "
    \n-
    580 << cond_2 << std::endl;
    \n-
    581 }
    \n-
    582 std::cout << blank_ << "Result ("
    \n-
    583 << "#iterations = " << nIterations_ << ", "
    \n-
    584 << "\u2551residual\u2551_2 = {" << r_max_norm << ","
    \n-
    585 << r_min_norm << "}, " << "\u03bb = {"
    \n-
    586 << lambda_max << "," << lambda_min
    \n-
    587 << "}): cond_2 = " << cond_2 << std::endl;
    \n-
    588 }
    \n-
    589
    \n-
    590 // free dynamically allocated memory
    \n-
    591 delete[] Ax_min_raw;
    \n-
    592 delete[] Ax_max_raw;
    \n-
    593 delete[] ev;
    \n-
    594 }
    \n-
    595
    \n-
    609 inline void computeNonSymMax (const Real& epsilon,
    \n-
    610 BlockVector& x, Real& sigma) const
    \n-
    611 {
    \n-
    612 // print verbosity information
    \n-
    613 if (verbosity_level_ > 0)
    \n-
    614 std::cout << title_ << "Computing an approximation of the "
    \n-
    615 << "largest singular value of a matrix which "
    \n-
    616 << "is assumed to be nonsymmetric." << std::endl;
    \n-
    617
    \n-
    618 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    619 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n-
    620 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    621 WrappedMatrix A(m_);
    \n-
    622
    \n-
    623 // get number of rows and columns in A
    \n-
    624 const int nrows = A.nrows();
    \n-
    625 const int ncols = A.ncols();
    \n-
    626
    \n-
    627 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n-
    628 if (nrows < ncols)
    \n-
    629 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n-
    630 << "columns (" << nrows << "x" << ncols << ")."
    \n-
    631 << " This case is not implemented, yet.");
    \n-
    632
    \n-
    633 // allocate memory for variables, set parameters
    \n-
    634 const int nev = 1; // Number of eigenvalues to compute
    \n-
    635 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    636 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    637 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    638 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n-
    639 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    640 int nconv; // Number of converged eigenvalues
    \n-
    641
    \n-
    642 // define what we need: eigenvalues with largest algebraic value
    \n-
    643 char which[] = "LA";
    \n-
    644 ARSymStdEig<Real,WrappedMatrix>
    \n-
    645 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n-
    646
    \n-
    647 // set ARPACK verbosity mode if requested
    \n-
    648 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    649
    \n-
    650 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n-
    651 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    652
    \n-
    653 // obtain approximated largest eigenvalue of A^T*A
    \n-
    654 const Real& lambda = ev[nev-1];
    \n-
    655
    \n-
    656 // obtain associated approximated eigenvector of A^T*A
    \n-
    657 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n-
    658 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n-
    659
    \n-
    660 // obtain number of Arnoldi update iterations actually taken
    \n-
    661 nIterations_ = dprob.GetIter();
    \n-
    662
    \n-
    663 // compute residual norm
    \n-
    664 BlockVector r(x);
    \n-
    665 Real* AtAx_raw = new Real[ncols];
    \n-
    666 A.multMtMv(x_raw,AtAx_raw);
    \n-
    667 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
    \n-
    668 r.axpy(-lambda,x);
    \n-
    669 const Real r_norm = r.two_norm();
    \n-
    670
    \n-
    671 // calculate largest singular value of A (note that
    \n-
    672 // x is right-singular / left-singular vector of A)
    \n-
    673 sigma = std::sqrt(lambda);
    \n-
    674
    \n-
    675 // print verbosity information
    \n-
    676 if (verbosity_level_ > 0)
    \n-
    677 {
    \n-
    678 if (verbosity_level_ > 1)
    \n-
    679 {
    \n-
    680 // print some information about the problem
    \n-
    681 std::cout << blank_ << "Obtained singular values of A by sol"
    \n-
    682 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n-
    683 << "class ARSymStdEig:" << std::endl;
    \n-
    684 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n-
    685 << nconv << " / " << nev << std::endl;
    \n-
    686 std::cout << blank_ << " largest eigenvalue of A^T*A: "
    \n-
    687 << lambda << std::endl;
    \n-
    688 std::cout << blank_ << " => largest singular value of A: "
    \n-
    689 << sigma << std::endl;
    \n-
    690 }
    \n-
    691 std::cout << blank_ << "Result ("
    \n-
    692 << "#iterations = " << nIterations_ << ", "
    \n-
    693 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    694 << "\u03c3 = " << sigma << std::endl;
    \n-
    695 if (verbosity_level_ > 2)
    \n-
    696 {
    \n-
    697 // print approximated right-singular / left-singular vector
    \n-
    698 // via DUNE-ISTL I/O methods
    \n-
    699 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    700 }
    \n-
    701 }
    \n-
    702
    \n-
    703 // free dynamically allocated memory
    \n-
    704 delete[] AtAx_raw;
    \n-
    705 delete[] ev;
    \n-
    706 }
    \n-
    707
    \n-
    721 inline void computeNonSymMin (const Real& epsilon,
    \n-
    722 BlockVector& x, Real& sigma) const
    \n-
    723 {
    \n-
    724 // print verbosity information
    \n-
    725 if (verbosity_level_ > 0)
    \n-
    726 std::cout << title_ << "Computing an approximation of the "
    \n-
    727 << "smallest singular value of a matrix which "
    \n-
    728 << "is assumed to be nonsymmetric." << std::endl;
    \n-
    729
    \n-
    730 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    731 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n-
    732 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    733 WrappedMatrix A(m_);
    \n-
    734
    \n-
    735 // get number of rows and columns in A
    \n-
    736 const int nrows = A.nrows();
    \n-
    737 const int ncols = A.ncols();
    \n-
    738
    \n-
    739 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n-
    740 if (nrows < ncols)
    \n-
    741 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n-
    742 << "columns (" << nrows << "x" << ncols << ")."
    \n-
    743 << " This case is not implemented, yet.");
    \n-
    744
    \n-
    745 // allocate memory for variables, set parameters
    \n-
    746 const int nev = 1; // Number of eigenvalues to compute
    \n-
    747 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    748 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    749 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    750 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n-
    751 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    752 int nconv; // Number of converged eigenvalues
    \n-
    753
    \n-
    754 // define what we need: eigenvalues with smallest algebraic value
    \n-
    755 char which[] = "SA";
    \n-
    756 ARSymStdEig<Real,WrappedMatrix>
    \n-
    757 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n-
    758
    \n-
    759 // set ARPACK verbosity mode if requested
    \n-
    760 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    761
    \n-
    762 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n-
    763 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    764
    \n-
    765 // obtain approximated smallest eigenvalue of A^T*A
    \n-
    766 const Real& lambda = ev[nev-1];
    \n-
    767
    \n-
    768 // obtain associated approximated eigenvector of A^T*A
    \n-
    769 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n-
    770 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n-
    771
    \n-
    772 // obtain number of Arnoldi update iterations actually taken
    \n-
    773 nIterations_ = dprob.GetIter();
    \n-
    774
    \n-
    775 // compute residual norm
    \n-
    776 BlockVector r(x);
    \n-
    777 Real* AtAx_raw = new Real[ncols];
    \n-
    778 A.multMtMv(x_raw,AtAx_raw);
    \n-
    779 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
    \n-
    780 r.axpy(-lambda,x);
    \n-
    781 const Real r_norm = r.two_norm();
    \n-
    782
    \n-
    783 // calculate smallest singular value of A (note that
    \n-
    784 // x is right-singular / left-singular vector of A)
    \n-
    785 sigma = std::sqrt(lambda);
    \n-
    786
    \n-
    787 // print verbosity information
    \n-
    788 if (verbosity_level_ > 0)
    \n-
    789 {
    \n-
    790 if (verbosity_level_ > 1)
    \n-
    791 {
    \n-
    792 // print some information about the problem
    \n-
    793 std::cout << blank_ << "Obtained singular values of A by sol"
    \n-
    794 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n-
    795 << "class ARSymStdEig:" << std::endl;
    \n-
    796 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n-
    797 << nconv << " / " << nev << std::endl;
    \n-
    798 std::cout << blank_ << " smallest eigenvalue of A^T*A: "
    \n-
    799 << lambda << std::endl;
    \n-
    800 std::cout << blank_ << " => smallest singular value of A: "
    \n-
    801 << sigma << std::endl;
    \n-
    802 }
    \n-
    803 std::cout << blank_ << "Result ("
    \n-
    804 << "#iterations = " << nIterations_ << ", "
    \n-
    805 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n-
    806 << "\u03c3 = " << sigma << std::endl;
    \n-
    807 if (verbosity_level_ > 2)
    \n-
    808 {
    \n-
    809 // print approximated right-singular / left-singular vector
    \n-
    810 // via DUNE-ISTL I/O methods
    \n-
    811 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n-
    812 }
    \n-
    813 }
    \n-
    814
    \n-
    815 // free dynamically allocated memory
    \n-
    816 delete[] AtAx_raw;
    \n-
    817 delete[] ev;
    \n-
    818 }
    \n-
    819
    \n-
    830 inline void computeNonSymCond2 (const Real& epsilon, Real& cond_2) const
    \n-
    831 {
    \n-
    832 // print verbosity information
    \n-
    833 if (verbosity_level_ > 0)
    \n-
    834 std::cout << title_ << "Computing an approximation of the "
    \n-
    835 << "spectral condition number of a matrix which "
    \n-
    836 << "is assumed to be nonsymmetric." << std::endl;
    \n-
    837
    \n-
    838 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n-
    839 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n-
    840 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n-
    841 WrappedMatrix A(m_);
    \n-
    842
    \n-
    843 // get number of rows and columns in A
    \n-
    844 const int nrows = A.nrows();
    \n-
    845 const int ncols = A.ncols();
    \n-
    846
    \n-
    847 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n-
    848 if (nrows < ncols)
    \n-
    849 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n-
    850 << "columns (" << nrows << "x" << ncols << ")."
    \n-
    851 << " This case is not implemented, yet.");
    \n-
    852
    \n-
    853 // allocate memory for variables, set parameters
    \n-
    854 const int nev = 2; // Number of eigenvalues to compute
    \n-
    855 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n-
    856 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n-
    857 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n-
    858 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n-
    859 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n-
    860 int nconv; // Number of converged eigenvalues
    \n-
    861
    \n-
    862 // define what we need: eigenvalues from both ends of the spectrum
    \n-
    863 char which[] = "BE";
    \n-
    864 ARSymStdEig<Real,WrappedMatrix>
    \n-
    865 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n-
    866
    \n-
    867 // set ARPACK verbosity mode if requested
    \n-
    868 if (verbosity_level_ > 3) dprob.Trace();
    \n-
    869
    \n-
    870 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n-
    871 nconv = dprob.Eigenvalues(ev,ivec);
    \n-
    872
    \n-
    873 // obtain approximated largest and smallest eigenvalue of A^T*A
    \n-
    874 const Real& lambda_max = ev[nev-1];
    \n-
    875 const Real& lambda_min = ev[0];
    \n-
    876
    \n-
    877 // obtain associated approximated eigenvectors of A^T*A
    \n-
    878 Real* x_max_raw = dprob.RawEigenvector(nev-1);
    \n-
    879 Real* x_min_raw = dprob.RawEigenvector(0);
    \n-
    880
    \n-
    881 // obtain number of Arnoldi update iterations actually taken
    \n-
    882 nIterations_ = dprob.GetIter();
    \n-
    883
    \n-
    884 // compute each residual norm
    \n-
    885 Real* AtAx_max_raw = new Real[ncols];
    \n-
    886 Real* AtAx_min_raw = new Real[ncols];
    \n-
    887 A.multMtMv(x_max_raw,AtAx_max_raw);
    \n-
    888 A.multMtMv(x_min_raw,AtAx_min_raw);
    \n-
    889 Real r_max_norm = 0.0;
    \n-
    890 Real r_min_norm = 0.0;
    \n-
    891 for (int i = 0; i < ncols; ++i)
    \n-
    892 {
    \n-
    893 r_max_norm += std::pow(AtAx_max_raw[i] - lambda_max * x_max_raw[i],2);
    \n-
    894 r_min_norm += std::pow(AtAx_min_raw[i] - lambda_min * x_min_raw[i],2);
    \n-
    895 }
    \n-
    896 r_max_norm = std::sqrt(r_max_norm);
    \n-
    897 r_min_norm = std::sqrt(r_min_norm);
    \n-
    898
    \n-
    899 // calculate largest and smallest singular value of A
    \n-
    900 const Real sigma_max = std::sqrt(lambda_max);
    \n-
    901 const Real sigma_min = std::sqrt(lambda_min);
    \n-
    902
    \n-
    903 // obtain approximated spectral condition number of A
    \n-
    904 cond_2 = sigma_max / sigma_min;
    \n-
    905
    \n-
    906 // print verbosity information
    \n-
    907 if (verbosity_level_ > 0)
    \n-
    908 {
    \n-
    909 if (verbosity_level_ > 1)
    \n-
    910 {
    \n-
    911 // print some information about the problem
    \n-
    912 std::cout << blank_ << "Obtained singular values of A by sol"
    \n-
    913 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n-
    914 << "class ARSymStdEig:" << std::endl;
    \n-
    915 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n-
    916 << nconv << " / " << nev << std::endl;
    \n-
    917 std::cout << blank_ << " largest eigenvalue of A^T*A: "
    \n-
    918 << lambda_max << std::endl;
    \n-
    919 std::cout << blank_ << " smallest eigenvalue of A^T*A: "
    \n-
    920 << lambda_min << std::endl;
    \n-
    921 std::cout << blank_ << " => largest singular value of A: "
    \n-
    922 << sigma_max << std::endl;
    \n-
    923 std::cout << blank_ << " => smallest singular value of A: "
    \n-
    924 << sigma_min << std::endl;
    \n-
    925 }
    \n-
    926 std::cout << blank_ << "Result ("
    \n-
    927 << "#iterations = " << nIterations_ << ", "
    \n-
    928 << "\u2551residual\u2551_2 = {" << r_max_norm << ","
    \n-
    929 << r_min_norm << "}, " << "\u03c3 = {"
    \n-
    930 << sigma_max << "," << sigma_min
    \n-
    931 << "}): cond_2 = " << cond_2 << std::endl;
    \n-
    932 }
    \n-
    933
    \n-
    934 // free dynamically allocated memory
    \n-
    935 delete[] AtAx_min_raw;
    \n-
    936 delete[] AtAx_max_raw;
    \n-
    937 delete[] ev;
    \n-
    938 }
    \n-
    939
    \n-
    944 inline unsigned int getIterationCount () const
    \n-
    945 {
    \n-
    946 if (nIterations_ == 0)
    \n-
    947 DUNE_THROW(Dune::ISTLError,"No algorithm applied, yet.");
    \n-
    948
    \n-
    949 return nIterations_;
    \n-
    950 }
    \n-
    951
    \n-
    952 protected:
    \n-
    953 // parameters related to iterative eigenvalue algorithms
    \n-\n-
    955 const unsigned int nIterationsMax_;
    \n-
    956
    \n-
    957 // verbosity setting
    \n-
    958 const unsigned int verbosity_level_;
    \n-
    959
    \n-
    960 // memory for storing temporary variables (mutable as they shall
    \n-
    961 // just be effectless auxiliary variables of the const apply*(...)
    \n-
    962 // methods)
    \n-
    963 mutable unsigned int nIterations_;
    \n-
    964
    \n-
    965 // constants for printing verbosity information
    \n-
    966 const std::string title_;
    \n-
    967 const std::string blank_;
    \n-
    968 };
    \n-
    969
    \n-
    972} // namespace Dune
    \n-
    973
    \n-
    974#endif // HAVE_ARPACKPP
    \n-
    975
    \n-
    976#endif // DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n-
    Some generic functions for pretty printing vectors and matrices.
    \n-
    void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
    Print an ISTL vector.
    Definition: io.hh:89
    \n+
    149 for (MM::iterator iter = bordercontribution.begin();
    \n+
    150 iter != bordercontribution.end(); ++iter)
    \n+
    151 bordercontribution.erase(iter);
    \n+
    152 std::map<int,int> owner; //key: local index i, value: process, that owns i
    \n+
    153 RIMap rimap;
    \n+
    154
    \n+
    155 // for each local index make multimap rimap:
    \n+
    156 // key: local index i, data: pair of process that knows i and pointer to RI entry
    \n+
    157 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i)
    \n+
    158 if (mask[i.index()] == 0)
    \n+
    159 for (RIIterator remote = ri.begin(); remote != ri.end(); ++remote) {
    \n+
    160 RIL& ril = *(remote->second.first);
    \n+
    161 for (RILIterator rindex = ril.begin(); rindex != ril.end(); ++rindex)
    \n+
    162 if (rindex->attribute() != OwnerOverlapCopyAttributeSet::overlap)
    \n+
    163 if (rindex->localIndexPair().local().local() == i.index()) {
    \n+
    164 rimap.insert
    \n+
    165 (std::make_pair(i.index(),
    \n+
    166 std::pair<int,RILIterator>(remote->first, rindex)));
    \n+
    167 if(rindex->attribute()==OwnerOverlapCopyAttributeSet::owner)
    \n+
    168 owner.insert(std::make_pair(i.index(),remote->first));
    \n+
    169 }
    \n+
    170 }
    \n+
    171
    \n+
    172 int iowner = 0;
    \n+
    173 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {
    \n+
    174 if (mask[i.index()] == 0) {
    \n+
    175 std::map<int,int>::iterator it = owner.find(i.index());
    \n+
    176 iowner = it->second;
    \n+
    177 std::pair<RIMapit, RIMapit> foundiit = rimap.equal_range(i.index());
    \n+
    178 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j) {
    \n+
    179 if (mask[j.index()] == 0) {
    \n+
    180 bool flag = true;
    \n+
    181 for (RIMapit foundi = foundiit.first; foundi != foundiit.second; ++foundi) {
    \n+
    182 std::pair<RIMapit, RIMapit> foundjit = rimap.equal_range(j.index());
    \n+
    183 for (RIMapit foundj = foundjit.first; foundj != foundjit.second; ++foundj)
    \n+
    184 if (foundj->second.first == foundi->second.first)
    \n+
    185 if (foundj->second.second->attribute() == OwnerOverlapCopyAttributeSet::owner
    \n+
    186 || foundj->second.first == iowner
    \n+
    187 || foundj->second.first < communication.communicator().rank()) {
    \n+
    188 flag = false;
    \n+
    189 continue;
    \n+
    190 }
    \n+
    191 if (flag == false)
    \n+
    192 continue;
    \n+
    193 }
    \n+
    194 // don\u00b4t contribute to Ax if
    \n+
    195 // 1. the owner of j has i as interior/border dof
    \n+
    196 // 2. iowner has j as interior/border dof
    \n+
    197 // 3. there is another process with smaller rank that has i and j
    \n+
    198 // as interor/border dofs
    \n+
    199 // if the owner of j does not have i as interior/border dof,
    \n+
    200 // it will not be taken into account
    \n+
    201 if (flag==true)
    \n+
    202 bordercontribution.insert(std::pair<int,int>(i.index(),j.index()));
    \n+
    203 }
    \n+
    204 }
    \n+
    205 }
    \n+
    206 }
    \n+
    207 buildcomm = false;
    \n+
    208 }
    \n+
    209
    \n+
    210 //compute alpha*A*x nonoverlapping case
    \n+
    211 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {
    \n+
    212 if (mask[i.index()] == 0) {
    \n+
    213 //dof doesn't belong to process but is border (not ghost)
    \n+
    214 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j) {
    \n+
    215 if (mask[j.index()] == 1) //j is owner => then sum entries
    \n+
    216 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n+
    217 else if (mask[j.index()] == 0) {
    \n+
    218 std::pair<MM::iterator, MM::iterator> itp =
    \n+
    219 bordercontribution.equal_range(i.index());
    \n+
    220 for (MM::iterator it = itp.first; it != itp.second; ++it)
    \n+
    221 if ((*it).second == (int)j.index())
    \n+
    222 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n+
    223 }
    \n+
    224 }
    \n+
    225 }
    \n+
    226 else if (mask[i.index()] == 1) {
    \n+
    227 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j)
    \n+
    228 if (mask[j.index()] != 2)
    \n+
    229 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n+
    230 }
    \n+
    231 }
    \n+
    232 }
    \n+
    233
    \n+\n+
    236 {
    \n+\n+
    238 }
    \n+
    239
    \n+\n+
    242 {
    \n+
    243 return communication;
    \n+
    244 }
    \n+
    245 private:
    \n+
    246 std::shared_ptr<const matrix_type> _A_;
    \n+
    247 const communication_type& communication;
    \n+
    248 mutable bool buildcomm;
    \n+
    249 mutable std::vector<double> mask;
    \n+
    250 mutable std::multimap<int,int> bordercontribution;
    \n+
    251 };
    \n+
    252
    \n+
    255 namespace Amg
    \n+
    256 {
    \n+
    257 template<class T> struct ConstructionTraits;
    \n+
    258 }
    \n+
    259
    \n+
    274 template<class C, class P>
    \n+\n+
    276 : public Preconditioner<typename P::domain_type,typename P::range_type> {
    \n+\n+
    278 using X = typename P::domain_type;
    \n+
    279 using Y = typename P::range_type;
    \n+
    280 public:
    \n+
    282 typedef typename P::domain_type domain_type;
    \n+
    284 typedef typename P::range_type range_type;
    \n+\n+
    287
    \n+\n+
    303 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)
    \n+
    304 { }
    \n+
    305
    \n+
    313 NonoverlappingBlockPreconditioner (const std::shared_ptr<P>& p, const communication_type& c)
    \n+
    314 : _preconditioner(p), _communication(c)
    \n+
    315 { }
    \n+
    316
    \n+
    322 virtual void pre (domain_type& x, range_type& b)
    \n+
    323 {
    \n+
    324 _preconditioner->pre(x,b);
    \n+
    325 }
    \n+
    326
    \n+
    332 virtual void apply (domain_type& v, const range_type& d)
    \n+
    333 {
    \n+
    334 // block preconditioner equivalent to WrappedPreconditioner from
    \n+
    335 // pdelab/backend/ovlpistsolverbackend.hh,
    \n+
    336 // but not to BlockPreconditioner from schwarz.hh
    \n+
    337 _preconditioner->apply(v,d);
    \n+
    338 _communication.addOwnerCopyToOwnerCopy(v,v);
    \n+
    339 }
    \n+
    340
    \n+
    341 template<bool forward>
    \n+
    342 void apply (X& v, const Y& d)
    \n+
    343 {
    \n+
    344 _preconditioner->template apply<forward>(v,d);
    \n+
    345 _communication.addOwnerCopyToOwnerCopy(v,v);
    \n+
    346 }
    \n+
    347
    \n+
    353 virtual void post (domain_type& x)
    \n+
    354 {
    \n+
    355 _preconditioner->post(x);
    \n+
    356 }
    \n+
    357
    \n+\n+
    360 {
    \n+\n+
    362 }
    \n+
    363
    \n+
    364 private:
    \n+
    366 std::shared_ptr<P> _preconditioner;
    \n+
    367
    \n+
    369 const communication_type& _communication;
    \n+
    370 };
    \n+
    371
    \n+
    374} // end namespace
    \n+
    375
    \n+
    376#endif
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n+\n+
    Define base class for scalar product and norm.
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+
    Implementations of the inverse operator interface.
    \n+
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    The incomplete LU factorization kernels.
    \n+
    Define general preconditioner interface.
    \n
    Definition: allocator.hh:11
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bcrsmatrix.hh:488
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n-
    A::size_type size_type
    The type for the index access.
    Definition: bvector.hh:410
    \n-
    Wrapper to use a range of ARPACK++ eigenvalue solvers.
    Definition: arpackpp.hh:245
    \n-
    const unsigned int verbosity_level_
    Definition: arpackpp.hh:958
    \n-
    unsigned int getIterationCount() const
    Return the number of iterations in last application of an algorithm.
    Definition: arpackpp.hh:944
    \n-
    const std::string title_
    Definition: arpackpp.hh:966
    \n-
    BlockVector::field_type Real
    Definition: arpackpp.hh:247
    \n-
    void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:289
    \n-
    void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:391
    \n-
    const BCRSMatrix & m_
    Definition: arpackpp.hh:954
    \n-
    const unsigned int nIterationsMax_
    Definition: arpackpp.hh:955
    \n-
    const std::string blank_
    Definition: arpackpp.hh:967
    \n-
    ArPackPlusPlus_Algorithms(const BCRSMatrix &m, const unsigned int nIterationsMax=100000, const unsigned int verbosity_level=0)
    Construct from required parameters.
    Definition: arpackpp.hh:268
    \n-
    void computeSymCond2(const Real &epsilon, Real &cond_2) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation of its spectra...
    Definition: arpackpp.hh:493
    \n-
    unsigned int nIterations_
    Definition: arpackpp.hh:963
    \n-
    void computeNonSymMin(const Real &epsilon, BlockVector &x, Real &sigma) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its smalle...
    Definition: arpackpp.hh:721
    \n-
    void computeNonSymCond2(const Real &epsilon, Real &cond_2) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation of its spectral con...
    Definition: arpackpp.hh:830
    \n-
    void computeNonSymMax(const Real &epsilon, BlockVector &x, Real &sigma) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its larges...
    Definition: arpackpp.hh:609
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n+
    C::PIS PIS
    Definition: novlpschwarz.hh:74
    \n+
    C communication_type
    The type of the communication object.
    Definition: novlpschwarz.hh:72
    \n+
    std::multimap< int, std::pair< int, RILIterator > > RIMap
    Definition: novlpschwarz.hh:82
    \n+
    C::RI RI
    Definition: novlpschwarz.hh:75
    \n+
    void novlp_op_apply(const X &x, Y &y, field_type alpha) const
    Definition: novlpschwarz.hh:126
    \n+
    NonoverlappingSchwarzOperator(std::shared_ptr< const matrix_type > A, const communication_type &com)
    Definition: novlpschwarz.hh:96
    \n+
    M::ConstColIterator ColIterator
    Definition: novlpschwarz.hh:79
    \n+
    virtual void apply(const X &x, Y &y) const
    apply operator to x:
    Definition: novlpschwarz.hh:101
    \n+
    X domain_type
    The type of the domain.
    Definition: novlpschwarz.hh:66
    \n+
    virtual SolverCategory::Category category() const
    Category of the linear operator (see SolverCategory::Category)
    Definition: novlpschwarz.hh:235
    \n+
    RIMap::iterator RIMapit
    Definition: novlpschwarz.hh:83
    \n+
    virtual const matrix_type & getmat() const
    get matrix via *
    Definition: novlpschwarz.hh:121
    \n+
    RIL::const_iterator RILIterator
    Definition: novlpschwarz.hh:78
    \n+
    std::multimap< int, int > MM
    Definition: novlpschwarz.hh:81
    \n+
    Y range_type
    The type of the range.
    Definition: novlpschwarz.hh:68
    \n+
    M matrix_type
    The type of the matrix we operate on.
    Definition: novlpschwarz.hh:64
    \n+
    M::ConstRowIterator RowIterator
    Definition: novlpschwarz.hh:80
    \n+
    const communication_type & getCommunication() const
    Get the object responsible for communication.
    Definition: novlpschwarz.hh:241
    \n+
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const
    apply operator to x, scale and add:
    Definition: novlpschwarz.hh:109
    \n+
    RI::RemoteIndexList RIL
    Definition: novlpschwarz.hh:76
    \n+
    X::field_type field_type
    The field type of the range.
    Definition: novlpschwarz.hh:70
    \n+
    NonoverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)
    constructor: just store a reference to a matrix.
    Definition: novlpschwarz.hh:92
    \n+
    RI::const_iterator RIIterator
    Definition: novlpschwarz.hh:77
    \n+
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n+
    Nonoverlapping parallel preconditioner.
    Definition: novlpschwarz.hh:276
    \n+
    NonoverlappingBlockPreconditioner(P &p, const communication_type &c)
    Constructor.
    Definition: novlpschwarz.hh:302
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: novlpschwarz.hh:359
    \n+
    virtual void apply(domain_type &v, const range_type &d)
    Apply the preconditioner.
    Definition: novlpschwarz.hh:332
    \n+
    P::range_type range_type
    The range type of the preconditioner.
    Definition: novlpschwarz.hh:284
    \n+
    NonoverlappingBlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)
    Constructor.
    Definition: novlpschwarz.hh:313
    \n+
    virtual void post(domain_type &x)
    Clean up.
    Definition: novlpschwarz.hh:353
    \n+
    C communication_type
    The type of the communication object.
    Definition: novlpschwarz.hh:286
    \n+
    virtual void pre(domain_type &x, range_type &b)
    Prepare the preconditioner.
    Definition: novlpschwarz.hh:322
    \n+
    void apply(X &v, const Y &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: novlpschwarz.hh:342
    \n+
    P::domain_type domain_type
    The domain type of the preconditioner.
    Definition: novlpschwarz.hh:282
    \n+
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n+
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n+
    @ copy
    Definition: owneroverlapcopy.hh:61
    \n+
    @ overlap
    Definition: owneroverlapcopy.hh:61
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,956 +4,479 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * eigenvalue\n-arpackpp.hh\n+novlpschwarz.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n- 6#define DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n+ 5#ifndef DUNE_ISTL_NOVLPSCHWARZ_HH\n+ 6#define DUNE_ISTL_NOVLPSCHWARZ_HH\n 7\n- 8#if HAVE_ARPACKPP || defined DOXYGEN\n- 9\n- 10#include // provides std::abs, std::pow, std::sqrt\n- 11\n- 12#include // provides std::cout, std::endl\n- 13#include // provides std::string\n+ 8#include // for input/output to shell\n+ 9#include // for input/output to files\n+ 10#include // STL vector class\n+ 11#include \n+ 12\n+ 13#include // Yes, we do some math here\n 14\n- 15#include // provides Dune::FieldVector\n- 16#include // provides DUNE_THROW(...)\n- 17\n- 18#include // provides Dune::blockLevel\n- 19#include // provides Dune::BlockVector\n- 20#include // provides Dune::ISTLError\n- 21#include // provides Dune::printvector(...)\n- 22\n- 23#ifdef Status\n- 24#undef Status // prevent preprocessor from damaging the ARPACK++\n- 25 // code when \"X11/Xlib.h\" is included (the latter\n- 26 // defines Status as \"#define Status int\" and\n- 27 // ARPACK++ provides a class with a method called\n- 28 // Status)\n- 29#endif\n- 30#include \"arssym.h\" // provides ARSymStdEig\n+ 15#include \n+ 16\n+ 17#include \n+ 18\n+ 19#include \"io.hh\"\n+ 20#include \"bvector.hh\"\n+ 21#include \"vbvector.hh\"\n+ 22#include \"bcrsmatrix.hh\"\n+ 23#include \"io.hh\"\n+ 24#include \"gsetc.hh\"\n+ 25#include \"ilu.hh\"\n+ 26#include \"operators.hh\"\n+ 27#include \"solvers.hh\"\n+ 28#include \"preconditioners.hh\"\n+ 29#include \"scalarproducts.hh\"\n+ 30#include \"owneroverlapcopy.hh\"\n 31\n- 32namespace Dune\n- 33{\n- 34\n- 39 namespace Impl {\n- 55 template \n- 56 class ArPackPlusPlus_BCRSMatrixWrapper\n- 57 {\n- 58 public:\n- 60 typedef typename BCRSMatrix::field_type Real;\n- 61\n+ 32namespace Dune {\n+ 33\n+ 59 template\n+60 class NonoverlappingSchwarzOperator : public AssembledLinearOperator\n+ 61 {\n 62 public:\n- 64 ArPackPlusPlus_BCRSMatrixWrapper (const BCRSMatrix& A)\n- 65 : A_(A),\n- 66 m_(A_.M() * mBlock), n_(A_.N() * nBlock)\n- 67 {\n- 68 // assert that BCRSMatrix type has blocklevel 2\n- 69 static_assert\n- 70 (blockLevel() == 2,\n- 71 \"Only BCRSMatrices with blocklevel 2 are supported.\");\n- 72\n- 73 // allocate memory for auxiliary block vector objects\n- 74 // which are compatible to matrix rows / columns\n- 75 domainBlockVector.resize(A_.N());\n- 76 rangeBlockVector.resize(A_.M());\n- 77 }\n- 78\n- 80 inline void multMv (Real* v, Real* w)\n- 81 {\n- 82 // get vector v as an object of appropriate type\n- 83 arrayToDomainBlockVector(v,domainBlockVector);\n+64 typedef M matrix_type;\n+66 typedef X domain_type;\n+68 typedef Y range_type;\n+70 typedef typename X::field_type field_type;\n+72 typedef C communication_type;\n+ 73\n+74 typedef typename C::PIS PIS;\n+75 typedef typename C::RI RI;\n+76 typedef typename RI::RemoteIndexList RIL;\n+77 typedef typename RI::const_iterator RIIterator;\n+78 typedef typename RIL::const_iterator RILIterator;\n+79 typedef typename M::ConstColIterator ColIterator;\n+80 typedef typename M::ConstRowIterator RowIterator;\n+81 typedef std::multimap MM;\n+82 typedef std::multimap > RIMap;\n+83 typedef typename RIMap::iterator RIMapit;\n 84\n- 85 // perform matrix-vector product\n- 86 A_.mv(domainBlockVector,rangeBlockVector);\n- 87\n- 88 // get vector w from object of appropriate type\n- 89 rangeBlockVectorToArray(rangeBlockVector,w);\n- 90 };\n- 91\n- 93 inline void multMtMv (Real* v, Real* w)\n- 94 {\n- 95 // get vector v as an object of appropriate type\n- 96 arrayToDomainBlockVector(v,domainBlockVector);\n- 97\n- 98 // perform matrix-vector product\n- 99 A_.mv(domainBlockVector,rangeBlockVector);\n- 100 A_.mtv(rangeBlockVector,domainBlockVector);\n- 101\n- 102 // get vector w from object of appropriate type\n- 103 domainBlockVectorToArray(domainBlockVector,w);\n- 104 };\n- 105\n- 107 inline void multMMtv (Real* v, Real* w)\n- 108 {\n- 109 // get vector v as an object of appropriate type\n- 110 arrayToRangeBlockVector(v,rangeBlockVector);\n- 111\n- 112 // perform matrix-vector product\n- 113 A_.mtv(rangeBlockVector,domainBlockVector);\n- 114 A_.mv(domainBlockVector,rangeBlockVector);\n- 115\n- 116 // get vector w from object of appropriate type\n- 117 rangeBlockVectorToArray(rangeBlockVector,w);\n- 118 };\n+92 NonoverlappingSchwarzOperator (const matrix_type& A, const\n+communication_type& com)\n+ 93 : _A_(stackobject_to_shared_ptr(A)), communication(com), buildcomm(true)\n+ 94 {}\n+ 95\n+96 NonoverlappingSchwarzOperator (std::shared_ptr A, const\n+communication_type& com)\n+ 97 : _A_(A), communication(com), buildcomm(true)\n+ 98 {}\n+ 99\n+101 virtual void apply (const X& x, Y& y) const\n+ 102 {\n+ 103 y = 0;\n+ 104 novlp_op_apply(x,y,1);\n+ 105 communication.addOwnerCopyToOwnerCopy(y,y);\n+ 106 }\n+ 107\n+109 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n+ 110 {\n+ 111 // only apply communication to alpha*A*x to make it consistent,\n+ 112 // y already has to be consistent.\n+ 113 Y y1(y);\n+ 114 y = 0;\n+ 115 novlp_op_apply(x,y,alpha);\n+ 116 communication.addOwnerCopyToOwnerCopy(y,y);\n+ 117 y += y1;\n+ 118 }\n 119\n- 121 inline int nrows () const { return m_; }\n- 122\n- 124 inline int ncols () const { return n_; }\n+121 virtual const matrix_type& getmat () const\n+ 122 {\n+ 123 return *_A_;\n+ 124 }\n 125\n- 126 protected:\n- 127 // Number of rows and columns in each block of the matrix\n- 128 constexpr static int mBlock = BCRSMatrix::block_type::rows;\n- 129 constexpr static int nBlock = BCRSMatrix::block_type::cols;\n- 130\n- 131 // Type of vectors in the domain of the linear map associated with\n- 132 // the matrix, i.e. block vectors compatible to matrix rows\n- 133 constexpr static int dbvBlockSize = nBlock;\n- 134 typedef Dune::FieldVector DomainBlockVectorBlock;\n- 135 typedef Dune::BlockVector DomainBlockVector;\n+126 void novlp_op_apply (const X& x, Y& y, field_type alpha) const\n+ 127 {\n+ 128 //get index sets\n+ 129 const PIS& pis=communication.indexSet();\n+ 130 const RI& ri = communication.remoteIndices();\n+ 131\n+ 132 // at the beginning make a multimap \"bordercontribution\".\n+ 133 // process has i and j as border dofs but is not the owner\n+ 134 // => only contribute to Ax if i,j is in bordercontribution\n+ 135 if (buildcomm == true) {\n 136\n- 137 // Type of vectors in the range of the linear map associated with\n- 138 // the matrix, i.e. block vectors compatible to matrix columns\n- 139 constexpr static int rbvBlockSize = mBlock;\n- 140 typedef Dune::FieldVector RangeBlockVectorBlock;\n- 141 typedef Dune::BlockVector RangeBlockVector;\n- 142\n- 143 // Types for vector index access\n- 144 typedef typename DomainBlockVector::size_type dbv_size_type;\n- 145 typedef typename RangeBlockVector::size_type rbv_size_type;\n- 146 typedef typename DomainBlockVectorBlock::size_type dbvb_size_type;\n- 147 typedef typename RangeBlockVectorBlock::size_type rbvb_size_type;\n+ 137 // set up mask vector\n+ 138 if (mask.size()!=static_cast::size_type>\n+(x.size())) {\n+ 139 mask.resize(x.size());\n+ 140 for (typename std::vector::size_type i=0; ilocal().attribute()==OwnerOverlapCopyAttributeSet::copy)\n+ 144 mask[i->local().local()] = 0;\n+ 145 else if (i->local().attribute()==OwnerOverlapCopyAttributeSet::overlap)\n+ 146 mask[i->local().local()] = 2;\n+ 147 }\n 148\n- 149 // Get vector v from a block vector object which is compatible to\n- 150 // matrix rows\n- 151 static inline void\n- 152 domainBlockVectorToArray (const DomainBlockVector& dbv, Real* v)\n- 153 {\n- 154 for (dbv_size_type block = 0; block < dbv.N(); ++block)\n- 155 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)\n- 156 v[block*dbvBlockSize + iBlock] = dbv[block][iBlock];\n- 157 }\n- 158\n- 159 // Get vector v from a block vector object which is compatible to\n- 160 // matrix columns\n- 161 static inline void\n- 162 rangeBlockVectorToArray (const RangeBlockVector& rbv, Real* v)\n- 163 {\n- 164 for (rbv_size_type block = 0; block < rbv.N(); ++block)\n- 165 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)\n- 166 v[block*rbvBlockSize + iBlock] = rbv[block][iBlock];\n- 167 }\n- 168\n- 169 public:\n- 172 static inline void arrayToDomainBlockVector (const Real* v,\n- 173 DomainBlockVector& dbv)\n- 174 {\n- 175 for (dbv_size_type block = 0; block < dbv.N(); ++block)\n- 176 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)\n- 177 dbv[block][iBlock] = v[block*dbvBlockSize + iBlock];\n- 178 }\n- 179\n- 182 static inline void arrayToRangeBlockVector (const Real* v,\n- 183 RangeBlockVector& rbv)\n- 184 {\n- 185 for (rbv_size_type block = 0; block < rbv.N(); ++block)\n- 186 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)\n- 187 rbv[block][iBlock] = v[block*rbvBlockSize + iBlock];\n- 188 }\n- 189\n- 190 protected:\n- 191 // The DUNE-ISTL BCRSMatrix\n- 192 const BCRSMatrix& A_;\n- 193\n- 194 // Number of rows and columns in the matrix\n- 195 const int m_, n_;\n- 196\n- 197 // Auxiliary block vector objects which are\n- 198 // compatible to matrix rows / columns\n- 199 mutable DomainBlockVector domainBlockVector;\n- 200 mutable RangeBlockVector rangeBlockVector;\n- 201 };\n- 202 } // end namespace Impl\n- 203\n- 243 template \n-244 class ArPackPlusPlus_Algorithms\n- 245 {\n- 246 public:\n-247 typedef typename BlockVector::field_type Real;\n- 248\n- 249 public:\n-268 ArPackPlusPlus_Algorithms (const BCRSMatrix& m,\n- 269 const unsigned int nIterationsMax = 100000,\n- 270 const unsigned int verbosity_level = 0)\n- 271 : m_(m), nIterationsMax_(nIterationsMax),\n- 272 verbosity_level_(verbosity_level),\n- 273 nIterations_(0),\n- 274 title_(\" ArPackPlusPlus_Algorithms: \"),\n- 275 blank_(title_.length(),' ')\n- 276 {}\n- 277\n-289 inline void computeSymMaxMagnitude (const Real& epsilon,\n- 290 BlockVector& x, Real& lambda) const\n- 291 {\n- 292 // print verbosity information\n- 293 if (verbosity_level_ > 0)\n- 294 std::cout << title_ << \"Computing an approximation of \"\n- 295 << \"the dominant eigenvalue of a matrix which \"\n- 296 << \"is assumed to be symmetric.\" << std::endl;\n- 297\n- 298 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 299 // and to perform the product A*v (LU decomposition is not used)\n- 300 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 301 WrappedMatrix A(m_);\n- 302\n- 303 // get number of rows and columns in A\n- 304 const int nrows = A.nrows();\n- 305 const int ncols = A.ncols();\n- 306\n- 307 // assert that A is square\n- 308 if (nrows != ncols)\n- 309 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n- 310 << nrows << \"x\" << ncols << \").\");\n- 311\n- 312 // allocate memory for variables, set parameters\n- 313 const int nev = 1; // Number of eigenvalues to compute\n- 314 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 315 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 316 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 317 Real* ev = new Real[nev]; // Computed eigenvalues of A\n- 318 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 319 int nconv; // Number of converged eigenvalues\n- 320\n- 321 // define what we need: eigenvalues with largest magnitude\n- 322 char which[] = \"LM\";\n- 323 ARSymStdEig\n- 324 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n- 325\n- 326 // set ARPACK verbosity mode if requested\n- 327 if (verbosity_level_ > 3) dprob.Trace();\n- 328\n- 329 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n- 330 nconv = dprob.Eigenvalues(ev,ivec);\n- 331\n- 332 // obtain approximated dominant eigenvalue of A\n- 333 lambda = ev[nev-1];\n- 334\n- 335 // obtain associated approximated eigenvector of A\n- 336 Real* x_raw = dprob.RawEigenvector(nev-1);\n- 337 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n- 338\n- 339 // obtain number of Arnoldi update iterations actually taken\n- 340 nIterations_ = dprob.GetIter();\n- 341\n- 342 // compute residual norm\n- 343 BlockVector r(x);\n- 344 Real* Ax_raw = new Real[nrows];\n- 345 A.multMv(x_raw,Ax_raw);\n- 346 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);\n- 347 r.axpy(-lambda,x);\n- 348 const Real r_norm = r.two_norm();\n- 349\n- 350 // print verbosity information\n- 351 if (verbosity_level_ > 0)\n- 352 {\n- 353 if (verbosity_level_ > 1)\n+ 149 for (MM::iterator iter = bordercontribution.begin();\n+ 150 iter != bordercontribution.end(); ++iter)\n+ 151 bordercontribution.erase(iter);\n+ 152 std::map owner; //key: local index i, value: process, that owns i\n+ 153 RIMap rimap;\n+ 154\n+ 155 // for each local index make multimap rimap:\n+ 156 // key: local index i, data: pair of process that knows i and pointer to\n+RI entry\n+ 157 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i)\n+ 158 if (mask[i.index()] == 0)\n+ 159 for (RIIterator remote = ri.begin(); remote != ri.end(); ++remote) {\n+ 160 RIL& ril = *(remote->second.first);\n+ 161 for (RILIterator rindex = ril.begin(); rindex != ril.end(); ++rindex)\n+ 162 if (rindex->attribute() != OwnerOverlapCopyAttributeSet::overlap)\n+ 163 if (rindex->localIndexPair().local().local() == i.index()) {\n+ 164 rimap.insert\n+ 165 (std::make_pair(i.index(),\n+ 166 std::pair(remote->first, rindex)));\n+ 167 if(rindex->attribute()==OwnerOverlapCopyAttributeSet::owner)\n+ 168 owner.insert(std::make_pair(i.index(),remote->first));\n+ 169 }\n+ 170 }\n+ 171\n+ 172 int iowner = 0;\n+ 173 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {\n+ 174 if (mask[i.index()] == 0) {\n+ 175 std::map::iterator it = owner.find(i.index());\n+ 176 iowner = it->second;\n+ 177 std::pair foundiit = rimap.equal_range(i.index());\n+ 178 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n+(); ++j) {\n+ 179 if (mask[j.index()] == 0) {\n+ 180 bool flag = true;\n+ 181 for (RIMapit foundi = foundiit.first; foundi != foundiit.second; ++foundi)\n+{\n+ 182 std::pair foundjit = rimap.equal_range(j.index());\n+ 183 for (RIMapit foundj = foundjit.first; foundj != foundjit.second; ++foundj)\n+ 184 if (foundj->second.first == foundi->second.first)\n+ 185 if (foundj->second.second->attribute() == OwnerOverlapCopyAttributeSet::\n+owner\n+ 186 || foundj->second.first == iowner\n+ 187 || foundj->second.first < communication.communicator().rank()) {\n+ 188 flag = false;\n+ 189 continue;\n+ 190 }\n+ 191 if (flag == false)\n+ 192 continue;\n+ 193 }\n+ 194 // don\u00b4t contribute to Ax if\n+ 195 // 1. the owner of j has i as interior/border dof\n+ 196 // 2. iowner has j as interior/border dof\n+ 197 // 3. there is another process with smaller rank that has i and j\n+ 198 // as interor/border dofs\n+ 199 // if the owner of j does not have i as interior/border dof,\n+ 200 // it will not be taken into account\n+ 201 if (flag==true)\n+ 202 bordercontribution.insert(std::pair(i.index(),j.index()));\n+ 203 }\n+ 204 }\n+ 205 }\n+ 206 }\n+ 207 buildcomm = false;\n+ 208 }\n+ 209\n+ 210 //compute alpha*A*x nonoverlapping case\n+ 211 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {\n+ 212 if (mask[i.index()] == 0) {\n+ 213 //dof doesn't belong to process but is border (not ghost)\n+ 214 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n+(); ++j) {\n+ 215 if (mask[j.index()] == 1) //j is owner => then sum entries\n+ 216 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n+ 217 else if (mask[j.index()] == 0) {\n+ 218 std::pair itp =\n+ 219 bordercontribution.equal_range(i.index());\n+ 220 for (MM::iterator it = itp.first; it != itp.second; ++it)\n+ 221 if ((*it).second == (int)j.index())\n+ 222 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n+ 223 }\n+ 224 }\n+ 225 }\n+ 226 else if (mask[i.index()] == 1) {\n+ 227 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n+(); ++j)\n+ 228 if (mask[j.index()] != 2)\n+ 229 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n+ 230 }\n+ 231 }\n+ 232 }\n+ 233\n+235 virtual SolverCategory::Category category() const\n+ 236 {\n+ 237 return SolverCategory::nonoverlapping;\n+ 238 }\n+ 239\n+241 const communication_type& getCommunication() const\n+ 242 {\n+ 243 return communication;\n+ 244 }\n+ 245 private:\n+ 246 std::shared_ptr _A_;\n+ 247 const communication_type& communication;\n+ 248 mutable bool buildcomm;\n+ 249 mutable std::vector mask;\n+250 mutable std::multimap bordercontribution;\n+ 251 };\n+ 252\n+255 namespace Amg\n+ 256 {\n+ 257 template struct ConstructionTraits;\n+ 258 }\n+ 259\n+ 274 template\n+275 class NonoverlappingBlockPreconditioner\n+ 276 : public Preconditioner {\n+ 277 friend struct Amg::\n+ConstructionTraits >;\n+ 278 using X = typename P::domain_type;\n+ 279 using Y = typename P::range_type;\n+ 280 public:\n+282 typedef typename P::domain_type domain_type;\n+284 typedef typename P::range_type range_type;\n+286 typedef C communication_type;\n+ 287\n+302 NonoverlappingBlockPreconditioner (P& p, const communication_type& c)\n+ 303 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)\n+ 304 { }\n+ 305\n+313 NonoverlappingBlockPreconditioner (const std::shared_ptr

    & p, const\n+communication_type& c)\n+ 314 : _preconditioner(p), _communication(c)\n+ 315 { }\n+ 316\n+322 virtual void pre (domain_type& x, range_type& b)\n+ 323 {\n+ 324 _preconditioner->pre(x,b);\n+ 325 }\n+ 326\n+332 virtual void apply (domain_type& v, const range_type& d)\n+ 333 {\n+ 334 // block preconditioner equivalent to WrappedPreconditioner from\n+ 335 // pdelab/backend/ovlpistsolverbackend.hh,\n+ 336 // but not to BlockPreconditioner from schwarz.hh\n+ 337 _preconditioner->apply(v,d);\n+ 338 _communication.addOwnerCopyToOwnerCopy(v,v);\n+ 339 }\n+ 340\n+ 341 template\n+342 void apply (X& v, const Y& d)\n+ 343 {\n+ 344 _preconditioner->template apply(v,d);\n+ 345 _communication.addOwnerCopyToOwnerCopy(v,v);\n+ 346 }\n+ 347\n+353 virtual void post (domain_type& x)\n 354 {\n- 355 // print some information about the problem\n- 356 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n- 357 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n- 358 << \"StdEig:\" << std::endl;\n- 359 std::cout << blank_ << \" converged eigenvalues of A: \"\n- 360 << nconv << \" / \" << nev << std::endl;\n- 361 std::cout << blank_ << \" dominant eigenvalue of A: \"\n- 362 << lambda << std::endl;\n- 363 }\n- 364 std::cout << blank_ << \"Result (\"\n- 365 << \"#iterations = \" << nIterations_ << \", \"\n- 366 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 367 << \"\u03bb = \" << lambda << std::endl;\n- 368 if (verbosity_level_ > 2)\n- 369 {\n- 370 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 371 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 372 }\n- 373 }\n- 374\n- 375 // free dynamically allocated memory\n- 376 delete[] Ax_raw;\n- 377 delete[] ev;\n- 378 }\n- 379\n-391 inline void computeSymMinMagnitude (const Real& epsilon,\n- 392 BlockVector& x, Real& lambda) const\n- 393 {\n- 394 // print verbosity information\n- 395 if (verbosity_level_ > 0)\n- 396 std::cout << title_ << \"Computing an approximation of the \"\n- 397 << \"least dominant eigenvalue of a matrix which \"\n- 398 << \"is assumed to be symmetric.\" << std::endl;\n- 399\n- 400 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 401 // and to perform the product A*v (LU decomposition is not used)\n- 402 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 403 WrappedMatrix A(m_);\n- 404\n- 405 // get number of rows and columns in A\n- 406 const int nrows = A.nrows();\n- 407 const int ncols = A.ncols();\n- 408\n- 409 // assert that A is square\n- 410 if (nrows != ncols)\n- 411 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n- 412 << nrows << \"x\" << ncols << \").\");\n- 413\n- 414 // allocate memory for variables, set parameters\n- 415 const int nev = 1; // Number of eigenvalues to compute\n- 416 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 417 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 418 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 419 Real* ev = new Real[nev]; // Computed eigenvalues of A\n- 420 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 421 int nconv; // Number of converged eigenvalues\n- 422\n- 423 // define what we need: eigenvalues with smallest magnitude\n- 424 char which[] = \"SM\";\n- 425 ARSymStdEig\n- 426 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n- 427\n- 428 // set ARPACK verbosity mode if requested\n- 429 if (verbosity_level_ > 3) dprob.Trace();\n- 430\n- 431 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n- 432 nconv = dprob.Eigenvalues(ev,ivec);\n- 433\n- 434 // obtain approximated least dominant eigenvalue of A\n- 435 lambda = ev[nev-1];\n- 436\n- 437 // obtain associated approximated eigenvector of A\n- 438 Real* x_raw = dprob.RawEigenvector(nev-1);\n- 439 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n- 440\n- 441 // obtain number of Arnoldi update iterations actually taken\n- 442 nIterations_ = dprob.GetIter();\n- 443\n- 444 // compute residual norm\n- 445 BlockVector r(x);\n- 446 Real* Ax_raw = new Real[nrows];\n- 447 A.multMv(x_raw,Ax_raw);\n- 448 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);\n- 449 r.axpy(-lambda,x);\n- 450 const Real r_norm = r.two_norm();\n- 451\n- 452 // print verbosity information\n- 453 if (verbosity_level_ > 0)\n- 454 {\n- 455 if (verbosity_level_ > 1)\n- 456 {\n- 457 // print some information about the problem\n- 458 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n- 459 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n- 460 << \"StdEig:\" << std::endl;\n- 461 std::cout << blank_ << \" converged eigenvalues of A: \"\n- 462 << nconv << \" / \" << nev << std::endl;\n- 463 std::cout << blank_ << \" least dominant eigenvalue of A: \"\n- 464 << lambda << std::endl;\n- 465 }\n- 466 std::cout << blank_ << \"Result (\"\n- 467 << \"#iterations = \" << nIterations_ << \", \"\n- 468 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 469 << \"\u03bb = \" << lambda << std::endl;\n- 470 if (verbosity_level_ > 2)\n- 471 {\n- 472 // print approximated eigenvector via DUNE-ISTL I/O methods\n- 473 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 474 }\n- 475 }\n- 476\n- 477 // free dynamically allocated memory\n- 478 delete[] Ax_raw;\n- 479 delete[] ev;\n- 480 }\n- 481\n-493 inline void computeSymCond2 (const Real& epsilon, Real& cond_2) const\n- 494 {\n- 495 // print verbosity information\n- 496 if (verbosity_level_ > 0)\n- 497 std::cout << title_ << \"Computing an approximation of the \"\n- 498 << \"spectral condition number of a matrix which \"\n- 499 << \"is assumed to be symmetric.\" << std::endl;\n- 500\n- 501 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 502 // and to perform the product A*v (LU decomposition is not used)\n- 503 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 504 WrappedMatrix A(m_);\n- 505\n- 506 // get number of rows and columns in A\n- 507 const int nrows = A.nrows();\n- 508 const int ncols = A.ncols();\n- 509\n- 510 // assert that A is square\n- 511 if (nrows != ncols)\n- 512 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n- 513 << nrows << \"x\" << ncols << \").\");\n- 514\n- 515 // allocate memory for variables, set parameters\n- 516 const int nev = 2; // Number of eigenvalues to compute\n- 517 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 518 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 519 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 520 Real* ev = new Real[nev]; // Computed eigenvalues of A\n- 521 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 522 int nconv; // Number of converged eigenvalues\n- 523\n- 524 // define what we need: eigenvalues from both ends of the spectrum\n- 525 char which[] = \"BE\";\n- 526 ARSymStdEig\n- 527 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n- 528\n- 529 // set ARPACK verbosity mode if requested\n- 530 if (verbosity_level_ > 3) dprob.Trace();\n- 531\n- 532 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n- 533 nconv = dprob.Eigenvalues(ev,ivec);\n- 534\n- 535 // obtain approximated dominant and least dominant eigenvalue of A\n- 536 const Real& lambda_max = ev[nev-1];\n- 537 const Real& lambda_min = ev[0];\n- 538\n- 539 // obtain associated approximated eigenvectors of A\n- 540 Real* x_max_raw = dprob.RawEigenvector(nev-1);\n- 541 Real* x_min_raw = dprob.RawEigenvector(0);\n- 542\n- 543 // obtain approximated spectral condition number of A\n- 544 cond_2 = std::abs(lambda_max / lambda_min);\n- 545\n- 546 // obtain number of Arnoldi update iterations actually taken\n- 547 nIterations_ = dprob.GetIter();\n- 548\n- 549 // compute each residual norm\n- 550 Real* Ax_max_raw = new Real[nrows];\n- 551 Real* Ax_min_raw = new Real[nrows];\n- 552 A.multMv(x_max_raw,Ax_max_raw);\n- 553 A.multMv(x_min_raw,Ax_min_raw);\n- 554 Real r_max_norm = 0.0;\n- 555 Real r_min_norm = 0.0;\n- 556 for (int i = 0; i < nrows; ++i)\n- 557 {\n- 558 r_max_norm += std::pow(Ax_max_raw[i] - lambda_max * x_max_raw[i],2);\n- 559 r_min_norm += std::pow(Ax_min_raw[i] - lambda_min * x_min_raw[i],2);\n- 560 }\n- 561 r_max_norm = std::sqrt(r_max_norm);\n- 562 r_min_norm = std::sqrt(r_min_norm);\n- 563\n- 564 // print verbosity information\n- 565 if (verbosity_level_ > 0)\n- 566 {\n- 567 if (verbosity_level_ > 1)\n- 568 {\n- 569 // print some information about the problem\n- 570 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n- 571 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n- 572 << \"StdEig:\" << std::endl;\n- 573 std::cout << blank_ << \" converged eigenvalues of A: \"\n- 574 << nconv << \" / \" << nev << std::endl;\n- 575 std::cout << blank_ << \" dominant eigenvalue of A: \"\n- 576 << lambda_max << std::endl;\n- 577 std::cout << blank_ << \" least dominant eigenvalue of A: \"\n- 578 << lambda_min << std::endl;\n- 579 std::cout << blank_ << \" spectral condition number of A: \"\n- 580 << cond_2 << std::endl;\n- 581 }\n- 582 std::cout << blank_ << \"Result (\"\n- 583 << \"#iterations = \" << nIterations_ << \", \"\n- 584 << \"\u2551residual\u2551_2 = {\" << r_max_norm << \",\"\n- 585 << r_min_norm << \"}, \" << \"\u03bb = {\"\n- 586 << lambda_max << \",\" << lambda_min\n- 587 << \"}): cond_2 = \" << cond_2 << std::endl;\n- 588 }\n- 589\n- 590 // free dynamically allocated memory\n- 591 delete[] Ax_min_raw;\n- 592 delete[] Ax_max_raw;\n- 593 delete[] ev;\n- 594 }\n- 595\n-609 inline void computeNonSymMax (const Real& epsilon,\n- 610 BlockVector& x, Real& sigma) const\n- 611 {\n- 612 // print verbosity information\n- 613 if (verbosity_level_ > 0)\n- 614 std::cout << title_ << \"Computing an approximation of the \"\n- 615 << \"largest singular value of a matrix which \"\n- 616 << \"is assumed to be nonsymmetric.\" << std::endl;\n- 617\n- 618 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 619 // and to perform the product A^T*A*v (LU decomposition is not used)\n- 620 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 621 WrappedMatrix A(m_);\n- 622\n- 623 // get number of rows and columns in A\n- 624 const int nrows = A.nrows();\n- 625 const int ncols = A.ncols();\n- 626\n- 627 // assert that A has more rows than columns (extend code later to the\n-opposite case!)\n- 628 if (nrows < ncols)\n- 629 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n- 630 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n- 631 << \" This case is not implemented, yet.\");\n- 632\n- 633 // allocate memory for variables, set parameters\n- 634 const int nev = 1; // Number of eigenvalues to compute\n- 635 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 636 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 637 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 638 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n- 639 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 640 int nconv; // Number of converged eigenvalues\n- 641\n- 642 // define what we need: eigenvalues with largest algebraic value\n- 643 char which[] = \"LA\";\n- 644 ARSymStdEig\n- 645 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n- 646\n- 647 // set ARPACK verbosity mode if requested\n- 648 if (verbosity_level_ > 3) dprob.Trace();\n- 649\n- 650 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n- 651 nconv = dprob.Eigenvalues(ev,ivec);\n- 652\n- 653 // obtain approximated largest eigenvalue of A^T*A\n- 654 const Real& lambda = ev[nev-1];\n- 655\n- 656 // obtain associated approximated eigenvector of A^T*A\n- 657 Real* x_raw = dprob.RawEigenvector(nev-1);\n- 658 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n- 659\n- 660 // obtain number of Arnoldi update iterations actually taken\n- 661 nIterations_ = dprob.GetIter();\n- 662\n- 663 // compute residual norm\n- 664 BlockVector r(x);\n- 665 Real* AtAx_raw = new Real[ncols];\n- 666 A.multMtMv(x_raw,AtAx_raw);\n- 667 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);\n- 668 r.axpy(-lambda,x);\n- 669 const Real r_norm = r.two_norm();\n- 670\n- 671 // calculate largest singular value of A (note that\n- 672 // x is right-singular / left-singular vector of A)\n- 673 sigma = std::sqrt(lambda);\n- 674\n- 675 // print verbosity information\n- 676 if (verbosity_level_ > 0)\n- 677 {\n- 678 if (verbosity_level_ > 1)\n- 679 {\n- 680 // print some information about the problem\n- 681 std::cout << blank_ << \"Obtained singular values of A by sol\"\n- 682 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n- 683 << \"class ARSymStdEig:\" << std::endl;\n- 684 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n- 685 << nconv << \" / \" << nev << std::endl;\n- 686 std::cout << blank_ << \" largest eigenvalue of A^T*A: \"\n- 687 << lambda << std::endl;\n- 688 std::cout << blank_ << \" => largest singular value of A: \"\n- 689 << sigma << std::endl;\n- 690 }\n- 691 std::cout << blank_ << \"Result (\"\n- 692 << \"#iterations = \" << nIterations_ << \", \"\n- 693 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 694 << \"\u03c3 = \" << sigma << std::endl;\n- 695 if (verbosity_level_ > 2)\n- 696 {\n- 697 // print approximated right-singular / left-singular vector\n- 698 // via DUNE-ISTL I/O methods\n- 699 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 700 }\n- 701 }\n- 702\n- 703 // free dynamically allocated memory\n- 704 delete[] AtAx_raw;\n- 705 delete[] ev;\n- 706 }\n- 707\n-721 inline void computeNonSymMin (const Real& epsilon,\n- 722 BlockVector& x, Real& sigma) const\n- 723 {\n- 724 // print verbosity information\n- 725 if (verbosity_level_ > 0)\n- 726 std::cout << title_ << \"Computing an approximation of the \"\n- 727 << \"smallest singular value of a matrix which \"\n- 728 << \"is assumed to be nonsymmetric.\" << std::endl;\n- 729\n- 730 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 731 // and to perform the product A^T*A*v (LU decomposition is not used)\n- 732 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 733 WrappedMatrix A(m_);\n- 734\n- 735 // get number of rows and columns in A\n- 736 const int nrows = A.nrows();\n- 737 const int ncols = A.ncols();\n- 738\n- 739 // assert that A has more rows than columns (extend code later to the\n-opposite case!)\n- 740 if (nrows < ncols)\n- 741 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n- 742 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n- 743 << \" This case is not implemented, yet.\");\n- 744\n- 745 // allocate memory for variables, set parameters\n- 746 const int nev = 1; // Number of eigenvalues to compute\n- 747 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 748 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 749 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 750 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n- 751 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 752 int nconv; // Number of converged eigenvalues\n- 753\n- 754 // define what we need: eigenvalues with smallest algebraic value\n- 755 char which[] = \"SA\";\n- 756 ARSymStdEig\n- 757 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n- 758\n- 759 // set ARPACK verbosity mode if requested\n- 760 if (verbosity_level_ > 3) dprob.Trace();\n- 761\n- 762 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n- 763 nconv = dprob.Eigenvalues(ev,ivec);\n- 764\n- 765 // obtain approximated smallest eigenvalue of A^T*A\n- 766 const Real& lambda = ev[nev-1];\n- 767\n- 768 // obtain associated approximated eigenvector of A^T*A\n- 769 Real* x_raw = dprob.RawEigenvector(nev-1);\n- 770 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n- 771\n- 772 // obtain number of Arnoldi update iterations actually taken\n- 773 nIterations_ = dprob.GetIter();\n- 774\n- 775 // compute residual norm\n- 776 BlockVector r(x);\n- 777 Real* AtAx_raw = new Real[ncols];\n- 778 A.multMtMv(x_raw,AtAx_raw);\n- 779 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);\n- 780 r.axpy(-lambda,x);\n- 781 const Real r_norm = r.two_norm();\n- 782\n- 783 // calculate smallest singular value of A (note that\n- 784 // x is right-singular / left-singular vector of A)\n- 785 sigma = std::sqrt(lambda);\n- 786\n- 787 // print verbosity information\n- 788 if (verbosity_level_ > 0)\n- 789 {\n- 790 if (verbosity_level_ > 1)\n- 791 {\n- 792 // print some information about the problem\n- 793 std::cout << blank_ << \"Obtained singular values of A by sol\"\n- 794 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n- 795 << \"class ARSymStdEig:\" << std::endl;\n- 796 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n- 797 << nconv << \" / \" << nev << std::endl;\n- 798 std::cout << blank_ << \" smallest eigenvalue of A^T*A: \"\n- 799 << lambda << std::endl;\n- 800 std::cout << blank_ << \" => smallest singular value of A: \"\n- 801 << sigma << std::endl;\n- 802 }\n- 803 std::cout << blank_ << \"Result (\"\n- 804 << \"#iterations = \" << nIterations_ << \", \"\n- 805 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n- 806 << \"\u03c3 = \" << sigma << std::endl;\n- 807 if (verbosity_level_ > 2)\n- 808 {\n- 809 // print approximated right-singular / left-singular vector\n- 810 // via DUNE-ISTL I/O methods\n- 811 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n- 812 }\n- 813 }\n- 814\n- 815 // free dynamically allocated memory\n- 816 delete[] AtAx_raw;\n- 817 delete[] ev;\n- 818 }\n- 819\n-830 inline void computeNonSymCond2 (const Real& epsilon, Real& cond_2) const\n- 831 {\n- 832 // print verbosity information\n- 833 if (verbosity_level_ > 0)\n- 834 std::cout << title_ << \"Computing an approximation of the \"\n- 835 << \"spectral condition number of a matrix which \"\n- 836 << \"is assumed to be nonsymmetric.\" << std::endl;\n- 837\n- 838 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n- 839 // and to perform the product A^T*A*v (LU decomposition is not used)\n- 840 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n- 841 WrappedMatrix A(m_);\n- 842\n- 843 // get number of rows and columns in A\n- 844 const int nrows = A.nrows();\n- 845 const int ncols = A.ncols();\n- 846\n- 847 // assert that A has more rows than columns (extend code later to the\n-opposite case!)\n- 848 if (nrows < ncols)\n- 849 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n- 850 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n- 851 << \" This case is not implemented, yet.\");\n- 852\n- 853 // allocate memory for variables, set parameters\n- 854 const int nev = 2; // Number of eigenvalues to compute\n- 855 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n-each iteration (0 == auto)\n- 856 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n-values) (0 == machine precision)\n- 857 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n-iterations allowed (0 == 100*nev)\n- 858 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n- 859 const bool ivec = true; // Flag deciding if eigenvectors shall be\n-determined\n- 860 int nconv; // Number of converged eigenvalues\n- 861\n- 862 // define what we need: eigenvalues from both ends of the spectrum\n- 863 char which[] = \"BE\";\n- 864 ARSymStdEig\n- 865 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n- 866\n- 867 // set ARPACK verbosity mode if requested\n- 868 if (verbosity_level_ > 3) dprob.Trace();\n- 869\n- 870 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n- 871 nconv = dprob.Eigenvalues(ev,ivec);\n- 872\n- 873 // obtain approximated largest and smallest eigenvalue of A^T*A\n- 874 const Real& lambda_max = ev[nev-1];\n- 875 const Real& lambda_min = ev[0];\n- 876\n- 877 // obtain associated approximated eigenvectors of A^T*A\n- 878 Real* x_max_raw = dprob.RawEigenvector(nev-1);\n- 879 Real* x_min_raw = dprob.RawEigenvector(0);\n- 880\n- 881 // obtain number of Arnoldi update iterations actually taken\n- 882 nIterations_ = dprob.GetIter();\n- 883\n- 884 // compute each residual norm\n- 885 Real* AtAx_max_raw = new Real[ncols];\n- 886 Real* AtAx_min_raw = new Real[ncols];\n- 887 A.multMtMv(x_max_raw,AtAx_max_raw);\n- 888 A.multMtMv(x_min_raw,AtAx_min_raw);\n- 889 Real r_max_norm = 0.0;\n- 890 Real r_min_norm = 0.0;\n- 891 for (int i = 0; i < ncols; ++i)\n- 892 {\n- 893 r_max_norm += std::pow(AtAx_max_raw[i] - lambda_max * x_max_raw[i],2);\n- 894 r_min_norm += std::pow(AtAx_min_raw[i] - lambda_min * x_min_raw[i],2);\n- 895 }\n- 896 r_max_norm = std::sqrt(r_max_norm);\n- 897 r_min_norm = std::sqrt(r_min_norm);\n- 898\n- 899 // calculate largest and smallest singular value of A\n- 900 const Real sigma_max = std::sqrt(lambda_max);\n- 901 const Real sigma_min = std::sqrt(lambda_min);\n- 902\n- 903 // obtain approximated spectral condition number of A\n- 904 cond_2 = sigma_max / sigma_min;\n- 905\n- 906 // print verbosity information\n- 907 if (verbosity_level_ > 0)\n- 908 {\n- 909 if (verbosity_level_ > 1)\n- 910 {\n- 911 // print some information about the problem\n- 912 std::cout << blank_ << \"Obtained singular values of A by sol\"\n- 913 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n- 914 << \"class ARSymStdEig:\" << std::endl;\n- 915 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n- 916 << nconv << \" / \" << nev << std::endl;\n- 917 std::cout << blank_ << \" largest eigenvalue of A^T*A: \"\n- 918 << lambda_max << std::endl;\n- 919 std::cout << blank_ << \" smallest eigenvalue of A^T*A: \"\n- 920 << lambda_min << std::endl;\n- 921 std::cout << blank_ << \" => largest singular value of A: \"\n- 922 << sigma_max << std::endl;\n- 923 std::cout << blank_ << \" => smallest singular value of A: \"\n- 924 << sigma_min << std::endl;\n- 925 }\n- 926 std::cout << blank_ << \"Result (\"\n- 927 << \"#iterations = \" << nIterations_ << \", \"\n- 928 << \"\u2551residual\u2551_2 = {\" << r_max_norm << \",\"\n- 929 << r_min_norm << \"}, \" << \"\u03c3 = {\"\n- 930 << sigma_max << \",\" << sigma_min\n- 931 << \"}): cond_2 = \" << cond_2 << std::endl;\n- 932 }\n- 933\n- 934 // free dynamically allocated memory\n- 935 delete[] AtAx_min_raw;\n- 936 delete[] AtAx_max_raw;\n- 937 delete[] ev;\n- 938 }\n- 939\n-944 inline unsigned int getIterationCount () const\n- 945 {\n- 946 if (nIterations_ == 0)\n- 947 DUNE_THROW(Dune::ISTLError,\"No algorithm applied, yet.\");\n- 948\n- 949 return nIterations_;\n- 950 }\n- 951\n- 952 protected:\n- 953 // parameters related to iterative eigenvalue algorithms\n-954 const BCRSMatrix& m_;\n-955 const unsigned int nIterationsMax_;\n- 956\n- 957 // verbosity setting\n-958 const unsigned int verbosity_level_;\n- 959\n- 960 // memory for storing temporary variables (mutable as they shall\n- 961 // just be effectless auxiliary variables of the const apply*(...)\n- 962 // methods)\n-963 mutable unsigned int nIterations_;\n- 964\n- 965 // constants for printing verbosity information\n-966 const std::string title_;\n-967 const std::string blank_;\n- 968 };\n- 969\n- 972} // namespace Dune\n- 973\n- 974#endif // HAVE_ARPACKPP\n- 975\n- 976#endif // DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n+ 355 _preconditioner->post(x);\n+ 356 }\n+ 357\n+359 virtual SolverCategory::Category category() const\n+ 360 {\n+ 361 return SolverCategory::nonoverlapping;\n+ 362 }\n+ 363\n+ 364 private:\n+ 366 std::shared_ptr

    _preconditioner;\n+ 367\n+ 369 const communication_type& _communication;\n+ 370 };\n+ 371\n+ 374} // end namespace\n+ 375\n+ 376#endif\n+io.hh\n+Some generic functions for pretty printing vectors and matrices.\n+vbvector.hh\n+???\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n bvector.hh\n This file implements a vector space as a tensor product of a given vector\n space. The number of compon...\n-istlexception.hh\n-io.hh\n-Some generic functions for pretty printing vectors and matrices.\n-Dune::printvector\n-void printvector(std::ostream &s, const V &v, std::string title, std::string\n-rowtext, int columns=1, int width=10, int precision=2)\n-Print an ISTL vector.\n-Definition: io.hh:89\n+solvers.hh\n+Implementations of the inverse operator interface.\n+gsetc.hh\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way.\n+ilu.hh\n+The incomplete LU factorization kernels.\n+preconditioners.hh\n+Define general preconditioner interface.\n Dune\n Definition: allocator.hh:11\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bcrsmatrix.hh:488\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::BlockVector::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bvector.hh:401\n-Dune::BlockVector::size_type\n-A::size_type size_type\n-The type for the index access.\n-Definition: bvector.hh:410\n-Dune::ArPackPlusPlus_Algorithms\n-Wrapper to use a range of ARPACK++ eigenvalue solvers.\n-Definition: arpackpp.hh:245\n-Dune::ArPackPlusPlus_Algorithms::verbosity_level_\n-const unsigned int verbosity_level_\n-Definition: arpackpp.hh:958\n-Dune::ArPackPlusPlus_Algorithms::getIterationCount\n-unsigned int getIterationCount() const\n-Return the number of iterations in last application of an algorithm.\n-Definition: arpackpp.hh:944\n-Dune::ArPackPlusPlus_Algorithms::title_\n-const std::string title_\n-Definition: arpackpp.hh:966\n-Dune::ArPackPlusPlus_Algorithms::Real\n-BlockVector::field_type Real\n-Definition: arpackpp.hh:247\n-Dune::ArPackPlusPlus_Algorithms::computeSymMaxMagnitude\n-void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n-const\n-Assume the matrix to be square, symmetric and perform IRLM to compute an\n-approximation lambda of its ...\n-Definition: arpackpp.hh:289\n-Dune::ArPackPlusPlus_Algorithms::computeSymMinMagnitude\n-void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n-const\n-Assume the matrix to be square, symmetric and perform IRLM to compute an\n-approximation lambda of its ...\n-Definition: arpackpp.hh:391\n-Dune::ArPackPlusPlus_Algorithms::m_\n-const BCRSMatrix & m_\n-Definition: arpackpp.hh:954\n-Dune::ArPackPlusPlus_Algorithms::nIterationsMax_\n-const unsigned int nIterationsMax_\n-Definition: arpackpp.hh:955\n-Dune::ArPackPlusPlus_Algorithms::blank_\n-const std::string blank_\n-Definition: arpackpp.hh:967\n-Dune::ArPackPlusPlus_Algorithms::ArPackPlusPlus_Algorithms\n-ArPackPlusPlus_Algorithms(const BCRSMatrix &m, const unsigned int\n-nIterationsMax=100000, const unsigned int verbosity_level=0)\n-Construct from required parameters.\n-Definition: arpackpp.hh:268\n-Dune::ArPackPlusPlus_Algorithms::computeSymCond2\n-void computeSymCond2(const Real &epsilon, Real &cond_2) const\n-Assume the matrix to be square, symmetric and perform IRLM to compute an\n-approximation of its spectra...\n-Definition: arpackpp.hh:493\n-Dune::ArPackPlusPlus_Algorithms::nIterations_\n-unsigned int nIterations_\n-Definition: arpackpp.hh:963\n-Dune::ArPackPlusPlus_Algorithms::computeNonSymMin\n-void computeNonSymMin(const Real &epsilon, BlockVector &x, Real &sigma) const\n-Assume the matrix to be nonsymmetric and perform IRLM to compute an\n-approximation sigma of its smalle...\n-Definition: arpackpp.hh:721\n-Dune::ArPackPlusPlus_Algorithms::computeNonSymCond2\n-void computeNonSymCond2(const Real &epsilon, Real &cond_2) const\n-Assume the matrix to be nonsymmetric and perform IRLM to compute an\n-approximation of its spectral con...\n-Definition: arpackpp.hh:830\n-Dune::ArPackPlusPlus_Algorithms::computeNonSymMax\n-void computeNonSymMax(const Real &epsilon, BlockVector &x, Real &sigma) const\n-Assume the matrix to be nonsymmetric and perform IRLM to compute an\n-approximation sigma of its larges...\n-Definition: arpackpp.hh:609\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n+Dune::NonoverlappingSchwarzOperator\n+A nonoverlapping operator with communication object.\n+Definition: novlpschwarz.hh:61\n+Dune::NonoverlappingSchwarzOperator::PIS\n+C::PIS PIS\n+Definition: novlpschwarz.hh:74\n+Dune::NonoverlappingSchwarzOperator::communication_type\n+C communication_type\n+The type of the communication object.\n+Definition: novlpschwarz.hh:72\n+Dune::NonoverlappingSchwarzOperator::RIMap\n+std::multimap< int, std::pair< int, RILIterator > > RIMap\n+Definition: novlpschwarz.hh:82\n+Dune::NonoverlappingSchwarzOperator::RI\n+C::RI RI\n+Definition: novlpschwarz.hh:75\n+Dune::NonoverlappingSchwarzOperator::novlp_op_apply\n+void novlp_op_apply(const X &x, Y &y, field_type alpha) const\n+Definition: novlpschwarz.hh:126\n+Dune::NonoverlappingSchwarzOperator::NonoverlappingSchwarzOperator\n+NonoverlappingSchwarzOperator(std::shared_ptr< const matrix_type > A, const\n+communication_type &com)\n+Definition: novlpschwarz.hh:96\n+Dune::NonoverlappingSchwarzOperator::ColIterator\n+M::ConstColIterator ColIterator\n+Definition: novlpschwarz.hh:79\n+Dune::NonoverlappingSchwarzOperator::apply\n+virtual void apply(const X &x, Y &y) const\n+apply operator to x:\n+Definition: novlpschwarz.hh:101\n+Dune::NonoverlappingSchwarzOperator::domain_type\n+X domain_type\n+The type of the domain.\n+Definition: novlpschwarz.hh:66\n+Dune::NonoverlappingSchwarzOperator::category\n+virtual SolverCategory::Category category() const\n+Category of the linear operator (see SolverCategory::Category)\n+Definition: novlpschwarz.hh:235\n+Dune::NonoverlappingSchwarzOperator::RIMapit\n+RIMap::iterator RIMapit\n+Definition: novlpschwarz.hh:83\n+Dune::NonoverlappingSchwarzOperator::getmat\n+virtual const matrix_type & getmat() const\n+get matrix via *\n+Definition: novlpschwarz.hh:121\n+Dune::NonoverlappingSchwarzOperator::RILIterator\n+RIL::const_iterator RILIterator\n+Definition: novlpschwarz.hh:78\n+Dune::NonoverlappingSchwarzOperator::MM\n+std::multimap< int, int > MM\n+Definition: novlpschwarz.hh:81\n+Dune::NonoverlappingSchwarzOperator::range_type\n+Y range_type\n+The type of the range.\n+Definition: novlpschwarz.hh:68\n+Dune::NonoverlappingSchwarzOperator::matrix_type\n+M matrix_type\n+The type of the matrix we operate on.\n+Definition: novlpschwarz.hh:64\n+Dune::NonoverlappingSchwarzOperator::RowIterator\n+M::ConstRowIterator RowIterator\n+Definition: novlpschwarz.hh:80\n+Dune::NonoverlappingSchwarzOperator::getCommunication\n+const communication_type & getCommunication() const\n+Get the object responsible for communication.\n+Definition: novlpschwarz.hh:241\n+Dune::NonoverlappingSchwarzOperator::applyscaleadd\n+virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const\n+apply operator to x, scale and add:\n+Definition: novlpschwarz.hh:109\n+Dune::NonoverlappingSchwarzOperator::RIL\n+RI::RemoteIndexList RIL\n+Definition: novlpschwarz.hh:76\n+Dune::NonoverlappingSchwarzOperator::field_type\n+X::field_type field_type\n+The field type of the range.\n+Definition: novlpschwarz.hh:70\n+Dune::NonoverlappingSchwarzOperator::NonoverlappingSchwarzOperator\n+NonoverlappingSchwarzOperator(const matrix_type &A, const communication_type\n+&com)\n+constructor: just store a reference to a matrix.\n+Definition: novlpschwarz.hh:92\n+Dune::NonoverlappingSchwarzOperator::RIIterator\n+RI::const_iterator RIIterator\n+Definition: novlpschwarz.hh:77\n+Dune::Amg::ConstructionTraits\n+Traits class for generically constructing non default constructable types.\n+Definition: construction.hh:39\n+Dune::NonoverlappingBlockPreconditioner\n+Nonoverlapping parallel preconditioner.\n+Definition: novlpschwarz.hh:276\n+Dune::NonoverlappingBlockPreconditioner::NonoverlappingBlockPreconditioner\n+NonoverlappingBlockPreconditioner(P &p, const communication_type &c)\n+Constructor.\n+Definition: novlpschwarz.hh:302\n+Dune::NonoverlappingBlockPreconditioner::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: novlpschwarz.hh:359\n+Dune::NonoverlappingBlockPreconditioner::apply\n+virtual void apply(domain_type &v, const range_type &d)\n+Apply the preconditioner.\n+Definition: novlpschwarz.hh:332\n+Dune::NonoverlappingBlockPreconditioner::range_type\n+P::range_type range_type\n+The range type of the preconditioner.\n+Definition: novlpschwarz.hh:284\n+Dune::NonoverlappingBlockPreconditioner::NonoverlappingBlockPreconditioner\n+NonoverlappingBlockPreconditioner(const std::shared_ptr< P > &p, const\n+communication_type &c)\n+Constructor.\n+Definition: novlpschwarz.hh:313\n+Dune::NonoverlappingBlockPreconditioner::post\n+virtual void post(domain_type &x)\n+Clean up.\n+Definition: novlpschwarz.hh:353\n+Dune::NonoverlappingBlockPreconditioner::communication_type\n+C communication_type\n+The type of the communication object.\n+Definition: novlpschwarz.hh:286\n+Dune::NonoverlappingBlockPreconditioner::pre\n+virtual void pre(domain_type &x, range_type &b)\n+Prepare the preconditioner.\n+Definition: novlpschwarz.hh:322\n+Dune::NonoverlappingBlockPreconditioner::apply\n+void apply(X &v, const Y &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: novlpschwarz.hh:342\n+Dune::NonoverlappingBlockPreconditioner::domain_type\n+P::domain_type domain_type\n+The domain type of the preconditioner.\n+Definition: novlpschwarz.hh:282\n+Dune::AssembledLinearOperator\n+A linear operator exporting itself in matrix form.\n+Definition: operators.hh:109\n+Dune::OwnerOverlapCopyAttributeSet::owner\n+@ owner\n+Definition: owneroverlapcopy.hh:61\n+Dune::OwnerOverlapCopyAttributeSet::copy\n+@ copy\n+Definition: owneroverlapcopy.hh:61\n+Dune::OwnerOverlapCopyAttributeSet::overlap\n+@ overlap\n+Definition: owneroverlapcopy.hh:61\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::nonoverlapping\n+@ nonoverlapping\n+Category for non-overlapping solvers.\n+Definition: solvercategory.hh:27\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00041.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00041.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solver.hh File Reference\n+dune-istl: umfpack.hh File Reference\n \n \n \n \n \n \n \n@@ -64,70 +64,71 @@\n

    \n
    \n
    \n \n+ \n
    \n
    \n \n-

    Define general, extensible interface for inverse operators. \n+

    Classes for using UMFPack with ISTL matrices. \n More...

    \n-
    #include <iomanip>
    \n-#include <ostream>
    \n-#include <string>
    \n-#include <functional>
    \n+
    #include <complex>
    \n+#include <type_traits>
    \n+#include <umfpack.h>
    \n #include <dune/common/exceptions.hh>
    \n-#include <dune/common/shared_ptr.hh>
    \n-#include <dune/common/simd/io.hh>
    \n-#include <dune/common/simd/simd.hh>
    \n-#include <dune/common/parametertree.hh>
    \n-#include <dune/common/timer.hh>
    \n-#include "solvertype.hh"
    \n-#include "preconditioner.hh"
    \n-#include "operators.hh"
    \n-#include "scalarproducts.hh"
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/istl/bccsmatrixinitializer.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/istl/solvers.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/istl/solverfactory.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::InverseOperatorResult
     Statistics about the application of an inverse operator. More...
    struct  Dune::UMFPackMethodChooser< T >
     
    class  Dune::InverseOperator< X, Y >
     Abstract base class for all solvers. More...
    struct  Dune::UMFPackMethodChooser< double >
     
    class  Dune::IterativeSolver< X, Y >
     Base class for all implementations of iterative solvers. More...
    struct  Dune::UMFPackMethodChooser< std::complex< double > >
     
    class  Dune::IterativeSolver< X, Y >::Iteration< CountType >
     Class for controlling iterative methods. More...
    class  Dune::UMFPack< M >
     The UMFPack direct sparse solver. More...
     
    class  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >
     Helper class for notifying a DUNE-ISTL linear solver about a change of the iteration matrix object in a unified way, i.e. independent from the solver's type (direct/iterative). More...
    struct  Dune::IsDirectSolver< UMFPack< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< is_direct_solver, Dummy >
     Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTABSolver. More...
    struct  Dune::StoresColumnCompressed< UMFPack< BCRSMatrix< T, A > > >
     
    struct  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< true, Dummy >
     Implementation that works together with direct ISTL solvers, e.g. Dune::SuperLU or Dune::UMFPack. More...
    struct  Dune::UMFPackCreator
     
    struct  Dune::UMFPackCreator::isValidBlock< F, class >
     
    struct  Dune::UMFPackCreator::isValidBlock< B, std::enable_if_t< std::is_same< typename FieldTraits< B >::real_type, double >::value > >
     
    \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n

    \n+Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("umfpack", Dune::UMFPackCreator())
     
    \n

    Detailed Description

    \n-

    Define general, extensible interface for inverse operators.

    \n-

    Implementation here covers only inversion of linear operators, but the implementation might be used for nonlinear operators as well.

    \n+

    Classes for using UMFPack with ISTL matrices.

    \n+
    Author
    Dominic Kempf
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,64 +4,58 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-solver.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers\n-Define general, extensible interface for inverse operators. More...\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+umfpack.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL)\n+Classes for using UMFPack with ISTL matrices. More...\n+#include \n+#include \n+#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"solvertype.hh\"\n-#include \"preconditioner.hh\"\n-#include \"operators.hh\"\n-#include \"scalarproducts.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::InverseOperatorResult\n-\u00a0 Statistics about the application of an inverse operator. More...\n+struct \u00a0Dune::UMFPackMethodChooser<_T_>\n \u00a0\n- class \u00a0Dune::InverseOperator<_X,_Y_>\n-\u00a0 Abstract base class for all solvers. More...\n+struct \u00a0Dune::UMFPackMethodChooser<_double_>\n \u00a0\n- class \u00a0Dune::IterativeSolver<_X,_Y_>\n-\u00a0 Base class for all implementations of iterative solvers. More...\n+struct \u00a0Dune::UMFPackMethodChooser<_std::complex<_double_>_>\n \u00a0\n- class \u00a0Dune::IterativeSolver<_X,_Y_>::Iteration<_CountType_>\n-\u00a0 Class for controlling iterative methods. More...\n-\u00a0\n- class \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>\n- Helper class for notifying a DUNE-ISTL linear solver about a change of\n-\u00a0 the iteration matrix object in a unified way, i.e. independent from\n- the solver's type (direct/iterative). More...\n-\u00a0\n-struct \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>::Implementation<\n- is_direct_solver,_Dummy_>\n-\u00a0 Implementation that works together with iterative ISTL solvers, e.g.\n- Dune::CGSolver or Dune::BiCGSTABSolver. More...\n-\u00a0\n-struct \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>::Implementation<\n- true,_Dummy_>\n-\u00a0 Implementation that works together with direct ISTL solvers, e.g.\n- Dune::SuperLU or Dune::UMFPack. More...\n+ class \u00a0Dune::UMFPack<_M_>\n+\u00a0 The UMFPack direct sparse solver. More...\n+\u00a0\n+struct \u00a0Dune::IsDirectSolver<_UMFPack<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>\n+ >_>\n+\u00a0\n+struct \u00a0Dune::StoresColumnCompressed<_UMFPack<_BCRSMatrix<_T,_A_>_>_>\n+\u00a0\n+struct \u00a0Dune::UMFPackCreator\n+\u00a0\n+struct \u00a0Dune::UMFPackCreator::isValidBlock<_F,_class_>\n+\u00a0\n+struct \u00a0Dune::UMFPackCreator::isValidBlock<_B,_std::enable_if_t<_std::is_same<\n+ typename_FieldTraits<_B_>::real_type,_double_>::value_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Functions\n+\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"umfpack\", Dune::UMFPackCreator())\n+\u00a0\n ***** Detailed Description *****\n-Define general, extensible interface for inverse operators.\n-Implementation here covers only inversion of linear operators, but the\n-implementation might be used for nonlinear operators as well.\n+Classes for using UMFPack with ISTL matrices.\n+ Author\n+ Dominic Kempf\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00041_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00041_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solver.hh Source File\n+dune-istl: umfpack.hh Source File\n \n \n \n \n \n \n \n@@ -62,439 +62,614 @@\n \n
    \n \n
    \n
    \n
    \n-
    solver.hh
    \n+
    umfpack.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5
    \n-
    6#ifndef DUNE_ISTL_SOLVER_HH
    \n-
    7#define DUNE_ISTL_SOLVER_HH
    \n-
    8
    \n-
    9#include <iomanip>
    \n-
    10#include <ostream>
    \n-
    11#include <string>
    \n-
    12#include <functional>
    \n-
    13
    \n-
    14#include <dune/common/exceptions.hh>
    \n-
    15#include <dune/common/shared_ptr.hh>
    \n-
    16#include <dune/common/simd/io.hh>
    \n-
    17#include <dune/common/simd/simd.hh>
    \n-
    18#include <dune/common/parametertree.hh>
    \n-
    19#include <dune/common/timer.hh>
    \n-
    20
    \n-
    21#include "solvertype.hh"
    \n-
    22#include "preconditioner.hh"
    \n-
    23#include "operators.hh"
    \n-
    24#include "scalarproducts.hh"
    \n+
    5#ifndef DUNE_ISTL_UMFPACK_HH
    \n+
    6#define DUNE_ISTL_UMFPACK_HH
    \n+
    7
    \n+
    8#if HAVE_SUITESPARSE_UMFPACK || defined DOXYGEN
    \n+
    9
    \n+
    10#include<complex>
    \n+
    11#include<type_traits>
    \n+
    12
    \n+
    13#include<umfpack.h>
    \n+
    14
    \n+
    15#include<dune/common/exceptions.hh>
    \n+
    16#include<dune/common/fmatrix.hh>
    \n+
    17#include<dune/common/fvector.hh>
    \n+\n+\n+\n+\n+\n+
    23
    \n+
    24
    \n
    25
    \n-
    26namespace Dune
    \n-
    27{
    \n-\n-
    48 {
    \n-\n-
    51 {
    \n-
    52 clear();
    \n-
    53 }
    \n-
    54
    \n-
    56 void clear ()
    \n-
    57 {
    \n-
    58 iterations = 0;
    \n-
    59 reduction = 0;
    \n-
    60 converged = false;
    \n-
    61 conv_rate = 1;
    \n-
    62 elapsed = 0;
    \n-\n-
    64 }
    \n-
    65
    \n-\n-
    68
    \n-
    70 double reduction;
    \n-
    71
    \n-\n-
    74
    \n-
    76 double conv_rate;
    \n-
    77
    \n-
    79 double condition_estimate = -1;
    \n-
    80
    \n-
    82 double elapsed;
    \n-
    83 };
    \n-
    84
    \n-
    85
    \n-
    86 //=====================================================================
    \n-
    98 template<class X, class Y>
    \n-\n-
    100 public:
    \n-
    102 typedef X domain_type;
    \n-
    103
    \n-
    105 typedef Y range_type;
    \n-
    106
    \n-
    108 typedef typename X::field_type field_type;
    \n+
    26namespace Dune {
    \n+
    38 // FORWARD DECLARATIONS
    \n+
    39 template<class M, class T, class TM, class TD, class TA>
    \n+
    40 class SeqOverlappingSchwarz;
    \n+
    41
    \n+
    42 template<class T, bool tag>
    \n+
    43 struct SeqOverlappingSchwarzAssemblerHelper;
    \n+
    44
    \n+
    45 // wrapper class for C-Function Calls in the backend. Choose the right function namespace
    \n+
    46 // depending on the template parameter used.
    \n+
    47 template<typename T>
    \n+\n+
    49 {
    \n+
    50 static constexpr bool valid = false ;
    \n+
    51 };
    \n+
    52
    \n+
    53 template<>
    \n+
    54 struct UMFPackMethodChooser<double>
    \n+
    55 {
    \n+
    56 static constexpr bool valid = true ;
    \n+
    57
    \n+
    58 template<typename... A>
    \n+
    59 static void defaults(A... args)
    \n+
    60 {
    \n+
    61 umfpack_dl_defaults(args...);
    \n+
    62 }
    \n+
    63 template<typename... A>
    \n+
    64 static void free_numeric(A... args)
    \n+
    65 {
    \n+
    66 umfpack_dl_free_numeric(args...);
    \n+
    67 }
    \n+
    68 template<typename... A>
    \n+
    69 static void free_symbolic(A... args)
    \n+
    70 {
    \n+
    71 umfpack_dl_free_symbolic(args...);
    \n+
    72 }
    \n+
    73 template<typename... A>
    \n+
    74 static int load_numeric(A... args)
    \n+
    75 {
    \n+
    76 return umfpack_dl_load_numeric(args...);
    \n+
    77 }
    \n+
    78 template<typename... A>
    \n+
    79 static void numeric(A... args)
    \n+
    80 {
    \n+
    81 umfpack_dl_numeric(args...);
    \n+
    82 }
    \n+
    83 template<typename... A>
    \n+
    84 static void report_info(A... args)
    \n+
    85 {
    \n+
    86 umfpack_dl_report_info(args...);
    \n+
    87 }
    \n+
    88 template<typename... A>
    \n+
    89 static void report_status(A... args)
    \n+
    90 {
    \n+
    91 umfpack_dl_report_status(args...);
    \n+
    92 }
    \n+
    93 template<typename... A>
    \n+
    94 static int save_numeric(A... args)
    \n+
    95 {
    \n+
    96 return umfpack_dl_save_numeric(args...);
    \n+
    97 }
    \n+
    98 template<typename... A>
    \n+
    99 static void solve(A... args)
    \n+
    100 {
    \n+
    101 umfpack_dl_solve(args...);
    \n+
    102 }
    \n+
    103 template<typename... A>
    \n+
    104 static void symbolic(A... args)
    \n+
    105 {
    \n+
    106 umfpack_dl_symbolic(args...);
    \n+
    107 }
    \n+
    108 };
    \n
    109
    \n-
    111 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-
    112
    \n-
    114 typedef Simd::Scalar<real_type> scalar_real_type;
    \n-
    115
    \n-
    128 virtual void apply (X& x, Y& b, InverseOperatorResult& res) = 0;
    \n-
    129
    \n-
    143 virtual void apply (X& x, Y& b, double reduction, InverseOperatorResult& res) = 0;
    \n-
    144
    \n-\n-
    147#ifdef DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n-
    148 {
    \n-
    149 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n-
    150 }
    \n-
    151#else
    \n-
    152 = 0;
    \n-
    153#endif
    \n-
    154
    \n-
    156 virtual ~InverseOperator () {}
    \n-
    157
    \n-
    158 protected:
    \n-
    159 // spacing values
    \n-
    160 enum { iterationSpacing = 5 , normSpacing = 16 };
    \n-
    161
    \n-
    163 void printHeader(std::ostream& s) const
    \n-
    164 {
    \n-
    165 s << std::setw(iterationSpacing) << " Iter";
    \n-
    166 s << std::setw(normSpacing) << "Defect";
    \n-
    167 s << std::setw(normSpacing) << "Rate" << std::endl;
    \n-
    168 }
    \n-
    169
    \n-
    171 template <typename CountType, typename DataType>
    \n-
    172 void printOutput(std::ostream& s,
    \n-
    173 const CountType& iter,
    \n-
    174 const DataType& norm,
    \n-
    175 const DataType& norm_old) const
    \n-
    176 {
    \n-
    177 const DataType rate = norm/norm_old;
    \n-
    178 s << std::setw(iterationSpacing) << iter << " ";
    \n-
    179 s << std::setw(normSpacing) << Simd::io(norm) << " ";
    \n-
    180 s << std::setw(normSpacing) << Simd::io(rate) << std::endl;
    \n-
    181 }
    \n-
    182
    \n-
    184 template <typename CountType, typename DataType>
    \n-
    185 void printOutput(std::ostream& s,
    \n-
    186 const CountType& iter,
    \n-
    187 const DataType& norm) const
    \n-
    188 {
    \n-
    189 s << std::setw(iterationSpacing) << iter << " ";
    \n-
    190 s << std::setw(normSpacing) << Simd::io(norm) << std::endl;
    \n-
    191 }
    \n-
    192 };
    \n-
    193
    \n-
    202 template<class X, class Y>
    \n-
    203 class IterativeSolver : public InverseOperator<X,Y>{
    \n-
    204 public:
    \n-\n-\n-\n-
    208 using typename InverseOperator<X,Y>::real_type;
    \n-\n-
    210
    \n-
    230 IterativeSolver (const LinearOperator<X,Y>& op, Preconditioner<X,Y>& prec, scalar_real_type reduction, int maxit, int verbose) :
    \n-
    231 _op(stackobject_to_shared_ptr(op)),
    \n-
    232 _prec(stackobject_to_shared_ptr(prec)),
    \n-
    233 _sp(new SeqScalarProduct<X>),
    \n-
    234 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category(SolverCategory::sequential)
    \n-
    235 {
    \n-\n-
    237 DUNE_THROW(InvalidSolverCategory, "LinearOperator has to be sequential!");
    \n-\n-
    239 DUNE_THROW(InvalidSolverCategory, "Preconditioner has to be sequential!");
    \n-
    240 }
    \n-
    241
    \n-\n-
    263 scalar_real_type reduction, int maxit, int verbose) :
    \n-
    264 _op(stackobject_to_shared_ptr(op)),
    \n-
    265 _prec(stackobject_to_shared_ptr(prec)),
    \n-
    266 _sp(stackobject_to_shared_ptr(sp)),
    \n-
    267 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category(SolverCategory::category(op))
    \n-
    268 {
    \n-\n-
    270 DUNE_THROW(InvalidSolverCategory, "LinearOperator and Preconditioner must have the same SolverCategory!");
    \n-\n-
    272 DUNE_THROW(InvalidSolverCategory, "LinearOperator and ScalarProduct must have the same SolverCategory!");
    \n-
    273 }
    \n-
    274
    \n-
    290 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    291 IterativeSolver(op,std::make_shared<SeqScalarProduct<X>>(),prec,
    \n-
    292 configuration.get<real_type>("reduction"),
    \n-
    293 configuration.get<int>("maxit"),
    \n-
    294 configuration.get<int>("verbose"))
    \n-
    295 {}
    \n-
    296
    \n-
    313 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    314 IterativeSolver(op,sp,prec,
    \n-
    315 configuration.get<scalar_real_type>("reduction"),
    \n-
    316 configuration.get<int>("maxit"),
    \n-
    317 configuration.get<int>("verbose"))
    \n-
    318 {}
    \n-
    319
    \n-
    340 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y>> op,
    \n-
    341 std::shared_ptr<const ScalarProduct<X>> sp,
    \n-
    342 std::shared_ptr<Preconditioner<X,Y>> prec,
    \n-
    343 scalar_real_type reduction, int maxit, int verbose) :
    \n-
    344 _op(op),
    \n-
    345 _prec(prec),
    \n-
    346 _sp(sp),
    \n-
    347 _reduction(reduction), _maxit(maxit), _verbose(verbose),
    \n-\n-
    349 {
    \n-\n-
    351 DUNE_THROW(InvalidSolverCategory, "LinearOperator and Preconditioner must have the same SolverCategory!");
    \n-\n-
    353 DUNE_THROW(InvalidSolverCategory, "LinearOperator and ScalarProduct must have the same SolverCategory!");
    \n-
    354 }
    \n-
    355
    \n-
    356 // #warning actually we want to have this as the default and just implement the second one
    \n-
    357 // //! \\copydoc InverseOperator::apply(X&,Y&,InverseOperatorResult&)
    \n-
    358 // virtual void apply (X& x, Y& b, InverseOperatorResult& res)
    \n-
    359 // {
    \n-
    360 // apply(x,b,_reduction,res);
    \n-
    361 // }
    \n-
    362
    \n-
    363#ifndef DOXYGEN
    \n-
    364 // make sure the three-argument apply from the base class does not get shadowed
    \n-
    365 // by the redefined four-argument version below
    \n-
    366 using InverseOperator<X,Y>::apply;
    \n-
    367#endif
    \n-
    368
    \n-
    374 virtual void apply (X& x, X& b, double reduction, InverseOperatorResult& res)
    \n-
    375 {
    \n-
    376 scalar_real_type saved_reduction = _reduction;
    \n-
    377 _reduction = reduction;
    \n-
    378 this->apply(x,b,res);
    \n-
    379 _reduction = saved_reduction;
    \n-
    380 }
    \n-
    381
    \n-\n-
    384 {
    \n-
    385 return _category;
    \n-
    386 }
    \n-
    387
    \n-
    388 std::string name() const{
    \n-
    389 std::string name = className(*this);
    \n-
    390 return name.substr(0, name.find("<"));
    \n-
    391 }
    \n-
    392
    \n-
    410 template<class CountType = unsigned int>
    \n-
    411 class Iteration {
    \n-
    412 public:
    \n-\n-
    414 : _i(0)
    \n-
    415 , _res(res)
    \n-
    416 , _parent(parent)
    \n-
    417 , _valid(true)
    \n-
    418 {
    \n-
    419 res.clear();
    \n-
    420 if(_parent._verbose>0){
    \n-
    421 std::cout << "=== " << parent.name() << std::endl;
    \n-
    422 if(_parent._verbose > 1)
    \n-
    423 _parent.printHeader(std::cout);
    \n-
    424 }
    \n-
    425 }
    \n-
    426
    \n-
    427 Iteration(const Iteration&) = delete;
    \n-\n-
    429 : _def0(other._def0)
    \n-
    430 , _def(other._def)
    \n-
    431 , _i(other._i)
    \n-
    432 , _watch(other._watch)
    \n-
    433 , _res(other._res)
    \n-
    434 , _parent(other._parent)
    \n-
    435 , _valid(other._valid)
    \n-
    436 {
    \n-
    437 other._valid = false;
    \n-
    438 }
    \n-
    439
    \n-\n-
    441 if(_valid)
    \n-
    442 finalize();
    \n-
    443 }
    \n-
    444
    \n-
    455 bool step(CountType i, real_type def){
    \n-
    456 if (!Simd::allTrue(isFinite(def))) // check for inf or NaN
    \n-
    457 {
    \n-
    458 if (_parent._verbose>0)
    \n-
    459 std::cout << "=== " << _parent.name() << ": abort due to infinite or NaN defect"
    \n-
    460 << std::endl;
    \n-
    461 DUNE_THROW(SolverAbort,
    \n-
    462 _parent.name() << ": defect=" << Simd::io(def)
    \n-
    463 << " is infinite or NaN");
    \n-
    464 }
    \n-
    465 if(i == 0)
    \n-
    466 _def0 = def;
    \n-
    467 if(_parent._verbose > 1){
    \n-
    468 if(i!=0)
    \n-
    469 _parent.printOutput(std::cout,i,def,_def);
    \n-
    470 else
    \n-
    471 _parent.printOutput(std::cout,i,def);
    \n-
    472 }
    \n-
    473 _def = def;
    \n-
    474 _i = i;
    \n-
    475 _res.converged = (Simd::allTrue(def<_def0*_parent._reduction || def<real_type(1E-30))); // convergence check
    \n-
    476 return _res.converged;
    \n-
    477 }
    \n-
    478
    \n-
    479 protected:
    \n-
    480 void finalize(){
    \n-
    481 _res.converged = (Simd::allTrue(_def<_def0*_parent._reduction || _def<real_type(1E-30)));
    \n-\n-
    483 _res.reduction = static_cast<double>(Simd::max(_def/_def0));
    \n-
    484 _res.conv_rate = pow(_res.reduction,1.0/_i);
    \n-
    485 _res.elapsed = _watch.elapsed();
    \n-
    486 if (_parent._verbose>0) // final print
    \n-
    487 {
    \n-
    488 std::cout << "=== rate=" << _res.conv_rate
    \n-
    489 << ", T=" << _res.elapsed
    \n-
    490 << ", TIT=" << _res.elapsed/_res.iterations
    \n-
    491 << ", IT=" << _res.iterations << std::endl;
    \n-
    492 }
    \n-
    493 }
    \n-
    494
    \n-
    495 real_type _def0 = 0.0, _def = 0.0;
    \n-
    496 CountType _i;
    \n-
    497 Timer _watch;
    \n-\n-\n-
    500 bool _valid;
    \n-
    501 };
    \n-
    502
    \n-
    503 protected:
    \n-
    504 std::shared_ptr<const LinearOperator<X,Y>> _op;
    \n-
    505 std::shared_ptr<Preconditioner<X,Y>> _prec;
    \n-
    506 std::shared_ptr<const ScalarProduct<X>> _sp;
    \n-\n-\n-\n-\n-
    511 };
    \n-
    512
    \n-
    520 template <typename ISTLLinearSolver, typename BCRSMatrix>
    \n-\n-
    522 {
    \n-
    523 public:
    \n-
    524 static void setMatrix (ISTLLinearSolver& solver,
    \n-
    525 const BCRSMatrix& matrix)
    \n-
    526 {
    \n-
    527 static const bool is_direct_solver
    \n-\n-\n-\n-
    531 }
    \n-
    532
    \n-
    533 protected:
    \n-
    538 template <bool is_direct_solver, typename Dummy = void>
    \n-\n-
    540 {
    \n-
    541 static void setMatrix (ISTLLinearSolver&,
    \n-
    542 const BCRSMatrix&)
    \n-
    543 {}
    \n-
    544 };
    \n-
    545
    \n-
    550 template <typename Dummy>
    \n-
    551 struct Implementation<true,Dummy>
    \n-
    552 {
    \n-
    553 static void setMatrix (ISTLLinearSolver& solver,
    \n-
    554 const BCRSMatrix& matrix)
    \n-
    555 {
    \n-
    556 solver.setMatrix(matrix);
    \n-
    557 }
    \n-
    558 };
    \n-
    559 };
    \n-
    560
    \n-
    564}
    \n-
    565
    \n-
    566#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Templates characterizing the type of a solver.
    \n-\n-
    Define base class for scalar product and norm.
    \n+
    110 template<>
    \n+
    111 struct UMFPackMethodChooser<std::complex<double> >
    \n+
    112 {
    \n+
    113 static constexpr bool valid = true ;
    \n+
    114
    \n+
    115 template<typename... A>
    \n+
    116 static void defaults(A... args)
    \n+
    117 {
    \n+
    118 umfpack_zl_defaults(args...);
    \n+
    119 }
    \n+
    120 template<typename... A>
    \n+
    121 static void free_numeric(A... args)
    \n+
    122 {
    \n+
    123 umfpack_zl_free_numeric(args...);
    \n+
    124 }
    \n+
    125 template<typename... A>
    \n+
    126 static void free_symbolic(A... args)
    \n+
    127 {
    \n+
    128 umfpack_zl_free_symbolic(args...);
    \n+
    129 }
    \n+
    130 template<typename... A>
    \n+
    131 static int load_numeric(A... args)
    \n+
    132 {
    \n+
    133 return umfpack_zl_load_numeric(args...);
    \n+
    134 }
    \n+
    135 template<typename... A>
    \n+
    136 static void numeric(const long int* cs, const long int* ri, const double* val, A... args)
    \n+
    137 {
    \n+
    138 umfpack_zl_numeric(cs,ri,val,NULL,args...);
    \n+
    139 }
    \n+
    140 template<typename... A>
    \n+
    141 static void report_info(A... args)
    \n+
    142 {
    \n+
    143 umfpack_zl_report_info(args...);
    \n+
    144 }
    \n+
    145 template<typename... A>
    \n+
    146 static void report_status(A... args)
    \n+
    147 {
    \n+
    148 umfpack_zl_report_status(args...);
    \n+
    149 }
    \n+
    150 template<typename... A>
    \n+
    151 static int save_numeric(A... args)
    \n+
    152 {
    \n+
    153 return umfpack_zl_save_numeric(args...);
    \n+
    154 }
    \n+
    155 template<typename... A>
    \n+
    156 static void solve(long int m, const long int* cs, const long int* ri, std::complex<double>* val, double* x, const double* b,A... args)
    \n+
    157 {
    \n+
    158 const double* cval = reinterpret_cast<const double*>(val);
    \n+
    159 umfpack_zl_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);
    \n+
    160 }
    \n+
    161 template<typename... A>
    \n+
    162 static void symbolic(long int m, long int n, const long int* cs, const long int* ri, const double* val, A... args)
    \n+
    163 {
    \n+
    164 umfpack_zl_symbolic(m,n,cs,ri,val,NULL,args...);
    \n+
    165 }
    \n+
    166 };
    \n+
    167
    \n+
    168 namespace Impl
    \n+
    169 {
    \n+
    170 template<class M>
    \n+
    171 struct UMFPackVectorChooser
    \n+
    172 {};
    \n+
    173
    \n+
    174 template<typename T, typename A, int n, int m>
    \n+
    175 struct UMFPackVectorChooser<BCRSMatrix<FieldMatrix<T,n,m>,A > >
    \n+
    176 {
    \n+
    178 using domain_type = BlockVector<
    \n+
    179 FieldVector<T,m>,
    \n+
    180 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,m> > >;
    \n+
    182 using range_type = BlockVector<
    \n+
    183 FieldVector<T,n>,
    \n+
    184 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,n> > >;
    \n+
    185 };
    \n+
    186
    \n+
    187 template<typename T, typename A>
    \n+
    188 struct UMFPackVectorChooser<BCRSMatrix<T,A> >
    \n+
    189 {
    \n+
    191 using domain_type = BlockVector<T, A>;
    \n+
    193 using range_type = BlockVector<T, A>;
    \n+
    194 };
    \n+
    195 }
    \n+
    196
    \n+
    210 template<typename M>
    \n+\n+
    212 : public InverseOperator<
    \n+
    213 typename Impl::UMFPackVectorChooser<M>::domain_type,
    \n+
    214 typename Impl::UMFPackVectorChooser<M>::range_type >
    \n+
    215 {
    \n+
    216 using T = typename M::field_type;
    \n+
    217
    \n+
    218 public:
    \n+
    220 using Matrix = M;
    \n+
    221 using matrix_type = M;
    \n+
    223 typedef ISTL::Impl::BCCSMatrix<typename Matrix::field_type, long int> UMFPackMatrix;
    \n+
    225 typedef ISTL::Impl::BCCSMatrixInitializer<M, long int> MatrixInitializer;
    \n+
    227 using domain_type = typename Impl::UMFPackVectorChooser<M>::domain_type;
    \n+
    229 using range_type = typename Impl::UMFPackVectorChooser<M>::range_type;
    \n+
    230
    \n+\n+
    233 {
    \n+
    234 return SolverCategory::Category::sequential;
    \n+
    235 }
    \n+
    236
    \n+
    245 UMFPack(const Matrix& matrix, int verbose=0) : matrixIsLoaded_(false)
    \n+
    246 {
    \n+
    247 //check whether T is a supported type
    \n+
    248 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n+
    249 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    250 Caller::defaults(UMF_Control);
    \n+
    251 setVerbosity(verbose);
    \n+
    252 setMatrix(matrix);
    \n+
    253 }
    \n+
    254
    \n+
    263 UMFPack(const Matrix& matrix, int verbose, bool) : matrixIsLoaded_(false)
    \n+
    264 {
    \n+
    265 //check whether T is a supported type
    \n+
    266 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n+
    267 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    268 Caller::defaults(UMF_Control);
    \n+
    269 setVerbosity(verbose);
    \n+
    270 setMatrix(matrix);
    \n+
    271 }
    \n+
    272
    \n+
    282 UMFPack(const Matrix& mat_, const ParameterTree& config)
    \n+
    283 : UMFPack(mat_, config.get<int>("verbose", 0))
    \n+
    284 {}
    \n+
    285
    \n+
    288 UMFPack() : matrixIsLoaded_(false), verbosity_(0)
    \n+
    289 {
    \n+
    290 //check whether T is a supported type
    \n+
    291 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n+
    292 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    293 Caller::defaults(UMF_Control);
    \n+
    294 }
    \n+
    295
    \n+
    306 UMFPack(const Matrix& mat_, const char* file, int verbose=0)
    \n+
    307 {
    \n+
    308 //check whether T is a supported type
    \n+
    309 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n+
    310 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    311 Caller::defaults(UMF_Control);
    \n+
    312 setVerbosity(verbose);
    \n+
    313 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast<char*>(file));
    \n+
    314 if ((errcode == UMFPACK_ERROR_out_of_memory) || (errcode == UMFPACK_ERROR_file_IO))
    \n+
    315 {
    \n+
    316 matrixIsLoaded_ = false;
    \n+
    317 setMatrix(mat_);
    \n+
    318 saveDecomposition(file);
    \n+
    319 }
    \n+
    320 else
    \n+
    321 {
    \n+
    322 matrixIsLoaded_ = true;
    \n+
    323 std::cout << "UMFPack decomposition successfully loaded from " << file << std::endl;
    \n+
    324 }
    \n+
    325 }
    \n+
    326
    \n+
    333 UMFPack(const char* file, int verbose=0)
    \n+
    334 {
    \n+
    335 //check whether T is a supported type
    \n+
    336 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n+
    337 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    338 Caller::defaults(UMF_Control);
    \n+
    339 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast<char*>(file));
    \n+
    340 if (errcode == UMFPACK_ERROR_out_of_memory)
    \n+
    341 DUNE_THROW(Dune::Exception, "ran out of memory while loading UMFPack decomposition");
    \n+
    342 if (errcode == UMFPACK_ERROR_file_IO)
    \n+
    343 DUNE_THROW(Dune::Exception, "IO error while loading UMFPack decomposition");
    \n+
    344 matrixIsLoaded_ = true;
    \n+
    345 std::cout << "UMFPack decomposition successfully loaded from " << file << std::endl;
    \n+
    346 setVerbosity(verbose);
    \n+
    347 }
    \n+
    348
    \n+
    349 virtual ~UMFPack()
    \n+
    350 {
    \n+
    351 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n+
    352 free();
    \n+
    353 }
    \n+
    354
    \n+\n+
    359 {
    \n+
    360 if (umfpackMatrix_.N() != b.dim())
    \n+
    361 DUNE_THROW(Dune::ISTLError, "Size of right-hand-side vector b does not match the number of matrix rows!");
    \n+
    362 if (umfpackMatrix_.M() != x.dim())
    \n+
    363 DUNE_THROW(Dune::ISTLError, "Size of solution vector x does not match the number of matrix columns!");
    \n+
    364 if (b.size() == 0)
    \n+
    365 return;
    \n+
    366
    \n+
    367 double UMF_Apply_Info[UMFPACK_INFO];
    \n+
    368 Caller::solve(UMFPACK_A,
    \n+
    369 umfpackMatrix_.getColStart(),
    \n+
    370 umfpackMatrix_.getRowIndex(),
    \n+
    371 umfpackMatrix_.getValues(),
    \n+
    372 reinterpret_cast<double*>(&x[0]),
    \n+
    373 reinterpret_cast<double*>(&b[0]),
    \n+
    374 UMF_Numeric,
    \n+
    375 UMF_Control,
    \n+
    376 UMF_Apply_Info);
    \n+
    377
    \n+
    378 //this is a direct solver
    \n+
    379 res.iterations = 1;
    \n+
    380 res.converged = true;
    \n+
    381 res.elapsed = UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME];
    \n+
    382
    \n+
    383 printOnApply(UMF_Apply_Info);
    \n+
    384 }
    \n+
    385
    \n+
    389 virtual void apply (domain_type& x, range_type& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n+
    390 {
    \n+
    391 apply(x,b,res);
    \n+
    392 }
    \n+
    393
    \n+
    399 void apply(T* x, T* b)
    \n+
    400 {
    \n+
    401 double UMF_Apply_Info[UMFPACK_INFO];
    \n+
    402 Caller::solve(UMFPACK_A,
    \n+
    403 umfpackMatrix_.getColStart(),
    \n+
    404 umfpackMatrix_.getRowIndex(),
    \n+
    405 umfpackMatrix_.getValues(),
    \n+
    406 x,
    \n+
    407 b,
    \n+
    408 UMF_Numeric,
    \n+
    409 UMF_Control,
    \n+
    410 UMF_Apply_Info);
    \n+
    411 printOnApply(UMF_Apply_Info);
    \n+
    412 }
    \n+
    413
    \n+
    425 void setOption(unsigned int option, double value)
    \n+
    426 {
    \n+
    427 if (option >= UMFPACK_CONTROL)
    \n+
    428 DUNE_THROW(RangeError, "Requested non-existing UMFPack option");
    \n+
    429
    \n+
    430 UMF_Control[option] = value;
    \n+
    431 }
    \n+
    432
    \n+
    436 void saveDecomposition(const char* file)
    \n+
    437 {
    \n+
    438 int errcode = Caller::save_numeric(UMF_Numeric, const_cast<char*>(file));
    \n+
    439 if (errcode != UMFPACK_OK)
    \n+
    440 DUNE_THROW(Dune::Exception,"IO ERROR while trying to save UMFPack decomposition");
    \n+
    441 }
    \n+
    442
    \n+
    444 void setMatrix(const Matrix& matrix)
    \n+
    445 {
    \n+
    446 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n+
    447 free();
    \n+
    448 if (matrix.N() == 0 or matrix.M() == 0)
    \n+
    449 return;
    \n+
    450
    \n+
    451 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes() != 0)
    \n+
    452 umfpackMatrix_.free();
    \n+
    453 umfpackMatrix_.setSize(MatrixDimension<Matrix>::rowdim(matrix),
    \n+\n+
    455 ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
    \n+
    456
    \n+
    457 copyToBCCSMatrix(initializer, matrix);
    \n+
    458
    \n+
    459 decompose();
    \n+
    460 }
    \n+
    461
    \n+
    462 template<class S>
    \n+
    463 void setSubMatrix(const Matrix& _mat, const S& rowIndexSet)
    \n+
    464 {
    \n+
    465 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n+
    466 free();
    \n+
    467
    \n+
    468 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes() != 0)
    \n+
    469 umfpackMatrix_.free();
    \n+
    470
    \n+
    471 umfpackMatrix_.setSize(rowIndexSet.size()*MatrixDimension<Matrix>::rowdim(_mat) / _mat.N(),
    \n+
    472 rowIndexSet.size()*MatrixDimension<Matrix>::coldim(_mat) / _mat.M());
    \n+
    473 ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
    \n+
    474
    \n+
    475 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset<Matrix,std::set<std::size_t> >(_mat,rowIndexSet));
    \n+
    476
    \n+
    477 decompose();
    \n+
    478 }
    \n+
    479
    \n+
    487 void setVerbosity(int v)
    \n+
    488 {
    \n+
    489 verbosity_ = v;
    \n+
    490 // set the verbosity level in UMFPack
    \n+
    491 if (verbosity_ == 0)
    \n+
    492 UMF_Control[UMFPACK_PRL] = 1;
    \n+
    493 if (verbosity_ == 1)
    \n+
    494 UMF_Control[UMFPACK_PRL] = 2;
    \n+
    495 if (verbosity_ == 2)
    \n+
    496 UMF_Control[UMFPACK_PRL] = 4;
    \n+
    497 }
    \n+
    498
    \n+\n+
    504 {
    \n+
    505 return UMF_Numeric;
    \n+
    506 }
    \n+
    507
    \n+\n+
    513 {
    \n+
    514 return umfpackMatrix_;
    \n+
    515 }
    \n+
    516
    \n+
    521 void free()
    \n+
    522 {
    \n+
    523 if (!matrixIsLoaded_)
    \n+
    524 {
    \n+
    525 Caller::free_symbolic(&UMF_Symbolic);
    \n+
    526 umfpackMatrix_.free();
    \n+
    527 }
    \n+
    528 Caller::free_numeric(&UMF_Numeric);
    \n+
    529 matrixIsLoaded_ = false;
    \n+
    530 }
    \n+
    531
    \n+
    532 const char* name() { return "UMFPACK"; }
    \n+
    533
    \n+
    534 private:
    \n+
    535 typedef typename Dune::UMFPackMethodChooser<T> Caller;
    \n+
    536
    \n+
    537 template<class Mat,class X, class TM, class TD, class T1>
    \n+\n+\n+
    540
    \n+
    542 void decompose()
    \n+
    543 {
    \n+
    544 double UMF_Decomposition_Info[UMFPACK_INFO];
    \n+
    545 Caller::symbolic(static_cast<int>(umfpackMatrix_.N()),
    \n+
    546 static_cast<int>(umfpackMatrix_.N()),
    \n+
    547 umfpackMatrix_.getColStart(),
    \n+
    548 umfpackMatrix_.getRowIndex(),
    \n+
    549 reinterpret_cast<double*>(umfpackMatrix_.getValues()),
    \n+
    550 &UMF_Symbolic,
    \n+
    551 UMF_Control,
    \n+
    552 UMF_Decomposition_Info);
    \n+
    553 Caller::numeric(umfpackMatrix_.getColStart(),
    \n+
    554 umfpackMatrix_.getRowIndex(),
    \n+
    555 reinterpret_cast<double*>(umfpackMatrix_.getValues()),
    \n+
    556 UMF_Symbolic,
    \n+
    557 &UMF_Numeric,
    \n+
    558 UMF_Control,
    \n+
    559 UMF_Decomposition_Info);
    \n+
    560 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);
    \n+
    561 if (verbosity_ == 1)
    \n+
    562 {
    \n+
    563 std::cout << "[UMFPack Decomposition]" << std::endl;
    \n+
    564 std::cout << "Wallclock Time taken: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_WALLTIME] << " (CPU Time: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_TIME] << ")" << std::endl;
    \n+
    565 std::cout << "Flops taken: " << UMF_Decomposition_Info[UMFPACK_FLOPS] << std::endl;
    \n+
    566 std::cout << "Peak Memory Usage: " << UMF_Decomposition_Info[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT] << " bytes" << std::endl;
    \n+
    567 std::cout << "Condition number estimate: " << 1./UMF_Decomposition_Info[UMFPACK_RCOND] << std::endl;
    \n+
    568 std::cout << "Numbers of non-zeroes in decomposition: L: " << UMF_Decomposition_Info[UMFPACK_LNZ] << " U: " << UMF_Decomposition_Info[UMFPACK_UNZ] << std::endl;
    \n+
    569 }
    \n+
    570 if (verbosity_ == 2)
    \n+
    571 {
    \n+
    572 Caller::report_info(UMF_Control,UMF_Decomposition_Info);
    \n+
    573 }
    \n+
    574 }
    \n+
    575
    \n+
    576 void printOnApply(double* UMF_Info)
    \n+
    577 {
    \n+
    578 Caller::report_status(UMF_Control,UMF_Info[UMFPACK_STATUS]);
    \n+
    579 if (verbosity_ > 0)
    \n+
    580 {
    \n+
    581 std::cout << "[UMFPack Solve]" << std::endl;
    \n+
    582 std::cout << "Wallclock Time: " << UMF_Info[UMFPACK_SOLVE_WALLTIME] << " (CPU Time: " << UMF_Info[UMFPACK_SOLVE_TIME] << ")" << std::endl;
    \n+
    583 std::cout << "Flops Taken: " << UMF_Info[UMFPACK_SOLVE_FLOPS] << std::endl;
    \n+
    584 std::cout << "Iterative Refinement steps taken: " << UMF_Info[UMFPACK_IR_TAKEN] << std::endl;
    \n+
    585 std::cout << "Error Estimate: " << UMF_Info[UMFPACK_OMEGA1] << " resp. " << UMF_Info[UMFPACK_OMEGA2] << std::endl;
    \n+
    586 }
    \n+
    587 }
    \n+
    588
    \n+
    589 UMFPackMatrix umfpackMatrix_;
    \n+
    590 bool matrixIsLoaded_;
    \n+
    591 int verbosity_;
    \n+
    592 void *UMF_Symbolic;
    \n+
    593 void *UMF_Numeric;
    \n+
    594 double UMF_Control[UMFPACK_CONTROL];
    \n+
    595 };
    \n+
    596
    \n+
    597 template<typename T, typename A, int n, int m>
    \n+\n+
    599 {
    \n+
    600 enum { value=true};
    \n+
    601 };
    \n+
    602
    \n+
    603 template<typename T, typename A>
    \n+\n+
    605 {
    \n+
    606 enum { value = true };
    \n+
    607 };
    \n+
    608
    \n+\n+
    610 template<class F,class=void> struct isValidBlock : std::false_type{};
    \n+
    611 template<class B> struct isValidBlock<B, std::enable_if_t<std::is_same<typename FieldTraits<B>::real_type,double>::value>> : std::true_type {};
    \n+
    612
    \n+
    613 template<typename TL, typename M>
    \n+
    614 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n+
    615 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    616 operator() (TL /*tl*/, const M& mat, const Dune::ParameterTree& config,
    \n+
    617 std::enable_if_t<
    \n+
    618 isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n+
    619 {
    \n+
    620 int verbose = config.get("verbose", 0);
    \n+
    621 return std::make_shared<Dune::UMFPack<M>>(mat,verbose);
    \n+
    622 }
    \n+
    623
    \n+
    624 // second version with SFINAE to validate the template parameters of UMFPack
    \n+
    625 template<typename TL, typename M>
    \n+
    626 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n+
    627 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    628 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n+
    629 std::enable_if_t<
    \n+
    630 !isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n+
    631 {
    \n+
    632 DUNE_THROW(UnsupportedType,
    \n+
    633 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n+
    634 }
    \n+
    635 };
    \n+\n+
    637} // end namespace Dune
    \n+
    638
    \n+
    639#endif // HAVE_SUITESPARSE_UMFPACK
    \n+
    640
    \n+
    641#endif //DUNE_ISTL_UMFPACK_HH
    \n+
    Templates characterizing the type of a solver.
    \n+\n+
    Implementation of the BCRSMatrix class.
    \n+
    Implementations of the inverse operator interface.
    \n+\n+
    void free()
    free allocated space.
    Definition: umfpack.hh:521
    \n+
    virtual void apply(domain_type &x, range_type &b, InverseOperatorResult &res)
    Apply inverse operator,.
    Definition: umfpack.hh:358
    \n+
    virtual SolverCategory::Category category() const
    Category of the solver (see SolverCategory::Category)
    Definition: umfpack.hh:232
    \n+
    M matrix_type
    Definition: umfpack.hh:221
    \n+
    static void solve(long int m, const long int *cs, const long int *ri, std::complex< double > *val, double *x, const double *b, A... args)
    Definition: umfpack.hh:156
    \n+
    void setMatrix(const Matrix &matrix)
    Initialize data from given matrix.
    Definition: umfpack.hh:444
    \n+
    static void report_info(A... args)
    Definition: umfpack.hh:141
    \n+
    UMFPack(const Matrix &mat_, const ParameterTree &config)
    Construct a solver object from a matrix.
    Definition: umfpack.hh:282
    \n+
    static int load_numeric(A... args)
    Definition: umfpack.hh:131
    \n+
    static int load_numeric(A... args)
    Definition: umfpack.hh:74
    \n+
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
    Definition: umfpack.hh:616
    \n+
    ISTL::Impl::BCCSMatrix< typename Matrix::field_type, long int > UMFPackMatrix
    The corresponding UMFPack matrix type.
    Definition: umfpack.hh:223
    \n+
    static void report_status(A... args)
    Definition: umfpack.hh:89
    \n+
    UMFPack(const Matrix &mat_, const char *file, int verbose=0)
    Try loading a decomposition from file and do a decomposition if unsuccessful.
    Definition: umfpack.hh:306
    \n+
    typename Impl::UMFPackVectorChooser< M >::range_type range_type
    The type of the range of the solver.
    Definition: umfpack.hh:229
    \n+
    DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
    \n+
    UMFPack()
    default constructor
    Definition: umfpack.hh:288
    \n+
    static void symbolic(A... args)
    Definition: umfpack.hh:104
    \n+
    static void report_info(A... args)
    Definition: umfpack.hh:84
    \n+
    static void symbolic(long int m, long int n, const long int *cs, const long int *ri, const double *val, A... args)
    Definition: umfpack.hh:162
    \n+
    static void free_symbolic(A... args)
    Definition: umfpack.hh:69
    \n+
    static int save_numeric(A... args)
    Definition: umfpack.hh:151
    \n+
    static void free_numeric(A... args)
    Definition: umfpack.hh:121
    \n+
    void setSubMatrix(const Matrix &_mat, const S &rowIndexSet)
    Definition: umfpack.hh:463
    \n+
    static int save_numeric(A... args)
    Definition: umfpack.hh:94
    \n+
    static void report_status(A... args)
    Definition: umfpack.hh:146
    \n+
    ISTL::Impl::BCCSMatrixInitializer< M, long int > MatrixInitializer
    Type of an associated initializer class.
    Definition: umfpack.hh:225
    \n+
    void apply(T *x, T *b)
    additional apply method with c-arrays in analogy to superlu
    Definition: umfpack.hh:399
    \n+
    static void defaults(A... args)
    Definition: umfpack.hh:116
    \n+
    static void free_numeric(A... args)
    Definition: umfpack.hh:64
    \n+
    void setVerbosity(int v)
    sets the verbosity level for the UMFPack solver
    Definition: umfpack.hh:487
    \n+
    UMFPack(const char *file, int verbose=0)
    try loading a decomposition from file
    Definition: umfpack.hh:333
    \n+
    static void numeric(A... args)
    Definition: umfpack.hh:79
    \n+
    static constexpr bool valid
    Definition: umfpack.hh:50
    \n+
    virtual ~UMFPack()
    Definition: umfpack.hh:349
    \n+
    const char * name()
    Definition: umfpack.hh:532
    \n+
    void saveDecomposition(const char *file)
    saves a decomposition to a file
    Definition: umfpack.hh:436
    \n+
    UMFPackMatrix & getInternalMatrix()
    Return the column compress matrix from UMFPack.
    Definition: umfpack.hh:512
    \n+
    typename Impl::UMFPackVectorChooser< M >::domain_type domain_type
    The type of the domain of the solver.
    Definition: umfpack.hh:227
    \n+
    UMFPack(const Matrix &matrix, int verbose=0)
    Construct a solver object from a matrix.
    Definition: umfpack.hh:245
    \n+
    virtual void apply(domain_type &x, range_type &b, double reduction, InverseOperatorResult &res)
    apply inverse operator, with given convergence criteria.
    Definition: umfpack.hh:389
    \n+
    void setOption(unsigned int option, double value)
    Set UMFPack-specific options.
    Definition: umfpack.hh:425
    \n+
    static void free_symbolic(A... args)
    Definition: umfpack.hh:126
    \n+
    M Matrix
    The matrix type.
    Definition: umfpack.hh:220
    \n+
    static void numeric(const long int *cs, const long int *ri, const double *val, A... args)
    Definition: umfpack.hh:136
    \n+
    static void defaults(A... args)
    Definition: umfpack.hh:59
    \n+
    static void solve(A... args)
    Definition: umfpack.hh:99
    \n+
    UMFPack(const Matrix &matrix, int verbose, bool)
    Constructor for compatibility with SuperLU standard constructor.
    Definition: umfpack.hh:263
    \n+
    void * getFactorization()
    Return the matrix factorization.
    Definition: umfpack.hh:503
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    Definition: matrixutils.hh:211
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    Thrown when a solver aborts due to some problem.
    Definition: istlexception.hh:46
    \n-
    A linear operator.
    Definition: operators.hh:67
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n-
    Default implementation for the scalar case.
    Definition: scalarproducts.hh:168
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n+
    Definition: overlappingschwarz.hh:694
    \n+
    Definition: matrixutils.hh:27
    \n
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    InverseOperatorResult()
    Default constructor.
    Definition: solver.hh:50
    \n-
    double condition_estimate
    Estimate of condition number.
    Definition: solver.hh:79
    \n
    double elapsed
    Elapsed time in seconds.
    Definition: solver.hh:82
    \n
    int iterations
    Number of iterations.
    Definition: solver.hh:67
    \n-
    double reduction
    Reduction achieved: .
    Definition: solver.hh:70
    \n-
    void clear()
    Resets all data.
    Definition: solver.hh:56
    \n-
    double conv_rate
    Convergence rate (average reduction per step)
    Definition: solver.hh:76
    \n
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n-
    void printHeader(std::ostream &s) const
    helper function for printing header of solver output
    Definition: solver.hh:163
    \n-
    virtual ~InverseOperator()
    Destructor.
    Definition: solver.hh:156
    \n-
    void printOutput(std::ostream &s, const CountType &iter, const DataType &norm) const
    helper function for printing solver output
    Definition: solver.hh:185
    \n-
    void printOutput(std::ostream &s, const CountType &iter, const DataType &norm, const DataType &norm_old) const
    helper function for printing solver output
    Definition: solver.hh:172
    \n-
    virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)=0
    apply inverse operator, with given convergence criteria.
    \n-
    Simd::Scalar< real_type > scalar_real_type
    scalar type underlying the field_type
    Definition: solver.hh:114
    \n-
    Y range_type
    Type of the range of the operator to be inverted.
    Definition: solver.hh:105
    \n-
    @ normSpacing
    Definition: solver.hh:160
    \n-
    @ iterationSpacing
    Definition: solver.hh:160
    \n-
    X domain_type
    Type of the domain of the operator to be inverted.
    Definition: solver.hh:102
    \n-
    virtual void apply(X &x, Y &b, InverseOperatorResult &res)=0
    Apply inverse operator,.
    \n-
    X::field_type field_type
    The field type of the operator.
    Definition: solver.hh:108
    \n-
    FieldTraits< field_type >::real_type real_type
    The real type of the field type (is the same if using real numbers, but differs for std::complex)
    Definition: solver.hh:111
    \n-
    virtual SolverCategory::Category category() const =0
    Category of the solver (see SolverCategory::Category)
    \n-
    Base class for all implementations of iterative solvers.
    Definition: solver.hh:203
    \n-
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solver.hh:313
    \n-
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solver.hh:290
    \n-
    virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)
    Apply inverse operator with given reduction factor.
    Definition: solver.hh:374
    \n-
    std::shared_ptr< const ScalarProduct< X > > _sp
    Definition: solver.hh:506
    \n-
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, Y > > prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:340
    \n-
    std::string name() const
    Definition: solver.hh:388
    \n-
    IterativeSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:230
    \n-
    std::shared_ptr< const LinearOperator< X, Y > > _op
    Definition: solver.hh:504
    \n-
    int _maxit
    Definition: solver.hh:508
    \n-
    int _verbose
    Definition: solver.hh:509
    \n-
    scalar_real_type _reduction
    Definition: solver.hh:507
    \n-
    IterativeSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:262
    \n-
    SolverCategory::Category _category
    Definition: solver.hh:510
    \n-
    std::shared_ptr< Preconditioner< X, Y > > _prec
    Definition: solver.hh:505
    \n-
    virtual SolverCategory::Category category() const
    Category of the solver (see SolverCategory::Category)
    Definition: solver.hh:383
    \n-
    Class for controlling iterative methods.
    Definition: solver.hh:411
    \n-
    Iteration(const IterativeSolver &parent, InverseOperatorResult &res)
    Definition: solver.hh:413
    \n-
    Iteration(Iteration &&other)
    Definition: solver.hh:428
    \n-
    InverseOperatorResult & _res
    Definition: solver.hh:498
    \n-
    const IterativeSolver & _parent
    Definition: solver.hh:499
    \n-
    Timer _watch
    Definition: solver.hh:497
    \n-
    Iteration(const Iteration &)=delete
    \n-
    CountType _i
    Definition: solver.hh:496
    \n-
    real_type _def0
    Definition: solver.hh:495
    \n-
    bool step(CountType i, real_type def)
    registers the iteration step, checks for invalid defect norm and convergence.
    Definition: solver.hh:455
    \n-
    void finalize()
    Definition: solver.hh:480
    \n-
    real_type _def
    Definition: solver.hh:495
    \n-
    ~Iteration()
    Definition: solver.hh:440
    \n-
    bool _valid
    Definition: solver.hh:500
    \n-
    Helper class for notifying a DUNE-ISTL linear solver about a change of the iteration matrix object in...
    Definition: solver.hh:522
    \n-
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:524
    \n-
    Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTAB...
    Definition: solver.hh:540
    \n-
    static void setMatrix(ISTLLinearSolver &, const BCRSMatrix &)
    Definition: solver.hh:541
    \n-
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:553
    \n-
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n-
    Definition: solvercategory.hh:54
    \n+
    Definition: solverregistry.hh:77
    \n
    Definition: solvertype.hh:16
    \n+
    @ value
    Whether this is a direct solver.
    Definition: solvertype.hh:24
    \n+
    Definition: solvertype.hh:30
    \n+
    @ value
    whether the solver internally uses column compressed storage
    Definition: solvertype.hh:36
    \n+
    Definition: umfpack.hh:49
    \n+
    The UMFPack direct sparse solver.
    Definition: umfpack.hh:215
    \n+
    Definition: umfpack.hh:609
    \n+
    Definition: umfpack.hh:610
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,644 +4,840 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solver.hh\n+umfpack.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5\n- 6#ifndef DUNE_ISTL_SOLVER_HH\n- 7#define DUNE_ISTL_SOLVER_HH\n- 8\n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13\n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20\n- 21#include \"solvertype.hh\"\n- 22#include \"preconditioner.hh\"\n- 23#include \"operators.hh\"\n- 24#include \"scalarproducts.hh\"\n+ 5#ifndef DUNE_ISTL_UMFPACK_HH\n+ 6#define DUNE_ISTL_UMFPACK_HH\n+ 7\n+ 8#if HAVE_SUITESPARSE_UMFPACK || defined DOXYGEN\n+ 9\n+ 10#include\n+ 11#include\n+ 12\n+ 13#include\n+ 14\n+ 15#include\n+ 16#include\n+ 17#include\n+ 18#include\n+ 19#include\n+ 20#include\n+ 21#include\n+ 22#include \n+ 23\n+ 24\n 25\n- 26namespace Dune\n- 27{\n-47 struct InverseOperatorResult\n- 48 {\n-50 InverseOperatorResult ()\n- 51 {\n- 52 clear();\n- 53 }\n- 54\n-56 void clear ()\n- 57 {\n- 58 iterations = 0;\n- 59 reduction = 0;\n- 60 converged = false;\n- 61 conv_rate = 1;\n- 62 elapsed = 0;\n- 63 condition_estimate = -1;\n- 64 }\n- 65\n-67 int iterations;\n- 68\n-70 double reduction;\n- 71\n-73 bool converged;\n- 74\n-76 double conv_rate;\n- 77\n-79 double condition_estimate = -1;\n- 80\n-82 double elapsed;\n- 83 };\n- 84\n- 85\n- 86 //=====================================================================\n- 98 template\n-99 class InverseOperator {\n- 100 public:\n-102 typedef X domain_type;\n- 103\n-105 typedef Y range_type;\n- 106\n-108 typedef typename X::field_type field_type;\n+ 26namespace Dune {\n+ 38 // FORWARD DECLARATIONS\n+ 39 template\n+ 40 class SeqOverlappingSchwarz;\n+ 41\n+ 42 template\n+ 43 struct SeqOverlappingSchwarzAssemblerHelper;\n+ 44\n+ 45 // wrapper class for C-Function Calls in the backend. Choose the right\n+function namespace\n+ 46 // depending on the template parameter used.\n+ 47 template\n+48 struct UMFPackMethodChooser\n+ 49 {\n+50 static constexpr bool valid = false ;\n+ 51 };\n+ 52\n+ 53 template<>\n+54 struct UMFPackMethodChooser\n+ 55 {\n+56 static constexpr bool valid = true ;\n+ 57\n+ 58 template\n+59 static void defaults(A... args)\n+ 60 {\n+ 61 umfpack_dl_defaults(args...);\n+ 62 }\n+ 63 template\n+64 static void free_numeric(A... args)\n+ 65 {\n+ 66 umfpack_dl_free_numeric(args...);\n+ 67 }\n+ 68 template\n+69 static void free_symbolic(A... args)\n+ 70 {\n+ 71 umfpack_dl_free_symbolic(args...);\n+ 72 }\n+ 73 template\n+74 static int load_numeric(A... args)\n+ 75 {\n+ 76 return umfpack_dl_load_numeric(args...);\n+ 77 }\n+ 78 template\n+79 static void numeric(A... args)\n+ 80 {\n+ 81 umfpack_dl_numeric(args...);\n+ 82 }\n+ 83 template\n+84 static void report_info(A... args)\n+ 85 {\n+ 86 umfpack_dl_report_info(args...);\n+ 87 }\n+ 88 template\n+89 static void report_status(A... args)\n+ 90 {\n+ 91 umfpack_dl_report_status(args...);\n+ 92 }\n+ 93 template\n+94 static int save_numeric(A... args)\n+ 95 {\n+ 96 return umfpack_dl_save_numeric(args...);\n+ 97 }\n+ 98 template\n+99 static void solve(A... args)\n+ 100 {\n+ 101 umfpack_dl_solve(args...);\n+ 102 }\n+ 103 template\n+104 static void symbolic(A... args)\n+ 105 {\n+ 106 umfpack_dl_symbolic(args...);\n+ 107 }\n+ 108 };\n 109\n-111 typedef typename FieldTraits::real_type real_type;\n- 112\n-114 typedef Simd::Scalar scalar_real_type;\n- 115\n-128 virtual void apply (X& x, Y& b, InverseOperatorResult& res) = 0;\n- 129\n-143 virtual void apply (X& x, Y& b, double reduction, InverseOperatorResult&\n-res) = 0;\n- 144\n-146 virtual SolverCategory::Category category() const\n- 147#ifdef DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n- 148 {\n- 149 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n-method in a derived classes, in the future this method will pure virtual.\");\n- 150 }\n- 151#else\n- 152 = 0;\n- 153#endif\n- 154\n-156 virtual ~InverseOperator () {}\n- 157\n- 158 protected:\n- 159 // spacing values\n-160 enum { iterationSpacing = 5 , normSpacing = 16 };\n- 161\n-163 void printHeader(std::ostream& s) const\n- 164 {\n- 165 s << std::setw(iterationSpacing) << \" Iter\";\n- 166 s << std::setw(normSpacing) << \"Defect\";\n- 167 s << std::setw(normSpacing) << \"Rate\" << std::endl;\n- 168 }\n- 169\n- 171 template \n-172 void printOutput(std::ostream& s,\n- 173 const CountType& iter,\n- 174 const DataType& norm,\n- 175 const DataType& norm_old) const\n+ 110 template<>\n+111 struct UMFPackMethodChooser >\n+ 112 {\n+113 static constexpr bool valid = true ;\n+ 114\n+ 115 template\n+116 static void defaults(A... args)\n+ 117 {\n+ 118 umfpack_zl_defaults(args...);\n+ 119 }\n+ 120 template\n+121 static void free_numeric(A... args)\n+ 122 {\n+ 123 umfpack_zl_free_numeric(args...);\n+ 124 }\n+ 125 template\n+126 static void free_symbolic(A... args)\n+ 127 {\n+ 128 umfpack_zl_free_symbolic(args...);\n+ 129 }\n+ 130 template\n+131 static int load_numeric(A... args)\n+ 132 {\n+ 133 return umfpack_zl_load_numeric(args...);\n+ 134 }\n+ 135 template\n+136 static void numeric(const long int* cs, const long int* ri, const double*\n+val, A... args)\n+ 137 {\n+ 138 umfpack_zl_numeric(cs,ri,val,NULL,args...);\n+ 139 }\n+ 140 template\n+141 static void report_info(A... args)\n+ 142 {\n+ 143 umfpack_zl_report_info(args...);\n+ 144 }\n+ 145 template\n+146 static void report_status(A... args)\n+ 147 {\n+ 148 umfpack_zl_report_status(args...);\n+ 149 }\n+ 150 template\n+151 static int save_numeric(A... args)\n+ 152 {\n+ 153 return umfpack_zl_save_numeric(args...);\n+ 154 }\n+ 155 template\n+156 static void solve(long int m, const long int* cs, const long int* ri, std::\n+complex* val, double* x, const double* b,A... args)\n+ 157 {\n+ 158 const double* cval = reinterpret_cast(val);\n+ 159 umfpack_zl_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);\n+ 160 }\n+ 161 template\n+162 static void symbolic(long int m, long int n, const long int* cs, const long\n+int* ri, const double* val, A... args)\n+ 163 {\n+ 164 umfpack_zl_symbolic(m,n,cs,ri,val,NULL,args...);\n+ 165 }\n+ 166 };\n+ 167\n+ 168 namespace Impl\n+ 169 {\n+ 170 template\n+ 171 struct UMFPackVectorChooser\n+ 172 {};\n+ 173\n+ 174 template\n+ 175 struct UMFPackVectorChooser,A > >\n 176 {\n- 177 const DataType rate = norm/norm_old;\n- 178 s << std::setw(iterationSpacing) << iter << \" \";\n- 179 s << std::setw(normSpacing) << Simd::io(norm) << \" \";\n- 180 s << std::setw(normSpacing) << Simd::io(rate) << std::endl;\n- 181 }\n- 182\n- 184 template \n-185 void printOutput(std::ostream& s,\n- 186 const CountType& iter,\n- 187 const DataType& norm) const\n- 188 {\n- 189 s << std::setw(iterationSpacing) << iter << \" \";\n- 190 s << std::setw(normSpacing) << Simd::io(norm) << std::endl;\n- 191 }\n- 192 };\n- 193\n- 202 template\n-203 class IterativeSolver : public InverseOperator{\n- 204 public:\n- 205 using typename InverseOperator::domain_type;\n- 206 using typename InverseOperator::range_type;\n- 207 using typename InverseOperator::field_type;\n- 208 using typename InverseOperator::real_type;\n- 209 using typename InverseOperator::scalar_real_type;\n- 210\n-230 IterativeSolver (const LinearOperator& op, Preconditioner& prec,\n-scalar_real_type reduction, int maxit, int verbose) :\n- 231 _op(stackobject_to_shared_ptr(op)),\n- 232 _prec(stackobject_to_shared_ptr(prec)),\n- 233 _sp(new SeqScalarProduct),\n- 234 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category\n-(SolverCategory::sequential)\n- 235 {\n- 236 if(SolverCategory::category(op) != SolverCategory::sequential)\n- 237 DUNE_THROW(InvalidSolverCategory, \"LinearOperator has to be sequential!\");\n- 238 if(SolverCategory::category(prec) != SolverCategory::sequential)\n- 239 DUNE_THROW(InvalidSolverCategory, \"Preconditioner has to be sequential!\");\n- 240 }\n- 241\n-262 IterativeSolver (const LinearOperator& op, const ScalarProduct& sp,\n-Preconditioner& prec,\n- 263 scalar_real_type reduction, int maxit, int verbose) :\n- 264 _op(stackobject_to_shared_ptr(op)),\n- 265 _prec(stackobject_to_shared_ptr(prec)),\n- 266 _sp(stackobject_to_shared_ptr(sp)),\n- 267 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category\n-(SolverCategory::category(op))\n- 268 {\n- 269 if(SolverCategory::category(op) != SolverCategory::category(prec))\n- 270 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and Preconditioner must\n-have the same SolverCategory!\");\n- 271 if(SolverCategory::category(op) != SolverCategory::category(sp))\n- 272 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and ScalarProduct must\n-have the same SolverCategory!\");\n- 273 }\n- 274\n-290 IterativeSolver (std::shared_ptr > op, std::\n-shared_ptr > prec, const ParameterTree& configuration) :\n- 291 IterativeSolver(op,std::make_shared>(),prec,\n- 292 configuration.get(\"reduction\"),\n- 293 configuration.get(\"maxit\"),\n- 294 configuration.get(\"verbose\"))\n- 295 {}\n- 296\n-313 IterativeSolver (std::shared_ptr > op, std::\n-shared_ptr > sp, std::shared_ptr >\n-prec, const ParameterTree& configuration) :\n- 314 IterativeSolver(op,sp,prec,\n- 315 configuration.get(\"reduction\"),\n- 316 configuration.get(\"maxit\"),\n- 317 configuration.get(\"verbose\"))\n- 318 {}\n- 319\n-340 IterativeSolver (std::shared_ptr> op,\n- 341 std::shared_ptr> sp,\n- 342 std::shared_ptr> prec,\n- 343 scalar_real_type reduction, int maxit, int verbose) :\n- 344 _op(op),\n- 345 _prec(prec),\n- 346 _sp(sp),\n- 347 _reduction(reduction), _maxit(maxit), _verbose(verbose),\n- 348 _category(SolverCategory::category(*op))\n- 349 {\n- 350 if(SolverCategory::category(*op) != SolverCategory::category(*prec))\n- 351 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and Preconditioner must\n-have the same SolverCategory!\");\n- 352 if(SolverCategory::category(*op) != SolverCategory::category(*sp))\n- 353 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and ScalarProduct must\n-have the same SolverCategory!\");\n- 354 }\n- 355\n- 356 // #warning actually we want to have this as the default and just\n-implement the second one\n- 357 // //! \\copydoc InverseOperator::apply(X&,Y&,InverseOperatorResult&)\n- 358 // virtual void apply (X& x, Y& b, InverseOperatorResult& res)\n- 359 // {\n- 360 // apply(x,b,_reduction,res);\n- 361 // }\n- 362\n- 363#ifndef DOXYGEN\n- 364 // make sure the three-argument apply from the base class does not get\n-shadowed\n- 365 // by the redefined four-argument version below\n- 366 using InverseOperator::apply;\n- 367#endif\n- 368\n-374 virtual void apply (X& x, X& b, double reduction, InverseOperatorResult&\n+ 178 using domain_type = BlockVector<\n+ 179 FieldVector,\n+ 180 typename std::allocator_traits::template rebind_alloc\n+> >;\n+ 182 using range_type = BlockVector<\n+ 183 FieldVector,\n+ 184 typename std::allocator_traits::template rebind_alloc\n+> >;\n+ 185 };\n+ 186\n+ 187 template\n+ 188 struct UMFPackVectorChooser >\n+ 189 {\n+ 191 using domain_type = BlockVector;\n+ 193 using range_type = BlockVector;\n+ 194 };\n+ 195 }\n+ 196\n+ 210 template\n+211 class UMFPack\n+ 212 : public InverseOperator<\n+ 213 typename Impl::UMFPackVectorChooser::domain_type,\n+ 214 typename Impl::UMFPackVectorChooser::range_type >\n+ 215 {\n+ 216 using T = typename M::field_type;\n+ 217\n+ 218 public:\n+220 using Matrix = M;\n+221 using matrix_type = M;\n+223 typedef ISTL::Impl::BCCSMatrix\n+UMFPackMatrix;\n+225 typedef ISTL::Impl::BCCSMatrixInitializer MatrixInitializer;\n+227 using domain_type = typename Impl::UMFPackVectorChooser::domain_type;\n+229 using range_type = typename Impl::UMFPackVectorChooser::range_type;\n+ 230\n+232 virtual SolverCategory::Category category() const\n+ 233 {\n+ 234 return SolverCategory::Category::sequential;\n+ 235 }\n+ 236\n+245 UMFPack(const Matrix& matrix, int verbose=0) : matrixIsLoaded_(false)\n+ 246 {\n+ 247 //check whether T is a supported type\n+ 248 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 249 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 250 Caller::defaults(UMF_Control);\n+ 251 setVerbosity(verbose);\n+ 252 setMatrix(matrix);\n+ 253 }\n+ 254\n+263 UMFPack(const Matrix& matrix, int verbose, bool) : matrixIsLoaded_(false)\n+ 264 {\n+ 265 //check whether T is a supported type\n+ 266 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 267 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 268 Caller::defaults(UMF_Control);\n+ 269 setVerbosity(verbose);\n+ 270 setMatrix(matrix);\n+ 271 }\n+ 272\n+282 UMFPack(const Matrix& mat_, const ParameterTree& config)\n+ 283 : UMFPack(mat_, config.get(\"verbose\", 0))\n+ 284 {}\n+ 285\n+288 UMFPack() : matrixIsLoaded_(false), verbosity_(0)\n+ 289 {\n+ 290 //check whether T is a supported type\n+ 291 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 292 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 293 Caller::defaults(UMF_Control);\n+ 294 }\n+ 295\n+306 UMFPack(const Matrix& mat_, const char* file, int verbose=0)\n+ 307 {\n+ 308 //check whether T is a supported type\n+ 309 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 310 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 311 Caller::defaults(UMF_Control);\n+ 312 setVerbosity(verbose);\n+ 313 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast(file));\n+ 314 if ((errcode == UMFPACK_ERROR_out_of_memory) || (errcode ==\n+UMFPACK_ERROR_file_IO))\n+ 315 {\n+ 316 matrixIsLoaded_ = false;\n+ 317 setMatrix(mat_);\n+ 318 saveDecomposition(file);\n+ 319 }\n+ 320 else\n+ 321 {\n+ 322 matrixIsLoaded_ = true;\n+ 323 std::cout << \"UMFPack decomposition successfully loaded from \" << file <<\n+std::endl;\n+ 324 }\n+ 325 }\n+ 326\n+333 UMFPack(const char* file, int verbose=0)\n+ 334 {\n+ 335 //check whether T is a supported type\n+ 336 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 337 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 338 Caller::defaults(UMF_Control);\n+ 339 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast(file));\n+ 340 if (errcode == UMFPACK_ERROR_out_of_memory)\n+ 341 DUNE_THROW(Dune::Exception, \"ran out of memory while loading UMFPack\n+decomposition\");\n+ 342 if (errcode == UMFPACK_ERROR_file_IO)\n+ 343 DUNE_THROW(Dune::Exception, \"IO error while loading UMFPack\n+decomposition\");\n+ 344 matrixIsLoaded_ = true;\n+ 345 std::cout << \"UMFPack decomposition successfully loaded from \" << file <<\n+std::endl;\n+ 346 setVerbosity(verbose);\n+ 347 }\n+ 348\n+349 virtual ~UMFPack()\n+ 350 {\n+ 351 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n+ 352 free();\n+ 353 }\n+ 354\n+358 virtual void apply(domain_type& x, range_type& b, InverseOperatorResult&\n res)\n- 375 {\n- 376 scalar_real_type saved_reduction = _reduction;\n- 377 _reduction = reduction;\n- 378 this->apply(x,b,res);\n- 379 _reduction = saved_reduction;\n- 380 }\n- 381\n-383 virtual SolverCategory::Category category() const\n- 384 {\n- 385 return _category;\n- 386 }\n- 387\n-388 std::string name() const{\n- 389 std::string name = className(*this);\n- 390 return name.substr(0, name.find(\"<\"));\n- 391 }\n- 392\n- 410 template\n-411 class Iteration {\n- 412 public:\n-413 Iteration(const IterativeSolver& parent, InverseOperatorResult& res)\n- 414 : _i(0)\n- 415 , _res(res)\n- 416 , _parent(parent)\n- 417 , _valid(true)\n- 418 {\n- 419 res.clear();\n- 420 if(_parent._verbose>0){\n- 421 std::cout << \"=== \" << parent.name() << std::endl;\n- 422 if(_parent._verbose > 1)\n- 423 _parent.printHeader(std::cout);\n- 424 }\n- 425 }\n- 426\n-427 Iteration(const Iteration&) = delete;\n-428 Iteration(Iteration&& other)\n- 429 : _def0(other._def0)\n- 430 , _def(other._def)\n- 431 , _i(other._i)\n- 432 , _watch(other._watch)\n- 433 , _res(other._res)\n- 434 , _parent(other._parent)\n- 435 , _valid(other._valid)\n- 436 {\n- 437 other._valid = false;\n- 438 }\n- 439\n-440 ~Iteration(){\n- 441 if(_valid)\n- 442 finalize();\n- 443 }\n- 444\n-455 bool step(CountType i, real_type def){\n- 456 if (!Simd::allTrue(isFinite(def))) // check for inf or NaN\n- 457 {\n- 458 if (_parent._verbose>0)\n- 459 std::cout << \"=== \" << _parent.name() << \": abort due to infinite or NaN\n-defect\"\n- 460 << std::endl;\n- 461 DUNE_THROW(SolverAbort,\n- 462 _parent.name() << \": defect=\" << Simd::io(def)\n- 463 << \" is infinite or NaN\");\n- 464 }\n- 465 if(i == 0)\n- 466 _def0 = def;\n- 467 if(_parent._verbose > 1){\n- 468 if(i!=0)\n- 469 _parent.printOutput(std::cout,i,def,_def);\n- 470 else\n- 471 _parent.printOutput(std::cout,i,def);\n- 472 }\n- 473 _def = def;\n- 474 _i = i;\n- 475 _res.converged = (Simd::allTrue(def<_def0*_parent._reduction ||\n-def(Simd::max(_def/_def0));\n- 484 _res.conv_rate = pow(_res.reduction,1.0/_i);\n- 485 _res.elapsed = _watch.elapsed();\n- 486 if (_parent._verbose>0) // final print\n- 487 {\n- 488 std::cout << \"=== rate=\" << _res.conv_rate\n- 489 << \", T=\" << _res.elapsed\n- 490 << \", TIT=\" << _res.elapsed/_res.iterations\n- 491 << \", IT=\" << _res.iterations << std::endl;\n- 492 }\n- 493 }\n- 494\n-495 real_type _def0 = 0.0, _def = 0.0;\n-496 CountType _i;\n-497 Timer _watch;\n-498 InverseOperatorResult& _res;\n-499 const IterativeSolver& _parent;\n-500 bool _valid;\n- 501 };\n- 502\n- 503 protected:\n-504 std::shared_ptr> _op;\n-505 std::shared_ptr> _prec;\n-506 std::shared_ptr> _sp;\n-507 scalar_real_type _reduction;\n-508 int _maxit;\n-509 int _verbose;\n-510 SolverCategory::Category _category;\n- 511 };\n- 512\n- 520 template \n-521 class SolverHelper\n+ 359 {\n+ 360 if (umfpackMatrix_.N() != b.dim())\n+ 361 DUNE_THROW(Dune::ISTLError, \"Size of right-hand-side vector b does not\n+match the number of matrix rows!\");\n+ 362 if (umfpackMatrix_.M() != x.dim())\n+ 363 DUNE_THROW(Dune::ISTLError, \"Size of solution vector x does not match the\n+number of matrix columns!\");\n+ 364 if (b.size() == 0)\n+ 365 return;\n+ 366\n+ 367 double UMF_Apply_Info[UMFPACK_INFO];\n+ 368 Caller::solve(UMFPACK_A,\n+ 369 umfpackMatrix_.getColStart(),\n+ 370 umfpackMatrix_.getRowIndex(),\n+ 371 umfpackMatrix_.getValues(),\n+ 372 reinterpret_cast(&x[0]),\n+ 373 reinterpret_cast(&b[0]),\n+ 374 UMF_Numeric,\n+ 375 UMF_Control,\n+ 376 UMF_Apply_Info);\n+ 377\n+ 378 //this is a direct solver\n+ 379 res.iterations = 1;\n+ 380 res.converged = true;\n+ 381 res.elapsed = UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME];\n+ 382\n+ 383 printOnApply(UMF_Apply_Info);\n+ 384 }\n+ 385\n+389 virtual void apply (domain_type& x, range_type& b, [[maybe_unused]] double\n+reduction, InverseOperatorResult& res)\n+ 390 {\n+ 391 apply(x,b,res);\n+ 392 }\n+ 393\n+399 void apply(T* x, T* b)\n+ 400 {\n+ 401 double UMF_Apply_Info[UMFPACK_INFO];\n+ 402 Caller::solve(UMFPACK_A,\n+ 403 umfpackMatrix_.getColStart(),\n+ 404 umfpackMatrix_.getRowIndex(),\n+ 405 umfpackMatrix_.getValues(),\n+ 406 x,\n+ 407 b,\n+ 408 UMF_Numeric,\n+ 409 UMF_Control,\n+ 410 UMF_Apply_Info);\n+ 411 printOnApply(UMF_Apply_Info);\n+ 412 }\n+ 413\n+425 void setOption(unsigned int option, double value)\n+ 426 {\n+ 427 if (option >= UMFPACK_CONTROL)\n+ 428 DUNE_THROW(RangeError, \"Requested non-existing UMFPack option\");\n+ 429\n+ 430 UMF_Control[option] = value;\n+ 431 }\n+ 432\n+436 void saveDecomposition(const char* file)\n+ 437 {\n+ 438 int errcode = Caller::save_numeric(UMF_Numeric, const_cast(file));\n+ 439 if (errcode != UMFPACK_OK)\n+ 440 DUNE_THROW(Dune::Exception,\"IO ERROR while trying to save UMFPack\n+decomposition\");\n+ 441 }\n+ 442\n+444 void setMatrix(const Matrix& matrix)\n+ 445 {\n+ 446 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n+ 447 free();\n+ 448 if (matrix.N() == 0 or matrix.M() == 0)\n+ 449 return;\n+ 450\n+ 451 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes()\n+!= 0)\n+ 452 umfpackMatrix_.free();\n+ 453 umfpackMatrix_.setSize(MatrixDimension::rowdim(matrix),\n+ 454 MatrixDimension::coldim(matrix));\n+ 455 ISTL::Impl::BCCSMatrixInitializer initializer\n+(umfpackMatrix_);\n+ 456\n+ 457 copyToBCCSMatrix(initializer, matrix);\n+ 458\n+ 459 decompose();\n+ 460 }\n+ 461\n+ 462 template\n+463 void setSubMatrix(const Matrix& _mat, const S& rowIndexSet)\n+ 464 {\n+ 465 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n+ 466 free();\n+ 467\n+ 468 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes()\n+!= 0)\n+ 469 umfpackMatrix_.free();\n+ 470\n+ 471 umfpackMatrix_.setSize(rowIndexSet.size()*MatrixDimension::rowdim\n+(_mat) / _mat.N(),\n+ 472 rowIndexSet.size()*MatrixDimension::coldim(_mat) / _mat.M());\n+ 473 ISTL::Impl::BCCSMatrixInitializer initializer\n+(umfpackMatrix_);\n+ 474\n+ 475 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset >(_mat,rowIndexSet));\n+ 476\n+ 477 decompose();\n+ 478 }\n+ 479\n+487 void setVerbosity(int v)\n+ 488 {\n+ 489 verbosity_ = v;\n+ 490 // set the verbosity level in UMFPack\n+ 491 if (verbosity_ == 0)\n+ 492 UMF_Control[UMFPACK_PRL] = 1;\n+ 493 if (verbosity_ == 1)\n+ 494 UMF_Control[UMFPACK_PRL] = 2;\n+ 495 if (verbosity_ == 2)\n+ 496 UMF_Control[UMFPACK_PRL] = 4;\n+ 497 }\n+ 498\n+503 void* getFactorization()\n+ 504 {\n+ 505 return UMF_Numeric;\n+ 506 }\n+ 507\n+512 UMFPackMatrix& getInternalMatrix()\n+ 513 {\n+ 514 return umfpackMatrix_;\n+ 515 }\n+ 516\n+521 void free()\n 522 {\n- 523 public:\n-524 static void setMatrix (ISTLLinearSolver& solver,\n- 525 const BCRSMatrix& matrix)\n- 526 {\n- 527 static const bool is_direct_solver\n- 528 = Dune::IsDirectSolver::value;\n- 529 SolverHelper::\n- 530Implementation::setMatrix(solver,matrix);\n- 531 }\n- 532\n- 533 protected:\n- 538 template \n-539 struct Implementation\n- 540 {\n-541 static void setMatrix (ISTLLinearSolver&,\n- 542 const BCRSMatrix&)\n- 543 {}\n- 544 };\n- 545\n- 550 template \n-551 struct Implementation\n- 552 {\n-553 static void setMatrix (ISTLLinearSolver& solver,\n- 554 const BCRSMatrix& matrix)\n- 555 {\n- 556 solver.setMatrix(matrix);\n- 557 }\n- 558 };\n- 559 };\n- 560\n- 564}\n- 565\n- 566#endif\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n+ 523 if (!matrixIsLoaded_)\n+ 524 {\n+ 525 Caller::free_symbolic(&UMF_Symbolic);\n+ 526 umfpackMatrix_.free();\n+ 527 }\n+ 528 Caller::free_numeric(&UMF_Numeric);\n+ 529 matrixIsLoaded_ = false;\n+ 530 }\n+ 531\n+532 const char* name() { return \"UMFPACK\"; }\n+ 533\n+ 534 private:\n+ 535 typedef typename Dune::UMFPackMethodChooser Caller;\n+ 536\n+ 537 template\n+538 friend class SeqOverlappingSchwarz;\n+ 539 friend struct SeqOverlappingSchwarzAssemblerHelper,true>;\n+ 540\n+ 542 void decompose()\n+ 543 {\n+ 544 double UMF_Decomposition_Info[UMFPACK_INFO];\n+ 545 Caller::symbolic(static_cast(umfpackMatrix_.N()),\n+ 546 static_cast(umfpackMatrix_.N()),\n+ 547 umfpackMatrix_.getColStart(),\n+ 548 umfpackMatrix_.getRowIndex(),\n+ 549 reinterpret_cast(umfpackMatrix_.getValues()),\n+ 550 &UMF_Symbolic,\n+ 551 UMF_Control,\n+ 552 UMF_Decomposition_Info);\n+ 553 Caller::numeric(umfpackMatrix_.getColStart(),\n+ 554 umfpackMatrix_.getRowIndex(),\n+ 555 reinterpret_cast(umfpackMatrix_.getValues()),\n+ 556 UMF_Symbolic,\n+ 557 &UMF_Numeric,\n+ 558 UMF_Control,\n+ 559 UMF_Decomposition_Info);\n+ 560 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);\n+ 561 if (verbosity_ == 1)\n+ 562 {\n+ 563 std::cout << \"[UMFPack Decomposition]\" << std::endl;\n+ 564 std::cout << \"Wallclock Time taken: \" << UMF_Decomposition_Info\n+[UMFPACK_NUMERIC_WALLTIME] << \" (CPU Time: \" << UMF_Decomposition_Info\n+[UMFPACK_NUMERIC_TIME] << \")\" << std::endl;\n+ 565 std::cout << \"Flops taken: \" << UMF_Decomposition_Info[UMFPACK_FLOPS] <<\n+std::endl;\n+ 566 std::cout << \"Peak Memory Usage: \" << UMF_Decomposition_Info\n+[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT] << \" bytes\"\n+<< std::endl;\n+ 567 std::cout << \"Condition number estimate: \" << 1./UMF_Decomposition_Info\n+[UMFPACK_RCOND] << std::endl;\n+ 568 std::cout << \"Numbers of non-zeroes in decomposition: L: \" <<\n+UMF_Decomposition_Info[UMFPACK_LNZ] << \" U: \" << UMF_Decomposition_Info\n+[UMFPACK_UNZ] << std::endl;\n+ 569 }\n+ 570 if (verbosity_ == 2)\n+ 571 {\n+ 572 Caller::report_info(UMF_Control,UMF_Decomposition_Info);\n+ 573 }\n+ 574 }\n+ 575\n+ 576 void printOnApply(double* UMF_Info)\n+ 577 {\n+ 578 Caller::report_status(UMF_Control,UMF_Info[UMFPACK_STATUS]);\n+ 579 if (verbosity_ > 0)\n+ 580 {\n+ 581 std::cout << \"[UMFPack Solve]\" << std::endl;\n+ 582 std::cout << \"Wallclock Time: \" << UMF_Info[UMFPACK_SOLVE_WALLTIME] << \"\n+(CPU Time: \" << UMF_Info[UMFPACK_SOLVE_TIME] << \")\" << std::endl;\n+ 583 std::cout << \"Flops Taken: \" << UMF_Info[UMFPACK_SOLVE_FLOPS] << std::\n+endl;\n+ 584 std::cout << \"Iterative Refinement steps taken: \" << UMF_Info\n+[UMFPACK_IR_TAKEN] << std::endl;\n+ 585 std::cout << \"Error Estimate: \" << UMF_Info[UMFPACK_OMEGA1] << \" resp. \"\n+<< UMF_Info[UMFPACK_OMEGA2] << std::endl;\n+ 586 }\n+ 587 }\n+ 588\n+ 589 UMFPackMatrix umfpackMatrix_;\n+ 590 bool matrixIsLoaded_;\n+ 591 int verbosity_;\n+ 592 void *UMF_Symbolic;\n+ 593 void *UMF_Numeric;\n+ 594 double UMF_Control[UMFPACK_CONTROL];\n+ 595 };\n+ 596\n+ 597 template\n+598 struct IsDirectSolver,A> > >\n+ 599 {\n+600 enum { value=true};\n+ 601 };\n+ 602\n+ 603 template\n+604 struct StoresColumnCompressed > >\n+ 605 {\n+606 enum { value = true };\n+ 607 };\n+ 608\n+609 struct UMFPackCreator {\n+610 template struct isValidBlock : std::false_type{};\n+611 template struct isValidBlock::real_type,double>::value>> : std::true_type\n+{};\n+ 612\n+ 613 template\n+ 614 std::shared_ptr::type,\n+ 615 typename Dune::TypeListElement<2, TL>::type>>\n+616 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& config,\n+ 617 std::enable_if_t<\n+ 618 isValidBlock::type::block_type>::\n+value,int> = 0) const\n+ 619 {\n+ 620 int verbose = config.get(\"verbose\", 0);\n+ 621 return std::make_shared>(mat,verbose);\n+ 622 }\n+ 623\n+ 624 // second version with SFINAE to validate the template parameters of\n+UMFPack\n+ 625 template\n+ 626 std::shared_ptr::type,\n+ 627 typename Dune::TypeListElement<2, TL>::type>>\n+628 operator()(TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n+*config*/,\n+ 629 std::enable_if_t<\n+ 630 !isValidBlock::type::block_type>::\n+value,int> = 0) const\n+ 631 {\n+ 632 DUNE_THROW(UnsupportedType,\n+ 633 \"Unsupported Type in UMFPack (only double and std::complex\n+supported)\");\n+ 634 }\n+ 635 };\n+636 DUNE_REGISTER_DIRECT_SOLVER(\"umfpack\",Dune::UMFPackCreator());\n+ 637} // end namespace Dune\n+ 638\n+ 639#endif // HAVE_SUITESPARSE_UMFPACK\n+ 640\n+ 641#endif //DUNE_ISTL_UMFPACK_HH\n solvertype.hh\n Templates characterizing the type of a solver.\n-preconditioner.hh\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n+bccsmatrixinitializer.hh\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+solvers.hh\n+Implementations of the inverse operator interface.\n+solverfactory.hh\n+Dune::UMFPack::free\n+void free()\n+free allocated space.\n+Definition: umfpack.hh:521\n+Dune::UMFPack::apply\n+virtual void apply(domain_type &x, range_type &b, InverseOperatorResult &res)\n+Apply inverse operator,.\n+Definition: umfpack.hh:358\n+Dune::UMFPack::category\n+virtual SolverCategory::Category category() const\n+Category of the solver (see SolverCategory::Category)\n+Definition: umfpack.hh:232\n+Dune::UMFPack::matrix_type\n+M matrix_type\n+Definition: umfpack.hh:221\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::solve\n+static void solve(long int m, const long int *cs, const long int *ri, std::\n+complex< double > *val, double *x, const double *b, A... args)\n+Definition: umfpack.hh:156\n+Dune::UMFPack::setMatrix\n+void setMatrix(const Matrix &matrix)\n+Initialize data from given matrix.\n+Definition: umfpack.hh:444\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::report_info\n+static void report_info(A... args)\n+Definition: umfpack.hh:141\n+Dune::UMFPack::UMFPack\n+UMFPack(const Matrix &mat_, const ParameterTree &config)\n+Construct a solver object from a matrix.\n+Definition: umfpack.hh:282\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::load_numeric\n+static int load_numeric(A... args)\n+Definition: umfpack.hh:131\n+Dune::UMFPackMethodChooser<_double_>::load_numeric\n+static int load_numeric(A... args)\n+Definition: umfpack.hh:74\n+Dune::UMFPackCreator::operator()\n+std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL\n+>::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const\n+M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock<\n+typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0)\n+const\n+Definition: umfpack.hh:616\n+Dune::UMFPack::UMFPackMatrix\n+ISTL::Impl::BCCSMatrix< typename Matrix::field_type, long int > UMFPackMatrix\n+The corresponding UMFPack matrix type.\n+Definition: umfpack.hh:223\n+Dune::UMFPackMethodChooser<_double_>::report_status\n+static void report_status(A... args)\n+Definition: umfpack.hh:89\n+Dune::UMFPack::UMFPack\n+UMFPack(const Matrix &mat_, const char *file, int verbose=0)\n+Try loading a decomposition from file and do a decomposition if unsuccessful.\n+Definition: umfpack.hh:306\n+Dune::UMFPack::range_type\n+typename Impl::UMFPackVectorChooser< M >::range_type range_type\n+The type of the range of the solver.\n+Definition: umfpack.hh:229\n+Dune::DUNE_REGISTER_DIRECT_SOLVER\n+DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n+Dune::UMFPack::UMFPack\n+UMFPack()\n+default constructor\n+Definition: umfpack.hh:288\n+Dune::UMFPackMethodChooser<_double_>::symbolic\n+static void symbolic(A... args)\n+Definition: umfpack.hh:104\n+Dune::UMFPackMethodChooser<_double_>::report_info\n+static void report_info(A... args)\n+Definition: umfpack.hh:84\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::symbolic\n+static void symbolic(long int m, long int n, const long int *cs, const long int\n+*ri, const double *val, A... args)\n+Definition: umfpack.hh:162\n+Dune::UMFPackMethodChooser<_double_>::free_symbolic\n+static void free_symbolic(A... args)\n+Definition: umfpack.hh:69\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::save_numeric\n+static int save_numeric(A... args)\n+Definition: umfpack.hh:151\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::free_numeric\n+static void free_numeric(A... args)\n+Definition: umfpack.hh:121\n+Dune::UMFPack::setSubMatrix\n+void setSubMatrix(const Matrix &_mat, const S &rowIndexSet)\n+Definition: umfpack.hh:463\n+Dune::UMFPackMethodChooser<_double_>::save_numeric\n+static int save_numeric(A... args)\n+Definition: umfpack.hh:94\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::report_status\n+static void report_status(A... args)\n+Definition: umfpack.hh:146\n+Dune::UMFPack::MatrixInitializer\n+ISTL::Impl::BCCSMatrixInitializer< M, long int > MatrixInitializer\n+Type of an associated initializer class.\n+Definition: umfpack.hh:225\n+Dune::UMFPack::apply\n+void apply(T *x, T *b)\n+additional apply method with c-arrays in analogy to superlu\n+Definition: umfpack.hh:399\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::defaults\n+static void defaults(A... args)\n+Definition: umfpack.hh:116\n+Dune::UMFPackMethodChooser<_double_>::free_numeric\n+static void free_numeric(A... args)\n+Definition: umfpack.hh:64\n+Dune::UMFPack::setVerbosity\n+void setVerbosity(int v)\n+sets the verbosity level for the UMFPack solver\n+Definition: umfpack.hh:487\n+Dune::UMFPack::UMFPack\n+UMFPack(const char *file, int verbose=0)\n+try loading a decomposition from file\n+Definition: umfpack.hh:333\n+Dune::UMFPackMethodChooser<_double_>::numeric\n+static void numeric(A... args)\n+Definition: umfpack.hh:79\n+Dune::UMFPackMethodChooser::valid\n+static constexpr bool valid\n+Definition: umfpack.hh:50\n+Dune::UMFPack::~UMFPack\n+virtual ~UMFPack()\n+Definition: umfpack.hh:349\n+Dune::UMFPack::name\n+const char * name()\n+Definition: umfpack.hh:532\n+Dune::UMFPack::saveDecomposition\n+void saveDecomposition(const char *file)\n+saves a decomposition to a file\n+Definition: umfpack.hh:436\n+Dune::UMFPack::getInternalMatrix\n+UMFPackMatrix & getInternalMatrix()\n+Return the column compress matrix from UMFPack.\n+Definition: umfpack.hh:512\n+Dune::UMFPack::domain_type\n+typename Impl::UMFPackVectorChooser< M >::domain_type domain_type\n+The type of the domain of the solver.\n+Definition: umfpack.hh:227\n+Dune::UMFPack::UMFPack\n+UMFPack(const Matrix &matrix, int verbose=0)\n+Construct a solver object from a matrix.\n+Definition: umfpack.hh:245\n+Dune::UMFPack::apply\n+virtual void apply(domain_type &x, range_type &b, double reduction,\n+InverseOperatorResult &res)\n+apply inverse operator, with given convergence criteria.\n+Definition: umfpack.hh:389\n+Dune::UMFPack::setOption\n+void setOption(unsigned int option, double value)\n+Set UMFPack-specific options.\n+Definition: umfpack.hh:425\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::free_symbolic\n+static void free_symbolic(A... args)\n+Definition: umfpack.hh:126\n+Dune::UMFPack::Matrix\n+M Matrix\n+The matrix type.\n+Definition: umfpack.hh:220\n+Dune::UMFPackMethodChooser<_std::complex<_double_>_>::numeric\n+static void numeric(const long int *cs, const long int *ri, const double *val,\n+A... args)\n+Definition: umfpack.hh:136\n+Dune::UMFPackMethodChooser<_double_>::defaults\n+static void defaults(A... args)\n+Definition: umfpack.hh:59\n+Dune::UMFPackMethodChooser<_double_>::solve\n+static void solve(A... args)\n+Definition: umfpack.hh:99\n+Dune::UMFPack::UMFPack\n+UMFPack(const Matrix &matrix, int verbose, bool)\n+Constructor for compatibility with SuperLU standard constructor.\n+Definition: umfpack.hh:263\n+Dune::UMFPack::getFactorization\n+void * getFactorization()\n+Return the matrix factorization.\n+Definition: umfpack.hh:503\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n std\n STL namespace.\n Dune\n Definition: allocator.hh:11\n Dune::get\n PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n Definition: dependency.hh:293\n+Dune::MatrixDimension\n+Definition: matrixutils.hh:211\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::SolverAbort\n-Thrown when a solver aborts due to some problem.\n-Definition: istlexception.hh:46\n-Dune::LinearOperator\n-A linear operator.\n-Definition: operators.hh:67\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::ScalarProduct\n-Base class for scalar product and norm computation.\n-Definition: scalarproducts.hh:52\n-Dune::SeqScalarProduct\n-Default implementation for the scalar case.\n-Definition: scalarproducts.hh:168\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::SeqOverlappingSchwarz\n+Sequential overlapping Schwarz preconditioner.\n+Definition: overlappingschwarz.hh:755\n+Dune::SeqOverlappingSchwarzAssemblerHelper\n+Definition: overlappingschwarz.hh:694\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n Dune::InverseOperatorResult\n Statistics about the application of an inverse operator.\n Definition: solver.hh:48\n-Dune::InverseOperatorResult::InverseOperatorResult\n-InverseOperatorResult()\n-Default constructor.\n-Definition: solver.hh:50\n-Dune::InverseOperatorResult::condition_estimate\n-double condition_estimate\n-Estimate of condition number.\n-Definition: solver.hh:79\n Dune::InverseOperatorResult::elapsed\n double elapsed\n Elapsed time in seconds.\n Definition: solver.hh:82\n Dune::InverseOperatorResult::iterations\n int iterations\n Number of iterations.\n Definition: solver.hh:67\n-Dune::InverseOperatorResult::reduction\n-double reduction\n-Reduction achieved: .\n-Definition: solver.hh:70\n-Dune::InverseOperatorResult::clear\n-void clear()\n-Resets all data.\n-Definition: solver.hh:56\n-Dune::InverseOperatorResult::conv_rate\n-double conv_rate\n-Convergence rate (average reduction per step)\n-Definition: solver.hh:76\n Dune::InverseOperatorResult::converged\n bool converged\n True if convergence criterion has been met.\n Definition: solver.hh:73\n Dune::InverseOperator\n Abstract base class for all solvers.\n Definition: solver.hh:99\n-Dune::InverseOperator::printHeader\n-void printHeader(std::ostream &s) const\n-helper function for printing header of solver output\n-Definition: solver.hh:163\n-Dune::InverseOperator::~InverseOperator\n-virtual ~InverseOperator()\n-Destructor.\n-Definition: solver.hh:156\n-Dune::InverseOperator::printOutput\n-void printOutput(std::ostream &s, const CountType &iter, const DataType &norm)\n-const\n-helper function for printing solver output\n-Definition: solver.hh:185\n-Dune::InverseOperator::printOutput\n-void printOutput(std::ostream &s, const CountType &iter, const DataType &norm,\n-const DataType &norm_old) const\n-helper function for printing solver output\n-Definition: solver.hh:172\n-Dune::InverseOperator::apply\n-virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)=0\n-apply inverse operator, with given convergence criteria.\n-Dune::InverseOperator::scalar_real_type\n-Simd::Scalar< real_type > scalar_real_type\n-scalar type underlying the field_type\n-Definition: solver.hh:114\n-Dune::InverseOperator::range_type\n-Y range_type\n-Type of the range of the operator to be inverted.\n-Definition: solver.hh:105\n-Dune::InverseOperator::normSpacing\n-@ normSpacing\n-Definition: solver.hh:160\n-Dune::InverseOperator::iterationSpacing\n-@ iterationSpacing\n-Definition: solver.hh:160\n-Dune::InverseOperator::domain_type\n-X domain_type\n-Type of the domain of the operator to be inverted.\n-Definition: solver.hh:102\n-Dune::InverseOperator::apply\n-virtual void apply(X &x, Y &b, InverseOperatorResult &res)=0\n-Apply inverse operator,.\n-Dune::InverseOperator::field_type\n-X::field_type field_type\n-The field type of the operator.\n-Definition: solver.hh:108\n-Dune::InverseOperator::real_type\n-FieldTraits< field_type >::real_type real_type\n-The real type of the field type (is the same if using real numbers, but differs\n-for std::complex)\n-Definition: solver.hh:111\n-Dune::InverseOperator::category\n-virtual SolverCategory::Category category() const =0\n-Category of the solver (see SolverCategory::Category)\n-Dune::IterativeSolver\n-Base class for all implementations of iterative solvers.\n-Definition: solver.hh:203\n-Dune::IterativeSolver::IterativeSolver\n-IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, const ParameterTree &configuration)\n-Constructor.\n-Definition: solver.hh:313\n-Dune::IterativeSolver::IterativeSolver\n-IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n-Constructor.\n-Definition: solver.hh:290\n-Dune::IterativeSolver::apply\n-virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)\n-Apply inverse operator with given reduction factor.\n-Definition: solver.hh:374\n-Dune::IterativeSolver::_sp\n-std::shared_ptr< const ScalarProduct< X > > _sp\n-Definition: solver.hh:506\n-Dune::IterativeSolver::IterativeSolver\n-IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-Y > > prec, scalar_real_type reduction, int maxit, int verbose)\n-General constructor to initialize an iterative solver.\n-Definition: solver.hh:340\n-Dune::IterativeSolver::name\n-std::string name() const\n-Definition: solver.hh:388\n-Dune::IterativeSolver::IterativeSolver\n-IterativeSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec,\n-scalar_real_type reduction, int maxit, int verbose)\n-General constructor to initialize an iterative solver.\n-Definition: solver.hh:230\n-Dune::IterativeSolver::_op\n-std::shared_ptr< const LinearOperator< X, Y > > _op\n-Definition: solver.hh:504\n-Dune::IterativeSolver::_maxit\n-int _maxit\n-Definition: solver.hh:508\n-Dune::IterativeSolver::_verbose\n-int _verbose\n-Definition: solver.hh:509\n-Dune::IterativeSolver::_reduction\n-scalar_real_type _reduction\n-Definition: solver.hh:507\n-Dune::IterativeSolver::IterativeSolver\n-IterativeSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp,\n-Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int\n-verbose)\n-General constructor to initialize an iterative solver.\n-Definition: solver.hh:262\n-Dune::IterativeSolver::_category\n-SolverCategory::Category _category\n-Definition: solver.hh:510\n-Dune::IterativeSolver::_prec\n-std::shared_ptr< Preconditioner< X, Y > > _prec\n-Definition: solver.hh:505\n-Dune::IterativeSolver::category\n-virtual SolverCategory::Category category() const\n-Category of the solver (see SolverCategory::Category)\n-Definition: solver.hh:383\n-Dune::IterativeSolver::Iteration\n-Class for controlling iterative methods.\n-Definition: solver.hh:411\n-Dune::IterativeSolver::Iteration::Iteration\n-Iteration(const IterativeSolver &parent, InverseOperatorResult &res)\n-Definition: solver.hh:413\n-Dune::IterativeSolver::Iteration::Iteration\n-Iteration(Iteration &&other)\n-Definition: solver.hh:428\n-Dune::IterativeSolver::Iteration::_res\n-InverseOperatorResult & _res\n-Definition: solver.hh:498\n-Dune::IterativeSolver::Iteration::_parent\n-const IterativeSolver & _parent\n-Definition: solver.hh:499\n-Dune::IterativeSolver::Iteration::_watch\n-Timer _watch\n-Definition: solver.hh:497\n-Dune::IterativeSolver::Iteration::Iteration\n-Iteration(const Iteration &)=delete\n-Dune::IterativeSolver::Iteration::_i\n-CountType _i\n-Definition: solver.hh:496\n-Dune::IterativeSolver::Iteration::_def0\n-real_type _def0\n-Definition: solver.hh:495\n-Dune::IterativeSolver::Iteration::step\n-bool step(CountType i, real_type def)\n-registers the iteration step, checks for invalid defect norm and convergence.\n-Definition: solver.hh:455\n-Dune::IterativeSolver::Iteration::finalize\n-void finalize()\n-Definition: solver.hh:480\n-Dune::IterativeSolver::Iteration::_def\n-real_type _def\n-Definition: solver.hh:495\n-Dune::IterativeSolver::Iteration::~Iteration\n-~Iteration()\n-Definition: solver.hh:440\n-Dune::IterativeSolver::Iteration::_valid\n-bool _valid\n-Definition: solver.hh:500\n-Dune::SolverHelper\n-Helper class for notifying a DUNE-ISTL linear solver about a change of the\n-iteration matrix object in...\n-Definition: solver.hh:522\n-Dune::SolverHelper::setMatrix\n-static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n-Definition: solver.hh:524\n-Dune::SolverHelper::Implementation\n-Implementation that works together with iterative ISTL solvers, e.g. Dune::\n-CGSolver or Dune::BiCGSTAB...\n-Definition: solver.hh:540\n-Dune::SolverHelper::Implementation::setMatrix\n-static void setMatrix(ISTLLinearSolver &, const BCRSMatrix &)\n-Definition: solver.hh:541\n-Dune::SolverHelper::Implementation<_true,_Dummy_>::setMatrix\n-static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n-Definition: solver.hh:553\n-Dune::SolverCategory\n-Categories for the solvers.\n-Definition: solvercategory.hh:22\n Dune::SolverCategory::Category\n Category\n Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n-Dune::InvalidSolverCategory\n-Definition: solvercategory.hh:54\n+Dune::UnsupportedType\n+Definition: solverregistry.hh:77\n Dune::IsDirectSolver\n Definition: solvertype.hh:16\n+Dune::IsDirectSolver::value\n+@ value\n+Whether this is a direct solver.\n+Definition: solvertype.hh:24\n+Dune::StoresColumnCompressed\n+Definition: solvertype.hh:30\n+Dune::StoresColumnCompressed::value\n+@ value\n+whether the solver internally uses column compressed storage\n+Definition: solvertype.hh:36\n+Dune::UMFPackMethodChooser\n+Definition: umfpack.hh:49\n+Dune::UMFPack\n+The UMFPack direct sparse solver.\n+Definition: umfpack.hh:215\n+Dune::UMFPackCreator\n+Definition: umfpack.hh:609\n+Dune::UMFPackCreator::isValidBlock\n+Definition: umfpack.hh:610\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00044.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00044.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixmarket.hh File Reference\n+dune-istl: bccsmatrixinitializer.hh File Reference\n \n \n \n \n \n \n \n@@ -63,266 +63,33 @@\n \n
    \n \n+
    bccsmatrixinitializer.hh File Reference
    \n
    \n
    \n-\n-

    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices. \n-More...

    \n-
    #include <algorithm>
    \n-#include <complex>
    \n-#include <cstddef>
    \n-#include <fstream>
    \n-#include <ios>
    \n-#include <iostream>
    \n-#include <istream>
    \n-#include <limits>
    \n-#include <ostream>
    \n+
    #include <limits>
    \n #include <set>
    \n-#include <sstream>
    \n-#include <string>
    \n-#include <tuple>
    \n-#include <type_traits>
    \n-#include <vector>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include <dune/common/stdstreams.hh>
    \n-#include <dune/common/simd/simd.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/bvector.hh>
    \n-#include <dune/istl/matrixutils.hh>
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/istl/bccsmatrix.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    struct  Dune::MatrixMarketImpl::mm_numeric_type< T >
     Helper metaprogram to get the matrix market string representation of the numeric type. More...
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< int >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< double >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< float >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< std::complex< double > >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< std::complex< float > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< BCRSMatrix< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< BlockVector< B, A > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< FieldVector< T, j > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< FieldMatrix< T, i, j > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< FieldVector< T, i >, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< FieldMatrix< T, i, j >, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< FieldMatrix< T, i, j > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< FieldVector< T, i > >
     
    struct  Dune::MatrixMarketImpl::MMHeader
     
    struct  Dune::MatrixMarketImpl::IndexData< T >
     
    struct  Dune::MatrixMarketImpl::NumericWrapper< T >
     a wrapper class of numeric values. More...
     
    struct  Dune::MatrixMarketImpl::PatternDummy
     Utility class for marking the pattern type of the MatrixMarket matrices. More...
     
    struct  Dune::MatrixMarketImpl::NumericWrapper< PatternDummy >
     
    struct  Dune::MatrixMarketImpl::MatrixValuesSetter< D, brows, bcols >
     Functor to the data values of the matrix. More...
     
    struct  Dune::MatrixMarketImpl::MatrixValuesSetter< PatternDummy, brows, bcols >
     
    struct  Dune::MatrixMarketImpl::is_complex< T >
     
    struct  Dune::MatrixMarketImpl::is_complex< std::complex< T > >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< M >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< B, A > >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< FieldMatrix< B, i, j >, A > >
     
    class  Dune::MatrixMarketFormatError
     
    \n \n \n \n-\n+\n \n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::MatrixMarketImpl
    namespace  Dune::ISTL
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Enumerations

    enum  Dune::MatrixMarketImpl::LineType { Dune::MatrixMarketImpl::MM_HEADER\n-, Dune::MatrixMarketImpl::MM_ISTLSTRUCT\n-, Dune::MatrixMarketImpl::DATA\n- }
     
    enum  { Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH =1025\n- }
     
    enum  Dune::MatrixMarketImpl::MM_TYPE { Dune::MatrixMarketImpl::coordinate_type\n-, Dune::MatrixMarketImpl::array_type\n-, Dune::MatrixMarketImpl::unknown_type\n- }
     
    enum  Dune::MatrixMarketImpl::MM_CTYPE {
    \n-  Dune::MatrixMarketImpl::integer_type\n-, Dune::MatrixMarketImpl::double_type\n-, Dune::MatrixMarketImpl::complex_type\n-, Dune::MatrixMarketImpl::pattern\n-,
    \n-  Dune::MatrixMarketImpl::unknown_ctype\n-
    \n- }
     
    enum  Dune::MatrixMarketImpl::MM_STRUCTURE {
    \n-  Dune::MatrixMarketImpl::general\n-, Dune::MatrixMarketImpl::symmetric\n-, Dune::MatrixMarketImpl::skew_symmetric\n-, Dune::MatrixMarketImpl::hermitian\n-,
    \n-  Dune::MatrixMarketImpl::unknown_structure\n-
    \n- }
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Functions

    bool Dune::MatrixMarketImpl::lineFeed (std::istream &file)
     
    void Dune::MatrixMarketImpl::skipComments (std::istream &file)
     
    bool Dune::MatrixMarketImpl::readMatrixMarketBanner (std::istream &file, MMHeader &mmHeader)
     
    template<std::size_t brows, std::size_t bcols>
    std::tuple< std::size_t, std::size_t, std::size_t > Dune::MatrixMarketImpl::calculateNNZ (std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader &header)
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, NumericWrapper< T > &num)
     
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, NumericWrapper< PatternDummy > &num)
     
    template<typename T >
    bool Dune::MatrixMarketImpl::operator< (const IndexData< T > &i1, const IndexData< T > &i2)
     LessThan operator. More...
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, IndexData< T > &data)
     Read IndexData from a stream. More...
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, IndexData< NumericWrapper< std::complex< T > > > &data)
     Read IndexData from a stream. Specialization for std::complex. More...
     
    template<class T >
    std::enable_if_t<!is_complex< T >::value, T > Dune::MatrixMarketImpl::conj (const T &r)
     
    template<class T >
    std::enable_if_t< is_complex< T >::value, T > Dune::MatrixMarketImpl::conj (const T &r)
     
    template<typename T , typename A , typename D >
    void Dune::MatrixMarketImpl::readSparseEntries (Dune::BCRSMatrix< T, A > &matrix, std::istream &file, std::size_t entries, const MMHeader &mmHeader, const D &)
     
    std::tuple< std::string, std::string > Dune::MatrixMarketImpl::splitFilename (const std::string &filename)
     
    void Dune::mm_read_header (std::size_t &rows, std::size_t &cols, MatrixMarketImpl::MMHeader &header, std::istream &istr, bool isVector)
     
    template<typename T , typename A >
    void Dune::mm_read_vector_entries (Dune::BlockVector< T, A > &vector, std::size_t size, std::istream &istr, size_t lane)
     
    template<typename T , typename A , int entries>
    void Dune::mm_read_vector_entries (Dune::BlockVector< Dune::FieldVector< T, entries >, A > &vector, std::size_t size, std::istream &istr, size_t lane)
     
    template<typename T , typename A >
    void Dune::readMatrixMarket (Dune::BlockVector< T, A > &vector, std::istream &istr)
     Reads a BlockVector from a matrix market file. More...
     
    template<typename T , typename A >
    void Dune::readMatrixMarket (Dune::BCRSMatrix< T, A > &matrix, std::istream &istr)
     Reads a sparse matrix from a matrix market file. More...
     
    template<typename B >
    void Dune::mm_print_entry (const B &entry, std::size_t rowidx, std::size_t colidx, std::ostream &ostr)
     
    template<typename V >
    void Dune::mm_print_vector_entry (const V &entry, std::ostream &ostr, const std::integral_constant< int, 1 > &, size_t lane)
     
    template<typename V >
    void Dune::mm_print_vector_entry (const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &, size_t lane)
     
    template<typename T , typename A >
    std::size_t Dune::countEntries (const BlockVector< T, A > &vector)
     
    template<typename T , typename A , int i>
    std::size_t Dune::countEntries (const BlockVector< FieldVector< T, i >, A > &vector)
     
    template<typename V >
    void Dune::writeMatrixMarket (const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &)
     
    template<typename M >
    void Dune::writeMatrixMarket (const M &matrix, std::ostream &ostr, const std::integral_constant< int, 1 > &)
     
    template<typename M >
    void Dune::writeMatrixMarket (const M &matrix, std::ostream &ostr)
     writes a ISTL matrix or vector to a stream in matrix market format. More...
     
    template<typename M >
    void Dune::storeMatrixMarket (const M &matrix, std::string filename, int prec=default_precision)
     Stores a parallel matrix/vector in matrix market format in a file. More...
     
    template<typename M , typename G , typename L >
    void Dune::storeMatrixMarket (const M &matrix, std::string filename, const OwnerOverlapCopyCommunication< G, L > &comm, bool storeIndices=true, int prec=default_precision)
     Stores a parallel matrix/vector in matrix market format in a file. More...
     
    template<typename M , typename G , typename L >
    void Dune::loadMatrixMarket (M &matrix, const std::string &filename, OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)
     Load a parallel matrix/vector stored in matrix market format. More...
     
    template<typename M >
    void Dune::loadMatrixMarket (M &matrix, const std::string &filename)
     Load a matrix/vector stored in matrix market format. More...
     
    \n-\n-\n-\n

    \n-Variables

    static const int Dune::default_precision = -1
     
    \n-

    Detailed Description

    \n-

    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,317 +4,23 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Enumerations | Functions | Variables\n-matrixmarket.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes \u00bb\n-IO_for_matrices_and_vectors.\n-Provides classes for reading and writing MatrixMarket Files with an extension\n-for parallel matrices. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Namespaces\n+bccsmatrixinitializer.hh File Reference\n #include \n-#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n- Classes\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_T_>\n-\u00a0 Helper metaprogram to get the matrix market string representation of\n- the numeric type. More...\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_int_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_double_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_float_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_double_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_float_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_BCRSMatrix<_T,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_BlockVector<_B,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_FieldVector<_T,_j_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_FieldMatrix<_T,_i,_j_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>\n- >\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<\n- FieldVector<_T,_i_>,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>\n- >\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<\n- FieldMatrix<_T,_i,_j_>,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,\n- j_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>\n- >\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::MMHeader\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::IndexData<_T_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::NumericWrapper<_T_>\n-\u00a0 a wrapper class of numeric values. More...\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::PatternDummy\n-\u00a0 Utility class for marking the pattern type of the MatrixMarket\n- matrices. More...\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::NumericWrapper<_PatternDummy_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::MatrixValuesSetter<_D,_brows,_bcols_>\n-\u00a0 Functor to the data values of the matrix. More...\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::MatrixValuesSetter<_PatternDummy,_brows,_bcols\n- >\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::is_complex<_T_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::is_complex<_std::complex<_T_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_M_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_BCRSMatrix<_B,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_BCRSMatrix<_FieldMatrix<_B,_i,\n- j_>,_A_>_>\n-\u00a0\n- class \u00a0Dune::MatrixMarketFormatError\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::MatrixMarketImpl\n-\u00a0\n- Enumerations\n-enum Dune::MatrixMarketImpl::LineType { Dune::MatrixMarketImpl::MM_HEADER , Dune::\n- \u00a0MatrixMarketImpl::MM_ISTLSTRUCT , Dune::MatrixMarketImpl::DATA }\n-\u00a0\n-enum\n- \u00a0{ Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH =1025 }\n-\u00a0\n-enum Dune::MatrixMarketImpl::MM_TYPE { Dune::MatrixMarketImpl::coordinate_type ,\n- \u00a0Dune::MatrixMarketImpl::array_type , Dune::MatrixMarketImpl::unknown_type }\n-\u00a0\n-enum Dune::MatrixMarketImpl::MM_CTYPE {\n- \u00a0\u00a0\u00a0Dune::MatrixMarketImpl::integer_type , Dune::MatrixMarketImpl::double_type ,\n- Dune::MatrixMarketImpl::complex_type , Dune::MatrixMarketImpl::pattern ,\n- \u00a0\u00a0Dune::MatrixMarketImpl::unknown_ctype\n- }\n-\u00a0\n-enum Dune::MatrixMarketImpl::MM_STRUCTURE {\n- \u00a0\u00a0\u00a0Dune::MatrixMarketImpl::general , Dune::MatrixMarketImpl::symmetric , Dune::\n- MatrixMarketImpl::skew_symmetric , Dune::MatrixMarketImpl::hermitian ,\n- \u00a0\u00a0Dune::MatrixMarketImpl::unknown_structure\n- }\n-\u00a0\n- Functions\n- bool\u00a0Dune::MatrixMarketImpl::lineFeed (std::\n- istream &file)\n-\u00a0\n- void\u00a0Dune::MatrixMarketImpl::skipComments\n- (std::istream &file)\n-\u00a0\n- bool\u00a0Dune::MatrixMarketImpl::\n- readMatrixMarketBanner (std::istream\n- &file, MMHeader &mmHeader)\n-\u00a0\n-template\n- std::tuple< std::size_t, std::size_t, Dune::MatrixMarketImpl::calculateNNZ\n- std::size_t >\u00a0(std::size_t rows, std::size_t cols,\n- std::size_t entries, const MMHeader\n- &header)\n-\u00a0\n-template\n- std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n- (std::istream &is, NumericWrapper< T >\n- &num)\n-\u00a0\n- std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n- (std::istream &is, NumericWrapper<\n- PatternDummy > &num)\n-\u00a0\n-template\n- bool\u00a0Dune::MatrixMarketImpl::operator<\n- (const IndexData< T > &i1, const\n- IndexData< T > &i2)\n-\u00a0 LessThan operator. More...\n-\u00a0\n-template\n- std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n- (std::istream &is, IndexData< T >\n- &data)\n-\u00a0 Read IndexData from a stream. More...\n-\u00a0\n-template\n- std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n- (std::istream &is, IndexData<\n- NumericWrapper< std::complex< T > > >\n- &data)\n- Read IndexData from a stream.\n-\u00a0 Specialization for std::complex.\n- More...\n-\u00a0\n-template\n- std::enable_if_t:: Dune::MatrixMarketImpl::conj (const T\n- value, T >\u00a0&r)\n-\u00a0\n-template\n- std::enable_if_t< is_complex< T >:: Dune::MatrixMarketImpl::conj (const T\n- value, T >\u00a0&r)\n-\u00a0\n-template\n- void\u00a0Dune::MatrixMarketImpl::\n- readSparseEntries (Dune::BCRSMatrix< T,\n- A > &matrix, std::istream &file, std::\n- size_t entries, const MMHeader\n- &mmHeader, const D &)\n-\u00a0\n-std::tuple< std::string, std::string >\u00a0Dune::MatrixMarketImpl::splitFilename\n- (const std::string &filename)\n-\u00a0\n- void\u00a0Dune::mm_read_header (std::size_t\n- &rows, std::size_t &cols,\n- MatrixMarketImpl::MMHeader &header,\n- std::istream &istr, bool isVector)\n-\u00a0\n-template\n- void\u00a0Dune::mm_read_vector_entries (Dune::\n- BlockVector< T, A > &vector, std::\n- size_t size, std::istream &istr, size_t\n- lane)\n-\u00a0\n-template\n- void\u00a0Dune::mm_read_vector_entries (Dune::\n- BlockVector< Dune::FieldVector< T,\n- entries >, A > &vector, std::size_t\n- size, std::istream &istr, size_t lane)\n-\u00a0\n-template\n- void\u00a0Dune::readMatrixMarket (Dune::\n- BlockVector< T, A > &vector, std::\n- istream &istr)\n-\u00a0 Reads a BlockVector from a matrix\n- market file. More...\n-\u00a0\n-template\n- void\u00a0Dune::readMatrixMarket (Dune::\n- BCRSMatrix< T, A > &matrix, std::\n- istream &istr)\n-\u00a0 Reads a sparse matrix from a matrix\n- market file. More...\n-\u00a0\n-template\n- void\u00a0Dune::mm_print_entry (const B &entry,\n- std::size_t rowidx, std::size_t colidx,\n- std::ostream &ostr)\n-\u00a0\n-template\n- void\u00a0Dune::mm_print_vector_entry (const V\n- &entry, std::ostream &ostr, const std::\n- integral_constant< int, 1 > &, size_t\n- lane)\n-\u00a0\n-template\n- void\u00a0Dune::mm_print_vector_entry (const V\n- &vector, std::ostream &ostr, const\n- std::integral_constant< int, 0 > &,\n- size_t lane)\n-\u00a0\n-template\n- std::size_t\u00a0Dune::countEntries (const BlockVector<\n- T, A > &vector)\n-\u00a0\n-template\n- std::size_t\u00a0Dune::countEntries (const BlockVector<\n- FieldVector< T, i >, A > &vector)\n-\u00a0\n-template\n- void\u00a0Dune::writeMatrixMarket (const V\n- &vector, std::ostream &ostr, const\n- std::integral_constant< int, 0 > &)\n-\u00a0\n-template\n- void\u00a0Dune::writeMatrixMarket (const M\n- &matrix, std::ostream &ostr, const\n- std::integral_constant< int, 1 > &)\n-\u00a0\n-template\n- void\u00a0Dune::writeMatrixMarket (const M\n- &matrix, std::ostream &ostr)\n-\u00a0 writes a ISTL matrix or vector to a\n- stream in matrix market format. More...\n-\u00a0\n-template\n- void\u00a0Dune::storeMatrixMarket (const M\n- &matrix, std::string filename, int\n- prec=default_precision)\n-\u00a0 Stores a parallel matrix/vector in\n- matrix market format in a file. More...\n-\u00a0\n-template\n- void\u00a0Dune::storeMatrixMarket (const M\n- &matrix, std::string filename, const\n- OwnerOverlapCopyCommunication< G, L >\n- &comm, bool storeIndices=true, int\n- prec=default_precision)\n-\u00a0 Stores a parallel matrix/vector in\n- matrix market format in a file. More...\n-\u00a0\n-template\n- void\u00a0Dune::loadMatrixMarket (M &matrix,\n- const std::string &filename,\n- OwnerOverlapCopyCommunication< G, L >\n- &comm, bool readIndices=true)\n-\u00a0 Load a parallel matrix/vector stored in\n- matrix market format. More...\n-\u00a0\n-template\n- void\u00a0Dune::loadMatrixMarket (M &matrix,\n- const std::string &filename)\n-\u00a0 Load a matrix/vector stored in matrix\n- market format. More...\n-\u00a0\n- Variables\n-static const int\u00a0Dune::default_precision = -1\n+namespace \u00a0Dune::ISTL\n \u00a0\n-***** Detailed Description *****\n-Provides classes for reading and writing MatrixMarket Files with an extension\n-for parallel matrices.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00044_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00044_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixmarket.hh Source File\n+dune-istl: bccsmatrixinitializer.hh Source File\n \n \n \n \n \n \n \n@@ -62,1343 +62,344 @@\n \n
    \n \n
    \n
    \n
    \n-
    matrixmarket.hh
    \n+
    bccsmatrixinitializer.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MATRIXMARKET_HH
    \n-
    6#define DUNE_ISTL_MATRIXMARKET_HH
    \n+
    5#ifndef DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH
    \n+
    6#define DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH
    \n
    7
    \n-
    8#include <algorithm>
    \n-
    9#include <complex>
    \n-
    10#include <cstddef>
    \n-
    11#include <fstream>
    \n-
    12#include <ios>
    \n-
    13#include <iostream>
    \n-
    14#include <istream>
    \n-
    15#include <limits>
    \n-
    16#include <ostream>
    \n-
    17#include <set>
    \n-
    18#include <sstream>
    \n-
    19#include <string>
    \n-
    20#include <tuple>
    \n-
    21#include <type_traits>
    \n-
    22#include <vector>
    \n-
    23
    \n-
    24#include <dune/common/exceptions.hh>
    \n-
    25#include <dune/common/fmatrix.hh>
    \n-
    26#include <dune/common/fvector.hh>
    \n-
    27#include <dune/common/hybridutilities.hh>
    \n-
    28#include <dune/common/stdstreams.hh>
    \n-
    29#include <dune/common/simd/simd.hh>
    \n-
    30
    \n-\n-
    32#include <dune/istl/bvector.hh>
    \n-
    33#include <dune/istl/matrixutils.hh> // countNonZeros()
    \n-\n-
    35
    \n-
    36namespace Dune
    \n-
    37{
    \n-
    38
    \n-
    64 namespace MatrixMarketImpl
    \n-
    65 {
    \n-
    75 template<class T>
    \n-\n-
    77 enum {
    \n-
    81 is_numeric=false
    \n-
    82 };
    \n-
    83 };
    \n-
    84
    \n-
    85 template<>
    \n-
    86 struct mm_numeric_type<int>
    \n-
    87 {
    \n-
    88 enum {
    \n-
    92 is_numeric=true
    \n-
    93 };
    \n-
    94
    \n-
    95 static std::string str()
    \n-
    96 {
    \n-
    97 return "integer";
    \n-
    98 }
    \n-
    99 };
    \n-
    100
    \n-
    101 template<>
    \n-
    102 struct mm_numeric_type<double>
    \n-
    103 {
    \n-
    104 enum {
    \n-
    108 is_numeric=true
    \n-
    109 };
    \n-
    110
    \n-
    111 static std::string str()
    \n-
    112 {
    \n-
    113 return "real";
    \n-
    114 }
    \n-
    115 };
    \n-
    116
    \n-
    117 template<>
    \n-
    118 struct mm_numeric_type<float>
    \n-
    119 {
    \n-
    120 enum {
    \n-
    124 is_numeric=true
    \n-
    125 };
    \n-
    126
    \n-
    127 static std::string str()
    \n-
    128 {
    \n-
    129 return "real";
    \n-
    130 }
    \n-
    131 };
    \n-
    132
    \n-
    133 template<>
    \n-
    134 struct mm_numeric_type<std::complex<double> >
    \n-
    135 {
    \n-
    136 enum {
    \n-
    140 is_numeric=true
    \n-
    141 };
    \n-
    142
    \n-
    143 static std::string str()
    \n-
    144 {
    \n-
    145 return "complex";
    \n-
    146 }
    \n-
    147 };
    \n-
    148
    \n-
    149 template<>
    \n-
    150 struct mm_numeric_type<std::complex<float> >
    \n-
    151 {
    \n-
    152 enum {
    \n-
    156 is_numeric=true
    \n-
    157 };
    \n-
    158
    \n-
    159 static std::string str()
    \n-
    160 {
    \n-
    161 return "complex";
    \n-
    162 }
    \n-
    163 };
    \n-
    164
    \n-
    173 template<class M>
    \n-\n+
    8#include <limits>
    \n+
    9#include <set>
    \n+
    10
    \n+
    11#include <dune/common/typetraits.hh>
    \n+
    12#include <dune/common/scalarmatrixview.hh>
    \n+
    13
    \n+\n+
    15
    \n+
    16namespace Dune
    \n+
    17{
    \n+
    18 template<class I, class S, class D>
    \n+
    19 class OverlappingSchwarzInitializer;
    \n+
    20}
    \n+
    21
    \n+
    22namespace Dune::ISTL::Impl
    \n+
    23{
    \n+
    31 template<class M, class S>
    \n+
    32 class MatrixRowSubset
    \n+
    33 {
    \n+
    34 public:
    \n+
    36 typedef M Matrix;
    \n+
    38 typedef S RowIndexSet;
    \n+
    39
    \n+
    45 MatrixRowSubset(const Matrix& m, const RowIndexSet& s)
    \n+
    46 : m_(m), s_(s)
    \n+
    47 {}
    \n+
    48
    \n+
    49 const Matrix& matrix() const
    \n+
    50 {
    \n+
    51 return m_;
    \n+
    52 }
    \n+
    53
    \n+
    54 const RowIndexSet& rowIndexSet() const
    \n+
    55 {
    \n+
    56 return s_;
    \n+
    57 }
    \n+
    58
    \n+
    60 class const_iterator
    \n+
    61 : public ForwardIteratorFacade<const_iterator, const typename Matrix::row_type>
    \n+
    62 {
    \n+
    63 public:
    \n+
    64 const_iterator(typename Matrix::const_iterator firstRow,
    \n+
    65 typename RowIndexSet::const_iterator pos)
    \n+
    66 : firstRow_(firstRow), pos_(pos)
    \n+
    67 {}
    \n+
    68
    \n+
    69
    \n+
    70 const typename Matrix::row_type& dereference() const
    \n+
    71 {
    \n+
    72 return *(firstRow_+ *pos_);
    \n+
    73 }
    \n+
    74 bool equals(const const_iterator& o) const
    \n+
    75 {
    \n+
    76 return pos_==o.pos_;
    \n+
    77 }
    \n+
    78 void increment()
    \n+
    79 {
    \n+
    80 ++pos_;
    \n+
    81 }
    \n+
    82 typename RowIndexSet::value_type index() const
    \n+
    83 {
    \n+
    84 return *pos_;
    \n+
    85 }
    \n+
    86
    \n+
    87 private:
    \n+
    89 typename Matrix::const_iterator firstRow_;
    \n+
    91 typename RowIndexSet::const_iterator pos_;
    \n+
    92 };
    \n+
    93
    \n+
    95 const_iterator begin() const
    \n+
    96 {
    \n+
    97 return const_iterator(m_.begin(), s_.begin());
    \n+
    98 }
    \n+
    100 const_iterator end() const
    \n+
    101 {
    \n+
    102 return const_iterator(m_.begin(), s_.end());
    \n+
    103 }
    \n+
    104
    \n+
    105 private:
    \n+
    107 const Matrix& m_;
    \n+
    109 const RowIndexSet& s_;
    \n+
    110 };
    \n+
    111
    \n+
    118 template<class M, class I = typename M::size_type>
    \n+
    119 class BCCSMatrixInitializer
    \n+
    120 {
    \n+
    121 template<class IList, class S, class D>
    \n+\n+
    123 public:
    \n+
    124 using Matrix = M;
    \n+
    125 using Index = I;
    \n+
    126 typedef Dune::ISTL::Impl::BCCSMatrix<typename Matrix::field_type, I> OutputMatrix;
    \n+
    127 typedef typename Matrix::size_type size_type;
    \n+
    128
    \n+
    131 BCCSMatrixInitializer(OutputMatrix& mat_)
    \n+
    132 : mat(&mat_), cols(mat_.M())
    \n+
    133 {
    \n+
    134 if constexpr (Dune::IsNumber<typename M::block_type>::value)
    \n+
    135 {
    \n+
    136 n = m = 1;
    \n+
    137 }
    \n+
    138 else
    \n+
    139 {
    \n+
    140 // WARNING: This assumes that all blocks are dense and identical
    \n+
    141 n = M::block_type::rows;
    \n+
    142 m = M::block_type::cols;
    \n+
    143 }
    \n+
    144
    \n+
    145 mat->Nnz_=0;
    \n+
    146 }
    \n+
    147
    \n+
    148 BCCSMatrixInitializer()
    \n+
    149 : mat(0), cols(0), n(0), m(0)
    \n+
    150 {}
    \n+
    151
    \n+
    152 virtual ~BCCSMatrixInitializer()
    \n+
    153 {}
    \n+
    154
    \n+
    155 template<typename Iter>
    \n+
    156 void addRowNnz(const Iter& row) const
    \n+
    157 {
    \n+
    158 mat->Nnz_+=row->getsize();
    \n+
    159 }
    \n+
    160
    \n+
    161 template<typename Iter, typename FullMatrixIndex>
    \n+
    162 void addRowNnz(const Iter& row, const std::set<FullMatrixIndex>& indices) const
    \n+
    163 {
    \n+
    164 auto siter =indices.begin();
    \n+
    165 for (auto entry=row->begin(); entry!=row->end(); ++entry)
    \n+
    166 {
    \n+
    167 for(; siter!=indices.end() && *siter<entry.index(); ++siter) ;
    \n+
    168 if(siter==indices.end())
    \n+
    169 break;
    \n+
    170 if(*siter==entry.index())
    \n+
    171 // index is in subdomain
    \n+
    172 ++mat->Nnz_;
    \n+
    173 }
    \n+
    174 }
    \n
    175
    \n-
    176 template<typename T, typename A>
    \n-\n-
    178 {
    \n-
    179 static void print(std::ostream& os)
    \n-
    180 {
    \n-
    181 os<<"%%MatrixMarket matrix coordinate ";
    \n-
    182 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<T>::field_type>>::str()<<" general"<<std::endl;
    \n-
    183 }
    \n-
    184 };
    \n-
    185
    \n-
    186 template<typename B, typename A>
    \n-\n-
    188 {
    \n-
    189 static void print(std::ostream& os)
    \n-
    190 {
    \n-
    191 os<<"%%MatrixMarket matrix array ";
    \n-
    192 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<B>::field_type>>::str()<<" general"<<std::endl;
    \n-
    193 }
    \n-
    194 };
    \n+
    176 template<typename Iter, typename SubMatrixIndex>
    \n+
    177 void addRowNnz(const Iter& row, const std::vector<SubMatrixIndex>& indices) const
    \n+
    178 {
    \n+
    179 for (auto entry=row->begin(); entry!=row->end(); ++entry)
    \n+
    180 if (indices[entry.index()]!=std::numeric_limits<SubMatrixIndex>::max())
    \n+
    181 ++mat->Nnz_;
    \n+
    182 }
    \n+
    183
    \n+
    184 void allocate()
    \n+
    185 {
    \n+
    186 allocateMatrixStorage();
    \n+
    187 allocateMarker();
    \n+
    188 }
    \n+
    189
    \n+
    190 template<typename Iter, typename CIter>
    \n+
    191 void countEntries([[maybe_unused]] const Iter& row, const CIter& col) const
    \n+
    192 {
    \n+
    193 countEntries(col.index());
    \n+
    194 }
    \n
    195
    \n-
    196 template<typename T, int j>
    \n-
    197 struct mm_header_printer<FieldVector<T,j> >
    \n-
    198 {
    \n-
    199 static void print(std::ostream& os)
    \n-
    200 {
    \n-
    201 os<<"%%MatrixMarket matrix array ";
    \n-
    202 os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
    \n-
    203 }
    \n-
    204 };
    \n-
    205
    \n-
    206 template<typename T, int i, int j>
    \n-\n-
    208 {
    \n-
    209 static void print(std::ostream& os)
    \n-
    210 {
    \n-
    211 os<<"%%MatrixMarket matrix array ";
    \n-
    212 os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
    \n-
    213 }
    \n-
    214 };
    \n-
    215
    \n-
    224 template<class M>
    \n-\n-
    226
    \n-
    227 template<typename T, typename A>
    \n-\n-
    229 {
    \n-\n-
    231 static_assert(IsNumber<T>::value, "Only scalar entries are expected here!");
    \n-
    232
    \n-
    233 static void print(std::ostream& os, const M&)
    \n-
    234 {
    \n-
    235 os<<"% ISTL_STRUCT blocked ";
    \n-
    236 os<<"1 1"<<std::endl;
    \n-
    237 }
    \n-
    238 };
    \n+
    196 void countEntries(size_type colindex) const
    \n+
    197 {
    \n+
    198 for(size_type i=0; i < m; ++i)
    \n+
    199 {
    \n+
    200 assert(colindex*m+i<cols);
    \n+
    201 marker[colindex*m+i]+=n;
    \n+
    202 }
    \n+
    203 }
    \n+
    204
    \n+
    205 void calcColstart() const
    \n+
    206 {
    \n+
    207 mat->colstart[0]=0;
    \n+
    208 for(size_type i=0; i < cols; ++i) {
    \n+
    209 assert(i<cols);
    \n+
    210 mat->colstart[i+1]=mat->colstart[i]+marker[i];
    \n+
    211 marker[i]=mat->colstart[i];
    \n+
    212 }
    \n+
    213 }
    \n+
    214
    \n+
    215 template<typename Iter, typename CIter>
    \n+
    216 void copyValue(const Iter& row, const CIter& col) const
    \n+
    217 {
    \n+
    218 copyValue(col, row.index(), col.index());
    \n+
    219 }
    \n+
    220
    \n+
    221 template<typename CIter>
    \n+
    222 void copyValue(const CIter& col, size_type rowindex, size_type colindex) const
    \n+
    223 {
    \n+
    224 for(size_type i=0; i<n; i++) {
    \n+
    225 for(size_type j=0; j<m; j++) {
    \n+
    226 assert(colindex*m+j<cols-1 || (size_type)marker[colindex*m+j]<(size_type)mat->colstart[colindex*m+j+1]);
    \n+
    227 assert((size_type)marker[colindex*m+j]<mat->Nnz_);
    \n+
    228 mat->rowindex[marker[colindex*m+j]]=rowindex*n+i;
    \n+
    229 mat->values[marker[colindex*m+j]] = Dune::Impl::asMatrix(*col)[i][j];
    \n+
    230 ++marker[colindex*m+j]; // index for next entry in column
    \n+
    231 }
    \n+
    232 }
    \n+
    233 }
    \n+
    234
    \n+
    235 virtual void createMatrix() const
    \n+
    236 {
    \n+
    237 marker.clear();
    \n+
    238 }
    \n
    239
    \n-
    240 template<typename T, typename A, int i>
    \n-
    241 struct mm_block_structure_header<BlockVector<FieldVector<T,i>,A> >
    \n-
    242 {
    \n-\n-
    244
    \n-
    245 static void print(std::ostream& os, const M&)
    \n-
    246 {
    \n-
    247 os<<"% ISTL_STRUCT blocked ";
    \n-
    248 os<<i<<" "<<1<<std::endl;
    \n-
    249 }
    \n-
    250 };
    \n-
    251
    \n-
    252 template<typename T, typename A>
    \n-\n-
    254 {
    \n-\n-
    256 static_assert(IsNumber<T>::value, "Only scalar entries are expected here!");
    \n-
    257
    \n-
    258 static void print(std::ostream& os, const M&)
    \n-
    259 {
    \n-
    260 os<<"% ISTL_STRUCT blocked ";
    \n-
    261 os<<"1 1"<<std::endl;
    \n-
    262 }
    \n-
    263 };
    \n-
    264
    \n-
    265 template<typename T, typename A, int i, int j>
    \n-\n-
    267 {
    \n-\n-
    269
    \n-
    270 static void print(std::ostream& os, const M&)
    \n-
    271 {
    \n-
    272 os<<"% ISTL_STRUCT blocked ";
    \n-
    273 os<<i<<" "<<j<<std::endl;
    \n-
    274 }
    \n-
    275 };
    \n+
    240 protected:
    \n+
    241
    \n+
    242 void allocateMatrixStorage() const
    \n+
    243 {
    \n+
    244 mat->Nnz_*=n*m;
    \n+
    245 // initialize data
    \n+
    246 mat->values=new typename M::field_type[mat->Nnz_];
    \n+
    247 mat->rowindex=new I[mat->Nnz_];
    \n+
    248 mat->colstart=new I[cols+1];
    \n+
    249 }
    \n+
    250
    \n+
    251 void allocateMarker()
    \n+
    252 {
    \n+
    253 marker.resize(cols);
    \n+
    254 std::fill(marker.begin(), marker.end(), 0);
    \n+
    255 }
    \n+
    256
    \n+
    257 OutputMatrix* mat;
    \n+
    258 size_type cols;
    \n+
    259
    \n+
    260 // Number of rows/columns of the matrix entries
    \n+
    261 // (assumed to be scalars or dense matrices)
    \n+
    262 size_type n, m;
    \n+
    263
    \n+
    264 mutable std::vector<size_type> marker;
    \n+
    265 };
    \n+
    266
    \n+
    267 template<class F, class Matrix>
    \n+
    268 void copyToBCCSMatrix(F& initializer, const Matrix& matrix)
    \n+
    269 {
    \n+
    270 for (auto row=matrix.begin(); row!= matrix.end(); ++row)
    \n+
    271 initializer.addRowNnz(row);
    \n+
    272
    \n+
    273 initializer.allocate();
    \n+
    274
    \n+
    275 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {
    \n
    276
    \n-
    277
    \n-
    278 template<typename T, int i, int j>
    \n-\n-
    280 {
    \n-\n+
    277 for (auto col=row->begin(); col != row->end(); ++col)
    \n+
    278 initializer.countEntries(row, col);
    \n+
    279 }
    \n+
    280
    \n+
    281 initializer.calcColstart();
    \n
    282
    \n-
    283 static void print(std::ostream& os, const M& m)
    \n-
    284 {}
    \n-
    285 };
    \n-
    286
    \n-
    287 template<typename T, int i>
    \n-
    288 struct mm_block_structure_header<FieldVector<T,i> >
    \n-
    289 {
    \n-
    290 typedef FieldVector<T,i> M;
    \n+
    283 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {
    \n+
    284 for (auto col=row->begin(); col != row->end(); ++col) {
    \n+
    285 initializer.copyValue(row, col);
    \n+
    286 }
    \n+
    287
    \n+
    288 }
    \n+
    289 initializer.createMatrix();
    \n+
    290 }
    \n
    291
    \n-
    292 static void print(std::ostream& os, const M& m)
    \n-
    293 {}
    \n-
    294 };
    \n-
    295
    \n-\n-
    297 enum { MM_MAX_LINE_LENGTH=1025 };
    \n-
    298
    \n-\n-
    300
    \n-\n-
    302
    \n-\n-
    304
    \n-
    305 struct MMHeader
    \n-
    306 {
    \n-\n-\n-
    309 {}
    \n-\n-\n-\n-
    313 };
    \n-
    314
    \n-
    315 inline bool lineFeed(std::istream& file)
    \n-
    316 {
    \n-
    317 char c;
    \n-
    318 if(!file.eof())
    \n-
    319 c=file.peek();
    \n-
    320 else
    \n-
    321 return false;
    \n-
    322 // ignore whitespace
    \n-
    323 while(c==' ')
    \n-
    324 {
    \n-
    325 file.get();
    \n-
    326 if(file.eof())
    \n-
    327 return false;
    \n-
    328 c=file.peek();
    \n-
    329 }
    \n-
    330
    \n-
    331 if(c=='\\n') {
    \n-
    332 /* eat the line feed */
    \n-
    333 file.get();
    \n-
    334 return true;
    \n-
    335 }
    \n-
    336 return false;
    \n-
    337 }
    \n-
    338
    \n-
    339 inline void skipComments(std::istream& file)
    \n-
    340 {
    \n-
    341 lineFeed(file);
    \n-
    342 char c=file.peek();
    \n-
    343 // ignore comment lines
    \n-
    344 while(c=='%')
    \n-
    345 {
    \n-
    346 /* discard the rest of the line */
    \n-
    347 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    348 c=file.peek();
    \n-
    349 }
    \n-
    350 }
    \n-
    351
    \n-
    352
    \n-
    353 inline bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)
    \n-
    354 {
    \n-
    355 std::string buffer;
    \n-
    356 char c;
    \n-
    357 file >> buffer;
    \n-
    358 c=buffer[0];
    \n-
    359 mmHeader=MMHeader();
    \n-
    360 if(c!='%')
    \n-
    361 return false;
    \n-
    362 dverb<<buffer<<std::endl;
    \n-
    363 /* read the banner */
    \n-
    364 if(buffer!="%%MatrixMarket") {
    \n-
    365 /* discard the rest of the line */
    \n-
    366 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    367 return false;
    \n-
    368 }
    \n-
    369
    \n-
    370 if(lineFeed(file))
    \n-
    371 /* premature end of line */
    \n-
    372 return false;
    \n-
    373
    \n-
    374 /* read the matrix_type */
    \n-
    375 file >> buffer;
    \n-
    376
    \n-
    377 if(buffer != "matrix")
    \n-
    378 {
    \n-
    379 /* discard the rest of the line */
    \n-
    380 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    381 return false;
    \n-
    382 }
    \n-
    383
    \n-
    384 if(lineFeed(file))
    \n-
    385 /* premature end of line */
    \n-
    386 return false;
    \n-
    387
    \n-
    388 /* The type of the matrix */
    \n-
    389 file >> buffer;
    \n-
    390
    \n-
    391 if(buffer.empty())
    \n-
    392 return false;
    \n-
    393
    \n-
    394 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n-
    395 ::tolower);
    \n-
    396
    \n-
    397 switch(buffer[0])
    \n-
    398 {
    \n-
    399 case 'a' :
    \n-
    400 /* sanity check */
    \n-
    401 if(buffer != "array")
    \n-
    402 {
    \n-
    403 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    404 return false;
    \n-
    405 }
    \n-
    406 mmHeader.type=array_type;
    \n-
    407 break;
    \n-
    408 case 'c' :
    \n-
    409 /* sanity check */
    \n-
    410 if(buffer != "coordinate")
    \n-
    411 {
    \n-
    412 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    413 return false;
    \n-
    414 }
    \n-
    415 mmHeader.type=coordinate_type;
    \n-
    416 break;
    \n-
    417 default :
    \n-
    418 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    419 return false;
    \n-
    420 }
    \n-
    421
    \n-
    422 if(lineFeed(file))
    \n-
    423 /* premature end of line */
    \n-
    424 return false;
    \n-
    425
    \n-
    426 /* The numeric type used. */
    \n-
    427 file >> buffer;
    \n-
    428
    \n-
    429 if(buffer.empty())
    \n-
    430 return false;
    \n-
    431
    \n-
    432 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n-
    433 ::tolower);
    \n-
    434 switch(buffer[0])
    \n-
    435 {
    \n-
    436 case 'i' :
    \n-
    437 /* sanity check */
    \n-
    438 if(buffer != "integer")
    \n-
    439 {
    \n-
    440 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    441 return false;
    \n-
    442 }
    \n-
    443 mmHeader.ctype=integer_type;
    \n-
    444 break;
    \n-
    445 case 'r' :
    \n-
    446 /* sanity check */
    \n-
    447 if(buffer != "real")
    \n-
    448 {
    \n-
    449 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    450 return false;
    \n-
    451 }
    \n-
    452 mmHeader.ctype=double_type;
    \n-
    453 break;
    \n-
    454 case 'c' :
    \n-
    455 /* sanity check */
    \n-
    456 if(buffer != "complex")
    \n-
    457 {
    \n-
    458 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    459 return false;
    \n-
    460 }
    \n-
    461 mmHeader.ctype=complex_type;
    \n-
    462 break;
    \n-
    463 case 'p' :
    \n-
    464 /* sanity check */
    \n-
    465 if(buffer != "pattern")
    \n-
    466 {
    \n-
    467 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    468 return false;
    \n-
    469 }
    \n-
    470 mmHeader.ctype=pattern;
    \n-
    471 break;
    \n-
    472 default :
    \n-
    473 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    474 return false;
    \n-
    475 }
    \n-
    476
    \n-
    477 if(lineFeed(file))
    \n-
    478 return false;
    \n-
    479
    \n-
    480 file >> buffer;
    \n-
    481
    \n-
    482 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n-
    483 ::tolower);
    \n-
    484 switch(buffer[0])
    \n-
    485 {
    \n-
    486 case 'g' :
    \n-
    487 /* sanity check */
    \n-
    488 if(buffer != "general")
    \n-
    489 {
    \n-
    490 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    491 return false;
    \n-
    492 }
    \n-
    493 mmHeader.structure=general;
    \n-
    494 break;
    \n-
    495 case 'h' :
    \n-
    496 /* sanity check */
    \n-
    497 if(buffer != "hermitian")
    \n-
    498 {
    \n-
    499 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    500 return false;
    \n-
    501 }
    \n-
    502 mmHeader.structure=hermitian;
    \n-
    503 break;
    \n-
    504 case 's' :
    \n-
    505 if(buffer.size()==1) {
    \n-
    506 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    507 return false;
    \n-
    508 }
    \n-
    509
    \n-
    510 switch(buffer[1])
    \n-
    511 {
    \n-
    512 case 'y' :
    \n-
    513 /* sanity check */
    \n-
    514 if(buffer != "symmetric")
    \n-
    515 {
    \n-
    516 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    517 return false;
    \n-
    518 }
    \n-
    519 mmHeader.structure=symmetric;
    \n-
    520 break;
    \n-
    521 case 'k' :
    \n-
    522 /* sanity check */
    \n-
    523 if(buffer != "skew-symmetric")
    \n-
    524 {
    \n-
    525 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    526 return false;
    \n-
    527 }
    \n-
    528 mmHeader.structure=skew_symmetric;
    \n-
    529 break;
    \n-
    530 default :
    \n-
    531 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    532 return false;
    \n-
    533 }
    \n-
    534 break;
    \n-
    535 default :
    \n-
    536 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    537 return false;
    \n-
    538 }
    \n-
    539 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    540 c=file.peek();
    \n-
    541 return true;
    \n-
    542
    \n-
    543 }
    \n-
    544
    \n-
    545 template<std::size_t brows, std::size_t bcols>
    \n-
    546 std::tuple<std::size_t, std::size_t, std::size_t>
    \n-
    547 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader& header)
    \n-
    548 {
    \n-
    549 std::size_t blockrows=rows/brows;
    \n-
    550 std::size_t blockcols=cols/bcols;
    \n-
    551 std::size_t blocksize=brows*bcols;
    \n-
    552 std::size_t blockentries=0;
    \n-
    553
    \n-
    554 switch(header.structure)
    \n-
    555 {
    \n-
    556 case general :
    \n-
    557 blockentries = entries/blocksize; break;
    \n-
    558 case skew_symmetric :
    \n-
    559 blockentries = 2*entries/blocksize; break;
    \n-
    560 case symmetric :
    \n-
    561 blockentries = (2*entries-rows)/blocksize; break;
    \n-
    562 case hermitian :
    \n-
    563 blockentries = (2*entries-rows)/blocksize; break;
    \n-
    564 default :
    \n-
    565 throw Dune::NotImplemented();
    \n-
    566 }
    \n-
    567 return std::make_tuple(blockrows, blockcols, blockentries);
    \n-
    568 }
    \n-
    569
    \n-
    570 /*
    \n-
    571 * @brief Storage class for the column index and the numeric value.
    \n-
    572 *
    \n-
    573 * \\tparam T Either a NumericWrapper of the numeric type or PatternDummy
    \n-
    574 * for MatrixMarket pattern case.
    \n-
    575 */
    \n-
    576 template<typename T>
    \n-
    577 struct IndexData : public T
    \n-
    578 {
    \n-
    579 std::size_t index = {};
    \n-
    580 };
    \n-
    581
    \n-
    582
    \n-
    593 template<typename T>
    \n-\n-
    595 {
    \n-
    596 T number = {};
    \n-
    597 operator T&()
    \n-
    598 {
    \n-
    599 return number;
    \n-
    600 }
    \n-
    601 };
    \n-
    602
    \n-\n-
    607 {};
    \n-
    608
    \n-
    609 template<>
    \n-\n-
    611 {};
    \n-
    612
    \n-
    613 template<typename T>
    \n-
    614 std::istream& operator>>(std::istream& is, NumericWrapper<T>& num)
    \n-
    615 {
    \n-
    616 return is>>num.number;
    \n-
    617 }
    \n-
    618
    \n-
    619 inline std::istream& operator>>(std::istream& is, [[maybe_unused]] NumericWrapper<PatternDummy>& num)
    \n-
    620 {
    \n-
    621 return is;
    \n-
    622 }
    \n-
    623
    \n-
    629 template<typename T>
    \n-
    630 bool operator<(const IndexData<T>& i1, const IndexData<T>& i2)
    \n-
    631 {
    \n-
    632 return i1.index<i2.index;
    \n-
    633 }
    \n-
    634
    \n-
    640 template<typename T>
    \n-
    641 std::istream& operator>>(std::istream& is, IndexData<T>& data)
    \n-
    642 {
    \n-
    643 is>>data.index;
    \n-
    644 /* MatrixMarket indices are one based. Decrement for C++ */
    \n-
    645 --data.index;
    \n-
    646 return is>>data.number;
    \n-
    647 }
    \n-
    648
    \n-
    654 template<typename T>
    \n-
    655 std::istream& operator>>(std::istream& is, IndexData<NumericWrapper<std::complex<T>>>& data)
    \n-
    656 {
    \n-
    657 is>>data.index;
    \n-
    658 /* MatrixMarket indices are one based. Decrement for C++ */
    \n-
    659 --data.index;
    \n-
    660 // real and imaginary part needs to be read separately as
    \n-
    661 // complex numbers are not provided in pair form. (x,y)
    \n-
    662 NumericWrapper<T> real, imag;
    \n-
    663 is>>real;
    \n-
    664 is>>imag;
    \n-
    665 data.number = {real.number, imag.number};
    \n-
    666 return is;
    \n-
    667 }
    \n-
    668
    \n-
    675 template<typename D, int brows, int bcols>
    \n-\n-
    677 {
    \n-
    683 template<typename T>
    \n-
    684 void operator()(const std::vector<std::set<IndexData<D> > >& rows,
    \n-
    685 BCRSMatrix<T>& matrix)
    \n-
    686 {
    \n-
    687 static_assert(IsNumber<T>::value && brows==1 && bcols==1, "Only scalar entries are expected here!");
    \n-
    688 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)
    \n-
    689 {
    \n-
    690 auto brow=iter.index();
    \n-
    691 for (auto siter=rows[brow].begin(); siter != rows[brow].end(); ++siter)
    \n-
    692 (*iter)[siter->index] = siter->number;
    \n-
    693 }
    \n-
    694 }
    \n-
    695
    \n-
    701 template<typename T>
    \n-
    702 void operator()(const std::vector<std::set<IndexData<D> > >& rows,
    \n-\n-
    704 {
    \n-
    705 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)
    \n-
    706 {
    \n-
    707 for (auto brow=iter.index()*brows,
    \n-
    708 browend=iter.index()*brows+brows;
    \n-
    709 brow<browend; ++brow)
    \n-
    710 {
    \n-
    711 for (auto siter=rows[brow].begin(), send=rows[brow].end();
    \n-
    712 siter != send; ++siter)
    \n-
    713 (*iter)[siter->index/bcols][brow%brows][siter->index%bcols]=siter->number;
    \n-
    714 }
    \n-
    715 }
    \n-
    716 }
    \n-
    717 };
    \n-
    718
    \n-
    719 template<int brows, int bcols>
    \n-\n-
    721 {
    \n-
    722 template<typename M>
    \n-
    723 void operator()(const std::vector<std::set<IndexData<PatternDummy> > >& rows,
    \n-
    724 M& matrix)
    \n-
    725 {}
    \n-
    726 };
    \n-
    727
    \n-
    728 template<class T> struct is_complex : std::false_type {};
    \n-
    729 template<class T> struct is_complex<std::complex<T>> : std::true_type {};
    \n-
    730
    \n-
    731 // wrapper for std::conj. Returns T if T is not complex.
    \n-
    732 template<class T>
    \n-
    733 std::enable_if_t<!is_complex<T>::value, T> conj(const T& r){
    \n-
    734 return r;
    \n-
    735 }
    \n-
    736
    \n-
    737 template<class T>
    \n-
    738 std::enable_if_t<is_complex<T>::value, T> conj(const T& r){
    \n-
    739 return std::conj(r);
    \n-
    740 }
    \n-
    741
    \n-
    742 template<typename M>
    \n-\n-
    744 {};
    \n-
    745
    \n-
    746 template<typename B, typename A>
    \n-\n-
    748 {
    \n-
    749 enum {
    \n-
    750 rows = 1,
    \n-
    751 cols = 1
    \n-
    752 };
    \n-
    753 };
    \n-
    754
    \n-
    755 template<typename B, int i, int j, typename A>
    \n-\n-
    757 {
    \n-
    758 enum {
    \n-
    759 rows = i,
    \n-
    760 cols = j
    \n-
    761 };
    \n-
    762 };
    \n-
    763
    \n-
    764 template<typename T, typename A, typename D>
    \n-\n-
    766 std::istream& file, std::size_t entries,
    \n-
    767 const MMHeader& mmHeader, const D&)
    \n-
    768 {
    \n-\n-
    770
    \n-
    771 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)
    \n-
    772 constexpr int brows = mm_multipliers<Matrix>::rows;
    \n-
    773 constexpr int bcols = mm_multipliers<Matrix>::cols;
    \n-
    774
    \n-
    775 // First path
    \n-
    776 // store entries together with column index in a separate
    \n-
    777 // data structure
    \n-
    778 std::vector<std::set<IndexData<D> > > rows(matrix.N()*brows);
    \n-
    779
    \n-
    780 auto readloop = [&] (auto symmetryFixup) {
    \n-
    781 for(std::size_t i = 0; i < entries; ++i) {
    \n-
    782 std::size_t row;
    \n-
    783 IndexData<D> data;
    \n-
    784 skipComments(file);
    \n-
    785 file>>row;
    \n-
    786 --row; // Index was 1 based.
    \n-
    787 assert(row/bcols<matrix.N());
    \n-
    788 file>>data;
    \n-
    789 assert(data.index/bcols<matrix.M());
    \n-
    790 rows[row].insert(data);
    \n-
    791 if(row!=data.index)
    \n-
    792 symmetryFixup(row, data);
    \n-
    793 }
    \n-
    794 };
    \n-
    795
    \n-
    796 switch(mmHeader.structure)
    \n-
    797 {
    \n-
    798 case general:
    \n-
    799 readloop([](auto...){});
    \n-
    800 break;
    \n-
    801 case symmetric :
    \n-
    802 readloop([&](auto row, auto data) {
    \n-
    803 IndexData<D> data_sym(data);
    \n-
    804 data_sym.index = row;
    \n-
    805 rows[data.index].insert(data_sym);
    \n-
    806 });
    \n-
    807 break;
    \n-
    808 case skew_symmetric :
    \n-
    809 readloop([&](auto row, auto data) {
    \n-
    810 IndexData<D> data_sym;
    \n-
    811 data_sym.number = -data.number;
    \n-
    812 data_sym.index = row;
    \n-
    813 rows[data.index].insert(data_sym);
    \n-
    814 });
    \n-
    815 break;
    \n-
    816 case hermitian :
    \n-
    817 readloop([&](auto row, auto data) {
    \n-
    818 IndexData<D> data_sym;
    \n-
    819 data_sym.number = conj(data.number);
    \n-
    820 data_sym.index = row;
    \n-
    821 rows[data.index].insert(data_sym);
    \n-
    822 });
    \n-
    823 break;
    \n-
    824 default:
    \n-
    825 DUNE_THROW(Dune::NotImplemented,
    \n-
    826 "Only general, symmetric, skew-symmetric and hermitian is supported right now!");
    \n-
    827 }
    \n-
    828
    \n-
    829 // Setup the matrix sparsity pattern
    \n-
    830 int nnz=0;
    \n-
    831 for(typename Matrix::CreateIterator iter=matrix.createbegin();
    \n-
    832 iter!= matrix.createend(); ++iter)
    \n-
    833 {
    \n-
    834 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
    \n-
    835 brow<browend; ++brow)
    \n-
    836 {
    \n-
    837 typedef typename std::set<IndexData<D> >::const_iterator Siter;
    \n-
    838 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
    \n-
    839 siter != send; ++siter, ++nnz)
    \n-
    840 iter.insert(siter->index/bcols);
    \n-
    841 }
    \n-
    842 }
    \n-
    843
    \n-
    844 //Set the matrix values
    \n-
    845 matrix=0;
    \n-
    846
    \n-\n-
    848
    \n-
    849 Setter(rows, matrix);
    \n-
    850 }
    \n-
    851
    \n-
    852 inline std::tuple<std::string, std::string> splitFilename(const std::string& filename) {
    \n-
    853 std::size_t lastdot = filename.find_last_of(".");
    \n-
    854 if(lastdot == std::string::npos)
    \n-
    855 return std::make_tuple(filename, "");
    \n-
    856 else {
    \n-
    857 std::string potentialFileExtension = filename.substr(lastdot);
    \n-
    858 if (potentialFileExtension == ".mm" || potentialFileExtension == ".mtx")
    \n-
    859 return std::make_tuple(filename.substr(0, lastdot), potentialFileExtension);
    \n-
    860 else
    \n-
    861 return std::make_tuple(filename, "");
    \n-
    862 }
    \n-
    863 }
    \n-
    864
    \n-
    865 } // end namespace MatrixMarketImpl
    \n-
    866
    \n-
    867 class MatrixMarketFormatError : public Dune::Exception
    \n-
    868 {};
    \n-
    869
    \n-
    870
    \n-
    871 inline void mm_read_header(std::size_t& rows, std::size_t& cols,
    \n-
    872 MatrixMarketImpl::MMHeader& header, std::istream& istr,
    \n-
    873 bool isVector)
    \n-
    874 {
    \n-
    875 using namespace MatrixMarketImpl;
    \n-
    876
    \n-
    877 if(!readMatrixMarketBanner(istr, header)) {
    \n-
    878 std::cerr << "First line was not a correct Matrix Market banner. Using default:\\n"
    \n-
    879 << "%%MatrixMarket matrix coordinate real general"<<std::endl;
    \n-
    880 // Go to the beginning of the file
    \n-
    881 istr.clear() ;
    \n-
    882 istr.seekg(0, std::ios::beg);
    \n-
    883 if(isVector)
    \n-
    884 header.type=array_type;
    \n-
    885 }
    \n-
    886
    \n-
    887 skipComments(istr);
    \n-
    888
    \n-
    889 if(lineFeed(istr))
    \n-\n-
    891
    \n-
    892 istr >> rows;
    \n-
    893
    \n-
    894 if(lineFeed(istr))
    \n-\n-
    896 istr >> cols;
    \n-
    897 }
    \n-
    898
    \n-
    899 template<typename T, typename A>
    \n-\n-
    901 std::size_t size,
    \n-
    902 std::istream& istr,
    \n-
    903 size_t lane)
    \n-
    904 {
    \n-
    905 for (int i=0; size>0; ++i, --size)
    \n-
    906 istr>>Simd::lane(lane,vector[i]);
    \n-
    907 }
    \n-
    908
    \n-
    909 template<typename T, typename A, int entries>
    \n-
    910 void mm_read_vector_entries(Dune::BlockVector<Dune::FieldVector<T,entries>,A>& vector,
    \n-
    911 std::size_t size,
    \n-
    912 std::istream& istr,
    \n-
    913 size_t lane)
    \n-
    914 {
    \n-
    915 for(int i=0; size>0; ++i, --size) {
    \n-
    916 Simd::Scalar<T> val;
    \n-
    917 istr>>val;
    \n-
    918 Simd::lane(lane, vector[i/entries][i%entries])=val;
    \n-
    919 }
    \n-
    920 }
    \n-
    921
    \n-
    922
    \n-
    929 template<typename T, typename A>
    \n-\n-
    931 std::istream& istr)
    \n-
    932 {
    \n-
    933 typedef typename Dune::BlockVector<T,A>::field_type field_type;
    \n-
    934 using namespace MatrixMarketImpl;
    \n-
    935
    \n-
    936 MMHeader header;
    \n-
    937 std::size_t rows, cols;
    \n-
    938 mm_read_header(rows,cols,header,istr, true);
    \n-
    939 if(cols!=Simd::lanes<field_type>()) {
    \n-
    940 if(Simd::lanes<field_type>() == 1)
    \n-
    941 DUNE_THROW(MatrixMarketFormatError, "cols!=1, therefore this is no vector!");
    \n-
    942 else
    \n-
    943 DUNE_THROW(MatrixMarketFormatError, "cols does not match the number of lanes in the field_type!");
    \n-
    944 }
    \n-
    945
    \n-
    946 if(header.type!=array_type)
    \n-
    947 DUNE_THROW(MatrixMarketFormatError, "Vectors have to be stored in array format!");
    \n-
    948
    \n-
    949
    \n-
    950 if constexpr (Dune::IsNumber<T>())
    \n-
    951 vector.resize(rows);
    \n-
    952 else
    \n-
    953 {
    \n-
    954 T dummy;
    \n-
    955 auto blocksize = dummy.size();
    \n-
    956 std::size_t size=rows/blocksize;
    \n-
    957 if(size*blocksize!=rows)
    \n-
    958 DUNE_THROW(MatrixMarketFormatError, "Block size of vector is not correct!");
    \n-
    959
    \n-
    960 vector.resize(size);
    \n-
    961 }
    \n-
    962
    \n-
    963 istr.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    964 for(size_t l=0;l<Simd::lanes<field_type>();++l){
    \n-
    965 mm_read_vector_entries(vector, rows, istr, l);
    \n-
    966 }
    \n-
    967 }
    \n-
    968
    \n-
    975 template<typename T, typename A>
    \n-\n-
    977 std::istream& istr)
    \n-
    978 {
    \n-
    979 using namespace MatrixMarketImpl;
    \n-\n-
    981
    \n-
    982 MMHeader header;
    \n-
    983 if(!readMatrixMarketBanner(istr, header)) {
    \n-
    984 std::cerr << "First line was not a correct Matrix Market banner. Using default:\\n"
    \n-
    985 << "%%MatrixMarket matrix coordinate real general"<<std::endl;
    \n-
    986 // Go to the beginning of the file
    \n-
    987 istr.clear() ;
    \n-
    988 istr.seekg(0, std::ios::beg);
    \n-
    989 }
    \n-
    990 skipComments(istr);
    \n-
    991
    \n-
    992 std::size_t rows, cols, entries;
    \n-
    993
    \n-
    994 if(lineFeed(istr))
    \n-\n-
    996
    \n-
    997 istr >> rows;
    \n-
    998
    \n-
    999 if(lineFeed(istr))
    \n-\n-
    1001 istr >> cols;
    \n-
    1002
    \n-
    1003 if(lineFeed(istr))
    \n-\n-
    1005
    \n-
    1006 istr >>entries;
    \n-
    1007
    \n-
    1008 std::size_t nnz, blockrows, blockcols;
    \n-
    1009
    \n-
    1010 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)
    \n-
    1011 constexpr int brows = mm_multipliers<Matrix>::rows;
    \n-
    1012 constexpr int bcols = mm_multipliers<Matrix>::cols;
    \n-
    1013
    \n-
    1014 std::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
    \n-
    1015
    \n-
    1016 istr.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n-
    1017
    \n-
    1018
    \n-
    1019 matrix.setSize(blockrows, blockcols, nnz);
    \n-\n-
    1021
    \n-
    1022 if(header.type==array_type)
    \n-
    1023 DUNE_THROW(Dune::NotImplemented, "Array format currently not supported for matrices!");
    \n-
    1024
    \n-
    1025 readSparseEntries(matrix, istr, entries, header, NumericWrapper<typename Matrix::field_type>());
    \n-
    1026 }
    \n-
    1027
    \n-
    1028 // Print a scalar entry
    \n-
    1029 template<typename B>
    \n-
    1030 void mm_print_entry(const B& entry,
    \n-
    1031 std::size_t rowidx,
    \n-
    1032 std::size_t colidx,
    \n-
    1033 std::ostream& ostr)
    \n-
    1034 {
    \n-
    1035 if constexpr (IsNumber<B>())
    \n-
    1036 ostr << rowidx << " " << colidx << " " << entry << std::endl;
    \n-
    1037 else
    \n-
    1038 {
    \n-
    1039 for (auto row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
    \n-
    1040 int coli=colidx;
    \n-
    1041 for (auto col = row->begin(); col != row->end(); ++col, ++coli)
    \n-
    1042 ostr<< rowidx<<" "<<coli<<" "<<*col<<std::endl;
    \n-
    1043 }
    \n-
    1044 }
    \n-
    1045 }
    \n-
    1046
    \n-
    1047 // Write a vector entry
    \n-
    1048 template<typename V>
    \n-
    1049 void mm_print_vector_entry(const V& entry, std::ostream& ostr,
    \n-
    1050 const std::integral_constant<int,1>&,
    \n-
    1051 size_t lane)
    \n-
    1052 {
    \n-
    1053 ostr<<Simd::lane(lane,entry)<<std::endl;
    \n-
    1054 }
    \n-
    1055
    \n-
    1056 // Write a vector
    \n-
    1057 template<typename V>
    \n-
    1058 void mm_print_vector_entry(const V& vector, std::ostream& ostr,
    \n-
    1059 const std::integral_constant<int,0>&,
    \n-
    1060 size_t lane)
    \n-
    1061 {
    \n-
    1062 using namespace MatrixMarketImpl;
    \n-
    1063
    \n-
    1064 // Is the entry a supported numeric type?
    \n-
    1065 const int isnumeric = mm_numeric_type<Simd::Scalar<typename V::block_type>>::is_numeric;
    \n-
    1066 typedef typename V::const_iterator VIter;
    \n-
    1067
    \n-
    1068 for(VIter i=vector.begin(); i != vector.end(); ++i)
    \n-
    1069
    \n-
    1070 mm_print_vector_entry(*i, ostr,
    \n-
    1071 std::integral_constant<int,isnumeric>(),
    \n-
    1072 lane);
    \n-
    1073 }
    \n-
    1074
    \n-
    1075 template<typename T, typename A>
    \n-
    1076 std::size_t countEntries(const BlockVector<T,A>& vector)
    \n-
    1077 {
    \n-
    1078 return vector.size();
    \n-
    1079 }
    \n-
    1080
    \n-
    1081 template<typename T, typename A, int i>
    \n-
    1082 std::size_t countEntries(const BlockVector<FieldVector<T,i>,A>& vector)
    \n-
    1083 {
    \n-
    1084 return vector.size()*i;
    \n-
    1085 }
    \n-
    1086
    \n-
    1087 // Version for writing vectors.
    \n-
    1088 template<typename V>
    \n-
    1089 void writeMatrixMarket(const V& vector, std::ostream& ostr,
    \n-
    1090 const std::integral_constant<int,0>&)
    \n-
    1091 {
    \n-
    1092 using namespace MatrixMarketImpl;
    \n-
    1093 typedef typename V::field_type field_type;
    \n-
    1094
    \n-
    1095 ostr<<countEntries(vector)<<" "<<Simd::lanes<field_type>()<<std::endl;
    \n-
    1096 const int isnumeric = mm_numeric_type<Simd::Scalar<V>>::is_numeric;
    \n-
    1097 for(size_t l=0;l<Simd::lanes<field_type>(); ++l){
    \n-
    1098 mm_print_vector_entry(vector,ostr, std::integral_constant<int,isnumeric>(), l);
    \n-
    1099 }
    \n-
    1100 }
    \n-
    1101
    \n-
    1102 // Versions for writing matrices
    \n-
    1103 template<typename M>
    \n-
    1104 void writeMatrixMarket(const M& matrix,
    \n-
    1105 std::ostream& ostr,
    \n-
    1106 const std::integral_constant<int,1>&)
    \n-
    1107 {
    \n-
    1108 ostr<<matrix.N()*MatrixMarketImpl::mm_multipliers<M>::rows<<" "
    \n-\n-
    1110 <<countNonZeros(matrix)<<std::endl;
    \n-
    1111
    \n-
    1112 typedef typename M::const_iterator riterator;
    \n-
    1113 typedef typename M::ConstColIterator citerator;
    \n-
    1114 for(riterator row=matrix.begin(); row != matrix.end(); ++row)
    \n-
    1115 for(citerator col = row->begin(); col != row->end(); ++col)
    \n-
    1116 // Matrix Market indexing start with 1!
    \n-\n-\n-
    1119 }
    \n-
    1120
    \n-
    1121
    \n-
    1125 template<typename M>
    \n-
    1126 void writeMatrixMarket(const M& matrix,
    \n-
    1127 std::ostream& ostr)
    \n-
    1128 {
    \n-
    1129 using namespace MatrixMarketImpl;
    \n-
    1130
    \n-
    1131 // Write header information
    \n-
    1132 mm_header_printer<M>::print(ostr);
    \n-
    1133 mm_block_structure_header<M>::print(ostr,matrix);
    \n-
    1134 // Choose the correct function for matrix and vector
    \n-
    1135 writeMatrixMarket(matrix,ostr,std::integral_constant<int,IsMatrix<M>::value>());
    \n-
    1136 }
    \n-
    1137
    \n-
    1138 static const int default_precision = -1;
    \n-
    1150 template<typename M>
    \n-
    1151 void storeMatrixMarket(const M& matrix,
    \n-
    1152 std::string filename,
    \n-
    1153 int prec=default_precision)
    \n-
    1154 {
    \n-
    1155 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n-
    1156 std::string rfilename;
    \n-
    1157 std::ofstream file;
    \n-
    1158 if (extension != "") {
    \n-
    1159 rfilename = pureFilename + extension;
    \n-
    1160 file.open(rfilename.c_str());
    \n-
    1161 if(!file)
    \n-
    1162 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n-
    1163 }
    \n-
    1164 else {
    \n-
    1165 // only try .mm so we do not ignore potential errors
    \n-
    1166 rfilename = pureFilename + ".mm";
    \n-
    1167 file.open(rfilename.c_str());
    \n-
    1168 if(!file)
    \n-
    1169 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n-
    1170 }
    \n-
    1171
    \n-
    1172 file.setf(std::ios::scientific,std::ios::floatfield);
    \n-
    1173 if(prec>0)
    \n-
    1174 file.precision(prec);
    \n-
    1175 writeMatrixMarket(matrix, file);
    \n-
    1176 file.close();
    \n-
    1177 }
    \n-
    1178
    \n-
    1179#if HAVE_MPI
    \n-
    1194 template<typename M, typename G, typename L>
    \n-
    1195 void storeMatrixMarket(const M& matrix,
    \n-
    1196 std::string filename,
    \n-\n-
    1198 bool storeIndices=true,
    \n-
    1199 int prec=default_precision)
    \n-
    1200 {
    \n-
    1201 // Get our rank
    \n-
    1202 int rank = comm.communicator().rank();
    \n-
    1203 // Write the local matrix
    \n-
    1204 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n-
    1205 std::string rfilename;
    \n-
    1206 std::ofstream file;
    \n-
    1207 if (extension != "") {
    \n-
    1208 rfilename = pureFilename + "_" + std::to_string(rank) + extension;
    \n-
    1209 file.open(rfilename.c_str());
    \n-
    1210 dverb<< rfilename <<std::endl;
    \n-
    1211 if(!file)
    \n-
    1212 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n-
    1213 }
    \n-
    1214 else {
    \n-
    1215 // only try .mm so we do not ignore potential errors
    \n-
    1216 rfilename = pureFilename + "_" + std::to_string(rank) + ".mm";
    \n-
    1217 file.open(rfilename.c_str());
    \n-
    1218 dverb<< rfilename <<std::endl;
    \n-
    1219 if(!file)
    \n-
    1220 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n-
    1221 }
    \n-
    1222 file.setf(std::ios::scientific,std::ios::floatfield);
    \n-
    1223 if(prec>0)
    \n-
    1224 file.precision(prec);
    \n-
    1225 writeMatrixMarket(matrix, file);
    \n-
    1226 file.close();
    \n-
    1227
    \n-
    1228 if(!storeIndices)
    \n-
    1229 return;
    \n-
    1230
    \n-
    1231 // Write the global to local index mapping
    \n-
    1232 rfilename = pureFilename + "_" + std::to_string(rank) + ".idx";
    \n-
    1233 file.open(rfilename.c_str());
    \n-
    1234 if(!file)
    \n-
    1235 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n-
    1236 file.setf(std::ios::scientific,std::ios::floatfield);
    \n-\n-
    1238 typedef typename IndexSet::const_iterator Iterator;
    \n-
    1239 for(Iterator iter = comm.indexSet().begin();
    \n-
    1240 iter != comm.indexSet().end(); ++iter) {
    \n-
    1241 file << iter->global()<<" "<<(std::size_t)iter->local()<<" "
    \n-
    1242 <<(int)iter->local().attribute()<<" "<<(int)iter->local().isPublic()<<std::endl;
    \n-
    1243 }
    \n-
    1244 // Store neighbour information for efficient remote indices setup.
    \n-
    1245 file<<"neighbours:";
    \n-
    1246 const std::set<int>& neighbours=comm.remoteIndices().getNeighbours();
    \n-
    1247 typedef std::set<int>::const_iterator SIter;
    \n-
    1248 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end(); ++neighbour) {
    \n-
    1249 file<<" "<< *neighbour;
    \n-
    1250 }
    \n-
    1251 file.close();
    \n-
    1252 }
    \n-
    1253
    \n-
    1268 template<typename M, typename G, typename L>
    \n-
    1269 void loadMatrixMarket(M& matrix,
    \n-
    1270 const std::string& filename,
    \n-\n-
    1272 bool readIndices=true)
    \n-
    1273 {
    \n-
    1274 using namespace MatrixMarketImpl;
    \n-
    1275
    \n-\n-
    1277 typedef typename LocalIndexT::Attribute Attribute;
    \n-
    1278 // Get our rank
    \n-
    1279 int rank = comm.communicator().rank();
    \n-
    1280 // load local matrix
    \n-
    1281 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n-
    1282 std::string rfilename;
    \n-
    1283 std::ifstream file;
    \n-
    1284 if (extension != "") {
    \n-
    1285 rfilename = pureFilename + "_" + std::to_string(rank) + extension;
    \n-
    1286 file.open(rfilename.c_str(), std::ios::in);
    \n-
    1287 dverb<< rfilename <<std::endl;
    \n-
    1288 if(!file)
    \n-
    1289 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n-
    1290 }
    \n-
    1291 else {
    \n-
    1292 // try both .mm and .mtx
    \n-
    1293 rfilename = pureFilename + "_" + std::to_string(rank) + ".mm";
    \n-
    1294 file.open(rfilename.c_str(), std::ios::in);
    \n-
    1295 if(!file) {
    \n-
    1296 rfilename = pureFilename + "_" + std::to_string(rank) + ".mtx";
    \n-
    1297 file.open(rfilename.c_str(), std::ios::in);
    \n-
    1298 dverb<< rfilename <<std::endl;
    \n-
    1299 if(!file)
    \n-
    1300 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n-
    1301 }
    \n-
    1302 }
    \n-
    1303 readMatrixMarket(matrix,file);
    \n-
    1304 file.close();
    \n-
    1305
    \n-
    1306 if(!readIndices)
    \n-
    1307 return;
    \n-
    1308
    \n-
    1309 // read indices
    \n-\n-
    1311 IndexSet& pis=comm.pis;
    \n-
    1312 rfilename = pureFilename + "_" + std::to_string(rank) + ".idx";
    \n-
    1313 file.open(rfilename.c_str());
    \n-
    1314 if(!file)
    \n-
    1315 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n-
    1316 if(pis.size()!=0)
    \n-
    1317 DUNE_THROW(InvalidIndexSetState, "Index set is not empty!");
    \n-
    1318
    \n-
    1319 pis.beginResize();
    \n-
    1320 while(!file.eof() && file.peek()!='n') {
    \n-
    1321 G g;
    \n-
    1322 file >>g;
    \n-
    1323 std::size_t l;
    \n-
    1324 file >>l;
    \n-
    1325 int c;
    \n-
    1326 file >>c;
    \n-
    1327 bool b;
    \n-
    1328 file >> b;
    \n-
    1329 pis.add(g,LocalIndexT(l,Attribute(c),b));
    \n-
    1330 lineFeed(file);
    \n-
    1331 }
    \n-
    1332 pis.endResize();
    \n-
    1333 if(!file.eof()) {
    \n-
    1334 // read neighbours
    \n-
    1335 std::string s;
    \n-
    1336 file>>s;
    \n-
    1337 if(s!="neighbours:")
    \n-
    1338 DUNE_THROW(MatrixMarketFormatError, "was expecting the string: \\"neighbours:\\"");
    \n-
    1339 std::set<int> nb;
    \n-
    1340 while(!file.eof()) {
    \n-
    1341 int i;
    \n-
    1342 file >> i;
    \n-
    1343 nb.insert(i);
    \n-
    1344 }
    \n-
    1345 file.close();
    \n-
    1346 comm.ri.setNeighbours(nb);
    \n-
    1347 }
    \n-
    1348 comm.ri.template rebuild<false>();
    \n-
    1349 }
    \n-
    1350
    \n-
    1351 #endif
    \n-
    1352
    \n-
    1363 template<typename M>
    \n-
    1364 void loadMatrixMarket(M& matrix,
    \n-
    1365 const std::string& filename)
    \n-
    1366 {
    \n-
    1367 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n-
    1368 std::string rfilename;
    \n-
    1369 std::ifstream file;
    \n-
    1370 if (extension != "") {
    \n-
    1371 rfilename = pureFilename + extension;
    \n-
    1372 file.open(rfilename.c_str());
    \n-
    1373 if(!file)
    \n-
    1374 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n-
    1375 }
    \n-
    1376 else {
    \n-
    1377 // try both .mm and .mtx
    \n-
    1378 rfilename = pureFilename + ".mm";
    \n-
    1379 file.open(rfilename.c_str(), std::ios::in);
    \n-
    1380 if(!file) {
    \n-
    1381 rfilename = pureFilename + ".mtx";
    \n-
    1382 file.open(rfilename.c_str(), std::ios::in);
    \n-
    1383 if(!file)
    \n-
    1384 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n-
    1385 }
    \n-
    1386 }
    \n-
    1387 readMatrixMarket(matrix,file);
    \n-
    1388 file.close();
    \n-
    1389 }
    \n-
    1390
    \n-
    1392}
    \n-
    1393#endif
    \n-
    Some handy generic functions for ISTL matrices.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    292 template<class F, class M,class S>
    \n+
    293 void copyToBCCSMatrix(F& initializer, const MatrixRowSubset<M,S>& mrs)
    \n+
    294 {
    \n+
    295 typedef MatrixRowSubset<M,S> MRS;
    \n+
    296 typedef typename MRS::RowIndexSet SIS;
    \n+
    297 typedef typename SIS::const_iterator SIter;
    \n+
    298 typedef typename MRS::const_iterator Iter;
    \n+
    299 typedef typename std::iterator_traits<Iter>::value_type row_type;
    \n+
    300 typedef typename row_type::const_iterator CIter;
    \n+
    301
    \n+
    302 typedef typename MRS::Matrix::size_type size_type;
    \n+
    303
    \n+
    304 // A vector containing the corresponding indices in
    \n+
    305 // the to create submatrix.
    \n+
    306 // If an entry is the maximum of size_type then this index will not appear in
    \n+
    307 // the submatrix.
    \n+
    308 std::vector<size_type> subMatrixIndex(mrs.matrix().N(),
    \n+
    309 std::numeric_limits<size_type>::max());
    \n+
    310 size_type s=0;
    \n+
    311 for(SIter index = mrs.rowIndexSet().begin(); index!=mrs.rowIndexSet().end(); ++index)
    \n+
    312 subMatrixIndex[*index]=s++;
    \n+
    313
    \n+
    314 // Calculate upper Bound for nonzeros
    \n+
    315 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n+
    316 initializer.addRowNnz(row, subMatrixIndex);
    \n+
    317
    \n+
    318 initializer.allocate();
    \n+
    319
    \n+
    320 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n+
    321 for(CIter col=row->begin(); col != row->end(); ++col) {
    \n+
    322 if(subMatrixIndex[col.index()]!=std::numeric_limits<size_type>::max())
    \n+
    323 // This column is in our subset (use submatrix column index)
    \n+
    324 initializer.countEntries(subMatrixIndex[col.index()]);
    \n+
    325 }
    \n+
    326
    \n+
    327 initializer.calcColstart();
    \n+
    328
    \n+
    329 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n+
    330 for(CIter col=row->begin(); col != row->end(); ++col) {
    \n+
    331 if(subMatrixIndex[col.index()]!=std::numeric_limits<size_type>::max())
    \n+
    332 // This value is in our submatrix -> copy (use submatrix indices
    \n+
    333 initializer.copyValue(col, subMatrixIndex[row.index()], subMatrixIndex[col.index()]);
    \n+
    334 }
    \n+
    335 initializer.createMatrix();
    \n+
    336 }
    \n+
    337
    \n+
    338}
    \n+
    339#endif
    \n+\n
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
    Get the number of nonzero fields in the matrix.
    Definition: matrixutils.hh:119
    \n-
    void readMatrixMarket(Dune::BlockVector< T, A > &vector, std::istream &istr)
    Reads a BlockVector from a matrix market file.
    Definition: matrixmarket.hh:930
    \n-
    void storeMatrixMarket(const M &matrix, std::string filename, int prec=default_precision)
    Stores a parallel matrix/vector in matrix market format in a file.
    Definition: matrixmarket.hh:1151
    \n-
    void loadMatrixMarket(M &matrix, const std::string &filename, OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)
    Load a parallel matrix/vector stored in matrix market format.
    Definition: matrixmarket.hh:1269
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    void addRowNnz(const Iter &row)
    Definition: overlappingschwarz.hh:895
    \n+
    void calcColstart() const
    Definition: overlappingschwarz.hh:926
    \n+
    void copyValue(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:933
    \n+
    void createMatrix() const
    Definition: overlappingschwarz.hh:947
    \n+
    void allocate()
    Definition: overlappingschwarz.hh:905
    \n
    std::size_t countEntries(const BlockVector< T, A > &vector)
    Definition: matrixmarket.hh:1076
    \n-
    void writeMatrixMarket(const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &)
    Definition: matrixmarket.hh:1089
    \n-
    void mm_print_vector_entry(const V &entry, std::ostream &ostr, const std::integral_constant< int, 1 > &, size_t lane)
    Definition: matrixmarket.hh:1049
    \n-
    static const int default_precision
    Definition: matrixmarket.hh:1138
    \n-
    void mm_read_vector_entries(Dune::BlockVector< T, A > &vector, std::size_t size, std::istream &istr, size_t lane)
    Definition: matrixmarket.hh:900
    \n-
    void mm_read_header(std::size_t &rows, std::size_t &cols, MatrixMarketImpl::MMHeader &header, std::istream &istr, bool isVector)
    Definition: matrixmarket.hh:871
    \n-
    void mm_print_entry(const B &entry, std::size_t rowidx, std::size_t colidx, std::ostream &ostr)
    Definition: matrixmarket.hh:1030
    \n-
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    std::tuple< std::size_t, std::size_t, std::size_t > calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader &header)
    Definition: matrixmarket.hh:547
    \n-
    bool operator<(const IndexData< T > &i1, const IndexData< T > &i2)
    LessThan operator.
    Definition: matrixmarket.hh:630
    \n-
    LineType
    Definition: matrixmarket.hh:296
    \n-
    @ DATA
    Definition: matrixmarket.hh:296
    \n-
    @ MM_HEADER
    Definition: matrixmarket.hh:296
    \n-
    @ MM_ISTLSTRUCT
    Definition: matrixmarket.hh:296
    \n-
    bool readMatrixMarketBanner(std::istream &file, MMHeader &mmHeader)
    Definition: matrixmarket.hh:353
    \n-
    std::enable_if_t< is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:738
    \n-
    void readSparseEntries(Dune::BCRSMatrix< T, A > &matrix, std::istream &file, std::size_t entries, const MMHeader &mmHeader, const D &)
    Definition: matrixmarket.hh:765
    \n-
    MM_TYPE
    Definition: matrixmarket.hh:299
    \n-
    @ array_type
    Definition: matrixmarket.hh:299
    \n-
    @ coordinate_type
    Definition: matrixmarket.hh:299
    \n-
    @ unknown_type
    Definition: matrixmarket.hh:299
    \n-
    std::istream & operator>>(std::istream &is, NumericWrapper< T > &num)
    Definition: matrixmarket.hh:614
    \n-
    void skipComments(std::istream &file)
    Definition: matrixmarket.hh:339
    \n-
    bool lineFeed(std::istream &file)
    Definition: matrixmarket.hh:315
    \n-
    @ MM_MAX_LINE_LENGTH
    Definition: matrixmarket.hh:297
    \n-
    MM_STRUCTURE
    Definition: matrixmarket.hh:303
    \n-
    @ skew_symmetric
    Definition: matrixmarket.hh:303
    \n-
    @ general
    Definition: matrixmarket.hh:303
    \n-
    @ hermitian
    Definition: matrixmarket.hh:303
    \n-
    @ unknown_structure
    Definition: matrixmarket.hh:303
    \n-
    @ symmetric
    Definition: matrixmarket.hh:303
    \n-
    MM_CTYPE
    Definition: matrixmarket.hh:301
    \n-
    @ unknown_ctype
    Definition: matrixmarket.hh:301
    \n-
    @ pattern
    Definition: matrixmarket.hh:301
    \n-
    @ complex_type
    Definition: matrixmarket.hh:301
    \n-
    @ double_type
    Definition: matrixmarket.hh:301
    \n-
    @ integer_type
    Definition: matrixmarket.hh:301
    \n-
    std::enable_if_t<!is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:733
    \n-
    std::tuple< std::string, std::string > splitFilename(const std::string &filename)
    Definition: matrixmarket.hh:852
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    Iterator begin()
    Get iterator to first row.
    Definition: bcrsmatrix.hh:675
    \n-
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n-
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: bcrsmatrix.hh:1103
    \n-
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n-
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n-
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n-
    void setBuildMode(BuildMode bm)
    Sets the build mode of the matrix.
    Definition: bcrsmatrix.hh:833
    \n-
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    void resize(size_type size)
    Resize the vector.
    Definition: bvector.hh:503
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    Helper metaprogram to get the matrix market string representation of the numeric type.
    Definition: matrixmarket.hh:76
    \n-
    @ is_numeric
    Whether T is a supported numeric type.
    Definition: matrixmarket.hh:81
    \n-
    static std::string str()
    Definition: matrixmarket.hh:95
    \n-
    static std::string str()
    Definition: matrixmarket.hh:111
    \n-
    static std::string str()
    Definition: matrixmarket.hh:127
    \n-
    static std::string str()
    Definition: matrixmarket.hh:143
    \n-
    static std::string str()
    Definition: matrixmarket.hh:159
    \n-
    Meta program to write the correct Matrix Market header.
    Definition: matrixmarket.hh:174
    \n-
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:179
    \n-
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:189
    \n-
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:199
    \n-
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:209
    \n-
    Metaprogram for writing the ISTL block structure header.
    Definition: matrixmarket.hh:225
    \n-
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:233
    \n-
    BlockVector< T, A > M
    Definition: matrixmarket.hh:230
    \n-
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:245
    \n-
    BCRSMatrix< T, A > M
    Definition: matrixmarket.hh:255
    \n-
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:258
    \n-
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:270
    \n-
    static void print(std::ostream &os, const M &m)
    Definition: matrixmarket.hh:283
    \n-
    FieldMatrix< T, i, j > M
    Definition: matrixmarket.hh:281
    \n-
    static void print(std::ostream &os, const M &m)
    Definition: matrixmarket.hh:292
    \n-
    FieldVector< T, i > M
    Definition: matrixmarket.hh:290
    \n-
    Definition: matrixmarket.hh:306
    \n-
    MM_STRUCTURE structure
    Definition: matrixmarket.hh:312
    \n-
    MM_TYPE type
    Definition: matrixmarket.hh:310
    \n-
    MMHeader()
    Definition: matrixmarket.hh:307
    \n-
    MM_CTYPE ctype
    Definition: matrixmarket.hh:311
    \n-
    Definition: matrixmarket.hh:578
    \n-
    std::size_t index
    Definition: matrixmarket.hh:579
    \n-
    a wrapper class of numeric values.
    Definition: matrixmarket.hh:595
    \n-
    T number
    Definition: matrixmarket.hh:596
    \n-
    Utility class for marking the pattern type of the MatrixMarket matrices.
    Definition: matrixmarket.hh:607
    \n-\n-
    Functor to the data values of the matrix.
    Definition: matrixmarket.hh:677
    \n-
    void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< T > &matrix)
    Sets the matrix values.
    Definition: matrixmarket.hh:684
    \n-
    void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< FieldMatrix< T, brows, bcols > > &matrix)
    Sets the matrix values.
    Definition: matrixmarket.hh:702
    \n-
    void operator()(const std::vector< std::set< IndexData< PatternDummy > > > &rows, M &matrix)
    Definition: matrixmarket.hh:723
    \n-
    Definition: matrixmarket.hh:728
    \n-
    Definition: matrixmarket.hh:744
    \n-
    Definition: matrixmarket.hh:868
    \n-
    Definition: matrixutils.hh:27
    \n-
    Test whether a type is an ISTL Matrix.
    Definition: matrixutils.hh:504
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n-
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n-
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n-
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n+
    Initializer for SuperLU Matrices representing the subdomains.
    Definition: overlappingschwarz.hh:47
    \n+
    Matrix::row_type::const_iterator CIter
    Definition: overlappingschwarz.hh:56
    \n+
    Matrix::const_iterator Iter
    Definition: overlappingschwarz.hh:55
    \n+
    IndexSet::size_type size_type
    Definition: overlappingschwarz.hh:59
    \n+
    AtomInitializer::Matrix Matrix
    Definition: overlappingschwarz.hh:54
    \n+
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n+
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1631 +4,383 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrixmarket.hh\n+bccsmatrixinitializer.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIXMARKET_HH\n- 6#define DUNE_ISTL_MATRIXMARKET_HH\n+ 5#ifndef DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH\n+ 6#define DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23\n- 24#include \n- 25#include \n- 26#include \n- 27#include \n- 28#include \n- 29#include \n- 30\n- 31#include \n- 32#include \n- 33#include // countNonZeros()\n- 34#include \n- 35\n- 36namespace Dune\n- 37{\n- 38\n-64 namespace MatrixMarketImpl\n- 65 {\n- 75 template\n-76 struct mm_numeric_type {\n- 77 enum {\n- 81 is_numeric=false\n-82 };\n- 83 };\n- 84\n- 85 template<>\n-86 struct mm_numeric_type\n- 87 {\n- 88 enum {\n- 92 is_numeric=true\n-93 };\n- 94\n-95 static std::string str()\n+ 8#include \n+ 9#include \n+ 10\n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \n+ 15\n+ 16namespace Dune\n+ 17{\n+ 18 template\n+ 19 class OverlappingSchwarzInitializer;\n+ 20}\n+ 21\n+ 22namespace Dune::ISTL::Impl\n+ 23{\n+ 31 template\n+ 32 class MatrixRowSubset\n+ 33 {\n+ 34 public:\n+ 36 typedef M Matrix;\n+ 38 typedef S RowIndexSet;\n+ 39\n+ 45 MatrixRowSubset(const Matrix& m, const RowIndexSet& s)\n+ 46 : m_(m), s_(s)\n+ 47 {}\n+ 48\n+ 49 const Matrix& matrix() const\n+ 50 {\n+ 51 return m_;\n+ 52 }\n+ 53\n+ 54 const RowIndexSet& rowIndexSet() const\n+ 55 {\n+ 56 return s_;\n+ 57 }\n+ 58\n+ 60 class const_iterator\n+ 61 : public ForwardIteratorFacade\n+ 62 {\n+ 63 public:\n+ 64 const_iterator(typename Matrix::const_iterator firstRow,\n+ 65 typename RowIndexSet::const_iterator pos)\n+ 66 : firstRow_(firstRow), pos_(pos)\n+ 67 {}\n+ 68\n+ 69\n+ 70 const typename Matrix::row_type& dereference() const\n+ 71 {\n+ 72 return *(firstRow_+ *pos_);\n+ 73 }\n+ 74 bool equals(const const_iterator& o) const\n+ 75 {\n+ 76 return pos_==o.pos_;\n+ 77 }\n+ 78 void increment()\n+ 79 {\n+ 80 ++pos_;\n+ 81 }\n+ 82 typename RowIndexSet::value_type index() const\n+ 83 {\n+ 84 return *pos_;\n+ 85 }\n+ 86\n+ 87 private:\n+ 89 typename Matrix::const_iterator firstRow_;\n+ 91 typename RowIndexSet::const_iterator pos_;\n+ 92 };\n+ 93\n+ 95 const_iterator begin() const\n 96 {\n- 97 return \"integer\";\n+ 97 return const_iterator(m_.begin(), s_.begin());\n 98 }\n- 99 };\n- 100\n- 101 template<>\n-102 struct mm_numeric_type\n- 103 {\n- 104 enum {\n- 108 is_numeric=true\n-109 };\n- 110\n-111 static std::string str()\n- 112 {\n- 113 return \"real\";\n- 114 }\n- 115 };\n- 116\n- 117 template<>\n-118 struct mm_numeric_type\n- 119 {\n- 120 enum {\n- 124 is_numeric=true\n-125 };\n- 126\n-127 static std::string str()\n- 128 {\n- 129 return \"real\";\n- 130 }\n- 131 };\n- 132\n- 133 template<>\n-134 struct mm_numeric_type >\n+ 100 const_iterator end() const\n+ 101 {\n+ 102 return const_iterator(m_.begin(), s_.end());\n+ 103 }\n+ 104\n+ 105 private:\n+ 107 const Matrix& m_;\n+ 109 const RowIndexSet& s_;\n+ 110 };\n+ 111\n+ 118 template\n+ 119 class BCCSMatrixInitializer\n+ 120 {\n+ 121 template\n+ 122 friend class Dune::OverlappingSchwarzInitializer;\n+ 123 public:\n+ 124 using Matrix = M;\n+ 125 using Index = I;\n+ 126 typedef Dune::ISTL::Impl::BCCSMatrix\n+OutputMatrix;\n+ 127 typedef typename Matrix::size_type size_type;\n+ 128\n+ 131 BCCSMatrixInitializer(OutputMatrix& mat_)\n+ 132 : mat(&mat_), cols(mat_.M())\n+ 133 {\n+ 134 if constexpr (Dune::IsNumber::value)\n 135 {\n- 136 enum {\n- 140 is_numeric=true\n-141 };\n- 142\n-143 static std::string str()\n- 144 {\n- 145 return \"complex\";\n+ 136 n = m = 1;\n+ 137 }\n+ 138 else\n+ 139 {\n+ 140 // WARNING: This assumes that all blocks are dense and identical\n+ 141 n = M::block_type::rows;\n+ 142 m = M::block_type::cols;\n+ 143 }\n+ 144\n+ 145 mat->Nnz_=0;\n 146 }\n- 147 };\n- 148\n- 149 template<>\n-150 struct mm_numeric_type >\n- 151 {\n- 152 enum {\n- 156 is_numeric=true\n-157 };\n- 158\n-159 static std::string str()\n- 160 {\n- 161 return \"complex\";\n- 162 }\n- 163 };\n- 164\n- 173 template\n-174 struct mm_header_printer;\n+ 147\n+ 148 BCCSMatrixInitializer()\n+ 149 : mat(0), cols(0), n(0), m(0)\n+ 150 {}\n+ 151\n+ 152 virtual ~BCCSMatrixInitializer()\n+ 153 {}\n+ 154\n+ 155 template\n+ 156 void addRowNnz(const Iter& row) const\n+ 157 {\n+ 158 mat->Nnz_+=row->getsize();\n+ 159 }\n+ 160\n+ 161 template\n+ 162 void addRowNnz(const Iter& row, const std::set& indices)\n+const\n+ 163 {\n+ 164 auto siter =indices.begin();\n+ 165 for (auto entry=row->begin(); entry!=row->end(); ++entry)\n+ 166 {\n+ 167 for(; siter!=indices.end() && *siterNnz_;\n+ 173 }\n+ 174 }\n 175\n- 176 template\n-177 struct mm_header_printer >\n+ 176 template\n+ 177 void addRowNnz(const Iter& row, const std::vector&\n+indices) const\n 178 {\n-179 static void print(std::ostream& os)\n- 180 {\n- 181 os<<\"%%MatrixMarket matrix coordinate \";\n- 182 os<::\n-field_type>>::str()<<\" general\"<\n-187 struct mm_header_printer >\n- 188 {\n-189 static void print(std::ostream& os)\n- 190 {\n- 191 os<<\"%%MatrixMarket matrix array \";\n- 192 os<::\n-field_type>>::str()<<\" general\"<begin(); entry!=row->end(); ++entry)\n+ 180 if (indices[entry.index()]!=std::numeric_limits::max())\n+ 181 ++mat->Nnz_;\n+ 182 }\n+ 183\n+ 184 void allocate()\n+ 185 {\n+ 186 allocateMatrixStorage();\n+ 187 allocateMarker();\n+ 188 }\n+ 189\n+ 190 template\n+ 191 void countEntries([[maybe_unused]] const Iter& row, const CIter& col)\n+const\n+ 192 {\n+ 193 countEntries(col.index());\n+ 194 }\n 195\n- 196 template\n-197 struct mm_header_printer >\n- 198 {\n-199 static void print(std::ostream& os)\n- 200 {\n- 201 os<<\"%%MatrixMarket matrix array \";\n- 202 os<::str()<<\" general\"<\n-207 struct mm_header_printer >\n- 208 {\n-209 static void print(std::ostream& os)\n- 210 {\n- 211 os<<\"%%MatrixMarket matrix array \";\n- 212 os<::str()<<\" general\"<colstart[0]=0;\n+ 208 for(size_type i=0; i < cols; ++i) {\n+ 209 assert(icolstart[i+1]=mat->colstart[i]+marker[i];\n+ 211 marker[i]=mat->colstart[i];\n+ 212 }\n 213 }\n- 214 };\n- 215\n- 224 template\n-225 struct mm_block_structure_header;\n- 226\n- 227 template\n-228 struct mm_block_structure_header >\n- 229 {\n-230 typedef BlockVector M;\n- 231 static_assert(IsNumber::value, \"Only scalar entries are expected\n-here!\");\n- 232\n-233 static void print(std::ostream& os, const M&)\n- 234 {\n- 235 os<<\"% ISTL_STRUCT blocked \";\n- 236 os<<\"1 1\"<\n+ 216 void copyValue(const Iter& row, const CIter& col) const\n+ 217 {\n+ 218 copyValue(col, row.index(), col.index());\n+ 219 }\n+ 220\n+ 221 template\n+ 222 void copyValue(const CIter& col, size_type rowindex, size_type colindex)\n+const\n+ 223 {\n+ 224 for(size_type i=0; icolstart[colindex*m+j+1]);\n+ 227 assert((size_type)marker[colindex*m+j]Nnz_);\n+ 228 mat->rowindex[marker[colindex*m+j]]=rowindex*n+i;\n+ 229 mat->values[marker[colindex*m+j]] = Dune::Impl::asMatrix(*col)[i][j];\n+ 230 ++marker[colindex*m+j]; // index for next entry in column\n+ 231 }\n+ 232 }\n+ 233 }\n+ 234\n+ 235 virtual void createMatrix() const\n+ 236 {\n+ 237 marker.clear();\n+ 238 }\n 239\n- 240 template\n-241 struct mm_block_structure_header,A> >\n- 242 {\n-243 typedef BlockVector,A> M;\n- 244\n-245 static void print(std::ostream& os, const M&)\n- 246 {\n- 247 os<<\"% ISTL_STRUCT blocked \";\n- 248 os<Nnz_*=n*m;\n+ 245 // initialize data\n+ 246 mat->values=new typename M::field_type[mat->Nnz_];\n+ 247 mat->rowindex=new I[mat->Nnz_];\n+ 248 mat->colstart=new I[cols+1];\n 249 }\n- 250 };\n- 251\n- 252 template\n-253 struct mm_block_structure_header >\n- 254 {\n-255 typedef BCRSMatrix M;\n- 256 static_assert(IsNumber::value, \"Only scalar entries are expected\n-here!\");\n- 257\n-258 static void print(std::ostream& os, const M&)\n- 259 {\n- 260 os<<\"% ISTL_STRUCT blocked \";\n- 261 os<<\"1 1\"<\n-266 struct mm_block_structure_header,A> >\n- 267 {\n-268 typedef BCRSMatrix,A> M;\n- 269\n-270 static void print(std::ostream& os, const M&)\n- 271 {\n- 272 os<<\"% ISTL_STRUCT blocked \";\n- 273 os< marker;\n+ 265 };\n+ 266\n+ 267 template\n+ 268 void copyToBCCSMatrix(F& initializer, const Matrix& matrix)\n+ 269 {\n+ 270 for (auto row=matrix.begin(); row!= matrix.end(); ++row)\n+ 271 initializer.addRowNnz(row);\n+ 272\n+ 273 initializer.allocate();\n+ 274\n+ 275 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {\n 276\n- 277\n- 278 template\n-279 struct mm_block_structure_header >\n- 280 {\n-281 typedef FieldMatrix M;\n+ 277 for (auto col=row->begin(); col != row->end(); ++col)\n+ 278 initializer.countEntries(row, col);\n+ 279 }\n+ 280\n+ 281 initializer.calcColstart();\n 282\n-283 static void print(std::ostream& os, const M& m)\n- 284 {}\n- 285 };\n- 286\n- 287 template\n-288 struct mm_block_structure_header >\n- 289 {\n-290 typedef FieldVector M;\n+ 283 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {\n+ 284 for (auto col=row->begin(); col != row->end(); ++col) {\n+ 285 initializer.copyValue(row, col);\n+ 286 }\n+ 287\n+ 288 }\n+ 289 initializer.createMatrix();\n+ 290 }\n 291\n-292 static void print(std::ostream& os, const M& m)\n- 293 {}\n- 294 };\n- 295\n-296 enum LineType { MM_HEADER, MM_ISTLSTRUCT, DATA };\n-297 enum { MM_MAX_LINE_LENGTH=1025 };\n- 298\n-299 enum MM_TYPE { coordinate_type, array_type, unknown_type };\n- 300\n-301 enum MM_CTYPE { integer_type, double_type, complex_type, pattern,\n-unknown_ctype };\n- 302\n-303 enum MM_STRUCTURE { general, symmetric, skew_symmetric, hermitian,\n-unknown_structure };\n- 304\n-305 struct MMHeader\n- 306 {\n-307 MMHeader()\n- 308 : type(coordinate_type), ctype(double_type), structure(general)\n- 309 {}\n-310 MM_TYPE type;\n-311 MM_CTYPE ctype;\n-312 MM_STRUCTURE structure;\n- 313 };\n- 314\n-315 inline bool lineFeed(std::istream& file)\n- 316 {\n- 317 char c;\n- 318 if(!file.eof())\n- 319 c=file.peek();\n- 320 else\n- 321 return false;\n- 322 // ignore whitespace\n- 323 while(c==' ')\n- 324 {\n- 325 file.get();\n- 326 if(file.eof())\n- 327 return false;\n- 328 c=file.peek();\n- 329 }\n- 330\n- 331 if(c=='\\n') {\n- 332 /* eat the line feed */\n- 333 file.get();\n- 334 return true;\n- 335 }\n- 336 return false;\n- 337 }\n- 338\n-339 inline void skipComments(std::istream& file)\n- 340 {\n- 341 lineFeed(file);\n- 342 char c=file.peek();\n- 343 // ignore comment lines\n- 344 while(c=='%')\n- 345 {\n- 346 /* discard the rest of the line */\n- 347 file.ignore(std::numeric_limits::max(),'\\n');\n- 348 c=file.peek();\n- 349 }\n- 350 }\n- 351\n- 352\n-353 inline bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)\n- 354 {\n- 355 std::string buffer;\n- 356 char c;\n- 357 file >> buffer;\n- 358 c=buffer[0];\n- 359 mmHeader=MMHeader();\n- 360 if(c!='%')\n- 361 return false;\n- 362 dverb<::max(),'\\n');\n- 367 return false;\n- 368 }\n- 369\n- 370 if(lineFeed(file))\n- 371 /* premature end of line */\n- 372 return false;\n- 373\n- 374 /* read the matrix_type */\n- 375 file >> buffer;\n- 376\n- 377 if(buffer != \"matrix\")\n- 378 {\n- 379 /* discard the rest of the line */\n- 380 file.ignore(std::numeric_limits::max(),'\\n');\n- 381 return false;\n- 382 }\n- 383\n- 384 if(lineFeed(file))\n- 385 /* premature end of line */\n- 386 return false;\n- 387\n- 388 /* The type of the matrix */\n- 389 file >> buffer;\n- 390\n- 391 if(buffer.empty())\n- 392 return false;\n- 393\n- 394 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n- 395 ::tolower);\n- 396\n- 397 switch(buffer[0])\n- 398 {\n- 399 case 'a' :\n- 400 /* sanity check */\n- 401 if(buffer != \"array\")\n- 402 {\n- 403 file.ignore(std::numeric_limits::max(),'\\n');\n- 404 return false;\n- 405 }\n- 406 mmHeader.type=array_type;\n- 407 break;\n- 408 case 'c' :\n- 409 /* sanity check */\n- 410 if(buffer != \"coordinate\")\n- 411 {\n- 412 file.ignore(std::numeric_limits::max(),'\\n');\n- 413 return false;\n- 414 }\n- 415 mmHeader.type=coordinate_type;\n- 416 break;\n- 417 default :\n- 418 file.ignore(std::numeric_limits::max(),'\\n');\n- 419 return false;\n- 420 }\n- 421\n- 422 if(lineFeed(file))\n- 423 /* premature end of line */\n- 424 return false;\n- 425\n- 426 /* The numeric type used. */\n- 427 file >> buffer;\n- 428\n- 429 if(buffer.empty())\n- 430 return false;\n- 431\n- 432 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n- 433 ::tolower);\n- 434 switch(buffer[0])\n- 435 {\n- 436 case 'i' :\n- 437 /* sanity check */\n- 438 if(buffer != \"integer\")\n- 439 {\n- 440 file.ignore(std::numeric_limits::max(),'\\n');\n- 441 return false;\n- 442 }\n- 443 mmHeader.ctype=integer_type;\n- 444 break;\n- 445 case 'r' :\n- 446 /* sanity check */\n- 447 if(buffer != \"real\")\n- 448 {\n- 449 file.ignore(std::numeric_limits::max(),'\\n');\n- 450 return false;\n- 451 }\n- 452 mmHeader.ctype=double_type;\n- 453 break;\n- 454 case 'c' :\n- 455 /* sanity check */\n- 456 if(buffer != \"complex\")\n- 457 {\n- 458 file.ignore(std::numeric_limits::max(),'\\n');\n- 459 return false;\n- 460 }\n- 461 mmHeader.ctype=complex_type;\n- 462 break;\n- 463 case 'p' :\n- 464 /* sanity check */\n- 465 if(buffer != \"pattern\")\n- 466 {\n- 467 file.ignore(std::numeric_limits::max(),'\\n');\n- 468 return false;\n- 469 }\n- 470 mmHeader.ctype=pattern;\n- 471 break;\n- 472 default :\n- 473 file.ignore(std::numeric_limits::max(),'\\n');\n- 474 return false;\n- 475 }\n- 476\n- 477 if(lineFeed(file))\n- 478 return false;\n- 479\n- 480 file >> buffer;\n- 481\n- 482 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n- 483 ::tolower);\n- 484 switch(buffer[0])\n- 485 {\n- 486 case 'g' :\n- 487 /* sanity check */\n- 488 if(buffer != \"general\")\n- 489 {\n- 490 file.ignore(std::numeric_limits::max(),'\\n');\n- 491 return false;\n- 492 }\n- 493 mmHeader.structure=general;\n- 494 break;\n- 495 case 'h' :\n- 496 /* sanity check */\n- 497 if(buffer != \"hermitian\")\n- 498 {\n- 499 file.ignore(std::numeric_limits::max(),'\\n');\n- 500 return false;\n- 501 }\n- 502 mmHeader.structure=hermitian;\n- 503 break;\n- 504 case 's' :\n- 505 if(buffer.size()==1) {\n- 506 file.ignore(std::numeric_limits::max(),'\\n');\n- 507 return false;\n- 508 }\n- 509\n- 510 switch(buffer[1])\n- 511 {\n- 512 case 'y' :\n- 513 /* sanity check */\n- 514 if(buffer != \"symmetric\")\n- 515 {\n- 516 file.ignore(std::numeric_limits::max(),'\\n');\n- 517 return false;\n- 518 }\n- 519 mmHeader.structure=symmetric;\n- 520 break;\n- 521 case 'k' :\n- 522 /* sanity check */\n- 523 if(buffer != \"skew-symmetric\")\n- 524 {\n- 525 file.ignore(std::numeric_limits::max(),'\\n');\n- 526 return false;\n- 527 }\n- 528 mmHeader.structure=skew_symmetric;\n- 529 break;\n- 530 default :\n- 531 file.ignore(std::numeric_limits::max(),'\\n');\n- 532 return false;\n- 533 }\n- 534 break;\n- 535 default :\n- 536 file.ignore(std::numeric_limits::max(),'\\n');\n- 537 return false;\n- 538 }\n- 539 file.ignore(std::numeric_limits::max(),'\\n');\n- 540 c=file.peek();\n- 541 return true;\n- 542\n- 543 }\n- 544\n- 545 template\n- 546 std::tuple\n-547 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const\n-MMHeader& header)\n- 548 {\n- 549 std::size_t blockrows=rows/brows;\n- 550 std::size_t blockcols=cols/bcols;\n- 551 std::size_t blocksize=brows*bcols;\n- 552 std::size_t blockentries=0;\n- 553\n- 554 switch(header.structure)\n- 555 {\n- 556 case general :\n- 557 blockentries = entries/blocksize; break;\n- 558 case skew_symmetric :\n- 559 blockentries = 2*entries/blocksize; break;\n- 560 case symmetric :\n- 561 blockentries = (2*entries-rows)/blocksize; break;\n- 562 case hermitian :\n- 563 blockentries = (2*entries-rows)/blocksize; break;\n- 564 default :\n- 565 throw Dune::NotImplemented();\n- 566 }\n- 567 return std::make_tuple(blockrows, blockcols, blockentries);\n- 568 }\n- 569\n- 570 /*\n- 571 * @brief Storage class for the column index and the numeric value.\n- 572 *\n- 573 * \\tparam T Either a NumericWrapper of the numeric type or PatternDummy\n- 574 * for MatrixMarket pattern case.\n- 575 */\n- 576 template\n-577 struct IndexData : public T\n- 578 {\n-579 std::size_t index = {};\n- 580 };\n- 581\n- 582\n- 593 template\n-594 struct NumericWrapper\n- 595 {\n-596 T number = {};\n-597 operator T&()\n- 598 {\n- 599 return number;\n- 600 }\n- 601 };\n- 602\n-606 struct PatternDummy\n- 607 {};\n- 608\n- 609 template<>\n-610 struct NumericWrapper\n- 611 {};\n- 612\n- 613 template\n-614 std::istream& operator>>(std::istream& is, NumericWrapper& num)\n- 615 {\n- 616 return is>>num.number;\n- 617 }\n- 618\n-619 inline std::istream& operator>>(std::istream& is, [[maybe_unused]]\n-NumericWrapper& num)\n- 620 {\n- 621 return is;\n- 622 }\n- 623\n- 629 template\n-630 bool operator<(const IndexData& i1, const IndexData& i2)\n- 631 {\n- 632 return i1.index\n-641 std::istream& operator>>(std::istream& is, IndexData& data)\n- 642 {\n- 643 is>>data.index;\n- 644 /* MatrixMarket indices are one based. Decrement for C++ */\n- 645 --data.index;\n- 646 return is>>data.number;\n- 647 }\n- 648\n- 654 template\n-655 std::istream& operator>>(std::istream& is, IndexData>>& data)\n- 656 {\n- 657 is>>data.index;\n- 658 /* MatrixMarket indices are one based. Decrement for C++ */\n- 659 --data.index;\n- 660 // real and imaginary part needs to be read separately as\n- 661 // complex numbers are not provided in pair form. (x,y)\n- 662 NumericWrapper real, imag;\n- 663 is>>real;\n- 664 is>>imag;\n- 665 data.number = {real.number, imag.number};\n- 666 return is;\n- 667 }\n- 668\n- 675 template\n-676 struct MatrixValuesSetter\n- 677 {\n- 683 template\n-684 void operator()(const std::vector > >& rows,\n- 685 BCRSMatrix& matrix)\n- 686 {\n- 687 static_assert(IsNumber::value && brows==1 && bcols==1, \"Only scalar\n-entries are expected here!\");\n- 688 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)\n- 689 {\n- 690 auto brow=iter.index();\n- 691 for (auto siter=rows[brow].begin(); siter != rows[brow].end(); ++siter)\n- 692 (*iter)[siter->index] = siter->number;\n- 693 }\n- 694 }\n- 695\n- 701 template\n-702 void operator()(const std::vector > >& rows,\n- 703 BCRSMatrix >& matrix)\n- 704 {\n- 705 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)\n- 706 {\n- 707 for (auto brow=iter.index()*brows,\n- 708 browend=iter.index()*brows+brows;\n- 709 browindex/bcols][brow%brows][siter->index%bcols]=siter->number;\n- 714 }\n- 715 }\n- 716 }\n- 717 };\n- 718\n- 719 template\n-720 struct MatrixValuesSetter\n- 721 {\n- 722 template\n-723 void operator()(const std::vector > >&\n-rows,\n- 724 M& matrix)\n- 725 {}\n- 726 };\n- 727\n-728 template struct is_complex : std::false_type {};\n-729 template struct is_complex> : std::true_type {};\n- 730\n- 731 // wrapper for std::conj. Returns T if T is not complex.\n- 732 template\n-733 std::enable_if_t::value, T> conj(const T& r){\n- 734 return r;\n- 735 }\n- 736\n- 737 template\n-738 std::enable_if_t::value, T> conj(const T& r){\n- 739 return std::conj(r);\n- 740 }\n- 741\n- 742 template\n-743 struct mm_multipliers\n- 744 {};\n- 745\n- 746 template\n-747 struct mm_multipliers >\n- 748 {\n- 749 enum {\n-750 rows = 1,\n- 751 cols = 1\n-752 };\n- 753 };\n- 754\n- 755 template\n-756 struct mm_multipliers,A> >\n- 757 {\n- 758 enum {\n-759 rows = i,\n- 760 cols = j\n-761 };\n- 762 };\n- 763\n- 764 template\n-765 void readSparseEntries(Dune::BCRSMatrix& matrix,\n- 766 std::istream& file, std::size_t entries,\n- 767 const MMHeader& mmHeader, const D&)\n- 768 {\n- 769 typedef Dune::BCRSMatrix Matrix;\n- 770\n- 771 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)\n- 772 constexpr int brows = mm_multipliers::rows;\n- 773 constexpr int bcols = mm_multipliers::cols;\n- 774\n- 775 // First path\n- 776 // store entries together with column index in a separate\n- 777 // data structure\n- 778 std::vector > > rows(matrix.N()*brows);\n- 779\n- 780 auto readloop = [&] (auto symmetryFixup) {\n- 781 for(std::size_t i = 0; i < entries; ++i) {\n- 782 std::size_t row;\n- 783 IndexData data;\n- 784 skipComments(file);\n- 785 file>>row;\n- 786 --row; // Index was 1 based.\n- 787 assert(row/bcols>data;\n- 789 assert(data.index/bcols data_sym(data);\n- 804 data_sym.index = row;\n- 805 rows[data.index].insert(data_sym);\n- 806 });\n- 807 break;\n- 808 case skew_symmetric :\n- 809 readloop([&](auto row, auto data) {\n- 810 IndexData data_sym;\n- 811 data_sym.number = -data.number;\n- 812 data_sym.index = row;\n- 813 rows[data.index].insert(data_sym);\n- 814 });\n- 815 break;\n- 816 case hermitian :\n- 817 readloop([&](auto row, auto data) {\n- 818 IndexData data_sym;\n- 819 data_sym.number = conj(data.number);\n- 820 data_sym.index = row;\n- 821 rows[data.index].insert(data_sym);\n- 822 });\n- 823 break;\n- 824 default:\n- 825 DUNE_THROW(Dune::NotImplemented,\n- 826 \"Only general, symmetric, skew-symmetric and hermitian is supported right\n-now!\");\n- 827 }\n- 828\n- 829 // Setup the matrix sparsity pattern\n- 830 int nnz=0;\n- 831 for(typename Matrix::CreateIterator iter=matrix.createbegin();\n- 832 iter!= matrix.createend(); ++iter)\n- 833 {\n- 834 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;\n- 835 brow >::const_iterator Siter;\n- 838 for(Siter siter=rows[brow].begin(), send=rows[brow].end();\n- 839 siter != send; ++siter, ++nnz)\n- 840 iter.insert(siter->index/bcols);\n- 841 }\n- 842 }\n- 843\n- 844 //Set the matrix values\n- 845 matrix=0;\n- 846\n- 847 MatrixValuesSetter Setter;\n- 848\n- 849 Setter(rows, matrix);\n- 850 }\n- 851\n-852 inline std::tuple splitFilename(const std::\n-string& filename) {\n- 853 std::size_t lastdot = filename.find_last_of(\".\");\n- 854 if(lastdot == std::string::npos)\n- 855 return std::make_tuple(filename, \"\");\n- 856 else {\n- 857 std::string potentialFileExtension = filename.substr(lastdot);\n- 858 if (potentialFileExtension == \".mm\" || potentialFileExtension == \".mtx\")\n- 859 return std::make_tuple(filename.substr(0, lastdot),\n-potentialFileExtension);\n- 860 else\n- 861 return std::make_tuple(filename, \"\");\n- 862 }\n- 863 }\n- 864\n- 865 } // end namespace MatrixMarketImpl\n- 866\n-867 class MatrixMarketFormatError : public Dune::Exception\n- 868 {};\n- 869\n- 870\n-871 inline void mm_read_header(std::size_t& rows, std::size_t& cols,\n- 872 MatrixMarketImpl::MMHeader& header, std::istream& istr,\n- 873 bool isVector)\n- 874 {\n- 875 using namespace MatrixMarketImpl;\n- 876\n- 877 if(!readMatrixMarketBanner(istr, header)) {\n- 878 std::cerr << \"First line was not a correct Matrix Market banner. Using\n-default:\\n\"\n- 879 << \"%%MatrixMarket matrix coordinate real general\"<> rows;\n- 893\n- 894 if(lineFeed(istr))\n- 895 throw MatrixMarketFormatError();\n- 896 istr >> cols;\n- 897 }\n- 898\n- 899 template\n-900 void mm_read_vector_entries(Dune::BlockVector& vector,\n- 901 std::size_t size,\n- 902 std::istream& istr,\n- 903 size_t lane)\n- 904 {\n- 905 for (int i=0; size>0; ++i, --size)\n- 906 istr>>Simd::lane(lane,vector[i]);\n- 907 }\n- 908\n- 909 template\n-910 void mm_read_vector_entries(Dune::BlockVector,A>& vector,\n- 911 std::size_t size,\n- 912 std::istream& istr,\n- 913 size_t lane)\n- 914 {\n- 915 for(int i=0; size>0; ++i, --size) {\n- 916 Simd::Scalar val;\n- 917 istr>>val;\n- 918 Simd::lane(lane, vector[i/entries][i%entries])=val;\n- 919 }\n- 920 }\n- 921\n- 922\n- 929 template\n-930 void readMatrixMarket(Dune::BlockVector& vector,\n- 931 std::istream& istr)\n- 932 {\n- 933 typedef typename Dune::BlockVector::field_type field_type;\n- 934 using namespace MatrixMarketImpl;\n- 935\n- 936 MMHeader header;\n- 937 std::size_t rows, cols;\n- 938 mm_read_header(rows,cols,header,istr, true);\n- 939 if(cols!=Simd::lanes()) {\n- 940 if(Simd::lanes() == 1)\n- 941 DUNE_THROW(MatrixMarketFormatError, \"cols!=1, therefore this is no\n-vector!\");\n- 942 else\n- 943 DUNE_THROW(MatrixMarketFormatError, \"cols does not match the number of\n-lanes in the field_type!\");\n- 944 }\n- 945\n- 946 if(header.type!=array_type)\n- 947 DUNE_THROW(MatrixMarketFormatError, \"Vectors have to be stored in array\n-format!\");\n- 948\n- 949\n- 950 if constexpr (Dune::IsNumber())\n- 951 vector.resize(rows);\n- 952 else\n- 953 {\n- 954 T dummy;\n- 955 auto blocksize = dummy.size();\n- 956 std::size_t size=rows/blocksize;\n- 957 if(size*blocksize!=rows)\n- 958 DUNE_THROW(MatrixMarketFormatError, \"Block size of vector is not\n-correct!\");\n- 959\n- 960 vector.resize(size);\n- 961 }\n- 962\n- 963 istr.ignore(std::numeric_limits::max(),'\\n');\n- 964 for(size_t l=0;l();++l){\n- 965 mm_read_vector_entries(vector, rows, istr, l);\n- 966 }\n- 967 }\n- 968\n- 975 template\n-976 void readMatrixMarket(Dune::BCRSMatrix& matrix,\n- 977 std::istream& istr)\n- 978 {\n- 979 using namespace MatrixMarketImpl;\n- 980 using Matrix = Dune::BCRSMatrix;\n- 981\n- 982 MMHeader header;\n- 983 if(!readMatrixMarketBanner(istr, header)) {\n- 984 std::cerr << \"First line was not a correct Matrix Market banner. Using\n-default:\\n\"\n- 985 << \"%%MatrixMarket matrix coordinate real general\"<> rows;\n- 998\n- 999 if(lineFeed(istr))\n- 1000 throw MatrixMarketFormatError();\n- 1001 istr >> cols;\n- 1002\n- 1003 if(lineFeed(istr))\n- 1004 throw MatrixMarketFormatError();\n- 1005\n- 1006 istr >>entries;\n- 1007\n- 1008 std::size_t nnz, blockrows, blockcols;\n- 1009\n- 1010 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)\n- 1011 constexpr int brows = mm_multipliers::rows;\n- 1012 constexpr int bcols = mm_multipliers::cols;\n- 1013\n- 1014 std::tie(blockrows, blockcols, nnz) = calculateNNZ(rows,\n-cols, entries, header);\n- 1015\n- 1016 istr.ignore(std::numeric_limits::max(),'\\n');\n- 1017\n- 1018\n- 1019 matrix.setSize(blockrows, blockcols, nnz);\n- 1020 matrix.setBuildMode(Dune::BCRSMatrix::row_wise);\n- 1021\n- 1022 if(header.type==array_type)\n- 1023 DUNE_THROW(Dune::NotImplemented, \"Array format currently not supported\n-for matrices!\");\n- 1024\n- 1025 readSparseEntries(matrix, istr, entries, header, NumericWrapper());\n- 1026 }\n- 1027\n- 1028 // Print a scalar entry\n- 1029 template\n-1030 void mm_print_entry(const B& entry,\n- 1031 std::size_t rowidx,\n- 1032 std::size_t colidx,\n- 1033 std::ostream& ostr)\n- 1034 {\n- 1035 if constexpr (IsNumber())\n- 1036 ostr << rowidx << \" \" << colidx << \" \" << entry << std::endl;\n- 1037 else\n- 1038 {\n- 1039 for (auto row=entry.begin(); row != entry.end(); ++row, ++rowidx) {\n- 1040 int coli=colidx;\n- 1041 for (auto col = row->begin(); col != row->end(); ++col, ++coli)\n- 1042 ostr<< rowidx<<\" \"<\n-1049 void mm_print_vector_entry(const V& entry, std::ostream& ostr,\n- 1050 const std::integral_constant&,\n- 1051 size_t lane)\n- 1052 {\n- 1053 ostr<\n-1058 void mm_print_vector_entry(const V& vector, std::ostream& ostr,\n- 1059 const std::integral_constant&,\n- 1060 size_t lane)\n- 1061 {\n- 1062 using namespace MatrixMarketImpl;\n- 1063\n- 1064 // Is the entry a supported numeric type?\n- 1065 const int isnumeric = mm_numeric_type>::is_numeric;\n- 1066 typedef typename V::const_iterator VIter;\n- 1067\n- 1068 for(VIter i=vector.begin(); i != vector.end(); ++i)\n- 1069\n- 1070 mm_print_vector_entry(*i, ostr,\n- 1071 std::integral_constant(),\n- 1072 lane);\n- 1073 }\n- 1074\n- 1075 template\n-1076 std::size_t countEntries(const BlockVector& vector)\n- 1077 {\n- 1078 return vector.size();\n- 1079 }\n- 1080\n- 1081 template\n-1082 std::size_t countEntries(const BlockVector,A>& vector)\n- 1083 {\n- 1084 return vector.size()*i;\n- 1085 }\n- 1086\n- 1087 // Version for writing vectors.\n- 1088 template\n-1089 void writeMatrixMarket(const V& vector, std::ostream& ostr,\n- 1090 const std::integral_constant&)\n- 1091 {\n- 1092 using namespace MatrixMarketImpl;\n- 1093 typedef typename V::field_type field_type;\n- 1094\n- 1095 ostr<()<>::is_numeric;\n- 1097 for(size_t l=0;l(); ++l){\n- 1098 mm_print_vector_entry(vector,ostr, std::integral_constant\n-(), l);\n- 1099 }\n- 1100 }\n- 1101\n- 1102 // Versions for writing matrices\n- 1103 template\n-1104 void writeMatrixMarket(const M& matrix,\n- 1105 std::ostream& ostr,\n- 1106 const std::integral_constant&)\n- 1107 {\n- 1108 ostr<::rows<<\" \"\n- 1109 <::cols<<\" \"\n- 1110 <begin(); col != row->end(); ++col)\n- 1116 // Matrix Market indexing start with 1!\n- 1117 mm_print_entry(*col, row.index()*MatrixMarketImpl::mm_multipliers::\n-rows+1,\n- 1118 col.index()*MatrixMarketImpl::mm_multipliers::cols+1, ostr);\n- 1119 }\n- 1120\n- 1121\n- 1125 template\n-1126 void writeMatrixMarket(const M& matrix,\n- 1127 std::ostream& ostr)\n- 1128 {\n- 1129 using namespace MatrixMarketImpl;\n- 1130\n- 1131 // Write header information\n- 1132 mm_header_printer::print(ostr);\n- 1133 mm_block_structure_header::print(ostr,matrix);\n- 1134 // Choose the correct function for matrix and vector\n- 1135 writeMatrixMarket(matrix,ostr,std::integral_constant::\n-value>());\n- 1136 }\n- 1137\n-1138 static const int default_precision = -1;\n- 1150 template\n-1151 void storeMatrixMarket(const M& matrix,\n- 1152 std::string filename,\n- 1153 int prec=default_precision)\n- 1154 {\n- 1155 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n-(filename);\n- 1156 std::string rfilename;\n- 1157 std::ofstream file;\n- 1158 if (extension != \"\") {\n- 1159 rfilename = pureFilename + extension;\n- 1160 file.open(rfilename.c_str());\n- 1161 if(!file)\n- 1162 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n-rfilename.c_str());\n- 1163 }\n- 1164 else {\n- 1165 // only try .mm so we do not ignore potential errors\n- 1166 rfilename = pureFilename + \".mm\";\n- 1167 file.open(rfilename.c_str());\n- 1168 if(!file)\n- 1169 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n-rfilename.c_str());\n- 1170 }\n- 1171\n- 1172 file.setf(std::ios::scientific,std::ios::floatfield);\n- 1173 if(prec>0)\n- 1174 file.precision(prec);\n- 1175 writeMatrixMarket(matrix, file);\n- 1176 file.close();\n- 1177 }\n- 1178\n- 1179#if HAVE_MPI\n- 1194 template\n-1195 void storeMatrixMarket(const M& matrix,\n- 1196 std::string filename,\n- 1197 const OwnerOverlapCopyCommunication& comm,\n- 1198 bool storeIndices=true,\n- 1199 int prec=default_precision)\n- 1200 {\n- 1201 // Get our rank\n- 1202 int rank = comm.communicator().rank();\n- 1203 // Write the local matrix\n- 1204 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n-(filename);\n- 1205 std::string rfilename;\n- 1206 std::ofstream file;\n- 1207 if (extension != \"\") {\n- 1208 rfilename = pureFilename + \"_\" + std::to_string(rank) + extension;\n- 1209 file.open(rfilename.c_str());\n- 1210 dverb<< rfilename <0)\n- 1224 file.precision(prec);\n- 1225 writeMatrixMarket(matrix, file);\n- 1226 file.close();\n- 1227\n- 1228 if(!storeIndices)\n- 1229 return;\n- 1230\n- 1231 // Write the global to local index mapping\n- 1232 rfilename = pureFilename + \"_\" + std::to_string(rank) + \".idx\";\n- 1233 file.open(rfilename.c_str());\n- 1234 if(!file)\n- 1235 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n-rfilename.c_str());\n- 1236 file.setf(std::ios::scientific,std::ios::floatfield);\n- 1237 typedef typename OwnerOverlapCopyCommunication::ParallelIndexSet\n-IndexSet;\n- 1238 typedef typename IndexSet::const_iterator Iterator;\n- 1239 for(Iterator iter = comm.indexSet().begin();\n- 1240 iter != comm.indexSet().end(); ++iter) {\n- 1241 file << iter->global()<<\" \"<<(std::size_t)iter->local()<<\" \"\n- 1242 <<(int)iter->local().attribute()<<\" \"<<(int)iter->local().isPublic\n-()<& neighbours=comm.remoteIndices().getNeighbours();\n- 1247 typedef std::set::const_iterator SIter;\n- 1248 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end();\n-++neighbour) {\n- 1249 file<<\" \"<< *neighbour;\n- 1250 }\n- 1251 file.close();\n- 1252 }\n- 1253\n- 1268 template\n-1269 void loadMatrixMarket(M& matrix,\n- 1270 const std::string& filename,\n- 1271 OwnerOverlapCopyCommunication& comm,\n- 1272 bool readIndices=true)\n- 1273 {\n- 1274 using namespace MatrixMarketImpl;\n- 1275\n- 1276 using LocalIndexT = typename OwnerOverlapCopyCommunication::\n-ParallelIndexSet::LocalIndex;\n- 1277 typedef typename LocalIndexT::Attribute Attribute;\n- 1278 // Get our rank\n- 1279 int rank = comm.communicator().rank();\n- 1280 // load local matrix\n- 1281 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n-(filename);\n- 1282 std::string rfilename;\n- 1283 std::ifstream file;\n- 1284 if (extension != \"\") {\n- 1285 rfilename = pureFilename + \"_\" + std::to_string(rank) + extension;\n- 1286 file.open(rfilename.c_str(), std::ios::in);\n- 1287 dverb<< rfilename <::ParallelIndexSet\n-IndexSet;\n- 1311 IndexSet& pis=comm.pis;\n- 1312 rfilename = pureFilename + \"_\" + std::to_string(rank) + \".idx\";\n- 1313 file.open(rfilename.c_str());\n- 1314 if(!file)\n- 1315 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n- 1316 if(pis.size()!=0)\n- 1317 DUNE_THROW(InvalidIndexSetState, \"Index set is not empty!\");\n- 1318\n- 1319 pis.beginResize();\n- 1320 while(!file.eof() && file.peek()!='n') {\n- 1321 G g;\n- 1322 file >>g;\n- 1323 std::size_t l;\n- 1324 file >>l;\n- 1325 int c;\n- 1326 file >>c;\n- 1327 bool b;\n- 1328 file >> b;\n- 1329 pis.add(g,LocalIndexT(l,Attribute(c),b));\n- 1330 lineFeed(file);\n- 1331 }\n- 1332 pis.endResize();\n- 1333 if(!file.eof()) {\n- 1334 // read neighbours\n- 1335 std::string s;\n- 1336 file>>s;\n- 1337 if(s!=\"neighbours:\")\n- 1338 DUNE_THROW(MatrixMarketFormatError, \"was expecting the string:\n-\\\"neighbours:\\\"\");\n- 1339 std::set nb;\n- 1340 while(!file.eof()) {\n- 1341 int i;\n- 1342 file >> i;\n- 1343 nb.insert(i);\n- 1344 }\n- 1345 file.close();\n- 1346 comm.ri.setNeighbours(nb);\n- 1347 }\n- 1348 comm.ri.template rebuild();\n- 1349 }\n- 1350\n- 1351 #endif\n- 1352\n- 1363 template\n-1364 void loadMatrixMarket(M& matrix,\n- 1365 const std::string& filename)\n- 1366 {\n- 1367 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n-(filename);\n- 1368 std::string rfilename;\n- 1369 std::ifstream file;\n- 1370 if (extension != \"\") {\n- 1371 rfilename = pureFilename + extension;\n- 1372 file.open(rfilename.c_str());\n- 1373 if(!file)\n- 1374 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n- 1375 }\n- 1376 else {\n- 1377 // try both .mm and .mtx\n- 1378 rfilename = pureFilename + \".mm\";\n- 1379 file.open(rfilename.c_str(), std::ios::in);\n- 1380 if(!file) {\n- 1381 rfilename = pureFilename + \".mtx\";\n- 1382 file.open(rfilename.c_str(), std::ios::in);\n- 1383 if(!file)\n- 1384 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n- 1385 }\n- 1386 }\n- 1387 readMatrixMarket(matrix,file);\n- 1388 file.close();\n- 1389 }\n- 1390\n- 1392}\n- 1393#endif\n-matrixutils.hh\n-Some handy generic functions for ISTL matrices.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n+ 292 template\n+ 293 void copyToBCCSMatrix(F& initializer, const MatrixRowSubset& mrs)\n+ 294 {\n+ 295 typedef MatrixRowSubset MRS;\n+ 296 typedef typename MRS::RowIndexSet SIS;\n+ 297 typedef typename SIS::const_iterator SIter;\n+ 298 typedef typename MRS::const_iterator Iter;\n+ 299 typedef typename std::iterator_traits::value_type row_type;\n+ 300 typedef typename row_type::const_iterator CIter;\n+ 301\n+ 302 typedef typename MRS::Matrix::size_type size_type;\n+ 303\n+ 304 // A vector containing the corresponding indices in\n+ 305 // the to create submatrix.\n+ 306 // If an entry is the maximum of size_type then this index will not appear\n+in\n+ 307 // the submatrix.\n+ 308 std::vector subMatrixIndex(mrs.matrix().N(),\n+ 309 std::numeric_limits::max());\n+ 310 size_type s=0;\n+ 311 for(SIter index = mrs.rowIndexSet().begin(); index!=mrs.rowIndexSet().end\n+(); ++index)\n+ 312 subMatrixIndex[*index]=s++;\n+ 313\n+ 314 // Calculate upper Bound for nonzeros\n+ 315 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n+ 316 initializer.addRowNnz(row, subMatrixIndex);\n+ 317\n+ 318 initializer.allocate();\n+ 319\n+ 320 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n+ 321 for(CIter col=row->begin(); col != row->end(); ++col) {\n+ 322 if(subMatrixIndex[col.index()]!=std::numeric_limits::max())\n+ 323 // This column is in our subset (use submatrix column index)\n+ 324 initializer.countEntries(subMatrixIndex[col.index()]);\n+ 325 }\n+ 326\n+ 327 initializer.calcColstart();\n+ 328\n+ 329 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n+ 330 for(CIter col=row->begin(); col != row->end(); ++col) {\n+ 331 if(subMatrixIndex[col.index()]!=std::numeric_limits::max())\n+ 332 // This value is in our submatrix -> copy (use submatrix indices\n+ 333 initializer.copyValue(col, subMatrixIndex[row.index()], subMatrixIndex\n+[col.index()]);\n+ 334 }\n+ 335 initializer.createMatrix();\n+ 336 }\n+ 337\n+ 338}\n+ 339#endif\n+bccsmatrix.hh\n col\n Col col\n Definition: matrixmatrix.hh:351\n-Dune::countNonZeros\n-auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n-value > *sfinae=nullptr)\n-Get the number of nonzero fields in the matrix.\n-Definition: matrixutils.hh:119\n-Dune::readMatrixMarket\n-void readMatrixMarket(Dune::BlockVector< T, A > &vector, std::istream &istr)\n-Reads a BlockVector from a matrix market file.\n-Definition: matrixmarket.hh:930\n-Dune::storeMatrixMarket\n-void storeMatrixMarket(const M &matrix, std::string filename, int\n-prec=default_precision)\n-Stores a parallel matrix/vector in matrix market format in a file.\n-Definition: matrixmarket.hh:1151\n-Dune::loadMatrixMarket\n-void loadMatrixMarket(M &matrix, const std::string &filename,\n-OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)\n-Load a parallel matrix/vector stored in matrix market format.\n-Definition: matrixmarket.hh:1269\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::OverlappingSchwarzInitializer::addRowNnz\n+void addRowNnz(const Iter &row)\n+Definition: overlappingschwarz.hh:895\n+Dune::OverlappingSchwarzInitializer::calcColstart\n+void calcColstart() const\n+Definition: overlappingschwarz.hh:926\n+Dune::OverlappingSchwarzInitializer::copyValue\n+void copyValue(const Iter &row, const CIter &col) const\n+Definition: overlappingschwarz.hh:933\n+Dune::OverlappingSchwarzInitializer::createMatrix\n+void createMatrix() const\n+Definition: overlappingschwarz.hh:947\n+Dune::OverlappingSchwarzInitializer::allocate\n+void allocate()\n+Definition: overlappingschwarz.hh:905\n Dune::countEntries\n std::size_t countEntries(const BlockVector< T, A > &vector)\n Definition: matrixmarket.hh:1076\n-Dune::writeMatrixMarket\n-void writeMatrixMarket(const V &vector, std::ostream &ostr, const std::\n-integral_constant< int, 0 > &)\n-Definition: matrixmarket.hh:1089\n-Dune::mm_print_vector_entry\n-void mm_print_vector_entry(const V &entry, std::ostream &ostr, const std::\n-integral_constant< int, 1 > &, size_t lane)\n-Definition: matrixmarket.hh:1049\n-Dune::default_precision\n-static const int default_precision\n-Definition: matrixmarket.hh:1138\n-Dune::mm_read_vector_entries\n-void mm_read_vector_entries(Dune::BlockVector< T, A > &vector, std::size_t\n-size, std::istream &istr, size_t lane)\n-Definition: matrixmarket.hh:900\n-Dune::mm_read_header\n-void mm_read_header(std::size_t &rows, std::size_t &cols, MatrixMarketImpl::\n-MMHeader &header, std::istream &istr, bool isVector)\n-Definition: matrixmarket.hh:871\n-Dune::mm_print_entry\n-void mm_print_entry(const B &entry, std::size_t rowidx, std::size_t colidx,\n-std::ostream &ostr)\n-Definition: matrixmarket.hh:1030\n-std\n-STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::MatrixMarketImpl::calculateNNZ\n-std::tuple< std::size_t, std::size_t, std::size_t > calculateNNZ(std::size_t\n-rows, std::size_t cols, std::size_t entries, const MMHeader &header)\n-Definition: matrixmarket.hh:547\n-Dune::MatrixMarketImpl::operator<\n-bool operator<(const IndexData< T > &i1, const IndexData< T > &i2)\n-LessThan operator.\n-Definition: matrixmarket.hh:630\n-Dune::MatrixMarketImpl::LineType\n-LineType\n-Definition: matrixmarket.hh:296\n-Dune::MatrixMarketImpl::DATA\n-@ DATA\n-Definition: matrixmarket.hh:296\n-Dune::MatrixMarketImpl::MM_HEADER\n-@ MM_HEADER\n-Definition: matrixmarket.hh:296\n-Dune::MatrixMarketImpl::MM_ISTLSTRUCT\n-@ MM_ISTLSTRUCT\n-Definition: matrixmarket.hh:296\n-Dune::MatrixMarketImpl::readMatrixMarketBanner\n-bool readMatrixMarketBanner(std::istream &file, MMHeader &mmHeader)\n-Definition: matrixmarket.hh:353\n-Dune::MatrixMarketImpl::conj\n-std::enable_if_t< is_complex< T >::value, T > conj(const T &r)\n-Definition: matrixmarket.hh:738\n-Dune::MatrixMarketImpl::readSparseEntries\n-void readSparseEntries(Dune::BCRSMatrix< T, A > &matrix, std::istream &file,\n-std::size_t entries, const MMHeader &mmHeader, const D &)\n-Definition: matrixmarket.hh:765\n-Dune::MatrixMarketImpl::MM_TYPE\n-MM_TYPE\n-Definition: matrixmarket.hh:299\n-Dune::MatrixMarketImpl::array_type\n-@ array_type\n-Definition: matrixmarket.hh:299\n-Dune::MatrixMarketImpl::coordinate_type\n-@ coordinate_type\n-Definition: matrixmarket.hh:299\n-Dune::MatrixMarketImpl::unknown_type\n-@ unknown_type\n-Definition: matrixmarket.hh:299\n-Dune::MatrixMarketImpl::operator>>\n-std::istream & operator>>(std::istream &is, NumericWrapper< T > &num)\n-Definition: matrixmarket.hh:614\n-Dune::MatrixMarketImpl::skipComments\n-void skipComments(std::istream &file)\n-Definition: matrixmarket.hh:339\n-Dune::MatrixMarketImpl::lineFeed\n-bool lineFeed(std::istream &file)\n-Definition: matrixmarket.hh:315\n-Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH\n-@ MM_MAX_LINE_LENGTH\n-Definition: matrixmarket.hh:297\n-Dune::MatrixMarketImpl::MM_STRUCTURE\n-MM_STRUCTURE\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::skew_symmetric\n-@ skew_symmetric\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::general\n-@ general\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::hermitian\n-@ hermitian\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::unknown_structure\n-@ unknown_structure\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::symmetric\n-@ symmetric\n-Definition: matrixmarket.hh:303\n-Dune::MatrixMarketImpl::MM_CTYPE\n-MM_CTYPE\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::unknown_ctype\n-@ unknown_ctype\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::pattern\n-@ pattern\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::complex_type\n-@ complex_type\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::double_type\n-@ double_type\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::integer_type\n-@ integer_type\n-Definition: matrixmarket.hh:301\n-Dune::MatrixMarketImpl::conj\n-std::enable_if_t::value, T > conj(const T &r)\n-Definition: matrixmarket.hh:733\n-Dune::MatrixMarketImpl::splitFilename\n-std::tuple< std::string, std::string > splitFilename(const std::string\n-&filename)\n-Definition: matrixmarket.hh:852\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::begin\n-Iterator begin()\n-Get iterator to first row.\n-Definition: bcrsmatrix.hh:675\n-Dune::BCRSMatrix::end\n-Iterator end()\n-Get iterator to one beyond last row.\n-Definition: bcrsmatrix.hh:681\n-Dune::BCRSMatrix::createend\n-CreateIterator createend()\n-get create iterator pointing to one after the last block\n-Definition: bcrsmatrix.hh:1103\n-Dune::BCRSMatrix::M\n-size_type M() const\n-number of columns (counted in blocks)\n-Definition: bcrsmatrix.hh:1978\n-Dune::BCRSMatrix::createbegin\n-CreateIterator createbegin()\n-get initial create iterator\n-Definition: bcrsmatrix.hh:1097\n-Dune::BCRSMatrix::N\n-size_type N() const\n-number of rows (counted in blocks)\n-Definition: bcrsmatrix.hh:1972\n-Dune::BCRSMatrix::setBuildMode\n-void setBuildMode(BuildMode bm)\n-Sets the build mode of the matrix.\n-Definition: bcrsmatrix.hh:833\n-Dune::BCRSMatrix::setSize\n-void setSize(size_type rows, size_type columns, size_type nnz=0)\n-Set the size of the matrix.\n-Definition: bcrsmatrix.hh:861\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::BlockVector::resize\n-void resize(size_type size)\n-Resize the vector.\n-Definition: bvector.hh:503\n-Dune::BlockVector::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bvector.hh:401\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::MatrixMarketImpl::mm_numeric_type\n-Helper metaprogram to get the matrix market string representation of the\n-numeric type.\n-Definition: matrixmarket.hh:76\n-Dune::MatrixMarketImpl::mm_numeric_type::is_numeric\n-@ is_numeric\n-Whether T is a supported numeric type.\n-Definition: matrixmarket.hh:81\n-Dune::MatrixMarketImpl::mm_numeric_type<_int_>::str\n-static std::string str()\n-Definition: matrixmarket.hh:95\n-Dune::MatrixMarketImpl::mm_numeric_type<_double_>::str\n-static std::string str()\n-Definition: matrixmarket.hh:111\n-Dune::MatrixMarketImpl::mm_numeric_type<_float_>::str\n-static std::string str()\n-Definition: matrixmarket.hh:127\n-Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_double_>_>::str\n-static std::string str()\n-Definition: matrixmarket.hh:143\n-Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_float_>_>::str\n-static std::string str()\n-Definition: matrixmarket.hh:159\n-Dune::MatrixMarketImpl::mm_header_printer\n-Meta program to write the correct Matrix Market header.\n-Definition: matrixmarket.hh:174\n-Dune::MatrixMarketImpl::mm_header_printer<_BCRSMatrix<_T,_A_>_>::print\n-static void print(std::ostream &os)\n-Definition: matrixmarket.hh:179\n-Dune::MatrixMarketImpl::mm_header_printer<_BlockVector<_B,_A_>_>::print\n-static void print(std::ostream &os)\n-Definition: matrixmarket.hh:189\n-Dune::MatrixMarketImpl::mm_header_printer<_FieldVector<_T,_j_>_>::print\n-static void print(std::ostream &os)\n-Definition: matrixmarket.hh:199\n-Dune::MatrixMarketImpl::mm_header_printer<_FieldMatrix<_T,_i,_j_>_>::print\n-static void print(std::ostream &os)\n-Definition: matrixmarket.hh:209\n-Dune::MatrixMarketImpl::mm_block_structure_header\n-Metaprogram for writing the ISTL block structure header.\n-Definition: matrixmarket.hh:225\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>_>::print\n-static void print(std::ostream &os, const M &)\n-Definition: matrixmarket.hh:233\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>_>::M\n-BlockVector< T, A > M\n-Definition: matrixmarket.hh:230\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_FieldVector<_T,\n-i_>,_A_>_>::print\n-static void print(std::ostream &os, const M &)\n-Definition: matrixmarket.hh:245\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>_>::M\n-BCRSMatrix< T, A > M\n-Definition: matrixmarket.hh:255\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>_>::print\n-static void print(std::ostream &os, const M &)\n-Definition: matrixmarket.hh:258\n-Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_FieldMatrix<_T,\n-i,_j_>,_A_>_>::print\n-static void print(std::ostream &os, const M &)\n-Definition: matrixmarket.hh:270\n-Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,_j_>_>::\n-print\n-static void print(std::ostream &os, const M &m)\n-Definition: matrixmarket.hh:283\n-Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,_j_>_>::M\n-FieldMatrix< T, i, j > M\n-Definition: matrixmarket.hh:281\n-Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>_>::print\n-static void print(std::ostream &os, const M &m)\n-Definition: matrixmarket.hh:292\n-Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>_>::M\n-FieldVector< T, i > M\n-Definition: matrixmarket.hh:290\n-Dune::MatrixMarketImpl::MMHeader\n-Definition: matrixmarket.hh:306\n-Dune::MatrixMarketImpl::MMHeader::structure\n-MM_STRUCTURE structure\n-Definition: matrixmarket.hh:312\n-Dune::MatrixMarketImpl::MMHeader::type\n-MM_TYPE type\n-Definition: matrixmarket.hh:310\n-Dune::MatrixMarketImpl::MMHeader::MMHeader\n-MMHeader()\n-Definition: matrixmarket.hh:307\n-Dune::MatrixMarketImpl::MMHeader::ctype\n-MM_CTYPE ctype\n-Definition: matrixmarket.hh:311\n-Dune::MatrixMarketImpl::IndexData\n-Definition: matrixmarket.hh:578\n-Dune::MatrixMarketImpl::IndexData::index\n-std::size_t index\n-Definition: matrixmarket.hh:579\n-Dune::MatrixMarketImpl::NumericWrapper\n-a wrapper class of numeric values.\n-Definition: matrixmarket.hh:595\n-Dune::MatrixMarketImpl::NumericWrapper::number\n-T number\n-Definition: matrixmarket.hh:596\n-Dune::MatrixMarketImpl::PatternDummy\n-Utility class for marking the pattern type of the MatrixMarket matrices.\n-Definition: matrixmarket.hh:607\n-Dune::MatrixMarketImpl::NumericWrapper<_PatternDummy_>\n-Definition: matrixmarket.hh:611\n-Dune::MatrixMarketImpl::MatrixValuesSetter\n-Functor to the data values of the matrix.\n-Definition: matrixmarket.hh:677\n-Dune::MatrixMarketImpl::MatrixValuesSetter::operator()\n-void operator()(const std::vector< std::set< IndexData< D > > > &rows,\n-BCRSMatrix< T > &matrix)\n-Sets the matrix values.\n-Definition: matrixmarket.hh:684\n-Dune::MatrixMarketImpl::MatrixValuesSetter::operator()\n-void operator()(const std::vector< std::set< IndexData< D > > > &rows,\n-BCRSMatrix< FieldMatrix< T, brows, bcols > > &matrix)\n-Sets the matrix values.\n-Definition: matrixmarket.hh:702\n-Dune::MatrixMarketImpl::MatrixValuesSetter<_PatternDummy,_brows,_bcols_>::\n-operator()\n-void operator()(const std::vector< std::set< IndexData< PatternDummy > > >\n-&rows, M &matrix)\n-Definition: matrixmarket.hh:723\n-Dune::MatrixMarketImpl::is_complex\n-Definition: matrixmarket.hh:728\n-Dune::MatrixMarketImpl::mm_multipliers\n-Definition: matrixmarket.hh:744\n-Dune::MatrixMarketFormatError\n-Definition: matrixmarket.hh:868\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n-Dune::IsMatrix\n-Test whether a type is an ISTL Matrix.\n-Definition: matrixutils.hh:504\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::indexSet\n-const ParallelIndexSet & indexSet() const\n-Get the underlying parallel index set.\n-Definition: owneroverlapcopy.hh:462\n-Dune::OwnerOverlapCopyCommunication::communicator\n-const Communication< MPI_Comm > & communicator() const\n-Definition: owneroverlapcopy.hh:299\n-Dune::OwnerOverlapCopyCommunication::remoteIndices\n-const RemoteIndices & remoteIndices() const\n-Get the underlying remote indices.\n-Definition: owneroverlapcopy.hh:471\n-Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n-Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n-The type of the parallel index set.\n-Definition: owneroverlapcopy.hh:449\n+Dune::OverlappingSchwarzInitializer\n+Initializer for SuperLU Matrices representing the subdomains.\n+Definition: overlappingschwarz.hh:47\n+Dune::OverlappingSchwarzInitializer::CIter\n+Matrix::row_type::const_iterator CIter\n+Definition: overlappingschwarz.hh:56\n+Dune::OverlappingSchwarzInitializer::Iter\n+Matrix::const_iterator Iter\n+Definition: overlappingschwarz.hh:55\n+Dune::OverlappingSchwarzInitializer::size_type\n+IndexSet::size_type size_type\n+Definition: overlappingschwarz.hh:59\n+Dune::OverlappingSchwarzInitializer::Matrix\n+AtomInitializer::Matrix Matrix\n+Definition: overlappingschwarz.hh:54\n+Dune::Matrix::size_type\n+A::size_type size_type\n+Type for indices and sizes.\n+Definition: matrix.hh:577\n+Dune::Matrix::row_type\n+MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n+The type implementing a matrix row.\n+Definition: matrix.hh:574\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00047.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00047.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvertype.hh File Reference\n+dune-istl: multitypeblockmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -64,38 +64,62 @@\n \n
    \n
    \n
    \n \n-
    solvertype.hh File Reference
    \n+Namespaces |\n+Functions
    \n+
    multitypeblockmatrix.hh File Reference
    \n
    \n
    \n-\n-

    Templates characterizing the type of a solver. \n-More...

    \n-\n+
    #include <cmath>
    \n+#include <iostream>
    \n+#include <tuple>
    \n+#include <dune/common/hybridutilities.hh>
    \n+#include "istlexception.hh"
    \n+#include "gsetc.hh"
    \n+
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n+\n+\n \n-\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::IsDirectSolver< Solver >
    class  Dune::MultiTypeBlockMatrix< FirstRow, Args >
     A Matrix class to support different block types. More...
     
    class  Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, remain_col >
     part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types More...
     
    class  Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, 0 >
     
    struct  Dune::StoresColumnCompressed< Solver >
    class  Dune::MultiTypeBlockMatrix_Solver< I, crow, remain_row >
     solver for MultiTypeBlockVector & MultiTypeBlockMatrix types More...
     
    class  Dune::MultiTypeBlockMatrix_Solver< I, crow, 0 >
     
    struct  std::tuple_element< i, Dune::MultiTypeBlockMatrix< Args... > >
     Make std::tuple_element work for MultiTypeBlockMatrix. More...
     
    \n \n \n \n+\n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  std
     STL namespace.
     
    \n+\n+\n+\n+\n+\n

    \n+Functions

    template<typename T1 , typename... Args>
    std::ostream & Dune::operator<< (std::ostream &s, const MultiTypeBlockMatrix< T1, Args... > &m)
     << operator for a MultiTypeBlockMatrix More...
     
    \n-

    Detailed Description

    \n-

    Templates characterizing the type of a solver.

    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,24 +4,49 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-solvertype.hh File Reference\n-Templates characterizing the type of a solver. More...\n+Classes | Namespaces | Functions\n+multitypeblockmatrix.hh File Reference\n+#include \n+#include \n+#include \n+#include \n+#include \"istlexception.hh\"\n+#include \"gsetc.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::IsDirectSolver<_Solver_>\n+ class \u00a0Dune::MultiTypeBlockMatrix<_FirstRow,_Args_>\n+\u00a0 A Matrix class to support different block types. More...\n \u00a0\n-struct \u00a0Dune::StoresColumnCompressed<_Solver_>\n+ class \u00a0Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_remain_col_>\n+\u00a0 part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types\n+ More...\n+\u00a0\n+ class \u00a0Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_0_>\n+\u00a0\n+ class \u00a0Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_remain_row_>\n+\u00a0 solver for MultiTypeBlockVector & MultiTypeBlockMatrix types More...\n+\u00a0\n+ class \u00a0Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>\n+\u00a0\n+struct \u00a0std::tuple_element<_i,_Dune::MultiTypeBlockMatrix<_Args..._>_>\n+\u00a0 Make std::tuple_element work for MultiTypeBlockMatrix. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-***** Detailed Description *****\n-Templates characterizing the type of a solver.\n+namespace \u00a0std\n+\u00a0 STL namespace.\n+\u00a0\n+ Functions\n+template\n+std::ostream &\u00a0Dune::operator<< (std::ostream &s, const MultiTypeBlockMatrix<\n+ T1, Args... > &m)\n+\u00a0 << operator for a MultiTypeBlockMatrix More...\n+\u00a0\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00047_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00047_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvertype.hh Source File\n+dune-istl: multitypeblockmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -62,50 +62,576 @@\n \n
    \n \n
    \n
    \n
    \n-
    solvertype.hh
    \n+
    multitypeblockmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SOLVERTYPE_HH
    \n-
    6#define DUNE_ISTL_SOLVERTYPE_HH
    \n+
    5#ifndef DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH
    \n+
    6#define DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH
    \n
    7
    \n-
    12namespace Dune
    \n-
    13{
    \n-
    14 template<typename Solver>
    \n-\n-
    16 {
    \n-
    17 enum
    \n-
    18 {
    \n-
    24 value =false
    \n-
    25 };
    \n-
    26 };
    \n+
    8#include <cmath>
    \n+
    9#include <iostream>
    \n+
    10#include <tuple>
    \n+
    11
    \n+
    12#include <dune/common/hybridutilities.hh>
    \n+
    13
    \n+
    14#include "istlexception.hh"
    \n+
    15
    \n+
    16// forward declaration
    \n+
    17namespace Dune
    \n+
    18{
    \n+
    19 template<typename FirstRow, typename... Args>
    \n+
    20 class MultiTypeBlockMatrix;
    \n+
    21
    \n+
    22 template<int I, int crow, int remain_row>
    \n+
    23 class MultiTypeBlockMatrix_Solver;
    \n+
    24}
    \n+
    25
    \n+
    26#include "gsetc.hh"
    \n
    27
    \n-
    28 template<typename Solver>
    \n-\n-
    30 {
    \n-
    31 enum
    \n-
    32 {
    \n-
    36 value = false
    \n-
    37 };
    \n-
    38 };
    \n-
    39} // end namespace Dune
    \n-
    40#endif
    \n+
    28namespace Dune {
    \n+
    29
    \n+
    43 template<typename FirstRow, typename... Args>
    \n+\n+
    45 : public std::tuple<FirstRow, Args...>
    \n+
    46 {
    \n+
    47 using ParentType = std::tuple<FirstRow, Args...>;
    \n+
    48 public:
    \n+
    49
    \n+
    51 using ParentType::ParentType;
    \n+
    52
    \n+
    56 typedef MultiTypeBlockMatrix<FirstRow, Args...> type;
    \n+
    57
    \n+
    59 using size_type = std::size_t;
    \n+
    60
    \n+
    61 typedef typename FirstRow::field_type field_type;
    \n+
    62
    \n+
    64 static constexpr size_type N()
    \n+
    65 {
    \n+
    66 return 1+sizeof...(Args);
    \n+
    67 }
    \n+
    68
    \n+
    74 [[deprecated("Use method 'N' instead")]]
    \n+
    75 static constexpr size_type size()
    \n+
    76 {
    \n+
    77 return 1+sizeof...(Args);
    \n+
    78 }
    \n+
    79
    \n+
    81 static constexpr size_type M()
    \n+
    82 {
    \n+
    83 return FirstRow::size();
    \n+
    84 }
    \n+
    85
    \n+
    102 template< size_type index >
    \n+
    103 auto
    \n+
    104 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable)
    \n+
    105 -> decltype(std::get<index>(*this))
    \n+
    106 {
    \n+
    107 return std::get<index>(*this);
    \n+
    108 }
    \n+
    109
    \n+
    115 template< size_type index >
    \n+
    116 auto
    \n+
    117 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable) const
    \n+
    118 -> decltype(std::get<index>(*this))
    \n+
    119 {
    \n+
    120 return std::get<index>(*this);
    \n+
    121 }
    \n+
    122
    \n+
    126 template<typename T>
    \n+
    127 void operator= (const T& newval) {
    \n+
    128 using namespace Dune::Hybrid;
    \n+
    129 auto size = index_constant<1+sizeof...(Args)>();
    \n+
    130 // Since Dune::Hybrid::size(MultiTypeBlockMatrix) is not implemented,
    \n+
    131 // we cannot use a plain forEach(*this, ...). This could be achieved,
    \n+
    132 // e.g., by implementing a static size() method.
    \n+
    133 forEach(integralRange(size), [&](auto&& i) {
    \n+
    134 (*this)[i] = newval;
    \n+
    135 });
    \n+
    136 }
    \n+
    137
    \n+
    138 //===== vector space arithmetic
    \n+
    139
    \n+\n+
    142 {
    \n+
    143 auto size = index_constant<N()>();
    \n+
    144 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n+
    145 (*this)[i] *= k;
    \n+
    146 });
    \n+
    147
    \n+
    148 return *this;
    \n+
    149 }
    \n+
    150
    \n+\n+
    153 {
    \n+
    154 auto size = index_constant<N()>();
    \n+
    155 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n+
    156 (*this)[i] /= k;
    \n+
    157 });
    \n+
    158
    \n+
    159 return *this;
    \n+
    160 }
    \n+
    161
    \n+
    162
    \n+\n+
    169 {
    \n+
    170 auto size = index_constant<N()>();
    \n+
    171 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n+
    172 (*this)[i] += b[i];
    \n+
    173 });
    \n+
    174
    \n+
    175 return *this;
    \n+
    176 }
    \n+
    177
    \n+\n+
    184 {
    \n+
    185 auto size = index_constant<N()>();
    \n+
    186 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n+
    187 (*this)[i] -= b[i];
    \n+
    188 });
    \n+
    189
    \n+
    190 return *this;
    \n+
    191 }
    \n+
    192
    \n+
    195 template<typename X, typename Y>
    \n+
    196 void mv (const X& x, Y& y) const {
    \n+
    197 static_assert(X::size() == M(), "length of x does not match row length");
    \n+
    198 static_assert(Y::size() == N(), "length of y does not match row count");
    \n+
    199 y = 0; //reset y (for mv uses umv)
    \n+
    200 umv(x,y);
    \n+
    201 }
    \n+
    202
    \n+
    205 template<typename X, typename Y>
    \n+
    206 void umv (const X& x, Y& y) const {
    \n+
    207 static_assert(X::size() == M(), "length of x does not match row length");
    \n+
    208 static_assert(Y::size() == N(), "length of y does not match row count");
    \n+
    209 using namespace Dune::Hybrid;
    \n+
    210 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    211 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    212 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    213 (*this)[i][j].umv(x[j], y[i]);
    \n+
    214 });
    \n+
    215 });
    \n+
    216 }
    \n+
    217
    \n+
    220 template<typename X, typename Y>
    \n+
    221 void mmv (const X& x, Y& y) const {
    \n+
    222 static_assert(X::size() == M(), "length of x does not match row length");
    \n+
    223 static_assert(Y::size() == N(), "length of y does not match row count");
    \n+
    224 using namespace Dune::Hybrid;
    \n+
    225 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    226 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    227 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    228 (*this)[i][j].mmv(x[j], y[i]);
    \n+
    229 });
    \n+
    230 });
    \n+
    231 }
    \n+
    232
    \n+
    235 template<typename AlphaType, typename X, typename Y>
    \n+
    236 void usmv (const AlphaType& alpha, const X& x, Y& y) const {
    \n+
    237 static_assert(X::size() == M(), "length of x does not match row length");
    \n+
    238 static_assert(Y::size() == N(), "length of y does not match row count");
    \n+
    239 using namespace Dune::Hybrid;
    \n+
    240 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    241 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    242 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    243 (*this)[i][j].usmv(alpha, x[j], y[i]);
    \n+
    244 });
    \n+
    245 });
    \n+
    246 }
    \n+
    247
    \n+
    250 template<typename X, typename Y>
    \n+
    251 void mtv (const X& x, Y& y) const {
    \n+
    252 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    253 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    254 y = 0;
    \n+
    255 umtv(x,y);
    \n+
    256 }
    \n+
    257
    \n+
    260 template<typename X, typename Y>
    \n+
    261 void umtv (const X& x, Y& y) const {
    \n+
    262 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    263 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    264 using namespace Dune::Hybrid;
    \n+
    265 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    266 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    267 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    268 (*this)[j][i].umtv(x[j], y[i]);
    \n+
    269 });
    \n+
    270 });
    \n+
    271 }
    \n+
    272
    \n+
    275 template<typename X, typename Y>
    \n+
    276 void mmtv (const X& x, Y& y) const {
    \n+
    277 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    278 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    279 using namespace Dune::Hybrid;
    \n+
    280 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    281 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    282 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    283 (*this)[j][i].mmtv(x[j], y[i]);
    \n+
    284 });
    \n+
    285 });
    \n+
    286 }
    \n+
    287
    \n+
    290 template<typename X, typename Y>
    \n+
    291 void usmtv (const field_type& alpha, const X& x, Y& y) const {
    \n+
    292 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    293 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    294 using namespace Dune::Hybrid;
    \n+
    295 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    296 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    297 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    298 (*this)[j][i].usmtv(alpha, x[j], y[i]);
    \n+
    299 });
    \n+
    300 });
    \n+
    301 }
    \n+
    302
    \n+
    305 template<typename X, typename Y>
    \n+
    306 void umhv (const X& x, Y& y) const {
    \n+
    307 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    308 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    309 using namespace Dune::Hybrid;
    \n+
    310 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    311 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    312 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    313 (*this)[j][i].umhv(x[j], y[i]);
    \n+
    314 });
    \n+
    315 });
    \n+
    316 }
    \n+
    317
    \n+
    320 template<typename X, typename Y>
    \n+
    321 void mmhv (const X& x, Y& y) const {
    \n+
    322 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    323 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    324 using namespace Dune::Hybrid;
    \n+
    325 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    326 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    327 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    328 (*this)[j][i].mmhv(x[j], y[i]);
    \n+
    329 });
    \n+
    330 });
    \n+
    331 }
    \n+
    332
    \n+
    335 template<typename X, typename Y>
    \n+
    336 void usmhv (const field_type& alpha, const X& x, Y& y) const {
    \n+
    337 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n+
    338 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n+
    339 using namespace Dune::Hybrid;
    \n+
    340 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n+
    341 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    342 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n+
    343 (*this)[j][i].usmhv(alpha, x[j], y[i]);
    \n+
    344 });
    \n+
    345 });
    \n+
    346 }
    \n+
    347
    \n+
    348
    \n+
    349 //===== norms
    \n+
    350
    \n+
    352 auto frobenius_norm2 () const
    \n+
    353 {
    \n+
    354 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n+
    355 typename FieldTraits<field_type_00>::real_type sum=0;
    \n+
    356
    \n+
    357 auto rows = index_constant<N()>();
    \n+
    358 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n+
    359 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n+
    360 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n+
    361 sum += (*this)[i][j].frobenius_norm2();
    \n+
    362 });
    \n+
    363 });
    \n+
    364
    \n+
    365 return sum;
    \n+
    366 }
    \n+
    367
    \n+
    369 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n+
    370 {
    \n+
    371 return sqrt(frobenius_norm2());
    \n+
    372 }
    \n+
    373
    \n+
    375 auto infinity_norm () const
    \n+
    376 {
    \n+
    377 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n+
    378 using std::max;
    \n+
    379 typename FieldTraits<field_type_00>::real_type norm=0;
    \n+
    380
    \n+
    381 auto rows = index_constant<N()>();
    \n+
    382 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n+
    383
    \n+
    384 typename FieldTraits<field_type_00>::real_type sum=0;
    \n+
    385 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n+
    386 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n+
    387 sum += (*this)[i][j].infinity_norm();
    \n+
    388 });
    \n+
    389 norm = max(sum, norm);
    \n+
    390 });
    \n+
    391
    \n+
    392 return norm;
    \n+
    393 }
    \n+
    394
    \n+
    396 auto infinity_norm_real () const
    \n+
    397 {
    \n+
    398 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n+
    399 using std::max;
    \n+
    400 typename FieldTraits<field_type_00>::real_type norm=0;
    \n+
    401
    \n+
    402 auto rows = index_constant<N()>();
    \n+
    403 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n+
    404
    \n+
    405 typename FieldTraits<field_type_00>::real_type sum=0;
    \n+
    406 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n+
    407 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n+
    408 sum += (*this)[i][j].infinity_norm_real();
    \n+
    409 });
    \n+
    410 norm = max(sum, norm);
    \n+
    411 });
    \n+
    412
    \n+
    413 return norm;
    \n+
    414 }
    \n+
    415
    \n+
    416 };
    \n+
    417
    \n+
    423 template<typename T1, typename... Args>
    \n+
    424 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockMatrix<T1,Args...>& m) {
    \n+
    425 auto N = index_constant<MultiTypeBlockMatrix<T1,Args...>::N()>();
    \n+
    426 auto M = index_constant<MultiTypeBlockMatrix<T1,Args...>::M()>();
    \n+
    427 using namespace Dune::Hybrid;
    \n+
    428 forEach(integralRange(N), [&](auto&& i) {
    \n+
    429 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    430 forEach(integralRange(M), [&](auto&& j) {
    \n+
    431 s << "\\t(" << i << ", " << j << "): \\n" << m[i][j];
    \n+
    432 });
    \n+
    433 });
    \n+
    434 s << std::endl;
    \n+
    435 return s;
    \n+
    436 }
    \n+
    437
    \n+
    438 //make algmeta_itsteps known
    \n+
    439 template<int I, typename M>
    \n+
    440 struct algmeta_itsteps;
    \n+
    441
    \n+
    448 template<int I, int crow, int ccol, int remain_col> //MultiTypeBlockMatrix_Solver_Col: iterating over one row
    \n+
    449 class MultiTypeBlockMatrix_Solver_Col { //calculating b- A[i][j]*x[j]
    \n+
    450 public:
    \n+
    454 template <typename Trhs, typename TVector, typename TMatrix, typename K>
    \n+
    455 static void calc_rhs(const TMatrix& A, TVector& x, TVector& v, Trhs& b, const K& w) {
    \n+
    456 std::get<ccol>( std::get<crow>(A) ).mmv( std::get<ccol>(x), b );
    \n+\n+
    458 }
    \n+
    459
    \n+
    460 };
    \n+
    461 template<int I, int crow, int ccol> //MultiTypeBlockMatrix_Solver_Col recursion end
    \n+
    462 class MultiTypeBlockMatrix_Solver_Col<I,crow,ccol,0> {
    \n+
    463 public:
    \n+
    464 template <typename Trhs, typename TVector, typename TMatrix, typename K>
    \n+
    465 static void calc_rhs(const TMatrix&, TVector&, TVector&, Trhs&, const K&) {}
    \n+
    466 };
    \n+
    467
    \n+
    468
    \n+
    469
    \n+
    476 template<int I, int crow, int remain_row>
    \n+\n+
    478 public:
    \n+
    479
    \n+
    483 template <typename TVector, typename TMatrix, typename K>
    \n+
    484 static void dbgs(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n+
    485 TVector xold(x);
    \n+
    486 xold=x; //store old x values
    \n+\n+
    488 x *= w;
    \n+
    489 x.axpy(1-w,xold); //improve x
    \n+
    490 }
    \n+
    491 template <typename TVector, typename TMatrix, typename K>
    \n+
    492 static void dbgs(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n+
    493 auto rhs = std::get<crow> (b);
    \n+
    494
    \n+
    495 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n+
    496 //solve on blocklevel I-1
    \n+
    497 using M =
    \n+
    498 typename std::remove_cv<
    \n+
    499 typename std::remove_reference<
    \n+
    500 decltype(std::get<crow>( std::get<crow>(A)))
    \n+
    501 >::type
    \n+
    502 >::type;
    \n+
    503 algmeta_itsteps<I-1,M>::dbgs(std::get<crow>( std::get<crow>(A)), std::get<crow>(x),rhs,w);
    \n+\n+
    505 }
    \n+
    506
    \n+
    507
    \n+
    508
    \n+
    512 template <typename TVector, typename TMatrix, typename K>
    \n+
    513 static void bsorf(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n+
    514 TVector v;
    \n+
    515 v=x; //use latest x values in right side calculation
    \n+\n+
    517
    \n+
    518 }
    \n+
    519 template <typename TVector, typename TMatrix, typename K> //recursion over all matrix rows (A)
    \n+
    520 static void bsorf(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n+
    521 auto rhs = std::get<crow> (b);
    \n+
    522
    \n+
    523 MultiTypeBlockMatrix_Solver_Col<I,crow,0,TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n+
    524 //solve on blocklevel I-1
    \n+
    525 using M =
    \n+
    526 typename std::remove_cv<
    \n+
    527 typename std::remove_reference<
    \n+
    528 decltype(std::get<crow>( std::get<crow>(A)))
    \n+
    529 >::type
    \n+
    530 >::type;
    \n+
    531 algmeta_itsteps<I-1,M>::bsorf(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n+
    532 std::get<crow>(x).axpy(w,std::get<crow>(v));
    \n+\n+
    534 }
    \n+
    535
    \n+
    539 template <typename TVector, typename TMatrix, typename K>
    \n+
    540 static void bsorb(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n+
    541 TVector v;
    \n+
    542 v=x; //use latest x values in right side calculation
    \n+\n+
    544
    \n+
    545 }
    \n+
    546 template <typename TVector, typename TMatrix, typename K> //recursion over all matrix rows (A)
    \n+
    547 static void bsorb(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n+
    548 auto rhs = std::get<crow> (b);
    \n+
    549
    \n+
    550 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n+
    551 //solve on blocklevel I-1
    \n+
    552 using M =
    \n+
    553 typename std::remove_cv<
    \n+
    554 typename std::remove_reference<
    \n+
    555 decltype(std::get<crow>( std::get<crow>(A)))
    \n+
    556 >::type
    \n+
    557 >::type;
    \n+
    558 algmeta_itsteps<I-1,M>::bsorb(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n+
    559 std::get<crow>(x).axpy(w,std::get<crow>(v));
    \n+\n+
    561 }
    \n+
    562
    \n+
    563
    \n+
    567 template <typename TVector, typename TMatrix, typename K>
    \n+
    568 static void dbjac(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n+
    569 TVector v(x);
    \n+
    570 v=0; //calc new x in v
    \n+\n+
    572 x.axpy(w,v); //improve x
    \n+
    573 }
    \n+
    574 template <typename TVector, typename TMatrix, typename K>
    \n+
    575 static void dbjac(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n+
    576 auto rhs = std::get<crow> (b);
    \n+
    577
    \n+
    578 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n+
    579 //solve on blocklevel I-1
    \n+
    580 using M =
    \n+
    581 typename std::remove_cv<
    \n+
    582 typename std::remove_reference<
    \n+
    583 decltype(std::get<crow>( std::get<crow>(A)))
    \n+
    584 >::type
    \n+
    585 >::type;
    \n+
    586 algmeta_itsteps<I-1,M>::dbjac(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n+\n+
    588 }
    \n+
    589
    \n+
    590
    \n+
    591
    \n+
    592
    \n+
    593 };
    \n+
    594 template<int I, int crow> //recursion end for remain_row = 0
    \n+\n+
    596 public:
    \n+
    597 template <typename TVector, typename TMatrix, typename K>
    \n+
    598 static void dbgs(const TMatrix&, TVector&, TVector&,
    \n+
    599 const TVector&, const K&) {}
    \n+
    600
    \n+
    601 template <typename TVector, typename TMatrix, typename K>
    \n+
    602 static void bsorf(const TMatrix&, TVector&, TVector&,
    \n+
    603 const TVector&, const K&) {}
    \n+
    604
    \n+
    605 template <typename TVector, typename TMatrix, typename K>
    \n+
    606 static void bsorb(const TMatrix&, TVector&, TVector&,
    \n+
    607 const TVector&, const K&) {}
    \n+
    608
    \n+
    609 template <typename TVector, typename TMatrix, typename K>
    \n+
    610 static void dbjac(const TMatrix&, TVector&, TVector&,
    \n+
    611 const TVector&, const K&) {}
    \n+
    612 };
    \n+
    613
    \n+
    614} // end namespace Dune
    \n+
    615
    \n+
    616namespace std
    \n+
    617{
    \n+
    622 template <size_t i, typename... Args>
    \n+
    623 struct tuple_element<i,Dune::MultiTypeBlockMatrix<Args...> >
    \n+
    624 {
    \n+
    625 using type = typename std::tuple_element<i, std::tuple<Args...> >::type;
    \n+
    626 };
    \n+
    627}
    \n+
    628#endif
    \n+\n+
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    MultiTypeBlockMatrix< FirstRow, Args... > type
    Definition: multitypeblockmatrix.hh:56
    \n+
    static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:568
    \n+
    MultiTypeBlockMatrix & operator+=(const MultiTypeBlockMatrix &b)
    Add the entries of another matrix to this one.
    Definition: multitypeblockmatrix.hh:168
    \n+
    void mv(const X &x, Y &y) const
    y = A x
    Definition: multitypeblockmatrix.hh:196
    \n+
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: multitypeblockmatrix.hh:276
    \n+
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: multitypeblockmatrix.hh:321
    \n+
    static void dbgs(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:598
    \n+
    static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:484
    \n+
    static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:540
    \n+
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: multitypeblockmatrix.hh:336
    \n+
    FirstRow::field_type field_type
    Definition: multitypeblockmatrix.hh:61
    \n+
    void usmv(const AlphaType &alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: multitypeblockmatrix.hh:236
    \n+
    MultiTypeBlockMatrix & operator/=(const field_type &k)
    vector space division by scalar
    Definition: multitypeblockmatrix.hh:152
    \n+
    typename std::tuple_element< i, std::tuple< Args... > >::type type
    Definition: multitypeblockmatrix.hh:625
    \n+
    static void dbgs(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:492
    \n+
    static void bsorf(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:520
    \n+
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: multitypeblockmatrix.hh:306
    \n+
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: multitypeblockmatrix.hh:369
    \n+
    static constexpr size_type N()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:64
    \n+
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: multitypeblockmatrix.hh:291
    \n+
    void operator=(const T &newval)
    Definition: multitypeblockmatrix.hh:127
    \n+
    static void calc_rhs(const TMatrix &, TVector &, TVector &, Trhs &, const K &)
    Definition: multitypeblockmatrix.hh:465
    \n+
    void umv(const X &x, Y &y) const
    y += A x
    Definition: multitypeblockmatrix.hh:206
    \n+
    static void calc_rhs(const TMatrix &A, TVector &x, TVector &v, Trhs &b, const K &w)
    Definition: multitypeblockmatrix.hh:455
    \n+
    static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:513
    \n+
    static constexpr size_type size()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:75
    \n+
    static void dbjac(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:610
    \n+
    auto infinity_norm_real() const
    Bastardized version of the infinity-norm / row-sum norm.
    Definition: multitypeblockmatrix.hh:396
    \n+
    auto frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: multitypeblockmatrix.hh:352
    \n+
    std::size_t size_type
    Type used for sizes.
    Definition: multitypeblockmatrix.hh:59
    \n+
    auto infinity_norm() const
    Bastardized version of the infinity-norm / row-sum norm.
    Definition: multitypeblockmatrix.hh:375
    \n+
    static void bsorb(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:606
    \n+
    MultiTypeBlockMatrix & operator-=(const MultiTypeBlockMatrix &b)
    Subtract the entries of another matrix from this one.
    Definition: multitypeblockmatrix.hh:183
    \n+
    auto operator[](const std::integral_constant< size_type, index > indexVariable) -> decltype(std::get< index >(*this))
    Random-access operator.
    Definition: multitypeblockmatrix.hh:104
    \n+
    static void dbjac(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:575
    \n+
    static void bsorf(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:602
    \n+
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: multitypeblockmatrix.hh:251
    \n+
    static constexpr size_type M()
    Return the number of matrix columns.
    Definition: multitypeblockmatrix.hh:81
    \n+
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: multitypeblockmatrix.hh:221
    \n+
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: multitypeblockmatrix.hh:261
    \n+
    static void bsorb(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:547
    \n+
    MultiTypeBlockMatrix & operator*=(const field_type &k)
    vector space multiplication with scalar
    Definition: multitypeblockmatrix.hh:141
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    Definition: solvertype.hh:16
    \n-
    @ value
    Whether this is a direct solver.
    Definition: solvertype.hh:24
    \n-
    Definition: solvertype.hh:30
    \n-
    @ value
    whether the solver internally uses column compressed storage
    Definition: solvertype.hh:36
    \n+
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n+
    A Matrix class to support different block types.
    Definition: multitypeblockmatrix.hh:46
    \n+
    static void bsorb(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:461
    \n+
    static void bsorf(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:418
    \n+
    static void dbjac(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:504
    \n+
    static void dbgs(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:378
    \n+
    solver for MultiTypeBlockVector & MultiTypeBlockMatrix types
    Definition: multitypeblockmatrix.hh:477
    \n+
    part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types
    Definition: multitypeblockmatrix.hh:449
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,55 +4,761 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solvertype.hh\n+multitypeblockmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SOLVERTYPE_HH\n- 6#define DUNE_ISTL_SOLVERTYPE_HH\n+ 5#ifndef DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH\n+ 6#define DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH\n 7\n- 12namespace Dune\n- 13{\n- 14 template\n-15 struct IsDirectSolver\n- 16 {\n- 17 enum\n- 18 {\n- 24 value =false\n-25 };\n- 26 };\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11\n+ 12#include \n+ 13\n+ 14#include \"istlexception.hh\"\n+ 15\n+ 16// forward declaration\n+ 17namespace Dune\n+ 18{\n+ 19 template\n+ 20 class MultiTypeBlockMatrix;\n+ 21\n+ 22 template\n+ 23 class MultiTypeBlockMatrix_Solver;\n+ 24}\n+ 25\n+ 26#include \"gsetc.hh\"\n 27\n- 28 template\n-29 struct StoresColumnCompressed\n- 30 {\n- 31 enum\n- 32 {\n- 36 value = false\n-37 };\n- 38 };\n- 39} // end namespace Dune\n- 40#endif\n+ 28namespace Dune {\n+ 29\n+ 43 template\n+44 class MultiTypeBlockMatrix\n+ 45 : public std::tuple\n+ 46 {\n+ 47 using ParentType = std::tuple;\n+ 48 public:\n+ 49\n+ 51 using ParentType::ParentType;\n+ 52\n+56 typedef MultiTypeBlockMatrix type;\n+ 57\n+59 using size_type = std::size_t;\n+ 60\n+61 typedef typename FirstRow::field_type field_type;\n+ 62\n+64 static constexpr size_type N()\n+ 65 {\n+ 66 return 1+sizeof...(Args);\n+ 67 }\n+ 68\n+ 74 [[deprecated(\"Use method 'N' instead\")]]\n+75 static constexpr size_type size()\n+ 76 {\n+ 77 return 1+sizeof...(Args);\n+ 78 }\n+ 79\n+81 static constexpr size_type M()\n+ 82 {\n+ 83 return FirstRow::size();\n+ 84 }\n+ 85\n+ 102 template< size_type index >\n+ 103 auto\n+104 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n+> indexVariable)\n+ 105 -> decltype(std::get(*this))\n+ 106 {\n+ 107 return std::get(*this);\n+ 108 }\n+ 109\n+ 115 template< size_type index >\n+ 116 auto\n+117 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n+> indexVariable) const\n+ 118 -> decltype(std::get(*this))\n+ 119 {\n+ 120 return std::get(*this);\n+ 121 }\n+ 122\n+ 126 template\n+127 void operator=(const T& newval) {\n+ 128 using namespace Dune::Hybrid;\n+ 129 auto size = index_constant<1+sizeof...(Args)>();\n+ 130 // Since Dune::Hybrid::size(MultiTypeBlockMatrix) is not implemented,\n+ 131 // we cannot use a plain forEach(*this, ...). This could be achieved,\n+ 132 // e.g., by implementing a static size() method.\n+ 133 forEach(integralRange(size), [&](auto&& i) {\n+ 134 (*this)[i] = newval;\n+ 135 });\n+ 136 }\n+ 137\n+ 138 //===== vector space arithmetic\n+ 139\n+141 MultiTypeBlockMatrix& operator*=(const field_type& k)\n+ 142 {\n+ 143 auto size = index_constant();\n+ 144 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n+ 145 (*this)[i] *= k;\n+ 146 });\n+ 147\n+ 148 return *this;\n+ 149 }\n+ 150\n+152 MultiTypeBlockMatrix& operator/=(const field_type& k)\n+ 153 {\n+ 154 auto size = index_constant();\n+ 155 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n+ 156 (*this)[i] /= k;\n+ 157 });\n+ 158\n+ 159 return *this;\n+ 160 }\n+ 161\n+ 162\n+168 MultiTypeBlockMatrix& operator+=(const MultiTypeBlockMatrix& b)\n+ 169 {\n+ 170 auto size = index_constant();\n+ 171 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n+ 172 (*this)[i] += b[i];\n+ 173 });\n+ 174\n+ 175 return *this;\n+ 176 }\n+ 177\n+183 MultiTypeBlockMatrix& operator-=(const MultiTypeBlockMatrix& b)\n+ 184 {\n+ 185 auto size = index_constant();\n+ 186 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n+ 187 (*this)[i] -= b[i];\n+ 188 });\n+ 189\n+ 190 return *this;\n+ 191 }\n+ 192\n+ 195 template\n+196 void mv (const X& x, Y& y) const {\n+ 197 static_assert(X::size() == M(), \"length of x does not match row length\");\n+ 198 static_assert(Y::size() == N(), \"length of y does not match row count\");\n+ 199 y = 0; //reset y (for mv uses umv)\n+ 200 umv(x,y);\n+ 201 }\n+ 202\n+ 205 template\n+206 void umv (const X& x, Y& y) const {\n+ 207 static_assert(X::size() == M(), \"length of x does not match row length\");\n+ 208 static_assert(Y::size() == N(), \"length of y does not match row count\");\n+ 209 using namespace Dune::Hybrid;\n+ 210 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 211 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 212 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 213 (*this)[i][j].umv(x[j], y[i]);\n+ 214 });\n+ 215 });\n+ 216 }\n+ 217\n+ 220 template\n+221 void mmv (const X& x, Y& y) const {\n+ 222 static_assert(X::size() == M(), \"length of x does not match row length\");\n+ 223 static_assert(Y::size() == N(), \"length of y does not match row count\");\n+ 224 using namespace Dune::Hybrid;\n+ 225 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 226 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 227 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 228 (*this)[i][j].mmv(x[j], y[i]);\n+ 229 });\n+ 230 });\n+ 231 }\n+ 232\n+ 235 template\n+236 void usmv (const AlphaType& alpha, const X& x, Y& y) const {\n+ 237 static_assert(X::size() == M(), \"length of x does not match row length\");\n+ 238 static_assert(Y::size() == N(), \"length of y does not match row count\");\n+ 239 using namespace Dune::Hybrid;\n+ 240 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 241 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 242 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 243 (*this)[i][j].usmv(alpha, x[j], y[i]);\n+ 244 });\n+ 245 });\n+ 246 }\n+ 247\n+ 250 template\n+251 void mtv (const X& x, Y& y) const {\n+ 252 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 253 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 254 y = 0;\n+ 255 umtv(x,y);\n+ 256 }\n+ 257\n+ 260 template\n+261 void umtv (const X& x, Y& y) const {\n+ 262 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 263 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 264 using namespace Dune::Hybrid;\n+ 265 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 266 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 267 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 268 (*this)[j][i].umtv(x[j], y[i]);\n+ 269 });\n+ 270 });\n+ 271 }\n+ 272\n+ 275 template\n+276 void mmtv (const X& x, Y& y) const {\n+ 277 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 278 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 279 using namespace Dune::Hybrid;\n+ 280 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 281 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 282 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 283 (*this)[j][i].mmtv(x[j], y[i]);\n+ 284 });\n+ 285 });\n+ 286 }\n+ 287\n+ 290 template\n+291 void usmtv (const field_type& alpha, const X& x, Y& y) const {\n+ 292 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 293 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 294 using namespace Dune::Hybrid;\n+ 295 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 296 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 297 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 298 (*this)[j][i].usmtv(alpha, x[j], y[i]);\n+ 299 });\n+ 300 });\n+ 301 }\n+ 302\n+ 305 template\n+306 void umhv (const X& x, Y& y) const {\n+ 307 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 308 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 309 using namespace Dune::Hybrid;\n+ 310 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 311 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 312 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 313 (*this)[j][i].umhv(x[j], y[i]);\n+ 314 });\n+ 315 });\n+ 316 }\n+ 317\n+ 320 template\n+321 void mmhv (const X& x, Y& y) const {\n+ 322 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 323 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 324 using namespace Dune::Hybrid;\n+ 325 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 326 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 327 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 328 (*this)[j][i].mmhv(x[j], y[i]);\n+ 329 });\n+ 330 });\n+ 331 }\n+ 332\n+ 335 template\n+336 void usmhv (const field_type& alpha, const X& x, Y& y) const {\n+ 337 static_assert(X::size() == N(), \"length of x does not match number of\n+rows\");\n+ 338 static_assert(Y::size() == M(), \"length of y does not match number of\n+columns\");\n+ 339 using namespace Dune::Hybrid;\n+ 340 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n+ 341 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 342 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n+ 343 (*this)[j][i].usmhv(alpha, x[j], y[i]);\n+ 344 });\n+ 345 });\n+ 346 }\n+ 347\n+ 348\n+ 349 //===== norms\n+ 350\n+352 auto frobenius_norm2 () const\n+ 353 {\n+ 354 using field_type_00 = typename std::decay_t::field_type;\n+ 355 typename FieldTraits::real_type sum=0;\n+ 356\n+ 357 auto rows = index_constant();\n+ 358 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n+ 359 auto cols = index_constant::M()>\n+();\n+ 360 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n+ 361 sum += (*this)[i][j].frobenius_norm2();\n+ 362 });\n+ 363 });\n+ 364\n+ 365 return sum;\n+ 366 }\n+ 367\n+369 typename FieldTraits::real_type frobenius_norm () const\n+ 370 {\n+ 371 return sqrt(frobenius_norm2());\n+ 372 }\n+ 373\n+375 auto infinity_norm () const\n+ 376 {\n+ 377 using field_type_00 = typename std::decay_t::field_type;\n+ 378 using std::max;\n+ 379 typename FieldTraits::real_type norm=0;\n+ 380\n+ 381 auto rows = index_constant();\n+ 382 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n+ 383\n+ 384 typename FieldTraits::real_type sum=0;\n+ 385 auto cols = index_constant::M()>\n+();\n+ 386 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n+ 387 sum += (*this)[i][j].infinity_norm();\n+ 388 });\n+ 389 norm = max(sum, norm);\n+ 390 });\n+ 391\n+ 392 return norm;\n+ 393 }\n+ 394\n+396 auto infinity_norm_real () const\n+ 397 {\n+ 398 using field_type_00 = typename std::decay_t::field_type;\n+ 399 using std::max;\n+ 400 typename FieldTraits::real_type norm=0;\n+ 401\n+ 402 auto rows = index_constant();\n+ 403 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n+ 404\n+ 405 typename FieldTraits::real_type sum=0;\n+ 406 auto cols = index_constant::M()>\n+();\n+ 407 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n+ 408 sum += (*this)[i][j].infinity_norm_real();\n+ 409 });\n+ 410 norm = max(sum, norm);\n+ 411 });\n+ 412\n+ 413 return norm;\n+ 414 }\n+ 415\n+ 416 };\n+ 417\n+ 423 template\n+424 std::ostream& operator<<(std::ostream& s, const\n+MultiTypeBlockMatrix& m) {\n+ 425 auto N = index_constant::N()>();\n+ 426 auto M = index_constant::M()>();\n+ 427 using namespace Dune::Hybrid;\n+ 428 forEach(integralRange(N), [&](auto&& i) {\n+ 429 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 430 forEach(integralRange(M), [&](auto&& j) {\n+ 431 s << \"\\t(\" << i << \", \" << j << \"): \\n\" << m[i][j];\n+ 432 });\n+ 433 });\n+ 434 s << std::endl;\n+ 435 return s;\n+ 436 }\n+ 437\n+ 438 //make algmeta_itsteps known\n+ 439 template\n+ 440 struct algmeta_itsteps;\n+ 441\n+ 448 template //\n+MultiTypeBlockMatrix_Solver_Col: iterating over one row\n+449 class MultiTypeBlockMatrix_Solver_Col { //calculating b- A[i][j]*x[j]\n+ 450 public:\n+ 454 template \n+455 static void calc_rhs(const TMatrix& A, TVector& x, TVector& v, Trhs& b,\n+const K& w) {\n+ 456 std::get( std::get(A) ).mmv( std::get(x), b );\n+ 457 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+(A,x,v,b,w); //next column element\n+ 458 }\n+ 459\n+ 460 };\n+ 461 template //MultiTypeBlockMatrix_Solver_Col\n+recursion end\n+462 class MultiTypeBlockMatrix_Solver_Col {\n+ 463 public:\n+ 464 template \n+465 static void calc_rhs(const TMatrix&, TVector&, TVector&, Trhs&, const K&)\n+{}\n+ 466 };\n+ 467\n+ 468\n+ 469\n+ 476 template\n+477 class MultiTypeBlockMatrix_Solver {\n+ 478 public:\n+ 479\n+ 483 template \n+484 static void dbgs(const TMatrix& A, TVector& x, const TVector& b, const K&\n+w) {\n+ 485 TVector xold(x);\n+ 486 xold=x; //store old x values\n+ 487 MultiTypeBlockMatrix_Solver::dbgs(A,x,x,b,w);\n+ 488 x *= w;\n+ 489 x.axpy(1-w,xold); //improve x\n+ 490 }\n+ 491 template \n+492 static void dbgs(const TMatrix& A, TVector& x, TVector& v, const TVector&\n+b, const K& w) {\n+ 493 auto rhs = std::get (b);\n+ 494\n+ 495 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+(A,x,v,rhs,w); // calculate right side of equation\n+ 496 //solve on blocklevel I-1\n+ 497 using M =\n+ 498 typename std::remove_cv<\n+ 499 typename std::remove_reference<\n+ 500 decltype(std::get( std::get(A)))\n+ 501 >::type\n+ 502 >::type;\n+ 503 algmeta_itsteps::dbgs(std::get( std::get(A)), std::\n+get(x),rhs,w);\n+ 504 MultiTypeBlockMatrix_Solver::dbgs(A,x,v,b,w); //\n+next row\n+ 505 }\n+ 506\n+ 507\n+ 508\n+ 512 template \n+513 static void bsorf(const TMatrix& A, TVector& x, const TVector& b, const K&\n+w) {\n+ 514 TVector v;\n+ 515 v=x; //use latest x values in right side calculation\n+ 516 MultiTypeBlockMatrix_Solver::bsorf(A,x,v,b,w);\n+ 517\n+ 518 }\n+ 519 template //recursion over\n+all matrix rows (A)\n+520 static void bsorf(const TMatrix& A, TVector& x, TVector& v, const TVector&\n+b, const K& w) {\n+ 521 auto rhs = std::get (b);\n+ 522\n+ 523 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+(A,x,v,rhs,w); // calculate right side of equation\n+ 524 //solve on blocklevel I-1\n+ 525 using M =\n+ 526 typename std::remove_cv<\n+ 527 typename std::remove_reference<\n+ 528 decltype(std::get( std::get(A)))\n+ 529 >::type\n+ 530 >::type;\n+ 531 algmeta_itsteps::bsorf(std::get( std::get(A)), std::\n+get(v),rhs,w);\n+ 532 std::get(x).axpy(w,std::get(v));\n+ 533 MultiTypeBlockMatrix_Solver::bsorf(A,x,v,b,w); //\n+next row\n+ 534 }\n+ 535\n+ 539 template \n+540 static void bsorb(const TMatrix& A, TVector& x, const TVector& b, const K&\n+w) {\n+ 541 TVector v;\n+ 542 v=x; //use latest x values in right side calculation\n+ 543 MultiTypeBlockMatrix_Solver::bsorb(A,x,v,b,w);\n+ 544\n+ 545 }\n+ 546 template //recursion over\n+all matrix rows (A)\n+547 static void bsorb(const TMatrix& A, TVector& x, TVector& v, const TVector&\n+b, const K& w) {\n+ 548 auto rhs = std::get (b);\n+ 549\n+ 550 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+(A,x,v,rhs,w); // calculate right side of equation\n+ 551 //solve on blocklevel I-1\n+ 552 using M =\n+ 553 typename std::remove_cv<\n+ 554 typename std::remove_reference<\n+ 555 decltype(std::get( std::get(A)))\n+ 556 >::type\n+ 557 >::type;\n+ 558 algmeta_itsteps::bsorb(std::get( std::get(A)), std::\n+get(v),rhs,w);\n+ 559 std::get(x).axpy(w,std::get(v));\n+ 560 MultiTypeBlockMatrix_Solver::bsorb(A,x,v,b,w); //\n+next row\n+ 561 }\n+ 562\n+ 563\n+ 567 template \n+568 static void dbjac(const TMatrix& A, TVector& x, const TVector& b, const K&\n+w) {\n+ 569 TVector v(x);\n+ 570 v=0; //calc new x in v\n+ 571 MultiTypeBlockMatrix_Solver::dbjac(A,x,v,b,w);\n+ 572 x.axpy(w,v); //improve x\n+ 573 }\n+ 574 template \n+575 static void dbjac(const TMatrix& A, TVector& x, TVector& v, const TVector&\n+b, const K& w) {\n+ 576 auto rhs = std::get (b);\n+ 577\n+ 578 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+(A,x,v,rhs,w); // calculate right side of equation\n+ 579 //solve on blocklevel I-1\n+ 580 using M =\n+ 581 typename std::remove_cv<\n+ 582 typename std::remove_reference<\n+ 583 decltype(std::get( std::get(A)))\n+ 584 >::type\n+ 585 >::type;\n+ 586 algmeta_itsteps::dbjac(std::get( std::get(A)), std::\n+get(v),rhs,w);\n+ 587 MultiTypeBlockMatrix_Solver::dbjac(A,x,v,b,w); //\n+next row\n+ 588 }\n+ 589\n+ 590\n+ 591\n+ 592\n+ 593 };\n+ 594 template //recursion end for remain_row = 0\n+595 class MultiTypeBlockMatrix_Solver {\n+ 596 public:\n+ 597 template \n+598 static void dbgs(const TMatrix&, TVector&, TVector&,\n+ 599 const TVector&, const K&) {}\n+ 600\n+ 601 template \n+602 static void bsorf(const TMatrix&, TVector&, TVector&,\n+ 603 const TVector&, const K&) {}\n+ 604\n+ 605 template \n+606 static void bsorb(const TMatrix&, TVector&, TVector&,\n+ 607 const TVector&, const K&) {}\n+ 608\n+ 609 template \n+610 static void dbjac(const TMatrix&, TVector&, TVector&,\n+ 611 const TVector&, const K&) {}\n+ 612 };\n+ 613\n+ 614} // end namespace Dune\n+ 615\n+ 616namespace std\n+ 617{\n+ 622 template \n+623 struct tuple_element >\n+ 624 {\n+625 using type = typename std::tuple_element >::type;\n+ 626 };\n+ 627}\n+ 628#endif\n+istlexception.hh\n+gsetc.hh\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way.\n+Dune::MultiTypeBlockMatrix::type\n+MultiTypeBlockMatrix< FirstRow, Args... > type\n+Definition: multitypeblockmatrix.hh:56\n+Dune::MultiTypeBlockMatrix_Solver::dbjac\n+static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:568\n+Dune::MultiTypeBlockMatrix::operator+=\n+MultiTypeBlockMatrix & operator+=(const MultiTypeBlockMatrix &b)\n+Add the entries of another matrix to this one.\n+Definition: multitypeblockmatrix.hh:168\n+Dune::MultiTypeBlockMatrix::mv\n+void mv(const X &x, Y &y) const\n+y = A x\n+Definition: multitypeblockmatrix.hh:196\n+Dune::MultiTypeBlockMatrix::mmtv\n+void mmtv(const X &x, Y &y) const\n+y -= A^T x\n+Definition: multitypeblockmatrix.hh:276\n+Dune::MultiTypeBlockMatrix::mmhv\n+void mmhv(const X &x, Y &y) const\n+y -= A^H x\n+Definition: multitypeblockmatrix.hh:321\n+Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::dbgs\n+static void dbgs(const TMatrix &, TVector &, TVector &, const TVector &, const\n+K &)\n+Definition: multitypeblockmatrix.hh:598\n+Dune::MultiTypeBlockMatrix_Solver::dbgs\n+static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:484\n+Dune::MultiTypeBlockMatrix_Solver::bsorb\n+static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:540\n+Dune::MultiTypeBlockMatrix::usmhv\n+void usmhv(const field_type &alpha, const X &x, Y &y) const\n+y += alpha A^H x\n+Definition: multitypeblockmatrix.hh:336\n+Dune::MultiTypeBlockMatrix::field_type\n+FirstRow::field_type field_type\n+Definition: multitypeblockmatrix.hh:61\n+Dune::MultiTypeBlockMatrix::usmv\n+void usmv(const AlphaType &alpha, const X &x, Y &y) const\n+y += alpha A x\n+Definition: multitypeblockmatrix.hh:236\n+Dune::MultiTypeBlockMatrix::operator/=\n+MultiTypeBlockMatrix & operator/=(const field_type &k)\n+vector space division by scalar\n+Definition: multitypeblockmatrix.hh:152\n+std::tuple_element<_i,_Dune::MultiTypeBlockMatrix<_Args..._>_>::type\n+typename std::tuple_element< i, std::tuple< Args... > >::type type\n+Definition: multitypeblockmatrix.hh:625\n+Dune::MultiTypeBlockMatrix_Solver::dbgs\n+static void dbgs(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n+const K &w)\n+Definition: multitypeblockmatrix.hh:492\n+Dune::MultiTypeBlockMatrix_Solver::bsorf\n+static void bsorf(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n+const K &w)\n+Definition: multitypeblockmatrix.hh:520\n+Dune::MultiTypeBlockMatrix::umhv\n+void umhv(const X &x, Y &y) const\n+y += A^H x\n+Definition: multitypeblockmatrix.hh:306\n+Dune::MultiTypeBlockMatrix::frobenius_norm\n+FieldTraits< field_type >::real_type frobenius_norm() const\n+frobenius norm: sqrt(sum over squared values of entries)\n+Definition: multitypeblockmatrix.hh:369\n+Dune::MultiTypeBlockMatrix::N\n+static constexpr size_type N()\n+Return the number of matrix rows.\n+Definition: multitypeblockmatrix.hh:64\n+Dune::MultiTypeBlockMatrix::usmtv\n+void usmtv(const field_type &alpha, const X &x, Y &y) const\n+y += alpha A^T x\n+Definition: multitypeblockmatrix.hh:291\n+Dune::MultiTypeBlockMatrix::operator=\n+void operator=(const T &newval)\n+Definition: multitypeblockmatrix.hh:127\n+Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_0_>::calc_rhs\n+static void calc_rhs(const TMatrix &, TVector &, TVector &, Trhs &, const K &)\n+Definition: multitypeblockmatrix.hh:465\n+Dune::MultiTypeBlockMatrix::umv\n+void umv(const X &x, Y &y) const\n+y += A x\n+Definition: multitypeblockmatrix.hh:206\n+Dune::MultiTypeBlockMatrix_Solver_Col::calc_rhs\n+static void calc_rhs(const TMatrix &A, TVector &x, TVector &v, Trhs &b, const K\n+&w)\n+Definition: multitypeblockmatrix.hh:455\n+Dune::MultiTypeBlockMatrix_Solver::bsorf\n+static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:513\n+Dune::MultiTypeBlockMatrix::size\n+static constexpr size_type size()\n+Return the number of matrix rows.\n+Definition: multitypeblockmatrix.hh:75\n+Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::dbjac\n+static void dbjac(const TMatrix &, TVector &, TVector &, const TVector &, const\n+K &)\n+Definition: multitypeblockmatrix.hh:610\n+Dune::MultiTypeBlockMatrix::infinity_norm_real\n+auto infinity_norm_real() const\n+Bastardized version of the infinity-norm / row-sum norm.\n+Definition: multitypeblockmatrix.hh:396\n+Dune::MultiTypeBlockMatrix::frobenius_norm2\n+auto frobenius_norm2() const\n+square of frobenius norm, need for block recursion\n+Definition: multitypeblockmatrix.hh:352\n+Dune::MultiTypeBlockMatrix::size_type\n+std::size_t size_type\n+Type used for sizes.\n+Definition: multitypeblockmatrix.hh:59\n+Dune::MultiTypeBlockMatrix::infinity_norm\n+auto infinity_norm() const\n+Bastardized version of the infinity-norm / row-sum norm.\n+Definition: multitypeblockmatrix.hh:375\n+Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::bsorb\n+static void bsorb(const TMatrix &, TVector &, TVector &, const TVector &, const\n+K &)\n+Definition: multitypeblockmatrix.hh:606\n+Dune::MultiTypeBlockMatrix::operator-=\n+MultiTypeBlockMatrix & operator-=(const MultiTypeBlockMatrix &b)\n+Subtract the entries of another matrix from this one.\n+Definition: multitypeblockmatrix.hh:183\n+Dune::MultiTypeBlockMatrix::operator[]\n+auto operator[](const std::integral_constant< size_type, index > indexVariable)\n+-> decltype(std::get< index >(*this))\n+Random-access operator.\n+Definition: multitypeblockmatrix.hh:104\n+Dune::MultiTypeBlockMatrix_Solver::dbjac\n+static void dbjac(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n+const K &w)\n+Definition: multitypeblockmatrix.hh:575\n+Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::bsorf\n+static void bsorf(const TMatrix &, TVector &, TVector &, const TVector &, const\n+K &)\n+Definition: multitypeblockmatrix.hh:602\n+Dune::MultiTypeBlockMatrix::mtv\n+void mtv(const X &x, Y &y) const\n+y = A^T x\n+Definition: multitypeblockmatrix.hh:251\n+Dune::MultiTypeBlockMatrix::M\n+static constexpr size_type M()\n+Return the number of matrix columns.\n+Definition: multitypeblockmatrix.hh:81\n+Dune::MultiTypeBlockMatrix::mmv\n+void mmv(const X &x, Y &y) const\n+y -= A x\n+Definition: multitypeblockmatrix.hh:221\n+Dune::MultiTypeBlockMatrix::umtv\n+void umtv(const X &x, Y &y) const\n+y += A^T x\n+Definition: multitypeblockmatrix.hh:261\n+Dune::MultiTypeBlockMatrix_Solver::bsorb\n+static void bsorb(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n+const K &w)\n+Definition: multitypeblockmatrix.hh:547\n+Dune::MultiTypeBlockMatrix::operator*=\n+MultiTypeBlockMatrix & operator*=(const field_type &k)\n+vector space multiplication with scalar\n+Definition: multitypeblockmatrix.hh:141\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::IsDirectSolver\n-Definition: solvertype.hh:16\n-Dune::IsDirectSolver::value\n-@ value\n-Whether this is a direct solver.\n-Definition: solvertype.hh:24\n-Dune::StoresColumnCompressed\n-Definition: solvertype.hh:30\n-Dune::StoresColumnCompressed::value\n-@ value\n-whether the solver internally uses column compressed storage\n-Definition: solvertype.hh:36\n+Dune::operator<<\n+std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n+Send BlockVector to an output stream.\n+Definition: bvector.hh:590\n+Dune::MultiTypeBlockMatrix\n+A Matrix class to support different block types.\n+Definition: multitypeblockmatrix.hh:46\n+Dune::algmeta_itsteps::bsorb\n+static void bsorb(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:461\n+Dune::algmeta_itsteps::bsorf\n+static void bsorf(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:418\n+Dune::algmeta_itsteps::dbjac\n+static void dbjac(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:504\n+Dune::algmeta_itsteps::dbgs\n+static void dbgs(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:378\n+Dune::MultiTypeBlockMatrix_Solver\n+solver for MultiTypeBlockVector & MultiTypeBlockMatrix types\n+Definition: multitypeblockmatrix.hh:477\n+Dune::MultiTypeBlockMatrix_Solver_Col\n+part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types\n+Definition: multitypeblockmatrix.hh:449\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00050.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00050.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: basearray.hh File Reference\n+dune-istl: ildl.hh File Reference\n \n \n \n \n \n \n \n@@ -63,38 +63,55 @@\n
    \n \n
    \n
    \n
    \n \n-
    basearray.hh File Reference
    \n+Namespaces |\n+Functions
    \n+
    ildl.hh File Reference
    \n
    \n
    \n \n-

    Implements several basic array containers. \n+

    Incomplete LDL decomposition. \n More...

    \n-
    #include "assert.h"
    \n-#include <cmath>
    \n-#include <cstddef>
    \n-#include <memory>
    \n-#include <algorithm>
    \n-#include "istlexception.hh"
    \n-#include <dune/common/iteratorfacades.hh>
    \n+
    #include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include "ilu.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<class K , int m, int n>
    static void Dune::bildl_subtractBCT (const FieldMatrix< K, m, n > &B, const FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)
     
    template<class K >
    static void Dune::bildl_subtractBCT (const K &B, const K &CT, K &A, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
     
    template<class Matrix >
    static void Dune::bildl_subtractBCT (const Matrix &B, const Matrix &CT, Matrix &A, typename std::enable_if_t<!Dune::IsNumber< Matrix >::value > *sfinae=nullptr)
     
    template<class Matrix >
    void Dune::bildl_decompose (Matrix &A)
     compute ILDL decomposition of a symmetric matrix A More...
     
    template<class Matrix , class X , class Y >
    void Dune::bildl_backsolve (const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
     
    \n

    Detailed Description

    \n-

    Implements several basic array containers.

    \n+

    Incomplete LDL decomposition.

    \n+
    Author
    Martin Nolte
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,26 +4,46 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Namespaces\n-basearray.hh File Reference\n-Implements several basic array containers. More...\n-#include \"assert.h\"\n-#include \n-#include \n-#include \n-#include \n-#include \"istlexception.hh\"\n-#include \n+Namespaces | Functions\n+ildl.hh File Reference\n+Incomplete LDL decomposition. More...\n+#include \n+#include \n+#include \"ilu.hh\"\n Go_to_the_source_code_of_this_file.\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Functions\n+template\n+static void\u00a0Dune::bildl_subtractBCT (const FieldMatrix< K, m, n > &B, const\n+ FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)\n+\u00a0\n+template\n+static void\u00a0Dune::bildl_subtractBCT (const K &B, const K &CT, K &A, typename\n+ std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n+\u00a0\n+template\n+static void\u00a0Dune::bildl_subtractBCT (const Matrix &B, const Matrix &CT, Matrix\n+ &A, typename std::enable_if_t::value >\n+ *sfinae=nullptr)\n+\u00a0\n+template\n+ void\u00a0Dune::bildl_decompose (Matrix &A)\n+\u00a0 compute ILDL decomposition of a symmetric matrix A More...\n+\u00a0\n+template\n+ void\u00a0Dune::bildl_backsolve (const Matrix &A, X &v, const Y &d, bool\n+ isLowerTriangular=false)\n+\u00a0\n ***** Detailed Description *****\n-Implements several basic array containers.\n+Incomplete LDL decomposition.\n+ Author\n+ Martin Nolte\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00050_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00050_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: basearray.hh Source File\n+dune-istl: ildl.hh Source File\n \n \n \n \n \n \n \n@@ -62,427 +62,237 @@\n \n
    \n \n
    \n
    \n
    \n-
    basearray.hh
    \n+
    ildl.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n-
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_BASEARRAY_HH
    \n-
    6#define DUNE_ISTL_BASEARRAY_HH
    \n-
    7
    \n-
    8#include "assert.h"
    \n-
    9#include <cmath>
    \n-
    10#include <cstddef>
    \n-
    11#include <memory>
    \n-
    12#include <algorithm>
    \n-
    13
    \n-
    14#include "istlexception.hh"
    \n-
    15#include <dune/common/iteratorfacades.hh>
    \n-
    16
    \n-
    21namespace Dune {
    \n+
    3#ifndef DUNE_ISTL_ILDL_HH
    \n+
    4#define DUNE_ISTL_ILDL_HH
    \n+
    5
    \n+
    6#include <dune/common/scalarvectorview.hh>
    \n+
    7#include <dune/common/scalarmatrixview.hh>
    \n+
    8#include "ilu.hh"
    \n+
    9
    \n+
    17namespace Dune
    \n+
    18{
    \n+
    19
    \n+
    20 // bildl_subtractBCT
    \n+
    21 // -----------------
    \n
    22
    \n-
    24namespace Imp {
    \n-
    25
    \n-
    50 template<class B, class A=std::allocator<B> >
    \n-
    51 class base_array_unmanaged
    \n-
    52 {
    \n-
    53 public:
    \n-
    54
    \n-
    55 //===== type definitions and constants
    \n-
    56
    \n-
    58 typedef B member_type;
    \n-
    59
    \n-
    61 typedef A allocator_type;
    \n-
    62
    \n-
    64 typedef typename A::size_type size_type;
    \n-
    65
    \n-
    67 using reference = B&;
    \n-
    68
    \n-
    70 using const_reference = const B&;
    \n-
    71
    \n-
    72 //===== access to components
    \n+
    23 template< class K, int m, int n >
    \n+\n+
    25 {
    \n+
    26 for( int i = 0; i < m; ++i )
    \n+
    27 {
    \n+
    28 for( int j = 0; j < n; ++j )
    \n+
    29 {
    \n+
    30 for( int k = 0; k < n; ++k )
    \n+
    31 A[ i ][ j ] -= B[ i ][ k ] * CT[ j ][ k ];
    \n+
    32 }
    \n+
    33 }
    \n+
    34 }
    \n+
    35
    \n+
    36 template< class K >
    \n+
    37 inline static void bildl_subtractBCT ( const K &B, const K &CT, K &A,
    \n+
    38 typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr )
    \n+
    39 {
    \n+
    40 A -= B * CT;
    \n+
    41 }
    \n+
    42
    \n+
    43 template< class Matrix >
    \n+
    44 inline static void bildl_subtractBCT ( const Matrix &B, const Matrix &CT, Matrix &A,
    \n+
    45 typename std::enable_if_t<!Dune::IsNumber<Matrix>::value>* sfinae = nullptr )
    \n+
    46 {
    \n+
    47 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    48 {
    \n+
    49 auto &&A_i = *i;
    \n+
    50 auto &&B_i = B[ i.index() ];
    \n+
    51 const auto ikend = B_i.end();
    \n+
    52 for( auto j = A_i.begin(), jend = A_i.end(); j != jend; ++j )
    \n+
    53 {
    \n+
    54 auto &&A_ij = *j;
    \n+
    55 auto &&CT_j = CT[ j.index() ];
    \n+
    56 const auto jkend = CT_j.end();
    \n+
    57 for( auto ik = B_i.begin(), jk = CT_j.begin(); (ik != ikend) && (jk != jkend); )
    \n+
    58 {
    \n+
    59 if( ik.index() == jk.index() )
    \n+
    60 {
    \n+
    61 bildl_subtractBCT( *ik, *jk, A_ij );
    \n+
    62 ++ik; ++jk;
    \n+
    63 }
    \n+
    64 else if( ik.index() < jk.index() )
    \n+
    65 ++ik;
    \n+
    66 else
    \n+
    67 ++jk;
    \n+
    68 }
    \n+
    69 }
    \n+
    70 }
    \n+
    71 }
    \n+
    72
    \n
    73
    \n-
    75 reference operator[] (size_type i)
    \n-
    76 {
    \n-
    77#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    78 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
    \n-
    79#endif
    \n-
    80 return p[i];
    \n-
    81 }
    \n-
    82
    \n-
    84 const_reference operator[] (size_type i) const
    \n-
    85 {
    \n-
    86#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    87 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
    \n-
    88#endif
    \n-
    89 return p[i];
    \n-
    90 }
    \n-
    91
    \n-
    93 template<class T>
    \n-
    94 class RealIterator
    \n-
    95 : public RandomAccessIteratorFacade<RealIterator<T>, T>
    \n-
    96 {
    \n-
    97 public:
    \n-
    99 typedef typename std::remove_const<T>::type ValueType;
    \n-
    100
    \n-
    101 friend class RandomAccessIteratorFacade<RealIterator<const ValueType>, const ValueType>;
    \n-
    102 friend class RandomAccessIteratorFacade<RealIterator<ValueType>, ValueType>;
    \n-
    103 friend class RealIterator<const ValueType>;
    \n-
    104 friend class RealIterator<ValueType>;
    \n-
    105
    \n-
    107 RealIterator ()
    \n-
    108 : p(0), i(0)
    \n-
    109 {}
    \n-
    110
    \n-
    111 RealIterator (const B* _p, B* _i) : p(_p), i(_i)
    \n-
    112 { }
    \n-
    113
    \n-
    114 RealIterator(const RealIterator<ValueType>& it)
    \n-
    115 : p(it.p), i(it.i)
    \n-
    116 {}
    \n+
    74
    \n+
    75 // bildl_decompose
    \n+
    76 // ---------------
    \n+
    77
    \n+
    87 template< class Matrix >
    \n+
    88 inline void bildl_decompose ( Matrix &A )
    \n+
    89 {
    \n+
    90 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    91 {
    \n+
    92 auto &&A_i = *i;
    \n+
    93
    \n+
    94 auto ij = A_i.begin();
    \n+
    95 for( ; ij.index() < i.index(); ++ij )
    \n+
    96 {
    \n+
    97 auto &&A_ij = *ij;
    \n+
    98 auto &&A_j = A[ ij.index() ];
    \n+
    99
    \n+
    100 // store L_ij Dj in A_ij (note: for k < i: A_kj = L_kj)
    \n+
    101 // L_ij Dj = A_ij - \\sum_{k < j} (L_ik D_k) L_jk^T
    \n+
    102 auto ik = A_i.begin();
    \n+
    103 auto jk = A_j.begin();
    \n+
    104 while( (ik != ij) && (jk.index() < ij.index()) )
    \n+
    105 {
    \n+
    106 if( ik.index() == jk.index() )
    \n+
    107 {
    \n+
    108 bildl_subtractBCT(*ik, *jk, A_ij);
    \n+
    109 ++ik; ++jk;
    \n+
    110 }
    \n+
    111 else if( ik.index() < jk.index() )
    \n+
    112 ++ik;
    \n+
    113 else
    \n+
    114 ++jk;
    \n+
    115 }
    \n+
    116 }
    \n
    117
    \n-
    119 size_type index () const
    \n-
    120 {
    \n-
    121 return i-p;
    \n-
    122 }
    \n-
    123
    \n-
    125 bool equals (const RealIterator<ValueType>& other) const
    \n-
    126 {
    \n-
    127 assert(other.p==p);
    \n-
    128 return i==other.i;
    \n-
    129 }
    \n-
    130
    \n-
    132 bool equals (const RealIterator<const ValueType>& other) const
    \n-
    133 {
    \n-
    134 assert(other.p==p);
    \n-
    135 return i==other.i;
    \n-
    136 }
    \n-
    137
    \n-
    138 std::ptrdiff_t distanceTo(const RealIterator& o) const
    \n-
    139 {
    \n-
    140 return o.i-i;
    \n-
    141 }
    \n+
    118 if( ij.index() != i.index() )
    \n+
    119 DUNE_THROW( ISTLError, "diagonal entry missing" );
    \n+
    120
    \n+
    121 // update diagonal and multiply A_ij by D_j^{-1}
    \n+
    122 auto &&A_ii = *ij;
    \n+
    123 for( auto ik = A_i.begin(); ik != ij; ++ik )
    \n+
    124 {
    \n+
    125 auto &&A_ik = *ik;
    \n+
    126 const auto &A_k = A[ ik.index() ];
    \n+
    127
    \n+
    128 auto B = A_ik;
    \n+
    129 Impl::asMatrix(A_ik).rightmultiply( Impl::asMatrix(*A_k.find( ik.index() )) );
    \n+
    130 bildl_subtractBCT( B, A_ik, A_ii );
    \n+
    131 }
    \n+
    132 try
    \n+
    133 {
    \n+
    134 Impl::asMatrix(A_ii).invert();
    \n+
    135 }
    \n+
    136 catch( const Dune::FMatrixError &e )
    \n+
    137 {
    \n+
    138 DUNE_THROW( MatrixBlockError, "ILDL failed to invert matrix block A[" << i.index() << "][" << ij.index() << "]" << e.what(); th__ex.r = i.index(); th__ex.c = ij.index() );
    \n+
    139 }
    \n+
    140 }
    \n+
    141 }
    \n
    142
    \n-
    143 private:
    \n-
    145 void increment()
    \n-
    146 {
    \n-
    147 ++i;
    \n-
    148 }
    \n-
    149
    \n-
    151 void decrement()
    \n-
    152 {
    \n-
    153 --i;
    \n-
    154 }
    \n-
    155
    \n-
    156 // Needed for operator[] of the iterator
    \n-
    157 reference elementAt (std::ptrdiff_t offset) const
    \n-
    158 {
    \n-
    159 return *(i+offset);
    \n+
    143
    \n+
    144
    \n+
    145 // bildl_backsolve
    \n+
    146 // ---------------
    \n+
    147
    \n+
    148 template< class Matrix, class X, class Y >
    \n+
    149 inline void bildl_backsolve ( const Matrix &A, X &v, const Y &d, bool isLowerTriangular = false )
    \n+
    150 {
    \n+
    151 // solve L v = d, note: Lii = I
    \n+
    152 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    153 {
    \n+
    154 const auto &A_i = *i;
    \n+
    155 v[ i.index() ] = d[ i.index() ];
    \n+
    156 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )
    \n+
    157 {
    \n+
    158 auto&& vi = Impl::asVector( v[ i.index() ] );
    \n+
    159 Impl::asMatrix(*ij).mmv(Impl::asVector( v[ ij.index() ] ), vi);
    \n
    160 }
    \n-
    161
    \n-
    163 reference dereference () const
    \n-
    164 {
    \n-
    165 return *i;
    \n-
    166 }
    \n-
    167
    \n-
    168 void advance(std::ptrdiff_t d)
    \n+
    161 }
    \n+
    162
    \n+
    163 // solve D w = v, note: diagonal stores Dii^{-1}
    \n+
    164 if( isLowerTriangular )
    \n+
    165 {
    \n+
    166 // The matrix is lower triangular, so the diagonal entry is the
    \n+
    167 // last one in each row.
    \n+
    168 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n
    169 {
    \n-
    170 i+=d;
    \n-
    171 }
    \n-
    172
    \n-
    173 const B* p;
    \n-
    174 B* i;
    \n-
    175 };
    \n-
    176
    \n-
    178 typedef RealIterator<B> iterator;
    \n-
    179
    \n-
    180
    \n-
    182 iterator begin ()
    \n-
    183 {
    \n-
    184 return iterator(p,p);
    \n-
    185 }
    \n-
    186
    \n-
    188 iterator end ()
    \n-
    189 {
    \n-
    190 return iterator(p,p+n);
    \n-
    191 }
    \n-
    192
    \n-
    195 iterator beforeEnd ()
    \n-
    196 {
    \n-
    197 return iterator(p,p+n-1);
    \n-
    198 }
    \n-
    199
    \n-
    202 iterator beforeBegin ()
    \n-
    203 {
    \n-
    204 return iterator(p,p-1);
    \n+
    170 const auto &A_i = *i;
    \n+
    171 const auto ii = A_i.beforeEnd();
    \n+
    172 assert( ii.index() == i.index() );
    \n+
    173 // We need to be careful here: Directly using
    \n+
    174 // auto rhs = Impl::asVector(v[ i.index() ]);
    \n+
    175 // is not OK in case this is a proxy. Hence
    \n+
    176 // we first have to copy the value. Notice that
    \n+
    177 // this is still not OK, if the vector type itself returns
    \n+
    178 // proxy references.
    \n+
    179 auto rhsValue = v[ i.index() ];
    \n+
    180 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    181 auto&& vi = Impl::asVector( v[ i.index() ] );
    \n+
    182 Impl::asMatrix(*ii).mv(rhs, vi);
    \n+
    183 }
    \n+
    184 }
    \n+
    185 else
    \n+
    186 {
    \n+
    187 // Without assumptions on the sparsity pattern we have to search
    \n+
    188 // for the diagonal entry in each row.
    \n+
    189 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    190 {
    \n+
    191 const auto &A_i = *i;
    \n+
    192 const auto ii = A_i.find( i.index() );
    \n+
    193 assert( ii.index() == i.index() );
    \n+
    194 // We need to be careful here: Directly using
    \n+
    195 // auto rhs = Impl::asVector(v[ i.index() ]);
    \n+
    196 // is not OK in case this is a proxy. Hence
    \n+
    197 // we first have to copy the value. Notice that
    \n+
    198 // this is still not OK, if the vector type itself returns
    \n+
    199 // proxy references.
    \n+
    200 auto rhsValue = v[ i.index() ];
    \n+
    201 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    202 auto&& vi = Impl::asVector( v[ i.index() ] );
    \n+
    203 Impl::asMatrix(*ii).mv(rhs, vi);
    \n+
    204 }
    \n
    205 }
    \n
    206
    \n-
    208 iterator find (size_type i)
    \n-
    209 {
    \n-
    210 return iterator(p,p+std::min(i,n));
    \n-
    211 }
    \n-
    212
    \n-
    214 typedef RealIterator<const B> const_iterator;
    \n-
    215
    \n-
    217 const_iterator begin () const
    \n-
    218 {
    \n-
    219 return const_iterator(p,p+0);
    \n-
    220 }
    \n+
    207 // solve L^T v = w, note: only L is stored
    \n+
    208 // note: we perform the operation column-wise from right to left
    \n+
    209 for( auto i = A.beforeEnd(), iend = A.beforeBegin(); i != iend; --i )
    \n+
    210 {
    \n+
    211 const auto &A_i = *i;
    \n+
    212 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )
    \n+
    213 {
    \n+
    214 auto&& vij = Impl::asVector( v[ ij.index() ] );
    \n+
    215 Impl::asMatrix(*ij).mmtv(Impl::asVector( v[ i.index() ] ), vij);
    \n+
    216 }
    \n+
    217 }
    \n+
    218 }
    \n+
    219
    \n+
    220} // namespace Dune
    \n
    221
    \n-
    223 const_iterator end () const
    \n-
    224 {
    \n-
    225 return const_iterator(p,p+n);
    \n-
    226 }
    \n-
    227
    \n-
    230 const_iterator beforeEnd () const
    \n-
    231 {
    \n-
    232 return const_iterator(p,p+n-1);
    \n-
    233 }
    \n-
    234
    \n-
    237 const_iterator beforeBegin () const
    \n-
    238 {
    \n-
    239 return const_iterator(p,p-1);
    \n-
    240 }
    \n-
    241
    \n-
    243 const_iterator find (size_type i) const
    \n-
    244 {
    \n-
    245 return const_iterator(p,p+std::min(i,n));
    \n-
    246 }
    \n-
    247
    \n-
    248
    \n-
    249 //===== sizes
    \n-
    250
    \n-
    252 size_type size () const
    \n-
    253 {
    \n-
    254 return n;
    \n-
    255 }
    \n-
    256
    \n-
    258 const B* data() const
    \n-
    259 {
    \n-
    260 return p;
    \n-
    261 }
    \n-
    262
    \n-
    264 B* data()
    \n-
    265 {
    \n-
    266 return p;
    \n-
    267 }
    \n-
    268
    \n-
    269 protected:
    \n-
    271 base_array_unmanaged ()
    \n-
    272 : n(0), p(0)
    \n-
    273 {}
    \n-
    275 base_array_unmanaged (size_type n_, B* p_)
    \n-
    276 : n(n_), p(p_)
    \n-
    277 {}
    \n-
    278 size_type n; // number of elements in array
    \n-
    279 B *p; // pointer to dynamically allocated built-in array
    \n-
    280 };
    \n-
    281
    \n-
    282
    \n-
    283
    \n-
    305 template<class B, class A=std::allocator<B> >
    \n-
    306 class compressed_base_array_unmanaged
    \n-
    307 {
    \n-
    308 public:
    \n-
    309
    \n-
    310 //===== type definitions and constants
    \n-
    311
    \n-
    313 typedef B member_type;
    \n-
    314
    \n-
    316 typedef A allocator_type;
    \n-
    317
    \n-
    319 typedef typename A::size_type size_type;
    \n-
    320
    \n-
    322 using reference = B&;
    \n-
    323
    \n-
    325 using const_reference = const B&;
    \n-
    326
    \n-
    327 //===== access to components
    \n-
    328
    \n-
    330 reference operator[] (size_type i)
    \n-
    331 {
    \n-
    332 const size_type* lb = std::lower_bound(j, j+n, i);
    \n-
    333 if (lb == j+n || *lb != i)
    \n-
    334 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
    \n-
    335 return p[lb-j];
    \n-
    336 }
    \n-
    337
    \n-
    339 const_reference operator[] (size_type i) const
    \n-
    340 {
    \n-
    341 const size_type* lb = std::lower_bound(j, j+n, i);
    \n-
    342 if (lb == j+n || *lb != i)
    \n-
    343 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
    \n-
    344 return p[lb-j];
    \n-
    345 }
    \n-
    346
    \n-
    348 template<class T>
    \n-
    349 class RealIterator
    \n-
    350 : public BidirectionalIteratorFacade<RealIterator<T>, T>
    \n-
    351 {
    \n-
    352 public:
    \n-
    354 typedef typename std::remove_const<T>::type ValueType;
    \n-
    355
    \n-
    356 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
    \n-
    357 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
    \n-
    358 friend class RealIterator<const ValueType>;
    \n-
    359 friend class RealIterator<ValueType>;
    \n-
    360
    \n-
    362 RealIterator ()
    \n-
    363 : p(0), j(0), i(0)
    \n-
    364 {}
    \n-
    365
    \n-
    367 RealIterator (B* _p, size_type* _j, size_type _i)
    \n-
    368 : p(_p), j(_j), i(_i)
    \n-
    369 { }
    \n-
    370
    \n-
    374 RealIterator(const RealIterator<ValueType>& it)
    \n-
    375 : p(it.p), j(it.j), i(it.i)
    \n-
    376 {}
    \n-
    377
    \n-
    378
    \n-
    380 bool equals (const RealIterator<ValueType>& it) const
    \n-
    381 {
    \n-
    382 assert(p==it.p);
    \n-
    383 return (i)==(it.i);
    \n-
    384 }
    \n-
    385
    \n-
    387 bool equals (const RealIterator<const ValueType>& it) const
    \n-
    388 {
    \n-
    389 assert(p==it.p);
    \n-
    390 return (i)==(it.i);
    \n-
    391 }
    \n-
    392
    \n-
    393
    \n-
    395 size_type index () const
    \n-
    396 {
    \n-
    397 return j[i];
    \n-
    398 }
    \n-
    399
    \n-
    401 void setindex (size_type k)
    \n-
    402 {
    \n-
    403 return j[i] = k;
    \n-
    404 }
    \n-
    405
    \n-
    413 size_type offset () const
    \n-
    414 {
    \n-
    415 return i;
    \n-
    416 }
    \n-
    417
    \n-
    418 private:
    \n-
    420 void increment()
    \n-
    421 {
    \n-
    422 ++i;
    \n-
    423 }
    \n-
    424
    \n-
    426 void decrement()
    \n-
    427 {
    \n-
    428 --i;
    \n-
    429 }
    \n-
    430
    \n-
    432 reference dereference () const
    \n-
    433 {
    \n-
    434 return p[i];
    \n-
    435 }
    \n-
    436
    \n-
    437 B* p;
    \n-
    438 size_type* j;
    \n-
    439 size_type i;
    \n-
    440 };
    \n-
    441
    \n-
    443 typedef RealIterator<B> iterator;
    \n-
    444
    \n-
    446 iterator begin ()
    \n-
    447 {
    \n-
    448 return iterator(p,j,0);
    \n-
    449 }
    \n-
    450
    \n-
    452 iterator end ()
    \n-
    453 {
    \n-
    454 return iterator(p,j,n);
    \n-
    455 }
    \n-
    456
    \n-
    459 iterator beforeEnd ()
    \n-
    460 {
    \n-
    461 return iterator(p,j,n-1);
    \n-
    462 }
    \n-
    463
    \n-
    466 iterator beforeBegin ()
    \n-
    467 {
    \n-
    468 return iterator(p,j,-1);
    \n-
    469 }
    \n-
    470
    \n-
    472 iterator find (size_type i)
    \n-
    473 {
    \n-
    474 const size_type* lb = std::lower_bound(j, j+n, i);
    \n-
    475 return (lb != j+n && *lb == i)
    \n-
    476 ? iterator(p,j,lb-j)
    \n-
    477 : end();
    \n-
    478 }
    \n-
    479
    \n-
    481 typedef RealIterator<const B> const_iterator;
    \n-
    482
    \n-
    484 const_iterator begin () const
    \n-
    485 {
    \n-
    486 return const_iterator(p,j,0);
    \n-
    487 }
    \n-
    488
    \n-
    490 const_iterator end () const
    \n-
    491 {
    \n-
    492 return const_iterator(p,j,n);
    \n-
    493 }
    \n-
    494
    \n-
    497 const_iterator beforeEnd () const
    \n-
    498 {
    \n-
    499 return const_iterator(p,j,n-1);
    \n-
    500 }
    \n-
    501
    \n-
    504 const_iterator beforeBegin () const
    \n-
    505 {
    \n-
    506 return const_iterator(p,j,-1);
    \n-
    507 }
    \n-
    508
    \n-
    510 const_iterator find (size_type i) const
    \n-
    511 {
    \n-
    512 const size_type* lb = std::lower_bound(j, j+n, i);
    \n-
    513 return (lb != j+n && *lb == i)
    \n-
    514 ? const_iterator(p,j,lb-j)
    \n-
    515 : end();
    \n-
    516 }
    \n-
    517
    \n-
    518 //===== sizes
    \n-
    519
    \n-
    521 size_type size () const
    \n-
    522 {
    \n-
    523 return n;
    \n-
    524 }
    \n-
    525
    \n-
    526 protected:
    \n-
    528 compressed_base_array_unmanaged ()
    \n-
    529 : n(0), p(0), j(0)
    \n-
    530 {}
    \n-
    531
    \n-
    532 size_type n; // number of elements in array
    \n-
    533 B *p; // pointer to dynamically allocated built-in array
    \n-
    534 size_type* j; // the index set
    \n-
    535 };
    \n-
    536
    \n-
    537} // end namespace Imp
    \n-
    538
    \n-
    539} // end namespace
    \n-
    540
    \n-
    541#endif
    \n-\n+
    222#endif // #ifndef DUNE_ISTL_ILDL_HH
    \n+
    The incomplete LU factorization kernels.
    \n
    Definition: allocator.hh:11
    \n+
    void bildl_decompose(Matrix &A)
    compute ILDL decomposition of a symmetric matrix A
    Definition: ildl.hh:88
    \n+
    void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
    Definition: ildl.hh:149
    \n+
    static void bildl_subtractBCT(const FieldMatrix< K, m, n > &B, const FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)
    Definition: ildl.hh:24
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    Error when performing an operation on a matrix block.
    Definition: istlexception.hh:52
    \n+
    int r
    Definition: istlexception.hh:54
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    RowIterator beforeBegin()
    Definition: matrix.hh:634
    \n+
    RowIterator beforeEnd()
    Definition: matrix.hh:627
    \n+
    RowIterator end()
    Get iterator to one beyond last row.
    Definition: matrix.hh:620
    \n+
    RowIterator begin()
    Get iterator to first row.
    Definition: matrix.hh:614
    \n+
    Definition: matrixutils.hh:27
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,428 +4,271 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-basearray.hh\n+ildl.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n- 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_BASEARRAY_HH\n- 6#define DUNE_ISTL_BASEARRAY_HH\n- 7\n- 8#include \"assert.h\"\n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13\n- 14#include \"istlexception.hh\"\n- 15#include \n- 16\n- 21namespace Dune {\n+ 3#ifndef DUNE_ISTL_ILDL_HH\n+ 4#define DUNE_ISTL_ILDL_HH\n+ 5\n+ 6#include \n+ 7#include \n+ 8#include \"ilu.hh\"\n+ 9\n+ 17namespace Dune\n+ 18{\n+ 19\n+ 20 // bildl_subtractBCT\n+ 21 // -----------------\n 22\n- 24namespace Imp {\n- 25\n- 50 template >\n- 51 class base_array_unmanaged\n- 52 {\n- 53 public:\n- 54\n- 55 //===== type definitions and constants\n- 56\n- 58 typedef B member_type;\n- 59\n- 61 typedef A allocator_type;\n- 62\n- 64 typedef typename A::size_type size_type;\n- 65\n- 67 using reference = B&;\n- 68\n- 70 using const_reference = const B&;\n- 71\n- 72 //===== access to components\n+ 23 template< class K, int m, int n >\n+24 inline static void bildl_subtractBCT ( const FieldMatrix<_K,_m,_n_> &B,\n+const FieldMatrix<_K,_m,_n_> &CT, FieldMatrix<_K,_m,_n_> &A )\n+ 25 {\n+ 26 for( int i = 0; i < m; ++i )\n+ 27 {\n+ 28 for( int j = 0; j < n; ++j )\n+ 29 {\n+ 30 for( int k = 0; k < n; ++k )\n+ 31 A[ i ][ j ] -= B[ i ][ k ] * CT[ j ][ k ];\n+ 32 }\n+ 33 }\n+ 34 }\n+ 35\n+ 36 template< class K >\n+37 inline static void bildl_subtractBCT ( const K &B, const K &CT, K &A,\n+ 38 typename std::enable_if_t::value>* sfinae = nullptr )\n+ 39 {\n+ 40 A -= B * CT;\n+ 41 }\n+ 42\n+ 43 template< class Matrix >\n+44 inline static void bildl_subtractBCT ( const Matrix &B, const Matrix &CT,\n+Matrix &A,\n+ 45 typename std::enable_if_t::value>* sfinae = nullptr\n+)\n+ 46 {\n+ 47 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 48 {\n+ 49 auto &&A_i = *i;\n+ 50 auto &&B_i = B[ i.index() ];\n+ 51 const auto ikend = B_i.end();\n+ 52 for( auto j = A_i.begin(), jend = A_i.end(); j != jend; ++j )\n+ 53 {\n+ 54 auto &&A_ij = *j;\n+ 55 auto &&CT_j = CT[ j.index() ];\n+ 56 const auto jkend = CT_j.end();\n+ 57 for( auto ik = B_i.begin(), jk = CT_j.begin(); (ik != ikend) && (jk !=\n+jkend); )\n+ 58 {\n+ 59 if( ik.index() == jk.index() )\n+ 60 {\n+ 61 bildl_subtractBCT( *ik, *jk, A_ij );\n+ 62 ++ik; ++jk;\n+ 63 }\n+ 64 else if( ik.index() < jk.index() )\n+ 65 ++ik;\n+ 66 else\n+ 67 ++jk;\n+ 68 }\n+ 69 }\n+ 70 }\n+ 71 }\n+ 72\n 73\n- 75 reference operator[] (size_type i)\n- 76 {\n- 77#ifdef DUNE_ISTL_WITH_CHECKING\n- 78 if (i>=n) DUNE_THROW(ISTLError,\"index out of range\");\n- 79#endif\n- 80 return p[i];\n- 81 }\n- 82\n- 84 const_reference operator[] (size_type i) const\n- 85 {\n- 86#ifdef DUNE_ISTL_WITH_CHECKING\n- 87 if (i>=n) DUNE_THROW(ISTLError,\"index out of range\");\n- 88#endif\n- 89 return p[i];\n- 90 }\n- 91\n- 93 template\n- 94 class RealIterator\n- 95 : public RandomAccessIteratorFacade, T>\n+ 74\n+ 75 // bildl_decompose\n+ 76 // ---------------\n+ 77\n+ 87 template< class Matrix >\n+88 inline void bildl_decompose ( Matrix &A )\n+ 89 {\n+ 90 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 91 {\n+ 92 auto &&A_i = *i;\n+ 93\n+ 94 auto ij = A_i.begin();\n+ 95 for( ; ij.index() < i.index(); ++ij )\n 96 {\n- 97 public:\n- 99 typedef typename std::remove_const::type ValueType;\n- 100\n- 101 friend class RandomAccessIteratorFacade,\n-const ValueType>;\n- 102 friend class RandomAccessIteratorFacade,\n-ValueType>;\n- 103 friend class RealIterator;\n- 104 friend class RealIterator;\n- 105\n- 107 RealIterator ()\n- 108 : p(0), i(0)\n- 109 {}\n- 110\n- 111 RealIterator (const B* _p, B* _i) : p(_p), i(_i)\n- 112 { }\n- 113\n- 114 RealIterator(const RealIterator& it)\n- 115 : p(it.p), i(it.i)\n- 116 {}\n+ 97 auto &&A_ij = *ij;\n+ 98 auto &&A_j = A[ ij.index() ];\n+ 99\n+ 100 // store L_ij Dj in A_ij (note: for k < i: A_kj = L_kj)\n+ 101 // L_ij Dj = A_ij - \\sum_{k < j} (L_ik D_k) L_jk^T\n+ 102 auto ik = A_i.begin();\n+ 103 auto jk = A_j.begin();\n+ 104 while( (ik != ij) && (jk.index() < ij.index()) )\n+ 105 {\n+ 106 if( ik.index() == jk.index() )\n+ 107 {\n+ 108 bildl_subtractBCT(*ik, *jk, A_ij);\n+ 109 ++ik; ++jk;\n+ 110 }\n+ 111 else if( ik.index() < jk.index() )\n+ 112 ++ik;\n+ 113 else\n+ 114 ++jk;\n+ 115 }\n+ 116 }\n 117\n- 119 size_type index () const\n- 120 {\n- 121 return i-p;\n- 122 }\n- 123\n- 125 bool equals (const RealIterator& other) const\n- 126 {\n- 127 assert(other.p==p);\n- 128 return i==other.i;\n- 129 }\n- 130\n- 132 bool equals (const RealIterator& other) const\n+ 118 if( ij.index() != i.index() )\n+ 119 DUNE_THROW( ISTLError, \"diagonal entry missing\" );\n+ 120\n+ 121 // update diagonal and multiply A_ij by D_j^{-1}\n+ 122 auto &&A_ii = *ij;\n+ 123 for( auto ik = A_i.begin(); ik != ij; ++ik )\n+ 124 {\n+ 125 auto &&A_ik = *ik;\n+ 126 const auto &A_k = A[ ik.index() ];\n+ 127\n+ 128 auto B = A_ik;\n+ 129 Impl::asMatrix(A_ik).rightmultiply( Impl::asMatrix(*A_k.find( ik.index()\n+)) );\n+ 130 bildl_subtractBCT( B, A_ik, A_ii );\n+ 131 }\n+ 132 try\n 133 {\n- 134 assert(other.p==p);\n- 135 return i==other.i;\n- 136 }\n- 137\n- 138 std::ptrdiff_t distanceTo(const RealIterator& o) const\n- 139 {\n- 140 return o.i-i;\n+ 134 Impl::asMatrix(A_ii).invert();\n+ 135 }\n+ 136 catch( const Dune::FMatrixError &e )\n+ 137 {\n+ 138 DUNE_THROW( MatrixBlockError, \"ILDL failed to invert matrix block A[\" <<\n+i.index() << \"][\" << ij.index() << \"]\" << e.what(); th__ex.r = i.index();\n+th__ex.c = ij.index() );\n+ 139 }\n+ 140 }\n 141 }\n 142\n- 143 private:\n- 145 void increment()\n- 146 {\n- 147 ++i;\n- 148 }\n- 149\n- 151 void decrement()\n- 152 {\n- 153 --i;\n- 154 }\n- 155\n- 156 // Needed for operator[] of the iterator\n- 157 reference elementAt (std::ptrdiff_t offset) const\n- 158 {\n- 159 return *(i+offset);\n+ 143\n+ 144\n+ 145 // bildl_backsolve\n+ 146 // ---------------\n+ 147\n+ 148 template< class Matrix, class X, class Y >\n+149 inline void bildl_backsolve ( const Matrix &A, X &v, const Y &d, bool\n+isLowerTriangular = false )\n+ 150 {\n+ 151 // solve L v = d, note: Lii = I\n+ 152 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 153 {\n+ 154 const auto &A_i = *i;\n+ 155 v[ i.index() ] = d[ i.index() ];\n+ 156 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )\n+ 157 {\n+ 158 auto&& vi = Impl::asVector( v[ i.index() ] );\n+ 159 Impl::asMatrix(*ij).mmv(Impl::asVector( v[ ij.index() ] ), vi);\n 160 }\n- 161\n- 163 reference dereference () const\n- 164 {\n- 165 return *i;\n- 166 }\n- 167\n- 168 void advance(std::ptrdiff_t d)\n+ 161 }\n+ 162\n+ 163 // solve D w = v, note: diagonal stores Dii^{-1}\n+ 164 if( isLowerTriangular )\n+ 165 {\n+ 166 // The matrix is lower triangular, so the diagonal entry is the\n+ 167 // last one in each row.\n+ 168 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n 169 {\n- 170 i+=d;\n- 171 }\n- 172\n- 173 const B* p;\n- 174 B* i;\n- 175 };\n- 176\n- 178 typedef RealIterator iterator;\n- 179\n- 180\n- 182 iterator begin ()\n- 183 {\n- 184 return iterator(p,p);\n- 185 }\n- 186\n- 188 iterator end ()\n- 189 {\n- 190 return iterator(p,p+n);\n- 191 }\n- 192\n- 195 iterator beforeEnd ()\n- 196 {\n- 197 return iterator(p,p+n-1);\n- 198 }\n- 199\n- 202 iterator beforeBegin ()\n- 203 {\n- 204 return iterator(p,p-1);\n+ 170 const auto &A_i = *i;\n+ 171 const auto ii = A_i.beforeEnd();\n+ 172 assert( ii.index() == i.index() );\n+ 173 // We need to be careful here: Directly using\n+ 174 // auto rhs = Impl::asVector(v[ i.index() ]);\n+ 175 // is not OK in case this is a proxy. Hence\n+ 176 // we first have to copy the value. Notice that\n+ 177 // this is still not OK, if the vector type itself returns\n+ 178 // proxy references.\n+ 179 auto rhsValue = v[ i.index() ];\n+ 180 auto&& rhs = Impl::asVector(rhsValue);\n+ 181 auto&& vi = Impl::asVector( v[ i.index() ] );\n+ 182 Impl::asMatrix(*ii).mv(rhs, vi);\n+ 183 }\n+ 184 }\n+ 185 else\n+ 186 {\n+ 187 // Without assumptions on the sparsity pattern we have to search\n+ 188 // for the diagonal entry in each row.\n+ 189 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 190 {\n+ 191 const auto &A_i = *i;\n+ 192 const auto ii = A_i.find( i.index() );\n+ 193 assert( ii.index() == i.index() );\n+ 194 // We need to be careful here: Directly using\n+ 195 // auto rhs = Impl::asVector(v[ i.index() ]);\n+ 196 // is not OK in case this is a proxy. Hence\n+ 197 // we first have to copy the value. Notice that\n+ 198 // this is still not OK, if the vector type itself returns\n+ 199 // proxy references.\n+ 200 auto rhsValue = v[ i.index() ];\n+ 201 auto&& rhs = Impl::asVector(rhsValue);\n+ 202 auto&& vi = Impl::asVector( v[ i.index() ] );\n+ 203 Impl::asMatrix(*ii).mv(rhs, vi);\n+ 204 }\n 205 }\n 206\n- 208 iterator find (size_type i)\n- 209 {\n- 210 return iterator(p,p+std::min(i,n));\n- 211 }\n- 212\n- 214 typedef RealIterator const_iterator;\n- 215\n- 217 const_iterator begin () const\n- 218 {\n- 219 return const_iterator(p,p+0);\n- 220 }\n+ 207 // solve L^T v = w, note: only L is stored\n+ 208 // note: we perform the operation column-wise from right to left\n+ 209 for( auto i = A.beforeEnd(), iend = A.beforeBegin(); i != iend; --i )\n+ 210 {\n+ 211 const auto &A_i = *i;\n+ 212 for( auto ij = A_i.begin(); ij.index() < i.index(); ++ij )\n+ 213 {\n+ 214 auto&& vij = Impl::asVector( v[ ij.index() ] );\n+ 215 Impl::asMatrix(*ij).mmtv(Impl::asVector( v[ i.index() ] ), vij);\n+ 216 }\n+ 217 }\n+ 218 }\n+ 219\n+ 220} // namespace Dune\n 221\n- 223 const_iterator end () const\n- 224 {\n- 225 return const_iterator(p,p+n);\n- 226 }\n- 227\n- 230 const_iterator beforeEnd () const\n- 231 {\n- 232 return const_iterator(p,p+n-1);\n- 233 }\n- 234\n- 237 const_iterator beforeBegin () const\n- 238 {\n- 239 return const_iterator(p,p-1);\n- 240 }\n- 241\n- 243 const_iterator find (size_type i) const\n- 244 {\n- 245 return const_iterator(p,p+std::min(i,n));\n- 246 }\n- 247\n- 248\n- 249 //===== sizes\n- 250\n- 252 size_type size () const\n- 253 {\n- 254 return n;\n- 255 }\n- 256\n- 258 const B* data() const\n- 259 {\n- 260 return p;\n- 261 }\n- 262\n- 264 B* data()\n- 265 {\n- 266 return p;\n- 267 }\n- 268\n- 269 protected:\n- 271 base_array_unmanaged ()\n- 272 : n(0), p(0)\n- 273 {}\n- 275 base_array_unmanaged (size_type n_, B* p_)\n- 276 : n(n_), p(p_)\n- 277 {}\n- 278 size_type n; // number of elements in array\n- 279 B *p; // pointer to dynamically allocated built-in array\n- 280 };\n- 281\n- 282\n- 283\n- 305 template >\n- 306 class compressed_base_array_unmanaged\n- 307 {\n- 308 public:\n- 309\n- 310 //===== type definitions and constants\n- 311\n- 313 typedef B member_type;\n- 314\n- 316 typedef A allocator_type;\n- 317\n- 319 typedef typename A::size_type size_type;\n- 320\n- 322 using reference = B&;\n- 323\n- 325 using const_reference = const B&;\n- 326\n- 327 //===== access to components\n- 328\n- 330 reference operator[] (size_type i)\n- 331 {\n- 332 const size_type* lb = std::lower_bound(j, j+n, i);\n- 333 if (lb == j+n || *lb != i)\n- 334 DUNE_THROW(ISTLError,\"index \"<\n- 349 class RealIterator\n- 350 : public BidirectionalIteratorFacade, T>\n- 351 {\n- 352 public:\n- 354 typedef typename std::remove_const::type ValueType;\n- 355\n- 356 friend class BidirectionalIteratorFacade,\n-const ValueType>;\n- 357 friend class BidirectionalIteratorFacade,\n-ValueType>;\n- 358 friend class RealIterator;\n- 359 friend class RealIterator;\n- 360\n- 362 RealIterator ()\n- 363 : p(0), j(0), i(0)\n- 364 {}\n- 365\n- 367 RealIterator (B* _p, size_type* _j, size_type _i)\n- 368 : p(_p), j(_j), i(_i)\n- 369 { }\n- 370\n- 374 RealIterator(const RealIterator& it)\n- 375 : p(it.p), j(it.j), i(it.i)\n- 376 {}\n- 377\n- 378\n- 380 bool equals (const RealIterator& it) const\n- 381 {\n- 382 assert(p==it.p);\n- 383 return (i)==(it.i);\n- 384 }\n- 385\n- 387 bool equals (const RealIterator& it) const\n- 388 {\n- 389 assert(p==it.p);\n- 390 return (i)==(it.i);\n- 391 }\n- 392\n- 393\n- 395 size_type index () const\n- 396 {\n- 397 return j[i];\n- 398 }\n- 399\n- 401 void setindex (size_type k)\n- 402 {\n- 403 return j[i] = k;\n- 404 }\n- 405\n- 413 size_type offset () const\n- 414 {\n- 415 return i;\n- 416 }\n- 417\n- 418 private:\n- 420 void increment()\n- 421 {\n- 422 ++i;\n- 423 }\n- 424\n- 426 void decrement()\n- 427 {\n- 428 --i;\n- 429 }\n- 430\n- 432 reference dereference () const\n- 433 {\n- 434 return p[i];\n- 435 }\n- 436\n- 437 B* p;\n- 438 size_type* j;\n- 439 size_type i;\n- 440 };\n- 441\n- 443 typedef RealIterator iterator;\n- 444\n- 446 iterator begin ()\n- 447 {\n- 448 return iterator(p,j,0);\n- 449 }\n- 450\n- 452 iterator end ()\n- 453 {\n- 454 return iterator(p,j,n);\n- 455 }\n- 456\n- 459 iterator beforeEnd ()\n- 460 {\n- 461 return iterator(p,j,n-1);\n- 462 }\n- 463\n- 466 iterator beforeBegin ()\n- 467 {\n- 468 return iterator(p,j,-1);\n- 469 }\n- 470\n- 472 iterator find (size_type i)\n- 473 {\n- 474 const size_type* lb = std::lower_bound(j, j+n, i);\n- 475 return (lb != j+n && *lb == i)\n- 476 ? iterator(p,j,lb-j)\n- 477 : end();\n- 478 }\n- 479\n- 481 typedef RealIterator const_iterator;\n- 482\n- 484 const_iterator begin () const\n- 485 {\n- 486 return const_iterator(p,j,0);\n- 487 }\n- 488\n- 490 const_iterator end () const\n- 491 {\n- 492 return const_iterator(p,j,n);\n- 493 }\n- 494\n- 497 const_iterator beforeEnd () const\n- 498 {\n- 499 return const_iterator(p,j,n-1);\n- 500 }\n- 501\n- 504 const_iterator beforeBegin () const\n- 505 {\n- 506 return const_iterator(p,j,-1);\n- 507 }\n- 508\n- 510 const_iterator find (size_type i) const\n- 511 {\n- 512 const size_type* lb = std::lower_bound(j, j+n, i);\n- 513 return (lb != j+n && *lb == i)\n- 514 ? const_iterator(p,j,lb-j)\n- 515 : end();\n- 516 }\n- 517\n- 518 //===== sizes\n- 519\n- 521 size_type size () const\n- 522 {\n- 523 return n;\n- 524 }\n- 525\n- 526 protected:\n- 528 compressed_base_array_unmanaged ()\n- 529 : n(0), p(0), j(0)\n- 530 {}\n- 531\n- 532 size_type n; // number of elements in array\n- 533 B *p; // pointer to dynamically allocated built-in array\n- 534 size_type* j; // the index set\n- 535 };\n- 536\n- 537} // end namespace Imp\n- 538\n- 539} // end namespace\n- 540\n- 541#endif\n-istlexception.hh\n+ 222#endif // #ifndef DUNE_ISTL_ILDL_HH\n+ilu.hh\n+The incomplete LU factorization kernels.\n Dune\n Definition: allocator.hh:11\n+Dune::bildl_decompose\n+void bildl_decompose(Matrix &A)\n+compute ILDL decomposition of a symmetric matrix A\n+Definition: ildl.hh:88\n+Dune::bildl_backsolve\n+void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool\n+isLowerTriangular=false)\n+Definition: ildl.hh:149\n+Dune::bildl_subtractBCT\n+static void bildl_subtractBCT(const FieldMatrix< K, m, n > &B, const\n+FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)\n+Definition: ildl.hh:24\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::MatrixBlockError\n+Error when performing an operation on a matrix block.\n+Definition: istlexception.hh:52\n+Dune::MatrixBlockError::r\n+int r\n+Definition: istlexception.hh:54\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::beforeBegin\n+RowIterator beforeBegin()\n+Definition: matrix.hh:634\n+Dune::Matrix::beforeEnd\n+RowIterator beforeEnd()\n+Definition: matrix.hh:627\n+Dune::Matrix::end\n+RowIterator end()\n+Get iterator to one beyond last row.\n+Definition: matrix.hh:620\n+Dune::Matrix::begin\n+RowIterator begin()\n+Get iterator to first row.\n+Definition: matrix.hh:614\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00053.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00053.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solverregistry.hh File Reference\n+dune-istl: owneroverlapcopy.hh File Reference\n \n \n \n \n \n \n \n@@ -65,137 +65,88 @@\n
  • dune
  • istl
  • \n
    \n
    \n
    \n \n-
    solverregistry.hh File Reference
    \n+ \n
    \n
    \n-
    #include <dune/istl/common/registry.hh>
    \n-#include <dune/istl/preconditioner.hh>
    \n-#include <dune/istl/solver.hh>
    \n+\n+

    Classes providing communication interfaces for overlapping Schwarz methods. \n+More...

    \n+
    #include <new>
    \n+#include <iostream>
    \n+#include <vector>
    \n+#include <list>
    \n+#include <map>
    \n+#include <set>
    \n+#include <tuple>
    \n+#include "cmath"
    \n+#include <mpi.h>
    \n+#include <dune/common/enumset.hh>
    \n+#include <dune/common/parallel/indexset.hh>
    \n+#include <dune/common/parallel/communicator.hh>
    \n+#include <dune/common/parallel/remoteindices.hh>
    \n+#include <dune/common/parallel/mpicommunication.hh>
    \n+#include "solvercategory.hh"
    \n+#include "istlexception.hh"
    \n+#include <dune/common/parallel/communication.hh>
    \n+#include <dune/istl/matrixmarket.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n \n-\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::UnsupportedType
    struct  Dune::OwnerOverlapCopyAttributeSet
     Attribute set for overlapping Schwarz. More...
     
    class  Dune::IndexInfoFromGrid< G, L >
     Information about the index distribution. More...
     
    class  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >
     A class setting up standard communication for a two-valued attribute set with owner/overlap/copy semantics. More...
     
    class  Dune::InvalidSolverFactoryConfiguration
    struct  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::CopyGatherScatter< T >
     gather/scatter callback for communcation More...
     
    struct  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::AddGatherScatter< T >
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-

    \n-Macros

    #define DUNE_REGISTER_DIRECT_SOLVER(name, ...)    DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
     
    #define DUNE_REGISTER_PRECONDITIONER(name, ...)    DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
     
    #define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...)    DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
     
    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n

    \n Functions

    template<template< class, class, class, int >class Preconditioner, int blockLevel = 1>
    auto Dune::defaultPreconditionerBlockLevelCreator ()
     
    template<template< class, class, class >class Preconditioner>
    auto Dune::defaultPreconditionerCreator ()
     
    template<template< class... >class Solver>
    auto Dune::defaultIterativeSolverCreator ()
     
    template<int dim, template< class, class > class Comm>
    void testRedistributed (int s)
     
    \n-

    Macro Definition Documentation

    \n-\n-

    ◆ DUNE_REGISTER_DIRECT_SOLVER

    \n-\n-
    \n-
    \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n-
    #define DUNE_REGISTER_DIRECT_SOLVER( name,
     ... 
    )    DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
    \n-
    \n-\n-
    \n-
    \n-\n-

    ◆ DUNE_REGISTER_ITERATIVE_SOLVER

    \n+

    Detailed Description

    \n+

    Classes providing communication interfaces for overlapping Schwarz methods.

    \n+
    Author
    Peter Bastian
    \n+

    Function Documentation

    \n+\n+

    ◆ testRedistributed()

    \n \n
    \n
    \n+
    \n+template<int dim, template< class, class > class Comm>
    \n \n \n- \n+ \n \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n-
    #define DUNE_REGISTER_ITERATIVE_SOLVERvoid testRedistributed ( name,
     ... 
    )    DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
    \n-
    \n-\n-
    \n-
    \n-\n-

    ◆ DUNE_REGISTER_PRECONDITIONER

    \n-\n-
    \n-
    \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n+ \n+ \n \n- \n- \n \n
    #define DUNE_REGISTER_PRECONDITIONER( name,
     ... 
    int s))    DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
    \n
    \n \n
    \n
    \n
    \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,64 +4,67 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Macros | Functions\n-solverregistry.hh File Reference\n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+owneroverlapcopy.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Communication_Interface\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"cmath\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"solvercategory.hh\"\n+#include \"istlexception.hh\"\n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::UnsupportedType\n+struct \u00a0Dune::OwnerOverlapCopyAttributeSet\n+\u00a0 Attribute set for overlapping Schwarz. More...\n \u00a0\n-class \u00a0Dune::InvalidSolverFactoryConfiguration\n+ class \u00a0Dune::IndexInfoFromGrid<_G,_L_>\n+\u00a0 Information about the index distribution. More...\n \u00a0\n- Namespaces\n-namespace \u00a0Dune\n-\u00a0\n- Macros\n-#define\u00a0DUNE_REGISTER_DIRECT_SOLVER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(DirectSolverTag,\n- name, __VA_ARGS__)\n+ class \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>\n+\u00a0 A class setting up standard communication for a two-valued attribute\n+ set with owner/overlap/copy semantics. More...\n+\u00a0\n+struct \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>::\n+ CopyGatherScatter<_T_>\n+\u00a0 gather/scatter callback for communcation More...\n \u00a0\n-#define\u00a0DUNE_REGISTER_PRECONDITIONER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(PreconditionerTag,\n- name, __VA_ARGS__)\n+struct \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>::\n+ AddGatherScatter<_T_>\n \u00a0\n-#define\u00a0DUNE_REGISTER_ITERATIVE_SOLVER(name, ...)\u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT\n- (IterativeSolverTag, name, __VA_ARGS__)\n+ Namespaces\n+namespace \u00a0Dune\n \u00a0\n Functions\n-templateclass Preconditioner, int\n-blockLevel = 1>\n-auto\u00a0Dune::defaultPreconditionerBlockLevelCreator ()\n-\u00a0\n-templateclass Preconditioner>\n-auto\u00a0Dune::defaultPreconditionerCreator ()\n-\u00a0\n-templateclass Solver>\n-auto\u00a0Dune::defaultIterativeSolverCreator ()\n-\u00a0\n-***** Macro Definition Documentation *****\n-***** \u25c6\u00a0DUNE_REGISTER_DIRECT_SOLVER *****\n-#define ( \u00a0name,\n-DUNE_REGISTER_DIRECT_SOLVER\n- \u00a0...\u00a0\n- ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(DirectSolverTag, name,\n- __VA_ARGS__)\n-***** \u25c6\u00a0DUNE_REGISTER_ITERATIVE_SOLVER *****\n-#define ( \u00a0name,\n-DUNE_REGISTER_ITERATIVE_SOLVER\n- \u00a0...\u00a0\n- ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(IterativeSolverTag, name,\n- __VA_ARGS__)\n-***** \u25c6\u00a0DUNE_REGISTER_PRECONDITIONER *****\n-#define ( \u00a0name,\n-DUNE_REGISTER_PRECONDITIONER\n- \u00a0...\u00a0\n- ) \u00a0\u00a0\u00a0 DUNE_REGISTRY_PUT(PreconditionerTag, name,\n- __VA_ARGS__)\n+template class Comm>\n+void\u00a0testRedistributed (int s)\n+\u00a0\n+***** Detailed Description *****\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+ Author\n+ Peter Bastian\n+***** Function Documentation *****\n+***** \u25c6\u00a0testRedistributed() *****\n+template class Comm>\n+void testRedistributed ( int\u00a0s )\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00053_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00053_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solverregistry.hh Source File\n+dune-istl: owneroverlapcopy.hh Source File\n \n \n \n \n \n \n \n@@ -62,106 +62,628 @@\n \n
    \n \n
    \n
    \n
    \n-
    solverregistry.hh
    \n+
    owneroverlapcopy.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5
    \n-
    6#ifndef DUNE_ISTL_SOLVERREGISTRY_HH
    \n-
    7#define DUNE_ISTL_SOLVERREGISTRY_HH
    \n-
    8
    \n-\n-\n-
    11#include <dune/istl/solver.hh>
    \n-
    12
    \n-
    13#define DUNE_REGISTER_DIRECT_SOLVER(name, ...) \\
    \n-
    14 DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)
    \n+
    5#ifndef DUNE_ISTL_OWNEROVERLAPCOPY_HH
    \n+
    6#define DUNE_ISTL_OWNEROVERLAPCOPY_HH
    \n+
    7
    \n+
    8#include <new>
    \n+
    9#include <iostream>
    \n+
    10#include <vector>
    \n+
    11#include <list>
    \n+
    12#include <map>
    \n+
    13#include <set>
    \n+
    14#include <tuple>
    \n
    15
    \n-
    16#define DUNE_REGISTER_PRECONDITIONER(name, ...) \\
    \n-
    17 DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
    \n-
    18
    \n-
    19#define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...) \\
    \n-
    20 DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)
    \n-
    21
    \n-
    22namespace Dune{
    \n-
    27 namespace {
    \n-
    28 struct DirectSolverTag {};
    \n-
    29 struct PreconditionerTag {};
    \n-
    30 struct IterativeSolverTag {};
    \n-
    31 }
    \n-
    32 template<template<class,class,class,int>class Preconditioner, int blockLevel=1>
    \n-\n-
    34 return [](auto typeList, const auto& matrix, const Dune::ParameterTree& config)
    \n-
    35 {
    \n-
    36 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n-
    37 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n-
    38 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;
    \n-
    39 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
    \n-
    40 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(matrix, config);
    \n-
    41 return preconditioner;
    \n-
    42 };
    \n-
    43 }
    \n-
    44
    \n-
    45 template<template<class,class,class>class Preconditioner>
    \n-\n-
    47 return [](auto typeList, const auto& matrix, const Dune::ParameterTree& config)
    \n-
    48 {
    \n-
    49 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n-
    50 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n-
    51 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;
    \n-
    52 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
    \n-
    53 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(matrix, config);
    \n-
    54 return preconditioner;
    \n-
    55 };
    \n-
    56 }
    \n-
    57
    \n-
    58 template<template<class...>class Solver>
    \n-\n-
    60 return [](auto typeList,
    \n-
    61 const auto& linearOperator,
    \n-
    62 const auto& scalarProduct,
    \n-
    63 const auto& preconditioner,
    \n-
    64 const Dune::ParameterTree& config)
    \n-
    65 {
    \n-
    66 using Domain = typename Dune::TypeListElement<0, decltype(typeList)>::type;
    \n-
    67 using Range = typename Dune::TypeListElement<1, decltype(typeList)>::type;
    \n-
    68 std::shared_ptr<Dune::InverseOperator<Domain, Range>> solver
    \n-
    69 = std::make_shared<Solver<Domain>>(linearOperator, scalarProduct, preconditioner, config);
    \n-
    70 return solver;
    \n-
    71 };
    \n-
    72 }
    \n-
    73
    \n-
    74 /* This exception is thrown, when the requested solver is in the factory but
    \n-
    75 cannot be instantiated for the required template parameters
    \n-
    76 */
    \n-
    77 class UnsupportedType : public NotImplemented {};
    \n-
    78
    \n-
    79 class InvalidSolverFactoryConfiguration : public InvalidStateException{};
    \n-
    80} // end namespace Dune
    \n-
    81
    \n-
    82#endif // DUNE_ISTL_SOLVERREGISTRY_HH
    \n-
    Define general, extensible interface for inverse operators.
    \n-\n-\n-
    auto defaultIterativeSolverCreator()
    Definition: solverregistry.hh:59
    \n-
    auto defaultPreconditionerBlockLevelCreator()
    Definition: solverregistry.hh:33
    \n-
    auto defaultPreconditionerCreator()
    Definition: solverregistry.hh:46
    \n+
    16#include "cmath"
    \n+
    17
    \n+
    18// MPI header
    \n+
    19#if HAVE_MPI
    \n+
    20#include <mpi.h>
    \n+
    21#endif
    \n+
    22
    \n+
    23#include <dune/common/enumset.hh>
    \n+
    24
    \n+
    25#if HAVE_MPI
    \n+
    26#include <dune/common/parallel/indexset.hh>
    \n+
    27#include <dune/common/parallel/communicator.hh>
    \n+
    28#include <dune/common/parallel/remoteindices.hh>
    \n+
    29#include <dune/common/parallel/mpicommunication.hh>
    \n+
    30#endif
    \n+
    31
    \n+
    32#include "solvercategory.hh"
    \n+
    33#include "istlexception.hh"
    \n+
    34#include <dune/common/parallel/communication.hh>
    \n+\n+
    36
    \n+
    37template<int dim, template<class,class> class Comm>
    \n+\n+
    39
    \n+
    40
    \n+
    41namespace Dune {
    \n+
    42
    \n+\n+
    59 {
    \n+\n+\n+
    62 };
    \n+
    63 };
    \n+
    64
    \n+
    76 template <class G, class L>
    \n+\n+
    78 {
    \n+
    79 public:
    \n+
    81 typedef G GlobalIdType;
    \n+
    82
    \n+
    84 typedef L LocalIdType;
    \n+
    85
    \n+
    92 typedef std::tuple<GlobalIdType,LocalIdType,int> IndexTripel;
    \n+
    99 typedef std::tuple<int,GlobalIdType,int> RemoteIndexTripel;
    \n+
    100
    \n+\n+
    107 {
    \n+
    108 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
    \n+\n+\n+
    111 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n+
    112 localindices.insert(x);
    \n+
    113 }
    \n+
    114
    \n+\n+
    121 {
    \n+
    122 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
    \n+\n+\n+
    125 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n+
    126 remoteindices.insert(x);
    \n+
    127 }
    \n+
    128
    \n+
    133 const std::set<IndexTripel>& localIndices () const
    \n+
    134 {
    \n+
    135 return localindices;
    \n+
    136 }
    \n+
    137
    \n+
    142 const std::set<RemoteIndexTripel>& remoteIndices () const
    \n+
    143 {
    \n+
    144 return remoteindices;
    \n+
    145 }
    \n+
    146
    \n+
    150 void clear ()
    \n+
    151 {
    \n+
    152 localindices.clear();
    \n+
    153 remoteindices.clear();
    \n+
    154 }
    \n+
    155
    \n+
    156 private:
    \n+
    158 std::set<IndexTripel> localindices;
    \n+
    160 std::set<RemoteIndexTripel> remoteindices;
    \n+
    161 };
    \n+
    162
    \n+
    163
    \n+
    164#if HAVE_MPI
    \n+
    165
    \n+
    172 template <class GlobalIdType, class LocalIdType=int>
    \n+\n+
    174 {
    \n+
    175 template<typename M, typename G, typename L>
    \n+
    176 friend void loadMatrixMarket(M&,
    \n+
    177 const std::string&,
    \n+\n+
    179 bool);
    \n+
    180 // used types
    \n+\n+\n+
    183 typedef typename std::set<IndexTripel>::const_iterator localindex_iterator;
    \n+
    184 typedef typename std::set<RemoteIndexTripel>::const_iterator remoteindex_iterator;
    \n+\n+
    186 typedef Dune::ParallelLocalIndex<AttributeSet> LI;
    \n+
    187 public:
    \n+
    188 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> PIS;
    \n+
    189 typedef Dune::RemoteIndices<PIS> RI;
    \n+
    190 typedef Dune::RemoteIndexListModifier<PIS,typename RI::Allocator,false> RILM;
    \n+
    191 typedef typename RI::RemoteIndex RX;
    \n+
    192 typedef Dune::BufferedCommunicator BC;
    \n+
    193 typedef Dune::Interface IF;
    \n+
    194 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner> OwnerSet;
    \n+
    195 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopySet;
    \n+
    196 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> OwnerOverlapSet;
    \n+
    197 typedef Dune::AllSet<AttributeSet> AllSet;
    \n+
    198 protected:
    \n+
    199
    \n+
    200
    \n+
    202 template<typename T>
    \n+\n+
    204 {
    \n+
    205 typedef typename CommPolicy<T>::IndexedType V;
    \n+
    206
    \n+
    207 static V gather(const T& a, std::size_t i)
    \n+
    208 {
    \n+
    209 return a[i];
    \n+
    210 }
    \n+
    211
    \n+
    212 static void scatter(T& a, V v, std::size_t i)
    \n+
    213 {
    \n+
    214 a[i] = v;
    \n+
    215 }
    \n+
    216 };
    \n+
    217 template<typename T>
    \n+\n+
    219 {
    \n+
    220 typedef typename CommPolicy<T>::IndexedType V;
    \n+
    221
    \n+
    222 static V gather(const T& a, std::size_t i)
    \n+
    223 {
    \n+
    224 return a[i];
    \n+
    225 }
    \n+
    226
    \n+
    227 static void scatter(T& a, V v, std::size_t i)
    \n+
    228 {
    \n+
    229 a[i] += v;
    \n+
    230 }
    \n+
    231 };
    \n+
    232
    \n+\n+
    234 {
    \n+
    235 if (OwnerOverlapToAllInterfaceBuilt)
    \n+
    236 OwnerOverlapToAllInterface.free();
    \n+
    237 OwnerOverlapSet sourceFlags;
    \n+
    238 Combine<OwnerOverlapSet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet>
    \n+
    239 destFlags;
    \n+
    240 OwnerOverlapToAllInterface.build(ri,sourceFlags,destFlags);
    \n+
    241 OwnerOverlapToAllInterfaceBuilt = true;
    \n+
    242 }
    \n+
    243
    \n+\n+
    245 {
    \n+
    246 if (OwnerToAllInterfaceBuilt)
    \n+
    247 OwnerToAllInterface.free();
    \n+
    248 OwnerSet sourceFlags;
    \n+
    249 AllSet destFlags;
    \n+
    250 OwnerToAllInterface.build(ri,sourceFlags,destFlags);
    \n+
    251 OwnerToAllInterfaceBuilt = true;
    \n+
    252 }
    \n+
    253
    \n+\n+
    255 {
    \n+
    256 if (OwnerCopyToAllInterfaceBuilt)
    \n+
    257 OwnerCopyToAllInterface.free();
    \n+
    258
    \n+
    259 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
    \n+
    260 OwnerCopySet sourceFlags;
    \n+
    261 Combine<OwnerCopySet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> destFlags;
    \n+
    262 OwnerCopyToAllInterface.build(ri,sourceFlags,destFlags);
    \n+
    263 OwnerCopyToAllInterfaceBuilt = true;
    \n+
    264 }
    \n+
    265
    \n+\n+
    267 {
    \n+
    268 if (OwnerCopyToOwnerCopyInterfaceBuilt)
    \n+
    269 OwnerCopyToOwnerCopyInterface.free();
    \n+
    270
    \n+
    271
    \n+
    272 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
    \n+
    273 OwnerCopySet sourceFlags;
    \n+
    274 OwnerCopySet destFlags;
    \n+
    275 OwnerCopyToOwnerCopyInterface.build(ri,sourceFlags,destFlags);
    \n+
    276 OwnerCopyToOwnerCopyInterfaceBuilt = true;
    \n+
    277 }
    \n+
    278
    \n+\n+
    280 {
    \n+
    281 if (CopyToAllInterfaceBuilt)
    \n+
    282 CopyToAllInterface.free();
    \n+
    283 CopySet sourceFlags;
    \n+
    284 AllSet destFlags;
    \n+
    285 CopyToAllInterface.build(ri,sourceFlags,destFlags);
    \n+
    286 CopyToAllInterfaceBuilt = true;
    \n+
    287 }
    \n+
    288
    \n+
    289 public:
    \n+
    290
    \n+\n+
    296 return category_;
    \n+
    297 }
    \n+
    298
    \n+
    299 const Communication<MPI_Comm>& communicator() const
    \n+
    300 {
    \n+
    301 return cc;
    \n+
    302 }
    \n+
    303
    \n+
    310 template<class T>
    \n+
    311 void copyOwnerToAll (const T& source, T& dest) const
    \n+
    312 {
    \n+
    313 if (!OwnerToAllInterfaceBuilt)
    \n+\n+\n+
    316 communicator.template build<T>(OwnerToAllInterface);
    \n+
    317 communicator.template forward<CopyGatherScatter<T> >(source,dest);
    \n+
    318 communicator.free();
    \n+
    319 }
    \n+
    320
    \n+
    327 template<class T>
    \n+
    328 void copyCopyToAll (const T& source, T& dest) const
    \n+
    329 {
    \n+
    330 if (!CopyToAllInterfaceBuilt)
    \n+\n+\n+
    333 communicator.template build<T>(CopyToAllInterface);
    \n+
    334 communicator.template forward<CopyGatherScatter<T> >(source,dest);
    \n+
    335 communicator.free();
    \n+
    336 }
    \n+
    337
    \n+
    344 template<class T>
    \n+
    345 void addOwnerOverlapToAll (const T& source, T& dest) const
    \n+
    346 {
    \n+
    347 if (!OwnerOverlapToAllInterfaceBuilt)
    \n+\n+\n+
    350 communicator.template build<T>(OwnerOverlapToAllInterface);
    \n+
    351 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n+
    352 communicator.free();
    \n+
    353 }
    \n+
    354
    \n+
    361 template<class T>
    \n+
    362 void addOwnerCopyToAll (const T& source, T& dest) const
    \n+
    363 {
    \n+
    364 if (!OwnerCopyToAllInterfaceBuilt)
    \n+\n+\n+
    367 communicator.template build<T>(OwnerCopyToAllInterface);
    \n+
    368 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n+
    369 communicator.free();
    \n+
    370 }
    \n+
    371
    \n+
    378 template<class T>
    \n+
    379 void addOwnerCopyToOwnerCopy (const T& source, T& dest) const
    \n+
    380 {
    \n+
    381 if (!OwnerCopyToOwnerCopyInterfaceBuilt)
    \n+\n+\n+
    384 communicator.template build<T>(OwnerCopyToOwnerCopyInterface);
    \n+
    385 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n+
    386 communicator.free();
    \n+
    387 }
    \n+
    388
    \n+
    389
    \n+
    397 template<class T1, class T2>
    \n+
    398 void dot (const T1& x, const T1& y, T2& result) const
    \n+
    399 {
    \n+
    400 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
    \n+
    401 // set up mask vector
    \n+
    402 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size()))
    \n+
    403 {
    \n+
    404 mask.resize(x.size());
    \n+
    405 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n+
    406 mask[i] = 1;
    \n+
    407 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n+
    408 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
    \n+
    409 mask[i->local().local()] = 0;
    \n+
    410 }
    \n+
    411 result = T2(0.0);
    \n+
    412
    \n+
    413 for (typename T1::size_type i=0; i<x.size(); i++)
    \n+
    414 result += (x[i]*(y[i]))*static_cast<real_type>(mask[i]);
    \n+
    415 result = cc.sum(result);
    \n+
    416 }
    \n+
    417
    \n+
    424 template<class T1>
    \n+
    425 typename FieldTraits<typename T1::field_type>::real_type norm (const T1& x) const
    \n+
    426 {
    \n+
    427 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
    \n+
    428
    \n+
    429 // set up mask vector
    \n+
    430 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size()))
    \n+
    431 {
    \n+
    432 mask.resize(x.size());
    \n+
    433 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n+
    434 mask[i] = 1;
    \n+
    435 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n+
    436 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
    \n+
    437 mask[i->local().local()] = 0;
    \n+
    438 }
    \n+
    439 auto result = real_type(0.0);
    \n+
    440 for (typename T1::size_type i=0; i<x.size(); i++)
    \n+
    441 result += Impl::asVector(x[i]).two_norm2()*mask[i];
    \n+
    442 using std::sqrt;
    \n+
    443 return sqrt(cc.sum(result));
    \n+
    444 }
    \n+
    445
    \n+
    446 typedef Dune::EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopyFlags;
    \n+
    447
    \n+
    449 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> ParallelIndexSet;
    \n+
    450
    \n+
    452 typedef Dune::RemoteIndices<PIS> RemoteIndices;
    \n+
    453
    \n+
    456 typedef Dune::GlobalLookupIndexSet<ParallelIndexSet> GlobalLookupIndexSet;
    \n+
    457
    \n+\n+
    463 {
    \n+
    464 return pis;
    \n+
    465 }
    \n+
    466
    \n+\n+
    472 {
    \n+
    473 return ri;
    \n+
    474 }
    \n+
    475
    \n+\n+
    481 {
    \n+
    482 return pis;
    \n+
    483 }
    \n+
    484
    \n+
    485
    \n+\n+
    491 {
    \n+
    492 return ri;
    \n+
    493 }
    \n+
    494
    \n+\n+
    496 {
    \n+
    497 if(globalLookup_) {
    \n+
    498 if(pis.seqNo()==oldseqNo)
    \n+
    499 // Nothing changed!
    \n+
    500 return;
    \n+
    501 delete globalLookup_;
    \n+
    502 }
    \n+
    503
    \n+
    504 globalLookup_ = new GlobalLookupIndexSet(pis);
    \n+
    505 oldseqNo = pis.seqNo();
    \n+
    506 }
    \n+
    507
    \n+
    508 void buildGlobalLookup(std::size_t size)
    \n+
    509 {
    \n+
    510 if(globalLookup_) {
    \n+
    511 if(pis.seqNo()==oldseqNo)
    \n+
    512 // Nothing changed!
    \n+
    513 return;
    \n+
    514 delete globalLookup_;
    \n+
    515 }
    \n+
    516 globalLookup_ = new GlobalLookupIndexSet(pis, size);
    \n+
    517 oldseqNo = pis.seqNo();
    \n+
    518 }
    \n+
    519
    \n+\n+
    521 {
    \n+
    522 delete globalLookup_;
    \n+
    523 globalLookup_=0;
    \n+
    524 }
    \n+
    525
    \n+\n+
    527 {
    \n+
    528 assert(globalLookup_ != 0);
    \n+
    529 return *globalLookup_;
    \n+
    530 }
    \n+
    531
    \n+
    537 template<class T1>
    \n+
    538 void project (T1& x) const
    \n+
    539 {
    \n+
    540 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n+
    541 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
    \n+
    542 x[i->local().local()] = 0;
    \n+
    543 }
    \n+
    544
    \n+\n+\n+
    556 bool freecomm_ = false)
    \n+
    557 : comm(comm_), cc(comm_), pis(), ri(pis,pis,comm_),
    \n+
    558 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
    \n+
    559 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
    \n+
    560 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),
    \n+
    561 freecomm(freecomm_)
    \n+
    562 {}
    \n+
    563
    \n+\n+
    573 : comm(MPI_COMM_WORLD), cc(MPI_COMM_WORLD), pis(), ri(pis,pis,MPI_COMM_WORLD),
    \n+
    574 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
    \n+
    575 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
    \n+
    576 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_), freecomm(false)
    \n+
    577 {}
    \n+
    578
    \n+\n+
    587 MPI_Comm comm_,
    \n+\n+
    589 bool freecomm_ = false)
    \n+
    590 : comm(comm_), cc(comm_), OwnerToAllInterfaceBuilt(false),
    \n+
    591 OwnerOverlapToAllInterfaceBuilt(false), OwnerCopyToAllInterfaceBuilt(false),
    \n+
    592 OwnerCopyToOwnerCopyInterfaceBuilt(false), CopyToAllInterfaceBuilt(false),
    \n+
    593 globalLookup_(0), category_(cat_), freecomm(freecomm_)
    \n+
    594 {
    \n+
    595 // set up an ISTL index set
    \n+
    596 pis.beginResize();
    \n+
    597 for (localindex_iterator i=indexinfo.localIndices().begin(); i!=indexinfo.localIndices().end(); ++i)
    \n+
    598 {
    \n+
    599 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
    \n+
    600 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::owner,true));
    \n+
    601 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
    \n+
    602 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::overlap,true));
    \n+
    603 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
    \n+
    604 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::copy,true));
    \n+
    605 // std::cout << cc.rank() << ": adding index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
    \n+
    606 }
    \n+
    607 pis.endResize();
    \n+
    608
    \n+
    609 // build remote indices WITHOUT communication
    \n+
    610 // std::cout << cc.rank() << ": build remote indices" << std::endl;
    \n+
    611 ri.setIndexSets(pis,pis,cc);
    \n+
    612 if (indexinfo.remoteIndices().size()>0)
    \n+
    613 {
    \n+
    614 remoteindex_iterator i=indexinfo.remoteIndices().begin();
    \n+
    615 int p = std::get<0>(*i);
    \n+
    616 RILM modifier = ri.template getModifier<false,true>(p);
    \n+
    617 typename PIS::const_iterator pi=pis.begin();
    \n+
    618 for ( ; i!=indexinfo.remoteIndices().end(); ++i)
    \n+
    619 {
    \n+
    620 // handle processor change
    \n+
    621 if (p!=std::get<0>(*i))
    \n+
    622 {
    \n+
    623 p = std::get<0>(*i);
    \n+
    624 modifier = ri.template getModifier<false,true>(p);
    \n+
    625 pi=pis.begin();
    \n+
    626 }
    \n+
    627
    \n+
    628 // position to correct entry in parallel index set
    \n+
    629 while (pi->global()!=std::get<1>(*i) && pi!=pis.end())
    \n+
    630 ++pi;
    \n+
    631 if (pi==pis.end())
    \n+
    632 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n+
    633
    \n+
    634 // insert entry
    \n+
    635 // std::cout << cc.rank() << ": adding remote index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
    \n+
    636 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
    \n+
    637 modifier.insert(RX(OwnerOverlapCopyAttributeSet::owner,&(*pi)));
    \n+
    638 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
    \n+
    639 modifier.insert(RX(OwnerOverlapCopyAttributeSet::overlap,&(*pi)));
    \n+
    640 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
    \n+
    641 modifier.insert(RX(OwnerOverlapCopyAttributeSet::copy,&(*pi)));
    \n+
    642 }
    \n+
    643 }else{
    \n+
    644 // Force remote indices to be synced!
    \n+
    645 ri.template getModifier<false,true>(0);
    \n+
    646 }
    \n+
    647 }
    \n+
    648
    \n+
    649 // destructor: free memory in some objects
    \n+\n+
    651 {
    \n+
    652 ri.free();
    \n+
    653 if (OwnerToAllInterfaceBuilt) OwnerToAllInterface.free();
    \n+
    654 if (OwnerOverlapToAllInterfaceBuilt) OwnerOverlapToAllInterface.free();
    \n+
    655 if (OwnerCopyToAllInterfaceBuilt) OwnerCopyToAllInterface.free();
    \n+
    656 if (OwnerCopyToOwnerCopyInterfaceBuilt) OwnerCopyToOwnerCopyInterface.free();
    \n+
    657 if (CopyToAllInterfaceBuilt) CopyToAllInterface.free();
    \n+
    658 if (globalLookup_) delete globalLookup_;
    \n+
    659 if (freecomm==true)
    \n+
    660 if(comm!=MPI_COMM_NULL)
    \n+
    661 {
    \n+
    662#ifdef MPI_2
    \n+
    663 // If it is possible to query whether MPI_Finalize
    \n+
    664 // was called, only free the communicator before
    \n+
    665 // calling MPI_Finalize.
    \n+
    666 int wasFinalized = 0;
    \n+
    667 MPI_Finalized( &wasFinalized );
    \n+
    668 if(!wasFinalized)
    \n+
    669#endif
    \n+
    670 MPI_Comm_free(&comm);
    \n+
    671 }
    \n+
    672 }
    \n+
    673
    \n+
    674 private:
    \n+\n+
    676 {}
    \n+
    677 MPI_Comm comm;
    \n+
    678 Communication<MPI_Comm> cc;
    \n+
    679 PIS pis;
    \n+
    680 RI ri;
    \n+
    681 mutable IF OwnerToAllInterface;
    \n+
    682 mutable bool OwnerToAllInterfaceBuilt;
    \n+
    683 mutable IF OwnerOverlapToAllInterface;
    \n+
    684 mutable bool OwnerOverlapToAllInterfaceBuilt;
    \n+
    685 mutable IF OwnerCopyToAllInterface;
    \n+
    686 mutable bool OwnerCopyToAllInterfaceBuilt;
    \n+
    687 mutable IF OwnerCopyToOwnerCopyInterface;
    \n+
    688 mutable bool OwnerCopyToOwnerCopyInterfaceBuilt;
    \n+
    689 mutable IF CopyToAllInterface;
    \n+
    690 mutable bool CopyToAllInterfaceBuilt;
    \n+
    691 mutable std::vector<double> mask;
    \n+
    692 int oldseqNo;
    \n+
    693 GlobalLookupIndexSet* globalLookup_;
    \n+
    694 const SolverCategory::Category category_;
    \n+
    695 bool freecomm;
    \n+
    696 };
    \n+
    697
    \n+
    698#endif
    \n+
    699
    \n+
    700
    \n+
    703} // end namespace
    \n+
    704
    \n+
    705#endif
    \n+
    void testRedistributed(int s)
    \n+
    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
    \n+\n+\n
    Definition: allocator.hh:11
    \n-
    constexpr std::size_t blockLevel()
    Determine the block level of a possibly nested vector/matrix type.
    Definition: blocklevel.hh:176
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    Definition: solverregistry.hh:77
    \n-
    Definition: solverregistry.hh:79
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    Attribute set for overlapping Schwarz.
    Definition: owneroverlapcopy.hh:59
    \n+
    AttributeSet
    Definition: owneroverlapcopy.hh:60
    \n+
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n+
    @ copy
    Definition: owneroverlapcopy.hh:61
    \n+
    @ overlap
    Definition: owneroverlapcopy.hh:61
    \n+
    Information about the index distribution.
    Definition: owneroverlapcopy.hh:78
    \n+
    std::tuple< GlobalIdType, LocalIdType, int > IndexTripel
    A triple describing a local index.
    Definition: owneroverlapcopy.hh:92
    \n+
    void addRemoteIndex(const RemoteIndexTripel &x)
    Add a new remote index triple to the set of remote indices.
    Definition: owneroverlapcopy.hh:120
    \n+
    G GlobalIdType
    The type of the global index.
    Definition: owneroverlapcopy.hh:81
    \n+
    const std::set< IndexTripel > & localIndices() const
    Get the set of indices local to the process.
    Definition: owneroverlapcopy.hh:133
    \n+
    const std::set< RemoteIndexTripel > & remoteIndices() const
    Get the set of remote indices.
    Definition: owneroverlapcopy.hh:142
    \n+
    L LocalIdType
    The type of the local index.
    Definition: owneroverlapcopy.hh:84
    \n+
    void clear()
    Remove all indices from the sets.
    Definition: owneroverlapcopy.hh:150
    \n+
    void addLocalIndex(const IndexTripel &x)
    Add a new index triple to the set of local indices.
    Definition: owneroverlapcopy.hh:106
    \n+
    std::tuple< int, GlobalIdType, int > RemoteIndexTripel
    A triple describing a remote index.
    Definition: owneroverlapcopy.hh:99
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopySet
    Definition: owneroverlapcopy.hh:195
    \n+
    const GlobalLookupIndexSet & globalLookup() const
    Definition: owneroverlapcopy.hh:526
    \n+
    FieldTraits< typenameT1::field_type >::real_type norm(const T1 &x) const
    Compute the global Euclidean norm of a vector.
    Definition: owneroverlapcopy.hh:425
    \n+
    void buildOwnerOverlapToAllInterface() const
    Definition: owneroverlapcopy.hh:233
    \n+
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > PIS
    Definition: owneroverlapcopy.hh:188
    \n+
    void buildOwnerCopyToAllInterface() const
    Definition: owneroverlapcopy.hh:254
    \n+
    void buildOwnerCopyToOwnerCopyInterface() const
    Definition: owneroverlapcopy.hh:266
    \n+
    OwnerOverlapCopyCommunication(const IndexInfoFromGrid< GlobalIdType, LocalIdType > &indexinfo, MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
    Constructor.
    Definition: owneroverlapcopy.hh:586
    \n+
    SolverCategory::Category category() const
    Get Solver Category.
    Definition: owneroverlapcopy.hh:295
    \n+
    void addOwnerCopyToOwnerCopy(const T &source, T &dest) const
    Communicate values from owner and copy data points to owner and copy data points and add them to thos...
    Definition: owneroverlapcopy.hh:379
    \n+
    void buildCopyToAllInterface() const
    Definition: owneroverlapcopy.hh:279
    \n+
    Dune::EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopyFlags
    Definition: owneroverlapcopy.hh:446
    \n+
    RemoteIndices & remoteIndices()
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:490
    \n+
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n+
    Dune::RemoteIndices< PIS > RI
    Definition: owneroverlapcopy.hh:189
    \n+
    void buildGlobalLookup(std::size_t size)
    Definition: owneroverlapcopy.hh:508
    \n+
    void addOwnerOverlapToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points and add them to those values.
    Definition: owneroverlapcopy.hh:345
    \n+
    Dune::RemoteIndices< PIS > RemoteIndices
    The type of the remote indices.
    Definition: owneroverlapcopy.hh:452
    \n+
    void project(T1 &x) const
    Set vector to zero at copy dofs.
    Definition: owneroverlapcopy.hh:538
    \n+
    Dune::AllSet< AttributeSet > AllSet
    Definition: owneroverlapcopy.hh:197
    \n+
    Combine< EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner >, EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::overlap >, AttributeSet > OwnerOverlapSet
    Definition: owneroverlapcopy.hh:196
    \n+
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n+
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n+
    Dune::Interface IF
    Definition: owneroverlapcopy.hh:193
    \n+
    ~OwnerOverlapCopyCommunication()
    Definition: owneroverlapcopy.hh:650
    \n+
    void buildGlobalLookup()
    Definition: owneroverlapcopy.hh:495
    \n+
    Dune::BufferedCommunicator BC
    Definition: owneroverlapcopy.hh:192
    \n+
    OwnerOverlapCopyCommunication(MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
    Construct the communication without any indices.
    Definition: owneroverlapcopy.hh:554
    \n+
    ParallelIndexSet & indexSet()
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:480
    \n+
    void dot(const T1 &x, const T1 &y, T2 &result) const
    Compute a global dot product of two vectors.
    Definition: owneroverlapcopy.hh:398
    \n+
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n+
    OwnerOverlapCopyCommunication(SolverCategory::Category cat_=SolverCategory::overlapping)
    Construct the communication without any indices using MPI_COMM_WORLD.
    Definition: owneroverlapcopy.hh:572
    \n+
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet
    Definition: owneroverlapcopy.hh:194
    \n+
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n+
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n+
    friend void loadMatrixMarket(M &, const std::string &, OwnerOverlapCopyCommunication< G, L > &, bool)
    Load a parallel matrix/vector stored in matrix market format.
    Definition: matrixmarket.hh:1269
    \n+
    RI::RemoteIndex RX
    Definition: owneroverlapcopy.hh:191
    \n+
    void addOwnerCopyToAll(const T &source, T &dest) const
    Communicate values from owner and copy data points to all other data points and add them to those val...
    Definition: owneroverlapcopy.hh:362
    \n+
    void freeGlobalLookup()
    Definition: owneroverlapcopy.hh:520
    \n+
    Dune::RemoteIndexListModifier< PIS, typename RI::Allocator, false > RILM
    Definition: owneroverlapcopy.hh:190
    \n+
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n+
    void buildOwnerToAllInterface() const
    Definition: owneroverlapcopy.hh:244
    \n+
    gather/scatter callback for communcation
    Definition: owneroverlapcopy.hh:204
    \n+
    static V gather(const T &a, std::size_t i)
    Definition: owneroverlapcopy.hh:207
    \n+
    static void scatter(T &a, V v, std::size_t i)
    Definition: owneroverlapcopy.hh:212
    \n+
    CommPolicy< T >::IndexedType V
    Definition: owneroverlapcopy.hh:205
    \n+\n+
    CommPolicy< T >::IndexedType V
    Definition: owneroverlapcopy.hh:220
    \n+
    static V gather(const T &a, std::size_t i)
    Definition: owneroverlapcopy.hh:222
    \n+
    static void scatter(T &a, V v, std::size_t i)
    Definition: owneroverlapcopy.hh:227
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,123 +4,844 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solverregistry.hh\n+owneroverlapcopy.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5\n- 6#ifndef DUNE_ISTL_SOLVERREGISTRY_HH\n- 7#define DUNE_ISTL_SOLVERREGISTRY_HH\n- 8\n- 9#include \n- 10#include \n- 11#include \n- 12\n-13#define DUNE_REGISTER_DIRECT_SOLVER(name, ...) \\\n- 14 DUNE_REGISTRY_PUT(DirectSolverTag, name, __VA_ARGS__)\n+ 5#ifndef DUNE_ISTL_OWNEROVERLAPCOPY_HH\n+ 6#define DUNE_ISTL_OWNEROVERLAPCOPY_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n 15\n-16#define DUNE_REGISTER_PRECONDITIONER(name, ...) \\\n- 17 DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)\n- 18\n-19#define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...) \\\n- 20 DUNE_REGISTRY_PUT(IterativeSolverTag, name, __VA_ARGS__)\n- 21\n- 22namespace Dune{\n- 27 namespace {\n- 28 struct DirectSolverTag {};\n- 29 struct PreconditionerTag {};\n- 30 struct IterativeSolverTag {};\n- 31 }\n- 32 templateclass Preconditioner, int\n-blockLevel=1>\n-33 auto defaultPreconditionerBlockLevelCreator(){\n- 34 return [](auto typeList, const auto& matrix, const Dune::ParameterTree&\n-config)\n- 35 {\n- 36 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n- 37 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n- 38 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;\n- 39 std::shared_ptr> preconditioner\n- 40 = std::make_shared>\n-(matrix, config);\n- 41 return preconditioner;\n- 42 };\n- 43 }\n- 44\n- 45 templateclass Preconditioner>\n-46 auto defaultPreconditionerCreator(){\n- 47 return [](auto typeList, const auto& matrix, const Dune::ParameterTree&\n-config)\n- 48 {\n- 49 using Matrix = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n- 50 using Domain = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n- 51 using Range = typename Dune::TypeListElement<2, decltype(typeList)>::type;\n- 52 std::shared_ptr> preconditioner\n- 53 = std::make_shared>(matrix, config);\n- 54 return preconditioner;\n- 55 };\n- 56 }\n- 57\n- 58 templateclass Solver>\n-59 auto defaultIterativeSolverCreator(){\n- 60 return [](auto typeList,\n- 61 const auto& linearOperator,\n- 62 const auto& scalarProduct,\n- 63 const auto& preconditioner,\n- 64 const Dune::ParameterTree& config)\n- 65 {\n- 66 using Domain = typename Dune::TypeListElement<0, decltype(typeList)>::type;\n- 67 using Range = typename Dune::TypeListElement<1, decltype(typeList)>::type;\n- 68 std::shared_ptr> solver\n- 69 = std::make_shared>(linearOperator, scalarProduct,\n-preconditioner, config);\n- 70 return solver;\n- 71 };\n- 72 }\n- 73\n- 74 /* This exception is thrown, when the requested solver is in the factory\n-but\n- 75 cannot be instantiated for the required template parameters\n- 76 */\n-77 class UnsupportedType : public NotImplemented {};\n- 78\n-79 class InvalidSolverFactoryConfiguration : public InvalidStateException{};\n- 80} // end namespace Dune\n- 81\n- 82#endif // DUNE_ISTL_SOLVERREGISTRY_HH\n-solver.hh\n-Define general, extensible interface for inverse operators.\n-registry.hh\n-preconditioner.hh\n-Dune::defaultIterativeSolverCreator\n-auto defaultIterativeSolverCreator()\n-Definition: solverregistry.hh:59\n-Dune::defaultPreconditionerBlockLevelCreator\n-auto defaultPreconditionerBlockLevelCreator()\n-Definition: solverregistry.hh:33\n-Dune::defaultPreconditionerCreator\n-auto defaultPreconditionerCreator()\n-Definition: solverregistry.hh:46\n+ 16#include \"cmath\"\n+ 17\n+ 18// MPI header\n+ 19#if HAVE_MPI\n+ 20#include \n+ 21#endif\n+ 22\n+ 23#include \n+ 24\n+ 25#if HAVE_MPI\n+ 26#include \n+ 27#include \n+ 28#include \n+ 29#include \n+ 30#endif\n+ 31\n+ 32#include \"solvercategory.hh\"\n+ 33#include \"istlexception.hh\"\n+ 34#include \n+ 35#include \n+ 36\n+ 37template class Comm>\n+38void testRedistributed(int s);\n+ 39\n+ 40\n+ 41namespace Dune {\n+ 42\n+58 struct OwnerOverlapCopyAttributeSet\n+ 59 {\n+60 enum AttributeSet {\n+61 owner=1, overlap=2, copy=3\n+62 };\n+ 63 };\n+ 64\n+ 76 template \n+77 class IndexInfoFromGrid\n+ 78 {\n+ 79 public:\n+81 typedef G GlobalIdType;\n+ 82\n+84 typedef L LocalIdType;\n+ 85\n+92 typedef std::tuple IndexTripel;\n+99 typedef std::tuple RemoteIndexTripel;\n+ 100\n+106 void addLocalIndex (const IndexTripel& x)\n+ 107 {\n+ 108 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&\n+ 109 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&\n+ 110 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)\n+ 111 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n+index set\");\n+ 112 localindices.insert(x);\n+ 113 }\n+ 114\n+120 void addRemoteIndex (const RemoteIndexTripel& x)\n+ 121 {\n+ 122 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&\n+ 123 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&\n+ 124 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)\n+ 125 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n+index set\");\n+ 126 remoteindices.insert(x);\n+ 127 }\n+ 128\n+133 const std::set& localIndices () const\n+ 134 {\n+ 135 return localindices;\n+ 136 }\n+ 137\n+142 const std::set& remoteIndices () const\n+ 143 {\n+ 144 return remoteindices;\n+ 145 }\n+ 146\n+150 void clear ()\n+ 151 {\n+ 152 localindices.clear();\n+ 153 remoteindices.clear();\n+ 154 }\n+ 155\n+ 156 private:\n+ 158 std::set localindices;\n+ 160 std::set remoteindices;\n+ 161 };\n+ 162\n+ 163\n+ 164#if HAVE_MPI\n+ 165\n+ 172 template \n+173 class OwnerOverlapCopyCommunication\n+ 174 {\n+ 175 template\n+ 176 friend void loadMatrixMarket(M&,\n+ 177 const std::string&,\n+ 178 OwnerOverlapCopyCommunication&,\n+ 179 bool);\n+ 180 // used types\n+ 181 typedef typename IndexInfoFromGrid::IndexTripel\n+IndexTripel;\n+ 182 typedef typename IndexInfoFromGrid::\n+RemoteIndexTripel RemoteIndexTripel;\n+ 183 typedef typename std::set::const_iterator\n+localindex_iterator;\n+ 184 typedef typename std::set::const_iterator\n+remoteindex_iterator;\n+ 185 typedef typename OwnerOverlapCopyAttributeSet::AttributeSet AttributeSet;\n+ 186 typedef Dune::ParallelLocalIndex LI;\n+ 187 public:\n+188 typedef Dune::ParallelIndexSet PIS;\n+189 typedef Dune::RemoteIndices RI;\n+190 typedef Dune::RemoteIndexListModifier\n+RILM;\n+191 typedef typename RI::RemoteIndex RX;\n+192 typedef Dune::BufferedCommunicator BC;\n+193 typedef Dune::Interface IF;\n+194 typedef EnumItem\n+OwnerSet;\n+195 typedef EnumItem CopySet;\n+196 typedef Combine,EnumItem,AttributeSet> OwnerOverlapSet;\n+197 typedef Dune::AllSet AllSet;\n+ 198 protected:\n+ 199\n+ 200\n+ 202 template\n+203 struct CopyGatherScatter\n+ 204 {\n+205 typedef typename CommPolicy::IndexedType V;\n+ 206\n+207 static V gather(const T& a, std::size_t i)\n+ 208 {\n+ 209 return a[i];\n+ 210 }\n+ 211\n+212 static void scatter(T& a, V v, std::size_t i)\n+ 213 {\n+ 214 a[i] = v;\n+ 215 }\n+ 216 };\n+ 217 template\n+218 struct AddGatherScatter\n+ 219 {\n+220 typedef typename CommPolicy::IndexedType V;\n+ 221\n+222 static V gather(const T& a, std::size_t i)\n+ 223 {\n+ 224 return a[i];\n+ 225 }\n+ 226\n+227 static void scatter(T& a, V v, std::size_t i)\n+ 228 {\n+ 229 a[i] += v;\n+ 230 }\n+ 231 };\n+ 232\n+233 void buildOwnerOverlapToAllInterface () const\n+ 234 {\n+ 235 if (OwnerOverlapToAllInterfaceBuilt)\n+ 236 OwnerOverlapToAllInterface.free();\n+ 237 OwnerOverlapSet sourceFlags;\n+ 238\n+Combine,AttributeSet>\n+ 239 destFlags;\n+ 240 OwnerOverlapToAllInterface.build(ri,sourceFlags,destFlags);\n+ 241 OwnerOverlapToAllInterfaceBuilt = true;\n+ 242 }\n+ 243\n+244 void buildOwnerToAllInterface () const\n+ 245 {\n+ 246 if (OwnerToAllInterfaceBuilt)\n+ 247 OwnerToAllInterface.free();\n+ 248 OwnerSet sourceFlags;\n+ 249 AllSet destFlags;\n+ 250 OwnerToAllInterface.build(ri,sourceFlags,destFlags);\n+ 251 OwnerToAllInterfaceBuilt = true;\n+ 252 }\n+ 253\n+254 void buildOwnerCopyToAllInterface () const\n+ 255 {\n+ 256 if (OwnerCopyToAllInterfaceBuilt)\n+ 257 OwnerCopyToAllInterface.free();\n+ 258\n+ 259 typedef Combine,EnumItem,AttributeSet>\n+OwnerCopySet;\n+ 260 OwnerCopySet sourceFlags;\n+ 261 Combine,AttributeSet> destFlags;\n+ 262 OwnerCopyToAllInterface.build(ri,sourceFlags,destFlags);\n+ 263 OwnerCopyToAllInterfaceBuilt = true;\n+ 264 }\n+ 265\n+266 void buildOwnerCopyToOwnerCopyInterface () const\n+ 267 {\n+ 268 if (OwnerCopyToOwnerCopyInterfaceBuilt)\n+ 269 OwnerCopyToOwnerCopyInterface.free();\n+ 270\n+ 271\n+ 272 typedef Combine,EnumItem,AttributeSet>\n+OwnerCopySet;\n+ 273 OwnerCopySet sourceFlags;\n+ 274 OwnerCopySet destFlags;\n+ 275 OwnerCopyToOwnerCopyInterface.build(ri,sourceFlags,destFlags);\n+ 276 OwnerCopyToOwnerCopyInterfaceBuilt = true;\n+ 277 }\n+ 278\n+279 void buildCopyToAllInterface () const\n+ 280 {\n+ 281 if (CopyToAllInterfaceBuilt)\n+ 282 CopyToAllInterface.free();\n+ 283 CopySet sourceFlags;\n+ 284 AllSet destFlags;\n+ 285 CopyToAllInterface.build(ri,sourceFlags,destFlags);\n+ 286 CopyToAllInterfaceBuilt = true;\n+ 287 }\n+ 288\n+ 289 public:\n+ 290\n+295 SolverCategory::Category category () const {\n+ 296 return category_;\n+ 297 }\n+ 298\n+299 const Communication& communicator() const\n+ 300 {\n+ 301 return cc;\n+ 302 }\n+ 303\n+ 310 template\n+311 void copyOwnerToAll (const T& source, T& dest) const\n+ 312 {\n+ 313 if (!OwnerToAllInterfaceBuilt)\n+ 314 buildOwnerToAllInterface ();\n+ 315 BC communicator;\n+ 316 communicator.template build(OwnerToAllInterface);\n+ 317 communicator.template forward >(source,dest);\n+ 318 communicator.free();\n+ 319 }\n+ 320\n+ 327 template\n+328 void copyCopyToAll (const T& source, T& dest) const\n+ 329 {\n+ 330 if (!CopyToAllInterfaceBuilt)\n+ 331 buildCopyToAllInterface ();\n+ 332 BC communicator;\n+ 333 communicator.template build(CopyToAllInterface);\n+ 334 communicator.template forward >(source,dest);\n+ 335 communicator.free();\n+ 336 }\n+ 337\n+ 344 template\n+345 void addOwnerOverlapToAll (const T& source, T& dest) const\n+ 346 {\n+ 347 if (!OwnerOverlapToAllInterfaceBuilt)\n+ 348 buildOwnerOverlapToAllInterface ();\n+ 349 BC communicator;\n+ 350 communicator.template build(OwnerOverlapToAllInterface);\n+ 351 communicator.template forward >(source,dest);\n+ 352 communicator.free();\n+ 353 }\n+ 354\n+ 361 template\n+362 void addOwnerCopyToAll (const T& source, T& dest) const\n+ 363 {\n+ 364 if (!OwnerCopyToAllInterfaceBuilt)\n+ 365 buildOwnerCopyToAllInterface ();\n+ 366 BC communicator;\n+ 367 communicator.template build(OwnerCopyToAllInterface);\n+ 368 communicator.template forward >(source,dest);\n+ 369 communicator.free();\n+ 370 }\n+ 371\n+ 378 template\n+379 void addOwnerCopyToOwnerCopy (const T& source, T& dest) const\n+ 380 {\n+ 381 if (!OwnerCopyToOwnerCopyInterfaceBuilt)\n+ 382 buildOwnerCopyToOwnerCopyInterface ();\n+ 383 BC communicator;\n+ 384 communicator.template build(OwnerCopyToOwnerCopyInterface);\n+ 385 communicator.template forward >(source,dest);\n+ 386 communicator.free();\n+ 387 }\n+ 388\n+ 389\n+ 397 template\n+398 void dot (const T1& x, const T1& y, T2& result) const\n+ 399 {\n+ 400 using real_type = typename FieldTraits::\n+real_type;\n+ 401 // set up mask vector\n+ 402 if (mask.size()!=static_cast::size_type>\n+(x.size()))\n+ 403 {\n+ 404 mask.resize(x.size());\n+ 405 for (typename std::vector::size_type i=0; ilocal().attribute()!=OwnerOverlapCopyAttributeSet::owner)\n+ 409 mask[i->local().local()] = 0;\n+ 410 }\n+ 411 result = T2(0.0);\n+ 412\n+ 413 for (typename T1::size_type i=0; i(mask[i]);\n+ 415 result = cc.sum(result);\n+ 416 }\n+ 417\n+ 424 template\n+425 typename FieldTraits::real_type norm (const T1& x)\n+const\n+ 426 {\n+ 427 using real_type = typename FieldTraits::\n+real_type;\n+ 428\n+ 429 // set up mask vector\n+ 430 if (mask.size()!=static_cast::size_type>\n+(x.size()))\n+ 431 {\n+ 432 mask.resize(x.size());\n+ 433 for (typename std::vector::size_type i=0; ilocal().attribute()!=OwnerOverlapCopyAttributeSet::owner)\n+ 437 mask[i->local().local()] = 0;\n+ 438 }\n+ 439 auto result = real_type(0.0);\n+ 440 for (typename T1::size_type i=0; i\n+CopyFlags;\n+ 447\n+449 typedef Dune::ParallelIndexSet ParallelIndexSet;\n+ 450\n+452 typedef Dune::RemoteIndices RemoteIndices;\n+ 453\n+456 typedef Dune::GlobalLookupIndexSet GlobalLookupIndexSet;\n+ 457\n+462 const ParallelIndexSet& indexSet() const\n+ 463 {\n+ 464 return pis;\n+ 465 }\n+ 466\n+471 const RemoteIndices& remoteIndices() const\n+ 472 {\n+ 473 return ri;\n+ 474 }\n+ 475\n+480 ParallelIndexSet& indexSet()\n+ 481 {\n+ 482 return pis;\n+ 483 }\n+ 484\n+ 485\n+490 RemoteIndices& remoteIndices()\n+ 491 {\n+ 492 return ri;\n+ 493 }\n+ 494\n+495 void buildGlobalLookup()\n+ 496 {\n+ 497 if(globalLookup_) {\n+ 498 if(pis.seqNo()==oldseqNo)\n+ 499 // Nothing changed!\n+ 500 return;\n+ 501 delete globalLookup_;\n+ 502 }\n+ 503\n+ 504 globalLookup_ = new GlobalLookupIndexSet(pis);\n+ 505 oldseqNo = pis.seqNo();\n+ 506 }\n+ 507\n+508 void buildGlobalLookup(std::size_t size)\n+ 509 {\n+ 510 if(globalLookup_) {\n+ 511 if(pis.seqNo()==oldseqNo)\n+ 512 // Nothing changed!\n+ 513 return;\n+ 514 delete globalLookup_;\n+ 515 }\n+ 516 globalLookup_ = new GlobalLookupIndexSet(pis, size);\n+ 517 oldseqNo = pis.seqNo();\n+ 518 }\n+ 519\n+520 void freeGlobalLookup()\n+ 521 {\n+ 522 delete globalLookup_;\n+ 523 globalLookup_=0;\n+ 524 }\n+ 525\n+526 const GlobalLookupIndexSet& globalLookup() const\n+ 527 {\n+ 528 assert(globalLookup_ != 0);\n+ 529 return *globalLookup_;\n+ 530 }\n+ 531\n+ 537 template\n+538 void project (T1& x) const\n+ 539 {\n+ 540 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)\n+ 541 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)\n+ 542 x[i->local().local()] = 0;\n+ 543 }\n+ 544\n+554 OwnerOverlapCopyCommunication (MPI_Comm comm_,\n+ 555 SolverCategory::Category cat_ = SolverCategory::overlapping,\n+ 556 bool freecomm_ = false)\n+ 557 : comm(comm_), cc(comm_), pis(), ri(pis,pis,comm_),\n+ 558 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),\n+ 559 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt\n+(false),\n+ 560 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),\n+ 561 freecomm(freecomm_)\n+ 562 {}\n+ 563\n+572 OwnerOverlapCopyCommunication (SolverCategory::Category cat_ =\n+SolverCategory::overlapping)\n+ 573 : comm(MPI_COMM_WORLD), cc(MPI_COMM_WORLD), pis(), ri\n+(pis,pis,MPI_COMM_WORLD),\n+ 574 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),\n+ 575 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt\n+(false),\n+ 576 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),\n+freecomm(false)\n+ 577 {}\n+ 578\n+586 OwnerOverlapCopyCommunication (const IndexInfoFromGrid& indexinfo,\n+ 587 MPI_Comm comm_,\n+ 588 SolverCategory::Category cat_ = SolverCategory::overlapping,\n+ 589 bool freecomm_ = false)\n+ 590 : comm(comm_), cc(comm_), OwnerToAllInterfaceBuilt(false),\n+ 591 OwnerOverlapToAllInterfaceBuilt(false), OwnerCopyToAllInterfaceBuilt\n+(false),\n+ 592 OwnerCopyToOwnerCopyInterfaceBuilt(false), CopyToAllInterfaceBuilt(false),\n+ 593 globalLookup_(0), category_(cat_), freecomm(freecomm_)\n+ 594 {\n+ 595 // set up an ISTL index set\n+ 596 pis.beginResize();\n+ 597 for (localindex_iterator i=indexinfo.localIndices().begin();\n+i!=indexinfo.localIndices().end(); ++i)\n+ 598 {\n+ 599 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)\n+ 600 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n+owner,true));\n+ 601 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)\n+ 602 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n+overlap,true));\n+ 603 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)\n+ 604 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n+copy,true));\n+ 605 // std::cout << cc.rank() << \": adding index \" << std::get<0>(*i) << \" \"\n+<< std::get<1>(*i) << \" \" << std::get<2>(*i) << std::endl;\n+ 606 }\n+ 607 pis.endResize();\n+ 608\n+ 609 // build remote indices WITHOUT communication\n+ 610 // std::cout << cc.rank() << \": build remote indices\" << std::endl;\n+ 611 ri.setIndexSets(pis,pis,cc);\n+ 612 if (indexinfo.remoteIndices().size()>0)\n+ 613 {\n+ 614 remoteindex_iterator i=indexinfo.remoteIndices().begin();\n+ 615 int p = std::get<0>(*i);\n+ 616 RILM modifier = ri.template getModifier(p);\n+ 617 typename PIS::const_iterator pi=pis.begin();\n+ 618 for ( ; i!=indexinfo.remoteIndices().end(); ++i)\n+ 619 {\n+ 620 // handle processor change\n+ 621 if (p!=std::get<0>(*i))\n+ 622 {\n+ 623 p = std::get<0>(*i);\n+ 624 modifier = ri.template getModifier(p);\n+ 625 pi=pis.begin();\n+ 626 }\n+ 627\n+ 628 // position to correct entry in parallel index set\n+ 629 while (pi->global()!=std::get<1>(*i) && pi!=pis.end())\n+ 630 ++pi;\n+ 631 if (pi==pis.end())\n+ 632 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n+index set\");\n+ 633\n+ 634 // insert entry\n+ 635 // std::cout << cc.rank() << \": adding remote index \" << std::get<0>(*i)\n+<< \" \" << std::get<1>(*i) << \" \" << std::get<2>(*i) << std::endl;\n+ 636 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)\n+ 637 modifier.insert(RX(OwnerOverlapCopyAttributeSet::owner,&(*pi)));\n+ 638 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)\n+ 639 modifier.insert(RX(OwnerOverlapCopyAttributeSet::overlap,&(*pi)));\n+ 640 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)\n+ 641 modifier.insert(RX(OwnerOverlapCopyAttributeSet::copy,&(*pi)));\n+ 642 }\n+ 643 }else{\n+ 644 // Force remote indices to be synced!\n+ 645 ri.template getModifier(0);\n+ 646 }\n+ 647 }\n+ 648\n+ 649 // destructor: free memory in some objects\n+650 ~OwnerOverlapCopyCommunication ()\n+ 651 {\n+ 652 ri.free();\n+ 653 if (OwnerToAllInterfaceBuilt) OwnerToAllInterface.free();\n+ 654 if (OwnerOverlapToAllInterfaceBuilt) OwnerOverlapToAllInterface.free();\n+ 655 if (OwnerCopyToAllInterfaceBuilt) OwnerCopyToAllInterface.free();\n+ 656 if (OwnerCopyToOwnerCopyInterfaceBuilt) OwnerCopyToOwnerCopyInterface.free\n+();\n+ 657 if (CopyToAllInterfaceBuilt) CopyToAllInterface.free();\n+ 658 if (globalLookup_) delete globalLookup_;\n+ 659 if (freecomm==true)\n+ 660 if(comm!=MPI_COMM_NULL)\n+ 661 {\n+ 662#ifdef MPI_2\n+ 663 // If it is possible to query whether MPI_Finalize\n+ 664 // was called, only free the communicator before\n+ 665 // calling MPI_Finalize.\n+ 666 int wasFinalized = 0;\n+ 667 MPI_Finalized( &wasFinalized );\n+ 668 if(!wasFinalized)\n+ 669#endif\n+ 670 MPI_Comm_free(&comm);\n+ 671 }\n+ 672 }\n+ 673\n+ 674 private:\n+ 675 OwnerOverlapCopyCommunication (const OwnerOverlapCopyCommunication&)\n+ 676 {}\n+ 677 MPI_Comm comm;\n+ 678 Communication cc;\n+ 679 PIS pis;\n+ 680 RI ri;\n+ 681 mutable IF OwnerToAllInterface;\n+ 682 mutable bool OwnerToAllInterfaceBuilt;\n+ 683 mutable IF OwnerOverlapToAllInterface;\n+ 684 mutable bool OwnerOverlapToAllInterfaceBuilt;\n+ 685 mutable IF OwnerCopyToAllInterface;\n+ 686 mutable bool OwnerCopyToAllInterfaceBuilt;\n+ 687 mutable IF OwnerCopyToOwnerCopyInterface;\n+ 688 mutable bool OwnerCopyToOwnerCopyInterfaceBuilt;\n+ 689 mutable IF CopyToAllInterface;\n+ 690 mutable bool CopyToAllInterfaceBuilt;\n+ 691 mutable std::vector mask;\n+ 692 int oldseqNo;\n+ 693 GlobalLookupIndexSet* globalLookup_;\n+ 694 const SolverCategory::Category category_;\n+ 695 bool freecomm;\n+ 696 };\n+ 697\n+ 698#endif\n+ 699\n+ 700\n+ 703} // end namespace\n+ 704\n+ 705#endif\n+testRedistributed\n+void testRedistributed(int s)\n+matrixmarket.hh\n+Provides classes for reading and writing MatrixMarket Files with an extension\n+for parallel matrices.\n+istlexception.hh\n+solvercategory.hh\n Dune\n Definition: allocator.hh:11\n-Dune::blockLevel\n-constexpr std::size_t blockLevel()\n-Determine the block level of a possibly nested vector/matrix type.\n-Definition: blocklevel.hh:176\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::UnsupportedType\n-Definition: solverregistry.hh:77\n-Dune::InvalidSolverFactoryConfiguration\n-Definition: solverregistry.hh:79\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::OwnerOverlapCopyAttributeSet\n+Attribute set for overlapping Schwarz.\n+Definition: owneroverlapcopy.hh:59\n+Dune::OwnerOverlapCopyAttributeSet::AttributeSet\n+AttributeSet\n+Definition: owneroverlapcopy.hh:60\n+Dune::OwnerOverlapCopyAttributeSet::owner\n+@ owner\n+Definition: owneroverlapcopy.hh:61\n+Dune::OwnerOverlapCopyAttributeSet::copy\n+@ copy\n+Definition: owneroverlapcopy.hh:61\n+Dune::OwnerOverlapCopyAttributeSet::overlap\n+@ overlap\n+Definition: owneroverlapcopy.hh:61\n+Dune::IndexInfoFromGrid\n+Information about the index distribution.\n+Definition: owneroverlapcopy.hh:78\n+Dune::IndexInfoFromGrid::IndexTripel\n+std::tuple< GlobalIdType, LocalIdType, int > IndexTripel\n+A triple describing a local index.\n+Definition: owneroverlapcopy.hh:92\n+Dune::IndexInfoFromGrid::addRemoteIndex\n+void addRemoteIndex(const RemoteIndexTripel &x)\n+Add a new remote index triple to the set of remote indices.\n+Definition: owneroverlapcopy.hh:120\n+Dune::IndexInfoFromGrid::GlobalIdType\n+G GlobalIdType\n+The type of the global index.\n+Definition: owneroverlapcopy.hh:81\n+Dune::IndexInfoFromGrid::localIndices\n+const std::set< IndexTripel > & localIndices() const\n+Get the set of indices local to the process.\n+Definition: owneroverlapcopy.hh:133\n+Dune::IndexInfoFromGrid::remoteIndices\n+const std::set< RemoteIndexTripel > & remoteIndices() const\n+Get the set of remote indices.\n+Definition: owneroverlapcopy.hh:142\n+Dune::IndexInfoFromGrid::LocalIdType\n+L LocalIdType\n+The type of the local index.\n+Definition: owneroverlapcopy.hh:84\n+Dune::IndexInfoFromGrid::clear\n+void clear()\n+Remove all indices from the sets.\n+Definition: owneroverlapcopy.hh:150\n+Dune::IndexInfoFromGrid::addLocalIndex\n+void addLocalIndex(const IndexTripel &x)\n+Add a new index triple to the set of local indices.\n+Definition: owneroverlapcopy.hh:106\n+Dune::IndexInfoFromGrid::RemoteIndexTripel\n+std::tuple< int, GlobalIdType, int > RemoteIndexTripel\n+A triple describing a remote index.\n+Definition: owneroverlapcopy.hh:99\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::CopySet\n+EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopySet\n+Definition: owneroverlapcopy.hh:195\n+Dune::OwnerOverlapCopyCommunication::globalLookup\n+const GlobalLookupIndexSet & globalLookup() const\n+Definition: owneroverlapcopy.hh:526\n+Dune::OwnerOverlapCopyCommunication::norm\n+FieldTraits< typenameT1::field_type >::real_type norm(const T1 &x) const\n+Compute the global Euclidean norm of a vector.\n+Definition: owneroverlapcopy.hh:425\n+Dune::OwnerOverlapCopyCommunication::buildOwnerOverlapToAllInterface\n+void buildOwnerOverlapToAllInterface() const\n+Definition: owneroverlapcopy.hh:233\n+Dune::OwnerOverlapCopyCommunication::PIS\n+Dune::ParallelIndexSet< GlobalIdType, LI, 512 > PIS\n+Definition: owneroverlapcopy.hh:188\n+Dune::OwnerOverlapCopyCommunication::buildOwnerCopyToAllInterface\n+void buildOwnerCopyToAllInterface() const\n+Definition: owneroverlapcopy.hh:254\n+Dune::OwnerOverlapCopyCommunication::buildOwnerCopyToOwnerCopyInterface\n+void buildOwnerCopyToOwnerCopyInterface() const\n+Definition: owneroverlapcopy.hh:266\n+Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n+OwnerOverlapCopyCommunication(const IndexInfoFromGrid< GlobalIdType,\n+LocalIdType > &indexinfo, MPI_Comm comm_, SolverCategory::Category\n+cat_=SolverCategory::overlapping, bool freecomm_=false)\n+Constructor.\n+Definition: owneroverlapcopy.hh:586\n+Dune::OwnerOverlapCopyCommunication::category\n+SolverCategory::Category category() const\n+Get Solver Category.\n+Definition: owneroverlapcopy.hh:295\n+Dune::OwnerOverlapCopyCommunication::addOwnerCopyToOwnerCopy\n+void addOwnerCopyToOwnerCopy(const T &source, T &dest) const\n+Communicate values from owner and copy data points to owner and copy data\n+points and add them to thos...\n+Definition: owneroverlapcopy.hh:379\n+Dune::OwnerOverlapCopyCommunication::buildCopyToAllInterface\n+void buildCopyToAllInterface() const\n+Definition: owneroverlapcopy.hh:279\n+Dune::OwnerOverlapCopyCommunication::CopyFlags\n+Dune::EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopyFlags\n+Definition: owneroverlapcopy.hh:446\n+Dune::OwnerOverlapCopyCommunication::remoteIndices\n+RemoteIndices & remoteIndices()\n+Get the underlying remote indices.\n+Definition: owneroverlapcopy.hh:490\n+Dune::OwnerOverlapCopyCommunication::indexSet\n+const ParallelIndexSet & indexSet() const\n+Get the underlying parallel index set.\n+Definition: owneroverlapcopy.hh:462\n+Dune::OwnerOverlapCopyCommunication::RI\n+Dune::RemoteIndices< PIS > RI\n+Definition: owneroverlapcopy.hh:189\n+Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n+void buildGlobalLookup(std::size_t size)\n+Definition: owneroverlapcopy.hh:508\n+Dune::OwnerOverlapCopyCommunication::addOwnerOverlapToAll\n+void addOwnerOverlapToAll(const T &source, T &dest) const\n+Communicate values from owner data points to all other data points and add them\n+to those values.\n+Definition: owneroverlapcopy.hh:345\n+Dune::OwnerOverlapCopyCommunication::RemoteIndices\n+Dune::RemoteIndices< PIS > RemoteIndices\n+The type of the remote indices.\n+Definition: owneroverlapcopy.hh:452\n+Dune::OwnerOverlapCopyCommunication::project\n+void project(T1 &x) const\n+Set vector to zero at copy dofs.\n+Definition: owneroverlapcopy.hh:538\n+Dune::OwnerOverlapCopyCommunication::AllSet\n+Dune::AllSet< AttributeSet > AllSet\n+Definition: owneroverlapcopy.hh:197\n+Dune::OwnerOverlapCopyCommunication::OwnerOverlapSet\n+Combine< EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner >,\n+EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::overlap >, AttributeSet >\n+OwnerOverlapSet\n+Definition: owneroverlapcopy.hh:196\n+Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n+void copyCopyToAll(const T &source, T &dest) const\n+Communicate values from copy data points to all other data points.\n+Definition: owneroverlapcopy.hh:328\n+Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n+Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n+The type of the reverse lookup of indices.\n+Definition: owneroverlapcopy.hh:456\n+Dune::OwnerOverlapCopyCommunication::IF\n+Dune::Interface IF\n+Definition: owneroverlapcopy.hh:193\n+Dune::OwnerOverlapCopyCommunication::~OwnerOverlapCopyCommunication\n+~OwnerOverlapCopyCommunication()\n+Definition: owneroverlapcopy.hh:650\n+Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n+void buildGlobalLookup()\n+Definition: owneroverlapcopy.hh:495\n+Dune::OwnerOverlapCopyCommunication::BC\n+Dune::BufferedCommunicator BC\n+Definition: owneroverlapcopy.hh:192\n+Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n+OwnerOverlapCopyCommunication(MPI_Comm comm_, SolverCategory::Category\n+cat_=SolverCategory::overlapping, bool freecomm_=false)\n+Construct the communication without any indices.\n+Definition: owneroverlapcopy.hh:554\n+Dune::OwnerOverlapCopyCommunication::indexSet\n+ParallelIndexSet & indexSet()\n+Get the underlying parallel index set.\n+Definition: owneroverlapcopy.hh:480\n+Dune::OwnerOverlapCopyCommunication::dot\n+void dot(const T1 &x, const T1 &y, T2 &result) const\n+Compute a global dot product of two vectors.\n+Definition: owneroverlapcopy.hh:398\n+Dune::OwnerOverlapCopyCommunication::communicator\n+const Communication< MPI_Comm > & communicator() const\n+Definition: owneroverlapcopy.hh:299\n+Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n+OwnerOverlapCopyCommunication(SolverCategory::Category cat_=SolverCategory::\n+overlapping)\n+Construct the communication without any indices using MPI_COMM_WORLD.\n+Definition: owneroverlapcopy.hh:572\n+Dune::OwnerOverlapCopyCommunication::OwnerSet\n+EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet\n+Definition: owneroverlapcopy.hh:194\n+Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n+void copyOwnerToAll(const T &source, T &dest) const\n+Communicate values from owner data points to all other data points.\n+Definition: owneroverlapcopy.hh:311\n+Dune::OwnerOverlapCopyCommunication::remoteIndices\n+const RemoteIndices & remoteIndices() const\n+Get the underlying remote indices.\n+Definition: owneroverlapcopy.hh:471\n+Dune::OwnerOverlapCopyCommunication::loadMatrixMarket\n+friend void loadMatrixMarket(M &, const std::string &,\n+OwnerOverlapCopyCommunication< G, L > &, bool)\n+Load a parallel matrix/vector stored in matrix market format.\n+Definition: matrixmarket.hh:1269\n+Dune::OwnerOverlapCopyCommunication::RX\n+RI::RemoteIndex RX\n+Definition: owneroverlapcopy.hh:191\n+Dune::OwnerOverlapCopyCommunication::addOwnerCopyToAll\n+void addOwnerCopyToAll(const T &source, T &dest) const\n+Communicate values from owner and copy data points to all other data points and\n+add them to those val...\n+Definition: owneroverlapcopy.hh:362\n+Dune::OwnerOverlapCopyCommunication::freeGlobalLookup\n+void freeGlobalLookup()\n+Definition: owneroverlapcopy.hh:520\n+Dune::OwnerOverlapCopyCommunication::RILM\n+Dune::RemoteIndexListModifier< PIS, typename RI::Allocator, false > RILM\n+Definition: owneroverlapcopy.hh:190\n+Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n+Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n+The type of the parallel index set.\n+Definition: owneroverlapcopy.hh:449\n+Dune::OwnerOverlapCopyCommunication::buildOwnerToAllInterface\n+void buildOwnerToAllInterface() const\n+Definition: owneroverlapcopy.hh:244\n+Dune::OwnerOverlapCopyCommunication::CopyGatherScatter\n+gather/scatter callback for communcation\n+Definition: owneroverlapcopy.hh:204\n+Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::gather\n+static V gather(const T &a, std::size_t i)\n+Definition: owneroverlapcopy.hh:207\n+Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::scatter\n+static void scatter(T &a, V v, std::size_t i)\n+Definition: owneroverlapcopy.hh:212\n+Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::V\n+CommPolicy< T >::IndexedType V\n+Definition: owneroverlapcopy.hh:205\n+Dune::OwnerOverlapCopyCommunication::AddGatherScatter\n+Definition: owneroverlapcopy.hh:219\n+Dune::OwnerOverlapCopyCommunication::AddGatherScatter::V\n+CommPolicy< T >::IndexedType V\n+Definition: owneroverlapcopy.hh:220\n+Dune::OwnerOverlapCopyCommunication::AddGatherScatter::gather\n+static V gather(const T &a, std::size_t i)\n+Definition: owneroverlapcopy.hh:222\n+Dune::OwnerOverlapCopyCommunication::AddGatherScatter::scatter\n+static void scatter(T &a, V v, std::size_t i)\n+Definition: owneroverlapcopy.hh:227\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::overlapping\n+@ overlapping\n+Category for overlapping solvers.\n+Definition: solvercategory.hh:29\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00056.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00056.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvers.hh File Reference\n+dune-istl: solver.hh File Reference\n \n \n \n \n \n \n \n@@ -64,111 +64,70 @@\n \n
    \n
    \n \n+ \n
    \n
    \n \n-

    Implementations of the inverse operator interface. \n+

    Define general, extensible interface for inverse operators. \n More...

    \n-
    #include <array>
    \n-#include <cmath>
    \n-#include <complex>
    \n-#include <iostream>
    \n-#include <memory>
    \n-#include <type_traits>
    \n-#include <vector>
    \n+
    #include <iomanip>
    \n+#include <ostream>
    \n+#include <string>
    \n+#include <functional>
    \n #include <dune/common/exceptions.hh>
    \n-#include <dune/common/math.hh>
    \n+#include <dune/common/shared_ptr.hh>
    \n #include <dune/common/simd/io.hh>
    \n #include <dune/common/simd/simd.hh>
    \n-#include <dune/common/std/type_traits.hh>
    \n+#include <dune/common/parametertree.hh>
    \n #include <dune/common/timer.hh>
    \n-#include <dune/istl/allocator.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/eigenvalue/arpackpp.hh>
    \n-#include <dune/istl/istlexception.hh>
    \n-#include <dune/istl/operators.hh>
    \n-#include <dune/istl/preconditioner.hh>
    \n-#include <dune/istl/scalarproducts.hh>
    \n-#include <dune/istl/solver.hh>
    \n-#include <dune/istl/solverregistry.hh>
    \n+#include "solvertype.hh"
    \n+#include "preconditioner.hh"
    \n+#include "operators.hh"
    \n+#include "scalarproducts.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::LoopSolver< X >
     Preconditioned loop solver. More...
    struct  Dune::InverseOperatorResult
     Statistics about the application of an inverse operator. More...
     
    class  Dune::GradientSolver< X >
     gradient method More...
    class  Dune::InverseOperator< X, Y >
     Abstract base class for all solvers. More...
     
    class  Dune::CGSolver< X >
     conjugate gradient method More...
    class  Dune::IterativeSolver< X, Y >
     Base class for all implementations of iterative solvers. More...
     
    class  Dune::BiCGSTABSolver< X >
     Bi-conjugate Gradient Stabilized (BiCG-STAB) More...
    class  Dune::IterativeSolver< X, Y >::Iteration< CountType >
     Class for controlling iterative methods. More...
     
    class  Dune::MINRESSolver< X >
     Minimal Residual Method (MINRES) More...
    class  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >
     Helper class for notifying a DUNE-ISTL linear solver about a change of the iteration matrix object in a unified way, i.e. independent from the solver's type (direct/iterative). More...
     
    class  Dune::RestartedGMResSolver< X, Y, F >
     implements the Generalized Minimal Residual (GMRes) method More...
    struct  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< is_direct_solver, Dummy >
     Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTABSolver. More...
     
    class  Dune::RestartedFlexibleGMResSolver< X, Y, F >
     implements the Flexible Generalized Minimal Residual (FGMRes) method (right preconditioned) More...
     
    class  Dune::GeneralizedPCGSolver< X >
     Generalized preconditioned conjugate gradient solver. More...
     
    class  Dune::RestartedFCGSolver< X >
     Accelerated flexible conjugate gradient method. More...
     
    class  Dune::CompleteFCGSolver< X >
     Complete flexible conjugate gradient method. More...
    struct  Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< true, Dummy >
     Implementation that works together with direct ISTL solvers, e.g. Dune::SuperLU or Dune::UMFPack. More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("loopsolver", defaultIterativeSolverCreator< Dune::LoopSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("gradientsolver", defaultIterativeSolverCreator< Dune::GradientSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("cgsolver", defaultIterativeSolverCreator< Dune::CGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("bicgstabsolver", defaultIterativeSolverCreator< Dune::BiCGSTABSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("minressolver", defaultIterativeSolverCreator< Dune::MINRESSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedgmressolver", defaultIterativeSolverCreator< Dune::RestartedGMResSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedflexiblegmressolver", defaultIterativeSolverCreator< Dune::RestartedFlexibleGMResSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("generalizedpcgsolver", defaultIterativeSolverCreator< Dune::GeneralizedPCGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedfcgsolver", defaultIterativeSolverCreator< Dune::RestartedFCGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("completefcgsolver", defaultIterativeSolverCreator< Dune::CompleteFCGSolver >())
     
    \n

    Detailed Description

    \n-

    Implementations of the inverse operator interface.

    \n-

    This file provides various preconditioned Krylov methods.

    \n+

    Define general, extensible interface for inverse operators.

    \n+

    Implementation here covers only inversion of linear operators, but the implementation might be used for nonlinear operators as well.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,106 +4,64 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-solvers.hh File Reference\n+Classes | Namespaces\n+solver.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers\n-Implementations of the inverse operator interface. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Define general, extensible interface for inverse operators. More...\n+#include \n+#include \n+#include \n+#include \n #include \n-#include \n+#include \n #include \n #include \n-#include \n+#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \"solvertype.hh\"\n+#include \"preconditioner.hh\"\n+#include \"operators.hh\"\n+#include \"scalarproducts.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::LoopSolver<_X_>\n-\u00a0 Preconditioned loop solver. More...\n+struct \u00a0Dune::InverseOperatorResult\n+\u00a0 Statistics about the application of an inverse operator. More...\n \u00a0\n-class \u00a0Dune::GradientSolver<_X_>\n-\u00a0 gradient method More...\n+ class \u00a0Dune::InverseOperator<_X,_Y_>\n+\u00a0 Abstract base class for all solvers. More...\n \u00a0\n-class \u00a0Dune::CGSolver<_X_>\n-\u00a0 conjugate gradient method More...\n+ class \u00a0Dune::IterativeSolver<_X,_Y_>\n+\u00a0 Base class for all implementations of iterative solvers. More...\n \u00a0\n-class \u00a0Dune::BiCGSTABSolver<_X_>\n-\u00a0 Bi-conjugate Gradient Stabilized (BiCG-STAB) More...\n-\u00a0\n-class \u00a0Dune::MINRESSolver<_X_>\n-\u00a0 Minimal Residual Method (MINRES) More...\n-\u00a0\n-class \u00a0Dune::RestartedGMResSolver<_X,_Y,_F_>\n-\u00a0 implements the Generalized Minimal Residual (GMRes) method More...\n-\u00a0\n-class \u00a0Dune::RestartedFlexibleGMResSolver<_X,_Y,_F_>\n-\u00a0 implements the Flexible Generalized Minimal Residual (FGMRes) method\n- (right preconditioned) More...\n-\u00a0\n-class \u00a0Dune::GeneralizedPCGSolver<_X_>\n-\u00a0 Generalized preconditioned conjugate gradient solver. More...\n-\u00a0\n-class \u00a0Dune::RestartedFCGSolver<_X_>\n-\u00a0 Accelerated flexible conjugate gradient method. More...\n-\u00a0\n-class \u00a0Dune::CompleteFCGSolver<_X_>\n-\u00a0 Complete flexible conjugate gradient method. More...\n+ class \u00a0Dune::IterativeSolver<_X,_Y_>::Iteration<_CountType_>\n+\u00a0 Class for controlling iterative methods. More...\n+\u00a0\n+ class \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>\n+ Helper class for notifying a DUNE-ISTL linear solver about a change of\n+\u00a0 the iteration matrix object in a unified way, i.e. independent from\n+ the solver's type (direct/iterative). More...\n+\u00a0\n+struct \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>::Implementation<\n+ is_direct_solver,_Dummy_>\n+\u00a0 Implementation that works together with iterative ISTL solvers, e.g.\n+ Dune::CGSolver or Dune::BiCGSTABSolver. More...\n+\u00a0\n+struct \u00a0Dune::SolverHelper<_ISTLLinearSolver,_BCRSMatrix_>::Implementation<\n+ true,_Dummy_>\n+\u00a0 Implementation that works together with direct ISTL solvers, e.g.\n+ Dune::SuperLU or Dune::UMFPack. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"loopsolver\",\n- defaultIterativeSolverCreator< Dune::LoopSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"gradientsolver\",\n- defaultIterativeSolverCreator< Dune::GradientSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"cgsolver\",\n- defaultIterativeSolverCreator< Dune::CGSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"bicgstabsolver\",\n- defaultIterativeSolverCreator< Dune::BiCGSTABSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"minressolver\",\n- defaultIterativeSolverCreator< Dune::MINRESSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedgmressolver\",\n- defaultIterativeSolverCreator< Dune::RestartedGMResSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedflexiblegmressolver\",\n- defaultIterativeSolverCreator< Dune::RestartedFlexibleGMResSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"generalizedpcgsolver\",\n- defaultIterativeSolverCreator< Dune::GeneralizedPCGSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedfcgsolver\",\n- defaultIterativeSolverCreator< Dune::RestartedFCGSolver >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"completefcgsolver\",\n- defaultIterativeSolverCreator< Dune::CompleteFCGSolver >())\n-\u00a0\n ***** Detailed Description *****\n-Implementations of the inverse operator interface.\n-This file provides various preconditioned Krylov methods.\n+Define general, extensible interface for inverse operators.\n+Implementation here covers only inversion of linear operators, but the\n+implementation might be used for nonlinear operators as well.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00056_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00056_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvers.hh Source File\n+dune-istl: solver.hh Source File\n \n \n \n \n \n \n \n@@ -62,1584 +62,439 @@\n \n
    \n \n
    \n
    \n
    \n-
    solvers.hh
    \n+
    solver.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n
    5
    \n-
    6#ifndef DUNE_ISTL_SOLVERS_HH
    \n-
    7#define DUNE_ISTL_SOLVERS_HH
    \n+
    6#ifndef DUNE_ISTL_SOLVER_HH
    \n+
    7#define DUNE_ISTL_SOLVER_HH
    \n
    8
    \n-
    9#include <array>
    \n-
    10#include <cmath>
    \n-
    11#include <complex>
    \n-
    12#include <iostream>
    \n-
    13#include <memory>
    \n-
    14#include <type_traits>
    \n-
    15#include <vector>
    \n-
    16
    \n-
    17#include <dune/common/exceptions.hh>
    \n-
    18#include <dune/common/math.hh>
    \n-
    19#include <dune/common/simd/io.hh>
    \n-
    20#include <dune/common/simd/simd.hh>
    \n-
    21#include <dune/common/std/type_traits.hh>
    \n-
    22#include <dune/common/timer.hh>
    \n-
    23
    \n-\n-\n-\n-\n-\n-\n-\n-
    31#include <dune/istl/solver.hh>
    \n-\n-
    33
    \n-
    34namespace Dune {
    \n-
    46 //=====================================================================
    \n-
    47 // Implementation of this interface
    \n-
    48 //=====================================================================
    \n-
    49
    \n-
    58 template<class X>
    \n-
    59 class LoopSolver : public IterativeSolver<X,X> {
    \n-
    60 public:
    \n-\n-\n-\n-\n+
    9#include <iomanip>
    \n+
    10#include <ostream>
    \n+
    11#include <string>
    \n+
    12#include <functional>
    \n+
    13
    \n+
    14#include <dune/common/exceptions.hh>
    \n+
    15#include <dune/common/shared_ptr.hh>
    \n+
    16#include <dune/common/simd/io.hh>
    \n+
    17#include <dune/common/simd/simd.hh>
    \n+
    18#include <dune/common/parametertree.hh>
    \n+
    19#include <dune/common/timer.hh>
    \n+
    20
    \n+
    21#include "solvertype.hh"
    \n+
    22#include "preconditioner.hh"
    \n+
    23#include "operators.hh"
    \n+
    24#include "scalarproducts.hh"
    \n+
    25
    \n+
    26namespace Dune
    \n+
    27{
    \n+\n+
    48 {
    \n+\n+
    51 {
    \n+
    52 clear();
    \n+
    53 }
    \n+
    54
    \n+
    56 void clear ()
    \n+
    57 {
    \n+
    58 iterations = 0;
    \n+
    59 reduction = 0;
    \n+
    60 converged = false;
    \n+
    61 conv_rate = 1;
    \n+
    62 elapsed = 0;
    \n+\n+
    64 }
    \n
    65
    \n-
    66 // copy base class constructors
    \n-\n+\n
    68
    \n-
    69 // don't shadow four-argument version of apply defined in the base class
    \n-
    70 using IterativeSolver<X,X>::apply;
    \n+
    70 double reduction;
    \n
    71
    \n-
    73 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    74 {
    \n-
    75 Iteration iteration(*this, res);
    \n-
    76 _prec->pre(x,b);
    \n+\n+
    74
    \n+
    76 double conv_rate;
    \n
    77
    \n-
    78 // overwrite b with defect
    \n-
    79 _op->applyscaleadd(-1,x,b);
    \n+
    79 double condition_estimate = -1;
    \n
    80
    \n-
    81 // compute norm, \\todo parallelization
    \n-
    82 real_type def = _sp->norm(b);
    \n-
    83 if(iteration.step(0, def)){
    \n-
    84 _prec->post(x);
    \n-
    85 return;
    \n-
    86 }
    \n-
    87 // prepare preconditioner
    \n-
    88
    \n-
    89 // allocate correction vector
    \n-
    90 X v(x);
    \n-
    91
    \n-
    92 // iteration loop
    \n-
    93 int i=1;
    \n-
    94 for ( ; i<=_maxit; i++ )
    \n-
    95 {
    \n-
    96 v = 0; // clear correction
    \n-
    97 _prec->apply(v,b); // apply preconditioner
    \n-
    98 x += v; // update solution
    \n-
    99 _op->applyscaleadd(-1,v,b); // update defect
    \n-
    100 def=_sp->norm(b); // comp defect norm
    \n-
    101 if(iteration.step(i, def))
    \n-
    102 break;
    \n-
    103 }
    \n-
    104
    \n-
    105 // postprocess preconditioner
    \n-
    106 _prec->post(x);
    \n-
    107 }
    \n-
    108
    \n-
    109 protected:
    \n-
    110 using IterativeSolver<X,X>::_op;
    \n-
    111 using IterativeSolver<X,X>::_prec;
    \n-
    112 using IterativeSolver<X,X>::_sp;
    \n-\n-
    114 using IterativeSolver<X,X>::_maxit;
    \n-
    115 using IterativeSolver<X,X>::_verbose;
    \n-\n-
    117 };
    \n-
    118 DUNE_REGISTER_ITERATIVE_SOLVER("loopsolver", defaultIterativeSolverCreator<Dune::LoopSolver>());
    \n-
    119
    \n-
    120
    \n-
    121 // all these solvers are taken from the SUMO library
    \n-
    123 template<class X>
    \n-
    124 class GradientSolver : public IterativeSolver<X,X> {
    \n-
    125 public:
    \n-\n-\n-\n-
    129 using typename IterativeSolver<X,X>::real_type;
    \n-
    130
    \n-
    131 // copy base class constructors
    \n-\n-
    133
    \n-
    134 // don't shadow four-argument version of apply defined in the base class
    \n-
    135 using IterativeSolver<X,X>::apply;
    \n-
    136
    \n-
    142 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    143 {
    \n-
    144 Iteration iteration(*this, res);
    \n-
    145 _prec->pre(x,b); // prepare preconditioner
    \n-
    146
    \n-
    147 _op->applyscaleadd(-1,x,b); // overwrite b with defec
    \n-
    148
    \n-
    149 real_type def = _sp->norm(b); // compute norm
    \n-
    150 if(iteration.step(0, def)){
    \n-
    151 _prec->post(x);
    \n-
    152 return;
    \n-
    153 }
    \n+
    82 double elapsed;
    \n+
    83 };
    \n+
    84
    \n+
    85
    \n+
    86 //=====================================================================
    \n+
    98 template<class X, class Y>
    \n+\n+
    100 public:
    \n+
    102 typedef X domain_type;
    \n+
    103
    \n+
    105 typedef Y range_type;
    \n+
    106
    \n+
    108 typedef typename X::field_type field_type;
    \n+
    109
    \n+
    111 typedef typename FieldTraits<field_type>::real_type real_type;
    \n+
    112
    \n+
    114 typedef Simd::Scalar<real_type> scalar_real_type;
    \n+
    115
    \n+
    128 virtual void apply (X& x, Y& b, InverseOperatorResult& res) = 0;
    \n+
    129
    \n+
    143 virtual void apply (X& x, Y& b, double reduction, InverseOperatorResult& res) = 0;
    \n+
    144
    \n+\n+
    147#ifdef DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n+
    148 {
    \n+
    149 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n+
    150 }
    \n+
    151#else
    \n+
    152 = 0;
    \n+
    153#endif
    \n
    154
    \n-
    155 X p(x); // create local vectors
    \n-
    156 X q(b);
    \n+
    156 virtual ~InverseOperator () {}
    \n
    157
    \n-
    158 int i=1; // loop variables
    \n-
    159 field_type lambda;
    \n-
    160 for ( ; i<=_maxit; i++ )
    \n-
    161 {
    \n-
    162 p = 0; // clear correction
    \n-
    163 _prec->apply(p,b); // apply preconditioner
    \n-
    164 _op->apply(p,q); // q=Ap
    \n-
    165 auto alpha = _sp->dot(q,p);
    \n-
    166 lambda = Simd::cond(def==field_type(0.),
    \n-
    167 field_type(0.), // no need for minimization if def is already 0
    \n-
    168 _sp->dot(p,b)/alpha); // minimization
    \n-
    169 x.axpy(lambda,p); // update solution
    \n-
    170 b.axpy(-lambda,q); // update defect
    \n-
    171
    \n-
    172 def =_sp->norm(b); // comp defect norm
    \n-
    173 if(iteration.step(i, def))
    \n-
    174 break;
    \n-
    175 }
    \n-
    176 // postprocess preconditioner
    \n-
    177 _prec->post(x);
    \n-
    178 }
    \n-
    179
    \n-
    180 protected:
    \n-
    181 using IterativeSolver<X,X>::_op;
    \n-
    182 using IterativeSolver<X,X>::_prec;
    \n-
    183 using IterativeSolver<X,X>::_sp;
    \n-\n-
    185 using IterativeSolver<X,X>::_maxit;
    \n-
    186 using IterativeSolver<X,X>::_verbose;
    \n-\n-
    188 };
    \n-
    189 DUNE_REGISTER_ITERATIVE_SOLVER("gradientsolver", defaultIterativeSolverCreator<Dune::GradientSolver>());
    \n-
    190
    \n-
    192 template<class X>
    \n-
    193 class CGSolver : public IterativeSolver<X,X> {
    \n-
    194 public:
    \n-\n-\n-\n-
    198 using typename IterativeSolver<X,X>::real_type;
    \n-
    199
    \n-
    200 // copy base class constructors
    \n-\n-
    202
    \n-
    203 private:
    \n-\n-
    205
    \n-
    206 protected:
    \n-
    207
    \n-
    208 static constexpr bool enableConditionEstimate = (std::is_same_v<field_type,float> || std::is_same_v<field_type,double>);
    \n-
    209
    \n-
    210 public:
    \n-
    211
    \n-
    212 // don't shadow four-argument version of apply defined in the base class
    \n-
    213 using IterativeSolver<X,X>::apply;
    \n-
    214
    \n-\n-
    223 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate) : IterativeSolver<X,X>(op, prec, reduction, maxit, verbose),
    \n-
    224 condition_estimate_(condition_estimate)
    \n-
    225 {
    \n-
    226 if (condition_estimate && !enableConditionEstimate) {
    \n-
    227 condition_estimate_ = false;
    \n-
    228 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n-
    229 }
    \n-
    230 }
    \n-
    231
    \n-\n-
    240 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate) : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose),
    \n-
    241 condition_estimate_(condition_estimate)
    \n-
    242 {
    \n-
    243 if (condition_estimate && !(std::is_same<field_type,float>::value || std::is_same<field_type,double>::value)) {
    \n-
    244 condition_estimate_ = false;
    \n-
    245 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n-
    246 }
    \n-
    247 }
    \n-
    248
    \n-
    256 CGSolver (std::shared_ptr<const LinearOperator<X,X>> op, std::shared_ptr<ScalarProduct<X>> sp,
    \n-
    257 std::shared_ptr<Preconditioner<X,X>> prec,
    \n-
    258 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    \n-
    259 : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose),
    \n-
    260 condition_estimate_(condition_estimate)
    \n-
    261 {
    \n-
    262 if (condition_estimate && !(std::is_same<field_type,float>::value || std::is_same<field_type,double>::value)) {
    \n-
    263 condition_estimate_ = false;
    \n-
    264 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n-
    265 }
    \n-
    266 }
    \n-
    267
    \n-
    279 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    280 {
    \n-
    281 Iteration iteration(*this,res);
    \n-
    282 _prec->pre(x,b); // prepare preconditioner
    \n-
    283
    \n-
    284 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n-
    285
    \n-
    286 real_type def = _sp->norm(b); // compute norm
    \n-
    287 if(iteration.step(0, def)){
    \n-
    288 _prec->post(x);
    \n-
    289 return;
    \n-
    290 }
    \n-
    291
    \n-
    292 X p(x); // the search direction
    \n-
    293 X q(x); // a temporary vector
    \n-
    294
    \n-
    295 // Remember lambda and beta values for condition estimate
    \n-
    296 std::vector<real_type> lambdas(0);
    \n-
    297 std::vector<real_type> betas(0);
    \n-
    298
    \n-
    299 // some local variables
    \n-
    300 field_type rho,rholast,lambda,alpha,beta;
    \n-
    301
    \n-
    302 // determine initial search direction
    \n-
    303 p = 0; // clear correction
    \n-
    304 _prec->apply(p,b); // apply preconditioner
    \n-
    305 rholast = _sp->dot(p,b); // orthogonalization
    \n-
    306
    \n-
    307 // the loop
    \n-
    308 int i=1;
    \n-
    309 for ( ; i<=_maxit; i++ )
    \n-
    310 {
    \n-
    311 // minimize in given search direction p
    \n-
    312 _op->apply(p,q); // q=Ap
    \n-
    313 alpha = _sp->dot(p,q); // scalar product
    \n-
    314 lambda = Simd::cond(def==field_type(0.), field_type(0.), rholast/alpha); // minimization
    \n-
    315 if constexpr (enableConditionEstimate)
    \n-
    316 if (condition_estimate_)
    \n-
    317 lambdas.push_back(std::real(lambda));
    \n-
    318 x.axpy(lambda,p); // update solution
    \n-
    319 b.axpy(-lambda,q); // update defect
    \n-
    320
    \n-
    321 // convergence test
    \n-
    322 def=_sp->norm(b); // comp defect norm
    \n-
    323 if(iteration.step(i, def))
    \n-
    324 break;
    \n-
    325
    \n-
    326 // determine new search direction
    \n-
    327 q = 0; // clear correction
    \n-
    328 _prec->apply(q,b); // apply preconditioner
    \n-
    329 rho = _sp->dot(q,b); // orthogonalization
    \n-
    330 beta = Simd::cond(def==field_type(0.), field_type(0.), rho/rholast); // scaling factor
    \n-
    331 if constexpr (enableConditionEstimate)
    \n-
    332 if (condition_estimate_)
    \n-
    333 betas.push_back(std::real(beta));
    \n-
    334 p *= beta; // scale old search direction
    \n-
    335 p += q; // orthogonalization with correction
    \n-
    336 rholast = rho; // remember rho for recurrence
    \n-
    337 }
    \n-
    338
    \n-
    339 _prec->post(x); // postprocess preconditioner
    \n-
    340
    \n-
    341 if (condition_estimate_) {
    \n-
    342#if HAVE_ARPACKPP
    \n-
    343 if constexpr (enableConditionEstimate) {
    \n-
    344 using std::sqrt;
    \n-
    345
    \n-
    346 // Build T matrix which has extreme eigenvalues approximating
    \n-
    347 // those of the original system
    \n-
    348 // (see Y. Saad, Iterative methods for sparse linear systems)
    \n-
    349
    \n-\n-
    351
    \n-
    352 for (auto row = T.createbegin(); row != T.createend(); ++row) {
    \n-
    353 if (row.index() > 0)
    \n-
    354 row.insert(row.index()-1);
    \n-
    355 row.insert(row.index());
    \n-
    356 if (row.index() < T.N() - 1)
    \n-
    357 row.insert(row.index()+1);
    \n-
    358 }
    \n-
    359 for (int row = 0; row < i; ++row) {
    \n-
    360 if (row > 0) {
    \n-
    361 T[row][row-1] = sqrt(betas[row-1]) / lambdas[row-1];
    \n-
    362 }
    \n-
    363
    \n-
    364 T[row][row] = 1.0 / lambdas[row];
    \n-
    365 if (row > 0) {
    \n-
    366 T[row][row] += betas[row-1] / lambdas[row-1];
    \n-
    367 }
    \n+
    158 protected:
    \n+
    159 // spacing values
    \n+
    160 enum { iterationSpacing = 5 , normSpacing = 16 };
    \n+
    161
    \n+
    163 void printHeader(std::ostream& s) const
    \n+
    164 {
    \n+
    165 s << std::setw(iterationSpacing) << " Iter";
    \n+
    166 s << std::setw(normSpacing) << "Defect";
    \n+
    167 s << std::setw(normSpacing) << "Rate" << std::endl;
    \n+
    168 }
    \n+
    169
    \n+
    171 template <typename CountType, typename DataType>
    \n+
    172 void printOutput(std::ostream& s,
    \n+
    173 const CountType& iter,
    \n+
    174 const DataType& norm,
    \n+
    175 const DataType& norm_old) const
    \n+
    176 {
    \n+
    177 const DataType rate = norm/norm_old;
    \n+
    178 s << std::setw(iterationSpacing) << iter << " ";
    \n+
    179 s << std::setw(normSpacing) << Simd::io(norm) << " ";
    \n+
    180 s << std::setw(normSpacing) << Simd::io(rate) << std::endl;
    \n+
    181 }
    \n+
    182
    \n+
    184 template <typename CountType, typename DataType>
    \n+
    185 void printOutput(std::ostream& s,
    \n+
    186 const CountType& iter,
    \n+
    187 const DataType& norm) const
    \n+
    188 {
    \n+
    189 s << std::setw(iterationSpacing) << iter << " ";
    \n+
    190 s << std::setw(normSpacing) << Simd::io(norm) << std::endl;
    \n+
    191 }
    \n+
    192 };
    \n+
    193
    \n+
    202 template<class X, class Y>
    \n+
    203 class IterativeSolver : public InverseOperator<X,Y>{
    \n+
    204 public:
    \n+\n+\n+\n+
    208 using typename InverseOperator<X,Y>::real_type;
    \n+\n+
    210
    \n+
    230 IterativeSolver (const LinearOperator<X,Y>& op, Preconditioner<X,Y>& prec, scalar_real_type reduction, int maxit, int verbose) :
    \n+
    231 _op(stackobject_to_shared_ptr(op)),
    \n+
    232 _prec(stackobject_to_shared_ptr(prec)),
    \n+
    233 _sp(new SeqScalarProduct<X>),
    \n+
    234 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category(SolverCategory::sequential)
    \n+
    235 {
    \n+\n+
    237 DUNE_THROW(InvalidSolverCategory, "LinearOperator has to be sequential!");
    \n+\n+
    239 DUNE_THROW(InvalidSolverCategory, "Preconditioner has to be sequential!");
    \n+
    240 }
    \n+
    241
    \n+\n+
    263 scalar_real_type reduction, int maxit, int verbose) :
    \n+
    264 _op(stackobject_to_shared_ptr(op)),
    \n+
    265 _prec(stackobject_to_shared_ptr(prec)),
    \n+
    266 _sp(stackobject_to_shared_ptr(sp)),
    \n+
    267 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category(SolverCategory::category(op))
    \n+
    268 {
    \n+\n+
    270 DUNE_THROW(InvalidSolverCategory, "LinearOperator and Preconditioner must have the same SolverCategory!");
    \n+\n+
    272 DUNE_THROW(InvalidSolverCategory, "LinearOperator and ScalarProduct must have the same SolverCategory!");
    \n+
    273 }
    \n+
    274
    \n+
    290 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    291 IterativeSolver(op,std::make_shared<SeqScalarProduct<X>>(),prec,
    \n+
    292 configuration.get<real_type>("reduction"),
    \n+
    293 configuration.get<int>("maxit"),
    \n+
    294 configuration.get<int>("verbose"))
    \n+
    295 {}
    \n+
    296
    \n+
    313 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    314 IterativeSolver(op,sp,prec,
    \n+
    315 configuration.get<scalar_real_type>("reduction"),
    \n+
    316 configuration.get<int>("maxit"),
    \n+
    317 configuration.get<int>("verbose"))
    \n+
    318 {}
    \n+
    319
    \n+
    340 IterativeSolver (std::shared_ptr<const LinearOperator<X,Y>> op,
    \n+
    341 std::shared_ptr<const ScalarProduct<X>> sp,
    \n+
    342 std::shared_ptr<Preconditioner<X,Y>> prec,
    \n+
    343 scalar_real_type reduction, int maxit, int verbose) :
    \n+
    344 _op(op),
    \n+
    345 _prec(prec),
    \n+
    346 _sp(sp),
    \n+
    347 _reduction(reduction), _maxit(maxit), _verbose(verbose),
    \n+\n+
    349 {
    \n+\n+
    351 DUNE_THROW(InvalidSolverCategory, "LinearOperator and Preconditioner must have the same SolverCategory!");
    \n+\n+
    353 DUNE_THROW(InvalidSolverCategory, "LinearOperator and ScalarProduct must have the same SolverCategory!");
    \n+
    354 }
    \n+
    355
    \n+
    356 // #warning actually we want to have this as the default and just implement the second one
    \n+
    357 // //! \\copydoc InverseOperator::apply(X&,Y&,InverseOperatorResult&)
    \n+
    358 // virtual void apply (X& x, Y& b, InverseOperatorResult& res)
    \n+
    359 // {
    \n+
    360 // apply(x,b,_reduction,res);
    \n+
    361 // }
    \n+
    362
    \n+
    363#ifndef DOXYGEN
    \n+
    364 // make sure the three-argument apply from the base class does not get shadowed
    \n+
    365 // by the redefined four-argument version below
    \n+
    366 using InverseOperator<X,Y>::apply;
    \n+
    367#endif
    \n
    368
    \n-
    369 if (row < i - 1) {
    \n-
    370 T[row][row+1] = sqrt(betas[row]) / lambdas[row];
    \n-
    371 }
    \n-
    372 }
    \n-
    373
    \n-
    374 // Compute largest and smallest eigenvalue of T matrix and return as estimate
    \n-\n-
    376
    \n-
    377 real_type eps = 0.0;
    \n-
    378 COND_VEC eigv;
    \n-
    379 real_type min_eigv, max_eigv;
    \n-
    380 arpack.computeSymMinMagnitude (eps, eigv, min_eigv);
    \n-
    381 arpack.computeSymMaxMagnitude (eps, eigv, max_eigv);
    \n-
    382
    \n-
    383 res.condition_estimate = max_eigv / min_eigv;
    \n-
    384
    \n-
    385 if (this->_verbose > 0) {
    \n-
    386 std::cout << "Min eigv estimate: " << Simd::io(min_eigv) << '\\n';
    \n-
    387 std::cout << "Max eigv estimate: " << Simd::io(max_eigv) << '\\n';
    \n-
    388 std::cout << "Condition estimate: "
    \n-
    389 << Simd::io(max_eigv / min_eigv) << std::endl;
    \n-
    390 }
    \n-
    391 }
    \n-
    392#else
    \n-
    393 std::cerr << "WARNING: Condition estimate was requested. This requires ARPACK, but ARPACK was not found!" << std::endl;
    \n-
    394#endif
    \n-
    395 }
    \n-
    396 }
    \n-
    397
    \n-
    398 private:
    \n-
    399 bool condition_estimate_ = false;
    \n-
    400
    \n-
    401 // Matrix and vector types used for condition estimate
    \n-\n-\n-
    404
    \n-
    405 protected:
    \n-
    406 using IterativeSolver<X,X>::_op;
    \n-
    407 using IterativeSolver<X,X>::_prec;
    \n-
    408 using IterativeSolver<X,X>::_sp;
    \n-\n-
    410 using IterativeSolver<X,X>::_maxit;
    \n-
    411 using IterativeSolver<X,X>::_verbose;
    \n-\n-
    413 };
    \n-
    414 DUNE_REGISTER_ITERATIVE_SOLVER("cgsolver", defaultIterativeSolverCreator<Dune::CGSolver>());
    \n-
    415
    \n-
    416 // Ronald Kriemanns BiCG-STAB implementation from Sumo
    \n-
    418 template<class X>
    \n-
    419 class BiCGSTABSolver : public IterativeSolver<X,X> {
    \n-
    420 public:
    \n-\n-\n-\n-
    424 using typename IterativeSolver<X,X>::real_type;
    \n-
    425
    \n-
    426 // copy base class constructors
    \n-\n-
    428
    \n-
    429 // don't shadow four-argument version of apply defined in the base class
    \n-
    430 using IterativeSolver<X,X>::apply;
    \n-
    431
    \n-
    439 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    440 {
    \n-
    441 using std::abs;
    \n-
    442 const Simd::Scalar<real_type> EPSILON=1e-80;
    \n-
    443 using std::abs;
    \n-
    444 double it;
    \n-
    445 field_type rho, rho_new, alpha, beta, h, omega;
    \n-
    446 real_type norm;
    \n-
    447
    \n-
    448 //
    \n-
    449 // get vectors and matrix
    \n-
    450 //
    \n-
    451 X& r=b;
    \n-
    452 X p(x);
    \n-
    453 X v(x);
    \n-
    454 X t(x);
    \n-
    455 X y(x);
    \n-
    456 X rt(x);
    \n-
    457
    \n-
    458 //
    \n-
    459 // begin iteration
    \n-
    460 //
    \n-
    461
    \n-
    462 // r = r - Ax; rt = r
    \n-
    463 Iteration<double> iteration(*this,res);
    \n-
    464 _prec->pre(x,r); // prepare preconditioner
    \n-
    465
    \n-
    466 _op->applyscaleadd(-1,x,r); // overwrite b with defect
    \n-
    467
    \n-
    468 rt=r;
    \n-
    469
    \n-
    470 norm = _sp->norm(r);
    \n-
    471 if(iteration.step(0, norm)){
    \n-
    472 _prec->post(x);
    \n-
    473 return;
    \n-
    474 }
    \n-
    475 p=0;
    \n-
    476 v=0;
    \n-
    477
    \n-
    478 rho = 1;
    \n-
    479 alpha = 1;
    \n-
    480 omega = 1;
    \n-
    481
    \n-
    482 //
    \n-
    483 // iteration
    \n-
    484 //
    \n-
    485
    \n-
    486 for (it = 0.5; it < _maxit; it+=.5)
    \n-
    487 {
    \n-
    488 //
    \n-
    489 // preprocess, set vecsizes etc.
    \n-
    490 //
    \n-
    491
    \n-
    492 // rho_new = < rt , r >
    \n-
    493 rho_new = _sp->dot(rt,r);
    \n+
    374 virtual void apply (X& x, X& b, double reduction, InverseOperatorResult& res)
    \n+
    375 {
    \n+
    376 scalar_real_type saved_reduction = _reduction;
    \n+
    377 _reduction = reduction;
    \n+
    378 this->apply(x,b,res);
    \n+
    379 _reduction = saved_reduction;
    \n+
    380 }
    \n+
    381
    \n+\n+
    384 {
    \n+
    385 return _category;
    \n+
    386 }
    \n+
    387
    \n+
    388 std::string name() const{
    \n+
    389 std::string name = className(*this);
    \n+
    390 return name.substr(0, name.find("<"));
    \n+
    391 }
    \n+
    392
    \n+
    410 template<class CountType = unsigned int>
    \n+
    411 class Iteration {
    \n+
    412 public:
    \n+\n+
    414 : _i(0)
    \n+
    415 , _res(res)
    \n+
    416 , _parent(parent)
    \n+
    417 , _valid(true)
    \n+
    418 {
    \n+
    419 res.clear();
    \n+
    420 if(_parent._verbose>0){
    \n+
    421 std::cout << "=== " << parent.name() << std::endl;
    \n+
    422 if(_parent._verbose > 1)
    \n+
    423 _parent.printHeader(std::cout);
    \n+
    424 }
    \n+
    425 }
    \n+
    426
    \n+
    427 Iteration(const Iteration&) = delete;
    \n+\n+
    429 : _def0(other._def0)
    \n+
    430 , _def(other._def)
    \n+
    431 , _i(other._i)
    \n+
    432 , _watch(other._watch)
    \n+
    433 , _res(other._res)
    \n+
    434 , _parent(other._parent)
    \n+
    435 , _valid(other._valid)
    \n+
    436 {
    \n+
    437 other._valid = false;
    \n+
    438 }
    \n+
    439
    \n+\n+
    441 if(_valid)
    \n+
    442 finalize();
    \n+
    443 }
    \n+
    444
    \n+
    455 bool step(CountType i, real_type def){
    \n+
    456 if (!Simd::allTrue(isFinite(def))) // check for inf or NaN
    \n+
    457 {
    \n+
    458 if (_parent._verbose>0)
    \n+
    459 std::cout << "=== " << _parent.name() << ": abort due to infinite or NaN defect"
    \n+
    460 << std::endl;
    \n+
    461 DUNE_THROW(SolverAbort,
    \n+
    462 _parent.name() << ": defect=" << Simd::io(def)
    \n+
    463 << " is infinite or NaN");
    \n+
    464 }
    \n+
    465 if(i == 0)
    \n+
    466 _def0 = def;
    \n+
    467 if(_parent._verbose > 1){
    \n+
    468 if(i!=0)
    \n+
    469 _parent.printOutput(std::cout,i,def,_def);
    \n+
    470 else
    \n+
    471 _parent.printOutput(std::cout,i,def);
    \n+
    472 }
    \n+
    473 _def = def;
    \n+
    474 _i = i;
    \n+
    475 _res.converged = (Simd::allTrue(def<_def0*_parent._reduction || def<real_type(1E-30))); // convergence check
    \n+
    476 return _res.converged;
    \n+
    477 }
    \n+
    478
    \n+
    479 protected:
    \n+
    480 void finalize(){
    \n+
    481 _res.converged = (Simd::allTrue(_def<_def0*_parent._reduction || _def<real_type(1E-30)));
    \n+\n+
    483 _res.reduction = static_cast<double>(Simd::max(_def/_def0));
    \n+
    484 _res.conv_rate = pow(_res.reduction,1.0/_i);
    \n+
    485 _res.elapsed = _watch.elapsed();
    \n+
    486 if (_parent._verbose>0) // final print
    \n+
    487 {
    \n+
    488 std::cout << "=== rate=" << _res.conv_rate
    \n+
    489 << ", T=" << _res.elapsed
    \n+
    490 << ", TIT=" << _res.elapsed/_res.iterations
    \n+
    491 << ", IT=" << _res.iterations << std::endl;
    \n+
    492 }
    \n+
    493 }
    \n
    494
    \n-
    495 // look if breakdown occurred
    \n-
    496 if (Simd::allTrue(abs(rho) <= EPSILON))
    \n-
    497 DUNE_THROW(SolverAbort,"breakdown in BiCGSTAB - rho "
    \n-
    498 << Simd::io(rho) << " <= EPSILON " << EPSILON
    \n-
    499 << " after " << it << " iterations");
    \n-
    500 if (Simd::allTrue(abs(omega) <= EPSILON))
    \n-
    501 DUNE_THROW(SolverAbort,"breakdown in BiCGSTAB - omega "
    \n-
    502 << Simd::io(omega) << " <= EPSILON " << EPSILON
    \n-
    503 << " after " << it << " iterations");
    \n-
    504
    \n-
    505
    \n-
    506 if (it<1)
    \n-
    507 p = r;
    \n-
    508 else
    \n-
    509 {
    \n-
    510 beta = Simd::cond(norm==field_type(0.),
    \n-
    511 field_type(0.), // no need for orthogonalization if norm is already 0
    \n-
    512 ( rho_new / rho ) * ( alpha / omega ));
    \n-
    513 p.axpy(-omega,v); // p = r + beta (p - omega*v)
    \n-
    514 p *= beta;
    \n-
    515 p += r;
    \n-
    516 }
    \n-
    517
    \n-
    518 // y = W^-1 * p
    \n-
    519 y = 0;
    \n-
    520 _prec->apply(y,p); // apply preconditioner
    \n-
    521
    \n-
    522 // v = A * y
    \n-
    523 _op->apply(y,v);
    \n-
    524
    \n-
    525 // alpha = rho_new / < rt, v >
    \n-
    526 h = _sp->dot(rt,v);
    \n-
    527
    \n-
    528 if ( Simd::allTrue(abs(h) < EPSILON) )
    \n-
    529 DUNE_THROW(SolverAbort,"abs(h) < EPSILON in BiCGSTAB - abs(h) "
    \n-
    530 << Simd::io(abs(h)) << " < EPSILON " << EPSILON
    \n-
    531 << " after " << it << " iterations");
    \n+
    495 real_type _def0 = 0.0, _def = 0.0;
    \n+
    496 CountType _i;
    \n+
    497 Timer _watch;
    \n+\n+\n+
    500 bool _valid;
    \n+
    501 };
    \n+
    502
    \n+
    503 protected:
    \n+
    504 std::shared_ptr<const LinearOperator<X,Y>> _op;
    \n+
    505 std::shared_ptr<Preconditioner<X,Y>> _prec;
    \n+
    506 std::shared_ptr<const ScalarProduct<X>> _sp;
    \n+\n+\n+\n+\n+
    511 };
    \n+
    512
    \n+
    520 template <typename ISTLLinearSolver, typename BCRSMatrix>
    \n+\n+
    522 {
    \n+
    523 public:
    \n+
    524 static void setMatrix (ISTLLinearSolver& solver,
    \n+
    525 const BCRSMatrix& matrix)
    \n+
    526 {
    \n+
    527 static const bool is_direct_solver
    \n+\n+\n+\n+
    531 }
    \n
    532
    \n-
    533 alpha = Simd::cond(norm==field_type(0.),
    \n-
    534 field_type(0.),
    \n-
    535 rho_new / h);
    \n-
    536
    \n-
    537 // apply first correction to x
    \n-
    538 // x <- x + alpha y
    \n-
    539 x.axpy(alpha,y);
    \n-
    540
    \n-
    541 // r = r - alpha*v
    \n-
    542 r.axpy(-alpha,v);
    \n-
    543
    \n-
    544 //
    \n-
    545 // test stop criteria
    \n-
    546 //
    \n-
    547
    \n-
    548 norm = _sp->norm(r);
    \n-
    549 if(iteration.step(it, norm)){
    \n-
    550 break;
    \n-
    551 }
    \n-
    552
    \n-
    553 it+=.5;
    \n-
    554
    \n-
    555 // y = W^-1 * r
    \n-
    556 y = 0;
    \n-
    557 _prec->apply(y,r);
    \n-
    558
    \n-
    559 // t = A * y
    \n-
    560 _op->apply(y,t);
    \n-
    561
    \n-
    562 // omega = < t, r > / < t, t >
    \n-
    563 h = _sp->dot(t,t);
    \n-
    564 omega = Simd::cond(norm==field_type(0.),
    \n-
    565 field_type(0.),
    \n-
    566 _sp->dot(t,r)/h);
    \n-
    567
    \n-
    568 // apply second correction to x
    \n-
    569 // x <- x + omega y
    \n-
    570 x.axpy(omega,y);
    \n-
    571
    \n-
    572 // r = s - omega*t (remember : r = s)
    \n-
    573 r.axpy(-omega,t);
    \n-
    574
    \n-
    575 rho = rho_new;
    \n-
    576
    \n-
    577 //
    \n-
    578 // test stop criteria
    \n-
    579 //
    \n-
    580
    \n-
    581 norm = _sp->norm(r);
    \n-
    582 if(iteration.step(it, norm)){
    \n-
    583 break;
    \n-
    584 }
    \n-
    585 } // end for
    \n-
    586
    \n-
    587 _prec->post(x); // postprocess preconditioner
    \n-
    588 }
    \n-
    589
    \n-
    590 protected:
    \n-
    591 using IterativeSolver<X,X>::_op;
    \n-
    592 using IterativeSolver<X,X>::_prec;
    \n-
    593 using IterativeSolver<X,X>::_sp;
    \n-\n-
    595 using IterativeSolver<X,X>::_maxit;
    \n-
    596 using IterativeSolver<X,X>::_verbose;
    \n-
    597 template<class CountType>
    \n-\n-
    599 };
    \n-
    600 DUNE_REGISTER_ITERATIVE_SOLVER("bicgstabsolver", defaultIterativeSolverCreator<Dune::BiCGSTABSolver>());
    \n-
    601
    \n-
    608 template<class X>
    \n-
    609 class MINRESSolver : public IterativeSolver<X,X> {
    \n-
    610 public:
    \n-\n-\n-\n-
    614 using typename IterativeSolver<X,X>::real_type;
    \n-
    615
    \n-
    616 // copy base class constructors
    \n-\n-
    618
    \n-
    619 // don't shadow four-argument version of apply defined in the base class
    \n-
    620 using IterativeSolver<X,X>::apply;
    \n-
    621
    \n-
    627 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    628 {
    \n-
    629 using std::sqrt;
    \n-
    630 using std::abs;
    \n-
    631 Iteration iteration(*this, res);
    \n-
    632 // prepare preconditioner
    \n-
    633 _prec->pre(x,b);
    \n-
    634
    \n-
    635 // overwrite rhs with defect
    \n-
    636 _op->applyscaleadd(-1.0,x,b); // b -= Ax
    \n-
    637
    \n-
    638 // some temporary vectors
    \n-
    639 X z(b), dummy(b);
    \n-
    640 z = 0.0;
    \n-
    641
    \n-
    642 // calculate preconditioned defect
    \n-
    643 _prec->apply(z,b); // r = W^-1 (b - Ax)
    \n-
    644 real_type def = _sp->norm(z);
    \n-
    645 if (iteration.step(0, def)){
    \n-
    646 _prec->post(x);
    \n-
    647 return;
    \n-
    648 }
    \n-
    649
    \n-
    650 // recurrence coefficients as computed in Lanczos algorithm
    \n-
    651 field_type alpha, beta;
    \n-
    652 // diagonal entries of givens rotation
    \n-
    653 std::array<real_type,2> c{{0.0,0.0}};
    \n-
    654 // off-diagonal entries of givens rotation
    \n-
    655 std::array<field_type,2> s{{0.0,0.0}};
    \n-
    656
    \n-
    657 // recurrence coefficients (column k of tridiag matrix T_k)
    \n-
    658 std::array<field_type,3> T{{0.0,0.0,0.0}};
    \n-
    659
    \n-
    660 // the rhs vector of the min problem
    \n-
    661 std::array<field_type,2> xi{{1.0,0.0}};
    \n-
    662
    \n-
    663 // beta is real and positive in exact arithmetic
    \n-
    664 // since it is the norm of the basis vectors (in unpreconditioned case)
    \n-
    665 beta = sqrt(_sp->dot(b,z));
    \n-
    666 field_type beta0 = beta;
    \n-
    667
    \n-
    668 // the search directions
    \n-
    669 std::array<X,3> p{{b,b,b}};
    \n-
    670 p[0] = 0.0;
    \n-
    671 p[1] = 0.0;
    \n-
    672 p[2] = 0.0;
    \n-
    673
    \n-
    674 // orthonormal basis vectors (in unpreconditioned case)
    \n-
    675 std::array<X,3> q{{b,b,b}};
    \n-
    676 q[0] = 0.0;
    \n-
    677 q[1] *= Simd::cond(def==field_type(0.),
    \n-
    678 field_type(0.),
    \n-
    679 real_type(1.0)/beta);
    \n-
    680 q[2] = 0.0;
    \n-
    681
    \n-
    682 z *= Simd::cond(def==field_type(0.),
    \n-
    683 field_type(0.),
    \n-
    684 real_type(1.0)/beta);
    \n-
    685
    \n-
    686 // the loop
    \n-
    687 int i = 1;
    \n-
    688 for( ; i<=_maxit; i++) {
    \n-
    689
    \n-
    690 dummy = z;
    \n-
    691 int i1 = i%3,
    \n-
    692 i0 = (i1+2)%3,
    \n-
    693 i2 = (i1+1)%3;
    \n-
    694
    \n-
    695 // symmetrically preconditioned Lanczos algorithm (see Greenbaum p.121)
    \n-
    696 _op->apply(z,q[i2]); // q[i2] = Az
    \n-
    697 q[i2].axpy(-beta,q[i0]);
    \n-
    698 // alpha is real since it is the diagonal entry of the hermitian tridiagonal matrix
    \n-
    699 // from the Lanczos Algorithm
    \n-
    700 // so the order in the scalar product doesn't matter even for the complex case
    \n-
    701 alpha = _sp->dot(z,q[i2]);
    \n-
    702 q[i2].axpy(-alpha,q[i1]);
    \n-
    703
    \n-
    704 z = 0.0;
    \n-
    705 _prec->apply(z,q[i2]);
    \n-
    706
    \n-
    707 // beta is real and positive in exact arithmetic
    \n-
    708 // since it is the norm of the basis vectors (in unpreconditioned case)
    \n-
    709 beta = sqrt(_sp->dot(q[i2],z));
    \n-
    710
    \n-
    711 q[i2] *= Simd::cond(def==field_type(0.),
    \n-
    712 field_type(0.),
    \n-
    713 real_type(1.0)/beta);
    \n-
    714 z *= Simd::cond(def==field_type(0.),
    \n-
    715 field_type(0.),
    \n-
    716 real_type(1.0)/beta);
    \n-
    717
    \n-
    718 // QR Factorization of recurrence coefficient matrix
    \n-
    719 // apply previous givens rotations to last column of T
    \n-
    720 T[1] = T[2];
    \n-
    721 if(i>2) {
    \n-
    722 T[0] = s[i%2]*T[1];
    \n-
    723 T[1] = c[i%2]*T[1];
    \n-
    724 }
    \n-
    725 if(i>1) {
    \n-
    726 T[2] = c[(i+1)%2]*alpha - s[(i+1)%2]*T[1];
    \n-
    727 T[1] = c[(i+1)%2]*T[1] + s[(i+1)%2]*alpha;
    \n-
    728 }
    \n-
    729 else
    \n-
    730 T[2] = alpha;
    \n-
    731
    \n-
    732 // update QR factorization
    \n-
    733 generateGivensRotation(T[2],beta,c[i%2],s[i%2]);
    \n-
    734 // to last column of T_k
    \n-
    735 T[2] = c[i%2]*T[2] + s[i%2]*beta;
    \n-
    736 // and to the rhs xi of the min problem
    \n-
    737 xi[i%2] = -s[i%2]*xi[(i+1)%2];
    \n-
    738 xi[(i+1)%2] *= c[i%2];
    \n-
    739
    \n-
    740 // compute correction direction
    \n-
    741 p[i2] = dummy;
    \n-
    742 p[i2].axpy(-T[1],p[i1]);
    \n-
    743 p[i2].axpy(-T[0],p[i0]);
    \n-
    744 p[i2] *= real_type(1.0)/T[2];
    \n-
    745
    \n-
    746 // apply correction/update solution
    \n-
    747 x.axpy(beta0*xi[(i+1)%2],p[i2]);
    \n-
    748
    \n-
    749 // remember beta_old
    \n-
    750 T[2] = beta;
    \n-
    751
    \n-
    752 // check for convergence
    \n-
    753 // the last entry in the rhs of the min-problem is the residual
    \n-
    754 def = abs(beta0*xi[i%2]);
    \n-
    755 if(iteration.step(i, def)){
    \n-
    756 break;
    \n-
    757 }
    \n-
    758 } // end for
    \n-
    759
    \n-
    760 // postprocess preconditioner
    \n-
    761 _prec->post(x);
    \n-
    762 }
    \n-
    763
    \n-
    764 private:
    \n-
    765
    \n-
    766 void generateGivensRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    \n-
    767 {
    \n-
    768 using std::sqrt;
    \n-
    769 using std::abs;
    \n-
    770 using std::max;
    \n-
    771 using std::min;
    \n-
    772 const real_type eps = 1e-15;
    \n-
    773 real_type norm_dx = abs(dx);
    \n-
    774 real_type norm_dy = abs(dy);
    \n-
    775 real_type norm_max = max(norm_dx, norm_dy);
    \n-
    776 real_type norm_min = min(norm_dx, norm_dy);
    \n-
    777 real_type temp = norm_min/norm_max;
    \n-
    778 // we rewrite the code in a vectorizable fashion
    \n-
    779 cs = Simd::cond(norm_dy < eps,
    \n-
    780 real_type(1.0),
    \n-
    781 Simd::cond(norm_dx < eps,
    \n-
    782 real_type(0.0),
    \n-
    783 Simd::cond(norm_dy > norm_dx,
    \n-
    784 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,
    \n-
    785 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)
    \n-
    786 )));
    \n-
    787 sn = Simd::cond(norm_dy < eps,
    \n-
    788 field_type(0.0),
    \n-
    789 Simd::cond(norm_dx < eps,
    \n-
    790 field_type(1.0),
    \n-
    791 Simd::cond(norm_dy > norm_dx,
    \n-
    792 // dy and dx are real in exact arithmetic
    \n-
    793 // thus dx*dy is real so we can explicitly enforce it
    \n-
    794 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*dy/norm_dx/norm_dy,
    \n-
    795 // dy and dx is real in exact arithmetic
    \n-
    796 // so we don't have to conjugate both of them
    \n-
    797 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dy/dx
    \n-
    798 )));
    \n-
    799 }
    \n-
    800
    \n-
    801 protected:
    \n-
    802 using IterativeSolver<X,X>::_op;
    \n-
    803 using IterativeSolver<X,X>::_prec;
    \n-
    804 using IterativeSolver<X,X>::_sp;
    \n-\n-
    806 using IterativeSolver<X,X>::_maxit;
    \n-
    807 using IterativeSolver<X,X>::_verbose;
    \n-\n-
    809 };
    \n-
    810 DUNE_REGISTER_ITERATIVE_SOLVER("minressolver", defaultIterativeSolverCreator<Dune::MINRESSolver>());
    \n-
    811
    \n-
    825 template<class X, class Y=X, class F = Y>
    \n-\n-
    827 {
    \n-
    828 public:
    \n-\n-\n-\n-
    832 using typename IterativeSolver<X,Y>::real_type;
    \n-
    833
    \n-
    834 protected:
    \n-\n-
    836
    \n-\n-\n-
    841
    \n-
    842 public:
    \n-
    843
    \n-
    850 RestartedGMResSolver (const LinearOperator<X,Y>& op, Preconditioner<X,Y>& prec, scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n-
    851 IterativeSolver<X,Y>::IterativeSolver(op,prec,reduction,maxit,verbose),
    \n-
    852 _restart(restart)
    \n-
    853 {}
    \n-
    854
    \n-
    861 RestartedGMResSolver (const LinearOperator<X,Y>& op, const ScalarProduct<X>& sp, Preconditioner<X,Y>& prec, scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n-
    862 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n-
    863 _restart(restart)
    \n-
    864 {}
    \n-
    865
    \n-
    878 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    879 IterativeSolver<X,Y>::IterativeSolver(op,prec,configuration),
    \n-
    880 _restart(configuration.get<int>("restart"))
    \n-
    881 {}
    \n-
    882
    \n-
    883 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    884 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,configuration),
    \n-
    885 _restart(configuration.get<int>("restart"))
    \n-
    886 {}
    \n-
    887
    \n-
    894 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y>> op,
    \n-
    895 std::shared_ptr<const ScalarProduct<X>> sp,
    \n-
    896 std::shared_ptr<Preconditioner<X,Y>> prec,
    \n-
    897 scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n-
    898 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n-
    899 _restart(restart)
    \n-
    900 {}
    \n-
    901
    \n-
    910 virtual void apply (X& x, Y& b, InverseOperatorResult& res)
    \n-
    911 {
    \n-
    912 apply(x,b,Simd::max(_reduction),res);
    \n-
    913 }
    \n-
    914
    \n-
    923 virtual void apply (X& x, Y& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n-
    924 {
    \n-
    925 using std::abs;
    \n-
    926 const Simd::Scalar<real_type> EPSILON = 1e-80;
    \n-
    927 const int m = _restart;
    \n-
    928 real_type norm = 0.0;
    \n-
    929 int j = 1;
    \n-
    930 std::vector<field_type,fAlloc> s(m+1), sn(m);
    \n-
    931 std::vector<real_type,rAlloc> cs(m);
    \n-
    932 // need copy of rhs if GMRes has to be restarted
    \n-
    933 Y b2(b);
    \n-
    934 // helper vector
    \n-
    935 Y w(b);
    \n-
    936 std::vector< std::vector<field_type,fAlloc> > H(m+1,s);
    \n-
    937 std::vector<F> v(m+1,b);
    \n-
    938
    \n-
    939 Iteration iteration(*this,res);
    \n-
    940
    \n-
    941 // clear solver statistics and set res.converged to false
    \n-
    942 _prec->pre(x,b);
    \n-
    943
    \n-
    944 // calculate defect and overwrite rhs with it
    \n-
    945 _op->applyscaleadd(-1.0,x,b); // b -= Ax
    \n-
    946 // calculate preconditioned defect
    \n-
    947 v[0] = 0.0; _prec->apply(v[0],b); // r = W^-1 b
    \n-
    948 norm = _sp->norm(v[0]);
    \n-
    949 if(iteration.step(0, norm)){
    \n-
    950 _prec->post(x);
    \n-
    951 return;
    \n-
    952 }
    \n-
    953
    \n-
    954 while(j <= _maxit && res.converged != true) {
    \n-
    955
    \n-
    956 int i = 0;
    \n-
    957 v[0] *= Simd::cond(norm==real_type(0.),
    \n-
    958 real_type(0.),
    \n-
    959 real_type(1.0)/norm);
    \n-
    960 s[0] = norm;
    \n-
    961 for(i=1; i<m+1; i++)
    \n-
    962 s[i] = 0.0;
    \n-
    963
    \n-
    964 for(i=0; i < m && j <= _maxit && res.converged != true; i++, j++) {
    \n-
    965 w = 0.0;
    \n-
    966 // use v[i+1] as temporary vector
    \n-
    967 v[i+1] = 0.0;
    \n-
    968 // do Arnoldi algorithm
    \n-
    969 _op->apply(v[i],v[i+1]);
    \n-
    970 _prec->apply(w,v[i+1]);
    \n-
    971 for(int k=0; k<i+1; k++) {
    \n-
    972 // notice that _sp->dot(v[k],w) = v[k]\\adjoint w
    \n-
    973 // so one has to pay attention to the order
    \n-
    974 // in the scalar product for the complex case
    \n-
    975 // doing the modified Gram-Schmidt algorithm
    \n-
    976 H[k][i] = _sp->dot(v[k],w);
    \n-
    977 // w -= H[k][i] * v[k]
    \n-
    978 w.axpy(-H[k][i],v[k]);
    \n-
    979 }
    \n-
    980 H[i+1][i] = _sp->norm(w);
    \n-
    981 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))
    \n-
    982 DUNE_THROW(SolverAbort,
    \n-
    983 "breakdown in GMRes - |w| == 0.0 after " << j << " iterations");
    \n-
    984
    \n-
    985 // normalize new vector
    \n-
    986 v[i+1] = w;
    \n-
    987 v[i+1] *= Simd::cond(norm==real_type(0.),
    \n-
    988 field_type(0.),
    \n-
    989 real_type(1.0)/H[i+1][i]);
    \n-
    990
    \n-
    991 // update QR factorization
    \n-
    992 for(int k=0; k<i; k++)
    \n-
    993 applyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);
    \n-
    994
    \n-
    995 // compute new givens rotation
    \n-
    996 generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n-
    997 // finish updating QR factorization
    \n-
    998 applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n-
    999 applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);
    \n-
    1000
    \n-
    1001 // norm of the defect is the last component the vector s
    \n-
    1002 norm = abs(s[i+1]);
    \n-
    1003
    \n-
    1004 iteration.step(j, norm);
    \n-
    1005
    \n-
    1006 } // end for
    \n-
    1007
    \n-
    1008 // calculate update vector
    \n-
    1009 w = 0.0;
    \n-
    1010 update(w,i,H,s,v);
    \n-
    1011 // and current iterate
    \n-
    1012 x += w;
    \n-
    1013
    \n-
    1014 // restart GMRes if convergence was not achieved,
    \n-
    1015 // i.e. linear defect has not reached desired reduction
    \n-
    1016 // and if j < _maxit (do not restart on last iteration)
    \n-
    1017 if( res.converged != true && j < _maxit ) {
    \n-
    1018
    \n-
    1019 if(_verbose > 0)
    \n-
    1020 std::cout << "=== GMRes::restart" << std::endl;
    \n-
    1021 // get saved rhs
    \n-
    1022 b = b2;
    \n-
    1023 // calculate new defect
    \n-
    1024 _op->applyscaleadd(-1.0,x,b); // b -= Ax;
    \n-
    1025 // calculate preconditioned defect
    \n-
    1026 v[0] = 0.0;
    \n-
    1027 _prec->apply(v[0],b);
    \n-
    1028 norm = _sp->norm(v[0]);
    \n-
    1029 }
    \n-
    1030
    \n-
    1031 } //end while
    \n-
    1032
    \n-
    1033 // postprocess preconditioner
    \n-
    1034 _prec->post(x);
    \n-
    1035 }
    \n-
    1036
    \n-
    1037 protected :
    \n-
    1038
    \n-
    1039 void update(X& w, int i,
    \n-
    1040 const std::vector<std::vector<field_type,fAlloc> >& H,
    \n-
    1041 const std::vector<field_type,fAlloc>& s,
    \n-
    1042 const std::vector<X>& v) {
    \n-
    1043 // solution vector of the upper triangular system
    \n-
    1044 std::vector<field_type,fAlloc> y(s);
    \n-
    1045
    \n-
    1046 // backsolve
    \n-
    1047 for(int a=i-1; a>=0; a--) {
    \n-
    1048 field_type rhs(s[a]);
    \n-
    1049 for(int b=a+1; b<i; b++)
    \n-
    1050 rhs -= H[a][b]*y[b];
    \n-
    1051 y[a] = Simd::cond(rhs==field_type(0.),
    \n-
    1052 field_type(0.),
    \n-
    1053 rhs/H[a][a]);
    \n-
    1054
    \n-
    1055 // compute update on the fly
    \n-
    1056 // w += y[a]*v[a]
    \n-
    1057 w.axpy(y[a],v[a]);
    \n-
    1058 }
    \n-
    1059 }
    \n-
    1060
    \n-
    1061 template<typename T>
    \n-
    1062 typename std::enable_if<std::is_same<field_type,real_type>::value,T>::type conjugate(const T& t) {
    \n-
    1063 return t;
    \n-
    1064 }
    \n-
    1065
    \n-
    1066 template<typename T>
    \n-
    1067 typename std::enable_if<!std::is_same<field_type,real_type>::value,T>::type conjugate(const T& t) {
    \n-
    1068 using std::conj;
    \n-
    1069 return conj(t);
    \n-
    1070 }
    \n-
    1071
    \n-
    1072 void
    \n-\n-
    1074 {
    \n-
    1075 using std::sqrt;
    \n-
    1076 using std::abs;
    \n-
    1077 using std::max;
    \n-
    1078 using std::min;
    \n-
    1079 const real_type eps = 1e-15;
    \n-
    1080 real_type norm_dx = abs(dx);
    \n-
    1081 real_type norm_dy = abs(dy);
    \n-
    1082 real_type norm_max = max(norm_dx, norm_dy);
    \n-
    1083 real_type norm_min = min(norm_dx, norm_dy);
    \n-
    1084 real_type temp = norm_min/norm_max;
    \n-
    1085 // we rewrite the code in a vectorizable fashion
    \n-
    1086 cs = Simd::cond(norm_dy < eps,
    \n-
    1087 real_type(1.0),
    \n-
    1088 Simd::cond(norm_dx < eps,
    \n-
    1089 real_type(0.0),
    \n-
    1090 Simd::cond(norm_dy > norm_dx,
    \n-
    1091 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,
    \n-
    1092 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)
    \n-
    1093 )));
    \n-
    1094 sn = Simd::cond(norm_dy < eps,
    \n-
    1095 field_type(0.0),
    \n-
    1096 Simd::cond(norm_dx < eps,
    \n-
    1097 field_type(1.0),
    \n-
    1098 Simd::cond(norm_dy > norm_dx,
    \n-
    1099 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*conjugate(dy)/norm_dx/norm_dy,
    \n-
    1100 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*conjugate(dy/dx)
    \n-
    1101 )));
    \n-
    1102 }
    \n-
    1103
    \n-
    1104
    \n-
    1105 void
    \n-\n-
    1107 {
    \n-
    1108 field_type temp = cs * dx + sn * dy;
    \n-
    1109 dy = -conjugate(sn) * dx + cs * dy;
    \n-
    1110 dx = temp;
    \n-
    1111 }
    \n-
    1112
    \n-
    1113 using IterativeSolver<X,Y>::_op;
    \n-
    1114 using IterativeSolver<X,Y>::_prec;
    \n-
    1115 using IterativeSolver<X,Y>::_sp;
    \n-
    1116 using IterativeSolver<X,Y>::_reduction;
    \n-
    1117 using IterativeSolver<X,Y>::_maxit;
    \n-
    1118 using IterativeSolver<X,Y>::_verbose;
    \n-\n-\n-
    1121 };
    \n-
    1122 DUNE_REGISTER_ITERATIVE_SOLVER("restartedgmressolver", defaultIterativeSolverCreator<Dune::RestartedGMResSolver>());
    \n-
    1123
    \n-
    1137 template<class X, class Y=X, class F = Y>
    \n-\n-
    1139 {
    \n-
    1140 public:
    \n-\n-\n-\n-\n-
    1145
    \n-
    1146 private:
    \n-\n-
    1148
    \n-
    1150 using fAlloc = typename RestartedGMResSolver<X,Y>::fAlloc;
    \n-
    1152 using rAlloc = typename RestartedGMResSolver<X,Y>::rAlloc;
    \n-
    1153
    \n-
    1154 public:
    \n-
    1155 // copy base class constructors
    \n-\n-
    1157
    \n-
    1158 // don't shadow four-argument version of apply defined in the base class
    \n-
    1159 using RestartedGMResSolver<X,Y>::apply;
    \n-
    1160
    \n-
    1169 void apply (X& x, Y& b, [[maybe_unused]] double reduction, InverseOperatorResult& res) override
    \n-
    1170 {
    \n-
    1171 using std::abs;
    \n-
    1172 const Simd::Scalar<real_type> EPSILON = 1e-80;
    \n-
    1173 const int m = _restart;
    \n-
    1174 real_type norm = 0.0;
    \n-
    1175 int i, j = 1, k;
    \n-
    1176 std::vector<field_type,fAlloc> s(m+1), sn(m);
    \n-
    1177 std::vector<real_type,rAlloc> cs(m);
    \n-
    1178 // helper vector
    \n-
    1179 Y tmp(b);
    \n-
    1180 std::vector< std::vector<field_type,fAlloc> > H(m+1,s);
    \n-
    1181 std::vector<F> v(m+1,b);
    \n-
    1182 std::vector<X> w(m+1,b);
    \n-
    1183
    \n-
    1184 Iteration iteration(*this,res);
    \n-
    1185 // setup preconditioner if it does something in pre
    \n-
    1186
    \n-
    1187 // calculate residual and overwrite a copy of the rhs with it
    \n-
    1188 _prec->pre(x, b);
    \n-
    1189 v[0] = b;
    \n-
    1190 _op->applyscaleadd(-1.0, x, v[0]); // b -= Ax
    \n-
    1191
    \n-
    1192 norm = _sp->norm(v[0]); // the residual norm
    \n-
    1193 if(iteration.step(0, norm)){
    \n-
    1194 _prec->post(x);
    \n-
    1195 return;
    \n-
    1196 }
    \n-
    1197
    \n-
    1198 // start iterations
    \n-
    1199 res.converged = false;;
    \n-
    1200 while(j <= _maxit && res.converged != true)
    \n-
    1201 {
    \n-
    1202 v[0] *= (1.0 / norm);
    \n-
    1203 s[0] = norm;
    \n-
    1204 for(i=1; i<m+1; ++i)
    \n-
    1205 s[i] = 0.0;
    \n-
    1206
    \n-
    1207 // inner loop
    \n-
    1208 for(i=0; i < m && j <= _maxit && res.converged != true; i++, j++)
    \n-
    1209 {
    \n-
    1210 w[i] = 0.0;
    \n-
    1211 // compute wi = M^-1*vi (also called zi)
    \n-
    1212 _prec->apply(w[i], v[i]);
    \n-
    1213 // compute vi = A*wi
    \n-
    1214 // use v[i+1] as temporary vector for w
    \n-
    1215 _op->apply(w[i], v[i+1]);
    \n-
    1216 // do Arnoldi algorithm
    \n-
    1217 for(int kk=0; kk<i+1; kk++)
    \n-
    1218 {
    \n-
    1219 // notice that _sp->dot(v[k],v[i+1]) = v[k]\\adjoint v[i+1]
    \n-
    1220 // so one has to pay attention to the order
    \n-
    1221 // in the scalar product for the complex case
    \n-
    1222 // doing the modified Gram-Schmidt algorithm
    \n-
    1223 H[kk][i] = _sp->dot(v[kk],v[i+1]);
    \n-
    1224 // w -= H[k][i] * v[kk]
    \n-
    1225 v[i+1].axpy(-H[kk][i], v[kk]);
    \n-
    1226 }
    \n-
    1227 H[i+1][i] = _sp->norm(v[i+1]);
    \n-
    1228 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))
    \n-
    1229 DUNE_THROW(SolverAbort, "breakdown in fGMRes - |w| (-> "
    \n-
    1230 << w[i] << ") == 0.0 after "
    \n-
    1231 << j << " iterations");
    \n-
    1232
    \n-
    1233 // v[i+1] = w*1/H[i+1][i]
    \n-
    1234 v[i+1] *= real_type(1.0)/H[i+1][i];
    \n-
    1235
    \n-
    1236 // update QR factorization
    \n-
    1237 for(k=0; k<i; k++)
    \n-
    1238 this->applyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);
    \n-
    1239
    \n-
    1240 // compute new givens rotation
    \n-
    1241 this->generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n-
    1242
    \n-
    1243 // finish updating QR factorization
    \n-
    1244 this->applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n-
    1245 this->applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);
    \n-
    1246
    \n-
    1247 // norm of the residual is the last component of vector s
    \n-
    1248 using std::abs;
    \n-
    1249 norm = abs(s[i+1]);
    \n-
    1250 iteration.step(j, norm);
    \n-
    1251 } // end inner for loop
    \n-
    1252
    \n-
    1253 // calculate update vector
    \n-
    1254 tmp = 0.0;
    \n-
    1255 this->update(tmp, i, H, s, w);
    \n-
    1256 // and update current iterate
    \n-
    1257 x += tmp;
    \n-
    1258
    \n-
    1259 // restart fGMRes if convergence was not achieved,
    \n-
    1260 // i.e. linear residual has not reached desired reduction
    \n-
    1261 // and if still j < _maxit (do not restart on last iteration)
    \n-
    1262 if( res.converged != true && j < _maxit)
    \n-
    1263 {
    \n-
    1264 if (_verbose > 0)
    \n-
    1265 std::cout << "=== fGMRes::restart" << std::endl;
    \n-
    1266 // get rhs
    \n-
    1267 v[0] = b;
    \n-
    1268 // calculate new defect
    \n-
    1269 _op->applyscaleadd(-1.0, x,v[0]); // b -= Ax;
    \n-
    1270 // calculate preconditioned defect
    \n-
    1271 norm = _sp->norm(v[0]); // update the residual norm
    \n-
    1272 }
    \n-
    1273
    \n-
    1274 } // end outer while loop
    \n-
    1275
    \n-
    1276 // post-process preconditioner
    \n-
    1277 _prec->post(x);
    \n-
    1278 }
    \n-
    1279
    \n-
    1280private:
    \n-
    1281 using RestartedGMResSolver<X,Y>::_op;
    \n-
    1282 using RestartedGMResSolver<X,Y>::_prec;
    \n-
    1283 using RestartedGMResSolver<X,Y>::_sp;
    \n-\n-\n-\n-\n-
    1288 using Iteration = typename IterativeSolver<X,X>::template Iteration<unsigned int>;
    \n-
    1289 };
    \n-
    1290 DUNE_REGISTER_ITERATIVE_SOLVER("restartedflexiblegmressolver", defaultIterativeSolverCreator<Dune::RestartedFlexibleGMResSolver>());
    \n-
    1291
    \n-
    1305 template<class X>
    \n-\n-
    1307 {
    \n-
    1308 public:
    \n-
    1309 using typename IterativeSolver<X,X>::domain_type;
    \n-
    1310 using typename IterativeSolver<X,X>::range_type;
    \n-
    1311 using typename IterativeSolver<X,X>::field_type;
    \n-
    1312 using typename IterativeSolver<X,X>::real_type;
    \n-
    1313
    \n-
    1314 private:
    \n-\n-
    1316
    \n-\n-
    1319
    \n-
    1320 public:
    \n-
    1321
    \n-
    1322 // don't shadow four-argument version of apply defined in the base class
    \n-
    1323 using IterativeSolver<X,X>::apply;
    \n-
    1324
    \n-
    1331 GeneralizedPCGSolver (const LinearOperator<X,X>& op, Preconditioner<X,X>& prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :
    \n-
    1332 IterativeSolver<X,X>::IterativeSolver(op,prec,reduction,maxit,verbose),
    \n-
    1333 _restart(restart)
    \n-
    1334 {}
    \n-
    1335
    \n-
    1343 GeneralizedPCGSolver (const LinearOperator<X,X>& op, const ScalarProduct<X>& sp, Preconditioner<X,X>& prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :
    \n-
    1344 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n-
    1345 _restart(restart)
    \n-
    1346 {}
    \n-
    1347
    \n-
    1348
    \n-
    1361 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    1362 IterativeSolver<X,X>::IterativeSolver(op,prec,configuration),
    \n-
    1363 _restart(configuration.get<int>("restart"))
    \n-
    1364 {}
    \n-
    1365
    \n-
    1366 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n-
    1367 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,configuration),
    \n-
    1368 _restart(configuration.get<int>("restart"))
    \n-
    1369 {}
    \n-
    1377 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n-
    1378 std::shared_ptr<const ScalarProduct<X>> sp,
    \n-
    1379 std::shared_ptr<Preconditioner<X,X>> prec,
    \n-
    1380 scalar_real_type reduction, int maxit, int verbose,
    \n-
    1381 int restart = 10) :
    \n-
    1382 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n-
    1383 _restart(restart)
    \n-
    1384 {}
    \n-
    1385
    \n-
    1391 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    1392 {
    \n-
    1393 Iteration iteration(*this, res);
    \n-
    1394 _prec->pre(x,b); // prepare preconditioner
    \n-
    1395 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n-
    1396
    \n-
    1397 std::vector<std::shared_ptr<X> > p(_restart);
    \n-
    1398 std::vector<field_type,fAlloc> pp(_restart);
    \n-
    1399 X q(x); // a temporary vector
    \n-
    1400 X prec_res(x); // a temporary vector for preconditioner output
    \n-
    1401
    \n-
    1402 p[0].reset(new X(x));
    \n-
    1403
    \n-
    1404 real_type def = _sp->norm(b); // compute norm
    \n-
    1405 if(iteration.step(0, def)){
    \n-
    1406 _prec->post(x);
    \n-
    1407 return;
    \n-
    1408 }
    \n-
    1409 // some local variables
    \n-
    1410 field_type rho, lambda;
    \n-
    1411
    \n-
    1412 int i=0;
    \n-
    1413 int ii=0;
    \n-
    1414 // determine initial search direction
    \n-
    1415 *(p[0]) = 0; // clear correction
    \n-
    1416 _prec->apply(*(p[0]),b); // apply preconditioner
    \n-
    1417 rho = _sp->dot(*(p[0]),b); // orthogonalization
    \n-
    1418 _op->apply(*(p[0]),q); // q=Ap
    \n-
    1419 pp[0] = _sp->dot(*(p[0]),q); // scalar product
    \n-
    1420 lambda = rho/pp[0]; // minimization
    \n-
    1421 x.axpy(lambda,*(p[0])); // update solution
    \n-
    1422 b.axpy(-lambda,q); // update defect
    \n-
    1423
    \n-
    1424 // convergence test
    \n-
    1425 def=_sp->norm(b); // comp defect norm
    \n-
    1426 ++i;
    \n-
    1427 if(iteration.step(i, def)){
    \n-
    1428 _prec->post(x);
    \n-
    1429 return;
    \n-
    1430 }
    \n-
    1431
    \n-
    1432 while(i<_maxit) {
    \n-
    1433 // the loop
    \n-
    1434 int end=std::min(_restart, _maxit-i+1);
    \n-
    1435 for (ii=1; ii<end; ++ii )
    \n-
    1436 {
    \n-
    1437 //std::cout<<" ii="<<ii<<" i="<<i<<std::endl;
    \n-
    1438 // compute next conjugate direction
    \n-
    1439 prec_res = 0; // clear correction
    \n-
    1440 _prec->apply(prec_res,b); // apply preconditioner
    \n-
    1441
    \n-
    1442 p[ii].reset(new X(prec_res));
    \n-
    1443 _op->apply(prec_res, q);
    \n-
    1444
    \n-
    1445 for(int j=0; j<ii; ++j) {
    \n-
    1446 rho =_sp->dot(q,*(p[j]))/pp[j];
    \n-
    1447 p[ii]->axpy(-rho, *(p[j]));
    \n-
    1448 }
    \n-
    1449
    \n-
    1450 // minimize in given search direction
    \n-
    1451 _op->apply(*(p[ii]),q); // q=Ap
    \n-
    1452 pp[ii] = _sp->dot(*(p[ii]),q); // scalar product
    \n-
    1453 rho = _sp->dot(*(p[ii]),b); // orthogonalization
    \n-
    1454 lambda = rho/pp[ii]; // minimization
    \n-
    1455 x.axpy(lambda,*(p[ii])); // update solution
    \n-
    1456 b.axpy(-lambda,q); // update defect
    \n-
    1457
    \n-
    1458 // convergence test
    \n-
    1459 def = _sp->norm(b); // comp defect norm
    \n-
    1460
    \n-
    1461 ++i;
    \n-
    1462 iteration.step(i, def);
    \n-
    1463 }
    \n-
    1464 if(res.converged)
    \n-
    1465 break;
    \n-
    1466 if(end==_restart) {
    \n-
    1467 *(p[0])=*(p[_restart-1]);
    \n-
    1468 pp[0]=pp[_restart-1];
    \n-
    1469 }
    \n-
    1470 }
    \n-
    1471
    \n-
    1472 // postprocess preconditioner
    \n-
    1473 _prec->post(x);
    \n-
    1474
    \n-
    1475 }
    \n-
    1476
    \n-
    1477 private:
    \n-
    1478 using IterativeSolver<X,X>::_op;
    \n-
    1479 using IterativeSolver<X,X>::_prec;
    \n-
    1480 using IterativeSolver<X,X>::_sp;
    \n-
    1481 using IterativeSolver<X,X>::_reduction;
    \n-
    1482 using IterativeSolver<X,X>::_maxit;
    \n-
    1483 using IterativeSolver<X,X>::_verbose;
    \n-
    1484 using Iteration = typename IterativeSolver<X,X>::template Iteration<unsigned int>;
    \n-
    1485 int _restart;
    \n-
    1486 };
    \n-
    1487 DUNE_REGISTER_ITERATIVE_SOLVER("generalizedpcgsolver", defaultIterativeSolverCreator<Dune::GeneralizedPCGSolver>());
    \n-
    1488
    \n-
    1500 template<class X>
    \n-\n-
    1502 public:
    \n-
    1503 using typename IterativeSolver<X,X>::domain_type;
    \n-
    1504 using typename IterativeSolver<X,X>::range_type;
    \n-
    1505 using typename IterativeSolver<X,X>::field_type;
    \n-
    1506 using typename IterativeSolver<X,X>::real_type;
    \n-
    1507
    \n-
    1508 private:
    \n-\n-
    1510
    \n-
    1511 public:
    \n-
    1512 // don't shadow four-argument version of apply defined in the base class
    \n-
    1513 using IterativeSolver<X,X>::apply;
    \n-\n-
    1520 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) : IterativeSolver<X,X>(op, prec, reduction, maxit, verbose), _mmax(mmax)
    \n-
    1521 {
    \n-
    1522 }
    \n-
    1523
    \n-\n-
    1530 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)
    \n-
    1531 {
    \n-
    1532 }
    \n-
    1533
    \n-
    1539 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n-
    1540 std::shared_ptr<const ScalarProduct<X>> sp,
    \n-
    1541 std::shared_ptr<Preconditioner<X,X>> prec,
    \n-
    1542 scalar_real_type reduction, int maxit, int verbose,
    \n-
    1543 int mmax = 10)
    \n-
    1544 : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)
    \n-
    1545 {}
    \n-
    1546
    \n-
    1559 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n-
    1560 std::shared_ptr<Preconditioner<X,X>> prec,
    \n-
    1561 const ParameterTree& config)
    \n-
    1562 : IterativeSolver<X,X>(op, prec, config), _mmax(config.get("mmax", 10))
    \n-
    1563 {}
    \n-
    1564
    \n-
    1565 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n-
    1566 std::shared_ptr<const ScalarProduct<X>> sp,
    \n-
    1567 std::shared_ptr<Preconditioner<X,X>> prec,
    \n-
    1568 const ParameterTree& config)
    \n-
    1569 : IterativeSolver<X,X>(op, sp, prec, config), _mmax(config.get("mmax", 10))
    \n-
    1570 {}
    \n-
    1571
    \n-
    1584 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n-
    1585 {
    \n-\n-
    1587 res.clear();
    \n-
    1588 Iteration iteration(*this,res);
    \n-
    1589 _prec->pre(x,b); // prepare preconditioner
    \n-
    1590 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n-
    1591
    \n-
    1592 //arrays for interim values:
    \n-
    1593 std::vector<X> d(_mmax+1, x); // array for directions
    \n-
    1594 std::vector<X> Ad(_mmax+1, x); // array for Ad[i]
    \n-
    1595 std::vector<field_type,rAlloc> ddotAd(_mmax+1,0); // array for <d[i],Ad[i]>
    \n-
    1596 X w(x);
    \n-
    1597
    \n-
    1598 real_type def = _sp->norm(b); // compute norm
    \n-
    1599 if(iteration.step(0, def)){
    \n-
    1600 _prec->post(x);
    \n-
    1601 return;
    \n-
    1602 }
    \n-
    1603
    \n-
    1604 // some local variables
    \n-
    1605 field_type alpha;
    \n-
    1606
    \n-
    1607 // the loop
    \n-
    1608 int i=1;
    \n-
    1609 int i_bounded=0;
    \n-
    1610 while(i<=_maxit && !res.converged) {
    \n-
    1611 for (; i_bounded <= _mmax && i<= _maxit; i_bounded++) {
    \n-
    1612 d[i_bounded] = 0; // reset search direction
    \n-
    1613 _prec->apply(d[i_bounded], b); // apply preconditioner
    \n-
    1614 w = d[i_bounded]; // copy of current d[i]
    \n-
    1615 // orthogonalization with previous directions
    \n-
    1616 orthogonalizations(i_bounded,Ad,w,ddotAd,d);
    \n-
    1617
    \n-
    1618 //saving interim values for future calculating
    \n-
    1619 _op->apply(d[i_bounded], Ad[i_bounded]); // save Ad[i]
    \n-
    1620 ddotAd[i_bounded]=_sp->dot(d[i_bounded],Ad[i_bounded]); // save <d[i],Ad[i]>
    \n-
    1621 alpha = _sp->dot(d[i_bounded], b)/ddotAd[i_bounded]; // <d[i],b>/<d[i],Ad[i]>
    \n-
    1622
    \n-
    1623 //update solution and defect
    \n-
    1624 x.axpy(alpha, d[i_bounded]);
    \n-
    1625 b.axpy(-alpha, Ad[i_bounded]);
    \n-
    1626
    \n-
    1627 // convergence test
    \n-
    1628 def = _sp->norm(b); // comp defect norm
    \n-
    1629
    \n-
    1630 iteration.step(i, def);
    \n-
    1631 i++;
    \n-
    1632 }
    \n-
    1633 //restart: exchange first and last stored values
    \n-
    1634 cycle(Ad,d,ddotAd,i_bounded);
    \n-
    1635 }
    \n-
    1636
    \n-
    1637 //correct i which is wrong if convergence was not achieved.
    \n-
    1638 i=std::min(_maxit,i);
    \n-
    1639
    \n-
    1640 _prec->post(x); // postprocess preconditioner
    \n-
    1641 }
    \n-
    1642
    \n-
    1643 private:
    \n-
    1644 //This function is called every iteration to orthogonalize against the last search directions
    \n-
    1645 virtual void orthogonalizations(const int& i_bounded,const std::vector<X>& Ad, const X& w, const std::vector<field_type,ReboundAllocatorType<X,field_type>>& ddotAd,std::vector<X>& d) {
    \n-
    1646 // The RestartedFCGSolver uses only values with lower array index;
    \n-
    1647 for (int k = 0; k < i_bounded; k++) {
    \n-
    1648 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= <<Ad[k],w>/<d[k],Ad[k]>>d[k]
    \n-
    1649 }
    \n-
    1650 }
    \n-
    1651
    \n-
    1652 // This function is called every mmax iterations to handle limited array sizes.
    \n-
    1653 virtual void cycle(std::vector<X>& Ad,std::vector<X>& d,std::vector<field_type,ReboundAllocatorType<X,field_type> >& ddotAd,int& i_bounded) {
    \n-
    1654 // Reset loop index and exchange the first and last arrays
    \n-
    1655 i_bounded = 1;
    \n-
    1656 std::swap(Ad[0], Ad[_mmax]);
    \n-
    1657 std::swap(d[0], d[_mmax]);
    \n-
    1658 std::swap(ddotAd[0], ddotAd[_mmax]);
    \n-
    1659 }
    \n-
    1660
    \n-
    1661 protected:
    \n-\n-
    1663 using IterativeSolver<X,X>::_op;
    \n-
    1664 using IterativeSolver<X,X>::_prec;
    \n-
    1665 using IterativeSolver<X,X>::_sp;
    \n-
    1666 using IterativeSolver<X,X>::_reduction;
    \n-
    1667 using IterativeSolver<X,X>::_maxit;
    \n-
    1668 using IterativeSolver<X,X>::_verbose;
    \n-\n-
    1670 };
    \n-
    1671 DUNE_REGISTER_ITERATIVE_SOLVER("restartedfcgsolver", defaultIterativeSolverCreator<Dune::RestartedFCGSolver>());
    \n-
    1672
    \n-
    1679 template<class X>
    \n-\n-
    1681 public:
    \n-\n-
    1683 using typename RestartedFCGSolver<X>::range_type;
    \n-
    1684 using typename RestartedFCGSolver<X>::field_type;
    \n-
    1685 using typename RestartedFCGSolver<X>::real_type;
    \n-
    1686
    \n-
    1687 // copy base class constructors
    \n-\n-
    1689
    \n-
    1690 // don't shadow four-argument version of apply defined in the base class
    \n-\n-
    1692
    \n-
    1693 // just a minor part of the RestartedFCGSolver apply method will be modified
    \n-
    1694 virtual void apply (X& x, X& b, InverseOperatorResult& res) override {
    \n-
    1695 // reset limiter of orthogonalization loop
    \n-
    1696 _k_limit = 0;
    \n-
    1697 this->RestartedFCGSolver<X>::apply(x,b,res);
    \n-
    1698 };
    \n-
    1699
    \n-
    1700 private:
    \n-
    1701 // This function is called every iteration to orthogonalize against the last search directions.
    \n-
    1702 virtual void orthogonalizations(const int& i_bounded,const std::vector<X>& Ad, const X& w, const std::vector<field_type,ReboundAllocatorType<X,field_type>>& ddotAd,std::vector<X>& d) override {
    \n-
    1703 // This FCGSolver uses values with higher array indexes too, if existent.
    \n-
    1704 for (int k = 0; k < _k_limit; k++) {
    \n-
    1705 if(i_bounded!=k)
    \n-
    1706 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= <<Ad[k],w>/<d[k],Ad[k]>>d[k]
    \n-
    1707 }
    \n-
    1708 // The loop limit increase, if array is not completely filled.
    \n-
    1709 if(_k_limit<=i_bounded)
    \n-
    1710 _k_limit++;
    \n-
    1711
    \n-
    1712 };
    \n-
    1713
    \n-
    1714 // This function is called every mmax iterations to handle limited array sizes.
    \n-
    1715 virtual void cycle(std::vector<X>& Ad, [[maybe_unused]] std::vector<X>& d, [[maybe_unused]] std::vector<field_type,ReboundAllocatorType<X,field_type> >& ddotAd,int& i_bounded) override {
    \n-
    1716 // Only the loop index i_bounded return to 0, if it reached mmax.
    \n-
    1717 i_bounded = 0;
    \n-
    1718 // Now all arrays are filled and the loop in void orthogonalizations can use the whole arrays.
    \n-
    1719 _k_limit = Ad.size();
    \n-
    1720 };
    \n-
    1721
    \n-
    1722 int _k_limit = 0;
    \n-
    1723
    \n-
    1724 protected:
    \n-\n-
    1726 using RestartedFCGSolver<X>::_op;
    \n-\n-
    1728 using RestartedFCGSolver<X>::_sp;
    \n-\n-\n-\n-
    1732 };
    \n-
    1733 DUNE_REGISTER_ITERATIVE_SOLVER("completefcgsolver", defaultIterativeSolverCreator<Dune::CompleteFCGSolver>());
    \n-
    1735} // end namespace
    \n-
    1736
    \n-
    1737#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-\n-
    Define general, extensible interface for inverse operators.
    \n-\n-\n-\n-
    Define base class for scalar product and norm.
    \n-\n-
    Implementation of the BCRSMatrix class.
    \n-
    DUNE_REGISTER_ITERATIVE_SOLVER("loopsolver", defaultIterativeSolverCreator< Dune::LoopSolver >())
    \n+
    533 protected:
    \n+
    538 template <bool is_direct_solver, typename Dummy = void>
    \n+\n+
    540 {
    \n+
    541 static void setMatrix (ISTLLinearSolver&,
    \n+
    542 const BCRSMatrix&)
    \n+
    543 {}
    \n+
    544 };
    \n+
    545
    \n+
    550 template <typename Dummy>
    \n+
    551 struct Implementation<true,Dummy>
    \n+
    552 {
    \n+
    553 static void setMatrix (ISTLLinearSolver& solver,
    \n+
    554 const BCRSMatrix& matrix)
    \n+
    555 {
    \n+
    556 solver.setMatrix(matrix);
    \n+
    557 }
    \n+
    558 };
    \n+
    559 };
    \n+
    560
    \n+
    564}
    \n+
    565
    \n+
    566#endif
    \n+
    Define base class for scalar product and norm.
    \n+
    Templates characterizing the type of a solver.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+\n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X > ReboundAllocatorType
    Definition: allocator.hh:37
    \n-
    std::enable_if_t<!is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:733
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    @ row_wise
    Build in a row-wise manner.
    Definition: bcrsmatrix.hh:521
    \n-
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: bcrsmatrix.hh:1103
    \n-
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n-
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    Wrapper to use a range of ARPACK++ eigenvalue solvers.
    Definition: arpackpp.hh:245
    \n-
    void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:289
    \n-
    void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:391
    \n
    Thrown when a solver aborts due to some problem.
    Definition: istlexception.hh:46
    \n-\n-\n+
    A linear operator.
    Definition: operators.hh:67
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n+
    Default implementation for the scalar case.
    Definition: scalarproducts.hh:168
    \n
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    InverseOperatorResult()
    Default constructor.
    Definition: solver.hh:50
    \n
    double condition_estimate
    Estimate of condition number.
    Definition: solver.hh:79
    \n+
    double elapsed
    Elapsed time in seconds.
    Definition: solver.hh:82
    \n+
    int iterations
    Number of iterations.
    Definition: solver.hh:67
    \n+
    double reduction
    Reduction achieved: .
    Definition: solver.hh:70
    \n
    void clear()
    Resets all data.
    Definition: solver.hh:56
    \n+
    double conv_rate
    Convergence rate (average reduction per step)
    Definition: solver.hh:76
    \n
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n-
    Simd::Scalar< real_type > scalar_real_type
    scalar type underlying the field_type
    Definition: solver.hh:114
    \n+
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n+
    void printHeader(std::ostream &s) const
    helper function for printing header of solver output
    Definition: solver.hh:163
    \n+
    virtual ~InverseOperator()
    Destructor.
    Definition: solver.hh:156
    \n+
    void printOutput(std::ostream &s, const CountType &iter, const DataType &norm) const
    helper function for printing solver output
    Definition: solver.hh:185
    \n+
    void printOutput(std::ostream &s, const CountType &iter, const DataType &norm, const DataType &norm_old) const
    helper function for printing solver output
    Definition: solver.hh:172
    \n+
    virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)=0
    apply inverse operator, with given convergence criteria.
    \n+
    Simd::Scalar< real_type > scalar_real_type
    scalar type underlying the field_type
    Definition: solver.hh:114
    \n
    Y range_type
    Type of the range of the operator to be inverted.
    Definition: solver.hh:105
    \n+
    @ normSpacing
    Definition: solver.hh:160
    \n+
    @ iterationSpacing
    Definition: solver.hh:160
    \n
    X domain_type
    Type of the domain of the operator to be inverted.
    Definition: solver.hh:102
    \n-
    X::field_type field_type
    The field type of the operator.
    Definition: solver.hh:108
    \n-
    FieldTraits< field_type >::real_type real_type
    The real type of the field type (is the same if using real numbers, but differs for std::complex)
    Definition: solver.hh:111
    \n+
    virtual void apply(X &x, Y &b, InverseOperatorResult &res)=0
    Apply inverse operator,.
    \n+
    X::field_type field_type
    The field type of the operator.
    Definition: solver.hh:108
    \n+
    FieldTraits< field_type >::real_type real_type
    The real type of the field type (is the same if using real numbers, but differs for std::complex)
    Definition: solver.hh:111
    \n+
    virtual SolverCategory::Category category() const =0
    Category of the solver (see SolverCategory::Category)
    \n
    Base class for all implementations of iterative solvers.
    Definition: solver.hh:203
    \n-
    std::shared_ptr< const ScalarProduct< X > > _sp
    Definition: solver.hh:506
    \n-
    IterativeSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:230
    \n-
    std::shared_ptr< const LinearOperator< X, X > > _op
    Definition: solver.hh:504
    \n-
    int _maxit
    Definition: solver.hh:508
    \n-
    int _verbose
    Definition: solver.hh:509
    \n-
    scalar_real_type _reduction
    Definition: solver.hh:507
    \n-
    std::shared_ptr< Preconditioner< X, X > > _prec
    Definition: solver.hh:505
    \n-
    Preconditioned loop solver.
    Definition: solvers.hh:59
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator,.
    Definition: solvers.hh:73
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:116
    \n-
    gradient method
    Definition: solvers.hh:124
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:142
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:187
    \n-
    conjugate gradient method
    Definition: solvers.hh:193
    \n-
    CGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:256
    \n-
    static constexpr bool enableConditionEstimate
    Definition: solvers.hh:208
    \n-
    CGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:239
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:279
    \n-
    CGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:222
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:412
    \n-
    Bi-conjugate Gradient Stabilized (BiCG-STAB)
    Definition: solvers.hh:419
    \n-
    typename IterativeSolver< X, X >::template Iteration< CountType > Iteration
    Definition: solvers.hh:598
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:439
    \n-
    Minimal Residual Method (MINRES)
    Definition: solvers.hh:609
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:627
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:808
    \n-
    implements the Generalized Minimal Residual (GMRes) method
    Definition: solvers.hh:827
    \n-
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solvers.hh:878
    \n-
    std::enable_if<!std::is_same< field_type, real_type >::value, T >::type conjugate(const T &t)
    Definition: solvers.hh:1067
    \n-
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Definition: solvers.hh:883
    \n-
    void update(X &w, int i, const std::vector< std::vector< field_type, fAlloc > > &H, const std::vector< field_type, fAlloc > &s, const std::vector< X > &v)
    Definition: solvers.hh:1039
    \n-
    std::enable_if< std::is_same< field_type, real_type >::value, T >::type conjugate(const T &t)
    Definition: solvers.hh:1062
    \n-
    ReboundAllocatorType< X, field_type > fAlloc
    field_type Allocator retrieved from domain type
    Definition: solvers.hh:838
    \n-
    int _restart
    Definition: solvers.hh:1120
    \n-
    ReboundAllocatorType< X, real_type > rAlloc
    real_type Allocator retrieved from domain type
    Definition: solvers.hh:840
    \n-
    virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:923
    \n-
    RestartedGMResSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:850
    \n-
    RestartedGMResSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:861
    \n-
    void generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    Definition: solvers.hh:1073
    \n-
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, Y > > prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:894
    \n-
    virtual void apply(X &x, Y &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:910
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:1119
    \n-
    void applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    Definition: solvers.hh:1106
    \n-
    implements the Flexible Generalized Minimal Residual (FGMRes) method (right preconditioned)
    Definition: solvers.hh:1139
    \n-
    void apply(X &x, Y &b, double reduction, InverseOperatorResult &res) override
    Apply inverse operator.
    Definition: solvers.hh:1169
    \n-
    Generalized preconditioned conjugate gradient solver.
    Definition: solvers.hh:1307
    \n-
    GeneralizedPCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1343
    \n-
    GeneralizedPCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1331
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:1391
    \n-
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solvers.hh:1361
    \n-
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1377
    \n-
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Definition: solvers.hh:1366
    \n-
    Accelerated flexible conjugate gradient method.
    Definition: solvers.hh:1501
    \n-
    RestartedFCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1519
    \n-
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)
    Constructor.
    Definition: solvers.hh:1559
    \n-
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1539
    \n-
    int _mmax
    Definition: solvers.hh:1662
    \n-
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)
    Definition: solvers.hh:1565
    \n-
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:1669
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:1584
    \n-
    RestartedFCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1529
    \n-
    Complete flexible conjugate gradient method.
    Definition: solvers.hh:1680
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res) override
    Apply inverse operator.
    Definition: solvers.hh:1694
    \n+
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solver.hh:313
    \n+
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solver.hh:290
    \n+
    virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)
    Apply inverse operator with given reduction factor.
    Definition: solver.hh:374
    \n+
    std::shared_ptr< const ScalarProduct< X > > _sp
    Definition: solver.hh:506
    \n+
    IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, Y > > prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:340
    \n+
    std::string name() const
    Definition: solver.hh:388
    \n+
    IterativeSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:230
    \n+
    std::shared_ptr< const LinearOperator< X, Y > > _op
    Definition: solver.hh:504
    \n+
    int _maxit
    Definition: solver.hh:508
    \n+
    int _verbose
    Definition: solver.hh:509
    \n+
    scalar_real_type _reduction
    Definition: solver.hh:507
    \n+
    IterativeSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:262
    \n+
    SolverCategory::Category _category
    Definition: solver.hh:510
    \n+
    std::shared_ptr< Preconditioner< X, Y > > _prec
    Definition: solver.hh:505
    \n+
    virtual SolverCategory::Category category() const
    Category of the solver (see SolverCategory::Category)
    Definition: solver.hh:383
    \n+
    Class for controlling iterative methods.
    Definition: solver.hh:411
    \n+
    Iteration(const IterativeSolver &parent, InverseOperatorResult &res)
    Definition: solver.hh:413
    \n+
    Iteration(Iteration &&other)
    Definition: solver.hh:428
    \n+
    InverseOperatorResult & _res
    Definition: solver.hh:498
    \n+
    const IterativeSolver & _parent
    Definition: solver.hh:499
    \n+
    Timer _watch
    Definition: solver.hh:497
    \n+
    Iteration(const Iteration &)=delete
    \n+
    CountType _i
    Definition: solver.hh:496
    \n+
    real_type _def0
    Definition: solver.hh:495
    \n+
    bool step(CountType i, real_type def)
    registers the iteration step, checks for invalid defect norm and convergence.
    Definition: solver.hh:455
    \n+
    void finalize()
    Definition: solver.hh:480
    \n+
    real_type _def
    Definition: solver.hh:495
    \n+
    ~Iteration()
    Definition: solver.hh:440
    \n+
    bool _valid
    Definition: solver.hh:500
    \n+
    Helper class for notifying a DUNE-ISTL linear solver about a change of the iteration matrix object in...
    Definition: solver.hh:522
    \n+
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:524
    \n+
    Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTAB...
    Definition: solver.hh:540
    \n+
    static void setMatrix(ISTLLinearSolver &, const BCRSMatrix &)
    Definition: solver.hh:541
    \n+
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:553
    \n+
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    Definition: solvercategory.hh:54
    \n+
    Definition: solvertype.hh:16
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1937 +4,644 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solvers.hh\n+solver.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n 5\n- 6#ifndef DUNE_ISTL_SOLVERS_HH\n- 7#define DUNE_ISTL_SOLVERS_HH\n+ 6#ifndef DUNE_ISTL_SOLVER_HH\n+ 7#define DUNE_ISTL_SOLVER_HH\n 8\n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16\n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23\n- 24#include \n- 25#include \n- 26#include \n- 27#include \n- 28#include \n- 29#include \n- 30#include \n- 31#include \n- 32#include \n- 33\n- 34namespace Dune {\n- 46 //=====================================================================\n- 47 // Implementation of this interface\n- 48 //=====================================================================\n- 49\n- 58 template\n-59 class LoopSolver : public IterativeSolver {\n- 60 public:\n- 61 using typename IterativeSolver::domain_type;\n- 62 using typename IterativeSolver::range_type;\n- 63 using typename IterativeSolver::field_type;\n- 64 using typename IterativeSolver::real_type;\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20\n+ 21#include \"solvertype.hh\"\n+ 22#include \"preconditioner.hh\"\n+ 23#include \"operators.hh\"\n+ 24#include \"scalarproducts.hh\"\n+ 25\n+ 26namespace Dune\n+ 27{\n+47 struct InverseOperatorResult\n+ 48 {\n+50 InverseOperatorResult ()\n+ 51 {\n+ 52 clear();\n+ 53 }\n+ 54\n+56 void clear ()\n+ 57 {\n+ 58 iterations = 0;\n+ 59 reduction = 0;\n+ 60 converged = false;\n+ 61 conv_rate = 1;\n+ 62 elapsed = 0;\n+ 63 condition_estimate = -1;\n+ 64 }\n 65\n- 66 // copy base class constructors\n- 67 using IterativeSolver::IterativeSolver;\n+67 int iterations;\n 68\n- 69 // don't shadow four-argument version of apply defined in the base class\n- 70 using IterativeSolver::apply;\n+70 double reduction;\n 71\n-73 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 74 {\n- 75 Iteration iteration(*this, res);\n- 76 _prec->pre(x,b);\n+73 bool converged;\n+ 74\n+76 double conv_rate;\n 77\n- 78 // overwrite b with defect\n- 79 _op->applyscaleadd(-1,x,b);\n+79 double condition_estimate = -1;\n 80\n- 81 // compute norm, \\todo parallelization\n- 82 real_type def = _sp->norm(b);\n- 83 if(iteration.step(0, def)){\n- 84 _prec->post(x);\n- 85 return;\n- 86 }\n- 87 // prepare preconditioner\n- 88\n- 89 // allocate correction vector\n- 90 X v(x);\n- 91\n- 92 // iteration loop\n- 93 int i=1;\n- 94 for ( ; i<=_maxit; i++ )\n- 95 {\n- 96 v = 0; // clear correction\n- 97 _prec->apply(v,b); // apply preconditioner\n- 98 x += v; // update solution\n- 99 _op->applyscaleadd(-1,v,b); // update defect\n- 100 def=_sp->norm(b); // comp defect norm\n- 101 if(iteration.step(i, def))\n- 102 break;\n- 103 }\n- 104\n- 105 // postprocess preconditioner\n- 106 _prec->post(x);\n- 107 }\n- 108\n- 109 protected:\n- 110 using IterativeSolver::_op;\n- 111 using IterativeSolver::_prec;\n- 112 using IterativeSolver::_sp;\n- 113 using IterativeSolver::_reduction;\n- 114 using IterativeSolver::_maxit;\n- 115 using IterativeSolver::_verbose;\n-116 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 117 };\n-118 DUNE_REGISTER_ITERATIVE_SOLVER(\"loopsolver\",\n-defaultIterativeSolverCreator());\n- 119\n- 120\n- 121 // all these solvers are taken from the SUMO library\n- 123 template\n-124 class GradientSolver : public IterativeSolver {\n- 125 public:\n- 126 using typename IterativeSolver::domain_type;\n- 127 using typename IterativeSolver::range_type;\n- 128 using typename IterativeSolver::field_type;\n- 129 using typename IterativeSolver::real_type;\n- 130\n- 131 // copy base class constructors\n- 132 using IterativeSolver::IterativeSolver;\n- 133\n- 134 // don't shadow four-argument version of apply defined in the base class\n- 135 using IterativeSolver::apply;\n- 136\n-142 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 143 {\n- 144 Iteration iteration(*this, res);\n- 145 _prec->pre(x,b); // prepare preconditioner\n- 146\n- 147 _op->applyscaleadd(-1,x,b); // overwrite b with defec\n- 148\n- 149 real_type def = _sp->norm(b); // compute norm\n- 150 if(iteration.step(0, def)){\n- 151 _prec->post(x);\n- 152 return;\n- 153 }\n+82 double elapsed;\n+ 83 };\n+ 84\n+ 85\n+ 86 //=====================================================================\n+ 98 template\n+99 class InverseOperator {\n+ 100 public:\n+102 typedef X domain_type;\n+ 103\n+105 typedef Y range_type;\n+ 106\n+108 typedef typename X::field_type field_type;\n+ 109\n+111 typedef typename FieldTraits::real_type real_type;\n+ 112\n+114 typedef Simd::Scalar scalar_real_type;\n+ 115\n+128 virtual void apply (X& x, Y& b, InverseOperatorResult& res) = 0;\n+ 129\n+143 virtual void apply (X& x, Y& b, double reduction, InverseOperatorResult&\n+res) = 0;\n+ 144\n+146 virtual SolverCategory::Category category() const\n+ 147#ifdef DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n+ 148 {\n+ 149 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n+method in a derived classes, in the future this method will pure virtual.\");\n+ 150 }\n+ 151#else\n+ 152 = 0;\n+ 153#endif\n 154\n- 155 X p(x); // create local vectors\n- 156 X q(b);\n+156 virtual ~InverseOperator () {}\n 157\n- 158 int i=1; // loop variables\n- 159 field_type lambda;\n- 160 for ( ; i<=_maxit; i++ )\n- 161 {\n- 162 p = 0; // clear correction\n- 163 _prec->apply(p,b); // apply preconditioner\n- 164 _op->apply(p,q); // q=Ap\n- 165 auto alpha = _sp->dot(q,p);\n- 166 lambda = Simd::cond(def==field_type(0.),\n- 167 field_type(0.), // no need for minimization if def is already 0\n- 168 _sp->dot(p,b)/alpha); // minimization\n- 169 x.axpy(lambda,p); // update solution\n- 170 b.axpy(-lambda,q); // update defect\n- 171\n- 172 def =_sp->norm(b); // comp defect norm\n- 173 if(iteration.step(i, def))\n- 174 break;\n- 175 }\n- 176 // postprocess preconditioner\n- 177 _prec->post(x);\n- 178 }\n- 179\n- 180 protected:\n- 181 using IterativeSolver::_op;\n- 182 using IterativeSolver::_prec;\n- 183 using IterativeSolver::_sp;\n- 184 using IterativeSolver::_reduction;\n- 185 using IterativeSolver::_maxit;\n- 186 using IterativeSolver::_verbose;\n-187 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 188 };\n-189 DUNE_REGISTER_ITERATIVE_SOLVER(\"gradientsolver\",\n-defaultIterativeSolverCreator());\n- 190\n- 192 template\n-193 class CGSolver : public IterativeSolver {\n- 194 public:\n- 195 using typename IterativeSolver::domain_type;\n- 196 using typename IterativeSolver::range_type;\n- 197 using typename IterativeSolver::field_type;\n- 198 using typename IterativeSolver::real_type;\n- 199\n- 200 // copy base class constructors\n- 201 using IterativeSolver::IterativeSolver;\n- 202\n- 203 private:\n- 204 using typename IterativeSolver::scalar_real_type;\n- 205\n- 206 protected:\n- 207\n-208 static constexpr bool enableConditionEstimate = (std::\n-is_same_v || std::is_same_v);\n- 209\n- 210 public:\n- 211\n- 212 // don't shadow four-argument version of apply defined in the base class\n- 213 using IterativeSolver::apply;\n- 214\n-222 CGSolver (const LinearOperator& op, Preconditioner& prec,\n- 223 scalar_real_type reduction, int maxit, int verbose, bool\n-condition_estimate) : IterativeSolver(op, prec, reduction, maxit,\n-verbose),\n- 224 condition_estimate_(condition_estimate)\n- 225 {\n- 226 if (condition_estimate && !enableConditionEstimate) {\n- 227 condition_estimate_ = false;\n- 228 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n-available for double and float field types!\" << std::endl;\n- 229 }\n- 230 }\n- 231\n-239 CGSolver (const LinearOperator& op, const ScalarProduct& sp,\n-Preconditioner& prec,\n- 240 scalar_real_type reduction, int maxit, int verbose, bool\n-condition_estimate) : IterativeSolver(op, sp, prec, reduction, maxit,\n-verbose),\n- 241 condition_estimate_(condition_estimate)\n- 242 {\n- 243 if (condition_estimate && !(std::is_same::value || std::\n-is_same::value)) {\n- 244 condition_estimate_ = false;\n- 245 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n-available for double and float field types!\" << std::endl;\n- 246 }\n- 247 }\n- 248\n-256 CGSolver (std::shared_ptr> op, std::\n-shared_ptr> sp,\n- 257 std::shared_ptr> prec,\n- 258 scalar_real_type reduction, int maxit, int verbose, bool\n-condition_estimate)\n- 259 : IterativeSolver(op, sp, prec, reduction, maxit, verbose),\n- 260 condition_estimate_(condition_estimate)\n- 261 {\n- 262 if (condition_estimate && !(std::is_same::value || std::\n-is_same::value)) {\n- 263 condition_estimate_ = false;\n- 264 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n-available for double and float field types!\" << std::endl;\n- 265 }\n- 266 }\n- 267\n-279 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 280 {\n- 281 Iteration iteration(*this,res);\n- 282 _prec->pre(x,b); // prepare preconditioner\n- 283\n- 284 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n- 285\n- 286 real_type def = _sp->norm(b); // compute norm\n- 287 if(iteration.step(0, def)){\n- 288 _prec->post(x);\n- 289 return;\n- 290 }\n- 291\n- 292 X p(x); // the search direction\n- 293 X q(x); // a temporary vector\n- 294\n- 295 // Remember lambda and beta values for condition estimate\n- 296 std::vector lambdas(0);\n- 297 std::vector betas(0);\n- 298\n- 299 // some local variables\n- 300 field_type rho,rholast,lambda,alpha,beta;\n- 301\n- 302 // determine initial search direction\n- 303 p = 0; // clear correction\n- 304 _prec->apply(p,b); // apply preconditioner\n- 305 rholast = _sp->dot(p,b); // orthogonalization\n- 306\n- 307 // the loop\n- 308 int i=1;\n- 309 for ( ; i<=_maxit; i++ )\n- 310 {\n- 311 // minimize in given search direction p\n- 312 _op->apply(p,q); // q=Ap\n- 313 alpha = _sp->dot(p,q); // scalar product\n- 314 lambda = Simd::cond(def==field_type(0.), field_type(0.), rholast/alpha); /\n-/ minimization\n- 315 if constexpr (enableConditionEstimate)\n- 316 if (condition_estimate_)\n- 317 lambdas.push_back(std::real(lambda));\n- 318 x.axpy(lambda,p); // update solution\n- 319 b.axpy(-lambda,q); // update defect\n- 320\n- 321 // convergence test\n- 322 def=_sp->norm(b); // comp defect norm\n- 323 if(iteration.step(i, def))\n- 324 break;\n- 325\n- 326 // determine new search direction\n- 327 q = 0; // clear correction\n- 328 _prec->apply(q,b); // apply preconditioner\n- 329 rho = _sp->dot(q,b); // orthogonalization\n- 330 beta = Simd::cond(def==field_type(0.), field_type(0.), rho/rholast); /\n-/ scaling factor\n- 331 if constexpr (enableConditionEstimate)\n- 332 if (condition_estimate_)\n- 333 betas.push_back(std::real(beta));\n- 334 p *= beta; // scale old search direction\n- 335 p += q; // orthogonalization with correction\n- 336 rholast = rho; // remember rho for recurrence\n- 337 }\n- 338\n- 339 _prec->post(x); // postprocess preconditioner\n- 340\n- 341 if (condition_estimate_) {\n- 342#if HAVE_ARPACKPP\n- 343 if constexpr (enableConditionEstimate) {\n- 344 using std::sqrt;\n- 345\n- 346 // Build T matrix which has extreme eigenvalues approximating\n- 347 // those of the original system\n- 348 // (see Y. Saad, Iterative methods for sparse linear systems)\n- 349\n- 350 COND_MAT T(i, i, COND_MAT::row_wise);\n- 351\n- 352 for (auto row = T.createbegin(); row != T.createend(); ++row) {\n- 353 if (row.index() > 0)\n- 354 row.insert(row.index()-1);\n- 355 row.insert(row.index());\n- 356 if (row.index() < T.N() - 1)\n- 357 row.insert(row.index()+1);\n- 358 }\n- 359 for (int row = 0; row < i; ++row) {\n- 360 if (row > 0) {\n- 361 T[row][row-1] = sqrt(betas[row-1]) / lambdas[row-1];\n- 362 }\n- 363\n- 364 T[row][row] = 1.0 / lambdas[row];\n- 365 if (row > 0) {\n- 366 T[row][row] += betas[row-1] / lambdas[row-1];\n- 367 }\n+ 158 protected:\n+ 159 // spacing values\n+160 enum { iterationSpacing = 5 , normSpacing = 16 };\n+ 161\n+163 void printHeader(std::ostream& s) const\n+ 164 {\n+ 165 s << std::setw(iterationSpacing) << \" Iter\";\n+ 166 s << std::setw(normSpacing) << \"Defect\";\n+ 167 s << std::setw(normSpacing) << \"Rate\" << std::endl;\n+ 168 }\n+ 169\n+ 171 template \n+172 void printOutput(std::ostream& s,\n+ 173 const CountType& iter,\n+ 174 const DataType& norm,\n+ 175 const DataType& norm_old) const\n+ 176 {\n+ 177 const DataType rate = norm/norm_old;\n+ 178 s << std::setw(iterationSpacing) << iter << \" \";\n+ 179 s << std::setw(normSpacing) << Simd::io(norm) << \" \";\n+ 180 s << std::setw(normSpacing) << Simd::io(rate) << std::endl;\n+ 181 }\n+ 182\n+ 184 template \n+185 void printOutput(std::ostream& s,\n+ 186 const CountType& iter,\n+ 187 const DataType& norm) const\n+ 188 {\n+ 189 s << std::setw(iterationSpacing) << iter << \" \";\n+ 190 s << std::setw(normSpacing) << Simd::io(norm) << std::endl;\n+ 191 }\n+ 192 };\n+ 193\n+ 202 template\n+203 class IterativeSolver : public InverseOperator{\n+ 204 public:\n+ 205 using typename InverseOperator::domain_type;\n+ 206 using typename InverseOperator::range_type;\n+ 207 using typename InverseOperator::field_type;\n+ 208 using typename InverseOperator::real_type;\n+ 209 using typename InverseOperator::scalar_real_type;\n+ 210\n+230 IterativeSolver (const LinearOperator& op, Preconditioner& prec,\n+scalar_real_type reduction, int maxit, int verbose) :\n+ 231 _op(stackobject_to_shared_ptr(op)),\n+ 232 _prec(stackobject_to_shared_ptr(prec)),\n+ 233 _sp(new SeqScalarProduct),\n+ 234 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category\n+(SolverCategory::sequential)\n+ 235 {\n+ 236 if(SolverCategory::category(op) != SolverCategory::sequential)\n+ 237 DUNE_THROW(InvalidSolverCategory, \"LinearOperator has to be sequential!\");\n+ 238 if(SolverCategory::category(prec) != SolverCategory::sequential)\n+ 239 DUNE_THROW(InvalidSolverCategory, \"Preconditioner has to be sequential!\");\n+ 240 }\n+ 241\n+262 IterativeSolver (const LinearOperator& op, const ScalarProduct& sp,\n+Preconditioner& prec,\n+ 263 scalar_real_type reduction, int maxit, int verbose) :\n+ 264 _op(stackobject_to_shared_ptr(op)),\n+ 265 _prec(stackobject_to_shared_ptr(prec)),\n+ 266 _sp(stackobject_to_shared_ptr(sp)),\n+ 267 _reduction(reduction), _maxit(maxit), _verbose(verbose), _category\n+(SolverCategory::category(op))\n+ 268 {\n+ 269 if(SolverCategory::category(op) != SolverCategory::category(prec))\n+ 270 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and Preconditioner must\n+have the same SolverCategory!\");\n+ 271 if(SolverCategory::category(op) != SolverCategory::category(sp))\n+ 272 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and ScalarProduct must\n+have the same SolverCategory!\");\n+ 273 }\n+ 274\n+290 IterativeSolver (std::shared_ptr > op, std::\n+shared_ptr > prec, const ParameterTree& configuration) :\n+ 291 IterativeSolver(op,std::make_shared>(),prec,\n+ 292 configuration.get(\"reduction\"),\n+ 293 configuration.get(\"maxit\"),\n+ 294 configuration.get(\"verbose\"))\n+ 295 {}\n+ 296\n+313 IterativeSolver (std::shared_ptr > op, std::\n+shared_ptr > sp, std::shared_ptr >\n+prec, const ParameterTree& configuration) :\n+ 314 IterativeSolver(op,sp,prec,\n+ 315 configuration.get(\"reduction\"),\n+ 316 configuration.get(\"maxit\"),\n+ 317 configuration.get(\"verbose\"))\n+ 318 {}\n+ 319\n+340 IterativeSolver (std::shared_ptr> op,\n+ 341 std::shared_ptr> sp,\n+ 342 std::shared_ptr> prec,\n+ 343 scalar_real_type reduction, int maxit, int verbose) :\n+ 344 _op(op),\n+ 345 _prec(prec),\n+ 346 _sp(sp),\n+ 347 _reduction(reduction), _maxit(maxit), _verbose(verbose),\n+ 348 _category(SolverCategory::category(*op))\n+ 349 {\n+ 350 if(SolverCategory::category(*op) != SolverCategory::category(*prec))\n+ 351 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and Preconditioner must\n+have the same SolverCategory!\");\n+ 352 if(SolverCategory::category(*op) != SolverCategory::category(*sp))\n+ 353 DUNE_THROW(InvalidSolverCategory, \"LinearOperator and ScalarProduct must\n+have the same SolverCategory!\");\n+ 354 }\n+ 355\n+ 356 // #warning actually we want to have this as the default and just\n+implement the second one\n+ 357 // //! \\copydoc InverseOperator::apply(X&,Y&,InverseOperatorResult&)\n+ 358 // virtual void apply (X& x, Y& b, InverseOperatorResult& res)\n+ 359 // {\n+ 360 // apply(x,b,_reduction,res);\n+ 361 // }\n+ 362\n+ 363#ifndef DOXYGEN\n+ 364 // make sure the three-argument apply from the base class does not get\n+shadowed\n+ 365 // by the redefined four-argument version below\n+ 366 using InverseOperator::apply;\n+ 367#endif\n 368\n- 369 if (row < i - 1) {\n- 370 T[row][row+1] = sqrt(betas[row]) / lambdas[row];\n- 371 }\n- 372 }\n- 373\n- 374 // Compute largest and smallest eigenvalue of T matrix and return as\n-estimate\n- 375 Dune::ArPackPlusPlus_Algorithms arpack(T);\n- 376\n- 377 real_type eps = 0.0;\n- 378 COND_VEC eigv;\n- 379 real_type min_eigv, max_eigv;\n- 380 arpack.computeSymMinMagnitude (eps, eigv, min_eigv);\n- 381 arpack.computeSymMaxMagnitude (eps, eigv, max_eigv);\n- 382\n- 383 res.condition_estimate = max_eigv / min_eigv;\n- 384\n- 385 if (this->_verbose > 0) {\n- 386 std::cout << \"Min eigv estimate: \" << Simd::io(min_eigv) << '\\n';\n- 387 std::cout << \"Max eigv estimate: \" << Simd::io(max_eigv) << '\\n';\n- 388 std::cout << \"Condition estimate: \"\n- 389 << Simd::io(max_eigv / min_eigv) << std::endl;\n- 390 }\n+374 virtual void apply (X& x, X& b, double reduction, InverseOperatorResult&\n+res)\n+ 375 {\n+ 376 scalar_real_type saved_reduction = _reduction;\n+ 377 _reduction = reduction;\n+ 378 this->apply(x,b,res);\n+ 379 _reduction = saved_reduction;\n+ 380 }\n+ 381\n+383 virtual SolverCategory::Category category() const\n+ 384 {\n+ 385 return _category;\n+ 386 }\n+ 387\n+388 std::string name() const{\n+ 389 std::string name = className(*this);\n+ 390 return name.substr(0, name.find(\"<\"));\n 391 }\n- 392#else\n- 393 std::cerr << \"WARNING: Condition estimate was requested. This requires\n-ARPACK, but ARPACK was not found!\" << std::endl;\n- 394#endif\n- 395 }\n- 396 }\n- 397\n- 398 private:\n- 399 bool condition_estimate_ = false;\n- 400\n- 401 // Matrix and vector types used for condition estimate\n- 402 typedef Dune::BCRSMatrix > COND_MAT;\n- 403 typedef Dune::BlockVector > COND_VEC;\n- 404\n- 405 protected:\n- 406 using IterativeSolver::_op;\n- 407 using IterativeSolver::_prec;\n- 408 using IterativeSolver::_sp;\n- 409 using IterativeSolver::_reduction;\n- 410 using IterativeSolver::_maxit;\n- 411 using IterativeSolver::_verbose;\n-412 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 413 };\n-414 DUNE_REGISTER_ITERATIVE_SOLVER(\"cgsolver\",\n-defaultIterativeSolverCreator());\n- 415\n- 416 // Ronald Kriemanns BiCG-STAB implementation from Sumo\n- 418 template\n-419 class BiCGSTABSolver : public IterativeSolver {\n- 420 public:\n- 421 using typename IterativeSolver::domain_type;\n- 422 using typename IterativeSolver::range_type;\n- 423 using typename IterativeSolver::field_type;\n- 424 using typename IterativeSolver::real_type;\n- 425\n- 426 // copy base class constructors\n- 427 using IterativeSolver::IterativeSolver;\n- 428\n- 429 // don't shadow four-argument version of apply defined in the base class\n- 430 using IterativeSolver::apply;\n- 431\n-439 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 440 {\n- 441 using std::abs;\n- 442 const Simd::Scalar EPSILON=1e-80;\n- 443 using std::abs;\n- 444 double it;\n- 445 field_type rho, rho_new, alpha, beta, h, omega;\n- 446 real_type norm;\n- 447\n- 448 //\n- 449 // get vectors and matrix\n- 450 //\n- 451 X& r=b;\n- 452 X p(x);\n- 453 X v(x);\n- 454 X t(x);\n- 455 X y(x);\n- 456 X rt(x);\n- 457\n- 458 //\n- 459 // begin iteration\n- 460 //\n- 461\n- 462 // r = r - Ax; rt = r\n- 463 Iteration iteration(*this,res);\n- 464 _prec->pre(x,r); // prepare preconditioner\n- 465\n- 466 _op->applyscaleadd(-1,x,r); // overwrite b with defect\n- 467\n- 468 rt=r;\n- 469\n- 470 norm = _sp->norm(r);\n- 471 if(iteration.step(0, norm)){\n- 472 _prec->post(x);\n- 473 return;\n- 474 }\n- 475 p=0;\n- 476 v=0;\n- 477\n- 478 rho = 1;\n- 479 alpha = 1;\n- 480 omega = 1;\n- 481\n- 482 //\n- 483 // iteration\n- 484 //\n- 485\n- 486 for (it = 0.5; it < _maxit; it+=.5)\n+ 392\n+ 410 template\n+411 class Iteration {\n+ 412 public:\n+413 Iteration(const IterativeSolver& parent, InverseOperatorResult& res)\n+ 414 : _i(0)\n+ 415 , _res(res)\n+ 416 , _parent(parent)\n+ 417 , _valid(true)\n+ 418 {\n+ 419 res.clear();\n+ 420 if(_parent._verbose>0){\n+ 421 std::cout << \"=== \" << parent.name() << std::endl;\n+ 422 if(_parent._verbose > 1)\n+ 423 _parent.printHeader(std::cout);\n+ 424 }\n+ 425 }\n+ 426\n+427 Iteration(const Iteration&) = delete;\n+428 Iteration(Iteration&& other)\n+ 429 : _def0(other._def0)\n+ 430 , _def(other._def)\n+ 431 , _i(other._i)\n+ 432 , _watch(other._watch)\n+ 433 , _res(other._res)\n+ 434 , _parent(other._parent)\n+ 435 , _valid(other._valid)\n+ 436 {\n+ 437 other._valid = false;\n+ 438 }\n+ 439\n+440 ~Iteration(){\n+ 441 if(_valid)\n+ 442 finalize();\n+ 443 }\n+ 444\n+455 bool step(CountType i, real_type def){\n+ 456 if (!Simd::allTrue(isFinite(def))) // check for inf or NaN\n+ 457 {\n+ 458 if (_parent._verbose>0)\n+ 459 std::cout << \"=== \" << _parent.name() << \": abort due to infinite or NaN\n+defect\"\n+ 460 << std::endl;\n+ 461 DUNE_THROW(SolverAbort,\n+ 462 _parent.name() << \": defect=\" << Simd::io(def)\n+ 463 << \" is infinite or NaN\");\n+ 464 }\n+ 465 if(i == 0)\n+ 466 _def0 = def;\n+ 467 if(_parent._verbose > 1){\n+ 468 if(i!=0)\n+ 469 _parent.printOutput(std::cout,i,def,_def);\n+ 470 else\n+ 471 _parent.printOutput(std::cout,i,def);\n+ 472 }\n+ 473 _def = def;\n+ 474 _i = i;\n+ 475 _res.converged = (Simd::allTrue(def<_def0*_parent._reduction ||\n+def(Simd::max(_def/_def0));\n+ 484 _res.conv_rate = pow(_res.reduction,1.0/_i);\n+ 485 _res.elapsed = _watch.elapsed();\n+ 486 if (_parent._verbose>0) // final print\n 487 {\n- 488 //\n- 489 // preprocess, set vecsizes etc.\n- 490 //\n- 491\n- 492 // rho_new = < rt , r >\n- 493 rho_new = _sp->dot(rt,r);\n+ 488 std::cout << \"=== rate=\" << _res.conv_rate\n+ 489 << \", T=\" << _res.elapsed\n+ 490 << \", TIT=\" << _res.elapsed/_res.iterations\n+ 491 << \", IT=\" << _res.iterations << std::endl;\n+ 492 }\n+ 493 }\n 494\n- 495 // look if breakdown occurred\n- 496 if (Simd::allTrue(abs(rho) <= EPSILON))\n- 497 DUNE_THROW(SolverAbort,\"breakdown in BiCGSTAB - rho \"\n- 498 << Simd::io(rho) << \" <= EPSILON \" << EPSILON\n- 499 << \" after \" << it << \" iterations\");\n- 500 if (Simd::allTrue(abs(omega) <= EPSILON))\n- 501 DUNE_THROW(SolverAbort,\"breakdown in BiCGSTAB - omega \"\n- 502 << Simd::io(omega) << \" <= EPSILON \" << EPSILON\n- 503 << \" after \" << it << \" iterations\");\n- 504\n- 505\n- 506 if (it<1)\n- 507 p = r;\n- 508 else\n- 509 {\n- 510 beta = Simd::cond(norm==field_type(0.),\n- 511 field_type(0.), // no need for orthogonalization if norm is already 0\n- 512 ( rho_new / rho ) * ( alpha / omega ));\n- 513 p.axpy(-omega,v); // p = r + beta (p - omega*v)\n- 514 p *= beta;\n- 515 p += r;\n- 516 }\n- 517\n- 518 // y = W^-1 * p\n- 519 y = 0;\n- 520 _prec->apply(y,p); // apply preconditioner\n- 521\n- 522 // v = A * y\n- 523 _op->apply(y,v);\n- 524\n- 525 // alpha = rho_new / < rt, v >\n- 526 h = _sp->dot(rt,v);\n- 527\n- 528 if ( Simd::allTrue(abs(h) < EPSILON) )\n- 529 DUNE_THROW(SolverAbort,\"abs(h) < EPSILON in BiCGSTAB - abs(h) \"\n- 530 << Simd::io(abs(h)) << \" < EPSILON \" << EPSILON\n- 531 << \" after \" << it << \" iterations\");\n+495 real_type _def0 = 0.0, _def = 0.0;\n+496 CountType _i;\n+497 Timer _watch;\n+498 InverseOperatorResult& _res;\n+499 const IterativeSolver& _parent;\n+500 bool _valid;\n+ 501 };\n+ 502\n+ 503 protected:\n+504 std::shared_ptr> _op;\n+505 std::shared_ptr> _prec;\n+506 std::shared_ptr> _sp;\n+507 scalar_real_type _reduction;\n+508 int _maxit;\n+509 int _verbose;\n+510 SolverCategory::Category _category;\n+ 511 };\n+ 512\n+ 520 template \n+521 class SolverHelper\n+ 522 {\n+ 523 public:\n+524 static void setMatrix (ISTLLinearSolver& solver,\n+ 525 const BCRSMatrix& matrix)\n+ 526 {\n+ 527 static const bool is_direct_solver\n+ 528 = Dune::IsDirectSolver::value;\n+ 529 SolverHelper::\n+ 530Implementation::setMatrix(solver,matrix);\n+ 531 }\n 532\n- 533 alpha = Simd::cond(norm==field_type(0.),\n- 534 field_type(0.),\n- 535 rho_new / h);\n- 536\n- 537 // apply first correction to x\n- 538 // x <- x + alpha y\n- 539 x.axpy(alpha,y);\n- 540\n- 541 // r = r - alpha*v\n- 542 r.axpy(-alpha,v);\n- 543\n- 544 //\n- 545 // test stop criteria\n- 546 //\n- 547\n- 548 norm = _sp->norm(r);\n- 549 if(iteration.step(it, norm)){\n- 550 break;\n- 551 }\n- 552\n- 553 it+=.5;\n- 554\n- 555 // y = W^-1 * r\n- 556 y = 0;\n- 557 _prec->apply(y,r);\n- 558\n- 559 // t = A * y\n- 560 _op->apply(y,t);\n- 561\n- 562 // omega = < t, r > / < t, t >\n- 563 h = _sp->dot(t,t);\n- 564 omega = Simd::cond(norm==field_type(0.),\n- 565 field_type(0.),\n- 566 _sp->dot(t,r)/h);\n- 567\n- 568 // apply second correction to x\n- 569 // x <- x + omega y\n- 570 x.axpy(omega,y);\n- 571\n- 572 // r = s - omega*t (remember : r = s)\n- 573 r.axpy(-omega,t);\n- 574\n- 575 rho = rho_new;\n- 576\n- 577 //\n- 578 // test stop criteria\n- 579 //\n- 580\n- 581 norm = _sp->norm(r);\n- 582 if(iteration.step(it, norm)){\n- 583 break;\n- 584 }\n- 585 } // end for\n- 586\n- 587 _prec->post(x); // postprocess preconditioner\n- 588 }\n- 589\n- 590 protected:\n- 591 using IterativeSolver::_op;\n- 592 using IterativeSolver::_prec;\n- 593 using IterativeSolver::_sp;\n- 594 using IterativeSolver::_reduction;\n- 595 using IterativeSolver::_maxit;\n- 596 using IterativeSolver::_verbose;\n- 597 template\n-598 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 599 };\n-600 DUNE_REGISTER_ITERATIVE_SOLVER(\"bicgstabsolver\",\n-defaultIterativeSolverCreator());\n- 601\n- 608 template\n-609 class MINRESSolver : public IterativeSolver {\n- 610 public:\n- 611 using typename IterativeSolver::domain_type;\n- 612 using typename IterativeSolver::range_type;\n- 613 using typename IterativeSolver::field_type;\n- 614 using typename IterativeSolver::real_type;\n- 615\n- 616 // copy base class constructors\n- 617 using IterativeSolver::IterativeSolver;\n- 618\n- 619 // don't shadow four-argument version of apply defined in the base class\n- 620 using IterativeSolver::apply;\n- 621\n-627 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 628 {\n- 629 using std::sqrt;\n- 630 using std::abs;\n- 631 Iteration iteration(*this, res);\n- 632 // prepare preconditioner\n- 633 _prec->pre(x,b);\n- 634\n- 635 // overwrite rhs with defect\n- 636 _op->applyscaleadd(-1.0,x,b); // b -= Ax\n- 637\n- 638 // some temporary vectors\n- 639 X z(b), dummy(b);\n- 640 z = 0.0;\n- 641\n- 642 // calculate preconditioned defect\n- 643 _prec->apply(z,b); // r = W^-1 (b - Ax)\n- 644 real_type def = _sp->norm(z);\n- 645 if (iteration.step(0, def)){\n- 646 _prec->post(x);\n- 647 return;\n- 648 }\n- 649\n- 650 // recurrence coefficients as computed in Lanczos algorithm\n- 651 field_type alpha, beta;\n- 652 // diagonal entries of givens rotation\n- 653 std::array c{{0.0,0.0}};\n- 654 // off-diagonal entries of givens rotation\n- 655 std::array s{{0.0,0.0}};\n- 656\n- 657 // recurrence coefficients (column k of tridiag matrix T_k)\n- 658 std::array T{{0.0,0.0,0.0}};\n- 659\n- 660 // the rhs vector of the min problem\n- 661 std::array xi{{1.0,0.0}};\n- 662\n- 663 // beta is real and positive in exact arithmetic\n- 664 // since it is the norm of the basis vectors (in unpreconditioned case)\n- 665 beta = sqrt(_sp->dot(b,z));\n- 666 field_type beta0 = beta;\n- 667\n- 668 // the search directions\n- 669 std::array p{{b,b,b}};\n- 670 p[0] = 0.0;\n- 671 p[1] = 0.0;\n- 672 p[2] = 0.0;\n- 673\n- 674 // orthonormal basis vectors (in unpreconditioned case)\n- 675 std::array q{{b,b,b}};\n- 676 q[0] = 0.0;\n- 677 q[1] *= Simd::cond(def==field_type(0.),\n- 678 field_type(0.),\n- 679 real_type(1.0)/beta);\n- 680 q[2] = 0.0;\n- 681\n- 682 z *= Simd::cond(def==field_type(0.),\n- 683 field_type(0.),\n- 684 real_type(1.0)/beta);\n- 685\n- 686 // the loop\n- 687 int i = 1;\n- 688 for( ; i<=_maxit; i++) {\n- 689\n- 690 dummy = z;\n- 691 int i1 = i%3,\n- 692 i0 = (i1+2)%3,\n- 693 i2 = (i1+1)%3;\n- 694\n- 695 // symmetrically preconditioned Lanczos algorithm (see Greenbaum p.121)\n- 696 _op->apply(z,q[i2]); // q[i2] = Az\n- 697 q[i2].axpy(-beta,q[i0]);\n- 698 // alpha is real since it is the diagonal entry of the hermitian\n-tridiagonal matrix\n- 699 // from the Lanczos Algorithm\n- 700 // so the order in the scalar product doesn't matter even for the complex\n-case\n- 701 alpha = _sp->dot(z,q[i2]);\n- 702 q[i2].axpy(-alpha,q[i1]);\n- 703\n- 704 z = 0.0;\n- 705 _prec->apply(z,q[i2]);\n- 706\n- 707 // beta is real and positive in exact arithmetic\n- 708 // since it is the norm of the basis vectors (in unpreconditioned case)\n- 709 beta = sqrt(_sp->dot(q[i2],z));\n- 710\n- 711 q[i2] *= Simd::cond(def==field_type(0.),\n- 712 field_type(0.),\n- 713 real_type(1.0)/beta);\n- 714 z *= Simd::cond(def==field_type(0.),\n- 715 field_type(0.),\n- 716 real_type(1.0)/beta);\n- 717\n- 718 // QR Factorization of recurrence coefficient matrix\n- 719 // apply previous givens rotations to last column of T\n- 720 T[1] = T[2];\n- 721 if(i>2) {\n- 722 T[0] = s[i%2]*T[1];\n- 723 T[1] = c[i%2]*T[1];\n- 724 }\n- 725 if(i>1) {\n- 726 T[2] = c[(i+1)%2]*alpha - s[(i+1)%2]*T[1];\n- 727 T[1] = c[(i+1)%2]*T[1] + s[(i+1)%2]*alpha;\n- 728 }\n- 729 else\n- 730 T[2] = alpha;\n- 731\n- 732 // update QR factorization\n- 733 generateGivensRotation(T[2],beta,c[i%2],s[i%2]);\n- 734 // to last column of T_k\n- 735 T[2] = c[i%2]*T[2] + s[i%2]*beta;\n- 736 // and to the rhs xi of the min problem\n- 737 xi[i%2] = -s[i%2]*xi[(i+1)%2];\n- 738 xi[(i+1)%2] *= c[i%2];\n- 739\n- 740 // compute correction direction\n- 741 p[i2] = dummy;\n- 742 p[i2].axpy(-T[1],p[i1]);\n- 743 p[i2].axpy(-T[0],p[i0]);\n- 744 p[i2] *= real_type(1.0)/T[2];\n- 745\n- 746 // apply correction/update solution\n- 747 x.axpy(beta0*xi[(i+1)%2],p[i2]);\n- 748\n- 749 // remember beta_old\n- 750 T[2] = beta;\n- 751\n- 752 // check for convergence\n- 753 // the last entry in the rhs of the min-problem is the residual\n- 754 def = abs(beta0*xi[i%2]);\n- 755 if(iteration.step(i, def)){\n- 756 break;\n- 757 }\n- 758 } // end for\n- 759\n- 760 // postprocess preconditioner\n- 761 _prec->post(x);\n- 762 }\n- 763\n- 764 private:\n- 765\n- 766 void generateGivensRotation(field_type &dx, field_type &dy, real_type &cs,\n-field_type &sn)\n- 767 {\n- 768 using std::sqrt;\n- 769 using std::abs;\n- 770 using std::max;\n- 771 using std::min;\n- 772 const real_type eps = 1e-15;\n- 773 real_type norm_dx = abs(dx);\n- 774 real_type norm_dy = abs(dy);\n- 775 real_type norm_max = max(norm_dx, norm_dy);\n- 776 real_type norm_min = min(norm_dx, norm_dy);\n- 777 real_type temp = norm_min/norm_max;\n- 778 // we rewrite the code in a vectorizable fashion\n- 779 cs = Simd::cond(norm_dy < eps,\n- 780 real_type(1.0),\n- 781 Simd::cond(norm_dx < eps,\n- 782 real_type(0.0),\n- 783 Simd::cond(norm_dy > norm_dx,\n- 784 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,\n- 785 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)\n- 786 )));\n- 787 sn = Simd::cond(norm_dy < eps,\n- 788 field_type(0.0),\n- 789 Simd::cond(norm_dx < eps,\n- 790 field_type(1.0),\n- 791 Simd::cond(norm_dy > norm_dx,\n- 792 // dy and dx are real in exact arithmetic\n- 793 // thus dx*dy is real so we can explicitly enforce it\n- 794 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*dy/norm_dx/norm_dy,\n- 795 // dy and dx is real in exact arithmetic\n- 796 // so we don't have to conjugate both of them\n- 797 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dy/dx\n- 798 )));\n- 799 }\n- 800\n- 801 protected:\n- 802 using IterativeSolver::_op;\n- 803 using IterativeSolver::_prec;\n- 804 using IterativeSolver::_sp;\n- 805 using IterativeSolver::_reduction;\n- 806 using IterativeSolver::_maxit;\n- 807 using IterativeSolver::_verbose;\n-808 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 809 };\n-810 DUNE_REGISTER_ITERATIVE_SOLVER(\"minressolver\",\n-defaultIterativeSolverCreator());\n- 811\n- 825 template\n-826 class RestartedGMResSolver : public IterativeSolver\n- 827 {\n- 828 public:\n- 829 using typename IterativeSolver::domain_type;\n- 830 using typename IterativeSolver::range_type;\n- 831 using typename IterativeSolver::field_type;\n- 832 using typename IterativeSolver::real_type;\n- 833\n- 834 protected:\n- 835 using typename IterativeSolver::scalar_real_type;\n- 836\n-838 using fAlloc = ReboundAllocatorType;\n-840 using rAlloc = ReboundAllocatorType;\n- 841\n- 842 public:\n- 843\n-850 RestartedGMResSolver (const LinearOperator& op, Preconditioner&\n-prec, scalar_real_type reduction, int restart, int maxit, int verbose) :\n- 851 IterativeSolver::IterativeSolver(op,prec,reduction,maxit,verbose),\n- 852 _restart(restart)\n- 853 {}\n- 854\n-861 RestartedGMResSolver (const LinearOperator& op, const\n-ScalarProduct& sp, Preconditioner& prec, scalar_real_type reduction,\n-int restart, int maxit, int verbose) :\n- 862 IterativeSolver::IterativeSolver(op,sp,prec,reduction,maxit,verbose),\n- 863 _restart(restart)\n- 864 {}\n- 865\n-878 RestartedGMResSolver (std::shared_ptr > op, std::\n-shared_ptr > prec, const ParameterTree& configuration) :\n- 879 IterativeSolver::IterativeSolver(op,prec,configuration),\n- 880 _restart(configuration.get(\"restart\"))\n- 881 {}\n- 882\n-883 RestartedGMResSolver (std::shared_ptr > op, std::\n-shared_ptr > sp, std::shared_ptr >\n-prec, const ParameterTree& configuration) :\n- 884 IterativeSolver::IterativeSolver(op,sp,prec,configuration),\n- 885 _restart(configuration.get(\"restart\"))\n- 886 {}\n- 887\n-894 RestartedGMResSolver (std::shared_ptr> op,\n- 895 std::shared_ptr> sp,\n- 896 std::shared_ptr> prec,\n- 897 scalar_real_type reduction, int restart, int maxit, int verbose) :\n- 898 IterativeSolver::IterativeSolver(op,sp,prec,reduction,maxit,verbose),\n- 899 _restart(restart)\n- 900 {}\n- 901\n-910 virtual void apply (X& x, Y& b, InverseOperatorResult& res)\n- 911 {\n- 912 apply(x,b,Simd::max(_reduction),res);\n- 913 }\n- 914\n-923 virtual void apply (X& x, Y& b, [[maybe_unused]] double reduction,\n-InverseOperatorResult& res)\n- 924 {\n- 925 using std::abs;\n- 926 const Simd::Scalar EPSILON = 1e-80;\n- 927 const int m = _restart;\n- 928 real_type norm = 0.0;\n- 929 int j = 1;\n- 930 std::vector s(m+1), sn(m);\n- 931 std::vector cs(m);\n- 932 // need copy of rhs if GMRes has to be restarted\n- 933 Y b2(b);\n- 934 // helper vector\n- 935 Y w(b);\n- 936 std::vector< std::vector > H(m+1,s);\n- 937 std::vector v(m+1,b);\n- 938\n- 939 Iteration iteration(*this,res);\n- 940\n- 941 // clear solver statistics and set res.converged to false\n- 942 _prec->pre(x,b);\n- 943\n- 944 // calculate defect and overwrite rhs with it\n- 945 _op->applyscaleadd(-1.0,x,b); // b -= Ax\n- 946 // calculate preconditioned defect\n- 947 v[0] = 0.0; _prec->apply(v[0],b); // r = W^-1 b\n- 948 norm = _sp->norm(v[0]);\n- 949 if(iteration.step(0, norm)){\n- 950 _prec->post(x);\n- 951 return;\n- 952 }\n- 953\n- 954 while(j <= _maxit && res.converged != true) {\n- 955\n- 956 int i = 0;\n- 957 v[0] *= Simd::cond(norm==real_type(0.),\n- 958 real_type(0.),\n- 959 real_type(1.0)/norm);\n- 960 s[0] = norm;\n- 961 for(i=1; iapply(v[i],v[i+1]);\n- 970 _prec->apply(w,v[i+1]);\n- 971 for(int k=0; kdot(v[k],w) = v[k]\\adjoint w\n- 973 // so one has to pay attention to the order\n- 974 // in the scalar product for the complex case\n- 975 // doing the modified Gram-Schmidt algorithm\n- 976 H[k][i] = _sp->dot(v[k],w);\n- 977 // w -= H[k][i] * v[k]\n- 978 w.axpy(-H[k][i],v[k]);\n- 979 }\n- 980 H[i+1][i] = _sp->norm(w);\n- 981 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))\n- 982 DUNE_THROW(SolverAbort,\n- 983 \"breakdown in GMRes - |w| == 0.0 after \" << j << \" iterations\");\n- 984\n- 985 // normalize new vector\n- 986 v[i+1] = w;\n- 987 v[i+1] *= Simd::cond(norm==real_type(0.),\n- 988 field_type(0.),\n- 989 real_type(1.0)/H[i+1][i]);\n- 990\n- 991 // update QR factorization\n- 992 for(int k=0; k 0)\n- 1020 std::cout << \"=== GMRes::restart\" << std::endl;\n- 1021 // get saved rhs\n- 1022 b = b2;\n- 1023 // calculate new defect\n- 1024 _op->applyscaleadd(-1.0,x,b); // b -= Ax;\n- 1025 // calculate preconditioned defect\n- 1026 v[0] = 0.0;\n- 1027 _prec->apply(v[0],b);\n- 1028 norm = _sp->norm(v[0]);\n- 1029 }\n- 1030\n- 1031 } //end while\n- 1032\n- 1033 // postprocess preconditioner\n- 1034 _prec->post(x);\n- 1035 }\n- 1036\n- 1037 protected :\n- 1038\n-1039 void update(X& w, int i,\n- 1040 const std::vector >& H,\n- 1041 const std::vector& s,\n- 1042 const std::vector& v) {\n- 1043 // solution vector of the upper triangular system\n- 1044 std::vector y(s);\n- 1045\n- 1046 // backsolve\n- 1047 for(int a=i-1; a>=0; a--) {\n- 1048 field_type rhs(s[a]);\n- 1049 for(int b=a+1; b\n-1062 typename std::enable_if::value,T>::type\n-conjugate(const T& t) {\n- 1063 return t;\n- 1064 }\n- 1065\n- 1066 template\n-1067 typename std::enable_if::value,T>::\n-type conjugate(const T& t) {\n- 1068 using std::conj;\n- 1069 return conj(t);\n- 1070 }\n- 1071\n- 1072 void\n-1073 generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n-field_type &sn)\n- 1074 {\n- 1075 using std::sqrt;\n- 1076 using std::abs;\n- 1077 using std::max;\n- 1078 using std::min;\n- 1079 const real_type eps = 1e-15;\n- 1080 real_type norm_dx = abs(dx);\n- 1081 real_type norm_dy = abs(dy);\n- 1082 real_type norm_max = max(norm_dx, norm_dy);\n- 1083 real_type norm_min = min(norm_dx, norm_dy);\n- 1084 real_type temp = norm_min/norm_max;\n- 1085 // we rewrite the code in a vectorizable fashion\n- 1086 cs = Simd::cond(norm_dy < eps,\n- 1087 real_type(1.0),\n- 1088 Simd::cond(norm_dx < eps,\n- 1089 real_type(0.0),\n- 1090 Simd::cond(norm_dy > norm_dx,\n- 1091 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,\n- 1092 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)\n- 1093 )));\n- 1094 sn = Simd::cond(norm_dy < eps,\n- 1095 field_type(0.0),\n- 1096 Simd::cond(norm_dx < eps,\n- 1097 field_type(1.0),\n- 1098 Simd::cond(norm_dy > norm_dx,\n- 1099 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*conjugate(dy)/\n-norm_dx/norm_dy,\n- 1100 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*conjugate(dy/dx)\n- 1101 )));\n- 1102 }\n- 1103\n- 1104\n- 1105 void\n-1106 applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n-field_type &sn)\n- 1107 {\n- 1108 field_type temp = cs * dx + sn * dy;\n- 1109 dy = -conjugate(sn) * dx + cs * dy;\n- 1110 dx = temp;\n- 1111 }\n- 1112\n- 1113 using IterativeSolver::_op;\n- 1114 using IterativeSolver::_prec;\n- 1115 using IterativeSolver::_sp;\n- 1116 using IterativeSolver::_reduction;\n- 1117 using IterativeSolver::_maxit;\n- 1118 using IterativeSolver::_verbose;\n-1119 using Iteration = typename IterativeSolver::template\n-Iteration;\n-1120 int _restart;\n- 1121 };\n-1122 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedgmressolver\",\n-defaultIterativeSolverCreator());\n- 1123\n- 1137 template\n-1138 class RestartedFlexibleGMResSolver : public RestartedGMResSolver\n- 1139 {\n- 1140 public:\n- 1141 using typename RestartedGMResSolver::domain_type;\n- 1142 using typename RestartedGMResSolver::range_type;\n- 1143 using typename RestartedGMResSolver::field_type;\n- 1144 using typename RestartedGMResSolver::real_type;\n- 1145\n- 1146 private:\n- 1147 using typename RestartedGMResSolver::scalar_real_type;\n- 1148\n- 1150 using fAlloc = typename RestartedGMResSolver::fAlloc;\n- 1152 using rAlloc = typename RestartedGMResSolver::rAlloc;\n- 1153\n- 1154 public:\n- 1155 // copy base class constructors\n- 1156 using RestartedGMResSolver::RestartedGMResSolver;\n- 1157\n- 1158 // don't shadow four-argument version of apply defined in the base class\n- 1159 using RestartedGMResSolver::apply;\n- 1160\n-1169 void apply (X& x, Y& b, [[maybe_unused]] double reduction,\n-InverseOperatorResult& res) override\n- 1170 {\n- 1171 using std::abs;\n- 1172 const Simd::Scalar EPSILON = 1e-80;\n- 1173 const int m = _restart;\n- 1174 real_type norm = 0.0;\n- 1175 int i, j = 1, k;\n- 1176 std::vector s(m+1), sn(m);\n- 1177 std::vector cs(m);\n- 1178 // helper vector\n- 1179 Y tmp(b);\n- 1180 std::vector< std::vector > H(m+1,s);\n- 1181 std::vector v(m+1,b);\n- 1182 std::vector w(m+1,b);\n- 1183\n- 1184 Iteration iteration(*this,res);\n- 1185 // setup preconditioner if it does something in pre\n- 1186\n- 1187 // calculate residual and overwrite a copy of the rhs with it\n- 1188 _prec->pre(x, b);\n- 1189 v[0] = b;\n- 1190 _op->applyscaleadd(-1.0, x, v[0]); // b -= Ax\n- 1191\n- 1192 norm = _sp->norm(v[0]); // the residual norm\n- 1193 if(iteration.step(0, norm)){\n- 1194 _prec->post(x);\n- 1195 return;\n- 1196 }\n- 1197\n- 1198 // start iterations\n- 1199 res.converged = false;;\n- 1200 while(j <= _maxit && res.converged != true)\n- 1201 {\n- 1202 v[0] *= (1.0 / norm);\n- 1203 s[0] = norm;\n- 1204 for(i=1; iapply(w[i], v[i]);\n- 1213 // compute vi = A*wi\n- 1214 // use v[i+1] as temporary vector for w\n- 1215 _op->apply(w[i], v[i+1]);\n- 1216 // do Arnoldi algorithm\n- 1217 for(int kk=0; kkdot(v[k],v[i+1]) = v[k]\\adjoint v[i+1]\n- 1220 // so one has to pay attention to the order\n- 1221 // in the scalar product for the complex case\n- 1222 // doing the modified Gram-Schmidt algorithm\n- 1223 H[kk][i] = _sp->dot(v[kk],v[i+1]);\n- 1224 // w -= H[k][i] * v[kk]\n- 1225 v[i+1].axpy(-H[kk][i], v[kk]);\n- 1226 }\n- 1227 H[i+1][i] = _sp->norm(v[i+1]);\n- 1228 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))\n- 1229 DUNE_THROW(SolverAbort, \"breakdown in fGMRes - |w| (-> \"\n- 1230 << w[i] << \") == 0.0 after \"\n- 1231 << j << \" iterations\");\n- 1232\n- 1233 // v[i+1] = w*1/H[i+1][i]\n- 1234 v[i+1] *= real_type(1.0)/H[i+1][i];\n- 1235\n- 1236 // update QR factorization\n- 1237 for(k=0; kapplyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);\n- 1239\n- 1240 // compute new givens rotation\n- 1241 this->generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);\n- 1242\n- 1243 // finish updating QR factorization\n- 1244 this->applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);\n- 1245 this->applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);\n- 1246\n- 1247 // norm of the residual is the last component of vector s\n- 1248 using std::abs;\n- 1249 norm = abs(s[i+1]);\n- 1250 iteration.step(j, norm);\n- 1251 } // end inner for loop\n- 1252\n- 1253 // calculate update vector\n- 1254 tmp = 0.0;\n- 1255 this->update(tmp, i, H, s, w);\n- 1256 // and update current iterate\n- 1257 x += tmp;\n- 1258\n- 1259 // restart fGMRes if convergence was not achieved,\n- 1260 // i.e. linear residual has not reached desired reduction\n- 1261 // and if still j < _maxit (do not restart on last iteration)\n- 1262 if( res.converged != true && j < _maxit)\n- 1263 {\n- 1264 if (_verbose > 0)\n- 1265 std::cout << \"=== fGMRes::restart\" << std::endl;\n- 1266 // get rhs\n- 1267 v[0] = b;\n- 1268 // calculate new defect\n- 1269 _op->applyscaleadd(-1.0, x,v[0]); // b -= Ax;\n- 1270 // calculate preconditioned defect\n- 1271 norm = _sp->norm(v[0]); // update the residual norm\n- 1272 }\n- 1273\n- 1274 } // end outer while loop\n- 1275\n- 1276 // post-process preconditioner\n- 1277 _prec->post(x);\n- 1278 }\n- 1279\n- 1280private:\n- 1281 using RestartedGMResSolver::_op;\n- 1282 using RestartedGMResSolver::_prec;\n- 1283 using RestartedGMResSolver::_sp;\n- 1284 using RestartedGMResSolver::_reduction;\n- 1285 using RestartedGMResSolver::_maxit;\n- 1286 using RestartedGMResSolver::_verbose;\n- 1287 using RestartedGMResSolver::_restart;\n- 1288 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 1289 };\n-1290 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedflexiblegmressolver\",\n-defaultIterativeSolverCreator());\n- 1291\n- 1305 template\n-1306 class GeneralizedPCGSolver : public IterativeSolver\n- 1307 {\n- 1308 public:\n- 1309 using typename IterativeSolver::domain_type;\n- 1310 using typename IterativeSolver::range_type;\n- 1311 using typename IterativeSolver::field_type;\n- 1312 using typename IterativeSolver::real_type;\n- 1313\n- 1314 private:\n- 1315 using typename IterativeSolver::scalar_real_type;\n- 1316\n- 1318 using fAlloc = ReboundAllocatorType;\n- 1319\n- 1320 public:\n- 1321\n- 1322 // don't shadow four-argument version of apply defined in the base class\n- 1323 using IterativeSolver::apply;\n- 1324\n-1331 GeneralizedPCGSolver (const LinearOperator& op, Preconditioner&\n-prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :\n- 1332 IterativeSolver::IterativeSolver(op,prec,reduction,maxit,verbose),\n- 1333 _restart(restart)\n- 1334 {}\n- 1335\n-1343 GeneralizedPCGSolver (const LinearOperator& op, const\n-ScalarProduct& sp, Preconditioner& prec, scalar_real_type reduction,\n-int maxit, int verbose, int restart = 10) :\n- 1344 IterativeSolver::IterativeSolver\n-(op,sp,prec,reduction,maxit,verbose),\n- 1345 _restart(restart)\n- 1346 {}\n- 1347\n- 1348\n-1361 GeneralizedPCGSolver (std::shared_ptr > op,\n-std::shared_ptr > prec, const ParameterTree& configuration)\n-:\n- 1362 IterativeSolver::IterativeSolver(op,prec,configuration),\n- 1363 _restart(configuration.get(\"restart\"))\n- 1364 {}\n- 1365\n-1366 GeneralizedPCGSolver (std::shared_ptr > op,\n-std::shared_ptr > sp, std::\n-shared_ptr > prec, const ParameterTree& configuration) :\n- 1367 IterativeSolver::IterativeSolver(op,sp,prec,configuration),\n- 1368 _restart(configuration.get(\"restart\"))\n- 1369 {}\n-1377 GeneralizedPCGSolver (std::shared_ptr> op,\n- 1378 std::shared_ptr> sp,\n- 1379 std::shared_ptr> prec,\n- 1380 scalar_real_type reduction, int maxit, int verbose,\n- 1381 int restart = 10) :\n- 1382 IterativeSolver::IterativeSolver\n-(op,sp,prec,reduction,maxit,verbose),\n- 1383 _restart(restart)\n- 1384 {}\n- 1385\n-1391 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 1392 {\n- 1393 Iteration iteration(*this, res);\n- 1394 _prec->pre(x,b); // prepare preconditioner\n- 1395 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n- 1396\n- 1397 std::vector > p(_restart);\n- 1398 std::vector pp(_restart);\n- 1399 X q(x); // a temporary vector\n- 1400 X prec_res(x); // a temporary vector for preconditioner output\n- 1401\n- 1402 p[0].reset(new X(x));\n- 1403\n- 1404 real_type def = _sp->norm(b); // compute norm\n- 1405 if(iteration.step(0, def)){\n- 1406 _prec->post(x);\n- 1407 return;\n- 1408 }\n- 1409 // some local variables\n- 1410 field_type rho, lambda;\n- 1411\n- 1412 int i=0;\n- 1413 int ii=0;\n- 1414 // determine initial search direction\n- 1415 *(p[0]) = 0; // clear correction\n- 1416 _prec->apply(*(p[0]),b); // apply preconditioner\n- 1417 rho = _sp->dot(*(p[0]),b); // orthogonalization\n- 1418 _op->apply(*(p[0]),q); // q=Ap\n- 1419 pp[0] = _sp->dot(*(p[0]),q); // scalar product\n- 1420 lambda = rho/pp[0]; // minimization\n- 1421 x.axpy(lambda,*(p[0])); // update solution\n- 1422 b.axpy(-lambda,q); // update defect\n- 1423\n- 1424 // convergence test\n- 1425 def=_sp->norm(b); // comp defect norm\n- 1426 ++i;\n- 1427 if(iteration.step(i, def)){\n- 1428 _prec->post(x);\n- 1429 return;\n- 1430 }\n- 1431\n- 1432 while(i<_maxit) {\n- 1433 // the loop\n- 1434 int end=std::min(_restart, _maxit-i+1);\n- 1435 for (ii=1; iiapply(prec_res,b); // apply preconditioner\n- 1441\n- 1442 p[ii].reset(new X(prec_res));\n- 1443 _op->apply(prec_res, q);\n- 1444\n- 1445 for(int j=0; jdot(q,*(p[j]))/pp[j];\n- 1447 p[ii]->axpy(-rho, *(p[j]));\n- 1448 }\n- 1449\n- 1450 // minimize in given search direction\n- 1451 _op->apply(*(p[ii]),q); // q=Ap\n- 1452 pp[ii] = _sp->dot(*(p[ii]),q); // scalar product\n- 1453 rho = _sp->dot(*(p[ii]),b); // orthogonalization\n- 1454 lambda = rho/pp[ii]; // minimization\n- 1455 x.axpy(lambda,*(p[ii])); // update solution\n- 1456 b.axpy(-lambda,q); // update defect\n- 1457\n- 1458 // convergence test\n- 1459 def = _sp->norm(b); // comp defect norm\n- 1460\n- 1461 ++i;\n- 1462 iteration.step(i, def);\n- 1463 }\n- 1464 if(res.converged)\n- 1465 break;\n- 1466 if(end==_restart) {\n- 1467 *(p[0])=*(p[_restart-1]);\n- 1468 pp[0]=pp[_restart-1];\n- 1469 }\n- 1470 }\n- 1471\n- 1472 // postprocess preconditioner\n- 1473 _prec->post(x);\n- 1474\n- 1475 }\n- 1476\n- 1477 private:\n- 1478 using IterativeSolver::_op;\n- 1479 using IterativeSolver::_prec;\n- 1480 using IterativeSolver::_sp;\n- 1481 using IterativeSolver::_reduction;\n- 1482 using IterativeSolver::_maxit;\n- 1483 using IterativeSolver::_verbose;\n- 1484 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 1485 int _restart;\n- 1486 };\n-1487 DUNE_REGISTER_ITERATIVE_SOLVER(\"generalizedpcgsolver\",\n-defaultIterativeSolverCreator());\n- 1488\n- 1500 template\n-1501 class RestartedFCGSolver : public IterativeSolver {\n- 1502 public:\n- 1503 using typename IterativeSolver::domain_type;\n- 1504 using typename IterativeSolver::range_type;\n- 1505 using typename IterativeSolver::field_type;\n- 1506 using typename IterativeSolver::real_type;\n- 1507\n- 1508 private:\n- 1509 using typename IterativeSolver::scalar_real_type;\n- 1510\n- 1511 public:\n- 1512 // don't shadow four-argument version of apply defined in the base class\n- 1513 using IterativeSolver::apply;\n-1519 RestartedFCGSolver (const LinearOperator& op, Preconditioner&\n-prec,\n- 1520 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) :\n-IterativeSolver(op, prec, reduction, maxit, verbose), _mmax(mmax)\n- 1521 {\n- 1522 }\n- 1523\n-1529 RestartedFCGSolver (const LinearOperator& op, const ScalarProduct&\n-sp, Preconditioner& prec,\n- 1530 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) :\n-IterativeSolver(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)\n- 1531 {\n- 1532 }\n- 1533\n-1539 RestartedFCGSolver (std::shared_ptr> op,\n- 1540 std::shared_ptr> sp,\n- 1541 std::shared_ptr> prec,\n- 1542 scalar_real_type reduction, int maxit, int verbose,\n- 1543 int mmax = 10)\n- 1544 : IterativeSolver(op, sp, prec, reduction, maxit, verbose), _mmax\n-(mmax)\n- 1545 {}\n- 1546\n-1559 RestartedFCGSolver (std::shared_ptr> op,\n- 1560 std::shared_ptr> prec,\n- 1561 const ParameterTree& config)\n- 1562 : IterativeSolver(op, prec, config), _mmax(config.get(\"mmax\", 10))\n- 1563 {}\n- 1564\n-1565 RestartedFCGSolver (std::shared_ptr> op,\n- 1566 std::shared_ptr> sp,\n- 1567 std::shared_ptr> prec,\n- 1568 const ParameterTree& config)\n- 1569 : IterativeSolver(op, sp, prec, config), _mmax(config.get(\"mmax\",\n-10))\n- 1570 {}\n- 1571\n-1584 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n- 1585 {\n- 1586 using rAlloc = ReboundAllocatorType;\n- 1587 res.clear();\n- 1588 Iteration iteration(*this,res);\n- 1589 _prec->pre(x,b); // prepare preconditioner\n- 1590 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n- 1591\n- 1592 //arrays for interim values:\n- 1593 std::vector d(_mmax+1, x); // array for directions\n- 1594 std::vector Ad(_mmax+1, x); // array for Ad[i]\n- 1595 std::vector ddotAd(_mmax+1,0); // array for \n- 1596 X w(x);\n- 1597\n- 1598 real_type def = _sp->norm(b); // compute norm\n- 1599 if(iteration.step(0, def)){\n- 1600 _prec->post(x);\n- 1601 return;\n- 1602 }\n- 1603\n- 1604 // some local variables\n- 1605 field_type alpha;\n- 1606\n- 1607 // the loop\n- 1608 int i=1;\n- 1609 int i_bounded=0;\n- 1610 while(i<=_maxit && !res.converged) {\n- 1611 for (; i_bounded <= _mmax && i<= _maxit; i_bounded++) {\n- 1612 d[i_bounded] = 0; // reset search direction\n- 1613 _prec->apply(d[i_bounded], b); // apply preconditioner\n- 1614 w = d[i_bounded]; // copy of current d[i]\n- 1615 // orthogonalization with previous directions\n- 1616 orthogonalizations(i_bounded,Ad,w,ddotAd,d);\n- 1617\n- 1618 //saving interim values for future calculating\n- 1619 _op->apply(d[i_bounded], Ad[i_bounded]); // save Ad[i]\n- 1620 ddotAd[i_bounded]=_sp->dot(d[i_bounded],Ad[i_bounded]); // save \n- 1621 alpha = _sp->dot(d[i_bounded], b)/ddotAd[i_bounded]; // /\n- 1622\n- 1623 //update solution and defect\n- 1624 x.axpy(alpha, d[i_bounded]);\n- 1625 b.axpy(-alpha, Ad[i_bounded]);\n- 1626\n- 1627 // convergence test\n- 1628 def = _sp->norm(b); // comp defect norm\n- 1629\n- 1630 iteration.step(i, def);\n- 1631 i++;\n- 1632 }\n- 1633 //restart: exchange first and last stored values\n- 1634 cycle(Ad,d,ddotAd,i_bounded);\n- 1635 }\n- 1636\n- 1637 //correct i which is wrong if convergence was not achieved.\n- 1638 i=std::min(_maxit,i);\n- 1639\n- 1640 _prec->post(x); // postprocess preconditioner\n- 1641 }\n- 1642\n- 1643 private:\n- 1644 //This function is called every iteration to orthogonalize against the\n-last search directions\n- 1645 virtual void orthogonalizations(const int& i_bounded,const std::\n-vector& Ad, const X& w, const std::\n-vector>& ddotAd,std::vector&\n-d) {\n- 1646 // The RestartedFCGSolver uses only values with lower array index;\n- 1647 for (int k = 0; k < i_bounded; k++) {\n- 1648 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= </>d[k]\n- 1649 }\n- 1650 }\n- 1651\n- 1652 // This function is called every mmax iterations to handle limited array\n-sizes.\n- 1653 virtual void cycle(std::vector& Ad,std::vector& d,std::\n-vector >& ddotAd,int& i_bounded)\n-{\n- 1654 // Reset loop index and exchange the first and last arrays\n- 1655 i_bounded = 1;\n- 1656 std::swap(Ad[0], Ad[_mmax]);\n- 1657 std::swap(d[0], d[_mmax]);\n- 1658 std::swap(ddotAd[0], ddotAd[_mmax]);\n- 1659 }\n- 1660\n- 1661 protected:\n-1662 int _mmax;\n- 1663 using IterativeSolver::_op;\n- 1664 using IterativeSolver::_prec;\n- 1665 using IterativeSolver::_sp;\n- 1666 using IterativeSolver::_reduction;\n- 1667 using IterativeSolver::_maxit;\n- 1668 using IterativeSolver::_verbose;\n-1669 using Iteration = typename IterativeSolver::template\n-Iteration;\n- 1670 };\n-1671 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedfcgsolver\",\n-defaultIterativeSolverCreator());\n- 1672\n- 1679 template\n-1680 class CompleteFCGSolver : public RestartedFCGSolver {\n- 1681 public:\n- 1682 using typename RestartedFCGSolver::domain_type;\n- 1683 using typename RestartedFCGSolver::range_type;\n- 1684 using typename RestartedFCGSolver::field_type;\n- 1685 using typename RestartedFCGSolver::real_type;\n- 1686\n- 1687 // copy base class constructors\n- 1688 using RestartedFCGSolver::RestartedFCGSolver;\n- 1689\n- 1690 // don't shadow four-argument version of apply defined in the base class\n- 1691 using RestartedFCGSolver::apply;\n- 1692\n- 1693 // just a minor part of the RestartedFCGSolver apply method will be\n-modified\n-1694 virtual void apply (X& x, X& b, InverseOperatorResult& res) override {\n- 1695 // reset limiter of orthogonalization loop\n- 1696 _k_limit = 0;\n- 1697 this->RestartedFCGSolver::apply(x,b,res);\n- 1698 };\n- 1699\n- 1700 private:\n- 1701 // This function is called every iteration to orthogonalize against the\n-last search directions.\n- 1702 virtual void orthogonalizations(const int& i_bounded,const std::\n-vector& Ad, const X& w, const std::\n-vector>& ddotAd,std::vector&\n-d) override {\n- 1703 // This FCGSolver uses values with higher array indexes too, if existent.\n- 1704 for (int k = 0; k < _k_limit; k++) {\n- 1705 if(i_bounded!=k)\n- 1706 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= </>d[k]\n- 1707 }\n- 1708 // The loop limit increase, if array is not completely filled.\n- 1709 if(_k_limit<=i_bounded)\n- 1710 _k_limit++;\n- 1711\n- 1712 };\n- 1713\n- 1714 // This function is called every mmax iterations to handle limited array\n-sizes.\n- 1715 virtual void cycle(std::vector& Ad, [[maybe_unused]] std::vector&\n-d, [[maybe_unused]] std::vector\n->& ddotAd,int& i_bounded) override {\n- 1716 // Only the loop index i_bounded return to 0, if it reached mmax.\n- 1717 i_bounded = 0;\n- 1718 // Now all arrays are filled and the loop in void orthogonalizations can\n-use the whole arrays.\n- 1719 _k_limit = Ad.size();\n- 1720 };\n- 1721\n- 1722 int _k_limit = 0;\n- 1723\n- 1724 protected:\n- 1725 using RestartedFCGSolver::_mmax;\n- 1726 using RestartedFCGSolver::_op;\n- 1727 using RestartedFCGSolver::_prec;\n- 1728 using RestartedFCGSolver::_sp;\n- 1729 using RestartedFCGSolver::_reduction;\n- 1730 using RestartedFCGSolver::_maxit;\n- 1731 using RestartedFCGSolver::_verbose;\n- 1732 };\n-1733 DUNE_REGISTER_ITERATIVE_SOLVER(\"completefcgsolver\",\n-defaultIterativeSolverCreator());\n- 1735} // end namespace\n- 1736\n- 1737#endif\n+ 533 protected:\n+ 538 template \n+539 struct Implementation\n+ 540 {\n+541 static void setMatrix (ISTLLinearSolver&,\n+ 542 const BCRSMatrix&)\n+ 543 {}\n+ 544 };\n+ 545\n+ 550 template \n+551 struct Implementation\n+ 552 {\n+553 static void setMatrix (ISTLLinearSolver& solver,\n+ 554 const BCRSMatrix& matrix)\n+ 555 {\n+ 556 solver.setMatrix(matrix);\n+ 557 }\n+ 558 };\n+ 559 };\n+ 560\n+ 564}\n+ 565\n+ 566#endif\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+solvertype.hh\n+Templates characterizing the type of a solver.\n operators.hh\n Define general, extensible interface for operators. The available\n implementation wraps a matrix.\n-arpackpp.hh\n-solver.hh\n-Define general, extensible interface for inverse operators.\n-solverregistry.hh\n preconditioner.hh\n-allocator.hh\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n-istlexception.hh\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-Dune::DUNE_REGISTER_ITERATIVE_SOLVER\n-DUNE_REGISTER_ITERATIVE_SOLVER(\"loopsolver\", defaultIterativeSolverCreator<\n-Dune::LoopSolver >())\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n Dune::get\n PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n Definition: dependency.hh:293\n-Dune::ReboundAllocatorType\n-typename std::allocator_traits< typename AllocatorTraits< T >::type >::template\n-rebind_alloc< X > ReboundAllocatorType\n-Definition: allocator.hh:37\n-Dune::MatrixMarketImpl::conj\n-std::enable_if_t::value, T > conj(const T &r)\n-Definition: matrixmarket.hh:733\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::row_wise\n-@ row_wise\n-Build in a row-wise manner.\n-Definition: bcrsmatrix.hh:521\n-Dune::BCRSMatrix::createend\n-CreateIterator createend()\n-get create iterator pointing to one after the last block\n-Definition: bcrsmatrix.hh:1103\n-Dune::BCRSMatrix::createbegin\n-CreateIterator createbegin()\n-get initial create iterator\n-Definition: bcrsmatrix.hh:1097\n-Dune::BCRSMatrix::N\n-size_type N() const\n-number of rows (counted in blocks)\n-Definition: bcrsmatrix.hh:1972\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::ArPackPlusPlus_Algorithms\n-Wrapper to use a range of ARPACK++ eigenvalue solvers.\n-Definition: arpackpp.hh:245\n-Dune::ArPackPlusPlus_Algorithms::computeSymMaxMagnitude\n-void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n-const\n-Assume the matrix to be square, symmetric and perform IRLM to compute an\n-approximation lambda of its ...\n-Definition: arpackpp.hh:289\n-Dune::ArPackPlusPlus_Algorithms::computeSymMinMagnitude\n-void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n-const\n-Assume the matrix to be square, symmetric and perform IRLM to compute an\n-approximation lambda of its ...\n-Definition: arpackpp.hh:391\n Dune::SolverAbort\n Thrown when a solver aborts due to some problem.\n Definition: istlexception.hh:46\n-Dune::LinearOperator<_X,_X_>\n-Dune::Preconditioner<_X,_X_>\n+Dune::LinearOperator\n+A linear operator.\n+Definition: operators.hh:67\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n Dune::ScalarProduct\n Base class for scalar product and norm computation.\n Definition: scalarproducts.hh:52\n+Dune::SeqScalarProduct\n+Default implementation for the scalar case.\n+Definition: scalarproducts.hh:168\n Dune::InverseOperatorResult\n Statistics about the application of an inverse operator.\n Definition: solver.hh:48\n+Dune::InverseOperatorResult::InverseOperatorResult\n+InverseOperatorResult()\n+Default constructor.\n+Definition: solver.hh:50\n Dune::InverseOperatorResult::condition_estimate\n double condition_estimate\n Estimate of condition number.\n Definition: solver.hh:79\n+Dune::InverseOperatorResult::elapsed\n+double elapsed\n+Elapsed time in seconds.\n+Definition: solver.hh:82\n+Dune::InverseOperatorResult::iterations\n+int iterations\n+Number of iterations.\n+Definition: solver.hh:67\n+Dune::InverseOperatorResult::reduction\n+double reduction\n+Reduction achieved: .\n+Definition: solver.hh:70\n Dune::InverseOperatorResult::clear\n void clear()\n Resets all data.\n Definition: solver.hh:56\n+Dune::InverseOperatorResult::conv_rate\n+double conv_rate\n+Convergence rate (average reduction per step)\n+Definition: solver.hh:76\n Dune::InverseOperatorResult::converged\n bool converged\n True if convergence criterion has been met.\n Definition: solver.hh:73\n-Dune::InverseOperator<_X,_X_>::scalar_real_type\n+Dune::InverseOperator\n+Abstract base class for all solvers.\n+Definition: solver.hh:99\n+Dune::InverseOperator::printHeader\n+void printHeader(std::ostream &s) const\n+helper function for printing header of solver output\n+Definition: solver.hh:163\n+Dune::InverseOperator::~InverseOperator\n+virtual ~InverseOperator()\n+Destructor.\n+Definition: solver.hh:156\n+Dune::InverseOperator::printOutput\n+void printOutput(std::ostream &s, const CountType &iter, const DataType &norm)\n+const\n+helper function for printing solver output\n+Definition: solver.hh:185\n+Dune::InverseOperator::printOutput\n+void printOutput(std::ostream &s, const CountType &iter, const DataType &norm,\n+const DataType &norm_old) const\n+helper function for printing solver output\n+Definition: solver.hh:172\n+Dune::InverseOperator::apply\n+virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)=0\n+apply inverse operator, with given convergence criteria.\n+Dune::InverseOperator::scalar_real_type\n Simd::Scalar< real_type > scalar_real_type\n scalar type underlying the field_type\n Definition: solver.hh:114\n Dune::InverseOperator::range_type\n Y range_type\n Type of the range of the operator to be inverted.\n Definition: solver.hh:105\n+Dune::InverseOperator::normSpacing\n+@ normSpacing\n+Definition: solver.hh:160\n+Dune::InverseOperator::iterationSpacing\n+@ iterationSpacing\n+Definition: solver.hh:160\n Dune::InverseOperator::domain_type\n X domain_type\n Type of the domain of the operator to be inverted.\n Definition: solver.hh:102\n-Dune::InverseOperator<_X,_X_>::field_type\n+Dune::InverseOperator::apply\n+virtual void apply(X &x, Y &b, InverseOperatorResult &res)=0\n+Apply inverse operator,.\n+Dune::InverseOperator::field_type\n X::field_type field_type\n The field type of the operator.\n Definition: solver.hh:108\n-Dune::InverseOperator<_X,_X_>::real_type\n+Dune::InverseOperator::real_type\n FieldTraits< field_type >::real_type real_type\n The real type of the field type (is the same if using real numbers, but differs\n for std::complex)\n Definition: solver.hh:111\n+Dune::InverseOperator::category\n+virtual SolverCategory::Category category() const =0\n+Category of the solver (see SolverCategory::Category)\n Dune::IterativeSolver\n Base class for all implementations of iterative solvers.\n Definition: solver.hh:203\n-Dune::IterativeSolver<_X,_X_>::_sp\n+Dune::IterativeSolver::IterativeSolver\n+IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, const ParameterTree &configuration)\n+Constructor.\n+Definition: solver.hh:313\n+Dune::IterativeSolver::IterativeSolver\n+IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n+Constructor.\n+Definition: solver.hh:290\n+Dune::IterativeSolver::apply\n+virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)\n+Apply inverse operator with given reduction factor.\n+Definition: solver.hh:374\n+Dune::IterativeSolver::_sp\n std::shared_ptr< const ScalarProduct< X > > _sp\n Definition: solver.hh:506\n-Dune::IterativeSolver<_X,_X_>::IterativeSolver\n-IterativeSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec,\n+Dune::IterativeSolver::IterativeSolver\n+IterativeSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+Y > > prec, scalar_real_type reduction, int maxit, int verbose)\n+General constructor to initialize an iterative solver.\n+Definition: solver.hh:340\n+Dune::IterativeSolver::name\n+std::string name() const\n+Definition: solver.hh:388\n+Dune::IterativeSolver::IterativeSolver\n+IterativeSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec,\n scalar_real_type reduction, int maxit, int verbose)\n General constructor to initialize an iterative solver.\n Definition: solver.hh:230\n-Dune::IterativeSolver<_X,_X_>::_op\n-std::shared_ptr< const LinearOperator< X, X > > _op\n+Dune::IterativeSolver::_op\n+std::shared_ptr< const LinearOperator< X, Y > > _op\n Definition: solver.hh:504\n-Dune::IterativeSolver<_X,_X_>::_maxit\n+Dune::IterativeSolver::_maxit\n int _maxit\n Definition: solver.hh:508\n-Dune::IterativeSolver<_X,_X_>::_verbose\n+Dune::IterativeSolver::_verbose\n int _verbose\n Definition: solver.hh:509\n-Dune::IterativeSolver<_X,_X_>::_reduction\n+Dune::IterativeSolver::_reduction\n scalar_real_type _reduction\n Definition: solver.hh:507\n-Dune::IterativeSolver<_X,_X_>::_prec\n-std::shared_ptr< Preconditioner< X, X > > _prec\n+Dune::IterativeSolver::IterativeSolver\n+IterativeSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp,\n+Preconditioner< X, Y > &prec, scalar_real_type reduction, int maxit, int\n+verbose)\n+General constructor to initialize an iterative solver.\n+Definition: solver.hh:262\n+Dune::IterativeSolver::_category\n+SolverCategory::Category _category\n+Definition: solver.hh:510\n+Dune::IterativeSolver::_prec\n+std::shared_ptr< Preconditioner< X, Y > > _prec\n Definition: solver.hh:505\n-Dune::LoopSolver\n-Preconditioned loop solver.\n-Definition: solvers.hh:59\n-Dune::LoopSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator,.\n-Definition: solvers.hh:73\n-Dune::LoopSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:116\n-Dune::GradientSolver\n-gradient method\n-Definition: solvers.hh:124\n-Dune::GradientSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:142\n-Dune::GradientSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:187\n-Dune::CGSolver\n-conjugate gradient method\n-Definition: solvers.hh:193\n-Dune::CGSolver::CGSolver\n-CGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr<\n-ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec,\n-scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)\n-Constructor to initialize a CG solver.\n-Definition: solvers.hh:256\n-Dune::CGSolver::enableConditionEstimate\n-static constexpr bool enableConditionEstimate\n-Definition: solvers.hh:208\n-Dune::CGSolver::CGSolver\n-CGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp,\n-Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n-verbose, bool condition_estimate)\n-Constructor to initialize a CG solver.\n-Definition: solvers.hh:239\n-Dune::CGSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:279\n-Dune::CGSolver::CGSolver\n-CGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec,\n-scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)\n-Constructor to initialize a CG solver.\n-Definition: solvers.hh:222\n-Dune::CGSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:412\n-Dune::BiCGSTABSolver\n-Bi-conjugate Gradient Stabilized (BiCG-STAB)\n-Definition: solvers.hh:419\n-Dune::BiCGSTABSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< CountType > Iteration\n-Definition: solvers.hh:598\n-Dune::BiCGSTABSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:439\n-Dune::MINRESSolver\n-Minimal Residual Method (MINRES)\n-Definition: solvers.hh:609\n-Dune::MINRESSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:627\n-Dune::MINRESSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:808\n-Dune::RestartedGMResSolver\n-implements the Generalized Minimal Residual (GMRes) method\n-Definition: solvers.hh:827\n-Dune::RestartedGMResSolver::RestartedGMResSolver\n-RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n-Constructor.\n-Definition: solvers.hh:878\n-Dune::RestartedGMResSolver::conjugate\n-std::enable_if::value, T >::type\n-conjugate(const T &t)\n-Definition: solvers.hh:1067\n-Dune::RestartedGMResSolver::RestartedGMResSolver\n-RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, const ParameterTree &configuration)\n-Definition: solvers.hh:883\n-Dune::RestartedGMResSolver::update\n-void update(X &w, int i, const std::vector< std::vector< field_type, fAlloc > >\n-&H, const std::vector< field_type, fAlloc > &s, const std::vector< X > &v)\n-Definition: solvers.hh:1039\n-Dune::RestartedGMResSolver::conjugate\n-std::enable_if< std::is_same< field_type, real_type >::value, T >::type\n-conjugate(const T &t)\n-Definition: solvers.hh:1062\n-Dune::RestartedGMResSolver::fAlloc\n-ReboundAllocatorType< X, field_type > fAlloc\n-field_type Allocator retrieved from domain type\n-Definition: solvers.hh:838\n-Dune::RestartedGMResSolver::_restart\n-int _restart\n-Definition: solvers.hh:1120\n-Dune::RestartedGMResSolver::rAlloc\n-ReboundAllocatorType< X, real_type > rAlloc\n-real_type Allocator retrieved from domain type\n-Definition: solvers.hh:840\n-Dune::RestartedGMResSolver::apply\n-virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:923\n-Dune::RestartedGMResSolver::RestartedGMResSolver\n-RestartedGMResSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y >\n-&prec, scalar_real_type reduction, int restart, int maxit, int verbose)\n-Set up RestartedGMResSolver solver.\n-Definition: solvers.hh:850\n-Dune::RestartedGMResSolver::RestartedGMResSolver\n-RestartedGMResSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X >\n-&sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int\n-maxit, int verbose)\n-Set up RestartedGMResSolver solver.\n-Definition: solvers.hh:861\n-Dune::RestartedGMResSolver::generatePlaneRotation\n-void generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n-field_type &sn)\n-Definition: solvers.hh:1073\n-Dune::RestartedGMResSolver::RestartedGMResSolver\n-RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-Y > > prec, scalar_real_type reduction, int restart, int maxit, int verbose)\n-Set up RestartedGMResSolver solver.\n-Definition: solvers.hh:894\n-Dune::RestartedGMResSolver::apply\n-virtual void apply(X &x, Y &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:910\n-Dune::RestartedGMResSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:1119\n-Dune::RestartedGMResSolver::applyPlaneRotation\n-void applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n-field_type &sn)\n-Definition: solvers.hh:1106\n-Dune::RestartedFlexibleGMResSolver\n-implements the Flexible Generalized Minimal Residual (FGMRes) method (right\n-preconditioned)\n-Definition: solvers.hh:1139\n-Dune::RestartedFlexibleGMResSolver::apply\n-void apply(X &x, Y &b, double reduction, InverseOperatorResult &res) override\n-Apply inverse operator.\n-Definition: solvers.hh:1169\n-Dune::GeneralizedPCGSolver\n-Generalized preconditioned conjugate gradient solver.\n-Definition: solvers.hh:1307\n-Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n-GeneralizedPCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X >\n-&sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n-verbose, int restart=10)\n-Set up nonlinear preconditioned conjugate gradient solver.\n-Definition: solvers.hh:1343\n-Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n-GeneralizedPCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X >\n-&prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)\n-Set up nonlinear preconditioned conjugate gradient solver.\n-Definition: solvers.hh:1331\n-Dune::GeneralizedPCGSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:1391\n-Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n-GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n-Constructor.\n-Definition: solvers.hh:1361\n-Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n-GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)\n-Set up nonlinear preconditioned conjugate gradient solver.\n-Definition: solvers.hh:1377\n-Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n-GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, const ParameterTree &configuration)\n-Definition: solvers.hh:1366\n-Dune::RestartedFCGSolver\n-Accelerated flexible conjugate gradient method.\n-Definition: solvers.hh:1501\n-Dune::RestartedFCGSolver::RestartedFCGSolver\n-RestartedFCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X >\n-&prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)\n-Constructor to initialize a RestartedFCG solver.\n-Definition: solvers.hh:1519\n-Dune::RestartedFCGSolver::RestartedFCGSolver\n-RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)\n-Constructor.\n-Definition: solvers.hh:1559\n-Dune::RestartedFCGSolver::RestartedFCGSolver\n-RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)\n-Constructor to initialize a RestartedFCG solver.\n-Definition: solvers.hh:1539\n-Dune::RestartedFCGSolver::_mmax\n-int _mmax\n-Definition: solvers.hh:1662\n-Dune::RestartedFCGSolver::RestartedFCGSolver\n-RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n-shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n-X > > prec, const ParameterTree &config)\n-Definition: solvers.hh:1565\n-Dune::RestartedFCGSolver::Iteration\n-typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n-Definition: solvers.hh:1669\n-Dune::RestartedFCGSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)\n-Apply inverse operator.\n-Definition: solvers.hh:1584\n-Dune::RestartedFCGSolver::RestartedFCGSolver\n-RestartedFCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X >\n-&sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n-verbose, int mmax=10)\n-Constructor to initialize a RestartedFCG solver.\n-Definition: solvers.hh:1529\n-Dune::CompleteFCGSolver\n-Complete flexible conjugate gradient method.\n-Definition: solvers.hh:1680\n-Dune::CompleteFCGSolver::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res) override\n-Apply inverse operator.\n-Definition: solvers.hh:1694\n+Dune::IterativeSolver::category\n+virtual SolverCategory::Category category() const\n+Category of the solver (see SolverCategory::Category)\n+Definition: solver.hh:383\n+Dune::IterativeSolver::Iteration\n+Class for controlling iterative methods.\n+Definition: solver.hh:411\n+Dune::IterativeSolver::Iteration::Iteration\n+Iteration(const IterativeSolver &parent, InverseOperatorResult &res)\n+Definition: solver.hh:413\n+Dune::IterativeSolver::Iteration::Iteration\n+Iteration(Iteration &&other)\n+Definition: solver.hh:428\n+Dune::IterativeSolver::Iteration::_res\n+InverseOperatorResult & _res\n+Definition: solver.hh:498\n+Dune::IterativeSolver::Iteration::_parent\n+const IterativeSolver & _parent\n+Definition: solver.hh:499\n+Dune::IterativeSolver::Iteration::_watch\n+Timer _watch\n+Definition: solver.hh:497\n+Dune::IterativeSolver::Iteration::Iteration\n+Iteration(const Iteration &)=delete\n+Dune::IterativeSolver::Iteration::_i\n+CountType _i\n+Definition: solver.hh:496\n+Dune::IterativeSolver::Iteration::_def0\n+real_type _def0\n+Definition: solver.hh:495\n+Dune::IterativeSolver::Iteration::step\n+bool step(CountType i, real_type def)\n+registers the iteration step, checks for invalid defect norm and convergence.\n+Definition: solver.hh:455\n+Dune::IterativeSolver::Iteration::finalize\n+void finalize()\n+Definition: solver.hh:480\n+Dune::IterativeSolver::Iteration::_def\n+real_type _def\n+Definition: solver.hh:495\n+Dune::IterativeSolver::Iteration::~Iteration\n+~Iteration()\n+Definition: solver.hh:440\n+Dune::IterativeSolver::Iteration::_valid\n+bool _valid\n+Definition: solver.hh:500\n+Dune::SolverHelper\n+Helper class for notifying a DUNE-ISTL linear solver about a change of the\n+iteration matrix object in...\n+Definition: solver.hh:522\n+Dune::SolverHelper::setMatrix\n+static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n+Definition: solver.hh:524\n+Dune::SolverHelper::Implementation\n+Implementation that works together with iterative ISTL solvers, e.g. Dune::\n+CGSolver or Dune::BiCGSTAB...\n+Definition: solver.hh:540\n+Dune::SolverHelper::Implementation::setMatrix\n+static void setMatrix(ISTLLinearSolver &, const BCRSMatrix &)\n+Definition: solver.hh:541\n+Dune::SolverHelper::Implementation<_true,_Dummy_>::setMatrix\n+static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n+Definition: solver.hh:553\n+Dune::SolverCategory\n+Categories for the solvers.\n+Definition: solvercategory.hh:22\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n+Dune::InvalidSolverCategory\n+Definition: solvercategory.hh:54\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00059.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00059.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: supermatrix.hh File Reference\n+dune-istl: spqr.hh File Reference\n \n \n \n \n \n \n \n@@ -64,63 +64,65 @@\n \n
    \n
    \n
    \n \n-
    supermatrix.hh File Reference
    \n+Namespaces |\n+Functions
    \n+ \n
    \n
    \n-
    #include "bcrsmatrix.hh"
    \n-#include "bvector.hh"
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <limits>
    \n-#include <dune/istl/bccsmatrixinitializer.hh>
    \n-#include "superlufunctions.hh"
    \n+\n+

    Class for using SPQR with ISTL matrices. \n+More...

    \n+
    #include <complex>
    \n+#include <type_traits>
    \n+#include <SuiteSparseQR.hpp>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/istl/bccsmatrixinitializer.hh>
    \n+#include <dune/istl/solvers.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/istl/solverfactory.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::SuperMatrixCreateSparseChooser< T >
     
    struct  Dune::SuperMatrixPrinter< T >
     
    struct  Dune::BaseGetSuperLUType< T >
     
    struct  Dune::GetSuperLUType< T >
    class  Dune::SPQR< Matrix >
     Use the SPQR package to directly solve linear systems – empty default class. More...
     
    struct  Dune::GetSuperLUType< double >
    class  Dune::SPQR< BCRSMatrix< FieldMatrix< T, n, m >, A > >
     The SPQR direct sparse solver for matrices of type BCRSMatrix. More...
     
    struct  Dune::GetSuperLUType< float >
    struct  Dune::IsDirectSolver< SPQR< BCRSMatrix< T, A > > >
     
    struct  Dune::GetSuperLUType< std::complex< double > >
    struct  Dune::StoresColumnCompressed< SPQR< BCRSMatrix< T, A > > >
     
    struct  Dune::GetSuperLUType< std::complex< float > >
    struct  Dune::SPQRCreator
     
    struct  Dune::SuperLUMatrix< M >
     Utility class for converting an ISTL Matrix into a SuperLU Matrix. More...
    struct  Dune::SPQRCreator::isValidBlock< class >
     
    struct  Dune::SuperMatrixInitializer< M >
     
    class  Dune::SuperLUMatrix< BCRSMatrix< B, TA > >
     Converter for BCRSMatrix to SuperLU Matrix. More...
     
    class  Dune::SuperMatrixInitializer< BCRSMatrix< B, A > >
    struct  Dune::SPQRCreator::isValidBlock< FieldVector< double, 1 > >
     
    \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n

    \n+Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("spqr", Dune::SPQRCreator())
     
    \n-
    \n+

    Detailed Description

    \n+

    Class for using SPQR with ISTL matrices.

    \n+
    Author
    Marco Agnese, Andrea Sacconi
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,52 +4,58 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-supermatrix.hh File Reference\n-#include \"bcrsmatrix.hh\"\n-#include \"bvector.hh\"\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+spqr.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL)\n+Class for using SPQR with ISTL matrices. More...\n+#include \n+#include \n+#include \n+#include \n #include \n-#include \"superlufunctions.hh\"\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::SuperMatrixCreateSparseChooser<_T_>\n+ class\n+ \u00a0Dune::SPQR<_Matrix_>\n+\u00a0 Use the SPQR package to directly solve linear systems \u2013 empty default class.\n+ More...\n \u00a0\n-struct \u00a0Dune::SuperMatrixPrinter<_T_>\n+ class\n+ \u00a0Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n+\u00a0 The SPQR direct sparse solver for matrices of type BCRSMatrix. More...\n \u00a0\n-struct \u00a0Dune::BaseGetSuperLUType<_T_>\n+struct\n+ \u00a0Dune::IsDirectSolver<_SPQR<_BCRSMatrix<_T,_A_>_>_>\n \u00a0\n-struct \u00a0Dune::GetSuperLUType<_T_>\n+struct\n+ \u00a0Dune::StoresColumnCompressed<_SPQR<_BCRSMatrix<_T,_A_>_>_>\n \u00a0\n-struct \u00a0Dune::GetSuperLUType<_double_>\n+struct\n+ \u00a0Dune::SPQRCreator\n \u00a0\n-struct \u00a0Dune::GetSuperLUType<_float_>\n+struct\n+ \u00a0Dune::SPQRCreator::isValidBlock<_class_>\n \u00a0\n-struct \u00a0Dune::GetSuperLUType<_std::complex<_double_>_>\n-\u00a0\n-struct \u00a0Dune::GetSuperLUType<_std::complex<_float_>_>\n-\u00a0\n-struct \u00a0Dune::SuperLUMatrix<_M_>\n-\u00a0 Utility class for converting an ISTL Matrix into a SuperLU Matrix.\n- More...\n-\u00a0\n-struct \u00a0Dune::SuperMatrixInitializer<_M_>\n-\u00a0\n- class \u00a0Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>\n-\u00a0 Converter for BCRSMatrix to SuperLU Matrix. More...\n-\u00a0\n- class \u00a0Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>\n+struct\n+ \u00a0Dune::SPQRCreator::isValidBlock<_FieldVector<_double,_1_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Functions\n+\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"spqr\", Dune::SPQRCreator())\n+\u00a0\n+***** Detailed Description *****\n+Class for using SPQR with ISTL matrices.\n+ Author\n+ Marco Agnese, Andrea Sacconi\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00059_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00059_source.html", "has_internal_linenos": true, "unified_diff": "@@ -21,4493 +21,4455 @@\n 00000140: 6f6e 7465 6e74 3d22 446f 7879 6765 6e20 ontent=\"Doxygen \n 00000150: 312e 392e 3422 2f3e 0a3c 6d65 7461 206e 1.9.4\"/>..<\n 000001a0: 7469 746c 653e 6475 6e65 2d69 7374 6c3a title>dune-istl:\n-000001b0: 2073 7570 6572 6d61 7472 6978 2e68 6820 supermatrix.hh \n-000001c0: 536f 7572 6365 2046 696c 653c 2f74 6974 Source File....\n-00000340: 3c2f 7363 7269 7074 3e0a 3c6c 696e 6b20 ...<\n-00000390: 626f 6479 3e0a 3c64 6976 2069 643d 2274 body>.
    ... . . . .
    .
    dune\n-00000470: 2d69 7374 6c3c 7370 616e 2069 643d 2270 -istl&#\n-00000490: 3136 303b 322e 392e 303c 2f73 7061 6e3e 160;2.9.0\n-000004a0: 0a20 2020 3c2f 6469 763e 0a20 203c 2f74 .
    . .
    ...\n-00000510: 0a3c 7363 7269 7074 2074 7970 653d 2274 .\n-00000630: 0a3c 7363 7269 7074 2074 7970 653d 2274 ..
    ..
    ....
    .
      .\n+00000990: 3c6c 6920 636c 6173 733d 226e 6176 656c
    • dune
    • \n+000009f0: 3c6c 6920 636c 6173 733d 226e 6176 656c
    • istl
    • \n+00000a50: 2020 3c2f 756c 3e0a 3c2f 6469 763e 0a3c
    .
    .<\n+00000a60: 2f64 6976 3e3c 212d 2d20 746f 7020 2d2d /div>..Go to \n+00000b10: 7468 6520 646f 6375 6d65 6e74 6174 696f the documentatio\n+00000b20: 6e20 6f66 2074 6869 7320 6669 6c65 2e3c n of this file.<\n+00000b30: 2f61 3e3c 6469 7620 636c 6173 733d 2266 /a>
    1// SPDX-FileC\n+00000bc0: 6f70 7972 6967 6874 5465 7874 3a20 436f opyrightText: Co\n+00000bd0: 7079 7269 6768 7420 2843 2920 4455 4e45 pyright (C) DUNE\n+00000be0: 2050 726f 6a65 6374 2063 6f6e 7472 6962 Project contrib\n+00000bf0: 7574 6f72 732c 2073 6565 2066 696c 6520 utors, see file \n+00000c00: 4c49 4345 4e53 452e 6d64 2069 6e20 6d6f LICENSE.md in mo\n+00000c10: 6475 6c65 2072 6f6f 743c 2f73 7061 6e3e dule root\n+00000c20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00000c70: 2020 2032 3c2f 7370 616e 3e3c 7370 616e 2// SPDX-License\n+00000ca0: 2d49 6465 6e74 6966 6965 723a 204c 6963 -Identifier: Lic\n+00000cb0: 656e 7365 5265 662d 4750 4c2d 322e 302d enseRef-GPL-2.0-\n+00000cc0: 6f6e 6c79 2d77 6974 682d 4455 4e45 2d65 only-with-DUNE-e\n+00000cd0: 7863 6570 7469 6f6e 3c2f 7370 616e 3e3c xception<\n+00000ce0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00000d30: 2020 333c 2f73 7061 6e3e 3c73 7061 6e20 3\n+00000d50: 2f2f 202d 2a2d 2074 6162 2d77 6964 7468 // -*- tab-width\n+00000d60: 3a20 343b 2069 6e64 656e 742d 7461 6273 : 4; indent-tabs\n+00000d70: 2d6d 6f64 653a 206e 696c 3b20 632d 6261 -mode: nil; c-ba\n+00000d80: 7369 632d 6f66 6673 6574 3a20 3220 2d2a sic-offset: 2 -*\n+00000d90: 2d3c 2f73 7061 6e3e 3c2f 6469 763e 0a3c -
    .<\n+00000da0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00000db0: 3e3c 6120 6964 3d22 6c30 3030 3034 2220 > 4// vi: \n+00000e10: 7365 7420 6574 2074 733d 3420 7377 3d32 set et ts=4 sw=2\n+00000e20: 2073 7473 3d32 3a3c 2f73 7061 6e3e 3c2f sts=2:.
    \n+00000e80: 2035 3c2f 7370 616e 3e3c 7370 616e 2063 5#ifndef DUNE\n+00000eb0: 5f49 5354 4c5f 5350 5152 5f48 483c 2f73 _ISTL_SPQR_HH
    .
    6<\n+00000f20: 7370 616e 2063 6c61 7373 3d22 7072 6570 span class=\"prep\n+00000f30: 726f 6365 7373 6f72 223e 2364 6566 696e rocessor\">#defin\n+00000f40: 6520 4455 4e45 5f49 5354 4c5f 5350 5152 e DUNE_ISTL_SPQR\n+00000f50: 5f48 483c 2f73 7061 6e3e 3c2f 6469 763e _HH
    \n+00000f60: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00000fd0: 6120 6964 3d22 6c30 3030 3038 2220 6e61 a id=\"l00008\" na\n+00000fe0: 6d65 3d22 6c30 3030 3038 223e 3c2f 613e me=\"l00008\">\n+00000ff0: 3c73 7061 6e20 636c 6173 733d 226c 696e 8#if \n+00001030: 4841 5645 5f53 5549 5445 5350 4152 5345 HAVE_SUITESPARSE\n+00001040: 5f53 5051 5220 7c7c 2064 6566 696e 6564 _SPQR || defined\n+00001050: 2044 4f58 5947 454e 3c2f 7370 616e 3e3c DOXYGEN<\n 00001060: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n 000010b0: 2020 393c 2f73 7061 6e3e 203c 2f64 6976 9 .
    10<\n 00001110: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#include "\n-00001140: 3c61 2063 6c61 7373 3d22 636f 6465 2220 bcrsmatrix.hh\n-00001170: 3c2f 613e 2671 756f 743b 3c2f 7370 616e "
    .
    \n-000011d0: 2020 2031 313c 2f73 7061 6e3e 3c73 7061 11#include \n-00001200: 2671 756f 743b 3c61 2063 6c61 7373 3d22 "bvector\n-00001230: 2e68 683c 2f61 3e26 7175 6f74 3b3c 2f73 .hh"
    .
    12<\n-000012a0: 7370 616e 2063 6c61 7373 3d22 7072 6570 span class=\"prep\n-000012b0: 726f 6365 7373 6f72 223e 2369 6e63 6c75 rocessor\">#inclu\n-000012c0: 6465 2026 6c74 3b64 756e 652f 636f 6d6d de <dune/comm\n-000012d0: 6f6e 2f66 6d61 7472 6978 2e68 6826 6774 on/fmatrix.hh>\n-000012e0: 3b3c 2f73 7061 6e3e 3c2f 6469 763e 0a3c ;
    .<\n-000012f0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00001300: 3e3c 6120 6964 3d22 6c30 3030 3133 2220 > 13#i\n-00001360: 6e63 6c75 6465 2026 6c74 3b64 756e 652f nclude <dune/\n-00001370: 636f 6d6d 6f6e 2f66 7665 6374 6f72 2e68 common/fvector.h\n-00001380: 6826 6774 3b3c 2f73 7061 6e3e 3c2f 6469 h>.
    14\n-000013e0: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 #include <d\n-00001410: 756e 652f 636f 6d6d 6f6e 2f74 7970 6574 une/common/typet\n-00001420: 7261 6974 732e 6868 2667 743b 3c2f 7370 raits.hh>
    .
    15#includ\n-000014b0: 6520 266c 743b 6c69 6d69 7473 2667 743b e <limits>\n-000014c0: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
    .\n-000014e0: 3c61 2069 643d 226c 3030 3031 3622 206e 16
    .
    17#includ\n-000015a0: 6520 266c 743b 3c61 2063 6c61 7373 3d22 e <dune/is\n-000015d0: 746c 2f62 6363 736d 6174 7269 7869 6e69 tl/bccsmatrixini\n-000015e0: 7469 616c 697a 6572 2e68 683c 2f61 3e26 tializer.hh&\n-000015f0: 6774 3b3c 2f73 7061 6e3e 3c2f 6469 763e gt;
    \n-00001600: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00001670: 6120 6964 3d22 6c30 3030 3139 2220 6e61 a id=\"l00019\" na\n-00001680: 6d65 3d22 6c30 3030 3139 223e 3c2f 613e me=\"l00019\">\n-00001690: 3c73 7061 6e20 636c 6173 733d 226c 696e 19#inc\n-000016d0: 6c75 6465 2026 7175 6f74 3b3c 6120 636c lude "su\n-00001700: 7065 726c 7566 756e 6374 696f 6e73 2e68 perlufunctions.h\n-00001710: 683c 2f61 3e26 7175 6f74 3b3c 2f73 7061 h"
    .
    20 #include <co\n+00001140: 6d70 6c65 7826 6774 3b3c 2f73 7061 6e3e mplex>\n+00001150: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+000011a0: 2020 3131 3c2f 7370 616e 3e3c 7370 616e 11#include &\n+000011d0: 6c74 3b74 7970 655f 7472 6169 7473 2667 lt;type_traits&g\n+000011e0: 743b 3c2f 7370 616e 3e3c 2f64 6976 3e0a t;
    .\n+000011f0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00001280: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00001290: 6e6f 223e 2020 2031 333c 2f73 7061 6e3e no\"> 13\n+000012a0: 3c73 7061 6e20 636c 6173 733d 2270 7265 #incl\n+000012c0: 7564 6520 266c 743b 5375 6974 6553 7061 ude <SuiteSpa\n+000012d0: 7273 6551 522e 6870 7026 6774 3b3c 2f73 rseQR.hpp>
    .
    14 \n+00001340: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00001390: 2020 3135 3c2f 7370 616e 3e3c 7370 616e 15#include &\n+000013c0: 6c74 3b64 756e 652f 636f 6d6d 6f6e 2f65 lt;dune/common/e\n+000013d0: 7863 6570 7469 6f6e 732e 6868 2667 743b xceptions.hh>\n+000013e0: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
    .\n+00001400: 3c61 2069 643d 226c 3030 3031 3622 206e 16
    .
    17#includ\n+000014c0: 6520 266c 743b 3c61 2063 6c61 7373 3d22 e <dune/is\n+000014f0: 746c 2f62 6363 736d 6174 7269 7869 6e69 tl/bccsmatrixini\n+00001500: 7469 616c 697a 6572 2e68 683c 2f61 3e26 tializer.hh&\n+00001510: 6774 3b3c 2f73 7061 6e3e 3c2f 6469 763e gt;
    \n+00001520: 0a3c 6469 7620 636c 6173 733d 226c 696e ..
    19#includ\n+00001660: 6520 266c 743b 3c61 2063 6c61 7373 3d22 e <dune/is\n+00001690: 746c 2f73 6f6c 7665 7274 7970 652e 6868 tl/solvertype.hh\n+000016a0: 3c2f 613e 2667 743b 3c2f 7370 616e 3e3c ><\n+000016b0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00001700: 2032 303c 2f73 7061 6e3e 3c73 7061 6e20 20#include &l\n+00001730: 743b 3c61 2063 6c61 7373 3d22 636f 6465 t;dune/istl/s\n+00001760: 6f6c 7665 7266 6163 746f 7279 2e68 683c olverfactory.hh<\n+00001770: 2f61 3e26 6774 3b3c 2f73 7061 6e3e 3c2f /a>>.
    \n-000017d0: 3231 3c2f 7370 616e 3e3c 7370 616e 2063 21n\n-000017f0: 616d 6573 7061 6365 203c 2f73 7061 6e3e amespace \n-00001800: 3c61 2063 6c61 7373 3d22 636f 6465 2068 \n-00001830: 4475 6e65 3c2f 613e 3c2f 6469 763e 0a3c Dune
    .<\n-00001840: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00001850: 3e3c 6120 6964 3d22 6c30 3030 3232 2220 > 22{
    .
    23 \n-000018f0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00001940: 2020 3234 3c2f 7370 616e 3e20 203c 7370 24 template<clas\n-00001990: 733c 2f73 7061 6e3e 2054 2667 743b 3c2f s T>..<\n-00001ad0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00001ae0: 6e6f 223e 2020 2032 363c 2f73 7061 6e3e no\"> 26\n-00001af0: 2020 7b7d 3b3c 2f64 6976 3e0a 3c64 6976 {};
    .<\n-00001b30: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00001b40: 6e6f 223e 2020 2032 373c 2f73 7061 6e3e no\"> 27\n-00001b50: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
    .
    \n-00001ba0: 2020 2032 383c 2f73 7061 6e3e 2020 3c73 28 template<cla\n-00001bf0: 7373 3c2f 7370 616e 3e20 5426 6774 3b3c ss T><\n-00001c00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    29 struct \n-00001ca0: 3c2f 7370 616e 3e3c 6120 636c 6173 733d SuperMatrixP\n-00001ce0: 7269 6e74 6572 3c2f 613e 3c2f 6469 763e rinter
    \n-00001cf0: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-00001d50: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00001dc0: 6120 6964 3d22 6c30 3030 3332 2220 6e61 a id=\"l00032\" na\n-00001dd0: 6d65 3d22 6c30 3030 3332 223e 3c2f 613e me=\"l00032\">\n-00001de0: 3c73 7061 6e20 636c 6173 733d 226c 696e 32#if \n-00001e20: 5f5f 6861 735f 696e 636c 7564 6528 2671 __has_include(&q\n-00001e30: 756f 743b 736c 755f 7364 6566 732e 6826 uot;slu_sdefs.h&\n-00001e40: 7175 6f74 3b3c 2f73 7061 6e3e 293c 2f64 quot;).
    3\n-00001ea0: 333c 2f73 7061 6e3e 2020 3c73 7061 6e20 3 \n-00001ec0: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-00001ed0: 6c74 3b26 6774 3b3c 2f64 6976 3e0a 3c64 lt;>
    .\n-00001ef0: 3c61 2069 643d 226c 3030 3033 3422 206e 34 struct\n-00001f50: 203c 2f73 7061 6e3e 3c61 2063 6c61 7373 SuperMatrix\n-00001f90: 4372 6561 7465 5370 6172 7365 4368 6f6f CreateSparseChoo\n-00001fa0: 7365 723c 2f61 3e26 6c74 3b66 6c6f 6174 ser<float\n-00001fb0: 2667 743b 3c2f 6469 763e 0a3c 6469 7620 >
    .
    35 \n-00002010: 207b 3c2f 6469 763e 0a3c 6469 7620 636c {
    .
    36 \n-00002070: 203c 7370 616e 2063 6c61 7373 3d22 6b65 static v\n-000020b0: 6f69 643c 2f73 7061 6e3e 2063 7265 6174 oid creat\n-000020c0: 6528 5375 7065 724d 6174 7269 7820 2a3c e(SuperMatrix *<\n-000020d0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-000020e0: 5f76 6172 6961 626c 6522 2068 7265 663d _variable\" href=\n-000020f0: 2261 3030 3233 372e 6874 6d6c 2367 6137 \"a00237.html#ga7\n-00002100: 3035 3166 3263 6636 6137 3466 6264 3264 051f2cf6a74fbd2d\n-00002110: 3734 6566 3532 6231 3338 3963 6230 6422 74ef52b1389cb0d\"\n-00002120: 3e6d 6174 3c2f 613e 2c20 3c73 7061 6e20 >mat, int n\n-00002150: 2c20 3c73 7061 6e20 636c 6173 733d 226b , int<\n-00002170: 2f73 7061 6e3e 206d 2c20 3c73 7061 6e20 /span> m, int o\n-000021a0: 6666 7365 742c 3c2f 6469 763e 0a3c 6469 ffset,
    .<\n-000021c0: 6120 6964 3d22 6c30 3030 3337 2220 6e61 a id=\"l00037\" na\n-000021d0: 6d65 3d22 6c30 3030 3337 223e 3c2f 613e me=\"l00037\">\n-000021e0: 3c73 7061 6e20 636c 6173 733d 226c 696e 37 \n-00002210: 2020 2020 2020 2020 3c73 7061 6e20 636c float *\n-00002240: 7661 6c75 6573 2c20 3c73 7061 6e20 636c values, int *ro\n-00002270: 7769 6e64 6578 2c20 3c73 7061 6e20 636c windex, int* co\n-000022a0: 6c69 6e64 6578 2c3c 2f64 6976 3e0a 3c64 lindex,.\n-000022c0: 3c61 2069 643d 226c 3030 3033 3822 206e 38 \n-00002310: 2020 2020 2020 2020 2053 7479 7065 5f74 Stype_t\n-00002320: 2073 7479 7065 2c20 4474 7970 655f 7420 stype, Dtype_t \n-00002330: 6474 7970 652c 204d 7479 7065 5f74 206d dtype, Mtype_t m\n-00002340: 7479 7065 293c 2f64 6976 3e0a 3c64 6976 type).<\n-00002380: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00002390: 6e6f 223e 2020 2033 393c 2f73 7061 6e3e no\"> 39\n-000023a0: 2020 2020 7b3c 2f64 6976 3e0a 3c64 6976 {.<\n-000023e0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-000023f0: 6e6f 223e 2020 2034 303c 2f73 7061 6e3e no\"> 40\n-00002400: 2020 2020 2020 7343 7265 6174 655f 436f sCreate_Co\n-00002410: 6d70 436f 6c5f 4d61 7472 6978 283c 6120 mpCol_Matrix(m\n-00002470: 6174 3c2f 613e 2c20 6e2c 206d 2c20 6f66 at, n, m, of\n-00002480: 6673 6574 2c20 7661 6c75 6573 2c20 726f fset, values, ro\n-00002490: 7769 6e64 6578 2c20 636f 6c69 6e64 6578 windex, colindex\n-000024a0: 2c3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ,.
    \n-000024f0: 2020 2034 313c 2f73 7061 6e3e 2020 2020 41 \n-00002500: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00002510: 2020 2020 2020 2020 2073 7479 7065 2c20 stype, \n-00002520: 6474 7970 652c 206d 7479 7065 293b 3c2f dtype, mtype);.
    \n-00002580: 3432 3c2f 7370 616e 3e20 2020 207d 3c2f 42 }.
    \n-000025e0: 3433 3c2f 7370 616e 3e20 207d 3b3c 2f64 43 };.
    4\n-00002640: 343c 2f73 7061 6e3e 203c 2f64 6976 3e0a 4
    .\n-00002650: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    46 \n-00002730: 3c73 7061 6e20 636c 6173 733d 226b 6579 struct SuperMatrixP\n-00002760: 7269 6e74 6572 266c 743b 666c 6f61 7426 rinter<float&\n-00002770: 6774 3b3c 2f64 6976 3e0a 3c64 6976 2063 gt;
    .
    47 \n-000027d0: 7b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 {
    .
    \n-00002820: 2020 2034 383c 2f73 7061 6e3e 2020 2020 48 \n-00002830: 3c73 7061 6e20 636c 6173 733d 226b 6579 static vo\n-00002870: 6964 3c2f 7370 616e 3e20 7072 696e 7428 id print(\n-00002880: 3c73 7061 6e20 636c 6173 733d 226b 6579 char* name, Sup\n-000028b0: 6572 4d61 7472 6978 2a20 3c61 2063 6c61 erMatrix* mat<\n-00002910: 2f61 3e29 3c2f 6469 763e 0a3c 6469 7620 /a>)
    .
    49 \n-00002970: 2020 207b 3c2f 6469 763e 0a3c 6469 7620 {
    .
    50 \n-000029d0: 2020 2020 2073 5072 696e 745f 436f 6d70 sPrint_Comp\n-000029e0: 436f 6c5f 4d61 7472 6978 286e 616d 652c Col_Matrix(name,\n-000029f0: 203c 6120 636c 6173 733d 2263 6f64 6520 mat);.
    51\n-00002aa0: 3c2f 7370 616e 3e20 2020 207d 3c2f 6469 }.
    52\n-00002b00: 3c2f 7370 616e 3e20 207d 3b3c 2f64 6976 };.
    53<\n-00002b60: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#endif.
    \n-00002be0: 3534 3c2f 7370 616e 3e20 3c2f 6469 763e 54
    \n-00002bf0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00002c20: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 55\n-00002c60: 2369 6620 5f5f 6861 735f 696e 636c 7564 #if __has_includ\n-00002c70: 6528 2671 756f 743b 736c 755f 6464 6566 e("slu_ddef\n-00002c80: 732e 6826 7175 6f74 3b3c 2f73 7061 6e3e s.h"\n-00002c90: 293c 2f64 6976 3e0a 3c64 6976 2063 6c61 )
    .
    \n-00002ce0: 2020 2035 363c 2f73 7061 6e3e 2020 3c73 56 template<>.
    57<\n-00002d70: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> st\n-00002d90: 7275 6374 203c 2f73 7061 6e3e 5375 7065 ruct Supe\n-00002da0: 724d 6174 7269 7843 7265 6174 6553 7061 rMatrixCreateSpa\n-00002db0: 7273 6543 686f 6f73 6572 266c 743b 646f rseChooser<do\n-00002dc0: 7562 6c65 2667 743b 3c2f 6469 763e 0a3c uble>
    .<\n-00002dd0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00002de0: 3e3c 6120 6964 3d22 6c30 3030 3538 2220 > 58 {
    .<\n-00002e40: 6120 6964 3d22 6c30 3030 3539 2220 6e61 a id=\"l00059\" na\n-00002e50: 6d65 3d22 6c30 3030 3539 223e 3c2f 613e me=\"l00059\">\n-00002e60: 3c73 7061 6e20 636c 6173 733d 226c 696e 59 stati\n-00002ea0: 633c 2f73 7061 6e3e 203c 7370 616e 2063 c void c\n-00002ed0: 7265 6174 6528 5375 7065 724d 6174 7269 reate(SuperMatri\n-00002ee0: 7820 2a3c 6120 636c 6173 733d 2263 6f64 x *mat, int n, \n-00002f80: 696e 743c 2f73 7061 6e3e 206d 2c20 3c73 int m, int offset,
    \n-00002fc0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00002ff0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 60 \n-00003020: 2020 2020 2020 2020 2020 2020 3c73 7061 double *values, int *rowindex, int* colindex,.
    61\n-00003110: 3c2f 7370 616e 3e20 2020 2020 2020 2020 \n-00003120: 2020 2020 2020 2020 2020 2020 2020 5374 St\n-00003130: 7970 655f 7420 7374 7970 652c 2044 7479 ype_t stype, Dty\n-00003140: 7065 5f74 2064 7479 7065 2c20 4d74 7970 pe_t dtype, Mtyp\n-00003150: 655f 7420 6d74 7970 6529 3c2f 6469 763e e_t mtype)
    \n-00003160: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-000031c0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-000031f0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 63 dCrea\n-00003220: 7465 5f43 6f6d 7043 6f6c 5f4d 6174 7269 te_CompCol_Matri\n-00003230: 7828 3c61 2063 6c61 7373 3d22 636f 6465 x(mat, n, \n-00003290: 6d2c 206f 6666 7365 742c 2076 616c 7565 m, offset, value\n-000032a0: 732c 2072 6f77 696e 6465 782c 2063 6f6c s, rowindex, col\n-000032b0: 696e 6465 782c 3c2f 6469 763e 0a3c 6469 index,
    .<\n-000032d0: 6120 6964 3d22 6c30 3030 3634 2220 6e61 a id=\"l00064\" na\n-000032e0: 6d65 3d22 6c30 3030 3634 223e 3c2f 613e me=\"l00064\">\n-000032f0: 3c73 7061 6e20 636c 6173 733d 226c 696e 64 \n-00003320: 2020 2020 2020 2020 2020 2020 2020 7374 st\n-00003330: 7970 652c 2064 7479 7065 2c20 6d74 7970 ype, dtype, mtyp\n-00003340: 6529 3b3c 2f64 6976 3e0a 3c64 6976 2063 e);
    .
    65 \n-000033a0: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
    .
    66 \n-00003400: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
    .
    67 .
    \n-000034b0: 3638 3c2f 7370 616e 3e20 203c 7370 616e 68 template\n-000034e0: 266c 743b 2667 743b 3c2f 6469 763e 0a3c <>
    .<\n-000034f0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00003500: 3e3c 6120 6964 3d22 6c30 3030 3639 2220 > 69 struc\n-00003560: 7420 3c2f 7370 616e 3e53 7570 6572 4d61 t SuperMa\n-00003570: 7472 6978 5072 696e 7465 7226 6c74 3b64 trixPrinter<d\n-00003580: 6f75 626c 6526 6774 3b3c 2f64 6976 3e0a ouble>
    .\n-00003590: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-00003600: 3c61 2069 643d 226c 3030 3037 3122 206e 71 stat\n-00003660: 6963 3c2f 7370 616e 3e20 3c73 7061 6e20 ic void \n-00003690: 7072 696e 7428 3c73 7061 6e20 636c 6173 print(\n-000036b0: 6368 6172 3c2f 7370 616e 3e2a 206e 616d char* nam\n-000036c0: 652c 2053 7570 6572 4d61 7472 6978 2a20 e, SuperMatrix* \n-000036d0: 3c61 2063 6c61 7373 3d22 636f 6465 2068 mat)
    \n-00003730: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-00003790: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-000037c0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 73 dPrin\n-000037f0: 745f 436f 6d70 436f 6c5f 4d61 7472 6978 t_CompCol_Matrix\n-00003800: 286e 616d 652c 203c 6120 636c 6173 733d (name, mat\n-00003860: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
    .
    74 \n-000038c0: 207d 3c2f 6469 763e 0a3c 6469 7620 636c }
    .
    75 }\n-00003920: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00003970: 2020 2037 363c 2f73 7061 6e3e 3c73 7061 76#endif
    .
    77 \n-00003a00: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00003a50: 2020 3738 3c2f 7370 616e 3e3c 7370 616e 78#if __has_\n-00003a80: 696e 636c 7564 6528 2671 756f 743b 736c include("sl\n-00003a90: 755f 6364 6566 732e 6826 7175 6f74 3b3c u_cdefs.h"<\n-00003aa0: 2f73 7061 6e3e 293c 2f64 6976 3e0a 3c64 /span>)
    .\n-00003ac0: 3c61 2069 643d 226c 3030 3037 3922 206e 79 templa\n-00003b20: 7465 3c2f 7370 616e 3e26 6c74 3b26 6774 te<>\n-00003b30: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00003b80: 2020 2038 303c 2f73 7061 6e3e 2020 3c73 80 struct SuperMatrixCre\n-00003bc0: 6174 6553 7061 7273 6543 686f 6f73 6572 ateSparseChooser\n-00003bd0: 266c 743b 3c61 2063 6c61 7373 3d22 636f <std::com\n-00003c10: 706c 6578 266c 743b 666c 6f61 7426 6774 plex<float>\n-00003c20: 3b20 2667 743b 3c2f 6469 763e 0a3c 6469 ; >
    .<\n-00003c40: 6120 6964 3d22 6c30 3030 3831 2220 6e61 a id=\"l00081\" na\n-00003c50: 6d65 3d22 6c30 3030 3831 223e 3c2f 613e me=\"l00081\">\n-00003c60: 3c73 7061 6e20 636c 6173 733d 226c 696e 81 {
    .
    82 \n-00003ce0: 2020 203c 7370 616e 2063 6c61 7373 3d22 static<\n-00003d00: 2f73 7061 6e3e 203c 7370 616e 2063 6c61 /span> void cre\n-00003d30: 6174 6528 5375 7065 724d 6174 7269 7820 ate(SuperMatrix \n-00003d40: 2a3c 6120 636c 6173 733d 2263 6f64 6520 *mat, int\n-00003dc0: 206e 2c20 3c73 7061 6e20 636c 6173 733d n, in\n-00003de0: 743c 2f73 7061 6e3e 206d 2c20 3c73 7061 t m, int\n-00003e10: 206f 6666 7365 742c 3c2f 6469 763e 0a3c offset,
    .<\n-00003e20: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00003e30: 3e3c 6120 6964 3d22 6c30 3030 3833 2220 > 83 \n-00003e80: 2020 2020 2020 2020 2020 7374 643a 3a63 std::c\n-00003e90: 6f6d 706c 6578 266c 743b 666c 6f61 7426 omplex<float&\n-00003ea0: 6774 3b20 2a76 616c 7565 732c 203c 7370 gt; *values, int *rowindex, int* colindex,.
    84\n-00003f60: 3c2f 7370 616e 3e20 2020 2020 2020 2020 \n-00003f70: 2020 2020 2020 2020 2020 2020 2020 5374 St\n-00003f80: 7970 655f 7420 7374 7970 652c 2044 7479 ype_t stype, Dty\n-00003f90: 7065 5f74 2064 7479 7065 2c20 4d74 7970 pe_t dtype, Mtyp\n-00003fa0: 655f 7420 6d74 7970 6529 3c2f 6469 763e e_t mtype)
    \n-00003fb0: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-00004010: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00004040: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 86 cCrea\n-00004070: 7465 5f43 6f6d 7043 6f6c 5f4d 6174 7269 te_CompCol_Matri\n-00004080: 7828 3c61 2063 6c61 7373 3d22 636f 6465 x(mat, n, \n-000040e0: 6d2c 206f 6666 7365 742c 203c 7370 616e m, offset, reinterpret_cas\n-00004110: 7426 6c74 3b3c 2f73 7061 6e3e 203a 3a63 t< ::c\n-00004120: 6f6d 706c 6578 2a3c 7370 616e 2063 6c61 omplex*>\n-00004140: 3b3c 2f73 7061 6e3e 2876 616c 7565 7329 ;(values)\n-00004150: 2c3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ,
    .
    \n-000041a0: 2020 2038 373c 2f73 7061 6e3e 2020 2020 87 \n-000041b0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-000041c0: 2020 2020 2020 2020 2072 6f77 696e 6465 rowinde\n-000041d0: 782c 2063 6f6c 696e 6465 782c 2073 7479 x, colindex, sty\n-000041e0: 7065 2c20 6474 7970 652c 206d 7479 7065 pe, dtype, mtype\n-000041f0: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
    .
    88 \n-00004250: 207d 3c2f 6469 763e 0a3c 6469 7620 636c }
    .
    89 }\n-000042b0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00004300: 2020 2039 303c 2f73 7061 6e3e 203c 2f64 90 .
    9\n-00004360: 313c 2f73 7061 6e3e 2020 3c73 7061 6e20 1 \n-00004380: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-00004390: 6c74 3b26 6774 3b3c 2f64 6976 3e0a 3c64 lt;>
    .\n-000043b0: 3c61 2069 643d 226c 3030 3039 3222 206e 92 struct\n-00004410: 203c 2f73 7061 6e3e 5375 7065 724d 6174 SuperMat\n-00004420: 7269 7850 7269 6e74 6572 266c 743b 3c61 rixPrinter<st\n-00004460: 643c 2f61 3e3a 3a63 6f6d 706c 6578 266c d::complex&l\n-00004470: 743b 666c 6f61 7426 6774 3b20 2667 743b t;float> >\n-00004480: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-000044d0: 2020 3933 3c2f 7370 616e 3e20 207b 3c2f 93 {.
    \n-00004530: 3934 3c2f 7370 616e 3e20 2020 203c 7370 94 static\n-00004560: 203c 7370 616e 2063 6c61 7373 3d22 6b65 void<\n-00004580: 2f73 7061 6e3e 2070 7269 6e74 283c 7370 /span> print(char* name, SuperM\n-000045c0: 6174 7269 782a 203c 6120 636c 6173 733d atrix* mat\n-00004620: 293c 2f64 6976 3e0a 3c64 6976 2063 6c61 )
    .
    \n-00004670: 2020 2039 353c 2f73 7061 6e3e 2020 2020 95 \n-00004680: 7b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 {
    .
    \n-000046d0: 2020 2039 363c 2f73 7061 6e3e 2020 2020 96 \n-000046e0: 2020 6350 7269 6e74 5f43 6f6d 7043 6f6c cPrint_CompCol\n-000046f0: 5f4d 6174 7269 7828 6e61 6d65 2c20 3c61 _Matrix(name, \n-00004750: 6d61 743c 2f61 3e29 3b3c 2f64 6976 3e0a mat);
    .\n-00004760: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n-000047c0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-00004820: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00004830: 3e3c 6120 6964 3d22 6c30 3030 3939 2220 > 99#e\n-00004890: 6e64 6966 3c2f 7370 616e 3e3c 2f64 6976 ndif.
    100<\n-000048f0: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
    .\n-00004910: 3c61 2069 643d 226c 3030 3130 3122 206e 101#if\n-00004970: 205f 5f68 6173 5f69 6e63 6c75 6465 2826 __has_include(&\n-00004980: 7175 6f74 3b73 6c75 5f7a 6465 6673 2e68 quot;slu_zdefs.h\n-00004990: 2671 756f 743b 3c2f 7370 616e 3e29 3c2f ").
    1\n-000049f0: 3032 3c2f 7370 616e 3e20 203c 7370 616e 02 template\n-00004a20: 266c 743b 2667 743b 3c2f 6469 763e 0a3c <>
    .<\n-00004a30: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00004a40: 3e3c 6120 6964 3d22 6c30 3031 3033 2220 > 103 struc\n-00004aa0: 7420 3c2f 7370 616e 3e53 7570 6572 4d61 t SuperMa\n-00004ab0: 7472 6978 4372 6561 7465 5370 6172 7365 trixCreateSparse\n-00004ac0: 4368 6f6f 7365 7226 6c74 3b3c 6120 636c Chooser<std::complex<d\n-00004b10: 6f75 626c 6526 6774 3b20 2667 743b 3c2f ouble> >.
    1\n-00004b70: 3034 3c2f 7370 616e 3e20 207b 3c2f 6469 04 {.
    105\n-00004bd0: 3c2f 7370 616e 3e20 2020 203c 7370 616e static <\n-00004c00: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-00004c10: 6f72 6474 7970 6522 3e76 6f69 643c 2f73 ordtype\">void create(Supe\n-00004c30: 724d 6174 7269 7820 2a3c 6120 636c 6173 rMatrix *mat, in\n-00004cb0: 743c 2f73 7061 6e3e 206e 2c20 3c73 7061 t n, int\n-00004ce0: 206d 2c20 3c73 7061 6e20 636c 6173 733d m, in\n-00004d00: 743c 2f73 7061 6e3e 206f 6666 7365 742c t offset,\n-00004d10: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00004d60: 2031 3036 3c2f 7370 616e 3e20 2020 2020 106 \n-00004d70: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00004d80: 2020 7374 643a 3a63 6f6d 706c 6578 266c std::complex&l\n-00004d90: 743b 646f 7562 6c65 2667 743b 202a 7661 t;double> *va\n-00004da0: 6c75 6573 2c20 3c73 7061 6e20 636c 6173 lues, \n-00004dc0: 696e 743c 2f73 7061 6e3e 202a 726f 7769 int *rowi\n-00004dd0: 6e64 6578 2c20 3c73 7061 6e20 636c 6173 ndex, \n-00004df0: 696e 743c 2f73 7061 6e3e 2a20 636f 6c69 int* coli\n-00004e00: 6e64 6578 2c3c 2f64 6976 3e0a 3c64 6976 ndex,
    .<\n-00004e40: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00004e50: 6e6f 223e 2020 3130 373c 2f73 7061 6e3e no\"> 107\n-00004e60: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00004e70: 2020 2020 2020 2053 7479 7065 5f74 2073 Stype_t s\n-00004e80: 7479 7065 2c20 4474 7970 655f 7420 6474 type, Dtype_t dt\n-00004e90: 7970 652c 204d 7479 7065 5f74 206d 7479 ype, Mtype_t mty\n-00004ea0: 7065 293c 2f64 6976 3e0a 3c64 6976 2063 pe)
    .
    108 \n-00004f00: 2020 7b3c 2f64 6976 3e0a 3c64 6976 2063 {
    .
    109 \n-00004f60: 2020 2020 7a43 7265 6174 655f 436f 6d70 zCreate_Comp\n-00004f70: 436f 6c5f 4d61 7472 6978 283c 6120 636c Col_Matrix(mat\n-00004fd0: 3c2f 613e 2c20 6e2c 206d 2c20 6f66 6673 , n, m, offs\n-00004fe0: 6574 2c20 3c73 7061 6e20 636c 6173 733d et, reinte\n-00005000: 7270 7265 745f 6361 7374 266c 743b 3c2f rpret_cast<doublecompl\n-00005020: 6578 2a3c 7370 616e 2063 6c61 7373 3d22 ex*>(values),.
    11\n-000050a0: 303c 2f73 7061 6e3e 2020 2020 2020 2020 0 \n-000050b0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-000050c0: 2020 2020 2072 6f77 696e 6465 782c 2063 rowindex, c\n-000050d0: 6f6c 696e 6465 782c 2073 7479 7065 2c20 olindex, stype, \n-000050e0: 6474 7970 652c 206d 7479 7065 293b 3c2f dtype, mtype);.
    1\n-00005140: 3131 3c2f 7370 616e 3e20 2020 207d 3c2f 11 }.
    1\n-000051a0: 3132 3c2f 7370 616e 3e20 207d 3b3c 2f64 12 };.
    11\n-00005200: 333c 2f73 7061 6e3e 203c 2f64 6976 3e0a 3
    .\n-00005210: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    115 \n-000052f0: 3c73 7061 6e20 636c 6173 733d 226b 6579 struct SuperMatrixP\n-00005320: 7269 6e74 6572 266c 743b 3c61 2063 6c61 rinter<std::complex<do\n-00005370: 7562 6c65 2667 743b 2026 6774 3b3c 2f64 uble> >.
    11\n-000053d0: 363c 2f73 7061 6e3e 2020 7b3c 2f64 6976 6 {.
    117<\n-00005430: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n-00005450: 7374 6174 6963 3c2f 7370 616e 3e20 3c73 static void print(char*\n-000054b0: 206e 616d 652c 2053 7570 6572 4d61 7472 name, SuperMatr\n-000054c0: 6978 2a20 3c61 2063 6c61 7373 3d22 636f ix* mat).
    1\n-00005570: 3138 3c2f 7370 616e 3e20 2020 207b 3c2f 18 {.
    1\n-000055d0: 3139 3c2f 7370 616e 3e20 2020 2020 207a 19 z\n-000055e0: 5072 696e 745f 436f 6d70 436f 6c5f 4d61 Print_CompCol_Ma\n-000055f0: 7472 6978 286e 616d 652c 203c 6120 636c trix(name, mat\n-00005650: 3c2f 613e 293b 3c2f 6469 763e 0a3c 6469 );
    .<\n-00005670: 6120 6964 3d22 6c30 3031 3230 2220 6e61 a id=\"l00120\" na\n-00005680: 6d65 3d22 6c30 3031 3230 223e 3c2f 613e me=\"l00120\">\n-00005690: 3c73 7061 6e20 636c 6173 733d 226c 696e 120 }
    .<\n-000056d0: 6120 6964 3d22 6c30 3031 3231 2220 6e61 a id=\"l00121\" na\n-000056e0: 6d65 3d22 6c30 3031 3231 223e 3c2f 613e me=\"l00121\">\n-000056f0: 3c73 7061 6e20 636c 6173 733d 226c 696e 121 };
    .<\n-00005750: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00005760: 6e6f 223e 2020 3132 323c 2f73 7061 6e3e no\"> 122\n-00005770: 3c73 7061 6e20 636c 6173 733d 2270 7265 #endi\n-00005790: 663c 2f73 7061 6e3e 3c2f 6469 763e 0a3c f
    .<\n-000057a0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000057b0: 3e3c 6120 6964 3d22 6c30 3031 3233 2220 > 123
    .
    124 \n-00005850: 203c 7370 616e 2063 6c61 7373 3d22 6b65 template<\n-00005870: 2f73 7061 6e3e 266c 743b 3c73 7061 6e20 /span><\n-00005890: 636c 6173 733c 2f73 7061 6e3e 2054 2667 class T&g\n-000058a0: 743b 3c2f 6469 763e 0a3c 6469 7620 636c t;
    .
    125 stru\n-00005940: 6374 203c 2f73 7061 6e3e 3c61 2063 6c61 ct BaseGetSu\n-00005980: 7065 724c 5554 7970 653c 2f61 3e3c 2f64 perLUType.
    12\n-000059e0: 363c 2f73 7061 6e3e 2020 7b3c 2f64 6976 6 {.
    \n-00005a80: 2031 3237 3c2f 613e 3c2f 7370 616e 3e20 127 \n-00005a90: 2020 203c 7370 616e 2063 6c61 7373 3d22 static<\n-00005ab0: 2f73 7061 6e3e 203c 7370 616e 2063 6c61 /span> con\n-00005ad0: 7374 3c2f 7370 616e 3e20 4474 7970 655f st Dtype_\n-00005ae0: 7420 3c61 2063 6c61 7373 3d22 636f 6465 t type;.
    128\n-00005b90: 3c2f 7370 616e 3e20 207d 3b3c 2f64 6976 };.
    129<\n-00005bf0: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
    .\n-00005c10: 3c61 2069 643d 226c 3030 3133 3022 206e 130 templa\n-00005c70: 7465 3c2f 7370 616e 3e26 6c74 3b3c 7370 te<class \n-00005ca0: 5426 6774 3b3c 2f64 6976 3e0a 3c64 6976 T>
    .<\n-00005ce0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00005cf0: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 131\n-00005d20: 3c2f 7370 616e 3e20 203c 7370 616e 2063
    s\n-00005d40: 7472 7563 7420 3c2f 7370 616e 3e3c 6120 truct GetSup\n-00005d80: 6572 4c55 5479 7065 3c2f 613e 3c2f 6469 erLUType.
    132\n-00005de0: 3c2f 7370 616e 3e20 207b 7d3b 3c2f 6469 {};.
    133\n-00005e40: 3c2f 7370 616e 3e20 3c2f 6469 763e 0a3c
    .<\n-00005e50: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00005e60: 3e3c 6120 6964 3d22 6c30 3031 3334 2220 > 134 templ\n-00005ec0: 6174 653c 2f73 7061 6e3e 266c 743b 3c73 ate<class\n-00005ef0: 2054 2667 743b 3c2f 6469 763e 0a3c 6469 T>
    .<\n-00005f10: 6120 6964 3d22 6c30 3031 3335 2220 6e61 a id=\"l00135\" na\n-00005f20: 6d65 3d22 6c30 3031 3335 223e 3c2f 613e me=\"l00135\">\n-00005f30: 3c73 7061 6e20 636c 6173 733d 226c 696e 135 const Dtype_t BaseG\n-00005fb0: 6574 5375 7065 724c 5554 7970 6526 6c74 etSuperLUType<\n-00005fc0: 3b54 2667 743b 3a3a 7479 7065 3c2f 613e ;T>::type\n-00005fd0: 203d 3c2f 6469 763e 0a3c 6469 7620 636c =
    .
    136 \n-00006030: 2073 7464 3a3a 6973 5f73 616d 6526 6c74 std::is_same<\n-00006040: 3b54 2c66 6c6f 6174 2667 743b 3a3a 7661 ;T,float>::va\n-00006050: 6c75 6520 3f20 534c 555f 5320 3a3c 2f64 lue ? SLU_S :.
    13\n-000060b0: 373c 2f73 7061 6e3e 2020 2020 2820 2073 7 ( s\n-000060c0: 7464 3a3a 6973 5f73 616d 6526 6c74 3b54 td::is_same<T\n-000060d0: 2c73 7464 3a3a 636f 6d70 6c65 7826 6c74 ,std::complex<\n-000060e0: 3b64 6f75 626c 6526 6774 3b20 2667 743b ;double> >\n-000060f0: 3a3a 7661 6c75 6520 3f20 534c 555f 5a20 ::value ? SLU_Z \n-00006100: 3a3c 2f64 6976 3e0a 3c64 6976 2063 6c61 :
    .
    \n-00006150: 2020 3133 383c 2f73 7061 6e3e 2020 2020 138 \n-00006160: 2020 2028 2073 7464 3a3a 6973 5f73 616d ( std::is_sam\n-00006170: 6526 6c74 3b54 2c73 7464 3a3a 636f 6d70 e<T,std::comp\n-00006180: 6c65 7826 6c74 3b66 6c6f 6174 2667 743b lex<float>\n-00006190: 2026 6774 3b3a 3a76 616c 7565 203f 2053 >::value ? S\n-000061a0: 4c55 5f43 203a 2053 4c55 5f44 2029 293b LU_C : SLU_D ));\n-000061b0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00006200: 2031 3339 3c2f 7370 616e 3e20 3c2f 6469 139 .
    140\n-00006260: 3c2f 7370 616e 3e20 203c 7370 616e 2063 t\n-00006280: 656d 706c 6174 653c 2f73 7061 6e3e 266c emplate&l\n-00006290: 743b 2667 743b 3c2f 6469 763e 0a3c 6469 t;>
    .<\n-000062b0: 6120 6964 3d22 6c30 3031 3431 2220 6e61 a id=\"l00141\" na\n-000062c0: 6d65 3d22 6c30 3031 3431 223e 3c2f 613e me=\"l00141\">\n-000062d0: 3c73 7061 6e20 636c 6173 733d 226c 696e 141 \n-00006330: 7374 7275 6374 203c 2f73 7061 6e3e 3c61 struct GetSu\n-00006370: 7065 724c 5554 7970 653c 2f61 3e26 6c74 perLUType<\n-00006380: 3b64 6f75 626c 6526 6774 3b3c 2f64 6976 ;double>.
    142<\n-000063e0: 2f73 7061 6e3e 2020 2020 3a20 3c73 7061 /span> : public \n-00006410: 3c61 2063 6c61 7373 3d22 636f 6465 2068 Bas\n-00006440: 6547 6574 5375 7065 724c 5554 7970 653c eGetSuperLUType<\n-00006450: 2f61 3e26 6c74 3b64 6f75 626c 6526 6774 /a><double>\n-00006460: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-000064b0: 2020 3134 333c 2f73 7061 6e3e 2020 7b3c 143 {<\n-000064c0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    144 typ\n-00006580: 6564 6566 3c2f 7370 616e 3e20 3c73 7061 edef double float_type;
    .
    145 \n-00006670: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
    .
    146 .
    1\n-00006720: 3437 3c2f 7370 616e 3e20 203c 7370 616e 47 template\n-00006750: 266c 743b 2667 743b 3c2f 6469 763e 0a3c <>
    .<\n-00006760: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00006770: 3e3c 6120 6964 3d22 6c30 3031 3438 2220 > 148<\n-000067d0: 2f61 3e3c 2f73 7061 6e3e 2020 3c73 7061 /a> struct \n-00006800: 3c61 2063 6c61 7373 3d22 636f 6465 2068 Get\n-00006830: 5375 7065 724c 5554 7970 653c 2f61 3e26 SuperLUType&\n-00006840: 6c74 3b66 6c6f 6174 2667 743b 3c2f 6469 lt;float>.
    149\n-000068a0: 3c2f 7370 616e 3e20 2020 203a 203c 7370 : public\n-000068d0: 203c 6120 636c 6173 733d 2263 6f64 6520 Ba\n-00006900: 7365 4765 7453 7570 6572 4c55 5479 7065 seGetSuperLUType\n-00006910: 3c2f 613e 266c 743b 666c 6f61 7426 6774 <float>\n-00006920: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00006970: 2020 3135 303c 2f73 7061 6e3e 2020 7b3c 150 {<\n-00006980: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    151 typ\n-00006a40: 6564 6566 3c2f 7370 616e 3e20 3c73 7061 edef float float_type;
    .
    152 }\n-00006b30: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+000017e0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+000018b0: 6120 6964 3d22 6c30 3030 3334 2220 6e61 a id=\"l00034\" na\n+000018c0: 6d65 3d22 6c30 3030 3334 223e 3c2f 613e me=\"l00034\">\n+000018d0: 3c73 7061 6e20 636c 6173 733d 226c 696e 34 // forw\n+00001910: 6172 6420 6465 636c 6172 6174 696f 6e73 ard declarations\n+00001920: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
    .\n+00001940: 3c61 2069 643d 226c 3030 3033 3522 206e 35 templa\n+000019a0: 7465 3c2f 7370 616e 3e26 6c74 3b3c 7370 te<class \n+000019d0: 4d2c 203c 7370 616e 2063 6c61 7373 3d22 M, class T, c\n+00001a10: 6c61 7373 3c2f 7370 616e 3e20 544d 2c20 lass TM, \n+00001a20: 3c73 7061 6e20 636c 6173 733d 226b 6579 class TD, cla\n+00001a60: 7373 3c2f 7370 616e 3e20 5441 2667 743b ss TA>\n+00001a70: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00001ac0: 2020 3336 3c2f 7370 616e 3e20 203c 7370 36 class \n+00001af0: 5365 714f 7665 726c 6170 7069 6e67 5363 SeqOverlappingSc\n+00001b00: 6877 6172 7a3b 3c2f 6469 763e 0a3c 6469 hwarz;
    .<\n+00001b20: 6120 6964 3d22 6c30 3030 3337 2220 6e61 a id=\"l00037\" na\n+00001b30: 6d65 3d22 6c30 3030 3337 223e 3c2f 613e me=\"l00037\">\n+00001b40: 3c73 7061 6e20 636c 6173 733d 226c 696e 37
    .
    38 <\n+00001bc0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00001bd0: 6f72 6422 3e74 656d 706c 6174 653c 2f73 ord\">template<cl\n+00001c00: 6173 733c 2f73 7061 6e3e 2054 2c20 3c73 ass T, bool tag>.
    39<\n+00001c90: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> st\n+00001cb0: 7275 6374 203c 2f73 7061 6e3e 5365 714f ruct SeqO\n+00001cc0: 7665 726c 6170 7069 6e67 5363 6877 6172 verlappingSchwar\n+00001cd0: 7a41 7373 656d 626c 6572 4865 6c70 6572 zAssemblerHelper\n+00001ce0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+00001d30: 2020 2034 303c 2f73 7061 6e3e 203c 2f64 40 .
    4\n+00001d90: 363c 2f73 7061 6e3e 2020 3c73 7061 6e20 6 \n+00001db0: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n+00001dc0: 6c74 3b3c 7370 616e 2063 6c61 7373 3d22 lt;class Matrix>\n+00001df0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n+00001e40: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+00001e50: 7265 663d 2261 3032 3830 382e 6874 6d6c ref=\"a02808.html\n+00001e60: 223e 2020 2034 373c 2f61 3e3c 2f73 7061 \"> 47 class \n+00001e90: 3c2f 7370 616e 3e3c 6120 636c 6173 733d SPQR..
    \n+00002100: 3c61 2063 6c61 7373 3d22 6c69 6e65 2220 64 class\n+00002150: 203c 2f73 7061 6e3e 3c61 2063 6c61 7373 SPQR<\n+00002190: 3c61 2063 6c61 7373 3d22 636f 6465 2068 BCRS\n+000021c0: 4d61 7472 6978 3c2f 613e 266c 743b 3c61 Matrix<FieldM\n+00002200: 6174 7269 783c 2f61 3e26 6c74 3b54 2c6e atrix<T,n\n+00002210: 2c6d 2667 743b 2c41 2026 6774 3b20 2667 ,m>,A > &g\n+00002220: 743b 3c2f 6469 763e 0a3c 6469 7620 636c t;
    .
    65 \n+00002280: 203a 203c 7370 616e 2063 6c61 7373 3d22 : public<\n+000022a0: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> InverseOperat\n+000022e0: 6f72 3c2f 613e 266c 743b 426c 6f63 6b56 or<BlockV\n+000022f0: 6563 746f 7226 6c74 3b46 6965 6c64 5665 ector<FieldVe\n+00002300: 6374 6f72 266c 743b 542c 6d26 6774 3b2c ctor<T,m>,\n+00002310: 2074 7970 656e 616d 6520 7374 643a 3a61 typename std::a\n+00002320: 6c6c 6f63 6174 6f72 5f74 7261 6974 7326 llocator_traits&\n+00002330: 6c74 3b41 2667 743b 3a3a 7465 6d70 6c61 lt;A>::templa\n+00002340: 7465 2072 6562 696e 645f 616c 6c6f 6326 te rebind_alloc&\n+00002350: 6c74 3b46 6965 6c64 5665 6374 6f72 266c lt;FieldVector&l\n+00002360: 743b 542c 6d26 6774 3b20 2667 743b 2026 t;T,m> > &\n+00002370: 6774 3b2c 3c2f 6469 763e 0a3c 6469 7620 gt;,
    .
    66 \n+000023d0: 2020 2020 2020 2020 2020 2020 2020 2020 \n+000023e0: 2020 2020 2020 2020 2020 2020 426c 6f63 Bloc\n+000023f0: 6b56 6563 746f 7226 6c74 3b46 6965 6c64 kVector<Field\n+00002400: 5665 6374 6f72 266c 743b 542c 6e26 6774 Vector<T,n>\n+00002410: 3b2c 2074 7970 656e 616d 6520 7374 643a ;, typename std:\n+00002420: 3a61 6c6c 6f63 6174 6f72 5f74 7261 6974 :allocator_trait\n+00002430: 7326 6c74 3b41 2667 743b 3a3a 7465 6d70 s<A>::temp\n+00002440: 6c61 7465 2072 6562 696e 645f 616c 6c6f late rebind_allo\n+00002450: 6326 6c74 3b46 6965 6c64 5665 6374 6f72 c<FieldVector\n+00002460: 266c 743b 542c 6e26 6774 3b20 2667 743b <T,n> >\n+00002470: 2026 6774 3b20 2667 743b 3c2f 6469 763e > >
    \n+00002480: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+000024e0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+000024f0: 3e3c 6120 6964 3d22 6c30 3030 3638 2220 > 68 pub\n+00002550: 6c69 633c 2f73 7061 6e3e 3a3c 2f64 6976 lic:...
    <\n+00002880: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+00002890: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n+000028a0: 2367 6137 6463 3833 6137 3131 3066 3731 #ga7dc83a7110f71\n+000028b0: 3466 3862 3566 3333 3766 3863 6337 3734 4f8b5f337f8cc774\n+000028c0: 6236 3222 3e20 2020 3733 3c2f 613e 3c2f b62\"> 73 t\n+000028f0: 7970 6564 6566 3c2f 7370 616e 3e20 4953 ypedef IS\n+00002900: 544c 3a3a 496d 706c 3a3a 4243 4353 4d61 TL::Impl::BCCSMa\n+00002910: 7472 6978 266c 743b 542c 696e 7426 6774 trix<T,int>\n+00002920: 3b20 3c61 2063 6c61 7373 3d22 636f 6465 ; SPQRMatrix;
    .
    75\n+00002a20: 3c2f 7370 616e 3e20 2020 203c 7370 616e typedef \n+00002a50: 4953 544c 3a3a 496d 706c 3a3a 4243 4353 ISTL::Impl::BCCS\n+00002a60: 4d61 7472 6978 496e 6974 6961 6c69 7a65 MatrixInitialize\n+00002a70: 7226 6c74 3b42 4352 534d 6174 7269 7826 r<BCRSMatrix&\n+00002a80: 6c74 3b46 6965 6c64 4d61 7472 6978 266c lt;FieldMatrix&l\n+00002a90: 743b 542c 6e2c 6d26 6774 3b2c 4126 6774 t;T,n,m>,A>\n+00002aa0: 3b2c 203c 7370 616e 2063 6c61 7373 3d22 ;, int\n+00002ac0: 3c2f 7370 616e 3e26 6774 3b20 3c61 2063 > Mat\n+00002b20: 7269 7849 6e69 7469 616c 697a 6572 3c2f rixInitializer;
    .
    77 typedef\n+00002c00: 203c 6120 636c 6173 733d 2263 6f64 6520 Dun\n+00002c30: 653a 3a42 6c6f 636b 5665 6374 6f72 266c e::BlockVector&l\n+00002c40: 743b 4669 656c 6456 6563 746f 7226 6c74 t;FieldVector<\n+00002c50: 3b54 2c6d 2667 743b 3c2f 613e 2c20 3c73 ;T,m>, typename std::allocat\n+00002c90: 6f72 5f74 7261 6974 7326 6c74 3b41 2667 or_traits<A&g\n+00002ca0: 743b 3a3a 7465 6d70 6c61 7465 2072 6562 t;::template reb\n+00002cb0: 696e 645f 616c 6c6f 6326 6c74 3b46 6965 ind_alloc<Fie\n+00002cc0: 6c64 5665 6374 6f72 266c 743b 542c 6d26 ldVector<T,m&\n+00002cd0: 6774 3b20 2667 743b 2026 6774 3b20 3c61 gt; > > d\n+00002d30: 6f6d 6169 6e5f 7479 7065 3c2f 613e 3b3c omain_type;<\n+00002d40: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    79 ty\n+00002e00: 7065 6465 663c 2f73 7061 6e3e 203c 6120 pedef Dune::B\n+00002e40: 6c6f 636b 5665 6374 6f72 266c 743b 4669 lockVector<Fi\n+00002e50: 656c 6456 6563 746f 7226 6c74 3b54 2c6e eldVector<T,n\n+00002e60: 2667 743b 3c2f 613e 2c20 3c73 7061 6e20 >, \n+00002e80: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n+00002e90: 7374 643a 3a61 6c6c 6f63 6174 6f72 5f74 std::allocator_t\n+00002ea0: 7261 6974 7326 6c74 3b41 2667 743b 3a3a raits<A>::\n+00002eb0: 7465 6d70 6c61 7465 2072 6562 696e 645f template rebind_\n+00002ec0: 616c 6c6f 6326 6c74 3b46 6965 6c64 5665 alloc<FieldVe\n+00002ed0: 6374 6f72 266c 743b 542c 6e26 6774 3b20 ctor<T,n> \n+00002ee0: 2667 743b 2026 6774 3b20 3c61 2063 6c61 > > range\n+00002f40: 5f74 7970 653c 2f61 3e3b 3c2f 6469 763e _type;
    \n+00002f50: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+00002fc0: 6120 6964 3d22 6c30 3030 3832 2220 6e61 a id=\"l00082\" na\n+00002fd0: 6d65 3d22 6c30 3030 3832 223e 3c2f 613e me=\"l00082\">\n+00002fe0: 3c73 7061 6e20 636c 6173 733d 226c 696e 82\n+00003040: 3c2f 613e 3c2f 7370 616e 3e20 2020 203c <\n+00003050: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00003060: 6f72 6422 3e76 6972 7475 616c 3c2f 7370 ord\">virtual SolverCa\n+000030d0: 7465 676f 7279 3a3a 4361 7465 676f 7279 tegory::Category\n+000030e0: 3c2f 613e 203c 6120 636c 6173 733d 2263 category<\n+00003140: 2f61 3e28 293c 7370 616e 2063 6c61 7373 /a>() cons\n+00003160: 743c 2f73 7061 6e3e 3c2f 6469 763e 0a3c t
    .<\n+00003170: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00003180: 3e3c 6120 6964 3d22 6c30 3030 3833 2220 > 83 {
    .<\n+00003220: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00003230: 6e6f 223e 2020 2038 343c 2f73 7061 6e3e no\"> 84\n+00003240: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+00003260: 7265 7475 726e 3c2f 7370 616e 3e20 536f return So\n+00003270: 6c76 6572 4361 7465 676f 7279 3a3a 4361 lverCategory::Ca\n+00003280: 7465 676f 7279 3a3a 7365 7175 656e 7469 tegory::sequenti\n+00003290: 616c 3b3c 2f64 6976 3e0a 3c64 6976 2063 al;
    .
    85 \n+000032f0: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
    .
    86 <\n+00003350: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    95 SPQR(const Matrix&\n+000034b0: 3b20 6d61 7472 6978 2c20 3c73 7061 6e20 ; matrix, int v\n+000034e0: 6572 626f 7365 3d30 2920 3a20 6d61 7472 erbose=0) : matr\n+000034f0: 6978 4973 4c6f 6164 6564 5f28 6661 6c73 ixIsLoaded_(fals\n+00003500: 6529 2c20 7665 7262 6f73 655f 2876 6572 e), verbose_(ver\n+00003510: 626f 7365 293c 2f64 6976 3e0a 3c64 6976 bose)
    .<\n+00003550: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00003560: 6e6f 223e 2020 2039 363c 2f73 7061 6e3e no\"> 96\n+00003570: 2020 2020 7b3c 2f64 6976 3e0a 3c64 6976 {
    .<\n+000035b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+000035c0: 6e6f 223e 2020 2039 373c 2f73 7061 6e3e no\"> 97\n+000035d0: 2020 2020 2020 3c73 7061 6e20 636c 6173 //ch\n+000035f0: 6563 6b20 7768 6574 6865 7220 5420 6973 eck whether T is\n+00003600: 2061 2073 7570 706f 7274 6564 2074 7970 a supported typ\n+00003610: 653c 2f73 7061 6e3e 3c2f 6469 763e 0a3c e
    .<\n+00003620: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00003630: 3e3c 6120 6964 3d22 6c30 3030 3938 2220 > 98 s\n+00003690: 7461 7469 635f 6173 7365 7274 3c2f 7370 tatic_assert((std::is_sam\n+000036b0: 6526 6c74 3b54 2c64 6f75 626c 6526 6774 e<T,double>\n+000036c0: 3b3a 3a76 616c 7565 2920 7c7c 2028 7374 ;::value) || (st\n+000036d0: 643a 3a69 735f 7361 6d65 266c 743b 542c d::is_same<T,\n+000036e0: 7374 643a 3a63 6f6d 706c 6578 266c 743b std::complex<\n+000036f0: 646f 7562 6c65 2667 743b 2026 6774 3b3a double> >:\n+00003700: 3a76 616c 7565 292c 3c2f 6469 763e 0a3c :value),
    .<\n+00003710: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00003720: 3e3c 6120 6964 3d22 6c30 3030 3939 2220 > 99 \n+00003770: 2020 2020 2020 203c 7370 616e 2063 6c61 "Unsuppo\n+000037a0: 7274 6564 2054 7970 6520 696e 2053 5051 rted Type in SPQ\n+000037b0: 5220 286f 6e6c 7920 646f 7562 6c65 2061 R (only double a\n+000037c0: 6e64 2073 7464 3a3a 636f 6d70 6c65 7826 nd std::complex&\n+000037d0: 6c74 3b64 6f75 626c 6526 6774 3b20 7375 lt;double> su\n+000037e0: 7070 6f72 7465 6429 2671 756f 743b 3c2f pported)");
    .\n+00003810: 3c61 2069 643d 226c 3030 3130 3022 206e 100 cc_ = new c\n+00003880: 686f 6c6d 6f64 5f63 6f6d 6d6f 6e28 293b holmod_common();\n+00003890: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+000038e0: 2031 3031 3c2f 7370 616e 3e20 2020 2020 101 \n+000038f0: 2063 686f 6c6d 6f64 5f6c 5f73 7461 7274 cholmod_l_start\n+00003900: 2863 635f 293b 3c2f 6469 763e 0a3c 6469 (cc_);
    .<\n+00003920: 6120 6964 3d22 6c30 3031 3032 2220 6e61 a id=\"l00102\" na\n+00003930: 6d65 3d22 6c30 3031 3032 223e 3c2f 613e me=\"l00102\">\n+00003940: 3c73 7061 6e20 636c 6173 733d 226c 696e 102 setMatrix\n+00003970: 286d 6174 7269 7829 3b3c 2f64 6976 3e0a (matrix);
    .\n+00003980: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+000039e0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00003a70: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00003a80: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 113<\n+00003ad0: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c61 /a> \n+00003b30: 5350 5152 3c2f 613e 283c 7370 616e 2063 SPQR(c\n+00003b50: 6f6e 7374 3c2f 7370 616e 3e20 3c61 2063 onst Matrix& matrix, \n+00003ba0: 3c73 7061 6e20 636c 6173 733d 226b 6579 int verbose, bool) : matrixIsL\n+00003c00: 6f61 6465 645f 2866 616c 7365 292c 2076 oaded_(false), v\n+00003c10: 6572 626f 7365 5f28 7665 7262 6f73 6529 erbose_(verbose)\n+00003c20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00003c70: 2031 3134 3c2f 7370 616e 3e20 2020 207b 114 {\n+00003c80: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00003cd0: 2031 3135 3c2f 7370 616e 3e20 2020 2020 115 \n+00003ce0: 203c 7370 616e 2063 6c61 7373 3d22 636f //check w\n+00003d00: 6865 7468 6572 2054 2069 7320 6120 7375 hether T is a su\n+00003d10: 7070 6f72 7465 6420 7479 7065 3c2f 7370 pported type
    .
    116 \n+00003d80: 2020 2020 3c73 7061 6e20 636c 6173 733d static\n+00003da0: 5f61 7373 6572 743c 2f73 7061 6e3e 2828 _assert((\n+00003db0: 7374 643a 3a69 735f 7361 6d65 266c 743b std::is_same<\n+00003dc0: 542c 646f 7562 6c65 2667 743b 3a3a 7661 T,double>::va\n+00003dd0: 6c75 6529 207c 7c20 2873 7464 3a3a 6973 lue) || (std::is\n+00003de0: 5f73 616d 6526 6c74 3b54 2c73 7464 3a3a _same<T,std::\n+00003df0: 636f 6d70 6c65 7826 6c74 3b64 6f75 626c complex<doubl\n+00003e00: 6526 6774 3b20 2667 743b 3a3a 7661 6c75 e> >::valu\n+00003e10: 6529 2c3c 2f64 6976 3e0a 3c64 6976 2063 e),
    .
    117 \n+00003e70: 2020 2020 2020 2020 2020 2020 2020 2020 \n+00003e80: 2020 3c73 7061 6e20 636c 6173 733d 2273 &q\n+00003ea0: 756f 743b 556e 7375 7070 6f72 7465 6420 uot;Unsupported \n+00003eb0: 5479 7065 2069 6e20 5350 5152 2028 6f6e Type in SPQR (on\n+00003ec0: 6c79 2064 6f75 626c 6520 616e 6420 7374 ly double and st\n+00003ed0: 643a 3a63 6f6d 706c 6578 266c 743b 646f d::complex<do\n+00003ee0: 7562 6c65 2667 743b 2073 7570 706f 7274 uble> support\n+00003ef0: 6564 2926 7175 6f74 3b3c 2f73 7061 6e3e ed)"\n+00003f00: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
    .
    118 \n+00003f60: 2020 2063 635f 203d 203c 7370 616e 2063 cc_ = n\n+00003f80: 6577 3c2f 7370 616e 3e20 6368 6f6c 6d6f ew cholmo\n+00003f90: 645f 636f 6d6d 6f6e 2829 3b3c 2f64 6976 d_common();.
    119<\n+00003ff0: 2f73 7061 6e3e 2020 2020 2020 6368 6f6c /span> chol\n+00004000: 6d6f 645f 6c5f 7374 6172 7428 6363 5f29 mod_l_start(cc_)\n+00004010: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+00004060: 2020 3132 303c 2f73 7061 6e3e 2020 2020 120 \n+00004070: 2020 7365 744d 6174 7269 7828 6d61 7472 setMatrix(matr\n+00004080: 6978 293b 3c2f 6469 763e 0a3c 6469 7620 ix);
    .
    121 \n+000040e0: 2020 207d 3c2f 6469 763e 0a3c 6469 7620 }
    .
    122 \n+00004140: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n+00004190: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+000041a0: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n+000041b0: 2367 6162 3962 6664 6435 3531 3334 3765 #gab9bfdd551347e\n+000041c0: 6336 3064 6432 3265 6461 3533 3532 3933 c60dd22eda535293\n+000041d0: 6536 3322 3e20 2031 3332 3c2f 613e 3c2f e63\"> 132 SPQR<\n+00004240: 2f61 3e28 3c73 7061 6e20 636c 6173 733d /a>(const<\n+00004260: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> Matrix&am\n+000042a0: 703b 206d 6174 7269 782c 203c 7370 616e p; matrix, const Pa\n+000042d0: 7261 6d65 7465 7254 7265 6526 616d 703b rameterTree&\n+000042e0: 2063 6f6e 6669 6729 3c2f 6469 763e 0a3c config)
    .<\n+000042f0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00004300: 3e3c 6120 6964 3d22 6c30 3031 3333 2220 > 133 : SPQR(\n+00004380: 6d61 7472 6978 2c20 636f 6e66 6967 2e3c matrix, config.<\n+00004390: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+000043a0: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n+000043b0: 2261 3030 3234 392e 6874 6d6c 2361 3334 \"a00249.html#a34\n+000043c0: 6637 3563 3538 6536 3536 3832 3362 3538 f75c58e656823b58\n+000043d0: 6533 6166 3137 6330 3966 6230 3365 223e e3af17c09fb03e\">\n+000043e0: 6765 743c 2f61 3e26 6c74 3b69 6e74 2667 get<int&g\n+000043f0: 743b 283c 7370 616e 2063 6c61 7373 3d22 t;(&\n+00004410: 7175 6f74 3b76 6572 626f 7365 2671 756f quot;verbose&quo\n+00004420: 743b 3c2f 7370 616e 3e2c 2030 2929 3c2f t;, 0)).
    1\n+00004480: 3334 3c2f 7370 616e 3e20 2020 207b 7d3c 34 {}<\n+00004490: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000044e0: 3133 353c 2f73 7061 6e3e 203c 2f64 6976 135 .
    \n+00004580: 2020 3133 373c 2f61 3e3c 2f73 7061 6e3e 137\n+00004590: 2020 2020 3c61 2063 6c61 7373 3d22 636f SPQR()\n+000045f0: 203a 206d 6174 7269 7849 734c 6f61 6465 : matrixIsLoade\n+00004600: 645f 2866 616c 7365 292c 2076 6572 626f d_(false), verbo\n+00004610: 7365 5f28 3029 3c2f 6469 763e 0a3c 6469 se_(0)
    .<\n+00004630: 6120 6964 3d22 6c30 3031 3338 2220 6e61 a id=\"l00138\" na\n+00004640: 6d65 3d22 6c30 3031 3338 223e 3c2f 613e me=\"l00138\">\n+00004650: 3c73 7061 6e20 636c 6173 733d 226c 696e 138 {
    .<\n+00004690: 6120 6964 3d22 6c30 3031 3339 2220 6e61 a id=\"l00139\" na\n+000046a0: 6d65 3d22 6c30 3031 3339 223e 3c2f 613e me=\"l00139\">\n+000046b0: 3c73 7061 6e20 636c 6173 733d 226c 696e 139 //c\n+000046f0: 6865 636b 2077 6865 7468 6572 2054 2069 heck whether T i\n+00004700: 7320 6120 7375 7070 6f72 7465 6420 7479 s a supported ty\n+00004710: 7065 3c2f 7370 616e 3e3c 2f64 6976 3e0a pe
    .\n+00004720: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+00004810: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00004900: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00004910: 3e3c 6120 6964 3d22 6c30 3031 3432 2220 > 142 cc_ = <\n+00004960: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00004970: 6f72 6422 3e6e 6577 3c2f 7370 616e 3e20 ord\">new \n+00004980: 6368 6f6c 6d6f 645f 636f 6d6d 6f6e 2829 cholmod_common()\n+00004990: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+000049e0: 2020 3134 333c 2f73 7061 6e3e 2020 2020 143 \n+000049f0: 2020 6368 6f6c 6d6f 645f 6c5f 7374 6172 cholmod_l_star\n+00004a00: 7428 6363 5f29 3b3c 2f64 6976 3e0a 3c64 t(cc_);
    .\n+00004a20: 3c61 2069 643d 226c 3030 3134 3422 206e 144 }
    .\n+00004a80: 3c61 2069 643d 226c 3030 3134 3522 206e 145
    .
    147 virtual\n+00004b90: 203c 6120 636c 6173 733d 2263 6f64 6520 ~SPQR().
    1\n+00004c40: 3438 3c2f 7370 616e 3e20 2020 207b 3c2f 48 {.
    1\n+00004ca0: 3439 3c2f 7370 616e 3e20 2020 2020 203c 49 <\n+00004cb0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00004cc0: 6f72 6466 6c6f 7722 3e69 663c 2f73 7061 ordflow\">if ((spqrMatrix_\n+00004ce0: 2e4e 2829 202b 2073 7071 724d 6174 7269 .N() + spqrMatri\n+00004cf0: 785f 2e4d 2829 2026 6774 3b20 3029 207c x_.M() > 0) |\n+00004d00: 7c20 6d61 7472 6978 4973 4c6f 6164 6564 | matrixIsLoaded\n+00004d10: 5f29 3c2f 6469 763e 0a3c 6469 7620 636c _)
    .
    150 \n+00004d70: 2020 2020 2066 7265 6528 293b 3c2f 6469 free();.
    151\n+00004dd0: 3c2f 7370 616e 3e20 2020 2020 2063 686f cho\n+00004de0: 6c6d 6f64 5f6c 5f66 696e 6973 6828 6363 lmod_l_finish(cc\n+00004df0: 5f29 3b3c 2f64 6976 3e0a 3c64 6976 2063 _);
    .
    152 \n+00004e50: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
    .
    153 <\n+00004eb0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    155 vi\n+00004f70: 7274 7561 6c3c 2f73 7061 6e3e 203c 7370 rtual void apply(<\n+00005000: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00005010: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n+00005020: 3132 3434 2e68 746d 6c22 3e64 6f6d 6169 1244.html\">domai\n+00005030: 6e5f 7479 7065 3c2f 613e 2661 6d70 3b20 n_type& \n+00005040: 782c 203c 6120 636c 6173 733d 2263 6f64 x, r\n+00005070: 616e 6765 5f74 7970 653c 2f61 3e26 616d ange_type&am\n+00005080: 703b 2062 2c20 3c61 2063 6c61 7373 3d22 p; b, InverseOperat\n+000050c0: 6f72 5265 7375 6c74 3c2f 613e 2661 6d70 orResult&\n+000050d0: 3b20 7265 7329 3c2f 6469 763e 0a3c 6469 ; res)
    .<\n+000050f0: 6120 6964 3d22 6c30 3031 3536 2220 6e61 a id=\"l00156\" na\n+00005100: 6d65 3d22 6c30 3031 3536 223e 3c2f 613e me=\"l00156\">\n+00005110: 3c73 7061 6e20 636c 6173 733d 226c 696e 156 {
    .<\n+00005150: 6120 6964 3d22 6c30 3031 3537 2220 6e61 a id=\"l00157\" na\n+00005160: 6d65 3d22 6c30 3031 3537 223e 3c2f 613e me=\"l00157\">\n+00005170: 3c73 7061 6e20 636c 6173 733d 226c 696e 157 con\n+000051b0: 7374 3c2f 7370 616e 3e20 7374 643a 3a73 st std::s\n+000051c0: 697a 655f 7420 6e75 6d52 6f77 7328 7370 ize_t numRows(sp\n+000051d0: 7172 4d61 7472 6978 5f2e 4e28 2929 3b3c qrMatrix_.N());<\n+000051e0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00005230: 3135 383c 2f73 7061 6e3e 2020 2020 2020 158 \n+00005240: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // fill B<\n+00005260: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
    .<\n+00005280: 6120 6964 3d22 6c30 3031 3539 2220 6e61 a id=\"l00159\" na\n+00005290: 6d65 3d22 6c30 3031 3539 223e 3c2f 613e me=\"l00159\">\n+000052a0: 3c73 7061 6e20 636c 6173 733d 226c 696e 159 for(std:\n+000052f0: 3a73 697a 655f 7420 6b20 3d20 303b 206b :size_t k = 0; k\n+00005300: 2021 3d20 6e75 6d52 6f77 732f 6e3b 202b != numRows/n; +\n+00005310: 2b6b 293c 2f64 6976 3e0a 3c64 6976 2063 +k)
    .
    160 \n+00005370: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+00005390: 666f 723c 2f73 7061 6e3e 2028 3c73 7061 for (int\n+000053c0: 206c 203d 2030 3b20 6c20 266c 743b 206e l = 0; l < n\n+000053d0: 3b20 2b2b 6c29 3c2f 6469 763e 0a3c 6469 ; ++l)
    .<\n+000053f0: 6120 6964 3d22 6c30 3031 3631 2220 6e61 a id=\"l00161\" na\n+00005400: 6d65 3d22 6c30 3031 3631 223e 3c2f 613e me=\"l00161\">\n+00005410: 3c73 7061 6e20 636c 6173 733d 226c 696e 161 (static_cast<\n+00005460: 3b3c 2f73 7061 6e3e 542a 3c73 7061 6e20 ;T*\n+00005480: 2667 743b 3c2f 7370 616e 3e28 425f 2d26 >(B_-&\n+00005490: 6774 3b78 2929 5b6e 2a6b 2b6c 5d20 3d20 gt;x))[n*k+l] = \n+000054a0: 625b 6b5d 5b6c 5d3b 3c2f 6469 763e 0a3c b[k][l];
    .<\n+000054b0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+000054c0: 3e3c 6120 6964 3d22 6c30 3031 3632 2220 > 162
    .
    163 \n+00005560: 2020 2020 2063 686f 6c6d 6f64 5f64 656e cholmod_den\n+00005570: 7365 2a20 4254 656d 7020 3d20 425f 3b3c se* BTemp = B_;<\n+00005580: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000055d0: 3136 343c 2f73 7061 6e3e 2020 2020 2020 164 \n+000055e0: 425f 203d 2053 7569 7465 5370 6172 7365 B_ = SuiteSparse\n+000055f0: 5152 5f71 6d75 6c74 266c 743b 5426 6774 QR_qmult<T>\n+00005600: 3b28 302c 2073 7071 7266 6163 746f 7269 ;(0, spqrfactori\n+00005610: 7a61 7469 6f6e 5f2c 2042 5f2c 2063 635f zation_, B_, cc_\n+00005620: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
    .
    165 \n+00005680: 2020 2063 686f 6c6d 6f64 5f64 656e 7365 cholmod_dense\n+00005690: 2a20 5820 3d20 5375 6974 6553 7061 7273 * X = SuiteSpars\n+000056a0: 6551 525f 736f 6c76 6526 6c74 3b54 2667 eQR_solve<T&g\n+000056b0: 743b 2831 2c20 7370 7172 6661 6374 6f72 t;(1, spqrfactor\n+000056c0: 697a 6174 696f 6e5f 2c20 425f 2c20 6363 ization_, B_, cc\n+000056d0: 5f29 3b3c 2f64 6976 3e0a 3c64 6976 2063 _);
    .
    166 \n+00005730: 2020 2020 6368 6f6c 6d6f 645f 6c5f 6672 cholmod_l_fr\n+00005740: 6565 5f64 656e 7365 2826 616d 703b 4254 ee_dense(&BT\n+00005750: 656d 702c 2063 635f 293b 3c2f 6469 763e emp, cc_);
    \n+00005760: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n+000057d0: 6120 6964 3d22 6c30 3031 3638 2220 6e61 a id=\"l00168\" na\n+000057e0: 6d65 3d22 6c30 3031 3638 223e 3c2f 613e me=\"l00168\">\n+000057f0: 3c73 7061 6e20 636c 6173 733d 226c 696e 168 con\n+00005830: 7374 3c2f 7370 616e 3e20 7374 643a 3a73 st std::s\n+00005840: 697a 655f 7420 6e75 6d43 6f6c 7328 7370 ize_t numCols(sp\n+00005850: 7172 4d61 7472 6978 5f2e 4d28 2929 3b3c qrMatrix_.M());<\n+00005860: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000058b0: 3136 393c 2f73 7061 6e3e 2020 2020 2020 169 \n+000058c0: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // fill x<\n+000058e0: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
    .<\n+00005900: 6120 6964 3d22 6c30 3031 3730 2220 6e61 a id=\"l00170\" na\n+00005910: 6d65 3d22 6c30 3031 3730 223e 3c2f 613e me=\"l00170\">\n+00005920: 3c73 7061 6e20 636c 6173 733d 226c 696e 170 for(std:\n+00005970: 3a73 697a 655f 7420 6b20 3d20 303b 206b :size_t k = 0; k\n+00005980: 2021 3d20 6e75 6d43 6f6c 732f 6d3b 202b != numCols/m; +\n+00005990: 2b6b 293c 2f64 6976 3e0a 3c64 6976 2063 +k)
    .
    171 \n+000059f0: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+00005a10: 666f 723c 2f73 7061 6e3e 2028 3c73 7061 for (int\n+00005a40: 206c 203d 2030 3b20 6c20 266c 743b 206d l = 0; l < m\n+00005a50: 3b20 2b2b 6c29 3c2f 6469 763e 0a3c 6469 ; ++l)
    .<\n+00005a70: 6120 6964 3d22 6c30 3031 3732 2220 6e61 a id=\"l00172\" na\n+00005a80: 6d65 3d22 6c30 3031 3732 223e 3c2f 613e me=\"l00172\">\n+00005a90: 3c73 7061 6e20 636c 6173 733d 226c 696e 172 x[k][\n+00005ac0: 6c5d 203d 2028 3c73 7061 6e20 636c 6173 l] = (stat\n+00005ae0: 6963 5f63 6173 7426 6c74 3b3c 2f73 7061 ic_cast<T*>(X->x))[\n+00005b20: 6d2a 6b2b 6c5d 3b3c 2f64 6976 3e0a 3c64 m*k+l];
    .\n+00005b40: 3c61 2069 643d 226c 3030 3137 3322 206e 173
    .
    174 \n+00005be0: 2020 2020 6368 6f6c 6d6f 645f 6c5f 6672 cholmod_l_fr\n+00005bf0: 6565 5f64 656e 7365 2826 616d 703b 582c ee_dense(&X,\n+00005c00: 2063 635f 293b 3c2f 6469 763e 0a3c 6469 cc_);
    .<\n+00005c20: 6120 6964 3d22 6c30 3031 3735 2220 6e61 a id=\"l00175\" na\n+00005c30: 6d65 3d22 6c30 3031 3735 223e 3c2f 613e me=\"l00175\">\n+00005c40: 3c73 7061 6e20 636c 6173 733d 226c 696e 175 // \n+00005c80: 7468 6973 2069 7320 6120 6469 7265 6374 this is a direct\n+00005c90: 2073 6f6c 7665 723c 2f73 7061 6e3e 3c2f solver.
    1\n+00005cf0: 3736 3c2f 7370 616e 3e20 2020 2020 2072 76 r\n+00005d00: 6573 2e3c 6120 636c 6173 733d 2263 6f64 es.iterations = 1;
    .\n+00005d80: 3c61 2069 643d 226c 3030 3137 3722 206e 177 res.con\n+00005e20: 7665 7267 6564 3c2f 613e 203d 203c 7370 verged = true
    ;<\n+00005e50: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00005ea0: 3137 383c 2f73 7061 6e3e 2020 2020 2020 178 \n+00005eb0: 3c73 7061 6e20 636c 6173 733d 226b 6579 if(verbose_ >\n+00005ee0: 3b20 3029 3c2f 6469 763e 0a3c 6469 7620 ; 0)
    .
    179 \n+00005f40: 2020 2020 207b 3c2f 6469 763e 0a3c 6469 {
    .<\n+00005f60: 6120 6964 3d22 6c30 3031 3830 2220 6e61 a id=\"l00180\" na\n+00005f70: 6d65 3d22 6c30 3031 3830 223e 3c2f 613e me=\"l00180\">\n+00005f80: 3c73 7061 6e20 636c 6173 733d 226c 696e 180 std::co\n+00005fb0: 7574 266c 743b 266c 743b 7374 643a 3a65 ut<<std::e\n+00005fc0: 6e64 6c26 6c74 3b26 6c74 3b3c 7370 616e ndl<<"Sol\n+00005ff0: 7669 6e67 2077 6974 6820 5375 6974 6553 ving with SuiteS\n+00006000: 7061 7273 6551 5226 7175 6f74 3b3c 2f73 parseQR"<<std:\n+00006020: 3a65 6e64 6c3b 3c2f 6469 763e 0a3c 6469 :endl;
    .<\n+00006040: 6120 6964 3d22 6c30 3031 3831 2220 6e61 a id=\"l00181\" na\n+00006050: 6d65 3d22 6c30 3031 3831 223e 3c2f 613e me=\"l00181\">\n+00006060: 3c73 7061 6e20 636c 6173 733d 226c 696e 181 std::co\n+00006090: 7574 266c 743b 266c 743b 3c73 7061 6e20 ut<<"Flop\n+000060c0: 7320 5461 6b65 6e3a 2026 7175 6f74 3b3c s Taken: "<\n+000060d0: 2f73 7061 6e3e 266c 743b 266c 743b 6363 /span><<cc\n+000060e0: 5f2d 2667 743b 5350 5152 5f66 6c6f 7063 _->SPQR_flopc\n+000060f0: 6f75 6e74 266c 743b 266c 743b 7374 643a ount<<std:\n+00006100: 3a65 6e64 6c3b 3c2f 6469 763e 0a3c 6469 :endl;
    .<\n+00006120: 6120 6964 3d22 6c30 3031 3832 2220 6e61 a id=\"l00182\" na\n+00006130: 6d65 3d22 6c30 3031 3832 223e 3c2f 613e me=\"l00182\">\n+00006140: 3c73 7061 6e20 636c 6173 733d 226c 696e 182 std::co\n+00006170: 7574 266c 743b 266c 743b 3c73 7061 6e20 ut<<"Anal\n+000061a0: 7973 6973 2054 696d 653a 2026 7175 6f74 ysis Time: "\n+000061b0: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n+000061c0: 6363 5f2d 2667 743b 5350 5152 5f61 6e61 cc_->SPQR_ana\n+000061d0: 6c79 7a65 5f74 696d 6526 6c74 3b26 6c74 lyze_time<<\n+000061e0: 3b3c 7370 616e 2063 6c61 7373 3d22 7374 ;&qu\n+00006200: 6f74 3b20 7326 7175 6f74 3b3c 2f73 7061 ot; s"<<std::e\n+00006220: 6e64 6c3b 3c2f 6469 763e 0a3c 6469 7620 ndl;
    .
    183 \n+00006280: 2020 2020 2020 2073 7464 3a3a 636f 7574 std::cout\n+00006290: 266c 743b 266c 743b 3c73 7061 6e20 636c <<"Factor\n+000062c0: 697a 6520 5469 6d65 3a20 2671 756f 743b ize Time: "\n+000062d0: 3c2f 7370 616e 3e26 6c74 3b26 6c74 3b63 <<c\n+000062e0: 635f 2d26 6774 3b53 5051 525f 6661 6374 c_->SPQR_fact\n+000062f0: 6f72 697a 655f 7469 6d65 266c 743b 266c orize_time<&l\n+00006300: 743b 3c73 7061 6e20 636c 6173 733d 2273 t;&q\n+00006320: 756f 743b 2073 2671 756f 743b 3c2f 7370 uot; s"<<std::\n+00006340: 656e 646c 3b3c 2f64 6976 3e0a 3c64 6976 endl;
    .<\n+00006380: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00006390: 6e6f 223e 2020 3138 343c 2f73 7061 6e3e no\"> 184\n+000063a0: 2020 2020 2020 2020 7374 643a 3a63 6f75 std::cou\n+000063b0: 7426 6c74 3b26 6c74 3b3c 7370 616e 2063 t<<"Backs\n+000063e0: 6f6c 7665 2054 696d 653a 2026 7175 6f74 olve Time: "\n+000063f0: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n+00006400: 6363 5f2d 2667 743b 5350 5152 5f73 6f6c cc_->SPQR_sol\n+00006410: 7665 5f74 696d 6526 6c74 3b26 6c74 3b3c ve_time<<<\n+00006420: 7370 616e 2063 6c61 7373 3d22 7374 7269 span class=\"stri\n+00006430: 6e67 6c69 7465 7261 6c22 3e26 7175 6f74 ngliteral\">"\n+00006440: 3b20 7326 7175 6f74 3b3c 2f73 7061 6e3e ; s"\n+00006450: 266c 743b 266c 743b 7374 643a 3a65 6e64 <<std::end\n+00006460: 6c3b 3c2f 6469 763e 0a3c 6469 7620 636c l;.
    185 \n+000064c0: 2020 2020 2073 7464 3a3a 636f 7574 266c std::cout&l\n+000064d0: 743b 266c 743b 3c73 7061 6e20 636c 6173 t;<"Peak Mem\n+00006500: 6f72 7920 5573 6167 653a 2026 7175 6f74 ory Usage: "\n+00006510: 3b3c 2f73 7061 6e3e 266c 743b 266c 743b ;<<\n+00006520: 6363 5f2d 2667 743b 6d65 6d6f 7279 5f75 cc_->memory_u\n+00006530: 7361 6765 266c 743b 266c 743b 3c73 7061 sage<<" b\n+00006560: 7974 6573 2671 756f 743b 3c2f 7370 616e ytes"<<std::en\n+00006580: 646c 3b3c 2f64 6976 3e0a 3c64 6976 2063 dl;
    .
    186 \n+000065e0: 2020 2020 2020 7374 643a 3a63 6f75 7426 std::cout&\n+000065f0: 6c74 3b26 6c74 3b3c 7370 616e 2063 6c61 lt;<"Rank Es\n+00006620: 7469 6d61 7465 3a20 2671 756f 743b 3c2f timate: "<<cc_\n+00006640: 2d26 6774 3b53 5051 525f 6973 7461 745b ->SPQR_istat[\n+00006650: 345d 266c 743b 266c 743b 7374 643a 3a65 4]<<std::e\n+00006660: 6e64 6c26 6c74 3b26 6c74 3b73 7464 3a3a ndl<<std::\n+00006670: 656e 646c 3b3c 2f64 6976 3e0a 3c64 6976 endl;
    .<\n+000066b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+000066c0: 6e6f 223e 2020 3138 373c 2f73 7061 6e3e no\"> 187\n+000066d0: 2020 2020 2020 7d3c 2f64 6976 3e0a 3c64 }.\n+000066f0: 3c61 2069 643d 226c 3030 3138 3822 206e 188 }.\n+00006750: 3c61 2069 643d 226c 3030 3138 3922 206e 189 .
    191 virtual\n+00006860: 203c 7370 616e 2063 6c61 7373 3d22 6b65 void<\n+00006880: 2f73 7061 6e3e 203c 6120 636c 6173 733d /span> apply (\n+00006910: 646f 6d61 696e 5f74 7970 653c 2f61 3e26 domain_type&\n+00006920: 616d 703b 2078 2c20 3c61 2063 6c61 7373 amp; x, range_type& b, [[may\n+00006970: 6265 5f75 6e75 7365 645d 5d20 3c73 7061 be_unused]] double reduction, <\n+000069b0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+000069c0: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n+000069d0: 3032 3730 302e 6874 6d6c 223e 496e 7665 02700.html\">Inve\n+000069e0: 7273 654f 7065 7261 746f 7252 6573 756c rseOperatorResul\n+000069f0: 743c 2f61 3e26 616d 703b 2072 6573 293c t& res)<\n+00006a00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00006a50: 3139 323c 2f73 7061 6e3e 2020 2020 7b3c 192 {<\n+00006a60: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00006ab0: 3139 333c 2f73 7061 6e3e 2020 2020 2020 193 \n+00006ac0: 6170 706c 7928 782c 2062 2c20 7265 7329 apply(x, b, res)\n+00006ad0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+00006b20: 2020 3139 343c 2f73 7061 6e3e 2020 2020 194 \n+00006b30: 7d3c 2f64 6976 3e0a 3c64 6976 2063 6c61 }
    .
    \n-00006b80: 2020 3135 333c 2f73 7061 6e3e 203c 2f64 153 .
    15\n-00006be0: 343c 2f73 7061 6e3e 2020 3c73 7061 6e20 4 \n-00006c00: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-00006c10: 6c74 3b26 6774 3b3c 2f64 6976 3e0a 3c64 lt;>
    .\n-00006c30: 3c61 2069 643d 226c 3030 3135 3522 206e 155 struct <\n-00006cc0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00006cd0: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n-00006ce0: 3032 3931 322e 6874 6d6c 223e 4765 7453 02912.html\">GetS\n-00006cf0: 7570 6572 4c55 5479 7065 3c2f 613e 266c uperLUType&l\n-00006d00: 743b 3c61 2063 6c61 7373 3d22 636f 6465 t;std::compl\n-00006d40: 6578 266c 743b 646f 7562 6c65 2667 743b ex<double>\n-00006d50: 2026 6774 3b3c 2f64 6976 3e0a 3c64 6976 >
    .<\n-00006d90: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00006da0: 6e6f 223e 2020 3135 363c 2f73 7061 6e3e no\"> 156\n-00006db0: 2020 2020 3a20 3c73 7061 6e20 636c 6173 : publ\n-00006dd0: 6963 3c2f 7370 616e 3e20 3c61 2063 6c61 ic BaseGetSu\n-00006e10: 7065 724c 5554 7970 653c 2f61 3e26 6c74 perLUType<\n-00006e20: 3b73 7464 3a3a 636f 6d70 6c65 7826 6c74 ;std::complex<\n-00006e30: 3b64 6f75 626c 6526 6774 3b20 2667 743b ;double> >\n-00006e40: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00006e90: 2031 3537 3c2f 7370 616e 3e20 207b 3c2f 157 {.
    158 type\n-00006f60: 6465 663c 2f73 7061 6e3e 203c 7370 616e def double float_type;
    .
    159 }\n-00007050: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-000070a0: 2020 3136 303c 2f73 7061 6e3e 203c 2f64 160 .
    16\n-00007100: 313c 2f73 7061 6e3e 2020 3c73 7061 6e20 1 \n-00007120: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n-00007130: 6c74 3b26 6774 3b3c 2f64 6976 3e0a 3c64 lt;>
    .\n-00007150: 3c61 2069 643d 226c 3030 3136 3222 206e 162 struct <\n-000071e0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-000071f0: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n-00007200: 3032 3931 322e 6874 6d6c 223e 4765 7453 02912.html\">GetS\n-00007210: 7570 6572 4c55 5479 7065 3c2f 613e 266c uperLUType&l\n-00007220: 743b 3c61 2063 6c61 7373 3d22 636f 6465 t;std::compl\n-00007260: 6578 266c 743b 666c 6f61 7426 6774 3b20 ex<float> \n-00007270: 2667 743b 3c2f 6469 763e 0a3c 6469 7620 >
    .
    163 \n-000072d0: 2020 203a 203c 7370 616e 2063 6c61 7373 : publi\n-000072f0: 633c 2f73 7061 6e3e 203c 6120 636c 6173 c BaseGetSup\n-00007330: 6572 4c55 5479 7065 3c2f 613e 266c 743b erLUType<\n-00007340: 7374 643a 3a63 6f6d 706c 6578 266c 743b std::complex<\n-00007350: 666c 6f61 7426 6774 3b20 2667 743b 3c2f float> >.
    1\n-000073b0: 3634 3c2f 7370 616e 3e20 207b 3c2f 6469 64 {.
    \n-00007450: 2020 3136 353c 2f61 3e3c 2f73 7061 6e3e 165\n-00007460: 2020 2020 3c73 7061 6e20 636c 6173 733d typede\n-00007480: 663c 2f73 7061 6e3e 203c 7370 616e 2063 f float \n-000074b0: 3c61 2063 6c61 7373 3d22 636f 6465 2068 \n-00007500: 666c 6f61 745f 7479 7065 3c2f 613e 3b3c float_type;<\n-00007510: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00007560: 3136 363c 2f73 7061 6e3e 203c 2f64 6976 166 .
    167<\n-000075c0: 2f73 7061 6e3e 2020 7d3b 3c2f 6469 763e /span> };
    \n-000075d0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00007640: 6120 6964 3d22 6c30 3031 3733 2220 6e61 a id=\"l00173\" na\n-00007650: 6d65 3d22 6c30 3031 3733 223e 3c2f 613e me=\"l00173\">\n-00007660: 3c73 7061 6e20 636c 6173 733d 226c 696e 173 templat\n-000076a0: 653c 2f73 7061 6e3e 266c 743b 3c73 7061 e<class M\n-000076d0: 2667 743b 3c2f 6469 763e 0a3c 6469 7620 >
    .
    174<\n-00007750: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> st\n-00007770: 7275 6374 203c 2f73 7061 6e3e 3c61 2063 ruct SuperLU\n-000077b0: 4d61 7472 6978 3c2f 613e 3c2f 6469 763e Matrix
    \n-000077c0: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-00007820: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00007890: 6120 6964 3d22 6c30 3031 3737 2220 6e61 a id=\"l00177\" na\n-000078a0: 6d65 3d22 6c30 3031 3737 223e 3c2f 613e me=\"l00177\">\n-000078b0: 3c73 7061 6e20 636c 6173 733d 226c 696e 177 templat\n-000078f0: 653c 2f73 7061 6e3e 266c 743b 3c73 7061 e<class M\n-00007920: 2667 743b 3c2f 6469 763e 0a3c 6469 7620 >
    .
    178<\n-000079a0: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> st\n-000079c0: 7275 6374 203c 2f73 7061 6e3e 3c61 2063 ruct SuperMa\n-00007a00: 7472 6978 496e 6974 6961 6c69 7a65 723c trixInitializer<\n-00007a10: 2f61 3e3c 2f64 6976 3e0a 3c64 6976 2063 /a>
    .
    179 \n-00007a70: 7b7d 3b3c 2f64 6976 3e0a 3c64 6976 2063 {};
    .
    180 <\n-00007ad0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00007b20: 3138 313c 2f73 7061 6e3e 2020 3c73 7061 181 template<class\n-00007b70: 3c2f 7370 616e 3e20 5426 6774 3b3c 2f64 T>.
    18\n-00007bd0: 323c 2f73 7061 6e3e 2020 3c73 7061 6e20 2 \n-00007bf0: 636c 6173 7320 3c2f 7370 616e 3e3c 6120 class SuperLU\n-00007c30: 3c2f 613e 3b3c 2f64 6976 3e0a 3c64 6976 ;
    .<\n-00007c70: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00007c80: 6e6f 223e 2020 3138 333c 2f73 7061 6e3e no\"> 183\n-00007c90: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
    .
    \n-00007ce0: 2020 3138 343c 2f73 7061 6e3e 2020 3c73 184 template<cla\n-00007d30: 7373 3c2f 7370 616e 3e20 4d2c 203c 7370 ss M, class \n-00007d60: 582c 203c 7370 616e 2063 6c61 7373 3d22 X, class TM, \n-00007da0: 636c 6173 733c 2f73 7061 6e3e 2054 442c class TD,\n-00007db0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 class T1>
    \n-00007de0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00007e10: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 185 cla\n-00007e50: 7373 203c 2f73 7061 6e3e 3c61 2063 6c61 ss SeqOverlap\n-00007e90: 7069 6e67 5363 6877 6172 7a3c 2f61 3e3b pingSchwarz;\n-00007ea0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00007ef0: 2031 3836 3c2f 7370 616e 3e20 3c2f 6469 186 .
    187\n-00007f50: 3c2f 7370 616e 3e20 203c 7370 616e 2063 t\n-00007f70: 656d 706c 6174 653c 2f73 7061 6e3e 266c emplate&l\n-00007f80: 743b 3c73 7061 6e20 636c 6173 733d 226b t;class T, bool fl\n-00007fd0: 6167 2667 743b 3c2f 6469 763e 0a3c 6469 ag>
    .<\n-00007ff0: 6120 6964 3d22 6c30 3031 3838 2220 6e61 a id=\"l00188\" na\n-00008000: 6d65 3d22 6c30 3031 3838 223e 3c2f 613e me=\"l00188\">\n-00008010: 3c73 7061 6e20 636c 6173 733d 226c 696e 188 struct \n-00008050: 3c2f 7370 616e 3e3c 6120 636c 6173 733d SeqOverlappi\n-00008090: 6e67 5363 6877 6172 7a41 7373 656d 626c ngSchwarzAssembl\n-000080a0: 6572 4865 6c70 6572 3c2f 613e 3b3c 2f64 erHelper;.
    18\n-00008100: 393c 2f73 7061 6e3e 203c 2f64 6976 3e0a 9
    .\n-00008110: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n-00008140: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 193 temp\n-00008180: 6c61 7465 3c2f 7370 616e 3e26 6c74 3b3c late<<\n-00008190: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-000081a0: 6f72 6422 3e63 6c61 7373 3c2f 7370 616e ord\">class B, class\n-000081d0: 3c2f 7370 616e 3e20 5441 2667 743b 3c2f TA>..
    195 \n-00008370: 203a 203c 7370 616e 2063 6c61 7373 3d22 : public<\n-00008390: 2f73 7061 6e3e 2049 5354 4c3a 3a49 6d70 /span> ISTL::Imp\n-000083a0: 6c3a 3a42 4343 534d 6174 7269 7826 6c74 l::BCCSMatrix<\n-000083b0: 3b74 7970 656e 616d 6520 4243 5253 4d61 ;typename BCRSMa\n-000083c0: 7472 6978 266c 743b 422c 5441 2667 743b trix<B,TA>\n-000083d0: 3a3a 6669 656c 645f 7479 7065 2c20 696e ::field_type, in\n-000083e0: 7426 6774 3b3c 2f64 6976 3e0a 3c64 6976 t>
    .<\n-00008420: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-00008430: 6e6f 223e 2020 3139 363c 2f73 7061 6e3e no\"> 196\n-00008440: 2020 7b3c 2f64 6976 3e0a 3c64 6976 2063 {
    .
    197 \n-000084a0: 2020 3c73 7061 6e20 636c 6173 733d 226b template\n-000084c0: 3c2f 7370 616e 3e26 6c74 3b3c 7370 616e <class M,\n-000084f0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 class X, cla\n-00008530: 7373 3c2f 7370 616e 3e20 544d 2c20 3c73 ss TM, class\n-00008560: 2054 442c 203c 7370 616e 2063 6c61 7373 TD, class\n-00008580: 3c2f 7370 616e 3e20 5431 2667 743b 3c2f T1>.
    198 frie\n-00008650: 6e64 3c2f 7370 616e 3e20 3c73 7061 6e20 nd \n-00008670: 636c 6173 7320 3c2f 7370 616e 3e3c 6120 class SeqOver\n-000086b0: 6c61 7070 696e 6753 6368 7761 727a 3c2f lappingSchwarz;
    .
    199 \n-00008720: 2020 3c73 7061 6e20 636c 6173 733d 226b friend stru\n-00008760: 6374 203c 2f73 7061 6e3e 3c61 2063 6c61 ct SuperMatr\n-000087a0: 6978 496e 6974 6961 6c69 7a65 723c 2f61 ixInitializer<BCRSMatrix&\n-000087f0: 6c74 3b42 2c54 4126 6774 3b20 2667 743b lt;B,TA> >\n-00008800: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00008850: 2020 3230 303c 2f73 7061 6e3e 2020 3c73 200 public:
    .
    202<\n-00008920: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n-00008940: 7479 7065 6465 663c 2f73 7061 6e3e 203c typedef <\n-00008950: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-00008960: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n-00008970: 3131 3532 2e68 746d 6c22 3e42 4352 534d 1152.html\">BCRSM\n-00008980: 6174 7269 7826 6c74 3b42 2c54 4126 6774 atrix<B,TA>\n-00008990: 3b3c 2f61 3e20 3c61 2063 6c61 7373 3d22 ; Matrix\n-000089f0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-00008a40: 2020 3230 333c 2f73 7061 6e3e 203c 2f64 203 .
    20\n-00008aa0: 343c 2f73 7061 6e3e 2020 2020 3c73 7061 4 friend \n-00008ad0: 3c73 7061 6e20 636c 6173 733d 226b 6579 struct SeqOverlappingS\n-00008b30: 6368 7761 727a 4173 7365 6d62 6c65 7248 chwarzAssemblerH\n-00008b40: 656c 7065 723c 2f61 3e26 6c74 3b3c 6120 elper<SuperLU\n-00008b80: 3c2f 613e 266c 743b 3c61 2063 6c61 7373 <Matrix&g\n-00008bc0: 743b 2c20 7472 7565 2667 743b 3b3c 2f64 t;, true>;.
    20\n-00008c20: 353c 2f73 7061 6e3e 203c 2f64 6976 3e0a 5
    .\n-00008c30: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n-00008c60: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 2\n-00008cc0: 3036 3c2f 613e 3c2f 7370 616e 3e20 2020 06 \n-00008cd0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 typedef type\n-00008d10: 6e61 6d65 3c2f 7370 616e 3e20 3c61 2063 name Matr\n-00008d70: 6978 3a3a 7369 7a65 5f74 7970 653c 2f61 ix::size_type size_type;\n-00008de0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00008e30: 2032 3037 3c2f 7370 616e 3e20 3c2f 6469 207 .
    \n-00008ed0: 2020 3231 323c 2f61 3e3c 2f73 7061 6e3e 212\n-00008ee0: 2020 2020 3c73 7061 6e20 636c 6173 733d explic\n-00008f00: 6974 3c2f 7370 616e 3e20 3c61 2063 6c61 it Super\n-00008f60: 4c55 4d61 7472 6978 3c2f 613e 283c 7370 LUMatrix(const \n-00008f90: 3c61 2063 6c61 7373 3d22 636f 6465 2068 Matr\n-00008fc0: 6978 3c2f 613e 2661 6d70 3b20 3c61 2063 ix& ma\n-00009020: 743c 2f61 3e29 203a 2049 5354 4c3a 3a49 t) : ISTL::I\n-00009030: 6d70 6c3a 3a42 4343 534d 6174 7269 7826 mpl::BCCSMatrix&\n-00009040: 6c74 3b3c 6120 636c 6173 733d 2263 6f64 lt;B\n-00009070: 4352 534d 6174 7269 783c 2f61 3e26 6c74 CRSMatrix<\n-00009080: 3b42 2c54 4126 6774 3b2c 2069 6e74 2667 ;B,TA>, int&g\n-00009090: 743b 283c 6120 636c 6173 733d 2263 6f64 t;(mat).
    21\n-00009140: 333c 2f73 7061 6e3e 2020 2020 7b7d 3c2f 3 {}.
    2\n-000091a0: 3134 3c2f 7370 616e 3e20 3c2f 6469 763e 14
    \n-000091b0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-000091e0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d \n-00009240: 3231 353c 2f61 3e3c 2f73 7061 6e3e 2020 215 \n-00009250: 2020 3c61 2063 6c61 7373 3d22 636f 6465 SuperLUMatrix\n-000092b0: 3c2f 613e 2829 203a 2049 5354 4c3a 3a49 () : ISTL::I\n-000092c0: 6d70 6c3a 3a42 4343 534d 6174 7269 7826 mpl::BCCSMatrix&\n-000092d0: 6c74 3b74 7970 656e 616d 6520 3c61 2063 lt;typename BCRSMatr\n-00009310: 6978 3c2f 613e 266c 743b 422c 5441 2667 ix<B,TA&g\n-00009320: 743b 3a3a 6669 656c 645f 7479 7065 2c20 t;::field_type, \n-00009330: 696e 7426 6774 3b28 293c 2f64 6976 3e0a int>()
    .\n-00009340: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 \n-000093a0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00009410: 6120 6964 3d22 6c30 3032 3139 2220 6e61 a id=\"l00219\" na\n-00009420: 6d65 3d22 6c30 3032 3139 223e 3c2f 613e me=\"l00219\">\n-00009430: 3c73 7061 6e20 636c 6173 733d 226c 696e 219<\n-00009490: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c73 /a> virtual ~SuperLUMatr\n-00009520: 6978 3c2f 613e 2829 3c2f 6469 763e 0a3c ix()
    .<\n-00009530: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00009540: 3e3c 6120 6964 3d22 6c30 3032 3230 2220 > 220 {
    .<\n-00009590: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-000095a0: 3e3c 6120 6964 3d22 6c30 3032 3231 2220 > 221 if (th\n-00009610: 6973 2d26 6774 3b4e 5f2b 7468 6973 2d26 is->N_+this-&\n-00009620: 6774 3b4d 5f2a 7468 6973 2d26 6774 3b4e gt;M_*this->N\n-00009630: 6e7a 5f20 213d 2030 293c 2f64 6976 3e0a nz_ != 0)
    .\n-00009640: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    223 \n-00009700: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
    .
    224 <\n-00009760: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    226 ope\n-00009820: 7261 746f 723c 2f73 7061 6e3e 2053 7570 rator Sup\n-00009830: 6572 4d61 7472 6978 2661 6d70 3b28 293c erMatrix&()<\n-00009840: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00009890: 3232 373c 2f73 7061 6e3e 2020 2020 7b3c 227 {<\n-000098a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-000098f0: 3232 383c 2f73 7061 6e3e 2020 2020 2020 228 \n-00009900: 3c73 7061 6e20 636c 6173 733d 226b 6579 return\n-00009920: 3c2f 7370 616e 3e20 413b 3c2f 6469 763e A;
    \n-00009930: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-00009990: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-00009a00: 6120 6964 3d22 6c30 3032 3332 2220 6e61 a id=\"l00232\" na\n-00009a10: 6d65 3d22 6c30 3032 3332 223e 3c2f 613e me=\"l00232\">\n-00009a20: 3c73 7061 6e20 636c 6173 733d 226c 696e 232<\n-00009a80: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c73 /a> operator const<\n-00009ad0: 2f73 7061 6e3e 2053 7570 6572 4d61 7472 /span> SuperMatr\n-00009ae0: 6978 2661 6d70 3b28 2920 3c73 7061 6e20 ix&() \n-00009b00: 636f 6e73 743c 2f73 7061 6e3e 3c2f 6469 const.
    233\n-00009b60: 3c2f 7370 616e 3e20 2020 207b 3c2f 6469 {.
    234\n-00009bc0: 3c2f 7370 616e 3e20 2020 2020 203c 7370 return A;
    .\n-00009c10: 3c61 2069 643d 226c 3030 3233 3522 206e 235 }
    .\n-00009c70: 3c61 2069 643d 226c 3030 3233 3622 206e 236
    ..<\n-00009f00: 6120 6964 3d22 6c30 3032 3338 2220 6e61 a id=\"l00238\" na\n-00009f10: 6d65 3d22 6c30 3032 3338 223e 3c2f 613e me=\"l00238\">\n-00009f20: 3c73 7061 6e20 636c 6173 733d 226c 696e 238 {
    .<\n-00009f60: 6120 6964 3d22 6c30 3032 3339 2220 6e61 a id=\"l00239\" na\n-00009f70: 6d65 3d22 6c30 3032 3339 223e 3c2f 613e me=\"l00239\">\n-00009f80: 3c73 7061 6e20 636c 6173 733d 226c 696e 239 if (this\n-00009fd0: 2d26 6774 3b4e 5f20 2b20 7468 6973 2d26 ->N_ + this-&\n-00009fe0: 6774 3b4d 5f20 2b20 7468 6973 2d26 6774 gt;M_ + this->\n-00009ff0: 3b4e 6e7a 5f21 3d30 293c 2f64 6976 3e0a ;Nnz_!=0)
    .\n-0000a000: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    241 <\n-0000a0c0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000a110: 3234 323c 2f73 7061 6e3e 2020 2020 2020 242 \n-0000a120: 3c73 7061 6e20 636c 6173 733d 226b 6579 using M\n-0000a170: 6174 7269 783c 2f61 3e20 3d20 3c61 2063 atrix = BCRSMatr\n-0000a1b0: 6978 266c 743b 422c 5441 2667 743b 3c2f ix<B,TA>;
    ..<\n-0000a310: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000a320: 3e3c 6120 6964 3d22 6c30 3032 3434 2220 > 244 this-&g\n-0000a370: 743b 4d5f 203d 203c 6120 636c 6173 733d t;M_ = MatrixDi\n-0000a3d0: 6d65 6e73 696f 6e26 6c74 3b4d 6174 7269 mension<Matri\n-0000a3e0: 7826 6774 3b3a 3a63 6f6c 6469 6d3c 2f61 x>::coldim(mat);.
    24\n-0000a4a0: 353c 2f73 7061 6e3e 2020 2020 2020 4953 5 IS\n-0000a4b0: 544c 3a3a 496d 706c 3a3a 4243 4353 4d61 TL::Impl::BCCSMa\n-0000a4c0: 7472 6978 496e 6974 6961 6c69 7a65 7226 trixInitializer&\n-0000a4d0: 6c74 3b4d 6174 7269 782c 2069 6e74 2667 lt;Matrix, int&g\n-0000a4e0: 743b 2069 6e69 7469 616c 697a 6572 282a t; initializer(*\n-0000a4f0: 3c73 7061 6e20 636c 6173 733d 226b 6579 this);
    .
    246 <\n-0000a570: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000a5c0: 3234 373c 2f73 7061 6e3e 2020 2020 2020 247 \n-0000a5d0: 636f 7079 546f 4243 4353 4d61 7472 6978 copyToBCCSMatrix\n-0000a5e0: 2869 6e69 7469 616c 697a 6572 2c20 3c61 (initializer, \n-0000a640: 6d61 743c 2f61 3e29 3b3c 2f64 6976 3e0a mat);
    .\n-0000a650: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n-0000a6e0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000a6f0: 6e6f 223e 2020 3234 393c 2f73 7061 6e3e no\"> 249\n-0000a700: 2020 2020 2020 3c61 2063 6c61 7373 3d22 SuperMatrixCr\n-0000a740: 6561 7465 5370 6172 7365 4368 6f6f 7365 eateSparseChoose\n-0000a750: 7226 6c74 3b74 7970 656e 616d 6520 4d61 r<typename Ma\n-0000a760: 7472 6978 3a3a 6669 656c 645f 7479 7065 trix::field_type\n-0000a770: 2667 743b 3c2f 613e 3c2f 6469 763e 0a3c >
    .<\n-0000a780: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000a790: 3e3c 6120 6964 3d22 6c30 3032 3530 2220 > 250\n-0000a800: 2020 2020 2020 2020 2020 203a 3a63 7265 ::cre\n-0000a810: 6174 653c 2f61 3e28 2661 6d70 3b41 2c20 ate(&A, \n-0000a820: 7468 6973 2d26 6774 3b4e 5f2c 2074 6869 this->N_, thi\n-0000a830: 732d 2667 743b 4d5f 2c20 7468 6973 2d26 s->M_, this-&\n-0000a840: 6774 3b63 6f6c 7374 6172 745b 7468 6973 gt;colstart[this\n-0000a850: 2d26 6774 3b4e 5f5d 2c3c 2f64 6976 3e0a ->N_],
    .\n-0000a860: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n-0000a890: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 251 \n-0000a8c0: 2074 6869 732d 2667 743b 7661 6c75 6573 this->values\n-0000a8d0: 2c74 6869 732d 2667 743b 726f 7769 6e64 ,this->rowind\n-0000a8e0: 6578 2c20 7468 6973 2d26 6774 3b63 6f6c ex, this->col\n-0000a8f0: 7374 6172 742c 2053 4c55 5f4e 432c 3c2f start, SLU_NC, 196 \n+00006c50: 766f 6964 3c2f 7370 616e 3e20 3c61 2063 void se\n+00006cb0: 744f 7074 696f 6e3c 2f61 3e28 5b5b 6d61 tOption([[ma\n+00006cc0: 7962 655f 756e 7573 6564 5d5d 203c 7370 ybe_unused]] unsigned<\n+00006cf0: 2f73 7061 6e3e 203c 7370 616e 2063 6c61 /span> int opti\n+00006d20: 6f6e 2c20 5b5b 6d61 7962 655f 756e 7573 on, [[maybe_unus\n+00006d30: 6564 5d5d 203c 7370 616e 2063 6c61 7373 ed]] d\n+00006d50: 6f75 626c 653c 2f73 7061 6e3e 2076 616c ouble val\n+00006d60: 7565 293c 2f64 6976 3e0a 3c64 6976 2063 ue)
    .
    197 \n+00006dc0: 2020 7b7d 3c2f 6469 763e 0a3c 6469 7620 {}
    .
    198 \n+00006e20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n+00006e70: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+00006e80: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n+00006e90: 2367 6134 3065 6332 6233 6561 3136 6231 #ga40ec2b3ea16b1\n+00006ea0: 6532 3134 6433 3862 3536 3666 3464 3037 e214d38b566f4d07\n+00006eb0: 6366 3022 3e20 2032 3030 3c2f 613e 3c2f cf0\"> 200 void <\n+00006ef0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00006f00: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n+00006f10: 2261 3030 3233 332e 6874 6d6c 2367 6134 \"a00233.html#ga4\n+00006f20: 3065 6332 6233 6561 3136 6231 6532 3134 0ec2b3ea16b1e214\n+00006f30: 6433 3862 3536 3666 3464 3037 6366 3022 d38b566f4d07cf0\"\n+00006f40: 3e73 6574 4d61 7472 6978 3c2f 613e 283c >setMatrix(<\n+00006f50: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00006f60: 6f72 6422 3e63 6f6e 7374 3c2f 7370 616e ord\">const Ma\n+00006fa0: 7472 6978 3c2f 613e 2661 6d70 3b20 6d61 trix& ma\n+00006fb0: 7472 6978 293c 2f64 6976 3e0a 3c64 6976 trix)
    .<\n+00006ff0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00007000: 6e6f 223e 2020 3230 313c 2f73 7061 6e3e no\"> 201
    \n+00007010: 2020 2020 7b3c 2f64 6976 3e0a 3c64 6976 {
    .<\n+00007050: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00007060: 6e6f 223e 2020 3230 323c 2f73 7061 6e3e no\"> 202\n+00007070: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+00007090: 6966 3c2f 7370 616e 3e20 2828 7370 7172 if ((spqr\n+000070a0: 4d61 7472 6978 5f2e 4e28 2920 2b20 7370 Matrix_.N() + sp\n+000070b0: 7172 4d61 7472 6978 5f2e 4d28 2920 2667 qrMatrix_.M() &g\n+000070c0: 743b 2030 2920 7c7c 206d 6174 7269 7849 t; 0) || matrixI\n+000070d0: 734c 6f61 6465 645f 293c 2f64 6976 3e0a sLoaded_)
    .\n+000070e0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    204 <\n+000071a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000071f0: 3230 353c 2f73 7061 6e3e 2020 2020 2020 205 \n+00007200: 3c73 7061 6e20 636c 6173 733d 226b 6579 if (spqrMatrix_\n+00007230: 2e4e 2829 202b 2073 7071 724d 6174 7269 .N() + spqrMatri\n+00007240: 785f 2e4d 2829 202b 2073 7071 724d 6174 x_.M() + spqrMat\n+00007250: 7269 785f 2e6e 6f6e 7a65 726f 6573 2829 rix_.nonzeroes()\n+00007260: 2021 3d20 3029 3c2f 6469 763e 0a3c 6469 != 0)
    .<\n+00007280: 6120 6964 3d22 6c30 3032 3036 2220 6e61 a id=\"l00206\" na\n+00007290: 6d65 3d22 6c30 3032 3036 223e 3c2f 613e me=\"l00206\">\n+000072a0: 3c73 7061 6e20 636c 6173 733d 226c 696e 206 spqrMat\n+000072d0: 7269 785f 2e66 7265 6528 293b 3c2f 6469 rix_.free();.
    207\n+00007330: 3c2f 7370 616e 3e20 2020 2020 2073 7071 spq\n+00007340: 724d 6174 7269 785f 2e73 6574 5369 7a65 rMatrix_.setSize\n+00007350: 283c 6120 636c 6173 733d 2263 6f64 6520 (Ma\n+00007380: 7472 6978 4469 6d65 6e73 696f 6e26 6c74 trixDimension<\n+00007390: 3b4d 6174 7269 7826 6774 3b3a 3a72 6f77 ;Matrix>::row\n+000073a0: 6469 6d3c 2f61 3e28 6d61 7472 6978 292c dim(matrix),\n+000073b0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00007400: 2032 3038 3c2f 7370 616e 3e20 2020 2020 208 \n+00007410: 2020 2020 2020 2020 2020 2020 2020 2020 \n+00007420: 2020 2020 203c 6120 636c 6173 733d 2263 MatrixDimensio\n+00007460: 6e26 6c74 3b4d 6174 7269 7826 6774 3b3a n<Matrix>:\n+00007470: 3a63 6f6c 6469 6d3c 2f61 3e28 6d61 7472 :coldim(matr\n+00007480: 6978 2929 3b3c 2f64 6976 3e0a 3c64 6976 ix));
    .<\n+000074c0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+000074d0: 6e6f 223e 2020 3230 393c 2f73 7061 6e3e no\"> 209
    \n+000074e0: 2020 2020 2020 4953 544c 3a3a 496d 706c ISTL::Impl\n+000074f0: 3a3a 4243 4353 4d61 7472 6978 496e 6974 ::BCCSMatrixInit\n+00007500: 6961 6c69 7a65 7226 6c74 3b4d 6174 7269 ializer<Matri\n+00007510: 782c 2069 6e74 2667 743b 2069 6e69 7469 x, int> initi\n+00007520: 616c 697a 6572 2873 7071 724d 6174 7269 alizer(spqrMatri\n+00007530: 785f 293b 3c2f 6469 763e 0a3c 6469 7620 x_);
    .
    210 \n+00007590: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+000075e0: 2032 3131 3c2f 7370 616e 3e20 2020 2020 211 \n+000075f0: 2063 6f70 7954 6f42 4343 534d 6174 7269 copyToBCCSMatri\n+00007600: 7828 696e 6974 6961 6c69 7a65 722c 206d x(initializer, m\n+00007610: 6174 7269 7829 3b3c 2f64 6976 3e0a 3c64 atrix);
    .\n+00007630: 3c61 2069 643d 226c 3030 3231 3222 206e 212
    .
    213 \n+000076d0: 2020 2020 6465 636f 6d70 6f73 6528 293b decompose();\n+000076e0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00007730: 2032 3134 3c2f 7370 616e 3e20 2020 207d 214 }\n+00007740: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00007790: 2032 3135 3c2f 7370 616e 3e20 3c2f 6469 215 .
    216\n+000077f0: 3c2f 7370 616e 3e20 2020 203c 7370 616e template\n+00007820: 266c 743b 3c73 7061 6e20 636c 6173 733d <class<\n+00007840: 2f73 7061 6e3e 2053 2667 743b 3c2f 6469 /span> S>.
    217 v\n+00007910: 6f69 643c 2f73 7061 6e3e 203c 6120 636c oid set\n+00007970: 5375 624d 6174 7269 783c 2f61 3e28 3c73 SubMatrix(const\n+000079a0: 203c 6120 636c 6173 733d 2263 6f64 6520 Mat\n+000079d0: 7269 783c 2f61 3e26 616d 703b 206d 6174 rix& mat\n+000079e0: 7269 782c 203c 7370 616e 2063 6c61 7373 rix, const\n+00007a00: 3c2f 7370 616e 3e20 5326 616d 703b 2072 S& r\n+00007a10: 6f77 496e 6465 7853 6574 293c 2f64 6976 owIndexSet).
    218<\n+00007a70: 2f73 7061 6e3e 2020 2020 7b3c 2f64 6976 /span> {.
    219<\n+00007ad0: 2f73 7061 6e3e 2020 2020 2020 3c73 7061 /span> if \n+00007b00: 2828 7370 7172 4d61 7472 6978 5f2e 4e28 ((spqrMatrix_.N(\n+00007b10: 2920 2b20 7370 7172 4d61 7472 6978 5f2e ) + spqrMatrix_.\n+00007b20: 4d28 2920 2667 743b 2030 2920 7c7c 206d M() > 0) || m\n+00007b30: 6174 7269 7849 734c 6f61 6465 645f 293c atrixIsLoaded_)<\n+00007b40: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00007b90: 3232 303c 2f73 7061 6e3e 2020 2020 2020 220 \n+00007ba0: 2020 6672 6565 2829 3b3c 2f64 6976 3e0a free();
    .\n+00007bb0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00007c40: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00007c50: 6e6f 223e 2020 3232 323c 2f73 7061 6e3e no\"> 222\n+00007c60: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+00007c80: 6966 3c2f 7370 616e 3e20 2873 7071 724d if (spqrM\n+00007c90: 6174 7269 785f 2e4e 2829 202b 2073 7071 atrix_.N() + spq\n+00007ca0: 724d 6174 7269 785f 2e4d 2829 202b 2073 rMatrix_.M() + s\n+00007cb0: 7071 724d 6174 7269 785f 2e6e 6f6e 7a65 pqrMatrix_.nonze\n+00007cc0: 726f 6573 2829 2021 3d20 3029 3c2f 6469 roes() != 0).
    223\n+00007d20: 3c2f 7370 616e 3e20 2020 2020 2020 2073 s\n+00007d30: 7071 724d 6174 7269 785f 2e66 7265 6528 pqrMatrix_.free(\n+00007d40: 293b 3c2f 6469 763e 0a3c 6469 7620 636c );
    .
    224 .
    2\n+00007df0: 3235 3c2f 7370 616e 3e20 2020 2020 2073 25 s\n+00007e00: 7071 724d 6174 7269 785f 2e73 6574 5369 pqrMatrix_.setSi\n+00007e10: 7a65 2872 6f77 496e 6465 7853 6574 2e73 ze(rowIndexSet.s\n+00007e20: 697a 6528 292a 3c61 2063 6c61 7373 3d22 ize()*MatrixDimensi\n+00007e60: 6f6e 266c 743b 4d61 7472 6978 2667 743b on<Matrix>\n+00007e70: 3a3a 726f 7764 696d 3c2f 613e 286d 6174 ::rowdim(mat\n+00007e80: 7269 7829 202f 206d 6174 7269 782e 3c61 rix) / matrix.N\n+00007ee0: 3c2f 613e 2829 2c3c 2f64 6976 3e0a 3c64 (),
    .\n+00007f00: 3c61 2069 643d 226c 3030 3232 3622 206e 226 \n+00007f50: 2020 2020 2020 2020 2020 2020 726f 7749 rowI\n+00007f60: 6e64 6578 5365 742e 7369 7a65 2829 2a3c ndexSet.size()*<\n+00007f70: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00007f80: 5f73 7472 7563 7422 2068 7265 663d 2261 _struct\" href=\"a\n+00007f90: 3031 3133 362e 6874 6d6c 223e 4d61 7472 01136.html\">Matr\n+00007fa0: 6978 4469 6d65 6e73 696f 6e26 6c74 3b4d ixDimension<M\n+00007fb0: 6174 7269 7826 6774 3b3a 3a63 6f6c 6469 atrix>::coldi\n+00007fc0: 6d3c 2f61 3e28 6d61 7472 6978 2920 2f20 m(matrix) / \n+00007fd0: 6d61 7472 6978 2e3c 6120 636c 6173 733d matrix.M())\n+00008030: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+00008080: 2020 3232 373c 2f73 7061 6e3e 2020 2020 227 \n+00008090: 2020 4953 544c 3a3a 496d 706c 3a3a 4243 ISTL::Impl::BC\n+000080a0: 4353 4d61 7472 6978 496e 6974 6961 6c69 CSMatrixInitiali\n+000080b0: 7a65 7226 6c74 3b4d 6174 7269 782c 2069 zer<Matrix, i\n+000080c0: 6e74 2667 743b 2069 6e69 7469 616c 697a nt> initializ\n+000080d0: 6572 2873 7071 724d 6174 7269 785f 293b er(spqrMatrix_);\n+000080e0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00008130: 2032 3238 3c2f 7370 616e 3e20 3c2f 6469 228 .
    229\n+00008190: 3c2f 7370 616e 3e20 2020 2020 2063 6f70 cop\n+000081a0: 7954 6f42 4343 534d 6174 7269 7828 696e yToBCCSMatrix(in\n+000081b0: 6974 6961 6c69 7a65 722c 2049 5354 4c3a itializer, ISTL:\n+000081c0: 3a49 6d70 6c3a 3a4d 6174 7269 7852 6f77 :Impl::MatrixRow\n+000081d0: 5375 6273 6574 266c 743b 3c61 2063 6c61 Subset<Matrix\n+00008210: 2c73 7464 3a3a 7365 7426 6c74 3b73 7464 ,std::set<std\n+00008220: 3a3a 7369 7a65 5f74 2667 743b 2026 6774 ::size_t> >\n+00008230: 3b28 6d61 7472 6978 2c72 6f77 496e 6465 ;(matrix,rowInde\n+00008240: 7853 6574 2929 3b3c 2f64 6976 3e0a 3c64 xSet));
    .\n+00008260: 3c61 2069 643d 226c 3030 3233 3022 206e 230
    .
    231 \n+00008300: 2020 2020 6465 636f 6d70 6f73 6528 293b decompose();\n+00008310: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00008360: 2032 3332 3c2f 7370 616e 3e20 2020 207d 232 }\n+00008370: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+000083c0: 2032 3333 3c2f 7370 616e 3e20 3c2f 6469 233 .
    238 inlin\n+00008490: 653c 2f73 7061 6e3e 203c 7370 616e 2063 e void <\n+000084c0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+000084d0: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n+000084e0: 2261 3030 3233 332e 6874 6d6c 2367 6137 \"a00233.html#ga7\n+000084f0: 3463 6537 6232 3139 3634 3763 3736 3838 4ce7b219647c7688\n+00008500: 3061 3631 3533 3731 6335 3763 3137 3322 0a615371c57c173\"\n+00008510: 3e73 6574 5665 7262 6f73 6974 793c 2f61 >setVerbosity(int<\n+00008540: 2f73 7061 6e3e 2076 293c 2f64 6976 3e0a /span> v)
    .\n+00008550: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+000085b0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00008650: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00008660: 6e6f 223e 2020 3234 313c 2f73 7061 6e3e no\"> 241\n+00008670: 2020 2020 7d3c 2f64 6976 3e0a 3c64 6976 }
    .<\n+000086b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+000086c0: 6e6f 223e 2020 3234 323c 2f73 7061 6e3e no\"> 242\n+000086d0: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
    .
    \n+00008720: 3c61 2063 6c61 7373 3d22 6c69 6e65 2220 247<\n+00008770: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n+00008790: 696e 6c69 6e65 3c2f 7370 616e 3e20 5375 inline Su\n+000087a0: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n+000087b0: 6f72 697a 6174 696f 6e26 6c74 3b54 2667 orization<T&g\n+000087c0: 743b 2a20 3c61 2063 6c61 7373 3d22 636f t;* getFactori\n+00008820: 7a61 7469 6f6e 3c2f 613e 2829 3c2f 6469 zation().
    248\n+00008880: 3c2f 7370 616e 3e20 2020 207b 3c2f 6469 {.
    249\n+000088e0: 3c2f 7370 616e 3e20 2020 2020 203c 7370 return spqrfactori\n+00008920: 7a61 7469 6f6e 5f3b 3c2f 6469 763e 0a3c zation_;
    .<\n+00008930: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00008940: 3e3c 6120 6964 3d22 6c30 3032 3530 2220 > 250 }
    .<\n+00008990: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+000089a0: 3e3c 6120 6964 3d22 6c30 3032 3531 2220 > 251
    .
    256 inline\n+00008ab0: 203c 6120 636c 6173 733d 2263 6f64 6520 SPQRMatrix\n+00008b10: 2661 6d70 3b20 3c61 2063 6c61 7373 3d22 & getInter\n+00008b70: 6e61 6c4d 6174 7269 783c 2f61 3e28 293c nalMatrix()<\n+00008b80: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00008bd0: 3235 373c 2f73 7061 6e3e 2020 2020 7b3c 257 {<\n+00008be0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+00008c30: 3235 383c 2f73 7061 6e3e 2020 2020 2020 258 \n+00008c40: 3c73 7061 6e20 636c 6173 733d 226b 6579 return\n+00008c60: 3c2f 7370 616e 3e20 7370 7172 4d61 7472 spqrMatr\n+00008c70: 6978 5f3b 3c2f 6469 763e 0a3c 6469 7620 ix_;
    .
    259 \n+00008cd0: 2020 207d 3c2f 6469 763e 0a3c 6469 7620 }
    .
    260 \n+00008d30: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n+00008d80: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+00008d90: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n+00008da0: 2367 6139 3237 3966 6633 3139 3530 3134 #ga9279ff3195014\n+00008db0: 3136 6338 6165 6630 3462 6565 6562 3362 16c8aef04beeeb3b\n+00008dc0: 3366 3922 3e20 2032 3635 3c2f 613e 3c2f 3f9\"> 265 void <\n+00008e00: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00008e10: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n+00008e20: 2261 3030 3233 332e 6874 6d6c 2367 6139 \"a00233.html#ga9\n+00008e30: 3237 3966 6633 3139 3530 3134 3136 6338 279ff319501416c8\n+00008e40: 6165 6630 3462 6565 6562 3362 3366 3922 aef04beeeb3b3f9\"\n+00008e50: 3e66 7265 653c 2f61 3e28 293c 2f64 6976 >free().
    266<\n+00008eb0: 2f73 7061 6e3e 2020 2020 7b3c 2f64 6976 /span> {.
    267<\n+00008f10: 2f73 7061 6e3e 2020 2020 2020 6368 6f6c /span> chol\n+00008f20: 6d6f 645f 6c5f 6672 6565 5f73 7061 7273 mod_l_free_spars\n+00008f30: 6528 2661 6d70 3b41 5f2c 2063 635f 293b e(&A_, cc_);\n+00008f40: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+00008f90: 2032 3638 3c2f 7370 616e 3e20 2020 2020 268 \n+00008fa0: 2063 686f 6c6d 6f64 5f6c 5f66 7265 655f cholmod_l_free_\n+00008fb0: 6465 6e73 6528 2661 6d70 3b42 5f2c 2063 dense(&B_, c\n+00008fc0: 635f 293b 3c2f 6469 763e 0a3c 6469 7620 c_);
    .
    269 \n+00009020: 2020 2020 2053 7569 7465 5370 6172 7365 SuiteSparse\n+00009030: 5152 5f66 7265 6526 6c74 3b54 2667 743b QR_free<T>\n+00009040: 2826 616d 703b 7370 7172 6661 6374 6f72 (&spqrfactor\n+00009050: 697a 6174 696f 6e5f 2c20 6363 5f29 3b3c ization_, cc_);<\n+00009060: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000090b0: 3237 303c 2f73 7061 6e3e 2020 2020 2020 270 \n+000090c0: 7370 7172 4d61 7472 6978 5f2e 6672 6565 spqrMatrix_.free\n+000090d0: 2829 3b3c 2f64 6976 3e0a 3c64 6976 2063 ();
    .
    271 \n+00009130: 2020 2020 6d61 7472 6978 4973 4c6f 6164 matrixIsLoad\n+00009140: 6564 5f20 3d20 3c73 7061 6e20 636c 6173 ed_ = fals\n+00009160: 653c 2f73 7061 6e3e 3b3c 2f64 6976 3e0a e;
    .\n+00009170: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+000091d0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .<\n+00009260: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00009270: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 275<\n+000092c0: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c73 /a> inline const c\n+00009330: 6861 723c 2f73 7061 6e3e 2a20 3c61 2063 har* na\n+00009390: 6d65 3c2f 613e 2829 3c2f 6469 763e 0a3c me()
    .<\n+000093a0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+000093b0: 3e3c 6120 6964 3d22 6c30 3032 3736 2220 > 276 {
    .<\n+00009400: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+00009410: 3e3c 6120 6964 3d22 6c30 3032 3737 2220 > 277 return\n+00009480: 203c 7370 616e 2063 6c61 7373 3d22 7374 &qu\n+000094a0: 6f74 3b53 5051 5226 7175 6f74 3b3c 2f73 ot;SPQR";
    .<\n+000094f0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00009500: 6e6f 223e 2020 3237 383c 2f73 7061 6e3e no\"> 278\n+00009510: 2020 2020 7d3c 2f64 6976 3e0a 3c64 6976 }
    .<\n+00009550: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00009560: 6e6f 223e 2020 3237 393c 2f73 7061 6e3e no\"> 279\n+00009570: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
    .
    \n+000095c0: 2020 3238 303c 2f73 7061 6e3e 2020 2020 280 \n+000095d0: 3c73 7061 6e20 636c 6173 733d 226b 6579 private:
    .<\n+00009630: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+00009640: 6e6f 223e 2020 3238 313c 2f73 7061 6e3e no\"> 281
    \n+00009650: 2020 2020 3c73 7061 6e20 636c 6173 733d templa\n+00009670: 7465 3c2f 7370 616e 3e26 6c74 3b3c 7370 te<class \n+000096a0: 4d2c 3c73 7061 6e20 636c 6173 733d 226b M,class X, cl\n+000096e0: 6173 733c 2f73 7061 6e3e 2054 4d2c 203c ass TM, <\n+000096f0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+00009700: 6f72 6422 3e63 6c61 7373 3c2f 7370 616e ord\">class TD, clas\n+00009730: 733c 2f73 7061 6e3e 2054 3126 6774 3b3c s T1><\n+00009740: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    282 fr\n+00009800: 6965 6e64 3c2f 7370 616e 3e20 3c73 7061 iend class <\n+00009830: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n+00009840: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n+00009850: 3134 3132 2e68 746d 6c22 3e53 6571 4f76 1412.html\">SeqOv\n+00009860: 6572 6c61 7070 696e 6753 6368 7761 727a erlappingSchwarz\n+00009870: 3c2f 613e 3b3c 2f64 6976 3e0a 3c64 6976 ;
    .<\n+000098b0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+000098c0: 6e6f 223e 2020 3238 333c 2f73 7061 6e3e no\"> 283
    \n+000098d0: 203c 2f64 6976 3e0a 3c64 6976 2063 6c61
    .
    \n+00009920: 2020 3238 343c 2f73 7061 6e3e 2020 2020 284 \n+00009930: 3c73 7061 6e20 636c 6173 733d 226b 6579 friend struct\n+00009970: 203c 2f73 7061 6e3e 3c61 2063 6c61 7373 SeqOverlapp\n+000099b0: 696e 6753 6368 7761 727a 4173 7365 6d62 ingSchwarzAssemb\n+000099c0: 6c65 7248 656c 7065 723c 2f61 3e26 6c74 lerHelper<\n+000099d0: 3b3c 6120 636c 6173 733d 2263 6f64 6520 ;SPQ\n+00009a00: 523c 2f61 3e26 6c74 3b3c 6120 636c 6173 R<Matrix&\n+00009a40: 6774 3b2c 7472 7565 2667 743b 3b3c 2f64 gt;,true>;.
    28\n+00009aa0: 353c 2f73 7061 6e3e 203c 2f64 6976 3e0a 5
    .\n+00009ab0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+00009b40: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .\n+00009ba0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 .
    \n+00009c90: 2032 3930 3c2f 7370 616e 3e20 2020 2020 290 \n+00009ca0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 const std::size_t \n+00009cd0: 6e63 6f6c 7328 7370 7172 4d61 7472 6978 ncols(spqrMatrix\n+00009ce0: 5f2e 4d28 2929 3b3c 2f64 6976 3e0a 3c64 _.M());
    .\n+00009d00: 3c61 2069 643d 226c 3030 3239 3122 206e 291 co\n+00009d60: 6e73 743c 2f73 7061 6e3e 2073 7464 3a3a nst std::\n+00009d70: 7369 7a65 5f74 206e 6e7a 2873 7071 724d size_t nnz(spqrM\n+00009d80: 6174 7269 785f 2e67 6574 436f 6c53 7461 atrix_.getColSta\n+00009d90: 7274 2829 5b6e 636f 6c73 5d29 3b3c 2f64 rt()[ncols]);.
    29\n+00009df0: 323c 2f73 7061 6e3e 203c 2f64 6976 3e0a 2
    .\n+00009e00: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n+00009e30: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 293 \n+00009e70: 2f2f 2069 6e69 7469 616c 6973 6520 7468 // initialise th\n+00009e80: 6520 6d61 7472 6978 2041 2028 736f 7274 e matrix A (sort\n+00009e90: 6564 2c20 7061 636b 6564 2c20 756e 7379 ed, packed, unsy\n+00009ea0: 6d6d 6574 7269 632c 2072 6561 6c20 656e mmetric, real en\n+00009eb0: 7472 6965 7329 3c2f 7370 616e 3e3c 2f64 tries).
    29\n+00009f10: 343c 2f73 7061 6e3e 2020 2020 2020 415f 4 A_\n+00009f20: 203d 2063 686f 6c6d 6f64 5f6c 5f61 6c6c = cholmod_l_all\n+00009f30: 6f63 6174 655f 7370 6172 7365 286e 726f ocate_sparse(nro\n+00009f40: 7773 2c20 6e63 6f6c 732c 206e 6e7a 2c20 ws, ncols, nnz, \n+00009f50: 312c 2031 2c20 302c 2031 2c20 6363 5f29 1, 1, 0, 1, cc_)\n+00009f60: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+00009fb0: 2020 3239 353c 2f73 7061 6e3e 203c 2f64 295 .
    29\n+0000a010: 363c 2f73 7061 6e3e 2020 2020 2020 3c73 6 // copy all \n+0000a040: 7468 6520 656e 7472 6965 7320 6f66 2041 the entries of A\n+0000a050: 702c 2041 692c 2041 783c 2f73 7061 6e3e p, Ai, Ax\n+0000a060: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000a0b0: 2032 3937 3c2f 7370 616e 3e20 2020 2020 297 \n+0000a0c0: 203c 7370 616e 2063 6c61 7373 3d22 6b65 for(std::size_\n+0000a0f0: 7420 6b20 3d20 303b 206b 2021 3d20 286e t k = 0; k != (n\n+0000a100: 636f 6c73 2b31 293b 202b 2b6b 293c 2f64 cols+1); ++k).
    29\n+0000a160: 383c 2f73 7061 6e3e 2020 2020 2020 2020 8 \n+0000a170: 283c 7370 616e 2063 6c61 7373 3d22 6b65 (static_ca\n+0000a190: 7374 266c 743b 3c2f 7370 616e 3e3c 7370 st<long int\n+0000a1e0: 3c2f 7370 616e 3e20 2a3c 7370 616e 2063 *&\n+0000a200: 6774 3b3c 2f73 7061 6e3e 2841 5f2d 2667 gt;(A_-&g\n+0000a210: 743b 7029 295b 6b5d 203d 2073 7071 724d t;p))[k] = spqrM\n+0000a220: 6174 7269 785f 2e67 6574 436f 6c53 7461 atrix_.getColSta\n+0000a230: 7274 2829 5b6b 5d3b 3c2f 6469 763e 0a3c rt()[k];
    .<\n+0000a240: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+0000a250: 3e3c 6120 6964 3d22 6c30 3032 3939 2220 > 299
    .
    300 \n+0000a2f0: 2020 2020 203c 7370 616e 2063 6c61 7373 f\n+0000a310: 6f72 3c2f 7370 616e 3e28 7374 643a 3a73 or(std::s\n+0000a320: 697a 655f 7420 6b20 3d20 303b 206b 2021 ize_t k = 0; k !\n+0000a330: 3d20 6e6e 7a3b 202b 2b6b 293c 2f64 6976 = nnz; ++k).
    301<\n+0000a390: 2f73 7061 6e3e 2020 2020 2020 7b3c 2f64 /span> {.
    30\n+0000a3f0: 323c 2f73 7061 6e3e 2020 2020 2020 2020 2 \n+0000a400: 283c 7370 616e 2063 6c61 7373 3d22 6b65 (static_ca\n+0000a420: 7374 266c 743b 3c2f 7370 616e 3e3c 7370 st<long int\n+0000a470: 3c2f 7370 616e 3e2a 3c73 7061 6e20 636c *&g\n+0000a490: 743b 3c2f 7370 616e 3e28 415f 2d26 6774 t;(A_->\n+0000a4a0: 3b69 2929 5b6b 5d20 3d20 7370 7172 4d61 ;i))[k] = spqrMa\n+0000a4b0: 7472 6978 5f2e 6765 7452 6f77 496e 6465 trix_.getRowInde\n+0000a4c0: 7828 295b 6b5d 3b3c 2f64 6976 3e0a 3c64 x()[k];
    .\n+0000a4e0: 3c61 2069 643d 226c 3030 3330 3322 206e 303 (static_cast<\n+0000a550: 3c2f 7370 616e 3e54 2a3c 7370 616e 2063 T*&\n+0000a570: 6774 3b3c 2f73 7061 6e3e 2841 5f2d 2667 gt;(A_-&g\n+0000a580: 743b 7829 295b 6b5d 203d 2073 7071 724d t;x))[k] = spqrM\n+0000a590: 6174 7269 785f 2e67 6574 5661 6c75 6573 atrix_.getValues\n+0000a5a0: 2829 5b6b 5d3b 3c2f 6469 763e 0a3c 6469 ()[k];
    .<\n+0000a5c0: 6120 6964 3d22 6c30 3033 3034 2220 6e61 a id=\"l00304\" na\n+0000a5d0: 6d65 3d22 6c30 3033 3034 223e 3c2f 613e me=\"l00304\">\n+0000a5e0: 3c73 7061 6e20 636c 6173 733d 226c 696e 304 }
    .<\n+0000a610: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+0000a620: 3e3c 6120 6964 3d22 6c30 3033 3035 2220 > 305
    .
    306 \n+0000a6c0: 2020 2020 203c 7370 616e 2063 6c61 7373 // in\n+0000a6e0: 6974 6961 6c69 7365 2074 6865 2076 6563 itialise the vec\n+0000a6f0: 746f 7220 423c 2f73 7061 6e3e 3c2f 6469 tor B.
    307\n+0000a750: 3c2f 7370 616e 3e20 2020 2020 2042 5f20 B_ \n+0000a760: 3d20 6368 6f6c 6d6f 645f 6c5f 616c 6c6f = cholmod_l_allo\n+0000a770: 6361 7465 5f64 656e 7365 286e 726f 7773 cate_dense(nrows\n+0000a780: 2c20 312c 206e 726f 7773 2c20 415f 2d26 , 1, nrows, A_-&\n+0000a790: 6774 3b78 7479 7065 2c20 6363 5f29 3b3c gt;xtype, cc_);<\n+0000a7a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+0000a7f0: 3330 383c 2f73 7061 6e3e 2020 2020 2020 308 \n+0000a800: 3c73 7061 6e20 636c 6173 733d 2263 6f6d // compute\n+0000a820: 2066 6163 746f 7269 7a61 7469 6f6e 206f factorization o\n+0000a830: 6620 413c 2f73 7061 6e3e 3c2f 6469 763e f A
    \n+0000a840: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n+0000a870: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 309 spqrf\n+0000a8a0: 6163 746f 7269 7a61 7469 6f6e 5f3d 5375 actorization_=Su\n+0000a8b0: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n+0000a8c0: 6f72 697a 6526 6c74 3b54 2667 743b 2853 orize<T>(S\n+0000a8d0: 5051 525f 4f52 4445 5249 4e47 5f44 4546 PQR_ORDERING_DEF\n+0000a8e0: 4155 4c54 2c53 5051 525f 4445 4641 554c AULT,SPQR_DEFAUL\n+0000a8f0: 545f 544f 4c2c 415f 2c63 635f 293b 3c2f T_TOL,A_,cc_);.
    2\n-0000a950: 3532 3c2f 7370 616e 3e20 2020 2020 2020 52 \n-0000a960: 2020 2020 2020 3c73 7061 6e20 636c 6173 stat\n-0000a980: 6963 5f63 6173 7426 6c74 3b3c 2f73 7061 ic_cast<Dtype_t&\n-0000a9b0: 6774 3b3c 2f73 7061 6e3e 283c 6120 636c gt;(GetSuper\n-0000a9f0: 4c55 5479 7065 266c 743b 7479 7065 6e61 LUType<typena\n-0000aa00: 6d65 204d 6174 7269 783a 3a66 6965 6c64 me Matrix::field\n-0000aa10: 5f74 7970 6526 6774 3b3a 3a74 7970 653c _type>::type<\n-0000aa20: 2f61 3e29 2c20 534c 555f 4745 293b 3c2f /a>), SLU_GE);.
    2\n-0000aa80: 3533 3c2f 7370 616e 3e20 2020 2020 203c 53 <\n+0000a920: 3033 3130 2220 6e61 6d65 3d22 6c30 3033 0310\" name=\"l003\n+0000a930: 3130 223e 3c2f 613e 3c73 7061 6e20 636c 10\"> 3\n+0000a950: 3130 3c2f 7370 616e 3e20 2020 207d 3c2f 10 }.
    3\n+0000a9b0: 3131 3c2f 7370 616e 3e20 3c2f 6469 763e 11
    \n+0000a9c0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n+0000a9f0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 312 SPQRMat\n+0000aa20: 7269 7820 7370 7172 4d61 7472 6978 5f3b rix spqrMatrix_;\n+0000aa30: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000aa80: 2033 3133 3c2f 7370 616e 3e20 2020 203c 313 <\n 0000aa90: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000aaa0: 6f72 6466 6c6f 7722 3e72 6574 7572 6e3c ordflow\">return<\n-0000aab0: 2f73 7061 6e3e 202a 3c73 7061 6e20 636c /span> *th\n-0000aad0: 6973 3c2f 7370 616e 3e3b 3c2f 6469 763e is;
    \n-0000aae0: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-0000ab40: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-0000abb0: 6120 6964 3d22 6c30 3032 3536 2220 6e61 a id=\"l00256\" na\n-0000abc0: 6d65 3d22 6c30 3032 3536 223e 3c2f 613e me=\"l00256\">\n-0000abd0: 3c73 7061 6e20 636c 6173 733d 226c 696e 256<\n-0000ac30: 2f61 3e3c 2f73 7061 6e3e 2020 2020 3c61 /a> Super\n-0000ac70: 4c55 4d61 7472 6978 266c 743b 4243 5253 LUMatrix<BCRS\n-0000ac80: 4d61 7472 6978 266c 743b 422c 5441 2667 Matrix<B,TA&g\n-0000ac90: 743b 3c2f 613e 2026 6774 3b26 616d 703b t; >&\n-0000aca0: 203c 6120 636c 6173 733d 2263 6f64 6520 operator=(\n-0000ad00: 3c73 7061 6e20 636c 6173 733d 226b 6579 const \n-0000ad50: 5375 7065 724c 554d 6174 7269 783c 2f61 SuperLUMatrix <BCRSMatrix<\n-0000ada0: 422c 5441 2667 743b 3c2f 613e 2026 6774 B,TA> >\n-0000adb0: 3b26 616d 703b 203c 6120 636c 6173 733d ;& mat\n-0000ae10: 293c 2f64 6976 3e0a 3c64 6976 2063 6c61 )
    .
    \n-0000ae60: 2020 3235 373c 2f73 7061 6e3e 2020 2020 257 \n-0000ae70: 7b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 {
    .
    \n-0000aec0: 2020 3235 383c 2f73 7061 6e3e 2020 2020 258 \n-0000aed0: 2020 3c73 7061 6e20 636c 6173 733d 226b if (this->\n-0000af00: 4e5f 202b 2074 6869 732d 2667 743b 4d5f N_ + this->M_\n-0000af10: 202b 2074 6869 732d 2667 743b 4e6e 7a5f + this->Nnz_\n-0000af20: 213d 3029 3c2f 6469 763e 0a3c 6469 7620 !=0)
    .
    259 \n-0000af80: 2020 2020 2020 2066 7265 6528 293b 3c2f free();.
    2\n-0000afe0: 3630 3c2f 7370 616e 3e20 3c2f 6469 763e 60
    \n-0000aff0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000b020: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 261 using Matrix\n-0000b0a0: 3c2f 613e 203d 203c 6120 636c 6173 733d = BCRSMatrix<\n-0000b0e0: 3b42 2c54 4126 6774 3b3c 2f61 3e3b 3c2f ;B,TA>;...<\n-0000b380: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000b390: 3e3c 6120 6964 3d22 6c30 3032 3634 2220 > 264 ISTL::I\n-0000b3e0: 6d70 6c3a 3a42 4343 534d 6174 7269 7849 mpl::BCCSMatrixI\n-0000b3f0: 6e69 7469 616c 697a 6572 266c 743b 4d61 nitializer<Ma\n-0000b400: 7472 6978 2c20 696e 7426 6774 3b20 696e trix, int> in\n-0000b410: 6974 6961 6c69 7a65 7228 2a3c 7370 616e itializer(*this);.
    2\n-0000b490: 3635 3c2f 7370 616e 3e20 3c2f 6469 763e 65
    \n-0000b4a0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000b4d0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 266 copyT\n-0000b500: 6f42 4343 534d 6174 7269 7828 696e 6974 oBCCSMatrix(init\n-0000b510: 6961 6c69 7a65 722c 203c 6120 636c 6173 ializer, mat);
    .
    267 \n-0000b5d0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    ..\n-0000b690: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n-0000b6c0: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 269 ::cr\n-0000b720: 6561 7465 3c2f 613e 2826 616d 703b 412c eate(&A,\n-0000b730: 2074 6869 732d 2667 743b 4e5f 2c20 7468 this->N_, th\n-0000b740: 6973 2d26 6774 3b4d 5f2c 2074 6869 732d is->M_, this-\n-0000b750: 2667 743b 636f 6c73 7461 7274 5b74 6869 >colstart[thi\n-0000b760: 732d 2667 743b 4e5f 5d2c 3c2f 6469 763e s->N_],
    \n-0000b770: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000b7a0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 270 \n-0000b7d0: 2020 7468 6973 2d26 6774 3b76 616c 7565 this->value\n-0000b7e0: 732c 7468 6973 2d26 6774 3b72 6f77 696e s,this->rowin\n-0000b7f0: 6465 782c 2074 6869 732d 2667 743b 636f dex, this->co\n-0000b800: 6c73 7461 7274 2c20 534c 555f 4e43 2c3c lstart, SLU_NC,<\n-0000b810: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000b860: 3237 313c 2f73 7061 6e3e 2020 2020 2020 271 \n-0000b870: 2020 2020 2020 203c 7370 616e 2063 6c61 sta\n-0000b890: 7469 635f 6361 7374 266c 743b 3c2f 7370 tic_cast<Dtype_t\n-0000b8c0: 2667 743b 3c2f 7370 616e 3e28 3c61 2063 >(GetSupe\n-0000b900: 724c 5554 7970 6526 6c74 3b42 2667 743b rLUType<B>\n-0000b910: 3a3a 7479 7065 3c2f 613e 292c 2053 4c55 ::type), SLU\n-0000b920: 5f47 4529 3b3c 2f64 6976 3e0a 3c64 6976 _GE);
    .<\n-0000b960: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000b970: 6e6f 223e 2020 3237 323c 2f73 7061 6e3e no\"> 272
    \n-0000b980: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n-0000b9a0: 7265 7475 726e 3c2f 7370 616e 3e20 2a3c return *<\n-0000b9b0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000b9c0: 6f72 6422 3e74 6869 733c 2f73 7061 6e3e ord\">this\n-0000b9d0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-0000ba20: 2020 3237 333c 2f73 7061 6e3e 2020 2020 273 \n-0000ba30: 7d3c 2f64 6976 3e0a 3c64 6976 2063 6c61 }
    .
    \n-0000ba80: 2020 3237 343c 2f73 7061 6e3e 203c 2f64 274 .
    281 virtu\n-0000bb50: 616c 3c2f 7370 616e 3e20 3c73 7061 6e20 al void \n-0000bb80: 3c61 2063 6c61 7373 3d22 636f 6465 2068 setMatrix(<\n-0000bbe0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000bbf0: 6f72 6422 3e63 6f6e 7374 3c2f 7370 616e ord\">const Ma\n-0000bc30: 7472 6978 3c2f 613e 2661 6d70 3b20 3c61 trix& \n-0000bc90: 6d61 743c 2f61 3e2c 203c 7370 616e 2063 mat, c\n-0000bcb0: 6f6e 7374 3c2f 7370 616e 3e20 7374 643a onst std:\n-0000bcc0: 3a73 6574 266c 743b 7374 643a 3a73 697a :set<std::siz\n-0000bcd0: 655f 7426 6774 3b26 616d 703b 206d 7273 e_t>& mrs\n-0000bce0: 293c 2f64 6976 3e0a 3c64 6976 2063 6c61 )
    .
    \n-0000bd30: 2020 3238 323c 2f73 7061 6e3e 2020 2020 282 \n-0000bd40: 7b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 {
    .
    \n-0000bd90: 2020 3238 333c 2f73 7061 6e3e 2020 2020 283 \n-0000bda0: 2020 3c73 7061 6e20 636c 6173 733d 226b if(this->N\n-0000bdd0: 5f2b 7468 6973 2d26 6774 3b4d 5f2b 7468 _+this->M_+th\n-0000bde0: 6973 2d26 6774 3b4e 6e7a 5f21 3d30 293c is->Nnz_!=0)<\n-0000bdf0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000be40: 3238 343c 2f73 7061 6e3e 2020 2020 2020 284 \n-0000be50: 2020 6672 6565 2829 3b3c 2f64 6976 3e0a free();
    .\n-0000be60: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 \n-0000bfd0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000c000: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 286 this-\n-0000c030: 2667 743b 4d5f 3d6d 7273 2e73 697a 6528 >M_=mrs.size(\n-0000c040: 292a 3c61 2063 6c61 7373 3d22 636f 6465 )*MatrixDimensi\n-0000c0a0: 6f6e 266c 743b 7479 7065 6e61 6d65 204d on<typename M\n-0000c0b0: 6174 7269 783a 3a62 6c6f 636b 5f74 7970 atrix::block_typ\n-0000c0c0: 6526 6774 3b3a 3a63 6f6c 6469 6d3c 2f61 e>::coldim(*(mat[0]\n-0000c130: 2e62 6567 696e 2829 2929 3b3c 2f64 6976 .begin()));..
    288 .
    2\n-0000c2d0: 3839 3c2f 7370 616e 3e20 2020 2020 2063 89 c\n-0000c2e0: 6f70 7954 6f42 4343 534d 6174 7269 7828 opyToBCCSMatrix(\n-0000c2f0: 696e 6974 6961 6c69 7a65 722c 2049 5354 initializer, IST\n-0000c300: 4c3a 3a49 6d70 6c3a 3a4d 6174 7269 7852 L::Impl::MatrixR\n-0000c310: 6f77 5375 6273 6574 266c 743b 3c61 2063 owSubset<Matrix,std::set<s\n-0000c360: 7464 3a3a 7369 7a65 5f74 2667 743b 2026 td::size_t> &\n-0000c370: 6774 3b28 3c61 2063 6c61 7373 3d22 636f gt;(mat,mr\n-0000c3d0: 7329 293b 3c2f 6469 763e 0a3c 6469 7620 s));
    .
    290 \n-0000c430: 2020 207d 3c2f 6469 763e 0a3c 6469 7620 }
    .
    291 \n-0000c490: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n-0000c4e0: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-0000c4f0: 7265 663d 2261 3032 3934 302e 6874 6d6c ref=\"a02940.html\n-0000c500: 2361 3663 3635 6631 3237 6138 3464 3533 #a6c65f127a84d53\n-0000c510: 6238 3665 3231 3964 3466 3732 6135 3132 b86e219d4f72a512\n-0000c520: 6337 223e 2020 3239 333c 2f61 3e3c 2f73 c7\"> 293 vi\n-0000c550: 7274 7561 6c3c 2f73 7061 6e3e 203c 7370 rtual void setMatrix(const Matrix&\n-0000c640: 203c 6120 636c 6173 733d 2263 6f64 6520 mat).
    294<\n-0000c6f0: 2f73 7061 6e3e 2020 2020 7b3c 2f64 6976 /span> {.
    295<\n-0000c750: 2f73 7061 6e3e 2020 2020 2020 7468 6973 /span> this\n-0000c760: 2d26 6774 3b4e 5f3d 3c61 2063 6c61 7373 ->N_=MatrixD\n-0000c7c0: 696d 656e 7369 6f6e 266c 743b 4d61 7472 imension<Matr\n-0000c7d0: 6978 2667 743b 3a3a 726f 7764 696d 3c2f ix>::rowdim(mat);.
    2\n-0000c890: 3936 3c2f 7370 616e 3e20 2020 2020 2074 96 t\n-0000c8a0: 6869 732d 2667 743b 4d5f 3d3c 6120 636c his->M_=Matr\n-0000c900: 6978 4469 6d65 6e73 696f 6e26 6c74 3b4d ixDimension<M\n-0000c910: 6174 7269 7826 6774 3b3a 3a63 6f6c 6469 atrix>::coldi\n-0000c920: 6d3c 2f61 3e28 3c61 2063 6c61 7373 3d22 m(mat)\n-0000c980: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-0000c9d0: 2020 3239 373c 2f73 7061 6e3e 2020 2020 297 \n-0000c9e0: 2020 3c61 2063 6c61 7373 3d22 636f 6465 S\n-0000ca10: 7570 6572 4d61 7472 6978 496e 6974 6961 uperMatrixInitia\n-0000ca20: 6c69 7a65 7226 6c74 3b4d 6174 7269 7826 lizer<Matrix&\n-0000ca30: 6774 3b3c 2f61 3e20 696e 6974 6961 6c69 gt; initiali\n-0000ca40: 7a65 7228 2a3c 7370 616e 2063 6c61 7373 zer(*this<\n-0000ca60: 2f73 7061 6e3e 293b 3c2f 6469 763e 0a3c /span>);
    .<\n-0000ca70: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000ca80: 3e3c 6120 6964 3d22 6c30 3032 3938 2220 > 298
    .
    299 \n-0000cb20: 2020 2020 2063 6f70 7954 6f42 4343 534d copyToBCCSM\n-0000cb30: 6174 7269 7828 696e 6974 6961 6c69 7a65 atrix(initialize\n-0000cb40: 722c 203c 6120 636c 6173 733d 2263 6f64 r, mat);.
    3\n-0000cbf0: 3030 3c2f 7370 616e 3e20 2020 207d 3c2f 00 }.
    3\n-0000cc50: 3031 3c2f 7370 616e 3e20 3c2f 6469 763e 01
    \n-0000cc60: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000cc90: 3c2f 613e 3c73 7061 6e20 636c 6173 733d \n-0000ccf0: 3330 333c 2f61 3e3c 2f73 7061 6e3e 2020 303 \n-0000cd00: 2020 3c73 7061 6e20 636c 6173 733d 226b virtual<\n-0000cd20: 2f73 7061 6e3e 203c 7370 616e 2063 6c61 /span> void fr\n-0000cda0: 6565 3c2f 613e 2829 3c2f 6469 763e 0a3c ee()
    .<\n-0000cdb0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000cdc0: 3e3c 6120 6964 3d22 6c30 3033 3034 2220 > 304 {
    .<\n-0000ce10: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000ce20: 3e3c 6120 6964 3d22 6c30 3033 3035 2220 > 305 ISTL::I\n-0000ce70: 6d70 6c3a 3a42 4343 534d 6174 7269 7826 mpl::BCCSMatrix&\n-0000ce80: 6c74 3b74 7970 656e 616d 6520 4243 5253 lt;typename BCRS\n-0000ce90: 4d61 7472 6978 266c 743b 422c 5441 2667 Matrix<B,TA&g\n-0000cea0: 743b 3a3a 6669 656c 645f 7479 7065 2c20 t;::field_type, \n-0000ceb0: 3c73 7061 6e20 636c 6173 733d 226b 6579 int>::free()\n-0000cee0: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-0000cf30: 2020 3330 363c 2f73 7061 6e3e 2020 2020 306 \n-0000cf40: 2020 5355 5045 524c 555f 4652 4545 2841 SUPERLU_FREE(A\n-0000cf50: 2e53 746f 7265 293b 3c2f 6469 763e 0a3c .Store);
    .<\n-0000cf60: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000cf70: 3e3c 6120 6964 3d22 6c30 3033 3037 2220 > 307 }
    .<\n-0000cfc0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000cfd0: 3e3c 6120 6964 3d22 6c30 3033 3038 2220 > 308 priva\n-0000d030: 7465 3c2f 7370 616e 3e3a 3c2f 6469 763e te:
    \n-0000d040: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000d070: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 309 SuperMa\n-0000d0a0: 7472 6978 2041 3b3c 2f64 6976 3e0a 3c64 trix A;
    .\n-0000d0c0: 3c61 2069 643d 226c 3030 3331 3022 206e 310 };
    .<\n-0000d120: 6120 6964 3d22 6c30 3033 3131 2220 6e61 a id=\"l00311\" na\n-0000d130: 6d65 3d22 6c30 3033 3131 223e 3c2f 613e me=\"l00311\">\n-0000d140: 3c73 7061 6e20 636c 6173 733d 226c 696e 311
    .
    312 <\n-0000d1c0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000d1d0: 6f72 6422 3e74 656d 706c 6174 653c 2f73 ord\">template<cl\n-0000d200: 6173 733c 2f73 7061 6e3e 2042 2c20 3c73 ass B, class\n-0000d230: 2041 2667 743b 3c2f 6469 763e 0a3c 6469 A>
    .<\n-0000d250: 6120 6964 3d22 6c30 3033 3133 2220 6e61 a id=\"l00313\" na\n-0000d260: 6d65 3d22 6c30 3033 3133 223e 3c2f 613e me=\"l00313\">\n-0000d270: 3c73 7061 6e20 636c 6173 733d 226c 696e 313 \n-0000d2d0: 636c 6173 7320 3c2f 7370 616e 3e3c 6120 class SuperM\n-0000d310: 6174 7269 7849 6e69 7469 616c 697a 6572 atrixInitializer\n-0000d320: 3c2f 613e 266c 743b 3c61 2063 6c61 7373 <BCRSMatrix<B,A> &g\n-0000d370: 743b 3c2f 6469 763e 0a3c 6469 7620 636c t;
    .
    314 \n-0000d3d0: 203a 203c 7370 616e 2063 6c61 7373 3d22 : public<\n-0000d3f0: 2f73 7061 6e3e 2049 5354 4c3a 3a49 6d70 /span> ISTL::Imp\n-0000d400: 6c3a 3a42 4343 534d 6174 7269 7849 6e69 l::BCCSMatrixIni\n-0000d410: 7469 616c 697a 6572 266c 743b 4243 5253 tializer<BCRS\n-0000d420: 4d61 7472 6978 266c 743b 422c 4126 6774 Matrix<B,A>\n-0000d430: 3b2c 2069 6e74 2667 743b 3c2f 6469 763e ;, int>
    \n-0000d440: 0a3c 6469 7620 636c 6173 733d 226c 696e ..<\n-0000d4a0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000d4b0: 3e3c 6120 6964 3d22 6c30 3033 3136 2220 > 316 tem\n-0000d510: 706c 6174 653c 2f73 7061 6e3e 266c 743b plate<\n-0000d520: 3c73 7061 6e20 636c 6173 733d 226b 6579 class I, clas\n-0000d560: 733c 2f73 7061 6e3e 2053 2c20 3c73 7061 s S, class D\n-0000d590: 2667 743b 3c2f 6469 763e 0a3c 6469 7620 >
    ..
    \n-0000d720: 2020 3331 383c 2f73 7061 6e3e 2020 3c73 318 public:
    .
    319<\n-0000d7f0: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n-0000d810: 7479 7065 6465 663c 2f73 7061 6e3e 203c typedef <\n-0000d820: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-0000d830: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n-0000d840: 3131 3532 2e68 746d 6c22 3e42 4352 534d 1152.html\">BCRSM\n-0000d850: 6174 7269 7826 6c74 3b42 2c41 2667 743b atrix<B,A>\n-0000d860: 3c2f 613e 203c 6120 636c 6173 733d 2263 Matrix;\n-0000d8c0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n-0000d910: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n-0000d920: 7265 663d 2261 3032 3934 342e 6874 6d6c ref=\"a02944.html\n-0000d930: 2361 3261 6139 6564 6637 3161 3239 3735 #a2aa9edf71a2975\n-0000d940: 6338 6562 6631 3332 6362 3663 3461 3530 c8ebf132cb6c4a50\n-0000d950: 3934 223e 2020 3332 303c 2f61 3e3c 2f73 94\"> 320 ty\n-0000d980: 7065 6465 663c 2f73 7061 6e3e 203c 6120 pedef Dune::S\n-0000d9c0: 7570 6572 4c55 4d61 7472 6978 266c 743b uperLUMatrix<\n-0000d9d0: 4d61 7472 6978 2667 743b 3c2f 613e 203c Matrix> <\n-0000d9e0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-0000d9f0: 5f74 7970 6564 6566 2220 6872 6566 3d22 _typedef\" href=\"\n-0000da00: 6130 3239 3434 2e68 746d 6c23 6132 6161 a02944.html#a2aa\n-0000da10: 3965 6466 3731 6132 3937 3563 3865 6266 9edf71a2975c8ebf\n-0000da20: 3133 3263 6236 6334 6135 3039 3422 3e53 132cb6c4a5094\">S\n-0000da30: 7570 6572 4c55 4d61 7472 6978 3c2f 613e uperLUMatrix\n-0000da40: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n-0000da90: 2020 3332 313c 2f73 7061 6e3e 203c 2f64 321 .
    322 SuperMatri\n-0000dba0: 7849 6e69 7469 616c 697a 6572 3c2f 613e xInitializer\n-0000dbb0: 283c 6120 636c 6173 733d 2263 6f64 6520 (Sup\n-0000dbe0: 6572 4c55 4d61 7472 6978 3c2f 613e 2661 erLUMatrix&a\n-0000dbf0: 6d70 3b20 6c75 6d29 203a 2049 5354 4c3a mp; lum) : ISTL:\n-0000dc00: 3a49 6d70 6c3a 3a42 4343 534d 6174 7269 :Impl::BCCSMatri\n-0000dc10: 7849 6e69 7469 616c 697a 6572 266c 743b xInitializer<\n-0000dc20: 3c61 2063 6c61 7373 3d22 636f 6465 2068 BCRS\n-0000dc50: 4d61 7472 6978 3c2f 613e 266c 743b 422c Matrix<B,\n-0000dc60: 4126 6774 3b2c 2069 6e74 2667 743b 286c A>, int>(l\n-0000dc70: 756d 293c 2f64 6976 3e0a 3c64 6976 2063 um)
    .
    323 \n-0000dcd0: 2020 2020 2c73 6c75 6d61 7428 2661 6d70 ,slumat(&\n-0000dce0: 3b6c 756d 293c 2f64 6976 3e0a 3c64 6976 ;lum)
    .<\n-0000dd20: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000dd30: 6e6f 223e 2020 3332 343c 2f73 7061 6e3e no\"> 324\n-0000dd40: 2020 2020 7b7d 3c2f 6469 763e 0a3c 6469 {}
    .<\n-0000dd60: 6120 6964 3d22 6c30 3033 3235 2220 6e61 a id=\"l00325\" na\n-0000dd70: 6d65 3d22 6c30 3033 3235 223e 3c2f 613e me=\"l00325\">\n-0000dd80: 3c73 7061 6e20 636c 6173 733d 226c 696e 325
    .
    326<\n-0000de40: 2f73 7061 6e3e 2020 2020 3c61 2063 6c61 /span> Super\n-0000dea0: 4d61 7472 6978 496e 6974 6961 6c69 7a65 MatrixInitialize\n-0000deb0: 723c 2f61 3e28 2920 3a20 4953 544c 3a3a r() : ISTL::\n-0000dec0: 496d 706c 3a3a 4243 4353 4d61 7472 6978 Impl::BCCSMatrix\n-0000ded0: 496e 6974 6961 6c69 7a65 7226 6c74 3b3c Initializer<<\n-0000dee0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-0000def0: 5f63 6c61 7373 2220 6872 6566 3d22 6130 _class\" href=\"a0\n-0000df00: 3131 3532 2e68 746d 6c22 3e42 4352 534d 1152.html\">BCRSM\n-0000df10: 6174 7269 783c 2f61 3e26 6c74 3b42 2c41 atrix<B,A\n-0000df20: 2667 743b 2c20 696e 7426 6774 3b28 293c >, int>()<\n-0000df30: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000df80: 3332 373c 2f73 7061 6e3e 2020 2020 7b7d 327 {}\n-0000df90: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-0000dfe0: 2033 3238 3c2f 7370 616e 3e20 3c2f 6469 328 .
    \n-0000e080: 2020 3332 393c 2f61 3e3c 2f73 7061 6e3e 329\n-0000e090: 2020 2020 3c73 7061 6e20 636c 6173 733d virtua\n-0000e0b0: 6c3c 2f73 7061 6e3e 203c 7370 616e 2063 l void <\n-0000e0e0: 6120 636c 6173 733d 2263 6f64 6520 686c a class=\"code hl\n-0000e0f0: 5f66 756e 6374 696f 6e22 2068 7265 663d _function\" href=\n-0000e100: 2261 3032 3934 342e 6874 6d6c 2361 3838 \"a02944.html#a88\n-0000e110: 3730 3032 6638 3337 3731 3134 3536 3038 7002f83771145608\n-0000e120: 3036 3834 3431 6636 3638 3636 3766 223e 068441f668667f\">\n-0000e130: 6372 6561 7465 4d61 7472 6978 3c2f 613e createMatrix\n-0000e140: 2829 3c73 7061 6e20 636c 6173 733d 226b () const
    .<\n-0000e1a0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n-0000e1b0: 6e6f 223e 2020 3333 303c 2f73 7061 6e3e no\"> 330\n-0000e1c0: 3c73 7061 6e20 636c 6173 733d 226b 6579 {
    .
    331 \n-0000e240: 2020 2049 5354 4c3a 3a49 6d70 6c3a 3a42 ISTL::Impl::B\n-0000e250: 4343 534d 6174 7269 7849 6e69 7469 616c CCSMatrixInitial\n-0000e260: 697a 6572 266c 743b 4243 5253 4d61 7472 izer<BCRSMatr\n-0000e270: 6978 266c 743b 422c 4126 6774 3b2c 203c ix<B,A>, <\n-0000e280: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n-0000e290: 6f72 6474 7970 6522 3e69 6e74 3c2f 7370 ordtype\">int>::createM\n-0000e2b0: 6174 7269 7828 293b 3c2f 6469 763e 0a3c atrix();
    .<\n-0000e2c0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-0000e2d0: 3e3c 6120 6964 3d22 6c30 3033 3332 2220 > 332 SuperMatri\n-0000e350: 7843 7265 6174 6553 7061 7273 6543 686f xCreateSparseCho\n-0000e360: 6f73 6572 266c 743b 7479 7065 6e61 6d65 oser<typename\n-0000e370: 204d 6174 7269 783a 3a66 6965 6c64 5f74 Matrix::field_t\n-0000e380: 7970 6526 6774 3b3c 2f61 3e3c 2f64 6976 ype>.
    333<\n-0000e3e0: 2f73 7061 6e3e 3c61 2063 6c61 7373 3d22 /span> ::\n-0000e420: 6372 6561 7465 3c2f 613e 2826 616d 703b create(&\n-0000e430: 736c 756d 6174 2d26 6774 3b41 2c20 736c slumat->A, sl\n-0000e440: 756d 6174 2d26 6774 3b4e 5f2c 2073 6c75 umat->N_, slu\n-0000e450: 6d61 742d 2667 743b 4d5f 2c20 736c 756d mat->M_, slum\n-0000e460: 6174 2d26 6774 3b63 6f6c 7374 6172 745b at->colstart[\n-0000e470: 7468 6973 2d26 6774 3b63 6f6c 735d 2c3c this->cols],<\n-0000e480: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000e4d0: 3333 343c 2f73 7061 6e3e 2020 2020 2020 334 \n-0000e4e0: 2020 2020 2020 2073 6c75 6d61 742d 2667 slumat-&g\n-0000e4f0: 743b 7661 6c75 6573 2c73 6c75 6d61 742d t;values,slumat-\n-0000e500: 2667 743b 726f 7769 6e64 6578 2c20 736c >rowindex, sl\n-0000e510: 756d 6174 2d26 6774 3b63 6f6c 7374 6172 umat->colstar\n-0000e520: 742c 2053 4c55 5f4e 432c 3c2f 6469 763e t, SLU_NC,
    \n-0000e530: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000e560: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 335 \n-0000e590: 2020 3c73 7061 6e20 636c 6173 733d 226b static_c\n-0000e5b0: 6173 7426 6c74 3b3c 2f73 7061 6e3e 4474 ast<Dt\n-0000e5c0: 7970 655f 743c 7370 616e 2063 6c61 7373 ype_t><\n-0000e5e0: 2f73 7061 6e3e 283c 6120 636c 6173 733d /span>(GetSuperLUTy\n-0000e620: 7065 266c 743b 7479 7065 6e61 6d65 204d pe<typename M\n-0000e630: 6174 7269 783a 3a66 6965 6c64 5f74 7970 atrix::field_typ\n-0000e640: 6526 6774 3b3a 3a74 7970 653c 2f61 3e29 e>::type)\n-0000e650: 2c20 534c 555f 4745 293b 3c2f 6469 763e , SLU_GE);
    \n-0000e660: 0a3c 6469 7620 636c 6173 733d 226c 696e .\n-0000e6c0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-0000e6f0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 337 p\n-0000e730: 7269 7661 7465 3c2f 7370 616e 3e3a 3c2f rivate:.
    3\n-0000e790: 3338 3c2f 7370 616e 3e20 2020 203c 6120 38 SuperL\n-0000e7d0: 554d 6174 7269 783c 2f61 3e2a 2073 6c75 UMatrix* slu\n-0000e7e0: 6d61 743b 3c2f 6469 763e 0a3c 6469 7620 mat;
    .
    339 \n-0000e840: 207d 3b3c 2f64 6976 3e0a 3c64 6976 2063 };
    .
    340}<\n-0000e8a0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000e8f0: 3334 313c 2f73 7061 6e3e 3c73 7061 6e20 341#endif // HAVE\n-0000e940: 5f53 5550 4552 4c55 3c2f 7370 616e 3e3c _SUPERLU<\n-0000e950: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000e9a0: 3334 323c 2f73 7061 6e3e 3c73 7061 6e20 342#endif
    .
    \n-0000ea10: 3c61 2068 7265 663d 2261 3030 3032 302e superlufun\n-0000ea30: 6374 696f 6e73 2e68 683c 2f61 3e3c 2f64 ctions.hh
    .
    Th\n-0000eac0: 6973 2066 696c 6520 696d 706c 656d 656e is file implemen\n-0000ead0: 7473 2061 2076 6563 746f 7220 7370 6163 ts a vector spac\n-0000eae0: 6520 6173 2061 2074 656e 736f 7220 7072 e as a tensor pr\n-0000eaf0: 6f64 7563 7420 6f66 2061 2067 6976 656e oduct of a given\n-0000eb00: 2076 6563 746f 7220 7370 6163 652e 2054 vector space. T\n-0000eb10: 6865 206e 756d 6265 7220 6f66 2063 6f6d he number of com\n-0000eb20: 706f 6e2e 2e2e 3c2f 6469 763e 3c2f 6469 pon...
    ...
    mat
    Matrix &\n-0000ed10: 616d 703b 206d 6174 3c2f 6469 763e 3c64 amp; mat
    Definition:<\n-0000ed40: 2f62 3e20 6d61 7472 6978 6d61 7472 6978 /b> matrixmatrix\n-0000ed50: 2e68 683a 3334 373c 2f64 6976 3e3c 2f64 .hh:347
    .
    STL namespace.<\n-0000ede0: 2f64 6976 3e3c 2f64 6976 3e0a 3c64 6976 /div>
    .<\n-0000ee10: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n-0000ee20: 6522 3e3c 6120 6872 6566 3d22 6130 3032 e\">Dune
    .
    \n-0000eec0: 3c61 2068 7265 663d 2261 3031 3132 302e Dune::Over\n-0000eee0: 6c61 7070 696e 6753 6368 7761 727a 496e lappingSchwarzIn\n-0000eef0: 6974 6961 6c69 7a65 723c 2f61 3e3c 2f64 itializer
    Initialize\n-0000ef20: 7220 666f 7220 5375 7065 724c 5520 4d61 r for SuperLU Ma\n-0000ef30: 7472 6963 6573 2072 6570 7265 7365 6e74 trices represent\n-0000ef40: 696e 6720 7468 6520 7375 6264 6f6d 6169 ing the subdomai\n-0000ef50: 6e73 2e3c 2f64 6976 3e3c 6469 7620 636c ns.
    D\n-0000ef70: 6566 696e 6974 696f 6e3a 3c2f 623e 206f efinition: o\n-0000ef80: 7665 726c 6170 7069 6e67 7363 6877 6172 verlappingschwar\n-0000ef90: 7a2e 6868 3a34 373c 2f64 6976 3e3c 2f64 z.hh:47
    .
    \n-0000f070: 7374 6174 6963 2061 7574 6f20 636f 6c64 static auto cold\n-0000f080: 696d 2863 6f6e 7374 204d 2026 616d 703b im(const M &\n-0000f090: 4129 3c2f 6469 763e 3c64 6976 2063 6c61 A)
    De\n-0000f0b0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 6d61 finition: ma\n-0000f0c0: 7472 6978 7574 696c 732e 6868 3a32 3139 trixutils.hh:219\n-0000f0d0: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
    .
    Du\n-0000f170: 6e65 3a3a 4d61 7472 6978 4469 6d65 6e73 ne::MatrixDimens\n-0000f180: 696f 6e3a 3a72 6f77 6469 6d3c 2f61 3e3c ion::rowdim<\n-0000f190: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    static \n-0000f1b0: 6175 746f 2072 6f77 6469 6d28 636f 6e73 auto rowdim(cons\n-0000f1c0: 7420 4d20 2661 6d70 3b41 293c 2f64 6976 t M &A)
    Definitio\n-0000f1f0: 6e3a 3c2f 623e 206d 6174 7269 7875 7469 n: matrixuti\n-0000f200: 6c73 2e68 683a 3231 343c 2f64 6976 3e3c ls.hh:214
    <\n-0000f210: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-0000f290: 4120 7370 6172 7365 2062 6c6f 636b 206d A sparse block m\n-0000f2a0: 6174 7269 7820 7769 7468 2063 6f6d 7072 atrix with compr\n-0000f2b0: 6573 7365 6420 726f 7720 7374 6f72 6167 essed row storag\n-0000f2c0: 652e 3c2f 6469 763e 3c64 6976 2063 6c61 e.
    De\n-0000f2e0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 6263 finition: bc\n-0000f2f0: 7273 6d61 7472 6978 2e68 683a 3436 363c rsmatrix.hh:466<\n-0000f300: 2f64 6976 3e3c 2f64 6976 3e0a 3c64 6976 /div>
    .
    Dun\n-0000f3a0: 653a 3a42 4352 534d 6174 7269 783a 3a73 e::BCRSMatrix::s\n-0000f3b0: 697a 655f 7479 7065 3c2f 613e 3c2f 6469 ize_type
    A::size_ty\n-0000f3e0: 7065 2073 697a 655f 7479 7065 3c2f 6469 pe size_type
    The type fo\n-0000f410: 7220 7468 6520 696e 6465 7820 6163 6365 r the index acce\n-0000f420: 7373 2061 6e64 2074 6865 2073 697a 652e ss and the size.\n-0000f430: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Defi\n-0000f450: 6e69 7469 6f6e 3a3c 2f62 3e20 6263 7273 nition: bcrs\n-0000f460: 6d61 7472 6978 2e68 683a 3530 303c 2f64 matrix.hh:500
    .S\n-0000f500: 6571 7565 6e74 6961 6c20 6f76 6572 6c61 equential overla\n-0000f510: 7070 696e 6720 5363 6877 6172 7a20 7072 pping Schwarz pr\n-0000f520: 6563 6f6e 6469 7469 6f6e 6572 2e3c 2f64 econditioner.
    Definit\n-0000f550: 696f 6e3a 3c2f 623e 206f 7665 726c 6170 ion: overlap\n-0000f560: 7069 6e67 7363 6877 6172 7a2e 6868 3a37 pingschwarz.hh:7\n-0000f570: 3535 3c2f 6469 763e 3c2f 6469 763e 0a3c 55
    .<\n-0000f580: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000f590: 6964 3d22 6161 3031 3431 365f 6874 6d6c id=\"aa01416_html\n-0000f5a0: 223e 3c64 6976 2063 6c61 7373 3d22 7474 \">\n-0000f600: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    Definition\n-0000f620: 3a3c 2f62 3e20 6f76 6572 6c61 7070 696e : overlappin\n-0000f630: 6773 6368 7761 727a 2e68 683a 3639 343c gschwarz.hh:694<\n-0000f640: 2f64 6976 3e3c 2f64 6976 3e0a 3c64 6976 /div>
    .<\n-0000f670: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n-0000f680: 6522 3e3c 6120 6872 6566 3d22 6130 3238 e\">Dune::S\n-0000f6a0: 7570 6572 4c55 3c2f 613e 3c2f 6469 763e uperLU
    \n-0000f6b0: 3c64 6976 2063 6c61 7373 3d22 7474 646f
    SuperLu Solve\n-0000f6d0: 722e 3c2f 6469 763e 3c64 6976 2063 6c61 r.
    De\n-0000f6f0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7375 finition: su\n-0000f700: 7065 726c 752e 6868 3a32 3731 3c2f 6469 perlu.hh:271
    .
    \n-0000f750: 3c61 2068 7265 663d 2261 3032 3930 302e Dune::Supe\n-0000f770: 724d 6174 7269 7843 7265 6174 6553 7061 rMatrixCreateSpa\n-0000f780: 7273 6543 686f 6f73 6572 3c2f 613e 3c2f rseChooser
    Defini\n-0000f7b0: 7469 6f6e 3a3c 2f62 3e20 7375 7065 726d tion: superm\n-0000f7c0: 6174 7269 782e 6868 3a32 363c 2f64 6976 atrix.hh:26
    .
    <\n-0000f810: 6120 6872 6566 3d22 6130 3239 3034 2e68 a href=\"a02904.h\n-0000f820: 746d 6c22 3e44 756e 653a 3a53 7570 6572 tml\">Dune::Super\n-0000f830: 4d61 7472 6978 5072 696e 7465 723c 2f61 MatrixPrinter
    Def\n-0000f860: 696e 6974 696f 6e3a 3c2f 623e 2073 7570 inition: sup\n-0000f870: 6572 6d61 7472 6978 2e68 683a 3330 3c2f ermatrix.hh:30
    .
    \n-0000f910: 4465 6669 6e69 7469 6f6e 3a3c 2f62 3e20 Definition: \n-0000f920: 7375 7065 726d 6174 7269 782e 6868 3a31 supermatrix.hh:1\n-0000f930: 3236 3c2f 6469 763e 3c2f 6469 763e 0a3c 26
    .<\n-0000f940: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n-0000f950: 6964 3d22 6161 3032 3930 385f 6874 6d6c id=\"aa02908_html\n-0000f960: 5f61 3963 3030 3836 6463 3865 3665 3236 _a9c0086dc8e6e26\n-0000f970: 6630 3231 3738 3135 6534 3961 6461 6335 f0217815e49adac5\n-0000f980: 6631 223e 3c64 6976 2063 6c61 7373 3d22 f1\">
    .\n-0000fa70: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    Definition:\n-0000fb00: 2073 7570 6572 6d61 7472 6978 2e68 683a supermatrix.hh:\n-0000fb10: 3133 323c 2f64 6976 3e3c 2f64 6976 3e0a 132
    .\n-0000fb20: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    d\n-0000fc00: 6f75 626c 6520 666c 6f61 745f 7479 7065 ouble float_type\n-0000fc10: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Defi\n-0000fc30: 6e69 7469 6f6e 3a3c 2f62 3e20 7375 7065 nition: supe\n-0000fc40: 726d 6174 7269 782e 6868 3a31 3434 3c2f rmatrix.hh:144
    .
    \n-0000fca0: 3c64 6976 2063 6c61 7373 3d22 7474 6e61
    Dune\n-0000fcf0: 3a3a 4765 7453 7570 6572 4c55 5479 7065 ::GetSuperLUType\n-0000fd00: 266c 743b 2066 6c6f 6174 2026 6774 3b3a < float >:\n-0000fd10: 3a66 6c6f 6174 5f74 7970 653c 2f61 3e3c :float_type<\n-0000fd20: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    float f\n-0000fd40: 6c6f 6174 5f74 7970 653c 2f64 6976 3e3c loat_type
    <\n-0000fd50: 6469 7620 636c 6173 733d 2274 7464 6566 div class=\"ttdef\n-0000fd60: 223e 3c62 3e44 6566 696e 6974 696f 6e3a \">Definition:\n-0000fd70: 3c2f 623e 2073 7570 6572 6d61 7472 6978 supermatrix\n-0000fd80: 2e68 683a 3135 313c 2f64 6976 3e3c 2f64 .hh:151
    .
    Dune::GetSu\n-0000fe30: 7065 724c 5554 7970 6526 6c74 3b20 7374 perLUType< st\n-0000fe40: 643a 3a63 6f6d 706c 6578 266c 743b 2064 d::complex< d\n-0000fe50: 6f75 626c 6520 2667 743b 2026 6774 3b3a ouble > >:\n-0000fe60: 3a66 6c6f 6174 5f74 7970 653c 2f61 3e3c :float_type<\n-0000fe70: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    double \n-0000fe90: 666c 6f61 745f 7479 7065 3c2f 6469 763e float_type
    \n-0000fea0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    Definition\n-0000fec0: 3a3c 2f62 3e20 7375 7065 726d 6174 7269 : supermatri\n-0000fed0: 782e 6868 3a31 3538 3c2f 6469 763e 3c2f x.hh:158
    .
    Dune::GetS\n-0000ff80: 7570 6572 4c55 5479 7065 266c 743b 2073 uperLUType< s\n-0000ff90: 7464 3a3a 636f 6d70 6c65 7826 6c74 3b20 td::complex< \n-0000ffa0: 666c 6f61 7420 2667 743b 2026 6774 3b3a float > >:\n-0000ffb0: 3a66 6c6f 6174 5f74 7970 653c 2f61 3e3c :float_type<\n-0000ffc0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    float f\n-0000ffe0: 6c6f 6174 5f74 7970 653c 2f64 6976 3e3c loat_type
    <\n-0000fff0: 6469 7620 636c 6173 733d 2274 7464 6566 div class=\"ttdef\n-00010000: 223e 3c62 3e44 6566 696e 6974 696f 6e3a \">Definition:\n-00010010: 3c2f 623e 2073 7570 6572 6d61 7472 6978 supermatrix\n-00010020: 2e68 683a 3136 353c 2f64 6976 3e3c 2f64 .hh:165
    .
    Utility class f\n-000100c0: 6f72 2063 6f6e 7665 7274 696e 6720 616e or converting an\n-000100d0: 2049 5354 4c20 4d61 7472 6978 2069 6e74 ISTL Matrix int\n-000100e0: 6f20 6120 5375 7065 724c 5520 4d61 7472 o a SuperLU Matr\n-000100f0: 6978 2e3c 2f64 6976 3e3c 6469 7620 636c ix.
    D\n-00010110: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n-00010120: 7570 6572 6d61 7472 6978 2e68 683a 3137 upermatrix.hh:17\n-00010130: 353c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 5
    .
    Dune:\n-00010190: 3a53 7570 6572 4d61 7472 6978 496e 6974 :SuperMatrixInit\n-000101a0: 6961 6c69 7a65 723c 2f61 3e3c 2f64 6976 ializer
    Definitio\n-000101d0: 6e3a 3c2f 623e 2073 7570 6572 6d61 7472 n: supermatr\n-000101e0: 6978 2e68 683a 3137 393c 2f64 6976 3e3c ix.hh:179
    <\n-000101f0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    <\n-00010250: 6120 6872 6566 3d22 6130 3239 3430 2e68 a href=\"a02940.h\n-00010260: 746d 6c23 6131 3438 3466 6535 6561 6237 tml#a1484fe5eab7\n-00010270: 3634 3836 6539 6262 3866 6362 6332 6162 6486e9bb8fcbc2ab\n-00010280: 3738 3537 6322 3e44 756e 653a 3a53 7570 7857c\">Dune::Sup\n-00010290: 6572 4c55 4d61 7472 6978 266c 743b 2042 erLUMatrix< B\n-000102a0: 4352 534d 6174 7269 7826 6c74 3b20 422c CRSMatrix< B,\n-000102b0: 2054 4120 2667 743b 2026 6774 3b3a 3a66 TA > >::f\n-000102c0: 7265 653c 2f61 3e3c 2f64 6976 3e3c 6469 ree
    virtual void fr\n-000102f0: 6565 2829 3c2f 6469 763e 3c64 6976 2063 ee()
    fre\n-00010310: 6520 616c 6c6f 6361 7465 6420 7370 6163 e allocated spac\n-00010320: 652e 3c2f 6469 763e 3c64 6976 2063 6c61 e.
    De\n-00010340: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7375 finition: su\n-00010350: 7065 726d 6174 7269 782e 6868 3a33 3033 permatrix.hh:303\n-00010360: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
    .
    Sup\n-00010460: 6572 4c55 4d61 7472 6978 266c 743b 2042 erLUMatrix< B\n-00010470: 4352 534d 6174 7269 7826 6c74 3b20 422c CRSMatrix< B,\n-00010480: 2054 4120 2667 743b 2026 6774 3b20 2661 TA > > &a\n-00010490: 6d70 3b20 6f70 6572 6174 6f72 3d28 636f mp; operator=(co\n-000104a0: 6e73 7420 5375 7065 724c 554d 6174 7269 nst SuperLUMatri\n-000104b0: 7826 6c74 3b20 4243 5253 4d61 7472 6978 x< BCRSMatrix\n-000104c0: 266c 743b 2042 2c20 5441 2026 6774 3b20 < B, TA > \n-000104d0: 2667 743b 2026 616d 703b 6d61 7429 3c2f > &mat)
    Defini\n-00010500: 7469 6f6e 3a3c 2f62 3e20 7375 7065 726d tion: superm\n-00010510: 6174 7269 782e 6868 3a32 3536 3c2f 6469 atrix.hh:256
    .
    Dune::\n-000105c0: 5375 7065 724c 554d 6174 7269 7826 6c74 SuperLUMatrix<\n-000105d0: 3b20 4243 5253 4d61 7472 6978 266c 743b ; BCRSMatrix<\n-000105e0: 2042 2c20 5441 2026 6774 3b20 2667 743b B, TA > >\n-000105f0: 3a3a 6f70 6572 6174 6f72 3d3c 2f61 3e3c ::operator=<\n-00010600: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    SuperLU\n-00010620: 4d61 7472 6978 266c 743b 2042 4352 534d Matrix< BCRSM\n-00010630: 6174 7269 7826 6c74 3b20 422c 2054 4120 atrix< B, TA \n-00010640: 2667 743b 2026 6774 3b20 2661 6d70 3b20 > > & \n-00010650: 6f70 6572 6174 6f72 3d28 636f 6e73 7420 operator=(const \n-00010660: 4243 5253 4d61 7472 6978 266c 743b 2042 BCRSMatrix< B\n-00010670: 2c20 5441 2026 6774 3b20 2661 6d70 3b6d , TA > &m\n-00010680: 6174 293c 2f64 6976 3e3c 6469 7620 636c at)
    D\n-000106a0: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n-000106b0: 7570 6572 6d61 7472 6978 2e68 683a 3233 upermatrix.hh:23\n-000106c0: 373c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 7
    .SuperLUMatrix(\n-000107d0: 636f 6e73 7420 4d61 7472 6978 2026 616d const Matrix &am\n-000107e0: 703b 6d61 7429 3c2f 6469 763e 3c64 6976 p;mat)
    C\n-00010800: 6f6e 7374 7275 6374 6f72 2074 6861 7420 onstructor that \n-00010810: 696e 6974 6961 6c69 7a65 7320 7468 6520 initializes the \n-00010820: 6461 7461 2e3c 2f64 6976 3e3c 6469 7620 data.
    Definition:\n-00010850: 2073 7570 6572 6d61 7472 6978 2e68 683a supermatrix.hh:\n-00010860: 3231 323c 2f64 6976 3e3c 2f64 6976 3e0a 212
    .\n-00010870: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    \n-00010960: 7669 7274 7561 6c20 766f 6964 2073 6574 virtual void set\n-00010970: 4d61 7472 6978 2863 6f6e 7374 204d 6174 Matrix(const Mat\n-00010980: 7269 7820 2661 6d70 3b6d 6174 293c 2f64 rix &mat)
    Initialize\n-000109b0: 2064 6174 6120 6672 6f6d 2067 6976 656e data from given\n-000109c0: 206d 6174 7269 782e 3c2f 6469 763e 3c64 matrix.
    Definition:<\n-000109f0: 2f62 3e20 7375 7065 726d 6174 7269 782e /b> supermatrix.\n-00010a00: 6868 3a32 3933 3c2f 6469 763e 3c2f 6469 hh:293
    .
    Dune::SuperL\n-00010ab0: 554d 6174 7269 7826 6c74 3b20 4243 5253 UMatrix< BCRS\n-00010ac0: 4d61 7472 6978 266c 743b 2042 2c20 5441 Matrix< B, TA\n-00010ad0: 2026 6774 3b20 2667 743b 3a3a 5375 7065 > >::Supe\n-00010ae0: 724c 554d 6174 7269 783c 2f61 3e3c 2f64 rLUMatrix
    SuperLUMa\n-00010b10: 7472 6978 2829 3c2f 6469 763e 3c64 6976 trix()
    <\n-00010b30: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: supermatrix.hh\n-00010b50: 3a32 3135 3c2f 6469 763e 3c2f 6469 763e :215
    \n-00010b60: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    Matrix::size_ty\n-00010c60: 7065 2073 697a 655f 7479 7065 3c2f 6469 pe size_type
    Definiti\n-00010c90: 6f6e 3a3c 2f62 3e20 7375 7065 726d 6174 on: supermat\n-00010ca0: 7269 782e 6868 3a32 3036 3c2f 6469 763e rix.hh:206
    \n-00010cb0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .\n-00010d90: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    BCRSMatrix&l\n-00010db0: 743b 2042 2c20 5441 2026 6774 3b20 4d61 t; B, TA > Ma\n-00010dc0: 7472 6978 3c2f 6469 763e 3c64 6976 2063 trix
    The\n-00010de0: 2074 7970 6520 6f66 2074 6865 206d 6174 type of the mat\n-00010df0: 7269 7820 746f 2063 6f6e 7665 7274 2e3c rix to convert.<\n-00010e00: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    Defin\n-00010e20: 6974 696f 6e3a 3c2f 623e 2073 7570 6572 ition: super\n-00010e30: 6d61 7472 6978 2e68 683a 3230 323c 2f64 matrix.hh:202
    .
    <\n-00010e90: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n-00010ea0: 6522 3e3c 6120 6872 6566 3d22 6130 3239 e\">Dune:\n-00010ee0: 3a53 7570 6572 4c55 4d61 7472 6978 266c :SuperLUMatrix&l\n-00010ef0: 743b 2042 4352 534d 6174 7269 7826 6c74 t; BCRSMatrix<\n-00010f00: 3b20 422c 2054 4120 2667 743b 2026 6774 ; B, TA > >\n-00010f10: 3b3a 3a73 6574 4d61 7472 6978 3c2f 613e ;::setMatrix\n-00010f20: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    virtua\n-00010f40: 6c20 766f 6964 2073 6574 4d61 7472 6978 l void setMatrix\n-00010f50: 2863 6f6e 7374 204d 6174 7269 7820 2661 (const Matrix &a\n-00010f60: 6d70 3b6d 6174 2c20 636f 6e73 7420 7374 mp;mat, const st\n-00010f70: 643a 3a73 6574 266c 743b 2073 7464 3a3a d::set< std::\n-00010f80: 7369 7a65 5f74 2026 6774 3b20 2661 6d70 size_t > &\n-00010f90: 3b6d 7273 293c 2f64 6976 3e3c 6469 7620 ;mrs)
    In\n-00010fb0: 6974 6961 6c69 7a65 2064 6174 6120 6672 itialize data fr\n-00010fc0: 6f6d 2061 2067 6976 656e 2073 6574 206f om a given set o\n-00010fd0: 6620 6d61 7472 6978 2072 6f77 7320 616e f matrix rows an\n-00010fe0: 6420 636f 6c75 6d6e 732e 3c2f 6469 763e d columns.
    \n-00010ff0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    Definition\n-00011010: 3a3c 2f62 3e20 7375 7065 726d 6174 7269 : supermatri\n-00011020: 782e 6868 3a32 3831 3c2f 6469 763e 3c2f x.hh:281
    .
    Dune::Supe\n-000110d0: 724c 554d 6174 7269 7826 6c74 3b20 4243 rLUMatrix< BC\n-000110e0: 5253 4d61 7472 6978 266c 743b 2042 2c20 RSMatrix< B, \n-000110f0: 5441 2026 6774 3b20 2667 743b 3a3a 7e53 TA > >::~S\n-00011100: 7570 6572 4c55 4d61 7472 6978 3c2f 613e uperLUMatrix\n-00011110: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    virtua\n-00011130: 6c20 7e53 7570 6572 4c55 4d61 7472 6978 l ~SuperLUMatrix\n-00011140: 2829 3c2f 6469 763e 3c64 6976 2063 6c61 ()
    Destr\n-00011160: 7563 746f 722e 3c2f 6469 763e 3c64 6976 uctor.
    <\n-00011180: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: supermatrix.hh\n-000111a0: 3a32 3139 3c2f 6469 763e 3c2f 6469 763e :219
    \n-000111b0: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    Dun\n-000112b0: 653a 3a53 7570 6572 4c55 4d61 7472 6978 e::SuperLUMatrix\n-000112c0: 266c 743b 204d 6174 7269 7820 2667 743b < Matrix >\n-000112d0: 2053 7570 6572 4c55 4d61 7472 6978 3c2f SuperLUMatrix
    Defini\n-00011300: 7469 6f6e 3a3c 2f62 3e20 7375 7065 726d tion: superm\n-00011310: 6174 7269 782e 6868 3a33 3230 3c2f 6469 atrix.hh:320
    .
    BC\n-00011420: 5253 4d61 7472 6978 266c 743b 2042 2c20 RSMatrix< B, \n-00011430: 4120 2667 743b 204d 6174 7269 783c 2f64 A > Matrix
    Definit\n-00011460: 696f 6e3a 3c2f 623e 2073 7570 6572 6d61 ion: superma\n-00011470: 7472 6978 2e68 683a 3331 393c 2f64 6976 trix.hh:319
    .
    .\n-000115f0: 3c64 6976 2063 6c61 7373 3d22 7474 6322 ..<\n-00011920: 6872 2063 6c61 7373 3d22 666f 6f74 6572 hr class=\"footer\n-00011930: 222f 3e3c 6164 6472 6573 7320 636c 6173 \"/>
    .Generated by&\n-00011960: 2331 3630 3b3c 6120 6872 6566 3d22 6874 #160;\"doxygen\"/<\n-000119e0: 2f61 3e20 312e 392e 340a 3c2f 736d 616c /a> 1.9.4.
    ...\n+0000aaa0: 6f72 6474 7970 6522 3e62 6f6f 6c3c 2f73 ordtype\">bool matrixIsLoa\n+0000aac0: 6465 645f 3b3c 2f64 6976 3e0a 3c64 6976 ded_;
    .<\n+0000ab00: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000ab10: 6e6f 223e 2020 3331 343c 2f73 7061 6e3e no\"> 314\n+0000ab20: 2020 2020 3c73 7061 6e20 636c 6173 733d in\n+0000ab40: 743c 2f73 7061 6e3e 2076 6572 626f 7365 t verbose\n+0000ab50: 5f3b 3c2f 6469 763e 0a3c 6469 7620 636c _;
    .
    315 \n+0000abb0: 2063 686f 6c6d 6f64 5f63 6f6d 6d6f 6e2a cholmod_common*\n+0000abc0: 2063 635f 3b3c 2f64 6976 3e0a 3c64 6976 cc_;
    .<\n+0000ac00: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000ac10: 6e6f 223e 2020 3331 363c 2f73 7061 6e3e no\"> 316\n+0000ac20: 2020 2020 6368 6f6c 6d6f 645f 7370 6172 cholmod_spar\n+0000ac30: 7365 2a20 415f 3b3c 2f64 6976 3e0a 3c64 se* A_;
    .\n+0000ac50: 3c61 2069 643d 226c 3030 3331 3722 206e 317 cholmod_de\n+0000aca0: 6e73 652a 2042 5f3b 3c2f 6469 763e 0a3c nse* B_;
    .<\n+0000acb0: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+0000acc0: 3e3c 6120 6964 3d22 6c30 3033 3138 2220 > 318 SuiteSpar\n+0000ad10: 7365 5152 5f66 6163 746f 7269 7a61 7469 seQR_factorizati\n+0000ad20: 6f6e 266c 743b 5426 6774 3b2a 2073 7071 on<T>* spq\n+0000ad30: 7266 6163 746f 7269 7a61 7469 6f6e 5f3b rfactorization_;\n+0000ad40: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000ad90: 2033 3139 3c2f 7370 616e 3e20 207d 3b3c 319 };<\n+0000ada0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+0000adf0: 3332 303c 2f73 7061 6e3e 203c 2f64 6976 320 .
    321<\n+0000ae50: 2f73 7061 6e3e 2020 3c73 7061 6e20 636c /span> te\n+0000ae70: 6d70 6c61 7465 3c2f 7370 616e 3e26 6c74 mplate<\n+0000ae80: 3b3c 7370 616e 2063 6c61 7373 3d22 6b65 ;typename<\n+0000aea0: 2f73 7061 6e3e 2054 2c20 3c73 7061 6e20 /span> T, \n+0000aec0: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n+0000aed0: 4126 6774 3b3c 2f64 6976 3e0a 3c64 6976 A>
    .<\n+0000af10: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000af20: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 322\n+0000af50: 3c2f 7370 616e 3e20 203c 7370 616e 2063 s\n+0000af70: 7472 7563 7420 3c2f 7370 616e 3e3c 6120 truct IsDire\n+0000afb0: 6374 536f 6c76 6572 3c2f 613e 266c 743b ctSolver<\n+0000afc0: 3c61 2063 6c61 7373 3d22 636f 6465 2068 SPQR\n+0000aff0: 3c2f 613e 266c 743b 3c61 2063 6c61 7373 <BCRSMatrix<T,A> &g\n+0000b040: 743b 2026 6774 3b3c 2f64 6976 3e0a 3c64 t; >
    .\n+0000b060: 3c61 2069 643d 226c 3030 3332 3322 206e 323 {
    .<\n+0000b0e0: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000b0f0: 6e6f 223e 3c61 2063 6c61 7373 3d22 6c69 no\"> 32\n+0000b160: 343c 2f61 3e3c 2f73 7061 6e3e 2020 2020 4 \n+0000b170: 3c73 7061 6e20 636c 6173 733d 226b 6579 enum {value \n+0000b210: 3d20 3c73 7061 6e20 636c 6173 733d 226b = true};
    .<\n+0000b270: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000b280: 6e6f 223e 2020 3332 353c 2f73 7061 6e3e no\"> 325
    \n+0000b290: 2020 7d3b 3c2f 6469 763e 0a3c 6469 7620 };
    .
    326 \n+0000b2f0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000b340: 2033 3237 3c2f 7370 616e 3e20 203c 7370 327 template<type\n+0000b390: 6e61 6d65 3c2f 7370 616e 3e20 542c 203c name T, <\n+0000b3a0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+0000b3b0: 6f72 6422 3e74 7970 656e 616d 653c 2f73 ord\">typename A>
    \n+0000b3d0: 0a3c 6469 7620 636c 6173 733d 226c 696e ..
    329 \n+0000b5a0: 207b 3c2f 6469 763e 0a3c 6469 7620 636c {
    .
    330 enum {\n+0000b690: 3c61 2063 6c61 7373 3d22 636f 6465 2068 value = <\n+0000b710: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+0000b720: 6f72 6422 3e74 7275 653c 2f73 7061 6e3e ord\">true\n+0000b730: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
    .
    331 }\n+0000b790: 3b3c 2f64 6976 3e0a 3c64 6976 2063 6c61 ;
    .
    \n+0000b7e0: 2020 3333 323c 2f73 7061 6e3e 203c 2f64 332 .
    \n+0000b860: 2033 3333 3c2f 613e 3c2f 7370 616e 3e20 333 \n+0000b870: 203c 7370 616e 2063 6c61 7373 3d22 6b65 struct SPQRCreator {
    .
    334 t\n+0000b970: 656d 706c 6174 653c 2f73 7061 6e3e 266c emplate&l\n+0000b980: 743b 3c73 7061 6e20 636c 6173 733d 226b t;class> s\n+0000b9c0: 7472 7563 7420 3c2f 7370 616e 3e3c 6120 truct isVali\n+0000ba00: 6442 6c6f 636b 3c2f 613e 203a 2073 7464 dBlock : std\n+0000ba10: 3a3a 6661 6c73 655f 7479 7065 7b7d 3b3c ::false_type{};<\n+0000ba20: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+0000ba70: 3333 353c 2f73 7061 6e3e 203c 2f64 6976 335 .
    336<\n+0000bad0: 2f73 7061 6e3e 2020 2020 3c73 7061 6e20 /span> \n+0000baf0: 7465 6d70 6c61 7465 3c2f 7370 616e 3e26 template&\n+0000bb00: 6c74 3b3c 7370 616e 2063 6c61 7373 3d22 lt;typenam\n+0000bb20: 653c 2f73 7061 6e3e 2054 4c2c 203c 7370 e TL, typename M>
    .<\n+0000bb60: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+0000bb70: 3e3c 6120 6964 3d22 6c30 3033 3337 2220 > 337 std::shar\n+0000bbc0: 6564 5f70 7472 266c 743b 4475 6e65 3a3a ed_ptr<Dune::\n+0000bbd0: 496e 7665 7273 654f 7065 7261 746f 7226 InverseOperator&\n+0000bbe0: 6c74 3b74 7970 656e 616d 6520 4475 6e65 lt;typename Dune\n+0000bbf0: 3a3a 5479 7065 4c69 7374 456c 656d 656e ::TypeListElemen\n+0000bc00: 7426 6c74 3b31 2c20 544c 2667 743b 3a3a t<1, TL>::\n+0000bc10: 7479 7065 2c3c 2f64 6976 3e0a 3c64 6976 type,
    .<\n+0000bc50: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000bc60: 6e6f 223e 2020 3333 383c 2f73 7061 6e3e no\"> 338
    \n+0000bc70: 2020 2020 2020 2020 2020 2020 2020 2020 \n+0000bc80: 2020 2020 2020 2020 2020 2020 2020 2020 \n+0000bc90: 2020 2020 2020 2020 2020 3c73 7061 6e20 \n+0000bcb0: 7479 7065 6e61 6d65 3c2f 7370 616e 3e20 typename \n+0000bcc0: 4475 6e65 3a3a 5479 7065 4c69 7374 456c Dune::TypeListEl\n+0000bcd0: 656d 656e 7426 6c74 3b32 2c20 544c 2667 ement<2, TL&g\n+0000bce0: 743b 3a3a 7479 7065 2667 743b 2667 743b t;::type>>\n+0000bcf0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    <\n+0000bd40: 6120 636c 6173 733d 226c 696e 6522 2068 a class=\"line\" h\n+0000bd50: 7265 663d 2261 3030 3233 332e 6874 6d6c ref=\"a00233.html\n+0000bd60: 2367 6136 3838 3461 3639 3066 3366 6164 #ga6884a690f3fad\n+0000bd70: 6439 6235 6538 6465 6633 3433 3335 3435 d9b5e8def3433545\n+0000bd80: 3966 3122 3e20 2033 3339 3c2f 613e 3c2f 9f1\"> 339 opera\n+0000bdf0: 746f 7228 2920 3c2f 613e 2854 4c20 3c73 tor() (TL /*tl*/, const M& m\n+0000bea0: 6174 3c2f 613e 2c20 3c73 7061 6e20 636c at, co\n+0000bec0: 6e73 743c 2f73 7061 6e3e 2044 756e 653a nst Dune:\n+0000bed0: 3a50 6172 616d 6574 6572 5472 6565 2661 :ParameterTree&a\n+0000bee0: 6d70 3b20 636f 6e66 6967 2c3c 2f64 6976 mp; config,.
    340<\n+0000bf40: 2f73 7061 6e3e 2020 2020 2020 7374 643a /span> std:\n+0000bf50: 3a65 6e61 626c 655f 6966 5f74 266c 743b :enable_if_t<\n+0000bf60: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000bfb0: 2033 3431 3c2f 7370 616e 3e20 2020 2020 341 \n+0000bfc0: 2020 2020 2020 2020 2020 203c 6120 636c isValidB\n+0000c000: 6c6f 636b 3c2f 613e 266c 743b 3c73 7061 lock<typename Dune::TypeList\n+0000c040: 456c 656d 656e 7426 6c74 3b31 2c20 544c Element<1, TL\n+0000c050: 2667 743b 3a3a 7479 7065 3a3a 626c 6f63 >::type::bloc\n+0000c060: 6b5f 7479 7065 2667 743b 3a3a 7661 6c75 k_type>::valu\n+0000c070: 652c 3c73 7061 6e20 636c 6173 733d 226b e,int<\n+0000c090: 2f73 7061 6e3e 2667 743b 203d 2030 293c /span>> = 0)<\n+0000c0a0: 7370 616e 2063 6c61 7373 3d22 6b65 7977 span class=\"keyw\n+0000c0b0: 6f72 6422 3e20 636f 6e73 743c 2f73 7061 ord\"> const
    .
    342 {<\n+0000c140: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+0000c190: 3334 333c 2f73 7061 6e3e 2020 2020 2020 343 \n+0000c1a0: 3c73 7061 6e20 636c 6173 733d 226b 6579 int verbose = c\n+0000c1d0: 6f6e 6669 672e 6765 7428 3c73 7061 6e20 onfig.get("verb\n+0000c200: 6f73 6526 7175 6f74 3b3c 2f73 7061 6e3e ose"\n+0000c210: 2c20 3029 3b3c 2f64 6976 3e0a 3c64 6976 , 0);
    .<\n+0000c250: 7370 616e 2063 6c61 7373 3d22 6c69 6e65 span class=\"line\n+0000c260: 6e6f 223e 2020 3334 343c 2f73 7061 6e3e no\"> 344\n+0000c270: 2020 2020 2020 3c73 7061 6e20 636c 6173 \n+0000c290: 7265 7475 726e 3c2f 7370 616e 3e20 7374 return st\n+0000c2a0: 643a 3a6d 616b 655f 7368 6172 6564 266c d::make_shared&l\n+0000c2b0: 743b 4475 6e65 3a3a 5350 5152 266c 743b t;Dune::SPQR<\n+0000c2c0: 4d26 6774 3b26 6774 3b28 3c61 2063 6c61 M>>(mat<\n+0000c320: 2f61 3e2c 7665 7262 6f73 6529 3b3c 2f64 /a>,verbose);.
    34\n+0000c380: 353c 2f73 7061 6e3e 2020 2020 7d3c 2f64 5 }.
    34\n+0000c3e0: 363c 2f73 7061 6e3e 203c 2f64 6976 3e0a 6
    .\n+0000c3f0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n+0000c420: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 347 //\n+0000c460: 2073 6563 6f6e 6420 7665 7273 696f 6e20 second version \n+0000c470: 7769 7468 2053 4649 4e41 4520 746f 2076 with SFINAE to v\n+0000c480: 616c 6964 6174 6520 7468 6520 7465 6d70 alidate the temp\n+0000c490: 6c61 7465 2070 6172 616d 6574 6572 7320 late parameters \n+0000c4a0: 6f66 2053 5051 523c 2f73 7061 6e3e 3c2f of SPQR.
    3\n+0000c500: 3438 3c2f 7370 616e 3e20 2020 203c 7370 48 template<type\n+0000c550: 6e61 6d65 3c2f 7370 616e 3e20 544c 2c20 name TL, \n+0000c560: 3c73 7061 6e20 636c 6173 733d 226b 6579 typename M>.
    349<\n+0000c5e0: 2f73 7061 6e3e 2020 2020 7374 643a 3a73 /span> std::s\n+0000c5f0: 6861 7265 645f 7074 7226 6c74 3b44 756e hared_ptr<Dun\n+0000c600: 653a 3a49 6e76 6572 7365 4f70 6572 6174 e::InverseOperat\n+0000c610: 6f72 266c 743b 7479 7065 6e61 6d65 2044 or<typename D\n+0000c620: 756e 653a 3a54 7970 654c 6973 7445 6c65 une::TypeListEle\n+0000c630: 6d65 6e74 266c 743b 312c 2054 4c26 6774 ment<1, TL>\n+0000c640: 3b3a 3a74 7970 652c 3c2f 6469 763e 0a3c ;::type,
    .<\n+0000c650: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n+0000c660: 3e3c 6120 6964 3d22 6c30 3033 3530 2220 > 350 \n+0000c6b0: 2020 2020 2020 2020 2020 2020 2020 2020 \n+0000c6c0: 2020 2020 2020 2020 2020 2020 203c 7370 typename Dune::TypeLis\n+0000c700: 7445 6c65 6d65 6e74 266c 743b 322c 2054 tElement<2, T\n+0000c710: 4c26 6774 3b3a 3a74 7970 6526 6774 3b26 L>::type>&\n+0000c720: 6774 3b3c 2f64 6976 3e0a 3c64 6976 2063 gt;
    .
    351 op\n+0000c820: 6572 6174 6f72 2829 203c 2f61 3e28 544c erator() (TL\n+0000c830: 203c 7370 616e 2063 6c61 7373 3d22 636f /*tl*/, cons\n+0000c870: 743c 2f73 7061 6e3e 204d 2661 6d70 3b20 t M& \n+0000c880: 3c73 7061 6e20 636c 6173 733d 2263 6f6d /*mat*/, cons\n+0000c8c0: 743c 2f73 7061 6e3e 2044 756e 653a 3a50 t Dune::P\n+0000c8d0: 6172 616d 6574 6572 5472 6565 2661 6d70 arameterTree&\n+0000c8e0: 3b20 3c73 7061 6e20 636c 6173 733d 2263 ; /*config\n+0000c900: 2a2f 3c2f 7370 616e 3e2c 3c2f 6469 763e */,
    \n+0000c910: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n+0000c940: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 352 std::\n+0000c970: 656e 6162 6c65 5f69 665f 7426 6c74 3b21 enable_if_t<!\n+0000c980: 3c61 2063 6c61 7373 3d22 636f 6465 2068 isV\n+0000c9b0: 616c 6964 426c 6f63 6b3c 2f61 3e26 6c74 alidBlock<\n+0000c9c0: 3b3c 7370 616e 2063 6c61 7373 3d22 6b65 ;typename<\n+0000c9e0: 2f73 7061 6e3e 2044 756e 653a 3a54 7970 /span> Dune::Typ\n+0000c9f0: 654c 6973 7445 6c65 6d65 6e74 266c 743b eListElement<\n+0000ca00: 312c 2054 4c26 6774 3b3a 3a74 7970 653a 1, TL>::type:\n+0000ca10: 3a62 6c6f 636b 5f74 7970 6526 6774 3b3a :block_type>:\n+0000ca20: 3a76 616c 7565 2c3c 7370 616e 2063 6c61 :value,int> \n+0000ca50: 3d20 3029 3c73 7061 6e20 636c 6173 733d = 0) const\n+0000ca70: 3c2f 7370 616e 3e3c 2f64 6976 3e0a 3c64
    .\n+0000ca90: 3c61 2069 643d 226c 3030 3335 3322 206e 353 {
    .
    354 \n+0000cb50: 2020 2020 2044 554e 455f 5448 524f 5728 DUNE_THROW(\n+0000cb60: 3c61 2063 6c61 7373 3d22 636f 6465 2068 Unsu\n+0000cb90: 7070 6f72 7465 6454 7970 653c 2f61 3e2c pportedType,\n+0000cba0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n+0000cbf0: 2033 3535 3c2f 7370 616e 3e20 2020 2020 355 \n+0000cc00: 2020 203c 7370 616e 2063 6c61 7373 3d22 &\n+0000cc20: 7175 6f74 3b55 6e73 7570 706f 7274 6564 quot;Unsupported\n+0000cc30: 2054 7970 6520 696e 2053 5051 5220 286f Type in SPQR (o\n+0000cc40: 6e6c 7920 646f 7562 6c65 2061 6e64 2073 nly double and s\n+0000cc50: 7464 3a3a 636f 6d70 6c65 7826 6c74 3b64 td::complex<d\n+0000cc60: 6f75 626c 6526 6774 3b20 7375 7070 6f72 ouble> suppor\n+0000cc70: 7465 6429 2671 756f 743b 3c2f 7370 616e ted)");
    .
    356 \n+0000cce0: 2020 7d3c 2f64 6976 3e0a 3c64 6976 2063 }
    .
    357 \n+0000cd40: 7d3b 3c2f 6469 763e 0a3c 6469 7620 636c };
    ..\n+0000cea0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n+0000ced0: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 359 // s\n+0000cf10: 7464 3a3a 636f 6d70 6c65 7820 6973 2074 td::complex is t\n+0000cf20: 656d 706f 7261 7279 2064 6973 6162 6c65 emporary disable\n+0000cf30: 642c 2062 6563 6175 7365 2069 7420 6661 d, because it fa\n+0000cf40: 696c 7320 6966 206c 6962 632b 2b20 6973 ils if libc++ is\n+0000cf50: 2075 7365 643c 2f73 7061 6e3e 3c2f 6469 used.
    360\n+0000cfb0: 3c2f 7370 616e 3e20 203c 7370 616e 2063 /\n+0000cfd0: 2f74 656d 706c 6174 6526 6c74 3b26 6774 /template<>\n+0000cfe0: 3b20 7374 7275 6374 2053 5051 5243 7265 ; struct SPQRCre\n+0000cff0: 6174 6f72 3a3a 6973 5661 6c69 644d 6174 ator::isValidMat\n+0000d000: 7269 7842 6c6f 636b 266c 743b 4669 656c rixBlock<Fiel\n+0000d010: 644d 6174 7269 7826 6c74 3b73 7464 3a3a dMatrix<std::\n+0000d020: 636f 6d70 6c65 7826 6c74 3b64 6f75 626c complex<doubl\n+0000d030: 6526 6774 3b2c 312c 3126 6774 3b26 6774 e>,1,1>>\n+0000d040: 3b20 3a20 7374 643a 3a74 7275 655f 7479 ; : std::true_ty\n+0000d050: 7065 7b7d 3b3c 2f73 7061 6e3e 3c2f 6469 pe{};..
    \n+0000d240: 2033 3632 3c2f 7370 616e 3e20 3c2f 6469 362 .
    363\n+0000d2a0: 3c2f 7370 616e 3e7d 203c 7370 616e 2063 } /\n+0000d2c0: 2f20 656e 6420 6e61 6d65 7370 6163 6520 / end namespace \n+0000d2d0: 4475 6e65 3c2f 7370 616e 3e3c 2f64 6976 Dune.
    364<\n+0000d330: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
    .\n+0000d350: 3c61 2069 643d 226c 3030 3336 3522 206e 365
    .
    366#endif \n+0000d410: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 //H\n+0000d430: 4156 455f 5355 4954 4553 5041 5253 455f AVE_SUITESPARSE_\n+0000d440: 5350 5152 3c2f 7370 616e 3e3c 2f64 6976 SPQR.
    367<\n+0000d4a0: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#endif <\n+0000d4d0: 7370 616e 2063 6c61 7373 3d22 636f 6d6d span class=\"comm\n+0000d4e0: 656e 7422 3e2f 2f44 554e 455f 4953 544c ent\">//DUNE_ISTL\n+0000d4f0: 5f53 5051 525f 4848 3c2f 7370 616e 3e3c _SPQR_HH<\n+0000d500: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    Tem\n+0000d580: 706c 6174 6573 2063 6861 7261 6374 6572 plates character\n+0000d590: 697a 696e 6720 7468 6520 7479 7065 206f izing the type o\n+0000d5a0: 6620 6120 736f 6c76 6572 2e3c 2f64 6976 f a solver.
    .
    <\n+0000d5f0: 6120 6872 6566 3d22 6130 3030 3434 2e68 a href=\"a00044.h\n+0000d600: 746d 6c22 3e62 6363 736d 6174 7269 7869 tml\">bccsmatrixi\n+0000d610: 6e69 7469 616c 697a 6572 2e68 683c 2f61 nitializer.hh
    .<\n+0000d690: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n+0000d6a0: 223e 496d 706c 656d 656e 7461 7469 6f6e \">Implementation\n+0000d6b0: 7320 6f66 2074 6865 2069 6e76 6572 7365 s of the inverse\n+0000d6c0: 206f 7065 7261 746f 7220 696e 7465 7266 operator interf\n+0000d6d0: 6163 652e 3c2f 6469 763e 3c2f 6469 763e ace.
    \n+0000d6e0: 0a3c 6469 7620 636c 6173 733d 2274 7463 ..<\n+0000d750: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+0000d760: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n+0000d770: 5f67 6130 6339 3334 6263 6233 3535 3736 _ga0c934bcb35576\n+0000d780: 3838 3661 3366 3737 3134 6431 3062 3330 886a3f7714d10b30\n+0000d790: 3834 3122 3e3c 6469 7620 636c 6173 733d 841\">
    vi\n+0000d850: 7274 7561 6c20 7e53 5051 5228 293c 2f64 rtual ~SPQR()
    Destructor\n+0000d880: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
    Def\n+0000d8a0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n+0000d8b0: 722e 6868 3a31 3437 3c2f 6469 763e 3c2f r.hh:147
    .
    <\n+0000d920: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n+0000d930: 746d 6c23 6761 3234 6637 3563 6262 3335 tml#ga24f75cbb35\n+0000d940: 3433 3036 3732 6239 3738 3962 6536 3236 430672b9789be626\n+0000d950: 3663 3539 6532 223e 4475 6e65 3a3a 5350 6c59e2\">Dune::SP\n+0000d960: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n+0000d970: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n+0000d980: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n+0000d990: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n+0000d9a0: 3a53 5051 523c 2f61 3e3c 2f64 6976 3e3c :SPQR
    <\n+0000d9b0: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+0000d9c0: 6922 3e53 5051 5228 636f 6e73 7420 4d61 i\">SPQR(const Ma\n+0000d9d0: 7472 6978 2026 616d 703b 6d61 7472 6978 trix &matrix\n+0000d9e0: 2c20 696e 7420 7665 7262 6f73 652c 2062 , int verbose, b\n+0000d9f0: 6f6f 6c29 3c2f 6469 763e 3c64 6976 2063 ool)
    Con\n+0000da10: 7374 7275 6374 6f72 2066 6f72 2063 6f6d structor for com\n+0000da20: 7061 7469 6269 6c69 7479 2077 6974 6820 patibility with \n+0000da30: 5375 7065 724c 5520 7374 616e 6461 7264 SuperLU standard\n+0000da40: 2063 6f6e 7374 7275 6374 6f72 2e3c 2f64 constructor.
    Definit\n+0000da70: 696f 6e3a 3c2f 623e 2073 7071 722e 6868 ion: spqr.hh\n+0000da80: 3a31 3133 3c2f 6469 763e 3c2f 6469 763e :113
    \n+0000da90: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    <\n+0000db80: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+0000db90: 6922 3e76 6972 7475 616c 2053 6f6c 7665 i\">virtual Solve\n+0000dba0: 7243 6174 6567 6f72 793a 3a43 6174 6567 rCategory::Categ\n+0000dbb0: 6f72 7920 6361 7465 676f 7279 2829 2063 ory category() c\n+0000dbc0: 6f6e 7374 3c2f 6469 763e 3c64 6976 2063 onst
    Cat\n+0000dbe0: 6567 6f72 7920 6f66 2074 6865 2073 6f6c egory of the sol\n+0000dbf0: 7665 7220 2873 6565 2053 6f6c 7665 7243 ver (see SolverC\n+0000dc00: 6174 6567 6f72 793a 3a43 6174 6567 6f72 ategory::Categor\n+0000dc10: 7929 3c2f 6469 763e 3c64 6976 2063 6c61 y)
    De\n+0000dc30: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n+0000dc40: 7172 2e68 683a 3832 3c2f 6469 763e 3c2f qr.hh:82
    .
    <\n+0000dcb0: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n+0000dcc0: 746d 6c23 6761 3332 6330 6433 3532 6532 tml#ga32c0d352e2\n+0000dcd0: 6239 3564 3038 3836 3162 6633 3833 3139 b95d08861bf38319\n+0000dce0: 6230 3537 6165 223e 4475 6e65 3a3a 5350 b057ae\">Dune::SP\n+0000dcf0: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n+0000dd00: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n+0000dd10: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n+0000dd20: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n+0000dd30: 3a67 6574 496e 7465 726e 616c 4d61 7472 :getInternalMatr\n+0000dd40: 6978 3c2f 613e 3c2f 6469 763e 3c64 6976 ix
    \n+0000dd60: 5350 5152 4d61 7472 6978 2026 616d 703b SPQRMatrix &\n+0000dd70: 2067 6574 496e 7465 726e 616c 4d61 7472 getInternalMatr\n+0000dd80: 6978 2829 3c2f 6469 763e 3c64 6976 2063 ix()
    Ret\n+0000dda0: 7572 6e20 7468 6520 636f 6c75 6d6e 2063 urn the column c\n+0000ddb0: 6f70 7072 6573 7365 6420 6d61 7472 6978 oppressed matrix\n+0000ddc0: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
    Def\n+0000dde0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n+0000ddf0: 722e 6868 3a32 3536 3c2f 6469 763e 3c2f r.hh:256
    .
    <\n+0000de60: 6120 6872 6566 3d22 6130 3032 3333 2e68 a href=\"a00233.h\n+0000de70: 746d 6c23 6761 3430 6563 3262 3365 6131 tml#ga40ec2b3ea1\n+0000de80: 3662 3165 3231 3464 3338 6235 3636 6634 6b1e214d38b566f4\n+0000de90: 6430 3763 6630 223e 4475 6e65 3a3a 5350 d07cf0\">Dune::SP\n+0000dea0: 5152 266c 743b 2042 4352 534d 6174 7269 QR< BCRSMatri\n+0000deb0: 7826 6c74 3b20 4669 656c 644d 6174 7269 x< FieldMatri\n+0000dec0: 7826 6c74 3b20 542c 206e 2c20 6d20 2667 x< T, n, m &g\n+0000ded0: 743b 2c20 4120 2667 743b 2026 6774 3b3a t;, A > >:\n+0000dee0: 3a73 6574 4d61 7472 6978 3c2f 613e 3c2f :setMatrix
    void set\n+0000df10: 4d61 7472 6978 2863 6f6e 7374 204d 6174 Matrix(const Mat\n+0000df20: 7269 7820 2661 6d70 3b6d 6174 7269 7829 rix &matrix)\n+0000df30: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Initial\n+0000df50: 697a 6520 6461 7461 2066 726f 6d20 6769 ize data from gi\n+0000df60: 7665 6e20 6d61 7472 6978 2e3c 2f64 6976 ven matrix.
    Definitio\n+0000df90: 6e3a 3c2f 623e 2073 7071 722e 6868 3a32 n: spqr.hh:2\n+0000dfa0: 3030 3c2f 6469 763e 3c2f 6469 763e 0a3c 00
    .<\n+0000dfb0: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+0000dfc0: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n+0000dfd0: 5f67 6134 6162 3461 3166 3431 3935 3532 _ga4ab4a1f419552\n+0000dfe0: 3332 3864 3539 3437 3237 3632 3765 3639 328d594727627e69\n+0000dff0: 3663 6222 3e3c 6469 7620 636c 6173 733d 6cb\">DUNE_REGISTER_D\n+0000e090: 4952 4543 545f 534f 4c56 4552 2826 7175 IRECT_SOLVER(&qu\n+0000e0a0: 6f74 3b6c 646c 2671 756f 743b 2c20 4475 ot;ldl", Du\n+0000e0b0: 6e65 3a3a 4c44 4c43 7265 6174 6f72 2829 ne::LDLCreator()\n+0000e0c0: 293c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 )
    .
    Dune::SPQR< \n+0000e170: 4243 5253 4d61 7472 6978 266c 743b 2046 BCRSMatrix< F\n+0000e180: 6965 6c64 4d61 7472 6978 266c 743b 2054 ieldMatrix< T\n+0000e190: 2c20 6e2c 206d 2026 6774 3b2c 2041 2026 , n, m >, A &\n+0000e1a0: 6774 3b20 2667 743b 3a3a 4d61 7472 6978 gt; >::Matrix\n+0000e1b0: 496e 6974 6961 6c69 7a65 723c 2f61 3e3c Initializer<\n+0000e1c0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    ISTL::I\n+0000e1e0: 6d70 6c3a 3a42 4343 534d 6174 7269 7849 mpl::BCCSMatrixI\n+0000e1f0: 6e69 7469 616c 697a 6572 266c 743b 2042 nitializer< B\n+0000e200: 4352 534d 6174 7269 7826 6c74 3b20 4669 CRSMatrix< Fi\n+0000e210: 656c 644d 6174 7269 7826 6c74 3b20 542c eldMatrix< T,\n+0000e220: 206e 2c20 6d20 2667 743b 2c20 4120 2667 n, m >, A &g\n+0000e230: 743b 2c20 696e 7420 2667 743b 204d 6174 t;, int > Mat\n+0000e240: 7269 7849 6e69 7469 616c 697a 6572 3c2f rixInitializer
    Type of a\n+0000e270: 6e20 6173 736f 6369 6174 6564 2069 6e69 n associated ini\n+0000e280: 7469 616c 697a 6572 2063 6c61 7373 2e3c tializer class.<\n+0000e290: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    Defin\n+0000e2b0: 6974 696f 6e3a 3c2f 623e 2073 7071 722e ition: spqr.\n+0000e2c0: 6868 3a37 353c 2f64 6976 3e3c 2f64 6976 hh:75
    .D\n+0000e3f0: 6566 6175 6c74 2063 6f6e 7374 7275 6374 efault construct\n+0000e400: 6f72 2e3c 2f64 6976 3e3c 6469 7620 636c or.
    D\n+0000e420: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n+0000e430: 7071 722e 6868 3a31 3337 3c2f 6469 763e pqr.hh:137
    \n+0000e440: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    Dune::\n+0000e4e0: 5350 5152 4372 6561 746f 723a 3a6f 7065 SPQRCreator::ope\n+0000e4f0: 7261 746f 7228 293c 2f61 3e3c 2f64 6976 rator()
    std::shared\n+0000e520: 5f70 7472 266c 743b 2044 756e 653a 3a49 _ptr< Dune::I\n+0000e530: 6e76 6572 7365 4f70 6572 6174 6f72 266c nverseOperator&l\n+0000e540: 743b 2074 7970 656e 616d 6520 4475 6e65 t; typename Dune\n+0000e550: 3a3a 5479 7065 4c69 7374 456c 656d 656e ::TypeListElemen\n+0000e560: 7426 6c74 3b20 312c 2054 4c20 2667 743b t< 1, TL >\n+0000e570: 3a3a 7479 7065 2c20 7479 7065 6e61 6d65 ::type, typename\n+0000e580: 2044 756e 653a 3a54 7970 654c 6973 7445 Dune::TypeListE\n+0000e590: 6c65 6d65 6e74 266c 743b 2032 2c20 544c lement< 2, TL\n+0000e5a0: 2026 6774 3b3a 3a74 7970 6520 2667 743b >::type >\n+0000e5b0: 2026 6774 3b20 6f70 6572 6174 6f72 2829 > operator()\n+0000e5c0: 2854 4c2c 2063 6f6e 7374 204d 2026 616d (TL, const M &am\n+0000e5d0: 703b 6d61 742c 2063 6f6e 7374 2044 756e p;mat, const Dun\n+0000e5e0: 653a 3a50 6172 616d 6574 6572 5472 6565 e::ParameterTree\n+0000e5f0: 2026 616d 703b 636f 6e66 6967 2c20 7374 &config, st\n+0000e600: 643a 3a65 6e61 626c 655f 6966 5f74 266c d::enable_if_t&l\n+0000e610: 743b 2069 7356 616c 6964 426c 6f63 6b26 t; isValidBlock&\n+0000e620: 6c74 3b20 7479 7065 6e61 6d65 2044 756e lt; typename Dun\n+0000e630: 653a 3a54 7970 654c 6973 7445 6c65 6d65 e::TypeListEleme\n+0000e640: 6e74 266c 743b 2031 2c20 544c 2026 6774 nt< 1, TL >\n+0000e650: 3b3a 3a74 7970 653a 3a62 6c6f 636b 5f74 ;::type::block_t\n+0000e660: 7970 6520 2667 743b 3a3a 7661 6c75 652c ype >::value,\n+0000e670: 2069 6e74 2026 6774 3b3d 3029 2063 6f6e int >=0) con\n+0000e680: 7374 3c2f 6469 763e 3c64 6976 2063 6c61 st
    De\n+0000e6a0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n+0000e6b0: 7172 2e68 683a 3333 393c 2f64 6976 3e3c qr.hh:339
    <\n+0000e6c0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n+0000e7b0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    const char *\n+0000e7d0: 206e 616d 6528 293c 2f64 6976 3e3c 6469 name()
    \n+0000e7f0: 4765 7420 6d65 7468 6f64 206e 616d 652e Get method name.\n+0000e800: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Defi\n+0000e820: 6e69 7469 6f6e 3a3c 2f62 3e20 7370 7172 nition: spqr\n+0000e830: 2e68 683a 3237 353c 2f64 6976 3e3c 2f64 .hh:275
    .
    Dune::SPQ\n+0000e8e0: 5226 6c74 3b20 4243 5253 4d61 7472 6978 R< BCRSMatrix\n+0000e8f0: 266c 743b 2046 6965 6c64 4d61 7472 6978 < FieldMatrix\n+0000e900: 266c 743b 2054 2c20 6e2c 206d 2026 6774 < T, n, m >\n+0000e910: 3b2c 2041 2026 6774 3b20 2667 743b 3a3a ;, A > >::\n+0000e920: 6765 7446 6163 746f 7269 7a61 7469 6f6e getFactorization\n+0000e930: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
    Su\n+0000e950: 6974 6553 7061 7273 6551 525f 6661 6374 iteSparseQR_fact\n+0000e960: 6f72 697a 6174 696f 6e26 6c74 3b20 5420 orization< T \n+0000e970: 2667 743b 202a 2067 6574 4661 6374 6f72 > * getFactor\n+0000e980: 697a 6174 696f 6e28 293c 2f64 6976 3e3c ization()
    <\n+0000e990: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n+0000e9a0: 223e 5265 7475 726e 2074 6865 206d 6174 \">Return the mat\n+0000e9b0: 7269 7820 6661 6374 6f72 697a 6174 696f rix factorizatio\n+0000e9c0: 6e2e 3c2f 6469 763e 3c64 6976 2063 6c61 n.
    De\n+0000e9e0: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n+0000e9f0: 7172 2e68 683a 3234 373c 2f64 6976 3e3c qr.hh:247
    <\n+0000ea00: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>..
    IST\n+0000ecb0: 4c3a 3a49 6d70 6c3a 3a42 4343 534d 6174 L::Impl::BCCSMat\n+0000ecc0: 7269 7826 6c74 3b20 542c 2069 6e74 2026 rix< T, int &\n+0000ecd0: 6774 3b20 5350 5152 4d61 7472 6978 3c2f gt; SPQRMatrix
    The corre\n+0000ed00: 7370 6f6e 6469 6e67 2053 7570 6572 4c55 sponding SuperLU\n+0000ed10: 204d 6174 7269 7820 7479 7065 2e3c 2f64 Matrix type.
    Definit\n+0000ed40: 696f 6e3a 3c2f 623e 2073 7071 722e 6868 ion: spqr.hh\n+0000ed50: 3a37 333c 2f64 6976 3e3c 2f64 6976 3e0a :73
    .\n+0000ed60: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    v\n+0000ee60: 6972 7475 616c 2076 6f69 6420 6170 706c irtual void appl\n+0000ee70: 7928 646f 6d61 696e 5f74 7970 6520 2661 y(domain_type &a\n+0000ee80: 6d70 3b78 2c20 7261 6e67 655f 7479 7065 mp;x, range_type\n+0000ee90: 2026 616d 703b 622c 2064 6f75 626c 6520 &b, double \n+0000eea0: 7265 6475 6374 696f 6e2c 2049 6e76 6572 reduction, Inver\n+0000eeb0: 7365 4f70 6572 6174 6f72 5265 7375 6c74 seOperatorResult\n+0000eec0: 2026 616d 703b 7265 7329 3c2f 6469 763e &res)
    \n+0000eed0: 3c64 6976 2063 6c61 7373 3d22 7474 646f
    apply inverse\n+0000eef0: 206f 7065 7261 746f 722c 2077 6974 6820 operator, with \n+0000ef00: 6769 7665 6e20 636f 6e76 6572 6765 6e63 given convergenc\n+0000ef10: 6520 6372 6974 6572 6961 2e3c 2f64 6976 e criteria.
    Definitio\n+0000ef40: 6e3a 3c2f 623e 2073 7071 722e 6868 3a31 n: spqr.hh:1\n+0000ef50: 3931 3c2f 6469 763e 3c2f 6469 763e 0a3c 91
    .<\n+0000ef60: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+0000ef70: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n+0000ef80: 5f67 6139 3237 3966 6633 3139 3530 3134 _ga9279ff3195014\n+0000ef90: 3136 6338 6165 6630 3462 6565 6562 3362 16c8aef04beeeb3b\n+0000efa0: 3366 3922 3e3c 6469 7620 636c 6173 733d 3f9\">Free allocated \n+0000f090: 7370 6163 652e 3c2f 6469 763e 3c64 6976 space.
    <\n+0000f0b0: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:265
    .
    \n+0000f120: 3c64 6976 2063 6c61 7373 3d22 7474 6e61
    Dun\n+0000f170: 653a 3a53 5051 5226 6c74 3b20 4243 5253 e::SPQR< BCRS\n+0000f180: 4d61 7472 6978 266c 743b 2046 6965 6c64 Matrix< Field\n+0000f190: 4d61 7472 6978 266c 743b 2054 2c20 6e2c Matrix< T, n,\n+0000f1a0: 206d 2026 6774 3b2c 2041 2026 6774 3b20 m >, A > \n+0000f1b0: 2667 743b 3a3a 5350 5152 3c2f 613e 3c2f >::SPQR
    SPQR(con\n+0000f1e0: 7374 204d 6174 7269 7820 2661 6d70 3b6d st Matrix &m\n+0000f1f0: 6174 7269 782c 2063 6f6e 7374 2050 6172 atrix, const Par\n+0000f200: 616d 6574 6572 5472 6565 2026 616d 703b ameterTree &\n+0000f210: 636f 6e66 6967 293c 2f64 6976 3e3c 6469 config)
    \n+0000f230: 436f 6e73 7472 7563 7473 2074 6865 2053 Constructs the S\n+0000f240: 5051 5220 736f 6c76 6572 2e3c 2f64 6976 PQR solver.
    Definitio\n+0000f270: 6e3a 3c2f 623e 2073 7071 722e 6868 3a31 n: spqr.hh:1\n+0000f280: 3332 3c2f 6469 763e 3c2f 6469 763e 0a3c 32
    .<\n+0000f290: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+0000f2a0: 6964 3d22 6161 3030 3233 335f 6874 6d6c id=\"aa00233_html\n+0000f2b0: 5f67 6163 3735 6364 3761 3564 3336 3436 _gac75cd7a5d3646\n+0000f2c0: 6638 3537 3330 6637 3435 6432 3466 3665 f85730f745d24f6e\n+0000f2d0: 6561 3122 3e3c 6469 7620 636c 6173 733d ea1\"><\n+0000f380: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+0000f390: 6922 3e44 756e 653a 3a42 6c6f 636b 5665 i\">Dune::BlockVe\n+0000f3a0: 6374 6f72 266c 743b 2046 6965 6c64 5665 ctor< FieldVe\n+0000f3b0: 6374 6f72 266c 743b 2054 2c20 6e20 2667 ctor< T, n &g\n+0000f3c0: 743b 2c20 7479 7065 6e61 6d65 2073 7464 t;, typename std\n+0000f3d0: 3a3a 616c 6c6f 6361 746f 725f 7472 6169 ::allocator_trai\n+0000f3e0: 7473 266c 743b 2041 2026 6774 3b3a 3a74 ts< A >::t\n+0000f3f0: 656d 706c 6174 6520 7265 6269 6e64 5f61 emplate rebind_a\n+0000f400: 6c6c 6f63 266c 743b 2046 6965 6c64 5665 lloc< FieldVe\n+0000f410: 6374 6f72 266c 743b 2054 2c20 6e20 2667 ctor< T, n &g\n+0000f420: 743b 2026 6774 3b20 2667 743b 2072 616e t; > > ran\n+0000f430: 6765 5f74 7970 653c 2f64 6976 3e3c 6469 ge_type
    \n+0000f450: 5468 6520 7479 7065 206f 6620 7468 6520 The type of the \n+0000f460: 7261 6e67 6520 6f66 2074 6865 2073 6f6c range of the sol\n+0000f470: 7665 722e 3c2f 6469 763e 3c64 6976 2063 ver.
    \n+0000f490: 4465 6669 6e69 7469 6f6e 3a3c 2f62 3e20 Definition: \n+0000f4a0: 7370 7172 2e68 683a 3739 3c2f 6469 763e spqr.hh:79
    \n+0000f4b0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .<\n+0000f640: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n+0000f870: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    \n+0000f970: 7669 7274 7561 6c20 766f 6964 2061 7070 virtual void app\n+0000f980: 6c79 2864 6f6d 6169 6e5f 7479 7065 2026 ly(domain_type &\n+0000f990: 616d 703b 782c 2072 616e 6765 5f74 7970 amp;x, range_typ\n+0000f9a0: 6520 2661 6d70 3b62 2c20 496e 7665 7273 e &b, Invers\n+0000f9b0: 654f 7065 7261 746f 7252 6573 756c 7420 eOperatorResult \n+0000f9c0: 2661 6d70 3b72 6573 293c 2f64 6976 3e3c &res)
    <\n+0000f9d0: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n+0000f9e0: 223e 4170 706c 7920 696e 7665 7273 6520 \">Apply inverse \n+0000f9f0: 6f70 6572 6174 6f72 2c2e 3c2f 6469 763e operator,.
    \n+0000fa00: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    Definition\n+0000fa20: 3a3c 2f62 3e20 7370 7172 2e68 683a 3135 : spqr.hh:15\n+0000fa30: 353c 2f64 6976 3e3c 2f64 6976 3e0a 3c64 5
    .void setOption(\n+0000fb50: 756e 7369 676e 6564 2069 6e74 206f 7074 unsigned int opt\n+0000fb60: 696f 6e2c 2064 6f75 626c 6520 7661 6c75 ion, double valu\n+0000fb70: 6529 3c2f 6469 763e 3c64 6976 2063 6c61 e)
    De\n+0000fb90: 6669 6e69 7469 6f6e 3a3c 2f62 3e20 7370 finition: sp\n+0000fba0: 7172 2e68 683a 3139 363c 2f64 6976 3e3c qr.hh:196
    <\n+0000fbb0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.\n+0000fca0: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    SPQR(const M\n+0000fcc0: 6174 7269 7820 2661 6d70 3b6d 6174 7269 atrix &matri\n+0000fcd0: 782c 2069 6e74 2076 6572 626f 7365 3d30 x, int verbose=0\n+0000fce0: 293c 2f64 6976 3e3c 6469 7620 636c 6173 )
    Constr\n+0000fd00: 7563 7420 6120 736f 6c76 6572 206f 626a uct a solver obj\n+0000fd10: 6563 7420 6672 6f6d 2061 2042 4352 534d ect from a BCRSM\n+0000fd20: 6174 7269 782e 3c2f 6469 763e 3c64 6976 atrix.
    <\n+0000fd40: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:95
    .
    <\n+0000fdb0: 6469 7620 636c 6173 733d 2274 746e 616d div class=\"ttnam\n+0000fdc0: 6522 3e3c 6120 6872 6566 3d22 6130 3032 e\">mat<\n+0000fe00: 2f61 3e3c 2f64 6976 3e3c 6469 7620 636c /a>
    Mat\n+0000fe20: 7269 7820 2661 6d70 3b20 6d61 743c 2f64 rix & mat
    Definit\n+0000fe50: 696f 6e3a 3c2f 623e 206d 6174 7269 786d ion: matrixm\n+0000fe60: 6174 7269 782e 6868 3a33 3437 3c2f 6469 atrix.hh:347
    .
    \n+0000feb0: 3c61 2068 7265 663d 2261 3030 3234 392e Dune
    Defini\n+0000fef0: 7469 6f6e 3a3c 2f62 3e20 616c 6c6f 6361 tion: alloca\n+0000ff00: 746f 722e 6868 3a31 313c 2f64 6976 3e3c tor.hh:11
    <\n+0000ff10: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    <\n+0000ff70: 6120 6872 6566 3d22 6130 3032 3439 2e68 a href=\"a00249.h\n+0000ff80: 746d 6c23 6133 3466 3735 6335 3865 3635 tml#a34f75c58e65\n+0000ff90: 3638 3233 6235 3865 3361 6631 3763 3039 6823b58e3af17c09\n+0000ffa0: 6662 3033 6522 3e44 756e 653a 3a67 6574 fb03e\">Dune::get\n+0000ffb0: 3c2f 613e 3c2f 6469 763e 3c64 6976 2063
    Pr\n+0000ffd0: 6f70 6572 7479 4d61 7054 7970 6553 656c opertyMapTypeSel\n+0000ffe0: 6563 746f 7226 6c74 3b20 416d 673a 3a56 ector< Amg::V\n+0000fff0: 6572 7465 7856 6973 6974 6564 5461 672c ertexVisitedTag,\n+00010000: 2041 6d67 3a3a 5072 6f70 6572 7469 6573 Amg::Properties\n+00010010: 4772 6170 6826 6c74 3b20 472c 2041 6d67 Graph< G, Amg\n+00010020: 3a3a 5665 7274 6578 5072 6f70 6572 7469 ::VertexProperti\n+00010030: 6573 2c20 4550 2c20 564d 2c20 454d 2026 es, EP, VM, EM &\n+00010040: 6774 3b20 2667 743b 3a3a 5479 7065 2067 gt; >::Type g\n+00010050: 6574 2863 6f6e 7374 2041 6d67 3a3a 5665 et(const Amg::Ve\n+00010060: 7274 6578 5669 7369 7465 6454 6167 2026 rtexVisitedTag &\n+00010070: 616d 703b 7461 672c 2041 6d67 3a3a 5072 amp;tag, Amg::Pr\n+00010080: 6f70 6572 7469 6573 4772 6170 6826 6c74 opertiesGraph<\n+00010090: 3b20 472c 2041 6d67 3a3a 5665 7274 6578 ; G, Amg::Vertex\n+000100a0: 5072 6f70 6572 7469 6573 2c20 4550 2c20 Properties, EP, \n+000100b0: 564d 2c20 454d 2026 6774 3b20 2661 6d70 VM, EM > &\n+000100c0: 3b67 7261 7068 293c 2f64 6976 3e3c 6469 ;graph)
    \n+000100e0: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: dependency.hh\n+00010100: 3a32 3933 3c2f 6469 763e 3c2f 6469 763e :293
    \n+00010110: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    \n+00010190: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: matrixutils.h\n+000101b0: 683a 3231 313c 2f64 6976 3e3c 2f64 6976 h:211
    .
    A sp\n+00010240: 6172 7365 2062 6c6f 636b 206d 6174 7269 arse block matri\n+00010250: 7820 7769 7468 2063 6f6d 7072 6573 7365 x with compresse\n+00010260: 6420 726f 7720 7374 6f72 6167 652e 3c2f d row storage.
    Defini\n+00010290: 7469 6f6e 3a3c 2f62 3e20 6263 7273 6d61 tion: bcrsma\n+000102a0: 7472 6978 2e68 683a 3436 363c 2f64 6976 trix.hh:466
    .
    Dune::B\n+00010350: 4352 534d 6174 7269 783a 3a4d 3c2f 613e CRSMatrix::M\n+00010360: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    size_t\n+00010380: 7970 6520 4d28 2920 636f 6e73 743c 2f64 ype M() const
    number of \n+000103b0: 636f 6c75 6d6e 7320 2863 6f75 6e74 6564 columns (counted\n+000103c0: 2069 6e20 626c 6f63 6b73 293c 2f64 6976 in blocks)
    Definitio\n+000103f0: 6e3a 3c2f 623e 2062 6372 736d 6174 7269 n: bcrsmatri\n+00010400: 782e 6868 3a31 3937 383c 2f64 6976 3e3c x.hh:1978
    <\n+00010410: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    <\n+00010470: 6120 6872 6566 3d22 6130 3131 3532 2e68 a href=\"a01152.h\n+00010480: 746d 6c23 6165 3634 3063 3466 6335 6139 tml#ae640c4fc5a9\n+00010490: 3334 3362 3838 3336 6233 3037 3333 6239 343b8836b30733b9\n+000104a0: 3866 3962 3422 3e44 756e 653a 3a42 4352 8f9b4\">Dune::BCR\n+000104b0: 534d 6174 7269 783a 3a4e 3c2f 613e 3c2f SMatrix::N
    size_typ\n+000104e0: 6520 4e28 2920 636f 6e73 743c 2f64 6976 e N() const
    number of ro\n+00010510: 7773 2028 636f 756e 7465 6420 696e 2062 ws (counted in b\n+00010520: 6c6f 636b 7329 3c2f 6469 763e 3c64 6976 locks)
    <\n+00010540: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: bcrsmatrix.hh:\n+00010560: 3139 3732 3c2f 6469 763e 3c2f 6469 763e 1972
    \n+00010570: 0a3c 6469 7620 636c 6173 733d 2274 7463 .
    .\n+00010680: 3c64 6976 2063 6c61 7373 3d22 7474 6e61 <\n+000106d0: 6469 7620 636c 6173 733d 2274 7464 6f63 div class=\"ttdoc\n+000106e0: 223e 5365 7175 656e 7469 616c 206f 7665 \">Sequential ove\n+000106f0: 726c 6170 7069 6e67 2053 6368 7761 727a rlapping Schwarz\n+00010700: 2070 7265 636f 6e64 6974 696f 6e65 722e preconditioner.\n+00010710: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Defi\n+00010730: 6e69 7469 6f6e 3a3c 2f62 3e20 6f76 6572 nition: over\n+00010740: 6c61 7070 696e 6773 6368 7761 727a 2e68 lappingschwarz.h\n+00010750: 683a 3735 353c 2f64 6976 3e3c 2f64 6976 h:755
    .
    D\n+000107b0: 756e 653a 3a53 6571 4f76 6572 6c61 7070 une::SeqOverlapp\n+000107c0: 696e 6753 6368 7761 727a 4173 7365 6d62 ingSchwarzAssemb\n+000107d0: 6c65 7248 656c 7065 723c 2f61 3e3c 2f64 lerHelper
    Definit\n+00010800: 696f 6e3a 3c2f 623e 206f 7665 726c 6170 ion: overlap\n+00010810: 7069 6e67 7363 6877 6172 7a2e 6868 3a36 pingschwarz.hh:6\n+00010820: 3934 3c2f 6469 763e 3c2f 6469 763e 0a3c 94
    .<\n+00010830: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+00010840: 6964 3d22 6161 3031 3733 325f 6874 6d6c id=\"aa01732_html\n+00010850: 223e 3c64 6976 2063 6c61 7373 3d22 7474 \">.\n+00010960: 5374 6174 6973 7469 6373 2061 626f 7574 Statistics about\n+00010970: 2074 6865 2061 7070 6c69 6361 7469 6f6e the application\n+00010980: 206f 6620 616e 2069 6e76 6572 7365 206f of an inverse o\n+00010990: 7065 7261 746f 722e 3c2f 6469 763e 3c64 perator.
    Definition:<\n+000109c0: 2f62 3e20 736f 6c76 6572 2e68 683a 3438 /b> solver.hh:48\n+000109d0: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
    .<\n+00010aa0: 6469 7620 636c 6173 733d 2274 7464 6563 div class=\"ttdec\n+00010ab0: 6922 3e69 6e74 2069 7465 7261 7469 6f6e i\">int iteration\n+00010ac0: 733c 2f64 6976 3e3c 6469 7620 636c 6173 s
    Number\n+00010ae0: 206f 6620 6974 6572 6174 696f 6e73 2e3c of iterations.<\n+00010af0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    Defin\n+00010b10: 6974 696f 6e3a 3c2f 623e 2073 6f6c 7665 ition: solve\n+00010b20: 722e 6868 3a36 373c 2f64 6976 3e3c 2f64 r.hh:67
    .
    Dune::Inver\n+00010bd0: 7365 4f70 6572 6174 6f72 5265 7375 6c74 seOperatorResult\n+00010be0: 3a3a 636f 6e76 6572 6765 643c 2f61 3e3c ::converged<\n+00010bf0: 2f64 6976 3e3c 6469 7620 636c 6173 733d /div>
    bool co\n+00010c10: 6e76 6572 6765 643c 2f64 6976 3e3c 6469 nverged
    \n+00010c30: 5472 7565 2069 6620 636f 6e76 6572 6765 True if converge\n+00010c40: 6e63 6520 6372 6974 6572 696f 6e20 6861 nce criterion ha\n+00010c50: 7320 6265 656e 206d 6574 2e3c 2f64 6976 s been met.
    Definitio\n+00010c80: 6e3a 3c2f 623e 2073 6f6c 7665 722e 6868 n: solver.hh\n+00010c90: 3a37 333c 2f64 6976 3e3c 2f64 6976 3e0a :73
    .\n+00010ca0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    A\n+00010d20: 6273 7472 6163 7420 6261 7365 2063 6c61 bstract base cla\n+00010d30: 7373 2066 6f72 2061 6c6c 2073 6f6c 7665 ss for all solve\n+00010d40: 7273 2e3c 2f64 6976 3e3c 6469 7620 636c rs.
    D\n+00010d60: 6566 696e 6974 696f 6e3a 3c2f 623e 2073 efinition: s\n+00010d70: 6f6c 7665 722e 6868 3a39 393c 2f64 6976 olver.hh:99
    .
    Dune::S\n+00010e20: 6f6c 7665 7243 6174 6567 6f72 793a 3a43 olverCategory::C\n+00010e30: 6174 6567 6f72 793c 2f61 3e3c 2f64 6976 ategory
    Category
    Definit\n+00010e80: 696f 6e3a 3c2f 623e 2073 6f6c 7665 7263 ion: solverc\n+00010e90: 6174 6567 6f72 792e 6868 3a32 333c 2f64 ategory.hh:23
    .
    Dune::Uns\n+00010f00: 7570 706f 7274 6564 5479 7065 3c2f 613e upportedType\n+00010f10: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    Defi\n+00010f30: 6e69 7469 6f6e 3a3c 2f62 3e20 736f 6c76 nition: solv\n+00010f40: 6572 7265 6769 7374 7279 2e68 683a 3737 erregistry.hh:77\n+00010f50: 3c2f 6469 763e 3c2f 6469 763e 0a3c 6469
    .\n+00010f80: 3c64 6976 2063 6c61 7373 3d22 7474 6e61 .
    Du\n+000110e0: 6e65 3a3a 4973 4469 7265 6374 536f 6c76 ne::IsDirectSolv\n+000110f0: 6572 3a3a 7661 6c75 653c 2f61 3e3c 2f64 er::value
    @ value
    Whether t\n+00011140: 6869 7320 6973 2061 2064 6972 6563 7420 his is a direct \n+00011150: 736f 6c76 6572 2e3c 2f64 6976 3e3c 6469 solver.
    \n+00011170: 3c62 3e44 6566 696e 6974 696f 6e3a 3c2f Definition: solvertype.hh\n+00011190: 3a32 343c 2f64 6976 3e3c 2f64 6976 3e0a :24
    .\n+000111a0: 3c64 6976 2063 6c61 7373 3d22 7474 6322
    Dun\n+000111f0: 653a 3a53 746f 7265 7343 6f6c 756d 6e43 e::StoresColumnC\n+00011200: 6f6d 7072 6573 7365 643c 2f61 3e3c 2f64 ompressed
    Definit\n+00011230: 696f 6e3a 3c2f 623e 2073 6f6c 7665 7274 ion: solvert\n+00011240: 7970 652e 6868 3a33 303c 2f64 6976 3e3c ype.hh:30
    <\n+00011250: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n+000112d0: 3c61 2068 7265 663d 2261 3032 3830 342e Dune::S\n+00011330: 746f 7265 7343 6f6c 756d 6e43 6f6d 7072 toresColumnCompr\n+00011340: 6573 7365 643a 3a76 616c 7565 3c2f 613e essed::value\n+00011350: 3c2f 6469 763e 3c64 6976 2063 6c61 7373
    @ valu\n+00011370: 653c 2f64 6976 3e3c 6469 7620 636c 6173 e
    whethe\n+00011390: 7220 7468 6520 736f 6c76 6572 2069 6e74 r the solver int\n+000113a0: 6572 6e61 6c6c 7920 7573 6573 2063 6f6c ernally uses col\n+000113b0: 756d 6e20 636f 6d70 7265 7373 6564 2073 umn compressed s\n+000113c0: 746f 7261 6765 3c2f 6469 763e 3c64 6976 torage
    <\n+000113e0: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: solvertype.hh:\n+00011400: 3336 3c2f 6469 763e 3c2f 6469 763e 0a3c 36
    .<\n+00011410: 6469 7620 636c 6173 733d 2274 7463 2220 div class=\"ttc\" \n+00011420: 6964 3d22 6161 3032 3830 385f 6874 6d6c id=\"aa02808_html\n+00011430: 223e 3c64 6976 2063 6c61 7373 3d22 7474 \">\n+00011470: 3c64 6976 2063 6c61 7373 3d22 7474 646f
    Use the SPQR \n+00011490: 7061 636b 6167 6520 746f 2064 6972 6563 package to direc\n+000114a0: 746c 7920 736f 6c76 6520 6c69 6e65 6172 tly solve linear\n+000114b0: 2073 7973 7465 6d73 20e2 8093 2065 6d70 systems ... emp\n+000114c0: 7479 2064 6566 6175 6c74 2063 6c61 7373 ty default class\n+000114d0: 2e3c 2f64 6976 3e3c 6469 7620 636c 6173 .
    Def\n+000114f0: 696e 6974 696f 6e3a 3c2f 623e 2073 7071 inition: spq\n+00011500: 722e 6868 3a34 383c 2f64 6976 3e3c 2f64 r.hh:48
    .
    <\n+00011590: 623e 4465 6669 6e69 7469 6f6e 3a3c 2f62 b>Definition: spqr.hh:333
    .\n+00011630: 3c64 6976 2063 6c61 7373 3d22 7474 6465
    Definition\n+00011650: 3a3c 2f62 3e20 7370 7172 2e68 683a 3333 : spqr.hh:33\n+00011660: 343c 2f64 6976 3e3c 2f64 6976 3e0a 3c2f 4
    .
    ..
    .Gene\n+000116f0: 7261 7465 6420 6279 2623 3136 303b 3c61 rated by \"do\n+00011770: 1.9\n+00011780: 2e34 0a3c 2f73 6d61 6c6c 3e3c 2f61 6464 .4....\n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,465 +4,492 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-supermatrix.hh\n+spqr.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SUPERMATRIX_HH\n- 6#define DUNE_ISTL_SUPERMATRIX_HH\n+ 5#ifndef DUNE_ISTL_SPQR_HH\n+ 6#define DUNE_ISTL_SPQR_HH\n 7\n- 8#if HAVE_SUPERLU\n+ 8#if HAVE_SUITESPARSE_SPQR || defined DOXYGEN\n 9\n- 10#include \"bcrsmatrix.hh\"\n- 11#include \"bvector.hh\"\n- 12#include \n- 13#include \n- 14#include \n- 15#include \n+ 10#include \n+ 11#include \n+ 12\n+ 13#include \n+ 14\n+ 15#include \n 16\n 17#include \n- 18\n- 19#include \"superlufunctions.hh\"\n- 20\n- 21namespace Dune\n- 22{\n- 23\n- 24 template\n-25 struct SuperMatrixCreateSparseChooser\n- 26 {};\n- 27\n- 28 template\n-29 struct SuperMatrixPrinter\n- 30 {};\n- 31\n- 32#if __has_include(\"slu_sdefs.h\")\n- 33 template<>\n- 34 struct SuperMatrixCreateSparseChooser\n- 35 {\n- 36 static void create(SuperMatrix *mat, int n, int m, int offset,\n- 37 float *values, int *rowindex, int* colindex,\n- 38 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 39 {\n- 40 sCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,\n- 41 stype, dtype, mtype);\n- 42 }\n- 43 };\n- 44\n- 45 template<>\n- 46 struct SuperMatrixPrinter\n- 47 {\n- 48 static void print(char* name, SuperMatrix* mat)\n- 49 {\n- 50 sPrint_CompCol_Matrix(name, mat);\n- 51 }\n- 52 };\n- 53#endif\n- 54\n- 55#if __has_include(\"slu_ddefs.h\")\n- 56 template<>\n- 57 struct SuperMatrixCreateSparseChooser\n- 58 {\n- 59 static void create(SuperMatrix *mat, int n, int m, int offset,\n- 60 double *values, int *rowindex, int* colindex,\n- 61 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 62 {\n- 63 dCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,\n- 64 stype, dtype, mtype);\n- 65 }\n- 66 };\n- 67\n- 68 template<>\n- 69 struct SuperMatrixPrinter\n- 70 {\n- 71 static void print(char* name, SuperMatrix* mat)\n- 72 {\n- 73 dPrint_CompCol_Matrix(name, mat);\n- 74 }\n- 75 };\n- 76#endif\n- 77\n- 78#if __has_include(\"slu_cdefs.h\")\n- 79 template<>\n- 80 struct SuperMatrixCreateSparseChooser >\n- 81 {\n- 82 static void create(SuperMatrix *mat, int n, int m, int offset,\n- 83 std::complex *values, int *rowindex, int* colindex,\n- 84 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 85 {\n- 86 cCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast< ::complex*>\n-(values),\n- 87 rowindex, colindex, stype, dtype, mtype);\n- 88 }\n- 89 };\n- 90\n- 91 template<>\n- 92 struct SuperMatrixPrinter >\n- 93 {\n- 94 static void print(char* name, SuperMatrix* mat)\n- 95 {\n- 96 cPrint_CompCol_Matrix(name, mat);\n- 97 }\n- 98 };\n- 99#endif\n- 100\n- 101#if __has_include(\"slu_zdefs.h\")\n- 102 template<>\n- 103 struct SuperMatrixCreateSparseChooser >\n- 104 {\n- 105 static void create(SuperMatrix *mat, int n, int m, int offset,\n- 106 std::complex *values, int *rowindex, int* colindex,\n- 107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 108 {\n- 109 zCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast\n-(values),\n- 110 rowindex, colindex, stype, dtype, mtype);\n- 111 }\n- 112 };\n- 113\n- 114 template<>\n- 115 struct SuperMatrixPrinter >\n- 116 {\n- 117 static void print(char* name, SuperMatrix* mat)\n- 118 {\n- 119 zPrint_CompCol_Matrix(name, mat);\n- 120 }\n- 121 };\n- 122#endif\n- 123\n- 124 template\n-125 struct BaseGetSuperLUType\n- 126 {\n-127 static const Dtype_t type;\n- 128 };\n- 129\n- 130 template\n-131 struct GetSuperLUType\n- 132 {};\n- 133\n- 134 template\n- 135 const Dtype_t BaseGetSuperLUType::type =\n- 136 std::is_same::value ? SLU_S :\n- 137 ( std::is_same >::value ? SLU_Z :\n- 138 ( std::is_same >::value ? SLU_C : SLU_D ));\n- 139\n- 140 template<>\n-141 struct GetSuperLUType\n- 142 : public BaseGetSuperLUType\n- 143 {\n-144 typedef double float_type;\n- 145 };\n- 146\n- 147 template<>\n-148 struct GetSuperLUType\n- 149 : public BaseGetSuperLUType\n- 150 {\n-151 typedef float float_type;\n- 152 };\n+ 18#include \n+ 19#include \n+ 20#include \n+ 21\n+ 22namespace Dune {\n+ 34 // forward declarations\n+ 35 template\n+ 36 class SeqOverlappingSchwarz;\n+ 37\n+ 38 template\n+ 39 struct SeqOverlappingSchwarzAssemblerHelper;\n+ 40\n+ 46 template\n+47 class SPQR\n+ 48 {};\n+ 49\n+ 63 template\n+64 class SPQR,A > >\n+ 65 : public InverseOperator, typename std::\n+allocator_traits::template rebind_alloc > >,\n+ 66 BlockVector, typename std::allocator_traits::template\n+rebind_alloc > > >\n+ 67 {\n+ 68 public:\n+70 typedef Dune::BCRSMatrix,A> Matrix;\n+71 typedef Dune::BCRSMatrix,A> matrix_type;\n+73 typedef ISTL::Impl::BCCSMatrix SPQRMatrix;\n+75 typedef ISTL::Impl::BCCSMatrixInitializer,A>,\n+int> MatrixInitializer;\n+77 typedef Dune::BlockVector, typename std::\n+allocator_traits::template rebind_alloc > > domain_type;\n+79 typedef Dune::BlockVector, typename std::\n+allocator_traits::template rebind_alloc > > range_type;\n+ 80\n+82 virtual SolverCategory::Category category() const\n+ 83 {\n+ 84 return SolverCategory::Category::sequential;\n+ 85 }\n+ 86\n+95 SPQR(const Matrix& matrix, int verbose=0) : matrixIsLoaded_(false), verbose_\n+(verbose)\n+ 96 {\n+ 97 //check whether T is a supported type\n+ 98 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 99 \"Unsupported Type in SPQR (only double and std::complex\n+supported)\");\n+ 100 cc_ = new cholmod_common();\n+ 101 cholmod_l_start(cc_);\n+ 102 setMatrix(matrix);\n+ 103 }\n+ 104\n+113 SPQR(const Matrix& matrix, int verbose, bool) : matrixIsLoaded_(false),\n+verbose_(verbose)\n+ 114 {\n+ 115 //check whether T is a supported type\n+ 116 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 117 \"Unsupported Type in SPQR (only double and std::complex\n+supported)\");\n+ 118 cc_ = new cholmod_common();\n+ 119 cholmod_l_start(cc_);\n+ 120 setMatrix(matrix);\n+ 121 }\n+ 122\n+132 SPQR(const Matrix& matrix, const ParameterTree& config)\n+ 133 : SPQR(matrix, config.get(\"verbose\", 0))\n+ 134 {}\n+ 135\n+137 SPQR() : matrixIsLoaded_(false), verbose_(0)\n+ 138 {\n+ 139 //check whether T is a supported type\n+ 140 static_assert((std::is_same::value) || (std::is_same >::value),\n+ 141 \"Unsupported Type in SPQR (only double and std::complex\n+supported)\");\n+ 142 cc_ = new cholmod_common();\n+ 143 cholmod_l_start(cc_);\n+ 144 }\n+ 145\n+147 virtual ~SPQR()\n+ 148 {\n+ 149 if ((spqrMatrix_.N() + spqrMatrix_.M() > 0) || matrixIsLoaded_)\n+ 150 free();\n+ 151 cholmod_l_finish(cc_);\n+ 152 }\n 153\n- 154 template<>\n-155 struct GetSuperLUType >\n- 156 : public BaseGetSuperLUType >\n- 157 {\n-158 typedef double float_type;\n- 159 };\n- 160\n- 161 template<>\n-162 struct GetSuperLUType >\n- 163 : public BaseGetSuperLUType >\n- 164 {\n-165 typedef float float_type;\n- 166\n- 167 };\n- 168\n- 173 template\n-174 struct SuperLUMatrix\n- 175 {};\n- 176\n- 177 template\n-178 struct SuperMatrixInitializer\n- 179 {};\n- 180\n- 181 template\n- 182 class SuperLU;\n- 183\n- 184 template\n- 185 class SeqOverlappingSchwarz;\n- 186\n- 187 template\n- 188 struct SeqOverlappingSchwarzAssemblerHelper;\n+155 virtual void apply(domain_type& x, range_type& b, InverseOperatorResult&\n+res)\n+ 156 {\n+ 157 const std::size_t numRows(spqrMatrix_.N());\n+ 158 // fill B\n+ 159 for(std::size_t k = 0; k != numRows/n; ++k)\n+ 160 for (int l = 0; l < n; ++l)\n+ 161 (static_cast(B_->x))[n*k+l] = b[k][l];\n+ 162\n+ 163 cholmod_dense* BTemp = B_;\n+ 164 B_ = SuiteSparseQR_qmult(0, spqrfactorization_, B_, cc_);\n+ 165 cholmod_dense* X = SuiteSparseQR_solve(1, spqrfactorization_, B_, cc_);\n+ 166 cholmod_l_free_dense(&BTemp, cc_);\n+ 167\n+ 168 const std::size_t numCols(spqrMatrix_.M());\n+ 169 // fill x\n+ 170 for(std::size_t k = 0; k != numCols/m; ++k)\n+ 171 for (int l = 0; l < m; ++l)\n+ 172 x[k][l] = (static_cast(X->x))[m*k+l];\n+ 173\n+ 174 cholmod_l_free_dense(&X, cc_);\n+ 175 // this is a direct solver\n+ 176 res.iterations = 1;\n+ 177 res.converged = true;\n+ 178 if(verbose_ > 0)\n+ 179 {\n+ 180 std::cout<SPQR_flopcount<SPQR_analyze_time<<\" s\"<SPQR_factorize_time<<\" s\"<SPQR_solve_time<<\" s\"<memory_usage<<\" bytes\"<SPQR_istat[4]<\n-194 class SuperLUMatrix >\n- 195 : public ISTL::Impl::BCCSMatrix::field_type,\n-int>\n- 196 {\n- 197 template\n-198 friend class SeqOverlappingSchwarz;\n- 199 friend struct SuperMatrixInitializer >;\n- 200 public:\n-202 typedef BCRSMatrix Matrix;\n- 203\n- 204 friend struct SeqOverlappingSchwarzAssemblerHelper, true>;\n- 205\n-206 typedef typename Matrix::size_type size_type;\n- 207\n-212 explicit SuperLUMatrix(const Matrix& mat) : ISTL::Impl::\n-BCCSMatrix, int>(mat)\n- 213 {}\n- 214\n-215 SuperLUMatrix() : ISTL::Impl::BCCSMatrix::\n-field_type, int>()\n- 216 {}\n- 217\n-219 virtual ~SuperLUMatrix()\n- 220 {\n- 221 if (this->N_+this->M_*this->Nnz_ != 0)\n- 222 free();\n- 223 }\n+191 virtual void apply (domain_type& x, range_type& b, [[maybe_unused]] double\n+reduction, InverseOperatorResult& res)\n+ 192 {\n+ 193 apply(x, b, res);\n+ 194 }\n+ 195\n+196 void setOption([[maybe_unused]] unsigned int option, [[maybe_unused]]\n+double value)\n+ 197 {}\n+ 198\n+200 void setMatrix(const Matrix& matrix)\n+ 201 {\n+ 202 if ((spqrMatrix_.N() + spqrMatrix_.M() > 0) || matrixIsLoaded_)\n+ 203 free();\n+ 204\n+ 205 if (spqrMatrix_.N() + spqrMatrix_.M() + spqrMatrix_.nonzeroes() != 0)\n+ 206 spqrMatrix_.free();\n+ 207 spqrMatrix_.setSize(MatrixDimension::rowdim(matrix),\n+ 208 MatrixDimension::coldim(matrix));\n+ 209 ISTL::Impl::BCCSMatrixInitializer initializer(spqrMatrix_);\n+ 210\n+ 211 copyToBCCSMatrix(initializer, matrix);\n+ 212\n+ 213 decompose();\n+ 214 }\n+ 215\n+ 216 template\n+217 void setSubMatrix(const Matrix& matrix, const S& rowIndexSet)\n+ 218 {\n+ 219 if ((spqrMatrix_.N() + spqrMatrix_.M() > 0) || matrixIsLoaded_)\n+ 220 free();\n+ 221\n+ 222 if (spqrMatrix_.N() + spqrMatrix_.M() + spqrMatrix_.nonzeroes() != 0)\n+ 223 spqrMatrix_.free();\n 224\n-226 operator SuperMatrix&()\n- 227 {\n- 228 return A;\n- 229 }\n+ 225 spqrMatrix_.setSize(rowIndexSet.size()*MatrixDimension::rowdim\n+(matrix) / matrix.N(),\n+ 226 rowIndexSet.size()*MatrixDimension::coldim(matrix) / matrix.M());\n+ 227 ISTL::Impl::BCCSMatrixInitializer initializer(spqrMatrix_);\n+ 228\n+ 229 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset >(matrix,rowIndexSet));\n 230\n-232 operator const SuperMatrix&() const\n- 233 {\n- 234 return A;\n- 235 }\n- 236\n-237 SuperLUMatrix >& operator=(const BCRSMatrix& mat)\n- 238 {\n- 239 if (this->N_ + this->M_ + this->Nnz_!=0)\n- 240 free();\n- 241\n- 242 using Matrix = BCRSMatrix;\n- 243 this->N_ = MatrixDimension::rowdim(mat);\n- 244 this->M_ = MatrixDimension::coldim(mat);\n- 245 ISTL::Impl::BCCSMatrixInitializer initializer(*this);\n- 246\n- 247 copyToBCCSMatrix(initializer, mat);\n- 248\n- 249 SuperMatrixCreateSparseChooser\n- 250::create(&A, this->N_, this->M_, this->colstart[this->N_],\n- 251 this->values,this->rowindex, this->colstart, SLU_NC,\n- 252 static_cast(GetSuperLUType::type),\n-SLU_GE);\n- 253 return *this;\n- 254 }\n- 255\n-256 SuperLUMatrix >& operator=(const SuperLUMatrix\n- >& mat)\n+ 231 decompose();\n+ 232 }\n+ 233\n+238 inline void setVerbosity(int v)\n+ 239 {\n+ 240 verbose_=v;\n+ 241 }\n+ 242\n+247 inline SuiteSparseQR_factorization* getFactorization()\n+ 248 {\n+ 249 return spqrfactorization_;\n+ 250 }\n+ 251\n+256 inline SPQRMatrix& getInternalMatrix()\n 257 {\n- 258 if (this->N_ + this->M_ + this->Nnz_!=0)\n- 259 free();\n+ 258 return spqrMatrix_;\n+ 259 }\n 260\n- 261 using Matrix = BCRSMatrix;\n- 262 this->N_ = MatrixDimension::rowdim(mat);\n- 263 this->M_ = MatrixDimension::coldim(mat);\n- 264 ISTL::Impl::BCCSMatrixInitializer initializer(*this);\n- 265\n- 266 copyToBCCSMatrix(initializer, mat);\n- 267\n- 268 SuperMatrixCreateSparseChooser\n- 269::create(&A, this->N_, this->M_, this->colstart[this->N_],\n- 270 this->values,this->rowindex, this->colstart, SLU_NC,\n- 271 static_cast(GetSuperLUType::type), SLU_GE);\n- 272 return *this;\n- 273 }\n- 274\n-281 virtual void setMatrix(const Matrix& mat, const std::set& mrs)\n- 282 {\n- 283 if(this->N_+this->M_+this->Nnz_!=0)\n- 284 free();\n- 285 this->N_=mrs.size()*MatrixDimension::rowdim(*\n-(mat[0].begin()));\n- 286 this->M_=mrs.size()*MatrixDimension::coldim(*\n-(mat[0].begin()));\n- 287 SuperMatrixInitializer initializer(*this);\n- 288\n- 289 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset >(mat,mrs));\n- 290 }\n- 291\n-293 virtual void setMatrix(const Matrix& mat)\n- 294 {\n- 295 this->N_=MatrixDimension::rowdim(mat);\n- 296 this->M_=MatrixDimension::coldim(mat);\n- 297 SuperMatrixInitializer initializer(*this);\n- 298\n- 299 copyToBCCSMatrix(initializer, mat);\n- 300 }\n- 301\n-303 virtual void free()\n- 304 {\n- 305 ISTL::Impl::BCCSMatrix::field_type, int>::free\n-();\n- 306 SUPERLU_FREE(A.Store);\n- 307 }\n- 308 private:\n- 309 SuperMatrix A;\n- 310 };\n+265 void free()\n+ 266 {\n+ 267 cholmod_l_free_sparse(&A_, cc_);\n+ 268 cholmod_l_free_dense(&B_, cc_);\n+ 269 SuiteSparseQR_free(&spqrfactorization_, cc_);\n+ 270 spqrMatrix_.free();\n+ 271 matrixIsLoaded_ = false;\n+ 272 }\n+ 273\n+275 inline const char* name()\n+ 276 {\n+ 277 return \"SPQR\";\n+ 278 }\n+ 279\n+ 280 private:\n+ 281 template\n+282 friend class SeqOverlappingSchwarz;\n+ 283\n+ 284 friend struct SeqOverlappingSchwarzAssemblerHelper,true>;\n+ 285\n+ 287 void decompose()\n+ 288 {\n+ 289 const std::size_t nrows(spqrMatrix_.N());\n+ 290 const std::size_t ncols(spqrMatrix_.M());\n+ 291 const std::size_t nnz(spqrMatrix_.getColStart()[ncols]);\n+ 292\n+ 293 // initialise the matrix A (sorted, packed, unsymmetric, real entries)\n+ 294 A_ = cholmod_l_allocate_sparse(nrows, ncols, nnz, 1, 1, 0, 1, cc_);\n+ 295\n+ 296 // copy all the entries of Ap, Ai, Ax\n+ 297 for(std::size_t k = 0; k != (ncols+1); ++k)\n+ 298 (static_cast(A_->p))[k] = spqrMatrix_.getColStart()[k];\n+ 299\n+ 300 for(std::size_t k = 0; k != nnz; ++k)\n+ 301 {\n+ 302 (static_cast(A_->i))[k] = spqrMatrix_.getRowIndex()[k];\n+ 303 (static_cast(A_->x))[k] = spqrMatrix_.getValues()[k];\n+ 304 }\n+ 305\n+ 306 // initialise the vector B\n+ 307 B_ = cholmod_l_allocate_dense(nrows, 1, nrows, A_->xtype, cc_);\n+ 308 // compute factorization of A\n+ 309 spqrfactorization_=SuiteSparseQR_factorize\n+(SPQR_ORDERING_DEFAULT,SPQR_DEFAULT_TOL,A_,cc_);\n+ 310 }\n 311\n- 312 template\n-313 class SuperMatrixInitializer >\n- 314 : public ISTL::Impl::BCCSMatrixInitializer, int>\n- 315 {\n- 316 template\n-317 friend class OverlappingSchwarzInitializer;\n- 318 public:\n-319 typedef BCRSMatrix Matrix;\n-320 typedef Dune::SuperLUMatrix SuperLUMatrix;\n- 321\n-322 SuperMatrixInitializer(SuperLUMatrix& lum) : ISTL::Impl::\n-BCCSMatrixInitializer, int>(lum)\n- 323 ,slumat(&lum)\n- 324 {}\n- 325\n-326 SuperMatrixInitializer() : ISTL::Impl::\n-BCCSMatrixInitializer, int>()\n- 327 {}\n- 328\n-329 virtual void createMatrix() const\n- 330 {\n- 331 ISTL::Impl::BCCSMatrixInitializer, int>::createMatrix();\n- 332 SuperMatrixCreateSparseChooser\n- 333::create(&slumat->A, slumat->N_, slumat->M_, slumat->colstart[this->cols],\n- 334 slumat->values,slumat->rowindex, slumat->colstart, SLU_NC,\n- 335 static_cast(GetSuperLUType::type),\n-SLU_GE);\n- 336 }\n- 337 private:\n- 338 SuperLUMatrix* slumat;\n- 339 };\n- 340}\n- 341#endif // HAVE_SUPERLU\n- 342#endif\n-superlufunctions.hh\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n+ 312 SPQRMatrix spqrMatrix_;\n+ 313 bool matrixIsLoaded_;\n+ 314 int verbose_;\n+ 315 cholmod_common* cc_;\n+ 316 cholmod_sparse* A_;\n+ 317 cholmod_dense* B_;\n+ 318 SuiteSparseQR_factorization* spqrfactorization_;\n+ 319 };\n+ 320\n+ 321 template\n+322 struct IsDirectSolver > >\n+ 323 {\n+324 enum {value = true};\n+ 325 };\n+ 326\n+ 327 template\n+328 struct StoresColumnCompressed > >\n+ 329 {\n+330 enum {value = true};\n+ 331 };\n+ 332\n+333 struct SPQRCreator {\n+334 template struct isValidBlock : std::false_type{};\n+ 335\n+ 336 template\n+ 337 std::shared_ptr::type,\n+ 338 typename Dune::TypeListElement<2, TL>::type>>\n+339 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& config,\n+ 340 std::enable_if_t<\n+ 341 isValidBlock::type::block_type>::\n+value,int> = 0) const\n+ 342 {\n+ 343 int verbose = config.get(\"verbose\", 0);\n+ 344 return std::make_shared>(mat,verbose);\n+ 345 }\n+ 346\n+ 347 // second version with SFINAE to validate the template parameters of SPQR\n+ 348 template\n+ 349 std::shared_ptr::type,\n+ 350 typename Dune::TypeListElement<2, TL>::type>>\n+351 operator()(TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n+*config*/,\n+ 352 std::enable_if_t::\n+type::block_type>::value,int> = 0) const\n+ 353 {\n+ 354 DUNE_THROW(UnsupportedType,\n+ 355 \"Unsupported Type in SPQR (only double and std::complex\n+supported)\");\n+ 356 }\n+ 357 };\n+358 template<> struct SPQRCreator::isValidBlock> : std::\n+true_type{};\n+ 359 // std::complex is temporary disabled, because it fails if libc++ is used\n+ 360 //template<> struct SPQRCreator::isValidMatrixBlock,1,1>> : std::true_type{};\n+361 DUNE_REGISTER_DIRECT_SOLVER(\"spqr\", Dune::SPQRCreator());\n+ 362\n+ 363} // end namespace Dune\n+ 364\n+ 365\n+ 366#endif //HAVE_SUITESPARSE_SPQR\n+ 367#endif //DUNE_ISTL_SPQR_HH\n+solvertype.hh\n+Templates characterizing the type of a solver.\n bccsmatrixinitializer.hh\n+solvers.hh\n+Implementations of the inverse operator interface.\n+solverfactory.hh\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::~SPQR\n+virtual ~SPQR()\n+Destructor.\n+Definition: spqr.hh:147\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::SPQR\n+SPQR(const Matrix &matrix, int verbose, bool)\n+Constructor for compatibility with SuperLU standard constructor.\n+Definition: spqr.hh:113\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::category\n+virtual SolverCategory::Category category() const\n+Category of the solver (see SolverCategory::Category)\n+Definition: spqr.hh:82\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::getInternalMatrix\n+SPQRMatrix & getInternalMatrix()\n+Return the column coppressed matrix.\n+Definition: spqr.hh:256\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::setMatrix\n+void setMatrix(const Matrix &matrix)\n+Initialize data from given matrix.\n+Definition: spqr.hh:200\n+Dune::DUNE_REGISTER_DIRECT_SOLVER\n+DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::MatrixInitializer\n+ISTL::Impl::BCCSMatrixInitializer< BCRSMatrix< FieldMatrix< T, n, m >, A >, int\n+> MatrixInitializer\n+Type of an associated initializer class.\n+Definition: spqr.hh:75\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::SPQR\n+SPQR()\n+Default constructor.\n+Definition: spqr.hh:137\n+Dune::SPQRCreator::operator()\n+std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL\n+>::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const\n+M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock<\n+typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0)\n+const\n+Definition: spqr.hh:339\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::name\n+const char * name()\n+Get method name.\n+Definition: spqr.hh:275\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::getFactorization\n+SuiteSparseQR_factorization< T > * getFactorization()\n+Return the matrix factorization.\n+Definition: spqr.hh:247\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::setVerbosity\n+void setVerbosity(int v)\n+Sets the verbosity level for the solver.\n+Definition: spqr.hh:238\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::SPQRMatrix\n+ISTL::Impl::BCCSMatrix< T, int > SPQRMatrix\n+The corresponding SuperLU Matrix type.\n+Definition: spqr.hh:73\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::apply\n+virtual void apply(domain_type &x, range_type &b, double reduction,\n+InverseOperatorResult &res)\n+apply inverse operator, with given convergence criteria.\n+Definition: spqr.hh:191\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::free\n+void free()\n+Free allocated space.\n+Definition: spqr.hh:265\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::SPQR\n+SPQR(const Matrix &matrix, const ParameterTree &config)\n+Constructs the SPQR solver.\n+Definition: spqr.hh:132\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::range_type\n+Dune::BlockVector< FieldVector< T, n >, typename std::allocator_traits< A >::\n+template rebind_alloc< FieldVector< T, n > > > range_type\n+The type of the range of the solver.\n+Definition: spqr.hh:79\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::setSubMatrix\n+void setSubMatrix(const Matrix &matrix, const S &rowIndexSet)\n+Definition: spqr.hh:217\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::domain_type\n+Dune::BlockVector< FieldVector< T, m >, typename std::allocator_traits< A >::\n+template rebind_alloc< FieldVector< T, m > > > domain_type\n+The type of the domain of the solver.\n+Definition: spqr.hh:77\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::apply\n+virtual void apply(domain_type &x, range_type &b, InverseOperatorResult &res)\n+Apply inverse operator,.\n+Definition: spqr.hh:155\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::setOption\n+void setOption(unsigned int option, double value)\n+Definition: spqr.hh:196\n+Dune::SPQR<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>::SPQR\n+SPQR(const Matrix &matrix, int verbose=0)\n+Construct a solver object from a BCRSMatrix.\n+Definition: spqr.hh:95\n mat\n Matrix & mat\n Definition: matrixmatrix.hh:347\n-std\n-STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::OverlappingSchwarzInitializer\n-Initializer for SuperLU Matrices representing the subdomains.\n-Definition: overlappingschwarz.hh:47\n-Dune::MatrixDimension::coldim\n-static auto coldim(const M &A)\n-Definition: matrixutils.hh:219\n-Dune::MatrixDimension::rowdim\n-static auto rowdim(const M &A)\n-Definition: matrixutils.hh:214\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::MatrixDimension\n+Definition: matrixutils.hh:211\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::M\n+size_type M() const\n+number of columns (counted in blocks)\n+Definition: bcrsmatrix.hh:1978\n+Dune::BCRSMatrix::N\n+size_type N() const\n+number of rows (counted in blocks)\n+Definition: bcrsmatrix.hh:1972\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n Dune::SeqOverlappingSchwarz\n Sequential overlapping Schwarz preconditioner.\n Definition: overlappingschwarz.hh:755\n Dune::SeqOverlappingSchwarzAssemblerHelper\n Definition: overlappingschwarz.hh:694\n-Dune::SuperLU\n-SuperLu Solver.\n-Definition: superlu.hh:271\n-Dune::SuperMatrixCreateSparseChooser\n-Definition: supermatrix.hh:26\n-Dune::SuperMatrixPrinter\n-Definition: supermatrix.hh:30\n-Dune::BaseGetSuperLUType\n-Definition: supermatrix.hh:126\n-Dune::BaseGetSuperLUType::type\n-static const Dtype_t type\n-Definition: supermatrix.hh:127\n-Dune::GetSuperLUType\n-Definition: supermatrix.hh:132\n-Dune::GetSuperLUType<_double_>::float_type\n-double float_type\n-Definition: supermatrix.hh:144\n-Dune::GetSuperLUType<_float_>::float_type\n-float float_type\n-Definition: supermatrix.hh:151\n-Dune::GetSuperLUType<_std::complex<_double_>_>::float_type\n-double float_type\n-Definition: supermatrix.hh:158\n-Dune::GetSuperLUType<_std::complex<_float_>_>::float_type\n-float float_type\n-Definition: supermatrix.hh:165\n-Dune::SuperLUMatrix\n-Utility class for converting an ISTL Matrix into a SuperLU Matrix.\n-Definition: supermatrix.hh:175\n-Dune::SuperMatrixInitializer\n-Definition: supermatrix.hh:179\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::free\n-virtual void free()\n-free allocated space.\n-Definition: supermatrix.hh:303\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::operator=\n-SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const SuperLUMatrix<\n-BCRSMatrix< B, TA > > &mat)\n-Definition: supermatrix.hh:256\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::operator=\n-SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const BCRSMatrix< B, TA >\n-&mat)\n-Definition: supermatrix.hh:237\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::SuperLUMatrix\n-SuperLUMatrix(const Matrix &mat)\n-Constructor that initializes the data.\n-Definition: supermatrix.hh:212\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::setMatrix\n-virtual void setMatrix(const Matrix &mat)\n-Initialize data from given matrix.\n-Definition: supermatrix.hh:293\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::SuperLUMatrix\n-SuperLUMatrix()\n-Definition: supermatrix.hh:215\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::size_type\n-Matrix::size_type size_type\n-Definition: supermatrix.hh:206\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::Matrix\n-BCRSMatrix< B, TA > Matrix\n-The type of the matrix to convert.\n-Definition: supermatrix.hh:202\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::setMatrix\n-virtual void setMatrix(const Matrix &mat, const std::set< std::size_t > &mrs)\n-Initialize data from a given set of matrix rows and columns.\n-Definition: supermatrix.hh:281\n-Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::~SuperLUMatrix\n-virtual ~SuperLUMatrix()\n-Destructor.\n-Definition: supermatrix.hh:219\n-Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperLUMatrix\n-Dune::SuperLUMatrix< Matrix > SuperLUMatrix\n-Definition: supermatrix.hh:320\n-Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::Matrix\n-BCRSMatrix< B, A > Matrix\n-Definition: supermatrix.hh:319\n-Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperMatrixInitializer\n-SuperMatrixInitializer()\n-Definition: supermatrix.hh:326\n-Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::createMatrix\n-virtual void createMatrix() const\n-Definition: supermatrix.hh:329\n-Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperMatrixInitializer\n-SuperMatrixInitializer(SuperLUMatrix &lum)\n-Definition: supermatrix.hh:322\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperatorResult::iterations\n+int iterations\n+Number of iterations.\n+Definition: solver.hh:67\n+Dune::InverseOperatorResult::converged\n+bool converged\n+True if convergence criterion has been met.\n+Definition: solver.hh:73\n+Dune::InverseOperator\n+Abstract base class for all solvers.\n+Definition: solver.hh:99\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::UnsupportedType\n+Definition: solverregistry.hh:77\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n+Dune::IsDirectSolver::value\n+@ value\n+Whether this is a direct solver.\n+Definition: solvertype.hh:24\n+Dune::StoresColumnCompressed\n+Definition: solvertype.hh:30\n+Dune::StoresColumnCompressed::value\n+@ value\n+whether the solver internally uses column compressed storage\n+Definition: solvertype.hh:36\n+Dune::SPQR\n+Use the SPQR package to directly solve linear systems \u2013 empty default class.\n+Definition: spqr.hh:48\n+Dune::SPQRCreator\n+Definition: spqr.hh:333\n+Dune::SPQRCreator::isValidBlock\n+Definition: spqr.hh:334\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00062.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00062.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: counter.hh File Reference\n+dune-istl: matrixutils.hh File Reference\n \n \n \n \n \n \n \n@@ -58,125 +58,99 @@\n \n
    \n \n \n
    \n
    \n \n-
    counter.hh File Reference
    \n+Functions
    \n+ \n
    \n
    \n-
    #include <cassert>
    \n-#include <typeinfo>
    \n-#include <iostream>
    \n-#include <memory>
    \n-#include <tuple>
    \n-#include <utility>
    \n-#include <dune/common/typeutilities.hh>
    \n+\n+

    Some handy generic functions for ISTL matrices. \n+More...

    \n+
    #include <set>
    \n+#include <vector>
    \n+#include <limits>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/dynmatrix.hh>
    \n+#include <dune/common/diagonalmatrix.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/istl/scaledidmatrix.hh>
    \n+#include "istlexception.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Classes

    struct  Dune::CheckIfDiagonalPresent< Matrix, blocklevel, l >
     Check whether the a matrix has diagonal values on blocklevel recursion levels. More...
     
    struct  Dune::CheckIfDiagonalPresent< Matrix, 0, l >
     
    struct  Dune::CheckIfDiagonalPresent< MultiTypeBlockMatrix< T1, Args... >, blocklevel, l >
     
    struct  Dune::MatrixDimension< M >
     
    struct  Dune::MatrixDimension< Matrix< B, TA > >
     
    struct  Dune::MatrixDimension< BCRSMatrix< B, TA > >
     
    struct  Dune::MatrixDimension< BCRSMatrix< FieldMatrix< B, n, m >, TA > >
     
    struct  Dune::MatrixDimension< FieldMatrix< K, n, m > >
     
    struct  Dune::MatrixDimension< Dune::DynamicMatrix< T > >
     
    struct  Dune::MatrixDimension< Matrix< FieldMatrix< K, n, m >, TA > >
     
    struct  Dune::MatrixDimension< DiagonalMatrix< K, n > >
     
    struct  Dune::MatrixDimension< ScaledIdentityMatrix< K, n > >
     
    struct  Dune::IsMatrix< T >
     Test whether a type is an ISTL Matrix. More...
     
    struct  Dune::IsMatrix< DenseMatrix< T > >
     
    struct  Dune::IsMatrix< BCRSMatrix< T, A > >
     
    struct  Dune::PointerCompare< T >
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::CounterImpl
     
    \n-\n-\n-\n-\n-\n-

    \n-Macros

    #define DUNE_GET_COUNTER(Tag)    (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
     
    #define DUNE_INC_COUNTER(Tag)
     
    \n-\n-\n-\n-

    \n-Variables

    constexpr std::size_t maxcount = 100
     
    \n-

    Macro Definition Documentation

    \n-\n-

    ◆ DUNE_GET_COUNTER

    \n-\n-
    \n-
    \n- \n- \n- \n- \n- \n- \n- \n- \n-
    #define DUNE_GET_COUNTER( Tag)    (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
    \n-
    \n-\n-
    \n-
    \n-\n-

    ◆ DUNE_INC_COUNTER

    \n-\n-
    \n-
    \n- \n- \n- \n- \n- \n- \n- \n- \n-
    #define DUNE_INC_COUNTER( Tag)
    \n-
    \n-Value:
    namespace { \\
    \n-
    namespace CounterImpl { \\
    \n-
    constexpr std::size_t \\
    \n-
    counterFunc(Dune::PriorityTag<DUNE_GET_COUNTER(Tag)+1> p, Tag, ADLTag) \\
    \n-
    { \\
    \n-
    return p.value; \\
    \n-
    } \\
    \n-
    } \\
    \n-
    } \\
    \n-
    static_assert(true, "unfudge indentation")
    \n-
    #define DUNE_GET_COUNTER(Tag)
    Definition: counter.hh:17
    \n-
    \n-
    \n-
    \n-

    Variable Documentation

    \n-\n-

    ◆ maxcount

    \n-\n-
    \n-
    \n-\n- \n- \n- \n- \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n
    \n- \n- \n- \n- \n-
    constexpr std::size_t maxcount = 100
    \n-
    \n-constexpr

    \n+Functions

    template<class M >
    auto Dune::countNonZeros (const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
     Get the number of nonzero fields in the matrix. More...
     
    template<class M >
    auto Dune::countNonZeros (const M &matrix, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
     
    template<class M , class C >
    void Dune::printGlobalSparseMatrix (const M &mat, C &ooc, std::ostream &os)
     
    \n-
    \n-\n-
    \n-
    \n-
    \n+

    Detailed Description

    \n+

    Some handy generic functions for ISTL matrices.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,58 +4,82 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * common\n-Namespaces | Macros | Variables\n-counter.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+matrixutils.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes\n+Some handy generic functions for ISTL matrices. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"istlexception.hh\"\n Go_to_the_source_code_of_this_file.\n+ Classes\n+struct \u00a0Dune::CheckIfDiagonalPresent<_Matrix,_blocklevel,_l_>\n+\u00a0 Check whether the a matrix has diagonal values on blocklevel recursion\n+ levels. More...\n+\u00a0\n+struct \u00a0Dune::CheckIfDiagonalPresent<_Matrix,_0,_l_>\n+\u00a0\n+struct \u00a0Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,\n+ blocklevel,_l_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_M_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_Matrix<_B,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>\n+\u00a0\n+struct \u00a0Dune::IsMatrix<_T_>\n+\u00a0 Test whether a type is an ISTL Matrix. More...\n+\u00a0\n+struct \u00a0Dune::IsMatrix<_DenseMatrix<_T_>_>\n+\u00a0\n+struct \u00a0Dune::IsMatrix<_BCRSMatrix<_T,_A_>_>\n+\u00a0\n+struct \u00a0Dune::PointerCompare<_T_>\n+\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::CounterImpl\n+ Functions\n+template\n+auto\u00a0Dune::countNonZeros (const M &, typename std::enable_if_t< Dune::\n+ IsNumber< M >::value > *sfinae=nullptr)\n+\u00a0 Get the number of nonzero fields in the matrix. More...\n+\u00a0\n+template\n+auto\u00a0Dune::countNonZeros (const M &matrix, typename std::enable_if_t::value > *sfinae=nullptr)\n+\u00a0\n+template\n+void\u00a0Dune::printGlobalSparseMatrix (const M &mat, C &ooc, std::ostream &os)\n \u00a0\n- Macros\n-#define\u00a0DUNE_GET_COUNTER(Tag)\u00a0\u00a0\u00a0 (counterFunc(Dune::PriorityTag{}, Tag{},\n- Dune::CounterImpl::ADLTag{}))\n-\u00a0\n-#define\u00a0DUNE_INC_COUNTER(Tag)\n-\u00a0\n- Variables\n-constexpr std::size_t\u00a0maxcount = 100\n-\u00a0\n-***** Macro Definition Documentation *****\n-***** \u25c6\u00a0DUNE_GET_COUNTER *****\n-#define ( \u00a0Tag ) \u00a0\u00a0\u00a0 (counterFunc(Dune::PriorityTag{}, Tag{}, Dune::CounterImpl::\n-DUNE_GET_COUNTER ADLTag{}))\n-***** \u25c6\u00a0DUNE_INC_COUNTER *****\n-#define DUNE_INC_COUNTER ( \u00a0Tag )\n-Value:\n-namespace { \\\n-namespace CounterImpl { \\\n-constexpr std::size_t \\\n-counterFunc(Dune::PriorityTag p, Tag, ADLTag) \\\n-{ \\\n-return p.value; \\\n-} \\\n-} \\\n-} \\\n-static_assert(true, \"unfudge indentation\")\n-DUNE_GET_COUNTER\n-#define DUNE_GET_COUNTER(Tag)\n-Definition: counter.hh:17\n-***** Variable Documentation *****\n-***** \u25c6\u00a0maxcount *****\n-constexpr std::size_t maxcount = 100 constexpr\n+***** Detailed Description *****\n+Some handy generic functions for ISTL matrices.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00062_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00062_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: counter.hh Source File\n+dune-istl: matrixutils.hh Source File\n \n \n \n \n \n \n \n@@ -58,71 +58,607 @@\n \n
    \n \n \n
    \n
    \n-
    counter.hh
    \n+
    matrixutils.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3#ifndef DUNE_ISTL_COMMON_COUNTER_HH
    \n-
    4#define DUNE_ISTL_COMMON_COUNTER_HH
    \n-
    5
    \n-
    6#include <cassert>
    \n-
    7#include <typeinfo>
    \n-
    8#include <iostream>
    \n-
    9#include <memory>
    \n-
    10#include <tuple>
    \n-
    11#include <utility>
    \n-
    12
    \n-
    13#include <dune/common/typeutilities.hh>
    \n-
    14
    \n-
    15constexpr std::size_t maxcount = 100;
    \n-
    16
    \n-
    17#define DUNE_GET_COUNTER(Tag) \\
    \n-
    18 (counterFunc(Dune::PriorityTag<maxcount>{}, Tag{}, Dune::CounterImpl::ADLTag{}))
    \n-
    19
    \n-
    20#define DUNE_INC_COUNTER(Tag) \\
    \n-
    21 namespace { \\
    \n-
    22 namespace CounterImpl { \\
    \n-
    23 constexpr std::size_t \\
    \n-
    24 counterFunc(Dune::PriorityTag<DUNE_GET_COUNTER(Tag)+1> p, Tag, ADLTag) \\
    \n-
    25 { \\
    \n-
    26 return p.value; \\
    \n-
    27 } \\
    \n-
    28 } \\
    \n-
    29 } \\
    \n-
    30 static_assert(true, "unfudge indentation")
    \n-
    31
    \n-
    32namespace Dune {
    \n-
    33 namespace {
    \n-
    34
    \n-
    35 namespace CounterImpl {
    \n-
    36
    \n-
    37 struct ADLTag {};
    \n-
    38
    \n-
    39 template<class Tag>
    \n-
    40 constexpr std::size_t counterFunc(Dune::PriorityTag<0>, Tag, ADLTag)
    \n-
    41 {
    \n-
    42 return 0;
    \n-
    43 }
    \n-
    44
    \n-
    45 } // end namespace CounterImpl
    \n-
    46 } // end empty namespace
    \n-
    47} // end namespace Dune
    \n-
    48#endif // DUNE_ISTL_COMMON_COUNTER_HH
    \n-
    constexpr std::size_t maxcount
    Definition: counter.hh:15
    \n+
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n+
    4// vi: set et ts=4 sw=2 sts=2:
    \n+
    5#ifndef DUNE_ISTL_MATRIXUTILS_HH
    \n+
    6#define DUNE_ISTL_MATRIXUTILS_HH
    \n+
    7
    \n+
    8#include <set>
    \n+
    9#include <vector>
    \n+
    10#include <limits>
    \n+
    11#include <dune/common/typetraits.hh>
    \n+
    12#include <dune/common/fmatrix.hh>
    \n+
    13#include <dune/common/dynmatrix.hh>
    \n+
    14#include <dune/common/diagonalmatrix.hh>
    \n+
    15#include <dune/common/scalarmatrixview.hh>
    \n+\n+
    17#include "istlexception.hh"
    \n+
    18
    \n+
    19namespace Dune
    \n+
    20{
    \n+
    21
    \n+
    22#ifndef DOYXGEN
    \n+
    23 template<typename B, typename A>
    \n+
    24 class BCRSMatrix;
    \n+
    25
    \n+
    26 template<typename K, int n, int m>
    \n+\n+
    28
    \n+
    29 template<class T, class A>
    \n+
    30 class Matrix;
    \n+
    31#endif
    \n+
    32
    \n+
    46 template<class Matrix, std::size_t blocklevel, std::size_t l=blocklevel>
    \n+\n+
    48 {
    \n+
    53 static void check([[maybe_unused]] const Matrix& mat)
    \n+
    54 {
    \n+
    55#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    56 typedef typename Matrix::ConstRowIterator Row;
    \n+
    57 typedef typename Matrix::ConstColIterator Entry;
    \n+
    58 for(Row row = mat.begin(); row!=mat.end(); ++row) {
    \n+
    59 Entry diagonal = row->find(row.index());
    \n+
    60 if(diagonal==row->end())
    \n+
    61 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
    \n+
    62 <<" at block recursion level "<<l-blocklevel);
    \n+
    63 else{
    \n+
    64 auto m = Impl::asMatrix(*diagonal);
    \n+
    65 CheckIfDiagonalPresent<decltype(m),blocklevel-1,l>::check(m);
    \n+
    66 }
    \n+
    67 }
    \n+
    68#endif
    \n+
    69 }
    \n+
    70 };
    \n+
    71
    \n+
    72 template<class Matrix, std::size_t l>
    \n+\n+
    74 {
    \n+
    75 static void check(const Matrix& mat)
    \n+
    76 {
    \n+
    77 typedef typename Matrix::ConstRowIterator Row;
    \n+
    78 for(Row row = mat.begin(); row!=mat.end(); ++row) {
    \n+
    79 if(row->find(row.index())==row->end())
    \n+
    80 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
    \n+
    81 <<" at block recursion level "<<l);
    \n+
    82 }
    \n+
    83 }
    \n+
    84 };
    \n+
    85
    \n+
    86 template<typename FirstRow, typename... Args>
    \n+
    87 class MultiTypeBlockMatrix;
    \n+
    88
    \n+
    89 template<std::size_t blocklevel, std::size_t l, typename T1, typename... Args>
    \n+\n+
    91 blocklevel,l>
    \n+
    92 {
    \n+
    93 typedef MultiTypeBlockMatrix<T1,Args...> Matrix;
    \n+
    94
    \n+
    99 static void check(const Matrix& /* mat */)
    \n+
    100 {
    \n+
    101#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    102 // TODO Implement check
    \n+
    103#endif
    \n+
    104 }
    \n+
    105 };
    \n+
    106
    \n+
    118 template<class M>
    \n+
    119 inline auto countNonZeros(const M&,
    \n+
    120 [[maybe_unused]] typename std::enable_if_t<Dune::IsNumber<M>::value>* sfinae = nullptr)
    \n+
    121 {
    \n+
    122 return 1;
    \n+
    123 }
    \n+
    124
    \n+
    125 template<class M>
    \n+
    126 inline auto countNonZeros(const M& matrix,
    \n+
    127 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
    \n+
    128 {
    \n+
    129 typename M::size_type nonZeros = 0;
    \n+
    130 for(auto&& row : matrix)
    \n+
    131 for(auto&& entry : row)
    \n+
    132 nonZeros += countNonZeros(entry);
    \n+
    133 return nonZeros;
    \n+
    134 }
    \n+
    135
    \n+
    136 /*
    \n+
    137 template<class M>
    \n+
    138 struct ProcessOnFieldsOfMatrix
    \n+
    139 */
    \n+
    140
    \n+
    142 namespace
    \n+
    143 {
    \n+
    144 struct CompPair {
    \n+
    145 template<class G,class M>
    \n+
    146 bool operator()(const std::pair<G,M>& p1, const std::pair<G,M>& p2) const
    \n+
    147 {
    \n+
    148 return p1.first<p2.first;
    \n+
    149 }
    \n+
    150 };
    \n+
    151
    \n+
    152 }
    \n+
    153 template<class M, class C>
    \n+
    154 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)
    \n+
    155 {
    \n+
    156 typedef typename C::ParallelIndexSet::const_iterator IIter;
    \n+
    157 typedef typename C::OwnerSet OwnerSet;
    \n+
    158 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;
    \n+
    159
    \n+
    160 GlobalIndex gmax=0;
    \n+
    161
    \n+
    162 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
    \n+
    163 idx!=eidx; ++idx)
    \n+
    164 gmax=std::max(gmax,idx->global());
    \n+
    165
    \n+
    166 gmax=ooc.communicator().max(gmax);
    \n+
    167 ooc.buildGlobalLookup();
    \n+
    168
    \n+
    169 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
    \n+
    170 idx!=eidx; ++idx) {
    \n+
    171 if(OwnerSet::contains(idx->local().attribute()))
    \n+
    172 {
    \n+
    173 typedef typename M::block_type Block;
    \n+
    174
    \n+
    175 std::set<std::pair<GlobalIndex,Block>,CompPair> entries;
    \n+
    176
    \n+
    177 // sort rows
    \n+
    178 typedef typename M::ConstColIterator CIter;
    \n+
    179 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();
    \n+
    180 c!=cend; ++c) {
    \n+
    181 const typename C::ParallelIndexSet::IndexPair* pair
    \n+
    182 =ooc.globalLookup().pair(c.index());
    \n+
    183 assert(pair);
    \n+
    184 entries.insert(std::make_pair(pair->global(), *c));
    \n+
    185 }
    \n+
    186
    \n+
    187 //wait until its the rows turn.
    \n+
    188 GlobalIndex rowidx = idx->global();
    \n+
    189 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
    \n+
    190 while(cur!=rowidx)
    \n+
    191 cur=ooc.communicator().min(rowidx);
    \n+
    192
    \n+
    193 // print rows
    \n+
    194 typedef typename std::set<std::pair<GlobalIndex,Block>,CompPair>::iterator SIter;
    \n+
    195 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)
    \n+
    196 os<<idx->global()<<" "<<s->first<<" "<<s->second<<std::endl;
    \n+
    197
    \n+
    198
    \n+
    199 }
    \n+
    200 }
    \n+
    201
    \n+
    202 ooc.freeGlobalLookup();
    \n+
    203 // Wait until everybody is finished
    \n+
    204 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
    \n+
    205 while(cur!=ooc.communicator().min(cur)) ;
    \n+
    206 }
    \n+
    207
    \n+
    208 // Default implementation for scalar types
    \n+
    209 template<typename M>
    \n+\n+
    211 {
    \n+
    212 static_assert(IsNumber<M>::value, "MatrixDimension is not implemented for this type!");
    \n+
    213
    \n+
    214 static auto rowdim(const M& A)
    \n+
    215 {
    \n+
    216 return 1;
    \n+
    217 }
    \n+
    218
    \n+
    219 static auto coldim(const M& A)
    \n+
    220 {
    \n+
    221 return 1;
    \n+
    222 }
    \n+
    223 };
    \n+
    224
    \n+
    225 // Default implementation for scalar types
    \n+
    226 template<typename B, typename TA>
    \n+
    227 struct MatrixDimension<Matrix<B,TA> >
    \n+
    228 {
    \n+\n+\n+
    231
    \n+\n+
    233 {
    \n+\n+
    235 }
    \n+
    236
    \n+\n+
    238 {
    \n+\n+
    240 }
    \n+
    241
    \n+
    242 static size_type rowdim (const Matrix<B,TA>& A)
    \n+
    243 {
    \n+
    244 size_type nn=0;
    \n+
    245 for (size_type i=0; i<A.N(); i++)
    \n+
    246 nn += rowdim(A,i);
    \n+
    247 return nn;
    \n+
    248 }
    \n+
    249
    \n+
    250 static size_type coldim (const Matrix<B,TA>& A)
    \n+
    251 {
    \n+
    252 size_type nn=0;
    \n+
    253 for (size_type i=0; i<A.M(); i++)
    \n+
    254 nn += coldim(A,i);
    \n+
    255 return nn;
    \n+
    256 }
    \n+
    257 };
    \n+
    258
    \n+
    259
    \n+
    260 template<typename B, typename TA>
    \n+\n+
    262 {
    \n+\n+\n+
    265 typedef typename Matrix::size_type size_type;
    \n+
    266
    \n+
    267 static size_type rowdim (const Matrix& A, size_type i)
    \n+
    268 {
    \n+
    269 const B* row = A.r[i].getptr();
    \n+
    270 if(row)
    \n+\n+
    272 else
    \n+
    273 return 0;
    \n+
    274 }
    \n+
    275
    \n+
    276 static size_type coldim (const Matrix& A, size_type c)
    \n+
    277 {
    \n+
    278 // find an entry in column c
    \n+
    279 if (A.nnz_ > 0)
    \n+
    280 {
    \n+
    281 for (size_type k=0; k<A.nnz_; k++) {
    \n+
    282 if (A.j_.get()[k] == c) {
    \n+\n+
    284 }
    \n+
    285 }
    \n+
    286 }
    \n+
    287 else
    \n+
    288 {
    \n+
    289 for (size_type i=0; i<A.N(); i++)
    \n+
    290 {
    \n+
    291 size_type* j = A.r[i].getindexptr();
    \n+
    292 B* a = A.r[i].getptr();
    \n+
    293 for (size_type k=0; k<A.r[i].getsize(); k++)
    \n+
    294 if (j[k]==c) {
    \n+\n+
    296 }
    \n+
    297 }
    \n+
    298 }
    \n+
    299
    \n+
    300 // not found
    \n+
    301 return 0;
    \n+
    302 }
    \n+
    303
    \n+
    304 static size_type rowdim (const Matrix& A){
    \n+
    305 size_type nn=0;
    \n+
    306 for (size_type i=0; i<A.N(); i++)
    \n+
    307 nn += rowdim(A,i);
    \n+
    308 return nn;
    \n+
    309 }
    \n+
    310
    \n+
    311 static size_type coldim (const Matrix& A){
    \n+
    312 typedef typename Matrix::ConstRowIterator ConstRowIterator;
    \n+
    313 typedef typename Matrix::ConstColIterator ConstColIterator;
    \n+
    314
    \n+
    315 // The following code has a complexity of nnz, and
    \n+
    316 // typically a very small constant.
    \n+
    317 //
    \n+
    318 std::vector<size_type> coldims(A.M(),
    \n+
    319 std::numeric_limits<size_type>::max());
    \n+
    320
    \n+
    321 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)
    \n+
    322 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)
    \n+
    323 // only compute blocksizes we don't already have
    \n+
    324 if (coldims[col.index()]==std::numeric_limits<size_type>::max())
    \n+
    325 coldims[col.index()] = MatrixDimension<block_type>::coldim(*col);
    \n+
    326
    \n+
    327 size_type sum = 0;
    \n+
    328 for (typename std::vector<size_type>::iterator it=coldims.begin();
    \n+
    329 it!=coldims.end(); ++it)
    \n+
    330 // skip rows for which no coldim could be determined
    \n+
    331 if ((*it)>=0)
    \n+
    332 sum += *it;
    \n+
    333
    \n+
    334 return sum;
    \n+
    335 }
    \n+
    336 };
    \n+
    337
    \n+
    338
    \n+
    339 template<typename B, int n, int m, typename TA>
    \n+\n+
    341 {
    \n+\n+
    343 typedef typename Matrix::size_type size_type;
    \n+
    344
    \n+
    345 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)
    \n+
    346 {
    \n+
    347 return n;
    \n+
    348 }
    \n+
    349
    \n+
    350 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)
    \n+
    351 {
    \n+
    352 return m;
    \n+
    353 }
    \n+
    354
    \n+
    355 static size_type rowdim (const Matrix& A) {
    \n+
    356 return A.N()*n;
    \n+
    357 }
    \n+
    358
    \n+
    359 static size_type coldim (const Matrix& A) {
    \n+
    360 return A.M()*m;
    \n+
    361 }
    \n+
    362 };
    \n+
    363
    \n+
    364 template<typename K, int n, int m>
    \n+\n+
    366 {
    \n+\n+
    368 typedef typename Matrix::size_type size_type;
    \n+
    369
    \n+
    370 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    371 {
    \n+
    372 return 1;
    \n+
    373 }
    \n+
    374
    \n+
    375 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    376 {
    \n+
    377 return 1;
    \n+
    378 }
    \n+
    379
    \n+
    380 static size_type rowdim(const Matrix& /*A*/)
    \n+
    381 {
    \n+
    382 return n;
    \n+
    383 }
    \n+
    384
    \n+
    385 static size_type coldim(const Matrix& /*A*/)
    \n+
    386 {
    \n+
    387 return m;
    \n+
    388 }
    \n+
    389 };
    \n+
    390
    \n+
    391 template <class T>
    \n+
    392 struct MatrixDimension<Dune::DynamicMatrix<T> >
    \n+
    393 {
    \n+
    394 typedef Dune::DynamicMatrix<T> MatrixType;
    \n+
    395 typedef typename MatrixType::size_type size_type;
    \n+
    396
    \n+
    397 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)
    \n+
    398 {
    \n+
    399 return 1;
    \n+
    400 }
    \n+
    401
    \n+
    402 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)
    \n+
    403 {
    \n+
    404 return 1;
    \n+
    405 }
    \n+
    406
    \n+
    407 static size_type rowdim(const MatrixType& A)
    \n+
    408 {
    \n+
    409 return A.N();
    \n+
    410 }
    \n+
    411
    \n+
    412 static size_type coldim(const MatrixType& A)
    \n+
    413 {
    \n+
    414 return A.M();
    \n+
    415 }
    \n+
    416 };
    \n+
    417
    \n+
    418 template<typename K, int n, int m, typename TA>
    \n+
    419 struct MatrixDimension<Matrix<FieldMatrix<K,n,m>, TA> >
    \n+
    420 {
    \n+\n+\n+
    423
    \n+
    424 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)
    \n+
    425 {
    \n+
    426 return n;
    \n+
    427 }
    \n+
    428
    \n+
    429 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)
    \n+
    430 {
    \n+
    431 return m;
    \n+
    432 }
    \n+
    433
    \n+
    434 static size_type rowdim(const ThisMatrix& A)
    \n+
    435 {
    \n+
    436 return A.N()*n;
    \n+
    437 }
    \n+
    438
    \n+
    439 static size_type coldim(const ThisMatrix& A)
    \n+
    440 {
    \n+
    441 return A.M()*m;
    \n+
    442 }
    \n+
    443 };
    \n+
    444
    \n+
    445 template<typename K, int n>
    \n+
    446 struct MatrixDimension<DiagonalMatrix<K,n> >
    \n+
    447 {
    \n+
    448 typedef DiagonalMatrix<K,n> Matrix;
    \n+
    449 typedef typename Matrix::size_type size_type;
    \n+
    450
    \n+
    451 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    452 {
    \n+
    453 return 1;
    \n+
    454 }
    \n+
    455
    \n+
    456 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    457 {
    \n+
    458 return 1;
    \n+
    459 }
    \n+
    460
    \n+
    461 static size_type rowdim(const Matrix& /*A*/)
    \n+
    462 {
    \n+
    463 return n;
    \n+
    464 }
    \n+
    465
    \n+
    466 static size_type coldim(const Matrix& /*A*/)
    \n+
    467 {
    \n+
    468 return n;
    \n+
    469 }
    \n+
    470 };
    \n+
    471
    \n+
    472 template<typename K, int n>
    \n+\n+
    474 {
    \n+\n+
    476 typedef typename Matrix::size_type size_type;
    \n+
    477
    \n+
    478 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    479 {
    \n+
    480 return 1;
    \n+
    481 }
    \n+
    482
    \n+
    483 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
    \n+
    484 {
    \n+
    485 return 1;
    \n+
    486 }
    \n+
    487
    \n+
    488 static size_type rowdim(const Matrix& /*A*/)
    \n+
    489 {
    \n+
    490 return n;
    \n+
    491 }
    \n+
    492
    \n+
    493 static size_type coldim(const Matrix& /*A*/)
    \n+
    494 {
    \n+
    495 return n;
    \n+
    496 }
    \n+
    497 };
    \n+
    498
    \n+
    502 template<typename T>
    \n+
    503 struct IsMatrix
    \n+
    504 {
    \n+
    505 enum {
    \n+
    509 value = false
    \n+
    510 };
    \n+
    511 };
    \n+
    512
    \n+
    513 template<typename T>
    \n+
    514 struct IsMatrix<DenseMatrix<T> >
    \n+
    515 {
    \n+
    516 enum {
    \n+
    520 value = true
    \n+
    521 };
    \n+
    522 };
    \n+
    523
    \n+
    524
    \n+
    525 template<typename T, typename A>
    \n+
    526 struct IsMatrix<BCRSMatrix<T,A> >
    \n+
    527 {
    \n+
    528 enum {
    \n+
    532 value = true
    \n+
    533 };
    \n+
    534 };
    \n+
    535
    \n+
    536 template<typename T>
    \n+\n+
    538 {
    \n+
    539 bool operator()(const T* l, const T* r)
    \n+
    540 {
    \n+
    541 return *l < *r;
    \n+
    542 }
    \n+
    543 };
    \n+
    544
    \n+
    545}
    \n+
    546#endif
    \n+
    This file implements a quadratic matrix of fixed size which is a multiple of the identity.
    \n+\n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
    Get the number of nonzero fields in the matrix.
    Definition: matrixutils.hh:119
    \n
    Definition: allocator.hh:11
    \n+
    void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)
    Definition: matrixutils.hh:154
    \n+
    Definition: matrixutils.hh:211
    \n+
    static auto coldim(const M &A)
    Definition: matrixutils.hh:219
    \n+
    static auto rowdim(const M &A)
    Definition: matrixutils.hh:214
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    row_type::ConstIterator ConstColIterator
    Const iterator to the entries of a row.
    Definition: bcrsmatrix.hh:741
    \n+
    B block_type
    export the type representing the components
    Definition: bcrsmatrix.hh:491
    \n+
    Iterator access to matrix rows
    Definition: bcrsmatrix.hh:579
    \n+
    A Matrix class to support different block types.
    Definition: multitypeblockmatrix.hh:46
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n+
    RowIterator end()
    Get iterator to one beyond last row.
    Definition: matrix.hh:620
    \n+
    RowIterator begin()
    Get iterator to first row.
    Definition: matrix.hh:614
    \n+
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n+
    Definition: matrixutils.hh:27
    \n+
    Check whether the a matrix has diagonal values on blocklevel recursion levels.
    Definition: matrixutils.hh:48
    \n+
    static void check(const Matrix &mat)
    Check whether the a matrix has diagonal values on blocklevel recursion levels.
    Definition: matrixutils.hh:53
    \n+
    static void check(const Matrix &mat)
    Definition: matrixutils.hh:75
    \n+
    static void check(const Matrix &)
    Check whether the a matrix has diagonal values on blocklevel recursion levels.
    Definition: matrixutils.hh:99
    \n+
    MultiTypeBlockMatrix< T1, Args... > Matrix
    Definition: matrixutils.hh:93
    \n+
    static size_type rowdim(const Matrix< B, TA > &A, size_type i)
    Definition: matrixutils.hh:232
    \n+
    static size_type coldim(const Matrix< B, TA > &A)
    Definition: matrixutils.hh:250
    \n+
    static size_type rowdim(const Matrix< B, TA > &A)
    Definition: matrixutils.hh:242
    \n+
    typename Matrix< B, TA >::size_type size_type
    Definition: matrixutils.hh:230
    \n+
    static size_type coldim(const Matrix< B, TA > &A, size_type c)
    Definition: matrixutils.hh:237
    \n+
    typename Matrix< B, TA >::block_type block_type
    Definition: matrixutils.hh:229
    \n+
    BCRSMatrix< B, TA > Matrix
    Definition: matrixutils.hh:263
    \n+
    static size_type coldim(const Matrix &A)
    Definition: matrixutils.hh:311
    \n+
    Matrix::block_type block_type
    Definition: matrixutils.hh:264
    \n+
    static size_type coldim(const Matrix &A, size_type c)
    Definition: matrixutils.hh:276
    \n+
    Matrix::size_type size_type
    Definition: matrixutils.hh:265
    \n+
    static size_type rowdim(const Matrix &A, size_type i)
    Definition: matrixutils.hh:267
    \n+
    static size_type rowdim(const Matrix &A)
    Definition: matrixutils.hh:304
    \n+
    static size_type coldim(const Matrix &A)
    Definition: matrixutils.hh:359
    \n+
    static size_type rowdim(const Matrix &, size_type)
    Definition: matrixutils.hh:345
    \n+
    static size_type rowdim(const Matrix &A)
    Definition: matrixutils.hh:355
    \n+
    Matrix::size_type size_type
    Definition: matrixutils.hh:343
    \n+
    BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix
    Definition: matrixutils.hh:342
    \n+
    static size_type coldim(const Matrix &, size_type)
    Definition: matrixutils.hh:350
    \n+
    static size_type rowdim(const Matrix &, size_type)
    Definition: matrixutils.hh:370
    \n+
    static size_type coldim(const Matrix &)
    Definition: matrixutils.hh:385
    \n+
    Matrix::size_type size_type
    Definition: matrixutils.hh:368
    \n+
    FieldMatrix< K, n, m > Matrix
    Definition: matrixutils.hh:367
    \n+
    static size_type coldim(const Matrix &, size_type)
    Definition: matrixutils.hh:375
    \n+
    static size_type rowdim(const Matrix &)
    Definition: matrixutils.hh:380
    \n+
    static size_type coldim(const MatrixType &A)
    Definition: matrixutils.hh:412
    \n+
    static size_type rowdim(const MatrixType &A)
    Definition: matrixutils.hh:407
    \n+
    static size_type rowdim(const MatrixType &, size_type)
    Definition: matrixutils.hh:397
    \n+
    MatrixType::size_type size_type
    Definition: matrixutils.hh:395
    \n+
    static size_type coldim(const MatrixType &, size_type)
    Definition: matrixutils.hh:402
    \n+
    Dune::DynamicMatrix< T > MatrixType
    Definition: matrixutils.hh:394
    \n+
    static size_type coldim(const ThisMatrix &A)
    Definition: matrixutils.hh:439
    \n+
    static size_type rowdim(const ThisMatrix &A)
    Definition: matrixutils.hh:434
    \n+
    Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix
    Definition: matrixutils.hh:421
    \n+
    static size_type coldim(const ThisMatrix &, size_type)
    Definition: matrixutils.hh:429
    \n+
    static size_type rowdim(const ThisMatrix &, size_type)
    Definition: matrixutils.hh:424
    \n+
    ThisMatrix::size_type size_type
    Definition: matrixutils.hh:422
    \n+
    static size_type coldim(const Matrix &, size_type)
    Definition: matrixutils.hh:456
    \n+
    Matrix::size_type size_type
    Definition: matrixutils.hh:449
    \n+
    static size_type coldim(const Matrix &)
    Definition: matrixutils.hh:466
    \n+
    static size_type rowdim(const Matrix &)
    Definition: matrixutils.hh:461
    \n+
    DiagonalMatrix< K, n > Matrix
    Definition: matrixutils.hh:448
    \n+
    static size_type rowdim(const Matrix &, size_type)
    Definition: matrixutils.hh:451
    \n+
    static size_type coldim(const Matrix &)
    Definition: matrixutils.hh:493
    \n+
    static size_type rowdim(const Matrix &, size_type)
    Definition: matrixutils.hh:478
    \n+
    static size_type coldim(const Matrix &, size_type)
    Definition: matrixutils.hh:483
    \n+
    Matrix::size_type size_type
    Definition: matrixutils.hh:476
    \n+
    ScaledIdentityMatrix< K, n > Matrix
    Definition: matrixutils.hh:475
    \n+
    static size_type rowdim(const Matrix &)
    Definition: matrixutils.hh:488
    \n+
    Test whether a type is an ISTL Matrix.
    Definition: matrixutils.hh:504
    \n+
    @ value
    True if T is an ISTL matrix.
    Definition: matrixutils.hh:509
    \n+
    Definition: matrixutils.hh:538
    \n+
    bool operator()(const T *l, const T *r)
    Definition: matrixutils.hh:539
    \n+
    A multiple of the identity matrix of static size.
    Definition: scaledidmatrix.hh:30
    \n+
    std::size_t size_type
    The type used for the index access and size operations.
    Definition: scaledidmatrix.hh:43
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,68 +4,784 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * common\n-counter.hh\n+matrixutils.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3#ifndef DUNE_ISTL_COMMON_COUNTER_HH\n- 4#define DUNE_ISTL_COMMON_COUNTER_HH\n- 5\n- 6#include \n- 7#include \n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12\n- 13#include \n- 14\n-15constexpr std::size_t maxcount = 100;\n- 16\n-17#define DUNE_GET_COUNTER(Tag) \\\n- 18 (counterFunc(Dune::PriorityTag{}, Tag{}, Dune::CounterImpl::\n-ADLTag{}))\n- 19\n-20#define DUNE_INC_COUNTER(Tag) \\\n- 21 namespace { \\\n- 22 namespace CounterImpl { \\\n- 23 constexpr std::size_t \\\n- 24 counterFunc(Dune::PriorityTag p, Tag, ADLTag) \\\n- 25 { \\\n- 26 return p.value; \\\n- 27 } \\\n- 28 } \\\n- 29 } \\\n- 30 static_assert(true, \"unfudge indentation\")\n- 31\n- 32namespace Dune {\n- 33 namespace {\n- 34\n-35 namespace CounterImpl {\n- 36\n- 37 struct ADLTag {};\n- 38\n- 39 template\n- 40 constexpr std::size_t counterFunc(Dune::PriorityTag<0>, Tag, ADLTag)\n- 41 {\n- 42 return 0;\n- 43 }\n- 44\n- 45 } // end namespace CounterImpl\n- 46 } // end empty namespace\n- 47} // end namespace Dune\n- 48#endif // DUNE_ISTL_COMMON_COUNTER_HH\n-maxcount\n-constexpr std::size_t maxcount\n-Definition: counter.hh:15\n+ 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n+ 4// vi: set et ts=4 sw=2 sts=2:\n+ 5#ifndef DUNE_ISTL_MATRIXUTILS_HH\n+ 6#define DUNE_ISTL_MATRIXUTILS_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \"istlexception.hh\"\n+ 18\n+ 19namespace Dune\n+ 20{\n+ 21\n+ 22#ifndef DOYXGEN\n+ 23 template\n+ 24 class BCRSMatrix;\n+ 25\n+ 26 template\n+27 class FieldMatrix;\n+ 28\n+ 29 template\n+ 30 class Matrix;\n+ 31#endif\n+ 32\n+ 46 template\n+47 struct CheckIfDiagonalPresent\n+ 48 {\n+53 static void check([[maybe_unused]] const Matrix& mat)\n+ 54 {\n+ 55#ifdef DUNE_ISTL_WITH_CHECKING\n+ 56 typedef typename Matrix::ConstRowIterator Row;\n+ 57 typedef typename Matrix::ConstColIterator Entry;\n+ 58 for(Row row = mat.begin(); row!=mat.end(); ++row) {\n+ 59 Entry diagonal = row->find(row.index());\n+ 60 if(diagonal==row->end())\n+ 61 DUNE_THROW(ISTLError, \"Missing diagonal value in row \"<::check(m);\n+ 66 }\n+ 67 }\n+ 68#endif\n+ 69 }\n+ 70 };\n+ 71\n+ 72 template\n+73 struct CheckIfDiagonalPresent\n+ 74 {\n+75 static void check(const Matrix& mat)\n+ 76 {\n+ 77 typedef typename Matrix::ConstRowIterator Row;\n+ 78 for(Row row = mat.begin(); row!=mat.end(); ++row) {\n+ 79 if(row->find(row.index())==row->end())\n+ 80 DUNE_THROW(ISTLError, \"Missing diagonal value in row \"<\n+ 87 class MultiTypeBlockMatrix;\n+ 88\n+ 89 template\n+90 struct CheckIfDiagonalPresent,\n+ 91 blocklevel,l>\n+ 92 {\n+93 typedef MultiTypeBlockMatrix Matrix;\n+ 94\n+99 static void check(const Matrix& /* mat */)\n+ 100 {\n+ 101#ifdef DUNE_ISTL_WITH_CHECKING\n+ 102 // TODO Implement check\n+ 103#endif\n+ 104 }\n+ 105 };\n+ 106\n+ 118 template\n+119 inline auto countNonZeros(const M&,\n+ 120 [[maybe_unused]] typename std::enable_if_t::value>*\n+sfinae = nullptr)\n+ 121 {\n+ 122 return 1;\n+ 123 }\n+ 124\n+ 125 template\n+126 inline auto countNonZeros(const M& matrix,\n+ 127 [[maybe_unused]] typename std::enable_if_t::value>*\n+sfinae = nullptr)\n+ 128 {\n+ 129 typename M::size_type nonZeros = 0;\n+ 130 for(auto&& row : matrix)\n+ 131 for(auto&& entry : row)\n+ 132 nonZeros += countNonZeros(entry);\n+ 133 return nonZeros;\n+ 134 }\n+ 135\n+ 136 /*\n+ 137 template\n+ 138 struct ProcessOnFieldsOfMatrix\n+ 139 */\n+ 140\n+ 142 namespace\n+ 143 {\n+ 144 struct CompPair {\n+ 145 template\n+ 146 bool operator()(const std::pair& p1, const std::pair& p2) const\n+ 147 {\n+ 148 return p1.first\n+154 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)\n+ 155 {\n+ 156 typedef typename C::ParallelIndexSet::const_iterator IIter;\n+ 157 typedef typename C::OwnerSet OwnerSet;\n+ 158 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;\n+ 159\n+ 160 GlobalIndex gmax=0;\n+ 161\n+ 162 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();\n+ 163 idx!=eidx; ++idx)\n+ 164 gmax=std::max(gmax,idx->global());\n+ 165\n+ 166 gmax=ooc.communicator().max(gmax);\n+ 167 ooc.buildGlobalLookup();\n+ 168\n+ 169 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();\n+ 170 idx!=eidx; ++idx) {\n+ 171 if(OwnerSet::contains(idx->local().attribute()))\n+ 172 {\n+ 173 typedef typename M::block_type Block;\n+ 174\n+ 175 std::set,CompPair> entries;\n+ 176\n+ 177 // sort rows\n+ 178 typedef typename M::ConstColIterator CIter;\n+ 179 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();\n+ 180 c!=cend; ++c) {\n+ 181 const typename C::ParallelIndexSet::IndexPair* pair\n+ 182 =ooc.globalLookup().pair(c.index());\n+ 183 assert(pair);\n+ 184 entries.insert(std::make_pair(pair->global(), *c));\n+ 185 }\n+ 186\n+ 187 //wait until its the rows turn.\n+ 188 GlobalIndex rowidx = idx->global();\n+ 189 GlobalIndex cur=std::numeric_limits::max();\n+ 190 while(cur!=rowidx)\n+ 191 cur=ooc.communicator().min(rowidx);\n+ 192\n+ 193 // print rows\n+ 194 typedef typename std::set,CompPair>::iterator\n+SIter;\n+ 195 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)\n+ 196 os<global()<<\" \"<first<<\" \"<second<::max();\n+ 205 while(cur!=ooc.communicator().min(cur)) ;\n+ 206 }\n+ 207\n+ 208 // Default implementation for scalar types\n+ 209 template\n+210 struct MatrixDimension\n+ 211 {\n+ 212 static_assert(IsNumber::value, \"MatrixDimension is not implemented for\n+this type!\");\n+ 213\n+214 static auto rowdim(const M& A)\n+ 215 {\n+ 216 return 1;\n+ 217 }\n+ 218\n+219 static auto coldim(const M& A)\n+ 220 {\n+ 221 return 1;\n+ 222 }\n+ 223 };\n+ 224\n+ 225 // Default implementation for scalar types\n+ 226 template\n+227 struct MatrixDimension >\n+ 228 {\n+229 using block_type = typename Matrix::block_type;\n+230 using size_type = typename Matrix::size_type;\n+ 231\n+232 static size_type rowdim (const Matrix& A, size_type i)\n+ 233 {\n+ 234 return MatrixDimension::rowdim(A[i][0]);\n+ 235 }\n+ 236\n+237 static size_type coldim (const Matrix& A, size_type c)\n+ 238 {\n+ 239 return MatrixDimension::coldim(A[0][c]);\n+ 240 }\n+ 241\n+242 static size_type rowdim (const Matrix& A)\n+ 243 {\n+ 244 size_type nn=0;\n+ 245 for (size_type i=0; i& A)\n+ 251 {\n+ 252 size_type nn=0;\n+ 253 for (size_type i=0; i\n+261 struct MatrixDimension >\n+ 262 {\n+263 typedef BCRSMatrix Matrix;\n+264 typedef typename Matrix::block_type block_type;\n+265 typedef typename Matrix::size_type size_type;\n+ 266\n+267 static size_type rowdim (const Matrix& A, size_type i)\n+ 268 {\n+ 269 const B* row = A.r[i].getptr();\n+ 270 if(row)\n+ 271 return MatrixDimension::rowdim(*row);\n+ 272 else\n+ 273 return 0;\n+ 274 }\n+ 275\n+276 static size_type coldim (const Matrix& A, size_type c)\n+ 277 {\n+ 278 // find an entry in column c\n+ 279 if (A.nnz_ > 0)\n+ 280 {\n+ 281 for (size_type k=0; k::coldim(A.a[k]);\n+ 284 }\n+ 285 }\n+ 286 }\n+ 287 else\n+ 288 {\n+ 289 for (size_type i=0; i::coldim(a[k]);\n+ 296 }\n+ 297 }\n+ 298 }\n+ 299\n+ 300 // not found\n+ 301 return 0;\n+ 302 }\n+ 303\n+304 static size_type rowdim (const Matrix& A){\n+ 305 size_type nn=0;\n+ 306 for (size_type i=0; i coldims(A.M(),\n+ 319 std::numeric_limits::max());\n+ 320\n+ 321 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)\n+ 322 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)\n+ 323 // only compute blocksizes we don't already have\n+ 324 if (coldims[col.index()]==std::numeric_limits::max())\n+ 325 coldims[col.index()] = MatrixDimension::coldim(*col);\n+ 326\n+ 327 size_type sum = 0;\n+ 328 for (typename std::vector::iterator it=coldims.begin();\n+ 329 it!=coldims.end(); ++it)\n+ 330 // skip rows for which no coldim could be determined\n+ 331 if ((*it)>=0)\n+ 332 sum += *it;\n+ 333\n+ 334 return sum;\n+ 335 }\n+ 336 };\n+ 337\n+ 338\n+ 339 template\n+340 struct MatrixDimension ,TA> >\n+ 341 {\n+342 typedef BCRSMatrix ,TA> Matrix;\n+343 typedef typename Matrix::size_type size_type;\n+ 344\n+345 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)\n+ 346 {\n+ 347 return n;\n+ 348 }\n+ 349\n+350 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)\n+ 351 {\n+ 352 return m;\n+ 353 }\n+ 354\n+355 static size_type rowdim (const Matrix& A) {\n+ 356 return A.N()*n;\n+ 357 }\n+ 358\n+359 static size_type coldim (const Matrix& A) {\n+ 360 return A.M()*m;\n+ 361 }\n+ 362 };\n+ 363\n+ 364 template\n+365 struct MatrixDimension >\n+ 366 {\n+367 typedef FieldMatrix Matrix;\n+368 typedef typename Matrix::size_type size_type;\n+ 369\n+370 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n+ 371 {\n+ 372 return 1;\n+ 373 }\n+ 374\n+375 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n+ 376 {\n+ 377 return 1;\n+ 378 }\n+ 379\n+380 static size_type rowdim(const Matrix& /*A*/)\n+ 381 {\n+ 382 return n;\n+ 383 }\n+ 384\n+385 static size_type coldim(const Matrix& /*A*/)\n+ 386 {\n+ 387 return m;\n+ 388 }\n+ 389 };\n+ 390\n+ 391 template \n+392 struct MatrixDimension >\n+ 393 {\n+394 typedef Dune::DynamicMatrix MatrixType;\n+395 typedef typename MatrixType::size_type size_type;\n+ 396\n+397 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)\n+ 398 {\n+ 399 return 1;\n+ 400 }\n+ 401\n+402 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)\n+ 403 {\n+ 404 return 1;\n+ 405 }\n+ 406\n+407 static size_type rowdim(const MatrixType& A)\n+ 408 {\n+ 409 return A.N();\n+ 410 }\n+ 411\n+412 static size_type coldim(const MatrixType& A)\n+ 413 {\n+ 414 return A.M();\n+ 415 }\n+ 416 };\n+ 417\n+ 418 template\n+419 struct MatrixDimension, TA> >\n+ 420 {\n+421 typedef Matrix, TA> ThisMatrix;\n+422 typedef typename ThisMatrix::size_type size_type;\n+ 423\n+424 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)\n+ 425 {\n+ 426 return n;\n+ 427 }\n+ 428\n+429 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)\n+ 430 {\n+ 431 return m;\n+ 432 }\n+ 433\n+434 static size_type rowdim(const ThisMatrix& A)\n+ 435 {\n+ 436 return A.N()*n;\n+ 437 }\n+ 438\n+439 static size_type coldim(const ThisMatrix& A)\n+ 440 {\n+ 441 return A.M()*m;\n+ 442 }\n+ 443 };\n+ 444\n+ 445 template\n+446 struct MatrixDimension >\n+ 447 {\n+448 typedef DiagonalMatrix Matrix;\n+449 typedef typename Matrix::size_type size_type;\n+ 450\n+451 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n+ 452 {\n+ 453 return 1;\n+ 454 }\n+ 455\n+456 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n+ 457 {\n+ 458 return 1;\n+ 459 }\n+ 460\n+461 static size_type rowdim(const Matrix& /*A*/)\n+ 462 {\n+ 463 return n;\n+ 464 }\n+ 465\n+466 static size_type coldim(const Matrix& /*A*/)\n+ 467 {\n+ 468 return n;\n+ 469 }\n+ 470 };\n+ 471\n+ 472 template\n+473 struct MatrixDimension >\n+ 474 {\n+475 typedef ScaledIdentityMatrix Matrix;\n+476 typedef typename Matrix::size_type size_type;\n+ 477\n+478 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)\n+ 479 {\n+ 480 return 1;\n+ 481 }\n+ 482\n+483 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)\n+ 484 {\n+ 485 return 1;\n+ 486 }\n+ 487\n+488 static size_type rowdim(const Matrix& /*A*/)\n+ 489 {\n+ 490 return n;\n+ 491 }\n+ 492\n+493 static size_type coldim(const Matrix& /*A*/)\n+ 494 {\n+ 495 return n;\n+ 496 }\n+ 497 };\n+ 498\n+ 502 template\n+503 struct IsMatrix\n+ 504 {\n+ 505 enum {\n+ 509 value = false\n+510 };\n+ 511 };\n+ 512\n+ 513 template\n+514 struct IsMatrix >\n+ 515 {\n+ 516 enum {\n+ 520 value = true\n+521 };\n+ 522 };\n+ 523\n+ 524\n+ 525 template\n+526 struct IsMatrix >\n+ 527 {\n+ 528 enum {\n+ 532 value = true\n+533 };\n+ 534 };\n+ 535\n+ 536 template\n+537 struct PointerCompare\n+ 538 {\n+539 bool operator()(const T* l, const T* r)\n+ 540 {\n+ 541 return *l < *r;\n+ 542 }\n+ 543 };\n+ 544\n+ 545}\n+ 546#endif\n+scaledidmatrix.hh\n+This file implements a quadratic matrix of fixed size which is a multiple of\n+the identity.\n+istlexception.hh\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::countNonZeros\n+auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n+value > *sfinae=nullptr)\n+Get the number of nonzero fields in the matrix.\n+Definition: matrixutils.hh:119\n Dune\n Definition: allocator.hh:11\n+Dune::printGlobalSparseMatrix\n+void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)\n+Definition: matrixutils.hh:154\n+Dune::MatrixDimension\n+Definition: matrixutils.hh:211\n+Dune::MatrixDimension::coldim\n+static auto coldim(const M &A)\n+Definition: matrixutils.hh:219\n+Dune::MatrixDimension::rowdim\n+static auto rowdim(const M &A)\n+Definition: matrixutils.hh:214\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::ConstColIterator\n+row_type::ConstIterator ConstColIterator\n+Const iterator to the entries of a row.\n+Definition: bcrsmatrix.hh:741\n+Dune::BCRSMatrix::block_type\n+B block_type\n+export the type representing the components\n+Definition: bcrsmatrix.hh:491\n+Dune::BCRSMatrix::RealRowIterator\n+Iterator access to matrix rows\n+Definition: bcrsmatrix.hh:579\n+Dune::MultiTypeBlockMatrix\n+A Matrix class to support different block types.\n+Definition: multitypeblockmatrix.hh:46\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator\n+ConstIterator class for sequential access.\n+Definition: matrix.hh:404\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::size_type\n+A::size_type size_type\n+Type for indices and sizes.\n+Definition: matrix.hh:577\n+Dune::Matrix::end\n+RowIterator end()\n+Get iterator to one beyond last row.\n+Definition: matrix.hh:620\n+Dune::Matrix::begin\n+RowIterator begin()\n+Get iterator to first row.\n+Definition: matrix.hh:614\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::block_type\n+T block_type\n+Export the type representing the components.\n+Definition: matrix.hh:568\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n+Dune::CheckIfDiagonalPresent\n+Check whether the a matrix has diagonal values on blocklevel recursion levels.\n+Definition: matrixutils.hh:48\n+Dune::CheckIfDiagonalPresent::check\n+static void check(const Matrix &mat)\n+Check whether the a matrix has diagonal values on blocklevel recursion levels.\n+Definition: matrixutils.hh:53\n+Dune::CheckIfDiagonalPresent<_Matrix,_0,_l_>::check\n+static void check(const Matrix &mat)\n+Definition: matrixutils.hh:75\n+Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,_blocklevel,\n+l_>::check\n+static void check(const Matrix &)\n+Check whether the a matrix has diagonal values on blocklevel recursion levels.\n+Definition: matrixutils.hh:99\n+Dune::CheckIfDiagonalPresent<_MultiTypeBlockMatrix<_T1,_Args..._>,_blocklevel,\n+l_>::Matrix\n+MultiTypeBlockMatrix< T1, Args... > Matrix\n+Definition: matrixutils.hh:93\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix< B, TA > &A, size_type i)\n+Definition: matrixutils.hh:232\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::coldim\n+static size_type coldim(const Matrix< B, TA > &A)\n+Definition: matrixutils.hh:250\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix< B, TA > &A)\n+Definition: matrixutils.hh:242\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::size_type\n+typename Matrix< B, TA >::size_type size_type\n+Definition: matrixutils.hh:230\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::coldim\n+static size_type coldim(const Matrix< B, TA > &A, size_type c)\n+Definition: matrixutils.hh:237\n+Dune::MatrixDimension<_Matrix<_B,_TA_>_>::block_type\n+typename Matrix< B, TA >::block_type block_type\n+Definition: matrixutils.hh:229\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::Matrix\n+BCRSMatrix< B, TA > Matrix\n+Definition: matrixutils.hh:263\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::coldim\n+static size_type coldim(const Matrix &A)\n+Definition: matrixutils.hh:311\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::block_type\n+Matrix::block_type block_type\n+Definition: matrixutils.hh:264\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::coldim\n+static size_type coldim(const Matrix &A, size_type c)\n+Definition: matrixutils.hh:276\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixutils.hh:265\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix &A, size_type i)\n+Definition: matrixutils.hh:267\n+Dune::MatrixDimension<_BCRSMatrix<_B,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix &A)\n+Definition: matrixutils.hh:304\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::coldim\n+static size_type coldim(const Matrix &A)\n+Definition: matrixutils.hh:359\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix &, size_type)\n+Definition: matrixutils.hh:345\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::rowdim\n+static size_type rowdim(const Matrix &A)\n+Definition: matrixutils.hh:355\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixutils.hh:343\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::Matrix\n+BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix\n+Definition: matrixutils.hh:342\n+Dune::MatrixDimension<_BCRSMatrix<_FieldMatrix<_B,_n,_m_>,_TA_>_>::coldim\n+static size_type coldim(const Matrix &, size_type)\n+Definition: matrixutils.hh:350\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::rowdim\n+static size_type rowdim(const Matrix &, size_type)\n+Definition: matrixutils.hh:370\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::coldim\n+static size_type coldim(const Matrix &)\n+Definition: matrixutils.hh:385\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixutils.hh:368\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::Matrix\n+FieldMatrix< K, n, m > Matrix\n+Definition: matrixutils.hh:367\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::coldim\n+static size_type coldim(const Matrix &, size_type)\n+Definition: matrixutils.hh:375\n+Dune::MatrixDimension<_FieldMatrix<_K,_n,_m_>_>::rowdim\n+static size_type rowdim(const Matrix &)\n+Definition: matrixutils.hh:380\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::coldim\n+static size_type coldim(const MatrixType &A)\n+Definition: matrixutils.hh:412\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::rowdim\n+static size_type rowdim(const MatrixType &A)\n+Definition: matrixutils.hh:407\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::rowdim\n+static size_type rowdim(const MatrixType &, size_type)\n+Definition: matrixutils.hh:397\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::size_type\n+MatrixType::size_type size_type\n+Definition: matrixutils.hh:395\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::coldim\n+static size_type coldim(const MatrixType &, size_type)\n+Definition: matrixutils.hh:402\n+Dune::MatrixDimension<_Dune::DynamicMatrix<_T_>_>::MatrixType\n+Dune::DynamicMatrix< T > MatrixType\n+Definition: matrixutils.hh:394\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::coldim\n+static size_type coldim(const ThisMatrix &A)\n+Definition: matrixutils.hh:439\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::rowdim\n+static size_type rowdim(const ThisMatrix &A)\n+Definition: matrixutils.hh:434\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::ThisMatrix\n+Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix\n+Definition: matrixutils.hh:421\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::coldim\n+static size_type coldim(const ThisMatrix &, size_type)\n+Definition: matrixutils.hh:429\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::rowdim\n+static size_type rowdim(const ThisMatrix &, size_type)\n+Definition: matrixutils.hh:424\n+Dune::MatrixDimension<_Matrix<_FieldMatrix<_K,_n,_m_>,_TA_>_>::size_type\n+ThisMatrix::size_type size_type\n+Definition: matrixutils.hh:422\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::coldim\n+static size_type coldim(const Matrix &, size_type)\n+Definition: matrixutils.hh:456\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixutils.hh:449\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::coldim\n+static size_type coldim(const Matrix &)\n+Definition: matrixutils.hh:466\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::rowdim\n+static size_type rowdim(const Matrix &)\n+Definition: matrixutils.hh:461\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::Matrix\n+DiagonalMatrix< K, n > Matrix\n+Definition: matrixutils.hh:448\n+Dune::MatrixDimension<_DiagonalMatrix<_K,_n_>_>::rowdim\n+static size_type rowdim(const Matrix &, size_type)\n+Definition: matrixutils.hh:451\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::coldim\n+static size_type coldim(const Matrix &)\n+Definition: matrixutils.hh:493\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::rowdim\n+static size_type rowdim(const Matrix &, size_type)\n+Definition: matrixutils.hh:478\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::coldim\n+static size_type coldim(const Matrix &, size_type)\n+Definition: matrixutils.hh:483\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixutils.hh:476\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::Matrix\n+ScaledIdentityMatrix< K, n > Matrix\n+Definition: matrixutils.hh:475\n+Dune::MatrixDimension<_ScaledIdentityMatrix<_K,_n_>_>::rowdim\n+static size_type rowdim(const Matrix &)\n+Definition: matrixutils.hh:488\n+Dune::IsMatrix\n+Test whether a type is an ISTL Matrix.\n+Definition: matrixutils.hh:504\n+Dune::IsMatrix::value\n+@ value\n+True if T is an ISTL matrix.\n+Definition: matrixutils.hh:509\n+Dune::PointerCompare\n+Definition: matrixutils.hh:538\n+Dune::PointerCompare::operator()\n+bool operator()(const T *l, const T *r)\n+Definition: matrixutils.hh:539\n+Dune::ScaledIdentityMatrix\n+A multiple of the identity matrix of static size.\n+Definition: scaledidmatrix.hh:30\n+Dune::ScaledIdentityMatrix::size_type\n+std::size_t size_type\n+The type used for the index access and size operations.\n+Definition: scaledidmatrix.hh:43\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00065.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00065.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: registry.hh File Reference\n+dune-istl: ldl.hh File Reference\n \n \n \n \n \n \n \n@@ -58,94 +58,71 @@\n \n
    \n \n \n
    \n
    \n \n-
    registry.hh File Reference
    \n+Functions
    \n+ \n
    \n
    \n-
    #include <cstddef>
    \n-#include <iostream>
    \n+\n+

    Class for using LDL with ISTL matrices. \n+More...

    \n+
    #include <iostream>
    \n #include <memory>
    \n-#include <string>
    \n-#include <utility>
    \n-#include "counter.hh"
    \n-#include <dune/common/typelist.hh>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include <dune/common/parameterizedobject.hh>
    \n+#include <type_traits>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/istl/bccsmatrixinitializer.hh>
    \n+#include <dune/istl/solvers.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/istl/solverfactory.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Classes

    class  Dune::LDL< Matrix >
     Use the LDL package to directly solve linear systems – empty default class. More...
     
    class  Dune::LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > >
     The LDL direct sparse solver for matrices of type BCRSMatrix. More...
     
    struct  Dune::IsDirectSolver< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::StoresColumnCompressed< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::LDLCreator
     
    struct  Dune::LDLCreator::isValidBlock< F >
     
    struct  Dune::LDLCreator::isValidBlock< FieldVector< double, k > >
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n+\n+\n+\n

    \n-Macros

    #define DUNE_REGISTRY_PUT(Tag, id, ...)
     

    \n+Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("ldl", Dune::LDLCreator())
     
    \n-

    Macro Definition Documentation

    \n-\n-

    ◆ DUNE_REGISTRY_PUT

    \n-\n-
    \n-
    \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n- \n-
    #define DUNE_REGISTRY_PUT( Tag,
     id,
     ... 
    )
    \n-
    \n-Value:
    namespace { \\
    \n-
    template<> \\
    \n-
    struct Registry<Tag, DUNE_GET_COUNTER(Tag)> \\
    \n-
    { \\
    \n-
    static auto getCreator() \\
    \n-
    { \\
    \n-
    return __VA_ARGS__; \\
    \n-
    } \\
    \n-
    static std::string name() { return id; } \\
    \n-
    }; \\
    \n-
    } \\
    \n-
    DUNE_INC_COUNTER(Tag)
    \n-
    #define DUNE_GET_COUNTER(Tag)
    Definition: counter.hh:17
    \n-
    \n-
    \n-
    \n-
    \n+

    Detailed Description

    \n+

    Class for using LDL with ISTL matrices.

    \n+
    Author
    Marco Agnese, Andrea Sacconi
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,51 +4,58 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * common\n-Namespaces | Macros\n-registry.hh File Reference\n-#include \n+Classes | Namespaces | Functions\n+ldl.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL)\n+Class for using LDL with ISTL matrices. More...\n #include \n #include \n-#include \n-#include \n-#include \"counter.hh\"\n-#include \n-#include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n+ Classes\n+ class\n+ \u00a0Dune::LDL<_Matrix_>\n+\u00a0 Use the LDL package to directly solve linear systems \u2013 empty default class.\n+ More...\n+\u00a0\n+ class\n+ \u00a0Dune::LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n+\u00a0 The LDL direct sparse solver for matrices of type BCRSMatrix. More...\n+\u00a0\n+struct\n+ \u00a0Dune::IsDirectSolver<_LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>_>\n+\u00a0\n+struct Dune::StoresColumnCompressed<_LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n+ \u00a0>\n+\u00a0\n+struct\n+ \u00a0Dune::LDLCreator\n+\u00a0\n+struct\n+ \u00a0Dune::LDLCreator::isValidBlock<_F_>\n+\u00a0\n+struct\n+ \u00a0Dune::LDLCreator::isValidBlock<_FieldVector<_double,_k_>_>\n+\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Macros\n-#define\u00a0DUNE_REGISTRY_PUT(Tag, id, ...)\n+ Functions\n+\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"ldl\", Dune::LDLCreator())\n \u00a0\n-***** Macro Definition Documentation *****\n-***** \u25c6\u00a0DUNE_REGISTRY_PUT *****\n-#define DUNE_REGISTRY_PUT ( \u00a0Tag,\n- \u00a0id,\n- \u00a0...\u00a0\n- )\n-Value:\n-namespace { \\\n-template<> \\\n-struct Registry \\\n-{ \\\n-static auto getCreator() \\\n-{ \\\n-return __VA_ARGS__; \\\n-} \\\n-static std::string name() { return id; } \\\n-}; \\\n-} \\\n-DUNE_INC_COUNTER(Tag)\n-DUNE_GET_COUNTER\n-#define DUNE_GET_COUNTER(Tag)\n-Definition: counter.hh:17\n+***** Detailed Description *****\n+Class for using LDL with ISTL matrices.\n+ Author\n+ Marco Agnese, Andrea Sacconi\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00065_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00065_source.html", "has_internal_linenos": true, "unified_diff": "@@ -21,1042 +21,4704 @@\n 00000140: 6f6e 7465 6e74 3d22 446f 7879 6765 6e20 ontent=\"Doxygen \n 00000150: 312e 392e 3422 2f3e 0a3c 6d65 7461 206e 1.9.4\"/>..<\n 000001a0: 7469 746c 653e 6475 6e65 2d69 7374 6c3a title>dune-istl:\n-000001b0: 2072 6567 6973 7472 792e 6868 2053 6f75 registry.hh Sou\n-000001c0: 7263 6520 4669 6c65 3c2f 7469 746c 653e rce File\n-000001d0: 0a3c 6c69 6e6b 2068 7265 663d 2274 6162 ...\n-00000280: 0a3c 6c69 6e6b 2068 7265 663d 2273 6561 .....
    ..\n-000007c0: 3c64 6976 2069 643d 224d 5365 6172 6368
    ....
    . <\n-00000af0: 6469 7620 636c 6173 733d 2268 6561 6465 div class=\"heade\n-00000b00: 7274 6974 6c65 223e 3c64 6976 2063 6c61 rtitle\">
    regis\n-00000b20: 7472 792e 6868 3c2f 6469 763e 3c2f 6469 try.hh
    .
    .
    .Go to the do\n-00000b80: 6375 6d65 6e74 6174 696f 6e20 6f66 2074 cumentation of t\n-00000b90: 6869 7320 6669 6c65 2e3c 2f61 3e3c 6469 his file.
    1\n-00000c00: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 // \n-00000c20: 5350 4458 2d46 696c 6543 6f70 7972 6967 SPDX-FileCopyrig\n-00000c30: 6874 5465 7874 3a20 436f 7079 7269 6768 htText: Copyrigh\n-00000c40: 7420 2843 2920 4455 4e45 2050 726f 6a65 t (C) DUNE Proje\n-00000c50: 6374 2063 6f6e 7472 6962 7574 6f72 732c ct contributors,\n-00000c60: 2073 6565 2066 696c 6520 4c49 4345 4e53 see file LICENS\n-00000c70: 452e 6d64 2069 6e20 6d6f 6475 6c65 2072 E.md in module r\n-00000c80: 6f6f 743c 2f73 7061 6e3e 3c2f 6469 763e oot
    \n-00000c90: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00000cc0: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 2// SP\n-00000d00: 4458 2d4c 6963 656e 7365 2d49 6465 6e74 DX-License-Ident\n-00000d10: 6966 6965 723a 204c 6963 656e 7365 5265 ifier: LicenseRe\n-00000d20: 662d 4750 4c2d 322e 302d 6f6e 6c79 2d77 f-GPL-2.0-only-w\n-00000d30: 6974 682d 4455 4e45 2d65 7863 6570 7469 ith-DUNE-excepti\n-00000d40: 6f6e 3c2f 7370 616e 3e3c 2f64 6976 3e0a on
    .\n-00000d50: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65 \n-00000df0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00000e20: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 4\n-00000e60: 2364 6566 696e 6520 4455 4e45 5f49 5354 #define DUNE_IST\n-00000e70: 4c5f 434f 4d4d 4f4e 5f52 4547 4953 5452 L_COMMON_REGISTR\n-00000e80: 595f 4848 3c2f 7370 616e 3e3c 2f64 6976 Y_HH.
    5<\n-00000ee0: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
    .\n-00000f00: 3c61 2069 643d 226c 3030 3030 3622 206e 6#in\n-00000f60: 636c 7564 6520 266c 743b 6373 7464 6465 clude <cstdde\n-00000f70: 6626 6774 3b3c 2f73 7061 6e3e 3c2f 6469 f>.
    7\n-00000fd0: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 #include <i\n-00001000: 6f73 7472 6561 6d26 6774 3b3c 2f73 7061 ostream>
    .
    8#include\n-00001090: 2026 6c74 3b6d 656d 6f72 7926 6774 3b3c <memory><\n-000010a0: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
    .<\n-000010c0: 6120 6964 3d22 6c30 3030 3039 2220 6e61 a id=\"l00009\" na\n-000010d0: 6d65 3d22 6c30 3030 3039 223e 3c2f 613e me=\"l00009\">\n-000010e0: 3c73 7061 6e20 636c 6173 733d 226c 696e 9#inc\n-00001120: 6c75 6465 2026 6c74 3b73 7472 696e 6726 lude <string&\n-00001130: 6774 3b3c 2f73 7061 6e3e 3c2f 6469 763e gt;
    \n-00001140: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00001170: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 10\n-000011b0: 2369 6e63 6c75 6465 2026 6c74 3b75 7469 #include <uti\n-000011c0: 6c69 7479 2667 743b 3c2f 7370 616e 3e3c lity><\n-000011d0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00001220: 2031 313c 2f73 7061 6e3e 203c 2f64 6976 11 .
    12<\n-00001280: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#include "\n-000012b0: 3c61 2063 6c61 7373 3d22 636f 6465 2220 counter.hh".
    \n-00001340: 3133 3c2f 7370 616e 3e20 3c2f 6469 763e 13
    \n-00001350: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00001380: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 14\n-000013c0: 2369 6e63 6c75 6465 2026 6c74 3b64 756e #include <dun\n-000013d0: 652f 636f 6d6d 6f6e 2f74 7970 656c 6973 e/common/typelis\n-000013e0: 742e 6868 2667 743b 3c2f 7370 616e 3e3c t.hh><\n-000013f0: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00001440: 2031 353c 2f73 7061 6e3e 3c73 7061 6e20 15#include &l\n-00001470: 743b 6475 6e65 2f63 6f6d 6d6f 6e2f 6879 t;dune/common/hy\n-00001480: 6272 6964 7574 696c 6974 6965 732e 6868 bridutilities.hh\n-00001490: 2667 743b 3c2f 7370 616e 3e3c 2f64 6976 >.
    16<\n-000014f0: 2f73 7061 6e3e 3c73 7061 6e20 636c 6173 /span>#include <du\n-00001520: 6e65 2f63 6f6d 6d6f 6e2f 7061 7261 6d65 ne/common/parame\n-00001530: 7465 7269 7a65 646f 626a 6563 742e 6868 terizedobject.hh\n-00001540: 2667 743b 3c2f 7370 616e 3e3c 2f64 6976 >.
    17<\n-000015a0: 2f73 7061 6e3e 203c 2f64 6976 3e0a 3c64 /span>
    .\n-000015c0: 3c61 2069 643d 226c 3030 3031 3822 206e 18\n-00001640: 3c2f 613e 3c2f 7370 616e 3e3c 7370 616e
    #define DU\n-00001670: 4e45 5f52 4547 4953 5452 595f 5055 5428 NE_REGISTRY_PUT(\n-00001680: 5461 672c 2069 642c 202e 2e2e 2920 2020 Tag, id, ...) \n-00001690: 2020 2020 2020 2020 2020 2020 5c3c 2f73 \\
    .
    19<\n-00001700: 7370 616e 2063 6c61 7373 3d22 7072 6570 span class=\"prep\n-00001710: 726f 6365 7373 6f72 223e 2020 6e61 6d65 rocessor\"> name\n-00001720: 7370 6163 6520 7b20 2020 2020 2020 2020 space { \n-00001730: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001740: 2020 2020 2020 2020 2020 5c3c 2f73 7061 \\
    .
    20 temp\n-000017d0: 6c61 7465 266c 743b 2667 743b 2020 2020 late<> \n-000017e0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-000017f0: 2020 2020 2020 2020 2020 2020 2020 5c3c \\<\n-00001800: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
    .<\n-00001820: 6120 6964 3d22 6c30 3030 3231 2220 6e61 a id=\"l00021\" na\n-00001830: 6d65 3d22 6c30 3030 3231 223e 3c2f 613e me=\"l00021\">\n-00001840: 3c73 7061 6e20 636c 6173 733d 226c 696e 21 \n-00001880: 7374 7275 6374 2052 6567 6973 7472 7926 struct Registry&\n-00001890: 6c74 3b54 6167 2c20 4455 4e45 5f47 4554 lt;Tag, DUNE_GET\n-000018a0: 5f43 4f55 4e54 4552 2854 6167 2926 6774 _COUNTER(Tag)>\n-000018b0: 3b20 2020 2020 2020 5c3c 2f73 7061 6e3e ; \\\n-000018c0: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00001910: 2020 3232 3c2f 7370 616e 3e3c 7370 616e 22 { \n-00001940: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001950: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001960: 2020 2020 2020 5c3c 2f73 7061 6e3e 3c2f \\.
    \n-000019c0: 3233 3c2f 7370 616e 3e3c 7370 616e 2063 23 static\n-000019f0: 2061 7574 6f20 6765 7443 7265 6174 6f72 auto getCreator\n-00001a00: 2829 2020 2020 2020 2020 2020 2020 2020 () \n-00001a10: 2020 2020 5c3c 2f73 7061 6e3e 3c2f 6469 \\.
    24\n-00001a70: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 { \n-00001aa0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001ab0: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001ac0: 2020 5c3c 2f73 7061 6e3e 3c2f 6469 763e \\
    \n-00001ad0: 0a3c 6469 7620 636c 6173 733d 226c 696e .
    \n-00001b00: 3c2f 613e 3c73 7061 6e20 636c 6173 733d 25\n-00001b40: 2020 2020 2020 2020 7265 7475 726e 205f return _\n-00001b50: 5f56 415f 4152 4753 5f5f 3b20 2020 2020 _VA_ARGS__; \n-00001b60: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001b70: 5c3c 2f73 7061 6e3e 3c2f 6469 763e 0a3c \\
    .<\n-00001b80: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00001b90: 3e3c 6120 6964 3d22 6c30 3030 3236 2220 > 26 \n-00001bf0: 2020 2020 7d20 2020 2020 2020 2020 2020 } \n-00001c00: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001c10: 2020 2020 2020 2020 2020 2020 2020 5c3c \\<\n-00001c20: 2f73 7061 6e3e 3c2f 6469 763e 0a3c 6469 /span>
    .<\n-00001c40: 6120 6964 3d22 6c30 3030 3237 2220 6e61 a id=\"l00027\" na\n-00001c50: 6d65 3d22 6c30 3030 3237 223e 3c2f 613e me=\"l00027\">\n-00001c60: 3c73 7061 6e20 636c 6173 733d 226c 696e 27 \n-00001ca0: 2020 7374 6174 6963 2073 7464 3a3a 7374 static std::st\n-00001cb0: 7269 6e67 206e 616d 6528 2920 7b20 7265 ring name() { re\n-00001cc0: 7475 726e 2069 643b 207d 2020 5c3c 2f73 turn id; } \\
    .
    28<\n-00001d30: 7370 616e 2063 6c61 7373 3d22 7072 6570 span class=\"prep\n-00001d40: 726f 6365 7373 6f72 223e 2020 2020 7d3b rocessor\"> };\n-00001d50: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001d60: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001d70: 2020 2020 2020 2020 2020 5c3c 2f73 7061 \\
    .
    29 } \n-00001e00: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001e10: 2020 2020 2020 2020 2020 2020 2020 2020 \n-00001e20: 2020 2020 2020 2020 5c3c 2f73 7061 6e3e \\\n-00001e30: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00001e80: 2020 3330 3c2f 7370 616e 3e3c 7370 616e 30 DUNE_INC\n-00001eb0: 5f43 4f55 4e54 4552 2854 6167 293c 2f73 _COUNTER(Tag)
    .
    31 \n-00001f20: 3c2f 6469 763e 0a3c 6469 7620 636c 6173
    .
    \n-00001f70: 2020 3332 3c2f 7370 616e 3e20 3c2f 6469 32 .
    33\n-00001fd0: 3c2f 7370 616e 3e3c 7370 616e 2063 6c61 nam\n-00001ff0: 6573 7061 6365 203c 2f73 7061 6e3e 3c61 espace Du\n-00002030: 6e65 3c2f 613e 207b 3c2f 6469 763e 0a3c ne {
    .<\n-00002040: 6469 7620 636c 6173 733d 226c 696e 6522 div class=\"line\"\n-00002050: 3e3c 6120 6964 3d22 6c30 3030 3334 2220 > 34 names\n-000020b0: 7061 6365 203c 2f73 7061 6e3e 7b3c 2f64 pace {.
    3\n-00002110: 353c 2f73 7061 6e3e 2020 2020 3c73 7061 5 template<class\n-00002160: 3c2f 7370 616e 3e20 5461 672c 2073 7464 Tag, std\n-00002170: 3a3a 3c73 7061 6e20 636c 6173 733d 226b ::size\n-00002190: 5f74 3c2f 7370 616e 3e20 696e 6465 7826 _t index&\n-000021a0: 6774 3b3c 2f64 6976 3e0a 3c64 6976 2063 gt;
    .
    36 \n-00002200: 2020 3c73 7061 6e20 636c 6173 733d 226b struct <\n-00002220: 2f73 7061 6e3e 5265 6769 7374 7279 3b3c /span>Registry;<\n-00002230: 2f64 6976 3e0a 3c64 6976 2063 6c61 7373 /div>.
    \n-00002280: 2033 373c 2f73 7061 6e3e 2020 7d3c 2f64 37 }.
    3\n-000022e0: 383c 2f73 7061 6e3e 203c 2f64 6976 3e0a 8
    .\n-000022f0: 3c64 6976 2063 6c61 7373 3d22 6c69 6e65
    <\n-00002320: 2f61 3e3c 7370 616e 2063 6c61 7373 3d22 /a> 39 name\n-00002360: 7370 6163 6520 3c2f 7370 616e 3e7b 3c2f space {.
    \n-000023c0: 3430 3c2f 7370 616e 3e20 2020 203c 7370 40 .......<\n+00000620: 2f73 6372 6970 743e 0a3c 7363 7269 7074 /script>..\n+00000660: 3c73 6372 6970 7420 7479 7065 3d22 7465 \n \n \n \n \n \n@@ -64,62 +64,59 @@\n \n
    \n
    \n
    \n \n-
    multitypeblockmatrix.hh File Reference
    \n+Namespaces
    \n+
    matrix.hh File Reference
    \n
    \n
    \n+\n+

    A dynamic dense block matrix class. \n+More...

    \n
    #include <cmath>
    \n-#include <iostream>
    \n-#include <tuple>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include "istlexception.hh"
    \n-#include "gsetc.hh"
    \n+#include <memory>
    \n+#include <dune/common/ftraits.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/istl/bvector.hh>
    \n+#include <dune/istl/istlexception.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n+\n+\n \n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n+\n \n-\n-\n+\n \n

    \n Classes

    class  Dune::MultiTypeBlockMatrix< FirstRow, Args >
     A Matrix class to support different block types. More...
     
    class  Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, remain_col >
     part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types More...
    class  Dune::MatrixImp::DenseMatrixBase< B, A >
     A Vector of blocks with different blocksizes. More...
     
    class  Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, 0 >
    class  Dune::MatrixImp::DenseMatrixBase< B, A >::Iterator
     Iterator class for sequential access. More...
     
    class  Dune::MultiTypeBlockMatrix_Solver< I, crow, remain_row >
     solver for MultiTypeBlockVector & MultiTypeBlockMatrix types More...
    class  Dune::MatrixImp::DenseMatrixBase< B, A >::ConstIterator
     ConstIterator class for sequential access. More...
     
    class  Dune::MultiTypeBlockMatrix_Solver< I, crow, 0 >
    class  Dune::Matrix< T, A >
     A generic dynamic dense matrix. More...
     
    struct  std::tuple_element< i, Dune::MultiTypeBlockMatrix< Args... > >
     Make std::tuple_element work for MultiTypeBlockMatrix. More...
    struct  Dune::FieldTraits< Matrix< T, A > >
     
    \n \n \n \n-\n-\n+\n \n-

    \n Namespaces

    namespace  Dune
     
    namespace  std
     STL namespace.
    namespace  Dune::MatrixImp
     
    \n-\n-\n-\n-\n-\n

    \n-Functions

    template<typename T1 , typename... Args>
    std::ostream & Dune::operator<< (std::ostream &s, const MultiTypeBlockMatrix< T1, Args... > &m)
     << operator for a MultiTypeBlockMatrix More...
     
    \n-
    \n+

    Detailed Description

    \n+

    A dynamic dense block matrix class.

    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,49 +4,45 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-multitypeblockmatrix.hh File Reference\n+Classes | Namespaces\n+matrix.hh File Reference\n+A dynamic dense block matrix class. More...\n #include \n-#include \n-#include \n-#include \n-#include \"istlexception.hh\"\n-#include \"gsetc.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::MultiTypeBlockMatrix<_FirstRow,_Args_>\n-\u00a0 A Matrix class to support different block types. More...\n+ class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>\n+\u00a0 A Vector of blocks with different blocksizes. More...\n \u00a0\n- class \u00a0Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_remain_col_>\n-\u00a0 part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types\n- More...\n+ class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>::Iterator\n+\u00a0 Iterator class for sequential access. More...\n \u00a0\n- class \u00a0Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_0_>\n+ class \u00a0Dune::MatrixImp::DenseMatrixBase<_B,_A_>::ConstIterator\n+\u00a0 ConstIterator class for sequential access. More...\n \u00a0\n- class \u00a0Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_remain_row_>\n-\u00a0 solver for MultiTypeBlockVector & MultiTypeBlockMatrix types More...\n+ class \u00a0Dune::Matrix<_T,_A_>\n+\u00a0 A generic dynamic dense matrix. More...\n \u00a0\n- class \u00a0Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>\n-\u00a0\n-struct \u00a0std::tuple_element<_i,_Dune::MultiTypeBlockMatrix<_Args..._>_>\n-\u00a0 Make std::tuple_element work for MultiTypeBlockMatrix. More...\n+struct \u00a0Dune::FieldTraits<_Matrix<_T,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0std\n-\u00a0 STL namespace.\n-\u00a0\n- Functions\n-template\n-std::ostream &\u00a0Dune::operator<< (std::ostream &s, const MultiTypeBlockMatrix<\n- T1, Args... > &m)\n-\u00a0 << operator for a MultiTypeBlockMatrix More...\n+namespace \u00a0Dune::MatrixImp\n \u00a0\n+***** Detailed Description *****\n+A dynamic dense block matrix class.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00068_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00068_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: multitypeblockmatrix.hh Source File\n+dune-istl: matrix.hh Source File\n \n \n \n \n \n \n \n@@ -62,576 +62,1070 @@\n \n
    \n \n
    \n
    \n
    \n-
    multitypeblockmatrix.hh
    \n+
    matrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH
    \n-
    6#define DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_MATRIX_HH
    \n+
    6#define DUNE_ISTL_MATRIX_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <iostream>
    \n-
    10#include <tuple>
    \n-
    11
    \n-
    12#include <dune/common/hybridutilities.hh>
    \n-
    13
    \n-
    14#include "istlexception.hh"
    \n-
    15
    \n-
    16// forward declaration
    \n-
    17namespace Dune
    \n-
    18{
    \n-
    19 template<typename FirstRow, typename... Args>
    \n-
    20 class MultiTypeBlockMatrix;
    \n-
    21
    \n-
    22 template<int I, int crow, int remain_row>
    \n-
    23 class MultiTypeBlockMatrix_Solver;
    \n-
    24}
    \n+
    12#include <cmath>
    \n+
    13#include <memory>
    \n+
    14
    \n+
    15#include <dune/common/ftraits.hh>
    \n+
    16#include <dune/common/typetraits.hh>
    \n+
    17#include <dune/common/scalarvectorview.hh>
    \n+
    18#include <dune/common/scalarmatrixview.hh>
    \n+
    19
    \n+
    20#include <dune/istl/bvector.hh>
    \n+\n+\n+
    23
    \n+
    24namespace Dune {
    \n
    25
    \n-
    26#include "gsetc.hh"
    \n-
    27
    \n-
    28namespace Dune {
    \n-
    29
    \n-
    43 template<typename FirstRow, typename... Args>
    \n-\n-
    45 : public std::tuple<FirstRow, Args...>
    \n-
    46 {
    \n-
    47 using ParentType = std::tuple<FirstRow, Args...>;
    \n-
    48 public:
    \n-
    49
    \n-
    51 using ParentType::ParentType;
    \n-
    52
    \n-
    56 typedef MultiTypeBlockMatrix<FirstRow, Args...> type;
    \n+
    26namespace MatrixImp
    \n+
    27{
    \n+
    39 template<class B, class A=std::allocator<B> >
    \n+
    40 class DenseMatrixBase : public Imp::block_vector_unmanaged<B,A>
    \n+
    41 // this derivation gives us all the blas level 1 and norms
    \n+
    42 // on the large array. However, access operators have to be
    \n+
    43 // overwritten.
    \n+
    44 {
    \n+
    45 public:
    \n+
    46
    \n+
    47 //===== type definitions and constants
    \n+
    48
    \n+
    50 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    51
    \n+
    53 typedef A allocator_type;
    \n+
    54
    \n+
    56 typedef typename A::size_type size_type;
    \n
    57
    \n-
    59 using size_type = std::size_t;
    \n-
    60
    \n-
    61 typedef typename FirstRow::field_type field_type;
    \n-
    62
    \n-
    64 static constexpr size_type N()
    \n-
    65 {
    \n-
    66 return 1+sizeof...(Args);
    \n-
    67 }
    \n+\n+
    64
    \n+\n
    68
    \n-
    74 [[deprecated("Use method 'N' instead")]]
    \n-
    75 static constexpr size_type size()
    \n-
    76 {
    \n-
    77 return 1+sizeof...(Args);
    \n-
    78 }
    \n-
    79
    \n-
    81 static constexpr size_type M()
    \n-
    82 {
    \n-
    83 return FirstRow::size();
    \n-
    84 }
    \n-
    85
    \n-
    102 template< size_type index >
    \n-
    103 auto
    \n-
    104 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable)
    \n-
    105 -> decltype(std::get<index>(*this))
    \n-
    106 {
    \n-
    107 return std::get<index>(*this);
    \n-
    108 }
    \n-
    109
    \n-
    115 template< size_type index >
    \n-
    116 auto
    \n-
    117 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable) const
    \n-
    118 -> decltype(std::get<index>(*this))
    \n-
    119 {
    \n-
    120 return std::get<index>(*this);
    \n-
    121 }
    \n-
    122
    \n-
    126 template<typename T>
    \n-
    127 void operator= (const T& newval) {
    \n-
    128 using namespace Dune::Hybrid;
    \n-
    129 auto size = index_constant<1+sizeof...(Args)>();
    \n-
    130 // Since Dune::Hybrid::size(MultiTypeBlockMatrix) is not implemented,
    \n-
    131 // we cannot use a plain forEach(*this, ...). This could be achieved,
    \n-
    132 // e.g., by implementing a static size() method.
    \n-
    133 forEach(integralRange(size), [&](auto&& i) {
    \n-
    134 (*this)[i] = newval;
    \n-
    135 });
    \n-
    136 }
    \n-
    137
    \n-
    138 //===== vector space arithmetic
    \n-
    139
    \n-\n-
    142 {
    \n-
    143 auto size = index_constant<N()>();
    \n-
    144 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n-
    145 (*this)[i] *= k;
    \n-
    146 });
    \n-
    147
    \n-
    148 return *this;
    \n-
    149 }
    \n-
    150
    \n-\n-
    153 {
    \n-
    154 auto size = index_constant<N()>();
    \n-
    155 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n-
    156 (*this)[i] /= k;
    \n-
    157 });
    \n-
    158
    \n-
    159 return *this;
    \n-
    160 }
    \n-
    161
    \n+
    69 // just a shorthand
    \n+
    70 typedef Imp::BlockVectorWindow<B,A> window_type;
    \n+
    71
    \n+\n+
    73
    \n+\n+
    75
    \n+
    76
    \n+
    77 //===== constructors and such
    \n+
    78
    \n+
    82 DenseMatrixBase () : Imp::block_vector_unmanaged<B,A>()
    \n+
    83 {
    \n+
    84 // nothing is known ...
    \n+
    85 rows_ = 0;
    \n+
    86 columns_ = 0;
    \n+
    87 }
    \n+
    88
    \n+
    95 DenseMatrixBase (size_type rows, size_type columns) : Imp::block_vector_unmanaged<B,A>()
    \n+
    96 {
    \n+
    97 // and we can allocate the big array in the base class
    \n+
    98 this->n = rows*columns;
    \n+
    99 columns_ = columns;
    \n+
    100 if (this->n>0)
    \n+
    101 {
    \n+
    102 this->p = allocator_.allocate(this->n);
    \n+
    103 new (this->p)B[this->n];
    \n+
    104 }
    \n+
    105 else
    \n+
    106 {
    \n+
    107 this->n = 0;
    \n+
    108 this->p = 0;
    \n+
    109 }
    \n+
    110
    \n+
    111 // we can allocate the windows now
    \n+
    112 rows_ = rows;
    \n+
    113 }
    \n+
    114
    \n+\n+
    117 {
    \n+
    118 // allocate the big array in the base class
    \n+
    119 this->n = a.n;
    \n+
    120 columns_ = a.columns_;
    \n+
    121 if (this->n>0)
    \n+
    122 {
    \n+
    123 // allocate and construct objects
    \n+
    124 this->p = allocator_.allocate(this->n);
    \n+
    125 new (this->p)B[this->n];
    \n+
    126
    \n+
    127 // copy data
    \n+
    128 for (size_type i=0; i<this->n; i++)
    \n+
    129 this->p[i]=a.p[i];
    \n+
    130 }
    \n+
    131 else
    \n+
    132 {
    \n+
    133 this->n = 0;
    \n+
    134 this->p = nullptr;
    \n+
    135 }
    \n+
    136
    \n+
    137 // we can allocate the windows now
    \n+
    138 rows_ = a.rows_;
    \n+
    139 }
    \n+
    140
    \n+\n+
    143 {
    \n+
    144 if (this->n>0) {
    \n+
    145 size_type i=this->n;
    \n+
    146 while (i)
    \n+
    147 this->p[--i].~B();
    \n+
    148 allocator_.deallocate(this->p,this->n);
    \n+
    149 }
    \n+
    150 }
    \n+
    151
    \n+
    153 void resize (size_type rows, size_type columns)
    \n+
    154 {
    \n+
    155 // deconstruct objects and deallocate memory if necessary
    \n+
    156 if (this->n>0) {
    \n+
    157 size_type i=this->n;
    \n+
    158 while (i)
    \n+
    159 this->p[--i].~B();
    \n+
    160 allocator_.deallocate(this->p,this->n);
    \n+
    161 }
    \n
    162
    \n-\n-
    169 {
    \n-
    170 auto size = index_constant<N()>();
    \n-
    171 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n-
    172 (*this)[i] += b[i];
    \n-
    173 });
    \n-
    174
    \n-
    175 return *this;
    \n-
    176 }
    \n-
    177
    \n-\n-
    184 {
    \n-
    185 auto size = index_constant<N()>();
    \n-
    186 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {
    \n-
    187 (*this)[i] -= b[i];
    \n-
    188 });
    \n-
    189
    \n-
    190 return *this;
    \n-
    191 }
    \n-
    192
    \n-
    195 template<typename X, typename Y>
    \n-
    196 void mv (const X& x, Y& y) const {
    \n-
    197 static_assert(X::size() == M(), "length of x does not match row length");
    \n-
    198 static_assert(Y::size() == N(), "length of y does not match row count");
    \n-
    199 y = 0; //reset y (for mv uses umv)
    \n-
    200 umv(x,y);
    \n-
    201 }
    \n-
    202
    \n-
    205 template<typename X, typename Y>
    \n-
    206 void umv (const X& x, Y& y) const {
    \n-
    207 static_assert(X::size() == M(), "length of x does not match row length");
    \n-
    208 static_assert(Y::size() == N(), "length of y does not match row count");
    \n-
    209 using namespace Dune::Hybrid;
    \n-
    210 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    211 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    212 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    213 (*this)[i][j].umv(x[j], y[i]);
    \n-
    214 });
    \n-
    215 });
    \n-
    216 }
    \n-
    217
    \n-
    220 template<typename X, typename Y>
    \n-
    221 void mmv (const X& x, Y& y) const {
    \n-
    222 static_assert(X::size() == M(), "length of x does not match row length");
    \n-
    223 static_assert(Y::size() == N(), "length of y does not match row count");
    \n-
    224 using namespace Dune::Hybrid;
    \n-
    225 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    226 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    227 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    228 (*this)[i][j].mmv(x[j], y[i]);
    \n-
    229 });
    \n-
    230 });
    \n-
    231 }
    \n-
    232
    \n-
    235 template<typename AlphaType, typename X, typename Y>
    \n-
    236 void usmv (const AlphaType& alpha, const X& x, Y& y) const {
    \n-
    237 static_assert(X::size() == M(), "length of x does not match row length");
    \n-
    238 static_assert(Y::size() == N(), "length of y does not match row count");
    \n-
    239 using namespace Dune::Hybrid;
    \n-
    240 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    241 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    242 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    243 (*this)[i][j].usmv(alpha, x[j], y[i]);
    \n-
    244 });
    \n-
    245 });
    \n-
    246 }
    \n-
    247
    \n-
    250 template<typename X, typename Y>
    \n-
    251 void mtv (const X& x, Y& y) const {
    \n-
    252 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    253 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    254 y = 0;
    \n-
    255 umtv(x,y);
    \n+
    163 // and we can allocate the big array in the base class
    \n+
    164 this->n = rows*columns;
    \n+
    165 if (this->n>0)
    \n+
    166 {
    \n+
    167 this->p = allocator_.allocate(this->n);
    \n+
    168 new (this->p)B[this->n];
    \n+
    169 }
    \n+
    170 else
    \n+
    171 {
    \n+
    172 this->n = 0;
    \n+
    173 this->p = nullptr;
    \n+
    174 }
    \n+
    175
    \n+
    176 // we can allocate the windows now
    \n+
    177 rows_ = rows;
    \n+
    178 columns_ = columns;
    \n+
    179 }
    \n+
    180
    \n+\n+
    183 {
    \n+
    184 if (&a!=this) // check if this and a are different objects
    \n+
    185 {
    \n+
    186 columns_ = a.columns_;
    \n+
    187 // reallocate arrays if necessary
    \n+
    188 // Note: still the block sizes may vary !
    \n+
    189 if (this->n!=a.n || rows_!=a.rows_)
    \n+
    190 {
    \n+
    191 // deconstruct objects and deallocate memory if necessary
    \n+
    192 if (this->n>0) {
    \n+
    193 size_type i=this->n;
    \n+
    194 while (i)
    \n+
    195 this->p[--i].~B();
    \n+
    196 allocator_.deallocate(this->p,this->n);
    \n+
    197 }
    \n+
    198
    \n+
    199 // allocate the big array in the base class
    \n+
    200 this->n = a.n;
    \n+
    201 if (this->n>0)
    \n+
    202 {
    \n+
    203 // allocate and construct objects
    \n+
    204 this->p = allocator_.allocate(this->n);
    \n+
    205 new (this->p)B[this->n];
    \n+
    206 }
    \n+
    207 else
    \n+
    208 {
    \n+
    209 this->n = 0;
    \n+
    210 this->p = nullptr;
    \n+
    211 }
    \n+
    212
    \n+
    213 // Copy number of rows
    \n+
    214 rows_ = a.rows_;
    \n+
    215 }
    \n+
    216
    \n+
    217 // and copy the data
    \n+
    218 for (size_type i=0; i<this->n; i++)
    \n+
    219 this->p[i]=a.p[i];
    \n+
    220 }
    \n+
    221
    \n+
    222 return *this;
    \n+
    223 }
    \n+
    224
    \n+
    225
    \n+
    226 //===== assignment from scalar
    \n+
    227
    \n+\n+
    230 {
    \n+
    231 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n+
    232 return *this;
    \n+
    233 }
    \n+
    234
    \n+
    235
    \n+
    236 //===== access to components
    \n+
    237 // has to be overwritten from base class because it must
    \n+
    238 // return access to the windows
    \n+
    239
    \n+\n+
    242 {
    \n+
    243#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    244 if (i>=rows_) DUNE_THROW(ISTLError,"index out of range");
    \n+
    245#endif
    \n+
    246 return window_type(this->p + i*columns_, columns_);
    \n+
    247 }
    \n+
    248
    \n+\n+
    251 {
    \n+
    252#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    253 if (i<0 || i>=rows_) DUNE_THROW(ISTLError,"index out of range");
    \n+
    254#endif
    \n+
    255 return window_type(this->p + i*columns_, columns_);
    \n
    256 }
    \n
    257
    \n-
    260 template<typename X, typename Y>
    \n-
    261 void umtv (const X& x, Y& y) const {
    \n-
    262 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    263 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    264 using namespace Dune::Hybrid;
    \n-
    265 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    266 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    267 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    268 (*this)[j][i].umtv(x[j], y[i]);
    \n-
    269 });
    \n-
    270 });
    \n-
    271 }
    \n-
    272
    \n-
    275 template<typename X, typename Y>
    \n-
    276 void mmtv (const X& x, Y& y) const {
    \n-
    277 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    278 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    279 using namespace Dune::Hybrid;
    \n-
    280 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    281 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    282 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    283 (*this)[j][i].mmtv(x[j], y[i]);
    \n-
    284 });
    \n-
    285 });
    \n-
    286 }
    \n-
    287
    \n-
    290 template<typename X, typename Y>
    \n-
    291 void usmtv (const field_type& alpha, const X& x, Y& y) const {
    \n-
    292 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    293 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    294 using namespace Dune::Hybrid;
    \n-
    295 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    296 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    297 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    298 (*this)[j][i].usmtv(alpha, x[j], y[i]);
    \n-
    299 });
    \n-
    300 });
    \n-
    301 }
    \n-
    302
    \n-
    305 template<typename X, typename Y>
    \n-
    306 void umhv (const X& x, Y& y) const {
    \n-
    307 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    308 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    309 using namespace Dune::Hybrid;
    \n-
    310 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    311 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    312 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    313 (*this)[j][i].umhv(x[j], y[i]);
    \n-
    314 });
    \n-
    315 });
    \n-
    316 }
    \n-
    317
    \n-
    320 template<typename X, typename Y>
    \n-
    321 void mmhv (const X& x, Y& y) const {
    \n-
    322 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    323 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    324 using namespace Dune::Hybrid;
    \n-
    325 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    326 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    327 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    328 (*this)[j][i].mmhv(x[j], y[i]);
    \n-
    329 });
    \n-
    330 });
    \n-
    331 }
    \n+
    258 // forward declaration
    \n+
    259 class ConstIterator;
    \n+
    260
    \n+\n+
    263 {
    \n+
    264 public:
    \n+\n+
    267 : window_(nullptr,0)
    \n+
    268 {
    \n+
    269 i = 0;
    \n+
    270 }
    \n+
    271
    \n+
    272 Iterator (Iterator& other) = default;
    \n+
    273 Iterator (Iterator&& other) = default;
    \n+
    274
    \n+
    276 Iterator (B* data, size_type columns, size_type _i)
    \n+
    277 : i(_i),
    \n+
    278 window_(data + _i*columns, columns)
    \n+
    279 {}
    \n+
    280
    \n+\n+
    283 {
    \n+
    284 i = other.i;
    \n+
    285 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n+
    286 window_.set(other.window_.getsize(),other.window_.getptr());
    \n+
    287 return *this;
    \n+
    288 }
    \n+
    289
    \n+\n+
    292 {
    \n+
    293 i = other.i;
    \n+
    294 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n+
    295 window_.set(other.window_.getsize(),other.window_.getptr());
    \n+
    296 return *this;
    \n+
    297 }
    \n+
    298
    \n+\n+
    301 {
    \n+
    302 ++i;
    \n+
    303 window_.setptr(window_.getptr()+window_.getsize());
    \n+
    304 return *this;
    \n+
    305 }
    \n+
    306
    \n+\n+
    309 {
    \n+
    310 --i;
    \n+
    311 window_.setptr(window_.getptr()-window_.getsize());
    \n+
    312 return *this;
    \n+
    313 }
    \n+
    314
    \n+
    316 bool operator== (const Iterator& it) const
    \n+
    317 {
    \n+
    318 return window_.getptr() == it.window_.getptr();
    \n+
    319 }
    \n+
    320
    \n+
    322 bool operator!= (const Iterator& it) const
    \n+
    323 {
    \n+
    324 return window_.getptr() != it.window_.getptr();
    \n+
    325 }
    \n+
    326
    \n+
    328 bool operator== (const ConstIterator& it) const
    \n+
    329 {
    \n+
    330 return window_.getptr() == it.window_.getptr();
    \n+
    331 }
    \n
    332
    \n-
    335 template<typename X, typename Y>
    \n-
    336 void usmhv (const field_type& alpha, const X& x, Y& y) const {
    \n-
    337 static_assert(X::size() == N(), "length of x does not match number of rows");
    \n-
    338 static_assert(Y::size() == M(), "length of y does not match number of columns");
    \n-
    339 using namespace Dune::Hybrid;
    \n-
    340 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {
    \n-
    341 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    342 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {
    \n-
    343 (*this)[j][i].usmhv(alpha, x[j], y[i]);
    \n-
    344 });
    \n-
    345 });
    \n-
    346 }
    \n-
    347
    \n-
    348
    \n-
    349 //===== norms
    \n+
    334 bool operator!= (const ConstIterator& it) const
    \n+
    335 {
    \n+
    336 return window_.getptr() != it.window_.getptr();
    \n+
    337 }
    \n+
    338
    \n+\n+
    341 {
    \n+
    342 return window_;
    \n+
    343 }
    \n+
    344
    \n+\n+
    347 {
    \n+
    348 return &window_;
    \n+
    349 }
    \n
    350
    \n-
    352 auto frobenius_norm2 () const
    \n-
    353 {
    \n-
    354 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n-
    355 typename FieldTraits<field_type_00>::real_type sum=0;
    \n+
    351 // return index corresponding to pointer
    \n+\n+
    353 {
    \n+
    354 return i;
    \n+
    355 }
    \n
    356
    \n-
    357 auto rows = index_constant<N()>();
    \n-
    358 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n-
    359 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n-
    360 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n-
    361 sum += (*this)[i][j].frobenius_norm2();
    \n-
    362 });
    \n-
    363 });
    \n-
    364
    \n-
    365 return sum;
    \n-
    366 }
    \n-
    367
    \n-
    369 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n-
    370 {
    \n-
    371 return sqrt(frobenius_norm2());
    \n-
    372 }
    \n-
    373
    \n-
    375 auto infinity_norm () const
    \n-
    376 {
    \n-
    377 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n-
    378 using std::max;
    \n-
    379 typename FieldTraits<field_type_00>::real_type norm=0;
    \n-
    380
    \n-
    381 auto rows = index_constant<N()>();
    \n-
    382 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n-
    383
    \n-
    384 typename FieldTraits<field_type_00>::real_type sum=0;
    \n-
    385 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n-
    386 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n-
    387 sum += (*this)[i][j].infinity_norm();
    \n-
    388 });
    \n-
    389 norm = max(sum, norm);
    \n-
    390 });
    \n-
    391
    \n-
    392 return norm;
    \n-
    393 }
    \n-
    394
    \n-
    396 auto infinity_norm_real () const
    \n-
    397 {
    \n-
    398 using field_type_00 = typename std::decay_t<decltype((*this)[Indices::_0][Indices::_0])>::field_type;
    \n-
    399 using std::max;
    \n-
    400 typename FieldTraits<field_type_00>::real_type norm=0;
    \n+
    357 friend class ConstIterator;
    \n+
    358
    \n+
    359 private:
    \n+
    360 size_type i;
    \n+
    361 mutable window_type window_;
    \n+
    362 };
    \n+
    363
    \n+\n+
    366 {
    \n+
    367 return Iterator(this->p, columns_, 0);
    \n+
    368 }
    \n+
    369
    \n+\n+
    372 {
    \n+
    373 return Iterator(this->p, columns_, rows_);
    \n+
    374 }
    \n+
    375
    \n+\n+
    379 {
    \n+
    380 return Iterator(this->p, columns_, rows_-1);
    \n+
    381 }
    \n+
    382
    \n+\n+
    386 {
    \n+
    387 return Iterator(this->p, columns_, -1);
    \n+
    388 }
    \n+
    389
    \n+\n+
    392 {
    \n+
    393 return Iterator(this->p, columns_, std::min(i,rows_));
    \n+
    394 }
    \n+
    395
    \n+\n+
    398 {
    \n+
    399 return ConstIterator(this->p, columns_, std::min(i,rows_));
    \n+
    400 }
    \n
    401
    \n-
    402 auto rows = index_constant<N()>();
    \n-
    403 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {
    \n-
    404
    \n-
    405 typename FieldTraits<field_type_00>::real_type sum=0;
    \n-
    406 auto cols = index_constant<MultiTypeBlockMatrix<FirstRow, Args...>::M()>();
    \n-
    407 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {
    \n-
    408 sum += (*this)[i][j].infinity_norm_real();
    \n-
    409 });
    \n-
    410 norm = max(sum, norm);
    \n-
    411 });
    \n+\n+
    404 {
    \n+
    405 public:
    \n+\n+
    408 : window_(nullptr,0)
    \n+
    409 {
    \n+
    410 i = 0;
    \n+
    411 }
    \n
    412
    \n-
    413 return norm;
    \n-
    414 }
    \n-
    415
    \n-
    416 };
    \n-
    417
    \n-
    423 template<typename T1, typename... Args>
    \n-
    424 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockMatrix<T1,Args...>& m) {
    \n-
    425 auto N = index_constant<MultiTypeBlockMatrix<T1,Args...>::N()>();
    \n-
    426 auto M = index_constant<MultiTypeBlockMatrix<T1,Args...>::M()>();
    \n-
    427 using namespace Dune::Hybrid;
    \n-
    428 forEach(integralRange(N), [&](auto&& i) {
    \n-
    429 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    430 forEach(integralRange(M), [&](auto&& j) {
    \n-
    431 s << "\\t(" << i << ", " << j << "): \\n" << m[i][j];
    \n-
    432 });
    \n-
    433 });
    \n-
    434 s << std::endl;
    \n-
    435 return s;
    \n-
    436 }
    \n-
    437
    \n-
    438 //make algmeta_itsteps known
    \n-
    439 template<int I, typename M>
    \n-
    440 struct algmeta_itsteps;
    \n-
    441
    \n-
    448 template<int I, int crow, int ccol, int remain_col> //MultiTypeBlockMatrix_Solver_Col: iterating over one row
    \n-
    449 class MultiTypeBlockMatrix_Solver_Col { //calculating b- A[i][j]*x[j]
    \n-
    450 public:
    \n-
    454 template <typename Trhs, typename TVector, typename TMatrix, typename K>
    \n-
    455 static void calc_rhs(const TMatrix& A, TVector& x, TVector& v, Trhs& b, const K& w) {
    \n-
    456 std::get<ccol>( std::get<crow>(A) ).mmv( std::get<ccol>(x), b );
    \n-\n-
    458 }
    \n-
    459
    \n-
    460 };
    \n-
    461 template<int I, int crow, int ccol> //MultiTypeBlockMatrix_Solver_Col recursion end
    \n-
    462 class MultiTypeBlockMatrix_Solver_Col<I,crow,ccol,0> {
    \n-
    463 public:
    \n-
    464 template <typename Trhs, typename TVector, typename TMatrix, typename K>
    \n-
    465 static void calc_rhs(const TMatrix&, TVector&, TVector&, Trhs&, const K&) {}
    \n-
    466 };
    \n+
    414 ConstIterator (const B* data, size_type columns, size_type _i)
    \n+
    415 : i(_i),
    \n+
    416 window_(const_cast<B*>(data + _i * columns), columns)
    \n+
    417 {}
    \n+
    418
    \n+\n+
    421 : i(it.i), window_(it.window_.getptr(),it.window_.getsize())
    \n+
    422 {}
    \n+
    423
    \n+\n+
    425 {
    \n+
    426 i = other.i;
    \n+
    427 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n+
    428 window_.set(other.window_.getsize(),other.window_.getptr());
    \n+
    429 return *this;
    \n+
    430 }
    \n+
    431
    \n+\n+
    433 {
    \n+
    434 i = other.i;
    \n+
    435 // Do NOT use window_.operator=, because that copies the window content, not just the window!
    \n+
    436 window_.set(other.window_.getsize(),other.window_.getptr());
    \n+
    437 return *this;
    \n+
    438 }
    \n+
    439
    \n+\n+
    442 {
    \n+
    443 ++i;
    \n+
    444 window_.setptr(window_.getptr()+window_.getsize());
    \n+
    445 return *this;
    \n+
    446 }
    \n+
    447
    \n+\n+
    450 {
    \n+
    451 --i;
    \n+
    452 window_.setptr(window_.getptr()-window_.getsize());
    \n+
    453 return *this;
    \n+
    454 }
    \n+
    455
    \n+
    457 bool operator== (const ConstIterator& it) const
    \n+
    458 {
    \n+
    459 return window_.getptr() == it.window_.getptr();
    \n+
    460 }
    \n+
    461
    \n+
    463 bool operator!= (const ConstIterator& it) const
    \n+
    464 {
    \n+
    465 return window_.getptr() != it.window_.getptr();
    \n+
    466 }
    \n
    467
    \n-
    468
    \n-
    469
    \n-
    476 template<int I, int crow, int remain_row>
    \n-\n-
    478 public:
    \n+
    469 bool operator== (const Iterator& it) const
    \n+
    470 {
    \n+
    471 return window_.getptr() == it.window_.getptr();
    \n+
    472 }
    \n+
    473
    \n+
    475 bool operator!= (const Iterator& it) const
    \n+
    476 {
    \n+
    477 return window_.getptr() != it.window_.getptr();
    \n+
    478 }
    \n
    479
    \n-
    483 template <typename TVector, typename TMatrix, typename K>
    \n-
    484 static void dbgs(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n-
    485 TVector xold(x);
    \n-
    486 xold=x; //store old x values
    \n-\n-
    488 x *= w;
    \n-
    489 x.axpy(1-w,xold); //improve x
    \n-
    490 }
    \n-
    491 template <typename TVector, typename TMatrix, typename K>
    \n-
    492 static void dbgs(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n-
    493 auto rhs = std::get<crow> (b);
    \n-
    494
    \n-
    495 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n-
    496 //solve on blocklevel I-1
    \n-
    497 using M =
    \n-
    498 typename std::remove_cv<
    \n-
    499 typename std::remove_reference<
    \n-
    500 decltype(std::get<crow>( std::get<crow>(A)))
    \n-
    501 >::type
    \n-
    502 >::type;
    \n-
    503 algmeta_itsteps<I-1,M>::dbgs(std::get<crow>( std::get<crow>(A)), std::get<crow>(x),rhs,w);
    \n-\n-
    505 }
    \n-
    506
    \n+
    481 const window_type& operator* () const
    \n+
    482 {
    \n+
    483 return window_;
    \n+
    484 }
    \n+
    485
    \n+\n+
    488 {
    \n+
    489 return &window_;
    \n+
    490 }
    \n+
    491
    \n+
    492 // return index corresponding to pointer
    \n+\n+
    494 {
    \n+
    495 return i;
    \n+
    496 }
    \n+
    497
    \n+
    498 friend class Iterator;
    \n+
    499
    \n+
    500 private:
    \n+
    501 size_type i;
    \n+
    502 mutable window_type window_;
    \n+
    503 };
    \n+
    504
    \n+\n
    507
    \n-
    508
    \n-
    512 template <typename TVector, typename TMatrix, typename K>
    \n-
    513 static void bsorf(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n-
    514 TVector v;
    \n-
    515 v=x; //use latest x values in right side calculation
    \n-\n-
    517
    \n-
    518 }
    \n-
    519 template <typename TVector, typename TMatrix, typename K> //recursion over all matrix rows (A)
    \n-
    520 static void bsorf(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n-
    521 auto rhs = std::get<crow> (b);
    \n+\n+
    510
    \n+\n+
    513 {
    \n+
    514 return ConstIterator(this->p, columns_, 0);
    \n+
    515 }
    \n+
    516
    \n+\n+
    519 {
    \n+
    520 return ConstIterator(this->p, columns_, rows_);
    \n+
    521 }
    \n
    522
    \n-
    523 MultiTypeBlockMatrix_Solver_Col<I,crow,0,TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n-
    524 //solve on blocklevel I-1
    \n-
    525 using M =
    \n-
    526 typename std::remove_cv<
    \n-
    527 typename std::remove_reference<
    \n-
    528 decltype(std::get<crow>( std::get<crow>(A)))
    \n-
    529 >::type
    \n-
    530 >::type;
    \n-
    531 algmeta_itsteps<I-1,M>::bsorf(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n-
    532 std::get<crow>(x).axpy(w,std::get<crow>(v));
    \n-\n+\n+
    526 {
    \n+
    527 return ConstIterator(this->p, columns_, rows_-1);
    \n+
    528 }
    \n+
    529
    \n+\n+
    532 {
    \n+
    533 return ConstIterator(this->p, columns_, -1);
    \n
    534 }
    \n
    535
    \n-
    539 template <typename TVector, typename TMatrix, typename K>
    \n-
    540 static void bsorb(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n-
    541 TVector v;
    \n-
    542 v=x; //use latest x values in right side calculation
    \n-\n+
    536 //===== sizes
    \n+
    537
    \n+
    539 size_type N () const
    \n+
    540 {
    \n+
    541 return rows_;
    \n+
    542 }
    \n+
    543
    \n
    544
    \n-
    545 }
    \n-
    546 template <typename TVector, typename TMatrix, typename K> //recursion over all matrix rows (A)
    \n-
    547 static void bsorb(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n-
    548 auto rhs = std::get<crow> (b);
    \n-
    549
    \n-
    550 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n-
    551 //solve on blocklevel I-1
    \n-
    552 using M =
    \n-
    553 typename std::remove_cv<
    \n-
    554 typename std::remove_reference<
    \n-
    555 decltype(std::get<crow>( std::get<crow>(A)))
    \n-
    556 >::type
    \n-
    557 >::type;
    \n-
    558 algmeta_itsteps<I-1,M>::bsorb(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n-
    559 std::get<crow>(x).axpy(w,std::get<crow>(v));
    \n-\n-
    561 }
    \n-
    562
    \n+
    545 private:
    \n+
    546 size_type rows_; // number of matrix rows
    \n+
    547 size_type columns_; // number of matrix columns
    \n+
    548
    \n+
    549 A allocator_;
    \n+
    550 };
    \n+
    551
    \n+
    552} // namespace MatrixImp
    \n+
    553
    \n+
    559 template<class T, class A=std::allocator<T> >
    \n+
    560 class Matrix
    \n+
    561 {
    \n+
    562 public:
    \n
    563
    \n-
    567 template <typename TVector, typename TMatrix, typename K>
    \n-
    568 static void dbjac(const TMatrix& A, TVector& x, const TVector& b, const K& w) {
    \n-
    569 TVector v(x);
    \n-
    570 v=0; //calc new x in v
    \n-\n-
    572 x.axpy(w,v); //improve x
    \n-
    573 }
    \n-
    574 template <typename TVector, typename TMatrix, typename K>
    \n-
    575 static void dbjac(const TMatrix& A, TVector& x, TVector& v, const TVector& b, const K& w) {
    \n-
    576 auto rhs = std::get<crow> (b);
    \n-
    577
    \n-
    578 MultiTypeBlockMatrix_Solver_Col<I,crow,0, TMatrix::M()>::calc_rhs(A,x,v,rhs,w); // calculate right side of equation
    \n-
    579 //solve on blocklevel I-1
    \n-
    580 using M =
    \n-
    581 typename std::remove_cv<
    \n-
    582 typename std::remove_reference<
    \n-
    583 decltype(std::get<crow>( std::get<crow>(A)))
    \n-
    584 >::type
    \n-
    585 >::type;
    \n-
    586 algmeta_itsteps<I-1,M>::dbjac(std::get<crow>( std::get<crow>(A)), std::get<crow>(v),rhs,w);
    \n-\n-
    588 }
    \n-
    589
    \n+
    565 using field_type = typename Imp::BlockTraits<T>::field_type;
    \n+
    566
    \n+
    568 typedef T block_type;
    \n+
    569
    \n+
    571 typedef A allocator_type;
    \n+
    572
    \n+\n+
    575
    \n+
    577 typedef typename A::size_type size_type;
    \n+
    578
    \n+\n+
    581
    \n+
    583 typedef typename row_type::iterator ColIterator;
    \n+
    584
    \n+\n+
    587
    \n+
    589 typedef typename row_type::const_iterator ConstColIterator;
    \n
    590
    \n-
    591
    \n-
    592
    \n-
    593 };
    \n-
    594 template<int I, int crow> //recursion end for remain_row = 0
    \n-\n-
    596 public:
    \n-
    597 template <typename TVector, typename TMatrix, typename K>
    \n-
    598 static void dbgs(const TMatrix&, TVector&, TVector&,
    \n-
    599 const TVector&, const K&) {}
    \n-
    600
    \n-
    601 template <typename TVector, typename TMatrix, typename K>
    \n-
    602 static void bsorf(const TMatrix&, TVector&, TVector&,
    \n-
    603 const TVector&, const K&) {}
    \n-
    604
    \n-
    605 template <typename TVector, typename TMatrix, typename K>
    \n-
    606 static void bsorb(const TMatrix&, TVector&, TVector&,
    \n-
    607 const TVector&, const K&) {}
    \n-
    608
    \n-
    609 template <typename TVector, typename TMatrix, typename K>
    \n-
    610 static void dbjac(const TMatrix&, TVector&, TVector&,
    \n-
    611 const TVector&, const K&) {}
    \n-
    612 };
    \n-
    613
    \n-
    614} // end namespace Dune
    \n-
    615
    \n-
    616namespace std
    \n-
    617{
    \n-
    622 template <size_t i, typename... Args>
    \n-
    623 struct tuple_element<i,Dune::MultiTypeBlockMatrix<Args...> >
    \n-
    624 {
    \n-
    625 using type = typename std::tuple_element<i, std::tuple<Args...> >::type;
    \n-
    626 };
    \n-
    627}
    \n-
    628#endif
    \n-\n-
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n-
    MultiTypeBlockMatrix< FirstRow, Args... > type
    Definition: multitypeblockmatrix.hh:56
    \n-
    static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:568
    \n-
    MultiTypeBlockMatrix & operator+=(const MultiTypeBlockMatrix &b)
    Add the entries of another matrix to this one.
    Definition: multitypeblockmatrix.hh:168
    \n-
    void mv(const X &x, Y &y) const
    y = A x
    Definition: multitypeblockmatrix.hh:196
    \n-
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: multitypeblockmatrix.hh:276
    \n-
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: multitypeblockmatrix.hh:321
    \n-
    static void dbgs(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:598
    \n-
    static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:484
    \n-
    static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:540
    \n-
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: multitypeblockmatrix.hh:336
    \n-
    FirstRow::field_type field_type
    Definition: multitypeblockmatrix.hh:61
    \n-
    void usmv(const AlphaType &alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: multitypeblockmatrix.hh:236
    \n-
    MultiTypeBlockMatrix & operator/=(const field_type &k)
    vector space division by scalar
    Definition: multitypeblockmatrix.hh:152
    \n-
    typename std::tuple_element< i, std::tuple< Args... > >::type type
    Definition: multitypeblockmatrix.hh:625
    \n-
    static void dbgs(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:492
    \n-
    static void bsorf(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:520
    \n-
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: multitypeblockmatrix.hh:306
    \n-
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: multitypeblockmatrix.hh:369
    \n-
    static constexpr size_type N()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:64
    \n-
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: multitypeblockmatrix.hh:291
    \n-
    void operator=(const T &newval)
    Definition: multitypeblockmatrix.hh:127
    \n-
    static void calc_rhs(const TMatrix &, TVector &, TVector &, Trhs &, const K &)
    Definition: multitypeblockmatrix.hh:465
    \n-
    void umv(const X &x, Y &y) const
    y += A x
    Definition: multitypeblockmatrix.hh:206
    \n-
    static void calc_rhs(const TMatrix &A, TVector &x, TVector &v, Trhs &b, const K &w)
    Definition: multitypeblockmatrix.hh:455
    \n-
    static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:513
    \n-
    static constexpr size_type size()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:75
    \n-
    static void dbjac(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:610
    \n-
    auto infinity_norm_real() const
    Bastardized version of the infinity-norm / row-sum norm.
    Definition: multitypeblockmatrix.hh:396
    \n-
    auto frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: multitypeblockmatrix.hh:352
    \n-
    std::size_t size_type
    Type used for sizes.
    Definition: multitypeblockmatrix.hh:59
    \n-
    auto infinity_norm() const
    Bastardized version of the infinity-norm / row-sum norm.
    Definition: multitypeblockmatrix.hh:375
    \n-
    static void bsorb(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:606
    \n-
    MultiTypeBlockMatrix & operator-=(const MultiTypeBlockMatrix &b)
    Subtract the entries of another matrix from this one.
    Definition: multitypeblockmatrix.hh:183
    \n-
    auto operator[](const std::integral_constant< size_type, index > indexVariable) -> decltype(std::get< index >(*this))
    Random-access operator.
    Definition: multitypeblockmatrix.hh:104
    \n-
    static void dbjac(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:575
    \n-
    static void bsorf(const TMatrix &, TVector &, TVector &, const TVector &, const K &)
    Definition: multitypeblockmatrix.hh:602
    \n-
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: multitypeblockmatrix.hh:251
    \n-
    static constexpr size_type M()
    Return the number of matrix columns.
    Definition: multitypeblockmatrix.hh:81
    \n-
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: multitypeblockmatrix.hh:221
    \n-
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: multitypeblockmatrix.hh:261
    \n-
    static void bsorb(const TMatrix &A, TVector &x, TVector &v, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:547
    \n-
    MultiTypeBlockMatrix & operator*=(const field_type &k)
    vector space multiplication with scalar
    Definition: multitypeblockmatrix.hh:141
    \n-
    STL namespace.
    \n+
    592 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    593 static constexpr auto blocklevel = blockLevel<T>()+1;
    \n+
    594
    \n+
    596 Matrix() : data_(0,0), cols_(0)
    \n+
    597 {}
    \n+
    598
    \n+
    601 Matrix(size_type rows, size_type cols) : data_(rows,cols), cols_(cols)
    \n+
    602 {}
    \n+
    603
    \n+
    608 void setSize(size_type rows, size_type cols) {
    \n+
    609 data_.resize(rows,cols);
    \n+
    610 cols_ = cols;
    \n+
    611 }
    \n+
    612
    \n+\n+
    615 {
    \n+
    616 return data_.begin();
    \n+
    617 }
    \n+
    618
    \n+\n+
    621 {
    \n+
    622 return data_.end();
    \n+
    623 }
    \n+
    624
    \n+\n+
    628 {
    \n+
    629 return data_.beforeEnd();
    \n+
    630 }
    \n+
    631
    \n+\n+
    635 {
    \n+
    636 return data_.beforeBegin();
    \n+
    637 }
    \n+
    638
    \n+\n+
    641 {
    \n+
    642 return data_.begin();
    \n+
    643 }
    \n+
    644
    \n+\n+
    647 {
    \n+
    648 return data_.end();
    \n+
    649 }
    \n+
    650
    \n+\n+
    654 {
    \n+
    655 return data_.beforeEnd();
    \n+
    656 }
    \n+
    657
    \n+\n+
    661 {
    \n+
    662 return data_.beforeBegin();
    \n+
    663 }
    \n+
    664
    \n+\n+
    667 {
    \n+
    668 data_ = t;
    \n+
    669 return *this;
    \n+
    670 }
    \n+
    671
    \n+\n+
    674#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    675 if (row<0)
    \n+
    676 DUNE_THROW(ISTLError, "Can't access negative rows!");
    \n+
    677 if (row>=N())
    \n+
    678 DUNE_THROW(ISTLError, "Row index out of range!");
    \n+
    679#endif
    \n+
    680 return data_[row];
    \n+
    681 }
    \n+
    682
    \n+
    684 const row_type operator[](size_type row) const {
    \n+
    685#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    686 if (row<0)
    \n+
    687 DUNE_THROW(ISTLError, "Can't access negative rows!");
    \n+
    688 if (row>=N())
    \n+
    689 DUNE_THROW(ISTLError, "Row index out of range!");
    \n+
    690#endif
    \n+
    691 return data_[row];
    \n+
    692 }
    \n+
    693
    \n+
    695 size_type N() const {
    \n+
    696 return data_.N();
    \n+
    697 }
    \n+
    698
    \n+
    700 size_type M() const {
    \n+
    701 return cols_;
    \n+
    702 }
    \n+
    703
    \n+\n+
    706 data_ *= scalar;
    \n+
    707 return (*this);
    \n+
    708 }
    \n+
    709
    \n+\n+
    712 data_ /= scalar;
    \n+
    713 return (*this);
    \n+
    714 }
    \n+
    715
    \n+\n+
    722#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    723 if(N()!=b.N() || M() != b.M())
    \n+
    724 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n+
    725#endif
    \n+
    726 data_ += b.data_;
    \n+
    727 return (*this);
    \n+
    728 }
    \n+
    729
    \n+\n+
    736#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    737 if(N()!=b.N() || M() != b.M())
    \n+
    738 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n+
    739#endif
    \n+
    740 data_ -= b.data_;
    \n+
    741 return (*this);
    \n+
    742 }
    \n+
    743
    \n+\n+
    746 Matrix out(M(), N());
    \n+
    747 for (size_type i=0; i<N(); i++)
    \n+
    748 for (size_type j=0; j<M(); j++)
    \n+
    749 out[j][i] = (*this)[i][j];
    \n+
    750
    \n+
    751 return out;
    \n+
    752 }
    \n+
    753
    \n+
    755 friend Matrix<T> operator*(const Matrix<T>& m1, const Matrix<T>& m2) {
    \n+
    756 Matrix<T> out(m1.N(), m2.M());
    \n+
    757 out = 0;
    \n+
    758
    \n+
    759 for (size_type i=0; i<out.N(); i++ ) {
    \n+
    760 for ( size_type j=0; j<out.M(); j++ )
    \n+
    761 for (size_type k=0; k<m1.M(); k++)
    \n+
    762 out[i][j] += m1[i][k]*m2[k][j];
    \n+
    763 }
    \n+
    764
    \n+
    765 return out;
    \n+
    766 }
    \n+
    767
    \n+
    769 template <class X, class Y>
    \n+
    770 friend Y operator*(const Matrix<T>& m, const X& vec) {
    \n+
    771#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    772 if (m.M()!=vec.size())
    \n+
    773 DUNE_THROW(ISTLError, "Vector size doesn't match the number of matrix columns!");
    \n+
    774#endif
    \n+
    775 Y out(m.N());
    \n+
    776 out = 0;
    \n+
    777
    \n+
    778 for (size_type i=0; i<out.size(); i++ ) {
    \n+
    779 for ( size_type j=0; j<vec.size(); j++ )
    \n+
    780 out[i] += m[i][j]*vec[j];
    \n+
    781 }
    \n+
    782
    \n+
    783 return out;
    \n+
    784 }
    \n+
    785
    \n+
    787 template <class X, class Y>
    \n+
    788 void mv(const X& x, Y& y) const
    \n+
    789 {
    \n+
    790#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    791 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    792 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    793#endif
    \n+
    794 for (size_type i=0; i<data_.N(); i++) {
    \n+
    795 y[i]=0;
    \n+
    796 for (size_type j=0; j<cols_; j++)
    \n+
    797 {
    \n+
    798 auto&& xj = Impl::asVector(x[j]);
    \n+
    799 auto&& yi = Impl::asVector(y[i]);
    \n+
    800 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
    \n+
    801 }
    \n+
    802 }
    \n+
    803 }
    \n+
    804
    \n+
    806 template<class X, class Y>
    \n+
    807 void mtv (const X& x, Y& y) const
    \n+
    808 {
    \n+
    809#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    810 if (x.N()!=N()) DUNE_THROW(ISTLError,"index out of range");
    \n+
    811 if (y.N()!=M()) DUNE_THROW(ISTLError,"index out of range");
    \n+
    812#endif
    \n+
    813 for(size_type i=0; i<y.N(); ++i)
    \n+
    814 y[i]=0;
    \n+
    815 umtv(x,y);
    \n+
    816 }
    \n+
    817
    \n+
    819 template <class X, class Y>
    \n+
    820 void umv(const X& x, Y& y) const
    \n+
    821 {
    \n+
    822#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    823 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    824 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    825#endif
    \n+
    826 for (size_type i=0; i<data_.N(); i++)
    \n+
    827 for (size_type j=0; j<cols_; j++)
    \n+
    828 {
    \n+
    829 auto&& xj = Impl::asVector(x[j]);
    \n+
    830 auto&& yi = Impl::asVector(y[i]);
    \n+
    831 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
    \n+
    832 }
    \n+
    833 }
    \n+
    834
    \n+
    836 template<class X, class Y>
    \n+
    837 void mmv (const X& x, Y& y) const
    \n+
    838 {
    \n+
    839#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    840 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    841 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    842#endif
    \n+
    843 for (size_type i=0; i<data_.N(); i++)
    \n+
    844 for (size_type j=0; j<cols_; j++)
    \n+
    845 {
    \n+
    846 auto&& xj = Impl::asVector(x[j]);
    \n+
    847 auto&& yi = Impl::asVector(y[i]);
    \n+
    848 Impl::asMatrix((*this)[i][j]).mmv(xj, yi);
    \n+
    849 }
    \n+
    850 }
    \n+
    851
    \n+
    853 template <class X, class Y>
    \n+
    854 void usmv(const field_type& alpha, const X& x, Y& y) const
    \n+
    855 {
    \n+
    856#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    857 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    858 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    859#endif
    \n+
    860 for (size_type i=0; i<data_.N(); i++)
    \n+
    861 for (size_type j=0; j<cols_; j++)
    \n+
    862 {
    \n+
    863 auto&& xj = Impl::asVector(x[j]);
    \n+
    864 auto&& yi = Impl::asVector(y[i]);
    \n+
    865 Impl::asMatrix((*this)[i][j]).usmv(alpha, xj, yi);
    \n+
    866 }
    \n+
    867 }
    \n+
    868
    \n+
    870 template<class X, class Y>
    \n+
    871 void umtv (const X& x, Y& y) const
    \n+
    872 {
    \n+
    873#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    874 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    875 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    876#endif
    \n+
    877 for (size_type i=0; i<data_.N(); i++)
    \n+
    878 for (size_type j=0; j<cols_; j++)
    \n+
    879 {
    \n+
    880 auto&& xi = Impl::asVector(x[i]);
    \n+
    881 auto&& yj = Impl::asVector(y[j]);
    \n+
    882 Impl::asMatrix((*this)[i][j]).umtv(xi, yj);
    \n+
    883 }
    \n+
    884 }
    \n+
    885
    \n+
    887 template<class X, class Y>
    \n+
    888 void mmtv (const X& x, Y& y) const
    \n+
    889 {
    \n+
    890#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    891 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    892 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    893#endif
    \n+
    894 for (size_type i=0; i<data_.N(); i++)
    \n+
    895 for (size_type j=0; j<cols_; j++)
    \n+
    896 {
    \n+
    897 auto&& xi = Impl::asVector(x[i]);
    \n+
    898 auto&& yj = Impl::asVector(y[j]);
    \n+
    899 Impl::asMatrix((*this)[i][j]).mmtv(xi, yj);
    \n+
    900 }
    \n+
    901 }
    \n+
    902
    \n+
    904 template<class X, class Y>
    \n+
    905 void usmtv (const field_type& alpha, const X& x, Y& y) const
    \n+
    906 {
    \n+
    907#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    908 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    909 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    910#endif
    \n+
    911 for (size_type i=0; i<data_.N(); i++)
    \n+
    912 for (size_type j=0; j<cols_; j++)
    \n+
    913 {
    \n+
    914 auto&& xi = Impl::asVector(x[i]);
    \n+
    915 auto&& yj = Impl::asVector(y[j]);
    \n+
    916 Impl::asMatrix((*this)[i][j]).usmtv(alpha, xi, yj);
    \n+
    917 }
    \n+
    918 }
    \n+
    919
    \n+
    921 template<class X, class Y>
    \n+
    922 void umhv (const X& x, Y& y) const
    \n+
    923 {
    \n+
    924#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    925 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    926 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    927#endif
    \n+
    928 for (size_type i=0; i<data_.N(); i++)
    \n+
    929 for (size_type j=0; j<cols_; j++)
    \n+
    930 {
    \n+
    931 auto&& xi = Impl::asVector(x[i]);
    \n+
    932 auto&& yj = Impl::asVector(y[j]);
    \n+
    933 Impl::asMatrix((*this)[i][j]).umhv(xi,yj);
    \n+
    934 }
    \n+
    935 }
    \n+
    936
    \n+
    938 template<class X, class Y>
    \n+
    939 void mmhv (const X& x, Y& y) const
    \n+
    940 {
    \n+
    941#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    942 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    943 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    944#endif
    \n+
    945 for (size_type i=0; i<data_.N(); i++)
    \n+
    946 for (size_type j=0; j<cols_; j++)
    \n+
    947 {
    \n+
    948 auto&& xi = Impl::asVector(x[i]);
    \n+
    949 auto&& yj = Impl::asVector(y[j]);
    \n+
    950 Impl::asMatrix((*this)[i][j]).mmhv(xi,yj);
    \n+
    951 }
    \n+
    952 }
    \n+
    953
    \n+
    955 template<class X, class Y>
    \n+
    956 void usmhv (const field_type& alpha, const X& x, Y& y) const
    \n+
    957 {
    \n+
    958#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    959 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    960 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
    \n+
    961#endif
    \n+
    962 for (size_type i=0; i<data_.N(); i++)
    \n+
    963 for (size_type j=0; j<cols_; j++)
    \n+
    964 {
    \n+
    965 auto&& xi = Impl::asVector(x[i]);
    \n+
    966 auto&& yj = Impl::asVector(y[j]);
    \n+
    967 Impl::asMatrix((*this)[i][j]).usmhv(alpha,xi,yj);
    \n+
    968 }
    \n+
    969 }
    \n+
    970
    \n+
    971 //===== norms
    \n+
    972
    \n+
    974 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n+
    975 {
    \n+
    976 return std::sqrt(frobenius_norm2());
    \n+
    977 }
    \n+
    978
    \n+
    980 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n+
    981 {
    \n+
    982 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    983 for (size_type i=0; i<this->N(); i++)
    \n+
    984 for (size_type j=0; j<this->M(); j++)
    \n+
    985 sum += Impl::asMatrix(data_[i][j]).frobenius_norm2();
    \n+
    986 return sum;
    \n+
    987 }
    \n+
    988
    \n+
    990 template <typename ft = field_type,
    \n+
    991 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    992 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    993 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    994 using std::max;
    \n+
    995
    \n+
    996 real_type norm = 0;
    \n+
    997 for (auto const &x : *this) {
    \n+
    998 real_type sum = 0;
    \n+
    999 for (auto const &y : x)
    \n+
    1000 sum += Impl::asMatrix(y).infinity_norm();
    \n+
    1001 norm = max(sum, norm);
    \n+
    1002 isNaN += sum;
    \n+
    1003 }
    \n+
    1004
    \n+
    1005 return norm;
    \n+
    1006 }
    \n+
    1007
    \n+
    1009 template <typename ft = field_type,
    \n+
    1010 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    1011 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    1012 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1013 using std::max;
    \n+
    1014
    \n+
    1015 real_type norm = 0;
    \n+
    1016 for (auto const &x : *this) {
    \n+
    1017 real_type sum = 0;
    \n+
    1018 for (auto const &y : x)
    \n+
    1019 sum += Impl::asMatrix(y).infinity_norm_real();
    \n+
    1020 norm = max(sum, norm);
    \n+
    1021 }
    \n+
    1022 return norm;
    \n+
    1023 }
    \n+
    1024
    \n+
    1026 template <typename ft = field_type,
    \n+
    1027 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    1028 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    1029 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1030 using std::max;
    \n+
    1031
    \n+
    1032 real_type norm = 0;
    \n+
    1033 real_type isNaN = 1;
    \n+
    1034 for (auto const &x : *this) {
    \n+
    1035 real_type sum = 0;
    \n+
    1036 for (auto const &y : x)
    \n+
    1037 sum += Impl::asMatrix(y).infinity_norm();
    \n+
    1038 norm = max(sum, norm);
    \n+
    1039 isNaN += sum;
    \n+
    1040 }
    \n+
    1041
    \n+
    1042 return norm * (isNaN / isNaN);
    \n+
    1043 }
    \n+
    1044
    \n+
    1046 template <typename ft = field_type,
    \n+
    1047 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    1048 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    1049 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1050 using std::max;
    \n+
    1051
    \n+
    1052 real_type norm = 0;
    \n+
    1053 real_type isNaN = 1;
    \n+
    1054 for (auto const &x : *this) {
    \n+
    1055 real_type sum = 0;
    \n+
    1056 for (auto const &y : x)
    \n+
    1057 sum += Impl::asMatrix(y).infinity_norm_real();
    \n+
    1058 norm = max(sum, norm);
    \n+
    1059 isNaN += sum;
    \n+
    1060 }
    \n+
    1061
    \n+
    1062 return norm * (isNaN / isNaN);
    \n+
    1063 }
    \n+
    1064
    \n+
    1065 //===== query
    \n+
    1066
    \n+
    1068 bool exists ([[maybe_unused]] size_type i, [[maybe_unused]] size_type j) const
    \n+
    1069 {
    \n+
    1070#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1071 if (i<0 || i>=N()) DUNE_THROW(ISTLError,"row index out of range");
    \n+
    1072 if (j<0 || i>=M()) DUNE_THROW(ISTLError,"column index out of range");
    \n+
    1073#endif
    \n+
    1074 return true;
    \n+
    1075 }
    \n+
    1076
    \n+
    1077 protected:
    \n+
    1078
    \n+\n+
    1082
    \n+\n+
    1089 };
    \n+
    1090
    \n+
    1091 template<class T, class A>
    \n+
    1092 struct FieldTraits< Matrix<T, A> >
    \n+
    1093 {
    \n+\n+
    1095 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    1096 };
    \n+
    1097
    \n+
    1099} // end namespace Dune
    \n+
    1100
    \n+
    1101#endif
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+
    Helper functions for determining the vector/matrix block level.
    \n
    Definition: allocator.hh:11
    \n-
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n-
    A Matrix class to support different block types.
    Definition: multitypeblockmatrix.hh:46
    \n-
    static void bsorb(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:461
    \n-
    static void bsorf(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:418
    \n-
    static void dbjac(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:504
    \n-
    static void dbgs(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:378
    \n-
    solver for MultiTypeBlockVector & MultiTypeBlockMatrix types
    Definition: multitypeblockmatrix.hh:477
    \n-
    part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types
    Definition: multitypeblockmatrix.hh:449
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    A Vector of blocks with different blocksizes.
    Definition: matrix.hh:44
    \n+
    Imp::BlockVectorWindow< B, A > window_type
    Definition: matrix.hh:70
    \n+
    BlockVector< B, A > block_type
    Same as value_type, here for historical reasons.
    Definition: matrix.hh:67
    \n+
    DenseMatrixBase & operator=(const DenseMatrixBase &a)
    assignment
    Definition: matrix.hh:182
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: matrix.hh:50
    \n+
    Iterator beforeBegin() const
    Definition: matrix.hh:385
    \n+
    void resize(size_type rows, size_type columns)
    same effect as constructor with same argument
    Definition: matrix.hh:153
    \n+
    const window_type const_reference
    Definition: matrix.hh:74
    \n+
    DenseMatrixBase(size_type rows, size_type columns)
    Definition: matrix.hh:95
    \n+
    Iterator end()
    end Iterator
    Definition: matrix.hh:371
    \n+
    reference operator[](size_type i)
    random access to blocks
    Definition: matrix.hh:241
    \n+
    BlockVector< B, A > value_type
    Type of the elements of the outer vector, i.e., dynamic vectors of B.
    Definition: matrix.hh:63
    \n+
    Iterator find(size_type i)
    random access returning iterator (end if not contained)
    Definition: matrix.hh:391
    \n+
    size_type N() const
    number of blocks in the vector (are of variable size here)
    Definition: matrix.hh:539
    \n+
    ConstIterator beforeEnd() const
    Definition: matrix.hh:525
    \n+
    ConstIterator end() const
    end ConstIterator
    Definition: matrix.hh:518
    \n+
    window_type reference
    Definition: matrix.hh:72
    \n+
    ConstIterator rend() const
    end ConstIterator
    Definition: matrix.hh:531
    \n+
    Iterator beforeEnd()
    Definition: matrix.hh:378
    \n+
    ConstIterator begin() const
    begin ConstIterator
    Definition: matrix.hh:512
    \n+
    A allocator_type
    export the allocator type
    Definition: matrix.hh:53
    \n+
    DenseMatrixBase()
    Definition: matrix.hh:82
    \n+
    ConstIterator find(size_type i) const
    random access returning iterator (end if not contained)
    Definition: matrix.hh:397
    \n+
    A::size_type size_type
    The size type for the index access.
    Definition: matrix.hh:56
    \n+
    ~DenseMatrixBase()
    free dynamic memory
    Definition: matrix.hh:142
    \n+
    Iterator begin()
    begin Iterator
    Definition: matrix.hh:365
    \n+
    DenseMatrixBase(const DenseMatrixBase &a)
    copy constructor, has copy semantics
    Definition: matrix.hh:116
    \n+
    Iterator class for sequential access.
    Definition: matrix.hh:263
    \n+
    Iterator & operator--()
    prefix decrement
    Definition: matrix.hh:308
    \n+
    size_type index() const
    Definition: matrix.hh:352
    \n+\n+\n+
    bool operator!=(const Iterator &it) const
    inequality
    Definition: matrix.hh:322
    \n+
    Iterator & operator=(Iterator &&other)
    Move assignment.
    Definition: matrix.hh:282
    \n+
    Iterator & operator++()
    prefix increment
    Definition: matrix.hh:300
    \n+
    Iterator()
    constructor, no arguments
    Definition: matrix.hh:266
    \n+
    window_type & operator*() const
    dereferencing
    Definition: matrix.hh:340
    \n+
    bool operator==(const Iterator &it) const
    equality
    Definition: matrix.hh:316
    \n+
    Iterator & operator=(Iterator &other)
    Copy assignment.
    Definition: matrix.hh:291
    \n+
    Iterator(B *data, size_type columns, size_type _i)
    constructor
    Definition: matrix.hh:276
    \n+
    window_type * operator->() const
    arrow
    Definition: matrix.hh:346
    \n+
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n+
    const window_type * operator->() const
    arrow
    Definition: matrix.hh:487
    \n+
    const window_type & operator*() const
    dereferencing
    Definition: matrix.hh:481
    \n+
    ConstIterator & operator++()
    prefix increment
    Definition: matrix.hh:441
    \n+
    ConstIterator(const B *data, size_type columns, size_type _i)
    constructor from pointer
    Definition: matrix.hh:414
    \n+
    ConstIterator & operator--()
    prefix decrement
    Definition: matrix.hh:449
    \n+
    ConstIterator(const Iterator &it)
    constructor from non_const iterator
    Definition: matrix.hh:420
    \n+
    bool operator!=(const ConstIterator &it) const
    inequality
    Definition: matrix.hh:463
    \n+
    ConstIterator()
    constructor
    Definition: matrix.hh:407
    \n+
    bool operator==(const ConstIterator &it) const
    equality
    Definition: matrix.hh:457
    \n+
    size_type index() const
    Definition: matrix.hh:493
    \n+
    ConstIterator & operator=(Iterator &&other)
    Definition: matrix.hh:424
    \n+
    ConstIterator & operator=(Iterator &other)
    Definition: matrix.hh:432
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    size_type cols_
    Number of columns of the matrix.
    Definition: matrix.hh:1088
    \n+
    FieldTraits< ft >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: matrix.hh:992
    \n+
    A allocator_type
    Export the allocator.
    Definition: matrix.hh:571
    \n+
    FieldTraits< ft >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: matrix.hh:1011
    \n+
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: matrix.hh:956
    \n+
    void usmv(const field_type &alpha, const X &x, Y &y) const
    Definition: matrix.hh:854
    \n+
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n+
    MatrixImp::DenseMatrixBase< T, A > data_
    Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.
    Definition: matrix.hh:1081
    \n+
    Matrix transpose() const
    Return the transpose of the matrix.
    Definition: matrix.hh:745
    \n+
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: matrix.hh:807
    \n+
    void umv(const X &x, Y &y) const
    y += A x
    Definition: matrix.hh:820
    \n+
    void mv(const X &x, Y &y) const
    y = A x
    Definition: matrix.hh:788
    \n+
    MatrixImp::DenseMatrixBase< T, A >::ConstIterator ConstRowIterator
    Const iterator over the matrix rows.
    Definition: matrix.hh:586
    \n+
    void setSize(size_type rows, size_type cols)
    Change the matrix size.
    Definition: matrix.hh:608
    \n+
    RowIterator beforeBegin()
    Definition: matrix.hh:634
    \n+
    RowIterator beforeEnd()
    Definition: matrix.hh:627
    \n+
    Matrix()
    Create empty matrix.
    Definition: matrix.hh:596
    \n+
    Matrix & operator-=(const Matrix &b)
    Subtract the entries of another matrix from this one.
    Definition: matrix.hh:735
    \n+
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: matrix.hh:980
    \n+
    row_type::iterator ColIterator
    Iterator for the entries of each row.
    Definition: matrix.hh:583
    \n+
    ConstRowIterator beforeEnd() const
    Definition: matrix.hh:653
    \n+
    Matrix & operator=(const field_type &t)
    Assignment from scalar.
    Definition: matrix.hh:666
    \n+
    RowIterator end()
    Get iterator to one beyond last row.
    Definition: matrix.hh:620
    \n+
    const row_type operator[](size_type row) const
    The const index operator.
    Definition: matrix.hh:684
    \n+
    ConstRowIterator end() const
    Get const iterator to one beyond last row.
    Definition: matrix.hh:646
    \n+
    friend Y operator*(const Matrix< T > &m, const X &vec)
    Generic matrix-vector multiplication.
    Definition: matrix.hh:770
    \n+
    Matrix< T > & operator*=(const field_type &scalar)
    Multiplication with a scalar.
    Definition: matrix.hh:705
    \n+
    row_type operator[](size_type row)
    The index operator.
    Definition: matrix.hh:673
    \n+
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: matrix.hh:837
    \n+
    Matrix & operator+=(const Matrix &b)
    Add the entries of another matrix to this one.
    Definition: matrix.hh:721
    \n+
    ConstRowIterator begin() const
    Get const iterator to first row.
    Definition: matrix.hh:640
    \n+
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: matrix.hh:939
    \n+
    RowIterator begin()
    Get iterator to first row.
    Definition: matrix.hh:614
    \n+
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n+
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    static constexpr auto blocklevel
    The number of nesting levels the matrix contains.
    Definition: matrix.hh:593
    \n+
    size_type M() const
    Return the number of columns.
    Definition: matrix.hh:700
    \n+
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n+
    bool exists(size_type i, size_type j) const
    return true if (i,j) is in pattern
    Definition: matrix.hh:1068
    \n+
    Matrix< T > & operator/=(const field_type &scalar)
    Division by a scalar.
    Definition: matrix.hh:711
    \n+
    friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)
    Generic matrix multiplication.
    Definition: matrix.hh:755
    \n+
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: matrix.hh:871
    \n+
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: matrix.hh:888
    \n+
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n+
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: matrix.hh:974
    \n+
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: matrix.hh:905
    \n+
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: matrix.hh:922
    \n+
    size_type N() const
    Return the number of rows.
    Definition: matrix.hh:695
    \n+
    ConstRowIterator beforeBegin() const
    Definition: matrix.hh:660
    \n+
    Matrix(size_type rows, size_type cols)
    Create uninitialized matrix of size rows x cols.
    Definition: matrix.hh:601
    \n+
    MatrixImp::DenseMatrixBase< T, A >::Iterator RowIterator
    Iterator over the matrix rows.
    Definition: matrix.hh:580
    \n+
    typename Matrix< T, A >::field_type field_type
    Definition: matrix.hh:1094
    \n+
    typename FieldTraits< field_type >::real_type real_type
    Definition: matrix.hh:1095
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,761 +4,1380 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-multitypeblockmatrix.hh\n+matrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH\n- 6#define DUNE_ISTL_MULTITYPEBLOCKMATRIX_HH\n+ 5#ifndef DUNE_ISTL_MATRIX_HH\n+ 6#define DUNE_ISTL_MATRIX_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11\n- 12#include \n- 13\n- 14#include \"istlexception.hh\"\n- 15\n- 16// forward declaration\n- 17namespace Dune\n- 18{\n- 19 template\n- 20 class MultiTypeBlockMatrix;\n- 21\n- 22 template\n- 23 class MultiTypeBlockMatrix_Solver;\n- 24}\n+ 12#include \n+ 13#include \n+ 14\n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19\n+ 20#include \n+ 21#include \n+ 22#include \n+ 23\n+ 24namespace Dune {\n 25\n- 26#include \"gsetc.hh\"\n- 27\n- 28namespace Dune {\n- 29\n- 43 template\n-44 class MultiTypeBlockMatrix\n- 45 : public std::tuple\n- 46 {\n- 47 using ParentType = std::tuple;\n- 48 public:\n- 49\n- 51 using ParentType::ParentType;\n- 52\n-56 typedef MultiTypeBlockMatrix type;\n+26namespace MatrixImp\n+ 27{\n+ 39 template >\n+40 class DenseMatrixBase : public Imp::block_vector_unmanaged\n+ 41 // this derivation gives us all the blas level 1 and norms\n+ 42 // on the large array. However, access operators have to be\n+ 43 // overwritten.\n+ 44 {\n+ 45 public:\n+ 46\n+ 47 //===== type definitions and constants\n+ 48\n+50 using field_type = typename Imp::BlockTraits::field_type;\n+ 51\n+53 typedef A allocator_type;\n+ 54\n+56 typedef typename A::size_type size_type;\n 57\n-59 using size_type = std::size_t;\n- 60\n-61 typedef typename FirstRow::field_type field_type;\n- 62\n-64 static constexpr size_type N()\n- 65 {\n- 66 return 1+sizeof...(Args);\n- 67 }\n+63 typedef BlockVector value_type;\n+ 64\n+67 typedef BlockVector block_type;\n 68\n- 74 [[deprecated(\"Use method 'N' instead\")]]\n-75 static constexpr size_type size()\n- 76 {\n- 77 return 1+sizeof...(Args);\n- 78 }\n- 79\n-81 static constexpr size_type M()\n- 82 {\n- 83 return FirstRow::size();\n- 84 }\n- 85\n- 102 template< size_type index >\n- 103 auto\n-104 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n-> indexVariable)\n- 105 -> decltype(std::get(*this))\n+ 69 // just a shorthand\n+70 typedef Imp::BlockVectorWindow window_type;\n+ 71\n+72 typedef window_type reference;\n+ 73\n+74 typedef const window_type const_reference;\n+ 75\n+ 76\n+ 77 //===== constructors and such\n+ 78\n+82 DenseMatrixBase () : Imp::block_vector_unmanaged()\n+ 83 {\n+ 84 // nothing is known ...\n+ 85 rows_ = 0;\n+ 86 columns_ = 0;\n+ 87 }\n+ 88\n+95 DenseMatrixBase (size_type rows, size_type columns) : Imp::\n+block_vector_unmanaged()\n+ 96 {\n+ 97 // and we can allocate the big array in the base class\n+ 98 this->n = rows*columns;\n+ 99 columns_ = columns;\n+ 100 if (this->n>0)\n+ 101 {\n+ 102 this->p = allocator_.allocate(this->n);\n+ 103 new (this->p)B[this->n];\n+ 104 }\n+ 105 else\n 106 {\n- 107 return std::get(*this);\n- 108 }\n- 109\n- 115 template< size_type index >\n- 116 auto\n-117 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n-> indexVariable) const\n- 118 -> decltype(std::get(*this))\n- 119 {\n- 120 return std::get(*this);\n- 121 }\n- 122\n- 126 template\n-127 void operator=(const T& newval) {\n- 128 using namespace Dune::Hybrid;\n- 129 auto size = index_constant<1+sizeof...(Args)>();\n- 130 // Since Dune::Hybrid::size(MultiTypeBlockMatrix) is not implemented,\n- 131 // we cannot use a plain forEach(*this, ...). This could be achieved,\n- 132 // e.g., by implementing a static size() method.\n- 133 forEach(integralRange(size), [&](auto&& i) {\n- 134 (*this)[i] = newval;\n- 135 });\n- 136 }\n- 137\n- 138 //===== vector space arithmetic\n- 139\n-141 MultiTypeBlockMatrix& operator*=(const field_type& k)\n- 142 {\n- 143 auto size = index_constant();\n- 144 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n- 145 (*this)[i] *= k;\n- 146 });\n- 147\n- 148 return *this;\n+ 107 this->n = 0;\n+ 108 this->p = 0;\n+ 109 }\n+ 110\n+ 111 // we can allocate the windows now\n+ 112 rows_ = rows;\n+ 113 }\n+ 114\n+116 DenseMatrixBase (const DenseMatrixBase& a)\n+ 117 {\n+ 118 // allocate the big array in the base class\n+ 119 this->n = a.n;\n+ 120 columns_ = a.columns_;\n+ 121 if (this->n>0)\n+ 122 {\n+ 123 // allocate and construct objects\n+ 124 this->p = allocator_.allocate(this->n);\n+ 125 new (this->p)B[this->n];\n+ 126\n+ 127 // copy data\n+ 128 for (size_type i=0; in; i++)\n+ 129 this->p[i]=a.p[i];\n+ 130 }\n+ 131 else\n+ 132 {\n+ 133 this->n = 0;\n+ 134 this->p = nullptr;\n+ 135 }\n+ 136\n+ 137 // we can allocate the windows now\n+ 138 rows_ = a.rows_;\n+ 139 }\n+ 140\n+142 ~DenseMatrixBase ()\n+ 143 {\n+ 144 if (this->n>0) {\n+ 145 size_type i=this->n;\n+ 146 while (i)\n+ 147 this->p[--i].~B();\n+ 148 allocator_.deallocate(this->p,this->n);\n 149 }\n- 150\n-152 MultiTypeBlockMatrix& operator/=(const field_type& k)\n- 153 {\n- 154 auto size = index_constant();\n- 155 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n- 156 (*this)[i] /= k;\n- 157 });\n- 158\n- 159 return *this;\n- 160 }\n- 161\n+ 150 }\n+ 151\n+153 void resize (size_type rows, size_type columns)\n+ 154 {\n+ 155 // deconstruct objects and deallocate memory if necessary\n+ 156 if (this->n>0) {\n+ 157 size_type i=this->n;\n+ 158 while (i)\n+ 159 this->p[--i].~B();\n+ 160 allocator_.deallocate(this->p,this->n);\n+ 161 }\n 162\n-168 MultiTypeBlockMatrix& operator+=(const MultiTypeBlockMatrix& b)\n- 169 {\n- 170 auto size = index_constant();\n- 171 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n- 172 (*this)[i] += b[i];\n- 173 });\n- 174\n- 175 return *this;\n- 176 }\n- 177\n-183 MultiTypeBlockMatrix& operator-=(const MultiTypeBlockMatrix& b)\n- 184 {\n- 185 auto size = index_constant();\n- 186 Hybrid::forEach(Hybrid::integralRange(size), [&](auto&& i) {\n- 187 (*this)[i] -= b[i];\n- 188 });\n- 189\n- 190 return *this;\n- 191 }\n- 192\n- 195 template\n-196 void mv (const X& x, Y& y) const {\n- 197 static_assert(X::size() == M(), \"length of x does not match row length\");\n- 198 static_assert(Y::size() == N(), \"length of y does not match row count\");\n- 199 y = 0; //reset y (for mv uses umv)\n- 200 umv(x,y);\n- 201 }\n- 202\n- 205 template\n-206 void umv (const X& x, Y& y) const {\n- 207 static_assert(X::size() == M(), \"length of x does not match row length\");\n- 208 static_assert(Y::size() == N(), \"length of y does not match row count\");\n- 209 using namespace Dune::Hybrid;\n- 210 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 211 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 212 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 213 (*this)[i][j].umv(x[j], y[i]);\n- 214 });\n- 215 });\n- 216 }\n- 217\n- 220 template\n-221 void mmv (const X& x, Y& y) const {\n- 222 static_assert(X::size() == M(), \"length of x does not match row length\");\n- 223 static_assert(Y::size() == N(), \"length of y does not match row count\");\n- 224 using namespace Dune::Hybrid;\n- 225 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 226 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 227 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 228 (*this)[i][j].mmv(x[j], y[i]);\n- 229 });\n- 230 });\n- 231 }\n- 232\n- 235 template\n-236 void usmv (const AlphaType& alpha, const X& x, Y& y) const {\n- 237 static_assert(X::size() == M(), \"length of x does not match row length\");\n- 238 static_assert(Y::size() == N(), \"length of y does not match row count\");\n- 239 using namespace Dune::Hybrid;\n- 240 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 241 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 242 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 243 (*this)[i][j].usmv(alpha, x[j], y[i]);\n- 244 });\n- 245 });\n- 246 }\n- 247\n- 250 template\n-251 void mtv (const X& x, Y& y) const {\n- 252 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 253 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 254 y = 0;\n- 255 umtv(x,y);\n+ 163 // and we can allocate the big array in the base class\n+ 164 this->n = rows*columns;\n+ 165 if (this->n>0)\n+ 166 {\n+ 167 this->p = allocator_.allocate(this->n);\n+ 168 new (this->p)B[this->n];\n+ 169 }\n+ 170 else\n+ 171 {\n+ 172 this->n = 0;\n+ 173 this->p = nullptr;\n+ 174 }\n+ 175\n+ 176 // we can allocate the windows now\n+ 177 rows_ = rows;\n+ 178 columns_ = columns;\n+ 179 }\n+ 180\n+182 DenseMatrixBase& operator=(const DenseMatrixBase& a)\n+ 183 {\n+ 184 if (&a!=this) // check if this and a are different objects\n+ 185 {\n+ 186 columns_ = a.columns_;\n+ 187 // reallocate arrays if necessary\n+ 188 // Note: still the block sizes may vary !\n+ 189 if (this->n!=a.n || rows_!=a.rows_)\n+ 190 {\n+ 191 // deconstruct objects and deallocate memory if necessary\n+ 192 if (this->n>0) {\n+ 193 size_type i=this->n;\n+ 194 while (i)\n+ 195 this->p[--i].~B();\n+ 196 allocator_.deallocate(this->p,this->n);\n+ 197 }\n+ 198\n+ 199 // allocate the big array in the base class\n+ 200 this->n = a.n;\n+ 201 if (this->n>0)\n+ 202 {\n+ 203 // allocate and construct objects\n+ 204 this->p = allocator_.allocate(this->n);\n+ 205 new (this->p)B[this->n];\n+ 206 }\n+ 207 else\n+ 208 {\n+ 209 this->n = 0;\n+ 210 this->p = nullptr;\n+ 211 }\n+ 212\n+ 213 // Copy number of rows\n+ 214 rows_ = a.rows_;\n+ 215 }\n+ 216\n+ 217 // and copy the data\n+ 218 for (size_type i=0; in; i++)\n+ 219 this->p[i]=a.p[i];\n+ 220 }\n+ 221\n+ 222 return *this;\n+ 223 }\n+ 224\n+ 225\n+ 226 //===== assignment from scalar\n+ 227\n+229 DenseMatrixBase& operator=(const field_type& k)\n+ 230 {\n+ 231 (static_cast&>(*this)) = k;\n+ 232 return *this;\n+ 233 }\n+ 234\n+ 235\n+ 236 //===== access to components\n+ 237 // has to be overwritten from base class because it must\n+ 238 // return access to the windows\n+ 239\n+241 reference operator[](size_type i)\n+ 242 {\n+ 243#ifdef DUNE_ISTL_WITH_CHECKING\n+ 244 if (i>=rows_) DUNE_THROW(ISTLError,\"index out of range\");\n+ 245#endif\n+ 246 return window_type(this->p + i*columns_, columns_);\n+ 247 }\n+ 248\n+250 const_reference operator[](size_type i) const\n+ 251 {\n+ 252#ifdef DUNE_ISTL_WITH_CHECKING\n+ 253 if (i<0 || i>=rows_) DUNE_THROW(ISTLError,\"index out of range\");\n+ 254#endif\n+ 255 return window_type(this->p + i*columns_, columns_);\n 256 }\n 257\n- 260 template\n-261 void umtv (const X& x, Y& y) const {\n- 262 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 263 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 264 using namespace Dune::Hybrid;\n- 265 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 266 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 267 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 268 (*this)[j][i].umtv(x[j], y[i]);\n- 269 });\n- 270 });\n- 271 }\n- 272\n- 275 template\n-276 void mmtv (const X& x, Y& y) const {\n- 277 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 278 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 279 using namespace Dune::Hybrid;\n- 280 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 281 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 282 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 283 (*this)[j][i].mmtv(x[j], y[i]);\n- 284 });\n- 285 });\n- 286 }\n- 287\n- 290 template\n-291 void usmtv (const field_type& alpha, const X& x, Y& y) const {\n- 292 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 293 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 294 using namespace Dune::Hybrid;\n- 295 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 296 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 297 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 298 (*this)[j][i].usmtv(alpha, x[j], y[i]);\n- 299 });\n- 300 });\n- 301 }\n- 302\n- 305 template\n-306 void umhv (const X& x, Y& y) const {\n- 307 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 308 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 309 using namespace Dune::Hybrid;\n- 310 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 311 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 312 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 313 (*this)[j][i].umhv(x[j], y[i]);\n- 314 });\n- 315 });\n- 316 }\n- 317\n- 320 template\n-321 void mmhv (const X& x, Y& y) const {\n- 322 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 323 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 324 using namespace Dune::Hybrid;\n- 325 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 326 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 327 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 328 (*this)[j][i].mmhv(x[j], y[i]);\n- 329 });\n- 330 });\n+ 258 // forward declaration\n+ 259 class ConstIterator;\n+ 260\n+262 class Iterator\n+ 263 {\n+ 264 public:\n+266 Iterator ()\n+ 267 : window_(nullptr,0)\n+ 268 {\n+ 269 i = 0;\n+ 270 }\n+ 271\n+272 Iterator (Iterator& other) = default;\n+273 Iterator (Iterator&& other) = default;\n+ 274\n+276 Iterator (B* data, size_type columns, size_type _i)\n+ 277 : i(_i),\n+ 278 window_(data + _i*columns, columns)\n+ 279 {}\n+ 280\n+282 Iterator& operator=(Iterator&& other)\n+ 283 {\n+ 284 i = other.i;\n+ 285 // Do NOT use window_.operator=, because that copies the window content,\n+not just the window!\n+ 286 window_.set(other.window_.getsize(),other.window_.getptr());\n+ 287 return *this;\n+ 288 }\n+ 289\n+291 Iterator& operator=(Iterator& other)\n+ 292 {\n+ 293 i = other.i;\n+ 294 // Do NOT use window_.operator=, because that copies the window content,\n+not just the window!\n+ 295 window_.set(other.window_.getsize(),other.window_.getptr());\n+ 296 return *this;\n+ 297 }\n+ 298\n+300 Iterator& operator++()\n+ 301 {\n+ 302 ++i;\n+ 303 window_.setptr(window_.getptr()+window_.getsize());\n+ 304 return *this;\n+ 305 }\n+ 306\n+308 Iterator& operator--()\n+ 309 {\n+ 310 --i;\n+ 311 window_.setptr(window_.getptr()-window_.getsize());\n+ 312 return *this;\n+ 313 }\n+ 314\n+316 bool operator==(const Iterator& it) const\n+ 317 {\n+ 318 return window_.getptr() == it.window_.getptr();\n+ 319 }\n+ 320\n+322 bool operator!=(const Iterator& it) const\n+ 323 {\n+ 324 return window_.getptr() != it.window_.getptr();\n+ 325 }\n+ 326\n+328 bool operator==(const ConstIterator& it) const\n+ 329 {\n+ 330 return window_.getptr() == it.window_.getptr();\n 331 }\n 332\n- 335 template\n-336 void usmhv (const field_type& alpha, const X& x, Y& y) const {\n- 337 static_assert(X::size() == N(), \"length of x does not match number of\n-rows\");\n- 338 static_assert(Y::size() == M(), \"length of y does not match number of\n-columns\");\n- 339 using namespace Dune::Hybrid;\n- 340 forEach(integralRange(Hybrid::size(y)), [&](auto&& i) {\n- 341 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 342 forEach(integralRange(Hybrid::size(x)), [&](auto&& j) {\n- 343 (*this)[j][i].usmhv(alpha, x[j], y[i]);\n- 344 });\n- 345 });\n- 346 }\n- 347\n- 348\n- 349 //===== norms\n+334 bool operator!=(const ConstIterator& it) const\n+ 335 {\n+ 336 return window_.getptr() != it.window_.getptr();\n+ 337 }\n+ 338\n+340 window_type& operator*() const\n+ 341 {\n+ 342 return window_;\n+ 343 }\n+ 344\n+346 window_type* operator->() const\n+ 347 {\n+ 348 return &window_;\n+ 349 }\n 350\n-352 auto frobenius_norm2 () const\n+ 351 // return index corresponding to pointer\n+352 size_type index () const\n 353 {\n- 354 using field_type_00 = typename std::decay_t::field_type;\n- 355 typename FieldTraits::real_type sum=0;\n+ 354 return i;\n+ 355 }\n 356\n- 357 auto rows = index_constant();\n- 358 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n- 359 auto cols = index_constant::M()>\n-();\n- 360 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n- 361 sum += (*this)[i][j].frobenius_norm2();\n- 362 });\n- 363 });\n- 364\n- 365 return sum;\n- 366 }\n- 367\n-369 typename FieldTraits::real_type frobenius_norm () const\n- 370 {\n- 371 return sqrt(frobenius_norm2());\n- 372 }\n- 373\n-375 auto infinity_norm () const\n- 376 {\n- 377 using field_type_00 = typename std::decay_t::field_type;\n- 378 using std::max;\n- 379 typename FieldTraits::real_type norm=0;\n- 380\n- 381 auto rows = index_constant();\n- 382 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n- 383\n- 384 typename FieldTraits::real_type sum=0;\n- 385 auto cols = index_constant::M()>\n-();\n- 386 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n- 387 sum += (*this)[i][j].infinity_norm();\n- 388 });\n- 389 norm = max(sum, norm);\n- 390 });\n- 391\n- 392 return norm;\n- 393 }\n- 394\n-396 auto infinity_norm_real () const\n- 397 {\n- 398 using field_type_00 = typename std::decay_t::field_type;\n- 399 using std::max;\n- 400 typename FieldTraits::real_type norm=0;\n+357 friend class ConstIterator;\n+ 358\n+ 359 private:\n+ 360 size_type i;\n+ 361 mutable window_type window_;\n+ 362 };\n+ 363\n+365 Iterator begin ()\n+ 366 {\n+ 367 return Iterator(this->p, columns_, 0);\n+ 368 }\n+ 369\n+371 Iterator end ()\n+ 372 {\n+ 373 return Iterator(this->p, columns_, rows_);\n+ 374 }\n+ 375\n+378 Iterator beforeEnd ()\n+ 379 {\n+ 380 return Iterator(this->p, columns_, rows_-1);\n+ 381 }\n+ 382\n+385 Iterator beforeBegin () const\n+ 386 {\n+ 387 return Iterator(this->p, columns_, -1);\n+ 388 }\n+ 389\n+391 Iterator find (size_type i)\n+ 392 {\n+ 393 return Iterator(this->p, columns_, std::min(i,rows_));\n+ 394 }\n+ 395\n+397 ConstIterator find (size_type i) const\n+ 398 {\n+ 399 return ConstIterator(this->p, columns_, std::min(i,rows_));\n+ 400 }\n 401\n- 402 auto rows = index_constant();\n- 403 Hybrid::forEach(Hybrid::integralRange(rows), [&](auto&& i) {\n- 404\n- 405 typename FieldTraits::real_type sum=0;\n- 406 auto cols = index_constant::M()>\n-();\n- 407 Hybrid::forEach(Hybrid::integralRange(cols), [&](auto&& j) {\n- 408 sum += (*this)[i][j].infinity_norm_real();\n- 409 });\n- 410 norm = max(sum, norm);\n- 411 });\n+403 class ConstIterator\n+ 404 {\n+ 405 public:\n+407 ConstIterator ()\n+ 408 : window_(nullptr,0)\n+ 409 {\n+ 410 i = 0;\n+ 411 }\n 412\n- 413 return norm;\n- 414 }\n- 415\n- 416 };\n- 417\n- 423 template\n-424 std::ostream& operator<<(std::ostream& s, const\n-MultiTypeBlockMatrix& m) {\n- 425 auto N = index_constant::N()>();\n- 426 auto M = index_constant::M()>();\n- 427 using namespace Dune::Hybrid;\n- 428 forEach(integralRange(N), [&](auto&& i) {\n- 429 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 430 forEach(integralRange(M), [&](auto&& j) {\n- 431 s << \"\\t(\" << i << \", \" << j << \"): \\n\" << m[i][j];\n- 432 });\n- 433 });\n- 434 s << std::endl;\n- 435 return s;\n- 436 }\n- 437\n- 438 //make algmeta_itsteps known\n- 439 template\n- 440 struct algmeta_itsteps;\n- 441\n- 448 template //\n-MultiTypeBlockMatrix_Solver_Col: iterating over one row\n-449 class MultiTypeBlockMatrix_Solver_Col { //calculating b- A[i][j]*x[j]\n- 450 public:\n- 454 template \n-455 static void calc_rhs(const TMatrix& A, TVector& x, TVector& v, Trhs& b,\n-const K& w) {\n- 456 std::get( std::get(A) ).mmv( std::get(x), b );\n- 457 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-(A,x,v,b,w); //next column element\n- 458 }\n- 459\n- 460 };\n- 461 template //MultiTypeBlockMatrix_Solver_Col\n-recursion end\n-462 class MultiTypeBlockMatrix_Solver_Col {\n- 463 public:\n- 464 template \n-465 static void calc_rhs(const TMatrix&, TVector&, TVector&, Trhs&, const K&)\n-{}\n- 466 };\n+414 ConstIterator (const B* data, size_type columns, size_type _i)\n+ 415 : i(_i),\n+ 416 window_(const_cast(data + _i * columns), columns)\n+ 417 {}\n+ 418\n+420 ConstIterator (const Iterator& it)\n+ 421 : i(it.i), window_(it.window_.getptr(),it.window_.getsize())\n+ 422 {}\n+ 423\n+424 ConstIterator& operator=(Iterator&& other)\n+ 425 {\n+ 426 i = other.i;\n+ 427 // Do NOT use window_.operator=, because that copies the window content,\n+not just the window!\n+ 428 window_.set(other.window_.getsize(),other.window_.getptr());\n+ 429 return *this;\n+ 430 }\n+ 431\n+432 ConstIterator& operator=(Iterator& other)\n+ 433 {\n+ 434 i = other.i;\n+ 435 // Do NOT use window_.operator=, because that copies the window content,\n+not just the window!\n+ 436 window_.set(other.window_.getsize(),other.window_.getptr());\n+ 437 return *this;\n+ 438 }\n+ 439\n+441 ConstIterator& operator++()\n+ 442 {\n+ 443 ++i;\n+ 444 window_.setptr(window_.getptr()+window_.getsize());\n+ 445 return *this;\n+ 446 }\n+ 447\n+449 ConstIterator& operator--()\n+ 450 {\n+ 451 --i;\n+ 452 window_.setptr(window_.getptr()-window_.getsize());\n+ 453 return *this;\n+ 454 }\n+ 455\n+457 bool operator==(const ConstIterator& it) const\n+ 458 {\n+ 459 return window_.getptr() == it.window_.getptr();\n+ 460 }\n+ 461\n+463 bool operator!=(const ConstIterator& it) const\n+ 464 {\n+ 465 return window_.getptr() != it.window_.getptr();\n+ 466 }\n 467\n- 468\n- 469\n- 476 template\n-477 class MultiTypeBlockMatrix_Solver {\n- 478 public:\n+469 bool operator==(const Iterator& it) const\n+ 470 {\n+ 471 return window_.getptr() == it.window_.getptr();\n+ 472 }\n+ 473\n+475 bool operator!=(const Iterator& it) const\n+ 476 {\n+ 477 return window_.getptr() != it.window_.getptr();\n+ 478 }\n 479\n- 483 template \n-484 static void dbgs(const TMatrix& A, TVector& x, const TVector& b, const K&\n-w) {\n- 485 TVector xold(x);\n- 486 xold=x; //store old x values\n- 487 MultiTypeBlockMatrix_Solver::dbgs(A,x,x,b,w);\n- 488 x *= w;\n- 489 x.axpy(1-w,xold); //improve x\n+481 const window_type& operator*() const\n+ 482 {\n+ 483 return window_;\n+ 484 }\n+ 485\n+487 const window_type* operator->() const\n+ 488 {\n+ 489 return &window_;\n 490 }\n- 491 template \n-492 static void dbgs(const TMatrix& A, TVector& x, TVector& v, const TVector&\n-b, const K& w) {\n- 493 auto rhs = std::get (b);\n- 494\n- 495 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-(A,x,v,rhs,w); // calculate right side of equation\n- 496 //solve on blocklevel I-1\n- 497 using M =\n- 498 typename std::remove_cv<\n- 499 typename std::remove_reference<\n- 500 decltype(std::get( std::get(A)))\n- 501 >::type\n- 502 >::type;\n- 503 algmeta_itsteps::dbgs(std::get( std::get(A)), std::\n-get(x),rhs,w);\n- 504 MultiTypeBlockMatrix_Solver::dbgs(A,x,v,b,w); //\n-next row\n- 505 }\n- 506\n+ 491\n+ 492 // return index corresponding to pointer\n+493 size_type index () const\n+ 494 {\n+ 495 return i;\n+ 496 }\n+ 497\n+498 friend class Iterator;\n+ 499\n+ 500 private:\n+ 501 size_type i;\n+ 502 mutable window_type window_;\n+ 503 };\n+ 504\n+506 using iterator = Iterator;\n 507\n- 508\n- 512 template \n-513 static void bsorf(const TMatrix& A, TVector& x, const TVector& b, const K&\n-w) {\n- 514 TVector v;\n- 515 v=x; //use latest x values in right side calculation\n- 516 MultiTypeBlockMatrix_Solver::bsorf(A,x,v,b,w);\n- 517\n- 518 }\n- 519 template //recursion over\n-all matrix rows (A)\n-520 static void bsorf(const TMatrix& A, TVector& x, TVector& v, const TVector&\n-b, const K& w) {\n- 521 auto rhs = std::get (b);\n+509 using const_iterator = ConstIterator;\n+ 510\n+512 ConstIterator begin () const\n+ 513 {\n+ 514 return ConstIterator(this->p, columns_, 0);\n+ 515 }\n+ 516\n+518 ConstIterator end () const\n+ 519 {\n+ 520 return ConstIterator(this->p, columns_, rows_);\n+ 521 }\n 522\n- 523 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-(A,x,v,rhs,w); // calculate right side of equation\n- 524 //solve on blocklevel I-1\n- 525 using M =\n- 526 typename std::remove_cv<\n- 527 typename std::remove_reference<\n- 528 decltype(std::get( std::get(A)))\n- 529 >::type\n- 530 >::type;\n- 531 algmeta_itsteps::bsorf(std::get( std::get(A)), std::\n-get(v),rhs,w);\n- 532 std::get(x).axpy(w,std::get(v));\n- 533 MultiTypeBlockMatrix_Solver::bsorf(A,x,v,b,w); //\n-next row\n+525 ConstIterator beforeEnd() const\n+ 526 {\n+ 527 return ConstIterator(this->p, columns_, rows_-1);\n+ 528 }\n+ 529\n+531 ConstIterator rend () const\n+ 532 {\n+ 533 return ConstIterator(this->p, columns_, -1);\n 534 }\n 535\n- 539 template \n-540 static void bsorb(const TMatrix& A, TVector& x, const TVector& b, const K&\n-w) {\n- 541 TVector v;\n- 542 v=x; //use latest x values in right side calculation\n- 543 MultiTypeBlockMatrix_Solver::bsorb(A,x,v,b,w);\n+ 536 //===== sizes\n+ 537\n+539 size_type N () const\n+ 540 {\n+ 541 return rows_;\n+ 542 }\n+ 543\n 544\n- 545 }\n- 546 template //recursion over\n-all matrix rows (A)\n-547 static void bsorb(const TMatrix& A, TVector& x, TVector& v, const TVector&\n-b, const K& w) {\n- 548 auto rhs = std::get (b);\n- 549\n- 550 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-(A,x,v,rhs,w); // calculate right side of equation\n- 551 //solve on blocklevel I-1\n- 552 using M =\n- 553 typename std::remove_cv<\n- 554 typename std::remove_reference<\n- 555 decltype(std::get( std::get(A)))\n- 556 >::type\n- 557 >::type;\n- 558 algmeta_itsteps::bsorb(std::get( std::get(A)), std::\n-get(v),rhs,w);\n- 559 std::get(x).axpy(w,std::get(v));\n- 560 MultiTypeBlockMatrix_Solver::bsorb(A,x,v,b,w); //\n-next row\n- 561 }\n- 562\n+ 545 private:\n+ 546 size_type rows_; // number of matrix rows\n+ 547 size_type columns_; // number of matrix columns\n+ 548\n+ 549 A allocator_;\n+ 550 };\n+ 551\n+ 552} // namespace MatrixImp\n+ 553\n+ 559 template >\n+560 class Matrix\n+ 561 {\n+ 562 public:\n 563\n- 567 template \n-568 static void dbjac(const TMatrix& A, TVector& x, const TVector& b, const K&\n-w) {\n- 569 TVector v(x);\n- 570 v=0; //calc new x in v\n- 571 MultiTypeBlockMatrix_Solver::dbjac(A,x,v,b,w);\n- 572 x.axpy(w,v); //improve x\n- 573 }\n- 574 template \n-575 static void dbjac(const TMatrix& A, TVector& x, TVector& v, const TVector&\n-b, const K& w) {\n- 576 auto rhs = std::get (b);\n- 577\n- 578 MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-(A,x,v,rhs,w); // calculate right side of equation\n- 579 //solve on blocklevel I-1\n- 580 using M =\n- 581 typename std::remove_cv<\n- 582 typename std::remove_reference<\n- 583 decltype(std::get( std::get(A)))\n- 584 >::type\n- 585 >::type;\n- 586 algmeta_itsteps::dbjac(std::get( std::get(A)), std::\n-get(v),rhs,w);\n- 587 MultiTypeBlockMatrix_Solver::dbjac(A,x,v,b,w); //\n-next row\n- 588 }\n- 589\n+565 using field_type = typename Imp::BlockTraits::field_type;\n+ 566\n+568 typedef T block_type;\n+ 569\n+571 typedef A allocator_type;\n+ 572\n+574 typedef typename MatrixImp::DenseMatrixBase::window_type row_type;\n+ 575\n+577 typedef typename A::size_type size_type;\n+ 578\n+580 typedef typename MatrixImp::DenseMatrixBase::Iterator RowIterator;\n+ 581\n+583 typedef typename row_type::iterator ColIterator;\n+ 584\n+586 typedef typename MatrixImp::DenseMatrixBase::ConstIterator\n+ConstRowIterator;\n+ 587\n+589 typedef typename row_type::const_iterator ConstColIterator;\n 590\n- 591\n- 592\n- 593 };\n- 594 template //recursion end for remain_row = 0\n-595 class MultiTypeBlockMatrix_Solver {\n- 596 public:\n- 597 template \n-598 static void dbgs(const TMatrix&, TVector&, TVector&,\n- 599 const TVector&, const K&) {}\n- 600\n- 601 template \n-602 static void bsorf(const TMatrix&, TVector&, TVector&,\n- 603 const TVector&, const K&) {}\n- 604\n- 605 template \n-606 static void bsorb(const TMatrix&, TVector&, TVector&,\n- 607 const TVector&, const K&) {}\n- 608\n- 609 template \n-610 static void dbjac(const TMatrix&, TVector&, TVector&,\n- 611 const TVector&, const K&) {}\n- 612 };\n- 613\n- 614} // end namespace Dune\n- 615\n- 616namespace std\n- 617{\n- 622 template \n-623 struct tuple_element >\n- 624 {\n-625 using type = typename std::tuple_element >::type;\n- 626 };\n- 627}\n- 628#endif\n+ 592 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+593 static constexpr auto blocklevel = blockLevel()+1;\n+ 594\n+596 Matrix() : data_(0,0), cols_(0)\n+ 597 {}\n+ 598\n+601 Matrix(size_type rows, size_type cols) : data_(rows,cols), cols_(cols)\n+ 602 {}\n+ 603\n+608 void setSize(size_type rows, size_type cols) {\n+ 609 data_.resize(rows,cols);\n+ 610 cols_ = cols;\n+ 611 }\n+ 612\n+614 RowIterator begin()\n+ 615 {\n+ 616 return data_.begin();\n+ 617 }\n+ 618\n+620 RowIterator end()\n+ 621 {\n+ 622 return data_.end();\n+ 623 }\n+ 624\n+627 RowIterator beforeEnd ()\n+ 628 {\n+ 629 return data_.beforeEnd();\n+ 630 }\n+ 631\n+634 RowIterator beforeBegin ()\n+ 635 {\n+ 636 return data_.beforeBegin();\n+ 637 }\n+ 638\n+640 ConstRowIterator begin() const\n+ 641 {\n+ 642 return data_.begin();\n+ 643 }\n+ 644\n+646 ConstRowIterator end() const\n+ 647 {\n+ 648 return data_.end();\n+ 649 }\n+ 650\n+653 ConstRowIterator beforeEnd() const\n+ 654 {\n+ 655 return data_.beforeEnd();\n+ 656 }\n+ 657\n+660 ConstRowIterator beforeBegin () const\n+ 661 {\n+ 662 return data_.beforeBegin();\n+ 663 }\n+ 664\n+666 Matrix& operator=(const field_type& t)\n+ 667 {\n+ 668 data_ = t;\n+ 669 return *this;\n+ 670 }\n+ 671\n+673 row_type operator[](size_type row) {\n+ 674#ifdef DUNE_ISTL_WITH_CHECKING\n+ 675 if (row<0)\n+ 676 DUNE_THROW(ISTLError, \"Can't access negative rows!\");\n+ 677 if (row>=N())\n+ 678 DUNE_THROW(ISTLError, \"Row index out of range!\");\n+ 679#endif\n+ 680 return data_[row];\n+ 681 }\n+ 682\n+684 const row_type operator[](size_type row) const {\n+ 685#ifdef DUNE_ISTL_WITH_CHECKING\n+ 686 if (row<0)\n+ 687 DUNE_THROW(ISTLError, \"Can't access negative rows!\");\n+ 688 if (row>=N())\n+ 689 DUNE_THROW(ISTLError, \"Row index out of range!\");\n+ 690#endif\n+ 691 return data_[row];\n+ 692 }\n+ 693\n+695 size_type N() const {\n+ 696 return data_.N();\n+ 697 }\n+ 698\n+700 size_type M() const {\n+ 701 return cols_;\n+ 702 }\n+ 703\n+705 Matrix& operator*=(const field_type& scalar) {\n+ 706 data_ *= scalar;\n+ 707 return (*this);\n+ 708 }\n+ 709\n+711 Matrix& operator/=(const field_type& scalar) {\n+ 712 data_ /= scalar;\n+ 713 return (*this);\n+ 714 }\n+ 715\n+721 Matrix& operator+=(const Matrix& b) {\n+ 722#ifdef DUNE_ISTL_WITH_CHECKING\n+ 723 if(N()!=b.N() || M() != b.M())\n+ 724 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n+ 725#endif\n+ 726 data_ += b.data_;\n+ 727 return (*this);\n+ 728 }\n+ 729\n+735 Matrix& operator-=(const Matrix& b) {\n+ 736#ifdef DUNE_ISTL_WITH_CHECKING\n+ 737 if(N()!=b.N() || M() != b.M())\n+ 738 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n+ 739#endif\n+ 740 data_ -= b.data_;\n+ 741 return (*this);\n+ 742 }\n+ 743\n+745 Matrix transpose() const {\n+ 746 Matrix out(M(), N());\n+ 747 for (size_type i=0; i operator*(const Matrix& m1, const Matrix& m2) {\n+ 756 Matrix out(m1.N(), m2.M());\n+ 757 out = 0;\n+ 758\n+ 759 for (size_type i=0; i\n+770 friend Y operator*(const Matrix& m, const X& vec) {\n+ 771#ifdef DUNE_ISTL_WITH_CHECKING\n+ 772 if (m.M()!=vec.size())\n+ 773 DUNE_THROW(ISTLError, \"Vector size doesn't match the number of matrix\n+columns!\");\n+ 774#endif\n+ 775 Y out(m.N());\n+ 776 out = 0;\n+ 777\n+ 778 for (size_type i=0; i\n+788 void mv(const X& x, Y& y) const\n+ 789 {\n+ 790#ifdef DUNE_ISTL_WITH_CHECKING\n+ 791 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 792 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 793#endif\n+ 794 for (size_type i=0; i\n+807 void mtv (const X& x, Y& y) const\n+ 808 {\n+ 809#ifdef DUNE_ISTL_WITH_CHECKING\n+ 810 if (x.N()!=N()) DUNE_THROW(ISTLError,\"index out of range\");\n+ 811 if (y.N()!=M()) DUNE_THROW(ISTLError,\"index out of range\");\n+ 812#endif\n+ 813 for(size_type i=0; i\n+820 void umv(const X& x, Y& y) const\n+ 821 {\n+ 822#ifdef DUNE_ISTL_WITH_CHECKING\n+ 823 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 824 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 825#endif\n+ 826 for (size_type i=0; i\n+837 void mmv (const X& x, Y& y) const\n+ 838 {\n+ 839#ifdef DUNE_ISTL_WITH_CHECKING\n+ 840 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 841 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 842#endif\n+ 843 for (size_type i=0; i\n+854 void usmv(const field_type& alpha, const X& x, Y& y) const\n+ 855 {\n+ 856#ifdef DUNE_ISTL_WITH_CHECKING\n+ 857 if (x.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 858 if (y.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 859#endif\n+ 860 for (size_type i=0; i\n+871 void umtv (const X& x, Y& y) const\n+ 872 {\n+ 873#ifdef DUNE_ISTL_WITH_CHECKING\n+ 874 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 875 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 876#endif\n+ 877 for (size_type i=0; i\n+888 void mmtv (const X& x, Y& y) const\n+ 889 {\n+ 890#ifdef DUNE_ISTL_WITH_CHECKING\n+ 891 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 892 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 893#endif\n+ 894 for (size_type i=0; i\n+905 void usmtv (const field_type& alpha, const X& x, Y& y) const\n+ 906 {\n+ 907#ifdef DUNE_ISTL_WITH_CHECKING\n+ 908 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 909 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 910#endif\n+ 911 for (size_type i=0; i\n+922 void umhv (const X& x, Y& y) const\n+ 923 {\n+ 924#ifdef DUNE_ISTL_WITH_CHECKING\n+ 925 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 926 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 927#endif\n+ 928 for (size_type i=0; i\n+939 void mmhv (const X& x, Y& y) const\n+ 940 {\n+ 941#ifdef DUNE_ISTL_WITH_CHECKING\n+ 942 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 943 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 944#endif\n+ 945 for (size_type i=0; i\n+956 void usmhv (const field_type& alpha, const X& x, Y& y) const\n+ 957 {\n+ 958#ifdef DUNE_ISTL_WITH_CHECKING\n+ 959 if (x.N()!=N()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 960 if (y.N()!=M()) DUNE_THROW(ISTLError,\"vector/matrix size mismatch!\");\n+ 961#endif\n+ 962 for (size_type i=0; i::real_type frobenius_norm () const\n+ 975 {\n+ 976 return std::sqrt(frobenius_norm2());\n+ 977 }\n+ 978\n+980 typename FieldTraits::real_type frobenius_norm2 () const\n+ 981 {\n+ 982 typename FieldTraits::real_type sum=0;\n+ 983 for (size_type i=0; iN(); i++)\n+ 984 for (size_type j=0; jM(); j++)\n+ 985 sum += Impl::asMatrix(data_[i][j]).frobenius_norm2();\n+ 986 return sum;\n+ 987 }\n+ 988\n+ 990 template ::value, int>::type = 0>\n+992 typename FieldTraits::real_type infinity_norm() const {\n+ 993 using real_type = typename FieldTraits::real_type;\n+ 994 using std::max;\n+ 995\n+ 996 real_type norm = 0;\n+ 997 for (auto const &x : *this) {\n+ 998 real_type sum = 0;\n+ 999 for (auto const &y : x)\n+ 1000 sum += Impl::asMatrix(y).infinity_norm();\n+ 1001 norm = max(sum, norm);\n+ 1002 isNaN += sum;\n+ 1003 }\n+ 1004\n+ 1005 return norm;\n+ 1006 }\n+ 1007\n+ 1009 template ::value, int>::type = 0>\n+1011 typename FieldTraits::real_type infinity_norm_real() const {\n+ 1012 using real_type = typename FieldTraits::real_type;\n+ 1013 using std::max;\n+ 1014\n+ 1015 real_type norm = 0;\n+ 1016 for (auto const &x : *this) {\n+ 1017 real_type sum = 0;\n+ 1018 for (auto const &y : x)\n+ 1019 sum += Impl::asMatrix(y).infinity_norm_real();\n+ 1020 norm = max(sum, norm);\n+ 1021 }\n+ 1022 return norm;\n+ 1023 }\n+ 1024\n+ 1026 template ::value, int>::type = 0>\n+1028 typename FieldTraits::real_type infinity_norm() const {\n+ 1029 using real_type = typename FieldTraits::real_type;\n+ 1030 using std::max;\n+ 1031\n+ 1032 real_type norm = 0;\n+ 1033 real_type isNaN = 1;\n+ 1034 for (auto const &x : *this) {\n+ 1035 real_type sum = 0;\n+ 1036 for (auto const &y : x)\n+ 1037 sum += Impl::asMatrix(y).infinity_norm();\n+ 1038 norm = max(sum, norm);\n+ 1039 isNaN += sum;\n+ 1040 }\n+ 1041\n+ 1042 return norm * (isNaN / isNaN);\n+ 1043 }\n+ 1044\n+ 1046 template ::value, int>::type = 0>\n+1048 typename FieldTraits::real_type infinity_norm_real() const {\n+ 1049 using real_type = typename FieldTraits::real_type;\n+ 1050 using std::max;\n+ 1051\n+ 1052 real_type norm = 0;\n+ 1053 real_type isNaN = 1;\n+ 1054 for (auto const &x : *this) {\n+ 1055 real_type sum = 0;\n+ 1056 for (auto const &y : x)\n+ 1057 sum += Impl::asMatrix(y).infinity_norm_real();\n+ 1058 norm = max(sum, norm);\n+ 1059 isNaN += sum;\n+ 1060 }\n+ 1061\n+ 1062 return norm * (isNaN / isNaN);\n+ 1063 }\n+ 1064\n+ 1065 //===== query\n+ 1066\n+1068 bool exists ([[maybe_unused]] size_type i, [[maybe_unused]] size_type j)\n+const\n+ 1069 {\n+ 1070#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1071 if (i<0 || i>=N()) DUNE_THROW(ISTLError,\"row index out of range\");\n+ 1072 if (j<0 || i>=M()) DUNE_THROW(ISTLError,\"column index out of range\");\n+ 1073#endif\n+ 1074 return true;\n+ 1075 }\n+ 1076\n+ 1077 protected:\n+ 1078\n+1081 MatrixImp::DenseMatrixBase data_;\n+ 1082\n+1088 size_type cols_;\n+ 1089 };\n+ 1090\n+ 1091 template\n+1092 struct FieldTraits< Matrix >\n+ 1093 {\n+1094 using field_type = typename Matrix::field_type;\n+1095 using real_type = typename FieldTraits::real_type;\n+ 1096 };\n+ 1097\n+ 1099} // end namespace Dune\n+ 1100\n+ 1101#endif\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n istlexception.hh\n-gsetc.hh\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way.\n-Dune::MultiTypeBlockMatrix::type\n-MultiTypeBlockMatrix< FirstRow, Args... > type\n-Definition: multitypeblockmatrix.hh:56\n-Dune::MultiTypeBlockMatrix_Solver::dbjac\n-static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:568\n-Dune::MultiTypeBlockMatrix::operator+=\n-MultiTypeBlockMatrix & operator+=(const MultiTypeBlockMatrix &b)\n-Add the entries of another matrix to this one.\n-Definition: multitypeblockmatrix.hh:168\n-Dune::MultiTypeBlockMatrix::mv\n-void mv(const X &x, Y &y) const\n-y = A x\n-Definition: multitypeblockmatrix.hh:196\n-Dune::MultiTypeBlockMatrix::mmtv\n-void mmtv(const X &x, Y &y) const\n-y -= A^T x\n-Definition: multitypeblockmatrix.hh:276\n-Dune::MultiTypeBlockMatrix::mmhv\n-void mmhv(const X &x, Y &y) const\n-y -= A^H x\n-Definition: multitypeblockmatrix.hh:321\n-Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::dbgs\n-static void dbgs(const TMatrix &, TVector &, TVector &, const TVector &, const\n-K &)\n-Definition: multitypeblockmatrix.hh:598\n-Dune::MultiTypeBlockMatrix_Solver::dbgs\n-static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:484\n-Dune::MultiTypeBlockMatrix_Solver::bsorb\n-static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:540\n-Dune::MultiTypeBlockMatrix::usmhv\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+Dune\n+Definition: allocator.hh:11\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::MatrixImp::DenseMatrixBase\n+A Vector of blocks with different blocksizes.\n+Definition: matrix.hh:44\n+Dune::MatrixImp::DenseMatrixBase::window_type\n+Imp::BlockVectorWindow< B, A > window_type\n+Definition: matrix.hh:70\n+Dune::MatrixImp::DenseMatrixBase::block_type\n+BlockVector< B, A > block_type\n+Same as value_type, here for historical reasons.\n+Definition: matrix.hh:67\n+Dune::MatrixImp::DenseMatrixBase::operator=\n+DenseMatrixBase & operator=(const DenseMatrixBase &a)\n+assignment\n+Definition: matrix.hh:182\n+Dune::MatrixImp::DenseMatrixBase::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: matrix.hh:50\n+Dune::MatrixImp::DenseMatrixBase::beforeBegin\n+Iterator beforeBegin() const\n+Definition: matrix.hh:385\n+Dune::MatrixImp::DenseMatrixBase::resize\n+void resize(size_type rows, size_type columns)\n+same effect as constructor with same argument\n+Definition: matrix.hh:153\n+Dune::MatrixImp::DenseMatrixBase::const_reference\n+const window_type const_reference\n+Definition: matrix.hh:74\n+Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n+DenseMatrixBase(size_type rows, size_type columns)\n+Definition: matrix.hh:95\n+Dune::MatrixImp::DenseMatrixBase::end\n+Iterator end()\n+end Iterator\n+Definition: matrix.hh:371\n+Dune::MatrixImp::DenseMatrixBase::operator[]\n+reference operator[](size_type i)\n+random access to blocks\n+Definition: matrix.hh:241\n+Dune::MatrixImp::DenseMatrixBase::value_type\n+BlockVector< B, A > value_type\n+Type of the elements of the outer vector, i.e., dynamic vectors of B.\n+Definition: matrix.hh:63\n+Dune::MatrixImp::DenseMatrixBase::find\n+Iterator find(size_type i)\n+random access returning iterator (end if not contained)\n+Definition: matrix.hh:391\n+Dune::MatrixImp::DenseMatrixBase::N\n+size_type N() const\n+number of blocks in the vector (are of variable size here)\n+Definition: matrix.hh:539\n+Dune::MatrixImp::DenseMatrixBase::beforeEnd\n+ConstIterator beforeEnd() const\n+Definition: matrix.hh:525\n+Dune::MatrixImp::DenseMatrixBase::end\n+ConstIterator end() const\n+end ConstIterator\n+Definition: matrix.hh:518\n+Dune::MatrixImp::DenseMatrixBase::reference\n+window_type reference\n+Definition: matrix.hh:72\n+Dune::MatrixImp::DenseMatrixBase::rend\n+ConstIterator rend() const\n+end ConstIterator\n+Definition: matrix.hh:531\n+Dune::MatrixImp::DenseMatrixBase::beforeEnd\n+Iterator beforeEnd()\n+Definition: matrix.hh:378\n+Dune::MatrixImp::DenseMatrixBase::begin\n+ConstIterator begin() const\n+begin ConstIterator\n+Definition: matrix.hh:512\n+Dune::MatrixImp::DenseMatrixBase::allocator_type\n+A allocator_type\n+export the allocator type\n+Definition: matrix.hh:53\n+Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n+DenseMatrixBase()\n+Definition: matrix.hh:82\n+Dune::MatrixImp::DenseMatrixBase::find\n+ConstIterator find(size_type i) const\n+random access returning iterator (end if not contained)\n+Definition: matrix.hh:397\n+Dune::MatrixImp::DenseMatrixBase::size_type\n+A::size_type size_type\n+The size type for the index access.\n+Definition: matrix.hh:56\n+Dune::MatrixImp::DenseMatrixBase::~DenseMatrixBase\n+~DenseMatrixBase()\n+free dynamic memory\n+Definition: matrix.hh:142\n+Dune::MatrixImp::DenseMatrixBase::begin\n+Iterator begin()\n+begin Iterator\n+Definition: matrix.hh:365\n+Dune::MatrixImp::DenseMatrixBase::DenseMatrixBase\n+DenseMatrixBase(const DenseMatrixBase &a)\n+copy constructor, has copy semantics\n+Definition: matrix.hh:116\n+Dune::MatrixImp::DenseMatrixBase::Iterator\n+Iterator class for sequential access.\n+Definition: matrix.hh:263\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator--\n+Iterator & operator--()\n+prefix decrement\n+Definition: matrix.hh:308\n+Dune::MatrixImp::DenseMatrixBase::Iterator::index\n+size_type index() const\n+Definition: matrix.hh:352\n+Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n+Iterator(Iterator &other)=default\n+Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n+Iterator(Iterator &&other)=default\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator!=\n+bool operator!=(const Iterator &it) const\n+inequality\n+Definition: matrix.hh:322\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator=\n+Iterator & operator=(Iterator &&other)\n+Move assignment.\n+Definition: matrix.hh:282\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator++\n+Iterator & operator++()\n+prefix increment\n+Definition: matrix.hh:300\n+Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n+Iterator()\n+constructor, no arguments\n+Definition: matrix.hh:266\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator*\n+window_type & operator*() const\n+dereferencing\n+Definition: matrix.hh:340\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator==\n+bool operator==(const Iterator &it) const\n+equality\n+Definition: matrix.hh:316\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator=\n+Iterator & operator=(Iterator &other)\n+Copy assignment.\n+Definition: matrix.hh:291\n+Dune::MatrixImp::DenseMatrixBase::Iterator::Iterator\n+Iterator(B *data, size_type columns, size_type _i)\n+constructor\n+Definition: matrix.hh:276\n+Dune::MatrixImp::DenseMatrixBase::Iterator::operator->\n+window_type * operator->() const\n+arrow\n+Definition: matrix.hh:346\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator\n+ConstIterator class for sequential access.\n+Definition: matrix.hh:404\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator->\n+const window_type * operator->() const\n+arrow\n+Definition: matrix.hh:487\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator*\n+const window_type & operator*() const\n+dereferencing\n+Definition: matrix.hh:481\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator++\n+ConstIterator & operator++()\n+prefix increment\n+Definition: matrix.hh:441\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n+ConstIterator(const B *data, size_type columns, size_type _i)\n+constructor from pointer\n+Definition: matrix.hh:414\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator--\n+ConstIterator & operator--()\n+prefix decrement\n+Definition: matrix.hh:449\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n+ConstIterator(const Iterator &it)\n+constructor from non_const iterator\n+Definition: matrix.hh:420\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator!=\n+bool operator!=(const ConstIterator &it) const\n+inequality\n+Definition: matrix.hh:463\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::ConstIterator\n+ConstIterator()\n+constructor\n+Definition: matrix.hh:407\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator==\n+bool operator==(const ConstIterator &it) const\n+equality\n+Definition: matrix.hh:457\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::index\n+size_type index() const\n+Definition: matrix.hh:493\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator=\n+ConstIterator & operator=(Iterator &&other)\n+Definition: matrix.hh:424\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator::operator=\n+ConstIterator & operator=(Iterator &other)\n+Definition: matrix.hh:432\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::cols_\n+size_type cols_\n+Number of columns of the matrix.\n+Definition: matrix.hh:1088\n+Dune::Matrix::infinity_norm\n+FieldTraits< ft >::real_type infinity_norm() const\n+infinity norm (row sum norm, how to generalize for blocks?)\n+Definition: matrix.hh:992\n+Dune::Matrix::allocator_type\n+A allocator_type\n+Export the allocator.\n+Definition: matrix.hh:571\n+Dune::Matrix::infinity_norm_real\n+FieldTraits< ft >::real_type infinity_norm_real() const\n+simplified infinity norm (uses Manhattan norm for complex values)\n+Definition: matrix.hh:1011\n+Dune::Matrix::usmhv\n void usmhv(const field_type &alpha, const X &x, Y &y) const\n y += alpha A^H x\n-Definition: multitypeblockmatrix.hh:336\n-Dune::MultiTypeBlockMatrix::field_type\n-FirstRow::field_type field_type\n-Definition: multitypeblockmatrix.hh:61\n-Dune::MultiTypeBlockMatrix::usmv\n-void usmv(const AlphaType &alpha, const X &x, Y &y) const\n-y += alpha A x\n-Definition: multitypeblockmatrix.hh:236\n-Dune::MultiTypeBlockMatrix::operator/=\n-MultiTypeBlockMatrix & operator/=(const field_type &k)\n-vector space division by scalar\n-Definition: multitypeblockmatrix.hh:152\n-std::tuple_element<_i,_Dune::MultiTypeBlockMatrix<_Args..._>_>::type\n-typename std::tuple_element< i, std::tuple< Args... > >::type type\n-Definition: multitypeblockmatrix.hh:625\n-Dune::MultiTypeBlockMatrix_Solver::dbgs\n-static void dbgs(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n-const K &w)\n-Definition: multitypeblockmatrix.hh:492\n-Dune::MultiTypeBlockMatrix_Solver::bsorf\n-static void bsorf(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n-const K &w)\n-Definition: multitypeblockmatrix.hh:520\n-Dune::MultiTypeBlockMatrix::umhv\n-void umhv(const X &x, Y &y) const\n-y += A^H x\n-Definition: multitypeblockmatrix.hh:306\n-Dune::MultiTypeBlockMatrix::frobenius_norm\n-FieldTraits< field_type >::real_type frobenius_norm() const\n-frobenius norm: sqrt(sum over squared values of entries)\n-Definition: multitypeblockmatrix.hh:369\n-Dune::MultiTypeBlockMatrix::N\n-static constexpr size_type N()\n-Return the number of matrix rows.\n-Definition: multitypeblockmatrix.hh:64\n-Dune::MultiTypeBlockMatrix::usmtv\n-void usmtv(const field_type &alpha, const X &x, Y &y) const\n-y += alpha A^T x\n-Definition: multitypeblockmatrix.hh:291\n-Dune::MultiTypeBlockMatrix::operator=\n-void operator=(const T &newval)\n-Definition: multitypeblockmatrix.hh:127\n-Dune::MultiTypeBlockMatrix_Solver_Col<_I,_crow,_ccol,_0_>::calc_rhs\n-static void calc_rhs(const TMatrix &, TVector &, TVector &, Trhs &, const K &)\n-Definition: multitypeblockmatrix.hh:465\n-Dune::MultiTypeBlockMatrix::umv\n+Definition: matrix.hh:956\n+Dune::Matrix::usmv\n+void usmv(const field_type &alpha, const X &x, Y &y) const\n+Definition: matrix.hh:854\n+Dune::Matrix::size_type\n+A::size_type size_type\n+Type for indices and sizes.\n+Definition: matrix.hh:577\n+Dune::Matrix::data_\n+MatrixImp::DenseMatrixBase< T, A > data_\n+Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.\n+Definition: matrix.hh:1081\n+Dune::Matrix::transpose\n+Matrix transpose() const\n+Return the transpose of the matrix.\n+Definition: matrix.hh:745\n+Dune::Matrix::mtv\n+void mtv(const X &x, Y &y) const\n+y = A^T x\n+Definition: matrix.hh:807\n+Dune::Matrix::umv\n void umv(const X &x, Y &y) const\n y += A x\n-Definition: multitypeblockmatrix.hh:206\n-Dune::MultiTypeBlockMatrix_Solver_Col::calc_rhs\n-static void calc_rhs(const TMatrix &A, TVector &x, TVector &v, Trhs &b, const K\n-&w)\n-Definition: multitypeblockmatrix.hh:455\n-Dune::MultiTypeBlockMatrix_Solver::bsorf\n-static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:513\n-Dune::MultiTypeBlockMatrix::size\n-static constexpr size_type size()\n-Return the number of matrix rows.\n-Definition: multitypeblockmatrix.hh:75\n-Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::dbjac\n-static void dbjac(const TMatrix &, TVector &, TVector &, const TVector &, const\n-K &)\n-Definition: multitypeblockmatrix.hh:610\n-Dune::MultiTypeBlockMatrix::infinity_norm_real\n-auto infinity_norm_real() const\n-Bastardized version of the infinity-norm / row-sum norm.\n-Definition: multitypeblockmatrix.hh:396\n-Dune::MultiTypeBlockMatrix::frobenius_norm2\n-auto frobenius_norm2() const\n-square of frobenius norm, need for block recursion\n-Definition: multitypeblockmatrix.hh:352\n-Dune::MultiTypeBlockMatrix::size_type\n-std::size_t size_type\n-Type used for sizes.\n-Definition: multitypeblockmatrix.hh:59\n-Dune::MultiTypeBlockMatrix::infinity_norm\n-auto infinity_norm() const\n-Bastardized version of the infinity-norm / row-sum norm.\n-Definition: multitypeblockmatrix.hh:375\n-Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::bsorb\n-static void bsorb(const TMatrix &, TVector &, TVector &, const TVector &, const\n-K &)\n-Definition: multitypeblockmatrix.hh:606\n-Dune::MultiTypeBlockMatrix::operator-=\n-MultiTypeBlockMatrix & operator-=(const MultiTypeBlockMatrix &b)\n+Definition: matrix.hh:820\n+Dune::Matrix::mv\n+void mv(const X &x, Y &y) const\n+y = A x\n+Definition: matrix.hh:788\n+Dune::Matrix::ConstRowIterator\n+MatrixImp::DenseMatrixBase< T, A >::ConstIterator ConstRowIterator\n+Const iterator over the matrix rows.\n+Definition: matrix.hh:586\n+Dune::Matrix::setSize\n+void setSize(size_type rows, size_type cols)\n+Change the matrix size.\n+Definition: matrix.hh:608\n+Dune::Matrix::beforeBegin\n+RowIterator beforeBegin()\n+Definition: matrix.hh:634\n+Dune::Matrix::beforeEnd\n+RowIterator beforeEnd()\n+Definition: matrix.hh:627\n+Dune::Matrix::Matrix\n+Matrix()\n+Create empty matrix.\n+Definition: matrix.hh:596\n+Dune::Matrix::operator-=\n+Matrix & operator-=(const Matrix &b)\n Subtract the entries of another matrix from this one.\n-Definition: multitypeblockmatrix.hh:183\n-Dune::MultiTypeBlockMatrix::operator[]\n-auto operator[](const std::integral_constant< size_type, index > indexVariable)\n--> decltype(std::get< index >(*this))\n-Random-access operator.\n-Definition: multitypeblockmatrix.hh:104\n-Dune::MultiTypeBlockMatrix_Solver::dbjac\n-static void dbjac(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n-const K &w)\n-Definition: multitypeblockmatrix.hh:575\n-Dune::MultiTypeBlockMatrix_Solver<_I,_crow,_0_>::bsorf\n-static void bsorf(const TMatrix &, TVector &, TVector &, const TVector &, const\n-K &)\n-Definition: multitypeblockmatrix.hh:602\n-Dune::MultiTypeBlockMatrix::mtv\n-void mtv(const X &x, Y &y) const\n-y = A^T x\n-Definition: multitypeblockmatrix.hh:251\n-Dune::MultiTypeBlockMatrix::M\n-static constexpr size_type M()\n-Return the number of matrix columns.\n-Definition: multitypeblockmatrix.hh:81\n-Dune::MultiTypeBlockMatrix::mmv\n+Definition: matrix.hh:735\n+Dune::Matrix::frobenius_norm2\n+FieldTraits< field_type >::real_type frobenius_norm2() const\n+square of frobenius norm, need for block recursion\n+Definition: matrix.hh:980\n+Dune::Matrix::ColIterator\n+row_type::iterator ColIterator\n+Iterator for the entries of each row.\n+Definition: matrix.hh:583\n+Dune::Matrix::beforeEnd\n+ConstRowIterator beforeEnd() const\n+Definition: matrix.hh:653\n+Dune::Matrix::operator=\n+Matrix & operator=(const field_type &t)\n+Assignment from scalar.\n+Definition: matrix.hh:666\n+Dune::Matrix::end\n+RowIterator end()\n+Get iterator to one beyond last row.\n+Definition: matrix.hh:620\n+Dune::Matrix::operator[]\n+const row_type operator[](size_type row) const\n+The const index operator.\n+Definition: matrix.hh:684\n+Dune::Matrix::end\n+ConstRowIterator end() const\n+Get const iterator to one beyond last row.\n+Definition: matrix.hh:646\n+Dune::Matrix::operator*\n+friend Y operator*(const Matrix< T > &m, const X &vec)\n+Generic matrix-vector multiplication.\n+Definition: matrix.hh:770\n+Dune::Matrix::operator*=\n+Matrix< T > & operator*=(const field_type &scalar)\n+Multiplication with a scalar.\n+Definition: matrix.hh:705\n+Dune::Matrix::operator[]\n+row_type operator[](size_type row)\n+The index operator.\n+Definition: matrix.hh:673\n+Dune::Matrix::mmv\n void mmv(const X &x, Y &y) const\n y -= A x\n-Definition: multitypeblockmatrix.hh:221\n-Dune::MultiTypeBlockMatrix::umtv\n+Definition: matrix.hh:837\n+Dune::Matrix::operator+=\n+Matrix & operator+=(const Matrix &b)\n+Add the entries of another matrix to this one.\n+Definition: matrix.hh:721\n+Dune::Matrix::begin\n+ConstRowIterator begin() const\n+Get const iterator to first row.\n+Definition: matrix.hh:640\n+Dune::Matrix::mmhv\n+void mmhv(const X &x, Y &y) const\n+y -= A^H x\n+Definition: matrix.hh:939\n+Dune::Matrix::begin\n+RowIterator begin()\n+Get iterator to first row.\n+Definition: matrix.hh:614\n+Dune::Matrix::field_type\n+typename Imp::BlockTraits< T >::field_type field_type\n+Export the type representing the underlying field.\n+Definition: matrix.hh:565\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::blocklevel\n+static constexpr auto blocklevel\n+The number of nesting levels the matrix contains.\n+Definition: matrix.hh:593\n+Dune::Matrix::M\n+size_type M() const\n+Return the number of columns.\n+Definition: matrix.hh:700\n+Dune::Matrix::block_type\n+T block_type\n+Export the type representing the components.\n+Definition: matrix.hh:568\n+Dune::Matrix::exists\n+bool exists(size_type i, size_type j) const\n+return true if (i,j) is in pattern\n+Definition: matrix.hh:1068\n+Dune::Matrix::operator/=\n+Matrix< T > & operator/=(const field_type &scalar)\n+Division by a scalar.\n+Definition: matrix.hh:711\n+Dune::Matrix::operator*\n+friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)\n+Generic matrix multiplication.\n+Definition: matrix.hh:755\n+Dune::Matrix::umtv\n void umtv(const X &x, Y &y) const\n y += A^T x\n-Definition: multitypeblockmatrix.hh:261\n-Dune::MultiTypeBlockMatrix_Solver::bsorb\n-static void bsorb(const TMatrix &A, TVector &x, TVector &v, const TVector &b,\n-const K &w)\n-Definition: multitypeblockmatrix.hh:547\n-Dune::MultiTypeBlockMatrix::operator*=\n-MultiTypeBlockMatrix & operator*=(const field_type &k)\n-vector space multiplication with scalar\n-Definition: multitypeblockmatrix.hh:141\n-std\n-STL namespace.\n-Dune\n-Definition: allocator.hh:11\n-Dune::operator<<\n-std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n-Send BlockVector to an output stream.\n-Definition: bvector.hh:590\n-Dune::MultiTypeBlockMatrix\n-A Matrix class to support different block types.\n-Definition: multitypeblockmatrix.hh:46\n-Dune::algmeta_itsteps::bsorb\n-static void bsorb(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:461\n-Dune::algmeta_itsteps::bsorf\n-static void bsorf(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:418\n-Dune::algmeta_itsteps::dbjac\n-static void dbjac(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:504\n-Dune::algmeta_itsteps::dbgs\n-static void dbgs(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:378\n-Dune::MultiTypeBlockMatrix_Solver\n-solver for MultiTypeBlockVector & MultiTypeBlockMatrix types\n-Definition: multitypeblockmatrix.hh:477\n-Dune::MultiTypeBlockMatrix_Solver_Col\n-part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types\n-Definition: multitypeblockmatrix.hh:449\n+Definition: matrix.hh:871\n+Dune::Matrix::mmtv\n+void mmtv(const X &x, Y &y) const\n+y -= A^T x\n+Definition: matrix.hh:888\n+Dune::Matrix::row_type\n+MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n+The type implementing a matrix row.\n+Definition: matrix.hh:574\n+Dune::Matrix::frobenius_norm\n+FieldTraits< field_type >::real_type frobenius_norm() const\n+frobenius norm: sqrt(sum over squared values of entries)\n+Definition: matrix.hh:974\n+Dune::Matrix::usmtv\n+void usmtv(const field_type &alpha, const X &x, Y &y) const\n+y += alpha A^T x\n+Definition: matrix.hh:905\n+Dune::Matrix::umhv\n+void umhv(const X &x, Y &y) const\n+y += A^H x\n+Definition: matrix.hh:922\n+Dune::Matrix::N\n+size_type N() const\n+Return the number of rows.\n+Definition: matrix.hh:695\n+Dune::Matrix::beforeBegin\n+ConstRowIterator beforeBegin() const\n+Definition: matrix.hh:660\n+Dune::Matrix::Matrix\n+Matrix(size_type rows, size_type cols)\n+Create uninitialized matrix of size rows x cols.\n+Definition: matrix.hh:601\n+Dune::Matrix::RowIterator\n+MatrixImp::DenseMatrixBase< T, A >::Iterator RowIterator\n+Iterator over the matrix rows.\n+Definition: matrix.hh:580\n+Dune::FieldTraits<_Matrix<_T,_A_>_>::field_type\n+typename Matrix< T, A >::field_type field_type\n+Definition: matrix.hh:1094\n+Dune::FieldTraits<_Matrix<_T,_A_>_>::real_type\n+typename FieldTraits< field_type >::real_type real_type\n+Definition: matrix.hh:1095\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00071.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00071.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: preconditioners.hh File Reference\n+dune-istl: schwarz.hh File Reference\n \n \n \n \n \n \n \n@@ -64,99 +64,57 @@\n \n
    \n
    \n \n+
    schwarz.hh File Reference
    \n
    \n
    \n-\n-

    Define general preconditioner interface. \n-More...

    \n-
    #include <cmath>
    \n-#include <complex>
    \n-#include <iostream>
    \n-#include <iomanip>
    \n-#include <memory>
    \n-#include <string>
    \n-#include <dune/common/simd/simd.hh>
    \n-#include <dune/common/parametertree.hh>
    \n-#include <dune/istl/solverregistry.hh>
    \n-#include "preconditioner.hh"
    \n-#include "solver.hh"
    \n-#include "solvercategory.hh"
    \n-#include "istlexception.hh"
    \n-#include "matrixutils.hh"
    \n-#include "gsetc.hh"
    \n-#include "ildl.hh"
    \n-#include "ilu.hh"
    \n+
    #include <iostream>
    \n+#include <fstream>
    \n+#include <vector>
    \n+#include <sstream>
    \n+#include <cmath>
    \n+#include <dune/common/timer.hh>
    \n+#include "io.hh"
    \n+#include "bvector.hh"
    \n+#include "vbvector.hh"
    \n+#include "bcrsmatrix.hh"
    \n+#include "gsetc.hh"
    \n+#include "ilu.hh"
    \n+#include "operators.hh"
    \n+#include "solvers.hh"
    \n+#include "preconditioners.hh"
    \n+#include "scalarproducts.hh"
    \n+#include "owneroverlapcopy.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::InverseOperator2Preconditioner< O, c >
     Turns an InverseOperator into a Preconditioner. More...
     
    class  Dune::SeqSSOR< M, X, Y, l >
     Sequential SSOR preconditioner. More...
     
    class  Dune::SeqSOR< M, X, Y, l >
     Sequential SOR preconditioner. More...
     
    class  Dune::SeqJac< M, X, Y, l >
     The sequential jacobian preconditioner. More...
    class  Dune::OverlappingSchwarzOperator< M, X, Y, C >
     An overlapping Schwarz operator. More...
     
    class  Dune::SeqILU< M, X, Y, l >
     Sequential ILU preconditioner. More...
    class  Dune::ParSSOR< M, X, Y, C >
     A parallel SSOR preconditioner. More...
     
    class  Dune::Richardson< X, Y >
     Richardson preconditioner. More...
     
    class  Dune::SeqILDL< M, X, Y >
     sequential ILDL preconditioner More...
    class  Dune::BlockPreconditioner< X, Y, C, P >
     Block parallel preconditioner. More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-

    \n-Typedefs

    template<class M , class X , class Y , int l = 1>
    using Dune::SeqGS = SeqSOR< M, X, Y, l >
     Sequential Gauss Seidel preconditioner. More...
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n

    \n-Functions

     Dune::DUNE_REGISTER_PRECONDITIONER ("ssor", defaultPreconditionerBlockLevelCreator< Dune::SeqSSOR >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("sor", defaultPreconditionerBlockLevelCreator< Dune::SeqSOR >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("gs", defaultPreconditionerBlockLevelCreator< Dune::SeqGS >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("jac", defaultPreconditionerBlockLevelCreator< Dune::SeqJac >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("ilu", defaultPreconditionerBlockLevelCreator< Dune::SeqILU >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("richardson", [](auto tl, const auto &, const ParameterTree &config){ using D=typename Dune::TypeListElement< 1, decltype(tl)>::type;using R=typename Dune::TypeListElement< 2, decltype(tl)>::type;return std::make_shared< Richardson< D, R > >(config);})
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("ildl", defaultPreconditionerCreator< Dune::SeqILDL >())
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Define general preconditioner interface.

    \n-

    Wrap the methods implemented by ISTL in this interface. However, the interface is extensible such that new preconditioners can be implemented and used with the solvers.

    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,91 +4,45 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Typedefs | Functions\n-preconditioners.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-Define general preconditioner interface. More...\n-#include \n-#include \n+Classes | Namespaces\n+schwarz.hh File Reference\n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"preconditioner.hh\"\n-#include \"solver.hh\"\n-#include \"solvercategory.hh\"\n-#include \"istlexception.hh\"\n-#include \"matrixutils.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"io.hh\"\n+#include \"bvector.hh\"\n+#include \"vbvector.hh\"\n+#include \"bcrsmatrix.hh\"\n #include \"gsetc.hh\"\n-#include \"ildl.hh\"\n #include \"ilu.hh\"\n+#include \"operators.hh\"\n+#include \"solvers.hh\"\n+#include \"preconditioners.hh\"\n+#include \"scalarproducts.hh\"\n+#include \"owneroverlapcopy.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::InverseOperator2Preconditioner<_O,_c_>\n-\u00a0 Turns an InverseOperator into a Preconditioner. More...\n-\u00a0\n-class \u00a0Dune::SeqSSOR<_M,_X,_Y,_l_>\n-\u00a0 Sequential SSOR preconditioner. More...\n-\u00a0\n-class \u00a0Dune::SeqSOR<_M,_X,_Y,_l_>\n-\u00a0 Sequential SOR preconditioner. More...\n+class \u00a0Dune::OverlappingSchwarzOperator<_M,_X,_Y,_C_>\n+\u00a0 An overlapping Schwarz operator. More...\n \u00a0\n-class \u00a0Dune::SeqJac<_M,_X,_Y,_l_>\n-\u00a0 The sequential jacobian preconditioner. More...\n+class \u00a0Dune::ParSSOR<_M,_X,_Y,_C_>\n+\u00a0 A parallel SSOR preconditioner. More...\n \u00a0\n-class \u00a0Dune::SeqILU<_M,_X,_Y,_l_>\n-\u00a0 Sequential ILU preconditioner. More...\n-\u00a0\n-class \u00a0Dune::Richardson<_X,_Y_>\n-\u00a0 Richardson preconditioner. More...\n-\u00a0\n-class \u00a0Dune::SeqILDL<_M,_X,_Y_>\n-\u00a0 sequential ILDL preconditioner More...\n+class \u00a0Dune::BlockPreconditioner<_X,_Y,_C,_P_>\n+\u00a0 Block parallel preconditioner. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Typedefs\n-template\n-using\u00a0Dune::SeqGS = SeqSOR< M, X, Y, l >\n-\u00a0 Sequential Gauss Seidel preconditioner. More...\n-\u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ssor\",\n- defaultPreconditionerBlockLevelCreator< Dune::SeqSSOR >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"sor\",\n- defaultPreconditionerBlockLevelCreator< Dune::SeqSOR >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"gs\",\n- defaultPreconditionerBlockLevelCreator< Dune::SeqGS >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"jac\",\n- defaultPreconditionerBlockLevelCreator< Dune::SeqJac >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ilu\",\n- defaultPreconditionerBlockLevelCreator< Dune::SeqILU >())\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"richardson\", [](auto tl, const auto &,\n- const ParameterTree &config){ using D=typename Dune::TypeListElement< 1,\n- decltype(tl)>::type;using R=typename Dune::TypeListElement< 2, decltype\n- (tl)>::type;return std::make_shared< Richardson< D, R > >(config);})\n-\u00a0\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ildl\", defaultPreconditionerCreator<\n- Dune::SeqILDL >())\n+namespace \u00a0Dune::Amg\n \u00a0\n-***** Detailed Description *****\n-Define general preconditioner interface.\n-Wrap the methods implemented by ISTL in this interface. However, the interface\n-is extensible such that new preconditioners can be implemented and used with\n-the solvers.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00071_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00071_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: preconditioners.hh Source File\n+dune-istl: schwarz.hh Source File\n \n \n \n \n \n \n \n@@ -62,630 +62,263 @@\n \n
    \n \n
    \n
    \n
    \n-
    preconditioners.hh
    \n+
    schwarz.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_PRECONDITIONERS_HH
    \n-
    6#define DUNE_ISTL_PRECONDITIONERS_HH
    \n+
    5#ifndef DUNE_ISTL_SCHWARZ_HH
    \n+
    6#define DUNE_ISTL_SCHWARZ_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <complex>
    \n-
    10#include <iostream>
    \n-
    11#include <iomanip>
    \n-
    12#include <memory>
    \n-
    13#include <string>
    \n+
    8#include <iostream> // for input/output to shell
    \n+
    9#include <fstream> // for input/output to files
    \n+
    10#include <vector> // STL vector class
    \n+
    11#include <sstream>
    \n+
    12
    \n+
    13#include <cmath> // Yes, we do some math here
    \n
    14
    \n-
    15#include <dune/common/simd/simd.hh>
    \n-
    16#include <dune/common/parametertree.hh>
    \n-
    17
    \n-\n-
    19#include "preconditioner.hh"
    \n-
    20#include "solver.hh"
    \n-
    21#include "solvercategory.hh"
    \n-
    22#include "istlexception.hh"
    \n-
    23#include "matrixutils.hh"
    \n-
    24#include "gsetc.hh"
    \n-
    25#include "ildl.hh"
    \n-
    26#include "ilu.hh"
    \n-
    27
    \n-
    28
    \n-
    29namespace Dune {
    \n-
    72 template<class O, int c = -1>
    \n-\n-
    74 public Preconditioner<typename O::domain_type, typename O::range_type>
    \n+
    15#include <dune/common/timer.hh>
    \n+
    16
    \n+
    17#include "io.hh"
    \n+
    18#include "bvector.hh"
    \n+
    19#include "vbvector.hh"
    \n+
    20#include "bcrsmatrix.hh"
    \n+
    21#include "io.hh"
    \n+
    22#include "gsetc.hh"
    \n+
    23#include "ilu.hh"
    \n+
    24#include "operators.hh"
    \n+
    25#include "solvers.hh"
    \n+
    26#include "preconditioners.hh"
    \n+
    27#include "scalarproducts.hh"
    \n+
    28#include "owneroverlapcopy.hh"
    \n+
    29
    \n+
    30namespace Dune {
    \n+
    31
    \n+
    73 template<class M, class X, class Y, class C>
    \n+\n
    75 {
    \n
    76 public:
    \n-
    78 typedef typename O::domain_type domain_type;
    \n-
    80 typedef typename O::range_type range_type;
    \n-
    82 typedef typename range_type::field_type field_type;
    \n-
    84 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    86 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    88 typedef O InverseOperator;
    \n-
    89
    \n-\n-
    95 : inverse_operator_(inverse_operator)
    \n-
    96 {
    \n-
    97 if(c != -1 && SolverCategory::category(inverse_operator_) != c)
    \n-
    98 DUNE_THROW(InvalidStateException, "User-supplied solver category does not match that of the given inverse operator");
    \n-
    99 }
    \n-
    100
    \n-
    101 virtual void pre(domain_type&,range_type&)
    \n-
    102 {}
    \n-
    103
    \n-
    104 virtual void apply(domain_type& v, const range_type& d)
    \n-
    105 {
    \n-\n-
    107 range_type copy(d);
    \n-
    108 inverse_operator_.apply(v, copy, res);
    \n-
    109 }
    \n+
    81 typedef M matrix_type;
    \n+
    86 typedef X domain_type;
    \n+
    91 typedef Y range_type;
    \n+
    93 typedef typename X::field_type field_type;
    \n+\n+
    99
    \n+\n+
    108 : _A_(stackobject_to_shared_ptr(A)), communication(com)
    \n+
    109 {}
    \n
    110
    \n-
    111 virtual void post(domain_type&)
    \n-
    112 {}
    \n-
    113
    \n-\n-
    116 {
    \n-
    117 return SolverCategory::category(inverse_operator_);
    \n-
    118 }
    \n-
    119
    \n-
    120 private:
    \n-
    121 InverseOperator& inverse_operator_;
    \n-
    122 };
    \n+
    111 OverlappingSchwarzOperator (const std::shared_ptr<matrix_type> A, const communication_type& com)
    \n+
    112 : _A_(A), communication(com)
    \n+
    113 {}
    \n+
    114
    \n+
    116 virtual void apply (const X& x, Y& y) const
    \n+
    117 {
    \n+
    118 y = 0;
    \n+
    119 _A_->umv(x,y); // result is consistent on interior+border
    \n+
    120 communication.project(y); // we want this here to avoid it before the preconditioner
    \n+
    121 // since there d is const!
    \n+
    122 }
    \n
    123
    \n-
    124 //=====================================================================
    \n-
    125 // Implementation of this interface for sequential ISTL-preconditioners
    \n-
    126 //=====================================================================
    \n-
    127
    \n-
    128
    \n-
    140 template<class M, class X, class Y, int l=1>
    \n-
    141 class SeqSSOR : public Preconditioner<X,Y> {
    \n-
    142 public:
    \n-
    144 typedef M matrix_type;
    \n-
    146 typedef X domain_type;
    \n-
    148 typedef Y range_type;
    \n-
    150 typedef typename X::field_type field_type;
    \n-
    152 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    154 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    155
    \n-
    163 SeqSSOR (const M& A, int n, real_field_type w)
    \n-
    164 : _A_(A), _n(n), _w(w)
    \n-
    165 {
    \n-\n-
    167 }
    \n-
    168
    \n-
    182 SeqSSOR (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n-
    183 : SeqSSOR(A->getmat(), configuration)
    \n-
    184 {}
    \n-
    185
    \n-
    199 SeqSSOR (const M& A, const ParameterTree& configuration)
    \n-
    200 : SeqSSOR(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n-
    201 {}
    \n-
    202
    \n-
    208 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n-
    209 {}
    \n+
    125 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n+
    126 {
    \n+
    127 _A_->usmv(alpha,x,y); // result is consistent on interior+border
    \n+
    128 communication.project(y); // we want this here to avoid it before the preconditioner
    \n+
    129 // since there d is const!
    \n+
    130 }
    \n+
    131
    \n+
    133 virtual const matrix_type& getmat () const
    \n+
    134 {
    \n+
    135 return *_A_;
    \n+
    136 }
    \n+
    137
    \n+\n+
    140 {
    \n+\n+
    142 }
    \n+
    143
    \n+
    144
    \n+\n+
    147 {
    \n+
    148 return communication;
    \n+
    149 }
    \n+
    150 private:
    \n+
    151 const std::shared_ptr<const matrix_type>_A_;
    \n+
    152 const communication_type& communication;
    \n+
    153 };
    \n+
    154
    \n+
    157 /*
    \n+
    158 * @addtogroup ISTL_Prec
    \n+
    159 * @{
    \n+
    160 */
    \n+
    174 template<class M, class X, class Y, class C>
    \n+
    175 class ParSSOR : public Preconditioner<X,Y> {
    \n+
    176 public:
    \n+
    178 typedef M matrix_type;
    \n+
    180 typedef X domain_type;
    \n+
    182 typedef Y range_type;
    \n+
    184 typedef typename X::field_type field_type;
    \n+\n+
    187
    \n+
    197 ParSSOR (const matrix_type& A, int n, field_type w, const communication_type& c)
    \n+
    198 : _A_(A), _n(n), _w(w), communication(c)
    \n+
    199 { }
    \n+
    200
    \n+
    206 virtual void pre (X& x, [[maybe_unused]] Y& b)
    \n+
    207 {
    \n+
    208 communication.copyOwnerToAll(x,x); // make dirichlet values consistent
    \n+
    209 }
    \n
    210
    \n-
    216 virtual void apply (X& v, const Y& d)
    \n+
    216 virtual void apply (X& v, const Y& d)
    \n
    217 {
    \n
    218 for (int i=0; i<_n; i++) {
    \n-
    219 bsorf(_A_,v,d,_w,BL<l>());
    \n-
    220 bsorb(_A_,v,d,_w,BL<l>());
    \n+
    219 bsorf(_A_,v,d,_w);
    \n+
    220 bsorb(_A_,v,d,_w);
    \n
    221 }
    \n-
    222 }
    \n-
    223
    \n-
    229 virtual void post ([[maybe_unused]] X& x)
    \n-
    230 {}
    \n+
    222 communication.copyOwnerToAll(v,v);
    \n+
    223 }
    \n+
    224
    \n+
    230 virtual void post ([[maybe_unused]] X& x) {}
    \n
    231
    \n-\n+\n
    234 {
    \n-\n+\n
    236 }
    \n
    237
    \n
    238 private:
    \n-
    240 const M& _A_;
    \n+
    240 const matrix_type& _A_;
    \n
    242 int _n;
    \n-\n-
    245 };
    \n-
    246 DUNE_REGISTER_PRECONDITIONER("ssor", defaultPreconditionerBlockLevelCreator<Dune::SeqSSOR>());
    \n-
    247
    \n+
    244 field_type _w;
    \n+
    246 const communication_type& communication;
    \n+
    247 };
    \n
    248
    \n-
    260 template<class M, class X, class Y, int l=1>
    \n-
    261 class SeqSOR : public Preconditioner<X,Y> {
    \n-
    262 public:
    \n-
    264 typedef M matrix_type;
    \n-
    266 typedef X domain_type;
    \n-
    268 typedef Y range_type;
    \n-
    270 typedef typename X::field_type field_type;
    \n-
    272 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    274 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    275
    \n-
    283 SeqSOR (const M& A, int n, real_field_type w)
    \n-
    284 : _A_(A), _n(n), _w(w)
    \n-
    285 {
    \n-\n-
    287 }
    \n-
    288
    \n-
    302 SeqSOR (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n-
    303 : SeqSOR(A->getmat(), configuration)
    \n-
    304 {}
    \n-
    305
    \n-
    319 SeqSOR (const M& A, const ParameterTree& configuration)
    \n-
    320 : SeqSOR(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n-
    321 {}
    \n-
    322
    \n-
    328 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n-
    329 {}
    \n-
    330
    \n-
    336 virtual void apply (X& v, const Y& d)
    \n-
    337 {
    \n-
    338 this->template apply<true>(v,d);
    \n-
    339 }
    \n-
    340
    \n-
    349 template<bool forward>
    \n-
    350 void apply(X& v, const Y& d)
    \n-
    351 {
    \n-
    352 if(forward)
    \n-
    353 for (int i=0; i<_n; i++) {
    \n-
    354 bsorf(_A_,v,d,_w,BL<l>());
    \n-
    355 }
    \n-
    356 else
    \n-
    357 for (int i=0; i<_n; i++) {
    \n-
    358 bsorb(_A_,v,d,_w,BL<l>());
    \n-
    359 }
    \n-
    360 }
    \n-
    361
    \n-
    367 virtual void post ([[maybe_unused]] X& x)
    \n-
    368 {}
    \n+
    249 namespace Amg
    \n+
    250 {
    \n+
    251 template<class T> struct ConstructionTraits;
    \n+
    252 }
    \n+
    253
    \n+
    277 template<class X, class Y, class C, class P=Preconditioner<X,Y> >
    \n+\n+
    279 friend struct Amg::ConstructionTraits<BlockPreconditioner<X,Y,C,P> >;
    \n+
    280 public:
    \n+
    285 typedef X domain_type;
    \n+
    290 typedef Y range_type;
    \n+
    292 typedef typename X::field_type field_type;
    \n+\n+
    298
    \n+\n+
    307 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)
    \n+
    308 { }
    \n+
    309
    \n+
    317 BlockPreconditioner (const std::shared_ptr<P>& p, const communication_type& c)
    \n+
    318 : _preconditioner(p), _communication(c)
    \n+
    319 { }
    \n+
    320
    \n+
    326 virtual void pre (X& x, Y& b)
    \n+
    327 {
    \n+
    328 _communication.copyOwnerToAll(x,x); // make dirichlet values consistent
    \n+
    329 _preconditioner->pre(x,b);
    \n+
    330 }
    \n+
    331
    \n+
    337 virtual void apply (X& v, const Y& d)
    \n+
    338 {
    \n+
    339 _preconditioner->apply(v,d);
    \n+
    340 _communication.copyOwnerToAll(v,v);
    \n+
    341 }
    \n+
    342
    \n+
    343 template<bool forward>
    \n+
    344 void apply (X& v, const Y& d)
    \n+
    345 {
    \n+
    346 _preconditioner->template apply<forward>(v,d);
    \n+
    347 _communication.copyOwnerToAll(v,v);
    \n+
    348 }
    \n+
    349
    \n+
    355 virtual void post (X& x)
    \n+
    356 {
    \n+
    357 _preconditioner->post(x);
    \n+
    358 }
    \n+
    359
    \n+\n+
    362 {
    \n+\n+
    364 }
    \n+
    365
    \n+
    366 private:
    \n+
    368 std::shared_ptr<P> _preconditioner;
    \n
    369
    \n-\n-
    372 {
    \n-\n-
    374 }
    \n-
    375
    \n-
    376 private:
    \n-
    378 const M& _A_;
    \n-
    380 int _n;
    \n-\n-
    383 };
    \n-
    384 DUNE_REGISTER_PRECONDITIONER("sor", defaultPreconditionerBlockLevelCreator<Dune::SeqSOR>());
    \n-
    385
    \n-
    386
    \n-
    397 template<class M, class X, class Y, int l=1>
    \n-\n-
    399 DUNE_REGISTER_PRECONDITIONER("gs", defaultPreconditionerBlockLevelCreator<Dune::SeqGS>());
    \n-
    400
    \n-
    411 template<class M, class X, class Y, int l=1>
    \n-\n-
    413 public:
    \n-
    415 typedef M matrix_type;
    \n-
    417 typedef X domain_type;
    \n-
    419 typedef Y range_type;
    \n-
    421 typedef typename X::field_type field_type;
    \n-
    423 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    425 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    426
    \n-
    434 SeqJac (const M& A, int n, real_field_type w)
    \n-
    435 : _A_(A), _n(n), _w(w)
    \n-
    436 {
    \n-\n-
    438 }
    \n-
    439
    \n-
    453 SeqJac (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n-
    454 : SeqJac(A->getmat(), configuration)
    \n-
    455 {}
    \n-
    456
    \n-
    470 SeqJac (const M& A, const ParameterTree& configuration)
    \n-
    471 : SeqJac(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n-
    472 {}
    \n-
    473
    \n-
    479 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n-
    480 {}
    \n-
    481
    \n-
    487 virtual void apply (X& v, const Y& d)
    \n-
    488 {
    \n-
    489 for (int i=0; i<_n; i++) {
    \n-
    490 dbjac(_A_,v,d,_w,BL<l>());
    \n-
    491 }
    \n-
    492 }
    \n-
    493
    \n-
    499 virtual void post ([[maybe_unused]] X& x)
    \n-
    500 {}
    \n-
    501
    \n-\n-
    504 {
    \n-\n-
    506 }
    \n-
    507
    \n-
    508 private:
    \n-
    510 const M& _A_;
    \n-
    512 int _n;
    \n-
    514 real_field_type _w;
    \n-
    515 };
    \n-
    516 DUNE_REGISTER_PRECONDITIONER("jac", defaultPreconditionerBlockLevelCreator<Dune::SeqJac>());
    \n-
    517
    \n-
    518
    \n-
    519
    \n-
    531 template<class M, class X, class Y, int l=1>
    \n-\n-
    533 public:
    \n-
    535 typedef typename std::remove_const<M>::type matrix_type;
    \n-
    537 typedef typename matrix_type :: block_type block_type;
    \n-
    539 typedef X domain_type;
    \n-
    541 typedef Y range_type;
    \n-
    542
    \n-
    544 typedef typename X::field_type field_type;
    \n-
    545
    \n-
    547 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    549 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    550
    \n-\n-
    553
    \n-
    561 SeqILU (const M& A, real_field_type w, const bool resort = false )
    \n-
    562 : SeqILU( A, 0, w, resort ) // construct ILU(0)
    \n-
    563 {
    \n-
    564 }
    \n-
    565
    \n-
    580 SeqILU (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n-
    581 : SeqILU(A->getmat(), configuration)
    \n-
    582 {}
    \n-
    583
    \n-
    598 SeqILU(const M& A, const ParameterTree& config)
    \n-
    599 : SeqILU(A, config.get("n", 0),
    \n-
    600 config.get<real_field_type>("relaxation", 1.0),
    \n-
    601 config.get("resort", false))
    \n-
    602 {}
    \n-
    603
    \n-
    612 SeqILU (const M& A, int n, real_field_type w, const bool resort = false )
    \n-
    613 : ILU_(),
    \n-
    614 lower_(),
    \n-
    615 upper_(),
    \n-
    616 inv_(),
    \n-
    617 w_(w),
    \n-
    618 wNotIdentity_([w]{using std::abs; return abs(w - real_field_type(1)) > 1e-15;}() )
    \n-
    619 {
    \n-
    620 if( n == 0 )
    \n-
    621 {
    \n-
    622 // copy A
    \n-
    623 ILU_.reset( new matrix_type( A ) );
    \n-
    624 // create ILU(0) decomposition
    \n-\n-
    626 }
    \n-
    627 else
    \n-
    628 {
    \n-
    629 // create matrix in build mode
    \n-
    630 ILU_.reset( new matrix_type( A.N(), A.M(), matrix_type::row_wise) );
    \n-
    631 // create ILU(n) decomposition
    \n-
    632 ILU::blockILUDecomposition( A, n, *ILU_ );
    \n-
    633 }
    \n-
    634
    \n-
    635 if( resort )
    \n-
    636 {
    \n-
    637 // store ILU in simple CRS format
    \n-
    638 ILU::convertToCRS( *ILU_, lower_, upper_, inv_ );
    \n-
    639 ILU_.reset();
    \n-
    640 }
    \n-
    641 }
    \n-
    642
    \n-
    648 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n-
    649 {}
    \n-
    650
    \n-
    656 virtual void apply (X& v, const Y& d)
    \n-
    657 {
    \n-
    658 if( ILU_ )
    \n-
    659 {
    \n-
    660 ILU::blockILUBacksolve( *ILU_, v, d);
    \n-
    661 }
    \n-
    662 else
    \n-
    663 {
    \n-
    664 ILU::blockILUBacksolve(lower_, upper_, inv_, v, d);
    \n-
    665 }
    \n-
    666
    \n-
    667 if( wNotIdentity_ )
    \n-
    668 {
    \n-
    669 v *= w_;
    \n-
    670 }
    \n-
    671 }
    \n-
    672
    \n-
    678 virtual void post ([[maybe_unused]] X& x)
    \n-
    679 {}
    \n-
    680
    \n-\n-
    683 {
    \n-\n-
    685 }
    \n-
    686
    \n-
    687 protected:
    \n-
    689 std::unique_ptr< matrix_type > ILU_;
    \n-
    690
    \n-\n-\n-
    694 std::vector< block_type, typename matrix_type::allocator_type > inv_;
    \n-
    695
    \n-\n-
    699 const bool wNotIdentity_;
    \n-
    700 };
    \n-
    701 DUNE_REGISTER_PRECONDITIONER("ilu", defaultPreconditionerBlockLevelCreator<Dune::SeqILU>());
    \n-
    702
    \n-
    703
    \n-
    712 template<class X, class Y>
    \n-
    713 class Richardson : public Preconditioner<X,Y> {
    \n-
    714 public:
    \n-
    716 typedef X domain_type;
    \n-
    718 typedef Y range_type;
    \n-
    720 typedef typename X::field_type field_type;
    \n-
    722 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    724 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    725
    \n-\n-
    732 _w(w)
    \n-
    733 {}
    \n-
    734
    \n-
    746 Richardson (const ParameterTree& configuration)
    \n-
    747 : Richardson(configuration.get<real_field_type>("relaxation", 1.0))
    \n-
    748 {}
    \n-
    749
    \n-
    755 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n-
    756 {}
    \n-
    757
    \n-
    763 virtual void apply (X& v, const Y& d)
    \n-
    764 {
    \n-
    765 v = d;
    \n-
    766 v *= _w;
    \n-
    767 }
    \n-
    768
    \n-
    774 virtual void post ([[maybe_unused]] X& x)
    \n-
    775 {}
    \n-
    776
    \n-\n-
    779 {
    \n-\n-
    781 }
    \n-
    782
    \n-
    783 private:
    \n-\n-
    786 };
    \n-
    787 DUNE_REGISTER_PRECONDITIONER("richardson", [](auto tl, const auto& /* mat */, const ParameterTree& config){
    \n-
    788 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;
    \n-
    789 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;
    \n-
    790 return std::make_shared<Richardson<D,R>>(config);
    \n-
    791 });
    \n-
    792
    \n-
    793
    \n-
    804 template< class M, class X, class Y >
    \n-\n-
    806 : public Preconditioner< X, Y >
    \n-
    807 {
    \n-
    808 typedef SeqILDL< M, X, Y > This;
    \n-\n-
    810
    \n-
    811 public:
    \n-
    813 typedef std::remove_const_t< M > matrix_type;
    \n-
    815 typedef X domain_type;
    \n-
    817 typedef Y range_type;
    \n-
    819 typedef typename X::field_type field_type;
    \n-
    821 typedef Simd::Scalar<field_type> scalar_field_type;
    \n-
    823 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n-
    824
    \n-
    837 SeqILDL (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n-
    838 : SeqILDL(A->getmat(), configuration)
    \n-
    839 {}
    \n-
    840
    \n-
    853 SeqILDL(const matrix_type& A, const ParameterTree& config)
    \n-
    854 : SeqILDL(A, config.get<real_field_type>("relaxation", 1.0))
    \n-
    855 {}
    \n-
    856
    \n-
    865 explicit SeqILDL ( const matrix_type &A, real_field_type relax = real_field_type( 1 ) )
    \n-
    866 : decomposition_( A.N(), A.M(), matrix_type::random ),
    \n-
    867 relax_( relax )
    \n-
    868 {
    \n-
    869 // setup row sizes for lower triangular matrix
    \n-
    870 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n-
    871 {
    \n-
    872 const auto &A_i = *i;
    \n-
    873 const auto ij = A_i.find( i.index() );
    \n-
    874 if( ij != A_i.end() )
    \n-
    875 decomposition_.setrowsize( i.index(), ij.offset()+1 );
    \n-
    876 else
    \n-
    877 DUNE_THROW( ISTLError, "diagonal entry missing" );
    \n-
    878 }
    \n-
    879 decomposition_.endrowsizes();
    \n-
    880
    \n-
    881 // setup row indices for lower triangular matrix
    \n-
    882 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n-
    883 {
    \n-
    884 const auto &A_i = *i;
    \n-
    885 for( auto ij = A_i.begin(); ij.index() < i.index() ; ++ij )
    \n-
    886 decomposition_.addindex( i.index(), ij.index() );
    \n-
    887 decomposition_.addindex( i.index(), i.index() );
    \n-
    888 }
    \n-
    889 decomposition_.endindices();
    \n-
    890
    \n-
    891 // copy values of lower triangular matrix
    \n-
    892 auto i = A.begin();
    \n-
    893 for( auto row = decomposition_.begin(), rowend = decomposition_.end(); row != rowend; ++row, ++i )
    \n-
    894 {
    \n-
    895 auto ij = i->begin();
    \n-
    896 for( auto col = row->begin(), colend = row->end(); col != colend; ++col, ++ij )
    \n-
    897 *col = *ij;
    \n-
    898 }
    \n-
    899
    \n-
    900 // perform ILDL decomposition
    \n-
    901 bildl_decompose( decomposition_ );
    \n-
    902 }
    \n-
    903
    \n-
    905 void pre ([[maybe_unused]] X &x, [[maybe_unused]] Y &b) override
    \n-
    906 {}
    \n-
    907
    \n-
    909 void apply ( X &v, const Y &d ) override
    \n-
    910 {
    \n-
    911 bildl_backsolve( decomposition_, v, d, true );
    \n-
    912 v *= relax_;
    \n-
    913 }
    \n-
    914
    \n-
    916 void post ([[maybe_unused]] X &x) override
    \n-
    917 {}
    \n-
    918
    \n-\n-
    921
    \n-
    922 private:
    \n-
    923 matrix_type decomposition_;
    \n-
    924 real_field_type relax_;
    \n-
    925 };
    \n-
    926 DUNE_REGISTER_PRECONDITIONER("ildl", defaultPreconditionerCreator<Dune::SeqILDL>());
    \n-
    927
    \n-
    930} // end namespace
    \n-
    931
    \n-
    932
    \n-
    933#endif
    \n-
    Incomplete LDL decomposition.
    \n-
    Some handy generic functions for ISTL matrices.
    \n-
    Define general, extensible interface for inverse operators.
    \n-\n-\n-
    The incomplete LU factorization kernels.
    \n-\n-\n-
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    371 const communication_type& _communication;
    \n+
    372 };
    \n+
    373
    \n+
    376} // end namespace
    \n+
    377
    \n+
    378#endif
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n+\n+
    Define base class for scalar product and norm.
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+
    Implementations of the inverse operator interface.
    \n+
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    The incomplete LU factorization kernels.
    \n+
    Define general preconditioner interface.
    \n
    void bsorb(const M &A, X &x, const Y &b, const K &w)
    SSOR step.
    Definition: gsetc.hh:646
    \n-
    void dbjac(const M &A, X &x, const Y &b, const K &w)
    Jacobi step.
    Definition: gsetc.hh:658
    \n
    void bsorf(const M &A, X &x, const Y &b, const K &w)
    SOR step.
    Definition: gsetc.hh:634
    \n
    Definition: allocator.hh:11
    \n-
    void bildl_decompose(Matrix &A)
    compute ILDL decomposition of a symmetric matrix A
    Definition: ildl.hh:88
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    DUNE_REGISTER_PRECONDITIONER("amg", AMGCreator())
    \n-
    void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
    Definition: ildl.hh:149
    \n-
    void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)
    convert ILU decomposition into CRS format for lower and upper triangular and inverse.
    Definition: ilu.hh:307
    \n-
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n-
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n-
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n-
    compile-time parameter for block recursion depth
    Definition: gsetc.hh:45
    \n-\n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    size_type M() const
    Return the number of columns.
    Definition: matrix.hh:700
    \n-
    size_type N() const
    Return the number of rows.
    Definition: matrix.hh:695
    \n-
    static void check(const Matrix &mat)
    Check whether the a matrix has diagonal values on blocklevel recursion levels.
    Definition: matrixutils.hh:53
    \n+
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n+
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n+
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n+
    const communication_type & getCommunication() const
    Get the object responsible for communication.
    Definition: schwarz.hh:146
    \n+
    virtual const matrix_type & getmat() const
    get the sequential assembled linear operator.
    Definition: schwarz.hh:133
    \n+
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const
    apply operator to x, scale and add:
    Definition: schwarz.hh:125
    \n+
    virtual void apply(const X &x, Y &y) const
    apply operator to x:
    Definition: schwarz.hh:116
    \n+
    C communication_type
    The type of the communication object.
    Definition: schwarz.hh:98
    \n+
    X domain_type
    The type of the domain.
    Definition: schwarz.hh:86
    \n+
    M matrix_type
    The type of the matrix we operate on.
    Definition: schwarz.hh:81
    \n+
    Y range_type
    The type of the range.
    Definition: schwarz.hh:91
    \n+
    X::field_type field_type
    The field type of the range.
    Definition: schwarz.hh:93
    \n+
    OverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)
    constructor: just store a reference to a matrix.
    Definition: schwarz.hh:107
    \n+
    OverlappingSchwarzOperator(const std::shared_ptr< matrix_type > A, const communication_type &com)
    Definition: schwarz.hh:111
    \n+
    virtual SolverCategory::Category category() const
    Category of the linear operator (see SolverCategory::Category)
    Definition: schwarz.hh:139
    \n
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Turns an InverseOperator into a Preconditioner.
    Definition: preconditioners.hh:75
    \n-
    O::range_type range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:80
    \n-
    O::domain_type domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:78
    \n-
    virtual void post(domain_type &)
    Clean up.
    Definition: preconditioners.hh:111
    \n-
    range_type::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:82
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:86
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:84
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:115
    \n-
    virtual void pre(domain_type &, range_type &)
    Prepare the preconditioner.
    Definition: preconditioners.hh:101
    \n-
    InverseOperator2Preconditioner(InverseOperator &inverse_operator)
    Construct the preconditioner from the solver.
    Definition: preconditioners.hh:94
    \n-
    O InverseOperator
    type of the wrapped inverse operator
    Definition: preconditioners.hh:88
    \n-
    virtual void apply(domain_type &v, const range_type &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: preconditioners.hh:104
    \n-
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:229
    \n-
    SeqSSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:182
    \n-
    SeqSSOR(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:199
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:233
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:150
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:152
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:146
    \n-
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:144
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:216
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:208
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:148
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:154
    \n-
    SeqSSOR(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:163
    \n-
    Sequential SOR preconditioner.
    Definition: preconditioners.hh:261
    \n-
    SeqSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:302
    \n-
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:264
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:274
    \n-
    void apply(X &v, const Y &d)
    Apply the preconditioner in a special direction.
    Definition: preconditioners.hh:350
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:266
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:367
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:328
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:272
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:371
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:336
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:268
    \n-
    SeqSOR(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:319
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:270
    \n-
    SeqSOR(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:283
    \n-
    The sequential jacobian preconditioner.
    Definition: preconditioners.hh:412
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:499
    \n-
    SeqJac(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:470
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:487
    \n-
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:415
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:423
    \n-
    SeqJac(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:453
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:421
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:479
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:417
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:425
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:503
    \n-
    SeqJac(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:434
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:419
    \n-
    Sequential ILU preconditioner.
    Definition: preconditioners.hh:532
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:678
    \n-
    SeqILU(const M &A, int n, real_field_type w, const bool resort=false)
    Constructor.
    Definition: preconditioners.hh:612
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:648
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:656
    \n-
    ILU::CRS< block_type, typename M::allocator_type > CRS
    type of ILU storage
    Definition: preconditioners.hh:552
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:541
    \n-
    CRS lower_
    The ILU(n) decomposition of the matrix. As storage a CRS structure is used.
    Definition: preconditioners.hh:692
    \n-
    const bool wNotIdentity_
    true if w != 1.0
    Definition: preconditioners.hh:699
    \n-
    SeqILU(const M &A, const ParameterTree &config)
    Constructor.
    Definition: preconditioners.hh:598
    \n-
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:535
    \n-
    matrix_type::block_type block_type
    block type of matrix
    Definition: preconditioners.hh:537
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:549
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:544
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:682
    \n-
    SeqILU(const M &A, real_field_type w, const bool resort=false)
    Constructor.
    Definition: preconditioners.hh:561
    \n-
    const real_field_type w_
    The relaxation factor to use.
    Definition: preconditioners.hh:697
    \n-
    SeqILU(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:580
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:539
    \n-
    std::vector< block_type, typename matrix_type::allocator_type > inv_
    Definition: preconditioners.hh:694
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:547
    \n-
    std::unique_ptr< matrix_type > ILU_
    The ILU(n) decomposition of the matrix. As storage a BCRSMatrix is used.
    Definition: preconditioners.hh:689
    \n-
    CRS upper_
    Definition: preconditioners.hh:693
    \n-
    Richardson preconditioner.
    Definition: preconditioners.hh:713
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:720
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:778
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:718
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:755
    \n-
    Richardson(real_field_type w=1.0)
    Constructor.
    Definition: preconditioners.hh:731
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:774
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:724
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:722
    \n-
    Richardson(const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:746
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:716
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the precondioner.
    Definition: preconditioners.hh:763
    \n-
    sequential ILDL preconditioner
    Definition: preconditioners.hh:807
    \n-
    SeqILDL(const matrix_type &A, const ParameterTree &config)
    Constructor.
    Definition: preconditioners.hh:853
    \n-
    SeqILDL(const matrix_type &A, real_field_type relax=real_field_type(1))
    constructor
    Definition: preconditioners.hh:865
    \n-
    X domain_type
    domain type of the preconditioner
    Definition: preconditioners.hh:815
    \n-
    void post(X &x) override
    Clean up.
    Definition: preconditioners.hh:916
    \n-
    Y range_type
    range type of the preconditioner
    Definition: preconditioners.hh:817
    \n-
    std::remove_const_t< M > matrix_type
    type of matrix the preconditioner is for
    Definition: preconditioners.hh:813
    \n-
    void apply(X &v, const Y &d) override
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: preconditioners.hh:909
    \n-
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:823
    \n-
    SeqILDL(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:837
    \n-
    void pre(X &x, Y &b) override
    Prepare the preconditioner.
    Definition: preconditioners.hh:905
    \n-
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:821
    \n-
    X::field_type field_type
    field type of the preconditioner
    Definition: preconditioners.hh:819
    \n-
    SolverCategory::Category category() const override
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:920
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n+
    A parallel SSOR preconditioner.
    Definition: schwarz.hh:175
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: schwarz.hh:184
    \n+
    C communication_type
    The type of the communication object.
    Definition: schwarz.hh:186
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: schwarz.hh:233
    \n+
    ParSSOR(const matrix_type &A, int n, field_type w, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:197
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: schwarz.hh:230
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:180
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:182
    \n+
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: schwarz.hh:178
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the precondtioner.
    Definition: schwarz.hh:216
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: schwarz.hh:206
    \n+
    Block parallel preconditioner.
    Definition: schwarz.hh:278
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: schwarz.hh:326
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:285
    \n+
    BlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:317
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: schwarz.hh:337
    \n+
    BlockPreconditioner(P &p, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:306
    \n+
    void apply(X &v, const Y &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: schwarz.hh:344
    \n+
    C communication_type
    The type of the communication object..
    Definition: schwarz.hh:297
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: schwarz.hh:292
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: schwarz.hh:355
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:290
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: schwarz.hh:361
    \n
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1026 +4,408 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-preconditioners.hh\n+schwarz.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_PRECONDITIONERS_HH\n- 6#define DUNE_ISTL_PRECONDITIONERS_HH\n+ 5#ifndef DUNE_ISTL_SCHWARZ_HH\n+ 6#define DUNE_ISTL_SCHWARZ_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n+ 8#include // for input/output to shell\n+ 9#include // for input/output to files\n+ 10#include // STL vector class\n+ 11#include \n+ 12\n+ 13#include // Yes, we do some math here\n 14\n- 15#include \n- 16#include \n- 17\n- 18#include \n- 19#include \"preconditioner.hh\"\n- 20#include \"solver.hh\"\n- 21#include \"solvercategory.hh\"\n- 22#include \"istlexception.hh\"\n- 23#include \"matrixutils.hh\"\n- 24#include \"gsetc.hh\"\n- 25#include \"ildl.hh\"\n- 26#include \"ilu.hh\"\n- 27\n- 28\n- 29namespace Dune {\n- 72 template\n-73 class InverseOperator2Preconditioner :\n- 74 public Preconditioner\n+ 15#include \n+ 16\n+ 17#include \"io.hh\"\n+ 18#include \"bvector.hh\"\n+ 19#include \"vbvector.hh\"\n+ 20#include \"bcrsmatrix.hh\"\n+ 21#include \"io.hh\"\n+ 22#include \"gsetc.hh\"\n+ 23#include \"ilu.hh\"\n+ 24#include \"operators.hh\"\n+ 25#include \"solvers.hh\"\n+ 26#include \"preconditioners.hh\"\n+ 27#include \"scalarproducts.hh\"\n+ 28#include \"owneroverlapcopy.hh\"\n+ 29\n+ 30namespace Dune {\n+ 31\n+ 73 template\n+74 class OverlappingSchwarzOperator : public AssembledLinearOperator\n 75 {\n 76 public:\n-78 typedef typename O::domain_type domain_type;\n-80 typedef typename O::range_type range_type;\n-82 typedef typename range_type::field_type field_type;\n-84 typedef Simd::Scalar scalar_field_type;\n-86 typedef typename FieldTraits::real_type real_field_type;\n-88 typedef O InverseOperator;\n- 89\n-94 InverseOperator2Preconditioner(InverseOperator& inverse_operator)\n- 95 : inverse_operator_(inverse_operator)\n- 96 {\n- 97 if(c != -1 && SolverCategory::category(inverse_operator_) != c)\n- 98 DUNE_THROW(InvalidStateException, \"User-supplied solver category does not\n-match that of the given inverse operator\");\n- 99 }\n- 100\n-101 virtual void pre(domain_type&,range_type&)\n- 102 {}\n- 103\n-104 virtual void apply(domain_type& v, const range_type& d)\n- 105 {\n- 106 InverseOperatorResult res;\n- 107 range_type copy(d);\n- 108 inverse_operator_.apply(v, copy, res);\n- 109 }\n+81 typedef M matrix_type;\n+86 typedef X domain_type;\n+91 typedef Y range_type;\n+93 typedef typename X::field_type field_type;\n+98 typedef C communication_type;\n+ 99\n+107 OverlappingSchwarzOperator (const matrix_type& A, const communication_type&\n+com)\n+ 108 : _A_(stackobject_to_shared_ptr(A)), communication(com)\n+ 109 {}\n 110\n-111 virtual void post(domain_type&)\n- 112 {}\n- 113\n-115 virtual SolverCategory::Category category() const\n- 116 {\n- 117 return SolverCategory::category(inverse_operator_);\n- 118 }\n- 119\n- 120 private:\n- 121 InverseOperator& inverse_operator_;\n- 122 };\n+111 OverlappingSchwarzOperator (const std::shared_ptr A, const\n+communication_type& com)\n+ 112 : _A_(A), communication(com)\n+ 113 {}\n+ 114\n+116 virtual void apply (const X& x, Y& y) const\n+ 117 {\n+ 118 y = 0;\n+ 119 _A_->umv(x,y); // result is consistent on interior+border\n+ 120 communication.project(y); // we want this here to avoid it before the\n+preconditioner\n+ 121 // since there d is const!\n+ 122 }\n 123\n- 124 //=====================================================================\n- 125 // Implementation of this interface for sequential ISTL-preconditioners\n- 126 //=====================================================================\n- 127\n- 128\n- 140 template\n-141 class SeqSSOR : public Preconditioner {\n- 142 public:\n-144 typedef M matrix_type;\n-146 typedef X domain_type;\n-148 typedef Y range_type;\n-150 typedef typename X::field_type field_type;\n-152 typedef Simd::Scalar scalar_field_type;\n-154 typedef typename FieldTraits::real_type real_field_type;\n- 155\n-163 SeqSSOR (const M& A, int n, real_field_type w)\n- 164 : _A_(A), _n(n), _w(w)\n- 165 {\n- 166 CheckIfDiagonalPresent::check(_A_);\n- 167 }\n- 168\n-182 SeqSSOR (const std::shared_ptr>& A,\n-const ParameterTree& configuration)\n- 183 : SeqSSOR(A->getmat(), configuration)\n- 184 {}\n- 185\n-199 SeqSSOR (const M& A, const ParameterTree& configuration)\n- 200 : SeqSSOR(A, configuration.get(\"iterations\",1),\n-configuration.get(\"relaxation\",1.0))\n- 201 {}\n- 202\n-208 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n- 209 {}\n+125 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n+ 126 {\n+ 127 _A_->usmv(alpha,x,y); // result is consistent on interior+border\n+ 128 communication.project(y); // we want this here to avoid it before the\n+preconditioner\n+ 129 // since there d is const!\n+ 130 }\n+ 131\n+133 virtual const matrix_type& getmat () const\n+ 134 {\n+ 135 return *_A_;\n+ 136 }\n+ 137\n+139 virtual SolverCategory::Category category() const\n+ 140 {\n+ 141 return SolverCategory::overlapping;\n+ 142 }\n+ 143\n+ 144\n+146 const communication_type& getCommunication() const\n+ 147 {\n+ 148 return communication;\n+ 149 }\n+ 150 private:\n+ 151 const std::shared_ptr_A_;\n+ 152 const communication_type& communication;\n+ 153 };\n+ 154\n+ 157 /*\n+ 158 * @addtogroup ISTL_Prec\n+ 159 * @{\n+ 160 */\n+ 174 template\n+175 class ParSSOR : public Preconditioner {\n+ 176 public:\n+178 typedef M matrix_type;\n+180 typedef X domain_type;\n+182 typedef Y range_type;\n+184 typedef typename X::field_type field_type;\n+186 typedef C communication_type;\n+ 187\n+197 ParSSOR (const matrix_type& A, int n, field_type w, const\n+communication_type& c)\n+ 198 : _A_(A), _n(n), _w(w), communication(c)\n+ 199 { }\n+ 200\n+206 virtual void pre (X& x, [[maybe_unused]] Y& b)\n+ 207 {\n+ 208 communication.copyOwnerToAll(x,x); // make dirichlet values consistent\n+ 209 }\n 210\n 216 virtual void apply (X& v, const Y& d)\n 217 {\n 218 for (int i=0; i<_n; i++) {\n- 219 bsorf(_A_,v,d,_w,BL());\n- 220 bsorb(_A_,v,d,_w,BL());\n+ 219 bsorf(_A_,v,d,_w);\n+ 220 bsorb(_A_,v,d,_w);\n 221 }\n- 222 }\n- 223\n-229 virtual void post ([[maybe_unused]] X& x)\n- 230 {}\n+ 222 communication.copyOwnerToAll(v,v);\n+ 223 }\n+ 224\n+230 virtual void post ([[maybe_unused]] X& x) {}\n 231\n 233 virtual SolverCategory::Category category() const\n 234 {\n- 235 return SolverCategory::sequential;\n+ 235 return SolverCategory::overlapping;\n 236 }\n 237\n 238 private:\n- 240 const M& _A_;\n+ 240 const matrix_type& _A_;\n 242 int _n;\n- 244 real_field_type _w;\n- 245 };\n-246 DUNE_REGISTER_PRECONDITIONER(\"ssor\",\n-defaultPreconditionerBlockLevelCreator());\n- 247\n+ 244 field_type _w;\n+246 const communication_type& communication;\n+ 247 };\n 248\n- 260 template\n-261 class SeqSOR : public Preconditioner {\n- 262 public:\n-264 typedef M matrix_type;\n-266 typedef X domain_type;\n-268 typedef Y range_type;\n-270 typedef typename X::field_type field_type;\n-272 typedef Simd::Scalar scalar_field_type;\n-274 typedef typename FieldTraits::real_type real_field_type;\n- 275\n-283 SeqSOR (const M& A, int n, real_field_type w)\n- 284 : _A_(A), _n(n), _w(w)\n- 285 {\n- 286 CheckIfDiagonalPresent::check(_A_);\n- 287 }\n- 288\n-302 SeqSOR (const std::shared_ptr>& A,\n-const ParameterTree& configuration)\n- 303 : SeqSOR(A->getmat(), configuration)\n- 304 {}\n- 305\n-319 SeqSOR (const M& A, const ParameterTree& configuration)\n- 320 : SeqSOR(A, configuration.get(\"iterations\",1),\n-configuration.get(\"relaxation\",1.0))\n- 321 {}\n- 322\n-328 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n- 329 {}\n- 330\n-336 virtual void apply (X& v, const Y& d)\n- 337 {\n- 338 this->template apply(v,d);\n- 339 }\n- 340\n- 349 template\n-350 void apply(X& v, const Y& d)\n- 351 {\n- 352 if(forward)\n- 353 for (int i=0; i<_n; i++) {\n- 354 bsorf(_A_,v,d,_w,BL());\n- 355 }\n- 356 else\n- 357 for (int i=0; i<_n; i++) {\n- 358 bsorb(_A_,v,d,_w,BL());\n- 359 }\n- 360 }\n- 361\n-367 virtual void post ([[maybe_unused]] X& x)\n- 368 {}\n+ 249 namespace Amg\n+ 250 {\n+ 251 template struct ConstructionTraits;\n+ 252 }\n+ 253\n+ 277 template >\n+278 class BlockPreconditioner : public Preconditioner {\n+ 279 friend struct Amg::ConstructionTraits >;\n+ 280 public:\n+285 typedef X domain_type;\n+290 typedef Y range_type;\n+292 typedef typename X::field_type field_type;\n+297 typedef C communication_type;\n+ 298\n+306 BlockPreconditioner (P& p, const communication_type& c)\n+ 307 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)\n+ 308 { }\n+ 309\n+317 BlockPreconditioner (const std::shared_ptr

    & p, const communication_type&\n+c)\n+ 318 : _preconditioner(p), _communication(c)\n+ 319 { }\n+ 320\n+326 virtual void pre (X& x, Y& b)\n+ 327 {\n+ 328 _communication.copyOwnerToAll(x,x); // make dirichlet values consistent\n+ 329 _preconditioner->pre(x,b);\n+ 330 }\n+ 331\n+337 virtual void apply (X& v, const Y& d)\n+ 338 {\n+ 339 _preconditioner->apply(v,d);\n+ 340 _communication.copyOwnerToAll(v,v);\n+ 341 }\n+ 342\n+ 343 template\n+344 void apply (X& v, const Y& d)\n+ 345 {\n+ 346 _preconditioner->template apply(v,d);\n+ 347 _communication.copyOwnerToAll(v,v);\n+ 348 }\n+ 349\n+355 virtual void post (X& x)\n+ 356 {\n+ 357 _preconditioner->post(x);\n+ 358 }\n+ 359\n+361 virtual SolverCategory::Category category() const\n+ 362 {\n+ 363 return SolverCategory::overlapping;\n+ 364 }\n+ 365\n+ 366 private:\n+ 368 std::shared_ptr

    _preconditioner;\n 369\n-371 virtual SolverCategory::Category category() const\n- 372 {\n- 373 return SolverCategory::sequential;\n- 374 }\n- 375\n- 376 private:\n- 378 const M& _A_;\n- 380 int _n;\n- 382 real_field_type _w;\n- 383 };\n-384 DUNE_REGISTER_PRECONDITIONER(\"sor\",\n-defaultPreconditionerBlockLevelCreator());\n- 385\n- 386\n- 397 template\n-398 using SeqGS = SeqSOR;\n-399 DUNE_REGISTER_PRECONDITIONER(\"gs\",\n-defaultPreconditionerBlockLevelCreator());\n- 400\n- 411 template\n-412 class SeqJac : public Preconditioner {\n- 413 public:\n-415 typedef M matrix_type;\n-417 typedef X domain_type;\n-419 typedef Y range_type;\n-421 typedef typename X::field_type field_type;\n-423 typedef Simd::Scalar scalar_field_type;\n-425 typedef typename FieldTraits::real_type real_field_type;\n- 426\n-434 SeqJac (const M& A, int n, real_field_type w)\n- 435 : _A_(A), _n(n), _w(w)\n- 436 {\n- 437 CheckIfDiagonalPresent::check(_A_);\n- 438 }\n- 439\n-453 SeqJac (const std::shared_ptr>& A,\n-const ParameterTree& configuration)\n- 454 : SeqJac(A->getmat(), configuration)\n- 455 {}\n- 456\n-470 SeqJac (const M& A, const ParameterTree& configuration)\n- 471 : SeqJac(A, configuration.get(\"iterations\",1),\n-configuration.get(\"relaxation\",1.0))\n- 472 {}\n- 473\n-479 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n- 480 {}\n- 481\n-487 virtual void apply (X& v, const Y& d)\n- 488 {\n- 489 for (int i=0; i<_n; i++) {\n- 490 dbjac(_A_,v,d,_w,BL());\n- 491 }\n- 492 }\n- 493\n-499 virtual void post ([[maybe_unused]] X& x)\n- 500 {}\n- 501\n-503 virtual SolverCategory::Category category() const\n- 504 {\n- 505 return SolverCategory::sequential;\n- 506 }\n- 507\n- 508 private:\n- 510 const M& _A_;\n- 512 int _n;\n- 514 real_field_type _w;\n- 515 };\n-516 DUNE_REGISTER_PRECONDITIONER(\"jac\",\n-defaultPreconditionerBlockLevelCreator());\n- 517\n- 518\n- 519\n- 531 template\n-532 class SeqILU : public Preconditioner {\n- 533 public:\n-535 typedef typename std::remove_const::type matrix_type;\n-537 typedef typename matrix_type :: block_type block_type;\n-539 typedef X domain_type;\n-541 typedef Y range_type;\n- 542\n-544 typedef typename X::field_type field_type;\n- 545\n-547 typedef Simd::Scalar scalar_field_type;\n-549 typedef typename FieldTraits::real_type real_field_type;\n- 550\n-552 typedef typename ILU::CRS<_block_type_,_typename_M::allocator_type> CRS;\n- 553\n-561 SeqILU (const M& A, real_field_type w, const bool resort = false )\n- 562 : SeqILU( A, 0, w, resort ) // construct ILU(0)\n- 563 {\n- 564 }\n- 565\n-580 SeqILU (const std::shared_ptr>& A,\n-const ParameterTree& configuration)\n- 581 : SeqILU(A->getmat(), configuration)\n- 582 {}\n- 583\n-598 SeqILU(const M& A, const ParameterTree& config)\n- 599 : SeqILU(A, config.get(\"n\", 0),\n- 600 config.get(\"relaxation\", 1.0),\n- 601 config.get(\"resort\", false))\n- 602 {}\n- 603\n-612 SeqILU (const M& A, int n, real_field_type w, const bool resort = false )\n- 613 : ILU_(),\n- 614 lower_(),\n- 615 upper_(),\n- 616 inv_(),\n- 617 w_(w),\n- 618 wNotIdentity_([w]{using std::abs; return abs(w - real_field_type(1)) > 1e-\n-15;}() )\n- 619 {\n- 620 if( n == 0 )\n- 621 {\n- 622 // copy A\n- 623 ILU_.reset( new matrix_type( A ) );\n- 624 // create ILU(0) decomposition\n- 625 ILU::blockILU0Decomposition( *ILU_ );\n- 626 }\n- 627 else\n- 628 {\n- 629 // create matrix in build mode\n- 630 ILU_.reset( new matrix_type( A.N(), A.M(), matrix_type::row_wise) );\n- 631 // create ILU(n) decomposition\n- 632 ILU::blockILUDecomposition( A, n, *ILU_ );\n- 633 }\n- 634\n- 635 if( resort )\n- 636 {\n- 637 // store ILU in simple CRS format\n- 638 ILU::convertToCRS( *ILU_, lower_, upper_, inv_ );\n- 639 ILU_.reset();\n- 640 }\n- 641 }\n- 642\n-648 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n- 649 {}\n- 650\n-656 virtual void apply (X& v, const Y& d)\n- 657 {\n- 658 if( ILU_ )\n- 659 {\n- 660 ILU::blockILUBacksolve( *ILU_, v, d);\n- 661 }\n- 662 else\n- 663 {\n- 664 ILU::blockILUBacksolve(lower_, upper_, inv_, v, d);\n- 665 }\n- 666\n- 667 if( wNotIdentity_ )\n- 668 {\n- 669 v *= w_;\n- 670 }\n- 671 }\n- 672\n-678 virtual void post ([[maybe_unused]] X& x)\n- 679 {}\n- 680\n-682 virtual SolverCategory::Category category() const\n- 683 {\n- 684 return SolverCategory::sequential;\n- 685 }\n- 686\n- 687 protected:\n-689 std::unique_ptr< matrix_type > ILU_;\n- 690\n-692 CRS lower_;\n-693 CRS upper_;\n-694 std::vector< block_type, typename matrix_type::allocator_type > inv_;\n- 695\n-697 const real_field_type w_;\n-699 const bool wNotIdentity_;\n- 700 };\n-701 DUNE_REGISTER_PRECONDITIONER(\"ilu\",\n-defaultPreconditionerBlockLevelCreator());\n- 702\n- 703\n- 712 template\n-713 class Richardson : public Preconditioner {\n- 714 public:\n-716 typedef X domain_type;\n-718 typedef Y range_type;\n-720 typedef typename X::field_type field_type;\n-722 typedef Simd::Scalar scalar_field_type;\n-724 typedef typename FieldTraits::real_type real_field_type;\n- 725\n-731 Richardson (real_field_type w=1.0) :\n- 732 _w(w)\n- 733 {}\n- 734\n-746 Richardson (const ParameterTree& configuration)\n- 747 : Richardson(configuration.get(\"relaxation\", 1.0))\n- 748 {}\n- 749\n-755 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n- 756 {}\n- 757\n-763 virtual void apply (X& v, const Y& d)\n- 764 {\n- 765 v = d;\n- 766 v *= _w;\n- 767 }\n- 768\n-774 virtual void post ([[maybe_unused]] X& x)\n- 775 {}\n- 776\n-778 virtual SolverCategory::Category category() const\n- 779 {\n- 780 return SolverCategory::sequential;\n- 781 }\n- 782\n- 783 private:\n- 785 real_field_type _w;\n- 786 };\n-787 DUNE_REGISTER_PRECONDITIONER(\"richardson\", [](auto tl, const auto& /* mat\n-*/, const ParameterTree& config){\n- 788 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;\n- 789 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;\n- 790 return std::make_shared>(config);\n- 791 });\n- 792\n- 793\n- 804 template< class M, class X, class Y >\n-805 class SeqILDL\n- 806 : public Preconditioner< X, Y >\n- 807 {\n- 808 typedef SeqILDL<_M,_X,_Y_> This;\n- 809 typedef Preconditioner<_X,_Y_> Base;\n- 810\n- 811 public:\n-813 typedef std::remove_const_t< M > matrix_type;\n-815 typedef X domain_type;\n-817 typedef Y range_type;\n-819 typedef typename X::field_type field_type;\n-821 typedef Simd::Scalar scalar_field_type;\n-823 typedef typename FieldTraits::real_type real_field_type;\n- 824\n-837 SeqILDL (const std::shared_ptr>& A,\n-const ParameterTree& configuration)\n- 838 : SeqILDL(A->getmat(), configuration)\n- 839 {}\n- 840\n-853 SeqILDL(const matrix_type& A, const ParameterTree& config)\n- 854 : SeqILDL(A, config.get(\"relaxation\", 1.0))\n- 855 {}\n- 856\n-865 explicit SeqILDL ( const matrix_type &A, real_field_type relax =\n-real_field_type( 1 ) )\n- 866 : decomposition_( A.N(), A.M(), matrix_type::random ),\n- 867 relax_( relax )\n- 868 {\n- 869 // setup row sizes for lower triangular matrix\n- 870 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 871 {\n- 872 const auto &A_i = *i;\n- 873 const auto ij = A_i.find( i.index() );\n- 874 if( ij != A_i.end() )\n- 875 decomposition_.setrowsize( i.index(), ij.offset()+1 );\n- 876 else\n- 877 DUNE_THROW( ISTLError, \"diagonal entry missing\" );\n- 878 }\n- 879 decomposition_.endrowsizes();\n- 880\n- 881 // setup row indices for lower triangular matrix\n- 882 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n- 883 {\n- 884 const auto &A_i = *i;\n- 885 for( auto ij = A_i.begin(); ij.index() < i.index() ; ++ij )\n- 886 decomposition_.addindex( i.index(), ij.index() );\n- 887 decomposition_.addindex( i.index(), i.index() );\n- 888 }\n- 889 decomposition_.endindices();\n- 890\n- 891 // copy values of lower triangular matrix\n- 892 auto i = A.begin();\n- 893 for( auto row = decomposition_.begin(), rowend = decomposition_.end(); row\n-!= rowend; ++row, ++i )\n- 894 {\n- 895 auto ij = i->begin();\n- 896 for( auto col = row->begin(), colend = row->end(); col != colend; ++col,\n-++ij )\n- 897 *col = *ij;\n- 898 }\n- 899\n- 900 // perform ILDL decomposition\n- 901 bildl_decompose( decomposition_ );\n- 902 }\n- 903\n-905 void pre ([[maybe_unused]] X &x, [[maybe_unused]] Y &b) override\n- 906 {}\n- 907\n-909 void apply ( X &v, const Y &d ) override\n- 910 {\n- 911 bildl_backsolve( decomposition_, v, d, true );\n- 912 v *= relax_;\n- 913 }\n- 914\n-916 void post ([[maybe_unused]] X &x) override\n- 917 {}\n- 918\n-920 SolverCategory::Category category () const override { return\n-SolverCategory::sequential; }\n- 921\n- 922 private:\n- 923 matrix_type decomposition_;\n- 924 real_field_type relax_;\n- 925 };\n-926 DUNE_REGISTER_PRECONDITIONER(\"ildl\", defaultPreconditionerCreator());\n- 927\n- 930} // end namespace\n- 931\n- 932\n- 933#endif\n-ildl.hh\n-Incomplete LDL decomposition.\n-matrixutils.hh\n-Some handy generic functions for ISTL matrices.\n-solver.hh\n-Define general, extensible interface for inverse operators.\n-solverregistry.hh\n-preconditioner.hh\n-ilu.hh\n-The incomplete LU factorization kernels.\n-istlexception.hh\n-solvercategory.hh\n+ 371 const communication_type& _communication;\n+ 372 };\n+ 373\n+ 376} // end namespace\n+ 377\n+ 378#endif\n+io.hh\n+Some generic functions for pretty printing vectors and matrices.\n+vbvector.hh\n+???\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+solvers.hh\n+Implementations of the inverse operator interface.\n gsetc.hh\n Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n generic way.\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+ilu.hh\n+The incomplete LU factorization kernels.\n+preconditioners.hh\n+Define general preconditioner interface.\n Dune::bsorb\n void bsorb(const M &A, X &x, const Y &b, const K &w)\n SSOR step.\n Definition: gsetc.hh:646\n-Dune::dbjac\n-void dbjac(const M &A, X &x, const Y &b, const K &w)\n-Jacobi step.\n-Definition: gsetc.hh:658\n Dune::bsorf\n void bsorf(const M &A, X &x, const Y &b, const K &w)\n SOR step.\n Definition: gsetc.hh:634\n Dune\n Definition: allocator.hh:11\n-Dune::bildl_decompose\n-void bildl_decompose(Matrix &A)\n-compute ILDL decomposition of a symmetric matrix A\n-Definition: ildl.hh:88\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::DUNE_REGISTER_PRECONDITIONER\n-DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator())\n-Dune::bildl_backsolve\n-void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool\n-isLowerTriangular=false)\n-Definition: ildl.hh:149\n-Dune::ILU::convertToCRS\n-void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)\n-convert ILU decomposition into CRS format for lower and upper triangular and\n-inverse.\n-Definition: ilu.hh:307\n-Dune::ILU::blockILUBacksolve\n-void blockILUBacksolve(const M &A, X &v, const Y &d)\n-LU backsolve with stored inverse.\n-Definition: ilu.hh:94\n-Dune::ILU::blockILU0Decomposition\n-void blockILU0Decomposition(M &A)\n-compute ILU decomposition of A. A is overwritten by its decomposition\n-Definition: ilu.hh:33\n-Dune::ILU::blockILUDecomposition\n-void blockILUDecomposition(const M &A, int n, M &ILU)\n-Definition: ilu.hh:167\n-Dune::BL\n-compile-time parameter for block recursion depth\n-Definition: gsetc.hh:45\n-Dune::ILU::CRS<_block_type,_typename_M::allocator_type_>\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::Matrix::M\n-size_type M() const\n-Return the number of columns.\n-Definition: matrix.hh:700\n-Dune::Matrix::N\n-size_type N() const\n-Return the number of rows.\n-Definition: matrix.hh:695\n-Dune::CheckIfDiagonalPresent::check\n-static void check(const Matrix &mat)\n-Check whether the a matrix has diagonal values on blocklevel recursion levels.\n-Definition: matrixutils.hh:53\n+Dune::Amg::ConstructionTraits\n+Traits class for generically constructing non default constructable types.\n+Definition: construction.hh:39\n+Dune::LinearOperator::field_type\n+X::field_type field_type\n+The field type of the operator.\n+Definition: operators.hh:74\n Dune::AssembledLinearOperator\n A linear operator exporting itself in matrix form.\n Definition: operators.hh:109\n+Dune::OverlappingSchwarzOperator\n+An overlapping Schwarz operator.\n+Definition: schwarz.hh:75\n+Dune::OverlappingSchwarzOperator::getCommunication\n+const communication_type & getCommunication() const\n+Get the object responsible for communication.\n+Definition: schwarz.hh:146\n+Dune::OverlappingSchwarzOperator::getmat\n+virtual const matrix_type & getmat() const\n+get the sequential assembled linear operator.\n+Definition: schwarz.hh:133\n+Dune::OverlappingSchwarzOperator::applyscaleadd\n+virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const\n+apply operator to x, scale and add:\n+Definition: schwarz.hh:125\n+Dune::OverlappingSchwarzOperator::apply\n+virtual void apply(const X &x, Y &y) const\n+apply operator to x:\n+Definition: schwarz.hh:116\n+Dune::OverlappingSchwarzOperator::communication_type\n+C communication_type\n+The type of the communication object.\n+Definition: schwarz.hh:98\n+Dune::OverlappingSchwarzOperator::domain_type\n+X domain_type\n+The type of the domain.\n+Definition: schwarz.hh:86\n+Dune::OverlappingSchwarzOperator::matrix_type\n+M matrix_type\n+The type of the matrix we operate on.\n+Definition: schwarz.hh:81\n+Dune::OverlappingSchwarzOperator::range_type\n+Y range_type\n+The type of the range.\n+Definition: schwarz.hh:91\n+Dune::OverlappingSchwarzOperator::field_type\n+X::field_type field_type\n+The field type of the range.\n+Definition: schwarz.hh:93\n+Dune::OverlappingSchwarzOperator::OverlappingSchwarzOperator\n+OverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)\n+constructor: just store a reference to a matrix.\n+Definition: schwarz.hh:107\n+Dune::OverlappingSchwarzOperator::OverlappingSchwarzOperator\n+OverlappingSchwarzOperator(const std::shared_ptr< matrix_type > A, const\n+communication_type &com)\n+Definition: schwarz.hh:111\n+Dune::OverlappingSchwarzOperator::category\n+virtual SolverCategory::Category category() const\n+Category of the linear operator (see SolverCategory::Category)\n+Definition: schwarz.hh:139\n Dune::Preconditioner\n Base class for matrix free definition of preconditioners.\n Definition: preconditioner.hh:32\n-Dune::InverseOperator2Preconditioner\n-Turns an InverseOperator into a Preconditioner.\n-Definition: preconditioners.hh:75\n-Dune::InverseOperator2Preconditioner::range_type\n-O::range_type range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:80\n-Dune::InverseOperator2Preconditioner::domain_type\n-O::domain_type domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioners.hh:78\n-Dune::InverseOperator2Preconditioner::post\n-virtual void post(domain_type &)\n-Clean up.\n-Definition: preconditioners.hh:111\n-Dune::InverseOperator2Preconditioner::field_type\n-range_type::field_type field_type\n+Dune::Preconditioner::field_type\n+X::field_type field_type\n The field type of the preconditioner.\n-Definition: preconditioners.hh:82\n-Dune::InverseOperator2Preconditioner::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:86\n-Dune::InverseOperator2Preconditioner::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:84\n-Dune::InverseOperator2Preconditioner::category\n+Definition: preconditioner.hh:39\n+Dune::ParSSOR\n+A parallel SSOR preconditioner.\n+Definition: schwarz.hh:175\n+Dune::ParSSOR::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: schwarz.hh:184\n+Dune::ParSSOR::communication_type\n+C communication_type\n+The type of the communication object.\n+Definition: schwarz.hh:186\n+Dune::ParSSOR::category\n virtual SolverCategory::Category category() const\n Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:115\n-Dune::InverseOperator2Preconditioner::pre\n-virtual void pre(domain_type &, range_type &)\n-Prepare the preconditioner.\n-Definition: preconditioners.hh:101\n-Dune::InverseOperator2Preconditioner::InverseOperator2Preconditioner\n-InverseOperator2Preconditioner(InverseOperator &inverse_operator)\n-Construct the preconditioner from the solver.\n-Definition: preconditioners.hh:94\n-Dune::InverseOperator2Preconditioner::InverseOperator\n-O InverseOperator\n-type of the wrapped inverse operator\n-Definition: preconditioners.hh:88\n-Dune::InverseOperator2Preconditioner::apply\n-virtual void apply(domain_type &v, const range_type &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: preconditioners.hh:104\n-Dune::SeqSSOR\n-Sequential SSOR preconditioner.\n-Definition: preconditioners.hh:141\n-Dune::SeqSSOR::post\n+Definition: schwarz.hh:233\n+Dune::ParSSOR::ParSSOR\n+ParSSOR(const matrix_type &A, int n, field_type w, const communication_type &c)\n+Constructor.\n+Definition: schwarz.hh:197\n+Dune::ParSSOR::post\n virtual void post(X &x)\n Clean up.\n-Definition: preconditioners.hh:229\n-Dune::SeqSSOR::SeqSSOR\n-SeqSSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n-const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:182\n-Dune::SeqSSOR::SeqSSOR\n-SeqSSOR(const M &A, const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:199\n-Dune::SeqSSOR::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:233\n-Dune::SeqSSOR::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioners.hh:150\n-Dune::SeqSSOR::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:152\n-Dune::SeqSSOR::domain_type\n+Definition: schwarz.hh:230\n+Dune::ParSSOR::domain_type\n X domain_type\n The domain type of the preconditioner.\n-Definition: preconditioners.hh:146\n-Dune::SeqSSOR::matrix_type\n-M matrix_type\n-The matrix type the preconditioner is for.\n-Definition: preconditioners.hh:144\n-Dune::SeqSSOR::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the preconditioner.\n-Definition: preconditioners.hh:216\n-Dune::SeqSSOR::pre\n-virtual void pre(X &x, Y &b)\n-Prepare the preconditioner.\n-Definition: preconditioners.hh:208\n-Dune::SeqSSOR::range_type\n+Definition: schwarz.hh:180\n+Dune::ParSSOR::range_type\n Y range_type\n The range type of the preconditioner.\n-Definition: preconditioners.hh:148\n-Dune::SeqSSOR::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:154\n-Dune::SeqSSOR::SeqSSOR\n-SeqSSOR(const M &A, int n, real_field_type w)\n-Constructor.\n-Definition: preconditioners.hh:163\n-Dune::SeqSOR\n-Sequential SOR preconditioner.\n-Definition: preconditioners.hh:261\n-Dune::SeqSOR::SeqSOR\n-SeqSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n-const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:302\n-Dune::SeqSOR::matrix_type\n+Definition: schwarz.hh:182\n+Dune::ParSSOR::matrix_type\n M matrix_type\n The matrix type the preconditioner is for.\n-Definition: preconditioners.hh:264\n-Dune::SeqSOR::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:274\n-Dune::SeqSOR::apply\n-void apply(X &v, const Y &d)\n-Apply the preconditioner in a special direction.\n-Definition: preconditioners.hh:350\n-Dune::SeqSOR::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioners.hh:266\n-Dune::SeqSOR::post\n-virtual void post(X &x)\n-Clean up.\n-Definition: preconditioners.hh:367\n-Dune::SeqSOR::pre\n+Definition: schwarz.hh:178\n+Dune::ParSSOR::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the precondtioner.\n+Definition: schwarz.hh:216\n+Dune::ParSSOR::pre\n virtual void pre(X &x, Y &b)\n Prepare the preconditioner.\n-Definition: preconditioners.hh:328\n-Dune::SeqSOR::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:272\n-Dune::SeqSOR::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:371\n-Dune::SeqSOR::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the preconditioner.\n-Definition: preconditioners.hh:336\n-Dune::SeqSOR::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:268\n-Dune::SeqSOR::SeqSOR\n-SeqSOR(const M &A, const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:319\n-Dune::SeqSOR::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioners.hh:270\n-Dune::SeqSOR::SeqSOR\n-SeqSOR(const M &A, int n, real_field_type w)\n-Constructor.\n-Definition: preconditioners.hh:283\n-Dune::SeqJac\n-The sequential jacobian preconditioner.\n-Definition: preconditioners.hh:412\n-Dune::SeqJac::post\n-virtual void post(X &x)\n-Clean up.\n-Definition: preconditioners.hh:499\n-Dune::SeqJac::SeqJac\n-SeqJac(const M &A, const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:470\n-Dune::SeqJac::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the preconditioner.\n-Definition: preconditioners.hh:487\n-Dune::SeqJac::matrix_type\n-M matrix_type\n-The matrix type the preconditioner is for.\n-Definition: preconditioners.hh:415\n-Dune::SeqJac::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:423\n-Dune::SeqJac::SeqJac\n-SeqJac(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n-const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:453\n-Dune::SeqJac::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioners.hh:421\n-Dune::SeqJac::pre\n+Definition: schwarz.hh:206\n+Dune::BlockPreconditioner\n+Block parallel preconditioner.\n+Definition: schwarz.hh:278\n+Dune::BlockPreconditioner::pre\n virtual void pre(X &x, Y &b)\n Prepare the preconditioner.\n-Definition: preconditioners.hh:479\n-Dune::SeqJac::domain_type\n+Definition: schwarz.hh:326\n+Dune::BlockPreconditioner::domain_type\n X domain_type\n The domain type of the preconditioner.\n-Definition: preconditioners.hh:417\n-Dune::SeqJac::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:425\n-Dune::SeqJac::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:503\n-Dune::SeqJac::SeqJac\n-SeqJac(const M &A, int n, real_field_type w)\n-Constructor.\n-Definition: preconditioners.hh:434\n-Dune::SeqJac::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:419\n-Dune::SeqILU\n-Sequential ILU preconditioner.\n-Definition: preconditioners.hh:532\n-Dune::SeqILU::post\n-virtual void post(X &x)\n-Clean up.\n-Definition: preconditioners.hh:678\n-Dune::SeqILU::SeqILU\n-SeqILU(const M &A, int n, real_field_type w, const bool resort=false)\n+Definition: schwarz.hh:285\n+Dune::BlockPreconditioner::BlockPreconditioner\n+BlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)\n Constructor.\n-Definition: preconditioners.hh:612\n-Dune::SeqILU::pre\n-virtual void pre(X &x, Y &b)\n-Prepare the preconditioner.\n-Definition: preconditioners.hh:648\n-Dune::SeqILU::apply\n+Definition: schwarz.hh:317\n+Dune::BlockPreconditioner::apply\n virtual void apply(X &v, const Y &d)\n Apply the preconditioner.\n-Definition: preconditioners.hh:656\n-Dune::SeqILU::CRS\n-ILU::CRS< block_type, typename M::allocator_type > CRS\n-type of ILU storage\n-Definition: preconditioners.hh:552\n-Dune::SeqILU::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:541\n-Dune::SeqILU::lower_\n-CRS lower_\n-The ILU(n) decomposition of the matrix. As storage a CRS structure is used.\n-Definition: preconditioners.hh:692\n-Dune::SeqILU::wNotIdentity_\n-const bool wNotIdentity_\n-true if w != 1.0\n-Definition: preconditioners.hh:699\n-Dune::SeqILU::SeqILU\n-SeqILU(const M &A, const ParameterTree &config)\n-Constructor.\n-Definition: preconditioners.hh:598\n-Dune::SeqILU::matrix_type\n-std::remove_const< M >::type matrix_type\n-The matrix type the preconditioner is for.\n-Definition: preconditioners.hh:535\n-Dune::SeqILU::block_type\n-matrix_type::block_type block_type\n-block type of matrix\n-Definition: preconditioners.hh:537\n-Dune::SeqILU::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:549\n-Dune::SeqILU::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioners.hh:544\n-Dune::SeqILU::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:682\n-Dune::SeqILU::SeqILU\n-SeqILU(const M &A, real_field_type w, const bool resort=false)\n+Definition: schwarz.hh:337\n+Dune::BlockPreconditioner::BlockPreconditioner\n+BlockPreconditioner(P &p, const communication_type &c)\n Constructor.\n-Definition: preconditioners.hh:561\n-Dune::SeqILU::w_\n-const real_field_type w_\n-The relaxation factor to use.\n-Definition: preconditioners.hh:697\n-Dune::SeqILU::SeqILU\n-SeqILU(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n-const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:580\n-Dune::SeqILU::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioners.hh:539\n-Dune::SeqILU::inv_\n-std::vector< block_type, typename matrix_type::allocator_type > inv_\n-Definition: preconditioners.hh:694\n-Dune::SeqILU::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:547\n-Dune::SeqILU::ILU_\n-std::unique_ptr< matrix_type > ILU_\n-The ILU(n) decomposition of the matrix. As storage a BCRSMatrix is used.\n-Definition: preconditioners.hh:689\n-Dune::SeqILU::upper_\n-CRS upper_\n-Definition: preconditioners.hh:693\n-Dune::Richardson\n-Richardson preconditioner.\n-Definition: preconditioners.hh:713\n-Dune::Richardson::field_type\n+Definition: schwarz.hh:306\n+Dune::BlockPreconditioner::apply\n+void apply(X &v, const Y &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: schwarz.hh:344\n+Dune::BlockPreconditioner::communication_type\n+C communication_type\n+The type of the communication object..\n+Definition: schwarz.hh:297\n+Dune::BlockPreconditioner::field_type\n X::field_type field_type\n The field type of the preconditioner.\n-Definition: preconditioners.hh:720\n-Dune::Richardson::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:778\n-Dune::Richardson::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:718\n-Dune::Richardson::pre\n-virtual void pre(X &x, Y &b)\n-Prepare the preconditioner.\n-Definition: preconditioners.hh:755\n-Dune::Richardson::Richardson\n-Richardson(real_field_type w=1.0)\n-Constructor.\n-Definition: preconditioners.hh:731\n-Dune::Richardson::post\n+Definition: schwarz.hh:292\n+Dune::BlockPreconditioner::post\n virtual void post(X &x)\n Clean up.\n-Definition: preconditioners.hh:774\n-Dune::Richardson::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:724\n-Dune::Richardson::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:722\n-Dune::Richardson::Richardson\n-Richardson(const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:746\n-Dune::Richardson::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioners.hh:716\n-Dune::Richardson::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the precondioner.\n-Definition: preconditioners.hh:763\n-Dune::SeqILDL\n-sequential ILDL preconditioner\n-Definition: preconditioners.hh:807\n-Dune::SeqILDL::SeqILDL\n-SeqILDL(const matrix_type &A, const ParameterTree &config)\n-Constructor.\n-Definition: preconditioners.hh:853\n-Dune::SeqILDL::SeqILDL\n-SeqILDL(const matrix_type &A, real_field_type relax=real_field_type(1))\n-constructor\n-Definition: preconditioners.hh:865\n-Dune::SeqILDL::domain_type\n-X domain_type\n-domain type of the preconditioner\n-Definition: preconditioners.hh:815\n-Dune::SeqILDL::post\n-void post(X &x) override\n-Clean up.\n-Definition: preconditioners.hh:916\n-Dune::SeqILDL::range_type\n+Definition: schwarz.hh:355\n+Dune::BlockPreconditioner::range_type\n Y range_type\n-range type of the preconditioner\n-Definition: preconditioners.hh:817\n-Dune::SeqILDL::matrix_type\n-std::remove_const_t< M > matrix_type\n-type of matrix the preconditioner is for\n-Definition: preconditioners.hh:813\n-Dune::SeqILDL::apply\n-void apply(X &v, const Y &d) override\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: preconditioners.hh:909\n-Dune::SeqILDL::real_field_type\n-FieldTraits< scalar_field_type >::real_type real_field_type\n-real scalar type underlying the field_type\n-Definition: preconditioners.hh:823\n-Dune::SeqILDL::SeqILDL\n-SeqILDL(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n-const ParameterTree &configuration)\n-Constructor.\n-Definition: preconditioners.hh:837\n-Dune::SeqILDL::pre\n-void pre(X &x, Y &b) override\n-Prepare the preconditioner.\n-Definition: preconditioners.hh:905\n-Dune::SeqILDL::scalar_field_type\n-Simd::Scalar< field_type > scalar_field_type\n-scalar type underlying the field_type\n-Definition: preconditioners.hh:821\n-Dune::SeqILDL::field_type\n-X::field_type field_type\n-field type of the preconditioner\n-Definition: preconditioners.hh:819\n-Dune::SeqILDL::category\n-SolverCategory::Category category() const override\n+The range type of the preconditioner.\n+Definition: schwarz.hh:290\n+Dune::BlockPreconditioner::category\n+virtual SolverCategory::Category category() const\n Category of the preconditioner (see SolverCategory::Category)\n-Definition: preconditioners.hh:920\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperator\n-Abstract base class for all solvers.\n-Definition: solver.hh:99\n+Definition: schwarz.hh:361\n Dune::SolverCategory::Category\n Category\n Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n+Dune::SolverCategory::overlapping\n+@ overlapping\n+Category for overlapping solvers.\n+Definition: solvercategory.hh:29\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00074.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00074.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bdmatrix.hh File Reference\n+dune-istl: matrixmarket.hh File Reference\n \n \n \n \n \n \n \n@@ -64,45 +64,265 @@\n

    \n
    \n
    \n
    \n \n-
    bdmatrix.hh File Reference
    \n+Namespaces |\n+Enumerations |\n+Functions |\n+Variables
    \n+ \n
    \n
    \n \n-

    Implementation of the BDMatrix class. \n+

    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices. \n More...

    \n-
    #include <memory>
    \n-#include <dune/common/rangeutilities.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n+
    #include <algorithm>
    \n+#include <complex>
    \n+#include <cstddef>
    \n+#include <fstream>
    \n+#include <ios>
    \n+#include <iostream>
    \n+#include <istream>
    \n+#include <limits>
    \n+#include <ostream>
    \n+#include <set>
    \n+#include <sstream>
    \n+#include <string>
    \n+#include <tuple>
    \n+#include <type_traits>
    \n+#include <vector>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/common/hybridutilities.hh>
    \n+#include <dune/common/stdstreams.hh>
    \n+#include <dune/common/simd/simd.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/istl/bvector.hh>
    \n+#include <dune/istl/matrixutils.hh>
    \n+#include <dune/istl/owneroverlapcopy.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::BDMatrix< B, A >
     A block-diagonal matrix. More...
    struct  Dune::MatrixMarketImpl::mm_numeric_type< T >
     Helper metaprogram to get the matrix market string representation of the numeric type. More...
     
    struct  Dune::FieldTraits< BDMatrix< B, A > >
    struct  Dune::MatrixMarketImpl::mm_numeric_type< int >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< double >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< float >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< std::complex< double > >
     
    struct  Dune::MatrixMarketImpl::mm_numeric_type< std::complex< float > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< BCRSMatrix< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< BlockVector< B, A > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< FieldVector< T, j > >
     
    struct  Dune::MatrixMarketImpl::mm_header_printer< FieldMatrix< T, i, j > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< FieldVector< T, i >, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< T, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< FieldMatrix< T, i, j >, A > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< FieldMatrix< T, i, j > >
     
    struct  Dune::MatrixMarketImpl::mm_block_structure_header< FieldVector< T, i > >
     
    struct  Dune::MatrixMarketImpl::MMHeader
     
    struct  Dune::MatrixMarketImpl::IndexData< T >
     
    struct  Dune::MatrixMarketImpl::NumericWrapper< T >
     a wrapper class of numeric values. More...
     
    struct  Dune::MatrixMarketImpl::PatternDummy
     Utility class for marking the pattern type of the MatrixMarket matrices. More...
     
    struct  Dune::MatrixMarketImpl::NumericWrapper< PatternDummy >
     
    struct  Dune::MatrixMarketImpl::MatrixValuesSetter< D, brows, bcols >
     Functor to the data values of the matrix. More...
     
    struct  Dune::MatrixMarketImpl::MatrixValuesSetter< PatternDummy, brows, bcols >
     
    struct  Dune::MatrixMarketImpl::is_complex< T >
     
    struct  Dune::MatrixMarketImpl::is_complex< std::complex< T > >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< M >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< B, A > >
     
    struct  Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< FieldMatrix< B, i, j >, A > >
     
    class  Dune::MatrixMarketFormatError
     
    \n \n \n \n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::MatrixMarketImpl
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Enumerations

    enum  Dune::MatrixMarketImpl::LineType { Dune::MatrixMarketImpl::MM_HEADER\n+, Dune::MatrixMarketImpl::MM_ISTLSTRUCT\n+, Dune::MatrixMarketImpl::DATA\n+ }
     
    enum  { Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH =1025\n+ }
     
    enum  Dune::MatrixMarketImpl::MM_TYPE { Dune::MatrixMarketImpl::coordinate_type\n+, Dune::MatrixMarketImpl::array_type\n+, Dune::MatrixMarketImpl::unknown_type\n+ }
     
    enum  Dune::MatrixMarketImpl::MM_CTYPE {
    \n+  Dune::MatrixMarketImpl::integer_type\n+, Dune::MatrixMarketImpl::double_type\n+, Dune::MatrixMarketImpl::complex_type\n+, Dune::MatrixMarketImpl::pattern\n+,
    \n+  Dune::MatrixMarketImpl::unknown_ctype\n+
    \n+ }
     
    enum  Dune::MatrixMarketImpl::MM_STRUCTURE {
    \n+  Dune::MatrixMarketImpl::general\n+, Dune::MatrixMarketImpl::symmetric\n+, Dune::MatrixMarketImpl::skew_symmetric\n+, Dune::MatrixMarketImpl::hermitian\n+,
    \n+  Dune::MatrixMarketImpl::unknown_structure\n+
    \n+ }
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Functions

    bool Dune::MatrixMarketImpl::lineFeed (std::istream &file)
     
    void Dune::MatrixMarketImpl::skipComments (std::istream &file)
     
    bool Dune::MatrixMarketImpl::readMatrixMarketBanner (std::istream &file, MMHeader &mmHeader)
     
    template<std::size_t brows, std::size_t bcols>
    std::tuple< std::size_t, std::size_t, std::size_t > Dune::MatrixMarketImpl::calculateNNZ (std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader &header)
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, NumericWrapper< T > &num)
     
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, NumericWrapper< PatternDummy > &num)
     
    template<typename T >
    bool Dune::MatrixMarketImpl::operator< (const IndexData< T > &i1, const IndexData< T > &i2)
     LessThan operator. More...
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, IndexData< T > &data)
     Read IndexData from a stream. More...
     
    template<typename T >
    std::istream & Dune::MatrixMarketImpl::operator>> (std::istream &is, IndexData< NumericWrapper< std::complex< T > > > &data)
     Read IndexData from a stream. Specialization for std::complex. More...
     
    template<class T >
    std::enable_if_t<!is_complex< T >::value, T > Dune::MatrixMarketImpl::conj (const T &r)
     
    template<class T >
    std::enable_if_t< is_complex< T >::value, T > Dune::MatrixMarketImpl::conj (const T &r)
     
    template<typename T , typename A , typename D >
    void Dune::MatrixMarketImpl::readSparseEntries (Dune::BCRSMatrix< T, A > &matrix, std::istream &file, std::size_t entries, const MMHeader &mmHeader, const D &)
     
    std::tuple< std::string, std::string > Dune::MatrixMarketImpl::splitFilename (const std::string &filename)
     
    void Dune::mm_read_header (std::size_t &rows, std::size_t &cols, MatrixMarketImpl::MMHeader &header, std::istream &istr, bool isVector)
     
    template<typename T , typename A >
    void Dune::mm_read_vector_entries (Dune::BlockVector< T, A > &vector, std::size_t size, std::istream &istr, size_t lane)
     
    template<typename T , typename A , int entries>
    void Dune::mm_read_vector_entries (Dune::BlockVector< Dune::FieldVector< T, entries >, A > &vector, std::size_t size, std::istream &istr, size_t lane)
     
    template<typename T , typename A >
    void Dune::readMatrixMarket (Dune::BlockVector< T, A > &vector, std::istream &istr)
     Reads a BlockVector from a matrix market file. More...
     
    template<typename T , typename A >
    void Dune::readMatrixMarket (Dune::BCRSMatrix< T, A > &matrix, std::istream &istr)
     Reads a sparse matrix from a matrix market file. More...
     
    template<typename B >
    void Dune::mm_print_entry (const B &entry, std::size_t rowidx, std::size_t colidx, std::ostream &ostr)
     
    template<typename V >
    void Dune::mm_print_vector_entry (const V &entry, std::ostream &ostr, const std::integral_constant< int, 1 > &, size_t lane)
     
    template<typename V >
    void Dune::mm_print_vector_entry (const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &, size_t lane)
     
    template<typename T , typename A >
    std::size_t Dune::countEntries (const BlockVector< T, A > &vector)
     
    template<typename T , typename A , int i>
    std::size_t Dune::countEntries (const BlockVector< FieldVector< T, i >, A > &vector)
     
    template<typename V >
    void Dune::writeMatrixMarket (const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &)
     
    template<typename M >
    void Dune::writeMatrixMarket (const M &matrix, std::ostream &ostr, const std::integral_constant< int, 1 > &)
     
    template<typename M >
    void Dune::writeMatrixMarket (const M &matrix, std::ostream &ostr)
     writes a ISTL matrix or vector to a stream in matrix market format. More...
     
    template<typename M >
    void Dune::storeMatrixMarket (const M &matrix, std::string filename, int prec=default_precision)
     Stores a parallel matrix/vector in matrix market format in a file. More...
     
    template<typename M , typename G , typename L >
    void Dune::storeMatrixMarket (const M &matrix, std::string filename, const OwnerOverlapCopyCommunication< G, L > &comm, bool storeIndices=true, int prec=default_precision)
     Stores a parallel matrix/vector in matrix market format in a file. More...
     
    template<typename M , typename G , typename L >
    void Dune::loadMatrixMarket (M &matrix, const std::string &filename, OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)
     Load a parallel matrix/vector stored in matrix market format. More...
     
    template<typename M >
    void Dune::loadMatrixMarket (M &matrix, const std::string &filename)
     Load a matrix/vector stored in matrix market format. More...
     
    \n+\n+\n+\n

    \n+Variables

    static const int Dune::default_precision = -1
     
    \n

    Detailed Description

    \n-

    Implementation of the BDMatrix class.

    \n-
    Author
    Oliver Sander
    \n+

    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.

    \n+
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,32 +4,317 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-bdmatrix.hh File Reference\n-Implementation of the BDMatrix class. More...\n-#include \n-#include \n-#include \n+Classes | Namespaces | Enumerations | Functions | Variables\n+matrixmarket.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes \u00bb\n+IO_for_matrices_and_vectors.\n+Provides classes for reading and writing MatrixMarket Files with an extension\n+for parallel matrices. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n #include \n-#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::BDMatrix<_B,_A_>\n-\u00a0 A block-diagonal matrix. More...\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_T_>\n+\u00a0 Helper metaprogram to get the matrix market string representation of\n+ the numeric type. More...\n \u00a0\n-struct \u00a0Dune::FieldTraits<_BDMatrix<_B,_A_>_>\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_int_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_double_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_float_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_double_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_float_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_BCRSMatrix<_T,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_BlockVector<_B,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_FieldVector<_T,_j_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_header_printer<_FieldMatrix<_T,_i,_j_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>\n+ >\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<\n+ FieldVector<_T,_i_>,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>\n+ >\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<\n+ FieldMatrix<_T,_i,_j_>,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,\n+ j_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>\n+ >\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::MMHeader\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::IndexData<_T_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::NumericWrapper<_T_>\n+\u00a0 a wrapper class of numeric values. More...\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::PatternDummy\n+\u00a0 Utility class for marking the pattern type of the MatrixMarket\n+ matrices. More...\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::NumericWrapper<_PatternDummy_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::MatrixValuesSetter<_D,_brows,_bcols_>\n+\u00a0 Functor to the data values of the matrix. More...\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::MatrixValuesSetter<_PatternDummy,_brows,_bcols\n+ >\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::is_complex<_T_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::is_complex<_std::complex<_T_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_M_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_BCRSMatrix<_B,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MatrixMarketImpl::mm_multipliers<_BCRSMatrix<_FieldMatrix<_B,_i,\n+ j_>,_A_>_>\n+\u00a0\n+ class \u00a0Dune::MatrixMarketFormatError\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::MatrixMarketImpl\n+\u00a0\n+ Enumerations\n+enum Dune::MatrixMarketImpl::LineType { Dune::MatrixMarketImpl::MM_HEADER , Dune::\n+ \u00a0MatrixMarketImpl::MM_ISTLSTRUCT , Dune::MatrixMarketImpl::DATA }\n+\u00a0\n+enum\n+ \u00a0{ Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH =1025 }\n+\u00a0\n+enum Dune::MatrixMarketImpl::MM_TYPE { Dune::MatrixMarketImpl::coordinate_type ,\n+ \u00a0Dune::MatrixMarketImpl::array_type , Dune::MatrixMarketImpl::unknown_type }\n+\u00a0\n+enum Dune::MatrixMarketImpl::MM_CTYPE {\n+ \u00a0\u00a0\u00a0Dune::MatrixMarketImpl::integer_type , Dune::MatrixMarketImpl::double_type ,\n+ Dune::MatrixMarketImpl::complex_type , Dune::MatrixMarketImpl::pattern ,\n+ \u00a0\u00a0Dune::MatrixMarketImpl::unknown_ctype\n+ }\n+\u00a0\n+enum Dune::MatrixMarketImpl::MM_STRUCTURE {\n+ \u00a0\u00a0\u00a0Dune::MatrixMarketImpl::general , Dune::MatrixMarketImpl::symmetric , Dune::\n+ MatrixMarketImpl::skew_symmetric , Dune::MatrixMarketImpl::hermitian ,\n+ \u00a0\u00a0Dune::MatrixMarketImpl::unknown_structure\n+ }\n+\u00a0\n+ Functions\n+ bool\u00a0Dune::MatrixMarketImpl::lineFeed (std::\n+ istream &file)\n+\u00a0\n+ void\u00a0Dune::MatrixMarketImpl::skipComments\n+ (std::istream &file)\n+\u00a0\n+ bool\u00a0Dune::MatrixMarketImpl::\n+ readMatrixMarketBanner (std::istream\n+ &file, MMHeader &mmHeader)\n+\u00a0\n+template\n+ std::tuple< std::size_t, std::size_t, Dune::MatrixMarketImpl::calculateNNZ\n+ std::size_t >\u00a0(std::size_t rows, std::size_t cols,\n+ std::size_t entries, const MMHeader\n+ &header)\n+\u00a0\n+template\n+ std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n+ (std::istream &is, NumericWrapper< T >\n+ &num)\n+\u00a0\n+ std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n+ (std::istream &is, NumericWrapper<\n+ PatternDummy > &num)\n+\u00a0\n+template\n+ bool\u00a0Dune::MatrixMarketImpl::operator<\n+ (const IndexData< T > &i1, const\n+ IndexData< T > &i2)\n+\u00a0 LessThan operator. More...\n+\u00a0\n+template\n+ std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n+ (std::istream &is, IndexData< T >\n+ &data)\n+\u00a0 Read IndexData from a stream. More...\n+\u00a0\n+template\n+ std::istream &\u00a0Dune::MatrixMarketImpl::operator>>\n+ (std::istream &is, IndexData<\n+ NumericWrapper< std::complex< T > > >\n+ &data)\n+ Read IndexData from a stream.\n+\u00a0 Specialization for std::complex.\n+ More...\n+\u00a0\n+template\n+ std::enable_if_t:: Dune::MatrixMarketImpl::conj (const T\n+ value, T >\u00a0&r)\n+\u00a0\n+template\n+ std::enable_if_t< is_complex< T >:: Dune::MatrixMarketImpl::conj (const T\n+ value, T >\u00a0&r)\n+\u00a0\n+template\n+ void\u00a0Dune::MatrixMarketImpl::\n+ readSparseEntries (Dune::BCRSMatrix< T,\n+ A > &matrix, std::istream &file, std::\n+ size_t entries, const MMHeader\n+ &mmHeader, const D &)\n+\u00a0\n+std::tuple< std::string, std::string >\u00a0Dune::MatrixMarketImpl::splitFilename\n+ (const std::string &filename)\n+\u00a0\n+ void\u00a0Dune::mm_read_header (std::size_t\n+ &rows, std::size_t &cols,\n+ MatrixMarketImpl::MMHeader &header,\n+ std::istream &istr, bool isVector)\n+\u00a0\n+template\n+ void\u00a0Dune::mm_read_vector_entries (Dune::\n+ BlockVector< T, A > &vector, std::\n+ size_t size, std::istream &istr, size_t\n+ lane)\n+\u00a0\n+template\n+ void\u00a0Dune::mm_read_vector_entries (Dune::\n+ BlockVector< Dune::FieldVector< T,\n+ entries >, A > &vector, std::size_t\n+ size, std::istream &istr, size_t lane)\n+\u00a0\n+template\n+ void\u00a0Dune::readMatrixMarket (Dune::\n+ BlockVector< T, A > &vector, std::\n+ istream &istr)\n+\u00a0 Reads a BlockVector from a matrix\n+ market file. More...\n+\u00a0\n+template\n+ void\u00a0Dune::readMatrixMarket (Dune::\n+ BCRSMatrix< T, A > &matrix, std::\n+ istream &istr)\n+\u00a0 Reads a sparse matrix from a matrix\n+ market file. More...\n+\u00a0\n+template\n+ void\u00a0Dune::mm_print_entry (const B &entry,\n+ std::size_t rowidx, std::size_t colidx,\n+ std::ostream &ostr)\n+\u00a0\n+template\n+ void\u00a0Dune::mm_print_vector_entry (const V\n+ &entry, std::ostream &ostr, const std::\n+ integral_constant< int, 1 > &, size_t\n+ lane)\n+\u00a0\n+template\n+ void\u00a0Dune::mm_print_vector_entry (const V\n+ &vector, std::ostream &ostr, const\n+ std::integral_constant< int, 0 > &,\n+ size_t lane)\n+\u00a0\n+template\n+ std::size_t\u00a0Dune::countEntries (const BlockVector<\n+ T, A > &vector)\n+\u00a0\n+template\n+ std::size_t\u00a0Dune::countEntries (const BlockVector<\n+ FieldVector< T, i >, A > &vector)\n+\u00a0\n+template\n+ void\u00a0Dune::writeMatrixMarket (const V\n+ &vector, std::ostream &ostr, const\n+ std::integral_constant< int, 0 > &)\n+\u00a0\n+template\n+ void\u00a0Dune::writeMatrixMarket (const M\n+ &matrix, std::ostream &ostr, const\n+ std::integral_constant< int, 1 > &)\n+\u00a0\n+template\n+ void\u00a0Dune::writeMatrixMarket (const M\n+ &matrix, std::ostream &ostr)\n+\u00a0 writes a ISTL matrix or vector to a\n+ stream in matrix market format. More...\n+\u00a0\n+template\n+ void\u00a0Dune::storeMatrixMarket (const M\n+ &matrix, std::string filename, int\n+ prec=default_precision)\n+\u00a0 Stores a parallel matrix/vector in\n+ matrix market format in a file. More...\n+\u00a0\n+template\n+ void\u00a0Dune::storeMatrixMarket (const M\n+ &matrix, std::string filename, const\n+ OwnerOverlapCopyCommunication< G, L >\n+ &comm, bool storeIndices=true, int\n+ prec=default_precision)\n+\u00a0 Stores a parallel matrix/vector in\n+ matrix market format in a file. More...\n+\u00a0\n+template\n+ void\u00a0Dune::loadMatrixMarket (M &matrix,\n+ const std::string &filename,\n+ OwnerOverlapCopyCommunication< G, L >\n+ &comm, bool readIndices=true)\n+\u00a0 Load a parallel matrix/vector stored in\n+ matrix market format. More...\n+\u00a0\n+template\n+ void\u00a0Dune::loadMatrixMarket (M &matrix,\n+ const std::string &filename)\n+\u00a0 Load a matrix/vector stored in matrix\n+ market format. More...\n+\u00a0\n+ Variables\n+static const int\u00a0Dune::default_precision = -1\n+\u00a0\n ***** Detailed Description *****\n-Implementation of the BDMatrix class.\n+Provides classes for reading and writing MatrixMarket Files with an extension\n+for parallel matrices.\n Author\n- Oliver Sander\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00074_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00074_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bdmatrix.hh Source File\n+dune-istl: matrixmarket.hh Source File\n \n \n \n \n \n \n \n@@ -62,173 +62,1343 @@\n \n
    \n \n
    \n
    \n
    \n-
    bdmatrix.hh
    \n+
    matrixmarket.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_BDMATRIX_HH
    \n-
    6#define DUNE_ISTL_BDMATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_MATRIXMARKET_HH
    \n+
    6#define DUNE_ISTL_MATRIXMARKET_HH
    \n
    7
    \n-
    8#include <memory>
    \n-
    9
    \n-
    10#include <dune/common/rangeutilities.hh>
    \n-
    11#include <dune/common/scalarmatrixview.hh>
    \n-
    12
    \n-\n-\n-
    15
    \n-
    21namespace Dune {
    \n-
    31 template <class B, class A=std::allocator<B> >
    \n-
    32 class BDMatrix : public BCRSMatrix<B,A>
    \n-
    33 {
    \n-
    34 public:
    \n+
    8#include <algorithm>
    \n+
    9#include <complex>
    \n+
    10#include <cstddef>
    \n+
    11#include <fstream>
    \n+
    12#include <ios>
    \n+
    13#include <iostream>
    \n+
    14#include <istream>
    \n+
    15#include <limits>
    \n+
    16#include <ostream>
    \n+
    17#include <set>
    \n+
    18#include <sstream>
    \n+
    19#include <string>
    \n+
    20#include <tuple>
    \n+
    21#include <type_traits>
    \n+
    22#include <vector>
    \n+
    23
    \n+
    24#include <dune/common/exceptions.hh>
    \n+
    25#include <dune/common/fmatrix.hh>
    \n+
    26#include <dune/common/fvector.hh>
    \n+
    27#include <dune/common/hybridutilities.hh>
    \n+
    28#include <dune/common/stdstreams.hh>
    \n+
    29#include <dune/common/simd/simd.hh>
    \n+
    30
    \n+\n+
    32#include <dune/istl/bvector.hh>
    \n+
    33#include <dune/istl/matrixutils.hh> // countNonZeros()
    \n+\n
    35
    \n-
    36 //===== type definitions and constants
    \n-
    37
    \n-
    39 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    40
    \n-
    42 typedef B block_type;
    \n-
    43
    \n-
    45 typedef A allocator_type;
    \n-
    46
    \n-
    48 //typedef BCRSMatrix<B,A>::row_type row_type;
    \n-
    49
    \n-
    51 typedef typename A::size_type size_type;
    \n-
    52
    \n-
    54 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    55 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n-
    56
    \n-
    58 BDMatrix() : BCRSMatrix<B,A>() {}
    \n-
    59
    \n-
    60 explicit BDMatrix(int size)
    \n-
    61 : BCRSMatrix<B,A>(size, size, BCRSMatrix<B,A>::random) {
    \n-
    62
    \n-
    63 for (int i=0; i<size; i++)
    \n-\n-
    65
    \n-\n-
    67
    \n-
    68 for (int i=0; i<size; i++)
    \n-
    69 this->BCRSMatrix<B,A>::addindex(i, i);
    \n-
    70
    \n-\n-
    72
    \n-
    73 }
    \n-
    74
    \n-
    76 BDMatrix (std::initializer_list<B> const &list)
    \n-
    77 : BDMatrix(list.size())
    \n-
    78 {
    \n-
    79 size_t i=0;
    \n-
    80 for (auto it = list.begin(); it != list.end(); ++it, ++i)
    \n-
    81 (*this)[i][i] = *it;
    \n-
    82 }
    \n-
    83
    \n-
    85 void setSize(size_type size)
    \n-
    86 {
    \n-
    87 this->BCRSMatrix<B,A>::setSize(size, // rows
    \n-
    88 size, // columns
    \n-
    89 size); // nonzeros
    \n-
    90
    \n-
    91 for (auto i : range(size))
    \n-\n-
    93
    \n-\n-
    95
    \n-
    96 for (auto i : range(size))
    \n-
    97 this->BCRSMatrix<B,A>::addindex(i, i);
    \n-
    98
    \n-\n-
    100 }
    \n-
    101
    \n-
    103 BDMatrix& operator= (const BDMatrix& other) {
    \n-
    104 this->BCRSMatrix<B,A>::operator=(other);
    \n-
    105 return *this;
    \n-
    106 }
    \n-
    107
    \n-\n-\n-
    111 return *this;
    \n-
    112 }
    \n-
    113
    \n-
    119 template <class V>
    \n-
    120 void solve (V& x, const V& rhs) const {
    \n-
    121 for (size_type i=0; i<this->N(); i++)
    \n-
    122 {
    \n-
    123 auto&& xv = Impl::asVector(x[i]);
    \n-
    124 auto&& rhsv = Impl::asVector(rhs[i]);
    \n-
    125 Impl::asMatrix((*this)[i][i]).solve(xv,rhsv);
    \n-
    126 }
    \n-
    127 }
    \n-
    128
    \n-
    130 void invert() {
    \n-
    131 for (size_type i=0; i<this->N(); i++)
    \n-
    132 Impl::asMatrix((*this)[i][i]).invert();
    \n-
    133 }
    \n-
    134
    \n-
    135 private:
    \n-
    136
    \n-
    137 // ////////////////////////////////////////////////////////////////////////////
    \n-
    138 // The following methods from the base class should now actually be called
    \n-
    139 // ////////////////////////////////////////////////////////////////////////////
    \n-
    140
    \n-
    141 // createbegin and createend should be in there, too, but I can't get it to compile
    \n-
    142 // BCRSMatrix<B,A>::CreateIterator createbegin () {}
    \n-
    143 // BCRSMatrix<B,A>::CreateIterator createend () {}
    \n-
    144 void setrowsize (size_type i, size_type s) {}
    \n-
    145 void incrementrowsize (size_type i) {}
    \n-
    146 void endrowsizes () {}
    \n-
    147 void addindex (size_type row, size_type col) {}
    \n-
    148 void endindices () {}
    \n-
    149 };
    \n-
    150
    \n-
    151 template<typename B, typename A>
    \n-
    152 struct FieldTraits< BDMatrix<B, A> >
    \n-
    153 {
    \n-\n-
    155 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    156 };
    \n-
    159} // end namespace Dune
    \n-
    160
    \n-
    161#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Implementation of the BCRSMatrix class.
    \n+
    36namespace Dune
    \n+
    37{
    \n+
    38
    \n+
    64 namespace MatrixMarketImpl
    \n+
    65 {
    \n+
    75 template<class T>
    \n+\n+
    77 enum {
    \n+
    81 is_numeric=false
    \n+
    82 };
    \n+
    83 };
    \n+
    84
    \n+
    85 template<>
    \n+
    86 struct mm_numeric_type<int>
    \n+
    87 {
    \n+
    88 enum {
    \n+
    92 is_numeric=true
    \n+
    93 };
    \n+
    94
    \n+
    95 static std::string str()
    \n+
    96 {
    \n+
    97 return "integer";
    \n+
    98 }
    \n+
    99 };
    \n+
    100
    \n+
    101 template<>
    \n+
    102 struct mm_numeric_type<double>
    \n+
    103 {
    \n+
    104 enum {
    \n+
    108 is_numeric=true
    \n+
    109 };
    \n+
    110
    \n+
    111 static std::string str()
    \n+
    112 {
    \n+
    113 return "real";
    \n+
    114 }
    \n+
    115 };
    \n+
    116
    \n+
    117 template<>
    \n+
    118 struct mm_numeric_type<float>
    \n+
    119 {
    \n+
    120 enum {
    \n+
    124 is_numeric=true
    \n+
    125 };
    \n+
    126
    \n+
    127 static std::string str()
    \n+
    128 {
    \n+
    129 return "real";
    \n+
    130 }
    \n+
    131 };
    \n+
    132
    \n+
    133 template<>
    \n+
    134 struct mm_numeric_type<std::complex<double> >
    \n+
    135 {
    \n+
    136 enum {
    \n+
    140 is_numeric=true
    \n+
    141 };
    \n+
    142
    \n+
    143 static std::string str()
    \n+
    144 {
    \n+
    145 return "complex";
    \n+
    146 }
    \n+
    147 };
    \n+
    148
    \n+
    149 template<>
    \n+
    150 struct mm_numeric_type<std::complex<float> >
    \n+
    151 {
    \n+
    152 enum {
    \n+
    156 is_numeric=true
    \n+
    157 };
    \n+
    158
    \n+
    159 static std::string str()
    \n+
    160 {
    \n+
    161 return "complex";
    \n+
    162 }
    \n+
    163 };
    \n+
    164
    \n+
    173 template<class M>
    \n+\n+
    175
    \n+
    176 template<typename T, typename A>
    \n+\n+
    178 {
    \n+
    179 static void print(std::ostream& os)
    \n+
    180 {
    \n+
    181 os<<"%%MatrixMarket matrix coordinate ";
    \n+
    182 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<T>::field_type>>::str()<<" general"<<std::endl;
    \n+
    183 }
    \n+
    184 };
    \n+
    185
    \n+
    186 template<typename B, typename A>
    \n+\n+
    188 {
    \n+
    189 static void print(std::ostream& os)
    \n+
    190 {
    \n+
    191 os<<"%%MatrixMarket matrix array ";
    \n+
    192 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<B>::field_type>>::str()<<" general"<<std::endl;
    \n+
    193 }
    \n+
    194 };
    \n+
    195
    \n+
    196 template<typename T, int j>
    \n+
    197 struct mm_header_printer<FieldVector<T,j> >
    \n+
    198 {
    \n+
    199 static void print(std::ostream& os)
    \n+
    200 {
    \n+
    201 os<<"%%MatrixMarket matrix array ";
    \n+
    202 os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
    \n+
    203 }
    \n+
    204 };
    \n+
    205
    \n+
    206 template<typename T, int i, int j>
    \n+\n+
    208 {
    \n+
    209 static void print(std::ostream& os)
    \n+
    210 {
    \n+
    211 os<<"%%MatrixMarket matrix array ";
    \n+
    212 os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
    \n+
    213 }
    \n+
    214 };
    \n+
    215
    \n+
    224 template<class M>
    \n+\n+
    226
    \n+
    227 template<typename T, typename A>
    \n+\n+
    229 {
    \n+\n+
    231 static_assert(IsNumber<T>::value, "Only scalar entries are expected here!");
    \n+
    232
    \n+
    233 static void print(std::ostream& os, const M&)
    \n+
    234 {
    \n+
    235 os<<"% ISTL_STRUCT blocked ";
    \n+
    236 os<<"1 1"<<std::endl;
    \n+
    237 }
    \n+
    238 };
    \n+
    239
    \n+
    240 template<typename T, typename A, int i>
    \n+
    241 struct mm_block_structure_header<BlockVector<FieldVector<T,i>,A> >
    \n+
    242 {
    \n+\n+
    244
    \n+
    245 static void print(std::ostream& os, const M&)
    \n+
    246 {
    \n+
    247 os<<"% ISTL_STRUCT blocked ";
    \n+
    248 os<<i<<" "<<1<<std::endl;
    \n+
    249 }
    \n+
    250 };
    \n+
    251
    \n+
    252 template<typename T, typename A>
    \n+\n+
    254 {
    \n+\n+
    256 static_assert(IsNumber<T>::value, "Only scalar entries are expected here!");
    \n+
    257
    \n+
    258 static void print(std::ostream& os, const M&)
    \n+
    259 {
    \n+
    260 os<<"% ISTL_STRUCT blocked ";
    \n+
    261 os<<"1 1"<<std::endl;
    \n+
    262 }
    \n+
    263 };
    \n+
    264
    \n+
    265 template<typename T, typename A, int i, int j>
    \n+\n+
    267 {
    \n+\n+
    269
    \n+
    270 static void print(std::ostream& os, const M&)
    \n+
    271 {
    \n+
    272 os<<"% ISTL_STRUCT blocked ";
    \n+
    273 os<<i<<" "<<j<<std::endl;
    \n+
    274 }
    \n+
    275 };
    \n+
    276
    \n+
    277
    \n+
    278 template<typename T, int i, int j>
    \n+\n+
    280 {
    \n+\n+
    282
    \n+
    283 static void print(std::ostream& os, const M& m)
    \n+
    284 {}
    \n+
    285 };
    \n+
    286
    \n+
    287 template<typename T, int i>
    \n+
    288 struct mm_block_structure_header<FieldVector<T,i> >
    \n+
    289 {
    \n+
    290 typedef FieldVector<T,i> M;
    \n+
    291
    \n+
    292 static void print(std::ostream& os, const M& m)
    \n+
    293 {}
    \n+
    294 };
    \n+
    295
    \n+\n+
    297 enum { MM_MAX_LINE_LENGTH=1025 };
    \n+
    298
    \n+\n+
    300
    \n+\n+
    302
    \n+\n+
    304
    \n+
    305 struct MMHeader
    \n+
    306 {
    \n+\n+\n+
    309 {}
    \n+\n+\n+\n+
    313 };
    \n+
    314
    \n+
    315 inline bool lineFeed(std::istream& file)
    \n+
    316 {
    \n+
    317 char c;
    \n+
    318 if(!file.eof())
    \n+
    319 c=file.peek();
    \n+
    320 else
    \n+
    321 return false;
    \n+
    322 // ignore whitespace
    \n+
    323 while(c==' ')
    \n+
    324 {
    \n+
    325 file.get();
    \n+
    326 if(file.eof())
    \n+
    327 return false;
    \n+
    328 c=file.peek();
    \n+
    329 }
    \n+
    330
    \n+
    331 if(c=='\\n') {
    \n+
    332 /* eat the line feed */
    \n+
    333 file.get();
    \n+
    334 return true;
    \n+
    335 }
    \n+
    336 return false;
    \n+
    337 }
    \n+
    338
    \n+
    339 inline void skipComments(std::istream& file)
    \n+
    340 {
    \n+
    341 lineFeed(file);
    \n+
    342 char c=file.peek();
    \n+
    343 // ignore comment lines
    \n+
    344 while(c=='%')
    \n+
    345 {
    \n+
    346 /* discard the rest of the line */
    \n+
    347 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    348 c=file.peek();
    \n+
    349 }
    \n+
    350 }
    \n+
    351
    \n+
    352
    \n+
    353 inline bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)
    \n+
    354 {
    \n+
    355 std::string buffer;
    \n+
    356 char c;
    \n+
    357 file >> buffer;
    \n+
    358 c=buffer[0];
    \n+
    359 mmHeader=MMHeader();
    \n+
    360 if(c!='%')
    \n+
    361 return false;
    \n+
    362 dverb<<buffer<<std::endl;
    \n+
    363 /* read the banner */
    \n+
    364 if(buffer!="%%MatrixMarket") {
    \n+
    365 /* discard the rest of the line */
    \n+
    366 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    367 return false;
    \n+
    368 }
    \n+
    369
    \n+
    370 if(lineFeed(file))
    \n+
    371 /* premature end of line */
    \n+
    372 return false;
    \n+
    373
    \n+
    374 /* read the matrix_type */
    \n+
    375 file >> buffer;
    \n+
    376
    \n+
    377 if(buffer != "matrix")
    \n+
    378 {
    \n+
    379 /* discard the rest of the line */
    \n+
    380 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    381 return false;
    \n+
    382 }
    \n+
    383
    \n+
    384 if(lineFeed(file))
    \n+
    385 /* premature end of line */
    \n+
    386 return false;
    \n+
    387
    \n+
    388 /* The type of the matrix */
    \n+
    389 file >> buffer;
    \n+
    390
    \n+
    391 if(buffer.empty())
    \n+
    392 return false;
    \n+
    393
    \n+
    394 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n+
    395 ::tolower);
    \n+
    396
    \n+
    397 switch(buffer[0])
    \n+
    398 {
    \n+
    399 case 'a' :
    \n+
    400 /* sanity check */
    \n+
    401 if(buffer != "array")
    \n+
    402 {
    \n+
    403 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    404 return false;
    \n+
    405 }
    \n+
    406 mmHeader.type=array_type;
    \n+
    407 break;
    \n+
    408 case 'c' :
    \n+
    409 /* sanity check */
    \n+
    410 if(buffer != "coordinate")
    \n+
    411 {
    \n+
    412 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    413 return false;
    \n+
    414 }
    \n+
    415 mmHeader.type=coordinate_type;
    \n+
    416 break;
    \n+
    417 default :
    \n+
    418 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    419 return false;
    \n+
    420 }
    \n+
    421
    \n+
    422 if(lineFeed(file))
    \n+
    423 /* premature end of line */
    \n+
    424 return false;
    \n+
    425
    \n+
    426 /* The numeric type used. */
    \n+
    427 file >> buffer;
    \n+
    428
    \n+
    429 if(buffer.empty())
    \n+
    430 return false;
    \n+
    431
    \n+
    432 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n+
    433 ::tolower);
    \n+
    434 switch(buffer[0])
    \n+
    435 {
    \n+
    436 case 'i' :
    \n+
    437 /* sanity check */
    \n+
    438 if(buffer != "integer")
    \n+
    439 {
    \n+
    440 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    441 return false;
    \n+
    442 }
    \n+
    443 mmHeader.ctype=integer_type;
    \n+
    444 break;
    \n+
    445 case 'r' :
    \n+
    446 /* sanity check */
    \n+
    447 if(buffer != "real")
    \n+
    448 {
    \n+
    449 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    450 return false;
    \n+
    451 }
    \n+
    452 mmHeader.ctype=double_type;
    \n+
    453 break;
    \n+
    454 case 'c' :
    \n+
    455 /* sanity check */
    \n+
    456 if(buffer != "complex")
    \n+
    457 {
    \n+
    458 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    459 return false;
    \n+
    460 }
    \n+
    461 mmHeader.ctype=complex_type;
    \n+
    462 break;
    \n+
    463 case 'p' :
    \n+
    464 /* sanity check */
    \n+
    465 if(buffer != "pattern")
    \n+
    466 {
    \n+
    467 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    468 return false;
    \n+
    469 }
    \n+
    470 mmHeader.ctype=pattern;
    \n+
    471 break;
    \n+
    472 default :
    \n+
    473 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    474 return false;
    \n+
    475 }
    \n+
    476
    \n+
    477 if(lineFeed(file))
    \n+
    478 return false;
    \n+
    479
    \n+
    480 file >> buffer;
    \n+
    481
    \n+
    482 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
    \n+
    483 ::tolower);
    \n+
    484 switch(buffer[0])
    \n+
    485 {
    \n+
    486 case 'g' :
    \n+
    487 /* sanity check */
    \n+
    488 if(buffer != "general")
    \n+
    489 {
    \n+
    490 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    491 return false;
    \n+
    492 }
    \n+
    493 mmHeader.structure=general;
    \n+
    494 break;
    \n+
    495 case 'h' :
    \n+
    496 /* sanity check */
    \n+
    497 if(buffer != "hermitian")
    \n+
    498 {
    \n+
    499 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    500 return false;
    \n+
    501 }
    \n+
    502 mmHeader.structure=hermitian;
    \n+
    503 break;
    \n+
    504 case 's' :
    \n+
    505 if(buffer.size()==1) {
    \n+
    506 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    507 return false;
    \n+
    508 }
    \n+
    509
    \n+
    510 switch(buffer[1])
    \n+
    511 {
    \n+
    512 case 'y' :
    \n+
    513 /* sanity check */
    \n+
    514 if(buffer != "symmetric")
    \n+
    515 {
    \n+
    516 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    517 return false;
    \n+
    518 }
    \n+
    519 mmHeader.structure=symmetric;
    \n+
    520 break;
    \n+
    521 case 'k' :
    \n+
    522 /* sanity check */
    \n+
    523 if(buffer != "skew-symmetric")
    \n+
    524 {
    \n+
    525 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    526 return false;
    \n+
    527 }
    \n+
    528 mmHeader.structure=skew_symmetric;
    \n+
    529 break;
    \n+
    530 default :
    \n+
    531 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    532 return false;
    \n+
    533 }
    \n+
    534 break;
    \n+
    535 default :
    \n+
    536 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    537 return false;
    \n+
    538 }
    \n+
    539 file.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    540 c=file.peek();
    \n+
    541 return true;
    \n+
    542
    \n+
    543 }
    \n+
    544
    \n+
    545 template<std::size_t brows, std::size_t bcols>
    \n+
    546 std::tuple<std::size_t, std::size_t, std::size_t>
    \n+
    547 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader& header)
    \n+
    548 {
    \n+
    549 std::size_t blockrows=rows/brows;
    \n+
    550 std::size_t blockcols=cols/bcols;
    \n+
    551 std::size_t blocksize=brows*bcols;
    \n+
    552 std::size_t blockentries=0;
    \n+
    553
    \n+
    554 switch(header.structure)
    \n+
    555 {
    \n+
    556 case general :
    \n+
    557 blockentries = entries/blocksize; break;
    \n+
    558 case skew_symmetric :
    \n+
    559 blockentries = 2*entries/blocksize; break;
    \n+
    560 case symmetric :
    \n+
    561 blockentries = (2*entries-rows)/blocksize; break;
    \n+
    562 case hermitian :
    \n+
    563 blockentries = (2*entries-rows)/blocksize; break;
    \n+
    564 default :
    \n+
    565 throw Dune::NotImplemented();
    \n+
    566 }
    \n+
    567 return std::make_tuple(blockrows, blockcols, blockentries);
    \n+
    568 }
    \n+
    569
    \n+
    570 /*
    \n+
    571 * @brief Storage class for the column index and the numeric value.
    \n+
    572 *
    \n+
    573 * \\tparam T Either a NumericWrapper of the numeric type or PatternDummy
    \n+
    574 * for MatrixMarket pattern case.
    \n+
    575 */
    \n+
    576 template<typename T>
    \n+
    577 struct IndexData : public T
    \n+
    578 {
    \n+
    579 std::size_t index = {};
    \n+
    580 };
    \n+
    581
    \n+
    582
    \n+
    593 template<typename T>
    \n+\n+
    595 {
    \n+
    596 T number = {};
    \n+
    597 operator T&()
    \n+
    598 {
    \n+
    599 return number;
    \n+
    600 }
    \n+
    601 };
    \n+
    602
    \n+\n+
    607 {};
    \n+
    608
    \n+
    609 template<>
    \n+\n+
    611 {};
    \n+
    612
    \n+
    613 template<typename T>
    \n+
    614 std::istream& operator>>(std::istream& is, NumericWrapper<T>& num)
    \n+
    615 {
    \n+
    616 return is>>num.number;
    \n+
    617 }
    \n+
    618
    \n+
    619 inline std::istream& operator>>(std::istream& is, [[maybe_unused]] NumericWrapper<PatternDummy>& num)
    \n+
    620 {
    \n+
    621 return is;
    \n+
    622 }
    \n+
    623
    \n+
    629 template<typename T>
    \n+
    630 bool operator<(const IndexData<T>& i1, const IndexData<T>& i2)
    \n+
    631 {
    \n+
    632 return i1.index<i2.index;
    \n+
    633 }
    \n+
    634
    \n+
    640 template<typename T>
    \n+
    641 std::istream& operator>>(std::istream& is, IndexData<T>& data)
    \n+
    642 {
    \n+
    643 is>>data.index;
    \n+
    644 /* MatrixMarket indices are one based. Decrement for C++ */
    \n+
    645 --data.index;
    \n+
    646 return is>>data.number;
    \n+
    647 }
    \n+
    648
    \n+
    654 template<typename T>
    \n+
    655 std::istream& operator>>(std::istream& is, IndexData<NumericWrapper<std::complex<T>>>& data)
    \n+
    656 {
    \n+
    657 is>>data.index;
    \n+
    658 /* MatrixMarket indices are one based. Decrement for C++ */
    \n+
    659 --data.index;
    \n+
    660 // real and imaginary part needs to be read separately as
    \n+
    661 // complex numbers are not provided in pair form. (x,y)
    \n+
    662 NumericWrapper<T> real, imag;
    \n+
    663 is>>real;
    \n+
    664 is>>imag;
    \n+
    665 data.number = {real.number, imag.number};
    \n+
    666 return is;
    \n+
    667 }
    \n+
    668
    \n+
    675 template<typename D, int brows, int bcols>
    \n+\n+
    677 {
    \n+
    683 template<typename T>
    \n+
    684 void operator()(const std::vector<std::set<IndexData<D> > >& rows,
    \n+
    685 BCRSMatrix<T>& matrix)
    \n+
    686 {
    \n+
    687 static_assert(IsNumber<T>::value && brows==1 && bcols==1, "Only scalar entries are expected here!");
    \n+
    688 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)
    \n+
    689 {
    \n+
    690 auto brow=iter.index();
    \n+
    691 for (auto siter=rows[brow].begin(); siter != rows[brow].end(); ++siter)
    \n+
    692 (*iter)[siter->index] = siter->number;
    \n+
    693 }
    \n+
    694 }
    \n+
    695
    \n+
    701 template<typename T>
    \n+
    702 void operator()(const std::vector<std::set<IndexData<D> > >& rows,
    \n+\n+
    704 {
    \n+
    705 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)
    \n+
    706 {
    \n+
    707 for (auto brow=iter.index()*brows,
    \n+
    708 browend=iter.index()*brows+brows;
    \n+
    709 brow<browend; ++brow)
    \n+
    710 {
    \n+
    711 for (auto siter=rows[brow].begin(), send=rows[brow].end();
    \n+
    712 siter != send; ++siter)
    \n+
    713 (*iter)[siter->index/bcols][brow%brows][siter->index%bcols]=siter->number;
    \n+
    714 }
    \n+
    715 }
    \n+
    716 }
    \n+
    717 };
    \n+
    718
    \n+
    719 template<int brows, int bcols>
    \n+\n+
    721 {
    \n+
    722 template<typename M>
    \n+
    723 void operator()(const std::vector<std::set<IndexData<PatternDummy> > >& rows,
    \n+
    724 M& matrix)
    \n+
    725 {}
    \n+
    726 };
    \n+
    727
    \n+
    728 template<class T> struct is_complex : std::false_type {};
    \n+
    729 template<class T> struct is_complex<std::complex<T>> : std::true_type {};
    \n+
    730
    \n+
    731 // wrapper for std::conj. Returns T if T is not complex.
    \n+
    732 template<class T>
    \n+
    733 std::enable_if_t<!is_complex<T>::value, T> conj(const T& r){
    \n+
    734 return r;
    \n+
    735 }
    \n+
    736
    \n+
    737 template<class T>
    \n+
    738 std::enable_if_t<is_complex<T>::value, T> conj(const T& r){
    \n+
    739 return std::conj(r);
    \n+
    740 }
    \n+
    741
    \n+
    742 template<typename M>
    \n+\n+
    744 {};
    \n+
    745
    \n+
    746 template<typename B, typename A>
    \n+\n+
    748 {
    \n+
    749 enum {
    \n+
    750 rows = 1,
    \n+
    751 cols = 1
    \n+
    752 };
    \n+
    753 };
    \n+
    754
    \n+
    755 template<typename B, int i, int j, typename A>
    \n+\n+
    757 {
    \n+
    758 enum {
    \n+
    759 rows = i,
    \n+
    760 cols = j
    \n+
    761 };
    \n+
    762 };
    \n+
    763
    \n+
    764 template<typename T, typename A, typename D>
    \n+\n+
    766 std::istream& file, std::size_t entries,
    \n+
    767 const MMHeader& mmHeader, const D&)
    \n+
    768 {
    \n+\n+
    770
    \n+
    771 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)
    \n+
    772 constexpr int brows = mm_multipliers<Matrix>::rows;
    \n+
    773 constexpr int bcols = mm_multipliers<Matrix>::cols;
    \n+
    774
    \n+
    775 // First path
    \n+
    776 // store entries together with column index in a separate
    \n+
    777 // data structure
    \n+
    778 std::vector<std::set<IndexData<D> > > rows(matrix.N()*brows);
    \n+
    779
    \n+
    780 auto readloop = [&] (auto symmetryFixup) {
    \n+
    781 for(std::size_t i = 0; i < entries; ++i) {
    \n+
    782 std::size_t row;
    \n+
    783 IndexData<D> data;
    \n+
    784 skipComments(file);
    \n+
    785 file>>row;
    \n+
    786 --row; // Index was 1 based.
    \n+
    787 assert(row/bcols<matrix.N());
    \n+
    788 file>>data;
    \n+
    789 assert(data.index/bcols<matrix.M());
    \n+
    790 rows[row].insert(data);
    \n+
    791 if(row!=data.index)
    \n+
    792 symmetryFixup(row, data);
    \n+
    793 }
    \n+
    794 };
    \n+
    795
    \n+
    796 switch(mmHeader.structure)
    \n+
    797 {
    \n+
    798 case general:
    \n+
    799 readloop([](auto...){});
    \n+
    800 break;
    \n+
    801 case symmetric :
    \n+
    802 readloop([&](auto row, auto data) {
    \n+
    803 IndexData<D> data_sym(data);
    \n+
    804 data_sym.index = row;
    \n+
    805 rows[data.index].insert(data_sym);
    \n+
    806 });
    \n+
    807 break;
    \n+
    808 case skew_symmetric :
    \n+
    809 readloop([&](auto row, auto data) {
    \n+
    810 IndexData<D> data_sym;
    \n+
    811 data_sym.number = -data.number;
    \n+
    812 data_sym.index = row;
    \n+
    813 rows[data.index].insert(data_sym);
    \n+
    814 });
    \n+
    815 break;
    \n+
    816 case hermitian :
    \n+
    817 readloop([&](auto row, auto data) {
    \n+
    818 IndexData<D> data_sym;
    \n+
    819 data_sym.number = conj(data.number);
    \n+
    820 data_sym.index = row;
    \n+
    821 rows[data.index].insert(data_sym);
    \n+
    822 });
    \n+
    823 break;
    \n+
    824 default:
    \n+
    825 DUNE_THROW(Dune::NotImplemented,
    \n+
    826 "Only general, symmetric, skew-symmetric and hermitian is supported right now!");
    \n+
    827 }
    \n+
    828
    \n+
    829 // Setup the matrix sparsity pattern
    \n+
    830 int nnz=0;
    \n+
    831 for(typename Matrix::CreateIterator iter=matrix.createbegin();
    \n+
    832 iter!= matrix.createend(); ++iter)
    \n+
    833 {
    \n+
    834 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
    \n+
    835 brow<browend; ++brow)
    \n+
    836 {
    \n+
    837 typedef typename std::set<IndexData<D> >::const_iterator Siter;
    \n+
    838 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
    \n+
    839 siter != send; ++siter, ++nnz)
    \n+
    840 iter.insert(siter->index/bcols);
    \n+
    841 }
    \n+
    842 }
    \n+
    843
    \n+
    844 //Set the matrix values
    \n+
    845 matrix=0;
    \n+
    846
    \n+\n+
    848
    \n+
    849 Setter(rows, matrix);
    \n+
    850 }
    \n+
    851
    \n+
    852 inline std::tuple<std::string, std::string> splitFilename(const std::string& filename) {
    \n+
    853 std::size_t lastdot = filename.find_last_of(".");
    \n+
    854 if(lastdot == std::string::npos)
    \n+
    855 return std::make_tuple(filename, "");
    \n+
    856 else {
    \n+
    857 std::string potentialFileExtension = filename.substr(lastdot);
    \n+
    858 if (potentialFileExtension == ".mm" || potentialFileExtension == ".mtx")
    \n+
    859 return std::make_tuple(filename.substr(0, lastdot), potentialFileExtension);
    \n+
    860 else
    \n+
    861 return std::make_tuple(filename, "");
    \n+
    862 }
    \n+
    863 }
    \n+
    864
    \n+
    865 } // end namespace MatrixMarketImpl
    \n+
    866
    \n+
    867 class MatrixMarketFormatError : public Dune::Exception
    \n+
    868 {};
    \n+
    869
    \n+
    870
    \n+
    871 inline void mm_read_header(std::size_t& rows, std::size_t& cols,
    \n+
    872 MatrixMarketImpl::MMHeader& header, std::istream& istr,
    \n+
    873 bool isVector)
    \n+
    874 {
    \n+
    875 using namespace MatrixMarketImpl;
    \n+
    876
    \n+
    877 if(!readMatrixMarketBanner(istr, header)) {
    \n+
    878 std::cerr << "First line was not a correct Matrix Market banner. Using default:\\n"
    \n+
    879 << "%%MatrixMarket matrix coordinate real general"<<std::endl;
    \n+
    880 // Go to the beginning of the file
    \n+
    881 istr.clear() ;
    \n+
    882 istr.seekg(0, std::ios::beg);
    \n+
    883 if(isVector)
    \n+
    884 header.type=array_type;
    \n+
    885 }
    \n+
    886
    \n+
    887 skipComments(istr);
    \n+
    888
    \n+
    889 if(lineFeed(istr))
    \n+\n+
    891
    \n+
    892 istr >> rows;
    \n+
    893
    \n+
    894 if(lineFeed(istr))
    \n+\n+
    896 istr >> cols;
    \n+
    897 }
    \n+
    898
    \n+
    899 template<typename T, typename A>
    \n+\n+
    901 std::size_t size,
    \n+
    902 std::istream& istr,
    \n+
    903 size_t lane)
    \n+
    904 {
    \n+
    905 for (int i=0; size>0; ++i, --size)
    \n+
    906 istr>>Simd::lane(lane,vector[i]);
    \n+
    907 }
    \n+
    908
    \n+
    909 template<typename T, typename A, int entries>
    \n+
    910 void mm_read_vector_entries(Dune::BlockVector<Dune::FieldVector<T,entries>,A>& vector,
    \n+
    911 std::size_t size,
    \n+
    912 std::istream& istr,
    \n+
    913 size_t lane)
    \n+
    914 {
    \n+
    915 for(int i=0; size>0; ++i, --size) {
    \n+
    916 Simd::Scalar<T> val;
    \n+
    917 istr>>val;
    \n+
    918 Simd::lane(lane, vector[i/entries][i%entries])=val;
    \n+
    919 }
    \n+
    920 }
    \n+
    921
    \n+
    922
    \n+
    929 template<typename T, typename A>
    \n+\n+
    931 std::istream& istr)
    \n+
    932 {
    \n+
    933 typedef typename Dune::BlockVector<T,A>::field_type field_type;
    \n+
    934 using namespace MatrixMarketImpl;
    \n+
    935
    \n+
    936 MMHeader header;
    \n+
    937 std::size_t rows, cols;
    \n+
    938 mm_read_header(rows,cols,header,istr, true);
    \n+
    939 if(cols!=Simd::lanes<field_type>()) {
    \n+
    940 if(Simd::lanes<field_type>() == 1)
    \n+
    941 DUNE_THROW(MatrixMarketFormatError, "cols!=1, therefore this is no vector!");
    \n+
    942 else
    \n+
    943 DUNE_THROW(MatrixMarketFormatError, "cols does not match the number of lanes in the field_type!");
    \n+
    944 }
    \n+
    945
    \n+
    946 if(header.type!=array_type)
    \n+
    947 DUNE_THROW(MatrixMarketFormatError, "Vectors have to be stored in array format!");
    \n+
    948
    \n+
    949
    \n+
    950 if constexpr (Dune::IsNumber<T>())
    \n+
    951 vector.resize(rows);
    \n+
    952 else
    \n+
    953 {
    \n+
    954 T dummy;
    \n+
    955 auto blocksize = dummy.size();
    \n+
    956 std::size_t size=rows/blocksize;
    \n+
    957 if(size*blocksize!=rows)
    \n+
    958 DUNE_THROW(MatrixMarketFormatError, "Block size of vector is not correct!");
    \n+
    959
    \n+
    960 vector.resize(size);
    \n+
    961 }
    \n+
    962
    \n+
    963 istr.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    964 for(size_t l=0;l<Simd::lanes<field_type>();++l){
    \n+
    965 mm_read_vector_entries(vector, rows, istr, l);
    \n+
    966 }
    \n+
    967 }
    \n+
    968
    \n+
    975 template<typename T, typename A>
    \n+\n+
    977 std::istream& istr)
    \n+
    978 {
    \n+
    979 using namespace MatrixMarketImpl;
    \n+\n+
    981
    \n+
    982 MMHeader header;
    \n+
    983 if(!readMatrixMarketBanner(istr, header)) {
    \n+
    984 std::cerr << "First line was not a correct Matrix Market banner. Using default:\\n"
    \n+
    985 << "%%MatrixMarket matrix coordinate real general"<<std::endl;
    \n+
    986 // Go to the beginning of the file
    \n+
    987 istr.clear() ;
    \n+
    988 istr.seekg(0, std::ios::beg);
    \n+
    989 }
    \n+
    990 skipComments(istr);
    \n+
    991
    \n+
    992 std::size_t rows, cols, entries;
    \n+
    993
    \n+
    994 if(lineFeed(istr))
    \n+\n+
    996
    \n+
    997 istr >> rows;
    \n+
    998
    \n+
    999 if(lineFeed(istr))
    \n+\n+
    1001 istr >> cols;
    \n+
    1002
    \n+
    1003 if(lineFeed(istr))
    \n+\n+
    1005
    \n+
    1006 istr >>entries;
    \n+
    1007
    \n+
    1008 std::size_t nnz, blockrows, blockcols;
    \n+
    1009
    \n+
    1010 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)
    \n+
    1011 constexpr int brows = mm_multipliers<Matrix>::rows;
    \n+
    1012 constexpr int bcols = mm_multipliers<Matrix>::cols;
    \n+
    1013
    \n+
    1014 std::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
    \n+
    1015
    \n+
    1016 istr.ignore(std::numeric_limits<std::streamsize>::max(),'\\n');
    \n+
    1017
    \n+
    1018
    \n+
    1019 matrix.setSize(blockrows, blockcols, nnz);
    \n+\n+
    1021
    \n+
    1022 if(header.type==array_type)
    \n+
    1023 DUNE_THROW(Dune::NotImplemented, "Array format currently not supported for matrices!");
    \n+
    1024
    \n+
    1025 readSparseEntries(matrix, istr, entries, header, NumericWrapper<typename Matrix::field_type>());
    \n+
    1026 }
    \n+
    1027
    \n+
    1028 // Print a scalar entry
    \n+
    1029 template<typename B>
    \n+
    1030 void mm_print_entry(const B& entry,
    \n+
    1031 std::size_t rowidx,
    \n+
    1032 std::size_t colidx,
    \n+
    1033 std::ostream& ostr)
    \n+
    1034 {
    \n+
    1035 if constexpr (IsNumber<B>())
    \n+
    1036 ostr << rowidx << " " << colidx << " " << entry << std::endl;
    \n+
    1037 else
    \n+
    1038 {
    \n+
    1039 for (auto row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
    \n+
    1040 int coli=colidx;
    \n+
    1041 for (auto col = row->begin(); col != row->end(); ++col, ++coli)
    \n+
    1042 ostr<< rowidx<<" "<<coli<<" "<<*col<<std::endl;
    \n+
    1043 }
    \n+
    1044 }
    \n+
    1045 }
    \n+
    1046
    \n+
    1047 // Write a vector entry
    \n+
    1048 template<typename V>
    \n+
    1049 void mm_print_vector_entry(const V& entry, std::ostream& ostr,
    \n+
    1050 const std::integral_constant<int,1>&,
    \n+
    1051 size_t lane)
    \n+
    1052 {
    \n+
    1053 ostr<<Simd::lane(lane,entry)<<std::endl;
    \n+
    1054 }
    \n+
    1055
    \n+
    1056 // Write a vector
    \n+
    1057 template<typename V>
    \n+
    1058 void mm_print_vector_entry(const V& vector, std::ostream& ostr,
    \n+
    1059 const std::integral_constant<int,0>&,
    \n+
    1060 size_t lane)
    \n+
    1061 {
    \n+
    1062 using namespace MatrixMarketImpl;
    \n+
    1063
    \n+
    1064 // Is the entry a supported numeric type?
    \n+
    1065 const int isnumeric = mm_numeric_type<Simd::Scalar<typename V::block_type>>::is_numeric;
    \n+
    1066 typedef typename V::const_iterator VIter;
    \n+
    1067
    \n+
    1068 for(VIter i=vector.begin(); i != vector.end(); ++i)
    \n+
    1069
    \n+
    1070 mm_print_vector_entry(*i, ostr,
    \n+
    1071 std::integral_constant<int,isnumeric>(),
    \n+
    1072 lane);
    \n+
    1073 }
    \n+
    1074
    \n+
    1075 template<typename T, typename A>
    \n+
    1076 std::size_t countEntries(const BlockVector<T,A>& vector)
    \n+
    1077 {
    \n+
    1078 return vector.size();
    \n+
    1079 }
    \n+
    1080
    \n+
    1081 template<typename T, typename A, int i>
    \n+
    1082 std::size_t countEntries(const BlockVector<FieldVector<T,i>,A>& vector)
    \n+
    1083 {
    \n+
    1084 return vector.size()*i;
    \n+
    1085 }
    \n+
    1086
    \n+
    1087 // Version for writing vectors.
    \n+
    1088 template<typename V>
    \n+
    1089 void writeMatrixMarket(const V& vector, std::ostream& ostr,
    \n+
    1090 const std::integral_constant<int,0>&)
    \n+
    1091 {
    \n+
    1092 using namespace MatrixMarketImpl;
    \n+
    1093 typedef typename V::field_type field_type;
    \n+
    1094
    \n+
    1095 ostr<<countEntries(vector)<<" "<<Simd::lanes<field_type>()<<std::endl;
    \n+
    1096 const int isnumeric = mm_numeric_type<Simd::Scalar<V>>::is_numeric;
    \n+
    1097 for(size_t l=0;l<Simd::lanes<field_type>(); ++l){
    \n+
    1098 mm_print_vector_entry(vector,ostr, std::integral_constant<int,isnumeric>(), l);
    \n+
    1099 }
    \n+
    1100 }
    \n+
    1101
    \n+
    1102 // Versions for writing matrices
    \n+
    1103 template<typename M>
    \n+
    1104 void writeMatrixMarket(const M& matrix,
    \n+
    1105 std::ostream& ostr,
    \n+
    1106 const std::integral_constant<int,1>&)
    \n+
    1107 {
    \n+
    1108 ostr<<matrix.N()*MatrixMarketImpl::mm_multipliers<M>::rows<<" "
    \n+\n+
    1110 <<countNonZeros(matrix)<<std::endl;
    \n+
    1111
    \n+
    1112 typedef typename M::const_iterator riterator;
    \n+
    1113 typedef typename M::ConstColIterator citerator;
    \n+
    1114 for(riterator row=matrix.begin(); row != matrix.end(); ++row)
    \n+
    1115 for(citerator col = row->begin(); col != row->end(); ++col)
    \n+
    1116 // Matrix Market indexing start with 1!
    \n+\n+\n+
    1119 }
    \n+
    1120
    \n+
    1121
    \n+
    1125 template<typename M>
    \n+
    1126 void writeMatrixMarket(const M& matrix,
    \n+
    1127 std::ostream& ostr)
    \n+
    1128 {
    \n+
    1129 using namespace MatrixMarketImpl;
    \n+
    1130
    \n+
    1131 // Write header information
    \n+
    1132 mm_header_printer<M>::print(ostr);
    \n+
    1133 mm_block_structure_header<M>::print(ostr,matrix);
    \n+
    1134 // Choose the correct function for matrix and vector
    \n+
    1135 writeMatrixMarket(matrix,ostr,std::integral_constant<int,IsMatrix<M>::value>());
    \n+
    1136 }
    \n+
    1137
    \n+
    1138 static const int default_precision = -1;
    \n+
    1150 template<typename M>
    \n+
    1151 void storeMatrixMarket(const M& matrix,
    \n+
    1152 std::string filename,
    \n+
    1153 int prec=default_precision)
    \n+
    1154 {
    \n+
    1155 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n+
    1156 std::string rfilename;
    \n+
    1157 std::ofstream file;
    \n+
    1158 if (extension != "") {
    \n+
    1159 rfilename = pureFilename + extension;
    \n+
    1160 file.open(rfilename.c_str());
    \n+
    1161 if(!file)
    \n+
    1162 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n+
    1163 }
    \n+
    1164 else {
    \n+
    1165 // only try .mm so we do not ignore potential errors
    \n+
    1166 rfilename = pureFilename + ".mm";
    \n+
    1167 file.open(rfilename.c_str());
    \n+
    1168 if(!file)
    \n+
    1169 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n+
    1170 }
    \n+
    1171
    \n+
    1172 file.setf(std::ios::scientific,std::ios::floatfield);
    \n+
    1173 if(prec>0)
    \n+
    1174 file.precision(prec);
    \n+
    1175 writeMatrixMarket(matrix, file);
    \n+
    1176 file.close();
    \n+
    1177 }
    \n+
    1178
    \n+
    1179#if HAVE_MPI
    \n+
    1194 template<typename M, typename G, typename L>
    \n+
    1195 void storeMatrixMarket(const M& matrix,
    \n+
    1196 std::string filename,
    \n+\n+
    1198 bool storeIndices=true,
    \n+
    1199 int prec=default_precision)
    \n+
    1200 {
    \n+
    1201 // Get our rank
    \n+
    1202 int rank = comm.communicator().rank();
    \n+
    1203 // Write the local matrix
    \n+
    1204 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n+
    1205 std::string rfilename;
    \n+
    1206 std::ofstream file;
    \n+
    1207 if (extension != "") {
    \n+
    1208 rfilename = pureFilename + "_" + std::to_string(rank) + extension;
    \n+
    1209 file.open(rfilename.c_str());
    \n+
    1210 dverb<< rfilename <<std::endl;
    \n+
    1211 if(!file)
    \n+
    1212 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n+
    1213 }
    \n+
    1214 else {
    \n+
    1215 // only try .mm so we do not ignore potential errors
    \n+
    1216 rfilename = pureFilename + "_" + std::to_string(rank) + ".mm";
    \n+
    1217 file.open(rfilename.c_str());
    \n+
    1218 dverb<< rfilename <<std::endl;
    \n+
    1219 if(!file)
    \n+
    1220 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n+
    1221 }
    \n+
    1222 file.setf(std::ios::scientific,std::ios::floatfield);
    \n+
    1223 if(prec>0)
    \n+
    1224 file.precision(prec);
    \n+
    1225 writeMatrixMarket(matrix, file);
    \n+
    1226 file.close();
    \n+
    1227
    \n+
    1228 if(!storeIndices)
    \n+
    1229 return;
    \n+
    1230
    \n+
    1231 // Write the global to local index mapping
    \n+
    1232 rfilename = pureFilename + "_" + std::to_string(rank) + ".idx";
    \n+
    1233 file.open(rfilename.c_str());
    \n+
    1234 if(!file)
    \n+
    1235 DUNE_THROW(IOError, "Could not open file for storage: " << rfilename.c_str());
    \n+
    1236 file.setf(std::ios::scientific,std::ios::floatfield);
    \n+\n+
    1238 typedef typename IndexSet::const_iterator Iterator;
    \n+
    1239 for(Iterator iter = comm.indexSet().begin();
    \n+
    1240 iter != comm.indexSet().end(); ++iter) {
    \n+
    1241 file << iter->global()<<" "<<(std::size_t)iter->local()<<" "
    \n+
    1242 <<(int)iter->local().attribute()<<" "<<(int)iter->local().isPublic()<<std::endl;
    \n+
    1243 }
    \n+
    1244 // Store neighbour information for efficient remote indices setup.
    \n+
    1245 file<<"neighbours:";
    \n+
    1246 const std::set<int>& neighbours=comm.remoteIndices().getNeighbours();
    \n+
    1247 typedef std::set<int>::const_iterator SIter;
    \n+
    1248 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end(); ++neighbour) {
    \n+
    1249 file<<" "<< *neighbour;
    \n+
    1250 }
    \n+
    1251 file.close();
    \n+
    1252 }
    \n+
    1253
    \n+
    1268 template<typename M, typename G, typename L>
    \n+
    1269 void loadMatrixMarket(M& matrix,
    \n+
    1270 const std::string& filename,
    \n+\n+
    1272 bool readIndices=true)
    \n+
    1273 {
    \n+
    1274 using namespace MatrixMarketImpl;
    \n+
    1275
    \n+\n+
    1277 typedef typename LocalIndexT::Attribute Attribute;
    \n+
    1278 // Get our rank
    \n+
    1279 int rank = comm.communicator().rank();
    \n+
    1280 // load local matrix
    \n+
    1281 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n+
    1282 std::string rfilename;
    \n+
    1283 std::ifstream file;
    \n+
    1284 if (extension != "") {
    \n+
    1285 rfilename = pureFilename + "_" + std::to_string(rank) + extension;
    \n+
    1286 file.open(rfilename.c_str(), std::ios::in);
    \n+
    1287 dverb<< rfilename <<std::endl;
    \n+
    1288 if(!file)
    \n+
    1289 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n+
    1290 }
    \n+
    1291 else {
    \n+
    1292 // try both .mm and .mtx
    \n+
    1293 rfilename = pureFilename + "_" + std::to_string(rank) + ".mm";
    \n+
    1294 file.open(rfilename.c_str(), std::ios::in);
    \n+
    1295 if(!file) {
    \n+
    1296 rfilename = pureFilename + "_" + std::to_string(rank) + ".mtx";
    \n+
    1297 file.open(rfilename.c_str(), std::ios::in);
    \n+
    1298 dverb<< rfilename <<std::endl;
    \n+
    1299 if(!file)
    \n+
    1300 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n+
    1301 }
    \n+
    1302 }
    \n+
    1303 readMatrixMarket(matrix,file);
    \n+
    1304 file.close();
    \n+
    1305
    \n+
    1306 if(!readIndices)
    \n+
    1307 return;
    \n+
    1308
    \n+
    1309 // read indices
    \n+\n+
    1311 IndexSet& pis=comm.pis;
    \n+
    1312 rfilename = pureFilename + "_" + std::to_string(rank) + ".idx";
    \n+
    1313 file.open(rfilename.c_str());
    \n+
    1314 if(!file)
    \n+
    1315 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n+
    1316 if(pis.size()!=0)
    \n+
    1317 DUNE_THROW(InvalidIndexSetState, "Index set is not empty!");
    \n+
    1318
    \n+
    1319 pis.beginResize();
    \n+
    1320 while(!file.eof() && file.peek()!='n') {
    \n+
    1321 G g;
    \n+
    1322 file >>g;
    \n+
    1323 std::size_t l;
    \n+
    1324 file >>l;
    \n+
    1325 int c;
    \n+
    1326 file >>c;
    \n+
    1327 bool b;
    \n+
    1328 file >> b;
    \n+
    1329 pis.add(g,LocalIndexT(l,Attribute(c),b));
    \n+
    1330 lineFeed(file);
    \n+
    1331 }
    \n+
    1332 pis.endResize();
    \n+
    1333 if(!file.eof()) {
    \n+
    1334 // read neighbours
    \n+
    1335 std::string s;
    \n+
    1336 file>>s;
    \n+
    1337 if(s!="neighbours:")
    \n+
    1338 DUNE_THROW(MatrixMarketFormatError, "was expecting the string: \\"neighbours:\\"");
    \n+
    1339 std::set<int> nb;
    \n+
    1340 while(!file.eof()) {
    \n+
    1341 int i;
    \n+
    1342 file >> i;
    \n+
    1343 nb.insert(i);
    \n+
    1344 }
    \n+
    1345 file.close();
    \n+
    1346 comm.ri.setNeighbours(nb);
    \n+
    1347 }
    \n+
    1348 comm.ri.template rebuild<false>();
    \n+
    1349 }
    \n+
    1350
    \n+
    1351 #endif
    \n+
    1352
    \n+
    1363 template<typename M>
    \n+
    1364 void loadMatrixMarket(M& matrix,
    \n+
    1365 const std::string& filename)
    \n+
    1366 {
    \n+
    1367 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
    \n+
    1368 std::string rfilename;
    \n+
    1369 std::ifstream file;
    \n+
    1370 if (extension != "") {
    \n+
    1371 rfilename = pureFilename + extension;
    \n+
    1372 file.open(rfilename.c_str());
    \n+
    1373 if(!file)
    \n+
    1374 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n+
    1375 }
    \n+
    1376 else {
    \n+
    1377 // try both .mm and .mtx
    \n+
    1378 rfilename = pureFilename + ".mm";
    \n+
    1379 file.open(rfilename.c_str(), std::ios::in);
    \n+
    1380 if(!file) {
    \n+
    1381 rfilename = pureFilename + ".mtx";
    \n+
    1382 file.open(rfilename.c_str(), std::ios::in);
    \n+
    1383 if(!file)
    \n+
    1384 DUNE_THROW(IOError, "Could not open file: " << rfilename.c_str());
    \n+
    1385 }
    \n+
    1386 }
    \n+
    1387 readMatrixMarket(matrix,file);
    \n+
    1388 file.close();
    \n+
    1389 }
    \n+
    1390
    \n+
    1392}
    \n+
    1393#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Some handy generic functions for ISTL matrices.
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
    Get the number of nonzero fields in the matrix.
    Definition: matrixutils.hh:119
    \n+
    void readMatrixMarket(Dune::BlockVector< T, A > &vector, std::istream &istr)
    Reads a BlockVector from a matrix market file.
    Definition: matrixmarket.hh:930
    \n+
    void storeMatrixMarket(const M &matrix, std::string filename, int prec=default_precision)
    Stores a parallel matrix/vector in matrix market format in a file.
    Definition: matrixmarket.hh:1151
    \n+
    void loadMatrixMarket(M &matrix, const std::string &filename, OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)
    Load a parallel matrix/vector stored in matrix market format.
    Definition: matrixmarket.hh:1269
    \n+
    std::size_t countEntries(const BlockVector< T, A > &vector)
    Definition: matrixmarket.hh:1076
    \n+
    void writeMatrixMarket(const V &vector, std::ostream &ostr, const std::integral_constant< int, 0 > &)
    Definition: matrixmarket.hh:1089
    \n+
    void mm_print_vector_entry(const V &entry, std::ostream &ostr, const std::integral_constant< int, 1 > &, size_t lane)
    Definition: matrixmarket.hh:1049
    \n+
    static const int default_precision
    Definition: matrixmarket.hh:1138
    \n+
    void mm_read_vector_entries(Dune::BlockVector< T, A > &vector, std::size_t size, std::istream &istr, size_t lane)
    Definition: matrixmarket.hh:900
    \n+
    void mm_read_header(std::size_t &rows, std::size_t &cols, MatrixMarketImpl::MMHeader &header, std::istream &istr, bool isVector)
    Definition: matrixmarket.hh:871
    \n+
    void mm_print_entry(const B &entry, std::size_t rowidx, std::size_t colidx, std::ostream &ostr)
    Definition: matrixmarket.hh:1030
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n+
    std::tuple< std::size_t, std::size_t, std::size_t > calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const MMHeader &header)
    Definition: matrixmarket.hh:547
    \n+
    bool operator<(const IndexData< T > &i1, const IndexData< T > &i2)
    LessThan operator.
    Definition: matrixmarket.hh:630
    \n+
    LineType
    Definition: matrixmarket.hh:296
    \n+
    @ DATA
    Definition: matrixmarket.hh:296
    \n+
    @ MM_HEADER
    Definition: matrixmarket.hh:296
    \n+
    @ MM_ISTLSTRUCT
    Definition: matrixmarket.hh:296
    \n+
    bool readMatrixMarketBanner(std::istream &file, MMHeader &mmHeader)
    Definition: matrixmarket.hh:353
    \n+
    std::enable_if_t< is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:738
    \n+
    void readSparseEntries(Dune::BCRSMatrix< T, A > &matrix, std::istream &file, std::size_t entries, const MMHeader &mmHeader, const D &)
    Definition: matrixmarket.hh:765
    \n+
    MM_TYPE
    Definition: matrixmarket.hh:299
    \n+
    @ array_type
    Definition: matrixmarket.hh:299
    \n+
    @ coordinate_type
    Definition: matrixmarket.hh:299
    \n+
    @ unknown_type
    Definition: matrixmarket.hh:299
    \n+
    std::istream & operator>>(std::istream &is, NumericWrapper< T > &num)
    Definition: matrixmarket.hh:614
    \n+
    void skipComments(std::istream &file)
    Definition: matrixmarket.hh:339
    \n+
    bool lineFeed(std::istream &file)
    Definition: matrixmarket.hh:315
    \n+
    @ MM_MAX_LINE_LENGTH
    Definition: matrixmarket.hh:297
    \n+
    MM_STRUCTURE
    Definition: matrixmarket.hh:303
    \n+
    @ skew_symmetric
    Definition: matrixmarket.hh:303
    \n+
    @ general
    Definition: matrixmarket.hh:303
    \n+
    @ hermitian
    Definition: matrixmarket.hh:303
    \n+
    @ unknown_structure
    Definition: matrixmarket.hh:303
    \n+
    @ symmetric
    Definition: matrixmarket.hh:303
    \n+
    MM_CTYPE
    Definition: matrixmarket.hh:301
    \n+
    @ unknown_ctype
    Definition: matrixmarket.hh:301
    \n+
    @ pattern
    Definition: matrixmarket.hh:301
    \n+
    @ complex_type
    Definition: matrixmarket.hh:301
    \n+
    @ double_type
    Definition: matrixmarket.hh:301
    \n+
    @ integer_type
    Definition: matrixmarket.hh:301
    \n+
    std::enable_if_t<!is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:733
    \n+
    std::tuple< std::string, std::string > splitFilename(const std::string &filename)
    Definition: matrixmarket.hh:852
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    void endrowsizes()
    indicate that size of all rows is defined
    Definition: bcrsmatrix.hh:1149
    \n-
    void setrowsize(size_type i, size_type s)
    Set number of indices in row i to s.
    Definition: bcrsmatrix.hh:1117
    \n-
    @ random
    Build entries randomly.
    Definition: bcrsmatrix.hh:530
    \n-
    void addindex(size_type row, size_type col)
    add index (row,col) to the matrix
    Definition: bcrsmatrix.hh:1191
    \n-
    void endindices()
    indicate that all indices are defined, check consistency
    Definition: bcrsmatrix.hh:1248
    \n-
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n+
    Iterator begin()
    Get iterator to first row.
    Definition: bcrsmatrix.hh:675
    \n+
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n+
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: bcrsmatrix.hh:1103
    \n+
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n+
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n+
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n+
    void setBuildMode(BuildMode bm)
    Sets the build mode of the matrix.
    Definition: bcrsmatrix.hh:833
    \n
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n-
    BCRSMatrix & operator=(const BCRSMatrix &Mat)
    assignment
    Definition: bcrsmatrix.hh:911
    \n-
    A block-diagonal matrix.
    Definition: bdmatrix.hh:33
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bdmatrix.hh:39
    \n-
    A::size_type size_type
    implement row_type with compressed vector
    Definition: bdmatrix.hh:51
    \n-
    BDMatrix()
    Default constructor.
    Definition: bdmatrix.hh:58
    \n-
    BDMatrix(std::initializer_list< B > const &list)
    Construct from a std::initializer_list.
    Definition: bdmatrix.hh:76
    \n-
    B block_type
    export the type representing the components
    Definition: bdmatrix.hh:42
    \n-
    void solve(V &x, const V &rhs) const
    Solve the system Ax=b in O(n) time.
    Definition: bdmatrix.hh:120
    \n-
    A allocator_type
    export the allocator type
    Definition: bdmatrix.hh:45
    \n-
    BDMatrix(int size)
    Definition: bdmatrix.hh:60
    \n-
    BDMatrix & operator=(const BDMatrix &other)
    assignment
    Definition: bdmatrix.hh:103
    \n-
    static constexpr unsigned int blocklevel
    increment block level counter
    Definition: bdmatrix.hh:55
    \n-
    void setSize(size_type size)
    Resize the matrix. Invalidates the content!
    Definition: bdmatrix.hh:85
    \n-
    void invert()
    Inverts the matrix.
    Definition: bdmatrix.hh:130
    \n-
    typename BDMatrix< B, A >::field_type field_type
    Definition: bdmatrix.hh:154
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: bdmatrix.hh:155
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    void resize(size_type size)
    Resize the vector.
    Definition: bvector.hh:503
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    Helper metaprogram to get the matrix market string representation of the numeric type.
    Definition: matrixmarket.hh:76
    \n+
    @ is_numeric
    Whether T is a supported numeric type.
    Definition: matrixmarket.hh:81
    \n+
    static std::string str()
    Definition: matrixmarket.hh:95
    \n+
    static std::string str()
    Definition: matrixmarket.hh:111
    \n+
    static std::string str()
    Definition: matrixmarket.hh:127
    \n+
    static std::string str()
    Definition: matrixmarket.hh:143
    \n+
    static std::string str()
    Definition: matrixmarket.hh:159
    \n+
    Meta program to write the correct Matrix Market header.
    Definition: matrixmarket.hh:174
    \n+
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:179
    \n+
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:189
    \n+
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:199
    \n+
    static void print(std::ostream &os)
    Definition: matrixmarket.hh:209
    \n+
    Metaprogram for writing the ISTL block structure header.
    Definition: matrixmarket.hh:225
    \n+
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:233
    \n+
    BlockVector< T, A > M
    Definition: matrixmarket.hh:230
    \n+
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:245
    \n+
    BCRSMatrix< T, A > M
    Definition: matrixmarket.hh:255
    \n+
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:258
    \n+
    static void print(std::ostream &os, const M &)
    Definition: matrixmarket.hh:270
    \n+
    static void print(std::ostream &os, const M &m)
    Definition: matrixmarket.hh:283
    \n+
    FieldMatrix< T, i, j > M
    Definition: matrixmarket.hh:281
    \n+
    static void print(std::ostream &os, const M &m)
    Definition: matrixmarket.hh:292
    \n+
    FieldVector< T, i > M
    Definition: matrixmarket.hh:290
    \n+
    Definition: matrixmarket.hh:306
    \n+
    MM_STRUCTURE structure
    Definition: matrixmarket.hh:312
    \n+
    MM_TYPE type
    Definition: matrixmarket.hh:310
    \n+
    MMHeader()
    Definition: matrixmarket.hh:307
    \n+
    MM_CTYPE ctype
    Definition: matrixmarket.hh:311
    \n+
    Definition: matrixmarket.hh:578
    \n+
    std::size_t index
    Definition: matrixmarket.hh:579
    \n+
    a wrapper class of numeric values.
    Definition: matrixmarket.hh:595
    \n+
    T number
    Definition: matrixmarket.hh:596
    \n+
    Utility class for marking the pattern type of the MatrixMarket matrices.
    Definition: matrixmarket.hh:607
    \n+\n+
    Functor to the data values of the matrix.
    Definition: matrixmarket.hh:677
    \n+
    void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< T > &matrix)
    Sets the matrix values.
    Definition: matrixmarket.hh:684
    \n+
    void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< FieldMatrix< T, brows, bcols > > &matrix)
    Sets the matrix values.
    Definition: matrixmarket.hh:702
    \n+
    void operator()(const std::vector< std::set< IndexData< PatternDummy > > > &rows, M &matrix)
    Definition: matrixmarket.hh:723
    \n+
    Definition: matrixmarket.hh:728
    \n+
    Definition: matrixmarket.hh:744
    \n+
    Definition: matrixmarket.hh:868
    \n+
    Definition: matrixutils.hh:27
    \n+
    Test whether a type is an ISTL Matrix.
    Definition: matrixutils.hh:504
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n+
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n+
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n+
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,245 +4,1631 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-bdmatrix.hh\n+matrixmarket.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_BDMATRIX_HH\n- 6#define DUNE_ISTL_BDMATRIX_HH\n+ 5#ifndef DUNE_ISTL_MATRIXMARKET_HH\n+ 6#define DUNE_ISTL_MATRIXMARKET_HH\n 7\n- 8#include \n- 9\n- 10#include \n- 11#include \n- 12\n- 13#include \n- 14#include \n- 15\n- 21namespace Dune {\n- 31 template >\n-32 class BDMatrix : public BCRSMatrix\n- 33 {\n- 34 public:\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23\n+ 24#include \n+ 25#include \n+ 26#include \n+ 27#include \n+ 28#include \n+ 29#include \n+ 30\n+ 31#include \n+ 32#include \n+ 33#include // countNonZeros()\n+ 34#include \n 35\n- 36 //===== type definitions and constants\n- 37\n-39 using field_type = typename Imp::BlockTraits::field_type;\n- 40\n-42 typedef B block_type;\n- 43\n-45 typedef A allocator_type;\n- 46\n- 48 //typedef BCRSMatrix::row_type row_type;\n- 49\n-51 typedef typename A::size_type size_type;\n- 52\n- 54 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-55 static constexpr unsigned int blocklevel = blockLevel()+1;\n- 56\n-58 BDMatrix() : BCRSMatrix() {}\n- 59\n-60 explicit BDMatrix(int size)\n- 61 : BCRSMatrix(size, size, BCRSMatrix::random) {\n- 62\n- 63 for (int i=0; iBCRSMatrix::setrowsize(i, 1);\n- 65\n- 66 this->BCRSMatrix::endrowsizes();\n- 67\n- 68 for (int i=0; iBCRSMatrix::addindex(i, i);\n- 70\n- 71 this->BCRSMatrix::endindices();\n- 72\n- 73 }\n- 74\n-76 BDMatrix (std::initializer_list const &list)\n- 77 : BDMatrix(list.size())\n- 78 {\n- 79 size_t i=0;\n- 80 for (auto it = list.begin(); it != list.end(); ++it, ++i)\n- 81 (*this)[i][i] = *it;\n- 82 }\n- 83\n-85 void setSize(size_type size)\n- 86 {\n- 87 this->BCRSMatrix::setSize(size, // rows\n- 88 size, // columns\n- 89 size); // nonzeros\n- 90\n- 91 for (auto i : range(size))\n- 92 this->BCRSMatrix::setrowsize(i, 1);\n- 93\n- 94 this->BCRSMatrix::endrowsizes();\n- 95\n- 96 for (auto i : range(size))\n- 97 this->BCRSMatrix::addindex(i, i);\n- 98\n- 99 this->BCRSMatrix::endindices();\n- 100 }\n- 101\n-103 BDMatrix& operator=(const BDMatrix& other) {\n- 104 this->BCRSMatrix::operator=(other);\n- 105 return *this;\n- 106 }\n- 107\n-109 BDMatrix& operator=(const field_type& k) {\n- 110 this->BCRSMatrix::operator=(k);\n- 111 return *this;\n- 112 }\n- 113\n- 119 template \n-120 void solve (V& x, const V& rhs) const {\n- 121 for (size_type i=0; iN(); i++)\n- 122 {\n- 123 auto&& xv = Impl::asVector(x[i]);\n- 124 auto&& rhsv = Impl::asVector(rhs[i]);\n- 125 Impl::asMatrix((*this)[i][i]).solve(xv,rhsv);\n- 126 }\n- 127 }\n- 128\n-130 void invert() {\n- 131 for (size_type i=0; iN(); i++)\n- 132 Impl::asMatrix((*this)[i][i]).invert();\n- 133 }\n- 134\n- 135 private:\n- 136\n- 137 // ///////////////////////////////////////////////////////////////////////\n-/////\n- 138 // The following methods from the base class should now actually be called\n- 139 // ///////////////////////////////////////////////////////////////////////\n-/////\n- 140\n- 141 // createbegin and createend should be in there, too, but I can't get it\n-to compile\n- 142 // BCRSMatrix::CreateIterator createbegin () {}\n- 143 // BCRSMatrix::CreateIterator createend () {}\n- 144 void setrowsize (size_type i, size_type s) {}\n- 145 void incrementrowsize (size_type i) {}\n- 146 void endrowsizes () {}\n- 147 void addindex (size_type row, size_type col) {}\n- 148 void endindices () {}\n- 149 };\n- 150\n- 151 template\n-152 struct FieldTraits< BDMatrix >\n- 153 {\n-154 using field_type = typename BDMatrix::field_type;\n-155 using real_type = typename FieldTraits::real_type;\n- 156 };\n- 159} // end namespace Dune\n- 160\n- 161#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n+ 36namespace Dune\n+ 37{\n+ 38\n+64 namespace MatrixMarketImpl\n+ 65 {\n+ 75 template\n+76 struct mm_numeric_type {\n+ 77 enum {\n+ 81 is_numeric=false\n+82 };\n+ 83 };\n+ 84\n+ 85 template<>\n+86 struct mm_numeric_type\n+ 87 {\n+ 88 enum {\n+ 92 is_numeric=true\n+93 };\n+ 94\n+95 static std::string str()\n+ 96 {\n+ 97 return \"integer\";\n+ 98 }\n+ 99 };\n+ 100\n+ 101 template<>\n+102 struct mm_numeric_type\n+ 103 {\n+ 104 enum {\n+ 108 is_numeric=true\n+109 };\n+ 110\n+111 static std::string str()\n+ 112 {\n+ 113 return \"real\";\n+ 114 }\n+ 115 };\n+ 116\n+ 117 template<>\n+118 struct mm_numeric_type\n+ 119 {\n+ 120 enum {\n+ 124 is_numeric=true\n+125 };\n+ 126\n+127 static std::string str()\n+ 128 {\n+ 129 return \"real\";\n+ 130 }\n+ 131 };\n+ 132\n+ 133 template<>\n+134 struct mm_numeric_type >\n+ 135 {\n+ 136 enum {\n+ 140 is_numeric=true\n+141 };\n+ 142\n+143 static std::string str()\n+ 144 {\n+ 145 return \"complex\";\n+ 146 }\n+ 147 };\n+ 148\n+ 149 template<>\n+150 struct mm_numeric_type >\n+ 151 {\n+ 152 enum {\n+ 156 is_numeric=true\n+157 };\n+ 158\n+159 static std::string str()\n+ 160 {\n+ 161 return \"complex\";\n+ 162 }\n+ 163 };\n+ 164\n+ 173 template\n+174 struct mm_header_printer;\n+ 175\n+ 176 template\n+177 struct mm_header_printer >\n+ 178 {\n+179 static void print(std::ostream& os)\n+ 180 {\n+ 181 os<<\"%%MatrixMarket matrix coordinate \";\n+ 182 os<::\n+field_type>>::str()<<\" general\"<\n+187 struct mm_header_printer >\n+ 188 {\n+189 static void print(std::ostream& os)\n+ 190 {\n+ 191 os<<\"%%MatrixMarket matrix array \";\n+ 192 os<::\n+field_type>>::str()<<\" general\"<\n+197 struct mm_header_printer >\n+ 198 {\n+199 static void print(std::ostream& os)\n+ 200 {\n+ 201 os<<\"%%MatrixMarket matrix array \";\n+ 202 os<::str()<<\" general\"<\n+207 struct mm_header_printer >\n+ 208 {\n+209 static void print(std::ostream& os)\n+ 210 {\n+ 211 os<<\"%%MatrixMarket matrix array \";\n+ 212 os<::str()<<\" general\"<\n+225 struct mm_block_structure_header;\n+ 226\n+ 227 template\n+228 struct mm_block_structure_header >\n+ 229 {\n+230 typedef BlockVector M;\n+ 231 static_assert(IsNumber::value, \"Only scalar entries are expected\n+here!\");\n+ 232\n+233 static void print(std::ostream& os, const M&)\n+ 234 {\n+ 235 os<<\"% ISTL_STRUCT blocked \";\n+ 236 os<<\"1 1\"<\n+241 struct mm_block_structure_header,A> >\n+ 242 {\n+243 typedef BlockVector,A> M;\n+ 244\n+245 static void print(std::ostream& os, const M&)\n+ 246 {\n+ 247 os<<\"% ISTL_STRUCT blocked \";\n+ 248 os<\n+253 struct mm_block_structure_header >\n+ 254 {\n+255 typedef BCRSMatrix M;\n+ 256 static_assert(IsNumber::value, \"Only scalar entries are expected\n+here!\");\n+ 257\n+258 static void print(std::ostream& os, const M&)\n+ 259 {\n+ 260 os<<\"% ISTL_STRUCT blocked \";\n+ 261 os<<\"1 1\"<\n+266 struct mm_block_structure_header,A> >\n+ 267 {\n+268 typedef BCRSMatrix,A> M;\n+ 269\n+270 static void print(std::ostream& os, const M&)\n+ 271 {\n+ 272 os<<\"% ISTL_STRUCT blocked \";\n+ 273 os<\n+279 struct mm_block_structure_header >\n+ 280 {\n+281 typedef FieldMatrix M;\n+ 282\n+283 static void print(std::ostream& os, const M& m)\n+ 284 {}\n+ 285 };\n+ 286\n+ 287 template\n+288 struct mm_block_structure_header >\n+ 289 {\n+290 typedef FieldVector M;\n+ 291\n+292 static void print(std::ostream& os, const M& m)\n+ 293 {}\n+ 294 };\n+ 295\n+296 enum LineType { MM_HEADER, MM_ISTLSTRUCT, DATA };\n+297 enum { MM_MAX_LINE_LENGTH=1025 };\n+ 298\n+299 enum MM_TYPE { coordinate_type, array_type, unknown_type };\n+ 300\n+301 enum MM_CTYPE { integer_type, double_type, complex_type, pattern,\n+unknown_ctype };\n+ 302\n+303 enum MM_STRUCTURE { general, symmetric, skew_symmetric, hermitian,\n+unknown_structure };\n+ 304\n+305 struct MMHeader\n+ 306 {\n+307 MMHeader()\n+ 308 : type(coordinate_type), ctype(double_type), structure(general)\n+ 309 {}\n+310 MM_TYPE type;\n+311 MM_CTYPE ctype;\n+312 MM_STRUCTURE structure;\n+ 313 };\n+ 314\n+315 inline bool lineFeed(std::istream& file)\n+ 316 {\n+ 317 char c;\n+ 318 if(!file.eof())\n+ 319 c=file.peek();\n+ 320 else\n+ 321 return false;\n+ 322 // ignore whitespace\n+ 323 while(c==' ')\n+ 324 {\n+ 325 file.get();\n+ 326 if(file.eof())\n+ 327 return false;\n+ 328 c=file.peek();\n+ 329 }\n+ 330\n+ 331 if(c=='\\n') {\n+ 332 /* eat the line feed */\n+ 333 file.get();\n+ 334 return true;\n+ 335 }\n+ 336 return false;\n+ 337 }\n+ 338\n+339 inline void skipComments(std::istream& file)\n+ 340 {\n+ 341 lineFeed(file);\n+ 342 char c=file.peek();\n+ 343 // ignore comment lines\n+ 344 while(c=='%')\n+ 345 {\n+ 346 /* discard the rest of the line */\n+ 347 file.ignore(std::numeric_limits::max(),'\\n');\n+ 348 c=file.peek();\n+ 349 }\n+ 350 }\n+ 351\n+ 352\n+353 inline bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)\n+ 354 {\n+ 355 std::string buffer;\n+ 356 char c;\n+ 357 file >> buffer;\n+ 358 c=buffer[0];\n+ 359 mmHeader=MMHeader();\n+ 360 if(c!='%')\n+ 361 return false;\n+ 362 dverb<::max(),'\\n');\n+ 367 return false;\n+ 368 }\n+ 369\n+ 370 if(lineFeed(file))\n+ 371 /* premature end of line */\n+ 372 return false;\n+ 373\n+ 374 /* read the matrix_type */\n+ 375 file >> buffer;\n+ 376\n+ 377 if(buffer != \"matrix\")\n+ 378 {\n+ 379 /* discard the rest of the line */\n+ 380 file.ignore(std::numeric_limits::max(),'\\n');\n+ 381 return false;\n+ 382 }\n+ 383\n+ 384 if(lineFeed(file))\n+ 385 /* premature end of line */\n+ 386 return false;\n+ 387\n+ 388 /* The type of the matrix */\n+ 389 file >> buffer;\n+ 390\n+ 391 if(buffer.empty())\n+ 392 return false;\n+ 393\n+ 394 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n+ 395 ::tolower);\n+ 396\n+ 397 switch(buffer[0])\n+ 398 {\n+ 399 case 'a' :\n+ 400 /* sanity check */\n+ 401 if(buffer != \"array\")\n+ 402 {\n+ 403 file.ignore(std::numeric_limits::max(),'\\n');\n+ 404 return false;\n+ 405 }\n+ 406 mmHeader.type=array_type;\n+ 407 break;\n+ 408 case 'c' :\n+ 409 /* sanity check */\n+ 410 if(buffer != \"coordinate\")\n+ 411 {\n+ 412 file.ignore(std::numeric_limits::max(),'\\n');\n+ 413 return false;\n+ 414 }\n+ 415 mmHeader.type=coordinate_type;\n+ 416 break;\n+ 417 default :\n+ 418 file.ignore(std::numeric_limits::max(),'\\n');\n+ 419 return false;\n+ 420 }\n+ 421\n+ 422 if(lineFeed(file))\n+ 423 /* premature end of line */\n+ 424 return false;\n+ 425\n+ 426 /* The numeric type used. */\n+ 427 file >> buffer;\n+ 428\n+ 429 if(buffer.empty())\n+ 430 return false;\n+ 431\n+ 432 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n+ 433 ::tolower);\n+ 434 switch(buffer[0])\n+ 435 {\n+ 436 case 'i' :\n+ 437 /* sanity check */\n+ 438 if(buffer != \"integer\")\n+ 439 {\n+ 440 file.ignore(std::numeric_limits::max(),'\\n');\n+ 441 return false;\n+ 442 }\n+ 443 mmHeader.ctype=integer_type;\n+ 444 break;\n+ 445 case 'r' :\n+ 446 /* sanity check */\n+ 447 if(buffer != \"real\")\n+ 448 {\n+ 449 file.ignore(std::numeric_limits::max(),'\\n');\n+ 450 return false;\n+ 451 }\n+ 452 mmHeader.ctype=double_type;\n+ 453 break;\n+ 454 case 'c' :\n+ 455 /* sanity check */\n+ 456 if(buffer != \"complex\")\n+ 457 {\n+ 458 file.ignore(std::numeric_limits::max(),'\\n');\n+ 459 return false;\n+ 460 }\n+ 461 mmHeader.ctype=complex_type;\n+ 462 break;\n+ 463 case 'p' :\n+ 464 /* sanity check */\n+ 465 if(buffer != \"pattern\")\n+ 466 {\n+ 467 file.ignore(std::numeric_limits::max(),'\\n');\n+ 468 return false;\n+ 469 }\n+ 470 mmHeader.ctype=pattern;\n+ 471 break;\n+ 472 default :\n+ 473 file.ignore(std::numeric_limits::max(),'\\n');\n+ 474 return false;\n+ 475 }\n+ 476\n+ 477 if(lineFeed(file))\n+ 478 return false;\n+ 479\n+ 480 file >> buffer;\n+ 481\n+ 482 std::transform(buffer.begin(), buffer.end(), buffer.begin(),\n+ 483 ::tolower);\n+ 484 switch(buffer[0])\n+ 485 {\n+ 486 case 'g' :\n+ 487 /* sanity check */\n+ 488 if(buffer != \"general\")\n+ 489 {\n+ 490 file.ignore(std::numeric_limits::max(),'\\n');\n+ 491 return false;\n+ 492 }\n+ 493 mmHeader.structure=general;\n+ 494 break;\n+ 495 case 'h' :\n+ 496 /* sanity check */\n+ 497 if(buffer != \"hermitian\")\n+ 498 {\n+ 499 file.ignore(std::numeric_limits::max(),'\\n');\n+ 500 return false;\n+ 501 }\n+ 502 mmHeader.structure=hermitian;\n+ 503 break;\n+ 504 case 's' :\n+ 505 if(buffer.size()==1) {\n+ 506 file.ignore(std::numeric_limits::max(),'\\n');\n+ 507 return false;\n+ 508 }\n+ 509\n+ 510 switch(buffer[1])\n+ 511 {\n+ 512 case 'y' :\n+ 513 /* sanity check */\n+ 514 if(buffer != \"symmetric\")\n+ 515 {\n+ 516 file.ignore(std::numeric_limits::max(),'\\n');\n+ 517 return false;\n+ 518 }\n+ 519 mmHeader.structure=symmetric;\n+ 520 break;\n+ 521 case 'k' :\n+ 522 /* sanity check */\n+ 523 if(buffer != \"skew-symmetric\")\n+ 524 {\n+ 525 file.ignore(std::numeric_limits::max(),'\\n');\n+ 526 return false;\n+ 527 }\n+ 528 mmHeader.structure=skew_symmetric;\n+ 529 break;\n+ 530 default :\n+ 531 file.ignore(std::numeric_limits::max(),'\\n');\n+ 532 return false;\n+ 533 }\n+ 534 break;\n+ 535 default :\n+ 536 file.ignore(std::numeric_limits::max(),'\\n');\n+ 537 return false;\n+ 538 }\n+ 539 file.ignore(std::numeric_limits::max(),'\\n');\n+ 540 c=file.peek();\n+ 541 return true;\n+ 542\n+ 543 }\n+ 544\n+ 545 template\n+ 546 std::tuple\n+547 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries, const\n+MMHeader& header)\n+ 548 {\n+ 549 std::size_t blockrows=rows/brows;\n+ 550 std::size_t blockcols=cols/bcols;\n+ 551 std::size_t blocksize=brows*bcols;\n+ 552 std::size_t blockentries=0;\n+ 553\n+ 554 switch(header.structure)\n+ 555 {\n+ 556 case general :\n+ 557 blockentries = entries/blocksize; break;\n+ 558 case skew_symmetric :\n+ 559 blockentries = 2*entries/blocksize; break;\n+ 560 case symmetric :\n+ 561 blockentries = (2*entries-rows)/blocksize; break;\n+ 562 case hermitian :\n+ 563 blockentries = (2*entries-rows)/blocksize; break;\n+ 564 default :\n+ 565 throw Dune::NotImplemented();\n+ 566 }\n+ 567 return std::make_tuple(blockrows, blockcols, blockentries);\n+ 568 }\n+ 569\n+ 570 /*\n+ 571 * @brief Storage class for the column index and the numeric value.\n+ 572 *\n+ 573 * \\tparam T Either a NumericWrapper of the numeric type or PatternDummy\n+ 574 * for MatrixMarket pattern case.\n+ 575 */\n+ 576 template\n+577 struct IndexData : public T\n+ 578 {\n+579 std::size_t index = {};\n+ 580 };\n+ 581\n+ 582\n+ 593 template\n+594 struct NumericWrapper\n+ 595 {\n+596 T number = {};\n+597 operator T&()\n+ 598 {\n+ 599 return number;\n+ 600 }\n+ 601 };\n+ 602\n+606 struct PatternDummy\n+ 607 {};\n+ 608\n+ 609 template<>\n+610 struct NumericWrapper\n+ 611 {};\n+ 612\n+ 613 template\n+614 std::istream& operator>>(std::istream& is, NumericWrapper& num)\n+ 615 {\n+ 616 return is>>num.number;\n+ 617 }\n+ 618\n+619 inline std::istream& operator>>(std::istream& is, [[maybe_unused]]\n+NumericWrapper& num)\n+ 620 {\n+ 621 return is;\n+ 622 }\n+ 623\n+ 629 template\n+630 bool operator<(const IndexData& i1, const IndexData& i2)\n+ 631 {\n+ 632 return i1.index\n+641 std::istream& operator>>(std::istream& is, IndexData& data)\n+ 642 {\n+ 643 is>>data.index;\n+ 644 /* MatrixMarket indices are one based. Decrement for C++ */\n+ 645 --data.index;\n+ 646 return is>>data.number;\n+ 647 }\n+ 648\n+ 654 template\n+655 std::istream& operator>>(std::istream& is, IndexData>>& data)\n+ 656 {\n+ 657 is>>data.index;\n+ 658 /* MatrixMarket indices are one based. Decrement for C++ */\n+ 659 --data.index;\n+ 660 // real and imaginary part needs to be read separately as\n+ 661 // complex numbers are not provided in pair form. (x,y)\n+ 662 NumericWrapper real, imag;\n+ 663 is>>real;\n+ 664 is>>imag;\n+ 665 data.number = {real.number, imag.number};\n+ 666 return is;\n+ 667 }\n+ 668\n+ 675 template\n+676 struct MatrixValuesSetter\n+ 677 {\n+ 683 template\n+684 void operator()(const std::vector > >& rows,\n+ 685 BCRSMatrix& matrix)\n+ 686 {\n+ 687 static_assert(IsNumber::value && brows==1 && bcols==1, \"Only scalar\n+entries are expected here!\");\n+ 688 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)\n+ 689 {\n+ 690 auto brow=iter.index();\n+ 691 for (auto siter=rows[brow].begin(); siter != rows[brow].end(); ++siter)\n+ 692 (*iter)[siter->index] = siter->number;\n+ 693 }\n+ 694 }\n+ 695\n+ 701 template\n+702 void operator()(const std::vector > >& rows,\n+ 703 BCRSMatrix >& matrix)\n+ 704 {\n+ 705 for (auto iter=matrix.begin(); iter!= matrix.end(); ++iter)\n+ 706 {\n+ 707 for (auto brow=iter.index()*brows,\n+ 708 browend=iter.index()*brows+brows;\n+ 709 browindex/bcols][brow%brows][siter->index%bcols]=siter->number;\n+ 714 }\n+ 715 }\n+ 716 }\n+ 717 };\n+ 718\n+ 719 template\n+720 struct MatrixValuesSetter\n+ 721 {\n+ 722 template\n+723 void operator()(const std::vector > >&\n+rows,\n+ 724 M& matrix)\n+ 725 {}\n+ 726 };\n+ 727\n+728 template struct is_complex : std::false_type {};\n+729 template struct is_complex> : std::true_type {};\n+ 730\n+ 731 // wrapper for std::conj. Returns T if T is not complex.\n+ 732 template\n+733 std::enable_if_t::value, T> conj(const T& r){\n+ 734 return r;\n+ 735 }\n+ 736\n+ 737 template\n+738 std::enable_if_t::value, T> conj(const T& r){\n+ 739 return std::conj(r);\n+ 740 }\n+ 741\n+ 742 template\n+743 struct mm_multipliers\n+ 744 {};\n+ 745\n+ 746 template\n+747 struct mm_multipliers >\n+ 748 {\n+ 749 enum {\n+750 rows = 1,\n+ 751 cols = 1\n+752 };\n+ 753 };\n+ 754\n+ 755 template\n+756 struct mm_multipliers,A> >\n+ 757 {\n+ 758 enum {\n+759 rows = i,\n+ 760 cols = j\n+761 };\n+ 762 };\n+ 763\n+ 764 template\n+765 void readSparseEntries(Dune::BCRSMatrix& matrix,\n+ 766 std::istream& file, std::size_t entries,\n+ 767 const MMHeader& mmHeader, const D&)\n+ 768 {\n+ 769 typedef Dune::BCRSMatrix Matrix;\n+ 770\n+ 771 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)\n+ 772 constexpr int brows = mm_multipliers::rows;\n+ 773 constexpr int bcols = mm_multipliers::cols;\n+ 774\n+ 775 // First path\n+ 776 // store entries together with column index in a separate\n+ 777 // data structure\n+ 778 std::vector > > rows(matrix.N()*brows);\n+ 779\n+ 780 auto readloop = [&] (auto symmetryFixup) {\n+ 781 for(std::size_t i = 0; i < entries; ++i) {\n+ 782 std::size_t row;\n+ 783 IndexData data;\n+ 784 skipComments(file);\n+ 785 file>>row;\n+ 786 --row; // Index was 1 based.\n+ 787 assert(row/bcols>data;\n+ 789 assert(data.index/bcols data_sym(data);\n+ 804 data_sym.index = row;\n+ 805 rows[data.index].insert(data_sym);\n+ 806 });\n+ 807 break;\n+ 808 case skew_symmetric :\n+ 809 readloop([&](auto row, auto data) {\n+ 810 IndexData data_sym;\n+ 811 data_sym.number = -data.number;\n+ 812 data_sym.index = row;\n+ 813 rows[data.index].insert(data_sym);\n+ 814 });\n+ 815 break;\n+ 816 case hermitian :\n+ 817 readloop([&](auto row, auto data) {\n+ 818 IndexData data_sym;\n+ 819 data_sym.number = conj(data.number);\n+ 820 data_sym.index = row;\n+ 821 rows[data.index].insert(data_sym);\n+ 822 });\n+ 823 break;\n+ 824 default:\n+ 825 DUNE_THROW(Dune::NotImplemented,\n+ 826 \"Only general, symmetric, skew-symmetric and hermitian is supported right\n+now!\");\n+ 827 }\n+ 828\n+ 829 // Setup the matrix sparsity pattern\n+ 830 int nnz=0;\n+ 831 for(typename Matrix::CreateIterator iter=matrix.createbegin();\n+ 832 iter!= matrix.createend(); ++iter)\n+ 833 {\n+ 834 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;\n+ 835 brow >::const_iterator Siter;\n+ 838 for(Siter siter=rows[brow].begin(), send=rows[brow].end();\n+ 839 siter != send; ++siter, ++nnz)\n+ 840 iter.insert(siter->index/bcols);\n+ 841 }\n+ 842 }\n+ 843\n+ 844 //Set the matrix values\n+ 845 matrix=0;\n+ 846\n+ 847 MatrixValuesSetter Setter;\n+ 848\n+ 849 Setter(rows, matrix);\n+ 850 }\n+ 851\n+852 inline std::tuple splitFilename(const std::\n+string& filename) {\n+ 853 std::size_t lastdot = filename.find_last_of(\".\");\n+ 854 if(lastdot == std::string::npos)\n+ 855 return std::make_tuple(filename, \"\");\n+ 856 else {\n+ 857 std::string potentialFileExtension = filename.substr(lastdot);\n+ 858 if (potentialFileExtension == \".mm\" || potentialFileExtension == \".mtx\")\n+ 859 return std::make_tuple(filename.substr(0, lastdot),\n+potentialFileExtension);\n+ 860 else\n+ 861 return std::make_tuple(filename, \"\");\n+ 862 }\n+ 863 }\n+ 864\n+ 865 } // end namespace MatrixMarketImpl\n+ 866\n+867 class MatrixMarketFormatError : public Dune::Exception\n+ 868 {};\n+ 869\n+ 870\n+871 inline void mm_read_header(std::size_t& rows, std::size_t& cols,\n+ 872 MatrixMarketImpl::MMHeader& header, std::istream& istr,\n+ 873 bool isVector)\n+ 874 {\n+ 875 using namespace MatrixMarketImpl;\n+ 876\n+ 877 if(!readMatrixMarketBanner(istr, header)) {\n+ 878 std::cerr << \"First line was not a correct Matrix Market banner. Using\n+default:\\n\"\n+ 879 << \"%%MatrixMarket matrix coordinate real general\"<> rows;\n+ 893\n+ 894 if(lineFeed(istr))\n+ 895 throw MatrixMarketFormatError();\n+ 896 istr >> cols;\n+ 897 }\n+ 898\n+ 899 template\n+900 void mm_read_vector_entries(Dune::BlockVector& vector,\n+ 901 std::size_t size,\n+ 902 std::istream& istr,\n+ 903 size_t lane)\n+ 904 {\n+ 905 for (int i=0; size>0; ++i, --size)\n+ 906 istr>>Simd::lane(lane,vector[i]);\n+ 907 }\n+ 908\n+ 909 template\n+910 void mm_read_vector_entries(Dune::BlockVector,A>& vector,\n+ 911 std::size_t size,\n+ 912 std::istream& istr,\n+ 913 size_t lane)\n+ 914 {\n+ 915 for(int i=0; size>0; ++i, --size) {\n+ 916 Simd::Scalar val;\n+ 917 istr>>val;\n+ 918 Simd::lane(lane, vector[i/entries][i%entries])=val;\n+ 919 }\n+ 920 }\n+ 921\n+ 922\n+ 929 template\n+930 void readMatrixMarket(Dune::BlockVector& vector,\n+ 931 std::istream& istr)\n+ 932 {\n+ 933 typedef typename Dune::BlockVector::field_type field_type;\n+ 934 using namespace MatrixMarketImpl;\n+ 935\n+ 936 MMHeader header;\n+ 937 std::size_t rows, cols;\n+ 938 mm_read_header(rows,cols,header,istr, true);\n+ 939 if(cols!=Simd::lanes()) {\n+ 940 if(Simd::lanes() == 1)\n+ 941 DUNE_THROW(MatrixMarketFormatError, \"cols!=1, therefore this is no\n+vector!\");\n+ 942 else\n+ 943 DUNE_THROW(MatrixMarketFormatError, \"cols does not match the number of\n+lanes in the field_type!\");\n+ 944 }\n+ 945\n+ 946 if(header.type!=array_type)\n+ 947 DUNE_THROW(MatrixMarketFormatError, \"Vectors have to be stored in array\n+format!\");\n+ 948\n+ 949\n+ 950 if constexpr (Dune::IsNumber())\n+ 951 vector.resize(rows);\n+ 952 else\n+ 953 {\n+ 954 T dummy;\n+ 955 auto blocksize = dummy.size();\n+ 956 std::size_t size=rows/blocksize;\n+ 957 if(size*blocksize!=rows)\n+ 958 DUNE_THROW(MatrixMarketFormatError, \"Block size of vector is not\n+correct!\");\n+ 959\n+ 960 vector.resize(size);\n+ 961 }\n+ 962\n+ 963 istr.ignore(std::numeric_limits::max(),'\\n');\n+ 964 for(size_t l=0;l();++l){\n+ 965 mm_read_vector_entries(vector, rows, istr, l);\n+ 966 }\n+ 967 }\n+ 968\n+ 975 template\n+976 void readMatrixMarket(Dune::BCRSMatrix& matrix,\n+ 977 std::istream& istr)\n+ 978 {\n+ 979 using namespace MatrixMarketImpl;\n+ 980 using Matrix = Dune::BCRSMatrix;\n+ 981\n+ 982 MMHeader header;\n+ 983 if(!readMatrixMarketBanner(istr, header)) {\n+ 984 std::cerr << \"First line was not a correct Matrix Market banner. Using\n+default:\\n\"\n+ 985 << \"%%MatrixMarket matrix coordinate real general\"<> rows;\n+ 998\n+ 999 if(lineFeed(istr))\n+ 1000 throw MatrixMarketFormatError();\n+ 1001 istr >> cols;\n+ 1002\n+ 1003 if(lineFeed(istr))\n+ 1004 throw MatrixMarketFormatError();\n+ 1005\n+ 1006 istr >>entries;\n+ 1007\n+ 1008 std::size_t nnz, blockrows, blockcols;\n+ 1009\n+ 1010 // Number of rows and columns of T, if it is a matrix (1x1 otherwise)\n+ 1011 constexpr int brows = mm_multipliers::rows;\n+ 1012 constexpr int bcols = mm_multipliers::cols;\n+ 1013\n+ 1014 std::tie(blockrows, blockcols, nnz) = calculateNNZ(rows,\n+cols, entries, header);\n+ 1015\n+ 1016 istr.ignore(std::numeric_limits::max(),'\\n');\n+ 1017\n+ 1018\n+ 1019 matrix.setSize(blockrows, blockcols, nnz);\n+ 1020 matrix.setBuildMode(Dune::BCRSMatrix::row_wise);\n+ 1021\n+ 1022 if(header.type==array_type)\n+ 1023 DUNE_THROW(Dune::NotImplemented, \"Array format currently not supported\n+for matrices!\");\n+ 1024\n+ 1025 readSparseEntries(matrix, istr, entries, header, NumericWrapper());\n+ 1026 }\n+ 1027\n+ 1028 // Print a scalar entry\n+ 1029 template\n+1030 void mm_print_entry(const B& entry,\n+ 1031 std::size_t rowidx,\n+ 1032 std::size_t colidx,\n+ 1033 std::ostream& ostr)\n+ 1034 {\n+ 1035 if constexpr (IsNumber())\n+ 1036 ostr << rowidx << \" \" << colidx << \" \" << entry << std::endl;\n+ 1037 else\n+ 1038 {\n+ 1039 for (auto row=entry.begin(); row != entry.end(); ++row, ++rowidx) {\n+ 1040 int coli=colidx;\n+ 1041 for (auto col = row->begin(); col != row->end(); ++col, ++coli)\n+ 1042 ostr<< rowidx<<\" \"<\n+1049 void mm_print_vector_entry(const V& entry, std::ostream& ostr,\n+ 1050 const std::integral_constant&,\n+ 1051 size_t lane)\n+ 1052 {\n+ 1053 ostr<\n+1058 void mm_print_vector_entry(const V& vector, std::ostream& ostr,\n+ 1059 const std::integral_constant&,\n+ 1060 size_t lane)\n+ 1061 {\n+ 1062 using namespace MatrixMarketImpl;\n+ 1063\n+ 1064 // Is the entry a supported numeric type?\n+ 1065 const int isnumeric = mm_numeric_type>::is_numeric;\n+ 1066 typedef typename V::const_iterator VIter;\n+ 1067\n+ 1068 for(VIter i=vector.begin(); i != vector.end(); ++i)\n+ 1069\n+ 1070 mm_print_vector_entry(*i, ostr,\n+ 1071 std::integral_constant(),\n+ 1072 lane);\n+ 1073 }\n+ 1074\n+ 1075 template\n+1076 std::size_t countEntries(const BlockVector& vector)\n+ 1077 {\n+ 1078 return vector.size();\n+ 1079 }\n+ 1080\n+ 1081 template\n+1082 std::size_t countEntries(const BlockVector,A>& vector)\n+ 1083 {\n+ 1084 return vector.size()*i;\n+ 1085 }\n+ 1086\n+ 1087 // Version for writing vectors.\n+ 1088 template\n+1089 void writeMatrixMarket(const V& vector, std::ostream& ostr,\n+ 1090 const std::integral_constant&)\n+ 1091 {\n+ 1092 using namespace MatrixMarketImpl;\n+ 1093 typedef typename V::field_type field_type;\n+ 1094\n+ 1095 ostr<()<>::is_numeric;\n+ 1097 for(size_t l=0;l(); ++l){\n+ 1098 mm_print_vector_entry(vector,ostr, std::integral_constant\n+(), l);\n+ 1099 }\n+ 1100 }\n+ 1101\n+ 1102 // Versions for writing matrices\n+ 1103 template\n+1104 void writeMatrixMarket(const M& matrix,\n+ 1105 std::ostream& ostr,\n+ 1106 const std::integral_constant&)\n+ 1107 {\n+ 1108 ostr<::rows<<\" \"\n+ 1109 <::cols<<\" \"\n+ 1110 <begin(); col != row->end(); ++col)\n+ 1116 // Matrix Market indexing start with 1!\n+ 1117 mm_print_entry(*col, row.index()*MatrixMarketImpl::mm_multipliers::\n+rows+1,\n+ 1118 col.index()*MatrixMarketImpl::mm_multipliers::cols+1, ostr);\n+ 1119 }\n+ 1120\n+ 1121\n+ 1125 template\n+1126 void writeMatrixMarket(const M& matrix,\n+ 1127 std::ostream& ostr)\n+ 1128 {\n+ 1129 using namespace MatrixMarketImpl;\n+ 1130\n+ 1131 // Write header information\n+ 1132 mm_header_printer::print(ostr);\n+ 1133 mm_block_structure_header::print(ostr,matrix);\n+ 1134 // Choose the correct function for matrix and vector\n+ 1135 writeMatrixMarket(matrix,ostr,std::integral_constant::\n+value>());\n+ 1136 }\n+ 1137\n+1138 static const int default_precision = -1;\n+ 1150 template\n+1151 void storeMatrixMarket(const M& matrix,\n+ 1152 std::string filename,\n+ 1153 int prec=default_precision)\n+ 1154 {\n+ 1155 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n+(filename);\n+ 1156 std::string rfilename;\n+ 1157 std::ofstream file;\n+ 1158 if (extension != \"\") {\n+ 1159 rfilename = pureFilename + extension;\n+ 1160 file.open(rfilename.c_str());\n+ 1161 if(!file)\n+ 1162 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n+rfilename.c_str());\n+ 1163 }\n+ 1164 else {\n+ 1165 // only try .mm so we do not ignore potential errors\n+ 1166 rfilename = pureFilename + \".mm\";\n+ 1167 file.open(rfilename.c_str());\n+ 1168 if(!file)\n+ 1169 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n+rfilename.c_str());\n+ 1170 }\n+ 1171\n+ 1172 file.setf(std::ios::scientific,std::ios::floatfield);\n+ 1173 if(prec>0)\n+ 1174 file.precision(prec);\n+ 1175 writeMatrixMarket(matrix, file);\n+ 1176 file.close();\n+ 1177 }\n+ 1178\n+ 1179#if HAVE_MPI\n+ 1194 template\n+1195 void storeMatrixMarket(const M& matrix,\n+ 1196 std::string filename,\n+ 1197 const OwnerOverlapCopyCommunication& comm,\n+ 1198 bool storeIndices=true,\n+ 1199 int prec=default_precision)\n+ 1200 {\n+ 1201 // Get our rank\n+ 1202 int rank = comm.communicator().rank();\n+ 1203 // Write the local matrix\n+ 1204 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n+(filename);\n+ 1205 std::string rfilename;\n+ 1206 std::ofstream file;\n+ 1207 if (extension != \"\") {\n+ 1208 rfilename = pureFilename + \"_\" + std::to_string(rank) + extension;\n+ 1209 file.open(rfilename.c_str());\n+ 1210 dverb<< rfilename <0)\n+ 1224 file.precision(prec);\n+ 1225 writeMatrixMarket(matrix, file);\n+ 1226 file.close();\n+ 1227\n+ 1228 if(!storeIndices)\n+ 1229 return;\n+ 1230\n+ 1231 // Write the global to local index mapping\n+ 1232 rfilename = pureFilename + \"_\" + std::to_string(rank) + \".idx\";\n+ 1233 file.open(rfilename.c_str());\n+ 1234 if(!file)\n+ 1235 DUNE_THROW(IOError, \"Could not open file for storage: \" <<\n+rfilename.c_str());\n+ 1236 file.setf(std::ios::scientific,std::ios::floatfield);\n+ 1237 typedef typename OwnerOverlapCopyCommunication::ParallelIndexSet\n+IndexSet;\n+ 1238 typedef typename IndexSet::const_iterator Iterator;\n+ 1239 for(Iterator iter = comm.indexSet().begin();\n+ 1240 iter != comm.indexSet().end(); ++iter) {\n+ 1241 file << iter->global()<<\" \"<<(std::size_t)iter->local()<<\" \"\n+ 1242 <<(int)iter->local().attribute()<<\" \"<<(int)iter->local().isPublic\n+()<& neighbours=comm.remoteIndices().getNeighbours();\n+ 1247 typedef std::set::const_iterator SIter;\n+ 1248 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end();\n+++neighbour) {\n+ 1249 file<<\" \"<< *neighbour;\n+ 1250 }\n+ 1251 file.close();\n+ 1252 }\n+ 1253\n+ 1268 template\n+1269 void loadMatrixMarket(M& matrix,\n+ 1270 const std::string& filename,\n+ 1271 OwnerOverlapCopyCommunication& comm,\n+ 1272 bool readIndices=true)\n+ 1273 {\n+ 1274 using namespace MatrixMarketImpl;\n+ 1275\n+ 1276 using LocalIndexT = typename OwnerOverlapCopyCommunication::\n+ParallelIndexSet::LocalIndex;\n+ 1277 typedef typename LocalIndexT::Attribute Attribute;\n+ 1278 // Get our rank\n+ 1279 int rank = comm.communicator().rank();\n+ 1280 // load local matrix\n+ 1281 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n+(filename);\n+ 1282 std::string rfilename;\n+ 1283 std::ifstream file;\n+ 1284 if (extension != \"\") {\n+ 1285 rfilename = pureFilename + \"_\" + std::to_string(rank) + extension;\n+ 1286 file.open(rfilename.c_str(), std::ios::in);\n+ 1287 dverb<< rfilename <::ParallelIndexSet\n+IndexSet;\n+ 1311 IndexSet& pis=comm.pis;\n+ 1312 rfilename = pureFilename + \"_\" + std::to_string(rank) + \".idx\";\n+ 1313 file.open(rfilename.c_str());\n+ 1314 if(!file)\n+ 1315 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n+ 1316 if(pis.size()!=0)\n+ 1317 DUNE_THROW(InvalidIndexSetState, \"Index set is not empty!\");\n+ 1318\n+ 1319 pis.beginResize();\n+ 1320 while(!file.eof() && file.peek()!='n') {\n+ 1321 G g;\n+ 1322 file >>g;\n+ 1323 std::size_t l;\n+ 1324 file >>l;\n+ 1325 int c;\n+ 1326 file >>c;\n+ 1327 bool b;\n+ 1328 file >> b;\n+ 1329 pis.add(g,LocalIndexT(l,Attribute(c),b));\n+ 1330 lineFeed(file);\n+ 1331 }\n+ 1332 pis.endResize();\n+ 1333 if(!file.eof()) {\n+ 1334 // read neighbours\n+ 1335 std::string s;\n+ 1336 file>>s;\n+ 1337 if(s!=\"neighbours:\")\n+ 1338 DUNE_THROW(MatrixMarketFormatError, \"was expecting the string:\n+\\\"neighbours:\\\"\");\n+ 1339 std::set nb;\n+ 1340 while(!file.eof()) {\n+ 1341 int i;\n+ 1342 file >> i;\n+ 1343 nb.insert(i);\n+ 1344 }\n+ 1345 file.close();\n+ 1346 comm.ri.setNeighbours(nb);\n+ 1347 }\n+ 1348 comm.ri.template rebuild();\n+ 1349 }\n+ 1350\n+ 1351 #endif\n+ 1352\n+ 1363 template\n+1364 void loadMatrixMarket(M& matrix,\n+ 1365 const std::string& filename)\n+ 1366 {\n+ 1367 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename\n+(filename);\n+ 1368 std::string rfilename;\n+ 1369 std::ifstream file;\n+ 1370 if (extension != \"\") {\n+ 1371 rfilename = pureFilename + extension;\n+ 1372 file.open(rfilename.c_str());\n+ 1373 if(!file)\n+ 1374 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n+ 1375 }\n+ 1376 else {\n+ 1377 // try both .mm and .mtx\n+ 1378 rfilename = pureFilename + \".mm\";\n+ 1379 file.open(rfilename.c_str(), std::ios::in);\n+ 1380 if(!file) {\n+ 1381 rfilename = pureFilename + \".mtx\";\n+ 1382 file.open(rfilename.c_str(), std::ios::in);\n+ 1383 if(!file)\n+ 1384 DUNE_THROW(IOError, \"Could not open file: \" << rfilename.c_str());\n+ 1385 }\n+ 1386 }\n+ 1387 readMatrixMarket(matrix,file);\n+ 1388 file.close();\n+ 1389 }\n+ 1390\n+ 1392}\n+ 1393#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+matrixutils.hh\n+Some handy generic functions for ISTL matrices.\n bcrsmatrix.hh\n Implementation of the BCRSMatrix class.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n col\n Col col\n Definition: matrixmatrix.hh:351\n+Dune::countNonZeros\n+auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n+value > *sfinae=nullptr)\n+Get the number of nonzero fields in the matrix.\n+Definition: matrixutils.hh:119\n+Dune::readMatrixMarket\n+void readMatrixMarket(Dune::BlockVector< T, A > &vector, std::istream &istr)\n+Reads a BlockVector from a matrix market file.\n+Definition: matrixmarket.hh:930\n+Dune::storeMatrixMarket\n+void storeMatrixMarket(const M &matrix, std::string filename, int\n+prec=default_precision)\n+Stores a parallel matrix/vector in matrix market format in a file.\n+Definition: matrixmarket.hh:1151\n+Dune::loadMatrixMarket\n+void loadMatrixMarket(M &matrix, const std::string &filename,\n+OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)\n+Load a parallel matrix/vector stored in matrix market format.\n+Definition: matrixmarket.hh:1269\n+Dune::countEntries\n+std::size_t countEntries(const BlockVector< T, A > &vector)\n+Definition: matrixmarket.hh:1076\n+Dune::writeMatrixMarket\n+void writeMatrixMarket(const V &vector, std::ostream &ostr, const std::\n+integral_constant< int, 0 > &)\n+Definition: matrixmarket.hh:1089\n+Dune::mm_print_vector_entry\n+void mm_print_vector_entry(const V &entry, std::ostream &ostr, const std::\n+integral_constant< int, 1 > &, size_t lane)\n+Definition: matrixmarket.hh:1049\n+Dune::default_precision\n+static const int default_precision\n+Definition: matrixmarket.hh:1138\n+Dune::mm_read_vector_entries\n+void mm_read_vector_entries(Dune::BlockVector< T, A > &vector, std::size_t\n+size, std::istream &istr, size_t lane)\n+Definition: matrixmarket.hh:900\n+Dune::mm_read_header\n+void mm_read_header(std::size_t &rows, std::size_t &cols, MatrixMarketImpl::\n+MMHeader &header, std::istream &istr, bool isVector)\n+Definition: matrixmarket.hh:871\n+Dune::mm_print_entry\n+void mm_print_entry(const B &entry, std::size_t rowidx, std::size_t colidx,\n+std::ostream &ostr)\n+Definition: matrixmarket.hh:1030\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n+Dune::MatrixMarketImpl::calculateNNZ\n+std::tuple< std::size_t, std::size_t, std::size_t > calculateNNZ(std::size_t\n+rows, std::size_t cols, std::size_t entries, const MMHeader &header)\n+Definition: matrixmarket.hh:547\n+Dune::MatrixMarketImpl::operator<\n+bool operator<(const IndexData< T > &i1, const IndexData< T > &i2)\n+LessThan operator.\n+Definition: matrixmarket.hh:630\n+Dune::MatrixMarketImpl::LineType\n+LineType\n+Definition: matrixmarket.hh:296\n+Dune::MatrixMarketImpl::DATA\n+@ DATA\n+Definition: matrixmarket.hh:296\n+Dune::MatrixMarketImpl::MM_HEADER\n+@ MM_HEADER\n+Definition: matrixmarket.hh:296\n+Dune::MatrixMarketImpl::MM_ISTLSTRUCT\n+@ MM_ISTLSTRUCT\n+Definition: matrixmarket.hh:296\n+Dune::MatrixMarketImpl::readMatrixMarketBanner\n+bool readMatrixMarketBanner(std::istream &file, MMHeader &mmHeader)\n+Definition: matrixmarket.hh:353\n+Dune::MatrixMarketImpl::conj\n+std::enable_if_t< is_complex< T >::value, T > conj(const T &r)\n+Definition: matrixmarket.hh:738\n+Dune::MatrixMarketImpl::readSparseEntries\n+void readSparseEntries(Dune::BCRSMatrix< T, A > &matrix, std::istream &file,\n+std::size_t entries, const MMHeader &mmHeader, const D &)\n+Definition: matrixmarket.hh:765\n+Dune::MatrixMarketImpl::MM_TYPE\n+MM_TYPE\n+Definition: matrixmarket.hh:299\n+Dune::MatrixMarketImpl::array_type\n+@ array_type\n+Definition: matrixmarket.hh:299\n+Dune::MatrixMarketImpl::coordinate_type\n+@ coordinate_type\n+Definition: matrixmarket.hh:299\n+Dune::MatrixMarketImpl::unknown_type\n+@ unknown_type\n+Definition: matrixmarket.hh:299\n+Dune::MatrixMarketImpl::operator>>\n+std::istream & operator>>(std::istream &is, NumericWrapper< T > &num)\n+Definition: matrixmarket.hh:614\n+Dune::MatrixMarketImpl::skipComments\n+void skipComments(std::istream &file)\n+Definition: matrixmarket.hh:339\n+Dune::MatrixMarketImpl::lineFeed\n+bool lineFeed(std::istream &file)\n+Definition: matrixmarket.hh:315\n+Dune::MatrixMarketImpl::MM_MAX_LINE_LENGTH\n+@ MM_MAX_LINE_LENGTH\n+Definition: matrixmarket.hh:297\n+Dune::MatrixMarketImpl::MM_STRUCTURE\n+MM_STRUCTURE\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::skew_symmetric\n+@ skew_symmetric\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::general\n+@ general\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::hermitian\n+@ hermitian\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::unknown_structure\n+@ unknown_structure\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::symmetric\n+@ symmetric\n+Definition: matrixmarket.hh:303\n+Dune::MatrixMarketImpl::MM_CTYPE\n+MM_CTYPE\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::unknown_ctype\n+@ unknown_ctype\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::pattern\n+@ pattern\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::complex_type\n+@ complex_type\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::double_type\n+@ double_type\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::integer_type\n+@ integer_type\n+Definition: matrixmarket.hh:301\n+Dune::MatrixMarketImpl::conj\n+std::enable_if_t::value, T > conj(const T &r)\n+Definition: matrixmarket.hh:733\n+Dune::MatrixMarketImpl::splitFilename\n+std::tuple< std::string, std::string > splitFilename(const std::string\n+&filename)\n+Definition: matrixmarket.hh:852\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::endrowsizes\n-void endrowsizes()\n-indicate that size of all rows is defined\n-Definition: bcrsmatrix.hh:1149\n-Dune::BCRSMatrix::setrowsize\n-void setrowsize(size_type i, size_type s)\n-Set number of indices in row i to s.\n-Definition: bcrsmatrix.hh:1117\n-Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::random\n-@ random\n-Build entries randomly.\n-Definition: bcrsmatrix.hh:530\n-Dune::BCRSMatrix::addindex\n-void addindex(size_type row, size_type col)\n-add index (row,col) to the matrix\n-Definition: bcrsmatrix.hh:1191\n-Dune::BCRSMatrix::endindices\n-void endindices()\n-indicate that all indices are defined, check consistency\n-Definition: bcrsmatrix.hh:1248\n-Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::N\n+Dune::BCRSMatrix::begin\n+Iterator begin()\n+Get iterator to first row.\n+Definition: bcrsmatrix.hh:675\n+Dune::BCRSMatrix::end\n+Iterator end()\n+Get iterator to one beyond last row.\n+Definition: bcrsmatrix.hh:681\n+Dune::BCRSMatrix::createend\n+CreateIterator createend()\n+get create iterator pointing to one after the last block\n+Definition: bcrsmatrix.hh:1103\n+Dune::BCRSMatrix::M\n+size_type M() const\n+number of columns (counted in blocks)\n+Definition: bcrsmatrix.hh:1978\n+Dune::BCRSMatrix::createbegin\n+CreateIterator createbegin()\n+get initial create iterator\n+Definition: bcrsmatrix.hh:1097\n+Dune::BCRSMatrix::N\n size_type N() const\n number of rows (counted in blocks)\n Definition: bcrsmatrix.hh:1972\n+Dune::BCRSMatrix::setBuildMode\n+void setBuildMode(BuildMode bm)\n+Sets the build mode of the matrix.\n+Definition: bcrsmatrix.hh:833\n Dune::BCRSMatrix::setSize\n void setSize(size_type rows, size_type columns, size_type nnz=0)\n Set the size of the matrix.\n Definition: bcrsmatrix.hh:861\n-Dune::BCRSMatrix::operator=\n-BCRSMatrix & operator=(const BCRSMatrix &Mat)\n-assignment\n-Definition: bcrsmatrix.hh:911\n-Dune::BDMatrix\n-A block-diagonal matrix.\n-Definition: bdmatrix.hh:33\n-Dune::BDMatrix::field_type\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::BlockVector::resize\n+void resize(size_type size)\n+Resize the vector.\n+Definition: bvector.hh:503\n+Dune::BlockVector::field_type\n typename Imp::BlockTraits< B >::field_type field_type\n export the type representing the field\n-Definition: bdmatrix.hh:39\n-Dune::BDMatrix::size_type\n-A::size_type size_type\n-implement row_type with compressed vector\n-Definition: bdmatrix.hh:51\n-Dune::BDMatrix::BDMatrix\n-BDMatrix()\n-Default constructor.\n-Definition: bdmatrix.hh:58\n-Dune::BDMatrix::BDMatrix\n-BDMatrix(std::initializer_list< B > const &list)\n-Construct from a std::initializer_list.\n-Definition: bdmatrix.hh:76\n-Dune::BDMatrix::block_type\n-B block_type\n-export the type representing the components\n-Definition: bdmatrix.hh:42\n-Dune::BDMatrix::solve\n-void solve(V &x, const V &rhs) const\n-Solve the system Ax=b in O(n) time.\n-Definition: bdmatrix.hh:120\n-Dune::BDMatrix::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: bdmatrix.hh:45\n-Dune::BDMatrix::BDMatrix\n-BDMatrix(int size)\n-Definition: bdmatrix.hh:60\n-Dune::BDMatrix::operator=\n-BDMatrix & operator=(const BDMatrix &other)\n-assignment\n-Definition: bdmatrix.hh:103\n-Dune::BDMatrix::blocklevel\n-static constexpr unsigned int blocklevel\n-increment block level counter\n-Definition: bdmatrix.hh:55\n-Dune::BDMatrix::setSize\n-void setSize(size_type size)\n-Resize the matrix. Invalidates the content!\n-Definition: bdmatrix.hh:85\n-Dune::BDMatrix::invert\n-void invert()\n-Inverts the matrix.\n-Definition: bdmatrix.hh:130\n-Dune::FieldTraits<_BDMatrix<_B,_A_>_>::field_type\n-typename BDMatrix< B, A >::field_type field_type\n-Definition: bdmatrix.hh:154\n-Dune::FieldTraits<_BDMatrix<_B,_A_>_>::real_type\n-typename FieldTraits< field_type >::real_type real_type\n-Definition: bdmatrix.hh:155\n+Definition: bvector.hh:401\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::MatrixMarketImpl::mm_numeric_type\n+Helper metaprogram to get the matrix market string representation of the\n+numeric type.\n+Definition: matrixmarket.hh:76\n+Dune::MatrixMarketImpl::mm_numeric_type::is_numeric\n+@ is_numeric\n+Whether T is a supported numeric type.\n+Definition: matrixmarket.hh:81\n+Dune::MatrixMarketImpl::mm_numeric_type<_int_>::str\n+static std::string str()\n+Definition: matrixmarket.hh:95\n+Dune::MatrixMarketImpl::mm_numeric_type<_double_>::str\n+static std::string str()\n+Definition: matrixmarket.hh:111\n+Dune::MatrixMarketImpl::mm_numeric_type<_float_>::str\n+static std::string str()\n+Definition: matrixmarket.hh:127\n+Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_double_>_>::str\n+static std::string str()\n+Definition: matrixmarket.hh:143\n+Dune::MatrixMarketImpl::mm_numeric_type<_std::complex<_float_>_>::str\n+static std::string str()\n+Definition: matrixmarket.hh:159\n+Dune::MatrixMarketImpl::mm_header_printer\n+Meta program to write the correct Matrix Market header.\n+Definition: matrixmarket.hh:174\n+Dune::MatrixMarketImpl::mm_header_printer<_BCRSMatrix<_T,_A_>_>::print\n+static void print(std::ostream &os)\n+Definition: matrixmarket.hh:179\n+Dune::MatrixMarketImpl::mm_header_printer<_BlockVector<_B,_A_>_>::print\n+static void print(std::ostream &os)\n+Definition: matrixmarket.hh:189\n+Dune::MatrixMarketImpl::mm_header_printer<_FieldVector<_T,_j_>_>::print\n+static void print(std::ostream &os)\n+Definition: matrixmarket.hh:199\n+Dune::MatrixMarketImpl::mm_header_printer<_FieldMatrix<_T,_i,_j_>_>::print\n+static void print(std::ostream &os)\n+Definition: matrixmarket.hh:209\n+Dune::MatrixMarketImpl::mm_block_structure_header\n+Metaprogram for writing the ISTL block structure header.\n+Definition: matrixmarket.hh:225\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>_>::print\n+static void print(std::ostream &os, const M &)\n+Definition: matrixmarket.hh:233\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_T,_A_>_>::M\n+BlockVector< T, A > M\n+Definition: matrixmarket.hh:230\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BlockVector<_FieldVector<_T,\n+i_>,_A_>_>::print\n+static void print(std::ostream &os, const M &)\n+Definition: matrixmarket.hh:245\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>_>::M\n+BCRSMatrix< T, A > M\n+Definition: matrixmarket.hh:255\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_T,_A_>_>::print\n+static void print(std::ostream &os, const M &)\n+Definition: matrixmarket.hh:258\n+Dune::MatrixMarketImpl::mm_block_structure_header<_BCRSMatrix<_FieldMatrix<_T,\n+i,_j_>,_A_>_>::print\n+static void print(std::ostream &os, const M &)\n+Definition: matrixmarket.hh:270\n+Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,_j_>_>::\n+print\n+static void print(std::ostream &os, const M &m)\n+Definition: matrixmarket.hh:283\n+Dune::MatrixMarketImpl::mm_block_structure_header<_FieldMatrix<_T,_i,_j_>_>::M\n+FieldMatrix< T, i, j > M\n+Definition: matrixmarket.hh:281\n+Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>_>::print\n+static void print(std::ostream &os, const M &m)\n+Definition: matrixmarket.hh:292\n+Dune::MatrixMarketImpl::mm_block_structure_header<_FieldVector<_T,_i_>_>::M\n+FieldVector< T, i > M\n+Definition: matrixmarket.hh:290\n+Dune::MatrixMarketImpl::MMHeader\n+Definition: matrixmarket.hh:306\n+Dune::MatrixMarketImpl::MMHeader::structure\n+MM_STRUCTURE structure\n+Definition: matrixmarket.hh:312\n+Dune::MatrixMarketImpl::MMHeader::type\n+MM_TYPE type\n+Definition: matrixmarket.hh:310\n+Dune::MatrixMarketImpl::MMHeader::MMHeader\n+MMHeader()\n+Definition: matrixmarket.hh:307\n+Dune::MatrixMarketImpl::MMHeader::ctype\n+MM_CTYPE ctype\n+Definition: matrixmarket.hh:311\n+Dune::MatrixMarketImpl::IndexData\n+Definition: matrixmarket.hh:578\n+Dune::MatrixMarketImpl::IndexData::index\n+std::size_t index\n+Definition: matrixmarket.hh:579\n+Dune::MatrixMarketImpl::NumericWrapper\n+a wrapper class of numeric values.\n+Definition: matrixmarket.hh:595\n+Dune::MatrixMarketImpl::NumericWrapper::number\n+T number\n+Definition: matrixmarket.hh:596\n+Dune::MatrixMarketImpl::PatternDummy\n+Utility class for marking the pattern type of the MatrixMarket matrices.\n+Definition: matrixmarket.hh:607\n+Dune::MatrixMarketImpl::NumericWrapper<_PatternDummy_>\n+Definition: matrixmarket.hh:611\n+Dune::MatrixMarketImpl::MatrixValuesSetter\n+Functor to the data values of the matrix.\n+Definition: matrixmarket.hh:677\n+Dune::MatrixMarketImpl::MatrixValuesSetter::operator()\n+void operator()(const std::vector< std::set< IndexData< D > > > &rows,\n+BCRSMatrix< T > &matrix)\n+Sets the matrix values.\n+Definition: matrixmarket.hh:684\n+Dune::MatrixMarketImpl::MatrixValuesSetter::operator()\n+void operator()(const std::vector< std::set< IndexData< D > > > &rows,\n+BCRSMatrix< FieldMatrix< T, brows, bcols > > &matrix)\n+Sets the matrix values.\n+Definition: matrixmarket.hh:702\n+Dune::MatrixMarketImpl::MatrixValuesSetter<_PatternDummy,_brows,_bcols_>::\n+operator()\n+void operator()(const std::vector< std::set< IndexData< PatternDummy > > >\n+&rows, M &matrix)\n+Definition: matrixmarket.hh:723\n+Dune::MatrixMarketImpl::is_complex\n+Definition: matrixmarket.hh:728\n+Dune::MatrixMarketImpl::mm_multipliers\n+Definition: matrixmarket.hh:744\n+Dune::MatrixMarketFormatError\n+Definition: matrixmarket.hh:868\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n+Dune::IsMatrix\n+Test whether a type is an ISTL Matrix.\n+Definition: matrixutils.hh:504\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::indexSet\n+const ParallelIndexSet & indexSet() const\n+Get the underlying parallel index set.\n+Definition: owneroverlapcopy.hh:462\n+Dune::OwnerOverlapCopyCommunication::communicator\n+const Communication< MPI_Comm > & communicator() const\n+Definition: owneroverlapcopy.hh:299\n+Dune::OwnerOverlapCopyCommunication::remoteIndices\n+const RemoteIndices & remoteIndices() const\n+Get the underlying remote indices.\n+Definition: owneroverlapcopy.hh:471\n+Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n+Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n+The type of the parallel index set.\n+Definition: owneroverlapcopy.hh:449\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00077.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00077.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: preconditioner.hh File Reference\n+dune-istl: bcrsmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -65,33 +65,72 @@\n
  • dune
  • istl
  • \n
    \n
    \n
    \n \n-
    preconditioner.hh File Reference
    \n+
    bcrsmatrix.hh File Reference
    \n
    \n
    \n-
    #include <dune/common/exceptions.hh>
    \n-#include "solvercategory.hh"
    \n+\n+

    Implementation of the BCRSMatrix class. \n+More...

    \n+
    #include <cmath>
    \n+#include <complex>
    \n+#include <set>
    \n+#include <iostream>
    \n+#include <algorithm>
    \n+#include <numeric>
    \n+#include <vector>
    \n+#include <map>
    \n+#include <memory>
    \n+#include "istlexception.hh"
    \n+#include "bvector.hh"
    \n+#include "matrixutils.hh"
    \n+#include <dune/common/stdstreams.hh>
    \n+#include <dune/common/iteratorfacades.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/ftraits.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Preconditioner< X, Y >
     Base class for matrix free definition of preconditioners. More...
    struct  Dune::CompressionStatistics< size_type >
     Statistics about compression achieved in implicit mode. More...
     
    class  Dune::ImplicitMatrixBuilder< M_ >
     A wrapper for uniform access to the BCRSMatrix during and after the build stage in implicit build mode. More...
     
    class  Dune::ImplicitMatrixBuilder< M_ >::row_object
     Proxy row object for entry access. More...
     
    class  Dune::BCRSMatrix< B, A >
     A sparse block matrix with compressed row storage. More...
     
    class  Dune::BCRSMatrix< B, A >::RealRowIterator< T >
     Iterator access to matrix rows More...
     
    class  Dune::BCRSMatrix< B, A >::CreateIterator
     Iterator class for sequential creation of blocks More...
     
    struct  Dune::FieldTraits< BCRSMatrix< B, A > >
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-
    \n+

    Detailed Description

    \n+

    Implementation of the BCRSMatrix class.

    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,21 +5,59 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n Classes | Namespaces\n-preconditioner.hh File Reference\n-#include \n-#include \"solvercategory.hh\"\n+bcrsmatrix.hh File Reference\n+Implementation of the BCRSMatrix class. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"istlexception.hh\"\n+#include \"bvector.hh\"\n+#include \"matrixutils.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Preconditioner<_X,_Y_>\n-\u00a0 Base class for matrix free definition of preconditioners. More...\n+struct \u00a0Dune::CompressionStatistics<_size_type_>\n+\u00a0 Statistics about compression achieved in implicit mode. More...\n+\u00a0\n+ class \u00a0Dune::ImplicitMatrixBuilder<_M__>\n+\u00a0 A wrapper for uniform access to the BCRSMatrix during and after the\n+ build stage in implicit build mode. More...\n+\u00a0\n+ class \u00a0Dune::ImplicitMatrixBuilder<_M__>::row_object\n+\u00a0 Proxy row object for entry access. More...\n+\u00a0\n+ class \u00a0Dune::BCRSMatrix<_B,_A_>\n+\u00a0 A sparse block matrix with compressed row storage. More...\n+\u00a0\n+ class \u00a0Dune::BCRSMatrix<_B,_A_>::RealRowIterator<_T_>\n+\u00a0 Iterator access to matrix rows More...\n+\u00a0\n+ class \u00a0Dune::BCRSMatrix<_B,_A_>::CreateIterator\n+\u00a0 Iterator class for sequential creation of blocks More...\n+\u00a0\n+struct \u00a0Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+***** Detailed Description *****\n+Implementation of the BCRSMatrix class.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00077_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00077_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: preconditioner.hh Source File\n+dune-istl: bcrsmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -62,71 +62,1875 @@\n \n
    \n \n
    \n
    \n
    \n-
    preconditioner.hh
    \n+
    bcrsmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_PRECONDITIONER_HH
    \n-
    6#define DUNE_ISTL_PRECONDITIONER_HH
    \n-
    7
    \n-
    8#include <dune/common/exceptions.hh>
    \n-
    9
    \n-
    10#include "solvercategory.hh"
    \n-
    11
    \n-
    12namespace Dune {
    \n-
    17 //=====================================================================
    \n-
    30 //=====================================================================
    \n-
    31 template<class X, class Y>
    \n-\n-
    33 public:
    \n-
    35 typedef X domain_type;
    \n-
    37 typedef Y range_type;
    \n-
    39 typedef typename X::field_type field_type;
    \n-
    40
    \n-
    69 virtual void pre (X& x, Y& b) = 0;
    \n-
    70
    \n-
    81 virtual void apply (X& v, const Y& d) = 0;
    \n-
    82
    \n-
    91 virtual void post (X& x) = 0;
    \n-
    92
    \n-\n-
    95#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n-
    96 {
    \n-
    97 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n-
    98 }
    \n-
    99#else
    \n-
    100 = 0;
    \n-
    101#endif
    \n-
    102
    \n-
    104 virtual ~Preconditioner () {}
    \n-
    105
    \n-
    106 };
    \n-
    107
    \n-
    111}
    \n-
    112#endif
    \n-\n+
    5
    \n+
    6#ifndef DUNE_ISTL_BCRSMATRIX_HH
    \n+
    7#define DUNE_ISTL_BCRSMATRIX_HH
    \n+
    8
    \n+
    9#include <cmath>
    \n+
    10#include <complex>
    \n+
    11#include <set>
    \n+
    12#include <iostream>
    \n+
    13#include <algorithm>
    \n+
    14#include <numeric>
    \n+
    15#include <vector>
    \n+
    16#include <map>
    \n+
    17#include <memory>
    \n+
    18
    \n+
    19#include "istlexception.hh"
    \n+
    20#include "bvector.hh"
    \n+
    21#include "matrixutils.hh"
    \n+
    22#include <dune/common/stdstreams.hh>
    \n+
    23#include <dune/common/iteratorfacades.hh>
    \n+
    24#include <dune/common/typetraits.hh>
    \n+
    25#include <dune/common/ftraits.hh>
    \n+
    26#include <dune/common/scalarvectorview.hh>
    \n+
    27#include <dune/common/scalarmatrixview.hh>
    \n+
    28
    \n+\n+
    30
    \n+
    35namespace Dune {
    \n+
    36
    \n+
    76 template<typename M>
    \n+
    77 struct MatrixDimension;
    \n+
    78
    \n+
    80
    \n+
    86 template<typename size_type>
    \n+\n+
    88 {
    \n+
    90 double avg;
    \n+
    92 size_type maximum;
    \n+
    94 size_type overflow_total;
    \n+
    96
    \n+
    99 double mem_ratio;
    \n+
    100 };
    \n+
    101
    \n+
    103
    \n+
    115 template<class M_>
    \n+\n+
    117 {
    \n+
    118
    \n+
    119 public:
    \n+
    120
    \n+
    122 typedef M_ Matrix;
    \n+
    123
    \n+\n+
    126
    \n+
    128 typedef typename Matrix::size_type size_type;
    \n+
    129
    \n+
    131
    \n+\n+
    137 {
    \n+
    138
    \n+
    139 public:
    \n+
    140
    \n+\n+
    143 {
    \n+
    144 return _m.entry(_i,j);
    \n+
    145 }
    \n+
    146
    \n+
    147#ifndef DOXYGEN
    \n+
    148
    \n+\n+
    150 : _m(m)
    \n+
    151 , _i(i)
    \n+
    152 {}
    \n+
    153
    \n+
    154#endif
    \n+
    155
    \n+
    156 private:
    \n+
    157
    \n+
    158 Matrix& _m;
    \n+\n+
    160
    \n+
    161 };
    \n+
    162
    \n+
    164
    \n+\n+
    171 : _m(m)
    \n+
    172 {
    \n+
    173 if (m.buildMode() != Matrix::implicit)
    \n+
    174 DUNE_THROW(BCRSMatrixError,"You can only create an ImplicitBuilder for a matrix in implicit build mode");
    \n+
    175 if (m.buildStage() != Matrix::building)
    \n+
    176 DUNE_THROW(BCRSMatrixError,"You can only create an ImplicitBuilder for a matrix with set size that has not been compressed() yet");
    \n+
    177 }
    \n+
    178
    \n+
    180
    \n+
    194 ImplicitMatrixBuilder(Matrix& m, size_type rows, size_type cols, size_type avg_cols_per_row, double overflow_fraction)
    \n+
    195 : _m(m)
    \n+
    196 {
    \n+
    197 if (m.buildStage() != Matrix::notAllocated)
    \n+
    198 DUNE_THROW(BCRSMatrixError,"You can only set up a matrix for this ImplicitBuilder if it has no memory allocated yet");
    \n+
    199 m.setBuildMode(Matrix::implicit);
    \n+
    200 m.setImplicitBuildModeParameters(avg_cols_per_row,overflow_fraction);
    \n+
    201 m.setSize(rows,cols);
    \n+
    202 }
    \n+
    203
    \n+\n+
    206 {
    \n+
    207 return row_object(_m,i);
    \n+
    208 }
    \n+
    209
    \n+
    211 size_type N() const
    \n+
    212 {
    \n+
    213 return _m.N();
    \n+
    214 }
    \n+
    215
    \n+
    217 size_type M() const
    \n+
    218 {
    \n+
    219 return _m.M();
    \n+
    220 }
    \n+
    221
    \n+
    222 private:
    \n+
    223
    \n+
    224 Matrix& _m;
    \n+
    225
    \n+
    226 };
    \n+
    227
    \n+
    464 template<class B, class A=std::allocator<B> >
    \n+\n+
    466 {
    \n+
    467 friend struct MatrixDimension<BCRSMatrix>;
    \n+
    468 public:
    \n+\n+\n+\n+\n+\n+
    482 built=3
    \n+
    483 };
    \n+
    484
    \n+
    485 //===== type definitions and constants
    \n+
    486
    \n+
    488 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    489
    \n+
    491 typedef B block_type;
    \n+
    492
    \n+
    494 typedef A allocator_type;
    \n+
    495
    \n+
    497 typedef Imp::CompressedBlockVectorWindow<B,A> row_type;
    \n+
    498
    \n+
    500 typedef typename A::size_type size_type;
    \n+
    501
    \n+
    503 typedef ::Dune::CompressionStatistics<size_type> CompressionStatistics;
    \n+
    504
    \n+
    506 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    507 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n+
    508
    \n+\n+\n+\n+\n+
    543 unknown
    \n+
    544 };
    \n+
    545
    \n+
    546 //===== random access interface to rows of the matrix
    \n+
    547
    \n+\n+
    550 {
    \n+
    551#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    552 if (build_mode == implicit && ready != built)
    \n+
    553 DUNE_THROW(BCRSMatrixError,"You cannot use operator[] in implicit build mode before calling compress()");
    \n+
    554 if (r==0) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n+
    555 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    556#endif
    \n+
    557 return r[i];
    \n+
    558 }
    \n+
    559
    \n+\n+
    562 {
    \n+
    563#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    564 if (build_mode == implicit && ready != built)
    \n+
    565 DUNE_THROW(BCRSMatrixError,"You cannot use operator[] in implicit build mode before calling compress()");
    \n+
    566 if (built!=ready) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n+
    567 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    568#endif
    \n+
    569 return r[i];
    \n+
    570 }
    \n+
    571
    \n+
    572
    \n+
    573 //===== iterator interface to rows of the matrix
    \n+
    574
    \n+
    576 template<class T>
    \n+\n+
    578 : public RandomAccessIteratorFacade<RealRowIterator<T>, T>
    \n+
    579 {
    \n+
    580
    \n+
    581 public:
    \n+
    583 typedef typename std::remove_const<T>::type ValueType;
    \n+
    584
    \n+
    585 friend class RandomAccessIteratorFacade<RealRowIterator<const ValueType>, const ValueType>;
    \n+
    586 friend class RandomAccessIteratorFacade<RealRowIterator<ValueType>, ValueType>;
    \n+
    587 friend class RealRowIterator<const ValueType>;
    \n+
    588 friend class RealRowIterator<ValueType>;
    \n+
    589
    \n+\n+
    592 : p(_p), i(_i)
    \n+
    593 {}
    \n+
    594
    \n+\n+
    597 : p(0), i(0)
    \n+
    598 {}
    \n+
    599
    \n+\n+
    601 : p(it.p), i(it.i)
    \n+
    602 {}
    \n+
    603
    \n+
    604
    \n+\n+
    607 {
    \n+
    608 return i;
    \n+
    609 }
    \n+
    610
    \n+
    611 std::ptrdiff_t distanceTo(const RealRowIterator<ValueType>& other) const
    \n+
    612 {
    \n+
    613 assert(other.p==p);
    \n+
    614 return (other.i-i);
    \n+
    615 }
    \n+
    616
    \n+
    617 std::ptrdiff_t distanceTo(const RealRowIterator<const ValueType>& other) const
    \n+
    618 {
    \n+
    619 assert(other.p==p);
    \n+
    620 return (other.i-i);
    \n+
    621 }
    \n+
    622
    \n+
    624 bool equals (const RealRowIterator<ValueType>& other) const
    \n+
    625 {
    \n+
    626 assert(other.p==p);
    \n+
    627 return i==other.i;
    \n+
    628 }
    \n+
    629
    \n+
    631 bool equals (const RealRowIterator<const ValueType>& other) const
    \n+
    632 {
    \n+
    633 assert(other.p==p);
    \n+
    634 return i==other.i;
    \n+
    635 }
    \n+
    636
    \n+
    637 private:
    \n+
    639 void increment()
    \n+
    640 {
    \n+
    641 ++i;
    \n+
    642 }
    \n+
    643
    \n+
    645 void decrement()
    \n+
    646 {
    \n+
    647 --i;
    \n+
    648 }
    \n+
    649
    \n+
    650 void advance(std::ptrdiff_t diff)
    \n+
    651 {
    \n+
    652 i+=diff;
    \n+
    653 }
    \n+
    654
    \n+
    655 T& elementAt(std::ptrdiff_t diff) const
    \n+
    656 {
    \n+
    657 return p[i+diff];
    \n+
    658 }
    \n+
    659
    \n+
    661 row_type& dereference () const
    \n+
    662 {
    \n+
    663 return p[i];
    \n+
    664 }
    \n+
    665
    \n+
    666 row_type* p;
    \n+
    667 size_type i;
    \n+
    668 };
    \n+
    669
    \n+\n+\n+
    673
    \n+\n+
    676 {
    \n+
    677 return Iterator(r,0);
    \n+
    678 }
    \n+
    679
    \n+\n+
    682 {
    \n+
    683 return Iterator(r,n);
    \n+
    684 }
    \n+
    685
    \n+\n+
    689 {
    \n+
    690 return Iterator(r,n-1);
    \n+
    691 }
    \n+
    692
    \n+\n+
    696 {
    \n+
    697 return Iterator(r,-1);
    \n+
    698 }
    \n+
    699
    \n+\n+
    702
    \n+
    704 typedef typename row_type::Iterator ColIterator;
    \n+
    705
    \n+\n+\n+
    709
    \n+
    710
    \n+\n+
    713 {
    \n+
    714 return ConstIterator(r,0);
    \n+
    715 }
    \n+
    716
    \n+\n+
    719 {
    \n+
    720 return ConstIterator(r,n);
    \n+
    721 }
    \n+
    722
    \n+\n+
    726 {
    \n+
    727 return ConstIterator(r,n-1);
    \n+
    728 }
    \n+
    729
    \n+\n+
    733 {
    \n+
    734 return ConstIterator(r,-1);
    \n+
    735 }
    \n+
    736
    \n+\n+
    739
    \n+
    741 typedef typename row_type::ConstIterator ConstColIterator;
    \n+
    742
    \n+
    743 //===== constructors & resizers
    \n+
    744
    \n+
    745 // we use a negative compressionBufferSize to indicate that the implicit
    \n+
    746 // mode parameters have not been set yet
    \n+
    747
    \n+\n+
    750 : build_mode(unknown), ready(notAllocated), n(0), m(0), nnz_(0),
    \n+
    751 allocationSize_(0), r(0), a(0),
    \n+\n+
    753 {}
    \n+
    754
    \n+\n+
    757 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n+
    758 allocationSize_(0), r(0), a(0),
    \n+\n+
    760 {
    \n+
    761 allocate(_n, _m, _nnz,true,false);
    \n+
    762 }
    \n+
    763
    \n+\n+
    766 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n+
    767 allocationSize_(0), r(0), a(0),
    \n+\n+
    769 {
    \n+
    770 allocate(_n, _m,0,true,false);
    \n+
    771 }
    \n+
    772
    \n+
    774
    \n+
    784 BCRSMatrix (size_type _n, size_type _m, size_type _avg, double compressionBufferSize, BuildMode bm)
    \n+
    785 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n+
    786 allocationSize_(0), r(0), a(0),
    \n+
    787 avg(_avg), compressionBufferSize_(compressionBufferSize)
    \n+
    788 {
    \n+
    789 if (bm != implicit)
    \n+
    790 DUNE_THROW(BCRSMatrixError,"Only call this constructor when using the implicit build mode");
    \n+
    791 // Prevent user from setting a negative compression buffer size:
    \n+
    792 // 1) It doesn't make sense
    \n+
    793 // 2) We use a negative value to indicate that the parameters
    \n+
    794 // have not been set yet
    \n+
    795 if (compressionBufferSize_ < 0.0)
    \n+
    796 DUNE_THROW(BCRSMatrixError,"You cannot set a negative overflow fraction");
    \n+
    797 implicit_allocate(_n,_m);
    \n+
    798 }
    \n+
    799
    \n+\n+
    806 : build_mode(Mat.build_mode), ready(notAllocated), n(0), m(0), nnz_(0),
    \n+
    807 allocationSize_(0), r(0), a(0),
    \n+\n+
    809 {
    \n+
    810 if (!(Mat.ready == notAllocated || Mat.ready == built))
    \n+
    811 DUNE_THROW(InvalidStateException,"BCRSMatrix can only be copy-constructed when source matrix is completely empty (size not set) or fully built)");
    \n+
    812
    \n+
    813 // deep copy in global array
    \n+
    814 size_type _nnz = Mat.nonzeroes();
    \n+
    815
    \n+
    816 j_ = Mat.j_; // enable column index sharing, release array in case of row-wise allocation
    \n+
    817 allocate(Mat.n, Mat.m, _nnz, true, true);
    \n+
    818
    \n+
    819 // build window structure
    \n+\n+
    821 }
    \n+
    822
    \n+\n+
    825 {
    \n+
    826 deallocate();
    \n+
    827 }
    \n+
    828
    \n+\n+
    834 {
    \n+
    835 if (ready == notAllocated)
    \n+
    836 {
    \n+
    837 build_mode = bm;
    \n+
    838 return;
    \n+
    839 }
    \n+
    840 if (ready == building && (build_mode == unknown || build_mode == random || build_mode == row_wise) && (bm == row_wise || bm == random))
    \n+
    841 build_mode = bm;
    \n+
    842 else
    \n+
    843 DUNE_THROW(InvalidStateException, "Matrix structure cannot be changed at this stage anymore (ready == "<<ready<<").");
    \n+
    844 }
    \n+
    845
    \n+
    861 void setSize(size_type rows, size_type columns, size_type nnz=0)
    \n+
    862 {
    \n+
    863 // deallocate already setup memory
    \n+
    864 deallocate();
    \n+
    865
    \n+
    866 if (build_mode == implicit)
    \n+
    867 {
    \n+
    868 if (nnz>0)
    \n+
    869 DUNE_THROW(Dune::BCRSMatrixError,"number of non-zeroes may not be set in implicit mode, use setImplicitBuildModeParameters() instead");
    \n+
    870
    \n+
    871 // implicit allocates differently
    \n+
    872 implicit_allocate(rows,columns);
    \n+
    873 }
    \n+
    874 else
    \n+
    875 {
    \n+
    876 // allocate matrix memory
    \n+
    877 allocate(rows, columns, nnz, true, false);
    \n+
    878 }
    \n+
    879 }
    \n+
    880
    \n+
    889 void setImplicitBuildModeParameters(size_type _avg, double compressionBufferSize)
    \n+
    890 {
    \n+
    891 // Prevent user from setting a negative compression buffer size:
    \n+
    892 // 1) It doesn't make sense
    \n+
    893 // 2) We use a negative value to indicate that the parameters
    \n+
    894 // have not been set yet
    \n+
    895 if (compressionBufferSize < 0.0)
    \n+
    896 DUNE_THROW(BCRSMatrixError,"You cannot set a negative compressionBufferSize value");
    \n+
    897
    \n+
    898 // make sure the parameters aren't changed after memory has been allocated
    \n+
    899 if (ready != notAllocated)
    \n+
    900 DUNE_THROW(InvalidStateException,"You cannot modify build mode parameters at this stage anymore");
    \n+
    901 avg = _avg;
    \n+
    902 compressionBufferSize_ = compressionBufferSize;
    \n+
    903 }
    \n+
    904
    \n+\n+
    912 {
    \n+
    913 // return immediately when self-assignment
    \n+
    914 if (&Mat==this) return *this;
    \n+
    915
    \n+
    916 if (!((ready == notAllocated || ready == built) && (Mat.ready == notAllocated || Mat.ready == built)))
    \n+
    917 DUNE_THROW(InvalidStateException,"BCRSMatrix can only be copied when both target and source are empty or fully built)");
    \n+
    918
    \n+
    919 // make it simple: ALWAYS throw away memory for a and j_
    \n+
    920 // and deallocate rows only if n != Mat.n
    \n+
    921 deallocate(n!=Mat.n);
    \n+
    922
    \n+
    923 // reallocate the rows if required
    \n+
    924 if (n>0 && n!=Mat.n) {
    \n+
    925 // free rows
    \n+
    926 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)
    \n+
    927 std::allocator_traits<decltype(rowAllocator_)>::destroy(rowAllocator_, riter);
    \n+
    928 rowAllocator_.deallocate(r,n);
    \n+
    929 }
    \n+
    930
    \n+
    931 nnz_ = Mat.nonzeroes();
    \n+
    932
    \n+
    933 // allocate a, share j_
    \n+
    934 j_ = Mat.j_;
    \n+
    935 allocate(Mat.n, Mat.m, nnz_, n!=Mat.n, true);
    \n+
    936
    \n+
    937 // build window structure
    \n+\n+
    939 return *this;
    \n+
    940 }
    \n+
    941
    \n+\n+
    944 {
    \n+
    945
    \n+
    946 if (!(ready == notAllocated || ready == built))
    \n+
    947 DUNE_THROW(InvalidStateException,"Scalar assignment only works on fully built BCRSMatrix)");
    \n+
    948
    \n+
    949 for (size_type i=0; i<n; i++) r[i] = k;
    \n+
    950 return *this;
    \n+
    951 }
    \n+
    952
    \n+
    953 //===== row-wise creation interface
    \n+
    954
    \n+\n+
    957 {
    \n+
    958 public:
    \n+\n+
    961 : Mat(_Mat), i(_i), nnz(0), current_row(nullptr, Mat.j_.get(), 0)
    \n+
    962 {
    \n+
    963 if (Mat.build_mode == unknown && Mat.ready == building)
    \n+
    964 {
    \n+
    965 Mat.build_mode = row_wise;
    \n+
    966 }
    \n+
    967 if (i==0 && Mat.ready != building)
    \n+
    968 DUNE_THROW(BCRSMatrixError,"creation only allowed for uninitialized matrix");
    \n+
    969 if(Mat.build_mode!=row_wise)
    \n+
    970 DUNE_THROW(BCRSMatrixError,"creation only allowed if row wise allocation was requested in the constructor");
    \n+
    971 if(i==0 && _Mat.N()==0)
    \n+
    972 // empty Matrix is always built.
    \n+
    973 Mat.ready = built;
    \n+
    974 }
    \n+
    975
    \n+\n+
    978 {
    \n+
    979 // this should only be called if matrix is in creation
    \n+
    980 if (Mat.ready != building)
    \n+
    981 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n+
    982
    \n+
    983 // row i is defined through the pattern
    \n+
    984 // get memory for the row and initialize the j_ array
    \n+
    985 // this depends on the allocation mode
    \n+
    986
    \n+
    987 // compute size of the row
    \n+
    988 size_type s = pattern.size();
    \n+
    989
    \n+
    990 if(s>0) {
    \n+
    991 // update number of nonzeroes including this row
    \n+
    992 nnz += s;
    \n+
    993
    \n+
    994 // alloc memory / set window
    \n+
    995 if (Mat.nnz_ > 0)
    \n+
    996 {
    \n+
    997 // memory is allocated in one long array
    \n+
    998
    \n+
    999 // check if that memory is sufficient
    \n+
    1000 if (nnz > Mat.nnz_)
    \n+
    1001 DUNE_THROW(BCRSMatrixError,"allocated nnz too small");
    \n+
    1002
    \n+
    1003 // set row i
    \n+
    1004 Mat.r[i].set(s,nullptr,current_row.getindexptr());
    \n+
    1005 current_row.setindexptr(current_row.getindexptr()+s);
    \n+
    1006 }else{
    \n+
    1007 // memory is allocated individually per row
    \n+
    1008 // allocate and set row i
    \n+
    1009 B* b = Mat.allocator_.allocate(s);
    \n+
    1010 // use placement new to call constructor that allocates
    \n+
    1011 // additional memory.
    \n+
    1012 new (b) B[s];
    \n+
    1013 size_type* j = Mat.sizeAllocator_.allocate(s);
    \n+
    1014 Mat.r[i].set(s,b,j);
    \n+
    1015 }
    \n+
    1016 }else
    \n+
    1017 // setup empty row
    \n+
    1018 Mat.r[i].set(0,nullptr,nullptr);
    \n+
    1019
    \n+
    1020 // initialize the j array for row i from pattern
    \n+
    1021 std::copy(pattern.cbegin(), pattern.cend(), Mat.r[i].getindexptr());
    \n+
    1022
    \n+
    1023 // now go to next row
    \n+
    1024 i++;
    \n+
    1025 pattern.clear();
    \n+
    1026
    \n+
    1027 // check if this was last row
    \n+
    1028 if (i==Mat.n)
    \n+
    1029 {
    \n+
    1030 Mat.ready = built;
    \n+
    1031 if(Mat.nnz_ > 0)
    \n+
    1032 {
    \n+
    1033 // Set nnz to the exact number of nonzero blocks inserted
    \n+
    1034 // as some methods rely on it
    \n+
    1035 Mat.nnz_ = nnz;
    \n+
    1036 // allocate data array
    \n+
    1037 Mat.allocateData();
    \n+
    1038 Mat.setDataPointers();
    \n+
    1039 }
    \n+
    1040 }
    \n+
    1041 // done
    \n+
    1042 return *this;
    \n+
    1043 }
    \n+
    1044
    \n+
    1046 bool operator!= (const CreateIterator& it) const
    \n+
    1047 {
    \n+
    1048 return (i!=it.i) || (&Mat!=&it.Mat);
    \n+
    1049 }
    \n+
    1050
    \n+
    1052 bool operator== (const CreateIterator& it) const
    \n+
    1053 {
    \n+
    1054 return (i==it.i) && (&Mat==&it.Mat);
    \n+
    1055 }
    \n+
    1056
    \n+\n+
    1059 {
    \n+
    1060 return i;
    \n+
    1061 }
    \n+
    1062
    \n+\n+
    1065 {
    \n+
    1066 pattern.insert(j);
    \n+
    1067 }
    \n+
    1068
    \n+\n+
    1071 {
    \n+
    1072 return pattern.find(j) != pattern.end();
    \n+
    1073 }
    \n+\n+
    1080 {
    \n+
    1081 return pattern.size();
    \n+
    1082 }
    \n+
    1083
    \n+
    1084 private:
    \n+
    1085 BCRSMatrix& Mat; // the matrix we are defining
    \n+
    1086 size_type i; // current row to be defined
    \n+
    1087 size_type nnz; // count total number of nonzeros
    \n+
    1088 typedef std::set<size_type,std::less<size_type> > PatternType;
    \n+
    1089 PatternType pattern; // used to compile entries in a row
    \n+
    1090 row_type current_row; // row pointing to the current row to setup
    \n+
    1091 };
    \n+
    1092
    \n+
    1094 friend class CreateIterator;
    \n+
    1095
    \n+\n+
    1098 {
    \n+
    1099 return CreateIterator(*this,0);
    \n+
    1100 }
    \n+
    1101
    \n+\n+
    1104 {
    \n+
    1105 return CreateIterator(*this,n);
    \n+
    1106 }
    \n+
    1107
    \n+
    1108
    \n+
    1109 //===== random creation interface
    \n+
    1110
    \n+\n+
    1118 {
    \n+
    1119 if (build_mode!=random)
    \n+
    1120 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n+
    1121 if (ready != building)
    \n+
    1122 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n+
    1123
    \n+
    1124 r[i].setsize(s);
    \n+
    1125 }
    \n+
    1126
    \n+\n+
    1129 {
    \n+
    1130#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1131 if (r==0) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n+
    1132 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1133#endif
    \n+
    1134 return r[i].getsize();
    \n+
    1135 }
    \n+
    1136
    \n+\n+
    1139 {
    \n+
    1140 if (build_mode!=random)
    \n+
    1141 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n+
    1142 if (ready != building)
    \n+
    1143 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n+
    1144
    \n+
    1145 r[i].setsize(r[i].getsize()+s);
    \n+
    1146 }
    \n+
    1147
    \n+\n+
    1150 {
    \n+
    1151 if (build_mode!=random)
    \n+
    1152 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n+
    1153 if (ready != building)
    \n+
    1154 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n+
    1155
    \n+
    1156 // compute total size, check positivity
    \n+
    1157 size_type total=0;
    \n+
    1158 for (size_type i=0; i<n; i++)
    \n+
    1159 {
    \n+
    1160 total += r[i].getsize();
    \n+
    1161 }
    \n+
    1162
    \n+
    1163 if(nnz_ == 0)
    \n+
    1164 // allocate/check memory
    \n+
    1165 allocate(n,m,total,false,false);
    \n+
    1166 else if(nnz_ < total)
    \n+
    1167 DUNE_THROW(BCRSMatrixError,"Specified number of nonzeros ("<<nnz_<<") not "
    \n+
    1168 <<"sufficient for calculated nonzeros ("<<total<<"! ");
    \n+
    1169
    \n+
    1170 // set the window pointers correctly
    \n+\n+
    1172
    \n+
    1173 // initialize j_ array with m (an invalid column index)
    \n+
    1174 // this indicates an unused entry
    \n+
    1175 for (size_type k=0; k<nnz_; k++)
    \n+
    1176 j_.get()[k] = m;
    \n+\n+
    1178 }
    \n+
    1179
    \n+
    1181
    \n+\n+
    1192 {
    \n+
    1193 if (build_mode!=random)
    \n+
    1194 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n+
    1195 if (ready==built)
    \n+
    1196 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n+
    1197 if (ready==building)
    \n+
    1198 DUNE_THROW(BCRSMatrixError,"matrix row sizes not built up yet");
    \n+
    1199 if (ready==notAllocated)
    \n+
    1200 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n+
    1201
    \n+
    1202 if (col >= m)
    \n+
    1203 DUNE_THROW(BCRSMatrixError,"column index exceeds matrix size");
    \n+
    1204
    \n+
    1205 // get row range
    \n+
    1206 size_type* const first = r[row].getindexptr();
    \n+
    1207 size_type* const last = first + r[row].getsize();
    \n+
    1208
    \n+
    1209 // find correct insertion position for new column index
    \n+
    1210 size_type* pos = std::lower_bound(first,last,col);
    \n+
    1211
    \n+
    1212 // check if index is already in row
    \n+
    1213 if (pos!=last && *pos == col) return;
    \n+
    1214
    \n+
    1215 // find end of already inserted column indices
    \n+
    1216 size_type* end = std::lower_bound(pos,last,m);
    \n+
    1217 if (end==last)
    \n+
    1218 DUNE_THROW(BCRSMatrixError,"row is too small");
    \n+
    1219
    \n+
    1220 // insert new column index at correct position
    \n+
    1221 std::copy_backward(pos,end,end+1);
    \n+
    1222 *pos = col;
    \n+
    1223 }
    \n+
    1224
    \n+
    1226
    \n+
    1233 template<typename It>
    \n+
    1234 void setIndices(size_type row, It begin, It end)
    \n+
    1235 {
    \n+
    1236 size_type row_size = r[row].size();
    \n+
    1237 size_type* col_begin = r[row].getindexptr();
    \n+
    1238 size_type* col_end;
    \n+
    1239 // consistency check between allocated row size and number of passed column indices
    \n+
    1240 if ((col_end = std::copy(begin,end,r[row].getindexptr())) != col_begin + row_size)
    \n+
    1241 DUNE_THROW(BCRSMatrixError,"Given size of row " << row
    \n+
    1242 << " (" << row_size
    \n+
    1243 << ") does not match number of passed entries (" << (col_end - col_begin) << ")");
    \n+
    1244 std::sort(col_begin,col_end);
    \n+
    1245 }
    \n+
    1246
    \n+\n+
    1249 {
    \n+
    1250 if (build_mode!=random)
    \n+
    1251 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n+
    1252 if (ready==built)
    \n+
    1253 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n+
    1254 if (ready==building)
    \n+
    1255 DUNE_THROW(BCRSMatrixError,"row sizes are not built up yet");
    \n+
    1256 if (ready==notAllocated)
    \n+
    1257 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n+
    1258
    \n+
    1259 // check if there are undefined indices
    \n+
    1260 RowIterator endi=end();
    \n+
    1261 for (RowIterator i=begin(); i!=endi; ++i)
    \n+
    1262 {
    \n+
    1263 ColIterator endj = (*i).end();
    \n+
    1264 for (ColIterator j=(*i).begin(); j!=endj; ++j) {
    \n+
    1265 if (j.index() >= m) {
    \n+
    1266 dwarn << "WARNING: size of row "<< i.index()<<" is "<<j.offset()<<". But was specified as being "<< (*i).end().offset()
    \n+
    1267 <<". This means you are wasting valuable space and creating additional cache misses!"<<std::endl;
    \n+
    1268 nnz_ -= ((*i).end().offset() - j.offset());
    \n+
    1269 r[i.index()].setsize(j.offset());
    \n+
    1270 break;
    \n+
    1271 }
    \n+
    1272 }
    \n+
    1273 }
    \n+
    1274
    \n+
    1275 allocateData();
    \n+\n+
    1277
    \n+
    1278 // if not, set matrix to built
    \n+
    1279 ready = built;
    \n+
    1280 }
    \n+
    1281
    \n+
    1282 //===== implicit creation interface
    \n+
    1283
    \n+
    1285
    \n+\n+
    1297 {
    \n+
    1298#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1299 if (build_mode!=implicit)
    \n+
    1300 DUNE_THROW(BCRSMatrixError,"requires implicit build mode");
    \n+
    1301 if (ready==built)
    \n+
    1302 DUNE_THROW(BCRSMatrixError,"matrix already built up, use operator[] for entry access now");
    \n+
    1303 if (ready==notAllocated)
    \n+
    1304 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n+
    1305 if (ready!=building)
    \n+
    1306 DUNE_THROW(InvalidStateException,"You may only use entry() during the 'building' stage");
    \n+
    1307
    \n+
    1308 if (row >= n)
    \n+
    1309 DUNE_THROW(BCRSMatrixError,"row index exceeds matrix size");
    \n+
    1310 if (col >= m)
    \n+
    1311 DUNE_THROW(BCRSMatrixError,"column index exceeds matrix size");
    \n+
    1312#endif
    \n+
    1313
    \n+
    1314 size_type* begin = r[row].getindexptr();
    \n+
    1315 size_type* end = begin + r[row].getsize();
    \n+
    1316
    \n+
    1317 size_type* pos = std::find(begin, end, col);
    \n+
    1318
    \n+
    1319 //treat the case that there was a match in the array
    \n+
    1320 if (pos != end)
    \n+
    1321 if (*pos == col)
    \n+
    1322 {
    \n+
    1323 std::ptrdiff_t offset = pos - r[row].getindexptr();
    \n+
    1324 B* aptr = r[row].getptr() + offset;
    \n+
    1325
    \n+
    1326 return *aptr;
    \n+
    1327 }
    \n+
    1328
    \n+
    1329 //determine whether overflow has to be taken into account or not
    \n+
    1330 if (r[row].getsize() == avg)
    \n+
    1331 return overflow[std::make_pair(row,col)];
    \n+
    1332 else
    \n+
    1333 {
    \n+
    1334 //modify index array
    \n+
    1335 *end = col;
    \n+
    1336
    \n+
    1337 //do simultaneous operations on data array a
    \n+
    1338 std::ptrdiff_t offset = end - r[row].getindexptr();
    \n+
    1339 B* apos = r[row].getptr() + offset;
    \n+
    1340
    \n+
    1341 //increase rowsize
    \n+
    1342 r[row].setsize(r[row].getsize()+1);
    \n+
    1343
    \n+
    1344 //return reference to the newly created entry
    \n+
    1345 return *apos;
    \n+
    1346 }
    \n+
    1347 }
    \n+
    1348
    \n+
    1350
    \n+\n+
    1361 {
    \n+
    1362 if (build_mode!=implicit)
    \n+
    1363 DUNE_THROW(BCRSMatrixError,"requires implicit build mode");
    \n+
    1364 if (ready==built)
    \n+
    1365 DUNE_THROW(BCRSMatrixError,"matrix already built up, no more need for compression");
    \n+
    1366 if (ready==notAllocated)
    \n+
    1367 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n+
    1368 if (ready!=building)
    \n+
    1369 DUNE_THROW(InvalidStateException,"You may only call compress() at the end of the 'building' stage");
    \n+
    1370
    \n+
    1371 //calculate statistics
    \n+\n+
    1373 stats.overflow_total = overflow.size();
    \n+
    1374 stats.maximum = 0;
    \n+
    1375
    \n+
    1376 //get insertion iterators pointing to one before start (for later use of ++it)
    \n+
    1377 size_type* jiit = j_.get();
    \n+
    1378 B* aiit = a;
    \n+
    1379
    \n+
    1380 //get iterator to the smallest overflow element
    \n+
    1381 typename OverflowType::iterator oit = overflow.begin();
    \n+
    1382
    \n+
    1383 //store a copy of index pointers on which to perform sorting
    \n+
    1384 std::vector<size_type*> perm;
    \n+
    1385
    \n+
    1386 //iterate over all rows and copy elements into their position in the compressed array
    \n+
    1387 for (size_type i=0; i<n; i++)
    \n+
    1388 {
    \n+
    1389 //get old pointers into a and j and size without overflow changes
    \n+
    1390 size_type* begin = r[i].getindexptr();
    \n+
    1391 //B* apos = r[i].getptr();
    \n+
    1392 size_type size = r[i].getsize();
    \n+
    1393
    \n+
    1394 perm.resize(size);
    \n+
    1395
    \n+
    1396 typename std::vector<size_type*>::iterator it = perm.begin();
    \n+
    1397 for (size_type* iit = begin; iit < begin + size; ++iit, ++it)
    \n+
    1398 *it = iit;
    \n+
    1399
    \n+
    1400 //sort permutation array
    \n+
    1401 std::sort(perm.begin(),perm.end(),PointerCompare<size_type>());
    \n+
    1402
    \n+
    1403 //change row window pointer to their new positions
    \n+
    1404 r[i].setindexptr(jiit);
    \n+
    1405 r[i].setptr(aiit);
    \n+
    1406
    \n+
    1407 for (it = perm.begin(); it != perm.end(); ++it)
    \n+
    1408 {
    \n+
    1409 //check whether there are elements in the overflow area which take precedence
    \n+
    1410 while ((oit!=overflow.end()) && (oit->first < std::make_pair(i,**it)))
    \n+
    1411 {
    \n+
    1412 //check whether there is enough memory to write to
    \n+
    1413 if (jiit > begin)
    \n+\n+
    1415 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n+
    1416 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n+
    1417 );
    \n+
    1418 //copy an element from the overflow area to the insertion position in a and j
    \n+
    1419 *jiit = oit->first.second;
    \n+
    1420 ++jiit;
    \n+
    1421 *aiit = oit->second;
    \n+
    1422 ++aiit;
    \n+
    1423 ++oit;
    \n+
    1424 r[i].setsize(r[i].getsize()+1);
    \n+
    1425 }
    \n+
    1426
    \n+
    1427 //check whether there is enough memory to write to
    \n+
    1428 if (jiit > begin)
    \n+\n+
    1430 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n+
    1431 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n+
    1432 );
    \n+
    1433
    \n+
    1434 //copy element from array
    \n+
    1435 *jiit = **it;
    \n+
    1436 ++jiit;
    \n+
    1437 B* apos = *it - j_.get() + a;
    \n+
    1438 *aiit = *apos;
    \n+
    1439 ++aiit;
    \n+
    1440 }
    \n+
    1441
    \n+
    1442 //copy remaining elements from the overflow area
    \n+
    1443 while ((oit!=overflow.end()) && (oit->first.first == i))
    \n+
    1444 {
    \n+
    1445 //check whether there is enough memory to write to
    \n+
    1446 if (jiit > begin)
    \n+\n+
    1448 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n+
    1449 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n+
    1450 );
    \n+
    1451
    \n+
    1452 //copy and element from the overflow area to the insertion position in a and j
    \n+
    1453 *jiit = oit->first.second;
    \n+
    1454 ++jiit;
    \n+
    1455 *aiit = oit->second;
    \n+
    1456 ++aiit;
    \n+
    1457 ++oit;
    \n+
    1458 r[i].setsize(r[i].getsize()+1);
    \n+
    1459 }
    \n+
    1460
    \n+
    1461 // update maximum row size
    \n+
    1462 if (r[i].getsize()>stats.maximum)
    \n+
    1463 stats.maximum = r[i].getsize();
    \n+
    1464 }
    \n+
    1465
    \n+
    1466 // overflow area may be cleared
    \n+
    1467 overflow.clear();
    \n+
    1468
    \n+
    1469 //determine average number of entries and memory usage
    \n+
    1470 std::ptrdiff_t diff = (r[n-1].getindexptr() + r[n-1].getsize() - j_.get());
    \n+
    1471 nnz_ = diff;
    \n+
    1472 stats.avg = (double) (nnz_) / (double) n;
    \n+
    1473 stats.mem_ratio = (double) (nnz_) / (double) allocationSize_;
    \n+
    1474
    \n+
    1475 //matrix is now built
    \n+
    1476 ready = built;
    \n+
    1477
    \n+
    1478 return stats;
    \n+
    1479 }
    \n+
    1480
    \n+
    1481 //===== vector space arithmetic
    \n+
    1482
    \n+\n+
    1485 {
    \n+
    1486#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1487 if (ready != built)
    \n+
    1488 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1489#endif
    \n+
    1490
    \n+
    1491 if (nnz_ > 0)
    \n+
    1492 {
    \n+
    1493 // process 1D array
    \n+
    1494 for (size_type i=0; i<nnz_; i++)
    \n+
    1495 a[i] *= k;
    \n+
    1496 }
    \n+
    1497 else
    \n+
    1498 {
    \n+
    1499 RowIterator endi=end();
    \n+
    1500 for (RowIterator i=begin(); i!=endi; ++i)
    \n+
    1501 {
    \n+
    1502 ColIterator endj = (*i).end();
    \n+
    1503 for (ColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1504 (*j) *= k;
    \n+
    1505 }
    \n+
    1506 }
    \n+
    1507
    \n+
    1508 return *this;
    \n+
    1509 }
    \n+
    1510
    \n+\n+
    1513 {
    \n+
    1514#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1515 if (ready != built)
    \n+
    1516 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1517#endif
    \n+
    1518
    \n+
    1519 if (nnz_ > 0)
    \n+
    1520 {
    \n+
    1521 // process 1D array
    \n+
    1522 for (size_type i=0; i<nnz_; i++)
    \n+
    1523 a[i] /= k;
    \n+
    1524 }
    \n+
    1525 else
    \n+
    1526 {
    \n+
    1527 RowIterator endi=end();
    \n+
    1528 for (RowIterator i=begin(); i!=endi; ++i)
    \n+
    1529 {
    \n+
    1530 ColIterator endj = (*i).end();
    \n+
    1531 for (ColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1532 (*j) /= k;
    \n+
    1533 }
    \n+
    1534 }
    \n+
    1535
    \n+
    1536 return *this;
    \n+
    1537 }
    \n+
    1538
    \n+
    1539
    \n+\n+
    1546 {
    \n+
    1547#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1548 if (ready != built || b.ready != built)
    \n+
    1549 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1550 if(N()!=b.N() || M() != b.M())
    \n+
    1551 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n+
    1552#endif
    \n+
    1553 RowIterator endi=end();
    \n+
    1554 ConstRowIterator j=b.begin();
    \n+
    1555 for (RowIterator i=begin(); i!=endi; ++i, ++j) {
    \n+
    1556 i->operator+=(*j);
    \n+
    1557 }
    \n+
    1558
    \n+
    1559 return *this;
    \n+
    1560 }
    \n+
    1561
    \n+\n+
    1568 {
    \n+
    1569#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1570 if (ready != built || b.ready != built)
    \n+
    1571 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1572 if(N()!=b.N() || M() != b.M())
    \n+
    1573 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n+
    1574#endif
    \n+
    1575 RowIterator endi=end();
    \n+
    1576 ConstRowIterator j=b.begin();
    \n+
    1577 for (RowIterator i=begin(); i!=endi; ++i, ++j) {
    \n+
    1578 i->operator-=(*j);
    \n+
    1579 }
    \n+
    1580
    \n+
    1581 return *this;
    \n+
    1582 }
    \n+
    1583
    \n+\n+
    1593 {
    \n+
    1594#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1595 if (ready != built || b.ready != built)
    \n+
    1596 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1597 if(N()!=b.N() || M() != b.M())
    \n+
    1598 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n+
    1599#endif
    \n+
    1600 RowIterator endi=end();
    \n+
    1601 ConstRowIterator j=b.begin();
    \n+
    1602 for(RowIterator i=begin(); i!=endi; ++i, ++j)
    \n+
    1603 i->axpy(alpha, *j);
    \n+
    1604
    \n+
    1605 return *this;
    \n+
    1606 }
    \n+
    1607
    \n+
    1608 //===== linear maps
    \n+
    1609
    \n+
    1611 template<class X, class Y>
    \n+
    1612 void mv (const X& x, Y& y) const
    \n+
    1613 {
    \n+
    1614#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1615 if (ready != built)
    \n+
    1616 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1617 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,
    \n+
    1618 "Size mismatch: M: " << N() << "x" << M() << " x: " << x.N());
    \n+
    1619 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,
    \n+
    1620 "Size mismatch: M: " << N() << "x" << M() << " y: " << y.N());
    \n+
    1621#endif
    \n+
    1622 ConstRowIterator endi=end();
    \n+
    1623 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1624 {
    \n+
    1625 y[i.index()]=0;
    \n+
    1626 ConstColIterator endj = (*i).end();
    \n+
    1627 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1628 {
    \n+
    1629 auto&& xj = Impl::asVector(x[j.index()]);
    \n+
    1630 auto&& yi = Impl::asVector(y[i.index()]);
    \n+
    1631 Impl::asMatrix(*j).umv(xj, yi);
    \n+
    1632 }
    \n+
    1633 }
    \n+
    1634 }
    \n+
    1635
    \n+
    1637 template<class X, class Y>
    \n+
    1638 void umv (const X& x, Y& y) const
    \n+
    1639 {
    \n+
    1640#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1641 if (ready != built)
    \n+
    1642 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1643 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1644 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1645#endif
    \n+
    1646 ConstRowIterator endi=end();
    \n+
    1647 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1648 {
    \n+
    1649 ConstColIterator endj = (*i).end();
    \n+
    1650 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1651 {
    \n+
    1652 auto&& xj = Impl::asVector(x[j.index()]);
    \n+
    1653 auto&& yi = Impl::asVector(y[i.index()]);
    \n+
    1654 Impl::asMatrix(*j).umv(xj,yi);
    \n+
    1655 }
    \n+
    1656 }
    \n+
    1657 }
    \n+
    1658
    \n+
    1660 template<class X, class Y>
    \n+
    1661 void mmv (const X& x, Y& y) const
    \n+
    1662 {
    \n+
    1663#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1664 if (ready != built)
    \n+
    1665 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1666 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1667 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1668#endif
    \n+
    1669 ConstRowIterator endi=end();
    \n+
    1670 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1671 {
    \n+
    1672 ConstColIterator endj = (*i).end();
    \n+
    1673 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1674 {
    \n+
    1675 auto&& xj = Impl::asVector(x[j.index()]);
    \n+
    1676 auto&& yi = Impl::asVector(y[i.index()]);
    \n+
    1677 Impl::asMatrix(*j).mmv(xj,yi);
    \n+
    1678 }
    \n+
    1679 }
    \n+
    1680 }
    \n+
    1681
    \n+
    1683 template<class X, class Y, class F>
    \n+
    1684 void usmv (F&& alpha, const X& x, Y& y) const
    \n+
    1685 {
    \n+
    1686#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1687 if (ready != built)
    \n+
    1688 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1689 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1690 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1691#endif
    \n+
    1692 ConstRowIterator endi=end();
    \n+
    1693 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1694 {
    \n+
    1695 ConstColIterator endj = (*i).end();
    \n+
    1696 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1697 {
    \n+
    1698 auto&& xj = Impl::asVector(x[j.index()]);
    \n+
    1699 auto&& yi = Impl::asVector(y[i.index()]);
    \n+
    1700 Impl::asMatrix(*j).usmv(alpha,xj,yi);
    \n+
    1701 }
    \n+
    1702 }
    \n+
    1703 }
    \n+
    1704
    \n+
    1706 template<class X, class Y>
    \n+
    1707 void mtv (const X& x, Y& y) const
    \n+
    1708 {
    \n+
    1709#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1710 if (ready != built)
    \n+
    1711 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1712 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1713 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1714#endif
    \n+
    1715 for(size_type i=0; i<y.N(); ++i)
    \n+
    1716 y[i]=0;
    \n+
    1717 umtv(x,y);
    \n+
    1718 }
    \n+
    1719
    \n+
    1721 template<class X, class Y>
    \n+
    1722 void umtv (const X& x, Y& y) const
    \n+
    1723 {
    \n+
    1724#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1725 if (ready != built)
    \n+
    1726 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1727 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1728 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1729#endif
    \n+
    1730 ConstRowIterator endi=end();
    \n+
    1731 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1732 {
    \n+
    1733 ConstColIterator endj = (*i).end();
    \n+
    1734 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1735 {
    \n+
    1736 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1737 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1738 Impl::asMatrix(*j).umtv(xi,yj);
    \n+
    1739 }
    \n+
    1740 }
    \n+
    1741 }
    \n+
    1742
    \n+
    1744 template<class X, class Y>
    \n+
    1745 void mmtv (const X& x, Y& y) const
    \n+
    1746 {
    \n+
    1747#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1748 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1749 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1750#endif
    \n+
    1751 ConstRowIterator endi=end();
    \n+
    1752 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1753 {
    \n+
    1754 ConstColIterator endj = (*i).end();
    \n+
    1755 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1756 {
    \n+
    1757 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1758 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1759 Impl::asMatrix(*j).mmtv(xi,yj);
    \n+
    1760 }
    \n+
    1761 }
    \n+
    1762 }
    \n+
    1763
    \n+
    1765 template<class X, class Y>
    \n+
    1766 void usmtv (const field_type& alpha, const X& x, Y& y) const
    \n+
    1767 {
    \n+
    1768#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1769 if (ready != built)
    \n+
    1770 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1771 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1772 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1773#endif
    \n+
    1774 ConstRowIterator endi=end();
    \n+
    1775 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1776 {
    \n+
    1777 ConstColIterator endj = (*i).end();
    \n+
    1778 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1779 {
    \n+
    1780 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1781 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1782 Impl::asMatrix(*j).usmtv(alpha,xi,yj);
    \n+
    1783 }
    \n+
    1784 }
    \n+
    1785 }
    \n+
    1786
    \n+
    1788 template<class X, class Y>
    \n+
    1789 void umhv (const X& x, Y& y) const
    \n+
    1790 {
    \n+
    1791#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1792 if (ready != built)
    \n+
    1793 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1794 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1795 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1796#endif
    \n+
    1797 ConstRowIterator endi=end();
    \n+
    1798 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1799 {
    \n+
    1800 ConstColIterator endj = (*i).end();
    \n+
    1801 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1802 {
    \n+
    1803 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1804 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1805 Impl::asMatrix(*j).umhv(xi,yj);
    \n+
    1806 }
    \n+
    1807 }
    \n+
    1808 }
    \n+
    1809
    \n+
    1811 template<class X, class Y>
    \n+
    1812 void mmhv (const X& x, Y& y) const
    \n+
    1813 {
    \n+
    1814#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1815 if (ready != built)
    \n+
    1816 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1817 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1818 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1819#endif
    \n+
    1820 ConstRowIterator endi=end();
    \n+
    1821 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1822 {
    \n+
    1823 ConstColIterator endj = (*i).end();
    \n+
    1824 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1825 {
    \n+
    1826 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1827 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1828 Impl::asMatrix(*j).mmhv(xi,yj);
    \n+
    1829 }
    \n+
    1830 }
    \n+
    1831 }
    \n+
    1832
    \n+
    1834 template<class X, class Y>
    \n+
    1835 void usmhv (const field_type& alpha, const X& x, Y& y) const
    \n+
    1836 {
    \n+
    1837#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1838 if (ready != built)
    \n+
    1839 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1840 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1841 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n+
    1842#endif
    \n+
    1843 ConstRowIterator endi=end();
    \n+
    1844 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n+
    1845 {
    \n+
    1846 ConstColIterator endj = (*i).end();
    \n+
    1847 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n+
    1848 {
    \n+
    1849 auto&& xi = Impl::asVector(x[i.index()]);
    \n+
    1850 auto&& yj = Impl::asVector(y[j.index()]);
    \n+
    1851 Impl::asMatrix(*j).usmhv(alpha,xi,yj);
    \n+
    1852 }
    \n+
    1853 }
    \n+
    1854 }
    \n+
    1855
    \n+
    1856
    \n+
    1857 //===== norms
    \n+
    1858
    \n+
    1860 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n+
    1861 {
    \n+
    1862#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1863 if (ready != built)
    \n+
    1864 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1865#endif
    \n+
    1866
    \n+
    1867 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    1868
    \n+
    1869 for (auto&& row : (*this))
    \n+
    1870 for (auto&& entry : row)
    \n+
    1871 sum += Impl::asMatrix(entry).frobenius_norm2();
    \n+
    1872
    \n+
    1873 return sum;
    \n+
    1874 }
    \n+
    1875
    \n+
    1877 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n+
    1878 {
    \n+
    1879 return sqrt(frobenius_norm2());
    \n+
    1880 }
    \n+
    1881
    \n+
    1883 template <typename ft = field_type,
    \n+
    1884 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    1885 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    1886 if (ready != built)
    \n+
    1887 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1888
    \n+
    1889 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1890 using std::max;
    \n+
    1891
    \n+
    1892 real_type norm = 0;
    \n+
    1893 for (auto const &x : *this) {
    \n+
    1894 real_type sum = 0;
    \n+
    1895 for (auto const &y : x)
    \n+
    1896 sum += Impl::asMatrix(y).infinity_norm();
    \n+
    1897 norm = max(sum, norm);
    \n+
    1898 }
    \n+
    1899 return norm;
    \n+
    1900 }
    \n+
    1901
    \n+
    1903 template <typename ft = field_type,
    \n+
    1904 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    1905 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    1906 if (ready != built)
    \n+
    1907 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1908
    \n+
    1909 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1910 using std::max;
    \n+
    1911
    \n+
    1912 real_type norm = 0;
    \n+
    1913 for (auto const &x : *this) {
    \n+
    1914 real_type sum = 0;
    \n+
    1915 for (auto const &y : x)
    \n+
    1916 sum += Impl::asMatrix(y).infinity_norm_real();
    \n+
    1917 norm = max(sum, norm);
    \n+
    1918 }
    \n+
    1919 return norm;
    \n+
    1920 }
    \n+
    1921
    \n+
    1923 template <typename ft = field_type,
    \n+
    1924 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    1925 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    1926 if (ready != built)
    \n+
    1927 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1928
    \n+
    1929 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1930 using std::max;
    \n+
    1931
    \n+
    1932 real_type norm = 0;
    \n+
    1933 real_type isNaN = 1;
    \n+
    1934 for (auto const &x : *this) {
    \n+
    1935 real_type sum = 0;
    \n+
    1936 for (auto const &y : x)
    \n+
    1937 sum += Impl::asMatrix(y).infinity_norm();
    \n+
    1938 norm = max(sum, norm);
    \n+
    1939 isNaN += sum;
    \n+
    1940 }
    \n+
    1941
    \n+
    1942 return norm * (isNaN / isNaN);
    \n+
    1943 }
    \n+
    1944
    \n+
    1946 template <typename ft = field_type,
    \n+
    1947 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    1948 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    1949 if (ready != built)
    \n+
    1950 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n+
    1951
    \n+
    1952 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    1953 using std::max;
    \n+
    1954
    \n+
    1955 real_type norm = 0;
    \n+
    1956 real_type isNaN = 1;
    \n+
    1957
    \n+
    1958 for (auto const &x : *this) {
    \n+
    1959 real_type sum = 0;
    \n+
    1960 for (auto const &y : x)
    \n+
    1961 sum += Impl::asMatrix(y).infinity_norm_real();
    \n+
    1962 norm = max(sum, norm);
    \n+
    1963 isNaN += sum;
    \n+
    1964 }
    \n+
    1965
    \n+
    1966 return norm * (isNaN / isNaN);
    \n+
    1967 }
    \n+
    1968
    \n+
    1969 //===== sizes
    \n+
    1970
    \n+
    1972 size_type N () const
    \n+
    1973 {
    \n+
    1974 return n;
    \n+
    1975 }
    \n+
    1976
    \n+
    1978 size_type M () const
    \n+
    1979 {
    \n+
    1980 return m;
    \n+
    1981 }
    \n+
    1982
    \n+\n+
    1985 {
    \n+
    1986 // in case of row-wise allocation
    \n+
    1987 if( nnz_ <= 0 )
    \n+
    1988 nnz_ = std::accumulate( begin(), end(), size_type( 0 ), [] ( size_type s, const row_type &row ) { return s+row.getsize(); } );
    \n+
    1989 return nnz_;
    \n+
    1990 }
    \n+
    1991
    \n+\n+
    1994 {
    \n+
    1995 return ready;
    \n+
    1996 }
    \n+
    1997
    \n+\n+
    2000 {
    \n+
    2001 return build_mode;
    \n+
    2002 }
    \n+
    2003
    \n+
    2004 //===== query
    \n+
    2005
    \n+
    2007 bool exists (size_type i, size_type j) const
    \n+
    2008 {
    \n+
    2009#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    2010 if (i<0 || i>=n) DUNE_THROW(BCRSMatrixError,"row index out of range");
    \n+
    2011 if (j<0 || j>=m) DUNE_THROW(BCRSMatrixError,"column index out of range");
    \n+
    2012#endif
    \n+
    2013 return (r[i].size() && r[i].find(j) != r[i].end());
    \n+
    2014 }
    \n+
    2015
    \n+
    2016
    \n+
    2017 protected:
    \n+
    2018 // state information
    \n+
    2019 BuildMode build_mode; // row wise or whole matrix
    \n+
    2020 BuildStage ready; // indicate the stage the matrix building is in
    \n+
    2021
    \n+
    2022 // The allocator used for memory management
    \n+
    2023 typename std::allocator_traits<A>::template rebind_alloc<B> allocator_;
    \n+
    2024
    \n+
    2025 typename std::allocator_traits<A>::template rebind_alloc<row_type> rowAllocator_;
    \n+
    2026
    \n+
    2027 typename std::allocator_traits<A>::template rebind_alloc<size_type> sizeAllocator_;
    \n+
    2028
    \n+
    2029 // size of the matrix
    \n+
    2030 size_type n; // number of rows
    \n+
    2031 size_type m; // number of columns
    \n+
    2032 mutable size_type nnz_; // number of nonzeroes contained in the matrix
    \n+
    2033 size_type allocationSize_; //allocated size of a and j arrays, except in implicit mode: nnz_==allocationsSize_
    \n+
    2034 // zero means that memory is allocated separately for each row.
    \n+
    2035
    \n+
    2036 // the rows are dynamically allocated
    \n+
    2037 row_type* r; // [n] the individual rows having pointers into a,j arrays
    \n+
    2038
    \n+
    2039 // dynamically allocated memory
    \n+
    2040 B* a; // [allocationSize] non-zero entries of the matrix in row-wise ordering
    \n+
    2041 // If a single array of column indices is used, it can be shared
    \n+
    2042 // between different matrices with the same sparsity pattern
    \n+
    2043 std::shared_ptr<size_type> j_; // [allocationSize] column indices of entries
    \n+
    2044
    \n+
    2045 // additional data is needed in implicit buildmode
    \n+\n+\n+
    2048
    \n+
    2049 typedef std::map<std::pair<size_type,size_type>, B> OverflowType;
    \n+\n+
    2051
    \n+\n+
    2053 {
    \n+
    2054 row_type current_row(a,j_.get(),0); // Pointers to current row data
    \n+
    2055 for (size_type i=0; i<n; i++, ++row) {
    \n+
    2056 // set row i
    \n+
    2057 size_type s = row->getsize();
    \n+
    2058
    \n+
    2059 if (s>0) {
    \n+
    2060 // setup pointers and size
    \n+
    2061 r[i].set(s,current_row.getptr(), current_row.getindexptr());
    \n+
    2062 // update pointer for next row
    \n+
    2063 current_row.setptr(current_row.getptr()+s);
    \n+
    2064 current_row.setindexptr(current_row.getindexptr()+s);
    \n+
    2065 } else{
    \n+
    2066 // empty row
    \n+
    2067 r[i].set(0,nullptr,nullptr);
    \n+
    2068 }
    \n+
    2069 }
    \n+
    2070 }
    \n+
    2071
    \n+
    2073
    \n+\n+
    2078 {
    \n+
    2079 size_type* jptr = j_.get();
    \n+
    2080 for (size_type i=0; i<n; ++i, ++row) {
    \n+
    2081 // set row i
    \n+
    2082 size_type s = row->getsize();
    \n+
    2083
    \n+
    2084 if (s>0) {
    \n+
    2085 // setup pointers and size
    \n+
    2086 r[i].setsize(s);
    \n+
    2087 r[i].setindexptr(jptr);
    \n+
    2088 } else{
    \n+
    2089 // empty row
    \n+
    2090 r[i].set(0,nullptr,nullptr);
    \n+
    2091 }
    \n+
    2092
    \n+
    2093 // advance position in global array
    \n+
    2094 jptr += s;
    \n+
    2095 }
    \n+
    2096 }
    \n+
    2097
    \n+
    2099
    \n+\n+
    2104 {
    \n+
    2105 B* aptr = a;
    \n+
    2106 for (size_type i=0; i<n; ++i) {
    \n+
    2107 // set row i
    \n+
    2108 if (r[i].getsize() > 0) {
    \n+
    2109 // setup pointers and size
    \n+
    2110 r[i].setptr(aptr);
    \n+
    2111 } else{
    \n+
    2112 // empty row
    \n+
    2113 r[i].set(0,nullptr,nullptr);
    \n+
    2114 }
    \n+
    2115
    \n+
    2116 // advance position in global array
    \n+
    2117 aptr += r[i].getsize();
    \n+
    2118 }
    \n+
    2119 }
    \n+
    2120
    \n+\n+
    2123 {
    \n+
    2124 setWindowPointers(Mat.begin());
    \n+
    2125
    \n+
    2126 // copy data
    \n+
    2127 for (size_type i=0; i<n; i++) r[i] = Mat.r[i];
    \n+
    2128
    \n+
    2129 // finish off
    \n+
    2130 build_mode = row_wise; // dummy
    \n+
    2131 ready = built;
    \n+
    2132 }
    \n+
    2133
    \n+
    2139 void deallocate(bool deallocateRows=true)
    \n+
    2140 {
    \n+
    2141
    \n+
    2142 if (notAllocated)
    \n+
    2143 return;
    \n+
    2144
    \n+
    2145 if (allocationSize_>0)
    \n+
    2146 {
    \n+
    2147 // a,j_ have been allocated as one long vector
    \n+
    2148 j_.reset();
    \n+
    2149 if (a)
    \n+
    2150 {
    \n+
    2151 for(B *aiter=a+(allocationSize_-1), *aend=a-1; aiter!=aend; --aiter)
    \n+
    2152 std::allocator_traits<decltype(allocator_)>::destroy(allocator_, aiter);
    \n+
    2153 allocator_.deallocate(a,allocationSize_);
    \n+
    2154 a = nullptr;
    \n+
    2155 }
    \n+
    2156 }
    \n+
    2157 else if (r)
    \n+
    2158 {
    \n+
    2159 // check if memory for rows have been allocated individually
    \n+
    2160 for (size_type i=0; i<n; i++)
    \n+
    2161 if (r[i].getsize()>0)
    \n+
    2162 {
    \n+
    2163 for (B *col=r[i].getptr()+(r[i].getsize()-1),
    \n+
    2164 *colend = r[i].getptr()-1; col!=colend; --col) {
    \n+
    2165 std::allocator_traits<decltype(allocator_)>::destroy(allocator_, col);
    \n+
    2166 }
    \n+
    2167 sizeAllocator_.deallocate(r[i].getindexptr(),1);
    \n+
    2168 allocator_.deallocate(r[i].getptr(),1);
    \n+
    2169 // clear out row data in case we don't want to deallocate the rows
    \n+
    2170 // otherwise we might run into a double free problem here later
    \n+
    2171 r[i].set(0,nullptr,nullptr);
    \n+
    2172 }
    \n+
    2173 }
    \n+
    2174
    \n+
    2175 // deallocate the rows
    \n+
    2176 if (n>0 && deallocateRows && r) {
    \n+
    2177 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)
    \n+
    2178 std::allocator_traits<decltype(rowAllocator_)>::destroy(rowAllocator_, riter);
    \n+
    2179 rowAllocator_.deallocate(r,n);
    \n+
    2180 r = nullptr;
    \n+
    2181 }
    \n+
    2182
    \n+
    2183 // Mark matrix as not built at all.
    \n+\n+
    2185
    \n+
    2186 }
    \n+
    2187
    \n+
    2205 void allocate(size_type rows, size_type columns, size_type allocationSize, bool allocateRows, bool allocate_data)
    \n+
    2206 {
    \n+
    2207 // Store size
    \n+
    2208 n = rows;
    \n+
    2209 m = columns;
    \n+
    2210 nnz_ = allocationSize;
    \n+
    2211 allocationSize_ = allocationSize;
    \n+
    2212
    \n+
    2213 // allocate rows
    \n+
    2214 if(allocateRows) {
    \n+
    2215 if (n>0) {
    \n+
    2216 if (r)
    \n+
    2217 DUNE_THROW(InvalidStateException,"Rows have already been allocated, cannot allocate a second time");
    \n+
    2218 r = rowAllocator_.allocate(rows);
    \n+
    2219 // initialize row entries
    \n+
    2220 for(row_type* ri=r; ri!=r+rows; ++ri)
    \n+
    2221 std::allocator_traits<decltype(rowAllocator_)>::construct(rowAllocator_, ri, row_type());
    \n+
    2222 }else{
    \n+
    2223 r = 0;
    \n+
    2224 }
    \n+
    2225 }
    \n+
    2226
    \n+
    2227 // allocate a and j_ array
    \n+
    2228 if (allocate_data)
    \n+
    2229 allocateData();
    \n+
    2230 // allocate column indices only if not yet present (enable sharing)
    \n+
    2231 if (allocationSize_>0) {
    \n+
    2232 // we copy allocator and size to the deleter since _j may outlive this class
    \n+
    2233 if (!j_.get())
    \n+
    2234 j_.reset(sizeAllocator_.allocate(allocationSize_),
    \n+
    2235 [alloc = sizeAllocator_, size = allocationSize_](auto ptr) mutable {
    \n+
    2236 alloc.deallocate(ptr, size);
    \n+
    2237 });
    \n+
    2238 }else{
    \n+
    2239 j_.reset();
    \n+
    2240 }
    \n+
    2241
    \n+
    2242 // Mark the matrix as not built.
    \n+
    2243 ready = building;
    \n+
    2244 }
    \n+
    2245
    \n+\n+
    2247 {
    \n+
    2248 if (a)
    \n+
    2249 DUNE_THROW(InvalidStateException,"Cannot allocate data array (already allocated)");
    \n+
    2250 if (allocationSize_>0) {
    \n+
    2251 a = allocator_.allocate(allocationSize_);
    \n+
    2252 // use placement new to call constructor that allocates
    \n+
    2253 // additional memory.
    \n+
    2254 new (a) B[allocationSize_];
    \n+
    2255 } else {
    \n+
    2256 a = nullptr;
    \n+
    2257 }
    \n+
    2258 }
    \n+
    2259
    \n+\n+
    2266 {
    \n+
    2267 if (build_mode != implicit)
    \n+
    2268 DUNE_THROW(InvalidStateException,"implicit_allocate() may only be called in implicit build mode");
    \n+
    2269 if (ready != notAllocated)
    \n+
    2270 DUNE_THROW(InvalidStateException,"memory has already been allocated");
    \n+
    2271
    \n+
    2272 // check to make sure the user has actually set the parameters
    \n+
    2273 if (compressionBufferSize_ < 0)
    \n+
    2274 DUNE_THROW(InvalidStateException,"You have to set the implicit build mode parameters before starting to build the matrix");
    \n+
    2275 //calculate size of overflow region, add buffer for row sort!
    \n+\n+
    2277 allocationSize_ = _n*avg + osize;
    \n+
    2278
    \n+
    2279 allocate(_n, _m, allocationSize_,true,true);
    \n+
    2280
    \n+
    2281 //set row pointers correctly
    \n+
    2282 size_type* jptr = j_.get() + osize;
    \n+
    2283 B* aptr = a + osize;
    \n+
    2284 for (size_type i=0; i<n; i++)
    \n+
    2285 {
    \n+
    2286 r[i].set(0,aptr,jptr);
    \n+
    2287 jptr = jptr + avg;
    \n+
    2288 aptr = aptr + avg;
    \n+
    2289 }
    \n+
    2290
    \n+
    2291 ready = building;
    \n+
    2292 }
    \n+
    2293 };
    \n+
    2294
    \n+
    2295
    \n+
    2296 template<class B, class A>
    \n+
    2297 struct FieldTraits< BCRSMatrix<B, A> >
    \n+
    2298 {
    \n+\n+
    2300 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    2301 };
    \n+
    2302
    \n+
    2305} // end namespace
    \n+
    2306
    \n+
    2307#endif
    \n+
    Some handy generic functions for ISTL matrices.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+
    Helper functions for determining the vector/matrix block level.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n
    Definition: allocator.hh:11
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    virtual void post(X &x)=0
    Clean up.
    \n-
    virtual void apply(X &v, const Y &d)=0
    Apply one step of the preconditioner to the system A(v)=d.
    \n-
    virtual ~Preconditioner()
    every abstract base class has a virtual destructor
    Definition: preconditioner.hh:104
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioner.hh:37
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioner.hh:35
    \n-
    virtual SolverCategory::Category category() const =0
    Category of the preconditioner (see SolverCategory::Category)
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n-
    virtual void pre(X &x, Y &b)=0
    Prepare the preconditioner.
    \n-
    Category
    Definition: solvercategory.hh:23
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    Definition: matrixutils.hh:211
    \n+
    Statistics about compression achieved in implicit mode.
    Definition: bcrsmatrix.hh:88
    \n+
    size_type overflow_total
    total number of elements written to the overflow area during construction.
    Definition: bcrsmatrix.hh:94
    \n+
    size_type maximum
    maximum number of non-zeroes per row.
    Definition: bcrsmatrix.hh:92
    \n+
    double avg
    average number of non-zeroes per row.
    Definition: bcrsmatrix.hh:90
    \n+
    double mem_ratio
    fraction of wasted memory resulting from non-used overflow area.
    Definition: bcrsmatrix.hh:99
    \n+
    A wrapper for uniform access to the BCRSMatrix during and after the build stage in implicit build mod...
    Definition: bcrsmatrix.hh:117
    \n+
    Matrix::block_type block_type
    The block_type of the underlying matrix.
    Definition: bcrsmatrix.hh:125
    \n+
    ImplicitMatrixBuilder(Matrix &m)
    Creates an ImplicitMatrixBuilder for matrix m.
    Definition: bcrsmatrix.hh:170
    \n+
    M_ Matrix
    The underlying matrix.
    Definition: bcrsmatrix.hh:122
    \n+
    ImplicitMatrixBuilder(Matrix &m, size_type rows, size_type cols, size_type avg_cols_per_row, double overflow_fraction)
    Sets up matrix m for implicit construction using the given parameters and creates an ImplicitBmatrixu...
    Definition: bcrsmatrix.hh:194
    \n+
    size_type M() const
    The number of columns in the matrix.
    Definition: bcrsmatrix.hh:217
    \n+
    Matrix::size_type size_type
    The size_type of the underlying matrix.
    Definition: bcrsmatrix.hh:128
    \n+
    row_object operator[](size_type i) const
    Returns a proxy for entries in row i.
    Definition: bcrsmatrix.hh:205
    \n+
    size_type N() const
    The number of rows in the matrix.
    Definition: bcrsmatrix.hh:211
    \n+
    Proxy row object for entry access.
    Definition: bcrsmatrix.hh:137
    \n+
    block_type & operator[](size_type j) const
    Returns entry in column j.
    Definition: bcrsmatrix.hh:142
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bcrsmatrix.hh:488
    \n+
    std::allocator_traits< A >::template rebind_alloc< row_type > rowAllocator_
    Definition: bcrsmatrix.hh:2025
    \n+
    bool exists(size_type i, size_type j) const
    return true if (i,j) is in pattern
    Definition: bcrsmatrix.hh:2007
    \n+
    BuildStage buildStage() const
    The current build stage of the matrix.
    Definition: bcrsmatrix.hh:1993
    \n+
    Iterator begin()
    Get iterator to first row.
    Definition: bcrsmatrix.hh:675
    \n+
    friend class CreateIterator
    allow CreateIterator to access internal data
    Definition: bcrsmatrix.hh:1094
    \n+
    void copyWindowStructure(const BCRSMatrix &Mat)
    Copy the window structure from another matrix.
    Definition: bcrsmatrix.hh:2122
    \n+
    B & entry(size_type row, size_type col)
    Returns reference to entry (row,col) of the matrix.
    Definition: bcrsmatrix.hh:1296
    \n+
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: bcrsmatrix.hh:1812
    \n+
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: bcrsmatrix.hh:1835
    \n+
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: bcrsmatrix.hh:1722
    \n+
    double compressionBufferSize_
    Definition: bcrsmatrix.hh:2047
    \n+
    size_type m
    Definition: bcrsmatrix.hh:2031
    \n+
    RealRowIterator< const row_type > const_iterator
    The const iterator over the matrix rows.
    Definition: bcrsmatrix.hh:707
    \n+
    static constexpr unsigned int blocklevel
    increment block level counter
    Definition: bcrsmatrix.hh:507
    \n+
    void allocate(size_type rows, size_type columns, size_type allocationSize, bool allocateRows, bool allocate_data)
    Allocate memory for the matrix structure.
    Definition: bcrsmatrix.hh:2205
    \n+
    BCRSMatrix & axpy(field_type alpha, const BCRSMatrix &b)
    Add the scaled entries of another matrix to this one.
    Definition: bcrsmatrix.hh:1592
    \n+
    FieldTraits< ft >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: bcrsmatrix.hh:1905
    \n+
    ~BCRSMatrix()
    destructor
    Definition: bcrsmatrix.hh:824
    \n+
    void allocateData()
    Definition: bcrsmatrix.hh:2246
    \n+
    void deallocate(bool deallocateRows=true)
    deallocate memory of the matrix.
    Definition: bcrsmatrix.hh:2139
    \n+
    Iterator RowIterator
    rename the iterators for easier access
    Definition: bcrsmatrix.hh:701
    \n+
    row_type & operator[](size_type i)
    random access to the rows
    Definition: bcrsmatrix.hh:549
    \n+
    BCRSMatrix()
    an empty matrix
    Definition: bcrsmatrix.hh:749
    \n+
    void endrowsizes()
    indicate that size of all rows is defined
    Definition: bcrsmatrix.hh:1149
    \n+
    void incrementrowsize(size_type i, size_type s=1)
    increment size of row i by s (1 by default)
    Definition: bcrsmatrix.hh:1138
    \n+
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: bcrsmatrix.hh:1707
    \n+
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: bcrsmatrix.hh:1789
    \n+
    size_type nonzeroes() const
    number of blocks that are stored (the number of blocks that possibly are nonzero)
    Definition: bcrsmatrix.hh:1984
    \n+
    size_type allocationSize_
    Definition: bcrsmatrix.hh:2033
    \n+
    ConstIterator ConstRowIterator
    rename the const row iterator for easier access
    Definition: bcrsmatrix.hh:738
    \n+
    BuildStage ready
    Definition: bcrsmatrix.hh:2020
    \n+
    BuildMode build_mode
    Definition: bcrsmatrix.hh:2019
    \n+
    void setrowsize(size_type i, size_type s)
    Set number of indices in row i to s.
    Definition: bcrsmatrix.hh:1117
    \n+
    RealRowIterator< row_type > Iterator
    Definition: bcrsmatrix.hh:672
    \n+
    size_type nnz_
    Definition: bcrsmatrix.hh:2032
    \n+
    BCRSMatrix & operator*=(const field_type &k)
    vector space multiplication with scalar
    Definition: bcrsmatrix.hh:1484
    \n+
    std::allocator_traits< A >::template rebind_alloc< size_type > sizeAllocator_
    Definition: bcrsmatrix.hh:2027
    \n+
    RealRowIterator< row_type > iterator
    The iterator over the (mutable matrix rows.
    Definition: bcrsmatrix.hh:671
    \n+
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: bcrsmatrix.hh:1766
    \n+
    ConstIterator beforeBegin() const
    Definition: bcrsmatrix.hh:732
    \n+
    RealRowIterator< const row_type > ConstIterator
    Definition: bcrsmatrix.hh:708
    \n+
    Iterator beforeBegin()
    Definition: bcrsmatrix.hh:695
    \n+
    B * a
    Definition: bcrsmatrix.hh:2040
    \n+
    BuildMode
    we support two modes
    Definition: bcrsmatrix.hh:510
    \n+
    @ implicit
    Build entries randomly with an educated guess for the number of entries per row.
    Definition: bcrsmatrix.hh:539
    \n+
    @ unknown
    Build mode not set!
    Definition: bcrsmatrix.hh:543
    \n+
    @ random
    Build entries randomly.
    Definition: bcrsmatrix.hh:530
    \n+
    @ row_wise
    Build in a row-wise manner.
    Definition: bcrsmatrix.hh:521
    \n+
    BCRSMatrix(size_type _n, size_type _m, size_type _nnz, BuildMode bm)
    matrix with known number of nonzeroes
    Definition: bcrsmatrix.hh:756
    \n+
    ::Dune::CompressionStatistics< size_type > CompressionStatistics
    The type for the statistics object returned by compress()
    Definition: bcrsmatrix.hh:503
    \n+
    BCRSMatrix & operator-=(const BCRSMatrix &b)
    Subtract the entries of another matrix from this one.
    Definition: bcrsmatrix.hh:1567
    \n+
    BCRSMatrix(const BCRSMatrix &Mat)
    copy constructor
    Definition: bcrsmatrix.hh:805
    \n+
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n+
    row_type * r
    Definition: bcrsmatrix.hh:2037
    \n+
    void setIndices(size_type row, It begin, It end)
    Set all column indices for row from the given iterator range.
    Definition: bcrsmatrix.hh:1234
    \n+
    void addindex(size_type row, size_type col)
    add index (row,col) to the matrix
    Definition: bcrsmatrix.hh:1191
    \n+
    std::map< std::pair< size_type, size_type >, B > OverflowType
    Definition: bcrsmatrix.hh:2049
    \n+
    row_type::Iterator ColIterator
    Iterator for the entries of each row.
    Definition: bcrsmatrix.hh:704
    \n+
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: bcrsmatrix.hh:1877
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    BCRSMatrix & operator/=(const field_type &k)
    vector space division by scalar
    Definition: bcrsmatrix.hh:1512
    \n+
    OverflowType overflow
    Definition: bcrsmatrix.hh:2050
    \n+
    BCRSMatrix & operator+=(const BCRSMatrix &b)
    Add the entries of another matrix to this one.
    Definition: bcrsmatrix.hh:1545
    \n+
    BCRSMatrix(size_type _n, size_type _m, size_type _avg, double compressionBufferSize, BuildMode bm)
    construct matrix with a known average number of entries per row
    Definition: bcrsmatrix.hh:784
    \n+
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: bcrsmatrix.hh:1103
    \n+
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: bcrsmatrix.hh:1860
    \n+
    Iterator beforeEnd()
    Definition: bcrsmatrix.hh:688
    \n+
    row_type::ConstIterator ConstColIterator
    Const iterator to the entries of a row.
    Definition: bcrsmatrix.hh:741
    \n+
    void usmv(F &&alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: bcrsmatrix.hh:1684
    \n+
    size_type getrowsize(size_type i) const
    get current number of indices in row i
    Definition: bcrsmatrix.hh:1128
    \n+
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n+
    size_type n
    Definition: bcrsmatrix.hh:2030
    \n+
    Imp::CompressedBlockVectorWindow< B, A > row_type
    implement row_type with compressed vector
    Definition: bcrsmatrix.hh:497
    \n+
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n+
    BuildStage
    Definition: bcrsmatrix.hh:469
    \n+
    @ rowSizesBuilt
    The row sizes of the matrix are known.
    Definition: bcrsmatrix.hh:480
    \n+
    @ built
    The matrix structure is fully built.
    Definition: bcrsmatrix.hh:482
    \n+
    @ notbuilt
    Matrix is not built at all, no memory has been allocated, build mode and size can still be set.
    Definition: bcrsmatrix.hh:471
    \n+
    @ notAllocated
    Matrix is not built at all, no memory has been allocated, build mode and size can still be set.
    Definition: bcrsmatrix.hh:473
    \n+
    @ building
    Matrix is currently being built, some memory has been allocated, build mode and size are fixed.
    Definition: bcrsmatrix.hh:475
    \n+
    BuildMode buildMode() const
    The currently selected build mode of the matrix.
    Definition: bcrsmatrix.hh:1999
    \n+
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: bcrsmatrix.hh:1661
    \n+
    FieldTraits< ft >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: bcrsmatrix.hh:1885
    \n+
    void mv(const X &x, Y &y) const
    y = A x
    Definition: bcrsmatrix.hh:1612
    \n+
    B block_type
    export the type representing the components
    Definition: bcrsmatrix.hh:491
    \n+
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: bcrsmatrix.hh:1745
    \n+
    size_type avg
    Definition: bcrsmatrix.hh:2046
    \n+
    void umv(const X &x, Y &y) const
    y += A x
    Definition: bcrsmatrix.hh:1638
    \n+
    void implicit_allocate(size_type _n, size_type _m)
    organizes allocation implicit mode calculates correct array size to be allocated and sets the the win...
    Definition: bcrsmatrix.hh:2265
    \n+
    void setImplicitBuildModeParameters(size_type _avg, double compressionBufferSize)
    Set parameters needed for creation in implicit build mode.
    Definition: bcrsmatrix.hh:889
    \n+
    BCRSMatrix(size_type _n, size_type _m, BuildMode bm)
    matrix with unknown number of nonzeroes
    Definition: bcrsmatrix.hh:765
    \n+
    void endindices()
    indicate that all indices are defined, check consistency
    Definition: bcrsmatrix.hh:1248
    \n+
    CompressionStatistics compress()
    Finishes the buildstage in implicit mode.
    Definition: bcrsmatrix.hh:1360
    \n+
    void setDataPointers()
    Set data pointers for all rows.
    Definition: bcrsmatrix.hh:2103
    \n+
    std::allocator_traits< A >::template rebind_alloc< B > allocator_
    Definition: bcrsmatrix.hh:2023
    \n+
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n+
    void setBuildMode(BuildMode bm)
    Sets the build mode of the matrix.
    Definition: bcrsmatrix.hh:833
    \n+
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n+
    std::shared_ptr< size_type > j_
    Definition: bcrsmatrix.hh:2043
    \n+
    void setWindowPointers(ConstRowIterator row)
    Definition: bcrsmatrix.hh:2052
    \n+
    BCRSMatrix & operator=(const BCRSMatrix &Mat)
    assignment
    Definition: bcrsmatrix.hh:911
    \n+
    void setColumnPointers(ConstRowIterator row)
    Copy row sizes from iterator range starting at row and set column index pointers for all rows.
    Definition: bcrsmatrix.hh:2077
    \n+
    ConstIterator end() const
    Get const iterator to one beyond last row.
    Definition: bcrsmatrix.hh:718
    \n+
    ConstIterator begin() const
    Get const iterator to first row.
    Definition: bcrsmatrix.hh:712
    \n+
    A allocator_type
    export the allocator type
    Definition: bcrsmatrix.hh:494
    \n+
    ConstIterator beforeEnd() const
    Definition: bcrsmatrix.hh:725
    \n+
    Iterator access to matrix rows
    Definition: bcrsmatrix.hh:579
    \n+
    RealRowIterator()
    empty constructor, use with care!
    Definition: bcrsmatrix.hh:596
    \n+
    bool equals(const RealRowIterator< ValueType > &other) const
    equality
    Definition: bcrsmatrix.hh:624
    \n+
    std::remove_const< T >::type ValueType
    The unqualified value type.
    Definition: bcrsmatrix.hh:583
    \n+
    RealRowIterator(const RealRowIterator< ValueType > &it)
    Definition: bcrsmatrix.hh:600
    \n+
    bool equals(const RealRowIterator< const ValueType > &other) const
    equality
    Definition: bcrsmatrix.hh:631
    \n+
    RealRowIterator(row_type *_p, size_type _i)
    constructor
    Definition: bcrsmatrix.hh:591
    \n+
    std::ptrdiff_t distanceTo(const RealRowIterator< const ValueType > &other) const
    Definition: bcrsmatrix.hh:617
    \n+
    size_type index() const
    return index
    Definition: bcrsmatrix.hh:606
    \n+
    std::ptrdiff_t distanceTo(const RealRowIterator< ValueType > &other) const
    Definition: bcrsmatrix.hh:611
    \n+
    Iterator class for sequential creation of blocks
    Definition: bcrsmatrix.hh:957
    \n+
    bool operator==(const CreateIterator &it) const
    equality
    Definition: bcrsmatrix.hh:1052
    \n+
    CreateIterator & operator++()
    prefix increment
    Definition: bcrsmatrix.hh:977
    \n+
    size_type index() const
    The number of the row that the iterator currently points to.
    Definition: bcrsmatrix.hh:1058
    \n+
    bool operator!=(const CreateIterator &it) const
    inequality
    Definition: bcrsmatrix.hh:1046
    \n+
    CreateIterator(BCRSMatrix &_Mat, size_type _i)
    constructor
    Definition: bcrsmatrix.hh:960
    \n+
    void insert(size_type j)
    put column index in row
    Definition: bcrsmatrix.hh:1064
    \n+
    bool contains(size_type j)
    return true if column index is in row
    Definition: bcrsmatrix.hh:1070
    \n+
    size_type size() const
    Get the current row size.
    Definition: bcrsmatrix.hh:1079
    \n+
    typename BCRSMatrix< B, A >::field_type field_type
    Definition: bcrsmatrix.hh:2299
    \n+
    typename FieldTraits< field_type >::real_type real_type
    Definition: bcrsmatrix.hh:2300
    \n+
    Error specific to BCRSMatrix.
    Definition: istlexception.hh:24
    \n+
    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted.
    Definition: istlexception.hh:37
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n+
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n+
    Definition: matrixutils.hh:538
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,93 +4,2393 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-preconditioner.hh\n+bcrsmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_PRECONDITIONER_HH\n- 6#define DUNE_ISTL_PRECONDITIONER_HH\n- 7\n- 8#include \n- 9\n- 10#include \"solvercategory.hh\"\n- 11\n- 12namespace Dune {\n- 17 //=====================================================================\n- 30 //=====================================================================\n- 31 template\n-32 class Preconditioner {\n- 33 public:\n-35 typedef X domain_type;\n-37 typedef Y range_type;\n-39 typedef typename X::field_type field_type;\n- 40\n-69 virtual void pre (X& x, Y& b) = 0;\n- 70\n-81 virtual void apply (X& v, const Y& d) = 0;\n- 82\n-91 virtual void post (X& x) = 0;\n- 92\n-94 virtual SolverCategory::Category category() const\n- 95#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n- 96 {\n- 97 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n-method in a derived classes, in the future this method will pure virtual.\");\n- 98 }\n- 99#else\n- 100 = 0;\n- 101#endif\n- 102\n-104 virtual ~Preconditioner () {}\n- 105\n- 106 };\n- 107\n- 111}\n- 112#endif\n-solvercategory.hh\n+ 5\n+ 6#ifndef DUNE_ISTL_BCRSMATRIX_HH\n+ 7#define DUNE_ISTL_BCRSMATRIX_HH\n+ 8\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18\n+ 19#include \"istlexception.hh\"\n+ 20#include \"bvector.hh\"\n+ 21#include \"matrixutils.hh\"\n+ 22#include \n+ 23#include \n+ 24#include \n+ 25#include \n+ 26#include \n+ 27#include \n+ 28\n+ 29#include \n+ 30\n+ 35namespace Dune {\n+ 36\n+ 76 template\n+ 77 struct MatrixDimension;\n+ 78\n+ 80\n+ 86 template\n+87 struct CompressionStatistics\n+ 88 {\n+90 double avg;\n+92 size_type maximum;\n+94 size_type overflow_total;\n+ 96\n+99 double mem_ratio;\n+ 100 };\n+ 101\n+ 103\n+ 115 template\n+116 class ImplicitMatrixBuilder\n+ 117 {\n+ 118\n+ 119 public:\n+ 120\n+122 typedef M_ Matrix;\n+ 123\n+125 typedef typename Matrix::block_type block_type;\n+ 126\n+128 typedef typename Matrix::size_type size_type;\n+ 129\n+ 131\n+136 class row_object\n+ 137 {\n+ 138\n+ 139 public:\n+ 140\n+142 block_type& operator[](size_type j) const\n+ 143 {\n+ 144 return _m.entry(_i,j);\n+ 145 }\n+ 146\n+ 147#ifndef DOXYGEN\n+ 148\n+ 149 row_object(Matrix& m, size_type i)\n+ 150 : _m(m)\n+ 151 , _i(i)\n+ 152 {}\n+ 153\n+ 154#endif\n+ 155\n+ 156 private:\n+ 157\n+ 158 Matrix& _m;\n+159 size_type _i;\n+ 160\n+ 161 };\n+ 162\n+ 164\n+170 ImplicitMatrixBuilder(Matrix& m)\n+ 171 : _m(m)\n+ 172 {\n+ 173 if (m.buildMode() != Matrix::implicit)\n+ 174 DUNE_THROW(BCRSMatrixError,\"You can only create an ImplicitBuilder for a\n+matrix in implicit build mode\");\n+ 175 if (m.buildStage() != Matrix::building)\n+ 176 DUNE_THROW(BCRSMatrixError,\"You can only create an ImplicitBuilder for a\n+matrix with set size that has not been compressed() yet\");\n+ 177 }\n+ 178\n+ 180\n+194 ImplicitMatrixBuilder(Matrix& m, size_type rows, size_type cols, size_type\n+avg_cols_per_row, double overflow_fraction)\n+ 195 : _m(m)\n+ 196 {\n+ 197 if (m.buildStage() != Matrix::notAllocated)\n+ 198 DUNE_THROW(BCRSMatrixError,\"You can only set up a matrix for this\n+ImplicitBuilder if it has no memory allocated yet\");\n+ 199 m.setBuildMode(Matrix::implicit);\n+ 200 m.setImplicitBuildModeParameters(avg_cols_per_row,overflow_fraction);\n+ 201 m.setSize(rows,cols);\n+ 202 }\n+ 203\n+205 row_object operator[](size_type i) const\n+ 206 {\n+ 207 return row_object(_m,i);\n+ 208 }\n+ 209\n+211 size_type N() const\n+ 212 {\n+ 213 return _m.N();\n+ 214 }\n+ 215\n+217 size_type M() const\n+ 218 {\n+ 219 return _m.M();\n+ 220 }\n+ 221\n+ 222 private:\n+ 223\n+ 224 Matrix& _m;\n+ 225\n+ 226 };\n+ 227\n+ 464 template >\n+465 class BCRSMatrix\n+ 466 {\n+ 467 friend struct MatrixDimension;\n+ 468 public:\n+469 enum BuildStage {\n+471 notbuilt=0,\n+473 notAllocated=0,\n+475 building=1,\n+480 rowSizesBuilt=2,\n+ 482 built=3\n+483 };\n+ 484\n+ 485 //===== type definitions and constants\n+ 486\n+488 using field_type = typename Imp::BlockTraits::field_type;\n+ 489\n+491 typedef B block_type;\n+ 492\n+494 typedef A allocator_type;\n+ 495\n+497 typedef Imp::CompressedBlockVectorWindow row_type;\n+ 498\n+500 typedef typename A::size_type size_type;\n+ 501\n+503 typedef ::Dune::CompressionStatistics CompressionStatistics;\n+ 504\n+ 506 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+507 static constexpr unsigned int blocklevel = blockLevel()+1;\n+ 508\n+510 enum BuildMode {\n+521 row_wise,\n+530 random,\n+539 implicit,\n+ 543 unknown\n+544 };\n+ 545\n+ 546 //===== random access interface to rows of the matrix\n+ 547\n+549 row_type& operator[](size_type i)\n+ 550 {\n+ 551#ifdef DUNE_ISTL_WITH_CHECKING\n+ 552 if (build_mode == implicit && ready != built)\n+ 553 DUNE_THROW(BCRSMatrixError,\"You cannot use operator[] in implicit build\n+mode before calling compress()\");\n+ 554 if (r==0) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n+ 555 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 556#endif\n+ 557 return r[i];\n+ 558 }\n+ 559\n+561 const row_type& operator[](size_type i) const\n+ 562 {\n+ 563#ifdef DUNE_ISTL_WITH_CHECKING\n+ 564 if (build_mode == implicit && ready != built)\n+ 565 DUNE_THROW(BCRSMatrixError,\"You cannot use operator[] in implicit build\n+mode before calling compress()\");\n+ 566 if (built!=ready) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n+ 567 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 568#endif\n+ 569 return r[i];\n+ 570 }\n+ 571\n+ 572\n+ 573 //===== iterator interface to rows of the matrix\n+ 574\n+ 576 template\n+577 class RealRowIterator\n+ 578 : public RandomAccessIteratorFacade, T>\n+ 579 {\n+ 580\n+ 581 public:\n+583 typedef typename std::remove_const::type ValueType;\n+ 584\n+ 585 friend class RandomAccessIteratorFacade,\n+const ValueType>;\n+ 586 friend class RandomAccessIteratorFacade,\n+ValueType>;\n+ 587 friend class RealRowIterator;\n+ 588 friend class RealRowIterator;\n+ 589\n+591 RealRowIterator (row_type* _p, size_type _i)\n+ 592 : p(_p), i(_i)\n+ 593 {}\n+ 594\n+596 RealRowIterator ()\n+ 597 : p(0), i(0)\n+ 598 {}\n+ 599\n+600 RealRowIterator(const RealRowIterator& it)\n+ 601 : p(it.p), i(it.i)\n+ 602 {}\n+ 603\n+ 604\n+606 size_type index () const\n+ 607 {\n+ 608 return i;\n+ 609 }\n+ 610\n+611 std::ptrdiff_t distanceTo(const RealRowIterator& other) const\n+ 612 {\n+ 613 assert(other.p==p);\n+ 614 return (other.i-i);\n+ 615 }\n+ 616\n+617 std::ptrdiff_t distanceTo(const RealRowIterator& other)\n+const\n+ 618 {\n+ 619 assert(other.p==p);\n+ 620 return (other.i-i);\n+ 621 }\n+ 622\n+624 bool equals (const RealRowIterator& other) const\n+ 625 {\n+ 626 assert(other.p==p);\n+ 627 return i==other.i;\n+ 628 }\n+ 629\n+631 bool equals (const RealRowIterator& other) const\n+ 632 {\n+ 633 assert(other.p==p);\n+ 634 return i==other.i;\n+ 635 }\n+ 636\n+ 637 private:\n+ 639 void increment()\n+ 640 {\n+ 641 ++i;\n+ 642 }\n+ 643\n+ 645 void decrement()\n+ 646 {\n+ 647 --i;\n+ 648 }\n+ 649\n+ 650 void advance(std::ptrdiff_t diff)\n+ 651 {\n+ 652 i+=diff;\n+ 653 }\n+ 654\n+ 655 T& elementAt(std::ptrdiff_t diff) const\n+ 656 {\n+ 657 return p[i+diff];\n+ 658 }\n+ 659\n+ 661 row_type& dereference () const\n+ 662 {\n+ 663 return p[i];\n+ 664 }\n+ 665\n+ 666 row_type* p;\n+ 667 size_type i;\n+ 668 };\n+ 669\n+671 typedef RealRowIterator iterator;\n+672 typedef RealRowIterator Iterator;\n+ 673\n+675 Iterator begin ()\n+ 676 {\n+ 677 return Iterator(r,0);\n+ 678 }\n+ 679\n+681 Iterator end ()\n+ 682 {\n+ 683 return Iterator(r,n);\n+ 684 }\n+ 685\n+688 Iterator beforeEnd ()\n+ 689 {\n+ 690 return Iterator(r,n-1);\n+ 691 }\n+ 692\n+695 Iterator beforeBegin ()\n+ 696 {\n+ 697 return Iterator(r,-1);\n+ 698 }\n+ 699\n+701 typedef Iterator RowIterator;\n+ 702\n+704 typedef typename row_type::Iterator ColIterator;\n+ 705\n+707 typedef RealRowIterator const_iterator;\n+708 typedef RealRowIterator ConstIterator;\n+ 709\n+ 710\n+712 ConstIterator begin () const\n+ 713 {\n+ 714 return ConstIterator(r,0);\n+ 715 }\n+ 716\n+718 ConstIterator end () const\n+ 719 {\n+ 720 return ConstIterator(r,n);\n+ 721 }\n+ 722\n+725 ConstIterator beforeEnd() const\n+ 726 {\n+ 727 return ConstIterator(r,n-1);\n+ 728 }\n+ 729\n+732 ConstIterator beforeBegin () const\n+ 733 {\n+ 734 return ConstIterator(r,-1);\n+ 735 }\n+ 736\n+738 typedef ConstIterator ConstRowIterator;\n+ 739\n+741 typedef typename row_type::ConstIterator ConstColIterator;\n+ 742\n+ 743 //===== constructors & resizers\n+ 744\n+ 745 // we use a negative compressionBufferSize to indicate that the implicit\n+ 746 // mode parameters have not been set yet\n+ 747\n+749 BCRSMatrix ()\n+ 750 : build_mode(unknown), ready(notAllocated), n(0), m(0), nnz_(0),\n+ 751 allocationSize_(0), r(0), a(0),\n+ 752 avg(0), compressionBufferSize_(-1.0)\n+ 753 {}\n+ 754\n+756 BCRSMatrix (size_type _n, size_type _m, size_type _nnz, BuildMode bm)\n+ 757 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n+ 758 allocationSize_(0), r(0), a(0),\n+ 759 avg(0), compressionBufferSize_(-1.0)\n+ 760 {\n+ 761 allocate(_n, _m, _nnz,true,false);\n+ 762 }\n+ 763\n+765 BCRSMatrix (size_type _n, size_type _m, BuildMode bm)\n+ 766 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n+ 767 allocationSize_(0), r(0), a(0),\n+ 768 avg(0), compressionBufferSize_(-1.0)\n+ 769 {\n+ 770 allocate(_n, _m,0,true,false);\n+ 771 }\n+ 772\n+ 774\n+784 BCRSMatrix (size_type _n, size_type _m, size_type _avg, double\n+compressionBufferSize, BuildMode bm)\n+ 785 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n+ 786 allocationSize_(0), r(0), a(0),\n+ 787 avg(_avg), compressionBufferSize_(compressionBufferSize)\n+ 788 {\n+ 789 if (bm != implicit)\n+ 790 DUNE_THROW(BCRSMatrixError,\"Only call this constructor when using the\n+implicit build mode\");\n+ 791 // Prevent user from setting a negative compression buffer size:\n+ 792 // 1) It doesn't make sense\n+ 793 // 2) We use a negative value to indicate that the parameters\n+ 794 // have not been set yet\n+ 795 if (compressionBufferSize_ < 0.0)\n+ 796 DUNE_THROW(BCRSMatrixError,\"You cannot set a negative overflow fraction\");\n+ 797 implicit_allocate(_n,_m);\n+ 798 }\n+ 799\n+805 BCRSMatrix (const BCRSMatrix& Mat)\n+ 806 : build_mode(Mat.build_mode), ready(notAllocated), n(0), m(0), nnz_(0),\n+ 807 allocationSize_(0), r(0), a(0),\n+ 808 avg(Mat.avg), compressionBufferSize_(Mat.compressionBufferSize_)\n+ 809 {\n+ 810 if (!(Mat.ready == notAllocated || Mat.ready == built))\n+ 811 DUNE_THROW(InvalidStateException,\"BCRSMatrix can only be copy-constructed\n+when source matrix is completely empty (size not set) or fully built)\");\n+ 812\n+ 813 // deep copy in global array\n+ 814 size_type _nnz = Mat.nonzeroes();\n+ 815\n+ 816 j_ = Mat.j_; // enable column index sharing, release array in case of row-\n+wise allocation\n+ 817 allocate(Mat.n, Mat.m, _nnz, true, true);\n+ 818\n+ 819 // build window structure\n+ 820 copyWindowStructure(Mat);\n+ 821 }\n+ 822\n+824 ~BCRSMatrix ()\n+ 825 {\n+ 826 deallocate();\n+ 827 }\n+ 828\n+833 void setBuildMode(BuildMode bm)\n+ 834 {\n+ 835 if (ready == notAllocated)\n+ 836 {\n+ 837 build_mode = bm;\n+ 838 return;\n+ 839 }\n+ 840 if (ready == building && (build_mode == unknown || build_mode == random ||\n+build_mode == row_wise) && (bm == row_wise || bm == random))\n+ 841 build_mode = bm;\n+ 842 else\n+ 843 DUNE_THROW(InvalidStateException, \"Matrix structure cannot be changed at\n+this stage anymore (ready == \"<0)\n+ 869 DUNE_THROW(Dune::BCRSMatrixError,\"number of non-zeroes may not be set in\n+implicit mode, use setImplicitBuildModeParameters() instead\");\n+ 870\n+ 871 // implicit allocates differently\n+ 872 implicit_allocate(rows,columns);\n+ 873 }\n+ 874 else\n+ 875 {\n+ 876 // allocate matrix memory\n+ 877 allocate(rows, columns, nnz, true, false);\n+ 878 }\n+ 879 }\n+ 880\n+889 void setImplicitBuildModeParameters(size_type _avg, double\n+compressionBufferSize)\n+ 890 {\n+ 891 // Prevent user from setting a negative compression buffer size:\n+ 892 // 1) It doesn't make sense\n+ 893 // 2) We use a negative value to indicate that the parameters\n+ 894 // have not been set yet\n+ 895 if (compressionBufferSize < 0.0)\n+ 896 DUNE_THROW(BCRSMatrixError,\"You cannot set a negative\n+compressionBufferSize value\");\n+ 897\n+ 898 // make sure the parameters aren't changed after memory has been allocated\n+ 899 if (ready != notAllocated)\n+ 900 DUNE_THROW(InvalidStateException,\"You cannot modify build mode parameters\n+at this stage anymore\");\n+ 901 avg = _avg;\n+ 902 compressionBufferSize_ = compressionBufferSize;\n+ 903 }\n+ 904\n+911 BCRSMatrix& operator=(const BCRSMatrix& Mat)\n+ 912 {\n+ 913 // return immediately when self-assignment\n+ 914 if (&Mat==this) return *this;\n+ 915\n+ 916 if (!((ready == notAllocated || ready == built) && (Mat.ready ==\n+notAllocated || Mat.ready == built)))\n+ 917 DUNE_THROW(InvalidStateException,\"BCRSMatrix can only be copied when both\n+target and source are empty or fully built)\");\n+ 918\n+ 919 // make it simple: ALWAYS throw away memory for a and j_\n+ 920 // and deallocate rows only if n != Mat.n\n+ 921 deallocate(n!=Mat.n);\n+ 922\n+ 923 // reallocate the rows if required\n+ 924 if (n>0 && n!=Mat.n) {\n+ 925 // free rows\n+ 926 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)\n+ 927 std::allocator_traits::destroy(rowAllocator_,\n+riter);\n+ 928 rowAllocator_.deallocate(r,n);\n+ 929 }\n+ 930\n+ 931 nnz_ = Mat.nonzeroes();\n+ 932\n+ 933 // allocate a, share j_\n+ 934 j_ = Mat.j_;\n+ 935 allocate(Mat.n, Mat.m, nnz_, n!=Mat.n, true);\n+ 936\n+ 937 // build window structure\n+ 938 copyWindowStructure(Mat);\n+ 939 return *this;\n+ 940 }\n+ 941\n+943 BCRSMatrix& operator=(const field_type& k)\n+ 944 {\n+ 945\n+ 946 if (!(ready == notAllocated || ready == built))\n+ 947 DUNE_THROW(InvalidStateException,\"Scalar assignment only works on fully\n+built BCRSMatrix)\");\n+ 948\n+ 949 for (size_type i=0; i0) {\n+ 991 // update number of nonzeroes including this row\n+ 992 nnz += s;\n+ 993\n+ 994 // alloc memory / set window\n+ 995 if (Mat.nnz_ > 0)\n+ 996 {\n+ 997 // memory is allocated in one long array\n+ 998\n+ 999 // check if that memory is sufficient\n+ 1000 if (nnz > Mat.nnz_)\n+ 1001 DUNE_THROW(BCRSMatrixError,\"allocated nnz too small\");\n+ 1002\n+ 1003 // set row i\n+ 1004 Mat.r[i].set(s,nullptr,current_row.getindexptr());\n+ 1005 current_row.setindexptr(current_row.getindexptr()+s);\n+ 1006 }else{\n+ 1007 // memory is allocated individually per row\n+ 1008 // allocate and set row i\n+ 1009 B* b = Mat.allocator_.allocate(s);\n+ 1010 // use placement new to call constructor that allocates\n+ 1011 // additional memory.\n+ 1012 new (b) B[s];\n+ 1013 size_type* j = Mat.sizeAllocator_.allocate(s);\n+ 1014 Mat.r[i].set(s,b,j);\n+ 1015 }\n+ 1016 }else\n+ 1017 // setup empty row\n+ 1018 Mat.r[i].set(0,nullptr,nullptr);\n+ 1019\n+ 1020 // initialize the j array for row i from pattern\n+ 1021 std::copy(pattern.cbegin(), pattern.cend(), Mat.r[i].getindexptr());\n+ 1022\n+ 1023 // now go to next row\n+ 1024 i++;\n+ 1025 pattern.clear();\n+ 1026\n+ 1027 // check if this was last row\n+ 1028 if (i==Mat.n)\n+ 1029 {\n+ 1030 Mat.ready = built;\n+ 1031 if(Mat.nnz_ > 0)\n+ 1032 {\n+ 1033 // Set nnz to the exact number of nonzero blocks inserted\n+ 1034 // as some methods rely on it\n+ 1035 Mat.nnz_ = nnz;\n+ 1036 // allocate data array\n+ 1037 Mat.allocateData();\n+ 1038 Mat.setDataPointers();\n+ 1039 }\n+ 1040 }\n+ 1041 // done\n+ 1042 return *this;\n+ 1043 }\n+ 1044\n+1046 bool operator!=(const CreateIterator& it) const\n+ 1047 {\n+ 1048 return (i!=it.i) || (&Mat!=&it.Mat);\n+ 1049 }\n+ 1050\n+1052 bool operator==(const CreateIterator& it) const\n+ 1053 {\n+ 1054 return (i==it.i) && (&Mat==&it.Mat);\n+ 1055 }\n+ 1056\n+1058 size_type index () const\n+ 1059 {\n+ 1060 return i;\n+ 1061 }\n+ 1062\n+1064 void insert (size_type j)\n+ 1065 {\n+ 1066 pattern.insert(j);\n+ 1067 }\n+ 1068\n+1070 bool contains (size_type j)\n+ 1071 {\n+ 1072 return pattern.find(j) != pattern.end();\n+ 1073 }\n+1079 size_type size() const\n+ 1080 {\n+ 1081 return pattern.size();\n+ 1082 }\n+ 1083\n+ 1084 private:\n+ 1085 BCRSMatrix& Mat; // the matrix we are defining\n+ 1086 size_type i; // current row to be defined\n+ 1087 size_type nnz; // count total number of nonzeros\n+ 1088 typedef std::set > PatternType;\n+ 1089 PatternType pattern; // used to compile entries in a row\n+ 1090 row_type current_row; // row pointing to the current row to setup\n+ 1091 };\n+ 1092\n+1094 friend class CreateIterator;\n+ 1095\n+1097 CreateIterator createbegin ()\n+ 1098 {\n+ 1099 return CreateIterator(*this,0);\n+ 1100 }\n+ 1101\n+1103 CreateIterator createend ()\n+ 1104 {\n+ 1105 return CreateIterator(*this,n);\n+ 1106 }\n+ 1107\n+ 1108\n+ 1109 //===== random creation interface\n+ 1110\n+1117 void setrowsize (size_type i, size_type s)\n+ 1118 {\n+ 1119 if (build_mode!=random)\n+ 1120 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n+ 1121 if (ready != building)\n+ 1122 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n+ 1123\n+ 1124 r[i].setsize(s);\n+ 1125 }\n+ 1126\n+1128 size_type getrowsize (size_type i) const\n+ 1129 {\n+ 1130#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1131 if (r==0) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n+ 1132 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1133#endif\n+ 1134 return r[i].getsize();\n+ 1135 }\n+ 1136\n+1138 void incrementrowsize (size_type i, size_type s = 1)\n+ 1139 {\n+ 1140 if (build_mode!=random)\n+ 1141 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n+ 1142 if (ready != building)\n+ 1143 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n+ 1144\n+ 1145 r[i].setsize(r[i].getsize()+s);\n+ 1146 }\n+ 1147\n+1149 void endrowsizes ()\n+ 1150 {\n+ 1151 if (build_mode!=random)\n+ 1152 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n+ 1153 if (ready != building)\n+ 1154 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n+ 1155\n+ 1156 // compute total size, check positivity\n+ 1157 size_type total=0;\n+ 1158 for (size_type i=0; i= m)\n+ 1203 DUNE_THROW(BCRSMatrixError,\"column index exceeds matrix size\");\n+ 1204\n+ 1205 // get row range\n+ 1206 size_type* const first = r[row].getindexptr();\n+ 1207 size_type* const last = first + r[row].getsize();\n+ 1208\n+ 1209 // find correct insertion position for new column index\n+ 1210 size_type* pos = std::lower_bound(first,last,col);\n+ 1211\n+ 1212 // check if index is already in row\n+ 1213 if (pos!=last && *pos == col) return;\n+ 1214\n+ 1215 // find end of already inserted column indices\n+ 1216 size_type* end = std::lower_bound(pos,last,m);\n+ 1217 if (end==last)\n+ 1218 DUNE_THROW(BCRSMatrixError,\"row is too small\");\n+ 1219\n+ 1220 // insert new column index at correct position\n+ 1221 std::copy_backward(pos,end,end+1);\n+ 1222 *pos = col;\n+ 1223 }\n+ 1224\n+ 1226\n+ 1233 template\n+1234 void setIndices(size_type row, It begin, It end)\n+ 1235 {\n+ 1236 size_type row_size = r[row].size();\n+ 1237 size_type* col_begin = r[row].getindexptr();\n+ 1238 size_type* col_end;\n+ 1239 // consistency check between allocated row size and number of passed\n+column indices\n+ 1240 if ((col_end = std::copy(begin,end,r[row].getindexptr())) != col_begin +\n+row_size)\n+ 1241 DUNE_THROW(BCRSMatrixError,\"Given size of row \" << row\n+ 1242 << \" (\" << row_size\n+ 1243 << \") does not match number of passed entries (\" << (col_end - col_begin)\n+<< \")\");\n+ 1244 std::sort(col_begin,col_end);\n+ 1245 }\n+ 1246\n+1248 void endindices ()\n+ 1249 {\n+ 1250 if (build_mode!=random)\n+ 1251 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n+ 1252 if (ready==built)\n+ 1253 DUNE_THROW(BCRSMatrixError,\"matrix already built up\");\n+ 1254 if (ready==building)\n+ 1255 DUNE_THROW(BCRSMatrixError,\"row sizes are not built up yet\");\n+ 1256 if (ready==notAllocated)\n+ 1257 DUNE_THROW(BCRSMatrixError,\"matrix size not set and no memory allocated\n+yet\");\n+ 1258\n+ 1259 // check if there are undefined indices\n+ 1260 RowIterator endi=end();\n+ 1261 for (RowIterator i=begin(); i!=endi; ++i)\n+ 1262 {\n+ 1263 ColIterator endj = (*i).end();\n+ 1264 for (ColIterator j=(*i).begin(); j!=endj; ++j) {\n+ 1265 if (j.index() >= m) {\n+ 1266 dwarn << \"WARNING: size of row \"<< i.index()<<\" is \"<= n)\n+ 1309 DUNE_THROW(BCRSMatrixError,\"row index exceeds matrix size\");\n+ 1310 if (col >= m)\n+ 1311 DUNE_THROW(BCRSMatrixError,\"column index exceeds matrix size\");\n+ 1312#endif\n+ 1313\n+ 1314 size_type* begin = r[row].getindexptr();\n+ 1315 size_type* end = begin + r[row].getsize();\n+ 1316\n+ 1317 size_type* pos = std::find(begin, end, col);\n+ 1318\n+ 1319 //treat the case that there was a match in the array\n+ 1320 if (pos != end)\n+ 1321 if (*pos == col)\n+ 1322 {\n+ 1323 std::ptrdiff_t offset = pos - r[row].getindexptr();\n+ 1324 B* aptr = r[row].getptr() + offset;\n+ 1325\n+ 1326 return *aptr;\n+ 1327 }\n+ 1328\n+ 1329 //determine whether overflow has to be taken into account or not\n+ 1330 if (r[row].getsize() == avg)\n+ 1331 return overflow[std::make_pair(row,col)];\n+ 1332 else\n+ 1333 {\n+ 1334 //modify index array\n+ 1335 *end = col;\n+ 1336\n+ 1337 //do simultaneous operations on data array a\n+ 1338 std::ptrdiff_t offset = end - r[row].getindexptr();\n+ 1339 B* apos = r[row].getptr() + offset;\n+ 1340\n+ 1341 //increase rowsize\n+ 1342 r[row].setsize(r[row].getsize()+1);\n+ 1343\n+ 1344 //return reference to the newly created entry\n+ 1345 return *apos;\n+ 1346 }\n+ 1347 }\n+ 1348\n+ 1350\n+1360 CompressionStatistics compress()\n+ 1361 {\n+ 1362 if (build_mode!=implicit)\n+ 1363 DUNE_THROW(BCRSMatrixError,\"requires implicit build mode\");\n+ 1364 if (ready==built)\n+ 1365 DUNE_THROW(BCRSMatrixError,\"matrix already built up, no more need for\n+compression\");\n+ 1366 if (ready==notAllocated)\n+ 1367 DUNE_THROW(BCRSMatrixError,\"matrix size not set and no memory allocated\n+yet\");\n+ 1368 if (ready!=building)\n+ 1369 DUNE_THROW(InvalidStateException,\"You may only call compress() at the end\n+of the 'building' stage\");\n+ 1370\n+ 1371 //calculate statistics\n+ 1372 CompressionStatistics stats;\n+ 1373 stats.overflow_total = overflow.size();\n+ 1374 stats.maximum = 0;\n+ 1375\n+ 1376 //get insertion iterators pointing to one before start (for later use of\n+++it)\n+ 1377 size_type* jiit = j_.get();\n+ 1378 B* aiit = a;\n+ 1379\n+ 1380 //get iterator to the smallest overflow element\n+ 1381 typename OverflowType::iterator oit = overflow.begin();\n+ 1382\n+ 1383 //store a copy of index pointers on which to perform sorting\n+ 1384 std::vector perm;\n+ 1385\n+ 1386 //iterate over all rows and copy elements into their position in the\n+compressed array\n+ 1387 for (size_type i=0; i::iterator it = perm.begin();\n+ 1397 for (size_type* iit = begin; iit < begin + size; ++iit, ++it)\n+ 1398 *it = iit;\n+ 1399\n+ 1400 //sort permutation array\n+ 1401 std::sort(perm.begin(),perm.end(),PointerCompare());\n+ 1402\n+ 1403 //change row window pointer to their new positions\n+ 1404 r[i].setindexptr(jiit);\n+ 1405 r[i].setptr(aiit);\n+ 1406\n+ 1407 for (it = perm.begin(); it != perm.end(); ++it)\n+ 1408 {\n+ 1409 //check whether there are elements in the overflow area which take\n+precedence\n+ 1410 while ((oit!=overflow.end()) && (oit->first < std::make_pair(i,**it)))\n+ 1411 {\n+ 1412 //check whether there is enough memory to write to\n+ 1413 if (jiit > begin)\n+ 1414 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n+ 1415 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n+ 1416 \"Please increase either the average number of entries per row or the\n+compressionBufferSize value.\"\n+ 1417 );\n+ 1418 //copy an element from the overflow area to the insertion position in a\n+and j\n+ 1419 *jiit = oit->first.second;\n+ 1420 ++jiit;\n+ 1421 *aiit = oit->second;\n+ 1422 ++aiit;\n+ 1423 ++oit;\n+ 1424 r[i].setsize(r[i].getsize()+1);\n+ 1425 }\n+ 1426\n+ 1427 //check whether there is enough memory to write to\n+ 1428 if (jiit > begin)\n+ 1429 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n+ 1430 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n+ 1431 \"Please increase either the average number of entries per row or the\n+compressionBufferSize value.\"\n+ 1432 );\n+ 1433\n+ 1434 //copy element from array\n+ 1435 *jiit = **it;\n+ 1436 ++jiit;\n+ 1437 B* apos = *it - j_.get() + a;\n+ 1438 *aiit = *apos;\n+ 1439 ++aiit;\n+ 1440 }\n+ 1441\n+ 1442 //copy remaining elements from the overflow area\n+ 1443 while ((oit!=overflow.end()) && (oit->first.first == i))\n+ 1444 {\n+ 1445 //check whether there is enough memory to write to\n+ 1446 if (jiit > begin)\n+ 1447 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n+ 1448 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n+ 1449 \"Please increase either the average number of entries per row or the\n+compressionBufferSize value.\"\n+ 1450 );\n+ 1451\n+ 1452 //copy and element from the overflow area to the insertion position in a\n+and j\n+ 1453 *jiit = oit->first.second;\n+ 1454 ++jiit;\n+ 1455 *aiit = oit->second;\n+ 1456 ++aiit;\n+ 1457 ++oit;\n+ 1458 r[i].setsize(r[i].getsize()+1);\n+ 1459 }\n+ 1460\n+ 1461 // update maximum row size\n+ 1462 if (r[i].getsize()>stats.maximum)\n+ 1463 stats.maximum = r[i].getsize();\n+ 1464 }\n+ 1465\n+ 1466 // overflow area may be cleared\n+ 1467 overflow.clear();\n+ 1468\n+ 1469 //determine average number of entries and memory usage\n+ 1470 std::ptrdiff_t diff = (r[n-1].getindexptr() + r[n-1].getsize() - j_.get\n+());\n+ 1471 nnz_ = diff;\n+ 1472 stats.avg = (double) (nnz_) / (double) n;\n+ 1473 stats.mem_ratio = (double) (nnz_) / (double) allocationSize_;\n+ 1474\n+ 1475 //matrix is now built\n+ 1476 ready = built;\n+ 1477\n+ 1478 return stats;\n+ 1479 }\n+ 1480\n+ 1481 //===== vector space arithmetic\n+ 1482\n+1484 BCRSMatrix& operator*=(const field_type& k)\n+ 1485 {\n+ 1486#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1487 if (ready != built)\n+ 1488 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1489#endif\n+ 1490\n+ 1491 if (nnz_ > 0)\n+ 1492 {\n+ 1493 // process 1D array\n+ 1494 for (size_type i=0; i 0)\n+ 1520 {\n+ 1521 // process 1D array\n+ 1522 for (size_type i=0; ioperator+=(*j);\n+ 1557 }\n+ 1558\n+ 1559 return *this;\n+ 1560 }\n+ 1561\n+1567 BCRSMatrix& operator-=(const BCRSMatrix& b)\n+ 1568 {\n+ 1569#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1570 if (ready != built || b.ready != built)\n+ 1571 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1572 if(N()!=b.N() || M() != b.M())\n+ 1573 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n+ 1574#endif\n+ 1575 RowIterator endi=end();\n+ 1576 ConstRowIterator j=b.begin();\n+ 1577 for (RowIterator i=begin(); i!=endi; ++i, ++j) {\n+ 1578 i->operator-=(*j);\n+ 1579 }\n+ 1580\n+ 1581 return *this;\n+ 1582 }\n+ 1583\n+1592 BCRSMatrix& axpy(field_type alpha, const BCRSMatrix& b)\n+ 1593 {\n+ 1594#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1595 if (ready != built || b.ready != built)\n+ 1596 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1597 if(N()!=b.N() || M() != b.M())\n+ 1598 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n+ 1599#endif\n+ 1600 RowIterator endi=end();\n+ 1601 ConstRowIterator j=b.begin();\n+ 1602 for(RowIterator i=begin(); i!=endi; ++i, ++j)\n+ 1603 i->axpy(alpha, *j);\n+ 1604\n+ 1605 return *this;\n+ 1606 }\n+ 1607\n+ 1608 //===== linear maps\n+ 1609\n+ 1611 template\n+1612 void mv (const X& x, Y& y) const\n+ 1613 {\n+ 1614#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1615 if (ready != built)\n+ 1616 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1617 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\n+ 1618 \"Size mismatch: M: \" << N() << \"x\" << M() << \" x: \" << x.N());\n+ 1619 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\n+ 1620 \"Size mismatch: M: \" << N() << \"x\" << M() << \" y: \" << y.N());\n+ 1621#endif\n+ 1622 ConstRowIterator endi=end();\n+ 1623 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1624 {\n+ 1625 y[i.index()]=0;\n+ 1626 ConstColIterator endj = (*i).end();\n+ 1627 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1628 {\n+ 1629 auto&& xj = Impl::asVector(x[j.index()]);\n+ 1630 auto&& yi = Impl::asVector(y[i.index()]);\n+ 1631 Impl::asMatrix(*j).umv(xj, yi);\n+ 1632 }\n+ 1633 }\n+ 1634 }\n+ 1635\n+ 1637 template\n+1638 void umv (const X& x, Y& y) const\n+ 1639 {\n+ 1640#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1641 if (ready != built)\n+ 1642 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1643 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1644 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1645#endif\n+ 1646 ConstRowIterator endi=end();\n+ 1647 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1648 {\n+ 1649 ConstColIterator endj = (*i).end();\n+ 1650 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1651 {\n+ 1652 auto&& xj = Impl::asVector(x[j.index()]);\n+ 1653 auto&& yi = Impl::asVector(y[i.index()]);\n+ 1654 Impl::asMatrix(*j).umv(xj,yi);\n+ 1655 }\n+ 1656 }\n+ 1657 }\n+ 1658\n+ 1660 template\n+1661 void mmv (const X& x, Y& y) const\n+ 1662 {\n+ 1663#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1664 if (ready != built)\n+ 1665 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1666 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1667 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1668#endif\n+ 1669 ConstRowIterator endi=end();\n+ 1670 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1671 {\n+ 1672 ConstColIterator endj = (*i).end();\n+ 1673 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1674 {\n+ 1675 auto&& xj = Impl::asVector(x[j.index()]);\n+ 1676 auto&& yi = Impl::asVector(y[i.index()]);\n+ 1677 Impl::asMatrix(*j).mmv(xj,yi);\n+ 1678 }\n+ 1679 }\n+ 1680 }\n+ 1681\n+ 1683 template\n+1684 void usmv (F&& alpha, const X& x, Y& y) const\n+ 1685 {\n+ 1686#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1687 if (ready != built)\n+ 1688 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1689 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1690 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1691#endif\n+ 1692 ConstRowIterator endi=end();\n+ 1693 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1694 {\n+ 1695 ConstColIterator endj = (*i).end();\n+ 1696 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1697 {\n+ 1698 auto&& xj = Impl::asVector(x[j.index()]);\n+ 1699 auto&& yi = Impl::asVector(y[i.index()]);\n+ 1700 Impl::asMatrix(*j).usmv(alpha,xj,yi);\n+ 1701 }\n+ 1702 }\n+ 1703 }\n+ 1704\n+ 1706 template\n+1707 void mtv (const X& x, Y& y) const\n+ 1708 {\n+ 1709#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1710 if (ready != built)\n+ 1711 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1712 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1713 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1714#endif\n+ 1715 for(size_type i=0; i\n+1722 void umtv (const X& x, Y& y) const\n+ 1723 {\n+ 1724#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1725 if (ready != built)\n+ 1726 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1727 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1728 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1729#endif\n+ 1730 ConstRowIterator endi=end();\n+ 1731 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1732 {\n+ 1733 ConstColIterator endj = (*i).end();\n+ 1734 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1735 {\n+ 1736 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1737 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1738 Impl::asMatrix(*j).umtv(xi,yj);\n+ 1739 }\n+ 1740 }\n+ 1741 }\n+ 1742\n+ 1744 template\n+1745 void mmtv (const X& x, Y& y) const\n+ 1746 {\n+ 1747#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1748 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1749 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1750#endif\n+ 1751 ConstRowIterator endi=end();\n+ 1752 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1753 {\n+ 1754 ConstColIterator endj = (*i).end();\n+ 1755 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1756 {\n+ 1757 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1758 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1759 Impl::asMatrix(*j).mmtv(xi,yj);\n+ 1760 }\n+ 1761 }\n+ 1762 }\n+ 1763\n+ 1765 template\n+1766 void usmtv (const field_type& alpha, const X& x, Y& y) const\n+ 1767 {\n+ 1768#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1769 if (ready != built)\n+ 1770 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1771 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1772 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1773#endif\n+ 1774 ConstRowIterator endi=end();\n+ 1775 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1776 {\n+ 1777 ConstColIterator endj = (*i).end();\n+ 1778 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1779 {\n+ 1780 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1781 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1782 Impl::asMatrix(*j).usmtv(alpha,xi,yj);\n+ 1783 }\n+ 1784 }\n+ 1785 }\n+ 1786\n+ 1788 template\n+1789 void umhv (const X& x, Y& y) const\n+ 1790 {\n+ 1791#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1792 if (ready != built)\n+ 1793 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1794 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1795 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1796#endif\n+ 1797 ConstRowIterator endi=end();\n+ 1798 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1799 {\n+ 1800 ConstColIterator endj = (*i).end();\n+ 1801 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1802 {\n+ 1803 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1804 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1805 Impl::asMatrix(*j).umhv(xi,yj);\n+ 1806 }\n+ 1807 }\n+ 1808 }\n+ 1809\n+ 1811 template\n+1812 void mmhv (const X& x, Y& y) const\n+ 1813 {\n+ 1814#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1815 if (ready != built)\n+ 1816 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1817 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1818 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1819#endif\n+ 1820 ConstRowIterator endi=end();\n+ 1821 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1822 {\n+ 1823 ConstColIterator endj = (*i).end();\n+ 1824 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1825 {\n+ 1826 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1827 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1828 Impl::asMatrix(*j).mmhv(xi,yj);\n+ 1829 }\n+ 1830 }\n+ 1831 }\n+ 1832\n+ 1834 template\n+1835 void usmhv (const field_type& alpha, const X& x, Y& y) const\n+ 1836 {\n+ 1837#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1838 if (ready != built)\n+ 1839 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1840 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1841 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n+ 1842#endif\n+ 1843 ConstRowIterator endi=end();\n+ 1844 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n+ 1845 {\n+ 1846 ConstColIterator endj = (*i).end();\n+ 1847 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n+ 1848 {\n+ 1849 auto&& xi = Impl::asVector(x[i.index()]);\n+ 1850 auto&& yj = Impl::asVector(y[j.index()]);\n+ 1851 Impl::asMatrix(*j).usmhv(alpha,xi,yj);\n+ 1852 }\n+ 1853 }\n+ 1854 }\n+ 1855\n+ 1856\n+ 1857 //===== norms\n+ 1858\n+1860 typename FieldTraits::real_type frobenius_norm2 () const\n+ 1861 {\n+ 1862#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1863 if (ready != built)\n+ 1864 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1865#endif\n+ 1866\n+ 1867 typename FieldTraits::real_type sum=0;\n+ 1868\n+ 1869 for (auto&& row : (*this))\n+ 1870 for (auto&& entry : row)\n+ 1871 sum += Impl::asMatrix(entry).frobenius_norm2();\n+ 1872\n+ 1873 return sum;\n+ 1874 }\n+ 1875\n+1877 typename FieldTraits::real_type frobenius_norm () const\n+ 1878 {\n+ 1879 return sqrt(frobenius_norm2());\n+ 1880 }\n+ 1881\n+ 1883 template ::value, int>::type = 0>\n+1885 typename FieldTraits::real_type infinity_norm() const {\n+ 1886 if (ready != built)\n+ 1887 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1888\n+ 1889 using real_type = typename FieldTraits::real_type;\n+ 1890 using std::max;\n+ 1891\n+ 1892 real_type norm = 0;\n+ 1893 for (auto const &x : *this) {\n+ 1894 real_type sum = 0;\n+ 1895 for (auto const &y : x)\n+ 1896 sum += Impl::asMatrix(y).infinity_norm();\n+ 1897 norm = max(sum, norm);\n+ 1898 }\n+ 1899 return norm;\n+ 1900 }\n+ 1901\n+ 1903 template ::value, int>::type = 0>\n+1905 typename FieldTraits::real_type infinity_norm_real() const {\n+ 1906 if (ready != built)\n+ 1907 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1908\n+ 1909 using real_type = typename FieldTraits::real_type;\n+ 1910 using std::max;\n+ 1911\n+ 1912 real_type norm = 0;\n+ 1913 for (auto const &x : *this) {\n+ 1914 real_type sum = 0;\n+ 1915 for (auto const &y : x)\n+ 1916 sum += Impl::asMatrix(y).infinity_norm_real();\n+ 1917 norm = max(sum, norm);\n+ 1918 }\n+ 1919 return norm;\n+ 1920 }\n+ 1921\n+ 1923 template ::value, int>::type = 0>\n+1925 typename FieldTraits::real_type infinity_norm() const {\n+ 1926 if (ready != built)\n+ 1927 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1928\n+ 1929 using real_type = typename FieldTraits::real_type;\n+ 1930 using std::max;\n+ 1931\n+ 1932 real_type norm = 0;\n+ 1933 real_type isNaN = 1;\n+ 1934 for (auto const &x : *this) {\n+ 1935 real_type sum = 0;\n+ 1936 for (auto const &y : x)\n+ 1937 sum += Impl::asMatrix(y).infinity_norm();\n+ 1938 norm = max(sum, norm);\n+ 1939 isNaN += sum;\n+ 1940 }\n+ 1941\n+ 1942 return norm * (isNaN / isNaN);\n+ 1943 }\n+ 1944\n+ 1946 template ::value, int>::type = 0>\n+1948 typename FieldTraits::real_type infinity_norm_real() const {\n+ 1949 if (ready != built)\n+ 1950 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n+fully built BCRSMatrix instances\");\n+ 1951\n+ 1952 using real_type = typename FieldTraits::real_type;\n+ 1953 using std::max;\n+ 1954\n+ 1955 real_type norm = 0;\n+ 1956 real_type isNaN = 1;\n+ 1957\n+ 1958 for (auto const &x : *this) {\n+ 1959 real_type sum = 0;\n+ 1960 for (auto const &y : x)\n+ 1961 sum += Impl::asMatrix(y).infinity_norm_real();\n+ 1962 norm = max(sum, norm);\n+ 1963 isNaN += sum;\n+ 1964 }\n+ 1965\n+ 1966 return norm * (isNaN / isNaN);\n+ 1967 }\n+ 1968\n+ 1969 //===== sizes\n+ 1970\n+1972 size_type N () const\n+ 1973 {\n+ 1974 return n;\n+ 1975 }\n+ 1976\n+1978 size_type M () const\n+ 1979 {\n+ 1980 return m;\n+ 1981 }\n+ 1982\n+1984 size_type nonzeroes () const\n+ 1985 {\n+ 1986 // in case of row-wise allocation\n+ 1987 if( nnz_ <= 0 )\n+ 1988 nnz_ = std::accumulate( begin(), end(), size_type( 0 ), [] ( size_type s,\n+const row_type &row ) { return s+row.getsize(); } );\n+ 1989 return nnz_;\n+ 1990 }\n+ 1991\n+1993 BuildStage buildStage() const\n+ 1994 {\n+ 1995 return ready;\n+ 1996 }\n+ 1997\n+1999 BuildMode buildMode() const\n+ 2000 {\n+ 2001 return build_mode;\n+ 2002 }\n+ 2003\n+ 2004 //===== query\n+ 2005\n+2007 bool exists (size_type i, size_type j) const\n+ 2008 {\n+ 2009#ifdef DUNE_ISTL_WITH_CHECKING\n+ 2010 if (i<0 || i>=n) DUNE_THROW(BCRSMatrixError,\"row index out of range\");\n+ 2011 if (j<0 || j>=m) DUNE_THROW(BCRSMatrixError,\"column index out of range\");\n+ 2012#endif\n+ 2013 return (r[i].size() && r[i].find(j) != r[i].end());\n+ 2014 }\n+ 2015\n+ 2016\n+ 2017 protected:\n+ 2018 // state information\n+2019 BuildMode build_mode; // row wise or whole matrix\n+2020 BuildStage ready; // indicate the stage the matrix building is in\n+ 2021\n+ 2022 // The allocator used for memory management\n+2023 typename std::allocator_traits::template rebind_alloc allocator_;\n+ 2024\n+2025 typename std::allocator_traits::template rebind_alloc\n+rowAllocator_;\n+ 2026\n+2027 typename std::allocator_traits::template rebind_alloc\n+sizeAllocator_;\n+ 2028\n+ 2029 // size of the matrix\n+2030 size_type n; // number of rows\n+2031 size_type m; // number of columns\n+2032 mutable size_type nnz_; // number of nonzeroes contained in the matrix\n+2033 size_type allocationSize_; //allocated size of a and j arrays, except in\n+implicit mode: nnz_==allocationsSize_\n+ 2034 // zero means that memory is allocated separately for each row.\n+ 2035\n+ 2036 // the rows are dynamically allocated\n+2037 row_type* r; // [n] the individual rows having pointers into a,j arrays\n+ 2038\n+ 2039 // dynamically allocated memory\n+2040 B* a; // [allocationSize] non-zero entries of the matrix in row-wise\n+ordering\n+ 2041 // If a single array of column indices is used, it can be shared\n+ 2042 // between different matrices with the same sparsity pattern\n+2043 std::shared_ptr j_; // [allocationSize] column indices of\n+entries\n+ 2044\n+ 2045 // additional data is needed in implicit buildmode\n+2046 size_type avg;\n+2047 double compressionBufferSize_;\n+ 2048\n+2049 typedef std::map, B> OverflowType;\n+2050 OverflowType overflow;\n+ 2051\n+2052 void setWindowPointers(ConstRowIterator row)\n+ 2053 {\n+ 2054 row_type current_row(a,j_.get(),0); // Pointers to current row data\n+ 2055 for (size_type i=0; igetsize();\n+ 2058\n+ 2059 if (s>0) {\n+ 2060 // setup pointers and size\n+ 2061 r[i].set(s,current_row.getptr(), current_row.getindexptr());\n+ 2062 // update pointer for next row\n+ 2063 current_row.setptr(current_row.getptr()+s);\n+ 2064 current_row.setindexptr(current_row.getindexptr()+s);\n+ 2065 } else{\n+ 2066 // empty row\n+ 2067 r[i].set(0,nullptr,nullptr);\n+ 2068 }\n+ 2069 }\n+ 2070 }\n+ 2071\n+ 2073\n+2077 void setColumnPointers(ConstRowIterator row)\n+ 2078 {\n+ 2079 size_type* jptr = j_.get();\n+ 2080 for (size_type i=0; igetsize();\n+ 2083\n+ 2084 if (s>0) {\n+ 2085 // setup pointers and size\n+ 2086 r[i].setsize(s);\n+ 2087 r[i].setindexptr(jptr);\n+ 2088 } else{\n+ 2089 // empty row\n+ 2090 r[i].set(0,nullptr,nullptr);\n+ 2091 }\n+ 2092\n+ 2093 // advance position in global array\n+ 2094 jptr += s;\n+ 2095 }\n+ 2096 }\n+ 2097\n+ 2099\n+2103 void setDataPointers()\n+ 2104 {\n+ 2105 B* aptr = a;\n+ 2106 for (size_type i=0; i 0) {\n+ 2109 // setup pointers and size\n+ 2110 r[i].setptr(aptr);\n+ 2111 } else{\n+ 2112 // empty row\n+ 2113 r[i].set(0,nullptr,nullptr);\n+ 2114 }\n+ 2115\n+ 2116 // advance position in global array\n+ 2117 aptr += r[i].getsize();\n+ 2118 }\n+ 2119 }\n+ 2120\n+2122 void copyWindowStructure(const BCRSMatrix& Mat)\n+ 2123 {\n+ 2124 setWindowPointers(Mat.begin());\n+ 2125\n+ 2126 // copy data\n+ 2127 for (size_type i=0; i0)\n+ 2146 {\n+ 2147 // a,j_ have been allocated as one long vector\n+ 2148 j_.reset();\n+ 2149 if (a)\n+ 2150 {\n+ 2151 for(B *aiter=a+(allocationSize_-1), *aend=a-1; aiter!=aend; --aiter)\n+ 2152 std::allocator_traits::destroy(allocator_, aiter);\n+ 2153 allocator_.deallocate(a,allocationSize_);\n+ 2154 a = nullptr;\n+ 2155 }\n+ 2156 }\n+ 2157 else if (r)\n+ 2158 {\n+ 2159 // check if memory for rows have been allocated individually\n+ 2160 for (size_type i=0; i0)\n+ 2162 {\n+ 2163 for (B *col=r[i].getptr()+(r[i].getsize()-1),\n+ 2164 *colend = r[i].getptr()-1; col!=colend; --col) {\n+ 2165 std::allocator_traits::destroy(allocator_, col);\n+ 2166 }\n+ 2167 sizeAllocator_.deallocate(r[i].getindexptr(),1);\n+ 2168 allocator_.deallocate(r[i].getptr(),1);\n+ 2169 // clear out row data in case we don't want to deallocate the rows\n+ 2170 // otherwise we might run into a double free problem here later\n+ 2171 r[i].set(0,nullptr,nullptr);\n+ 2172 }\n+ 2173 }\n+ 2174\n+ 2175 // deallocate the rows\n+ 2176 if (n>0 && deallocateRows && r) {\n+ 2177 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)\n+ 2178 std::allocator_traits::destroy(rowAllocator_,\n+riter);\n+ 2179 rowAllocator_.deallocate(r,n);\n+ 2180 r = nullptr;\n+ 2181 }\n+ 2182\n+ 2183 // Mark matrix as not built at all.\n+ 2184 ready=notAllocated;\n+ 2185\n+ 2186 }\n+ 2187\n+2205 void allocate(size_type rows, size_type columns, size_type allocationSize,\n+bool allocateRows, bool allocate_data)\n+ 2206 {\n+ 2207 // Store size\n+ 2208 n = rows;\n+ 2209 m = columns;\n+ 2210 nnz_ = allocationSize;\n+ 2211 allocationSize_ = allocationSize;\n+ 2212\n+ 2213 // allocate rows\n+ 2214 if(allocateRows) {\n+ 2215 if (n>0) {\n+ 2216 if (r)\n+ 2217 DUNE_THROW(InvalidStateException,\"Rows have already been allocated,\n+cannot allocate a second time\");\n+ 2218 r = rowAllocator_.allocate(rows);\n+ 2219 // initialize row entries\n+ 2220 for(row_type* ri=r; ri!=r+rows; ++ri)\n+ 2221 std::allocator_traits::construct(rowAllocator_,\n+ri, row_type());\n+ 2222 }else{\n+ 2223 r = 0;\n+ 2224 }\n+ 2225 }\n+ 2226\n+ 2227 // allocate a and j_ array\n+ 2228 if (allocate_data)\n+ 2229 allocateData();\n+ 2230 // allocate column indices only if not yet present (enable sharing)\n+ 2231 if (allocationSize_>0) {\n+ 2232 // we copy allocator and size to the deleter since _j may outlive this\n+class\n+ 2233 if (!j_.get())\n+ 2234 j_.reset(sizeAllocator_.allocate(allocationSize_),\n+ 2235 [alloc = sizeAllocator_, size = allocationSize_](auto ptr) mutable {\n+ 2236 alloc.deallocate(ptr, size);\n+ 2237 });\n+ 2238 }else{\n+ 2239 j_.reset();\n+ 2240 }\n+ 2241\n+ 2242 // Mark the matrix as not built.\n+ 2243 ready = building;\n+ 2244 }\n+ 2245\n+2246 void allocateData()\n+ 2247 {\n+ 2248 if (a)\n+ 2249 DUNE_THROW(InvalidStateException,\"Cannot allocate data array (already\n+allocated)\");\n+ 2250 if (allocationSize_>0) {\n+ 2251 a = allocator_.allocate(allocationSize_);\n+ 2252 // use placement new to call constructor that allocates\n+ 2253 // additional memory.\n+ 2254 new (a) B[allocationSize_];\n+ 2255 } else {\n+ 2256 a = nullptr;\n+ 2257 }\n+ 2258 }\n+ 2259\n+2265 void implicit_allocate(size_type _n, size_type _m)\n+ 2266 {\n+ 2267 if (build_mode != implicit)\n+ 2268 DUNE_THROW(InvalidStateException,\"implicit_allocate() may only be called\n+in implicit build mode\");\n+ 2269 if (ready != notAllocated)\n+ 2270 DUNE_THROW(InvalidStateException,\"memory has already been allocated\");\n+ 2271\n+ 2272 // check to make sure the user has actually set the parameters\n+ 2273 if (compressionBufferSize_ < 0)\n+ 2274 DUNE_THROW(InvalidStateException,\"You have to set the implicit build mode\n+parameters before starting to build the matrix\");\n+ 2275 //calculate size of overflow region, add buffer for row sort!\n+ 2276 size_type osize = (size_type) (_n*avg)*compressionBufferSize_ + 4*avg;\n+ 2277 allocationSize_ = _n*avg + osize;\n+ 2278\n+ 2279 allocate(_n, _m, allocationSize_,true,true);\n+ 2280\n+ 2281 //set row pointers correctly\n+ 2282 size_type* jptr = j_.get() + osize;\n+ 2283 B* aptr = a + osize;\n+ 2284 for (size_type i=0; i\n+2297 struct FieldTraits< BCRSMatrix >\n+ 2298 {\n+2299 using field_type = typename BCRSMatrix::field_type;\n+2300 using real_type = typename FieldTraits::real_type;\n+ 2301 };\n+ 2302\n+ 2305} // end namespace\n+ 2306\n+ 2307#endif\n+matrixutils.hh\n+Some handy generic functions for ISTL matrices.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+istlexception.hh\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n Dune\n Definition: allocator.hh:11\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::Preconditioner::post\n-virtual void post(X &x)=0\n-Clean up.\n-Dune::Preconditioner::apply\n-virtual void apply(X &v, const Y &d)=0\n-Apply one step of the preconditioner to the system A(v)=d.\n-Dune::Preconditioner::~Preconditioner\n-virtual ~Preconditioner()\n-every abstract base class has a virtual destructor\n-Definition: preconditioner.hh:104\n-Dune::Preconditioner::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioner.hh:37\n-Dune::Preconditioner::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioner.hh:35\n-Dune::Preconditioner::category\n-virtual SolverCategory::Category category() const =0\n-Category of the preconditioner (see SolverCategory::Category)\n-Dune::Preconditioner::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioner.hh:39\n-Dune::Preconditioner::pre\n-virtual void pre(X &x, Y &b)=0\n-Prepare the preconditioner.\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::MatrixDimension\n+Definition: matrixutils.hh:211\n+Dune::CompressionStatistics\n+Statistics about compression achieved in implicit mode.\n+Definition: bcrsmatrix.hh:88\n+Dune::CompressionStatistics::overflow_total\n+size_type overflow_total\n+total number of elements written to the overflow area during construction.\n+Definition: bcrsmatrix.hh:94\n+Dune::CompressionStatistics::maximum\n+size_type maximum\n+maximum number of non-zeroes per row.\n+Definition: bcrsmatrix.hh:92\n+Dune::CompressionStatistics::avg\n+double avg\n+average number of non-zeroes per row.\n+Definition: bcrsmatrix.hh:90\n+Dune::CompressionStatistics::mem_ratio\n+double mem_ratio\n+fraction of wasted memory resulting from non-used overflow area.\n+Definition: bcrsmatrix.hh:99\n+Dune::ImplicitMatrixBuilder\n+A wrapper for uniform access to the BCRSMatrix during and after the build stage\n+in implicit build mod...\n+Definition: bcrsmatrix.hh:117\n+Dune::ImplicitMatrixBuilder::block_type\n+Matrix::block_type block_type\n+The block_type of the underlying matrix.\n+Definition: bcrsmatrix.hh:125\n+Dune::ImplicitMatrixBuilder::ImplicitMatrixBuilder\n+ImplicitMatrixBuilder(Matrix &m)\n+Creates an ImplicitMatrixBuilder for matrix m.\n+Definition: bcrsmatrix.hh:170\n+Dune::ImplicitMatrixBuilder::Matrix\n+M_ Matrix\n+The underlying matrix.\n+Definition: bcrsmatrix.hh:122\n+Dune::ImplicitMatrixBuilder::ImplicitMatrixBuilder\n+ImplicitMatrixBuilder(Matrix &m, size_type rows, size_type cols, size_type\n+avg_cols_per_row, double overflow_fraction)\n+Sets up matrix m for implicit construction using the given parameters and\n+creates an ImplicitBmatrixu...\n+Definition: bcrsmatrix.hh:194\n+Dune::ImplicitMatrixBuilder::M\n+size_type M() const\n+The number of columns in the matrix.\n+Definition: bcrsmatrix.hh:217\n+Dune::ImplicitMatrixBuilder::size_type\n+Matrix::size_type size_type\n+The size_type of the underlying matrix.\n+Definition: bcrsmatrix.hh:128\n+Dune::ImplicitMatrixBuilder::operator[]\n+row_object operator[](size_type i) const\n+Returns a proxy for entries in row i.\n+Definition: bcrsmatrix.hh:205\n+Dune::ImplicitMatrixBuilder::N\n+size_type N() const\n+The number of rows in the matrix.\n+Definition: bcrsmatrix.hh:211\n+Dune::ImplicitMatrixBuilder::row_object\n+Proxy row object for entry access.\n+Definition: bcrsmatrix.hh:137\n+Dune::ImplicitMatrixBuilder::row_object::operator[]\n+block_type & operator[](size_type j) const\n+Returns entry in column j.\n+Definition: bcrsmatrix.hh:142\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: bcrsmatrix.hh:488\n+Dune::BCRSMatrix::rowAllocator_\n+std::allocator_traits< A >::template rebind_alloc< row_type > rowAllocator_\n+Definition: bcrsmatrix.hh:2025\n+Dune::BCRSMatrix::exists\n+bool exists(size_type i, size_type j) const\n+return true if (i,j) is in pattern\n+Definition: bcrsmatrix.hh:2007\n+Dune::BCRSMatrix::buildStage\n+BuildStage buildStage() const\n+The current build stage of the matrix.\n+Definition: bcrsmatrix.hh:1993\n+Dune::BCRSMatrix::begin\n+Iterator begin()\n+Get iterator to first row.\n+Definition: bcrsmatrix.hh:675\n+Dune::BCRSMatrix::CreateIterator\n+friend class CreateIterator\n+allow CreateIterator to access internal data\n+Definition: bcrsmatrix.hh:1094\n+Dune::BCRSMatrix::copyWindowStructure\n+void copyWindowStructure(const BCRSMatrix &Mat)\n+Copy the window structure from another matrix.\n+Definition: bcrsmatrix.hh:2122\n+Dune::BCRSMatrix::entry\n+B & entry(size_type row, size_type col)\n+Returns reference to entry (row,col) of the matrix.\n+Definition: bcrsmatrix.hh:1296\n+Dune::BCRSMatrix::mmhv\n+void mmhv(const X &x, Y &y) const\n+y -= A^H x\n+Definition: bcrsmatrix.hh:1812\n+Dune::BCRSMatrix::usmhv\n+void usmhv(const field_type &alpha, const X &x, Y &y) const\n+y += alpha A^H x\n+Definition: bcrsmatrix.hh:1835\n+Dune::BCRSMatrix::umtv\n+void umtv(const X &x, Y &y) const\n+y += A^T x\n+Definition: bcrsmatrix.hh:1722\n+Dune::BCRSMatrix::compressionBufferSize_\n+double compressionBufferSize_\n+Definition: bcrsmatrix.hh:2047\n+Dune::BCRSMatrix::m\n+size_type m\n+Definition: bcrsmatrix.hh:2031\n+Dune::BCRSMatrix::const_iterator\n+RealRowIterator< const row_type > const_iterator\n+The const iterator over the matrix rows.\n+Definition: bcrsmatrix.hh:707\n+Dune::BCRSMatrix::blocklevel\n+static constexpr unsigned int blocklevel\n+increment block level counter\n+Definition: bcrsmatrix.hh:507\n+Dune::BCRSMatrix::allocate\n+void allocate(size_type rows, size_type columns, size_type allocationSize, bool\n+allocateRows, bool allocate_data)\n+Allocate memory for the matrix structure.\n+Definition: bcrsmatrix.hh:2205\n+Dune::BCRSMatrix::axpy\n+BCRSMatrix & axpy(field_type alpha, const BCRSMatrix &b)\n+Add the scaled entries of another matrix to this one.\n+Definition: bcrsmatrix.hh:1592\n+Dune::BCRSMatrix::infinity_norm_real\n+FieldTraits< ft >::real_type infinity_norm_real() const\n+simplified infinity norm (uses Manhattan norm for complex values)\n+Definition: bcrsmatrix.hh:1905\n+Dune::BCRSMatrix::~BCRSMatrix\n+~BCRSMatrix()\n+destructor\n+Definition: bcrsmatrix.hh:824\n+Dune::BCRSMatrix::allocateData\n+void allocateData()\n+Definition: bcrsmatrix.hh:2246\n+Dune::BCRSMatrix::deallocate\n+void deallocate(bool deallocateRows=true)\n+deallocate memory of the matrix.\n+Definition: bcrsmatrix.hh:2139\n+Dune::BCRSMatrix::RowIterator\n+Iterator RowIterator\n+rename the iterators for easier access\n+Definition: bcrsmatrix.hh:701\n+Dune::BCRSMatrix::operator[]\n+row_type & operator[](size_type i)\n+random access to the rows\n+Definition: bcrsmatrix.hh:549\n+Dune::BCRSMatrix::BCRSMatrix\n+BCRSMatrix()\n+an empty matrix\n+Definition: bcrsmatrix.hh:749\n+Dune::BCRSMatrix::endrowsizes\n+void endrowsizes()\n+indicate that size of all rows is defined\n+Definition: bcrsmatrix.hh:1149\n+Dune::BCRSMatrix::incrementrowsize\n+void incrementrowsize(size_type i, size_type s=1)\n+increment size of row i by s (1 by default)\n+Definition: bcrsmatrix.hh:1138\n+Dune::BCRSMatrix::mtv\n+void mtv(const X &x, Y &y) const\n+y = A^T x\n+Definition: bcrsmatrix.hh:1707\n+Dune::BCRSMatrix::umhv\n+void umhv(const X &x, Y &y) const\n+y += A^H x\n+Definition: bcrsmatrix.hh:1789\n+Dune::BCRSMatrix::nonzeroes\n+size_type nonzeroes() const\n+number of blocks that are stored (the number of blocks that possibly are\n+nonzero)\n+Definition: bcrsmatrix.hh:1984\n+Dune::BCRSMatrix::allocationSize_\n+size_type allocationSize_\n+Definition: bcrsmatrix.hh:2033\n+Dune::BCRSMatrix::ConstRowIterator\n+ConstIterator ConstRowIterator\n+rename the const row iterator for easier access\n+Definition: bcrsmatrix.hh:738\n+Dune::BCRSMatrix::ready\n+BuildStage ready\n+Definition: bcrsmatrix.hh:2020\n+Dune::BCRSMatrix::build_mode\n+BuildMode build_mode\n+Definition: bcrsmatrix.hh:2019\n+Dune::BCRSMatrix::setrowsize\n+void setrowsize(size_type i, size_type s)\n+Set number of indices in row i to s.\n+Definition: bcrsmatrix.hh:1117\n+Dune::BCRSMatrix::Iterator\n+RealRowIterator< row_type > Iterator\n+Definition: bcrsmatrix.hh:672\n+Dune::BCRSMatrix::nnz_\n+size_type nnz_\n+Definition: bcrsmatrix.hh:2032\n+Dune::BCRSMatrix::operator*=\n+BCRSMatrix & operator*=(const field_type &k)\n+vector space multiplication with scalar\n+Definition: bcrsmatrix.hh:1484\n+Dune::BCRSMatrix::sizeAllocator_\n+std::allocator_traits< A >::template rebind_alloc< size_type > sizeAllocator_\n+Definition: bcrsmatrix.hh:2027\n+Dune::BCRSMatrix::iterator\n+RealRowIterator< row_type > iterator\n+The iterator over the (mutable matrix rows.\n+Definition: bcrsmatrix.hh:671\n+Dune::BCRSMatrix::usmtv\n+void usmtv(const field_type &alpha, const X &x, Y &y) const\n+y += alpha A^T x\n+Definition: bcrsmatrix.hh:1766\n+Dune::BCRSMatrix::beforeBegin\n+ConstIterator beforeBegin() const\n+Definition: bcrsmatrix.hh:732\n+Dune::BCRSMatrix::ConstIterator\n+RealRowIterator< const row_type > ConstIterator\n+Definition: bcrsmatrix.hh:708\n+Dune::BCRSMatrix::beforeBegin\n+Iterator beforeBegin()\n+Definition: bcrsmatrix.hh:695\n+Dune::BCRSMatrix::a\n+B * a\n+Definition: bcrsmatrix.hh:2040\n+Dune::BCRSMatrix::BuildMode\n+BuildMode\n+we support two modes\n+Definition: bcrsmatrix.hh:510\n+Dune::BCRSMatrix::implicit\n+@ implicit\n+Build entries randomly with an educated guess for the number of entries per\n+row.\n+Definition: bcrsmatrix.hh:539\n+Dune::BCRSMatrix::unknown\n+@ unknown\n+Build mode not set!\n+Definition: bcrsmatrix.hh:543\n+Dune::BCRSMatrix::random\n+@ random\n+Build entries randomly.\n+Definition: bcrsmatrix.hh:530\n+Dune::BCRSMatrix::row_wise\n+@ row_wise\n+Build in a row-wise manner.\n+Definition: bcrsmatrix.hh:521\n+Dune::BCRSMatrix::BCRSMatrix\n+BCRSMatrix(size_type _n, size_type _m, size_type _nnz, BuildMode bm)\n+matrix with known number of nonzeroes\n+Definition: bcrsmatrix.hh:756\n+Dune::BCRSMatrix::CompressionStatistics\n+::Dune::CompressionStatistics< size_type > CompressionStatistics\n+The type for the statistics object returned by compress()\n+Definition: bcrsmatrix.hh:503\n+Dune::BCRSMatrix::operator-=\n+BCRSMatrix & operator-=(const BCRSMatrix &b)\n+Subtract the entries of another matrix from this one.\n+Definition: bcrsmatrix.hh:1567\n+Dune::BCRSMatrix::BCRSMatrix\n+BCRSMatrix(const BCRSMatrix &Mat)\n+copy constructor\n+Definition: bcrsmatrix.hh:805\n+Dune::BCRSMatrix::end\n+Iterator end()\n+Get iterator to one beyond last row.\n+Definition: bcrsmatrix.hh:681\n+Dune::BCRSMatrix::r\n+row_type * r\n+Definition: bcrsmatrix.hh:2037\n+Dune::BCRSMatrix::setIndices\n+void setIndices(size_type row, It begin, It end)\n+Set all column indices for row from the given iterator range.\n+Definition: bcrsmatrix.hh:1234\n+Dune::BCRSMatrix::addindex\n+void addindex(size_type row, size_type col)\n+add index (row,col) to the matrix\n+Definition: bcrsmatrix.hh:1191\n+Dune::BCRSMatrix::OverflowType\n+std::map< std::pair< size_type, size_type >, B > OverflowType\n+Definition: bcrsmatrix.hh:2049\n+Dune::BCRSMatrix::ColIterator\n+row_type::Iterator ColIterator\n+Iterator for the entries of each row.\n+Definition: bcrsmatrix.hh:704\n+Dune::BCRSMatrix::frobenius_norm\n+FieldTraits< field_type >::real_type frobenius_norm() const\n+frobenius norm: sqrt(sum over squared values of entries)\n+Definition: bcrsmatrix.hh:1877\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::operator/=\n+BCRSMatrix & operator/=(const field_type &k)\n+vector space division by scalar\n+Definition: bcrsmatrix.hh:1512\n+Dune::BCRSMatrix::overflow\n+OverflowType overflow\n+Definition: bcrsmatrix.hh:2050\n+Dune::BCRSMatrix::operator+=\n+BCRSMatrix & operator+=(const BCRSMatrix &b)\n+Add the entries of another matrix to this one.\n+Definition: bcrsmatrix.hh:1545\n+Dune::BCRSMatrix::BCRSMatrix\n+BCRSMatrix(size_type _n, size_type _m, size_type _avg, double\n+compressionBufferSize, BuildMode bm)\n+construct matrix with a known average number of entries per row\n+Definition: bcrsmatrix.hh:784\n+Dune::BCRSMatrix::createend\n+CreateIterator createend()\n+get create iterator pointing to one after the last block\n+Definition: bcrsmatrix.hh:1103\n+Dune::BCRSMatrix::frobenius_norm2\n+FieldTraits< field_type >::real_type frobenius_norm2() const\n+square of frobenius norm, need for block recursion\n+Definition: bcrsmatrix.hh:1860\n+Dune::BCRSMatrix::beforeEnd\n+Iterator beforeEnd()\n+Definition: bcrsmatrix.hh:688\n+Dune::BCRSMatrix::ConstColIterator\n+row_type::ConstIterator ConstColIterator\n+Const iterator to the entries of a row.\n+Definition: bcrsmatrix.hh:741\n+Dune::BCRSMatrix::usmv\n+void usmv(F &&alpha, const X &x, Y &y) const\n+y += alpha A x\n+Definition: bcrsmatrix.hh:1684\n+Dune::BCRSMatrix::getrowsize\n+size_type getrowsize(size_type i) const\n+get current number of indices in row i\n+Definition: bcrsmatrix.hh:1128\n+Dune::BCRSMatrix::M\n+size_type M() const\n+number of columns (counted in blocks)\n+Definition: bcrsmatrix.hh:1978\n+Dune::BCRSMatrix::n\n+size_type n\n+Definition: bcrsmatrix.hh:2030\n+Dune::BCRSMatrix::row_type\n+Imp::CompressedBlockVectorWindow< B, A > row_type\n+implement row_type with compressed vector\n+Definition: bcrsmatrix.hh:497\n+Dune::BCRSMatrix::createbegin\n+CreateIterator createbegin()\n+get initial create iterator\n+Definition: bcrsmatrix.hh:1097\n+Dune::BCRSMatrix::BuildStage\n+BuildStage\n+Definition: bcrsmatrix.hh:469\n+Dune::BCRSMatrix::rowSizesBuilt\n+@ rowSizesBuilt\n+The row sizes of the matrix are known.\n+Definition: bcrsmatrix.hh:480\n+Dune::BCRSMatrix::built\n+@ built\n+The matrix structure is fully built.\n+Definition: bcrsmatrix.hh:482\n+Dune::BCRSMatrix::notbuilt\n+@ notbuilt\n+Matrix is not built at all, no memory has been allocated, build mode and size\n+can still be set.\n+Definition: bcrsmatrix.hh:471\n+Dune::BCRSMatrix::notAllocated\n+@ notAllocated\n+Matrix is not built at all, no memory has been allocated, build mode and size\n+can still be set.\n+Definition: bcrsmatrix.hh:473\n+Dune::BCRSMatrix::building\n+@ building\n+Matrix is currently being built, some memory has been allocated, build mode and\n+size are fixed.\n+Definition: bcrsmatrix.hh:475\n+Dune::BCRSMatrix::buildMode\n+BuildMode buildMode() const\n+The currently selected build mode of the matrix.\n+Definition: bcrsmatrix.hh:1999\n+Dune::BCRSMatrix::mmv\n+void mmv(const X &x, Y &y) const\n+y -= A x\n+Definition: bcrsmatrix.hh:1661\n+Dune::BCRSMatrix::infinity_norm\n+FieldTraits< ft >::real_type infinity_norm() const\n+infinity norm (row sum norm, how to generalize for blocks?)\n+Definition: bcrsmatrix.hh:1885\n+Dune::BCRSMatrix::mv\n+void mv(const X &x, Y &y) const\n+y = A x\n+Definition: bcrsmatrix.hh:1612\n+Dune::BCRSMatrix::block_type\n+B block_type\n+export the type representing the components\n+Definition: bcrsmatrix.hh:491\n+Dune::BCRSMatrix::mmtv\n+void mmtv(const X &x, Y &y) const\n+y -= A^T x\n+Definition: bcrsmatrix.hh:1745\n+Dune::BCRSMatrix::avg\n+size_type avg\n+Definition: bcrsmatrix.hh:2046\n+Dune::BCRSMatrix::umv\n+void umv(const X &x, Y &y) const\n+y += A x\n+Definition: bcrsmatrix.hh:1638\n+Dune::BCRSMatrix::implicit_allocate\n+void implicit_allocate(size_type _n, size_type _m)\n+organizes allocation implicit mode calculates correct array size to be\n+allocated and sets the the win...\n+Definition: bcrsmatrix.hh:2265\n+Dune::BCRSMatrix::setImplicitBuildModeParameters\n+void setImplicitBuildModeParameters(size_type _avg, double\n+compressionBufferSize)\n+Set parameters needed for creation in implicit build mode.\n+Definition: bcrsmatrix.hh:889\n+Dune::BCRSMatrix::BCRSMatrix\n+BCRSMatrix(size_type _n, size_type _m, BuildMode bm)\n+matrix with unknown number of nonzeroes\n+Definition: bcrsmatrix.hh:765\n+Dune::BCRSMatrix::endindices\n+void endindices()\n+indicate that all indices are defined, check consistency\n+Definition: bcrsmatrix.hh:1248\n+Dune::BCRSMatrix::compress\n+CompressionStatistics compress()\n+Finishes the buildstage in implicit mode.\n+Definition: bcrsmatrix.hh:1360\n+Dune::BCRSMatrix::setDataPointers\n+void setDataPointers()\n+Set data pointers for all rows.\n+Definition: bcrsmatrix.hh:2103\n+Dune::BCRSMatrix::allocator_\n+std::allocator_traits< A >::template rebind_alloc< B > allocator_\n+Definition: bcrsmatrix.hh:2023\n+Dune::BCRSMatrix::N\n+size_type N() const\n+number of rows (counted in blocks)\n+Definition: bcrsmatrix.hh:1972\n+Dune::BCRSMatrix::setBuildMode\n+void setBuildMode(BuildMode bm)\n+Sets the build mode of the matrix.\n+Definition: bcrsmatrix.hh:833\n+Dune::BCRSMatrix::setSize\n+void setSize(size_type rows, size_type columns, size_type nnz=0)\n+Set the size of the matrix.\n+Definition: bcrsmatrix.hh:861\n+Dune::BCRSMatrix::j_\n+std::shared_ptr< size_type > j_\n+Definition: bcrsmatrix.hh:2043\n+Dune::BCRSMatrix::setWindowPointers\n+void setWindowPointers(ConstRowIterator row)\n+Definition: bcrsmatrix.hh:2052\n+Dune::BCRSMatrix::operator=\n+BCRSMatrix & operator=(const BCRSMatrix &Mat)\n+assignment\n+Definition: bcrsmatrix.hh:911\n+Dune::BCRSMatrix::setColumnPointers\n+void setColumnPointers(ConstRowIterator row)\n+Copy row sizes from iterator range starting at row and set column index\n+pointers for all rows.\n+Definition: bcrsmatrix.hh:2077\n+Dune::BCRSMatrix::end\n+ConstIterator end() const\n+Get const iterator to one beyond last row.\n+Definition: bcrsmatrix.hh:718\n+Dune::BCRSMatrix::begin\n+ConstIterator begin() const\n+Get const iterator to first row.\n+Definition: bcrsmatrix.hh:712\n+Dune::BCRSMatrix::allocator_type\n+A allocator_type\n+export the allocator type\n+Definition: bcrsmatrix.hh:494\n+Dune::BCRSMatrix::beforeEnd\n+ConstIterator beforeEnd() const\n+Definition: bcrsmatrix.hh:725\n+Dune::BCRSMatrix::RealRowIterator\n+Iterator access to matrix rows\n+Definition: bcrsmatrix.hh:579\n+Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n+RealRowIterator()\n+empty constructor, use with care!\n+Definition: bcrsmatrix.hh:596\n+Dune::BCRSMatrix::RealRowIterator::equals\n+bool equals(const RealRowIterator< ValueType > &other) const\n+equality\n+Definition: bcrsmatrix.hh:624\n+Dune::BCRSMatrix::RealRowIterator::ValueType\n+std::remove_const< T >::type ValueType\n+The unqualified value type.\n+Definition: bcrsmatrix.hh:583\n+Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n+RealRowIterator(const RealRowIterator< ValueType > &it)\n+Definition: bcrsmatrix.hh:600\n+Dune::BCRSMatrix::RealRowIterator::equals\n+bool equals(const RealRowIterator< const ValueType > &other) const\n+equality\n+Definition: bcrsmatrix.hh:631\n+Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n+RealRowIterator(row_type *_p, size_type _i)\n+constructor\n+Definition: bcrsmatrix.hh:591\n+Dune::BCRSMatrix::RealRowIterator::distanceTo\n+std::ptrdiff_t distanceTo(const RealRowIterator< const ValueType > &other)\n+const\n+Definition: bcrsmatrix.hh:617\n+Dune::BCRSMatrix::RealRowIterator::index\n+size_type index() const\n+return index\n+Definition: bcrsmatrix.hh:606\n+Dune::BCRSMatrix::RealRowIterator::distanceTo\n+std::ptrdiff_t distanceTo(const RealRowIterator< ValueType > &other) const\n+Definition: bcrsmatrix.hh:611\n+Dune::BCRSMatrix::CreateIterator\n+Iterator class for sequential creation of blocks\n+Definition: bcrsmatrix.hh:957\n+Dune::BCRSMatrix::CreateIterator::operator==\n+bool operator==(const CreateIterator &it) const\n+equality\n+Definition: bcrsmatrix.hh:1052\n+Dune::BCRSMatrix::CreateIterator::operator++\n+CreateIterator & operator++()\n+prefix increment\n+Definition: bcrsmatrix.hh:977\n+Dune::BCRSMatrix::CreateIterator::index\n+size_type index() const\n+The number of the row that the iterator currently points to.\n+Definition: bcrsmatrix.hh:1058\n+Dune::BCRSMatrix::CreateIterator::operator!=\n+bool operator!=(const CreateIterator &it) const\n+inequality\n+Definition: bcrsmatrix.hh:1046\n+Dune::BCRSMatrix::CreateIterator::CreateIterator\n+CreateIterator(BCRSMatrix &_Mat, size_type _i)\n+constructor\n+Definition: bcrsmatrix.hh:960\n+Dune::BCRSMatrix::CreateIterator::insert\n+void insert(size_type j)\n+put column index in row\n+Definition: bcrsmatrix.hh:1064\n+Dune::BCRSMatrix::CreateIterator::contains\n+bool contains(size_type j)\n+return true if column index is in row\n+Definition: bcrsmatrix.hh:1070\n+Dune::BCRSMatrix::CreateIterator::size\n+size_type size() const\n+Get the current row size.\n+Definition: bcrsmatrix.hh:1079\n+Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>::field_type\n+typename BCRSMatrix< B, A >::field_type field_type\n+Definition: bcrsmatrix.hh:2299\n+Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>::real_type\n+typename FieldTraits< field_type >::real_type real_type\n+Definition: bcrsmatrix.hh:2300\n+Dune::BCRSMatrixError\n+Error specific to BCRSMatrix.\n+Definition: istlexception.hh:24\n+Dune::ImplicitModeCompressionBufferExhausted\n+Thrown when the compression buffer used by the implicit BCRSMatrix construction\n+is exhausted.\n+Definition: istlexception.hh:37\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::size_type\n+A::size_type size_type\n+Type for indices and sizes.\n+Definition: matrix.hh:577\n+Dune::Matrix::block_type\n+T block_type\n+Export the type representing the components.\n+Definition: matrix.hh:568\n+Dune::PointerCompare\n+Definition: matrixutils.hh:538\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00080.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00080.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixmatrix.hh File Reference\n+dune-istl: operators.hh File Reference\n \n \n \n \n \n \n \n@@ -64,69 +64,51 @@\n \n
    \n
    \n \n+ \n
    \n
    \n \n-

    provides functions for sparse matrix matrix multiplication. \n+

    Define general, extensible interface for operators. The available implementation wraps a matrix. \n More...

    \n-
    #include <tuple>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/timer.hh>
    \n+
    #include <cmath>
    \n+#include <complex>
    \n+#include <iostream>
    \n+#include <iomanip>
    \n+#include <string>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/shared_ptr.hh>
    \n+#include "solvercategory.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    struct  Dune::MatMultMatResult< M1, M2 >
     Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") More...
    class  Dune::LinearOperator< X, Y >
     A linear operator. More...
     
    struct  Dune::MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >
    class  Dune::AssembledLinearOperator< M, X, Y >
     A linear operator exporting itself in matrix form. More...
     
    struct  Dune::MatMultMatResult< BCRSMatrix< FieldMatrix< T, n, k >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >
     
    struct  Dune::TransposedMatMultMatResult< M1, M2 >
     Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") More...
     
    struct  Dune::TransposedMatMultMatResult< FieldMatrix< T, k, n >, FieldMatrix< T, k, m > >
     
    struct  Dune::TransposedMatMultMatResult< BCRSMatrix< FieldMatrix< T, k, n >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >
    class  Dune::MatrixAdapter< M, X, Y >
     Adapter to turn a matrix into a linear operator. More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::matMultTransposeMat (BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of a sparse matrix with a transposed sparse matrices ( \"$C=A*B^T$\"). More...
     
    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::matMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of two sparse matrices ( \"$C=A*B$\"). More...
     
    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::transposeMatMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of a transposed sparse matrix with another sparse matrices ( \"$C=A^T*B$\"). More...
     
    \n

    Detailed Description

    \n-

    provides functions for sparse matrix matrix multiplication.

    \n-
    Author
    Markus Blatt
    \n+

    Define general, extensible interface for operators. The available implementation wraps a matrix.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,68 +4,41 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-matrixmatrix.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes\n-provides functions for sparse matrix matrix multiplication. More...\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+operators.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Operator\n+concept\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"solvercategory.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::MatMultMatResult<_M1,_M2_>\n-\u00a0 Helper TMP to get the result type of a sparse matrix matrix\n- multiplication ( [$C=A*B$]) More...\n+class \u00a0Dune::LinearOperator<_X,_Y_>\n+\u00a0 A linear operator. More...\n \u00a0\n-struct \u00a0Dune::MatMultMatResult<_FieldMatrix<_T,_n,_k_>,_FieldMatrix<_T,_k,_m_>\n- >\n+class \u00a0Dune::AssembledLinearOperator<_M,_X,_Y_>\n+\u00a0 A linear operator exporting itself in matrix form. More...\n \u00a0\n-struct \u00a0Dune::MatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_n,_k_>,_A_>,\n- BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>\n-\u00a0\n-struct \u00a0Dune::TransposedMatMultMatResult<_M1,_M2_>\n-\u00a0 Helper TMP to get the result type of a sparse matrix matrix\n- multiplication ( [$C=A*B$]) More...\n-\u00a0\n-struct \u00a0Dune::TransposedMatMultMatResult<_FieldMatrix<_T,_k,_n_>,_FieldMatrix<\n- T,_k,_m_>_>\n-\u00a0\n-struct \u00a0Dune::TransposedMatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_k,_n_>,\n- A_>,_BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>\n+class \u00a0Dune::MatrixAdapter<_M,_X,_Y_>\n+\u00a0 Adapter to turn a matrix into a linear operator. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-template\n-void\u00a0Dune::matMultTransposeMat (BCRSMatrix< FieldMatrix< T, n, k >, A > &res,\n- const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix<\n- FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n-\u00a0 Calculate product of a sparse matrix with a transposed sparse matrices (\n- [$C=A*B^T$]). More...\n-\u00a0\n-template\n-void\u00a0Dune::matMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const\n- BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix<\n- FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n-\u00a0 Calculate product of two sparse matrices ( [$C=A*B$]). More...\n-\u00a0\n-template\n-void\u00a0Dune::transposeMatMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res,\n- const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix<\n- FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n-\u00a0 Calculate product of a transposed sparse matrix with another sparse\n- matrices ( [$C=A^T*B$]). More...\n-\u00a0\n ***** Detailed Description *****\n-provides functions for sparse matrix matrix multiplication.\n- Author\n- Markus Blatt\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00080_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00080_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixmatrix.hh Source File\n+dune-istl: operators.hh Source File\n \n \n \n \n \n \n \n@@ -62,595 +62,156 @@\n \n
    \n \n
    \n
    \n
    \n-
    matrixmatrix.hh
    \n+
    operators.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MATRIXMATRIX_HH
    \n-
    6#define DUNE_ISTL_MATRIXMATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_OPERATORS_HH
    \n+
    6#define DUNE_ISTL_OPERATORS_HH
    \n
    7
    \n-
    8#include <tuple>
    \n-
    9
    \n-\n-
    11#include <dune/common/fmatrix.hh>
    \n-
    12#include <dune/common/timer.hh>
    \n-
    13namespace Dune
    \n-
    14{
    \n-
    15
    \n-
    26 namespace
    \n-
    27 {
    \n-
    28
    \n-
    37 template<int b>
    \n-
    38 struct NonzeroPatternTraverser
    \n-
    39 {};
    \n-
    40
    \n-
    41
    \n-
    42 template<>
    \n-
    43 struct NonzeroPatternTraverser<0>
    \n-
    44 {
    \n-
    45 template<class T,class A1, class A2, class F, int n, int m, int k>
    \n-
    46 static void traverse(const Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>& A,
    \n-\n-
    48 F& func)
    \n-
    49 {
    \n-
    50 if(A.M()!=B.N())
    \n-
    51 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<A.M()<<"!="<<B.N());
    \n-
    52
    \n-
    53 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>::ConstRowIterator Row;
    \n-
    54 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>::ConstColIterator Col;
    \n-
    55 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,m>,A2>::ConstColIterator BCol;
    \n-
    56 for(Row row= A.begin(); row != A.end(); ++row) {
    \n-
    57 // Loop over all column entries
    \n-
    58 for(Col col = row->begin(); col != row->end(); ++col) {
    \n-
    59 // entry at i,k
    \n-
    60 // search for all nonzeros in row k
    \n-
    61 for(BCol bcol = B[col.index()].begin(); bcol != B[col.index()].end(); ++bcol) {
    \n-
    62 func(*col, *bcol, row.index(), bcol.index());
    \n-
    63 }
    \n-
    64 }
    \n-
    65 }
    \n-
    66 }
    \n-
    67
    \n-
    68 };
    \n-
    69
    \n-
    70 template<>
    \n-
    71 struct NonzeroPatternTraverser<1>
    \n-
    72 {
    \n-
    73 template<class T, class A1, class A2, class F, int n, int m, int k>
    \n-
    74 static void traverse(const Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>& A,
    \n-\n-
    76 F& func)
    \n-
    77 {
    \n-
    78
    \n-
    79 if(A.N()!=B.N())
    \n-
    80 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<A.N()<<"!="<<B.N());
    \n+
    8#include <cmath>
    \n+
    9#include <complex>
    \n+
    10#include <iostream>
    \n+
    11#include <iomanip>
    \n+
    12#include <string>
    \n+
    13
    \n+
    14#include <dune/common/exceptions.hh>
    \n+
    15#include <dune/common/shared_ptr.hh>
    \n+
    16
    \n+
    17#include "solvercategory.hh"
    \n+
    18
    \n+
    19
    \n+
    20namespace Dune {
    \n+
    21
    \n+
    44 //=====================================================================
    \n+
    45 // Abstract operator interface
    \n+
    46 //=====================================================================
    \n+
    47
    \n+
    48
    \n+
    66 template<class X, class Y>
    \n+\n+
    68 public:
    \n+
    70 typedef X domain_type;
    \n+
    72 typedef Y range_type;
    \n+
    74 typedef typename X::field_type field_type;
    \n+
    75
    \n+
    80 virtual void apply (const X& x, Y& y) const = 0;
    \n
    81
    \n-
    82 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>::ConstRowIterator Row;
    \n-
    83 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>::ConstColIterator Col;
    \n-
    84 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,m>,A2>::ConstColIterator BCol;
    \n-
    85
    \n-
    86 for(Row row=A.begin(); row!=A.end(); ++row) {
    \n-
    87 for(Col col=row->begin(); col!=row->end(); ++col) {
    \n-
    88 for(BCol bcol = B[row.index()].begin(); bcol != B[row.index()].end(); ++bcol) {
    \n-
    89 func(*col, *bcol, col.index(), bcol.index());
    \n-
    90 }
    \n-
    91 }
    \n-
    92 }
    \n-
    93 }
    \n-
    94 };
    \n-
    95
    \n-
    96 template<>
    \n-
    97 struct NonzeroPatternTraverser<2>
    \n-
    98 {
    \n-
    99 template<class T, class A1, class A2, class F, int n, int m, int k>
    \n-
    100 static void traverse(const BCRSMatrix<FieldMatrix<T,n,m>,A1>& mat,
    \n-
    101 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt,
    \n-
    102 F& func)
    \n-
    103 {
    \n-
    104 if(mat.M()!=matt.M())
    \n-
    105 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<mat.M()<<"!="<<matt.M());
    \n-
    106
    \n-
    107 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstRowIterator row_iterator;
    \n-
    108 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstColIterator col_iterator;
    \n-
    109 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstRowIterator row_iterator_t;
    \n-
    110 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstColIterator col_iterator_t;
    \n-
    111
    \n-
    112 for(row_iterator mrow=mat.begin(); mrow != mat.end(); ++mrow) {
    \n-
    113 //iterate over the column entries
    \n-
    114 // mt is a transposed matrix crs therefore it is treated as a ccs matrix
    \n-
    115 // and the row_iterator iterates over the columns of the transposed matrix.
    \n-
    116 // search the row of the transposed matrix for an entry with the same index
    \n-
    117 // as the mcol iterator
    \n-
    118
    \n-
    119 for(row_iterator_t mtcol=matt.begin(); mtcol != matt.end(); ++mtcol) {
    \n-
    120 //Search for col entries in mat that have a corrsponding row index in matt
    \n-
    121 // (i.e. corresponding col index in the as this is the transposed matrix
    \n-
    122 col_iterator_t mtrow=mtcol->begin();
    \n-
    123 bool funcCalled = false;
    \n-
    124 for(col_iterator mcol=mrow->begin(); mcol != mrow->end(); ++mcol) {
    \n-
    125 // search
    \n-
    126 // TODO: This should probably be substituted by a binary search
    \n-
    127 for( ; mtrow != mtcol->end(); ++mtrow)
    \n-
    128 if(mtrow.index()>=mcol.index())
    \n-
    129 break;
    \n-
    130 if(mtrow != mtcol->end() && mtrow.index()==mcol.index()) {
    \n-
    131 func(*mcol, *mtrow, mtcol.index());
    \n-
    132 funcCalled = true;
    \n-
    133 // In some cases we only search for one pair, then we break here
    \n-
    134 // and continue with the next column.
    \n-
    135 if(F::do_break)
    \n-
    136 break;
    \n-
    137 }
    \n-
    138 }
    \n-
    139 // move on with func only if func was called, otherwise they might
    \n-
    140 // get out of sync
    \n-
    141 if (funcCalled)
    \n-
    142 func.nextCol();
    \n-
    143 }
    \n-
    144 func.nextRow();
    \n-
    145 }
    \n-
    146 }
    \n-
    147 };
    \n-
    148
    \n-
    149
    \n+
    83 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const = 0;
    \n+
    84
    \n+
    86 virtual ~LinearOperator () {}
    \n+
    87
    \n+\n+
    90#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n+
    91 {
    \n+
    92 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n+
    93 };
    \n+
    94#else
    \n+
    95 = 0;
    \n+
    96#endif
    \n+
    97 };
    \n+
    98
    \n+
    99
    \n+
    108 template<class M, class X, class Y>
    \n+\n+
    110 public:
    \n+
    112 typedef M matrix_type;
    \n+
    113 typedef X domain_type;
    \n+
    114 typedef Y range_type;
    \n+
    115 typedef typename X::field_type field_type;
    \n+
    116
    \n+
    118 virtual const M& getmat () const = 0;
    \n+
    119
    \n+\n+
    122 };
    \n+
    123
    \n+
    124
    \n+
    125
    \n+
    126 //=====================================================================
    \n+
    127 // Implementation for ISTL-matrix based operator
    \n+
    128 //=====================================================================
    \n+
    129
    \n+
    135 template<class M, class X, class Y>
    \n+\n+
    137 {
    \n+
    138 public:
    \n+
    140 typedef M matrix_type;
    \n+
    141 typedef X domain_type;
    \n+
    142 typedef Y range_type;
    \n+
    143 typedef typename X::field_type field_type;
    \n+
    144
    \n+
    146 explicit MatrixAdapter (const M& A) : _A_(stackobject_to_shared_ptr(A)) {}
    \n+
    147
    \n+
    149 explicit MatrixAdapter (std::shared_ptr<const M> A) : _A_(A) {}
    \n
    150
    \n-
    151 template<class T, class A, int n, int m>
    \n-
    152 class SparsityPatternInitializer
    \n-
    153 {
    \n-
    154 public:
    \n-
    155 enum {do_break=true};
    \n-
    156 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::CreateIterator CreateIterator;
    \n-
    157 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::size_type size_type;
    \n-
    158
    \n-
    159 SparsityPatternInitializer(CreateIterator iter)
    \n-
    160 : rowiter(iter)
    \n-
    161 {}
    \n+
    152 void apply (const X& x, Y& y) const override
    \n+
    153 {
    \n+
    154 _A_->mv(x,y);
    \n+
    155 }
    \n+
    156
    \n+
    158 void applyscaleadd (field_type alpha, const X& x, Y& y) const override
    \n+
    159 {
    \n+
    160 _A_->usmv(alpha,x,y);
    \n+
    161 }
    \n
    162
    \n-
    163 template<class T1, class T2>
    \n-
    164 void operator()(const T1&, const T2&, size_type j)
    \n-
    165 {
    \n-
    166 rowiter.insert(j);
    \n-
    167 }
    \n+
    164 const M& getmat () const override
    \n+
    165 {
    \n+
    166 return *_A_;
    \n+
    167 }
    \n
    168
    \n-
    169 void nextRow()
    \n-
    170 {
    \n-
    171 ++rowiter;
    \n-
    172 }
    \n-
    173 void nextCol()
    \n-
    174 {}
    \n-
    175
    \n-
    176 private:
    \n-
    177 CreateIterator rowiter;
    \n-
    178 };
    \n-
    179
    \n-
    180
    \n-
    181 template<int transpose, class T, class TA, int n, int m>
    \n-
    182 class MatrixInitializer
    \n-
    183 {
    \n-
    184 public:
    \n-
    185 enum {do_break=true};
    \n-\n-\n-
    188 typedef typename Matrix::size_type size_type;
    \n-
    189
    \n-
    190 MatrixInitializer(Matrix& A_, size_type)
    \n-
    191 : count(0), A(A_)
    \n-
    192 {}
    \n-
    193 template<class T1, class T2>
    \n-
    194 void operator()(const T1&, const T2&, int)
    \n-
    195 {
    \n-
    196 ++count;
    \n-
    197 }
    \n-
    198
    \n-
    199 void nextCol()
    \n-
    200 {}
    \n-
    201
    \n-
    202 void nextRow()
    \n-
    203 {}
    \n-
    204
    \n-
    205 std::size_t nonzeros()
    \n-
    206 {
    \n-
    207 return count;
    \n-
    208 }
    \n-
    209
    \n-
    210 template<class A1, class A2, int n2, int m2, int n3, int m3>
    \n-
    211 void initPattern(const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
    \n-
    212 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
    \n-
    213 {
    \n-
    214 SparsityPatternInitializer<T, TA, n, m> sparsity(A.createbegin());
    \n-
    215 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,sparsity);
    \n-
    216 }
    \n-
    217
    \n-
    218 private:
    \n-
    219 std::size_t count;
    \n-
    220 Matrix& A;
    \n-
    221 };
    \n-
    222
    \n-
    223 template<class T, class TA, int n, int m>
    \n-
    224 class MatrixInitializer<1,T,TA,n,m>
    \n-
    225 {
    \n-
    226 public:
    \n-
    227 enum {do_break=false};
    \n-\n-\n-
    230 typedef typename Matrix::size_type size_type;
    \n-
    231
    \n-
    232 MatrixInitializer(Matrix& A_, size_type rows)
    \n-
    233 : A(A_), entries(rows)
    \n-
    234 {}
    \n-
    235
    \n-
    236 template<class T1, class T2>
    \n-
    237 void operator()(const T1&, const T2&, size_type i, size_type j)
    \n-
    238 {
    \n-
    239 entries[i].insert(j);
    \n-
    240 }
    \n-
    241
    \n-
    242 void nextCol()
    \n-
    243 {}
    \n-
    244
    \n-
    245 size_type nonzeros()
    \n-
    246 {
    \n-
    247 size_type nnz=0;
    \n-
    248 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
    \n-
    249 for(Iter iter = entries.begin(); iter != entries.end(); ++iter)
    \n-
    250 nnz+=(*iter).size();
    \n-
    251 return nnz;
    \n-
    252 }
    \n-
    253 template<class A1, class A2, int n2, int m2, int n3, int m3>
    \n-
    254 void initPattern(const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>&,
    \n-
    255 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>&)
    \n-
    256 {
    \n-
    257 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
    \n-
    258 CreateIterator citer = A.createbegin();
    \n-
    259 for(Iter iter = entries.begin(); iter != entries.end(); ++iter, ++citer) {
    \n-
    260 typedef std::set<size_t>::const_iterator SetIter;
    \n-
    261 for(SetIter index=iter->begin(); index != iter->end(); ++index)
    \n-
    262 citer.insert(*index);
    \n-
    263 }
    \n-
    264 }
    \n-
    265
    \n-
    266 private:
    \n-
    267 Matrix& A;
    \n-
    268 std::vector<std::set<size_t> > entries;
    \n-
    269 };
    \n-
    270
    \n-
    271 template<class T, class TA, int n, int m>
    \n-
    272 struct MatrixInitializer<0,T,TA,n,m>
    \n-
    273 : public MatrixInitializer<1,T,TA,n,m>
    \n-
    274 {
    \n-
    275 MatrixInitializer(Dune::BCRSMatrix<Dune::FieldMatrix<T,n,m>,TA>& A_,
    \n-
    276 typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,m>,TA>::size_type rows)
    \n-
    277 : MatrixInitializer<1,T,TA,n,m>(A_,rows)
    \n-
    278 {}
    \n-
    279 };
    \n-
    280
    \n-
    281
    \n-
    282 template<class T, class T1, class T2, int n, int m, int k>
    \n-
    283 void addMatMultTransposeMat(FieldMatrix<T,n,k>& res, const FieldMatrix<T1,n,m>& mat,
    \n-
    284 const FieldMatrix<T2,k,m>& matt)
    \n-
    285 {
    \n-
    286 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n-
    287
    \n-
    288 for(size_type row=0; row<n; ++row)
    \n-
    289 for(size_type col=0; col<k; ++col) {
    \n-
    290 for(size_type i=0; i < m; ++i)
    \n-
    291 res[row][col]+=mat[row][i]*matt[col][i];
    \n-
    292 }
    \n-
    293 }
    \n-
    294
    \n-
    295 template<class T, class T1, class T2, int n, int m, int k>
    \n-
    296 void addTransposeMatMultMat(FieldMatrix<T,n,k>& res, const FieldMatrix<T1,m,n>& mat,
    \n-
    297 const FieldMatrix<T2,m,k>& matt)
    \n-
    298 {
    \n-
    299 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n-
    300 for(size_type i=0; i<m; ++i)
    \n-
    301 for(size_type row=0; row<n; ++row) {
    \n-
    302 for(size_type col=0; col < k; ++col)
    \n-
    303 res[row][col]+=mat[i][row]*matt[i][col];
    \n-
    304 }
    \n-
    305 }
    \n-
    306
    \n-
    307 template<class T, class T1, class T2, int n, int m, int k>
    \n-
    308 void addMatMultMat(FieldMatrix<T,n,m>& res, const FieldMatrix<T1,n,k>& mat,
    \n-
    309 const FieldMatrix<T2,k,m>& matt)
    \n-
    310 {
    \n-
    311 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n-
    312 for(size_type row=0; row<n; ++row)
    \n-
    313 for(size_type col=0; col<m; ++col) {
    \n-
    314 for(size_type i=0; i < k; ++i)
    \n-
    315 res[row][col]+=mat[row][i]*matt[i][col];
    \n-
    316 }
    \n-
    317 }
    \n-
    318
    \n-
    319
    \n-
    320 template<class T, class A, int n, int m>
    \n-
    321 class EntryAccumulatorFather
    \n-
    322 {
    \n-
    323 public:
    \n-
    324 enum {do_break=false};
    \n-\n-
    326 typedef typename Matrix::RowIterator Row;
    \n-
    327 typedef typename Matrix::ColIterator Col;
    \n-
    328
    \n-
    329 EntryAccumulatorFather(Matrix& mat_)
    \n-
    330 : mat(mat_), row(mat.begin())
    \n-
    331 {
    \n-
    332 mat=0;
    \n-
    333 col=row->begin();
    \n-
    334 }
    \n-
    335 void nextRow()
    \n-
    336 {
    \n-
    337 ++row;
    \n-
    338 if(row!=mat.end())
    \n-
    339 col=row->begin();
    \n-
    340 }
    \n-
    341
    \n-
    342 void nextCol()
    \n-
    343 {
    \n-
    344 ++this->col;
    \n-
    345 }
    \n-
    346 protected:
    \n-
    347 Matrix& mat;
    \n-
    348 private:
    \n-
    349 Row row;
    \n-
    350 protected:
    \n-\n-
    352 };
    \n-
    353
    \n-
    354 template<class T, class A, int n, int m, int transpose>
    \n-
    355 class EntryAccumulator
    \n-
    356 : public EntryAccumulatorFather<T,A,n,m>
    \n-
    357 {
    \n-
    358 public:
    \n-\n-
    360 typedef typename Matrix::size_type size_type;
    \n-
    361
    \n-
    362 EntryAccumulator(Matrix& mat_)
    \n-
    363 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n-
    364 {}
    \n-
    365
    \n-
    366 template<class T1, class T2>
    \n-
    367 void operator()(const T1& t1, const T2& t2, size_type i)
    \n-
    368 {
    \n-
    369 assert(this->col.index()==i);
    \n-
    370 addMatMultMat(*(this->col),t1,t2);
    \n-
    371 }
    \n-
    372 };
    \n-
    373
    \n-
    374 template<class T, class A, int n, int m>
    \n-
    375 class EntryAccumulator<T,A,n,m,0>
    \n-
    376 : public EntryAccumulatorFather<T,A,n,m>
    \n-
    377 {
    \n-
    378 public:
    \n-\n-
    380 typedef typename Matrix::size_type size_type;
    \n-
    381
    \n-
    382 EntryAccumulator(Matrix& mat_)
    \n-
    383 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n-
    384 {}
    \n-
    385
    \n-
    386 template<class T1, class T2>
    \n-
    387 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)
    \n-
    388 {
    \n-
    389 addMatMultMat(this->mat[i][j], t1, t2);
    \n-
    390 }
    \n-
    391 };
    \n-
    392
    \n-
    393 template<class T, class A, int n, int m>
    \n-
    394 class EntryAccumulator<T,A,n,m,1>
    \n-
    395 : public EntryAccumulatorFather<T,A,n,m>
    \n-
    396 {
    \n-
    397 public:
    \n-\n-
    399 typedef typename Matrix::size_type size_type;
    \n-
    400
    \n-
    401 EntryAccumulator(Matrix& mat_)
    \n-
    402 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n-
    403 {}
    \n-
    404
    \n-
    405 template<class T1, class T2>
    \n-
    406 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)
    \n-
    407 {
    \n-
    408 addTransposeMatMultMat(this->mat[i][j], t1, t2);
    \n-
    409 }
    \n-
    410 };
    \n-
    411
    \n-
    412 template<class T, class A, int n, int m>
    \n-
    413 class EntryAccumulator<T,A,n,m,2>
    \n-
    414 : public EntryAccumulatorFather<T,A,n,m>
    \n-
    415 {
    \n-
    416 public:
    \n-\n-
    418 typedef typename Matrix::size_type size_type;
    \n-
    419
    \n-
    420 EntryAccumulator(Matrix& mat_)
    \n-
    421 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n-
    422 {}
    \n-
    423
    \n-
    424 template<class T1, class T2>
    \n-
    425 void operator()(const T1& t1, const T2& t2, [[maybe_unused]] size_type i)
    \n-
    426 {
    \n-
    427 assert(this->col.index()==i);
    \n-
    428 addMatMultTransposeMat(*this->col,t1,t2);
    \n-
    429 }
    \n-
    430 };
    \n-
    431
    \n-
    432
    \n-
    433 template<int transpose>
    \n-
    434 struct SizeSelector
    \n-
    435 {};
    \n-
    436
    \n-
    437 template<>
    \n-
    438 struct SizeSelector<0>
    \n-
    439 {
    \n-
    440 template<class M1, class M2>
    \n-
    441 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n-
    442 size(const M1& m1, const M2& m2)
    \n-
    443 {
    \n-
    444 return std::make_tuple(m1.N(), m2.M());
    \n-
    445 }
    \n-
    446 };
    \n-
    447
    \n-
    448 template<>
    \n-
    449 struct SizeSelector<1>
    \n-
    450 {
    \n-
    451 template<class M1, class M2>
    \n-
    452 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n-
    453 size(const M1& m1, const M2& m2)
    \n-
    454 {
    \n-
    455 return std::make_tuple(m1.M(), m2.M());
    \n-
    456 }
    \n-
    457 };
    \n-
    458
    \n-
    459
    \n-
    460 template<>
    \n-
    461 struct SizeSelector<2>
    \n-
    462 {
    \n-
    463 template<class M1, class M2>
    \n-
    464 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n-
    465 size(const M1& m1, const M2& m2)
    \n-
    466 {
    \n-
    467 return std::make_tuple(m1.N(), m2.N());
    \n-
    468 }
    \n-
    469 };
    \n-
    470
    \n-
    471 template<int transpose, class T, class A, class A1, class A2, int n1, int m1, int n2, int m2, int n3, int m3>
    \n-
    472 void matMultMat(BCRSMatrix<FieldMatrix<T,n1,m1>,A>& res, const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
    \n-
    473 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
    \n-
    474 {
    \n-
    475 // First step is to count the number of nonzeros
    \n-
    476 typename BCRSMatrix<FieldMatrix<T,n1,m1>,A>::size_type rows, cols;
    \n-
    477 std::tie(rows,cols)=SizeSelector<transpose>::size(mat1, mat2);
    \n-
    478 MatrixInitializer<transpose,T,A,n1,m1> patternInit(res, rows);
    \n-
    479 Timer timer;
    \n-
    480 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,patternInit);
    \n-
    481 res.setSize(rows, cols, patternInit.nonzeros());
    \n-
    482 res.setBuildMode(BCRSMatrix<FieldMatrix<T,n1,m1>,A>::row_wise);
    \n-
    483
    \n-
    484 //std::cout<<"Counting nonzeros took "<<timer.elapsed()<<std::endl;
    \n-
    485 timer.reset();
    \n-
    486
    \n-
    487 // Second step is to allocate the storage for the result and initialize the nonzero pattern
    \n-
    488 patternInit.initPattern(mat1, mat2);
    \n-
    489
    \n-
    490 //std::cout<<"Setting up sparsity pattern took "<<timer.elapsed()<<std::endl;
    \n-
    491 timer.reset();
    \n-
    492 // As a last step calculate the entries
    \n-
    493 res = 0.0;
    \n-
    494 EntryAccumulator<T,A,n1,m1, transpose> entriesAccu(res);
    \n-
    495 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,entriesAccu);
    \n-
    496 //std::cout<<"Calculating entries took "<<timer.elapsed()<<std::endl;
    \n-
    497 }
    \n-
    498
    \n-
    499 }
    \n-
    500
    \n-
    508 template<typename M1, typename M2>
    \n-\n-
    510 {};
    \n-
    511
    \n-
    512 template<typename T, int n, int k, int m>
    \n-\n-
    514 {
    \n-\n-
    516 };
    \n-
    517
    \n-
    518 template<typename T, typename A, typename A1, int n, int k, int m>
    \n-\n-
    520 {
    \n-\n-
    522 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
    \n-
    523 };
    \n-
    524
    \n-
    525
    \n-
    533 template<typename M1, typename M2>
    \n-\n-
    535 {};
    \n-
    536
    \n-
    537 template<typename T, int n, int k, int m>
    \n-\n-
    539 {
    \n-\n-
    541 };
    \n-
    542
    \n-
    543 template<typename T, typename A, typename A1, int n, int k, int m>
    \n-\n-
    545 {
    \n-\n-
    547 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
    \n-
    548 };
    \n-
    549
    \n-
    550
    \n-
    559 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n-\n-
    561 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, [[maybe_unused]] bool tryHard=false)
    \n-
    562 {
    \n-
    563 matMultMat<2>(res,mat, matt);
    \n-
    564 }
    \n-
    565
    \n-
    574 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n-\n-
    576 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, bool tryHard=false)
    \n-
    577 {
    \n-
    578 matMultMat<0>(res,mat, matt);
    \n-
    579 }
    \n-
    580
    \n-
    589 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n-\n-
    591 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, [[maybe_unused]] bool tryHard=false)
    \n-
    592 {
    \n-
    593 matMultMat<1>(res,mat, matt);
    \n-
    594 }
    \n-
    595
    \n-
    596}
    \n-
    597#endif
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    FieldMatrix< T, n, m > type
    Definition: matrixmatrix.hh:515
    \n-
    void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of a transposed sparse matrix with another sparse matrices ( ).
    Definition: matrixmatrix.hh:590
    \n-
    void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of two sparse matrices ( ).
    Definition: matrixmatrix.hh:575
    \n-
    Matrix::RowIterator Row
    Definition: matrixmatrix.hh:326
    \n-
    Dune::BCRSMatrix< Dune::FieldMatrix< T, n, m >, TA > Matrix
    Definition: matrixmatrix.hh:228
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:360
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:380
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix::ColIterator Col
    Definition: matrixmatrix.hh:327
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:188
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:230
    \n-\n-
    void matMultTransposeMat(BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of a sparse matrix with a transposed sparse matrices ( ).
    Definition: matrixmatrix.hh:560
    \n-
    Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
    Definition: matrixmatrix.hh:186
    \n-
    BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
    Definition: matrixmatrix.hh:522
    \n-
    Matrix::CreateIterator CreateIterator
    Definition: matrixmatrix.hh:229
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:399
    \n-
    Matrix::CreateIterator CreateIterator
    Definition: matrixmatrix.hh:187
    \n-
    BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
    Definition: matrixmatrix.hh:547
    \n-
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:418
    \n-
    BCRSMatrix< FieldMatrix< T, n, m >, A >::size_type size_type
    Definition: matrixmatrix.hh:157
    \n+\n+
    171 {
    \n+\n+
    173 }
    \n+
    174
    \n+
    175 private:
    \n+
    176 const std::shared_ptr<const M> _A_;
    \n+
    177 };
    \n+
    178
    \n+
    181} // end namespace
    \n+
    182
    \n+
    183#endif
    \n+\n
    Definition: allocator.hh:11
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n-
    row_type::Iterator ColIterator
    Iterator for the entries of each row.
    Definition: bcrsmatrix.hh:704
    \n-
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n-
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n-
    Iterator access to matrix rows
    Definition: bcrsmatrix.hh:579
    \n-
    Iterator class for sequential creation of blocks
    Definition: bcrsmatrix.hh:957
    \n-
    void insert(size_type j)
    put column index in row
    Definition: bcrsmatrix.hh:1064
    \n-
    Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
    Definition: matrixmatrix.hh:510
    \n-
    Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
    Definition: matrixmatrix.hh:535
    \n-
    Definition: matrixutils.hh:27
    \n+
    A linear operator.
    Definition: operators.hh:67
    \n+
    virtual ~LinearOperator()
    every abstract base class has a virtual destructor
    Definition: operators.hh:86
    \n+
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n+
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const =0
    apply operator to x, scale and add:
    \n+
    virtual SolverCategory::Category category() const =0
    Category of the linear operator (see SolverCategory::Category)
    \n+
    Y range_type
    The type of the range of the operator.
    Definition: operators.hh:72
    \n+
    virtual void apply(const X &x, Y &y) const =0
    apply operator to x: The input vector is consistent and the output must also be consistent on the in...
    \n+
    X domain_type
    The type of the domain of the operator.
    Definition: operators.hh:70
    \n+
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n+
    virtual const M & getmat() const =0
    get matrix via *
    \n+
    X domain_type
    Definition: operators.hh:113
    \n+
    X::field_type field_type
    Definition: operators.hh:115
    \n+
    Y range_type
    Definition: operators.hh:114
    \n+
    M matrix_type
    export types, usually they come from the derived class
    Definition: operators.hh:112
    \n+
    virtual ~AssembledLinearOperator()
    every abstract base class has a virtual destructor
    Definition: operators.hh:121
    \n+
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n+
    MatrixAdapter(std::shared_ptr< const M > A)
    constructor: store an std::shared_ptr to a matrix
    Definition: operators.hh:149
    \n+
    MatrixAdapter(const M &A)
    constructor: just store a reference to a matrix
    Definition: operators.hh:146
    \n+
    void applyscaleadd(field_type alpha, const X &x, Y &y) const override
    apply operator to x, scale and add:
    Definition: operators.hh:158
    \n+
    Y range_type
    Definition: operators.hh:142
    \n+
    X domain_type
    Definition: operators.hh:141
    \n+
    X::field_type field_type
    Definition: operators.hh:143
    \n+
    const M & getmat() const override
    get matrix via *
    Definition: operators.hh:164
    \n+
    SolverCategory::Category category() const override
    Category of the solver (see SolverCategory::Category)
    Definition: operators.hh:170
    \n+
    void apply(const X &x, Y &y) const override
    apply operator to x:
    Definition: operators.hh:152
    \n+
    M matrix_type
    export types
    Definition: operators.hh:140
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,722 +4,225 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrixmatrix.hh\n+operators.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIXMATRIX_HH\n- 6#define DUNE_ISTL_MATRIXMATRIX_HH\n+ 5#ifndef DUNE_ISTL_OPERATORS_HH\n+ 6#define DUNE_ISTL_OPERATORS_HH\n 7\n- 8#include \n- 9\n- 10#include \n- 11#include \n- 12#include \n- 13namespace Dune\n- 14{\n- 15\n- 26 namespace\n- 27 {\n- 28\n- 37 template\n- 38 struct NonzeroPatternTraverser\n- 39 {};\n- 40\n- 41\n- 42 template<>\n- 43 struct NonzeroPatternTraverser<0>\n- 44 {\n- 45 template\n- 46 static void traverse(const Dune::BCRSMatrix,A1>&\n-A,\n- 47 const Dune::BCRSMatrix,A2>& B,\n- 48 F& func)\n- 49 {\n- 50 if(A.M()!=B.N())\n- 51 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<,A1>::\n-ConstRowIterator Row;\n- 54 typedef typename Dune::BCRSMatrix,A1>::\n-ConstColIterator Col;\n- 55 typedef typename Dune::BCRSMatrix,A2>::\n-ConstColIterator BCol;\n- 56 for(Row row= A.begin(); row != A.end(); ++row) {\n- 57 // Loop over all column entries\n- 58 for(Col col = row->begin(); col != row->end(); ++col) {\n- 59 // entry at i,k\n- 60 // search for all nonzeros in row k\n- 61 for(BCol bcol = B[col.index()].begin(); bcol != B[col.index()].end();\n-++bcol) {\n- 62 func(*col, *bcol, row.index(), bcol.index());\n- 63 }\n- 64 }\n- 65 }\n- 66 }\n- 67\n- 68 };\n- 69\n- 70 template<>\n- 71 struct NonzeroPatternTraverser<1>\n- 72 {\n- 73 template\n- 74 static void traverse(const Dune::BCRSMatrix,A1>&\n-A,\n- 75 const Dune::BCRSMatrix,A2>& B,\n- 76 F& func)\n- 77 {\n- 78\n- 79 if(A.N()!=B.N())\n- 80 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \n+ 15#include \n+ 16\n+ 17#include \"solvercategory.hh\"\n+ 18\n+ 19\n+ 20namespace Dune {\n+ 21\n+ 44 //=====================================================================\n+ 45 // Abstract operator interface\n+ 46 //=====================================================================\n+ 47\n+ 48\n+ 66 template\n+67 class LinearOperator {\n+ 68 public:\n+70 typedef X domain_type;\n+72 typedef Y range_type;\n+74 typedef typename X::field_type field_type;\n+ 75\n+80 virtual void apply (const X& x, Y& y) const = 0;\n 81\n- 82 typedef typename Dune::BCRSMatrix,A1>::\n-ConstRowIterator Row;\n- 83 typedef typename Dune::BCRSMatrix,A1>::\n-ConstColIterator Col;\n- 84 typedef typename Dune::BCRSMatrix,A2>::\n-ConstColIterator BCol;\n- 85\n- 86 for(Row row=A.begin(); row!=A.end(); ++row) {\n- 87 for(Col col=row->begin(); col!=row->end(); ++col) {\n- 88 for(BCol bcol = B[row.index()].begin(); bcol != B[row.index()].end();\n-++bcol) {\n- 89 func(*col, *bcol, col.index(), bcol.index());\n- 90 }\n- 91 }\n- 92 }\n- 93 }\n- 94 };\n- 95\n- 96 template<>\n- 97 struct NonzeroPatternTraverser<2>\n- 98 {\n- 99 template\n- 100 static void traverse(const BCRSMatrix,A1>& mat,\n- 101 const BCRSMatrix,A2>& matt,\n- 102 F& func)\n- 103 {\n- 104 if(mat.M()!=matt.M())\n- 105 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<,A1>::ConstRowIterator\n-row_iterator;\n- 108 typedef typename BCRSMatrix,A1>::ConstColIterator\n-col_iterator;\n- 109 typedef typename BCRSMatrix,A2>::ConstRowIterator\n-row_iterator_t;\n- 110 typedef typename BCRSMatrix,A2>::ConstColIterator\n-col_iterator_t;\n- 111\n- 112 for(row_iterator mrow=mat.begin(); mrow != mat.end(); ++mrow) {\n- 113 //iterate over the column entries\n- 114 // mt is a transposed matrix crs therefore it is treated as a ccs matrix\n- 115 // and the row_iterator iterates over the columns of the transposed\n-matrix.\n- 116 // search the row of the transposed matrix for an entry with the same\n-index\n- 117 // as the mcol iterator\n- 118\n- 119 for(row_iterator_t mtcol=matt.begin(); mtcol != matt.end(); ++mtcol) {\n- 120 //Search for col entries in mat that have a corrsponding row index in matt\n- 121 // (i.e. corresponding col index in the as this is the transposed matrix\n- 122 col_iterator_t mtrow=mtcol->begin();\n- 123 bool funcCalled = false;\n- 124 for(col_iterator mcol=mrow->begin(); mcol != mrow->end(); ++mcol) {\n- 125 // search\n- 126 // TODO: This should probably be substituted by a binary search\n- 127 for( ; mtrow != mtcol->end(); ++mtrow)\n- 128 if(mtrow.index()>=mcol.index())\n- 129 break;\n- 130 if(mtrow != mtcol->end() && mtrow.index()==mcol.index()) {\n- 131 func(*mcol, *mtrow, mtcol.index());\n- 132 funcCalled = true;\n- 133 // In some cases we only search for one pair, then we break here\n- 134 // and continue with the next column.\n- 135 if(F::do_break)\n- 136 break;\n- 137 }\n- 138 }\n- 139 // move on with func only if func was called, otherwise they might\n- 140 // get out of sync\n- 141 if (funcCalled)\n- 142 func.nextCol();\n- 143 }\n- 144 func.nextRow();\n- 145 }\n- 146 }\n- 147 };\n- 148\n- 149\n+83 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const = 0;\n+ 84\n+86 virtual ~LinearOperator () {}\n+ 87\n+89 virtual SolverCategory::Category category() const\n+ 90#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n+ 91 {\n+ 92 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n+method in a derived classes, in the future this method will pure virtual.\");\n+ 93 };\n+ 94#else\n+ 95 = 0;\n+ 96#endif\n+ 97 };\n+ 98\n+ 99\n+ 108 template\n+109 class AssembledLinearOperator : public LinearOperator {\n+ 110 public:\n+112 typedef M matrix_type;\n+113 typedef X domain_type;\n+114 typedef Y range_type;\n+115 typedef typename X::field_type field_type;\n+ 116\n+118 virtual const M& getmat () const = 0;\n+ 119\n+121 virtual ~AssembledLinearOperator () {}\n+ 122 };\n+ 123\n+ 124\n+ 125\n+ 126 //=====================================================================\n+ 127 // Implementation for ISTL-matrix based operator\n+ 128 //=====================================================================\n+ 129\n+ 135 template\n+136 class MatrixAdapter : public AssembledLinearOperator\n+ 137 {\n+ 138 public:\n+140 typedef M matrix_type;\n+141 typedef X domain_type;\n+142 typedef Y range_type;\n+143 typedef typename X::field_type field_type;\n+ 144\n+146 explicit MatrixAdapter (const M& A) : _A_(stackobject_to_shared_ptr(A)) {}\n+ 147\n+149 explicit MatrixAdapter (std::shared_ptr A) : _A_(A) {}\n 150\n- 151 template\n- 152 class SparsityPatternInitializer\n+152 void apply (const X& x, Y& y) const override\n 153 {\n- 154 public:\n-155 enum {do_break=true};\n-156 typedef typename BCRSMatrix,A>::CreateIterator\n-CreateIterator;\n-157 typedef typename BCRSMatrix,A>::size_type size_type;\n- 158\n- 159 SparsityPatternInitializer(CreateIterator iter)\n- 160 : rowiter(iter)\n- 161 {}\n+ 154 _A_->mv(x,y);\n+ 155 }\n+ 156\n+158 void applyscaleadd (field_type alpha, const X& x, Y& y) const override\n+ 159 {\n+ 160 _A_->usmv(alpha,x,y);\n+ 161 }\n 162\n- 163 template\n- 164 void operator()(const T1&, const T2&, size_type j)\n+164 const M& getmat () const override\n 165 {\n- 166 rowiter.insert(j);\n+ 166 return *_A_;\n 167 }\n 168\n- 169 void nextRow()\n- 170 {\n- 171 ++rowiter;\n- 172 }\n- 173 void nextCol()\n- 174 {}\n- 175\n- 176 private:\n- 177 CreateIterator rowiter;\n- 178 };\n- 179\n- 180\n- 181 template\n- 182 class MatrixInitializer\n- 183 {\n- 184 public:\n-185 enum {do_break=true};\n-186 typedef typename Dune::BCRSMatrix,TA> Matrix;\n-187 typedef typename Matrix::CreateIterator CreateIterator;\n-188 typedef typename Matrix::size_type size_type;\n- 189\n- 190 MatrixInitializer(Matrix& A_, size_type)\n- 191 : count(0), A(A_)\n- 192 {}\n- 193 template\n- 194 void operator()(const T1&, const T2&, int)\n- 195 {\n- 196 ++count;\n- 197 }\n- 198\n- 199 void nextCol()\n- 200 {}\n- 201\n- 202 void nextRow()\n- 203 {}\n- 204\n- 205 std::size_t nonzeros()\n- 206 {\n- 207 return count;\n- 208 }\n- 209\n- 210 template\n- 211 void initPattern(const BCRSMatrix,A1>& mat1,\n- 212 const BCRSMatrix,A2>& mat2)\n- 213 {\n- 214 SparsityPatternInitializer sparsity(A.createbegin());\n- 215 NonzeroPatternTraverser::traverse(mat1,mat2,sparsity);\n- 216 }\n- 217\n- 218 private:\n- 219 std::size_t count;\n- 220 Matrix& A;\n- 221 };\n- 222\n- 223 template\n- 224 class MatrixInitializer<1,T,TA,n,m>\n- 225 {\n- 226 public:\n-227 enum {do_break=false};\n-228 typedef Dune::BCRSMatrix,TA> Matrix;\n-229 typedef typename Matrix::CreateIterator CreateIterator;\n-230 typedef typename Matrix::size_type size_type;\n- 231\n- 232 MatrixInitializer(Matrix& A_, size_type rows)\n- 233 : A(A_), entries(rows)\n- 234 {}\n- 235\n- 236 template\n- 237 void operator()(const T1&, const T2&, size_type i, size_type j)\n- 238 {\n- 239 entries[i].insert(j);\n- 240 }\n- 241\n- 242 void nextCol()\n- 243 {}\n- 244\n- 245 size_type nonzeros()\n- 246 {\n- 247 size_type nnz=0;\n- 248 typedef typename std::vector >::const_iterator Iter;\n- 249 for(Iter iter = entries.begin(); iter != entries.end(); ++iter)\n- 250 nnz+=(*iter).size();\n- 251 return nnz;\n- 252 }\n- 253 template\n- 254 void initPattern(const BCRSMatrix,A1>&,\n- 255 const BCRSMatrix,A2>&)\n- 256 {\n- 257 typedef typename std::vector >::const_iterator Iter;\n- 258 CreateIterator citer = A.createbegin();\n- 259 for(Iter iter = entries.begin(); iter != entries.end(); ++iter, ++citer) {\n- 260 typedef std::set::const_iterator SetIter;\n- 261 for(SetIter index=iter->begin(); index != iter->end(); ++index)\n- 262 citer.insert(*index);\n- 263 }\n- 264 }\n- 265\n- 266 private:\n- 267 Matrix& A;\n- 268 std::vector > entries;\n- 269 };\n- 270\n- 271 template\n- 272 struct MatrixInitializer<0,T,TA,n,m>\n- 273 : public MatrixInitializer<1,T,TA,n,m>\n- 274 {\n- 275 MatrixInitializer(Dune::BCRSMatrix,TA>& A_,\n- 276 typename Dune::BCRSMatrix,TA>::size_type rows)\n- 277 : MatrixInitializer<1,T,TA,n,m>(A_,rows)\n- 278 {}\n- 279 };\n- 280\n- 281\n- 282 template\n- 283 void addMatMultTransposeMat(FieldMatrix& res, const\n-FieldMatrix& mat,\n- 284 const FieldMatrix& matt)\n- 285 {\n- 286 typedef typename FieldMatrix::size_type size_type;\n- 287\n- 288 for(size_type row=0; row\n- 296 void addTransposeMatMultMat(FieldMatrix& res, const\n-FieldMatrix& mat,\n- 297 const FieldMatrix& matt)\n- 298 {\n- 299 typedef typename FieldMatrix::size_type size_type;\n- 300 for(size_type i=0; i\n- 308 void addMatMultMat(FieldMatrix& res, const FieldMatrix&\n-mat,\n- 309 const FieldMatrix& matt)\n- 310 {\n- 311 typedef typename FieldMatrix::size_type size_type;\n- 312 for(size_type row=0; row\n- 321 class EntryAccumulatorFather\n- 322 {\n- 323 public:\n-324 enum {do_break=false};\n-325 typedef BCRSMatrix,A> Matrix;\n-326 typedef typename Matrix::RowIterator Row;\n-327 typedef typename Matrix::ColIterator Col;\n- 328\n- 329 EntryAccumulatorFather(Matrix& mat_)\n- 330 : mat(mat_), row(mat.begin())\n- 331 {\n- 332 mat=0;\n- 333 col=row->begin();\n- 334 }\n- 335 void nextRow()\n- 336 {\n- 337 ++row;\n- 338 if(row!=mat.end())\n- 339 col=row->begin();\n- 340 }\n- 341\n- 342 void nextCol()\n- 343 {\n- 344 ++this->col;\n- 345 }\n- 346 protected:\n-347 Matrix& mat;\n- 348 private:\n- 349 Row row;\n- 350 protected:\n-351 Col col;\n- 352 };\n- 353\n- 354 template\n- 355 class EntryAccumulator\n- 356 : public EntryAccumulatorFather\n- 357 {\n- 358 public:\n-359 typedef BCRSMatrix,A> Matrix;\n-360 typedef typename Matrix::size_type size_type;\n- 361\n- 362 EntryAccumulator(Matrix& mat_)\n- 363 : EntryAccumulatorFather(mat_)\n- 364 {}\n- 365\n- 366 template\n- 367 void operator()(const T1& t1, const T2& t2, size_type i)\n- 368 {\n- 369 assert(this->col.index()==i);\n- 370 addMatMultMat(*(this->col),t1,t2);\n- 371 }\n- 372 };\n- 373\n- 374 template\n- 375 class EntryAccumulator\n- 376 : public EntryAccumulatorFather\n- 377 {\n- 378 public:\n-379 typedef BCRSMatrix,A> Matrix;\n-380 typedef typename Matrix::size_type size_type;\n- 381\n- 382 EntryAccumulator(Matrix& mat_)\n- 383 : EntryAccumulatorFather(mat_)\n- 384 {}\n- 385\n- 386 template\n- 387 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)\n- 388 {\n- 389 addMatMultMat(this->mat[i][j], t1, t2);\n- 390 }\n- 391 };\n- 392\n- 393 template\n- 394 class EntryAccumulator\n- 395 : public EntryAccumulatorFather\n- 396 {\n- 397 public:\n-398 typedef BCRSMatrix,A> Matrix;\n-399 typedef typename Matrix::size_type size_type;\n- 400\n- 401 EntryAccumulator(Matrix& mat_)\n- 402 : EntryAccumulatorFather(mat_)\n- 403 {}\n- 404\n- 405 template\n- 406 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)\n- 407 {\n- 408 addTransposeMatMultMat(this->mat[i][j], t1, t2);\n- 409 }\n- 410 };\n- 411\n- 412 template\n- 413 class EntryAccumulator\n- 414 : public EntryAccumulatorFather\n- 415 {\n- 416 public:\n-417 typedef BCRSMatrix,A> Matrix;\n-418 typedef typename Matrix::size_type size_type;\n- 419\n- 420 EntryAccumulator(Matrix& mat_)\n- 421 : EntryAccumulatorFather(mat_)\n- 422 {}\n- 423\n- 424 template\n- 425 void operator()(const T1& t1, const T2& t2, [[maybe_unused]] size_type i)\n- 426 {\n- 427 assert(this->col.index()==i);\n- 428 addMatMultTransposeMat(*this->col,t1,t2);\n- 429 }\n- 430 };\n- 431\n- 432\n- 433 template\n- 434 struct SizeSelector\n- 435 {};\n- 436\n- 437 template<>\n- 438 struct SizeSelector<0>\n- 439 {\n- 440 template\n- 441 static std::tuple\n- 442 size(const M1& m1, const M2& m2)\n- 443 {\n- 444 return std::make_tuple(m1.N(), m2.M());\n- 445 }\n- 446 };\n- 447\n- 448 template<>\n- 449 struct SizeSelector<1>\n- 450 {\n- 451 template\n- 452 static std::tuple\n- 453 size(const M1& m1, const M2& m2)\n- 454 {\n- 455 return std::make_tuple(m1.M(), m2.M());\n- 456 }\n- 457 };\n- 458\n- 459\n- 460 template<>\n- 461 struct SizeSelector<2>\n- 462 {\n- 463 template\n- 464 static std::tuple\n- 465 size(const M1& m1, const M2& m2)\n- 466 {\n- 467 return std::make_tuple(m1.N(), m2.N());\n- 468 }\n- 469 };\n- 470\n- 471 template\n- 472 void matMultMat(BCRSMatrix,A>& res, const\n-BCRSMatrix,A1>& mat1,\n- 473 const BCRSMatrix,A2>& mat2)\n- 474 {\n- 475 // First step is to count the number of nonzeros\n- 476 typename BCRSMatrix,A>::size_type rows, cols;\n- 477 std::tie(rows,cols)=SizeSelector::size(mat1, mat2);\n- 478 MatrixInitializer patternInit(res, rows);\n- 479 Timer timer;\n- 480 NonzeroPatternTraverser::traverse(mat1,mat2,patternInit);\n- 481 res.setSize(rows, cols, patternInit.nonzeros());\n- 482 res.setBuildMode(BCRSMatrix,A>::row_wise);\n- 483\n- 484 //std::cout<<\"Counting nonzeros took \"< entriesAccu(res);\n- 495 NonzeroPatternTraverser::traverse(mat1,mat2,entriesAccu);\n- 496 //std::cout<<\"Calculating entries took \"<\n-509 struct MatMultMatResult\n- 510 {};\n- 511\n- 512 template\n-513 struct MatMultMatResult,FieldMatrix >\n- 514 {\n-515 typedef FieldMatrix type;\n- 516 };\n- 517\n- 518 template\n-519 struct MatMultMatResult,A\n->,BCRSMatrix,A1 > >\n- 520 {\n- 521 typedef BCRSMatrix,FieldMatrix >::type,\n-522 std::allocator,FieldMatrix >::type> > type;\n- 523 };\n- 524\n- 525\n- 533 template\n-534 struct TransposedMatMultMatResult\n- 535 {};\n- 536\n- 537 template\n-538 struct TransposedMatMultMatResult,FieldMatrix >\n- 539 {\n-540 typedef FieldMatrix type;\n- 541 };\n- 542\n- 543 template\n-544 struct TransposedMatMultMatResult,A\n->,BCRSMatrix,A1 > >\n- 545 {\n- 546 typedef BCRSMatrix,FieldMatrix >::type,\n-547 std::allocator,FieldMatrix >::type> > type;\n- 548 };\n- 549\n- 550\n- 559 template\n-560 void matMultTransposeMat(BCRSMatrix,A>& res, const\n-BCRSMatrix,A1>& mat,\n- 561 const BCRSMatrix,A2>& matt, [[maybe_unused]] bool\n-tryHard=false)\n- 562 {\n- 563 matMultMat<2>(res,mat, matt);\n- 564 }\n- 565\n- 574 template\n-575 void matMultMat(BCRSMatrix,A>& res, const\n-BCRSMatrix,A1>& mat,\n- 576 const BCRSMatrix,A2>& matt, bool tryHard=false)\n- 577 {\n- 578 matMultMat<0>(res,mat, matt);\n- 579 }\n- 580\n- 589 template\n-590 void transposeMatMultMat(BCRSMatrix,A>& res, const\n-BCRSMatrix,A1>& mat,\n- 591 const BCRSMatrix,A2>& matt, [[maybe_unused]] bool\n-tryHard=false)\n- 592 {\n- 593 matMultMat<1>(res,mat, matt);\n- 594 }\n- 595\n- 596}\n- 597#endif\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-Dune::MatMultMatResult<_FieldMatrix<_T,_n,_k_>,_FieldMatrix<_T,_k,_m_>_>::type\n-FieldMatrix< T, n, m > type\n-Definition: matrixmatrix.hh:515\n-Dune::transposeMatMultMat\n-void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const\n-BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix<\n-T, k, m >, A2 > &matt, bool tryHard=false)\n-Calculate product of a transposed sparse matrix with another sparse matrices\n-( ).\n-Definition: matrixmatrix.hh:590\n-Dune::matMultMat\n-void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix<\n-FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2\n-> &matt, bool tryHard=false)\n-Calculate product of two sparse matrices ( ).\n-Definition: matrixmatrix.hh:575\n-Dune::EntryAccumulatorFather::Row\n-Matrix::RowIterator Row\n-Definition: matrixmatrix.hh:326\n-Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::Matrix\n-Dune::BCRSMatrix< Dune::FieldMatrix< T, n, m >, TA > Matrix\n-Definition: matrixmatrix.hh:228\n-Dune::EntryAccumulator::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:360\n-Dune::EntryAccumulator<_T,_A,_n,_m,_0_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:380\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n-Dune::EntryAccumulatorFather::Col\n-Matrix::ColIterator Col\n-Definition: matrixmatrix.hh:327\n-Dune::MatrixInitializer::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:188\n-Dune::EntryAccumulatorFather::col\n-Col col\n-Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::EntryAccumulatorFather::mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:230\n-Dune::TransposedMatMultMatResult<_FieldMatrix<_T,_k,_n_>,_FieldMatrix<_T,_k,_m\n->_>::type\n-FieldMatrix< T, n, m > type\n-Definition: matrixmatrix.hh:540\n-Dune::matMultTransposeMat\n-void matMultTransposeMat(BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const\n-BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix<\n-T, k, m >, A2 > &matt, bool tryHard=false)\n-Calculate product of a sparse matrix with a transposed sparse matrices ( ).\n-Definition: matrixmatrix.hh:560\n-Dune::MatrixInitializer::Matrix\n-Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix\n-Definition: matrixmatrix.hh:186\n-Dune::MatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_n,_k_>,_A_>,_BCRSMatrix<\n-FieldMatrix<_T,_k,_m_>,_A1_>_>::type\n-BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T,\n-k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k\n->, FieldMatrix< T, k, m > >::type > > type\n-Definition: matrixmatrix.hh:522\n-Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::CreateIterator\n-Matrix::CreateIterator CreateIterator\n-Definition: matrixmatrix.hh:229\n-Dune::EntryAccumulator<_T,_A,_n,_m,_1_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:399\n-Dune::MatrixInitializer::CreateIterator\n-Matrix::CreateIterator CreateIterator\n-Definition: matrixmatrix.hh:187\n-Dune::TransposedMatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_k,_n_>,_A_>,\n-BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>::type\n-BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T,\n-k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k\n->, FieldMatrix< T, k, m > >::type > > type\n-Definition: matrixmatrix.hh:547\n-Dune::EntryAccumulator<_T,_A,_n,_m,_2_>::size_type\n-Matrix::size_type size_type\n-Definition: matrixmatrix.hh:418\n-Dune::SparsityPatternInitializer::size_type\n-BCRSMatrix< FieldMatrix< T, n, m >, A >::size_type size_type\n-Definition: matrixmatrix.hh:157\n+170 SolverCategory::Category category() const override\n+ 171 {\n+ 172 return SolverCategory::sequential;\n+ 173 }\n+ 174\n+ 175 private:\n+ 176 const std::shared_ptr _A_;\n+ 177 };\n+ 178\n+ 181} // end namespace\n+ 182\n+ 183#endif\n+solvercategory.hh\n Dune\n Definition: allocator.hh:11\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::end\n-Iterator end()\n-Get iterator to one beyond last row.\n-Definition: bcrsmatrix.hh:681\n-Dune::BCRSMatrix::ColIterator\n-row_type::Iterator ColIterator\n-Iterator for the entries of each row.\n-Definition: bcrsmatrix.hh:704\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n-Dune::BCRSMatrix::createbegin\n-CreateIterator createbegin()\n-get initial create iterator\n-Definition: bcrsmatrix.hh:1097\n-Dune::BCRSMatrix::RealRowIterator\n-Iterator access to matrix rows\n-Definition: bcrsmatrix.hh:579\n-Dune::BCRSMatrix::CreateIterator\n-Iterator class for sequential creation of blocks\n-Definition: bcrsmatrix.hh:957\n-Dune::BCRSMatrix::CreateIterator::insert\n-void insert(size_type j)\n-put column index in row\n-Definition: bcrsmatrix.hh:1064\n-Dune::MatMultMatResult\n-Helper TMP to get the result type of a sparse matrix matrix multiplication ( )\n-Definition: matrixmatrix.hh:510\n-Dune::TransposedMatMultMatResult\n-Helper TMP to get the result type of a sparse matrix matrix multiplication ( )\n-Definition: matrixmatrix.hh:535\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n+Dune::LinearOperator\n+A linear operator.\n+Definition: operators.hh:67\n+Dune::LinearOperator::~LinearOperator\n+virtual ~LinearOperator()\n+every abstract base class has a virtual destructor\n+Definition: operators.hh:86\n+Dune::LinearOperator::field_type\n+X::field_type field_type\n+The field type of the operator.\n+Definition: operators.hh:74\n+Dune::LinearOperator::applyscaleadd\n+virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const =0\n+apply operator to x, scale and add:\n+Dune::LinearOperator::category\n+virtual SolverCategory::Category category() const =0\n+Category of the linear operator (see SolverCategory::Category)\n+Dune::LinearOperator::range_type\n+Y range_type\n+The type of the range of the operator.\n+Definition: operators.hh:72\n+Dune::LinearOperator::apply\n+virtual void apply(const X &x, Y &y) const =0\n+apply operator to x: The input vector is consistent and the output must also be\n+consistent on the in...\n+Dune::LinearOperator::domain_type\n+X domain_type\n+The type of the domain of the operator.\n+Definition: operators.hh:70\n+Dune::AssembledLinearOperator\n+A linear operator exporting itself in matrix form.\n+Definition: operators.hh:109\n+Dune::AssembledLinearOperator::getmat\n+virtual const M & getmat() const =0\n+get matrix via *\n+Dune::AssembledLinearOperator::domain_type\n+X domain_type\n+Definition: operators.hh:113\n+Dune::AssembledLinearOperator::field_type\n+X::field_type field_type\n+Definition: operators.hh:115\n+Dune::AssembledLinearOperator::range_type\n+Y range_type\n+Definition: operators.hh:114\n+Dune::AssembledLinearOperator::matrix_type\n+M matrix_type\n+export types, usually they come from the derived class\n+Definition: operators.hh:112\n+Dune::AssembledLinearOperator::~AssembledLinearOperator\n+virtual ~AssembledLinearOperator()\n+every abstract base class has a virtual destructor\n+Definition: operators.hh:121\n+Dune::MatrixAdapter\n+Adapter to turn a matrix into a linear operator.\n+Definition: operators.hh:137\n+Dune::MatrixAdapter::MatrixAdapter\n+MatrixAdapter(std::shared_ptr< const M > A)\n+constructor: store an std::shared_ptr to a matrix\n+Definition: operators.hh:149\n+Dune::MatrixAdapter::MatrixAdapter\n+MatrixAdapter(const M &A)\n+constructor: just store a reference to a matrix\n+Definition: operators.hh:146\n+Dune::MatrixAdapter::applyscaleadd\n+void applyscaleadd(field_type alpha, const X &x, Y &y) const override\n+apply operator to x, scale and add:\n+Definition: operators.hh:158\n+Dune::MatrixAdapter::range_type\n+Y range_type\n+Definition: operators.hh:142\n+Dune::MatrixAdapter::domain_type\n+X domain_type\n+Definition: operators.hh:141\n+Dune::MatrixAdapter::field_type\n+X::field_type field_type\n+Definition: operators.hh:143\n+Dune::MatrixAdapter::getmat\n+const M & getmat() const override\n+get matrix via *\n+Definition: operators.hh:164\n+Dune::MatrixAdapter::category\n+SolverCategory::Category category() const override\n+Category of the solver (see SolverCategory::Category)\n+Definition: operators.hh:170\n+Dune::MatrixAdapter::apply\n+void apply(const X &x, Y &y) const override\n+apply operator to x:\n+Definition: operators.hh:152\n+Dune::MatrixAdapter::matrix_type\n+M matrix_type\n+export types\n+Definition: operators.hh:140\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00083.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00083.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bccsmatrix.hh File Reference\n+dune-istl: multitypeblockvector.hh File Reference\n \n \n \n \n \n \n \n@@ -63,30 +63,58 @@\n
    \n \n
    \n
    \n
    \n \n-
    bccsmatrix.hh File Reference
    \n+Classes |\n+Namespaces |\n+Functions
    \n+
    multitypeblockvector.hh File Reference
    \n
    \n
    \n-
    #include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n+
    #include <cmath>
    \n+#include <iostream>
    \n+#include <tuple>
    \n+#include <dune/common/dotproduct.hh>
    \n+#include <dune/common/ftraits.hh>
    \n+#include <dune/common/hybridutilities.hh>
    \n #include <dune/common/typetraits.hh>
    \n+#include <dune/common/std/type_traits.hh>
    \n+#include "istlexception.hh"
    \n+#include "gsetc.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Classes

    struct  Dune::FieldTraits< MultiTypeBlockVector< Args... > >
     
    class  Dune::MultiTypeBlockVector< Args >
     A Vector class to support different block types. More...
     
    struct  std::tuple_element< i, Dune::MultiTypeBlockVector< Args... > >
     Make std::tuple_element work for MultiTypeBlockVector. More...
     
    \n \n \n \n-\n+\n+\n \n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::ISTL
    namespace  std
     STL namespace.
     
    \n+\n+\n+\n+\n+\n

    \n+Functions

    template<typename... Args>
    std::ostream & Dune::operator<< (std::ostream &s, const MultiTypeBlockVector< Args... > &v)
     Send MultiTypeBlockVector to an outstream. More...
     
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,21 +4,44 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Namespaces\n-bccsmatrix.hh File Reference\n-#include \n-#include \n+Classes | Namespaces | Functions\n+multitypeblockvector.hh File Reference\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n #include \n+#include \n+#include \"istlexception.hh\"\n+#include \"gsetc.hh\"\n Go_to_the_source_code_of_this_file.\n+ Classes\n+struct \u00a0Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>\n+\u00a0\n+ class \u00a0Dune::MultiTypeBlockVector<_Args_>\n+\u00a0 A Vector class to support different block types. More...\n+\u00a0\n+struct \u00a0std::tuple_element<_i,_Dune::MultiTypeBlockVector<_Args..._>_>\n+\u00a0 Make std::tuple_element work for MultiTypeBlockVector. More...\n+\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::ISTL\n+namespace \u00a0std\n+\u00a0 STL namespace.\n+\u00a0\n+ Functions\n+template\n+std::ostream &\u00a0Dune::operator<< (std::ostream &s, const MultiTypeBlockVector<\n+ Args... > &v)\n+\u00a0 Send MultiTypeBlockVector to an outstream. More...\n \u00a0\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00083_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00083_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bccsmatrix.hh Source File\n+dune-istl: multitypeblockvector.hh Source File\n \n \n \n \n \n \n \n@@ -62,129 +62,308 @@\n \n
    \n \n
    \n
    \n
    \n-
    bccsmatrix.hh
    \n+
    multitypeblockvector.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_BCCSMATRIX_HH
    \n-
    6#define DUNE_ISTL_BCCSMATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
    \n+
    6#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
    \n
    7
    \n-
    8#include <dune/common/fmatrix.hh>
    \n-
    9#include <dune/common/fvector.hh>
    \n-
    10#include <dune/common/typetraits.hh>
    \n+
    8#include <cmath>
    \n+
    9#include <iostream>
    \n+
    10#include <tuple>
    \n
    11
    \n-
    12namespace Dune::ISTL::Impl
    \n-
    13{
    \n-
    27 template<class B, class I = typename std::allocator<B>::size_type>
    \n-
    28 class BCCSMatrix
    \n-
    29 {
    \n-
    30 public:
    \n-
    31 using Index = I;
    \n-
    32 using size_type = std::size_t;
    \n-
    33
    \n-
    36 BCCSMatrix()
    \n-
    37 : N_(0), M_(0), Nnz_(0), values(0), rowindex(0), colstart(0)
    \n-
    38 {}
    \n-
    39
    \n-
    41 ~BCCSMatrix()
    \n-
    42 {
    \n-
    43 if(N_+M_+Nnz_!=0)
    \n-
    44 free();
    \n-
    45 }
    \n-
    46
    \n-
    48 void setSize(size_type rows, size_type columns)
    \n-
    49 {
    \n-
    50 N_ = rows;
    \n-
    51 M_ = columns;
    \n-
    52 }
    \n-
    53
    \n-
    58 size_type N() const
    \n-
    59 {
    \n-
    60 return N_;
    \n-
    61 }
    \n-
    62
    \n-
    64 size_type nonzeroes() const
    \n-
    65 {
    \n-
    66 return Nnz_;
    \n-
    67 }
    \n-
    68
    \n-
    73 size_type M() const
    \n-
    74 {
    \n-
    75 return M_;
    \n-
    76 }
    \n-
    77
    \n-
    84 B* getValues() const
    \n-
    85 {
    \n-
    86 return values;
    \n-
    87 }
    \n+
    12#include <dune/common/dotproduct.hh>
    \n+
    13#include <dune/common/ftraits.hh>
    \n+
    14#include <dune/common/hybridutilities.hh>
    \n+
    15#include <dune/common/typetraits.hh>
    \n+
    16#include <dune/common/std/type_traits.hh>
    \n+
    17
    \n+
    18#include "istlexception.hh"
    \n+
    19
    \n+
    20// forward declaration
    \n+
    21namespace Dune {
    \n+
    22 template < typename... Args >
    \n+
    23 class MultiTypeBlockVector;
    \n+
    24}
    \n+
    25
    \n+
    26#include "gsetc.hh"
    \n+
    27
    \n+
    28namespace Dune {
    \n+
    29
    \n+
    41 template <typename... Args>
    \n+
    42 struct FieldTraits< MultiTypeBlockVector<Args...> >
    \n+
    43 {
    \n+
    44 using field_type = typename MultiTypeBlockVector<Args...>::field_type;
    \n+
    45 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    46 };
    \n+
    56 template < typename... Args >
    \n+\n+
    58 : public std::tuple<Args...>
    \n+
    59 {
    \n+
    61 typedef std::tuple<Args...> TupleType;
    \n+
    62 public:
    \n+
    63
    \n+
    65 using size_type = std::size_t;
    \n+
    66
    \n+
    70 using TupleType::TupleType;
    \n+
    71
    \n+
    75 typedef MultiTypeBlockVector<Args...> type;
    \n+
    76
    \n+
    82 using field_type = Std::detected_t<std::common_type_t, typename FieldTraits< std::decay_t<Args> >::field_type...>;
    \n+
    83
    \n+
    84 // make sure that we have an std::common_type: using an assertion produces a more readable error message
    \n+
    85 // than a compiler template instantiation error
    \n+
    86 static_assert ( sizeof...(Args) == 0 or not std::is_same_v<field_type, Std::nonesuch>,
    \n+
    87 "No std::common_type implemented for the given field_types of the Args. Please provide an implementation and check that a FieldTraits class is present for your type.");
    \n
    88
    \n-
    95 Index* getRowIndex() const
    \n-
    96 {
    \n-
    97 return rowindex;
    \n+
    89
    \n+
    95 static constexpr size_type size()
    \n+
    96 {
    \n+
    97 return sizeof...(Args);
    \n
    98 }
    \n
    99
    \n-
    106 Index* getColStart() const
    \n-
    107 {
    \n-
    108 return colstart;
    \n-
    109 }
    \n-
    110
    \n-
    112 BCCSMatrix& operator=(const BCCSMatrix& mat)
    \n-
    113 {
    \n-
    114 if(N_+M_+Nnz_!=0)
    \n-
    115 free();
    \n-
    116 N_=mat.N_;
    \n-
    117 M_=mat.M_;
    \n-
    118 Nnz_= mat.Nnz_;
    \n-
    119 if(M_>0) {
    \n-
    120 colstart=new size_type[M_+1];
    \n-
    121 for(size_type i=0; i<=M_; ++i)
    \n-
    122 colstart[i]=mat.colstart[i];
    \n-
    123 }
    \n-
    124
    \n-
    125 if(Nnz_>0) {
    \n-
    126 values = new B[Nnz_];
    \n-
    127 rowindex = new size_type[Nnz_];
    \n+
    102 static constexpr size_type N()
    \n+
    103 {
    \n+
    104 return sizeof...(Args);
    \n+
    105 }
    \n+
    106
    \n+
    113 [[deprecated("Use method 'N' instead")]]
    \n+
    114 int count() const
    \n+
    115 {
    \n+
    116 return sizeof...(Args);
    \n+
    117 }
    \n+
    118
    \n+\n+
    121 {
    \n+
    122 size_type result = 0;
    \n+
    123 Hybrid::forEach(std::make_index_sequence<N()>{},
    \n+
    124 [&](auto i){result += std::get<i>(*this).dim();});
    \n+
    125
    \n+
    126 return result;
    \n+
    127 }
    \n
    128
    \n-
    129 for(size_type i=0; i<Nnz_; ++i)
    \n-
    130 values[i]=mat.values[i];
    \n-
    131
    \n-
    132 for(size_type i=0; i<Nnz_; ++i)
    \n-
    133 rowindex[i]=mat.rowindex[i];
    \n-
    134 }
    \n-
    135 return *this;
    \n-
    136 }
    \n-
    137
    \n-
    139 virtual void free()
    \n-
    140 {
    \n-
    141 delete[] values;
    \n-
    142 delete[] rowindex;
    \n-
    143 delete[] colstart;
    \n-
    144 N_ = 0;
    \n-
    145 M_ = 0;
    \n-
    146 Nnz_ = 0;
    \n-
    147 }
    \n-
    148
    \n-
    149 public:
    \n-
    150 size_type N_, M_, Nnz_;
    \n-
    151 B* values;
    \n-
    152 Index* rowindex;
    \n-
    153 Index* colstart;
    \n-
    154 };
    \n-
    155
    \n-
    156}
    \n-
    157#endif
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    147 template< size_type index >
    \n+
    148 typename std::tuple_element<index,TupleType>::type&
    \n+
    149 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable)
    \n+
    150 {
    \n+
    151 return std::get<index>(*this);
    \n+
    152 }
    \n+
    153
    \n+
    159 template< size_type index >
    \n+
    160 const typename std::tuple_element<index,TupleType>::type&
    \n+
    161 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable) const
    \n+
    162 {
    \n+
    163 return std::get<index>(*this);
    \n+
    164 }
    \n+
    165
    \n+
    168 template<typename T>
    \n+
    169 void operator= (const T& newval) {
    \n+
    170 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
    \n+
    171 entry = newval;
    \n+
    172 });
    \n+
    173 }
    \n+
    174
    \n+
    178 void operator+= (const type& newv) {
    \n+
    179 using namespace Dune::Hybrid;
    \n+
    180 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n+
    181 (*this)[i] += newv[i];
    \n+
    182 });
    \n+
    183 }
    \n+
    184
    \n+
    188 void operator-= (const type& newv) {
    \n+
    189 using namespace Dune::Hybrid;
    \n+
    190 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n+
    191 (*this)[i] -= newv[i];
    \n+
    192 });
    \n+
    193 }
    \n+
    194
    \n+
    196 template<class T,
    \n+
    197 std::enable_if_t< IsNumber<T>::value, int> = 0>
    \n+
    198 void operator*= (const T& w) {
    \n+
    199 Hybrid::forEach(*this, [&](auto&& entry) {
    \n+
    200 entry *= w;
    \n+
    201 });
    \n+
    202 }
    \n+
    203
    \n+
    205 template<class T,
    \n+
    206 std::enable_if_t< IsNumber<T>::value, int> = 0>
    \n+
    207 void operator/= (const T& w) {
    \n+
    208 Hybrid::forEach(*this, [&](auto&& entry) {
    \n+
    209 entry /= w;
    \n+
    210 });
    \n+
    211 }
    \n+
    212
    \n+
    213 field_type operator* (const type& newv) const {
    \n+
    214 using namespace Dune::Hybrid;
    \n+
    215 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
    \n+
    216 return a + (*this)[i]*newv[i];
    \n+
    217 });
    \n+
    218 }
    \n+
    219
    \n+
    220 field_type dot (const type& newv) const {
    \n+
    221 using namespace Dune::Hybrid;
    \n+
    222 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
    \n+
    223 return a + (*this)[i].dot(newv[i]);
    \n+
    224 });
    \n+
    225 }
    \n+
    226
    \n+
    229 auto one_norm() const {
    \n+
    230 using namespace Dune::Hybrid;
    \n+
    231 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n+
    232 return a + entry.one_norm();
    \n+
    233 });
    \n+
    234 }
    \n+
    235
    \n+
    238 auto one_norm_real() const {
    \n+
    239 using namespace Dune::Hybrid;
    \n+
    240 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n+
    241 return a + entry.one_norm_real();
    \n+
    242 });
    \n+
    243 }
    \n+
    244
    \n+
    247 typename FieldTraits<field_type>::real_type two_norm2() const {
    \n+
    248 using namespace Dune::Hybrid;
    \n+
    249 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n+
    250 return a + entry.two_norm2();
    \n+
    251 });
    \n+
    252 }
    \n+
    253
    \n+
    256 typename FieldTraits<field_type>::real_type two_norm() const {return sqrt(this->two_norm2());}
    \n+
    257
    \n+
    260 typename FieldTraits<field_type>::real_type infinity_norm() const
    \n+
    261 {
    \n+
    262 using namespace Dune::Hybrid;
    \n+
    263 using std::max;
    \n+
    264 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    265
    \n+
    266 real_type result = 0.0;
    \n+
    267 // Compute max norm tracking appearing nan values
    \n+
    268 // if the field type supports nan.
    \n+
    269 if constexpr (HasNaN<field_type>()) {
    \n+
    270 // This variable will preserve any nan value
    \n+
    271 real_type nanTracker = 1.0;
    \n+
    272 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    273 forEach(*this, [&](auto&& entry) {
    \n+
    274 real_type entryNorm = entry.infinity_norm();
    \n+
    275 result = max(entryNorm, result);
    \n+
    276 nanTracker += entryNorm;
    \n+
    277 });
    \n+
    278 // Incorporate possible nan value into result
    \n+
    279 result *= (nanTracker / nanTracker);
    \n+
    280 } else {
    \n+
    281 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    282 forEach(*this, [&](auto&& entry) {
    \n+
    283 result = max(entry.infinity_norm(), result);
    \n+
    284 });
    \n+
    285 }
    \n+
    286 return result;
    \n+
    287 }
    \n+
    288
    \n+
    291 typename FieldTraits<field_type>::real_type infinity_norm_real() const
    \n+
    292 {
    \n+
    293 using namespace Dune::Hybrid;
    \n+
    294 using std::max;
    \n+
    295 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    296
    \n+
    297 real_type result = 0.0;
    \n+
    298 // Compute max norm tracking appearing nan values
    \n+
    299 // if the field type supports nan.
    \n+
    300 if constexpr (HasNaN<field_type>()) {
    \n+
    301 // This variable will preserve any nan value
    \n+
    302 real_type nanTracker = 1.0;
    \n+
    303 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    304 forEach(*this, [&](auto&& entry) {
    \n+
    305 real_type entryNorm = entry.infinity_norm_real();
    \n+
    306 result = max(entryNorm, result);
    \n+
    307 nanTracker += entryNorm;
    \n+
    308 });
    \n+
    309 // Incorporate possible nan value into result
    \n+
    310 result *= (nanTracker / nanTracker);
    \n+
    311 } else {
    \n+
    312 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    313 forEach(*this, [&](auto&& entry) {
    \n+
    314 result = max(entry.infinity_norm_real(), result);
    \n+
    315 });
    \n+
    316 }
    \n+
    317 return result;
    \n+
    318 }
    \n+
    319
    \n+
    324 template<typename Ta>
    \n+
    325 void axpy (const Ta& a, const type& y) {
    \n+
    326 using namespace Dune::Hybrid;
    \n+
    327 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n+
    328 (*this)[i].axpy(a, y[i]);
    \n+
    329 });
    \n+
    330 }
    \n+
    331
    \n+
    332 };
    \n+
    333
    \n+
    334
    \n+
    335
    \n+
    338 template <typename... Args>
    \n+
    339 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockVector<Args...>& v) {
    \n+
    340 using namespace Dune::Hybrid;
    \n+
    341 forEach(integralRange(Dune::Hybrid::size(v)), [&](auto&& i) {
    \n+
    342 s << "\\t(" << i << "):\\n" << v[i] << "\\n";
    \n+
    343 });
    \n+
    344 return s;
    \n+
    345 }
    \n+
    346
    \n+
    347} // end namespace Dune
    \n+
    348
    \n+
    349namespace std
    \n+
    350{
    \n+
    355 template <size_t i, typename... Args>
    \n+
    356 struct tuple_element<i,Dune::MultiTypeBlockVector<Args...> >
    \n+
    357 {
    \n+
    358 using type = typename std::tuple_element<i, std::tuple<Args...> >::type;
    \n+
    359 };
    \n+
    360}
    \n+
    361
    \n+
    362#endif
    \n+\n+
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    void operator=(const T &newval)
    Assignment operator.
    Definition: multitypeblockvector.hh:169
    \n+
    std::size_t size_type
    Type used for vector sizes.
    Definition: multitypeblockvector.hh:65
    \n+
    typename FieldTraits< field_type >::real_type real_type
    Definition: multitypeblockvector.hh:45
    \n+
    int count() const
    Definition: multitypeblockvector.hh:114
    \n+
    static constexpr size_type N()
    Number of elements.
    Definition: multitypeblockvector.hh:102
    \n+
    Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args > >::field_type... > field_type
    The type used for scalars.
    Definition: multitypeblockvector.hh:82
    \n+
    static constexpr size_type size()
    Return the number of non-zero vector entries.
    Definition: multitypeblockvector.hh:95
    \n+
    std::tuple_element< index, TupleType >::type & operator[](const std::integral_constant< size_type, index > indexVariable)
    Random-access operator.
    Definition: multitypeblockvector.hh:149
    \n+
    FieldTraits< field_type >::real_type two_norm() const
    Compute the Euclidean norm.
    Definition: multitypeblockvector.hh:256
    \n+
    typename MultiTypeBlockVector< Args... >::field_type field_type
    Definition: multitypeblockvector.hh:44
    \n+
    size_type dim() const
    Number of scalar elements.
    Definition: multitypeblockvector.hh:120
    \n+
    field_type dot(const type &newv) const
    Definition: multitypeblockvector.hh:220
    \n+
    void operator*=(const T &w)
    Multiplication with a scalar.
    Definition: multitypeblockvector.hh:198
    \n+
    void axpy(const Ta &a, const type &y)
    Axpy operation on this vector (*this += a * y)
    Definition: multitypeblockvector.hh:325
    \n+
    void operator/=(const T &w)
    Division by a scalar.
    Definition: multitypeblockvector.hh:207
    \n+
    MultiTypeBlockVector< Args... > type
    Definition: multitypeblockvector.hh:75
    \n+
    FieldTraits< field_type >::real_type infinity_norm_real() const
    Compute the simplified maximum norm (uses 1-norm for complex values)
    Definition: multitypeblockvector.hh:291
    \n+
    auto one_norm() const
    Compute the 1-norm.
    Definition: multitypeblockvector.hh:229
    \n+
    void operator-=(const type &newv)
    Definition: multitypeblockvector.hh:188
    \n+
    field_type operator*(const type &newv) const
    Definition: multitypeblockvector.hh:213
    \n+
    void operator+=(const type &newv)
    Definition: multitypeblockvector.hh:178
    \n+
    typename std::tuple_element< i, std::tuple< Args... > >::type type
    Definition: multitypeblockvector.hh:358
    \n+
    FieldTraits< field_type >::real_type infinity_norm() const
    Compute the maximum norm.
    Definition: multitypeblockvector.hh:260
    \n+
    auto one_norm_real() const
    Compute the simplified 1-norm (uses 1-norm also for complex values)
    Definition: multitypeblockvector.hh:238
    \n+
    FieldTraits< field_type >::real_type two_norm2() const
    Compute the squared Euclidean norm.
    Definition: multitypeblockvector.hh:247
    \n+
    STL namespace.
    \n+
    Definition: allocator.hh:11
    \n+
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n+
    A Vector class to support different block types.
    Definition: multitypeblockvector.hh:59
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,127 +4,395 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-bccsmatrix.hh\n+multitypeblockvector.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_BCCSMATRIX_HH\n- 6#define DUNE_ISTL_BCCSMATRIX_HH\n+ 5#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH\n+ 6#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n+ 8#include \n+ 9#include \n+ 10#include \n 11\n-12namespace Dune::ISTL::Impl\n- 13{\n- 27 template::size_type>\n- 28 class BCCSMatrix\n- 29 {\n- 30 public:\n- 31 using Index = I;\n- 32 using size_type = std::size_t;\n- 33\n- 36 BCCSMatrix()\n- 37 : N_(0), M_(0), Nnz_(0), values(0), rowindex(0), colstart(0)\n- 38 {}\n- 39\n- 41 ~BCCSMatrix()\n- 42 {\n- 43 if(N_+M_+Nnz_!=0)\n- 44 free();\n- 45 }\n- 46\n- 48 void setSize(size_type rows, size_type columns)\n- 49 {\n- 50 N_ = rows;\n- 51 M_ = columns;\n- 52 }\n- 53\n- 58 size_type N() const\n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17\n+ 18#include \"istlexception.hh\"\n+ 19\n+ 20// forward declaration\n+ 21namespace Dune {\n+ 22 template < typename... Args >\n+ 23 class MultiTypeBlockVector;\n+ 24}\n+ 25\n+ 26#include \"gsetc.hh\"\n+ 27\n+ 28namespace Dune {\n+ 29\n+ 41 template \n+42 struct FieldTraits< MultiTypeBlockVector >\n+ 43 {\n+44 using field_type = typename MultiTypeBlockVector::field_type;\n+45 using real_type = typename FieldTraits::real_type;\n+ 46 };\n+ 56 template < typename... Args >\n+57 class MultiTypeBlockVector\n+ 58 : public std::tuple\n 59 {\n- 60 return N_;\n- 61 }\n- 62\n- 64 size_type nonzeroes() const\n- 65 {\n- 66 return Nnz_;\n- 67 }\n- 68\n- 73 size_type M() const\n- 74 {\n- 75 return M_;\n- 76 }\n- 77\n- 84 B* getValues() const\n- 85 {\n- 86 return values;\n- 87 }\n+ 61 typedef std::tuple TupleType;\n+ 62 public:\n+ 63\n+65 using size_type = std::size_t;\n+ 66\n+ 70 using TupleType::TupleType;\n+ 71\n+75 typedef MultiTypeBlockVector type;\n+ 76\n+82 using field_type = Std::detected_t >::field_type...>;\n+ 83\n+ 84 // make sure that we have an std::common_type: using an assertion produces\n+a more readable error message\n+ 85 // than a compiler template instantiation error\n+ 86 static_assert ( sizeof...(Args) == 0 or not std::is_same_v,\n+ 87 \"No std::common_type implemented for the given field_types of the Args.\n+Please provide an implementation and check that a FieldTraits class is present\n+for your type.\");\n 88\n- 95 Index* getRowIndex() const\n+ 89\n+95 static constexpr size_type size()\n 96 {\n- 97 return rowindex;\n+ 97 return sizeof...(Args);\n 98 }\n 99\n- 106 Index* getColStart() const\n- 107 {\n- 108 return colstart;\n- 109 }\n- 110\n- 112 BCCSMatrix& operator=(const BCCSMatrix& mat)\n- 113 {\n- 114 if(N_+M_+Nnz_!=0)\n- 115 free();\n- 116 N_=mat.N_;\n- 117 M_=mat.M_;\n- 118 Nnz_= mat.Nnz_;\n- 119 if(M_>0) {\n- 120 colstart=new size_type[M_+1];\n- 121 for(size_type i=0; i<=M_; ++i)\n- 122 colstart[i]=mat.colstart[i];\n- 123 }\n- 124\n- 125 if(Nnz_>0) {\n- 126 values = new B[Nnz_];\n- 127 rowindex = new size_type[Nnz_];\n+102 static constexpr size_type N()\n+ 103 {\n+ 104 return sizeof...(Args);\n+ 105 }\n+ 106\n+ 113 [[deprecated(\"Use method 'N' instead\")]]\n+114 int count() const\n+ 115 {\n+ 116 return sizeof...(Args);\n+ 117 }\n+ 118\n+120 size_type dim() const\n+ 121 {\n+ 122 size_type result = 0;\n+ 123 Hybrid::forEach(std::make_index_sequence{},\n+ 124 [&](auto i){result += std::get(*this).dim();});\n+ 125\n+ 126 return result;\n+ 127 }\n 128\n- 129 for(size_type i=0; i\n+ 148 typename std::tuple_element::type&\n+149 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n+> indexVariable)\n+ 150 {\n+ 151 return std::get(*this);\n+ 152 }\n+ 153\n+ 159 template< size_type index >\n+ 160 const typename std::tuple_element::type&\n+161 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n+> indexVariable) const\n+ 162 {\n+ 163 return std::get(*this);\n+ 164 }\n+ 165\n+ 168 template\n+169 void operator=(const T& newval) {\n+ 170 Dune::Hybrid::forEach(*this, [&](auto&& entry) {\n+ 171 entry = newval;\n+ 172 });\n+ 173 }\n+ 174\n+178 void operator+=(const type& newv) {\n+ 179 using namespace Dune::Hybrid;\n+ 180 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n+ 181 (*this)[i] += newv[i];\n+ 182 });\n+ 183 }\n+ 184\n+188 void operator-=(const type& newv) {\n+ 189 using namespace Dune::Hybrid;\n+ 190 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n+ 191 (*this)[i] -= newv[i];\n+ 192 });\n+ 193 }\n+ 194\n+ 196 template::value, int> = 0>\n+198 void operator*=(const T& w) {\n+ 199 Hybrid::forEach(*this, [&](auto&& entry) {\n+ 200 entry *= w;\n+ 201 });\n+ 202 }\n+ 203\n+ 205 template::value, int> = 0>\n+207 void operator/=(const T& w) {\n+ 208 Hybrid::forEach(*this, [&](auto&& entry) {\n+ 209 entry /= w;\n+ 210 });\n+ 211 }\n+ 212\n+213 field_type operator*(const type& newv) const {\n+ 214 using namespace Dune::Hybrid;\n+ 215 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&]\n+(auto&& a, auto&& i) {\n+ 216 return a + (*this)[i]*newv[i];\n+ 217 });\n+ 218 }\n+ 219\n+220 field_type dot (const type& newv) const {\n+ 221 using namespace Dune::Hybrid;\n+ 222 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&]\n+(auto&& a, auto&& i) {\n+ 223 return a + (*this)[i].dot(newv[i]);\n+ 224 });\n+ 225 }\n+ 226\n+229 auto one_norm() const {\n+ 230 using namespace Dune::Hybrid;\n+ 231 return accumulate(*this, typename FieldTraits::real_type(0),\n+[&](auto&& a, auto&& entry) {\n+ 232 return a + entry.one_norm();\n+ 233 });\n+ 234 }\n+ 235\n+238 auto one_norm_real() const {\n+ 239 using namespace Dune::Hybrid;\n+ 240 return accumulate(*this, typename FieldTraits::real_type(0),\n+[&](auto&& a, auto&& entry) {\n+ 241 return a + entry.one_norm_real();\n+ 242 });\n+ 243 }\n+ 244\n+247 typename FieldTraits::real_type two_norm2() const {\n+ 248 using namespace Dune::Hybrid;\n+ 249 return accumulate(*this, typename FieldTraits::real_type(0),\n+[&](auto&& a, auto&& entry) {\n+ 250 return a + entry.two_norm2();\n+ 251 });\n+ 252 }\n+ 253\n+256 typename FieldTraits::real_type two_norm() const {return sqrt\n+(this->two_norm2());}\n+ 257\n+260 typename FieldTraits::real_type infinity_norm() const\n+ 261 {\n+ 262 using namespace Dune::Hybrid;\n+ 263 using std::max;\n+ 264 using real_type = typename FieldTraits::real_type;\n+ 265\n+ 266 real_type result = 0.0;\n+ 267 // Compute max norm tracking appearing nan values\n+ 268 // if the field type supports nan.\n+ 269 if constexpr (HasNaN()) {\n+ 270 // This variable will preserve any nan value\n+ 271 real_type nanTracker = 1.0;\n+ 272 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 273 forEach(*this, [&](auto&& entry) {\n+ 274 real_type entryNorm = entry.infinity_norm();\n+ 275 result = max(entryNorm, result);\n+ 276 nanTracker += entryNorm;\n+ 277 });\n+ 278 // Incorporate possible nan value into result\n+ 279 result *= (nanTracker / nanTracker);\n+ 280 } else {\n+ 281 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 282 forEach(*this, [&](auto&& entry) {\n+ 283 result = max(entry.infinity_norm(), result);\n+ 284 });\n+ 285 }\n+ 286 return result;\n+ 287 }\n+ 288\n+291 typename FieldTraits::real_type infinity_norm_real() const\n+ 292 {\n+ 293 using namespace Dune::Hybrid;\n+ 294 using std::max;\n+ 295 using real_type = typename FieldTraits::real_type;\n+ 296\n+ 297 real_type result = 0.0;\n+ 298 // Compute max norm tracking appearing nan values\n+ 299 // if the field type supports nan.\n+ 300 if constexpr (HasNaN()) {\n+ 301 // This variable will preserve any nan value\n+ 302 real_type nanTracker = 1.0;\n+ 303 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 304 forEach(*this, [&](auto&& entry) {\n+ 305 real_type entryNorm = entry.infinity_norm_real();\n+ 306 result = max(entryNorm, result);\n+ 307 nanTracker += entryNorm;\n+ 308 });\n+ 309 // Incorporate possible nan value into result\n+ 310 result *= (nanTracker / nanTracker);\n+ 311 } else {\n+ 312 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 313 forEach(*this, [&](auto&& entry) {\n+ 314 result = max(entry.infinity_norm_real(), result);\n+ 315 });\n+ 316 }\n+ 317 return result;\n+ 318 }\n+ 319\n+ 324 template\n+325 void axpy (const Ta& a, const type& y) {\n+ 326 using namespace Dune::Hybrid;\n+ 327 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n+ 328 (*this)[i].axpy(a, y[i]);\n+ 329 });\n+ 330 }\n+ 331\n+ 332 };\n+ 333\n+ 334\n+ 335\n+ 338 template \n+339 std::ostream& operator<<(std::ostream& s, const\n+MultiTypeBlockVector& v) {\n+ 340 using namespace Dune::Hybrid;\n+ 341 forEach(integralRange(Dune::Hybrid::size(v)), [&](auto&& i) {\n+ 342 s << \"\\t(\" << i << \"):\\n\" << v[i] << \"\\n\";\n+ 343 });\n+ 344 return s;\n+ 345 }\n+ 346\n+ 347} // end namespace Dune\n+ 348\n+ 349namespace std\n+ 350{\n+ 355 template \n+356 struct tuple_element >\n+ 357 {\n+358 using type = typename std::tuple_element >::type;\n+ 359 };\n+ 360}\n+ 361\n+ 362#endif\n+istlexception.hh\n+gsetc.hh\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way.\n+Dune::MultiTypeBlockVector::operator=\n+void operator=(const T &newval)\n+Assignment operator.\n+Definition: multitypeblockvector.hh:169\n+Dune::MultiTypeBlockVector::size_type\n+std::size_t size_type\n+Type used for vector sizes.\n+Definition: multitypeblockvector.hh:65\n+Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>::real_type\n+typename FieldTraits< field_type >::real_type real_type\n+Definition: multitypeblockvector.hh:45\n+Dune::MultiTypeBlockVector::count\n+int count() const\n+Definition: multitypeblockvector.hh:114\n+Dune::MultiTypeBlockVector::N\n+static constexpr size_type N()\n+Number of elements.\n+Definition: multitypeblockvector.hh:102\n+Dune::MultiTypeBlockVector::field_type\n+Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args >\n+>::field_type... > field_type\n+The type used for scalars.\n+Definition: multitypeblockvector.hh:82\n+Dune::MultiTypeBlockVector::size\n+static constexpr size_type size()\n+Return the number of non-zero vector entries.\n+Definition: multitypeblockvector.hh:95\n+Dune::MultiTypeBlockVector::operator[]\n+std::tuple_element< index, TupleType >::type & operator[](const std::\n+integral_constant< size_type, index > indexVariable)\n+Random-access operator.\n+Definition: multitypeblockvector.hh:149\n+Dune::MultiTypeBlockVector::two_norm\n+FieldTraits< field_type >::real_type two_norm() const\n+Compute the Euclidean norm.\n+Definition: multitypeblockvector.hh:256\n+Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>::field_type\n+typename MultiTypeBlockVector< Args... >::field_type field_type\n+Definition: multitypeblockvector.hh:44\n+Dune::MultiTypeBlockVector::dim\n+size_type dim() const\n+Number of scalar elements.\n+Definition: multitypeblockvector.hh:120\n+Dune::MultiTypeBlockVector::dot\n+field_type dot(const type &newv) const\n+Definition: multitypeblockvector.hh:220\n+Dune::MultiTypeBlockVector::operator*=\n+void operator*=(const T &w)\n+Multiplication with a scalar.\n+Definition: multitypeblockvector.hh:198\n+Dune::MultiTypeBlockVector::axpy\n+void axpy(const Ta &a, const type &y)\n+Axpy operation on this vector (*this += a * y)\n+Definition: multitypeblockvector.hh:325\n+Dune::MultiTypeBlockVector::operator/=\n+void operator/=(const T &w)\n+Division by a scalar.\n+Definition: multitypeblockvector.hh:207\n+Dune::MultiTypeBlockVector::type\n+MultiTypeBlockVector< Args... > type\n+Definition: multitypeblockvector.hh:75\n+Dune::MultiTypeBlockVector::infinity_norm_real\n+FieldTraits< field_type >::real_type infinity_norm_real() const\n+Compute the simplified maximum norm (uses 1-norm for complex values)\n+Definition: multitypeblockvector.hh:291\n+Dune::MultiTypeBlockVector::one_norm\n+auto one_norm() const\n+Compute the 1-norm.\n+Definition: multitypeblockvector.hh:229\n+Dune::MultiTypeBlockVector::operator-=\n+void operator-=(const type &newv)\n+Definition: multitypeblockvector.hh:188\n+Dune::MultiTypeBlockVector::operator*\n+field_type operator*(const type &newv) const\n+Definition: multitypeblockvector.hh:213\n+Dune::MultiTypeBlockVector::operator+=\n+void operator+=(const type &newv)\n+Definition: multitypeblockvector.hh:178\n+std::tuple_element<_i,_Dune::MultiTypeBlockVector<_Args..._>_>::type\n+typename std::tuple_element< i, std::tuple< Args... > >::type type\n+Definition: multitypeblockvector.hh:358\n+Dune::MultiTypeBlockVector::infinity_norm\n+FieldTraits< field_type >::real_type infinity_norm() const\n+Compute the maximum norm.\n+Definition: multitypeblockvector.hh:260\n+Dune::MultiTypeBlockVector::one_norm_real\n+auto one_norm_real() const\n+Compute the simplified 1-norm (uses 1-norm also for complex values)\n+Definition: multitypeblockvector.hh:238\n+Dune::MultiTypeBlockVector::two_norm2\n+FieldTraits< field_type >::real_type two_norm2() const\n+Compute the squared Euclidean norm.\n+Definition: multitypeblockvector.hh:247\n+std\n+STL namespace.\n+Dune\n+Definition: allocator.hh:11\n+Dune::operator<<\n+std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n+Send BlockVector to an output stream.\n+Definition: bvector.hh:590\n+Dune::MultiTypeBlockVector\n+A Vector class to support different block types.\n+Definition: multitypeblockvector.hh:59\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00086.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00086.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: allocator.hh File Reference\n+dune-istl: basearray.hh File Reference\n \n \n \n \n \n \n \n@@ -63,51 +63,38 @@\n
    \n \n
    \n
    \n
    \n \n-
    allocator.hh File Reference
    \n+Namespaces
    \n+
    basearray.hh File Reference
    \n
    \n
    \n-
    #include <memory>
    \n-#include <type_traits>
    \n-#include <dune/common/typetraits.hh>
    \n+\n+

    Implements several basic array containers. \n+More...

    \n+
    #include "assert.h"
    \n+#include <cmath>
    \n+#include <cstddef>
    \n+#include <memory>
    \n+#include <algorithm>
    \n+#include "istlexception.hh"
    \n+#include <dune/common/iteratorfacades.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    struct  Dune::exists< T >
     
    struct  Dune::DefaultAllocatorTraits< T, typename >
     
    struct  Dune::DefaultAllocatorTraits< T, std::void_t< typename T::allocator_type > >
     
    struct  Dune::AllocatorTraits< T >
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n

    \n-Typedefs

    template<typename T >
    using Dune::AllocatorType = typename AllocatorTraits< T >::type
     
    template<typename T , typename X >
    using Dune::ReboundAllocatorType = typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X >
     
    \n-
    \n+

    Detailed Description

    \n+

    Implements several basic array containers.

    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,37 +4,26 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Typedefs\n-allocator.hh File Reference\n+Namespaces\n+basearray.hh File Reference\n+Implements several basic array containers. More...\n+#include \"assert.h\"\n+#include \n+#include \n #include \n-#include \n-#include \n+#include \n+#include \"istlexception.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n- Classes\n-struct \u00a0Dune::exists<_T_>\n-\u00a0\n-struct \u00a0Dune::DefaultAllocatorTraits<_T,_typename_>\n-\u00a0\n-struct \u00a0Dune::DefaultAllocatorTraits<_T,_std::void_t<_typename_T::\n- allocator_type_>_>\n-\u00a0\n-struct \u00a0Dune::AllocatorTraits<_T_>\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Typedefs\n-template\n-using\u00a0Dune::AllocatorType = typename AllocatorTraits< T >::type\n-\u00a0\n-template\n-using\u00a0Dune::ReboundAllocatorType = typename std::allocator_traits< typename\n- AllocatorTraits< T >::type >::template rebind_alloc< X >\n-\u00a0\n+***** Detailed Description *****\n+Implements several basic array containers.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00086_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00086_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: allocator.hh Source File\n+dune-istl: basearray.hh Source File\n \n \n \n \n \n \n \n@@ -62,68 +62,427 @@\n \n
    \n \n
    \n
    \n
    \n-
    allocator.hh
    \n+
    basearray.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3#ifndef DUNE_ISTL_ALLOCATOR_HH
    \n-
    4#define DUNE_ISTL_ALLOCATOR_HH
    \n-
    5
    \n-
    6#include <memory>
    \n-
    7#include <type_traits>
    \n-
    8
    \n-
    9#include <dune/common/typetraits.hh>
    \n-
    10
    \n-
    11namespace Dune {
    \n-
    12
    \n-
    13 template<typename T>
    \n-
    14 struct exists{
    \n-
    15 static const bool value = true;
    \n-
    16 };
    \n-
    17
    \n-
    18 template<typename T, typename = void>
    \n-\n-
    20 {
    \n-
    21 using type = std::allocator<T>;
    \n-
    22 };
    \n-
    23
    \n-
    24 template<typename T>
    \n-
    25 struct DefaultAllocatorTraits<T, std::void_t<typename T::allocator_type> >
    \n-
    26 {
    \n-
    27 using type = typename T::allocator_type;
    \n-
    28 };
    \n-
    29
    \n-
    30 template<typename T>
    \n-\n-
    32
    \n-
    33 template<typename T>
    \n-\n-
    35
    \n-
    36 template<typename T, typename X>
    \n-
    37 using ReboundAllocatorType = typename std::allocator_traits<typename AllocatorTraits<T>::type>::template rebind_alloc<X>;
    \n-
    38
    \n-
    39} // end namespace Dune
    \n-
    40
    \n-
    41#endif // DUNE_ISTL_ALLOCATOR_HH
    \n-
    STL namespace.
    \n+
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n+
    4// vi: set et ts=4 sw=2 sts=2:
    \n+
    5#ifndef DUNE_ISTL_BASEARRAY_HH
    \n+
    6#define DUNE_ISTL_BASEARRAY_HH
    \n+
    7
    \n+
    8#include "assert.h"
    \n+
    9#include <cmath>
    \n+
    10#include <cstddef>
    \n+
    11#include <memory>
    \n+
    12#include <algorithm>
    \n+
    13
    \n+
    14#include "istlexception.hh"
    \n+
    15#include <dune/common/iteratorfacades.hh>
    \n+
    16
    \n+
    21namespace Dune {
    \n+
    22
    \n+
    24namespace Imp {
    \n+
    25
    \n+
    50 template<class B, class A=std::allocator<B> >
    \n+
    51 class base_array_unmanaged
    \n+
    52 {
    \n+
    53 public:
    \n+
    54
    \n+
    55 //===== type definitions and constants
    \n+
    56
    \n+
    58 typedef B member_type;
    \n+
    59
    \n+
    61 typedef A allocator_type;
    \n+
    62
    \n+
    64 typedef typename A::size_type size_type;
    \n+
    65
    \n+
    67 using reference = B&;
    \n+
    68
    \n+
    70 using const_reference = const B&;
    \n+
    71
    \n+
    72 //===== access to components
    \n+
    73
    \n+
    75 reference operator[] (size_type i)
    \n+
    76 {
    \n+
    77#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    78 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
    \n+
    79#endif
    \n+
    80 return p[i];
    \n+
    81 }
    \n+
    82
    \n+
    84 const_reference operator[] (size_type i) const
    \n+
    85 {
    \n+
    86#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    87 if (i>=n) DUNE_THROW(ISTLError,"index out of range");
    \n+
    88#endif
    \n+
    89 return p[i];
    \n+
    90 }
    \n+
    91
    \n+
    93 template<class T>
    \n+
    94 class RealIterator
    \n+
    95 : public RandomAccessIteratorFacade<RealIterator<T>, T>
    \n+
    96 {
    \n+
    97 public:
    \n+
    99 typedef typename std::remove_const<T>::type ValueType;
    \n+
    100
    \n+
    101 friend class RandomAccessIteratorFacade<RealIterator<const ValueType>, const ValueType>;
    \n+
    102 friend class RandomAccessIteratorFacade<RealIterator<ValueType>, ValueType>;
    \n+
    103 friend class RealIterator<const ValueType>;
    \n+
    104 friend class RealIterator<ValueType>;
    \n+
    105
    \n+
    107 RealIterator ()
    \n+
    108 : p(0), i(0)
    \n+
    109 {}
    \n+
    110
    \n+
    111 RealIterator (const B* _p, B* _i) : p(_p), i(_i)
    \n+
    112 { }
    \n+
    113
    \n+
    114 RealIterator(const RealIterator<ValueType>& it)
    \n+
    115 : p(it.p), i(it.i)
    \n+
    116 {}
    \n+
    117
    \n+
    119 size_type index () const
    \n+
    120 {
    \n+
    121 return i-p;
    \n+
    122 }
    \n+
    123
    \n+
    125 bool equals (const RealIterator<ValueType>& other) const
    \n+
    126 {
    \n+
    127 assert(other.p==p);
    \n+
    128 return i==other.i;
    \n+
    129 }
    \n+
    130
    \n+
    132 bool equals (const RealIterator<const ValueType>& other) const
    \n+
    133 {
    \n+
    134 assert(other.p==p);
    \n+
    135 return i==other.i;
    \n+
    136 }
    \n+
    137
    \n+
    138 std::ptrdiff_t distanceTo(const RealIterator& o) const
    \n+
    139 {
    \n+
    140 return o.i-i;
    \n+
    141 }
    \n+
    142
    \n+
    143 private:
    \n+
    145 void increment()
    \n+
    146 {
    \n+
    147 ++i;
    \n+
    148 }
    \n+
    149
    \n+
    151 void decrement()
    \n+
    152 {
    \n+
    153 --i;
    \n+
    154 }
    \n+
    155
    \n+
    156 // Needed for operator[] of the iterator
    \n+
    157 reference elementAt (std::ptrdiff_t offset) const
    \n+
    158 {
    \n+
    159 return *(i+offset);
    \n+
    160 }
    \n+
    161
    \n+
    163 reference dereference () const
    \n+
    164 {
    \n+
    165 return *i;
    \n+
    166 }
    \n+
    167
    \n+
    168 void advance(std::ptrdiff_t d)
    \n+
    169 {
    \n+
    170 i+=d;
    \n+
    171 }
    \n+
    172
    \n+
    173 const B* p;
    \n+
    174 B* i;
    \n+
    175 };
    \n+
    176
    \n+
    178 typedef RealIterator<B> iterator;
    \n+
    179
    \n+
    180
    \n+
    182 iterator begin ()
    \n+
    183 {
    \n+
    184 return iterator(p,p);
    \n+
    185 }
    \n+
    186
    \n+
    188 iterator end ()
    \n+
    189 {
    \n+
    190 return iterator(p,p+n);
    \n+
    191 }
    \n+
    192
    \n+
    195 iterator beforeEnd ()
    \n+
    196 {
    \n+
    197 return iterator(p,p+n-1);
    \n+
    198 }
    \n+
    199
    \n+
    202 iterator beforeBegin ()
    \n+
    203 {
    \n+
    204 return iterator(p,p-1);
    \n+
    205 }
    \n+
    206
    \n+
    208 iterator find (size_type i)
    \n+
    209 {
    \n+
    210 return iterator(p,p+std::min(i,n));
    \n+
    211 }
    \n+
    212
    \n+
    214 typedef RealIterator<const B> const_iterator;
    \n+
    215
    \n+
    217 const_iterator begin () const
    \n+
    218 {
    \n+
    219 return const_iterator(p,p+0);
    \n+
    220 }
    \n+
    221
    \n+
    223 const_iterator end () const
    \n+
    224 {
    \n+
    225 return const_iterator(p,p+n);
    \n+
    226 }
    \n+
    227
    \n+
    230 const_iterator beforeEnd () const
    \n+
    231 {
    \n+
    232 return const_iterator(p,p+n-1);
    \n+
    233 }
    \n+
    234
    \n+
    237 const_iterator beforeBegin () const
    \n+
    238 {
    \n+
    239 return const_iterator(p,p-1);
    \n+
    240 }
    \n+
    241
    \n+
    243 const_iterator find (size_type i) const
    \n+
    244 {
    \n+
    245 return const_iterator(p,p+std::min(i,n));
    \n+
    246 }
    \n+
    247
    \n+
    248
    \n+
    249 //===== sizes
    \n+
    250
    \n+
    252 size_type size () const
    \n+
    253 {
    \n+
    254 return n;
    \n+
    255 }
    \n+
    256
    \n+
    258 const B* data() const
    \n+
    259 {
    \n+
    260 return p;
    \n+
    261 }
    \n+
    262
    \n+
    264 B* data()
    \n+
    265 {
    \n+
    266 return p;
    \n+
    267 }
    \n+
    268
    \n+
    269 protected:
    \n+
    271 base_array_unmanaged ()
    \n+
    272 : n(0), p(0)
    \n+
    273 {}
    \n+
    275 base_array_unmanaged (size_type n_, B* p_)
    \n+
    276 : n(n_), p(p_)
    \n+
    277 {}
    \n+
    278 size_type n; // number of elements in array
    \n+
    279 B *p; // pointer to dynamically allocated built-in array
    \n+
    280 };
    \n+
    281
    \n+
    282
    \n+
    283
    \n+
    305 template<class B, class A=std::allocator<B> >
    \n+
    306 class compressed_base_array_unmanaged
    \n+
    307 {
    \n+
    308 public:
    \n+
    309
    \n+
    310 //===== type definitions and constants
    \n+
    311
    \n+
    313 typedef B member_type;
    \n+
    314
    \n+
    316 typedef A allocator_type;
    \n+
    317
    \n+
    319 typedef typename A::size_type size_type;
    \n+
    320
    \n+
    322 using reference = B&;
    \n+
    323
    \n+
    325 using const_reference = const B&;
    \n+
    326
    \n+
    327 //===== access to components
    \n+
    328
    \n+
    330 reference operator[] (size_type i)
    \n+
    331 {
    \n+
    332 const size_type* lb = std::lower_bound(j, j+n, i);
    \n+
    333 if (lb == j+n || *lb != i)
    \n+
    334 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
    \n+
    335 return p[lb-j];
    \n+
    336 }
    \n+
    337
    \n+
    339 const_reference operator[] (size_type i) const
    \n+
    340 {
    \n+
    341 const size_type* lb = std::lower_bound(j, j+n, i);
    \n+
    342 if (lb == j+n || *lb != i)
    \n+
    343 DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
    \n+
    344 return p[lb-j];
    \n+
    345 }
    \n+
    346
    \n+
    348 template<class T>
    \n+
    349 class RealIterator
    \n+
    350 : public BidirectionalIteratorFacade<RealIterator<T>, T>
    \n+
    351 {
    \n+
    352 public:
    \n+
    354 typedef typename std::remove_const<T>::type ValueType;
    \n+
    355
    \n+
    356 friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
    \n+
    357 friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
    \n+
    358 friend class RealIterator<const ValueType>;
    \n+
    359 friend class RealIterator<ValueType>;
    \n+
    360
    \n+
    362 RealIterator ()
    \n+
    363 : p(0), j(0), i(0)
    \n+
    364 {}
    \n+
    365
    \n+
    367 RealIterator (B* _p, size_type* _j, size_type _i)
    \n+
    368 : p(_p), j(_j), i(_i)
    \n+
    369 { }
    \n+
    370
    \n+
    374 RealIterator(const RealIterator<ValueType>& it)
    \n+
    375 : p(it.p), j(it.j), i(it.i)
    \n+
    376 {}
    \n+
    377
    \n+
    378
    \n+
    380 bool equals (const RealIterator<ValueType>& it) const
    \n+
    381 {
    \n+
    382 assert(p==it.p);
    \n+
    383 return (i)==(it.i);
    \n+
    384 }
    \n+
    385
    \n+
    387 bool equals (const RealIterator<const ValueType>& it) const
    \n+
    388 {
    \n+
    389 assert(p==it.p);
    \n+
    390 return (i)==(it.i);
    \n+
    391 }
    \n+
    392
    \n+
    393
    \n+
    395 size_type index () const
    \n+
    396 {
    \n+
    397 return j[i];
    \n+
    398 }
    \n+
    399
    \n+
    401 void setindex (size_type k)
    \n+
    402 {
    \n+
    403 return j[i] = k;
    \n+
    404 }
    \n+
    405
    \n+
    413 size_type offset () const
    \n+
    414 {
    \n+
    415 return i;
    \n+
    416 }
    \n+
    417
    \n+
    418 private:
    \n+
    420 void increment()
    \n+
    421 {
    \n+
    422 ++i;
    \n+
    423 }
    \n+
    424
    \n+
    426 void decrement()
    \n+
    427 {
    \n+
    428 --i;
    \n+
    429 }
    \n+
    430
    \n+
    432 reference dereference () const
    \n+
    433 {
    \n+
    434 return p[i];
    \n+
    435 }
    \n+
    436
    \n+
    437 B* p;
    \n+
    438 size_type* j;
    \n+
    439 size_type i;
    \n+
    440 };
    \n+
    441
    \n+
    443 typedef RealIterator<B> iterator;
    \n+
    444
    \n+
    446 iterator begin ()
    \n+
    447 {
    \n+
    448 return iterator(p,j,0);
    \n+
    449 }
    \n+
    450
    \n+
    452 iterator end ()
    \n+
    453 {
    \n+
    454 return iterator(p,j,n);
    \n+
    455 }
    \n+
    456
    \n+
    459 iterator beforeEnd ()
    \n+
    460 {
    \n+
    461 return iterator(p,j,n-1);
    \n+
    462 }
    \n+
    463
    \n+
    466 iterator beforeBegin ()
    \n+
    467 {
    \n+
    468 return iterator(p,j,-1);
    \n+
    469 }
    \n+
    470
    \n+
    472 iterator find (size_type i)
    \n+
    473 {
    \n+
    474 const size_type* lb = std::lower_bound(j, j+n, i);
    \n+
    475 return (lb != j+n && *lb == i)
    \n+
    476 ? iterator(p,j,lb-j)
    \n+
    477 : end();
    \n+
    478 }
    \n+
    479
    \n+
    481 typedef RealIterator<const B> const_iterator;
    \n+
    482
    \n+
    484 const_iterator begin () const
    \n+
    485 {
    \n+
    486 return const_iterator(p,j,0);
    \n+
    487 }
    \n+
    488
    \n+
    490 const_iterator end () const
    \n+
    491 {
    \n+
    492 return const_iterator(p,j,n);
    \n+
    493 }
    \n+
    494
    \n+
    497 const_iterator beforeEnd () const
    \n+
    498 {
    \n+
    499 return const_iterator(p,j,n-1);
    \n+
    500 }
    \n+
    501
    \n+
    504 const_iterator beforeBegin () const
    \n+
    505 {
    \n+
    506 return const_iterator(p,j,-1);
    \n+
    507 }
    \n+
    508
    \n+
    510 const_iterator find (size_type i) const
    \n+
    511 {
    \n+
    512 const size_type* lb = std::lower_bound(j, j+n, i);
    \n+
    513 return (lb != j+n && *lb == i)
    \n+
    514 ? const_iterator(p,j,lb-j)
    \n+
    515 : end();
    \n+
    516 }
    \n+
    517
    \n+
    518 //===== sizes
    \n+
    519
    \n+
    521 size_type size () const
    \n+
    522 {
    \n+
    523 return n;
    \n+
    524 }
    \n+
    525
    \n+
    526 protected:
    \n+
    528 compressed_base_array_unmanaged ()
    \n+
    529 : n(0), p(0), j(0)
    \n+
    530 {}
    \n+
    531
    \n+
    532 size_type n; // number of elements in array
    \n+
    533 B *p; // pointer to dynamically allocated built-in array
    \n+
    534 size_type* j; // the index set
    \n+
    535 };
    \n+
    536
    \n+
    537} // end namespace Imp
    \n+
    538
    \n+
    539} // end namespace
    \n+
    540
    \n+
    541#endif
    \n+\n
    Definition: allocator.hh:11
    \n-
    typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X > ReboundAllocatorType
    Definition: allocator.hh:37
    \n-
    typename AllocatorTraits< T >::type AllocatorType
    Definition: allocator.hh:34
    \n-
    Definition: allocator.hh:14
    \n-
    static const bool value
    Definition: allocator.hh:15
    \n-
    Definition: allocator.hh:20
    \n-
    std::allocator< T > type
    Definition: allocator.hh:21
    \n-
    typename T::allocator_type type
    Definition: allocator.hh:27
    \n-
    Definition: allocator.hh:31
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,82 +4,428 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-allocator.hh\n+basearray.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3#ifndef DUNE_ISTL_ALLOCATOR_HH\n- 4#define DUNE_ISTL_ALLOCATOR_HH\n- 5\n- 6#include \n- 7#include \n- 8\n- 9#include \n- 10\n-11namespace Dune {\n- 12\n- 13 template\n-14 struct exists{\n-15 static const bool value = true;\n- 16 };\n- 17\n- 18 template\n-19 struct DefaultAllocatorTraits\n- 20 {\n-21 using type = std::allocator;\n- 22 };\n- 23\n- 24 template\n-25 struct DefaultAllocatorTraits >\n- 26 {\n-27 using type = typename T::allocator_type;\n- 28 };\n- 29\n- 30 template\n-31 struct AllocatorTraits : public DefaultAllocatorTraits {};\n- 32\n- 33 template\n-34 using AllocatorType = typename AllocatorTraits::type;\n- 35\n- 36 template\n-37 using ReboundAllocatorType = typename std::allocator_traits::type>::template rebind_alloc;\n- 38\n- 39} // end namespace Dune\n- 40\n- 41#endif // DUNE_ISTL_ALLOCATOR_HH\n-std\n-STL namespace.\n+ 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n+ 4// vi: set et ts=4 sw=2 sts=2:\n+ 5#ifndef DUNE_ISTL_BASEARRAY_HH\n+ 6#define DUNE_ISTL_BASEARRAY_HH\n+ 7\n+ 8#include \"assert.h\"\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \"istlexception.hh\"\n+ 15#include \n+ 16\n+ 21namespace Dune {\n+ 22\n+ 24namespace Imp {\n+ 25\n+ 50 template >\n+ 51 class base_array_unmanaged\n+ 52 {\n+ 53 public:\n+ 54\n+ 55 //===== type definitions and constants\n+ 56\n+ 58 typedef B member_type;\n+ 59\n+ 61 typedef A allocator_type;\n+ 62\n+ 64 typedef typename A::size_type size_type;\n+ 65\n+ 67 using reference = B&;\n+ 68\n+ 70 using const_reference = const B&;\n+ 71\n+ 72 //===== access to components\n+ 73\n+ 75 reference operator[] (size_type i)\n+ 76 {\n+ 77#ifdef DUNE_ISTL_WITH_CHECKING\n+ 78 if (i>=n) DUNE_THROW(ISTLError,\"index out of range\");\n+ 79#endif\n+ 80 return p[i];\n+ 81 }\n+ 82\n+ 84 const_reference operator[] (size_type i) const\n+ 85 {\n+ 86#ifdef DUNE_ISTL_WITH_CHECKING\n+ 87 if (i>=n) DUNE_THROW(ISTLError,\"index out of range\");\n+ 88#endif\n+ 89 return p[i];\n+ 90 }\n+ 91\n+ 93 template\n+ 94 class RealIterator\n+ 95 : public RandomAccessIteratorFacade, T>\n+ 96 {\n+ 97 public:\n+ 99 typedef typename std::remove_const::type ValueType;\n+ 100\n+ 101 friend class RandomAccessIteratorFacade,\n+const ValueType>;\n+ 102 friend class RandomAccessIteratorFacade,\n+ValueType>;\n+ 103 friend class RealIterator;\n+ 104 friend class RealIterator;\n+ 105\n+ 107 RealIterator ()\n+ 108 : p(0), i(0)\n+ 109 {}\n+ 110\n+ 111 RealIterator (const B* _p, B* _i) : p(_p), i(_i)\n+ 112 { }\n+ 113\n+ 114 RealIterator(const RealIterator& it)\n+ 115 : p(it.p), i(it.i)\n+ 116 {}\n+ 117\n+ 119 size_type index () const\n+ 120 {\n+ 121 return i-p;\n+ 122 }\n+ 123\n+ 125 bool equals (const RealIterator& other) const\n+ 126 {\n+ 127 assert(other.p==p);\n+ 128 return i==other.i;\n+ 129 }\n+ 130\n+ 132 bool equals (const RealIterator& other) const\n+ 133 {\n+ 134 assert(other.p==p);\n+ 135 return i==other.i;\n+ 136 }\n+ 137\n+ 138 std::ptrdiff_t distanceTo(const RealIterator& o) const\n+ 139 {\n+ 140 return o.i-i;\n+ 141 }\n+ 142\n+ 143 private:\n+ 145 void increment()\n+ 146 {\n+ 147 ++i;\n+ 148 }\n+ 149\n+ 151 void decrement()\n+ 152 {\n+ 153 --i;\n+ 154 }\n+ 155\n+ 156 // Needed for operator[] of the iterator\n+ 157 reference elementAt (std::ptrdiff_t offset) const\n+ 158 {\n+ 159 return *(i+offset);\n+ 160 }\n+ 161\n+ 163 reference dereference () const\n+ 164 {\n+ 165 return *i;\n+ 166 }\n+ 167\n+ 168 void advance(std::ptrdiff_t d)\n+ 169 {\n+ 170 i+=d;\n+ 171 }\n+ 172\n+ 173 const B* p;\n+ 174 B* i;\n+ 175 };\n+ 176\n+ 178 typedef RealIterator iterator;\n+ 179\n+ 180\n+ 182 iterator begin ()\n+ 183 {\n+ 184 return iterator(p,p);\n+ 185 }\n+ 186\n+ 188 iterator end ()\n+ 189 {\n+ 190 return iterator(p,p+n);\n+ 191 }\n+ 192\n+ 195 iterator beforeEnd ()\n+ 196 {\n+ 197 return iterator(p,p+n-1);\n+ 198 }\n+ 199\n+ 202 iterator beforeBegin ()\n+ 203 {\n+ 204 return iterator(p,p-1);\n+ 205 }\n+ 206\n+ 208 iterator find (size_type i)\n+ 209 {\n+ 210 return iterator(p,p+std::min(i,n));\n+ 211 }\n+ 212\n+ 214 typedef RealIterator const_iterator;\n+ 215\n+ 217 const_iterator begin () const\n+ 218 {\n+ 219 return const_iterator(p,p+0);\n+ 220 }\n+ 221\n+ 223 const_iterator end () const\n+ 224 {\n+ 225 return const_iterator(p,p+n);\n+ 226 }\n+ 227\n+ 230 const_iterator beforeEnd () const\n+ 231 {\n+ 232 return const_iterator(p,p+n-1);\n+ 233 }\n+ 234\n+ 237 const_iterator beforeBegin () const\n+ 238 {\n+ 239 return const_iterator(p,p-1);\n+ 240 }\n+ 241\n+ 243 const_iterator find (size_type i) const\n+ 244 {\n+ 245 return const_iterator(p,p+std::min(i,n));\n+ 246 }\n+ 247\n+ 248\n+ 249 //===== sizes\n+ 250\n+ 252 size_type size () const\n+ 253 {\n+ 254 return n;\n+ 255 }\n+ 256\n+ 258 const B* data() const\n+ 259 {\n+ 260 return p;\n+ 261 }\n+ 262\n+ 264 B* data()\n+ 265 {\n+ 266 return p;\n+ 267 }\n+ 268\n+ 269 protected:\n+ 271 base_array_unmanaged ()\n+ 272 : n(0), p(0)\n+ 273 {}\n+ 275 base_array_unmanaged (size_type n_, B* p_)\n+ 276 : n(n_), p(p_)\n+ 277 {}\n+ 278 size_type n; // number of elements in array\n+ 279 B *p; // pointer to dynamically allocated built-in array\n+ 280 };\n+ 281\n+ 282\n+ 283\n+ 305 template >\n+ 306 class compressed_base_array_unmanaged\n+ 307 {\n+ 308 public:\n+ 309\n+ 310 //===== type definitions and constants\n+ 311\n+ 313 typedef B member_type;\n+ 314\n+ 316 typedef A allocator_type;\n+ 317\n+ 319 typedef typename A::size_type size_type;\n+ 320\n+ 322 using reference = B&;\n+ 323\n+ 325 using const_reference = const B&;\n+ 326\n+ 327 //===== access to components\n+ 328\n+ 330 reference operator[] (size_type i)\n+ 331 {\n+ 332 const size_type* lb = std::lower_bound(j, j+n, i);\n+ 333 if (lb == j+n || *lb != i)\n+ 334 DUNE_THROW(ISTLError,\"index \"<\n+ 349 class RealIterator\n+ 350 : public BidirectionalIteratorFacade, T>\n+ 351 {\n+ 352 public:\n+ 354 typedef typename std::remove_const::type ValueType;\n+ 355\n+ 356 friend class BidirectionalIteratorFacade,\n+const ValueType>;\n+ 357 friend class BidirectionalIteratorFacade,\n+ValueType>;\n+ 358 friend class RealIterator;\n+ 359 friend class RealIterator;\n+ 360\n+ 362 RealIterator ()\n+ 363 : p(0), j(0), i(0)\n+ 364 {}\n+ 365\n+ 367 RealIterator (B* _p, size_type* _j, size_type _i)\n+ 368 : p(_p), j(_j), i(_i)\n+ 369 { }\n+ 370\n+ 374 RealIterator(const RealIterator& it)\n+ 375 : p(it.p), j(it.j), i(it.i)\n+ 376 {}\n+ 377\n+ 378\n+ 380 bool equals (const RealIterator& it) const\n+ 381 {\n+ 382 assert(p==it.p);\n+ 383 return (i)==(it.i);\n+ 384 }\n+ 385\n+ 387 bool equals (const RealIterator& it) const\n+ 388 {\n+ 389 assert(p==it.p);\n+ 390 return (i)==(it.i);\n+ 391 }\n+ 392\n+ 393\n+ 395 size_type index () const\n+ 396 {\n+ 397 return j[i];\n+ 398 }\n+ 399\n+ 401 void setindex (size_type k)\n+ 402 {\n+ 403 return j[i] = k;\n+ 404 }\n+ 405\n+ 413 size_type offset () const\n+ 414 {\n+ 415 return i;\n+ 416 }\n+ 417\n+ 418 private:\n+ 420 void increment()\n+ 421 {\n+ 422 ++i;\n+ 423 }\n+ 424\n+ 426 void decrement()\n+ 427 {\n+ 428 --i;\n+ 429 }\n+ 430\n+ 432 reference dereference () const\n+ 433 {\n+ 434 return p[i];\n+ 435 }\n+ 436\n+ 437 B* p;\n+ 438 size_type* j;\n+ 439 size_type i;\n+ 440 };\n+ 441\n+ 443 typedef RealIterator iterator;\n+ 444\n+ 446 iterator begin ()\n+ 447 {\n+ 448 return iterator(p,j,0);\n+ 449 }\n+ 450\n+ 452 iterator end ()\n+ 453 {\n+ 454 return iterator(p,j,n);\n+ 455 }\n+ 456\n+ 459 iterator beforeEnd ()\n+ 460 {\n+ 461 return iterator(p,j,n-1);\n+ 462 }\n+ 463\n+ 466 iterator beforeBegin ()\n+ 467 {\n+ 468 return iterator(p,j,-1);\n+ 469 }\n+ 470\n+ 472 iterator find (size_type i)\n+ 473 {\n+ 474 const size_type* lb = std::lower_bound(j, j+n, i);\n+ 475 return (lb != j+n && *lb == i)\n+ 476 ? iterator(p,j,lb-j)\n+ 477 : end();\n+ 478 }\n+ 479\n+ 481 typedef RealIterator const_iterator;\n+ 482\n+ 484 const_iterator begin () const\n+ 485 {\n+ 486 return const_iterator(p,j,0);\n+ 487 }\n+ 488\n+ 490 const_iterator end () const\n+ 491 {\n+ 492 return const_iterator(p,j,n);\n+ 493 }\n+ 494\n+ 497 const_iterator beforeEnd () const\n+ 498 {\n+ 499 return const_iterator(p,j,n-1);\n+ 500 }\n+ 501\n+ 504 const_iterator beforeBegin () const\n+ 505 {\n+ 506 return const_iterator(p,j,-1);\n+ 507 }\n+ 508\n+ 510 const_iterator find (size_type i) const\n+ 511 {\n+ 512 const size_type* lb = std::lower_bound(j, j+n, i);\n+ 513 return (lb != j+n && *lb == i)\n+ 514 ? const_iterator(p,j,lb-j)\n+ 515 : end();\n+ 516 }\n+ 517\n+ 518 //===== sizes\n+ 519\n+ 521 size_type size () const\n+ 522 {\n+ 523 return n;\n+ 524 }\n+ 525\n+ 526 protected:\n+ 528 compressed_base_array_unmanaged ()\n+ 529 : n(0), p(0), j(0)\n+ 530 {}\n+ 531\n+ 532 size_type n; // number of elements in array\n+ 533 B *p; // pointer to dynamically allocated built-in array\n+ 534 size_type* j; // the index set\n+ 535 };\n+ 536\n+ 537} // end namespace Imp\n+ 538\n+ 539} // end namespace\n+ 540\n+ 541#endif\n+istlexception.hh\n Dune\n Definition: allocator.hh:11\n-Dune::ReboundAllocatorType\n-typename std::allocator_traits< typename AllocatorTraits< T >::type >::template\n-rebind_alloc< X > ReboundAllocatorType\n-Definition: allocator.hh:37\n-Dune::AllocatorType\n-typename AllocatorTraits< T >::type AllocatorType\n-Definition: allocator.hh:34\n-Dune::exists\n-Definition: allocator.hh:14\n-Dune::exists::value\n-static const bool value\n-Definition: allocator.hh:15\n-Dune::DefaultAllocatorTraits\n-Definition: allocator.hh:20\n-Dune::DefaultAllocatorTraits::type\n-std::allocator< T > type\n-Definition: allocator.hh:21\n-Dune::DefaultAllocatorTraits<_T,_std::void_t<_typename_T::allocator_type_>_>::\n-type\n-typename T::allocator_type type\n-Definition: allocator.hh:27\n-Dune::AllocatorTraits\n-Definition: allocator.hh:31\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00089.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00089.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bvector.hh File Reference\n+dune-istl: overlappingschwarz.hh File Reference\n \n \n \n \n \n \n \n@@ -65,64 +65,132 @@\n
  • dune
  • istl
  • \n
    \n
    \n
    \n \n-
    bvector.hh File Reference
    \n+Typedefs
    \n+ \n
    \n
    \n \n-

    This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time. \n+

    Contains one level overlapping Schwarz preconditioners. \n More...

    \n-
    #include <algorithm>
    \n-#include <cmath>
    \n-#include <complex>
    \n-#include <initializer_list>
    \n-#include <limits>
    \n+
    #include <cassert>
    \n+#include <algorithm>
    \n+#include <functional>
    \n #include <memory>
    \n-#include <utility>
    \n #include <vector>
    \n-#include <dune/common/dotproduct.hh>
    \n-#include <dune/common/ftraits.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/promotiontraits.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n-#include "basearray.hh"
    \n-#include "istlexception.hh"
    \n+#include <set>
    \n+#include <dune/common/dynmatrix.hh>
    \n+#include <dune/common/sllist.hh>
    \n+#include <dune/istl/bccsmatrixinitializer.hh>
    \n+#include "preconditioners.hh"
    \n+#include "superlu.hh"
    \n+#include "umfpack.hh"
    \n+#include "bvector.hh"
    \n+#include "bcrsmatrix.hh"
    \n+#include "ilusubdomainsolver.hh"
    \n+#include <dune/istl/solvertype.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::BlockVector< B, A >
     A vector of blocks with memory management. More...
    class  Dune::OverlappingSchwarzInitializer< I, S, D >
     Initializer for SuperLU Matrices representing the subdomains. More...
     
    struct  Dune::FieldTraits< BlockVector< B, A > >
    struct  Dune::AdditiveSchwarzMode
     Tag that the tells the Schwarz method to be additive. More...
     
    struct  Dune::MultiplicativeSchwarzMode
     Tag that tells the Schwarz method to be multiplicative. More...
     
    struct  Dune::SymmetricMultiplicativeSchwarzMode
     Tag that tells the Schwarz method to be multiplicative and symmetric. More...
     
    class  Dune::DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >
     
    class  Dune::OverlappingAssignerHelper< T, tag >
     
    class  Dune::OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false >
     
    struct  Dune::OverlappingAssignerHelper< S< BCRSMatrix< T, A > >, true >
     
    class  Dune::OverlappingAssignerILUBase< M, X, Y >
     
    class  Dune::OverlappingAssignerHelper< ILU0SubdomainSolver< M, X, Y >, false >
     
    class  Dune::OverlappingAssignerHelper< ILUNSubdomainSolver< M, X, Y >, false >
     
    struct  Dune::AdditiveAdder< S, T >
     
    struct  Dune::AdditiveAdder< S, BlockVector< T, A > >
     
    struct  Dune::MultiplicativeAdder< S, T >
     
    struct  Dune::MultiplicativeAdder< S, BlockVector< T, A > >
     
    struct  Dune::AdderSelector< T, X, S >
     template meta program for choosing how to add the correction. More...
     
    struct  Dune::AdderSelector< AdditiveSchwarzMode, X, S >
     
    struct  Dune::AdderSelector< MultiplicativeSchwarzMode, X, S >
     
    struct  Dune::AdderSelector< SymmetricMultiplicativeSchwarzMode, X, S >
     
    struct  Dune::IteratorDirectionSelector< T1, T2, forward >
     Helper template meta program for application of overlapping Schwarz. More...
     
    struct  Dune::IteratorDirectionSelector< T1, T2, false >
     
    struct  Dune::SeqOverlappingSchwarzApplier< T >
     Helper template meta program for application of overlapping Schwarz. More...
     
    struct  Dune::SeqOverlappingSchwarzApplier< SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< T, tag >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< S< BCRSMatrix< T, A > >, true >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerILUBase< M, X, Y >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< ILU0SubdomainSolver< M, X, Y >, false >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< ILUNSubdomainSolver< M, X, Y >, false >
     
    class  Dune::SeqOverlappingSchwarz< M, X, TM, TD, TA >
     Sequential overlapping Schwarz preconditioner. More...
     
    struct  Dune::SeqOverlappingSchwarzDomainSize< M >
     
    struct  Dune::SeqOverlappingSchwarzDomainSize< BCRSMatrix< T, A > >
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n

    \n-Functions

    template<class K , class A >
    std::ostream & Dune::operator<< (std::ostream &s, const BlockVector< K, A > &v)
     Send BlockVector to an output stream. More...
     

    \n+Typedefs

    template<typename T >
    using Dune::OverlappingAssigner = OverlappingAssignerHelper< T, Dune::StoresColumnCompressed< T >::value >
     
    template<class T >
    using Dune::SeqOverlappingSchwarzAssembler = SeqOverlappingSchwarzAssemblerHelper< T, Dune::StoresColumnCompressed< T >::value >
     
    \n

    Detailed Description

    \n-

    This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time.

    \n+

    Contains one level overlapping Schwarz preconditioners.

    \n+
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,51 +4,132 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-bvector.hh File Reference\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of components can be given at run-time. More...\n+Classes | Namespaces | Typedefs\n+overlappingschwarz.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+Contains one level overlapping Schwarz preconditioners. More...\n+#include \n #include \n-#include \n-#include \n-#include \n-#include \n+#include \n #include \n-#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"basearray.hh\"\n-#include \"istlexception.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \"preconditioners.hh\"\n+#include \"superlu.hh\"\n+#include \"umfpack.hh\"\n+#include \"bvector.hh\"\n+#include \"bcrsmatrix.hh\"\n+#include \"ilusubdomainsolver.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::BlockVector<_B,_A_>\n-\u00a0 A vector of blocks with memory management. More...\n+ class \u00a0Dune::OverlappingSchwarzInitializer<_I,_S,_D_>\n+\u00a0 Initializer for SuperLU Matrices representing the subdomains. More...\n \u00a0\n-struct \u00a0Dune::FieldTraits<_BlockVector<_B,_A_>_>\n+struct \u00a0Dune::AdditiveSchwarzMode\n+\u00a0 Tag that the tells the Schwarz method to be additive. More...\n+\u00a0\n+struct \u00a0Dune::MultiplicativeSchwarzMode\n+\u00a0 Tag that tells the Schwarz method to be multiplicative. More...\n+\u00a0\n+struct \u00a0Dune::SymmetricMultiplicativeSchwarzMode\n+\u00a0 Tag that tells the Schwarz method to be multiplicative and symmetric.\n+ More...\n+\u00a0\n+ class \u00a0Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>\n+\u00a0\n+ class \u00a0Dune::OverlappingAssignerHelper<_T,_tag_>\n+\u00a0\n+ class \u00a0Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<\n+ BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>\n+\u00a0\n+struct \u00a0Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>\n+\u00a0\n+ class \u00a0Dune::OverlappingAssignerILUBase<_M,_X,_Y_>\n+\u00a0\n+ class \u00a0Dune::OverlappingAssignerHelper<_ILU0SubdomainSolver<_M,_X,_Y_>,_false\n+ >\n+\u00a0\n+ class \u00a0Dune::OverlappingAssignerHelper<_ILUNSubdomainSolver<_M,_X,_Y_>,_false\n+ >\n+\u00a0\n+struct \u00a0Dune::AdditiveAdder<_S,_T_>\n+\u00a0\n+struct \u00a0Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>\n+\u00a0\n+struct \u00a0Dune::MultiplicativeAdder<_S,_T_>\n+\u00a0\n+struct \u00a0Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>\n+\u00a0\n+struct \u00a0Dune::AdderSelector<_T,_X,_S_>\n+\u00a0 template meta program for choosing how to add the correction. More...\n+\u00a0\n+struct \u00a0Dune::AdderSelector<_AdditiveSchwarzMode,_X,_S_>\n+\u00a0\n+struct \u00a0Dune::AdderSelector<_MultiplicativeSchwarzMode,_X,_S_>\n+\u00a0\n+struct \u00a0Dune::AdderSelector<_SymmetricMultiplicativeSchwarzMode,_X,_S_>\n+\u00a0\n+struct \u00a0Dune::IteratorDirectionSelector<_T1,_T2,_forward_>\n+\u00a0 Helper template meta program for application of overlapping Schwarz.\n+ More...\n+\u00a0\n+struct \u00a0Dune::IteratorDirectionSelector<_T1,_T2,_false_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzApplier<_T_>\n+\u00a0 Helper template meta program for application of overlapping Schwarz.\n+ More...\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n+ SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_T,_tag_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<\n+ DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_S<_BCRSMatrix<_T,_A_>_>,\n+ true_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerILUBase<_M,_X,_Y_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_ILU0SubdomainSolver<_M,_X,\n+ Y_>,_false_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_ILUNSubdomainSolver<_M,_X,\n+ Y_>,_false_>\n+\u00a0\n+ class \u00a0Dune::SeqOverlappingSchwarz<_M,_X,_TM,_TD,_TA_>\n+\u00a0 Sequential overlapping Schwarz preconditioner. More...\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzDomainSize<_M_>\n+\u00a0\n+struct \u00a0Dune::SeqOverlappingSchwarzDomainSize<_BCRSMatrix<_T,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-template\n-std::ostream &\u00a0Dune::operator<< (std::ostream &s, const BlockVector< K, A >\n- &v)\n-\u00a0 Send BlockVector to an output stream. More...\n+ Typedefs\n+template\n+using\u00a0Dune::OverlappingAssigner = OverlappingAssignerHelper< T, Dune::\n+ StoresColumnCompressed< T >::value >\n+\u00a0\n+template\n+using\u00a0Dune::SeqOverlappingSchwarzAssembler =\n+ SeqOverlappingSchwarzAssemblerHelper< T, Dune::StoresColumnCompressed< T\n+ >::value >\n \u00a0\n ***** Detailed Description *****\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of components can be given at run-time.\n+Contains one level overlapping Schwarz preconditioners.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00089_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00089_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bvector.hh Source File\n+dune-istl: overlappingschwarz.hh Source File\n \n \n \n \n \n \n \n@@ -62,929 +62,1450 @@\n \n
    \n \n
    \n
    \n
    \n-
    bvector.hh
    \n+
    overlappingschwarz.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5
    \n-
    6#ifndef DUNE_ISTL_BVECTOR_HH
    \n-
    7#define DUNE_ISTL_BVECTOR_HH
    \n-
    8
    \n-
    9#include <algorithm>
    \n-
    10#include <cmath>
    \n-
    11#include <complex>
    \n-
    12#include <initializer_list>
    \n-
    13#include <limits>
    \n-
    14#include <memory>
    \n-
    15#include <utility>
    \n-
    16#include <vector>
    \n-
    17
    \n-
    18#include <dune/common/dotproduct.hh>
    \n-
    19#include <dune/common/ftraits.hh>
    \n-
    20#include <dune/common/fmatrix.hh>
    \n-
    21#include <dune/common/fvector.hh>
    \n-
    22#include <dune/common/promotiontraits.hh>
    \n-
    23#include <dune/common/typetraits.hh>
    \n-
    24#include <dune/common/scalarvectorview.hh>
    \n-
    25
    \n-\n+
    5#ifndef DUNE_ISTL_OVERLAPPINGSCHWARZ_HH
    \n+
    6#define DUNE_ISTL_OVERLAPPINGSCHWARZ_HH
    \n+
    7#include <cassert>
    \n+
    8#include <algorithm>
    \n+
    9#include <functional>
    \n+
    10#include <memory>
    \n+
    11#include <vector>
    \n+
    12#include <set>
    \n+
    13#include <dune/common/dynmatrix.hh>
    \n+
    14#include <dune/common/sllist.hh>
    \n+
    15
    \n+\n+
    17#include "preconditioners.hh"
    \n+
    18#include "superlu.hh"
    \n+
    19#include "umfpack.hh"
    \n+
    20#include "bvector.hh"
    \n+
    21#include "bcrsmatrix.hh"
    \n+
    22#include "ilusubdomainsolver.hh"
    \n+\n+
    24
    \n+
    25namespace Dune
    \n+
    26{
    \n
    27
    \n-
    28#include "basearray.hh"
    \n-
    29#include "istlexception.hh"
    \n-
    30
    \n-
    38namespace Dune {
    \n-
    39
    \n-
    41namespace Imp {
    \n-
    42
    \n-
    48 template <class B, bool isNumber>
    \n-
    49 class BlockTraitsImp;
    \n-
    50
    \n-
    51 template <class B>
    \n-
    52 class BlockTraitsImp<B,true>
    \n-
    53 {
    \n-
    54 public:
    \n-
    55 using field_type = B;
    \n-
    56 };
    \n+
    39 template<class M, class X, class TM, class TD, class TA>
    \n+
    40 class SeqOverlappingSchwarz;
    \n+
    41
    \n+
    45 template<class I, class S, class D>
    \n+\n+
    47 {
    \n+
    48 public:
    \n+\n+
    51
    \n+
    52 typedef I InitializerList;
    \n+
    53 typedef typename InitializerList::value_type AtomInitializer;
    \n+
    54 typedef typename AtomInitializer::Matrix Matrix;
    \n+
    55 typedef typename Matrix::const_iterator Iter;
    \n+
    56 typedef typename Matrix::row_type::const_iterator CIter;
    \n
    57
    \n-
    58 template <class B>
    \n-
    59 class BlockTraitsImp<B,false>
    \n-
    60 {
    \n-
    61 public:
    \n-
    62 using field_type = typename B::field_type;
    \n-
    63 };
    \n+
    58 typedef S IndexSet;
    \n+
    59 typedef typename IndexSet::size_type size_type;
    \n+
    60
    \n+\n+
    62 const IndexSet& indices,
    \n+
    63 const subdomain_vector& domains);
    \n
    64
    \n-
    67 template <class B>
    \n-
    68 using BlockTraits = BlockTraitsImp<B,IsNumber<B>::value>;
    \n+
    65
    \n+
    66 void addRowNnz(const Iter& row);
    \n+
    67
    \n+
    68 void allocate();
    \n
    69
    \n-
    83 template<class B, class A=std::allocator<B> >
    \n-
    84 class block_vector_unmanaged : public base_array_unmanaged<B,A>
    \n-
    85 {
    \n-
    86 public:
    \n+
    70 void countEntries(const Iter& row, const CIter& col) const;
    \n+
    71
    \n+
    72 void calcColstart() const;
    \n+
    73
    \n+
    74 void copyValue(const Iter& row, const CIter& col) const;
    \n+
    75
    \n+
    76 void createMatrix() const;
    \n+
    77 private:
    \n+
    78 class IndexMap
    \n+
    79 {
    \n+
    80 public:
    \n+
    81 typedef typename S::size_type size_type;
    \n+
    82 typedef std::map<size_type,size_type> Map;
    \n+
    83 typedef typename Map::iterator iterator;
    \n+
    84 typedef typename Map::const_iterator const_iterator;
    \n+
    85
    \n+
    86 IndexMap();
    \n
    87
    \n-
    88 //===== type definitions and constants
    \n-
    89 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    90
    \n-
    92 typedef B block_type;
    \n+
    88 void insert(size_type grow);
    \n+
    89
    \n+
    90 const_iterator find(size_type grow) const;
    \n+
    91
    \n+
    92 iterator find(size_type grow);
    \n
    93
    \n-
    95 typedef A allocator_type;
    \n-
    96
    \n-
    98 typedef typename A::size_type size_type;
    \n+
    94 iterator begin();
    \n+
    95
    \n+
    96 const_iterator begin() const;
    \n+
    97
    \n+
    98 iterator end();
    \n
    99
    \n-
    101 typedef typename base_array_unmanaged<B,A>::iterator Iterator;
    \n-
    102
    \n-
    104 typedef typename base_array_unmanaged<B,A>::const_iterator ConstIterator;
    \n-
    105
    \n-
    107 typedef B value_type;
    \n-
    108
    \n-
    110 typedef B& reference;
    \n-
    111
    \n-
    113 typedef const B& const_reference;
    \n-
    114
    \n-
    115 //===== assignment from scalar
    \n-
    117
    \n-
    118 block_vector_unmanaged& operator= (const field_type& k)
    \n-
    119 {
    \n-
    120 for (size_type i=0; i<this->n; i++)
    \n-
    121 (*this)[i] = k;
    \n-
    122 return *this;
    \n-
    123 }
    \n-
    124
    \n-
    125 //===== vector space arithmetic
    \n-
    127 block_vector_unmanaged& operator+= (const block_vector_unmanaged& y)
    \n-
    128 {
    \n-
    129#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    130 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    131#endif
    \n-
    132 for (size_type i=0; i<this->n; ++i) (*this)[i] += y[i];
    \n-
    133 return *this;
    \n-
    134 }
    \n-
    135
    \n-
    137 block_vector_unmanaged& operator-= (const block_vector_unmanaged& y)
    \n-
    138 {
    \n-
    139#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    140 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    141#endif
    \n-
    142 for (size_type i=0; i<this->n; ++i) (*this)[i] -= y[i];
    \n-
    143 return *this;
    \n-
    144 }
    \n-
    145
    \n-
    147 block_vector_unmanaged& operator*= (const field_type& k)
    \n-
    148 {
    \n-
    149 for (size_type i=0; i<this->n; ++i) (*this)[i] *= k;
    \n-
    150 return *this;
    \n-
    151 }
    \n-
    152
    \n-
    154 block_vector_unmanaged& operator/= (const field_type& k)
    \n-
    155 {
    \n-
    156 for (size_type i=0; i<this->n; ++i) (*this)[i] /= k;
    \n-
    157 return *this;
    \n-
    158 }
    \n-
    159
    \n-
    161 block_vector_unmanaged& axpy (const field_type& a, const block_vector_unmanaged& y)
    \n-
    162 {
    \n-
    163#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    164 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    165#endif
    \n-
    166 for (size_type i=0; i<this->n; ++i)
    \n-
    167 Impl::asVector((*this)[i]).axpy(a,Impl::asVector(y[i]));
    \n-
    168
    \n-
    169 return *this;
    \n-
    170 }
    \n-
    171
    \n-
    172
    \n-
    180 template<class OtherB, class OtherA>
    \n-
    181 auto operator* (const block_vector_unmanaged<OtherB,OtherA>& y) const
    \n-
    182 {
    \n-
    183 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
    \n-
    184 PromotedType sum(0);
    \n-
    185#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    186 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    187#endif
    \n-
    188 for (size_type i=0; i<this->n; ++i) {
    \n-
    189 sum += PromotedType(((*this)[i])*y[i]);
    \n-
    190 }
    \n-
    191 return sum;
    \n-
    192 }
    \n-
    193
    \n-
    201 template<class OtherB, class OtherA>
    \n-
    202 auto dot(const block_vector_unmanaged<OtherB,OtherA>& y) const
    \n-
    203 {
    \n-
    204 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
    \n-
    205 PromotedType sum(0);
    \n-
    206#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    207 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    208#endif
    \n-
    209
    \n-
    210 for (size_type i=0; i<this->n; ++i)
    \n-
    211 sum += Impl::asVector((*this)[i]).dot(Impl::asVector(y[i]));
    \n+
    100 const_iterator end() const;
    \n+
    101
    \n+
    102 private:
    \n+
    103 std::map<size_type,size_type> map_;
    \n+
    104 size_type row;
    \n+
    105 };
    \n+
    106
    \n+
    107
    \n+
    108 typedef typename InitializerList::iterator InitIterator;
    \n+
    109 typedef typename IndexSet::const_iterator IndexIteratur;
    \n+
    110 InitializerList* initializers;
    \n+
    111 const IndexSet *indices;
    \n+
    112 mutable std::vector<IndexMap> indexMaps;
    \n+
    113 const subdomain_vector& domains;
    \n+
    114 };
    \n+
    115
    \n+\n+
    120 {};
    \n+
    121
    \n+\n+
    126 {};
    \n+
    127
    \n+\n+
    133 {};
    \n+
    134
    \n+
    139 template<class M, class X, class Y>
    \n+\n+
    141
    \n+
    142 // Specialization for BCRSMatrix
    \n+
    143 template<class K, class Al, class X, class Y>
    \n+\n+
    145 {
    \n+
    146 typedef BCRSMatrix< K, Al> M;
    \n+
    147 public:
    \n+
    149 typedef typename std::remove_const<M>::type matrix_type;
    \n+
    150 typedef typename X::field_type field_type;
    \n+
    151 typedef typename std::remove_const<M>::type rilu_type;
    \n+
    153 typedef X domain_type;
    \n+
    155 typedef Y range_type;
    \n+
    156 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n+
    157
    \n+
    162 void apply (DynamicVector<field_type>& v, DynamicVector<field_type>& d)
    \n+
    163 {
    \n+
    164 assert(v.size() > 0);
    \n+
    165 assert(v.size() == d.size());
    \n+
    166 assert(A.rows() <= v.size());
    \n+
    167 assert(A.cols() <= v.size());
    \n+
    168 size_t sz = A.rows();
    \n+
    169 v.resize(sz);
    \n+
    170 d.resize(sz);
    \n+
    171 A.solve(v,d);
    \n+
    172 v.resize(v.capacity());
    \n+
    173 d.resize(d.capacity());
    \n+
    174 }
    \n+
    175
    \n+
    183 template<class S>
    \n+
    184 void setSubMatrix(const M& BCRS, S& rowset)
    \n+
    185 {
    \n+
    186 size_t sz = rowset.size();
    \n+
    187 A.resize(sz*n,sz*n);
    \n+
    188 typedef typename S::const_iterator SIter;
    \n+
    189 size_t r = 0, c = 0;
    \n+
    190 for(SIter rowIdx = rowset.begin(), rowEnd=rowset.end();
    \n+
    191 rowIdx!= rowEnd; ++rowIdx, r++)
    \n+
    192 {
    \n+
    193 c = 0;
    \n+
    194 for(SIter colIdx = rowset.begin(), colEnd=rowset.end();
    \n+
    195 colIdx!= colEnd; ++colIdx, c++)
    \n+
    196 {
    \n+
    197 if (BCRS[*rowIdx].find(*colIdx) == BCRS[*rowIdx].end())
    \n+
    198 continue;
    \n+
    199 for (size_t i=0; i<n; i++)
    \n+
    200 {
    \n+
    201 for (size_t j=0; j<n; j++)
    \n+
    202 {
    \n+
    203 A[r*n+i][c*n+j] = Impl::asMatrix(BCRS[*rowIdx][*colIdx])[i][j];
    \n+
    204 }
    \n+
    205 }
    \n+
    206 }
    \n+
    207 }
    \n+
    208 }
    \n+
    209 private:
    \n+
    210 DynamicMatrix<K> A;
    \n+
    211 };
    \n
    212
    \n-
    213 return sum;
    \n-
    214 }
    \n-
    215
    \n-
    216 //===== norms
    \n-
    217
    \n-
    219 typename FieldTraits<field_type>::real_type one_norm () const
    \n-
    220 {
    \n-
    221 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    222 for (size_type i=0; i<this->n; ++i)
    \n-
    223 sum += Impl::asVector((*this)[i]).one_norm();
    \n-
    224 return sum;
    \n-
    225 }
    \n-
    226
    \n-
    228 typename FieldTraits<field_type>::real_type one_norm_real () const
    \n-
    229 {
    \n-
    230 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    231 for (size_type i=0; i<this->n; ++i)
    \n-
    232 sum += Impl::asVector((*this)[i]).one_norm_real();
    \n-
    233 return sum;
    \n-
    234 }
    \n-
    235
    \n-
    237 typename FieldTraits<field_type>::real_type two_norm () const
    \n-
    238 {
    \n-
    239 using std::sqrt;
    \n-
    240 return sqrt(two_norm2());
    \n-
    241 }
    \n-
    242
    \n-
    244 typename FieldTraits<field_type>::real_type two_norm2 () const
    \n-
    245 {
    \n-
    246 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    247 for (size_type i=0; i<this->n; ++i)
    \n-
    248 sum += Impl::asVector((*this)[i]).two_norm2();
    \n-
    249 return sum;
    \n-
    250 }
    \n+
    213 template<typename T, bool tag>
    \n+\n+
    215 {};
    \n+
    216
    \n+
    217 template<typename T>
    \n+\n+
    219
    \n+
    220 // specialization for DynamicMatrix
    \n+
    221 template<class K, class Al, class X, class Y>
    \n+\n+
    223 {
    \n+
    224 public:
    \n+\n+
    226 typedef typename X::field_type field_type;
    \n+
    227 typedef Y range_type;
    \n+
    228 typedef typename range_type::block_type block_type;
    \n+\n+
    230 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n+
    238 OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix<K, Al>& mat_, const X& b_, Y& x_);
    \n+
    239
    \n+
    243 inline
    \n+
    244 void deallocate();
    \n+
    245
    \n+
    249 inline
    \n+
    250 void resetIndexForNextDomain();
    \n
    251
    \n-
    253 template <typename ft = field_type,
    \n-
    254 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    255 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    256 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    257 using std::max;
    \n+
    256 inline
    \n+
    257 DynamicVector<field_type> & lhs();
    \n
    258
    \n-
    259 real_type norm = 0;
    \n-
    260 for (auto const &xi : *this) {
    \n-
    261 real_type const a = Impl::asVector(xi).infinity_norm();
    \n-
    262 norm = max(a, norm);
    \n-
    263 }
    \n-
    264 return norm;
    \n-
    265 }
    \n-
    266
    \n-
    268 template <typename ft = field_type,
    \n-
    269 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    270 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    271 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    272 using std::max;
    \n-
    273
    \n-
    274 real_type norm = 0;
    \n-
    275 for (auto const &xi : *this) {
    \n-
    276 real_type const a = Impl::asVector(xi).infinity_norm_real();
    \n-
    277 norm = max(a, norm);
    \n-
    278 }
    \n-
    279 return norm;
    \n-
    280 }
    \n-
    281
    \n-
    283 template <typename ft = field_type,
    \n-
    284 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    285 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    286 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    287 using std::max;
    \n-
    288 using std::abs;
    \n-
    289
    \n-
    290 real_type norm = 0;
    \n-
    291 real_type isNaN = 1;
    \n-
    292
    \n-
    293 for (auto const &xi : *this) {
    \n-
    294 real_type const a = Impl::asVector(xi).infinity_norm();
    \n-
    295 norm = max(a, norm);
    \n-
    296 isNaN += a;
    \n-
    297 }
    \n-
    298 return norm * (isNaN / isNaN);
    \n-
    299 }
    \n-
    300
    \n-
    302 template <typename ft = field_type,
    \n-
    303 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    304 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    305 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    306 using std::max;
    \n-
    307
    \n-
    308 real_type norm = 0;
    \n-
    309 real_type isNaN = 1;
    \n-
    310
    \n-
    311 for (auto const &xi : *this) {
    \n-
    312 real_type const a = Impl::asVector(xi).infinity_norm_real();
    \n-
    313 norm = max(a, norm);
    \n-
    314 isNaN += a;
    \n-
    315 }
    \n-
    316
    \n-
    317 return norm * (isNaN / isNaN);
    \n-
    318 }
    \n-
    319
    \n-
    320 //===== sizes
    \n-
    321
    \n-
    323 size_type N () const
    \n-
    324 {
    \n-
    325 return this->n;
    \n-
    326 }
    \n-
    327
    \n-
    329 size_type dim () const
    \n-
    330 {
    \n-
    331 size_type d=0;
    \n-
    332
    \n-
    333 for (size_type i=0; i<this->n; i++)
    \n-
    334 d += Impl::asVector((*this)[i]).dim();
    \n-
    335
    \n-
    336 return d;
    \n-
    337 }
    \n+
    263 inline
    \n+
    264 DynamicVector<field_type> & rhs();
    \n+
    265
    \n+
    270 inline
    \n+
    271 void relaxResult(field_type relax);
    \n+
    272
    \n+
    277 void operator()(const size_type& domainIndex);
    \n+
    278
    \n+
    286 inline
    \n+
    287 void assignResult(block_type& res);
    \n+
    288
    \n+
    289 private:
    \n+
    293 const matrix_type* mat;
    \n+
    295 // we need a pointer, because we have to avoid deep copies
    \n+
    296 DynamicVector<field_type> * rhs_;
    \n+
    298 // we need a pointer, because we have to avoid deep copies
    \n+
    299 DynamicVector<field_type> * lhs_;
    \n+
    301 const range_type* b;
    \n+
    303 range_type* x;
    \n+
    305 std::size_t i;
    \n+
    307 std::size_t maxlength_;
    \n+
    308 };
    \n+
    309
    \n+
    310#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n+
    311 template<template<class> class S, typename T, typename A>
    \n+\n+
    313 {
    \n+\n+
    315 typedef typename S<BCRSMatrix<T, A>>::range_type range_type;
    \n+
    316 typedef typename range_type::field_type field_type;
    \n+
    317 typedef typename range_type::block_type block_type;
    \n+
    318
    \n+\n+
    320
    \n+
    321 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n+
    322 static constexpr size_t m = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::cols;
    \n+
    330 OverlappingAssignerHelper(std::size_t maxlength, const matrix_type& mat,
    \n+
    331 const range_type& b, range_type& x);
    \n+
    337 void deallocate();
    \n
    338
    \n-
    339 protected:
    \n-
    341 block_vector_unmanaged () : base_array_unmanaged<B,A>()
    \n-
    342 { }
    \n-
    343 };
    \n-
    344
    \n-
    346
    \n-
    351 template<class F>
    \n-
    352 class ScopeGuard {
    \n-
    353 F cleanupFunc_;
    \n-
    354 public:
    \n-
    355 ScopeGuard(F cleanupFunc) : cleanupFunc_(std::move(cleanupFunc)) {}
    \n-
    356 ScopeGuard(const ScopeGuard &) = delete;
    \n-
    357 ScopeGuard(ScopeGuard &&) = delete;
    \n-
    358 ScopeGuard &operator=(ScopeGuard) = delete;
    \n-
    359 ~ScopeGuard() { cleanupFunc_(); }
    \n-
    360 };
    \n+
    339 /*
    \n+
    340 * @brief Resets the local index to zero.
    \n+
    341 */
    \n+
    342 void resetIndexForNextDomain();
    \n+
    343
    \n+
    348 field_type* lhs();
    \n+
    349
    \n+
    354 field_type* rhs();
    \n+
    355
    \n+
    360 void relaxResult(field_type relax);
    \n
    361
    \n-
    363
    \n-
    372 template<class F>
    \n-
    373 ScopeGuard<F> makeScopeGuard(F cleanupFunc)
    \n-
    374 {
    \n-
    375 return { std::move(cleanupFunc) };
    \n-
    376 }
    \n-
    377
    \n-
    378} // end namespace Imp
    \n-
    393 template<class B, class A=std::allocator<B> >
    \n-
    394 class BlockVector : public Imp::block_vector_unmanaged<B,A>
    \n-
    395 {
    \n-
    396 public:
    \n+
    366 void operator()(const size_type& domain);
    \n+
    367
    \n+
    375 void assignResult(block_type& res);
    \n+
    376
    \n+
    377 private:
    \n+
    381 const matrix_type* mat;
    \n+
    383 field_type* rhs_;
    \n+
    385 field_type* lhs_;
    \n+
    387 const range_type* b;
    \n+
    389 range_type* x;
    \n+
    391 std::size_t i;
    \n+
    393 std::size_t maxlength_;
    \n+
    394 };
    \n+
    395
    \n+
    396#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n
    397
    \n-
    398 //===== type definitions and constants
    \n-
    399
    \n-
    401 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    402
    \n-
    404 typedef B block_type;
    \n+
    398 template<class M, class X, class Y>
    \n+\n+
    400 {
    \n+
    401 public:
    \n+
    402 typedef M matrix_type;
    \n+
    403
    \n+
    404 typedef typename Y::field_type field_type;
    \n
    405
    \n-
    407 typedef A allocator_type;
    \n-
    408
    \n-
    410 typedef typename A::size_type size_type;
    \n-
    411
    \n-
    413 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    414 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n-
    415
    \n-
    417 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator Iterator;
    \n-
    418
    \n-
    420 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n-
    421
    \n-
    422 //===== constructors and such
    \n-
    423
    \n-\n-
    426 {
    \n-
    427 syncBaseArray();
    \n-
    428 }
    \n+
    406 typedef typename Y::block_type block_type;
    \n+
    407
    \n+
    408 typedef typename matrix_type::size_type size_type;
    \n+
    416 OverlappingAssignerILUBase(std::size_t maxlength, const M& mat,
    \n+
    417 const Y& b, X& x);
    \n+
    423 void deallocate();
    \n+
    424
    \n+\n
    429
    \n-
    431 explicit BlockVector (size_type _n) : storage_(_n)
    \n-
    432 {
    \n-
    433 syncBaseArray();
    \n-
    434 }
    \n+
    434 X& lhs();
    \n
    435
    \n-
    437 BlockVector (std::initializer_list<B> const &l) : storage_(l)
    \n-
    438 {
    \n-
    439 syncBaseArray();
    \n-
    440 }
    \n+
    440 Y& rhs();
    \n
    441
    \n-
    442
    \n-
    454 template<typename S>
    \n-
    455 BlockVector (size_type _n, S _capacity)
    \n-
    456 {
    \n-
    457 static_assert(std::numeric_limits<S>::is_integer,
    \n-
    458 "capacity must be an unsigned integral type (be aware, that this constructor does not set the default value!)" );
    \n-
    459 if((size_type)_capacity > _n)
    \n-
    460 storage_.reserve(_capacity);
    \n-
    461 storage_.resize(_n);
    \n-
    462 syncBaseArray();
    \n-
    463 }
    \n-
    464
    \n-
    465
    \n-\n-
    476 {
    \n-
    477 [[maybe_unused]] const auto &guard =
    \n-
    478 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n-
    479 storage_.reserve(capacity);
    \n-
    480 }
    \n-
    481
    \n-\n-
    489 {
    \n-
    490 return storage_.capacity();
    \n-
    491 }
    \n-
    492
    \n-
    503 void resize(size_type size)
    \n-
    504 {
    \n-
    505 [[maybe_unused]] const auto &guard =
    \n-
    506 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n-
    507 storage_.resize(size);
    \n-
    508 }
    \n-
    509
    \n-\n-
    512 noexcept(noexcept(std::declval<BlockVector>().storage_ = a.storage_))
    \n-
    513 {
    \n-
    514 storage_ = a.storage_;
    \n-
    515 syncBaseArray();
    \n-
    516 }
    \n+
    446 void relaxResult(field_type relax);
    \n+
    447
    \n+
    452 void operator()(const size_type& domain);
    \n+
    453
    \n+
    461 void assignResult(block_type& res);
    \n+
    462
    \n+
    463 private:
    \n+
    467 const M* mat;
    \n+
    469 X* lhs_;
    \n+
    471 Y* rhs_;
    \n+
    473 const Y* b;
    \n+
    475 X* x;
    \n+
    477 size_type i;
    \n+
    478 };
    \n+
    479
    \n+
    480 // specialization for ILU0
    \n+
    481 template<class M, class X, class Y>
    \n+\n+
    483 : public OverlappingAssignerILUBase<M,X,Y>
    \n+
    484 {
    \n+
    485 public:
    \n+
    493 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,
    \n+
    494 const Y& b, X& x)
    \n+
    495 : OverlappingAssignerILUBase<M,X,Y>(maxlength, mat,b,x)
    \n+
    496 {}
    \n+
    497 };
    \n+
    498
    \n+
    499 // specialization for ILUN
    \n+
    500 template<class M, class X, class Y>
    \n+\n+
    502 : public OverlappingAssignerILUBase<M,X,Y>
    \n+
    503 {
    \n+
    504 public:
    \n+
    512 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,
    \n+
    513 const Y& b, X& x)
    \n+
    514 : OverlappingAssignerILUBase<M,X,Y>(maxlength, mat,b,x)
    \n+
    515 {}
    \n+
    516 };
    \n
    517
    \n-\n-
    520 noexcept(noexcept(std::declval<BlockVector>().swap(a)))
    \n-
    521 {
    \n-
    522 swap(a);
    \n-
    523 }
    \n-
    524
    \n-\n-
    527 noexcept(noexcept(std::declval<BlockVector>().storage_ = a.storage_))
    \n-
    528 {
    \n-
    529 [[maybe_unused]] const auto &guard =
    \n-
    530 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n-
    531 storage_ = a.storage_;
    \n-
    532 return *this;
    \n-
    533 }
    \n-
    534
    \n-\n-
    537 noexcept(noexcept(std::declval<BlockVector>().swap(a)))
    \n-
    538 {
    \n-
    539 swap(a);
    \n-
    540 return *this;
    \n-
    541 }
    \n-
    542
    \n-
    544 void swap(BlockVector &other)
    \n-
    545 noexcept(noexcept(
    \n-
    546 std::declval<BlockVector&>().storage_.swap(other.storage_)))
    \n-
    547 {
    \n-
    548 [[maybe_unused]] const auto &guard = Imp::makeScopeGuard([&]{
    \n-
    549 syncBaseArray();
    \n-
    550 other.syncBaseArray();
    \n-
    551 });
    \n-
    552 storage_.swap(other.storage_);
    \n-
    553 }
    \n+
    518 template<typename S, typename T>
    \n+\n+
    520 {};
    \n+
    521
    \n+
    522 template<typename S, typename T, typename A>
    \n+
    523 struct AdditiveAdder<S, BlockVector<T,A> >
    \n+
    524 {
    \n+
    525 typedef typename A::size_type size_type;
    \n+
    526 typedef typename std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::field_type field_type;
    \n+\n+
    528 OverlappingAssigner<S>& assigner, const field_type& relax_);
    \n+
    529 void operator()(const size_type& domain);
    \n+
    530 void axpy();
    \n+
    531 static constexpr size_t n = std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::dimension;
    \n+
    532
    \n+
    533 private:
    \n+\n+\n+
    536 OverlappingAssigner<S>* assigner;
    \n+
    537 field_type relax;
    \n+
    538 };
    \n+
    539
    \n+
    540 template<typename S,typename T>
    \n+\n+
    542 {};
    \n+
    543
    \n+
    544 template<typename S, typename T, typename A>
    \n+\n+
    546 {
    \n+
    547 typedef typename A::size_type size_type;
    \n+
    548 typedef typename std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::field_type field_type;
    \n+\n+
    550 OverlappingAssigner<S>& assigner_, const field_type& relax_);
    \n+
    551 void operator()(const size_type& domain);
    \n+
    552 void axpy();
    \n+
    553 static constexpr size_t n = std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::dimension;
    \n
    554
    \n-\n-
    557 {
    \n-
    558 // forward to operator= in base class
    \n-
    559 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n-
    560 return *this;
    \n-
    561 }
    \n-
    562
    \n-
    563 private:
    \n-
    564 void syncBaseArray() noexcept
    \n-
    565 {
    \n-
    566 this->p = storage_.data();
    \n-
    567 this->n = storage_.size();
    \n-
    568 }
    \n-
    569
    \n-
    570 std::vector<B, A> storage_;
    \n-
    571 };
    \n-
    572
    \n-
    578 template<class B, class A>
    \n-
    579 struct FieldTraits< BlockVector<B, A> >
    \n-
    580 {
    \n-
    581 typedef typename FieldTraits<B>::field_type field_type;
    \n-
    582 typedef typename FieldTraits<B>::real_type real_type;
    \n-
    583 };
    \n-
    589 template<class K, class A>
    \n-
    590 std::ostream& operator<< (std::ostream& s, const BlockVector<K, A>& v)
    \n-
    591 {
    \n-
    592 typedef typename BlockVector<K, A>::size_type size_type;
    \n-
    593
    \n-
    594 for (size_type i=0; i<v.size(); i++)
    \n-
    595 s << v[i] << std::endl;
    \n-
    596
    \n-
    597 return s;
    \n-
    598 }
    \n-
    599
    \n-
    601namespace Imp {
    \n-
    602
    \n-
    621#ifndef DOXYGEN
    \n-
    622 template<class B, class A>
    \n-
    623#else
    \n-
    624 template<class B, class A=std::allocator<B> >
    \n-
    625#endif
    \n-
    626 class BlockVectorWindow : public Imp::block_vector_unmanaged<B,A>
    \n-
    627 {
    \n-
    628 public:
    \n-
    629
    \n-
    630 //===== type definitions and constants
    \n-
    631
    \n-
    633 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    634
    \n-
    636 typedef B block_type;
    \n-
    637
    \n-
    639 typedef A allocator_type;
    \n-
    640
    \n-
    642 typedef typename A::size_type size_type;
    \n+
    555 private:
    \n+\n+
    557 OverlappingAssigner<S>* assigner;
    \n+
    558 field_type relax;
    \n+
    559 };
    \n+
    560
    \n+
    570 template<typename T, class X, class S>
    \n+\n+
    572 {};
    \n+
    573
    \n+
    574 template<class X, class S>
    \n+\n+
    576 {
    \n+\n+
    578 };
    \n+
    579
    \n+
    580 template<class X, class S>
    \n+\n+
    582 {
    \n+\n+
    584 };
    \n+
    585
    \n+
    586 template<class X, class S>
    \n+\n+
    588 {
    \n+\n+
    590 };
    \n+
    591
    \n+
    603 template<typename T1, typename T2, bool forward>
    \n+\n+
    605 {
    \n+
    606 typedef T1 solver_vector;
    \n+
    607 typedef typename solver_vector::iterator solver_iterator;
    \n+\n+
    609 typedef typename subdomain_vector::const_iterator domain_iterator;
    \n+
    610
    \n+\n+
    612 {
    \n+
    613 return sv.begin();
    \n+
    614 }
    \n+
    615
    \n+\n+
    617 {
    \n+
    618 return sv.end();
    \n+
    619 }
    \n+\n+
    621 {
    \n+
    622 return sv.begin();
    \n+
    623 }
    \n+
    624
    \n+\n+
    626 {
    \n+
    627 return sv.end();
    \n+
    628 }
    \n+
    629 };
    \n+
    630
    \n+
    631 template<typename T1, typename T2>
    \n+
    632 struct IteratorDirectionSelector<T1,T2,false>
    \n+
    633 {
    \n+
    634 typedef T1 solver_vector;
    \n+
    635 typedef typename solver_vector::reverse_iterator solver_iterator;
    \n+\n+
    637 typedef typename subdomain_vector::const_reverse_iterator domain_iterator;
    \n+
    638
    \n+\n+
    640 {
    \n+
    641 return sv.rbegin();
    \n+
    642 }
    \n
    643
    \n-
    645 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    646 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n-
    647
    \n-
    649 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator Iterator;
    \n-
    650
    \n-
    652 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n-
    653
    \n-
    654
    \n-
    655 //===== constructors and such
    \n-
    657 BlockVectorWindow () : Imp::block_vector_unmanaged<B,A>()
    \n-
    658 { }
    \n-
    659
    \n-
    661 BlockVectorWindow (B* _p, size_type _n)
    \n-
    662 {
    \n-
    663 this->n = _n;
    \n-
    664 this->p = _p;
    \n-
    665 }
    \n-
    666
    \n-
    668 BlockVectorWindow (const BlockVectorWindow& a)
    \n-
    669 {
    \n-
    670 this->n = a.n;
    \n-
    671 this->p = a.p;
    \n-
    672 }
    \n-
    673
    \n-
    675 BlockVectorWindow& operator= (const BlockVectorWindow& a)
    \n-
    676 {
    \n-
    677 // check correct size
    \n-
    678#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    679 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    680#endif
    \n-
    681
    \n-
    682 if (&a!=this) // check if this and a are different objects
    \n-
    683 {
    \n-
    684 // copy data
    \n-
    685 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n-
    686 }
    \n-
    687 return *this;
    \n-
    688 }
    \n-
    689
    \n-
    691 BlockVectorWindow& operator= (const field_type& k)
    \n-
    692 {
    \n-
    693 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n-
    694 return *this;
    \n-
    695 }
    \n-
    696
    \n-
    698 operator BlockVector<B, A>() const {
    \n-
    699 auto bv = BlockVector<B, A>(this->n);
    \n-
    700
    \n-
    701 std::copy(this->begin(), this->end(), bv.begin());
    \n-
    702
    \n-
    703 return bv;
    \n-
    704 }
    \n-
    705
    \n-
    706 //===== window manipulation methods
    \n-
    707
    \n-
    709 void set (size_type _n, B* _p)
    \n-
    710 {
    \n-
    711 this->n = _n;
    \n-
    712 this->p = _p;
    \n-
    713 }
    \n-
    714
    \n-
    716 void setsize (size_type _n)
    \n-
    717 {
    \n-
    718 this->n = _n;
    \n-
    719 }
    \n+\n+
    645 {
    \n+
    646 return sv.rend();
    \n+
    647 }
    \n+\n+
    649 {
    \n+
    650 return sv.rbegin();
    \n+
    651 }
    \n+
    652
    \n+\n+
    654 {
    \n+
    655 return sv.rend();
    \n+
    656 }
    \n+
    657 };
    \n+
    658
    \n+
    667 template<class T>
    \n+\n+
    669 {
    \n+
    670 typedef T smoother;
    \n+
    671 typedef typename smoother::range_type range_type;
    \n+
    672
    \n+
    673 static void apply(smoother& sm, range_type& v, const range_type& b)
    \n+
    674 {
    \n+
    675 sm.template apply<true>(v, b);
    \n+
    676 }
    \n+
    677 };
    \n+
    678
    \n+
    679 template<class M, class X, class TD, class TA>
    \n+\n+
    681 {
    \n+\n+\n+
    684
    \n+
    685 static void apply(smoother& sm, range_type& v, const range_type& b)
    \n+
    686 {
    \n+
    687 sm.template apply<true>(v, b);
    \n+
    688 sm.template apply<false>(v, b);
    \n+
    689 }
    \n+
    690 };
    \n+
    691
    \n+
    692 template<class T, bool tag>
    \n+\n+
    694 {};
    \n+
    695
    \n+
    696 template<class T>
    \n+\n+
    698
    \n+
    699 template<class K, class Al, class X, class Y>
    \n+\n+
    701 {
    \n+\n+
    703 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n+
    704 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    705 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n+
    706 Solvers& solvers, const SubDomains& domains,
    \n+
    707 bool onTheFly);
    \n+
    708 };
    \n+
    709
    \n+
    710 template<template<class> class S, typename T, typename A>
    \n+\n+
    712 {
    \n+\n+
    714 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n+
    715 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    716 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n+
    717 Solvers& solvers, const SubDomains& domains,
    \n+
    718 bool onTheFly);
    \n+
    719 };
    \n
    720
    \n-
    722 void setptr (B* _p)
    \n-
    723 {
    \n-
    724 this->p = _p;
    \n-
    725 }
    \n-
    726
    \n-
    728 B* getptr ()
    \n-
    729 {
    \n-
    730 return this->p;
    \n-
    731 }
    \n-
    732
    \n-
    734 size_type getsize () const
    \n-
    735 {
    \n-
    736 return this->n;
    \n-
    737 }
    \n-
    738 };
    \n-
    739
    \n+
    721 template<class M,class X, class Y>
    \n+\n+
    723 {
    \n+
    724 typedef M matrix_type;
    \n+
    725 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    726 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n+
    727 Solvers& solvers, const SubDomains& domains,
    \n+
    728 bool onTheFly);
    \n+
    729 };
    \n+
    730
    \n+
    731 template<class M,class X, class Y>
    \n+\n+\n+
    734 {};
    \n+
    735
    \n+
    736 template<class M,class X, class Y>
    \n+\n+\n+
    739 {};
    \n
    740
    \n-
    741
    \n-
    752 template<class B, class A=std::allocator<B> >
    \n-
    753 class compressed_block_vector_unmanaged : public compressed_base_array_unmanaged<B,A>
    \n-
    754 {
    \n-
    755 public:
    \n-
    756
    \n-
    757 //===== type definitions and constants
    \n-
    758
    \n-
    760 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    751 template<class M, class X, class TM=AdditiveSchwarzMode,
    \n+
    752 class TD=ILU0SubdomainSolver<M,X,X>, class TA=std::allocator<X> >
    \n+\n+
    754 : public Preconditioner<X,X>
    \n+
    755 {
    \n+
    756 public:
    \n+
    760 typedef M matrix_type;
    \n
    761
    \n-
    763 typedef B block_type;
    \n-
    764
    \n-
    766 typedef A allocator_type;
    \n-
    767
    \n-
    769 typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator;
    \n-
    770
    \n-
    772 typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator;
    \n-
    773
    \n-
    775 typedef typename A::size_type size_type;
    \n-
    776
    \n-
    777 //===== assignment from scalar
    \n-
    778
    \n-
    779 compressed_block_vector_unmanaged& operator= (const field_type& k)
    \n-
    780 {
    \n-
    781 for (size_type i=0; i<this->n; i++)
    \n-
    782 (this->p)[i] = k;
    \n-
    783 return *this;
    \n-
    784 }
    \n-
    785
    \n-
    786
    \n-
    787 //===== vector space arithmetic
    \n-
    788
    \n-
    790 template<class V>
    \n-
    791 compressed_block_vector_unmanaged& operator+= (const V& y)
    \n-
    792 {
    \n-
    793#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    794 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n-
    795#endif
    \n-
    796 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) += y.p[i];
    \n-
    797 return *this;
    \n-
    798 }
    \n-
    799
    \n-
    801 template<class V>
    \n-
    802 compressed_block_vector_unmanaged& operator-= (const V& y)
    \n-
    803 {
    \n-
    804#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    805 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n-
    806#endif
    \n-
    807 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) -= y.p[i];
    \n-
    808 return *this;
    \n-
    809 }
    \n+
    765 typedef X domain_type;
    \n+
    766
    \n+
    770 typedef X range_type;
    \n+
    771
    \n+
    778 typedef TM Mode;
    \n+
    779
    \n+
    783 typedef typename X::field_type field_type;
    \n+
    784
    \n+
    786 typedef typename matrix_type::size_type size_type;
    \n+
    787
    \n+
    789 typedef TA allocator;
    \n+
    790
    \n+
    792 typedef std::set<size_type, std::less<size_type>,
    \n+
    793 typename std::allocator_traits<TA>::template rebind_alloc<size_type> >
    \n+\n+
    795
    \n+
    797 typedef std::vector<subdomain_type, typename std::allocator_traits<TA>::template rebind_alloc<subdomain_type> > subdomain_vector;
    \n+
    798
    \n+
    800 typedef SLList<size_type, typename std::allocator_traits<TA>::template rebind_alloc<size_type> > subdomain_list;
    \n+
    801
    \n+
    803 typedef std::vector<subdomain_list, typename std::allocator_traits<TA>::template rebind_alloc<subdomain_list> > rowtodomain_vector;
    \n+
    804
    \n+
    806 typedef TD slu;
    \n+
    807
    \n+
    809 typedef std::vector<slu, typename std::allocator_traits<TA>::template rebind_alloc<slu> > slu_vector;
    \n
    810
    \n-
    812 template<class V>
    \n-
    813 compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)
    \n-
    814 {
    \n-
    815#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    816 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n-
    817#endif
    \n-
    818 for (size_type i=0; i<y.n; ++i)
    \n-
    819 Impl::asVector((*this)[y.j[i]]).axpy(a,Impl::asVector(y.p[i]));
    \n-
    820 return *this;
    \n-
    821 }
    \n-
    822
    \n-
    824 compressed_block_vector_unmanaged& operator*= (const field_type& k)
    \n-
    825 {
    \n-
    826 for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k;
    \n-
    827 return *this;
    \n-
    828 }
    \n-
    829
    \n-
    831 compressed_block_vector_unmanaged& operator/= (const field_type& k)
    \n-
    832 {
    \n-
    833 for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k;
    \n-
    834 return *this;
    \n-
    835 }
    \n-
    836
    \n-
    837
    \n-
    838 //===== Euclidean scalar product
    \n-
    839
    \n-
    841 field_type operator* (const compressed_block_vector_unmanaged& y) const
    \n-
    842 {
    \n-
    843#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    844 if (!includesindexset(y) || !y.includesindexset(*this) )
    \n-
    845 DUNE_THROW(ISTLError,"index set mismatch");
    \n-
    846#endif
    \n-
    847 field_type sum=0;
    \n-
    848 for (size_type i=0; i<this->n; ++i)
    \n-
    849 sum += (this->p)[i] * y[(this->j)[i]];
    \n-
    850 return sum;
    \n-
    851 }
    \n-
    852
    \n-
    853
    \n-
    854 //===== norms
    \n+\n+
    825 field_type relaxationFactor=1, bool onTheFly_=true);
    \n+
    826
    \n+\n+
    839 field_type relaxationFactor=1, bool onTheFly_=true);
    \n+
    840
    \n+
    846 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] X& b)
    \n+
    847 {}
    \n+
    848
    \n+
    854 virtual void apply (X& v, const X& d);
    \n
    855
    \n-
    857 typename FieldTraits<field_type>::real_type one_norm () const
    \n-
    858 {
    \n-
    859 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    860 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm();
    \n-
    861 return sum;
    \n-
    862 }
    \n+
    861 virtual void post ([[maybe_unused]] X& x)
    \n+
    862 {}
    \n
    863
    \n-
    865 typename FieldTraits<field_type>::real_type one_norm_real () const
    \n-
    866 {
    \n-
    867 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    868 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real();
    \n-
    869 return sum;
    \n-
    870 }
    \n-
    871
    \n-
    873 typename FieldTraits<field_type>::real_type two_norm () const
    \n-
    874 {
    \n-
    875 using std::sqrt;
    \n-
    876 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    877 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
    \n-
    878 return sqrt(sum);
    \n-
    879 }
    \n+
    864 template<bool forward>
    \n+
    865 void apply(X& v, const X& d);
    \n+
    866
    \n+\n+
    869 {
    \n+\n+
    871 }
    \n+
    872
    \n+
    873 private:
    \n+
    874 const M& mat;
    \n+
    875 slu_vector solvers;
    \n+
    876 subdomain_vector subDomains;
    \n+
    877 field_type relax;
    \n+
    878
    \n+
    879 typename M::size_type maxlength;
    \n
    880
    \n-
    882 typename FieldTraits<field_type>::real_type two_norm2 () const
    \n-
    883 {
    \n-
    884 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    885 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
    \n-
    886 return sum;
    \n-
    887 }
    \n-
    888
    \n-
    890 template <typename ft = field_type,
    \n-
    891 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    892 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    893 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    894 using std::max;
    \n-
    895
    \n-
    896 real_type norm = 0;
    \n-
    897 for (auto const &x : *this) {
    \n-
    898 real_type const a = x.infinity_norm();
    \n-
    899 norm = max(a, norm);
    \n-
    900 }
    \n-
    901 return norm;
    \n-
    902 }
    \n+
    881 bool onTheFly;
    \n+
    882 };
    \n+
    883
    \n+
    884
    \n+
    885
    \n+
    886 template<class I, class S, class D>
    \n+\n+
    888 const IndexSet& idx,
    \n+
    889 const subdomain_vector& domains_)
    \n+
    890 : initializers(&il), indices(&idx), indexMaps(il.size()), domains(domains_)
    \n+
    891 {}
    \n+
    892
    \n+
    893
    \n+
    894 template<class I, class S, class D>
    \n+\n+
    896 {
    \n+
    897 typedef typename IndexSet::value_type::const_iterator iterator;
    \n+
    898 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)[row.index()].end(); ++domain) {
    \n+
    899 (*initializers)[*domain].addRowNnz(row, domains[*domain]);
    \n+
    900 indexMaps[*domain].insert(row.index());
    \n+
    901 }
    \n+
    902 }
    \n
    903
    \n-
    905 template <typename ft = field_type,
    \n-
    906 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    907 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    908 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    909 using std::max;
    \n-
    910
    \n-
    911 real_type norm = 0;
    \n-
    912 for (auto const &x : *this) {
    \n-
    913 real_type const a = x.infinity_norm_real();
    \n-
    914 norm = max(a, norm);
    \n-
    915 }
    \n-
    916 return norm;
    \n-
    917 }
    \n-
    918
    \n-
    920 template <typename ft = field_type,
    \n-
    921 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    922 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    923 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    924 using std::max;
    \n-
    925
    \n-
    926 real_type norm = 0;
    \n-
    927 real_type isNaN = 1;
    \n-
    928 for (auto const &x : *this) {
    \n-
    929 real_type const a = x.infinity_norm();
    \n-
    930 norm = max(a, norm);
    \n-
    931 isNaN += a;
    \n-
    932 }
    \n-
    933 return norm * (isNaN / isNaN);
    \n-
    934 }
    \n-
    935
    \n-
    937 template <typename ft = field_type,
    \n-
    938 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    939 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    940 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    941 using std::max;
    \n-
    942
    \n-
    943 real_type norm = 0;
    \n-
    944 real_type isNaN = 1;
    \n-
    945 for (auto const &x : *this) {
    \n-
    946 real_type const a = x.infinity_norm_real();
    \n-
    947 norm = max(a, norm);
    \n-
    948 isNaN += a;
    \n-
    949 }
    \n-
    950 return norm * (isNaN / isNaN);
    \n-
    951 }
    \n-
    952
    \n-
    953 //===== sizes
    \n-
    954
    \n-
    956 size_type N () const
    \n-
    957 {
    \n-
    958 return this->n;
    \n-
    959 }
    \n-
    960
    \n-
    962 size_type dim () const
    \n-
    963 {
    \n-
    964 size_type d=0;
    \n-
    965 for (size_type i=0; i<this->n; i++)
    \n-
    966 d += (this->p)[i].dim();
    \n-
    967 return d;
    \n-
    968 }
    \n-
    969
    \n-
    970 protected:
    \n-
    972 compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>()
    \n-
    973 { }
    \n-
    974
    \n-
    976 template<class V>
    \n-
    977 bool includesindexset (const V& y)
    \n-
    978 {
    \n-
    979 typename V::ConstIterator e=this->end();
    \n-
    980 for (size_type i=0; i<y.n; i++)
    \n-
    981 if (this->find(y.j[i])==e)
    \n-
    982 return false;
    \n-
    983 return true;
    \n-
    984 }
    \n-
    985 };
    \n+
    904 template<class I, class S, class D>
    \n+\n+
    906 {
    \n+
    907 for(auto&& i: *initializers)
    \n+
    908 i.allocateMatrixStorage();
    \n+
    909 for(auto&& i: *initializers)
    \n+
    910 i.allocateMarker();
    \n+
    911 }
    \n+
    912
    \n+
    913 template<class I, class S, class D>
    \n+\n+
    915 {
    \n+
    916 typedef typename IndexSet::value_type::const_iterator iterator;
    \n+
    917 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)[row.index()].end(); ++domain) {
    \n+
    918 typename std::map<size_type,size_type>::const_iterator v = indexMaps[*domain].find(col.index());
    \n+
    919 if(v!= indexMaps[*domain].end()) {
    \n+
    920 (*initializers)[*domain].countEntries(indexMaps[*domain].find(col.index())->second);
    \n+
    921 }
    \n+
    922 }
    \n+
    923 }
    \n+
    924
    \n+
    925 template<class I, class S, class D>
    \n+\n+
    927 {
    \n+
    928 for(auto&& i : *initializers)
    \n+
    929 i.calcColstart();
    \n+
    930 }
    \n+
    931
    \n+
    932 template<class I, class S, class D>
    \n+\n+
    934 {
    \n+
    935 typedef typename IndexSet::value_type::const_iterator iterator;
    \n+
    936 for(iterator domain=(*indices)[row.index()].begin(); domain!= (*indices)[row.index()].end(); ++domain) {
    \n+
    937 typename std::map<size_type,size_type>::const_iterator v = indexMaps[*domain].find(col.index());
    \n+
    938 if(v!= indexMaps[*domain].end()) {
    \n+
    939 assert(indexMaps[*domain].end()!=indexMaps[*domain].find(row.index()));
    \n+
    940 (*initializers)[*domain].copyValue(col, indexMaps[*domain].find(row.index())->second,
    \n+
    941 v->second);
    \n+
    942 }
    \n+
    943 }
    \n+
    944 }
    \n+
    945
    \n+
    946 template<class I, class S, class D>
    \n+\n+
    948 {
    \n+
    949 std::vector<IndexMap>().swap(indexMaps);
    \n+
    950 for(auto&& i: *initializers)
    \n+
    951 i.createMatrix();
    \n+
    952 }
    \n+
    953
    \n+
    954 template<class I, class S, class D>
    \n+\n+
    956 : row(0)
    \n+
    957 {}
    \n+
    958
    \n+
    959 template<class I, class S, class D>
    \n+\n+
    961 {
    \n+
    962 assert(map_.find(grow)==map_.end());
    \n+
    963 map_.insert(std::make_pair(grow, row++));
    \n+
    964 }
    \n+
    965
    \n+
    966 template<class I, class S, class D>
    \n+
    967 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n+\n+
    969 {
    \n+
    970 return map_.find(grow);
    \n+
    971 }
    \n+
    972
    \n+
    973 template<class I, class S, class D>
    \n+
    974 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n+\n+
    976 {
    \n+
    977 return map_.find(grow);
    \n+
    978 }
    \n+
    979
    \n+
    980 template<class I, class S, class D>
    \n+
    981 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n+\n+
    983 {
    \n+
    984 return map_.end();
    \n+
    985 }
    \n
    986
    \n-
    987
    \n-
    1006 template<class B, class A=std::allocator<B> >
    \n-
    1007 class CompressedBlockVectorWindow : public compressed_block_vector_unmanaged<B,A>
    \n-
    1008 {
    \n-
    1009 public:
    \n-
    1010
    \n-
    1011 //===== type definitions and constants
    \n-
    1012
    \n-
    1014 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    1015
    \n-
    1017 typedef B block_type;
    \n+
    987 template<class I, class S, class D>
    \n+
    988 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n+\n+
    990 {
    \n+
    991 return map_.end();
    \n+
    992 }
    \n+
    993
    \n+
    994 template<class I, class S, class D>
    \n+
    995 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n+\n+
    997 {
    \n+
    998 return map_.begin();
    \n+
    999 }
    \n+
    1000
    \n+
    1001 template<class I, class S, class D>
    \n+
    1002 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n+\n+
    1004 {
    \n+
    1005 return map_.begin();
    \n+
    1006 }
    \n+
    1007
    \n+
    1008 template<class M, class X, class TM, class TD, class TA>
    \n+\n+
    1010 field_type relaxationFactor, bool fly)
    \n+
    1011 : mat(mat_), relax(relaxationFactor), onTheFly(fly)
    \n+
    1012 {
    \n+
    1013 typedef typename rowtodomain_vector::const_iterator RowDomainIterator;
    \n+
    1014 typedef typename subdomain_list::const_iterator DomainIterator;
    \n+
    1015#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1016 assert(rowToDomain.size()==mat.N());
    \n+
    1017 assert(rowToDomain.size()==mat.M());
    \n
    1018
    \n-
    1020 typedef A allocator_type;
    \n+
    1019 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter)
    \n+
    1020 assert(iter->size()>0);
    \n
    1021
    \n-
    1023 typedef typename A::size_type size_type;
    \n-
    1024
    \n-
    1026 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    1027 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n-
    1028
    \n-
    1030 typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator;
    \n-
    1031
    \n-
    1033 typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n-
    1034
    \n-
    1035
    \n-
    1036 //===== constructors and such
    \n-
    1038 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>()
    \n-
    1039 { }
    \n-
    1040
    \n-
    1042 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)
    \n-
    1043 {
    \n-
    1044 this->n = _n;
    \n-
    1045 this->p = _p;
    \n-
    1046 this->j = _j;
    \n-
    1047 }
    \n-
    1048
    \n-
    1050 CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)
    \n-
    1051 {
    \n-
    1052 this->n = a.n;
    \n-
    1053 this->p = a.p;
    \n-
    1054 this->j = a.j;
    \n-
    1055 }
    \n-
    1056
    \n-
    1058 CompressedBlockVectorWindow& operator= (const CompressedBlockVectorWindow& a)
    \n-
    1059 {
    \n-
    1060 // check correct size
    \n-
    1061#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1062 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n-
    1063#endif
    \n+
    1022#endif
    \n+
    1023 // calculate the number of domains
    \n+
    1024 size_type domains=0;
    \n+
    1025 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter)
    \n+
    1026 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)
    \n+
    1027 domains=std::max(domains, *d);
    \n+
    1028 ++domains;
    \n+
    1029
    \n+
    1030 solvers.resize(domains);
    \n+
    1031 subDomains.resize(domains);
    \n+
    1032
    \n+
    1033 // initialize subdomains to row mapping from row to subdomain mapping
    \n+
    1034 size_type row=0;
    \n+
    1035 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter, ++row)
    \n+
    1036 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)
    \n+
    1037 subDomains[*d].insert(row);
    \n+
    1038
    \n+
    1039#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1040 size_type i=0;
    \n+
    1041 typedef typename subdomain_vector::const_iterator iterator;
    \n+
    1042 for(iterator iter=subDomains.begin(); iter != subDomains.end(); ++iter) {
    \n+
    1043 typedef typename subdomain_type::const_iterator entry_iterator;
    \n+
    1044 Dune::dvverb<<"domain "<<i++<<":";
    \n+
    1045 for(entry_iterator entry = iter->begin(); entry != iter->end(); ++entry) {
    \n+
    1046 Dune::dvverb<<" "<<*entry;
    \n+
    1047 }
    \n+
    1048 Dune::dvverb<<std::endl;
    \n+
    1049 }
    \n+
    1050#endif
    \n+\n+
    1052 ::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);
    \n+
    1053 }
    \n+
    1054
    \n+
    1055 template<class M, class X, class TM, class TD, class TA>
    \n+\n+
    1057 const subdomain_vector& sd,
    \n+
    1058 field_type relaxationFactor,
    \n+
    1059 bool fly)
    \n+
    1060 : mat(mat_), solvers(sd.size()), subDomains(sd), relax(relaxationFactor),
    \n+
    1061 onTheFly(fly)
    \n+
    1062 {
    \n+
    1063 typedef typename subdomain_vector::const_iterator DomainIterator;
    \n
    1064
    \n-
    1065 if (&a!=this) // check if this and a are different objects
    \n-
    1066 {
    \n-
    1067 // copy data
    \n-
    1068 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n-
    1069 for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i];
    \n-
    1070 }
    \n-
    1071 return *this;
    \n-
    1072 }
    \n-
    1073
    \n-
    1075 CompressedBlockVectorWindow& operator= (const field_type& k)
    \n-
    1076 {
    \n-
    1077 (static_cast<compressed_block_vector_unmanaged<B,A>&>(*this)) = k;
    \n-
    1078 return *this;
    \n-
    1079 }
    \n+
    1065#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1066 size_type i=0;
    \n+
    1067
    \n+
    1068 for(DomainIterator d=sd.begin(); d != sd.end(); ++d,++i) {
    \n+
    1069 //std::cout<<i<<": "<<d->size()<<std::endl;
    \n+
    1070 assert(d->size()>0);
    \n+
    1071 typedef typename DomainIterator::value_type::const_iterator entry_iterator;
    \n+
    1072 Dune::dvverb<<"domain "<<i<<":";
    \n+
    1073 for(entry_iterator entry = d->begin(); entry != d->end(); ++entry) {
    \n+
    1074 Dune::dvverb<<" "<<*entry;
    \n+
    1075 }
    \n+
    1076 Dune::dvverb<<std::endl;
    \n+
    1077 }
    \n+
    1078
    \n+
    1079#endif
    \n
    1080
    \n-
    1081
    \n-
    1082 //===== window manipulation methods
    \n+
    1081 // Create a row to subdomain mapping
    \n+
    1082 rowtodomain_vector rowToDomain(mat.N());
    \n
    1083
    \n-
    1085 void set (size_type _n, B* _p, size_type* _j)
    \n-
    1086 {
    \n-
    1087 this->n = _n;
    \n-
    1088 this->p = _p;
    \n-
    1089 this->j = _j;
    \n+
    1084 size_type domainId=0;
    \n+
    1085
    \n+
    1086 for(DomainIterator domain=sd.begin(); domain != sd.end(); ++domain, ++domainId) {
    \n+
    1087 typedef typename subdomain_type::const_iterator iterator;
    \n+
    1088 for(iterator row=domain->begin(); row != domain->end(); ++row)
    \n+
    1089 rowToDomain[*row].push_back(domainId);
    \n
    1090 }
    \n
    1091
    \n-
    1093 void setsize (size_type _n)
    \n-
    1094 {
    \n-
    1095 this->n = _n;
    \n-
    1096 }
    \n-
    1097
    \n-
    1099 void setptr (B* _p)
    \n-
    1100 {
    \n-
    1101 this->p = _p;
    \n-
    1102 }
    \n-
    1103
    \n-
    1105 void setindexptr (size_type* _j)
    \n-
    1106 {
    \n-
    1107 this->j = _j;
    \n-
    1108 }
    \n-
    1109
    \n-
    1111 B* getptr ()
    \n+\n+
    1093 ::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);
    \n+
    1094 }
    \n+
    1095
    \n+
    1102 template<class M>
    \n+\n+
    1104
    \n+
    1105 template<typename T, typename A>
    \n+\n+
    1107 {
    \n+
    1108 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n+
    1109 static constexpr size_t m = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::cols;
    \n+
    1110 template<class Domain>
    \n+
    1111 static int size(const Domain & d)
    \n
    1112 {
    \n-
    1113 return this->p;
    \n-
    1114 }
    \n-
    1115
    \n-
    1117 size_type* getindexptr ()
    \n-
    1118 {
    \n-
    1119 return this->j;
    \n-
    1120 }
    \n-
    1121
    \n-
    1123 const B* getptr () const
    \n-
    1124 {
    \n-
    1125 return this->p;
    \n-
    1126 }
    \n-
    1127
    \n-
    1129 const size_type* getindexptr () const
    \n-
    1130 {
    \n-
    1131 return this->j;
    \n-
    1132 }
    \n-
    1134 size_type getsize () const
    \n-
    1135 {
    \n-
    1136 return this->n;
    \n-
    1137 }
    \n-
    1138 };
    \n+
    1113 assert(n==m);
    \n+
    1114 return m*d.size();
    \n+
    1115 }
    \n+
    1116 };
    \n+
    1117
    \n+
    1118 template<class K, class Al, class X, class Y>
    \n+
    1119 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    1120 std::size_t
    \n+\n+
    1122 assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,
    \n+
    1123 [[maybe_unused]] const matrix_type& mat,
    \n+
    1124 [[maybe_unused]] Solvers& solvers,
    \n+
    1125 const SubDomains& subDomains,
    \n+
    1126 [[maybe_unused]] bool onTheFly)
    \n+
    1127 {
    \n+
    1128 typedef typename SubDomains::const_iterator DomainIterator;
    \n+
    1129 std::size_t maxlength = 0;
    \n+
    1130
    \n+
    1131 assert(onTheFly);
    \n+
    1132
    \n+
    1133 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n+
    1134 maxlength=std::max(maxlength, domain->size());
    \n+
    1135 maxlength*=n;
    \n+
    1136
    \n+
    1137 return maxlength;
    \n+
    1138 }
    \n
    1139
    \n-
    1140} // end namespace 'Imp'
    \n-
    1141
    \n-
    1142
    \n-
    1144 template<typename B, typename A>
    \n-
    1145 struct AutonomousValueType<Imp::BlockVectorWindow<B,A>>
    \n-
    1146 {
    \n-
    1147 using type = BlockVector<B, A>;
    \n-
    1148 };
    \n-
    1149
    \n-
    1150
    \n-
    1151} // end namespace 'Dune'
    \n-
    1152
    \n-
    1153#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Implements several basic array containers.
    \n-\n-
    STL namespace.
    \n+
    1140#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n+
    1141 template<template<class> class S, typename T, typename A>
    \n+
    1142 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    1143 std::size_t SeqOverlappingSchwarzAssemblerHelper<S<BCRSMatrix<T,A>>,true>::assembleLocalProblems(const RowToDomain& rowToDomain,
    \n+
    1144 const matrix_type& mat,
    \n+
    1145 Solvers& solvers,
    \n+
    1146 const SubDomains& subDomains,
    \n+
    1147 bool onTheFly)
    \n+
    1148 {
    \n+
    1149 typedef typename S<BCRSMatrix<T,A>>::MatrixInitializer MatrixInitializer;
    \n+
    1150 typedef typename std::vector<MatrixInitializer>::iterator InitializerIterator;
    \n+
    1151 typedef typename SubDomains::const_iterator DomainIterator;
    \n+
    1152 typedef typename Solvers::iterator SolverIterator;
    \n+
    1153 std::size_t maxlength = 0;
    \n+
    1154
    \n+
    1155 if(onTheFly) {
    \n+
    1156 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n+
    1157 maxlength=std::max(maxlength, domain->size());
    \n+
    1158 maxlength*=Impl::asMatrix(*mat[0].begin()).N();
    \n+
    1159 }else{
    \n+
    1160 // initialize the initializers
    \n+
    1161 DomainIterator domain=subDomains.begin();
    \n+
    1162
    \n+
    1163 // Create the initializers list.
    \n+
    1164 std::vector<MatrixInitializer> initializers(subDomains.size());
    \n+
    1165
    \n+
    1166 SolverIterator solver=solvers.begin();
    \n+
    1167 for(InitializerIterator initializer=initializers.begin(); initializer!=initializers.end();
    \n+
    1168 ++initializer, ++solver, ++domain) {
    \n+
    1169 solver->getInternalMatrix().N_=SeqOverlappingSchwarzDomainSize<matrix_type>::size(*domain);
    \n+
    1170 solver->getInternalMatrix().M_=SeqOverlappingSchwarzDomainSize<matrix_type>::size(*domain);
    \n+
    1171 //solver->setVerbosity(true);
    \n+
    1172 *initializer=MatrixInitializer(solver->getInternalMatrix());
    \n+
    1173 }
    \n+
    1174
    \n+
    1175 // Set up the supermatrices according to the subdomains
    \n+\n+
    1177 RowToDomain, SubDomains> Initializer;
    \n+
    1178
    \n+
    1179 Initializer initializer(initializers, rowToDomain, subDomains);
    \n+
    1180 copyToBCCSMatrix(initializer, mat);
    \n+
    1181
    \n+
    1182 // Calculate the LU decompositions
    \n+
    1183 for(auto&& s: solvers)
    \n+
    1184 s.decompose();
    \n+
    1185 for (SolverIterator solverIt = solvers.begin(); solverIt != solvers.end(); ++solverIt)
    \n+
    1186 {
    \n+
    1187 assert(solverIt->getInternalMatrix().N() == solverIt->getInternalMatrix().M());
    \n+
    1188 maxlength = std::max(maxlength, solverIt->getInternalMatrix().N());
    \n+
    1189 }
    \n+
    1190 }
    \n+
    1191 return maxlength;
    \n+
    1192 }
    \n+
    1193
    \n+
    1194#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n+
    1195
    \n+
    1196 template<class M,class X,class Y>
    \n+
    1197 template<class RowToDomain, class Solvers, class SubDomains>
    \n+
    1198 std::size_t SeqOverlappingSchwarzAssemblerILUBase<M,X,Y>::assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,
    \n+
    1199 const matrix_type& mat,
    \n+
    1200 Solvers& solvers,
    \n+
    1201 const SubDomains& subDomains,
    \n+
    1202 bool onTheFly)
    \n+
    1203 {
    \n+
    1204 typedef typename SubDomains::const_iterator DomainIterator;
    \n+
    1205 typedef typename Solvers::iterator SolverIterator;
    \n+
    1206 std::size_t maxlength = 0;
    \n+
    1207
    \n+
    1208 if(onTheFly) {
    \n+
    1209 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n+
    1210 maxlength=std::max(maxlength, domain->size());
    \n+
    1211 }else{
    \n+
    1212 // initialize the solvers of the local prolems.
    \n+
    1213 SolverIterator solver=solvers.begin();
    \n+
    1214 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();
    \n+
    1215 ++domain, ++solver) {
    \n+
    1216 solver->setSubMatrix(mat, *domain);
    \n+
    1217 maxlength=std::max(maxlength, domain->size());
    \n+
    1218 }
    \n+
    1219 }
    \n+
    1220
    \n+
    1221 return maxlength;
    \n+
    1222
    \n+
    1223 }
    \n+
    1224
    \n+
    1225
    \n+
    1226 template<class M, class X, class TM, class TD, class TA>
    \n+\n+
    1228 {
    \n+\n+
    1230 }
    \n+
    1231
    \n+
    1232 template<class M, class X, class TM, class TD, class TA>
    \n+
    1233 template<bool forward>
    \n+
    1234 void SeqOverlappingSchwarz<M,X,TM,TD,TA>::apply(X& x, const X& b)
    \n+
    1235 {
    \n+
    1236 typedef slu_vector solver_vector;
    \n+\n+\n+
    1239 domain_iterator;
    \n+
    1240
    \n+
    1241 OverlappingAssigner<TD> assigner(maxlength, mat, b, x);
    \n+
    1242
    \n+\n+\n+
    1245 X v(x); // temporary for the update
    \n+
    1246 v=0;
    \n+
    1247
    \n+
    1248 typedef typename AdderSelector<TM,X,TD >::Adder Adder;
    \n+
    1249 Adder adder(v, x, assigner, relax);
    \n+
    1250
    \n+
    1251 for(; domain != IteratorDirectionSelector<solver_vector,subdomain_vector,forward>::end(subDomains); ++domain) {
    \n+
    1252 //Copy rhs to C-array for SuperLU
    \n+
    1253 std::for_each(domain->begin(), domain->end(), assigner);
    \n+
    1254 assigner.resetIndexForNextDomain();
    \n+
    1255 if(onTheFly) {
    \n+
    1256 // Create the subdomain solver
    \n+
    1257 slu sdsolver;
    \n+
    1258 sdsolver.setSubMatrix(mat, *domain);
    \n+
    1259 // Apply
    \n+
    1260 sdsolver.apply(assigner.lhs(), assigner.rhs());
    \n+
    1261 }else{
    \n+
    1262 solver->apply(assigner.lhs(), assigner.rhs());
    \n+
    1263 ++solver;
    \n+
    1264 }
    \n+
    1265
    \n+
    1266 //Add relaxed correction to from SuperLU to v
    \n+
    1267 std::for_each(domain->begin(), domain->end(), adder);
    \n+
    1268 assigner.resetIndexForNextDomain();
    \n+
    1269
    \n+
    1270 }
    \n+
    1271
    \n+
    1272 adder.axpy();
    \n+
    1273 assigner.deallocate();
    \n+
    1274 }
    \n+
    1275
    \n+
    1276 template<class K, class Al, class X, class Y>
    \n+
    1277 OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al>, X, Y >,false>
    \n+
    1278 ::OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix<K, Al>& mat_,
    \n+
    1279 const X& b_, Y& x_) :
    \n+
    1280 mat(&mat_),
    \n+
    1281 rhs_( new DynamicVector<field_type>(maxlength, 42) ),
    \n+
    1282 lhs_( new DynamicVector<field_type>(maxlength, -42) ),
    \n+
    1283 b(&b_),
    \n+
    1284 x(&x_),
    \n+
    1285 i(0),
    \n+
    1286 maxlength_(maxlength)
    \n+
    1287 {}
    \n+
    1288
    \n+
    1289 template<class K, class Al, class X, class Y>
    \n+
    1290 void
    \n+\n+
    1292 ::deallocate()
    \n+
    1293 {
    \n+
    1294 delete rhs_;
    \n+
    1295 delete lhs_;
    \n+
    1296 }
    \n+
    1297
    \n+
    1298 template<class K, class Al, class X, class Y>
    \n+
    1299 void
    \n+\n+
    1301 ::resetIndexForNextDomain()
    \n+
    1302 {
    \n+
    1303 i=0;
    \n+
    1304 }
    \n+
    1305
    \n+
    1306 template<class K, class Al, class X, class Y>
    \n+
    1307 DynamicVector<typename X::field_type> &
    \n+\n+
    1309 ::lhs()
    \n+
    1310 {
    \n+
    1311 return *lhs_;
    \n+
    1312 }
    \n+
    1313
    \n+
    1314 template<class K, class Al, class X, class Y>
    \n+
    1315 DynamicVector<typename X::field_type> &
    \n+\n+
    1317 ::rhs()
    \n+
    1318 {
    \n+
    1319 return *rhs_;
    \n+
    1320 }
    \n+
    1321
    \n+
    1322 template<class K, class Al, class X, class Y>
    \n+
    1323 void
    \n+\n+
    1325 ::relaxResult(field_type relax)
    \n+
    1326 {
    \n+
    1327 lhs() *= relax;
    \n+
    1328 }
    \n+
    1329
    \n+
    1330 template<class K, class Al, class X, class Y>
    \n+
    1331 void
    \n+\n+
    1333 ::operator()(const size_type& domainIndex)
    \n+
    1334 {
    \n+
    1335 lhs() = 0.0;
    \n+
    1336#if 0
    \n+
    1337 //assign right hand side of current domainindex block
    \n+
    1338 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1339 assert(i<maxlength_);
    \n+
    1340 rhs()[i]=(*b)[domainIndex][j];
    \n+
    1341 }
    \n+
    1342
    \n+
    1343 // loop over all Matrix row entries and calculate defect.
    \n+
    1344 typedef typename matrix_type::ConstColIterator col_iterator;
    \n+
    1345
    \n+
    1346 // calculate defect for current row index block
    \n+
    1347 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n+
    1348 block_type tmp(0.0);
    \n+
    1349 (*col).mv((*x)[col.index()], tmp);
    \n+
    1350 i-=n;
    \n+
    1351 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1352 assert(i<maxlength_);
    \n+
    1353 rhs()[i]-=tmp[j];
    \n+
    1354 }
    \n+
    1355 }
    \n+
    1356#else
    \n+
    1357 //assign right hand side of current domainindex block
    \n+
    1358 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1359 assert(i<maxlength_);
    \n+
    1360 rhs()[i]=Impl::asVector((*b)[domainIndex])[j];
    \n+
    1361
    \n+
    1362 // loop over all Matrix row entries and calculate defect.
    \n+
    1363 typedef typename matrix_type::ConstColIterator col_iterator;
    \n+
    1364
    \n+
    1365 // calculate defect for current row index block
    \n+
    1366 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n+
    1367 for(size_type k=0; k<n; ++k) {
    \n+
    1368 rhs()[i]-=Impl::asMatrix(*col)[j][k] * Impl::asVector((*x)[col.index()])[k];
    \n+
    1369 }
    \n+
    1370 }
    \n+
    1371 }
    \n+
    1372#endif
    \n+
    1373 }
    \n+
    1374
    \n+
    1375 template<class K, class Al, class X, class Y>
    \n+
    1376 void
    \n+\n+
    1378 ::assignResult(block_type& res)
    \n+
    1379 {
    \n+
    1380 // assign the result of the local solve to the global vector
    \n+
    1381 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1382 assert(i<maxlength_);
    \n+
    1383 Impl::asVector(res)[j]+=lhs()[i];
    \n+
    1384 }
    \n+
    1385 }
    \n+
    1386
    \n+
    1387#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n+
    1388
    \n+
    1389 template<template<class> class S, typename T, typename A>
    \n+\n+
    1391 ::OverlappingAssignerHelper(std::size_t maxlength,
    \n+
    1392 const BCRSMatrix<T,A>& mat_,
    \n+
    1393 const range_type& b_,
    \n+
    1394 range_type& x_)
    \n+
    1395 : mat(&mat_),
    \n+
    1396 b(&b_),
    \n+
    1397 x(&x_), i(0), maxlength_(maxlength)
    \n+
    1398 {
    \n+
    1399 rhs_ = new field_type[maxlength];
    \n+
    1400 lhs_ = new field_type[maxlength];
    \n+
    1401
    \n+
    1402 }
    \n+
    1403
    \n+
    1404 template<template<class> class S, typename T, typename A>
    \n+\n+
    1406 {
    \n+
    1407 delete[] rhs_;
    \n+
    1408 delete[] lhs_;
    \n+
    1409 }
    \n+
    1410
    \n+
    1411 template<template<class> class S, typename T, typename A>
    \n+
    1412 void OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::operator()(const size_type& domainIndex)
    \n+
    1413 {
    \n+
    1414 //assign right hand side of current domainindex block
    \n+
    1415 // rhs is an array of doubles!
    \n+
    1416 // rhs[starti] = b[domainindex]
    \n+
    1417 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1418 assert(i<maxlength_);
    \n+
    1419 rhs_[i]=Impl::asVector((*b)[domainIndex])[j];
    \n+
    1420 }
    \n+
    1421
    \n+
    1422
    \n+
    1423 // loop over all Matrix row entries and calculate defect.
    \n+
    1424 typedef typename matrix_type::ConstColIterator col_iterator;
    \n+
    1425
    \n+
    1426 // calculate defect for current row index block
    \n+
    1427 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n+
    1428 block_type tmp;
    \n+
    1429 Impl::asMatrix(*col).mv((*x)[col.index()], tmp);
    \n+
    1430 i-=n;
    \n+
    1431 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1432 assert(i<maxlength_);
    \n+
    1433 rhs_[i]-=Impl::asVector(tmp)[j];
    \n+
    1434 }
    \n+
    1435
    \n+
    1436 }
    \n+
    1437
    \n+
    1438 }
    \n+
    1439
    \n+
    1440 template<template<class> class S, typename T, typename A>
    \n+\n+
    1442 {
    \n+
    1443 for(size_type j=i+n; i<j; ++i) {
    \n+
    1444 assert(i<maxlength_);
    \n+
    1445 lhs_[i]*=relax;
    \n+
    1446 }
    \n+
    1447 i-=n;
    \n+
    1448 }
    \n+
    1449
    \n+
    1450 template<template<class> class S, typename T, typename A>
    \n+\n+
    1452 {
    \n+
    1453 // assign the result of the local solve to the global vector
    \n+
    1454 for(size_type j=0; j<n; ++j, ++i) {
    \n+
    1455 assert(i<maxlength_);
    \n+
    1456 Impl::asVector(res)[j]+=lhs_[i];
    \n+
    1457 }
    \n+
    1458 }
    \n+
    1459
    \n+
    1460 template<template<class> class S, typename T, typename A>
    \n+
    1461 void OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::resetIndexForNextDomain()
    \n+
    1462 {
    \n+
    1463 i=0;
    \n+
    1464 }
    \n+
    1465
    \n+
    1466 template<template<class> class S, typename T, typename A>
    \n+
    1467 typename OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::field_type*
    \n+\n+
    1469 {
    \n+
    1470 return lhs_;
    \n+
    1471 }
    \n+
    1472
    \n+
    1473 template<template<class> class S, typename T, typename A>
    \n+
    1474 typename OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::field_type*
    \n+\n+
    1476 {
    \n+
    1477 return rhs_;
    \n+
    1478 }
    \n+
    1479
    \n+
    1480#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n+
    1481
    \n+
    1482 template<class M, class X, class Y>
    \n+\n+
    1484 const M& mat_,
    \n+
    1485 const Y& b_,
    \n+
    1486 X& x_)
    \n+
    1487 : mat(&mat_),
    \n+
    1488 b(&b_),
    \n+
    1489 x(&x_), i(0)
    \n+
    1490 {
    \n+
    1491 rhs_= new Y(maxlength);
    \n+
    1492 lhs_ = new X(maxlength);
    \n+
    1493 }
    \n+
    1494
    \n+
    1495 template<class M, class X, class Y>
    \n+\n+
    1497 {
    \n+
    1498 delete rhs_;
    \n+
    1499 delete lhs_;
    \n+
    1500 }
    \n+
    1501
    \n+
    1502 template<class M, class X, class Y>
    \n+\n+
    1504 {
    \n+
    1505 (*rhs_)[i]=(*b)[domainIndex];
    \n+
    1506
    \n+
    1507 // loop over all Matrix row entries and calculate defect.
    \n+
    1508 typedef typename matrix_type::ConstColIterator col_iterator;
    \n+
    1509
    \n+
    1510 // calculate defect for current row index block
    \n+
    1511 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n+
    1512 Impl::asMatrix(*col).mmv((*x)[col.index()], (*rhs_)[i]);
    \n+
    1513 }
    \n+
    1514 // Goto next local index
    \n+
    1515 ++i;
    \n+
    1516 }
    \n+
    1517
    \n+
    1518 template<class M, class X, class Y>
    \n+\n+
    1520 {
    \n+
    1521 (*lhs_)[i]*=relax;
    \n+
    1522 }
    \n+
    1523
    \n+
    1524 template<class M, class X, class Y>
    \n+\n+
    1526 {
    \n+
    1527 res+=(*lhs_)[i++];
    \n+
    1528 }
    \n+
    1529
    \n+
    1530 template<class M, class X, class Y>
    \n+\n+
    1532 {
    \n+
    1533 return *lhs_;
    \n+
    1534 }
    \n+
    1535
    \n+
    1536 template<class M, class X, class Y>
    \n+\n+
    1538 {
    \n+
    1539 return *rhs_;
    \n+
    1540 }
    \n+
    1541
    \n+
    1542 template<class M, class X, class Y>
    \n+\n+
    1544 {
    \n+
    1545 i=0;
    \n+
    1546 }
    \n+
    1547
    \n+
    1548 template<typename S, typename T, typename A>
    \n+\n+
    1550 BlockVector<T,A>& x_,
    \n+
    1551 OverlappingAssigner<S>& assigner_,
    \n+
    1552 const field_type& relax_)
    \n+
    1553 : v(&v_), x(&x_), assigner(&assigner_), relax(relax_)
    \n+
    1554 {}
    \n+
    1555
    \n+
    1556 template<typename S, typename T, typename A>
    \n+
    1557 void AdditiveAdder<S,BlockVector<T,A> >::operator()(const size_type& domainIndex)
    \n+
    1558 {
    \n+
    1559 // add the result of the local solve to the current update
    \n+
    1560 assigner->assignResult((*v)[domainIndex]);
    \n+
    1561 }
    \n+
    1562
    \n+
    1563
    \n+
    1564 template<typename S, typename T, typename A>
    \n+\n+
    1566 {
    \n+
    1567 // relax the update and add it to the current guess.
    \n+
    1568 x->axpy(relax,*v);
    \n+
    1569 }
    \n+
    1570
    \n+
    1571
    \n+
    1572 template<typename S, typename T, typename A>
    \n+\n+
    1574 ::MultiplicativeAdder([[maybe_unused]] BlockVector<T,A>& v_,
    \n+
    1575 BlockVector<T,A>& x_,
    \n+
    1576 OverlappingAssigner<S>& assigner_, const field_type& relax_)
    \n+
    1577 : x(&x_), assigner(&assigner_), relax(relax_)
    \n+
    1578 {}
    \n+
    1579
    \n+
    1580
    \n+
    1581 template<typename S,typename T, typename A>
    \n+
    1582 void MultiplicativeAdder<S,BlockVector<T,A> >::operator()(const size_type& domainIndex)
    \n+
    1583 {
    \n+
    1584 // add the result of the local solve to the current guess
    \n+
    1585 assigner->relaxResult(relax);
    \n+
    1586 assigner->assignResult((*x)[domainIndex]);
    \n+
    1587 }
    \n+
    1588
    \n+
    1589
    \n+
    1590 template<typename S,typename T, typename A>
    \n+\n+
    1592 {
    \n+
    1593 // nothing to do, as the corrections already relaxed and added in operator()
    \n+
    1594 }
    \n+
    1595
    \n+
    1596
    \n+
    1598}
    \n+
    1599
    \n+
    1600#endif
    \n+
    Classes for using SuperLU with ISTL matrices.
    \n+
    Templates characterizing the type of a solver.
    \n+
    Classes for using UMFPack with ISTL matrices.
    \n+\n+
    Implementation of the BCRSMatrix class.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+
    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.
    \n+
    Define general preconditioner interface.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    void addRowNnz(const Iter &row)
    Definition: overlappingschwarz.hh:895
    \n+
    X & lhs()
    Get the local left hand side.
    Definition: overlappingschwarz.hh:1531
    \n+
    void calcColstart() const
    Definition: overlappingschwarz.hh:926
    \n+
    Y & rhs()
    Get the local right hand side.
    Definition: overlappingschwarz.hh:1537
    \n+
    void resetIndexForNextDomain()
    Resets the local index to zero.
    Definition: overlappingschwarz.hh:1543
    \n+
    void copyValue(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:933
    \n+
    void createMatrix() const
    Definition: overlappingschwarz.hh:947
    \n+
    OverlappingSchwarzInitializer(InitializerList &il, const IndexSet &indices, const subdomain_vector &domains)
    Definition: overlappingschwarz.hh:887
    \n+
    virtual void apply(X &v, const X &d)
    Apply the precondtioner.
    Definition: overlappingschwarz.hh:1227
    \n+
    OverlappingAssignerILUBase(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:1483
    \n+
    void operator()(const size_type &domain)
    calculate one entry of the local defect.
    Definition: overlappingschwarz.hh:1503
    \n+
    SeqOverlappingSchwarz(const matrix_type &mat, const subdomain_vector &subDomains, field_type relaxationFactor=1, bool onTheFly_=true)
    Construct the overlapping Schwarz method.
    Definition: overlappingschwarz.hh:1056
    \n+
    void allocate()
    Definition: overlappingschwarz.hh:905
    \n+
    void deallocate()
    Deallocates memory of the local vector.
    Definition: overlappingschwarz.hh:1496
    \n+
    void countEntries(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:914
    \n+
    static std::size_t assembleLocalProblems(const RowToDomain &rowToDomain, const matrix_type &mat, Solvers &solvers, const SubDomains &domains, bool onTheFly)
    Definition: overlappingschwarz.hh:1198
    \n+
    void relaxResult(field_type relax)
    relax the result.
    Definition: overlappingschwarz.hh:1519
    \n+
    void assignResult(block_type &res)
    Assigns the block to the current local index. At the same time the local defect is calculated for the...
    Definition: overlappingschwarz.hh:1525
    \n+
    SeqOverlappingSchwarz(const matrix_type &mat, const rowtodomain_vector &rowToDomain, field_type relaxationFactor=1, bool onTheFly_=true)
    Definition: overlappingschwarz.hh:1009
    \n
    Definition: allocator.hh:11
    \n-
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n+
    Initializer for SuperLU Matrices representing the subdomains.
    Definition: overlappingschwarz.hh:47
    \n+
    Matrix::row_type::const_iterator CIter
    Definition: overlappingschwarz.hh:56
    \n+
    S IndexSet
    Definition: overlappingschwarz.hh:58
    \n+
    Matrix::const_iterator Iter
    Definition: overlappingschwarz.hh:55
    \n+
    IndexSet::size_type size_type
    Definition: overlappingschwarz.hh:59
    \n+
    I InitializerList
    Definition: overlappingschwarz.hh:52
    \n+
    AtomInitializer::Matrix Matrix
    Definition: overlappingschwarz.hh:54
    \n+
    InitializerList::value_type AtomInitializer
    Definition: overlappingschwarz.hh:53
    \n+
    D subdomain_vector
    The vector type containing the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:50
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    row_type::ConstIterator ConstColIterator
    Const iterator to the entries of a row.
    Definition: bcrsmatrix.hh:741
    \n
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    BlockVector()
    makes empty vector
    Definition: bvector.hh:425
    \n-
    void reserve(size_type capacity)
    Reserve space.
    Definition: bvector.hh:475
    \n-
    BlockVector(BlockVector &&a) noexcept(noexcept(std::declval< BlockVector >().swap(a)))
    move constructor
    Definition: bvector.hh:519
    \n-
    BlockVector(size_type _n)
    make vector with _n components
    Definition: bvector.hh:431
    \n-
    void resize(size_type size)
    Resize the vector.
    Definition: bvector.hh:503
    \n-
    Imp::block_vector_unmanaged< B, A >::Iterator Iterator
    make iterators available as types
    Definition: bvector.hh:417
    \n-
    static constexpr unsigned int blocklevel
    increment block level counter
    Definition: bvector.hh:414
    \n-
    BlockVector(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
    copy constructor
    Definition: bvector.hh:511
    \n-
    A allocator_type
    export the allocator type
    Definition: bvector.hh:407
    \n-
    BlockVector & operator=(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
    assignment
    Definition: bvector.hh:526
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n-
    A::size_type size_type
    The type for the index access.
    Definition: bvector.hh:410
    \n-
    BlockVector(std::initializer_list< B > const &l)
    Construct from a std::initializer_list.
    Definition: bvector.hh:437
    \n-
    size_type capacity() const
    Get the capacity of the vector.
    Definition: bvector.hh:488
    \n-
    BlockVector(size_type _n, S _capacity)
    Make vector with _n components but preallocating capacity components.
    Definition: bvector.hh:455
    \n-
    B block_type
    export the type representing the components
    Definition: bvector.hh:404
    \n-
    void swap(BlockVector &other) noexcept(noexcept(std::declval< BlockVector & >().storage_.swap(other.storage_)))
    swap operation
    Definition: bvector.hh:544
    \n-
    Imp::block_vector_unmanaged< B, A >::ConstIterator ConstIterator
    make iterators available as types
    Definition: bvector.hh:420
    \n-
    FieldTraits< B >::real_type real_type
    Definition: bvector.hh:582
    \n-
    FieldTraits< B >::field_type field_type
    Definition: bvector.hh:581
    \n+
    Exact subdomain solver using ILU(p) with appropriate p.
    Definition: ilusubdomainsolver.hh:78
    \n+
    Definition: ilusubdomainsolver.hh:111
    \n+
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: overlappingschwarz.hh:783
    \n+
    void apply(X &v, const X &d)
    Apply one step of the preconditioner to the system A(v)=d.
    \n+
    SLList< size_type, typename std::allocator_traits< TA >::template rebind_alloc< size_type > > subdomain_list
    The type for the row to subdomain mapping.
    Definition: overlappingschwarz.hh:800
    \n+
    std::vector< slu, typename std::allocator_traits< TA >::template rebind_alloc< slu > > slu_vector
    The vector type containing subdomain solvers.
    Definition: overlappingschwarz.hh:809
    \n+
    M matrix_type
    The type of the matrix to precondition.
    Definition: overlappingschwarz.hh:760
    \n+
    TM Mode
    The mode (additive or multiplicative) of the Schwarz method.
    Definition: overlappingschwarz.hh:778
    \n+
    X range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:770
    \n+
    std::set< size_type, std::less< size_type >, typename std::allocator_traits< TA >::template rebind_alloc< size_type > > subdomain_type
    The type for the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:794
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:765
    \n+
    TD slu
    The type for the subdomain solver in use.
    Definition: overlappingschwarz.hh:806
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: overlappingschwarz.hh:868
    \n+
    virtual void pre(X &x, X &b)
    Prepare the preconditioner.
    Definition: overlappingschwarz.hh:846
    \n+
    virtual void post(X &x)
    Postprocess the preconditioner.
    Definition: overlappingschwarz.hh:861
    \n+
    TA allocator
    The allocator to use.
    Definition: overlappingschwarz.hh:789
    \n+
    std::vector< subdomain_type, typename std::allocator_traits< TA >::template rebind_alloc< subdomain_type > > subdomain_vector
    The vector type containing the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:797
    \n+
    std::vector< subdomain_list, typename std::allocator_traits< TA >::template rebind_alloc< subdomain_list > > rowtodomain_vector
    The vector type containing the row index to subdomain mapping.
    Definition: overlappingschwarz.hh:803
    \n+
    matrix_type::size_type size_type
    The return type of the size method.
    Definition: overlappingschwarz.hh:786
    \n+
    Definition: overlappingschwarz.hh:694
    \n+
    Tag that the tells the Schwarz method to be additive.
    Definition: overlappingschwarz.hh:120
    \n+
    Tag that tells the Schwarz method to be multiplicative.
    Definition: overlappingschwarz.hh:126
    \n+
    Tag that tells the Schwarz method to be multiplicative and symmetric.
    Definition: overlappingschwarz.hh:133
    \n+
    Exact subdomain solver using Dune::DynamicMatrix<T>::solve.
    Definition: overlappingschwarz.hh:140
    \n+
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: overlappingschwarz.hh:149
    \n+
    X::field_type field_type
    Definition: overlappingschwarz.hh:150
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:153
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:155
    \n+
    void setSubMatrix(const M &BCRS, S &rowset)
    Set the data of the local problem.
    Definition: overlappingschwarz.hh:184
    \n+
    void apply(DynamicVector< field_type > &v, DynamicVector< field_type > &d)
    Apply the subdomain solver.
    Definition: overlappingschwarz.hh:162
    \n+
    std::remove_const< M >::type rilu_type
    Definition: overlappingschwarz.hh:151
    \n+
    Definition: overlappingschwarz.hh:215
    \n+\n+\n+\n+\n+\n+
    S< BCRSMatrix< T, A > >::range_type range_type
    Definition: overlappingschwarz.hh:315
    \n+
    range_type::block_type block_type
    Definition: overlappingschwarz.hh:317
    \n+
    range_type::field_type field_type
    Definition: overlappingschwarz.hh:316
    \n+
    matrix_type::size_type size_type
    Definition: overlappingschwarz.hh:319
    \n+
    BCRSMatrix< T, A > matrix_type
    Definition: overlappingschwarz.hh:314
    \n+
    Definition: overlappingschwarz.hh:400
    \n+
    matrix_type::size_type size_type
    Definition: overlappingschwarz.hh:408
    \n+
    Y::field_type field_type
    Definition: overlappingschwarz.hh:404
    \n+
    Y::block_type block_type
    Definition: overlappingschwarz.hh:406
    \n+
    M matrix_type
    Definition: overlappingschwarz.hh:402
    \n+
    OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:493
    \n+
    OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:512
    \n+
    Definition: overlappingschwarz.hh:520
    \n+
    std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
    Definition: overlappingschwarz.hh:526
    \n+
    A::size_type size_type
    Definition: overlappingschwarz.hh:525
    \n+
    Definition: overlappingschwarz.hh:542
    \n+
    A::size_type size_type
    Definition: overlappingschwarz.hh:547
    \n+
    std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
    Definition: overlappingschwarz.hh:548
    \n+
    template meta program for choosing how to add the correction.
    Definition: overlappingschwarz.hh:572
    \n+
    AdditiveAdder< S, X > Adder
    Definition: overlappingschwarz.hh:577
    \n+
    MultiplicativeAdder< S, X > Adder
    Definition: overlappingschwarz.hh:583
    \n+
    MultiplicativeAdder< S, X > Adder
    Definition: overlappingschwarz.hh:589
    \n+
    Helper template meta program for application of overlapping Schwarz.
    Definition: overlappingschwarz.hh:605
    \n+
    static solver_iterator begin(solver_vector &sv)
    Definition: overlappingschwarz.hh:611
    \n+
    solver_vector::iterator solver_iterator
    Definition: overlappingschwarz.hh:607
    \n+
    static domain_iterator end(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:625
    \n+
    subdomain_vector::const_iterator domain_iterator
    Definition: overlappingschwarz.hh:609
    \n+
    T1 solver_vector
    Definition: overlappingschwarz.hh:606
    \n+
    static domain_iterator begin(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:620
    \n+
    T2 subdomain_vector
    Definition: overlappingschwarz.hh:608
    \n+
    static solver_iterator end(solver_vector &sv)
    Definition: overlappingschwarz.hh:616
    \n+
    T2 subdomain_vector
    Definition: overlappingschwarz.hh:636
    \n+
    static solver_iterator end(solver_vector &sv)
    Definition: overlappingschwarz.hh:644
    \n+
    solver_vector::reverse_iterator solver_iterator
    Definition: overlappingschwarz.hh:635
    \n+
    subdomain_vector::const_reverse_iterator domain_iterator
    Definition: overlappingschwarz.hh:637
    \n+
    static solver_iterator begin(solver_vector &sv)
    Definition: overlappingschwarz.hh:639
    \n+
    T1 solver_vector
    Definition: overlappingschwarz.hh:634
    \n+
    static domain_iterator begin(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:648
    \n+
    static domain_iterator end(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:653
    \n+
    Helper template meta program for application of overlapping Schwarz.
    Definition: overlappingschwarz.hh:669
    \n+
    smoother::range_type range_type
    Definition: overlappingschwarz.hh:671
    \n+
    T smoother
    Definition: overlappingschwarz.hh:670
    \n+
    static void apply(smoother &sm, range_type &v, const range_type &b)
    Definition: overlappingschwarz.hh:673
    \n+
    static void apply(smoother &sm, range_type &v, const range_type &b)
    Definition: overlappingschwarz.hh:685
    \n+
    SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > smoother
    Definition: overlappingschwarz.hh:682
    \n+\n+\n+
    BCRSMatrix< T, A > matrix_type
    Definition: overlappingschwarz.hh:713
    \n+
    Definition: overlappingschwarz.hh:723
    \n+
    M matrix_type
    Definition: overlappingschwarz.hh:724
    \n+
    Definition: overlappingschwarz.hh:1103
    \n+
    static int size(const Domain &d)
    Definition: overlappingschwarz.hh:1111
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1012 +4,1862 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-bvector.hh\n+overlappingschwarz.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5\n- 6#ifndef DUNE_ISTL_BVECTOR_HH\n- 7#define DUNE_ISTL_BVECTOR_HH\n- 8\n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17\n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23#include \n- 24#include \n- 25\n- 26#include \n+ 5#ifndef DUNE_ISTL_OVERLAPPINGSCHWARZ_HH\n+ 6#define DUNE_ISTL_OVERLAPPINGSCHWARZ_HH\n+ 7#include \n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15\n+ 16#include \n+ 17#include \"preconditioners.hh\"\n+ 18#include \"superlu.hh\"\n+ 19#include \"umfpack.hh\"\n+ 20#include \"bvector.hh\"\n+ 21#include \"bcrsmatrix.hh\"\n+ 22#include \"ilusubdomainsolver.hh\"\n+ 23#include \n+ 24\n+ 25namespace Dune\n+ 26{\n 27\n- 28#include \"basearray.hh\"\n- 29#include \"istlexception.hh\"\n- 30\n- 38namespace Dune {\n- 39\n- 41namespace Imp {\n- 42\n- 48 template \n- 49 class BlockTraitsImp;\n- 50\n- 51 template \n- 52 class BlockTraitsImp\n- 53 {\n- 54 public:\n- 55 using field_type = B;\n- 56 };\n+ 39 template\n+ 40 class SeqOverlappingSchwarz;\n+ 41\n+ 45 template\n+46 class OverlappingSchwarzInitializer\n+ 47 {\n+ 48 public:\n+50 typedef D subdomain_vector;\n+ 51\n+52 typedef I InitializerList;\n+53 typedef typename InitializerList::value_type AtomInitializer;\n+54 typedef typename AtomInitializer::Matrix Matrix;\n+55 typedef typename Matrix::const_iterator Iter;\n+56 typedef typename Matrix::row_type::const_iterator CIter;\n 57\n- 58 template \n- 59 class BlockTraitsImp\n- 60 {\n- 61 public:\n- 62 using field_type = typename B::field_type;\n- 63 };\n+58 typedef S IndexSet;\n+59 typedef typename IndexSet::size_type size_type;\n+ 60\n+ 61 OverlappingSchwarzInitializer(InitializerList& il,\n+ 62 const IndexSet& indices,\n+ 63 const subdomain_vector& domains);\n 64\n- 67 template \n- 68 using BlockTraits = BlockTraitsImp::value>;\n+ 65\n+ 66 void addRowNnz(const Iter& row);\n+ 67\n+ 68 void allocate();\n 69\n- 83 template >\n- 84 class block_vector_unmanaged : public base_array_unmanaged\n- 85 {\n- 86 public:\n+ 70 void countEntries(const Iter& row, const CIter& col) const;\n+ 71\n+ 72 void calcColstart() const;\n+ 73\n+ 74 void copyValue(const Iter& row, const CIter& col) const;\n+ 75\n+ 76 void createMatrix() const;\n+ 77 private:\n+ 78 class IndexMap\n+ 79 {\n+ 80 public:\n+ 81 typedef typename S::size_type size_type;\n+ 82 typedef std::map Map;\n+ 83 typedef typename Map::iterator iterator;\n+ 84 typedef typename Map::const_iterator const_iterator;\n+ 85\n+ 86 IndexMap();\n 87\n- 88 //===== type definitions and constants\n- 89 using field_type = typename Imp::BlockTraits::field_type;\n- 90\n- 92 typedef B block_type;\n+ 88 void insert(size_type grow);\n+ 89\n+ 90 const_iterator find(size_type grow) const;\n+ 91\n+ 92 iterator find(size_type grow);\n 93\n- 95 typedef A allocator_type;\n- 96\n- 98 typedef typename A::size_type size_type;\n+ 94 iterator begin();\n+ 95\n+ 96 const_iterator begin() const;\n+ 97\n+ 98 iterator end();\n 99\n- 101 typedef typename base_array_unmanaged::iterator Iterator;\n- 102\n- 104 typedef typename base_array_unmanaged::const_iterator ConstIterator;\n- 105\n- 107 typedef B value_type;\n- 108\n- 110 typedef B& reference;\n- 111\n- 113 typedef const B& const_reference;\n- 114\n- 115 //===== assignment from scalar\n- 117\n- 118 block_vector_unmanaged& operator= (const field_type& k)\n- 119 {\n- 120 for (size_type i=0; in; i++)\n- 121 (*this)[i] = k;\n- 122 return *this;\n- 123 }\n- 124\n- 125 //===== vector space arithmetic\n- 127 block_vector_unmanaged& operator+= (const block_vector_unmanaged& y)\n- 128 {\n- 129#ifdef DUNE_ISTL_WITH_CHECKING\n- 130 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 131#endif\n- 132 for (size_type i=0; in; ++i) (*this)[i] += y[i];\n- 133 return *this;\n- 134 }\n- 135\n- 137 block_vector_unmanaged& operator-= (const block_vector_unmanaged& y)\n- 138 {\n- 139#ifdef DUNE_ISTL_WITH_CHECKING\n- 140 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 141#endif\n- 142 for (size_type i=0; in; ++i) (*this)[i] -= y[i];\n- 143 return *this;\n- 144 }\n- 145\n- 147 block_vector_unmanaged& operator*= (const field_type& k)\n- 148 {\n- 149 for (size_type i=0; in; ++i) (*this)[i] *= k;\n- 150 return *this;\n- 151 }\n- 152\n- 154 block_vector_unmanaged& operator/= (const field_type& k)\n- 155 {\n- 156 for (size_type i=0; in; ++i) (*this)[i] /= k;\n- 157 return *this;\n- 158 }\n- 159\n- 161 block_vector_unmanaged& axpy (const field_type& a, const\n-block_vector_unmanaged& y)\n- 162 {\n- 163#ifdef DUNE_ISTL_WITH_CHECKING\n- 164 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 165#endif\n- 166 for (size_type i=0; in; ++i)\n- 167 Impl::asVector((*this)[i]).axpy(a,Impl::asVector(y[i]));\n- 168\n- 169 return *this;\n- 170 }\n- 171\n- 172\n- 180 template\n- 181 auto operator* (const block_vector_unmanaged& y) const\n- 182 {\n- 183 typedef typename PromotionTraits::\n-field_type>::PromotedType PromotedType;\n- 184 PromotedType sum(0);\n- 185#ifdef DUNE_ISTL_WITH_CHECKING\n- 186 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 187#endif\n- 188 for (size_type i=0; in; ++i) {\n- 189 sum += PromotedType(((*this)[i])*y[i]);\n- 190 }\n- 191 return sum;\n- 192 }\n- 193\n- 201 template\n- 202 auto dot(const block_vector_unmanaged& y) const\n- 203 {\n- 204 typedef typename PromotionTraits::\n-field_type>::PromotedType PromotedType;\n- 205 PromotedType sum(0);\n- 206#ifdef DUNE_ISTL_WITH_CHECKING\n- 207 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 208#endif\n- 209\n- 210 for (size_type i=0; in; ++i)\n- 211 sum += Impl::asVector((*this)[i]).dot(Impl::asVector(y[i]));\n+ 100 const_iterator end() const;\n+ 101\n+ 102 private:\n+ 103 std::map map_;\n+ 104 size_type row;\n+ 105 };\n+ 106\n+ 107\n+ 108 typedef typename InitializerList::iterator InitIterator;\n+ 109 typedef typename IndexSet::const_iterator IndexIteratur;\n+ 110 InitializerList* initializers;\n+ 111 const IndexSet *indices;\n+ 112 mutable std::vector indexMaps;\n+ 113 const subdomain_vector& domains;\n+ 114 };\n+ 115\n+119 struct AdditiveSchwarzMode\n+ 120 {};\n+ 121\n+125 struct MultiplicativeSchwarzMode\n+ 126 {};\n+ 127\n+132 struct SymmetricMultiplicativeSchwarzMode\n+ 133 {};\n+ 134\n+ 139 template\n+140 class DynamicMatrixSubdomainSolver;\n+ 141\n+ 142 // Specialization for BCRSMatrix\n+ 143 template\n+144 class DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al>, X, Y >\n+ 145 {\n+ 146 typedef BCRSMatrix<_K,_Al> M;\n+ 147 public:\n+149 typedef typename std::remove_const::type matrix_type;\n+150 typedef typename X::field_type field_type;\n+151 typedef typename std::remove_const::type rilu_type;\n+153 typedef X domain_type;\n+155 typedef Y range_type;\n+156 static constexpr size_t n = std::decay_t()))>::rows;\n+ 157\n+162 void apply (DynamicVector& v, DynamicVector& d)\n+ 163 {\n+ 164 assert(v.size() > 0);\n+ 165 assert(v.size() == d.size());\n+ 166 assert(A.rows() <= v.size());\n+ 167 assert(A.cols() <= v.size());\n+ 168 size_t sz = A.rows();\n+ 169 v.resize(sz);\n+ 170 d.resize(sz);\n+ 171 A.solve(v,d);\n+ 172 v.resize(v.capacity());\n+ 173 d.resize(d.capacity());\n+ 174 }\n+ 175\n+ 183 template\n+184 void setSubMatrix(const M& BCRS, S& rowset)\n+ 185 {\n+ 186 size_t sz = rowset.size();\n+ 187 A.resize(sz*n,sz*n);\n+ 188 typedef typename S::const_iterator SIter;\n+ 189 size_t r = 0, c = 0;\n+ 190 for(SIter rowIdx = rowset.begin(), rowEnd=rowset.end();\n+ 191 rowIdx!= rowEnd; ++rowIdx, r++)\n+ 192 {\n+ 193 c = 0;\n+ 194 for(SIter colIdx = rowset.begin(), colEnd=rowset.end();\n+ 195 colIdx!= colEnd; ++colIdx, c++)\n+ 196 {\n+ 197 if (BCRS[*rowIdx].find(*colIdx) == BCRS[*rowIdx].end())\n+ 198 continue;\n+ 199 for (size_t i=0; i A;\n+ 211 };\n 212\n- 213 return sum;\n- 214 }\n- 215\n- 216 //===== norms\n- 217\n- 219 typename FieldTraits::real_type one_norm () const\n- 220 {\n- 221 typename FieldTraits::real_type sum=0;\n- 222 for (size_type i=0; in; ++i)\n- 223 sum += Impl::asVector((*this)[i]).one_norm();\n- 224 return sum;\n- 225 }\n- 226\n- 228 typename FieldTraits::real_type one_norm_real () const\n- 229 {\n- 230 typename FieldTraits::real_type sum=0;\n- 231 for (size_type i=0; in; ++i)\n- 232 sum += Impl::asVector((*this)[i]).one_norm_real();\n- 233 return sum;\n- 234 }\n- 235\n- 237 typename FieldTraits::real_type two_norm () const\n- 238 {\n- 239 using std::sqrt;\n- 240 return sqrt(two_norm2());\n- 241 }\n- 242\n- 244 typename FieldTraits::real_type two_norm2 () const\n- 245 {\n- 246 typename FieldTraits::real_type sum=0;\n- 247 for (size_type i=0; in; ++i)\n- 248 sum += Impl::asVector((*this)[i]).two_norm2();\n- 249 return sum;\n- 250 }\n+ 213 template\n+214 class OverlappingAssignerHelper\n+ 215 {};\n+ 216\n+ 217 template\n+218 using OverlappingAssigner = OverlappingAssignerHelper::value>;\n+ 219\n+ 220 // specialization for DynamicMatrix\n+ 221 template\n+222 class OverlappingAssignerHelper< DynamicMatrixSubdomainSolver<\n+BCRSMatrix, X, Y >,false>\n+ 223 {\n+ 224 public:\n+225 typedef BCRSMatrix<_K,_Al> matrix_type;\n+226 typedef typename X::field_type field_type;\n+227 typedef Y range_type;\n+228 typedef typename range_type::block_type block_type;\n+229 typedef typename matrix_type::size_type size_type;\n+230 static constexpr size_t n = std::decay_t()))>::rows;\n+ 238 OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix&\n+mat_, const X& b_, Y& x_);\n+ 239\n+ 243 inline\n+ 244 void deallocate();\n+ 245\n+ 249 inline\n+ 250 void resetIndexForNextDomain();\n 251\n- 253 template ::value, int>::type = 0>\n- 255 typename FieldTraits::real_type infinity_norm() const {\n- 256 using real_type = typename FieldTraits::real_type;\n- 257 using std::max;\n+ 256 inline\n+ 257 DynamicVector & lhs();\n 258\n- 259 real_type norm = 0;\n- 260 for (auto const &xi : *this) {\n- 261 real_type const a = Impl::asVector(xi).infinity_norm();\n- 262 norm = max(a, norm);\n- 263 }\n- 264 return norm;\n- 265 }\n- 266\n- 268 template ::value, int>::type = 0>\n- 270 typename FieldTraits::real_type infinity_norm_real() const {\n- 271 using real_type = typename FieldTraits::real_type;\n- 272 using std::max;\n- 273\n- 274 real_type norm = 0;\n- 275 for (auto const &xi : *this) {\n- 276 real_type const a = Impl::asVector(xi).infinity_norm_real();\n- 277 norm = max(a, norm);\n- 278 }\n- 279 return norm;\n- 280 }\n- 281\n- 283 template ::value, int>::type = 0>\n- 285 typename FieldTraits::real_type infinity_norm() const {\n- 286 using real_type = typename FieldTraits::real_type;\n- 287 using std::max;\n- 288 using std::abs;\n- 289\n- 290 real_type norm = 0;\n- 291 real_type isNaN = 1;\n- 292\n- 293 for (auto const &xi : *this) {\n- 294 real_type const a = Impl::asVector(xi).infinity_norm();\n- 295 norm = max(a, norm);\n- 296 isNaN += a;\n- 297 }\n- 298 return norm * (isNaN / isNaN);\n- 299 }\n- 300\n- 302 template ::value, int>::type = 0>\n- 304 typename FieldTraits::real_type infinity_norm_real() const {\n- 305 using real_type = typename FieldTraits::real_type;\n- 306 using std::max;\n- 307\n- 308 real_type norm = 0;\n- 309 real_type isNaN = 1;\n- 310\n- 311 for (auto const &xi : *this) {\n- 312 real_type const a = Impl::asVector(xi).infinity_norm_real();\n- 313 norm = max(a, norm);\n- 314 isNaN += a;\n- 315 }\n- 316\n- 317 return norm * (isNaN / isNaN);\n- 318 }\n- 319\n- 320 //===== sizes\n- 321\n- 323 size_type N () const\n- 324 {\n- 325 return this->n;\n- 326 }\n- 327\n- 329 size_type dim () const\n- 330 {\n- 331 size_type d=0;\n- 332\n- 333 for (size_type i=0; in; i++)\n- 334 d += Impl::asVector((*this)[i]).dim();\n- 335\n- 336 return d;\n- 337 }\n+ 263 inline\n+ 264 DynamicVector & rhs();\n+ 265\n+ 270 inline\n+ 271 void relaxResult(field_type relax);\n+ 272\n+ 277 void operator()(const size_type& domainIndex);\n+ 278\n+ 286 inline\n+ 287 void assignResult(block_type& res);\n+ 288\n+ 289 private:\n+ 293 const matrix_type* mat;\n+ 295 // we need a pointer, because we have to avoid deep copies\n+ 296 DynamicVector * rhs_;\n+ 298 // we need a pointer, because we have to avoid deep copies\n+ 299 DynamicVector * lhs_;\n+ 301 const range_type* b;\n+ 303 range_type* x;\n+ 305 std::size_t i;\n+ 307 std::size_t maxlength_;\n+ 308 };\n+ 309\n+ 310#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n+ 311 template class S, typename T, typename A>\n+312 struct OverlappingAssignerHelper>, true>\n+ 313 {\n+314 typedef BCRSMatrix matrix_type;\n+315 typedef typename S>::range_type range_type;\n+316 typedef typename range_type::field_type field_type;\n+317 typedef typename range_type::block_type block_type;\n+ 318\n+319 typedef typename matrix_type::size_type size_type;\n+ 320\n+321 static constexpr size_t n = std::decay_t()))>::rows;\n+322 static constexpr size_t m = std::decay_t()))>::cols;\n+ 330 OverlappingAssignerHelper(std::size_t maxlength, const matrix_type& mat,\n+ 331 const range_type& b, range_type& x);\n+ 337 void deallocate();\n 338\n- 339 protected:\n- 341 block_vector_unmanaged () : base_array_unmanaged()\n- 342 { }\n- 343 };\n- 344\n- 346\n- 351 template\n- 352 class ScopeGuard {\n- 353 F cleanupFunc_;\n- 354 public:\n- 355 ScopeGuard(F cleanupFunc) : cleanupFunc_(std::move(cleanupFunc)) {}\n- 356 ScopeGuard(const ScopeGuard &) = delete;\n- 357 ScopeGuard(ScopeGuard &&) = delete;\n- 358 ScopeGuard &operator=(ScopeGuard) = delete;\n- 359 ~ScopeGuard() { cleanupFunc_(); }\n- 360 };\n+ 339 /*\n+ 340 * @brief Resets the local index to zero.\n+ 341 */\n+ 342 void resetIndexForNextDomain();\n+ 343\n+ 348 field_type* lhs();\n+ 349\n+ 354 field_type* rhs();\n+ 355\n+ 360 void relaxResult(field_type relax);\n 361\n- 363\n- 372 template\n- 373 ScopeGuard makeScopeGuard(F cleanupFunc)\n- 374 {\n- 375 return { std::move(cleanupFunc) };\n- 376 }\n- 377\n- 378} // end namespace Imp\n- 393 template >\n-394 class BlockVector : public Imp::block_vector_unmanaged\n- 395 {\n- 396 public:\n+ 366 void operator()(const size_type& domain);\n+ 367\n+ 375 void assignResult(block_type& res);\n+ 376\n+ 377 private:\n+ 381 const matrix_type* mat;\n+ 383 field_type* rhs_;\n+ 385 field_type* lhs_;\n+ 387 const range_type* b;\n+ 389 range_type* x;\n+ 391 std::size_t i;\n+ 393 std::size_t maxlength_;\n+ 394 };\n+ 395\n+ 396#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n 397\n- 398 //===== type definitions and constants\n- 399\n-401 using field_type = typename Imp::BlockTraits::field_type;\n- 402\n-404 typedef B block_type;\n+ 398 template\n+399 class OverlappingAssignerILUBase\n+ 400 {\n+ 401 public:\n+402 typedef M matrix_type;\n+ 403\n+404 typedef typename Y::field_type field_type;\n 405\n-407 typedef A allocator_type;\n- 408\n-410 typedef typename A::size_type size_type;\n- 411\n- 413 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-414 static constexpr unsigned int blocklevel = blockLevel()+1;\n- 415\n-417 typedef typename Imp::block_vector_unmanaged::Iterator Iterator;\n- 418\n-420 typedef typename Imp::block_vector_unmanaged::ConstIterator\n-ConstIterator;\n- 421\n- 422 //===== constructors and such\n- 423\n-425 BlockVector ()\n- 426 {\n- 427 syncBaseArray();\n- 428 }\n+406 typedef typename Y::block_type block_type;\n+ 407\n+408 typedef typename matrix_type::size_type size_type;\n+ 416 OverlappingAssignerILUBase(std::size_t maxlength, const M& mat,\n+ 417 const Y& b, X& x);\n+ 423 void deallocate();\n+ 424\n+ 428 void resetIndexForNextDomain();\n 429\n-431 explicit BlockVector (size_type _n) : storage_(_n)\n- 432 {\n- 433 syncBaseArray();\n- 434 }\n+ 434 X& lhs();\n 435\n-437 BlockVector (std::initializer_list const &l) : storage_(l)\n- 438 {\n- 439 syncBaseArray();\n- 440 }\n+ 440 Y& rhs();\n 441\n- 442\n- 454 template\n-455 BlockVector (size_type _n, S _capacity)\n- 456 {\n- 457 static_assert(std::numeric_limits::is_integer,\n- 458 \"capacity must be an unsigned integral type (be aware, that this\n-constructor does not set the default value!)\" );\n- 459 if((size_type)_capacity > _n)\n- 460 storage_.reserve(_capacity);\n- 461 storage_.resize(_n);\n- 462 syncBaseArray();\n- 463 }\n- 464\n- 465\n-475 void reserve(size_type capacity)\n- 476 {\n- 477 [[maybe_unused]] const auto &guard =\n- 478 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n- 479 storage_.reserve(capacity);\n- 480 }\n- 481\n-488 size_type capacity() const\n- 489 {\n- 490 return storage_.capacity();\n- 491 }\n- 492\n-503 void resize(size_type size)\n- 504 {\n- 505 [[maybe_unused]] const auto &guard =\n- 506 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n- 507 storage_.resize(size);\n- 508 }\n- 509\n-511 BlockVector(const BlockVector &a)\n- 512 noexcept(noexcept(std::declval().storage_ = a.storage_))\n- 513 {\n- 514 storage_ = a.storage_;\n- 515 syncBaseArray();\n- 516 }\n+ 446 void relaxResult(field_type relax);\n+ 447\n+ 452 void operator()(const size_type& domain);\n+ 453\n+ 461 void assignResult(block_type& res);\n+ 462\n+ 463 private:\n+ 467 const M* mat;\n+ 469 X* lhs_;\n+ 471 Y* rhs_;\n+ 473 const Y* b;\n+ 475 X* x;\n+ 477 size_type i;\n+ 478 };\n+ 479\n+ 480 // specialization for ILU0\n+ 481 template\n+482 class OverlappingAssignerHelper, false>\n+ 483 : public OverlappingAssignerILUBase\n+ 484 {\n+ 485 public:\n+493 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,\n+ 494 const Y& b, X& x)\n+ 495 : OverlappingAssignerILUBase(maxlength, mat,b,x)\n+ 496 {}\n+ 497 };\n+ 498\n+ 499 // specialization for ILUN\n+ 500 template\n+501 class OverlappingAssignerHelper,false>\n+ 502 : public OverlappingAssignerILUBase\n+ 503 {\n+ 504 public:\n+512 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,\n+ 513 const Y& b, X& x)\n+ 514 : OverlappingAssignerILUBase(maxlength, mat,b,x)\n+ 515 {}\n+ 516 };\n 517\n-519 BlockVector(BlockVector &&a)\n- 520 noexcept(noexcept(std::declval().swap(a)))\n- 521 {\n- 522 swap(a);\n- 523 }\n- 524\n-526 BlockVector& operator=(const BlockVector& a)\n- 527 noexcept(noexcept(std::declval().storage_ = a.storage_))\n- 528 {\n- 529 [[maybe_unused]] const auto &guard =\n- 530 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n- 531 storage_ = a.storage_;\n- 532 return *this;\n- 533 }\n- 534\n-536 BlockVector& operator=(BlockVector&& a)\n- 537 noexcept(noexcept(std::declval().swap(a)))\n- 538 {\n- 539 swap(a);\n- 540 return *this;\n- 541 }\n- 542\n-544 void swap(BlockVector &other)\n- 545 noexcept(noexcept(\n- 546 std::declval().storage_.swap(other.storage_)))\n- 547 {\n- 548 [[maybe_unused]] const auto &guard = Imp::makeScopeGuard([&]{\n- 549 syncBaseArray();\n- 550 other.syncBaseArray();\n- 551 });\n- 552 storage_.swap(other.storage_);\n- 553 }\n+ 518 template\n+519 struct AdditiveAdder\n+ 520 {};\n+ 521\n+ 522 template\n+523 struct AdditiveAdder >\n+ 524 {\n+525 typedef typename A::size_type size_type;\n+526 typedef typename std::decay_t\n+()))>::field_type field_type;\n+ 527 AdditiveAdder(BlockVector& v, BlockVector& x,\n+ 528 OverlappingAssigner& assigner, const field_type& relax_);\n+ 529 void operator()(const size_type& domain);\n+ 530 void axpy();\n+531 static constexpr size_t n = std::decay_t()))>::dimension;\n+ 532\n+ 533 private:\n+ 534 BlockVector* v;\n+ 535 BlockVector* x;\n+ 536 OverlappingAssigner* assigner;\n+ 537 field_type relax;\n+ 538 };\n+ 539\n+ 540 template\n+541 struct MultiplicativeAdder\n+ 542 {};\n+ 543\n+ 544 template\n+545 struct MultiplicativeAdder >\n+ 546 {\n+547 typedef typename A::size_type size_type;\n+548 typedef typename std::decay_t\n+()))>::field_type field_type;\n+ 549 MultiplicativeAdder(BlockVector& v, BlockVector& x,\n+ 550 OverlappingAssigner& assigner_, const field_type& relax_);\n+ 551 void operator()(const size_type& domain);\n+ 552 void axpy();\n+553 static constexpr size_t n = std::decay_t()))>::dimension;\n 554\n-556 BlockVector& operator=(const field_type& k)\n- 557 {\n- 558 // forward to operator= in base class\n- 559 (static_cast&>(*this)) = k;\n- 560 return *this;\n- 561 }\n- 562\n- 563 private:\n- 564 void syncBaseArray() noexcept\n- 565 {\n- 566 this->p = storage_.data();\n- 567 this->n = storage_.size();\n- 568 }\n- 569\n- 570 std::vector storage_;\n- 571 };\n- 572\n- 578 template\n-579 struct FieldTraits< BlockVector >\n- 580 {\n-581 typedef typename FieldTraits::field_type field_type;\n-582 typedef typename FieldTraits::real_type real_type;\n- 583 };\n- 589 template\n-590 std::ostream& operator<<(std::ostream& s, const BlockVector& v)\n- 591 {\n- 592 typedef typename BlockVector::size_type size_type;\n- 593\n- 594 for (size_type i=0; i\n- 623#else\n- 624 template >\n- 625#endif\n- 626 class BlockVectorWindow : public Imp::block_vector_unmanaged\n- 627 {\n- 628 public:\n- 629\n- 630 //===== type definitions and constants\n- 631\n- 633 using field_type = typename Imp::BlockTraits::field_type;\n- 634\n- 636 typedef B block_type;\n- 637\n- 639 typedef A allocator_type;\n- 640\n- 642 typedef typename A::size_type size_type;\n+ 555 private:\n+ 556 BlockVector* x;\n+ 557 OverlappingAssigner* assigner;\n+ 558 field_type relax;\n+ 559 };\n+ 560\n+ 570 template\n+571 struct AdderSelector\n+ 572 {};\n+ 573\n+ 574 template\n+575 struct AdderSelector\n+ 576 {\n+577 typedef AdditiveAdder Adder;\n+ 578 };\n+ 579\n+ 580 template\n+581 struct AdderSelector\n+ 582 {\n+583 typedef MultiplicativeAdder Adder;\n+ 584 };\n+ 585\n+ 586 template\n+587 struct AdderSelector\n+ 588 {\n+589 typedef MultiplicativeAdder Adder;\n+ 590 };\n+ 591\n+ 603 template\n+604 struct IteratorDirectionSelector\n+ 605 {\n+606 typedef T1 solver_vector;\n+607 typedef typename solver_vector::iterator solver_iterator;\n+608 typedef T2 subdomain_vector;\n+609 typedef typename subdomain_vector::const_iterator domain_iterator;\n+ 610\n+611 static solver_iterator begin(solver_vector& sv)\n+ 612 {\n+ 613 return sv.begin();\n+ 614 }\n+ 615\n+616 static solver_iterator end(solver_vector& sv)\n+ 617 {\n+ 618 return sv.end();\n+ 619 }\n+620 static domain_iterator begin(const subdomain_vector& sv)\n+ 621 {\n+ 622 return sv.begin();\n+ 623 }\n+ 624\n+625 static domain_iterator end(const subdomain_vector& sv)\n+ 626 {\n+ 627 return sv.end();\n+ 628 }\n+ 629 };\n+ 630\n+ 631 template\n+632 struct IteratorDirectionSelector\n+ 633 {\n+634 typedef T1 solver_vector;\n+635 typedef typename solver_vector::reverse_iterator solver_iterator;\n+636 typedef T2 subdomain_vector;\n+637 typedef typename subdomain_vector::const_reverse_iterator domain_iterator;\n+ 638\n+639 static solver_iterator begin(solver_vector& sv)\n+ 640 {\n+ 641 return sv.rbegin();\n+ 642 }\n 643\n- 645 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n- 646 static constexpr unsigned int blocklevel = blockLevel()+1;\n- 647\n- 649 typedef typename Imp::block_vector_unmanaged::Iterator Iterator;\n- 650\n- 652 typedef typename Imp::block_vector_unmanaged::ConstIterator\n-ConstIterator;\n- 653\n- 654\n- 655 //===== constructors and such\n- 657 BlockVectorWindow () : Imp::block_vector_unmanaged()\n- 658 { }\n- 659\n- 661 BlockVectorWindow (B* _p, size_type _n)\n- 662 {\n- 663 this->n = _n;\n- 664 this->p = _p;\n- 665 }\n- 666\n- 668 BlockVectorWindow (const BlockVectorWindow& a)\n+644 static solver_iterator end(solver_vector& sv)\n+ 645 {\n+ 646 return sv.rend();\n+ 647 }\n+648 static domain_iterator begin(const subdomain_vector& sv)\n+ 649 {\n+ 650 return sv.rbegin();\n+ 651 }\n+ 652\n+653 static domain_iterator end(const subdomain_vector& sv)\n+ 654 {\n+ 655 return sv.rend();\n+ 656 }\n+ 657 };\n+ 658\n+ 667 template\n+668 struct SeqOverlappingSchwarzApplier\n 669 {\n- 670 this->n = a.n;\n- 671 this->p = a.p;\n- 672 }\n- 673\n- 675 BlockVectorWindow& operator= (const BlockVectorWindow& a)\n- 676 {\n- 677 // check correct size\n- 678#ifdef DUNE_ISTL_WITH_CHECKING\n- 679 if (this->n!=a.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 680#endif\n- 681\n- 682 if (&a!=this) // check if this and a are different objects\n- 683 {\n- 684 // copy data\n- 685 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n- 686 }\n- 687 return *this;\n- 688 }\n- 689\n- 691 BlockVectorWindow& operator= (const field_type& k)\n- 692 {\n- 693 (static_cast&>(*this)) = k;\n- 694 return *this;\n- 695 }\n- 696\n- 698 operator BlockVector() const {\n- 699 auto bv = BlockVector(this->n);\n- 700\n- 701 std::copy(this->begin(), this->end(), bv.begin());\n- 702\n- 703 return bv;\n- 704 }\n- 705\n- 706 //===== window manipulation methods\n- 707\n- 709 void set (size_type _n, B* _p)\n- 710 {\n- 711 this->n = _n;\n- 712 this->p = _p;\n- 713 }\n- 714\n- 716 void setsize (size_type _n)\n- 717 {\n- 718 this->n = _n;\n- 719 }\n+670 typedef T smoother;\n+671 typedef typename smoother::range_type range_type;\n+ 672\n+673 static void apply(smoother& sm, range_type& v, const range_type& b)\n+ 674 {\n+ 675 sm.template apply(v, b);\n+ 676 }\n+ 677 };\n+ 678\n+ 679 template\n+680 struct\n+SeqOverlappingSchwarzApplier\n+>\n+ 681 {\n+682 typedef SeqOverlappingSchwarz\n+smoother;\n+683 typedef typename smoother::range_type range_type;\n+ 684\n+685 static void apply(smoother& sm, range_type& v, const range_type& b)\n+ 686 {\n+ 687 sm.template apply(v, b);\n+ 688 sm.template apply(v, b);\n+ 689 }\n+ 690 };\n+ 691\n+ 692 template\n+693 struct SeqOverlappingSchwarzAssemblerHelper\n+ 694 {};\n+ 695\n+ 696 template\n+697 using SeqOverlappingSchwarzAssembler =\n+SeqOverlappingSchwarzAssemblerHelper::value>;\n+ 698\n+ 699 template\n+700 struct SeqOverlappingSchwarzAssemblerHelper< DynamicMatrixSubdomainSolver<\n+BCRSMatrix< K, Al>, X, Y >,false>\n+ 701 {\n+702 typedef BCRSMatrix<_K,_Al> matrix_type;\n+703 static constexpr size_t n = std::decay_t()))>::rows;\n+ 704 template\n+ 705 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n+const matrix_type& mat,\n+ 706 Solvers& solvers, const SubDomains& domains,\n+ 707 bool onTheFly);\n+ 708 };\n+ 709\n+ 710 template class S, typename T, typename A>\n+711 struct SeqOverlappingSchwarzAssemblerHelper>,true>\n+ 712 {\n+713 typedef BCRSMatrix matrix_type;\n+714 static constexpr size_t n = std::decay_t()))>::rows;\n+ 715 template\n+ 716 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n+const matrix_type& mat,\n+ 717 Solvers& solvers, const SubDomains& domains,\n+ 718 bool onTheFly);\n+ 719 };\n 720\n- 722 void setptr (B* _p)\n+ 721 template\n+722 struct SeqOverlappingSchwarzAssemblerILUBase\n 723 {\n- 724 this->p = _p;\n- 725 }\n- 726\n- 728 B* getptr ()\n- 729 {\n- 730 return this->p;\n- 731 }\n- 732\n- 734 size_type getsize () const\n- 735 {\n- 736 return this->n;\n- 737 }\n- 738 };\n- 739\n+724 typedef M matrix_type;\n+ 725 template\n+ 726 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n+const matrix_type& mat,\n+ 727 Solvers& solvers, const SubDomains& domains,\n+ 728 bool onTheFly);\n+ 729 };\n+ 730\n+ 731 template\n+732 struct\n+SeqOverlappingSchwarzAssemblerHelper,false>\n+ 733 : public SeqOverlappingSchwarzAssemblerILUBase\n+ 734 {};\n+ 735\n+ 736 template\n+737 struct\n+SeqOverlappingSchwarzAssemblerHelper,false>\n+ 738 : public SeqOverlappingSchwarzAssemblerILUBase\n+ 739 {};\n 740\n- 741\n- 752 template >\n- 753 class compressed_block_vector_unmanaged : public\n-compressed_base_array_unmanaged\n- 754 {\n- 755 public:\n- 756\n- 757 //===== type definitions and constants\n- 758\n- 760 using field_type = typename Imp::BlockTraits::field_type;\n+ 751 template, class TA=std::allocator >\n+753 class SeqOverlappingSchwarz\n+ 754 : public Preconditioner\n+ 755 {\n+ 756 public:\n+760 typedef M matrix_type;\n 761\n- 763 typedef B block_type;\n- 764\n- 766 typedef A allocator_type;\n- 767\n- 769 typedef typename compressed_base_array_unmanaged::iterator Iterator;\n- 770\n- 772 typedef typename compressed_base_array_unmanaged::const_iterator\n-ConstIterator;\n- 773\n- 775 typedef typename A::size_type size_type;\n- 776\n- 777 //===== assignment from scalar\n- 778\n- 779 compressed_block_vector_unmanaged& operator= (const field_type& k)\n- 780 {\n- 781 for (size_type i=0; in; i++)\n- 782 (this->p)[i] = k;\n- 783 return *this;\n- 784 }\n- 785\n- 786\n- 787 //===== vector space arithmetic\n- 788\n- 790 template\n- 791 compressed_block_vector_unmanaged& operator+= (const V& y)\n- 792 {\n- 793#ifdef DUNE_ISTL_WITH_CHECKING\n- 794 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n- 795#endif\n- 796 for (size_type i=0; ioperator[](y.j[i]) += y.p[i];\n- 797 return *this;\n- 798 }\n- 799\n- 801 template\n- 802 compressed_block_vector_unmanaged& operator-= (const V& y)\n- 803 {\n- 804#ifdef DUNE_ISTL_WITH_CHECKING\n- 805 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n- 806#endif\n- 807 for (size_type i=0; ioperator[](y.j[i]) -= y.p[i];\n- 808 return *this;\n- 809 }\n+765 typedef X domain_type;\n+ 766\n+770 typedef X range_type;\n+ 771\n+778 typedef TM Mode;\n+ 779\n+783 typedef typename X::field_type field_type;\n+ 784\n+786 typedef typename matrix_type::size_type size_type;\n+ 787\n+789 typedef TA allocator;\n+ 790\n+ 792 typedef std::set,\n+ 793 typename std::allocator_traits::template rebind_alloc >\n+794 subdomain_type;\n+ 795\n+797 typedef std::vector::\n+template rebind_alloc > subdomain_vector;\n+ 798\n+800 typedef SLList::template\n+rebind_alloc > subdomain_list;\n+ 801\n+803 typedef std::vector::\n+template rebind_alloc > rowtodomain_vector;\n+ 804\n+806 typedef TD slu;\n+ 807\n+809 typedef std::vector::template\n+rebind_alloc > slu_vector;\n 810\n- 812 template\n- 813 compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)\n- 814 {\n- 815#ifdef DUNE_ISTL_WITH_CHECKING\n- 816 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n- 817#endif\n- 818 for (size_type i=0; in; ++i) (this->p)[i] *= k;\n- 827 return *this;\n- 828 }\n- 829\n- 831 compressed_block_vector_unmanaged& operator/= (const field_type& k)\n- 832 {\n- 833 for (size_type i=0; in; ++i) (this->p)[i] /= k;\n- 834 return *this;\n- 835 }\n- 836\n- 837\n- 838 //===== Euclidean scalar product\n- 839\n- 841 field_type operator* (const compressed_block_vector_unmanaged& y) const\n- 842 {\n- 843#ifdef DUNE_ISTL_WITH_CHECKING\n- 844 if (!includesindexset(y) || !y.includesindexset(*this) )\n- 845 DUNE_THROW(ISTLError,\"index set mismatch\");\n- 846#endif\n- 847 field_type sum=0;\n- 848 for (size_type i=0; in; ++i)\n- 849 sum += (this->p)[i] * y[(this->j)[i]];\n- 850 return sum;\n- 851 }\n- 852\n- 853\n- 854 //===== norms\n+824 SeqOverlappingSchwarz(const matrix_type& mat, const subdomain_vector&\n+subDomains,\n+ 825 field_type relaxationFactor=1, bool onTheFly_=true);\n+ 826\n+838 SeqOverlappingSchwarz(const matrix_type& mat, const rowtodomain_vector&\n+rowToDomain,\n+ 839 field_type relaxationFactor=1, bool onTheFly_=true);\n+ 840\n+846 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] X& b)\n+ 847 {}\n+ 848\n+854 virtual void apply (X& v, const X& d);\n 855\n- 857 typename FieldTraits::real_type one_norm () const\n- 858 {\n- 859 typename FieldTraits::real_type sum=0;\n- 860 for (size_type i=0; in; ++i) sum += (this->p)[i].one_norm();\n- 861 return sum;\n- 862 }\n+861 virtual void post ([[maybe_unused]] X& x)\n+ 862 {}\n 863\n- 865 typename FieldTraits::real_type one_norm_real () const\n- 866 {\n- 867 typename FieldTraits::real_type sum=0;\n- 868 for (size_type i=0; in; ++i) sum += (this->p)[i].one_norm_real();\n- 869 return sum;\n- 870 }\n- 871\n- 873 typename FieldTraits::real_type two_norm () const\n- 874 {\n- 875 using std::sqrt;\n- 876 typename FieldTraits::real_type sum=0;\n- 877 for (size_type i=0; in; ++i) sum += (this->p)[i].two_norm2();\n- 878 return sqrt(sum);\n- 879 }\n+ 864 template\n+865 void apply(X& v, const X& d);\n+ 866\n+868 virtual SolverCategory::Category category() const\n+ 869 {\n+ 870 return SolverCategory::sequential;\n+ 871 }\n+ 872\n+ 873 private:\n+ 874 const M& mat;\n+ 875 slu_vector solvers;\n+ 876 subdomain_vector subDomains;\n+ 877 field_type relax;\n+ 878\n+ 879 typename M::size_type maxlength;\n 880\n- 882 typename FieldTraits::real_type two_norm2 () const\n- 883 {\n- 884 typename FieldTraits::real_type sum=0;\n- 885 for (size_type i=0; in; ++i) sum += (this->p)[i].two_norm2();\n- 886 return sum;\n- 887 }\n- 888\n- 890 template ::value, int>::type = 0>\n- 892 typename FieldTraits::real_type infinity_norm() const {\n- 893 using real_type = typename FieldTraits::real_type;\n- 894 using std::max;\n- 895\n- 896 real_type norm = 0;\n- 897 for (auto const &x : *this) {\n- 898 real_type const a = x.infinity_norm();\n- 899 norm = max(a, norm);\n- 900 }\n- 901 return norm;\n+ 881 bool onTheFly;\n+ 882 };\n+ 883\n+ 884\n+ 885\n+ 886 template\n+887 OverlappingSchwarzInitializer::OverlappingSchwarzInitializer\n+(InitializerList& il,\n+ 888 const IndexSet& idx,\n+ 889 const subdomain_vector& domains_)\n+ 890 : initializers(&il), indices(&idx), indexMaps(il.size()), domains\n+(domains_)\n+ 891 {}\n+ 892\n+ 893\n+ 894 template\n+895 void OverlappingSchwarzInitializer::addRowNnz(const Iter& row)\n+ 896 {\n+ 897 typedef typename IndexSet::value_type::const_iterator iterator;\n+ 898 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)\n+[row.index()].end(); ++domain) {\n+ 899 (*initializers)[*domain].addRowNnz(row, domains[*domain]);\n+ 900 indexMaps[*domain].insert(row.index());\n+ 901 }\n 902 }\n 903\n- 905 template ::value, int>::type = 0>\n- 907 typename FieldTraits::real_type infinity_norm_real() const {\n- 908 using real_type = typename FieldTraits::real_type;\n- 909 using std::max;\n- 910\n- 911 real_type norm = 0;\n- 912 for (auto const &x : *this) {\n- 913 real_type const a = x.infinity_norm_real();\n- 914 norm = max(a, norm);\n- 915 }\n- 916 return norm;\n- 917 }\n- 918\n- 920 template ::value, int>::type = 0>\n- 922 typename FieldTraits::real_type infinity_norm() const {\n- 923 using real_type = typename FieldTraits::real_type;\n- 924 using std::max;\n- 925\n- 926 real_type norm = 0;\n- 927 real_type isNaN = 1;\n- 928 for (auto const &x : *this) {\n- 929 real_type const a = x.infinity_norm();\n- 930 norm = max(a, norm);\n- 931 isNaN += a;\n- 932 }\n- 933 return norm * (isNaN / isNaN);\n- 934 }\n- 935\n- 937 template ::value, int>::type = 0>\n- 939 typename FieldTraits::real_type infinity_norm_real() const {\n- 940 using real_type = typename FieldTraits::real_type;\n- 941 using std::max;\n- 942\n- 943 real_type norm = 0;\n- 944 real_type isNaN = 1;\n- 945 for (auto const &x : *this) {\n- 946 real_type const a = x.infinity_norm_real();\n- 947 norm = max(a, norm);\n- 948 isNaN += a;\n- 949 }\n- 950 return norm * (isNaN / isNaN);\n- 951 }\n- 952\n- 953 //===== sizes\n- 954\n- 956 size_type N () const\n- 957 {\n- 958 return this->n;\n- 959 }\n- 960\n- 962 size_type dim () const\n- 963 {\n- 964 size_type d=0;\n- 965 for (size_type i=0; in; i++)\n- 966 d += (this->p)[i].dim();\n- 967 return d;\n- 968 }\n- 969\n- 970 protected:\n- 972 compressed_block_vector_unmanaged () :\n-compressed_base_array_unmanaged()\n- 973 { }\n- 974\n- 976 template\n- 977 bool includesindexset (const V& y)\n- 978 {\n- 979 typename V::ConstIterator e=this->end();\n- 980 for (size_type i=0; ifind(y.j[i])==e)\n- 982 return false;\n- 983 return true;\n- 984 }\n- 985 };\n+ 904 template\n+905 void OverlappingSchwarzInitializer::allocate()\n+ 906 {\n+ 907 for(auto&& i: *initializers)\n+ 908 i.allocateMatrixStorage();\n+ 909 for(auto&& i: *initializers)\n+ 910 i.allocateMarker();\n+ 911 }\n+ 912\n+ 913 template\n+914 void OverlappingSchwarzInitializer::countEntries(const Iter& row,\n+const CIter& col) const\n+ 915 {\n+ 916 typedef typename IndexSet::value_type::const_iterator iterator;\n+ 917 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)\n+[row.index()].end(); ++domain) {\n+ 918 typename std::map::const_iterator v = indexMaps\n+[*domain].find(col.index());\n+ 919 if(v!= indexMaps[*domain].end()) {\n+ 920 (*initializers)[*domain].countEntries(indexMaps[*domain].find(col.index\n+())->second);\n+ 921 }\n+ 922 }\n+ 923 }\n+ 924\n+ 925 template\n+926 void OverlappingSchwarzInitializer::calcColstart() const\n+ 927 {\n+ 928 for(auto&& i : *initializers)\n+ 929 i.calcColstart();\n+ 930 }\n+ 931\n+ 932 template\n+933 void OverlappingSchwarzInitializer::copyValue(const Iter& row, const\n+CIter& col) const\n+ 934 {\n+ 935 typedef typename IndexSet::value_type::const_iterator iterator;\n+ 936 for(iterator domain=(*indices)[row.index()].begin(); domain!= (*indices)\n+[row.index()].end(); ++domain) {\n+ 937 typename std::map::const_iterator v = indexMaps\n+[*domain].find(col.index());\n+ 938 if(v!= indexMaps[*domain].end()) {\n+ 939 assert(indexMaps[*domain].end()!=indexMaps[*domain].find(row.index()));\n+ 940 (*initializers)[*domain].copyValue(col, indexMaps[*domain].find(row.index\n+())->second,\n+ 941 v->second);\n+ 942 }\n+ 943 }\n+ 944 }\n+ 945\n+ 946 template\n+947 void OverlappingSchwarzInitializer::createMatrix() const\n+ 948 {\n+ 949 std::vector().swap(indexMaps);\n+ 950 for(auto&& i: *initializers)\n+ 951 i.createMatrix();\n+ 952 }\n+ 953\n+ 954 template\n+955 OverlappingSchwarzInitializer::IndexMap::IndexMap()\n+ 956 : row(0)\n+ 957 {}\n+ 958\n+ 959 template\n+960 void OverlappingSchwarzInitializer::IndexMap::insert(size_type grow)\n+ 961 {\n+ 962 assert(map_.find(grow)==map_.end());\n+ 963 map_.insert(std::make_pair(grow, row++));\n+ 964 }\n+ 965\n+ 966 template\n+ 967 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n+968 OverlappingSchwarzInitializer::IndexMap::find(size_type grow) const\n+ 969 {\n+ 970 return map_.find(grow);\n+ 971 }\n+ 972\n+ 973 template\n+ 974 typename OverlappingSchwarzInitializer::IndexMap::iterator\n+975 OverlappingSchwarzInitializer::IndexMap::find(size_type grow)\n+ 976 {\n+ 977 return map_.find(grow);\n+ 978 }\n+ 979\n+ 980 template\n+ 981 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n+982 OverlappingSchwarzInitializer::IndexMap::end() const\n+ 983 {\n+ 984 return map_.end();\n+ 985 }\n 986\n- 987\n- 1006 template >\n- 1007 class CompressedBlockVectorWindow : public\n-compressed_block_vector_unmanaged\n- 1008 {\n- 1009 public:\n- 1010\n- 1011 //===== type definitions and constants\n- 1012\n- 1014 using field_type = typename Imp::BlockTraits::field_type;\n- 1015\n- 1017 typedef B block_type;\n+ 987 template\n+ 988 typename OverlappingSchwarzInitializer::IndexMap::iterator\n+989 OverlappingSchwarzInitializer::IndexMap::end()\n+ 990 {\n+ 991 return map_.end();\n+ 992 }\n+ 993\n+ 994 template\n+ 995 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n+996 OverlappingSchwarzInitializer::IndexMap::begin() const\n+ 997 {\n+ 998 return map_.begin();\n+ 999 }\n+ 1000\n+ 1001 template\n+ 1002 typename OverlappingSchwarzInitializer::IndexMap::iterator\n+1003 OverlappingSchwarzInitializer::IndexMap::begin()\n+ 1004 {\n+ 1005 return map_.begin();\n+ 1006 }\n+ 1007\n+ 1008 template\n+1009 SeqOverlappingSchwarz::SeqOverlappingSchwarz(const\n+matrix_type& mat_, const rowtodomain_vector& rowToDomain,\n+ 1010 field_type relaxationFactor, bool fly)\n+ 1011 : mat(mat_), relax(relaxationFactor), onTheFly(fly)\n+ 1012 {\n+ 1013 typedef typename rowtodomain_vector::const_iterator RowDomainIterator;\n+ 1014 typedef typename subdomain_list::const_iterator DomainIterator;\n+ 1015#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1016 assert(rowToDomain.size()==mat.N());\n+ 1017 assert(rowToDomain.size()==mat.M());\n 1018\n- 1020 typedef A allocator_type;\n+ 1019 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n+(); ++iter)\n+ 1020 assert(iter->size()>0);\n 1021\n- 1023 typedef typename A::size_type size_type;\n- 1024\n- 1026 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n- 1027 static constexpr unsigned int blocklevel = blockLevel()+1;\n- 1028\n- 1030 typedef typename compressed_block_vector_unmanaged::Iterator\n-Iterator;\n- 1031\n- 1033 typedef typename compressed_block_vector_unmanaged::ConstIterator\n-ConstIterator;\n- 1034\n- 1035\n- 1036 //===== constructors and such\n- 1038 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged()\n- 1039 { }\n- 1040\n- 1042 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)\n- 1043 {\n- 1044 this->n = _n;\n- 1045 this->p = _p;\n- 1046 this->j = _j;\n+ 1022#endif\n+ 1023 // calculate the number of domains\n+ 1024 size_type domains=0;\n+ 1025 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n+(); ++iter)\n+ 1026 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)\n+ 1027 domains=std::max(domains, *d);\n+ 1028 ++domains;\n+ 1029\n+ 1030 solvers.resize(domains);\n+ 1031 subDomains.resize(domains);\n+ 1032\n+ 1033 // initialize subdomains to row mapping from row to subdomain mapping\n+ 1034 size_type row=0;\n+ 1035 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n+(); ++iter, ++row)\n+ 1036 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)\n+ 1037 subDomains[*d].insert(row);\n+ 1038\n+ 1039#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1040 size_type i=0;\n+ 1041 typedef typename subdomain_vector::const_iterator iterator;\n+ 1042 for(iterator iter=subDomains.begin(); iter != subDomains.end(); ++iter) {\n+ 1043 typedef typename subdomain_type::const_iterator entry_iterator;\n+ 1044 Dune::dvverb<<\"domain \"<begin(); entry != iter->end(); ++entry)\n+{\n+ 1046 Dune::dvverb<<\" \"<<*entry;\n 1047 }\n- 1048\n- 1050 CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)\n- 1051 {\n- 1052 this->n = a.n;\n- 1053 this->p = a.p;\n- 1054 this->j = a.j;\n- 1055 }\n- 1056\n- 1058 CompressedBlockVectorWindow& operator= (const\n-CompressedBlockVectorWindow& a)\n- 1059 {\n- 1060 // check correct size\n- 1061#ifdef DUNE_ISTL_WITH_CHECKING\n- 1062 if (this->n!=a.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n- 1063#endif\n+ 1048 Dune::dvverb<\n+ 1052::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);\n+ 1053 }\n+ 1054\n+ 1055 template\n+1056 SeqOverlappingSchwarz::SeqOverlappingSchwarz(const\n+matrix_type& mat_,\n+ 1057 const subdomain_vector& sd,\n+ 1058 field_type relaxationFactor,\n+ 1059 bool fly)\n+ 1060 : mat(mat_), solvers(sd.size()), subDomains(sd), relax(relaxationFactor),\n+ 1061 onTheFly(fly)\n+ 1062 {\n+ 1063 typedef typename subdomain_vector::const_iterator DomainIterator;\n 1064\n- 1065 if (&a!=this) // check if this and a are different objects\n- 1066 {\n- 1067 // copy data\n- 1068 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n- 1069 for (size_type i=0; in; i++) this->j[i]=a.j[i];\n- 1070 }\n- 1071 return *this;\n- 1072 }\n- 1073\n- 1075 CompressedBlockVectorWindow& operator= (const field_type& k)\n- 1076 {\n- 1077 (static_cast&>(*this)) = k;\n- 1078 return *this;\n- 1079 }\n+ 1065#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1066 size_type i=0;\n+ 1067\n+ 1068 for(DomainIterator d=sd.begin(); d != sd.end(); ++d,++i) {\n+ 1069 //std::cout<size()<size()>0);\n+ 1071 typedef typename DomainIterator::value_type::const_iterator\n+entry_iterator;\n+ 1072 Dune::dvverb<<\"domain \"<begin(); entry != d->end(); ++entry) {\n+ 1074 Dune::dvverb<<\" \"<<*entry;\n+ 1075 }\n+ 1076 Dune::dvverb<n = _n;\n- 1088 this->p = _p;\n- 1089 this->j = _j;\n+ 1084 size_type domainId=0;\n+ 1085\n+ 1086 for(DomainIterator domain=sd.begin(); domain != sd.end(); ++domain,\n+++domainId) {\n+ 1087 typedef typename subdomain_type::const_iterator iterator;\n+ 1088 for(iterator row=domain->begin(); row != domain->end(); ++row)\n+ 1089 rowToDomain[*row].push_back(domainId);\n 1090 }\n 1091\n- 1093 void setsize (size_type _n)\n- 1094 {\n- 1095 this->n = _n;\n- 1096 }\n- 1097\n- 1099 void setptr (B* _p)\n- 1100 {\n- 1101 this->p = _p;\n- 1102 }\n- 1103\n- 1105 void setindexptr (size_type* _j)\n- 1106 {\n- 1107 this->j = _j;\n- 1108 }\n- 1109\n- 1111 B* getptr ()\n+ 1092 maxlength = SeqOverlappingSchwarzAssembler\n+ 1093::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);\n+ 1094 }\n+ 1095\n+ 1102 template\n+1103 struct SeqOverlappingSchwarzDomainSize {};\n+ 1104\n+ 1105 template\n+1106 struct SeqOverlappingSchwarzDomainSize >\n+ 1107 {\n+1108 static constexpr size_t n = std::decay_t()))>::rows;\n+1109 static constexpr size_t m = std::decay_t()))>::cols;\n+ 1110 template\n+1111 static int size(const Domain & d)\n 1112 {\n- 1113 return this->p;\n- 1114 }\n- 1115\n- 1117 size_type* getindexptr ()\n- 1118 {\n- 1119 return this->j;\n- 1120 }\n- 1121\n- 1123 const B* getptr () const\n- 1124 {\n- 1125 return this->p;\n- 1126 }\n- 1127\n- 1129 const size_type* getindexptr () const\n- 1130 {\n- 1131 return this->j;\n- 1132 }\n- 1134 size_type getsize () const\n- 1135 {\n- 1136 return this->n;\n- 1137 }\n- 1138 };\n+ 1113 assert(n==m);\n+ 1114 return m*d.size();\n+ 1115 }\n+ 1116 };\n+ 1117\n+ 1118 template\n+ 1119 template\n+ 1120 std::size_t\n+1121 SeqOverlappingSchwarzAssemblerHelper<_DynamicMatrixSubdomainSolver<\n+BCRSMatrix<_K,_Al>, X, Y >,false>::\n+ 1122 assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,\n+ 1123 [[maybe_unused]] const matrix_type& mat,\n+ 1124 [[maybe_unused]] Solvers& solvers,\n+ 1125 const SubDomains& subDomains,\n+ 1126 [[maybe_unused]] bool onTheFly)\n+ 1127 {\n+ 1128 typedef typename SubDomains::const_iterator DomainIterator;\n+ 1129 std::size_t maxlength = 0;\n+ 1130\n+ 1131 assert(onTheFly);\n+ 1132\n+ 1133 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n+++domain)\n+ 1134 maxlength=std::max(maxlength, domain->size());\n+ 1135 maxlength*=n;\n+ 1136\n+ 1137 return maxlength;\n+ 1138 }\n 1139\n- 1140} // end namespace 'Imp'\n- 1141\n- 1142\n- 1144 template\n- 1145 struct AutonomousValueType>\n- 1146 {\n- 1147 using type = BlockVector;\n- 1148 };\n- 1149\n- 1150\n- 1151} // end namespace 'Dune'\n- 1152\n- 1153#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n-basearray.hh\n-Implements several basic array containers.\n-istlexception.hh\n-std\n-STL namespace.\n+ 1140#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n+ 1141 template class S, typename T, typename A>\n+ 1142 template\n+1143 std::size_t\n+SeqOverlappingSchwarzAssemblerHelper>,true>::\n+assembleLocalProblems(const RowToDomain& rowToDomain,\n+ 1144 const matrix_type& mat,\n+ 1145 Solvers& solvers,\n+ 1146 const SubDomains& subDomains,\n+ 1147 bool onTheFly)\n+ 1148 {\n+ 1149 typedef typename S>::MatrixInitializer MatrixInitializer;\n+ 1150 typedef typename std::vector::iterator\n+InitializerIterator;\n+ 1151 typedef typename SubDomains::const_iterator DomainIterator;\n+ 1152 typedef typename Solvers::iterator SolverIterator;\n+ 1153 std::size_t maxlength = 0;\n+ 1154\n+ 1155 if(onTheFly) {\n+ 1156 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n+++domain)\n+ 1157 maxlength=std::max(maxlength, domain->size());\n+ 1158 maxlength*=Impl::asMatrix(*mat[0].begin()).N();\n+ 1159 }else{\n+ 1160 // initialize the initializers\n+ 1161 DomainIterator domain=subDomains.begin();\n+ 1162\n+ 1163 // Create the initializers list.\n+ 1164 std::vector initializers(subDomains.size());\n+ 1165\n+ 1166 SolverIterator solver=solvers.begin();\n+ 1167 for(InitializerIterator initializer=initializers.begin();\n+initializer!=initializers.end();\n+ 1168 ++initializer, ++solver, ++domain) {\n+ 1169 solver->getInternalMatrix\n+().N_=SeqOverlappingSchwarzDomainSize::size(*domain);\n+ 1170 solver->getInternalMatrix\n+().M_=SeqOverlappingSchwarzDomainSize::size(*domain);\n+ 1171 //solver->setVerbosity(true);\n+ 1172 *initializer=MatrixInitializer(solver->getInternalMatrix());\n+ 1173 }\n+ 1174\n+ 1175 // Set up the supermatrices according to the subdomains\n+ 1176 typedef OverlappingSchwarzInitializer,\n+ 1177 RowToDomain, SubDomains> Initializer;\n+ 1178\n+ 1179 Initializer initializer(initializers, rowToDomain, subDomains);\n+ 1180 copyToBCCSMatrix(initializer, mat);\n+ 1181\n+ 1182 // Calculate the LU decompositions\n+ 1183 for(auto&& s: solvers)\n+ 1184 s.decompose();\n+ 1185 for (SolverIterator solverIt = solvers.begin(); solverIt != solvers.end\n+(); ++solverIt)\n+ 1186 {\n+ 1187 assert(solverIt->getInternalMatrix().N() == solverIt->getInternalMatrix\n+().M());\n+ 1188 maxlength = std::max(maxlength, solverIt->getInternalMatrix().N());\n+ 1189 }\n+ 1190 }\n+ 1191 return maxlength;\n+ 1192 }\n+ 1193\n+ 1194#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n+ 1195\n+ 1196 template\n+ 1197 template\n+1198 std::size_t SeqOverlappingSchwarzAssemblerILUBase::\n+assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,\n+ 1199 const matrix_type& mat,\n+ 1200 Solvers& solvers,\n+ 1201 const SubDomains& subDomains,\n+ 1202 bool onTheFly)\n+ 1203 {\n+ 1204 typedef typename SubDomains::const_iterator DomainIterator;\n+ 1205 typedef typename Solvers::iterator SolverIterator;\n+ 1206 std::size_t maxlength = 0;\n+ 1207\n+ 1208 if(onTheFly) {\n+ 1209 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n+++domain)\n+ 1210 maxlength=std::max(maxlength, domain->size());\n+ 1211 }else{\n+ 1212 // initialize the solvers of the local prolems.\n+ 1213 SolverIterator solver=solvers.begin();\n+ 1214 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n+ 1215 ++domain, ++solver) {\n+ 1216 solver->setSubMatrix(mat, *domain);\n+ 1217 maxlength=std::max(maxlength, domain->size());\n+ 1218 }\n+ 1219 }\n+ 1220\n+ 1221 return maxlength;\n+ 1222\n+ 1223 }\n+ 1224\n+ 1225\n+ 1226 template\n+1227 void SeqOverlappingSchwarz::apply(X& x, const X& b)\n+ 1228 {\n+ 1229 SeqOverlappingSchwarzApplier::apply(*this, x, b);\n+ 1230 }\n+ 1231\n+ 1232 template\n+ 1233 template\n+ 1234 void SeqOverlappingSchwarz::apply(X& x, const X& b)\n+ 1235 {\n+ 1236 typedef slu_vector solver_vector;\n+ 1237 typedef typename\n+IteratorDirectionSelector::\n+solver_iterator iterator;\n+ 1238 typedef typename\n+IteratorDirectionSelector::\n+domain_iterator\n+ 1239 domain_iterator;\n+ 1240\n+ 1241 OverlappingAssigner assigner(maxlength, mat, b, x);\n+ 1242\n+ 1243 domain_iterator\n+domain=IteratorDirectionSelector::begin\n+(subDomains);\n+ 1244 iterator solver =\n+IteratorDirectionSelector::begin\n+(solvers);\n+ 1245 X v(x); // temporary for the update\n+ 1246 v=0;\n+ 1247\n+ 1248 typedef typename AdderSelector::Adder Adder;\n+ 1249 Adder adder(v, x, assigner, relax);\n+ 1250\n+ 1251 for(; domain !=\n+IteratorDirectionSelector::end\n+(subDomains); ++domain) {\n+ 1252 //Copy rhs to C-array for SuperLU\n+ 1253 std::for_each(domain->begin(), domain->end(), assigner);\n+ 1254 assigner.resetIndexForNextDomain();\n+ 1255 if(onTheFly) {\n+ 1256 // Create the subdomain solver\n+ 1257 slu sdsolver;\n+ 1258 sdsolver.setSubMatrix(mat, *domain);\n+ 1259 // Apply\n+ 1260 sdsolver.apply(assigner.lhs(), assigner.rhs());\n+ 1261 }else{\n+ 1262 solver->apply(assigner.lhs(), assigner.rhs());\n+ 1263 ++solver;\n+ 1264 }\n+ 1265\n+ 1266 //Add relaxed correction to from SuperLU to v\n+ 1267 std::for_each(domain->begin(), domain->end(), adder);\n+ 1268 assigner.resetIndexForNextDomain();\n+ 1269\n+ 1270 }\n+ 1271\n+ 1272 adder.axpy();\n+ 1273 assigner.deallocate();\n+ 1274 }\n+ 1275\n+ 1276 template\n+ 1277 OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K,\n+Al>, X, Y >,false>\n+1278 ::OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix& mat_,\n+ 1279 const X& b_, Y& x_) :\n+ 1280 mat(&mat_),\n+ 1281 rhs_( new DynamicVector(maxlength, 42) ),\n+ 1282 lhs_( new DynamicVector(maxlength, -42) ),\n+ 1283 b(&b_),\n+ 1284 x(&x_),\n+ 1285 i(0),\n+ 1286 maxlength_(maxlength)\n+ 1287 {}\n+ 1288\n+ 1289 template\n+ 1290 void\n+ 1291 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1292 ::deallocate()\n+ 1293 {\n+ 1294 delete rhs_;\n+ 1295 delete lhs_;\n+ 1296 }\n+ 1297\n+ 1298 template\n+ 1299 void\n+ 1300 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1301 ::resetIndexForNextDomain()\n+ 1302 {\n+ 1303 i=0;\n+ 1304 }\n+ 1305\n+ 1306 template\n+ 1307 DynamicVector &\n+ 1308 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1309 ::lhs()\n+ 1310 {\n+ 1311 return *lhs_;\n+ 1312 }\n+ 1313\n+ 1314 template\n+ 1315 DynamicVector &\n+ 1316 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1317 ::rhs()\n+ 1318 {\n+ 1319 return *rhs_;\n+ 1320 }\n+ 1321\n+ 1322 template\n+ 1323 void\n+ 1324 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1325 ::relaxResult(field_type relax)\n+ 1326 {\n+ 1327 lhs() *= relax;\n+ 1328 }\n+ 1329\n+ 1330 template\n+ 1331 void\n+ 1332 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1333 ::operator()(const size_type& domainIndex)\n+ 1334 {\n+ 1335 lhs() = 0.0;\n+ 1336#if 0\n+ 1337 //assign right hand side of current domainindex block\n+ 1338 for(size_type j=0; j\n+ 1376 void\n+ 1377 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al>, X, Y >,false>\n+1378 ::assignResult(block_type& res)\n+ 1379 {\n+ 1380 // assign the result of the local solve to the global vector\n+ 1381 for(size_type j=0; j class S, typename T, typename A>\n+ 1390 OverlappingAssignerHelper>,true>\n+1391 ::OverlappingAssignerHelper(std::size_t maxlength,\n+ 1392 const BCRSMatrix& mat_,\n+ 1393 const range_type& b_,\n+ 1394 range_type& x_)\n+ 1395 : mat(&mat_),\n+ 1396 b(&b_),\n+ 1397 x(&x_), i(0), maxlength_(maxlength)\n+ 1398 {\n+ 1399 rhs_ = new field_type[maxlength];\n+ 1400 lhs_ = new field_type[maxlength];\n+ 1401\n+ 1402 }\n+ 1403\n+ 1404 template class S, typename T, typename A>\n+1405 void OverlappingAssignerHelper >,true>::deallocate()\n+ 1406 {\n+ 1407 delete[] rhs_;\n+ 1408 delete[] lhs_;\n+ 1409 }\n+ 1410\n+ 1411 template class S, typename T, typename A>\n+1412 void OverlappingAssignerHelper>,true>::operator()(const\n+size_type& domainIndex)\n+ 1413 {\n+ 1414 //assign right hand side of current domainindex block\n+ 1415 // rhs is an array of doubles!\n+ 1416 // rhs[starti] = b[domainindex]\n+ 1417 for(size_type j=0; j class S, typename T, typename A>\n+1441 void OverlappingAssignerHelper>,true>::relaxResult\n+(field_type relax)\n+ 1442 {\n+ 1443 for(size_type j=i+n; i class S, typename T, typename A>\n+1451 void OverlappingAssignerHelper>,true>::assignResult\n+(block_type& res)\n+ 1452 {\n+ 1453 // assign the result of the local solve to the global vector\n+ 1454 for(size_type j=0; j class S, typename T, typename A>\n+1461 void OverlappingAssignerHelper>,true>::\n+resetIndexForNextDomain()\n+ 1462 {\n+ 1463 i=0;\n+ 1464 }\n+ 1465\n+ 1466 template class S, typename T, typename A>\n+ 1467 typename OverlappingAssignerHelper>,true>::field_type*\n+1468 OverlappingAssignerHelper>,true>::lhs()\n+ 1469 {\n+ 1470 return lhs_;\n+ 1471 }\n+ 1472\n+ 1473 template class S, typename T, typename A>\n+ 1474 typename OverlappingAssignerHelper>,true>::field_type*\n+1475 OverlappingAssignerHelper>,true>::rhs()\n+ 1476 {\n+ 1477 return rhs_;\n+ 1478 }\n+ 1479\n+ 1480#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n+ 1481\n+ 1482 template\n+1483 OverlappingAssignerILUBase::OverlappingAssignerILUBase(std::size_t\n+maxlength,\n+ 1484 const M& mat_,\n+ 1485 const Y& b_,\n+ 1486 X& x_)\n+ 1487 : mat(&mat_),\n+ 1488 b(&b_),\n+ 1489 x(&x_), i(0)\n+ 1490 {\n+ 1491 rhs_= new Y(maxlength);\n+ 1492 lhs_ = new X(maxlength);\n+ 1493 }\n+ 1494\n+ 1495 template\n+1496 void OverlappingAssignerILUBase::deallocate()\n+ 1497 {\n+ 1498 delete rhs_;\n+ 1499 delete lhs_;\n+ 1500 }\n+ 1501\n+ 1502 template\n+1503 void OverlappingAssignerILUBase::operator()(const size_type&\n+domainIndex)\n+ 1504 {\n+ 1505 (*rhs_)[i]=(*b)[domainIndex];\n+ 1506\n+ 1507 // loop over all Matrix row entries and calculate defect.\n+ 1508 typedef typename matrix_type::ConstColIterator col_iterator;\n+ 1509\n+ 1510 // calculate defect for current row index block\n+ 1511 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)\n+[domainIndex].end(); ++col) {\n+ 1512 Impl::asMatrix(*col).mmv((*x)[col.index()], (*rhs_)[i]);\n+ 1513 }\n+ 1514 // Goto next local index\n+ 1515 ++i;\n+ 1516 }\n+ 1517\n+ 1518 template\n+1519 void OverlappingAssignerILUBase::relaxResult(field_type relax)\n+ 1520 {\n+ 1521 (*lhs_)[i]*=relax;\n+ 1522 }\n+ 1523\n+ 1524 template\n+1525 void OverlappingAssignerILUBase::assignResult(block_type& res)\n+ 1526 {\n+ 1527 res+=(*lhs_)[i++];\n+ 1528 }\n+ 1529\n+ 1530 template\n+1531 X& OverlappingAssignerILUBase::lhs()\n+ 1532 {\n+ 1533 return *lhs_;\n+ 1534 }\n+ 1535\n+ 1536 template\n+1537 Y& OverlappingAssignerILUBase::rhs()\n+ 1538 {\n+ 1539 return *rhs_;\n+ 1540 }\n+ 1541\n+ 1542 template\n+1543 void OverlappingAssignerILUBase::resetIndexForNextDomain()\n+ 1544 {\n+ 1545 i=0;\n+ 1546 }\n+ 1547\n+ 1548 template\n+1549 AdditiveAdder >::AdditiveAdder(BlockVector& v_,\n+ 1550 BlockVector& x_,\n+ 1551 OverlappingAssigner& assigner_,\n+ 1552 const field_type& relax_)\n+ 1553 : v(&v_), x(&x_), assigner(&assigner_), relax(relax_)\n+ 1554 {}\n+ 1555\n+ 1556 template\n+1557 void AdditiveAdder >::operator()(const size_type&\n+domainIndex)\n+ 1558 {\n+ 1559 // add the result of the local solve to the current update\n+ 1560 assigner->assignResult((*v)[domainIndex]);\n+ 1561 }\n+ 1562\n+ 1563\n+ 1564 template\n+1565 void AdditiveAdder >::axpy()\n+ 1566 {\n+ 1567 // relax the update and add it to the current guess.\n+ 1568 x->axpy(relax,*v);\n+ 1569 }\n+ 1570\n+ 1571\n+ 1572 template\n+ 1573 MultiplicativeAdder >\n+1574 ::MultiplicativeAdder([[maybe_unused]] BlockVector& v_,\n+ 1575 BlockVector& x_,\n+ 1576 OverlappingAssigner& assigner_, const field_type& relax_)\n+ 1577 : x(&x_), assigner(&assigner_), relax(relax_)\n+ 1578 {}\n+ 1579\n+ 1580\n+ 1581 template\n+1582 void MultiplicativeAdder >::operator()(const size_type&\n+domainIndex)\n+ 1583 {\n+ 1584 // add the result of the local solve to the current guess\n+ 1585 assigner->relaxResult(relax);\n+ 1586 assigner->assignResult((*x)[domainIndex]);\n+ 1587 }\n+ 1588\n+ 1589\n+ 1590 template\n+1591 void MultiplicativeAdder >::axpy()\n+ 1592 {\n+ 1593 // nothing to do, as the corrections already relaxed and added in\n+operator()\n+ 1594 }\n+ 1595\n+ 1596\n+ 1598}\n+ 1599\n+ 1600#endif\n+superlu.hh\n+Classes for using SuperLU with ISTL matrices.\n+solvertype.hh\n+Templates characterizing the type of a solver.\n+umfpack.hh\n+Classes for using UMFPack with ISTL matrices.\n+bccsmatrixinitializer.hh\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+ilusubdomainsolver.hh\n+Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.\n+preconditioners.hh\n+Define general preconditioner interface.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::OverlappingSchwarzInitializer::addRowNnz\n+void addRowNnz(const Iter &row)\n+Definition: overlappingschwarz.hh:895\n+Dune::OverlappingAssignerILUBase::lhs\n+X & lhs()\n+Get the local left hand side.\n+Definition: overlappingschwarz.hh:1531\n+Dune::OverlappingSchwarzInitializer::calcColstart\n+void calcColstart() const\n+Definition: overlappingschwarz.hh:926\n+Dune::OverlappingAssignerILUBase::rhs\n+Y & rhs()\n+Get the local right hand side.\n+Definition: overlappingschwarz.hh:1537\n+Dune::OverlappingAssignerILUBase::resetIndexForNextDomain\n+void resetIndexForNextDomain()\n+Resets the local index to zero.\n+Definition: overlappingschwarz.hh:1543\n+Dune::OverlappingSchwarzInitializer::copyValue\n+void copyValue(const Iter &row, const CIter &col) const\n+Definition: overlappingschwarz.hh:933\n+Dune::OverlappingSchwarzInitializer::createMatrix\n+void createMatrix() const\n+Definition: overlappingschwarz.hh:947\n+Dune::OverlappingSchwarzInitializer::OverlappingSchwarzInitializer\n+OverlappingSchwarzInitializer(InitializerList &il, const IndexSet &indices,\n+const subdomain_vector &domains)\n+Definition: overlappingschwarz.hh:887\n+Dune::SeqOverlappingSchwarz::apply\n+virtual void apply(X &v, const X &d)\n+Apply the precondtioner.\n+Definition: overlappingschwarz.hh:1227\n+Dune::OverlappingAssignerILUBase::OverlappingAssignerILUBase\n+OverlappingAssignerILUBase(std::size_t maxlength, const M &mat, const Y &b, X\n+&x)\n+Constructor.\n+Definition: overlappingschwarz.hh:1483\n+Dune::OverlappingAssignerILUBase::operator()\n+void operator()(const size_type &domain)\n+calculate one entry of the local defect.\n+Definition: overlappingschwarz.hh:1503\n+Dune::SeqOverlappingSchwarz::SeqOverlappingSchwarz\n+SeqOverlappingSchwarz(const matrix_type &mat, const subdomain_vector\n+&subDomains, field_type relaxationFactor=1, bool onTheFly_=true)\n+Construct the overlapping Schwarz method.\n+Definition: overlappingschwarz.hh:1056\n+Dune::OverlappingSchwarzInitializer::allocate\n+void allocate()\n+Definition: overlappingschwarz.hh:905\n+Dune::OverlappingAssignerILUBase::deallocate\n+void deallocate()\n+Deallocates memory of the local vector.\n+Definition: overlappingschwarz.hh:1496\n+Dune::OverlappingSchwarzInitializer::countEntries\n+void countEntries(const Iter &row, const CIter &col) const\n+Definition: overlappingschwarz.hh:914\n+Dune::SeqOverlappingSchwarzAssemblerILUBase::assembleLocalProblems\n+static std::size_t assembleLocalProblems(const RowToDomain &rowToDomain, const\n+matrix_type &mat, Solvers &solvers, const SubDomains &domains, bool onTheFly)\n+Definition: overlappingschwarz.hh:1198\n+Dune::OverlappingAssignerILUBase::relaxResult\n+void relaxResult(field_type relax)\n+relax the result.\n+Definition: overlappingschwarz.hh:1519\n+Dune::OverlappingAssignerILUBase::assignResult\n+void assignResult(block_type &res)\n+Assigns the block to the current local index. At the same time the local defect\n+is calculated for the...\n+Definition: overlappingschwarz.hh:1525\n+Dune::SeqOverlappingSchwarz::SeqOverlappingSchwarz\n+SeqOverlappingSchwarz(const matrix_type &mat, const rowtodomain_vector\n+&rowToDomain, field_type relaxationFactor=1, bool onTheFly_=true)\n+Definition: overlappingschwarz.hh:1009\n Dune\n Definition: allocator.hh:11\n-Dune::operator<<\n-std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n-Send BlockVector to an output stream.\n-Definition: bvector.hh:590\n+Dune::OverlappingSchwarzInitializer\n+Initializer for SuperLU Matrices representing the subdomains.\n+Definition: overlappingschwarz.hh:47\n+Dune::OverlappingSchwarzInitializer::CIter\n+Matrix::row_type::const_iterator CIter\n+Definition: overlappingschwarz.hh:56\n+Dune::OverlappingSchwarzInitializer::IndexSet\n+S IndexSet\n+Definition: overlappingschwarz.hh:58\n+Dune::OverlappingSchwarzInitializer::Iter\n+Matrix::const_iterator Iter\n+Definition: overlappingschwarz.hh:55\n+Dune::OverlappingSchwarzInitializer::size_type\n+IndexSet::size_type size_type\n+Definition: overlappingschwarz.hh:59\n+Dune::OverlappingSchwarzInitializer::InitializerList\n+I InitializerList\n+Definition: overlappingschwarz.hh:52\n+Dune::OverlappingSchwarzInitializer::Matrix\n+AtomInitializer::Matrix Matrix\n+Definition: overlappingschwarz.hh:54\n+Dune::OverlappingSchwarzInitializer::AtomInitializer\n+InitializerList::value_type AtomInitializer\n+Definition: overlappingschwarz.hh:53\n+Dune::OverlappingSchwarzInitializer::subdomain_vector\n+D subdomain_vector\n+The vector type containing the subdomain to row index mapping.\n+Definition: overlappingschwarz.hh:50\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::ConstColIterator\n+row_type::ConstIterator ConstColIterator\n+Const iterator to the entries of a row.\n+Definition: bcrsmatrix.hh:741\n Dune::BlockVector\n A vector of blocks with memory management.\n Definition: bvector.hh:395\n-Dune::BlockVector::BlockVector\n-BlockVector()\n-makes empty vector\n-Definition: bvector.hh:425\n-Dune::BlockVector::reserve\n-void reserve(size_type capacity)\n-Reserve space.\n-Definition: bvector.hh:475\n-Dune::BlockVector::BlockVector\n-BlockVector(BlockVector &&a) noexcept(noexcept(std::declval< BlockVector >\n-().swap(a)))\n-move constructor\n-Definition: bvector.hh:519\n-Dune::BlockVector::BlockVector\n-BlockVector(size_type _n)\n-make vector with _n components\n-Definition: bvector.hh:431\n-Dune::BlockVector::resize\n-void resize(size_type size)\n-Resize the vector.\n-Definition: bvector.hh:503\n-Dune::BlockVector::Iterator\n-Imp::block_vector_unmanaged< B, A >::Iterator Iterator\n-make iterators available as types\n-Definition: bvector.hh:417\n-Dune::BlockVector::blocklevel\n-static constexpr unsigned int blocklevel\n-increment block level counter\n-Definition: bvector.hh:414\n-Dune::BlockVector::BlockVector\n-BlockVector(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >\n-().storage_=a.storage_))\n-copy constructor\n-Definition: bvector.hh:511\n-Dune::BlockVector::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: bvector.hh:407\n-Dune::BlockVector::operator=\n-BlockVector & operator=(const BlockVector &a) noexcept(noexcept(std::declval<\n-BlockVector >().storage_=a.storage_))\n-assignment\n-Definition: bvector.hh:526\n-Dune::BlockVector::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bvector.hh:401\n-Dune::BlockVector::size_type\n+Dune::ILU0SubdomainSolver\n+Exact subdomain solver using ILU(p) with appropriate p.\n+Definition: ilusubdomainsolver.hh:78\n+Dune::ILUNSubdomainSolver\n+Definition: ilusubdomainsolver.hh:111\n+Dune::SeqOverlappingSchwarz\n+Sequential overlapping Schwarz preconditioner.\n+Definition: overlappingschwarz.hh:755\n+Dune::SeqOverlappingSchwarz::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: overlappingschwarz.hh:783\n+Dune::SeqOverlappingSchwarz::apply\n+void apply(X &v, const X &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Dune::SeqOverlappingSchwarz::subdomain_list\n+SLList< size_type, typename std::allocator_traits< TA >::template rebind_alloc<\n+size_type > > subdomain_list\n+The type for the row to subdomain mapping.\n+Definition: overlappingschwarz.hh:800\n+Dune::SeqOverlappingSchwarz::slu_vector\n+std::vector< slu, typename std::allocator_traits< TA >::template rebind_alloc<\n+slu > > slu_vector\n+The vector type containing subdomain solvers.\n+Definition: overlappingschwarz.hh:809\n+Dune::SeqOverlappingSchwarz::matrix_type\n+M matrix_type\n+The type of the matrix to precondition.\n+Definition: overlappingschwarz.hh:760\n+Dune::SeqOverlappingSchwarz::Mode\n+TM Mode\n+The mode (additive or multiplicative) of the Schwarz method.\n+Definition: overlappingschwarz.hh:778\n+Dune::SeqOverlappingSchwarz::range_type\n+X range_type\n+The range type of the preconditioner.\n+Definition: overlappingschwarz.hh:770\n+Dune::SeqOverlappingSchwarz::subdomain_type\n+std::set< size_type, std::less< size_type >, typename std::allocator_traits< TA\n+>::template rebind_alloc< size_type > > subdomain_type\n+The type for the subdomain to row index mapping.\n+Definition: overlappingschwarz.hh:794\n+Dune::SeqOverlappingSchwarz::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: overlappingschwarz.hh:765\n+Dune::SeqOverlappingSchwarz::slu\n+TD slu\n+The type for the subdomain solver in use.\n+Definition: overlappingschwarz.hh:806\n+Dune::SeqOverlappingSchwarz::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: overlappingschwarz.hh:868\n+Dune::SeqOverlappingSchwarz::pre\n+virtual void pre(X &x, X &b)\n+Prepare the preconditioner.\n+Definition: overlappingschwarz.hh:846\n+Dune::SeqOverlappingSchwarz::post\n+virtual void post(X &x)\n+Postprocess the preconditioner.\n+Definition: overlappingschwarz.hh:861\n+Dune::SeqOverlappingSchwarz::allocator\n+TA allocator\n+The allocator to use.\n+Definition: overlappingschwarz.hh:789\n+Dune::SeqOverlappingSchwarz::subdomain_vector\n+std::vector< subdomain_type, typename std::allocator_traits< TA >::template\n+rebind_alloc< subdomain_type > > subdomain_vector\n+The vector type containing the subdomain to row index mapping.\n+Definition: overlappingschwarz.hh:797\n+Dune::SeqOverlappingSchwarz::rowtodomain_vector\n+std::vector< subdomain_list, typename std::allocator_traits< TA >::template\n+rebind_alloc< subdomain_list > > rowtodomain_vector\n+The vector type containing the row index to subdomain mapping.\n+Definition: overlappingschwarz.hh:803\n+Dune::SeqOverlappingSchwarz::size_type\n+matrix_type::size_type size_type\n+The return type of the size method.\n+Definition: overlappingschwarz.hh:786\n+Dune::SeqOverlappingSchwarzAssemblerHelper\n+Definition: overlappingschwarz.hh:694\n+Dune::AdditiveSchwarzMode\n+Tag that the tells the Schwarz method to be additive.\n+Definition: overlappingschwarz.hh:120\n+Dune::MultiplicativeSchwarzMode\n+Tag that tells the Schwarz method to be multiplicative.\n+Definition: overlappingschwarz.hh:126\n+Dune::SymmetricMultiplicativeSchwarzMode\n+Tag that tells the Schwarz method to be multiplicative and symmetric.\n+Definition: overlappingschwarz.hh:133\n+Dune::DynamicMatrixSubdomainSolver\n+Exact subdomain solver using Dune::DynamicMatrix::solve.\n+Definition: overlappingschwarz.hh:140\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::matrix_type\n+std::remove_const< M >::type matrix_type\n+The matrix type the preconditioner is for.\n+Definition: overlappingschwarz.hh:149\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::field_type\n+X::field_type field_type\n+Definition: overlappingschwarz.hh:150\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: overlappingschwarz.hh:153\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: overlappingschwarz.hh:155\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::setSubMatrix\n+void setSubMatrix(const M &BCRS, S &rowset)\n+Set the data of the local problem.\n+Definition: overlappingschwarz.hh:184\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::apply\n+void apply(DynamicVector< field_type > &v, DynamicVector< field_type > &d)\n+Apply the subdomain solver.\n+Definition: overlappingschwarz.hh:162\n+Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::rilu_type\n+std::remove_const< M >::type rilu_type\n+Definition: overlappingschwarz.hh:151\n+Dune::OverlappingAssignerHelper\n+Definition: overlappingschwarz.hh:215\n+Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al_>,_X,_Y_>,_false_>::size_type\n+matrix_type::size_type size_type\n+Definition: overlappingschwarz.hh:229\n+Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al_>,_X,_Y_>,_false_>::field_type\n+X::field_type field_type\n+Definition: overlappingschwarz.hh:226\n+Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al_>,_X,_Y_>,_false_>::matrix_type\n+BCRSMatrix< K, Al > matrix_type\n+Definition: overlappingschwarz.hh:225\n+Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al_>,_X,_Y_>,_false_>::range_type\n+Y range_type\n+Definition: overlappingschwarz.hh:227\n+Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n+Al_>,_X,_Y_>,_false_>::block_type\n+range_type::block_type block_type\n+Definition: overlappingschwarz.hh:228\n+Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::range_type\n+S< BCRSMatrix< T, A > >::range_type range_type\n+Definition: overlappingschwarz.hh:315\n+Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::block_type\n+range_type::block_type block_type\n+Definition: overlappingschwarz.hh:317\n+Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::field_type\n+range_type::field_type field_type\n+Definition: overlappingschwarz.hh:316\n+Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::size_type\n+matrix_type::size_type size_type\n+Definition: overlappingschwarz.hh:319\n+Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::matrix_type\n+BCRSMatrix< T, A > matrix_type\n+Definition: overlappingschwarz.hh:314\n+Dune::OverlappingAssignerILUBase\n+Definition: overlappingschwarz.hh:400\n+Dune::OverlappingAssignerILUBase::size_type\n+matrix_type::size_type size_type\n+Definition: overlappingschwarz.hh:408\n+Dune::OverlappingAssignerILUBase::field_type\n+Y::field_type field_type\n+Definition: overlappingschwarz.hh:404\n+Dune::OverlappingAssignerILUBase::block_type\n+Y::block_type block_type\n+Definition: overlappingschwarz.hh:406\n+Dune::OverlappingAssignerILUBase::matrix_type\n+M matrix_type\n+Definition: overlappingschwarz.hh:402\n+Dune::OverlappingAssignerHelper<_ILU0SubdomainSolver<_M,_X,_Y_>,_false_>::\n+OverlappingAssignerHelper\n+OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X\n+&x)\n+Constructor.\n+Definition: overlappingschwarz.hh:493\n+Dune::OverlappingAssignerHelper<_ILUNSubdomainSolver<_M,_X,_Y_>,_false_>::\n+OverlappingAssignerHelper\n+OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X\n+&x)\n+Constructor.\n+Definition: overlappingschwarz.hh:512\n+Dune::AdditiveAdder\n+Definition: overlappingschwarz.hh:520\n+Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>::field_type\n+std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type\n+field_type\n+Definition: overlappingschwarz.hh:526\n+Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>::size_type\n+A::size_type size_type\n+Definition: overlappingschwarz.hh:525\n+Dune::MultiplicativeAdder\n+Definition: overlappingschwarz.hh:542\n+Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>::size_type\n A::size_type size_type\n-The type for the index access.\n-Definition: bvector.hh:410\n-Dune::BlockVector::BlockVector\n-BlockVector(std::initializer_list< B > const &l)\n-Construct from a std::initializer_list.\n-Definition: bvector.hh:437\n-Dune::BlockVector::capacity\n-size_type capacity() const\n-Get the capacity of the vector.\n-Definition: bvector.hh:488\n-Dune::BlockVector::BlockVector\n-BlockVector(size_type _n, S _capacity)\n-Make vector with _n components but preallocating capacity components.\n-Definition: bvector.hh:455\n-Dune::BlockVector::block_type\n-B block_type\n-export the type representing the components\n-Definition: bvector.hh:404\n-Dune::BlockVector::swap\n-void swap(BlockVector &other) noexcept(noexcept(std::declval< BlockVector & >\n-().storage_.swap(other.storage_)))\n-swap operation\n-Definition: bvector.hh:544\n-Dune::BlockVector::ConstIterator\n-Imp::block_vector_unmanaged< B, A >::ConstIterator ConstIterator\n-make iterators available as types\n-Definition: bvector.hh:420\n-Dune::FieldTraits<_BlockVector<_B,_A_>_>::real_type\n-FieldTraits< B >::real_type real_type\n-Definition: bvector.hh:582\n-Dune::FieldTraits<_BlockVector<_B,_A_>_>::field_type\n-FieldTraits< B >::field_type field_type\n-Definition: bvector.hh:581\n+Definition: overlappingschwarz.hh:547\n+Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>::field_type\n+std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type\n+field_type\n+Definition: overlappingschwarz.hh:548\n+Dune::AdderSelector\n+template meta program for choosing how to add the correction.\n+Definition: overlappingschwarz.hh:572\n+Dune::AdderSelector<_AdditiveSchwarzMode,_X,_S_>::Adder\n+AdditiveAdder< S, X > Adder\n+Definition: overlappingschwarz.hh:577\n+Dune::AdderSelector<_MultiplicativeSchwarzMode,_X,_S_>::Adder\n+MultiplicativeAdder< S, X > Adder\n+Definition: overlappingschwarz.hh:583\n+Dune::AdderSelector<_SymmetricMultiplicativeSchwarzMode,_X,_S_>::Adder\n+MultiplicativeAdder< S, X > Adder\n+Definition: overlappingschwarz.hh:589\n+Dune::IteratorDirectionSelector\n+Helper template meta program for application of overlapping Schwarz.\n+Definition: overlappingschwarz.hh:605\n+Dune::IteratorDirectionSelector::begin\n+static solver_iterator begin(solver_vector &sv)\n+Definition: overlappingschwarz.hh:611\n+Dune::IteratorDirectionSelector::solver_iterator\n+solver_vector::iterator solver_iterator\n+Definition: overlappingschwarz.hh:607\n+Dune::IteratorDirectionSelector::end\n+static domain_iterator end(const subdomain_vector &sv)\n+Definition: overlappingschwarz.hh:625\n+Dune::IteratorDirectionSelector::domain_iterator\n+subdomain_vector::const_iterator domain_iterator\n+Definition: overlappingschwarz.hh:609\n+Dune::IteratorDirectionSelector::solver_vector\n+T1 solver_vector\n+Definition: overlappingschwarz.hh:606\n+Dune::IteratorDirectionSelector::begin\n+static domain_iterator begin(const subdomain_vector &sv)\n+Definition: overlappingschwarz.hh:620\n+Dune::IteratorDirectionSelector::subdomain_vector\n+T2 subdomain_vector\n+Definition: overlappingschwarz.hh:608\n+Dune::IteratorDirectionSelector::end\n+static solver_iterator end(solver_vector &sv)\n+Definition: overlappingschwarz.hh:616\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::subdomain_vector\n+T2 subdomain_vector\n+Definition: overlappingschwarz.hh:636\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::end\n+static solver_iterator end(solver_vector &sv)\n+Definition: overlappingschwarz.hh:644\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::solver_iterator\n+solver_vector::reverse_iterator solver_iterator\n+Definition: overlappingschwarz.hh:635\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::domain_iterator\n+subdomain_vector::const_reverse_iterator domain_iterator\n+Definition: overlappingschwarz.hh:637\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::begin\n+static solver_iterator begin(solver_vector &sv)\n+Definition: overlappingschwarz.hh:639\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::solver_vector\n+T1 solver_vector\n+Definition: overlappingschwarz.hh:634\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::begin\n+static domain_iterator begin(const subdomain_vector &sv)\n+Definition: overlappingschwarz.hh:648\n+Dune::IteratorDirectionSelector<_T1,_T2,_false_>::end\n+static domain_iterator end(const subdomain_vector &sv)\n+Definition: overlappingschwarz.hh:653\n+Dune::SeqOverlappingSchwarzApplier\n+Helper template meta program for application of overlapping Schwarz.\n+Definition: overlappingschwarz.hh:669\n+Dune::SeqOverlappingSchwarzApplier::range_type\n+smoother::range_type range_type\n+Definition: overlappingschwarz.hh:671\n+Dune::SeqOverlappingSchwarzApplier::smoother\n+T smoother\n+Definition: overlappingschwarz.hh:670\n+Dune::SeqOverlappingSchwarzApplier::apply\n+static void apply(smoother &sm, range_type &v, const range_type &b)\n+Definition: overlappingschwarz.hh:673\n+Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n+SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::apply\n+static void apply(smoother &sm, range_type &v, const range_type &b)\n+Definition: overlappingschwarz.hh:685\n+Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n+SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::smoother\n+SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA >\n+smoother\n+Definition: overlappingschwarz.hh:682\n+Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n+SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::range_type\n+smoother::range_type range_type\n+Definition: overlappingschwarz.hh:683\n+Dune::SeqOverlappingSchwarzAssemblerHelper<_DynamicMatrixSubdomainSolver<\n+BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>::matrix_type\n+BCRSMatrix< K, Al > matrix_type\n+Definition: overlappingschwarz.hh:702\n+Dune::SeqOverlappingSchwarzAssemblerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::\n+matrix_type\n+BCRSMatrix< T, A > matrix_type\n+Definition: overlappingschwarz.hh:713\n+Dune::SeqOverlappingSchwarzAssemblerILUBase\n+Definition: overlappingschwarz.hh:723\n+Dune::SeqOverlappingSchwarzAssemblerILUBase::matrix_type\n+M matrix_type\n+Definition: overlappingschwarz.hh:724\n+Dune::SeqOverlappingSchwarzDomainSize\n+Definition: overlappingschwarz.hh:1103\n+Dune::SeqOverlappingSchwarzDomainSize<_BCRSMatrix<_T,_A_>_>::size\n+static int size(const Domain &d)\n+Definition: overlappingschwarz.hh:1111\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00092.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00092.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: repartition.hh File Reference\n+dune-istl: btdmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -64,101 +64,45 @@\n \n
    \n
    \n
    \n \n-
    repartition.hh File Reference
    \n+Namespaces
    \n+
    btdmatrix.hh File Reference
    \n
    \n
    \n \n-

    Functionality for redistributing a parallel index set using graph partitioning. \n+

    Implementation of the BTDMatrix class. \n More...

    \n-
    #include <cassert>
    \n-#include <map>
    \n-#include <utility>
    \n-#include <cmath>
    \n-#include <dune/common/timer.hh>
    \n-#include <dune/common/enumset.hh>
    \n-#include <dune/common/stdstreams.hh>
    \n-#include <dune/common/parallel/mpitraits.hh>
    \n-#include <dune/common/parallel/communicator.hh>
    \n-#include <dune/common/parallel/indexset.hh>
    \n-#include <dune/common/parallel/indicessyncer.hh>
    \n-#include <dune/common/parallel/remoteindices.hh>
    \n-#include <dune/common/rangeutilities.hh>
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n-#include <dune/istl/paamg/graph.hh>
    \n+
    #include <dune/common/fmatrix.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::RedistributeInterface
    class  Dune::BTDMatrix< B, A >
     A block-tridiagonal matrix. More...
     
    struct  Dune::FieldTraits< BTDMatrix< B, A > >
     
    \n \n \n \n-\n-\n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Metis
     
    \n-\n-\n-\n-\n-\n-

    \n-Typedefs

    using Dune::Metis::real_t = float
     
    using Dune::Metis::idx_t = std::size_t
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<class G , class T1 , class T2 >
    void Dune::fillIndexSetHoles (const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
     Fills the holes in an index set. More...
     
    template<class G , class T1 , class T2 >
    bool Dune::buildCommunication (const G &graph, std::vector< int > &realparts, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     
    template<class S , class T >
    void Dune::print_carray (S &os, T *array, std::size_t l)
     
    template<class S , class T >
    bool Dune::isValidGraph (std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T *adjncy, bool checkSymmetry)
     
    template<class M , class T1 , class T2 >
    bool Dune::commGraphRepartition (const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     
    template<class G , class T1 , class T2 >
    bool Dune::graphRepartition (const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     execute a graph repartition for a giving graph and indexset. More...
     
    \n

    Detailed Description

    \n-

    Functionality for redistributing a parallel index set using graph partitioning.

    \n-

    Refactored version of an intern.

    Author
    Markus Blatt
    \n-

    Variable Documentation

    \n-\n-

    ◆ globalOwnerVertices

    \n-\n-
    \n-
    \n- \n- \n- \n- \n-
    int globalOwnerVertices
    \n-
    \n-\n-
    \n-
    \n-
    \n+

    Implementation of the BTDMatrix class.

    \n+
    Author
    Oliver Sander
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,83 +4,32 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Typedefs | Functions\n-repartition.hh File Reference\n-Functionality for redistributing a parallel index set using graph partitioning.\n-More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+btdmatrix.hh File Reference\n+Implementation of the BTDMatrix class. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::RedistributeInterface\n+ class \u00a0Dune::BTDMatrix<_B,_A_>\n+\u00a0 A block-tridiagonal matrix. More...\n+\u00a0\n+struct \u00a0Dune::FieldTraits<_BTDMatrix<_B,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Metis\n-\u00a0\n- Typedefs\n-using\u00a0Dune::Metis::real_t = float\n-\u00a0\n-using\u00a0Dune::Metis::idx_t = std::size_t\n-\u00a0\n- Functions\n-template\n-void\u00a0Dune::fillIndexSetHoles (const G &graph, Dune::\n- OwnerOverlapCopyCommunication< T1, T2 > &oocomm)\n-\u00a0 Fills the holes in an index set. More...\n-\u00a0\n-template\n-bool\u00a0Dune::buildCommunication (const G &graph, std::vector< int > &realparts,\n- Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr<\n- Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm,\n- RedistributeInterface &redistInf, bool verbose=false)\n-\u00a0\n-template\n-void\u00a0Dune::print_carray (S &os, T *array, std::size_t l)\n-\u00a0\n-template\n-bool\u00a0Dune::isValidGraph (std::size_t noVtx, std::size_t gnoVtx, S noEdges, T\n- *xadj, T *adjncy, bool checkSymmetry)\n-\u00a0\n-template\n-bool\u00a0Dune::commGraphRepartition (const M &mat, Dune::\n- OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts,\n- std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > >\n- &outcomm, RedistributeInterface &redistInf, bool verbose=false)\n-\u00a0\n-template\n-bool\u00a0Dune::graphRepartition (const G &graph, Dune::\n- OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts,\n- std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > >\n- &outcomm, RedistributeInterface &redistInf, bool verbose=false)\n-\u00a0 execute a graph repartition for a giving graph and indexset. More...\n-\u00a0\n ***** Detailed Description *****\n-Functionality for redistributing a parallel index set using graph partitioning.\n-Refactored version of an intern.\n+Implementation of the BTDMatrix class.\n Author\n- Markus Blatt\n-***** Variable Documentation *****\n-***** \u25c6\u00a0globalOwnerVertices *****\n-int globalOwnerVertices\n+ Oliver Sander\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00092_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00092_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: repartition.hh Source File\n+dune-istl: btdmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -62,1823 +62,226 @@\n \n
    \n \n
    \n
    \n
    \n-
    repartition.hh
    \n+
    btdmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_REPARTITION_HH
    \n-
    6#define DUNE_ISTL_REPARTITION_HH
    \n+
    5#ifndef DUNE_ISTL_BTDMATRIX_HH
    \n+
    6#define DUNE_ISTL_BTDMATRIX_HH
    \n
    7
    \n-
    8#include <cassert>
    \n-
    9#include <map>
    \n-
    10#include <utility>
    \n-
    11#include <cmath>
    \n-
    12
    \n-
    13#if HAVE_PARMETIS
    \n-
    14// Explicitly use C linkage as scotch does not extern "C" in its headers.
    \n-
    15// Works because ParMETIS/METIS checks whether compiler is C++ and otherwise
    \n-
    16// does not use extern "C". Therfore no nested extern "C" will be created
    \n-
    17extern "C"
    \n-
    18{
    \n-
    19#include <parmetis.h>
    \n-
    20}
    \n-
    21#endif
    \n-
    22
    \n-
    23#include <dune/common/timer.hh>
    \n-
    24#include <dune/common/enumset.hh>
    \n-
    25#include <dune/common/stdstreams.hh>
    \n-
    26#include <dune/common/parallel/mpitraits.hh>
    \n-
    27#include <dune/common/parallel/communicator.hh>
    \n-
    28#include <dune/common/parallel/indexset.hh>
    \n-
    29#include <dune/common/parallel/indicessyncer.hh>
    \n-
    30#include <dune/common/parallel/remoteindices.hh>
    \n-
    31#include <dune/common/rangeutilities.hh>
    \n-
    32
    \n-\n-\n+
    8#include <dune/common/fmatrix.hh>
    \n+
    9#include <dune/common/scalarvectorview.hh>
    \n+
    10#include <dune/common/scalarmatrixview.hh>
    \n+\n+\n+
    13
    \n+
    19namespace Dune {
    \n+
    29 template <class B, class A=std::allocator<B> >
    \n+
    30 class BTDMatrix : public BCRSMatrix<B,A>
    \n+
    31 {
    \n+
    32 public:
    \n+
    33
    \n+
    34 //===== type definitions and constants
    \n
    35
    \n-
    44namespace Dune
    \n-
    45{
    \n-
    46 namespace Metis
    \n-
    47 {
    \n-
    48 // Explicitly specify a real_t and idx_t for older (Par)METIS versions that do not
    \n-
    49 // provide these typedefs
    \n-
    50#if HAVE_PARMETIS && defined(REALTYPEWIDTH)
    \n-
    51 using real_t = ::real_t;
    \n-
    52#else
    \n-
    53 using real_t = float;
    \n-
    54#endif
    \n-
    55
    \n-
    56#if HAVE_PARMETIS && defined(IDXTYPEWIDTH)
    \n-
    57 using idx_t = ::idx_t;
    \n-
    58#elif HAVE_PARMETIS && defined(HAVE_SCOTCH_NUM_TYPE)
    \n-
    59 using idx_t = SCOTCH_Num;
    \n-
    60#elif HAVE_PARMETIS
    \n-
    61 using idx_t = int;
    \n-
    62#else
    \n-
    63 using idx_t = std::size_t;
    \n-
    64#endif
    \n-
    65 }
    \n-
    66
    \n+
    37 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    38
    \n+
    40 typedef B block_type;
    \n+
    41
    \n+
    43 typedef A allocator_type;
    \n+
    44
    \n+
    46 //typedef BCRSMatrix<B,A>::row_type row_type;
    \n+
    47
    \n+
    49 typedef typename A::size_type size_type;
    \n+
    50
    \n+
    52 [[deprecated("Use free blockLevel function. Will be removed after 2.8.")]]
    \n+
    53 static constexpr auto blocklevel = blockLevel<B>()+1;
    \n+
    54
    \n+
    56 BTDMatrix() : BCRSMatrix<B,A>() {}
    \n+
    57
    \n+
    58 explicit BTDMatrix(size_type size)
    \n+
    59 : BCRSMatrix<B,A>(size, size, BCRSMatrix<B,A>::random)
    \n+
    60 {
    \n+
    61 // Set number of entries for each row
    \n+
    62 // All rows get three entries, except for the first and the last one
    \n+
    63 for (size_t i=0; i<size; i++)
    \n+
    64 this->BCRSMatrix<B,A>::setrowsize(i, 3 - (i==0) - (i==(size-1)));
    \n+
    65
    \n+\n
    67
    \n-
    68#if HAVE_MPI
    \n-
    82 template<class G, class T1, class T2>
    \n-\n-
    84 {
    \n-\n-
    86 typedef typename IndexSet::LocalIndex::Attribute Attribute;
    \n+
    68 // The actual entries for each row
    \n+
    69 for (size_t i=0; i<size; i++) {
    \n+
    70 if (i>0)
    \n+
    71 this->BCRSMatrix<B,A>::addindex(i, i-1);
    \n+
    72 this->BCRSMatrix<B,A>::addindex(i, i );
    \n+
    73 if (i<size-1)
    \n+
    74 this->BCRSMatrix<B,A>::addindex(i, i+1);
    \n+
    75 }
    \n+
    76
    \n+\n+
    78 }
    \n+
    79
    \n+
    81 void setSize(size_type size)
    \n+
    82 {
    \n+
    83 auto nonZeros = (size==0) ? 0 : size + 2*(size-1);
    \n+
    84 this->BCRSMatrix<B,A>::setSize(size, // rows
    \n+
    85 size, // columns
    \n+
    86 nonZeros);
    \n
    87
    \n-
    88 IndexSet& indexSet = oocomm.indexSet();
    \n-\n-
    90
    \n-
    91 std::size_t sum=0, needed = graph.noVertices()-indexSet.size();
    \n-
    92 std::vector<std::size_t> neededall(oocomm.communicator().size(), 0);
    \n-
    93
    \n-
    94 MPI_Allgather(&needed, 1, MPITraits<std::size_t>::getType() , &(neededall[0]), 1, MPITraits<std::size_t>::getType(), oocomm.communicator());
    \n-
    95 for(int i=0; i<oocomm.communicator().size(); ++i)
    \n-
    96 sum=sum+neededall[i]; // MAke this for generic
    \n-
    97
    \n-
    98 if(sum==0)
    \n-
    99 // Nothing to do
    \n-
    100 return;
    \n-
    101
    \n-
    102 //Compute Maximum Global Index
    \n-
    103 T1 maxgi=0;
    \n-
    104 auto end = indexSet.end();
    \n-
    105 for(auto it = indexSet.begin(); it != end; ++it)
    \n-
    106 maxgi=std::max(maxgi,it->global());
    \n-
    107
    \n-
    108 //Process p creates global indices consecutively
    \n-
    109 //starting atmaxgi+\\sum_{i=1}^p neededall[i]
    \n-
    110 // All created indices are owned by the process
    \n-
    111 maxgi=oocomm.communicator().max(maxgi);
    \n-
    112 ++maxgi; //Sart with the next free index.
    \n-
    113
    \n-
    114 for(int i=0; i<oocomm.communicator().rank(); ++i)
    \n-
    115 maxgi=maxgi+neededall[i]; // TODO: make this more generic
    \n-
    116
    \n-
    117 // Store the global index information for repairing the remote index information
    \n-
    118 std::map<int,SLList<std::pair<T1,Attribute> > > globalIndices;
    \n-
    119 storeGlobalIndicesOfRemoteIndices(globalIndices, oocomm.remoteIndices());
    \n-
    120 indexSet.beginResize();
    \n-
    121
    \n-
    122 for(auto vertex = graph.begin(), vend=graph.end(); vertex != vend; ++vertex) {
    \n-
    123 const typename IndexSet::IndexPair* pair=lookup.pair(*vertex);
    \n-
    124 if(pair==0) {
    \n-
    125 // No index yet, add new one
    \n-
    126 indexSet.add(maxgi, typename IndexSet::LocalIndex(*vertex, OwnerOverlapCopyAttributeSet::owner, false));
    \n-
    127 ++maxgi;
    \n-
    128 }
    \n-
    129 }
    \n-
    130
    \n-
    131 indexSet.endResize();
    \n-
    132
    \n-
    133 repairLocalIndexPointers(globalIndices, oocomm.remoteIndices(), indexSet);
    \n+
    88 // Set number of entries for each row
    \n+
    89 // All rows get three entries, except for the first and the last one
    \n+
    90 for (size_t i=0; i<size; i++)
    \n+
    91 this->BCRSMatrix<B,A>::setrowsize(i, 3 - (i==0) - (i==(size-1)));
    \n+
    92
    \n+\n+
    94
    \n+
    95 // The actual entries for each row
    \n+
    96 for (size_t i=0; i<size; i++) {
    \n+
    97 if (i>0)
    \n+
    98 this->BCRSMatrix<B,A>::addindex(i, i-1);
    \n+
    99 this->BCRSMatrix<B,A>::addindex(i, i );
    \n+
    100 if (i<size-1)
    \n+
    101 this->BCRSMatrix<B,A>::addindex(i, i+1);
    \n+
    102 }
    \n+
    103
    \n+\n+
    105 }
    \n+
    106
    \n+\n+
    109 this->BCRSMatrix<B,A>::operator=(other);
    \n+
    110 return *this;
    \n+
    111 }
    \n+
    112
    \n+\n+\n+
    116 return *this;
    \n+
    117 }
    \n+
    118
    \n+
    124 template <class V>
    \n+
    125 void solve (V& x, const V& rhs) const {
    \n+
    126
    \n+
    127 // special handling for 1x1 matrices. The generic algorithm doesn't work for them
    \n+
    128 if (this->N()==1) {
    \n+
    129 auto&& x0 = Impl::asVector(x[0]);
    \n+
    130 auto&& rhs0 = Impl::asVector(rhs[0]);
    \n+
    131 Impl::asMatrix((*this)[0][0]).solve(x0, rhs0);
    \n+
    132 return;
    \n+
    133 }
    \n
    134
    \n-
    135 oocomm.freeGlobalLookup();
    \n-
    136 oocomm.buildGlobalLookup();
    \n-
    137#ifdef DEBUG_REPART
    \n-
    138 std::cout<<"Holes are filled!"<<std::endl;
    \n-
    139 std::cout<<oocomm.communicator().rank()<<": "<<oocomm.indexSet()<<std::endl;
    \n-
    140#endif
    \n-
    141 }
    \n-
    142
    \n-
    143 namespace
    \n-
    144 {
    \n-
    145
    \n-
    146 class ParmetisDuneIndexMap
    \n-
    147 {
    \n-
    148 public:
    \n-
    149 template<class Graph, class OOComm>
    \n-
    150 ParmetisDuneIndexMap(const Graph& graph, const OOComm& com);
    \n-
    151 int toParmetis(int i) const
    \n-
    152 {
    \n-
    153 return duneToParmetis[i];
    \n-
    154 }
    \n-
    155 int toLocalParmetis(int i) const
    \n-
    156 {
    \n-
    157 return duneToParmetis[i]-base_;
    \n-
    158 }
    \n-
    159 int operator[](int i) const
    \n-
    160 {
    \n-
    161 return duneToParmetis[i];
    \n-
    162 }
    \n-
    163 int toDune(int i) const
    \n-
    164 {
    \n-
    165 return parmetisToDune[i];
    \n-
    166 }
    \n-
    167 std::vector<int>::size_type numOfOwnVtx() const
    \n-
    168 {
    \n-
    169 return parmetisToDune.size();
    \n-
    170 }
    \n-
    171 Metis::idx_t* vtxDist()
    \n-
    172 {
    \n-
    173 return &vtxDist_[0];
    \n-
    174 }
    \n-\n-
    176 private:
    \n-
    177 int base_;
    \n-
    178 std::vector<int> duneToParmetis;
    \n-
    179 std::vector<int> parmetisToDune;
    \n-
    180 // range of vertices for processor i: vtxdist[i] to vtxdist[i+1] (parmetis global)
    \n-
    181 std::vector<Metis::idx_t> vtxDist_;
    \n-
    182 };
    \n-
    183
    \n-
    184 template<class G, class OOComm>
    \n-
    185 ParmetisDuneIndexMap::ParmetisDuneIndexMap(const G& graph, const OOComm& oocomm)
    \n-
    186 : duneToParmetis(graph.noVertices(), -1), vtxDist_(oocomm.communicator().size()+1)
    \n-
    187 {
    \n-
    188 int npes=oocomm.communicator().size(), mype=oocomm.communicator().rank();
    \n+
    135 // Make copies of the rhs and the right matrix band
    \n+
    136 V d = rhs;
    \n+
    137 std::vector<block_type> c(this->N()-1);
    \n+
    138 for (size_t i=0; i<this->N()-1; i++)
    \n+
    139 c[i] = (*this)[i][i+1];
    \n+
    140
    \n+
    141 /* Modify the coefficients. */
    \n+
    142 block_type a_00_inv = (*this)[0][0];
    \n+
    143 Impl::asMatrix(a_00_inv).invert();
    \n+
    144
    \n+
    145 //c[0] /= (*this)[0][0]; /* Division by zero risk. */
    \n+
    146 block_type tmp = a_00_inv;
    \n+
    147 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[0]));
    \n+
    148 c[0] = tmp;
    \n+
    149
    \n+
    150 // d = a^{-1} d /* Division by zero would imply a singular matrix. */
    \n+
    151 auto d_0_tmp = d[0];
    \n+
    152 auto&& d_0 = Impl::asVector(d[0]);
    \n+
    153 Impl::asMatrix(a_00_inv).mv(Impl::asVector(d_0_tmp),d_0);
    \n+
    154
    \n+
    155 for (unsigned int i = 1; i < this->N(); i++) {
    \n+
    156
    \n+
    157 // id = ( a_ii - c_{i-1} a_{i, i-1} ) ^{-1}
    \n+
    158 block_type tmp;
    \n+
    159 tmp = (*this)[i][i-1];
    \n+
    160 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[i-1]));
    \n+
    161
    \n+
    162 block_type id = (*this)[i][i];
    \n+
    163 id -= tmp;
    \n+
    164 Impl::asMatrix(id).invert(); /* Division by zero risk. */
    \n+
    165
    \n+
    166 if (i<c.size()) {
    \n+
    167 Impl::asMatrix(c[i]).leftmultiply(Impl::asMatrix(id)); /* Last value calculated is redundant. */
    \n+
    168 }
    \n+
    169
    \n+
    170 // d[i] = (d[i] - d[i-1] * (*this)[i][i-1]) * id;
    \n+
    171 auto&& d_i = Impl::asVector(d[i]);
    \n+
    172 Impl::asMatrix((*this)[i][i-1]).mmv(Impl::asVector(d[i-1]), d_i);
    \n+
    173 auto tmpVec = d[i];
    \n+
    174 Impl::asMatrix(id).mv(Impl::asVector(tmpVec), d_i);
    \n+
    175 }
    \n+
    176
    \n+
    177 /* Now back substitute. */
    \n+
    178 x[this->N() - 1] = d[this->N() - 1];
    \n+
    179 for (int i = this->N() - 2; i >= 0; i--) {
    \n+
    180 //x[i] = d[i] - c[i] * x[i + 1];
    \n+
    181 x[i] = d[i];
    \n+
    182 auto&& x_i = Impl::asVector(x[i]);
    \n+
    183 Impl::asMatrix(c[i]).mmv(Impl::asVector(x[i+1]), x_i);
    \n+
    184 }
    \n+
    185
    \n+
    186 }
    \n+
    187
    \n+
    188 private:
    \n
    189
    \n-
    190 typedef typename OOComm::OwnerSet OwnerSet;
    \n-
    191
    \n-
    192 int numOfOwnVtx=0;
    \n-
    193 auto end = oocomm.indexSet().end();
    \n-
    194 for(auto index = oocomm.indexSet().begin(); index != end; ++index) {
    \n-
    195 if (OwnerSet::contains(index->local().attribute())) {
    \n-
    196 numOfOwnVtx++;
    \n-
    197 }
    \n-
    198 }
    \n-
    199 parmetisToDune.resize(numOfOwnVtx);
    \n-
    200 std::vector<int> globalNumOfVtx(npes);
    \n-
    201 // make this number available to all processes
    \n-
    202 MPI_Allgather(&numOfOwnVtx, 1, MPI_INT, &(globalNumOfVtx[0]), 1, MPI_INT, oocomm.communicator());
    \n+
    190 // ////////////////////////////////////////////////////////////////////////////
    \n+
    191 // The following methods from the base class should now actually be called
    \n+
    192 // ////////////////////////////////////////////////////////////////////////////
    \n+
    193
    \n+
    194 // createbegin and createend should be in there, too, but I can't get it to compile
    \n+
    195 // BCRSMatrix<B,A>::CreateIterator createbegin () {}
    \n+
    196 // BCRSMatrix<B,A>::CreateIterator createend () {}
    \n+
    197 void setrowsize (size_type i, size_type s) {}
    \n+
    198 void incrementrowsize (size_type i) {}
    \n+
    199 void endrowsizes () {}
    \n+
    200 void addindex (size_type row, size_type col) {}
    \n+
    201 void endindices () {}
    \n+
    202 };
    \n
    203
    \n-
    204 int base=0;
    \n-
    205 vtxDist_[0] = 0;
    \n-
    206 for(int i=0; i<npes; i++) {
    \n-
    207 if (i<mype) {
    \n-
    208 base += globalNumOfVtx[i];
    \n-
    209 }
    \n-
    210 vtxDist_[i+1] = vtxDist_[i] + globalNumOfVtx[i];
    \n-
    211 }
    \n-
    212 globalOwnerVertices=vtxDist_[npes];
    \n-
    213 base_=base;
    \n+
    204 template<typename B, typename A>
    \n+
    205 struct FieldTraits< BTDMatrix<B, A> >
    \n+
    206 {
    \n+\n+
    208 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    209 };
    \n+
    210
    \n+
    213} // end namespace Dune
    \n
    214
    \n-
    215#ifdef DEBUG_REPART
    \n-
    216 std::cout << oocomm.communicator().rank()<<" vtxDist: ";
    \n-
    217 for(int i=0; i<= npes; ++i)
    \n-
    218 std::cout << vtxDist_[i]<<" ";
    \n-
    219 std::cout<<std::endl;
    \n-
    220#endif
    \n-
    221
    \n-
    222 // Traverse the graph and assign a new consecutive number/index
    \n-
    223 // starting by "base" to all owner vertices.
    \n-
    224 // The new index is used as the ParMETIS global index and is
    \n-
    225 // stored in the vector "duneToParmetis"
    \n-
    226 auto vend = graph.end();
    \n-
    227 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {
    \n-
    228 const typename OOComm::ParallelIndexSet::IndexPair* index=oocomm.globalLookup().pair(*vertex);
    \n-
    229 assert(index);
    \n-
    230 if (OwnerSet::contains(index->local().attribute())) {
    \n-
    231 // assign and count the index
    \n-
    232 parmetisToDune[base-base_]=index->local();
    \n-
    233 duneToParmetis[index->local()] = base++;
    \n-
    234 }
    \n-
    235 }
    \n-
    236
    \n-
    237 // At this point, every process knows the ParMETIS global index
    \n-
    238 // of it's owner vertices. The next step is to get the
    \n-
    239 // ParMETIS global index of the overlap vertices from the
    \n-
    240 // associated processes. To do this, the Dune::Interface class
    \n-
    241 // is used.
    \n-
    242#ifdef DEBUG_REPART
    \n-
    243 std::cout <<oocomm.communicator().rank()<<": before ";
    \n-
    244 for(std::size_t i=0; i<duneToParmetis.size(); ++i)
    \n-
    245 std::cout<<duneToParmetis[i]<<" ";
    \n-
    246 std::cout<<std::endl;
    \n-
    247#endif
    \n-
    248 oocomm.copyOwnerToAll(duneToParmetis,duneToParmetis);
    \n-
    249#ifdef DEBUG_REPART
    \n-
    250 std::cout <<oocomm.communicator().rank()<<": after ";
    \n-
    251 for(std::size_t i=0; i<duneToParmetis.size(); ++i)
    \n-
    252 std::cout<<duneToParmetis[i]<<" ";
    \n-
    253 std::cout<<std::endl;
    \n-
    254#endif
    \n-
    255 }
    \n-
    256 }
    \n-
    257
    \n-\n-
    259 : public Interface
    \n-
    260 {
    \n-
    261 void setCommunicator(MPI_Comm comm)
    \n-
    262 {
    \n-
    263 communicator_=comm;
    \n-
    264 }
    \n-
    265 template<class Flags,class IS>
    \n-
    266 void buildSendInterface(const std::vector<int>& toPart, const IS& idxset)
    \n-
    267 {
    \n-
    268 std::map<int,int> sizes;
    \n-
    269
    \n-
    270 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)
    \n-
    271 if(Flags::contains(i->local().attribute()))
    \n-
    272 ++sizes[toPart[i->local()]];
    \n-
    273
    \n-
    274 // Allocate the necessary space
    \n-
    275 for(auto i=sizes.begin(), end=sizes.end(); i!=end; ++i)
    \n-
    276 interfaces()[i->first].first.reserve(i->second);
    \n-
    277
    \n-
    278 //Insert the interface information
    \n-
    279 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)
    \n-
    280 if(Flags::contains(i->local().attribute()))
    \n-
    281 interfaces()[toPart[i->local()]].first.add(i->local());
    \n-
    282 }
    \n-
    283
    \n-
    284 void reserveSpaceForReceiveInterface(int proc, int size)
    \n-
    285 {
    \n-
    286 interfaces()[proc].second.reserve(size);
    \n-
    287 }
    \n-
    288 void addReceiveIndex(int proc, std::size_t idx)
    \n-
    289 {
    \n-
    290 interfaces()[proc].second.add(idx);
    \n-
    291 }
    \n-
    292 template<typename TG>
    \n-
    293 void buildReceiveInterface(std::vector<std::pair<TG,int> >& indices)
    \n-
    294 {
    \n-
    295 std::size_t i=0;
    \n-
    296 for(auto idx=indices.begin(); idx!= indices.end(); ++idx) {
    \n-
    297 interfaces()[idx->second].second.add(i++);
    \n-
    298 }
    \n-
    299 }
    \n-
    300
    \n-\n-
    302 {}
    \n-
    303
    \n-
    304 };
    \n-
    305
    \n-
    306 namespace
    \n-
    307 {
    \n-
    317 template<class GI>
    \n-
    318 void createSendBuf(std::vector<GI>& ownerVec, std::set<GI>& overlapVec, std::set<int>& neighbors, char *sendBuf, int buffersize, MPI_Comm comm) {
    \n-
    319 // Pack owner vertices
    \n-
    320 std::size_t s=ownerVec.size();
    \n-
    321 int pos=0;
    \n-
    322 if(s==0)
    \n-
    323 ownerVec.resize(1); // otherwise would read beyond the memory bound
    \n-
    324 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n-
    325 MPI_Pack(&(ownerVec[0]), s, MPITraits<GI>::getType(), sendBuf, buffersize, &pos, comm);
    \n-
    326 s = overlapVec.size();
    \n-
    327 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n-
    328 for(auto i=overlapVec.begin(), end= overlapVec.end(); i != end; ++i)
    \n-
    329 MPI_Pack(const_cast<GI*>(&(*i)), 1, MPITraits<GI>::getType(), sendBuf, buffersize, &pos, comm);
    \n-
    330
    \n-
    331 s=neighbors.size();
    \n-
    332 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n-
    333
    \n-
    334 for(auto i=neighbors.begin(), end= neighbors.end(); i != end; ++i)
    \n-
    335 MPI_Pack(const_cast<int*>(&(*i)), 1, MPI_INT, sendBuf, buffersize, &pos, comm);
    \n-
    336 }
    \n-
    345 template<class GI>
    \n-
    346 void saveRecvBuf(char *recvBuf, int bufferSize, std::vector<std::pair<GI,int> >& ownerVec,
    \n-
    347 std::set<GI>& overlapVec, std::set<int>& neighbors, RedistributeInterface& inf, int from, MPI_Comm comm) {
    \n-
    348 std::size_t size;
    \n-
    349 int pos=0;
    \n-
    350 // unpack owner vertices
    \n-
    351 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n-
    352 inf.reserveSpaceForReceiveInterface(from, size);
    \n-
    353 ownerVec.reserve(ownerVec.size()+size);
    \n-
    354 for(; size!=0; --size) {
    \n-
    355 GI gi;
    \n-
    356 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits<GI>::getType(), comm);
    \n-
    357 ownerVec.push_back(std::make_pair(gi,from));
    \n-
    358 }
    \n-
    359 // unpack overlap vertices
    \n-
    360 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n-
    361 typename std::set<GI>::iterator ipos = overlapVec.begin();
    \n-
    362 Dune::dverb << "unpacking "<<size<<" overlap"<<std::endl;
    \n-
    363 for(; size!=0; --size) {
    \n-
    364 GI gi;
    \n-
    365 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits<GI>::getType(), comm);
    \n-
    366 ipos=overlapVec.insert(ipos, gi);
    \n-
    367 }
    \n-
    368 //unpack neighbors
    \n-
    369 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n-
    370 Dune::dverb << "unpacking "<<size<<" neighbors"<<std::endl;
    \n-
    371 typename std::set<int>::iterator npos = neighbors.begin();
    \n-
    372 for(; size!=0; --size) {
    \n-
    373 int n;
    \n-
    374 MPI_Unpack(recvBuf, bufferSize, &pos, &n, 1, MPI_INT, comm);
    \n-
    375 npos=neighbors.insert(npos, n);
    \n-
    376 }
    \n-
    377 }
    \n-
    378
    \n-
    392 template<typename T>
    \n-
    393 void getDomain(const MPI_Comm& comm, T *part, int numOfOwnVtx, int nparts, int *myDomain, std::vector<int> &domainMapping) {
    \n-
    394 int npes, mype;
    \n-
    395 MPI_Comm_size(comm, &npes);
    \n-
    396 MPI_Comm_rank(comm, &mype);
    \n-
    397 MPI_Status status;
    \n-
    398
    \n-
    399 *myDomain = -1;
    \n-
    400 int i=0;
    \n-
    401 int j=0;
    \n-
    402
    \n-
    403 std::vector<int> domain(nparts, 0);
    \n-
    404 std::vector<int> assigned(npes, 0);
    \n-
    405 // init domain Mapping
    \n-
    406 domainMapping.assign(domainMapping.size(), -1);
    \n-
    407
    \n-
    408 // count the occurrence of domains
    \n-
    409 for (i=0; i<numOfOwnVtx; i++) {
    \n-
    410 domain[part[i]]++;
    \n-
    411 }
    \n-
    412
    \n-
    413 std::vector<int> domainMatrix(npes * nparts, -1);
    \n-
    414
    \n-
    415 // init buffer with the own domain
    \n-
    416 int *buf = new int[nparts];
    \n-
    417 for (i=0; i<nparts; i++) {
    \n-
    418 buf[i] = domain[i];
    \n-
    419 domainMatrix[mype*nparts+i] = domain[i];
    \n-
    420 }
    \n-
    421 int pe=0;
    \n-
    422 int src = (mype-1+npes)%npes;
    \n-
    423 int dest = (mype+1)%npes;
    \n-
    424 // ring communication, we need n-1 communications for n processors
    \n-
    425 for (i=0; i<npes-1; i++) {
    \n-
    426 MPI_Sendrecv_replace(buf, nparts, MPI_INT, dest, 0, src, 0, comm, &status);
    \n-
    427 // pe is the process of the actual received buffer
    \n-
    428 pe = ((mype-1-i)+npes)%npes;
    \n-
    429 for(j=0; j<nparts; j++) {
    \n-
    430 // save the values to the domain matrix
    \n-
    431 domainMatrix[pe*nparts+j] = buf[j];
    \n-
    432 }
    \n-
    433 }
    \n-
    434 delete[] buf;
    \n-
    435
    \n-
    436 // Start the domain calculation.
    \n-
    437 // The process which contains the maximum number of vertices of a
    \n-
    438 // particular domain is selected to choose it's favorate domain
    \n-
    439 int maxOccurance = 0;
    \n-
    440 pe = -1;
    \n-
    441 std::set<std::size_t> unassigned;
    \n-
    442
    \n-
    443 for(i=0; i<nparts; i++) {
    \n-
    444 for(j=0; j<npes; j++) {
    \n-
    445 // process has no domain assigned
    \n-
    446 if (assigned[j]==0) {
    \n-
    447 if (maxOccurance < domainMatrix[j*nparts+i]) {
    \n-
    448 maxOccurance = domainMatrix[j*nparts+i];
    \n-
    449 pe = j;
    \n-
    450 }
    \n-
    451 }
    \n-
    452
    \n-
    453 }
    \n-
    454 if (pe!=-1) {
    \n-
    455 // process got a domain, ...
    \n-
    456 domainMapping[i] = pe;
    \n-
    457 // ...mark as assigned
    \n-
    458 assigned[pe] = 1;
    \n-
    459 if (pe==mype) {
    \n-
    460 *myDomain = i;
    \n-
    461 }
    \n-
    462 pe = -1;
    \n-
    463 }
    \n-
    464 else
    \n-
    465 {
    \n-
    466 unassigned.insert(i);
    \n-
    467 }
    \n-
    468 maxOccurance = 0;
    \n-
    469 }
    \n-
    470
    \n-
    471 typename std::vector<int>::iterator next_free = assigned.begin();
    \n-
    472
    \n-
    473 for(auto udomain = unassigned.begin(),
    \n-
    474 end = unassigned.end(); udomain != end; ++udomain)
    \n-
    475 {
    \n-
    476 next_free = std::find_if(next_free, assigned.end(), std::bind(std::less<int>(), std::placeholders::_1, 1));
    \n-
    477 assert(next_free != assigned.end());
    \n-
    478 domainMapping[*udomain] = next_free-assigned.begin();
    \n-
    479 *next_free = 1;
    \n-
    480 }
    \n-
    481 }
    \n-
    482
    \n-
    483 struct SortFirst
    \n-
    484 {
    \n-
    485 template<class T>
    \n-
    486 bool operator()(const T& t1, const T& t2) const
    \n-
    487 {
    \n-
    488 return t1<t2;
    \n-
    489 }
    \n-
    490 };
    \n-
    491
    \n-
    492
    \n-
    503 template<class GI>
    \n-
    504 void mergeVec(std::vector<std::pair<GI, int> >& ownerVec, std::set<GI>& overlapSet) {
    \n-
    505
    \n-
    506#ifdef DEBUG_REPART
    \n-
    507 // Safety check for duplicates.
    \n-
    508 if(ownerVec.size()>0)
    \n-
    509 {
    \n-
    510 auto old=ownerVec.begin();
    \n-
    511 for(auto i=old+1, end=ownerVec.end(); i != end; old=i++)
    \n-
    512 {
    \n-
    513 if(i->first==old->first)
    \n-
    514 {
    \n-
    515 std::cerr<<"Value at indes"<<old-ownerVec.begin()<<" is the same as at index "
    \n-
    516 <<i-ownerVec.begin()<<" ["<<old->first<<","<<old->second<<"]==["
    \n-
    517 <<i->first<<","<<i->second<<"]"<<std::endl;
    \n-
    518 throw "Huch!";
    \n-
    519 }
    \n-
    520 }
    \n-
    521 }
    \n-
    522
    \n-
    523#endif
    \n-
    524
    \n-
    525 auto v=ownerVec.begin(), vend=ownerVec.end();
    \n-
    526 for(auto s=overlapSet.begin(), send=overlapSet.end(); s!=send;)
    \n-
    527 {
    \n-
    528 while(v!=vend && v->first<*s) ++v;
    \n-
    529 if(v!=vend && v->first==*s) {
    \n-
    530 // Move to the next element before erasing
    \n-
    531 // thus s stays valid!
    \n-
    532 auto tmp=s;
    \n-
    533 ++s;
    \n-
    534 overlapSet.erase(tmp);
    \n-
    535 }else
    \n-
    536 ++s;
    \n-
    537 }
    \n-
    538 }
    \n-
    539
    \n-
    540
    \n-
    554 template<class OwnerSet, class Graph, class IS, class GI>
    \n-
    555 void getNeighbor(const Graph& g, std::vector<int>& part,
    \n-
    556 typename Graph::VertexDescriptor vtx, const IS& indexSet,
    \n-
    557 int toPe, std::set<GI>& neighbor, std::set<int>& neighborProcs) {
    \n-
    558 for(auto edge=g.beginEdges(vtx), end=g.endEdges(vtx); edge!=end; ++edge)
    \n-
    559 {
    \n-
    560 const typename IS::IndexPair* pindex = indexSet.pair(edge.target());
    \n-
    561 assert(pindex);
    \n-
    562 if(part[pindex->local()]!=toPe || !OwnerSet::contains(pindex->local().attribute()))
    \n-
    563 {
    \n-
    564 // is sent to another process and therefore becomes overlap
    \n-
    565 neighbor.insert(pindex->global());
    \n-
    566 neighborProcs.insert(part[pindex->local()]);
    \n-
    567 }
    \n-
    568 }
    \n-
    569 }
    \n-
    570
    \n-
    571 template<class T, class I>
    \n-
    572 void my_push_back(std::vector<T>& ownerVec, const I& index, [[maybe_unused]] int proc)
    \n-
    573 {
    \n-
    574 ownerVec.push_back(index);
    \n-
    575 }
    \n-
    576
    \n-
    577 template<class T, class I>
    \n-
    578 void my_push_back(std::vector<std::pair<T,int> >& ownerVec, const I& index, int proc)
    \n-
    579 {
    \n-
    580 ownerVec.push_back(std::make_pair(index,proc));
    \n-
    581 }
    \n-
    582 template<class T>
    \n-
    583 void reserve(std::vector<T>&, RedistributeInterface&, int)
    \n-
    584 {}
    \n-
    585 template<class T>
    \n-
    586 void reserve(std::vector<std::pair<T,int> >& ownerVec, RedistributeInterface& redist, int proc)
    \n-
    587 {
    \n-
    588 redist.reserveSpaceForReceiveInterface(proc, ownerVec.size());
    \n-
    589 }
    \n-
    590
    \n-
    591
    \n-
    609 template<class OwnerSet, class G, class IS, class T, class GI>
    \n-
    610 void getOwnerOverlapVec(const G& graph, std::vector<int>& part, IS& indexSet,
    \n-
    611 [[maybe_unused]] int myPe, int toPe, std::vector<T>& ownerVec, std::set<GI>& overlapSet,
    \n-
    612 RedistributeInterface& redist, std::set<int>& neighborProcs) {
    \n-
    613 for(auto index = indexSet.begin(); index != indexSet.end(); ++index) {
    \n-
    614 // Only Process owner vertices, the others are not in the parmetis graph.
    \n-
    615 if(OwnerSet::contains(index->local().attribute()))
    \n-
    616 {
    \n-
    617 if(part[index->local()]==toPe)
    \n-
    618 {
    \n-
    619 getNeighbor<OwnerSet>(graph, part, index->local(), indexSet,
    \n-
    620 toPe, overlapSet, neighborProcs);
    \n-
    621 my_push_back(ownerVec, index->global(), toPe);
    \n-
    622 }
    \n-
    623 }
    \n-
    624 }
    \n-
    625 reserve(ownerVec, redist, toPe);
    \n-
    626
    \n-
    627 }
    \n-
    628
    \n-
    629
    \n-
    636 template<class F, class IS>
    \n-
    637 inline bool isOwner(IS& indexSet, int index) {
    \n-
    638
    \n-
    639 const typename IS::IndexPair* pindex=indexSet.pair(index);
    \n-
    640
    \n-
    641 assert(pindex);
    \n-
    642 return F::contains(pindex->local().attribute());
    \n-
    643 }
    \n-
    644
    \n-
    645
    \n-
    646 class BaseEdgeFunctor
    \n-
    647 {
    \n-
    648 public:
    \n-
    649 BaseEdgeFunctor(Metis::idx_t* adj,const ParmetisDuneIndexMap& data)
    \n-
    650 : i_(), adj_(adj), data_(data)
    \n-
    651 {}
    \n-
    652
    \n-
    653 template<class T>
    \n-
    654 void operator()(const T& edge)
    \n-
    655 {
    \n-
    656 // Get the egde weight
    \n-
    657 // const Weight& weight=edge.weight();
    \n-
    658 adj_[i_] = data_.toParmetis(edge.target());
    \n-
    659 i_++;
    \n-
    660 }
    \n-
    661 std::size_t index()
    \n-
    662 {
    \n-
    663 return i_;
    \n-
    664 }
    \n-
    665
    \n-
    666 private:
    \n-
    667 std::size_t i_;
    \n-
    668 Metis::idx_t* adj_;
    \n-
    669 const ParmetisDuneIndexMap& data_;
    \n-
    670 };
    \n-
    671
    \n-
    672 template<typename G>
    \n-
    673 struct EdgeFunctor
    \n-
    674 : public BaseEdgeFunctor
    \n-
    675 {
    \n-
    676 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::size_t)
    \n-
    677 : BaseEdgeFunctor(adj, data)
    \n-
    678 {}
    \n-
    679
    \n-
    680 Metis::idx_t* getWeights()
    \n-
    681 {
    \n-
    682 return NULL;
    \n-
    683 }
    \n-
    684 void free(){}
    \n-
    685 };
    \n-
    686
    \n-
    687 template<class G, class V, class E, class VM, class EM>
    \n-
    688 class EdgeFunctor<Dune::Amg::PropertiesGraph<G,V,E,VM,EM> >
    \n-
    689 : public BaseEdgeFunctor
    \n-
    690 {
    \n-
    691 public:
    \n-
    692 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::size_t s)
    \n-
    693 : BaseEdgeFunctor(adj, data)
    \n-
    694 {
    \n-
    695 weight_=new Metis::idx_t[s];
    \n-
    696 }
    \n-
    697
    \n-
    698 template<class T>
    \n-
    699 void operator()(const T& edge)
    \n-
    700 {
    \n-
    701 weight_[index()]=edge.properties().depends() ? 3 : 1;
    \n-
    702 BaseEdgeFunctor::operator()(edge);
    \n-
    703 }
    \n-
    704 Metis::idx_t* getWeights()
    \n-
    705 {
    \n-
    706 return weight_;
    \n-
    707 }
    \n-
    708 void free(){
    \n-
    709 if(weight_!=0) {
    \n-
    710 delete weight_;
    \n-
    711 weight_=0;
    \n-
    712 }
    \n-
    713 }
    \n-
    714 private:
    \n-
    715 Metis::idx_t* weight_;
    \n-
    716 };
    \n-
    717
    \n-
    718
    \n-
    719
    \n-
    733 template<class F, class G, class IS, class EW>
    \n-
    734 void getAdjArrays(G& graph, IS& indexSet, Metis::idx_t *xadj,
    \n-
    735 EW& ew)
    \n-
    736 {
    \n-
    737 int j=0;
    \n-
    738 auto vend = graph.end();
    \n-
    739
    \n-
    740 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {
    \n-
    741 if (isOwner<F>(indexSet,*vertex)) {
    \n-
    742 // The type of const edge iterator.
    \n-
    743 auto eend = vertex.end();
    \n-
    744 xadj[j] = ew.index();
    \n-
    745 j++;
    \n-
    746 for(auto edge = vertex.begin(); edge != eend; ++edge) {
    \n-
    747 ew(edge);
    \n-
    748 }
    \n-
    749 }
    \n-
    750 }
    \n-
    751 xadj[j] = ew.index();
    \n-
    752 }
    \n-
    753 } // end anonymous namespace
    \n-
    754
    \n-
    755 template<class G, class T1, class T2>
    \n-
    756 bool buildCommunication(const G& graph, std::vector<int>& realparts,
    \n-\n-
    758 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n-
    759 RedistributeInterface& redistInf,
    \n-
    760 bool verbose=false);
    \n-
    761#if HAVE_PARMETIS
    \n-
    762#ifndef METIS_VER_MAJOR
    \n-
    763 extern "C"
    \n-
    764 {
    \n-
    765 // backwards compatibility to parmetis < 4.0.0
    \n-
    766 void METIS_PartGraphKway(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t *adjncy, Metis::idx_t *vwgt,
    \n-
    767 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,
    \n-
    768 int *options, int *edgecut, Metis::idx_t *part);
    \n-
    769
    \n-
    770 void METIS_PartGraphRecursive(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t *adjncy, Metis::idx_t *vwgt,
    \n-
    771 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,
    \n-
    772 int *options, int *edgecut, Metis::idx_t *part);
    \n-
    773 }
    \n-
    774#endif
    \n-
    775#endif // HAVE_PARMETIS
    \n-
    776
    \n-
    777 template<class S, class T>
    \n-
    778 inline void print_carray(S& os, T* array, std::size_t l)
    \n-
    779 {
    \n-
    780 for(T *cur=array, *end=array+l; cur!=end; ++cur)
    \n-
    781 os<<*cur<<" ";
    \n-
    782 }
    \n-
    783
    \n-
    784 template<class S, class T>
    \n-
    785 inline bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T* xadj,
    \n-
    786 T* adjncy, bool checkSymmetry)
    \n-
    787 {
    \n-
    788 bool correct=true;
    \n-
    789
    \n-
    790 using std::signbit;
    \n-
    791 for(Metis::idx_t vtx=0; vtx<(Metis::idx_t)noVtx; ++vtx) {
    \n-
    792 if(static_cast<S>(xadj[vtx])>noEdges || signbit(xadj[vtx])) {
    \n-
    793 std::cerr <<"Check graph: xadj["<<vtx<<"]="<<xadj[vtx]<<" (>"
    \n-
    794 <<noEdges<<") out of range!"<<std::endl;
    \n-
    795 correct=false;
    \n-
    796 }
    \n-
    797 if(static_cast<S>(xadj[vtx+1])>noEdges || signbit(xadj[vtx+1])) {
    \n-
    798 std::cerr <<"Check graph: xadj["<<vtx+1<<"]="<<xadj[vtx+1]<<" (>"
    \n-
    799 <<noEdges<<") out of range!"<<std::endl;
    \n-
    800 correct=false;
    \n-
    801 }
    \n-
    802 // Check numbers in adjncy
    \n-
    803 for(Metis::idx_t i=xadj[vtx]; i< xadj[vtx+1]; ++i) {
    \n-
    804 if(signbit(adjncy[i]) || ((std::size_t)adjncy[i])>gnoVtx) {
    \n-
    805 std::cerr<<" Edge "<<adjncy[i]<<" out of range ["<<0<<","<<noVtx<<")"
    \n-
    806 <<std::endl;
    \n-
    807 correct=false;
    \n-
    808 }
    \n-
    809 }
    \n-
    810 if(checkSymmetry) {
    \n-
    811 for(Metis::idx_t i=xadj[vtx]; i< xadj[vtx+1]; ++i) {
    \n-
    812 Metis::idx_t target=adjncy[i];
    \n-
    813 // search for symmetric edge
    \n-
    814 int found=0;
    \n-
    815 for(Metis::idx_t j=xadj[target]; j< xadj[target+1]; ++j)
    \n-
    816 if(adjncy[j]==vtx)
    \n-
    817 found++;
    \n-
    818 if(found!=1) {
    \n-
    819 std::cerr<<"Edge ("<<target<<","<<vtx<<") "<<i<<" time"<<std::endl;
    \n-
    820 correct=false;
    \n-
    821 }
    \n-
    822 }
    \n-
    823 }
    \n-
    824 }
    \n-
    825 return correct;
    \n-
    826 }
    \n-
    827
    \n-
    828 template<class M, class T1, class T2>
    \n-\n-
    830 Metis::idx_t nparts,
    \n-
    831 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n-
    832 RedistributeInterface& redistInf,
    \n-
    833 bool verbose=false)
    \n-
    834 {
    \n-
    835 if(verbose && oocomm.communicator().rank()==0)
    \n-
    836 std::cout<<"Repartitioning from "<<oocomm.communicator().size()
    \n-
    837 <<" to "<<nparts<<" parts"<<std::endl;
    \n-
    838 Timer time;
    \n-
    839 int rank = oocomm.communicator().rank();
    \n-
    840#if !HAVE_PARMETIS
    \n-
    841 int* part = new int[1];
    \n-
    842 part[0]=0;
    \n-
    843#else
    \n-
    844 Metis::idx_t* part = new Metis::idx_t[1]; // where all our data moves to
    \n-
    845
    \n-
    846 if(nparts>1) {
    \n-
    847
    \n-
    848 part[0]=rank;
    \n-
    849
    \n-
    850 { // sublock for automatic memory deletion
    \n-
    851
    \n-
    852 // Build the graph of the communication scheme and create an appropriate indexset.
    \n-
    853 // calculate the neighbour vertices
    \n-
    854 int noNeighbours = oocomm.remoteIndices().neighbours();
    \n-
    855
    \n-
    856 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n-
    857 ++n)
    \n-
    858 if(n->first==rank) {
    \n-
    859 //do not include ourselves.
    \n-
    860 --noNeighbours;
    \n-
    861 break;
    \n-
    862 }
    \n-
    863
    \n-
    864 // A parmetis graph representing the communication graph.
    \n-
    865 // The diagonal entries are the number of nodes on the process.
    \n-
    866 // The offdiagonal entries are the number of edges leading to other processes.
    \n-
    867
    \n-
    868 Metis::idx_t *xadj=new Metis::idx_t[2];
    \n-
    869 Metis::idx_t *vtxdist=new Metis::idx_t[oocomm.communicator().size()+1];
    \n-
    870 Metis::idx_t *adjncy=new Metis::idx_t[noNeighbours];
    \n-
    871#ifdef USE_WEIGHTS
    \n-
    872 Metis::idx_t *vwgt = 0;
    \n-
    873 Metis::idx_t *adjwgt = 0;
    \n-
    874#endif
    \n-
    875
    \n-
    876 // each process has exactly one vertex!
    \n-
    877 for(int i=0; i<oocomm.communicator().size(); ++i)
    \n-
    878 vtxdist[i]=i;
    \n-
    879 vtxdist[oocomm.communicator().size()]=oocomm.communicator().size();
    \n-
    880
    \n-
    881 xadj[0]=0;
    \n-
    882 xadj[1]=noNeighbours;
    \n-
    883
    \n-
    884 // count edges to other processor
    \n-
    885 // a vector mapping the index to the owner
    \n-
    886 // std::vector<int> owner(mat.N(), oocomm.communicator().rank());
    \n-
    887 // for(NeighbourIterator n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n-
    888 // ++n)
    \n-
    889 // {
    \n-
    890 // if(n->first!=oocomm.communicator().rank()){
    \n-
    891 // typedef typename RemoteIndices::RemoteIndexList RIList;
    \n-
    892 // const RIList& rlist = *(n->second.first);
    \n-
    893 // typedef typename RIList::const_iterator LIter;
    \n-
    894 // for(LIter entry=rlist.begin(); entry!=rlist.end(); ++entry){
    \n-
    895 // if(entry->attribute()==OwnerOverlapCopyAttributeSet::owner)
    \n-
    896 // owner[entry->localIndexPair().local()] = n->first;
    \n-
    897 // }
    \n-
    898 // }
    \n-
    899 // }
    \n-
    900
    \n-
    901 // std::map<int,Metis::idx_t> edgecount; // edges to other processors
    \n-
    902 // typedef typename M::ConstRowIterator RIter;
    \n-
    903 // typedef typename M::ConstColIterator CIter;
    \n-
    904
    \n-
    905 // // calculate edge count
    \n-
    906 // for(RIter row=mat.begin(), endr=mat.end(); row != endr; ++row)
    \n-
    907 // if(owner[row.index()]==OwnerOverlapCopyAttributeSet::owner)
    \n-
    908 // for(CIter entry= row->begin(), ende = row->end(); entry != ende; ++entry)
    \n-
    909 // ++edgecount[owner[entry.index()]];
    \n-
    910
    \n-
    911 // setup edge and weight pattern
    \n-
    912
    \n-
    913 Metis::idx_t* adjp=adjncy;
    \n-
    914
    \n-
    915#ifdef USE_WEIGHTS
    \n-
    916 vwgt = new Metis::idx_t[1];
    \n-
    917 vwgt[0]= mat.N(); // weight is numer of rows TODO: Should actually be the nonzeros.
    \n-
    918
    \n-
    919 adjwgt = new Metis::idx_t[noNeighbours];
    \n-
    920 Metis::idx_t* adjwp=adjwgt;
    \n-
    921#endif
    \n-
    922
    \n-
    923 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n-
    924 ++n)
    \n-
    925 if(n->first != rank) {
    \n-
    926 *adjp=n->first;
    \n-
    927 ++adjp;
    \n-
    928#ifdef USE_WEIGHTS
    \n-
    929 *adjwp=1; //edgecount[n->first];
    \n-
    930 ++adjwp;
    \n-
    931#endif
    \n-
    932 }
    \n-
    933 assert(isValidGraph(vtxdist[rank+1]-vtxdist[rank],
    \n-
    934 vtxdist[oocomm.communicator().size()],
    \n-
    935 noNeighbours, xadj, adjncy, false));
    \n-
    936
    \n-
    937 [[maybe_unused]] Metis::idx_t wgtflag=0;
    \n-
    938 Metis::idx_t numflag=0;
    \n-
    939 Metis::idx_t edgecut;
    \n-
    940#ifdef USE_WEIGHTS
    \n-
    941 wgtflag=3;
    \n-
    942#endif
    \n-
    943 Metis::real_t *tpwgts = new Metis::real_t[nparts];
    \n-
    944 for(int i=0; i<nparts; ++i)
    \n-
    945 tpwgts[i]=1.0/nparts;
    \n-
    946 MPI_Comm comm=oocomm.communicator();
    \n-
    947
    \n-
    948 Dune::dinfo<<rank<<" vtxdist: ";
    \n-
    949 print_carray(Dune::dinfo, vtxdist, oocomm.communicator().size()+1);
    \n-
    950 Dune::dinfo<<std::endl<<rank<<" xadj: ";
    \n-
    951 print_carray(Dune::dinfo, xadj, 2);
    \n-
    952 Dune::dinfo<<std::endl<<rank<<" adjncy: ";
    \n-
    953 print_carray(Dune::dinfo, adjncy, noNeighbours);
    \n-
    954
    \n-
    955#ifdef USE_WEIGHTS
    \n-
    956 Dune::dinfo<<std::endl<<rank<<" vwgt: ";
    \n-
    957 print_carray(Dune::dinfo, vwgt, 1);
    \n-
    958 Dune::dinfo<<std::endl<<rank<<" adwgt: ";
    \n-
    959 print_carray(Dune::dinfo, adjwgt, noNeighbours);
    \n-
    960#endif
    \n-
    961 Dune::dinfo<<std::endl;
    \n-
    962 oocomm.communicator().barrier();
    \n-
    963 if(verbose && oocomm.communicator().rank()==0)
    \n-
    964 std::cout<<"Creating comm graph took "<<time.elapsed()<<std::endl;
    \n-
    965 time.reset();
    \n-
    966
    \n-
    967#ifdef PARALLEL_PARTITION
    \n-
    968 Metis::real_t ubvec = 1.15;
    \n-
    969 int ncon=1;
    \n-
    970 int options[5] ={ 0,1,15,0,0};
    \n-
    971
    \n-
    972 //=======================================================
    \n-
    973 // ParMETIS_V3_PartKway
    \n-
    974 //=======================================================
    \n-
    975 ParMETIS_V3_PartKway(vtxdist, xadj, adjncy,
    \n-
    976 vwgt, adjwgt, &wgtflag,
    \n-
    977 &numflag, &ncon, &nparts, tpwgts, &ubvec, options, &edgecut, part,
    \n-
    978 &comm);
    \n-
    979 if(verbose && oocomm.communicator().rank()==0)
    \n-
    980 std::cout<<"ParMETIS took "<<time.elapsed()<<std::endl;
    \n-
    981 time.reset();
    \n-
    982#else
    \n-
    983 Timer time1;
    \n-
    984 std::size_t gnoedges=0;
    \n-
    985 int* noedges = 0;
    \n-
    986 noedges = new int[oocomm.communicator().size()];
    \n-
    987 Dune::dverb<<"noNeighbours: "<<noNeighbours<<std::endl;
    \n-
    988 // gather number of edges for each vertex.
    \n-
    989 MPI_Allgather(&noNeighbours,1,MPI_INT,noedges,1, MPI_INT,oocomm.communicator());
    \n-
    990
    \n-
    991 if(verbose && oocomm.communicator().rank()==0)
    \n-
    992 std::cout<<"Gathering noedges took "<<time1.elapsed()<<std::endl;
    \n-
    993 time1.reset();
    \n-
    994
    \n-
    995 Metis::idx_t noVertices = vtxdist[oocomm.communicator().size()];
    \n-
    996 Metis::idx_t *gxadj = 0;
    \n-
    997 Metis::idx_t *gvwgt = 0;
    \n-
    998 Metis::idx_t *gadjncy = 0;
    \n-
    999 Metis::idx_t *gadjwgt = 0;
    \n-
    1000 Metis::idx_t *gpart = 0;
    \n-
    1001 int* displ = 0;
    \n-
    1002 int* noxs = 0;
    \n-
    1003 int* xdispl = 0; // displacement for xadj
    \n-
    1004 int* novs = 0;
    \n-
    1005 int* vdispl=0; // real vertex displacement
    \n-
    1006#ifdef USE_WEIGHTS
    \n-
    1007 std::size_t localNoVtx=vtxdist[rank+1]-vtxdist[rank];
    \n-
    1008#endif
    \n-
    1009 std::size_t gxadjlen = vtxdist[oocomm.communicator().size()]-vtxdist[0]+oocomm.communicator().size();
    \n-
    1010
    \n-
    1011 {
    \n-
    1012 Dune::dinfo<<"noedges: ";
    \n-
    1013 print_carray(Dune::dinfo, noedges, oocomm.communicator().size());
    \n-
    1014 Dune::dinfo<<std::endl;
    \n-
    1015 displ = new int[oocomm.communicator().size()];
    \n-
    1016 xdispl = new int[oocomm.communicator().size()];
    \n-
    1017 noxs = new int[oocomm.communicator().size()];
    \n-
    1018 vdispl = new int[oocomm.communicator().size()];
    \n-
    1019 novs = new int[oocomm.communicator().size()];
    \n-
    1020
    \n-
    1021 for(int i=0; i < oocomm.communicator().size(); ++i) {
    \n-
    1022 noxs[i]=vtxdist[i+1]-vtxdist[i]+1;
    \n-
    1023 novs[i]=vtxdist[i+1]-vtxdist[i];
    \n-
    1024 }
    \n-
    1025
    \n-
    1026 Metis::idx_t *so= vtxdist;
    \n-
    1027 int offset = 0;
    \n-
    1028 for(int *xcurr = xdispl, *vcurr = vdispl, *end=vdispl+oocomm.communicator().size();
    \n-
    1029 vcurr!=end; ++vcurr, ++xcurr, ++so, ++offset) {
    \n-
    1030 *vcurr = *so;
    \n-
    1031 *xcurr = offset + *so;
    \n-
    1032 }
    \n-
    1033
    \n-
    1034 int *pdispl =displ;
    \n-
    1035 int cdispl = 0;
    \n-
    1036 *pdispl = 0;
    \n-
    1037 for(int *curr=noedges, *end=noedges+oocomm.communicator().size()-1;
    \n-
    1038 curr!=end; ++curr) {
    \n-
    1039 ++pdispl; // next displacement
    \n-
    1040 cdispl += *curr; // next value
    \n-
    1041 *pdispl = cdispl;
    \n-
    1042 }
    \n-
    1043 Dune::dinfo<<"displ: ";
    \n-
    1044 print_carray(Dune::dinfo, displ, oocomm.communicator().size());
    \n-
    1045 Dune::dinfo<<std::endl;
    \n-
    1046
    \n-
    1047 // calculate global number of edges
    \n-
    1048 // It is bigger than the actual one as we habe size-1 additional end entries
    \n-
    1049 for(int *curr=noedges, *end=noedges+oocomm.communicator().size();
    \n-
    1050 curr!=end; ++curr)
    \n-
    1051 gnoedges += *curr;
    \n-
    1052
    \n-
    1053 // alocate gobal graph
    \n-
    1054 Dune::dinfo<<"gxadjlen: "<<gxadjlen<<" noVertices: "<<noVertices
    \n-
    1055 <<" gnoedges: "<<gnoedges<<std::endl;
    \n-
    1056 gxadj = new Metis::idx_t[gxadjlen];
    \n-
    1057 gpart = new Metis::idx_t[noVertices];
    \n-
    1058#ifdef USE_WEIGHTS
    \n-
    1059 gvwgt = new Metis::idx_t[noVertices];
    \n-
    1060 gadjwgt = new Metis::idx_t[gnoedges];
    \n-
    1061#endif
    \n-
    1062 gadjncy = new Metis::idx_t[gnoedges];
    \n-
    1063 }
    \n-
    1064
    \n-
    1065 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1066 std::cout<<"Preparing global graph took "<<time1.elapsed()<<std::endl;
    \n-
    1067 time1.reset();
    \n-
    1068 // Communicate data
    \n-
    1069
    \n-
    1070 MPI_Allgatherv(xadj,2,MPITraits<Metis::idx_t>::getType(),
    \n-
    1071 gxadj,noxs,xdispl,MPITraits<Metis::idx_t>::getType(),
    \n-
    1072 comm);
    \n-
    1073 MPI_Allgatherv(adjncy,noNeighbours,MPITraits<Metis::idx_t>::getType(),
    \n-
    1074 gadjncy,noedges,displ,MPITraits<Metis::idx_t>::getType(),
    \n-
    1075 comm);
    \n-
    1076#ifdef USE_WEIGHTS
    \n-
    1077 MPI_Allgatherv(adjwgt,noNeighbours,MPITraits<Metis::idx_t>::getType(),
    \n-
    1078 gadjwgt,noedges,displ,MPITraits<Metis::idx_t>::getType(),
    \n-
    1079 comm);
    \n-
    1080 MPI_Allgatherv(vwgt,localNoVtx,MPITraits<Metis::idx_t>::getType(),
    \n-
    1081 gvwgt,novs,vdispl,MPITraits<Metis::idx_t>::getType(),
    \n-
    1082 comm);
    \n-
    1083#endif
    \n-
    1084 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1085 std::cout<<"Gathering global graph data took "<<time1.elapsed()<<std::endl;
    \n-
    1086 time1.reset();
    \n-
    1087
    \n-
    1088 {
    \n-
    1089 // create the real gxadj array
    \n-
    1090 // i.e. shift entries and add displacements.
    \n-
    1091
    \n-
    1092 print_carray(Dune::dinfo, gxadj, gxadjlen);
    \n-
    1093
    \n-
    1094 int offset = 0;
    \n-
    1095 Metis::idx_t increment = vtxdist[1];
    \n-
    1096 Metis::idx_t *start=gxadj+1;
    \n-
    1097 for(int i=1; i<oocomm.communicator().size(); ++i) {
    \n-
    1098 offset+=1;
    \n-
    1099 int lprev = vtxdist[i]-vtxdist[i-1];
    \n-
    1100 int l = vtxdist[i+1]-vtxdist[i];
    \n-
    1101 start+=lprev;
    \n-
    1102 assert((start+l+offset)-gxadj<=static_cast<Metis::idx_t>(gxadjlen));
    \n-
    1103 increment = *(start-1);
    \n-
    1104 std::transform(start+offset, start+l+offset, start, std::bind(std::plus<Metis::idx_t>(), std::placeholders::_1, increment));
    \n-
    1105 }
    \n-
    1106 Dune::dinfo<<std::endl<<"shifted xadj:";
    \n-
    1107 print_carray(Dune::dinfo, gxadj, noVertices+1);
    \n-
    1108 Dune::dinfo<<std::endl<<" gadjncy: ";
    \n-
    1109 print_carray(Dune::dinfo, gadjncy, gnoedges);
    \n-
    1110#ifdef USE_WEIGHTS
    \n-
    1111 Dune::dinfo<<std::endl<<" gvwgt: ";
    \n-
    1112 print_carray(Dune::dinfo, gvwgt, noVertices);
    \n-
    1113 Dune::dinfo<<std::endl<<"adjwgt: ";
    \n-
    1114 print_carray(Dune::dinfo, gadjwgt, gnoedges);
    \n-
    1115 Dune::dinfo<<std::endl;
    \n-
    1116#endif
    \n-
    1117 // everything should be fine now!!!
    \n-
    1118 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1119 std::cout<<"Postprocesing global graph data took "<<time1.elapsed()<<std::endl;
    \n-
    1120 time1.reset();
    \n-
    1121#ifndef NDEBUG
    \n-
    1122 assert(isValidGraph(noVertices, noVertices, gnoedges,
    \n-
    1123 gxadj, gadjncy, true));
    \n-
    1124#endif
    \n-
    1125
    \n-
    1126 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1127 std::cout<<"Creating grah one 1 process took "<<time.elapsed()<<std::endl;
    \n-
    1128 time.reset();
    \n-
    1129#if METIS_VER_MAJOR >= 5
    \n-
    1130 Metis::idx_t ncon = 1;
    \n-
    1131 Metis::idx_t moptions[METIS_NOPTIONS];
    \n-
    1132 METIS_SetDefaultOptions(moptions);
    \n-
    1133 moptions[METIS_OPTION_NUMBERING] = numflag;
    \n-
    1134 METIS_PartGraphRecursive(&noVertices, &ncon, gxadj, gadjncy, gvwgt, NULL, gadjwgt,
    \n-
    1135 &nparts, NULL, NULL, moptions, &edgecut, gpart);
    \n-
    1136#else
    \n-
    1137 int options[5] = {0, 1, 1, 3, 3};
    \n-
    1138 // Call metis
    \n-
    1139 METIS_PartGraphRecursive(&noVertices, gxadj, gadjncy, gvwgt, gadjwgt, &wgtflag,
    \n-
    1140 &numflag, &nparts, options, &edgecut, gpart);
    \n-
    1141#endif
    \n-
    1142
    \n-
    1143 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1144 std::cout<<"METIS took "<<time.elapsed()<<std::endl;
    \n-
    1145 time.reset();
    \n-
    1146
    \n-
    1147 Dune::dinfo<<std::endl<<"part:";
    \n-
    1148 print_carray(Dune::dinfo, gpart, noVertices);
    \n-
    1149
    \n-
    1150 delete[] gxadj;
    \n-
    1151 delete[] gadjncy;
    \n-
    1152#ifdef USE_WEIGHTS
    \n-
    1153 delete[] gvwgt;
    \n-
    1154 delete[] gadjwgt;
    \n-
    1155#endif
    \n-
    1156 }
    \n-
    1157 // Scatter result
    \n-
    1158 MPI_Scatter(gpart, 1, MPITraits<Metis::idx_t>::getType(), part, 1,
    \n-
    1159 MPITraits<Metis::idx_t>::getType(), 0, comm);
    \n-
    1160
    \n-
    1161 {
    \n-
    1162 // release remaining memory
    \n-
    1163 delete[] gpart;
    \n-
    1164 delete[] noedges;
    \n-
    1165 delete[] displ;
    \n-
    1166 }
    \n-
    1167
    \n-
    1168
    \n-
    1169#endif
    \n-
    1170 delete[] xadj;
    \n-
    1171 delete[] vtxdist;
    \n-
    1172 delete[] adjncy;
    \n-
    1173#ifdef USE_WEIGHTS
    \n-
    1174 delete[] vwgt;
    \n-
    1175 delete[] adjwgt;
    \n-
    1176#endif
    \n-
    1177 delete[] tpwgts;
    \n-
    1178 }
    \n-
    1179 }else{
    \n-
    1180 part[0]=0;
    \n-
    1181 }
    \n-
    1182#endif
    \n-
    1183 Dune::dinfo<<" repart "<<rank <<" -> "<< part[0]<<std::endl;
    \n-
    1184
    \n-
    1185 std::vector<int> realpart(mat.N(), part[0]);
    \n-
    1186 delete[] part;
    \n-
    1187
    \n-
    1188 oocomm.copyOwnerToAll(realpart, realpart);
    \n-
    1189
    \n-
    1190 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1191 std::cout<<"Scattering repartitioning took "<<time.elapsed()<<std::endl;
    \n-
    1192 time.reset();
    \n-
    1193
    \n-
    1194
    \n-
    1195 oocomm.buildGlobalLookup(mat.N());
    \n-
    1196 Dune::Amg::MatrixGraph<M> graph(const_cast<M&>(mat));
    \n-
    1197 fillIndexSetHoles(graph, oocomm);
    \n-
    1198 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1199 std::cout<<"Filling index set took "<<time.elapsed()<<std::endl;
    \n-
    1200 time.reset();
    \n-
    1201
    \n-
    1202 if(verbose) {
    \n-
    1203 int noNeighbours=oocomm.remoteIndices().neighbours();
    \n-
    1204 noNeighbours = oocomm.communicator().sum(noNeighbours)
    \n-
    1205 / oocomm.communicator().size();
    \n-
    1206 if(oocomm.communicator().rank()==0)
    \n-
    1207 std::cout<<"Average no neighbours was "<<noNeighbours<<std::endl;
    \n-
    1208 }
    \n-
    1209 bool ret = buildCommunication(graph, realpart, oocomm, outcomm, redistInf,
    \n-
    1210 verbose);
    \n-
    1211 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1212 std::cout<<"Building index sets took "<<time.elapsed()<<std::endl;
    \n-
    1213 time.reset();
    \n-
    1214
    \n-
    1215
    \n-
    1216 return ret;
    \n-
    1217
    \n-
    1218 }
    \n-
    1219
    \n-
    1234 template<class G, class T1, class T2>
    \n-\n-
    1236 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n-
    1237 RedistributeInterface& redistInf,
    \n-
    1238 bool verbose=false)
    \n-
    1239 {
    \n-
    1240 Timer time;
    \n-
    1241
    \n-
    1242 MPI_Comm comm=oocomm.communicator();
    \n-
    1243 oocomm.buildGlobalLookup(graph.noVertices());
    \n-
    1244 fillIndexSetHoles(graph, oocomm);
    \n-
    1245
    \n-
    1246 if(verbose && oocomm.communicator().rank()==0)
    \n-
    1247 std::cout<<"Filling holes took "<<time.elapsed()<<std::endl;
    \n-
    1248 time.reset();
    \n-
    1249
    \n-
    1250 // simple precondition checks
    \n-
    1251
    \n-
    1252#ifdef PERF_REPART
    \n-
    1253 // Profiling variables
    \n-
    1254 double t1=0.0, t2=0.0, t3=0.0, t4=0.0, tSum=0.0;
    \n-
    1255#endif
    \n-
    1256
    \n-
    1257
    \n-
    1258 // MPI variables
    \n-
    1259 int mype = oocomm.communicator().rank();
    \n-
    1260
    \n-
    1261 assert(nparts<=static_cast<Metis::idx_t>(oocomm.communicator().size()));
    \n-
    1262
    \n-
    1263 int myDomain = -1;
    \n-
    1264
    \n-
    1265 //
    \n-
    1266 // 1) Prepare the required parameters for using ParMETIS
    \n-
    1267 // Especially the arrays that represent the graph must be
    \n-
    1268 // generated by the DUNE Graph and IndexSet input variables.
    \n-
    1269 // These are the arrays:
    \n-
    1270 // - vtxdist
    \n-
    1271 // - xadj
    \n-
    1272 // - adjncy
    \n-
    1273 //
    \n-
    1274 //
    \n-
    1275#ifdef PERF_REPART
    \n-
    1276 // reset timer for step 1)
    \n-
    1277 t1=MPI_Wtime();
    \n-
    1278#endif
    \n-
    1279
    \n-
    1280
    \n-
    1281 typedef typename Dune::OwnerOverlapCopyCommunication<T1,T2> OOComm;
    \n-
    1282 typedef typename OOComm::OwnerSet OwnerSet;
    \n-
    1283
    \n-
    1284 // Create the vtxdist array and parmetisVtxMapping.
    \n-
    1285 // Global communications are necessary
    \n-
    1286 // The parmetis global identifiers for the owner vertices.
    \n-
    1287 ParmetisDuneIndexMap indexMap(graph,oocomm);
    \n-
    1288 Metis::idx_t *part = new Metis::idx_t[indexMap.numOfOwnVtx()];
    \n-
    1289 for(std::size_t i=0; i < indexMap.numOfOwnVtx(); ++i)
    \n-
    1290 part[i]=mype;
    \n-
    1291
    \n-
    1292#if !HAVE_PARMETIS
    \n-
    1293 if(oocomm.communicator().rank()==0 && nparts>1)
    \n-
    1294 std::cerr<<"ParMETIS not activated. Will repartition to 1 domain instead of requested "
    \n-
    1295 <<nparts<<" domains."<<std::endl;
    \n-
    1296 nparts=1; // No parmetis available, fallback to agglomerating to 1 process
    \n-
    1297
    \n-
    1298#else
    \n-
    1299
    \n-
    1300 if(nparts>1) {
    \n-
    1301 // Create the xadj and adjncy arrays
    \n-
    1302 Metis::idx_t *xadj = new Metis::idx_t[indexMap.numOfOwnVtx()+1];
    \n-
    1303 Metis::idx_t *adjncy = new Metis::idx_t[graph.noEdges()];
    \n-
    1304 EdgeFunctor<G> ef(adjncy, indexMap, graph.noEdges());
    \n-
    1305 getAdjArrays<OwnerSet>(graph, oocomm.globalLookup(), xadj, ef);
    \n-
    1306
    \n-
    1307 //
    \n-
    1308 // 2) Call ParMETIS
    \n-
    1309 //
    \n-
    1310 //
    \n-
    1311 Metis::idx_t numflag=0, wgtflag=0, options[3], edgecut=0, ncon=1;
    \n-
    1312 //float *tpwgts = NULL;
    \n-
    1313 Metis::real_t *tpwgts = new Metis::real_t[nparts];
    \n-
    1314 for(int i=0; i<nparts; ++i)
    \n-
    1315 tpwgts[i]=1.0/nparts;
    \n-
    1316 Metis::real_t ubvec[1];
    \n-
    1317 options[0] = 0; // 0=default, 1=options are defined in [1]+[2]
    \n-
    1318#ifdef DEBUG_REPART
    \n-
    1319 options[1] = 3; // show info: 0=no message
    \n-
    1320#else
    \n-
    1321 options[1] = 0; // show info: 0=no message
    \n-
    1322#endif
    \n-
    1323 options[2] = 1; // random number seed, default is 15
    \n-
    1324 wgtflag = (ef.getWeights()!=NULL) ? 1 : 0;
    \n-
    1325 numflag = 0;
    \n-
    1326 edgecut = 0;
    \n-
    1327 ncon=1;
    \n-
    1328 ubvec[0]=1.05; // recommended by ParMETIS
    \n-
    1329
    \n-
    1330#ifdef DEBUG_REPART
    \n-
    1331 if (mype == 0) {
    \n-
    1332 std::cout<<std::endl;
    \n-
    1333 std::cout<<"Testing ParMETIS_V3_PartKway with options[1-2] = {"
    \n-
    1334 <<options[1]<<" "<<options[2]<<"}, Ncon: "
    \n-
    1335 <<ncon<<", Nparts: "<<nparts<<std::endl;
    \n-
    1336 }
    \n-
    1337#endif
    \n-
    1338#ifdef PERF_REPART
    \n-
    1339 // stop the time for step 1)
    \n-
    1340 t1=MPI_Wtime()-t1;
    \n-
    1341 // reset timer for step 2)
    \n-
    1342 t2=MPI_Wtime();
    \n-
    1343#endif
    \n-
    1344
    \n-
    1345 if(verbose) {
    \n-
    1346 oocomm.communicator().barrier();
    \n-
    1347 if(oocomm.communicator().rank()==0)
    \n-
    1348 std::cout<<"Preparing for parmetis took "<<time.elapsed()<<std::endl;
    \n-
    1349 }
    \n-
    1350 time.reset();
    \n-
    1351
    \n-
    1352 //=======================================================
    \n-
    1353 // ParMETIS_V3_PartKway
    \n-
    1354 //=======================================================
    \n-
    1355 ParMETIS_V3_PartKway(indexMap.vtxDist(), xadj, adjncy,
    \n-
    1356 NULL, ef.getWeights(), &wgtflag,
    \n-
    1357 &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &const_cast<MPI_Comm&>(comm));
    \n-
    1358
    \n-
    1359
    \n-
    1360 delete[] xadj;
    \n-
    1361 delete[] adjncy;
    \n-
    1362 delete[] tpwgts;
    \n-
    1363
    \n-
    1364 ef.free();
    \n-
    1365
    \n-
    1366#ifdef DEBUG_REPART
    \n-
    1367 if (mype == 0) {
    \n-
    1368 std::cout<<std::endl;
    \n-
    1369 std::cout<<"ParMETIS_V3_PartKway reported a cut of "<<edgecut<<std::endl;
    \n-
    1370 std::cout<<std::endl;
    \n-
    1371 }
    \n-
    1372 std::cout<<mype<<": PARMETIS-Result: ";
    \n-
    1373 for(int i=0; i < indexMap.vtxDist()[mype+1]-indexMap.vtxDist()[mype]; ++i) {
    \n-
    1374 std::cout<<part[i]<<" ";
    \n-
    1375 }
    \n-
    1376 std::cout<<std::endl;
    \n-
    1377 std::cout<<"Testing ParMETIS_V3_PartKway with options[1-2] = {"
    \n-
    1378 <<options[1]<<" "<<options[2]<<"}, Ncon: "
    \n-
    1379 <<ncon<<", Nparts: "<<nparts<<std::endl;
    \n-
    1380#endif
    \n-
    1381#ifdef PERF_REPART
    \n-
    1382 // stop the time for step 2)
    \n-
    1383 t2=MPI_Wtime()-t2;
    \n-
    1384 // reset timer for step 3)
    \n-
    1385 t3=MPI_Wtime();
    \n-
    1386#endif
    \n-
    1387
    \n-
    1388
    \n-
    1389 if(verbose) {
    \n-
    1390 oocomm.communicator().barrier();
    \n-
    1391 if(oocomm.communicator().rank()==0)
    \n-
    1392 std::cout<<"Parmetis took "<<time.elapsed()<<std::endl;
    \n-
    1393 }
    \n-
    1394 time.reset();
    \n-
    1395 }else
    \n-
    1396#endif
    \n-
    1397 {
    \n-
    1398 // Everything goes to process 0!
    \n-
    1399 for(std::size_t i=0; i<indexMap.numOfOwnVtx(); ++i)
    \n-
    1400 part[i]=0;
    \n-
    1401 }
    \n-
    1402
    \n-
    1403
    \n-
    1404 //
    \n-
    1405 // 3) Find a optimal domain based on the ParMETIS repartitioning
    \n-
    1406 // result
    \n-
    1407 //
    \n-
    1408
    \n-
    1409 std::vector<int> domainMapping(nparts);
    \n-
    1410 if(nparts>1)
    \n-
    1411 getDomain(comm, part, indexMap.numOfOwnVtx(), nparts, &myDomain, domainMapping);
    \n-
    1412 else
    \n-
    1413 domainMapping[0]=0;
    \n-
    1414
    \n-
    1415#ifdef DEBUG_REPART
    \n-
    1416 std::cout<<mype<<": myDomain: "<<myDomain<<std::endl;
    \n-
    1417 std::cout<<mype<<": DomainMapping: ";
    \n-
    1418 for(auto j : range(nparts)) {
    \n-
    1419 std::cout<<" do: "<<j<<" pe: "<<domainMapping[j]<<" ";
    \n-
    1420 }
    \n-
    1421 std::cout<<std::endl;
    \n-
    1422#endif
    \n-
    1423
    \n-
    1424 // Make a domain mapping for the indexset and translate
    \n-
    1425 //domain number to real process number
    \n-
    1426 // domainMapping is the one of parmetis, that is without
    \n-
    1427 // the overlap/copy vertices
    \n-
    1428 std::vector<int> setPartition(oocomm.indexSet().size(), -1);
    \n-
    1429
    \n-
    1430 std::size_t i=0; // parmetis index
    \n-
    1431 for(auto index = oocomm.indexSet().begin(); index != oocomm.indexSet().end(); ++index)
    \n-
    1432 if(OwnerSet::contains(index->local().attribute())) {
    \n-
    1433 setPartition[index->local()]=domainMapping[part[i++]];
    \n-
    1434 }
    \n-
    1435
    \n-
    1436 delete[] part;
    \n-
    1437 oocomm.copyOwnerToAll(setPartition, setPartition);
    \n-
    1438 // communication only needed for ALU
    \n-
    1439 // (ghosts with same global id as owners on the same process)
    \n-
    1440 if (SolverCategory::category(oocomm) ==
    \n-
    1441 static_cast<int>(SolverCategory::nonoverlapping))
    \n-
    1442 oocomm.copyCopyToAll(setPartition, setPartition);
    \n-
    1443 bool ret = buildCommunication(graph, setPartition, oocomm, outcomm, redistInf,
    \n-
    1444 verbose);
    \n-
    1445 if(verbose) {
    \n-
    1446 oocomm.communicator().barrier();
    \n-
    1447 if(oocomm.communicator().rank()==0)
    \n-
    1448 std::cout<<"Creating indexsets took "<<time.elapsed()<<std::endl;
    \n-
    1449 }
    \n-
    1450 return ret;
    \n-
    1451 }
    \n-
    1452
    \n-
    1453
    \n-
    1454
    \n-
    1455 template<class G, class T1, class T2>
    \n-
    1456 bool buildCommunication(const G& graph,
    \n-
    1457 std::vector<int>& setPartition, Dune::OwnerOverlapCopyCommunication<T1,T2>& oocomm,
    \n-
    1458 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n-
    1459 RedistributeInterface& redistInf,
    \n-
    1460 bool verbose)
    \n-
    1461 {
    \n-
    1462 typedef typename Dune::OwnerOverlapCopyCommunication<T1,T2> OOComm;
    \n-
    1463 typedef typename OOComm::OwnerSet OwnerSet;
    \n-
    1464
    \n-
    1465 Timer time;
    \n-
    1466
    \n-
    1467 // Build the send interface
    \n-
    1468 redistInf.buildSendInterface<OwnerSet>(setPartition, oocomm.indexSet());
    \n-
    1469
    \n-
    1470#ifdef PERF_REPART
    \n-
    1471 // stop the time for step 3)
    \n-
    1472 t3=MPI_Wtime()-t3;
    \n-
    1473 // reset timer for step 4)
    \n-
    1474 t4=MPI_Wtime();
    \n-
    1475#endif
    \n-
    1476
    \n-
    1477
    \n-
    1478 //
    \n-
    1479 // 4) Create the output IndexSet and RemoteIndices
    \n-
    1480 // 4.1) Determine the "send to" and "receive from" relation
    \n-
    1481 // according to the new partition using a MPI ring
    \n-
    1482 // communication.
    \n-
    1483 //
    \n-
    1484 // 4.2) Depends on the "send to" and "receive from" vector,
    \n-
    1485 // the processes will exchange the vertices each other
    \n-
    1486 //
    \n-
    1487 // 4.3) Create the IndexSet, RemoteIndices and the new MPI
    \n-
    1488 // communicator
    \n-
    1489 //
    \n-
    1490
    \n-
    1491 //
    \n-
    1492 // 4.1) Let's start...
    \n-
    1493 //
    \n-
    1494 int npes = oocomm.communicator().size();
    \n-
    1495 int *sendTo = 0;
    \n-
    1496 int noSendTo = 0;
    \n-
    1497 std::set<int> recvFrom;
    \n-
    1498
    \n-
    1499 // the max number of vertices is stored in the sendTo buffer,
    \n-
    1500 // not the number of vertices to send! Because the max number of Vtx
    \n-
    1501 // is used as the fixed buffer size by the MPI send/receive calls
    \n-
    1502
    \n-
    1503 int mype = oocomm.communicator().rank();
    \n-
    1504
    \n-
    1505 {
    \n-
    1506 std::set<int> tsendTo;
    \n-
    1507 for(auto i=setPartition.begin(), iend = setPartition.end(); i!=iend; ++i)
    \n-
    1508 tsendTo.insert(*i);
    \n-
    1509
    \n-
    1510 noSendTo = tsendTo.size();
    \n-
    1511 sendTo = new int[noSendTo];
    \n-
    1512 int idx=0;
    \n-
    1513 for(auto i=tsendTo.begin(); i != tsendTo.end(); ++i, ++idx)
    \n-
    1514 sendTo[idx]=*i;
    \n-
    1515 }
    \n-
    1516
    \n-
    1517 //
    \n-
    1518 int* gnoSend= new int[oocomm.communicator().size()];
    \n-
    1519 int* gsendToDispl = new int[oocomm.communicator().size()+1];
    \n-
    1520
    \n-
    1521 MPI_Allgather(&noSendTo, 1, MPI_INT, gnoSend, 1,
    \n-
    1522 MPI_INT, oocomm.communicator());
    \n-
    1523
    \n-
    1524 // calculate total receive message size
    \n-
    1525 int totalNoRecv = 0;
    \n-
    1526 for(int i=0; i<npes; ++i)
    \n-
    1527 totalNoRecv += gnoSend[i];
    \n-
    1528
    \n-
    1529 int *gsendTo = new int[totalNoRecv];
    \n-
    1530
    \n-
    1531 // calculate displacement for allgatherv
    \n-
    1532 gsendToDispl[0]=0;
    \n-
    1533 for(int i=0; i<npes; ++i)
    \n-
    1534 gsendToDispl[i+1]=gsendToDispl[i]+gnoSend[i];
    \n-
    1535
    \n-
    1536 // gather the data
    \n-
    1537 MPI_Allgatherv(sendTo, noSendTo, MPI_INT, gsendTo, gnoSend, gsendToDispl,
    \n-
    1538 MPI_INT, oocomm.communicator());
    \n-
    1539
    \n-
    1540 // Extract from which processes we will receive data
    \n-
    1541 for(int proc=0; proc < npes; ++proc)
    \n-
    1542 for(int i=gsendToDispl[proc]; i < gsendToDispl[proc+1]; ++i)
    \n-
    1543 if(gsendTo[i]==mype)
    \n-
    1544 recvFrom.insert(proc);
    \n-
    1545
    \n-
    1546 bool existentOnNextLevel = recvFrom.size()>0;
    \n-
    1547
    \n-
    1548 // Delete memory
    \n-
    1549 delete[] gnoSend;
    \n-
    1550 delete[] gsendToDispl;
    \n-
    1551 delete[] gsendTo;
    \n-
    1552
    \n-
    1553
    \n-
    1554#ifdef DEBUG_REPART
    \n-
    1555 if(recvFrom.size()) {
    \n-
    1556 std::cout<<mype<<": recvFrom: ";
    \n-
    1557 for(auto i=recvFrom.begin(); i!= recvFrom.end(); ++i) {
    \n-
    1558 std::cout<<*i<<" ";
    \n-
    1559 }
    \n-
    1560 }
    \n-
    1561
    \n-
    1562 std::cout<<std::endl<<std::endl;
    \n-
    1563 std::cout<<mype<<": sendTo: ";
    \n-
    1564 for(int i=0; i<noSendTo; i++) {
    \n-
    1565 std::cout<<sendTo[i]<<" ";
    \n-
    1566 }
    \n-
    1567 std::cout<<std::endl<<std::endl;
    \n-
    1568#endif
    \n-
    1569
    \n-
    1570 if(verbose)
    \n-
    1571 if(oocomm.communicator().rank()==0)
    \n-
    1572 std::cout<<" Communicating the receive information took "<<
    \n-
    1573 time.elapsed()<<std::endl;
    \n-
    1574 time.reset();
    \n-
    1575
    \n-
    1576 //
    \n-
    1577 // 4.2) Start the communication
    \n-
    1578 //
    \n-
    1579
    \n-
    1580 // Get all the owner and overlap vertices for myself ans save
    \n-
    1581 // it in the vectors myOwnerVec and myOverlapVec.
    \n-
    1582 // The received vertices from the other processes are simple
    \n-
    1583 // added to these vector.
    \n-
    1584 //
    \n-
    1585
    \n-
    1586
    \n-
    1587 typedef typename OOComm::ParallelIndexSet::GlobalIndex GI;
    \n-
    1588 typedef std::vector<GI> GlobalVector;
    \n-
    1589 std::vector<std::pair<GI,int> > myOwnerVec;
    \n-
    1590 std::set<GI> myOverlapSet;
    \n-
    1591 GlobalVector sendOwnerVec;
    \n-
    1592 std::set<GI> sendOverlapSet;
    \n-
    1593 std::set<int> myNeighbors;
    \n-
    1594
    \n-
    1595 // getOwnerOverlapVec<OwnerSet>(graph, setPartition, oocomm.globalLookup(),
    \n-
    1596 // mype, mype, myOwnerVec, myOverlapSet, redistInf, myNeighbors);
    \n-
    1597
    \n-
    1598 char **sendBuffers=new char*[noSendTo];
    \n-
    1599 MPI_Request *requests = new MPI_Request[noSendTo];
    \n-
    1600
    \n-
    1601 // Create all messages to be sent
    \n-
    1602 for(int i=0; i < noSendTo; ++i) {
    \n-
    1603 // clear the vector for sending
    \n-
    1604 sendOwnerVec.clear();
    \n-
    1605 sendOverlapSet.clear();
    \n-
    1606 // get all owner and overlap vertices for process j and save these
    \n-
    1607 // in the vectors sendOwnerVec and sendOverlapSet
    \n-
    1608 std::set<int> neighbors;
    \n-
    1609 getOwnerOverlapVec<OwnerSet>(graph, setPartition, oocomm.globalLookup(),
    \n-
    1610 mype, sendTo[i], sendOwnerVec, sendOverlapSet, redistInf,
    \n-
    1611 neighbors);
    \n-
    1612 // +2, we need 2 integer more for the length of each part
    \n-
    1613 // (owner/overlap) of the array
    \n-
    1614 int buffersize=0;
    \n-
    1615 int tsize;
    \n-
    1616 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &buffersize);
    \n-
    1617 MPI_Pack_size(sendOwnerVec.size(), MPITraits<GI>::getType(), oocomm.communicator(), &tsize);
    \n-
    1618 buffersize +=tsize;
    \n-
    1619 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &tsize);
    \n-
    1620 buffersize +=tsize;
    \n-
    1621 MPI_Pack_size(sendOverlapSet.size(), MPITraits<GI>::getType(), oocomm.communicator(), &tsize);
    \n-
    1622 buffersize += tsize;
    \n-
    1623 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &tsize);
    \n-
    1624 buffersize += tsize;
    \n-
    1625 MPI_Pack_size(neighbors.size(), MPI_INT, oocomm.communicator(), &tsize);
    \n-
    1626 buffersize += tsize;
    \n-
    1627
    \n-
    1628 sendBuffers[i] = new char[buffersize];
    \n-
    1629
    \n-
    1630#ifdef DEBUG_REPART
    \n-
    1631 std::cout<<mype<<" sending "<<sendOwnerVec.size()<<" owner and "<<
    \n-
    1632 sendOverlapSet.size()<<" overlap to "<<sendTo[i]<<" buffersize="<<buffersize<<std::endl;
    \n-
    1633#endif
    \n-
    1634 createSendBuf(sendOwnerVec, sendOverlapSet, neighbors, sendBuffers[i], buffersize, oocomm.communicator());
    \n-
    1635 MPI_Issend(sendBuffers[i], buffersize, MPI_PACKED, sendTo[i], 99, oocomm.communicator(), requests+i);
    \n-
    1636 }
    \n-
    1637
    \n-
    1638 if(verbose) {
    \n-
    1639 oocomm.communicator().barrier();
    \n-
    1640 if(oocomm.communicator().rank()==0)
    \n-
    1641 std::cout<<" Creating sends took "<<
    \n-
    1642 time.elapsed()<<std::endl;
    \n-
    1643 }
    \n-
    1644 time.reset();
    \n-
    1645
    \n-
    1646 // Receive Messages
    \n-
    1647 int noRecv = recvFrom.size();
    \n-
    1648 int oldbuffersize=0;
    \n-
    1649 char* recvBuf = 0;
    \n-
    1650 while(noRecv>0) {
    \n-
    1651 // probe for an incoming message
    \n-
    1652 MPI_Status stat;
    \n-
    1653 MPI_Probe(MPI_ANY_SOURCE, 99, oocomm.communicator(), &stat);
    \n-
    1654 int buffersize;
    \n-
    1655 MPI_Get_count(&stat, MPI_PACKED, &buffersize);
    \n-
    1656
    \n-
    1657 if(oldbuffersize<buffersize) {
    \n-
    1658 // buffer too small, reallocate
    \n-
    1659 delete[] recvBuf;
    \n-
    1660 recvBuf = new char[buffersize];
    \n-
    1661 oldbuffersize = buffersize;
    \n-
    1662 }
    \n-
    1663 MPI_Recv(recvBuf, buffersize, MPI_PACKED, stat.MPI_SOURCE, 99, oocomm.communicator(), &stat);
    \n-
    1664 saveRecvBuf(recvBuf, buffersize, myOwnerVec, myOverlapSet, myNeighbors, redistInf,
    \n-
    1665 stat.MPI_SOURCE, oocomm.communicator());
    \n-
    1666 --noRecv;
    \n-
    1667 }
    \n-
    1668
    \n-
    1669 if(recvBuf)
    \n-
    1670 delete[] recvBuf;
    \n-
    1671
    \n-
    1672 time.reset();
    \n-
    1673 // Wait for sending messages to complete
    \n-
    1674 MPI_Status *statuses = new MPI_Status[noSendTo];
    \n-
    1675 int send = MPI_Waitall(noSendTo, requests, statuses);
    \n-
    1676
    \n-
    1677 // check for errors
    \n-
    1678 if(send==MPI_ERR_IN_STATUS) {
    \n-
    1679 std::cerr<<mype<<": Error in sending :"<<std::endl;
    \n-
    1680 // Search for the error
    \n-
    1681 for(int i=0; i< noSendTo; i++)
    \n-
    1682 if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
    \n-
    1683 char message[300];
    \n-
    1684 int messageLength;
    \n-
    1685 MPI_Error_string(statuses[i].MPI_ERROR, message, &messageLength);
    \n-
    1686 std::cerr<<" source="<<statuses[i].MPI_SOURCE<<" message: ";
    \n-
    1687 for(int j = 0; j < messageLength; j++)
    \n-
    1688 std::cout<<message[j];
    \n-
    1689 }
    \n-
    1690 std::cerr<<std::endl;
    \n-
    1691 }
    \n-
    1692
    \n-
    1693 if(verbose) {
    \n-
    1694 oocomm.communicator().barrier();
    \n-
    1695 if(oocomm.communicator().rank()==0)
    \n-
    1696 std::cout<<" Receiving and saving took "<<
    \n-
    1697 time.elapsed()<<std::endl;
    \n-
    1698 }
    \n-
    1699 time.reset();
    \n-
    1700
    \n-
    1701 for(int i=0; i < noSendTo; ++i)
    \n-
    1702 delete[] sendBuffers[i];
    \n-
    1703
    \n-
    1704 delete[] sendBuffers;
    \n-
    1705 delete[] statuses;
    \n-
    1706 delete[] requests;
    \n-
    1707
    \n-
    1708 redistInf.setCommunicator(oocomm.communicator());
    \n-
    1709
    \n-
    1710 //
    \n-
    1711 // 4.2) Create the IndexSet etc.
    \n-
    1712 //
    \n-
    1713
    \n-
    1714 // build the new outputIndexSet
    \n-
    1715
    \n-
    1716
    \n-
    1717 int color=0;
    \n-
    1718
    \n-
    1719 if (!existentOnNextLevel) {
    \n-
    1720 // this process is not used anymore
    \n-
    1721 color= MPI_UNDEFINED;
    \n-
    1722 }
    \n-
    1723 MPI_Comm outputComm;
    \n-
    1724
    \n-
    1725 MPI_Comm_split(oocomm.communicator(), color, oocomm.communicator().rank(), &outputComm);
    \n-
    1726 outcomm = std::make_shared<OOComm>(outputComm,SolverCategory::category(oocomm),true);
    \n-
    1727
    \n-
    1728 // translate neighbor ranks.
    \n-
    1729 int newrank=outcomm->communicator().rank();
    \n-
    1730 int *newranks=new int[oocomm.communicator().size()];
    \n-
    1731 std::vector<int> tneighbors;
    \n-
    1732 tneighbors.reserve(myNeighbors.size());
    \n-
    1733
    \n-
    1734 typename OOComm::ParallelIndexSet& outputIndexSet = outcomm->indexSet();
    \n-
    1735
    \n-
    1736 MPI_Allgather(&newrank, 1, MPI_INT, newranks, 1,
    \n-
    1737 MPI_INT, oocomm.communicator());
    \n-
    1738
    \n-
    1739#ifdef DEBUG_REPART
    \n-
    1740 std::cout<<oocomm.communicator().rank()<<" ";
    \n-
    1741 for(auto i=myNeighbors.begin(), end=myNeighbors.end();
    \n-
    1742 i!=end; ++i) {
    \n-
    1743 assert(newranks[*i]>=0);
    \n-
    1744 std::cout<<*i<<"->"<<newranks[*i]<<" ";
    \n-
    1745 tneighbors.push_back(newranks[*i]);
    \n-
    1746 }
    \n-
    1747 std::cout<<std::endl;
    \n-
    1748#else
    \n-
    1749 for(auto i=myNeighbors.begin(), end=myNeighbors.end();
    \n-
    1750 i!=end; ++i) {
    \n-
    1751 tneighbors.push_back(newranks[*i]);
    \n-
    1752 }
    \n-
    1753#endif
    \n-
    1754 delete[] newranks;
    \n-
    1755 myNeighbors.clear();
    \n-
    1756
    \n-
    1757 if(verbose) {
    \n-
    1758 oocomm.communicator().barrier();
    \n-
    1759 if(oocomm.communicator().rank()==0)
    \n-
    1760 std::cout<<" Calculating new neighbours ("<<tneighbors.size()<<") took "<<
    \n-
    1761 time.elapsed()<<std::endl;
    \n-
    1762 }
    \n-
    1763 time.reset();
    \n-
    1764
    \n-
    1765
    \n-
    1766 outputIndexSet.beginResize();
    \n-
    1767 // 1) add the owner vertices
    \n-
    1768 // Sort the owners
    \n-
    1769 std::sort(myOwnerVec.begin(), myOwnerVec.end(), SortFirst());
    \n-
    1770 // The owners are sorted according to there global index
    \n-
    1771 // Therefore the entries of ownerVec are the same as the
    \n-
    1772 // ones in the resulting index set.
    \n-
    1773 int i=0;
    \n-
    1774 using LocalIndexT = typename OOComm::ParallelIndexSet::LocalIndex;
    \n-
    1775 for(auto g=myOwnerVec.begin(), end =myOwnerVec.end(); g!=end; ++g, ++i ) {
    \n-
    1776 outputIndexSet.add(g->first,LocalIndexT(i, OwnerOverlapCopyAttributeSet::owner, true));
    \n-
    1777 redistInf.addReceiveIndex(g->second, i);
    \n-
    1778 }
    \n-
    1779
    \n-
    1780 if(verbose) {
    \n-
    1781 oocomm.communicator().barrier();
    \n-
    1782 if(oocomm.communicator().rank()==0)
    \n-
    1783 std::cout<<" Adding owner indices took "<<
    \n-
    1784 time.elapsed()<<std::endl;
    \n-
    1785 }
    \n-
    1786 time.reset();
    \n-
    1787
    \n-
    1788
    \n-
    1789 // After all the vertices are received, the vectors must
    \n-
    1790 // be "merged" together to create the final vectors.
    \n-
    1791 // Because some vertices that are sent as overlap could now
    \n-
    1792 // already included as owner vertiecs in the new partition
    \n-
    1793 mergeVec(myOwnerVec, myOverlapSet);
    \n-
    1794
    \n-
    1795 // Trick to free memory
    \n-
    1796 myOwnerVec.clear();
    \n-
    1797 myOwnerVec.swap(myOwnerVec);
    \n-
    1798
    \n-
    1799 if(verbose) {
    \n-
    1800 oocomm.communicator().barrier();
    \n-
    1801 if(oocomm.communicator().rank()==0)
    \n-
    1802 std::cout<<" Merging indices took "<<
    \n-
    1803 time.elapsed()<<std::endl;
    \n-
    1804 }
    \n-
    1805 time.reset();
    \n-
    1806
    \n-
    1807
    \n-
    1808 // 2) add the overlap vertices
    \n-
    1809 for(auto g=myOverlapSet.begin(), end=myOverlapSet.end(); g!=end; ++g, i++) {
    \n-
    1810 outputIndexSet.add(*g,LocalIndexT(i, OwnerOverlapCopyAttributeSet::copy, true));
    \n-
    1811 }
    \n-
    1812 myOverlapSet.clear();
    \n-
    1813 outputIndexSet.endResize();
    \n-
    1814
    \n-
    1815#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1816 int numOfOwnVtx =0;
    \n-
    1817 auto end = outputIndexSet.end();
    \n-
    1818 for(auto index = outputIndexSet.begin(); index != end; ++index) {
    \n-
    1819 if (OwnerSet::contains(index->local().attribute())) {
    \n-
    1820 numOfOwnVtx++;
    \n-
    1821 }
    \n-
    1822 }
    \n-
    1823 numOfOwnVtx = oocomm.communicator().sum(numOfOwnVtx);
    \n-
    1824 // if(numOfOwnVtx!=indexMap.globalOwnerVertices)
    \n-
    1825 // {
    \n-
    1826 // std::cerr<<numOfOwnVtx<<"!="<<indexMap.globalOwnerVertices<<" owners missing or additional ones!"<<std::endl;
    \n-
    1827 // DUNE_THROW(ISTLError, numOfOwnVtx<<"!="<<indexMap.globalOwnerVertices<<" owners missing or additional ones"
    \n-
    1828 // <<" during repartitioning.");
    \n-
    1829 // }
    \n-
    1830 std::is_sorted(outputIndexSet.begin(), outputIndexSet.end(),
    \n-
    1831 [](const auto& v1, const auto& v2){ return v1.global() < v2.global();});
    \n-
    1832#endif
    \n-
    1833 if(verbose) {
    \n-
    1834 oocomm.communicator().barrier();
    \n-
    1835 if(oocomm.communicator().rank()==0)
    \n-
    1836 std::cout<<" Adding overlap indices took "<<
    \n-
    1837 time.elapsed()<<std::endl;
    \n-
    1838 }
    \n-
    1839 time.reset();
    \n-
    1840
    \n-
    1841
    \n-
    1842 if(color != MPI_UNDEFINED) {
    \n-
    1843 outcomm->remoteIndices().setNeighbours(tneighbors);
    \n-
    1844 outcomm->remoteIndices().template rebuild<true>();
    \n-
    1845
    \n-
    1846 }
    \n-
    1847
    \n-
    1848 // release the memory
    \n-
    1849 delete[] sendTo;
    \n-
    1850
    \n-
    1851 if(verbose) {
    \n-
    1852 oocomm.communicator().barrier();
    \n-
    1853 if(oocomm.communicator().rank()==0)
    \n-
    1854 std::cout<<" Storing indexsets took "<<
    \n-
    1855 time.elapsed()<<std::endl;
    \n-
    1856 }
    \n-
    1857
    \n-
    1858#ifdef PERF_REPART
    \n-
    1859 // stop the time for step 4) and print the results
    \n-
    1860 t4=MPI_Wtime()-t4;
    \n-
    1861 tSum = t1 + t2 + t3 + t4;
    \n-
    1862 std::cout<<std::endl
    \n-
    1863 <<mype<<": WTime for step 1): "<<t1
    \n-
    1864 <<" 2): "<<t2
    \n-
    1865 <<" 3): "<<t3
    \n-
    1866 <<" 4): "<<t4
    \n-
    1867 <<" total: "<<tSum
    \n-
    1868 <<std::endl;
    \n-
    1869#endif
    \n-
    1870
    \n-
    1871 return color!=MPI_UNDEFINED;
    \n-
    1872
    \n-
    1873 }
    \n-
    1874#else
    \n-
    1875 template<class G, class P,class T1, class T2, class R>
    \n-
    1876 bool graphRepartition(const G& graph, P& oocomm, int nparts,
    \n-
    1877 std::shared_ptr<P>& outcomm,
    \n-
    1878 R& redistInf,
    \n-
    1879 bool v=false)
    \n-
    1880 {
    \n-
    1881 if(nparts!=oocomm.size())
    \n-
    1882 DUNE_THROW(NotImplemented, "only available for MPI programs");
    \n-
    1883 }
    \n-
    1884
    \n-
    1885
    \n-
    1886 template<class G, class P,class T1, class T2, class R>
    \n-
    1887 bool commGraphRepartition(const G& graph, P& oocomm, int nparts,
    \n-
    1888 std::shared_ptr<P>& outcomm,
    \n-
    1889 R& redistInf,
    \n-
    1890 bool v=false)
    \n-
    1891 {
    \n-
    1892 if(nparts!=oocomm.size())
    \n-
    1893 DUNE_THROW(NotImplemented, "only available for MPI programs");
    \n-
    1894 }
    \n-
    1895#endif // HAVE_MPI
    \n-
    1896} // end of namespace Dune
    \n-
    1897#endif
    \n-
    int globalOwnerVertices
    Definition: repartition.hh:175
    \n-
    Provides classes for building the matrix graph.
    \n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    215#endif
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    Helper functions for determining the vector/matrix block level.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n
    Definition: allocator.hh:11
    \n-
    bool buildCommunication(const G &graph, std::vector< int > &realparts, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:1456
    \n-
    void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
    Fills the holes in an index set.
    Definition: repartition.hh:83
    \n-
    bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:829
    \n-
    void print_carray(S &os, T *array, std::size_t l)
    Definition: repartition.hh:778
    \n-
    bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T *adjncy, bool checkSymmetry)
    Definition: repartition.hh:785
    \n-
    bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    execute a graph repartition for a giving graph and indexset.
    Definition: repartition.hh:1235
    \n-
    float real_t
    Definition: repartition.hh:53
    \n-
    std::size_t idx_t
    Definition: repartition.hh:63
    \n-
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    const GlobalLookupIndexSet & globalLookup() const
    Definition: owneroverlapcopy.hh:526
    \n-
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n-
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n-
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n-
    void buildGlobalLookup()
    Definition: owneroverlapcopy.hh:495
    \n-
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n-
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n-
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n-
    void freeGlobalLookup()
    Definition: owneroverlapcopy.hh:520
    \n-
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n-
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n-
    Definition: repartition.hh:260
    \n-
    void reserveSpaceForReceiveInterface(int proc, int size)
    Definition: repartition.hh:284
    \n-
    void buildReceiveInterface(std::vector< std::pair< TG, int > > &indices)
    Definition: repartition.hh:293
    \n-
    ~RedistributeInterface()
    Definition: repartition.hh:301
    \n-
    void setCommunicator(MPI_Comm comm)
    Definition: repartition.hh:261
    \n-
    void buildSendInterface(const std::vector< int > &toPart, const IS &idxset)
    Definition: repartition.hh:266
    \n-
    void addReceiveIndex(int proc, std::size_t idx)
    Definition: repartition.hh:288
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    void endrowsizes()
    indicate that size of all rows is defined
    Definition: bcrsmatrix.hh:1149
    \n+
    @ random
    Build entries randomly.
    Definition: bcrsmatrix.hh:530
    \n+
    void addindex(size_type row, size_type col)
    add index (row,col) to the matrix
    Definition: bcrsmatrix.hh:1191
    \n+
    void endindices()
    indicate that all indices are defined, check consistency
    Definition: bcrsmatrix.hh:1248
    \n+
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n+
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n+
    BCRSMatrix & operator=(const BCRSMatrix &Mat)
    assignment
    Definition: bcrsmatrix.hh:911
    \n+
    A block-tridiagonal matrix.
    Definition: btdmatrix.hh:31
    \n+
    static constexpr auto blocklevel
    increment block level counter
    Definition: btdmatrix.hh:53
    \n+
    BTDMatrix(size_type size)
    Definition: btdmatrix.hh:58
    \n+
    void solve(V &x, const V &rhs) const
    Use the Thomas algorithm to solve the system Ax=b in O(n) time.
    Definition: btdmatrix.hh:125
    \n+
    A::size_type size_type
    implement row_type with compressed vector
    Definition: btdmatrix.hh:49
    \n+
    A allocator_type
    export the allocator type
    Definition: btdmatrix.hh:43
    \n+
    B block_type
    export the type representing the components
    Definition: btdmatrix.hh:40
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: btdmatrix.hh:37
    \n+
    BTDMatrix & operator=(const BTDMatrix &other)
    assignment
    Definition: btdmatrix.hh:108
    \n+
    BTDMatrix()
    Default constructor.
    Definition: btdmatrix.hh:56
    \n+
    void setSize(size_type size)
    Resize the matrix. Invalidates the content!
    Definition: btdmatrix.hh:81
    \n+
    typename FieldTraits< field_type >::real_type real_type
    Definition: btdmatrix.hh:208
    \n+
    typename BTDMatrix< B, A >::field_type field_type
    Definition: btdmatrix.hh:207
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1994 +4,290 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-repartition.hh\n+btdmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_REPARTITION_HH\n- 6#define DUNE_ISTL_REPARTITION_HH\n+ 5#ifndef DUNE_ISTL_BTDMATRIX_HH\n+ 6#define DUNE_ISTL_BTDMATRIX_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12\n- 13#if HAVE_PARMETIS\n- 14// Explicitly use C linkage as scotch does not extern \"C\" in its headers.\n- 15// Works because ParMETIS/METIS checks whether compiler is C++ and otherwise\n- 16// does not use extern \"C\". Therfore no nested extern \"C\" will be created\n- 17extern \"C\"\n- 18{\n- 19#include \n- 20}\n- 21#endif\n- 22\n- 23#include \n- 24#include \n- 25#include \n- 26#include \n- 27#include \n- 28#include \n- 29#include \n- 30#include \n- 31#include \n- 32\n- 33#include \n- 34#include \n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 19namespace Dune {\n+ 29 template >\n+30 class BTDMatrix : public BCRSMatrix\n+ 31 {\n+ 32 public:\n+ 33\n+ 34 //===== type definitions and constants\n 35\n- 44namespace Dune\n- 45{\n-46 namespace Metis\n- 47 {\n- 48 // Explicitly specify a real_t and idx_t for older (Par)METIS versions that\n-do not\n- 49 // provide these typedefs\n- 50#if HAVE_PARMETIS && defined(REALTYPEWIDTH)\n- 51 using real_t = ::real_t;\n- 52#else\n-53 using real_t = float;\n- 54#endif\n- 55\n- 56#if HAVE_PARMETIS && defined(IDXTYPEWIDTH)\n- 57 using idx_t = ::idx_t;\n- 58#elif HAVE_PARMETIS && defined(HAVE_SCOTCH_NUM_TYPE)\n- 59 using idx_t = SCOTCH_Num;\n- 60#elif HAVE_PARMETIS\n- 61 using idx_t = int;\n- 62#else\n-63 using idx_t = std::size_t;\n- 64#endif\n- 65 }\n- 66\n+37 using field_type = typename Imp::BlockTraits::field_type;\n+ 38\n+40 typedef B block_type;\n+ 41\n+43 typedef A allocator_type;\n+ 44\n+ 46 //typedef BCRSMatrix::row_type row_type;\n+ 47\n+49 typedef typename A::size_type size_type;\n+ 50\n+ 52 [[deprecated(\"Use free blockLevel function. Will be removed after 2.8.\")]]\n+53 static constexpr auto blocklevel = blockLevel()+1;\n+ 54\n+56 BTDMatrix() : BCRSMatrix() {}\n+ 57\n+58 explicit BTDMatrix(size_type size)\n+ 59 : BCRSMatrix(size, size, BCRSMatrix::random)\n+ 60 {\n+ 61 // Set number of entries for each row\n+ 62 // All rows get three entries, except for the first and the last one\n+ 63 for (size_t i=0; iBCRSMatrix::setrowsize(i, 3 - (i==0) - (i==(size-1)));\n+ 65\n+ 66 this->BCRSMatrix::endrowsizes();\n 67\n- 68#if HAVE_MPI\n- 82 template\n-83 void fillIndexSetHoles(const G& graph, Dune::\n-OwnerOverlapCopyCommunication& oocomm)\n- 84 {\n- 85 typedef typename Dune::OwnerOverlapCopyCommunication::\n-ParallelIndexSet IndexSet;\n- 86 typedef typename IndexSet::LocalIndex::Attribute Attribute;\n+ 68 // The actual entries for each row\n+ 69 for (size_t i=0; i0)\n+ 71 this->BCRSMatrix::addindex(i, i-1);\n+ 72 this->BCRSMatrix::addindex(i, i );\n+ 73 if (iBCRSMatrix::addindex(i, i+1);\n+ 75 }\n+ 76\n+ 77 this->BCRSMatrix::endindices();\n+ 78 }\n+ 79\n+81 void setSize(size_type size)\n+ 82 {\n+ 83 auto nonZeros = (size==0) ? 0 : size + 2*(size-1);\n+ 84 this->BCRSMatrix::setSize(size, // rows\n+ 85 size, // columns\n+ 86 nonZeros);\n 87\n- 88 IndexSet& indexSet = oocomm.indexSet();\n- 89 const typename Dune::OwnerOverlapCopyCommunication::\n-GlobalLookupIndexSet& lookup =oocomm.globalLookup();\n- 90\n- 91 std::size_t sum=0, needed = graph.noVertices()-indexSet.size();\n- 92 std::vector neededall(oocomm.communicator().size(), 0);\n- 93\n- 94 MPI_Allgather(&needed, 1, MPITraits::getType() , &(neededall\n-[0]), 1, MPITraits::getType(), oocomm.communicator());\n- 95 for(int i=0; iglobal());\n- 107\n- 108 //Process p creates global indices consecutively\n- 109 //starting atmaxgi+\\sum_{i=1}^p neededall[i]\n- 110 // All created indices are owned by the process\n- 111 maxgi=oocomm.communicator().max(maxgi);\n- 112 ++maxgi; //Sart with the next free index.\n- 113\n- 114 for(int i=0; i > > globalIndices;\n- 119 storeGlobalIndicesOfRemoteIndices(globalIndices, oocomm.remoteIndices());\n- 120 indexSet.beginResize();\n- 121\n- 122 for(auto vertex = graph.begin(), vend=graph.end(); vertex != vend;\n-++vertex) {\n- 123 const typename IndexSet::IndexPair* pair=lookup.pair(*vertex);\n- 124 if(pair==0) {\n- 125 // No index yet, add new one\n- 126 indexSet.add(maxgi, typename IndexSet::LocalIndex(*vertex,\n-OwnerOverlapCopyAttributeSet::owner, false));\n- 127 ++maxgi;\n- 128 }\n- 129 }\n- 130\n- 131 indexSet.endResize();\n- 132\n- 133 repairLocalIndexPointers(globalIndices, oocomm.remoteIndices(), indexSet);\n+ 88 // Set number of entries for each row\n+ 89 // All rows get three entries, except for the first and the last one\n+ 90 for (size_t i=0; iBCRSMatrix::setrowsize(i, 3 - (i==0) - (i==(size-1)));\n+ 92\n+ 93 this->BCRSMatrix::endrowsizes();\n+ 94\n+ 95 // The actual entries for each row\n+ 96 for (size_t i=0; i0)\n+ 98 this->BCRSMatrix::addindex(i, i-1);\n+ 99 this->BCRSMatrix::addindex(i, i );\n+ 100 if (iBCRSMatrix::addindex(i, i+1);\n+ 102 }\n+ 103\n+ 104 this->BCRSMatrix::endindices();\n+ 105 }\n+ 106\n+108 BTDMatrix& operator=(const BTDMatrix& other) {\n+ 109 this->BCRSMatrix::operator=(other);\n+ 110 return *this;\n+ 111 }\n+ 112\n+114 BTDMatrix& operator=(const field_type& k) {\n+ 115 this->BCRSMatrix::operator=(k);\n+ 116 return *this;\n+ 117 }\n+ 118\n+ 124 template \n+125 void solve (V& x, const V& rhs) const {\n+ 126\n+ 127 // special handling for 1x1 matrices. The generic algorithm doesn't work\n+for them\n+ 128 if (this->N()==1) {\n+ 129 auto&& x0 = Impl::asVector(x[0]);\n+ 130 auto&& rhs0 = Impl::asVector(rhs[0]);\n+ 131 Impl::asMatrix((*this)[0][0]).solve(x0, rhs0);\n+ 132 return;\n+ 133 }\n 134\n- 135 oocomm.freeGlobalLookup();\n- 136 oocomm.buildGlobalLookup();\n- 137#ifdef DEBUG_REPART\n- 138 std::cout<<\"Holes are filled!\"<\n- 150 ParmetisDuneIndexMap(const Graph& graph, const OOComm& com);\n- 151 int toParmetis(int i) const\n- 152 {\n- 153 return duneToParmetis[i];\n- 154 }\n- 155 int toLocalParmetis(int i) const\n- 156 {\n- 157 return duneToParmetis[i]-base_;\n- 158 }\n- 159 int operator[](int i) const\n- 160 {\n- 161 return duneToParmetis[i];\n- 162 }\n- 163 int toDune(int i) const\n- 164 {\n- 165 return parmetisToDune[i];\n- 166 }\n- 167 std::vector::size_type numOfOwnVtx() const\n- 168 {\n- 169 return parmetisToDune.size();\n- 170 }\n- 171 Metis::idx_t* vtxDist()\n- 172 {\n- 173 return &vtxDist_[0];\n- 174 }\n-175 int globalOwnerVertices;\n- 176 private:\n- 177 int base_;\n- 178 std::vector duneToParmetis;\n- 179 std::vector parmetisToDune;\n- 180 // range of vertices for processor i: vtxdist[i] to vtxdist[i+1] (parmetis\n-global)\n- 181 std::vector vtxDist_;\n- 182 };\n- 183\n- 184 template\n- 185 ParmetisDuneIndexMap::ParmetisDuneIndexMap(const G& graph, const OOComm&\n-oocomm)\n- 186 : duneToParmetis(graph.noVertices(), -1), vtxDist_(oocomm.communicator\n-().size()+1)\n- 187 {\n- 188 int npes=oocomm.communicator().size(), mype=oocomm.communicator().rank();\n+ 135 // Make copies of the rhs and the right matrix band\n+ 136 V d = rhs;\n+ 137 std::vector c(this->N()-1);\n+ 138 for (size_t i=0; iN()-1; i++)\n+ 139 c[i] = (*this)[i][i+1];\n+ 140\n+ 141 /* Modify the coefficients. */\n+ 142 block_type a_00_inv = (*this)[0][0];\n+ 143 Impl::asMatrix(a_00_inv).invert();\n+ 144\n+ 145 //c[0] /= (*this)[0][0]; /* Division by zero risk. */\n+ 146 block_type tmp = a_00_inv;\n+ 147 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[0]));\n+ 148 c[0] = tmp;\n+ 149\n+ 150 // d = a^{-1} d /* Division by zero would imply a singular matrix. */\n+ 151 auto d_0_tmp = d[0];\n+ 152 auto&& d_0 = Impl::asVector(d[0]);\n+ 153 Impl::asMatrix(a_00_inv).mv(Impl::asVector(d_0_tmp),d_0);\n+ 154\n+ 155 for (unsigned int i = 1; i < this->N(); i++) {\n+ 156\n+ 157 // id = ( a_ii - c_{i-1} a_{i, i-1} ) ^{-1}\n+ 158 block_type tmp;\n+ 159 tmp = (*this)[i][i-1];\n+ 160 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[i-1]));\n+ 161\n+ 162 block_type id = (*this)[i][i];\n+ 163 id -= tmp;\n+ 164 Impl::asMatrix(id).invert(); /* Division by zero risk. */\n+ 165\n+ 166 if (iN() - 1] = d[this->N() - 1];\n+ 179 for (int i = this->N() - 2; i >= 0; i--) {\n+ 180 //x[i] = d[i] - c[i] * x[i + 1];\n+ 181 x[i] = d[i];\n+ 182 auto&& x_i = Impl::asVector(x[i]);\n+ 183 Impl::asMatrix(c[i]).mmv(Impl::asVector(x[i+1]), x_i);\n+ 184 }\n+ 185\n+ 186 }\n+ 187\n+ 188 private:\n 189\n- 190 typedef typename OOComm::OwnerSet OwnerSet;\n- 191\n- 192 int numOfOwnVtx=0;\n- 193 auto end = oocomm.indexSet().end();\n- 194 for(auto index = oocomm.indexSet().begin(); index != end; ++index) {\n- 195 if (OwnerSet::contains(index->local().attribute())) {\n- 196 numOfOwnVtx++;\n- 197 }\n- 198 }\n- 199 parmetisToDune.resize(numOfOwnVtx);\n- 200 std::vector globalNumOfVtx(npes);\n- 201 // make this number available to all processes\n- 202 MPI_Allgather(&numOfOwnVtx, 1, MPI_INT, &(globalNumOfVtx[0]), 1, MPI_INT,\n-oocomm.communicator());\n+ 190 // ///////////////////////////////////////////////////////////////////////\n+/////\n+ 191 // The following methods from the base class should now actually be called\n+ 192 // ///////////////////////////////////////////////////////////////////////\n+/////\n+ 193\n+ 194 // createbegin and createend should be in there, too, but I can't get it\n+to compile\n+ 195 // BCRSMatrix::CreateIterator createbegin () {}\n+ 196 // BCRSMatrix::CreateIterator createend () {}\n+ 197 void setrowsize (size_type i, size_type s) {}\n+ 198 void incrementrowsize (size_type i) {}\n+ 199 void endrowsizes () {}\n+ 200 void addindex (size_type row, size_type col) {}\n+ 201 void endindices () {}\n+ 202 };\n 203\n- 204 int base=0;\n- 205 vtxDist_[0] = 0;\n- 206 for(int i=0; i\n+205 struct FieldTraits< BTDMatrix >\n+ 206 {\n+207 using field_type = typename BTDMatrix::field_type;\n+208 using real_type = typename FieldTraits::real_type;\n+ 209 };\n+ 210\n+ 213} // end namespace Dune\n 214\n- 215#ifdef DEBUG_REPART\n- 216 std::cout << oocomm.communicator().rank()<<\" vtxDist: \";\n- 217 for(int i=0; i<= npes; ++i)\n- 218 std::cout << vtxDist_[i]<<\" \";\n- 219 std::cout<local().attribute())) {\n- 231 // assign and count the index\n- 232 parmetisToDune[base-base_]=index->local();\n- 233 duneToParmetis[index->local()] = base++;\n- 234 }\n- 235 }\n- 236\n- 237 // At this point, every process knows the ParMETIS global index\n- 238 // of it's owner vertices. The next step is to get the\n- 239 // ParMETIS global index of the overlap vertices from the\n- 240 // associated processes. To do this, the Dune::Interface class\n- 241 // is used.\n- 242#ifdef DEBUG_REPART\n- 243 std::cout <\n-266 void buildSendInterface(const std::vector& toPart, const IS& idxset)\n- 267 {\n- 268 std::map sizes;\n- 269\n- 270 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)\n- 271 if(Flags::contains(i->local().attribute()))\n- 272 ++sizes[toPart[i->local()]];\n- 273\n- 274 // Allocate the necessary space\n- 275 for(auto i=sizes.begin(), end=sizes.end(); i!=end; ++i)\n- 276 interfaces()[i->first].first.reserve(i->second);\n- 277\n- 278 //Insert the interface information\n- 279 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)\n- 280 if(Flags::contains(i->local().attribute()))\n- 281 interfaces()[toPart[i->local()]].first.add(i->local());\n- 282 }\n- 283\n-284 void reserveSpaceForReceiveInterface(int proc, int size)\n- 285 {\n- 286 interfaces()[proc].second.reserve(size);\n- 287 }\n-288 void addReceiveIndex(int proc, std::size_t idx)\n- 289 {\n- 290 interfaces()[proc].second.add(idx);\n- 291 }\n- 292 template\n-293 void buildReceiveInterface(std::vector >& indices)\n- 294 {\n- 295 std::size_t i=0;\n- 296 for(auto idx=indices.begin(); idx!= indices.end(); ++idx) {\n- 297 interfaces()[idx->second].second.add(i++);\n- 298 }\n- 299 }\n- 300\n-301 ~RedistributeInterface()\n- 302 {}\n- 303\n- 304 };\n- 305\n- 306 namespace\n- 307 {\n- 317 template\n- 318 void createSendBuf(std::vector& ownerVec, std::set& overlapVec,\n-std::set& neighbors, char *sendBuf, int buffersize, MPI_Comm comm) {\n- 319 // Pack owner vertices\n- 320 std::size_t s=ownerVec.size();\n- 321 int pos=0;\n- 322 if(s==0)\n- 323 ownerVec.resize(1); // otherwise would read beyond the memory bound\n- 324 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n-&pos, comm);\n- 325 MPI_Pack(&(ownerVec[0]), s, MPITraits::getType(), sendBuf, buffersize,\n-&pos, comm);\n- 326 s = overlapVec.size();\n- 327 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n-&pos, comm);\n- 328 for(auto i=overlapVec.begin(), end= overlapVec.end(); i != end; ++i)\n- 329 MPI_Pack(const_cast(&(*i)), 1, MPITraits::getType(), sendBuf,\n-buffersize, &pos, comm);\n- 330\n- 331 s=neighbors.size();\n- 332 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n-&pos, comm);\n- 333\n- 334 for(auto i=neighbors.begin(), end= neighbors.end(); i != end; ++i)\n- 335 MPI_Pack(const_cast(&(*i)), 1, MPI_INT, sendBuf, buffersize, &pos,\n-comm);\n- 336 }\n- 345 template\n- 346 void saveRecvBuf(char *recvBuf, int bufferSize, std::vector >& ownerVec,\n- 347 std::set& overlapVec, std::set& neighbors, RedistributeInterface&\n-inf, int from, MPI_Comm comm) {\n- 348 std::size_t size;\n- 349 int pos=0;\n- 350 // unpack owner vertices\n- 351 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n-getType(), comm);\n- 352 inf.reserveSpaceForReceiveInterface(from, size);\n- 353 ownerVec.reserve(ownerVec.size()+size);\n- 354 for(; size!=0; --size) {\n- 355 GI gi;\n- 356 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits::getType(),\n-comm);\n- 357 ownerVec.push_back(std::make_pair(gi,from));\n- 358 }\n- 359 // unpack overlap vertices\n- 360 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n-getType(), comm);\n- 361 typename std::set::iterator ipos = overlapVec.begin();\n- 362 Dune::dverb << \"unpacking \"<::getType(),\n-comm);\n- 366 ipos=overlapVec.insert(ipos, gi);\n- 367 }\n- 368 //unpack neighbors\n- 369 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n-getType(), comm);\n- 370 Dune::dverb << \"unpacking \"<::iterator npos = neighbors.begin();\n- 372 for(; size!=0; --size) {\n- 373 int n;\n- 374 MPI_Unpack(recvBuf, bufferSize, &pos, &n, 1, MPI_INT, comm);\n- 375 npos=neighbors.insert(npos, n);\n- 376 }\n- 377 }\n- 378\n- 392 template\n- 393 void getDomain(const MPI_Comm& comm, T *part, int numOfOwnVtx, int nparts,\n-int *myDomain, std::vector &domainMapping) {\n- 394 int npes, mype;\n- 395 MPI_Comm_size(comm, &npes);\n- 396 MPI_Comm_rank(comm, &mype);\n- 397 MPI_Status status;\n- 398\n- 399 *myDomain = -1;\n- 400 int i=0;\n- 401 int j=0;\n- 402\n- 403 std::vector domain(nparts, 0);\n- 404 std::vector assigned(npes, 0);\n- 405 // init domain Mapping\n- 406 domainMapping.assign(domainMapping.size(), -1);\n- 407\n- 408 // count the occurrence of domains\n- 409 for (i=0; i domainMatrix(npes * nparts, -1);\n- 414\n- 415 // init buffer with the own domain\n- 416 int *buf = new int[nparts];\n- 417 for (i=0; i unassigned;\n- 442\n- 443 for(i=0; i::iterator next_free = assigned.begin();\n- 472\n- 473 for(auto udomain = unassigned.begin(),\n- 474 end = unassigned.end(); udomain != end; ++udomain)\n- 475 {\n- 476 next_free = std::find_if(next_free, assigned.end(), std::bind(std::\n-less(), std::placeholders::_1, 1));\n- 477 assert(next_free != assigned.end());\n- 478 domainMapping[*udomain] = next_free-assigned.begin();\n- 479 *next_free = 1;\n- 480 }\n- 481 }\n- 482\n- 483 struct SortFirst\n- 484 {\n- 485 template\n- 486 bool operator()(const T& t1, const T& t2) const\n- 487 {\n- 488 return t1\n- 504 void mergeVec(std::vector >& ownerVec, std::set&\n-overlapSet) {\n- 505\n- 506#ifdef DEBUG_REPART\n- 507 // Safety check for duplicates.\n- 508 if(ownerVec.size()>0)\n- 509 {\n- 510 auto old=ownerVec.begin();\n- 511 for(auto i=old+1, end=ownerVec.end(); i != end; old=i++)\n- 512 {\n- 513 if(i->first==old->first)\n- 514 {\n- 515 std::cerr<<\"Value at indes\"<first<<\",\"<second<<\"]==[\"\n- 517 <first<<\",\"<second<<\"]\"<first<*s) ++v;\n- 529 if(v!=vend && v->first==*s) {\n- 530 // Move to the next element before erasing\n- 531 // thus s stays valid!\n- 532 auto tmp=s;\n- 533 ++s;\n- 534 overlapSet.erase(tmp);\n- 535 }else\n- 536 ++s;\n- 537 }\n- 538 }\n- 539\n- 540\n- 554 template\n- 555 void getNeighbor(const Graph& g, std::vector& part,\n- 556 typename Graph::VertexDescriptor vtx, const IS& indexSet,\n- 557 int toPe, std::set& neighbor, std::set& neighborProcs) {\n- 558 for(auto edge=g.beginEdges(vtx), end=g.endEdges(vtx); edge!=end; ++edge)\n- 559 {\n- 560 const typename IS::IndexPair* pindex = indexSet.pair(edge.target());\n- 561 assert(pindex);\n- 562 if(part[pindex->local()]!=toPe || !OwnerSet::contains(pindex->local\n-().attribute()))\n- 563 {\n- 564 // is sent to another process and therefore becomes overlap\n- 565 neighbor.insert(pindex->global());\n- 566 neighborProcs.insert(part[pindex->local()]);\n- 567 }\n- 568 }\n- 569 }\n- 570\n- 571 template\n- 572 void my_push_back(std::vector& ownerVec, const I& index, [\n-[maybe_unused]] int proc)\n- 573 {\n- 574 ownerVec.push_back(index);\n- 575 }\n- 576\n- 577 template\n- 578 void my_push_back(std::vector >& ownerVec, const I&\n-index, int proc)\n- 579 {\n- 580 ownerVec.push_back(std::make_pair(index,proc));\n- 581 }\n- 582 template\n- 583 void reserve(std::vector&, RedistributeInterface&, int)\n- 584 {}\n- 585 template\n- 586 void reserve(std::vector >& ownerVec,\n-RedistributeInterface& redist, int proc)\n- 587 {\n- 588 redist.reserveSpaceForReceiveInterface(proc, ownerVec.size());\n- 589 }\n- 590\n- 591\n- 609 template\n- 610 void getOwnerOverlapVec(const G& graph, std::vector& part, IS&\n-indexSet,\n- 611 [[maybe_unused]] int myPe, int toPe, std::vector& ownerVec, std::\n-set& overlapSet,\n- 612 RedistributeInterface& redist, std::set& neighborProcs) {\n- 613 for(auto index = indexSet.begin(); index != indexSet.end(); ++index) {\n- 614 // Only Process owner vertices, the others are not in the parmetis graph.\n- 615 if(OwnerSet::contains(index->local().attribute()))\n- 616 {\n- 617 if(part[index->local()]==toPe)\n- 618 {\n- 619 getNeighbor(graph, part, index->local(), indexSet,\n- 620 toPe, overlapSet, neighborProcs);\n- 621 my_push_back(ownerVec, index->global(), toPe);\n- 622 }\n- 623 }\n- 624 }\n- 625 reserve(ownerVec, redist, toPe);\n- 626\n- 627 }\n- 628\n- 629\n- 636 template\n- 637 inline bool isOwner(IS& indexSet, int index) {\n- 638\n- 639 const typename IS::IndexPair* pindex=indexSet.pair(index);\n- 640\n- 641 assert(pindex);\n- 642 return F::contains(pindex->local().attribute());\n- 643 }\n- 644\n- 645\n- 646 class BaseEdgeFunctor\n- 647 {\n- 648 public:\n- 649 BaseEdgeFunctor(Metis::idx_t* adj,const ParmetisDuneIndexMap& data)\n- 650 : i_(), adj_(adj), data_(data)\n- 651 {}\n- 652\n- 653 template\n- 654 void operator()(const T& edge)\n- 655 {\n- 656 // Get the egde weight\n- 657 // const Weight& weight=edge.weight();\n- 658 adj_[i_] = data_.toParmetis(edge.target());\n- 659 i_++;\n- 660 }\n- 661 std::size_t index()\n- 662 {\n- 663 return i_;\n- 664 }\n- 665\n- 666 private:\n- 667 std::size_t i_;\n- 668 Metis::idx_t* adj_;\n- 669 const ParmetisDuneIndexMap& data_;\n- 670 };\n- 671\n- 672 template\n- 673 struct EdgeFunctor\n- 674 : public BaseEdgeFunctor\n- 675 {\n- 676 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::\n-size_t)\n- 677 : BaseEdgeFunctor(adj, data)\n- 678 {}\n- 679\n- 680 Metis::idx_t* getWeights()\n- 681 {\n- 682 return NULL;\n- 683 }\n- 684 void free(){}\n- 685 };\n- 686\n- 687 template\n- 688 class EdgeFunctor >\n- 689 : public BaseEdgeFunctor\n- 690 {\n- 691 public:\n- 692 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::\n-size_t s)\n- 693 : BaseEdgeFunctor(adj, data)\n- 694 {\n- 695 weight_=new Metis::idx_t[s];\n- 696 }\n- 697\n- 698 template\n- 699 void operator()(const T& edge)\n- 700 {\n- 701 weight_[index()]=edge.properties().depends() ? 3 : 1;\n- 702 BaseEdgeFunctor::operator()(edge);\n- 703 }\n- 704 Metis::idx_t* getWeights()\n- 705 {\n- 706 return weight_;\n- 707 }\n- 708 void free(){\n- 709 if(weight_!=0) {\n- 710 delete weight_;\n- 711 weight_=0;\n- 712 }\n- 713 }\n- 714 private:\n- 715 Metis::idx_t* weight_;\n- 716 };\n- 717\n- 718\n- 719\n- 733 template\n- 734 void getAdjArrays(G& graph, IS& indexSet, Metis::idx_t *xadj,\n- 735 EW& ew)\n- 736 {\n- 737 int j=0;\n- 738 auto vend = graph.end();\n- 739\n- 740 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {\n- 741 if (isOwner(indexSet,*vertex)) {\n- 742 // The type of const edge iterator.\n- 743 auto eend = vertex.end();\n- 744 xadj[j] = ew.index();\n- 745 j++;\n- 746 for(auto edge = vertex.begin(); edge != eend; ++edge) {\n- 747 ew(edge);\n- 748 }\n- 749 }\n- 750 }\n- 751 xadj[j] = ew.index();\n- 752 }\n- 753 } // end anonymous namespace\n- 754\n- 755 template\n- 756 bool buildCommunication(const G& graph, std::vector& realparts,\n- 757 Dune::OwnerOverlapCopyCommunication& oocomm,\n- 758 std::shared_ptr>& outcomm,\n- 759 RedistributeInterface& redistInf,\n- 760 bool verbose=false);\n- 761#if HAVE_PARMETIS\n- 762#ifndef METIS_VER_MAJOR\n- 763 extern \"C\"\n- 764 {\n- 765 // backwards compatibility to parmetis < 4.0.0\n- 766 void METIS_PartGraphKway(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t\n-*adjncy, Metis::idx_t *vwgt,\n- 767 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,\n- 768 int *options, int *edgecut, Metis::idx_t *part);\n- 769\n- 770 void METIS_PartGraphRecursive(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t\n-*adjncy, Metis::idx_t *vwgt,\n- 771 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,\n- 772 int *options, int *edgecut, Metis::idx_t *part);\n- 773 }\n- 774#endif\n- 775#endif // HAVE_PARMETIS\n- 776\n- 777 template\n-778 inline void print_carray(S& os, T* array, std::size_t l)\n- 779 {\n- 780 for(T *cur=array, *end=array+l; cur!=end; ++cur)\n- 781 os<<*cur<<\" \";\n- 782 }\n- 783\n- 784 template\n-785 inline bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges,\n-T* xadj,\n- 786 T* adjncy, bool checkSymmetry)\n- 787 {\n- 788 bool correct=true;\n- 789\n- 790 using std::signbit;\n- 791 for(Metis::idx_t vtx=0; vtx<(Metis::idx_t)noVtx; ++vtx) {\n- 792 if(static_cast(xadj[vtx])>noEdges || signbit(xadj[vtx])) {\n- 793 std::cerr <<\"Check graph: xadj[\"<\"\n- 794 <(xadj[vtx+1])>noEdges || signbit(xadj[vtx+1])) {\n- 798 std::cerr <<\"Check graph: xadj[\"<\"\n- 799 <gnoVtx) {\n- 805 std::cerr<<\" Edge \"<\n-829 bool commGraphRepartition(const M& mat, Dune::\n-OwnerOverlapCopyCommunication& oocomm,\n- 830 Metis::idx_t nparts,\n- 831 std::shared_ptr>& outcomm,\n- 832 RedistributeInterface& redistInf,\n- 833 bool verbose=false)\n- 834 {\n- 835 if(verbose && oocomm.communicator().rank()==0)\n- 836 std::cout<<\"Repartitioning from \"<1) {\n- 847\n- 848 part[0]=rank;\n- 849\n- 850 { // sublock for automatic memory deletion\n- 851\n- 852 // Build the graph of the communication scheme and create an appropriate\n-indexset.\n- 853 // calculate the neighbour vertices\n- 854 int noNeighbours = oocomm.remoteIndices().neighbours();\n- 855\n- 856 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices\n-().end();\n- 857 ++n)\n- 858 if(n->first==rank) {\n- 859 //do not include ourselves.\n- 860 --noNeighbours;\n- 861 break;\n- 862 }\n- 863\n- 864 // A parmetis graph representing the communication graph.\n- 865 // The diagonal entries are the number of nodes on the process.\n- 866 // The offdiagonal entries are the number of edges leading to other\n-processes.\n- 867\n- 868 Metis::idx_t *xadj=new Metis::idx_t[2];\n- 869 Metis::idx_t *vtxdist=new Metis::idx_t[oocomm.communicator().size()+1];\n- 870 Metis::idx_t *adjncy=new Metis::idx_t[noNeighbours];\n- 871#ifdef USE_WEIGHTS\n- 872 Metis::idx_t *vwgt = 0;\n- 873 Metis::idx_t *adjwgt = 0;\n- 874#endif\n- 875\n- 876 // each process has exactly one vertex!\n- 877 for(int i=0; i owner(mat.N(), oocomm.communicator().rank());\n- 887 // for(NeighbourIterator n= oocomm.remoteIndices().begin(); n !=\n-oocomm.remoteIndices().end();\n- 888 // ++n)\n- 889 // {\n- 890 // if(n->first!=oocomm.communicator().rank()){\n- 891 // typedef typename RemoteIndices::RemoteIndexList RIList;\n- 892 // const RIList& rlist = *(n->second.first);\n- 893 // typedef typename RIList::const_iterator LIter;\n- 894 // for(LIter entry=rlist.begin(); entry!=rlist.end(); ++entry){\n- 895 // if(entry->attribute()==OwnerOverlapCopyAttributeSet::owner)\n- 896 // owner[entry->localIndexPair().local()] = n->first;\n- 897 // }\n- 898 // }\n- 899 // }\n- 900\n- 901 // std::map edgecount; // edges to other processors\n- 902 // typedef typename M::ConstRowIterator RIter;\n- 903 // typedef typename M::ConstColIterator CIter;\n- 904\n- 905 // // calculate edge count\n- 906 // for(RIter row=mat.begin(), endr=mat.end(); row != endr; ++row)\n- 907 // if(owner[row.index()]==OwnerOverlapCopyAttributeSet::owner)\n- 908 // for(CIter entry= row->begin(), ende = row->end(); entry != ende;\n-++entry)\n- 909 // ++edgecount[owner[entry.index()]];\n- 910\n- 911 // setup edge and weight pattern\n- 912\n- 913 Metis::idx_t* adjp=adjncy;\n- 914\n- 915#ifdef USE_WEIGHTS\n- 916 vwgt = new Metis::idx_t[1];\n- 917 vwgt[0]= mat.N(); // weight is numer of rows TODO: Should actually be the\n-nonzeros.\n- 918\n- 919 adjwgt = new Metis::idx_t[noNeighbours];\n- 920 Metis::idx_t* adjwp=adjwgt;\n- 921#endif\n- 922\n- 923 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices\n-().end();\n- 924 ++n)\n- 925 if(n->first != rank) {\n- 926 *adjp=n->first;\n- 927 ++adjp;\n- 928#ifdef USE_WEIGHTS\n- 929 *adjwp=1; //edgecount[n->first];\n- 930 ++adjwp;\n- 931#endif\n- 932 }\n- 933 assert(isValidGraph(vtxdist[rank+1]-vtxdist[rank],\n- 934 vtxdist[oocomm.communicator().size()],\n- 935 noNeighbours, xadj, adjncy, false));\n- 936\n- 937 [[maybe_unused]] Metis::idx_t wgtflag=0;\n- 938 Metis::idx_t numflag=0;\n- 939 Metis::idx_t edgecut;\n- 940#ifdef USE_WEIGHTS\n- 941 wgtflag=3;\n- 942#endif\n- 943 Metis::real_t *tpwgts = new Metis::real_t[nparts];\n- 944 for(int i=0; i::getType(),\n- 1071 gxadj,noxs,xdispl,MPITraits::getType(),\n- 1072 comm);\n- 1073 MPI_Allgatherv(adjncy,noNeighbours,MPITraits::getType(),\n- 1074 gadjncy,noedges,displ,MPITraits::getType(),\n- 1075 comm);\n- 1076#ifdef USE_WEIGHTS\n- 1077 MPI_Allgatherv(adjwgt,noNeighbours,MPITraits::getType(),\n- 1078 gadjwgt,noedges,displ,MPITraits::getType(),\n- 1079 comm);\n- 1080 MPI_Allgatherv(vwgt,localNoVtx,MPITraits::getType(),\n- 1081 gvwgt,novs,vdispl,MPITraits::getType(),\n- 1082 comm);\n- 1083#endif\n- 1084 if(verbose && oocomm.communicator().rank()==0)\n- 1085 std::cout<<\"Gathering global graph data took \"<(gxadjlen));\n- 1103 increment = *(start-1);\n- 1104 std::transform(start+offset, start+l+offset, start, std::bind(std::\n-plus(), std::placeholders::_1, increment));\n- 1105 }\n- 1106 Dune::dinfo<= 5\n- 1130 Metis::idx_t ncon = 1;\n- 1131 Metis::idx_t moptions[METIS_NOPTIONS];\n- 1132 METIS_SetDefaultOptions(moptions);\n- 1133 moptions[METIS_OPTION_NUMBERING] = numflag;\n- 1134 METIS_PartGraphRecursive(&noVertices, &ncon, gxadj, gadjncy, gvwgt, NULL,\n-gadjwgt,\n- 1135 &nparts, NULL, NULL, moptions, &edgecut, gpart);\n- 1136#else\n- 1137 int options[5] = {0, 1, 1, 3, 3};\n- 1138 // Call metis\n- 1139 METIS_PartGraphRecursive(&noVertices, gxadj, gadjncy, gvwgt, gadjwgt,\n-&wgtflag,\n- 1140 &numflag, &nparts, options, &edgecut, gpart);\n- 1141#endif\n- 1142\n- 1143 if(verbose && oocomm.communicator().rank()==0)\n- 1144 std::cout<<\"METIS took \"<::getType(), part, 1,\n- 1159 MPITraits::getType(), 0, comm);\n- 1160\n- 1161 {\n- 1162 // release remaining memory\n- 1163 delete[] gpart;\n- 1164 delete[] noedges;\n- 1165 delete[] displ;\n- 1166 }\n- 1167\n- 1168\n- 1169#endif\n- 1170 delete[] xadj;\n- 1171 delete[] vtxdist;\n- 1172 delete[] adjncy;\n- 1173#ifdef USE_WEIGHTS\n- 1174 delete[] vwgt;\n- 1175 delete[] adjwgt;\n- 1176#endif\n- 1177 delete[] tpwgts;\n- 1178 }\n- 1179 }else{\n- 1180 part[0]=0;\n- 1181 }\n- 1182#endif\n- 1183 Dune::dinfo<<\" repart \"< \"<< part[0]< realpart(mat.N(), part[0]);\n- 1186 delete[] part;\n- 1187\n- 1188 oocomm.copyOwnerToAll(realpart, realpart);\n- 1189\n- 1190 if(verbose && oocomm.communicator().rank()==0)\n- 1191 std::cout<<\"Scattering repartitioning took \"< graph(const_cast(mat));\n- 1197 fillIndexSetHoles(graph, oocomm);\n- 1198 if(verbose && oocomm.communicator().rank()==0)\n- 1199 std::cout<<\"Filling index set took \"<\n-1235 bool graphRepartition(const G& graph, Dune::\n-OwnerOverlapCopyCommunication& oocomm, Metis::idx_t nparts,\n- 1236 std::shared_ptr>& outcomm,\n- 1237 RedistributeInterface& redistInf,\n- 1238 bool verbose=false)\n- 1239 {\n- 1240 Timer time;\n- 1241\n- 1242 MPI_Comm comm=oocomm.communicator();\n- 1243 oocomm.buildGlobalLookup(graph.noVertices());\n- 1244 fillIndexSetHoles(graph, oocomm);\n- 1245\n- 1246 if(verbose && oocomm.communicator().rank()==0)\n- 1247 std::cout<<\"Filling holes took \"<(oocomm.communicator().size()));\n- 1262\n- 1263 int myDomain = -1;\n- 1264\n- 1265 //\n- 1266 // 1) Prepare the required parameters for using ParMETIS\n- 1267 // Especially the arrays that represent the graph must be\n- 1268 // generated by the DUNE Graph and IndexSet input variables.\n- 1269 // These are the arrays:\n- 1270 // - vtxdist\n- 1271 // - xadj\n- 1272 // - adjncy\n- 1273 //\n- 1274 //\n- 1275#ifdef PERF_REPART\n- 1276 // reset timer for step 1)\n- 1277 t1=MPI_Wtime();\n- 1278#endif\n- 1279\n- 1280\n- 1281 typedef typename Dune::OwnerOverlapCopyCommunication OOComm;\n- 1282 typedef typename OOComm::OwnerSet OwnerSet;\n- 1283\n- 1284 // Create the vtxdist array and parmetisVtxMapping.\n- 1285 // Global communications are necessary\n- 1286 // The parmetis global identifiers for the owner vertices.\n- 1287 ParmetisDuneIndexMap indexMap(graph,oocomm);\n- 1288 Metis::idx_t *part = new Metis::idx_t[indexMap.numOfOwnVtx()];\n- 1289 for(std::size_t i=0; i < indexMap.numOfOwnVtx(); ++i)\n- 1290 part[i]=mype;\n- 1291\n- 1292#if !HAVE_PARMETIS\n- 1293 if(oocomm.communicator().rank()==0 && nparts>1)\n- 1294 std::cerr<<\"ParMETIS not activated. Will repartition to 1 domain instead\n-of requested \"\n- 1295 <1) {\n- 1301 // Create the xadj and adjncy arrays\n- 1302 Metis::idx_t *xadj = new Metis::idx_t[indexMap.numOfOwnVtx()+1];\n- 1303 Metis::idx_t *adjncy = new Metis::idx_t[graph.noEdges()];\n- 1304 EdgeFunctor ef(adjncy, indexMap, graph.noEdges());\n- 1305 getAdjArrays(graph, oocomm.globalLookup(), xadj, ef);\n- 1306\n- 1307 //\n- 1308 // 2) Call ParMETIS\n- 1309 //\n- 1310 //\n- 1311 Metis::idx_t numflag=0, wgtflag=0, options[3], edgecut=0, ncon=1;\n- 1312 //float *tpwgts = NULL;\n- 1313 Metis::real_t *tpwgts = new Metis::real_t[nparts];\n- 1314 for(int i=0; i(comm));\n- 1358\n- 1359\n- 1360 delete[] xadj;\n- 1361 delete[] adjncy;\n- 1362 delete[] tpwgts;\n- 1363\n- 1364 ef.free();\n- 1365\n- 1366#ifdef DEBUG_REPART\n- 1367 if (mype == 0) {\n- 1368 std::cout< domainMapping(nparts);\n- 1410 if(nparts>1)\n- 1411 getDomain(comm, part, indexMap.numOfOwnVtx(), nparts, &myDomain,\n-domainMapping);\n- 1412 else\n- 1413 domainMapping[0]=0;\n- 1414\n- 1415#ifdef DEBUG_REPART\n- 1416 std::cout< setPartition(oocomm.indexSet().size(), -1);\n- 1429\n- 1430 std::size_t i=0; // parmetis index\n- 1431 for(auto index = oocomm.indexSet().begin(); index != oocomm.indexSet\n-().end(); ++index)\n- 1432 if(OwnerSet::contains(index->local().attribute())) {\n- 1433 setPartition[index->local()]=domainMapping[part[i++]];\n- 1434 }\n- 1435\n- 1436 delete[] part;\n- 1437 oocomm.copyOwnerToAll(setPartition, setPartition);\n- 1438 // communication only needed for ALU\n- 1439 // (ghosts with same global id as owners on the same process)\n- 1440 if (SolverCategory::category(oocomm) ==\n- 1441 static_cast(SolverCategory::nonoverlapping))\n- 1442 oocomm.copyCopyToAll(setPartition, setPartition);\n- 1443 bool ret = buildCommunication(graph, setPartition, oocomm, outcomm,\n-redistInf,\n- 1444 verbose);\n- 1445 if(verbose) {\n- 1446 oocomm.communicator().barrier();\n- 1447 if(oocomm.communicator().rank()==0)\n- 1448 std::cout<<\"Creating indexsets took \"<\n-1456 bool buildCommunication(const G& graph,\n- 1457 std::vector& setPartition, Dune::\n-OwnerOverlapCopyCommunication& oocomm,\n- 1458 std::shared_ptr>& outcomm,\n- 1459 RedistributeInterface& redistInf,\n- 1460 bool verbose)\n- 1461 {\n- 1462 typedef typename Dune::OwnerOverlapCopyCommunication OOComm;\n- 1463 typedef typename OOComm::OwnerSet OwnerSet;\n- 1464\n- 1465 Timer time;\n- 1466\n- 1467 // Build the send interface\n- 1468 redistInf.buildSendInterface(setPartition, oocomm.indexSet());\n- 1469\n- 1470#ifdef PERF_REPART\n- 1471 // stop the time for step 3)\n- 1472 t3=MPI_Wtime()-t3;\n- 1473 // reset timer for step 4)\n- 1474 t4=MPI_Wtime();\n- 1475#endif\n- 1476\n- 1477\n- 1478 //\n- 1479 // 4) Create the output IndexSet and RemoteIndices\n- 1480 // 4.1) Determine the \"send to\" and \"receive from\" relation\n- 1481 // according to the new partition using a MPI ring\n- 1482 // communication.\n- 1483 //\n- 1484 // 4.2) Depends on the \"send to\" and \"receive from\" vector,\n- 1485 // the processes will exchange the vertices each other\n- 1486 //\n- 1487 // 4.3) Create the IndexSet, RemoteIndices and the new MPI\n- 1488 // communicator\n- 1489 //\n- 1490\n- 1491 //\n- 1492 // 4.1) Let's start...\n- 1493 //\n- 1494 int npes = oocomm.communicator().size();\n- 1495 int *sendTo = 0;\n- 1496 int noSendTo = 0;\n- 1497 std::set recvFrom;\n- 1498\n- 1499 // the max number of vertices is stored in the sendTo buffer,\n- 1500 // not the number of vertices to send! Because the max number of Vtx\n- 1501 // is used as the fixed buffer size by the MPI send/receive calls\n- 1502\n- 1503 int mype = oocomm.communicator().rank();\n- 1504\n- 1505 {\n- 1506 std::set tsendTo;\n- 1507 for(auto i=setPartition.begin(), iend = setPartition.end(); i!=iend; ++i)\n- 1508 tsendTo.insert(*i);\n- 1509\n- 1510 noSendTo = tsendTo.size();\n- 1511 sendTo = new int[noSendTo];\n- 1512 int idx=0;\n- 1513 for(auto i=tsendTo.begin(); i != tsendTo.end(); ++i, ++idx)\n- 1514 sendTo[idx]=*i;\n- 1515 }\n- 1516\n- 1517 //\n- 1518 int* gnoSend= new int[oocomm.communicator().size()];\n- 1519 int* gsendToDispl = new int[oocomm.communicator().size()+1];\n- 1520\n- 1521 MPI_Allgather(&noSendTo, 1, MPI_INT, gnoSend, 1,\n- 1522 MPI_INT, oocomm.communicator());\n- 1523\n- 1524 // calculate total receive message size\n- 1525 int totalNoRecv = 0;\n- 1526 for(int i=0; i0;\n- 1547\n- 1548 // Delete memory\n- 1549 delete[] gnoSend;\n- 1550 delete[] gsendToDispl;\n- 1551 delete[] gsendTo;\n- 1552\n- 1553\n- 1554#ifdef DEBUG_REPART\n- 1555 if(recvFrom.size()) {\n- 1556 std::cout< GlobalVector;\n- 1589 std::vector > myOwnerVec;\n- 1590 std::set myOverlapSet;\n- 1591 GlobalVector sendOwnerVec;\n- 1592 std::set sendOverlapSet;\n- 1593 std::set myNeighbors;\n- 1594\n- 1595 // getOwnerOverlapVec(graph, setPartition, oocomm.globalLookup\n-(),\n- 1596 // mype, mype, myOwnerVec, myOverlapSet, redistInf, myNeighbors);\n- 1597\n- 1598 char **sendBuffers=new char*[noSendTo];\n- 1599 MPI_Request *requests = new MPI_Request[noSendTo];\n- 1600\n- 1601 // Create all messages to be sent\n- 1602 for(int i=0; i < noSendTo; ++i) {\n- 1603 // clear the vector for sending\n- 1604 sendOwnerVec.clear();\n- 1605 sendOverlapSet.clear();\n- 1606 // get all owner and overlap vertices for process j and save these\n- 1607 // in the vectors sendOwnerVec and sendOverlapSet\n- 1608 std::set neighbors;\n- 1609 getOwnerOverlapVec(graph, setPartition, oocomm.globalLookup(),\n- 1610 mype, sendTo[i], sendOwnerVec, sendOverlapSet, redistInf,\n- 1611 neighbors);\n- 1612 // +2, we need 2 integer more for the length of each part\n- 1613 // (owner/overlap) of the array\n- 1614 int buffersize=0;\n- 1615 int tsize;\n- 1616 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n-(), &buffersize);\n- 1617 MPI_Pack_size(sendOwnerVec.size(), MPITraits::getType(),\n-oocomm.communicator(), &tsize);\n- 1618 buffersize +=tsize;\n- 1619 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n-(), &tsize);\n- 1620 buffersize +=tsize;\n- 1621 MPI_Pack_size(sendOverlapSet.size(), MPITraits::getType(),\n-oocomm.communicator(), &tsize);\n- 1622 buffersize += tsize;\n- 1623 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n-(), &tsize);\n- 1624 buffersize += tsize;\n- 1625 MPI_Pack_size(neighbors.size(), MPI_INT, oocomm.communicator(), &tsize);\n- 1626 buffersize += tsize;\n- 1627\n- 1628 sendBuffers[i] = new char[buffersize];\n- 1629\n- 1630#ifdef DEBUG_REPART\n- 1631 std::cout<0) {\n- 1651 // probe for an incoming message\n- 1652 MPI_Status stat;\n- 1653 MPI_Probe(MPI_ANY_SOURCE, 99, oocomm.communicator(), &stat);\n- 1654 int buffersize;\n- 1655 MPI_Get_count(&stat, MPI_PACKED, &buffersize);\n- 1656\n- 1657 if(oldbuffersize(outputComm,SolverCategory::category\n-(oocomm),true);\n- 1727\n- 1728 // translate neighbor ranks.\n- 1729 int newrank=outcomm->communicator().rank();\n- 1730 int *newranks=new int[oocomm.communicator().size()];\n- 1731 std::vector tneighbors;\n- 1732 tneighbors.reserve(myNeighbors.size());\n- 1733\n- 1734 typename OOComm::ParallelIndexSet& outputIndexSet = outcomm->indexSet();\n- 1735\n- 1736 MPI_Allgather(&newrank, 1, MPI_INT, newranks, 1,\n- 1737 MPI_INT, oocomm.communicator());\n- 1738\n- 1739#ifdef DEBUG_REPART\n- 1740 std::cout<=0);\n- 1744 std::cout<<*i<<\"->\"<first,LocalIndexT(i, OwnerOverlapCopyAttributeSet::\n-owner, true));\n- 1777 redistInf.addReceiveIndex(g->second, i);\n- 1778 }\n- 1779\n- 1780 if(verbose) {\n- 1781 oocomm.communicator().barrier();\n- 1782 if(oocomm.communicator().rank()==0)\n- 1783 std::cout<<\" Adding owner indices took \"<<\n- 1784 time.elapsed()<local().attribute())) {\n- 1820 numOfOwnVtx++;\n- 1821 }\n- 1822 }\n- 1823 numOfOwnVtx = oocomm.communicator().sum(numOfOwnVtx);\n- 1824 // if(numOfOwnVtx!=indexMap.globalOwnerVertices)\n- 1825 // {\n- 1826 // std::cerr<remoteIndices().setNeighbours(tneighbors);\n- 1844 outcomm->remoteIndices().template rebuild();\n- 1845\n- 1846 }\n- 1847\n- 1848 // release the memory\n- 1849 delete[] sendTo;\n- 1850\n- 1851 if(verbose) {\n- 1852 oocomm.communicator().barrier();\n- 1853 if(oocomm.communicator().rank()==0)\n- 1854 std::cout<<\" Storing indexsets took \"<<\n- 1855 time.elapsed()<\n- 1876 bool graphRepartition(const G& graph, P& oocomm, int nparts,\n- 1877 std::shared_ptr

    & outcomm,\n- 1878 R& redistInf,\n- 1879 bool v=false)\n- 1880 {\n- 1881 if(nparts!=oocomm.size())\n- 1882 DUNE_THROW(NotImplemented, \"only available for MPI programs\");\n- 1883 }\n- 1884\n- 1885\n- 1886 template\n- 1887 bool commGraphRepartition(const G& graph, P& oocomm, int nparts,\n- 1888 std::shared_ptr

    & outcomm,\n- 1889 R& redistInf,\n- 1890 bool v=false)\n- 1891 {\n- 1892 if(nparts!=oocomm.size())\n- 1893 DUNE_THROW(NotImplemented, \"only available for MPI programs\");\n- 1894 }\n- 1895#endif // HAVE_MPI\n- 1896} // end of namespace Dune\n- 1897#endif\n-globalOwnerVertices\n-int globalOwnerVertices\n-Definition: repartition.hh:175\n-graph.hh\n-Provides classes for building the matrix graph.\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n+ 215#endif\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n Dune\n Definition: allocator.hh:11\n-Dune::buildCommunication\n-bool buildCommunication(const G &graph, std::vector< int > &realparts, Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n-&redistInf, bool verbose=false)\n-Definition: repartition.hh:1456\n-Dune::fillIndexSetHoles\n-void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n-T2 > &oocomm)\n-Fills the holes in an index set.\n-Definition: repartition.hh:83\n-Dune::commGraphRepartition\n-bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication<\n-T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n-&redistInf, bool verbose=false)\n-Definition: repartition.hh:829\n-Dune::print_carray\n-void print_carray(S &os, T *array, std::size_t l)\n-Definition: repartition.hh:778\n-Dune::isValidGraph\n-bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T\n-*adjncy, bool checkSymmetry)\n-Definition: repartition.hh:785\n-Dune::graphRepartition\n-bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n-T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n-&redistInf, bool verbose=false)\n-execute a graph repartition for a giving graph and indexset.\n-Definition: repartition.hh:1235\n-Dune::Metis::real_t\n-float real_t\n-Definition: repartition.hh:53\n-Dune::Metis::idx_t\n-std::size_t idx_t\n-Definition: repartition.hh:63\n-Dune::OwnerOverlapCopyAttributeSet::owner\n-@ owner\n-Definition: owneroverlapcopy.hh:61\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::globalLookup\n-const GlobalLookupIndexSet & globalLookup() const\n-Definition: owneroverlapcopy.hh:526\n-Dune::OwnerOverlapCopyCommunication::indexSet\n-const ParallelIndexSet & indexSet() const\n-Get the underlying parallel index set.\n-Definition: owneroverlapcopy.hh:462\n-Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n-void copyCopyToAll(const T &source, T &dest) const\n-Communicate values from copy data points to all other data points.\n-Definition: owneroverlapcopy.hh:328\n-Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n-Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n-The type of the reverse lookup of indices.\n-Definition: owneroverlapcopy.hh:456\n-Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n-void buildGlobalLookup()\n-Definition: owneroverlapcopy.hh:495\n-Dune::OwnerOverlapCopyCommunication::communicator\n-const Communication< MPI_Comm > & communicator() const\n-Definition: owneroverlapcopy.hh:299\n-Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n-void copyOwnerToAll(const T &source, T &dest) const\n-Communicate values from owner data points to all other data points.\n-Definition: owneroverlapcopy.hh:311\n-Dune::OwnerOverlapCopyCommunication::remoteIndices\n-const RemoteIndices & remoteIndices() const\n-Get the underlying remote indices.\n-Definition: owneroverlapcopy.hh:471\n-Dune::OwnerOverlapCopyCommunication::freeGlobalLookup\n-void freeGlobalLookup()\n-Definition: owneroverlapcopy.hh:520\n-Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n-Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n-The type of the parallel index set.\n-Definition: owneroverlapcopy.hh:449\n-Dune::Amg::MatrixGraph\n-The (undirected) graph of a matrix.\n-Definition: graph.hh:51\n-Dune::RedistributeInterface\n-Definition: repartition.hh:260\n-Dune::RedistributeInterface::reserveSpaceForReceiveInterface\n-void reserveSpaceForReceiveInterface(int proc, int size)\n-Definition: repartition.hh:284\n-Dune::RedistributeInterface::buildReceiveInterface\n-void buildReceiveInterface(std::vector< std::pair< TG, int > > &indices)\n-Definition: repartition.hh:293\n-Dune::RedistributeInterface::~RedistributeInterface\n-~RedistributeInterface()\n-Definition: repartition.hh:301\n-Dune::RedistributeInterface::setCommunicator\n-void setCommunicator(MPI_Comm comm)\n-Definition: repartition.hh:261\n-Dune::RedistributeInterface::buildSendInterface\n-void buildSendInterface(const std::vector< int > &toPart, const IS &idxset)\n-Definition: repartition.hh:266\n-Dune::RedistributeInterface::addReceiveIndex\n-void addReceiveIndex(int proc, std::size_t idx)\n-Definition: repartition.hh:288\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::endrowsizes\n+void endrowsizes()\n+indicate that size of all rows is defined\n+Definition: bcrsmatrix.hh:1149\n+Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::random\n+@ random\n+Build entries randomly.\n+Definition: bcrsmatrix.hh:530\n+Dune::BCRSMatrix::addindex\n+void addindex(size_type row, size_type col)\n+add index (row,col) to the matrix\n+Definition: bcrsmatrix.hh:1191\n+Dune::BCRSMatrix::endindices\n+void endindices()\n+indicate that all indices are defined, check consistency\n+Definition: bcrsmatrix.hh:1248\n+Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::N\n+size_type N() const\n+number of rows (counted in blocks)\n+Definition: bcrsmatrix.hh:1972\n+Dune::BCRSMatrix::setSize\n+void setSize(size_type rows, size_type columns, size_type nnz=0)\n+Set the size of the matrix.\n+Definition: bcrsmatrix.hh:861\n+Dune::BCRSMatrix::operator=\n+BCRSMatrix & operator=(const BCRSMatrix &Mat)\n+assignment\n+Definition: bcrsmatrix.hh:911\n+Dune::BTDMatrix\n+A block-tridiagonal matrix.\n+Definition: btdmatrix.hh:31\n+Dune::BTDMatrix::blocklevel\n+static constexpr auto blocklevel\n+increment block level counter\n+Definition: btdmatrix.hh:53\n+Dune::BTDMatrix::BTDMatrix\n+BTDMatrix(size_type size)\n+Definition: btdmatrix.hh:58\n+Dune::BTDMatrix::solve\n+void solve(V &x, const V &rhs) const\n+Use the Thomas algorithm to solve the system Ax=b in O(n) time.\n+Definition: btdmatrix.hh:125\n+Dune::BTDMatrix::size_type\n+A::size_type size_type\n+implement row_type with compressed vector\n+Definition: btdmatrix.hh:49\n+Dune::BTDMatrix::allocator_type\n+A allocator_type\n+export the allocator type\n+Definition: btdmatrix.hh:43\n+Dune::BTDMatrix::block_type\n+B block_type\n+export the type representing the components\n+Definition: btdmatrix.hh:40\n+Dune::BTDMatrix::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: btdmatrix.hh:37\n+Dune::BTDMatrix::operator=\n+BTDMatrix & operator=(const BTDMatrix &other)\n+assignment\n+Definition: btdmatrix.hh:108\n+Dune::BTDMatrix::BTDMatrix\n+BTDMatrix()\n+Default constructor.\n+Definition: btdmatrix.hh:56\n+Dune::BTDMatrix::setSize\n+void setSize(size_type size)\n+Resize the matrix. Invalidates the content!\n+Definition: btdmatrix.hh:81\n+Dune::FieldTraits<_BTDMatrix<_B,_A_>_>::real_type\n+typename FieldTraits< field_type >::real_type real_type\n+Definition: btdmatrix.hh:208\n+Dune::FieldTraits<_BTDMatrix<_B,_A_>_>::field_type\n+typename BTDMatrix< B, A >::field_type field_type\n+Definition: btdmatrix.hh:207\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00095.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00095.html", "unified_diff": "@@ -75,16 +75,16 @@\n

    #include <type_traits>
    \n #include <utility>
    \n #include <cassert>
    \n #include <dune/common/std/type_traits.hh>
    \n #include <dune/common/diagonalmatrix.hh>
    \n #include <dune/common/hybridutilities.hh>
    \n #include <dune/common/indices.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/scaledidmatrix.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/istl/scaledidmatrix.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00095_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00095_source.html", "unified_diff": "@@ -78,16 +78,16 @@\n
    7#include<cassert>
    \n
    8
    \n
    9#include<dune/common/std/type_traits.hh>
    \n
    10#include<dune/common/diagonalmatrix.hh>
    \n
    11#include<dune/common/hybridutilities.hh>
    \n
    12#include<dune/common/indices.hh>
    \n
    13
    \n-\n-\n+\n+\n
    16
    \n
    17namespace Dune{
    \n
    18
    \n
    19 namespace Impl {
    \n
    20
    \n
    21 // stolen from dune-functions: we call a type "scalar" if it does not support index accessing
    \n
    22 template<class C>
    \n@@ -232,16 +232,16 @@\n
    190 });
    \n
    191 return {r,c};
    \n
    192 }
    \n
    193 }
    \n
    194}
    \n
    195
    \n
    196} // namespace Dune
    \n-
    This file implements a quadratic matrix of fixed size which is a multiple of the identity.
    \n-
    Implementation of the BCRSMatrix class.
    \n+
    This file implements a quadratic matrix of fixed size which is a multiple of the identity.
    \n+
    Implementation of the BCRSMatrix class.
    \n
    Definition: allocator.hh:11
    \n
    std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f, std::size_t rowOffset=0, std::size_t colOffset=0)
    Traverse a blocked matrix and call a functor at each scalar entry.
    Definition: foreach.hh:132
    \n
    std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)
    Traverse a blocked vector and call a functor at each scalar entry.
    Definition: foreach.hh:95
    \n
    auto rows(Matrix const &matrix)
    Definition: foreach.hh:69
    \n
    auto cols(Matrix const &matrix)
    Definition: foreach.hh:72
    \n
    auto size(Vector const &vector)
    Definition: foreach.hh:75
    \n
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00098.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00098.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: graph.hh File Reference\n+dune-istl: matrixmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -58,100 +58,75 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n \n
    \n \n-

    Provides classes for building the matrix graph. \n+

    provides functions for sparse matrix matrix multiplication. \n More...

    \n-
    #include <cstddef>
    \n-#include <algorithm>
    \n-#include <vector>
    \n-#include <cassert>
    \n-#include <limits>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/iteratorfacades.hh>
    \n-#include <dune/istl/istlexception.hh>
    \n-#include <dune/common/propertymap.hh>
    \n+
    #include <tuple>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/timer.hh>
    \n
    \n

    Go to the source code of this file.

    \n

    \n Namespaces

    namespace  Dune
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::Amg::MatrixGraph< M >
     The (undirected) graph of a matrix. More...
    struct  Dune::MatMultMatResult< M1, M2 >
     Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") More...
     
    class  Dune::Amg::MatrixGraph< M >::EdgeIteratorT< C >
     Iterator over all edges starting from a vertex. More...
    struct  Dune::MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >
     
    class  Dune::Amg::MatrixGraph< M >::VertexIteratorT< C >
     The vertex iterator type of the graph. More...
    struct  Dune::MatMultMatResult< BCRSMatrix< FieldMatrix< T, n, k >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >
     
    class  Dune::Amg::SubGraph< G, T >
     A subgraph of a graph. More...
    struct  Dune::TransposedMatMultMatResult< M1, M2 >
     Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") More...
     
    class  Dune::Amg::SubGraph< G, T >::EdgeIndexMap
     An index map for mapping the edges to indices. More...
    struct  Dune::TransposedMatMultMatResult< FieldMatrix< T, k, n >, FieldMatrix< T, k, m > >
     
    class  Dune::Amg::SubGraph< G, T >::EdgeIterator
     The edge iterator of the graph. More...
     
    class  Dune::Amg::SubGraph< G, T >::VertexIterator
     The vertex iterator of the graph. More...
     
    class  Dune::Amg::VertexPropertiesGraph< G, VP, VM >
     Attaches properties to the vertices of a graph. More...
     
    class  Dune::Amg::VertexPropertiesGraph< G, VP, VM >::VertexIteratorT< C >
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >
     Attaches properties to the edges and vertices of a graph. More...
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::EdgeIteratorT< C >
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::VertexIteratorT< C >
     
    class  Dune::Amg::GraphVertexPropertiesSelector< G >
     Wrapper to access the internal edge properties of a graph via operator[]() More...
     
    class  Dune::Amg::GraphEdgePropertiesSelector< G >
     Wrapper to access the internal vertex properties of a graph via operator[]() More...
    struct  Dune::TransposedMatMultMatResult< BCRSMatrix< FieldMatrix< T, k, n >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n \n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<class G , class V >
    int Dune::Amg::visitNeighbours (const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
     Visit all neighbour vertices of a vertex in a graph. More...
     
    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::matMultTransposeMat (BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of a sparse matrix with a transposed sparse matrices ( \"$C=A*B^T$\"). More...
     
    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::matMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of two sparse matrices ( \"$C=A*B$\"). More...
     
    template<class T , class A , class A1 , class A2 , int n, int m, int k>
    void Dune::transposeMatMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
     Calculate product of a transposed sparse matrix with another sparse matrices ( \"$C=A^T*B$\"). More...
     
    \n

    Detailed Description

    \n-

    Provides classes for building the matrix graph.

    \n-
    Author
    Markus Blatt
    \n-

    During the coarsening process in AMG the matrix graph together with the dependencies, what connections in the graph are considered strong or weak, what vertices are isolated, etc., have to build. This information will be contained in the MatrixGraph class.

    \n+

    provides functions for sparse matrix matrix multiplication.

    \n+
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,87 +4,68 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n Classes | Namespaces | Functions\n-graph.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides classes for building the matrix graph. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+matrixmatrix.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes\n+provides functions for sparse matrix matrix multiplication. More...\n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::MatrixGraph<_M_>\n-\u00a0 The (undirected) graph of a matrix. More...\n+struct \u00a0Dune::MatMultMatResult<_M1,_M2_>\n+\u00a0 Helper TMP to get the result type of a sparse matrix matrix\n+ multiplication ( [$C=A*B$]) More...\n \u00a0\n-class \u00a0Dune::Amg::MatrixGraph<_M_>::EdgeIteratorT<_C_>\n-\u00a0 Iterator over all edges starting from a vertex. More...\n+struct \u00a0Dune::MatMultMatResult<_FieldMatrix<_T,_n,_k_>,_FieldMatrix<_T,_k,_m_>\n+ >\n \u00a0\n-class \u00a0Dune::Amg::MatrixGraph<_M_>::VertexIteratorT<_C_>\n-\u00a0 The vertex iterator type of the graph. More...\n+struct \u00a0Dune::MatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_n,_k_>,_A_>,\n+ BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>\n \u00a0\n-class \u00a0Dune::Amg::SubGraph<_G,_T_>\n-\u00a0 A subgraph of a graph. More...\n+struct \u00a0Dune::TransposedMatMultMatResult<_M1,_M2_>\n+\u00a0 Helper TMP to get the result type of a sparse matrix matrix\n+ multiplication ( [$C=A*B$]) More...\n \u00a0\n-class \u00a0Dune::Amg::SubGraph<_G,_T_>::EdgeIndexMap\n-\u00a0 An index map for mapping the edges to indices. More...\n+struct \u00a0Dune::TransposedMatMultMatResult<_FieldMatrix<_T,_k,_n_>,_FieldMatrix<\n+ T,_k,_m_>_>\n \u00a0\n-class \u00a0Dune::Amg::SubGraph<_G,_T_>::EdgeIterator\n-\u00a0 The edge iterator of the graph. More...\n-\u00a0\n-class \u00a0Dune::Amg::SubGraph<_G,_T_>::VertexIterator\n-\u00a0 The vertex iterator of the graph. More...\n-\u00a0\n-class \u00a0Dune::Amg::VertexPropertiesGraph<_G,_VP,_VM_>\n-\u00a0 Attaches properties to the vertices of a graph. More...\n-\u00a0\n-class \u00a0Dune::Amg::VertexPropertiesGraph<_G,_VP,_VM_>::VertexIteratorT<_C_>\n-\u00a0\n-class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>\n-\u00a0 Attaches properties to the edges and vertices of a graph. More...\n-\u00a0\n-class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>::EdgeIteratorT<_C_>\n-\u00a0\n-class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>::VertexIteratorT<_C_>\n-\u00a0\n-class \u00a0Dune::Amg::GraphVertexPropertiesSelector<_G_>\n-\u00a0 Wrapper to access the internal edge properties of a graph via operator\n- []() More...\n-\u00a0\n-class \u00a0Dune::Amg::GraphEdgePropertiesSelector<_G_>\n-\u00a0 Wrapper to access the internal vertex properties of a graph via\n- operator[]() More...\n+struct \u00a0Dune::TransposedMatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_k,_n_>,\n+ A_>,_BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n Functions\n-template\n-int\u00a0Dune::Amg::visitNeighbours (const G &graph, const typename G::\n- VertexDescriptor &vertex, V &visitor)\n-\u00a0 Visit all neighbour vertices of a vertex in a graph. More...\n+template\n+void\u00a0Dune::matMultTransposeMat (BCRSMatrix< FieldMatrix< T, n, k >, A > &res,\n+ const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix<\n+ FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n+\u00a0 Calculate product of a sparse matrix with a transposed sparse matrices (\n+ [$C=A*B^T$]). More...\n+\u00a0\n+template\n+void\u00a0Dune::matMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const\n+ BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix<\n+ FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n+\u00a0 Calculate product of two sparse matrices ( [$C=A*B$]). More...\n+\u00a0\n+template\n+void\u00a0Dune::transposeMatMultMat (BCRSMatrix< FieldMatrix< T, n, m >, A > &res,\n+ const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix<\n+ FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)\n+\u00a0 Calculate product of a transposed sparse matrix with another sparse\n+ matrices ( [$C=A^T*B$]). More...\n \u00a0\n ***** Detailed Description *****\n-Provides classes for building the matrix graph.\n+provides functions for sparse matrix matrix multiplication.\n Author\n Markus Blatt\n-During the coarsening process in AMG the matrix graph together with the\n-dependencies, what connections in the graph are considered strong or weak, what\n-vertices are isolated, etc., have to build. This information will be contained\n-in the MatrixGraph class.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00098_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00098_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: graph.hh Source File\n+dune-istl: matrixmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -58,1779 +58,599 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n
    \n
    \n-
    graph.hh
    \n+
    matrixmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_GRAPH_HH
    \n-
    6#define DUNE_AMG_GRAPH_HH
    \n+
    5#ifndef DUNE_ISTL_MATRIXMATRIX_HH
    \n+
    6#define DUNE_ISTL_MATRIXMATRIX_HH
    \n
    7
    \n-
    8#include <cstddef>
    \n-
    9#include <algorithm>
    \n-
    10#include <vector>
    \n-
    11#include <cassert>
    \n-
    12#include <limits>
    \n-
    13#include <dune/common/typetraits.hh>
    \n-
    14#include <dune/common/iteratorfacades.hh>
    \n-\n-
    16#include <dune/common/propertymap.hh>
    \n-
    17
    \n-
    18namespace Dune
    \n-
    19{
    \n-
    20 namespace Amg
    \n-
    21 {
    \n-
    49 template<class M>
    \n-\n-
    51 {
    \n-
    52 public:
    \n-
    56 typedef M Matrix;
    \n-
    57
    \n-
    61 typedef typename std::remove_const<M>::type MutableMatrix;
    \n-
    62
    \n-
    66 typedef typename M::block_type Weight;
    \n+
    8#include <tuple>
    \n+
    9
    \n+\n+
    11#include <dune/common/fmatrix.hh>
    \n+
    12#include <dune/common/timer.hh>
    \n+
    13namespace Dune
    \n+
    14{
    \n+
    15
    \n+
    26 namespace
    \n+
    27 {
    \n+
    28
    \n+
    37 template<int b>
    \n+
    38 struct NonzeroPatternTraverser
    \n+
    39 {};
    \n+
    40
    \n+
    41
    \n+
    42 template<>
    \n+
    43 struct NonzeroPatternTraverser<0>
    \n+
    44 {
    \n+
    45 template<class T,class A1, class A2, class F, int n, int m, int k>
    \n+
    46 static void traverse(const Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>& A,
    \n+\n+
    48 F& func)
    \n+
    49 {
    \n+
    50 if(A.M()!=B.N())
    \n+
    51 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<A.M()<<"!="<<B.N());
    \n+
    52
    \n+
    53 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>::ConstRowIterator Row;
    \n+
    54 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,k>,A1>::ConstColIterator Col;
    \n+
    55 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,m>,A2>::ConstColIterator BCol;
    \n+
    56 for(Row row= A.begin(); row != A.end(); ++row) {
    \n+
    57 // Loop over all column entries
    \n+
    58 for(Col col = row->begin(); col != row->end(); ++col) {
    \n+
    59 // entry at i,k
    \n+
    60 // search for all nonzeros in row k
    \n+
    61 for(BCol bcol = B[col.index()].begin(); bcol != B[col.index()].end(); ++bcol) {
    \n+
    62 func(*col, *bcol, row.index(), bcol.index());
    \n+
    63 }
    \n+
    64 }
    \n+
    65 }
    \n+
    66 }
    \n
    67
    \n-
    73 typedef typename M::size_type VertexDescriptor;
    \n-
    74
    \n-
    80 typedef std::ptrdiff_t EdgeDescriptor;
    \n+
    68 };
    \n+
    69
    \n+
    70 template<>
    \n+
    71 struct NonzeroPatternTraverser<1>
    \n+
    72 {
    \n+
    73 template<class T, class A1, class A2, class F, int n, int m, int k>
    \n+
    74 static void traverse(const Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>& A,
    \n+\n+
    76 F& func)
    \n+
    77 {
    \n+
    78
    \n+
    79 if(A.N()!=B.N())
    \n+
    80 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<A.N()<<"!="<<B.N());
    \n
    81
    \n-
    82 enum {
    \n-
    83 /*
    \n-
    84 * @brief Whether Matrix is mutable.
    \n-
    85 */
    \n-
    86 mutableMatrix = std::is_same<M, typename std::remove_const<M>::type>::value
    \n-
    87 };
    \n-
    88
    \n-
    89
    \n-
    93 template<class C>
    \n-\n-
    95 {
    \n-
    96
    \n-
    97 public:
    \n-
    101 typedef typename std::remove_const<C>::type MutableContainer;
    \n-
    105 typedef const typename std::remove_const<C>::type ConstContainer;
    \n+
    82 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>::ConstRowIterator Row;
    \n+
    83 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,n>,A1>::ConstColIterator Col;
    \n+
    84 typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<T,k,m>,A2>::ConstColIterator BCol;
    \n+
    85
    \n+
    86 for(Row row=A.begin(); row!=A.end(); ++row) {
    \n+
    87 for(Col col=row->begin(); col!=row->end(); ++col) {
    \n+
    88 for(BCol bcol = B[row.index()].begin(); bcol != B[row.index()].end(); ++bcol) {
    \n+
    89 func(*col, *bcol, col.index(), bcol.index());
    \n+
    90 }
    \n+
    91 }
    \n+
    92 }
    \n+
    93 }
    \n+
    94 };
    \n+
    95
    \n+
    96 template<>
    \n+
    97 struct NonzeroPatternTraverser<2>
    \n+
    98 {
    \n+
    99 template<class T, class A1, class A2, class F, int n, int m, int k>
    \n+
    100 static void traverse(const BCRSMatrix<FieldMatrix<T,n,m>,A1>& mat,
    \n+
    101 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt,
    \n+
    102 F& func)
    \n+
    103 {
    \n+
    104 if(mat.M()!=matt.M())
    \n+
    105 DUNE_THROW(ISTLError, "The sizes of the matrices do not match: "<<mat.M()<<"!="<<matt.M());
    \n
    106
    \n-
    107 friend class EdgeIteratorT<MutableContainer>;
    \n-
    108 friend class EdgeIteratorT<ConstContainer>;
    \n-
    109
    \n-
    110 enum {
    \n-
    112 isMutable = std::is_same<C, MutableContainer>::value
    \n-
    113 };
    \n-
    114
    \n-
    118 typedef typename std::conditional<isMutable && C::mutableMatrix,typename Matrix::row_type::Iterator,
    \n-
    119 typename Matrix::row_type::ConstIterator>::type
    \n-\n-
    121
    \n-
    125 typedef typename std::conditional<isMutable && C::mutableMatrix,typename M::block_type,
    \n-
    126 const typename M::block_type>::type
    \n-\n-
    128
    \n-\n-
    137 const ColIterator& end, const EdgeDescriptor& edge);
    \n-
    138
    \n-\n-
    146
    \n-
    151 template<class C1>
    \n-\n-
    153
    \n-
    154 typedef typename std::conditional<std::is_same<C, typename std::remove_const<C>::type>::value && C::mutableMatrix,
    \n-
    155 typename M::block_type, const typename M::block_type>::type
    \n-\n-
    157
    \n-\n+
    107 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstRowIterator row_iterator;
    \n+
    108 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstColIterator col_iterator;
    \n+
    109 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstRowIterator row_iterator_t;
    \n+
    110 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstColIterator col_iterator_t;
    \n+
    111
    \n+
    112 for(row_iterator mrow=mat.begin(); mrow != mat.end(); ++mrow) {
    \n+
    113 //iterate over the column entries
    \n+
    114 // mt is a transposed matrix crs therefore it is treated as a ccs matrix
    \n+
    115 // and the row_iterator iterates over the columns of the transposed matrix.
    \n+
    116 // search the row of the transposed matrix for an entry with the same index
    \n+
    117 // as the mcol iterator
    \n+
    118
    \n+
    119 for(row_iterator_t mtcol=matt.begin(); mtcol != matt.end(); ++mtcol) {
    \n+
    120 //Search for col entries in mat that have a corrsponding row index in matt
    \n+
    121 // (i.e. corresponding col index in the as this is the transposed matrix
    \n+
    122 col_iterator_t mtrow=mtcol->begin();
    \n+
    123 bool funcCalled = false;
    \n+
    124 for(col_iterator mcol=mrow->begin(); mcol != mrow->end(); ++mcol) {
    \n+
    125 // search
    \n+
    126 // TODO: This should probably be substituted by a binary search
    \n+
    127 for( ; mtrow != mtcol->end(); ++mtrow)
    \n+
    128 if(mtrow.index()>=mcol.index())
    \n+
    129 break;
    \n+
    130 if(mtrow != mtcol->end() && mtrow.index()==mcol.index()) {
    \n+
    131 func(*mcol, *mtrow, mtcol.index());
    \n+
    132 funcCalled = true;
    \n+
    133 // In some cases we only search for one pair, then we break here
    \n+
    134 // and continue with the next column.
    \n+
    135 if(F::do_break)
    \n+
    136 break;
    \n+
    137 }
    \n+
    138 }
    \n+
    139 // move on with func only if func was called, otherwise they might
    \n+
    140 // get out of sync
    \n+
    141 if (funcCalled)
    \n+
    142 func.nextCol();
    \n+
    143 }
    \n+
    144 func.nextRow();
    \n+
    145 }
    \n+
    146 }
    \n+
    147 };
    \n+
    148
    \n+
    149
    \n+
    150
    \n+
    151 template<class T, class A, int n, int m>
    \n+
    152 class SparsityPatternInitializer
    \n+
    153 {
    \n+
    154 public:
    \n+
    155 enum {do_break=true};
    \n+
    156 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::CreateIterator CreateIterator;
    \n+
    157 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::size_type size_type;
    \n+
    158
    \n+
    159 SparsityPatternInitializer(CreateIterator iter)
    \n+
    160 : rowiter(iter)
    \n+
    161 {}
    \n
    162
    \n-\n-
    165
    \n-
    167 bool operator!=(const EdgeIteratorT<typename std::remove_const<C>::type>& other) const;
    \n+
    163 template<class T1, class T2>
    \n+
    164 void operator()(const T1&, const T2&, size_type j)
    \n+
    165 {
    \n+
    166 rowiter.insert(j);
    \n+
    167 }
    \n
    168
    \n-
    170 bool operator!=(const EdgeIteratorT<const typename std::remove_const<C>::type>& other) const;
    \n-
    171
    \n-
    173 bool operator==(const EdgeIteratorT<typename std::remove_const<C>::type>& other) const;
    \n-
    174
    \n-
    176 bool operator==(const EdgeIteratorT<const typename std::remove_const<C>::type>& other) const;
    \n-
    177
    \n-\n+
    169 void nextRow()
    \n+
    170 {
    \n+
    171 ++rowiter;
    \n+
    172 }
    \n+
    173 void nextCol()
    \n+
    174 {}
    \n+
    175
    \n+
    176 private:
    \n+
    177 CreateIterator rowiter;
    \n+
    178 };
    \n+
    179
    \n
    180
    \n-\n-
    183
    \n-
    185 const EdgeDescriptor& operator*() const;
    \n-
    186
    \n-\n+
    181 template<int transpose, class T, class TA, int n, int m>
    \n+
    182 class MatrixInitializer
    \n+
    183 {
    \n+
    184 public:
    \n+
    185 enum {do_break=true};
    \n+\n+\n+
    188 typedef typename Matrix::size_type size_type;
    \n
    189
    \n-
    190 private:
    \n-
    192 VertexDescriptor source_;
    \n-
    194 ColIterator block_;
    \n-
    195 /***
    \n-
    196 * @brief The column iterator positioned at the end of the row
    \n-
    197 * of vertex source_
    \n-
    198 */
    \n-
    199 ColIterator blockEnd_;
    \n-
    201 EdgeDescriptor edge_;
    \n-
    202 };
    \n-
    203
    \n-
    207 template<class C>
    \n-\n-
    209 {
    \n-
    210 public:
    \n-
    214 typedef typename std::remove_const<C>::type MutableContainer;
    \n-
    218 typedef const typename std::remove_const<C>::type ConstContainer;
    \n-
    219
    \n-
    220 friend class VertexIteratorT<MutableContainer>;
    \n-
    221 friend class VertexIteratorT<ConstContainer>;
    \n+
    190 MatrixInitializer(Matrix& A_, size_type)
    \n+
    191 : count(0), A(A_)
    \n+
    192 {}
    \n+
    193 template<class T1, class T2>
    \n+
    194 void operator()(const T1&, const T2&, int)
    \n+
    195 {
    \n+
    196 ++count;
    \n+
    197 }
    \n+
    198
    \n+
    199 void nextCol()
    \n+
    200 {}
    \n+
    201
    \n+
    202 void nextRow()
    \n+
    203 {}
    \n+
    204
    \n+
    205 std::size_t nonzeros()
    \n+
    206 {
    \n+
    207 return count;
    \n+
    208 }
    \n+
    209
    \n+
    210 template<class A1, class A2, int n2, int m2, int n3, int m3>
    \n+
    211 void initPattern(const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
    \n+
    212 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
    \n+
    213 {
    \n+
    214 SparsityPatternInitializer<T, TA, n, m> sparsity(A.createbegin());
    \n+
    215 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,sparsity);
    \n+
    216 }
    \n+
    217
    \n+
    218 private:
    \n+
    219 std::size_t count;
    \n+
    220 Matrix& A;
    \n+
    221 };
    \n
    222
    \n-
    223 enum {
    \n-
    225 isMutable = std::is_same<C, MutableContainer>::value
    \n-
    226 };
    \n-
    227
    \n-
    233 explicit VertexIteratorT(C* graph, const VertexDescriptor& current);
    \n-
    234
    \n-
    242 explicit VertexIteratorT(const VertexDescriptor& current);
    \n-
    243
    \n-\n-
    245
    \n-\n-
    251
    \n-\n-
    254
    \n-\n-
    257
    \n-\n-
    260
    \n-\n-
    263
    \n-
    264 typedef typename std::conditional<std::is_same<C, typename std::remove_const<C>::type>::value && C::mutableMatrix,
    \n-
    265 typename M::block_type, const typename M::block_type>::type
    \n-\n-\n-
    269
    \n-\n-
    275
    \n-\n-
    282
    \n-\n-
    289
    \n-
    290 private:
    \n-
    291 C* graph_;
    \n-
    292 VertexDescriptor current_;
    \n-
    293 };
    \n+
    223 template<class T, class TA, int n, int m>
    \n+
    224 class MatrixInitializer<1,T,TA,n,m>
    \n+
    225 {
    \n+
    226 public:
    \n+
    227 enum {do_break=false};
    \n+\n+\n+
    230 typedef typename Matrix::size_type size_type;
    \n+
    231
    \n+
    232 MatrixInitializer(Matrix& A_, size_type rows)
    \n+
    233 : A(A_), entries(rows)
    \n+
    234 {}
    \n+
    235
    \n+
    236 template<class T1, class T2>
    \n+
    237 void operator()(const T1&, const T2&, size_type i, size_type j)
    \n+
    238 {
    \n+
    239 entries[i].insert(j);
    \n+
    240 }
    \n+
    241
    \n+
    242 void nextCol()
    \n+
    243 {}
    \n+
    244
    \n+
    245 size_type nonzeros()
    \n+
    246 {
    \n+
    247 size_type nnz=0;
    \n+
    248 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
    \n+
    249 for(Iter iter = entries.begin(); iter != entries.end(); ++iter)
    \n+
    250 nnz+=(*iter).size();
    \n+
    251 return nnz;
    \n+
    252 }
    \n+
    253 template<class A1, class A2, int n2, int m2, int n3, int m3>
    \n+
    254 void initPattern(const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>&,
    \n+
    255 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>&)
    \n+
    256 {
    \n+
    257 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
    \n+
    258 CreateIterator citer = A.createbegin();
    \n+
    259 for(Iter iter = entries.begin(); iter != entries.end(); ++iter, ++citer) {
    \n+
    260 typedef std::set<size_t>::const_iterator SetIter;
    \n+
    261 for(SetIter index=iter->begin(); index != iter->end(); ++index)
    \n+
    262 citer.insert(*index);
    \n+
    263 }
    \n+
    264 }
    \n+
    265
    \n+
    266 private:
    \n+
    267 Matrix& A;
    \n+
    268 std::vector<std::set<size_t> > entries;
    \n+
    269 };
    \n+
    270
    \n+
    271 template<class T, class TA, int n, int m>
    \n+
    272 struct MatrixInitializer<0,T,TA,n,m>
    \n+
    273 : public MatrixInitializer<1,T,TA,n,m>
    \n+
    274 {
    \n+
    275 MatrixInitializer(Dune::BCRSMatrix<Dune::FieldMatrix<T,n,m>,TA>& A_,
    \n+
    276 typename Dune::BCRSMatrix<Dune::FieldMatrix<T,n,m>,TA>::size_type rows)
    \n+
    277 : MatrixInitializer<1,T,TA,n,m>(A_,rows)
    \n+
    278 {}
    \n+
    279 };
    \n+
    280
    \n+
    281
    \n+
    282 template<class T, class T1, class T2, int n, int m, int k>
    \n+
    283 void addMatMultTransposeMat(FieldMatrix<T,n,k>& res, const FieldMatrix<T1,n,m>& mat,
    \n+
    284 const FieldMatrix<T2,k,m>& matt)
    \n+
    285 {
    \n+
    286 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n+
    287
    \n+
    288 for(size_type row=0; row<n; ++row)
    \n+
    289 for(size_type col=0; col<k; ++col) {
    \n+
    290 for(size_type i=0; i < m; ++i)
    \n+
    291 res[row][col]+=mat[row][i]*matt[col][i];
    \n+
    292 }
    \n+
    293 }
    \n
    294
    \n-\n-
    299
    \n-\n-
    304
    \n-\n-
    309
    \n-\n-
    314
    \n-\n-
    320
    \n-\n-
    325
    \n-\n-
    331
    \n-\n-
    337
    \n-\n-
    343
    \n-\n-
    349
    \n-\n-
    357
    \n-\n+
    295 template<class T, class T1, class T2, int n, int m, int k>
    \n+
    296 void addTransposeMatMultMat(FieldMatrix<T,n,k>& res, const FieldMatrix<T1,m,n>& mat,
    \n+
    297 const FieldMatrix<T2,m,k>& matt)
    \n+
    298 {
    \n+
    299 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n+
    300 for(size_type i=0; i<m; ++i)
    \n+
    301 for(size_type row=0; row<n; ++row) {
    \n+
    302 for(size_type col=0; col < k; ++col)
    \n+
    303 res[row][col]+=mat[i][row]*matt[i][col];
    \n+
    304 }
    \n+
    305 }
    \n+
    306
    \n+
    307 template<class T, class T1, class T2, int n, int m, int k>
    \n+
    308 void addMatMultMat(FieldMatrix<T,n,m>& res, const FieldMatrix<T1,n,k>& mat,
    \n+
    309 const FieldMatrix<T2,k,m>& matt)
    \n+
    310 {
    \n+
    311 typedef typename FieldMatrix<T,n,k>::size_type size_type;
    \n+
    312 for(size_type row=0; row<n; ++row)
    \n+
    313 for(size_type col=0; col<m; ++col) {
    \n+
    314 for(size_type i=0; i < k; ++i)
    \n+
    315 res[row][col]+=mat[row][i]*matt[i][col];
    \n+
    316 }
    \n+
    317 }
    \n+
    318
    \n+
    319
    \n+
    320 template<class T, class A, int n, int m>
    \n+
    321 class EntryAccumulatorFather
    \n+
    322 {
    \n+
    323 public:
    \n+
    324 enum {do_break=false};
    \n+\n+
    326 typedef typename Matrix::RowIterator Row;
    \n+
    327 typedef typename Matrix::ColIterator Col;
    \n+
    328
    \n+
    329 EntryAccumulatorFather(Matrix& mat_)
    \n+
    330 : mat(mat_), row(mat.begin())
    \n+
    331 {
    \n+
    332 mat=0;
    \n+
    333 col=row->begin();
    \n+
    334 }
    \n+
    335 void nextRow()
    \n+
    336 {
    \n+
    337 ++row;
    \n+
    338 if(row!=mat.end())
    \n+
    339 col=row->begin();
    \n+
    340 }
    \n+
    341
    \n+
    342 void nextCol()
    \n+
    343 {
    \n+
    344 ++this->col;
    \n+
    345 }
    \n+
    346 protected:
    \n+
    347 Matrix& mat;
    \n+
    348 private:
    \n+
    349 Row row;
    \n+
    350 protected:
    \n+\n+
    352 };
    \n+
    353
    \n+
    354 template<class T, class A, int n, int m, int transpose>
    \n+
    355 class EntryAccumulator
    \n+
    356 : public EntryAccumulatorFather<T,A,n,m>
    \n+
    357 {
    \n+
    358 public:
    \n+\n+
    360 typedef typename Matrix::size_type size_type;
    \n+
    361
    \n+
    362 EntryAccumulator(Matrix& mat_)
    \n+
    363 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n+
    364 {}
    \n
    365
    \n-
    366
    \n-\n-
    374
    \n-\n-
    382
    \n-\n-
    388
    \n-
    393 const Matrix& matrix() const;
    \n-
    394
    \n-
    398 std::size_t noVertices() const;
    \n-
    399
    \n-\n-
    407
    \n-
    411 std::size_t noEdges() const;
    \n-
    412
    \n-\n-
    420 const VertexDescriptor& target) const;
    \n-
    421
    \n-
    422 private:
    \n-
    424 Matrix& matrix_;
    \n-
    426 EdgeDescriptor* start_;
    \n-
    428 MatrixGraph(const MatrixGraph&);
    \n-
    429
    \n+
    366 template<class T1, class T2>
    \n+
    367 void operator()(const T1& t1, const T2& t2, size_type i)
    \n+
    368 {
    \n+
    369 assert(this->col.index()==i);
    \n+
    370 addMatMultMat(*(this->col),t1,t2);
    \n+
    371 }
    \n+
    372 };
    \n+
    373
    \n+
    374 template<class T, class A, int n, int m>
    \n+
    375 class EntryAccumulator<T,A,n,m,0>
    \n+
    376 : public EntryAccumulatorFather<T,A,n,m>
    \n+
    377 {
    \n+
    378 public:
    \n+\n+
    380 typedef typename Matrix::size_type size_type;
    \n+
    381
    \n+
    382 EntryAccumulator(Matrix& mat_)
    \n+
    383 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n+
    384 {}
    \n+
    385
    \n+
    386 template<class T1, class T2>
    \n+
    387 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)
    \n+
    388 {
    \n+
    389 addMatMultMat(this->mat[i][j], t1, t2);
    \n+
    390 }
    \n+
    391 };
    \n+
    392
    \n+
    393 template<class T, class A, int n, int m>
    \n+
    394 class EntryAccumulator<T,A,n,m,1>
    \n+
    395 : public EntryAccumulatorFather<T,A,n,m>
    \n+
    396 {
    \n+
    397 public:
    \n+\n+
    399 typedef typename Matrix::size_type size_type;
    \n+
    400
    \n+
    401 EntryAccumulator(Matrix& mat_)
    \n+
    402 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n+
    403 {}
    \n+
    404
    \n+
    405 template<class T1, class T2>
    \n+
    406 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)
    \n+
    407 {
    \n+
    408 addTransposeMatMultMat(this->mat[i][j], t1, t2);
    \n+
    409 }
    \n+
    410 };
    \n+
    411
    \n+
    412 template<class T, class A, int n, int m>
    \n+
    413 class EntryAccumulator<T,A,n,m,2>
    \n+
    414 : public EntryAccumulatorFather<T,A,n,m>
    \n+
    415 {
    \n+
    416 public:
    \n+\n+
    418 typedef typename Matrix::size_type size_type;
    \n+
    419
    \n+
    420 EntryAccumulator(Matrix& mat_)
    \n+
    421 : EntryAccumulatorFather<T,A,n,m>(mat_)
    \n+
    422 {}
    \n+
    423
    \n+
    424 template<class T1, class T2>
    \n+
    425 void operator()(const T1& t1, const T2& t2, [[maybe_unused]] size_type i)
    \n+
    426 {
    \n+
    427 assert(this->col.index()==i);
    \n+
    428 addMatMultTransposeMat(*this->col,t1,t2);
    \n+
    429 }
    \n
    430 };
    \n
    431
    \n-
    441 template<class G, class T>
    \n-\n-
    443 {
    \n-
    444 public:
    \n-
    448 typedef G Graph;
    \n-
    449
    \n-
    454 typedef T Excluded;
    \n-
    455
    \n-
    459 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n-
    460
    \n-\n-
    462
    \n-\n-
    470 {
    \n-
    471 public:
    \n-
    472 typedef ReadablePropertyMapTag Category;
    \n-
    473
    \n-
    474 EdgeIndexMap(const EdgeDescriptor& firstEdge)
    \n-
    475 : firstEdge_(firstEdge)
    \n-
    476 {}
    \n-
    477
    \n-\n-
    480 : firstEdge_(emap.firstEdge_)
    \n-
    481 {}
    \n-
    482
    \n-
    483 std::size_t operator[](const EdgeDescriptor& edge) const
    \n-
    484 {
    \n-
    485 return edge-firstEdge_;
    \n-
    486 }
    \n-
    487 private:
    \n-
    489 EdgeDescriptor firstEdge_;
    \n-\n-
    492 {}
    \n-
    493 };
    \n-
    494
    \n-\n+
    432
    \n+
    433 template<int transpose>
    \n+
    434 struct SizeSelector
    \n+
    435 {};
    \n+
    436
    \n+
    437 template<>
    \n+
    438 struct SizeSelector<0>
    \n+
    439 {
    \n+
    440 template<class M1, class M2>
    \n+
    441 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n+
    442 size(const M1& m1, const M2& m2)
    \n+
    443 {
    \n+
    444 return std::make_tuple(m1.N(), m2.M());
    \n+
    445 }
    \n+
    446 };
    \n+
    447
    \n+
    448 template<>
    \n+
    449 struct SizeSelector<1>
    \n+
    450 {
    \n+
    451 template<class M1, class M2>
    \n+
    452 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n+
    453 size(const M1& m1, const M2& m2)
    \n+
    454 {
    \n+
    455 return std::make_tuple(m1.M(), m2.M());
    \n+
    456 }
    \n+
    457 };
    \n+
    458
    \n+
    459
    \n+
    460 template<>
    \n+
    461 struct SizeSelector<2>
    \n+
    462 {
    \n+
    463 template<class M1, class M2>
    \n+
    464 static std::tuple<typename M1::size_type, typename M2::size_type>
    \n+
    465 size(const M1& m1, const M2& m2)
    \n+
    466 {
    \n+
    467 return std::make_tuple(m1.N(), m2.N());
    \n+
    468 }
    \n+
    469 };
    \n+
    470
    \n+
    471 template<int transpose, class T, class A, class A1, class A2, int n1, int m1, int n2, int m2, int n3, int m3>
    \n+
    472 void matMultMat(BCRSMatrix<FieldMatrix<T,n1,m1>,A>& res, const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
    \n+
    473 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
    \n+
    474 {
    \n+
    475 // First step is to count the number of nonzeros
    \n+
    476 typename BCRSMatrix<FieldMatrix<T,n1,m1>,A>::size_type rows, cols;
    \n+
    477 std::tie(rows,cols)=SizeSelector<transpose>::size(mat1, mat2);
    \n+
    478 MatrixInitializer<transpose,T,A,n1,m1> patternInit(res, rows);
    \n+
    479 Timer timer;
    \n+
    480 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,patternInit);
    \n+
    481 res.setSize(rows, cols, patternInit.nonzeros());
    \n+
    482 res.setBuildMode(BCRSMatrix<FieldMatrix<T,n1,m1>,A>::row_wise);
    \n+
    483
    \n+
    484 //std::cout<<"Counting nonzeros took "<<timer.elapsed()<<std::endl;
    \n+
    485 timer.reset();
    \n+
    486
    \n+
    487 // Second step is to allocate the storage for the result and initialize the nonzero pattern
    \n+
    488 patternInit.initPattern(mat1, mat2);
    \n+
    489
    \n+
    490 //std::cout<<"Setting up sparsity pattern took "<<timer.elapsed()<<std::endl;
    \n+
    491 timer.reset();
    \n+
    492 // As a last step calculate the entries
    \n+
    493 res = 0.0;
    \n+
    494 EntryAccumulator<T,A,n1,m1, transpose> entriesAccu(res);
    \n+
    495 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,entriesAccu);
    \n+
    496 //std::cout<<"Calculating entries took "<<timer.elapsed()<<std::endl;
    \n+
    497 }
    \n+
    498
    \n+
    499 }
    \n
    500
    \n-
    504 class EdgeIterator : public RandomAccessIteratorFacade<EdgeIterator,const EdgeDescriptor>
    \n-
    505 {
    \n-
    506 public:
    \n-
    512 explicit EdgeIterator(const VertexDescriptor& source, const EdgeDescriptor& edge);
    \n-
    513
    \n-
    521 explicit EdgeIterator(const EdgeDescriptor& edge);
    \n-
    522
    \n-
    524 bool equals(const EdgeIterator& other) const;
    \n+
    508 template<typename M1, typename M2>
    \n+\n+
    510 {};
    \n+
    511
    \n+
    512 template<typename T, int n, int k, int m>
    \n+\n+
    514 {
    \n+\n+
    516 };
    \n+
    517
    \n+
    518 template<typename T, typename A, typename A1, int n, int k, int m>
    \n+\n+
    520 {
    \n+\n+
    522 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
    \n+
    523 };
    \n+
    524
    \n
    525
    \n-\n-
    528
    \n-\n-
    531
    \n-
    532 EdgeIterator& advance(std::ptrdiff_t n);
    \n-
    533
    \n-\n+
    533 template<typename M1, typename M2>
    \n+\n+
    535 {};
    \n
    536
    \n-
    538 const VertexDescriptor& target() const;
    \n-
    539
    \n-
    541 const VertexDescriptor& source() const;
    \n+
    537 template<typename T, int n, int k, int m>
    \n+\n+
    539 {
    \n+\n+
    541 };
    \n
    542
    \n-
    543 std::ptrdiff_t distanceTo(const EdgeIterator& other) const;
    \n-
    544
    \n-
    545 private:
    \n-
    547 VertexDescriptor source_;
    \n-
    552 EdgeDescriptor edge_;
    \n-
    553 };
    \n-
    554
    \n-\n-
    559 : public ForwardIteratorFacade<VertexIterator,const VertexDescriptor>
    \n-
    560 {
    \n-
    561 public:
    \n-
    568 explicit VertexIterator(const SubGraph<G,T>* graph, const VertexDescriptor& current,
    \n-
    569 const VertexDescriptor& end);
    \n-
    570
    \n-
    571
    \n-
    578 explicit VertexIterator(const VertexDescriptor& current);
    \n-
    579
    \n-\n-
    582
    \n-
    584 bool equals(const VertexIterator& other) const;
    \n-
    585
    \n-\n-
    591
    \n-\n-
    598
    \n-\n-
    605
    \n-
    606 private:
    \n-
    608 const SubGraph<Graph,T>* graph_;
    \n-
    610 VertexDescriptor current_;
    \n-
    612 VertexDescriptor end_;
    \n-
    613 };
    \n-
    614
    \n-\n-
    619
    \n-\n-
    624
    \n-\n-
    630
    \n-\n-
    636
    \n-\n-
    644
    \n-\n-
    652
    \n-
    656 std::size_t noVertices() const;
    \n-
    657
    \n-\n-
    665
    \n-
    669 std::size_t noEdges() const;
    \n-\n-
    677 const VertexDescriptor& target) const;
    \n-
    685 SubGraph(const Graph& graph, const T& excluded);
    \n-
    686
    \n-\n-
    691
    \n-
    692 private:
    \n-
    694 const T& excluded_;
    \n-
    696 std::size_t noVertices_;
    \n-
    698 VertexDescriptor endVertex_;
    \n-
    700 int noEdges_;
    \n-
    705 VertexDescriptor maxVertex_;
    \n-
    707 VertexDescriptor* edges_;
    \n-
    709 std::ptrdiff_t* start_;
    \n-
    711 std::ptrdiff_t* end_;
    \n-
    713 SubGraph(const SubGraph&)
    \n-
    714 {}
    \n-
    715 };
    \n-
    716
    \n-
    717
    \n-
    721 template<class G, class VP, class VM=IdentityMap>
    \n-\n-
    723 {
    \n-
    724 public:
    \n-
    728 typedef G Graph;
    \n-
    729
    \n-
    733 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n-
    734
    \n-
    738 typedef typename Graph::EdgeDescriptor EdgeDescriptor;
    \n-
    739
    \n-\n-
    744
    \n-
    756 typedef VM VertexMap;
    \n-
    757
    \n-
    761 typedef typename Graph::EdgeIterator EdgeIterator;
    \n-
    762
    \n-
    766 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;
    \n-
    767
    \n-\n-
    774
    \n-\n-
    781
    \n-\n-
    788
    \n-\n-
    795
    \n-
    796
    \n-
    797 template<class C>
    \n-\n-
    799 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    800 C>::value,
    \n-
    801 typename Graph::VertexIterator,
    \n-
    802 typename Graph::ConstVertexIterator>::type
    \n-
    803 {
    \n-
    804 friend class VertexIteratorT<const typename std::remove_const<C>::type>;
    \n-
    805 friend class VertexIteratorT<typename std::remove_const<C>::type>;
    \n-
    806 public:
    \n-
    810 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    811 C>::value,
    \n-
    812 typename Graph::VertexIterator,
    \n-
    813 typename Graph::ConstVertexIterator>::type
    \n-\n-
    815
    \n-
    819 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    820 C>::value,
    \n-
    821 typename Graph::EdgeIterator,
    \n-
    822 typename Graph::ConstEdgeIterator>::type
    \n-\n-
    824
    \n-
    830 explicit VertexIteratorT(const Father& iter,
    \n-
    831 C* graph);
    \n-
    832
    \n-
    833
    \n-
    841 explicit VertexIteratorT(const Father& iter);
    \n-
    842
    \n-
    847 template<class C1>
    \n-
    848 VertexIteratorT(const VertexIteratorT<C1>& other);
    \n-
    849
    \n-
    853 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n-
    854 VertexProperties&,
    \n-
    855 const VertexProperties&>::type
    \n-
    856 properties() const;
    \n-
    857
    \n-\n-
    864
    \n-\n-
    871
    \n-
    872 private:
    \n-
    876 C* graph_;
    \n-
    877 };
    \n-
    878
    \n-
    882 typedef VertexIteratorT<VertexPropertiesGraph<Graph,
    \n-
    883 VertexProperties,VM> > VertexIterator;
    \n-
    884
    \n-
    888 typedef VertexIteratorT<const VertexPropertiesGraph<Graph,
    \n-
    889 VertexProperties,VM> > ConstVertexIterator;
    \n-
    890
    \n-\n-
    896
    \n-\n-
    902
    \n-\n-
    908
    \n-\n-
    914
    \n-
    920 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);
    \n-
    921
    \n-
    927 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex) const;
    \n-
    928
    \n-
    933 const Graph& graph() const;
    \n-
    934
    \n-
    938 std::size_t noVertices() const;
    \n-
    939
    \n-
    943 std::size_t noEdges() const;
    \n-
    944
    \n-\n-
    952
    \n-
    958 VertexPropertiesGraph(Graph& graph, const VertexMap vmap=VertexMap());
    \n-
    959
    \n-
    960 private:
    \n-
    961 VertexPropertiesGraph(const VertexPropertiesGraph&)
    \n-
    962 {}
    \n-
    963
    \n-
    965 Graph& graph_;
    \n-
    967 VertexMap vmap_;
    \n-
    969 std::vector<VertexProperties> vertexProperties_;
    \n-
    970
    \n-
    971 };
    \n-
    972
    \n-
    976 template<class G, class VP, class EP, class VM=IdentityMap, class EM=IdentityMap>
    \n-\n-
    978 {
    \n-
    979 public:
    \n-
    983 typedef G Graph;
    \n-
    984
    \n-
    988 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n-
    989
    \n-
    993 typedef typename Graph::EdgeDescriptor EdgeDescriptor;
    \n-
    994
    \n-\n-
    999
    \n-
    1011 typedef VM VertexMap;
    \n-
    1012
    \n-
    1016 typedef EP EdgeProperties;
    \n-
    1017
    \n-
    1018
    \n-
    1030 typedef EM EdgeMap;
    \n-
    1031
    \n-
    1032 template<class C>
    \n-\n-
    1034 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    1035 C>::value,
    \n-
    1036 typename Graph::EdgeIterator,
    \n-
    1037 typename Graph::ConstEdgeIterator>::type
    \n-
    1038 {
    \n-
    1039
    \n-
    1040 friend class EdgeIteratorT<const typename std::remove_const<C>::type>;
    \n-
    1041 friend class EdgeIteratorT<typename std::remove_const<C>::type>;
    \n-
    1042 public:
    \n-
    1046 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    1047 C>::value,
    \n-
    1048 typename Graph::EdgeIterator,
    \n-
    1049 typename Graph::ConstEdgeIterator>::type
    \n-\n-
    1051
    \n-
    1057 explicit EdgeIteratorT(const Father& iter,
    \n-
    1058 C* graph);
    \n-
    1059
    \n-
    1067 explicit EdgeIteratorT(const Father& iter);
    \n-
    1068
    \n-
    1073 template<class C1>
    \n-
    1074 EdgeIteratorT(const EdgeIteratorT<C1>& other);
    \n-
    1075
    \n-
    1079 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n-
    1080 EdgeProperties&,
    \n-
    1081 const EdgeProperties&>::type
    \n-
    1082 properties() const;
    \n-
    1083
    \n-
    1084 private:
    \n-
    1088 C* graph_;
    \n-
    1089 };
    \n-
    1090
    \n-
    1094 typedef EdgeIteratorT<PropertiesGraph<Graph,
    \n-
    1095 VertexProperties,
    \n-
    1096 EdgeProperties,VM,EM> > EdgeIterator;
    \n-
    1097
    \n-
    1101 typedef EdgeIteratorT<const PropertiesGraph<Graph,
    \n-
    1102 VertexProperties,
    \n-
    1103 EdgeProperties,VM,EM> > ConstEdgeIterator;
    \n-
    1104
    \n-
    1110 EdgeIterator beginEdges(const VertexDescriptor& source);
    \n-
    1111
    \n-
    1117 EdgeIterator endEdges(const VertexDescriptor& source);
    \n-
    1118
    \n-
    1124 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;
    \n-
    1125
    \n-
    1131 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;
    \n-
    1132
    \n-
    1133
    \n-
    1134 template<class C>
    \n-\n-
    1136 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    1137 C>::value,
    \n-
    1138 typename Graph::VertexIterator,
    \n-
    1139 typename Graph::ConstVertexIterator>::type
    \n-
    1140 {
    \n-
    1141 friend class VertexIteratorT<const typename std::remove_const<C>::type>;
    \n-
    1142 friend class VertexIteratorT<typename std::remove_const<C>::type>;
    \n-
    1143 public:
    \n-
    1147 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    1148 C>::value,
    \n-
    1149 typename Graph::VertexIterator,
    \n-
    1150 typename Graph::ConstVertexIterator>::type
    \n-\n-
    1152
    \n-
    1158 explicit VertexIteratorT(const Father& iter,
    \n-
    1159 C* graph);
    \n-
    1160
    \n-
    1161
    \n-
    1169 explicit VertexIteratorT(const Father& iter);
    \n-
    1170
    \n-
    1175 template<class C1>
    \n-
    1176 VertexIteratorT(const VertexIteratorT<C1>& other);
    \n-
    1177
    \n-
    1181 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n-
    1182 VertexProperties&,
    \n-
    1183 const VertexProperties&>::type
    \n-
    1184 properties() const;
    \n-
    1185
    \n-\n-
    1192
    \n-
    1198 EdgeIteratorT<C> end() const;
    \n-
    1199
    \n-
    1200 private:
    \n-
    1204 C* graph_;
    \n-
    1205 };
    \n-
    1206
    \n-
    1210 typedef VertexIteratorT<PropertiesGraph<Graph,
    \n-
    1211 VertexProperties,
    \n-
    1212 EdgeProperties,VM,EM> > VertexIterator;
    \n-
    1213
    \n-
    1217 typedef VertexIteratorT<const PropertiesGraph<Graph,
    \n-
    1218 VertexProperties,
    \n-
    1219 EdgeProperties,VM,EM> > ConstVertexIterator;
    \n-
    1220
    \n-\n-
    1226
    \n-\n-
    1232
    \n-\n-
    1238
    \n-\n-
    1244
    \n-
    1250 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);
    \n-
    1251
    \n-
    1257 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex) const;
    \n-
    1258
    \n-
    1265 EdgeDescriptor findEdge(const VertexDescriptor& source,
    \n-
    1266 const VertexDescriptor& target)
    \n-
    1267 {
    \n-
    1268 return graph_.findEdge(source,target);
    \n-
    1269 }
    \n-
    1270
    \n-\n-
    1277
    \n-
    1278
    \n-\n-
    1285
    \n-\n-
    1293 const VertexDescriptor& target);
    \n-
    1294
    \n-\n-
    1302 const VertexDescriptor& target) const;
    \n-
    1303
    \n-
    1308 const Graph& graph() const;
    \n-
    1309
    \n-
    1313 std::size_t noVertices() const;
    \n-
    1314
    \n-
    1318 std::size_t noEdges() const;
    \n-
    1319
    \n-\n-
    1327
    \n-\n-
    1335 const EdgeMap& emap=EdgeMap());
    \n-
    1336
    \n-
    1337 private:
    \n-\n-
    1339 {}
    \n-
    1340
    \n-
    1342 Graph& graph_;
    \n-
    1345 VertexMap vmap_;
    \n-
    1346 std::vector<VertexProperties> vertexProperties_;
    \n-
    1348 EdgeMap emap_;
    \n-
    1350 std::vector<EdgeProperties> edgeProperties_;
    \n-
    1351
    \n-
    1352 };
    \n-
    1353
    \n-
    1354
    \n-
    1359 template<typename G>
    \n-\n-
    1361 {
    \n-
    1362 public:
    \n-
    1366 typedef G Graph;
    \n-
    1370 typedef typename G::VertexProperties VertexProperties;
    \n-
    1374 typedef typename G::VertexDescriptor Vertex;
    \n-
    1375
    \n-\n-
    1381 : graph_(g)
    \n-
    1382 {}
    \n-\n-
    1387 : graph_(0)
    \n-
    1388 {}
    \n-
    1389
    \n-
    1390
    \n-
    1395 VertexProperties& operator[](const Vertex& vertex) const
    \n-
    1396 {
    \n-
    1397 return graph_->getVertexProperties(vertex);
    \n-
    1398 }
    \n-
    1399 private:
    \n-
    1400 Graph* graph_;
    \n-
    1401 };
    \n-
    1402
    \n-
    1407 template<typename G>
    \n-\n-
    1409 {
    \n-
    1410 public:
    \n-
    1414 typedef G Graph;
    \n-
    1418 typedef typename G::EdgeProperties EdgeProperties;
    \n-
    1422 typedef typename G::EdgeDescriptor Edge;
    \n-
    1423
    \n-\n-
    1429 : graph_(g)
    \n-
    1430 {}
    \n-\n-
    1435 : graph_(0)
    \n-
    1436 {}
    \n-
    1437
    \n-
    1442 EdgeProperties& operator[](const Edge& edge) const
    \n-
    1443 {
    \n-
    1444 return graph_->getEdgeProperties(edge);
    \n-
    1445 }
    \n-
    1446 private:
    \n-
    1447 Graph* graph_;
    \n-
    1448 };
    \n-
    1449
    \n-
    1450
    \n-
    1461 template<class G, class V>
    \n-
    1462 int visitNeighbours(const G& graph, const typename G::VertexDescriptor& vertex,
    \n-
    1463 V& visitor);
    \n-
    1464
    \n-
    1465#ifndef DOXYGEN
    \n-
    1466
    \n-
    1467 template<class M>
    \n-\n-
    1469 : matrix_(matrix)
    \n-
    1470 {
    \n-
    1471 if(matrix_.N()!=matrix_.M())
    \n-
    1472 DUNE_THROW(ISTLError, "Matrix has to have as many columns as rows!");
    \n-
    1473
    \n-
    1474 start_ = new EdgeDescriptor[matrix_.N()+1];
    \n-
    1475
    \n-
    1476 typedef typename M::ConstIterator Iterator;
    \n-
    1477 start_[matrix_.begin().index()] = 0;
    \n-
    1478
    \n-
    1479 for(Iterator row=matrix_.begin(); row != matrix_.end(); ++row)
    \n-
    1480 start_[row.index()+1] = start_[row.index()] + row->size();
    \n-
    1481 }
    \n-
    1482
    \n-
    1483 template<class M>
    \n-
    1484 MatrixGraph<M>::~MatrixGraph()
    \n-
    1485 {
    \n-
    1486 delete[] start_;
    \n-
    1487 }
    \n-
    1488
    \n-
    1489 template<class M>
    \n-
    1490 inline std::size_t MatrixGraph<M>::noEdges() const
    \n-
    1491 {
    \n-
    1492 return start_[matrix_.N()];
    \n-
    1493 }
    \n-
    1494
    \n-
    1495 template<class M>
    \n-
    1496 inline std::size_t MatrixGraph<M>::noVertices() const
    \n-
    1497 {
    \n-
    1498 return matrix_.N();
    \n-
    1499 }
    \n-
    1500
    \n-
    1501 template<class M>
    \n-
    1502 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::maxVertex() const
    \n-
    1503 {
    \n-
    1504 return matrix_.N()-1;
    \n-
    1505 }
    \n-
    1506
    \n-
    1507 template<class M>
    \n-
    1508 typename MatrixGraph<M>::EdgeDescriptor
    \n-
    1509 MatrixGraph<M>::findEdge(const VertexDescriptor& source,
    \n-
    1510 const VertexDescriptor& target) const
    \n-
    1511 {
    \n-
    1512 typename M::ConstColIterator found =matrix_[source].find(target);
    \n-
    1513 if(found == matrix_[source].end())
    \n-
    1514 return std::numeric_limits<EdgeDescriptor>::max();
    \n-
    1515 std::size_t offset = found.offset();
    \n-
    1516 if(target>source)
    \n-
    1517 offset--;
    \n-
    1518
    \n-
    1519 assert(offset<noEdges());
    \n-
    1520
    \n-
    1521 return start_[source]+offset;
    \n-
    1522 }
    \n-
    1523
    \n-
    1524
    \n-
    1525 template<class M>
    \n-
    1526 inline M& MatrixGraph<M>::matrix()
    \n-
    1527 {
    \n-
    1528 return matrix_;
    \n-
    1529 }
    \n-
    1530
    \n-
    1531 template<class M>
    \n-
    1532 inline const M& MatrixGraph<M>::matrix() const
    \n-
    1533 {
    \n-
    1534 return matrix_;
    \n-
    1535 }
    \n-
    1536
    \n-
    1537 template<class M>
    \n-
    1538 template<class C>
    \n-
    1539 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const VertexDescriptor& source, const ColIterator& block,
    \n-
    1540 const ColIterator& end, const EdgeDescriptor& edge)
    \n-
    1541 : source_(source), block_(block), blockEnd_(end), edge_(edge)
    \n-
    1542 {
    \n-
    1543 if(block_!=blockEnd_ && block_.index() == source_) {
    \n-
    1544 // This is the edge from the diagonal to the diagonal. Skip it.
    \n-
    1545 ++block_;
    \n-
    1546 }
    \n-
    1547 }
    \n-
    1548
    \n-
    1549 template<class M>
    \n-
    1550 template<class C>
    \n-
    1551 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const ColIterator& block)
    \n-
    1552 : block_(block)
    \n-
    1553 {}
    \n-
    1554
    \n-
    1555 template<class M>
    \n-
    1556 template<class C>
    \n-
    1557 template<class C1>
    \n-
    1558 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const EdgeIteratorT<C1>& other)
    \n-
    1559 : source_(other.source_), block_(other.block_), blockEnd_(other.blockEnd_), edge_(other.edge_)
    \n-
    1560 {}
    \n-
    1561
    \n-
    1562
    \n-
    1563 template<class M>
    \n-
    1564 template<class C>
    \n-
    1565 inline typename MatrixGraph<M>::template EdgeIteratorT<C>::WeightType&
    \n-
    1566 MatrixGraph<M>::EdgeIteratorT<C>::weight() const
    \n-
    1567 {
    \n-
    1568 return *block_;
    \n-
    1569 }
    \n-
    1570
    \n-
    1571 template<class M>
    \n-
    1572 template<class C>
    \n-
    1573 inline typename MatrixGraph<M>::template EdgeIteratorT<C>& MatrixGraph<M>::EdgeIteratorT<C>::operator++()
    \n-
    1574 {
    \n-
    1575 ++block_;
    \n-
    1576 ++edge_;
    \n-
    1577
    \n-
    1578 if(block_!=blockEnd_ && block_.index() == source_) {
    \n-
    1579 // This is the edge from the diagonal to the diagonal. Skip it.
    \n-
    1580 ++block_;
    \n-
    1581 }
    \n-
    1582
    \n-
    1583 return *this;
    \n-
    1584 }
    \n-
    1585
    \n-
    1586 template<class M>
    \n-
    1587 template<class C>
    \n-
    1588 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator!=(const typename MatrixGraph<M>::template EdgeIteratorT<typename std::remove_const<C>::type>& other) const
    \n-
    1589 {
    \n-
    1590 return block_!=other.block_;
    \n-
    1591 }
    \n-
    1592
    \n-
    1593 template<class M>
    \n-
    1594 template<class C>
    \n-
    1595 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator!=(const typename MatrixGraph<M>::template EdgeIteratorT<const typename std::remove_const<C>::type>& other) const
    \n-
    1596 {
    \n-
    1597 return block_!=other.block_;
    \n-
    1598 }
    \n-
    1599
    \n-
    1600 template<class M>
    \n-
    1601 template<class C>
    \n-
    1602 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator==(const typename MatrixGraph<M>::template EdgeIteratorT<typename std::remove_const<C>::type>& other) const
    \n-
    1603 {
    \n-
    1604 return block_==other.block_;
    \n-
    1605 }
    \n-
    1606
    \n-
    1607 template<class M>
    \n-
    1608 template<class C>
    \n-
    1609 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator==(const typename MatrixGraph<M>::template EdgeIteratorT<const typename std::remove_const<C>::type>& other) const
    \n-
    1610 {
    \n-
    1611 return block_==other.block_;
    \n-
    1612 }
    \n-
    1613
    \n-
    1614 template<class M>
    \n-
    1615 template<class C>
    \n-
    1616 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::EdgeIteratorT<C>::target() const
    \n-
    1617 {
    \n-
    1618 return block_.index();
    \n-
    1619 }
    \n-
    1620
    \n-
    1621 template<class M>
    \n-
    1622 template<class C>
    \n-
    1623 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::EdgeIteratorT<C>::source() const
    \n-
    1624 {
    \n-
    1625 return source_;
    \n-
    1626 }
    \n-
    1627
    \n-
    1628 template<class M>
    \n-
    1629 template<class C>
    \n-
    1630 inline const typename MatrixGraph<M>::EdgeDescriptor& MatrixGraph<M>::EdgeIteratorT<C>::operator*() const
    \n-
    1631 {
    \n-
    1632 return edge_;
    \n-
    1633 }
    \n-
    1634
    \n-
    1635 template<class M>
    \n-
    1636 template<class C>
    \n-
    1637 inline const typename MatrixGraph<M>::EdgeDescriptor* MatrixGraph<M>::EdgeIteratorT<C>::operator->() const
    \n-
    1638 {
    \n-
    1639 return &edge_;
    \n-
    1640 }
    \n-
    1641
    \n-
    1642 template<class M>
    \n-
    1643 template<class C>
    \n-
    1644 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(C* graph,
    \n-
    1645 const VertexDescriptor& current)
    \n-
    1646 : graph_(graph), current_(current)
    \n-
    1647 {}
    \n-
    1648
    \n-
    1649
    \n-
    1650 template<class M>
    \n-
    1651 template<class C>
    \n-
    1652 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(const VertexDescriptor& current)
    \n-
    1653 : current_(current)
    \n-
    1654 {}
    \n-
    1655
    \n-
    1656 template<class M>
    \n-
    1657 template<class C>
    \n-
    1658 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(const VertexIteratorT<MutableContainer>& other)
    \n-
    1659 : graph_(other.graph_), current_(other.current_)
    \n-
    1660 {}
    \n-
    1661
    \n-
    1662 template<class M>
    \n-
    1663 template<class C>
    \n-
    1664 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator!=(const VertexIteratorT<MutableContainer>& other) const
    \n-
    1665 {
    \n-
    1666 return current_ != other.current_;
    \n-
    1667 }
    \n-
    1668
    \n-
    1669 template<class M>
    \n-
    1670 template<class C>
    \n-
    1671 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator!=(const VertexIteratorT<ConstContainer>& other) const
    \n-
    1672 {
    \n-
    1673 return current_ != other.current_;
    \n-
    1674 }
    \n-
    1675
    \n-
    1676
    \n-
    1677 template<class M>
    \n-
    1678 template<class C>
    \n-
    1679 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator==(const VertexIteratorT<MutableContainer>& other) const
    \n-
    1680 {
    \n-
    1681 return current_ == other.current_;
    \n-
    1682 }
    \n-
    1683
    \n-
    1684 template<class M>
    \n-
    1685 template<class C>
    \n-
    1686 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator==(const VertexIteratorT<ConstContainer>& other) const
    \n-
    1687 {
    \n-
    1688 return current_ == other.current_;
    \n-
    1689 }
    \n-
    1690
    \n-
    1691 template<class M>
    \n-
    1692 template<class C>
    \n-
    1693 inline typename MatrixGraph<M>::template VertexIteratorT<C>& MatrixGraph<M>::VertexIteratorT<C>::operator++()
    \n-
    1694 {
    \n-
    1695 ++current_;
    \n-
    1696 return *this;
    \n-
    1697 }
    \n-
    1698
    \n-
    1699 template<class M>
    \n-
    1700 template<class C>
    \n-
    1701 inline typename MatrixGraph<M>::template VertexIteratorT<C>::WeightType&
    \n-
    1702 MatrixGraph<M>::VertexIteratorT<C>::weight() const
    \n-
    1703 {
    \n-
    1704 return graph_->matrix()[current_][current_];
    \n-
    1705 }
    \n-
    1706
    \n-
    1707 template<class M>
    \n-
    1708 template<class C>
    \n-
    1709 inline const typename MatrixGraph<M>::VertexDescriptor&
    \n-
    1710 MatrixGraph<M>::VertexIteratorT<C>::operator*() const
    \n-
    1711 {
    \n-
    1712 return current_;
    \n-
    1713 }
    \n-
    1714
    \n-
    1715 template<class M>
    \n-
    1716 template<class C>
    \n-
    1717 inline typename MatrixGraph<M>::template EdgeIteratorT<C>
    \n-
    1718 MatrixGraph<M>::VertexIteratorT<C>::begin() const
    \n-
    1719 {
    \n-
    1720 return graph_->beginEdges(current_);
    \n-
    1721 }
    \n-
    1722
    \n-
    1723 template<class M>
    \n-
    1724 template<class C>
    \n-
    1725 inline typename MatrixGraph<M>::template EdgeIteratorT<C>
    \n-
    1726 MatrixGraph<M>::VertexIteratorT<C>::end() const
    \n-
    1727 {
    \n-
    1728 return graph_->endEdges(current_);
    \n-
    1729 }
    \n-
    1730
    \n-
    1731 template<class M>
    \n-
    1732 inline typename MatrixGraph<M>::template VertexIteratorT<MatrixGraph<M> >
    \n-
    1733 MatrixGraph<M>::begin()
    \n-
    1734 {
    \n-
    1735 return VertexIterator(this,0);
    \n-
    1736 }
    \n-
    1737
    \n-
    1738 template<class M>
    \n-
    1739 inline typename MatrixGraph<M>::template VertexIteratorT<MatrixGraph<M> >
    \n-
    1740 MatrixGraph<M>::end()
    \n-
    1741 {
    \n-
    1742 return VertexIterator(matrix_.N());
    \n-
    1743 }
    \n-
    1744
    \n-
    1745
    \n-
    1746 template<class M>
    \n-
    1747 inline typename MatrixGraph<M>::template VertexIteratorT<const MatrixGraph<M> >
    \n-
    1748 MatrixGraph<M>::begin() const
    \n-
    1749 {
    \n-
    1750 return ConstVertexIterator(this, 0);
    \n-
    1751 }
    \n-
    1752
    \n-
    1753 template<class M>
    \n-
    1754 inline typename MatrixGraph<M>::template VertexIteratorT<const MatrixGraph<M> >
    \n-
    1755 MatrixGraph<M>::end() const
    \n-
    1756 {
    \n-
    1757 return ConstVertexIterator(matrix_.N());
    \n-
    1758 }
    \n-
    1759
    \n-
    1760 template<class M>
    \n-
    1761 inline typename MatrixGraph<M>::template EdgeIteratorT<MatrixGraph<M> >
    \n-
    1762 MatrixGraph<M>::beginEdges(const VertexDescriptor& source)
    \n-
    1763 {
    \n-
    1764 return EdgeIterator(source, matrix_.operator[](source).begin(),
    \n-
    1765 matrix_.operator[](source).end(), start_[source]);
    \n-
    1766 }
    \n-
    1767
    \n-
    1768 template<class M>
    \n-
    1769 inline typename MatrixGraph<M>::template EdgeIteratorT<MatrixGraph<M> >
    \n-
    1770 MatrixGraph<M>::endEdges(const VertexDescriptor& source)
    \n-
    1771 {
    \n-
    1772 return EdgeIterator(matrix_.operator[](source).end());
    \n-
    1773 }
    \n-
    1774
    \n-
    1775
    \n-
    1776 template<class M>
    \n-
    1777 inline typename MatrixGraph<M>::template EdgeIteratorT<const MatrixGraph<M> >
    \n-
    1778 MatrixGraph<M>::beginEdges(const VertexDescriptor& source) const
    \n-
    1779 {
    \n-
    1780 return ConstEdgeIterator(source, matrix_.operator[](source).begin(),
    \n-
    1781 matrix_.operator[](source).end(), start_[source]);
    \n-
    1782 }
    \n-
    1783
    \n-
    1784 template<class M>
    \n-
    1785 inline typename MatrixGraph<M>::template EdgeIteratorT<const MatrixGraph<M> >
    \n-
    1786 MatrixGraph<M>::endEdges(const VertexDescriptor& source) const
    \n-
    1787 {
    \n-
    1788 return ConstEdgeIterator(matrix_.operator[](source).end());
    \n-
    1789 }
    \n-
    1790
    \n-
    1791
    \n-
    1792 template<class G, class T>
    \n-
    1793 SubGraph<G,T>::EdgeIterator::EdgeIterator(const VertexDescriptor& source,
    \n-
    1794 const EdgeDescriptor& edge)
    \n-
    1795 : source_(source), edge_(edge)
    \n-
    1796 {}
    \n-
    1797
    \n-
    1798
    \n-
    1799 template<class G, class T>
    \n-
    1800 SubGraph<G,T>::EdgeIterator::EdgeIterator(const EdgeDescriptor& edge)
    \n-
    1801 : edge_(edge)
    \n-
    1802 {}
    \n-
    1803
    \n-
    1804 template<class G, class T>
    \n-
    1805 typename SubGraph<G,T>::EdgeIndexMap SubGraph<G,T>::getEdgeIndexMap()
    \n-
    1806 {
    \n-
    1807 return EdgeIndexMap(edges_);
    \n-
    1808 }
    \n-
    1809
    \n-
    1810 template<class G, class T>
    \n-
    1811 inline bool SubGraph<G,T>::EdgeIterator::equals(const EdgeIterator & other) const
    \n-
    1812 {
    \n-
    1813 return other.edge_==edge_;
    \n-
    1814 }
    \n-
    1815
    \n-
    1816 template<class G, class T>
    \n-
    1817 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::increment()
    \n-
    1818 {
    \n-
    1819 ++edge_;
    \n-
    1820 return *this;
    \n-
    1821 }
    \n-
    1822
    \n-
    1823 template<class G, class T>
    \n-
    1824 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::decrement()
    \n-
    1825 {
    \n-
    1826 --edge_;
    \n-
    1827 return *this;
    \n-
    1828 }
    \n-
    1829
    \n-
    1830 template<class G, class T>
    \n-
    1831 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::advance(std::ptrdiff_t n)
    \n-
    1832 {
    \n-
    1833 edge_+=n;
    \n-
    1834 return *this;
    \n-
    1835 }
    \n-
    1836 template<class G, class T>
    \n-
    1837 inline const typename G::VertexDescriptor& SubGraph<G,T>::EdgeIterator::source() const
    \n-
    1838 {
    \n-
    1839 return source_;
    \n-
    1840 }
    \n-
    1841
    \n-
    1842 template<class G, class T>
    \n-
    1843 inline const typename G::VertexDescriptor& SubGraph<G,T>::EdgeIterator::target() const
    \n-
    1844 {
    \n-
    1845 return *edge_;
    \n-
    1846 }
    \n-
    1847
    \n-
    1848
    \n-
    1849 template<class G, class T>
    \n-
    1850 inline const typename SubGraph<G,T>::EdgeDescriptor& SubGraph<G,T>::EdgeIterator::dereference() const
    \n-
    1851 {
    \n-
    1852 return edge_;
    \n-
    1853 }
    \n-
    1854
    \n-
    1855 template<class G, class T>
    \n-
    1856 inline std::ptrdiff_t SubGraph<G,T>::EdgeIterator::distanceTo(const EdgeIterator & other) const
    \n-
    1857 {
    \n-
    1858 return other.edge_-edge_;
    \n-
    1859 }
    \n-
    1860
    \n-
    1861 template<class G, class T>
    \n-
    1862 SubGraph<G,T>::VertexIterator::VertexIterator(const SubGraph<G,T>* graph,
    \n-
    1863 const VertexDescriptor& current,
    \n-
    1864 const VertexDescriptor& end)
    \n-
    1865 : graph_(graph), current_(current), end_(end)
    \n-
    1866 {
    \n-
    1867 // Skip excluded vertices
    \n-
    1868 typedef typename T::const_iterator Iterator;
    \n-
    1869
    \n-
    1870 for(Iterator vertex = graph_->excluded_.begin();
    \n-
    1871 current_ != end_ && *vertex;
    \n-
    1872 ++vertex)
    \n-
    1873 ++current_;
    \n-
    1874 assert(current_ == end_ || !graph_->excluded_[current_]);
    \n-
    1875 }
    \n-
    1876
    \n-
    1877 template<class G, class T>
    \n-
    1878 SubGraph<G,T>::VertexIterator::VertexIterator(const VertexDescriptor& current)
    \n-
    1879 : current_(current)
    \n-
    1880 {}
    \n-
    1881
    \n-
    1882 template<class G, class T>
    \n-
    1883 inline typename SubGraph<G,T>::VertexIterator& SubGraph<G,T>::VertexIterator::increment()
    \n-
    1884 {
    \n-
    1885 ++current_;
    \n-
    1886 //Skip excluded vertices
    \n-
    1887 while(current_ != end_ && graph_->excluded_[current_])
    \n-
    1888 ++current_;
    \n-
    1889
    \n-
    1890 assert(current_ == end_ || !graph_->excluded_[current_]);
    \n-
    1891 return *this;
    \n-
    1892 }
    \n-
    1893
    \n-
    1894 template<class G, class T>
    \n-
    1895 inline bool SubGraph<G,T>::VertexIterator::equals(const VertexIterator & other) const
    \n-
    1896 {
    \n-
    1897 return current_==other.current_;
    \n-
    1898 }
    \n-
    1899
    \n-
    1900 template<class G, class T>
    \n-
    1901 inline const typename G::VertexDescriptor& SubGraph<G,T>::VertexIterator::dereference() const
    \n-
    1902 {
    \n-
    1903 return current_;
    \n-
    1904 }
    \n-
    1905
    \n-
    1906 template<class G, class T>
    \n-
    1907 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::VertexIterator::begin() const
    \n-
    1908 {
    \n-
    1909 return graph_->beginEdges(current_);
    \n-
    1910 }
    \n-
    1911
    \n-
    1912 template<class G, class T>
    \n-
    1913 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::VertexIterator::end() const
    \n-
    1914 {
    \n-
    1915 return graph_->endEdges(current_);
    \n-
    1916 }
    \n-
    1917
    \n-
    1918 template<class G, class T>
    \n-
    1919 inline typename SubGraph<G,T>::VertexIterator SubGraph<G,T>::begin() const
    \n-
    1920 {
    \n-
    1921 return VertexIterator(this, 0, endVertex_);
    \n-
    1922 }
    \n-
    1923
    \n-
    1924
    \n-
    1925 template<class G, class T>
    \n-
    1926 inline typename SubGraph<G,T>::VertexIterator SubGraph<G,T>::end() const
    \n-
    1927 {
    \n-
    1928 return VertexIterator(endVertex_);
    \n-
    1929 }
    \n-
    1930
    \n-
    1931
    \n-
    1932 template<class G, class T>
    \n-
    1933 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::beginEdges(const VertexDescriptor& source) const
    \n-
    1934 {
    \n-
    1935 return EdgeIterator(source, edges_+start_[source]);
    \n-
    1936 }
    \n-
    1937
    \n-
    1938 template<class G, class T>
    \n-
    1939 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::endEdges(const VertexDescriptor& source) const
    \n-
    1940 {
    \n-
    1941 return EdgeIterator(edges_+end_[source]);
    \n-
    1942 }
    \n-
    1943
    \n-
    1944 template<class G, class T>
    \n-
    1945 std::size_t SubGraph<G,T>::noVertices() const
    \n-
    1946 {
    \n-
    1947 return noVertices_;
    \n-
    1948 }
    \n-
    1949
    \n-
    1950 template<class G, class T>
    \n-
    1951 inline typename SubGraph<G,T>::VertexDescriptor SubGraph<G,T>::maxVertex() const
    \n-
    1952 {
    \n-
    1953 return maxVertex_;
    \n-
    1954 }
    \n-
    1955
    \n-
    1956 template<class G, class T>
    \n-
    1957 inline std::size_t SubGraph<G,T>::noEdges() const
    \n-
    1958 {
    \n-
    1959 return noEdges_;
    \n-
    1960 }
    \n-
    1961
    \n-
    1962 template<class G, class T>
    \n-
    1963 inline typename SubGraph<G,T>::EdgeDescriptor SubGraph<G,T>::findEdge(const VertexDescriptor& source,
    \n-
    1964 const VertexDescriptor& target) const
    \n-
    1965 {
    \n-
    1966 const EdgeDescriptor edge = std::lower_bound(edges_+start_[source], edges_+end_[source], target);
    \n-
    1967 if(edge==edges_+end_[source] || *edge!=target)
    \n-
    1968 return std::numeric_limits<EdgeDescriptor>::max();
    \n-
    1969
    \n-
    1970 return edge;
    \n-
    1971 }
    \n-
    1972
    \n-
    1973 template<class G, class T>
    \n-
    1974 SubGraph<G,T>::~SubGraph()
    \n-
    1975 {
    \n-
    1976 delete[] edges_;
    \n-
    1977 delete[] end_;
    \n-
    1978 delete[] start_;
    \n-
    1979 }
    \n-
    1980
    \n-
    1981 template<class G, class T>
    \n-
    1982 SubGraph<G,T>::SubGraph(const G& graph, const T& excluded)
    \n-
    1983 : excluded_(excluded), noVertices_(0), endVertex_(0), maxVertex_(graph.maxVertex())
    \n-
    1984 {
    \n-
    1985 start_ = new std::ptrdiff_t[graph.noVertices()];
    \n-
    1986 end_ = new std::ptrdiff_t[graph.noVertices()];
    \n-
    1987 edges_ = new VertexDescriptor[graph.noEdges()];
    \n-
    1988
    \n-
    1989 VertexDescriptor* edge=edges_;
    \n-
    1990
    \n-
    1991 // Cater for the case that there are no vertices.
    \n-
    1992 // Otherwise endVertex_ will get 1 below.
    \n-
    1993 if ( graph.noVertices() == 0)
    \n-
    1994 return;
    \n-
    1995
    \n-
    1996 typedef typename Graph::ConstVertexIterator Iterator;
    \n-
    1997 Iterator endVertex=graph.end();
    \n-
    1998
    \n-
    1999 for(Iterator vertex = graph.begin(); vertex != endVertex; ++vertex)
    \n-
    2000 if(excluded_[*vertex])
    \n-
    2001 start_[*vertex]=end_[*vertex]=-1;
    \n-
    2002 else{
    \n-
    2003 ++noVertices_;
    \n-
    2004 endVertex_ = std::max(*vertex, endVertex_);
    \n-
    2005
    \n-
    2006 start_[*vertex] = edge-edges_;
    \n-
    2007
    \n-
    2008 auto endEdge = vertex.end();
    \n-
    2009
    \n-
    2010 for(auto iter=vertex.begin(); iter!= endEdge; ++iter)
    \n-
    2011 if(!excluded[iter.target()]) {
    \n-
    2012 *edge = iter.target();
    \n-
    2013 ++edge;
    \n-
    2014 }
    \n-
    2015
    \n-
    2016 end_[*vertex] = edge - edges_;
    \n-
    2017
    \n-
    2018 // Sort the edges
    \n-
    2019 std::sort(edges_+start_[*vertex], edge);
    \n-
    2020 }
    \n-
    2021 noEdges_ = edge-edges_;
    \n-
    2022 ++endVertex_;
    \n-
    2023 }
    \n-
    2024
    \n-
    2025 template<class G, class V, class VM>
    \n-
    2026 inline std::size_t VertexPropertiesGraph<G,V,VM>::noEdges() const
    \n-
    2027 {
    \n-
    2028 return graph_.noEdges();
    \n-
    2029 }
    \n-
    2030
    \n-
    2031 template<class G, class V, class VM>
    \n-
    2032 inline typename VertexPropertiesGraph<G,V,VM>::EdgeIterator
    \n-
    2033 VertexPropertiesGraph<G,V,VM>::beginEdges(const VertexDescriptor& source)
    \n-
    2034 {
    \n-
    2035 return graph_.beginEdges(source);
    \n-
    2036 }
    \n-
    2037
    \n-
    2038 template<class G, class V, class VM>
    \n-
    2039 inline typename VertexPropertiesGraph<G,V,VM>::EdgeIterator
    \n-
    2040 VertexPropertiesGraph<G,V,VM>::endEdges(const VertexDescriptor& source)
    \n-
    2041 {
    \n-
    2042 return graph_.endEdges(source);
    \n-
    2043 }
    \n-
    2044
    \n-
    2045 template<class G, class V, class VM>
    \n-
    2046 typename VertexPropertiesGraph<G,V,VM>::ConstEdgeIterator
    \n-
    2047 inline VertexPropertiesGraph<G,V,VM>::beginEdges(const VertexDescriptor& source) const
    \n-
    2048 {
    \n-
    2049 return graph_.beginEdges(source);
    \n-
    2050 }
    \n-
    2051
    \n-
    2052 template<class G, class V, class VM>
    \n-
    2053 typename VertexPropertiesGraph<G,V,VM>::ConstEdgeIterator
    \n-
    2054 VertexPropertiesGraph<G,V,VM>::endEdges(const VertexDescriptor& source) const
    \n-
    2055 {
    \n-
    2056 return graph_.endEdges(source);
    \n-
    2057 }
    \n-
    2058
    \n-
    2059 template<class G, class V, class VM>
    \n-
    2060 template<class C>
    \n-
    2061 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n-
    2062 ::VertexIteratorT(const Father& iter,
    \n-
    2063 C* graph)
    \n-
    2064 : Father(iter), graph_(graph)
    \n-
    2065 {}
    \n-
    2066
    \n-
    2067 template<class G, class V, class VM>
    \n-
    2068 template<class C>
    \n-
    2069 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n-
    2070 ::VertexIteratorT(const Father& iter)
    \n-
    2071 : Father(iter)
    \n-
    2072 {}
    \n-
    2073
    \n-
    2074 template<class G, class V, class VM>
    \n-
    2075 template<class C>
    \n-
    2076 template<class C1>
    \n-
    2077 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n-
    2078 ::VertexIteratorT(const VertexIteratorT<C1>& other)
    \n-
    2079 : Father(other), graph_(other.graph_)
    \n-
    2080 {}
    \n-
    2081
    \n-
    2082 template<class G, class V, class VM>
    \n-
    2083 template<class C>
    \n-
    2084 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n-
    2085 V&, const V&>::type
    \n-
    2086 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::properties() const
    \n-
    2087 {
    \n-
    2088 return graph_->getVertexProperties(Father::operator*());
    \n-
    2089 }
    \n-
    2090
    \n-
    2091 template<class G, class V, class VM>
    \n-
    2092 template<class C>
    \n-
    2093 typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    2094 C>::value,
    \n-
    2095 typename G::EdgeIterator,
    \n-
    2096 typename G::ConstEdgeIterator>::type
    \n-
    2097 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::begin() const
    \n-
    2098 {
    \n-
    2099 return graph_->beginEdges(Father::operator*());
    \n-
    2100 }
    \n-
    2101
    \n-
    2102 template<class G, class V, class VM>
    \n-
    2103 template<class C>
    \n-
    2104 typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n-
    2105 C>::value,
    \n-
    2106 typename G::EdgeIterator,
    \n-
    2107 typename G::ConstEdgeIterator>::type
    \n-
    2108 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::end() const
    \n-
    2109 {
    \n-
    2110 return graph_->endEdges(Father::operator*());
    \n-
    2111 }
    \n-
    2112
    \n-
    2113 template<class G, class V, class VM>
    \n-
    2114 inline typename VertexPropertiesGraph<G,V,VM>::VertexIterator VertexPropertiesGraph<G,V,VM>::begin()
    \n-
    2115 {
    \n-
    2116 return VertexIterator(graph_.begin(), this);
    \n-
    2117 }
    \n-
    2118
    \n-
    2119 template<class G, class V, class VM>
    \n-
    2120 inline typename VertexPropertiesGraph<G,V,VM>::VertexIterator VertexPropertiesGraph<G,V,VM>::end()
    \n-
    2121 {
    \n-
    2122 return VertexIterator(graph_.end());
    \n-
    2123 }
    \n-
    2124
    \n-
    2125
    \n-
    2126 template<class G, class V, class VM>
    \n-
    2127 inline typename VertexPropertiesGraph<G,V,VM>::ConstVertexIterator VertexPropertiesGraph<G,V,VM>::begin() const
    \n-
    2128 {
    \n-
    2129 return ConstVertexIterator(graph_.begin(), this);
    \n-
    2130 }
    \n-
    2131
    \n-
    2132 template<class G, class V, class VM>
    \n-
    2133 inline typename VertexPropertiesGraph<G,V,VM>::ConstVertexIterator VertexPropertiesGraph<G,V,VM>::end() const
    \n-
    2134 {
    \n-
    2135 return ConstVertexIterator(graph_.end());
    \n-
    2136 }
    \n-
    2137
    \n-
    2138 template<class G, class V, class VM>
    \n-
    2139 inline V& VertexPropertiesGraph<G,V,VM>::getVertexProperties(const VertexDescriptor& vertex)
    \n-
    2140 {
    \n-
    2141 return vertexProperties_[vmap_[vertex]];
    \n-
    2142 }
    \n-
    2143
    \n-
    2144 template<class G, class V, class VM>
    \n-
    2145 inline const V& VertexPropertiesGraph<G,V,VM>::getVertexProperties(const VertexDescriptor& vertex) const
    \n-
    2146 {
    \n-
    2147 return vertexProperties_[vmap_[vertex]];
    \n-
    2148 }
    \n-
    2149
    \n-
    2150 template<class G, class V, class VM>
    \n-
    2151 inline const G& VertexPropertiesGraph<G,V,VM>::graph() const
    \n-
    2152 {
    \n-
    2153 return graph_;
    \n-
    2154 }
    \n-
    2155
    \n-
    2156 template<class G, class V, class VM>
    \n-
    2157 inline std::size_t VertexPropertiesGraph<G,V,VM>::noVertices() const
    \n-
    2158 {
    \n-
    2159 return graph_.noVertices();
    \n-
    2160 }
    \n-
    2161
    \n-
    2162
    \n-
    2163 template<class G, class V, class VM>
    \n-
    2164 inline typename VertexPropertiesGraph<G,V,VM>::VertexDescriptor VertexPropertiesGraph<G,V,VM>::maxVertex() const
    \n-
    2165 {
    \n-
    2166 return graph_.maxVertex();
    \n-
    2167 }
    \n-
    2168
    \n-
    2169 template<class G, class V, class VM>
    \n-
    2170 VertexPropertiesGraph<G,V,VM>::VertexPropertiesGraph(Graph& graph, const VM vmap)
    \n-
    2171 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex()+1], V())
    \n-
    2172 {}
    \n-
    2173
    \n-
    2174 template<class G, class V, class E, class VM, class EM>
    \n-
    2175 template<class C>
    \n-
    2176 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const Father& iter,
    \n-
    2177 C* graph)
    \n-
    2178 : Father(iter), graph_(graph)
    \n-
    2179 {}
    \n-
    2180
    \n-
    2181 template<class G, class V, class E, class VM, class EM>
    \n-
    2182 template<class C>
    \n-
    2183 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const Father& iter)
    \n-
    2184 : Father(iter)
    \n-
    2185 {}
    \n-
    2186
    \n-
    2187 template<class G, class V, class E, class VM, class EM>
    \n-
    2188 template<class C>
    \n-
    2189 template<class C1>
    \n-
    2190 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const EdgeIteratorT<C1>& other)
    \n-
    2191 : Father(other), graph_(other.graph_)
    \n-
    2192 {}
    \n-
    2193
    \n-
    2194
    \n-
    2195 template<class G, class V, class E, class VM, class EM>
    \n-
    2196 inline std::size_t PropertiesGraph<G,V,E,VM,EM>::noEdges() const
    \n-
    2197 {
    \n-
    2198 return graph_.noEdges();
    \n-
    2199 }
    \n-
    2200
    \n-
    2201 template<class G, class V, class E, class VM, class EM>
    \n-
    2202 template<class C>
    \n-
    2203 inline typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,E&,const E&>::type
    \n-
    2204 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::properties() const
    \n-
    2205 {
    \n-
    2206 return graph_->getEdgeProperties(Father::operator*());
    \n-
    2207 }
    \n-
    2208
    \n-
    2209 template<class G, class V, class E, class VM, class EM>
    \n-
    2210 inline typename PropertiesGraph<G,V,E,VM,EM>::EdgeIterator
    \n-
    2211 PropertiesGraph<G,V,E,VM,EM>::beginEdges(const VertexDescriptor& source)
    \n-
    2212 {
    \n-
    2213 return EdgeIterator(graph_.beginEdges(source), this);
    \n-
    2214 }
    \n-
    2215
    \n-
    2216 template<class G, class V, class E, class VM, class EM>
    \n-
    2217 inline typename PropertiesGraph<G,V,E,VM,EM>::EdgeIterator
    \n-
    2218 PropertiesGraph<G,V,E,VM,EM>::endEdges(const VertexDescriptor& source)
    \n-
    2219 {
    \n-
    2220 return EdgeIterator(graph_.endEdges(source));
    \n-
    2221 }
    \n-
    2222
    \n-
    2223 template<class G, class V, class E, class VM, class EM>
    \n-
    2224 typename PropertiesGraph<G,V,E,VM,EM>::ConstEdgeIterator
    \n-
    2225 inline PropertiesGraph<G,V,E,VM,EM>::beginEdges(const VertexDescriptor& source) const
    \n-
    2226 {
    \n-
    2227 return ConstEdgeIterator(graph_.beginEdges(source), this);
    \n-
    2228 }
    \n-
    2229
    \n-
    2230 template<class G, class V, class E, class VM, class EM>
    \n-
    2231 typename PropertiesGraph<G,V,E,VM,EM>::ConstEdgeIterator
    \n-
    2232 PropertiesGraph<G,V,E,VM,EM>::endEdges(const VertexDescriptor& source) const
    \n-
    2233 {
    \n-
    2234 return ConstEdgeIterator(graph_.endEdges(source));
    \n-
    2235 }
    \n-
    2236
    \n-
    2237 template<class G, class V, class E, class VM, class EM>
    \n-
    2238 template<class C>
    \n-
    2239 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n-
    2240 ::VertexIteratorT(const Father& iter,
    \n-
    2241 C* graph)
    \n-
    2242 : Father(iter), graph_(graph)
    \n-
    2243 {}
    \n-
    2244
    \n-
    2245 template<class G, class V, class E, class VM, class EM>
    \n-
    2246 template<class C>
    \n-
    2247 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n-
    2248 ::VertexIteratorT(const Father& iter)
    \n-
    2249 : Father(iter)
    \n-
    2250 {}
    \n-
    2251
    \n-
    2252 template<class G, class V, class E, class VM, class EM>
    \n-
    2253 template<class C>
    \n-
    2254 template<class C1>
    \n-
    2255 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n-
    2256 ::VertexIteratorT(const VertexIteratorT<C1>& other)
    \n-
    2257 : Father(other), graph_(other.graph_)
    \n-
    2258 {}
    \n-
    2259
    \n-
    2260 template<class G, class V, class E, class VM, class EM>
    \n-
    2261 template<class C>
    \n-
    2262 inline typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n-
    2263 V&, const V&>::type
    \n-
    2264 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::properties() const
    \n-
    2265 {
    \n-
    2266 return graph_->getVertexProperties(Father::operator*());
    \n-
    2267 }
    \n-
    2268
    \n-
    2269 template<class G, class V, class E, class VM, class EM>
    \n-
    2270 template<class C>
    \n-
    2271 inline typename PropertiesGraph<G,V,E,VM,EM>::template EdgeIteratorT<C>
    \n-
    2272 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::begin() const
    \n-
    2273 {
    \n-
    2274 return graph_->beginEdges(Father::operator*());
    \n-
    2275 }
    \n-
    2276
    \n-
    2277 template<class G, class V, class E, class VM, class EM>
    \n-
    2278 template<class C>
    \n-
    2279 inline typename PropertiesGraph<G,V,E,VM,EM>::template EdgeIteratorT<C>
    \n-
    2280 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::end() const
    \n-
    2281 {
    \n-
    2282 return graph_->endEdges(Father::operator*());
    \n-
    2283 }
    \n-
    2284
    \n-
    2285 template<class G, class V, class E, class VM, class EM>
    \n-
    2286 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexIterator PropertiesGraph<G,V,E,VM,EM>::begin()
    \n-
    2287 {
    \n-
    2288 return VertexIterator(graph_.begin(), this);
    \n-
    2289 }
    \n-
    2290
    \n-
    2291 template<class G, class V, class E, class VM, class EM>
    \n-
    2292 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexIterator PropertiesGraph<G,V,E,VM,EM>::end()
    \n-
    2293 {
    \n-
    2294 return VertexIterator(graph_.end());
    \n-
    2295 }
    \n-
    2296
    \n-
    2297
    \n-
    2298 template<class G, class V, class E, class VM, class EM>
    \n-
    2299 inline typename PropertiesGraph<G,V,E,VM,EM>::ConstVertexIterator PropertiesGraph<G,V,E,VM,EM>::begin() const
    \n-
    2300 {
    \n-
    2301 return ConstVertexIterator(graph_.begin(), this);
    \n-
    2302 }
    \n-
    2303
    \n-
    2304 template<class G, class V, class E, class VM, class EM>
    \n-
    2305 inline typename PropertiesGraph<G,V,E,VM,EM>::ConstVertexIterator PropertiesGraph<G,V,E,VM,EM>::end() const
    \n-
    2306 {
    \n-
    2307 return ConstVertexIterator(graph_.end());
    \n-
    2308 }
    \n-
    2309
    \n-
    2310 template<class G, class V, class E, class VM, class EM>
    \n-
    2311 inline V& PropertiesGraph<G,V,E,VM,EM>::getVertexProperties(const VertexDescriptor& vertex)
    \n-
    2312 {
    \n-
    2313 return vertexProperties_[vmap_[vertex]];
    \n-
    2314 }
    \n-
    2315
    \n-
    2316 template<class G, class V, class E, class VM, class EM>
    \n-
    2317 inline const V& PropertiesGraph<G,V,E,VM,EM>::getVertexProperties(const VertexDescriptor& vertex) const
    \n-
    2318 {
    \n-
    2319 return vertexProperties_[vmap_[vertex]];
    \n-
    2320 }
    \n-
    2321
    \n-
    2322 template<class G, class V, class E, class VM, class EM>
    \n-
    2323 inline E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const EdgeDescriptor& edge)
    \n-
    2324 {
    \n-
    2325 return edgeProperties_[emap_[edge]];
    \n-
    2326 }
    \n-
    2327
    \n-
    2328 template<class G, class V, class E, class VM, class EM>
    \n-
    2329 inline const E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const EdgeDescriptor& edge) const
    \n-
    2330 {
    \n-
    2331 return edgeProperties_[emap_[edge]];
    \n-
    2332 }
    \n-
    2333
    \n-
    2334 template<class G, class V, class E, class VM, class EM>
    \n-
    2335 inline E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const VertexDescriptor& source,
    \n-
    2336 const VertexDescriptor& target)
    \n-
    2337 {
    \n-
    2338 return getEdgeProperties(graph_.findEdge(source,target));
    \n-
    2339 }
    \n-
    2340
    \n-
    2341 template<class G, class V, class E, class VM, class EM>
    \n-
    2342 inline const E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const VertexDescriptor& source,
    \n-
    2343 const VertexDescriptor& target) const
    \n-
    2344 {
    \n-
    2345 return getEdgeProperties(graph_.findEdge(source,target));
    \n-
    2346 }
    \n-
    2347
    \n-
    2348 template<class G, class V, class E, class VM, class EM>
    \n-
    2349 inline const G& PropertiesGraph<G,V,E,VM,EM>::graph() const
    \n-
    2350 {
    \n-
    2351 return graph_;
    \n-
    2352 }
    \n-
    2353
    \n-
    2354 template<class G, class V, class E, class VM, class EM>
    \n-
    2355 inline std::size_t PropertiesGraph<G,V,E,VM,EM>::noVertices() const
    \n-
    2356 {
    \n-
    2357 return graph_.noVertices();
    \n-
    2358 }
    \n-
    2359
    \n-
    2360
    \n-
    2361 template<class G, class V, class E, class VM, class EM>
    \n-
    2362 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexDescriptor PropertiesGraph<G,V,E,VM,EM>::maxVertex() const
    \n-
    2363 {
    \n-
    2364 return graph_.maxVertex();
    \n-
    2365 }
    \n-
    2366
    \n-
    2367 template<class G, class V, class E, class VM, class EM>
    \n-
    2368 PropertiesGraph<G,V,E,VM,EM>::PropertiesGraph(Graph& graph, const VM& vmap, const EM& emap)
    \n-
    2369 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex()+1], V()),
    \n-
    2370 emap_(emap), edgeProperties_(graph_.noEdges(), E())
    \n-
    2371 {}
    \n-
    2372
    \n-
    2373 template<class G, class V>
    \n-
    2374 inline int visitNeighbours(const G& graph, const typename G::VertexDescriptor& vertex,
    \n-
    2375 V& visitor)
    \n-
    2376 {
    \n-
    2377 typedef typename G::ConstEdgeIterator iterator;
    \n-
    2378 const iterator end = graph.endEdges(vertex);
    \n-
    2379 int noNeighbours=0;
    \n-
    2380 for(iterator edge = graph.beginEdges(vertex); edge != end; ++edge, ++noNeighbours)
    \n-
    2381 visitor(edge);
    \n-
    2382 return noNeighbours;
    \n-
    2383 }
    \n-
    2384
    \n-
    2385#endif // DOXYGEN
    \n-
    2386
    \n-
    2388 }
    \n-
    2389}
    \n-
    2390#endif
    \n-\n-
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n-
    STL namespace.
    \n+
    543 template<typename T, typename A, typename A1, int n, int k, int m>
    \n+\n+
    545 {
    \n+\n+
    547 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
    \n+
    548 };
    \n+
    549
    \n+
    550
    \n+
    559 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n+\n+
    561 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, [[maybe_unused]] bool tryHard=false)
    \n+
    562 {
    \n+
    563 matMultMat<2>(res,mat, matt);
    \n+
    564 }
    \n+
    565
    \n+
    574 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n+\n+
    576 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, bool tryHard=false)
    \n+
    577 {
    \n+
    578 matMultMat<0>(res,mat, matt);
    \n+
    579 }
    \n+
    580
    \n+
    589 template<class T, class A, class A1, class A2, int n, int m, int k>
    \n+\n+
    591 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt, [[maybe_unused]] bool tryHard=false)
    \n+
    592 {
    \n+
    593 matMultMat<1>(res,mat, matt);
    \n+
    594 }
    \n+
    595
    \n+
    596}
    \n+
    597#endif
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    FieldMatrix< T, n, m > type
    Definition: matrixmatrix.hh:515
    \n+
    void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of a transposed sparse matrix with another sparse matrices ( ).
    Definition: matrixmatrix.hh:590
    \n+
    void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of two sparse matrices ( ).
    Definition: matrixmatrix.hh:575
    \n+
    Matrix::RowIterator Row
    Definition: matrixmatrix.hh:326
    \n+
    Dune::BCRSMatrix< Dune::FieldMatrix< T, n, m >, TA > Matrix
    Definition: matrixmatrix.hh:228
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:360
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:380
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix::ColIterator Col
    Definition: matrixmatrix.hh:327
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:188
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:230
    \n+\n+
    void matMultTransposeMat(BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
    Calculate product of a sparse matrix with a transposed sparse matrices ( ).
    Definition: matrixmatrix.hh:560
    \n+
    Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
    Definition: matrixmatrix.hh:186
    \n+
    BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
    Definition: matrixmatrix.hh:522
    \n+
    Matrix::CreateIterator CreateIterator
    Definition: matrixmatrix.hh:229
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:399
    \n+
    Matrix::CreateIterator CreateIterator
    Definition: matrixmatrix.hh:187
    \n+
    BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
    Definition: matrixmatrix.hh:547
    \n+
    Matrix::size_type size_type
    Definition: matrixmatrix.hh:418
    \n+
    BCRSMatrix< FieldMatrix< T, n, m >, A >::size_type size_type
    Definition: matrixmatrix.hh:157
    \n
    Definition: allocator.hh:11
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n-
    MatrixGraph(Matrix &matrix)
    Constructor.
    \n-
    VertexIterator end()
    Get an iterator over the vertices.
    \n-
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n-
    M Matrix
    The type of the matrix we are a graph for.
    Definition: graph.hh:56
    \n-
    ConstVertexIterator begin() const
    Get an iterator over the vertices.
    \n-
    VertexIteratorT< const MatrixGraph< Matrix > > ConstVertexIterator
    The constant vertex iterator type.
    Definition: graph.hh:308
    \n-
    ~MatrixGraph()
    Destructor.
    \n-
    std::ptrdiff_t EdgeDescriptor
    The edge descriptor.
    Definition: graph.hh:80
    \n-
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n-
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n-
    const Matrix & matrix() const
    Get the underlying matrix.
    \n-
    @ mutableMatrix
    Definition: graph.hh:86
    \n-
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n-
    ConstVertexIterator end() const
    Get an iterator over the vertices.
    \n-
    EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:298
    \n-
    EdgeIterator beginEdges(const VertexDescriptor &source)
    Get an iterator over the edges starting at a vertex.
    \n-
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n-
    EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor &target) const
    Find the descriptor of an edge.
    \n-
    M::block_type Weight
    The type of the weights.
    Definition: graph.hh:66
    \n-
    std::remove_const< M >::type MutableMatrix
    The mutable type of the matrix we are a graph for.
    Definition: graph.hh:61
    \n-
    EdgeIteratorT< MatrixGraph< Matrix > > EdgeIterator
    The mutable edge iterator type.
    Definition: graph.hh:303
    \n-
    VertexIteratorT< MatrixGraph< Matrix > > VertexIterator
    The mutable vertex iterator type.
    Definition: graph.hh:313
    \n-
    EdgeIterator endEdges(const VertexDescriptor &source)
    Get an iterator over the edges starting at a vertex.
    \n-
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n-
    Matrix & matrix()
    Get the underlying matrix.
    \n-
    VertexIterator begin()
    Get an iterator over the vertices.
    \n-
    Iterator over all edges starting from a vertex.
    Definition: graph.hh:95
    \n-
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type WeightType
    Definition: graph.hh:156
    \n-
    EdgeIteratorT(const VertexDescriptor &source, const ColIterator &block, const ColIterator &end, const EdgeDescriptor &edge)
    Constructor.
    \n-
    @ isMutable
    whether C is mutable.
    Definition: graph.hh:112
    \n-
    VertexDescriptor target() const
    The index of the target vertex of the current edge.
    \n-
    EdgeIteratorT< C > & operator++()
    preincrement operator.
    \n-
    bool operator!=(const EdgeIteratorT< const typename std::remove_const< C >::type > &other) const
    Inequality operator.
    \n-
    bool operator==(const EdgeIteratorT< const typename std::remove_const< C >::type > &other) const
    Equality operator.
    \n-
    EdgeIteratorT(const EdgeIteratorT< C1 > &other)
    Copy Constructor.
    \n-
    bool operator!=(const EdgeIteratorT< typename std::remove_const< C >::type > &other) const
    Inequality operator.
    \n-
    WeightType & weight() const
    Access the edge weight.
    \n-
    VertexDescriptor source() const
    The index of the source vertex of the current edge.
    \n-
    std::conditional< isMutable &&C::mutableMatrix, typenameMatrix::row_type::Iterator, typenameMatrix::row_type::ConstIterator >::type ColIterator
    The column iterator of the matrix we use.
    Definition: graph.hh:120
    \n-
    const std::remove_const< C >::type ConstContainer
    The constant type of the container type.
    Definition: graph.hh:105
    \n-
    bool operator==(const EdgeIteratorT< typename std::remove_const< C >::type > &other) const
    Equality operator.
    \n-
    EdgeIteratorT(const ColIterator &block)
    Constructor for the end iterator.
    \n-
    std::conditional< isMutable &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type Weight
    The matrix block type we use as weights.
    Definition: graph.hh:127
    \n-
    const EdgeDescriptor & operator*() const
    Get the edge descriptor.
    \n-
    const EdgeDescriptor * operator->() const
    Get the edge descriptor.
    \n-
    std::remove_const< C >::type MutableContainer
    The mutable type of the container type.
    Definition: graph.hh:101
    \n-
    The vertex iterator type of the graph.
    Definition: graph.hh:209
    \n-
    EdgeIteratorT< C > begin() const
    Get an iterator over all edges starting at the current vertex.
    \n-
    const VertexDescriptor & operator*() const
    Get the descriptor of the current vertex.
    \n-
    WeightType & weight() const
    Access the weight of the vertex.
    \n-
    VertexIteratorT(C *graph, const VertexDescriptor &current)
    Constructor.
    \n-
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type WeightType
    Definition: graph.hh:266
    \n-
    VertexIteratorT(const VertexIteratorT< MutableContainer > &other)
    \n-
    std::remove_const< C >::type MutableContainer
    The mutable type of the container type.
    Definition: graph.hh:214
    \n-
    bool operator!=(const VertexIteratorT< MutableContainer > &other) const
    Inequality operator.
    \n-
    @ isMutable
    whether C is mutable.
    Definition: graph.hh:225
    \n-
    bool operator==(const VertexIteratorT< MutableContainer > &other) const
    Equality operator.
    \n-
    const std::remove_const< C >::type ConstContainer
    The constant type of the container type.
    Definition: graph.hh:218
    \n-
    VertexIteratorT< C > & operator++()
    Move to the next vertex.
    \n-
    EdgeIteratorT< C > end() const
    Get an iterator over all edges starting at the current vertex.
    \n-
    bool operator==(const VertexIteratorT< ConstContainer > &other) const
    Equality operator.
    \n-
    bool operator!=(const VertexIteratorT< ConstContainer > &other) const
    Inequality operator.
    \n-
    VertexIteratorT(const VertexDescriptor &current)
    Constructor for the end iterator.
    \n-
    A subgraph of a graph.
    Definition: graph.hh:443
    \n-
    EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor &target) const
    Find the descriptor of an edge.
    \n-
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n-
    EdgeIndexMap getEdgeIndexMap()
    Get an edge index map for the graph.
    \n-
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n-
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n-
    ConstVertexIterator end() const
    Get an iterator over the vertices.
    \n-
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n-
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n-
    T Excluded
    Random access container providing information about which vertices are excluded.
    Definition: graph.hh:454
    \n-
    ~SubGraph()
    Destructor.
    \n-
    EdgeIterator ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:618
    \n-
    G Graph
    The type of the graph we are a sub graph for.
    Definition: graph.hh:448
    \n-
    VertexIterator ConstVertexIterator
    The constant vertex iterator type.
    Definition: graph.hh:623
    \n-
    SubGraph(const Graph &graph, const T &excluded)
    Constructor.
    \n-
    ConstVertexIterator begin() const
    Get an iterator over the vertices.
    \n-
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:459
    \n-
    VertexDescriptor * EdgeDescriptor
    Definition: graph.hh:461
    \n-
    An index map for mapping the edges to indices.
    Definition: graph.hh:470
    \n-
    EdgeIndexMap(const EdgeIndexMap &emap)
    Protect copy construction.
    Definition: graph.hh:479
    \n-
    ReadablePropertyMapTag Category
    Definition: graph.hh:472
    \n-
    EdgeIndexMap(const EdgeDescriptor &firstEdge)
    Definition: graph.hh:474
    \n-
    std::size_t operator[](const EdgeDescriptor &edge) const
    Definition: graph.hh:483
    \n-
    The edge iterator of the graph.
    Definition: graph.hh:505
    \n-
    const EdgeDescriptor & dereference() const
    The descriptor of the current edge.
    \n-
    EdgeIterator(const EdgeDescriptor &edge)
    Constructor for the end iterator.
    \n-
    bool equals(const EdgeIterator &other) const
    Equality operator.
    \n-
    EdgeIterator & advance(std::ptrdiff_t n)
    \n-
    EdgeIterator & increment()
    Preincrement operator.
    \n-
    const VertexDescriptor & target() const
    The index of the target vertex of the current edge.
    \n-
    const VertexDescriptor & source() const
    The index of the source vertex of the current edge.
    \n-
    EdgeIterator & decrement()
    Preincrement operator.
    \n-
    std::ptrdiff_t distanceTo(const EdgeIterator &other) const
    \n-
    EdgeIterator(const VertexDescriptor &source, const EdgeDescriptor &edge)
    Constructor.
    \n-
    The vertex iterator of the graph.
    Definition: graph.hh:560
    \n-
    VertexIterator(const VertexDescriptor &current)
    Constructor for end iterator.
    \n-
    VertexIterator & increment()
    Preincrement operator.
    \n-
    EdgeIterator begin() const
    Get an iterator over all edges starting at the current vertex.
    \n-
    bool equals(const VertexIterator &other) const
    Equality iterator.
    \n-
    VertexIterator(const SubGraph< G, T > *graph, const VertexDescriptor &current, const VertexDescriptor &end)
    Constructor.
    \n-
    EdgeIterator end() const
    Get an iterator over all edges starting at the current vertex.
    \n-
    const VertexDescriptor & dereference() const
    Get the descriptor of the current vertex.
    \n-
    Attaches properties to the vertices of a graph.
    Definition: graph.hh:723
    \n-
    VertexIterator end()
    Get an iterator over the vertices.
    \n-
    const Graph & graph() const
    Get the graph the properties are attached to.
    \n-
    Graph::ConstEdgeIterator ConstEdgeIterator
    The type of the constant edge iterator.
    Definition: graph.hh:766
    \n-
    VertexProperties & getVertexProperties(const VertexDescriptor &vertex)
    Get the properties associated with a vertex.
    \n-
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n-
    Graph::EdgeDescriptor EdgeDescriptor
    The edge descritor.
    Definition: graph.hh:738
    \n-
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get the mutable edge iterator over edges starting at a vertex.
    \n-
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:733
    \n-
    G Graph
    The graph we attach properties to.
    Definition: graph.hh:728
    \n-
    VM VertexMap
    The type of the map for converting the VertexDescriptor to std::size_t.
    Definition: graph.hh:756
    \n-
    EdgeIterator endEdges(const VertexDescriptor &source)
    Get the mutable edge iterator over edges starting at a vertex.
    \n-
    EdgeIterator beginEdges(const VertexDescriptor &source)
    Get the mutable edge iterator over edges starting at a vertex.
    \n-
    VP VertexProperties
    The type of the properties of the vertices.
    Definition: graph.hh:743
    \n-
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n-
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get the mutable edge iterator over edges starting at a vertex.
    \n-
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n-
    VertexIterator begin()
    Get an iterator over the vertices.
    \n-
    Graph::EdgeIterator EdgeIterator
    The type of the mutable edge iterator.
    Definition: graph.hh:761
    \n-\n-
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type EdgeIterator
    The class of the edge iterator.
    Definition: graph.hh:823
    \n-
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value, VertexProperties &, constVertexProperties & >::type properties() const
    Get the properties of the current Vertex.
    \n-
    EdgeIterator end() const
    Get an iterator over the edges starting from the current vertex.
    \n-
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::type Father
    The father class.
    Definition: graph.hh:814
    \n-
    EdgeIterator begin() const
    Get an iterator over the edges starting from the current vertex.
    \n-
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n-
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n-
    Graph::EdgeDescriptor EdgeDescriptor
    The edge descritor.
    Definition: graph.hh:993
    \n-
    const EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const VertexDescriptor &target) const
    Get the properties associated with a edge.
    \n-
    const EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge) const
    Get the properties associated with a edge.
    \n-
    const Graph & graph() const
    Get the graph the properties are attached to.
    \n-
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n-
    G Graph
    The graph we attach properties to.
    Definition: graph.hh:983
    \n-
    EM EdgeMap
    The type of the map for converting the EdgeDescriptor to std::size_t.
    Definition: graph.hh:1030
    \n-
    VM VertexMap
    The type of the map for converting the VertexDescriptor to std::size_t.
    Definition: graph.hh:1011
    \n-
    VP VertexProperties
    The type of the properties of the vertices.
    Definition: graph.hh:998
    \n-
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n-
    EP EdgeProperties
    The type of the properties of the edges;.
    Definition: graph.hh:1016
    \n-
    EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const VertexDescriptor &target)
    Get the properties associated with a edge.
    \n-
    EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge)
    Get the properties associated with a edge.
    \n-
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:988
    \n-
    PropertiesGraph(Graph &graph, const VertexMap &vmap=VertexMap(), const EdgeMap &emap=EdgeMap())
    Constructor.
    \n-\n-
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type Father
    The father class.
    Definition: graph.hh:1050
    \n-\n-
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::type Father
    The father class.
    Definition: graph.hh:1151
    \n-
    Wrapper to access the internal edge properties of a graph via operator[]()
    Definition: graph.hh:1361
    \n-
    GraphVertexPropertiesSelector(G &g)
    Constructor.
    Definition: graph.hh:1380
    \n-
    VertexProperties & operator[](const Vertex &vertex) const
    Get the properties associated to a vertex.
    Definition: graph.hh:1395
    \n-
    G Graph
    The type of the graph with internal properties.
    Definition: graph.hh:1366
    \n-
    G::VertexProperties VertexProperties
    The type of the vertex properties.
    Definition: graph.hh:1370
    \n-
    GraphVertexPropertiesSelector()
    Default constructor.
    Definition: graph.hh:1386
    \n-
    G::VertexDescriptor Vertex
    The vertex descriptor.
    Definition: graph.hh:1374
    \n-
    Wrapper to access the internal vertex properties of a graph via operator[]()
    Definition: graph.hh:1409
    \n-
    EdgeProperties & operator[](const Edge &edge) const
    Get the properties associated to a vertex.
    Definition: graph.hh:1442
    \n-
    G::EdgeProperties EdgeProperties
    The type of the vertex properties.
    Definition: graph.hh:1418
    \n-
    G::EdgeDescriptor Edge
    The edge descriptor.
    Definition: graph.hh:1422
    \n-
    GraphEdgePropertiesSelector()
    Default constructor.
    Definition: graph.hh:1434
    \n-
    G Graph
    The type of the graph with internal properties.
    Definition: graph.hh:1414
    \n-
    GraphEdgePropertiesSelector(G &g)
    Constructor.
    Definition: graph.hh:1428
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n+
    row_type::Iterator ColIterator
    Iterator for the entries of each row.
    Definition: bcrsmatrix.hh:704
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n+
    Iterator access to matrix rows
    Definition: bcrsmatrix.hh:579
    \n+
    Iterator class for sequential creation of blocks
    Definition: bcrsmatrix.hh:957
    \n+
    void insert(size_type j)
    put column index in row
    Definition: bcrsmatrix.hh:1064
    \n+
    Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
    Definition: matrixmatrix.hh:510
    \n+
    Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
    Definition: matrixmatrix.hh:535
    \n+
    Definition: matrixutils.hh:27
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,2296 +4,722 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-graph.hh\n+matrixmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_GRAPH_HH\n- 6#define DUNE_AMG_GRAPH_HH\n+ 5#ifndef DUNE_ISTL_MATRIXMATRIX_HH\n+ 6#define DUNE_ISTL_MATRIXMATRIX_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17\n- 18namespace Dune\n- 19{\n- 20 namespace Amg\n- 21 {\n- 49 template\n-50 class MatrixGraph\n- 51 {\n- 52 public:\n-56 typedef M Matrix;\n- 57\n-61 typedef typename std::remove_const::type MutableMatrix;\n- 62\n-66 typedef typename M::block_type Weight;\n+ 8#include \n+ 9\n+ 10#include \n+ 11#include \n+ 12#include \n+ 13namespace Dune\n+ 14{\n+ 15\n+ 26 namespace\n+ 27 {\n+ 28\n+ 37 template\n+ 38 struct NonzeroPatternTraverser\n+ 39 {};\n+ 40\n+ 41\n+ 42 template<>\n+ 43 struct NonzeroPatternTraverser<0>\n+ 44 {\n+ 45 template\n+ 46 static void traverse(const Dune::BCRSMatrix,A1>&\n+A,\n+ 47 const Dune::BCRSMatrix,A2>& B,\n+ 48 F& func)\n+ 49 {\n+ 50 if(A.M()!=B.N())\n+ 51 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<,A1>::\n+ConstRowIterator Row;\n+ 54 typedef typename Dune::BCRSMatrix,A1>::\n+ConstColIterator Col;\n+ 55 typedef typename Dune::BCRSMatrix,A2>::\n+ConstColIterator BCol;\n+ 56 for(Row row= A.begin(); row != A.end(); ++row) {\n+ 57 // Loop over all column entries\n+ 58 for(Col col = row->begin(); col != row->end(); ++col) {\n+ 59 // entry at i,k\n+ 60 // search for all nonzeros in row k\n+ 61 for(BCol bcol = B[col.index()].begin(); bcol != B[col.index()].end();\n+++bcol) {\n+ 62 func(*col, *bcol, row.index(), bcol.index());\n+ 63 }\n+ 64 }\n+ 65 }\n+ 66 }\n 67\n-73 typedef typename M::size_type VertexDescriptor;\n- 74\n-80 typedef std::ptrdiff_t EdgeDescriptor;\n+ 68 };\n+ 69\n+ 70 template<>\n+ 71 struct NonzeroPatternTraverser<1>\n+ 72 {\n+ 73 template\n+ 74 static void traverse(const Dune::BCRSMatrix,A1>&\n+A,\n+ 75 const Dune::BCRSMatrix,A2>& B,\n+ 76 F& func)\n+ 77 {\n+ 78\n+ 79 if(A.N()!=B.N())\n+ 80 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<::type>::value\n-87 };\n- 88\n- 89\n- 93 template\n-94 class EdgeIteratorT\n- 95 {\n- 96\n- 97 public:\n-101 typedef typename std::remove_const::type MutableContainer;\n-105 typedef const typename std::remove_const::type ConstContainer;\n+ 82 typedef typename Dune::BCRSMatrix,A1>::\n+ConstRowIterator Row;\n+ 83 typedef typename Dune::BCRSMatrix,A1>::\n+ConstColIterator Col;\n+ 84 typedef typename Dune::BCRSMatrix,A2>::\n+ConstColIterator BCol;\n+ 85\n+ 86 for(Row row=A.begin(); row!=A.end(); ++row) {\n+ 87 for(Col col=row->begin(); col!=row->end(); ++col) {\n+ 88 for(BCol bcol = B[row.index()].begin(); bcol != B[row.index()].end();\n+++bcol) {\n+ 89 func(*col, *bcol, col.index(), bcol.index());\n+ 90 }\n+ 91 }\n+ 92 }\n+ 93 }\n+ 94 };\n+ 95\n+ 96 template<>\n+ 97 struct NonzeroPatternTraverser<2>\n+ 98 {\n+ 99 template\n+ 100 static void traverse(const BCRSMatrix,A1>& mat,\n+ 101 const BCRSMatrix,A2>& matt,\n+ 102 F& func)\n+ 103 {\n+ 104 if(mat.M()!=matt.M())\n+ 105 DUNE_THROW(ISTLError, \"The sizes of the matrices do not match: \"<;\n- 108 friend class EdgeIteratorT;\n- 109\n- 110 enum {\n- 112 isMutable = std::is_same::value\n-113 };\n- 114\n- 118 typedef typename std::conditional::type\n-120 ColIterator;\n- 121\n- 125 typedef typename std::conditional::type\n-127 Weight;\n- 128\n-136 EdgeIteratorT(const VertexDescriptor& source, const ColIterator& block,\n- 137 const ColIterator& end, const EdgeDescriptor& edge);\n- 138\n-145 EdgeIteratorT(const ColIterator& block);\n- 146\n- 151 template\n-152 EdgeIteratorT(const EdgeIteratorT& other);\n- 153\n- 154 typedef typename std::conditional::type>::value && C::mutableMatrix,\n- 155 typename M::block_type, const typename M::block_type>::type\n-156 WeightType;\n- 157\n-161 WeightType& weight() const;\n+ 107 typedef typename BCRSMatrix,A1>::ConstRowIterator\n+row_iterator;\n+ 108 typedef typename BCRSMatrix,A1>::ConstColIterator\n+col_iterator;\n+ 109 typedef typename BCRSMatrix,A2>::ConstRowIterator\n+row_iterator_t;\n+ 110 typedef typename BCRSMatrix,A2>::ConstColIterator\n+col_iterator_t;\n+ 111\n+ 112 for(row_iterator mrow=mat.begin(); mrow != mat.end(); ++mrow) {\n+ 113 //iterate over the column entries\n+ 114 // mt is a transposed matrix crs therefore it is treated as a ccs matrix\n+ 115 // and the row_iterator iterates over the columns of the transposed\n+matrix.\n+ 116 // search the row of the transposed matrix for an entry with the same\n+index\n+ 117 // as the mcol iterator\n+ 118\n+ 119 for(row_iterator_t mtcol=matt.begin(); mtcol != matt.end(); ++mtcol) {\n+ 120 //Search for col entries in mat that have a corrsponding row index in matt\n+ 121 // (i.e. corresponding col index in the as this is the transposed matrix\n+ 122 col_iterator_t mtrow=mtcol->begin();\n+ 123 bool funcCalled = false;\n+ 124 for(col_iterator mcol=mrow->begin(); mcol != mrow->end(); ++mcol) {\n+ 125 // search\n+ 126 // TODO: This should probably be substituted by a binary search\n+ 127 for( ; mtrow != mtcol->end(); ++mtrow)\n+ 128 if(mtrow.index()>=mcol.index())\n+ 129 break;\n+ 130 if(mtrow != mtcol->end() && mtrow.index()==mcol.index()) {\n+ 131 func(*mcol, *mtrow, mtcol.index());\n+ 132 funcCalled = true;\n+ 133 // In some cases we only search for one pair, then we break here\n+ 134 // and continue with the next column.\n+ 135 if(F::do_break)\n+ 136 break;\n+ 137 }\n+ 138 }\n+ 139 // move on with func only if func was called, otherwise they might\n+ 140 // get out of sync\n+ 141 if (funcCalled)\n+ 142 func.nextCol();\n+ 143 }\n+ 144 func.nextRow();\n+ 145 }\n+ 146 }\n+ 147 };\n+ 148\n+ 149\n+ 150\n+ 151 template\n+ 152 class SparsityPatternInitializer\n+ 153 {\n+ 154 public:\n+155 enum {do_break=true};\n+156 typedef typename BCRSMatrix,A>::CreateIterator\n+CreateIterator;\n+157 typedef typename BCRSMatrix,A>::size_type size_type;\n+ 158\n+ 159 SparsityPatternInitializer(CreateIterator iter)\n+ 160 : rowiter(iter)\n+ 161 {}\n 162\n-164 EdgeIteratorT& operator++();\n- 165\n-167 bool operator!=(const EdgeIteratorT::type>&\n-other) const;\n+ 163 template\n+ 164 void operator()(const T1&, const T2&, size_type j)\n+ 165 {\n+ 166 rowiter.insert(j);\n+ 167 }\n 168\n-170 bool operator!=(const EdgeIteratorT::\n-type>& other) const;\n- 171\n-173 bool operator==(const EdgeIteratorT::type>&\n-other) const;\n- 174\n-176 bool operator==(const EdgeIteratorT::\n-type>& other) const;\n- 177\n-179 VertexDescriptor target() const;\n+ 169 void nextRow()\n+ 170 {\n+ 171 ++rowiter;\n+ 172 }\n+ 173 void nextCol()\n+ 174 {}\n+ 175\n+ 176 private:\n+ 177 CreateIterator rowiter;\n+ 178 };\n+ 179\n 180\n-182 VertexDescriptor source() const;\n- 183\n-185 const EdgeDescriptor& operator*() const;\n- 186\n-188 const EdgeDescriptor* operator->() const;\n+ 181 template\n+ 182 class MatrixInitializer\n+ 183 {\n+ 184 public:\n+185 enum {do_break=true};\n+186 typedef typename Dune::BCRSMatrix,TA> Matrix;\n+187 typedef typename Matrix::CreateIterator CreateIterator;\n+188 typedef typename Matrix::size_type size_type;\n 189\n- 190 private:\n- 192 VertexDescriptor source_;\n- 194 ColIterator block_;\n- 195 /***\n- 196 * @brief The column iterator positioned at the end of the row\n- 197 * of vertex source_\n- 198 */\n- 199 ColIterator blockEnd_;\n- 201 EdgeDescriptor edge_;\n- 202 };\n- 203\n- 207 template\n-208 class VertexIteratorT\n- 209 {\n- 210 public:\n-214 typedef typename std::remove_const::type MutableContainer;\n-218 typedef const typename std::remove_const::type ConstContainer;\n- 219\n- 220 friend class VertexIteratorT;\n- 221 friend class VertexIteratorT;\n+ 190 MatrixInitializer(Matrix& A_, size_type)\n+ 191 : count(0), A(A_)\n+ 192 {}\n+ 193 template\n+ 194 void operator()(const T1&, const T2&, int)\n+ 195 {\n+ 196 ++count;\n+ 197 }\n+ 198\n+ 199 void nextCol()\n+ 200 {}\n+ 201\n+ 202 void nextRow()\n+ 203 {}\n+ 204\n+ 205 std::size_t nonzeros()\n+ 206 {\n+ 207 return count;\n+ 208 }\n+ 209\n+ 210 template\n+ 211 void initPattern(const BCRSMatrix,A1>& mat1,\n+ 212 const BCRSMatrix,A2>& mat2)\n+ 213 {\n+ 214 SparsityPatternInitializer sparsity(A.createbegin());\n+ 215 NonzeroPatternTraverser::traverse(mat1,mat2,sparsity);\n+ 216 }\n+ 217\n+ 218 private:\n+ 219 std::size_t count;\n+ 220 Matrix& A;\n+ 221 };\n 222\n- 223 enum {\n- 225 isMutable = std::is_same::value\n-226 };\n- 227\n-233 explicit VertexIteratorT(C* graph, const VertexDescriptor& current);\n- 234\n-242 explicit VertexIteratorT(const VertexDescriptor& current);\n- 243\n-244 VertexIteratorT(const VertexIteratorT& other);\n- 245\n-250 VertexIteratorT& operator++();\n- 251\n-253 bool operator!=(const VertexIteratorT& other) const;\n- 254\n-256 bool operator==(const VertexIteratorT& other) const;\n- 257\n-259 bool operator!=(const VertexIteratorT& other) const;\n- 260\n-262 bool operator==(const VertexIteratorT& other) const;\n- 263\n- 264 typedef typename std::conditional::type>::value && C::mutableMatrix,\n- 265 typename M::block_type, const typename M::block_type>::type\n-266 WeightType;\n-268 WeightType& weight() const;\n- 269\n-274 const VertexDescriptor& operator*() const;\n- 275\n-281 EdgeIteratorT begin() const;\n- 282\n-288 EdgeIteratorT end() const;\n- 289\n- 290 private:\n- 291 C* graph_;\n- 292 VertexDescriptor current_;\n- 293 };\n+ 223 template\n+ 224 class MatrixInitializer<1,T,TA,n,m>\n+ 225 {\n+ 226 public:\n+227 enum {do_break=false};\n+228 typedef Dune::BCRSMatrix,TA> Matrix;\n+229 typedef typename Matrix::CreateIterator CreateIterator;\n+230 typedef typename Matrix::size_type size_type;\n+ 231\n+ 232 MatrixInitializer(Matrix& A_, size_type rows)\n+ 233 : A(A_), entries(rows)\n+ 234 {}\n+ 235\n+ 236 template\n+ 237 void operator()(const T1&, const T2&, size_type i, size_type j)\n+ 238 {\n+ 239 entries[i].insert(j);\n+ 240 }\n+ 241\n+ 242 void nextCol()\n+ 243 {}\n+ 244\n+ 245 size_type nonzeros()\n+ 246 {\n+ 247 size_type nnz=0;\n+ 248 typedef typename std::vector >::const_iterator Iter;\n+ 249 for(Iter iter = entries.begin(); iter != entries.end(); ++iter)\n+ 250 nnz+=(*iter).size();\n+ 251 return nnz;\n+ 252 }\n+ 253 template\n+ 254 void initPattern(const BCRSMatrix,A1>&,\n+ 255 const BCRSMatrix,A2>&)\n+ 256 {\n+ 257 typedef typename std::vector >::const_iterator Iter;\n+ 258 CreateIterator citer = A.createbegin();\n+ 259 for(Iter iter = entries.begin(); iter != entries.end(); ++iter, ++citer) {\n+ 260 typedef std::set::const_iterator SetIter;\n+ 261 for(SetIter index=iter->begin(); index != iter->end(); ++index)\n+ 262 citer.insert(*index);\n+ 263 }\n+ 264 }\n+ 265\n+ 266 private:\n+ 267 Matrix& A;\n+ 268 std::vector > entries;\n+ 269 };\n+ 270\n+ 271 template\n+ 272 struct MatrixInitializer<0,T,TA,n,m>\n+ 273 : public MatrixInitializer<1,T,TA,n,m>\n+ 274 {\n+ 275 MatrixInitializer(Dune::BCRSMatrix,TA>& A_,\n+ 276 typename Dune::BCRSMatrix,TA>::size_type rows)\n+ 277 : MatrixInitializer<1,T,TA,n,m>(A_,rows)\n+ 278 {}\n+ 279 };\n+ 280\n+ 281\n+ 282 template\n+ 283 void addMatMultTransposeMat(FieldMatrix& res, const\n+FieldMatrix& mat,\n+ 284 const FieldMatrix& matt)\n+ 285 {\n+ 286 typedef typename FieldMatrix::size_type size_type;\n+ 287\n+ 288 for(size_type row=0; row > ConstEdgeIterator;\n- 299\n-303 typedef EdgeIteratorT > EdgeIterator;\n- 304\n-308 typedef VertexIteratorT > ConstVertexIterator;\n- 309\n-313 typedef VertexIteratorT > VertexIterator;\n- 314\n-319 MatrixGraph(Matrix& matrix);\n- 320\n-324 ~MatrixGraph();\n- 325\n-330 VertexIterator begin();\n- 331\n-336 VertexIterator end();\n- 337\n-342 ConstVertexIterator begin() const;\n- 343\n-348 ConstVertexIterator end() const;\n- 349\n-356 EdgeIterator beginEdges(const VertexDescriptor& source);\n- 357\n-364 EdgeIterator endEdges(const VertexDescriptor& source);\n+ 295 template\n+ 296 void addTransposeMatMultMat(FieldMatrix& res, const\n+FieldMatrix& mat,\n+ 297 const FieldMatrix& matt)\n+ 298 {\n+ 299 typedef typename FieldMatrix::size_type size_type;\n+ 300 for(size_type i=0; i\n+ 308 void addMatMultMat(FieldMatrix& res, const FieldMatrix&\n+mat,\n+ 309 const FieldMatrix& matt)\n+ 310 {\n+ 311 typedef typename FieldMatrix::size_type size_type;\n+ 312 for(size_type row=0; row\n+ 321 class EntryAccumulatorFather\n+ 322 {\n+ 323 public:\n+324 enum {do_break=false};\n+325 typedef BCRSMatrix,A> Matrix;\n+326 typedef typename Matrix::RowIterator Row;\n+327 typedef typename Matrix::ColIterator Col;\n+ 328\n+ 329 EntryAccumulatorFather(Matrix& mat_)\n+ 330 : mat(mat_), row(mat.begin())\n+ 331 {\n+ 332 mat=0;\n+ 333 col=row->begin();\n+ 334 }\n+ 335 void nextRow()\n+ 336 {\n+ 337 ++row;\n+ 338 if(row!=mat.end())\n+ 339 col=row->begin();\n+ 340 }\n+ 341\n+ 342 void nextCol()\n+ 343 {\n+ 344 ++this->col;\n+ 345 }\n+ 346 protected:\n+347 Matrix& mat;\n+ 348 private:\n+ 349 Row row;\n+ 350 protected:\n+351 Col col;\n+ 352 };\n+ 353\n+ 354 template\n+ 355 class EntryAccumulator\n+ 356 : public EntryAccumulatorFather\n+ 357 {\n+ 358 public:\n+359 typedef BCRSMatrix,A> Matrix;\n+360 typedef typename Matrix::size_type size_type;\n+ 361\n+ 362 EntryAccumulator(Matrix& mat_)\n+ 363 : EntryAccumulatorFather(mat_)\n+ 364 {}\n 365\n- 366\n-373 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n- 374\n-381 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n- 382\n-387 Matrix& matrix();\n- 388\n-393 const Matrix& matrix() const;\n- 394\n-398 std::size_t noVertices() const;\n- 399\n-406 VertexDescriptor maxVertex() const;\n- 407\n-411 std::size_t noEdges() const;\n- 412\n-419 EdgeDescriptor findEdge(const VertexDescriptor& source,\n- 420 const VertexDescriptor& target) const;\n- 421\n- 422 private:\n- 424 Matrix& matrix_;\n- 426 EdgeDescriptor* start_;\n- 428 MatrixGraph(const MatrixGraph&);\n- 429\n+ 366 template\n+ 367 void operator()(const T1& t1, const T2& t2, size_type i)\n+ 368 {\n+ 369 assert(this->col.index()==i);\n+ 370 addMatMultMat(*(this->col),t1,t2);\n+ 371 }\n+ 372 };\n+ 373\n+ 374 template\n+ 375 class EntryAccumulator\n+ 376 : public EntryAccumulatorFather\n+ 377 {\n+ 378 public:\n+379 typedef BCRSMatrix,A> Matrix;\n+380 typedef typename Matrix::size_type size_type;\n+ 381\n+ 382 EntryAccumulator(Matrix& mat_)\n+ 383 : EntryAccumulatorFather(mat_)\n+ 384 {}\n+ 385\n+ 386 template\n+ 387 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)\n+ 388 {\n+ 389 addMatMultMat(this->mat[i][j], t1, t2);\n+ 390 }\n+ 391 };\n+ 392\n+ 393 template\n+ 394 class EntryAccumulator\n+ 395 : public EntryAccumulatorFather\n+ 396 {\n+ 397 public:\n+398 typedef BCRSMatrix,A> Matrix;\n+399 typedef typename Matrix::size_type size_type;\n+ 400\n+ 401 EntryAccumulator(Matrix& mat_)\n+ 402 : EntryAccumulatorFather(mat_)\n+ 403 {}\n+ 404\n+ 405 template\n+ 406 void operator()(const T1& t1, const T2& t2, size_type i, size_type j)\n+ 407 {\n+ 408 addTransposeMatMultMat(this->mat[i][j], t1, t2);\n+ 409 }\n+ 410 };\n+ 411\n+ 412 template\n+ 413 class EntryAccumulator\n+ 414 : public EntryAccumulatorFather\n+ 415 {\n+ 416 public:\n+417 typedef BCRSMatrix,A> Matrix;\n+418 typedef typename Matrix::size_type size_type;\n+ 419\n+ 420 EntryAccumulator(Matrix& mat_)\n+ 421 : EntryAccumulatorFather(mat_)\n+ 422 {}\n+ 423\n+ 424 template\n+ 425 void operator()(const T1& t1, const T2& t2, [[maybe_unused]] size_type i)\n+ 426 {\n+ 427 assert(this->col.index()==i);\n+ 428 addMatMultTransposeMat(*this->col,t1,t2);\n+ 429 }\n 430 };\n 431\n- 441 template\n-442 class SubGraph\n+ 432\n+ 433 template\n+ 434 struct SizeSelector\n+ 435 {};\n+ 436\n+ 437 template<>\n+ 438 struct SizeSelector<0>\n+ 439 {\n+ 440 template\n+ 441 static std::tuple\n+ 442 size(const M1& m1, const M2& m2)\n 443 {\n- 444 public:\n-448 typedef G Graph;\n- 449\n-454 typedef T Excluded;\n- 455\n-459 typedef typename Graph::VertexDescriptor VertexDescriptor;\n- 460\n-461 typedef VertexDescriptor* EdgeDescriptor;\n- 462\n-469 class EdgeIndexMap\n- 470 {\n- 471 public:\n-472 typedef ReadablePropertyMapTag Category;\n- 473\n-474 EdgeIndexMap(const EdgeDescriptor& firstEdge)\n- 475 : firstEdge_(firstEdge)\n- 476 {}\n- 477\n-479 EdgeIndexMap(const EdgeIndexMap& emap)\n- 480 : firstEdge_(emap.firstEdge_)\n- 481 {}\n- 482\n-483 std::size_t operator[](const EdgeDescriptor& edge) const\n- 484 {\n- 485 return edge-firstEdge_;\n- 486 }\n- 487 private:\n- 489 EdgeDescriptor firstEdge_;\n- 491 EdgeIndexMap()\n- 492 {}\n- 493 };\n- 494\n-499 EdgeIndexMap getEdgeIndexMap();\n+ 444 return std::make_tuple(m1.N(), m2.M());\n+ 445 }\n+ 446 };\n+ 447\n+ 448 template<>\n+ 449 struct SizeSelector<1>\n+ 450 {\n+ 451 template\n+ 452 static std::tuple\n+ 453 size(const M1& m1, const M2& m2)\n+ 454 {\n+ 455 return std::make_tuple(m1.M(), m2.M());\n+ 456 }\n+ 457 };\n+ 458\n+ 459\n+ 460 template<>\n+ 461 struct SizeSelector<2>\n+ 462 {\n+ 463 template\n+ 464 static std::tuple\n+ 465 size(const M1& m1, const M2& m2)\n+ 466 {\n+ 467 return std::make_tuple(m1.N(), m2.N());\n+ 468 }\n+ 469 };\n+ 470\n+ 471 template\n+ 472 void matMultMat(BCRSMatrix,A>& res, const\n+BCRSMatrix,A1>& mat1,\n+ 473 const BCRSMatrix,A2>& mat2)\n+ 474 {\n+ 475 // First step is to count the number of nonzeros\n+ 476 typename BCRSMatrix,A>::size_type rows, cols;\n+ 477 std::tie(rows,cols)=SizeSelector::size(mat1, mat2);\n+ 478 MatrixInitializer patternInit(res, rows);\n+ 479 Timer timer;\n+ 480 NonzeroPatternTraverser::traverse(mat1,mat2,patternInit);\n+ 481 res.setSize(rows, cols, patternInit.nonzeros());\n+ 482 res.setBuildMode(BCRSMatrix,A>::row_wise);\n+ 483\n+ 484 //std::cout<<\"Counting nonzeros took \"< entriesAccu(res);\n+ 495 NonzeroPatternTraverser::traverse(mat1,mat2,entriesAccu);\n+ 496 //std::cout<<\"Calculating entries took \"<\n- 505 {\n- 506 public:\n-512 explicit EdgeIterator(const VertexDescriptor& source, const EdgeDescriptor&\n-edge);\n- 513\n-521 explicit EdgeIterator(const EdgeDescriptor& edge);\n- 522\n-524 bool equals(const EdgeIterator& other) const;\n+ 508 template\n+509 struct MatMultMatResult\n+ 510 {};\n+ 511\n+ 512 template\n+513 struct MatMultMatResult,FieldMatrix >\n+ 514 {\n+515 typedef FieldMatrix type;\n+ 516 };\n+ 517\n+ 518 template\n+519 struct MatMultMatResult,A\n+>,BCRSMatrix,A1 > >\n+ 520 {\n+ 521 typedef BCRSMatrix,FieldMatrix >::type,\n+522 std::allocator,FieldMatrix >::type> > type;\n+ 523 };\n+ 524\n 525\n-527 EdgeIterator& increment();\n- 528\n-530 EdgeIterator& decrement();\n- 531\n-532 EdgeIterator& advance(std::ptrdiff_t n);\n- 533\n-535 const EdgeDescriptor& dereference() const;\n+ 533 template\n+534 struct TransposedMatMultMatResult\n+ 535 {};\n 536\n-538 const VertexDescriptor& target() const;\n- 539\n-541 const VertexDescriptor& source() const;\n+ 537 template\n+538 struct TransposedMatMultMatResult,FieldMatrix >\n+ 539 {\n+540 typedef FieldMatrix type;\n+ 541 };\n 542\n-543 std::ptrdiff_t distanceTo(const EdgeIterator& other) const;\n- 544\n- 545 private:\n- 547 VertexDescriptor source_;\n- 552 EdgeDescriptor edge_;\n- 553 };\n- 554\n-558 class VertexIterator\n- 559 : public ForwardIteratorFacade\n- 560 {\n- 561 public:\n-568 explicit VertexIterator(const SubGraph* graph, const VertexDescriptor&\n-current,\n- 569 const VertexDescriptor& end);\n- 570\n- 571\n-578 explicit VertexIterator(const VertexDescriptor& current);\n- 579\n-581 VertexIterator& increment();\n- 582\n-584 bool equals(const VertexIterator& other) const;\n- 585\n-590 const VertexDescriptor& dereference() const;\n- 591\n-597 EdgeIterator begin() const;\n- 598\n-604 EdgeIterator end() const;\n- 605\n- 606 private:\n- 608 const SubGraph* graph_;\n- 610 VertexDescriptor current_;\n- 612 VertexDescriptor end_;\n- 613 };\n- 614\n-618 typedef EdgeIterator ConstEdgeIterator;\n- 619\n-623 typedef VertexIterator ConstVertexIterator;\n- 624\n-629 ConstVertexIterator begin() const;\n- 630\n-635 ConstVertexIterator end() const;\n- 636\n-643 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n- 644\n-651 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n- 652\n-656 std::size_t noVertices() const;\n- 657\n-664 VertexDescriptor maxVertex() const;\n- 665\n-669 std::size_t noEdges() const;\n-676 EdgeDescriptor findEdge(const VertexDescriptor& source,\n- 677 const VertexDescriptor& target) const;\n-685 SubGraph(const Graph& graph, const T& excluded);\n- 686\n-690 ~SubGraph();\n- 691\n- 692 private:\n- 694 const T& excluded_;\n- 696 std::size_t noVertices_;\n- 698 VertexDescriptor endVertex_;\n- 700 int noEdges_;\n- 705 VertexDescriptor maxVertex_;\n- 707 VertexDescriptor* edges_;\n- 709 std::ptrdiff_t* start_;\n- 711 std::ptrdiff_t* end_;\n- 713 SubGraph(const SubGraph&)\n- 714 {}\n- 715 };\n- 716\n- 717\n- 721 template\n-722 class VertexPropertiesGraph\n- 723 {\n- 724 public:\n-728 typedef G Graph;\n- 729\n-733 typedef typename Graph::VertexDescriptor VertexDescriptor;\n- 734\n-738 typedef typename Graph::EdgeDescriptor EdgeDescriptor;\n- 739\n-743 typedef VP VertexProperties;\n- 744\n-756 typedef VM VertexMap;\n- 757\n-761 typedef typename Graph::EdgeIterator EdgeIterator;\n- 762\n-766 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;\n- 767\n-773 EdgeIterator beginEdges(const VertexDescriptor& source);\n- 774\n-780 EdgeIterator endEdges(const VertexDescriptor& source);\n- 781\n-787 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n- 788\n-794 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n- 795\n- 796\n- 797 template\n-798 class VertexIteratorT\n- 799 : public std::conditional::\n-type,\n- 800 C>::value,\n- 801 typename Graph::VertexIterator,\n- 802 typename Graph::ConstVertexIterator>::type\n- 803 {\n- 804 friend class VertexIteratorT::type>;\n- 805 friend class VertexIteratorT::type>;\n- 806 public:\n- 810 typedef typename std::conditional::type,\n- 811 C>::value,\n- 812 typename Graph::VertexIterator,\n- 813 typename Graph::ConstVertexIterator>::type\n-814 Father;\n- 815\n- 819 typedef typename std::conditional::type,\n- 820 C>::value,\n- 821 typename Graph::EdgeIterator,\n- 822 typename Graph::ConstEdgeIterator>::type\n-823 EdgeIterator;\n- 824\n-830 explicit VertexIteratorT(const Father& iter,\n- 831 C* graph);\n- 832\n- 833\n-841 explicit VertexIteratorT(const Father& iter);\n- 842\n- 847 template\n-848 VertexIteratorT(const VertexIteratorT& other);\n- 849\n- 853 typename std::conditional::\n-type>::value,\n- 854 VertexProperties&,\n- 855 const VertexProperties&>::type\n-856 properties() const;\n- 857\n-863 EdgeIterator begin() const;\n- 864\n-870 EdgeIterator end() const;\n- 871\n- 872 private:\n- 876 C* graph_;\n- 877 };\n- 878\n- 882 typedef VertexIteratorT > VertexIterator;\n- 884\n- 888 typedef VertexIteratorT > ConstVertexIterator;\n- 890\n-895 VertexIterator begin();\n- 896\n-901 VertexIterator end();\n- 902\n-907 ConstVertexIterator begin() const;\n- 908\n-913 ConstVertexIterator end() const;\n- 914\n-920 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);\n- 921\n-927 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex)\n-const;\n- 928\n-933 const Graph& graph() const;\n- 934\n-938 std::size_t noVertices() const;\n- 939\n-943 std::size_t noEdges() const;\n- 944\n-951 VertexDescriptor maxVertex() const;\n- 952\n-958 VertexPropertiesGraph(Graph& graph, const VertexMap vmap=VertexMap());\n- 959\n- 960 private:\n- 961 VertexPropertiesGraph(const VertexPropertiesGraph&)\n- 962 {}\n- 963\n- 965 Graph& graph_;\n- 967 VertexMap vmap_;\n-969 std::vector vertexProperties_;\n- 970\n- 971 };\n- 972\n- 976 template\n-977 class PropertiesGraph\n- 978 {\n- 979 public:\n-983 typedef G Graph;\n- 984\n-988 typedef typename Graph::VertexDescriptor VertexDescriptor;\n- 989\n-993 typedef typename Graph::EdgeDescriptor EdgeDescriptor;\n- 994\n-998 typedef VP VertexProperties;\n- 999\n-1011 typedef VM VertexMap;\n- 1012\n-1016 typedef EP EdgeProperties;\n- 1017\n- 1018\n-1030 typedef EM EdgeMap;\n- 1031\n- 1032 template\n-1033 class EdgeIteratorT\n- 1034 : public std::conditional::\n-type,\n- 1035 C>::value,\n- 1036 typename Graph::EdgeIterator,\n- 1037 typename Graph::ConstEdgeIterator>::type\n- 1038 {\n- 1039\n- 1040 friend class EdgeIteratorT::type>;\n- 1041 friend class EdgeIteratorT::type>;\n- 1042 public:\n- 1046 typedef typename std::conditional::type,\n- 1047 C>::value,\n- 1048 typename Graph::EdgeIterator,\n- 1049 typename Graph::ConstEdgeIterator>::type\n-1050 Father;\n- 1051\n-1057 explicit EdgeIteratorT(const Father& iter,\n- 1058 C* graph);\n- 1059\n-1067 explicit EdgeIteratorT(const Father& iter);\n- 1068\n- 1073 template\n-1074 EdgeIteratorT(const EdgeIteratorT& other);\n- 1075\n- 1079 typename std::conditional::\n-type>::value,\n- 1080 EdgeProperties&,\n- 1081 const EdgeProperties&>::type\n-1082 properties() const;\n- 1083\n- 1084 private:\n-1088 C* graph_;\n- 1089 };\n- 1090\n- 1094 typedef EdgeIteratorT > EdgeIterator;\n- 1097\n- 1101 typedef EdgeIteratorT > ConstEdgeIterator;\n- 1104\n-1110 EdgeIterator beginEdges(const VertexDescriptor& source);\n- 1111\n-1117 EdgeIterator endEdges(const VertexDescriptor& source);\n- 1118\n-1124 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n- 1125\n-1131 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n- 1132\n- 1133\n- 1134 template\n-1135 class VertexIteratorT\n- 1136 : public std::conditional::\n-type,\n- 1137 C>::value,\n- 1138 typename Graph::VertexIterator,\n- 1139 typename Graph::ConstVertexIterator>::type\n- 1140 {\n- 1141 friend class VertexIteratorT::type>;\n- 1142 friend class VertexIteratorT::type>;\n- 1143 public:\n- 1147 typedef typename std::conditional::type,\n- 1148 C>::value,\n- 1149 typename Graph::VertexIterator,\n- 1150 typename Graph::ConstVertexIterator>::type\n-1151 Father;\n- 1152\n-1158 explicit VertexIteratorT(const Father& iter,\n- 1159 C* graph);\n- 1160\n- 1161\n-1169 explicit VertexIteratorT(const Father& iter);\n- 1170\n- 1175 template\n-1176 VertexIteratorT(const VertexIteratorT& other);\n- 1177\n- 1181 typename std::conditional::\n-type>::value,\n- 1182 VertexProperties&,\n- 1183 const VertexProperties&>::type\n-1184 properties() const;\n- 1185\n-1191 EdgeIteratorT begin() const;\n- 1192\n-1198 EdgeIteratorT end() const;\n- 1199\n- 1200 private:\n- 1204 C* graph_;\n- 1205 };\n- 1206\n- 1210 typedef VertexIteratorT > VertexIterator;\n- 1213\n- 1217 typedef VertexIteratorT > ConstVertexIterator;\n- 1220\n-1225 VertexIterator begin();\n- 1226\n-1231 VertexIterator end();\n- 1232\n-1237 ConstVertexIterator begin() const;\n- 1238\n-1243 ConstVertexIterator end() const;\n- 1244\n-1250 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);\n- 1251\n-1257 const VertexProperties& getVertexProperties(const VertexDescriptor&\n-vertex) const;\n- 1258\n-1265 EdgeDescriptor findEdge(const VertexDescriptor& source,\n- 1266 const VertexDescriptor& target)\n- 1267 {\n- 1268 return graph_.findEdge(source,target);\n- 1269 }\n- 1270\n-1276 EdgeProperties& getEdgeProperties(const EdgeDescriptor& edge);\n- 1277\n- 1278\n-1284 const EdgeProperties& getEdgeProperties(const EdgeDescriptor& edge) const;\n- 1285\n-1292 EdgeProperties& getEdgeProperties(const VertexDescriptor& source,\n- 1293 const VertexDescriptor& target);\n- 1294\n-1301 const EdgeProperties& getEdgeProperties(const VertexDescriptor& source,\n- 1302 const VertexDescriptor& target) const;\n- 1303\n-1308 const Graph& graph() const;\n- 1309\n-1313 std::size_t noVertices() const;\n- 1314\n-1318 std::size_t noEdges() const;\n- 1319\n-1326 VertexDescriptor maxVertex() const;\n- 1327\n-1334 PropertiesGraph(Graph& graph, const VertexMap& vmap=VertexMap(),\n- 1335 const EdgeMap& emap=EdgeMap());\n- 1336\n- 1337 private:\n- 1338 PropertiesGraph(const PropertiesGraph&)\n- 1339 {}\n- 1340\n- 1342 Graph& graph_;\n- 1345 VertexMap vmap_;\n- 1346 std::vector vertexProperties_;\n- 1348 EdgeMap emap_;\n-1350 std::vector edgeProperties_;\n- 1351\n- 1352 };\n- 1353\n- 1354\n- 1359 template\n-1360 class GraphVertexPropertiesSelector\n- 1361 {\n- 1362 public:\n-1366 typedef G Graph;\n-1370 typedef typename G::VertexProperties VertexProperties;\n-1374 typedef typename G::VertexDescriptor Vertex;\n- 1375\n-1380 GraphVertexPropertiesSelector(G& g)\n- 1381 : graph_(g)\n- 1382 {}\n-1386 GraphVertexPropertiesSelector()\n- 1387 : graph_(0)\n- 1388 {}\n- 1389\n- 1390\n-1395 VertexProperties& operator[](const Vertex& vertex) const\n- 1396 {\n- 1397 return graph_->getVertexProperties(vertex);\n- 1398 }\n- 1399 private:\n- 1400 Graph* graph_;\n- 1401 };\n- 1402\n- 1407 template\n-1408 class GraphEdgePropertiesSelector\n- 1409 {\n- 1410 public:\n-1414 typedef G Graph;\n-1418 typedef typename G::EdgeProperties EdgeProperties;\n-1422 typedef typename G::EdgeDescriptor Edge;\n- 1423\n-1428 GraphEdgePropertiesSelector(G& g)\n- 1429 : graph_(g)\n- 1430 {}\n-1434 GraphEdgePropertiesSelector()\n- 1435 : graph_(0)\n- 1436 {}\n- 1437\n-1442 EdgeProperties& operator[](const Edge& edge) const\n- 1443 {\n- 1444 return graph_->getEdgeProperties(edge);\n- 1445 }\n- 1446 private:\n- 1447 Graph* graph_;\n- 1448 };\n- 1449\n- 1450\n- 1461 template\n-1462 int visitNeighbours(const G& graph, const typename G::VertexDescriptor&\n-vertex,\n- 1463 V& visitor);\n- 1464\n- 1465#ifndef DOXYGEN\n- 1466\n- 1467 template\n- 1468 MatrixGraph::MatrixGraph(M& matrix)\n- 1469 : matrix_(matrix)\n- 1470 {\n- 1471 if(matrix_.N()!=matrix_.M())\n- 1472 DUNE_THROW(ISTLError, \"Matrix has to have as many columns as rows!\");\n- 1473\n- 1474 start_ = new EdgeDescriptor[matrix_.N()+1];\n- 1475\n- 1476 typedef typename M::ConstIterator Iterator;\n- 1477 start_[matrix_.begin().index()] = 0;\n- 1478\n- 1479 for(Iterator row=matrix_.begin(); row != matrix_.end(); ++row)\n- 1480 start_[row.index()+1] = start_[row.index()] + row->size();\n- 1481 }\n- 1482\n- 1483 template\n- 1484 MatrixGraph::~MatrixGraph()\n- 1485 {\n- 1486 delete[] start_;\n- 1487 }\n- 1488\n- 1489 template\n- 1490 inline std::size_t MatrixGraph::noEdges() const\n- 1491 {\n- 1492 return start_[matrix_.N()];\n- 1493 }\n- 1494\n- 1495 template\n- 1496 inline std::size_t MatrixGraph::noVertices() const\n- 1497 {\n- 1498 return matrix_.N();\n- 1499 }\n- 1500\n- 1501 template\n- 1502 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n-maxVertex() const\n- 1503 {\n- 1504 return matrix_.N()-1;\n- 1505 }\n- 1506\n- 1507 template\n- 1508 typename MatrixGraph::EdgeDescriptor\n- 1509 MatrixGraph::findEdge(const VertexDescriptor& source,\n- 1510 const VertexDescriptor& target) const\n- 1511 {\n- 1512 typename M::ConstColIterator found =matrix_[source].find(target);\n- 1513 if(found == matrix_[source].end())\n- 1514 return std::numeric_limits::max();\n- 1515 std::size_t offset = found.offset();\n- 1516 if(target>source)\n- 1517 offset--;\n- 1518\n- 1519 assert(offset\n- 1526 inline M& MatrixGraph::matrix()\n- 1527 {\n- 1528 return matrix_;\n- 1529 }\n- 1530\n- 1531 template\n- 1532 inline const M& MatrixGraph::matrix() const\n- 1533 {\n- 1534 return matrix_;\n- 1535 }\n- 1536\n- 1537 template\n- 1538 template\n- 1539 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const VertexDescriptor&\n-source, const ColIterator& block,\n- 1540 const ColIterator& end, const EdgeDescriptor& edge)\n- 1541 : source_(source), block_(block), blockEnd_(end), edge_(edge)\n- 1542 {\n- 1543 if(block_!=blockEnd_ && block_.index() == source_) {\n- 1544 // This is the edge from the diagonal to the diagonal. Skip it.\n- 1545 ++block_;\n- 1546 }\n- 1547 }\n- 1548\n- 1549 template\n- 1550 template\n- 1551 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const ColIterator& block)\n- 1552 : block_(block)\n- 1553 {}\n- 1554\n- 1555 template\n- 1556 template\n- 1557 template\n- 1558 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const EdgeIteratorT&\n-other)\n- 1559 : source_(other.source_), block_(other.block_), blockEnd_\n-(other.blockEnd_), edge_(other.edge_)\n- 1560 {}\n- 1561\n- 1562\n- 1563 template\n- 1564 template\n- 1565 inline typename MatrixGraph::template EdgeIteratorT::WeightType&\n- 1566 MatrixGraph::EdgeIteratorT::weight() const\n- 1567 {\n- 1568 return *block_;\n- 1569 }\n- 1570\n- 1571 template\n- 1572 template\n- 1573 inline typename MatrixGraph::template EdgeIteratorT&\n-MatrixGraph::EdgeIteratorT::operator++()\n- 1574 {\n- 1575 ++block_;\n- 1576 ++edge_;\n- 1577\n- 1578 if(block_!=blockEnd_ && block_.index() == source_) {\n- 1579 // This is the edge from the diagonal to the diagonal. Skip it.\n- 1580 ++block_;\n- 1581 }\n- 1582\n- 1583 return *this;\n- 1584 }\n- 1585\n- 1586 template\n- 1587 template\n- 1588 inline bool MatrixGraph::EdgeIteratorT::operator!=(const typename\n-MatrixGraph::template EdgeIteratorT::type>&\n-other) const\n- 1589 {\n- 1590 return block_!=other.block_;\n- 1591 }\n- 1592\n- 1593 template\n- 1594 template\n- 1595 inline bool MatrixGraph::EdgeIteratorT::operator!=(const typename\n-MatrixGraph::template EdgeIteratorT::\n-type>& other) const\n- 1596 {\n- 1597 return block_!=other.block_;\n- 1598 }\n- 1599\n- 1600 template\n- 1601 template\n- 1602 inline bool MatrixGraph::EdgeIteratorT::operator==(const typename\n-MatrixGraph::template EdgeIteratorT::type>&\n-other) const\n- 1603 {\n- 1604 return block_==other.block_;\n- 1605 }\n- 1606\n- 1607 template\n- 1608 template\n- 1609 inline bool MatrixGraph::EdgeIteratorT::operator==(const typename\n-MatrixGraph::template EdgeIteratorT::\n-type>& other) const\n- 1610 {\n- 1611 return block_==other.block_;\n- 1612 }\n- 1613\n- 1614 template\n- 1615 template\n- 1616 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n-EdgeIteratorT::target() const\n- 1617 {\n- 1618 return block_.index();\n- 1619 }\n- 1620\n- 1621 template\n- 1622 template\n- 1623 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n-EdgeIteratorT::source() const\n- 1624 {\n- 1625 return source_;\n- 1626 }\n- 1627\n- 1628 template\n- 1629 template\n- 1630 inline const typename MatrixGraph::EdgeDescriptor& MatrixGraph::\n-EdgeIteratorT::operator*() const\n- 1631 {\n- 1632 return edge_;\n- 1633 }\n- 1634\n- 1635 template\n- 1636 template\n- 1637 inline const typename MatrixGraph::EdgeDescriptor* MatrixGraph::\n-EdgeIteratorT::operator->() const\n- 1638 {\n- 1639 return &edge_;\n- 1640 }\n- 1641\n- 1642 template\n- 1643 template\n- 1644 MatrixGraph::VertexIteratorT::VertexIteratorT(C* graph,\n- 1645 const VertexDescriptor& current)\n- 1646 : graph_(graph), current_(current)\n- 1647 {}\n- 1648\n- 1649\n- 1650 template\n- 1651 template\n- 1652 MatrixGraph::VertexIteratorT::VertexIteratorT(const\n-VertexDescriptor& current)\n- 1653 : current_(current)\n- 1654 {}\n- 1655\n- 1656 template\n- 1657 template\n- 1658 MatrixGraph::VertexIteratorT::VertexIteratorT(const\n-VertexIteratorT& other)\n- 1659 : graph_(other.graph_), current_(other.current_)\n- 1660 {}\n- 1661\n- 1662 template\n- 1663 template\n- 1664 inline bool MatrixGraph::VertexIteratorT::operator!=(const\n-VertexIteratorT& other) const\n- 1665 {\n- 1666 return current_ != other.current_;\n- 1667 }\n- 1668\n- 1669 template\n- 1670 template\n- 1671 inline bool MatrixGraph::VertexIteratorT::operator!=(const\n-VertexIteratorT& other) const\n- 1672 {\n- 1673 return current_ != other.current_;\n- 1674 }\n- 1675\n- 1676\n- 1677 template\n- 1678 template\n- 1679 inline bool MatrixGraph::VertexIteratorT::operator==(const\n-VertexIteratorT& other) const\n- 1680 {\n- 1681 return current_ == other.current_;\n- 1682 }\n- 1683\n- 1684 template\n- 1685 template\n- 1686 inline bool MatrixGraph::VertexIteratorT::operator==(const\n-VertexIteratorT& other) const\n- 1687 {\n- 1688 return current_ == other.current_;\n- 1689 }\n- 1690\n- 1691 template\n- 1692 template\n- 1693 inline typename MatrixGraph::template VertexIteratorT&\n-MatrixGraph::VertexIteratorT::operator++()\n- 1694 {\n- 1695 ++current_;\n- 1696 return *this;\n- 1697 }\n- 1698\n- 1699 template\n- 1700 template\n- 1701 inline typename MatrixGraph::template VertexIteratorT::WeightType&\n- 1702 MatrixGraph::VertexIteratorT::weight() const\n- 1703 {\n- 1704 return graph_->matrix()[current_][current_];\n- 1705 }\n- 1706\n- 1707 template\n- 1708 template\n- 1709 inline const typename MatrixGraph::VertexDescriptor&\n- 1710 MatrixGraph::VertexIteratorT::operator*() const\n- 1711 {\n- 1712 return current_;\n- 1713 }\n- 1714\n- 1715 template\n- 1716 template\n- 1717 inline typename MatrixGraph::template EdgeIteratorT\n- 1718 MatrixGraph::VertexIteratorT::begin() const\n- 1719 {\n- 1720 return graph_->beginEdges(current_);\n- 1721 }\n- 1722\n- 1723 template\n- 1724 template\n- 1725 inline typename MatrixGraph::template EdgeIteratorT\n- 1726 MatrixGraph::VertexIteratorT::end() const\n- 1727 {\n- 1728 return graph_->endEdges(current_);\n- 1729 }\n- 1730\n- 1731 template\n- 1732 inline typename MatrixGraph::template VertexIteratorT >\n- 1733 MatrixGraph::begin()\n- 1734 {\n- 1735 return VertexIterator(this,0);\n- 1736 }\n- 1737\n- 1738 template\n- 1739 inline typename MatrixGraph::template VertexIteratorT >\n- 1740 MatrixGraph::end()\n- 1741 {\n- 1742 return VertexIterator(matrix_.N());\n- 1743 }\n- 1744\n- 1745\n- 1746 template\n- 1747 inline typename MatrixGraph::template VertexIteratorT >\n- 1748 MatrixGraph::begin() const\n- 1749 {\n- 1750 return ConstVertexIterator(this, 0);\n- 1751 }\n- 1752\n- 1753 template\n- 1754 inline typename MatrixGraph::template VertexIteratorT >\n- 1755 MatrixGraph::end() const\n- 1756 {\n- 1757 return ConstVertexIterator(matrix_.N());\n- 1758 }\n- 1759\n- 1760 template\n- 1761 inline typename MatrixGraph::template EdgeIteratorT >\n- 1762 MatrixGraph::beginEdges(const VertexDescriptor& source)\n- 1763 {\n- 1764 return EdgeIterator(source, matrix_.operator[](source).begin(),\n- 1765 matrix_.operator[](source).end(), start_[source]);\n- 1766 }\n- 1767\n- 1768 template\n- 1769 inline typename MatrixGraph::template EdgeIteratorT >\n- 1770 MatrixGraph::endEdges(const VertexDescriptor& source)\n- 1771 {\n- 1772 return EdgeIterator(matrix_.operator[](source).end());\n- 1773 }\n- 1774\n- 1775\n- 1776 template\n- 1777 inline typename MatrixGraph::template EdgeIteratorT >\n- 1778 MatrixGraph::beginEdges(const VertexDescriptor& source) const\n- 1779 {\n- 1780 return ConstEdgeIterator(source, matrix_.operator[](source).begin(),\n- 1781 matrix_.operator[](source).end(), start_[source]);\n- 1782 }\n- 1783\n- 1784 template\n- 1785 inline typename MatrixGraph::template EdgeIteratorT >\n- 1786 MatrixGraph::endEdges(const VertexDescriptor& source) const\n- 1787 {\n- 1788 return ConstEdgeIterator(matrix_.operator[](source).end());\n- 1789 }\n- 1790\n- 1791\n- 1792 template\n- 1793 SubGraph::EdgeIterator::EdgeIterator(const VertexDescriptor& source,\n- 1794 const EdgeDescriptor& edge)\n- 1795 : source_(source), edge_(edge)\n- 1796 {}\n- 1797\n- 1798\n- 1799 template\n- 1800 SubGraph::EdgeIterator::EdgeIterator(const EdgeDescriptor& edge)\n- 1801 : edge_(edge)\n- 1802 {}\n- 1803\n- 1804 template\n- 1805 typename SubGraph::EdgeIndexMap SubGraph::getEdgeIndexMap()\n- 1806 {\n- 1807 return EdgeIndexMap(edges_);\n- 1808 }\n- 1809\n- 1810 template\n- 1811 inline bool SubGraph::EdgeIterator::equals(const EdgeIterator &\n-other) const\n- 1812 {\n- 1813 return other.edge_==edge_;\n- 1814 }\n- 1815\n- 1816 template\n- 1817 inline typename SubGraph::EdgeIterator& SubGraph::\n-EdgeIterator::increment()\n- 1818 {\n- 1819 ++edge_;\n- 1820 return *this;\n- 1821 }\n- 1822\n- 1823 template\n- 1824 inline typename SubGraph::EdgeIterator& SubGraph::\n-EdgeIterator::decrement()\n- 1825 {\n- 1826 --edge_;\n- 1827 return *this;\n- 1828 }\n- 1829\n- 1830 template\n- 1831 inline typename SubGraph::EdgeIterator& SubGraph::\n-EdgeIterator::advance(std::ptrdiff_t n)\n- 1832 {\n- 1833 edge_+=n;\n- 1834 return *this;\n- 1835 }\n- 1836 template\n- 1837 inline const typename G::VertexDescriptor& SubGraph::EdgeIterator::\n-source() const\n- 1838 {\n- 1839 return source_;\n- 1840 }\n- 1841\n- 1842 template\n- 1843 inline const typename G::VertexDescriptor& SubGraph::EdgeIterator::\n-target() const\n- 1844 {\n- 1845 return *edge_;\n- 1846 }\n- 1847\n- 1848\n- 1849 template\n- 1850 inline const typename SubGraph::EdgeDescriptor& SubGraph::\n-EdgeIterator::dereference() const\n- 1851 {\n- 1852 return edge_;\n- 1853 }\n- 1854\n- 1855 template\n- 1856 inline std::ptrdiff_t SubGraph::EdgeIterator::distanceTo(const\n-EdgeIterator & other) const\n- 1857 {\n- 1858 return other.edge_-edge_;\n- 1859 }\n- 1860\n- 1861 template\n- 1862 SubGraph::VertexIterator::VertexIterator(const SubGraph* graph,\n- 1863 const VertexDescriptor& current,\n- 1864 const VertexDescriptor& end)\n- 1865 : graph_(graph), current_(current), end_(end)\n- 1866 {\n- 1867 // Skip excluded vertices\n- 1868 typedef typename T::const_iterator Iterator;\n- 1869\n- 1870 for(Iterator vertex = graph_->excluded_.begin();\n- 1871 current_ != end_ && *vertex;\n- 1872 ++vertex)\n- 1873 ++current_;\n- 1874 assert(current_ == end_ || !graph_->excluded_[current_]);\n- 1875 }\n- 1876\n- 1877 template\n- 1878 SubGraph::VertexIterator::VertexIterator(const VertexDescriptor&\n-current)\n- 1879 : current_(current)\n- 1880 {}\n- 1881\n- 1882 template\n- 1883 inline typename SubGraph::VertexIterator& SubGraph::\n-VertexIterator::increment()\n- 1884 {\n- 1885 ++current_;\n- 1886 //Skip excluded vertices\n- 1887 while(current_ != end_ && graph_->excluded_[current_])\n- 1888 ++current_;\n- 1889\n- 1890 assert(current_ == end_ || !graph_->excluded_[current_]);\n- 1891 return *this;\n- 1892 }\n- 1893\n- 1894 template\n- 1895 inline bool SubGraph::VertexIterator::equals(const VertexIterator &\n-other) const\n- 1896 {\n- 1897 return current_==other.current_;\n- 1898 }\n- 1899\n- 1900 template\n- 1901 inline const typename G::VertexDescriptor& SubGraph::\n-VertexIterator::dereference() const\n- 1902 {\n- 1903 return current_;\n- 1904 }\n- 1905\n- 1906 template\n- 1907 inline typename SubGraph::EdgeIterator SubGraph::\n-VertexIterator::begin() const\n- 1908 {\n- 1909 return graph_->beginEdges(current_);\n- 1910 }\n- 1911\n- 1912 template\n- 1913 inline typename SubGraph::EdgeIterator SubGraph::\n-VertexIterator::end() const\n- 1914 {\n- 1915 return graph_->endEdges(current_);\n- 1916 }\n- 1917\n- 1918 template\n- 1919 inline typename SubGraph::VertexIterator SubGraph::begin()\n-const\n- 1920 {\n- 1921 return VertexIterator(this, 0, endVertex_);\n- 1922 }\n- 1923\n- 1924\n- 1925 template\n- 1926 inline typename SubGraph::VertexIterator SubGraph::end() const\n- 1927 {\n- 1928 return VertexIterator(endVertex_);\n- 1929 }\n- 1930\n- 1931\n- 1932 template\n- 1933 inline typename SubGraph::EdgeIterator SubGraph::beginEdges\n-(const VertexDescriptor& source) const\n- 1934 {\n- 1935 return EdgeIterator(source, edges_+start_[source]);\n- 1936 }\n- 1937\n- 1938 template\n- 1939 inline typename SubGraph::EdgeIterator SubGraph::endEdges(const\n-VertexDescriptor& source) const\n- 1940 {\n- 1941 return EdgeIterator(edges_+end_[source]);\n- 1942 }\n- 1943\n- 1944 template\n- 1945 std::size_t SubGraph::noVertices() const\n- 1946 {\n- 1947 return noVertices_;\n- 1948 }\n- 1949\n- 1950 template\n- 1951 inline typename SubGraph::VertexDescriptor SubGraph::maxVertex\n-() const\n- 1952 {\n- 1953 return maxVertex_;\n- 1954 }\n- 1955\n- 1956 template\n- 1957 inline std::size_t SubGraph::noEdges() const\n- 1958 {\n- 1959 return noEdges_;\n- 1960 }\n- 1961\n- 1962 template\n- 1963 inline typename SubGraph::EdgeDescriptor SubGraph::findEdge\n-(const VertexDescriptor& source,\n- 1964 const VertexDescriptor& target) const\n- 1965 {\n- 1966 const EdgeDescriptor edge = std::lower_bound(edges_+start_[source],\n-edges_+end_[source], target);\n- 1967 if(edge==edges_+end_[source] || *edge!=target)\n- 1968 return std::numeric_limits::max();\n- 1969\n- 1970 return edge;\n- 1971 }\n- 1972\n- 1973 template\n- 1974 SubGraph::~SubGraph()\n- 1975 {\n- 1976 delete[] edges_;\n- 1977 delete[] end_;\n- 1978 delete[] start_;\n- 1979 }\n- 1980\n- 1981 template\n- 1982 SubGraph::SubGraph(const G& graph, const T& excluded)\n- 1983 : excluded_(excluded), noVertices_(0), endVertex_(0), maxVertex_\n-(graph.maxVertex())\n- 1984 {\n- 1985 start_ = new std::ptrdiff_t[graph.noVertices()];\n- 1986 end_ = new std::ptrdiff_t[graph.noVertices()];\n- 1987 edges_ = new VertexDescriptor[graph.noEdges()];\n- 1988\n- 1989 VertexDescriptor* edge=edges_;\n- 1990\n- 1991 // Cater for the case that there are no vertices.\n- 1992 // Otherwise endVertex_ will get 1 below.\n- 1993 if ( graph.noVertices() == 0)\n- 1994 return;\n- 1995\n- 1996 typedef typename Graph::ConstVertexIterator Iterator;\n- 1997 Iterator endVertex=graph.end();\n- 1998\n- 1999 for(Iterator vertex = graph.begin(); vertex != endVertex; ++vertex)\n- 2000 if(excluded_[*vertex])\n- 2001 start_[*vertex]=end_[*vertex]=-1;\n- 2002 else{\n- 2003 ++noVertices_;\n- 2004 endVertex_ = std::max(*vertex, endVertex_);\n- 2005\n- 2006 start_[*vertex] = edge-edges_;\n- 2007\n- 2008 auto endEdge = vertex.end();\n- 2009\n- 2010 for(auto iter=vertex.begin(); iter!= endEdge; ++iter)\n- 2011 if(!excluded[iter.target()]) {\n- 2012 *edge = iter.target();\n- 2013 ++edge;\n- 2014 }\n- 2015\n- 2016 end_[*vertex] = edge - edges_;\n- 2017\n- 2018 // Sort the edges\n- 2019 std::sort(edges_+start_[*vertex], edge);\n- 2020 }\n- 2021 noEdges_ = edge-edges_;\n- 2022 ++endVertex_;\n- 2023 }\n- 2024\n- 2025 template\n- 2026 inline std::size_t VertexPropertiesGraph::noEdges() const\n- 2027 {\n- 2028 return graph_.noEdges();\n- 2029 }\n- 2030\n- 2031 template\n- 2032 inline typename VertexPropertiesGraph::EdgeIterator\n- 2033 VertexPropertiesGraph::beginEdges(const VertexDescriptor& source)\n- 2034 {\n- 2035 return graph_.beginEdges(source);\n- 2036 }\n- 2037\n- 2038 template\n- 2039 inline typename VertexPropertiesGraph::EdgeIterator\n- 2040 VertexPropertiesGraph::endEdges(const VertexDescriptor& source)\n- 2041 {\n- 2042 return graph_.endEdges(source);\n- 2043 }\n- 2044\n- 2045 template\n- 2046 typename VertexPropertiesGraph::ConstEdgeIterator\n- 2047 inline VertexPropertiesGraph::beginEdges(const VertexDescriptor&\n-source) const\n- 2048 {\n- 2049 return graph_.beginEdges(source);\n- 2050 }\n- 2051\n- 2052 template\n- 2053 typename VertexPropertiesGraph::ConstEdgeIterator\n- 2054 VertexPropertiesGraph::endEdges(const VertexDescriptor& source)\n-const\n- 2055 {\n- 2056 return graph_.endEdges(source);\n- 2057 }\n- 2058\n- 2059 template\n- 2060 template\n- 2061 VertexPropertiesGraph::VertexIteratorT\n- 2062 ::VertexIteratorT(const Father& iter,\n- 2063 C* graph)\n- 2064 : Father(iter), graph_(graph)\n- 2065 {}\n- 2066\n- 2067 template\n- 2068 template\n- 2069 VertexPropertiesGraph::VertexIteratorT\n- 2070 ::VertexIteratorT(const Father& iter)\n- 2071 : Father(iter)\n- 2072 {}\n- 2073\n- 2074 template\n- 2075 template\n- 2076 template\n- 2077 VertexPropertiesGraph::VertexIteratorT\n- 2078 ::VertexIteratorT(const VertexIteratorT& other)\n- 2079 : Father(other), graph_(other.graph_)\n- 2080 {}\n- 2081\n- 2082 template\n- 2083 template\n- 2084 typename std::conditional::\n-type>::value,\n- 2085 V&, const V&>::type\n- 2086 inline VertexPropertiesGraph::VertexIteratorT::properties()\n-const\n- 2087 {\n- 2088 return graph_->getVertexProperties(Father::operator*());\n- 2089 }\n- 2090\n- 2091 template\n- 2092 template\n- 2093 typename std::conditional::\n-type,\n- 2094 C>::value,\n- 2095 typename G::EdgeIterator,\n- 2096 typename G::ConstEdgeIterator>::type\n- 2097 inline VertexPropertiesGraph::VertexIteratorT::begin() const\n- 2098 {\n- 2099 return graph_->beginEdges(Father::operator*());\n- 2100 }\n- 2101\n- 2102 template\n- 2103 template\n- 2104 typename std::conditional::\n-type,\n- 2105 C>::value,\n- 2106 typename G::EdgeIterator,\n- 2107 typename G::ConstEdgeIterator>::type\n- 2108 inline VertexPropertiesGraph::VertexIteratorT::end() const\n- 2109 {\n- 2110 return graph_->endEdges(Father::operator*());\n- 2111 }\n- 2112\n- 2113 template\n- 2114 inline typename VertexPropertiesGraph::VertexIterator\n-VertexPropertiesGraph::begin()\n- 2115 {\n- 2116 return VertexIterator(graph_.begin(), this);\n- 2117 }\n- 2118\n- 2119 template\n- 2120 inline typename VertexPropertiesGraph::VertexIterator\n-VertexPropertiesGraph::end()\n- 2121 {\n- 2122 return VertexIterator(graph_.end());\n- 2123 }\n- 2124\n- 2125\n- 2126 template\n- 2127 inline typename VertexPropertiesGraph::ConstVertexIterator\n-VertexPropertiesGraph::begin() const\n- 2128 {\n- 2129 return ConstVertexIterator(graph_.begin(), this);\n- 2130 }\n- 2131\n- 2132 template\n- 2133 inline typename VertexPropertiesGraph::ConstVertexIterator\n-VertexPropertiesGraph::end() const\n- 2134 {\n- 2135 return ConstVertexIterator(graph_.end());\n- 2136 }\n- 2137\n- 2138 template\n- 2139 inline V& VertexPropertiesGraph::getVertexProperties(const\n-VertexDescriptor& vertex)\n- 2140 {\n- 2141 return vertexProperties_[vmap_[vertex]];\n- 2142 }\n- 2143\n- 2144 template\n- 2145 inline const V& VertexPropertiesGraph::getVertexProperties(const\n-VertexDescriptor& vertex) const\n- 2146 {\n- 2147 return vertexProperties_[vmap_[vertex]];\n- 2148 }\n- 2149\n- 2150 template\n- 2151 inline const G& VertexPropertiesGraph::graph() const\n- 2152 {\n- 2153 return graph_;\n- 2154 }\n- 2155\n- 2156 template\n- 2157 inline std::size_t VertexPropertiesGraph::noVertices() const\n- 2158 {\n- 2159 return graph_.noVertices();\n- 2160 }\n- 2161\n- 2162\n- 2163 template\n- 2164 inline typename VertexPropertiesGraph::VertexDescriptor\n-VertexPropertiesGraph::maxVertex() const\n- 2165 {\n- 2166 return graph_.maxVertex();\n- 2167 }\n- 2168\n- 2169 template\n- 2170 VertexPropertiesGraph::VertexPropertiesGraph(Graph& graph, const\n-VM vmap)\n- 2171 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex\n-()+1], V())\n- 2172 {}\n- 2173\n- 2174 template\n- 2175 template\n- 2176 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n-Father& iter,\n- 2177 C* graph)\n- 2178 : Father(iter), graph_(graph)\n- 2179 {}\n- 2180\n- 2181 template\n- 2182 template\n- 2183 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n-Father& iter)\n- 2184 : Father(iter)\n- 2185 {}\n- 2186\n- 2187 template\n- 2188 template\n- 2189 template\n- 2190 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n-EdgeIteratorT& other)\n- 2191 : Father(other), graph_(other.graph_)\n- 2192 {}\n- 2193\n- 2194\n- 2195 template\n- 2196 inline std::size_t PropertiesGraph::noEdges() const\n- 2197 {\n- 2198 return graph_.noEdges();\n- 2199 }\n- 2200\n- 2201 template\n- 2202 template\n- 2203 inline typename std::conditional::type>::value,E&,const E&>::type\n- 2204 PropertiesGraph::EdgeIteratorT::properties() const\n- 2205 {\n- 2206 return graph_->getEdgeProperties(Father::operator*());\n- 2207 }\n- 2208\n- 2209 template\n- 2210 inline typename PropertiesGraph::EdgeIterator\n- 2211 PropertiesGraph::beginEdges(const VertexDescriptor& source)\n- 2212 {\n- 2213 return EdgeIterator(graph_.beginEdges(source), this);\n- 2214 }\n- 2215\n- 2216 template\n- 2217 inline typename PropertiesGraph::EdgeIterator\n- 2218 PropertiesGraph::endEdges(const VertexDescriptor& source)\n- 2219 {\n- 2220 return EdgeIterator(graph_.endEdges(source));\n- 2221 }\n- 2222\n- 2223 template\n- 2224 typename PropertiesGraph::ConstEdgeIterator\n- 2225 inline PropertiesGraph::beginEdges(const VertexDescriptor&\n-source) const\n- 2226 {\n- 2227 return ConstEdgeIterator(graph_.beginEdges(source), this);\n- 2228 }\n- 2229\n- 2230 template\n- 2231 typename PropertiesGraph::ConstEdgeIterator\n- 2232 PropertiesGraph::endEdges(const VertexDescriptor& source)\n-const\n- 2233 {\n- 2234 return ConstEdgeIterator(graph_.endEdges(source));\n- 2235 }\n- 2236\n- 2237 template\n- 2238 template\n- 2239 PropertiesGraph::VertexIteratorT\n- 2240 ::VertexIteratorT(const Father& iter,\n- 2241 C* graph)\n- 2242 : Father(iter), graph_(graph)\n- 2243 {}\n- 2244\n- 2245 template\n- 2246 template\n- 2247 PropertiesGraph::VertexIteratorT\n- 2248 ::VertexIteratorT(const Father& iter)\n- 2249 : Father(iter)\n- 2250 {}\n- 2251\n- 2252 template\n- 2253 template\n- 2254 template\n- 2255 PropertiesGraph::VertexIteratorT\n- 2256 ::VertexIteratorT(const VertexIteratorT& other)\n- 2257 : Father(other), graph_(other.graph_)\n- 2258 {}\n- 2259\n- 2260 template\n- 2261 template\n- 2262 inline typename std::conditional::type>::value,\n- 2263 V&, const V&>::type\n- 2264 PropertiesGraph::VertexIteratorT::properties() const\n- 2265 {\n- 2266 return graph_->getVertexProperties(Father::operator*());\n- 2267 }\n- 2268\n- 2269 template\n- 2270 template\n- 2271 inline typename PropertiesGraph::template EdgeIteratorT\n- 2272 PropertiesGraph::VertexIteratorT::begin() const\n- 2273 {\n- 2274 return graph_->beginEdges(Father::operator*());\n- 2275 }\n- 2276\n- 2277 template\n- 2278 template\n- 2279 inline typename PropertiesGraph::template EdgeIteratorT\n- 2280 PropertiesGraph::VertexIteratorT::end() const\n- 2281 {\n- 2282 return graph_->endEdges(Father::operator*());\n- 2283 }\n- 2284\n- 2285 template\n- 2286 inline typename PropertiesGraph::VertexIterator\n-PropertiesGraph::begin()\n- 2287 {\n- 2288 return VertexIterator(graph_.begin(), this);\n- 2289 }\n- 2290\n- 2291 template\n- 2292 inline typename PropertiesGraph::VertexIterator\n-PropertiesGraph::end()\n- 2293 {\n- 2294 return VertexIterator(graph_.end());\n- 2295 }\n- 2296\n- 2297\n- 2298 template\n- 2299 inline typename PropertiesGraph::ConstVertexIterator\n-PropertiesGraph::begin() const\n- 2300 {\n- 2301 return ConstVertexIterator(graph_.begin(), this);\n- 2302 }\n- 2303\n- 2304 template\n- 2305 inline typename PropertiesGraph::ConstVertexIterator\n-PropertiesGraph::end() const\n- 2306 {\n- 2307 return ConstVertexIterator(graph_.end());\n- 2308 }\n- 2309\n- 2310 template\n- 2311 inline V& PropertiesGraph::getVertexProperties(const\n-VertexDescriptor& vertex)\n- 2312 {\n- 2313 return vertexProperties_[vmap_[vertex]];\n- 2314 }\n- 2315\n- 2316 template\n- 2317 inline const V& PropertiesGraph::getVertexProperties(const\n-VertexDescriptor& vertex) const\n- 2318 {\n- 2319 return vertexProperties_[vmap_[vertex]];\n- 2320 }\n- 2321\n- 2322 template\n- 2323 inline E& PropertiesGraph::getEdgeProperties(const\n-EdgeDescriptor& edge)\n- 2324 {\n- 2325 return edgeProperties_[emap_[edge]];\n- 2326 }\n- 2327\n- 2328 template\n- 2329 inline const E& PropertiesGraph::getEdgeProperties(const\n-EdgeDescriptor& edge) const\n- 2330 {\n- 2331 return edgeProperties_[emap_[edge]];\n- 2332 }\n- 2333\n- 2334 template\n- 2335 inline E& PropertiesGraph::getEdgeProperties(const\n-VertexDescriptor& source,\n- 2336 const VertexDescriptor& target)\n- 2337 {\n- 2338 return getEdgeProperties(graph_.findEdge(source,target));\n- 2339 }\n- 2340\n- 2341 template\n- 2342 inline const E& PropertiesGraph::getEdgeProperties(const\n-VertexDescriptor& source,\n- 2343 const VertexDescriptor& target) const\n- 2344 {\n- 2345 return getEdgeProperties(graph_.findEdge(source,target));\n- 2346 }\n- 2347\n- 2348 template\n- 2349 inline const G& PropertiesGraph::graph() const\n- 2350 {\n- 2351 return graph_;\n- 2352 }\n- 2353\n- 2354 template\n- 2355 inline std::size_t PropertiesGraph::noVertices() const\n- 2356 {\n- 2357 return graph_.noVertices();\n- 2358 }\n- 2359\n- 2360\n- 2361 template\n- 2362 inline typename PropertiesGraph::VertexDescriptor\n-PropertiesGraph::maxVertex() const\n- 2363 {\n- 2364 return graph_.maxVertex();\n- 2365 }\n- 2366\n- 2367 template\n- 2368 PropertiesGraph::PropertiesGraph(Graph& graph, const VM&\n-vmap, const EM& emap)\n- 2369 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex\n-()+1], V()),\n- 2370 emap_(emap), edgeProperties_(graph_.noEdges(), E())\n- 2371 {}\n- 2372\n- 2373 template\n- 2374 inline int visitNeighbours(const G& graph, const typename G::\n-VertexDescriptor& vertex,\n- 2375 V& visitor)\n- 2376 {\n- 2377 typedef typename G::ConstEdgeIterator iterator;\n- 2378 const iterator end = graph.endEdges(vertex);\n- 2379 int noNeighbours=0;\n- 2380 for(iterator edge = graph.beginEdges(vertex); edge != end; ++edge,\n-++noNeighbours)\n- 2381 visitor(edge);\n- 2382 return noNeighbours;\n- 2383 }\n- 2384\n- 2385#endif // DOXYGEN\n- 2386\n- 2388 }\n- 2389}\n- 2390#endif\n-istlexception.hh\n-Dune::Amg::visitNeighbours\n-int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n-V &visitor)\n-Visit all neighbour vertices of a vertex in a graph.\n-std\n-STL namespace.\n+ 543 template\n+544 struct TransposedMatMultMatResult,A\n+>,BCRSMatrix,A1 > >\n+ 545 {\n+ 546 typedef BCRSMatrix,FieldMatrix >::type,\n+547 std::allocator,FieldMatrix >::type> > type;\n+ 548 };\n+ 549\n+ 550\n+ 559 template\n+560 void matMultTransposeMat(BCRSMatrix,A>& res, const\n+BCRSMatrix,A1>& mat,\n+ 561 const BCRSMatrix,A2>& matt, [[maybe_unused]] bool\n+tryHard=false)\n+ 562 {\n+ 563 matMultMat<2>(res,mat, matt);\n+ 564 }\n+ 565\n+ 574 template\n+575 void matMultMat(BCRSMatrix,A>& res, const\n+BCRSMatrix,A1>& mat,\n+ 576 const BCRSMatrix,A2>& matt, bool tryHard=false)\n+ 577 {\n+ 578 matMultMat<0>(res,mat, matt);\n+ 579 }\n+ 580\n+ 589 template\n+590 void transposeMatMultMat(BCRSMatrix,A>& res, const\n+BCRSMatrix,A1>& mat,\n+ 591 const BCRSMatrix,A2>& matt, [[maybe_unused]] bool\n+tryHard=false)\n+ 592 {\n+ 593 matMultMat<1>(res,mat, matt);\n+ 594 }\n+ 595\n+ 596}\n+ 597#endif\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+Dune::MatMultMatResult<_FieldMatrix<_T,_n,_k_>,_FieldMatrix<_T,_k,_m_>_>::type\n+FieldMatrix< T, n, m > type\n+Definition: matrixmatrix.hh:515\n+Dune::transposeMatMultMat\n+void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const\n+BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix<\n+T, k, m >, A2 > &matt, bool tryHard=false)\n+Calculate product of a transposed sparse matrix with another sparse matrices\n+( ).\n+Definition: matrixmatrix.hh:590\n+Dune::matMultMat\n+void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix<\n+FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2\n+> &matt, bool tryHard=false)\n+Calculate product of two sparse matrices ( ).\n+Definition: matrixmatrix.hh:575\n+Dune::EntryAccumulatorFather::Row\n+Matrix::RowIterator Row\n+Definition: matrixmatrix.hh:326\n+Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::Matrix\n+Dune::BCRSMatrix< Dune::FieldMatrix< T, n, m >, TA > Matrix\n+Definition: matrixmatrix.hh:228\n+Dune::EntryAccumulator::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:360\n+Dune::EntryAccumulator<_T,_A,_n,_m,_0_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:380\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+Dune::EntryAccumulatorFather::Col\n+Matrix::ColIterator Col\n+Definition: matrixmatrix.hh:327\n+Dune::MatrixInitializer::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:188\n+Dune::EntryAccumulatorFather::col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::EntryAccumulatorFather::mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:230\n+Dune::TransposedMatMultMatResult<_FieldMatrix<_T,_k,_n_>,_FieldMatrix<_T,_k,_m\n+>_>::type\n+FieldMatrix< T, n, m > type\n+Definition: matrixmatrix.hh:540\n+Dune::matMultTransposeMat\n+void matMultTransposeMat(BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const\n+BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix<\n+T, k, m >, A2 > &matt, bool tryHard=false)\n+Calculate product of a sparse matrix with a transposed sparse matrices ( ).\n+Definition: matrixmatrix.hh:560\n+Dune::MatrixInitializer::Matrix\n+Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix\n+Definition: matrixmatrix.hh:186\n+Dune::MatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_n,_k_>,_A_>,_BCRSMatrix<\n+FieldMatrix<_T,_k,_m_>,_A1_>_>::type\n+BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T,\n+k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k\n+>, FieldMatrix< T, k, m > >::type > > type\n+Definition: matrixmatrix.hh:522\n+Dune::MatrixInitializer<_1,_T,_TA,_n,_m_>::CreateIterator\n+Matrix::CreateIterator CreateIterator\n+Definition: matrixmatrix.hh:229\n+Dune::EntryAccumulator<_T,_A,_n,_m,_1_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:399\n+Dune::MatrixInitializer::CreateIterator\n+Matrix::CreateIterator CreateIterator\n+Definition: matrixmatrix.hh:187\n+Dune::TransposedMatMultMatResult<_BCRSMatrix<_FieldMatrix<_T,_k,_n_>,_A_>,\n+BCRSMatrix<_FieldMatrix<_T,_k,_m_>,_A1_>_>::type\n+BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T,\n+k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k\n+>, FieldMatrix< T, k, m > >::type > > type\n+Definition: matrixmatrix.hh:547\n+Dune::EntryAccumulator<_T,_A,_n,_m,_2_>::size_type\n+Matrix::size_type size_type\n+Definition: matrixmatrix.hh:418\n+Dune::SparsityPatternInitializer::size_type\n+BCRSMatrix< FieldMatrix< T, n, m >, A >::size_type size_type\n+Definition: matrixmatrix.hh:157\n Dune\n Definition: allocator.hh:11\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::Amg::MatrixGraph\n-The (undirected) graph of a matrix.\n-Definition: graph.hh:51\n-Dune::Amg::MatrixGraph::MatrixGraph\n-MatrixGraph(Matrix &matrix)\n-Constructor.\n-Dune::Amg::MatrixGraph::end\n-VertexIterator end()\n-Get an iterator over the vertices.\n-Dune::Amg::MatrixGraph::maxVertex\n-VertexDescriptor maxVertex() const\n-Get the maximal vertex descriptor.\n-Dune::Amg::MatrixGraph::Matrix\n-M Matrix\n-The type of the matrix we are a graph for.\n-Definition: graph.hh:56\n-Dune::Amg::MatrixGraph::begin\n-ConstVertexIterator begin() const\n-Get an iterator over the vertices.\n-Dune::Amg::MatrixGraph::ConstVertexIterator\n-VertexIteratorT< const MatrixGraph< Matrix > > ConstVertexIterator\n-The constant vertex iterator type.\n-Definition: graph.hh:308\n-Dune::Amg::MatrixGraph::~MatrixGraph\n-~MatrixGraph()\n-Destructor.\n-Dune::Amg::MatrixGraph::EdgeDescriptor\n-std::ptrdiff_t EdgeDescriptor\n-The edge descriptor.\n-Definition: graph.hh:80\n-Dune::Amg::MatrixGraph::endEdges\n-ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::MatrixGraph::VertexDescriptor\n-M::size_type VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:73\n-Dune::Amg::MatrixGraph::matrix\n-const Matrix & matrix() const\n-Get the underlying matrix.\n-Dune::Amg::MatrixGraph::mutableMatrix\n-@ mutableMatrix\n-Definition: graph.hh:86\n-Dune::Amg::MatrixGraph::beginEdges\n-ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::MatrixGraph::end\n-ConstVertexIterator end() const\n-Get an iterator over the vertices.\n-Dune::Amg::MatrixGraph::ConstEdgeIterator\n-EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator\n-The constant edge iterator type.\n-Definition: graph.hh:298\n-Dune::Amg::MatrixGraph::beginEdges\n-EdgeIterator beginEdges(const VertexDescriptor &source)\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::MatrixGraph::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices in the graph.\n-Dune::Amg::MatrixGraph::findEdge\n-EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor\n-&target) const\n-Find the descriptor of an edge.\n-Dune::Amg::MatrixGraph::Weight\n-M::block_type Weight\n-The type of the weights.\n-Definition: graph.hh:66\n-Dune::Amg::MatrixGraph::MutableMatrix\n-std::remove_const< M >::type MutableMatrix\n-The mutable type of the matrix we are a graph for.\n-Definition: graph.hh:61\n-Dune::Amg::MatrixGraph::EdgeIterator\n-EdgeIteratorT< MatrixGraph< Matrix > > EdgeIterator\n-The mutable edge iterator type.\n-Definition: graph.hh:303\n-Dune::Amg::MatrixGraph::VertexIterator\n-VertexIteratorT< MatrixGraph< Matrix > > VertexIterator\n-The mutable vertex iterator type.\n-Definition: graph.hh:313\n-Dune::Amg::MatrixGraph::endEdges\n-EdgeIterator endEdges(const VertexDescriptor &source)\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::MatrixGraph::noEdges\n-std::size_t noEdges() const\n-Get the number of edges in the graph.\n-Dune::Amg::MatrixGraph::matrix\n-Matrix & matrix()\n-Get the underlying matrix.\n-Dune::Amg::MatrixGraph::begin\n-VertexIterator begin()\n-Get an iterator over the vertices.\n-Dune::Amg::MatrixGraph::EdgeIteratorT\n-Iterator over all edges starting from a vertex.\n-Definition: graph.hh:95\n-Dune::Amg::MatrixGraph::EdgeIteratorT::WeightType\n-std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n-value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::\n-type WeightType\n-Definition: graph.hh:156\n-Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n-EdgeIteratorT(const VertexDescriptor &source, const ColIterator &block, const\n-ColIterator &end, const EdgeDescriptor &edge)\n-Constructor.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::isMutable\n-@ isMutable\n-whether C is mutable.\n-Definition: graph.hh:112\n-Dune::Amg::MatrixGraph::EdgeIteratorT::target\n-VertexDescriptor target() const\n-The index of the target vertex of the current edge.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator++\n-EdgeIteratorT< C > & operator++()\n-preincrement operator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator!=\n-bool operator!=(const EdgeIteratorT< const typename std::remove_const< C >::\n-type > &other) const\n-Inequality operator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator==\n-bool operator==(const EdgeIteratorT< const typename std::remove_const< C >::\n-type > &other) const\n-Equality operator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n-EdgeIteratorT(const EdgeIteratorT< C1 > &other)\n-Copy Constructor.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator!=\n-bool operator!=(const EdgeIteratorT< typename std::remove_const< C >::type >\n-&other) const\n-Inequality operator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::weight\n-WeightType & weight() const\n-Access the edge weight.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::source\n-VertexDescriptor source() const\n-The index of the source vertex of the current edge.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::ColIterator\n-std::conditional< isMutable &&C::mutableMatrix, typenameMatrix::row_type::\n-Iterator, typenameMatrix::row_type::ConstIterator >::type ColIterator\n-The column iterator of the matrix we use.\n-Definition: graph.hh:120\n-Dune::Amg::MatrixGraph::EdgeIteratorT::ConstContainer\n-const std::remove_const< C >::type ConstContainer\n-The constant type of the container type.\n-Definition: graph.hh:105\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator==\n-bool operator==(const EdgeIteratorT< typename std::remove_const< C >::type >\n-&other) const\n-Equality operator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n-EdgeIteratorT(const ColIterator &block)\n-Constructor for the end iterator.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::Weight\n-std::conditional< isMutable &&C::mutableMatrix, typenameM::block_type,\n-consttypenameM::block_type >::type Weight\n-The matrix block type we use as weights.\n-Definition: graph.hh:127\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator*\n-const EdgeDescriptor & operator*() const\n-Get the edge descriptor.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::operator->\n-const EdgeDescriptor * operator->() const\n-Get the edge descriptor.\n-Dune::Amg::MatrixGraph::EdgeIteratorT::MutableContainer\n-std::remove_const< C >::type MutableContainer\n-The mutable type of the container type.\n-Definition: graph.hh:101\n-Dune::Amg::MatrixGraph::VertexIteratorT\n-The vertex iterator type of the graph.\n-Definition: graph.hh:209\n-Dune::Amg::MatrixGraph::VertexIteratorT::begin\n-EdgeIteratorT< C > begin() const\n-Get an iterator over all edges starting at the current vertex.\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator*\n-const VertexDescriptor & operator*() const\n-Get the descriptor of the current vertex.\n-Dune::Amg::MatrixGraph::VertexIteratorT::weight\n-WeightType & weight() const\n-Access the weight of the vertex.\n-Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n-VertexIteratorT(C *graph, const VertexDescriptor ¤t)\n-Constructor.\n-Dune::Amg::MatrixGraph::VertexIteratorT::WeightType\n-std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n-value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::\n-type WeightType\n-Definition: graph.hh:266\n-Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n-VertexIteratorT(const VertexIteratorT< MutableContainer > &other)\n-Dune::Amg::MatrixGraph::VertexIteratorT::MutableContainer\n-std::remove_const< C >::type MutableContainer\n-The mutable type of the container type.\n-Definition: graph.hh:214\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator!=\n-bool operator!=(const VertexIteratorT< MutableContainer > &other) const\n-Inequality operator.\n-Dune::Amg::MatrixGraph::VertexIteratorT::isMutable\n-@ isMutable\n-whether C is mutable.\n-Definition: graph.hh:225\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator==\n-bool operator==(const VertexIteratorT< MutableContainer > &other) const\n-Equality operator.\n-Dune::Amg::MatrixGraph::VertexIteratorT::ConstContainer\n-const std::remove_const< C >::type ConstContainer\n-The constant type of the container type.\n-Definition: graph.hh:218\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator++\n-VertexIteratorT< C > & operator++()\n-Move to the next vertex.\n-Dune::Amg::MatrixGraph::VertexIteratorT::end\n-EdgeIteratorT< C > end() const\n-Get an iterator over all edges starting at the current vertex.\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator==\n-bool operator==(const VertexIteratorT< ConstContainer > &other) const\n-Equality operator.\n-Dune::Amg::MatrixGraph::VertexIteratorT::operator!=\n-bool operator!=(const VertexIteratorT< ConstContainer > &other) const\n-Inequality operator.\n-Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n-VertexIteratorT(const VertexDescriptor ¤t)\n-Constructor for the end iterator.\n-Dune::Amg::SubGraph\n-A subgraph of a graph.\n-Definition: graph.hh:443\n-Dune::Amg::SubGraph::findEdge\n-EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor\n-&target) const\n-Find the descriptor of an edge.\n-Dune::Amg::SubGraph::maxVertex\n-VertexDescriptor maxVertex() const\n-Get the maximal vertex descriptor.\n-Dune::Amg::SubGraph::getEdgeIndexMap\n-EdgeIndexMap getEdgeIndexMap()\n-Get an edge index map for the graph.\n-Dune::Amg::SubGraph::noEdges\n-std::size_t noEdges() const\n-Get the number of edges in the graph.\n-Dune::Amg::SubGraph::endEdges\n-ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::SubGraph::end\n-ConstVertexIterator end() const\n-Get an iterator over the vertices.\n-Dune::Amg::SubGraph::beginEdges\n-ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n-Get an iterator over the edges starting at a vertex.\n-Dune::Amg::SubGraph::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices in the graph.\n-Dune::Amg::SubGraph::Excluded\n-T Excluded\n-Random access container providing information about which vertices are\n-excluded.\n-Definition: graph.hh:454\n-Dune::Amg::SubGraph::~SubGraph\n-~SubGraph()\n-Destructor.\n-Dune::Amg::SubGraph::ConstEdgeIterator\n-EdgeIterator ConstEdgeIterator\n-The constant edge iterator type.\n-Definition: graph.hh:618\n-Dune::Amg::SubGraph::Graph\n-G Graph\n-The type of the graph we are a sub graph for.\n-Definition: graph.hh:448\n-Dune::Amg::SubGraph::ConstVertexIterator\n-VertexIterator ConstVertexIterator\n-The constant vertex iterator type.\n-Definition: graph.hh:623\n-Dune::Amg::SubGraph::SubGraph\n-SubGraph(const Graph &graph, const T &excluded)\n-Constructor.\n-Dune::Amg::SubGraph::begin\n-ConstVertexIterator begin() const\n-Get an iterator over the vertices.\n-Dune::Amg::SubGraph::VertexDescriptor\n-Graph::VertexDescriptor VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:459\n-Dune::Amg::SubGraph::EdgeDescriptor\n-VertexDescriptor * EdgeDescriptor\n-Definition: graph.hh:461\n-Dune::Amg::SubGraph::EdgeIndexMap\n-An index map for mapping the edges to indices.\n-Definition: graph.hh:470\n-Dune::Amg::SubGraph::EdgeIndexMap::EdgeIndexMap\n-EdgeIndexMap(const EdgeIndexMap &emap)\n-Protect copy construction.\n-Definition: graph.hh:479\n-Dune::Amg::SubGraph::EdgeIndexMap::Category\n-ReadablePropertyMapTag Category\n-Definition: graph.hh:472\n-Dune::Amg::SubGraph::EdgeIndexMap::EdgeIndexMap\n-EdgeIndexMap(const EdgeDescriptor &firstEdge)\n-Definition: graph.hh:474\n-Dune::Amg::SubGraph::EdgeIndexMap::operator[]\n-std::size_t operator[](const EdgeDescriptor &edge) const\n-Definition: graph.hh:483\n-Dune::Amg::SubGraph::EdgeIterator\n-The edge iterator of the graph.\n-Definition: graph.hh:505\n-Dune::Amg::SubGraph::EdgeIterator::dereference\n-const EdgeDescriptor & dereference() const\n-The descriptor of the current edge.\n-Dune::Amg::SubGraph::EdgeIterator::EdgeIterator\n-EdgeIterator(const EdgeDescriptor &edge)\n-Constructor for the end iterator.\n-Dune::Amg::SubGraph::EdgeIterator::equals\n-bool equals(const EdgeIterator &other) const\n-Equality operator.\n-Dune::Amg::SubGraph::EdgeIterator::advance\n-EdgeIterator & advance(std::ptrdiff_t n)\n-Dune::Amg::SubGraph::EdgeIterator::increment\n-EdgeIterator & increment()\n-Preincrement operator.\n-Dune::Amg::SubGraph::EdgeIterator::target\n-const VertexDescriptor & target() const\n-The index of the target vertex of the current edge.\n-Dune::Amg::SubGraph::EdgeIterator::source\n-const VertexDescriptor & source() const\n-The index of the source vertex of the current edge.\n-Dune::Amg::SubGraph::EdgeIterator::decrement\n-EdgeIterator & decrement()\n-Preincrement operator.\n-Dune::Amg::SubGraph::EdgeIterator::distanceTo\n-std::ptrdiff_t distanceTo(const EdgeIterator &other) const\n-Dune::Amg::SubGraph::EdgeIterator::EdgeIterator\n-EdgeIterator(const VertexDescriptor &source, const EdgeDescriptor &edge)\n-Constructor.\n-Dune::Amg::SubGraph::VertexIterator\n-The vertex iterator of the graph.\n-Definition: graph.hh:560\n-Dune::Amg::SubGraph::VertexIterator::VertexIterator\n-VertexIterator(const VertexDescriptor ¤t)\n-Constructor for end iterator.\n-Dune::Amg::SubGraph::VertexIterator::increment\n-VertexIterator & increment()\n-Preincrement operator.\n-Dune::Amg::SubGraph::VertexIterator::begin\n-EdgeIterator begin() const\n-Get an iterator over all edges starting at the current vertex.\n-Dune::Amg::SubGraph::VertexIterator::equals\n-bool equals(const VertexIterator &other) const\n-Equality iterator.\n-Dune::Amg::SubGraph::VertexIterator::VertexIterator\n-VertexIterator(const SubGraph< G, T > *graph, const VertexDescriptor ¤t,\n-const VertexDescriptor &end)\n-Constructor.\n-Dune::Amg::SubGraph::VertexIterator::end\n-EdgeIterator end() const\n-Get an iterator over all edges starting at the current vertex.\n-Dune::Amg::SubGraph::VertexIterator::dereference\n-const VertexDescriptor & dereference() const\n-Get the descriptor of the current vertex.\n-Dune::Amg::VertexPropertiesGraph\n-Attaches properties to the vertices of a graph.\n-Definition: graph.hh:723\n-Dune::Amg::VertexPropertiesGraph::end\n-VertexIterator end()\n-Get an iterator over the vertices.\n-Dune::Amg::VertexPropertiesGraph::graph\n-const Graph & graph() const\n-Get the graph the properties are attached to.\n-Dune::Amg::VertexPropertiesGraph::ConstEdgeIterator\n-Graph::ConstEdgeIterator ConstEdgeIterator\n-The type of the constant edge iterator.\n-Definition: graph.hh:766\n-Dune::Amg::VertexPropertiesGraph::getVertexProperties\n-VertexProperties & getVertexProperties(const VertexDescriptor &vertex)\n-Get the properties associated with a vertex.\n-Dune::Amg::VertexPropertiesGraph::noEdges\n-std::size_t noEdges() const\n-Get the number of edges in the graph.\n-Dune::Amg::VertexPropertiesGraph::EdgeDescriptor\n-Graph::EdgeDescriptor EdgeDescriptor\n-The edge descritor.\n-Definition: graph.hh:738\n-Dune::Amg::VertexPropertiesGraph::endEdges\n-ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n-Get the mutable edge iterator over edges starting at a vertex.\n-Dune::Amg::VertexPropertiesGraph::VertexDescriptor\n-Graph::VertexDescriptor VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:733\n-Dune::Amg::VertexPropertiesGraph::Graph\n-G Graph\n-The graph we attach properties to.\n-Definition: graph.hh:728\n-Dune::Amg::VertexPropertiesGraph::VertexMap\n-VM VertexMap\n-The type of the map for converting the VertexDescriptor to std::size_t.\n-Definition: graph.hh:756\n-Dune::Amg::VertexPropertiesGraph::endEdges\n-EdgeIterator endEdges(const VertexDescriptor &source)\n-Get the mutable edge iterator over edges starting at a vertex.\n-Dune::Amg::VertexPropertiesGraph::beginEdges\n-EdgeIterator beginEdges(const VertexDescriptor &source)\n-Get the mutable edge iterator over edges starting at a vertex.\n-Dune::Amg::VertexPropertiesGraph::VertexProperties\n-VP VertexProperties\n-The type of the properties of the vertices.\n-Definition: graph.hh:743\n-Dune::Amg::VertexPropertiesGraph::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices in the graph.\n-Dune::Amg::VertexPropertiesGraph::beginEdges\n-ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n-Get the mutable edge iterator over edges starting at a vertex.\n-Dune::Amg::VertexPropertiesGraph::maxVertex\n-VertexDescriptor maxVertex() const\n-Get the maximal vertex descriptor.\n-Dune::Amg::VertexPropertiesGraph::begin\n-VertexIterator begin()\n-Get an iterator over the vertices.\n-Dune::Amg::VertexPropertiesGraph::EdgeIterator\n-Graph::EdgeIterator EdgeIterator\n-The type of the mutable edge iterator.\n-Definition: graph.hh:761\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT\n-Definition: graph.hh:803\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT::EdgeIterator\n-std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n-value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type\n-EdgeIterator\n-The class of the edge iterator.\n-Definition: graph.hh:823\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT::properties\n-std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n-value, VertexProperties &, constVertexProperties & >::type properties() const\n-Get the properties of the current Vertex.\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT::end\n-EdgeIterator end() const\n-Get an iterator over the edges starting from the current vertex.\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT::Father\n-std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n-value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::\n-type Father\n-The father class.\n-Definition: graph.hh:814\n-Dune::Amg::VertexPropertiesGraph::VertexIteratorT::begin\n-EdgeIterator begin() const\n-Get an iterator over the edges starting from the current vertex.\n-Dune::Amg::PropertiesGraph\n-Attaches properties to the edges and vertices of a graph.\n-Definition: graph.hh:978\n-Dune::Amg::PropertiesGraph::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices in the graph.\n-Dune::Amg::PropertiesGraph::EdgeDescriptor\n-Graph::EdgeDescriptor EdgeDescriptor\n-The edge descritor.\n-Definition: graph.hh:993\n-Dune::Amg::PropertiesGraph::getEdgeProperties\n-const EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const\n-VertexDescriptor &target) const\n-Get the properties associated with a edge.\n-Dune::Amg::PropertiesGraph::getEdgeProperties\n-const EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge) const\n-Get the properties associated with a edge.\n-Dune::Amg::PropertiesGraph::graph\n-const Graph & graph() const\n-Get the graph the properties are attached to.\n-Dune::Amg::PropertiesGraph::maxVertex\n-VertexDescriptor maxVertex() const\n-Get the maximal vertex descriptor.\n-Dune::Amg::PropertiesGraph::Graph\n-G Graph\n-The graph we attach properties to.\n-Definition: graph.hh:983\n-Dune::Amg::PropertiesGraph::EdgeMap\n-EM EdgeMap\n-The type of the map for converting the EdgeDescriptor to std::size_t.\n-Definition: graph.hh:1030\n-Dune::Amg::PropertiesGraph::VertexMap\n-VM VertexMap\n-The type of the map for converting the VertexDescriptor to std::size_t.\n-Definition: graph.hh:1011\n-Dune::Amg::PropertiesGraph::VertexProperties\n-VP VertexProperties\n-The type of the properties of the vertices.\n-Definition: graph.hh:998\n-Dune::Amg::PropertiesGraph::noEdges\n-std::size_t noEdges() const\n-Get the number of edges in the graph.\n-Dune::Amg::PropertiesGraph::EdgeProperties\n-EP EdgeProperties\n-The type of the properties of the edges;.\n-Definition: graph.hh:1016\n-Dune::Amg::PropertiesGraph::getEdgeProperties\n-EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const\n-VertexDescriptor &target)\n-Get the properties associated with a edge.\n-Dune::Amg::PropertiesGraph::getEdgeProperties\n-EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge)\n-Get the properties associated with a edge.\n-Dune::Amg::PropertiesGraph::VertexDescriptor\n-Graph::VertexDescriptor VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:988\n-Dune::Amg::PropertiesGraph::PropertiesGraph\n-PropertiesGraph(Graph &graph, const VertexMap &vmap=VertexMap(), const EdgeMap\n-&emap=EdgeMap())\n-Constructor.\n-Dune::Amg::PropertiesGraph::EdgeIteratorT\n-Definition: graph.hh:1038\n-Dune::Amg::PropertiesGraph::EdgeIteratorT::Father\n-std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n-value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type\n-Father\n-The father class.\n-Definition: graph.hh:1050\n-Dune::Amg::PropertiesGraph::VertexIteratorT\n-Definition: graph.hh:1140\n-Dune::Amg::PropertiesGraph::VertexIteratorT::Father\n-std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n-value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::\n-type Father\n-The father class.\n-Definition: graph.hh:1151\n-Dune::Amg::GraphVertexPropertiesSelector\n-Wrapper to access the internal edge properties of a graph via operator[]()\n-Definition: graph.hh:1361\n-Dune::Amg::GraphVertexPropertiesSelector::GraphVertexPropertiesSelector\n-GraphVertexPropertiesSelector(G &g)\n-Constructor.\n-Definition: graph.hh:1380\n-Dune::Amg::GraphVertexPropertiesSelector::operator[]\n-VertexProperties & operator[](const Vertex &vertex) const\n-Get the properties associated to a vertex.\n-Definition: graph.hh:1395\n-Dune::Amg::GraphVertexPropertiesSelector::Graph\n-G Graph\n-The type of the graph with internal properties.\n-Definition: graph.hh:1366\n-Dune::Amg::GraphVertexPropertiesSelector::VertexProperties\n-G::VertexProperties VertexProperties\n-The type of the vertex properties.\n-Definition: graph.hh:1370\n-Dune::Amg::GraphVertexPropertiesSelector::GraphVertexPropertiesSelector\n-GraphVertexPropertiesSelector()\n-Default constructor.\n-Definition: graph.hh:1386\n-Dune::Amg::GraphVertexPropertiesSelector::Vertex\n-G::VertexDescriptor Vertex\n-The vertex descriptor.\n-Definition: graph.hh:1374\n-Dune::Amg::GraphEdgePropertiesSelector\n-Wrapper to access the internal vertex properties of a graph via operator[]()\n-Definition: graph.hh:1409\n-Dune::Amg::GraphEdgePropertiesSelector::operator[]\n-EdgeProperties & operator[](const Edge &edge) const\n-Get the properties associated to a vertex.\n-Definition: graph.hh:1442\n-Dune::Amg::GraphEdgePropertiesSelector::EdgeProperties\n-G::EdgeProperties EdgeProperties\n-The type of the vertex properties.\n-Definition: graph.hh:1418\n-Dune::Amg::GraphEdgePropertiesSelector::Edge\n-G::EdgeDescriptor Edge\n-The edge descriptor.\n-Definition: graph.hh:1422\n-Dune::Amg::GraphEdgePropertiesSelector::GraphEdgePropertiesSelector\n-GraphEdgePropertiesSelector()\n-Default constructor.\n-Definition: graph.hh:1434\n-Dune::Amg::GraphEdgePropertiesSelector::Graph\n-G Graph\n-The type of the graph with internal properties.\n-Definition: graph.hh:1414\n-Dune::Amg::GraphEdgePropertiesSelector::GraphEdgePropertiesSelector\n-GraphEdgePropertiesSelector(G &g)\n-Constructor.\n-Definition: graph.hh:1428\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::end\n+Iterator end()\n+Get iterator to one beyond last row.\n+Definition: bcrsmatrix.hh:681\n+Dune::BCRSMatrix::ColIterator\n+row_type::Iterator ColIterator\n+Iterator for the entries of each row.\n+Definition: bcrsmatrix.hh:704\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::createbegin\n+CreateIterator createbegin()\n+get initial create iterator\n+Definition: bcrsmatrix.hh:1097\n+Dune::BCRSMatrix::RealRowIterator\n+Iterator access to matrix rows\n+Definition: bcrsmatrix.hh:579\n+Dune::BCRSMatrix::CreateIterator\n+Iterator class for sequential creation of blocks\n+Definition: bcrsmatrix.hh:957\n+Dune::BCRSMatrix::CreateIterator::insert\n+void insert(size_type j)\n+put column index in row\n+Definition: bcrsmatrix.hh:1064\n+Dune::MatMultMatResult\n+Helper TMP to get the result type of a sparse matrix matrix multiplication ( )\n+Definition: matrixmatrix.hh:510\n+Dune::TransposedMatMultMatResult\n+Helper TMP to get the result type of a sparse matrix matrix multiplication ( )\n+Definition: matrixmatrix.hh:535\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00101.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00101.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: aggregates.hh File Reference\n+dune-istl: matrixredistribute.hh File Reference\n \n \n \n \n \n \n \n@@ -58,116 +58,91 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n
    \n
    \n \n- \n+
    matrixredistribute.hh File Reference
    \n
    \n
    \n \n-

    Provides classes for the Coloring process of AMG. \n+

    Functionality for redistributing a sparse matrix. \n More...

    \n-
    #include "parameters.hh"
    \n-#include "graph.hh"
    \n-#include "properties.hh"
    \n-#include "combinedfunctor.hh"
    \n-#include <dune/common/timer.hh>
    \n-#include <dune/common/stdstreams.hh>
    \n-#include <dune/common/poolallocator.hh>
    \n-#include <dune/common/sllist.hh>
    \n-#include <dune/common/ftraits.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <utility>
    \n-#include <set>
    \n-#include <algorithm>
    \n-#include <complex>
    \n-#include <limits>
    \n-#include <ostream>
    \n-#include <tuple>
    \n+
    #include <memory>
    \n+#include "repartition.hh"
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/parallel/indexset.hh>
    \n+#include <dune/istl/owneroverlapcopy.hh>
    \n+#include <dune/istl/paamg/pinfo.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::Amg::AggregationCriterion< T >
     Base class of all aggregation criterions. More...
    struct  Dune::RedistributeInformation< T >
     
    class  Dune::Amg::SymmetricMatrixDependency< M, N >
     Dependency policy for symmetric matrices. More...
    class  Dune::RedistributeInformation< OwnerOverlapCopyCommunication< T, T1 > >
     
    class  Dune::Amg::Dependency< M, N >
     Dependency policy for symmetric matrices. More...
    struct  Dune::CommMatrixRowSize< M, RI >
     Utility class to communicate and set the row sizes of a redistributed matrix. More...
     
    class  Dune::Amg::SymmetricDependency< M, N >
     Dependency policy for symmetric matrices. More...
    struct  Dune::CommMatrixSparsityPattern< M, I >
     Utility class to communicate and build the sparsity pattern of a redistributed matrix. More...
     
    class  Dune::Amg::Diagonal< N >
     Norm that uses only the [N][N] entry of the block to determine couplings. More...
    struct  Dune::CommPolicy< CommMatrixSparsityPattern< M, I > >
     
    class  Dune::Amg::FirstDiagonal
     Norm that uses only the [0][0] entry of the block to determine couplings. More...
    struct  Dune::CommMatrixRow< M, I >
     Utility class for comunicating the matrix entries. More...
     
    struct  Dune::Amg::RowSum
     Functor using the row sum (infinity) norm to determine strong couplings. More...
    struct  Dune::CommPolicy< CommMatrixRow< M, I > >
     
    struct  Dune::Amg::FrobeniusNorm
    struct  Dune::MatrixRowSizeGatherScatter< M, I, RI >
     
    struct  Dune::Amg::AlwaysOneNorm
    struct  Dune::MatrixCopyRowSizeGatherScatter< M, I, RI >
     
    class  Dune::Amg::SymmetricCriterion< M, Norm >
     Criterion taking advantage of symmetric matrices. More...
    struct  Dune::MatrixSparsityPatternGatherScatter< M, I >
     
    class  Dune::Amg::UnSymmetricCriterion< M, Norm >
     Criterion suitable for unsymmetric matrices. More...
     
    class  Dune::Amg::AggregatesMap< V >
     Class providing information about the mapping of the vertices onto aggregates. More...
     
    class  Dune::Amg::AggregatesMap< V >::DummyEdgeVisitor
     A Dummy visitor that does nothing for each visited edge. More...
     
    class  Dune::Amg::Aggregate< G, S >
     A class for temporarily storing the vertices of an aggregate in. More...
     
    class  Dune::Amg::Aggregator< G >
     Class for building the aggregates. More...
    struct  Dune::MatrixRowGatherScatter< M, I >
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<class T >
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const AggregationCriterion< T > &criterion)
     
    template<class G , class C >
    void Dune::Amg::buildDependency (G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
     Build the dependency of the matrix graph. More...
     
    template<class V >
    void Dune::Amg::printAggregates2d (const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)
     
    template<typename M , typename C >
    void Dune::redistributeSparsityPattern (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     
    template<typename M , typename C >
    void Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     
    template<typename M , typename C >
    void Dune::redistributeMatrix (M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
     Redistribute a matrix according to given domain decompositions. More...
     
    template<typename M >
    void Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, Dune::Amg::SequentialInformation &origComm, Dune::Amg::SequentialInformation &newComm, RedistributeInformation< Dune::Amg::SequentialInformation > &ri)
     
    template<typename M >
    void Dune::redistributeMatrix (M &origMatrix, M &newMatrix, Dune::Amg::SequentialInformation &origComm, Dune::Amg::SequentialInformation &newComm, RedistributeInformation< Dune::Amg::SequentialInformation > &ri)
     
    \n

    Detailed Description

    \n-

    Provides classes for the Coloring process of AMG.

    \n+

    Functionality for redistributing a sparse matrix.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,106 +4,82 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n Classes | Namespaces | Functions\n-aggregates.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides classes for the Coloring process of AMG. More...\n-#include \"parameters.hh\"\n-#include \"graph.hh\"\n-#include \"properties.hh\"\n-#include \"combinedfunctor.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+matrixredistribute.hh File Reference\n+Functionality for redistributing a sparse matrix. More...\n+#include \n+#include \"repartition.hh\"\n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::Amg::AggregationCriterion<_T_>\n-\u00a0 Base class of all aggregation criterions. More...\n+struct \u00a0Dune::RedistributeInformation<_T_>\n \u00a0\n- class \u00a0Dune::Amg::SymmetricMatrixDependency<_M,_N_>\n-\u00a0 Dependency policy for symmetric matrices. More...\n+ class \u00a0Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>\n+ >\n \u00a0\n- class \u00a0Dune::Amg::Dependency<_M,_N_>\n-\u00a0 Dependency policy for symmetric matrices. More...\n+struct \u00a0Dune::CommMatrixRowSize<_M,_RI_>\n+\u00a0 Utility class to communicate and set the row sizes of a redistributed\n+ matrix. More...\n \u00a0\n- class \u00a0Dune::Amg::SymmetricDependency<_M,_N_>\n-\u00a0 Dependency policy for symmetric matrices. More...\n+struct \u00a0Dune::CommMatrixSparsityPattern<_M,_I_>\n+\u00a0 Utility class to communicate and build the sparsity pattern of a\n+ redistributed matrix. More...\n \u00a0\n- class \u00a0Dune::Amg::Diagonal<_N_>\n-\u00a0 Norm that uses only the [N][N] entry of the block to determine\n- couplings. More...\n+struct \u00a0Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>\n \u00a0\n- class \u00a0Dune::Amg::FirstDiagonal\n-\u00a0 Norm that uses only the [0][0] entry of the block to determine\n- couplings. More...\n+struct \u00a0Dune::CommMatrixRow<_M,_I_>\n+\u00a0 Utility class for comunicating the matrix entries. More...\n \u00a0\n-struct \u00a0Dune::Amg::RowSum\n-\u00a0 Functor using the row sum (infinity) norm to determine strong\n- couplings. More...\n+struct \u00a0Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>\n \u00a0\n-struct \u00a0Dune::Amg::FrobeniusNorm\n+struct \u00a0Dune::MatrixRowSizeGatherScatter<_M,_I,_RI_>\n \u00a0\n-struct \u00a0Dune::Amg::AlwaysOneNorm\n+struct \u00a0Dune::MatrixCopyRowSizeGatherScatter<_M,_I,_RI_>\n \u00a0\n- class \u00a0Dune::Amg::SymmetricCriterion<_M,_Norm_>\n-\u00a0 Criterion taking advantage of symmetric matrices. More...\n+struct \u00a0Dune::MatrixSparsityPatternGatherScatter<_M,_I_>\n \u00a0\n- class \u00a0Dune::Amg::UnSymmetricCriterion<_M,_Norm_>\n-\u00a0 Criterion suitable for unsymmetric matrices. More...\n-\u00a0\n- class \u00a0Dune::Amg::AggregatesMap<_V_>\n-\u00a0 Class providing information about the mapping of the vertices onto\n- aggregates. More...\n-\u00a0\n- class \u00a0Dune::Amg::AggregatesMap<_V_>::DummyEdgeVisitor\n-\u00a0 A Dummy visitor that does nothing for each visited edge. More...\n-\u00a0\n- class \u00a0Dune::Amg::Aggregate<_G,_S_>\n-\u00a0 A class for temporarily storing the vertices of an aggregate in.\n- More...\n-\u00a0\n- class \u00a0Dune::Amg::Aggregator<_G_>\n-\u00a0 Class for building the aggregates. More...\n+struct \u00a0Dune::MatrixRowGatherScatter<_M,_I_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n Functions\n-template\n-std::ostream &\u00a0Dune::Amg::operator<< (std::ostream &os, const\n- AggregationCriterion< T > &criterion)\n-\u00a0\n-template\n- void\u00a0Dune::Amg::buildDependency (G &graph, const typename C::Matrix\n- &matrix, C criterion, bool finestLevel)\n-\u00a0 Build the dependency of the matrix graph. More...\n-\u00a0\n-template\n- void\u00a0Dune::Amg::printAggregates2d (const AggregatesMap< V >\n- &aggregates, int n, int m, std::ostream &os)\n+template\n+void\u00a0Dune::redistributeSparsityPattern (M &origMatrix, M &newMatrix, C\n+ &origComm, C &newComm, RedistributeInformation< C > &ri)\n+\u00a0\n+template\n+void\u00a0Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, C\n+ &origComm, C &newComm, RedistributeInformation< C > &ri)\n+\u00a0\n+template\n+void\u00a0Dune::redistributeMatrix (M &origMatrix, M &newMatrix, C &origComm, C\n+ &newComm, RedistributeInformation< C > &ri)\n+\u00a0 Redistribute a matrix according to given domain decompositions. More...\n+\u00a0\n+template\n+void\u00a0Dune::redistributeMatrixEntries (M &origMatrix, M &newMatrix, Dune::Amg::\n+ SequentialInformation &origComm, Dune::Amg::SequentialInformation\n+ &newComm, RedistributeInformation< Dune::Amg::SequentialInformation >\n+ &ri)\n+\u00a0\n+template\n+void\u00a0Dune::redistributeMatrix (M &origMatrix, M &newMatrix, Dune::Amg::\n+ SequentialInformation &origComm, Dune::Amg::SequentialInformation\n+ &newComm, RedistributeInformation< Dune::Amg::SequentialInformation >\n+ &ri)\n \u00a0\n ***** Detailed Description *****\n-Provides classes for the Coloring process of AMG.\n+Functionality for redistributing a sparse matrix.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00101_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00101_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: aggregates.hh Source File\n+dune-istl: matrixredistribute.hh Source File\n \n \n \n \n \n \n \n@@ -58,2166 +58,872 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n
    \n
    \n-
    aggregates.hh
    \n+
    matrixredistribute.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_AGGREGATES_HH
    \n-
    6#define DUNE_AMG_AGGREGATES_HH
    \n-
    7
    \n-
    8
    \n-
    9#include "parameters.hh"
    \n-
    10#include "graph.hh"
    \n-
    11#include "properties.hh"
    \n-
    12#include "combinedfunctor.hh"
    \n-
    13
    \n-
    14#include <dune/common/timer.hh>
    \n-
    15#include <dune/common/stdstreams.hh>
    \n-
    16#include <dune/common/poolallocator.hh>
    \n-
    17#include <dune/common/sllist.hh>
    \n-
    18#include <dune/common/ftraits.hh>
    \n-
    19#include <dune/common/scalarmatrixview.hh>
    \n-
    20
    \n-
    21#include <utility>
    \n-
    22#include <set>
    \n-
    23#include <algorithm>
    \n-
    24#include <complex>
    \n-
    25#include <limits>
    \n-
    26#include <ostream>
    \n-
    27#include <tuple>
    \n-
    28
    \n-
    29namespace Dune
    \n-
    30{
    \n-
    31 namespace Amg
    \n-
    32 {
    \n-
    33
    \n-
    47 template<class T>
    \n-
    48 class AggregationCriterion : public T
    \n-
    49 {
    \n-
    50
    \n-
    51 public:
    \n-\n+
    5#ifndef DUNE_ISTL_MATRIXREDISTRIBUTE_HH
    \n+
    6#define DUNE_ISTL_MATRIXREDISTRIBUTE_HH
    \n+
    7#include <memory>
    \n+
    8#include "repartition.hh"
    \n+
    9#include <dune/common/exceptions.hh>
    \n+
    10#include <dune/common/parallel/indexset.hh>
    \n+\n+\n+
    18namespace Dune
    \n+
    19{
    \n+
    20 template<typename T>
    \n+\n+
    22 {
    \n+
    23 bool isSetup() const
    \n+
    24 {
    \n+
    25 return false;
    \n+
    26 }
    \n+
    27 template<class D>
    \n+
    28 void redistribute([[maybe_unused]] const D& from, [[maybe_unused]] D& to) const
    \n+
    29 {}
    \n+
    30
    \n+
    31 template<class D>
    \n+
    32 void redistributeBackward([[maybe_unused]] D& from, [[maybe_unused]]const D& to) const
    \n+
    33 {}
    \n+
    34
    \n+\n+
    36 {}
    \n+
    37
    \n+
    38 void setNoRows([[maybe_unused]] std::size_t size)
    \n+
    39 {}
    \n+
    40
    \n+
    41 void setNoCopyRows([[maybe_unused]] std::size_t size)
    \n+
    42 {}
    \n+
    43
    \n+
    44 void setNoBackwardsCopyRows([[maybe_unused]] std::size_t size)
    \n+
    45 {}
    \n+
    46
    \n+
    47 std::size_t getRowSize([[maybe_unused]] std::size_t index) const
    \n+
    48 {
    \n+
    49 return -1;
    \n+
    50 }
    \n+
    51
    \n+
    52 std::size_t getCopyRowSize([[maybe_unused]] std::size_t index) const
    \n+
    53 {
    \n+
    54 return -1;
    \n+
    55 }
    \n
    56
    \n-\n-
    67 : T()
    \n-
    68 {}
    \n-
    69
    \n-\n-
    71 : T(parms)
    \n-
    72 {}
    \n-
    82 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    \n-
    83 {
    \n-
    84 this->setMaxDistance(diameter-1);
    \n-
    85 std::size_t csize=1;
    \n-
    86
    \n-
    87 for(; dim>0; dim--) {
    \n-
    88 csize*=diameter;
    \n-
    89 this->setMaxDistance(this->maxDistance()+diameter-1);
    \n-
    90 }
    \n-
    91 this->setMinAggregateSize(csize);
    \n-
    92 this->setMaxAggregateSize(static_cast<std::size_t>(csize*1.5));
    \n-
    93 }
    \n-
    94
    \n-
    105 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)
    \n-
    106 {
    \n-
    107 setDefaultValuesIsotropic(dim, diameter);
    \n-
    108 this->setMaxDistance(this->maxDistance()+dim-1);
    \n-
    109 }
    \n-
    110 };
    \n+
    57 std::size_t getBackwardsCopyRowSize([[maybe_unused]] std::size_t index) const
    \n+
    58 {
    \n+
    59 return -1;
    \n+
    60 }
    \n+
    61
    \n+
    62 };
    \n+
    63
    \n+
    64#if HAVE_MPI
    \n+
    65 template<typename T, typename T1>
    \n+\n+
    67 {
    \n+
    68 public:
    \n+\n+
    70
    \n+\n+
    72 : interface(), setup_(false)
    \n+
    73 {}
    \n+
    74
    \n+\n+
    76 {
    \n+
    77 return interface;
    \n+
    78 }
    \n+
    79 template<typename IS>
    \n+
    80 void checkInterface(const IS& source,
    \n+
    81 const IS& target, MPI_Comm comm)
    \n+
    82 {
    \n+
    83 auto ri = std::make_unique<RemoteIndices<IS> >(source, target, comm);
    \n+
    84 ri->template rebuild<true>();
    \n+
    85 Interface inf;
    \n+\n+
    87 int rank;
    \n+
    88 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n+
    89 inf.free();
    \n+
    90 inf.build(*ri, flags, flags);
    \n+
    91
    \n+
    92
    \n+
    93#ifdef DEBUG_REPART
    \n+
    94 if(inf!=interface) {
    \n+
    95
    \n+
    96 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n+
    97 if(rank==0)
    \n+
    98 std::cout<<"Interfaces do not match!"<<std::endl;
    \n+
    99 std::cout<<rank<<": redist interface new :"<<inf<<std::endl;
    \n+
    100 std::cout<<rank<<": redist interface :"<<interface<<std::endl;
    \n+
    101
    \n+
    102 throw "autsch!";
    \n+
    103 }
    \n+
    104#endif
    \n+
    105 }
    \n+
    106 void setSetup()
    \n+
    107 {
    \n+
    108 setup_=true;
    \n+
    109 interface.strip();
    \n+
    110 }
    \n
    111
    \n-
    112 template<class T>
    \n-
    113 std::ostream& operator<<(std::ostream& os, const AggregationCriterion<T>& criterion)
    \n-
    114 {
    \n-
    115 os<<"{ maxdistance="<<criterion.maxDistance()<<" minAggregateSize="
    \n-
    116 <<criterion.minAggregateSize()<< " maxAggregateSize="<<criterion.maxAggregateSize()
    \n-
    117 <<" connectivity="<<criterion.maxConnectivity()<<" debugLevel="<<criterion.debugLevel()<<"}";
    \n-
    118 return os;
    \n-
    119 }
    \n-
    120
    \n-
    132 template<class M, class N>
    \n-\n-
    134 {
    \n-
    135 public:
    \n-
    139 typedef M Matrix;
    \n-
    140
    \n-
    144 typedef N Norm;
    \n-
    145
    \n-
    149 typedef typename Matrix::row_type Row;
    \n-
    150
    \n-\n-
    155
    \n-
    156 void init(const Matrix* matrix);
    \n+\n+
    113 {
    \n+
    114 setup_=false;
    \n+
    115 }
    \n+
    116
    \n+
    117 template<class GatherScatter, class D>
    \n+
    118 void redistribute(const D& from, D& to) const
    \n+
    119 {
    \n+
    120 BufferedCommunicator communicator;
    \n+
    121 communicator.template build<D>(from,to, interface);
    \n+
    122 communicator.template forward<GatherScatter>(from, to);
    \n+
    123 communicator.free();
    \n+
    124 }
    \n+
    125 template<class GatherScatter, class D>
    \n+
    126 void redistributeBackward(D& from, const D& to) const
    \n+
    127 {
    \n+
    128
    \n+
    129 BufferedCommunicator communicator;
    \n+
    130 communicator.template build<D>(from,to, interface);
    \n+
    131 communicator.template backward<GatherScatter>(from, to);
    \n+
    132 communicator.free();
    \n+
    133 }
    \n+
    134
    \n+
    135 template<class D>
    \n+
    136 void redistribute(const D& from, D& to) const
    \n+
    137 {
    \n+
    138 redistribute<CopyGatherScatter<D> >(from,to);
    \n+
    139 }
    \n+
    140 template<class D>
    \n+
    141 void redistributeBackward(D& from, const D& to) const
    \n+
    142 {
    \n+
    143 redistributeBackward<CopyGatherScatter<D> >(from,to);
    \n+
    144 }
    \n+
    145 bool isSetup() const
    \n+
    146 {
    \n+
    147 return setup_;
    \n+
    148 }
    \n+
    149
    \n+
    150 void reserve(std::size_t size)
    \n+
    151 {}
    \n+
    152
    \n+
    153 std::size_t& getRowSize(std::size_t index)
    \n+
    154 {
    \n+
    155 return rowSize[index];
    \n+
    156 }
    \n
    157
    \n-
    158 void initRow(const Row& row, int index);
    \n-
    159
    \n-
    160 void examine(const ColIter& col);
    \n-
    161
    \n-
    162 template<class G>
    \n-
    163 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n-
    164
    \n-
    165 bool isIsolated();
    \n-
    166
    \n+
    158 std::size_t getRowSize(std::size_t index) const
    \n+
    159 {
    \n+
    160 return rowSize[index];
    \n+
    161 }
    \n+
    162
    \n+
    163 std::size_t& getCopyRowSize(std::size_t index)
    \n+
    164 {
    \n+
    165 return copyrowSize[index];
    \n+
    166 }
    \n
    167
    \n-\n-
    169 : Parameters(parms)
    \n-
    170 {}
    \n-\n-
    172 : Parameters()
    \n-
    173 {}
    \n-
    174
    \n-
    175 protected:
    \n-\n-\n-
    180 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-\n-\n-
    185 int row_;
    \n-\n-
    188 std::vector<real_type> vals_;
    \n-
    189 typename std::vector<real_type>::iterator valIter_;
    \n-
    190
    \n-
    191 };
    \n+
    168 std::size_t getCopyRowSize(std::size_t index) const
    \n+
    169 {
    \n+
    170 return copyrowSize[index];
    \n+
    171 }
    \n+
    172
    \n+
    173 std::size_t& getBackwardsCopyRowSize(std::size_t index)
    \n+
    174 {
    \n+
    175 return backwardscopyrowSize[index];
    \n+
    176 }
    \n+
    177
    \n+
    178 std::size_t getBackwardsCopyRowSize(std::size_t index) const
    \n+
    179 {
    \n+
    180 return backwardscopyrowSize[index];
    \n+
    181 }
    \n+
    182
    \n+
    183 void setNoRows(std::size_t rows)
    \n+
    184 {
    \n+
    185 rowSize.resize(rows, 0);
    \n+
    186 }
    \n+
    187
    \n+
    188 void setNoCopyRows(std::size_t rows)
    \n+
    189 {
    \n+
    190 copyrowSize.resize(rows, 0);
    \n+
    191 }
    \n
    192
    \n-
    193
    \n-
    194 template<class M, class N>
    \n-\n-
    196 {
    \n-
    197 matrix_ = matrix;
    \n-
    198 }
    \n-
    199
    \n-
    200 template<class M, class N>
    \n-
    201 inline void SymmetricMatrixDependency<M,N>::initRow(const Row& row, int index)
    \n-
    202 {
    \n-
    203 using std::min;
    \n-
    204 vals_.assign(row.size(), 0.0);
    \n-
    205 assert(vals_.size()==row.size());
    \n-
    206 valIter_=vals_.begin();
    \n-
    207
    \n-
    208 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
    \n-
    209 diagonal_=norm_(row[index]);
    \n-
    210 row_ = index;
    \n-
    211 }
    \n-
    212
    \n-
    213 template<class M, class N>
    \n-\n-
    215 {
    \n-
    216 using std::max;
    \n-
    217 // skip positive offdiagonals if norm preserves sign of them.
    \n-
    218 real_type eij = norm_(*col);
    \n-
    219 if(!N::is_sign_preserving || eij<0) // || eji<0)
    \n-
    220 {
    \n-
    221 *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())[col.index()]);
    \n-
    222 maxValue_ = max(maxValue_, *valIter_);
    \n-
    223 }else
    \n-
    224 *valIter_ =0;
    \n-
    225 ++valIter_;
    \n-
    226 }
    \n-
    227
    \n-
    228 template<class M, class N>
    \n-
    229 template<class G>
    \n-
    230 inline void SymmetricMatrixDependency<M,N>::examine(G&, const typename G::EdgeIterator& edge, const ColIter&)
    \n-
    231 {
    \n-
    232 if(*valIter_ > alpha() * maxValue_) {
    \n-
    233 edge.properties().setDepends();
    \n-
    234 edge.properties().setInfluences();
    \n-
    235 }
    \n-
    236 ++valIter_;
    \n-
    237 }
    \n-
    238
    \n-
    239 template<class M, class N>
    \n-\n-
    241 {
    \n-
    242 if(diagonal_==0)
    \n-
    243 DUNE_THROW(Dune::ISTLError, "No diagonal entry for row "<<row_<<".");
    \n-
    244 valIter_=vals_.begin();
    \n-
    245 return maxValue_ < beta();
    \n-
    246 }
    \n+
    193 void setNoBackwardsCopyRows(std::size_t rows)
    \n+
    194 {
    \n+
    195 backwardscopyrowSize.resize(rows, 0);
    \n+
    196 }
    \n+
    197
    \n+
    198 private:
    \n+
    199 std::vector<std::size_t> rowSize;
    \n+
    200 std::vector<std::size_t> copyrowSize;
    \n+
    201 std::vector<std::size_t> backwardscopyrowSize;
    \n+
    202 RedistributeInterface interface;
    \n+
    203 bool setup_;
    \n+
    204 };
    \n+
    205
    \n+
    214 template<class M, class RI>
    \n+\n+
    216 {
    \n+
    217 // Make the default communication policy work.
    \n+
    218 typedef typename M::size_type value_type;
    \n+
    219 typedef typename M::size_type size_type;
    \n+
    220
    \n+
    226 CommMatrixRowSize(const M& m_, RI& rowsize_)
    \n+
    227 : matrix(m_), rowsize(rowsize_)
    \n+
    228 {}
    \n+
    229 const M& matrix;
    \n+\n+
    231
    \n+
    232 };
    \n+
    233
    \n+
    234
    \n+
    243 template<class M, class I>
    \n+\n+
    245 {
    \n+
    246 typedef typename M::size_type size_type;
    \n
    247
    \n-
    251 template<class M, class N>
    \n-
    252 class Dependency : public Parameters
    \n-
    253 {
    \n-
    254 public:
    \n-
    258 typedef M Matrix;
    \n-
    259
    \n-
    263 typedef N Norm;
    \n-
    264
    \n-
    268 typedef typename Matrix::row_type Row;
    \n+
    254 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_)
    \n+
    255 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()
    \n+
    256 {}
    \n+
    257
    \n+
    265 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_,
    \n+
    266 const std::vector<typename M::size_type>& rowsize_)
    \n+
    267 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), sparsity(aggidxset_.size()), rowsize(&rowsize_)
    \n+
    268 {}
    \n
    269
    \n-\n-
    274
    \n-
    275 void init(const Matrix* matrix);
    \n-
    276
    \n-
    277 void initRow(const Row& row, int index);
    \n-
    278
    \n-
    279 void examine(const ColIter& col);
    \n-
    280
    \n-
    281 template<class G>
    \n-
    282 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n-
    283
    \n-\n-
    285
    \n-
    286 Dependency(const Parameters& parms)
    \n-
    287 : Parameters(parms)
    \n-
    288 {}
    \n-
    289
    \n-\n-
    291 : Parameters()
    \n-
    292 {}
    \n-
    293
    \n-
    294 protected:
    \n-\n-\n-
    299 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-\n-\n-
    304 int row_;
    \n-\n-
    307 };
    \n-
    308
    \n-
    312 template<class M, class N>
    \n-\n-
    314 {
    \n-
    315 public:
    \n-
    319 typedef M Matrix;
    \n-
    320
    \n-
    324 typedef N Norm;
    \n-
    325
    \n-
    329 typedef typename Matrix::row_type Row;
    \n-
    330
    \n-\n-
    335
    \n-
    336 void init(const Matrix* matrix);
    \n-
    337
    \n-
    338 void initRow(const Row& row, int index);
    \n-
    339
    \n-
    340 void examine(const ColIter& col);
    \n-
    341
    \n-
    342 template<class G>
    \n-
    343 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n-
    344
    \n-\n-
    346
    \n-
    347
    \n-\n-
    349 : Parameters(parms)
    \n-
    350 {}
    \n-\n-
    352 : Parameters()
    \n-
    353 {}
    \n-
    354
    \n-
    355 protected:
    \n-\n-\n-
    360 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-\n-\n-
    365 int row_;
    \n-\n-
    368 private:
    \n-
    369 void initRow(const Row& row, int index, const std::true_type&);
    \n-
    370 void initRow(const Row& row, int index, const std::false_type&);
    \n-
    371 };
    \n+\n+
    277 {
    \n+
    278 // insert diagonal to overlap rows
    \n+
    279 typedef typename Dune::GlobalLookupIndexSet<I>::const_iterator IIter;
    \n+\n+
    281 std::size_t nnz=0;
    \n+
    282#ifdef DEBUG_REPART
    \n+
    283 int rank;
    \n+
    284
    \n+
    285 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    \n+
    286#endif
    \n+
    287 for(IIter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i) {
    \n+
    288 if(!OwnerSet::contains(i->local().attribute())) {
    \n+
    289#ifdef DEBUG_REPART
    \n+
    290 std::cout<<rank<<" Inserting diagonal for"<<i->local()<<std::endl;
    \n+
    291#endif
    \n+
    292 sparsity[i->local()].insert(i->local());
    \n+
    293 }
    \n+
    294
    \n+
    295 nnz+=sparsity[i->local()].size();
    \n+
    296 }
    \n+
    297 assert( aggidxset.size()==sparsity.size());
    \n+
    298
    \n+
    299 if(nnz>0) {
    \n+
    300 m.setSize(aggidxset.size(), aggidxset.size(), nnz);
    \n+
    301 m.setBuildMode(M::row_wise);
    \n+
    302 typename M::CreateIterator citer=m.createbegin();
    \n+
    303#ifdef DEBUG_REPART
    \n+
    304 std::size_t idx=0;
    \n+
    305 bool correct=true;
    \n+
    306 Dune::GlobalLookupIndexSet<I> global(aggidxset);
    \n+
    307#endif
    \n+
    308 typedef typename std::vector<std::set<size_type> >::const_iterator Iter;
    \n+
    309 for(Iter i=sparsity.begin(), end=sparsity.end(); i!=end; ++i, ++citer)
    \n+
    310 {
    \n+
    311 typedef typename std::set<size_type>::const_iterator SIter;
    \n+
    312 for(SIter si=i->begin(), send=i->end(); si!=send; ++si)
    \n+
    313 citer.insert(*si);
    \n+
    314#ifdef DEBUG_REPART
    \n+
    315 if(i->find(idx)==i->end()) {
    \n+
    316 const typename I::IndexPair* gi=global.pair(idx);
    \n+
    317 assert(gi);
    \n+
    318 std::cout<<rank<<": row "<<idx<<" is missing a diagonal entry! global="<<gi->global()<<" attr="<<gi->local().attribute()<<" "<<
    \n+
    319 OwnerSet::contains(gi->local().attribute())<<
    \n+
    320 " row size="<<i->size()<<std::endl;
    \n+
    321 correct=false;
    \n+
    322 }
    \n+
    323 ++idx;
    \n+
    324#endif
    \n+
    325 }
    \n+
    326#ifdef DEBUG_REPART
    \n+
    327 if(!correct)
    \n+
    328 throw "bla";
    \n+
    329#endif
    \n+
    330 }
    \n+
    331 }
    \n+
    332
    \n+
    340 void completeSparsityPattern(std::vector<std::set<size_type> > add_sparsity)
    \n+
    341 {
    \n+
    342 for (unsigned int i = 0; i != sparsity.size(); ++i) {
    \n+
    343 if (add_sparsity[i].size() != 0) {
    \n+
    344 typedef std::set<size_type> Set;
    \n+
    345 Set tmp_set;
    \n+
    346 std::insert_iterator<Set> tmp_insert (tmp_set, tmp_set.begin());
    \n+
    347 std::set_union(add_sparsity[i].begin(), add_sparsity[i].end(),
    \n+
    348 sparsity[i].begin(), sparsity[i].end(), tmp_insert);
    \n+
    349 sparsity[i].swap(tmp_set);
    \n+
    350 }
    \n+
    351 }
    \n+
    352 }
    \n+
    353
    \n+
    354 const M& matrix;
    \n+
    355 typedef Dune::GlobalLookupIndexSet<I> LookupIndexSet;
    \n+
    356 const Dune::GlobalLookupIndexSet<I>& idxset;
    \n+
    357 const I& aggidxset;
    \n+
    358 std::vector<std::set<size_type> > sparsity;
    \n+
    359 const std::vector<size_type>* rowsize;
    \n+
    360 };
    \n+
    361
    \n+
    362 template<class M, class I>
    \n+
    363 struct CommPolicy<CommMatrixSparsityPattern<M,I> >
    \n+
    364 {
    \n+\n+
    366
    \n+
    371 typedef typename I::GlobalIndex IndexedType;
    \n
    372
    \n-
    377 template<int N>
    \n-\n-
    379 {
    \n-
    380 public:
    \n-
    381 enum { /* @brief We preserve the sign.*/
    \n-
    382 is_sign_preserving = true
    \n-
    383 };
    \n-
    384
    \n-
    389 template<class M>
    \n-
    390 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m,
    \n-
    391 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr) const
    \n-
    392 {
    \n-
    393 typedef typename M::field_type field_type;
    \n-
    394 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-
    395 static_assert( std::is_convertible<field_type, real_type >::value,
    \n-
    396 "use of diagonal norm in AMG not implemented for complex field_type");
    \n-
    397 return m[N][N];
    \n-
    398 // possible implementation for complex types: return signed_abs(m[N][N]);
    \n-
    399 }
    \n-
    400
    \n-
    405 template<class M>
    \n-
    406 auto operator()(const M& m,
    \n-
    407 typename std::enable_if_t<Dune::IsNumber<M>::value>* sfinae = nullptr) const
    \n-
    408 {
    \n-
    409 typedef typename FieldTraits<M>::real_type real_type;
    \n-
    410 static_assert( std::is_convertible<M, real_type >::value,
    \n-
    411 "use of diagonal norm in AMG not implemented for complex field_type");
    \n-
    412 return m;
    \n-
    413 // possible implementation for complex types: return signed_abs(m[N][N]);
    \n-
    414 }
    \n-
    415
    \n-
    416 private:
    \n-
    417
    \n-
    419 template<typename T>
    \n-
    420 static T signed_abs(const T & v)
    \n-
    421 {
    \n-
    422 return v;
    \n-
    423 }
    \n-
    424
    \n-
    426 template<typename T>
    \n-
    427 static T signed_abs(const std::complex<T> & v)
    \n-
    428 {
    \n-
    429 // return sign * abs_value
    \n-
    430 // in case of complex numbers this extends to using the csgn function to determine the sign
    \n-
    431 return csgn(v) * std::abs(v);
    \n-
    432 }
    \n-
    433
    \n-
    435 template<typename T>
    \n-
    436 static T csgn(const T & v)
    \n-
    437 {
    \n-
    438 return (T(0) < v) - (v < T(0));
    \n-
    439 }
    \n-
    440
    \n-
    442 template<typename T>
    \n-
    443 static T csgn(std::complex<T> a)
    \n-
    444 {
    \n-
    445 return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());
    \n-
    446 }
    \n-
    447
    \n-
    448 };
    \n-
    449
    \n-
    454 class FirstDiagonal : public Diagonal<0>
    \n-
    455 {};
    \n-
    456
    \n-
    462 struct RowSum
    \n-
    463 {
    \n-
    464
    \n-
    465 enum { /* @brief We preserve the sign.*/
    \n-
    466 is_sign_preserving = false
    \n-
    467 };
    \n-
    472 template<class M>
    \n-
    473 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n-
    474 {
    \n-
    475 return m.infinity_norm();
    \n-
    476 }
    \n-
    477 };
    \n-
    478
    \n-\n-
    480 {
    \n-
    481
    \n-
    482 enum { /* @brief We preserve the sign.*/
    \n-
    483 is_sign_preserving = false
    \n-
    484 };
    \n-
    489 template<class M>
    \n-
    490 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n-
    491 {
    \n-
    492 return m.frobenius_norm();
    \n-
    493 }
    \n-
    494 };
    \n-\n-
    496 {
    \n+
    374 typedef VariableSize IndexedTypeFlag;
    \n+
    375
    \n+
    376 static typename M::size_type getSize(const Type& t, std::size_t i)
    \n+
    377 {
    \n+
    378 if(!t.rowsize)
    \n+
    379 return t.matrix[i].size();
    \n+
    380 else
    \n+
    381 {
    \n+
    382 assert((*t.rowsize)[i]>0);
    \n+
    383 return (*t.rowsize)[i];
    \n+
    384 }
    \n+
    385 }
    \n+
    386 };
    \n+
    387
    \n+
    394 template<class M, class I>
    \n+\n+
    396 {
    \n+
    405 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_)
    \n+
    406 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()
    \n+
    407 {}
    \n+
    408
    \n+
    412 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet<I>& idxset_, const I& aggidxset_,
    \n+
    413 std::vector<size_t>& rowsize_)
    \n+
    414 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize(&rowsize_)
    \n+
    415 {}
    \n+\n+
    422 {
    \n+
    423 typedef typename Dune::GlobalLookupIndexSet<I>::const_iterator Iter;
    \n+\n+
    425
    \n+
    426 for(Iter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i)
    \n+
    427 if(!OwnerSet::contains(i->local().attribute())) {
    \n+
    428 // Set to Dirchlet
    \n+
    429 typedef typename M::ColIterator CIter;
    \n+
    430 for(CIter c=matrix[i->local()].begin(), cend= matrix[i->local()].end();
    \n+
    431 c!= cend; ++c)
    \n+
    432 {
    \n+
    433 *c=0;
    \n+
    434 if(c.index()==i->local()) {
    \n+
    435 auto setDiagonal = [](auto&& scalarOrMatrix, const auto& value) {
    \n+
    436 auto&& matrixView = Dune::Impl::asMatrix(scalarOrMatrix);
    \n+
    437 for (auto rowIt = matrixView.begin(); rowIt != matrixView.end(); ++rowIt)
    \n+
    438 (*rowIt)[rowIt.index()] = value;
    \n+
    439 };
    \n+
    440 setDiagonal(*c, 1);
    \n+
    441 }
    \n+
    442 }
    \n+
    443 }
    \n+
    444 }
    \n+\n+
    448 const Dune::GlobalLookupIndexSet<I>& idxset;
    \n+
    450 const I& aggidxset;
    \n+
    452 std::vector<size_t>* rowsize; // row sizes differ from sender side in overlap!
    \n+
    453 };
    \n+
    454
    \n+
    455 template<class M, class I>
    \n+
    456 struct CommPolicy<CommMatrixRow<M,I> >
    \n+
    457 {
    \n+\n+
    459
    \n+
    464 typedef std::pair<typename I::GlobalIndex,typename M::block_type> IndexedType;
    \n+
    465
    \n+
    467 typedef VariableSize IndexedTypeFlag;
    \n+
    468
    \n+
    469 static std::size_t getSize(const Type& t, std::size_t i)
    \n+
    470 {
    \n+
    471 if(!t.rowsize)
    \n+
    472 return t.matrix[i].size();
    \n+
    473 else
    \n+
    474 {
    \n+
    475 assert((*t.rowsize)[i]>0);
    \n+
    476 return (*t.rowsize)[i];
    \n+
    477 }
    \n+
    478 }
    \n+
    479 };
    \n+
    480
    \n+
    481 template<class M, class I, class RI>
    \n+\n+
    483 {
    \n+\n+
    485
    \n+
    486 static const typename M::size_type gather(const Container& cont, std::size_t i)
    \n+
    487 {
    \n+
    488 return cont.matrix[i].size();
    \n+
    489 }
    \n+
    490 static void scatter(Container& cont, const typename M::size_type& rowsize, std::size_t i)
    \n+
    491 {
    \n+
    492 assert(rowsize);
    \n+
    493 cont.rowsize.getRowSize(i)=rowsize;
    \n+
    494 }
    \n+
    495
    \n+
    496 };
    \n
    497
    \n-
    498 enum { /* @brief We preserve the sign.*/
    \n-
    499 is_sign_preserving = false
    \n-
    500 };
    \n-
    505 template<class M>
    \n-
    506 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n-
    507 {
    \n-
    508 return 1;
    \n-
    509 }
    \n-
    510 };
    \n-
    517 template<class M, class Norm>
    \n-
    518 class SymmetricCriterion : public AggregationCriterion<SymmetricDependency<M,Norm> >
    \n-
    519 {
    \n-
    520 public:
    \n-\n-\n-
    523 {}
    \n-\n-
    525 {}
    \n-
    526 };
    \n-
    527
    \n-
    528
    \n-
    537 template<class M, class Norm>
    \n-
    538 class UnSymmetricCriterion : public AggregationCriterion<Dependency<M,Norm> >
    \n-
    539 {
    \n-
    540 public:
    \n-\n-\n-
    543 {}
    \n-\n-
    545 {}
    \n-
    546 };
    \n-
    547 // forward declaration
    \n-
    548 template<class G> class Aggregator;
    \n-
    549
    \n-
    550
    \n-
    558 template<class V>
    \n-\n-
    560 {
    \n-
    561 public:
    \n-
    562
    \n-
    566 static const V UNAGGREGATED;
    \n-
    567
    \n-
    571 static const V ISOLATED;
    \n-\n-
    576
    \n-\n-
    581
    \n-
    586 typedef PoolAllocator<VertexDescriptor,100> Allocator;
    \n-
    587
    \n-
    592 typedef SLList<VertexDescriptor,Allocator> VertexList;
    \n-
    593
    \n-\n-
    598 {
    \n-
    599 public:
    \n-
    600 template<class EdgeIterator>
    \n-
    601 void operator()([[maybe_unused]] const EdgeIterator& edge) const
    \n-
    602 {}
    \n-
    603 };
    \n-
    604
    \n-
    605
    \n-\n-
    610
    \n-\n-
    617
    \n-\n-
    622
    \n-
    634 template<class M, class G, class C>
    \n-
    635 std::tuple<int,int,int,int> buildAggregates(const M& matrix, G& graph, const C& criterion,
    \n-
    636 bool finestLevel);
    \n-
    637
    \n-
    655 template<bool reset, class G, class F, class VM>
    \n-
    656 std::size_t breadthFirstSearch(const VertexDescriptor& start,
    \n-
    657 const AggregateDescriptor& aggregate,
    \n-
    658 const G& graph,
    \n-
    659 F& aggregateVisitor,
    \n-
    660 VM& visitedMap) const;
    \n+
    498 template<class M, class I, class RI>
    \n+\n+
    500 {
    \n+\n+
    502
    \n+
    503 static const typename M::size_type gather(const Container& cont, std::size_t i)
    \n+
    504 {
    \n+
    505 return cont.matrix[i].size();
    \n+
    506 }
    \n+
    507 static void scatter(Container& cont, const typename M::size_type& rowsize, std::size_t i)
    \n+
    508 {
    \n+
    509 assert(rowsize);
    \n+
    510 if (rowsize > cont.rowsize.getCopyRowSize(i))
    \n+
    511 cont.rowsize.getCopyRowSize(i)=rowsize;
    \n+
    512 }
    \n+
    513
    \n+
    514 };
    \n+
    515
    \n+
    516 template<class M, class I>
    \n+\n+
    518 {
    \n+
    519 typedef typename I::GlobalIndex GlobalIndex;
    \n+\n+
    521 typedef typename M::ConstColIterator ColIter;
    \n+
    522
    \n+
    523 static ColIter col;
    \n+\n+
    525
    \n+
    526 static const GlobalIndex& gather(const Container& cont, std::size_t i, std::size_t j)
    \n+
    527 {
    \n+
    528 if(j==0)
    \n+
    529 col=cont.matrix[i].begin();
    \n+
    530 else if (col!=cont.matrix[i].end())
    \n+
    531 ++col;
    \n+
    532
    \n+
    533 //copy communication: different row sizes for copy rows with the same global index
    \n+
    534 //are possible. If all values of current matrix row are sent, send
    \n+
    535 //std::numeric_limits<GlobalIndex>::max()
    \n+
    536 //and receiver will ignore it.
    \n+
    537 if (col==cont.matrix[i].end()) {
    \n+
    538 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n+
    539 return numlimits;
    \n+
    540 }
    \n+
    541 else {
    \n+
    542 const typename I::IndexPair* index=cont.idxset.pair(col.index());
    \n+
    543 assert(index);
    \n+
    544 // Only send index if col is no ghost
    \n+
    545 if ( index->local().attribute() != 2)
    \n+
    546 return index->global();
    \n+
    547 else {
    \n+
    548 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n+
    549 return numlimits;
    \n+
    550 }
    \n+
    551 }
    \n+
    552 }
    \n+
    553 static void scatter(Container& cont, const GlobalIndex& gi, std::size_t i, [[maybe_unused]] std::size_t j)
    \n+
    554 {
    \n+
    555 try{
    \n+
    556 if (gi != std::numeric_limits<GlobalIndex>::max()) {
    \n+
    557 const typename I::IndexPair& ip=cont.aggidxset.at(gi);
    \n+
    558 assert(ip.global()==gi);
    \n+
    559 std::size_t column = ip.local();
    \n+
    560 cont.sparsity[i].insert(column);
    \n+
    561
    \n+\n+
    563 if(!OwnerSet::contains(ip.local().attribute()))
    \n+
    564 // preserve symmetry for overlap
    \n+
    565 cont.sparsity[column].insert(i);
    \n+
    566 }
    \n+
    567 }
    \n+
    568 catch(const Dune::RangeError&) {
    \n+
    569 // Entry not present in the new index set. Ignore!
    \n+
    570#ifdef DEBUG_REPART
    \n+
    571 typedef typename Container::LookupIndexSet GlobalLookup;
    \n+
    572 typedef typename GlobalLookup::IndexPair IndexPair;
    \n+\n+
    574
    \n+
    575 GlobalLookup lookup(cont.aggidxset);
    \n+
    576 const IndexPair* pi=lookup.pair(i);
    \n+
    577 assert(pi);
    \n+
    578 if(OwnerSet::contains(pi->local().attribute())) {
    \n+
    579 int rank;
    \n+
    580 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    \n+
    581 std::cout<<rank<<cont.aggidxset<<std::endl;
    \n+
    582 std::cout<<rank<<": row "<<i<<" (global="<<gi <<") not in index set for owner index "<<pi->global()<<std::endl;
    \n+
    583 throw;
    \n+
    584 }
    \n+
    585#endif
    \n+
    586 }
    \n+
    587 }
    \n+
    588
    \n+
    589 };
    \n+
    590 template<class M, class I>
    \n+\n+
    592
    \n+
    593 template<class M, class I>
    \n+\n+
    595
    \n+
    596
    \n+
    597 template<class M, class I>
    \n+\n+
    599 {
    \n+
    600 typedef typename I::GlobalIndex GlobalIndex;
    \n+\n+
    602 typedef typename M::ConstColIterator ColIter;
    \n+
    603 typedef typename std::pair<GlobalIndex,typename M::block_type> Data;
    \n+
    604 static ColIter col;
    \n+\n+\n+
    607
    \n+
    608 static const Data& gather(const Container& cont, std::size_t i, std::size_t j)
    \n+
    609 {
    \n+
    610 if(j==0)
    \n+
    611 col=cont.matrix[i].begin();
    \n+
    612 else if (col!=cont.matrix[i].end())
    \n+
    613 ++col;
    \n+
    614 // copy communication: different row sizes for copy rows with the same global index
    \n+
    615 // are possible. If all values of current matrix row are sent, send
    \n+
    616 // std::numeric_limits<GlobalIndex>::max()
    \n+
    617 // and receiver will ignore it.
    \n+
    618 if (col==cont.matrix[i].end()) {
    \n+
    619 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n+\n+
    621 return datastore;
    \n+
    622 }
    \n+
    623 else {
    \n+
    624 // convert local column index to global index
    \n+
    625 const typename I::IndexPair* index=cont.idxset.pair(col.index());
    \n+
    626 assert(index);
    \n+
    627 // Store the data to prevent reference to temporary
    \n+
    628 // Only send index if col is no ghost
    \n+
    629 if ( index->local().attribute() != 2)
    \n+
    630 datastore = Data(index->global(),*col);
    \n+
    631 else {
    \n+
    632 numlimits = std::numeric_limits<GlobalIndex>::max();
    \n+\n+
    634 }
    \n+
    635 return datastore;
    \n+
    636 }
    \n+
    637 }
    \n+
    638 static void scatter(Container& cont, const Data& data, std::size_t i, [[maybe_unused]] std::size_t j)
    \n+
    639 {
    \n+
    640 try{
    \n+
    641 if (data.first != std::numeric_limits<GlobalIndex>::max()) {
    \n+
    642 typename M::size_type column=cont.aggidxset.at(data.first).local();
    \n+
    643 cont.matrix[i][column]=data.second;
    \n+
    644 }
    \n+
    645 }
    \n+
    646 catch(const Dune::RangeError&) {
    \n+
    647 // This an overlap row and might therefore lack some entries!
    \n+
    648 }
    \n+
    649
    \n+
    650 }
    \n+
    651 };
    \n+
    652
    \n+
    653 template<class M, class I>
    \n+\n+
    655
    \n+
    656 template<class M, class I>
    \n+\n+
    658
    \n+
    659 template<class M, class I>
    \n+\n
    661
    \n-
    685 template<bool remove, bool reset, class G, class L, class F1, class F2, class VM>
    \n-
    686 std::size_t breadthFirstSearch(const VertexDescriptor& start,
    \n-
    687 const AggregateDescriptor& aggregate,
    \n-
    688 const G& graph, L& visited, F1& aggregateVisitor,
    \n-
    689 F2& nonAggregateVisitor,
    \n-
    690 VM& visitedMap) const;
    \n-
    691
    \n-
    697 void allocate(std::size_t noVertices);
    \n-
    698
    \n-
    702 std::size_t noVertices() const;
    \n-
    703
    \n-
    707 void free();
    \n-
    708
    \n-\n-
    715
    \n-\n-
    722
    \n-\n+
    662 template<typename M, typename C>
    \n+
    663 void redistributeSparsityPattern(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n+\n+
    665 {
    \n+
    666 typename C::CopySet copyflags;
    \n+
    667 typename C::OwnerSet ownerflags;
    \n+
    668 typedef typename C::ParallelIndexSet IndexSet;
    \n+\n+
    670 std::vector<typename M::size_type> rowsize(newComm.indexSet().size(), 0);
    \n+
    671 std::vector<typename M::size_type> copyrowsize(newComm.indexSet().size(), 0);
    \n+
    672 std::vector<typename M::size_type> backwardscopyrowsize(origComm.indexSet().size(), 0);
    \n+
    673
    \n+
    674 // get owner rowsizes
    \n+
    675 CommMatrixRowSize<M,RI> commRowSize(origMatrix, ri);
    \n+
    676 ri.template redistribute<MatrixRowSizeGatherScatter<M,IndexSet,RI> >(commRowSize,commRowSize);
    \n+
    677
    \n+
    678 origComm.buildGlobalLookup();
    \n+
    679
    \n+
    680 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n+
    681 rowsize[i] = ri.getRowSize(i);
    \n+
    682 }
    \n+
    683 // get sparsity pattern from owner rows
    \n+\n+
    685 origsp(origMatrix, origComm.globalLookup(), newComm.indexSet());
    \n+\n+
    687 newsp(origMatrix, origComm.globalLookup(), newComm.indexSet(), rowsize);
    \n+
    688
    \n+
    689 ri.template redistribute<MatrixSparsityPatternGatherScatter<M,IndexSet> >(origsp,newsp);
    \n+
    690
    \n+
    691 // build copy to owner interface to get missing matrix values for novlp case
    \n+\n+
    693 RemoteIndices<IndexSet> *ris = new RemoteIndices<IndexSet>(origComm.indexSet(),
    \n+
    694 newComm.indexSet(),
    \n+
    695 origComm.communicator());
    \n+
    696 ris->template rebuild<true>();
    \n+
    697
    \n+
    698 ri.getInterface().free();
    \n+
    699 ri.getInterface().build(*ris,copyflags,ownerflags);
    \n+
    700
    \n+
    701 // get copy rowsizes
    \n+
    702 CommMatrixRowSize<M,RI> commRowSize_copy(origMatrix, ri);
    \n+
    703 ri.template redistribute<MatrixCopyRowSizeGatherScatter<M,IndexSet,RI> >(commRowSize_copy,
    \n+
    704 commRowSize_copy);
    \n+
    705
    \n+
    706 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n+
    707 copyrowsize[i] = ri.getCopyRowSize(i);
    \n+
    708 }
    \n+
    709 //get copy rowsizes for sender
    \n+
    710 ri.redistributeBackward(backwardscopyrowsize,copyrowsize);
    \n+
    711 for (std::size_t i=0; i < origComm.indexSet().size(); i++) {
    \n+
    712 ri.getBackwardsCopyRowSize(i) = backwardscopyrowsize[i];
    \n+
    713 }
    \n+
    714
    \n+
    715 // get sparsity pattern from copy rows
    \n+
    716 CommMatrixSparsityPattern<M,IndexSet> origsp_copy(origMatrix,
    \n+
    717 origComm.globalLookup(),
    \n+
    718 newComm.indexSet(),
    \n+
    719 backwardscopyrowsize);
    \n+
    720 CommMatrixSparsityPattern<M,IndexSet> newsp_copy(origMatrix, origComm.globalLookup(),
    \n+
    721 newComm.indexSet(), copyrowsize);
    \n+
    722 ri.template redistribute<MatrixSparsityPatternGatherScatter<M,IndexSet> >(origsp_copy,
    \n+
    723 newsp_copy);
    \n
    724
    \n-\n-
    726 {
    \n-
    727 return aggregates_;
    \n-
    728 }
    \n-
    729
    \n-\n-
    731 {
    \n-
    732 return aggregates_+noVertices();
    \n-
    733 }
    \n-
    734
    \n-\n-
    736
    \n-\n+
    725 newsp.completeSparsityPattern(newsp_copy.sparsity);
    \n+
    726 newsp.storeSparsityPattern(newMatrix);
    \n+
    727 }
    \n+
    728 else
    \n+
    729 newsp.storeSparsityPattern(newMatrix);
    \n+
    730
    \n+
    731#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    732 // Check for symmetry
    \n+
    733 int ret=0;
    \n+
    734 typedef typename M::ConstRowIterator RIter;
    \n+
    735 for(RIter row=newMatrix.begin(), rend=newMatrix.end(); row != rend; ++row) {
    \n+
    736 typedef typename M::ConstColIterator CIter;
    \n+
    737 for(CIter col=row->begin(), cend=row->end(); col!=cend; ++col)
    \n
    738 {
    \n-
    739 return aggregates_;
    \n-
    740 }
    \n-
    741
    \n-\n-
    743 {
    \n-
    744 return aggregates_+noVertices();
    \n-
    745 }
    \n-
    746 private:
    \n-
    748 AggregatesMap(const AggregatesMap<V>&) = delete;
    \n-
    750 AggregatesMap<V>& operator=(const AggregatesMap<V>&) = delete;
    \n-
    751
    \n-
    755 AggregateDescriptor* aggregates_;
    \n-
    756
    \n-
    760 std::size_t noVertices_;
    \n-
    761 };
    \n-
    762
    \n-
    766 template<class G, class C>
    \n-
    767 void buildDependency(G& graph,
    \n-
    768 const typename C::Matrix& matrix,
    \n-
    769 C criterion,
    \n-
    770 bool finestLevel);
    \n-
    771
    \n-
    776 template<class G, class S>
    \n-\n-
    778 {
    \n-
    779
    \n-
    780 public:
    \n-
    781
    \n-
    782 /***
    \n-
    783 * @brief The type of the matrix graph we work with.
    \n-
    784 */
    \n-
    785 typedef G MatrixGraph;
    \n-\n-
    790
    \n-
    795 typedef PoolAllocator<Vertex,100> Allocator;
    \n-
    796
    \n-
    801 typedef S VertexSet;
    \n+
    739 try{
    \n+
    740 newMatrix[col.index()][row.index()];
    \n+
    741 }catch(const Dune::ISTLError&) {
    \n+
    742 std::cerr<<newComm.communicator().rank()<<": entry ("
    \n+
    743 <<col.index()<<","<<row.index()<<") missing! for symmetry!"<<std::endl;
    \n+
    744 ret=1;
    \n+
    745
    \n+
    746 }
    \n+
    747
    \n+
    748 }
    \n+
    749 }
    \n+
    750
    \n+
    751 if(ret)
    \n+
    752 DUNE_THROW(ISTLError, "Matrix not symmetric!");
    \n+
    753#endif
    \n+
    754 }
    \n+
    755
    \n+
    756 template<typename M, typename C>
    \n+
    757 void redistributeMatrixEntries(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n+\n+
    759 {
    \n+
    760 typedef typename C::ParallelIndexSet IndexSet;
    \n+
    761 typename C::OwnerSet ownerflags;
    \n+
    762 std::vector<typename M::size_type> rowsize(newComm.indexSet().size(), 0);
    \n+
    763 std::vector<typename M::size_type> copyrowsize(newComm.indexSet().size(), 0);
    \n+
    764 std::vector<typename M::size_type> backwardscopyrowsize(origComm.indexSet().size(), 0);
    \n+
    765
    \n+
    766 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {
    \n+
    767 rowsize[i] = ri.getRowSize(i);
    \n+\n+
    769 copyrowsize[i] = ri.getCopyRowSize(i);
    \n+
    770 }
    \n+
    771 }
    \n+
    772
    \n+
    773 for (std::size_t i=0; i < origComm.indexSet().size(); i++)
    \n+\n+
    775 backwardscopyrowsize[i] = ri.getBackwardsCopyRowSize(i);
    \n+
    776
    \n+
    777
    \n+\n+
    779 // fill sparsity pattern from copy rows
    \n+
    780 CommMatrixRow<M,IndexSet> origrow_copy(origMatrix, origComm.globalLookup(),
    \n+
    781 newComm.indexSet(), backwardscopyrowsize);
    \n+
    782 CommMatrixRow<M,IndexSet> newrow_copy(newMatrix, origComm.globalLookup(),
    \n+
    783 newComm.indexSet(),copyrowsize);
    \n+
    784 ri.template redistribute<MatrixRowGatherScatter<M,IndexSet> >(origrow_copy,
    \n+
    785 newrow_copy);
    \n+
    786 ri.getInterface().free();
    \n+
    787 RemoteIndices<IndexSet> *ris = new RemoteIndices<IndexSet>(origComm.indexSet(),
    \n+
    788 newComm.indexSet(),
    \n+
    789 origComm.communicator());
    \n+
    790 ris->template rebuild<true>();
    \n+
    791 ri.getInterface().build(*ris,ownerflags,ownerflags);
    \n+
    792 }
    \n+
    793
    \n+\n+
    795 origrow(origMatrix, origComm.globalLookup(), newComm.indexSet());
    \n+\n+
    797 newrow(newMatrix, origComm.globalLookup(), newComm.indexSet(),rowsize);
    \n+
    798 ri.template redistribute<MatrixRowGatherScatter<M,IndexSet> >(origrow,newrow);
    \n+
    799 if (SolverCategory::category(origComm) != static_cast<int>(SolverCategory::nonoverlapping))
    \n+\n+
    801 }
    \n
    802
    \n-
    804 typedef typename VertexSet::const_iterator const_iterator;
    \n-
    805
    \n-
    809 typedef std::size_t* SphereMap;
    \n-
    810
    \n-\n-
    820 VertexSet& connectivity, std::vector<Vertex>& front_);
    \n-
    821
    \n-\n-
    823 {
    \n-
    824 --id_;
    \n-
    825 }
    \n-
    826
    \n-
    833 void reconstruct(const Vertex& vertex);
    \n-
    834
    \n-
    838 void seed(const Vertex& vertex);
    \n-
    839
    \n-
    843 void add(const Vertex& vertex);
    \n-
    844
    \n-
    845 void add(std::vector<Vertex>& vertex);
    \n-
    849 void clear();
    \n-
    850
    \n-
    854 typename VertexSet::size_type size();
    \n-
    858 typename VertexSet::size_type connectSize();
    \n-
    859
    \n-
    863 int id();
    \n-
    864
    \n-\n-
    867
    \n-\n-
    870
    \n-
    871 private:
    \n-
    875 VertexSet vertices_;
    \n-
    876
    \n-
    881 int id_;
    \n-
    882
    \n-
    886 MatrixGraph& graph_;
    \n-
    887
    \n-
    891 AggregatesMap<Vertex>& aggregates_;
    \n-
    892
    \n-
    896 VertexSet& connected_;
    \n-
    897
    \n-
    901 std::vector<Vertex>& front_;
    \n-
    902 };
    \n-
    903
    \n-
    907 template<class G>
    \n-\n-
    909 {
    \n-
    910 public:
    \n-
    911
    \n-
    915 typedef G MatrixGraph;
    \n-
    916
    \n-\n-
    921
    \n-\n-
    924
    \n-\n-
    929
    \n-\n-
    934
    \n-
    951 template<class M, class C>
    \n-
    952 std::tuple<int,int,int,int> build(const M& m, G& graph,
    \n-
    953 AggregatesMap<Vertex>& aggregates, const C& c,
    \n-
    954 bool finestLevel);
    \n-
    955 private:
    \n-
    960 typedef PoolAllocator<Vertex,100> Allocator;
    \n-
    961
    \n-
    965 typedef SLList<Vertex,Allocator> VertexList;
    \n-
    966
    \n-
    970 typedef std::set<Vertex,std::less<Vertex>,Allocator> VertexSet;
    \n-
    971
    \n-
    975 typedef std::size_t* SphereMap;
    \n-
    976
    \n-
    980 MatrixGraph* graph_;
    \n-
    981
    \n-\n-
    986
    \n-
    990 std::vector<Vertex> front_;
    \n-
    991
    \n-
    995 VertexSet connected_;
    \n-
    996
    \n-
    1000 int size_;
    \n-
    1001
    \n-
    1005 class Stack
    \n-
    1006 {
    \n-
    1007 public:
    \n-
    1008 static const Vertex NullEntry;
    \n-
    1009
    \n-
    1010 Stack(const MatrixGraph& graph,
    \n-
    1011 const Aggregator<G>& aggregatesBuilder,
    \n-
    1012 const AggregatesMap<Vertex>& aggregates);
    \n-\n-\n-
    1015 private:
    \n-
    1016 enum { N = 1300000 };
    \n-
    1017
    \n-
    1019 const MatrixGraph& graph_;
    \n-
    1021 const Aggregator<G>& aggregatesBuilder_;
    \n-
    1023 const AggregatesMap<Vertex>& aggregates_;
    \n-
    1025 int size_;
    \n-
    1026 Vertex maxSize_;
    \n-
    1028 typename MatrixGraph::ConstVertexIterator begin_;
    \n-\n-
    1030
    \n-
    1032 Vertex* vals_;
    \n-
    1033
    \n-
    1034 };
    \n-
    1035
    \n-
    1036 friend class Stack;
    \n-
    1037
    \n-
    1048 template<class V>
    \n-
    1049 void visitAggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n-
    1050 const AggregatesMap<Vertex>& aggregates,
    \n-
    1051 V& visitor) const;
    \n-
    1052
    \n-
    1057 template<class V>
    \n-
    1058 class AggregateVisitor
    \n-
    1059 {
    \n-
    1060 public:
    \n-
    1064 typedef V Visitor;
    \n-\n-
    1073 Visitor& visitor);
    \n-
    1074
    \n-
    1081 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1082
    \n-
    1083 private:
    \n-
    1085 const AggregatesMap<Vertex>& aggregates_;
    \n-
    1087 AggregateDescriptor aggregate_;
    \n-
    1089 Visitor* visitor_;
    \n-
    1090 };
    \n-
    1091
    \n-
    1095 class Counter
    \n-
    1096 {
    \n-
    1097 public:
    \n-\n-
    1101 int value();
    \n-
    1102
    \n-
    1103 protected:
    \n-\n-\n-
    1108
    \n-
    1109 private:
    \n-
    1110 int count_;
    \n-
    1111 };
    \n-
    1112
    \n-
    1113
    \n-
    1118 class FrontNeighbourCounter : public Counter
    \n-
    1119 {
    \n-
    1120 public:
    \n-\n-
    1126
    \n-
    1127 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1128
    \n-
    1129 private:
    \n-
    1130 const MatrixGraph& graph_;
    \n-
    1131 };
    \n-
    1132
    \n-
    1137 int noFrontNeighbours(const Vertex& vertex) const;
    \n-
    1138
    \n-
    1142 class TwoWayCounter : public Counter
    \n-
    1143 {
    \n-
    1144 public:
    \n-
    1145 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1146 };
    \n-
    1147
    \n-
    1159 int twoWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
    \n-
    1160 const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1161
    \n-
    1165 class OneWayCounter : public Counter
    \n-
    1166 {
    \n-
    1167 public:
    \n-
    1168 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1169 };
    \n-
    1170
    \n-
    1182 int oneWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
    \n-
    1183 const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1184
    \n-
    1191 class ConnectivityCounter : public Counter
    \n-
    1192 {
    \n-
    1193 public:
    \n-
    1200 ConnectivityCounter(const VertexSet& connected, const AggregatesMap<Vertex>& aggregates);
    \n-
    1201
    \n-
    1202 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1203
    \n-
    1204 private:
    \n-
    1206 const VertexSet& connected_;
    \n-
    1208 const AggregatesMap<Vertex>& aggregates_;
    \n-
    1209
    \n-
    1210 };
    \n-
    1211
    \n-
    1223 double connectivity(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1231 bool connected(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n-
    1232 const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1233
    \n-
    1241 bool connected(const Vertex& vertex, const SLList<AggregateDescriptor>& aggregateList,
    \n-
    1242 const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1243
    \n-
    1251 class DependencyCounter : public Counter
    \n-
    1252 {
    \n-
    1253 public:
    \n-\n-
    1258
    \n-
    1259 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1260 };
    \n-
    1261
    \n-
    1268 class FrontMarker
    \n-
    1269 {
    \n-
    1270 public:
    \n-
    1277 FrontMarker(std::vector<Vertex>& front, MatrixGraph& graph);
    \n-
    1278
    \n-
    1279 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n-
    1280
    \n-
    1281 private:
    \n-
    1283 std::vector<Vertex>& front_;
    \n-
    1285 MatrixGraph& graph_;
    \n-
    1286 };
    \n-
    1287
    \n-
    1291 void unmarkFront();
    \n-
    1292
    \n-
    1307 int unusedNeighbours(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1308
    \n-
    1322 std::pair<int,int> neighbours(const Vertex& vertex,
    \n-
    1323 const AggregateDescriptor& aggregate,
    \n-
    1324 const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1341 int aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1342
    \n-
    1350 bool admissible(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1351
    \n-
    1359 std::size_t distance(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates);
    \n-
    1360
    \n-
    1369 Vertex mergeNeighbour(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n-
    1370
    \n-
    1379 void nonisoNeighbourAggregate(const Vertex& vertex,
    \n-
    1380 const AggregatesMap<Vertex>& aggregates,
    \n-
    1381 SLList<Vertex>& neighbours) const;
    \n-
    1382
    \n-
    1390 template<class C>
    \n-
    1391 void growAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
    \n-
    1392 template<class C>
    \n-
    1393 void growIsolatedAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
    \n-
    1394 };
    \n-
    1395
    \n-
    1396#ifndef DOXYGEN
    \n-
    1397
    \n-
    1398 template<class M, class N>
    \n-
    1399 inline void SymmetricDependency<M,N>::init(const Matrix* matrix)
    \n-
    1400 {
    \n-
    1401 matrix_ = matrix;
    \n-
    1402 }
    \n-
    1403
    \n-
    1404 template<class M, class N>
    \n-
    1405 inline void SymmetricDependency<M,N>::initRow(const Row& row, int index)
    \n-
    1406 {
    \n-
    1407 initRow(row, index, std::is_convertible<field_type, real_type>());
    \n-
    1408 }
    \n-
    1409
    \n-
    1410 template<class M, class N>
    \n-
    1411 inline void SymmetricDependency<M,N>::initRow(const Row& row, int index, const std::false_type&)
    \n-
    1412 {
    \n-
    1413 DUNE_THROW(InvalidStateException, "field_type needs to convertible to real_type");
    \n-
    1414 }
    \n-
    1415
    \n-
    1416 template<class M, class N>
    \n-
    1417 inline void SymmetricDependency<M,N>::initRow([[maybe_unused]] const Row& row, int index, const std::true_type&)
    \n-
    1418 {
    \n-
    1419 using std::min;
    \n-
    1420 maxValue_ = min(- std::numeric_limits<typename Matrix::field_type>::max(), std::numeric_limits<typename Matrix::field_type>::min());
    \n-
    1421 row_ = index;
    \n-
    1422 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
    \n-
    1423 }
    \n-
    1424
    \n-
    1425 template<class M, class N>
    \n-
    1426 inline void SymmetricDependency<M,N>::examine(const ColIter& col)
    \n-
    1427 {
    \n-
    1428 using std::max;
    \n-
    1429 real_type eij = norm_(*col);
    \n-
    1430 typename Matrix::ConstColIterator opposite_entry =
    \n-
    1431 matrix_->operator[](col.index()).find(row_);
    \n-
    1432 if ( opposite_entry == matrix_->operator[](col.index()).end() )
    \n-
    1433 {
    \n-
    1434 // Consider this a weak connection we disregard.
    \n-
    1435 return;
    \n-
    1436 }
    \n-
    1437 real_type eji = norm_(*opposite_entry);
    \n-
    1438
    \n-
    1439 // skip positive offdiagonals if norm preserves sign of them.
    \n-
    1440 if(!N::is_sign_preserving || eij<0 || eji<0)
    \n-
    1441 maxValue_ = max(maxValue_,
    \n-
    1442 eij /diagonal_ * eji/
    \n-
    1443 norm_(matrix_->operator[](col.index())[col.index()]));
    \n-
    1444 }
    \n-
    1445
    \n-
    1446 template<class M, class N>
    \n-
    1447 template<class G>
    \n-
    1448 inline void SymmetricDependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
    \n-
    1449 {
    \n-
    1450 real_type eij = norm_(*col);
    \n-
    1451 typename Matrix::ConstColIterator opposite_entry =
    \n-
    1452 matrix_->operator[](col.index()).find(row_);
    \n-
    1453
    \n-
    1454 if ( opposite_entry == matrix_->operator[](col.index()).end() )
    \n-
    1455 {
    \n-
    1456 // Consider this as a weak connection we disregard.
    \n-
    1457 return;
    \n-
    1458 }
    \n-
    1459 real_type eji = norm_(*opposite_entry);
    \n-
    1460 // skip positve offdiagonals if norm preserves sign of them.
    \n-
    1461 if(!N::is_sign_preserving || (eij<0 || eji<0))
    \n-
    1462 if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *
    \n-
    1463 eij/ diagonal_ > alpha() * maxValue_) {
    \n-
    1464 edge.properties().setDepends();
    \n-
    1465 edge.properties().setInfluences();
    \n-
    1466 typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target(), edge.source());
    \n-
    1467 other.setInfluences();
    \n-
    1468 other.setDepends();
    \n-
    1469 }
    \n-
    1470 }
    \n-
    1471
    \n-
    1472 template<class M, class N>
    \n-\n-
    1474 {
    \n-
    1475 return maxValue_ < beta();
    \n-
    1476 }
    \n-
    1477
    \n-
    1478
    \n-
    1479 template<class M, class N>
    \n-
    1480 inline void Dependency<M,N>::init(const Matrix* matrix)
    \n-
    1481 {
    \n-
    1482 matrix_ = matrix;
    \n-
    1483 }
    \n-
    1484
    \n-
    1485 template<class M, class N>
    \n-
    1486 inline void Dependency<M,N>::initRow([[maybe_unused]] const Row& row, int index)
    \n-
    1487 {
    \n-
    1488 using std::min;
    \n-
    1489 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
    \n-
    1490 row_ = index;
    \n-
    1491 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
    \n-
    1492 }
    \n-
    1493
    \n-
    1494 template<class M, class N>
    \n-
    1495 inline void Dependency<M,N>::examine(const ColIter& col)
    \n-
    1496 {
    \n-
    1497 using std::max;
    \n-
    1498 maxValue_ = max(maxValue_, -norm_(*col));
    \n-
    1499 }
    \n-
    1500
    \n-
    1501 template<class M, class N>
    \n-
    1502 template<class G>
    \n-
    1503 inline void Dependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
    \n-
    1504 {
    \n-
    1505 if(-norm_(*col) >= maxValue_ * alpha()) {
    \n-
    1506 edge.properties().setDepends();
    \n-
    1507 typedef typename G::EdgeDescriptor ED;
    \n-
    1508 ED e= graph.findEdge(edge.target(), edge.source());
    \n-
    1509 if(e!=std::numeric_limits<ED>::max())
    \n-
    1510 {
    \n-
    1511 typename G::EdgeProperties& other = graph.getEdgeProperties(e);
    \n-
    1512 other.setInfluences();
    \n-
    1513 }
    \n-
    1514 }
    \n-
    1515 }
    \n-
    1516
    \n-
    1517 template<class M, class N>
    \n-
    1518 inline bool Dependency<M,N>::isIsolated()
    \n-
    1519 {
    \n-
    1520 return maxValue_ < beta() * diagonal_;
    \n-
    1521 }
    \n-
    1522
    \n-
    1523 template<class G,class S>
    \n-
    1524 Aggregate<G,S>::Aggregate(MatrixGraph& graph, AggregatesMap<Vertex>& aggregates,
    \n-
    1525 VertexSet& connected, std::vector<Vertex>& front)
    \n-
    1526 : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),
    \n-
    1527 connected_(connected), front_(front)
    \n-
    1528 {}
    \n-
    1529
    \n-
    1530 template<class G,class S>
    \n-
    1531 void Aggregate<G,S>::reconstruct(const Vertex& vertex)
    \n-
    1532 {
    \n-
    1533 /*
    \n-
    1534 vertices_.push_back(vertex);
    \n-
    1535 typedef typename VertexList::const_iterator iterator;
    \n-
    1536 iterator begin = vertices_.begin();
    \n-
    1537 iterator end = vertices_.end();*/
    \n-
    1538 throw "Not yet implemented";
    \n-
    1539
    \n-
    1540 // while(begin!=end){
    \n-
    1541 //for();
    \n-
    1542 // }
    \n-
    1543
    \n-
    1544 }
    \n-
    1545
    \n-
    1546 template<class G,class S>
    \n-
    1547 inline void Aggregate<G,S>::seed(const Vertex& vertex)
    \n-
    1548 {
    \n-
    1549 dvverb<<"Connected cleared"<<std::endl;
    \n-
    1550 connected_.clear();
    \n-
    1551 vertices_.clear();
    \n-
    1552 connected_.insert(vertex);
    \n-
    1553 dvverb << " Inserting "<<vertex<<" size="<<connected_.size();
    \n-
    1554 ++id_ ;
    \n-
    1555 add(vertex);
    \n-
    1556 }
    \n-
    1557
    \n-
    1558
    \n-
    1559 template<class G,class S>
    \n-
    1560 inline void Aggregate<G,S>::add(const Vertex& vertex)
    \n-
    1561 {
    \n-
    1562 vertices_.insert(vertex);
    \n-
    1563 aggregates_[vertex]=id_;
    \n-
    1564 if(front_.size())
    \n-
    1565 front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));
    \n-
    1566
    \n-
    1567
    \n-
    1568 typedef typename MatrixGraph::ConstEdgeIterator iterator;
    \n-
    1569 const iterator end = graph_.endEdges(vertex);
    \n-
    1570 for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {
    \n-
    1571 dvverb << " Inserting "<<aggregates_[edge.target()];
    \n-
    1572 connected_.insert(aggregates_[edge.target()]);
    \n-
    1573 dvverb <<" size="<<connected_.size();
    \n-
    1574 if(aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED &&
    \n-
    1575 !graph_.getVertexProperties(edge.target()).front())
    \n-
    1576 {
    \n-
    1577 front_.push_back(edge.target());
    \n-
    1578 graph_.getVertexProperties(edge.target()).setFront();
    \n-
    1579 }
    \n-
    1580 }
    \n-
    1581 dvverb <<std::endl;
    \n-
    1582 std::sort(front_.begin(), front_.end());
    \n-
    1583 }
    \n-
    1584
    \n-
    1585 template<class G,class S>
    \n-
    1586 inline void Aggregate<G,S>::add(std::vector<Vertex>& vertices)
    \n-
    1587 {
    \n-
    1588#ifndef NDEBUG
    \n-
    1589 std::size_t oldsize = vertices_.size();
    \n-
    1590#endif
    \n-
    1591 typedef typename std::vector<Vertex>::iterator Iterator;
    \n-
    1592
    \n-
    1593 typedef typename VertexSet::iterator SIterator;
    \n-
    1594
    \n-
    1595 SIterator pos=vertices_.begin();
    \n-
    1596 std::vector<Vertex> newFront;
    \n-
    1597 newFront.reserve(front_.capacity());
    \n-
    1598
    \n-
    1599 std::set_difference(front_.begin(), front_.end(), vertices.begin(), vertices.end(),
    \n-
    1600 std::back_inserter(newFront));
    \n-
    1601 front_=newFront;
    \n-
    1602
    \n-
    1603 for(Iterator vertex=vertices.begin(); vertex != vertices.end(); ++vertex)
    \n-
    1604 {
    \n-
    1605 pos=vertices_.insert(pos,*vertex);
    \n-
    1606 vertices_.insert(*vertex);
    \n-
    1607 graph_.getVertexProperties(*vertex).resetFront(); // Not a front node any more.
    \n-
    1608 aggregates_[*vertex]=id_;
    \n-
    1609
    \n-
    1610 typedef typename MatrixGraph::ConstEdgeIterator iterator;
    \n-
    1611 const iterator end = graph_.endEdges(*vertex);
    \n-
    1612 for(iterator edge = graph_.beginEdges(*vertex); edge != end; ++edge) {
    \n-
    1613 dvverb << " Inserting "<<aggregates_[edge.target()];
    \n-
    1614 connected_.insert(aggregates_[edge.target()]);
    \n-
    1615 if(aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED &&
    \n-
    1616 !graph_.getVertexProperties(edge.target()).front())
    \n-
    1617 {
    \n-
    1618 front_.push_back(edge.target());
    \n-
    1619 graph_.getVertexProperties(edge.target()).setFront();
    \n-
    1620 }
    \n-
    1621 dvverb <<" size="<<connected_.size();
    \n-
    1622 }
    \n-
    1623 dvverb <<std::endl;
    \n-
    1624 }
    \n-
    1625 std::sort(front_.begin(), front_.end());
    \n-
    1626 assert(oldsize+vertices.size()==vertices_.size());
    \n-
    1627 }
    \n-
    1628 template<class G,class S>
    \n-
    1629 inline void Aggregate<G,S>::clear()
    \n-
    1630 {
    \n-
    1631 vertices_.clear();
    \n-
    1632 connected_.clear();
    \n-
    1633 id_=-1;
    \n-
    1634 }
    \n-
    1635
    \n-
    1636 template<class G,class S>
    \n-
    1637 inline typename Aggregate<G,S>::VertexSet::size_type
    \n-\n-
    1639 {
    \n-
    1640 return vertices_.size();
    \n-
    1641 }
    \n-
    1642
    \n-
    1643 template<class G,class S>
    \n-
    1644 inline typename Aggregate<G,S>::VertexSet::size_type
    \n-\n-
    1646 {
    \n-
    1647 return connected_.size();
    \n-
    1648 }
    \n-
    1649
    \n-
    1650 template<class G,class S>
    \n-
    1651 inline int Aggregate<G,S>::id()
    \n-
    1652 {
    \n-
    1653 return id_;
    \n-
    1654 }
    \n-
    1655
    \n-
    1656 template<class G,class S>
    \n-\n-
    1658 {
    \n-
    1659 return vertices_.begin();
    \n-
    1660 }
    \n-
    1661
    \n-
    1662 template<class G,class S>
    \n-\n-
    1664 {
    \n-
    1665 return vertices_.end();
    \n-
    1666 }
    \n-
    1667
    \n-
    1668 template<class V>
    \n-
    1669 const V AggregatesMap<V>::UNAGGREGATED = std::numeric_limits<V>::max();
    \n-
    1670
    \n-
    1671 template<class V>
    \n-
    1672 const V AggregatesMap<V>::ISOLATED = std::numeric_limits<V>::max()-1;
    \n-
    1673
    \n-
    1674 template<class V>
    \n-\n-
    1676 : aggregates_(0)
    \n-
    1677 {}
    \n-
    1678
    \n-
    1679 template<class V>
    \n-\n-
    1681 {
    \n-
    1682 if(aggregates_!=0)
    \n-
    1683 delete[] aggregates_;
    \n-
    1684 }
    \n-
    1685
    \n-
    1686
    \n-
    1687 template<class V>
    \n-
    1688 inline AggregatesMap<V>::AggregatesMap(std::size_t noVertices)
    \n-
    1689 {
    \n-
    1690 allocate(noVertices);
    \n-
    1691 }
    \n-
    1692
    \n-
    1693 template<class V>
    \n-
    1694 inline std::size_t AggregatesMap<V>::noVertices() const
    \n-
    1695 {
    \n-
    1696 return noVertices_;
    \n-
    1697 }
    \n-
    1698
    \n-
    1699 template<class V>
    \n-
    1700 inline void AggregatesMap<V>::allocate(std::size_t noVertices)
    \n-
    1701 {
    \n-
    1702 aggregates_ = new AggregateDescriptor[noVertices];
    \n-
    1703 noVertices_ = noVertices;
    \n-
    1704
    \n-
    1705 for(std::size_t i=0; i < noVertices; i++)
    \n-
    1706 aggregates_[i]=UNAGGREGATED;
    \n-
    1707 }
    \n-
    1708
    \n-
    1709 template<class V>
    \n-
    1710 inline void AggregatesMap<V>::free()
    \n-
    1711 {
    \n-
    1712 assert(aggregates_ != 0);
    \n-
    1713 delete[] aggregates_;
    \n-
    1714 aggregates_=0;
    \n-
    1715 }
    \n-
    1716
    \n-
    1717 template<class V>
    \n-\n-
    1719 AggregatesMap<V>::operator[](const VertexDescriptor& v)
    \n-
    1720 {
    \n-
    1721 return aggregates_[v];
    \n-
    1722 }
    \n-
    1723
    \n-
    1724 template<class V>
    \n-
    1725 inline const typename AggregatesMap<V>::AggregateDescriptor&
    \n-
    1726 AggregatesMap<V>::operator[](const VertexDescriptor& v) const
    \n-
    1727 {
    \n-
    1728 return aggregates_[v];
    \n-
    1729 }
    \n-
    1730
    \n-
    1731 template<class V>
    \n-
    1732 template<bool reset, class G, class F,class VM>
    \n-
    1733 inline std::size_t AggregatesMap<V>::breadthFirstSearch(const V& start,
    \n-
    1734 const AggregateDescriptor& aggregate,
    \n-
    1735 const G& graph, F& aggregateVisitor,
    \n-
    1736 VM& visitedMap) const
    \n-
    1737 {
    \n-
    1738 VertexList vlist;
    \n-
    1739
    \n-
    1740 DummyEdgeVisitor dummy;
    \n-
    1741 return breadthFirstSearch<true,reset>(start, aggregate, graph, vlist, aggregateVisitor, dummy, visitedMap);
    \n-
    1742 }
    \n-
    1743
    \n-
    1744 template<class V>
    \n-
    1745 template<bool remove, bool reset, class G, class L, class F1, class F2, class VM>
    \n-
    1746 std::size_t AggregatesMap<V>::breadthFirstSearch(const V& start,
    \n-
    1747 const AggregateDescriptor& aggregate,
    \n-
    1748 const G& graph,
    \n-
    1749 L& visited,
    \n-
    1750 F1& aggregateVisitor,
    \n-
    1751 F2& nonAggregateVisitor,
    \n-
    1752 VM& visitedMap) const
    \n-
    1753 {
    \n-
    1754 typedef typename L::const_iterator ListIterator;
    \n-
    1755 int visitedSpheres = 0;
    \n-
    1756
    \n-
    1757 visited.push_back(start);
    \n-
    1758 put(visitedMap, start, true);
    \n-
    1759
    \n-
    1760 ListIterator current = visited.begin();
    \n-
    1761 ListIterator end = visited.end();
    \n-
    1762 std::size_t i=0, size=visited.size();
    \n-
    1763
    \n-
    1764 // visit the neighbours of all vertices of the
    \n-
    1765 // current sphere.
    \n-
    1766 while(current != end) {
    \n-
    1767
    \n-
    1768 for(; i<size; ++current, ++i) {
    \n-
    1769 typedef typename G::ConstEdgeIterator EdgeIterator;
    \n-
    1770 const EdgeIterator endEdge = graph.endEdges(*current);
    \n-
    1771
    \n-
    1772 for(EdgeIterator edge = graph.beginEdges(*current);
    \n-
    1773 edge != endEdge; ++edge) {
    \n-
    1774
    \n-
    1775 if(aggregates_[edge.target()]==aggregate) {
    \n-
    1776 if(!get(visitedMap, edge.target())) {
    \n-
    1777 put(visitedMap, edge.target(), true);
    \n-
    1778 visited.push_back(edge.target());
    \n-
    1779 aggregateVisitor(edge);
    \n-
    1780 }
    \n-
    1781 }else
    \n-
    1782 nonAggregateVisitor(edge);
    \n-
    1783 }
    \n-
    1784 }
    \n-
    1785 end = visited.end();
    \n-
    1786 size = visited.size();
    \n-
    1787 if(current != end)
    \n-
    1788 visitedSpheres++;
    \n-
    1789 }
    \n-
    1790
    \n-
    1791 if(reset)
    \n-
    1792 for(current = visited.begin(); current != end; ++current)
    \n-
    1793 put(visitedMap, *current, false);
    \n-
    1794
    \n-
    1795
    \n-
    1796 if(remove)
    \n-
    1797 visited.clear();
    \n-
    1798
    \n-
    1799 return visitedSpheres;
    \n-
    1800 }
    \n-
    1801
    \n-
    1802 template<class G>
    \n-\n-
    1804 : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)
    \n-
    1805 {}
    \n-
    1806
    \n-
    1807 template<class G>
    \n-\n-
    1809 {
    \n-
    1810 size_=-1;
    \n-
    1811 }
    \n-
    1812
    \n-
    1813 template<class G, class C>
    \n-
    1814 void buildDependency(G& graph,
    \n-
    1815 const typename C::Matrix& matrix,
    \n-
    1816 C criterion, bool firstlevel)
    \n-
    1817 {
    \n-
    1818 // assert(graph.isBuilt());
    \n-
    1819 typedef typename C::Matrix Matrix;
    \n-
    1820 typedef typename G::VertexIterator VertexIterator;
    \n-
    1821
    \n-
    1822 criterion.init(&matrix);
    \n-
    1823
    \n-
    1824 for(VertexIterator vertex = graph.begin(); vertex != graph.end(); ++vertex) {
    \n-
    1825 typedef typename Matrix::row_type Row;
    \n-
    1826
    \n-
    1827 const Row& row = matrix[*vertex];
    \n-
    1828
    \n-
    1829 // Tell the criterion what row we will examine now
    \n-
    1830 // This might for example be used for calculating the
    \n-
    1831 // maximum offdiagonal value
    \n-
    1832 criterion.initRow(row, *vertex);
    \n-
    1833
    \n-
    1834 // On a first path all columns are examined. After this
    \n-
    1835 // the calculator should know whether the vertex is isolated.
    \n-
    1836 typedef typename Matrix::ConstColIterator ColIterator;
    \n-
    1837 ColIterator end = row.end();
    \n-
    1838 typename FieldTraits<typename Matrix::field_type>::real_type absoffdiag=0.;
    \n-
    1839
    \n-
    1840 using std::max;
    \n-
    1841 if(firstlevel) {
    \n-
    1842 for(ColIterator col = row.begin(); col != end; ++col)
    \n-
    1843 if(col.index()!=*vertex) {
    \n-
    1844 criterion.examine(col);
    \n-
    1845 absoffdiag = max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());
    \n-
    1846 }
    \n-
    1847
    \n-
    1848 if(absoffdiag==0)
    \n-
    1849 vertex.properties().setExcludedBorder();
    \n-
    1850 }
    \n-
    1851 else
    \n-
    1852 for(ColIterator col = row.begin(); col != end; ++col)
    \n-
    1853 if(col.index()!=*vertex)
    \n-
    1854 criterion.examine(col);
    \n-
    1855
    \n-
    1856 // reset the vertex properties
    \n-
    1857 //vertex.properties().reset();
    \n-
    1858
    \n-
    1859 // Check whether the vertex is isolated.
    \n-
    1860 if(criterion.isIsolated()) {
    \n-
    1861 //std::cout<<"ISOLATED: "<<*vertex<<std::endl;
    \n-
    1862 vertex.properties().setIsolated();
    \n-
    1863 }else{
    \n-
    1864 // Examine all the edges beginning at this vertex.
    \n-
    1865 auto eEnd = vertex.end();
    \n-
    1866 auto col = matrix[*vertex].begin();
    \n-
    1867
    \n-
    1868 for(auto edge = vertex.begin(); edge!= eEnd; ++edge, ++col) {
    \n-
    1869 // Move to the right column.
    \n-
    1870 while(col.index()!=edge.target())
    \n-
    1871 ++col;
    \n-
    1872 criterion.examine(graph, edge, col);
    \n-
    1873 }
    \n-
    1874 }
    \n-
    1875
    \n-
    1876 }
    \n-
    1877 }
    \n-
    1878
    \n-
    1879
    \n-
    1880 template<class G>
    \n-
    1881 template<class V>
    \n-
    1882 inline Aggregator<G>::AggregateVisitor<V>::AggregateVisitor(const AggregatesMap<Vertex>& aggregates,
    \n-
    1883 const AggregateDescriptor& aggregate, V& visitor)
    \n-
    1884 : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)
    \n-
    1885 {}
    \n-
    1886
    \n-
    1887 template<class G>
    \n-
    1888 template<class V>
    \n-
    1889 inline void Aggregator<G>::AggregateVisitor<V>::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    1890 {
    \n-
    1891 if(aggregates_[edge.target()]==aggregate_)
    \n-
    1892 visitor_->operator()(edge);
    \n-
    1893 }
    \n-
    1894
    \n-
    1895 template<class G>
    \n-
    1896 template<class V>
    \n-
    1897 inline void Aggregator<G>::visitAggregateNeighbours(const Vertex& vertex,
    \n-
    1898 const AggregateDescriptor& aggregate,
    \n-
    1899 const AggregatesMap<Vertex>& aggregates,
    \n-
    1900 V& visitor) const
    \n-
    1901 {
    \n-
    1902 // Only evaluates for edge pointing to the aggregate
    \n-
    1903 AggregateVisitor<V> v(aggregates, aggregate, visitor);
    \n-
    1904 visitNeighbours(*graph_, vertex, v);
    \n-
    1905 }
    \n-
    1906
    \n-
    1907
    \n-
    1908 template<class G>
    \n-
    1909 inline Aggregator<G>::Counter::Counter()
    \n-
    1910 : count_(0)
    \n-
    1911 {}
    \n-
    1912
    \n-
    1913 template<class G>
    \n-
    1914 inline void Aggregator<G>::Counter::increment()
    \n-
    1915 {
    \n-
    1916 ++count_;
    \n-
    1917 }
    \n-
    1918
    \n-
    1919 template<class G>
    \n-
    1920 inline void Aggregator<G>::Counter::decrement()
    \n-
    1921 {
    \n-
    1922 --count_;
    \n-
    1923 }
    \n-
    1924 template<class G>
    \n-
    1925 inline int Aggregator<G>::Counter::value()
    \n-
    1926 {
    \n-
    1927 return count_;
    \n-
    1928 }
    \n-
    1929
    \n-
    1930 template<class G>
    \n-
    1931 inline void Aggregator<G>::TwoWayCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    1932 {
    \n-
    1933 if(edge.properties().isTwoWay())
    \n-
    1934 Counter::increment();
    \n-
    1935 }
    \n-
    1936
    \n-
    1937 template<class G>
    \n-
    1938 int Aggregator<G>::twoWayConnections(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n-
    1939 const AggregatesMap<Vertex>& aggregates) const
    \n-
    1940 {
    \n-
    1941 TwoWayCounter counter;
    \n-
    1942 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n-
    1943 return counter.value();
    \n-
    1944 }
    \n-
    1945
    \n-
    1946 template<class G>
    \n-
    1947 int Aggregator<G>::oneWayConnections(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n-
    1948 const AggregatesMap<Vertex>& aggregates) const
    \n-
    1949 {
    \n-
    1950 OneWayCounter counter;
    \n-
    1951 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n-
    1952 return counter.value();
    \n-
    1953 }
    \n-
    1954
    \n-
    1955 template<class G>
    \n-
    1956 inline void Aggregator<G>::OneWayCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    1957 {
    \n-
    1958 if(edge.properties().isOneWay())
    \n-
    1959 Counter::increment();
    \n-
    1960 }
    \n-
    1961
    \n-
    1962 template<class G>
    \n-
    1963 inline Aggregator<G>::ConnectivityCounter::ConnectivityCounter(const VertexSet& connected,
    \n-
    1964 const AggregatesMap<Vertex>& aggregates)
    \n-
    1965 : Counter(), connected_(connected), aggregates_(aggregates)
    \n-
    1966 {}
    \n-
    1967
    \n-
    1968
    \n-
    1969 template<class G>
    \n-
    1970 inline void Aggregator<G>::ConnectivityCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    1971 {
    \n-
    1972 if(connected_.find(aggregates_[edge.target()]) == connected_.end() || aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED)
    \n-
    1973 // Would be a new connection
    \n-
    1974 Counter::increment();
    \n-
    1975 else{
    \n-
    1976 Counter::increment();
    \n-
    1977 Counter::increment();
    \n-
    1978 }
    \n-
    1979 }
    \n-
    1980
    \n-
    1981 template<class G>
    \n-
    1982 inline double Aggregator<G>::connectivity(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n-
    1983 {
    \n-
    1984 ConnectivityCounter counter(connected_, aggregates);
    \n-
    1985 double noNeighbours=visitNeighbours(*graph_, vertex, counter);
    \n-
    1986 return (double)counter.value()/noNeighbours;
    \n-
    1987 }
    \n-
    1988
    \n-
    1989 template<class G>
    \n-
    1990 inline Aggregator<G>::DependencyCounter::DependencyCounter()
    \n-
    1991 : Counter()
    \n-
    1992 {}
    \n-
    1993
    \n-
    1994 template<class G>
    \n-
    1995 inline void Aggregator<G>::DependencyCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    1996 {
    \n-
    1997 if(edge.properties().depends())
    \n-
    1998 Counter::increment();
    \n-
    1999 if(edge.properties().influences())
    \n-
    2000 Counter::increment();
    \n-
    2001 }
    \n-
    2002
    \n-
    2003 template<class G>
    \n-
    2004 int Aggregator<G>::unusedNeighbours(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n-
    2005 {
    \n-
    2006 return aggregateNeighbours(vertex, AggregatesMap<Vertex>::UNAGGREGATED, aggregates);
    \n-
    2007 }
    \n-
    2008
    \n-
    2009 template<class G>
    \n-
    2010 std::pair<int,int> Aggregator<G>::neighbours(const Vertex& vertex,
    \n-
    2011 const AggregateDescriptor& aggregate,
    \n-
    2012 const AggregatesMap<Vertex>& aggregates) const
    \n-
    2013 {
    \n-
    2014 DependencyCounter unused, aggregated;
    \n-
    2015 typedef AggregateVisitor<DependencyCounter> CounterT;
    \n-
    2016 typedef std::tuple<CounterT,CounterT> CounterTuple;
    \n-
    2017 CombinedFunctor<CounterTuple> visitors(CounterTuple(CounterT(aggregates, AggregatesMap<Vertex>::UNAGGREGATED, unused), CounterT(aggregates, aggregate, aggregated)));
    \n-
    2018 visitNeighbours(*graph_, vertex, visitors);
    \n-
    2019 return std::make_pair(unused.value(), aggregated.value());
    \n-
    2020 }
    \n-
    2021
    \n-
    2022
    \n-
    2023 template<class G>
    \n-
    2024 int Aggregator<G>::aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const
    \n-
    2025 {
    \n-
    2026 DependencyCounter counter;
    \n-
    2027 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n-
    2028 return counter.value();
    \n-
    2029 }
    \n-
    2030
    \n-
    2031 template<class G>
    \n-
    2032 std::size_t Aggregator<G>::distance(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates)
    \n-
    2033 {
    \n-
    2034 return 0;
    \n-
    2035 typename PropertyMapTypeSelector<VertexVisitedTag,G>::Type visitedMap = get(VertexVisitedTag(), *graph_);
    \n-
    2036 VertexList vlist;
    \n-
    2037 typename AggregatesMap<Vertex>::DummyEdgeVisitor dummy;
    \n-
    2038 return aggregates.template breadthFirstSearch<true,true>(vertex,
    \n-
    2039 aggregate_->id(), *graph_,
    \n-
    2040 vlist, dummy, dummy, visitedMap);
    \n-
    2041 }
    \n-
    2042
    \n-
    2043 template<class G>
    \n-
    2044 inline Aggregator<G>::FrontMarker::FrontMarker(std::vector<Vertex>& front, MatrixGraph& graph)
    \n-
    2045 : front_(front), graph_(graph)
    \n-
    2046 {}
    \n-
    2047
    \n-
    2048 template<class G>
    \n-
    2049 inline void Aggregator<G>::FrontMarker::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    2050 {
    \n-
    2051 Vertex target = edge.target();
    \n-
    2052
    \n-
    2053 if(!graph_.getVertexProperties(target).front()) {
    \n-
    2054 front_.push_back(target);
    \n-
    2055 graph_.getVertexProperties(target).setFront();
    \n-
    2056 }
    \n-
    2057 }
    \n-
    2058
    \n-
    2059 template<class G>
    \n-
    2060 inline bool Aggregator<G>::admissible(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const
    \n-
    2061 {
    \n-
    2062 // Todo
    \n-
    2063 Dune::dvverb<<" Admissible not yet implemented!"<<std::endl;
    \n-
    2064 return true;
    \n-
    2065 //Situation 1: front node depends on two nodes. Then these
    \n-
    2066 // have to be strongly connected to each other
    \n-
    2067
    \n-
    2068 // Iterate over all all neighbours of front node
    \n-
    2069 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n-
    2070 Iterator vend = graph_->endEdges(vertex);
    \n-
    2071 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
    \n-
    2072 // if(edge.properties().depends() && !edge.properties().influences()
    \n-
    2073 if(edge.properties().isStrong()
    \n-
    2074 && aggregates[edge.target()]==aggregate)
    \n-
    2075 {
    \n-
    2076 // Search for another link to the aggregate
    \n-
    2077 Iterator edge1 = edge;
    \n-
    2078 for(++edge1; edge1 != vend; ++edge1) {
    \n-
    2079 //if(edge1.properties().depends() && !edge1.properties().influences()
    \n-
    2080 if(edge1.properties().isStrong()
    \n-
    2081 && aggregates[edge.target()]==aggregate)
    \n-
    2082 {
    \n-
    2083 //Search for an edge connecting the two vertices that is
    \n-
    2084 //strong
    \n-
    2085 bool found=false;
    \n-
    2086 Iterator v2end = graph_->endEdges(edge.target());
    \n-
    2087 for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end; ++edge2) {
    \n-
    2088 if(edge2.target()==edge1.target() &&
    \n-
    2089 edge2.properties().isStrong()) {
    \n-
    2090 found =true;
    \n-
    2091 break;
    \n-
    2092 }
    \n-
    2093 }
    \n-
    2094 if(found)
    \n-
    2095 {
    \n-
    2096 return true;
    \n-
    2097 }
    \n-
    2098 }
    \n-
    2099 }
    \n-
    2100 }
    \n-
    2101 }
    \n-
    2102
    \n-
    2103 // Situation 2: cluster node depends on front node and other cluster node
    \n-
    2105 vend = graph_->endEdges(vertex);
    \n-
    2106 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
    \n-
    2107 //if(!edge.properties().depends() && edge.properties().influences()
    \n-
    2108 if(edge.properties().isStrong()
    \n-
    2109 && aggregates[edge.target()]==aggregate)
    \n-
    2110 {
    \n-
    2111 // Search for a link from target that stays within the aggregate
    \n-
    2112 Iterator v1end = graph_->endEdges(edge.target());
    \n-
    2113
    \n-
    2114 for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end; ++edge1) {
    \n-
    2115 //if(edge1.properties().depends() && !edge1.properties().influences()
    \n-
    2116 if(edge1.properties().isStrong()
    \n-
    2117 && aggregates[edge1.target()]==aggregate)
    \n-
    2118 {
    \n-
    2119 bool found=false;
    \n-
    2120 // Check if front node is also connected to this one
    \n-
    2121 Iterator v2end = graph_->endEdges(vertex);
    \n-
    2122 for(Iterator edge2 = graph_->beginEdges(vertex); edge2 != v2end; ++edge2) {
    \n-
    2123 if(edge2.target()==edge1.target()) {
    \n-
    2124 if(edge2.properties().isStrong())
    \n-
    2125 found=true;
    \n-
    2126 break;
    \n-
    2127 }
    \n-
    2128 }
    \n-
    2129 if(found)
    \n-
    2130 {
    \n-
    2131 return true;
    \n-
    2132 }
    \n-
    2133 }
    \n-
    2134 }
    \n-
    2135 }
    \n-
    2136 }
    \n-
    2137 return false;
    \n-
    2138 }
    \n-
    2139
    \n-
    2140 template<class G>
    \n-
    2141 void Aggregator<G>::unmarkFront()
    \n-
    2142 {
    \n-
    2143 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n-
    2144
    \n-
    2145 for(Iterator vertex=front_.begin(); vertex != front_.end(); ++vertex)
    \n-
    2146 graph_->getVertexProperties(*vertex).resetFront();
    \n-
    2147
    \n-
    2148 front_.clear();
    \n-
    2149 }
    \n-
    2150
    \n-
    2151 template<class G>
    \n-
    2152 inline void
    \n-
    2153 Aggregator<G>::nonisoNeighbourAggregate(const Vertex& vertex,
    \n-
    2154 const AggregatesMap<Vertex>& aggregates,
    \n-
    2155 SLList<Vertex>& neighbours) const
    \n-
    2156 {
    \n-
    2157 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n-
    2158 Iterator end=graph_->beginEdges(vertex);
    \n-
    2159 neighbours.clear();
    \n-
    2160
    \n-
    2161 for(Iterator edge=graph_->beginEdges(vertex); edge!=end; ++edge)
    \n-
    2162 {
    \n-
    2163 if(aggregates[edge.target()]!=AggregatesMap<Vertex>::UNAGGREGATED && graph_->getVertexProperties(edge.target()).isolated())
    \n-
    2164 neighbours.push_back(aggregates[edge.target()]);
    \n-
    2165 }
    \n-
    2166 }
    \n-
    2167
    \n-
    2168 template<class G>
    \n-
    2169 inline typename G::VertexDescriptor Aggregator<G>::mergeNeighbour(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n-
    2170 {
    \n-
    2171 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n-
    2172
    \n-
    2173 Iterator end = graph_->endEdges(vertex);
    \n-
    2174 for(Iterator edge = graph_->beginEdges(vertex); edge != end; ++edge) {
    \n-
    2175 if(aggregates[edge.target()] != AggregatesMap<Vertex>::UNAGGREGATED &&
    \n-
    2176 graph_->getVertexProperties(edge.target()).isolated() == graph_->getVertexProperties(edge.source()).isolated()) {
    \n-
    2177 if( graph_->getVertexProperties(vertex).isolated() ||
    \n-
    2178 ((edge.properties().depends() || edge.properties().influences())
    \n-
    2179 && admissible(vertex, aggregates[edge.target()], aggregates)))
    \n-
    2180 return edge.target();
    \n-
    2181 }
    \n-
    2182 }
    \n-\n-
    2184 }
    \n-
    2185
    \n-
    2186 template<class G>
    \n-
    2187 Aggregator<G>::FrontNeighbourCounter::FrontNeighbourCounter(const MatrixGraph& graph)
    \n-
    2188 : Counter(), graph_(graph)
    \n-
    2189 {}
    \n-
    2190
    \n-
    2191 template<class G>
    \n-
    2192 void Aggregator<G>::FrontNeighbourCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n-
    2193 {
    \n-
    2194 if(graph_.getVertexProperties(edge.target()).front())
    \n-
    2195 Counter::increment();
    \n-
    2196 }
    \n-
    2197
    \n-
    2198 template<class G>
    \n-
    2199 int Aggregator<G>::noFrontNeighbours(const Vertex& vertex) const
    \n-
    2200 {
    \n-
    2201 FrontNeighbourCounter counter(*graph_);
    \n-
    2202 visitNeighbours(*graph_, vertex, counter);
    \n-
    2203 return counter.value();
    \n-
    2204 }
    \n-
    2205 template<class G>
    \n-
    2206 inline bool Aggregator<G>::connected(const Vertex& vertex,
    \n-
    2207 const AggregateDescriptor& aggregate,
    \n-
    2208 const AggregatesMap<Vertex>& aggregates) const
    \n-
    2209 {
    \n-
    2210 typedef typename G::ConstEdgeIterator iterator;
    \n-
    2211 const iterator end = graph_->endEdges(vertex);
    \n-
    2212 for(iterator edge = graph_->beginEdges(vertex); edge != end; ++edge)
    \n-
    2213 if(aggregates[edge.target()]==aggregate)
    \n-
    2214 return true;
    \n-
    2215 return false;
    \n-
    2216 }
    \n-
    2217 template<class G>
    \n-
    2218 inline bool Aggregator<G>::connected(const Vertex& vertex,
    \n-
    2219 const SLList<AggregateDescriptor>& aggregateList,
    \n-
    2220 const AggregatesMap<Vertex>& aggregates) const
    \n-
    2221 {
    \n-
    2222 typedef typename SLList<AggregateDescriptor>::const_iterator Iter;
    \n-
    2223 for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)
    \n-
    2224 if(connected(vertex, *i, aggregates))
    \n-
    2225 return true;
    \n-
    2226 return false;
    \n-
    2227 }
    \n-
    2228
    \n-
    2229 template<class G>
    \n-
    2230 template<class C>
    \n-
    2231 void Aggregator<G>::growIsolatedAggregate(const Vertex& seed, const AggregatesMap<Vertex>& aggregates, const C& c)
    \n-
    2232 {
    \n-
    2233 SLList<Vertex> connectedAggregates;
    \n-
    2234 nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);
    \n-
    2235
    \n-
    2236 while(aggregate_->size()< c.minAggregateSize() && aggregate_->connectSize() < c.maxConnectivity()) {
    \n-
    2237 double maxCon=-1;
    \n-
    2238 std::size_t maxFrontNeighbours=0;
    \n-
    2239
    \n-\n-
    2241
    \n-
    2242 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n-
    2243
    \n-
    2244 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n-
    2245 if(distance(*vertex, aggregates)>c.maxDistance())
    \n-
    2246 continue; // distance of proposes aggregate too big
    \n-
    2247
    \n-
    2248 if(connectedAggregates.size()>0) {
    \n-
    2249 // there is already a neighbour cluster
    \n-
    2250 // front node must be connected to same neighbour cluster
    \n-
    2251
    \n-
    2252 if(!connected(*vertex, connectedAggregates, aggregates))
    \n-
    2253 continue;
    \n-
    2254 }
    \n-
    2255
    \n-
    2256 double con = connectivity(*vertex, aggregates);
    \n-
    2257
    \n-
    2258 if(con == maxCon) {
    \n-
    2259 std::size_t frontNeighbours = noFrontNeighbours(*vertex);
    \n-
    2260
    \n-
    2261 if(frontNeighbours >= maxFrontNeighbours) {
    \n-
    2262 maxFrontNeighbours = frontNeighbours;
    \n-
    2263 candidate = *vertex;
    \n-
    2264 }
    \n-
    2265 }else if(con > maxCon) {
    \n-
    2266 maxCon = con;
    \n-
    2267 maxFrontNeighbours = noFrontNeighbours(*vertex);
    \n-
    2268 candidate = *vertex;
    \n-
    2269 }
    \n-
    2270 }
    \n-
    2271
    \n-\n-
    2273 break;
    \n-
    2274
    \n-
    2275 aggregate_->add(candidate);
    \n-
    2276 }
    \n-
    2277 }
    \n-
    2278
    \n-
    2279 template<class G>
    \n-
    2280 template<class C>
    \n-
    2281 void Aggregator<G>::growAggregate(const Vertex& seed, const AggregatesMap<Vertex>& aggregates, const C& c)
    \n-
    2282 {
    \n-
    2283 using std::min;
    \n-
    2284
    \n-
    2285 std::size_t distance_ =0;
    \n-
    2286 while(aggregate_->size() < c.minAggregateSize()&& distance_<c.maxDistance()) {
    \n-
    2287 int maxTwoCons=0, maxOneCons=0, maxNeighbours=-1;
    \n-
    2288 double maxCon=-1;
    \n-
    2289
    \n-
    2290 std::vector<Vertex> candidates;
    \n-
    2291 candidates.reserve(30);
    \n-
    2292
    \n-
    2293 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n-
    2294
    \n-
    2295 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n-
    2296 // Only nonisolated nodes are considered
    \n-
    2297 if(graph_->getVertexProperties(*vertex).isolated())
    \n-
    2298 continue;
    \n-
    2299
    \n-
    2300 int twoWayCons = twoWayConnections(*vertex, aggregate_->id(), aggregates);
    \n-
    2301
    \n-
    2302 /* The case of two way connections. */
    \n-
    2303 if( maxTwoCons == twoWayCons && twoWayCons > 0) {
    \n-
    2304 double con = connectivity(*vertex, aggregates);
    \n-
    2305
    \n-
    2306 if(con == maxCon) {
    \n-
    2307 int neighbours = noFrontNeighbours(*vertex);
    \n-
    2308
    \n-
    2309 if(neighbours > maxNeighbours) {
    \n-
    2310 maxNeighbours = neighbours;
    \n-
    2311 candidates.clear();
    \n-
    2312 candidates.push_back(*vertex);
    \n-
    2313 }else{
    \n-
    2314 candidates.push_back(*vertex);
    \n-
    2315 }
    \n-
    2316 }else if( con > maxCon) {
    \n-
    2317 maxCon = con;
    \n-
    2318 maxNeighbours = noFrontNeighbours(*vertex);
    \n-
    2319 candidates.clear();
    \n-
    2320 candidates.push_back(*vertex);
    \n-
    2321 }
    \n-
    2322 }else if(twoWayCons > maxTwoCons) {
    \n-
    2323 maxTwoCons = twoWayCons;
    \n-
    2324 maxCon = connectivity(*vertex, aggregates);
    \n-
    2325 maxNeighbours = noFrontNeighbours(*vertex);
    \n-
    2326 candidates.clear();
    \n-
    2327 candidates.push_back(*vertex);
    \n-
    2328
    \n-
    2329 // two way connections precede
    \n-
    2330 maxOneCons = std::numeric_limits<int>::max();
    \n-
    2331 }
    \n-
    2332
    \n-
    2333 if(twoWayCons > 0)
    \n-
    2334 {
    \n-
    2335 continue; // THis is a two-way node, skip tests for one way nodes
    \n-
    2336 }
    \n-
    2337
    \n-
    2338 /* The one way case */
    \n-
    2339 int oneWayCons = oneWayConnections(*vertex, aggregate_->id(), aggregates);
    \n-
    2340
    \n-
    2341 if(oneWayCons==0)
    \n-
    2342 continue; // No strong connections, skip the tests.
    \n-
    2343
    \n-
    2344 if(!admissible(*vertex, aggregate_->id(), aggregates))
    \n-
    2345 continue;
    \n-
    2346
    \n-
    2347 if( maxOneCons == oneWayCons && oneWayCons > 0) {
    \n-
    2348 double con = connectivity(*vertex, aggregates);
    \n-
    2349
    \n-
    2350 if(con == maxCon) {
    \n-
    2351 int neighbours = noFrontNeighbours(*vertex);
    \n-
    2352
    \n-
    2353 if(neighbours > maxNeighbours) {
    \n-
    2354 maxNeighbours = neighbours;
    \n-
    2355 candidates.clear();
    \n-
    2356 candidates.push_back(*vertex);
    \n-
    2357 }else{
    \n-
    2358 if(neighbours==maxNeighbours)
    \n-
    2359 {
    \n-
    2360 candidates.push_back(*vertex);
    \n-
    2361 }
    \n-
    2362 }
    \n-
    2363 }else if( con > maxCon) {
    \n-
    2364 maxCon = con;
    \n-
    2365 maxNeighbours = noFrontNeighbours(*vertex);
    \n-
    2366 candidates.clear();
    \n-
    2367 candidates.push_back(*vertex);
    \n-
    2368 }
    \n-
    2369 }else if(oneWayCons > maxOneCons) {
    \n-
    2370 maxOneCons = oneWayCons;
    \n-
    2371 maxCon = connectivity(*vertex, aggregates);
    \n-
    2372 maxNeighbours = noFrontNeighbours(*vertex);
    \n-
    2373 candidates.clear();
    \n-
    2374 candidates.push_back(*vertex);
    \n-
    2375 }
    \n-
    2376 }
    \n-
    2377
    \n-
    2378
    \n-
    2379 if(!candidates.size())
    \n-
    2380 break; // No more candidates found
    \n-
    2381 distance_=distance(seed, aggregates);
    \n-
    2382 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
    \n-
    2383 aggregate_->size()));
    \n-
    2384 aggregate_->add(candidates);
    \n-
    2385 }
    \n-
    2386 }
    \n-
    2387
    \n-
    2388 template<typename V>
    \n-
    2389 template<typename M, typename G, typename C>
    \n-
    2390 std::tuple<int,int,int,int> AggregatesMap<V>::buildAggregates(const M& matrix, G& graph, const C& criterion,
    \n-
    2391 bool finestLevel)
    \n-
    2392 {
    \n-
    2393 Aggregator<G> aggregator;
    \n-
    2394 return aggregator.build(matrix, graph, *this, criterion, finestLevel);
    \n-
    2395 }
    \n-
    2396
    \n-
    2397 template<class G>
    \n-
    2398 template<class M, class C>
    \n-
    2399 std::tuple<int,int,int,int> Aggregator<G>::build(const M& m, G& graph, AggregatesMap<Vertex>& aggregates, const C& c,
    \n-
    2400 bool finestLevel)
    \n-
    2401 {
    \n-
    2402 using std::max;
    \n-
    2403 using std::min;
    \n-
    2404 // Stack for fast vertex access
    \n-
    2405 Stack stack_(graph, *this, aggregates);
    \n-
    2406
    \n-
    2407 graph_ = &graph;
    \n-
    2408
    \n-
    2409 aggregate_ = new Aggregate<G,VertexSet>(graph, aggregates, connected_, front_);
    \n-
    2410
    \n-
    2411 Timer watch;
    \n-
    2412 watch.reset();
    \n-
    2413
    \n-
    2414 buildDependency(graph, m, c, finestLevel);
    \n-
    2415
    \n-
    2416 dverb<<"Build dependency took "<< watch.elapsed()<<" seconds."<<std::endl;
    \n-
    2417 int noAggregates, conAggregates, isoAggregates, oneAggregates;
    \n-
    2418 std::size_t maxA=0, minA=1000000, avg=0;
    \n-
    2419 int skippedAggregates;
    \n-
    2420 noAggregates = conAggregates = isoAggregates = oneAggregates =
    \n-
    2421 skippedAggregates = 0;
    \n-
    2422
    \n-
    2423 while(true) {
    \n-
    2424 Vertex seed = stack_.pop();
    \n-
    2425
    \n-
    2426 if(seed == Stack::NullEntry)
    \n-
    2427 // No more unaggregated vertices. We are finished!
    \n-
    2428 break;
    \n-
    2429
    \n-
    2430 // Debugging output
    \n-
    2431 if((noAggregates+1)%10000 == 0)
    \n-
    2432 Dune::dverb<<"c";
    \n-
    2433 unmarkFront();
    \n-
    2434
    \n-
    2435 if(graph.getVertexProperties(seed).excludedBorder()) {
    \n-
    2436 aggregates[seed]=AggregatesMap<Vertex>::ISOLATED;
    \n-
    2437 ++skippedAggregates;
    \n-
    2438 continue;
    \n-
    2439 }
    \n-
    2440
    \n-
    2441 if(graph.getVertexProperties(seed).isolated()) {
    \n-
    2442 if(c.skipIsolated()) {
    \n-
    2443 // isolated vertices are not aggregated but skipped on the coarser levels.
    \n-
    2444 aggregates[seed]=AggregatesMap<Vertex>::ISOLATED;
    \n-
    2445 ++skippedAggregates;
    \n-
    2446 // skip rest as no agglomeration is done.
    \n-
    2447 continue;
    \n-
    2448 }else{
    \n-
    2449 aggregate_->seed(seed);
    \n-
    2450 growIsolatedAggregate(seed, aggregates, c);
    \n-
    2451 }
    \n-
    2452 }else{
    \n-
    2453 aggregate_->seed(seed);
    \n-
    2454 growAggregate(seed, aggregates, c);
    \n-
    2455 }
    \n-
    2456
    \n-
    2457 /* The rounding step. */
    \n-
    2458 while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->size() < c.maxAggregateSize()) {
    \n-
    2459
    \n-
    2460 std::vector<Vertex> candidates;
    \n-
    2461 candidates.reserve(30);
    \n-
    2462
    \n-
    2463 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n-
    2464
    \n-
    2465 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n-
    2466
    \n-
    2467 if(graph.getVertexProperties(*vertex).isolated())
    \n-
    2468 continue; // No isolated nodes here
    \n-
    2469
    \n-
    2470 if(twoWayConnections( *vertex, aggregate_->id(), aggregates) == 0 &&
    \n-
    2471 (oneWayConnections( *vertex, aggregate_->id(), aggregates) == 0 ||
    \n-
    2472 !admissible( *vertex, aggregate_->id(), aggregates) ))
    \n-
    2473 continue;
    \n-
    2474
    \n-
    2475 std::pair<int,int> neighbourPair=neighbours(*vertex, aggregate_->id(),
    \n-
    2476 aggregates);
    \n-
    2477
    \n-
    2478 //if(aggregateNeighbours(*vertex, aggregate_->id(), aggregates) <= unusedNeighbours(*vertex, aggregates))
    \n-
    2479 // continue;
    \n-
    2480
    \n-
    2481 if(neighbourPair.first >= neighbourPair.second)
    \n-
    2482 continue;
    \n-
    2483
    \n-
    2484 if(distance(*vertex, aggregates) > c.maxDistance())
    \n-
    2485 continue; // Distance too far
    \n-
    2486 candidates.push_back(*vertex);
    \n-
    2487 break;
    \n-
    2488 }
    \n-
    2489
    \n-
    2490 if(!candidates.size()) break; // no more candidates found.
    \n-
    2491
    \n-
    2492 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
    \n-
    2493 aggregate_->size()));
    \n-
    2494 aggregate_->add(candidates);
    \n-
    2495
    \n-
    2496 }
    \n-
    2497
    \n-
    2498 // try to merge aggregates consisting of only one nonisolated vertex with other aggregates
    \n-
    2499 if(aggregate_->size()==1 && c.maxAggregateSize()>1) {
    \n-
    2500 if(!graph.getVertexProperties(seed).isolated()) {
    \n-
    2501 Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);
    \n-
    2502
    \n-
    2503 if(mergedNeighbour != AggregatesMap<Vertex>::UNAGGREGATED) {
    \n-
    2504 // assign vertex to the neighbouring cluster
    \n-
    2505 aggregates[seed] = aggregates[mergedNeighbour];
    \n-
    2506 aggregate_->invalidate();
    \n-
    2507 }else{
    \n-
    2508 ++avg;
    \n-
    2509 minA=min(minA,static_cast<std::size_t>(1));
    \n-
    2510 maxA=max(maxA,static_cast<std::size_t>(1));
    \n-
    2511 ++oneAggregates;
    \n-
    2512 ++conAggregates;
    \n-
    2513 }
    \n-
    2514 }else{
    \n-
    2515 ++avg;
    \n-
    2516 minA=min(minA,static_cast<std::size_t>(1));
    \n-
    2517 maxA=max(maxA,static_cast<std::size_t>(1));
    \n-
    2518 ++oneAggregates;
    \n-
    2519 ++isoAggregates;
    \n-
    2520 }
    \n-
    2521 ++avg;
    \n-
    2522 }else{
    \n-
    2523 avg+=aggregate_->size();
    \n-
    2524 minA=min(minA,aggregate_->size());
    \n-
    2525 maxA=max(maxA,aggregate_->size());
    \n-
    2526 if(graph.getVertexProperties(seed).isolated())
    \n-
    2527 ++isoAggregates;
    \n-
    2528 else
    \n-
    2529 ++conAggregates;
    \n-
    2530 }
    \n-
    2531
    \n-
    2532 }
    \n-
    2533
    \n-
    2534 Dune::dinfo<<"connected aggregates: "<<conAggregates;
    \n-
    2535 Dune::dinfo<<" isolated aggregates: "<<isoAggregates;
    \n-
    2536 if(conAggregates+isoAggregates>0)
    \n-
    2537 Dune::dinfo<<" one node aggregates: "<<oneAggregates<<" min size="
    \n-
    2538 <<minA<<" max size="<<maxA
    \n-
    2539 <<" avg="<<avg/(conAggregates+isoAggregates)<<std::endl;
    \n-
    2540
    \n-
    2541 delete aggregate_;
    \n-
    2542 return std::make_tuple(conAggregates+isoAggregates,isoAggregates,
    \n-
    2543 oneAggregates,skippedAggregates);
    \n-
    2544 }
    \n-
    2545
    \n-
    2546
    \n-
    2547 template<class G>
    \n-
    2548 Aggregator<G>::Stack::Stack(const MatrixGraph& graph, const Aggregator<G>& aggregatesBuilder,
    \n-
    2549 const AggregatesMap<Vertex>& aggregates)
    \n-
    2550 : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_(aggregates), begin_(graph.begin()), end_(graph.end())
    \n-
    2551 {
    \n-
    2552 //vals_ = new Vertex[N];
    \n-
    2553 }
    \n-
    2554
    \n-
    2555 template<class G>
    \n-
    2556 Aggregator<G>::Stack::~Stack()
    \n-
    2557 {
    \n-
    2558 //Dune::dverb << "Max stack size was "<<maxSize_<<" filled="<<filled_<<std::endl;
    \n-
    2559 //delete[] vals_;
    \n-
    2560 }
    \n-
    2561
    \n-
    2562 template<class G>
    \n-
    2563 const typename Aggregator<G>::Vertex Aggregator<G>::Stack::NullEntry
    \n-
    2564 = std::numeric_limits<typename G::VertexDescriptor>::max();
    \n-
    2565
    \n-
    2566 template<class G>
    \n-
    2567 inline typename G::VertexDescriptor Aggregator<G>::Stack::pop()
    \n-
    2568 {
    \n-
    2569 for(; begin_!=end_ && aggregates_[*begin_] != AggregatesMap<Vertex>::UNAGGREGATED; ++begin_) ;
    \n-
    2570
    \n-
    2571 if(begin_!=end_)
    \n-
    2572 {
    \n-
    2573 typename G::VertexDescriptor current=*begin_;
    \n-
    2574 ++begin_;
    \n-
    2575 return current;
    \n-
    2576 }else
    \n-
    2577 return NullEntry;
    \n-
    2578 }
    \n-
    2579
    \n-
    2580#endif // DOXYGEN
    \n-
    2581
    \n-
    2582 template<class V>
    \n-
    2583 void printAggregates2d(const AggregatesMap<V>& aggregates, int n, int m, std::ostream& os)
    \n-
    2584 {
    \n-
    2585 using std::max;
    \n-
    2586
    \n-
    2587 std::ios_base::fmtflags oldOpts=os.flags();
    \n-
    2588
    \n-
    2589 os.setf(std::ios_base::right, std::ios_base::adjustfield);
    \n-
    2590
    \n-
    2591 V maxVal=0;
    \n-
    2592 int width=1;
    \n-
    2593
    \n-
    2594 for(int i=0; i< n*m; i++)
    \n-
    2595 maxVal=max(maxVal, aggregates[i]);
    \n-
    2596
    \n-
    2597 for(int i=10; i < 1000000; i*=10)
    \n-
    2598 if(maxVal/i>0)
    \n-
    2599 width++;
    \n-
    2600 else
    \n-
    2601 break;
    \n-
    2602
    \n-
    2603 for(int j=0, entry=0; j < m; j++) {
    \n-
    2604 for(int i=0; i<n; i++, entry++) {
    \n-
    2605 os.width(width);
    \n-
    2606 os<<aggregates[entry]<<" ";
    \n-
    2607 }
    \n-
    2608
    \n-
    2609 os<<std::endl;
    \n-
    2610 }
    \n-
    2611 os<<std::endl;
    \n-
    2612 os.flags(oldOpts);
    \n-
    2613 }
    \n-
    2614
    \n-
    2615
    \n-
    2616 } // namespace Amg
    \n-
    2617
    \n-
    2618} // namespace Dune
    \n-
    2619
    \n-
    2620
    \n-
    2621#endif
    \n-
    Provides classes for building the matrix graph.
    \n-
    Parameter classes for customizing AMG.
    \n-\n-
    Provides classes for handling internal properties in a graph.
    \n+
    819 template<typename M, typename C>
    \n+
    820 void redistributeMatrix(M& origMatrix, M& newMatrix, C& origComm, C& newComm,
    \n+\n+
    822 {
    \n+
    823 ri.setNoRows(newComm.indexSet().size());
    \n+
    824 ri.setNoCopyRows(newComm.indexSet().size());
    \n+
    825 ri.setNoBackwardsCopyRows(origComm.indexSet().size());
    \n+
    826 redistributeSparsityPattern(origMatrix, newMatrix, origComm, newComm, ri);
    \n+
    827 redistributeMatrixEntries(origMatrix, newMatrix, origComm, newComm, ri);
    \n+
    828 }
    \n+
    829#endif
    \n+
    830
    \n+
    831template<typename M>
    \n+
    832 void redistributeMatrixEntries(M& origMatrix, M& newMatrix,
    \n+\n+\n+\n+
    836 {
    \n+
    837 DUNE_THROW(InvalidStateException, "Trying to redistribute in sequential program!");
    \n+
    838 }
    \n+
    839 template<typename M>
    \n+
    840 void redistributeMatrix(M& origMatrix, M& newMatrix,
    \n+\n+\n+\n+
    844 {
    \n+
    845 DUNE_THROW(InvalidStateException, "Trying to redistribute in sequential program!");
    \n+
    846 }
    \n+
    847}
    \n+
    848#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Functionality for redistributing a parallel index set using graph partitioning.
    \n+\n
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:273
    \n-
    std::vector< real_type >::iterator valIter_
    Definition: aggregates.hh:189
    \n-
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:154
    \n-
    std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, L &visited, F1 &aggregateVisitor, F2 &nonAggregateVisitor, VM &visitedMap) const
    Breadth first search within an aggregate.
    \n-
    PoolAllocator< VertexDescriptor, 100 > Allocator
    The allocator we use for our lists and the set.
    Definition: aggregates.hh:586
    \n-
    iterator begin()
    Definition: aggregates.hh:737
    \n-
    int id()
    Get the id identifying the aggregate.
    \n-
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:302
    \n-
    MatrixGraph::VertexDescriptor Vertex
    The vertex identifier.
    Definition: aggregates.hh:920
    \n-
    AggregationCriterion()
    Constructor.
    Definition: aggregates.hh:66
    \n-
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:357
    \n-
    auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr) const
    Compute the norm of a scalar.
    Definition: aggregates.hh:406
    \n-
    void initRow(const Row &row, int index)
    \n-
    SymmetricMatrixDependency(const Parameters &parms)
    Definition: aggregates.hh:168
    \n-
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:258
    \n-\n-
    G MatrixGraph
    The matrix graph type used.
    Definition: aggregates.hh:915
    \n-
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:363
    \n-
    void operator()(const EdgeIterator &edge) const
    Definition: aggregates.hh:601
    \n-
    SymmetricCriterion()
    Definition: aggregates.hh:524
    \n-
    Dependency()
    Definition: aggregates.hh:290
    \n-
    void examine(const ColIter &col)
    \n-
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:319
    \n-
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:187
    \n-
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:263
    \n-
    iterator end()
    Definition: aggregates.hh:742
    \n-
    UnSymmetricCriterion(const Parameters &parms)
    Definition: aggregates.hh:541
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    void initRow(const Row &row, int index)
    Definition: aggregates.hh:201
    \n-\n-
    static const Vertex NullEntry
    Definition: aggregates.hh:1008
    \n-
    void examine(const ColIter &col)
    Definition: aggregates.hh:214
    \n-
    Dependency(const Parameters &parms)
    Definition: aggregates.hh:286
    \n-
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:185
    \n-
    friend class Stack
    Definition: aggregates.hh:1036
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    std::tuple< int, int, int, int > build(const M &m, G &graph, AggregatesMap< Vertex > &aggregates, const C &c, bool finestLevel)
    Build the aggregates.
    \n-
    FrontNeighbourCounter(const MatrixGraph &front)
    Constructor.
    \n-
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:329
    \n-
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:296
    \n-
    const AggregateDescriptor & operator[](const VertexDescriptor &v) const
    Get the aggregate a vertex belongs to.
    \n-
    void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
    \n-
    AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const AggregateDescriptor &aggregate, Visitor &visitor)
    Constructor.
    \n-
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:334
    \n-
    ~AggregatesMap()
    Destructor.
    \n-
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:179
    \n-
    void decrement()
    Decrement counter.
    \n-
    Aggregate(MatrixGraph &graph, AggregatesMap< Vertex > &aggregates, VertexSet &connectivity, std::vector< Vertex > &front_)
    Constructor.
    \n-
    V Visitor
    The type of the adapted visitor.
    Definition: aggregates.hh:1064
    \n-
    std::size_t * SphereMap
    Type of the mapping of aggregate members onto distance spheres.
    Definition: aggregates.hh:809
    \n-
    AggregationCriterion(const Parameters &parms)
    Definition: aggregates.hh:70
    \n-
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:268
    \n-
    VertexSet::size_type connectSize()
    Get tne number of connections to other aggregates.
    \n-
    std::vector< real_type > vals_
    Definition: aggregates.hh:188
    \n-
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:324
    \n-
    void printAggregates2d(const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)
    Definition: aggregates.hh:2583
    \n-
    void invalidate()
    Definition: aggregates.hh:822
    \n-
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n-
    real_type maxValue_
    Definition: aggregates.hh:181
    \n-
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:183
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    VertexSet::const_iterator const_iterator
    Const iterator over a vertex list.
    Definition: aggregates.hh:804
    \n-
    SymmetricCriterion(const Parameters &parms)
    Definition: aggregates.hh:521
    \n-
    MatrixGraph::VertexDescriptor AggregateDescriptor
    The type of the aggregate descriptor.
    Definition: aggregates.hh:923
    \n-
    real_type maxValue_
    Definition: aggregates.hh:361
    \n-
    void init(const Matrix *matrix)
    Definition: aggregates.hh:195
    \n-
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:367
    \n-
    AggregateDescriptor * iterator
    Definition: aggregates.hh:735
    \n-
    SymmetricDependency(const Parameters &parms)
    Definition: aggregates.hh:348
    \n-
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:360
    \n-
    ~Aggregator()
    Destructor.
    \n-
    void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
    \n-
    void add(const Vertex &vertex)
    Add a vertex to the aggregate.
    \n-
    T DependencyPolicy
    The policy for calculating the dependency graph.
    Definition: aggregates.hh:55
    \n-
    void add(std::vector< Vertex > &vertex)
    \n-
    void examine(const ColIter &col)
    \n-
    Aggregator()
    Constructor.
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    Examine an edge.
    \n-
    FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)
    Constructor.
    \n-
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:506
    \n-
    void init(const Matrix *matrix)
    \n-
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n-
    void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an isotropic problem.
    Definition: aggregates.hh:82
    \n-
    const_iterator end() const
    Definition: aggregates.hh:730
    \n-
    V AggregateDescriptor
    The aggregate descriptor type.
    Definition: aggregates.hh:580
    \n-
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n-
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:365
    \n-
    SymmetricMatrixDependency()
    Definition: aggregates.hh:171
    \n-\n-\n-
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:306
    \n-
    std::size_t noVertices() const
    Get the number of vertices.
    \n-
    void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an aisotropic problem.
    Definition: aggregates.hh:105
    \n-
    AggregatesMap(std::size_t noVertices)
    Constructs with allocating memory.
    \n-
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:359
    \n-
    AggregateDescriptor & operator[](const VertexDescriptor &v)
    Get the aggregate a vertex belongs to.
    \n-
    AggregatesMap()
    Constructs without allocating memory.
    \n-
    int value()
    Access the current count.
    \n-
    SLList< VertexDescriptor, Allocator > VertexList
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:592
    \n-\n-
    ConnectivityCounter(const VertexSet &connected, const AggregatesMap< Vertex > &aggregates)
    Constructor.
    \n-
    VertexSet::size_type size()
    Get the size of the aggregate.
    \n-
    const_iterator end() const
    get an iterator over the vertices of the aggregate.
    \n-
    void init(const Matrix *matrix)
    \n-
    UnSymmetricCriterion()
    Definition: aggregates.hh:544
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    const AggregateDescriptor * const_iterator
    Definition: aggregates.hh:723
    \n-
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:304
    \n-
    Stack(const MatrixGraph &graph, const Aggregator< G > &aggregatesBuilder, const AggregatesMap< Vertex > &aggregates)
    \n-
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:180
    \n-
    void initRow(const Row &row, int index)
    \n-
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:139
    \n-
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:299
    \n-
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:177
    \n-
    S VertexSet
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:801
    \n-
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:490
    \n-
    static const V UNAGGREGATED
    Identifier of not yet aggregated vertices.
    Definition: aggregates.hh:566
    \n-
    std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, F &aggregateVisitor, VM &visitedMap) const
    Breadth first search within an aggregate.
    \n-
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:298
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T > &criterion)
    Definition: aggregates.hh:113
    \n-
    bool isIsolated()
    Definition: aggregates.hh:240
    \n-
    void allocate(std::size_t noVertices)
    Allocate memory for holding the information.
    \n-
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:144
    \n-
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:473
    \n-
    void reconstruct(const Vertex &vertex)
    Reconstruct the aggregat from an seed node.
    \n-
    const_iterator begin() const
    get an iterator over the vertices of the aggregate.
    \n-
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr) const
    compute the norm of a matrix.
    Definition: aggregates.hh:390
    \n-
    MatrixGraph::VertexDescriptor Vertex
    The vertex descriptor type.
    Definition: aggregates.hh:789
    \n-
    void seed(const Vertex &vertex)
    Initialize the aggregate with one vertex.
    \n-\n-
    SymmetricDependency()
    Definition: aggregates.hh:351
    \n-
    void clear()
    Clear the aggregate.
    \n-
    void free()
    Free the allocated memory.
    \n-
    void increment()
    Increment counter.
    \n-
    void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
    Build the dependency of the matrix graph.
    \n-
    V VertexDescriptor
    The vertex descriptor type.
    Definition: aggregates.hh:575
    \n-
    real_type maxValue_
    Definition: aggregates.hh:300
    \n-
    std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph, const C &criterion, bool finestLevel)
    Build the aggregates.
    \n-
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:149
    \n-
    PoolAllocator< Vertex, 100 > Allocator
    The allocator we use for our lists and the set.
    Definition: aggregates.hh:795
    \n-
    G MatrixGraph
    Definition: aggregates.hh:785
    \n-
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n-
    @ is_sign_preserving
    Definition: aggregates.hh:483
    \n-
    @ is_sign_preserving
    Definition: aggregates.hh:382
    \n-
    @ is_sign_preserving
    Definition: aggregates.hh:499
    \n-
    @ is_sign_preserving
    Definition: aggregates.hh:466
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:757
    \n+
    void redistributeSparsityPattern(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:663
    \n+
    void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Redistribute a matrix according to given domain decompositions.
    Definition: matrixredistribute.hh:820
    \n
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n-
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n-
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n-
    Base class of all aggregation criterions.
    Definition: aggregates.hh:49
    \n-
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:134
    \n-
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:253
    \n-
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:314
    \n-
    Norm that uses only the [N][N] entry of the block to determine couplings.
    Definition: aggregates.hh:379
    \n-
    Norm that uses only the [0][0] entry of the block to determine couplings.
    Definition: aggregates.hh:455
    \n-
    Functor using the row sum (infinity) norm to determine strong couplings.
    Definition: aggregates.hh:463
    \n-
    Definition: aggregates.hh:480
    \n-
    Definition: aggregates.hh:496
    \n-
    Criterion taking advantage of symmetric matrices.
    Definition: aggregates.hh:519
    \n-
    Criterion suitable for unsymmetric matrices.
    Definition: aggregates.hh:539
    \n-
    Class for building the aggregates.
    Definition: aggregates.hh:909
    \n-
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-
    A Dummy visitor that does nothing for each visited edge.
    Definition: aggregates.hh:598
    \n-
    A class for temporarily storing the vertices of an aggregate in.
    Definition: aggregates.hh:778
    \n-
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n-
    EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:298
    \n-
    Iterator over all edges starting from a vertex.
    Definition: graph.hh:95
    \n-
    The vertex iterator type of the graph.
    Definition: graph.hh:209
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Definition: matrixredistribute.hh:22
    \n+
    void setNoBackwardsCopyRows(std::size_t size)
    Definition: matrixredistribute.hh:44
    \n+
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:28
    \n+
    void resetSetup()
    Definition: matrixredistribute.hh:35
    \n+
    void setNoCopyRows(std::size_t size)
    Definition: matrixredistribute.hh:41
    \n+
    bool isSetup() const
    Definition: matrixredistribute.hh:23
    \n+
    void setNoRows(std::size_t size)
    Definition: matrixredistribute.hh:38
    \n+
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:32
    \n+
    std::size_t getBackwardsCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:57
    \n+
    std::size_t getRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:47
    \n+
    std::size_t getCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:52
    \n+
    std::size_t getRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:158
    \n+
    std::size_t & getBackwardsCopyRowSize(std::size_t index)
    Definition: matrixredistribute.hh:173
    \n+
    RedistributeInterface & getInterface()
    Definition: matrixredistribute.hh:75
    \n+
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:136
    \n+
    void setNoBackwardsCopyRows(std::size_t rows)
    Definition: matrixredistribute.hh:193
    \n+
    std::size_t & getCopyRowSize(std::size_t index)
    Definition: matrixredistribute.hh:163
    \n+\n+
    std::size_t getCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:168
    \n+
    void setNoRows(std::size_t rows)
    Definition: matrixredistribute.hh:183
    \n+
    void reserve(std::size_t size)
    Definition: matrixredistribute.hh:150
    \n+
    OwnerOverlapCopyCommunication< T, T1 > Comm
    Definition: matrixredistribute.hh:69
    \n+
    void setNoCopyRows(std::size_t rows)
    Definition: matrixredistribute.hh:188
    \n+
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:141
    \n+\n+
    std::size_t getBackwardsCopyRowSize(std::size_t index) const
    Definition: matrixredistribute.hh:178
    \n+
    void redistribute(const D &from, D &to) const
    Definition: matrixredistribute.hh:118
    \n+\n+
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:126
    \n+
    void checkInterface(const IS &source, const IS &target, MPI_Comm comm)
    Definition: matrixredistribute.hh:80
    \n+
    bool isSetup() const
    Definition: matrixredistribute.hh:145
    \n+
    std::size_t & getRowSize(std::size_t index)
    Definition: matrixredistribute.hh:153
    \n+
    Utility class to communicate and set the row sizes of a redistributed matrix.
    Definition: matrixredistribute.hh:216
    \n+
    M::size_type size_type
    Definition: matrixredistribute.hh:219
    \n+
    M::size_type value_type
    Definition: matrixredistribute.hh:218
    \n+
    RI & rowsize
    Definition: matrixredistribute.hh:230
    \n+
    const M & matrix
    Definition: matrixredistribute.hh:229
    \n+
    CommMatrixRowSize(const M &m_, RI &rowsize_)
    Constructor.
    Definition: matrixredistribute.hh:226
    \n+
    Utility class to communicate and build the sparsity pattern of a redistributed matrix.
    Definition: matrixredistribute.hh:245
    \n+
    M::size_type size_type
    Definition: matrixredistribute.hh:246
    \n+
    const Dune::GlobalLookupIndexSet< I > & idxset
    Definition: matrixredistribute.hh:356
    \n+
    void storeSparsityPattern(M &m)
    Creates and stores the sparsity pattern of the redistributed matrix.
    Definition: matrixredistribute.hh:276
    \n+
    const I & aggidxset
    Definition: matrixredistribute.hh:357
    \n+
    const std::vector< size_type > * rowsize
    Definition: matrixredistribute.hh:359
    \n+
    void completeSparsityPattern(std::vector< std::set< size_type > > add_sparsity)
    Completes the sparsity pattern of the redistributed matrix with data from copy rows for the novlp cas...
    Definition: matrixredistribute.hh:340
    \n+
    CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_)
    Constructor for the original side.
    Definition: matrixredistribute.hh:254
    \n+
    const M & matrix
    Definition: matrixredistribute.hh:354
    \n+
    CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_, const std::vector< typename M::size_type > &rowsize_)
    Constructor for the redistruted side.
    Definition: matrixredistribute.hh:265
    \n+
    std::vector< std::set< size_type > > sparsity
    Definition: matrixredistribute.hh:358
    \n+
    Dune::GlobalLookupIndexSet< I > LookupIndexSet
    Definition: matrixredistribute.hh:355
    \n+
    static M::size_type getSize(const Type &t, std::size_t i)
    Definition: matrixredistribute.hh:376
    \n+
    CommMatrixSparsityPattern< M, I > Type
    Definition: matrixredistribute.hh:365
    \n+
    I::GlobalIndex IndexedType
    The indexed type we send. This is the global index indentitfying the column.
    Definition: matrixredistribute.hh:371
    \n+
    VariableSize IndexedTypeFlag
    Each row varies in size.
    Definition: matrixredistribute.hh:374
    \n+
    Utility class for comunicating the matrix entries.
    Definition: matrixredistribute.hh:396
    \n+
    std::vector< size_t > * rowsize
    row size information for the receiving side.
    Definition: matrixredistribute.hh:452
    \n+
    M & matrix
    The matrix to communicate the values of.
    Definition: matrixredistribute.hh:446
    \n+
    CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_, std::vector< size_t > &rowsize_)
    Constructor.
    Definition: matrixredistribute.hh:412
    \n+
    const Dune::GlobalLookupIndexSet< I > & idxset
    Index set for the original matrix.
    Definition: matrixredistribute.hh:448
    \n+
    void setOverlapRowsToDirichlet()
    Sets the non-owner rows correctly as Dirichlet boundaries.
    Definition: matrixredistribute.hh:421
    \n+
    const I & aggidxset
    Index set for the redistributed matrix.
    Definition: matrixredistribute.hh:450
    \n+
    CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_)
    Constructor.
    Definition: matrixredistribute.hh:405
    \n+
    std::pair< typename I::GlobalIndex, typename M::block_type > IndexedType
    The indexed type we send. This is the pair of global index indentitfying the column and the value its...
    Definition: matrixredistribute.hh:464
    \n+
    CommMatrixRow< M, I > Type
    Definition: matrixredistribute.hh:458
    \n+
    static std::size_t getSize(const Type &t, std::size_t i)
    Definition: matrixredistribute.hh:469
    \n+
    VariableSize IndexedTypeFlag
    Each row varies in size.
    Definition: matrixredistribute.hh:467
    \n+
    Definition: matrixredistribute.hh:483
    \n+
    static void scatter(Container &cont, const typename M::size_type &rowsize, std::size_t i)
    Definition: matrixredistribute.hh:490
    \n+
    static const M::size_type gather(const Container &cont, std::size_t i)
    Definition: matrixredistribute.hh:486
    \n+
    CommMatrixRowSize< M, RI > Container
    Definition: matrixredistribute.hh:484
    \n+
    Definition: matrixredistribute.hh:500
    \n+
    static const M::size_type gather(const Container &cont, std::size_t i)
    Definition: matrixredistribute.hh:503
    \n+
    static void scatter(Container &cont, const typename M::size_type &rowsize, std::size_t i)
    Definition: matrixredistribute.hh:507
    \n+
    CommMatrixRowSize< M, RI > Container
    Definition: matrixredistribute.hh:501
    \n+
    Definition: matrixredistribute.hh:518
    \n+
    M::ConstColIterator ColIter
    Definition: matrixredistribute.hh:521
    \n+
    static void scatter(Container &cont, const GlobalIndex &gi, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:553
    \n+
    CommMatrixSparsityPattern< M, I > Container
    Definition: matrixredistribute.hh:520
    \n+
    static GlobalIndex numlimits
    Definition: matrixredistribute.hh:524
    \n+
    static ColIter col
    Definition: matrixredistribute.hh:523
    \n+
    I::GlobalIndex GlobalIndex
    Definition: matrixredistribute.hh:519
    \n+
    static const GlobalIndex & gather(const Container &cont, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:526
    \n+
    Definition: matrixredistribute.hh:599
    \n+
    I::GlobalIndex GlobalIndex
    Definition: matrixredistribute.hh:600
    \n+
    static Data datastore
    Definition: matrixredistribute.hh:605
    \n+
    static GlobalIndex numlimits
    Definition: matrixredistribute.hh:606
    \n+
    M::ConstColIterator ColIter
    Definition: matrixredistribute.hh:602
    \n+
    static const Data & gather(const Container &cont, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:608
    \n+
    std::pair< GlobalIndex, typename M::block_type > Data
    Definition: matrixredistribute.hh:603
    \n+
    static void scatter(Container &cont, const Data &data, std::size_t i, std::size_t j)
    Definition: matrixredistribute.hh:638
    \n+
    static ColIter col
    Definition: matrixredistribute.hh:604
    \n+
    CommMatrixRow< M, I > Container
    Definition: matrixredistribute.hh:601
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet
    Definition: owneroverlapcopy.hh:194
    \n+
    Definition: pinfo.hh:28
    \n+
    Definition: repartition.hh:260
    \n+
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,2667 +4,1180 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-aggregates.hh\n+matrixredistribute.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_AGGREGATES_HH\n- 6#define DUNE_AMG_AGGREGATES_HH\n- 7\n- 8\n- 9#include \"parameters.hh\"\n- 10#include \"graph.hh\"\n- 11#include \"properties.hh\"\n- 12#include \"combinedfunctor.hh\"\n- 13\n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20\n- 21#include \n- 22#include \n- 23#include \n- 24#include \n- 25#include \n- 26#include \n- 27#include \n- 28\n- 29namespace Dune\n- 30{\n- 31 namespace Amg\n- 32 {\n- 33\n- 47 template\n-48 class AggregationCriterion : public T\n- 49 {\n- 50\n- 51 public:\n-55 typedef T DependencyPolicy;\n+ 5#ifndef DUNE_ISTL_MATRIXREDISTRIBUTE_HH\n+ 6#define DUNE_ISTL_MATRIXREDISTRIBUTE_HH\n+ 7#include \n+ 8#include \"repartition.hh\"\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 18namespace Dune\n+ 19{\n+ 20 template\n+21 struct RedistributeInformation\n+ 22 {\n+23 bool isSetup() const\n+ 24 {\n+ 25 return false;\n+ 26 }\n+ 27 template\n+28 void redistribute([[maybe_unused]] const D& from, [[maybe_unused]] D& to)\n+const\n+ 29 {}\n+ 30\n+ 31 template\n+32 void redistributeBackward([[maybe_unused]] D& from, [[maybe_unused]]const D&\n+to) const\n+ 33 {}\n+ 34\n+35 void resetSetup()\n+ 36 {}\n+ 37\n+38 void setNoRows([[maybe_unused]] std::size_t size)\n+ 39 {}\n+ 40\n+41 void setNoCopyRows([[maybe_unused]] std::size_t size)\n+ 42 {}\n+ 43\n+44 void setNoBackwardsCopyRows([[maybe_unused]] std::size_t size)\n+ 45 {}\n+ 46\n+47 std::size_t getRowSize([[maybe_unused]] std::size_t index) const\n+ 48 {\n+ 49 return -1;\n+ 50 }\n+ 51\n+52 std::size_t getCopyRowSize([[maybe_unused]] std::size_t index) const\n+ 53 {\n+ 54 return -1;\n+ 55 }\n 56\n-66 AggregationCriterion()\n- 67 : T()\n- 68 {}\n- 69\n-70 AggregationCriterion(const Parameters& parms)\n- 71 : T(parms)\n- 72 {}\n-82 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n- 83 {\n- 84 this->setMaxDistance(diameter-1);\n- 85 std::size_t csize=1;\n- 86\n- 87 for(; dim>0; dim--) {\n- 88 csize*=diameter;\n- 89 this->setMaxDistance(this->maxDistance()+diameter-1);\n- 90 }\n- 91 this->setMinAggregateSize(csize);\n- 92 this->setMaxAggregateSize(static_cast(csize*1.5));\n- 93 }\n- 94\n-105 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)\n- 106 {\n- 107 setDefaultValuesIsotropic(dim, diameter);\n- 108 this->setMaxDistance(this->maxDistance()+dim-1);\n- 109 }\n- 110 };\n+57 std::size_t getBackwardsCopyRowSize([[maybe_unused]] std::size_t index)\n+const\n+ 58 {\n+ 59 return -1;\n+ 60 }\n+ 61\n+ 62 };\n+ 63\n+ 64#if HAVE_MPI\n+ 65 template\n+66 class RedistributeInformation >\n+ 67 {\n+ 68 public:\n+69 typedef OwnerOverlapCopyCommunication Comm;\n+ 70\n+71 RedistributeInformation()\n+ 72 : interface(), setup_(false)\n+ 73 {}\n+ 74\n+75 RedistributeInterface& getInterface()\n+ 76 {\n+ 77 return interface;\n+ 78 }\n+ 79 template\n+80 void checkInterface(const IS& source,\n+ 81 const IS& target, MPI_Comm comm)\n+ 82 {\n+ 83 auto ri = std::make_unique >(source, target, comm);\n+ 84 ri->template rebuild();\n+ 85 Interface inf;\n+ 86 typename OwnerOverlapCopyCommunication::OwnerSet flags;\n+ 87 int rank;\n+ 88 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n+ 89 inf.free();\n+ 90 inf.build(*ri, flags, flags);\n+ 91\n+ 92\n+ 93#ifdef DEBUG_REPART\n+ 94 if(inf!=interface) {\n+ 95\n+ 96 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n+ 97 if(rank==0)\n+ 98 std::cout<<\"Interfaces do not match!\"<\n-113 std::ostream& operator<<(std::ostream& os, const AggregationCriterion&\n-criterion)\n- 114 {\n- 115 os<<\"{ maxdistance=\"<\n-133 class SymmetricMatrixDependency : public Dune::Amg::Parameters\n- 134 {\n- 135 public:\n-139 typedef M Matrix;\n- 140\n-144 typedef N Norm;\n- 145\n-149 typedef typename Matrix::row_type Row;\n- 150\n-154 typedef typename Matrix::ConstColIterator ColIter;\n- 155\n- 156 void init(const Matrix* matrix);\n+112 void resetSetup()\n+ 113 {\n+ 114 setup_=false;\n+ 115 }\n+ 116\n+ 117 template\n+118 void redistribute(const D& from, D& to) const\n+ 119 {\n+ 120 BufferedCommunicator communicator;\n+ 121 communicator.template build(from,to, interface);\n+ 122 communicator.template forward(from, to);\n+ 123 communicator.free();\n+ 124 }\n+ 125 template\n+126 void redistributeBackward(D& from, const D& to) const\n+ 127 {\n+ 128\n+ 129 BufferedCommunicator communicator;\n+ 130 communicator.template build(from,to, interface);\n+ 131 communicator.template backward(from, to);\n+ 132 communicator.free();\n+ 133 }\n+ 134\n+ 135 template\n+136 void redistribute(const D& from, D& to) const\n+ 137 {\n+ 138 redistribute >(from,to);\n+ 139 }\n+ 140 template\n+141 void redistributeBackward(D& from, const D& to) const\n+ 142 {\n+ 143 redistributeBackward >(from,to);\n+ 144 }\n+145 bool isSetup() const\n+ 146 {\n+ 147 return setup_;\n+ 148 }\n+ 149\n+150 void reserve(std::size_t size)\n+ 151 {}\n+ 152\n+153 std::size_t& getRowSize(std::size_t index)\n+ 154 {\n+ 155 return rowSize[index];\n+ 156 }\n 157\n- 158 void initRow(const Row& row, int index);\n- 159\n- 160 void examine(const ColIter& col);\n- 161\n- 162 template\n- 163 void examine(G& graph, const typename G::EdgeIterator& edge, const\n-ColIter& col);\n- 164\n- 165 bool isIsolated();\n- 166\n+158 std::size_t getRowSize(std::size_t index) const\n+ 159 {\n+ 160 return rowSize[index];\n+ 161 }\n+ 162\n+163 std::size_t& getCopyRowSize(std::size_t index)\n+ 164 {\n+ 165 return copyrowSize[index];\n+ 166 }\n 167\n-168 SymmetricMatrixDependency(const Parameters& parms)\n- 169 : Parameters(parms)\n- 170 {}\n-171 SymmetricMatrixDependency()\n- 172 : Parameters()\n- 173 {}\n- 174\n- 175 protected:\n-177 const Matrix* matrix_;\n-179 typedef typename Matrix::field_type field_type;\n-180 typedef typename FieldTraits::real_type real_type;\n-181 real_type maxValue_;\n-183 Norm norm_;\n-185 int row_;\n-187 real_type diagonal_;\n-188 std::vector vals_;\n-189 typename std::vector::iterator valIter_;\n- 190\n- 191 };\n+168 std::size_t getCopyRowSize(std::size_t index) const\n+ 169 {\n+ 170 return copyrowSize[index];\n+ 171 }\n+ 172\n+173 std::size_t& getBackwardsCopyRowSize(std::size_t index)\n+ 174 {\n+ 175 return backwardscopyrowSize[index];\n+ 176 }\n+ 177\n+178 std::size_t getBackwardsCopyRowSize(std::size_t index) const\n+ 179 {\n+ 180 return backwardscopyrowSize[index];\n+ 181 }\n+ 182\n+183 void setNoRows(std::size_t rows)\n+ 184 {\n+ 185 rowSize.resize(rows, 0);\n+ 186 }\n+ 187\n+188 void setNoCopyRows(std::size_t rows)\n+ 189 {\n+ 190 copyrowSize.resize(rows, 0);\n+ 191 }\n 192\n- 193\n- 194 template\n-195 inline void SymmetricMatrixDependency::init(const Matrix* matrix)\n- 196 {\n- 197 matrix_ = matrix;\n- 198 }\n- 199\n- 200 template\n-201 inline void SymmetricMatrixDependency::initRow(const Row& row, int\n-index)\n- 202 {\n- 203 using std::min;\n- 204 vals_.assign(row.size(), 0.0);\n- 205 assert(vals_.size()==row.size());\n- 206 valIter_=vals_.begin();\n- 207\n- 208 maxValue_ = min(- std::numeric_limits::max(), std::\n-numeric_limits::min());\n- 209 diagonal_=norm_(row[index]);\n- 210 row_ = index;\n- 211 }\n- 212\n- 213 template\n-214 inline void SymmetricMatrixDependency::examine(const ColIter& col)\n- 215 {\n- 216 using std::max;\n- 217 // skip positive offdiagonals if norm preserves sign of them.\n- 218 real_type eij = norm_(*col);\n- 219 if(!N::is_sign_preserving || eij<0) // || eji<0)\n- 220 {\n- 221 *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())\n-[col.index()]);\n- 222 maxValue_ = max(maxValue_, *valIter_);\n- 223 }else\n- 224 *valIter_ =0;\n- 225 ++valIter_;\n- 226 }\n- 227\n- 228 template\n- 229 template\n-230 inline void SymmetricMatrixDependency::examine(G&, const typename G::\n-EdgeIterator& edge, const ColIter&)\n- 231 {\n- 232 if(*valIter_ > alpha() * maxValue_) {\n- 233 edge.properties().setDepends();\n- 234 edge.properties().setInfluences();\n- 235 }\n- 236 ++valIter_;\n- 237 }\n- 238\n- 239 template\n-240 inline bool SymmetricMatrixDependency::isIsolated()\n- 241 {\n- 242 if(diagonal_==0)\n- 243 DUNE_THROW(Dune::ISTLError, \"No diagonal entry for row \"< rowSize;\n+ 200 std::vector copyrowSize;\n+ 201 std::vector backwardscopyrowSize;\n+ 202 RedistributeInterface interface;\n+ 203 bool setup_;\n+ 204 };\n+ 205\n+ 214 template\n+215 struct CommMatrixRowSize\n+ 216 {\n+ 217 // Make the default communication policy work.\n+218 typedef typename M::size_type value_type;\n+219 typedef typename M::size_type size_type;\n+ 220\n+226 CommMatrixRowSize(const M& m_, RI& rowsize_)\n+ 227 : matrix(m_), rowsize(rowsize_)\n+ 228 {}\n+229 const M& matrix;\n+230 RI& rowsize;\n+ 231\n+ 232 };\n+ 233\n+ 234\n+ 243 template\n+244 struct CommMatrixSparsityPattern\n+ 245 {\n+246 typedef typename M::size_type size_type;\n 247\n- 251 template\n-252 class Dependency : public Parameters\n- 253 {\n- 254 public:\n-258 typedef M Matrix;\n- 259\n-263 typedef N Norm;\n- 264\n-268 typedef typename Matrix::row_type Row;\n+254 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet&\n+idxset_, const I& aggidxset_)\n+ 255 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()\n+ 256 {}\n+ 257\n+265 CommMatrixSparsityPattern(const M& m_, const Dune::GlobalLookupIndexSet&\n+idxset_, const I& aggidxset_,\n+ 266 const std::vector& rowsize_)\n+ 267 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), sparsity\n+(aggidxset_.size()), rowsize(&rowsize_)\n+ 268 {}\n 269\n-273 typedef typename Matrix::ConstColIterator ColIter;\n- 274\n-275 void init(const Matrix* matrix);\n- 276\n-277 void initRow(const Row& row, int index);\n- 278\n-279 void examine(const ColIter& col);\n- 280\n- 281 template\n-282 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter&\n-col);\n- 283\n-284 bool isIsolated();\n- 285\n-286 Dependency(const Parameters& parms)\n- 287 : Parameters(parms)\n- 288 {}\n- 289\n-290 Dependency()\n- 291 : Parameters()\n- 292 {}\n- 293\n- 294 protected:\n-296 const Matrix* matrix_;\n-298 typedef typename Matrix::field_type field_type;\n-299 typedef typename FieldTraits::real_type real_type;\n-300 real_type maxValue_;\n-302 Norm norm_;\n-304 int row_;\n-306 real_type diagonal_;\n- 307 };\n- 308\n- 312 template\n-313 class SymmetricDependency : public Parameters\n- 314 {\n- 315 public:\n-319 typedef M Matrix;\n- 320\n-324 typedef N Norm;\n- 325\n-329 typedef typename Matrix::row_type Row;\n- 330\n-334 typedef typename Matrix::ConstColIterator ColIter;\n- 335\n-336 void init(const Matrix* matrix);\n- 337\n-338 void initRow(const Row& row, int index);\n- 339\n-340 void examine(const ColIter& col);\n- 341\n- 342 template\n-343 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter&\n-col);\n- 344\n-345 bool isIsolated();\n- 346\n- 347\n-348 SymmetricDependency(const Parameters& parms)\n- 349 : Parameters(parms)\n- 350 {}\n-351 SymmetricDependency()\n- 352 : Parameters()\n- 353 {}\n- 354\n- 355 protected:\n-357 const Matrix* matrix_;\n-359 typedef typename Matrix::field_type field_type;\n-360 typedef typename FieldTraits::real_type real_type;\n-361 real_type maxValue_;\n-363 Norm norm_;\n-365 int row_;\n-367 real_type diagonal_;\n- 368 private:\n- 369 void initRow(const Row& row, int index, const std::true_type&);\n- 370 void initRow(const Row& row, int index, const std::false_type&);\n- 371 };\n+276 void storeSparsityPattern(M& m)\n+ 277 {\n+ 278 // insert diagonal to overlap rows\n+ 279 typedef typename Dune::GlobalLookupIndexSet::const_iterator IIter;\n+ 280 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n+OwnerSet;\n+ 281 std::size_t nnz=0;\n+ 282#ifdef DEBUG_REPART\n+ 283 int rank;\n+ 284\n+ 285 MPI_Comm_rank(MPI_COMM_WORLD, &rank);\n+ 286#endif\n+ 287 for(IIter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i) {\n+ 288 if(!OwnerSet::contains(i->local().attribute())) {\n+ 289#ifdef DEBUG_REPART\n+ 290 std::cout<local()<local()].insert(i->local());\n+ 293 }\n+ 294\n+ 295 nnz+=sparsity[i->local()].size();\n+ 296 }\n+ 297 assert( aggidxset.size()==sparsity.size());\n+ 298\n+ 299 if(nnz>0) {\n+ 300 m.setSize(aggidxset.size(), aggidxset.size(), nnz);\n+ 301 m.setBuildMode(M::row_wise);\n+ 302 typename M::CreateIterator citer=m.createbegin();\n+ 303#ifdef DEBUG_REPART\n+ 304 std::size_t idx=0;\n+ 305 bool correct=true;\n+ 306 Dune::GlobalLookupIndexSet global(aggidxset);\n+ 307#endif\n+ 308 typedef typename std::vector >::const_iterator Iter;\n+ 309 for(Iter i=sparsity.begin(), end=sparsity.end(); i!=end; ++i, ++citer)\n+ 310 {\n+ 311 typedef typename std::set::const_iterator SIter;\n+ 312 for(SIter si=i->begin(), send=i->end(); si!=send; ++si)\n+ 313 citer.insert(*si);\n+ 314#ifdef DEBUG_REPART\n+ 315 if(i->find(idx)==i->end()) {\n+ 316 const typename I::IndexPair* gi=global.pair(idx);\n+ 317 assert(gi);\n+ 318 std::cout<global()<<\" attr=\"<local().attribute()<<\" \"<<\n+ 319 OwnerSet::contains(gi->local().attribute())<<\n+ 320 \" row size=\"<size()< >\n+add_sparsity)\n+ 341 {\n+ 342 for (unsigned int i = 0; i != sparsity.size(); ++i) {\n+ 343 if (add_sparsity[i].size() != 0) {\n+ 344 typedef std::set Set;\n+ 345 Set tmp_set;\n+ 346 std::insert_iterator tmp_insert (tmp_set, tmp_set.begin());\n+ 347 std::set_union(add_sparsity[i].begin(), add_sparsity[i].end(),\n+ 348 sparsity[i].begin(), sparsity[i].end(), tmp_insert);\n+ 349 sparsity[i].swap(tmp_set);\n+ 350 }\n+ 351 }\n+ 352 }\n+ 353\n+354 const M& matrix;\n+355 typedef Dune::GlobalLookupIndexSet LookupIndexSet;\n+356 const Dune::GlobalLookupIndexSet& idxset;\n+357 const I& aggidxset;\n+358 std::vector > sparsity;\n+359 const std::vector* rowsize;\n+ 360 };\n+ 361\n+ 362 template\n+363 struct CommPolicy >\n+ 364 {\n+365 typedef CommMatrixSparsityPattern Type;\n+ 366\n+371 typedef typename I::GlobalIndex IndexedType;\n 372\n- 377 template\n-378 class Diagonal\n- 379 {\n- 380 public:\n- 381 enum { /* @brief We preserve the sign.*/\n- 382 is_sign_preserving = true\n-383 };\n- 384\n- 389 template\n-390 typename FieldTraits::real_type operator()(const M&\n-m,\n- 391 [[maybe_unused]] typename std::enable_if_t::value>*\n-sfinae = nullptr) const\n- 392 {\n- 393 typedef typename M::field_type field_type;\n- 394 typedef typename FieldTraits::real_type real_type;\n- 395 static_assert( std::is_convertible::value,\n- 396 \"use of diagonal norm in AMG not implemented for complex field_type\");\n- 397 return m[N][N];\n- 398 // possible implementation for complex types: return signed_abs(m[N][N]);\n- 399 }\n- 400\n- 405 template\n-406 auto operator()(const M& m,\n- 407 typename std::enable_if_t::value>* sfinae = nullptr)\n-const\n- 408 {\n- 409 typedef typename FieldTraits::real_type real_type;\n- 410 static_assert( std::is_convertible::value,\n- 411 \"use of diagonal norm in AMG not implemented for complex field_type\");\n- 412 return m;\n- 413 // possible implementation for complex types: return signed_abs(m[N][N]);\n- 414 }\n- 415\n- 416 private:\n- 417\n- 419 template\n- 420 static T signed_abs(const T & v)\n- 421 {\n- 422 return v;\n- 423 }\n- 424\n- 426 template\n- 427 static T signed_abs(const std::complex & v)\n- 428 {\n- 429 // return sign * abs_value\n- 430 // in case of complex numbers this extends to using the csgn function to\n-determine the sign\n- 431 return csgn(v) * std::abs(v);\n- 432 }\n- 433\n- 435 template\n- 436 static T csgn(const T & v)\n- 437 {\n- 438 return (T(0) < v) - (v < T(0));\n- 439 }\n- 440\n- 442 template\n- 443 static T csgn(std::complex a)\n- 444 {\n- 445 return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());\n- 446 }\n- 447\n- 448 };\n- 449\n-454 class FirstDiagonal : public Diagonal<0>\n- 455 {};\n- 456\n-462 struct RowSum\n- 463 {\n- 464\n- 465 enum { /* @brief We preserve the sign.*/\n- 466 is_sign_preserving = false\n-467 };\n- 472 template\n-473 typename FieldTraits::real_type operator()(const M&\n-m) const\n+374 typedef VariableSize IndexedTypeFlag;\n+ 375\n+376 static typename M::size_type getSize(const Type& t, std::size_t i)\n+ 377 {\n+ 378 if(!t.rowsize)\n+ 379 return t.matrix[i].size();\n+ 380 else\n+ 381 {\n+ 382 assert((*t.rowsize)[i]>0);\n+ 383 return (*t.rowsize)[i];\n+ 384 }\n+ 385 }\n+ 386 };\n+ 387\n+ 394 template\n+395 struct CommMatrixRow\n+ 396 {\n+405 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet& idxset_, const I&\n+aggidxset_)\n+ 406 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize()\n+ 407 {}\n+ 408\n+412 CommMatrixRow(M& m_, const Dune::GlobalLookupIndexSet& idxset_, const I&\n+aggidxset_,\n+ 413 std::vector& rowsize_)\n+ 414 : matrix(m_), idxset(idxset_), aggidxset(aggidxset_), rowsize(&rowsize_)\n+ 415 {}\n+421 void setOverlapRowsToDirichlet()\n+ 422 {\n+ 423 typedef typename Dune::GlobalLookupIndexSet::const_iterator Iter;\n+ 424 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n+OwnerSet;\n+ 425\n+ 426 for(Iter i= aggidxset.begin(), end=aggidxset.end(); i!=end; ++i)\n+ 427 if(!OwnerSet::contains(i->local().attribute())) {\n+ 428 // Set to Dirchlet\n+ 429 typedef typename M::ColIterator CIter;\n+ 430 for(CIter c=matrix[i->local()].begin(), cend= matrix[i->local()].end();\n+ 431 c!= cend; ++c)\n+ 432 {\n+ 433 *c=0;\n+ 434 if(c.index()==i->local()) {\n+ 435 auto setDiagonal = [](auto&& scalarOrMatrix, const auto& value) {\n+ 436 auto&& matrixView = Dune::Impl::asMatrix(scalarOrMatrix);\n+ 437 for (auto rowIt = matrixView.begin(); rowIt != matrixView.end(); ++rowIt)\n+ 438 (*rowIt)[rowIt.index()] = value;\n+ 439 };\n+ 440 setDiagonal(*c, 1);\n+ 441 }\n+ 442 }\n+ 443 }\n+ 444 }\n+446 M& matrix;\n+448 const Dune::GlobalLookupIndexSet& idxset;\n+450 const I& aggidxset;\n+452 std::vector* rowsize; // row sizes differ from sender side in\n+overlap!\n+ 453 };\n+ 454\n+ 455 template\n+456 struct CommPolicy >\n+ 457 {\n+458 typedef CommMatrixRow Type;\n+ 459\n+464 typedef std::pair\n+IndexedType;\n+ 465\n+467 typedef VariableSize IndexedTypeFlag;\n+ 468\n+469 static std::size_t getSize(const Type& t, std::size_t i)\n+ 470 {\n+ 471 if(!t.rowsize)\n+ 472 return t.matrix[i].size();\n+ 473 else\n 474 {\n- 475 return m.infinity_norm();\n- 476 }\n- 477 };\n- 478\n-479 struct FrobeniusNorm\n- 480 {\n- 481\n- 482 enum { /* @brief We preserve the sign.*/\n- 483 is_sign_preserving = false\n-484 };\n- 489 template\n-490 typename FieldTraits::real_type operator()(const M&\n-m) const\n+ 475 assert((*t.rowsize)[i]>0);\n+ 476 return (*t.rowsize)[i];\n+ 477 }\n+ 478 }\n+ 479 };\n+ 480\n+ 481 template\n+482 struct MatrixRowSizeGatherScatter\n+ 483 {\n+484 typedef CommMatrixRowSize Container;\n+ 485\n+486 static const typename M::size_type gather(const Container& cont, std::\n+size_t i)\n+ 487 {\n+ 488 return cont.matrix[i].size();\n+ 489 }\n+490 static void scatter(Container& cont, const typename M::size_type& rowsize,\n+std::size_t i)\n 491 {\n- 492 return m.frobenius_norm();\n- 493 }\n- 494 };\n-495 struct AlwaysOneNorm\n- 496 {\n+ 492 assert(rowsize);\n+ 493 cont.rowsize.getRowSize(i)=rowsize;\n+ 494 }\n+ 495\n+ 496 };\n 497\n- 498 enum { /* @brief We preserve the sign.*/\n- 499 is_sign_preserving = false\n-500 };\n- 505 template\n-506 typename FieldTraits::real_type operator()(const M&\n-m) const\n- 507 {\n- 508 return 1;\n- 509 }\n- 510 };\n- 517 template\n-518 class SymmetricCriterion : public\n-AggregationCriterion >\n- 519 {\n- 520 public:\n-521 SymmetricCriterion(const Parameters& parms)\n- 522 : AggregationCriterion >(parms)\n- 523 {}\n-524 SymmetricCriterion()\n- 525 {}\n- 526 };\n- 527\n- 528\n- 537 template\n-538 class UnSymmetricCriterion : public AggregationCriterion\n->\n- 539 {\n- 540 public:\n-541 UnSymmetricCriterion(const Parameters& parms)\n- 542 : AggregationCriterion >(parms)\n- 543 {}\n-544 UnSymmetricCriterion()\n- 545 {}\n- 546 };\n- 547 // forward declaration\n- 548 template class Aggregator;\n- 549\n- 550\n- 558 template\n-559 class AggregatesMap\n- 560 {\n- 561 public:\n- 562\n-566 static const V UNAGGREGATED;\n- 567\n-571 static const V ISOLATED;\n-575 typedef V VertexDescriptor;\n- 576\n-580 typedef V AggregateDescriptor;\n- 581\n-586 typedef PoolAllocator Allocator;\n- 587\n-592 typedef SLList VertexList;\n- 593\n-597 class DummyEdgeVisitor\n- 598 {\n- 599 public:\n- 600 template\n-601 void operator()([[maybe_unused]] const EdgeIterator& edge) const\n- 602 {}\n- 603 };\n- 604\n- 605\n-609 AggregatesMap();\n- 610\n-616 AggregatesMap(std::size_t noVertices);\n- 617\n-621 ~AggregatesMap();\n- 622\n- 634 template\n-635 std::tuple buildAggregates(const M& matrix, G& graph,\n-const C& criterion,\n- 636 bool finestLevel);\n- 637\n- 655 template\n-656 std::size_t breadthFirstSearch(const VertexDescriptor& start,\n- 657 const AggregateDescriptor& aggregate,\n- 658 const G& graph,\n- 659 F& aggregateVisitor,\n- 660 VM& visitedMap) const;\n+ 498 template\n+499 struct MatrixCopyRowSizeGatherScatter\n+ 500 {\n+501 typedef CommMatrixRowSize Container;\n+ 502\n+503 static const typename M::size_type gather(const Container& cont, std::\n+size_t i)\n+ 504 {\n+ 505 return cont.matrix[i].size();\n+ 506 }\n+507 static void scatter(Container& cont, const typename M::size_type& rowsize,\n+std::size_t i)\n+ 508 {\n+ 509 assert(rowsize);\n+ 510 if (rowsize > cont.rowsize.getCopyRowSize(i))\n+ 511 cont.rowsize.getCopyRowSize(i)=rowsize;\n+ 512 }\n+ 513\n+ 514 };\n+ 515\n+ 516 template\n+517 struct MatrixSparsityPatternGatherScatter\n+ 518 {\n+519 typedef typename I::GlobalIndex GlobalIndex;\n+520 typedef CommMatrixSparsityPattern Container;\n+521 typedef typename M::ConstColIterator ColIter;\n+ 522\n+523 static ColIter col;\n+524 static GlobalIndex numlimits;\n+ 525\n+526 static const GlobalIndex& gather(const Container& cont, std::size_t i,\n+std::size_t j)\n+ 527 {\n+ 528 if(j==0)\n+ 529 col=cont.matrix[i].begin();\n+ 530 else if (col!=cont.matrix[i].end())\n+ 531 ++col;\n+ 532\n+ 533 //copy communication: different row sizes for copy rows with the same\n+global index\n+ 534 //are possible. If all values of current matrix row are sent, send\n+ 535 //std::numeric_limits::max()\n+ 536 //and receiver will ignore it.\n+ 537 if (col==cont.matrix[i].end()) {\n+ 538 numlimits = std::numeric_limits::max();\n+ 539 return numlimits;\n+ 540 }\n+ 541 else {\n+ 542 const typename I::IndexPair* index=cont.idxset.pair(col.index());\n+ 543 assert(index);\n+ 544 // Only send index if col is no ghost\n+ 545 if ( index->local().attribute() != 2)\n+ 546 return index->global();\n+ 547 else {\n+ 548 numlimits = std::numeric_limits::max();\n+ 549 return numlimits;\n+ 550 }\n+ 551 }\n+ 552 }\n+553 static void scatter(Container& cont, const GlobalIndex& gi, std::size_t i,\n+[[maybe_unused]] std::size_t j)\n+ 554 {\n+ 555 try{\n+ 556 if (gi != std::numeric_limits::max()) {\n+ 557 const typename I::IndexPair& ip=cont.aggidxset.at(gi);\n+ 558 assert(ip.global()==gi);\n+ 559 std::size_t column = ip.local();\n+ 560 cont.sparsity[i].insert(column);\n+ 561\n+ 562 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n+OwnerSet;\n+ 563 if(!OwnerSet::contains(ip.local().attribute()))\n+ 564 // preserve symmetry for overlap\n+ 565 cont.sparsity[column].insert(i);\n+ 566 }\n+ 567 }\n+ 568 catch(const Dune::RangeError&) {\n+ 569 // Entry not present in the new index set. Ignore!\n+ 570#ifdef DEBUG_REPART\n+ 571 typedef typename Container::LookupIndexSet GlobalLookup;\n+ 572 typedef typename GlobalLookup::IndexPair IndexPair;\n+ 573 typedef typename Dune::OwnerOverlapCopyCommunication::OwnerSet\n+OwnerSet;\n+ 574\n+ 575 GlobalLookup lookup(cont.aggidxset);\n+ 576 const IndexPair* pi=lookup.pair(i);\n+ 577 assert(pi);\n+ 578 if(OwnerSet::contains(pi->local().attribute())) {\n+ 579 int rank;\n+ 580 MPI_Comm_rank(MPI_COMM_WORLD,&rank);\n+ 581 std::cout<global()<\n+ 591 typename MatrixSparsityPatternGatherScatter::ColIter\n+MatrixSparsityPatternGatherScatter::col;\n+ 592\n+ 593 template\n+ 594 typename MatrixSparsityPatternGatherScatter::GlobalIndex\n+MatrixSparsityPatternGatherScatter::numlimits;\n+ 595\n+ 596\n+ 597 template\n+598 struct MatrixRowGatherScatter\n+ 599 {\n+600 typedef typename I::GlobalIndex GlobalIndex;\n+601 typedef CommMatrixRow Container;\n+602 typedef typename M::ConstColIterator ColIter;\n+603 typedef typename std::pair Data;\n+604 static ColIter col;\n+605 static Data datastore;\n+606 static GlobalIndex numlimits;\n+ 607\n+608 static const Data& gather(const Container& cont, std::size_t i, std::size_t\n+j)\n+ 609 {\n+ 610 if(j==0)\n+ 611 col=cont.matrix[i].begin();\n+ 612 else if (col!=cont.matrix[i].end())\n+ 613 ++col;\n+ 614 // copy communication: different row sizes for copy rows with the same\n+global index\n+ 615 // are possible. If all values of current matrix row are sent, send\n+ 616 // std::numeric_limits::max()\n+ 617 // and receiver will ignore it.\n+ 618 if (col==cont.matrix[i].end()) {\n+ 619 numlimits = std::numeric_limits::max();\n+ 620 datastore = Data(numlimits,*col);\n+ 621 return datastore;\n+ 622 }\n+ 623 else {\n+ 624 // convert local column index to global index\n+ 625 const typename I::IndexPair* index=cont.idxset.pair(col.index());\n+ 626 assert(index);\n+ 627 // Store the data to prevent reference to temporary\n+ 628 // Only send index if col is no ghost\n+ 629 if ( index->local().attribute() != 2)\n+ 630 datastore = Data(index->global(),*col);\n+ 631 else {\n+ 632 numlimits = std::numeric_limits::max();\n+ 633 datastore = Data(numlimits,*col);\n+ 634 }\n+ 635 return datastore;\n+ 636 }\n+ 637 }\n+638 static void scatter(Container& cont, const Data& data, std::size_t i, [\n+[maybe_unused]] std::size_t j)\n+ 639 {\n+ 640 try{\n+ 641 if (data.first != std::numeric_limits::max()) {\n+ 642 typename M::size_type column=cont.aggidxset.at(data.first).local();\n+ 643 cont.matrix[i][column]=data.second;\n+ 644 }\n+ 645 }\n+ 646 catch(const Dune::RangeError&) {\n+ 647 // This an overlap row and might therefore lack some entries!\n+ 648 }\n+ 649\n+ 650 }\n+ 651 };\n+ 652\n+ 653 template\n+ 654 typename MatrixRowGatherScatter::ColIter\n+MatrixRowGatherScatter::col;\n+ 655\n+ 656 template\n+ 657 typename MatrixRowGatherScatter::Data MatrixRowGatherScatter::\n+datastore;\n+ 658\n+ 659 template\n+ 660 typename MatrixRowGatherScatter::GlobalIndex\n+MatrixRowGatherScatter::numlimits;\n 661\n- 685 template\n-686 std::size_t breadthFirstSearch(const VertexDescriptor& start,\n- 687 const AggregateDescriptor& aggregate,\n- 688 const G& graph, L& visited, F1& aggregateVisitor,\n- 689 F2& nonAggregateVisitor,\n- 690 VM& visitedMap) const;\n- 691\n-697 void allocate(std::size_t noVertices);\n- 698\n-702 std::size_t noVertices() const;\n- 703\n-707 void free();\n- 708\n-714 AggregateDescriptor& operator[](const VertexDescriptor& v);\n- 715\n-721 const AggregateDescriptor& operator[](const VertexDescriptor& v) const;\n- 722\n-723 typedef const AggregateDescriptor* const_iterator;\n+ 662 template\n+663 void redistributeSparsityPattern(M& origMatrix, M& newMatrix, C& origComm,\n+C& newComm,\n+ 664 RedistributeInformation& ri)\n+ 665 {\n+ 666 typename C::CopySet copyflags;\n+ 667 typename C::OwnerSet ownerflags;\n+ 668 typedef typename C::ParallelIndexSet IndexSet;\n+ 669 typedef RedistributeInformation RI;\n+ 670 std::vector rowsize(newComm.indexSet().size(), 0);\n+ 671 std::vector copyrowsize(newComm.indexSet().size(),\n+0);\n+ 672 std::vector backwardscopyrowsize(origComm.indexSet\n+().size(), 0);\n+ 673\n+ 674 // get owner rowsizes\n+ 675 CommMatrixRowSize commRowSize(origMatrix, ri);\n+ 676 ri.template redistribute >\n+(commRowSize,commRowSize);\n+ 677\n+ 678 origComm.buildGlobalLookup();\n+ 679\n+ 680 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n+ 681 rowsize[i] = ri.getRowSize(i);\n+ 682 }\n+ 683 // get sparsity pattern from owner rows\n+ 684 CommMatrixSparsityPattern\n+ 685 origsp(origMatrix, origComm.globalLookup(), newComm.indexSet());\n+ 686 CommMatrixSparsityPattern\n+ 687 newsp(origMatrix, origComm.globalLookup(), newComm.indexSet(), rowsize);\n+ 688\n+ 689 ri.template redistribute >\n+(origsp,newsp);\n+ 690\n+ 691 // build copy to owner interface to get missing matrix values for novlp\n+case\n+ 692 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n+{\n+ 693 RemoteIndices *ris = new RemoteIndices\n+(origComm.indexSet(),\n+ 694 newComm.indexSet(),\n+ 695 origComm.communicator());\n+ 696 ris->template rebuild();\n+ 697\n+ 698 ri.getInterface().free();\n+ 699 ri.getInterface().build(*ris,copyflags,ownerflags);\n+ 700\n+ 701 // get copy rowsizes\n+ 702 CommMatrixRowSize commRowSize_copy(origMatrix, ri);\n+ 703 ri.template redistribute >\n+(commRowSize_copy,\n+ 704 commRowSize_copy);\n+ 705\n+ 706 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n+ 707 copyrowsize[i] = ri.getCopyRowSize(i);\n+ 708 }\n+ 709 //get copy rowsizes for sender\n+ 710 ri.redistributeBackward(backwardscopyrowsize,copyrowsize);\n+ 711 for (std::size_t i=0; i < origComm.indexSet().size(); i++) {\n+ 712 ri.getBackwardsCopyRowSize(i) = backwardscopyrowsize[i];\n+ 713 }\n+ 714\n+ 715 // get sparsity pattern from copy rows\n+ 716 CommMatrixSparsityPattern origsp_copy(origMatrix,\n+ 717 origComm.globalLookup(),\n+ 718 newComm.indexSet(),\n+ 719 backwardscopyrowsize);\n+ 720 CommMatrixSparsityPattern newsp_copy(origMatrix,\n+origComm.globalLookup(),\n+ 721 newComm.indexSet(), copyrowsize);\n+ 722 ri.template redistribute >\n+(origsp_copy,\n+ 723 newsp_copy);\n 724\n-725 const_iterator begin() const\n- 726 {\n- 727 return aggregates_;\n- 728 }\n- 729\n-730 const_iterator end() const\n- 731 {\n- 732 return aggregates_+noVertices();\n- 733 }\n- 734\n-735 typedef AggregateDescriptor* iterator;\n- 736\n-737 iterator begin()\n+ 725 newsp.completeSparsityPattern(newsp_copy.sparsity);\n+ 726 newsp.storeSparsityPattern(newMatrix);\n+ 727 }\n+ 728 else\n+ 729 newsp.storeSparsityPattern(newMatrix);\n+ 730\n+ 731#ifdef DUNE_ISTL_WITH_CHECKING\n+ 732 // Check for symmetry\n+ 733 int ret=0;\n+ 734 typedef typename M::ConstRowIterator RIter;\n+ 735 for(RIter row=newMatrix.begin(), rend=newMatrix.end(); row != rend; ++row)\n+{\n+ 736 typedef typename M::ConstColIterator CIter;\n+ 737 for(CIter col=row->begin(), cend=row->end(); col!=cend; ++col)\n 738 {\n- 739 return aggregates_;\n- 740 }\n- 741\n-742 iterator end()\n- 743 {\n- 744 return aggregates_+noVertices();\n- 745 }\n- 746 private:\n- 748 AggregatesMap(const AggregatesMap&) = delete;\n- 750 AggregatesMap& operator=(const AggregatesMap&) = delete;\n- 751\n- 755 AggregateDescriptor* aggregates_;\n- 756\n- 760 std::size_t noVertices_;\n- 761 };\n- 762\n- 766 template\n-767 void buildDependency(G& graph,\n- 768 const typename C::Matrix& matrix,\n- 769 C criterion,\n- 770 bool finestLevel);\n- 771\n- 776 template\n-777 class Aggregate\n- 778 {\n- 779\n- 780 public:\n- 781\n- 782 /***\n- 783 * @brief The type of the matrix graph we work with.\n- 784 */\n-785 typedef G MatrixGraph;\n-789 typedef typename MatrixGraph::VertexDescriptor Vertex;\n- 790\n-795 typedef PoolAllocator Allocator;\n- 796\n-801 typedef S VertexSet;\n- 802\n-804 typedef typename VertexSet::const_iterator const_iterator;\n- 805\n-809 typedef std::size_t* SphereMap;\n- 810\n-819 Aggregate(MatrixGraph& graph, AggregatesMap& aggregates,\n- 820 VertexSet& connectivity, std::vector& front_);\n- 821\n-822 void invalidate()\n- 823 {\n- 824 --id_;\n- 825 }\n- 826\n-833 void reconstruct(const Vertex& vertex);\n- 834\n-838 void seed(const Vertex& vertex);\n- 839\n-843 void add(const Vertex& vertex);\n- 844\n-845 void add(std::vector& vertex);\n-849 void clear();\n- 850\n-854 typename VertexSet::size_type size();\n-858 typename VertexSet::size_type connectSize();\n- 859\n-863 int id();\n- 864\n-866 const_iterator begin() const;\n- 867\n-869 const_iterator end() const;\n- 870\n- 871 private:\n- 875 VertexSet vertices_;\n- 876\n- 881 int id_;\n- 882\n- 886 MatrixGraph& graph_;\n- 887\n- 891 AggregatesMap& aggregates_;\n- 892\n- 896 VertexSet& connected_;\n- 897\n- 901 std::vector& front_;\n- 902 };\n- 903\n- 907 template\n-908 class Aggregator\n- 909 {\n- 910 public:\n- 911\n-915 typedef G MatrixGraph;\n- 916\n-920 typedef typename MatrixGraph::VertexDescriptor Vertex;\n- 921\n-923 typedef typename MatrixGraph::VertexDescriptor AggregateDescriptor;\n- 924\n-928 Aggregator();\n- 929\n-933 ~Aggregator();\n- 934\n- 951 template\n-952 std::tuple build(const M& m, G& graph,\n- 953 AggregatesMap& aggregates, const C& c,\n- 954 bool finestLevel);\n- 955 private:\n- 960 typedef PoolAllocator Allocator;\n- 961\n- 965 typedef SLList VertexList;\n- 966\n- 970 typedef std::set,Allocator> VertexSet;\n- 971\n- 975 typedef std::size_t* SphereMap;\n- 976\n- 980 MatrixGraph* graph_;\n- 981\n- 985 Aggregate* aggregate_;\n- 986\n- 990 std::vector front_;\n- 991\n- 995 VertexSet connected_;\n- 996\n- 1000 int size_;\n- 1001\n- 1005 class Stack\n- 1006 {\n- 1007 public:\n-1008 static const Vertex NullEntry;\n- 1009\n-1010 Stack(const MatrixGraph& graph,\n- 1011 const Aggregator& aggregatesBuilder,\n- 1012 const AggregatesMap& aggregates);\n-1013 ~Stack();\n-1014 Vertex pop();\n- 1015 private:\n- 1016 enum { N = 1300000 };\n- 1017\n- 1019 const MatrixGraph& graph_;\n- 1021 const Aggregator& aggregatesBuilder_;\n- 1023 const AggregatesMap& aggregates_;\n- 1025 int size_;\n- 1026 Vertex maxSize_;\n- 1028 typename MatrixGraph::ConstVertexIterator begin_;\n- 1029 typename MatrixGraph::ConstVertexIterator end_;\n- 1030\n- 1032 Vertex* vals_;\n- 1033\n- 1034 };\n- 1035\n-1036 friend class Stack;\n- 1037\n- 1048 template\n- 1049 void visitAggregateNeighbours(const Vertex& vertex, const\n-AggregateDescriptor& aggregate,\n- 1050 const AggregatesMap& aggregates,\n- 1051 V& visitor) const;\n- 1052\n- 1057 template\n- 1058 class AggregateVisitor\n- 1059 {\n- 1060 public:\n-1064 typedef V Visitor;\n-1072 AggregateVisitor(const AggregatesMap& aggregates, const\n-AggregateDescriptor& aggregate,\n- 1073 Visitor& visitor);\n- 1074\n-1081 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1082\n- 1083 private:\n- 1085 const AggregatesMap& aggregates_;\n- 1087 AggregateDescriptor aggregate_;\n- 1089 Visitor* visitor_;\n- 1090 };\n- 1091\n- 1095 class Counter\n- 1096 {\n- 1097 public:\n-1099 Counter();\n-1101 int value();\n- 1102\n- 1103 protected:\n-1105 void increment();\n-1107 void decrement();\n- 1108\n- 1109 private:\n- 1110 int count_;\n- 1111 };\n- 1112\n- 1113\n- 1118 class FrontNeighbourCounter : public Counter\n- 1119 {\n- 1120 public:\n-1125 FrontNeighbourCounter(const MatrixGraph& front);\n- 1126\n-1127 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1128\n- 1129 private:\n- 1130 const MatrixGraph& graph_;\n- 1131 };\n- 1132\n- 1137 int noFrontNeighbours(const Vertex& vertex) const;\n- 1138\n- 1142 class TwoWayCounter : public Counter\n- 1143 {\n- 1144 public:\n-1145 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1146 };\n- 1147\n- 1159 int twoWayConnections(const Vertex&, const AggregateDescriptor&\n-aggregate,\n- 1160 const AggregatesMap& aggregates) const;\n- 1161\n- 1165 class OneWayCounter : public Counter\n- 1166 {\n- 1167 public:\n-1168 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1169 };\n- 1170\n- 1182 int oneWayConnections(const Vertex&, const AggregateDescriptor&\n-aggregate,\n- 1183 const AggregatesMap& aggregates) const;\n- 1184\n- 1191 class ConnectivityCounter : public Counter\n- 1192 {\n- 1193 public:\n-1200 ConnectivityCounter(const VertexSet& connected, const\n-AggregatesMap& aggregates);\n- 1201\n-1202 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1203\n- 1204 private:\n- 1206 const VertexSet& connected_;\n- 1208 const AggregatesMap& aggregates_;\n- 1209\n- 1210 };\n- 1211\n- 1223 double connectivity(const Vertex& vertex, const AggregatesMap&\n-aggregates) const;\n- 1231 bool connected(const Vertex& vertex, const AggregateDescriptor&\n-aggregate,\n- 1232 const AggregatesMap& aggregates) const;\n- 1233\n- 1241 bool connected(const Vertex& vertex, const SLList&\n-aggregateList,\n- 1242 const AggregatesMap& aggregates) const;\n- 1243\n- 1251 class DependencyCounter : public Counter\n- 1252 {\n- 1253 public:\n-1257 DependencyCounter();\n- 1258\n-1259 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1260 };\n- 1261\n- 1268 class FrontMarker\n- 1269 {\n- 1270 public:\n-1277 FrontMarker(std::vector& front, MatrixGraph& graph);\n- 1278\n-1279 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n- 1280\n- 1281 private:\n- 1283 std::vector& front_;\n- 1285 MatrixGraph& graph_;\n- 1286 };\n- 1287\n- 1291 void unmarkFront();\n- 1292\n- 1307 int unusedNeighbours(const Vertex& vertex, const AggregatesMap&\n-aggregates) const;\n- 1308\n- 1322 std::pair neighbours(const Vertex& vertex,\n- 1323 const AggregateDescriptor& aggregate,\n- 1324 const AggregatesMap& aggregates) const;\n- 1341 int aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor&\n-aggregate, const AggregatesMap& aggregates) const;\n- 1342\n- 1350 bool admissible(const Vertex& vertex, const AggregateDescriptor&\n-aggregate, const AggregatesMap& aggregates) const;\n- 1351\n- 1359 std::size_t distance(const Vertex& vertex, const AggregatesMap&\n-aggregates);\n- 1360\n- 1369 Vertex mergeNeighbour(const Vertex& vertex, const AggregatesMap&\n-aggregates) const;\n- 1370\n- 1379 void nonisoNeighbourAggregate(const Vertex& vertex,\n- 1380 const AggregatesMap& aggregates,\n- 1381 SLList& neighbours) const;\n- 1382\n- 1390 template\n- 1391 void growAggregate(const Vertex& vertex, const AggregatesMap&\n-aggregates, const C& c);\n- 1392 template\n- 1393 void growIsolatedAggregate(const Vertex& vertex, const\n-AggregatesMap& aggregates, const C& c);\n- 1394 };\n- 1395\n- 1396#ifndef DOXYGEN\n- 1397\n- 1398 template\n- 1399 inline void SymmetricDependency::init(const Matrix* matrix)\n- 1400 {\n- 1401 matrix_ = matrix;\n- 1402 }\n- 1403\n- 1404 template\n- 1405 inline void SymmetricDependency::initRow(const Row& row, int index)\n- 1406 {\n- 1407 initRow(row, index, std::is_convertible());\n- 1408 }\n- 1409\n- 1410 template\n- 1411 inline void SymmetricDependency::initRow(const Row& row, int index,\n-const std::false_type&)\n- 1412 {\n- 1413 DUNE_THROW(InvalidStateException, \"field_type needs to convertible to\n-real_type\");\n- 1414 }\n- 1415\n- 1416 template\n- 1417 inline void SymmetricDependency::initRow([[maybe_unused]] const Row&\n-row, int index, const std::true_type&)\n- 1418 {\n- 1419 using std::min;\n- 1420 maxValue_ = min(- std::numeric_limits::max\n-(), std::numeric_limits::min());\n- 1421 row_ = index;\n- 1422 diagonal_ = norm_(matrix_->operator[](row_)[row_]);\n- 1423 }\n- 1424\n- 1425 template\n- 1426 inline void SymmetricDependency::examine(const ColIter& col)\n- 1427 {\n- 1428 using std::max;\n- 1429 real_type eij = norm_(*col);\n- 1430 typename Matrix::ConstColIterator opposite_entry =\n- 1431 matrix_->operator[](col.index()).find(row_);\n- 1432 if ( opposite_entry == matrix_->operator[](col.index()).end() )\n- 1433 {\n- 1434 // Consider this a weak connection we disregard.\n- 1435 return;\n- 1436 }\n- 1437 real_type eji = norm_(*opposite_entry);\n- 1438\n- 1439 // skip positive offdiagonals if norm preserves sign of them.\n- 1440 if(!N::is_sign_preserving || eij<0 || eji<0)\n- 1441 maxValue_ = max(maxValue_,\n- 1442 eij /diagonal_ * eji/\n- 1443 norm_(matrix_->operator[](col.index())[col.index()]));\n- 1444 }\n- 1445\n- 1446 template\n- 1447 template\n- 1448 inline void SymmetricDependency::examine(G& graph, const typename\n-G::EdgeIterator& edge, const ColIter& col)\n- 1449 {\n- 1450 real_type eij = norm_(*col);\n- 1451 typename Matrix::ConstColIterator opposite_entry =\n- 1452 matrix_->operator[](col.index()).find(row_);\n- 1453\n- 1454 if ( opposite_entry == matrix_->operator[](col.index()).end() )\n- 1455 {\n- 1456 // Consider this as a weak connection we disregard.\n- 1457 return;\n- 1458 }\n- 1459 real_type eji = norm_(*opposite_entry);\n- 1460 // skip positve offdiagonals if norm preserves sign of them.\n- 1461 if(!N::is_sign_preserving || (eij<0 || eji<0))\n- 1462 if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *\n- 1463 eij/ diagonal_ > alpha() * maxValue_) {\n- 1464 edge.properties().setDepends();\n- 1465 edge.properties().setInfluences();\n- 1466 typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target\n-(), edge.source());\n- 1467 other.setInfluences();\n- 1468 other.setDepends();\n- 1469 }\n- 1470 }\n- 1471\n- 1472 template\n- 1473 inline bool SymmetricDependency::isIsolated()\n- 1474 {\n- 1475 return maxValue_ < beta();\n- 1476 }\n- 1477\n- 1478\n- 1479 template\n- 1480 inline void Dependency::init(const Matrix* matrix)\n- 1481 {\n- 1482 matrix_ = matrix;\n- 1483 }\n- 1484\n- 1485 template\n- 1486 inline void Dependency::initRow([[maybe_unused]] const Row& row, int\n-index)\n- 1487 {\n- 1488 using std::min;\n- 1489 maxValue_ = min(- std::numeric_limits::max(), std::\n-numeric_limits::min());\n- 1490 row_ = index;\n- 1491 diagonal_ = norm_(matrix_->operator[](row_)[row_]);\n- 1492 }\n- 1493\n- 1494 template\n- 1495 inline void Dependency::examine(const ColIter& col)\n- 1496 {\n- 1497 using std::max;\n- 1498 maxValue_ = max(maxValue_, -norm_(*col));\n- 1499 }\n- 1500\n- 1501 template\n- 1502 template\n- 1503 inline void Dependency::examine(G& graph, const typename G::\n-EdgeIterator& edge, const ColIter& col)\n- 1504 {\n- 1505 if(-norm_(*col) >= maxValue_ * alpha()) {\n- 1506 edge.properties().setDepends();\n- 1507 typedef typename G::EdgeDescriptor ED;\n- 1508 ED e= graph.findEdge(edge.target(), edge.source());\n- 1509 if(e!=std::numeric_limits::max())\n- 1510 {\n- 1511 typename G::EdgeProperties& other = graph.getEdgeProperties(e);\n- 1512 other.setInfluences();\n- 1513 }\n- 1514 }\n- 1515 }\n- 1516\n- 1517 template\n- 1518 inline bool Dependency::isIsolated()\n- 1519 {\n- 1520 return maxValue_ < beta() * diagonal_;\n- 1521 }\n- 1522\n- 1523 template\n- 1524 Aggregate::Aggregate(MatrixGraph& graph, AggregatesMap&\n-aggregates,\n- 1525 VertexSet& connected, std::vector& front)\n- 1526 : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),\n- 1527 connected_(connected), front_(front)\n- 1528 {}\n- 1529\n- 1530 template\n- 1531 void Aggregate::reconstruct(const Vertex& vertex)\n- 1532 {\n- 1533 /*\n- 1534 vertices_.push_back(vertex);\n- 1535 typedef typename VertexList::const_iterator iterator;\n- 1536 iterator begin = vertices_.begin();\n- 1537 iterator end = vertices_.end();*/\n- 1538 throw \"Not yet implemented\";\n- 1539\n- 1540 // while(begin!=end){\n- 1541 //for();\n- 1542 // }\n- 1543\n- 1544 }\n- 1545\n- 1546 template\n- 1547 inline void Aggregate::seed(const Vertex& vertex)\n- 1548 {\n- 1549 dvverb<<\"Connected cleared\"<\n- 1560 inline void Aggregate::add(const Vertex& vertex)\n- 1561 {\n- 1562 vertices_.insert(vertex);\n- 1563 aggregates_[vertex]=id_;\n- 1564 if(front_.size())\n- 1565 front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));\n- 1566\n- 1567\n- 1568 typedef typename MatrixGraph::ConstEdgeIterator iterator;\n- 1569 const iterator end = graph_.endEdges(vertex);\n- 1570 for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {\n- 1571 dvverb << \" Inserting \"<::UNAGGREGATED &&\n- 1575 !graph_.getVertexProperties(edge.target()).front())\n- 1576 {\n- 1577 front_.push_back(edge.target());\n- 1578 graph_.getVertexProperties(edge.target()).setFront();\n- 1579 }\n- 1580 }\n- 1581 dvverb <\n- 1586 inline void Aggregate::add(std::vector& vertices)\n- 1587 {\n- 1588#ifndef NDEBUG\n- 1589 std::size_t oldsize = vertices_.size();\n- 1590#endif\n- 1591 typedef typename std::vector::iterator Iterator;\n- 1592\n- 1593 typedef typename VertexSet::iterator SIterator;\n- 1594\n- 1595 SIterator pos=vertices_.begin();\n- 1596 std::vector newFront;\n- 1597 newFront.reserve(front_.capacity());\n- 1598\n- 1599 std::set_difference(front_.begin(), front_.end(), vertices.begin(),\n-vertices.end(),\n- 1600 std::back_inserter(newFront));\n- 1601 front_=newFront;\n- 1602\n- 1603 for(Iterator vertex=vertices.begin(); vertex != vertices.end(); ++vertex)\n- 1604 {\n- 1605 pos=vertices_.insert(pos,*vertex);\n- 1606 vertices_.insert(*vertex);\n- 1607 graph_.getVertexProperties(*vertex).resetFront(); // Not a front node any\n-more.\n- 1608 aggregates_[*vertex]=id_;\n- 1609\n- 1610 typedef typename MatrixGraph::ConstEdgeIterator iterator;\n- 1611 const iterator end = graph_.endEdges(*vertex);\n- 1612 for(iterator edge = graph_.beginEdges(*vertex); edge != end; ++edge) {\n- 1613 dvverb << \" Inserting \"<::UNAGGREGATED &&\n- 1616 !graph_.getVertexProperties(edge.target()).front())\n- 1617 {\n- 1618 front_.push_back(edge.target());\n- 1619 graph_.getVertexProperties(edge.target()).setFront();\n- 1620 }\n- 1621 dvverb <<\" size=\"<\n- 1629 inline void Aggregate::clear()\n- 1630 {\n- 1631 vertices_.clear();\n- 1632 connected_.clear();\n- 1633 id_=-1;\n- 1634 }\n- 1635\n- 1636 template\n- 1637 inline typename Aggregate::VertexSet::size_type\n- 1638 Aggregate::size()\n- 1639 {\n- 1640 return vertices_.size();\n- 1641 }\n- 1642\n- 1643 template\n- 1644 inline typename Aggregate::VertexSet::size_type\n- 1645 Aggregate::connectSize()\n- 1646 {\n- 1647 return connected_.size();\n- 1648 }\n- 1649\n- 1650 template\n- 1651 inline int Aggregate::id()\n- 1652 {\n- 1653 return id_;\n- 1654 }\n- 1655\n- 1656 template\n- 1657 inline typename Aggregate::const_iterator Aggregate::begin()\n-const\n- 1658 {\n- 1659 return vertices_.begin();\n- 1660 }\n- 1661\n- 1662 template\n- 1663 inline typename Aggregate::const_iterator Aggregate::end()\n-const\n- 1664 {\n- 1665 return vertices_.end();\n- 1666 }\n- 1667\n- 1668 template\n- 1669 const V AggregatesMap::UNAGGREGATED = std::numeric_limits::max();\n- 1670\n- 1671 template\n- 1672 const V AggregatesMap::ISOLATED = std::numeric_limits::max()-1;\n- 1673\n- 1674 template\n- 1675 AggregatesMap::AggregatesMap()\n- 1676 : aggregates_(0)\n- 1677 {}\n- 1678\n- 1679 template\n- 1680 AggregatesMap::~AggregatesMap()\n- 1681 {\n- 1682 if(aggregates_!=0)\n- 1683 delete[] aggregates_;\n- 1684 }\n- 1685\n- 1686\n- 1687 template\n- 1688 inline AggregatesMap::AggregatesMap(std::size_t noVertices)\n- 1689 {\n- 1690 allocate(noVertices);\n- 1691 }\n- 1692\n- 1693 template\n- 1694 inline std::size_t AggregatesMap::noVertices() const\n- 1695 {\n- 1696 return noVertices_;\n- 1697 }\n- 1698\n- 1699 template\n- 1700 inline void AggregatesMap::allocate(std::size_t noVertices)\n- 1701 {\n- 1702 aggregates_ = new AggregateDescriptor[noVertices];\n- 1703 noVertices_ = noVertices;\n- 1704\n- 1705 for(std::size_t i=0; i < noVertices; i++)\n- 1706 aggregates_[i]=UNAGGREGATED;\n- 1707 }\n- 1708\n- 1709 template\n- 1710 inline void AggregatesMap::free()\n- 1711 {\n- 1712 assert(aggregates_ != 0);\n- 1713 delete[] aggregates_;\n- 1714 aggregates_=0;\n- 1715 }\n- 1716\n- 1717 template\n- 1718 inline typename AggregatesMap::AggregateDescriptor&\n- 1719 AggregatesMap::operator[](const VertexDescriptor& v)\n- 1720 {\n- 1721 return aggregates_[v];\n- 1722 }\n- 1723\n- 1724 template\n- 1725 inline const typename AggregatesMap::AggregateDescriptor&\n- 1726 AggregatesMap::operator[](const VertexDescriptor& v) const\n- 1727 {\n- 1728 return aggregates_[v];\n- 1729 }\n- 1730\n- 1731 template\n- 1732 template\n- 1733 inline std::size_t AggregatesMap::breadthFirstSearch(const V& start,\n- 1734 const AggregateDescriptor& aggregate,\n- 1735 const G& graph, F& aggregateVisitor,\n- 1736 VM& visitedMap) const\n- 1737 {\n- 1738 VertexList vlist;\n- 1739\n- 1740 DummyEdgeVisitor dummy;\n- 1741 return breadthFirstSearch(start, aggregate, graph, vlist,\n-aggregateVisitor, dummy, visitedMap);\n- 1742 }\n- 1743\n- 1744 template\n- 1745 template\n- 1746 std::size_t AggregatesMap::breadthFirstSearch(const V& start,\n- 1747 const AggregateDescriptor& aggregate,\n- 1748 const G& graph,\n- 1749 L& visited,\n- 1750 F1& aggregateVisitor,\n- 1751 F2& nonAggregateVisitor,\n- 1752 VM& visitedMap) const\n- 1753 {\n- 1754 typedef typename L::const_iterator ListIterator;\n- 1755 int visitedSpheres = 0;\n- 1756\n- 1757 visited.push_back(start);\n- 1758 put(visitedMap, start, true);\n- 1759\n- 1760 ListIterator current = visited.begin();\n- 1761 ListIterator end = visited.end();\n- 1762 std::size_t i=0, size=visited.size();\n- 1763\n- 1764 // visit the neighbours of all vertices of the\n- 1765 // current sphere.\n- 1766 while(current != end) {\n- 1767\n- 1768 for(; i\n- 1803 Aggregator::Aggregator()\n- 1804 : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)\n- 1805 {}\n- 1806\n- 1807 template\n- 1808 Aggregator::~Aggregator()\n- 1809 {\n- 1810 size_=-1;\n- 1811 }\n- 1812\n- 1813 template\n- 1814 void buildDependency(G& graph,\n- 1815 const typename C::Matrix& matrix,\n- 1816 C criterion, bool firstlevel)\n- 1817 {\n- 1818 // assert(graph.isBuilt());\n- 1819 typedef typename C::Matrix Matrix;\n- 1820 typedef typename G::VertexIterator VertexIterator;\n- 1821\n- 1822 criterion.init(&matrix);\n- 1823\n- 1824 for(VertexIterator vertex = graph.begin(); vertex != graph.end();\n-++vertex) {\n- 1825 typedef typename Matrix::row_type Row;\n- 1826\n- 1827 const Row& row = matrix[*vertex];\n- 1828\n- 1829 // Tell the criterion what row we will examine now\n- 1830 // This might for example be used for calculating the\n- 1831 // maximum offdiagonal value\n- 1832 criterion.initRow(row, *vertex);\n- 1833\n- 1834 // On a first path all columns are examined. After this\n- 1835 // the calculator should know whether the vertex is isolated.\n- 1836 typedef typename Matrix::ConstColIterator ColIterator;\n- 1837 ColIterator end = row.end();\n- 1838 typename FieldTraits::real_type\n-absoffdiag=0.;\n- 1839\n- 1840 using std::max;\n- 1841 if(firstlevel) {\n- 1842 for(ColIterator col = row.begin(); col != end; ++col)\n- 1843 if(col.index()!=*vertex) {\n- 1844 criterion.examine(col);\n- 1845 absoffdiag = max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());\n- 1846 }\n- 1847\n- 1848 if(absoffdiag==0)\n- 1849 vertex.properties().setExcludedBorder();\n- 1850 }\n- 1851 else\n- 1852 for(ColIterator col = row.begin(); col != end; ++col)\n- 1853 if(col.index()!=*vertex)\n- 1854 criterion.examine(col);\n- 1855\n- 1856 // reset the vertex properties\n- 1857 //vertex.properties().reset();\n- 1858\n- 1859 // Check whether the vertex is isolated.\n- 1860 if(criterion.isIsolated()) {\n- 1861 //std::cout<<\"ISOLATED: \"<<*vertex<\n- 1881 template\n- 1882 inline Aggregator::AggregateVisitor::AggregateVisitor(const\n-AggregatesMap& aggregates,\n- 1883 const AggregateDescriptor& aggregate, V& visitor)\n- 1884 : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)\n- 1885 {}\n- 1886\n- 1887 template\n- 1888 template\n- 1889 inline void Aggregator::AggregateVisitor::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 1890 {\n- 1891 if(aggregates_[edge.target()]==aggregate_)\n- 1892 visitor_->operator()(edge);\n- 1893 }\n- 1894\n- 1895 template\n- 1896 template\n- 1897 inline void Aggregator::visitAggregateNeighbours(const Vertex& vertex,\n- 1898 const AggregateDescriptor& aggregate,\n- 1899 const AggregatesMap& aggregates,\n- 1900 V& visitor) const\n- 1901 {\n- 1902 // Only evaluates for edge pointing to the aggregate\n- 1903 AggregateVisitor v(aggregates, aggregate, visitor);\n- 1904 visitNeighbours(*graph_, vertex, v);\n- 1905 }\n- 1906\n- 1907\n- 1908 template\n- 1909 inline Aggregator::Counter::Counter()\n- 1910 : count_(0)\n- 1911 {}\n- 1912\n- 1913 template\n- 1914 inline void Aggregator::Counter::increment()\n- 1915 {\n- 1916 ++count_;\n- 1917 }\n- 1918\n- 1919 template\n- 1920 inline void Aggregator::Counter::decrement()\n- 1921 {\n- 1922 --count_;\n- 1923 }\n- 1924 template\n- 1925 inline int Aggregator::Counter::value()\n- 1926 {\n- 1927 return count_;\n- 1928 }\n- 1929\n- 1930 template\n- 1931 inline void Aggregator::TwoWayCounter::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 1932 {\n- 1933 if(edge.properties().isTwoWay())\n- 1934 Counter::increment();\n- 1935 }\n- 1936\n- 1937 template\n- 1938 int Aggregator::twoWayConnections(const Vertex& vertex, const\n-AggregateDescriptor& aggregate,\n- 1939 const AggregatesMap& aggregates) const\n- 1940 {\n- 1941 TwoWayCounter counter;\n- 1942 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n- 1943 return counter.value();\n- 1944 }\n- 1945\n- 1946 template\n- 1947 int Aggregator::oneWayConnections(const Vertex& vertex, const\n-AggregateDescriptor& aggregate,\n- 1948 const AggregatesMap& aggregates) const\n- 1949 {\n- 1950 OneWayCounter counter;\n- 1951 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n- 1952 return counter.value();\n- 1953 }\n- 1954\n- 1955 template\n- 1956 inline void Aggregator::OneWayCounter::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 1957 {\n- 1958 if(edge.properties().isOneWay())\n- 1959 Counter::increment();\n- 1960 }\n- 1961\n- 1962 template\n- 1963 inline Aggregator::ConnectivityCounter::ConnectivityCounter(const\n-VertexSet& connected,\n- 1964 const AggregatesMap& aggregates)\n- 1965 : Counter(), connected_(connected), aggregates_(aggregates)\n- 1966 {}\n- 1967\n- 1968\n- 1969 template\n- 1970 inline void Aggregator::ConnectivityCounter::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 1971 {\n- 1972 if(connected_.find(aggregates_[edge.target()]) == connected_.end() ||\n-aggregates_[edge.target()]==AggregatesMap::UNAGGREGATED)\n- 1973 // Would be a new connection\n- 1974 Counter::increment();\n- 1975 else{\n- 1976 Counter::increment();\n- 1977 Counter::increment();\n- 1978 }\n- 1979 }\n- 1980\n- 1981 template\n- 1982 inline double Aggregator::connectivity(const Vertex& vertex, const\n-AggregatesMap& aggregates) const\n- 1983 {\n- 1984 ConnectivityCounter counter(connected_, aggregates);\n- 1985 double noNeighbours=visitNeighbours(*graph_, vertex, counter);\n- 1986 return (double)counter.value()/noNeighbours;\n- 1987 }\n- 1988\n- 1989 template\n- 1990 inline Aggregator::DependencyCounter::DependencyCounter()\n- 1991 : Counter()\n- 1992 {}\n- 1993\n- 1994 template\n- 1995 inline void Aggregator::DependencyCounter::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 1996 {\n- 1997 if(edge.properties().depends())\n- 1998 Counter::increment();\n- 1999 if(edge.properties().influences())\n- 2000 Counter::increment();\n- 2001 }\n- 2002\n- 2003 template\n- 2004 int Aggregator::unusedNeighbours(const Vertex& vertex, const\n-AggregatesMap& aggregates) const\n- 2005 {\n- 2006 return aggregateNeighbours(vertex, AggregatesMap::UNAGGREGATED,\n-aggregates);\n- 2007 }\n- 2008\n- 2009 template\n- 2010 std::pair Aggregator::neighbours(const Vertex& vertex,\n- 2011 const AggregateDescriptor& aggregate,\n- 2012 const AggregatesMap& aggregates) const\n- 2013 {\n- 2014 DependencyCounter unused, aggregated;\n- 2015 typedef AggregateVisitor CounterT;\n- 2016 typedef std::tuple CounterTuple;\n- 2017 CombinedFunctor visitors(CounterTuple(CounterT(aggregates,\n-AggregatesMap::UNAGGREGATED, unused), CounterT(aggregates, aggregate,\n-aggregated)));\n- 2018 visitNeighbours(*graph_, vertex, visitors);\n- 2019 return std::make_pair(unused.value(), aggregated.value());\n- 2020 }\n- 2021\n- 2022\n- 2023 template\n- 2024 int Aggregator::aggregateNeighbours(const Vertex& vertex, const\n-AggregateDescriptor& aggregate, const AggregatesMap& aggregates) const\n- 2025 {\n- 2026 DependencyCounter counter;\n- 2027 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n- 2028 return counter.value();\n- 2029 }\n- 2030\n- 2031 template\n- 2032 std::size_t Aggregator::distance(const Vertex& vertex, const\n-AggregatesMap& aggregates)\n- 2033 {\n- 2034 return 0;\n- 2035 typename PropertyMapTypeSelector::Type visitedMap =\n-get(VertexVisitedTag(), *graph_);\n- 2036 VertexList vlist;\n- 2037 typename AggregatesMap::DummyEdgeVisitor dummy;\n- 2038 return aggregates.template breadthFirstSearch(vertex,\n- 2039 aggregate_->id(), *graph_,\n- 2040 vlist, dummy, dummy, visitedMap);\n- 2041 }\n- 2042\n- 2043 template\n- 2044 inline Aggregator::FrontMarker::FrontMarker(std::vector&\n-front, MatrixGraph& graph)\n- 2045 : front_(front), graph_(graph)\n- 2046 {}\n- 2047\n- 2048 template\n- 2049 inline void Aggregator::FrontMarker::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 2050 {\n- 2051 Vertex target = edge.target();\n- 2052\n- 2053 if(!graph_.getVertexProperties(target).front()) {\n- 2054 front_.push_back(target);\n- 2055 graph_.getVertexProperties(target).setFront();\n- 2056 }\n- 2057 }\n- 2058\n- 2059 template\n- 2060 inline bool Aggregator::admissible(const Vertex& vertex, const\n-AggregateDescriptor& aggregate, const AggregatesMap& aggregates) const\n- 2061 {\n- 2062 // Todo\n- 2063 Dune::dvverb<<\" Admissible not yet implemented!\"<endEdges(vertex);\n- 2071 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {\n- 2072 // if(edge.properties().depends() && !edge.properties().influences()\n- 2073 if(edge.properties().isStrong()\n- 2074 && aggregates[edge.target()]==aggregate)\n- 2075 {\n- 2076 // Search for another link to the aggregate\n- 2077 Iterator edge1 = edge;\n- 2078 for(++edge1; edge1 != vend; ++edge1) {\n- 2079 //if(edge1.properties().depends() && !edge1.properties().influences()\n- 2080 if(edge1.properties().isStrong()\n- 2081 && aggregates[edge.target()]==aggregate)\n- 2082 {\n- 2083 //Search for an edge connecting the two vertices that is\n- 2084 //strong\n- 2085 bool found=false;\n- 2086 Iterator v2end = graph_->endEdges(edge.target());\n- 2087 for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end;\n-++edge2) {\n- 2088 if(edge2.target()==edge1.target() &&\n- 2089 edge2.properties().isStrong()) {\n- 2090 found =true;\n- 2091 break;\n- 2092 }\n- 2093 }\n- 2094 if(found)\n- 2095 {\n- 2096 return true;\n- 2097 }\n- 2098 }\n- 2099 }\n- 2100 }\n- 2101 }\n- 2102\n- 2103 // Situation 2: cluster node depends on front node and other cluster node\n- 2105 vend = graph_->endEdges(vertex);\n- 2106 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {\n- 2107 //if(!edge.properties().depends() && edge.properties().influences()\n- 2108 if(edge.properties().isStrong()\n- 2109 && aggregates[edge.target()]==aggregate)\n- 2110 {\n- 2111 // Search for a link from target that stays within the aggregate\n- 2112 Iterator v1end = graph_->endEdges(edge.target());\n- 2113\n- 2114 for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end;\n-++edge1) {\n- 2115 //if(edge1.properties().depends() && !edge1.properties().influences()\n- 2116 if(edge1.properties().isStrong()\n- 2117 && aggregates[edge1.target()]==aggregate)\n- 2118 {\n- 2119 bool found=false;\n- 2120 // Check if front node is also connected to this one\n- 2121 Iterator v2end = graph_->endEdges(vertex);\n- 2122 for(Iterator edge2 = graph_->beginEdges(vertex); edge2 != v2end; ++edge2)\n+ 739 try{\n+ 740 newMatrix[col.index()][row.index()];\n+ 741 }catch(const Dune::ISTLError&) {\n+ 742 std::cerr<\n+757 void redistributeMatrixEntries(M& origMatrix, M& newMatrix, C& origComm, C&\n+newComm,\n+ 758 RedistributeInformation& ri)\n+ 759 {\n+ 760 typedef typename C::ParallelIndexSet IndexSet;\n+ 761 typename C::OwnerSet ownerflags;\n+ 762 std::vector rowsize(newComm.indexSet().size(), 0);\n+ 763 std::vector copyrowsize(newComm.indexSet().size(),\n+0);\n+ 764 std::vector backwardscopyrowsize(origComm.indexSet\n+().size(), 0);\n+ 765\n+ 766 for (std::size_t i=0; i < newComm.indexSet().size(); i++) {\n+ 767 rowsize[i] = ri.getRowSize(i);\n+ 768 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n+{\n+ 769 copyrowsize[i] = ri.getCopyRowSize(i);\n+ 770 }\n+ 771 }\n+ 772\n+ 773 for (std::size_t i=0; i < origComm.indexSet().size(); i++)\n+ 774 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n+ 775 backwardscopyrowsize[i] = ri.getBackwardsCopyRowSize(i);\n+ 776\n+ 777\n+ 778 if (SolverCategory::category(origComm) == SolverCategory::nonoverlapping)\n {\n- 2123 if(edge2.target()==edge1.target()) {\n- 2124 if(edge2.properties().isStrong())\n- 2125 found=true;\n- 2126 break;\n- 2127 }\n- 2128 }\n- 2129 if(found)\n- 2130 {\n- 2131 return true;\n- 2132 }\n- 2133 }\n- 2134 }\n- 2135 }\n- 2136 }\n- 2137 return false;\n- 2138 }\n- 2139\n- 2140 template\n- 2141 void Aggregator::unmarkFront()\n- 2142 {\n- 2143 typedef typename std::vector::const_iterator Iterator;\n- 2144\n- 2145 for(Iterator vertex=front_.begin(); vertex != front_.end(); ++vertex)\n- 2146 graph_->getVertexProperties(*vertex).resetFront();\n- 2147\n- 2148 front_.clear();\n- 2149 }\n- 2150\n- 2151 template\n- 2152 inline void\n- 2153 Aggregator::nonisoNeighbourAggregate(const Vertex& vertex,\n- 2154 const AggregatesMap& aggregates,\n- 2155 SLList& neighbours) const\n- 2156 {\n- 2157 typedef typename MatrixGraph::ConstEdgeIterator Iterator;\n- 2158 Iterator end=graph_->beginEdges(vertex);\n- 2159 neighbours.clear();\n- 2160\n- 2161 for(Iterator edge=graph_->beginEdges(vertex); edge!=end; ++edge)\n- 2162 {\n- 2163 if(aggregates[edge.target()]!=AggregatesMap::UNAGGREGATED &&\n-graph_->getVertexProperties(edge.target()).isolated())\n- 2164 neighbours.push_back(aggregates[edge.target()]);\n- 2165 }\n- 2166 }\n- 2167\n- 2168 template\n- 2169 inline typename G::VertexDescriptor Aggregator::mergeNeighbour(const\n-Vertex& vertex, const AggregatesMap& aggregates) const\n- 2170 {\n- 2171 typedef typename MatrixGraph::ConstEdgeIterator Iterator;\n- 2172\n- 2173 Iterator end = graph_->endEdges(vertex);\n- 2174 for(Iterator edge = graph_->beginEdges(vertex); edge != end; ++edge) {\n- 2175 if(aggregates[edge.target()] != AggregatesMap::UNAGGREGATED &&\n- 2176 graph_->getVertexProperties(edge.target()).isolated() == graph_-\n->getVertexProperties(edge.source()).isolated()) {\n- 2177 if( graph_->getVertexProperties(vertex).isolated() ||\n- 2178 ((edge.properties().depends() || edge.properties().influences())\n- 2179 && admissible(vertex, aggregates[edge.target()], aggregates)))\n- 2180 return edge.target();\n- 2181 }\n- 2182 }\n- 2183 return AggregatesMap::UNAGGREGATED;\n- 2184 }\n- 2185\n- 2186 template\n- 2187 Aggregator::FrontNeighbourCounter::FrontNeighbourCounter(const\n-MatrixGraph& graph)\n- 2188 : Counter(), graph_(graph)\n- 2189 {}\n- 2190\n- 2191 template\n- 2192 void Aggregator::FrontNeighbourCounter::operator()(const typename\n-MatrixGraph::ConstEdgeIterator& edge)\n- 2193 {\n- 2194 if(graph_.getVertexProperties(edge.target()).front())\n- 2195 Counter::increment();\n- 2196 }\n- 2197\n- 2198 template\n- 2199 int Aggregator::noFrontNeighbours(const Vertex& vertex) const\n- 2200 {\n- 2201 FrontNeighbourCounter counter(*graph_);\n- 2202 visitNeighbours(*graph_, vertex, counter);\n- 2203 return counter.value();\n- 2204 }\n- 2205 template\n- 2206 inline bool Aggregator::connected(const Vertex& vertex,\n- 2207 const AggregateDescriptor& aggregate,\n- 2208 const AggregatesMap& aggregates) const\n- 2209 {\n- 2210 typedef typename G::ConstEdgeIterator iterator;\n- 2211 const iterator end = graph_->endEdges(vertex);\n- 2212 for(iterator edge = graph_->beginEdges(vertex); edge != end; ++edge)\n- 2213 if(aggregates[edge.target()]==aggregate)\n- 2214 return true;\n- 2215 return false;\n- 2216 }\n- 2217 template\n- 2218 inline bool Aggregator::connected(const Vertex& vertex,\n- 2219 const SLList& aggregateList,\n- 2220 const AggregatesMap& aggregates) const\n- 2221 {\n- 2222 typedef typename SLList::const_iterator Iter;\n- 2223 for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)\n- 2224 if(connected(vertex, *i, aggregates))\n- 2225 return true;\n- 2226 return false;\n- 2227 }\n- 2228\n- 2229 template\n- 2230 template\n- 2231 void Aggregator::growIsolatedAggregate(const Vertex& seed, const\n-AggregatesMap& aggregates, const C& c)\n- 2232 {\n- 2233 SLList connectedAggregates;\n- 2234 nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);\n- 2235\n- 2236 while(aggregate_->size()< c.minAggregateSize() && aggregate_->connectSize\n-() < c.maxConnectivity()) {\n- 2237 double maxCon=-1;\n- 2238 std::size_t maxFrontNeighbours=0;\n- 2239\n- 2240 Vertex candidate=AggregatesMap::UNAGGREGATED;\n- 2241\n- 2242 typedef typename std::vector::const_iterator Iterator;\n- 2243\n- 2244 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n- 2245 if(distance(*vertex, aggregates)>c.maxDistance())\n- 2246 continue; // distance of proposes aggregate too big\n- 2247\n- 2248 if(connectedAggregates.size()>0) {\n- 2249 // there is already a neighbour cluster\n- 2250 // front node must be connected to same neighbour cluster\n- 2251\n- 2252 if(!connected(*vertex, connectedAggregates, aggregates))\n- 2253 continue;\n- 2254 }\n- 2255\n- 2256 double con = connectivity(*vertex, aggregates);\n- 2257\n- 2258 if(con == maxCon) {\n- 2259 std::size_t frontNeighbours = noFrontNeighbours(*vertex);\n- 2260\n- 2261 if(frontNeighbours >= maxFrontNeighbours) {\n- 2262 maxFrontNeighbours = frontNeighbours;\n- 2263 candidate = *vertex;\n- 2264 }\n- 2265 }else if(con > maxCon) {\n- 2266 maxCon = con;\n- 2267 maxFrontNeighbours = noFrontNeighbours(*vertex);\n- 2268 candidate = *vertex;\n- 2269 }\n- 2270 }\n- 2271\n- 2272 if(candidate==AggregatesMap::UNAGGREGATED)\n- 2273 break;\n- 2274\n- 2275 aggregate_->add(candidate);\n- 2276 }\n- 2277 }\n- 2278\n- 2279 template\n- 2280 template\n- 2281 void Aggregator::growAggregate(const Vertex& seed, const\n-AggregatesMap& aggregates, const C& c)\n- 2282 {\n- 2283 using std::min;\n- 2284\n- 2285 std::size_t distance_ =0;\n- 2286 while(aggregate_->size() < c.minAggregateSize()&& distance_ candidates;\n- 2291 candidates.reserve(30);\n- 2292\n- 2293 typedef typename std::vector::const_iterator Iterator;\n- 2294\n- 2295 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n- 2296 // Only nonisolated nodes are considered\n- 2297 if(graph_->getVertexProperties(*vertex).isolated())\n- 2298 continue;\n- 2299\n- 2300 int twoWayCons = twoWayConnections(*vertex, aggregate_->id(),\n-aggregates);\n- 2301\n- 2302 /* The case of two way connections. */\n- 2303 if( maxTwoCons == twoWayCons && twoWayCons > 0) {\n- 2304 double con = connectivity(*vertex, aggregates);\n- 2305\n- 2306 if(con == maxCon) {\n- 2307 int neighbours = noFrontNeighbours(*vertex);\n- 2308\n- 2309 if(neighbours > maxNeighbours) {\n- 2310 maxNeighbours = neighbours;\n- 2311 candidates.clear();\n- 2312 candidates.push_back(*vertex);\n- 2313 }else{\n- 2314 candidates.push_back(*vertex);\n- 2315 }\n- 2316 }else if( con > maxCon) {\n- 2317 maxCon = con;\n- 2318 maxNeighbours = noFrontNeighbours(*vertex);\n- 2319 candidates.clear();\n- 2320 candidates.push_back(*vertex);\n- 2321 }\n- 2322 }else if(twoWayCons > maxTwoCons) {\n- 2323 maxTwoCons = twoWayCons;\n- 2324 maxCon = connectivity(*vertex, aggregates);\n- 2325 maxNeighbours = noFrontNeighbours(*vertex);\n- 2326 candidates.clear();\n- 2327 candidates.push_back(*vertex);\n- 2328\n- 2329 // two way connections precede\n- 2330 maxOneCons = std::numeric_limits::max();\n- 2331 }\n- 2332\n- 2333 if(twoWayCons > 0)\n- 2334 {\n- 2335 continue; // THis is a two-way node, skip tests for one way nodes\n- 2336 }\n- 2337\n- 2338 /* The one way case */\n- 2339 int oneWayCons = oneWayConnections(*vertex, aggregate_->id(),\n-aggregates);\n- 2340\n- 2341 if(oneWayCons==0)\n- 2342 continue; // No strong connections, skip the tests.\n- 2343\n- 2344 if(!admissible(*vertex, aggregate_->id(), aggregates))\n- 2345 continue;\n- 2346\n- 2347 if( maxOneCons == oneWayCons && oneWayCons > 0) {\n- 2348 double con = connectivity(*vertex, aggregates);\n- 2349\n- 2350 if(con == maxCon) {\n- 2351 int neighbours = noFrontNeighbours(*vertex);\n- 2352\n- 2353 if(neighbours > maxNeighbours) {\n- 2354 maxNeighbours = neighbours;\n- 2355 candidates.clear();\n- 2356 candidates.push_back(*vertex);\n- 2357 }else{\n- 2358 if(neighbours==maxNeighbours)\n- 2359 {\n- 2360 candidates.push_back(*vertex);\n- 2361 }\n- 2362 }\n- 2363 }else if( con > maxCon) {\n- 2364 maxCon = con;\n- 2365 maxNeighbours = noFrontNeighbours(*vertex);\n- 2366 candidates.clear();\n- 2367 candidates.push_back(*vertex);\n- 2368 }\n- 2369 }else if(oneWayCons > maxOneCons) {\n- 2370 maxOneCons = oneWayCons;\n- 2371 maxCon = connectivity(*vertex, aggregates);\n- 2372 maxNeighbours = noFrontNeighbours(*vertex);\n- 2373 candidates.clear();\n- 2374 candidates.push_back(*vertex);\n- 2375 }\n- 2376 }\n- 2377\n- 2378\n- 2379 if(!candidates.size())\n- 2380 break; // No more candidates found\n- 2381 distance_=distance(seed, aggregates);\n- 2382 candidates.resize(min(candidates.size(), c.maxAggregateSize()-\n- 2383 aggregate_->size()));\n- 2384 aggregate_->add(candidates);\n- 2385 }\n- 2386 }\n- 2387\n- 2388 template\n- 2389 template\n- 2390 std::tuple AggregatesMap::buildAggregates(const M&\n-matrix, G& graph, const C& criterion,\n- 2391 bool finestLevel)\n- 2392 {\n- 2393 Aggregator aggregator;\n- 2394 return aggregator.build(matrix, graph, *this, criterion, finestLevel);\n- 2395 }\n- 2396\n- 2397 template\n- 2398 template\n- 2399 std::tuple Aggregator::build(const M& m, G& graph,\n-AggregatesMap& aggregates, const C& c,\n- 2400 bool finestLevel)\n- 2401 {\n- 2402 using std::max;\n- 2403 using std::min;\n- 2404 // Stack for fast vertex access\n- 2405 Stack stack_(graph, *this, aggregates);\n- 2406\n- 2407 graph_ = &graph;\n- 2408\n- 2409 aggregate_ = new Aggregate(graph, aggregates, connected_,\n-front_);\n- 2410\n- 2411 Timer watch;\n- 2412 watch.reset();\n- 2413\n- 2414 buildDependency(graph, m, c, finestLevel);\n- 2415\n- 2416 dverb<<\"Build dependency took \"<< watch.elapsed()<<\" seconds.\"<::ISOLATED;\n- 2437 ++skippedAggregates;\n- 2438 continue;\n- 2439 }\n- 2440\n- 2441 if(graph.getVertexProperties(seed).isolated()) {\n- 2442 if(c.skipIsolated()) {\n- 2443 // isolated vertices are not aggregated but skipped on the coarser\n-levels.\n- 2444 aggregates[seed]=AggregatesMap::ISOLATED;\n- 2445 ++skippedAggregates;\n- 2446 // skip rest as no agglomeration is done.\n- 2447 continue;\n- 2448 }else{\n- 2449 aggregate_->seed(seed);\n- 2450 growIsolatedAggregate(seed, aggregates, c);\n- 2451 }\n- 2452 }else{\n- 2453 aggregate_->seed(seed);\n- 2454 growAggregate(seed, aggregates, c);\n- 2455 }\n- 2456\n- 2457 /* The rounding step. */\n- 2458 while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->size()\n-< c.maxAggregateSize()) {\n- 2459\n- 2460 std::vector candidates;\n- 2461 candidates.reserve(30);\n- 2462\n- 2463 typedef typename std::vector::const_iterator Iterator;\n- 2464\n- 2465 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n- 2466\n- 2467 if(graph.getVertexProperties(*vertex).isolated())\n- 2468 continue; // No isolated nodes here\n- 2469\n- 2470 if(twoWayConnections( *vertex, aggregate_->id(), aggregates) == 0 &&\n- 2471 (oneWayConnections( *vertex, aggregate_->id(), aggregates) == 0 ||\n- 2472 !admissible( *vertex, aggregate_->id(), aggregates) ))\n- 2473 continue;\n- 2474\n- 2475 std::pair neighbourPair=neighbours(*vertex, aggregate_->id(),\n- 2476 aggregates);\n- 2477\n- 2478 //if(aggregateNeighbours(*vertex, aggregate_->id(), aggregates) <=\n-unusedNeighbours(*vertex, aggregates))\n- 2479 // continue;\n- 2480\n- 2481 if(neighbourPair.first >= neighbourPair.second)\n- 2482 continue;\n- 2483\n- 2484 if(distance(*vertex, aggregates) > c.maxDistance())\n- 2485 continue; // Distance too far\n- 2486 candidates.push_back(*vertex);\n- 2487 break;\n- 2488 }\n- 2489\n- 2490 if(!candidates.size()) break; // no more candidates found.\n- 2491\n- 2492 candidates.resize(min(candidates.size(), c.maxAggregateSize()-\n- 2493 aggregate_->size()));\n- 2494 aggregate_->add(candidates);\n- 2495\n- 2496 }\n- 2497\n- 2498 // try to merge aggregates consisting of only one nonisolated vertex with\n-other aggregates\n- 2499 if(aggregate_->size()==1 && c.maxAggregateSize()>1) {\n- 2500 if(!graph.getVertexProperties(seed).isolated()) {\n- 2501 Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);\n- 2502\n- 2503 if(mergedNeighbour != AggregatesMap::UNAGGREGATED) {\n- 2504 // assign vertex to the neighbouring cluster\n- 2505 aggregates[seed] = aggregates[mergedNeighbour];\n- 2506 aggregate_->invalidate();\n- 2507 }else{\n- 2508 ++avg;\n- 2509 minA=min(minA,static_cast(1));\n- 2510 maxA=max(maxA,static_cast(1));\n- 2511 ++oneAggregates;\n- 2512 ++conAggregates;\n- 2513 }\n- 2514 }else{\n- 2515 ++avg;\n- 2516 minA=min(minA,static_cast(1));\n- 2517 maxA=max(maxA,static_cast(1));\n- 2518 ++oneAggregates;\n- 2519 ++isoAggregates;\n- 2520 }\n- 2521 ++avg;\n- 2522 }else{\n- 2523 avg+=aggregate_->size();\n- 2524 minA=min(minA,aggregate_->size());\n- 2525 maxA=max(maxA,aggregate_->size());\n- 2526 if(graph.getVertexProperties(seed).isolated())\n- 2527 ++isoAggregates;\n- 2528 else\n- 2529 ++conAggregates;\n- 2530 }\n- 2531\n- 2532 }\n- 2533\n- 2534 Dune::dinfo<<\"connected aggregates: \"<0)\n- 2537 Dune::dinfo<<\" one node aggregates: \"<\n- 2548 Aggregator::Stack::Stack(const MatrixGraph& graph, const\n-Aggregator& aggregatesBuilder,\n- 2549 const AggregatesMap& aggregates)\n- 2550 : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_\n-(aggregates), begin_(graph.begin()), end_(graph.end())\n- 2551 {\n- 2552 //vals_ = new Vertex[N];\n- 2553 }\n- 2554\n- 2555 template\n- 2556 Aggregator::Stack::~Stack()\n- 2557 {\n- 2558 //Dune::dverb << \"Max stack size was \"<\n- 2563 const typename Aggregator::Vertex Aggregator::Stack::NullEntry\n- 2564 = std::numeric_limits::max();\n- 2565\n- 2566 template\n- 2567 inline typename G::VertexDescriptor Aggregator::Stack::pop()\n- 2568 {\n- 2569 for(; begin_!=end_ && aggregates_[*begin_] != AggregatesMap::\n-UNAGGREGATED; ++begin_) ;\n- 2570\n- 2571 if(begin_!=end_)\n- 2572 {\n- 2573 typename G::VertexDescriptor current=*begin_;\n- 2574 ++begin_;\n- 2575 return current;\n- 2576 }else\n- 2577 return NullEntry;\n- 2578 }\n- 2579\n- 2580#endif // DOXYGEN\n- 2581\n- 2582 template\n-2583 void printAggregates2d(const AggregatesMap& aggregates, int n, int m,\n-std::ostream& os)\n- 2584 {\n- 2585 using std::max;\n- 2586\n- 2587 std::ios_base::fmtflags oldOpts=os.flags();\n- 2588\n- 2589 os.setf(std::ios_base::right, std::ios_base::adjustfield);\n- 2590\n- 2591 V maxVal=0;\n- 2592 int width=1;\n- 2593\n- 2594 for(int i=0; i< n*m; i++)\n- 2595 maxVal=max(maxVal, aggregates[i]);\n- 2596\n- 2597 for(int i=10; i < 1000000; i*=10)\n- 2598 if(maxVal/i>0)\n- 2599 width++;\n- 2600 else\n- 2601 break;\n- 2602\n- 2603 for(int j=0, entry=0; j < m; j++) {\n- 2604 for(int i=0; i origrow_copy(origMatrix, origComm.globalLookup\n+(),\n+ 781 newComm.indexSet(), backwardscopyrowsize);\n+ 782 CommMatrixRow newrow_copy(newMatrix, origComm.globalLookup(),\n+ 783 newComm.indexSet(),copyrowsize);\n+ 784 ri.template redistribute >\n+(origrow_copy,\n+ 785 newrow_copy);\n+ 786 ri.getInterface().free();\n+ 787 RemoteIndices *ris = new RemoteIndices\n+(origComm.indexSet(),\n+ 788 newComm.indexSet(),\n+ 789 origComm.communicator());\n+ 790 ris->template rebuild();\n+ 791 ri.getInterface().build(*ris,ownerflags,ownerflags);\n+ 792 }\n+ 793\n+ 794 CommMatrixRow\n+ 795 origrow(origMatrix, origComm.globalLookup(), newComm.indexSet());\n+ 796 CommMatrixRow\n+ 797 newrow(newMatrix, origComm.globalLookup(), newComm.indexSet(),rowsize);\n+ 798 ri.template redistribute >\n+(origrow,newrow);\n+ 799 if (SolverCategory::category(origComm) != static_cast\n+(SolverCategory::nonoverlapping))\n+ 800 newrow.setOverlapRowsToDirichlet();\n+ 801 }\n+ 802\n+ 819 template\n+820 void redistributeMatrix(M& origMatrix, M& newMatrix, C& origComm, C&\n+newComm,\n+ 821 RedistributeInformation& ri)\n+ 822 {\n+ 823 ri.setNoRows(newComm.indexSet().size());\n+ 824 ri.setNoCopyRows(newComm.indexSet().size());\n+ 825 ri.setNoBackwardsCopyRows(origComm.indexSet().size());\n+ 826 redistributeSparsityPattern(origMatrix, newMatrix, origComm, newComm, ri);\n+ 827 redistributeMatrixEntries(origMatrix, newMatrix, origComm, newComm, ri);\n+ 828 }\n+ 829#endif\n+ 830\n+ 831template\n+832 void redistributeMatrixEntries(M& origMatrix, M& newMatrix,\n+ 833 Dune::Amg::SequentialInformation& origComm,\n+ 834 Dune::Amg::SequentialInformation& newComm,\n+ 835 RedistributeInformation& ri)\n+ 836 {\n+ 837 DUNE_THROW(InvalidStateException, \"Trying to redistribute in sequential\n+program!\");\n+ 838 }\n+ 839 template\n+840 void redistributeMatrix(M& origMatrix, M& newMatrix,\n+ 841 Dune::Amg::SequentialInformation& origComm,\n+ 842 Dune::Amg::SequentialInformation& newComm,\n+ 843 RedistributeInformation& ri)\n+ 844 {\n+ 845 DUNE_THROW(InvalidStateException, \"Trying to redistribute in sequential\n+program!\");\n+ 846 }\n+ 847}\n+ 848#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+repartition.hh\n+Functionality for redistributing a parallel index set using graph partitioning.\n+pinfo.hh\n col\n Col col\n Definition: matrixmatrix.hh:351\n-Dune::Amg::Dependency::ColIter\n-Matrix::ConstColIterator ColIter\n-Constant column iterator of the matrix.\n-Definition: aggregates.hh:273\n-Dune::Amg::SymmetricMatrixDependency::valIter_\n-std::vector< real_type >::iterator valIter_\n-Definition: aggregates.hh:189\n-Dune::Amg::SymmetricMatrixDependency::ColIter\n-Matrix::ConstColIterator ColIter\n-Constant column iterator of the matrix.\n-Definition: aggregates.hh:154\n-Dune::Amg::AggregatesMap::breadthFirstSearch\n-std::size_t breadthFirstSearch(const VertexDescriptor &start, const\n-AggregateDescriptor &aggregate, const G &graph, L &visited, F1\n-&aggregateVisitor, F2 &nonAggregateVisitor, VM &visitedMap) const\n-Breadth first search within an aggregate.\n-Dune::Amg::AggregatesMap::Allocator\n-PoolAllocator< VertexDescriptor, 100 > Allocator\n-The allocator we use for our lists and the set.\n-Definition: aggregates.hh:586\n-Dune::Amg::AggregatesMap::begin\n-iterator begin()\n-Definition: aggregates.hh:737\n-Dune::Amg::Aggregate::id\n-int id()\n-Get the id identifying the aggregate.\n-Dune::Amg::Dependency::norm_\n-Norm norm_\n-The functor for calculating the norm.\n-Definition: aggregates.hh:302\n-Dune::Amg::Aggregator::Vertex\n-MatrixGraph::VertexDescriptor Vertex\n-The vertex identifier.\n-Definition: aggregates.hh:920\n-Dune::Amg::AggregationCriterion::AggregationCriterion\n-AggregationCriterion()\n-Constructor.\n-Definition: aggregates.hh:66\n-Dune::Amg::SymmetricDependency::matrix_\n-const Matrix * matrix_\n-The matrix we work on.\n-Definition: aggregates.hh:357\n-Dune::Amg::Diagonal::operator()\n-auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::\n-value > *sfinae=nullptr) const\n-Compute the norm of a scalar.\n-Definition: aggregates.hh:406\n-Dune::Amg::Dependency::initRow\n-void initRow(const Row &row, int index)\n-Dune::Amg::SymmetricMatrixDependency::SymmetricMatrixDependency\n-SymmetricMatrixDependency(const Parameters &parms)\n-Definition: aggregates.hh:168\n-Dune::Amg::Dependency::Matrix\n-M Matrix\n-The matrix type we build the dependency of.\n-Definition: aggregates.hh:258\n-Dune::Amg::Aggregator::Counter::Counter\n-Counter()\n-Constructor.\n-Dune::Amg::Aggregator::MatrixGraph\n-G MatrixGraph\n-The matrix graph type used.\n-Definition: aggregates.hh:915\n-Dune::Amg::SymmetricDependency::norm_\n-Norm norm_\n-The functor for calculating the norm.\n-Definition: aggregates.hh:363\n-Dune::Amg::AggregatesMap::DummyEdgeVisitor::operator()\n-void operator()(const EdgeIterator &edge) const\n-Definition: aggregates.hh:601\n-Dune::Amg::SymmetricCriterion::SymmetricCriterion\n-SymmetricCriterion()\n-Definition: aggregates.hh:524\n-Dune::Amg::Dependency::Dependency\n-Dependency()\n-Definition: aggregates.hh:290\n-Dune::Amg::SymmetricDependency::examine\n-void examine(const ColIter &col)\n-Dune::Amg::SymmetricDependency::Matrix\n-M Matrix\n-The matrix type we build the dependency of.\n-Definition: aggregates.hh:319\n-Dune::Amg::SymmetricMatrixDependency::diagonal_\n-real_type diagonal_\n-The norm of the current diagonal.\n-Definition: aggregates.hh:187\n-Dune::Amg::Dependency::Norm\n-N Norm\n-The norm to use for examining the matrix entries.\n-Definition: aggregates.hh:263\n-Dune::Amg::AggregatesMap::end\n-iterator end()\n-Definition: aggregates.hh:742\n-Dune::Amg::UnSymmetricCriterion::UnSymmetricCriterion\n-UnSymmetricCriterion(const Parameters &parms)\n-Definition: aggregates.hh:541\n-Dune::Amg::Aggregator::TwoWayCounter::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::SymmetricMatrixDependency::initRow\n-void initRow(const Row &row, int index)\n-Definition: aggregates.hh:201\n-Dune::Amg::Dependency::isIsolated\n-bool isIsolated()\n-Dune::Amg::Aggregator::Stack::NullEntry\n-static const Vertex NullEntry\n-Definition: aggregates.hh:1008\n-Dune::Amg::SymmetricMatrixDependency::examine\n-void examine(const ColIter &col)\n-Definition: aggregates.hh:214\n-Dune::Amg::Dependency::Dependency\n-Dependency(const Parameters &parms)\n-Definition: aggregates.hh:286\n-Dune::Amg::SymmetricMatrixDependency::row_\n-int row_\n-index of the currently evaluated row.\n-Definition: aggregates.hh:185\n-Dune::Amg::Aggregator::Stack\n-friend class Stack\n-Definition: aggregates.hh:1036\n-Dune::Amg::Aggregator::ConnectivityCounter::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::Aggregator::build\n-std::tuple< int, int, int, int > build(const M &m, G &graph, AggregatesMap<\n-Vertex > &aggregates, const C &c, bool finestLevel)\n-Build the aggregates.\n-Dune::Amg::Aggregator::FrontNeighbourCounter::FrontNeighbourCounter\n-FrontNeighbourCounter(const MatrixGraph &front)\n-Constructor.\n-Dune::Amg::SymmetricDependency::Row\n-Matrix::row_type Row\n-Constant Row iterator of the matrix.\n-Definition: aggregates.hh:329\n-Dune::Amg::Dependency::matrix_\n-const Matrix * matrix_\n-The matrix we work on.\n-Definition: aggregates.hh:296\n-Dune::Amg::AggregatesMap::operator[]\n-const AggregateDescriptor & operator[](const VertexDescriptor &v) const\n-Get the aggregate a vertex belongs to.\n-Dune::Amg::SymmetricDependency::examine\n-void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter\n-&col)\n-Dune::Amg::Aggregator::AggregateVisitor::AggregateVisitor\n-AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const\n-AggregateDescriptor &aggregate, Visitor &visitor)\n-Constructor.\n-Dune::Amg::SymmetricDependency::ColIter\n-Matrix::ConstColIterator ColIter\n-Constant column iterator of the matrix.\n-Definition: aggregates.hh:334\n-Dune::Amg::AggregatesMap::~AggregatesMap\n-~AggregatesMap()\n-Destructor.\n-Dune::Amg::SymmetricMatrixDependency::field_type\n-Matrix::field_type field_type\n-The current max value.\n-Definition: aggregates.hh:179\n-Dune::Amg::Aggregator::Counter::decrement\n-void decrement()\n-Decrement counter.\n-Dune::Amg::Aggregate::Aggregate\n-Aggregate(MatrixGraph &graph, AggregatesMap< Vertex > &aggregates, VertexSet\n-&connectivity, std::vector< Vertex > &front_)\n-Constructor.\n-Dune::Amg::Aggregator::AggregateVisitor::Visitor\n-V Visitor\n-The type of the adapted visitor.\n-Definition: aggregates.hh:1064\n-Dune::Amg::Aggregate::SphereMap\n-std::size_t * SphereMap\n-Type of the mapping of aggregate members onto distance spheres.\n-Definition: aggregates.hh:809\n-Dune::Amg::AggregationCriterion::AggregationCriterion\n-AggregationCriterion(const Parameters &parms)\n-Definition: aggregates.hh:70\n-Dune::Amg::Dependency::Row\n-Matrix::row_type Row\n-Constant Row iterator of the matrix.\n-Definition: aggregates.hh:268\n-Dune::Amg::Aggregate::connectSize\n-VertexSet::size_type connectSize()\n-Get tne number of connections to other aggregates.\n-Dune::Amg::SymmetricMatrixDependency::vals_\n-std::vector< real_type > vals_\n-Definition: aggregates.hh:188\n-Dune::Amg::SymmetricDependency::Norm\n-N Norm\n-The norm to use for examining the matrix entries.\n-Definition: aggregates.hh:324\n-Dune::Amg::printAggregates2d\n-void printAggregates2d(const AggregatesMap< V > &aggregates, int n, int m,\n-std::ostream &os)\n-Definition: aggregates.hh:2583\n-Dune::Amg::Aggregate::invalidate\n-void invalidate()\n-Definition: aggregates.hh:822\n-Dune::Amg::AggregatesMap::begin\n-const_iterator begin() const\n-Definition: aggregates.hh:725\n-Dune::Amg::SymmetricMatrixDependency::maxValue_\n-real_type maxValue_\n-Definition: aggregates.hh:181\n-Dune::Amg::SymmetricMatrixDependency::norm_\n-Norm norm_\n-The functor for calculating the norm.\n-Definition: aggregates.hh:183\n-Dune::Amg::Aggregator::FrontMarker::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::Aggregate::const_iterator\n-VertexSet::const_iterator const_iterator\n-Const iterator over a vertex list.\n-Definition: aggregates.hh:804\n-Dune::Amg::SymmetricCriterion::SymmetricCriterion\n-SymmetricCriterion(const Parameters &parms)\n-Definition: aggregates.hh:521\n-Dune::Amg::Aggregator::AggregateDescriptor\n-MatrixGraph::VertexDescriptor AggregateDescriptor\n-The type of the aggregate descriptor.\n-Definition: aggregates.hh:923\n-Dune::Amg::SymmetricDependency::maxValue_\n-real_type maxValue_\n-Definition: aggregates.hh:361\n-Dune::Amg::SymmetricMatrixDependency::init\n-void init(const Matrix *matrix)\n-Definition: aggregates.hh:195\n-Dune::Amg::SymmetricDependency::diagonal_\n-real_type diagonal_\n-The norm of the current diagonal.\n-Definition: aggregates.hh:367\n-Dune::Amg::AggregatesMap::iterator\n-AggregateDescriptor * iterator\n-Definition: aggregates.hh:735\n-Dune::Amg::SymmetricDependency::SymmetricDependency\n-SymmetricDependency(const Parameters &parms)\n-Definition: aggregates.hh:348\n-Dune::Amg::SymmetricDependency::real_type\n-FieldTraits< field_type >::real_type real_type\n-Definition: aggregates.hh:360\n-Dune::Amg::Aggregator::~Aggregator\n-~Aggregator()\n-Destructor.\n-Dune::Amg::Dependency::examine\n-void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter\n-&col)\n-Dune::Amg::Aggregate::add\n-void add(const Vertex &vertex)\n-Add a vertex to the aggregate.\n-Dune::Amg::AggregationCriterion::DependencyPolicy\n-T DependencyPolicy\n-The policy for calculating the dependency graph.\n-Definition: aggregates.hh:55\n-Dune::Amg::Aggregate::add\n-void add(std::vector< Vertex > &vertex)\n-Dune::Amg::Dependency::examine\n-void examine(const ColIter &col)\n-Dune::Amg::Aggregator::Aggregator\n-Aggregator()\n-Constructor.\n-Dune::Amg::Aggregator::AggregateVisitor::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Examine an edge.\n-Dune::Amg::Aggregator::FrontMarker::FrontMarker\n-FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)\n-Constructor.\n-Dune::Amg::AlwaysOneNorm::operator()\n-FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n-compute the norm of a matrix.\n-Definition: aggregates.hh:506\n-Dune::Amg::Dependency::init\n-void init(const Matrix *matrix)\n-Dune::Amg::visitNeighbours\n-int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n-V &visitor)\n-Visit all neighbour vertices of a vertex in a graph.\n-Dune::Amg::AggregationCriterion::setDefaultValuesIsotropic\n-void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n-Sets reasonable default values for an isotropic problem.\n-Definition: aggregates.hh:82\n-Dune::Amg::AggregatesMap::end\n-const_iterator end() const\n-Definition: aggregates.hh:730\n-Dune::Amg::AggregatesMap::AggregateDescriptor\n-V AggregateDescriptor\n-The aggregate descriptor type.\n-Definition: aggregates.hh:580\n-Dune::Amg::AggregatesMap::ISOLATED\n-static const V ISOLATED\n-Identifier of isolated vertices.\n-Definition: aggregates.hh:571\n-Dune::Amg::SymmetricDependency::row_\n-int row_\n-index of the currently evaluated row.\n-Definition: aggregates.hh:365\n-Dune::Amg::SymmetricMatrixDependency::SymmetricMatrixDependency\n-SymmetricMatrixDependency()\n-Definition: aggregates.hh:171\n-Dune::Amg::Aggregator::DependencyCounter::DependencyCounter\n-DependencyCounter()\n-Constructor.\n-Dune::Amg::Aggregator::Stack::pop\n-Vertex pop()\n-Dune::Amg::Dependency::diagonal_\n-real_type diagonal_\n-The norm of the current diagonal.\n-Definition: aggregates.hh:306\n-Dune::Amg::AggregatesMap::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices.\n-Dune::Amg::AggregationCriterion::setDefaultValuesAnisotropic\n-void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)\n-Sets reasonable default values for an aisotropic problem.\n-Definition: aggregates.hh:105\n-Dune::Amg::AggregatesMap::AggregatesMap\n-AggregatesMap(std::size_t noVertices)\n-Constructs with allocating memory.\n-Dune::Amg::SymmetricDependency::field_type\n-Matrix::field_type field_type\n-The current max value.\n-Definition: aggregates.hh:359\n-Dune::Amg::AggregatesMap::operator[]\n-AggregateDescriptor & operator[](const VertexDescriptor &v)\n-Get the aggregate a vertex belongs to.\n-Dune::Amg::AggregatesMap::AggregatesMap\n-AggregatesMap()\n-Constructs without allocating memory.\n-Dune::Amg::Aggregator::Counter::value\n-int value()\n-Access the current count.\n-Dune::Amg::AggregatesMap::VertexList\n-SLList< VertexDescriptor, Allocator > VertexList\n-The type of a single linked list of vertex descriptors.\n-Definition: aggregates.hh:592\n-Dune::Amg::Aggregator::Stack::~Stack\n-~Stack()\n-Dune::Amg::Aggregator::ConnectivityCounter::ConnectivityCounter\n-ConnectivityCounter(const VertexSet &connected, const AggregatesMap< Vertex >\n-&aggregates)\n-Constructor.\n-Dune::Amg::Aggregate::size\n-VertexSet::size_type size()\n-Get the size of the aggregate.\n-Dune::Amg::Aggregate::end\n-const_iterator end() const\n-get an iterator over the vertices of the aggregate.\n-Dune::Amg::SymmetricDependency::init\n-void init(const Matrix *matrix)\n-Dune::Amg::UnSymmetricCriterion::UnSymmetricCriterion\n-UnSymmetricCriterion()\n-Definition: aggregates.hh:544\n-Dune::Amg::Aggregator::FrontNeighbourCounter::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::AggregatesMap::const_iterator\n-const AggregateDescriptor * const_iterator\n-Definition: aggregates.hh:723\n-Dune::Amg::Dependency::row_\n-int row_\n-index of the currently evaluated row.\n-Definition: aggregates.hh:304\n-Dune::Amg::Aggregator::Stack::Stack\n-Stack(const MatrixGraph &graph, const Aggregator< G > &aggregatesBuilder, const\n-AggregatesMap< Vertex > &aggregates)\n-Dune::Amg::SymmetricMatrixDependency::real_type\n-FieldTraits< field_type >::real_type real_type\n-Definition: aggregates.hh:180\n-Dune::Amg::SymmetricDependency::initRow\n-void initRow(const Row &row, int index)\n-Dune::Amg::SymmetricMatrixDependency::Matrix\n-M Matrix\n-The matrix type we build the dependency of.\n-Definition: aggregates.hh:139\n-Dune::Amg::Dependency::real_type\n-FieldTraits< field_type >::real_type real_type\n-Definition: aggregates.hh:299\n-Dune::Amg::SymmetricMatrixDependency::matrix_\n-const Matrix * matrix_\n-The matrix we work on.\n-Definition: aggregates.hh:177\n-Dune::Amg::Aggregate::VertexSet\n-S VertexSet\n-The type of a single linked list of vertex descriptors.\n-Definition: aggregates.hh:801\n-Dune::Amg::FrobeniusNorm::operator()\n-FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n-compute the norm of a matrix.\n-Definition: aggregates.hh:490\n-Dune::Amg::AggregatesMap::UNAGGREGATED\n-static const V UNAGGREGATED\n-Identifier of not yet aggregated vertices.\n-Definition: aggregates.hh:566\n-Dune::Amg::AggregatesMap::breadthFirstSearch\n-std::size_t breadthFirstSearch(const VertexDescriptor &start, const\n-AggregateDescriptor &aggregate, const G &graph, F &aggregateVisitor, VM\n-&visitedMap) const\n-Breadth first search within an aggregate.\n-Dune::Amg::Dependency::field_type\n-Matrix::field_type field_type\n-The current max value.\n-Definition: aggregates.hh:298\n-Dune::Amg::Aggregator::OneWayCounter::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::operator<<\n-std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T >\n-&criterion)\n-Definition: aggregates.hh:113\n-Dune::Amg::SymmetricMatrixDependency::isIsolated\n-bool isIsolated()\n-Definition: aggregates.hh:240\n-Dune::Amg::AggregatesMap::allocate\n-void allocate(std::size_t noVertices)\n-Allocate memory for holding the information.\n-Dune::Amg::SymmetricMatrixDependency::Norm\n-N Norm\n-The norm to use for examining the matrix entries.\n-Definition: aggregates.hh:144\n-Dune::Amg::RowSum::operator()\n-FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n-compute the norm of a matrix.\n-Definition: aggregates.hh:473\n-Dune::Amg::Aggregate::reconstruct\n-void reconstruct(const Vertex &vertex)\n-Reconstruct the aggregat from an seed node.\n-Dune::Amg::Aggregate::begin\n-const_iterator begin() const\n-get an iterator over the vertices of the aggregate.\n-Dune::Amg::Diagonal::operator()\n-FieldTraits< typenameM::field_type >::real_type operator()(const M &m, typename\n-std::enable_if_t::value > *sfinae=nullptr) const\n-compute the norm of a matrix.\n-Definition: aggregates.hh:390\n-Dune::Amg::Aggregate::Vertex\n-MatrixGraph::VertexDescriptor Vertex\n-The vertex descriptor type.\n-Definition: aggregates.hh:789\n-Dune::Amg::Aggregate::seed\n-void seed(const Vertex &vertex)\n-Initialize the aggregate with one vertex.\n-Dune::Amg::SymmetricDependency::isIsolated\n-bool isIsolated()\n-Dune::Amg::SymmetricDependency::SymmetricDependency\n-SymmetricDependency()\n-Definition: aggregates.hh:351\n-Dune::Amg::Aggregate::clear\n-void clear()\n-Clear the aggregate.\n-Dune::Amg::AggregatesMap::free\n-void free()\n-Free the allocated memory.\n-Dune::Amg::Aggregator::Counter::increment\n-void increment()\n-Increment counter.\n-Dune::Amg::buildDependency\n-void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion,\n-bool finestLevel)\n-Build the dependency of the matrix graph.\n-Dune::Amg::AggregatesMap::VertexDescriptor\n-V VertexDescriptor\n-The vertex descriptor type.\n-Definition: aggregates.hh:575\n-Dune::Amg::Dependency::maxValue_\n-real_type maxValue_\n-Definition: aggregates.hh:300\n-Dune::Amg::AggregatesMap::buildAggregates\n-std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph,\n-const C &criterion, bool finestLevel)\n-Build the aggregates.\n-Dune::Amg::SymmetricMatrixDependency::Row\n-Matrix::row_type Row\n-Constant Row iterator of the matrix.\n-Definition: aggregates.hh:149\n-Dune::Amg::Aggregate::Allocator\n-PoolAllocator< Vertex, 100 > Allocator\n-The allocator we use for our lists and the set.\n-Definition: aggregates.hh:795\n-Dune::Amg::Aggregate::MatrixGraph\n-G MatrixGraph\n-Definition: aggregates.hh:785\n-Dune::Amg::Aggregator::DependencyCounter::operator()\n-void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n-Dune::Amg::FrobeniusNorm::is_sign_preserving\n-@ is_sign_preserving\n-Definition: aggregates.hh:483\n-Dune::Amg::Diagonal::is_sign_preserving\n-@ is_sign_preserving\n-Definition: aggregates.hh:382\n-Dune::Amg::AlwaysOneNorm::is_sign_preserving\n-@ is_sign_preserving\n-Definition: aggregates.hh:499\n-Dune::Amg::RowSum::is_sign_preserving\n-@ is_sign_preserving\n-Definition: aggregates.hh:466\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n+Dune::redistributeMatrixEntries\n+void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C\n+&newComm, RedistributeInformation< C > &ri)\n+Definition: matrixredistribute.hh:757\n+Dune::redistributeSparsityPattern\n+void redistributeSparsityPattern(M &origMatrix, M &newMatrix, C &origComm, C\n+&newComm, RedistributeInformation< C > &ri)\n+Definition: matrixredistribute.hh:663\n+Dune::redistributeMatrix\n+void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm,\n+RedistributeInformation< C > &ri)\n+Redistribute a matrix according to given domain decompositions.\n+Definition: matrixredistribute.hh:820\n Dune::ISTLError\n derive error class from the base class in common\n Definition: istlexception.hh:19\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::field_type\n-typename Imp::BlockTraits< T >::field_type field_type\n-Export the type representing the underlying field.\n-Definition: matrix.hh:565\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n-Dune::Matrix::row_type\n-MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n-The type implementing a matrix row.\n-Definition: matrix.hh:574\n-Dune::Amg::AggregationCriterion\n-Base class of all aggregation criterions.\n-Definition: aggregates.hh:49\n-Dune::Amg::SymmetricMatrixDependency\n-Dependency policy for symmetric matrices.\n-Definition: aggregates.hh:134\n-Dune::Amg::Dependency\n-Dependency policy for symmetric matrices.\n-Definition: aggregates.hh:253\n-Dune::Amg::SymmetricDependency\n-Dependency policy for symmetric matrices.\n-Definition: aggregates.hh:314\n-Dune::Amg::Diagonal\n-Norm that uses only the [N][N] entry of the block to determine couplings.\n-Definition: aggregates.hh:379\n-Dune::Amg::FirstDiagonal\n-Norm that uses only the [0][0] entry of the block to determine couplings.\n-Definition: aggregates.hh:455\n-Dune::Amg::RowSum\n-Functor using the row sum (infinity) norm to determine strong couplings.\n-Definition: aggregates.hh:463\n-Dune::Amg::FrobeniusNorm\n-Definition: aggregates.hh:480\n-Dune::Amg::AlwaysOneNorm\n-Definition: aggregates.hh:496\n-Dune::Amg::SymmetricCriterion\n-Criterion taking advantage of symmetric matrices.\n-Definition: aggregates.hh:519\n-Dune::Amg::UnSymmetricCriterion\n-Criterion suitable for unsymmetric matrices.\n-Definition: aggregates.hh:539\n-Dune::Amg::Aggregator\n-Class for building the aggregates.\n-Definition: aggregates.hh:909\n-Dune::Amg::AggregatesMap\n-Class providing information about the mapping of the vertices onto aggregates.\n-Definition: aggregates.hh:560\n-Dune::Amg::AggregatesMap::DummyEdgeVisitor\n-A Dummy visitor that does nothing for each visited edge.\n-Definition: aggregates.hh:598\n-Dune::Amg::Aggregate\n-A class for temporarily storing the vertices of an aggregate in.\n-Definition: aggregates.hh:778\n-Dune::Amg::MatrixGraph::VertexDescriptor\n-M::size_type VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:73\n-Dune::Amg::MatrixGraph::ConstEdgeIterator\n-EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator\n-The constant edge iterator type.\n-Definition: graph.hh:298\n-Dune::Amg::MatrixGraph::EdgeIteratorT\n-Iterator over all edges starting from a vertex.\n-Definition: graph.hh:95\n-Dune::Amg::MatrixGraph::VertexIteratorT\n-The vertex iterator type of the graph.\n-Definition: graph.hh:209\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n+Dune::RedistributeInformation\n+Definition: matrixredistribute.hh:22\n+Dune::RedistributeInformation::setNoBackwardsCopyRows\n+void setNoBackwardsCopyRows(std::size_t size)\n+Definition: matrixredistribute.hh:44\n+Dune::RedistributeInformation::redistribute\n+void redistribute(const D &from, D &to) const\n+Definition: matrixredistribute.hh:28\n+Dune::RedistributeInformation::resetSetup\n+void resetSetup()\n+Definition: matrixredistribute.hh:35\n+Dune::RedistributeInformation::setNoCopyRows\n+void setNoCopyRows(std::size_t size)\n+Definition: matrixredistribute.hh:41\n+Dune::RedistributeInformation::isSetup\n+bool isSetup() const\n+Definition: matrixredistribute.hh:23\n+Dune::RedistributeInformation::setNoRows\n+void setNoRows(std::size_t size)\n+Definition: matrixredistribute.hh:38\n+Dune::RedistributeInformation::redistributeBackward\n+void redistributeBackward(D &from, const D &to) const\n+Definition: matrixredistribute.hh:32\n+Dune::RedistributeInformation::getBackwardsCopyRowSize\n+std::size_t getBackwardsCopyRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:57\n+Dune::RedistributeInformation::getRowSize\n+std::size_t getRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:47\n+Dune::RedistributeInformation::getCopyRowSize\n+std::size_t getCopyRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:52\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getRowSize\n+std::size_t getRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:158\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getBackwardsCopyRowSize\n+std::size_t & getBackwardsCopyRowSize(std::size_t index)\n+Definition: matrixredistribute.hh:173\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getInterface\n+RedistributeInterface & getInterface()\n+Definition: matrixredistribute.hh:75\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+redistribute\n+void redistribute(const D &from, D &to) const\n+Definition: matrixredistribute.hh:136\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+setNoBackwardsCopyRows\n+void setNoBackwardsCopyRows(std::size_t rows)\n+Definition: matrixredistribute.hh:193\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getCopyRowSize\n+std::size_t & getCopyRowSize(std::size_t index)\n+Definition: matrixredistribute.hh:163\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+RedistributeInformation\n+RedistributeInformation()\n+Definition: matrixredistribute.hh:71\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getCopyRowSize\n+std::size_t getCopyRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:168\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+setNoRows\n+void setNoRows(std::size_t rows)\n+Definition: matrixredistribute.hh:183\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+reserve\n+void reserve(std::size_t size)\n+Definition: matrixredistribute.hh:150\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::Comm\n+OwnerOverlapCopyCommunication< T, T1 > Comm\n+Definition: matrixredistribute.hh:69\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+setNoCopyRows\n+void setNoCopyRows(std::size_t rows)\n+Definition: matrixredistribute.hh:188\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+redistributeBackward\n+void redistributeBackward(D &from, const D &to) const\n+Definition: matrixredistribute.hh:141\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+setSetup\n+void setSetup()\n+Definition: matrixredistribute.hh:106\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getBackwardsCopyRowSize\n+std::size_t getBackwardsCopyRowSize(std::size_t index) const\n+Definition: matrixredistribute.hh:178\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+redistribute\n+void redistribute(const D &from, D &to) const\n+Definition: matrixredistribute.hh:118\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+resetSetup\n+void resetSetup()\n+Definition: matrixredistribute.hh:112\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+redistributeBackward\n+void redistributeBackward(D &from, const D &to) const\n+Definition: matrixredistribute.hh:126\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+checkInterface\n+void checkInterface(const IS &source, const IS &target, MPI_Comm comm)\n+Definition: matrixredistribute.hh:80\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+isSetup\n+bool isSetup() const\n+Definition: matrixredistribute.hh:145\n+Dune::RedistributeInformation<_OwnerOverlapCopyCommunication<_T,_T1_>_>::\n+getRowSize\n+std::size_t & getRowSize(std::size_t index)\n+Definition: matrixredistribute.hh:153\n+Dune::CommMatrixRowSize\n+Utility class to communicate and set the row sizes of a redistributed matrix.\n+Definition: matrixredistribute.hh:216\n+Dune::CommMatrixRowSize::size_type\n+M::size_type size_type\n+Definition: matrixredistribute.hh:219\n+Dune::CommMatrixRowSize::value_type\n+M::size_type value_type\n+Definition: matrixredistribute.hh:218\n+Dune::CommMatrixRowSize::rowsize\n+RI & rowsize\n+Definition: matrixredistribute.hh:230\n+Dune::CommMatrixRowSize::matrix\n+const M & matrix\n+Definition: matrixredistribute.hh:229\n+Dune::CommMatrixRowSize::CommMatrixRowSize\n+CommMatrixRowSize(const M &m_, RI &rowsize_)\n+Constructor.\n+Definition: matrixredistribute.hh:226\n+Dune::CommMatrixSparsityPattern\n+Utility class to communicate and build the sparsity pattern of a redistributed\n+matrix.\n+Definition: matrixredistribute.hh:245\n+Dune::CommMatrixSparsityPattern::size_type\n+M::size_type size_type\n+Definition: matrixredistribute.hh:246\n+Dune::CommMatrixSparsityPattern::idxset\n+const Dune::GlobalLookupIndexSet< I > & idxset\n+Definition: matrixredistribute.hh:356\n+Dune::CommMatrixSparsityPattern::storeSparsityPattern\n+void storeSparsityPattern(M &m)\n+Creates and stores the sparsity pattern of the redistributed matrix.\n+Definition: matrixredistribute.hh:276\n+Dune::CommMatrixSparsityPattern::aggidxset\n+const I & aggidxset\n+Definition: matrixredistribute.hh:357\n+Dune::CommMatrixSparsityPattern::rowsize\n+const std::vector< size_type > * rowsize\n+Definition: matrixredistribute.hh:359\n+Dune::CommMatrixSparsityPattern::completeSparsityPattern\n+void completeSparsityPattern(std::vector< std::set< size_type > > add_sparsity)\n+Completes the sparsity pattern of the redistributed matrix with data from copy\n+rows for the novlp cas...\n+Definition: matrixredistribute.hh:340\n+Dune::CommMatrixSparsityPattern::CommMatrixSparsityPattern\n+CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I >\n+&idxset_, const I &aggidxset_)\n+Constructor for the original side.\n+Definition: matrixredistribute.hh:254\n+Dune::CommMatrixSparsityPattern::matrix\n+const M & matrix\n+Definition: matrixredistribute.hh:354\n+Dune::CommMatrixSparsityPattern::CommMatrixSparsityPattern\n+CommMatrixSparsityPattern(const M &m_, const Dune::GlobalLookupIndexSet< I >\n+&idxset_, const I &aggidxset_, const std::vector< typename M::size_type >\n+&rowsize_)\n+Constructor for the redistruted side.\n+Definition: matrixredistribute.hh:265\n+Dune::CommMatrixSparsityPattern::sparsity\n+std::vector< std::set< size_type > > sparsity\n+Definition: matrixredistribute.hh:358\n+Dune::CommMatrixSparsityPattern::LookupIndexSet\n+Dune::GlobalLookupIndexSet< I > LookupIndexSet\n+Definition: matrixredistribute.hh:355\n+Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::getSize\n+static M::size_type getSize(const Type &t, std::size_t i)\n+Definition: matrixredistribute.hh:376\n+Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::Type\n+CommMatrixSparsityPattern< M, I > Type\n+Definition: matrixredistribute.hh:365\n+Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::IndexedType\n+I::GlobalIndex IndexedType\n+The indexed type we send. This is the global index indentitfying the column.\n+Definition: matrixredistribute.hh:371\n+Dune::CommPolicy<_CommMatrixSparsityPattern<_M,_I_>_>::IndexedTypeFlag\n+VariableSize IndexedTypeFlag\n+Each row varies in size.\n+Definition: matrixredistribute.hh:374\n+Dune::CommMatrixRow\n+Utility class for comunicating the matrix entries.\n+Definition: matrixredistribute.hh:396\n+Dune::CommMatrixRow::rowsize\n+std::vector< size_t > * rowsize\n+row size information for the receiving side.\n+Definition: matrixredistribute.hh:452\n+Dune::CommMatrixRow::matrix\n+M & matrix\n+The matrix to communicate the values of.\n+Definition: matrixredistribute.hh:446\n+Dune::CommMatrixRow::CommMatrixRow\n+CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I\n+&aggidxset_, std::vector< size_t > &rowsize_)\n+Constructor.\n+Definition: matrixredistribute.hh:412\n+Dune::CommMatrixRow::idxset\n+const Dune::GlobalLookupIndexSet< I > & idxset\n+Index set for the original matrix.\n+Definition: matrixredistribute.hh:448\n+Dune::CommMatrixRow::setOverlapRowsToDirichlet\n+void setOverlapRowsToDirichlet()\n+Sets the non-owner rows correctly as Dirichlet boundaries.\n+Definition: matrixredistribute.hh:421\n+Dune::CommMatrixRow::aggidxset\n+const I & aggidxset\n+Index set for the redistributed matrix.\n+Definition: matrixredistribute.hh:450\n+Dune::CommMatrixRow::CommMatrixRow\n+CommMatrixRow(M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I\n+&aggidxset_)\n+Constructor.\n+Definition: matrixredistribute.hh:405\n+Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::IndexedType\n+std::pair< typename I::GlobalIndex, typename M::block_type > IndexedType\n+The indexed type we send. This is the pair of global index indentitfying the\n+column and the value its...\n+Definition: matrixredistribute.hh:464\n+Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::Type\n+CommMatrixRow< M, I > Type\n+Definition: matrixredistribute.hh:458\n+Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::getSize\n+static std::size_t getSize(const Type &t, std::size_t i)\n+Definition: matrixredistribute.hh:469\n+Dune::CommPolicy<_CommMatrixRow<_M,_I_>_>::IndexedTypeFlag\n+VariableSize IndexedTypeFlag\n+Each row varies in size.\n+Definition: matrixredistribute.hh:467\n+Dune::MatrixRowSizeGatherScatter\n+Definition: matrixredistribute.hh:483\n+Dune::MatrixRowSizeGatherScatter::scatter\n+static void scatter(Container &cont, const typename M::size_type &rowsize,\n+std::size_t i)\n+Definition: matrixredistribute.hh:490\n+Dune::MatrixRowSizeGatherScatter::gather\n+static const M::size_type gather(const Container &cont, std::size_t i)\n+Definition: matrixredistribute.hh:486\n+Dune::MatrixRowSizeGatherScatter::Container\n+CommMatrixRowSize< M, RI > Container\n+Definition: matrixredistribute.hh:484\n+Dune::MatrixCopyRowSizeGatherScatter\n+Definition: matrixredistribute.hh:500\n+Dune::MatrixCopyRowSizeGatherScatter::gather\n+static const M::size_type gather(const Container &cont, std::size_t i)\n+Definition: matrixredistribute.hh:503\n+Dune::MatrixCopyRowSizeGatherScatter::scatter\n+static void scatter(Container &cont, const typename M::size_type &rowsize,\n+std::size_t i)\n+Definition: matrixredistribute.hh:507\n+Dune::MatrixCopyRowSizeGatherScatter::Container\n+CommMatrixRowSize< M, RI > Container\n+Definition: matrixredistribute.hh:501\n+Dune::MatrixSparsityPatternGatherScatter\n+Definition: matrixredistribute.hh:518\n+Dune::MatrixSparsityPatternGatherScatter::ColIter\n+M::ConstColIterator ColIter\n+Definition: matrixredistribute.hh:521\n+Dune::MatrixSparsityPatternGatherScatter::scatter\n+static void scatter(Container &cont, const GlobalIndex &gi, std::size_t i,\n+std::size_t j)\n+Definition: matrixredistribute.hh:553\n+Dune::MatrixSparsityPatternGatherScatter::Container\n+CommMatrixSparsityPattern< M, I > Container\n+Definition: matrixredistribute.hh:520\n+Dune::MatrixSparsityPatternGatherScatter::numlimits\n+static GlobalIndex numlimits\n+Definition: matrixredistribute.hh:524\n+Dune::MatrixSparsityPatternGatherScatter::col\n+static ColIter col\n+Definition: matrixredistribute.hh:523\n+Dune::MatrixSparsityPatternGatherScatter::GlobalIndex\n+I::GlobalIndex GlobalIndex\n+Definition: matrixredistribute.hh:519\n+Dune::MatrixSparsityPatternGatherScatter::gather\n+static const GlobalIndex & gather(const Container &cont, std::size_t i, std::\n+size_t j)\n+Definition: matrixredistribute.hh:526\n+Dune::MatrixRowGatherScatter\n+Definition: matrixredistribute.hh:599\n+Dune::MatrixRowGatherScatter::GlobalIndex\n+I::GlobalIndex GlobalIndex\n+Definition: matrixredistribute.hh:600\n+Dune::MatrixRowGatherScatter::datastore\n+static Data datastore\n+Definition: matrixredistribute.hh:605\n+Dune::MatrixRowGatherScatter::numlimits\n+static GlobalIndex numlimits\n+Definition: matrixredistribute.hh:606\n+Dune::MatrixRowGatherScatter::ColIter\n+M::ConstColIterator ColIter\n+Definition: matrixredistribute.hh:602\n+Dune::MatrixRowGatherScatter::gather\n+static const Data & gather(const Container &cont, std::size_t i, std::size_t j)\n+Definition: matrixredistribute.hh:608\n+Dune::MatrixRowGatherScatter::Data\n+std::pair< GlobalIndex, typename M::block_type > Data\n+Definition: matrixredistribute.hh:603\n+Dune::MatrixRowGatherScatter::scatter\n+static void scatter(Container &cont, const Data &data, std::size_t i, std::\n+size_t j)\n+Definition: matrixredistribute.hh:638\n+Dune::MatrixRowGatherScatter::col\n+static ColIter col\n+Definition: matrixredistribute.hh:604\n+Dune::MatrixRowGatherScatter::Container\n+CommMatrixRow< M, I > Container\n+Definition: matrixredistribute.hh:601\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::OwnerSet\n+EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet\n+Definition: owneroverlapcopy.hh:194\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::RedistributeInterface\n+Definition: repartition.hh:260\n+Dune::SolverCategory::nonoverlapping\n+@ nonoverlapping\n+Category for non-overlapping solvers.\n+Definition: solvercategory.hh:27\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00104.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00104.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: galerkin.hh File Reference\n+dune-istl: cholmod.hh File Reference\n \n \n \n \n \n \n \n@@ -58,74 +58,23 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n- \n- \n+
    cholmod.hh File Reference
    \n
    \n
    \n \n-

    Provides a class for building the galerkin product based on a aggregation scheme. \n-More...

    \n-
    #include "aggregates.hh"
    \n-#include "pinfo.hh"
    \n-#include <dune/common/poolallocator.hh>
    \n-#include <dune/common/enumset.hh>
    \n-#include <set>
    \n-#include <limits>
    \n-#include <algorithm>
    \n-
    \n

    Go to the source code of this file.

    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    struct  Dune::Amg::OverlapVertex< T >
     
    class  Dune::Amg::SparsityBuilder< M >
     Functor for building the sparsity pattern of the matrix using examineConnectivity. More...
     
    class  Dune::Amg::BaseGalerkinProduct
     
    class  Dune::Amg::GalerkinProduct< T >
     
    class  Dune::Amg::GalerkinProduct< SequentialInformation >
     
    struct  Dune::Amg::BaseConnectivityConstructor
     
    class  Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder< G, S, V >
     Visitor for identifying connected aggregates during a breadthFirstSearch. More...
     
    struct  Dune::Amg::ConnectivityConstructor< G, T >
     
    struct  Dune::Amg::ConnectivityConstructor< G, SequentialInformation >
     
    struct  Dune::Amg::DirichletBoundarySetter< T >
     
    struct  Dune::Amg::DirichletBoundarySetter< SequentialInformation >
     
    \n-\n-\n-\n-\n-\n-

    \n-Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Provides a class for building the galerkin product based on a aggregation scheme.

    \n-
    Author
    Markus Blatt
    \n-
    \n+\n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,62 +4,12 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces\n-galerkin.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides a class for building the galerkin product based on a aggregation\n-scheme. More...\n-#include \"aggregates.hh\"\n-#include \"pinfo.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n+cholmod.hh File Reference\n Go_to_the_source_code_of_this_file.\n- Classes\n-struct \u00a0Dune::Amg::OverlapVertex<_T_>\n-\u00a0\n- class \u00a0Dune::Amg::SparsityBuilder<_M_>\n-\u00a0 Functor for building the sparsity pattern of the matrix using\n- examineConnectivity. More...\n-\u00a0\n- class \u00a0Dune::Amg::BaseGalerkinProduct\n-\u00a0\n- class \u00a0Dune::Amg::GalerkinProduct<_T_>\n-\u00a0\n- class \u00a0Dune::Amg::GalerkinProduct<_SequentialInformation_>\n-\u00a0\n-struct \u00a0Dune::Amg::BaseConnectivityConstructor\n-\u00a0\n- class \u00a0Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder<_G,_S,_V_>\n-\u00a0 Visitor for identifying connected aggregates during a\n- breadthFirstSearch. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConnectivityConstructor<_G,_T_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConnectivityConstructor<_G,_SequentialInformation_>\n-\u00a0\n-struct \u00a0Dune::Amg::DirichletBoundarySetter<_T_>\n-\u00a0\n-struct \u00a0Dune::Amg::DirichletBoundarySetter<_SequentialInformation_>\n-\u00a0\n- Namespaces\n-namespace \u00a0Dune\n-\u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n-***** Detailed Description *****\n-Provides a class for building the galerkin product based on a aggregation\n-scheme.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00104_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00104_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: galerkin.hh Source File\n+dune-istl: cholmod.hh Source File\n \n \n \n \n \n \n \n@@ -58,681 +58,383 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    galerkin.hh
    \n+
    cholmod.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n-
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_GALERKIN_HH
    \n-
    6#define DUNE_GALERKIN_HH
    \n-
    7
    \n-
    8#include "aggregates.hh"
    \n-
    9#include "pinfo.hh"
    \n-
    10#include <dune/common/poolallocator.hh>
    \n-
    11#include <dune/common/enumset.hh>
    \n-
    12#include <set>
    \n-
    13#include <limits>
    \n-
    14#include <algorithm>
    \n-
    15
    \n-
    16namespace Dune
    \n-
    17{
    \n-
    18 namespace Amg
    \n-
    19 {
    \n-
    31 template<class T>
    \n-\n-
    33 {
    \n-
    37 typedef T Aggregate;
    \n-
    38
    \n-
    42 typedef T Vertex;
    \n-
    43
    \n-\n-
    48
    \n-\n-
    53 };
    \n-
    54
    \n-
    55
    \n-
    56
    \n-
    61 template<class M>
    \n-\n-
    63 {
    \n-
    64 public:
    \n-
    70 SparsityBuilder(M& matrix);
    \n+
    3#pragma once
    \n+
    4
    \n+
    5#if HAVE_SUITESPARSE_CHOLMOD
    \n+
    6
    \n+
    7#include <dune/common/fmatrix.hh>
    \n+
    8#include <dune/common/fvector.hh>
    \n+\n+
    10#include <dune/istl/bvector.hh>
    \n+
    11#include<dune/istl/solver.hh>
    \n+\n+
    13#include <dune/istl/foreach.hh>
    \n+
    14
    \n+
    15#include <vector>
    \n+
    16#include <memory>
    \n+
    17
    \n+
    18#include <cholmod.h>
    \n+
    19
    \n+
    20namespace Dune {
    \n+
    21
    \n+
    22namespace Impl{
    \n+
    23
    \n+
    32 struct NoIgnore
    \n+
    33 {
    \n+
    34 const NoIgnore& operator[](std::size_t) const { return *this; }
    \n+
    35 explicit operator bool() const { return false; }
    \n+
    36 static constexpr std::size_t size() { return 0; }
    \n+
    37
    \n+
    38 };
    \n+
    39
    \n+
    40
    \n+
    41 template<class BlockedVector, class FlatVector>
    \n+
    42 void copyToFlatVector(const BlockedVector& blockedVector, FlatVector& flatVector)
    \n+
    43 {
    \n+
    44 // traverse the vector once just to compute the size
    \n+
    45 std::size_t len = flatVectorForEach(blockedVector, [&](auto&&, auto...){});
    \n+
    46 flatVector.resize(len);
    \n+
    47
    \n+
    48 flatVectorForEach(blockedVector, [&](auto&& entry, auto offset){
    \n+
    49 flatVector[offset] = entry;
    \n+
    50 });
    \n+
    51 }
    \n+
    52
    \n+
    53 // special (dummy) case for NoIgnore
    \n+
    54 template<class FlatVector>
    \n+
    55 void copyToFlatVector(const NoIgnore&, FlatVector&)
    \n+
    56 {
    \n+
    57 // just do nothing
    \n+
    58 return;
    \n+
    59 }
    \n+
    60
    \n+
    61 template<class FlatVector, class BlockedVector>
    \n+
    62 void copyToBlockedVector(const FlatVector& flatVector, BlockedVector& blockedVector)
    \n+
    63 {
    \n+
    64 flatVectorForEach(blockedVector, [&](auto& entry, auto offset){
    \n+
    65 entry = flatVector[offset];
    \n+
    66 });
    \n+
    67 }
    \n+
    68
    \n+
    69
    \n+
    70} //namespace Impl
    \n
    71
    \n-
    72 void insert(const typename M::size_type& index);
    \n-
    73
    \n-
    74 void operator++();
    \n-
    75
    \n-
    76 std::size_t minRowSize();
    \n-
    77
    \n-
    78 std::size_t maxRowSize();
    \n-
    79
    \n-
    80 std::size_t sumRowSize();
    \n-
    81 std::size_t index()
    \n-
    82 {
    \n-
    83 return row_.index();
    \n-
    84 }
    \n-
    85 private:
    \n-
    87 typename M::CreateIterator row_;
    \n-
    89 std::size_t minRowSize_;
    \n-
    91 std::size_t maxRowSize_;
    \n-
    92 std::size_t sumRowSize_;
    \n-
    93#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    94 bool diagonalInserted;
    \n-
    95#endif
    \n-
    96 };
    \n-
    97
    \n-\n-
    99 {
    \n-
    100 public:
    \n-
    109 template<class M, class V, class I, class O>
    \n-
    110 void calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
    \n-
    111 const I& pinfo, const O& copy);
    \n-
    112
    \n-
    113 };
    \n+
    76template<class Vector>
    \n+
    77class Cholmod : public InverseOperator<Vector, Vector>
    \n+
    78{
    \n+
    79public:
    \n+
    80
    \n+
    86 Cholmod()
    \n+
    87 {
    \n+
    88 cholmod_start(&c_);
    \n+
    89 }
    \n+
    90
    \n+
    96 ~Cholmod()
    \n+
    97 {
    \n+
    98 if (L_)
    \n+
    99 cholmod_free_factor(&L_, &c_);
    \n+
    100 cholmod_finish(&c_);
    \n+
    101 }
    \n+
    102
    \n+
    103 // forbid copying to avoid freeing memory twice
    \n+
    104 Cholmod(const Cholmod&) = delete;
    \n+
    105 Cholmod& operator=(const Cholmod&) = delete;
    \n+
    106
    \n+
    107
    \n+
    110 void apply (Vector& x, Vector& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n+
    111 {
    \n+
    112 apply(x,b,res);
    \n+
    113 }
    \n
    114
    \n-
    115 template<class T>
    \n-\n-
    117 : public BaseGalerkinProduct
    \n-
    118 {
    \n-
    119 public:
    \n-\n-
    121
    \n-
    131 template<class G, class V, class Set>
    \n-
    132 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
    \n-
    133 const ParallelInformation& pinfo,
    \n-\n-
    135 const typename G::Matrix::size_type& size,
    \n-
    136 const Set& copy);
    \n-
    137 private:
    \n-
    138
    \n-
    145 template<class G, class I, class Set>
    \n-\n-
    147 buildOverlapVertices(const G& graph, const I& pinfo,
    \n-\n-
    149 const Set& overlap,
    \n-
    150 std::size_t& overlapCount);
    \n+
    120 void apply(Vector& x, Vector& b, InverseOperatorResult& res)
    \n+
    121 {
    \n+
    122 // do nothing if N=0
    \n+
    123 if ( nIsZero_ )
    \n+
    124 {
    \n+
    125 return;
    \n+
    126 }
    \n+
    127
    \n+
    128 if (x.size() != b.size())
    \n+
    129 DUNE_THROW(Exception, "Error in apply(): sizes of x and b do not match!");
    \n+
    130
    \n+
    131 // cast to double array
    \n+
    132 auto b2 = std::make_unique<double[]>(L_->n);
    \n+
    133 auto x2 = std::make_unique<double[]>(L_->n);
    \n+
    134
    \n+
    135 // copy to cholmod
    \n+
    136 auto bp = b2.get();
    \n+
    137
    \n+
    138 flatVectorForEach(b, [&](auto&& entry, auto&& flatIndex){
    \n+
    139 if ( subIndices_.empty() )
    \n+
    140 bp[ flatIndex ] = entry;
    \n+
    141 else
    \n+
    142 if( subIndices_[ flatIndex ] != std::numeric_limits<std::size_t>::max() )
    \n+
    143 bp[ subIndices_[ flatIndex ] ] = entry;
    \n+
    144 });
    \n+
    145
    \n+
    146 // create a cholmod dense object
    \n+
    147 auto b3 = make_cholmod_dense(cholmod_allocate_dense(L_->n, 1, L_->n, CHOLMOD_REAL, &c_), &c_);
    \n+
    148 // cast because void-ptr
    \n+
    149 auto b4 = static_cast<double*>(b3->x);
    \n+
    150 std::copy(b2.get(), b2.get() + L_->n, b4);
    \n
    151
    \n-
    152 template<class A>
    \n-
    153 struct OVLess
    \n-
    154 {
    \n-\n-
    156 {
    \n-
    157 return *o1.aggregate < *o2.aggregate;
    \n-
    158 }
    \n-
    159 };
    \n-
    160 };
    \n-
    161
    \n-
    162 template<>
    \n-\n-
    164 : public BaseGalerkinProduct
    \n-
    165 {
    \n-
    166 public:
    \n-
    176 template<class G, class V, class Set>
    \n-
    177 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
    \n-
    178 const SequentialInformation& pinfo,
    \n-\n-
    180 const typename G::Matrix::size_type& size,
    \n-
    181 const Set& copy);
    \n-
    182 };
    \n+
    152 // solve for a cholmod x object
    \n+
    153 auto x3 = make_cholmod_dense(cholmod_solve(CHOLMOD_A, L_, b3.get(), &c_), &c_);
    \n+
    154 // cast because void-ptr
    \n+
    155 auto xp = static_cast<double*>(x3->x);
    \n+
    156
    \n+
    157 // copy into x
    \n+
    158 flatVectorForEach(x, [&](auto&& entry, auto&& flatIndex){
    \n+
    159 if ( subIndices_.empty() )
    \n+
    160 entry = xp[ flatIndex ];
    \n+
    161 else
    \n+
    162 if( subIndices_[ flatIndex ] != std::numeric_limits<std::size_t>::max() )
    \n+
    163 entry = xp[ subIndices_[ flatIndex ] ];
    \n+
    164 });
    \n+
    165
    \n+
    166 // statistics for a direct solver
    \n+
    167 res.iterations = 1;
    \n+
    168 res.converged = true;
    \n+
    169 }
    \n+
    170
    \n+
    171
    \n+
    177 template<class Matrix>
    \n+
    178 void setMatrix(const Matrix& matrix)
    \n+
    179 {
    \n+
    180 const Impl::NoIgnore* noIgnore = nullptr;
    \n+
    181 setMatrix(matrix, noIgnore);
    \n+
    182 }
    \n
    183
    \n-\n-
    185 {
    \n-
    186 template<class R, class G, class V>
    \n-
    187 static void constructOverlapConnectivity(R& row, G& graph, V& visitedMap,
    \n-\n-\n-\n-
    191
    \n-
    195 template<class R, class G, class V>
    \n-
    196 static void constructNonOverlapConnectivity(R& row, G& graph, V& visitedMap,
    \n-\n-
    198 const typename G::VertexDescriptor& seed);
    \n-
    199
    \n-
    200
    \n-
    204 template<class G, class S, class V>
    \n-\n-
    206 {
    \n-
    207 public:
    \n-
    211 typedef G Graph;
    \n-
    215 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;
    \n-
    216
    \n-
    220 typedef S Set;
    \n+
    198 template<class Matrix, class Ignore>
    \n+
    199 void setMatrix(const Matrix& matrix, const Ignore* ignore)
    \n+
    200 {
    \n+
    201 // count the number of entries and diagonal entries
    \n+
    202 int nonZeros = 0;
    \n+
    203 int numberOfIgnoredDofs = 0;
    \n+
    204
    \n+
    205
    \n+
    206 auto [flatRows,flatCols] = flatMatrixForEach( matrix, [&](auto&& /*entry*/, auto&& flatRowIndex, auto&& flatColIndex){
    \n+
    207 if( flatRowIndex <= flatColIndex )
    \n+
    208 nonZeros++;
    \n+
    209 });
    \n+
    210
    \n+
    211 std::vector<bool> flatIgnore;
    \n+
    212
    \n+
    213 if ( ignore )
    \n+
    214 {
    \n+
    215 Impl::copyToFlatVector(*ignore,flatIgnore);
    \n+
    216 numberOfIgnoredDofs = std::count(flatIgnore.begin(),flatIgnore.end(),true);
    \n+
    217 }
    \n+
    218
    \n+
    219 // Total number of rows
    \n+
    220 int N = flatRows - numberOfIgnoredDofs;
    \n
    221
    \n-
    225 typedef V VisitedMap;
    \n-
    226
    \n-
    230 typedef typename Graph::VertexDescriptor Vertex;
    \n-
    231
    \n-
    239 ConnectedBuilder(const AggregatesMap<Vertex>& aggregates, Graph& graph,
    \n-
    240 VisitedMap& visitedMap, Set& connected);
    \n-
    241
    \n-
    246 void operator()(const ConstEdgeIterator& edge);
    \n+
    222 nIsZero_ = (N <= 0);
    \n+
    223
    \n+
    224 if ( nIsZero_ )
    \n+
    225 {
    \n+
    226 return;
    \n+
    227 }
    \n+
    228
    \n+
    229 /*
    \n+
    230 * CHOLMOD uses compressed-column sparse matrices, but for symmetric
    \n+
    231 * matrices this is the same as the compressed-row sparse matrix used
    \n+
    232 * by DUNE. So we can just store M\u1d40 instead of M (as M = M\u1d40).
    \n+
    233 */
    \n+
    234 const auto deleter = [c = &this->c_](auto* p) {
    \n+
    235 cholmod_free_sparse(&p, c);
    \n+
    236 };
    \n+
    237 auto M = std::unique_ptr<cholmod_sparse, decltype(deleter)>(
    \n+
    238 cholmod_allocate_sparse(N, // # rows
    \n+
    239 N, // # cols
    \n+
    240 nonZeros, // # of nonzeroes
    \n+
    241 1, // indices are sorted ( 1 = true)
    \n+
    242 1, // matrix is "packed" ( 1 = true)
    \n+
    243 -1, // stype of matrix ( -1 = consider the lower part only )
    \n+
    244 CHOLMOD_REAL, // xtype of matrix ( CHOLMOD_REAL = single array, no complex numbers)
    \n+
    245 &c_ // cholmod_common ptr
    \n+
    246 ), deleter);
    \n
    247
    \n-
    248 private:
    \n-
    252 const AggregatesMap<Vertex>& aggregates_;
    \n+
    248 // copy the data of BCRS matrix to Cholmod Sparse matrix
    \n+
    249 int* Ap = static_cast<int*>(M->p);
    \n+
    250 int* Ai = static_cast<int*>(M->i);
    \n+
    251 double* Ax = static_cast<double*>(M->x);
    \n+
    252
    \n
    253
    \n-
    254 Graph& graph_;
    \n-
    255
    \n-
    259 VisitedMap& visitedMap_;
    \n+
    254 if ( ignore )
    \n+
    255 {
    \n+
    256 // init the mapping
    \n+
    257 subIndices_.resize(flatRows,std::numeric_limits<std::size_t>::max());
    \n+
    258
    \n+
    259 std::size_t subIndexCounter = 0;
    \n
    260
    \n-
    264 Set& connected_;
    \n-
    265 };
    \n-
    266
    \n-
    267 };
    \n-
    268
    \n-
    269 template<class G, class T>
    \n-\n-
    271 {
    \n-
    272 typedef typename G::VertexDescriptor Vertex;
    \n+
    261 for ( std::size_t i=0; i<flatRows; i++ )
    \n+
    262 {
    \n+
    263 if ( not flatIgnore[ i ] )
    \n+
    264 {
    \n+
    265 subIndices_[ i ] = subIndexCounter++;
    \n+
    266 }
    \n+
    267 }
    \n+
    268 }
    \n+
    269
    \n+
    270 // at first, we need to compute the row starts "Ap"
    \n+
    271 // therefore, we count all (not ignored) entries in each row and in the end we accumulate everything
    \n+
    272 flatMatrixForEach(matrix, [&](auto&& /*entry*/, auto&& flatRowIndex, auto&& flatColIndex){
    \n
    273
    \n-
    274 template<class V, class O, class R>
    \n-
    275 static void examine(G& graph,
    \n-
    276 V& visitedMap,
    \n-
    277 const T& pinfo,
    \n-
    278 const AggregatesMap<Vertex>& aggregates,
    \n-
    279 const O& overlap,
    \n-
    280 const OverlapVertex<Vertex>* overlapVertices,
    \n-
    281 const OverlapVertex<Vertex>* overlapEnd,
    \n-
    282 R& row);
    \n-
    283 };
    \n-
    284
    \n-
    285 template<class G>
    \n-\n-
    287 {
    \n-
    288 typedef typename G::VertexDescriptor Vertex;
    \n-
    289
    \n-
    290 template<class V, class R>
    \n-
    291 static void examine(G& graph,
    \n-
    292 V& visitedMap,
    \n-
    293 const SequentialInformation& pinfo,
    \n-
    294 const AggregatesMap<Vertex>& aggregates,
    \n-
    295 R& row);
    \n-
    296 };
    \n+
    274 // stop if ignored
    \n+
    275 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
    \n+
    276 return;
    \n+
    277
    \n+
    278 // stop if in lower half
    \n+
    279 if ( flatRowIndex > flatColIndex )
    \n+
    280 return;
    \n+
    281
    \n+
    282 // ok, count the entry
    \n+
    283 auto idx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
    \n+
    284 Ap[idx+1]++;
    \n+
    285
    \n+
    286 });
    \n+
    287
    \n+
    288 // now accumulate
    \n+
    289 Ap[0] = 0;
    \n+
    290 for ( int i=0; i<N; i++ )
    \n+
    291 {
    \n+
    292 Ap[i+1] += Ap[i];
    \n+
    293 }
    \n+
    294
    \n+
    295 // we need a compressed row position counter
    \n+
    296 std::vector<std::size_t> rowPosition(N,0);
    \n
    297
    \n-
    298 template<class T>
    \n-\n-
    300 {
    \n-
    301 template<class M, class O>
    \n-
    302 static void set(M& coarse, const T& pinfo, const O& copy);
    \n-
    303 };
    \n+
    298 // now we can set the entries
    \n+
    299 flatMatrixForEach(matrix, [&](auto&& entry, auto&& flatRowIndex, auto&& flatColIndex){
    \n+
    300
    \n+
    301 // stop if ignored
    \n+
    302 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
    \n+
    303 return;
    \n
    304
    \n-
    305 template<>
    \n-\n-
    307 {
    \n-
    308 template<class M, class O>
    \n-
    309 static void set(M& coarse, const SequentialInformation& pinfo, const O& copy);
    \n-
    310 };
    \n-
    311
    \n-
    312 template<class R, class G, class V>
    \n-\n-\n-
    315 const typename G::VertexDescriptor& seed)
    \n-
    316 {
    \n-
    317 assert(row.index()==aggregates[seed]);
    \n-
    318 row.insert(aggregates[seed]);
    \n-
    319 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
    \n-
    320 typedef typename G::VertexDescriptor Vertex;
    \n-
    321 typedef std::allocator<Vertex> Allocator;
    \n-
    322 typedef SLList<Vertex,Allocator> VertexList;
    \n-
    323 typedef typename AggregatesMap<Vertex>::DummyEdgeVisitor DummyVisitor;
    \n-
    324 VertexList vlist;
    \n-
    325 DummyVisitor dummy;
    \n-
    326 aggregates.template breadthFirstSearch<true,false>(seed,aggregates[seed], graph, vlist, dummy,
    \n-
    327 conBuilder, visitedMap);
    \n-
    328 }
    \n-
    329
    \n-
    330 template<class R, class G, class V>
    \n-\n-\n-\n-\n-
    335 {
    \n-
    336 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
    \n-
    337 const typename G::VertexDescriptor aggregate=*seed->aggregate;
    \n-
    338
    \n-
    339 if (row.index()==*seed->aggregate) {
    \n-
    340 while(seed != overlapEnd && aggregate == *seed->aggregate) {
    \n-
    341 row.insert(*seed->aggregate);
    \n-
    342 // Walk over all neighbours and add them to the connected array.
    \n-
    343 visitNeighbours(graph, seed->vertex, conBuilder);
    \n-
    344 // Mark vertex as visited
    \n-
    345 put(visitedMap, seed->vertex, true);
    \n-
    346 ++seed;
    \n-
    347 }
    \n-
    348 }
    \n-
    349 }
    \n-
    350
    \n-
    351 template<class G, class S, class V>
    \n-\n-
    353 Graph& graph, VisitedMap& visitedMap,
    \n-
    354 Set& connected)
    \n-
    355 : aggregates_(aggregates), graph_(graph), visitedMap_(visitedMap), connected_(connected)
    \n-
    356 {}
    \n-
    357
    \n-
    358 template<class G, class S, class V>
    \n-\n-
    360 {
    \n-
    361 const Vertex& vertex = aggregates_[edge.target()];
    \n-\n-\n-
    364 connected_.insert(vertex);
    \n-
    365 }
    \n-
    366
    \n-
    367 template<class T>
    \n-
    368 template<class G, class I, class Set>
    \n-\n-
    370 GalerkinProduct<T>::buildOverlapVertices(const G& graph, const I& pinfo,
    \n-\n-
    372 const Set& overlap,
    \n-
    373 std::size_t& overlapCount)
    \n-
    374 {
    \n-
    375 // count the overlap vertices.
    \n-
    376 typedef typename G::ConstVertexIterator ConstIterator;
    \n-
    377 typedef typename I::GlobalLookupIndexSet GlobalLookup;
    \n-
    378 typedef typename GlobalLookup::IndexPair IndexPair;
    \n-
    379
    \n-
    380 const ConstIterator end = graph.end();
    \n-
    381 overlapCount = 0;
    \n+
    305 // stop if in lower half
    \n+
    306 if ( flatRowIndex > flatColIndex )
    \n+
    307 return;
    \n+
    308
    \n+
    309 // ok, set the entry
    \n+
    310 auto rowIdx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
    \n+
    311 auto colIdx = ignore ? subIndices_[flatColIndex] : flatColIndex;
    \n+
    312 auto rowStart = Ap[rowIdx];
    \n+
    313 auto rowPos = rowPosition[rowIdx];
    \n+
    314 Ai[ rowStart + rowPos ] = colIdx;
    \n+
    315 Ax[ rowStart + rowPos ] = entry;
    \n+
    316 rowPosition[rowIdx]++;
    \n+
    317
    \n+
    318 });
    \n+
    319
    \n+
    320 // Now analyse the pattern and optimal row order
    \n+
    321 L_ = cholmod_analyze(M.get(), &c_);
    \n+
    322
    \n+
    323 // Do the factorization (this may take some time)
    \n+
    324 cholmod_factorize(M.get(), L_, &c_);
    \n+
    325 }
    \n+
    326
    \n+
    327 virtual SolverCategory::Category category() const
    \n+
    328 {
    \n+
    329 return SolverCategory::Category::sequential;
    \n+
    330 }
    \n+
    331
    \n+
    337 cholmod_common& cholmodCommonObject()
    \n+
    338 {
    \n+
    339 return c_;
    \n+
    340 }
    \n+
    341
    \n+
    347 cholmod_factor& cholmodFactor()
    \n+
    348 {
    \n+
    349 return *L_;
    \n+
    350 }
    \n+
    351
    \n+
    357 const cholmod_factor& cholmodFactor() const
    \n+
    358 {
    \n+
    359 return *L_;
    \n+
    360 }
    \n+
    361private:
    \n+
    362
    \n+
    363 // create a std::unique_ptr to a cholmod_dense object with a deleter
    \n+
    364 // that calls the appropriate cholmod cleanup routine
    \n+
    365 auto make_cholmod_dense(cholmod_dense* x, cholmod_common* c)
    \n+
    366 {
    \n+
    367 const auto deleter = [c](auto* p) {
    \n+
    368 cholmod_free_dense(&p, c);
    \n+
    369 };
    \n+
    370 return std::unique_ptr<cholmod_dense, decltype(deleter)>(x, deleter);
    \n+
    371 }
    \n+
    372
    \n+
    373 cholmod_common c_;
    \n+
    374 cholmod_factor* L_ = nullptr;
    \n+
    375
    \n+
    376 // indicator for a 0x0 problem (due to ignore dof's)
    \n+
    377 bool nIsZero_ = false;
    \n+
    378
    \n+
    379 // vector mapping all indices in flat order to the not ignored indices
    \n+
    380 std::vector<std::size_t> subIndices_;
    \n+
    381};
    \n
    382
    \n-
    383 const GlobalLookup& lookup=pinfo.globalLookup();
    \n-
    384
    \n-
    385 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
    \n-
    386 const IndexPair* pair = lookup.pair(*vertex);
    \n+
    383 struct CholmodCreator{
    \n+
    384 template<class F> struct isValidBlock : std::false_type{};
    \n+
    385 template<int k> struct isValidBlock<FieldVector<double,k>> : std::true_type{};
    \n+
    386 template<int k> struct isValidBlock<FieldVector<float,k>> : std::true_type{};
    \n
    387
    \n-
    388 if(pair!=0 && overlap.contains(pair->local().attribute()))
    \n-
    389 ++overlapCount;
    \n-
    390 }
    \n-
    391 // Allocate space
    \n-
    392 typedef typename G::VertexDescriptor Vertex;
    \n-
    393
    \n-
    394 OverlapVertex<Vertex>* overlapVertices = new OverlapVertex<Vertex>[overlapCount=0 ? 1 : overlapCount];
    \n-
    395 if(overlapCount==0)
    \n-
    396 return overlapVertices;
    \n-
    397
    \n-
    398 // Initialize them
    \n-
    399 overlapCount=0;
    \n-
    400 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
    \n-
    401 const IndexPair* pair = lookup.pair(*vertex);
    \n-
    402
    \n-
    403 if(pair!=0 && overlap.contains(pair->local().attribute())) {
    \n-
    404 overlapVertices[overlapCount].aggregate = &aggregates[pair->local()];
    \n-
    405 overlapVertices[overlapCount].vertex = pair->local();
    \n-
    406 ++overlapCount;
    \n-
    407 }
    \n-
    408 }
    \n-
    409
    \n-
    410 dverb << overlapCount<<" overlap vertices"<<std::endl;
    \n+
    388 template<class TL, typename M>
    \n+
    389 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n+
    390 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    391 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& /*config*/,
    \n+
    392 std::enable_if_t<isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n+
    393 {
    \n+
    394 using D = typename Dune::TypeListElement<1, TL>::type;
    \n+
    395 auto solver = std::make_shared<Dune::Cholmod<D>>();
    \n+
    396 solver->setMatrix(mat);
    \n+
    397 return solver;
    \n+
    398 }
    \n+
    399
    \n+
    400 // second version with SFINAE to validate the template parameters of Cholmod
    \n+
    401 template<typename TL, typename M>
    \n+
    402 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n+
    403 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    404 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n+
    405 std::enable_if_t<!isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n+
    406 {
    \n+
    407 DUNE_THROW(UnsupportedType, "Unsupported Type in Cholmod");
    \n+
    408 }
    \n+
    409 };
    \n+
    410 DUNE_REGISTER_DIRECT_SOLVER("cholmod", Dune::CholmodCreator());
    \n
    411
    \n-
    412 std::sort(overlapVertices, overlapVertices+overlapCount, OVLess<Vertex>());
    \n-
    413 // due to the sorting the isolated aggregates (to be skipped) are at the end.
    \n-
    414
    \n-
    415 return overlapVertices;
    \n-
    416 }
    \n-
    417
    \n-
    418 template<class G, class T>
    \n-
    419 template<class V, class O, class R>
    \n-\n-
    421 V& visitedMap,
    \n-
    422 const T& pinfo,
    \n-
    423 const AggregatesMap<Vertex>& aggregates,
    \n-
    424 const O& overlap,
    \n-
    425 const OverlapVertex<Vertex>* overlapVertices,
    \n-
    426 const OverlapVertex<Vertex>* overlapEnd,
    \n-
    427 R& row)
    \n-
    428 {
    \n-
    429 typedef typename T::GlobalLookupIndexSet GlobalLookup;
    \n-
    430 const GlobalLookup& lookup = pinfo.globalLookup();
    \n-
    431
    \n-
    432 typedef typename G::VertexIterator VertexIterator;
    \n-
    433
    \n-
    434 VertexIterator vend=graph.end();
    \n-
    435
    \n-
    436#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    437 std::set<Vertex> examined;
    \n-
    438#endif
    \n-
    439
    \n-
    440 // The aggregates owned by the process have lower local indices
    \n-
    441 // then those not owned. We process them in the first pass.
    \n-
    442 // They represent the rows 0, 1, ..., n of the coarse matrix
    \n-
    443 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex)
    \n-
    444 if(!get(visitedMap, *vertex)) {
    \n-
    445 // In the first pass we only process owner nodes
    \n-
    446 typedef typename GlobalLookup::IndexPair IndexPair;
    \n-
    447 const IndexPair* pair = lookup.pair(*vertex);
    \n-
    448 if(pair==0 || !overlap.contains(pair->local().attribute())) {
    \n-
    449#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    450 assert(examined.find(aggregates[*vertex])==examined.end());
    \n-
    451 examined.insert(aggregates[*vertex]);
    \n-
    452#endif
    \n-
    453 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
    \n-
    454
    \n-
    455 // only needed for ALU
    \n-
    456 // (ghosts with same global id as owners on the same process)
    \n-
    457 if (SolverCategory::category(pinfo) == static_cast<int>(SolverCategory::nonoverlapping)) {
    \n-
    458 if(overlapVertices != overlapEnd) {
    \n-
    459 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
    \n-
    460 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
    \n-
    461 }
    \n-
    462 else{
    \n-
    463 ++overlapVertices;
    \n-
    464 }
    \n-
    465 }
    \n-
    466 }
    \n-
    467 ++row;
    \n-
    468 }
    \n-
    469 }
    \n-
    470
    \n-
    471 dvverb<<"constructed "<<row.index()<<" non-overlapping rows"<<std::endl;
    \n-
    472
    \n-
    473 // Now come the aggregates not owned by use.
    \n-
    474 // They represent the rows n+1, ..., N
    \n-
    475 while(overlapVertices != overlapEnd)
    \n-
    476 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
    \n-
    477
    \n-
    478#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    479 typedef typename GlobalLookup::IndexPair IndexPair;
    \n-
    480 const IndexPair* pair = lookup.pair(overlapVertices->vertex);
    \n-
    481 assert(pair!=0 && overlap.contains(pair->local().attribute()));
    \n-
    482 assert(examined.find(aggregates[overlapVertices->vertex])==examined.end());
    \n-
    483 examined.insert(aggregates[overlapVertices->vertex]);
    \n-
    484#endif
    \n-
    485 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
    \n-
    486 ++row;
    \n-
    487 }else{
    \n-
    488 ++overlapVertices;
    \n-
    489 }
    \n-
    490 }
    \n-
    491
    \n-
    492 template<class G>
    \n-
    493 template<class V, class R>
    \n-\n-
    495 V& visitedMap,
    \n-
    496 [[maybe_unused]] const SequentialInformation& pinfo,
    \n-
    497 const AggregatesMap<Vertex>& aggregates,
    \n-
    498 R& row)
    \n-
    499 {
    \n-
    500 typedef typename G::VertexIterator VertexIterator;
    \n-
    501
    \n-
    502 VertexIterator vend=graph.end();
    \n-
    503 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex) {
    \n-
    504 if(!get(visitedMap, *vertex)) {
    \n-
    505 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
    \n-
    506 ++row;
    \n-
    507 }
    \n-
    508 }
    \n-
    509
    \n-
    510 }
    \n-
    511
    \n-
    512 template<class M>
    \n-\n-
    514 : row_(matrix.createbegin()),
    \n-
    515 minRowSize_(std::numeric_limits<std::size_t>::max()),
    \n-
    516 maxRowSize_(0), sumRowSize_(0)
    \n-
    517 {
    \n-
    518#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    519 diagonalInserted = false;
    \n-
    520#endif
    \n-
    521 }
    \n-
    522 template<class M>
    \n-\n-
    524 {
    \n-
    525 return maxRowSize_;
    \n-
    526 }
    \n-
    527 template<class M>
    \n-\n-
    529 {
    \n-
    530 return minRowSize_;
    \n-
    531 }
    \n-
    532
    \n-
    533 template<class M>
    \n-\n-
    535 {
    \n-
    536 return sumRowSize_;
    \n-
    537 }
    \n-
    538 template<class M>
    \n-\n-
    540 {
    \n-
    541 sumRowSize_ += row_.size();
    \n-
    542 minRowSize_=std::min(minRowSize_, row_.size());
    \n-
    543 maxRowSize_=std::max(maxRowSize_, row_.size());
    \n-
    544 ++row_;
    \n-
    545#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    546 assert(diagonalInserted);
    \n-
    547 diagonalInserted = false;
    \n-
    548#endif
    \n-
    549 }
    \n-
    550
    \n-
    551 template<class M>
    \n-
    552 void SparsityBuilder<M>::insert(const typename M::size_type& index)
    \n-
    553 {
    \n-
    554 row_.insert(index);
    \n-
    555#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    556 diagonalInserted = diagonalInserted || row_.index()==index;
    \n-
    557#endif
    \n-
    558 }
    \n-
    559
    \n-
    560 template<class T>
    \n-
    561 template<class G, class V, class Set>
    \n-
    562 typename G::MutableMatrix*
    \n-
    563 GalerkinProduct<T>::build(G& fineGraph, V& visitedMap,
    \n-
    564 const ParallelInformation& pinfo,
    \n-\n-
    566 const typename G::Matrix::size_type& size,
    \n-
    567 const Set& overlap)
    \n-
    568 {
    \n-\n-
    570
    \n-
    571 std::size_t count;
    \n-
    572
    \n-
    573 const OverlapVertex* overlapVertices = buildOverlapVertices(fineGraph,
    \n-
    574 pinfo,
    \n-
    575 aggregates,
    \n-
    576 overlap,
    \n-
    577 count);
    \n-
    578 typedef typename G::MutableMatrix M;
    \n-
    579 M* coarseMatrix = new M(size, size, M::row_wise);
    \n-
    580
    \n-
    581 // Reset the visited flags of all vertices.
    \n-
    582 // As the isolated nodes will be skipped we simply mark them as visited
    \n-
    583
    \n-
    584 typedef typename G::VertexIterator Vertex;
    \n-
    585 Vertex vend = fineGraph.end();
    \n-
    586 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
    \n-\n-
    588 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
    \n-
    589 }
    \n-
    590
    \n-
    591 typedef typename G::MutableMatrix M;
    \n-
    592 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
    \n-
    593
    \n-
    594 ConnectivityConstructor<G,T>::examine(fineGraph, visitedMap, pinfo,
    \n-
    595 aggregates, overlap,
    \n-
    596 overlapVertices,
    \n-
    597 overlapVertices+count,
    \n-
    598 sparsityBuilder);
    \n-
    599
    \n-
    600 dinfo<<pinfo.communicator().rank()<<": Matrix ("<<coarseMatrix->N()<<"x"<<coarseMatrix->M()<<" row: min="<<sparsityBuilder.minRowSize()<<" max="
    \n-
    601 <<sparsityBuilder.maxRowSize()<<" avg="
    \n-
    602 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()
    \n-
    603 <<std::endl;
    \n-
    604
    \n-
    605 delete[] overlapVertices;
    \n-
    606
    \n-
    607 return coarseMatrix;
    \n-
    608 }
    \n-
    609
    \n-
    610 template<class G, class V, class Set>
    \n-
    611 typename G::MutableMatrix*
    \n-\n-
    613 const SequentialInformation& pinfo,
    \n-\n-
    615 const typename G::Matrix::size_type& size,
    \n-
    616 [[maybe_unused]] const Set& overlap)
    \n-
    617 {
    \n-
    618 typedef typename G::MutableMatrix M;
    \n-
    619 M* coarseMatrix = new M(size, size, M::row_wise);
    \n-
    620
    \n-
    621 // Reset the visited flags of all vertices.
    \n-
    622 // As the isolated nodes will be skipped we simply mark them as visited
    \n-
    623
    \n-
    624 typedef typename G::VertexIterator Vertex;
    \n-
    625 Vertex vend = fineGraph.end();
    \n-
    626 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
    \n-\n-
    628 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
    \n-
    629 }
    \n-
    630
    \n-
    631 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
    \n-
    632
    \n-\n-
    634 aggregates, sparsityBuilder);
    \n-
    635 dinfo<<"Matrix row: min="<<sparsityBuilder.minRowSize()<<" max="
    \n-
    636 <<sparsityBuilder.maxRowSize()<<" average="
    \n-
    637 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()<<std::endl;
    \n-
    638 return coarseMatrix;
    \n-
    639 }
    \n-
    640
    \n-
    641 template<class M, class V, class P, class O>
    \n-
    642 void BaseGalerkinProduct::calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
    \n-
    643 const P& pinfo, [[maybe_unused]] const O& copy)
    \n-
    644 {
    \n-
    645 coarse = static_cast<typename M::field_type>(0);
    \n-
    646
    \n-
    647 typedef typename M::ConstIterator RowIterator;
    \n-
    648 RowIterator endRow = fine.end();
    \n-
    649
    \n-
    650 for(RowIterator row = fine.begin(); row != endRow; ++row)
    \n-
    651 if(aggregates[row.index()] != AggregatesMap<V>::ISOLATED) {
    \n-
    652 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
    \n-
    653 typedef typename M::ConstColIterator ColIterator;
    \n-
    654 ColIterator endCol = row->end();
    \n-
    655
    \n-
    656 for(ColIterator col = row->begin(); col != endCol; ++col)
    \n-
    657 if(aggregates[col.index()] != AggregatesMap<V>::ISOLATED) {
    \n-
    658 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
    \n-
    659 coarse[aggregates[row.index()]][aggregates[col.index()]]+=*col;
    \n-
    660 }
    \n-
    661 }
    \n-
    662
    \n-
    663 // get the right diagonal matrix values on copy lines from owner processes
    \n-
    664 typedef typename M::block_type BlockType;
    \n-
    665 std::vector<BlockType> rowsize(coarse.N(),BlockType(0));
    \n-
    666 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
    \n-
    667 rowsize[row.index()]=coarse[row.index()][row.index()];
    \n-
    668 pinfo.copyOwnerToAll(rowsize,rowsize);
    \n-
    669 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
    \n-
    670 coarse[row.index()][row.index()] = rowsize[row.index()];
    \n-
    671
    \n-
    672 // don't set dirichlet boundaries for copy lines to make novlp case work,
    \n-
    673 // the preconditioner yields slightly different results now.
    \n-
    674
    \n-
    675 // Set the dirichlet border
    \n-
    676 //DirichletBoundarySetter<P>::template set<M>(coarse, pinfo, copy);
    \n-
    677
    \n-
    678 }
    \n-
    679
    \n-
    680 template<class T>
    \n-
    681 template<class M, class O>
    \n-
    682 void DirichletBoundarySetter<T>::set(M& coarse, const T& pinfo, const O& copy)
    \n-
    683 {
    \n-
    684 typedef typename T::ParallelIndexSet::const_iterator ConstIterator;
    \n-
    685 ConstIterator end = pinfo.indexSet().end();
    \n-
    686 typedef typename M::block_type Block;
    \n-
    687 Block identity=Block(0.0);
    \n-
    688 for(typename Block::RowIterator b=identity.begin(); b != identity.end(); ++b)
    \n-
    689 b->operator[](b.index())=1.0;
    \n-
    690
    \n-
    691 for(ConstIterator index = pinfo.indexSet().begin();
    \n-
    692 index != end; ++index) {
    \n-
    693 if(copy.contains(index->local().attribute())) {
    \n-
    694 typedef typename M::ColIterator ColIterator;
    \n-
    695 typedef typename M::row_type Row;
    \n-
    696 Row row = coarse[index->local()];
    \n-
    697 ColIterator cend = row.find(index->local());
    \n-
    698 ColIterator col = row.begin();
    \n-
    699 for(; col != cend; ++col)
    \n-
    700 *col = 0;
    \n-
    701
    \n-
    702 cend = row.end();
    \n-
    703
    \n-
    704 assert(col != cend); // There should be a diagonal entry
    \n-
    705 *col = identity;
    \n-
    706
    \n-
    707 for(++col; col != cend; ++col)
    \n-
    708 *col = 0;
    \n-
    709 }
    \n-
    710 }
    \n-
    711 }
    \n-
    712
    \n-
    713 template<class M, class O>
    \n-\n-
    715 const SequentialInformation& pinfo,
    \n-
    716 const O& overlap)
    \n-
    717 {}
    \n-
    718
    \n-
    719 } // namespace Amg
    \n-
    720} // namespace Dune
    \n-
    721#endif
    \n-
    Provides classes for the Coloring process of AMG.
    \n-\n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    bool operator()(const OverlapVertex< A > &o1, const OverlapVertex< A > &o2)
    Definition: galerkin.hh:155
    \n-
    static void constructNonOverlapConnectivity(R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::VertexDescriptor &seed)
    Construct the connectivity of an aggregate in the overlap.
    Definition: galerkin.hh:313
    \n-
    G Graph
    The type of the graph.
    Definition: galerkin.hh:211
    \n-
    void operator++()
    Definition: galerkin.hh:539
    \n-
    void operator()(const ConstEdgeIterator &edge)
    Process an edge pointing to another aggregate.
    Definition: galerkin.hh:359
    \n-
    void insert(const typename M::size_type &index)
    Definition: galerkin.hh:552
    \n-
    static void constructOverlapConnectivity(R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const OverlapVertex< typename G::VertexDescriptor > *&seed, const OverlapVertex< typename G::VertexDescriptor > *overlapEnd)
    Definition: galerkin.hh:331
    \n-
    G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation &pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::Matrix::size_type &size, const Set &copy)
    Calculates the coarse matrix via a Galerkin product.
    Definition: galerkin.hh:563
    \n-
    std::size_t index()
    Definition: galerkin.hh:81
    \n-
    T ParallelInformation
    Definition: galerkin.hh:120
    \n-
    G::VertexDescriptor Vertex
    Definition: galerkin.hh:272
    \n-
    T Aggregate
    The aggregate descriptor.
    Definition: galerkin.hh:37
    \n-
    SparsityBuilder(M &matrix)
    Constructor.
    Definition: galerkin.hh:513
    \n-
    ConnectedBuilder(const AggregatesMap< Vertex > &aggregates, Graph &graph, VisitedMap &visitedMap, Set &connected)
    Constructor.
    Definition: galerkin.hh:352
    \n-
    Graph::ConstEdgeIterator ConstEdgeIterator
    The constant edge iterator.
    Definition: galerkin.hh:215
    \n-
    T Vertex
    The vertex descriptor.
    Definition: galerkin.hh:42
    \n-
    G::VertexDescriptor Vertex
    Definition: galerkin.hh:288
    \n-
    static void examine(G &graph, V &visitedMap, const T &pinfo, const AggregatesMap< Vertex > &aggregates, const O &overlap, const OverlapVertex< Vertex > *overlapVertices, const OverlapVertex< Vertex > *overlapEnd, R &row)
    Definition: galerkin.hh:420
    \n-
    V VisitedMap
    The type of the map for marking vertices as visited.
    Definition: galerkin.hh:225
    \n-
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n-
    S Set
    The type of the connected set.
    Definition: galerkin.hh:220
    \n-
    Aggregate * aggregate
    The aggregate the vertex belongs to.
    Definition: galerkin.hh:47
    \n-
    std::size_t sumRowSize()
    Definition: galerkin.hh:534
    \n-
    Vertex vertex
    The vertex descriptor.
    Definition: galerkin.hh:52
    \n-
    std::size_t minRowSize()
    Definition: galerkin.hh:528
    \n-
    static void set(M &coarse, const T &pinfo, const O &copy)
    Definition: galerkin.hh:682
    \n-
    Graph::VertexDescriptor Vertex
    The vertex descriptor of the graph.
    Definition: galerkin.hh:230
    \n-
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n-
    std::size_t maxRowSize()
    Definition: galerkin.hh:523
    \n-
    STL namespace.
    \n+
    412} /* namespace Dune */
    \n+
    413
    \n+
    414#endif // HAVE_SUITESPARSE_CHOLMOD
    \n+
    Define general, extensible interface for inverse operators.
    \n+
    Implementation of the BCRSMatrix class.
    \n+\n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+
    DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-
    Definition: galerkin.hh:33
    \n-
    Functor for building the sparsity pattern of the matrix using examineConnectivity.
    Definition: galerkin.hh:63
    \n-
    Definition: galerkin.hh:99
    \n-
    Definition: galerkin.hh:118
    \n-
    Definition: galerkin.hh:185
    \n-
    Visitor for identifying connected aggregates during a breadthFirstSearch.
    Definition: galerkin.hh:206
    \n-
    Definition: galerkin.hh:271
    \n-
    Definition: galerkin.hh:300
    \n-
    Definition: pinfo.hh:28
    \n-
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f, std::size_t rowOffset=0, std::size_t colOffset=0)
    Traverse a blocked matrix and call a functor at each scalar entry.
    Definition: foreach.hh:132
    \n+
    std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)
    Traverse a blocked vector and call a functor at each scalar entry.
    Definition: foreach.hh:95
    \n+
    Category
    Definition: solvercategory.hh:23
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-us-ascii\n+utf-8\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,817 +4,411 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-galerkin.hh\n+cholmod.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n- 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_GALERKIN_HH\n- 6#define DUNE_GALERKIN_HH\n- 7\n- 8#include \"aggregates.hh\"\n- 9#include \"pinfo.hh\"\n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15\n- 16namespace Dune\n- 17{\n- 18 namespace Amg\n- 19 {\n- 31 template\n-32 struct OverlapVertex\n+ 3#pragma once\n+ 4\n+ 5#if HAVE_SUITESPARSE_CHOLMOD\n+ 6\n+ 7#include \n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include\n+ 12#include \n+ 13#include \n+ 14\n+ 15#include \n+ 16#include \n+ 17\n+ 18#include \n+ 19\n+ 20namespace Dune {\n+ 21\n+ 22namespace Impl{\n+ 23\n+ 32 struct NoIgnore\n 33 {\n-37 typedef T Aggregate;\n- 38\n-42 typedef T Vertex;\n- 43\n-47 Aggregate* aggregate;\n- 48\n-52 Vertex vertex;\n- 53 };\n- 54\n- 55\n- 56\n- 61 template\n-62 class SparsityBuilder\n+ 34 const NoIgnore& operator[](std::size_t) const { return *this; }\n+ 35 explicit operator bool() const { return false; }\n+ 36 static constexpr std::size_t size() { return 0; }\n+ 37\n+ 38 };\n+ 39\n+ 40\n+ 41 template\n+ 42 void copyToFlatVector(const BlockedVector& blockedVector, FlatVector&\n+flatVector)\n+ 43 {\n+ 44 // traverse the vector once just to compute the size\n+ 45 std::size_t len = flatVectorForEach(blockedVector, [&](auto&&, auto...){});\n+ 46 flatVector.resize(len);\n+ 47\n+ 48 flatVectorForEach(blockedVector, [&](auto&& entry, auto offset){\n+ 49 flatVector[offset] = entry;\n+ 50 });\n+ 51 }\n+ 52\n+ 53 // special (dummy) case for NoIgnore\n+ 54 template\n+ 55 void copyToFlatVector(const NoIgnore&, FlatVector&)\n+ 56 {\n+ 57 // just do nothing\n+ 58 return;\n+ 59 }\n+ 60\n+ 61 template\n+ 62 void copyToBlockedVector(const FlatVector& flatVector, BlockedVector&\n+blockedVector)\n 63 {\n- 64 public:\n- 70 SparsityBuilder(M& matrix);\n+ 64 flatVectorForEach(blockedVector, [&](auto& entry, auto offset){\n+ 65 entry = flatVector[offset];\n+ 66 });\n+ 67 }\n+ 68\n+ 69\n+ 70} //namespace Impl\n 71\n- 72 void insert(const typename M::size_type& index);\n- 73\n- 74 void operator++();\n- 75\n- 76 std::size_t minRowSize();\n- 77\n- 78 std::size_t maxRowSize();\n- 79\n- 80 std::size_t sumRowSize();\n-81 std::size_t index()\n- 82 {\n- 83 return row_.index();\n- 84 }\n- 85 private:\n- 87 typename M::CreateIterator row_;\n- 89 std::size_t minRowSize_;\n- 91 std::size_t maxRowSize_;\n- 92 std::size_t sumRowSize_;\n- 93#ifdef DUNE_ISTL_WITH_CHECKING\n- 94 bool diagonalInserted;\n- 95#endif\n- 96 };\n- 97\n-98 class BaseGalerkinProduct\n- 99 {\n- 100 public:\n- 109 template\n-110 void calculate(const M& fine, const AggregatesMap& aggregates, M&\n-coarse,\n- 111 const I& pinfo, const O& copy);\n- 112\n- 113 };\n+ 76template\n+ 77class Cholmod : public InverseOperator\n+ 78{\n+ 79public:\n+ 80\n+ 86 Cholmod()\n+ 87 {\n+ 88 cholmod_start(&c_);\n+ 89 }\n+ 90\n+ 96 ~Cholmod()\n+ 97 {\n+ 98 if (L_)\n+ 99 cholmod_free_factor(&L_, &c_);\n+ 100 cholmod_finish(&c_);\n+ 101 }\n+ 102\n+ 103 // forbid copying to avoid freeing memory twice\n+ 104 Cholmod(const Cholmod&) = delete;\n+ 105 Cholmod& operator=(const Cholmod&) = delete;\n+ 106\n+ 107\n+ 110 void apply (Vector& x, Vector& b, [[maybe_unused]] double reduction,\n+InverseOperatorResult& res)\n+ 111 {\n+ 112 apply(x,b,res);\n+ 113 }\n 114\n- 115 template\n-116 class GalerkinProduct\n- 117 : public BaseGalerkinProduct\n- 118 {\n- 119 public:\n-120 typedef T ParallelInformation;\n- 121\n- 131 template\n- 132 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,\n- 133 const ParallelInformation& pinfo,\n- 134 AggregatesMap& aggregates,\n- 135 const typename G::Matrix::size_type& size,\n- 136 const Set& copy);\n- 137 private:\n- 138\n- 145 template\n- 146 const OverlapVertex*\n- 147 buildOverlapVertices(const G& graph, const I& pinfo,\n- 148 AggregatesMap& aggregates,\n- 149 const Set& overlap,\n- 150 std::size_t& overlapCount);\n+ 120 void apply(Vector& x, Vector& b, InverseOperatorResult& res)\n+ 121 {\n+ 122 // do nothing if N=0\n+ 123 if ( nIsZero_ )\n+ 124 {\n+ 125 return;\n+ 126 }\n+ 127\n+ 128 if (x.size() != b.size())\n+ 129 DUNE_THROW(Exception, \"Error in apply(): sizes of x and b do not match!\");\n+ 130\n+ 131 // cast to double array\n+ 132 auto b2 = std::make_unique(L_->n);\n+ 133 auto x2 = std::make_unique(L_->n);\n+ 134\n+ 135 // copy to cholmod\n+ 136 auto bp = b2.get();\n+ 137\n+ 138 flatVectorForEach(b, [&](auto&& entry, auto&& flatIndex){\n+ 139 if ( subIndices_.empty() )\n+ 140 bp[ flatIndex ] = entry;\n+ 141 else\n+ 142 if( subIndices_[ flatIndex ] != std::numeric_limits::max() )\n+ 143 bp[ subIndices_[ flatIndex ] ] = entry;\n+ 144 });\n+ 145\n+ 146 // create a cholmod dense object\n+ 147 auto b3 = make_cholmod_dense(cholmod_allocate_dense(L_->n, 1, L_->n,\n+CHOLMOD_REAL, &c_), &c_);\n+ 148 // cast because void-ptr\n+ 149 auto b4 = static_cast(b3->x);\n+ 150 std::copy(b2.get(), b2.get() + L_->n, b4);\n 151\n- 152 template\n- 153 struct OVLess\n- 154 {\n-155 bool operator()(const OverlapVertex& o1, const OverlapVertex& o2)\n- 156 {\n- 157 return *o1.aggregate < *o2.aggregate;\n- 158 }\n- 159 };\n- 160 };\n- 161\n- 162 template<>\n-163 class GalerkinProduct\n- 164 : public BaseGalerkinProduct\n- 165 {\n- 166 public:\n- 176 template\n- 177 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,\n- 178 const SequentialInformation& pinfo,\n- 179 const AggregatesMap& aggregates,\n- 180 const typename G::Matrix::size_type& size,\n- 181 const Set& copy);\n- 182 };\n+ 152 // solve for a cholmod x object\n+ 153 auto x3 = make_cholmod_dense(cholmod_solve(CHOLMOD_A, L_, b3.get(), &c_),\n+&c_);\n+ 154 // cast because void-ptr\n+ 155 auto xp = static_cast(x3->x);\n+ 156\n+ 157 // copy into x\n+ 158 flatVectorForEach(x, [&](auto&& entry, auto&& flatIndex){\n+ 159 if ( subIndices_.empty() )\n+ 160 entry = xp[ flatIndex ];\n+ 161 else\n+ 162 if( subIndices_[ flatIndex ] != std::numeric_limits::max() )\n+ 163 entry = xp[ subIndices_[ flatIndex ] ];\n+ 164 });\n+ 165\n+ 166 // statistics for a direct solver\n+ 167 res.iterations = 1;\n+ 168 res.converged = true;\n+ 169 }\n+ 170\n+ 171\n+ 177 template\n+ 178 void setMatrix(const Matrix& matrix)\n+ 179 {\n+ 180 const Impl::NoIgnore* noIgnore = nullptr;\n+ 181 setMatrix(matrix, noIgnore);\n+ 182 }\n 183\n-184 struct BaseConnectivityConstructor\n- 185 {\n- 186 template\n- 187 static void constructOverlapConnectivity(R& row, G& graph, V& visitedMap,\n- 188 const AggregatesMap& aggregates,\n- 189 const OverlapVertex*& seed,\n- 190 const OverlapVertex* overlapEnd);\n- 191\n- 195 template\n- 196 static void constructNonOverlapConnectivity(R& row, G& graph, V&\n-visitedMap,\n- 197 const AggregatesMap& aggregates,\n- 198 const typename G::VertexDescriptor& seed);\n- 199\n- 200\n- 204 template\n-205 class ConnectedBuilder\n- 206 {\n- 207 public:\n-211 typedef G Graph;\n-215 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;\n- 216\n-220 typedef S Set;\n+ 198 template\n+ 199 void setMatrix(const Matrix& matrix, const Ignore* ignore)\n+ 200 {\n+ 201 // count the number of entries and diagonal entries\n+ 202 int nonZeros = 0;\n+ 203 int numberOfIgnoredDofs = 0;\n+ 204\n+ 205\n+ 206 auto [flatRows,flatCols] = flatMatrixForEach( matrix, [&](auto&& /\n+*entry*/, auto&& flatRowIndex, auto&& flatColIndex){\n+ 207 if( flatRowIndex <= flatColIndex )\n+ 208 nonZeros++;\n+ 209 });\n+ 210\n+ 211 std::vector flatIgnore;\n+ 212\n+ 213 if ( ignore )\n+ 214 {\n+ 215 Impl::copyToFlatVector(*ignore,flatIgnore);\n+ 216 numberOfIgnoredDofs = std::count(flatIgnore.begin(),flatIgnore.end\n+(),true);\n+ 217 }\n+ 218\n+ 219 // Total number of rows\n+ 220 int N = flatRows - numberOfIgnoredDofs;\n 221\n-225 typedef V VisitedMap;\n- 226\n-230 typedef typename Graph::VertexDescriptor Vertex;\n- 231\n- 239 ConnectedBuilder(const AggregatesMap& aggregates, Graph& graph,\n- 240 VisitedMap& visitedMap, Set& connected);\n- 241\n- 246 void operator()(const ConstEdgeIterator& edge);\n+ 222 nIsZero_ = (N <= 0);\n+ 223\n+ 224 if ( nIsZero_ )\n+ 225 {\n+ 226 return;\n+ 227 }\n+ 228\n+ 229 /*\n+ 230 * CHOLMOD uses compressed-column sparse matrices, but for symmetric\n+ 231 * matrices this is the same as the compressed-row sparse matrix used\n+ 232 * by DUNE. So we can just store M\u1d40 instead of M (as M = M\u1d40).\n+ 233 */\n+ 234 const auto deleter = [c = &this->c_](auto* p) {\n+ 235 cholmod_free_sparse(&p, c);\n+ 236 };\n+ 237 auto M = std::unique_ptr(\n+ 238 cholmod_allocate_sparse(N, // # rows\n+ 239 N, // # cols\n+ 240 nonZeros, // # of nonzeroes\n+ 241 1, // indices are sorted ( 1 = true)\n+ 242 1, // matrix is \"packed\" ( 1 = true)\n+ 243 -1, // stype of matrix ( -1 = consider the lower part only )\n+ 244 CHOLMOD_REAL, // xtype of matrix ( CHOLMOD_REAL = single array, no complex\n+numbers)\n+ 245 &c_ // cholmod_common ptr\n+ 246 ), deleter);\n 247\n- 248 private:\n- 252 const AggregatesMap& aggregates_;\n+ 248 // copy the data of BCRS matrix to Cholmod Sparse matrix\n+ 249 int* Ap = static_cast(M->p);\n+ 250 int* Ai = static_cast(M->i);\n+ 251 double* Ax = static_cast(M->x);\n+ 252\n 253\n- 254 Graph& graph_;\n- 255\n- 259 VisitedMap& visitedMap_;\n+ 254 if ( ignore )\n+ 255 {\n+ 256 // init the mapping\n+ 257 subIndices_.resize(flatRows,std::numeric_limits::max());\n+ 258\n+ 259 std::size_t subIndexCounter = 0;\n 260\n- 264 Set& connected_;\n- 265 };\n- 266\n- 267 };\n- 268\n- 269 template\n-270 struct ConnectivityConstructor : public BaseConnectivityConstructor\n- 271 {\n-272 typedef typename G::VertexDescriptor Vertex;\n+ 261 for ( std::size_t i=0; i\n- 275 static void examine(G& graph,\n- 276 V& visitedMap,\n- 277 const T& pinfo,\n- 278 const AggregatesMap& aggregates,\n- 279 const O& overlap,\n- 280 const OverlapVertex* overlapVertices,\n- 281 const OverlapVertex* overlapEnd,\n- 282 R& row);\n- 283 };\n- 284\n- 285 template\n-286 struct ConnectivityConstructor : public\n-BaseConnectivityConstructor\n- 287 {\n-288 typedef typename G::VertexDescriptor Vertex;\n- 289\n- 290 template\n- 291 static void examine(G& graph,\n- 292 V& visitedMap,\n- 293 const SequentialInformation& pinfo,\n- 294 const AggregatesMap& aggregates,\n- 295 R& row);\n- 296 };\n+ 274 // stop if ignored\n+ 275 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )\n+ 276 return;\n+ 277\n+ 278 // stop if in lower half\n+ 279 if ( flatRowIndex > flatColIndex )\n+ 280 return;\n+ 281\n+ 282 // ok, count the entry\n+ 283 auto idx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;\n+ 284 Ap[idx+1]++;\n+ 285\n+ 286 });\n+ 287\n+ 288 // now accumulate\n+ 289 Ap[0] = 0;\n+ 290 for ( int i=0; i rowPosition(N,0);\n 297\n- 298 template\n-299 struct DirichletBoundarySetter\n- 300 {\n- 301 template\n- 302 static void set(M& coarse, const T& pinfo, const O& copy);\n- 303 };\n+ 298 // now we can set the entries\n+ 299 flatMatrixForEach(matrix, [&](auto&& entry, auto&& flatRowIndex, auto&&\n+flatColIndex){\n+ 300\n+ 301 // stop if ignored\n+ 302 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )\n+ 303 return;\n 304\n- 305 template<>\n-306 struct DirichletBoundarySetter\n- 307 {\n- 308 template\n- 309 static void set(M& coarse, const SequentialInformation& pinfo, const O&\n-copy);\n- 310 };\n- 311\n- 312 template\n-313 void BaseConnectivityConstructor::constructNonOverlapConnectivity(R& row,\n-G& graph, V& visitedMap,\n- 314 const AggregatesMap& aggregates,\n- 315 const typename G::VertexDescriptor& seed)\n- 316 {\n- 317 assert(row.index()==aggregates[seed]);\n- 318 row.insert(aggregates[seed]);\n- 319 ConnectedBuilder conBuilder(aggregates, graph, visitedMap, row);\n- 320 typedef typename G::VertexDescriptor Vertex;\n- 321 typedef std::allocator Allocator;\n- 322 typedef SLList VertexList;\n- 323 typedef typename AggregatesMap::DummyEdgeVisitor DummyVisitor;\n- 324 VertexList vlist;\n- 325 DummyVisitor dummy;\n- 326 aggregates.template breadthFirstSearch(seed,aggregates[seed],\n-graph, vlist, dummy,\n- 327 conBuilder, visitedMap);\n- 328 }\n- 329\n- 330 template\n-331 void BaseConnectivityConstructor::constructOverlapConnectivity(R& row, G&\n-graph, V& visitedMap,\n- 332 const AggregatesMap& aggregates,\n- 333 const OverlapVertex*& seed,\n- 334 const OverlapVertex* overlapEnd)\n- 335 {\n- 336 ConnectedBuilder conBuilder(aggregates, graph, visitedMap, row);\n- 337 const typename G::VertexDescriptor aggregate=*seed->aggregate;\n- 338\n- 339 if (row.index()==*seed->aggregate) {\n- 340 while(seed != overlapEnd && aggregate == *seed->aggregate) {\n- 341 row.insert(*seed->aggregate);\n- 342 // Walk over all neighbours and add them to the connected array.\n- 343 visitNeighbours(graph, seed->vertex, conBuilder);\n- 344 // Mark vertex as visited\n- 345 put(visitedMap, seed->vertex, true);\n- 346 ++seed;\n- 347 }\n- 348 }\n- 349 }\n- 350\n- 351 template\n-352 BaseConnectivityConstructor::ConnectedBuilder::ConnectedBuilder\n-(const AggregatesMap& aggregates,\n- 353 Graph& graph, VisitedMap& visitedMap,\n- 354 Set& connected)\n- 355 : aggregates_(aggregates), graph_(graph), visitedMap_(visitedMap),\n-connected_(connected)\n- 356 {}\n- 357\n- 358 template\n-359 void BaseConnectivityConstructor::ConnectedBuilder::operator()(const\n-ConstEdgeIterator& edge)\n- 360 {\n- 361 const Vertex& vertex = aggregates_[edge.target()];\n- 362 assert(vertex!= AggregatesMap::UNAGGREGATED);\n- 363 if(vertex!= AggregatesMap::ISOLATED)\n- 364 connected_.insert(vertex);\n- 365 }\n- 366\n- 367 template\n- 368 template\n- 369 const OverlapVertex*\n- 370 GalerkinProduct::buildOverlapVertices(const G& graph, const I& pinfo,\n- 371 AggregatesMap& aggregates,\n- 372 const Set& overlap,\n- 373 std::size_t& overlapCount)\n- 374 {\n- 375 // count the overlap vertices.\n- 376 typedef typename G::ConstVertexIterator ConstIterator;\n- 377 typedef typename I::GlobalLookupIndexSet GlobalLookup;\n- 378 typedef typename GlobalLookup::IndexPair IndexPair;\n- 379\n- 380 const ConstIterator end = graph.end();\n- 381 overlapCount = 0;\n+ 305 // stop if in lower half\n+ 306 if ( flatRowIndex > flatColIndex )\n+ 307 return;\n+ 308\n+ 309 // ok, set the entry\n+ 310 auto rowIdx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;\n+ 311 auto colIdx = ignore ? subIndices_[flatColIndex] : flatColIndex;\n+ 312 auto rowStart = Ap[rowIdx];\n+ 313 auto rowPos = rowPosition[rowIdx];\n+ 314 Ai[ rowStart + rowPos ] = colIdx;\n+ 315 Ax[ rowStart + rowPos ] = entry;\n+ 316 rowPosition[rowIdx]++;\n+ 317\n+ 318 });\n+ 319\n+ 320 // Now analyse the pattern and optimal row order\n+ 321 L_ = cholmod_analyze(M.get(), &c_);\n+ 322\n+ 323 // Do the factorization (this may take some time)\n+ 324 cholmod_factorize(M.get(), L_, &c_);\n+ 325 }\n+ 326\n+ 327 virtual SolverCategory::Category category() const\n+ 328 {\n+ 329 return SolverCategory::Category::sequential;\n+ 330 }\n+ 331\n+ 337 cholmod_common& cholmodCommonObject()\n+ 338 {\n+ 339 return c_;\n+ 340 }\n+ 341\n+ 347 cholmod_factor& cholmodFactor()\n+ 348 {\n+ 349 return *L_;\n+ 350 }\n+ 351\n+ 357 const cholmod_factor& cholmodFactor() const\n+ 358 {\n+ 359 return *L_;\n+ 360 }\n+ 361private:\n+ 362\n+ 363 // create a std::unique_ptr to a cholmod_dense object with a deleter\n+ 364 // that calls the appropriate cholmod cleanup routine\n+ 365 auto make_cholmod_dense(cholmod_dense* x, cholmod_common* c)\n+ 366 {\n+ 367 const auto deleter = [c](auto* p) {\n+ 368 cholmod_free_dense(&p, c);\n+ 369 };\n+ 370 return std::unique_ptr(x, deleter);\n+ 371 }\n+ 372\n+ 373 cholmod_common c_;\n+ 374 cholmod_factor* L_ = nullptr;\n+ 375\n+ 376 // indicator for a 0x0 problem (due to ignore dof's)\n+ 377 bool nIsZero_ = false;\n+ 378\n+ 379 // vector mapping all indices in flat order to the not ignored indices\n+ 380 std::vector subIndices_;\n+ 381};\n 382\n- 383 const GlobalLookup& lookup=pinfo.globalLookup();\n- 384\n- 385 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {\n- 386 const IndexPair* pair = lookup.pair(*vertex);\n+ 383 struct CholmodCreator{\n+ 384 template struct isValidBlock : std::false_type{};\n+ 385 template struct isValidBlock> : std::\n+true_type{};\n+ 386 template struct isValidBlock> : std::true_type\n+{};\n 387\n- 388 if(pair!=0 && overlap.contains(pair->local().attribute()))\n- 389 ++overlapCount;\n- 390 }\n- 391 // Allocate space\n- 392 typedef typename G::VertexDescriptor Vertex;\n- 393\n- 394 OverlapVertex* overlapVertices = new OverlapVertex\n-[overlapCount=0 ? 1 : overlapCount];\n- 395 if(overlapCount==0)\n- 396 return overlapVertices;\n- 397\n- 398 // Initialize them\n- 399 overlapCount=0;\n- 400 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {\n- 401 const IndexPair* pair = lookup.pair(*vertex);\n- 402\n- 403 if(pair!=0 && overlap.contains(pair->local().attribute())) {\n- 404 overlapVertices[overlapCount].aggregate = &aggregates[pair->local()];\n- 405 overlapVertices[overlapCount].vertex = pair->local();\n- 406 ++overlapCount;\n- 407 }\n+ 388 template\n+ 389 std::shared_ptr::type,\n+ 390 typename Dune::TypeListElement<2, TL>::type>>\n+ 391 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& /*config*/,\n+ 392 std::enable_if_t::\n+type::block_type>::value,int> = 0) const\n+ 393 {\n+ 394 using D = typename Dune::TypeListElement<1, TL>::type;\n+ 395 auto solver = std::make_shared>();\n+ 396 solver->setMatrix(mat);\n+ 397 return solver;\n+ 398 }\n+ 399\n+ 400 // second version with SFINAE to validate the template parameters of\n+Cholmod\n+ 401 template\n+ 402 std::shared_ptr::type,\n+ 403 typename Dune::TypeListElement<2, TL>::type>>\n+ 404 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n+*config*/,\n+ 405 std::enable_if_t::\n+type::block_type>::value,int> = 0) const\n+ 406 {\n+ 407 DUNE_THROW(UnsupportedType, \"Unsupported Type in Cholmod\");\n 408 }\n- 409\n- 410 dverb << overlapCount<<\" overlap vertices\"<\n-());\n- 413 // due to the sorting the isolated aggregates (to be skipped) are at the\n-end.\n- 414\n- 415 return overlapVertices;\n- 416 }\n- 417\n- 418 template\n- 419 template\n-420 void ConnectivityConstructor::examine(G& graph,\n- 421 V& visitedMap,\n- 422 const T& pinfo,\n- 423 const AggregatesMap& aggregates,\n- 424 const O& overlap,\n- 425 const OverlapVertex* overlapVertices,\n- 426 const OverlapVertex* overlapEnd,\n- 427 R& row)\n- 428 {\n- 429 typedef typename T::GlobalLookupIndexSet GlobalLookup;\n- 430 const GlobalLookup& lookup = pinfo.globalLookup();\n- 431\n- 432 typedef typename G::VertexIterator VertexIterator;\n- 433\n- 434 VertexIterator vend=graph.end();\n- 435\n- 436#ifdef DUNE_ISTL_WITH_CHECKING\n- 437 std::set examined;\n- 438#endif\n- 439\n- 440 // The aggregates owned by the process have lower local indices\n- 441 // then those not owned. We process them in the first pass.\n- 442 // They represent the rows 0, 1, ..., n of the coarse matrix\n- 443 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex)\n- 444 if(!get(visitedMap, *vertex)) {\n- 445 // In the first pass we only process owner nodes\n- 446 typedef typename GlobalLookup::IndexPair IndexPair;\n- 447 const IndexPair* pair = lookup.pair(*vertex);\n- 448 if(pair==0 || !overlap.contains(pair->local().attribute())) {\n- 449#ifdef DUNE_ISTL_WITH_CHECKING\n- 450 assert(examined.find(aggregates[*vertex])==examined.end());\n- 451 examined.insert(aggregates[*vertex]);\n- 452#endif\n- 453 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates,\n-*vertex);\n- 454\n- 455 // only needed for ALU\n- 456 // (ghosts with same global id as owners on the same process)\n- 457 if (SolverCategory::category(pinfo) == static_cast(SolverCategory::\n-nonoverlapping)) {\n- 458 if(overlapVertices != overlapEnd) {\n- 459 if(*overlapVertices->aggregate!=AggregatesMap::ISOLATED) {\n- 460 constructOverlapConnectivity(row, graph, visitedMap, aggregates,\n-overlapVertices, overlapEnd);\n- 461 }\n- 462 else{\n- 463 ++overlapVertices;\n- 464 }\n- 465 }\n- 466 }\n- 467 ++row;\n- 468 }\n- 469 }\n- 470\n- 471 dvverb<<\"constructed \"<aggregate!=AggregatesMap::ISOLATED) {\n- 477\n- 478#ifdef DUNE_ISTL_WITH_CHECKING\n- 479 typedef typename GlobalLookup::IndexPair IndexPair;\n- 480 const IndexPair* pair = lookup.pair(overlapVertices->vertex);\n- 481 assert(pair!=0 && overlap.contains(pair->local().attribute()));\n- 482 assert(examined.find(aggregates[overlapVertices->vertex])==examined.end\n-());\n- 483 examined.insert(aggregates[overlapVertices->vertex]);\n- 484#endif\n- 485 constructOverlapConnectivity(row, graph, visitedMap, aggregates,\n-overlapVertices, overlapEnd);\n- 486 ++row;\n- 487 }else{\n- 488 ++overlapVertices;\n- 489 }\n- 490 }\n- 491\n- 492 template\n- 493 template\n-494 void ConnectivityConstructor::examine(G& graph,\n- 495 V& visitedMap,\n- 496 [[maybe_unused]] const SequentialInformation& pinfo,\n- 497 const AggregatesMap& aggregates,\n- 498 R& row)\n- 499 {\n- 500 typedef typename G::VertexIterator VertexIterator;\n- 501\n- 502 VertexIterator vend=graph.end();\n- 503 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex) {\n- 504 if(!get(visitedMap, *vertex)) {\n- 505 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates,\n-*vertex);\n- 506 ++row;\n- 507 }\n- 508 }\n- 509\n- 510 }\n- 511\n- 512 template\n-513 SparsityBuilder::SparsityBuilder(M& matrix)\n- 514 : row_(matrix.createbegin()),\n- 515 minRowSize_(std::numeric_limits::max()),\n- 516 maxRowSize_(0), sumRowSize_(0)\n- 517 {\n- 518#ifdef DUNE_ISTL_WITH_CHECKING\n- 519 diagonalInserted = false;\n- 520#endif\n- 521 }\n- 522 template\n-523 std::size_t SparsityBuilder::maxRowSize()\n- 524 {\n- 525 return maxRowSize_;\n- 526 }\n- 527 template\n-528 std::size_t SparsityBuilder::minRowSize()\n- 529 {\n- 530 return minRowSize_;\n- 531 }\n- 532\n- 533 template\n-534 std::size_t SparsityBuilder::sumRowSize()\n- 535 {\n- 536 return sumRowSize_;\n- 537 }\n- 538 template\n-539 void SparsityBuilder::operator++()\n- 540 {\n- 541 sumRowSize_ += row_.size();\n- 542 minRowSize_=std::min(minRowSize_, row_.size());\n- 543 maxRowSize_=std::max(maxRowSize_, row_.size());\n- 544 ++row_;\n- 545#ifdef DUNE_ISTL_WITH_CHECKING\n- 546 assert(diagonalInserted);\n- 547 diagonalInserted = false;\n- 548#endif\n- 549 }\n- 550\n- 551 template\n-552 void SparsityBuilder::insert(const typename M::size_type& index)\n- 553 {\n- 554 row_.insert(index);\n- 555#ifdef DUNE_ISTL_WITH_CHECKING\n- 556 diagonalInserted = diagonalInserted || row_.index()==index;\n- 557#endif\n- 558 }\n- 559\n- 560 template\n- 561 template\n- 562 typename G::MutableMatrix*\n-563 GalerkinProduct::build(G& fineGraph, V& visitedMap,\n- 564 const ParallelInformation& pinfo,\n- 565 AggregatesMap& aggregates,\n- 566 const typename G::Matrix::size_type& size,\n- 567 const Set& overlap)\n- 568 {\n- 569 typedef OverlapVertex OverlapVertex;\n- 570\n- 571 std::size_t count;\n- 572\n- 573 const OverlapVertex* overlapVertices = buildOverlapVertices(fineGraph,\n- 574 pinfo,\n- 575 aggregates,\n- 576 overlap,\n- 577 count);\n- 578 typedef typename G::MutableMatrix M;\n- 579 M* coarseMatrix = new M(size, size, M::row_wise);\n- 580\n- 581 // Reset the visited flags of all vertices.\n- 582 // As the isolated nodes will be skipped we simply mark them as visited\n- 583\n- 584 typedef typename G::VertexIterator Vertex;\n- 585 Vertex vend = fineGraph.end();\n- 586 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {\n- 587 assert(aggregates[*vertex] != AggregatesMap::UNAGGREGATED);\n- 588 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap::ISOLATED);\n- 589 }\n- 590\n- 591 typedef typename G::MutableMatrix M;\n- 592 SparsityBuilder sparsityBuilder(*coarseMatrix);\n- 593\n- 594 ConnectivityConstructor::examine(fineGraph, visitedMap, pinfo,\n- 595 aggregates, overlap,\n- 596 overlapVertices,\n- 597 overlapVertices+count,\n- 598 sparsityBuilder);\n- 599\n- 600 dinfo<N\n-()<<\"x\"<M()<<\" row: min=\"<(sparsityBuilder.sumRowSize())/coarseMatrix->N()\n- 603 <\n- 611 typename G::MutableMatrix*\n-612 GalerkinProduct::build(G& fineGraph, V& visitedMap,\n- 613 const SequentialInformation& pinfo,\n- 614 const AggregatesMap& aggregates,\n- 615 const typename G::Matrix::size_type& size,\n- 616 [[maybe_unused]] const Set& overlap)\n- 617 {\n- 618 typedef typename G::MutableMatrix M;\n- 619 M* coarseMatrix = new M(size, size, M::row_wise);\n- 620\n- 621 // Reset the visited flags of all vertices.\n- 622 // As the isolated nodes will be skipped we simply mark them as visited\n- 623\n- 624 typedef typename G::VertexIterator Vertex;\n- 625 Vertex vend = fineGraph.end();\n- 626 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {\n- 627 assert(aggregates[*vertex] != AggregatesMap::UNAGGREGATED);\n- 628 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap::ISOLATED);\n- 629 }\n- 630\n- 631 SparsityBuilder sparsityBuilder(*coarseMatrix);\n- 632\n- 633 ConnectivityConstructor::examine(fineGraph,\n-visitedMap, pinfo,\n- 634 aggregates, sparsityBuilder);\n- 635 dinfo<<\"Matrix row: min=\"<(sparsityBuilder.sumRowSize())/coarseMatrix->N\n-()<\n-642 void BaseGalerkinProduct::calculate(const M& fine, const AggregatesMap&\n-aggregates, M& coarse,\n- 643 const P& pinfo, [[maybe_unused]] const O& copy)\n- 644 {\n- 645 coarse = static_cast(0);\n- 646\n- 647 typedef typename M::ConstIterator RowIterator;\n- 648 RowIterator endRow = fine.end();\n- 649\n- 650 for(RowIterator row = fine.begin(); row != endRow; ++row)\n- 651 if(aggregates[row.index()] != AggregatesMap::ISOLATED) {\n- 652 assert(aggregates[row.index()]!=AggregatesMap::UNAGGREGATED);\n- 653 typedef typename M::ConstColIterator ColIterator;\n- 654 ColIterator endCol = row->end();\n- 655\n- 656 for(ColIterator col = row->begin(); col != endCol; ++col)\n- 657 if(aggregates[col.index()] != AggregatesMap::ISOLATED) {\n- 658 assert(aggregates[row.index()]!=AggregatesMap::UNAGGREGATED);\n- 659 coarse[aggregates[row.index()]][aggregates[col.index()]]+=*col;\n- 660 }\n- 661 }\n- 662\n- 663 // get the right diagonal matrix values on copy lines from owner processes\n- 664 typedef typename M::block_type BlockType;\n- 665 std::vector rowsize(coarse.N(),BlockType(0));\n- 666 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)\n- 667 rowsize[row.index()]=coarse[row.index()][row.index()];\n- 668 pinfo.copyOwnerToAll(rowsize,rowsize);\n- 669 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)\n- 670 coarse[row.index()][row.index()] = rowsize[row.index()];\n- 671\n- 672 // don't set dirichlet boundaries for copy lines to make novlp case work,\n- 673 // the preconditioner yields slightly different results now.\n- 674\n- 675 // Set the dirichlet border\n- 676 //DirichletBoundarySetter

    ::template set(coarse, pinfo, copy);\n- 677\n- 678 }\n- 679\n- 680 template\n- 681 template\n-682 void DirichletBoundarySetter::set(M& coarse, const T& pinfo, const O&\n-copy)\n- 683 {\n- 684 typedef typename T::ParallelIndexSet::const_iterator ConstIterator;\n- 685 ConstIterator end = pinfo.indexSet().end();\n- 686 typedef typename M::block_type Block;\n- 687 Block identity=Block(0.0);\n- 688 for(typename Block::RowIterator b=identity.begin(); b != identity.end();\n-++b)\n- 689 b->operator[](b.index())=1.0;\n- 690\n- 691 for(ConstIterator index = pinfo.indexSet().begin();\n- 692 index != end; ++index) {\n- 693 if(copy.contains(index->local().attribute())) {\n- 694 typedef typename M::ColIterator ColIterator;\n- 695 typedef typename M::row_type Row;\n- 696 Row row = coarse[index->local()];\n- 697 ColIterator cend = row.find(index->local());\n- 698 ColIterator col = row.begin();\n- 699 for(; col != cend; ++col)\n- 700 *col = 0;\n- 701\n- 702 cend = row.end();\n- 703\n- 704 assert(col != cend); // There should be a diagonal entry\n- 705 *col = identity;\n- 706\n- 707 for(++col; col != cend; ++col)\n- 708 *col = 0;\n- 709 }\n- 710 }\n- 711 }\n- 712\n- 713 template\n-714 void DirichletBoundarySetter::set(M& coarse,\n- 715 const SequentialInformation& pinfo,\n- 716 const O& overlap)\n- 717 {}\n- 718\n- 719 } // namespace Amg\n- 720} // namespace Dune\n- 721#endif\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n-pinfo.hh\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n-Dune::Amg::GalerkinProduct::OVLess::operator()\n-bool operator()(const OverlapVertex< A > &o1, const OverlapVertex< A > &o2)\n-Definition: galerkin.hh:155\n-Dune::Amg::BaseConnectivityConstructor::constructNonOverlapConnectivity\n-static void constructNonOverlapConnectivity(R &row, G &graph, V &visitedMap,\n-const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename\n-G::VertexDescriptor &seed)\n-Construct the connectivity of an aggregate in the overlap.\n-Definition: galerkin.hh:313\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Graph\n-G Graph\n-The type of the graph.\n-Definition: galerkin.hh:211\n-Dune::Amg::SparsityBuilder::operator++\n-void operator++()\n-Definition: galerkin.hh:539\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::operator()\n-void operator()(const ConstEdgeIterator &edge)\n-Process an edge pointing to another aggregate.\n-Definition: galerkin.hh:359\n-Dune::Amg::SparsityBuilder::insert\n-void insert(const typename M::size_type &index)\n-Definition: galerkin.hh:552\n-Dune::Amg::BaseConnectivityConstructor::constructOverlapConnectivity\n-static void constructOverlapConnectivity(R &row, G &graph, V &visitedMap, const\n-AggregatesMap< typename G::VertexDescriptor > &aggregates, const OverlapVertex<\n-typename G::VertexDescriptor > *&seed, const OverlapVertex< typename G::\n-VertexDescriptor > *overlapEnd)\n-Definition: galerkin.hh:331\n-Dune::Amg::GalerkinProduct::build\n-G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation\n-&pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const\n-typename G::Matrix::size_type &size, const Set ©)\n-Calculates the coarse matrix via a Galerkin product.\n-Definition: galerkin.hh:563\n-Dune::Amg::SparsityBuilder::index\n-std::size_t index()\n-Definition: galerkin.hh:81\n-Dune::Amg::GalerkinProduct::ParallelInformation\n-T ParallelInformation\n-Definition: galerkin.hh:120\n-Dune::Amg::ConnectivityConstructor::Vertex\n-G::VertexDescriptor Vertex\n-Definition: galerkin.hh:272\n-Dune::Amg::OverlapVertex::Aggregate\n-T Aggregate\n-The aggregate descriptor.\n-Definition: galerkin.hh:37\n-Dune::Amg::SparsityBuilder::SparsityBuilder\n-SparsityBuilder(M &matrix)\n-Constructor.\n-Definition: galerkin.hh:513\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::ConnectedBuilder\n-ConnectedBuilder(const AggregatesMap< Vertex > &aggregates, Graph &graph,\n-VisitedMap &visitedMap, Set &connected)\n-Constructor.\n-Definition: galerkin.hh:352\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::ConstEdgeIterator\n-Graph::ConstEdgeIterator ConstEdgeIterator\n-The constant edge iterator.\n-Definition: galerkin.hh:215\n-Dune::Amg::OverlapVertex::Vertex\n-T Vertex\n-The vertex descriptor.\n-Definition: galerkin.hh:42\n-Dune::Amg::ConnectivityConstructor<_G,_SequentialInformation_>::Vertex\n-G::VertexDescriptor Vertex\n-Definition: galerkin.hh:288\n-Dune::Amg::ConnectivityConstructor::examine\n-static void examine(G &graph, V &visitedMap, const T &pinfo, const\n-AggregatesMap< Vertex > &aggregates, const O &overlap, const OverlapVertex<\n-Vertex > *overlapVertices, const OverlapVertex< Vertex > *overlapEnd, R &row)\n-Definition: galerkin.hh:420\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::VisitedMap\n-V VisitedMap\n-The type of the map for marking vertices as visited.\n-Definition: galerkin.hh:225\n-Dune::Amg::visitNeighbours\n-int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n-V &visitor)\n-Visit all neighbour vertices of a vertex in a graph.\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Set\n-S Set\n-The type of the connected set.\n-Definition: galerkin.hh:220\n-Dune::Amg::OverlapVertex::aggregate\n-Aggregate * aggregate\n-The aggregate the vertex belongs to.\n-Definition: galerkin.hh:47\n-Dune::Amg::SparsityBuilder::sumRowSize\n-std::size_t sumRowSize()\n-Definition: galerkin.hh:534\n-Dune::Amg::OverlapVertex::vertex\n-Vertex vertex\n-The vertex descriptor.\n-Definition: galerkin.hh:52\n-Dune::Amg::SparsityBuilder::minRowSize\n-std::size_t minRowSize()\n-Definition: galerkin.hh:528\n-Dune::Amg::DirichletBoundarySetter::set\n-static void set(M &coarse, const T &pinfo, const O ©)\n-Definition: galerkin.hh:682\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Vertex\n-Graph::VertexDescriptor Vertex\n-The vertex descriptor of the graph.\n-Definition: galerkin.hh:230\n-Dune::Amg::BaseGalerkinProduct::calculate\n-void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n-const I &pinfo, const O ©)\n-Calculate the galerkin product.\n-Dune::Amg::SparsityBuilder::maxRowSize\n-std::size_t maxRowSize()\n-Definition: galerkin.hh:523\n-std\n-STL namespace.\n+ 412} /* namespace Dune */\n+ 413\n+ 414#endif // HAVE_SUITESPARSE_CHOLMOD\n+solver.hh\n+Define general, extensible interface for inverse operators.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+foreach.hh\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+solverfactory.hh\n+Dune::DUNE_REGISTER_DIRECT_SOLVER\n+DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::Amg::AggregatesMap\n-Class providing information about the mapping of the vertices onto aggregates.\n-Definition: aggregates.hh:560\n-Dune::Amg::OverlapVertex\n-Definition: galerkin.hh:33\n-Dune::Amg::SparsityBuilder\n-Functor for building the sparsity pattern of the matrix using\n-examineConnectivity.\n-Definition: galerkin.hh:63\n-Dune::Amg::BaseGalerkinProduct\n-Definition: galerkin.hh:99\n-Dune::Amg::GalerkinProduct\n-Definition: galerkin.hh:118\n-Dune::Amg::BaseConnectivityConstructor\n-Definition: galerkin.hh:185\n-Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder\n-Visitor for identifying connected aggregates during a breadthFirstSearch.\n-Definition: galerkin.hh:206\n-Dune::Amg::ConnectivityConstructor\n-Definition: galerkin.hh:271\n-Dune::Amg::DirichletBoundarySetter\n-Definition: galerkin.hh:300\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::SolverCategory::nonoverlapping\n-@ nonoverlapping\n-Category for non-overlapping solvers.\n-Definition: solvercategory.hh:27\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n+Dune::flatMatrixForEach\n+std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f,\n+std::size_t rowOffset=0, std::size_t colOffset=0)\n+Traverse a blocked matrix and call a functor at each scalar entry.\n+Definition: foreach.hh:132\n+Dune::flatVectorForEach\n+std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)\n+Traverse a blocked vector and call a functor at each scalar entry.\n+Definition: foreach.hh:95\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00107.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00107.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: globalaggregates.hh File Reference\n+dune-istl: bccsmatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -58,61 +58,36 @@\n \n \n \n

    \n \n
    \n \n- \n+
    bccsmatrix.hh File Reference
    \n
    \n
    \n-\n-

    Provdes class for identifying aggregates globally. \n-More...

    \n-
    #include "aggregates.hh"
    \n-#include "pinfo.hh"
    \n-#include <dune/common/parallel/indexset.hh>
    \n+
    #include <dune/common/fmatrix.hh>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/common/typetraits.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    struct  Dune::Amg::GlobalAggregatesMap< T, TI >
     
    class  Dune::Amg::GlobalAggregatesMap< T, TI >::Proxy
     
    struct  Dune::Amg::AggregatesGatherScatter< T, TI >
     
    struct  Dune::Amg::AggregatesPublisher< T, O, I >
     
    struct  Dune::Amg::AggregatesPublisher< T, O, OwnerOverlapCopyCommunication< T1, T2 > >
     Utility class for publishing the aggregate number of the DOFs in the overlap to other processors and convert them to local indices. More...
     
    struct  Dune::Amg::AggregatesPublisher< T, O, SequentialInformation >
     
    struct  Dune::CommPolicy< Amg::GlobalAggregatesMap< T, TI > >
     
    \n \n \n \n-\n+\n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
    namespace  Dune::ISTL
     
    \n-

    Detailed Description

    \n-

    Provdes class for identifying aggregates globally.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,47 +4,21 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces\n-globalaggregates.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provdes class for identifying aggregates globally. More...\n-#include \"aggregates.hh\"\n-#include \"pinfo.hh\"\n-#include \n+Namespaces\n+bccsmatrix.hh File Reference\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n- Classes\n-struct \u00a0Dune::Amg::GlobalAggregatesMap<_T,_TI_>\n-\u00a0\n- class \u00a0Dune::Amg::GlobalAggregatesMap<_T,_TI_>::Proxy\n-\u00a0\n-struct \u00a0Dune::Amg::AggregatesGatherScatter<_T,_TI_>\n-\u00a0\n-struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_I_>\n-\u00a0\n-struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<\n- T1,_T2_>_>\n-\u00a0 Utility class for publishing the aggregate number of the DOFs in the\n- overlap to other processors and convert them to local indices. More...\n-\u00a0\n-struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>\n-\u00a0\n-struct \u00a0Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n+namespace \u00a0Dune::ISTL\n \u00a0\n-***** Detailed Description *****\n-Provdes class for identifying aggregates globally.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00107_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00107_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: globalaggregates.hh Source File\n+dune-istl: bccsmatrix.hh Source File\n \n \n \n \n \n \n \n@@ -58,304 +58,133 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    globalaggregates.hh
    \n+
    bccsmatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_GLOBALAGGREGATES_HH
    \n-
    6#define DUNE_GLOBALAGGREGATES_HH
    \n+
    5#ifndef DUNE_ISTL_BCCSMATRIX_HH
    \n+
    6#define DUNE_ISTL_BCCSMATRIX_HH
    \n
    7
    \n-
    18#include "aggregates.hh"
    \n-
    19#include "pinfo.hh"
    \n-
    20#include <dune/common/parallel/indexset.hh>
    \n-
    21
    \n-
    22namespace Dune
    \n-
    23{
    \n-
    24 namespace Amg
    \n-
    25 {
    \n-
    26
    \n-
    27 template<typename T, typename TI>
    \n-\n-
    29 {
    \n-
    30 public:
    \n-
    31 typedef TI ParallelIndexSet;
    \n-
    32
    \n-
    33 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n-
    34
    \n-
    35 typedef typename ParallelIndexSet::GlobalIndex IndexedType;
    \n-
    36
    \n-
    37 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
    \n-
    38
    \n-
    39 typedef T Vertex;
    \n-
    40
    \n-\n-
    42 const GlobalLookupIndexSet<ParallelIndexSet>& indexset)
    \n-
    43 : aggregates_(aggregates), indexset_(indexset)
    \n-
    44 {}
    \n-
    45
    \n-
    46 inline const GlobalIndex& operator[](std::size_t index) const
    \n-
    47 {
    \n-
    48 const Vertex& aggregate = aggregates_[index];
    \n-
    49 if(aggregate >= AggregatesMap<Vertex>::ISOLATED) {
    \n-
    50 assert(aggregate != AggregatesMap<Vertex>::UNAGGREGATED);
    \n-
    51 return isolatedMarker;
    \n-
    52 }else{
    \n-
    53 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
    \n-
    54 assert(pair!=0);
    \n-
    55 return pair->global();
    \n-
    56 }
    \n-
    57 }
    \n-
    58
    \n-
    59
    \n-
    60 inline GlobalIndex& get(std::size_t index)
    \n-
    61 {
    \n-
    62 const Vertex& aggregate = aggregates_[index];
    \n-
    63 assert(aggregate < AggregatesMap<Vertex>::ISOLATED);
    \n-
    64 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
    \n-
    65 assert(pair!=0);
    \n-
    66 return const_cast<GlobalIndex&>(pair->global());
    \n-
    67 }
    \n+
    8#include <dune/common/fmatrix.hh>
    \n+
    9#include <dune/common/fvector.hh>
    \n+
    10#include <dune/common/typetraits.hh>
    \n+
    11
    \n+
    12namespace Dune::ISTL::Impl
    \n+
    13{
    \n+
    27 template<class B, class I = typename std::allocator<B>::size_type>
    \n+
    28 class BCCSMatrix
    \n+
    29 {
    \n+
    30 public:
    \n+
    31 using Index = I;
    \n+
    32 using size_type = std::size_t;
    \n+
    33
    \n+
    36 BCCSMatrix()
    \n+
    37 : N_(0), M_(0), Nnz_(0), values(0), rowindex(0), colstart(0)
    \n+
    38 {}
    \n+
    39
    \n+
    41 ~BCCSMatrix()
    \n+
    42 {
    \n+
    43 if(N_+M_+Nnz_!=0)
    \n+
    44 free();
    \n+
    45 }
    \n+
    46
    \n+
    48 void setSize(size_type rows, size_type columns)
    \n+
    49 {
    \n+
    50 N_ = rows;
    \n+
    51 M_ = columns;
    \n+
    52 }
    \n+
    53
    \n+
    58 size_type N() const
    \n+
    59 {
    \n+
    60 return N_;
    \n+
    61 }
    \n+
    62
    \n+
    64 size_type nonzeroes() const
    \n+
    65 {
    \n+
    66 return Nnz_;
    \n+
    67 }
    \n
    68
    \n-
    69 class Proxy
    \n-
    70 {
    \n-
    71 public:
    \n-
    72 Proxy(const GlobalLookupIndexSet<ParallelIndexSet>& indexset, Vertex& aggregate)
    \n-
    73 : indexset_(&indexset), aggregate_(&aggregate)
    \n-
    74 {}
    \n-
    75
    \n-
    76 Proxy& operator=(const GlobalIndex& global)
    \n-
    77 {
    \n-
    78 if(global==isolatedMarker)
    \n-\n-
    80 else{
    \n-
    81 //assert(global < AggregatesMap<Vertex>::ISOLATED);
    \n-
    82 *aggregate_ = indexset_->operator[](global).local();
    \n-
    83 }
    \n-
    84 return *this;
    \n-
    85 }
    \n-
    86 private:
    \n-
    87 const GlobalLookupIndexSet<ParallelIndexSet>* indexset_;
    \n-
    88 Vertex* aggregate_;
    \n-
    89 };
    \n-
    90
    \n-
    91 inline Proxy operator[](std::size_t index)
    \n-
    92 {
    \n-
    93 return Proxy(indexset_, aggregates_[index]);
    \n-
    94 }
    \n-
    95
    \n-
    96 inline void put(const GlobalIndex& global, size_t i)
    \n-
    97 {
    \n-
    98 aggregates_[i]=indexset_[global].local();
    \n+
    73 size_type M() const
    \n+
    74 {
    \n+
    75 return M_;
    \n+
    76 }
    \n+
    77
    \n+
    84 B* getValues() const
    \n+
    85 {
    \n+
    86 return values;
    \n+
    87 }
    \n+
    88
    \n+
    95 Index* getRowIndex() const
    \n+
    96 {
    \n+
    97 return rowindex;
    \n+
    98 }
    \n
    99
    \n-
    100 }
    \n-
    101
    \n-
    102 private:
    \n-
    103 AggregatesMap<Vertex>& aggregates_;
    \n-
    104 const GlobalLookupIndexSet<ParallelIndexSet>& indexset_;
    \n-
    105 static const GlobalIndex isolatedMarker;
    \n-
    106 };
    \n-
    107
    \n-
    108 template<typename T, typename TI>
    \n-
    109 const typename TI::GlobalIndex GlobalAggregatesMap<T,TI>::isolatedMarker =
    \n-
    110 std::numeric_limits<typename TI::GlobalIndex>::max();
    \n-
    111
    \n-
    112 template<typename T, typename TI>
    \n-\n-
    114 {
    \n-\n-
    116 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n-
    117
    \n-
    118 static const GlobalIndex& gather(const GlobalAggregatesMap<T,TI>& ga, size_t i)
    \n-
    119 {
    \n-
    120 return ga[i];
    \n-
    121 }
    \n-
    122
    \n-
    123 static void scatter(GlobalAggregatesMap<T,TI>& ga, GlobalIndex global, size_t i)
    \n-
    124 {
    \n-
    125 ga[i]=global;
    \n-
    126 }
    \n-
    127 };
    \n+
    106 Index* getColStart() const
    \n+
    107 {
    \n+
    108 return colstart;
    \n+
    109 }
    \n+
    110
    \n+
    112 BCCSMatrix& operator=(const BCCSMatrix& mat)
    \n+
    113 {
    \n+
    114 if(N_+M_+Nnz_!=0)
    \n+
    115 free();
    \n+
    116 N_=mat.N_;
    \n+
    117 M_=mat.M_;
    \n+
    118 Nnz_= mat.Nnz_;
    \n+
    119 if(M_>0) {
    \n+
    120 colstart=new size_type[M_+1];
    \n+
    121 for(size_type i=0; i<=M_; ++i)
    \n+
    122 colstart[i]=mat.colstart[i];
    \n+
    123 }
    \n+
    124
    \n+
    125 if(Nnz_>0) {
    \n+
    126 values = new B[Nnz_];
    \n+
    127 rowindex = new size_type[Nnz_];
    \n
    128
    \n-
    129 template<typename T, typename O, typename I>
    \n-\n-
    131 {};
    \n-
    132
    \n-
    133#if HAVE_MPI
    \n-
    134
    \n-
    135#endif
    \n-
    136
    \n-
    137 } // namespace Amg
    \n-
    138
    \n-
    139#if HAVE_MPI
    \n-
    140 // forward declaration
    \n-
    141 template<class T1, class T2>
    \n-\n-
    143#endif
    \n-
    144
    \n-
    145 namespace Amg
    \n-
    146 {
    \n-
    147
    \n-
    148#if HAVE_MPI
    \n-
    158 template<typename T, typename O, typename T1, typename T2>
    \n-\n-
    160 {
    \n-
    161 typedef T Vertex;
    \n-
    162 typedef O OverlapFlags;
    \n-\n-\n-\n-
    166
    \n-
    167 static void publish(AggregatesMap<Vertex>& aggregates,
    \n-
    168 ParallelInformation& pinfo,
    \n-
    169 const GlobalLookupIndexSet& globalLookup)
    \n-
    170 {
    \n-\n-
    172 GlobalMap gmap(aggregates, globalLookup);
    \n-
    173 pinfo.copyOwnerToAll(gmap,gmap);
    \n-
    174 // communication only needed for ALU
    \n-
    175 // (ghosts with same global id as owners on the same process)
    \n-
    176 if (SolverCategory::category(pinfo) == static_cast<int>(SolverCategory::nonoverlapping))
    \n-
    177 pinfo.copyCopyToAll(gmap,gmap);
    \n-
    178
    \n-
    179 typedef typename ParallelInformation::RemoteIndices::const_iterator Lists;
    \n-
    180 Lists lists = pinfo.remoteIndices().find(pinfo.communicator().rank());
    \n-
    181 if(lists!=pinfo.remoteIndices().end()) {
    \n-
    182
    \n-
    183 // For periodic boundary conditions we must renumber
    \n-
    184 // the aggregates of vertices in the overlap whose owners are
    \n-
    185 // on the same process
    \n-
    186 Vertex maxAggregate =0;
    \n-
    187 typedef typename AggregatesMap<Vertex>::const_iterator Iter;
    \n-
    188 for(Iter i=aggregates.begin(), end=aggregates.end(); i!=end; ++i)
    \n-
    189 maxAggregate = std::max(maxAggregate, *i);
    \n-
    190
    \n-
    191 // Compute new mapping of aggregates in the overlap that we also own
    \n-
    192 std::map<Vertex,Vertex> newMapping;
    \n-
    193
    \n-
    194 // insert all elements into map
    \n-
    195 typedef typename ParallelInformation::RemoteIndices::RemoteIndexList
    \n-
    196 ::const_iterator RIter;
    \n-
    197 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end();
    \n-
    198 ri!=rend; ++ri)
    \n-
    199 if(O::contains(ri->localIndexPair().local().attribute()))
    \n-
    200 newMapping.insert(std::make_pair(aggregates[ri->localIndexPair().local()],
    \n-
    201 maxAggregate));
    \n-
    202 // renumber
    \n-
    203 typedef typename std::map<Vertex,Vertex>::iterator MIter;
    \n-
    204 for(MIter mi=newMapping.begin(), mend=newMapping.end();
    \n-
    205 mi != mend; ++mi)
    \n-
    206 mi->second=++maxAggregate;
    \n-
    207
    \n-
    208
    \n-
    209 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end();
    \n-
    210 ri!=rend; ++ri)
    \n-
    211 if(O::contains(ri->localIndexPair().local().attribute()))
    \n-
    212 aggregates[ri->localIndexPair().local()] =
    \n-
    213 newMapping[aggregates[ri->localIndexPair().local()]];
    \n-
    214 }
    \n-
    215 }
    \n-
    216 };
    \n-
    217#endif
    \n-
    218
    \n-
    219 template<typename T, typename O>
    \n-\n-
    221 {
    \n-
    222 typedef T Vertex;
    \n-\n-\n-
    225
    \n-
    226 static void publish([[maybe_unused]] AggregatesMap<Vertex>& aggregates,
    \n-
    227 [[maybe_unused]] ParallelInformation& pinfo,
    \n-
    228 [[maybe_unused]] const GlobalLookupIndexSet& globalLookup)
    \n-
    229 {}
    \n-
    230 };
    \n-
    231
    \n-
    232 } // end Amg namespace
    \n-
    233
    \n-
    234
    \n-
    235#if HAVE_MPI
    \n-
    236 template<typename T, typename TI>
    \n-
    237 struct CommPolicy<Amg::GlobalAggregatesMap<T,TI> >
    \n-
    238 {
    \n-\n-\n-
    241 typedef SizeOne IndexedTypeFlag;
    \n-
    242 static int getSize(const Type&, int)
    \n-
    243 {
    \n-
    244 return 1;
    \n-
    245 }
    \n-
    246 };
    \n-
    247#endif
    \n-
    248
    \n-
    249} // end Dune namespace
    \n-
    250 /* @} */
    \n-
    251#endif
    \n-
    Provides classes for the Coloring process of AMG.
    \n-\n-
    ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet
    Definition: globalaggregates.hh:164
    \n-
    const GlobalIndex & operator[](std::size_t index) const
    Definition: globalaggregates.hh:46
    \n-\n-
    static int getSize(const Type &, int)
    Definition: globalaggregates.hh:242
    \n-
    Amg::GlobalAggregatesMap< T, TI >::IndexedType IndexedType
    Definition: globalaggregates.hh:240
    \n-
    GlobalIndex & get(std::size_t index)
    Definition: globalaggregates.hh:60
    \n-\n-
    static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation &pinfo, const GlobalLookupIndexSet &globalLookup)
    Definition: globalaggregates.hh:226
    \n-
    SequentialInformation ParallelInformation
    Definition: globalaggregates.hh:223
    \n-
    ParallelIndexSet::GlobalIndex GlobalIndex
    Definition: globalaggregates.hh:33
    \n-
    ParallelInformation::ParallelIndexSet IndexSet
    Definition: globalaggregates.hh:165
    \n-
    void put(const GlobalIndex &global, size_t i)
    Definition: globalaggregates.hh:96
    \n-
    T Vertex
    Definition: globalaggregates.hh:39
    \n-
    GlobalAggregatesMap(AggregatesMap< Vertex > &aggregates, const GlobalLookupIndexSet< ParallelIndexSet > &indexset)
    Definition: globalaggregates.hh:41
    \n-
    TI ParallelIndexSet
    Definition: globalaggregates.hh:31
    \n-
    Amg::AggregatesMap< T > Type
    Definition: globalaggregates.hh:239
    \n-
    static void scatter(GlobalAggregatesMap< T, TI > &ga, GlobalIndex global, size_t i)
    Definition: globalaggregates.hh:123
    \n-
    OwnerOverlapCopyCommunication< T1, T2 > ParallelInformation
    Definition: globalaggregates.hh:163
    \n-
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n-
    SizeOne IndexedTypeFlag
    Definition: globalaggregates.hh:241
    \n-
    Proxy(const GlobalLookupIndexSet< ParallelIndexSet > &indexset, Vertex &aggregate)
    Definition: globalaggregates.hh:72
    \n-
    const_iterator end() const
    Definition: aggregates.hh:730
    \n-
    static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation &pinfo, const GlobalLookupIndexSet &globalLookup)
    Definition: globalaggregates.hh:167
    \n-
    ParallelIndexSet::GlobalIndex GlobalIndex
    Definition: globalaggregates.hh:116
    \n-
    ParallelIndexSet::LocalIndex LocalIndex
    Definition: globalaggregates.hh:37
    \n-
    TI ParallelIndexSet
    Definition: globalaggregates.hh:115
    \n-\n-
    ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet
    Definition: globalaggregates.hh:224
    \n-
    static const GlobalIndex & gather(const GlobalAggregatesMap< T, TI > &ga, size_t i)
    Definition: globalaggregates.hh:118
    \n-
    Proxy & operator=(const GlobalIndex &global)
    Definition: globalaggregates.hh:76
    \n-
    ParallelIndexSet::GlobalIndex IndexedType
    Definition: globalaggregates.hh:35
    \n-
    Proxy operator[](std::size_t index)
    Definition: globalaggregates.hh:91
    \n-
    Definition: allocator.hh:11
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n-
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n-
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n-
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n-
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n-
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n-\n-
    Definition: globalaggregates.hh:29
    \n-
    Definition: globalaggregates.hh:70
    \n-
    Definition: globalaggregates.hh:114
    \n-
    Definition: globalaggregates.hh:131
    \n-
    Definition: pinfo.hh:28
    \n-
    int GlobalLookupIndexSet
    Definition: pinfo.hh:54
    \n-
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    129 for(size_type i=0; i<Nnz_; ++i)
    \n+
    130 values[i]=mat.values[i];
    \n+
    131
    \n+
    132 for(size_type i=0; i<Nnz_; ++i)
    \n+
    133 rowindex[i]=mat.rowindex[i];
    \n+
    134 }
    \n+
    135 return *this;
    \n+
    136 }
    \n+
    137
    \n+
    139 virtual void free()
    \n+
    140 {
    \n+
    141 delete[] values;
    \n+
    142 delete[] rowindex;
    \n+
    143 delete[] colstart;
    \n+
    144 N_ = 0;
    \n+
    145 M_ = 0;
    \n+
    146 Nnz_ = 0;
    \n+
    147 }
    \n+
    148
    \n+
    149 public:
    \n+
    150 size_type N_, M_, Nnz_;
    \n+
    151 B* values;
    \n+
    152 Index* rowindex;
    \n+
    153 Index* colstart;
    \n+
    154 };
    \n+
    155
    \n+
    156}
    \n+
    157#endif
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,421 +4,127 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-globalaggregates.hh\n+bccsmatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_GLOBALAGGREGATES_HH\n- 6#define DUNE_GLOBALAGGREGATES_HH\n+ 5#ifndef DUNE_ISTL_BCCSMATRIX_HH\n+ 6#define DUNE_ISTL_BCCSMATRIX_HH\n 7\n- 18#include \"aggregates.hh\"\n- 19#include \"pinfo.hh\"\n- 20#include \n- 21\n- 22namespace Dune\n- 23{\n- 24 namespace Amg\n- 25 {\n- 26\n- 27 template\n-28 struct GlobalAggregatesMap\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11\n+12namespace Dune::ISTL::Impl\n+ 13{\n+ 27 template::size_type>\n+ 28 class BCCSMatrix\n 29 {\n 30 public:\n-31 typedef TI ParallelIndexSet;\n- 32\n-33 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n- 34\n-35 typedef typename ParallelIndexSet::GlobalIndex IndexedType;\n- 36\n-37 typedef typename ParallelIndexSet::LocalIndex LocalIndex;\n- 38\n-39 typedef T Vertex;\n- 40\n-41 GlobalAggregatesMap(AggregatesMap& aggregates,\n- 42 const GlobalLookupIndexSet& indexset)\n- 43 : aggregates_(aggregates), indexset_(indexset)\n- 44 {}\n- 45\n-46 inline const GlobalIndex& operator[](std::size_t index) const\n- 47 {\n- 48 const Vertex& aggregate = aggregates_[index];\n- 49 if(aggregate >= AggregatesMap::ISOLATED) {\n- 50 assert(aggregate != AggregatesMap::UNAGGREGATED);\n- 51 return isolatedMarker;\n- 52 }else{\n- 53 const Dune::IndexPair* pair = indexset_.pair\n-(aggregate);\n- 54 assert(pair!=0);\n- 55 return pair->global();\n- 56 }\n- 57 }\n- 58\n- 59\n-60 inline GlobalIndex& get(std::size_t index)\n- 61 {\n- 62 const Vertex& aggregate = aggregates_[index];\n- 63 assert(aggregate < AggregatesMap::ISOLATED);\n- 64 const Dune::IndexPair* pair = indexset_.pair\n-(aggregate);\n- 65 assert(pair!=0);\n- 66 return const_cast(pair->global());\n+ 31 using Index = I;\n+ 32 using size_type = std::size_t;\n+ 33\n+ 36 BCCSMatrix()\n+ 37 : N_(0), M_(0), Nnz_(0), values(0), rowindex(0), colstart(0)\n+ 38 {}\n+ 39\n+ 41 ~BCCSMatrix()\n+ 42 {\n+ 43 if(N_+M_+Nnz_!=0)\n+ 44 free();\n+ 45 }\n+ 46\n+ 48 void setSize(size_type rows, size_type columns)\n+ 49 {\n+ 50 N_ = rows;\n+ 51 M_ = columns;\n+ 52 }\n+ 53\n+ 58 size_type N() const\n+ 59 {\n+ 60 return N_;\n+ 61 }\n+ 62\n+ 64 size_type nonzeroes() const\n+ 65 {\n+ 66 return Nnz_;\n 67 }\n 68\n-69 class Proxy\n- 70 {\n- 71 public:\n-72 Proxy(const GlobalLookupIndexSet& indexset, Vertex&\n-aggregate)\n- 73 : indexset_(&indexset), aggregate_(&aggregate)\n- 74 {}\n- 75\n-76 Proxy& operator=(const GlobalIndex& global)\n- 77 {\n- 78 if(global==isolatedMarker)\n- 79 *aggregate_ = AggregatesMap::ISOLATED;\n- 80 else{\n- 81 //assert(global < AggregatesMap::ISOLATED);\n- 82 *aggregate_ = indexset_->operator[](global).local();\n- 83 }\n- 84 return *this;\n- 85 }\n- 86 private:\n- 87 const GlobalLookupIndexSet* indexset_;\n- 88 Vertex* aggregate_;\n- 89 };\n- 90\n-91 inline Proxy operator[](std::size_t index)\n- 92 {\n- 93 return Proxy(indexset_, aggregates_[index]);\n- 94 }\n- 95\n-96 inline void put(const GlobalIndex& global, size_t i)\n- 97 {\n- 98 aggregates_[i]=indexset_[global].local();\n+ 73 size_type M() const\n+ 74 {\n+ 75 return M_;\n+ 76 }\n+ 77\n+ 84 B* getValues() const\n+ 85 {\n+ 86 return values;\n+ 87 }\n+ 88\n+ 95 Index* getRowIndex() const\n+ 96 {\n+ 97 return rowindex;\n+ 98 }\n 99\n- 100 }\n- 101\n- 102 private:\n- 103 AggregatesMap& aggregates_;\n- 104 const GlobalLookupIndexSet& indexset_;\n- 105 static const GlobalIndex isolatedMarker;\n- 106 };\n- 107\n- 108 template\n- 109 const typename TI::GlobalIndex GlobalAggregatesMap::isolatedMarker =\n- 110 std::numeric_limits::max();\n- 111\n- 112 template\n-113 struct AggregatesGatherScatter\n- 114 {\n-115 typedef TI ParallelIndexSet;\n-116 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n- 117\n-118 static const GlobalIndex& gather(const GlobalAggregatesMap& ga,\n-size_t i)\n- 119 {\n- 120 return ga[i];\n- 121 }\n- 122\n-123 static void scatter(GlobalAggregatesMap& ga, GlobalIndex global,\n-size_t i)\n- 124 {\n- 125 ga[i]=global;\n- 126 }\n- 127 };\n+ 106 Index* getColStart() const\n+ 107 {\n+ 108 return colstart;\n+ 109 }\n+ 110\n+ 112 BCCSMatrix& operator=(const BCCSMatrix& mat)\n+ 113 {\n+ 114 if(N_+M_+Nnz_!=0)\n+ 115 free();\n+ 116 N_=mat.N_;\n+ 117 M_=mat.M_;\n+ 118 Nnz_= mat.Nnz_;\n+ 119 if(M_>0) {\n+ 120 colstart=new size_type[M_+1];\n+ 121 for(size_type i=0; i<=M_; ++i)\n+ 122 colstart[i]=mat.colstart[i];\n+ 123 }\n+ 124\n+ 125 if(Nnz_>0) {\n+ 126 values = new B[Nnz_];\n+ 127 rowindex = new size_type[Nnz_];\n 128\n- 129 template\n-130 struct AggregatesPublisher\n- 131 {};\n- 132\n- 133#if HAVE_MPI\n- 134\n- 135#endif\n- 136\n- 137 } // namespace Amg\n- 138\n- 139#if HAVE_MPI\n- 140 // forward declaration\n- 141 template\n- 142 class OwnerOverlapCopyCommunication;\n- 143#endif\n- 144\n- 145 namespace Amg\n- 146 {\n- 147\n- 148#if HAVE_MPI\n- 158 template\n-159 struct AggregatesPublisher >\n- 160 {\n-161 typedef T Vertex;\n-162 typedef O OverlapFlags;\n-163 typedef OwnerOverlapCopyCommunication ParallelInformation;\n-164 typedef typename ParallelInformation::GlobalLookupIndexSet\n-GlobalLookupIndexSet;\n-165 typedef typename ParallelInformation::ParallelIndexSet IndexSet;\n- 166\n-167 static void publish(AggregatesMap& aggregates,\n- 168 ParallelInformation& pinfo,\n- 169 const GlobalLookupIndexSet& globalLookup)\n- 170 {\n- 171 typedef Dune::Amg::GlobalAggregatesMap GlobalMap;\n- 172 GlobalMap gmap(aggregates, globalLookup);\n- 173 pinfo.copyOwnerToAll(gmap,gmap);\n- 174 // communication only needed for ALU\n- 175 // (ghosts with same global id as owners on the same process)\n- 176 if (SolverCategory::category(pinfo) == static_cast(SolverCategory::\n-nonoverlapping))\n- 177 pinfo.copyCopyToAll(gmap,gmap);\n- 178\n- 179 typedef typename ParallelInformation::RemoteIndices::const_iterator Lists;\n- 180 Lists lists = pinfo.remoteIndices().find(pinfo.communicator().rank());\n- 181 if(lists!=pinfo.remoteIndices().end()) {\n- 182\n- 183 // For periodic boundary conditions we must renumber\n- 184 // the aggregates of vertices in the overlap whose owners are\n- 185 // on the same process\n- 186 Vertex maxAggregate =0;\n- 187 typedef typename AggregatesMap::const_iterator Iter;\n- 188 for(Iter i=aggregates.begin(), end=aggregates.end(); i!=end; ++i)\n- 189 maxAggregate = std::max(maxAggregate, *i);\n- 190\n- 191 // Compute new mapping of aggregates in the overlap that we also own\n- 192 std::map newMapping;\n- 193\n- 194 // insert all elements into map\n- 195 typedef typename ParallelInformation::RemoteIndices::RemoteIndexList\n- 196 ::const_iterator RIter;\n- 197 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end\n-();\n- 198 ri!=rend; ++ri)\n- 199 if(O::contains(ri->localIndexPair().local().attribute()))\n- 200 newMapping.insert(std::make_pair(aggregates[ri->localIndexPair().local()],\n- 201 maxAggregate));\n- 202 // renumber\n- 203 typedef typename std::map::iterator MIter;\n- 204 for(MIter mi=newMapping.begin(), mend=newMapping.end();\n- 205 mi != mend; ++mi)\n- 206 mi->second=++maxAggregate;\n- 207\n- 208\n- 209 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end\n-();\n- 210 ri!=rend; ++ri)\n- 211 if(O::contains(ri->localIndexPair().local().attribute()))\n- 212 aggregates[ri->localIndexPair().local()] =\n- 213 newMapping[aggregates[ri->localIndexPair().local()]];\n- 214 }\n- 215 }\n- 216 };\n- 217#endif\n- 218\n- 219 template\n-220 struct AggregatesPublisher\n- 221 {\n-222 typedef T Vertex;\n-223 typedef SequentialInformation ParallelInformation;\n-224 typedef typename ParallelInformation::GlobalLookupIndexSet\n-GlobalLookupIndexSet;\n- 225\n-226 static void publish([[maybe_unused]] AggregatesMap& aggregates,\n- 227 [[maybe_unused]] ParallelInformation& pinfo,\n- 228 [[maybe_unused]] const GlobalLookupIndexSet& globalLookup)\n- 229 {}\n- 230 };\n- 231\n- 232 } // end Amg namespace\n- 233\n- 234\n- 235#if HAVE_MPI\n- 236 template\n-237 struct CommPolicy >\n- 238 {\n-239 typedef Amg::AggregatesMap Type;\n-240 typedef typename Amg::GlobalAggregatesMap::IndexedType IndexedType;\n-241 typedef SizeOne IndexedTypeFlag;\n-242 static int getSize(const Type&, int)\n- 243 {\n- 244 return 1;\n- 245 }\n- 246 };\n- 247#endif\n- 248\n- 249} // end Dune namespace\n- 250 /* @} */\n- 251#endif\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n-pinfo.hh\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::GlobalLookupIndexSet\n-ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet\n-Definition: globalaggregates.hh:164\n-Dune::Amg::GlobalAggregatesMap::operator[]\n-const GlobalIndex & operator[](std::size_t index) const\n-Definition: globalaggregates.hh:46\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::OverlapFlags\n-O OverlapFlags\n-Definition: globalaggregates.hh:162\n-Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::getSize\n-static int getSize(const Type &, int)\n-Definition: globalaggregates.hh:242\n-Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::IndexedType\n-Amg::GlobalAggregatesMap< T, TI >::IndexedType IndexedType\n-Definition: globalaggregates.hh:240\n-Dune::Amg::GlobalAggregatesMap::get\n-GlobalIndex & get(std::size_t index)\n-Definition: globalaggregates.hh:60\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::Vertex\n-T Vertex\n-Definition: globalaggregates.hh:161\n-Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::publish\n-static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation\n-&pinfo, const GlobalLookupIndexSet &globalLookup)\n-Definition: globalaggregates.hh:226\n-Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::\n-ParallelInformation\n-SequentialInformation ParallelInformation\n-Definition: globalaggregates.hh:223\n-Dune::Amg::GlobalAggregatesMap::GlobalIndex\n-ParallelIndexSet::GlobalIndex GlobalIndex\n-Definition: globalaggregates.hh:33\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::IndexSet\n-ParallelInformation::ParallelIndexSet IndexSet\n-Definition: globalaggregates.hh:165\n-Dune::Amg::GlobalAggregatesMap::put\n-void put(const GlobalIndex &global, size_t i)\n-Definition: globalaggregates.hh:96\n-Dune::Amg::GlobalAggregatesMap::Vertex\n-T Vertex\n-Definition: globalaggregates.hh:39\n-Dune::Amg::GlobalAggregatesMap::GlobalAggregatesMap\n-GlobalAggregatesMap(AggregatesMap< Vertex > &aggregates, const\n-GlobalLookupIndexSet< ParallelIndexSet > &indexset)\n-Definition: globalaggregates.hh:41\n-Dune::Amg::GlobalAggregatesMap::ParallelIndexSet\n-TI ParallelIndexSet\n-Definition: globalaggregates.hh:31\n-Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::Type\n-Amg::AggregatesMap< T > Type\n-Definition: globalaggregates.hh:239\n-Dune::Amg::AggregatesGatherScatter::scatter\n-static void scatter(GlobalAggregatesMap< T, TI > &ga, GlobalIndex global,\n-size_t i)\n-Definition: globalaggregates.hh:123\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::ParallelInformation\n-OwnerOverlapCopyCommunication< T1, T2 > ParallelInformation\n-Definition: globalaggregates.hh:163\n-Dune::Amg::AggregatesMap::begin\n-const_iterator begin() const\n-Definition: aggregates.hh:725\n-Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::IndexedTypeFlag\n-SizeOne IndexedTypeFlag\n-Definition: globalaggregates.hh:241\n-Dune::Amg::GlobalAggregatesMap::Proxy::Proxy\n-Proxy(const GlobalLookupIndexSet< ParallelIndexSet > &indexset, Vertex\n-&aggregate)\n-Definition: globalaggregates.hh:72\n-Dune::Amg::AggregatesMap::end\n-const_iterator end() const\n-Definition: aggregates.hh:730\n-Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n->::publish\n-static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation\n-&pinfo, const GlobalLookupIndexSet &globalLookup)\n-Definition: globalaggregates.hh:167\n-Dune::Amg::AggregatesGatherScatter::GlobalIndex\n-ParallelIndexSet::GlobalIndex GlobalIndex\n-Definition: globalaggregates.hh:116\n-Dune::Amg::GlobalAggregatesMap::LocalIndex\n-ParallelIndexSet::LocalIndex LocalIndex\n-Definition: globalaggregates.hh:37\n-Dune::Amg::AggregatesGatherScatter::ParallelIndexSet\n-TI ParallelIndexSet\n-Definition: globalaggregates.hh:115\n-Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::Vertex\n-T Vertex\n-Definition: globalaggregates.hh:222\n-Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::\n-GlobalLookupIndexSet\n-ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet\n-Definition: globalaggregates.hh:224\n-Dune::Amg::AggregatesGatherScatter::gather\n-static const GlobalIndex & gather(const GlobalAggregatesMap< T, TI > &ga,\n-size_t i)\n-Definition: globalaggregates.hh:118\n-Dune::Amg::GlobalAggregatesMap::Proxy::operator=\n-Proxy & operator=(const GlobalIndex &global)\n-Definition: globalaggregates.hh:76\n-Dune::Amg::GlobalAggregatesMap::IndexedType\n-ParallelIndexSet::GlobalIndex IndexedType\n-Definition: globalaggregates.hh:35\n-Dune::Amg::GlobalAggregatesMap::operator[]\n-Proxy operator[](std::size_t index)\n-Definition: globalaggregates.hh:91\n-Dune\n-Definition: allocator.hh:11\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n-void copyCopyToAll(const T &source, T &dest) const\n-Communicate values from copy data points to all other data points.\n-Definition: owneroverlapcopy.hh:328\n-Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n-Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n-The type of the reverse lookup of indices.\n-Definition: owneroverlapcopy.hh:456\n-Dune::OwnerOverlapCopyCommunication::communicator\n-const Communication< MPI_Comm > & communicator() const\n-Definition: owneroverlapcopy.hh:299\n-Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n-void copyOwnerToAll(const T &source, T &dest) const\n-Communicate values from owner data points to all other data points.\n-Definition: owneroverlapcopy.hh:311\n-Dune::OwnerOverlapCopyCommunication::remoteIndices\n-const RemoteIndices & remoteIndices() const\n-Get the underlying remote indices.\n-Definition: owneroverlapcopy.hh:471\n-Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n-Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n-The type of the parallel index set.\n-Definition: owneroverlapcopy.hh:449\n-Dune::Amg::AggregatesMap<_Vertex_>\n-Dune::Amg::GlobalAggregatesMap\n-Definition: globalaggregates.hh:29\n-Dune::Amg::GlobalAggregatesMap::Proxy\n-Definition: globalaggregates.hh:70\n-Dune::Amg::AggregatesGatherScatter\n-Definition: globalaggregates.hh:114\n-Dune::Amg::AggregatesPublisher\n-Definition: globalaggregates.hh:131\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::SequentialInformation::GlobalLookupIndexSet\n-int GlobalLookupIndexSet\n-Definition: pinfo.hh:54\n-Dune::SolverCategory::nonoverlapping\n-@ nonoverlapping\n-Category for non-overlapping solvers.\n-Definition: solvercategory.hh:27\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n+ 129 for(size_type i=0; i\n \n \n \n \n \n \n-dune-istl: hierarchy.hh File Reference\n+dune-istl: repartition.hh File Reference\n \n \n \n \n \n \n \n@@ -58,56 +58,107 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n \n+
    repartition.hh File Reference
    \n \n
    \n \n-

    Provides a classes representing the hierarchies in AMG. \n+

    Functionality for redistributing a parallel index set using graph partitioning. \n More...

    \n-
    #include <list>
    \n-#include <memory>
    \n-#include <limits>
    \n-#include <dune/common/stdstreams.hh>
    \n+
    #include <cassert>
    \n+#include <map>
    \n+#include <utility>
    \n+#include <cmath>
    \n #include <dune/common/timer.hh>
    \n-#include <dune/common/bigunsignedint.hh>
    \n-#include <dune/istl/paamg/construction.hh>
    \n+#include <dune/common/enumset.hh>
    \n+#include <dune/common/stdstreams.hh>
    \n+#include <dune/common/parallel/mpitraits.hh>
    \n+#include <dune/common/parallel/communicator.hh>
    \n+#include <dune/common/parallel/indexset.hh>
    \n+#include <dune/common/parallel/indicessyncer.hh>
    \n+#include <dune/common/parallel/remoteindices.hh>
    \n+#include <dune/common/rangeutilities.hh>
    \n+#include <dune/istl/owneroverlapcopy.hh>
    \n+#include <dune/istl/paamg/graph.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::Amg::Hierarchy< T, A >
     A hierarchy of containers (e.g. matrices or vectors) More...
     
    class  Dune::Amg::Hierarchy< T, A >::LevelIterator< C, T1 >
     Iterator over the levels in the hierarchy. More...
    struct  Dune::RedistributeInterface
     
    \n \n \n \n-\n+\n \n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
    namespace  Dune::Metis
     
    \n+\n+\n+\n+\n+\n+

    \n+Typedefs

    using Dune::Metis::real_t = float
     
    using Dune::Metis::idx_t = std::size_t
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<class G , class T1 , class T2 >
    void Dune::fillIndexSetHoles (const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
     Fills the holes in an index set. More...
     
    template<class G , class T1 , class T2 >
    bool Dune::buildCommunication (const G &graph, std::vector< int > &realparts, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     
    template<class S , class T >
    void Dune::print_carray (S &os, T *array, std::size_t l)
     
    template<class S , class T >
    bool Dune::isValidGraph (std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T *adjncy, bool checkSymmetry)
     
    template<class M , class T1 , class T2 >
    bool Dune::commGraphRepartition (const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     
    template<class G , class T1 , class T2 >
    bool Dune::graphRepartition (const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
     execute a graph repartition for a giving graph and indexset. More...
     
    \n

    Detailed Description

    \n-

    Provides a classes representing the hierarchies in AMG.

    \n-
    Author
    Markus Blatt
    \n-
    \n+

    Functionality for redistributing a parallel index set using graph partitioning.

    \n+

    Refactored version of an intern.

    Author
    Markus Blatt
    \n+

    Variable Documentation

    \n+\n+

    ◆ globalOwnerVertices

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+
    int globalOwnerVertices
    \n+
    \n+\n+
    \n+
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,40 +4,83 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces\n-hierarchy.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides a classes representing the hierarchies in AMG. More...\n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Typedefs | Functions\n+repartition.hh File Reference\n+Functionality for redistributing a parallel index set using graph partitioning.\n+More...\n+#include \n+#include \n+#include \n+#include \n #include \n-#include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::Hierarchy<_T,_A_>\n-\u00a0 A hierarchy of containers (e.g. matrices or vectors) More...\n-\u00a0\n-class \u00a0Dune::Amg::Hierarchy<_T,_A_>::LevelIterator<_C,_T1_>\n-\u00a0 Iterator over the levels in the hierarchy. More...\n+struct \u00a0Dune::RedistributeInterface\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n+namespace \u00a0Dune::Metis\n+\u00a0\n+ Typedefs\n+using\u00a0Dune::Metis::real_t = float\n+\u00a0\n+using\u00a0Dune::Metis::idx_t = std::size_t\n+\u00a0\n+ Functions\n+template\n+void\u00a0Dune::fillIndexSetHoles (const G &graph, Dune::\n+ OwnerOverlapCopyCommunication< T1, T2 > &oocomm)\n+\u00a0 Fills the holes in an index set. More...\n+\u00a0\n+template\n+bool\u00a0Dune::buildCommunication (const G &graph, std::vector< int > &realparts,\n+ Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr<\n+ Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm,\n+ RedistributeInterface &redistInf, bool verbose=false)\n+\u00a0\n+template\n+void\u00a0Dune::print_carray (S &os, T *array, std::size_t l)\n+\u00a0\n+template\n+bool\u00a0Dune::isValidGraph (std::size_t noVtx, std::size_t gnoVtx, S noEdges, T\n+ *xadj, T *adjncy, bool checkSymmetry)\n+\u00a0\n+template\n+bool\u00a0Dune::commGraphRepartition (const M &mat, Dune::\n+ OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts,\n+ std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > >\n+ &outcomm, RedistributeInterface &redistInf, bool verbose=false)\n+\u00a0\n+template\n+bool\u00a0Dune::graphRepartition (const G &graph, Dune::\n+ OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts,\n+ std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > >\n+ &outcomm, RedistributeInterface &redistInf, bool verbose=false)\n+\u00a0 execute a graph repartition for a giving graph and indexset. More...\n \u00a0\n ***** Detailed Description *****\n-Provides a classes representing the hierarchies in AMG.\n+Functionality for redistributing a parallel index set using graph partitioning.\n+Refactored version of an intern.\n Author\n Markus Blatt\n+***** Variable Documentation *****\n+***** \u25c6\u00a0globalOwnerVertices *****\n+int globalOwnerVertices\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00110_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00110_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: hierarchy.hh Source File\n+dune-istl: repartition.hh Source File\n \n \n \n \n \n \n \n@@ -58,351 +58,1827 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    hierarchy.hh
    \n+
    repartition.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMGHIERARCHY_HH
    \n-
    6#define DUNE_AMGHIERARCHY_HH
    \n+
    5#ifndef DUNE_ISTL_REPARTITION_HH
    \n+
    6#define DUNE_ISTL_REPARTITION_HH
    \n
    7
    \n-
    8#include <list>
    \n-
    9#include <memory>
    \n-
    10#include <limits>
    \n-
    11#include <dune/common/stdstreams.hh>
    \n-
    12#include <dune/common/timer.hh>
    \n-
    13#include <dune/common/bigunsignedint.hh>
    \n-\n-
    15
    \n-
    16namespace Dune
    \n-
    17{
    \n-
    18 namespace Amg
    \n-
    19 {
    \n-
    38 template<typename T, typename A=std::allocator<T> >
    \n-\n-
    40 {
    \n-
    41 public:
    \n-
    45 typedef T MemberType;
    \n-
    46
    \n-
    47 template<typename T1, typename T2>
    \n-
    48 class LevelIterator;
    \n-
    49
    \n-
    50 private:
    \n-
    54 struct Element
    \n-
    55 {
    \n-
    56 friend class LevelIterator<Hierarchy<T,A>, T>;
    \n-
    57 friend class LevelIterator<const Hierarchy<T,A>, const T>;
    \n-
    58
    \n-
    60 std::weak_ptr<Element> coarser_;
    \n-
    61
    \n-
    63 std::shared_ptr<Element> finer_;
    \n-
    64
    \n-
    66 std::shared_ptr<MemberType> element_;
    \n+
    8#include <cassert>
    \n+
    9#include <map>
    \n+
    10#include <utility>
    \n+
    11#include <cmath>
    \n+
    12
    \n+
    13#if HAVE_PARMETIS
    \n+
    14// Explicitly use C linkage as scotch does not extern "C" in its headers.
    \n+
    15// Works because ParMETIS/METIS checks whether compiler is C++ and otherwise
    \n+
    16// does not use extern "C". Therfore no nested extern "C" will be created
    \n+
    17extern "C"
    \n+
    18{
    \n+
    19#include <parmetis.h>
    \n+
    20}
    \n+
    21#endif
    \n+
    22
    \n+
    23#include <dune/common/timer.hh>
    \n+
    24#include <dune/common/enumset.hh>
    \n+
    25#include <dune/common/stdstreams.hh>
    \n+
    26#include <dune/common/parallel/mpitraits.hh>
    \n+
    27#include <dune/common/parallel/communicator.hh>
    \n+
    28#include <dune/common/parallel/indexset.hh>
    \n+
    29#include <dune/common/parallel/indicessyncer.hh>
    \n+
    30#include <dune/common/parallel/remoteindices.hh>
    \n+
    31#include <dune/common/rangeutilities.hh>
    \n+
    32
    \n+\n+\n+
    35
    \n+
    44namespace Dune
    \n+
    45{
    \n+
    46 namespace Metis
    \n+
    47 {
    \n+
    48 // Explicitly specify a real_t and idx_t for older (Par)METIS versions that do not
    \n+
    49 // provide these typedefs
    \n+
    50#if HAVE_PARMETIS && defined(REALTYPEWIDTH)
    \n+
    51 using real_t = ::real_t;
    \n+
    52#else
    \n+
    53 using real_t = float;
    \n+
    54#endif
    \n+
    55
    \n+
    56#if HAVE_PARMETIS && defined(IDXTYPEWIDTH)
    \n+
    57 using idx_t = ::idx_t;
    \n+
    58#elif HAVE_PARMETIS && defined(HAVE_SCOTCH_NUM_TYPE)
    \n+
    59 using idx_t = SCOTCH_Num;
    \n+
    60#elif HAVE_PARMETIS
    \n+
    61 using idx_t = int;
    \n+
    62#else
    \n+
    63 using idx_t = std::size_t;
    \n+
    64#endif
    \n+
    65 }
    \n+
    66
    \n
    67
    \n-
    69 std::shared_ptr<MemberType> redistributed_;
    \n-
    70 };
    \n-
    71 public:
    \n-
    72
    \n-
    76 using Allocator = typename std::allocator_traits<A>::template rebind_alloc<Element>;
    \n-
    77
    \n-\n-
    79
    \n-
    84 Hierarchy(const std::shared_ptr<MemberType> & first);
    \n-
    85
    \n-
    89 Hierarchy() : levels_(0)
    \n-
    90 {}
    \n-
    91
    \n-
    95 Hierarchy(const Hierarchy& other);
    \n-
    96
    \n-\n-
    102
    \n-\n-
    104
    \n-
    109 void addFiner(Arguments& args);
    \n-
    110
    \n-
    117 template<class C, class T1>
    \n-\n-
    119 : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
    \n-
    120 {
    \n-
    121 friend class LevelIterator<typename std::remove_const<C>::type,
    \n-
    122 typename std::remove_const<T1>::type >;
    \n-
    123 friend class LevelIterator<const typename std::remove_const<C>::type,
    \n-
    124 const typename std::remove_const<T1>::type >;
    \n-
    125
    \n-
    126 public:
    \n-\n-
    129 {}
    \n+
    68#if HAVE_MPI
    \n+
    82 template<class G, class T1, class T2>
    \n+\n+
    84 {
    \n+\n+
    86 typedef typename IndexSet::LocalIndex::Attribute Attribute;
    \n+
    87
    \n+
    88 IndexSet& indexSet = oocomm.indexSet();
    \n+\n+
    90
    \n+
    91 std::size_t sum=0, needed = graph.noVertices()-indexSet.size();
    \n+
    92 std::vector<std::size_t> neededall(oocomm.communicator().size(), 0);
    \n+
    93
    \n+
    94 MPI_Allgather(&needed, 1, MPITraits<std::size_t>::getType() , &(neededall[0]), 1, MPITraits<std::size_t>::getType(), oocomm.communicator());
    \n+
    95 for(int i=0; i<oocomm.communicator().size(); ++i)
    \n+
    96 sum=sum+neededall[i]; // MAke this for generic
    \n+
    97
    \n+
    98 if(sum==0)
    \n+
    99 // Nothing to do
    \n+
    100 return;
    \n+
    101
    \n+
    102 //Compute Maximum Global Index
    \n+
    103 T1 maxgi=0;
    \n+
    104 auto end = indexSet.end();
    \n+
    105 for(auto it = indexSet.begin(); it != end; ++it)
    \n+
    106 maxgi=std::max(maxgi,it->global());
    \n+
    107
    \n+
    108 //Process p creates global indices consecutively
    \n+
    109 //starting atmaxgi+\\sum_{i=1}^p neededall[i]
    \n+
    110 // All created indices are owned by the process
    \n+
    111 maxgi=oocomm.communicator().max(maxgi);
    \n+
    112 ++maxgi; //Sart with the next free index.
    \n+
    113
    \n+
    114 for(int i=0; i<oocomm.communicator().rank(); ++i)
    \n+
    115 maxgi=maxgi+neededall[i]; // TODO: make this more generic
    \n+
    116
    \n+
    117 // Store the global index information for repairing the remote index information
    \n+
    118 std::map<int,SLList<std::pair<T1,Attribute> > > globalIndices;
    \n+
    119 storeGlobalIndicesOfRemoteIndices(globalIndices, oocomm.remoteIndices());
    \n+
    120 indexSet.beginResize();
    \n+
    121
    \n+
    122 for(auto vertex = graph.begin(), vend=graph.end(); vertex != vend; ++vertex) {
    \n+
    123 const typename IndexSet::IndexPair* pair=lookup.pair(*vertex);
    \n+
    124 if(pair==0) {
    \n+
    125 // No index yet, add new one
    \n+
    126 indexSet.add(maxgi, typename IndexSet::LocalIndex(*vertex, OwnerOverlapCopyAttributeSet::owner, false));
    \n+
    127 ++maxgi;
    \n+
    128 }
    \n+
    129 }
    \n
    130
    \n-
    131 LevelIterator(std::shared_ptr<Element> element)
    \n-
    132 : element_(element)
    \n-
    133 {}
    \n+
    131 indexSet.endResize();
    \n+
    132
    \n+
    133 repairLocalIndexPointers(globalIndices, oocomm.remoteIndices(), indexSet);
    \n
    134
    \n-
    136 LevelIterator(const LevelIterator<typename std::remove_const<C>::type,
    \n-
    137 typename std::remove_const<T1>::type>& other)
    \n-
    138 : element_(other.element_)
    \n-
    139 {}
    \n-
    140
    \n-
    142 LevelIterator(const LevelIterator<const typename std::remove_const<C>::type,
    \n-
    143 const typename std::remove_const<T1>::type>& other)
    \n-
    144 : element_(other.element_)
    \n-
    145 {}
    \n-
    146
    \n-
    150 bool equals(const LevelIterator<typename std::remove_const<C>::type,
    \n-
    151 typename std::remove_const<T1>::type>& other) const
    \n-
    152 {
    \n-
    153 return element_ == other.element_;
    \n-
    154 }
    \n-
    155
    \n-
    159 bool equals(const LevelIterator<const typename std::remove_const<C>::type,
    \n-
    160 const typename std::remove_const<T1>::type>& other) const
    \n-
    161 {
    \n-
    162 return element_ == other.element_;
    \n-
    163 }
    \n-
    164
    \n-
    166 T1& dereference() const
    \n-
    167 {
    \n-
    168 return *(element_->element_);
    \n-
    169 }
    \n-
    170
    \n-\n-
    173 {
    \n-
    174 element_ = element_->coarser_.lock();
    \n-
    175 }
    \n-
    176
    \n-\n-
    179 {
    \n-
    180 element_ = element_->finer_;
    \n-
    181 }
    \n-
    182
    \n-
    187 bool isRedistributed() const
    \n-
    188 {
    \n-
    189 return (bool)element_->redistributed_;
    \n-
    190 }
    \n+
    135 oocomm.freeGlobalLookup();
    \n+
    136 oocomm.buildGlobalLookup();
    \n+
    137#ifdef DEBUG_REPART
    \n+
    138 std::cout<<"Holes are filled!"<<std::endl;
    \n+
    139 std::cout<<oocomm.communicator().rank()<<": "<<oocomm.indexSet()<<std::endl;
    \n+
    140#endif
    \n+
    141 }
    \n+
    142
    \n+
    143 namespace
    \n+
    144 {
    \n+
    145
    \n+
    146 class ParmetisDuneIndexMap
    \n+
    147 {
    \n+
    148 public:
    \n+
    149 template<class Graph, class OOComm>
    \n+
    150 ParmetisDuneIndexMap(const Graph& graph, const OOComm& com);
    \n+
    151 int toParmetis(int i) const
    \n+
    152 {
    \n+
    153 return duneToParmetis[i];
    \n+
    154 }
    \n+
    155 int toLocalParmetis(int i) const
    \n+
    156 {
    \n+
    157 return duneToParmetis[i]-base_;
    \n+
    158 }
    \n+
    159 int operator[](int i) const
    \n+
    160 {
    \n+
    161 return duneToParmetis[i];
    \n+
    162 }
    \n+
    163 int toDune(int i) const
    \n+
    164 {
    \n+
    165 return parmetisToDune[i];
    \n+
    166 }
    \n+
    167 std::vector<int>::size_type numOfOwnVtx() const
    \n+
    168 {
    \n+
    169 return parmetisToDune.size();
    \n+
    170 }
    \n+
    171 Metis::idx_t* vtxDist()
    \n+
    172 {
    \n+
    173 return &vtxDist_[0];
    \n+
    174 }
    \n+\n+
    176 private:
    \n+
    177 int base_;
    \n+
    178 std::vector<int> duneToParmetis;
    \n+
    179 std::vector<int> parmetisToDune;
    \n+
    180 // range of vertices for processor i: vtxdist[i] to vtxdist[i+1] (parmetis global)
    \n+
    181 std::vector<Metis::idx_t> vtxDist_;
    \n+
    182 };
    \n+
    183
    \n+
    184 template<class G, class OOComm>
    \n+
    185 ParmetisDuneIndexMap::ParmetisDuneIndexMap(const G& graph, const OOComm& oocomm)
    \n+
    186 : duneToParmetis(graph.noVertices(), -1), vtxDist_(oocomm.communicator().size()+1)
    \n+
    187 {
    \n+
    188 int npes=oocomm.communicator().size(), mype=oocomm.communicator().rank();
    \n+
    189
    \n+
    190 typedef typename OOComm::OwnerSet OwnerSet;
    \n
    191
    \n-\n-
    197 {
    \n-
    198 assert(element_->redistributed_);
    \n-
    199 return *element_->redistributed_;
    \n-
    200 }
    \n-
    201 void addRedistributed(std::shared_ptr<T1> t)
    \n-
    202 {
    \n-
    203 element_->redistributed_ = t;
    \n-
    204 }
    \n-
    205
    \n-\n-
    207 {
    \n-
    208 element_->redistributed_ = nullptr;
    \n+
    192 int numOfOwnVtx=0;
    \n+
    193 auto end = oocomm.indexSet().end();
    \n+
    194 for(auto index = oocomm.indexSet().begin(); index != end; ++index) {
    \n+
    195 if (OwnerSet::contains(index->local().attribute())) {
    \n+
    196 numOfOwnVtx++;
    \n+
    197 }
    \n+
    198 }
    \n+
    199 parmetisToDune.resize(numOfOwnVtx);
    \n+
    200 std::vector<int> globalNumOfVtx(npes);
    \n+
    201 // make this number available to all processes
    \n+
    202 MPI_Allgather(&numOfOwnVtx, 1, MPI_INT, &(globalNumOfVtx[0]), 1, MPI_INT, oocomm.communicator());
    \n+
    203
    \n+
    204 int base=0;
    \n+
    205 vtxDist_[0] = 0;
    \n+
    206 for(int i=0; i<npes; i++) {
    \n+
    207 if (i<mype) {
    \n+
    208 base += globalNumOfVtx[i];
    \n
    209 }
    \n-
    210
    \n-
    211 private:
    \n-
    212 std::shared_ptr<Element> element_;
    \n-
    213 };
    \n+
    210 vtxDist_[i+1] = vtxDist_[i] + globalNumOfVtx[i];
    \n+
    211 }
    \n+
    212 globalOwnerVertices=vtxDist_[npes];
    \n+
    213 base_=base;
    \n
    214
    \n-\n-
    217
    \n-\n-
    220
    \n-\n-
    226
    \n-\n-
    232
    \n-
    233
    \n-\n-
    239
    \n-\n-
    245
    \n-
    250 std::size_t levels() const;
    \n-
    251
    \n-
    252 private:
    \n-
    258 std::shared_ptr<MemberType> originalFinest_;
    \n-
    260 std::shared_ptr<Element> finest_;
    \n-
    262 std::shared_ptr<Element> coarsest_;
    \n-
    264 Allocator allocator_;
    \n-
    266 int levels_;
    \n-
    267 };
    \n-
    268
    \n-
    269 template<class T, class A>
    \n-
    270 Hierarchy<T,A>::Hierarchy(const std::shared_ptr<MemberType> & first)
    \n-
    271 : originalFinest_(first)
    \n-
    272 {
    \n-
    273 finest_ = std::allocate_shared<Element>(allocator_);
    \n-
    274 finest_->element_ = originalFinest_;
    \n-
    275 coarsest_ = finest_;
    \n-
    276 levels_ = 1;
    \n-
    277 }
    \n-
    278
    \n-
    280 //TODO: do we actually want to support this? This might be very expensive?!
    \n-
    281 template<class T, class A>
    \n-\n-
    283 : allocator_(other.allocator_),
    \n-
    284 levels_(other.levels_)
    \n+
    215#ifdef DEBUG_REPART
    \n+
    216 std::cout << oocomm.communicator().rank()<<" vtxDist: ";
    \n+
    217 for(int i=0; i<= npes; ++i)
    \n+
    218 std::cout << vtxDist_[i]<<" ";
    \n+
    219 std::cout<<std::endl;
    \n+
    220#endif
    \n+
    221
    \n+
    222 // Traverse the graph and assign a new consecutive number/index
    \n+
    223 // starting by "base" to all owner vertices.
    \n+
    224 // The new index is used as the ParMETIS global index and is
    \n+
    225 // stored in the vector "duneToParmetis"
    \n+
    226 auto vend = graph.end();
    \n+
    227 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {
    \n+
    228 const typename OOComm::ParallelIndexSet::IndexPair* index=oocomm.globalLookup().pair(*vertex);
    \n+
    229 assert(index);
    \n+
    230 if (OwnerSet::contains(index->local().attribute())) {
    \n+
    231 // assign and count the index
    \n+
    232 parmetisToDune[base-base_]=index->local();
    \n+
    233 duneToParmetis[index->local()] = base++;
    \n+
    234 }
    \n+
    235 }
    \n+
    236
    \n+
    237 // At this point, every process knows the ParMETIS global index
    \n+
    238 // of it's owner vertices. The next step is to get the
    \n+
    239 // ParMETIS global index of the overlap vertices from the
    \n+
    240 // associated processes. To do this, the Dune::Interface class
    \n+
    241 // is used.
    \n+
    242#ifdef DEBUG_REPART
    \n+
    243 std::cout <<oocomm.communicator().rank()<<": before ";
    \n+
    244 for(std::size_t i=0; i<duneToParmetis.size(); ++i)
    \n+
    245 std::cout<<duneToParmetis[i]<<" ";
    \n+
    246 std::cout<<std::endl;
    \n+
    247#endif
    \n+
    248 oocomm.copyOwnerToAll(duneToParmetis,duneToParmetis);
    \n+
    249#ifdef DEBUG_REPART
    \n+
    250 std::cout <<oocomm.communicator().rank()<<": after ";
    \n+
    251 for(std::size_t i=0; i<duneToParmetis.size(); ++i)
    \n+
    252 std::cout<<duneToParmetis[i]<<" ";
    \n+
    253 std::cout<<std::endl;
    \n+
    254#endif
    \n+
    255 }
    \n+
    256 }
    \n+
    257
    \n+\n+
    259 : public Interface
    \n+
    260 {
    \n+
    261 void setCommunicator(MPI_Comm comm)
    \n+
    262 {
    \n+
    263 communicator_=comm;
    \n+
    264 }
    \n+
    265 template<class Flags,class IS>
    \n+
    266 void buildSendInterface(const std::vector<int>& toPart, const IS& idxset)
    \n+
    267 {
    \n+
    268 std::map<int,int> sizes;
    \n+
    269
    \n+
    270 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)
    \n+
    271 if(Flags::contains(i->local().attribute()))
    \n+
    272 ++sizes[toPart[i->local()]];
    \n+
    273
    \n+
    274 // Allocate the necessary space
    \n+
    275 for(auto i=sizes.begin(), end=sizes.end(); i!=end; ++i)
    \n+
    276 interfaces()[i->first].first.reserve(i->second);
    \n+
    277
    \n+
    278 //Insert the interface information
    \n+
    279 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)
    \n+
    280 if(Flags::contains(i->local().attribute()))
    \n+
    281 interfaces()[toPart[i->local()]].first.add(i->local());
    \n+
    282 }
    \n+
    283
    \n+
    284 void reserveSpaceForReceiveInterface(int proc, int size)
    \n
    285 {
    \n-
    286 if(!other.finest_)
    \n-
    287 {
    \n-
    288 finest_=coarsest_=nullptr;
    \n-
    289 return;
    \n-
    290 }
    \n-
    291 finest_ = std::allocate_shared<Element>(allocator_);
    \n-
    292 std::shared_ptr<Element> finer_;
    \n-
    293 std::shared_ptr<Element> current_ = finest_;
    \n-
    294 std::weak_ptr<Element> otherWeak_ = other.finest_;
    \n-
    295
    \n-
    296 while(! otherWeak_.expired())
    \n-
    297 {
    \n-
    298 // create shared_ptr from weak_ptr, we just checked that this is safe
    \n-
    299 std::shared_ptr<Element> otherCurrent_ = std::shared_ptr<Element>(otherWeak_);
    \n-
    300 // clone current level
    \n-
    301 //TODO: should we use the allocator?
    \n-
    302 current_->element_ =
    \n-
    303 std::make_shared<MemberType>(*(otherCurrent_->element_));
    \n-
    304 current_->finer_=finer_;
    \n-
    305 if(otherCurrent_->redistributed_)
    \n-
    306 current_->redistributed_ =
    \n-
    307 std::make_shared<MemberType>(*(otherCurrent_->redistributed_));
    \n-
    308 finer_=current_;
    \n-
    309 if(not otherCurrent_->coarser_.expired())
    \n-
    310 {
    \n-
    311 auto c = std::allocate_shared<Element>(allocator_);
    \n-
    312 current_->coarser_ = c;
    \n-
    313 current_ = c;
    \n-
    314 }
    \n-
    315 // go to coarser level
    \n-
    316 otherWeak_ = otherCurrent_->coarser_;
    \n-
    317 }
    \n-
    318 coarsest_=current_;
    \n-
    319 }
    \n-
    320
    \n-
    321 template<class T, class A>
    \n-
    322 std::size_t Hierarchy<T,A>::levels() const
    \n-
    323 {
    \n-
    324 return levels_;
    \n-
    325 }
    \n-
    326
    \n-
    327 template<class T, class A>
    \n-\n-
    329 {
    \n-
    330 coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
    \n-
    331 }
    \n-
    332
    \n-
    333 template<class T, class A>
    \n-\n-
    335 {
    \n-
    336 if(!coarsest_) {
    \n-
    337 // we have no levels at all...
    \n-
    338 assert(!finest_);
    \n-
    339 // allocate into the shared_ptr
    \n-
    340 originalFinest_ = ConstructionTraits<MemberType>::construct(args);
    \n-
    341 coarsest_ = std::allocate_shared<Element>(allocator_);
    \n-
    342 coarsest_->element_ = originalFinest_;
    \n-
    343 finest_ = coarsest_;
    \n-
    344 }else{
    \n-
    345 auto old_coarsest = coarsest_;
    \n-
    346 coarsest_ = std::allocate_shared<Element>(allocator_);
    \n-
    347 coarsest_->finer_ = old_coarsest;
    \n-
    348 coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
    \n-
    349 old_coarsest->coarser_ = coarsest_;
    \n-
    350 }
    \n-
    351 ++levels_;
    \n-
    352 }
    \n-
    353
    \n-
    354
    \n-
    355 template<class T, class A>
    \n-\n-
    357 {
    \n-
    358 //TODO: wouldn't it be better to do this in the constructor?'
    \n-
    359 if(!finest_) {
    \n-
    360 // we have no levels at all...
    \n-
    361 assert(!coarsest_);
    \n-
    362 // allocate into the shared_ptr
    \n-
    363 originalFinest_ = ConstructionTraits<MemberType>::construct(args);
    \n-
    364 finest_ = std::allocate_shared<Element>(allocator_);
    \n-
    365 finest_->element = originalFinest_;
    \n-
    366 coarsest_ = finest_;
    \n-
    367 }else{
    \n-
    368 finest_->finer_ = std::allocate_shared<Element>(allocator_);
    \n-
    369 finest_->finer_->coarser_ = finest_;
    \n-
    370 finest_ = finest_->finer_;
    \n-
    371 finest_->element = ConstructionTraits<T>::construct(args);
    \n-
    372 }
    \n-
    373 ++levels_;
    \n-
    374 }
    \n-
    375
    \n-
    376 template<class T, class A>
    \n-\n-
    378 {
    \n-
    379 return Iterator(finest_);
    \n-
    380 }
    \n-
    381
    \n-
    382 template<class T, class A>
    \n-\n-
    384 {
    \n-
    385 return Iterator(coarsest_);
    \n-
    386 }
    \n-
    387
    \n-
    388 template<class T, class A>
    \n-\n-
    390 {
    \n-
    391 return ConstIterator(finest_);
    \n-
    392 }
    \n-
    393
    \n-
    394 template<class T, class A>
    \n-\n-
    396 {
    \n-
    397 return ConstIterator(coarsest_);
    \n-
    398 }
    \n-
    400 } // namespace Amg
    \n-
    401} // namespace Dune
    \n+
    286 interfaces()[proc].second.reserve(size);
    \n+
    287 }
    \n+
    288 void addReceiveIndex(int proc, std::size_t idx)
    \n+
    289 {
    \n+
    290 interfaces()[proc].second.add(idx);
    \n+
    291 }
    \n+
    292 template<typename TG>
    \n+
    293 void buildReceiveInterface(std::vector<std::pair<TG,int> >& indices)
    \n+
    294 {
    \n+
    295 std::size_t i=0;
    \n+
    296 for(auto idx=indices.begin(); idx!= indices.end(); ++idx) {
    \n+
    297 interfaces()[idx->second].second.add(i++);
    \n+
    298 }
    \n+
    299 }
    \n+
    300
    \n+\n+
    302 {}
    \n+
    303
    \n+
    304 };
    \n+
    305
    \n+
    306 namespace
    \n+
    307 {
    \n+
    317 template<class GI>
    \n+
    318 void createSendBuf(std::vector<GI>& ownerVec, std::set<GI>& overlapVec, std::set<int>& neighbors, char *sendBuf, int buffersize, MPI_Comm comm) {
    \n+
    319 // Pack owner vertices
    \n+
    320 std::size_t s=ownerVec.size();
    \n+
    321 int pos=0;
    \n+
    322 if(s==0)
    \n+
    323 ownerVec.resize(1); // otherwise would read beyond the memory bound
    \n+
    324 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n+
    325 MPI_Pack(&(ownerVec[0]), s, MPITraits<GI>::getType(), sendBuf, buffersize, &pos, comm);
    \n+
    326 s = overlapVec.size();
    \n+
    327 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n+
    328 for(auto i=overlapVec.begin(), end= overlapVec.end(); i != end; ++i)
    \n+
    329 MPI_Pack(const_cast<GI*>(&(*i)), 1, MPITraits<GI>::getType(), sendBuf, buffersize, &pos, comm);
    \n+
    330
    \n+
    331 s=neighbors.size();
    \n+
    332 MPI_Pack(&s, 1, MPITraits<std::size_t>::getType(), sendBuf, buffersize, &pos, comm);
    \n+
    333
    \n+
    334 for(auto i=neighbors.begin(), end= neighbors.end(); i != end; ++i)
    \n+
    335 MPI_Pack(const_cast<int*>(&(*i)), 1, MPI_INT, sendBuf, buffersize, &pos, comm);
    \n+
    336 }
    \n+
    345 template<class GI>
    \n+
    346 void saveRecvBuf(char *recvBuf, int bufferSize, std::vector<std::pair<GI,int> >& ownerVec,
    \n+
    347 std::set<GI>& overlapVec, std::set<int>& neighbors, RedistributeInterface& inf, int from, MPI_Comm comm) {
    \n+
    348 std::size_t size;
    \n+
    349 int pos=0;
    \n+
    350 // unpack owner vertices
    \n+
    351 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n+
    352 inf.reserveSpaceForReceiveInterface(from, size);
    \n+
    353 ownerVec.reserve(ownerVec.size()+size);
    \n+
    354 for(; size!=0; --size) {
    \n+
    355 GI gi;
    \n+
    356 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits<GI>::getType(), comm);
    \n+
    357 ownerVec.push_back(std::make_pair(gi,from));
    \n+
    358 }
    \n+
    359 // unpack overlap vertices
    \n+
    360 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n+
    361 typename std::set<GI>::iterator ipos = overlapVec.begin();
    \n+
    362 Dune::dverb << "unpacking "<<size<<" overlap"<<std::endl;
    \n+
    363 for(; size!=0; --size) {
    \n+
    364 GI gi;
    \n+
    365 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits<GI>::getType(), comm);
    \n+
    366 ipos=overlapVec.insert(ipos, gi);
    \n+
    367 }
    \n+
    368 //unpack neighbors
    \n+
    369 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits<std::size_t>::getType(), comm);
    \n+
    370 Dune::dverb << "unpacking "<<size<<" neighbors"<<std::endl;
    \n+
    371 typename std::set<int>::iterator npos = neighbors.begin();
    \n+
    372 for(; size!=0; --size) {
    \n+
    373 int n;
    \n+
    374 MPI_Unpack(recvBuf, bufferSize, &pos, &n, 1, MPI_INT, comm);
    \n+
    375 npos=neighbors.insert(npos, n);
    \n+
    376 }
    \n+
    377 }
    \n+
    378
    \n+
    392 template<typename T>
    \n+
    393 void getDomain(const MPI_Comm& comm, T *part, int numOfOwnVtx, int nparts, int *myDomain, std::vector<int> &domainMapping) {
    \n+
    394 int npes, mype;
    \n+
    395 MPI_Comm_size(comm, &npes);
    \n+
    396 MPI_Comm_rank(comm, &mype);
    \n+
    397 MPI_Status status;
    \n+
    398
    \n+
    399 *myDomain = -1;
    \n+
    400 int i=0;
    \n+
    401 int j=0;
    \n
    402
    \n-
    403#endif
    \n-
    Helper classes for the construction of classes without empty constructor.
    \n-
    Hierarchy(const Hierarchy &other)
    Copy constructor (deep copy!).
    Definition: hierarchy.hh:282
    \n-
    void addRedistributedOnCoarsest(Arguments &args)
    Definition: hierarchy.hh:328
    \n-
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: hierarchy.hh:322
    \n-
    ConstIterator coarsest() const
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:395
    \n-
    void addCoarser(Arguments &args)
    Add an element on a coarser level.
    Definition: hierarchy.hh:334
    \n-
    void addFiner(Arguments &args)
    Add an element on a finer level.
    Definition: hierarchy.hh:356
    \n-
    Hierarchy(const std::shared_ptr< MemberType > &first)
    Construct a new hierarchy.
    Definition: hierarchy.hh:270
    \n-
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n-
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n-
    Iterator coarsest()
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:383
    \n-
    ConstIterator finest() const
    Get an iterator positioned at the finest level.
    Definition: hierarchy.hh:389
    \n-
    Iterator finest()
    Get an iterator positioned at the finest level.
    Definition: hierarchy.hh:377
    \n-
    STL namespace.
    \n+
    403 std::vector<int> domain(nparts, 0);
    \n+
    404 std::vector<int> assigned(npes, 0);
    \n+
    405 // init domain Mapping
    \n+
    406 domainMapping.assign(domainMapping.size(), -1);
    \n+
    407
    \n+
    408 // count the occurrence of domains
    \n+
    409 for (i=0; i<numOfOwnVtx; i++) {
    \n+
    410 domain[part[i]]++;
    \n+
    411 }
    \n+
    412
    \n+
    413 std::vector<int> domainMatrix(npes * nparts, -1);
    \n+
    414
    \n+
    415 // init buffer with the own domain
    \n+
    416 int *buf = new int[nparts];
    \n+
    417 for (i=0; i<nparts; i++) {
    \n+
    418 buf[i] = domain[i];
    \n+
    419 domainMatrix[mype*nparts+i] = domain[i];
    \n+
    420 }
    \n+
    421 int pe=0;
    \n+
    422 int src = (mype-1+npes)%npes;
    \n+
    423 int dest = (mype+1)%npes;
    \n+
    424 // ring communication, we need n-1 communications for n processors
    \n+
    425 for (i=0; i<npes-1; i++) {
    \n+
    426 MPI_Sendrecv_replace(buf, nparts, MPI_INT, dest, 0, src, 0, comm, &status);
    \n+
    427 // pe is the process of the actual received buffer
    \n+
    428 pe = ((mype-1-i)+npes)%npes;
    \n+
    429 for(j=0; j<nparts; j++) {
    \n+
    430 // save the values to the domain matrix
    \n+
    431 domainMatrix[pe*nparts+j] = buf[j];
    \n+
    432 }
    \n+
    433 }
    \n+
    434 delete[] buf;
    \n+
    435
    \n+
    436 // Start the domain calculation.
    \n+
    437 // The process which contains the maximum number of vertices of a
    \n+
    438 // particular domain is selected to choose it's favorate domain
    \n+
    439 int maxOccurance = 0;
    \n+
    440 pe = -1;
    \n+
    441 std::set<std::size_t> unassigned;
    \n+
    442
    \n+
    443 for(i=0; i<nparts; i++) {
    \n+
    444 for(j=0; j<npes; j++) {
    \n+
    445 // process has no domain assigned
    \n+
    446 if (assigned[j]==0) {
    \n+
    447 if (maxOccurance < domainMatrix[j*nparts+i]) {
    \n+
    448 maxOccurance = domainMatrix[j*nparts+i];
    \n+
    449 pe = j;
    \n+
    450 }
    \n+
    451 }
    \n+
    452
    \n+
    453 }
    \n+
    454 if (pe!=-1) {
    \n+
    455 // process got a domain, ...
    \n+
    456 domainMapping[i] = pe;
    \n+
    457 // ...mark as assigned
    \n+
    458 assigned[pe] = 1;
    \n+
    459 if (pe==mype) {
    \n+
    460 *myDomain = i;
    \n+
    461 }
    \n+
    462 pe = -1;
    \n+
    463 }
    \n+
    464 else
    \n+
    465 {
    \n+
    466 unassigned.insert(i);
    \n+
    467 }
    \n+
    468 maxOccurance = 0;
    \n+
    469 }
    \n+
    470
    \n+
    471 typename std::vector<int>::iterator next_free = assigned.begin();
    \n+
    472
    \n+
    473 for(auto udomain = unassigned.begin(),
    \n+
    474 end = unassigned.end(); udomain != end; ++udomain)
    \n+
    475 {
    \n+
    476 next_free = std::find_if(next_free, assigned.end(), std::bind(std::less<int>(), std::placeholders::_1, 1));
    \n+
    477 assert(next_free != assigned.end());
    \n+
    478 domainMapping[*udomain] = next_free-assigned.begin();
    \n+
    479 *next_free = 1;
    \n+
    480 }
    \n+
    481 }
    \n+
    482
    \n+
    483 struct SortFirst
    \n+
    484 {
    \n+
    485 template<class T>
    \n+
    486 bool operator()(const T& t1, const T& t2) const
    \n+
    487 {
    \n+
    488 return t1<t2;
    \n+
    489 }
    \n+
    490 };
    \n+
    491
    \n+
    492
    \n+
    503 template<class GI>
    \n+
    504 void mergeVec(std::vector<std::pair<GI, int> >& ownerVec, std::set<GI>& overlapSet) {
    \n+
    505
    \n+
    506#ifdef DEBUG_REPART
    \n+
    507 // Safety check for duplicates.
    \n+
    508 if(ownerVec.size()>0)
    \n+
    509 {
    \n+
    510 auto old=ownerVec.begin();
    \n+
    511 for(auto i=old+1, end=ownerVec.end(); i != end; old=i++)
    \n+
    512 {
    \n+
    513 if(i->first==old->first)
    \n+
    514 {
    \n+
    515 std::cerr<<"Value at indes"<<old-ownerVec.begin()<<" is the same as at index "
    \n+
    516 <<i-ownerVec.begin()<<" ["<<old->first<<","<<old->second<<"]==["
    \n+
    517 <<i->first<<","<<i->second<<"]"<<std::endl;
    \n+
    518 throw "Huch!";
    \n+
    519 }
    \n+
    520 }
    \n+
    521 }
    \n+
    522
    \n+
    523#endif
    \n+
    524
    \n+
    525 auto v=ownerVec.begin(), vend=ownerVec.end();
    \n+
    526 for(auto s=overlapSet.begin(), send=overlapSet.end(); s!=send;)
    \n+
    527 {
    \n+
    528 while(v!=vend && v->first<*s) ++v;
    \n+
    529 if(v!=vend && v->first==*s) {
    \n+
    530 // Move to the next element before erasing
    \n+
    531 // thus s stays valid!
    \n+
    532 auto tmp=s;
    \n+
    533 ++s;
    \n+
    534 overlapSet.erase(tmp);
    \n+
    535 }else
    \n+
    536 ++s;
    \n+
    537 }
    \n+
    538 }
    \n+
    539
    \n+
    540
    \n+
    554 template<class OwnerSet, class Graph, class IS, class GI>
    \n+
    555 void getNeighbor(const Graph& g, std::vector<int>& part,
    \n+
    556 typename Graph::VertexDescriptor vtx, const IS& indexSet,
    \n+
    557 int toPe, std::set<GI>& neighbor, std::set<int>& neighborProcs) {
    \n+
    558 for(auto edge=g.beginEdges(vtx), end=g.endEdges(vtx); edge!=end; ++edge)
    \n+
    559 {
    \n+
    560 const typename IS::IndexPair* pindex = indexSet.pair(edge.target());
    \n+
    561 assert(pindex);
    \n+
    562 if(part[pindex->local()]!=toPe || !OwnerSet::contains(pindex->local().attribute()))
    \n+
    563 {
    \n+
    564 // is sent to another process and therefore becomes overlap
    \n+
    565 neighbor.insert(pindex->global());
    \n+
    566 neighborProcs.insert(part[pindex->local()]);
    \n+
    567 }
    \n+
    568 }
    \n+
    569 }
    \n+
    570
    \n+
    571 template<class T, class I>
    \n+
    572 void my_push_back(std::vector<T>& ownerVec, const I& index, [[maybe_unused]] int proc)
    \n+
    573 {
    \n+
    574 ownerVec.push_back(index);
    \n+
    575 }
    \n+
    576
    \n+
    577 template<class T, class I>
    \n+
    578 void my_push_back(std::vector<std::pair<T,int> >& ownerVec, const I& index, int proc)
    \n+
    579 {
    \n+
    580 ownerVec.push_back(std::make_pair(index,proc));
    \n+
    581 }
    \n+
    582 template<class T>
    \n+
    583 void reserve(std::vector<T>&, RedistributeInterface&, int)
    \n+
    584 {}
    \n+
    585 template<class T>
    \n+
    586 void reserve(std::vector<std::pair<T,int> >& ownerVec, RedistributeInterface& redist, int proc)
    \n+
    587 {
    \n+
    588 redist.reserveSpaceForReceiveInterface(proc, ownerVec.size());
    \n+
    589 }
    \n+
    590
    \n+
    591
    \n+
    609 template<class OwnerSet, class G, class IS, class T, class GI>
    \n+
    610 void getOwnerOverlapVec(const G& graph, std::vector<int>& part, IS& indexSet,
    \n+
    611 [[maybe_unused]] int myPe, int toPe, std::vector<T>& ownerVec, std::set<GI>& overlapSet,
    \n+
    612 RedistributeInterface& redist, std::set<int>& neighborProcs) {
    \n+
    613 for(auto index = indexSet.begin(); index != indexSet.end(); ++index) {
    \n+
    614 // Only Process owner vertices, the others are not in the parmetis graph.
    \n+
    615 if(OwnerSet::contains(index->local().attribute()))
    \n+
    616 {
    \n+
    617 if(part[index->local()]==toPe)
    \n+
    618 {
    \n+
    619 getNeighbor<OwnerSet>(graph, part, index->local(), indexSet,
    \n+
    620 toPe, overlapSet, neighborProcs);
    \n+
    621 my_push_back(ownerVec, index->global(), toPe);
    \n+
    622 }
    \n+
    623 }
    \n+
    624 }
    \n+
    625 reserve(ownerVec, redist, toPe);
    \n+
    626
    \n+
    627 }
    \n+
    628
    \n+
    629
    \n+
    636 template<class F, class IS>
    \n+
    637 inline bool isOwner(IS& indexSet, int index) {
    \n+
    638
    \n+
    639 const typename IS::IndexPair* pindex=indexSet.pair(index);
    \n+
    640
    \n+
    641 assert(pindex);
    \n+
    642 return F::contains(pindex->local().attribute());
    \n+
    643 }
    \n+
    644
    \n+
    645
    \n+
    646 class BaseEdgeFunctor
    \n+
    647 {
    \n+
    648 public:
    \n+
    649 BaseEdgeFunctor(Metis::idx_t* adj,const ParmetisDuneIndexMap& data)
    \n+
    650 : i_(), adj_(adj), data_(data)
    \n+
    651 {}
    \n+
    652
    \n+
    653 template<class T>
    \n+
    654 void operator()(const T& edge)
    \n+
    655 {
    \n+
    656 // Get the egde weight
    \n+
    657 // const Weight& weight=edge.weight();
    \n+
    658 adj_[i_] = data_.toParmetis(edge.target());
    \n+
    659 i_++;
    \n+
    660 }
    \n+
    661 std::size_t index()
    \n+
    662 {
    \n+
    663 return i_;
    \n+
    664 }
    \n+
    665
    \n+
    666 private:
    \n+
    667 std::size_t i_;
    \n+
    668 Metis::idx_t* adj_;
    \n+
    669 const ParmetisDuneIndexMap& data_;
    \n+
    670 };
    \n+
    671
    \n+
    672 template<typename G>
    \n+
    673 struct EdgeFunctor
    \n+
    674 : public BaseEdgeFunctor
    \n+
    675 {
    \n+
    676 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::size_t)
    \n+
    677 : BaseEdgeFunctor(adj, data)
    \n+
    678 {}
    \n+
    679
    \n+
    680 Metis::idx_t* getWeights()
    \n+
    681 {
    \n+
    682 return NULL;
    \n+
    683 }
    \n+
    684 void free(){}
    \n+
    685 };
    \n+
    686
    \n+
    687 template<class G, class V, class E, class VM, class EM>
    \n+
    688 class EdgeFunctor<Dune::Amg::PropertiesGraph<G,V,E,VM,EM> >
    \n+
    689 : public BaseEdgeFunctor
    \n+
    690 {
    \n+
    691 public:
    \n+
    692 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::size_t s)
    \n+
    693 : BaseEdgeFunctor(adj, data)
    \n+
    694 {
    \n+
    695 weight_=new Metis::idx_t[s];
    \n+
    696 }
    \n+
    697
    \n+
    698 template<class T>
    \n+
    699 void operator()(const T& edge)
    \n+
    700 {
    \n+
    701 weight_[index()]=edge.properties().depends() ? 3 : 1;
    \n+
    702 BaseEdgeFunctor::operator()(edge);
    \n+
    703 }
    \n+
    704 Metis::idx_t* getWeights()
    \n+
    705 {
    \n+
    706 return weight_;
    \n+
    707 }
    \n+
    708 void free(){
    \n+
    709 if(weight_!=0) {
    \n+
    710 delete weight_;
    \n+
    711 weight_=0;
    \n+
    712 }
    \n+
    713 }
    \n+
    714 private:
    \n+
    715 Metis::idx_t* weight_;
    \n+
    716 };
    \n+
    717
    \n+
    718
    \n+
    719
    \n+
    733 template<class F, class G, class IS, class EW>
    \n+
    734 void getAdjArrays(G& graph, IS& indexSet, Metis::idx_t *xadj,
    \n+
    735 EW& ew)
    \n+
    736 {
    \n+
    737 int j=0;
    \n+
    738 auto vend = graph.end();
    \n+
    739
    \n+
    740 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {
    \n+
    741 if (isOwner<F>(indexSet,*vertex)) {
    \n+
    742 // The type of const edge iterator.
    \n+
    743 auto eend = vertex.end();
    \n+
    744 xadj[j] = ew.index();
    \n+
    745 j++;
    \n+
    746 for(auto edge = vertex.begin(); edge != eend; ++edge) {
    \n+
    747 ew(edge);
    \n+
    748 }
    \n+
    749 }
    \n+
    750 }
    \n+
    751 xadj[j] = ew.index();
    \n+
    752 }
    \n+
    753 } // end anonymous namespace
    \n+
    754
    \n+
    755 template<class G, class T1, class T2>
    \n+
    756 bool buildCommunication(const G& graph, std::vector<int>& realparts,
    \n+\n+
    758 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n+
    759 RedistributeInterface& redistInf,
    \n+
    760 bool verbose=false);
    \n+
    761#if HAVE_PARMETIS
    \n+
    762#ifndef METIS_VER_MAJOR
    \n+
    763 extern "C"
    \n+
    764 {
    \n+
    765 // backwards compatibility to parmetis < 4.0.0
    \n+
    766 void METIS_PartGraphKway(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t *adjncy, Metis::idx_t *vwgt,
    \n+
    767 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,
    \n+
    768 int *options, int *edgecut, Metis::idx_t *part);
    \n+
    769
    \n+
    770 void METIS_PartGraphRecursive(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t *adjncy, Metis::idx_t *vwgt,
    \n+
    771 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,
    \n+
    772 int *options, int *edgecut, Metis::idx_t *part);
    \n+
    773 }
    \n+
    774#endif
    \n+
    775#endif // HAVE_PARMETIS
    \n+
    776
    \n+
    777 template<class S, class T>
    \n+
    778 inline void print_carray(S& os, T* array, std::size_t l)
    \n+
    779 {
    \n+
    780 for(T *cur=array, *end=array+l; cur!=end; ++cur)
    \n+
    781 os<<*cur<<" ";
    \n+
    782 }
    \n+
    783
    \n+
    784 template<class S, class T>
    \n+
    785 inline bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T* xadj,
    \n+
    786 T* adjncy, bool checkSymmetry)
    \n+
    787 {
    \n+
    788 bool correct=true;
    \n+
    789
    \n+
    790 using std::signbit;
    \n+
    791 for(Metis::idx_t vtx=0; vtx<(Metis::idx_t)noVtx; ++vtx) {
    \n+
    792 if(static_cast<S>(xadj[vtx])>noEdges || signbit(xadj[vtx])) {
    \n+
    793 std::cerr <<"Check graph: xadj["<<vtx<<"]="<<xadj[vtx]<<" (>"
    \n+
    794 <<noEdges<<") out of range!"<<std::endl;
    \n+
    795 correct=false;
    \n+
    796 }
    \n+
    797 if(static_cast<S>(xadj[vtx+1])>noEdges || signbit(xadj[vtx+1])) {
    \n+
    798 std::cerr <<"Check graph: xadj["<<vtx+1<<"]="<<xadj[vtx+1]<<" (>"
    \n+
    799 <<noEdges<<") out of range!"<<std::endl;
    \n+
    800 correct=false;
    \n+
    801 }
    \n+
    802 // Check numbers in adjncy
    \n+
    803 for(Metis::idx_t i=xadj[vtx]; i< xadj[vtx+1]; ++i) {
    \n+
    804 if(signbit(adjncy[i]) || ((std::size_t)adjncy[i])>gnoVtx) {
    \n+
    805 std::cerr<<" Edge "<<adjncy[i]<<" out of range ["<<0<<","<<noVtx<<")"
    \n+
    806 <<std::endl;
    \n+
    807 correct=false;
    \n+
    808 }
    \n+
    809 }
    \n+
    810 if(checkSymmetry) {
    \n+
    811 for(Metis::idx_t i=xadj[vtx]; i< xadj[vtx+1]; ++i) {
    \n+
    812 Metis::idx_t target=adjncy[i];
    \n+
    813 // search for symmetric edge
    \n+
    814 int found=0;
    \n+
    815 for(Metis::idx_t j=xadj[target]; j< xadj[target+1]; ++j)
    \n+
    816 if(adjncy[j]==vtx)
    \n+
    817 found++;
    \n+
    818 if(found!=1) {
    \n+
    819 std::cerr<<"Edge ("<<target<<","<<vtx<<") "<<i<<" time"<<std::endl;
    \n+
    820 correct=false;
    \n+
    821 }
    \n+
    822 }
    \n+
    823 }
    \n+
    824 }
    \n+
    825 return correct;
    \n+
    826 }
    \n+
    827
    \n+
    828 template<class M, class T1, class T2>
    \n+\n+
    830 Metis::idx_t nparts,
    \n+
    831 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n+
    832 RedistributeInterface& redistInf,
    \n+
    833 bool verbose=false)
    \n+
    834 {
    \n+
    835 if(verbose && oocomm.communicator().rank()==0)
    \n+
    836 std::cout<<"Repartitioning from "<<oocomm.communicator().size()
    \n+
    837 <<" to "<<nparts<<" parts"<<std::endl;
    \n+
    838 Timer time;
    \n+
    839 int rank = oocomm.communicator().rank();
    \n+
    840#if !HAVE_PARMETIS
    \n+
    841 int* part = new int[1];
    \n+
    842 part[0]=0;
    \n+
    843#else
    \n+
    844 Metis::idx_t* part = new Metis::idx_t[1]; // where all our data moves to
    \n+
    845
    \n+
    846 if(nparts>1) {
    \n+
    847
    \n+
    848 part[0]=rank;
    \n+
    849
    \n+
    850 { // sublock for automatic memory deletion
    \n+
    851
    \n+
    852 // Build the graph of the communication scheme and create an appropriate indexset.
    \n+
    853 // calculate the neighbour vertices
    \n+
    854 int noNeighbours = oocomm.remoteIndices().neighbours();
    \n+
    855
    \n+
    856 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n+
    857 ++n)
    \n+
    858 if(n->first==rank) {
    \n+
    859 //do not include ourselves.
    \n+
    860 --noNeighbours;
    \n+
    861 break;
    \n+
    862 }
    \n+
    863
    \n+
    864 // A parmetis graph representing the communication graph.
    \n+
    865 // The diagonal entries are the number of nodes on the process.
    \n+
    866 // The offdiagonal entries are the number of edges leading to other processes.
    \n+
    867
    \n+
    868 Metis::idx_t *xadj=new Metis::idx_t[2];
    \n+
    869 Metis::idx_t *vtxdist=new Metis::idx_t[oocomm.communicator().size()+1];
    \n+
    870 Metis::idx_t *adjncy=new Metis::idx_t[noNeighbours];
    \n+
    871#ifdef USE_WEIGHTS
    \n+
    872 Metis::idx_t *vwgt = 0;
    \n+
    873 Metis::idx_t *adjwgt = 0;
    \n+
    874#endif
    \n+
    875
    \n+
    876 // each process has exactly one vertex!
    \n+
    877 for(int i=0; i<oocomm.communicator().size(); ++i)
    \n+
    878 vtxdist[i]=i;
    \n+
    879 vtxdist[oocomm.communicator().size()]=oocomm.communicator().size();
    \n+
    880
    \n+
    881 xadj[0]=0;
    \n+
    882 xadj[1]=noNeighbours;
    \n+
    883
    \n+
    884 // count edges to other processor
    \n+
    885 // a vector mapping the index to the owner
    \n+
    886 // std::vector<int> owner(mat.N(), oocomm.communicator().rank());
    \n+
    887 // for(NeighbourIterator n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n+
    888 // ++n)
    \n+
    889 // {
    \n+
    890 // if(n->first!=oocomm.communicator().rank()){
    \n+
    891 // typedef typename RemoteIndices::RemoteIndexList RIList;
    \n+
    892 // const RIList& rlist = *(n->second.first);
    \n+
    893 // typedef typename RIList::const_iterator LIter;
    \n+
    894 // for(LIter entry=rlist.begin(); entry!=rlist.end(); ++entry){
    \n+
    895 // if(entry->attribute()==OwnerOverlapCopyAttributeSet::owner)
    \n+
    896 // owner[entry->localIndexPair().local()] = n->first;
    \n+
    897 // }
    \n+
    898 // }
    \n+
    899 // }
    \n+
    900
    \n+
    901 // std::map<int,Metis::idx_t> edgecount; // edges to other processors
    \n+
    902 // typedef typename M::ConstRowIterator RIter;
    \n+
    903 // typedef typename M::ConstColIterator CIter;
    \n+
    904
    \n+
    905 // // calculate edge count
    \n+
    906 // for(RIter row=mat.begin(), endr=mat.end(); row != endr; ++row)
    \n+
    907 // if(owner[row.index()]==OwnerOverlapCopyAttributeSet::owner)
    \n+
    908 // for(CIter entry= row->begin(), ende = row->end(); entry != ende; ++entry)
    \n+
    909 // ++edgecount[owner[entry.index()]];
    \n+
    910
    \n+
    911 // setup edge and weight pattern
    \n+
    912
    \n+
    913 Metis::idx_t* adjp=adjncy;
    \n+
    914
    \n+
    915#ifdef USE_WEIGHTS
    \n+
    916 vwgt = new Metis::idx_t[1];
    \n+
    917 vwgt[0]= mat.N(); // weight is numer of rows TODO: Should actually be the nonzeros.
    \n+
    918
    \n+
    919 adjwgt = new Metis::idx_t[noNeighbours];
    \n+
    920 Metis::idx_t* adjwp=adjwgt;
    \n+
    921#endif
    \n+
    922
    \n+
    923 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices().end();
    \n+
    924 ++n)
    \n+
    925 if(n->first != rank) {
    \n+
    926 *adjp=n->first;
    \n+
    927 ++adjp;
    \n+
    928#ifdef USE_WEIGHTS
    \n+
    929 *adjwp=1; //edgecount[n->first];
    \n+
    930 ++adjwp;
    \n+
    931#endif
    \n+
    932 }
    \n+
    933 assert(isValidGraph(vtxdist[rank+1]-vtxdist[rank],
    \n+
    934 vtxdist[oocomm.communicator().size()],
    \n+
    935 noNeighbours, xadj, adjncy, false));
    \n+
    936
    \n+
    937 [[maybe_unused]] Metis::idx_t wgtflag=0;
    \n+
    938 Metis::idx_t numflag=0;
    \n+
    939 Metis::idx_t edgecut;
    \n+
    940#ifdef USE_WEIGHTS
    \n+
    941 wgtflag=3;
    \n+
    942#endif
    \n+
    943 Metis::real_t *tpwgts = new Metis::real_t[nparts];
    \n+
    944 for(int i=0; i<nparts; ++i)
    \n+
    945 tpwgts[i]=1.0/nparts;
    \n+
    946 MPI_Comm comm=oocomm.communicator();
    \n+
    947
    \n+
    948 Dune::dinfo<<rank<<" vtxdist: ";
    \n+
    949 print_carray(Dune::dinfo, vtxdist, oocomm.communicator().size()+1);
    \n+
    950 Dune::dinfo<<std::endl<<rank<<" xadj: ";
    \n+
    951 print_carray(Dune::dinfo, xadj, 2);
    \n+
    952 Dune::dinfo<<std::endl<<rank<<" adjncy: ";
    \n+
    953 print_carray(Dune::dinfo, adjncy, noNeighbours);
    \n+
    954
    \n+
    955#ifdef USE_WEIGHTS
    \n+
    956 Dune::dinfo<<std::endl<<rank<<" vwgt: ";
    \n+
    957 print_carray(Dune::dinfo, vwgt, 1);
    \n+
    958 Dune::dinfo<<std::endl<<rank<<" adwgt: ";
    \n+
    959 print_carray(Dune::dinfo, adjwgt, noNeighbours);
    \n+
    960#endif
    \n+
    961 Dune::dinfo<<std::endl;
    \n+
    962 oocomm.communicator().barrier();
    \n+
    963 if(verbose && oocomm.communicator().rank()==0)
    \n+
    964 std::cout<<"Creating comm graph took "<<time.elapsed()<<std::endl;
    \n+
    965 time.reset();
    \n+
    966
    \n+
    967#ifdef PARALLEL_PARTITION
    \n+
    968 Metis::real_t ubvec = 1.15;
    \n+
    969 int ncon=1;
    \n+
    970 int options[5] ={ 0,1,15,0,0};
    \n+
    971
    \n+
    972 //=======================================================
    \n+
    973 // ParMETIS_V3_PartKway
    \n+
    974 //=======================================================
    \n+
    975 ParMETIS_V3_PartKway(vtxdist, xadj, adjncy,
    \n+
    976 vwgt, adjwgt, &wgtflag,
    \n+
    977 &numflag, &ncon, &nparts, tpwgts, &ubvec, options, &edgecut, part,
    \n+
    978 &comm);
    \n+
    979 if(verbose && oocomm.communicator().rank()==0)
    \n+
    980 std::cout<<"ParMETIS took "<<time.elapsed()<<std::endl;
    \n+
    981 time.reset();
    \n+
    982#else
    \n+
    983 Timer time1;
    \n+
    984 std::size_t gnoedges=0;
    \n+
    985 int* noedges = 0;
    \n+
    986 noedges = new int[oocomm.communicator().size()];
    \n+
    987 Dune::dverb<<"noNeighbours: "<<noNeighbours<<std::endl;
    \n+
    988 // gather number of edges for each vertex.
    \n+
    989 MPI_Allgather(&noNeighbours,1,MPI_INT,noedges,1, MPI_INT,oocomm.communicator());
    \n+
    990
    \n+
    991 if(verbose && oocomm.communicator().rank()==0)
    \n+
    992 std::cout<<"Gathering noedges took "<<time1.elapsed()<<std::endl;
    \n+
    993 time1.reset();
    \n+
    994
    \n+
    995 Metis::idx_t noVertices = vtxdist[oocomm.communicator().size()];
    \n+
    996 Metis::idx_t *gxadj = 0;
    \n+
    997 Metis::idx_t *gvwgt = 0;
    \n+
    998 Metis::idx_t *gadjncy = 0;
    \n+
    999 Metis::idx_t *gadjwgt = 0;
    \n+
    1000 Metis::idx_t *gpart = 0;
    \n+
    1001 int* displ = 0;
    \n+
    1002 int* noxs = 0;
    \n+
    1003 int* xdispl = 0; // displacement for xadj
    \n+
    1004 int* novs = 0;
    \n+
    1005 int* vdispl=0; // real vertex displacement
    \n+
    1006#ifdef USE_WEIGHTS
    \n+
    1007 std::size_t localNoVtx=vtxdist[rank+1]-vtxdist[rank];
    \n+
    1008#endif
    \n+
    1009 std::size_t gxadjlen = vtxdist[oocomm.communicator().size()]-vtxdist[0]+oocomm.communicator().size();
    \n+
    1010
    \n+
    1011 {
    \n+
    1012 Dune::dinfo<<"noedges: ";
    \n+
    1013 print_carray(Dune::dinfo, noedges, oocomm.communicator().size());
    \n+
    1014 Dune::dinfo<<std::endl;
    \n+
    1015 displ = new int[oocomm.communicator().size()];
    \n+
    1016 xdispl = new int[oocomm.communicator().size()];
    \n+
    1017 noxs = new int[oocomm.communicator().size()];
    \n+
    1018 vdispl = new int[oocomm.communicator().size()];
    \n+
    1019 novs = new int[oocomm.communicator().size()];
    \n+
    1020
    \n+
    1021 for(int i=0; i < oocomm.communicator().size(); ++i) {
    \n+
    1022 noxs[i]=vtxdist[i+1]-vtxdist[i]+1;
    \n+
    1023 novs[i]=vtxdist[i+1]-vtxdist[i];
    \n+
    1024 }
    \n+
    1025
    \n+
    1026 Metis::idx_t *so= vtxdist;
    \n+
    1027 int offset = 0;
    \n+
    1028 for(int *xcurr = xdispl, *vcurr = vdispl, *end=vdispl+oocomm.communicator().size();
    \n+
    1029 vcurr!=end; ++vcurr, ++xcurr, ++so, ++offset) {
    \n+
    1030 *vcurr = *so;
    \n+
    1031 *xcurr = offset + *so;
    \n+
    1032 }
    \n+
    1033
    \n+
    1034 int *pdispl =displ;
    \n+
    1035 int cdispl = 0;
    \n+
    1036 *pdispl = 0;
    \n+
    1037 for(int *curr=noedges, *end=noedges+oocomm.communicator().size()-1;
    \n+
    1038 curr!=end; ++curr) {
    \n+
    1039 ++pdispl; // next displacement
    \n+
    1040 cdispl += *curr; // next value
    \n+
    1041 *pdispl = cdispl;
    \n+
    1042 }
    \n+
    1043 Dune::dinfo<<"displ: ";
    \n+
    1044 print_carray(Dune::dinfo, displ, oocomm.communicator().size());
    \n+
    1045 Dune::dinfo<<std::endl;
    \n+
    1046
    \n+
    1047 // calculate global number of edges
    \n+
    1048 // It is bigger than the actual one as we habe size-1 additional end entries
    \n+
    1049 for(int *curr=noedges, *end=noedges+oocomm.communicator().size();
    \n+
    1050 curr!=end; ++curr)
    \n+
    1051 gnoedges += *curr;
    \n+
    1052
    \n+
    1053 // alocate gobal graph
    \n+
    1054 Dune::dinfo<<"gxadjlen: "<<gxadjlen<<" noVertices: "<<noVertices
    \n+
    1055 <<" gnoedges: "<<gnoedges<<std::endl;
    \n+
    1056 gxadj = new Metis::idx_t[gxadjlen];
    \n+
    1057 gpart = new Metis::idx_t[noVertices];
    \n+
    1058#ifdef USE_WEIGHTS
    \n+
    1059 gvwgt = new Metis::idx_t[noVertices];
    \n+
    1060 gadjwgt = new Metis::idx_t[gnoedges];
    \n+
    1061#endif
    \n+
    1062 gadjncy = new Metis::idx_t[gnoedges];
    \n+
    1063 }
    \n+
    1064
    \n+
    1065 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1066 std::cout<<"Preparing global graph took "<<time1.elapsed()<<std::endl;
    \n+
    1067 time1.reset();
    \n+
    1068 // Communicate data
    \n+
    1069
    \n+
    1070 MPI_Allgatherv(xadj,2,MPITraits<Metis::idx_t>::getType(),
    \n+
    1071 gxadj,noxs,xdispl,MPITraits<Metis::idx_t>::getType(),
    \n+
    1072 comm);
    \n+
    1073 MPI_Allgatherv(adjncy,noNeighbours,MPITraits<Metis::idx_t>::getType(),
    \n+
    1074 gadjncy,noedges,displ,MPITraits<Metis::idx_t>::getType(),
    \n+
    1075 comm);
    \n+
    1076#ifdef USE_WEIGHTS
    \n+
    1077 MPI_Allgatherv(adjwgt,noNeighbours,MPITraits<Metis::idx_t>::getType(),
    \n+
    1078 gadjwgt,noedges,displ,MPITraits<Metis::idx_t>::getType(),
    \n+
    1079 comm);
    \n+
    1080 MPI_Allgatherv(vwgt,localNoVtx,MPITraits<Metis::idx_t>::getType(),
    \n+
    1081 gvwgt,novs,vdispl,MPITraits<Metis::idx_t>::getType(),
    \n+
    1082 comm);
    \n+
    1083#endif
    \n+
    1084 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1085 std::cout<<"Gathering global graph data took "<<time1.elapsed()<<std::endl;
    \n+
    1086 time1.reset();
    \n+
    1087
    \n+
    1088 {
    \n+
    1089 // create the real gxadj array
    \n+
    1090 // i.e. shift entries and add displacements.
    \n+
    1091
    \n+
    1092 print_carray(Dune::dinfo, gxadj, gxadjlen);
    \n+
    1093
    \n+
    1094 int offset = 0;
    \n+
    1095 Metis::idx_t increment = vtxdist[1];
    \n+
    1096 Metis::idx_t *start=gxadj+1;
    \n+
    1097 for(int i=1; i<oocomm.communicator().size(); ++i) {
    \n+
    1098 offset+=1;
    \n+
    1099 int lprev = vtxdist[i]-vtxdist[i-1];
    \n+
    1100 int l = vtxdist[i+1]-vtxdist[i];
    \n+
    1101 start+=lprev;
    \n+
    1102 assert((start+l+offset)-gxadj<=static_cast<Metis::idx_t>(gxadjlen));
    \n+
    1103 increment = *(start-1);
    \n+
    1104 std::transform(start+offset, start+l+offset, start, std::bind(std::plus<Metis::idx_t>(), std::placeholders::_1, increment));
    \n+
    1105 }
    \n+
    1106 Dune::dinfo<<std::endl<<"shifted xadj:";
    \n+
    1107 print_carray(Dune::dinfo, gxadj, noVertices+1);
    \n+
    1108 Dune::dinfo<<std::endl<<" gadjncy: ";
    \n+
    1109 print_carray(Dune::dinfo, gadjncy, gnoedges);
    \n+
    1110#ifdef USE_WEIGHTS
    \n+
    1111 Dune::dinfo<<std::endl<<" gvwgt: ";
    \n+
    1112 print_carray(Dune::dinfo, gvwgt, noVertices);
    \n+
    1113 Dune::dinfo<<std::endl<<"adjwgt: ";
    \n+
    1114 print_carray(Dune::dinfo, gadjwgt, gnoedges);
    \n+
    1115 Dune::dinfo<<std::endl;
    \n+
    1116#endif
    \n+
    1117 // everything should be fine now!!!
    \n+
    1118 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1119 std::cout<<"Postprocesing global graph data took "<<time1.elapsed()<<std::endl;
    \n+
    1120 time1.reset();
    \n+
    1121#ifndef NDEBUG
    \n+
    1122 assert(isValidGraph(noVertices, noVertices, gnoedges,
    \n+
    1123 gxadj, gadjncy, true));
    \n+
    1124#endif
    \n+
    1125
    \n+
    1126 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1127 std::cout<<"Creating grah one 1 process took "<<time.elapsed()<<std::endl;
    \n+
    1128 time.reset();
    \n+
    1129#if METIS_VER_MAJOR >= 5
    \n+
    1130 Metis::idx_t ncon = 1;
    \n+
    1131 Metis::idx_t moptions[METIS_NOPTIONS];
    \n+
    1132 METIS_SetDefaultOptions(moptions);
    \n+
    1133 moptions[METIS_OPTION_NUMBERING] = numflag;
    \n+
    1134 METIS_PartGraphRecursive(&noVertices, &ncon, gxadj, gadjncy, gvwgt, NULL, gadjwgt,
    \n+
    1135 &nparts, NULL, NULL, moptions, &edgecut, gpart);
    \n+
    1136#else
    \n+
    1137 int options[5] = {0, 1, 1, 3, 3};
    \n+
    1138 // Call metis
    \n+
    1139 METIS_PartGraphRecursive(&noVertices, gxadj, gadjncy, gvwgt, gadjwgt, &wgtflag,
    \n+
    1140 &numflag, &nparts, options, &edgecut, gpart);
    \n+
    1141#endif
    \n+
    1142
    \n+
    1143 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1144 std::cout<<"METIS took "<<time.elapsed()<<std::endl;
    \n+
    1145 time.reset();
    \n+
    1146
    \n+
    1147 Dune::dinfo<<std::endl<<"part:";
    \n+
    1148 print_carray(Dune::dinfo, gpart, noVertices);
    \n+
    1149
    \n+
    1150 delete[] gxadj;
    \n+
    1151 delete[] gadjncy;
    \n+
    1152#ifdef USE_WEIGHTS
    \n+
    1153 delete[] gvwgt;
    \n+
    1154 delete[] gadjwgt;
    \n+
    1155#endif
    \n+
    1156 }
    \n+
    1157 // Scatter result
    \n+
    1158 MPI_Scatter(gpart, 1, MPITraits<Metis::idx_t>::getType(), part, 1,
    \n+
    1159 MPITraits<Metis::idx_t>::getType(), 0, comm);
    \n+
    1160
    \n+
    1161 {
    \n+
    1162 // release remaining memory
    \n+
    1163 delete[] gpart;
    \n+
    1164 delete[] noedges;
    \n+
    1165 delete[] displ;
    \n+
    1166 }
    \n+
    1167
    \n+
    1168
    \n+
    1169#endif
    \n+
    1170 delete[] xadj;
    \n+
    1171 delete[] vtxdist;
    \n+
    1172 delete[] adjncy;
    \n+
    1173#ifdef USE_WEIGHTS
    \n+
    1174 delete[] vwgt;
    \n+
    1175 delete[] adjwgt;
    \n+
    1176#endif
    \n+
    1177 delete[] tpwgts;
    \n+
    1178 }
    \n+
    1179 }else{
    \n+
    1180 part[0]=0;
    \n+
    1181 }
    \n+
    1182#endif
    \n+
    1183 Dune::dinfo<<" repart "<<rank <<" -> "<< part[0]<<std::endl;
    \n+
    1184
    \n+
    1185 std::vector<int> realpart(mat.N(), part[0]);
    \n+
    1186 delete[] part;
    \n+
    1187
    \n+
    1188 oocomm.copyOwnerToAll(realpart, realpart);
    \n+
    1189
    \n+
    1190 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1191 std::cout<<"Scattering repartitioning took "<<time.elapsed()<<std::endl;
    \n+
    1192 time.reset();
    \n+
    1193
    \n+
    1194
    \n+
    1195 oocomm.buildGlobalLookup(mat.N());
    \n+
    1196 Dune::Amg::MatrixGraph<M> graph(const_cast<M&>(mat));
    \n+
    1197 fillIndexSetHoles(graph, oocomm);
    \n+
    1198 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1199 std::cout<<"Filling index set took "<<time.elapsed()<<std::endl;
    \n+
    1200 time.reset();
    \n+
    1201
    \n+
    1202 if(verbose) {
    \n+
    1203 int noNeighbours=oocomm.remoteIndices().neighbours();
    \n+
    1204 noNeighbours = oocomm.communicator().sum(noNeighbours)
    \n+
    1205 / oocomm.communicator().size();
    \n+
    1206 if(oocomm.communicator().rank()==0)
    \n+
    1207 std::cout<<"Average no neighbours was "<<noNeighbours<<std::endl;
    \n+
    1208 }
    \n+
    1209 bool ret = buildCommunication(graph, realpart, oocomm, outcomm, redistInf,
    \n+
    1210 verbose);
    \n+
    1211 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1212 std::cout<<"Building index sets took "<<time.elapsed()<<std::endl;
    \n+
    1213 time.reset();
    \n+
    1214
    \n+
    1215
    \n+
    1216 return ret;
    \n+
    1217
    \n+
    1218 }
    \n+
    1219
    \n+
    1234 template<class G, class T1, class T2>
    \n+\n+
    1236 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n+
    1237 RedistributeInterface& redistInf,
    \n+
    1238 bool verbose=false)
    \n+
    1239 {
    \n+
    1240 Timer time;
    \n+
    1241
    \n+
    1242 MPI_Comm comm=oocomm.communicator();
    \n+
    1243 oocomm.buildGlobalLookup(graph.noVertices());
    \n+
    1244 fillIndexSetHoles(graph, oocomm);
    \n+
    1245
    \n+
    1246 if(verbose && oocomm.communicator().rank()==0)
    \n+
    1247 std::cout<<"Filling holes took "<<time.elapsed()<<std::endl;
    \n+
    1248 time.reset();
    \n+
    1249
    \n+
    1250 // simple precondition checks
    \n+
    1251
    \n+
    1252#ifdef PERF_REPART
    \n+
    1253 // Profiling variables
    \n+
    1254 double t1=0.0, t2=0.0, t3=0.0, t4=0.0, tSum=0.0;
    \n+
    1255#endif
    \n+
    1256
    \n+
    1257
    \n+
    1258 // MPI variables
    \n+
    1259 int mype = oocomm.communicator().rank();
    \n+
    1260
    \n+
    1261 assert(nparts<=static_cast<Metis::idx_t>(oocomm.communicator().size()));
    \n+
    1262
    \n+
    1263 int myDomain = -1;
    \n+
    1264
    \n+
    1265 //
    \n+
    1266 // 1) Prepare the required parameters for using ParMETIS
    \n+
    1267 // Especially the arrays that represent the graph must be
    \n+
    1268 // generated by the DUNE Graph and IndexSet input variables.
    \n+
    1269 // These are the arrays:
    \n+
    1270 // - vtxdist
    \n+
    1271 // - xadj
    \n+
    1272 // - adjncy
    \n+
    1273 //
    \n+
    1274 //
    \n+
    1275#ifdef PERF_REPART
    \n+
    1276 // reset timer for step 1)
    \n+
    1277 t1=MPI_Wtime();
    \n+
    1278#endif
    \n+
    1279
    \n+
    1280
    \n+
    1281 typedef typename Dune::OwnerOverlapCopyCommunication<T1,T2> OOComm;
    \n+
    1282 typedef typename OOComm::OwnerSet OwnerSet;
    \n+
    1283
    \n+
    1284 // Create the vtxdist array and parmetisVtxMapping.
    \n+
    1285 // Global communications are necessary
    \n+
    1286 // The parmetis global identifiers for the owner vertices.
    \n+
    1287 ParmetisDuneIndexMap indexMap(graph,oocomm);
    \n+
    1288 Metis::idx_t *part = new Metis::idx_t[indexMap.numOfOwnVtx()];
    \n+
    1289 for(std::size_t i=0; i < indexMap.numOfOwnVtx(); ++i)
    \n+
    1290 part[i]=mype;
    \n+
    1291
    \n+
    1292#if !HAVE_PARMETIS
    \n+
    1293 if(oocomm.communicator().rank()==0 && nparts>1)
    \n+
    1294 std::cerr<<"ParMETIS not activated. Will repartition to 1 domain instead of requested "
    \n+
    1295 <<nparts<<" domains."<<std::endl;
    \n+
    1296 nparts=1; // No parmetis available, fallback to agglomerating to 1 process
    \n+
    1297
    \n+
    1298#else
    \n+
    1299
    \n+
    1300 if(nparts>1) {
    \n+
    1301 // Create the xadj and adjncy arrays
    \n+
    1302 Metis::idx_t *xadj = new Metis::idx_t[indexMap.numOfOwnVtx()+1];
    \n+
    1303 Metis::idx_t *adjncy = new Metis::idx_t[graph.noEdges()];
    \n+
    1304 EdgeFunctor<G> ef(adjncy, indexMap, graph.noEdges());
    \n+
    1305 getAdjArrays<OwnerSet>(graph, oocomm.globalLookup(), xadj, ef);
    \n+
    1306
    \n+
    1307 //
    \n+
    1308 // 2) Call ParMETIS
    \n+
    1309 //
    \n+
    1310 //
    \n+
    1311 Metis::idx_t numflag=0, wgtflag=0, options[3], edgecut=0, ncon=1;
    \n+
    1312 //float *tpwgts = NULL;
    \n+
    1313 Metis::real_t *tpwgts = new Metis::real_t[nparts];
    \n+
    1314 for(int i=0; i<nparts; ++i)
    \n+
    1315 tpwgts[i]=1.0/nparts;
    \n+
    1316 Metis::real_t ubvec[1];
    \n+
    1317 options[0] = 0; // 0=default, 1=options are defined in [1]+[2]
    \n+
    1318#ifdef DEBUG_REPART
    \n+
    1319 options[1] = 3; // show info: 0=no message
    \n+
    1320#else
    \n+
    1321 options[1] = 0; // show info: 0=no message
    \n+
    1322#endif
    \n+
    1323 options[2] = 1; // random number seed, default is 15
    \n+
    1324 wgtflag = (ef.getWeights()!=NULL) ? 1 : 0;
    \n+
    1325 numflag = 0;
    \n+
    1326 edgecut = 0;
    \n+
    1327 ncon=1;
    \n+
    1328 ubvec[0]=1.05; // recommended by ParMETIS
    \n+
    1329
    \n+
    1330#ifdef DEBUG_REPART
    \n+
    1331 if (mype == 0) {
    \n+
    1332 std::cout<<std::endl;
    \n+
    1333 std::cout<<"Testing ParMETIS_V3_PartKway with options[1-2] = {"
    \n+
    1334 <<options[1]<<" "<<options[2]<<"}, Ncon: "
    \n+
    1335 <<ncon<<", Nparts: "<<nparts<<std::endl;
    \n+
    1336 }
    \n+
    1337#endif
    \n+
    1338#ifdef PERF_REPART
    \n+
    1339 // stop the time for step 1)
    \n+
    1340 t1=MPI_Wtime()-t1;
    \n+
    1341 // reset timer for step 2)
    \n+
    1342 t2=MPI_Wtime();
    \n+
    1343#endif
    \n+
    1344
    \n+
    1345 if(verbose) {
    \n+
    1346 oocomm.communicator().barrier();
    \n+
    1347 if(oocomm.communicator().rank()==0)
    \n+
    1348 std::cout<<"Preparing for parmetis took "<<time.elapsed()<<std::endl;
    \n+
    1349 }
    \n+
    1350 time.reset();
    \n+
    1351
    \n+
    1352 //=======================================================
    \n+
    1353 // ParMETIS_V3_PartKway
    \n+
    1354 //=======================================================
    \n+
    1355 ParMETIS_V3_PartKway(indexMap.vtxDist(), xadj, adjncy,
    \n+
    1356 NULL, ef.getWeights(), &wgtflag,
    \n+
    1357 &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &const_cast<MPI_Comm&>(comm));
    \n+
    1358
    \n+
    1359
    \n+
    1360 delete[] xadj;
    \n+
    1361 delete[] adjncy;
    \n+
    1362 delete[] tpwgts;
    \n+
    1363
    \n+
    1364 ef.free();
    \n+
    1365
    \n+
    1366#ifdef DEBUG_REPART
    \n+
    1367 if (mype == 0) {
    \n+
    1368 std::cout<<std::endl;
    \n+
    1369 std::cout<<"ParMETIS_V3_PartKway reported a cut of "<<edgecut<<std::endl;
    \n+
    1370 std::cout<<std::endl;
    \n+
    1371 }
    \n+
    1372 std::cout<<mype<<": PARMETIS-Result: ";
    \n+
    1373 for(int i=0; i < indexMap.vtxDist()[mype+1]-indexMap.vtxDist()[mype]; ++i) {
    \n+
    1374 std::cout<<part[i]<<" ";
    \n+
    1375 }
    \n+
    1376 std::cout<<std::endl;
    \n+
    1377 std::cout<<"Testing ParMETIS_V3_PartKway with options[1-2] = {"
    \n+
    1378 <<options[1]<<" "<<options[2]<<"}, Ncon: "
    \n+
    1379 <<ncon<<", Nparts: "<<nparts<<std::endl;
    \n+
    1380#endif
    \n+
    1381#ifdef PERF_REPART
    \n+
    1382 // stop the time for step 2)
    \n+
    1383 t2=MPI_Wtime()-t2;
    \n+
    1384 // reset timer for step 3)
    \n+
    1385 t3=MPI_Wtime();
    \n+
    1386#endif
    \n+
    1387
    \n+
    1388
    \n+
    1389 if(verbose) {
    \n+
    1390 oocomm.communicator().barrier();
    \n+
    1391 if(oocomm.communicator().rank()==0)
    \n+
    1392 std::cout<<"Parmetis took "<<time.elapsed()<<std::endl;
    \n+
    1393 }
    \n+
    1394 time.reset();
    \n+
    1395 }else
    \n+
    1396#endif
    \n+
    1397 {
    \n+
    1398 // Everything goes to process 0!
    \n+
    1399 for(std::size_t i=0; i<indexMap.numOfOwnVtx(); ++i)
    \n+
    1400 part[i]=0;
    \n+
    1401 }
    \n+
    1402
    \n+
    1403
    \n+
    1404 //
    \n+
    1405 // 3) Find a optimal domain based on the ParMETIS repartitioning
    \n+
    1406 // result
    \n+
    1407 //
    \n+
    1408
    \n+
    1409 std::vector<int> domainMapping(nparts);
    \n+
    1410 if(nparts>1)
    \n+
    1411 getDomain(comm, part, indexMap.numOfOwnVtx(), nparts, &myDomain, domainMapping);
    \n+
    1412 else
    \n+
    1413 domainMapping[0]=0;
    \n+
    1414
    \n+
    1415#ifdef DEBUG_REPART
    \n+
    1416 std::cout<<mype<<": myDomain: "<<myDomain<<std::endl;
    \n+
    1417 std::cout<<mype<<": DomainMapping: ";
    \n+
    1418 for(auto j : range(nparts)) {
    \n+
    1419 std::cout<<" do: "<<j<<" pe: "<<domainMapping[j]<<" ";
    \n+
    1420 }
    \n+
    1421 std::cout<<std::endl;
    \n+
    1422#endif
    \n+
    1423
    \n+
    1424 // Make a domain mapping for the indexset and translate
    \n+
    1425 //domain number to real process number
    \n+
    1426 // domainMapping is the one of parmetis, that is without
    \n+
    1427 // the overlap/copy vertices
    \n+
    1428 std::vector<int> setPartition(oocomm.indexSet().size(), -1);
    \n+
    1429
    \n+
    1430 std::size_t i=0; // parmetis index
    \n+
    1431 for(auto index = oocomm.indexSet().begin(); index != oocomm.indexSet().end(); ++index)
    \n+
    1432 if(OwnerSet::contains(index->local().attribute())) {
    \n+
    1433 setPartition[index->local()]=domainMapping[part[i++]];
    \n+
    1434 }
    \n+
    1435
    \n+
    1436 delete[] part;
    \n+
    1437 oocomm.copyOwnerToAll(setPartition, setPartition);
    \n+
    1438 // communication only needed for ALU
    \n+
    1439 // (ghosts with same global id as owners on the same process)
    \n+
    1440 if (SolverCategory::category(oocomm) ==
    \n+
    1441 static_cast<int>(SolverCategory::nonoverlapping))
    \n+
    1442 oocomm.copyCopyToAll(setPartition, setPartition);
    \n+
    1443 bool ret = buildCommunication(graph, setPartition, oocomm, outcomm, redistInf,
    \n+
    1444 verbose);
    \n+
    1445 if(verbose) {
    \n+
    1446 oocomm.communicator().barrier();
    \n+
    1447 if(oocomm.communicator().rank()==0)
    \n+
    1448 std::cout<<"Creating indexsets took "<<time.elapsed()<<std::endl;
    \n+
    1449 }
    \n+
    1450 return ret;
    \n+
    1451 }
    \n+
    1452
    \n+
    1453
    \n+
    1454
    \n+
    1455 template<class G, class T1, class T2>
    \n+
    1456 bool buildCommunication(const G& graph,
    \n+
    1457 std::vector<int>& setPartition, Dune::OwnerOverlapCopyCommunication<T1,T2>& oocomm,
    \n+
    1458 std::shared_ptr<Dune::OwnerOverlapCopyCommunication<T1,T2>>& outcomm,
    \n+
    1459 RedistributeInterface& redistInf,
    \n+
    1460 bool verbose)
    \n+
    1461 {
    \n+
    1462 typedef typename Dune::OwnerOverlapCopyCommunication<T1,T2> OOComm;
    \n+
    1463 typedef typename OOComm::OwnerSet OwnerSet;
    \n+
    1464
    \n+
    1465 Timer time;
    \n+
    1466
    \n+
    1467 // Build the send interface
    \n+
    1468 redistInf.buildSendInterface<OwnerSet>(setPartition, oocomm.indexSet());
    \n+
    1469
    \n+
    1470#ifdef PERF_REPART
    \n+
    1471 // stop the time for step 3)
    \n+
    1472 t3=MPI_Wtime()-t3;
    \n+
    1473 // reset timer for step 4)
    \n+
    1474 t4=MPI_Wtime();
    \n+
    1475#endif
    \n+
    1476
    \n+
    1477
    \n+
    1478 //
    \n+
    1479 // 4) Create the output IndexSet and RemoteIndices
    \n+
    1480 // 4.1) Determine the "send to" and "receive from" relation
    \n+
    1481 // according to the new partition using a MPI ring
    \n+
    1482 // communication.
    \n+
    1483 //
    \n+
    1484 // 4.2) Depends on the "send to" and "receive from" vector,
    \n+
    1485 // the processes will exchange the vertices each other
    \n+
    1486 //
    \n+
    1487 // 4.3) Create the IndexSet, RemoteIndices and the new MPI
    \n+
    1488 // communicator
    \n+
    1489 //
    \n+
    1490
    \n+
    1491 //
    \n+
    1492 // 4.1) Let's start...
    \n+
    1493 //
    \n+
    1494 int npes = oocomm.communicator().size();
    \n+
    1495 int *sendTo = 0;
    \n+
    1496 int noSendTo = 0;
    \n+
    1497 std::set<int> recvFrom;
    \n+
    1498
    \n+
    1499 // the max number of vertices is stored in the sendTo buffer,
    \n+
    1500 // not the number of vertices to send! Because the max number of Vtx
    \n+
    1501 // is used as the fixed buffer size by the MPI send/receive calls
    \n+
    1502
    \n+
    1503 int mype = oocomm.communicator().rank();
    \n+
    1504
    \n+
    1505 {
    \n+
    1506 std::set<int> tsendTo;
    \n+
    1507 for(auto i=setPartition.begin(), iend = setPartition.end(); i!=iend; ++i)
    \n+
    1508 tsendTo.insert(*i);
    \n+
    1509
    \n+
    1510 noSendTo = tsendTo.size();
    \n+
    1511 sendTo = new int[noSendTo];
    \n+
    1512 int idx=0;
    \n+
    1513 for(auto i=tsendTo.begin(); i != tsendTo.end(); ++i, ++idx)
    \n+
    1514 sendTo[idx]=*i;
    \n+
    1515 }
    \n+
    1516
    \n+
    1517 //
    \n+
    1518 int* gnoSend= new int[oocomm.communicator().size()];
    \n+
    1519 int* gsendToDispl = new int[oocomm.communicator().size()+1];
    \n+
    1520
    \n+
    1521 MPI_Allgather(&noSendTo, 1, MPI_INT, gnoSend, 1,
    \n+
    1522 MPI_INT, oocomm.communicator());
    \n+
    1523
    \n+
    1524 // calculate total receive message size
    \n+
    1525 int totalNoRecv = 0;
    \n+
    1526 for(int i=0; i<npes; ++i)
    \n+
    1527 totalNoRecv += gnoSend[i];
    \n+
    1528
    \n+
    1529 int *gsendTo = new int[totalNoRecv];
    \n+
    1530
    \n+
    1531 // calculate displacement for allgatherv
    \n+
    1532 gsendToDispl[0]=0;
    \n+
    1533 for(int i=0; i<npes; ++i)
    \n+
    1534 gsendToDispl[i+1]=gsendToDispl[i]+gnoSend[i];
    \n+
    1535
    \n+
    1536 // gather the data
    \n+
    1537 MPI_Allgatherv(sendTo, noSendTo, MPI_INT, gsendTo, gnoSend, gsendToDispl,
    \n+
    1538 MPI_INT, oocomm.communicator());
    \n+
    1539
    \n+
    1540 // Extract from which processes we will receive data
    \n+
    1541 for(int proc=0; proc < npes; ++proc)
    \n+
    1542 for(int i=gsendToDispl[proc]; i < gsendToDispl[proc+1]; ++i)
    \n+
    1543 if(gsendTo[i]==mype)
    \n+
    1544 recvFrom.insert(proc);
    \n+
    1545
    \n+
    1546 bool existentOnNextLevel = recvFrom.size()>0;
    \n+
    1547
    \n+
    1548 // Delete memory
    \n+
    1549 delete[] gnoSend;
    \n+
    1550 delete[] gsendToDispl;
    \n+
    1551 delete[] gsendTo;
    \n+
    1552
    \n+
    1553
    \n+
    1554#ifdef DEBUG_REPART
    \n+
    1555 if(recvFrom.size()) {
    \n+
    1556 std::cout<<mype<<": recvFrom: ";
    \n+
    1557 for(auto i=recvFrom.begin(); i!= recvFrom.end(); ++i) {
    \n+
    1558 std::cout<<*i<<" ";
    \n+
    1559 }
    \n+
    1560 }
    \n+
    1561
    \n+
    1562 std::cout<<std::endl<<std::endl;
    \n+
    1563 std::cout<<mype<<": sendTo: ";
    \n+
    1564 for(int i=0; i<noSendTo; i++) {
    \n+
    1565 std::cout<<sendTo[i]<<" ";
    \n+
    1566 }
    \n+
    1567 std::cout<<std::endl<<std::endl;
    \n+
    1568#endif
    \n+
    1569
    \n+
    1570 if(verbose)
    \n+
    1571 if(oocomm.communicator().rank()==0)
    \n+
    1572 std::cout<<" Communicating the receive information took "<<
    \n+
    1573 time.elapsed()<<std::endl;
    \n+
    1574 time.reset();
    \n+
    1575
    \n+
    1576 //
    \n+
    1577 // 4.2) Start the communication
    \n+
    1578 //
    \n+
    1579
    \n+
    1580 // Get all the owner and overlap vertices for myself ans save
    \n+
    1581 // it in the vectors myOwnerVec and myOverlapVec.
    \n+
    1582 // The received vertices from the other processes are simple
    \n+
    1583 // added to these vector.
    \n+
    1584 //
    \n+
    1585
    \n+
    1586
    \n+
    1587 typedef typename OOComm::ParallelIndexSet::GlobalIndex GI;
    \n+
    1588 typedef std::vector<GI> GlobalVector;
    \n+
    1589 std::vector<std::pair<GI,int> > myOwnerVec;
    \n+
    1590 std::set<GI> myOverlapSet;
    \n+
    1591 GlobalVector sendOwnerVec;
    \n+
    1592 std::set<GI> sendOverlapSet;
    \n+
    1593 std::set<int> myNeighbors;
    \n+
    1594
    \n+
    1595 // getOwnerOverlapVec<OwnerSet>(graph, setPartition, oocomm.globalLookup(),
    \n+
    1596 // mype, mype, myOwnerVec, myOverlapSet, redistInf, myNeighbors);
    \n+
    1597
    \n+
    1598 char **sendBuffers=new char*[noSendTo];
    \n+
    1599 MPI_Request *requests = new MPI_Request[noSendTo];
    \n+
    1600
    \n+
    1601 // Create all messages to be sent
    \n+
    1602 for(int i=0; i < noSendTo; ++i) {
    \n+
    1603 // clear the vector for sending
    \n+
    1604 sendOwnerVec.clear();
    \n+
    1605 sendOverlapSet.clear();
    \n+
    1606 // get all owner and overlap vertices for process j and save these
    \n+
    1607 // in the vectors sendOwnerVec and sendOverlapSet
    \n+
    1608 std::set<int> neighbors;
    \n+
    1609 getOwnerOverlapVec<OwnerSet>(graph, setPartition, oocomm.globalLookup(),
    \n+
    1610 mype, sendTo[i], sendOwnerVec, sendOverlapSet, redistInf,
    \n+
    1611 neighbors);
    \n+
    1612 // +2, we need 2 integer more for the length of each part
    \n+
    1613 // (owner/overlap) of the array
    \n+
    1614 int buffersize=0;
    \n+
    1615 int tsize;
    \n+
    1616 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &buffersize);
    \n+
    1617 MPI_Pack_size(sendOwnerVec.size(), MPITraits<GI>::getType(), oocomm.communicator(), &tsize);
    \n+
    1618 buffersize +=tsize;
    \n+
    1619 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &tsize);
    \n+
    1620 buffersize +=tsize;
    \n+
    1621 MPI_Pack_size(sendOverlapSet.size(), MPITraits<GI>::getType(), oocomm.communicator(), &tsize);
    \n+
    1622 buffersize += tsize;
    \n+
    1623 MPI_Pack_size(1, MPITraits<std::size_t>::getType(), oocomm.communicator(), &tsize);
    \n+
    1624 buffersize += tsize;
    \n+
    1625 MPI_Pack_size(neighbors.size(), MPI_INT, oocomm.communicator(), &tsize);
    \n+
    1626 buffersize += tsize;
    \n+
    1627
    \n+
    1628 sendBuffers[i] = new char[buffersize];
    \n+
    1629
    \n+
    1630#ifdef DEBUG_REPART
    \n+
    1631 std::cout<<mype<<" sending "<<sendOwnerVec.size()<<" owner and "<<
    \n+
    1632 sendOverlapSet.size()<<" overlap to "<<sendTo[i]<<" buffersize="<<buffersize<<std::endl;
    \n+
    1633#endif
    \n+
    1634 createSendBuf(sendOwnerVec, sendOverlapSet, neighbors, sendBuffers[i], buffersize, oocomm.communicator());
    \n+
    1635 MPI_Issend(sendBuffers[i], buffersize, MPI_PACKED, sendTo[i], 99, oocomm.communicator(), requests+i);
    \n+
    1636 }
    \n+
    1637
    \n+
    1638 if(verbose) {
    \n+
    1639 oocomm.communicator().barrier();
    \n+
    1640 if(oocomm.communicator().rank()==0)
    \n+
    1641 std::cout<<" Creating sends took "<<
    \n+
    1642 time.elapsed()<<std::endl;
    \n+
    1643 }
    \n+
    1644 time.reset();
    \n+
    1645
    \n+
    1646 // Receive Messages
    \n+
    1647 int noRecv = recvFrom.size();
    \n+
    1648 int oldbuffersize=0;
    \n+
    1649 char* recvBuf = 0;
    \n+
    1650 while(noRecv>0) {
    \n+
    1651 // probe for an incoming message
    \n+
    1652 MPI_Status stat;
    \n+
    1653 MPI_Probe(MPI_ANY_SOURCE, 99, oocomm.communicator(), &stat);
    \n+
    1654 int buffersize;
    \n+
    1655 MPI_Get_count(&stat, MPI_PACKED, &buffersize);
    \n+
    1656
    \n+
    1657 if(oldbuffersize<buffersize) {
    \n+
    1658 // buffer too small, reallocate
    \n+
    1659 delete[] recvBuf;
    \n+
    1660 recvBuf = new char[buffersize];
    \n+
    1661 oldbuffersize = buffersize;
    \n+
    1662 }
    \n+
    1663 MPI_Recv(recvBuf, buffersize, MPI_PACKED, stat.MPI_SOURCE, 99, oocomm.communicator(), &stat);
    \n+
    1664 saveRecvBuf(recvBuf, buffersize, myOwnerVec, myOverlapSet, myNeighbors, redistInf,
    \n+
    1665 stat.MPI_SOURCE, oocomm.communicator());
    \n+
    1666 --noRecv;
    \n+
    1667 }
    \n+
    1668
    \n+
    1669 if(recvBuf)
    \n+
    1670 delete[] recvBuf;
    \n+
    1671
    \n+
    1672 time.reset();
    \n+
    1673 // Wait for sending messages to complete
    \n+
    1674 MPI_Status *statuses = new MPI_Status[noSendTo];
    \n+
    1675 int send = MPI_Waitall(noSendTo, requests, statuses);
    \n+
    1676
    \n+
    1677 // check for errors
    \n+
    1678 if(send==MPI_ERR_IN_STATUS) {
    \n+
    1679 std::cerr<<mype<<": Error in sending :"<<std::endl;
    \n+
    1680 // Search for the error
    \n+
    1681 for(int i=0; i< noSendTo; i++)
    \n+
    1682 if(statuses[i].MPI_ERROR!=MPI_SUCCESS) {
    \n+
    1683 char message[300];
    \n+
    1684 int messageLength;
    \n+
    1685 MPI_Error_string(statuses[i].MPI_ERROR, message, &messageLength);
    \n+
    1686 std::cerr<<" source="<<statuses[i].MPI_SOURCE<<" message: ";
    \n+
    1687 for(int j = 0; j < messageLength; j++)
    \n+
    1688 std::cout<<message[j];
    \n+
    1689 }
    \n+
    1690 std::cerr<<std::endl;
    \n+
    1691 }
    \n+
    1692
    \n+
    1693 if(verbose) {
    \n+
    1694 oocomm.communicator().barrier();
    \n+
    1695 if(oocomm.communicator().rank()==0)
    \n+
    1696 std::cout<<" Receiving and saving took "<<
    \n+
    1697 time.elapsed()<<std::endl;
    \n+
    1698 }
    \n+
    1699 time.reset();
    \n+
    1700
    \n+
    1701 for(int i=0; i < noSendTo; ++i)
    \n+
    1702 delete[] sendBuffers[i];
    \n+
    1703
    \n+
    1704 delete[] sendBuffers;
    \n+
    1705 delete[] statuses;
    \n+
    1706 delete[] requests;
    \n+
    1707
    \n+
    1708 redistInf.setCommunicator(oocomm.communicator());
    \n+
    1709
    \n+
    1710 //
    \n+
    1711 // 4.2) Create the IndexSet etc.
    \n+
    1712 //
    \n+
    1713
    \n+
    1714 // build the new outputIndexSet
    \n+
    1715
    \n+
    1716
    \n+
    1717 int color=0;
    \n+
    1718
    \n+
    1719 if (!existentOnNextLevel) {
    \n+
    1720 // this process is not used anymore
    \n+
    1721 color= MPI_UNDEFINED;
    \n+
    1722 }
    \n+
    1723 MPI_Comm outputComm;
    \n+
    1724
    \n+
    1725 MPI_Comm_split(oocomm.communicator(), color, oocomm.communicator().rank(), &outputComm);
    \n+
    1726 outcomm = std::make_shared<OOComm>(outputComm,SolverCategory::category(oocomm),true);
    \n+
    1727
    \n+
    1728 // translate neighbor ranks.
    \n+
    1729 int newrank=outcomm->communicator().rank();
    \n+
    1730 int *newranks=new int[oocomm.communicator().size()];
    \n+
    1731 std::vector<int> tneighbors;
    \n+
    1732 tneighbors.reserve(myNeighbors.size());
    \n+
    1733
    \n+
    1734 typename OOComm::ParallelIndexSet& outputIndexSet = outcomm->indexSet();
    \n+
    1735
    \n+
    1736 MPI_Allgather(&newrank, 1, MPI_INT, newranks, 1,
    \n+
    1737 MPI_INT, oocomm.communicator());
    \n+
    1738
    \n+
    1739#ifdef DEBUG_REPART
    \n+
    1740 std::cout<<oocomm.communicator().rank()<<" ";
    \n+
    1741 for(auto i=myNeighbors.begin(), end=myNeighbors.end();
    \n+
    1742 i!=end; ++i) {
    \n+
    1743 assert(newranks[*i]>=0);
    \n+
    1744 std::cout<<*i<<"->"<<newranks[*i]<<" ";
    \n+
    1745 tneighbors.push_back(newranks[*i]);
    \n+
    1746 }
    \n+
    1747 std::cout<<std::endl;
    \n+
    1748#else
    \n+
    1749 for(auto i=myNeighbors.begin(), end=myNeighbors.end();
    \n+
    1750 i!=end; ++i) {
    \n+
    1751 tneighbors.push_back(newranks[*i]);
    \n+
    1752 }
    \n+
    1753#endif
    \n+
    1754 delete[] newranks;
    \n+
    1755 myNeighbors.clear();
    \n+
    1756
    \n+
    1757 if(verbose) {
    \n+
    1758 oocomm.communicator().barrier();
    \n+
    1759 if(oocomm.communicator().rank()==0)
    \n+
    1760 std::cout<<" Calculating new neighbours ("<<tneighbors.size()<<") took "<<
    \n+
    1761 time.elapsed()<<std::endl;
    \n+
    1762 }
    \n+
    1763 time.reset();
    \n+
    1764
    \n+
    1765
    \n+
    1766 outputIndexSet.beginResize();
    \n+
    1767 // 1) add the owner vertices
    \n+
    1768 // Sort the owners
    \n+
    1769 std::sort(myOwnerVec.begin(), myOwnerVec.end(), SortFirst());
    \n+
    1770 // The owners are sorted according to there global index
    \n+
    1771 // Therefore the entries of ownerVec are the same as the
    \n+
    1772 // ones in the resulting index set.
    \n+
    1773 int i=0;
    \n+
    1774 using LocalIndexT = typename OOComm::ParallelIndexSet::LocalIndex;
    \n+
    1775 for(auto g=myOwnerVec.begin(), end =myOwnerVec.end(); g!=end; ++g, ++i ) {
    \n+
    1776 outputIndexSet.add(g->first,LocalIndexT(i, OwnerOverlapCopyAttributeSet::owner, true));
    \n+
    1777 redistInf.addReceiveIndex(g->second, i);
    \n+
    1778 }
    \n+
    1779
    \n+
    1780 if(verbose) {
    \n+
    1781 oocomm.communicator().barrier();
    \n+
    1782 if(oocomm.communicator().rank()==0)
    \n+
    1783 std::cout<<" Adding owner indices took "<<
    \n+
    1784 time.elapsed()<<std::endl;
    \n+
    1785 }
    \n+
    1786 time.reset();
    \n+
    1787
    \n+
    1788
    \n+
    1789 // After all the vertices are received, the vectors must
    \n+
    1790 // be "merged" together to create the final vectors.
    \n+
    1791 // Because some vertices that are sent as overlap could now
    \n+
    1792 // already included as owner vertiecs in the new partition
    \n+
    1793 mergeVec(myOwnerVec, myOverlapSet);
    \n+
    1794
    \n+
    1795 // Trick to free memory
    \n+
    1796 myOwnerVec.clear();
    \n+
    1797 myOwnerVec.swap(myOwnerVec);
    \n+
    1798
    \n+
    1799 if(verbose) {
    \n+
    1800 oocomm.communicator().barrier();
    \n+
    1801 if(oocomm.communicator().rank()==0)
    \n+
    1802 std::cout<<" Merging indices took "<<
    \n+
    1803 time.elapsed()<<std::endl;
    \n+
    1804 }
    \n+
    1805 time.reset();
    \n+
    1806
    \n+
    1807
    \n+
    1808 // 2) add the overlap vertices
    \n+
    1809 for(auto g=myOverlapSet.begin(), end=myOverlapSet.end(); g!=end; ++g, i++) {
    \n+
    1810 outputIndexSet.add(*g,LocalIndexT(i, OwnerOverlapCopyAttributeSet::copy, true));
    \n+
    1811 }
    \n+
    1812 myOverlapSet.clear();
    \n+
    1813 outputIndexSet.endResize();
    \n+
    1814
    \n+
    1815#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1816 int numOfOwnVtx =0;
    \n+
    1817 auto end = outputIndexSet.end();
    \n+
    1818 for(auto index = outputIndexSet.begin(); index != end; ++index) {
    \n+
    1819 if (OwnerSet::contains(index->local().attribute())) {
    \n+
    1820 numOfOwnVtx++;
    \n+
    1821 }
    \n+
    1822 }
    \n+
    1823 numOfOwnVtx = oocomm.communicator().sum(numOfOwnVtx);
    \n+
    1824 // if(numOfOwnVtx!=indexMap.globalOwnerVertices)
    \n+
    1825 // {
    \n+
    1826 // std::cerr<<numOfOwnVtx<<"!="<<indexMap.globalOwnerVertices<<" owners missing or additional ones!"<<std::endl;
    \n+
    1827 // DUNE_THROW(ISTLError, numOfOwnVtx<<"!="<<indexMap.globalOwnerVertices<<" owners missing or additional ones"
    \n+
    1828 // <<" during repartitioning.");
    \n+
    1829 // }
    \n+
    1830 std::is_sorted(outputIndexSet.begin(), outputIndexSet.end(),
    \n+
    1831 [](const auto& v1, const auto& v2){ return v1.global() < v2.global();});
    \n+
    1832#endif
    \n+
    1833 if(verbose) {
    \n+
    1834 oocomm.communicator().barrier();
    \n+
    1835 if(oocomm.communicator().rank()==0)
    \n+
    1836 std::cout<<" Adding overlap indices took "<<
    \n+
    1837 time.elapsed()<<std::endl;
    \n+
    1838 }
    \n+
    1839 time.reset();
    \n+
    1840
    \n+
    1841
    \n+
    1842 if(color != MPI_UNDEFINED) {
    \n+
    1843 outcomm->remoteIndices().setNeighbours(tneighbors);
    \n+
    1844 outcomm->remoteIndices().template rebuild<true>();
    \n+
    1845
    \n+
    1846 }
    \n+
    1847
    \n+
    1848 // release the memory
    \n+
    1849 delete[] sendTo;
    \n+
    1850
    \n+
    1851 if(verbose) {
    \n+
    1852 oocomm.communicator().barrier();
    \n+
    1853 if(oocomm.communicator().rank()==0)
    \n+
    1854 std::cout<<" Storing indexsets took "<<
    \n+
    1855 time.elapsed()<<std::endl;
    \n+
    1856 }
    \n+
    1857
    \n+
    1858#ifdef PERF_REPART
    \n+
    1859 // stop the time for step 4) and print the results
    \n+
    1860 t4=MPI_Wtime()-t4;
    \n+
    1861 tSum = t1 + t2 + t3 + t4;
    \n+
    1862 std::cout<<std::endl
    \n+
    1863 <<mype<<": WTime for step 1): "<<t1
    \n+
    1864 <<" 2): "<<t2
    \n+
    1865 <<" 3): "<<t3
    \n+
    1866 <<" 4): "<<t4
    \n+
    1867 <<" total: "<<tSum
    \n+
    1868 <<std::endl;
    \n+
    1869#endif
    \n+
    1870
    \n+
    1871 return color!=MPI_UNDEFINED;
    \n+
    1872
    \n+
    1873 }
    \n+
    1874#else
    \n+
    1875 template<class G, class P,class T1, class T2, class R>
    \n+
    1876 bool graphRepartition(const G& graph, P& oocomm, int nparts,
    \n+
    1877 std::shared_ptr<P>& outcomm,
    \n+
    1878 R& redistInf,
    \n+
    1879 bool v=false)
    \n+
    1880 {
    \n+
    1881 if(nparts!=oocomm.size())
    \n+
    1882 DUNE_THROW(NotImplemented, "only available for MPI programs");
    \n+
    1883 }
    \n+
    1884
    \n+
    1885
    \n+
    1886 template<class G, class P,class T1, class T2, class R>
    \n+
    1887 bool commGraphRepartition(const G& graph, P& oocomm, int nparts,
    \n+
    1888 std::shared_ptr<P>& outcomm,
    \n+
    1889 R& redistInf,
    \n+
    1890 bool v=false)
    \n+
    1891 {
    \n+
    1892 if(nparts!=oocomm.size())
    \n+
    1893 DUNE_THROW(NotImplemented, "only available for MPI programs");
    \n+
    1894 }
    \n+
    1895#endif // HAVE_MPI
    \n+
    1896} // end of namespace Dune
    \n+
    1897#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    int globalOwnerVertices
    Definition: repartition.hh:175
    \n+
    Provides classes for building the matrix graph.
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n
    Definition: allocator.hh:11
    \n-
    A hierarchy of containers (e.g. matrices or vectors)
    Definition: hierarchy.hh:40
    \n-
    T MemberType
    The type of the container we store.
    Definition: hierarchy.hh:45
    \n-
    LevelIterator< Hierarchy< T, A >, T > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n-
    LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n-
    ConstructionTraits< T >::Arguments Arguments
    Definition: hierarchy.hh:78
    \n-
    Hierarchy()
    Construct an empty hierarchy.
    Definition: hierarchy.hh:89
    \n-
    typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator
    The allocator to use for the list elements.
    Definition: hierarchy.hh:76
    \n-
    Iterator over the levels in the hierarchy.
    Definition: hierarchy.hh:120
    \n-
    LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
    Copy constructor.
    Definition: hierarchy.hh:136
    \n-
    void addRedistributed(std::shared_ptr< T1 > t)
    Definition: hierarchy.hh:201
    \n-
    T1 & dereference() const
    Dereference the iterator.
    Definition: hierarchy.hh:166
    \n-
    bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
    Equality check.
    Definition: hierarchy.hh:150
    \n-
    bool isRedistributed() const
    Check whether there was a redistribution at the current level.
    Definition: hierarchy.hh:187
    \n-
    bool equals(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other) const
    Equality check.
    Definition: hierarchy.hh:159
    \n-
    void increment()
    Move to the next coarser level.
    Definition: hierarchy.hh:172
    \n-
    LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
    Copy constructor.
    Definition: hierarchy.hh:142
    \n-
    void deleteRedistributed()
    Definition: hierarchy.hh:206
    \n-
    void decrement()
    Move to the next fine level.
    Definition: hierarchy.hh:178
    \n-
    LevelIterator(std::shared_ptr< Element > element)
    Definition: hierarchy.hh:131
    \n-
    T1 & getRedistributed() const
    Get the redistributed container.
    Definition: hierarchy.hh:196
    \n+
    bool buildCommunication(const G &graph, std::vector< int > &realparts, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:1456
    \n+
    void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm)
    Fills the holes in an index set.
    Definition: repartition.hh:83
    \n+
    bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:829
    \n+
    void print_carray(S &os, T *array, std::size_t l)
    Definition: repartition.hh:778
    \n+
    bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T *adjncy, bool checkSymmetry)
    Definition: repartition.hh:785
    \n+
    bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    execute a graph repartition for a giving graph and indexset.
    Definition: repartition.hh:1235
    \n+
    float real_t
    Definition: repartition.hh:53
    \n+
    std::size_t idx_t
    Definition: repartition.hh:63
    \n+
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    const GlobalLookupIndexSet & globalLookup() const
    Definition: owneroverlapcopy.hh:526
    \n+
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n+
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n+
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n+
    void buildGlobalLookup()
    Definition: owneroverlapcopy.hh:495
    \n+
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n+
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n+
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n+
    void freeGlobalLookup()
    Definition: owneroverlapcopy.hh:520
    \n+
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n+
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n+
    Definition: repartition.hh:260
    \n+
    void reserveSpaceForReceiveInterface(int proc, int size)
    Definition: repartition.hh:284
    \n+
    void buildReceiveInterface(std::vector< std::pair< TG, int > > &indices)
    Definition: repartition.hh:293
    \n+
    ~RedistributeInterface()
    Definition: repartition.hh:301
    \n+
    void setCommunicator(MPI_Comm comm)
    Definition: repartition.hh:261
    \n+
    void buildSendInterface(const std::vector< int > &toPart, const IS &idxset)
    Definition: repartition.hh:266
    \n+
    void addReceiveIndex(int proc, std::size_t idx)
    Definition: repartition.hh:288
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,445 +4,1994 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-hierarchy.hh\n+repartition.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMGHIERARCHY_HH\n- 6#define DUNE_AMGHIERARCHY_HH\n+ 5#ifndef DUNE_ISTL_REPARTITION_HH\n+ 6#define DUNE_ISTL_REPARTITION_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15\n- 16namespace Dune\n- 17{\n- 18 namespace Amg\n- 19 {\n- 38 template >\n-39 class Hierarchy\n- 40 {\n- 41 public:\n-45 typedef T MemberType;\n- 46\n- 47 template\n- 48 class LevelIterator;\n- 49\n- 50 private:\n- 54 struct Element\n- 55 {\n- 56 friend class LevelIterator, T>;\n- 57 friend class LevelIterator, const T>;\n- 58\n- 60 std::weak_ptr coarser_;\n- 61\n- 63 std::shared_ptr finer_;\n- 64\n- 66 std::shared_ptr element_;\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12\n+ 13#if HAVE_PARMETIS\n+ 14// Explicitly use C linkage as scotch does not extern \"C\" in its headers.\n+ 15// Works because ParMETIS/METIS checks whether compiler is C++ and otherwise\n+ 16// does not use extern \"C\". Therfore no nested extern \"C\" will be created\n+ 17extern \"C\"\n+ 18{\n+ 19#include \n+ 20}\n+ 21#endif\n+ 22\n+ 23#include \n+ 24#include \n+ 25#include \n+ 26#include \n+ 27#include \n+ 28#include \n+ 29#include \n+ 30#include \n+ 31#include \n+ 32\n+ 33#include \n+ 34#include \n+ 35\n+ 44namespace Dune\n+ 45{\n+46 namespace Metis\n+ 47 {\n+ 48 // Explicitly specify a real_t and idx_t for older (Par)METIS versions that\n+do not\n+ 49 // provide these typedefs\n+ 50#if HAVE_PARMETIS && defined(REALTYPEWIDTH)\n+ 51 using real_t = ::real_t;\n+ 52#else\n+53 using real_t = float;\n+ 54#endif\n+ 55\n+ 56#if HAVE_PARMETIS && defined(IDXTYPEWIDTH)\n+ 57 using idx_t = ::idx_t;\n+ 58#elif HAVE_PARMETIS && defined(HAVE_SCOTCH_NUM_TYPE)\n+ 59 using idx_t = SCOTCH_Num;\n+ 60#elif HAVE_PARMETIS\n+ 61 using idx_t = int;\n+ 62#else\n+63 using idx_t = std::size_t;\n+ 64#endif\n+ 65 }\n+ 66\n 67\n-69 std::shared_ptr redistributed_;\n- 70 };\n- 71 public:\n- 72\n-76 using Allocator = typename std::allocator_traits::template\n-rebind_alloc;\n- 77\n-78 typedef typename ConstructionTraits::Arguments Arguments;\n- 79\n-84 Hierarchy(const std::shared_ptr & first);\n- 85\n-89 Hierarchy() : levels_(0)\n- 90 {}\n- 91\n-95 Hierarchy(const Hierarchy& other);\n- 96\n-101 void addCoarser(Arguments& args);\n- 102\n-103 void addRedistributedOnCoarsest(Arguments& args);\n- 104\n-109 void addFiner(Arguments& args);\n- 110\n- 117 template\n-118 class LevelIterator\n- 119 : public BidirectionalIteratorFacade,T1,T1&>\n- 120 {\n- 121 friend class LevelIterator::type,\n- 122 typename std::remove_const::type >;\n- 123 friend class LevelIterator::type,\n- 124 const typename std::remove_const::type >;\n- 125\n- 126 public:\n-128 LevelIterator()\n- 129 {}\n+ 68#if HAVE_MPI\n+ 82 template\n+83 void fillIndexSetHoles(const G& graph, Dune::\n+OwnerOverlapCopyCommunication& oocomm)\n+ 84 {\n+ 85 typedef typename Dune::OwnerOverlapCopyCommunication::\n+ParallelIndexSet IndexSet;\n+ 86 typedef typename IndexSet::LocalIndex::Attribute Attribute;\n+ 87\n+ 88 IndexSet& indexSet = oocomm.indexSet();\n+ 89 const typename Dune::OwnerOverlapCopyCommunication::\n+GlobalLookupIndexSet& lookup =oocomm.globalLookup();\n+ 90\n+ 91 std::size_t sum=0, needed = graph.noVertices()-indexSet.size();\n+ 92 std::vector neededall(oocomm.communicator().size(), 0);\n+ 93\n+ 94 MPI_Allgather(&needed, 1, MPITraits::getType() , &(neededall\n+[0]), 1, MPITraits::getType(), oocomm.communicator());\n+ 95 for(int i=0; iglobal());\n+ 107\n+ 108 //Process p creates global indices consecutively\n+ 109 //starting atmaxgi+\\sum_{i=1}^p neededall[i]\n+ 110 // All created indices are owned by the process\n+ 111 maxgi=oocomm.communicator().max(maxgi);\n+ 112 ++maxgi; //Sart with the next free index.\n+ 113\n+ 114 for(int i=0; i > > globalIndices;\n+ 119 storeGlobalIndicesOfRemoteIndices(globalIndices, oocomm.remoteIndices());\n+ 120 indexSet.beginResize();\n+ 121\n+ 122 for(auto vertex = graph.begin(), vend=graph.end(); vertex != vend;\n+++vertex) {\n+ 123 const typename IndexSet::IndexPair* pair=lookup.pair(*vertex);\n+ 124 if(pair==0) {\n+ 125 // No index yet, add new one\n+ 126 indexSet.add(maxgi, typename IndexSet::LocalIndex(*vertex,\n+OwnerOverlapCopyAttributeSet::owner, false));\n+ 127 ++maxgi;\n+ 128 }\n+ 129 }\n 130\n-131 LevelIterator(std::shared_ptr element)\n- 132 : element_(element)\n- 133 {}\n+ 131 indexSet.endResize();\n+ 132\n+ 133 repairLocalIndexPointers(globalIndices, oocomm.remoteIndices(), indexSet);\n 134\n-136 LevelIterator(const LevelIterator::type,\n- 137 typename std::remove_const::type>& other)\n- 138 : element_(other.element_)\n- 139 {}\n- 140\n-142 LevelIterator(const LevelIterator::\n-type,\n- 143 const typename std::remove_const::type>& other)\n- 144 : element_(other.element_)\n- 145 {}\n- 146\n-150 bool equals(const LevelIterator::type,\n- 151 typename std::remove_const::type>& other) const\n+ 135 oocomm.freeGlobalLookup();\n+ 136 oocomm.buildGlobalLookup();\n+ 137#ifdef DEBUG_REPART\n+ 138 std::cout<<\"Holes are filled!\"<\n+ 150 ParmetisDuneIndexMap(const Graph& graph, const OOComm& com);\n+ 151 int toParmetis(int i) const\n 152 {\n- 153 return element_ == other.element_;\n+ 153 return duneToParmetis[i];\n 154 }\n- 155\n-159 bool equals(const LevelIterator::type,\n- 160 const typename std::remove_const::type>& other) const\n- 161 {\n- 162 return element_ == other.element_;\n- 163 }\n- 164\n-166 T1& dereference() const\n- 167 {\n- 168 return *(element_->element_);\n- 169 }\n- 170\n-172 void increment()\n- 173 {\n- 174 element_ = element_->coarser_.lock();\n- 175 }\n- 176\n-178 void decrement()\n- 179 {\n- 180 element_ = element_->finer_;\n- 181 }\n- 182\n-187 bool isRedistributed() const\n- 188 {\n- 189 return (bool)element_->redistributed_;\n- 190 }\n+ 155 int toLocalParmetis(int i) const\n+ 156 {\n+ 157 return duneToParmetis[i]-base_;\n+ 158 }\n+ 159 int operator[](int i) const\n+ 160 {\n+ 161 return duneToParmetis[i];\n+ 162 }\n+ 163 int toDune(int i) const\n+ 164 {\n+ 165 return parmetisToDune[i];\n+ 166 }\n+ 167 std::vector::size_type numOfOwnVtx() const\n+ 168 {\n+ 169 return parmetisToDune.size();\n+ 170 }\n+ 171 Metis::idx_t* vtxDist()\n+ 172 {\n+ 173 return &vtxDist_[0];\n+ 174 }\n+175 int globalOwnerVertices;\n+ 176 private:\n+ 177 int base_;\n+ 178 std::vector duneToParmetis;\n+ 179 std::vector parmetisToDune;\n+ 180 // range of vertices for processor i: vtxdist[i] to vtxdist[i+1] (parmetis\n+global)\n+ 181 std::vector vtxDist_;\n+ 182 };\n+ 183\n+ 184 template\n+ 185 ParmetisDuneIndexMap::ParmetisDuneIndexMap(const G& graph, const OOComm&\n+oocomm)\n+ 186 : duneToParmetis(graph.noVertices(), -1), vtxDist_(oocomm.communicator\n+().size()+1)\n+ 187 {\n+ 188 int npes=oocomm.communicator().size(), mype=oocomm.communicator().rank();\n+ 189\n+ 190 typedef typename OOComm::OwnerSet OwnerSet;\n 191\n-196 T1& getRedistributed() const\n- 197 {\n- 198 assert(element_->redistributed_);\n- 199 return *element_->redistributed_;\n- 200 }\n-201 void addRedistributed(std::shared_ptr t)\n- 202 {\n- 203 element_->redistributed_ = t;\n- 204 }\n- 205\n-206 void deleteRedistributed()\n- 207 {\n- 208 element_->redistributed_ = nullptr;\n+ 192 int numOfOwnVtx=0;\n+ 193 auto end = oocomm.indexSet().end();\n+ 194 for(auto index = oocomm.indexSet().begin(); index != end; ++index) {\n+ 195 if (OwnerSet::contains(index->local().attribute())) {\n+ 196 numOfOwnVtx++;\n+ 197 }\n+ 198 }\n+ 199 parmetisToDune.resize(numOfOwnVtx);\n+ 200 std::vector globalNumOfVtx(npes);\n+ 201 // make this number available to all processes\n+ 202 MPI_Allgather(&numOfOwnVtx, 1, MPI_INT, &(globalNumOfVtx[0]), 1, MPI_INT,\n+oocomm.communicator());\n+ 203\n+ 204 int base=0;\n+ 205 vtxDist_[0] = 0;\n+ 206 for(int i=0; i element_;\n- 213 };\n+ 210 vtxDist_[i+1] = vtxDist_[i] + globalNumOfVtx[i];\n+ 211 }\n+ 212 globalOwnerVertices=vtxDist_[npes];\n+ 213 base_=base;\n 214\n-216 typedef LevelIterator,T> Iterator;\n- 217\n-219 typedef LevelIterator, const T> ConstIterator;\n- 220\n-225 Iterator finest();\n- 226\n-231 Iterator coarsest();\n- 232\n- 233\n-238 ConstIterator finest() const;\n- 239\n-244 ConstIterator coarsest() const;\n- 245\n-250 std::size_t levels() const;\n- 251\n- 252 private:\n- 258 std::shared_ptr originalFinest_;\n- 260 std::shared_ptr finest_;\n- 262 std::shared_ptr coarsest_;\n- 264 Allocator allocator_;\n- 266 int levels_;\n- 267 };\n- 268\n- 269 template\n-270 Hierarchy::Hierarchy(const std::shared_ptr & first)\n- 271 : originalFinest_(first)\n- 272 {\n- 273 finest_ = std::allocate_shared(allocator_);\n- 274 finest_->element_ = originalFinest_;\n- 275 coarsest_ = finest_;\n- 276 levels_ = 1;\n- 277 }\n- 278\n- 280 //TODO: do we actually want to support this? This might be very\n-expensive?!\n- 281 template\n-282 Hierarchy::Hierarchy(const Hierarchy& other)\n- 283 : allocator_(other.allocator_),\n- 284 levels_(other.levels_)\n+ 215#ifdef DEBUG_REPART\n+ 216 std::cout << oocomm.communicator().rank()<<\" vtxDist: \";\n+ 217 for(int i=0; i<= npes; ++i)\n+ 218 std::cout << vtxDist_[i]<<\" \";\n+ 219 std::cout<local().attribute())) {\n+ 231 // assign and count the index\n+ 232 parmetisToDune[base-base_]=index->local();\n+ 233 duneToParmetis[index->local()] = base++;\n+ 234 }\n+ 235 }\n+ 236\n+ 237 // At this point, every process knows the ParMETIS global index\n+ 238 // of it's owner vertices. The next step is to get the\n+ 239 // ParMETIS global index of the overlap vertices from the\n+ 240 // associated processes. To do this, the Dune::Interface class\n+ 241 // is used.\n+ 242#ifdef DEBUG_REPART\n+ 243 std::cout <\n+266 void buildSendInterface(const std::vector& toPart, const IS& idxset)\n+ 267 {\n+ 268 std::map sizes;\n+ 269\n+ 270 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)\n+ 271 if(Flags::contains(i->local().attribute()))\n+ 272 ++sizes[toPart[i->local()]];\n+ 273\n+ 274 // Allocate the necessary space\n+ 275 for(auto i=sizes.begin(), end=sizes.end(); i!=end; ++i)\n+ 276 interfaces()[i->first].first.reserve(i->second);\n+ 277\n+ 278 //Insert the interface information\n+ 279 for(auto i=idxset.begin(), end=idxset.end(); i!=end; ++i)\n+ 280 if(Flags::contains(i->local().attribute()))\n+ 281 interfaces()[toPart[i->local()]].first.add(i->local());\n+ 282 }\n+ 283\n+284 void reserveSpaceForReceiveInterface(int proc, int size)\n 285 {\n- 286 if(!other.finest_)\n- 287 {\n- 288 finest_=coarsest_=nullptr;\n- 289 return;\n- 290 }\n- 291 finest_ = std::allocate_shared(allocator_);\n- 292 std::shared_ptr finer_;\n- 293 std::shared_ptr current_ = finest_;\n- 294 std::weak_ptr otherWeak_ = other.finest_;\n- 295\n- 296 while(! otherWeak_.expired())\n- 297 {\n- 298 // create shared_ptr from weak_ptr, we just checked that this is safe\n- 299 std::shared_ptr otherCurrent_ = std::shared_ptr\n-(otherWeak_);\n- 300 // clone current level\n- 301 //TODO: should we use the allocator?\n- 302 current_->element_ =\n- 303 std::make_shared(*(otherCurrent_->element_));\n- 304 current_->finer_=finer_;\n- 305 if(otherCurrent_->redistributed_)\n- 306 current_->redistributed_ =\n- 307 std::make_shared(*(otherCurrent_->redistributed_));\n- 308 finer_=current_;\n- 309 if(not otherCurrent_->coarser_.expired())\n- 310 {\n- 311 auto c = std::allocate_shared(allocator_);\n- 312 current_->coarser_ = c;\n- 313 current_ = c;\n- 314 }\n- 315 // go to coarser level\n- 316 otherWeak_ = otherCurrent_->coarser_;\n- 317 }\n- 318 coarsest_=current_;\n- 319 }\n- 320\n- 321 template\n-322 std::size_t Hierarchy::levels() const\n- 323 {\n- 324 return levels_;\n- 325 }\n- 326\n- 327 template\n-328 void Hierarchy::addRedistributedOnCoarsest(Arguments& args)\n- 329 {\n- 330 coarsest_->redistributed_ = ConstructionTraits::construct\n-(args);\n- 331 }\n- 332\n- 333 template\n-334 void Hierarchy::addCoarser(Arguments& args)\n- 335 {\n- 336 if(!coarsest_) {\n- 337 // we have no levels at all...\n- 338 assert(!finest_);\n- 339 // allocate into the shared_ptr\n- 340 originalFinest_ = ConstructionTraits::construct(args);\n- 341 coarsest_ = std::allocate_shared(allocator_);\n- 342 coarsest_->element_ = originalFinest_;\n- 343 finest_ = coarsest_;\n- 344 }else{\n- 345 auto old_coarsest = coarsest_;\n- 346 coarsest_ = std::allocate_shared(allocator_);\n- 347 coarsest_->finer_ = old_coarsest;\n- 348 coarsest_->element_ = ConstructionTraits::construct(args);\n- 349 old_coarsest->coarser_ = coarsest_;\n- 350 }\n- 351 ++levels_;\n- 352 }\n- 353\n- 354\n- 355 template\n-356 void Hierarchy::addFiner(Arguments& args)\n- 357 {\n- 358 //TODO: wouldn't it be better to do this in the constructor?'\n- 359 if(!finest_) {\n- 360 // we have no levels at all...\n- 361 assert(!coarsest_);\n- 362 // allocate into the shared_ptr\n- 363 originalFinest_ = ConstructionTraits::construct(args);\n- 364 finest_ = std::allocate_shared(allocator_);\n- 365 finest_->element = originalFinest_;\n- 366 coarsest_ = finest_;\n- 367 }else{\n- 368 finest_->finer_ = std::allocate_shared(allocator_);\n- 369 finest_->finer_->coarser_ = finest_;\n- 370 finest_ = finest_->finer_;\n- 371 finest_->element = ConstructionTraits::construct(args);\n- 372 }\n- 373 ++levels_;\n- 374 }\n- 375\n- 376 template\n-377 typename Hierarchy::Iterator Hierarchy::finest()\n- 378 {\n- 379 return Iterator(finest_);\n- 380 }\n- 381\n- 382 template\n-383 typename Hierarchy::Iterator Hierarchy::coarsest()\n- 384 {\n- 385 return Iterator(coarsest_);\n- 386 }\n- 387\n- 388 template\n-389 typename Hierarchy::ConstIterator Hierarchy::finest() const\n- 390 {\n- 391 return ConstIterator(finest_);\n- 392 }\n- 393\n- 394 template\n-395 typename Hierarchy::ConstIterator Hierarchy::coarsest() const\n- 396 {\n- 397 return ConstIterator(coarsest_);\n- 398 }\n- 400 } // namespace Amg\n- 401} // namespace Dune\n+ 286 interfaces()[proc].second.reserve(size);\n+ 287 }\n+288 void addReceiveIndex(int proc, std::size_t idx)\n+ 289 {\n+ 290 interfaces()[proc].second.add(idx);\n+ 291 }\n+ 292 template\n+293 void buildReceiveInterface(std::vector >& indices)\n+ 294 {\n+ 295 std::size_t i=0;\n+ 296 for(auto idx=indices.begin(); idx!= indices.end(); ++idx) {\n+ 297 interfaces()[idx->second].second.add(i++);\n+ 298 }\n+ 299 }\n+ 300\n+301 ~RedistributeInterface()\n+ 302 {}\n+ 303\n+ 304 };\n+ 305\n+ 306 namespace\n+ 307 {\n+ 317 template\n+ 318 void createSendBuf(std::vector& ownerVec, std::set& overlapVec,\n+std::set& neighbors, char *sendBuf, int buffersize, MPI_Comm comm) {\n+ 319 // Pack owner vertices\n+ 320 std::size_t s=ownerVec.size();\n+ 321 int pos=0;\n+ 322 if(s==0)\n+ 323 ownerVec.resize(1); // otherwise would read beyond the memory bound\n+ 324 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n+&pos, comm);\n+ 325 MPI_Pack(&(ownerVec[0]), s, MPITraits::getType(), sendBuf, buffersize,\n+&pos, comm);\n+ 326 s = overlapVec.size();\n+ 327 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n+&pos, comm);\n+ 328 for(auto i=overlapVec.begin(), end= overlapVec.end(); i != end; ++i)\n+ 329 MPI_Pack(const_cast(&(*i)), 1, MPITraits::getType(), sendBuf,\n+buffersize, &pos, comm);\n+ 330\n+ 331 s=neighbors.size();\n+ 332 MPI_Pack(&s, 1, MPITraits::getType(), sendBuf, buffersize,\n+&pos, comm);\n+ 333\n+ 334 for(auto i=neighbors.begin(), end= neighbors.end(); i != end; ++i)\n+ 335 MPI_Pack(const_cast(&(*i)), 1, MPI_INT, sendBuf, buffersize, &pos,\n+comm);\n+ 336 }\n+ 345 template\n+ 346 void saveRecvBuf(char *recvBuf, int bufferSize, std::vector >& ownerVec,\n+ 347 std::set& overlapVec, std::set& neighbors, RedistributeInterface&\n+inf, int from, MPI_Comm comm) {\n+ 348 std::size_t size;\n+ 349 int pos=0;\n+ 350 // unpack owner vertices\n+ 351 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n+getType(), comm);\n+ 352 inf.reserveSpaceForReceiveInterface(from, size);\n+ 353 ownerVec.reserve(ownerVec.size()+size);\n+ 354 for(; size!=0; --size) {\n+ 355 GI gi;\n+ 356 MPI_Unpack(recvBuf, bufferSize, &pos, &gi, 1, MPITraits::getType(),\n+comm);\n+ 357 ownerVec.push_back(std::make_pair(gi,from));\n+ 358 }\n+ 359 // unpack overlap vertices\n+ 360 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n+getType(), comm);\n+ 361 typename std::set::iterator ipos = overlapVec.begin();\n+ 362 Dune::dverb << \"unpacking \"<::getType(),\n+comm);\n+ 366 ipos=overlapVec.insert(ipos, gi);\n+ 367 }\n+ 368 //unpack neighbors\n+ 369 MPI_Unpack(recvBuf, bufferSize, &pos, &size, 1, MPITraits::\n+getType(), comm);\n+ 370 Dune::dverb << \"unpacking \"<::iterator npos = neighbors.begin();\n+ 372 for(; size!=0; --size) {\n+ 373 int n;\n+ 374 MPI_Unpack(recvBuf, bufferSize, &pos, &n, 1, MPI_INT, comm);\n+ 375 npos=neighbors.insert(npos, n);\n+ 376 }\n+ 377 }\n+ 378\n+ 392 template\n+ 393 void getDomain(const MPI_Comm& comm, T *part, int numOfOwnVtx, int nparts,\n+int *myDomain, std::vector &domainMapping) {\n+ 394 int npes, mype;\n+ 395 MPI_Comm_size(comm, &npes);\n+ 396 MPI_Comm_rank(comm, &mype);\n+ 397 MPI_Status status;\n+ 398\n+ 399 *myDomain = -1;\n+ 400 int i=0;\n+ 401 int j=0;\n 402\n- 403#endif\n-construction.hh\n-Helper classes for the construction of classes without empty constructor.\n-Dune::Amg::Hierarchy::Hierarchy\n-Hierarchy(const Hierarchy &other)\n-Copy constructor (deep copy!).\n-Definition: hierarchy.hh:282\n-Dune::Amg::Hierarchy::addRedistributedOnCoarsest\n-void addRedistributedOnCoarsest(Arguments &args)\n-Definition: hierarchy.hh:328\n-Dune::Amg::Hierarchy::levels\n-std::size_t levels() const\n-Get the number of levels in the hierarchy.\n-Definition: hierarchy.hh:322\n-Dune::Amg::Hierarchy::coarsest\n-ConstIterator coarsest() const\n-Get an iterator positioned at the coarsest level.\n-Definition: hierarchy.hh:395\n-Dune::Amg::Hierarchy::addCoarser\n-void addCoarser(Arguments &args)\n-Add an element on a coarser level.\n-Definition: hierarchy.hh:334\n-Dune::Amg::Hierarchy::addFiner\n-void addFiner(Arguments &args)\n-Add an element on a finer level.\n-Definition: hierarchy.hh:356\n-Dune::Amg::Hierarchy::Hierarchy\n-Hierarchy(const std::shared_ptr< MemberType > &first)\n-Construct a new hierarchy.\n-Definition: hierarchy.hh:270\n-Dune::Amg::ConstructionTraits::Arguments\n-const void * Arguments\n-A type holding all the arguments needed to call the constructor.\n-Definition: construction.hh:44\n-Dune::Amg::ConstructionTraits::construct\n-static std::shared_ptr< T > construct(Arguments &args)\n-Construct an object with the specified arguments.\n-Definition: construction.hh:52\n-Dune::Amg::Hierarchy::coarsest\n-Iterator coarsest()\n-Get an iterator positioned at the coarsest level.\n-Definition: hierarchy.hh:383\n-Dune::Amg::Hierarchy::finest\n-ConstIterator finest() const\n-Get an iterator positioned at the finest level.\n-Definition: hierarchy.hh:389\n-Dune::Amg::Hierarchy::finest\n-Iterator finest()\n-Get an iterator positioned at the finest level.\n-Definition: hierarchy.hh:377\n-std\n-STL namespace.\n+ 403 std::vector domain(nparts, 0);\n+ 404 std::vector assigned(npes, 0);\n+ 405 // init domain Mapping\n+ 406 domainMapping.assign(domainMapping.size(), -1);\n+ 407\n+ 408 // count the occurrence of domains\n+ 409 for (i=0; i domainMatrix(npes * nparts, -1);\n+ 414\n+ 415 // init buffer with the own domain\n+ 416 int *buf = new int[nparts];\n+ 417 for (i=0; i unassigned;\n+ 442\n+ 443 for(i=0; i::iterator next_free = assigned.begin();\n+ 472\n+ 473 for(auto udomain = unassigned.begin(),\n+ 474 end = unassigned.end(); udomain != end; ++udomain)\n+ 475 {\n+ 476 next_free = std::find_if(next_free, assigned.end(), std::bind(std::\n+less(), std::placeholders::_1, 1));\n+ 477 assert(next_free != assigned.end());\n+ 478 domainMapping[*udomain] = next_free-assigned.begin();\n+ 479 *next_free = 1;\n+ 480 }\n+ 481 }\n+ 482\n+ 483 struct SortFirst\n+ 484 {\n+ 485 template\n+ 486 bool operator()(const T& t1, const T& t2) const\n+ 487 {\n+ 488 return t1\n+ 504 void mergeVec(std::vector >& ownerVec, std::set&\n+overlapSet) {\n+ 505\n+ 506#ifdef DEBUG_REPART\n+ 507 // Safety check for duplicates.\n+ 508 if(ownerVec.size()>0)\n+ 509 {\n+ 510 auto old=ownerVec.begin();\n+ 511 for(auto i=old+1, end=ownerVec.end(); i != end; old=i++)\n+ 512 {\n+ 513 if(i->first==old->first)\n+ 514 {\n+ 515 std::cerr<<\"Value at indes\"<first<<\",\"<second<<\"]==[\"\n+ 517 <first<<\",\"<second<<\"]\"<first<*s) ++v;\n+ 529 if(v!=vend && v->first==*s) {\n+ 530 // Move to the next element before erasing\n+ 531 // thus s stays valid!\n+ 532 auto tmp=s;\n+ 533 ++s;\n+ 534 overlapSet.erase(tmp);\n+ 535 }else\n+ 536 ++s;\n+ 537 }\n+ 538 }\n+ 539\n+ 540\n+ 554 template\n+ 555 void getNeighbor(const Graph& g, std::vector& part,\n+ 556 typename Graph::VertexDescriptor vtx, const IS& indexSet,\n+ 557 int toPe, std::set& neighbor, std::set& neighborProcs) {\n+ 558 for(auto edge=g.beginEdges(vtx), end=g.endEdges(vtx); edge!=end; ++edge)\n+ 559 {\n+ 560 const typename IS::IndexPair* pindex = indexSet.pair(edge.target());\n+ 561 assert(pindex);\n+ 562 if(part[pindex->local()]!=toPe || !OwnerSet::contains(pindex->local\n+().attribute()))\n+ 563 {\n+ 564 // is sent to another process and therefore becomes overlap\n+ 565 neighbor.insert(pindex->global());\n+ 566 neighborProcs.insert(part[pindex->local()]);\n+ 567 }\n+ 568 }\n+ 569 }\n+ 570\n+ 571 template\n+ 572 void my_push_back(std::vector& ownerVec, const I& index, [\n+[maybe_unused]] int proc)\n+ 573 {\n+ 574 ownerVec.push_back(index);\n+ 575 }\n+ 576\n+ 577 template\n+ 578 void my_push_back(std::vector >& ownerVec, const I&\n+index, int proc)\n+ 579 {\n+ 580 ownerVec.push_back(std::make_pair(index,proc));\n+ 581 }\n+ 582 template\n+ 583 void reserve(std::vector&, RedistributeInterface&, int)\n+ 584 {}\n+ 585 template\n+ 586 void reserve(std::vector >& ownerVec,\n+RedistributeInterface& redist, int proc)\n+ 587 {\n+ 588 redist.reserveSpaceForReceiveInterface(proc, ownerVec.size());\n+ 589 }\n+ 590\n+ 591\n+ 609 template\n+ 610 void getOwnerOverlapVec(const G& graph, std::vector& part, IS&\n+indexSet,\n+ 611 [[maybe_unused]] int myPe, int toPe, std::vector& ownerVec, std::\n+set& overlapSet,\n+ 612 RedistributeInterface& redist, std::set& neighborProcs) {\n+ 613 for(auto index = indexSet.begin(); index != indexSet.end(); ++index) {\n+ 614 // Only Process owner vertices, the others are not in the parmetis graph.\n+ 615 if(OwnerSet::contains(index->local().attribute()))\n+ 616 {\n+ 617 if(part[index->local()]==toPe)\n+ 618 {\n+ 619 getNeighbor(graph, part, index->local(), indexSet,\n+ 620 toPe, overlapSet, neighborProcs);\n+ 621 my_push_back(ownerVec, index->global(), toPe);\n+ 622 }\n+ 623 }\n+ 624 }\n+ 625 reserve(ownerVec, redist, toPe);\n+ 626\n+ 627 }\n+ 628\n+ 629\n+ 636 template\n+ 637 inline bool isOwner(IS& indexSet, int index) {\n+ 638\n+ 639 const typename IS::IndexPair* pindex=indexSet.pair(index);\n+ 640\n+ 641 assert(pindex);\n+ 642 return F::contains(pindex->local().attribute());\n+ 643 }\n+ 644\n+ 645\n+ 646 class BaseEdgeFunctor\n+ 647 {\n+ 648 public:\n+ 649 BaseEdgeFunctor(Metis::idx_t* adj,const ParmetisDuneIndexMap& data)\n+ 650 : i_(), adj_(adj), data_(data)\n+ 651 {}\n+ 652\n+ 653 template\n+ 654 void operator()(const T& edge)\n+ 655 {\n+ 656 // Get the egde weight\n+ 657 // const Weight& weight=edge.weight();\n+ 658 adj_[i_] = data_.toParmetis(edge.target());\n+ 659 i_++;\n+ 660 }\n+ 661 std::size_t index()\n+ 662 {\n+ 663 return i_;\n+ 664 }\n+ 665\n+ 666 private:\n+ 667 std::size_t i_;\n+ 668 Metis::idx_t* adj_;\n+ 669 const ParmetisDuneIndexMap& data_;\n+ 670 };\n+ 671\n+ 672 template\n+ 673 struct EdgeFunctor\n+ 674 : public BaseEdgeFunctor\n+ 675 {\n+ 676 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::\n+size_t)\n+ 677 : BaseEdgeFunctor(adj, data)\n+ 678 {}\n+ 679\n+ 680 Metis::idx_t* getWeights()\n+ 681 {\n+ 682 return NULL;\n+ 683 }\n+ 684 void free(){}\n+ 685 };\n+ 686\n+ 687 template\n+ 688 class EdgeFunctor >\n+ 689 : public BaseEdgeFunctor\n+ 690 {\n+ 691 public:\n+ 692 EdgeFunctor(Metis::idx_t* adj, const ParmetisDuneIndexMap& data, std::\n+size_t s)\n+ 693 : BaseEdgeFunctor(adj, data)\n+ 694 {\n+ 695 weight_=new Metis::idx_t[s];\n+ 696 }\n+ 697\n+ 698 template\n+ 699 void operator()(const T& edge)\n+ 700 {\n+ 701 weight_[index()]=edge.properties().depends() ? 3 : 1;\n+ 702 BaseEdgeFunctor::operator()(edge);\n+ 703 }\n+ 704 Metis::idx_t* getWeights()\n+ 705 {\n+ 706 return weight_;\n+ 707 }\n+ 708 void free(){\n+ 709 if(weight_!=0) {\n+ 710 delete weight_;\n+ 711 weight_=0;\n+ 712 }\n+ 713 }\n+ 714 private:\n+ 715 Metis::idx_t* weight_;\n+ 716 };\n+ 717\n+ 718\n+ 719\n+ 733 template\n+ 734 void getAdjArrays(G& graph, IS& indexSet, Metis::idx_t *xadj,\n+ 735 EW& ew)\n+ 736 {\n+ 737 int j=0;\n+ 738 auto vend = graph.end();\n+ 739\n+ 740 for(auto vertex = graph.begin(); vertex != vend; ++vertex) {\n+ 741 if (isOwner(indexSet,*vertex)) {\n+ 742 // The type of const edge iterator.\n+ 743 auto eend = vertex.end();\n+ 744 xadj[j] = ew.index();\n+ 745 j++;\n+ 746 for(auto edge = vertex.begin(); edge != eend; ++edge) {\n+ 747 ew(edge);\n+ 748 }\n+ 749 }\n+ 750 }\n+ 751 xadj[j] = ew.index();\n+ 752 }\n+ 753 } // end anonymous namespace\n+ 754\n+ 755 template\n+ 756 bool buildCommunication(const G& graph, std::vector& realparts,\n+ 757 Dune::OwnerOverlapCopyCommunication& oocomm,\n+ 758 std::shared_ptr>& outcomm,\n+ 759 RedistributeInterface& redistInf,\n+ 760 bool verbose=false);\n+ 761#if HAVE_PARMETIS\n+ 762#ifndef METIS_VER_MAJOR\n+ 763 extern \"C\"\n+ 764 {\n+ 765 // backwards compatibility to parmetis < 4.0.0\n+ 766 void METIS_PartGraphKway(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t\n+*adjncy, Metis::idx_t *vwgt,\n+ 767 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,\n+ 768 int *options, int *edgecut, Metis::idx_t *part);\n+ 769\n+ 770 void METIS_PartGraphRecursive(int *nvtxs, Metis::idx_t *xadj, Metis::idx_t\n+*adjncy, Metis::idx_t *vwgt,\n+ 771 Metis::idx_t *adjwgt, int *wgtflag, int *numflag, int *nparts,\n+ 772 int *options, int *edgecut, Metis::idx_t *part);\n+ 773 }\n+ 774#endif\n+ 775#endif // HAVE_PARMETIS\n+ 776\n+ 777 template\n+778 inline void print_carray(S& os, T* array, std::size_t l)\n+ 779 {\n+ 780 for(T *cur=array, *end=array+l; cur!=end; ++cur)\n+ 781 os<<*cur<<\" \";\n+ 782 }\n+ 783\n+ 784 template\n+785 inline bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges,\n+T* xadj,\n+ 786 T* adjncy, bool checkSymmetry)\n+ 787 {\n+ 788 bool correct=true;\n+ 789\n+ 790 using std::signbit;\n+ 791 for(Metis::idx_t vtx=0; vtx<(Metis::idx_t)noVtx; ++vtx) {\n+ 792 if(static_cast(xadj[vtx])>noEdges || signbit(xadj[vtx])) {\n+ 793 std::cerr <<\"Check graph: xadj[\"<\"\n+ 794 <(xadj[vtx+1])>noEdges || signbit(xadj[vtx+1])) {\n+ 798 std::cerr <<\"Check graph: xadj[\"<\"\n+ 799 <gnoVtx) {\n+ 805 std::cerr<<\" Edge \"<\n+829 bool commGraphRepartition(const M& mat, Dune::\n+OwnerOverlapCopyCommunication& oocomm,\n+ 830 Metis::idx_t nparts,\n+ 831 std::shared_ptr>& outcomm,\n+ 832 RedistributeInterface& redistInf,\n+ 833 bool verbose=false)\n+ 834 {\n+ 835 if(verbose && oocomm.communicator().rank()==0)\n+ 836 std::cout<<\"Repartitioning from \"<1) {\n+ 847\n+ 848 part[0]=rank;\n+ 849\n+ 850 { // sublock for automatic memory deletion\n+ 851\n+ 852 // Build the graph of the communication scheme and create an appropriate\n+indexset.\n+ 853 // calculate the neighbour vertices\n+ 854 int noNeighbours = oocomm.remoteIndices().neighbours();\n+ 855\n+ 856 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices\n+().end();\n+ 857 ++n)\n+ 858 if(n->first==rank) {\n+ 859 //do not include ourselves.\n+ 860 --noNeighbours;\n+ 861 break;\n+ 862 }\n+ 863\n+ 864 // A parmetis graph representing the communication graph.\n+ 865 // The diagonal entries are the number of nodes on the process.\n+ 866 // The offdiagonal entries are the number of edges leading to other\n+processes.\n+ 867\n+ 868 Metis::idx_t *xadj=new Metis::idx_t[2];\n+ 869 Metis::idx_t *vtxdist=new Metis::idx_t[oocomm.communicator().size()+1];\n+ 870 Metis::idx_t *adjncy=new Metis::idx_t[noNeighbours];\n+ 871#ifdef USE_WEIGHTS\n+ 872 Metis::idx_t *vwgt = 0;\n+ 873 Metis::idx_t *adjwgt = 0;\n+ 874#endif\n+ 875\n+ 876 // each process has exactly one vertex!\n+ 877 for(int i=0; i owner(mat.N(), oocomm.communicator().rank());\n+ 887 // for(NeighbourIterator n= oocomm.remoteIndices().begin(); n !=\n+oocomm.remoteIndices().end();\n+ 888 // ++n)\n+ 889 // {\n+ 890 // if(n->first!=oocomm.communicator().rank()){\n+ 891 // typedef typename RemoteIndices::RemoteIndexList RIList;\n+ 892 // const RIList& rlist = *(n->second.first);\n+ 893 // typedef typename RIList::const_iterator LIter;\n+ 894 // for(LIter entry=rlist.begin(); entry!=rlist.end(); ++entry){\n+ 895 // if(entry->attribute()==OwnerOverlapCopyAttributeSet::owner)\n+ 896 // owner[entry->localIndexPair().local()] = n->first;\n+ 897 // }\n+ 898 // }\n+ 899 // }\n+ 900\n+ 901 // std::map edgecount; // edges to other processors\n+ 902 // typedef typename M::ConstRowIterator RIter;\n+ 903 // typedef typename M::ConstColIterator CIter;\n+ 904\n+ 905 // // calculate edge count\n+ 906 // for(RIter row=mat.begin(), endr=mat.end(); row != endr; ++row)\n+ 907 // if(owner[row.index()]==OwnerOverlapCopyAttributeSet::owner)\n+ 908 // for(CIter entry= row->begin(), ende = row->end(); entry != ende;\n+++entry)\n+ 909 // ++edgecount[owner[entry.index()]];\n+ 910\n+ 911 // setup edge and weight pattern\n+ 912\n+ 913 Metis::idx_t* adjp=adjncy;\n+ 914\n+ 915#ifdef USE_WEIGHTS\n+ 916 vwgt = new Metis::idx_t[1];\n+ 917 vwgt[0]= mat.N(); // weight is numer of rows TODO: Should actually be the\n+nonzeros.\n+ 918\n+ 919 adjwgt = new Metis::idx_t[noNeighbours];\n+ 920 Metis::idx_t* adjwp=adjwgt;\n+ 921#endif\n+ 922\n+ 923 for(auto n= oocomm.remoteIndices().begin(); n != oocomm.remoteIndices\n+().end();\n+ 924 ++n)\n+ 925 if(n->first != rank) {\n+ 926 *adjp=n->first;\n+ 927 ++adjp;\n+ 928#ifdef USE_WEIGHTS\n+ 929 *adjwp=1; //edgecount[n->first];\n+ 930 ++adjwp;\n+ 931#endif\n+ 932 }\n+ 933 assert(isValidGraph(vtxdist[rank+1]-vtxdist[rank],\n+ 934 vtxdist[oocomm.communicator().size()],\n+ 935 noNeighbours, xadj, adjncy, false));\n+ 936\n+ 937 [[maybe_unused]] Metis::idx_t wgtflag=0;\n+ 938 Metis::idx_t numflag=0;\n+ 939 Metis::idx_t edgecut;\n+ 940#ifdef USE_WEIGHTS\n+ 941 wgtflag=3;\n+ 942#endif\n+ 943 Metis::real_t *tpwgts = new Metis::real_t[nparts];\n+ 944 for(int i=0; i::getType(),\n+ 1071 gxadj,noxs,xdispl,MPITraits::getType(),\n+ 1072 comm);\n+ 1073 MPI_Allgatherv(adjncy,noNeighbours,MPITraits::getType(),\n+ 1074 gadjncy,noedges,displ,MPITraits::getType(),\n+ 1075 comm);\n+ 1076#ifdef USE_WEIGHTS\n+ 1077 MPI_Allgatherv(adjwgt,noNeighbours,MPITraits::getType(),\n+ 1078 gadjwgt,noedges,displ,MPITraits::getType(),\n+ 1079 comm);\n+ 1080 MPI_Allgatherv(vwgt,localNoVtx,MPITraits::getType(),\n+ 1081 gvwgt,novs,vdispl,MPITraits::getType(),\n+ 1082 comm);\n+ 1083#endif\n+ 1084 if(verbose && oocomm.communicator().rank()==0)\n+ 1085 std::cout<<\"Gathering global graph data took \"<(gxadjlen));\n+ 1103 increment = *(start-1);\n+ 1104 std::transform(start+offset, start+l+offset, start, std::bind(std::\n+plus(), std::placeholders::_1, increment));\n+ 1105 }\n+ 1106 Dune::dinfo<= 5\n+ 1130 Metis::idx_t ncon = 1;\n+ 1131 Metis::idx_t moptions[METIS_NOPTIONS];\n+ 1132 METIS_SetDefaultOptions(moptions);\n+ 1133 moptions[METIS_OPTION_NUMBERING] = numflag;\n+ 1134 METIS_PartGraphRecursive(&noVertices, &ncon, gxadj, gadjncy, gvwgt, NULL,\n+gadjwgt,\n+ 1135 &nparts, NULL, NULL, moptions, &edgecut, gpart);\n+ 1136#else\n+ 1137 int options[5] = {0, 1, 1, 3, 3};\n+ 1138 // Call metis\n+ 1139 METIS_PartGraphRecursive(&noVertices, gxadj, gadjncy, gvwgt, gadjwgt,\n+&wgtflag,\n+ 1140 &numflag, &nparts, options, &edgecut, gpart);\n+ 1141#endif\n+ 1142\n+ 1143 if(verbose && oocomm.communicator().rank()==0)\n+ 1144 std::cout<<\"METIS took \"<::getType(), part, 1,\n+ 1159 MPITraits::getType(), 0, comm);\n+ 1160\n+ 1161 {\n+ 1162 // release remaining memory\n+ 1163 delete[] gpart;\n+ 1164 delete[] noedges;\n+ 1165 delete[] displ;\n+ 1166 }\n+ 1167\n+ 1168\n+ 1169#endif\n+ 1170 delete[] xadj;\n+ 1171 delete[] vtxdist;\n+ 1172 delete[] adjncy;\n+ 1173#ifdef USE_WEIGHTS\n+ 1174 delete[] vwgt;\n+ 1175 delete[] adjwgt;\n+ 1176#endif\n+ 1177 delete[] tpwgts;\n+ 1178 }\n+ 1179 }else{\n+ 1180 part[0]=0;\n+ 1181 }\n+ 1182#endif\n+ 1183 Dune::dinfo<<\" repart \"< \"<< part[0]< realpart(mat.N(), part[0]);\n+ 1186 delete[] part;\n+ 1187\n+ 1188 oocomm.copyOwnerToAll(realpart, realpart);\n+ 1189\n+ 1190 if(verbose && oocomm.communicator().rank()==0)\n+ 1191 std::cout<<\"Scattering repartitioning took \"< graph(const_cast(mat));\n+ 1197 fillIndexSetHoles(graph, oocomm);\n+ 1198 if(verbose && oocomm.communicator().rank()==0)\n+ 1199 std::cout<<\"Filling index set took \"<\n+1235 bool graphRepartition(const G& graph, Dune::\n+OwnerOverlapCopyCommunication& oocomm, Metis::idx_t nparts,\n+ 1236 std::shared_ptr>& outcomm,\n+ 1237 RedistributeInterface& redistInf,\n+ 1238 bool verbose=false)\n+ 1239 {\n+ 1240 Timer time;\n+ 1241\n+ 1242 MPI_Comm comm=oocomm.communicator();\n+ 1243 oocomm.buildGlobalLookup(graph.noVertices());\n+ 1244 fillIndexSetHoles(graph, oocomm);\n+ 1245\n+ 1246 if(verbose && oocomm.communicator().rank()==0)\n+ 1247 std::cout<<\"Filling holes took \"<(oocomm.communicator().size()));\n+ 1262\n+ 1263 int myDomain = -1;\n+ 1264\n+ 1265 //\n+ 1266 // 1) Prepare the required parameters for using ParMETIS\n+ 1267 // Especially the arrays that represent the graph must be\n+ 1268 // generated by the DUNE Graph and IndexSet input variables.\n+ 1269 // These are the arrays:\n+ 1270 // - vtxdist\n+ 1271 // - xadj\n+ 1272 // - adjncy\n+ 1273 //\n+ 1274 //\n+ 1275#ifdef PERF_REPART\n+ 1276 // reset timer for step 1)\n+ 1277 t1=MPI_Wtime();\n+ 1278#endif\n+ 1279\n+ 1280\n+ 1281 typedef typename Dune::OwnerOverlapCopyCommunication OOComm;\n+ 1282 typedef typename OOComm::OwnerSet OwnerSet;\n+ 1283\n+ 1284 // Create the vtxdist array and parmetisVtxMapping.\n+ 1285 // Global communications are necessary\n+ 1286 // The parmetis global identifiers for the owner vertices.\n+ 1287 ParmetisDuneIndexMap indexMap(graph,oocomm);\n+ 1288 Metis::idx_t *part = new Metis::idx_t[indexMap.numOfOwnVtx()];\n+ 1289 for(std::size_t i=0; i < indexMap.numOfOwnVtx(); ++i)\n+ 1290 part[i]=mype;\n+ 1291\n+ 1292#if !HAVE_PARMETIS\n+ 1293 if(oocomm.communicator().rank()==0 && nparts>1)\n+ 1294 std::cerr<<\"ParMETIS not activated. Will repartition to 1 domain instead\n+of requested \"\n+ 1295 <1) {\n+ 1301 // Create the xadj and adjncy arrays\n+ 1302 Metis::idx_t *xadj = new Metis::idx_t[indexMap.numOfOwnVtx()+1];\n+ 1303 Metis::idx_t *adjncy = new Metis::idx_t[graph.noEdges()];\n+ 1304 EdgeFunctor ef(adjncy, indexMap, graph.noEdges());\n+ 1305 getAdjArrays(graph, oocomm.globalLookup(), xadj, ef);\n+ 1306\n+ 1307 //\n+ 1308 // 2) Call ParMETIS\n+ 1309 //\n+ 1310 //\n+ 1311 Metis::idx_t numflag=0, wgtflag=0, options[3], edgecut=0, ncon=1;\n+ 1312 //float *tpwgts = NULL;\n+ 1313 Metis::real_t *tpwgts = new Metis::real_t[nparts];\n+ 1314 for(int i=0; i(comm));\n+ 1358\n+ 1359\n+ 1360 delete[] xadj;\n+ 1361 delete[] adjncy;\n+ 1362 delete[] tpwgts;\n+ 1363\n+ 1364 ef.free();\n+ 1365\n+ 1366#ifdef DEBUG_REPART\n+ 1367 if (mype == 0) {\n+ 1368 std::cout< domainMapping(nparts);\n+ 1410 if(nparts>1)\n+ 1411 getDomain(comm, part, indexMap.numOfOwnVtx(), nparts, &myDomain,\n+domainMapping);\n+ 1412 else\n+ 1413 domainMapping[0]=0;\n+ 1414\n+ 1415#ifdef DEBUG_REPART\n+ 1416 std::cout< setPartition(oocomm.indexSet().size(), -1);\n+ 1429\n+ 1430 std::size_t i=0; // parmetis index\n+ 1431 for(auto index = oocomm.indexSet().begin(); index != oocomm.indexSet\n+().end(); ++index)\n+ 1432 if(OwnerSet::contains(index->local().attribute())) {\n+ 1433 setPartition[index->local()]=domainMapping[part[i++]];\n+ 1434 }\n+ 1435\n+ 1436 delete[] part;\n+ 1437 oocomm.copyOwnerToAll(setPartition, setPartition);\n+ 1438 // communication only needed for ALU\n+ 1439 // (ghosts with same global id as owners on the same process)\n+ 1440 if (SolverCategory::category(oocomm) ==\n+ 1441 static_cast(SolverCategory::nonoverlapping))\n+ 1442 oocomm.copyCopyToAll(setPartition, setPartition);\n+ 1443 bool ret = buildCommunication(graph, setPartition, oocomm, outcomm,\n+redistInf,\n+ 1444 verbose);\n+ 1445 if(verbose) {\n+ 1446 oocomm.communicator().barrier();\n+ 1447 if(oocomm.communicator().rank()==0)\n+ 1448 std::cout<<\"Creating indexsets took \"<\n+1456 bool buildCommunication(const G& graph,\n+ 1457 std::vector& setPartition, Dune::\n+OwnerOverlapCopyCommunication& oocomm,\n+ 1458 std::shared_ptr>& outcomm,\n+ 1459 RedistributeInterface& redistInf,\n+ 1460 bool verbose)\n+ 1461 {\n+ 1462 typedef typename Dune::OwnerOverlapCopyCommunication OOComm;\n+ 1463 typedef typename OOComm::OwnerSet OwnerSet;\n+ 1464\n+ 1465 Timer time;\n+ 1466\n+ 1467 // Build the send interface\n+ 1468 redistInf.buildSendInterface(setPartition, oocomm.indexSet());\n+ 1469\n+ 1470#ifdef PERF_REPART\n+ 1471 // stop the time for step 3)\n+ 1472 t3=MPI_Wtime()-t3;\n+ 1473 // reset timer for step 4)\n+ 1474 t4=MPI_Wtime();\n+ 1475#endif\n+ 1476\n+ 1477\n+ 1478 //\n+ 1479 // 4) Create the output IndexSet and RemoteIndices\n+ 1480 // 4.1) Determine the \"send to\" and \"receive from\" relation\n+ 1481 // according to the new partition using a MPI ring\n+ 1482 // communication.\n+ 1483 //\n+ 1484 // 4.2) Depends on the \"send to\" and \"receive from\" vector,\n+ 1485 // the processes will exchange the vertices each other\n+ 1486 //\n+ 1487 // 4.3) Create the IndexSet, RemoteIndices and the new MPI\n+ 1488 // communicator\n+ 1489 //\n+ 1490\n+ 1491 //\n+ 1492 // 4.1) Let's start...\n+ 1493 //\n+ 1494 int npes = oocomm.communicator().size();\n+ 1495 int *sendTo = 0;\n+ 1496 int noSendTo = 0;\n+ 1497 std::set recvFrom;\n+ 1498\n+ 1499 // the max number of vertices is stored in the sendTo buffer,\n+ 1500 // not the number of vertices to send! Because the max number of Vtx\n+ 1501 // is used as the fixed buffer size by the MPI send/receive calls\n+ 1502\n+ 1503 int mype = oocomm.communicator().rank();\n+ 1504\n+ 1505 {\n+ 1506 std::set tsendTo;\n+ 1507 for(auto i=setPartition.begin(), iend = setPartition.end(); i!=iend; ++i)\n+ 1508 tsendTo.insert(*i);\n+ 1509\n+ 1510 noSendTo = tsendTo.size();\n+ 1511 sendTo = new int[noSendTo];\n+ 1512 int idx=0;\n+ 1513 for(auto i=tsendTo.begin(); i != tsendTo.end(); ++i, ++idx)\n+ 1514 sendTo[idx]=*i;\n+ 1515 }\n+ 1516\n+ 1517 //\n+ 1518 int* gnoSend= new int[oocomm.communicator().size()];\n+ 1519 int* gsendToDispl = new int[oocomm.communicator().size()+1];\n+ 1520\n+ 1521 MPI_Allgather(&noSendTo, 1, MPI_INT, gnoSend, 1,\n+ 1522 MPI_INT, oocomm.communicator());\n+ 1523\n+ 1524 // calculate total receive message size\n+ 1525 int totalNoRecv = 0;\n+ 1526 for(int i=0; i0;\n+ 1547\n+ 1548 // Delete memory\n+ 1549 delete[] gnoSend;\n+ 1550 delete[] gsendToDispl;\n+ 1551 delete[] gsendTo;\n+ 1552\n+ 1553\n+ 1554#ifdef DEBUG_REPART\n+ 1555 if(recvFrom.size()) {\n+ 1556 std::cout< GlobalVector;\n+ 1589 std::vector > myOwnerVec;\n+ 1590 std::set myOverlapSet;\n+ 1591 GlobalVector sendOwnerVec;\n+ 1592 std::set sendOverlapSet;\n+ 1593 std::set myNeighbors;\n+ 1594\n+ 1595 // getOwnerOverlapVec(graph, setPartition, oocomm.globalLookup\n+(),\n+ 1596 // mype, mype, myOwnerVec, myOverlapSet, redistInf, myNeighbors);\n+ 1597\n+ 1598 char **sendBuffers=new char*[noSendTo];\n+ 1599 MPI_Request *requests = new MPI_Request[noSendTo];\n+ 1600\n+ 1601 // Create all messages to be sent\n+ 1602 for(int i=0; i < noSendTo; ++i) {\n+ 1603 // clear the vector for sending\n+ 1604 sendOwnerVec.clear();\n+ 1605 sendOverlapSet.clear();\n+ 1606 // get all owner and overlap vertices for process j and save these\n+ 1607 // in the vectors sendOwnerVec and sendOverlapSet\n+ 1608 std::set neighbors;\n+ 1609 getOwnerOverlapVec(graph, setPartition, oocomm.globalLookup(),\n+ 1610 mype, sendTo[i], sendOwnerVec, sendOverlapSet, redistInf,\n+ 1611 neighbors);\n+ 1612 // +2, we need 2 integer more for the length of each part\n+ 1613 // (owner/overlap) of the array\n+ 1614 int buffersize=0;\n+ 1615 int tsize;\n+ 1616 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n+(), &buffersize);\n+ 1617 MPI_Pack_size(sendOwnerVec.size(), MPITraits::getType(),\n+oocomm.communicator(), &tsize);\n+ 1618 buffersize +=tsize;\n+ 1619 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n+(), &tsize);\n+ 1620 buffersize +=tsize;\n+ 1621 MPI_Pack_size(sendOverlapSet.size(), MPITraits::getType(),\n+oocomm.communicator(), &tsize);\n+ 1622 buffersize += tsize;\n+ 1623 MPI_Pack_size(1, MPITraits::getType(), oocomm.communicator\n+(), &tsize);\n+ 1624 buffersize += tsize;\n+ 1625 MPI_Pack_size(neighbors.size(), MPI_INT, oocomm.communicator(), &tsize);\n+ 1626 buffersize += tsize;\n+ 1627\n+ 1628 sendBuffers[i] = new char[buffersize];\n+ 1629\n+ 1630#ifdef DEBUG_REPART\n+ 1631 std::cout<0) {\n+ 1651 // probe for an incoming message\n+ 1652 MPI_Status stat;\n+ 1653 MPI_Probe(MPI_ANY_SOURCE, 99, oocomm.communicator(), &stat);\n+ 1654 int buffersize;\n+ 1655 MPI_Get_count(&stat, MPI_PACKED, &buffersize);\n+ 1656\n+ 1657 if(oldbuffersize(outputComm,SolverCategory::category\n+(oocomm),true);\n+ 1727\n+ 1728 // translate neighbor ranks.\n+ 1729 int newrank=outcomm->communicator().rank();\n+ 1730 int *newranks=new int[oocomm.communicator().size()];\n+ 1731 std::vector tneighbors;\n+ 1732 tneighbors.reserve(myNeighbors.size());\n+ 1733\n+ 1734 typename OOComm::ParallelIndexSet& outputIndexSet = outcomm->indexSet();\n+ 1735\n+ 1736 MPI_Allgather(&newrank, 1, MPI_INT, newranks, 1,\n+ 1737 MPI_INT, oocomm.communicator());\n+ 1738\n+ 1739#ifdef DEBUG_REPART\n+ 1740 std::cout<=0);\n+ 1744 std::cout<<*i<<\"->\"<first,LocalIndexT(i, OwnerOverlapCopyAttributeSet::\n+owner, true));\n+ 1777 redistInf.addReceiveIndex(g->second, i);\n+ 1778 }\n+ 1779\n+ 1780 if(verbose) {\n+ 1781 oocomm.communicator().barrier();\n+ 1782 if(oocomm.communicator().rank()==0)\n+ 1783 std::cout<<\" Adding owner indices took \"<<\n+ 1784 time.elapsed()<local().attribute())) {\n+ 1820 numOfOwnVtx++;\n+ 1821 }\n+ 1822 }\n+ 1823 numOfOwnVtx = oocomm.communicator().sum(numOfOwnVtx);\n+ 1824 // if(numOfOwnVtx!=indexMap.globalOwnerVertices)\n+ 1825 // {\n+ 1826 // std::cerr<remoteIndices().setNeighbours(tneighbors);\n+ 1844 outcomm->remoteIndices().template rebuild();\n+ 1845\n+ 1846 }\n+ 1847\n+ 1848 // release the memory\n+ 1849 delete[] sendTo;\n+ 1850\n+ 1851 if(verbose) {\n+ 1852 oocomm.communicator().barrier();\n+ 1853 if(oocomm.communicator().rank()==0)\n+ 1854 std::cout<<\" Storing indexsets took \"<<\n+ 1855 time.elapsed()<\n+ 1876 bool graphRepartition(const G& graph, P& oocomm, int nparts,\n+ 1877 std::shared_ptr

    & outcomm,\n+ 1878 R& redistInf,\n+ 1879 bool v=false)\n+ 1880 {\n+ 1881 if(nparts!=oocomm.size())\n+ 1882 DUNE_THROW(NotImplemented, \"only available for MPI programs\");\n+ 1883 }\n+ 1884\n+ 1885\n+ 1886 template\n+ 1887 bool commGraphRepartition(const G& graph, P& oocomm, int nparts,\n+ 1888 std::shared_ptr

    & outcomm,\n+ 1889 R& redistInf,\n+ 1890 bool v=false)\n+ 1891 {\n+ 1892 if(nparts!=oocomm.size())\n+ 1893 DUNE_THROW(NotImplemented, \"only available for MPI programs\");\n+ 1894 }\n+ 1895#endif // HAVE_MPI\n+ 1896} // end of namespace Dune\n+ 1897#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+globalOwnerVertices\n+int globalOwnerVertices\n+Definition: repartition.hh:175\n+graph.hh\n+Provides classes for building the matrix graph.\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::Hierarchy\n-A hierarchy of containers (e.g. matrices or vectors)\n-Definition: hierarchy.hh:40\n-Dune::Amg::Hierarchy::MemberType\n-T MemberType\n-The type of the container we store.\n-Definition: hierarchy.hh:45\n-Dune::Amg::Hierarchy::Iterator\n-LevelIterator< Hierarchy< T, A >, T > Iterator\n-Type of the mutable iterator.\n-Definition: hierarchy.hh:216\n-Dune::Amg::Hierarchy::ConstIterator\n-LevelIterator< const Hierarchy< T, A >, const T > ConstIterator\n-Type of the const iterator.\n-Definition: hierarchy.hh:219\n-Dune::Amg::Hierarchy::Arguments\n-ConstructionTraits< T >::Arguments Arguments\n-Definition: hierarchy.hh:78\n-Dune::Amg::Hierarchy::Hierarchy\n-Hierarchy()\n-Construct an empty hierarchy.\n-Definition: hierarchy.hh:89\n-Dune::Amg::Hierarchy::Allocator\n-typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator\n-The allocator to use for the list elements.\n-Definition: hierarchy.hh:76\n-Dune::Amg::Hierarchy::LevelIterator\n-Iterator over the levels in the hierarchy.\n-Definition: hierarchy.hh:120\n-Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n-LevelIterator(const LevelIterator< typename std::remove_const< C >::type,\n-typename std::remove_const< T1 >::type > &other)\n-Copy constructor.\n-Definition: hierarchy.hh:136\n-Dune::Amg::Hierarchy::LevelIterator::addRedistributed\n-void addRedistributed(std::shared_ptr< T1 > t)\n-Definition: hierarchy.hh:201\n-Dune::Amg::Hierarchy::LevelIterator::dereference\n-T1 & dereference() const\n-Dereference the iterator.\n-Definition: hierarchy.hh:166\n-Dune::Amg::Hierarchy::LevelIterator::equals\n-bool equals(const LevelIterator< typename std::remove_const< C >::type,\n-typename std::remove_const< T1 >::type > &other) const\n-Equality check.\n-Definition: hierarchy.hh:150\n-Dune::Amg::Hierarchy::LevelIterator::isRedistributed\n-bool isRedistributed() const\n-Check whether there was a redistribution at the current level.\n-Definition: hierarchy.hh:187\n-Dune::Amg::Hierarchy::LevelIterator::equals\n-bool equals(const LevelIterator< const typename std::remove_const< C >::type,\n-const typename std::remove_const< T1 >::type > &other) const\n-Equality check.\n-Definition: hierarchy.hh:159\n-Dune::Amg::Hierarchy::LevelIterator::increment\n-void increment()\n-Move to the next coarser level.\n-Definition: hierarchy.hh:172\n-Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n-LevelIterator(const LevelIterator< const typename std::remove_const< C >::type,\n-const typename std::remove_const< T1 >::type > &other)\n-Copy constructor.\n-Definition: hierarchy.hh:142\n-Dune::Amg::Hierarchy::LevelIterator::deleteRedistributed\n-void deleteRedistributed()\n-Definition: hierarchy.hh:206\n-Dune::Amg::Hierarchy::LevelIterator::decrement\n-void decrement()\n-Move to the next fine level.\n-Definition: hierarchy.hh:178\n-Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n-LevelIterator(std::shared_ptr< Element > element)\n-Definition: hierarchy.hh:131\n-Dune::Amg::Hierarchy::LevelIterator::getRedistributed\n-T1 & getRedistributed() const\n-Get the redistributed container.\n-Definition: hierarchy.hh:196\n+Dune::buildCommunication\n+bool buildCommunication(const G &graph, std::vector< int > &realparts, Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > &oocomm, std::shared_ptr< Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n+&redistInf, bool verbose=false)\n+Definition: repartition.hh:1456\n+Dune::fillIndexSetHoles\n+void fillIndexSetHoles(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n+T2 > &oocomm)\n+Fills the holes in an index set.\n+Definition: repartition.hh:83\n+Dune::commGraphRepartition\n+bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication<\n+T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n+&redistInf, bool verbose=false)\n+Definition: repartition.hh:829\n+Dune::print_carray\n+void print_carray(S &os, T *array, std::size_t l)\n+Definition: repartition.hh:778\n+Dune::isValidGraph\n+bool isValidGraph(std::size_t noVtx, std::size_t gnoVtx, S noEdges, T *xadj, T\n+*adjncy, bool checkSymmetry)\n+Definition: repartition.hh:785\n+Dune::graphRepartition\n+bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n+T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n+&redistInf, bool verbose=false)\n+execute a graph repartition for a giving graph and indexset.\n+Definition: repartition.hh:1235\n+Dune::Metis::real_t\n+float real_t\n+Definition: repartition.hh:53\n+Dune::Metis::idx_t\n+std::size_t idx_t\n+Definition: repartition.hh:63\n+Dune::OwnerOverlapCopyAttributeSet::owner\n+@ owner\n+Definition: owneroverlapcopy.hh:61\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::globalLookup\n+const GlobalLookupIndexSet & globalLookup() const\n+Definition: owneroverlapcopy.hh:526\n+Dune::OwnerOverlapCopyCommunication::indexSet\n+const ParallelIndexSet & indexSet() const\n+Get the underlying parallel index set.\n+Definition: owneroverlapcopy.hh:462\n+Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n+void copyCopyToAll(const T &source, T &dest) const\n+Communicate values from copy data points to all other data points.\n+Definition: owneroverlapcopy.hh:328\n+Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n+Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n+The type of the reverse lookup of indices.\n+Definition: owneroverlapcopy.hh:456\n+Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n+void buildGlobalLookup()\n+Definition: owneroverlapcopy.hh:495\n+Dune::OwnerOverlapCopyCommunication::communicator\n+const Communication< MPI_Comm > & communicator() const\n+Definition: owneroverlapcopy.hh:299\n+Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n+void copyOwnerToAll(const T &source, T &dest) const\n+Communicate values from owner data points to all other data points.\n+Definition: owneroverlapcopy.hh:311\n+Dune::OwnerOverlapCopyCommunication::remoteIndices\n+const RemoteIndices & remoteIndices() const\n+Get the underlying remote indices.\n+Definition: owneroverlapcopy.hh:471\n+Dune::OwnerOverlapCopyCommunication::freeGlobalLookup\n+void freeGlobalLookup()\n+Definition: owneroverlapcopy.hh:520\n+Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n+Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n+The type of the parallel index set.\n+Definition: owneroverlapcopy.hh:449\n+Dune::Amg::MatrixGraph\n+The (undirected) graph of a matrix.\n+Definition: graph.hh:51\n+Dune::RedistributeInterface\n+Definition: repartition.hh:260\n+Dune::RedistributeInterface::reserveSpaceForReceiveInterface\n+void reserveSpaceForReceiveInterface(int proc, int size)\n+Definition: repartition.hh:284\n+Dune::RedistributeInterface::buildReceiveInterface\n+void buildReceiveInterface(std::vector< std::pair< TG, int > > &indices)\n+Definition: repartition.hh:293\n+Dune::RedistributeInterface::~RedistributeInterface\n+~RedistributeInterface()\n+Definition: repartition.hh:301\n+Dune::RedistributeInterface::setCommunicator\n+void setCommunicator(MPI_Comm comm)\n+Definition: repartition.hh:261\n+Dune::RedistributeInterface::buildSendInterface\n+void buildSendInterface(const std::vector< int > &toPart, const IS &idxset)\n+Definition: repartition.hh:266\n+Dune::RedistributeInterface::addReceiveIndex\n+void addReceiveIndex(int proc, std::size_t idx)\n+Definition: repartition.hh:288\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00113.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00113.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: twolevelmethod.hh File Reference\n+dune-istl: allocator.hh File Reference\n \n \n \n \n \n \n \n@@ -58,59 +58,56 @@\n \n \n \n

    \n \n \n+
    allocator.hh File Reference
    \n \n
    \n-\n-

    Algebraic twolevel methods. \n-More...

    \n-
    #include <tuple>
    \n-#include <dune/istl/operators.hh>
    \n-#include "amg.hh"
    \n-#include "galerkin.hh"
    \n-#include <dune/istl/solver.hh>
    \n+
    #include <memory>
    \n+#include <type_traits>
    \n+#include <dune/common/typetraits.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n+\n \n

    \n Classes

    class  Dune::Amg::LevelTransferPolicy< FO, CO >
     Abstract base class for transfer between levels and creation of the coarse level system. More...
    struct  Dune::exists< T >
     
    class  Dune::Amg::AggregationLevelTransferPolicy< O, C >
     A LeveTransferPolicy that used aggregation to construct the coarse level system. More...
    struct  Dune::DefaultAllocatorTraits< T, typename >
     
    class  Dune::Amg::OneStepAMGCoarseSolverPolicy< O, S, C >
     A policy class for solving the coarse level system using one step of AMG. More...
    struct  Dune::DefaultAllocatorTraits< T, std::void_t< typename T::allocator_type > >
     
    class  Dune::Amg::TwoLevelMethod< FO, CSP, S >
    struct  Dune::AllocatorTraits< T >
     
    \n \n \n \n-\n-\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n+\n+\n+\n

    \n+Typedefs

    template<typename T >
    using Dune::AllocatorType = typename AllocatorTraits< T >::type
     
    template<typename T , typename X >
    using Dune::ReboundAllocatorType = typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X >
     
    \n-

    Detailed Description

    \n-

    Algebraic twolevel methods.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,46 +4,37 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces\n-twolevelmethod.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Algebraic twolevel methods. More...\n-#include \n-#include \n-#include \"amg.hh\"\n-#include \"galerkin.hh\"\n-#include \n+Classes | Namespaces | Typedefs\n+allocator.hh File Reference\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::LevelTransferPolicy<_FO,_CO_>\n-\u00a0 Abstract base class for transfer between levels and creation of the\n- coarse level system. More...\n-\u00a0\n-class \u00a0Dune::Amg::AggregationLevelTransferPolicy<_O,_C_>\n-\u00a0 A LeveTransferPolicy that used aggregation to construct the coarse\n- level system. More...\n-\u00a0\n-class \u00a0Dune::Amg::OneStepAMGCoarseSolverPolicy<_O,_S,_C_>\n-\u00a0 A policy class for solving the coarse level system using one step of\n- AMG. More...\n+struct \u00a0Dune::exists<_T_>\n \u00a0\n-class \u00a0Dune::Amg::TwoLevelMethod<_FO,_CSP,_S_>\n+struct \u00a0Dune::DefaultAllocatorTraits<_T,_typename_>\n+\u00a0\n+struct \u00a0Dune::DefaultAllocatorTraits<_T,_std::void_t<_typename_T::\n+ allocator_type_>_>\n+\u00a0\n+struct \u00a0Dune::AllocatorTraits<_T_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n+ Typedefs\n+template\n+using\u00a0Dune::AllocatorType = typename AllocatorTraits< T >::type\n+\u00a0\n+template\n+using\u00a0Dune::ReboundAllocatorType = typename std::allocator_traits< typename\n+ AllocatorTraits< T >::type >::template rebind_alloc< X >\n \u00a0\n-***** Detailed Description *****\n-Algebraic twolevel methods.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00113_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00113_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: twolevelmethod.hh Source File\n+dune-istl: allocator.hh Source File\n \n \n \n \n \n \n \n@@ -58,439 +58,72 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    twolevelmethod.hh
    \n+
    allocator.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n-
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n-
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_TWOLEVELMETHOD_HH
    \n-
    6#define DUNE_ISTL_TWOLEVELMETHOD_HH
    \n-
    7
    \n-
    8#include <tuple>
    \n-
    9
    \n-\n-
    11#include"amg.hh"
    \n-
    12#include"galerkin.hh"
    \n-
    13#include<dune/istl/solver.hh>
    \n-
    14
    \n-
    22namespace Dune
    \n-
    23{
    \n-
    24namespace Amg
    \n-
    25{
    \n-
    26
    \n-
    36template<class FO, class CO>
    \n-\n-
    38{
    \n-
    39public:
    \n-
    44 typedef FO FineOperatorType;
    \n-
    48 typedef typename FineOperatorType::range_type FineRangeType;
    \n-
    52 typedef typename FineOperatorType::domain_type FineDomainType;
    \n-\n-
    61 typedef typename CoarseOperatorType::range_type CoarseRangeType;
    \n-
    65 typedef typename CoarseOperatorType::domain_type CoarseDomainType;
    \n-
    70 std::shared_ptr<CoarseOperatorType>& getCoarseLevelOperator()
    \n-
    71 {
    \n-
    72 return operator_;
    \n-
    73 }
    \n-\n-
    79 {
    \n-
    80 return rhs_;
    \n-
    81 }
    \n-
    82
    \n-\n-
    88 {
    \n-
    89 return lhs_;
    \n-
    90 }
    \n-
    100 virtual void moveToCoarseLevel(const FineRangeType& fineRhs)=0;
    \n-
    110 virtual void moveToFineLevel(FineDomainType& fineLhs)=0;
    \n-
    118 virtual void createCoarseLevelSystem(const FineOperatorType& fineOperator)=0;
    \n-
    119
    \n-
    121 virtual LevelTransferPolicy* clone() const =0;
    \n-
    122
    \n-\n-
    125
    \n-
    126 protected:
    \n-\n-\n-
    132 std::shared_ptr<CoarseOperatorType> operator_;
    \n-
    133};
    \n-
    134
    \n-
    140template<class O, class C>
    \n-\n-
    142 : public LevelTransferPolicy<O,O>
    \n-
    143{
    \n-\n-
    145public:
    \n-\n-
    147 typedef C Criterion;
    \n-\n-
    149
    \n-\n-
    151 : criterion_(crit)
    \n-
    152 {}
    \n-
    153
    \n-
    154 void createCoarseLevelSystem(const O& fineOperator)
    \n-
    155 {
    \n-
    156 prolongDamp_ = criterion_.getProlongationDampingFactor();
    \n-\n-\n-\n-
    160 Dune::Amg::EdgeProperties,Dune::IdentityMap,Dune::IdentityMap> PropertiesGraph;
    \n-
    161 MatrixGraph mg(fineOperator.getmat());
    \n-
    162 PropertiesGraph pg(mg,Dune::IdentityMap(),Dune::IdentityMap());
    \n-
    163 typedef NegateSet<typename ParallelInformation::OwnerSet> OverlapFlags;
    \n-
    164
    \n-
    165 aggregatesMap_ = std::make_shared<AggregatesMap>(pg.maxVertex()+1);
    \n-
    166
    \n-
    167 int noAggregates, isoAggregates, oneAggregates, skippedAggregates;
    \n-
    168
    \n-
    169 std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =
    \n-
    170 aggregatesMap_->buildAggregates(fineOperator.getmat(), pg, criterion_, true);
    \n-
    171 std::cout<<"no aggregates="<<noAggregates<<" iso="<<isoAggregates<<" one="<<oneAggregates<<" skipped="<<skippedAggregates<<std::endl;
    \n-
    172 // misuse coarsener to renumber aggregates
    \n-\n-
    174 typedef std::vector<bool>::iterator Iterator;
    \n-
    175 typedef Dune::IteratorPropertyMap<Iterator, Dune::IdentityMap> VisitedMap;
    \n-
    176 std::vector<bool> excluded(fineOperator.getmat().N(), false);
    \n-
    177 VisitedMap vm(excluded.begin(), Dune::IdentityMap());
    \n-\n-
    179 std::size_t aggregates = renumberer.coarsen(pinfo, pg, vm,
    \n-
    180 *aggregatesMap_, pinfo,
    \n-
    181 noAggregates);
    \n-
    182 std::vector<bool>& visited=excluded;
    \n-
    183
    \n-
    184 typedef std::vector<bool>::iterator Iterator;
    \n-
    185
    \n-
    186 for(Iterator iter= visited.begin(), end=visited.end();
    \n-
    187 iter != end; ++iter)
    \n-
    188 *iter=false;
    \n-
    189 matrix_.reset(productBuilder.build(mg, vm,
    \n-\n-
    191 *aggregatesMap_,
    \n-
    192 aggregates,
    \n-
    193 OverlapFlags()));
    \n-
    194 productBuilder.calculate(fineOperator.getmat(), *aggregatesMap_, *matrix_, pinfo, OverlapFlags());
    \n-
    195 this->lhs_.resize(this->matrix_->M());
    \n-
    196 this->rhs_.resize(this->matrix_->N());
    \n-
    197 this->operator_ = std::make_shared<O>(*matrix_);
    \n-
    198 }
    \n-
    199
    \n-
    200 void moveToCoarseLevel(const typename FatherType::FineRangeType& fineRhs)
    \n-
    201 {
    \n-\n-
    203 ::restrictVector(*aggregatesMap_, this->rhs_, fineRhs, ParallelInformation());
    \n-
    204 this->lhs_=0;
    \n-
    205 }
    \n-
    206
    \n-\n-
    208 {
    \n-\n-
    210 ::prolongateVector(*aggregatesMap_, this->lhs_, fineLhs,
    \n-
    211 prolongDamp_, ParallelInformation());
    \n-
    212 }
    \n-
    213
    \n-\n-
    215 {
    \n-
    216 return new AggregationLevelTransferPolicy(*this);
    \n-
    217 }
    \n-
    218
    \n-
    219private:
    \n-
    220 typename O::matrix_type::field_type prolongDamp_;
    \n-
    221 std::shared_ptr<AggregatesMap> aggregatesMap_;
    \n-
    222 Criterion criterion_;
    \n-
    223 std::shared_ptr<typename O::matrix_type> matrix_;
    \n-
    224};
    \n-
    225
    \n-
    232template<class O, class S, class C>
    \n-\n-
    234{
    \n-
    235public:
    \n-
    237 typedef O Operator;
    \n-
    239 typedef typename O::range_type X;
    \n-
    241 typedef C Criterion;
    \n-
    243 typedef S Smoother;
    \n-\n-\n-\n-
    254 : smootherArgs_(args), criterion_(c)
    \n-
    255 {}
    \n-\n-
    258 : coarseOperator_(other.coarseOperator_), smootherArgs_(other.smootherArgs_),
    \n-
    259 criterion_(other.criterion_)
    \n-
    260 {}
    \n-
    261private:
    \n-
    268 struct AMGInverseOperator : public InverseOperator<X,X>
    \n-
    269 {
    \n-
    270 AMGInverseOperator(const typename AMGType::Operator& op,
    \n-
    271 const Criterion& crit,
    \n-
    272 const typename AMGType::SmootherArgs& args)
    \n-
    273 : amg_(op, crit,args), first_(true)
    \n-
    274 {}
    \n-
    275
    \n-
    276 void apply(X& x, X& b, [[maybe_unused]] double reduction, [[maybe_unused]] InverseOperatorResult& res)
    \n-
    277 {
    \n-
    278 if(first_)
    \n-
    279 {
    \n-
    280 amg_.pre(x,b);
    \n-
    281 first_=false;
    \n-
    282 x_=x;
    \n-
    283 }
    \n-
    284 amg_.apply(x,b);
    \n-
    285 }
    \n-
    286
    \n-
    287 void apply(X& x, X& b, InverseOperatorResult& res)
    \n-
    288 {
    \n-
    289 return apply(x,b,1e-8,res);
    \n-
    290 }
    \n-
    291
    \n-
    293 virtual SolverCategory::Category category() const
    \n-
    294 {
    \n-
    295 return amg_.category();
    \n-
    296 }
    \n-
    297
    \n-
    298 ~AMGInverseOperator()
    \n-
    299 {
    \n-
    300 if(!first_)
    \n-
    301 amg_.post(x_);
    \n-
    302 }
    \n-
    303 AMGInverseOperator(const AMGInverseOperator& other)
    \n-
    304 : x_(other.x_), amg_(other.amg_), first_(other.first_)
    \n-
    305 {
    \n-
    306 }
    \n-
    307 private:
    \n-
    308 X x_;
    \n-
    309 AMGType amg_;
    \n-
    310 bool first_;
    \n-
    311 };
    \n-
    312
    \n-
    313public:
    \n-
    315 typedef AMGInverseOperator CoarseLevelSolver;
    \n-
    316
    \n-
    324 template<class P>
    \n-\n-
    326 {
    \n-
    327 coarseOperator_=transferPolicy.getCoarseLevelOperator();
    \n-
    328 AMGInverseOperator* inv = new AMGInverseOperator(*coarseOperator_,
    \n-
    329 criterion_,
    \n-
    330 smootherArgs_);
    \n-
    331
    \n-
    332 return inv; //std::shared_ptr<InverseOperator<X,X> >(inv);
    \n-
    333
    \n-
    334 }
    \n-
    335
    \n-
    336private:
    \n-
    338 std::shared_ptr<Operator> coarseOperator_;
    \n-
    340 SmootherArgs smootherArgs_;
    \n-
    342 Criterion criterion_;
    \n-
    343};
    \n-
    344
    \n-
    350template<class FO, class CSP, class S>
    \n-\n-
    352 public Preconditioner<typename FO::domain_type, typename FO::range_type>
    \n-
    353{
    \n-
    354public:
    \n-\n-
    358 typedef typename CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver;
    \n-\n-
    367 typedef typename FineOperatorType::range_type FineRangeType;
    \n-
    371 typedef typename FineOperatorType::domain_type FineDomainType;
    \n-
    376 typedef typename CSP::Operator CoarseOperatorType;
    \n-
    380 typedef typename CoarseOperatorType::range_type CoarseRangeType;
    \n-
    384 typedef typename CoarseOperatorType::domain_type CoarseDomainType;
    \n-
    388 typedef S SmootherType;
    \n-
    389
    \n-\n-
    405 std::shared_ptr<SmootherType> smoother,
    \n-\n-
    407 CoarseOperatorType>& policy,
    \n-
    408 CoarseLevelSolverPolicy& coarsePolicy,
    \n-
    409 std::size_t preSteps=1, std::size_t postSteps=1)
    \n-
    410 : operator_(&op), smoother_(smoother),
    \n-
    411 preSteps_(preSteps), postSteps_(postSteps)
    \n-
    412 {
    \n-
    413 policy_ = policy.clone();
    \n-
    414 policy_->createCoarseLevelSystem(*operator_);
    \n-
    415 coarseSolver_=coarsePolicy.createCoarseLevelSolver(*policy_);
    \n-
    416 }
    \n-
    417
    \n-\n-
    419 : operator_(other.operator_), coarseSolver_(new CoarseLevelSolver(*other.coarseSolver_)),
    \n-
    420 smoother_(other.smoother_), policy_(other.policy_->clone()),
    \n-
    421 preSteps_(other.preSteps_), postSteps_(other.postSteps_)
    \n-
    422 {}
    \n-
    423
    \n-\n-
    425 {
    \n-
    426 // Each instance has its own policy.
    \n-
    427 delete policy_;
    \n-
    428 delete coarseSolver_;
    \n-
    429 }
    \n-
    430
    \n-\n-
    432 {
    \n-
    433 smoother_->pre(x,b);
    \n-
    434 }
    \n-
    435
    \n-
    436 void post([[maybe_unused]] FineDomainType& x)
    \n-
    437 {}
    \n-
    438
    \n-\n-
    440 {
    \n-
    441 FineDomainType u(v);
    \n-
    442 FineRangeType rhs(d);
    \n-
    443 LevelContext context;
    \n-\n-
    445 context.pinfo=&info;
    \n-
    446 context.lhs=&u;
    \n-
    447 context.update=&v;
    \n-
    448 context.smoother=smoother_;
    \n-
    449 context.rhs=&rhs;
    \n-
    450 context.matrix=operator_;
    \n-
    451 // Presmoothing
    \n-
    452 presmooth(context, preSteps_);
    \n-
    453 //Coarse grid correction
    \n-
    454 policy_->moveToCoarseLevel(*context.rhs);
    \n-\n-
    456 coarseSolver_->apply(policy_->getCoarseLevelLhs(), policy_->getCoarseLevelRhs(), res);
    \n-
    457 *context.lhs=0;
    \n-
    458 policy_->moveToFineLevel(*context.lhs);
    \n-
    459 *context.update += *context.lhs;
    \n-
    460 // Postsmoothing
    \n-
    461 postsmooth(context, postSteps_);
    \n-
    462
    \n-
    463 }
    \n-
    464
    \n-\n-
    467 {
    \n-\n-
    469 }
    \n-
    470
    \n-
    471private:
    \n-
    475 struct LevelContext
    \n-
    476 {
    \n-
    478 typedef S SmootherType;
    \n-
    480 std::shared_ptr<SmootherType> smoother;
    \n-
    482 FineDomainType* lhs;
    \n-
    483 /*
    \n-
    484 * @brief The right hand side holding the current residual.
    \n-
    485 *
    \n-
    486 * This is passed to the smoother as the right hand side.
    \n-
    487 */
    \n-
    488 FineRangeType* rhs;
    \n-
    494 FineDomainType* update;
    \n-\n-
    502 const FineOperatorType* matrix;
    \n-
    503 };
    \n-
    504 const FineOperatorType* operator_;
    \n-
    506 CoarseLevelSolver* coarseSolver_;
    \n-
    508 std::shared_ptr<S> smoother_;
    \n-
    510 LevelTransferPolicy<FO,typename CSP::Operator>* policy_;
    \n-
    512 std::size_t preSteps_;
    \n-
    514 std::size_t postSteps_;
    \n-
    515};
    \n-
    516}// end namespace Amg
    \n-
    517}// end namespace Dune
    \n-
    518
    \n-
    520#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Define general, extensible interface for inverse operators.
    \n-
    Provides a class for building the galerkin product based on a aggregation scheme.
    \n-
    The AMG preconditioner.
    \n-
    G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation &pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::Matrix::size_type &size, const Set &copy)
    Calculates the coarse matrix via a Galerkin product.
    Definition: galerkin.hh:563
    \n-
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n-
    Operator Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n-
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n-
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n-
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n+
    3#ifndef DUNE_ISTL_ALLOCATOR_HH
    \n+
    4#define DUNE_ISTL_ALLOCATOR_HH
    \n+
    5
    \n+
    6#include <memory>
    \n+
    7#include <type_traits>
    \n+
    8
    \n+
    9#include <dune/common/typetraits.hh>
    \n+
    10
    \n+
    11namespace Dune {
    \n+
    12
    \n+
    13 template<typename T>
    \n+
    14 struct exists{
    \n+
    15 static const bool value = true;
    \n+
    16 };
    \n+
    17
    \n+
    18 template<typename T, typename = void>
    \n+\n+
    20 {
    \n+
    21 using type = std::allocator<T>;
    \n+
    22 };
    \n+
    23
    \n+
    24 template<typename T>
    \n+
    25 struct DefaultAllocatorTraits<T, std::void_t<typename T::allocator_type> >
    \n+
    26 {
    \n+
    27 using type = typename T::allocator_type;
    \n+
    28 };
    \n+
    29
    \n+
    30 template<typename T>
    \n+\n+
    32
    \n+
    33 template<typename T>
    \n+\n+
    35
    \n+
    36 template<typename T, typename X>
    \n+
    37 using ReboundAllocatorType = typename std::allocator_traits<typename AllocatorTraits<T>::type>::template rebind_alloc<X>;
    \n+
    38
    \n+
    39} // end namespace Dune
    \n+
    40
    \n+
    41#endif // DUNE_ISTL_ALLOCATOR_HH
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-\n-
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n-
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n-
    Definition: galerkin.hh:118
    \n-
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n-
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n-
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n-
    Definition: indicescoarsener.hh:36
    \n-
    Definition: pinfo.hh:28
    \n-
    The default class for the smoother arguments.
    Definition: smoother.hh:38
    \n-
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n-
    Abstract base class for transfer between levels and creation of the coarse level system.
    Definition: twolevelmethod.hh:38
    \n-
    CO CoarseOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:57
    \n-
    virtual void moveToCoarseLevel(const FineRangeType &fineRhs)=0
    Transfers the data to the coarse level.
    \n-
    FineOperatorType::range_type FineRangeType
    The type of the range of the fine level operator.
    Definition: twolevelmethod.hh:48
    \n-
    virtual void createCoarseLevelSystem(const FineOperatorType &fineOperator)=0
    Algebraically creates the coarse level system.
    \n-
    CoarseOperatorType::range_type CoarseRangeType
    The type of the range of the coarse level operator.
    Definition: twolevelmethod.hh:61
    \n-
    virtual ~LevelTransferPolicy()
    Destructor.
    Definition: twolevelmethod.hh:124
    \n-
    CoarseDomainType lhs_
    The coarse level lhs.
    Definition: twolevelmethod.hh:130
    \n-
    virtual LevelTransferPolicy * clone() const =0
    Clone the current object.
    \n-
    CoarseDomainType & getCoarseLevelLhs()
    Get the coarse level left hand side.
    Definition: twolevelmethod.hh:87
    \n-
    std::shared_ptr< CoarseOperatorType > operator_
    the coarse level linear operator.
    Definition: twolevelmethod.hh:132
    \n-
    CoarseRangeType rhs_
    The coarse level rhs.
    Definition: twolevelmethod.hh:128
    \n-
    virtual void moveToFineLevel(FineDomainType &fineLhs)=0
    Updates the fine level linear system after the correction of the coarse levels system.
    \n-
    std::shared_ptr< CoarseOperatorType > & getCoarseLevelOperator()
    Get the coarse level operator.
    Definition: twolevelmethod.hh:70
    \n-
    CoarseRangeType & getCoarseLevelRhs()
    Get the coarse level right hand side.
    Definition: twolevelmethod.hh:78
    \n-
    FO FineOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:44
    \n-
    CoarseOperatorType::domain_type CoarseDomainType
    The type of the domain of the coarse level operator.
    Definition: twolevelmethod.hh:65
    \n-
    FineOperatorType::domain_type FineDomainType
    The type of the domain of the fine level operator.
    Definition: twolevelmethod.hh:52
    \n-
    A LeveTransferPolicy that used aggregation to construct the coarse level system.
    Definition: twolevelmethod.hh:143
    \n-
    C Criterion
    Definition: twolevelmethod.hh:147
    \n-
    AggregationLevelTransferPolicy(const Criterion &crit)
    Definition: twolevelmethod.hh:150
    \n-
    AggregationLevelTransferPolicy * clone() const
    Clone the current object.
    Definition: twolevelmethod.hh:214
    \n-
    void moveToFineLevel(typename FatherType::FineDomainType &fineLhs)
    Updates the fine level linear system after the correction of the coarse levels system.
    Definition: twolevelmethod.hh:207
    \n-
    void moveToCoarseLevel(const typename FatherType::FineRangeType &fineRhs)
    Definition: twolevelmethod.hh:200
    \n-
    SequentialInformation ParallelInformation
    Definition: twolevelmethod.hh:148
    \n-
    LevelTransferPolicy< O, O > FatherType
    Definition: twolevelmethod.hh:146
    \n-
    void createCoarseLevelSystem(const O &fineOperator)
    Algebraically creates the coarse level system.
    Definition: twolevelmethod.hh:154
    \n-
    A policy class for solving the coarse level system using one step of AMG.
    Definition: twolevelmethod.hh:234
    \n-
    OneStepAMGCoarseSolverPolicy(const SmootherArgs &args, const Criterion &c)
    Constructs the coarse solver policy.
    Definition: twolevelmethod.hh:253
    \n-
    AMGInverseOperator CoarseLevelSolver
    The type of solver constructed for the coarse level.
    Definition: twolevelmethod.hh:315
    \n-
    OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy &other)
    Copy constructor.
    Definition: twolevelmethod.hh:257
    \n-
    O::range_type X
    The type of the range and domain of the operator.
    Definition: twolevelmethod.hh:239
    \n-
    C Criterion
    The type of the crition used for the aggregation within AMG.
    Definition: twolevelmethod.hh:241
    \n-
    Dune::Amg::SmootherTraits< S >::Arguments SmootherArgs
    The type of the arguments used for constructing the smoother.
    Definition: twolevelmethod.hh:245
    \n-
    O Operator
    The type of the linear operator used.
    Definition: twolevelmethod.hh:237
    \n-
    AMG< Operator, X, Smoother > AMGType
    The type of the AMG construct on the coarse level.
    Definition: twolevelmethod.hh:247
    \n-
    CoarseLevelSolver * createCoarseLevelSolver(P &transferPolicy)
    Constructs a coarse level solver.
    Definition: twolevelmethod.hh:325
    \n-
    S Smoother
    The type of the smoother used in AMG.
    Definition: twolevelmethod.hh:243
    \n-
    Definition: twolevelmethod.hh:353
    \n-
    CoarseOperatorType::range_type CoarseRangeType
    The type of the range of the coarse level operator.
    Definition: twolevelmethod.hh:380
    \n-
    FineOperatorType::domain_type FineDomainType
    The type of the domain of the fine level operator.
    Definition: twolevelmethod.hh:371
    \n-
    TwoLevelMethod(const TwoLevelMethod &other)
    Definition: twolevelmethod.hh:418
    \n-
    void pre(FineDomainType &x, FineRangeType &b)
    Definition: twolevelmethod.hh:431
    \n-
    FO FineOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:363
    \n-
    CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver
    The type of the coarse level solver.
    Definition: twolevelmethod.hh:358
    \n-
    void apply(FineDomainType &v, const FineRangeType &d)
    Definition: twolevelmethod.hh:439
    \n-
    CSP CoarseLevelSolverPolicy
    The type of the policy for constructing the coarse level solver.
    Definition: twolevelmethod.hh:356
    \n-
    CoarseOperatorType::domain_type CoarseDomainType
    The type of the domain of the coarse level operator.
    Definition: twolevelmethod.hh:384
    \n-
    TwoLevelMethod(const FineOperatorType &op, std::shared_ptr< SmootherType > smoother, const LevelTransferPolicy< FineOperatorType, CoarseOperatorType > &policy, CoarseLevelSolverPolicy &coarsePolicy, std::size_t preSteps=1, std::size_t postSteps=1)
    Constructs a two level method.
    Definition: twolevelmethod.hh:404
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: twolevelmethod.hh:466
    \n-
    FineOperatorType::range_type FineRangeType
    The type of the range of the fine level operator.
    Definition: twolevelmethod.hh:367
    \n-
    ~TwoLevelMethod()
    Definition: twolevelmethod.hh:424
    \n-
    CSP::Operator CoarseOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:376
    \n-
    void post(FineDomainType &x)
    Definition: twolevelmethod.hh:436
    \n-
    S SmootherType
    The type of the fine level smoother.
    Definition: twolevelmethod.hh:388
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n-
    virtual void apply(X &x, X &b, InverseOperatorResult &res)=0
    Apply inverse operator,.
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X > ReboundAllocatorType
    Definition: allocator.hh:37
    \n+
    typename AllocatorTraits< T >::type AllocatorType
    Definition: allocator.hh:34
    \n+
    Definition: allocator.hh:14
    \n+
    static const bool value
    Definition: allocator.hh:15
    \n+
    Definition: allocator.hh:20
    \n+
    std::allocator< T > type
    Definition: allocator.hh:21
    \n+
    typename T::allocator_type type
    Definition: allocator.hh:27
    \n+
    Definition: allocator.hh:31
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,667 +4,82 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-twolevelmethod.hh\n+allocator.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n- 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n- 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_TWOLEVELMETHOD_HH\n- 6#define DUNE_ISTL_TWOLEVELMETHOD_HH\n- 7\n- 8#include \n- 9\n- 10#include\n- 11#include\"amg.hh\"\n- 12#include\"galerkin.hh\"\n- 13#include\n- 14\n- 22namespace Dune\n- 23{\n- 24namespace Amg\n- 25{\n- 26\n- 36template\n-37class LevelTransferPolicy\n- 38{\n- 39public:\n-44 typedef FO FineOperatorType;\n-48 typedef typename FineOperatorType::range_type FineRangeType;\n-52 typedef typename FineOperatorType::domain_type FineDomainType;\n-57 typedef CO CoarseOperatorType;\n-61 typedef typename CoarseOperatorType::range_type CoarseRangeType;\n-65 typedef typename CoarseOperatorType::domain_type CoarseDomainType;\n-70 std::shared_ptr& getCoarseLevelOperator()\n- 71 {\n- 72 return operator_;\n- 73 }\n-78 CoarseRangeType& getCoarseLevelRhs()\n- 79 {\n- 80 return rhs_;\n- 81 }\n- 82\n-87 CoarseDomainType& getCoarseLevelLhs()\n- 88 {\n- 89 return lhs_;\n- 90 }\n-100 virtual void moveToCoarseLevel(const FineRangeType& fineRhs)=0;\n-110 virtual void moveToFineLevel(FineDomainType& fineLhs)=0;\n-118 virtual void createCoarseLevelSystem(const FineOperatorType&\n-fineOperator)=0;\n- 119\n-121 virtual LevelTransferPolicy* clone() const =0;\n- 122\n-124 virtual ~LevelTransferPolicy(){}\n- 125\n- 126 protected:\n-128 CoarseRangeType rhs_;\n-130 CoarseDomainType lhs_;\n-132 std::shared_ptr operator_;\n- 133};\n- 134\n- 140template\n-141class AggregationLevelTransferPolicy\n- 142 : public LevelTransferPolicy\n- 143{\n- 144 typedef Dune::Amg::AggregatesMap\n-AggregatesMap;\n- 145public:\n-146 typedef LevelTransferPolicy FatherType;\n-147 typedef C Criterion;\n-148 typedef SequentialInformation ParallelInformation;\n- 149\n-150 AggregationLevelTransferPolicy(const Criterion& crit)\n- 151 : criterion_(crit)\n- 152 {}\n- 153\n-154 void createCoarseLevelSystem(const O& fineOperator)\n- 155 {\n- 156 prolongDamp_ = criterion_.getProlongationDampingFactor();\n- 157 GalerkinProduct productBuilder;\n- 158 typedef typename Dune::Amg::MatrixGraph\n-MatrixGraph;\n- 159 typedef typename Dune::Amg::PropertiesGraph\n-PropertiesGraph;\n- 161 MatrixGraph mg(fineOperator.getmat());\n- 162 PropertiesGraph pg(mg,Dune::IdentityMap(),Dune::IdentityMap());\n- 163 typedef NegateSet OverlapFlags;\n- 164\n- 165 aggregatesMap_ = std::make_shared(pg.maxVertex()+1);\n- 166\n- 167 int noAggregates, isoAggregates, oneAggregates, skippedAggregates;\n- 168\n- 169 std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =\n- 170 aggregatesMap_->buildAggregates(fineOperator.getmat(), pg, criterion_,\n-true);\n- 171 std::cout<<\"no aggregates=\"<\n-renumberer;\n- 174 typedef std::vector::iterator Iterator;\n- 175 typedef Dune::IteratorPropertyMap VisitedMap;\n- 176 std::vector excluded(fineOperator.getmat().N(), false);\n- 177 VisitedMap vm(excluded.begin(), Dune::IdentityMap());\n- 178 ParallelInformation pinfo;\n- 179 std::size_t aggregates = renumberer.coarsen(pinfo, pg, vm,\n- 180 *aggregatesMap_, pinfo,\n- 181 noAggregates);\n- 182 std::vector& visited=excluded;\n- 183\n- 184 typedef std::vector::iterator Iterator;\n- 185\n- 186 for(Iterator iter= visited.begin(), end=visited.end();\n- 187 iter != end; ++iter)\n- 188 *iter=false;\n- 189 matrix_.reset(productBuilder.build(mg, vm,\n- 190 SequentialInformation(),\n- 191 *aggregatesMap_,\n- 192 aggregates,\n- 193 OverlapFlags()));\n- 194 productBuilder.calculate(fineOperator.getmat(), *aggregatesMap_, *matrix_,\n-pinfo, OverlapFlags());\n- 195 this->lhs_.resize(this->matrix_->M());\n- 196 this->rhs_.resize(this->matrix_->N());\n- 197 this->operator_ = std::make_shared(*matrix_);\n- 198 }\n- 199\n-200 void moveToCoarseLevel(const typename FatherType::FineRangeType& fineRhs)\n- 201 {\n- 202 Transfer\n- 203::restrictVector(*aggregatesMap_, this->rhs_, fineRhs, ParallelInformation\n-());\n- 204 this->lhs_=0;\n- 205 }\n- 206\n-207 void moveToFineLevel(typename FatherType::FineDomainType& fineLhs)\n- 208 {\n- 209 Transfer\n- 210::prolongateVector(*aggregatesMap_, this->lhs_, fineLhs,\n- 211 prolongDamp_, ParallelInformation());\n- 212 }\n- 213\n-214 AggregationLevelTransferPolicy* clone() const\n- 215 {\n- 216 return new AggregationLevelTransferPolicy(*this);\n- 217 }\n- 218\n- 219private:\n- 220 typename O::matrix_type::field_type prolongDamp_;\n- 221 std::shared_ptr aggregatesMap_;\n- 222 Criterion criterion_;\n- 223 std::shared_ptr matrix_;\n- 224};\n- 225\n- 232template\n-233class OneStepAMGCoarseSolverPolicy\n- 234{\n- 235public:\n-237 typedef O Operator;\n-239 typedef typename O::range_type X;\n-241 typedef C Criterion;\n-243 typedef S Smoother;\n-245 typedef typename Dune::Amg::SmootherTraits::Arguments SmootherArgs;\n-247 typedef AMG AMGType;\n-253 OneStepAMGCoarseSolverPolicy(const SmootherArgs& args, const Criterion& c)\n- 254 : smootherArgs_(args), criterion_(c)\n- 255 {}\n-257 OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy& other)\n- 258 : coarseOperator_(other.coarseOperator_), smootherArgs_\n-(other.smootherArgs_),\n- 259 criterion_(other.criterion_)\n- 260 {}\n- 261private:\n- 268 struct AMGInverseOperator : public InverseOperator\n- 269 {\n- 270 AMGInverseOperator(const typename AMGType::Operator& op,\n- 271 const Criterion& crit,\n- 272 const typename AMGType::SmootherArgs& args)\n- 273 : amg_(op, crit,args), first_(true)\n- 274 {}\n- 275\n- 276 void apply(X& x, X& b, [[maybe_unused]] double reduction, [[maybe_unused]]\n-InverseOperatorResult& res)\n- 277 {\n- 278 if(first_)\n- 279 {\n- 280 amg_.pre(x,b);\n- 281 first_=false;\n- 282 x_=x;\n- 283 }\n- 284 amg_.apply(x,b);\n- 285 }\n- 286\n- 287 void apply(X& x, X& b, InverseOperatorResult& res)\n- 288 {\n- 289 return apply(x,b,1e-8,res);\n- 290 }\n- 291\n- 293 virtual SolverCategory::Category category() const\n- 294 {\n- 295 return amg_.category();\n- 296 }\n- 297\n- 298 ~AMGInverseOperator()\n- 299 {\n- 300 if(!first_)\n- 301 amg_.post(x_);\n- 302 }\n- 303 AMGInverseOperator(const AMGInverseOperator& other)\n- 304 : x_(other.x_), amg_(other.amg_), first_(other.first_)\n- 305 {\n- 306 }\n- 307 private:\n- 308 X x_;\n- 309 AMGType amg_;\n- 310 bool first_;\n- 311 };\n- 312\n- 313public:\n-315 typedef AMGInverseOperator CoarseLevelSolver;\n- 316\n- 324 template\n-325 CoarseLevelSolver* createCoarseLevelSolver(P& transferPolicy)\n- 326 {\n- 327 coarseOperator_=transferPolicy.getCoarseLevelOperator();\n- 328 AMGInverseOperator* inv = new AMGInverseOperator(*coarseOperator_,\n- 329 criterion_,\n- 330 smootherArgs_);\n- 331\n- 332 return inv; //std::shared_ptr >(inv);\n- 333\n- 334 }\n- 335\n- 336private:\n- 338 std::shared_ptr coarseOperator_;\n- 340 SmootherArgs smootherArgs_;\n- 342 Criterion criterion_;\n- 343};\n- 344\n- 350template\n-351class TwoLevelMethod :\n- 352 public Preconditioner\n- 353{\n- 354public:\n-356 typedef CSP CoarseLevelSolverPolicy;\n-358 typedef typename CoarseLevelSolverPolicy::CoarseLevelSolver\n-CoarseLevelSolver;\n-363 typedef FO FineOperatorType;\n-367 typedef typename FineOperatorType::range_type FineRangeType;\n-371 typedef typename FineOperatorType::domain_type FineDomainType;\n-376 typedef typename CSP::Operator CoarseOperatorType;\n-380 typedef typename CoarseOperatorType::range_type CoarseRangeType;\n-384 typedef typename CoarseOperatorType::domain_type CoarseDomainType;\n-388 typedef S SmootherType;\n- 389\n-404 TwoLevelMethod(const FineOperatorType& op,\n- 405 std::shared_ptr smoother,\n- 406 const LevelTransferPolicy& policy,\n- 408 CoarseLevelSolverPolicy& coarsePolicy,\n- 409 std::size_t preSteps=1, std::size_t postSteps=1)\n- 410 : operator_(&op), smoother_(smoother),\n- 411 preSteps_(preSteps), postSteps_(postSteps)\n- 412 {\n- 413 policy_ = policy.clone();\n- 414 policy_->createCoarseLevelSystem(*operator_);\n- 415 coarseSolver_=coarsePolicy.createCoarseLevelSolver(*policy_);\n- 416 }\n- 417\n-418 TwoLevelMethod(const TwoLevelMethod& other)\n- 419 : operator_(other.operator_), coarseSolver_(new CoarseLevelSolver\n-(*other.coarseSolver_)),\n- 420 smoother_(other.smoother_), policy_(other.policy_->clone()),\n- 421 preSteps_(other.preSteps_), postSteps_(other.postSteps_)\n- 422 {}\n- 423\n-424 ~TwoLevelMethod()\n- 425 {\n- 426 // Each instance has its own policy.\n- 427 delete policy_;\n- 428 delete coarseSolver_;\n- 429 }\n- 430\n-431 void pre(FineDomainType& x, FineRangeType& b)\n- 432 {\n- 433 smoother_->pre(x,b);\n- 434 }\n- 435\n-436 void post([[maybe_unused]] FineDomainType& x)\n- 437 {}\n- 438\n-439 void apply(FineDomainType& v, const FineRangeType& d)\n- 440 {\n- 441 FineDomainType u(v);\n- 442 FineRangeType rhs(d);\n- 443 LevelContext context;\n- 444 SequentialInformation info;\n- 445 context.pinfo=&info;\n- 446 context.lhs=&u;\n- 447 context.update=&v;\n- 448 context.smoother=smoother_;\n- 449 context.rhs=&rhs;\n- 450 context.matrix=operator_;\n- 451 // Presmoothing\n- 452 presmooth(context, preSteps_);\n- 453 //Coarse grid correction\n- 454 policy_->moveToCoarseLevel(*context.rhs);\n- 455 InverseOperatorResult res;\n- 456 coarseSolver_->apply(policy_->getCoarseLevelLhs(), policy_-\n->getCoarseLevelRhs(), res);\n- 457 *context.lhs=0;\n- 458 policy_->moveToFineLevel(*context.lhs);\n- 459 *context.update += *context.lhs;\n- 460 // Postsmoothing\n- 461 postsmooth(context, postSteps_);\n- 462\n- 463 }\n- 464\n-466 virtual SolverCategory::Category category() const\n- 467 {\n- 468 return SolverCategory::sequential;\n- 469 }\n- 470\n- 471private:\n- 475 struct LevelContext\n- 476 {\n- 478 typedef S SmootherType;\n- 480 std::shared_ptr smoother;\n- 482 FineDomainType* lhs;\n- 483 /*\n- 484 * @brief The right hand side holding the current residual.\n- 485 *\n- 486 * This is passed to the smoother as the right hand side.\n- 487 */\n- 488 FineRangeType* rhs;\n- 494 FineDomainType* update;\n- 496 SequentialInformation* pinfo;\n- 502 const FineOperatorType* matrix;\n- 503 };\n- 504 const FineOperatorType* operator_;\n- 506 CoarseLevelSolver* coarseSolver_;\n- 508 std::shared_ptr smoother_;\n- 510 LevelTransferPolicy* policy_;\n- 512 std::size_t preSteps_;\n- 514 std::size_t postSteps_;\n- 515};\n- 516}// end namespace Amg\n- 517}// end namespace Dune\n- 518\n- 520#endif\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n-solver.hh\n-Define general, extensible interface for inverse operators.\n-galerkin.hh\n-Provides a class for building the galerkin product based on a aggregation\n-scheme.\n-amg.hh\n-The AMG preconditioner.\n-Dune::Amg::GalerkinProduct::build\n-G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation\n-&pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const\n-typename G::Matrix::size_type &size, const Set ©)\n-Calculates the coarse matrix via a Galerkin product.\n-Definition: galerkin.hh:563\n-Dune::Amg::AMG<_Operator,_X,_Smoother_>::SmootherArgs\n-SmootherTraits< Smoother >::Arguments SmootherArgs\n-The argument type for the construction of the smoother.\n-Definition: amg.hh:100\n-Dune::Amg::AMG<_Operator,_X,_Smoother_>::Operator\n-Operator Operator\n-The matrix operator type.\n-Definition: amg.hh:73\n-Dune::Amg::presmooth\n-void presmooth(LevelContext &levelContext, size_t steps)\n-Apply pre smoothing on the current level.\n-Definition: smoother.hh:406\n-Dune::Amg::postsmooth\n-void postsmooth(LevelContext &levelContext, size_t steps)\n-Apply post smoothing on the current level.\n-Definition: smoother.hh:428\n-Dune::Amg::BaseGalerkinProduct::calculate\n-void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n-const I &pinfo, const O ©)\n-Calculate the galerkin product.\n+ 3#ifndef DUNE_ISTL_ALLOCATOR_HH\n+ 4#define DUNE_ISTL_ALLOCATOR_HH\n+ 5\n+ 6#include \n+ 7#include \n+ 8\n+ 9#include \n+ 10\n+11namespace Dune {\n+ 12\n+ 13 template\n+14 struct exists{\n+15 static const bool value = true;\n+ 16 };\n+ 17\n+ 18 template\n+19 struct DefaultAllocatorTraits\n+ 20 {\n+21 using type = std::allocator;\n+ 22 };\n+ 23\n+ 24 template\n+25 struct DefaultAllocatorTraits >\n+ 26 {\n+27 using type = typename T::allocator_type;\n+ 28 };\n+ 29\n+ 30 template\n+31 struct AllocatorTraits : public DefaultAllocatorTraits {};\n+ 32\n+ 33 template\n+34 using AllocatorType = typename AllocatorTraits::type;\n+ 35\n+ 36 template\n+37 using ReboundAllocatorType = typename std::allocator_traits::type>::template rebind_alloc;\n+ 38\n+ 39} // end namespace Dune\n+ 40\n+ 41#endif // DUNE_ISTL_ALLOCATOR_HH\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::AggregatesMap\n-Class providing information about the mapping of the vertices onto aggregates.\n-Definition: aggregates.hh:560\n-Dune::Amg::AMG<_Operator,_X,_Smoother_>\n-Dune::Amg::EdgeProperties\n-Class representing the properties of an ede in the matrix graph.\n-Definition: dependency.hh:39\n-Dune::Amg::VertexProperties\n-Class representing a node in the matrix graph.\n-Definition: dependency.hh:126\n-Dune::Amg::GalerkinProduct\n-Definition: galerkin.hh:118\n-Dune::Amg::MatrixGraph\n-The (undirected) graph of a matrix.\n-Definition: graph.hh:51\n-Dune::Amg::PropertiesGraph\n-Attaches properties to the edges and vertices of a graph.\n-Definition: graph.hh:978\n-Dune::Amg::PropertiesGraph::maxVertex\n-VertexDescriptor maxVertex() const\n-Get the maximal vertex descriptor.\n-Dune::Amg::IndicesCoarsener\n-Definition: indicescoarsener.hh:36\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::DefaultSmootherArgs\n-The default class for the smoother arguments.\n-Definition: smoother.hh:38\n-Dune::Amg::Transfer::restrictVector\n-static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, const Vector &fine, T &comm)\n-Dune::Amg::Transfer::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n-Dune::Amg::LevelTransferPolicy\n-Abstract base class for transfer between levels and creation of the coarse\n-level system.\n-Definition: twolevelmethod.hh:38\n-Dune::Amg::LevelTransferPolicy::CoarseOperatorType\n-CO CoarseOperatorType\n-The linear operator of the finel level system. Has to be derived from\n-AssembledLinearOperator.\n-Definition: twolevelmethod.hh:57\n-Dune::Amg::LevelTransferPolicy::moveToCoarseLevel\n-virtual void moveToCoarseLevel(const FineRangeType &fineRhs)=0\n-Transfers the data to the coarse level.\n-Dune::Amg::LevelTransferPolicy::FineRangeType\n-FineOperatorType::range_type FineRangeType\n-The type of the range of the fine level operator.\n-Definition: twolevelmethod.hh:48\n-Dune::Amg::LevelTransferPolicy::createCoarseLevelSystem\n-virtual void createCoarseLevelSystem(const FineOperatorType &fineOperator)=0\n-Algebraically creates the coarse level system.\n-Dune::Amg::LevelTransferPolicy::CoarseRangeType\n-CoarseOperatorType::range_type CoarseRangeType\n-The type of the range of the coarse level operator.\n-Definition: twolevelmethod.hh:61\n-Dune::Amg::LevelTransferPolicy::~LevelTransferPolicy\n-virtual ~LevelTransferPolicy()\n-Destructor.\n-Definition: twolevelmethod.hh:124\n-Dune::Amg::LevelTransferPolicy::lhs_\n-CoarseDomainType lhs_\n-The coarse level lhs.\n-Definition: twolevelmethod.hh:130\n-Dune::Amg::LevelTransferPolicy::clone\n-virtual LevelTransferPolicy * clone() const =0\n-Clone the current object.\n-Dune::Amg::LevelTransferPolicy::getCoarseLevelLhs\n-CoarseDomainType & getCoarseLevelLhs()\n-Get the coarse level left hand side.\n-Definition: twolevelmethod.hh:87\n-Dune::Amg::LevelTransferPolicy::operator_\n-std::shared_ptr< CoarseOperatorType > operator_\n-the coarse level linear operator.\n-Definition: twolevelmethod.hh:132\n-Dune::Amg::LevelTransferPolicy::rhs_\n-CoarseRangeType rhs_\n-The coarse level rhs.\n-Definition: twolevelmethod.hh:128\n-Dune::Amg::LevelTransferPolicy::moveToFineLevel\n-virtual void moveToFineLevel(FineDomainType &fineLhs)=0\n-Updates the fine level linear system after the correction of the coarse levels\n-system.\n-Dune::Amg::LevelTransferPolicy::getCoarseLevelOperator\n-std::shared_ptr< CoarseOperatorType > & getCoarseLevelOperator()\n-Get the coarse level operator.\n-Definition: twolevelmethod.hh:70\n-Dune::Amg::LevelTransferPolicy::getCoarseLevelRhs\n-CoarseRangeType & getCoarseLevelRhs()\n-Get the coarse level right hand side.\n-Definition: twolevelmethod.hh:78\n-Dune::Amg::LevelTransferPolicy::FineOperatorType\n-FO FineOperatorType\n-The linear operator of the finel level system. Has to be derived from\n-AssembledLinearOperator.\n-Definition: twolevelmethod.hh:44\n-Dune::Amg::LevelTransferPolicy::CoarseDomainType\n-CoarseOperatorType::domain_type CoarseDomainType\n-The type of the domain of the coarse level operator.\n-Definition: twolevelmethod.hh:65\n-Dune::Amg::LevelTransferPolicy::FineDomainType\n-FineOperatorType::domain_type FineDomainType\n-The type of the domain of the fine level operator.\n-Definition: twolevelmethod.hh:52\n-Dune::Amg::AggregationLevelTransferPolicy\n-A LeveTransferPolicy that used aggregation to construct the coarse level\n-system.\n-Definition: twolevelmethod.hh:143\n-Dune::Amg::AggregationLevelTransferPolicy::Criterion\n-C Criterion\n-Definition: twolevelmethod.hh:147\n-Dune::Amg::AggregationLevelTransferPolicy::AggregationLevelTransferPolicy\n-AggregationLevelTransferPolicy(const Criterion &crit)\n-Definition: twolevelmethod.hh:150\n-Dune::Amg::AggregationLevelTransferPolicy::clone\n-AggregationLevelTransferPolicy * clone() const\n-Clone the current object.\n-Definition: twolevelmethod.hh:214\n-Dune::Amg::AggregationLevelTransferPolicy::moveToFineLevel\n-void moveToFineLevel(typename FatherType::FineDomainType &fineLhs)\n-Updates the fine level linear system after the correction of the coarse levels\n-system.\n-Definition: twolevelmethod.hh:207\n-Dune::Amg::AggregationLevelTransferPolicy::moveToCoarseLevel\n-void moveToCoarseLevel(const typename FatherType::FineRangeType &fineRhs)\n-Definition: twolevelmethod.hh:200\n-Dune::Amg::AggregationLevelTransferPolicy::ParallelInformation\n-SequentialInformation ParallelInformation\n-Definition: twolevelmethod.hh:148\n-Dune::Amg::AggregationLevelTransferPolicy::FatherType\n-LevelTransferPolicy< O, O > FatherType\n-Definition: twolevelmethod.hh:146\n-Dune::Amg::AggregationLevelTransferPolicy::createCoarseLevelSystem\n-void createCoarseLevelSystem(const O &fineOperator)\n-Algebraically creates the coarse level system.\n-Definition: twolevelmethod.hh:154\n-Dune::Amg::OneStepAMGCoarseSolverPolicy\n-A policy class for solving the coarse level system using one step of AMG.\n-Definition: twolevelmethod.hh:234\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::OneStepAMGCoarseSolverPolicy\n-OneStepAMGCoarseSolverPolicy(const SmootherArgs &args, const Criterion &c)\n-Constructs the coarse solver policy.\n-Definition: twolevelmethod.hh:253\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::CoarseLevelSolver\n-AMGInverseOperator CoarseLevelSolver\n-The type of solver constructed for the coarse level.\n-Definition: twolevelmethod.hh:315\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::OneStepAMGCoarseSolverPolicy\n-OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy &other)\n-Copy constructor.\n-Definition: twolevelmethod.hh:257\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::X\n-O::range_type X\n-The type of the range and domain of the operator.\n-Definition: twolevelmethod.hh:239\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::Criterion\n-C Criterion\n-The type of the crition used for the aggregation within AMG.\n-Definition: twolevelmethod.hh:241\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::SmootherArgs\n-Dune::Amg::SmootherTraits< S >::Arguments SmootherArgs\n-The type of the arguments used for constructing the smoother.\n-Definition: twolevelmethod.hh:245\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::Operator\n-O Operator\n-The type of the linear operator used.\n-Definition: twolevelmethod.hh:237\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::AMGType\n-AMG< Operator, X, Smoother > AMGType\n-The type of the AMG construct on the coarse level.\n-Definition: twolevelmethod.hh:247\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::createCoarseLevelSolver\n-CoarseLevelSolver * createCoarseLevelSolver(P &transferPolicy)\n-Constructs a coarse level solver.\n-Definition: twolevelmethod.hh:325\n-Dune::Amg::OneStepAMGCoarseSolverPolicy::Smoother\n-S Smoother\n-The type of the smoother used in AMG.\n-Definition: twolevelmethod.hh:243\n-Dune::Amg::TwoLevelMethod\n-Definition: twolevelmethod.hh:353\n-Dune::Amg::TwoLevelMethod::CoarseRangeType\n-CoarseOperatorType::range_type CoarseRangeType\n-The type of the range of the coarse level operator.\n-Definition: twolevelmethod.hh:380\n-Dune::Amg::TwoLevelMethod::FineDomainType\n-FineOperatorType::domain_type FineDomainType\n-The type of the domain of the fine level operator.\n-Definition: twolevelmethod.hh:371\n-Dune::Amg::TwoLevelMethod::TwoLevelMethod\n-TwoLevelMethod(const TwoLevelMethod &other)\n-Definition: twolevelmethod.hh:418\n-Dune::Amg::TwoLevelMethod::pre\n-void pre(FineDomainType &x, FineRangeType &b)\n-Definition: twolevelmethod.hh:431\n-Dune::Amg::TwoLevelMethod::FineOperatorType\n-FO FineOperatorType\n-The linear operator of the finel level system. Has to be derived from\n-AssembledLinearOperator.\n-Definition: twolevelmethod.hh:363\n-Dune::Amg::TwoLevelMethod::CoarseLevelSolver\n-CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver\n-The type of the coarse level solver.\n-Definition: twolevelmethod.hh:358\n-Dune::Amg::TwoLevelMethod::apply\n-void apply(FineDomainType &v, const FineRangeType &d)\n-Definition: twolevelmethod.hh:439\n-Dune::Amg::TwoLevelMethod::CoarseLevelSolverPolicy\n-CSP CoarseLevelSolverPolicy\n-The type of the policy for constructing the coarse level solver.\n-Definition: twolevelmethod.hh:356\n-Dune::Amg::TwoLevelMethod::CoarseDomainType\n-CoarseOperatorType::domain_type CoarseDomainType\n-The type of the domain of the coarse level operator.\n-Definition: twolevelmethod.hh:384\n-Dune::Amg::TwoLevelMethod::TwoLevelMethod\n-TwoLevelMethod(const FineOperatorType &op, std::shared_ptr< SmootherType >\n-smoother, const LevelTransferPolicy< FineOperatorType, CoarseOperatorType >\n-&policy, CoarseLevelSolverPolicy &coarsePolicy, std::size_t preSteps=1, std::\n-size_t postSteps=1)\n-Constructs a two level method.\n-Definition: twolevelmethod.hh:404\n-Dune::Amg::TwoLevelMethod::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: twolevelmethod.hh:466\n-Dune::Amg::TwoLevelMethod::FineRangeType\n-FineOperatorType::range_type FineRangeType\n-The type of the range of the fine level operator.\n-Definition: twolevelmethod.hh:367\n-Dune::Amg::TwoLevelMethod::~TwoLevelMethod\n-~TwoLevelMethod()\n-Definition: twolevelmethod.hh:424\n-Dune::Amg::TwoLevelMethod::CoarseOperatorType\n-CSP::Operator CoarseOperatorType\n-The linear operator of the finel level system. Has to be derived from\n-AssembledLinearOperator.\n-Definition: twolevelmethod.hh:376\n-Dune::Amg::TwoLevelMethod::post\n-void post(FineDomainType &x)\n-Definition: twolevelmethod.hh:436\n-Dune::Amg::TwoLevelMethod::SmootherType\n-S SmootherType\n-The type of the fine level smoother.\n-Definition: twolevelmethod.hh:388\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperator\n-Abstract base class for all solvers.\n-Definition: solver.hh:99\n-Dune::InverseOperator<_X,_X_>::apply\n-virtual void apply(X &x, X &b, InverseOperatorResult &res)=0\n-Apply inverse operator,.\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n+Dune::ReboundAllocatorType\n+typename std::allocator_traits< typename AllocatorTraits< T >::type >::template\n+rebind_alloc< X > ReboundAllocatorType\n+Definition: allocator.hh:37\n+Dune::AllocatorType\n+typename AllocatorTraits< T >::type AllocatorType\n+Definition: allocator.hh:34\n+Dune::exists\n+Definition: allocator.hh:14\n+Dune::exists::value\n+static const bool value\n+Definition: allocator.hh:15\n+Dune::DefaultAllocatorTraits\n+Definition: allocator.hh:20\n+Dune::DefaultAllocatorTraits::type\n+std::allocator< T > type\n+Definition: allocator.hh:21\n+Dune::DefaultAllocatorTraits<_T,_std::void_t<_typename_T::allocator_type_>_>::\n+type\n+typename T::allocator_type type\n+Definition: allocator.hh:27\n+Dune::AllocatorTraits\n+Definition: allocator.hh:31\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00116.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00116.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: construction.hh File Reference\n+dune-istl: preconditioner.hh File Reference\n \n \n \n \n \n \n \n@@ -58,71 +58,40 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n \n- \n+
    preconditioner.hh File Reference
    \n
    \n
    \n-\n-

    Helper classes for the construction of classes without empty constructor. \n-More...

    \n-
    #include <dune/istl/bvector.hh>
    \n-#include <dune/istl/operators.hh>
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n-#include <dune/istl/solvercategory.hh>
    \n-#include "pinfo.hh"
    \n+
    #include <dune/common/exceptions.hh>
    \n+#include "solvercategory.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    struct  Dune::Amg::ConstructionTraits< T >
     Traits class for generically constructing non default constructable types. More...
     
    struct  Dune::Amg::ConstructionTraits< BlockVector< T, A > >
     
    struct  Dune::Amg::ParallelOperatorArgs< M, C >
     
    struct  Dune::Amg::OwnerOverlapCopyCommunicationArgs
     
    struct  Dune::Amg::SequentialCommunicationArgs
     
    struct  Dune::Amg::ConstructionTraits< OverlappingSchwarzOperator< M, X, Y, C > >
     
    struct  Dune::Amg::ConstructionTraits< NonoverlappingSchwarzOperator< M, X, Y, C > >
     
    struct  Dune::Amg::MatrixAdapterArgs< M, X, Y >
     
    struct  Dune::Amg::ConstructionTraits< MatrixAdapter< M, X, Y > >
     
    struct  Dune::Amg::ConstructionTraits< SequentialInformation >
     
    struct  Dune::Amg::ConstructionTraits< OwnerOverlapCopyCommunication< T1, T2 > >
    class  Dune::Preconditioner< X, Y >
     Base class for matrix free definition of preconditioners. More...
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Helper classes for the construction of classes without empty constructor.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,60 +4,22 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n Classes | Namespaces\n-construction.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Helper classes for the construction of classes without empty constructor.\n-More...\n-#include \n-#include \n-#include \n-#include \n-#include \"pinfo.hh\"\n+preconditioner.hh File Reference\n+#include \n+#include \"solvercategory.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::ConstructionTraits<_T_>\n-\u00a0 Traits class for generically constructing non default constructable\n- types. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::ParallelOperatorArgs<_M,_C_>\n-\u00a0\n-struct \u00a0Dune::Amg::OwnerOverlapCopyCommunicationArgs\n-\u00a0\n-struct \u00a0Dune::Amg::SequentialCommunicationArgs\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C\n- >_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,\n- C_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::MatrixAdapterArgs<_M,_X,_Y_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SequentialInformation_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>\n- >\n+class \u00a0Dune::Preconditioner<_X,_Y_>\n+\u00a0 Base class for matrix free definition of preconditioners. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n-***** Detailed Description *****\n-Helper classes for the construction of classes without empty constructor.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00116_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00116_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: construction.hh Source File\n+dune-istl: preconditioner.hh Source File\n \n \n \n \n \n \n \n@@ -58,218 +58,74 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    construction.hh
    \n+
    preconditioner.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMGCONSTRUCTION_HH
    \n-
    6#define DUNE_AMGCONSTRUCTION_HH
    \n+
    5#ifndef DUNE_ISTL_PRECONDITIONER_HH
    \n+
    6#define DUNE_ISTL_PRECONDITIONER_HH
    \n
    7
    \n-\n-\n-\n-\n-
    12#include "pinfo.hh"
    \n-
    13
    \n-
    14namespace Dune
    \n-
    15{
    \n-
    16 namespace Amg
    \n-
    17 {
    \n-
    18
    \n-
    37 template<typename T>
    \n-\n-
    39 {
    \n-
    44 typedef const void* Arguments;
    \n-
    45
    \n-
    52 static inline std::shared_ptr<T> construct(Arguments& args)
    \n-
    53 {
    \n-
    54 return std::make_shared<T>();
    \n-
    55 }
    \n-
    56 };
    \n-
    57
    \n-
    58 template<class T, class A>
    \n-\n-
    60 {
    \n-
    61 typedef const int Arguments;
    \n-
    62 static inline std::shared_ptr<BlockVector<T,A>> construct(Arguments& n)
    \n-
    63 {
    \n-
    64 return std::make_shared<BlockVector<T,A>>(n);
    \n-
    65 }
    \n-
    66 };
    \n-
    67
    \n-
    68 template<class M, class C>
    \n-\n-
    70 {
    \n-
    71 ParallelOperatorArgs(std::shared_ptr<M> matrix, const C& comm)
    \n-
    72 : matrix_(matrix), comm_(comm)
    \n-
    73 {}
    \n-
    74
    \n-
    75 std::shared_ptr<M> matrix_;
    \n-
    76 const C& comm_;
    \n-
    77 };
    \n-
    78
    \n-
    79#if HAVE_MPI
    \n-\n-
    81 {
    \n-\n-
    83 : comm_(comm), cat_(cat)
    \n-
    84 {}
    \n-
    85
    \n-
    86 MPI_Comm comm_;
    \n-\n-
    88 };
    \n-
    89#endif
    \n-
    90
    \n-\n-
    92 {
    \n-
    93 SequentialCommunicationArgs(Communication<void*> comm, [[maybe_unused]] int cat)
    \n-
    94 : comm_(comm)
    \n-
    95 {}
    \n-
    96
    \n-
    97 Communication<void*> comm_;
    \n-
    98 };
    \n-
    99
    \n-
    100 } // end Amg namspace
    \n-
    101
    \n-
    102 // forward declaration
    \n-
    103 template<class M, class X, class Y, class C>
    \n-\n+
    8#include <dune/common/exceptions.hh>
    \n+
    9
    \n+
    10#include "solvercategory.hh"
    \n+
    11
    \n+
    12namespace Dune {
    \n+
    17 //=====================================================================
    \n+
    30 //=====================================================================
    \n+
    31 template<class X, class Y>
    \n+\n+
    33 public:
    \n+
    35 typedef X domain_type;
    \n+
    37 typedef Y range_type;
    \n+
    39 typedef typename X::field_type field_type;
    \n+
    40
    \n+
    69 virtual void pre (X& x, Y& b) = 0;
    \n+
    70
    \n+
    81 virtual void apply (X& v, const Y& d) = 0;
    \n+
    82
    \n+
    91 virtual void post (X& x) = 0;
    \n+
    92
    \n+\n+
    95#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE
    \n+
    96 {
    \n+
    97 DUNE_THROW(Dune::Exception,"It is necessary to implement the category method in a derived classes, in the future this method will pure virtual.");
    \n+
    98 }
    \n+
    99#else
    \n+
    100 = 0;
    \n+
    101#endif
    \n+
    102
    \n+
    104 virtual ~Preconditioner () {}
    \n
    105
    \n-
    106 template<class M, class X, class Y, class C>
    \n-\n-
    108
    \n-
    109 namespace Amg
    \n-
    110 {
    \n-
    111 template<class M, class X, class Y, class C>
    \n-\n-
    113 {
    \n-\n-
    115
    \n-
    116 static inline std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C>> construct(const Arguments& args)
    \n-
    117 {
    \n-
    118 return std::make_shared<OverlappingSchwarzOperator<M,X,Y,C>>
    \n-
    119 (args.matrix_, args.comm_);
    \n-
    120 }
    \n-
    121 };
    \n-
    122
    \n-
    123 template<class M, class X, class Y, class C>
    \n-\n-
    125 {
    \n-\n-
    127
    \n-
    128 static inline std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C>> construct(const Arguments& args)
    \n-
    129 {
    \n-
    130 return std::make_shared<NonoverlappingSchwarzOperator<M,X,Y,C>>
    \n-
    131 (args.matrix_, args.comm_);
    \n-
    132 }
    \n-
    133 };
    \n-
    134
    \n-
    135 template<class M, class X, class Y>
    \n-\n-
    137 {
    \n-
    138 MatrixAdapterArgs(std::shared_ptr<M> matrix, const SequentialInformation)
    \n-
    139 : matrix_(matrix)
    \n-
    140 {}
    \n-
    141
    \n-
    142 std::shared_ptr<M> matrix_;
    \n-
    143 };
    \n-
    144
    \n-
    145 template<class M, class X, class Y>
    \n-\n-
    147 {
    \n-\n-
    149
    \n-
    150 static inline std::shared_ptr<MatrixAdapter<M,X,Y>> construct(Arguments& args)
    \n-
    151 {
    \n-
    152 return std::make_shared<MatrixAdapter<M,X,Y>>(args.matrix_);
    \n-
    153 }
    \n-
    154 };
    \n-
    155
    \n-
    156 template<>
    \n-\n-
    158 {
    \n-\n-
    160 static inline std::shared_ptr<SequentialInformation> construct(Arguments& args)
    \n-
    161 {
    \n-
    162 return std::make_shared<SequentialInformation>(args.comm_);
    \n-
    163 }
    \n-
    164 };
    \n-
    165
    \n-
    166
    \n-
    167#if HAVE_MPI
    \n-
    168
    \n-
    169 template<class T1, class T2>
    \n-\n-
    171 {
    \n-\n-
    173
    \n-
    174 static inline std::shared_ptr<OwnerOverlapCopyCommunication<T1,T2>> construct(Arguments& args)
    \n-
    175 {
    \n-
    176 return std::make_shared<OwnerOverlapCopyCommunication<T1,T2>>(args.comm_, args.cat_);
    \n-
    177 }
    \n-
    178 };
    \n-
    179
    \n-
    180#endif
    \n-
    181
    \n-
    183 } // namespace Amg
    \n-
    184} // namespace Dune
    \n-
    185#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n-\n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-
    const int Arguments
    Definition: construction.hh:61
    \n-
    SequentialCommunicationArgs(Communication< void * > comm, int cat)
    Definition: construction.hh:93
    \n-
    OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category cat)
    Definition: construction.hh:82
    \n-
    MPI_Comm comm_
    Definition: construction.hh:86
    \n-
    SolverCategory::Category cat_
    Definition: construction.hh:87
    \n-
    const C & comm_
    Definition: construction.hh:76
    \n-
    ParallelOperatorArgs(std::shared_ptr< M > matrix, const C &comm)
    Definition: construction.hh:71
    \n-
    std::shared_ptr< M > matrix_
    Definition: construction.hh:75
    \n-
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n-
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n-
    Communication< void * > comm_
    Definition: construction.hh:97
    \n-
    static std::shared_ptr< BlockVector< T, A > > construct(Arguments &n)
    Definition: construction.hh:62
    \n+
    106 };
    \n+
    107
    \n+
    111}
    \n+
    112#endif
    \n+\n
    Definition: allocator.hh:11
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n-
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n-
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    Definition: construction.hh:70
    \n-
    Definition: construction.hh:81
    \n-
    Definition: construction.hh:92
    \n-
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n-
    ParallelOperatorArgs< M, C > Arguments
    Definition: construction.hh:114
    \n-
    static std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > construct(const Arguments &args)
    Definition: construction.hh:116
    \n-
    ParallelOperatorArgs< M, C > Arguments
    Definition: construction.hh:126
    \n-
    static std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > construct(const Arguments &args)
    Definition: construction.hh:128
    \n-
    Definition: construction.hh:137
    \n-
    MatrixAdapterArgs(std::shared_ptr< M > matrix, const SequentialInformation)
    Definition: construction.hh:138
    \n-
    std::shared_ptr< M > matrix_
    Definition: construction.hh:142
    \n-
    static std::shared_ptr< MatrixAdapter< M, X, Y > > construct(Arguments &args)
    Definition: construction.hh:150
    \n-
    const MatrixAdapterArgs< M, X, Y > Arguments
    Definition: construction.hh:148
    \n-
    const SequentialCommunicationArgs Arguments
    Definition: construction.hh:159
    \n-
    static std::shared_ptr< SequentialInformation > construct(Arguments &args)
    Definition: construction.hh:160
    \n-
    static std::shared_ptr< OwnerOverlapCopyCommunication< T1, T2 > > construct(Arguments &args)
    Definition: construction.hh:174
    \n-
    const OwnerOverlapCopyCommunicationArgs Arguments
    Definition: construction.hh:172
    \n-
    Definition: pinfo.hh:28
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    virtual void post(X &x)=0
    Clean up.
    \n+
    virtual void apply(X &v, const Y &d)=0
    Apply one step of the preconditioner to the system A(v)=d.
    \n+
    virtual ~Preconditioner()
    every abstract base class has a virtual destructor
    Definition: preconditioner.hh:104
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioner.hh:37
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioner.hh:35
    \n+
    virtual SolverCategory::Category category() const =0
    Category of the preconditioner (see SolverCategory::Category)
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n+
    virtual void pre(X &x, Y &b)=0
    Prepare the preconditioner.
    \n
    Category
    Definition: solvercategory.hh:23
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,305 +4,93 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-construction.hh\n+preconditioner.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMGCONSTRUCTION_HH\n- 6#define DUNE_AMGCONSTRUCTION_HH\n+ 5#ifndef DUNE_ISTL_PRECONDITIONER_HH\n+ 6#define DUNE_ISTL_PRECONDITIONER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \"pinfo.hh\"\n- 13\n- 14namespace Dune\n- 15{\n- 16 namespace Amg\n- 17 {\n- 18\n- 37 template\n-38 struct ConstructionTraits\n- 39 {\n-44 typedef const void* Arguments;\n- 45\n-52 static inline std::shared_ptr construct(Arguments& args)\n- 53 {\n- 54 return std::make_shared();\n- 55 }\n- 56 };\n- 57\n- 58 template\n-59 struct ConstructionTraits >\n- 60 {\n-61 typedef const int Arguments;\n-62 static inline std::shared_ptr> construct(Arguments& n)\n- 63 {\n- 64 return std::make_shared>(n);\n- 65 }\n- 66 };\n- 67\n- 68 template\n-69 struct ParallelOperatorArgs\n- 70 {\n-71 ParallelOperatorArgs(std::shared_ptr matrix, const C& comm)\n- 72 : matrix_(matrix), comm_(comm)\n- 73 {}\n- 74\n-75 std::shared_ptr matrix_;\n-76 const C& comm_;\n- 77 };\n- 78\n- 79#if HAVE_MPI\n-80 struct OwnerOverlapCopyCommunicationArgs\n- 81 {\n-82 OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category\n-cat)\n- 83 : comm_(comm), cat_(cat)\n- 84 {}\n- 85\n-86 MPI_Comm comm_;\n-87 SolverCategory::Category cat_;\n- 88 };\n- 89#endif\n- 90\n-91 struct SequentialCommunicationArgs\n- 92 {\n-93 SequentialCommunicationArgs(Communication comm, [[maybe_unused]] int\n-cat)\n- 94 : comm_(comm)\n- 95 {}\n- 96\n-97 Communication comm_;\n- 98 };\n- 99\n- 100 } // end Amg namspace\n- 101\n- 102 // forward declaration\n- 103 template\n- 104 class OverlappingSchwarzOperator;\n+ 8#include \n+ 9\n+ 10#include \"solvercategory.hh\"\n+ 11\n+ 12namespace Dune {\n+ 17 //=====================================================================\n+ 30 //=====================================================================\n+ 31 template\n+32 class Preconditioner {\n+ 33 public:\n+35 typedef X domain_type;\n+37 typedef Y range_type;\n+39 typedef typename X::field_type field_type;\n+ 40\n+69 virtual void pre (X& x, Y& b) = 0;\n+ 70\n+81 virtual void apply (X& v, const Y& d) = 0;\n+ 82\n+91 virtual void post (X& x) = 0;\n+ 92\n+94 virtual SolverCategory::Category category() const\n+ 95#if DUNE_ISTL_SUPPORT_OLD_CATEGORY_INTERFACE\n+ 96 {\n+ 97 DUNE_THROW(Dune::Exception,\"It is necessary to implement the category\n+method in a derived classes, in the future this method will pure virtual.\");\n+ 98 }\n+ 99#else\n+ 100 = 0;\n+ 101#endif\n+ 102\n+104 virtual ~Preconditioner () {}\n 105\n- 106 template\n- 107 class NonoverlappingSchwarzOperator;\n- 108\n- 109 namespace Amg\n- 110 {\n- 111 template\n-112 struct ConstructionTraits >\n- 113 {\n-114 typedef ParallelOperatorArgs Arguments;\n- 115\n-116 static inline std::shared_ptr>\n-construct(const Arguments& args)\n- 117 {\n- 118 return std::make_shared>\n- 119 (args.matrix_, args.comm_);\n- 120 }\n- 121 };\n- 122\n- 123 template\n-124 struct ConstructionTraits >\n- 125 {\n-126 typedef ParallelOperatorArgs Arguments;\n- 127\n-128 static inline std::shared_ptr>\n-construct(const Arguments& args)\n- 129 {\n- 130 return std::make_shared>\n- 131 (args.matrix_, args.comm_);\n- 132 }\n- 133 };\n- 134\n- 135 template\n-136 struct MatrixAdapterArgs\n- 137 {\n-138 MatrixAdapterArgs(std::shared_ptr matrix, const SequentialInformation)\n- 139 : matrix_(matrix)\n- 140 {}\n- 141\n-142 std::shared_ptr matrix_;\n- 143 };\n- 144\n- 145 template\n-146 struct ConstructionTraits >\n- 147 {\n-148 typedef const MatrixAdapterArgs Arguments;\n- 149\n-150 static inline std::shared_ptr> construct(Arguments&\n-args)\n- 151 {\n- 152 return std::make_shared>(args.matrix_);\n- 153 }\n- 154 };\n- 155\n- 156 template<>\n-157 struct ConstructionTraits\n- 158 {\n-159 typedef const SequentialCommunicationArgs Arguments;\n-160 static inline std::shared_ptr construct(Arguments&\n-args)\n- 161 {\n- 162 return std::make_shared(args.comm_);\n- 163 }\n- 164 };\n- 165\n- 166\n- 167#if HAVE_MPI\n- 168\n- 169 template\n-170 struct ConstructionTraits >\n- 171 {\n-172 typedef const OwnerOverlapCopyCommunicationArgs Arguments;\n- 173\n-174 static inline std::shared_ptr>\n-construct(Arguments& args)\n- 175 {\n- 176 return std::make_shared>(args.comm_,\n-args.cat_);\n- 177 }\n- 178 };\n- 179\n- 180#endif\n- 181\n- 183 } // namespace Amg\n- 184} // namespace Dune\n- 185#endif\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-pinfo.hh\n+ 106 };\n+ 107\n+ 111}\n+ 112#endif\n solvercategory.hh\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>::Arguments\n-const int Arguments\n-Definition: construction.hh:61\n-Dune::Amg::SequentialCommunicationArgs::SequentialCommunicationArgs\n-SequentialCommunicationArgs(Communication< void * > comm, int cat)\n-Definition: construction.hh:93\n-Dune::Amg::OwnerOverlapCopyCommunicationArgs::OwnerOverlapCopyCommunicationArgs\n-OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category cat)\n-Definition: construction.hh:82\n-Dune::Amg::OwnerOverlapCopyCommunicationArgs::comm_\n-MPI_Comm comm_\n-Definition: construction.hh:86\n-Dune::Amg::OwnerOverlapCopyCommunicationArgs::cat_\n-SolverCategory::Category cat_\n-Definition: construction.hh:87\n-Dune::Amg::ParallelOperatorArgs::comm_\n-const C & comm_\n-Definition: construction.hh:76\n-Dune::Amg::ParallelOperatorArgs::ParallelOperatorArgs\n-ParallelOperatorArgs(std::shared_ptr< M > matrix, const C &comm)\n-Definition: construction.hh:71\n-Dune::Amg::ParallelOperatorArgs::matrix_\n-std::shared_ptr< M > matrix_\n-Definition: construction.hh:75\n-Dune::Amg::ConstructionTraits::Arguments\n-const void * Arguments\n-A type holding all the arguments needed to call the constructor.\n-Definition: construction.hh:44\n-Dune::Amg::ConstructionTraits::construct\n-static std::shared_ptr< T > construct(Arguments &args)\n-Construct an object with the specified arguments.\n-Definition: construction.hh:52\n-Dune::Amg::SequentialCommunicationArgs::comm_\n-Communication< void * > comm_\n-Definition: construction.hh:97\n-Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>::construct\n-static std::shared_ptr< BlockVector< T, A > > construct(Arguments &n)\n-Definition: construction.hh:62\n Dune\n Definition: allocator.hh:11\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::NonoverlappingSchwarzOperator\n-A nonoverlapping operator with communication object.\n-Definition: novlpschwarz.hh:61\n-Dune::Amg::ConstructionTraits\n-Traits class for generically constructing non default constructable types.\n-Definition: construction.hh:39\n-Dune::MatrixAdapter\n-Adapter to turn a matrix into a linear operator.\n-Definition: operators.hh:137\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::Amg::ParallelOperatorArgs\n-Definition: construction.hh:70\n-Dune::Amg::OwnerOverlapCopyCommunicationArgs\n-Definition: construction.hh:81\n-Dune::Amg::SequentialCommunicationArgs\n-Definition: construction.hh:92\n-Dune::OverlappingSchwarzOperator\n-An overlapping Schwarz operator.\n-Definition: schwarz.hh:75\n-Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n-Arguments\n-ParallelOperatorArgs< M, C > Arguments\n-Definition: construction.hh:114\n-Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n-construct\n-static std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > construct\n-(const Arguments &args)\n-Definition: construction.hh:116\n-Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n-Arguments\n-ParallelOperatorArgs< M, C > Arguments\n-Definition: construction.hh:126\n-Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n-construct\n-static std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > construct\n-(const Arguments &args)\n-Definition: construction.hh:128\n-Dune::Amg::MatrixAdapterArgs\n-Definition: construction.hh:137\n-Dune::Amg::MatrixAdapterArgs::MatrixAdapterArgs\n-MatrixAdapterArgs(std::shared_ptr< M > matrix, const SequentialInformation)\n-Definition: construction.hh:138\n-Dune::Amg::MatrixAdapterArgs::matrix_\n-std::shared_ptr< M > matrix_\n-Definition: construction.hh:142\n-Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>::construct\n-static std::shared_ptr< MatrixAdapter< M, X, Y > > construct(Arguments &args)\n-Definition: construction.hh:150\n-Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>::Arguments\n-const MatrixAdapterArgs< M, X, Y > Arguments\n-Definition: construction.hh:148\n-Dune::Amg::ConstructionTraits<_SequentialInformation_>::Arguments\n-const SequentialCommunicationArgs Arguments\n-Definition: construction.hh:159\n-Dune::Amg::ConstructionTraits<_SequentialInformation_>::construct\n-static std::shared_ptr< SequentialInformation > construct(Arguments &args)\n-Definition: construction.hh:160\n-Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>_>::\n-construct\n-static std::shared_ptr< OwnerOverlapCopyCommunication< T1, T2 > > construct\n-(Arguments &args)\n-Definition: construction.hh:174\n-Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>_>::\n-Arguments\n-const OwnerOverlapCopyCommunicationArgs Arguments\n-Definition: construction.hh:172\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::Preconditioner::post\n+virtual void post(X &x)=0\n+Clean up.\n+Dune::Preconditioner::apply\n+virtual void apply(X &v, const Y &d)=0\n+Apply one step of the preconditioner to the system A(v)=d.\n+Dune::Preconditioner::~Preconditioner\n+virtual ~Preconditioner()\n+every abstract base class has a virtual destructor\n+Definition: preconditioner.hh:104\n+Dune::Preconditioner::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioner.hh:37\n+Dune::Preconditioner::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioner.hh:35\n+Dune::Preconditioner::category\n+virtual SolverCategory::Category category() const =0\n+Category of the preconditioner (see SolverCategory::Category)\n+Dune::Preconditioner::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioner.hh:39\n+Dune::Preconditioner::pre\n+virtual void pre(X &x, Y &b)=0\n+Prepare the preconditioner.\n Dune::SolverCategory::Category\n Category\n Definition: solvercategory.hh:23\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00119.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00119.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: renumberer.hh File Reference\n+dune-istl: supermatrix.hh File Reference\n \n \n \n \n \n \n \n@@ -58,46 +58,68 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n \n-
    renumberer.hh File Reference
    \n+Namespaces
    \n+
    supermatrix.hh File Reference
    \n \n
    \n-
    #include "aggregates.hh"
    \n+
    #include "bcrsmatrix.hh"
    \n+#include "bvector.hh"
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <limits>
    \n+#include <dune/istl/bccsmatrixinitializer.hh>
    \n+#include "superlufunctions.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::AggregateRenumberer< G >
    struct  Dune::SuperMatrixCreateSparseChooser< T >
     
    struct  Dune::SuperMatrixPrinter< T >
     
    struct  Dune::BaseGetSuperLUType< T >
     
    struct  Dune::GetSuperLUType< T >
     
    struct  Dune::GetSuperLUType< double >
     
    struct  Dune::GetSuperLUType< float >
     
    struct  Dune::GetSuperLUType< std::complex< double > >
     
    struct  Dune::GetSuperLUType< std::complex< float > >
     
    struct  Dune::SuperLUMatrix< M >
     Utility class for converting an ISTL Matrix into a SuperLU Matrix. More...
     
    struct  Dune::SuperMatrixInitializer< M >
     
    class  Dune::SuperLUMatrix< BCRSMatrix< B, TA > >
     Converter for BCRSMatrix to SuperLU Matrix. More...
     
    class  Dune::SuperMatrixInitializer< BCRSMatrix< B, A > >
     
    \n \n \n \n-\n-\n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n-\n

    \n-Functions

    template<class G , class I , class V >
    void Dune::Amg::renumberAggregates (const G &graph, I index, I endIndex, V &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)
     
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,28 +4,52 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces | Functions\n-renumberer.hh File Reference\n-#include \"aggregates.hh\"\n+Classes | Namespaces\n+supermatrix.hh File Reference\n+#include \"bcrsmatrix.hh\"\n+#include \"bvector.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"superlufunctions.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::AggregateRenumberer<_G_>\n+struct \u00a0Dune::SuperMatrixCreateSparseChooser<_T_>\n \u00a0\n- Namespaces\n-namespace \u00a0Dune\n+struct \u00a0Dune::SuperMatrixPrinter<_T_>\n+\u00a0\n+struct \u00a0Dune::BaseGetSuperLUType<_T_>\n+\u00a0\n+struct \u00a0Dune::GetSuperLUType<_T_>\n+\u00a0\n+struct \u00a0Dune::GetSuperLUType<_double_>\n+\u00a0\n+struct \u00a0Dune::GetSuperLUType<_float_>\n+\u00a0\n+struct \u00a0Dune::GetSuperLUType<_std::complex<_double_>_>\n \u00a0\n-namespace \u00a0Dune::Amg\n+struct \u00a0Dune::GetSuperLUType<_std::complex<_float_>_>\n \u00a0\n- Functions\n-template\n-void\u00a0Dune::Amg::renumberAggregates (const G &graph, I index, I endIndex, V\n- &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)\n+struct \u00a0Dune::SuperLUMatrix<_M_>\n+\u00a0 Utility class for converting an ISTL Matrix into a SuperLU Matrix.\n+ More...\n+\u00a0\n+struct \u00a0Dune::SuperMatrixInitializer<_M_>\n+\u00a0\n+ class \u00a0Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>\n+\u00a0 Converter for BCRSMatrix to SuperLU Matrix. More...\n+\u00a0\n+ class \u00a0Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>\n+\u00a0\n+ Namespaces\n+namespace \u00a0Dune\n \u00a0\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00119_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00119_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: renumberer.hh Source File\n+dune-istl: supermatrix.hh Source File\n \n \n \n \n \n \n \n@@ -58,110 +58,381 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    renumberer.hh
    \n+
    supermatrix.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_RENUMBERER_HH
    \n-
    6#define DUNE_AMG_RENUMBERER_HH
    \n+
    5#ifndef DUNE_ISTL_SUPERMATRIX_HH
    \n+
    6#define DUNE_ISTL_SUPERMATRIX_HH
    \n
    7
    \n-
    8#include "aggregates.hh"
    \n+
    8#if HAVE_SUPERLU
    \n
    9
    \n-
    10namespace Dune
    \n-
    11{
    \n-
    12 namespace Amg
    \n-
    13 {
    \n-
    14 template<class G>
    \n-\n-
    16 {
    \n-
    17 public:
    \n-
    19 typedef typename G::VertexDescriptor Vertex;
    \n+
    10#include "bcrsmatrix.hh"
    \n+
    11#include "bvector.hh"
    \n+
    12#include <dune/common/fmatrix.hh>
    \n+
    13#include <dune/common/fvector.hh>
    \n+
    14#include <dune/common/typetraits.hh>
    \n+
    15#include <limits>
    \n+
    16
    \n+\n+
    18
    \n+
    19#include "superlufunctions.hh"
    \n
    20
    \n-\n-
    26
    \n-
    28 operator Vertex() const;
    \n-
    29
    \n-
    30 void operator()(const typename G::ConstEdgeIterator& edge);
    \n+
    21namespace Dune
    \n+
    22{
    \n+
    23
    \n+
    24 template<class T>
    \n+\n+
    26 {};
    \n+
    27
    \n+
    28 template<class T>
    \n+\n+
    30 {};
    \n
    31
    \n-
    32 void operator++();
    \n-
    33
    \n-
    34 protected:
    \n-\n-\n-
    37 };
    \n-
    38
    \n-
    39 template<class G>
    \n-\n-
    41 : number_(0), aggregates_(aggregates)
    \n-
    42 {}
    \n-
    43
    \n-
    44 template<class G>
    \n-\n-
    46 {
    \n-
    47 return number_;
    \n-
    48 }
    \n-
    49
    \n-
    50 template<class G>
    \n-
    51 void AggregateRenumberer<G>::operator()(const typename G::ConstEdgeIterator& edge)
    \n-
    52 {
    \n-
    53 aggregates_[edge.target()]=number_;
    \n-
    54 }
    \n-
    55
    \n-
    56 template<class G>
    \n-\n-
    58 {
    \n-
    59 ++number_;
    \n-
    60 }
    \n-
    61
    \n-
    62 template<class G, class I, class V>
    \n-
    63 void renumberAggregates(const G& graph, I index, I endIndex, V& visitedMap,
    \n-\n-
    65 {
    \n-
    66 AggregateRenumberer<G> renumberer(aggregates);
    \n+
    32#if __has_include("slu_sdefs.h")
    \n+
    33 template<>
    \n+\n+
    35 {
    \n+
    36 static void create(SuperMatrix *mat, int n, int m, int offset,
    \n+
    37 float *values, int *rowindex, int* colindex,
    \n+
    38 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n+
    39 {
    \n+
    40 sCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,
    \n+
    41 stype, dtype, mtype);
    \n+
    42 }
    \n+
    43 };
    \n+
    44
    \n+
    45 template<>
    \n+
    46 struct SuperMatrixPrinter<float>
    \n+
    47 {
    \n+
    48 static void print(char* name, SuperMatrix* mat)
    \n+
    49 {
    \n+
    50 sPrint_CompCol_Matrix(name, mat);
    \n+
    51 }
    \n+
    52 };
    \n+
    53#endif
    \n+
    54
    \n+
    55#if __has_include("slu_ddefs.h")
    \n+
    56 template<>
    \n+
    57 struct SuperMatrixCreateSparseChooser<double>
    \n+
    58 {
    \n+
    59 static void create(SuperMatrix *mat, int n, int m, int offset,
    \n+
    60 double *values, int *rowindex, int* colindex,
    \n+
    61 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n+
    62 {
    \n+
    63 dCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,
    \n+
    64 stype, dtype, mtype);
    \n+
    65 }
    \n+
    66 };
    \n
    67
    \n-
    68 for(I index1=index; index1 != endIndex; ++index1)
    \n-
    69 if(aggregates[index1.index()]!=AggregatesMap<typename G::VertexDescriptor>::ISOLATED &&
    \n-
    70 !get(visitedMap, index1.index())) {
    \n-
    71
    \n-
    72 aggregates.template breadthFirstSearch<false>(index1.index(), aggregates[index1.index()],
    \n-
    73 graph, renumberer, visitedMap);
    \n-
    74 aggregates[index1.index()] = renumberer;
    \n-
    75 ++renumberer;
    \n-
    76 }
    \n-
    77 for(; index != endIndex; ++index)
    \n-
    78 put(visitedMap, index.index(), false);
    \n-
    79 }
    \n-
    80
    \n-
    81 } // namespace AMG
    \n-
    82} // namespace Dune
    \n-
    83#endif
    \n-
    Provides classes for the Coloring process of AMG.
    \n+
    68 template<>
    \n+
    69 struct SuperMatrixPrinter<double>
    \n+
    70 {
    \n+
    71 static void print(char* name, SuperMatrix* mat)
    \n+
    72 {
    \n+
    73 dPrint_CompCol_Matrix(name, mat);
    \n+
    74 }
    \n+
    75 };
    \n+
    76#endif
    \n+
    77
    \n+
    78#if __has_include("slu_cdefs.h")
    \n+
    79 template<>
    \n+
    80 struct SuperMatrixCreateSparseChooser<std::complex<float> >
    \n+
    81 {
    \n+
    82 static void create(SuperMatrix *mat, int n, int m, int offset,
    \n+
    83 std::complex<float> *values, int *rowindex, int* colindex,
    \n+
    84 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n+
    85 {
    \n+
    86 cCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast< ::complex*>(values),
    \n+
    87 rowindex, colindex, stype, dtype, mtype);
    \n+
    88 }
    \n+
    89 };
    \n+
    90
    \n+
    91 template<>
    \n+
    92 struct SuperMatrixPrinter<std::complex<float> >
    \n+
    93 {
    \n+
    94 static void print(char* name, SuperMatrix* mat)
    \n+
    95 {
    \n+
    96 cPrint_CompCol_Matrix(name, mat);
    \n+
    97 }
    \n+
    98 };
    \n+
    99#endif
    \n+
    100
    \n+
    101#if __has_include("slu_zdefs.h")
    \n+
    102 template<>
    \n+
    103 struct SuperMatrixCreateSparseChooser<std::complex<double> >
    \n+
    104 {
    \n+
    105 static void create(SuperMatrix *mat, int n, int m, int offset,
    \n+
    106 std::complex<double> *values, int *rowindex, int* colindex,
    \n+
    107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n+
    108 {
    \n+
    109 zCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast<doublecomplex*>(values),
    \n+
    110 rowindex, colindex, stype, dtype, mtype);
    \n+
    111 }
    \n+
    112 };
    \n+
    113
    \n+
    114 template<>
    \n+
    115 struct SuperMatrixPrinter<std::complex<double> >
    \n+
    116 {
    \n+
    117 static void print(char* name, SuperMatrix* mat)
    \n+
    118 {
    \n+
    119 zPrint_CompCol_Matrix(name, mat);
    \n+
    120 }
    \n+
    121 };
    \n+
    122#endif
    \n+
    123
    \n+
    124 template<class T>
    \n+\n+
    126 {
    \n+
    127 static const Dtype_t type;
    \n+
    128 };
    \n+
    129
    \n+
    130 template<class T>
    \n+\n+
    132 {};
    \n+
    133
    \n+
    134 template<class T>
    \n+
    135 const Dtype_t BaseGetSuperLUType<T>::type =
    \n+
    136 std::is_same<T,float>::value ? SLU_S :
    \n+
    137 ( std::is_same<T,std::complex<double> >::value ? SLU_Z :
    \n+
    138 ( std::is_same<T,std::complex<float> >::value ? SLU_C : SLU_D ));
    \n+
    139
    \n+
    140 template<>
    \n+
    141 struct GetSuperLUType<double>
    \n+
    142 : public BaseGetSuperLUType<double>
    \n+
    143 {
    \n+
    144 typedef double float_type;
    \n+
    145 };
    \n+
    146
    \n+
    147 template<>
    \n+
    148 struct GetSuperLUType<float>
    \n+
    149 : public BaseGetSuperLUType<float>
    \n+
    150 {
    \n+
    151 typedef float float_type;
    \n+
    152 };
    \n+
    153
    \n+
    154 template<>
    \n+
    155 struct GetSuperLUType<std::complex<double> >
    \n+
    156 : public BaseGetSuperLUType<std::complex<double> >
    \n+
    157 {
    \n+
    158 typedef double float_type;
    \n+
    159 };
    \n+
    160
    \n+
    161 template<>
    \n+
    162 struct GetSuperLUType<std::complex<float> >
    \n+
    163 : public BaseGetSuperLUType<std::complex<float> >
    \n+
    164 {
    \n+
    165 typedef float float_type;
    \n+
    166
    \n+
    167 };
    \n+
    168
    \n+
    173 template<class M>
    \n+\n+
    175 {};
    \n+
    176
    \n+
    177 template<class M>
    \n+\n+
    179 {};
    \n+
    180
    \n+
    181 template<class T>
    \n+
    182 class SuperLU;
    \n+
    183
    \n+
    184 template<class M, class X, class TM, class TD, class T1>
    \n+\n+
    186
    \n+
    187 template<class T, bool flag>
    \n+\n+
    189
    \n+
    193 template<class B, class TA>
    \n+\n+
    195 : public ISTL::Impl::BCCSMatrix<typename BCRSMatrix<B,TA>::field_type, int>
    \n+
    196 {
    \n+
    197 template<class M, class X, class TM, class TD, class T1>
    \n+\n+
    199 friend struct SuperMatrixInitializer<BCRSMatrix<B,TA> >;
    \n+
    200 public:
    \n+\n+
    203
    \n+\n+
    205
    \n+
    206 typedef typename Matrix::size_type size_type;
    \n+
    207
    \n+
    212 explicit SuperLUMatrix(const Matrix& mat) : ISTL::Impl::BCCSMatrix<BCRSMatrix<B,TA>, int>(mat)
    \n+
    213 {}
    \n+
    214
    \n+
    215 SuperLUMatrix() : ISTL::Impl::BCCSMatrix<typename BCRSMatrix<B,TA>::field_type, int>()
    \n+
    216 {}
    \n+
    217
    \n+\n+
    220 {
    \n+
    221 if (this->N_+this->M_*this->Nnz_ != 0)
    \n+
    222 free();
    \n+
    223 }
    \n+
    224
    \n+
    226 operator SuperMatrix&()
    \n+
    227 {
    \n+
    228 return A;
    \n+
    229 }
    \n+
    230
    \n+
    232 operator const SuperMatrix&() const
    \n+
    233 {
    \n+
    234 return A;
    \n+
    235 }
    \n+
    236
    \n+\n+
    238 {
    \n+
    239 if (this->N_ + this->M_ + this->Nnz_!=0)
    \n+
    240 free();
    \n+
    241
    \n+
    242 using Matrix = BCRSMatrix<B,TA>;
    \n+\n+\n+
    245 ISTL::Impl::BCCSMatrixInitializer<Matrix, int> initializer(*this);
    \n+
    246
    \n+
    247 copyToBCCSMatrix(initializer, mat);
    \n+
    248
    \n+\n+
    250 ::create(&A, this->N_, this->M_, this->colstart[this->N_],
    \n+
    251 this->values,this->rowindex, this->colstart, SLU_NC,
    \n+
    252 static_cast<Dtype_t>(GetSuperLUType<typename Matrix::field_type>::type), SLU_GE);
    \n+
    253 return *this;
    \n+
    254 }
    \n+
    255
    \n+\n+
    257 {
    \n+
    258 if (this->N_ + this->M_ + this->Nnz_!=0)
    \n+
    259 free();
    \n+
    260
    \n+
    261 using Matrix = BCRSMatrix<B,TA>;
    \n+\n+\n+
    264 ISTL::Impl::BCCSMatrixInitializer<Matrix, int> initializer(*this);
    \n+
    265
    \n+
    266 copyToBCCSMatrix(initializer, mat);
    \n+
    267
    \n+\n+
    269 ::create(&A, this->N_, this->M_, this->colstart[this->N_],
    \n+
    270 this->values,this->rowindex, this->colstart, SLU_NC,
    \n+
    271 static_cast<Dtype_t>(GetSuperLUType<B>::type), SLU_GE);
    \n+
    272 return *this;
    \n+
    273 }
    \n+
    274
    \n+
    281 virtual void setMatrix(const Matrix& mat, const std::set<std::size_t>& mrs)
    \n+
    282 {
    \n+
    283 if(this->N_+this->M_+this->Nnz_!=0)
    \n+
    284 free();
    \n+
    285 this->N_=mrs.size()*MatrixDimension<typename Matrix::block_type>::rowdim(*(mat[0].begin()));
    \n+
    286 this->M_=mrs.size()*MatrixDimension<typename Matrix::block_type>::coldim(*(mat[0].begin()));
    \n+
    287 SuperMatrixInitializer<Matrix> initializer(*this);
    \n+
    288
    \n+
    289 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset<Matrix,std::set<std::size_t> >(mat,mrs));
    \n+
    290 }
    \n+
    291
    \n+
    293 virtual void setMatrix(const Matrix& mat)
    \n+
    294 {
    \n+\n+\n+
    297 SuperMatrixInitializer<Matrix> initializer(*this);
    \n+
    298
    \n+
    299 copyToBCCSMatrix(initializer, mat);
    \n+
    300 }
    \n+
    301
    \n+
    303 virtual void free()
    \n+
    304 {
    \n+
    305 ISTL::Impl::BCCSMatrix<typename BCRSMatrix<B,TA>::field_type, int>::free();
    \n+
    306 SUPERLU_FREE(A.Store);
    \n+
    307 }
    \n+
    308 private:
    \n+
    309 SuperMatrix A;
    \n+
    310 };
    \n+
    311
    \n+
    312 template<class B, class A>
    \n+\n+
    314 : public ISTL::Impl::BCCSMatrixInitializer<BCRSMatrix<B,A>, int>
    \n+
    315 {
    \n+
    316 template<class I, class S, class D>
    \n+\n+
    318 public:
    \n+\n+\n+
    321
    \n+
    322 SuperMatrixInitializer(SuperLUMatrix& lum) : ISTL::Impl::BCCSMatrixInitializer<BCRSMatrix<B,A>, int>(lum)
    \n+
    323 ,slumat(&lum)
    \n+
    324 {}
    \n+
    325
    \n+
    326 SuperMatrixInitializer() : ISTL::Impl::BCCSMatrixInitializer<BCRSMatrix<B,A>, int>()
    \n+
    327 {}
    \n+
    328
    \n+
    329 virtual void createMatrix() const
    \n+
    330 {
    \n+
    331 ISTL::Impl::BCCSMatrixInitializer<BCRSMatrix<B,A>, int>::createMatrix();
    \n+\n+
    333 ::create(&slumat->A, slumat->N_, slumat->M_, slumat->colstart[this->cols],
    \n+
    334 slumat->values,slumat->rowindex, slumat->colstart, SLU_NC,
    \n+
    335 static_cast<Dtype_t>(GetSuperLUType<typename Matrix::field_type>::type), SLU_GE);
    \n+
    336 }
    \n+
    337 private:
    \n+
    338 SuperLUMatrix* slumat;
    \n+
    339 };
    \n+
    340}
    \n+
    341#endif // HAVE_SUPERLU
    \n+
    342#endif
    \n+\n+
    Implementation of the BCRSMatrix class.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    void renumberAggregates(const G &graph, I index, I endIndex, V &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)
    Definition: renumberer.hh:63
    \n-\n-
    Definition: renumberer.hh:16
    \n-
    void operator++()
    Definition: renumberer.hh:57
    \n-
    G::VertexDescriptor Vertex
    The vertex type.
    Definition: renumberer.hh:19
    \n-
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: renumberer.hh:51
    \n-
    AggregatesMap< Vertex > & aggregates_
    Definition: renumberer.hh:36
    \n-
    AggregateRenumberer(AggregatesMap< Vertex > &aggregates)
    Constructor.
    Definition: renumberer.hh:40
    \n-
    Vertex number_
    Definition: renumberer.hh:35
    \n+
    Initializer for SuperLU Matrices representing the subdomains.
    Definition: overlappingschwarz.hh:47
    \n+
    static auto coldim(const M &A)
    Definition: matrixutils.hh:219
    \n+
    static auto rowdim(const M &A)
    Definition: matrixutils.hh:214
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n+
    Definition: overlappingschwarz.hh:694
    \n+
    SuperLu Solver.
    Definition: superlu.hh:271
    \n+
    Definition: supermatrix.hh:26
    \n+
    Definition: supermatrix.hh:30
    \n+
    Definition: supermatrix.hh:126
    \n+
    static const Dtype_t type
    Definition: supermatrix.hh:127
    \n+
    Definition: supermatrix.hh:132
    \n+
    double float_type
    Definition: supermatrix.hh:144
    \n+
    float float_type
    Definition: supermatrix.hh:151
    \n+
    double float_type
    Definition: supermatrix.hh:158
    \n+
    float float_type
    Definition: supermatrix.hh:165
    \n+
    Utility class for converting an ISTL Matrix into a SuperLU Matrix.
    Definition: supermatrix.hh:175
    \n+
    Definition: supermatrix.hh:179
    \n+
    virtual void free()
    free allocated space.
    Definition: supermatrix.hh:303
    \n+
    SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const SuperLUMatrix< BCRSMatrix< B, TA > > &mat)
    Definition: supermatrix.hh:256
    \n+
    SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const BCRSMatrix< B, TA > &mat)
    Definition: supermatrix.hh:237
    \n+
    SuperLUMatrix(const Matrix &mat)
    Constructor that initializes the data.
    Definition: supermatrix.hh:212
    \n+
    virtual void setMatrix(const Matrix &mat)
    Initialize data from given matrix.
    Definition: supermatrix.hh:293
    \n+
    SuperLUMatrix()
    Definition: supermatrix.hh:215
    \n+
    Matrix::size_type size_type
    Definition: supermatrix.hh:206
    \n+
    BCRSMatrix< B, TA > Matrix
    The type of the matrix to convert.
    Definition: supermatrix.hh:202
    \n+
    virtual void setMatrix(const Matrix &mat, const std::set< std::size_t > &mrs)
    Initialize data from a given set of matrix rows and columns.
    Definition: supermatrix.hh:281
    \n+
    virtual ~SuperLUMatrix()
    Destructor.
    Definition: supermatrix.hh:219
    \n+
    Dune::SuperLUMatrix< Matrix > SuperLUMatrix
    Definition: supermatrix.hh:320
    \n+
    BCRSMatrix< B, A > Matrix
    Definition: supermatrix.hh:319
    \n+
    SuperMatrixInitializer()
    Definition: supermatrix.hh:326
    \n+
    virtual void createMatrix() const
    Definition: supermatrix.hh:329
    \n+
    SuperMatrixInitializer(SuperLUMatrix &lum)
    Definition: supermatrix.hh:322
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,131 +4,465 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-renumberer.hh\n+supermatrix.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_RENUMBERER_HH\n- 6#define DUNE_AMG_RENUMBERER_HH\n+ 5#ifndef DUNE_ISTL_SUPERMATRIX_HH\n+ 6#define DUNE_ISTL_SUPERMATRIX_HH\n 7\n- 8#include \"aggregates.hh\"\n+ 8#if HAVE_SUPERLU\n 9\n- 10namespace Dune\n- 11{\n- 12 namespace Amg\n- 13 {\n- 14 template\n-15 class AggregateRenumberer\n- 16 {\n- 17 public:\n-19 typedef typename G::VertexDescriptor Vertex;\n+ 10#include \"bcrsmatrix.hh\"\n+ 11#include \"bvector.hh\"\n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16\n+ 17#include \n+ 18\n+ 19#include \"superlufunctions.hh\"\n 20\n- 25 AggregateRenumberer(AggregatesMap& aggregates);\n- 26\n- 28 operator Vertex() const;\n- 29\n- 30 void operator()(const typename G::ConstEdgeIterator& edge);\n+ 21namespace Dune\n+ 22{\n+ 23\n+ 24 template\n+25 struct SuperMatrixCreateSparseChooser\n+ 26 {};\n+ 27\n+ 28 template\n+29 struct SuperMatrixPrinter\n+ 30 {};\n 31\n- 32 void operator++();\n- 33\n- 34 protected:\n-35 Vertex number_;\n-36 AggregatesMap& aggregates_;\n- 37 };\n- 38\n- 39 template\n-40 AggregateRenumberer::AggregateRenumberer(AggregatesMap&\n-aggregates)\n- 41 : number_(0), aggregates_(aggregates)\n- 42 {}\n- 43\n- 44 template\n-45 AggregateRenumberer::operator Vertex() const\n- 46 {\n- 47 return number_;\n- 48 }\n- 49\n- 50 template\n-51 void AggregateRenumberer::operator()(const typename G::ConstEdgeIterator&\n-edge)\n- 52 {\n- 53 aggregates_[edge.target()]=number_;\n- 54 }\n- 55\n- 56 template\n-57 void AggregateRenumberer::operator++()\n+ 32#if __has_include(\"slu_sdefs.h\")\n+ 33 template<>\n+ 34 struct SuperMatrixCreateSparseChooser\n+ 35 {\n+ 36 static void create(SuperMatrix *mat, int n, int m, int offset,\n+ 37 float *values, int *rowindex, int* colindex,\n+ 38 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 39 {\n+ 40 sCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,\n+ 41 stype, dtype, mtype);\n+ 42 }\n+ 43 };\n+ 44\n+ 45 template<>\n+ 46 struct SuperMatrixPrinter\n+ 47 {\n+ 48 static void print(char* name, SuperMatrix* mat)\n+ 49 {\n+ 50 sPrint_CompCol_Matrix(name, mat);\n+ 51 }\n+ 52 };\n+ 53#endif\n+ 54\n+ 55#if __has_include(\"slu_ddefs.h\")\n+ 56 template<>\n+ 57 struct SuperMatrixCreateSparseChooser\n 58 {\n- 59 ++number_;\n- 60 }\n- 61\n- 62 template\n-63 void renumberAggregates(const G& graph, I index, I endIndex, V& visitedMap,\n- 64 AggregatesMap& aggregates)\n- 65 {\n- 66 AggregateRenumberer renumberer(aggregates);\n+ 59 static void create(SuperMatrix *mat, int n, int m, int offset,\n+ 60 double *values, int *rowindex, int* colindex,\n+ 61 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 62 {\n+ 63 dCreate_CompCol_Matrix(mat, n, m, offset, values, rowindex, colindex,\n+ 64 stype, dtype, mtype);\n+ 65 }\n+ 66 };\n 67\n- 68 for(I index1=index; index1 != endIndex; ++index1)\n- 69 if(aggregates[index1.index()]!=AggregatesMap::ISOLATED &&\n- 70 !get(visitedMap, index1.index())) {\n- 71\n- 72 aggregates.template breadthFirstSearch(index1.index(), aggregates\n-[index1.index()],\n- 73 graph, renumberer, visitedMap);\n- 74 aggregates[index1.index()] = renumberer;\n- 75 ++renumberer;\n- 76 }\n- 77 for(; index != endIndex; ++index)\n- 78 put(visitedMap, index.index(), false);\n- 79 }\n- 80\n- 81 } // namespace AMG\n- 82} // namespace Dune\n- 83#endif\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n+ 68 template<>\n+ 69 struct SuperMatrixPrinter\n+ 70 {\n+ 71 static void print(char* name, SuperMatrix* mat)\n+ 72 {\n+ 73 dPrint_CompCol_Matrix(name, mat);\n+ 74 }\n+ 75 };\n+ 76#endif\n+ 77\n+ 78#if __has_include(\"slu_cdefs.h\")\n+ 79 template<>\n+ 80 struct SuperMatrixCreateSparseChooser >\n+ 81 {\n+ 82 static void create(SuperMatrix *mat, int n, int m, int offset,\n+ 83 std::complex *values, int *rowindex, int* colindex,\n+ 84 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 85 {\n+ 86 cCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast< ::complex*>\n+(values),\n+ 87 rowindex, colindex, stype, dtype, mtype);\n+ 88 }\n+ 89 };\n+ 90\n+ 91 template<>\n+ 92 struct SuperMatrixPrinter >\n+ 93 {\n+ 94 static void print(char* name, SuperMatrix* mat)\n+ 95 {\n+ 96 cPrint_CompCol_Matrix(name, mat);\n+ 97 }\n+ 98 };\n+ 99#endif\n+ 100\n+ 101#if __has_include(\"slu_zdefs.h\")\n+ 102 template<>\n+ 103 struct SuperMatrixCreateSparseChooser >\n+ 104 {\n+ 105 static void create(SuperMatrix *mat, int n, int m, int offset,\n+ 106 std::complex *values, int *rowindex, int* colindex,\n+ 107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n+ 108 {\n+ 109 zCreate_CompCol_Matrix(mat, n, m, offset, reinterpret_cast\n+(values),\n+ 110 rowindex, colindex, stype, dtype, mtype);\n+ 111 }\n+ 112 };\n+ 113\n+ 114 template<>\n+ 115 struct SuperMatrixPrinter >\n+ 116 {\n+ 117 static void print(char* name, SuperMatrix* mat)\n+ 118 {\n+ 119 zPrint_CompCol_Matrix(name, mat);\n+ 120 }\n+ 121 };\n+ 122#endif\n+ 123\n+ 124 template\n+125 struct BaseGetSuperLUType\n+ 126 {\n+127 static const Dtype_t type;\n+ 128 };\n+ 129\n+ 130 template\n+131 struct GetSuperLUType\n+ 132 {};\n+ 133\n+ 134 template\n+ 135 const Dtype_t BaseGetSuperLUType::type =\n+ 136 std::is_same::value ? SLU_S :\n+ 137 ( std::is_same >::value ? SLU_Z :\n+ 138 ( std::is_same >::value ? SLU_C : SLU_D ));\n+ 139\n+ 140 template<>\n+141 struct GetSuperLUType\n+ 142 : public BaseGetSuperLUType\n+ 143 {\n+144 typedef double float_type;\n+ 145 };\n+ 146\n+ 147 template<>\n+148 struct GetSuperLUType\n+ 149 : public BaseGetSuperLUType\n+ 150 {\n+151 typedef float float_type;\n+ 152 };\n+ 153\n+ 154 template<>\n+155 struct GetSuperLUType >\n+ 156 : public BaseGetSuperLUType >\n+ 157 {\n+158 typedef double float_type;\n+ 159 };\n+ 160\n+ 161 template<>\n+162 struct GetSuperLUType >\n+ 163 : public BaseGetSuperLUType >\n+ 164 {\n+165 typedef float float_type;\n+ 166\n+ 167 };\n+ 168\n+ 173 template\n+174 struct SuperLUMatrix\n+ 175 {};\n+ 176\n+ 177 template\n+178 struct SuperMatrixInitializer\n+ 179 {};\n+ 180\n+ 181 template\n+ 182 class SuperLU;\n+ 183\n+ 184 template\n+ 185 class SeqOverlappingSchwarz;\n+ 186\n+ 187 template\n+ 188 struct SeqOverlappingSchwarzAssemblerHelper;\n+ 189\n+ 193 template\n+194 class SuperLUMatrix >\n+ 195 : public ISTL::Impl::BCCSMatrix::field_type,\n+int>\n+ 196 {\n+ 197 template\n+198 friend class SeqOverlappingSchwarz;\n+ 199 friend struct SuperMatrixInitializer >;\n+ 200 public:\n+202 typedef BCRSMatrix Matrix;\n+ 203\n+ 204 friend struct SeqOverlappingSchwarzAssemblerHelper, true>;\n+ 205\n+206 typedef typename Matrix::size_type size_type;\n+ 207\n+212 explicit SuperLUMatrix(const Matrix& mat) : ISTL::Impl::\n+BCCSMatrix, int>(mat)\n+ 213 {}\n+ 214\n+215 SuperLUMatrix() : ISTL::Impl::BCCSMatrix::\n+field_type, int>()\n+ 216 {}\n+ 217\n+219 virtual ~SuperLUMatrix()\n+ 220 {\n+ 221 if (this->N_+this->M_*this->Nnz_ != 0)\n+ 222 free();\n+ 223 }\n+ 224\n+226 operator SuperMatrix&()\n+ 227 {\n+ 228 return A;\n+ 229 }\n+ 230\n+232 operator const SuperMatrix&() const\n+ 233 {\n+ 234 return A;\n+ 235 }\n+ 236\n+237 SuperLUMatrix >& operator=(const BCRSMatrix& mat)\n+ 238 {\n+ 239 if (this->N_ + this->M_ + this->Nnz_!=0)\n+ 240 free();\n+ 241\n+ 242 using Matrix = BCRSMatrix;\n+ 243 this->N_ = MatrixDimension::rowdim(mat);\n+ 244 this->M_ = MatrixDimension::coldim(mat);\n+ 245 ISTL::Impl::BCCSMatrixInitializer initializer(*this);\n+ 246\n+ 247 copyToBCCSMatrix(initializer, mat);\n+ 248\n+ 249 SuperMatrixCreateSparseChooser\n+ 250::create(&A, this->N_, this->M_, this->colstart[this->N_],\n+ 251 this->values,this->rowindex, this->colstart, SLU_NC,\n+ 252 static_cast(GetSuperLUType::type),\n+SLU_GE);\n+ 253 return *this;\n+ 254 }\n+ 255\n+256 SuperLUMatrix >& operator=(const SuperLUMatrix\n+ >& mat)\n+ 257 {\n+ 258 if (this->N_ + this->M_ + this->Nnz_!=0)\n+ 259 free();\n+ 260\n+ 261 using Matrix = BCRSMatrix;\n+ 262 this->N_ = MatrixDimension::rowdim(mat);\n+ 263 this->M_ = MatrixDimension::coldim(mat);\n+ 264 ISTL::Impl::BCCSMatrixInitializer initializer(*this);\n+ 265\n+ 266 copyToBCCSMatrix(initializer, mat);\n+ 267\n+ 268 SuperMatrixCreateSparseChooser\n+ 269::create(&A, this->N_, this->M_, this->colstart[this->N_],\n+ 270 this->values,this->rowindex, this->colstart, SLU_NC,\n+ 271 static_cast(GetSuperLUType::type), SLU_GE);\n+ 272 return *this;\n+ 273 }\n+ 274\n+281 virtual void setMatrix(const Matrix& mat, const std::set& mrs)\n+ 282 {\n+ 283 if(this->N_+this->M_+this->Nnz_!=0)\n+ 284 free();\n+ 285 this->N_=mrs.size()*MatrixDimension::rowdim(*\n+(mat[0].begin()));\n+ 286 this->M_=mrs.size()*MatrixDimension::coldim(*\n+(mat[0].begin()));\n+ 287 SuperMatrixInitializer initializer(*this);\n+ 288\n+ 289 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset >(mat,mrs));\n+ 290 }\n+ 291\n+293 virtual void setMatrix(const Matrix& mat)\n+ 294 {\n+ 295 this->N_=MatrixDimension::rowdim(mat);\n+ 296 this->M_=MatrixDimension::coldim(mat);\n+ 297 SuperMatrixInitializer initializer(*this);\n+ 298\n+ 299 copyToBCCSMatrix(initializer, mat);\n+ 300 }\n+ 301\n+303 virtual void free()\n+ 304 {\n+ 305 ISTL::Impl::BCCSMatrix::field_type, int>::free\n+();\n+ 306 SUPERLU_FREE(A.Store);\n+ 307 }\n+ 308 private:\n+ 309 SuperMatrix A;\n+ 310 };\n+ 311\n+ 312 template\n+313 class SuperMatrixInitializer >\n+ 314 : public ISTL::Impl::BCCSMatrixInitializer, int>\n+ 315 {\n+ 316 template\n+317 friend class OverlappingSchwarzInitializer;\n+ 318 public:\n+319 typedef BCRSMatrix Matrix;\n+320 typedef Dune::SuperLUMatrix SuperLUMatrix;\n+ 321\n+322 SuperMatrixInitializer(SuperLUMatrix& lum) : ISTL::Impl::\n+BCCSMatrixInitializer, int>(lum)\n+ 323 ,slumat(&lum)\n+ 324 {}\n+ 325\n+326 SuperMatrixInitializer() : ISTL::Impl::\n+BCCSMatrixInitializer, int>()\n+ 327 {}\n+ 328\n+329 virtual void createMatrix() const\n+ 330 {\n+ 331 ISTL::Impl::BCCSMatrixInitializer, int>::createMatrix();\n+ 332 SuperMatrixCreateSparseChooser\n+ 333::create(&slumat->A, slumat->N_, slumat->M_, slumat->colstart[this->cols],\n+ 334 slumat->values,slumat->rowindex, slumat->colstart, SLU_NC,\n+ 335 static_cast(GetSuperLUType::type),\n+SLU_GE);\n+ 336 }\n+ 337 private:\n+ 338 SuperLUMatrix* slumat;\n+ 339 };\n+ 340}\n+ 341#endif // HAVE_SUPERLU\n+ 342#endif\n+bccsmatrixinitializer.hh\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+superlufunctions.hh\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::Amg::renumberAggregates\n-void renumberAggregates(const G &graph, I index, I endIndex, V &visitedMap,\n-AggregatesMap< typename G::VertexDescriptor > &aggregates)\n-Definition: renumberer.hh:63\n-Dune::Amg::AggregatesMap<_Vertex_>\n-Dune::Amg::AggregateRenumberer\n-Definition: renumberer.hh:16\n-Dune::Amg::AggregateRenumberer::operator++\n-void operator++()\n-Definition: renumberer.hh:57\n-Dune::Amg::AggregateRenumberer::Vertex\n-G::VertexDescriptor Vertex\n-The vertex type.\n-Definition: renumberer.hh:19\n-Dune::Amg::AggregateRenumberer::operator()\n-void operator()(const typename G::ConstEdgeIterator &edge)\n-Definition: renumberer.hh:51\n-Dune::Amg::AggregateRenumberer::aggregates_\n-AggregatesMap< Vertex > & aggregates_\n-Definition: renumberer.hh:36\n-Dune::Amg::AggregateRenumberer::AggregateRenumberer\n-AggregateRenumberer(AggregatesMap< Vertex > &aggregates)\n-Constructor.\n-Definition: renumberer.hh:40\n-Dune::Amg::AggregateRenumberer::number_\n-Vertex number_\n-Definition: renumberer.hh:35\n+Dune::OverlappingSchwarzInitializer\n+Initializer for SuperLU Matrices representing the subdomains.\n+Definition: overlappingschwarz.hh:47\n+Dune::MatrixDimension::coldim\n+static auto coldim(const M &A)\n+Definition: matrixutils.hh:219\n+Dune::MatrixDimension::rowdim\n+static auto rowdim(const M &A)\n+Definition: matrixutils.hh:214\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::SeqOverlappingSchwarz\n+Sequential overlapping Schwarz preconditioner.\n+Definition: overlappingschwarz.hh:755\n+Dune::SeqOverlappingSchwarzAssemblerHelper\n+Definition: overlappingschwarz.hh:694\n+Dune::SuperLU\n+SuperLu Solver.\n+Definition: superlu.hh:271\n+Dune::SuperMatrixCreateSparseChooser\n+Definition: supermatrix.hh:26\n+Dune::SuperMatrixPrinter\n+Definition: supermatrix.hh:30\n+Dune::BaseGetSuperLUType\n+Definition: supermatrix.hh:126\n+Dune::BaseGetSuperLUType::type\n+static const Dtype_t type\n+Definition: supermatrix.hh:127\n+Dune::GetSuperLUType\n+Definition: supermatrix.hh:132\n+Dune::GetSuperLUType<_double_>::float_type\n+double float_type\n+Definition: supermatrix.hh:144\n+Dune::GetSuperLUType<_float_>::float_type\n+float float_type\n+Definition: supermatrix.hh:151\n+Dune::GetSuperLUType<_std::complex<_double_>_>::float_type\n+double float_type\n+Definition: supermatrix.hh:158\n+Dune::GetSuperLUType<_std::complex<_float_>_>::float_type\n+float float_type\n+Definition: supermatrix.hh:165\n+Dune::SuperLUMatrix\n+Utility class for converting an ISTL Matrix into a SuperLU Matrix.\n+Definition: supermatrix.hh:175\n+Dune::SuperMatrixInitializer\n+Definition: supermatrix.hh:179\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::free\n+virtual void free()\n+free allocated space.\n+Definition: supermatrix.hh:303\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::operator=\n+SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const SuperLUMatrix<\n+BCRSMatrix< B, TA > > &mat)\n+Definition: supermatrix.hh:256\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::operator=\n+SuperLUMatrix< BCRSMatrix< B, TA > > & operator=(const BCRSMatrix< B, TA >\n+&mat)\n+Definition: supermatrix.hh:237\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::SuperLUMatrix\n+SuperLUMatrix(const Matrix &mat)\n+Constructor that initializes the data.\n+Definition: supermatrix.hh:212\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::setMatrix\n+virtual void setMatrix(const Matrix &mat)\n+Initialize data from given matrix.\n+Definition: supermatrix.hh:293\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::SuperLUMatrix\n+SuperLUMatrix()\n+Definition: supermatrix.hh:215\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::size_type\n+Matrix::size_type size_type\n+Definition: supermatrix.hh:206\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::Matrix\n+BCRSMatrix< B, TA > Matrix\n+The type of the matrix to convert.\n+Definition: supermatrix.hh:202\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::setMatrix\n+virtual void setMatrix(const Matrix &mat, const std::set< std::size_t > &mrs)\n+Initialize data from a given set of matrix rows and columns.\n+Definition: supermatrix.hh:281\n+Dune::SuperLUMatrix<_BCRSMatrix<_B,_TA_>_>::~SuperLUMatrix\n+virtual ~SuperLUMatrix()\n+Destructor.\n+Definition: supermatrix.hh:219\n+Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperLUMatrix\n+Dune::SuperLUMatrix< Matrix > SuperLUMatrix\n+Definition: supermatrix.hh:320\n+Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::Matrix\n+BCRSMatrix< B, A > Matrix\n+Definition: supermatrix.hh:319\n+Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperMatrixInitializer\n+SuperMatrixInitializer()\n+Definition: supermatrix.hh:326\n+Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::createMatrix\n+virtual void createMatrix() const\n+Definition: supermatrix.hh:329\n+Dune::SuperMatrixInitializer<_BCRSMatrix<_B,_A_>_>::SuperMatrixInitializer\n+SuperMatrixInitializer(SuperLUMatrix &lum)\n+Definition: supermatrix.hh:322\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00122.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00122.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: fastamgsmoother.hh File Reference\n+dune-istl: bvector.hh File Reference\n \n \n \n \n \n \n \n@@ -58,42 +58,71 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n \n-
    fastamgsmoother.hh File Reference
    \n+Namespaces |\n+Functions
    \n+
    bvector.hh File Reference
    \n \n
    \n-
    #include <cstddef>
    \n+\n+

    This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time. \n+More...

    \n+
    #include <algorithm>
    \n+#include <cmath>
    \n+#include <complex>
    \n+#include <initializer_list>
    \n+#include <limits>
    \n+#include <memory>
    \n+#include <utility>
    \n+#include <vector>
    \n+#include <dune/common/dotproduct.hh>
    \n+#include <dune/common/ftraits.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/common/promotiontraits.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n+#include "basearray.hh"
    \n+#include "istlexception.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n \n-\n+\n \n

    \n Classes

    struct  Dune::Amg::GaussSeidelPresmoothDefect< level >
    class  Dune::BlockVector< B, A >
     A vector of blocks with memory management. More...
     
    struct  Dune::Amg::GaussSeidelPostsmoothDefect< level >
    struct  Dune::FieldTraits< BlockVector< B, A > >
     
    \n \n \n \n-\n-\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n+\n

    \n+Functions

    template<class K , class A >
    std::ostream & Dune::operator<< (std::ostream &s, const BlockVector< K, A > &v)
     Send BlockVector to an output stream. More...
     
    \n-
    \n+

    Detailed Description

    \n+

    This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time.

    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,25 +4,51 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces\n-fastamgsmoother.hh File Reference\n-#include \n+Classes | Namespaces | Functions\n+bvector.hh File Reference\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of components can be given at run-time. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"basearray.hh\"\n+#include \"istlexception.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::GaussSeidelPresmoothDefect<_level_>\n+ class \u00a0Dune::BlockVector<_B,_A_>\n+\u00a0 A vector of blocks with memory management. More...\n \u00a0\n-struct \u00a0Dune::Amg::GaussSeidelPostsmoothDefect<_level_>\n+struct \u00a0Dune::FieldTraits<_BlockVector<_B,_A_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n+ Functions\n+template\n+std::ostream &\u00a0Dune::operator<< (std::ostream &s, const BlockVector< K, A >\n+ &v)\n+\u00a0 Send BlockVector to an output stream. More...\n \u00a0\n+***** Detailed Description *****\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of components can be given at run-time.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00122_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00122_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: fastamgsmoother.hh Source File\n+dune-istl: bvector.hh Source File\n \n \n \n \n \n \n \n@@ -58,123 +58,933 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    fastamgsmoother.hh
    \n+
    bvector.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_FASTAMGSMOOTHER_HH
    \n-
    6#define DUNE_ISTL_FASTAMGSMOOTHER_HH
    \n-
    7
    \n-
    8#include <cstddef>
    \n-
    9
    \n-
    10namespace Dune
    \n-
    11{
    \n-
    12 namespace Amg
    \n-
    13 {
    \n-
    14
    \n-
    15 template<std::size_t level>
    \n-\n+
    5
    \n+
    6#ifndef DUNE_ISTL_BVECTOR_HH
    \n+
    7#define DUNE_ISTL_BVECTOR_HH
    \n+
    8
    \n+
    9#include <algorithm>
    \n+
    10#include <cmath>
    \n+
    11#include <complex>
    \n+
    12#include <initializer_list>
    \n+
    13#include <limits>
    \n+
    14#include <memory>
    \n+
    15#include <utility>
    \n+
    16#include <vector>
    \n
    17
    \n-
    18 template<typename M, typename X, typename Y>
    \n-
    19 static void apply(const M& A, X& x, Y& d,
    \n-
    20 const Y& b)
    \n-
    21 {
    \n-
    22 typedef typename M::ConstRowIterator RowIterator;
    \n-
    23 typedef typename M::ConstColIterator ColIterator;
    \n-
    24
    \n-
    25 typename Y::iterator dIter=d.begin();
    \n-
    26 typename Y::const_iterator bIter=b.begin();
    \n-
    27 typename X::iterator xIter=x.begin();
    \n-
    28
    \n-
    29 for(RowIterator row=A.begin(), end=A.end(); row != end;
    \n-
    30 ++row, ++dIter, ++xIter, ++bIter)
    \n-
    31 {
    \n-
    32 ColIterator col=(*row).begin();
    \n-
    33 *dIter = *bIter;
    \n-
    34
    \n-
    35 for (; col.index()<row.index(); ++col)
    \n-
    36 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    37 assert(row.index()==col.index());
    \n-
    38 ColIterator diag=col; // upper diagonal matrix not needed as x was 0 before.
    \n+
    18#include <dune/common/dotproduct.hh>
    \n+
    19#include <dune/common/ftraits.hh>
    \n+
    20#include <dune/common/fmatrix.hh>
    \n+
    21#include <dune/common/fvector.hh>
    \n+
    22#include <dune/common/promotiontraits.hh>
    \n+
    23#include <dune/common/typetraits.hh>
    \n+
    24#include <dune/common/scalarvectorview.hh>
    \n+
    25
    \n+\n+
    27
    \n+
    28#include "basearray.hh"
    \n+
    29#include "istlexception.hh"
    \n+
    30
    \n+
    38namespace Dune {
    \n
    39
    \n-
    40 // Not recursive yet. Just solve with the diagonal
    \n-
    41 diag->solve(*xIter,*dIter);
    \n-
    42 *dIter=0; //as r=v
    \n-
    43
    \n-
    44 // Update residual for the symmetric case
    \n-
    45 for(col=(*row).begin(); col.index()<row.index(); ++col)
    \n-
    46 col->mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i
    \n-
    47 }
    \n-
    48 }
    \n-
    49 };
    \n+
    41namespace Imp {
    \n+
    42
    \n+
    48 template <class B, bool isNumber>
    \n+
    49 class BlockTraitsImp;
    \n
    50
    \n-
    51 template<std::size_t level>
    \n-\n-
    53
    \n-
    54 template<typename M, typename X, typename Y>
    \n-
    55 static void apply(const M& A, X& x, Y& d,
    \n-
    56 const Y& b)
    \n-
    57 {
    \n-
    58 typedef typename M::ConstRowIterator RowIterator;
    \n-
    59 typedef typename M::ConstColIterator ColIterator;
    \n-
    60 typedef typename Y::block_type YBlock;
    \n-
    61
    \n-
    62 typename Y::iterator dIter=d.beforeEnd();
    \n-
    63 typename X::iterator xIter=x.beforeEnd();
    \n-
    64 typename Y::const_iterator bIter=b.beforeEnd();
    \n-
    65
    \n-
    66 for(RowIterator row=A.beforeEnd(), end=A.beforeBegin(); row != end;
    \n-
    67 --row, --dIter, --xIter, --bIter)
    \n-
    68 {
    \n-
    69 ColIterator endCol=(*row).beforeBegin();
    \n-
    70 ColIterator col=(*row).beforeEnd();
    \n-
    71 *dIter = *bIter;
    \n-
    72
    \n-
    73 for (; col.index()>row.index(); --col)
    \n-
    74 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{i>j} a_ij * xnew_j
    \n-
    75 assert(row.index()==col.index());
    \n-
    76 ColIterator diag=col;
    \n-
    77 YBlock v=*dIter;
    \n-
    78 // upper diagonal matrix
    \n-
    79 for (--col; col!=endCol; --col)
    \n-
    80 (*col).mmv(x[col.index()],v); // v -= sum_{j<i} a_ij * xold_j
    \n-
    81
    \n-
    82 // Not recursive yet. Just solve with the diagonal
    \n-
    83 diag->solve(*xIter,v);
    \n-
    84
    \n-
    85 *dIter-=v;
    \n-
    86
    \n-
    87 // Update residual for the symmetric case
    \n-
    88 // Skip residual computation as it is not needed.
    \n-
    89 //for(col=(*row).begin();col.index()<row.index(); ++col)
    \n-
    90 //col.mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i
    \n-
    91 }
    \n-
    92 }
    \n-
    93 };
    \n-
    94 } // end namespace Amg
    \n-
    95} // end namespace Dune
    \n-
    96#endif
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    51 template <class B>
    \n+
    52 class BlockTraitsImp<B,true>
    \n+
    53 {
    \n+
    54 public:
    \n+
    55 using field_type = B;
    \n+
    56 };
    \n+
    57
    \n+
    58 template <class B>
    \n+
    59 class BlockTraitsImp<B,false>
    \n+
    60 {
    \n+
    61 public:
    \n+
    62 using field_type = typename B::field_type;
    \n+
    63 };
    \n+
    64
    \n+
    67 template <class B>
    \n+
    68 using BlockTraits = BlockTraitsImp<B,IsNumber<B>::value>;
    \n+
    69
    \n+
    83 template<class B, class A=std::allocator<B> >
    \n+
    84 class block_vector_unmanaged : public base_array_unmanaged<B,A>
    \n+
    85 {
    \n+
    86 public:
    \n+
    87
    \n+
    88 //===== type definitions and constants
    \n+
    89 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    90
    \n+
    92 typedef B block_type;
    \n+
    93
    \n+
    95 typedef A allocator_type;
    \n+
    96
    \n+
    98 typedef typename A::size_type size_type;
    \n+
    99
    \n+
    101 typedef typename base_array_unmanaged<B,A>::iterator Iterator;
    \n+
    102
    \n+
    104 typedef typename base_array_unmanaged<B,A>::const_iterator ConstIterator;
    \n+
    105
    \n+
    107 typedef B value_type;
    \n+
    108
    \n+
    110 typedef B& reference;
    \n+
    111
    \n+
    113 typedef const B& const_reference;
    \n+
    114
    \n+
    115 //===== assignment from scalar
    \n+
    117
    \n+
    118 block_vector_unmanaged& operator= (const field_type& k)
    \n+
    119 {
    \n+
    120 for (size_type i=0; i<this->n; i++)
    \n+
    121 (*this)[i] = k;
    \n+
    122 return *this;
    \n+
    123 }
    \n+
    124
    \n+
    125 //===== vector space arithmetic
    \n+
    127 block_vector_unmanaged& operator+= (const block_vector_unmanaged& y)
    \n+
    128 {
    \n+
    129#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    130 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    131#endif
    \n+
    132 for (size_type i=0; i<this->n; ++i) (*this)[i] += y[i];
    \n+
    133 return *this;
    \n+
    134 }
    \n+
    135
    \n+
    137 block_vector_unmanaged& operator-= (const block_vector_unmanaged& y)
    \n+
    138 {
    \n+
    139#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    140 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    141#endif
    \n+
    142 for (size_type i=0; i<this->n; ++i) (*this)[i] -= y[i];
    \n+
    143 return *this;
    \n+
    144 }
    \n+
    145
    \n+
    147 block_vector_unmanaged& operator*= (const field_type& k)
    \n+
    148 {
    \n+
    149 for (size_type i=0; i<this->n; ++i) (*this)[i] *= k;
    \n+
    150 return *this;
    \n+
    151 }
    \n+
    152
    \n+
    154 block_vector_unmanaged& operator/= (const field_type& k)
    \n+
    155 {
    \n+
    156 for (size_type i=0; i<this->n; ++i) (*this)[i] /= k;
    \n+
    157 return *this;
    \n+
    158 }
    \n+
    159
    \n+
    161 block_vector_unmanaged& axpy (const field_type& a, const block_vector_unmanaged& y)
    \n+
    162 {
    \n+
    163#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    164 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    165#endif
    \n+
    166 for (size_type i=0; i<this->n; ++i)
    \n+
    167 Impl::asVector((*this)[i]).axpy(a,Impl::asVector(y[i]));
    \n+
    168
    \n+
    169 return *this;
    \n+
    170 }
    \n+
    171
    \n+
    172
    \n+
    180 template<class OtherB, class OtherA>
    \n+
    181 auto operator* (const block_vector_unmanaged<OtherB,OtherA>& y) const
    \n+
    182 {
    \n+
    183 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
    \n+
    184 PromotedType sum(0);
    \n+
    185#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    186 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    187#endif
    \n+
    188 for (size_type i=0; i<this->n; ++i) {
    \n+
    189 sum += PromotedType(((*this)[i])*y[i]);
    \n+
    190 }
    \n+
    191 return sum;
    \n+
    192 }
    \n+
    193
    \n+
    201 template<class OtherB, class OtherA>
    \n+
    202 auto dot(const block_vector_unmanaged<OtherB,OtherA>& y) const
    \n+
    203 {
    \n+
    204 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
    \n+
    205 PromotedType sum(0);
    \n+
    206#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    207 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    208#endif
    \n+
    209
    \n+
    210 for (size_type i=0; i<this->n; ++i)
    \n+
    211 sum += Impl::asVector((*this)[i]).dot(Impl::asVector(y[i]));
    \n+
    212
    \n+
    213 return sum;
    \n+
    214 }
    \n+
    215
    \n+
    216 //===== norms
    \n+
    217
    \n+
    219 typename FieldTraits<field_type>::real_type one_norm () const
    \n+
    220 {
    \n+
    221 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    222 for (size_type i=0; i<this->n; ++i)
    \n+
    223 sum += Impl::asVector((*this)[i]).one_norm();
    \n+
    224 return sum;
    \n+
    225 }
    \n+
    226
    \n+
    228 typename FieldTraits<field_type>::real_type one_norm_real () const
    \n+
    229 {
    \n+
    230 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    231 for (size_type i=0; i<this->n; ++i)
    \n+
    232 sum += Impl::asVector((*this)[i]).one_norm_real();
    \n+
    233 return sum;
    \n+
    234 }
    \n+
    235
    \n+
    237 typename FieldTraits<field_type>::real_type two_norm () const
    \n+
    238 {
    \n+
    239 using std::sqrt;
    \n+
    240 return sqrt(two_norm2());
    \n+
    241 }
    \n+
    242
    \n+
    244 typename FieldTraits<field_type>::real_type two_norm2 () const
    \n+
    245 {
    \n+
    246 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    247 for (size_type i=0; i<this->n; ++i)
    \n+
    248 sum += Impl::asVector((*this)[i]).two_norm2();
    \n+
    249 return sum;
    \n+
    250 }
    \n+
    251
    \n+
    253 template <typename ft = field_type,
    \n+
    254 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    255 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    256 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    257 using std::max;
    \n+
    258
    \n+
    259 real_type norm = 0;
    \n+
    260 for (auto const &xi : *this) {
    \n+
    261 real_type const a = Impl::asVector(xi).infinity_norm();
    \n+
    262 norm = max(a, norm);
    \n+
    263 }
    \n+
    264 return norm;
    \n+
    265 }
    \n+
    266
    \n+
    268 template <typename ft = field_type,
    \n+
    269 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    270 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    271 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    272 using std::max;
    \n+
    273
    \n+
    274 real_type norm = 0;
    \n+
    275 for (auto const &xi : *this) {
    \n+
    276 real_type const a = Impl::asVector(xi).infinity_norm_real();
    \n+
    277 norm = max(a, norm);
    \n+
    278 }
    \n+
    279 return norm;
    \n+
    280 }
    \n+
    281
    \n+
    283 template <typename ft = field_type,
    \n+
    284 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    285 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    286 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    287 using std::max;
    \n+
    288 using std::abs;
    \n+
    289
    \n+
    290 real_type norm = 0;
    \n+
    291 real_type isNaN = 1;
    \n+
    292
    \n+
    293 for (auto const &xi : *this) {
    \n+
    294 real_type const a = Impl::asVector(xi).infinity_norm();
    \n+
    295 norm = max(a, norm);
    \n+
    296 isNaN += a;
    \n+
    297 }
    \n+
    298 return norm * (isNaN / isNaN);
    \n+
    299 }
    \n+
    300
    \n+
    302 template <typename ft = field_type,
    \n+
    303 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    304 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    305 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    306 using std::max;
    \n+
    307
    \n+
    308 real_type norm = 0;
    \n+
    309 real_type isNaN = 1;
    \n+
    310
    \n+
    311 for (auto const &xi : *this) {
    \n+
    312 real_type const a = Impl::asVector(xi).infinity_norm_real();
    \n+
    313 norm = max(a, norm);
    \n+
    314 isNaN += a;
    \n+
    315 }
    \n+
    316
    \n+
    317 return norm * (isNaN / isNaN);
    \n+
    318 }
    \n+
    319
    \n+
    320 //===== sizes
    \n+
    321
    \n+
    323 size_type N () const
    \n+
    324 {
    \n+
    325 return this->n;
    \n+
    326 }
    \n+
    327
    \n+
    329 size_type dim () const
    \n+
    330 {
    \n+
    331 size_type d=0;
    \n+
    332
    \n+
    333 for (size_type i=0; i<this->n; i++)
    \n+
    334 d += Impl::asVector((*this)[i]).dim();
    \n+
    335
    \n+
    336 return d;
    \n+
    337 }
    \n+
    338
    \n+
    339 protected:
    \n+
    341 block_vector_unmanaged () : base_array_unmanaged<B,A>()
    \n+
    342 { }
    \n+
    343 };
    \n+
    344
    \n+
    346
    \n+
    351 template<class F>
    \n+
    352 class ScopeGuard {
    \n+
    353 F cleanupFunc_;
    \n+
    354 public:
    \n+
    355 ScopeGuard(F cleanupFunc) : cleanupFunc_(std::move(cleanupFunc)) {}
    \n+
    356 ScopeGuard(const ScopeGuard &) = delete;
    \n+
    357 ScopeGuard(ScopeGuard &&) = delete;
    \n+
    358 ScopeGuard &operator=(ScopeGuard) = delete;
    \n+
    359 ~ScopeGuard() { cleanupFunc_(); }
    \n+
    360 };
    \n+
    361
    \n+
    363
    \n+
    372 template<class F>
    \n+
    373 ScopeGuard<F> makeScopeGuard(F cleanupFunc)
    \n+
    374 {
    \n+
    375 return { std::move(cleanupFunc) };
    \n+
    376 }
    \n+
    377
    \n+
    378} // end namespace Imp
    \n+
    393 template<class B, class A=std::allocator<B> >
    \n+
    394 class BlockVector : public Imp::block_vector_unmanaged<B,A>
    \n+
    395 {
    \n+
    396 public:
    \n+
    397
    \n+
    398 //===== type definitions and constants
    \n+
    399
    \n+
    401 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    402
    \n+
    404 typedef B block_type;
    \n+
    405
    \n+
    407 typedef A allocator_type;
    \n+
    408
    \n+
    410 typedef typename A::size_type size_type;
    \n+
    411
    \n+
    413 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    414 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n+
    415
    \n+
    417 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator Iterator;
    \n+
    418
    \n+
    420 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n+
    421
    \n+
    422 //===== constructors and such
    \n+
    423
    \n+\n+
    426 {
    \n+
    427 syncBaseArray();
    \n+
    428 }
    \n+
    429
    \n+
    431 explicit BlockVector (size_type _n) : storage_(_n)
    \n+
    432 {
    \n+
    433 syncBaseArray();
    \n+
    434 }
    \n+
    435
    \n+
    437 BlockVector (std::initializer_list<B> const &l) : storage_(l)
    \n+
    438 {
    \n+
    439 syncBaseArray();
    \n+
    440 }
    \n+
    441
    \n+
    442
    \n+
    454 template<typename S>
    \n+
    455 BlockVector (size_type _n, S _capacity)
    \n+
    456 {
    \n+
    457 static_assert(std::numeric_limits<S>::is_integer,
    \n+
    458 "capacity must be an unsigned integral type (be aware, that this constructor does not set the default value!)" );
    \n+
    459 if((size_type)_capacity > _n)
    \n+
    460 storage_.reserve(_capacity);
    \n+
    461 storage_.resize(_n);
    \n+
    462 syncBaseArray();
    \n+
    463 }
    \n+
    464
    \n+
    465
    \n+\n+
    476 {
    \n+
    477 [[maybe_unused]] const auto &guard =
    \n+
    478 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n+
    479 storage_.reserve(capacity);
    \n+
    480 }
    \n+
    481
    \n+\n+
    489 {
    \n+
    490 return storage_.capacity();
    \n+
    491 }
    \n+
    492
    \n+
    503 void resize(size_type size)
    \n+
    504 {
    \n+
    505 [[maybe_unused]] const auto &guard =
    \n+
    506 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n+
    507 storage_.resize(size);
    \n+
    508 }
    \n+
    509
    \n+\n+
    512 noexcept(noexcept(std::declval<BlockVector>().storage_ = a.storage_))
    \n+
    513 {
    \n+
    514 storage_ = a.storage_;
    \n+
    515 syncBaseArray();
    \n+
    516 }
    \n+
    517
    \n+\n+
    520 noexcept(noexcept(std::declval<BlockVector>().swap(a)))
    \n+
    521 {
    \n+
    522 swap(a);
    \n+
    523 }
    \n+
    524
    \n+\n+
    527 noexcept(noexcept(std::declval<BlockVector>().storage_ = a.storage_))
    \n+
    528 {
    \n+
    529 [[maybe_unused]] const auto &guard =
    \n+
    530 Imp::makeScopeGuard([this]{ syncBaseArray(); });
    \n+
    531 storage_ = a.storage_;
    \n+
    532 return *this;
    \n+
    533 }
    \n+
    534
    \n+\n+
    537 noexcept(noexcept(std::declval<BlockVector>().swap(a)))
    \n+
    538 {
    \n+
    539 swap(a);
    \n+
    540 return *this;
    \n+
    541 }
    \n+
    542
    \n+
    544 void swap(BlockVector &other)
    \n+
    545 noexcept(noexcept(
    \n+
    546 std::declval<BlockVector&>().storage_.swap(other.storage_)))
    \n+
    547 {
    \n+
    548 [[maybe_unused]] const auto &guard = Imp::makeScopeGuard([&]{
    \n+
    549 syncBaseArray();
    \n+
    550 other.syncBaseArray();
    \n+
    551 });
    \n+
    552 storage_.swap(other.storage_);
    \n+
    553 }
    \n+
    554
    \n+\n+
    557 {
    \n+
    558 // forward to operator= in base class
    \n+
    559 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n+
    560 return *this;
    \n+
    561 }
    \n+
    562
    \n+
    563 private:
    \n+
    564 void syncBaseArray() noexcept
    \n+
    565 {
    \n+
    566 this->p = storage_.data();
    \n+
    567 this->n = storage_.size();
    \n+
    568 }
    \n+
    569
    \n+
    570 std::vector<B, A> storage_;
    \n+
    571 };
    \n+
    572
    \n+
    578 template<class B, class A>
    \n+
    579 struct FieldTraits< BlockVector<B, A> >
    \n+
    580 {
    \n+
    581 typedef typename FieldTraits<B>::field_type field_type;
    \n+
    582 typedef typename FieldTraits<B>::real_type real_type;
    \n+
    583 };
    \n+
    589 template<class K, class A>
    \n+
    590 std::ostream& operator<< (std::ostream& s, const BlockVector<K, A>& v)
    \n+
    591 {
    \n+
    592 typedef typename BlockVector<K, A>::size_type size_type;
    \n+
    593
    \n+
    594 for (size_type i=0; i<v.size(); i++)
    \n+
    595 s << v[i] << std::endl;
    \n+
    596
    \n+
    597 return s;
    \n+
    598 }
    \n+
    599
    \n+
    601namespace Imp {
    \n+
    602
    \n+
    621#ifndef DOXYGEN
    \n+
    622 template<class B, class A>
    \n+
    623#else
    \n+
    624 template<class B, class A=std::allocator<B> >
    \n+
    625#endif
    \n+
    626 class BlockVectorWindow : public Imp::block_vector_unmanaged<B,A>
    \n+
    627 {
    \n+
    628 public:
    \n+
    629
    \n+
    630 //===== type definitions and constants
    \n+
    631
    \n+
    633 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    634
    \n+
    636 typedef B block_type;
    \n+
    637
    \n+
    639 typedef A allocator_type;
    \n+
    640
    \n+
    642 typedef typename A::size_type size_type;
    \n+
    643
    \n+
    645 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    646 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n+
    647
    \n+
    649 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator Iterator;
    \n+
    650
    \n+
    652 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n+
    653
    \n+
    654
    \n+
    655 //===== constructors and such
    \n+
    657 BlockVectorWindow () : Imp::block_vector_unmanaged<B,A>()
    \n+
    658 { }
    \n+
    659
    \n+
    661 BlockVectorWindow (B* _p, size_type _n)
    \n+
    662 {
    \n+
    663 this->n = _n;
    \n+
    664 this->p = _p;
    \n+
    665 }
    \n+
    666
    \n+
    668 BlockVectorWindow (const BlockVectorWindow& a)
    \n+
    669 {
    \n+
    670 this->n = a.n;
    \n+
    671 this->p = a.p;
    \n+
    672 }
    \n+
    673
    \n+
    675 BlockVectorWindow& operator= (const BlockVectorWindow& a)
    \n+
    676 {
    \n+
    677 // check correct size
    \n+
    678#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    679 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    680#endif
    \n+
    681
    \n+
    682 if (&a!=this) // check if this and a are different objects
    \n+
    683 {
    \n+
    684 // copy data
    \n+
    685 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n+
    686 }
    \n+
    687 return *this;
    \n+
    688 }
    \n+
    689
    \n+
    691 BlockVectorWindow& operator= (const field_type& k)
    \n+
    692 {
    \n+
    693 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n+
    694 return *this;
    \n+
    695 }
    \n+
    696
    \n+
    698 operator BlockVector<B, A>() const {
    \n+
    699 auto bv = BlockVector<B, A>(this->n);
    \n+
    700
    \n+
    701 std::copy(this->begin(), this->end(), bv.begin());
    \n+
    702
    \n+
    703 return bv;
    \n+
    704 }
    \n+
    705
    \n+
    706 //===== window manipulation methods
    \n+
    707
    \n+
    709 void set (size_type _n, B* _p)
    \n+
    710 {
    \n+
    711 this->n = _n;
    \n+
    712 this->p = _p;
    \n+
    713 }
    \n+
    714
    \n+
    716 void setsize (size_type _n)
    \n+
    717 {
    \n+
    718 this->n = _n;
    \n+
    719 }
    \n+
    720
    \n+
    722 void setptr (B* _p)
    \n+
    723 {
    \n+
    724 this->p = _p;
    \n+
    725 }
    \n+
    726
    \n+
    728 B* getptr ()
    \n+
    729 {
    \n+
    730 return this->p;
    \n+
    731 }
    \n+
    732
    \n+
    734 size_type getsize () const
    \n+
    735 {
    \n+
    736 return this->n;
    \n+
    737 }
    \n+
    738 };
    \n+
    739
    \n+
    740
    \n+
    741
    \n+
    752 template<class B, class A=std::allocator<B> >
    \n+
    753 class compressed_block_vector_unmanaged : public compressed_base_array_unmanaged<B,A>
    \n+
    754 {
    \n+
    755 public:
    \n+
    756
    \n+
    757 //===== type definitions and constants
    \n+
    758
    \n+
    760 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    761
    \n+
    763 typedef B block_type;
    \n+
    764
    \n+
    766 typedef A allocator_type;
    \n+
    767
    \n+
    769 typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator;
    \n+
    770
    \n+
    772 typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator;
    \n+
    773
    \n+
    775 typedef typename A::size_type size_type;
    \n+
    776
    \n+
    777 //===== assignment from scalar
    \n+
    778
    \n+
    779 compressed_block_vector_unmanaged& operator= (const field_type& k)
    \n+
    780 {
    \n+
    781 for (size_type i=0; i<this->n; i++)
    \n+
    782 (this->p)[i] = k;
    \n+
    783 return *this;
    \n+
    784 }
    \n+
    785
    \n+
    786
    \n+
    787 //===== vector space arithmetic
    \n+
    788
    \n+
    790 template<class V>
    \n+
    791 compressed_block_vector_unmanaged& operator+= (const V& y)
    \n+
    792 {
    \n+
    793#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    794 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n+
    795#endif
    \n+
    796 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) += y.p[i];
    \n+
    797 return *this;
    \n+
    798 }
    \n+
    799
    \n+
    801 template<class V>
    \n+
    802 compressed_block_vector_unmanaged& operator-= (const V& y)
    \n+
    803 {
    \n+
    804#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    805 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n+
    806#endif
    \n+
    807 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) -= y.p[i];
    \n+
    808 return *this;
    \n+
    809 }
    \n+
    810
    \n+
    812 template<class V>
    \n+
    813 compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)
    \n+
    814 {
    \n+
    815#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    816 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
    \n+
    817#endif
    \n+
    818 for (size_type i=0; i<y.n; ++i)
    \n+
    819 Impl::asVector((*this)[y.j[i]]).axpy(a,Impl::asVector(y.p[i]));
    \n+
    820 return *this;
    \n+
    821 }
    \n+
    822
    \n+
    824 compressed_block_vector_unmanaged& operator*= (const field_type& k)
    \n+
    825 {
    \n+
    826 for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k;
    \n+
    827 return *this;
    \n+
    828 }
    \n+
    829
    \n+
    831 compressed_block_vector_unmanaged& operator/= (const field_type& k)
    \n+
    832 {
    \n+
    833 for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k;
    \n+
    834 return *this;
    \n+
    835 }
    \n+
    836
    \n+
    837
    \n+
    838 //===== Euclidean scalar product
    \n+
    839
    \n+
    841 field_type operator* (const compressed_block_vector_unmanaged& y) const
    \n+
    842 {
    \n+
    843#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    844 if (!includesindexset(y) || !y.includesindexset(*this) )
    \n+
    845 DUNE_THROW(ISTLError,"index set mismatch");
    \n+
    846#endif
    \n+
    847 field_type sum=0;
    \n+
    848 for (size_type i=0; i<this->n; ++i)
    \n+
    849 sum += (this->p)[i] * y[(this->j)[i]];
    \n+
    850 return sum;
    \n+
    851 }
    \n+
    852
    \n+
    853
    \n+
    854 //===== norms
    \n+
    855
    \n+
    857 typename FieldTraits<field_type>::real_type one_norm () const
    \n+
    858 {
    \n+
    859 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    860 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm();
    \n+
    861 return sum;
    \n+
    862 }
    \n+
    863
    \n+
    865 typename FieldTraits<field_type>::real_type one_norm_real () const
    \n+
    866 {
    \n+
    867 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    868 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real();
    \n+
    869 return sum;
    \n+
    870 }
    \n+
    871
    \n+
    873 typename FieldTraits<field_type>::real_type two_norm () const
    \n+
    874 {
    \n+
    875 using std::sqrt;
    \n+
    876 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    877 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
    \n+
    878 return sqrt(sum);
    \n+
    879 }
    \n+
    880
    \n+
    882 typename FieldTraits<field_type>::real_type two_norm2 () const
    \n+
    883 {
    \n+
    884 typename FieldTraits<field_type>::real_type sum=0;
    \n+
    885 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
    \n+
    886 return sum;
    \n+
    887 }
    \n+
    888
    \n+
    890 template <typename ft = field_type,
    \n+
    891 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    892 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    893 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    894 using std::max;
    \n+
    895
    \n+
    896 real_type norm = 0;
    \n+
    897 for (auto const &x : *this) {
    \n+
    898 real_type const a = x.infinity_norm();
    \n+
    899 norm = max(a, norm);
    \n+
    900 }
    \n+
    901 return norm;
    \n+
    902 }
    \n+
    903
    \n+
    905 template <typename ft = field_type,
    \n+
    906 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n+
    907 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    908 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    909 using std::max;
    \n+
    910
    \n+
    911 real_type norm = 0;
    \n+
    912 for (auto const &x : *this) {
    \n+
    913 real_type const a = x.infinity_norm_real();
    \n+
    914 norm = max(a, norm);
    \n+
    915 }
    \n+
    916 return norm;
    \n+
    917 }
    \n+
    918
    \n+
    920 template <typename ft = field_type,
    \n+
    921 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    922 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n+
    923 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    924 using std::max;
    \n+
    925
    \n+
    926 real_type norm = 0;
    \n+
    927 real_type isNaN = 1;
    \n+
    928 for (auto const &x : *this) {
    \n+
    929 real_type const a = x.infinity_norm();
    \n+
    930 norm = max(a, norm);
    \n+
    931 isNaN += a;
    \n+
    932 }
    \n+
    933 return norm * (isNaN / isNaN);
    \n+
    934 }
    \n+
    935
    \n+
    937 template <typename ft = field_type,
    \n+
    938 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n+
    939 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n+
    940 using real_type = typename FieldTraits<ft>::real_type;
    \n+
    941 using std::max;
    \n+
    942
    \n+
    943 real_type norm = 0;
    \n+
    944 real_type isNaN = 1;
    \n+
    945 for (auto const &x : *this) {
    \n+
    946 real_type const a = x.infinity_norm_real();
    \n+
    947 norm = max(a, norm);
    \n+
    948 isNaN += a;
    \n+
    949 }
    \n+
    950 return norm * (isNaN / isNaN);
    \n+
    951 }
    \n+
    952
    \n+
    953 //===== sizes
    \n+
    954
    \n+
    956 size_type N () const
    \n+
    957 {
    \n+
    958 return this->n;
    \n+
    959 }
    \n+
    960
    \n+
    962 size_type dim () const
    \n+
    963 {
    \n+
    964 size_type d=0;
    \n+
    965 for (size_type i=0; i<this->n; i++)
    \n+
    966 d += (this->p)[i].dim();
    \n+
    967 return d;
    \n+
    968 }
    \n+
    969
    \n+
    970 protected:
    \n+
    972 compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>()
    \n+
    973 { }
    \n+
    974
    \n+
    976 template<class V>
    \n+
    977 bool includesindexset (const V& y)
    \n+
    978 {
    \n+
    979 typename V::ConstIterator e=this->end();
    \n+
    980 for (size_type i=0; i<y.n; i++)
    \n+
    981 if (this->find(y.j[i])==e)
    \n+
    982 return false;
    \n+
    983 return true;
    \n+
    984 }
    \n+
    985 };
    \n+
    986
    \n+
    987
    \n+
    1006 template<class B, class A=std::allocator<B> >
    \n+
    1007 class CompressedBlockVectorWindow : public compressed_block_vector_unmanaged<B,A>
    \n+
    1008 {
    \n+
    1009 public:
    \n+
    1010
    \n+
    1011 //===== type definitions and constants
    \n+
    1012
    \n+
    1014 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    1015
    \n+
    1017 typedef B block_type;
    \n+
    1018
    \n+
    1020 typedef A allocator_type;
    \n+
    1021
    \n+
    1023 typedef typename A::size_type size_type;
    \n+
    1024
    \n+
    1026 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n+
    1027 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n+
    1028
    \n+
    1030 typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator;
    \n+
    1031
    \n+
    1033 typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
    \n+
    1034
    \n+
    1035
    \n+
    1036 //===== constructors and such
    \n+
    1038 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>()
    \n+
    1039 { }
    \n+
    1040
    \n+
    1042 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)
    \n+
    1043 {
    \n+
    1044 this->n = _n;
    \n+
    1045 this->p = _p;
    \n+
    1046 this->j = _j;
    \n+
    1047 }
    \n+
    1048
    \n+
    1050 CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)
    \n+
    1051 {
    \n+
    1052 this->n = a.n;
    \n+
    1053 this->p = a.p;
    \n+
    1054 this->j = a.j;
    \n+
    1055 }
    \n+
    1056
    \n+
    1058 CompressedBlockVectorWindow& operator= (const CompressedBlockVectorWindow& a)
    \n+
    1059 {
    \n+
    1060 // check correct size
    \n+
    1061#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    1062 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
    \n+
    1063#endif
    \n+
    1064
    \n+
    1065 if (&a!=this) // check if this and a are different objects
    \n+
    1066 {
    \n+
    1067 // copy data
    \n+
    1068 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n+
    1069 for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i];
    \n+
    1070 }
    \n+
    1071 return *this;
    \n+
    1072 }
    \n+
    1073
    \n+
    1075 CompressedBlockVectorWindow& operator= (const field_type& k)
    \n+
    1076 {
    \n+
    1077 (static_cast<compressed_block_vector_unmanaged<B,A>&>(*this)) = k;
    \n+
    1078 return *this;
    \n+
    1079 }
    \n+
    1080
    \n+
    1081
    \n+
    1082 //===== window manipulation methods
    \n+
    1083
    \n+
    1085 void set (size_type _n, B* _p, size_type* _j)
    \n+
    1086 {
    \n+
    1087 this->n = _n;
    \n+
    1088 this->p = _p;
    \n+
    1089 this->j = _j;
    \n+
    1090 }
    \n+
    1091
    \n+
    1093 void setsize (size_type _n)
    \n+
    1094 {
    \n+
    1095 this->n = _n;
    \n+
    1096 }
    \n+
    1097
    \n+
    1099 void setptr (B* _p)
    \n+
    1100 {
    \n+
    1101 this->p = _p;
    \n+
    1102 }
    \n+
    1103
    \n+
    1105 void setindexptr (size_type* _j)
    \n+
    1106 {
    \n+
    1107 this->j = _j;
    \n+
    1108 }
    \n+
    1109
    \n+
    1111 B* getptr ()
    \n+
    1112 {
    \n+
    1113 return this->p;
    \n+
    1114 }
    \n+
    1115
    \n+
    1117 size_type* getindexptr ()
    \n+
    1118 {
    \n+
    1119 return this->j;
    \n+
    1120 }
    \n+
    1121
    \n+
    1123 const B* getptr () const
    \n+
    1124 {
    \n+
    1125 return this->p;
    \n+
    1126 }
    \n+
    1127
    \n+
    1129 const size_type* getindexptr () const
    \n+
    1130 {
    \n+
    1131 return this->j;
    \n+
    1132 }
    \n+
    1134 size_type getsize () const
    \n+
    1135 {
    \n+
    1136 return this->n;
    \n+
    1137 }
    \n+
    1138 };
    \n+
    1139
    \n+
    1140} // end namespace 'Imp'
    \n+
    1141
    \n+
    1142
    \n+
    1144 template<typename B, typename A>
    \n+
    1145 struct AutonomousValueType<Imp::BlockVectorWindow<B,A>>
    \n+
    1146 {
    \n+
    1147 using type = BlockVector<B, A>;
    \n+
    1148 };
    \n+
    1149
    \n+
    1150
    \n+
    1151} // end namespace 'Dune'
    \n+
    1152
    \n+
    1153#endif
    \n+
    Implements several basic array containers.
    \n+\n+
    Helper functions for determining the vector/matrix block level.
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    Definition: fastamgsmoother.hh:16
    \n-
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:19
    \n-
    Definition: fastamgsmoother.hh:52
    \n-
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:55
    \n+
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    BlockVector()
    makes empty vector
    Definition: bvector.hh:425
    \n+
    void reserve(size_type capacity)
    Reserve space.
    Definition: bvector.hh:475
    \n+
    BlockVector(BlockVector &&a) noexcept(noexcept(std::declval< BlockVector >().swap(a)))
    move constructor
    Definition: bvector.hh:519
    \n+
    BlockVector(size_type _n)
    make vector with _n components
    Definition: bvector.hh:431
    \n+
    void resize(size_type size)
    Resize the vector.
    Definition: bvector.hh:503
    \n+
    Imp::block_vector_unmanaged< B, A >::Iterator Iterator
    make iterators available as types
    Definition: bvector.hh:417
    \n+
    static constexpr unsigned int blocklevel
    increment block level counter
    Definition: bvector.hh:414
    \n+
    BlockVector(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
    copy constructor
    Definition: bvector.hh:511
    \n+
    A allocator_type
    export the allocator type
    Definition: bvector.hh:407
    \n+
    BlockVector & operator=(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
    assignment
    Definition: bvector.hh:526
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n+
    A::size_type size_type
    The type for the index access.
    Definition: bvector.hh:410
    \n+
    BlockVector(std::initializer_list< B > const &l)
    Construct from a std::initializer_list.
    Definition: bvector.hh:437
    \n+
    size_type capacity() const
    Get the capacity of the vector.
    Definition: bvector.hh:488
    \n+
    BlockVector(size_type _n, S _capacity)
    Make vector with _n components but preallocating capacity components.
    Definition: bvector.hh:455
    \n+
    B block_type
    export the type representing the components
    Definition: bvector.hh:404
    \n+
    void swap(BlockVector &other) noexcept(noexcept(std::declval< BlockVector & >().storage_.swap(other.storage_)))
    swap operation
    Definition: bvector.hh:544
    \n+
    Imp::block_vector_unmanaged< B, A >::ConstIterator ConstIterator
    make iterators available as types
    Definition: bvector.hh:420
    \n+
    FieldTraits< B >::real_type real_type
    Definition: bvector.hh:582
    \n+
    FieldTraits< B >::field_type field_type
    Definition: bvector.hh:581
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,126 +4,1012 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-fastamgsmoother.hh\n+bvector.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_FASTAMGSMOOTHER_HH\n- 6#define DUNE_ISTL_FASTAMGSMOOTHER_HH\n- 7\n- 8#include \n- 9\n- 10namespace Dune\n- 11{\n- 12 namespace Amg\n- 13 {\n- 14\n- 15 template\n-16 struct GaussSeidelPresmoothDefect {\n+ 5\n+ 6#ifndef DUNE_ISTL_BVECTOR_HH\n+ 7#define DUNE_ISTL_BVECTOR_HH\n+ 8\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n 17\n- 18 template\n-19 static void apply(const M& A, X& x, Y& d,\n- 20 const Y& b)\n- 21 {\n- 22 typedef typename M::ConstRowIterator RowIterator;\n- 23 typedef typename M::ConstColIterator ColIterator;\n- 24\n- 25 typename Y::iterator dIter=d.begin();\n- 26 typename Y::const_iterator bIter=b.begin();\n- 27 typename X::iterator xIter=x.begin();\n- 28\n- 29 for(RowIterator row=A.begin(), end=A.end(); row != end;\n- 30 ++row, ++dIter, ++xIter, ++bIter)\n- 31 {\n- 32 ColIterator col=(*row).begin();\n- 33 *dIter = *bIter;\n- 34\n- 35 for (; col.index()\n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23#include \n+ 24#include \n+ 25\n+ 26#include \n+ 27\n+ 28#include \"basearray.hh\"\n+ 29#include \"istlexception.hh\"\n+ 30\n+ 38namespace Dune {\n 39\n- 40 // Not recursive yet. Just solve with the diagonal\n- 41 diag->solve(*xIter,*dIter);\n- 42 *dIter=0; //as r=v\n- 43\n- 44 // Update residual for the symmetric case\n- 45 for(col=(*row).begin(); col.index()mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i\n- 47 }\n- 48 }\n- 49 };\n+ 41namespace Imp {\n+ 42\n+ 48 template \n+ 49 class BlockTraitsImp;\n 50\n- 51 template\n-52 struct GaussSeidelPostsmoothDefect {\n- 53\n- 54 template\n-55 static void apply(const M& A, X& x, Y& d,\n- 56 const Y& b)\n- 57 {\n- 58 typedef typename M::ConstRowIterator RowIterator;\n- 59 typedef typename M::ConstColIterator ColIterator;\n- 60 typedef typename Y::block_type YBlock;\n- 61\n- 62 typename Y::iterator dIter=d.beforeEnd();\n- 63 typename X::iterator xIter=x.beforeEnd();\n- 64 typename Y::const_iterator bIter=b.beforeEnd();\n- 65\n- 66 for(RowIterator row=A.beforeEnd(), end=A.beforeBegin(); row != end;\n- 67 --row, --dIter, --xIter, --bIter)\n- 68 {\n- 69 ColIterator endCol=(*row).beforeBegin();\n- 70 ColIterator col=(*row).beforeEnd();\n- 71 *dIter = *bIter;\n- 72\n- 73 for (; col.index()>row.index(); --col)\n- 74 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{i>j} a_ij * xnew_j\n- 75 assert(row.index()==col.index());\n- 76 ColIterator diag=col;\n- 77 YBlock v=*dIter;\n- 78 // upper diagonal matrix\n- 79 for (--col; col!=endCol; --col)\n- 80 (*col).mmv(x[col.index()],v); // v -= sum_{jsolve(*xIter,v);\n- 84\n- 85 *dIter-=v;\n- 86\n- 87 // Update residual for the symmetric case\n- 88 // Skip residual computation as it is not needed.\n- 89 //for(col=(*row).begin();col.index()\n+ 52 class BlockTraitsImp\n+ 53 {\n+ 54 public:\n+ 55 using field_type = B;\n+ 56 };\n+ 57\n+ 58 template \n+ 59 class BlockTraitsImp\n+ 60 {\n+ 61 public:\n+ 62 using field_type = typename B::field_type;\n+ 63 };\n+ 64\n+ 67 template \n+ 68 using BlockTraits = BlockTraitsImp::value>;\n+ 69\n+ 83 template >\n+ 84 class block_vector_unmanaged : public base_array_unmanaged\n+ 85 {\n+ 86 public:\n+ 87\n+ 88 //===== type definitions and constants\n+ 89 using field_type = typename Imp::BlockTraits::field_type;\n+ 90\n+ 92 typedef B block_type;\n+ 93\n+ 95 typedef A allocator_type;\n+ 96\n+ 98 typedef typename A::size_type size_type;\n+ 99\n+ 101 typedef typename base_array_unmanaged::iterator Iterator;\n+ 102\n+ 104 typedef typename base_array_unmanaged::const_iterator ConstIterator;\n+ 105\n+ 107 typedef B value_type;\n+ 108\n+ 110 typedef B& reference;\n+ 111\n+ 113 typedef const B& const_reference;\n+ 114\n+ 115 //===== assignment from scalar\n+ 117\n+ 118 block_vector_unmanaged& operator= (const field_type& k)\n+ 119 {\n+ 120 for (size_type i=0; in; i++)\n+ 121 (*this)[i] = k;\n+ 122 return *this;\n+ 123 }\n+ 124\n+ 125 //===== vector space arithmetic\n+ 127 block_vector_unmanaged& operator+= (const block_vector_unmanaged& y)\n+ 128 {\n+ 129#ifdef DUNE_ISTL_WITH_CHECKING\n+ 130 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 131#endif\n+ 132 for (size_type i=0; in; ++i) (*this)[i] += y[i];\n+ 133 return *this;\n+ 134 }\n+ 135\n+ 137 block_vector_unmanaged& operator-= (const block_vector_unmanaged& y)\n+ 138 {\n+ 139#ifdef DUNE_ISTL_WITH_CHECKING\n+ 140 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 141#endif\n+ 142 for (size_type i=0; in; ++i) (*this)[i] -= y[i];\n+ 143 return *this;\n+ 144 }\n+ 145\n+ 147 block_vector_unmanaged& operator*= (const field_type& k)\n+ 148 {\n+ 149 for (size_type i=0; in; ++i) (*this)[i] *= k;\n+ 150 return *this;\n+ 151 }\n+ 152\n+ 154 block_vector_unmanaged& operator/= (const field_type& k)\n+ 155 {\n+ 156 for (size_type i=0; in; ++i) (*this)[i] /= k;\n+ 157 return *this;\n+ 158 }\n+ 159\n+ 161 block_vector_unmanaged& axpy (const field_type& a, const\n+block_vector_unmanaged& y)\n+ 162 {\n+ 163#ifdef DUNE_ISTL_WITH_CHECKING\n+ 164 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 165#endif\n+ 166 for (size_type i=0; in; ++i)\n+ 167 Impl::asVector((*this)[i]).axpy(a,Impl::asVector(y[i]));\n+ 168\n+ 169 return *this;\n+ 170 }\n+ 171\n+ 172\n+ 180 template\n+ 181 auto operator* (const block_vector_unmanaged& y) const\n+ 182 {\n+ 183 typedef typename PromotionTraits::\n+field_type>::PromotedType PromotedType;\n+ 184 PromotedType sum(0);\n+ 185#ifdef DUNE_ISTL_WITH_CHECKING\n+ 186 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 187#endif\n+ 188 for (size_type i=0; in; ++i) {\n+ 189 sum += PromotedType(((*this)[i])*y[i]);\n+ 190 }\n+ 191 return sum;\n+ 192 }\n+ 193\n+ 201 template\n+ 202 auto dot(const block_vector_unmanaged& y) const\n+ 203 {\n+ 204 typedef typename PromotionTraits::\n+field_type>::PromotedType PromotedType;\n+ 205 PromotedType sum(0);\n+ 206#ifdef DUNE_ISTL_WITH_CHECKING\n+ 207 if (this->n!=y.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 208#endif\n+ 209\n+ 210 for (size_type i=0; in; ++i)\n+ 211 sum += Impl::asVector((*this)[i]).dot(Impl::asVector(y[i]));\n+ 212\n+ 213 return sum;\n+ 214 }\n+ 215\n+ 216 //===== norms\n+ 217\n+ 219 typename FieldTraits::real_type one_norm () const\n+ 220 {\n+ 221 typename FieldTraits::real_type sum=0;\n+ 222 for (size_type i=0; in; ++i)\n+ 223 sum += Impl::asVector((*this)[i]).one_norm();\n+ 224 return sum;\n+ 225 }\n+ 226\n+ 228 typename FieldTraits::real_type one_norm_real () const\n+ 229 {\n+ 230 typename FieldTraits::real_type sum=0;\n+ 231 for (size_type i=0; in; ++i)\n+ 232 sum += Impl::asVector((*this)[i]).one_norm_real();\n+ 233 return sum;\n+ 234 }\n+ 235\n+ 237 typename FieldTraits::real_type two_norm () const\n+ 238 {\n+ 239 using std::sqrt;\n+ 240 return sqrt(two_norm2());\n+ 241 }\n+ 242\n+ 244 typename FieldTraits::real_type two_norm2 () const\n+ 245 {\n+ 246 typename FieldTraits::real_type sum=0;\n+ 247 for (size_type i=0; in; ++i)\n+ 248 sum += Impl::asVector((*this)[i]).two_norm2();\n+ 249 return sum;\n+ 250 }\n+ 251\n+ 253 template ::value, int>::type = 0>\n+ 255 typename FieldTraits::real_type infinity_norm() const {\n+ 256 using real_type = typename FieldTraits::real_type;\n+ 257 using std::max;\n+ 258\n+ 259 real_type norm = 0;\n+ 260 for (auto const &xi : *this) {\n+ 261 real_type const a = Impl::asVector(xi).infinity_norm();\n+ 262 norm = max(a, norm);\n+ 263 }\n+ 264 return norm;\n+ 265 }\n+ 266\n+ 268 template ::value, int>::type = 0>\n+ 270 typename FieldTraits::real_type infinity_norm_real() const {\n+ 271 using real_type = typename FieldTraits::real_type;\n+ 272 using std::max;\n+ 273\n+ 274 real_type norm = 0;\n+ 275 for (auto const &xi : *this) {\n+ 276 real_type const a = Impl::asVector(xi).infinity_norm_real();\n+ 277 norm = max(a, norm);\n+ 278 }\n+ 279 return norm;\n+ 280 }\n+ 281\n+ 283 template ::value, int>::type = 0>\n+ 285 typename FieldTraits::real_type infinity_norm() const {\n+ 286 using real_type = typename FieldTraits::real_type;\n+ 287 using std::max;\n+ 288 using std::abs;\n+ 289\n+ 290 real_type norm = 0;\n+ 291 real_type isNaN = 1;\n+ 292\n+ 293 for (auto const &xi : *this) {\n+ 294 real_type const a = Impl::asVector(xi).infinity_norm();\n+ 295 norm = max(a, norm);\n+ 296 isNaN += a;\n+ 297 }\n+ 298 return norm * (isNaN / isNaN);\n+ 299 }\n+ 300\n+ 302 template ::value, int>::type = 0>\n+ 304 typename FieldTraits::real_type infinity_norm_real() const {\n+ 305 using real_type = typename FieldTraits::real_type;\n+ 306 using std::max;\n+ 307\n+ 308 real_type norm = 0;\n+ 309 real_type isNaN = 1;\n+ 310\n+ 311 for (auto const &xi : *this) {\n+ 312 real_type const a = Impl::asVector(xi).infinity_norm_real();\n+ 313 norm = max(a, norm);\n+ 314 isNaN += a;\n+ 315 }\n+ 316\n+ 317 return norm * (isNaN / isNaN);\n+ 318 }\n+ 319\n+ 320 //===== sizes\n+ 321\n+ 323 size_type N () const\n+ 324 {\n+ 325 return this->n;\n+ 326 }\n+ 327\n+ 329 size_type dim () const\n+ 330 {\n+ 331 size_type d=0;\n+ 332\n+ 333 for (size_type i=0; in; i++)\n+ 334 d += Impl::asVector((*this)[i]).dim();\n+ 335\n+ 336 return d;\n+ 337 }\n+ 338\n+ 339 protected:\n+ 341 block_vector_unmanaged () : base_array_unmanaged()\n+ 342 { }\n+ 343 };\n+ 344\n+ 346\n+ 351 template\n+ 352 class ScopeGuard {\n+ 353 F cleanupFunc_;\n+ 354 public:\n+ 355 ScopeGuard(F cleanupFunc) : cleanupFunc_(std::move(cleanupFunc)) {}\n+ 356 ScopeGuard(const ScopeGuard &) = delete;\n+ 357 ScopeGuard(ScopeGuard &&) = delete;\n+ 358 ScopeGuard &operator=(ScopeGuard) = delete;\n+ 359 ~ScopeGuard() { cleanupFunc_(); }\n+ 360 };\n+ 361\n+ 363\n+ 372 template\n+ 373 ScopeGuard makeScopeGuard(F cleanupFunc)\n+ 374 {\n+ 375 return { std::move(cleanupFunc) };\n+ 376 }\n+ 377\n+ 378} // end namespace Imp\n+ 393 template >\n+394 class BlockVector : public Imp::block_vector_unmanaged\n+ 395 {\n+ 396 public:\n+ 397\n+ 398 //===== type definitions and constants\n+ 399\n+401 using field_type = typename Imp::BlockTraits::field_type;\n+ 402\n+404 typedef B block_type;\n+ 405\n+407 typedef A allocator_type;\n+ 408\n+410 typedef typename A::size_type size_type;\n+ 411\n+ 413 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+414 static constexpr unsigned int blocklevel = blockLevel()+1;\n+ 415\n+417 typedef typename Imp::block_vector_unmanaged::Iterator Iterator;\n+ 418\n+420 typedef typename Imp::block_vector_unmanaged::ConstIterator\n+ConstIterator;\n+ 421\n+ 422 //===== constructors and such\n+ 423\n+425 BlockVector ()\n+ 426 {\n+ 427 syncBaseArray();\n+ 428 }\n+ 429\n+431 explicit BlockVector (size_type _n) : storage_(_n)\n+ 432 {\n+ 433 syncBaseArray();\n+ 434 }\n+ 435\n+437 BlockVector (std::initializer_list const &l) : storage_(l)\n+ 438 {\n+ 439 syncBaseArray();\n+ 440 }\n+ 441\n+ 442\n+ 454 template\n+455 BlockVector (size_type _n, S _capacity)\n+ 456 {\n+ 457 static_assert(std::numeric_limits::is_integer,\n+ 458 \"capacity must be an unsigned integral type (be aware, that this\n+constructor does not set the default value!)\" );\n+ 459 if((size_type)_capacity > _n)\n+ 460 storage_.reserve(_capacity);\n+ 461 storage_.resize(_n);\n+ 462 syncBaseArray();\n+ 463 }\n+ 464\n+ 465\n+475 void reserve(size_type capacity)\n+ 476 {\n+ 477 [[maybe_unused]] const auto &guard =\n+ 478 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n+ 479 storage_.reserve(capacity);\n+ 480 }\n+ 481\n+488 size_type capacity() const\n+ 489 {\n+ 490 return storage_.capacity();\n+ 491 }\n+ 492\n+503 void resize(size_type size)\n+ 504 {\n+ 505 [[maybe_unused]] const auto &guard =\n+ 506 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n+ 507 storage_.resize(size);\n+ 508 }\n+ 509\n+511 BlockVector(const BlockVector &a)\n+ 512 noexcept(noexcept(std::declval().storage_ = a.storage_))\n+ 513 {\n+ 514 storage_ = a.storage_;\n+ 515 syncBaseArray();\n+ 516 }\n+ 517\n+519 BlockVector(BlockVector &&a)\n+ 520 noexcept(noexcept(std::declval().swap(a)))\n+ 521 {\n+ 522 swap(a);\n+ 523 }\n+ 524\n+526 BlockVector& operator=(const BlockVector& a)\n+ 527 noexcept(noexcept(std::declval().storage_ = a.storage_))\n+ 528 {\n+ 529 [[maybe_unused]] const auto &guard =\n+ 530 Imp::makeScopeGuard([this]{ syncBaseArray(); });\n+ 531 storage_ = a.storage_;\n+ 532 return *this;\n+ 533 }\n+ 534\n+536 BlockVector& operator=(BlockVector&& a)\n+ 537 noexcept(noexcept(std::declval().swap(a)))\n+ 538 {\n+ 539 swap(a);\n+ 540 return *this;\n+ 541 }\n+ 542\n+544 void swap(BlockVector &other)\n+ 545 noexcept(noexcept(\n+ 546 std::declval().storage_.swap(other.storage_)))\n+ 547 {\n+ 548 [[maybe_unused]] const auto &guard = Imp::makeScopeGuard([&]{\n+ 549 syncBaseArray();\n+ 550 other.syncBaseArray();\n+ 551 });\n+ 552 storage_.swap(other.storage_);\n+ 553 }\n+ 554\n+556 BlockVector& operator=(const field_type& k)\n+ 557 {\n+ 558 // forward to operator= in base class\n+ 559 (static_cast&>(*this)) = k;\n+ 560 return *this;\n+ 561 }\n+ 562\n+ 563 private:\n+ 564 void syncBaseArray() noexcept\n+ 565 {\n+ 566 this->p = storage_.data();\n+ 567 this->n = storage_.size();\n+ 568 }\n+ 569\n+ 570 std::vector storage_;\n+ 571 };\n+ 572\n+ 578 template\n+579 struct FieldTraits< BlockVector >\n+ 580 {\n+581 typedef typename FieldTraits::field_type field_type;\n+582 typedef typename FieldTraits::real_type real_type;\n+ 583 };\n+ 589 template\n+590 std::ostream& operator<<(std::ostream& s, const BlockVector& v)\n+ 591 {\n+ 592 typedef typename BlockVector::size_type size_type;\n+ 593\n+ 594 for (size_type i=0; i\n+ 623#else\n+ 624 template >\n+ 625#endif\n+ 626 class BlockVectorWindow : public Imp::block_vector_unmanaged\n+ 627 {\n+ 628 public:\n+ 629\n+ 630 //===== type definitions and constants\n+ 631\n+ 633 using field_type = typename Imp::BlockTraits::field_type;\n+ 634\n+ 636 typedef B block_type;\n+ 637\n+ 639 typedef A allocator_type;\n+ 640\n+ 642 typedef typename A::size_type size_type;\n+ 643\n+ 645 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+ 646 static constexpr unsigned int blocklevel = blockLevel()+1;\n+ 647\n+ 649 typedef typename Imp::block_vector_unmanaged::Iterator Iterator;\n+ 650\n+ 652 typedef typename Imp::block_vector_unmanaged::ConstIterator\n+ConstIterator;\n+ 653\n+ 654\n+ 655 //===== constructors and such\n+ 657 BlockVectorWindow () : Imp::block_vector_unmanaged()\n+ 658 { }\n+ 659\n+ 661 BlockVectorWindow (B* _p, size_type _n)\n+ 662 {\n+ 663 this->n = _n;\n+ 664 this->p = _p;\n+ 665 }\n+ 666\n+ 668 BlockVectorWindow (const BlockVectorWindow& a)\n+ 669 {\n+ 670 this->n = a.n;\n+ 671 this->p = a.p;\n+ 672 }\n+ 673\n+ 675 BlockVectorWindow& operator= (const BlockVectorWindow& a)\n+ 676 {\n+ 677 // check correct size\n+ 678#ifdef DUNE_ISTL_WITH_CHECKING\n+ 679 if (this->n!=a.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 680#endif\n+ 681\n+ 682 if (&a!=this) // check if this and a are different objects\n+ 683 {\n+ 684 // copy data\n+ 685 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n+ 686 }\n+ 687 return *this;\n+ 688 }\n+ 689\n+ 691 BlockVectorWindow& operator= (const field_type& k)\n+ 692 {\n+ 693 (static_cast&>(*this)) = k;\n+ 694 return *this;\n+ 695 }\n+ 696\n+ 698 operator BlockVector() const {\n+ 699 auto bv = BlockVector(this->n);\n+ 700\n+ 701 std::copy(this->begin(), this->end(), bv.begin());\n+ 702\n+ 703 return bv;\n+ 704 }\n+ 705\n+ 706 //===== window manipulation methods\n+ 707\n+ 709 void set (size_type _n, B* _p)\n+ 710 {\n+ 711 this->n = _n;\n+ 712 this->p = _p;\n+ 713 }\n+ 714\n+ 716 void setsize (size_type _n)\n+ 717 {\n+ 718 this->n = _n;\n+ 719 }\n+ 720\n+ 722 void setptr (B* _p)\n+ 723 {\n+ 724 this->p = _p;\n+ 725 }\n+ 726\n+ 728 B* getptr ()\n+ 729 {\n+ 730 return this->p;\n+ 731 }\n+ 732\n+ 734 size_type getsize () const\n+ 735 {\n+ 736 return this->n;\n+ 737 }\n+ 738 };\n+ 739\n+ 740\n+ 741\n+ 752 template >\n+ 753 class compressed_block_vector_unmanaged : public\n+compressed_base_array_unmanaged\n+ 754 {\n+ 755 public:\n+ 756\n+ 757 //===== type definitions and constants\n+ 758\n+ 760 using field_type = typename Imp::BlockTraits::field_type;\n+ 761\n+ 763 typedef B block_type;\n+ 764\n+ 766 typedef A allocator_type;\n+ 767\n+ 769 typedef typename compressed_base_array_unmanaged::iterator Iterator;\n+ 770\n+ 772 typedef typename compressed_base_array_unmanaged::const_iterator\n+ConstIterator;\n+ 773\n+ 775 typedef typename A::size_type size_type;\n+ 776\n+ 777 //===== assignment from scalar\n+ 778\n+ 779 compressed_block_vector_unmanaged& operator= (const field_type& k)\n+ 780 {\n+ 781 for (size_type i=0; in; i++)\n+ 782 (this->p)[i] = k;\n+ 783 return *this;\n+ 784 }\n+ 785\n+ 786\n+ 787 //===== vector space arithmetic\n+ 788\n+ 790 template\n+ 791 compressed_block_vector_unmanaged& operator+= (const V& y)\n+ 792 {\n+ 793#ifdef DUNE_ISTL_WITH_CHECKING\n+ 794 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n+ 795#endif\n+ 796 for (size_type i=0; ioperator[](y.j[i]) += y.p[i];\n+ 797 return *this;\n+ 798 }\n+ 799\n+ 801 template\n+ 802 compressed_block_vector_unmanaged& operator-= (const V& y)\n+ 803 {\n+ 804#ifdef DUNE_ISTL_WITH_CHECKING\n+ 805 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n+ 806#endif\n+ 807 for (size_type i=0; ioperator[](y.j[i]) -= y.p[i];\n+ 808 return *this;\n+ 809 }\n+ 810\n+ 812 template\n+ 813 compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)\n+ 814 {\n+ 815#ifdef DUNE_ISTL_WITH_CHECKING\n+ 816 if (!includesindexset(y)) DUNE_THROW(ISTLError,\"index set mismatch\");\n+ 817#endif\n+ 818 for (size_type i=0; in; ++i) (this->p)[i] *= k;\n+ 827 return *this;\n+ 828 }\n+ 829\n+ 831 compressed_block_vector_unmanaged& operator/= (const field_type& k)\n+ 832 {\n+ 833 for (size_type i=0; in; ++i) (this->p)[i] /= k;\n+ 834 return *this;\n+ 835 }\n+ 836\n+ 837\n+ 838 //===== Euclidean scalar product\n+ 839\n+ 841 field_type operator* (const compressed_block_vector_unmanaged& y) const\n+ 842 {\n+ 843#ifdef DUNE_ISTL_WITH_CHECKING\n+ 844 if (!includesindexset(y) || !y.includesindexset(*this) )\n+ 845 DUNE_THROW(ISTLError,\"index set mismatch\");\n+ 846#endif\n+ 847 field_type sum=0;\n+ 848 for (size_type i=0; in; ++i)\n+ 849 sum += (this->p)[i] * y[(this->j)[i]];\n+ 850 return sum;\n+ 851 }\n+ 852\n+ 853\n+ 854 //===== norms\n+ 855\n+ 857 typename FieldTraits::real_type one_norm () const\n+ 858 {\n+ 859 typename FieldTraits::real_type sum=0;\n+ 860 for (size_type i=0; in; ++i) sum += (this->p)[i].one_norm();\n+ 861 return sum;\n+ 862 }\n+ 863\n+ 865 typename FieldTraits::real_type one_norm_real () const\n+ 866 {\n+ 867 typename FieldTraits::real_type sum=0;\n+ 868 for (size_type i=0; in; ++i) sum += (this->p)[i].one_norm_real();\n+ 869 return sum;\n+ 870 }\n+ 871\n+ 873 typename FieldTraits::real_type two_norm () const\n+ 874 {\n+ 875 using std::sqrt;\n+ 876 typename FieldTraits::real_type sum=0;\n+ 877 for (size_type i=0; in; ++i) sum += (this->p)[i].two_norm2();\n+ 878 return sqrt(sum);\n+ 879 }\n+ 880\n+ 882 typename FieldTraits::real_type two_norm2 () const\n+ 883 {\n+ 884 typename FieldTraits::real_type sum=0;\n+ 885 for (size_type i=0; in; ++i) sum += (this->p)[i].two_norm2();\n+ 886 return sum;\n+ 887 }\n+ 888\n+ 890 template ::value, int>::type = 0>\n+ 892 typename FieldTraits::real_type infinity_norm() const {\n+ 893 using real_type = typename FieldTraits::real_type;\n+ 894 using std::max;\n+ 895\n+ 896 real_type norm = 0;\n+ 897 for (auto const &x : *this) {\n+ 898 real_type const a = x.infinity_norm();\n+ 899 norm = max(a, norm);\n+ 900 }\n+ 901 return norm;\n+ 902 }\n+ 903\n+ 905 template ::value, int>::type = 0>\n+ 907 typename FieldTraits::real_type infinity_norm_real() const {\n+ 908 using real_type = typename FieldTraits::real_type;\n+ 909 using std::max;\n+ 910\n+ 911 real_type norm = 0;\n+ 912 for (auto const &x : *this) {\n+ 913 real_type const a = x.infinity_norm_real();\n+ 914 norm = max(a, norm);\n+ 915 }\n+ 916 return norm;\n+ 917 }\n+ 918\n+ 920 template ::value, int>::type = 0>\n+ 922 typename FieldTraits::real_type infinity_norm() const {\n+ 923 using real_type = typename FieldTraits::real_type;\n+ 924 using std::max;\n+ 925\n+ 926 real_type norm = 0;\n+ 927 real_type isNaN = 1;\n+ 928 for (auto const &x : *this) {\n+ 929 real_type const a = x.infinity_norm();\n+ 930 norm = max(a, norm);\n+ 931 isNaN += a;\n+ 932 }\n+ 933 return norm * (isNaN / isNaN);\n+ 934 }\n+ 935\n+ 937 template ::value, int>::type = 0>\n+ 939 typename FieldTraits::real_type infinity_norm_real() const {\n+ 940 using real_type = typename FieldTraits::real_type;\n+ 941 using std::max;\n+ 942\n+ 943 real_type norm = 0;\n+ 944 real_type isNaN = 1;\n+ 945 for (auto const &x : *this) {\n+ 946 real_type const a = x.infinity_norm_real();\n+ 947 norm = max(a, norm);\n+ 948 isNaN += a;\n+ 949 }\n+ 950 return norm * (isNaN / isNaN);\n+ 951 }\n+ 952\n+ 953 //===== sizes\n+ 954\n+ 956 size_type N () const\n+ 957 {\n+ 958 return this->n;\n+ 959 }\n+ 960\n+ 962 size_type dim () const\n+ 963 {\n+ 964 size_type d=0;\n+ 965 for (size_type i=0; in; i++)\n+ 966 d += (this->p)[i].dim();\n+ 967 return d;\n+ 968 }\n+ 969\n+ 970 protected:\n+ 972 compressed_block_vector_unmanaged () :\n+compressed_base_array_unmanaged()\n+ 973 { }\n+ 974\n+ 976 template\n+ 977 bool includesindexset (const V& y)\n+ 978 {\n+ 979 typename V::ConstIterator e=this->end();\n+ 980 for (size_type i=0; ifind(y.j[i])==e)\n+ 982 return false;\n+ 983 return true;\n+ 984 }\n+ 985 };\n+ 986\n+ 987\n+ 1006 template >\n+ 1007 class CompressedBlockVectorWindow : public\n+compressed_block_vector_unmanaged\n+ 1008 {\n+ 1009 public:\n+ 1010\n+ 1011 //===== type definitions and constants\n+ 1012\n+ 1014 using field_type = typename Imp::BlockTraits::field_type;\n+ 1015\n+ 1017 typedef B block_type;\n+ 1018\n+ 1020 typedef A allocator_type;\n+ 1021\n+ 1023 typedef typename A::size_type size_type;\n+ 1024\n+ 1026 [[deprecated(\"Use free function blockLevel(). Will be removed after\n+2.8.\")]]\n+ 1027 static constexpr unsigned int blocklevel = blockLevel()+1;\n+ 1028\n+ 1030 typedef typename compressed_block_vector_unmanaged::Iterator\n+Iterator;\n+ 1031\n+ 1033 typedef typename compressed_block_vector_unmanaged::ConstIterator\n+ConstIterator;\n+ 1034\n+ 1035\n+ 1036 //===== constructors and such\n+ 1038 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged()\n+ 1039 { }\n+ 1040\n+ 1042 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)\n+ 1043 {\n+ 1044 this->n = _n;\n+ 1045 this->p = _p;\n+ 1046 this->j = _j;\n+ 1047 }\n+ 1048\n+ 1050 CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)\n+ 1051 {\n+ 1052 this->n = a.n;\n+ 1053 this->p = a.p;\n+ 1054 this->j = a.j;\n+ 1055 }\n+ 1056\n+ 1058 CompressedBlockVectorWindow& operator= (const\n+CompressedBlockVectorWindow& a)\n+ 1059 {\n+ 1060 // check correct size\n+ 1061#ifdef DUNE_ISTL_WITH_CHECKING\n+ 1062 if (this->n!=a.N()) DUNE_THROW(ISTLError,\"vector size mismatch\");\n+ 1063#endif\n+ 1064\n+ 1065 if (&a!=this) // check if this and a are different objects\n+ 1066 {\n+ 1067 // copy data\n+ 1068 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n+ 1069 for (size_type i=0; in; i++) this->j[i]=a.j[i];\n+ 1070 }\n+ 1071 return *this;\n+ 1072 }\n+ 1073\n+ 1075 CompressedBlockVectorWindow& operator= (const field_type& k)\n+ 1076 {\n+ 1077 (static_cast&>(*this)) = k;\n+ 1078 return *this;\n+ 1079 }\n+ 1080\n+ 1081\n+ 1082 //===== window manipulation methods\n+ 1083\n+ 1085 void set (size_type _n, B* _p, size_type* _j)\n+ 1086 {\n+ 1087 this->n = _n;\n+ 1088 this->p = _p;\n+ 1089 this->j = _j;\n+ 1090 }\n+ 1091\n+ 1093 void setsize (size_type _n)\n+ 1094 {\n+ 1095 this->n = _n;\n+ 1096 }\n+ 1097\n+ 1099 void setptr (B* _p)\n+ 1100 {\n+ 1101 this->p = _p;\n+ 1102 }\n+ 1103\n+ 1105 void setindexptr (size_type* _j)\n+ 1106 {\n+ 1107 this->j = _j;\n+ 1108 }\n+ 1109\n+ 1111 B* getptr ()\n+ 1112 {\n+ 1113 return this->p;\n+ 1114 }\n+ 1115\n+ 1117 size_type* getindexptr ()\n+ 1118 {\n+ 1119 return this->j;\n+ 1120 }\n+ 1121\n+ 1123 const B* getptr () const\n+ 1124 {\n+ 1125 return this->p;\n+ 1126 }\n+ 1127\n+ 1129 const size_type* getindexptr () const\n+ 1130 {\n+ 1131 return this->j;\n+ 1132 }\n+ 1134 size_type getsize () const\n+ 1135 {\n+ 1136 return this->n;\n+ 1137 }\n+ 1138 };\n+ 1139\n+ 1140} // end namespace 'Imp'\n+ 1141\n+ 1142\n+ 1144 template\n+ 1145 struct AutonomousValueType>\n+ 1146 {\n+ 1147 using type = BlockVector;\n+ 1148 };\n+ 1149\n+ 1150\n+ 1151} // end namespace 'Dune'\n+ 1152\n+ 1153#endif\n+basearray.hh\n+Implements several basic array containers.\n+istlexception.hh\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::GaussSeidelPresmoothDefect\n-Definition: fastamgsmoother.hh:16\n-Dune::Amg::GaussSeidelPresmoothDefect::apply\n-static void apply(const M &A, X &x, Y &d, const Y &b)\n-Definition: fastamgsmoother.hh:19\n-Dune::Amg::GaussSeidelPostsmoothDefect\n-Definition: fastamgsmoother.hh:52\n-Dune::Amg::GaussSeidelPostsmoothDefect::apply\n-static void apply(const M &A, X &x, Y &d, const Y &b)\n-Definition: fastamgsmoother.hh:55\n+Dune::operator<<\n+std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n+Send BlockVector to an output stream.\n+Definition: bvector.hh:590\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::BlockVector::BlockVector\n+BlockVector()\n+makes empty vector\n+Definition: bvector.hh:425\n+Dune::BlockVector::reserve\n+void reserve(size_type capacity)\n+Reserve space.\n+Definition: bvector.hh:475\n+Dune::BlockVector::BlockVector\n+BlockVector(BlockVector &&a) noexcept(noexcept(std::declval< BlockVector >\n+().swap(a)))\n+move constructor\n+Definition: bvector.hh:519\n+Dune::BlockVector::BlockVector\n+BlockVector(size_type _n)\n+make vector with _n components\n+Definition: bvector.hh:431\n+Dune::BlockVector::resize\n+void resize(size_type size)\n+Resize the vector.\n+Definition: bvector.hh:503\n+Dune::BlockVector::Iterator\n+Imp::block_vector_unmanaged< B, A >::Iterator Iterator\n+make iterators available as types\n+Definition: bvector.hh:417\n+Dune::BlockVector::blocklevel\n+static constexpr unsigned int blocklevel\n+increment block level counter\n+Definition: bvector.hh:414\n+Dune::BlockVector::BlockVector\n+BlockVector(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >\n+().storage_=a.storage_))\n+copy constructor\n+Definition: bvector.hh:511\n+Dune::BlockVector::allocator_type\n+A allocator_type\n+export the allocator type\n+Definition: bvector.hh:407\n+Dune::BlockVector::operator=\n+BlockVector & operator=(const BlockVector &a) noexcept(noexcept(std::declval<\n+BlockVector >().storage_=a.storage_))\n+assignment\n+Definition: bvector.hh:526\n+Dune::BlockVector::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: bvector.hh:401\n+Dune::BlockVector::size_type\n+A::size_type size_type\n+The type for the index access.\n+Definition: bvector.hh:410\n+Dune::BlockVector::BlockVector\n+BlockVector(std::initializer_list< B > const &l)\n+Construct from a std::initializer_list.\n+Definition: bvector.hh:437\n+Dune::BlockVector::capacity\n+size_type capacity() const\n+Get the capacity of the vector.\n+Definition: bvector.hh:488\n+Dune::BlockVector::BlockVector\n+BlockVector(size_type _n, S _capacity)\n+Make vector with _n components but preallocating capacity components.\n+Definition: bvector.hh:455\n+Dune::BlockVector::block_type\n+B block_type\n+export the type representing the components\n+Definition: bvector.hh:404\n+Dune::BlockVector::swap\n+void swap(BlockVector &other) noexcept(noexcept(std::declval< BlockVector & >\n+().storage_.swap(other.storage_)))\n+swap operation\n+Definition: bvector.hh:544\n+Dune::BlockVector::ConstIterator\n+Imp::block_vector_unmanaged< B, A >::ConstIterator ConstIterator\n+make iterators available as types\n+Definition: bvector.hh:420\n+Dune::FieldTraits<_BlockVector<_B,_A_>_>::real_type\n+FieldTraits< B >::real_type real_type\n+Definition: bvector.hh:582\n+Dune::FieldTraits<_BlockVector<_B,_A_>_>::field_type\n+FieldTraits< B >::field_type field_type\n+Definition: bvector.hh:581\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00125.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00125.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: amg.hh File Reference\n+dune-istl: ilusubdomainsolver.hh File Reference\n \n \n \n \n \n \n \n@@ -58,78 +58,54 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n \n+
    ilusubdomainsolver.hh File Reference
    \n \n
    \n \n-

    The AMG preconditioner. \n+

    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz. \n More...

    \n-
    #include <memory>
    \n-#include <sstream>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/istl/paamg/smoother.hh>
    \n-#include <dune/istl/paamg/transfer.hh>
    \n-#include <dune/istl/paamg/matrixhierarchy.hh>
    \n-#include <dune/istl/solvers.hh>
    \n-#include <dune/istl/scalarproducts.hh>
    \n-#include <dune/istl/superlu.hh>
    \n-#include <dune/istl/umfpack.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n+
    #include <map>
    \n #include <dune/common/typetraits.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/common/parametertree.hh>
    \n+#include <dune/istl/preconditioners.hh>
    \n+#include "matrix.hh"
    \n+#include <cmath>
    \n+#include <cstdlib>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::Amg::AMG< M, X, S, PI, A >
     Parallel algebraic multigrid based on agglomeration. More...
    class  Dune::ILUSubdomainSolver< M, X, Y >
     base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver. More...
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >
    class  Dune::ILU0SubdomainSolver< M, X, Y >
     Exact subdomain solver using ILU(p) with appropriate p. More...
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, SolverType >
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, superlu >
     
    struct  Dune::AMGCreator
     
    struct  Dune::AMGCreator::isValidBlockType< class >
     
    struct  Dune::AMGCreator::isValidBlockType< FieldMatrix< T, n, m > >
    class  Dune::ILUNSubdomainSolver< M, X, Y >
     
    \n \n \n \n-\n-\n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n

    \n-Functions

     Dune::DUNE_REGISTER_PRECONDITIONER ("amg", AMGCreator())
     
    \n

    Detailed Description

    \n-

    The AMG preconditioner.

    \n+

    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,62 +4,37 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-Classes | Namespaces | Functions\n-amg.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-The AMG preconditioner. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+ilusubdomainsolver.hh File Reference\n+Various local subdomain solvers based on ILU for SeqOverlappingSchwarz. More...\n+#include \n #include \n-#include \n-#include \n-#include \n+#include \n+#include \"matrix.hh\"\n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::Amg::AMG<_M,_X,_S,_PI,_A_>\n-\u00a0 Parallel algebraic multigrid based on agglomeration. More...\n+class \u00a0Dune::ILUSubdomainSolver<_M,_X,_Y_>\n+\u00a0 base class encapsulating common algorithms of ILU0SubdomainSolver and\n+ ILUNSubdomainSolver. More...\n \u00a0\n-struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>\n+class \u00a0Dune::ILU0SubdomainSolver<_M,_X,_Y_>\n+\u00a0 Exact subdomain solver using ILU(p) with appropriate p. More...\n \u00a0\n-struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>::Solver<_M,\n- SolverType_>\n-\u00a0\n-struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>::Solver<_M,_superlu\n- >\n-\u00a0\n-struct \u00a0Dune::AMGCreator\n-\u00a0\n-struct \u00a0Dune::AMGCreator::isValidBlockType<_class_>\n-\u00a0\n-struct \u00a0Dune::AMGCreator::isValidBlockType<_FieldMatrix<_T,_n,_m_>_>\n+class \u00a0Dune::ILUNSubdomainSolver<_M,_X,_Y_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"amg\", AMGCreator())\n-\u00a0\n ***** Detailed Description *****\n-The AMG preconditioner.\n+Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00125_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00125_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: amg.hh Source File\n+dune-istl: ilusubdomainsolver.hh Source File\n \n \n \n \n \n \n \n@@ -58,1207 +58,220 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n
    \n
    \n-
    amg.hh
    \n+
    ilusubdomainsolver.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_AMG_HH
    \n-
    6#define DUNE_AMG_AMG_HH
    \n+
    5#ifndef DUNE_ISTL_ILUSUBDOMAINSOLVER_HH
    \n+
    6#define DUNE_ISTL_ILUSUBDOMAINSOLVER_HH
    \n
    7
    \n-
    8#include <memory>
    \n-
    9#include <sstream>
    \n-
    10#include <dune/common/exceptions.hh>
    \n-\n-\n-\n-
    14#include <dune/istl/solvers.hh>
    \n-\n-
    16#include <dune/istl/superlu.hh>
    \n-
    17#include <dune/istl/umfpack.hh>
    \n-\n-
    19#include <dune/common/typetraits.hh>
    \n-
    20#include <dune/common/exceptions.hh>
    \n-
    21#include <dune/common/scalarvectorview.hh>
    \n-
    22#include <dune/common/scalarmatrixview.hh>
    \n-
    23#include <dune/common/parametertree.hh>
    \n-
    24
    \n-
    25namespace Dune
    \n-
    26{
    \n-
    27 namespace Amg
    \n-
    28 {
    \n-
    46 template<class M, class X, class S, class P, class K, class A>
    \n-
    47 class KAMG;
    \n-
    48
    \n-
    49 template<class T>
    \n-
    50 class KAmgTwoGrid;
    \n-
    51
    \n-
    62 template<class M, class X, class S, class PI=SequentialInformation,
    \n-
    63 class A=std::allocator<X> >
    \n-
    64 class AMG : public Preconditioner<X,X>
    \n-
    65 {
    \n-
    66 template<class M1, class X1, class S1, class P1, class K1, class A1>
    \n-
    67 friend class KAMG;
    \n-
    68
    \n-
    69 friend class KAmgTwoGrid<AMG>;
    \n-
    70
    \n-
    71 public:
    \n-
    73 typedef M Operator;
    \n-\n-\n-\n-
    85
    \n-
    87 typedef X Domain;
    \n-
    89 typedef X Range;
    \n-\n-
    97 typedef S Smoother;
    \n-
    98
    \n-\n-
    101
    \n-
    111 AMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n-
    112 const SmootherArgs& smootherArgs, const Parameters& parms);
    \n-
    113
    \n-
    125 template<class C>
    \n-
    126 AMG(const Operator& fineOperator, const C& criterion,
    \n-
    127 const SmootherArgs& smootherArgs=SmootherArgs(),
    \n-\n+
    8#include <map>
    \n+
    9#include <dune/common/typetraits.hh>
    \n+\n+
    11#include "matrix.hh"
    \n+
    12#include <cmath>
    \n+
    13#include <cstdlib>
    \n+
    14
    \n+
    15namespace Dune {
    \n+
    16
    \n+
    35 template<class M, class X, class Y>
    \n+\n+
    37 public:
    \n+
    39 typedef typename std::remove_const<M>::type matrix_type;
    \n+
    41 typedef X domain_type;
    \n+
    43 typedef Y range_type;
    \n+
    44
    \n+
    51 virtual void apply (X& v, const Y& d) =0;
    \n+
    52
    \n+\n+
    54 {}
    \n+
    55
    \n+
    56 protected:
    \n+
    62 template<class S>
    \n+
    63 std::size_t copyToLocalMatrix(const M& A, S& rowset);
    \n+
    64
    \n+
    66 // for ILUN
    \n+\n+
    68 };
    \n+
    69
    \n+
    76 template<class M, class X, class Y>
    \n+\n+
    78 : public ILUSubdomainSolver<M,X,Y>{
    \n+
    79 public:
    \n+
    81 typedef typename std::remove_const<M>::type matrix_type;
    \n+
    82 typedef typename std::remove_const<M>::type rilu_type;
    \n+
    84 typedef X domain_type;
    \n+
    86 typedef Y range_type;
    \n+
    87
    \n+
    88
    \n+
    93 void apply (X& v, const Y& d)
    \n+
    94 {
    \n+
    95 ILU::blockILUBacksolve(this->ILU,v,d);
    \n+
    96 }
    \n+
    104 template<class S>
    \n+
    105 void setSubMatrix(const M& A, S& rowset);
    \n+
    106
    \n+
    107 };
    \n+
    108
    \n+
    109 template<class M, class X, class Y>
    \n+\n+
    111 : public ILUSubdomainSolver<M,X,Y>{
    \n+
    112 public:
    \n+
    114 typedef typename std::remove_const<M>::type matrix_type;
    \n+
    115 typedef typename std::remove_const<M>::type rilu_type;
    \n+
    117 typedef X domain_type;
    \n+
    119 typedef Y range_type;
    \n+
    120
    \n+
    125 void apply (X& v, const Y& d)
    \n+
    126 {
    \n+
    127 ILU::blockILUBacksolve(RILU,v,d);
    \n+
    128 }
    \n
    129
    \n-
    180 AMG(std::shared_ptr<const Operator> fineOperator, const ParameterTree& configuration, const ParallelInformation& pinfo=ParallelInformation());
    \n-
    181
    \n-
    185 AMG(const AMG& amg);
    \n-
    186
    \n-
    188 void pre(Domain& x, Range& b);
    \n-
    189
    \n-
    191 void apply(Domain& v, const Range& d);
    \n-
    192
    \n-\n-
    195 {
    \n-
    196 return category_;
    \n-
    197 }
    \n+
    137 template<class S>
    \n+
    138 void setSubMatrix(const M& A, S& rowset);
    \n+
    139
    \n+
    140 private:
    \n+
    144 rilu_type RILU;
    \n+
    145 };
    \n+
    146
    \n+
    147
    \n+
    148
    \n+
    149 template<class M, class X, class Y>
    \n+
    150 template<class S>
    \n+
    151 std::size_t ILUSubdomainSolver<M,X,Y>::copyToLocalMatrix(const M& A, S& rowSet)
    \n+
    152 {
    \n+
    153 // Calculate consecutive indices for local problem
    \n+
    154 // while perserving the ordering
    \n+
    155 typedef typename M::size_type size_type;
    \n+
    156 typedef std::map<typename S::value_type,size_type> IndexMap;
    \n+
    157 typedef typename IndexMap::iterator IMIter;
    \n+
    158 IndexMap indexMap;
    \n+
    159 IMIter guess = indexMap.begin();
    \n+
    160 size_type localIndex=0;
    \n+
    161
    \n+
    162 typedef typename S::const_iterator SIter;
    \n+
    163 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n+
    164 rowIdx!= rowEnd; ++rowIdx, ++localIndex)
    \n+
    165 guess = indexMap.insert(guess,
    \n+
    166 std::make_pair(*rowIdx,localIndex));
    \n+
    167
    \n+
    168
    \n+
    169 // Build Matrix for local subproblem
    \n+
    170 ILU.setSize(rowSet.size(),rowSet.size());
    \n+
    171 ILU.setBuildMode(matrix_type::row_wise);
    \n+
    172
    \n+
    173 // Create sparsity pattern
    \n+
    174 typedef typename matrix_type::CreateIterator CIter;
    \n+
    175 CIter rowCreator = ILU.createbegin();
    \n+
    176 std::size_t offset=0;
    \n+
    177 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n+
    178 rowIdx!= rowEnd; ++rowIdx, ++rowCreator) {
    \n+
    179 // See which row entries are in our subset and add them to
    \n+
    180 // the sparsity pattern
    \n+
    181 guess = indexMap.begin();
    \n+
    182
    \n+
    183 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),
    \n+
    184 endcol=A[*rowIdx].end(); col != endcol; ++col) {
    \n+
    185 // search for the entry in the row set
    \n+
    186 guess = indexMap.find(col.index());
    \n+
    187 if(guess!=indexMap.end()) {
    \n+
    188 // add local index to row
    \n+
    189 rowCreator.insert(guess->second);
    \n+
    190 offset=std::max(offset,(std::size_t)std::abs((int)(guess->second-rowCreator.index())));
    \n+
    191 }
    \n+
    192 }
    \n+
    193
    \n+
    194 }
    \n+
    195
    \n+
    196 // Insert the matrix values for the local problem
    \n+
    197 typename matrix_type::iterator iluRow=ILU.begin();
    \n
    198
    \n-
    200 void post(Domain& x);
    \n-
    201
    \n-
    206 template<class A1>
    \n-
    207 void getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont);
    \n-
    208
    \n-
    209 std::size_t levels();
    \n-
    210
    \n-
    211 std::size_t maxlevels();
    \n-
    212
    \n-\n-
    222 {
    \n-
    223 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
    \n-
    224 }
    \n-
    225
    \n-\n-
    231
    \n-
    232 private:
    \n-
    233 /*
    \n-
    234 * @brief Helper function to create hierarchies with parameter tree.
    \n-
    235 *
    \n-
    236 * Will create the coarsen criterion with the norm and create the
    \n-
    237 * Hierarchies
    \n-
    238 * \\tparam Norm Type of the norm to use.
    \n-
    239 */
    \n-
    240 template<class Norm>
    \n-
    241 void createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr,
    \n-
    242 const PI& pinfo, const Norm&,
    \n-
    243 const ParameterTree& configuration,
    \n-
    244 std::true_type compiles = std::true_type());
    \n-
    245 template<class Norm>
    \n-
    246 void createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr,
    \n-
    247 const PI& pinfo, const Norm&,
    \n-
    248 const ParameterTree& configuration,
    \n-
    249 std::false_type);
    \n-
    254 template<class C>
    \n-
    255 void createHierarchies(C& criterion, std::shared_ptr<const Operator> matrixptr,
    \n-
    256 const PI& pinfo, const ParameterTree& configuration);
    \n-
    263 template<class C>
    \n-
    264 void createHierarchies(C& criterion,
    \n-
    265 const std::shared_ptr<const Operator>& matrixptr,
    \n-
    266 const PI& pinfo);
    \n-
    273 struct LevelContext
    \n-
    274 {
    \n-\n-\n-\n-\n-
    291 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
    \n-
    295 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
    \n-\n-\n-\n-
    311 std::size_t level;
    \n-
    312 };
    \n-
    313
    \n-
    314
    \n-
    319 void mgc(LevelContext& levelContext);
    \n-
    320
    \n-
    321 void additiveMgc();
    \n-
    322
    \n-
    329 void moveToFineLevel(LevelContext& levelContext,bool processedFineLevel);
    \n-
    330
    \n-
    335 bool moveToCoarseLevel(LevelContext& levelContext);
    \n-
    336
    \n-
    341 void initIteratorsWithFineLevel(LevelContext& levelContext);
    \n-
    342
    \n-
    344 std::shared_ptr<OperatorHierarchy> matrices_;
    \n-
    346 SmootherArgs smootherArgs_;
    \n-
    348 std::shared_ptr<Hierarchy<Smoother,A> > smoothers_;
    \n-
    350 std::shared_ptr<CoarseSolver> solver_;
    \n-
    352 std::shared_ptr<Hierarchy<Range,A>> rhs_;
    \n-
    354 std::shared_ptr<Hierarchy<Domain,A>> lhs_;
    \n-
    356 std::shared_ptr<Hierarchy<Domain,A>> update_;
    \n-\n-
    360 std::shared_ptr<ScalarProduct> scalarProduct_;
    \n-
    362 std::size_t gamma_;
    \n-
    364 std::size_t preSteps_;
    \n-
    366 std::size_t postSteps_;
    \n-
    367 bool buildHierarchy_;
    \n-
    368 bool additive;
    \n-
    369 bool coarsesolverconverged;
    \n-
    370 std::shared_ptr<Smoother> coarseSmoother_;
    \n-
    372 SolverCategory::Category category_;
    \n-
    374 std::size_t verbosity_;
    \n-
    375
    \n-
    376 struct ToLower
    \n-
    377 {
    \n-
    378 std::string operator()(const std::string& str)
    \n-
    379 {
    \n-
    380 std::stringstream retval;
    \n-
    381 std::ostream_iterator<char> out(retval);
    \n-
    382 std::transform(str.begin(), str.end(), out,
    \n-
    383 [](char c){
    \n-
    384 return std::tolower(c, std::locale::classic());
    \n-
    385 });
    \n-
    386 return retval.str();
    \n-
    387 }
    \n-
    388 };
    \n-
    389 };
    \n-
    390
    \n-
    391 template<class M, class X, class S, class PI, class A>
    \n-
    392 inline AMG<M,X,S,PI,A>::AMG(const AMG& amg)
    \n-
    393 : matrices_(amg.matrices_), smootherArgs_(amg.smootherArgs_),
    \n-
    394 smoothers_(amg.smoothers_), solver_(amg.solver_),
    \n-
    395 rhs_(), lhs_(), update_(),
    \n-
    396 scalarProduct_(amg.scalarProduct_), gamma_(amg.gamma_),
    \n-
    397 preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
    \n-
    398 buildHierarchy_(amg.buildHierarchy_),
    \n-
    399 additive(amg.additive), coarsesolverconverged(amg.coarsesolverconverged),
    \n-
    400 coarseSmoother_(amg.coarseSmoother_),
    \n-
    401 category_(amg.category_),
    \n-
    402 verbosity_(amg.verbosity_)
    \n-
    403 {}
    \n-
    404
    \n-
    405 template<class M, class X, class S, class PI, class A>
    \n-\n-
    407 const SmootherArgs& smootherArgs,
    \n-
    408 const Parameters& parms)
    \n-
    409 : matrices_(stackobject_to_shared_ptr(matrices)), smootherArgs_(smootherArgs),
    \n-
    410 smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver),
    \n-
    411 rhs_(), lhs_(), update_(), scalarProduct_(0),
    \n-
    412 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
    \n-
    413 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
    \n-
    414 additive(parms.getAdditive()), coarsesolverconverged(true),
    \n-
    415 coarseSmoother_(),
    \n-
    416// #warning should category be retrieved from matrices?
    \n-
    417 category_(SolverCategory::category(*smoothers_->coarsest())),
    \n-
    418 verbosity_(parms.debugLevel())
    \n-
    419 {
    \n-
    420 assert(matrices_->isBuilt());
    \n-
    421
    \n-
    422 // build the necessary smoother hierarchies
    \n-
    423 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);
    \n-
    424 }
    \n-
    425
    \n-
    426 template<class M, class X, class S, class PI, class A>
    \n-
    427 template<class C>
    \n-\n-
    429 const C& criterion,
    \n-
    430 const SmootherArgs& smootherArgs,
    \n-
    431 const PI& pinfo)
    \n-
    432 : smootherArgs_(smootherArgs),
    \n-
    433 smoothers_(new Hierarchy<Smoother,A>), solver_(),
    \n-
    434 rhs_(), lhs_(), update_(), scalarProduct_(),
    \n-
    435 gamma_(criterion.getGamma()), preSteps_(criterion.getNoPreSmoothSteps()),
    \n-
    436 postSteps_(criterion.getNoPostSmoothSteps()), buildHierarchy_(true),
    \n-
    437 additive(criterion.getAdditive()), coarsesolverconverged(true),
    \n-
    438 coarseSmoother_(),
    \n-
    439 category_(SolverCategory::category(pinfo)),
    \n-
    440 verbosity_(criterion.debugLevel())
    \n-
    441 {
    \n-\n-
    443 DUNE_THROW(InvalidSolverCategory, "Matrix and Communication must have the same SolverCategory!");
    \n-
    444 // TODO: reestablish compile time checks.
    \n-
    445 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
    \n-
    446 // "Matrix and Solver must match in terms of category!");
    \n-
    447 auto matrixptr = stackobject_to_shared_ptr(matrix);
    \n-
    448 createHierarchies(criterion, matrixptr, pinfo);
    \n-
    449 }
    \n-
    450
    \n-
    451 template<class M, class X, class S, class PI, class A>
    \n-
    452 AMG<M,X,S,PI,A>::AMG(std::shared_ptr<const Operator> matrixptr,
    \n-
    453 const ParameterTree& configuration,
    \n-
    454 const ParallelInformation& pinfo) :
    \n-
    455 smoothers_(new Hierarchy<Smoother,A>),
    \n-
    456 solver_(), rhs_(), lhs_(), update_(), scalarProduct_(), buildHierarchy_(true),
    \n-
    457 coarsesolverconverged(true), coarseSmoother_(),
    \n-
    458 category_(SolverCategory::category(pinfo))
    \n-
    459 {
    \n-
    460
    \n-
    461 if (configuration.hasKey ("smootherIterations"))
    \n-
    462 smootherArgs_.iterations = configuration.get<int>("smootherIterations");
    \n-
    463
    \n-
    464 if (configuration.hasKey ("smootherRelaxation"))
    \n-
    465 smootherArgs_.relaxationFactor = configuration.get<typename SmootherArgs::RelaxationFactor>("smootherRelaxation");
    \n-
    466
    \n-
    467 auto normName = ToLower()(configuration.get("strengthMeasure", "diagonal"));
    \n-
    468 auto index = configuration.get<int>("diagonalRowIndex", 0);
    \n-
    469
    \n-
    470 if ( normName == "diagonal")
    \n-
    471 {
    \n-
    472 using field_type = typename M::field_type;
    \n-
    473 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    474 std::is_convertible<field_type, real_type> compiles;
    \n-
    475
    \n-
    476 switch (index)
    \n-
    477 {
    \n-
    478 case 0:
    \n-
    479 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<0>(), configuration, compiles);
    \n-
    480 break;
    \n-
    481 case 1:
    \n-
    482 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<1>(), configuration, compiles);
    \n-
    483 break;
    \n-
    484 case 2:
    \n-
    485 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<2>(), configuration, compiles);
    \n-
    486 break;
    \n-
    487 case 3:
    \n-
    488 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<3>(), configuration, compiles);
    \n-
    489 break;
    \n-
    490 case 4:
    \n-
    491 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<4>(), configuration, compiles);
    \n-
    492 break;
    \n-
    493 default:
    \n-
    494 DUNE_THROW(InvalidStateException, "Currently strengthIndex>4 is not supported.");
    \n-
    495 }
    \n-
    496 }
    \n-
    497 else if (normName == "rowsum")
    \n-
    498 createCriterionAndHierarchies(matrixptr, pinfo, RowSum(), configuration);
    \n-
    499 else if (normName == "frobenius")
    \n-
    500 createCriterionAndHierarchies(matrixptr, pinfo, FrobeniusNorm(), configuration);
    \n-
    501 else if (normName == "one")
    \n-
    502 createCriterionAndHierarchies(matrixptr, pinfo, AlwaysOneNorm(), configuration);
    \n-
    503 else
    \n-
    504 DUNE_THROW(Dune::NotImplemented, "Wrong config file: strengthMeasure "<<normName<<" is not supported by AMG");
    \n-
    505 }
    \n-
    506
    \n-
    507 template<class M, class X, class S, class PI, class A>
    \n-
    508 template<class Norm>
    \n-
    509 void AMG<M,X,S,PI,A>::createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const Norm&, const ParameterTree& configuration, std::false_type)
    \n-
    510 {
    \n-
    511 DUNE_THROW(InvalidStateException, "Strength of connection measure does not support this type ("
    \n-
    512 << className<typename M::field_type>() << ") as it is lacking a conversion to"
    \n-
    513 << className<typename FieldTraits<typename M::field_type>::real_type>() << ".");
    \n-
    514 }
    \n-
    515
    \n-
    516 template<class M, class X, class S, class PI, class A>
    \n-
    517 template<class Norm>
    \n-
    518 void AMG<M,X,S,PI,A>::createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const Norm&, const ParameterTree& configuration, std::true_type)
    \n-
    519 {
    \n-
    520 if (configuration.get<bool>("criterionSymmetric", true))
    \n-
    521 {
    \n-
    522 using Criterion = Dune::Amg::CoarsenCriterion<
    \n-\n-
    524 Criterion criterion;
    \n-
    525 createHierarchies(criterion, matrixptr, pinfo, configuration);
    \n-
    526 }
    \n-
    527 else
    \n-
    528 {
    \n-
    529 using Criterion = Dune::Amg::CoarsenCriterion<
    \n-\n-
    531 Criterion criterion;
    \n-
    532 createHierarchies(criterion, matrixptr, pinfo, configuration);
    \n-
    533 }
    \n-
    534 }
    \n-
    535
    \n-
    536 template<class M, class X, class S, class PI, class A>
    \n-
    537 template<class C>
    \n-
    538 void AMG<M,X,S,PI,A>::createHierarchies(C& criterion, std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const ParameterTree& configuration)
    \n-
    539 {
    \n-
    540 if (configuration.hasKey ("maxLevel"))
    \n-
    541 criterion.setMaxLevel(configuration.get<int>("maxLevel"));
    \n-
    542
    \n-
    543 if (configuration.hasKey ("minCoarseningRate"))
    \n-
    544 criterion.setMinCoarsenRate(configuration.get<int>("minCoarseningRate"));
    \n-
    545
    \n-
    546 if (configuration.hasKey ("coarsenTarget"))
    \n-
    547 criterion.setCoarsenTarget (configuration.get<int>("coarsenTarget"));
    \n-
    548
    \n-
    549 if (configuration.hasKey ("accumulationMode"))
    \n-
    550 {
    \n-
    551 std::string mode = ToLower()(configuration.get<std::string>("accumulationMode"));
    \n-
    552 if ( mode == "none")
    \n-
    553 criterion.setAccumulate(AccumulationMode::noAccu);
    \n-
    554 else if ( mode == "atonce" )
    \n-
    555 criterion.setAccumulate(AccumulationMode::atOnceAccu);
    \n-
    556 else if ( mode == "successive")
    \n-
    557 criterion.setCoarsenTarget (AccumulationMode::successiveAccu);
    \n-
    558 else
    \n-
    559 DUNE_THROW(InvalidSolverFactoryConfiguration, "Parameter accumulationMode does not allow value "
    \n-
    560 << mode <<".");
    \n-
    561 }
    \n-
    562
    \n-
    563 if (configuration.hasKey ("prolongationDampingFactor"))
    \n-
    564 criterion.setProlongationDampingFactor (configuration.get<double>("prolongationDampingFactor"));
    \n-
    565
    \n-
    566 if (configuration.hasKey("defaultAggregationSizeMode"))
    \n-
    567 {
    \n-
    568 auto mode = ToLower()(configuration.get<std::string>("defaultAggregationSizeMode"));
    \n-
    569 auto dim = configuration.get<std::size_t>("defaultAggregationDimension");
    \n-
    570 std::size_t maxDistance = 2;
    \n-
    571 if (configuration.hasKey("MaxAggregateDistance"))
    \n-
    572 maxDistance = configuration.get<std::size_t>("maxAggregateDistance");
    \n-
    573 if (mode == "isotropic")
    \n-
    574 criterion.setDefaultValuesIsotropic(dim, maxDistance);
    \n-
    575 else if(mode == "anisotropic")
    \n-
    576 criterion.setDefaultValuesAnisotropic(dim, maxDistance);
    \n-
    577 else
    \n-
    578 DUNE_THROW(InvalidSolverFactoryConfiguration, "Parameter accumulationMode does not allow value "
    \n-
    579 << mode <<".");
    \n-
    580 }
    \n-
    581
    \n-
    582 if (configuration.hasKey("maxAggregateDistance"))
    \n-
    583 criterion.setMaxDistance(configuration.get<std::size_t>("maxAggregateDistance"));
    \n-
    584
    \n-
    585 if (configuration.hasKey("minAggregateSize"))
    \n-
    586 criterion.setMinAggregateSize(configuration.get<std::size_t>("minAggregateSize"));
    \n-
    587
    \n-
    588 if (configuration.hasKey("maxAggregateSize"))
    \n-
    589 criterion.setMaxAggregateSize(configuration.get<std::size_t>("maxAggregateSize"));
    \n-
    590
    \n-
    591 if (configuration.hasKey("maxAggregateConnectivity"))
    \n-
    592 criterion.setMaxConnectivity(configuration.get<std::size_t>("maxAggregateConnectivity"));
    \n-
    593
    \n-
    594 if (configuration.hasKey ("alpha"))
    \n-
    595 criterion.setAlpha (configuration.get<double> ("alpha"));
    \n-
    596
    \n-
    597 if (configuration.hasKey ("beta"))
    \n-
    598 criterion.setBeta (configuration.get<double> ("beta"));
    \n-
    599
    \n-
    600 if (configuration.hasKey ("gamma"))
    \n-
    601 criterion.setGamma (configuration.get<std::size_t> ("gamma"));
    \n-
    602 gamma_ = criterion.getGamma();
    \n-
    603
    \n-
    604 if (configuration.hasKey ("additive"))
    \n-
    605 criterion.setAdditive (configuration.get<bool>("additive"));
    \n-
    606 additive = criterion.getAdditive();
    \n-
    607
    \n-
    608 if (configuration.hasKey ("preSteps"))
    \n-
    609 criterion.setNoPreSmoothSteps (configuration.get<std::size_t> ("preSteps"));
    \n-
    610 preSteps_ = criterion.getNoPreSmoothSteps ();
    \n-
    611
    \n-
    612 if (configuration.hasKey ("postSteps"))
    \n-
    613 criterion.setNoPostSmoothSteps (configuration.get<std::size_t> ("postSteps"));
    \n-
    614 postSteps_ = criterion.getNoPostSmoothSteps ();
    \n-
    615
    \n-
    616 verbosity_ = configuration.get("verbosity", 0);
    \n-
    617 criterion.setDebugLevel (verbosity_);
    \n-
    618
    \n-
    619 createHierarchies(criterion, matrixptr, pinfo);
    \n-
    620 }
    \n-
    621
    \n-
    622 template <class Matrix,
    \n-
    623 class Vector>
    \n-\n-
    625 {
    \n-\n-\n-
    628
    \n-
    629 static constexpr SolverType solver =
    \n-
    630#if DISABLE_AMG_DIRECTSOLVER
    \n-
    631 none;
    \n-
    632#elif HAVE_SUITESPARSE_UMFPACK
    \n-\n-
    634#elif HAVE_SUPERLU
    \n-
    635 superlu ;
    \n-
    636#else
    \n-
    637 none;
    \n-
    638#endif
    \n-
    639
    \n-
    640 template <class M, SolverType>
    \n-
    641 struct Solver
    \n-
    642 {
    \n-\n-
    644 static type* create(const M& mat, bool verbose, bool reusevector )
    \n-
    645 {
    \n-
    646 DUNE_THROW(NotImplemented,"DirectSolver not selected");
    \n-
    647 return nullptr;
    \n-
    648 }
    \n-
    649 static std::string name () { return "None"; }
    \n-
    650 };
    \n-
    651#if HAVE_SUITESPARSE_UMFPACK
    \n-
    652 template <class M>
    \n-
    653 struct Solver< M, umfpack >
    \n-
    654 {
    \n-
    655 typedef UMFPack< M > type;
    \n-
    656 static type* create(const M& mat, bool verbose, bool reusevector )
    \n-
    657 {
    \n-
    658 return new type(mat, verbose, reusevector );
    \n-
    659 }
    \n-
    660 static std::string name () { return "UMFPack"; }
    \n-
    661 };
    \n-
    662#endif
    \n-
    663#if HAVE_SUPERLU
    \n-
    664 template <class M>
    \n-
    665 struct Solver< M, superlu >
    \n-
    666 {
    \n-\n-
    668 static type* create(const M& mat, bool verbose, bool reusevector )
    \n-
    669 {
    \n-
    670 return new type(mat, verbose, reusevector );
    \n-
    671 }
    \n-
    672 static std::string name () { return "SuperLU"; }
    \n-
    673 };
    \n-
    674#endif
    \n-
    675
    \n-
    676 // define direct solver type to be used
    \n-\n-\n-
    679 static constexpr bool isDirectSolver = solver != none;
    \n-
    680 static std::string name() { return SelectedSolver :: name (); }
    \n-
    681 static DirectSolver* create(const Matrix& mat, bool verbose, bool reusevector )
    \n-
    682 {
    \n-
    683 return SelectedSolver :: create( mat, verbose, reusevector );
    \n-
    684 }
    \n-
    685 };
    \n-
    686
    \n-
    687 template<class M, class X, class S, class PI, class A>
    \n-
    688 template<class C>
    \n-
    689 void AMG<M,X,S,PI,A>::createHierarchies(C& criterion,
    \n-
    690 const std::shared_ptr<const Operator>& matrixptr,
    \n-
    691 const PI& pinfo)
    \n-
    692 {
    \n-
    693 Timer watch;
    \n-
    694 matrices_ = std::make_shared<OperatorHierarchy>(
    \n-
    695 std::const_pointer_cast<Operator>(matrixptr),
    \n-
    696 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
    \n-
    697
    \n-
    698 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
    \n-
    699
    \n-
    700 // build the necessary smoother hierarchies
    \n-
    701 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);
    \n-
    702
    \n-
    703 // test whether we should solve on the coarse level. That is the case if we
    \n-
    704 // have that level and if there was a redistribution on this level then our
    \n-
    705 // communicator has to be valid (size()>0) as the smoother might try to communicate
    \n-
    706 // in the constructor.
    \n-
    707 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()
    \n-
    708 && ( ! matrices_->redistributeInformation().back().isSetup() ||
    \n-
    709 matrices_->parallelInformation().coarsest().getRedistributed().communicator().size() ) )
    \n-
    710 {
    \n-
    711 // We have the carsest level. Create the coarse Solver
    \n-
    712 SmootherArgs sargs(smootherArgs_);
    \n-
    713 sargs.iterations = 1;
    \n-
    714
    \n-\n-
    716 cargs.setArgs(sargs);
    \n-
    717 if(matrices_->redistributeInformation().back().isSetup()) {
    \n-
    718 // Solve on the redistributed partitioning
    \n-
    719 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
    \n-
    720 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
    \n-
    721 }else{
    \n-
    722 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
    \n-
    723 cargs.setComm(*matrices_->parallelInformation().coarsest());
    \n-
    724 }
    \n-
    725
    \n-
    726 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
    \n-
    727 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
    \n-
    728
    \n-
    729 typedef DirectSolverSelector< typename M::matrix_type, X > SolverSelector;
    \n-
    730
    \n-
    731 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
    \n-
    732 if( SolverSelector::isDirectSolver &&
    \n-
    733 (std::is_same<ParallelInformation,SequentialInformation>::value // sequential mode
    \n-
    734 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
    \n-
    735 || (matrices_->parallelInformation().coarsest().isRedistributed()
    \n-
    736 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
    \n-
    737 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0) )
    \n-
    738 )
    \n-
    739 { // redistribute and 1 proc
    \n-
    740 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n-
    741 {
    \n-
    742 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n-
    743 {
    \n-
    744 // We are still participating on this level
    \n-
    745 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
    \n-
    746 }
    \n-
    747 else
    \n-
    748 solver_.reset();
    \n-
    749 }
    \n-
    750 else
    \n-
    751 {
    \n-
    752 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest()->getmat(), false, false));
    \n-
    753 }
    \n-
    754 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
    \n-
    755 std::cout<< "Using a direct coarse solver (" << SolverSelector::name() << ")" << std::endl;
    \n-
    756 }
    \n-
    757 else
    \n-
    758 {
    \n-
    759 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n-
    760 {
    \n-
    761 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n-
    762 // We are still participating on this level
    \n-
    763
    \n-
    764 // we have to allocate these types using the rebound allocator
    \n-
    765 // in order to ensure that we fulfill the alignment requirements
    \n-
    766 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
    \n-
    767 *scalarProduct_,
    \n-
    768 *coarseSmoother_, 1E-2, 1000, 0));
    \n-
    769 else
    \n-
    770 solver_.reset();
    \n-
    771 }else
    \n-
    772 {
    \n-
    773 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
    \n-
    774 *scalarProduct_,
    \n-
    775 *coarseSmoother_, 1E-2, 1000, 0));
    \n-
    776 // // we have to allocate these types using the rebound allocator
    \n-
    777 // // in order to ensure that we fulfill the alignment requirements
    \n-
    778 // using Alloc = typename std::allocator_traits<A>::template rebind_alloc<BiCGSTABSolver<X>>;
    \n-
    779 // Alloc alloc;
    \n-
    780 // auto p = alloc.allocate(1);
    \n-
    781 // std::allocator_traits<Alloc>::construct(alloc, p,
    \n-
    782 // const_cast<M&>(*matrices_->matrices().coarsest()),
    \n-
    783 // *scalarProduct_,
    \n-
    784 // *coarseSmoother_, 1E-2, 1000, 0);
    \n-
    785 // solver_.reset(p,[](BiCGSTABSolver<X>* p){
    \n-
    786 // Alloc alloc;
    \n-
    787 // std::allocator_traits<Alloc>::destroy(alloc, p);
    \n-
    788 // alloc.deallocate(p,1);
    \n-
    789 // });
    \n-
    790 }
    \n-
    791 }
    \n-
    792 }
    \n-
    793
    \n-
    794 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n-
    795 std::cout<<"Building hierarchy of "<<matrices_->maxlevels()<<" levels "
    \n-
    796 <<"(including coarse solver) took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    797 }
    \n-
    798
    \n-
    799
    \n-
    800 template<class M, class X, class S, class PI, class A>
    \n-\n-
    802 {
    \n-
    803 // Detect Matrix rows where all offdiagonal entries are
    \n-
    804 // zero and set x such that A_dd*x_d=b_d
    \n-
    805 // Thus users can be more careless when setting up their linear
    \n-
    806 // systems.
    \n-
    807 typedef typename M::matrix_type Matrix;
    \n-
    808 typedef typename Matrix::ConstRowIterator RowIter;
    \n-
    809 typedef typename Matrix::ConstColIterator ColIter;
    \n-
    810 typedef typename Matrix::block_type Block;
    \n-
    811 Block zero;
    \n-
    812 zero=typename Matrix::field_type();
    \n-
    813
    \n-
    814 const Matrix& mat=matrices_->matrices().finest()->getmat();
    \n-
    815 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {
    \n-
    816 bool isDirichlet = true;
    \n-
    817 bool hasDiagonal = false;
    \n-
    818 Block diagonal{};
    \n-
    819 for(ColIter col=row->begin(); col!=row->end(); ++col) {
    \n-
    820 if(row.index()==col.index()) {
    \n-
    821 diagonal = *col;
    \n-
    822 hasDiagonal = true;
    \n-
    823 }else{
    \n-
    824 if(*col!=zero)
    \n-
    825 isDirichlet = false;
    \n-
    826 }
    \n-
    827 }
    \n-
    828 if(isDirichlet && hasDiagonal)
    \n-
    829 {
    \n-
    830 auto&& xEntry = Impl::asVector(x[row.index()]);
    \n-
    831 auto&& bEntry = Impl::asVector(b[row.index()]);
    \n-
    832 Impl::asMatrix(diagonal).solve(xEntry, bEntry);
    \n-
    833 }
    \n-
    834 }
    \n-
    835
    \n-
    836 if(smoothers_->levels()>0)
    \n-
    837 smoothers_->finest()->pre(x,b);
    \n-
    838 else
    \n-
    839 // No smoother to make x consistent! Do it by hand
    \n-
    840 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
    \n-
    841 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
    \n-
    842 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n-
    843 update_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n-
    844 matrices_->coarsenVector(*rhs_);
    \n-
    845 matrices_->coarsenVector(*lhs_);
    \n-
    846 matrices_->coarsenVector(*update_);
    \n-
    847
    \n-
    848 // Preprocess all smoothers
    \n-
    849 typedef typename Hierarchy<Smoother,A>::Iterator Iterator;
    \n-
    850 typedef typename Hierarchy<Range,A>::Iterator RIterator;
    \n-
    851 typedef typename Hierarchy<Domain,A>::Iterator DIterator;
    \n-
    852 Iterator coarsest = smoothers_->coarsest();
    \n-
    853 Iterator smoother = smoothers_->finest();
    \n-
    854 RIterator rhs = rhs_->finest();
    \n-
    855 DIterator lhs = lhs_->finest();
    \n-
    856 if(smoothers_->levels()>1) {
    \n-
    857
    \n-
    858 assert(lhs_->levels()==rhs_->levels());
    \n-
    859 assert(smoothers_->levels()==lhs_->levels() || matrices_->levels()==matrices_->maxlevels());
    \n-
    860 assert(smoothers_->levels()+1==lhs_->levels() || matrices_->levels()<matrices_->maxlevels());
    \n-
    861
    \n-
    862 if(smoother!=coarsest)
    \n-
    863 for(++smoother, ++lhs, ++rhs; smoother != coarsest; ++smoother, ++lhs, ++rhs)
    \n-
    864 smoother->pre(*lhs,*rhs);
    \n-
    865 smoother->pre(*lhs,*rhs);
    \n-
    866 }
    \n-
    867
    \n-
    868
    \n-
    869 // The preconditioner might change x and b. So we have to
    \n-
    870 // copy the changes to the original vectors.
    \n-
    871 x = *lhs_->finest();
    \n-
    872 b = *rhs_->finest();
    \n-
    873
    \n-
    874 }
    \n-
    875 template<class M, class X, class S, class PI, class A>
    \n-\n-
    877 {
    \n-
    878 return matrices_->levels();
    \n-
    879 }
    \n-
    880 template<class M, class X, class S, class PI, class A>
    \n-\n-
    882 {
    \n-
    883 return matrices_->maxlevels();
    \n-
    884 }
    \n-
    885
    \n-
    887 template<class M, class X, class S, class PI, class A>
    \n-\n-
    889 {
    \n-
    890 LevelContext levelContext;
    \n-
    891
    \n-
    892 if(additive) {
    \n-
    893 *(rhs_->finest())=d;
    \n-
    894 additiveMgc();
    \n-
    895 v=*lhs_->finest();
    \n-
    896 }else{
    \n-
    897 // Init all iterators for the current level
    \n-
    898 initIteratorsWithFineLevel(levelContext);
    \n-
    899
    \n-
    900
    \n-
    901 *levelContext.lhs = v;
    \n-
    902 *levelContext.rhs = d;
    \n-
    903 *levelContext.update=0;
    \n-
    904 levelContext.level=0;
    \n-
    905
    \n-
    906 mgc(levelContext);
    \n-
    907
    \n-
    908 if(postSteps_==0||matrices_->maxlevels()==1)
    \n-
    909 levelContext.pinfo->copyOwnerToAll(*levelContext.update, *levelContext.update);
    \n-
    910
    \n-
    911 v=*levelContext.update;
    \n-
    912 }
    \n-
    913
    \n-
    914 }
    \n-
    915
    \n-
    916 template<class M, class X, class S, class PI, class A>
    \n-
    917 void AMG<M,X,S,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
    \n-
    918 {
    \n-
    919 levelContext.smoother = smoothers_->finest();
    \n-
    920 levelContext.matrix = matrices_->matrices().finest();
    \n-
    921 levelContext.pinfo = matrices_->parallelInformation().finest();
    \n-
    922 levelContext.redist =
    \n-
    923 matrices_->redistributeInformation().begin();
    \n-
    924 levelContext.aggregates = matrices_->aggregatesMaps().begin();
    \n-
    925 levelContext.lhs = lhs_->finest();
    \n-
    926 levelContext.update = update_->finest();
    \n-
    927 levelContext.rhs = rhs_->finest();
    \n-
    928 }
    \n-
    929
    \n-
    930 template<class M, class X, class S, class PI, class A>
    \n-
    931 bool AMG<M,X,S,PI,A>
    \n-
    932 ::moveToCoarseLevel(LevelContext& levelContext)
    \n-
    933 {
    \n-
    934
    \n-
    935 bool processNextLevel=true;
    \n-
    936
    \n-
    937 if(levelContext.redist->isSetup()) {
    \n-
    938 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.rhs),
    \n-
    939 levelContext.rhs.getRedistributed());
    \n-
    940 processNextLevel = levelContext.rhs.getRedistributed().size()>0;
    \n-
    941 if(processNextLevel) {
    \n-
    942 //restrict defect to coarse level right hand side.
    \n-
    943 typename Hierarchy<Range,A>::Iterator fineRhs = levelContext.rhs++;
    \n-
    944 ++levelContext.pinfo;
    \n-\n-
    946 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n-
    947 static_cast<const Range&>(fineRhs.getRedistributed()),
    \n-
    948 *levelContext.pinfo);
    \n-
    949 }
    \n-
    950 }else{
    \n-
    951 //restrict defect to coarse level right hand side.
    \n-
    952 typename Hierarchy<Range,A>::Iterator fineRhs = levelContext.rhs++;
    \n-
    953 ++levelContext.pinfo;
    \n-\n-
    955 ::restrictVector(*(*levelContext.aggregates),
    \n-
    956 *levelContext.rhs, static_cast<const Range&>(*fineRhs),
    \n-
    957 *levelContext.pinfo);
    \n-
    958 }
    \n-
    959
    \n-
    960 if(processNextLevel) {
    \n-
    961 // prepare coarse system
    \n-
    962 ++levelContext.lhs;
    \n-
    963 ++levelContext.update;
    \n-
    964 ++levelContext.matrix;
    \n-
    965 ++levelContext.level;
    \n-
    966 ++levelContext.redist;
    \n-
    967
    \n-
    968 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n-
    969 // next level is not the globally coarsest one
    \n-
    970 ++levelContext.smoother;
    \n-
    971 ++levelContext.aggregates;
    \n-
    972 }
    \n-
    973 // prepare the update on the next level
    \n-
    974 *levelContext.update=0;
    \n-
    975 }
    \n-
    976 return processNextLevel;
    \n-
    977 }
    \n-
    978
    \n-
    979 template<class M, class X, class S, class PI, class A>
    \n-
    980 void AMG<M,X,S,PI,A>
    \n-
    981 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel)
    \n-
    982 {
    \n-
    983 if(processNextLevel) {
    \n-
    984 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n-
    985 // previous level is not the globally coarsest one
    \n-
    986 --levelContext.smoother;
    \n-
    987 --levelContext.aggregates;
    \n-
    988 }
    \n-
    989 --levelContext.redist;
    \n-
    990 --levelContext.level;
    \n-
    991 //prolongate and add the correction (update is in coarse left hand side)
    \n-
    992 --levelContext.matrix;
    \n-
    993
    \n-
    994 //typename Hierarchy<Domain,A>::Iterator coarseLhs = lhs--;
    \n-
    995 --levelContext.lhs;
    \n-
    996 --levelContext.pinfo;
    \n-
    997 }
    \n-
    998 if(levelContext.redist->isSetup()) {
    \n-
    999 // Need to redistribute during prolongateVector
    \n-
    1000 levelContext.lhs.getRedistributed()=0;
    \n-\n-
    1002 ::prolongateVector(*(*levelContext.aggregates), *levelContext.update, *levelContext.lhs,
    \n-
    1003 levelContext.lhs.getRedistributed(),
    \n-
    1004 matrices_->getProlongationDampingFactor(),
    \n-
    1005 *levelContext.pinfo, *levelContext.redist);
    \n-
    1006 }else{
    \n-
    1007 *levelContext.lhs=0;
    \n-\n-
    1009 ::prolongateVector(*(*levelContext.aggregates), *levelContext.update, *levelContext.lhs,
    \n-
    1010 matrices_->getProlongationDampingFactor(),
    \n-
    1011 *levelContext.pinfo);
    \n-
    1012 }
    \n-
    1013
    \n-
    1014
    \n-
    1015 if(processNextLevel) {
    \n-
    1016 --levelContext.update;
    \n-
    1017 --levelContext.rhs;
    \n-
    1018 }
    \n-
    1019
    \n-
    1020 *levelContext.update += *levelContext.lhs;
    \n-
    1021 }
    \n-
    1022
    \n-
    1023 template<class M, class X, class S, class PI, class A>
    \n-\n-
    1025 {
    \n-\n-
    1027 }
    \n-
    1028
    \n-
    1029 template<class M, class X, class S, class PI, class A>
    \n-
    1030 void AMG<M,X,S,PI,A>::mgc(LevelContext& levelContext){
    \n-
    1031 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
    \n-
    1032 // Solve directly
    \n-\n-
    1034 res.converged=true; // If we do not compute this flag will not get updated
    \n-
    1035 if(levelContext.redist->isSetup()) {
    \n-
    1036 levelContext.redist->redistribute(*levelContext.rhs, levelContext.rhs.getRedistributed());
    \n-
    1037 if(levelContext.rhs.getRedistributed().size()>0) {
    \n-
    1038 // We are still participating in the computation
    \n-
    1039 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
    \n-
    1040 levelContext.rhs.getRedistributed());
    \n-
    1041 solver_->apply(levelContext.update.getRedistributed(),
    \n-
    1042 levelContext.rhs.getRedistributed(), res);
    \n-
    1043 }
    \n-
    1044 levelContext.redist->redistributeBackward(*levelContext.update, levelContext.update.getRedistributed());
    \n-
    1045 levelContext.pinfo->copyOwnerToAll(*levelContext.update, *levelContext.update);
    \n-
    1046 }else{
    \n-
    1047 levelContext.pinfo->copyOwnerToAll(*levelContext.rhs, *levelContext.rhs);
    \n-
    1048 solver_->apply(*levelContext.update, *levelContext.rhs, res);
    \n-
    1049 }
    \n-
    1050
    \n-
    1051 if (!res.converged)
    \n-
    1052 coarsesolverconverged = false;
    \n-
    1053 }else{
    \n-
    1054 // presmoothing
    \n-
    1055 presmooth(levelContext, preSteps_);
    \n-
    1056
    \n-
    1057#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n-
    1058 bool processNextLevel = moveToCoarseLevel(levelContext);
    \n-
    1059
    \n-
    1060 if(processNextLevel) {
    \n-
    1061 // next level
    \n-
    1062 for(std::size_t i=0; i<gamma_; i++){
    \n-
    1063 mgc(levelContext);
    \n-
    1064 if (levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels())
    \n-
    1065 break;
    \n-
    1066 if(i+1 < gamma_){
    \n-
    1067 levelContext.matrix->applyscaleadd(-1., *levelContext.lhs, *levelContext.rhs);
    \n-
    1068 }
    \n-
    1069 }
    \n-
    1070 }
    \n-
    1071
    \n-
    1072 moveToFineLevel(levelContext, processNextLevel);
    \n-
    1073#else
    \n-
    1074 *lhs=0;
    \n-
    1075#endif
    \n-
    1076
    \n-
    1077 if(levelContext.matrix == matrices_->matrices().finest()) {
    \n-
    1078 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
    \n-
    1079 if(!coarsesolverconverged)
    \n-
    1080 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n-
    1081 }
    \n-
    1082 // postsmoothing
    \n-
    1083 postsmooth(levelContext, postSteps_);
    \n-
    1084
    \n-
    1085 }
    \n-
    1086 }
    \n-
    1087
    \n-
    1088 template<class M, class X, class S, class PI, class A>
    \n-
    1089 void AMG<M,X,S,PI,A>::additiveMgc(){
    \n-
    1090
    \n-
    1091 // restrict residual to all levels
    \n-
    1092 typename ParallelInformationHierarchy::Iterator pinfo=matrices_->parallelInformation().finest();
    \n-
    1093 typename Hierarchy<Range,A>::Iterator rhs=rhs_->finest();
    \n-
    1094 typename Hierarchy<Domain,A>::Iterator lhs = lhs_->finest();
    \n-
    1095 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates=matrices_->aggregatesMaps().begin();
    \n-
    1096
    \n-
    1097 for(typename Hierarchy<Range,A>::Iterator fineRhs=rhs++; fineRhs != rhs_->coarsest(); fineRhs=rhs++, ++aggregates) {
    \n-
    1098 ++pinfo;
    \n-\n-
    1100 ::restrictVector(*(*aggregates), *rhs, static_cast<const Range&>(*fineRhs), *pinfo);
    \n-
    1101 }
    \n-
    1102
    \n-
    1103 // pinfo is invalid, set to coarsest level
    \n-
    1104 //pinfo = matrices_->parallelInformation().coarsest
    \n-
    1105 // calculate correction for all levels
    \n-
    1106 lhs = lhs_->finest();
    \n-
    1107 typename Hierarchy<Smoother,A>::Iterator smoother = smoothers_->finest();
    \n-
    1108
    \n-
    1109 for(rhs=rhs_->finest(); rhs != rhs_->coarsest(); ++lhs, ++rhs, ++smoother) {
    \n-
    1110 // presmoothing
    \n-
    1111 *lhs=0;
    \n-
    1112 smoother->apply(*lhs, *rhs);
    \n-
    1113 }
    \n-
    1114
    \n-
    1115 // Coarse level solve
    \n-
    1116#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n-
    1117 InverseOperatorResult res;
    \n-
    1118 pinfo->copyOwnerToAll(*rhs, *rhs);
    \n-
    1119 solver_->apply(*lhs, *rhs, res);
    \n-
    1120
    \n-
    1121 if(!res.converged)
    \n-
    1122 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n-
    1123#else
    \n-
    1124 *lhs=0;
    \n-
    1125#endif
    \n-
    1126 // Prologate and add up corrections from all levels
    \n-
    1127 --pinfo;
    \n-
    1128 --aggregates;
    \n-
    1129
    \n-
    1130 for(typename Hierarchy<Domain,A>::Iterator coarseLhs = lhs--; coarseLhs != lhs_->finest(); coarseLhs = lhs--, --aggregates, --pinfo) {
    \n-\n-
    1132 ::prolongateVector(*(*aggregates), *coarseLhs, *lhs, 1.0, *pinfo);
    \n-
    1133 }
    \n-
    1134 }
    \n-
    1135
    \n-
    1136
    \n-
    1138 template<class M, class X, class S, class PI, class A>
    \n-
    1139 void AMG<M,X,S,PI,A>::post([[maybe_unused]] Domain& x)
    \n-
    1140 {
    \n-
    1141 // Postprocess all smoothers
    \n-
    1142 typedef typename Hierarchy<Smoother,A>::Iterator Iterator;
    \n-
    1143 typedef typename Hierarchy<Domain,A>::Iterator DIterator;
    \n-
    1144 Iterator coarsest = smoothers_->coarsest();
    \n-
    1145 Iterator smoother = smoothers_->finest();
    \n-
    1146 DIterator lhs = lhs_->finest();
    \n-
    1147 if(smoothers_->levels()>0) {
    \n-
    1148 if(smoother != coarsest || matrices_->levels()<matrices_->maxlevels())
    \n-
    1149 smoother->post(*lhs);
    \n-
    1150 if(smoother!=coarsest)
    \n-
    1151 for(++smoother, ++lhs; smoother != coarsest; ++smoother, ++lhs)
    \n-
    1152 smoother->post(*lhs);
    \n-
    1153 smoother->post(*lhs);
    \n-
    1154 }
    \n-
    1155 lhs_ = nullptr;
    \n-
    1156 update_ = nullptr;
    \n-
    1157 rhs_ = nullptr;
    \n-
    1158 }
    \n-
    1159
    \n-
    1160 template<class M, class X, class S, class PI, class A>
    \n-
    1161 template<class A1>
    \n-
    1162 void AMG<M,X,S,PI,A>::getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont)
    \n-
    1163 {
    \n-
    1164 matrices_->getCoarsestAggregatesOnFinest(cont);
    \n-
    1165 }
    \n-
    1166
    \n-
    1167 } // end namespace Amg
    \n-
    1168
    \n-\n-
    1170 template<class> struct isValidBlockType : std::false_type{};
    \n-
    1171 template<class T, int n, int m> struct isValidBlockType<FieldMatrix<T,n,m>> : std::true_type{};
    \n-
    1172
    \n-
    1173 template<class OP>
    \n-
    1174 std::shared_ptr<Dune::Preconditioner<typename OP::element_type::domain_type, typename OP::element_type::range_type> >
    \n-
    1175 makeAMG(const OP& op, const std::string& smoother, const Dune::ParameterTree& config) const
    \n-
    1176 {
    \n-
    1177 DUNE_THROW(Dune::Exception, "Operator type not supported by AMG");
    \n-
    1178 }
    \n-
    1179
    \n-
    1180 template<class M, class X, class Y>
    \n-
    1181 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n-
    1182 makeAMG(const std::shared_ptr<MatrixAdapter<M,X,Y>>& op, const std::string& smoother,
    \n-
    1183 const Dune::ParameterTree& config) const
    \n-
    1184 {
    \n-
    1185 using OP = MatrixAdapter<M,X,Y>;
    \n-
    1186
    \n-
    1187 if(smoother == "ssor")
    \n-
    1188 return std::make_shared<Amg::AMG<OP, X, SeqSSOR<M,X,Y>>>(op, config);
    \n-
    1189 if(smoother == "sor")
    \n-
    1190 return std::make_shared<Amg::AMG<OP, X, SeqSOR<M,X,Y>>>(op, config);
    \n-
    1191 if(smoother == "jac")
    \n-
    1192 return std::make_shared<Amg::AMG<OP, X, SeqJac<M,X,Y>>>(op, config);
    \n-
    1193 if(smoother == "gs")
    \n-
    1194 return std::make_shared<Amg::AMG<OP, X, SeqGS<M,X,Y>>>(op, config);
    \n-
    1195 if(smoother == "ilu")
    \n-
    1196 return std::make_shared<Amg::AMG<OP, X, SeqILU<M,X,Y>>>(op, config);
    \n-
    1197 else
    \n-
    1198 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n-
    1199 }
    \n-
    1200
    \n-
    1201 template<class M, class X, class Y, class C>
    \n-
    1202 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n-
    1203 makeAMG(const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C>>& op, const std::string& smoother,
    \n-
    1204 const Dune::ParameterTree& config) const
    \n-
    1205 {
    \n-\n-
    1207
    \n-
    1208 auto cop = std::static_pointer_cast<const OP>(op);
    \n-
    1209
    \n-
    1210 if(smoother == "ssor")
    \n-
    1211 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqSSOR<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n-
    1212 if(smoother == "sor")
    \n-
    1213 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqSOR<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n-
    1214 if(smoother == "jac")
    \n-
    1215 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqJac<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n-
    1216 if(smoother == "gs")
    \n-
    1217 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqGS<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n-
    1218 if(smoother == "ilu")
    \n-
    1219 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqILU<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n-
    1220 else
    \n-
    1221 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n-
    1222 }
    \n-
    1223
    \n-
    1224 template<class M, class X, class Y, class C>
    \n-
    1225 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n-
    1226 makeAMG(const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C>>& op, const std::string& smoother,
    \n-
    1227 const Dune::ParameterTree& config) const
    \n-
    1228 {
    \n-\n-
    1230
    \n-
    1231 if(smoother == "ssor")
    \n-
    1232 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqSSOR<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n-
    1233 if(smoother == "sor")
    \n-
    1234 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqSOR<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n-
    1235 if(smoother == "jac")
    \n-
    1236 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqJac<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n-
    1237 if(smoother == "gs")
    \n-
    1238 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqGS<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n-
    1239 if(smoother == "ilu")
    \n-
    1240 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqILU<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n-
    1241 else
    \n-
    1242 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n-
    1243 }
    \n-
    1244
    \n-
    1245 template<typename TL, typename OP>
    \n-
    1246 std::shared_ptr<Dune::Preconditioner<typename Dune::TypeListElement<1, TL>::type,
    \n-
    1247 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    1248 operator() (TL tl, const std::shared_ptr<OP>& op, const Dune::ParameterTree& config,
    \n-\n-
    1250 {
    \n-
    1251 using field_type = typename OP::matrix_type::field_type;
    \n-
    1252 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    1253 if (!std::is_convertible<field_type, real_type>())
    \n-
    1254 DUNE_THROW(UnsupportedType, "AMG needs field_type(" <<
    \n-
    1255 className<field_type>() <<
    \n-
    1256 ") to be convertible to its real_type (" <<
    \n-
    1257 className<real_type>() <<
    \n-
    1258 ").");
    \n-
    1259 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;
    \n-
    1260 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;
    \n-
    1261 std::shared_ptr<Preconditioner<D,R>> amg;
    \n-
    1262 std::string smoother = config.get("smoother", "ssor");
    \n-
    1263 return makeAMG(op, smoother, config);
    \n-
    1264 }
    \n-
    1265
    \n-
    1266 template<typename TL, typename OP>
    \n-
    1267 std::shared_ptr<Dune::Preconditioner<typename Dune::TypeListElement<1, TL>::type,
    \n-
    1268 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    1269 operator() (TL /*tl*/, const std::shared_ptr<OP>& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n-\n-
    1271 {
    \n-
    1272 DUNE_THROW(UnsupportedType, "AMG needs a FieldMatrix as Matrix block_type");
    \n-
    1273 }
    \n-
    1274 };
    \n-
    1275
    \n-\n-
    1277} // end namespace Dune
    \n-
    1278
    \n-
    1279#endif
    \n-
    Templates characterizing the type of a solver.
    \n-
    Implementations of the inverse operator interface.
    \n-
    Prolongation and restriction for amg.
    \n-
    Classes for the generic construction and application of the smoothers.
    \n-
    Provides a classes representing the hierarchies in AMG.
    \n-
    Define base class for scalar product and norm.
    \n-
    Classes for using UMFPack with ISTL matrices.
    \n-
    Classes for using SuperLU with ISTL matrices.
    \n+
    199 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n+
    200 rowIdx!= rowEnd; ++rowIdx, ++iluRow) {
    \n+
    201 // See which row entries are in our subset and add them to
    \n+
    202 // the sparsity pattern
    \n+
    203 typename matrix_type::ColIterator localCol=iluRow->begin();
    \n+
    204 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),
    \n+
    205 endcol=A[*rowIdx].end(); col != endcol; ++col) {
    \n+
    206 // search for the entry in the row set
    \n+
    207 guess = indexMap.find(col.index());
    \n+
    208 if(guess!=indexMap.end()) {
    \n+
    209 // set local value
    \n+
    210 (*localCol)=(*col);
    \n+
    211 ++localCol;
    \n+
    212 }
    \n+
    213 }
    \n+
    214 }
    \n+
    215 return offset;
    \n+
    216 }
    \n+
    217
    \n+
    218
    \n+
    219 template<class M, class X, class Y>
    \n+
    220 template<class S>
    \n+\n+
    222 {
    \n+
    223 this->copyToLocalMatrix(A,rowSet);
    \n+\n+
    225 }
    \n+
    226
    \n+
    227 template<class M, class X, class Y>
    \n+
    228 template<class S>
    \n+\n+
    230 {
    \n+
    231 std::size_t offset=copyToLocalMatrix(A,rowSet);
    \n+
    232 RILU.setSize(rowSet.size(),rowSet.size(), (1+2*offset)*rowSet.size());
    \n+
    233 RILU.setBuildMode(matrix_type::row_wise);
    \n+
    234 ILU::blockILUDecomposition(this->ILU, (offset+1)/2, RILU);
    \n+
    235 }
    \n+
    236
    \n+
    238} // end name space DUNE
    \n+
    239
    \n+
    240
    \n+
    241#endif
    \n+
    A dynamic dense block matrix class.
    \n+
    Define general preconditioner interface.
    \n+
    std::size_t copyToLocalMatrix(const M &A, S &rowset)
    Copy the local part of the global matrix to ILU.
    Definition: ilusubdomainsolver.hh:151
    \n+
    void setSubMatrix(const M &A, S &rowset)
    Set the data of the local problem.
    Definition: ilusubdomainsolver.hh:229
    \n+
    void setSubMatrix(const M &A, S &rowset)
    Set the data of the local problem.
    Definition: ilusubdomainsolver.hh:221
    \n
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    AMG(const AMG &amg)
    Copy constructor.
    Definition: amg.hh:392
    \n-
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: amg.hh:801
    \n-
    static DirectSolver * create(const Matrix &mat, bool verbose, bool reusevector)
    Definition: amg.hh:681
    \n-
    static std::string name()
    Definition: amg.hh:680
    \n-
    Hierarchy< Domain, A >::Iterator update
    The iterator over the updates.
    Definition: amg.hh:303
    \n-
    Hierarchy< Range, A >::Iterator rhs
    The iterator over the right hand sided.
    Definition: amg.hh:307
    \n-
    static std::string name()
    Definition: amg.hh:672
    \n-
    bool usesDirectCoarseLevelSolver() const
    Check whether the coarse solver used is a direct solver.
    Definition: amg.hh:1024
    \n-
    X Domain
    The domain type.
    Definition: amg.hh:87
    \n-
    static type * create(const M &mat, bool verbose, bool reusevector)
    Definition: amg.hh:644
    \n-
    AMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms)
    Construct a new amg with a specific coarse solver.
    Definition: amg.hh:406
    \n-
    AMG(std::shared_ptr< const Operator > fineOperator, const ParameterTree &configuration, const ParallelInformation &pinfo=ParallelInformation())
    Constructor an AMG via ParameterTree.
    Definition: amg.hh:452
    \n-
    ParallelInformationHierarchy::Iterator pinfo
    The iterator over the parallel information.
    Definition: amg.hh:287
    \n-
    SolverType
    Definition: amg.hh:627
    \n-
    OperatorHierarchy::AggregatesMapList::const_iterator aggregates
    The iterator over the aggregates maps.
    Definition: amg.hh:295
    \n-
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n-
    Solver< Matrix, solver > SelectedSolver
    Definition: amg.hh:677
    \n-
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< MatrixAdapter< M, X, Y > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1182
    \n-
    std::string operator()(const std::string &str)
    Definition: amg.hh:378
    \n-
    std::shared_ptr< Dune::Preconditioner< typename OP::element_type::domain_type, typename OP::element_type::range_type > > makeAMG(const OP &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1175
    \n-
    S Smoother
    The type of the smoother.
    Definition: amg.hh:97
    \n-
    static std::string name()
    Definition: amg.hh:649
    \n-
    Hierarchy< Smoother, A >::Iterator smoother
    The iterator over the smoothers.
    Definition: amg.hh:279
    \n-
    M Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n-
    OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
    The iterator over the matrices.
    Definition: amg.hh:283
    \n-\n-
    static type * create(const M &mat, bool verbose, bool reusevector)
    Definition: amg.hh:668
    \n-
    OperatorHierarchy::RedistributeInfoList::const_iterator redist
    The iterator over the redistribution information.
    Definition: amg.hh:291
    \n-
    X Range
    The range type.
    Definition: amg.hh:89
    \n-
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n-
    void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
    Get the aggregate number of each unknown on the coarsest level.
    Definition: amg.hh:1162
    \n-
    std::size_t levels()
    Definition: amg.hh:876
    \n-
    InverseOperator< Vector, Vector > type
    Definition: amg.hh:643
    \n-
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1203
    \n-
    Hierarchy< Domain, A >::Iterator lhs
    The iterator over the left hand side.
    Definition: amg.hh:299
    \n-
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n-
    static constexpr SolverType solver
    Definition: amg.hh:629
    \n-
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n-
    static constexpr bool isDirectSolver
    Definition: amg.hh:679
    \n-
    void recalculateHierarchy()
    Recalculate the matrix hierarchy.
    Definition: amg.hh:221
    \n-
    Iterator coarsest()
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:383
    \n-
    Matrix::field_type field_type
    Definition: amg.hh:626
    \n-
    SelectedSolver::type DirectSolver
    Definition: amg.hh:678
    \n-
    std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL tl, const std::shared_ptr< OP > &op, const Dune::ParameterTree &config, std::enable_if_t< isValidBlockType< typename OP::matrix_type::block_type >::value, int >=0) const
    Definition: amg.hh:1248
    \n-
    OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
    The parallal data distribution hierarchy type.
    Definition: amg.hh:84
    \n-
    InverseOperator< X, X > CoarseSolver
    the type of the coarse solver.
    Definition: amg.hh:91
    \n-
    void post(Domain &x)
    Clean up.
    Definition: amg.hh:1139
    \n-
    std::size_t maxlevels()
    Definition: amg.hh:881
    \n-
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1226
    \n-
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n-
    std::size_t level
    The level index.
    Definition: amg.hh:311
    \n-
    AMG(const Operator &fineOperator, const C &criterion, const SmootherArgs &smootherArgs=SmootherArgs(), const ParallelInformation &pinfo=ParallelInformation())
    Construct an AMG with an inexact coarse solver based on the smoother.
    Definition: amg.hh:428
    \n-
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: amg.hh:888
    \n-
    Smoother SmootherType
    Definition: amg.hh:275
    \n-
    MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
    The operator hierarchy type.
    Definition: amg.hh:82
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: amg.hh:194
    \n-
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: amg.hh:80
    \n-
    @ none
    Definition: amg.hh:627
    \n-
    @ umfpack
    Definition: amg.hh:627
    \n-
    @ superlu
    Definition: amg.hh:627
    \n-
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n-
    @ noAccu
    No data accumulution.
    Definition: parameters.hh:238
    \n-
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n
    Definition: allocator.hh:11
    \n-
    DUNE_REGISTER_PRECONDITIONER("amg", AMGCreator())
    \n-
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n-
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n-
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n-
    Definition: matrixutils.hh:27
    \n-
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n-
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n-\n-
    Functor using the row sum (infinity) norm to determine strong couplings.
    Definition: aggregates.hh:463
    \n-
    Definition: aggregates.hh:480
    \n-
    Definition: aggregates.hh:496
    \n-
    Criterion taking advantage of symmetric matrices.
    Definition: aggregates.hh:519
    \n-
    Criterion suitable for unsymmetric matrices.
    Definition: aggregates.hh:539
    \n-
    an algebraic multigrid method using a Krylov-cycle.
    Definition: kamg.hh:140
    \n-
    Two grid operator for AMG with Krylov cycle.
    Definition: kamg.hh:33
    \n-
    Parallel algebraic multigrid based on agglomeration.
    Definition: amg.hh:65
    \n-
    Definition: amg.hh:625
    \n-\n-
    Definition: amg.hh:1169
    \n-
    Definition: amg.hh:1170
    \n-
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n-\n-
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n-
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n-
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n-
    The criterion describing the stop criteria for the coarsening process.
    Definition: matrixhierarchy.hh:283
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n-
    Definition: pinfo.hh:28
    \n-
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n-
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n-
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n-\n-
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n-
    Definition: solvercategory.hh:54
    \n-
    Definition: solverregistry.hh:77
    \n-
    Definition: solvertype.hh:16
    \n-
    SuperLu Solver.
    Definition: superlu.hh:271
    \n-
    Definition: umfpack.hh:49
    \n-
    The UMFPack direct sparse solver.
    Definition: umfpack.hh:215
    \n+
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n+
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n+
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n+
    base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver.
    Definition: ilusubdomainsolver.hh:36
    \n+
    matrix_type ILU
    The ILU0 decomposition of the matrix, or the local matrix.
    Definition: ilusubdomainsolver.hh:67
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:41
    \n+
    virtual ~ILUSubdomainSolver()
    Definition: ilusubdomainsolver.hh:53
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:43
    \n+
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:39
    \n+
    virtual void apply(X &v, const Y &d)=0
    Apply the subdomain solver.
    \n+
    Exact subdomain solver using ILU(p) with appropriate p.
    Definition: ilusubdomainsolver.hh:78
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:84
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:86
    \n+
    std::remove_const< M >::type rilu_type
    Definition: ilusubdomainsolver.hh:82
    \n+
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:81
    \n+
    void apply(X &v, const Y &d)
    Apply the subdomain solver.
    Definition: ilusubdomainsolver.hh:93
    \n+
    Definition: ilusubdomainsolver.hh:111
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:117
    \n+
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:114
    \n+
    std::remove_const< M >::type rilu_type
    Definition: ilusubdomainsolver.hh:115
    \n+
    void apply(X &v, const Y &d)
    Apply the subdomain solver.
    Definition: ilusubdomainsolver.hh:125
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:119
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1609 +4,286 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-amg.hh\n+ilusubdomainsolver.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_AMG_HH\n- 6#define DUNE_AMG_AMG_HH\n+ 5#ifndef DUNE_ISTL_ILUSUBDOMAINSOLVER_HH\n+ 6#define DUNE_ISTL_ILUSUBDOMAINSOLVER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23#include \n- 24\n- 25namespace Dune\n- 26{\n- 27 namespace Amg\n- 28 {\n- 46 template\n- 47 class KAMG;\n- 48\n- 49 template\n- 50 class KAmgTwoGrid;\n- 51\n- 62 template >\n-64 class AMG : public Preconditioner\n- 65 {\n- 66 template\n-67 friend class KAMG;\n- 68\n- 69 friend class KAmgTwoGrid;\n- 70\n- 71 public:\n-73 typedef M Operator;\n-80 typedef PI ParallelInformation;\n-82 typedef MatrixHierarchy OperatorHierarchy;\n-84 typedef typename OperatorHierarchy::ParallelInformationHierarchy\n-ParallelInformationHierarchy;\n- 85\n-87 typedef X Domain;\n-89 typedef X Range;\n-91 typedef InverseOperator CoarseSolver;\n-97 typedef S Smoother;\n- 98\n-100 typedef typename SmootherTraits::Arguments SmootherArgs;\n- 101\n-111 AMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n- 112 const SmootherArgs& smootherArgs, const Parameters& parms);\n- 113\n- 125 template\n-126 AMG(const Operator& fineOperator, const C& criterion,\n- 127 const SmootherArgs& smootherArgs=SmootherArgs(),\n- 128 const ParallelInformation& pinfo=ParallelInformation());\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \"matrix.hh\"\n+ 12#include \n+ 13#include \n+ 14\n+ 15namespace Dune {\n+ 16\n+ 35 template\n+36 class ILUSubdomainSolver {\n+ 37 public:\n+39 typedef typename std::remove_const::type matrix_type;\n+41 typedef X domain_type;\n+43 typedef Y range_type;\n+ 44\n+51 virtual void apply (X& v, const Y& d) =0;\n+ 52\n+53 virtual ~ILUSubdomainSolver()\n+ 54 {}\n+ 55\n+ 56 protected:\n+ 62 template\n+ 63 std::size_t copyToLocalMatrix(const M& A, S& rowset);\n+ 64\n+ 66 // for ILUN\n+67 matrix_type ILU;\n+ 68 };\n+ 69\n+ 76 template\n+77 class ILU0SubdomainSolver\n+ 78 : public ILUSubdomainSolver{\n+ 79 public:\n+81 typedef typename std::remove_const::type matrix_type;\n+82 typedef typename std::remove_const::type rilu_type;\n+84 typedef X domain_type;\n+86 typedef Y range_type;\n+ 87\n+ 88\n+93 void apply (X& v, const Y& d)\n+ 94 {\n+ 95 ILU::blockILUBacksolve(this->ILU,v,d);\n+ 96 }\n+ 104 template\n+ 105 void setSubMatrix(const M& A, S& rowset);\n+ 106\n+ 107 };\n+ 108\n+ 109 template\n+110 class ILUNSubdomainSolver\n+ 111 : public ILUSubdomainSolver{\n+ 112 public:\n+114 typedef typename std::remove_const::type matrix_type;\n+115 typedef typename std::remove_const::type rilu_type;\n+117 typedef X domain_type;\n+119 typedef Y range_type;\n+ 120\n+125 void apply (X& v, const Y& d)\n+ 126 {\n+ 127 ILU::blockILUBacksolve(RILU,v,d);\n+ 128 }\n 129\n-180 AMG(std::shared_ptr fineOperator, const ParameterTree&\n-configuration, const ParallelInformation& pinfo=ParallelInformation());\n- 181\n-185 AMG(const AMG& amg);\n- 186\n-188 void pre(Domain& x, Range& b);\n- 189\n-191 void apply(Domain& v, const Range& d);\n- 192\n-194 virtual SolverCategory::Category category() const\n- 195 {\n- 196 return category_;\n- 197 }\n+ 137 template\n+ 138 void setSubMatrix(const M& A, S& rowset);\n+ 139\n+ 140 private:\n+ 144 rilu_type RILU;\n+ 145 };\n+ 146\n+ 147\n+ 148\n+ 149 template\n+ 150 template\n+151 std::size_t ILUSubdomainSolver::copyToLocalMatrix(const M& A, S&\n+rowSet)\n+ 152 {\n+ 153 // Calculate consecutive indices for local problem\n+ 154 // while perserving the ordering\n+ 155 typedef typename M::size_type size_type;\n+ 156 typedef std::map IndexMap;\n+ 157 typedef typename IndexMap::iterator IMIter;\n+ 158 IndexMap indexMap;\n+ 159 IMIter guess = indexMap.begin();\n+ 160 size_type localIndex=0;\n+ 161\n+ 162 typedef typename S::const_iterator SIter;\n+ 163 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n+ 164 rowIdx!= rowEnd; ++rowIdx, ++localIndex)\n+ 165 guess = indexMap.insert(guess,\n+ 166 std::make_pair(*rowIdx,localIndex));\n+ 167\n+ 168\n+ 169 // Build Matrix for local subproblem\n+ 170 ILU.setSize(rowSet.size(),rowSet.size());\n+ 171 ILU.setBuildMode(matrix_type::row_wise);\n+ 172\n+ 173 // Create sparsity pattern\n+ 174 typedef typename matrix_type::CreateIterator CIter;\n+ 175 CIter rowCreator = ILU.createbegin();\n+ 176 std::size_t offset=0;\n+ 177 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n+ 178 rowIdx!= rowEnd; ++rowIdx, ++rowCreator) {\n+ 179 // See which row entries are in our subset and add them to\n+ 180 // the sparsity pattern\n+ 181 guess = indexMap.begin();\n+ 182\n+ 183 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),\n+ 184 endcol=A[*rowIdx].end(); col != endcol; ++col) {\n+ 185 // search for the entry in the row set\n+ 186 guess = indexMap.find(col.index());\n+ 187 if(guess!=indexMap.end()) {\n+ 188 // add local index to row\n+ 189 rowCreator.insert(guess->second);\n+ 190 offset=std::max(offset,(std::size_t)std::abs((int)(guess->second-\n+rowCreator.index())));\n+ 191 }\n+ 192 }\n+ 193\n+ 194 }\n+ 195\n+ 196 // Insert the matrix values for the local problem\n+ 197 typename matrix_type::iterator iluRow=ILU.begin();\n 198\n-200 void post(Domain& x);\n- 201\n- 206 template\n-207 void getCoarsestAggregateNumbers(std::vector& cont);\n- 208\n-209 std::size_t levels();\n- 210\n-211 std::size_t maxlevels();\n- 212\n-221 void recalculateHierarchy()\n+ 199 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n+ 200 rowIdx!= rowEnd; ++rowIdx, ++iluRow) {\n+ 201 // See which row entries are in our subset and add them to\n+ 202 // the sparsity pattern\n+ 203 typename matrix_type::ColIterator localCol=iluRow->begin();\n+ 204 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),\n+ 205 endcol=A[*rowIdx].end(); col != endcol; ++col) {\n+ 206 // search for the entry in the row set\n+ 207 guess = indexMap.find(col.index());\n+ 208 if(guess!=indexMap.end()) {\n+ 209 // set local value\n+ 210 (*localCol)=(*col);\n+ 211 ++localCol;\n+ 212 }\n+ 213 }\n+ 214 }\n+ 215 return offset;\n+ 216 }\n+ 217\n+ 218\n+ 219 template\n+ 220 template\n+221 void ILU0SubdomainSolver::setSubMatrix(const M& A, S& rowSet)\n 222 {\n- 223 matrices_->recalculateGalerkin(NegateSet());\n- 224 }\n- 225\n-230 bool usesDirectCoarseLevelSolver() const;\n- 231\n- 232 private:\n- 233 /*\n- 234 * @brief Helper function to create hierarchies with parameter tree.\n- 235 *\n- 236 * Will create the coarsen criterion with the norm and create the\n- 237 * Hierarchies\n- 238 * \\tparam Norm Type of the norm to use.\n- 239 */\n- 240 template\n- 241 void createCriterionAndHierarchies(std::shared_ptr\n-matrixptr,\n- 242 const PI& pinfo, const Norm&,\n- 243 const ParameterTree& configuration,\n- 244 std::true_type compiles = std::true_type());\n- 245 template\n- 246 void createCriterionAndHierarchies(std::shared_ptr\n-matrixptr,\n- 247 const PI& pinfo, const Norm&,\n- 248 const ParameterTree& configuration,\n- 249 std::false_type);\n- 254 template\n- 255 void createHierarchies(C& criterion, std::shared_ptr\n-matrixptr,\n- 256 const PI& pinfo, const ParameterTree& configuration);\n- 263 template\n- 264 void createHierarchies(C& criterion,\n- 265 const std::shared_ptr& matrixptr,\n- 266 const PI& pinfo);\n- 273 struct LevelContext\n- 274 {\n-275 typedef Smoother SmootherType;\n-279 typename Hierarchy::Iterator smoother;\n-283 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix;\n-287 typename ParallelInformationHierarchy::Iterator pinfo;\n-291 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;\n-295 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;\n-299 typename Hierarchy::Iterator lhs;\n-303 typename Hierarchy::Iterator update;\n-307 typename Hierarchy::Iterator rhs;\n-311 std::size_t level;\n- 312 };\n- 313\n- 314\n- 319 void mgc(LevelContext& levelContext);\n- 320\n- 321 void additiveMgc();\n- 322\n- 329 void moveToFineLevel(LevelContext& levelContext,bool processedFineLevel);\n- 330\n- 335 bool moveToCoarseLevel(LevelContext& levelContext);\n- 336\n- 341 void initIteratorsWithFineLevel(LevelContext& levelContext);\n- 342\n- 344 std::shared_ptr matrices_;\n- 346 SmootherArgs smootherArgs_;\n- 348 std::shared_ptr > smoothers_;\n- 350 std::shared_ptr solver_;\n- 352 std::shared_ptr> rhs_;\n- 354 std::shared_ptr> lhs_;\n- 356 std::shared_ptr> update_;\n- 358 using ScalarProduct = Dune::ScalarProduct;\n- 360 std::shared_ptr scalarProduct_;\n- 362 std::size_t gamma_;\n- 364 std::size_t preSteps_;\n- 366 std::size_t postSteps_;\n- 367 bool buildHierarchy_;\n- 368 bool additive;\n- 369 bool coarsesolverconverged;\n- 370 std::shared_ptr coarseSmoother_;\n- 372 SolverCategory::Category category_;\n- 374 std::size_t verbosity_;\n- 375\n- 376 struct ToLower\n- 377 {\n-378 std::string operator()(const std::string& str)\n- 379 {\n- 380 std::stringstream retval;\n- 381 std::ostream_iterator out(retval);\n- 382 std::transform(str.begin(), str.end(), out,\n- 383 [](char c){\n- 384 return std::tolower(c, std::locale::classic());\n- 385 });\n- 386 return retval.str();\n- 387 }\n- 388 };\n- 389 };\n- 390\n- 391 template\n-392 inline AMG::AMG(const AMG& amg)\n- 393 : matrices_(amg.matrices_), smootherArgs_(amg.smootherArgs_),\n- 394 smoothers_(amg.smoothers_), solver_(amg.solver_),\n- 395 rhs_(), lhs_(), update_(),\n- 396 scalarProduct_(amg.scalarProduct_), gamma_(amg.gamma_),\n- 397 preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),\n- 398 buildHierarchy_(amg.buildHierarchy_),\n- 399 additive(amg.additive), coarsesolverconverged(amg.coarsesolverconverged),\n- 400 coarseSmoother_(amg.coarseSmoother_),\n- 401 category_(amg.category_),\n- 402 verbosity_(amg.verbosity_)\n- 403 {}\n- 404\n- 405 template\n-406 AMG::AMG(OperatorHierarchy& matrices, CoarseSolver&\n-coarseSolver,\n- 407 const SmootherArgs& smootherArgs,\n- 408 const Parameters& parms)\n- 409 : matrices_(stackobject_to_shared_ptr(matrices)), smootherArgs_\n-(smootherArgs),\n- 410 smoothers_(new Hierarchy), solver_(&coarseSolver),\n- 411 rhs_(), lhs_(), update_(), scalarProduct_(0),\n- 412 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),\n- 413 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),\n- 414 additive(parms.getAdditive()), coarsesolverconverged(true),\n- 415 coarseSmoother_(),\n- 416// #warning should category be retrieved from matrices?\n- 417 category_(SolverCategory::category(*smoothers_->coarsest())),\n- 418 verbosity_(parms.debugLevel())\n- 419 {\n- 420 assert(matrices_->isBuilt());\n- 421\n- 422 // build the necessary smoother hierarchies\n- 423 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);\n- 424 }\n- 425\n- 426 template\n- 427 template\n-428 AMG::AMG(const Operator& matrix,\n- 429 const C& criterion,\n- 430 const SmootherArgs& smootherArgs,\n- 431 const PI& pinfo)\n- 432 : smootherArgs_(smootherArgs),\n- 433 smoothers_(new Hierarchy), solver_(),\n- 434 rhs_(), lhs_(), update_(), scalarProduct_(),\n- 435 gamma_(criterion.getGamma()), preSteps_(criterion.getNoPreSmoothSteps()),\n- 436 postSteps_(criterion.getNoPostSmoothSteps()), buildHierarchy_(true),\n- 437 additive(criterion.getAdditive()), coarsesolverconverged(true),\n- 438 coarseSmoother_(),\n- 439 category_(SolverCategory::category(pinfo)),\n- 440 verbosity_(criterion.debugLevel())\n- 441 {\n- 442 if(SolverCategory::category(matrix) != SolverCategory::category(pinfo))\n- 443 DUNE_THROW(InvalidSolverCategory, \"Matrix and Communication must have the\n-same SolverCategory!\");\n- 444 // TODO: reestablish compile time checks.\n- 445 //static_assert(static_cast(PI::category)==static_cast(S::\n-category),\n- 446 // \"Matrix and Solver must match in terms of category!\");\n- 447 auto matrixptr = stackobject_to_shared_ptr(matrix);\n- 448 createHierarchies(criterion, matrixptr, pinfo);\n- 449 }\n- 450\n- 451 template\n-452 AMG::AMG(std::shared_ptr matrixptr,\n- 453 const ParameterTree& configuration,\n- 454 const ParallelInformation& pinfo) :\n- 455 smoothers_(new Hierarchy),\n- 456 solver_(), rhs_(), lhs_(), update_(), scalarProduct_(), buildHierarchy_\n-(true),\n- 457 coarsesolverconverged(true), coarseSmoother_(),\n- 458 category_(SolverCategory::category(pinfo))\n- 459 {\n- 460\n- 461 if (configuration.hasKey (\"smootherIterations\"))\n- 462 smootherArgs_.iterations = configuration.get(\"smootherIterations\");\n- 463\n- 464 if (configuration.hasKey (\"smootherRelaxation\"))\n- 465 smootherArgs_.relaxationFactor = configuration.get(\"smootherRelaxation\");\n- 466\n- 467 auto normName = ToLower()(configuration.get(\"strengthMeasure\",\n-\"diagonal\"));\n- 468 auto index = configuration.get(\"diagonalRowIndex\", 0);\n- 469\n- 470 if ( normName == \"diagonal\")\n- 471 {\n- 472 using field_type = typename M::field_type;\n- 473 using real_type = typename FieldTraits::real_type;\n- 474 std::is_convertible compiles;\n- 475\n- 476 switch (index)\n- 477 {\n- 478 case 0:\n- 479 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<0>(),\n-configuration, compiles);\n- 480 break;\n- 481 case 1:\n- 482 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<1>(),\n-configuration, compiles);\n- 483 break;\n- 484 case 2:\n- 485 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<2>(),\n-configuration, compiles);\n- 486 break;\n- 487 case 3:\n- 488 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<3>(),\n-configuration, compiles);\n- 489 break;\n- 490 case 4:\n- 491 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<4>(),\n-configuration, compiles);\n- 492 break;\n- 493 default:\n- 494 DUNE_THROW(InvalidStateException, \"Currently strengthIndex>4 is not\n-supported.\");\n- 495 }\n- 496 }\n- 497 else if (normName == \"rowsum\")\n- 498 createCriterionAndHierarchies(matrixptr, pinfo, RowSum(), configuration);\n- 499 else if (normName == \"frobenius\")\n- 500 createCriterionAndHierarchies(matrixptr, pinfo, FrobeniusNorm(),\n-configuration);\n- 501 else if (normName == \"one\")\n- 502 createCriterionAndHierarchies(matrixptr, pinfo, AlwaysOneNorm(),\n-configuration);\n- 503 else\n- 504 DUNE_THROW(Dune::NotImplemented, \"Wrong config file: strengthMeasure\n-\"<\n- 508 template\n- 509 void AMG::createCriterionAndHierarchies(std::shared_ptr matrixptr, const PI& pinfo, const Norm&, const ParameterTree&\n-configuration, std::false_type)\n- 510 {\n- 511 DUNE_THROW(InvalidStateException, \"Strength of connection measure does not\n-support this type (\"\n- 512 << className() << \") as it is lacking a conversion\n-to\"\n- 513 << className::real_type>() <<\n-\".\");\n- 514 }\n- 515\n- 516 template\n- 517 template\n- 518 void AMG::createCriterionAndHierarchies(std::shared_ptr matrixptr, const PI& pinfo, const Norm&, const ParameterTree&\n-configuration, std::true_type)\n- 519 {\n- 520 if (configuration.get(\"criterionSymmetric\", true))\n- 521 {\n- 522 using Criterion = Dune::Amg::CoarsenCriterion<\n- 523 Dune::Amg::SymmetricCriterion >;\n- 524 Criterion criterion;\n- 525 createHierarchies(criterion, matrixptr, pinfo, configuration);\n- 526 }\n- 527 else\n- 528 {\n- 529 using Criterion = Dune::Amg::CoarsenCriterion<\n- 530 Dune::Amg::UnSymmetricCriterion >;\n- 531 Criterion criterion;\n- 532 createHierarchies(criterion, matrixptr, pinfo, configuration);\n- 533 }\n- 534 }\n- 535\n- 536 template\n- 537 template\n- 538 void AMG::createHierarchies(C& criterion, std::\n-shared_ptr matrixptr, const PI& pinfo, const ParameterTree&\n-configuration)\n- 539 {\n- 540 if (configuration.hasKey (\"maxLevel\"))\n- 541 criterion.setMaxLevel(configuration.get(\"maxLevel\"));\n- 542\n- 543 if (configuration.hasKey (\"minCoarseningRate\"))\n- 544 criterion.setMinCoarsenRate(configuration.get(\"minCoarseningRate\"));\n- 545\n- 546 if (configuration.hasKey (\"coarsenTarget\"))\n- 547 criterion.setCoarsenTarget (configuration.get(\"coarsenTarget\"));\n- 548\n- 549 if (configuration.hasKey (\"accumulationMode\"))\n- 550 {\n- 551 std::string mode = ToLower()(configuration.get\n-(\"accumulationMode\"));\n- 552 if ( mode == \"none\")\n- 553 criterion.setAccumulate(AccumulationMode::noAccu);\n- 554 else if ( mode == \"atonce\" )\n- 555 criterion.setAccumulate(AccumulationMode::atOnceAccu);\n- 556 else if ( mode == \"successive\")\n- 557 criterion.setCoarsenTarget (AccumulationMode::successiveAccu);\n- 558 else\n- 559 DUNE_THROW(InvalidSolverFactoryConfiguration, \"Parameter accumulationMode\n-does not allow value \"\n- 560 << mode <<\".\");\n- 561 }\n- 562\n- 563 if (configuration.hasKey (\"prolongationDampingFactor\"))\n- 564 criterion.setProlongationDampingFactor (configuration.get\n-(\"prolongationDampingFactor\"));\n- 565\n- 566 if (configuration.hasKey(\"defaultAggregationSizeMode\"))\n- 567 {\n- 568 auto mode = ToLower()(configuration.get\n-(\"defaultAggregationSizeMode\"));\n- 569 auto dim = configuration.get(\"defaultAggregationDimension\");\n- 570 std::size_t maxDistance = 2;\n- 571 if (configuration.hasKey(\"MaxAggregateDistance\"))\n- 572 maxDistance = configuration.get(\"maxAggregateDistance\");\n- 573 if (mode == \"isotropic\")\n- 574 criterion.setDefaultValuesIsotropic(dim, maxDistance);\n- 575 else if(mode == \"anisotropic\")\n- 576 criterion.setDefaultValuesAnisotropic(dim, maxDistance);\n- 577 else\n- 578 DUNE_THROW(InvalidSolverFactoryConfiguration, \"Parameter accumulationMode\n-does not allow value \"\n- 579 << mode <<\".\");\n- 580 }\n- 581\n- 582 if (configuration.hasKey(\"maxAggregateDistance\"))\n- 583 criterion.setMaxDistance(configuration.get\n-(\"maxAggregateDistance\"));\n- 584\n- 585 if (configuration.hasKey(\"minAggregateSize\"))\n- 586 criterion.setMinAggregateSize(configuration.get\n-(\"minAggregateSize\"));\n- 587\n- 588 if (configuration.hasKey(\"maxAggregateSize\"))\n- 589 criterion.setMaxAggregateSize(configuration.get\n-(\"maxAggregateSize\"));\n- 590\n- 591 if (configuration.hasKey(\"maxAggregateConnectivity\"))\n- 592 criterion.setMaxConnectivity(configuration.get\n-(\"maxAggregateConnectivity\"));\n- 593\n- 594 if (configuration.hasKey (\"alpha\"))\n- 595 criterion.setAlpha (configuration.get (\"alpha\"));\n- 596\n- 597 if (configuration.hasKey (\"beta\"))\n- 598 criterion.setBeta (configuration.get (\"beta\"));\n- 599\n- 600 if (configuration.hasKey (\"gamma\"))\n- 601 criterion.setGamma (configuration.get (\"gamma\"));\n- 602 gamma_ = criterion.getGamma();\n- 603\n- 604 if (configuration.hasKey (\"additive\"))\n- 605 criterion.setAdditive (configuration.get(\"additive\"));\n- 606 additive = criterion.getAdditive();\n- 607\n- 608 if (configuration.hasKey (\"preSteps\"))\n- 609 criterion.setNoPreSmoothSteps (configuration.get\n-(\"preSteps\"));\n- 610 preSteps_ = criterion.getNoPreSmoothSteps ();\n- 611\n- 612 if (configuration.hasKey (\"postSteps\"))\n- 613 criterion.setNoPostSmoothSteps (configuration.get\n-(\"postSteps\"));\n- 614 postSteps_ = criterion.getNoPostSmoothSteps ();\n- 615\n- 616 verbosity_ = configuration.get(\"verbosity\", 0);\n- 617 criterion.setDebugLevel (verbosity_);\n- 618\n- 619 createHierarchies(criterion, matrixptr, pinfo);\n- 620 }\n- 621\n- 622 template \n-624 struct DirectSolverSelector\n- 625 {\n-626 typedef typename Matrix_::_field_type field_type;\n-627 enum SolverType { umfpack, superlu, none };\n- 628\n-629 static constexpr SolverType solver =\n- 630#if DISABLE_AMG_DIRECTSOLVER\n- 631 none;\n- 632#elif HAVE_SUITESPARSE_UMFPACK\n- 633 UMFPackMethodChooser<_field_type_> :: valid ? umfpack : none ;\n- 634#elif HAVE_SUPERLU\n- 635 superlu ;\n- 636#else\n- 637 none;\n- 638#endif\n- 639\n- 640 template \n-641 struct Solver\n- 642 {\n-643 typedef InverseOperator type;\n-644 static type* create(const M& mat, bool verbose, bool reusevector )\n- 645 {\n- 646 DUNE_THROW(NotImplemented,\"DirectSolver not selected\");\n- 647 return nullptr;\n- 648 }\n-649 static std::string name () { return \"None\"; }\n- 650 };\n- 651#if HAVE_SUITESPARSE_UMFPACK\n- 652 template \n- 653 struct Solver< M, umfpack >\n- 654 {\n- 655 typedef UMFPack<_M_> type;\n- 656 static type* create(const M& mat, bool verbose, bool reusevector )\n- 657 {\n- 658 return new type(mat, verbose, reusevector );\n- 659 }\n- 660 static std::string name () { return \"UMFPack\"; }\n- 661 };\n- 662#endif\n- 663#if HAVE_SUPERLU\n- 664 template \n-665 struct Solver< M, superlu >\n- 666 {\n-667 typedef SuperLU<_M_> type;\n-668 static type* create(const M& mat, bool verbose, bool reusevector )\n- 669 {\n- 670 return new type(mat, verbose, reusevector );\n- 671 }\n-672 static std::string name () { return \"SuperLU\"; }\n- 673 };\n- 674#endif\n- 675\n- 676 // define direct solver type to be used\n-677 typedef Solver<_Matrix,_solver_> SelectedSolver ;\n-678 typedef typename SelectedSolver_::_type DirectSolver;\n-679 static constexpr bool isDirectSolver = solver != none;\n-680 static std::string name() { return SelectedSolver_::_name (); }\n-681 static DirectSolver* create(const Matrix& mat, bool verbose, bool\n-reusevector )\n- 682 {\n- 683 return SelectedSolver_::_create( mat, verbose, reusevector );\n- 684 }\n- 685 };\n- 686\n- 687 template\n- 688 template\n- 689 void AMG::createHierarchies(C& criterion,\n- 690 const std::shared_ptr& matrixptr,\n- 691 const PI& pinfo)\n- 692 {\n- 693 Timer watch;\n- 694 matrices_ = std::make_shared(\n- 695 std::const_pointer_cast(matrixptr),\n- 696 stackobject_to_shared_ptr(const_cast(pinfo)));\n- 697\n- 698 matrices_->template build >(criterion);\n- 699\n- 700 // build the necessary smoother hierarchies\n- 701 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);\n- 702\n- 703 // test whether we should solve on the coarse level. That is the case if\n-we\n- 704 // have that level and if there was a redistribution on this level then\n-our\n- 705 // communicator has to be valid (size()>0) as the smoother might try to\n-communicate\n- 706 // in the constructor.\n- 707 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()\n- 708 && ( ! matrices_->redistributeInformation().back().isSetup() ||\n- 709 matrices_->parallelInformation().coarsest().getRedistributed\n-().communicator().size() ) )\n- 710 {\n- 711 // We have the carsest level. Create the coarse Solver\n- 712 SmootherArgs sargs(smootherArgs_);\n- 713 sargs.iterations = 1;\n- 714\n- 715 typename ConstructionTraits::Arguments cargs;\n- 716 cargs.setArgs(sargs);\n- 717 if(matrices_->redistributeInformation().back().isSetup()) {\n- 718 // Solve on the redistributed partitioning\n- 719 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat\n-());\n- 720 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed\n-());\n- 721 }else{\n- 722 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());\n- 723 cargs.setComm(*matrices_->parallelInformation().coarsest());\n- 724 }\n- 725\n- 726 coarseSmoother_ = ConstructionTraits::construct(cargs);\n- 727 scalarProduct_ = createScalarProduct(cargs.getComm(),category());\n- 728\n- 729 typedef DirectSolverSelector< typename M::matrix_type, X > SolverSelector;\n- 730\n- 731 // Use superlu if we are purely sequential or with only one processor on\n-the coarsest level.\n- 732 if( SolverSelector::isDirectSolver &&\n- 733 (std::is_same::value /\n-/ sequential mode\n- 734 || matrices_->parallelInformation().coarsest()->communicator().size()==1 /\n-/parallel mode and only one processor\n- 735 || (matrices_->parallelInformation().coarsest().isRedistributed()\n- 736 && matrices_->parallelInformation().coarsest().getRedistributed\n-().communicator().size()==1\n- 737 && matrices_->parallelInformation().coarsest().getRedistributed\n-().communicator().size()>0) )\n- 738 )\n- 739 { // redistribute and 1 proc\n- 740 if(matrices_->parallelInformation().coarsest().isRedistributed())\n- 741 {\n- 742 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n- 743 {\n- 744 // We are still participating on this level\n- 745 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest\n-().getRedistributed().getmat(), false, false));\n- 746 }\n- 747 else\n- 748 solver_.reset();\n- 749 }\n- 750 else\n- 751 {\n- 752 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest()-\n->getmat(), false, false));\n- 753 }\n- 754 if(verbosity_>0 && matrices_->parallelInformation().coarsest()-\n->communicator().rank()==0)\n- 755 std::cout<< \"Using a direct coarse solver (\" << SolverSelector::name() <<\n-\")\" << std::endl;\n- 756 }\n- 757 else\n- 758 {\n- 759 if(matrices_->parallelInformation().coarsest().isRedistributed())\n- 760 {\n- 761 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n- 762 // We are still participating on this level\n- 763\n- 764 // we have to allocate these types using the rebound allocator\n- 765 // in order to ensure that we fulfill the alignment requirements\n- 766 solver_.reset(new BiCGSTABSolver(const_cast(matrices_->matrices\n-().coarsest().getRedistributed()),\n- 767 *scalarProduct_,\n- 768 *coarseSmoother_, 1E-2, 1000, 0));\n- 769 else\n- 770 solver_.reset();\n- 771 }else\n- 772 {\n- 773 solver_.reset(new BiCGSTABSolver(const_cast(*matrices_->matrices\n-().coarsest()),\n- 774 *scalarProduct_,\n- 775 *coarseSmoother_, 1E-2, 1000, 0));\n- 776 // // we have to allocate these types using the rebound allocator\n- 777 // // in order to ensure that we fulfill the alignment requirements\n- 778 // using Alloc = typename std::allocator_traits::template\n-rebind_alloc>;\n- 779 // Alloc alloc;\n- 780 // auto p = alloc.allocate(1);\n- 781 // std::allocator_traits::construct(alloc, p,\n- 782 // const_cast(*matrices_->matrices().coarsest()),\n- 783 // *scalarProduct_,\n- 784 // *coarseSmoother_, 1E-2, 1000, 0);\n- 785 // solver_.reset(p,[](BiCGSTABSolver* p){\n- 786 // Alloc alloc;\n- 787 // std::allocator_traits::destroy(alloc, p);\n- 788 // alloc.deallocate(p,1);\n- 789 // });\n- 790 }\n- 791 }\n- 792 }\n- 793\n- 794 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n-().rank()==0)\n- 795 std::cout<<\"Building hierarchy of \"<maxlevels()<<\" levels \"\n- 796 <<\"(including coarse solver) took \"<\n-801 void AMG::pre(Domain& x, Range& b)\n- 802 {\n- 803 // Detect Matrix rows where all offdiagonal entries are\n- 804 // zero and set x such that A_dd*x_d=b_d\n- 805 // Thus users can be more careless when setting up their linear\n- 806 // systems.\n- 807 typedef typename M::matrix_type Matrix;\n- 808 typedef typename Matrix::ConstRowIterator RowIter;\n- 809 typedef typename Matrix::ConstColIterator ColIter;\n- 810 typedef typename Matrix::block_type Block;\n- 811 Block zero;\n- 812 zero=typename Matrix::field_type();\n- 813\n- 814 const Matrix& mat=matrices_->matrices().finest()->getmat();\n- 815 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {\n- 816 bool isDirichlet = true;\n- 817 bool hasDiagonal = false;\n- 818 Block diagonal{};\n- 819 for(ColIter col=row->begin(); col!=row->end(); ++col) {\n- 820 if(row.index()==col.index()) {\n- 821 diagonal = *col;\n- 822 hasDiagonal = true;\n- 823 }else{\n- 824 if(*col!=zero)\n- 825 isDirichlet = false;\n- 826 }\n- 827 }\n- 828 if(isDirichlet && hasDiagonal)\n- 829 {\n- 830 auto&& xEntry = Impl::asVector(x[row.index()]);\n- 831 auto&& bEntry = Impl::asVector(b[row.index()]);\n- 832 Impl::asMatrix(diagonal).solve(xEntry, bEntry);\n- 833 }\n- 834 }\n- 835\n- 836 if(smoothers_->levels()>0)\n- 837 smoothers_->finest()->pre(x,b);\n- 838 else\n- 839 // No smoother to make x consistent! Do it by hand\n- 840 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);\n- 841 rhs_ = std::make_shared>(std::make_shared(b));\n- 842 lhs_ = std::make_shared>(std::make_shared(x));\n- 843 update_ = std::make_shared>(std::make_shared\n-(x));\n- 844 matrices_->coarsenVector(*rhs_);\n- 845 matrices_->coarsenVector(*lhs_);\n- 846 matrices_->coarsenVector(*update_);\n- 847\n- 848 // Preprocess all smoothers\n- 849 typedef typename Hierarchy::Iterator Iterator;\n- 850 typedef typename Hierarchy::Iterator RIterator;\n- 851 typedef typename Hierarchy::Iterator DIterator;\n- 852 Iterator coarsest = smoothers_->coarsest();\n- 853 Iterator smoother = smoothers_->finest();\n- 854 RIterator rhs = rhs_->finest();\n- 855 DIterator lhs = lhs_->finest();\n- 856 if(smoothers_->levels()>1) {\n- 857\n- 858 assert(lhs_->levels()==rhs_->levels());\n- 859 assert(smoothers_->levels()==lhs_->levels() || matrices_->levels\n-()==matrices_->maxlevels());\n- 860 assert(smoothers_->levels()+1==lhs_->levels() || matrices_->levels\n-()maxlevels());\n- 861\n- 862 if(smoother!=coarsest)\n- 863 for(++smoother, ++lhs, ++rhs; smoother != coarsest; ++smoother, ++lhs,\n-++rhs)\n- 864 smoother->pre(*lhs,*rhs);\n- 865 smoother->pre(*lhs,*rhs);\n- 866 }\n- 867\n- 868\n- 869 // The preconditioner might change x and b. So we have to\n- 870 // copy the changes to the original vectors.\n- 871 x = *lhs_->finest();\n- 872 b = *rhs_->finest();\n- 873\n- 874 }\n- 875 template\n-876 std::size_t AMG::levels()\n- 877 {\n- 878 return matrices_->levels();\n- 879 }\n- 880 template\n-881 std::size_t AMG::maxlevels()\n- 882 {\n- 883 return matrices_->maxlevels();\n- 884 }\n- 885\n- 887 template\n-888 void AMG::apply(Domain& v, const Range& d)\n- 889 {\n- 890 LevelContext levelContext;\n- 891\n- 892 if(additive) {\n- 893 *(rhs_->finest())=d;\n- 894 additiveMgc();\n- 895 v=*lhs_->finest();\n- 896 }else{\n- 897 // Init all iterators for the current level\n- 898 initIteratorsWithFineLevel(levelContext);\n- 899\n- 900\n- 901 *levelContext.lhs = v;\n- 902 *levelContext.rhs = d;\n- 903 *levelContext.update=0;\n- 904 levelContext.level=0;\n- 905\n- 906 mgc(levelContext);\n- 907\n- 908 if(postSteps_==0||matrices_->maxlevels()==1)\n- 909 levelContext.pinfo->copyOwnerToAll(*levelContext.update,\n-*levelContext.update);\n- 910\n- 911 v=*levelContext.update;\n- 912 }\n- 913\n- 914 }\n- 915\n- 916 template\n- 917 void AMG::initIteratorsWithFineLevel(LevelContext&\n-levelContext)\n- 918 {\n- 919 levelContext.smoother = smoothers_->finest();\n- 920 levelContext.matrix = matrices_->matrices().finest();\n- 921 levelContext.pinfo = matrices_->parallelInformation().finest();\n- 922 levelContext.redist =\n- 923 matrices_->redistributeInformation().begin();\n- 924 levelContext.aggregates = matrices_->aggregatesMaps().begin();\n- 925 levelContext.lhs = lhs_->finest();\n- 926 levelContext.update = update_->finest();\n- 927 levelContext.rhs = rhs_->finest();\n- 928 }\n- 929\n- 930 template\n- 931 bool AMG\n- 932 ::moveToCoarseLevel(LevelContext& levelContext)\n- 933 {\n- 934\n- 935 bool processNextLevel=true;\n- 936\n- 937 if(levelContext.redist->isSetup()) {\n- 938 levelContext.redist->redistribute(static_cast\n-(*levelContext.rhs),\n- 939 levelContext.rhs.getRedistributed());\n- 940 processNextLevel = levelContext.rhs.getRedistributed().size()>0;\n- 941 if(processNextLevel) {\n- 942 //restrict defect to coarse level right hand side.\n- 943 typename Hierarchy::Iterator fineRhs = levelContext.rhs++;\n- 944 ++levelContext.pinfo;\n- 945 Transfer\n- 946::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n- 947 static_cast(fineRhs.getRedistributed()),\n- 948 *levelContext.pinfo);\n- 949 }\n- 950 }else{\n- 951 //restrict defect to coarse level right hand side.\n- 952 typename Hierarchy::Iterator fineRhs = levelContext.rhs++;\n- 953 ++levelContext.pinfo;\n- 954 Transfer\n- 955::restrictVector(*(*levelContext.aggregates),\n- 956 *levelContext.rhs, static_cast(*fineRhs),\n- 957 *levelContext.pinfo);\n- 958 }\n- 959\n- 960 if(processNextLevel) {\n- 961 // prepare coarse system\n- 962 ++levelContext.lhs;\n- 963 ++levelContext.update;\n- 964 ++levelContext.matrix;\n- 965 ++levelContext.level;\n- 966 ++levelContext.redist;\n- 967\n- 968 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n->levels()maxlevels()) {\n- 969 // next level is not the globally coarsest one\n- 970 ++levelContext.smoother;\n- 971 ++levelContext.aggregates;\n- 972 }\n- 973 // prepare the update on the next level\n- 974 *levelContext.update=0;\n- 975 }\n- 976 return processNextLevel;\n- 977 }\n- 978\n- 979 template\n- 980 void AMG\n- 981 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel)\n- 982 {\n- 983 if(processNextLevel) {\n- 984 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n->levels()maxlevels()) {\n- 985 // previous level is not the globally coarsest one\n- 986 --levelContext.smoother;\n- 987 --levelContext.aggregates;\n- 988 }\n- 989 --levelContext.redist;\n- 990 --levelContext.level;\n- 991 //prolongate and add the correction (update is in coarse left hand side)\n- 992 --levelContext.matrix;\n- 993\n- 994 //typename Hierarchy::Iterator coarseLhs = lhs--;\n- 995 --levelContext.lhs;\n- 996 --levelContext.pinfo;\n- 997 }\n- 998 if(levelContext.redist->isSetup()) {\n- 999 // Need to redistribute during prolongateVector\n- 1000 levelContext.lhs.getRedistributed()=0;\n- 1001 Transfer\n- 1002::prolongateVector(*(*levelContext.aggregates), *levelContext.update,\n-*levelContext.lhs,\n- 1003 levelContext.lhs.getRedistributed(),\n- 1004 matrices_->getProlongationDampingFactor(),\n- 1005 *levelContext.pinfo, *levelContext.redist);\n- 1006 }else{\n- 1007 *levelContext.lhs=0;\n- 1008 Transfer\n- 1009::prolongateVector(*(*levelContext.aggregates), *levelContext.update,\n-*levelContext.lhs,\n- 1010 matrices_->getProlongationDampingFactor(),\n- 1011 *levelContext.pinfo);\n- 1012 }\n- 1013\n- 1014\n- 1015 if(processNextLevel) {\n- 1016 --levelContext.update;\n- 1017 --levelContext.rhs;\n- 1018 }\n- 1019\n- 1020 *levelContext.update += *levelContext.lhs;\n- 1021 }\n- 1022\n- 1023 template\n-1024 bool AMG::usesDirectCoarseLevelSolver() const\n- 1025 {\n- 1026 return IsDirectSolver<_CoarseSolver>::value;\n- 1027 }\n- 1028\n- 1029 template\n- 1030 void AMG::mgc(LevelContext& levelContext){\n- 1031 if(levelContext.matrix == matrices_->matrices().coarsest() && levels\n-()==maxlevels()) {\n- 1032 // Solve directly\n- 1033 InverseOperatorResult res;\n- 1034 res.converged=true; // If we do not compute this flag will not get\n-updated\n- 1035 if(levelContext.redist->isSetup()) {\n- 1036 levelContext.redist->redistribute(*levelContext.rhs,\n-levelContext.rhs.getRedistributed());\n- 1037 if(levelContext.rhs.getRedistributed().size()>0) {\n- 1038 // We are still participating in the computation\n- 1039 levelContext.pinfo.getRedistributed().copyOwnerToAll\n-(levelContext.rhs.getRedistributed(),\n- 1040 levelContext.rhs.getRedistributed());\n- 1041 solver_->apply(levelContext.update.getRedistributed(),\n- 1042 levelContext.rhs.getRedistributed(), res);\n- 1043 }\n- 1044 levelContext.redist->redistributeBackward(*levelContext.update,\n-levelContext.update.getRedistributed());\n- 1045 levelContext.pinfo->copyOwnerToAll(*levelContext.update,\n-*levelContext.update);\n- 1046 }else{\n- 1047 levelContext.pinfo->copyOwnerToAll(*levelContext.rhs, *levelContext.rhs);\n- 1048 solver_->apply(*levelContext.update, *levelContext.rhs, res);\n- 1049 }\n- 1050\n- 1051 if (!res.converged)\n- 1052 coarsesolverconverged = false;\n- 1053 }else{\n- 1054 // presmoothing\n- 1055 presmooth(levelContext, preSteps_);\n- 1056\n- 1057#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n- 1058 bool processNextLevel = moveToCoarseLevel(levelContext);\n- 1059\n- 1060 if(processNextLevel) {\n- 1061 // next level\n- 1062 for(std::size_t i=0; imatrices().coarsest() && levels\n-()==maxlevels())\n- 1065 break;\n- 1066 if(i+1 < gamma_){\n- 1067 levelContext.matrix->applyscaleadd(-1., *levelContext.lhs,\n-*levelContext.rhs);\n- 1068 }\n- 1069 }\n- 1070 }\n- 1071\n- 1072 moveToFineLevel(levelContext, processNextLevel);\n- 1073#else\n- 1074 *lhs=0;\n- 1075#endif\n- 1076\n- 1077 if(levelContext.matrix == matrices_->matrices().finest()) {\n- 1078 coarsesolverconverged = matrices_->parallelInformation().finest()-\n->communicator().prod(coarsesolverconverged);\n- 1079 if(!coarsesolverconverged)\n- 1080 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n- 1081 }\n- 1082 // postsmoothing\n- 1083 postsmooth(levelContext, postSteps_);\n- 1084\n- 1085 }\n- 1086 }\n- 1087\n- 1088 template\n- 1089 void AMG::additiveMgc(){\n- 1090\n- 1091 // restrict residual to all levels\n- 1092 typename ParallelInformationHierarchy::Iterator pinfo=matrices_-\n->parallelInformation().finest();\n- 1093 typename Hierarchy::Iterator rhs=rhs_->finest();\n- 1094 typename Hierarchy::Iterator lhs = lhs_->finest();\n- 1095 typename OperatorHierarchy::AggregatesMapList::const_iterator\n-aggregates=matrices_->aggregatesMaps().begin();\n- 1096\n- 1097 for(typename Hierarchy::Iterator fineRhs=rhs++; fineRhs != rhs_-\n->coarsest(); fineRhs=rhs++, ++aggregates) {\n- 1098 ++pinfo;\n- 1099 Transfer\n- 1100::restrictVector(*(*aggregates), *rhs, static_cast\n-(*fineRhs), *pinfo);\n- 1101 }\n- 1102\n- 1103 // pinfo is invalid, set to coarsest level\n- 1104 //pinfo = matrices_->parallelInformation().coarsest\n- 1105 // calculate correction for all levels\n- 1106 lhs = lhs_->finest();\n- 1107 typename Hierarchy::Iterator smoother = smoothers_->finest();\n- 1108\n- 1109 for(rhs=rhs_->finest(); rhs != rhs_->coarsest(); ++lhs, ++rhs,\n-++smoother) {\n- 1110 // presmoothing\n- 1111 *lhs=0;\n- 1112 smoother->apply(*lhs, *rhs);\n- 1113 }\n- 1114\n- 1115 // Coarse level solve\n- 1116#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n- 1117 InverseOperatorResult res;\n- 1118 pinfo->copyOwnerToAll(*rhs, *rhs);\n- 1119 solver_->apply(*lhs, *rhs, res);\n- 1120\n- 1121 if(!res.converged)\n- 1122 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n- 1123#else\n- 1124 *lhs=0;\n- 1125#endif\n- 1126 // Prologate and add up corrections from all levels\n- 1127 --pinfo;\n- 1128 --aggregates;\n- 1129\n- 1130 for(typename Hierarchy::Iterator coarseLhs = lhs--; coarseLhs\n-!= lhs_->finest(); coarseLhs = lhs--, --aggregates, --pinfo) {\n- 1131 Transfer\n- 1132::prolongateVector(*(*aggregates), *coarseLhs, *lhs, 1.0, *pinfo);\n- 1133 }\n- 1134 }\n- 1135\n- 1136\n- 1138 template\n-1139 void AMG::post([[maybe_unused]] Domain& x)\n- 1140 {\n- 1141 // Postprocess all smoothers\n- 1142 typedef typename Hierarchy::Iterator Iterator;\n- 1143 typedef typename Hierarchy::Iterator DIterator;\n- 1144 Iterator coarsest = smoothers_->coarsest();\n- 1145 Iterator smoother = smoothers_->finest();\n- 1146 DIterator lhs = lhs_->finest();\n- 1147 if(smoothers_->levels()>0) {\n- 1148 if(smoother != coarsest || matrices_->levels()maxlevels())\n- 1149 smoother->post(*lhs);\n- 1150 if(smoother!=coarsest)\n- 1151 for(++smoother, ++lhs; smoother != coarsest; ++smoother, ++lhs)\n- 1152 smoother->post(*lhs);\n- 1153 smoother->post(*lhs);\n- 1154 }\n- 1155 lhs_ = nullptr;\n- 1156 update_ = nullptr;\n- 1157 rhs_ = nullptr;\n- 1158 }\n- 1159\n- 1160 template\n- 1161 template\n-1162 void AMG::getCoarsestAggregateNumbers(std::vector& cont)\n- 1163 {\n- 1164 matrices_->getCoarsestAggregatesOnFinest(cont);\n- 1165 }\n- 1166\n- 1167 } // end namespace Amg\n- 1168\n-1169 struct AMGCreator{\n-1170 template struct isValidBlockType : std::false_type{};\n-1171 template struct\n-isValidBlockType> : std::true_type{};\n- 1172\n- 1173 template\n- 1174 std::shared_ptr >\n-1175 makeAMG(const OP& op, const std::string& smoother, const Dune::\n-ParameterTree& config) const\n- 1176 {\n- 1177 DUNE_THROW(Dune::Exception, \"Operator type not supported by AMG\");\n- 1178 }\n- 1179\n- 1180 template\n- 1181 std::shared_ptr >\n-1182 makeAMG(const std::shared_ptr>& op, const std::\n-string& smoother,\n- 1183 const Dune::ParameterTree& config) const\n- 1184 {\n- 1185 using OP = MatrixAdapter;\n- 1186\n- 1187 if(smoother == \"ssor\")\n- 1188 return std::make_shared>>(op, config);\n- 1189 if(smoother == \"sor\")\n- 1190 return std::make_shared>>(op, config);\n- 1191 if(smoother == \"jac\")\n- 1192 return std::make_shared>>(op, config);\n- 1193 if(smoother == \"gs\")\n- 1194 return std::make_shared>>(op, config);\n- 1195 if(smoother == \"ilu\")\n- 1196 return std::make_shared>>(op, config);\n- 1197 else\n- 1198 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n- 1199 }\n- 1200\n- 1201 template\n- 1202 std::shared_ptr >\n-1203 makeAMG(const std::shared_ptr>& op,\n-const std::string& smoother,\n- 1204 const Dune::ParameterTree& config) const\n- 1205 {\n- 1206 using OP = OverlappingSchwarzOperator;\n- 1207\n- 1208 auto cop = std::static_pointer_cast(op);\n- 1209\n- 1210 if(smoother == \"ssor\")\n- 1211 return std::make_shared>,C>>(cop, config, op->getCommunication\n-());\n- 1212 if(smoother == \"sor\")\n- 1213 return std::make_shared>,C>>(cop, config, op->getCommunication\n-());\n- 1214 if(smoother == \"jac\")\n- 1215 return std::make_shared>,C>>(cop, config, op->getCommunication\n-());\n- 1216 if(smoother == \"gs\")\n- 1217 return std::make_shared>,C>>(cop, config, op->getCommunication\n-());\n- 1218 if(smoother == \"ilu\")\n- 1219 return std::make_shared>,C>>(cop, config, op->getCommunication\n-());\n- 1220 else\n- 1221 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n- 1222 }\n- 1223\n- 1224 template\n- 1225 std::shared_ptr >\n-1226 makeAMG(const std::shared_ptr>& op,\n-const std::string& smoother,\n- 1227 const Dune::ParameterTree& config) const\n- 1228 {\n- 1229 using OP = NonoverlappingSchwarzOperator;\n- 1230\n- 1231 if(smoother == \"ssor\")\n- 1232 return std::make_shared>,C>>(op, config, op-\n->getCommunication());\n- 1233 if(smoother == \"sor\")\n- 1234 return std::make_shared>,C>>(op, config, op-\n->getCommunication());\n- 1235 if(smoother == \"jac\")\n- 1236 return std::make_shared>,C>>(op, config, op-\n->getCommunication());\n- 1237 if(smoother == \"gs\")\n- 1238 return std::make_shared>,C>>(op, config, op-\n->getCommunication());\n- 1239 if(smoother == \"ilu\")\n- 1240 return std::make_shared>,C>>(op, config, op-\n->getCommunication());\n- 1241 else\n- 1242 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n- 1243 }\n- 1244\n- 1245 template\n- 1246 std::shared_ptr::type,\n- 1247 typename Dune::TypeListElement<2, TL>::type>>\n-1248 operator()(TL tl, const std::shared_ptr& op, const Dune::\n-ParameterTree& config,\n- 1249 std::enable_if_t::\n-value,int> = 0) const\n- 1250 {\n- 1251 using field_type = typename OP::matrix_type::field_type;\n- 1252 using real_type = typename FieldTraits::real_type;\n- 1253 if (!std::is_convertible())\n- 1254 DUNE_THROW(UnsupportedType, \"AMG needs field_type(\" <<\n- 1255 className() <<\n- 1256 \") to be convertible to its real_type (\" <<\n- 1257 className() <<\n- 1258 \").\");\n- 1259 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;\n- 1260 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;\n- 1261 std::shared_ptr> amg;\n- 1262 std::string smoother = config.get(\"smoother\", \"ssor\");\n- 1263 return makeAMG(op, smoother, config);\n- 1264 }\n- 1265\n- 1266 template\n- 1267 std::shared_ptr::type,\n- 1268 typename Dune::TypeListElement<2, TL>::type>>\n-1269 operator()(TL /*tl*/, const std::shared_ptr& /*mat*/, const Dune::\n-ParameterTree& /*config*/,\n- 1270 std::enable_if_t::value,int> = 0) const\n- 1271 {\n- 1272 DUNE_THROW(UnsupportedType, \"AMG needs a FieldMatrix as Matrix\n-block_type\");\n- 1273 }\n- 1274 };\n- 1275\n-1276 DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator());\n- 1277} // end namespace Dune\n- 1278\n- 1279#endif\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-transfer.hh\n-Prolongation and restriction for amg.\n-smoother.hh\n-Classes for the generic construction and application of the smoothers.\n-matrixhierarchy.hh\n-Provides a classes representing the hierarchies in AMG.\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n-umfpack.hh\n-Classes for using UMFPack with ISTL matrices.\n-superlu.hh\n-Classes for using SuperLU with ISTL matrices.\n+ 223 this->copyToLocalMatrix(A,rowSet);\n+ 224 ILU::blockILU0Decomposition(this->ILU);\n+ 225 }\n+ 226\n+ 227 template\n+ 228 template\n+229 void ILUNSubdomainSolver::setSubMatrix(const M& A, S& rowSet)\n+ 230 {\n+ 231 std::size_t offset=copyToLocalMatrix(A,rowSet);\n+ 232 RILU.setSize(rowSet.size(),rowSet.size(), (1+2*offset)*rowSet.size());\n+ 233 RILU.setBuildMode(matrix_type::row_wise);\n+ 234 ILU::blockILUDecomposition(this->ILU, (offset+1)/2, RILU);\n+ 235 }\n+ 236\n+ 238} // end name space DUNE\n+ 239\n+ 240\n+ 241#endif\n+matrix.hh\n+A dynamic dense block matrix class.\n+preconditioners.hh\n+Define general preconditioner interface.\n+Dune::ILUSubdomainSolver::copyToLocalMatrix\n+std::size_t copyToLocalMatrix(const M &A, S &rowset)\n+Copy the local part of the global matrix to ILU.\n+Definition: ilusubdomainsolver.hh:151\n+Dune::ILUNSubdomainSolver::setSubMatrix\n+void setSubMatrix(const M &A, S &rowset)\n+Set the data of the local problem.\n+Definition: ilusubdomainsolver.hh:229\n+Dune::ILU0SubdomainSolver::setSubMatrix\n+void setSubMatrix(const M &A, S &rowset)\n+Set the data of the local problem.\n+Definition: ilusubdomainsolver.hh:221\n col\n Col col\n Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::Amg::AMG::AMG\n-AMG(const AMG &amg)\n-Copy constructor.\n-Definition: amg.hh:392\n-Dune::Amg::AMG::pre\n-void pre(Domain &x, Range &b)\n-Prepare the preconditioner.\n-Definition: amg.hh:801\n-Dune::Amg::DirectSolverSelector::create\n-static DirectSolver * create(const Matrix &mat, bool verbose, bool reusevector)\n-Definition: amg.hh:681\n-Dune::Amg::DirectSolverSelector::name\n-static std::string name()\n-Definition: amg.hh:680\n-Dune::Amg::AMG::LevelContext::update\n-Hierarchy< Domain, A >::Iterator update\n-The iterator over the updates.\n-Definition: amg.hh:303\n-Dune::Amg::AMG::LevelContext::rhs\n-Hierarchy< Range, A >::Iterator rhs\n-The iterator over the right hand sided.\n-Definition: amg.hh:307\n-Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::name\n-static std::string name()\n-Definition: amg.hh:672\n-Dune::Amg::AMG::usesDirectCoarseLevelSolver\n-bool usesDirectCoarseLevelSolver() const\n-Check whether the coarse solver used is a direct solver.\n-Definition: amg.hh:1024\n-Dune::Amg::AMG::Domain\n-X Domain\n-The domain type.\n-Definition: amg.hh:87\n-Dune::Amg::DirectSolverSelector::Solver::create\n-static type * create(const M &mat, bool verbose, bool reusevector)\n-Definition: amg.hh:644\n-Dune::Amg::AMG::AMG\n-AMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs\n-&smootherArgs, const Parameters &parms)\n-Construct a new amg with a specific coarse solver.\n-Definition: amg.hh:406\n-Dune::Amg::AMG::AMG\n-AMG(std::shared_ptr< const Operator > fineOperator, const ParameterTree\n-&configuration, const ParallelInformation &pinfo=ParallelInformation())\n-Constructor an AMG via ParameterTree.\n-Definition: amg.hh:452\n-Dune::Amg::AMG::LevelContext::pinfo\n-ParallelInformationHierarchy::Iterator pinfo\n-The iterator over the parallel information.\n-Definition: amg.hh:287\n-Dune::Amg::DirectSolverSelector::SolverType\n-SolverType\n-Definition: amg.hh:627\n-Dune::Amg::AMG::LevelContext::aggregates\n-OperatorHierarchy::AggregatesMapList::const_iterator aggregates\n-The iterator over the aggregates maps.\n-Definition: amg.hh:295\n-Dune::Amg::AMG::SmootherArgs\n-SmootherTraits< Smoother >::Arguments SmootherArgs\n-The argument type for the construction of the smoother.\n-Definition: amg.hh:100\n-Dune::Amg::DirectSolverSelector::SelectedSolver\n-Solver< Matrix, solver > SelectedSolver\n-Definition: amg.hh:677\n-Dune::AMGCreator::makeAMG\n-std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n-MatrixAdapter< M, X, Y > > &op, const std::string &smoother, const Dune::\n-ParameterTree &config) const\n-Definition: amg.hh:1182\n-Dune::Amg::AMG::ToLower::operator()\n-std::string operator()(const std::string &str)\n-Definition: amg.hh:378\n-Dune::AMGCreator::makeAMG\n-std::shared_ptr< Dune::Preconditioner< typename OP::element_type::domain_type,\n-typename OP::element_type::range_type > > makeAMG(const OP &op, const std::\n-string &smoother, const Dune::ParameterTree &config) const\n-Definition: amg.hh:1175\n-Dune::Amg::AMG::Smoother\n-S Smoother\n-The type of the smoother.\n-Definition: amg.hh:97\n-Dune::Amg::DirectSolverSelector::Solver::name\n-static std::string name()\n-Definition: amg.hh:649\n-Dune::Amg::AMG::LevelContext::smoother\n-Hierarchy< Smoother, A >::Iterator smoother\n-The iterator over the smoothers.\n-Definition: amg.hh:279\n-Dune::Amg::AMG::Operator\n-M Operator\n-The matrix operator type.\n-Definition: amg.hh:73\n-Dune::Amg::AMG::LevelContext::matrix\n-OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix\n-The iterator over the matrices.\n-Definition: amg.hh:283\n-Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::type\n-SuperLU< M > type\n-Definition: amg.hh:667\n-Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::create\n-static type * create(const M &mat, bool verbose, bool reusevector)\n-Definition: amg.hh:668\n-Dune::Amg::AMG::LevelContext::redist\n-OperatorHierarchy::RedistributeInfoList::const_iterator redist\n-The iterator over the redistribution information.\n-Definition: amg.hh:291\n-Dune::Amg::AMG::Range\n-X Range\n-The range type.\n-Definition: amg.hh:89\n-Dune::Amg::presmooth\n-void presmooth(LevelContext &levelContext, size_t steps)\n-Apply pre smoothing on the current level.\n-Definition: smoother.hh:406\n-Dune::Amg::AMG::getCoarsestAggregateNumbers\n-void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)\n-Get the aggregate number of each unknown on the coarsest level.\n-Definition: amg.hh:1162\n-Dune::Amg::AMG::levels\n-std::size_t levels()\n-Definition: amg.hh:876\n-Dune::Amg::DirectSolverSelector::Solver::type\n-InverseOperator< Vector, Vector > type\n-Definition: amg.hh:643\n-Dune::AMGCreator::makeAMG\n-std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n-OverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother,\n-const Dune::ParameterTree &config) const\n-Definition: amg.hh:1203\n-Dune::Amg::AMG::LevelContext::lhs\n-Hierarchy< Domain, A >::Iterator lhs\n-The iterator over the left hand side.\n-Definition: amg.hh:299\n-Dune::Amg::ConstructionTraits::Arguments\n-const void * Arguments\n-A type holding all the arguments needed to call the constructor.\n-Definition: construction.hh:44\n-Dune::Amg::DirectSolverSelector::solver\n-static constexpr SolverType solver\n-Definition: amg.hh:629\n-Dune::Amg::ConstructionTraits::construct\n-static std::shared_ptr< T > construct(Arguments &args)\n-Construct an object with the specified arguments.\n-Definition: construction.hh:52\n-Dune::Amg::DirectSolverSelector::isDirectSolver\n-static constexpr bool isDirectSolver\n-Definition: amg.hh:679\n-Dune::Amg::AMG::recalculateHierarchy\n-void recalculateHierarchy()\n-Recalculate the matrix hierarchy.\n-Definition: amg.hh:221\n-Dune::Amg::Hierarchy::coarsest\n-Iterator coarsest()\n-Get an iterator positioned at the coarsest level.\n-Definition: hierarchy.hh:383\n-Dune::Amg::DirectSolverSelector::field_type\n-Matrix::field_type field_type\n-Definition: amg.hh:626\n-Dune::Amg::DirectSolverSelector::DirectSolver\n-SelectedSolver::type DirectSolver\n-Definition: amg.hh:678\n-Dune::AMGCreator::operator()\n-std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL\n->::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL tl,\n-const std::shared_ptr< OP > &op, const Dune::ParameterTree &config, std::\n-enable_if_t< isValidBlockType< typename OP::matrix_type::block_type >::value,\n-int >=0) const\n-Definition: amg.hh:1248\n-Dune::Amg::AMG::ParallelInformationHierarchy\n-OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy\n-The parallal data distribution hierarchy type.\n-Definition: amg.hh:84\n-Dune::Amg::AMG::CoarseSolver\n-InverseOperator< X, X > CoarseSolver\n-the type of the coarse solver.\n-Definition: amg.hh:91\n-Dune::Amg::AMG::post\n-void post(Domain &x)\n-Clean up.\n-Definition: amg.hh:1139\n-Dune::Amg::AMG::maxlevels\n-std::size_t maxlevels()\n-Definition: amg.hh:881\n-Dune::AMGCreator::makeAMG\n-std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n-NonoverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother,\n-const Dune::ParameterTree &config) const\n-Definition: amg.hh:1226\n-Dune::Amg::postsmooth\n-void postsmooth(LevelContext &levelContext, size_t steps)\n-Apply post smoothing on the current level.\n-Definition: smoother.hh:428\n-Dune::Amg::AMG::LevelContext::level\n-std::size_t level\n-The level index.\n-Definition: amg.hh:311\n-Dune::Amg::AMG::AMG\n-AMG(const Operator &fineOperator, const C &criterion, const SmootherArgs\n-&smootherArgs=SmootherArgs(), const ParallelInformation\n-&pinfo=ParallelInformation())\n-Construct an AMG with an inexact coarse solver based on the smoother.\n-Definition: amg.hh:428\n-Dune::Amg::AMG::apply\n-void apply(Domain &v, const Range &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: amg.hh:888\n-Dune::Amg::AMG::LevelContext::SmootherType\n-Smoother SmootherType\n-Definition: amg.hh:275\n-Dune::Amg::AMG::OperatorHierarchy\n-MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy\n-The operator hierarchy type.\n-Definition: amg.hh:82\n-Dune::Amg::AMG::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: amg.hh:194\n-Dune::Amg::AMG::ParallelInformation\n-PI ParallelInformation\n-The type of the parallel information. Either OwnerOverlapCommunication or\n-another type describing the...\n-Definition: amg.hh:80\n-Dune::Amg::DirectSolverSelector::none\n-@ none\n-Definition: amg.hh:627\n-Dune::Amg::DirectSolverSelector::umfpack\n-@ umfpack\n-Definition: amg.hh:627\n-Dune::Amg::DirectSolverSelector::superlu\n-@ superlu\n-Definition: amg.hh:627\n-Dune::Amg::atOnceAccu\n-@ atOnceAccu\n-Accumulate data to one process at once.\n-Definition: parameters.hh:244\n-Dune::Amg::noAccu\n-@ noAccu\n-No data accumulution.\n-Definition: parameters.hh:238\n-Dune::Amg::successiveAccu\n-@ successiveAccu\n-Successively accumulate to fewer processes.\n-Definition: parameters.hh:248\n Dune\n Definition: allocator.hh:11\n-Dune::DUNE_REGISTER_PRECONDITIONER\n-DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator())\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator\n-ConstIterator class for sequential access.\n-Definition: matrix.hh:404\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::field_type\n-typename Imp::BlockTraits< T >::field_type field_type\n-Export the type representing the underlying field.\n-Definition: matrix.hh:565\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n-Dune::Matrix::block_type\n-T block_type\n-Export the type representing the components.\n-Definition: matrix.hh:568\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n-Dune::NonoverlappingSchwarzOperator\n-A nonoverlapping operator with communication object.\n-Definition: novlpschwarz.hh:61\n-Dune::MatrixAdapter\n-Adapter to turn a matrix into a linear operator.\n-Definition: operators.hh:137\n-Dune::Amg::Diagonal<_0_>\n-Dune::Amg::RowSum\n-Functor using the row sum (infinity) norm to determine strong couplings.\n-Definition: aggregates.hh:463\n-Dune::Amg::FrobeniusNorm\n-Definition: aggregates.hh:480\n-Dune::Amg::AlwaysOneNorm\n-Definition: aggregates.hh:496\n-Dune::Amg::SymmetricCriterion\n-Criterion taking advantage of symmetric matrices.\n-Definition: aggregates.hh:519\n-Dune::Amg::UnSymmetricCriterion\n-Criterion suitable for unsymmetric matrices.\n-Definition: aggregates.hh:539\n-Dune::Amg::KAMG\n-an algebraic multigrid method using a Krylov-cycle.\n-Definition: kamg.hh:140\n-Dune::Amg::KAmgTwoGrid\n-Two grid operator for AMG with Krylov cycle.\n-Definition: kamg.hh:33\n-Dune::Amg::AMG\n-Parallel algebraic multigrid based on agglomeration.\n-Definition: amg.hh:65\n-Dune::Amg::DirectSolverSelector\n-Definition: amg.hh:625\n-Dune::Amg::DirectSolverSelector::Solver\n-Definition: amg.hh:642\n-Dune::AMGCreator\n-Definition: amg.hh:1169\n-Dune::AMGCreator::isValidBlockType\n-Definition: amg.hh:1170\n-Dune::OverlappingSchwarzOperator\n-An overlapping Schwarz operator.\n-Definition: schwarz.hh:75\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n-LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n-> Iterator\n-Type of the mutable iterator.\n-Definition: hierarchy.hh:216\n-Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n-LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n-MatrixOperator > ConstIterator\n-Type of the const iterator.\n-Definition: hierarchy.hh:219\n-Dune::Amg::MatrixHierarchy\n-The hierarchies build by the coarsening process.\n-Definition: matrixhierarchy.hh:61\n-Dune::Amg::CoarsenCriterion\n-The criterion describing the stop criteria for the coarsening process.\n-Definition: matrixhierarchy.hh:283\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::SmootherTraits\n-Traits class for getting the attribute class of a smoother.\n-Definition: smoother.hh:66\n-Dune::Amg::Transfer::restrictVector\n-static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, const Vector &fine, T &comm)\n-Dune::Amg::Transfer::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::Preconditioner<_X,_X_>::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioner.hh:39\n-Dune::ScalarProduct\n-Base class for scalar product and norm computation.\n-Definition: scalarproducts.hh:52\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperatorResult::converged\n-bool converged\n-True if convergence criterion has been met.\n-Definition: solver.hh:73\n-Dune::InverseOperator<_X,_X_>\n-Dune::SolverCategory\n-Categories for the solvers.\n-Definition: solvercategory.hh:22\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n-Dune::InvalidSolverCategory\n-Definition: solvercategory.hh:54\n-Dune::UnsupportedType\n-Definition: solverregistry.hh:77\n-Dune::IsDirectSolver\n-Definition: solvertype.hh:16\n-Dune::SuperLU\n-SuperLu Solver.\n-Definition: superlu.hh:271\n-Dune::UMFPackMethodChooser\n-Definition: umfpack.hh:49\n-Dune::UMFPack\n-The UMFPack direct sparse solver.\n-Definition: umfpack.hh:215\n+Dune::ILU::blockILUBacksolve\n+void blockILUBacksolve(const M &A, X &v, const Y &d)\n+LU backsolve with stored inverse.\n+Definition: ilu.hh:94\n+Dune::ILU::blockILU0Decomposition\n+void blockILU0Decomposition(M &A)\n+compute ILU decomposition of A. A is overwritten by its decomposition\n+Definition: ilu.hh:33\n+Dune::ILU::blockILUDecomposition\n+void blockILUDecomposition(const M &A, int n, M &ILU)\n+Definition: ilu.hh:167\n+Dune::ILUSubdomainSolver\n+base class encapsulating common algorithms of ILU0SubdomainSolver and\n+ILUNSubdomainSolver.\n+Definition: ilusubdomainsolver.hh:36\n+Dune::ILUSubdomainSolver::ILU\n+matrix_type ILU\n+The ILU0 decomposition of the matrix, or the local matrix.\n+Definition: ilusubdomainsolver.hh:67\n+Dune::ILUSubdomainSolver::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:41\n+Dune::ILUSubdomainSolver::~ILUSubdomainSolver\n+virtual ~ILUSubdomainSolver()\n+Definition: ilusubdomainsolver.hh:53\n+Dune::ILUSubdomainSolver::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:43\n+Dune::ILUSubdomainSolver::matrix_type\n+std::remove_const< M >::type matrix_type\n+The matrix type the preconditioner is for.\n+Definition: ilusubdomainsolver.hh:39\n+Dune::ILUSubdomainSolver::apply\n+virtual void apply(X &v, const Y &d)=0\n+Apply the subdomain solver.\n+Dune::ILU0SubdomainSolver\n+Exact subdomain solver using ILU(p) with appropriate p.\n+Definition: ilusubdomainsolver.hh:78\n+Dune::ILU0SubdomainSolver::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:84\n+Dune::ILU0SubdomainSolver::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:86\n+Dune::ILU0SubdomainSolver::rilu_type\n+std::remove_const< M >::type rilu_type\n+Definition: ilusubdomainsolver.hh:82\n+Dune::ILU0SubdomainSolver::matrix_type\n+std::remove_const< M >::type matrix_type\n+The matrix type the preconditioner is for.\n+Definition: ilusubdomainsolver.hh:81\n+Dune::ILU0SubdomainSolver::apply\n+void apply(X &v, const Y &d)\n+Apply the subdomain solver.\n+Definition: ilusubdomainsolver.hh:93\n+Dune::ILUNSubdomainSolver\n+Definition: ilusubdomainsolver.hh:111\n+Dune::ILUNSubdomainSolver::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:117\n+Dune::ILUNSubdomainSolver::matrix_type\n+std::remove_const< M >::type matrix_type\n+The matrix type the preconditioner is for.\n+Definition: ilusubdomainsolver.hh:114\n+Dune::ILUNSubdomainSolver::rilu_type\n+std::remove_const< M >::type rilu_type\n+Definition: ilusubdomainsolver.hh:115\n+Dune::ILUNSubdomainSolver::apply\n+void apply(X &v, const Y &d)\n+Apply the subdomain solver.\n+Definition: ilusubdomainsolver.hh:125\n+Dune::ILUNSubdomainSolver::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: ilusubdomainsolver.hh:119\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00128.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00128.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: transfer.hh File Reference\n+dune-istl: istlexception.hh File Reference\n \n \n \n \n \n \n \n@@ -58,55 +58,52 @@\n \n \n \n \n \n
    \n \n- \n+
    istlexception.hh File Reference
    \n
    \n
    \n-\n-

    Prolongation and restriction for amg. \n-More...

    \n-
    #include <dune/istl/bvector.hh>
    \n-#include <dune/istl/matrixredistribute.hh>
    \n-#include <dune/istl/paamg/pinfo.hh>
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n-#include <dune/istl/paamg/aggregates.hh>
    \n-#include <dune/common/exceptions.hh>
    \n+
    #include <dune/common/exceptions.hh>
    \n+#include <dune/common/fmatrix.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n \n-\n+\n+\n \n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::Transfer< V1, V2, T >
    class  Dune::ISTLError
     derive error class from the base class in common More...
     
    class  Dune::BCRSMatrixError
     Error specific to BCRSMatrix. More...
     
    class  Dune::Amg::Transfer< V, V1, SequentialInformation >
    class  Dune::ImplicitModeCompressionBufferExhausted
     Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted. More...
     
    class  Dune::Amg::Transfer< V, V1, OwnerOverlapCopyCommunication< T1, T2 > >
    class  Dune::SolverAbort
     Thrown when a solver aborts due to some problem. More...
     
    class  Dune::MatrixBlockError
     Error when performing an operation on a matrix block. More...
     
    \n \n \n \n-\n-\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Prolongation and restriction for amg.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,39 +4,35 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n Classes | Namespaces\n-transfer.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Prolongation and restriction for amg. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n+istlexception.hh File Reference\n #include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::Transfer<_V1,_V2,_T_>\n+class \u00a0Dune::ISTLError\n+\u00a0 derive error class from the base class in common More...\n \u00a0\n-class \u00a0Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>\n+class \u00a0Dune::BCRSMatrixError\n+\u00a0 Error specific to BCRSMatrix. More...\n \u00a0\n-class \u00a0Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>\n+class \u00a0Dune::ImplicitModeCompressionBufferExhausted\n+\u00a0 Thrown when the compression buffer used by the implicit BCRSMatrix\n+ construction is exhausted. More...\n+\u00a0\n+class \u00a0Dune::SolverAbort\n+\u00a0 Thrown when a solver aborts due to some problem. More...\n+\u00a0\n+class \u00a0Dune::MatrixBlockError\n+\u00a0 Error when performing an operation on a matrix block. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n-\u00a0\n-***** Detailed Description *****\n-Prolongation and restriction for amg.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00128_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00128_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: transfer.hh Source File\n+dune-istl: istlexception.hh Source File\n \n \n \n \n \n \n \n@@ -58,231 +58,63 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • \n
    \n \n
    \n-
    transfer.hh
    \n+
    istlexception.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMGTRANSFER_HH
    \n-
    6#define DUNE_AMGTRANSFER_HH
    \n+
    5#ifndef DUNE_ISTL_ISTLEXCEPTION_HH
    \n+
    6#define DUNE_ISTL_ISTLEXCEPTION_HH
    \n
    7
    \n-\n-\n-\n-\n-\n-
    13#include <dune/common/exceptions.hh>
    \n-
    14
    \n-
    15namespace Dune
    \n-
    16{
    \n-
    17 namespace Amg
    \n-
    18 {
    \n-
    19
    \n-
    30 template<class V1, class V2, class T>
    \n-\n-
    32 {
    \n-
    33
    \n-
    34 public:
    \n-
    35 typedef V1 Vertex;
    \n-
    36 typedef V2 Vector;
    \n-
    37
    \n-
    38 template<typename T1, typename R>
    \n-
    39 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-
    40 Vector& fineRedist,T1 damp, R& redistributor=R());
    \n-
    41
    \n-
    42 template<typename T1, typename R>
    \n-
    43 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-
    44 T1 damp);
    \n-
    45
    \n-
    46 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n-
    47 T& comm);
    \n-
    48 };
    \n+
    8#include <dune/common/exceptions.hh>
    \n+
    9#include <dune/common/fmatrix.hh>
    \n+
    10
    \n+
    11namespace Dune {
    \n+
    12
    \n+
    19 class ISTLError : public Dune::MathError {};
    \n+
    20
    \n+\n+
    23 : public ISTLError
    \n+
    24 {};
    \n+
    25
    \n+\n+
    36 : public BCRSMatrixError
    \n+
    37 {};
    \n+
    38
    \n+
    40
    \n+
    46 class SolverAbort : public ISTLError {};
    \n+
    47
    \n
    49
    \n-
    50 template<class V,class V1>
    \n-\n-
    52 {
    \n-
    53 public:
    \n-
    54 typedef V Vertex;
    \n-
    55 typedef V1 Vector;
    \n-\n-
    57 template<typename T1>
    \n-
    58 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-
    59 Vector& fineRedist, T1 damp,
    \n-\n-
    61 const Redist& redist=Redist());
    \n-
    62 template<typename T1>
    \n-
    63 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-
    64 T1 damp,
    \n-\n-
    66
    \n-
    67
    \n-
    68 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n-
    69 const SequentialInformation& comm);
    \n-
    70 };
    \n-
    71
    \n-
    72#if HAVE_MPI
    \n-
    73
    \n-
    74 template<class V,class V1, class T1, class T2>
    \n-\n-
    76 {
    \n-
    77 public:
    \n-
    78 typedef V Vertex;
    \n-
    79 typedef V1 Vector;
    \n-\n-
    81 template<typename T3>
    \n-
    82 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-
    83 Vector& fineRedist, T3 damp, OwnerOverlapCopyCommunication<T1,T2>& comm,
    \n-
    84 const Redist& redist);
    \n-
    85 template<typename T3>
    \n-
    86 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n-\n-
    88
    \n-
    89 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n-\n-
    91 };
    \n-
    92
    \n-
    93#endif
    \n-
    94
    \n-
    95 template<class V, class V1>
    \n-
    96 template<typename T>
    \n-
    97 inline void
    \n-\n-
    99 Vector& coarse, Vector& fine,
    \n-
    100 [[maybe_unused]] Vector& fineRedist,
    \n-
    101 T damp,
    \n-
    102 [[maybe_unused]] const SequentialInformation& comm,
    \n-
    103 [[maybe_unused]] const Redist& redist)
    \n-
    104 {
    \n-
    105 prolongateVector(aggregates, coarse, fine, damp);
    \n-
    106 }
    \n-
    107 template<class V, class V1>
    \n-
    108 template<typename T>
    \n-
    109 inline void
    \n-\n-
    111 Vector& coarse, Vector& fine,
    \n-
    112 T damp,
    \n-
    113 [[maybe_unused]] const SequentialInformation& comm)
    \n-
    114 {
    \n-
    115 typedef typename Vector::iterator Iterator;
    \n-
    116
    \n-
    117 Iterator end = coarse.end();
    \n-
    118 Iterator begin= coarse.begin();
    \n-
    119 for(; begin!=end; ++begin)
    \n-
    120 *begin*=damp;
    \n-
    121 end=fine.end();
    \n-
    122 begin=fine.begin();
    \n-
    123
    \n-
    124 for(Iterator block=begin; block != end; ++block) {
    \n-
    125 std::ptrdiff_t index=block-begin;
    \n-
    126 const Vertex& vertex = aggregates[index];
    \n-\n-
    128 *block += coarse[aggregates[index]];
    \n-
    129 }
    \n-
    130 }
    \n-
    131
    \n-
    132 template<class V, class V1>
    \n-
    133 inline void
    \n-\n-
    135 Vector& coarse,
    \n-
    136 const Vector& fine,
    \n-
    137 [[maybe_unused]] const SequentialInformation& comm)
    \n-
    138 {
    \n-
    139 // Set coarse vector to zero
    \n-
    140 coarse=0;
    \n-
    141
    \n-
    142 typedef typename Vector::const_iterator Iterator;
    \n-
    143 Iterator end = fine.end();
    \n-
    144 Iterator begin=fine.begin();
    \n-
    145
    \n-
    146 for(Iterator block=begin; block != end; ++block) {
    \n-
    147 const Vertex& vertex = aggregates[block-begin];
    \n-\n-
    149 coarse[vertex] += *block;
    \n-
    150 }
    \n-
    151 }
    \n-
    152
    \n-
    153#if HAVE_MPI
    \n-
    154 template<class V, class V1, class T1, class T2>
    \n-
    155 template<typename T3>
    \n-
    156 inline void Transfer<V,V1,OwnerOverlapCopyCommunication<T1,T2> >::prolongateVector(const AggregatesMap<Vertex>& aggregates,
    \n-
    157 Vector& coarse, Vector& fine,
    \n-
    158 Vector& fineRedist, T3 damp,
    \n-\n-
    160 const Redist& redist)
    \n-
    161 {
    \n-
    162 if(fineRedist.size()>0)
    \n-
    163 // we operated on the coarse level
    \n-
    164 Transfer<V,V1,SequentialInformation>::prolongateVector(aggregates, coarse, fineRedist, damp);
    \n-
    165
    \n-
    166 // TODO This could be accomplished with one communication, too!
    \n-
    167 redist.redistributeBackward(fine, fineRedist);
    \n-
    168 comm.copyOwnerToAll(fine,fine);
    \n-
    169 }
    \n-
    170
    \n-
    171 template<class V, class V1, class T1, class T2>
    \n-
    172 template<typename T3>
    \n-\n-
    174 const AggregatesMap<Vertex>& aggregates,
    \n-
    175 Vector& coarse, Vector& fine, T3 damp,
    \n-
    176 [[maybe_unused]] OwnerOverlapCopyCommunication<T1,T2>& comm)
    \n-
    177 {
    \n-
    178 Transfer<V,V1,SequentialInformation>::prolongateVector(aggregates, coarse, fine, damp);
    \n-
    179 }
    \n-
    180 template<class V, class V1, class T1, class T2>
    \n-
    181 inline void Transfer<V,V1,OwnerOverlapCopyCommunication<T1,T2> >::restrictVector(const AggregatesMap<Vertex>& aggregates,
    \n-
    182 Vector& coarse, const Vector& fine,
    \n-\n-
    184 {
    \n-\n-
    186 // We need this here to avoid it in the smoothers on the coarse level.
    \n-
    187 // There (in the preconditioner d is const.
    \n-
    188 comm.project(coarse);
    \n-
    189 }
    \n-
    190#endif
    \n-
    192 } // namspace Amg
    \n-
    193} // namspace Dune
    \n-
    194#endif
    \n-
    Functionality for redistributing a sparse matrix.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Provides classes for the Coloring process of AMG.
    \n-\n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    52 class MatrixBlockError : public virtual Dune::FMatrixError {
    \n+
    53 public:
    \n+
    54 int r, c; // row and column index of the entry from which the error resulted
    \n+
    55 };
    \n+
    56
    \n+
    59} // end namespace
    \n+
    60
    \n+
    61#endif
    \n
    Definition: allocator.hh:11
    \n-
    Definition: matrixredistribute.hh:22
    \n-
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:32
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    void project(T1 &x) const
    Set vector to zero at copy dofs.
    Definition: owneroverlapcopy.hh:538
    \n-
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n-\n-
    Definition: pinfo.hh:28
    \n-
    Definition: transfer.hh:32
    \n-
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, T1 damp)
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n-
    V1 Vertex
    Definition: transfer.hh:35
    \n-
    V2 Vector
    Definition: transfer.hh:36
    \n-
    RedistributeInformation< SequentialInformation > Redist
    Definition: transfer.hh:56
    \n-\n-\n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, const SequentialInformation &comm=SequentialInformation(), const Redist &redist=Redist())
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, T1 damp, const SequentialInformation &comm=SequentialInformation())
    \n-\n-
    RedistributeInformation< OwnerOverlapCopyCommunication< T1, T2 > > Redist
    Definition: transfer.hh:80
    \n-\n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    Error specific to BCRSMatrix.
    Definition: istlexception.hh:24
    \n+
    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted.
    Definition: istlexception.hh:37
    \n+
    Thrown when a solver aborts due to some problem.
    Definition: istlexception.hh:46
    \n+
    Error when performing an operation on a matrix block.
    Definition: istlexception.hh:52
    \n+
    int c
    Definition: istlexception.hh:54
    \n+
    int r
    Definition: istlexception.hh:54
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,291 +4,71 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n- * paamg\n-transfer.hh\n+istlexception.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMGTRANSFER_HH\n- 6#define DUNE_AMGTRANSFER_HH\n+ 5#ifndef DUNE_ISTL_ISTLEXCEPTION_HH\n+ 6#define DUNE_ISTL_ISTLEXCEPTION_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14\n- 15namespace Dune\n- 16{\n- 17 namespace Amg\n- 18 {\n- 19\n- 30 template\n-31 class Transfer\n- 32 {\n- 33\n- 34 public:\n-35 typedef V1 Vertex;\n-36 typedef V2 Vector;\n- 37\n- 38 template\n-39 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 40 Vector& fineRedist,T1 damp, R& redistributor=R());\n- 41\n- 42 template\n-43 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 44 T1 damp);\n- 45\n-46 static void restrictVector(const AggregatesMap& aggregates, Vector&\n-coarse, const Vector& fine,\n- 47 T& comm);\n- 48 };\n+ 8#include \n+ 9#include \n+ 10\n+ 11namespace Dune {\n+ 12\n+19 class ISTLError : public Dune::MathError {};\n+ 20\n+22 class BCRSMatrixError\n+ 23 : public ISTLError\n+ 24 {};\n+ 25\n+35 class ImplicitModeCompressionBufferExhausted\n+ 36 : public BCRSMatrixError\n+ 37 {};\n+ 38\n+ 40\n+46 class SolverAbort : public ISTLError {};\n+ 47\n 49\n- 50 template\n-51 class Transfer\n- 52 {\n+52 class MatrixBlockError : public virtual Dune::FMatrixError {\n 53 public:\n-54 typedef V Vertex;\n-55 typedef V1 Vector;\n-56 typedef RedistributeInformation Redist;\n- 57 template\n-58 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 59 Vector& fineRedist, T1 damp,\n- 60 const SequentialInformation& comm=SequentialInformation(),\n- 61 const Redist& redist=Redist());\n- 62 template\n-63 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 64 T1 damp,\n- 65 const SequentialInformation& comm=SequentialInformation());\n- 66\n- 67\n- 68 static void restrictVector(const AggregatesMap& aggregates, Vector&\n-coarse, const Vector& fine,\n- 69 const SequentialInformation& comm);\n- 70 };\n- 71\n- 72#if HAVE_MPI\n- 73\n- 74 template\n-75 class Transfer >\n- 76 {\n- 77 public:\n-78 typedef V Vertex;\n-79 typedef V1 Vector;\n-80 typedef RedistributeInformation >\n-Redist;\n- 81 template\n- 82 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 83 Vector& fineRedist, T3 damp, OwnerOverlapCopyCommunication& comm,\n- 84 const Redist& redist);\n- 85 template\n- 86 static void prolongateVector(const AggregatesMap& aggregates,\n-Vector& coarse, Vector& fine,\n- 87 T3 damp, OwnerOverlapCopyCommunication& comm);\n- 88\n- 89 static void restrictVector(const AggregatesMap& aggregates, Vector&\n-coarse, const Vector& fine,\n- 90 OwnerOverlapCopyCommunication& comm);\n- 91 };\n- 92\n- 93#endif\n- 94\n- 95 template\n- 96 template\n- 97 inline void\n-98 Transfer::prolongateVector(const\n-AggregatesMap& aggregates,\n- 99 Vector& coarse, Vector& fine,\n- 100 [[maybe_unused]] Vector& fineRedist,\n- 101 T damp,\n- 102 [[maybe_unused]] const SequentialInformation& comm,\n- 103 [[maybe_unused]] const Redist& redist)\n- 104 {\n- 105 prolongateVector(aggregates, coarse, fine, damp);\n- 106 }\n- 107 template\n- 108 template\n- 109 inline void\n-110 Transfer::prolongateVector(const\n-AggregatesMap& aggregates,\n- 111 Vector& coarse, Vector& fine,\n- 112 T damp,\n- 113 [[maybe_unused]] const SequentialInformation& comm)\n- 114 {\n- 115 typedef typename Vector::iterator Iterator;\n- 116\n- 117 Iterator end = coarse.end();\n- 118 Iterator begin= coarse.begin();\n- 119 for(; begin!=end; ++begin)\n- 120 *begin*=damp;\n- 121 end=fine.end();\n- 122 begin=fine.begin();\n- 123\n- 124 for(Iterator block=begin; block != end; ++block) {\n- 125 std::ptrdiff_t index=block-begin;\n- 126 const Vertex& vertex = aggregates[index];\n- 127 if(vertex != AggregatesMap::ISOLATED)\n- 128 *block += coarse[aggregates[index]];\n- 129 }\n- 130 }\n- 131\n- 132 template\n- 133 inline void\n-134 Transfer::restrictVector(const\n-AggregatesMap& aggregates,\n- 135 Vector& coarse,\n- 136 const Vector& fine,\n- 137 [[maybe_unused]] const SequentialInformation& comm)\n- 138 {\n- 139 // Set coarse vector to zero\n- 140 coarse=0;\n- 141\n- 142 typedef typename Vector::const_iterator Iterator;\n- 143 Iterator end = fine.end();\n- 144 Iterator begin=fine.begin();\n- 145\n- 146 for(Iterator block=begin; block != end; ++block) {\n- 147 const Vertex& vertex = aggregates[block-begin];\n- 148 if(vertex != AggregatesMap::ISOLATED)\n- 149 coarse[vertex] += *block;\n- 150 }\n- 151 }\n- 152\n- 153#if HAVE_MPI\n- 154 template\n- 155 template\n-156 inline void Transfer >::\n-prolongateVector(const AggregatesMap& aggregates,\n- 157 Vector& coarse, Vector& fine,\n- 158 Vector& fineRedist, T3 damp,\n- 159 OwnerOverlapCopyCommunication& comm,\n- 160 const Redist& redist)\n- 161 {\n- 162 if(fineRedist.size()>0)\n- 163 // we operated on the coarse level\n- 164 Transfer::prolongateVector(aggregates, coarse,\n-fineRedist, damp);\n- 165\n- 166 // TODO This could be accomplished with one communication, too!\n- 167 redist.redistributeBackward(fine, fineRedist);\n- 168 comm.copyOwnerToAll(fine,fine);\n- 169 }\n- 170\n- 171 template\n- 172 template\n-173 inline void Transfer >::\n-prolongateVector(\n- 174 const AggregatesMap& aggregates,\n- 175 Vector& coarse, Vector& fine, T3 damp,\n- 176 [[maybe_unused]] OwnerOverlapCopyCommunication& comm)\n- 177 {\n- 178 Transfer::prolongateVector(aggregates, coarse,\n-fine, damp);\n- 179 }\n- 180 template\n-181 inline void Transfer >::\n-restrictVector(const AggregatesMap& aggregates,\n- 182 Vector& coarse, const Vector& fine,\n- 183 OwnerOverlapCopyCommunication& comm)\n- 184 {\n- 185 Transfer::restrictVector(aggregates, coarse,\n-fine, SequentialInformation());\n- 186 // We need this here to avoid it in the smoothers on the coarse level.\n- 187 // There (in the preconditioner d is const.\n- 188 comm.project(coarse);\n- 189 }\n- 190#endif\n- 192 } // namspace Amg\n- 193} // namspace Dune\n- 194#endif\n-matrixredistribute.hh\n-Functionality for redistributing a sparse matrix.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n-pinfo.hh\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n+54 int r, c; // row and column index of the entry from which the error resulted\n+ 55 };\n+ 56\n+ 59} // end namespace\n+ 60\n+ 61#endif\n Dune\n Definition: allocator.hh:11\n-Dune::RedistributeInformation\n-Definition: matrixredistribute.hh:22\n-Dune::RedistributeInformation::redistributeBackward\n-void redistributeBackward(D &from, const D &to) const\n-Definition: matrixredistribute.hh:32\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::project\n-void project(T1 &x) const\n-Set vector to zero at copy dofs.\n-Definition: owneroverlapcopy.hh:538\n-Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n-void copyOwnerToAll(const T &source, T &dest) const\n-Communicate values from owner data points to all other data points.\n-Definition: owneroverlapcopy.hh:311\n-Dune::Amg::AggregatesMap<_Vertex_>\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::Transfer\n-Definition: transfer.hh:32\n-Dune::Amg::Transfer::restrictVector\n-static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, const Vector &fine, T &comm)\n-Dune::Amg::Transfer::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, T1 damp)\n-Dune::Amg::Transfer::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n-Dune::Amg::Transfer::Vertex\n-V1 Vertex\n-Definition: transfer.hh:35\n-Dune::Amg::Transfer::Vector\n-V2 Vector\n-Definition: transfer.hh:36\n-Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Redist\n-RedistributeInformation< SequentialInformation > Redist\n-Definition: transfer.hh:56\n-Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Vertex\n-V Vertex\n-Definition: transfer.hh:54\n-Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Vector\n-V1 Vector\n-Definition: transfer.hh:55\n-Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, Vector &fineRedist, T1 damp, const SequentialInformation\n-&comm=SequentialInformation(), const Redist &redist=Redist())\n-Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, T1 damp, const SequentialInformation\n-&comm=SequentialInformation())\n-Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Vertex\n-V Vertex\n-Definition: transfer.hh:78\n-Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Redist\n-RedistributeInformation< OwnerOverlapCopyCommunication< T1, T2 > > Redist\n-Definition: transfer.hh:80\n-Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Vector\n-V1 Vector\n-Definition: transfer.hh:79\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::BCRSMatrixError\n+Error specific to BCRSMatrix.\n+Definition: istlexception.hh:24\n+Dune::ImplicitModeCompressionBufferExhausted\n+Thrown when the compression buffer used by the implicit BCRSMatrix construction\n+is exhausted.\n+Definition: istlexception.hh:37\n+Dune::SolverAbort\n+Thrown when a solver aborts due to some problem.\n+Definition: istlexception.hh:46\n+Dune::MatrixBlockError\n+Error when performing an operation on a matrix block.\n+Definition: istlexception.hh:52\n+Dune::MatrixBlockError::c\n+int c\n+Definition: istlexception.hh:54\n+Dune::MatrixBlockError::r\n+int r\n+Definition: istlexception.hh:54\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00131.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00131.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: pinfo.hh File Reference\n+dune-istl: aggregates.hh File Reference\n \n \n \n \n \n \n \n@@ -64,41 +64,111 @@\n \n \n \n
    \n \n-
    pinfo.hh File Reference
    \n+Namespaces |\n+Functions
    \n+ \n \n
    \n-
    #include <dune/common/parallel/communication.hh>
    \n-#include <dune/common/enumset.hh>
    \n-#include <dune/common/parallel/mpicommunication.hh>
    \n-#include <dune/common/parallel/mpitraits.hh>
    \n-#include <dune/common/parallel/remoteindices.hh>
    \n-#include <dune/common/parallel/interface.hh>
    \n-#include <dune/common/parallel/communicator.hh>
    \n-#include <dune/istl/solvercategory.hh>
    \n+\n+

    Provides classes for the Coloring process of AMG. \n+More...

    \n+
    #include "parameters.hh"
    \n+#include "graph.hh"
    \n+#include "properties.hh"
    \n+#include "combinedfunctor.hh"
    \n+#include <dune/common/timer.hh>
    \n+#include <dune/common/stdstreams.hh>
    \n+#include <dune/common/poolallocator.hh>
    \n+#include <dune/common/sllist.hh>
    \n+#include <dune/common/ftraits.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <utility>
    \n+#include <set>
    \n+#include <algorithm>
    \n+#include <complex>
    \n+#include <limits>
    \n+#include <ostream>
    \n+#include <tuple>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::SequentialInformation
    class  Dune::Amg::AggregationCriterion< T >
     Base class of all aggregation criterions. More...
     
    class  Dune::Amg::SymmetricMatrixDependency< M, N >
     Dependency policy for symmetric matrices. More...
     
    class  Dune::Amg::Dependency< M, N >
     Dependency policy for symmetric matrices. More...
     
    class  Dune::Amg::SymmetricDependency< M, N >
     Dependency policy for symmetric matrices. More...
     
    class  Dune::Amg::Diagonal< N >
     Norm that uses only the [N][N] entry of the block to determine couplings. More...
     
    class  Dune::Amg::FirstDiagonal
     Norm that uses only the [0][0] entry of the block to determine couplings. More...
     
    struct  Dune::Amg::RowSum
     Functor using the row sum (infinity) norm to determine strong couplings. More...
     
    struct  Dune::Amg::FrobeniusNorm
     
    struct  Dune::Amg::AlwaysOneNorm
     
    class  Dune::Amg::SymmetricCriterion< M, Norm >
     Criterion taking advantage of symmetric matrices. More...
     
    class  Dune::Amg::UnSymmetricCriterion< M, Norm >
     Criterion suitable for unsymmetric matrices. More...
     
    class  Dune::Amg::AggregatesMap< V >
     Class providing information about the mapping of the vertices onto aggregates. More...
     
    class  Dune::Amg::AggregatesMap< V >::DummyEdgeVisitor
     A Dummy visitor that does nothing for each visited edge. More...
     
    class  Dune::Amg::Aggregate< G, S >
     A class for temporarily storing the vertices of an aggregate in. More...
     
    class  Dune::Amg::Aggregator< G >
     Class for building the aggregates. More...
     
    \n \n \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<class T >
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const AggregationCriterion< T > &criterion)
     
    template<class G , class C >
    void Dune::Amg::buildDependency (G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
     Build the dependency of the matrix graph. More...
     
    template<class V >
    void Dune::Amg::printAggregates2d (const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)
     
    \n-
    \n+

    Detailed Description

    \n+

    Provides classes for the Coloring process of AMG.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,29 +5,105 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces\n-pinfo.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces | Functions\n+aggregates.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides classes for the Coloring process of AMG. More...\n+#include \"parameters.hh\"\n+#include \"graph.hh\"\n+#include \"properties.hh\"\n+#include \"combinedfunctor.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::SequentialInformation\n+ class \u00a0Dune::Amg::AggregationCriterion<_T_>\n+\u00a0 Base class of all aggregation criterions. More...\n+\u00a0\n+ class \u00a0Dune::Amg::SymmetricMatrixDependency<_M,_N_>\n+\u00a0 Dependency policy for symmetric matrices. More...\n+\u00a0\n+ class \u00a0Dune::Amg::Dependency<_M,_N_>\n+\u00a0 Dependency policy for symmetric matrices. More...\n+\u00a0\n+ class \u00a0Dune::Amg::SymmetricDependency<_M,_N_>\n+\u00a0 Dependency policy for symmetric matrices. More...\n+\u00a0\n+ class \u00a0Dune::Amg::Diagonal<_N_>\n+\u00a0 Norm that uses only the [N][N] entry of the block to determine\n+ couplings. More...\n+\u00a0\n+ class \u00a0Dune::Amg::FirstDiagonal\n+\u00a0 Norm that uses only the [0][0] entry of the block to determine\n+ couplings. More...\n+\u00a0\n+struct \u00a0Dune::Amg::RowSum\n+\u00a0 Functor using the row sum (infinity) norm to determine strong\n+ couplings. More...\n+\u00a0\n+struct \u00a0Dune::Amg::FrobeniusNorm\n+\u00a0\n+struct \u00a0Dune::Amg::AlwaysOneNorm\n+\u00a0\n+ class \u00a0Dune::Amg::SymmetricCriterion<_M,_Norm_>\n+\u00a0 Criterion taking advantage of symmetric matrices. More...\n+\u00a0\n+ class \u00a0Dune::Amg::UnSymmetricCriterion<_M,_Norm_>\n+\u00a0 Criterion suitable for unsymmetric matrices. More...\n+\u00a0\n+ class \u00a0Dune::Amg::AggregatesMap<_V_>\n+\u00a0 Class providing information about the mapping of the vertices onto\n+ aggregates. More...\n+\u00a0\n+ class \u00a0Dune::Amg::AggregatesMap<_V_>::DummyEdgeVisitor\n+\u00a0 A Dummy visitor that does nothing for each visited edge. More...\n+\u00a0\n+ class \u00a0Dune::Amg::Aggregate<_G,_S_>\n+\u00a0 A class for temporarily storing the vertices of an aggregate in.\n+ More...\n+\u00a0\n+ class \u00a0Dune::Amg::Aggregator<_G_>\n+\u00a0 Class for building the aggregates. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n+ Functions\n+template\n+std::ostream &\u00a0Dune::Amg::operator<< (std::ostream &os, const\n+ AggregationCriterion< T > &criterion)\n+\u00a0\n+template\n+ void\u00a0Dune::Amg::buildDependency (G &graph, const typename C::Matrix\n+ &matrix, C criterion, bool finestLevel)\n+\u00a0 Build the dependency of the matrix graph. More...\n+\u00a0\n+template\n+ void\u00a0Dune::Amg::printAggregates2d (const AggregatesMap< V >\n+ &aggregates, int n, int m, std::ostream &os)\n+\u00a0\n+***** Detailed Description *****\n+Provides classes for the Coloring process of AMG.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00131_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00131_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: pinfo.hh Source File\n+dune-istl: aggregates.hh Source File\n \n \n \n \n \n \n \n@@ -62,144 +62,2162 @@\n \n
    \n \n
    \n \n
    \n-
    pinfo.hh
    \n+
    aggregates.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_PINFO_HH
    \n-
    6#define DUNE_AMG_PINFO_HH
    \n+
    5#ifndef DUNE_AMG_AGGREGATES_HH
    \n+
    6#define DUNE_AMG_AGGREGATES_HH
    \n
    7
    \n-
    8#include <dune/common/parallel/communication.hh>
    \n-
    9#include <dune/common/enumset.hh>
    \n-
    10
    \n-
    11#if HAVE_MPI
    \n-
    12
    \n-
    13#include <dune/common/parallel/mpicommunication.hh>
    \n-
    14#include <dune/common/parallel/mpitraits.hh>
    \n-
    15#include <dune/common/parallel/remoteindices.hh>
    \n-
    16#include <dune/common/parallel/interface.hh>
    \n-
    17#include <dune/common/parallel/communicator.hh>
    \n-
    18
    \n-
    19#endif
    \n+
    8
    \n+
    9#include "parameters.hh"
    \n+
    10#include "graph.hh"
    \n+
    11#include "properties.hh"
    \n+
    12#include "combinedfunctor.hh"
    \n+
    13
    \n+
    14#include <dune/common/timer.hh>
    \n+
    15#include <dune/common/stdstreams.hh>
    \n+
    16#include <dune/common/poolallocator.hh>
    \n+
    17#include <dune/common/sllist.hh>
    \n+
    18#include <dune/common/ftraits.hh>
    \n+
    19#include <dune/common/scalarmatrixview.hh>
    \n
    20
    \n-\n-
    22namespace Dune
    \n-
    23{
    \n-
    24 namespace Amg
    \n-
    25 {
    \n-
    26
    \n-\n-
    28 {
    \n-
    29 public:
    \n-
    30 typedef Communication<void*> MPICommunicator;
    \n-
    31 typedef EmptySet<int> CopyFlags;
    \n-
    32 typedef AllSet<int> OwnerSet;
    \n+
    21#include <utility>
    \n+
    22#include <set>
    \n+
    23#include <algorithm>
    \n+
    24#include <complex>
    \n+
    25#include <limits>
    \n+
    26#include <ostream>
    \n+
    27#include <tuple>
    \n+
    28
    \n+
    29namespace Dune
    \n+
    30{
    \n+
    31 namespace Amg
    \n+
    32 {
    \n
    33
    \n-\n-\n-
    36 }
    \n-
    37
    \n-\n-
    39 {
    \n-
    40 return comm_;
    \n-
    41 }
    \n-
    42
    \n-
    43 int procs() const
    \n-
    44 {
    \n-
    45 return 1;
    \n-
    46 }
    \n-
    47
    \n-
    48 template<typename T>
    \n-
    49 T globalSum(const T& t) const
    \n-
    50 {
    \n-
    51 return t;
    \n-
    52 }
    \n-
    53
    \n-\n-
    55
    \n-
    56 void buildGlobalLookup(std::size_t){}
    \n-
    57
    \n-\n-
    59
    \n-\n-
    61 {
    \n-
    62 return gli;
    \n-
    63 }
    \n-
    64
    \n-
    65 template<class V>
    \n-
    66 void copyOwnerToAll([[maybe_unused]] V& v, [[maybe_unused]] V& v1) const
    \n-
    67 {}
    \n-
    68
    \n-
    69 template<class V>
    \n-
    70 void project([[maybe_unused]] V& v) const
    \n-
    71 {}
    \n-
    72
    \n-
    73 template<class T1, class T2>
    \n-
    74 void dot (const T1&, const T1&, T2&) const
    \n-
    75 {
    \n-
    76 // This function should never be called
    \n-
    77 std::abort();
    \n-
    78 }
    \n-
    79
    \n-
    80 template<class T1>
    \n-
    81 typename FieldTraits<typename T1::field_type>::real_type norm (const T1&) const
    \n-
    82 {
    \n-
    83 // This function should never be called
    \n-
    84 std::abort();
    \n-
    85 }
    \n+
    47 template<class T>
    \n+
    48 class AggregationCriterion : public T
    \n+
    49 {
    \n+
    50
    \n+
    51 public:
    \n+\n+
    56
    \n+\n+
    67 : T()
    \n+
    68 {}
    \n+
    69
    \n+\n+
    71 : T(parms)
    \n+
    72 {}
    \n+
    82 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    \n+
    83 {
    \n+
    84 this->setMaxDistance(diameter-1);
    \n+
    85 std::size_t csize=1;
    \n
    86
    \n-
    87 template<class T>
    \n-
    88 SequentialInformation(const Communication<T>&)
    \n-
    89 {}
    \n-
    90
    \n-\n-
    92 {}
    \n-
    93
    \n-\n-
    95 {}
    \n-
    96 private:
    \n-
    97 MPICommunicator comm_;
    \n-\n-
    99 };
    \n-
    100
    \n-
    101
    \n-
    102 } // namespace Amg
    \n-
    103} //namespace Dune
    \n-
    104#endif
    \n-\n+
    87 for(; dim>0; dim--) {
    \n+
    88 csize*=diameter;
    \n+
    89 this->setMaxDistance(this->maxDistance()+diameter-1);
    \n+
    90 }
    \n+
    91 this->setMinAggregateSize(csize);
    \n+
    92 this->setMaxAggregateSize(static_cast<std::size_t>(csize*1.5));
    \n+
    93 }
    \n+
    94
    \n+
    105 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)
    \n+
    106 {
    \n+
    107 setDefaultValuesIsotropic(dim, diameter);
    \n+
    108 this->setMaxDistance(this->maxDistance()+dim-1);
    \n+
    109 }
    \n+
    110 };
    \n+
    111
    \n+
    112 template<class T>
    \n+
    113 std::ostream& operator<<(std::ostream& os, const AggregationCriterion<T>& criterion)
    \n+
    114 {
    \n+
    115 os<<"{ maxdistance="<<criterion.maxDistance()<<" minAggregateSize="
    \n+
    116 <<criterion.minAggregateSize()<< " maxAggregateSize="<<criterion.maxAggregateSize()
    \n+
    117 <<" connectivity="<<criterion.maxConnectivity()<<" debugLevel="<<criterion.debugLevel()<<"}";
    \n+
    118 return os;
    \n+
    119 }
    \n+
    120
    \n+
    132 template<class M, class N>
    \n+\n+
    134 {
    \n+
    135 public:
    \n+
    139 typedef M Matrix;
    \n+
    140
    \n+
    144 typedef N Norm;
    \n+
    145
    \n+
    149 typedef typename Matrix::row_type Row;
    \n+
    150
    \n+\n+
    155
    \n+
    156 void init(const Matrix* matrix);
    \n+
    157
    \n+
    158 void initRow(const Row& row, int index);
    \n+
    159
    \n+
    160 void examine(const ColIter& col);
    \n+
    161
    \n+
    162 template<class G>
    \n+
    163 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n+
    164
    \n+
    165 bool isIsolated();
    \n+
    166
    \n+
    167
    \n+\n+
    169 : Parameters(parms)
    \n+
    170 {}
    \n+\n+
    172 : Parameters()
    \n+
    173 {}
    \n+
    174
    \n+
    175 protected:
    \n+\n+\n+
    180 typedef typename FieldTraits<field_type>::real_type real_type;
    \n+\n+\n+
    185 int row_;
    \n+\n+
    188 std::vector<real_type> vals_;
    \n+
    189 typename std::vector<real_type>::iterator valIter_;
    \n+
    190
    \n+
    191 };
    \n+
    192
    \n+
    193
    \n+
    194 template<class M, class N>
    \n+\n+
    196 {
    \n+
    197 matrix_ = matrix;
    \n+
    198 }
    \n+
    199
    \n+
    200 template<class M, class N>
    \n+
    201 inline void SymmetricMatrixDependency<M,N>::initRow(const Row& row, int index)
    \n+
    202 {
    \n+
    203 using std::min;
    \n+
    204 vals_.assign(row.size(), 0.0);
    \n+
    205 assert(vals_.size()==row.size());
    \n+
    206 valIter_=vals_.begin();
    \n+
    207
    \n+
    208 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
    \n+
    209 diagonal_=norm_(row[index]);
    \n+
    210 row_ = index;
    \n+
    211 }
    \n+
    212
    \n+
    213 template<class M, class N>
    \n+\n+
    215 {
    \n+
    216 using std::max;
    \n+
    217 // skip positive offdiagonals if norm preserves sign of them.
    \n+
    218 real_type eij = norm_(*col);
    \n+
    219 if(!N::is_sign_preserving || eij<0) // || eji<0)
    \n+
    220 {
    \n+
    221 *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())[col.index()]);
    \n+
    222 maxValue_ = max(maxValue_, *valIter_);
    \n+
    223 }else
    \n+
    224 *valIter_ =0;
    \n+
    225 ++valIter_;
    \n+
    226 }
    \n+
    227
    \n+
    228 template<class M, class N>
    \n+
    229 template<class G>
    \n+
    230 inline void SymmetricMatrixDependency<M,N>::examine(G&, const typename G::EdgeIterator& edge, const ColIter&)
    \n+
    231 {
    \n+
    232 if(*valIter_ > alpha() * maxValue_) {
    \n+
    233 edge.properties().setDepends();
    \n+
    234 edge.properties().setInfluences();
    \n+
    235 }
    \n+
    236 ++valIter_;
    \n+
    237 }
    \n+
    238
    \n+
    239 template<class M, class N>
    \n+\n+
    241 {
    \n+
    242 if(diagonal_==0)
    \n+
    243 DUNE_THROW(Dune::ISTLError, "No diagonal entry for row "<<row_<<".");
    \n+
    244 valIter_=vals_.begin();
    \n+
    245 return maxValue_ < beta();
    \n+
    246 }
    \n+
    247
    \n+
    251 template<class M, class N>
    \n+
    252 class Dependency : public Parameters
    \n+
    253 {
    \n+
    254 public:
    \n+
    258 typedef M Matrix;
    \n+
    259
    \n+
    263 typedef N Norm;
    \n+
    264
    \n+
    268 typedef typename Matrix::row_type Row;
    \n+
    269
    \n+\n+
    274
    \n+
    275 void init(const Matrix* matrix);
    \n+
    276
    \n+
    277 void initRow(const Row& row, int index);
    \n+
    278
    \n+
    279 void examine(const ColIter& col);
    \n+
    280
    \n+
    281 template<class G>
    \n+
    282 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n+
    283
    \n+\n+
    285
    \n+
    286 Dependency(const Parameters& parms)
    \n+
    287 : Parameters(parms)
    \n+
    288 {}
    \n+
    289
    \n+\n+
    291 : Parameters()
    \n+
    292 {}
    \n+
    293
    \n+
    294 protected:
    \n+\n+\n+
    299 typedef typename FieldTraits<field_type>::real_type real_type;
    \n+\n+\n+
    304 int row_;
    \n+\n+
    307 };
    \n+
    308
    \n+
    312 template<class M, class N>
    \n+\n+
    314 {
    \n+
    315 public:
    \n+
    319 typedef M Matrix;
    \n+
    320
    \n+
    324 typedef N Norm;
    \n+
    325
    \n+
    329 typedef typename Matrix::row_type Row;
    \n+
    330
    \n+\n+
    335
    \n+
    336 void init(const Matrix* matrix);
    \n+
    337
    \n+
    338 void initRow(const Row& row, int index);
    \n+
    339
    \n+
    340 void examine(const ColIter& col);
    \n+
    341
    \n+
    342 template<class G>
    \n+
    343 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
    \n+
    344
    \n+\n+
    346
    \n+
    347
    \n+\n+
    349 : Parameters(parms)
    \n+
    350 {}
    \n+\n+
    352 : Parameters()
    \n+
    353 {}
    \n+
    354
    \n+
    355 protected:
    \n+\n+\n+
    360 typedef typename FieldTraits<field_type>::real_type real_type;
    \n+\n+\n+
    365 int row_;
    \n+\n+
    368 private:
    \n+
    369 void initRow(const Row& row, int index, const std::true_type&);
    \n+
    370 void initRow(const Row& row, int index, const std::false_type&);
    \n+
    371 };
    \n+
    372
    \n+
    377 template<int N>
    \n+\n+
    379 {
    \n+
    380 public:
    \n+
    381 enum { /* @brief We preserve the sign.*/
    \n+
    382 is_sign_preserving = true
    \n+
    383 };
    \n+
    384
    \n+
    389 template<class M>
    \n+
    390 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m,
    \n+
    391 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr) const
    \n+
    392 {
    \n+
    393 typedef typename M::field_type field_type;
    \n+
    394 typedef typename FieldTraits<field_type>::real_type real_type;
    \n+
    395 static_assert( std::is_convertible<field_type, real_type >::value,
    \n+
    396 "use of diagonal norm in AMG not implemented for complex field_type");
    \n+
    397 return m[N][N];
    \n+
    398 // possible implementation for complex types: return signed_abs(m[N][N]);
    \n+
    399 }
    \n+
    400
    \n+
    405 template<class M>
    \n+
    406 auto operator()(const M& m,
    \n+
    407 typename std::enable_if_t<Dune::IsNumber<M>::value>* sfinae = nullptr) const
    \n+
    408 {
    \n+
    409 typedef typename FieldTraits<M>::real_type real_type;
    \n+
    410 static_assert( std::is_convertible<M, real_type >::value,
    \n+
    411 "use of diagonal norm in AMG not implemented for complex field_type");
    \n+
    412 return m;
    \n+
    413 // possible implementation for complex types: return signed_abs(m[N][N]);
    \n+
    414 }
    \n+
    415
    \n+
    416 private:
    \n+
    417
    \n+
    419 template<typename T>
    \n+
    420 static T signed_abs(const T & v)
    \n+
    421 {
    \n+
    422 return v;
    \n+
    423 }
    \n+
    424
    \n+
    426 template<typename T>
    \n+
    427 static T signed_abs(const std::complex<T> & v)
    \n+
    428 {
    \n+
    429 // return sign * abs_value
    \n+
    430 // in case of complex numbers this extends to using the csgn function to determine the sign
    \n+
    431 return csgn(v) * std::abs(v);
    \n+
    432 }
    \n+
    433
    \n+
    435 template<typename T>
    \n+
    436 static T csgn(const T & v)
    \n+
    437 {
    \n+
    438 return (T(0) < v) - (v < T(0));
    \n+
    439 }
    \n+
    440
    \n+
    442 template<typename T>
    \n+
    443 static T csgn(std::complex<T> a)
    \n+
    444 {
    \n+
    445 return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());
    \n+
    446 }
    \n+
    447
    \n+
    448 };
    \n+
    449
    \n+
    454 class FirstDiagonal : public Diagonal<0>
    \n+
    455 {};
    \n+
    456
    \n+
    462 struct RowSum
    \n+
    463 {
    \n+
    464
    \n+
    465 enum { /* @brief We preserve the sign.*/
    \n+
    466 is_sign_preserving = false
    \n+
    467 };
    \n+
    472 template<class M>
    \n+
    473 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n+
    474 {
    \n+
    475 return m.infinity_norm();
    \n+
    476 }
    \n+
    477 };
    \n+
    478
    \n+\n+
    480 {
    \n+
    481
    \n+
    482 enum { /* @brief We preserve the sign.*/
    \n+
    483 is_sign_preserving = false
    \n+
    484 };
    \n+
    489 template<class M>
    \n+
    490 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n+
    491 {
    \n+
    492 return m.frobenius_norm();
    \n+
    493 }
    \n+
    494 };
    \n+\n+
    496 {
    \n+
    497
    \n+
    498 enum { /* @brief We preserve the sign.*/
    \n+
    499 is_sign_preserving = false
    \n+
    500 };
    \n+
    505 template<class M>
    \n+
    506 typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
    \n+
    507 {
    \n+
    508 return 1;
    \n+
    509 }
    \n+
    510 };
    \n+
    517 template<class M, class Norm>
    \n+
    518 class SymmetricCriterion : public AggregationCriterion<SymmetricDependency<M,Norm> >
    \n+
    519 {
    \n+
    520 public:
    \n+\n+\n+
    523 {}
    \n+\n+
    525 {}
    \n+
    526 };
    \n+
    527
    \n+
    528
    \n+
    537 template<class M, class Norm>
    \n+
    538 class UnSymmetricCriterion : public AggregationCriterion<Dependency<M,Norm> >
    \n+
    539 {
    \n+
    540 public:
    \n+\n+\n+
    543 {}
    \n+\n+
    545 {}
    \n+
    546 };
    \n+
    547 // forward declaration
    \n+
    548 template<class G> class Aggregator;
    \n+
    549
    \n+
    550
    \n+
    558 template<class V>
    \n+\n+
    560 {
    \n+
    561 public:
    \n+
    562
    \n+
    566 static const V UNAGGREGATED;
    \n+
    567
    \n+
    571 static const V ISOLATED;
    \n+\n+
    576
    \n+\n+
    581
    \n+
    586 typedef PoolAllocator<VertexDescriptor,100> Allocator;
    \n+
    587
    \n+
    592 typedef SLList<VertexDescriptor,Allocator> VertexList;
    \n+
    593
    \n+\n+
    598 {
    \n+
    599 public:
    \n+
    600 template<class EdgeIterator>
    \n+
    601 void operator()([[maybe_unused]] const EdgeIterator& edge) const
    \n+
    602 {}
    \n+
    603 };
    \n+
    604
    \n+
    605
    \n+\n+
    610
    \n+\n+
    617
    \n+\n+
    622
    \n+
    634 template<class M, class G, class C>
    \n+
    635 std::tuple<int,int,int,int> buildAggregates(const M& matrix, G& graph, const C& criterion,
    \n+
    636 bool finestLevel);
    \n+
    637
    \n+
    655 template<bool reset, class G, class F, class VM>
    \n+
    656 std::size_t breadthFirstSearch(const VertexDescriptor& start,
    \n+
    657 const AggregateDescriptor& aggregate,
    \n+
    658 const G& graph,
    \n+
    659 F& aggregateVisitor,
    \n+
    660 VM& visitedMap) const;
    \n+
    661
    \n+
    685 template<bool remove, bool reset, class G, class L, class F1, class F2, class VM>
    \n+
    686 std::size_t breadthFirstSearch(const VertexDescriptor& start,
    \n+
    687 const AggregateDescriptor& aggregate,
    \n+
    688 const G& graph, L& visited, F1& aggregateVisitor,
    \n+
    689 F2& nonAggregateVisitor,
    \n+
    690 VM& visitedMap) const;
    \n+
    691
    \n+
    697 void allocate(std::size_t noVertices);
    \n+
    698
    \n+
    702 std::size_t noVertices() const;
    \n+
    703
    \n+
    707 void free();
    \n+
    708
    \n+\n+
    715
    \n+\n+
    722
    \n+\n+
    724
    \n+\n+
    726 {
    \n+
    727 return aggregates_;
    \n+
    728 }
    \n+
    729
    \n+\n+
    731 {
    \n+
    732 return aggregates_+noVertices();
    \n+
    733 }
    \n+
    734
    \n+\n+
    736
    \n+\n+
    738 {
    \n+
    739 return aggregates_;
    \n+
    740 }
    \n+
    741
    \n+\n+
    743 {
    \n+
    744 return aggregates_+noVertices();
    \n+
    745 }
    \n+
    746 private:
    \n+
    748 AggregatesMap(const AggregatesMap<V>&) = delete;
    \n+
    750 AggregatesMap<V>& operator=(const AggregatesMap<V>&) = delete;
    \n+
    751
    \n+
    755 AggregateDescriptor* aggregates_;
    \n+
    756
    \n+
    760 std::size_t noVertices_;
    \n+
    761 };
    \n+
    762
    \n+
    766 template<class G, class C>
    \n+
    767 void buildDependency(G& graph,
    \n+
    768 const typename C::Matrix& matrix,
    \n+
    769 C criterion,
    \n+
    770 bool finestLevel);
    \n+
    771
    \n+
    776 template<class G, class S>
    \n+\n+
    778 {
    \n+
    779
    \n+
    780 public:
    \n+
    781
    \n+
    782 /***
    \n+
    783 * @brief The type of the matrix graph we work with.
    \n+
    784 */
    \n+
    785 typedef G MatrixGraph;
    \n+\n+
    790
    \n+
    795 typedef PoolAllocator<Vertex,100> Allocator;
    \n+
    796
    \n+
    801 typedef S VertexSet;
    \n+
    802
    \n+
    804 typedef typename VertexSet::const_iterator const_iterator;
    \n+
    805
    \n+
    809 typedef std::size_t* SphereMap;
    \n+
    810
    \n+\n+
    820 VertexSet& connectivity, std::vector<Vertex>& front_);
    \n+
    821
    \n+\n+
    823 {
    \n+
    824 --id_;
    \n+
    825 }
    \n+
    826
    \n+
    833 void reconstruct(const Vertex& vertex);
    \n+
    834
    \n+
    838 void seed(const Vertex& vertex);
    \n+
    839
    \n+
    843 void add(const Vertex& vertex);
    \n+
    844
    \n+
    845 void add(std::vector<Vertex>& vertex);
    \n+
    849 void clear();
    \n+
    850
    \n+
    854 typename VertexSet::size_type size();
    \n+
    858 typename VertexSet::size_type connectSize();
    \n+
    859
    \n+
    863 int id();
    \n+
    864
    \n+\n+
    867
    \n+\n+
    870
    \n+
    871 private:
    \n+
    875 VertexSet vertices_;
    \n+
    876
    \n+
    881 int id_;
    \n+
    882
    \n+
    886 MatrixGraph& graph_;
    \n+
    887
    \n+
    891 AggregatesMap<Vertex>& aggregates_;
    \n+
    892
    \n+
    896 VertexSet& connected_;
    \n+
    897
    \n+
    901 std::vector<Vertex>& front_;
    \n+
    902 };
    \n+
    903
    \n+
    907 template<class G>
    \n+\n+
    909 {
    \n+
    910 public:
    \n+
    911
    \n+
    915 typedef G MatrixGraph;
    \n+
    916
    \n+\n+
    921
    \n+\n+
    924
    \n+\n+
    929
    \n+\n+
    934
    \n+
    951 template<class M, class C>
    \n+
    952 std::tuple<int,int,int,int> build(const M& m, G& graph,
    \n+
    953 AggregatesMap<Vertex>& aggregates, const C& c,
    \n+
    954 bool finestLevel);
    \n+
    955 private:
    \n+
    960 typedef PoolAllocator<Vertex,100> Allocator;
    \n+
    961
    \n+
    965 typedef SLList<Vertex,Allocator> VertexList;
    \n+
    966
    \n+
    970 typedef std::set<Vertex,std::less<Vertex>,Allocator> VertexSet;
    \n+
    971
    \n+
    975 typedef std::size_t* SphereMap;
    \n+
    976
    \n+
    980 MatrixGraph* graph_;
    \n+
    981
    \n+\n+
    986
    \n+
    990 std::vector<Vertex> front_;
    \n+
    991
    \n+
    995 VertexSet connected_;
    \n+
    996
    \n+
    1000 int size_;
    \n+
    1001
    \n+
    1005 class Stack
    \n+
    1006 {
    \n+
    1007 public:
    \n+
    1008 static const Vertex NullEntry;
    \n+
    1009
    \n+
    1010 Stack(const MatrixGraph& graph,
    \n+
    1011 const Aggregator<G>& aggregatesBuilder,
    \n+
    1012 const AggregatesMap<Vertex>& aggregates);
    \n+\n+\n+
    1015 private:
    \n+
    1016 enum { N = 1300000 };
    \n+
    1017
    \n+
    1019 const MatrixGraph& graph_;
    \n+
    1021 const Aggregator<G>& aggregatesBuilder_;
    \n+
    1023 const AggregatesMap<Vertex>& aggregates_;
    \n+
    1025 int size_;
    \n+
    1026 Vertex maxSize_;
    \n+
    1028 typename MatrixGraph::ConstVertexIterator begin_;
    \n+\n+
    1030
    \n+
    1032 Vertex* vals_;
    \n+
    1033
    \n+
    1034 };
    \n+
    1035
    \n+
    1036 friend class Stack;
    \n+
    1037
    \n+
    1048 template<class V>
    \n+
    1049 void visitAggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n+
    1050 const AggregatesMap<Vertex>& aggregates,
    \n+
    1051 V& visitor) const;
    \n+
    1052
    \n+
    1057 template<class V>
    \n+
    1058 class AggregateVisitor
    \n+
    1059 {
    \n+
    1060 public:
    \n+
    1064 typedef V Visitor;
    \n+\n+
    1073 Visitor& visitor);
    \n+
    1074
    \n+
    1081 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1082
    \n+
    1083 private:
    \n+
    1085 const AggregatesMap<Vertex>& aggregates_;
    \n+
    1087 AggregateDescriptor aggregate_;
    \n+
    1089 Visitor* visitor_;
    \n+
    1090 };
    \n+
    1091
    \n+
    1095 class Counter
    \n+
    1096 {
    \n+
    1097 public:
    \n+\n+
    1101 int value();
    \n+
    1102
    \n+
    1103 protected:
    \n+\n+\n+
    1108
    \n+
    1109 private:
    \n+
    1110 int count_;
    \n+
    1111 };
    \n+
    1112
    \n+
    1113
    \n+
    1118 class FrontNeighbourCounter : public Counter
    \n+
    1119 {
    \n+
    1120 public:
    \n+\n+
    1126
    \n+
    1127 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1128
    \n+
    1129 private:
    \n+
    1130 const MatrixGraph& graph_;
    \n+
    1131 };
    \n+
    1132
    \n+
    1137 int noFrontNeighbours(const Vertex& vertex) const;
    \n+
    1138
    \n+
    1142 class TwoWayCounter : public Counter
    \n+
    1143 {
    \n+
    1144 public:
    \n+
    1145 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1146 };
    \n+
    1147
    \n+
    1159 int twoWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
    \n+
    1160 const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1161
    \n+
    1165 class OneWayCounter : public Counter
    \n+
    1166 {
    \n+
    1167 public:
    \n+
    1168 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1169 };
    \n+
    1170
    \n+
    1182 int oneWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
    \n+
    1183 const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1184
    \n+
    1191 class ConnectivityCounter : public Counter
    \n+
    1192 {
    \n+
    1193 public:
    \n+
    1200 ConnectivityCounter(const VertexSet& connected, const AggregatesMap<Vertex>& aggregates);
    \n+
    1201
    \n+
    1202 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1203
    \n+
    1204 private:
    \n+
    1206 const VertexSet& connected_;
    \n+
    1208 const AggregatesMap<Vertex>& aggregates_;
    \n+
    1209
    \n+
    1210 };
    \n+
    1211
    \n+
    1223 double connectivity(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1231 bool connected(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n+
    1232 const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1233
    \n+
    1241 bool connected(const Vertex& vertex, const SLList<AggregateDescriptor>& aggregateList,
    \n+
    1242 const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1243
    \n+
    1251 class DependencyCounter : public Counter
    \n+
    1252 {
    \n+
    1253 public:
    \n+\n+
    1258
    \n+
    1259 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1260 };
    \n+
    1261
    \n+
    1268 class FrontMarker
    \n+
    1269 {
    \n+
    1270 public:
    \n+
    1277 FrontMarker(std::vector<Vertex>& front, MatrixGraph& graph);
    \n+
    1278
    \n+
    1279 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
    \n+
    1280
    \n+
    1281 private:
    \n+
    1283 std::vector<Vertex>& front_;
    \n+
    1285 MatrixGraph& graph_;
    \n+
    1286 };
    \n+
    1287
    \n+
    1291 void unmarkFront();
    \n+
    1292
    \n+
    1307 int unusedNeighbours(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1308
    \n+
    1322 std::pair<int,int> neighbours(const Vertex& vertex,
    \n+
    1323 const AggregateDescriptor& aggregate,
    \n+
    1324 const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1341 int aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1342
    \n+
    1350 bool admissible(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1351
    \n+
    1359 std::size_t distance(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates);
    \n+
    1360
    \n+
    1369 Vertex mergeNeighbour(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
    \n+
    1370
    \n+
    1379 void nonisoNeighbourAggregate(const Vertex& vertex,
    \n+
    1380 const AggregatesMap<Vertex>& aggregates,
    \n+
    1381 SLList<Vertex>& neighbours) const;
    \n+
    1382
    \n+
    1390 template<class C>
    \n+
    1391 void growAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
    \n+
    1392 template<class C>
    \n+
    1393 void growIsolatedAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
    \n+
    1394 };
    \n+
    1395
    \n+
    1396#ifndef DOXYGEN
    \n+
    1397
    \n+
    1398 template<class M, class N>
    \n+
    1399 inline void SymmetricDependency<M,N>::init(const Matrix* matrix)
    \n+
    1400 {
    \n+
    1401 matrix_ = matrix;
    \n+
    1402 }
    \n+
    1403
    \n+
    1404 template<class M, class N>
    \n+
    1405 inline void SymmetricDependency<M,N>::initRow(const Row& row, int index)
    \n+
    1406 {
    \n+
    1407 initRow(row, index, std::is_convertible<field_type, real_type>());
    \n+
    1408 }
    \n+
    1409
    \n+
    1410 template<class M, class N>
    \n+
    1411 inline void SymmetricDependency<M,N>::initRow(const Row& row, int index, const std::false_type&)
    \n+
    1412 {
    \n+
    1413 DUNE_THROW(InvalidStateException, "field_type needs to convertible to real_type");
    \n+
    1414 }
    \n+
    1415
    \n+
    1416 template<class M, class N>
    \n+
    1417 inline void SymmetricDependency<M,N>::initRow([[maybe_unused]] const Row& row, int index, const std::true_type&)
    \n+
    1418 {
    \n+
    1419 using std::min;
    \n+
    1420 maxValue_ = min(- std::numeric_limits<typename Matrix::field_type>::max(), std::numeric_limits<typename Matrix::field_type>::min());
    \n+
    1421 row_ = index;
    \n+
    1422 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
    \n+
    1423 }
    \n+
    1424
    \n+
    1425 template<class M, class N>
    \n+
    1426 inline void SymmetricDependency<M,N>::examine(const ColIter& col)
    \n+
    1427 {
    \n+
    1428 using std::max;
    \n+
    1429 real_type eij = norm_(*col);
    \n+
    1430 typename Matrix::ConstColIterator opposite_entry =
    \n+
    1431 matrix_->operator[](col.index()).find(row_);
    \n+
    1432 if ( opposite_entry == matrix_->operator[](col.index()).end() )
    \n+
    1433 {
    \n+
    1434 // Consider this a weak connection we disregard.
    \n+
    1435 return;
    \n+
    1436 }
    \n+
    1437 real_type eji = norm_(*opposite_entry);
    \n+
    1438
    \n+
    1439 // skip positive offdiagonals if norm preserves sign of them.
    \n+
    1440 if(!N::is_sign_preserving || eij<0 || eji<0)
    \n+
    1441 maxValue_ = max(maxValue_,
    \n+
    1442 eij /diagonal_ * eji/
    \n+
    1443 norm_(matrix_->operator[](col.index())[col.index()]));
    \n+
    1444 }
    \n+
    1445
    \n+
    1446 template<class M, class N>
    \n+
    1447 template<class G>
    \n+
    1448 inline void SymmetricDependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
    \n+
    1449 {
    \n+
    1450 real_type eij = norm_(*col);
    \n+
    1451 typename Matrix::ConstColIterator opposite_entry =
    \n+
    1452 matrix_->operator[](col.index()).find(row_);
    \n+
    1453
    \n+
    1454 if ( opposite_entry == matrix_->operator[](col.index()).end() )
    \n+
    1455 {
    \n+
    1456 // Consider this as a weak connection we disregard.
    \n+
    1457 return;
    \n+
    1458 }
    \n+
    1459 real_type eji = norm_(*opposite_entry);
    \n+
    1460 // skip positve offdiagonals if norm preserves sign of them.
    \n+
    1461 if(!N::is_sign_preserving || (eij<0 || eji<0))
    \n+
    1462 if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *
    \n+
    1463 eij/ diagonal_ > alpha() * maxValue_) {
    \n+
    1464 edge.properties().setDepends();
    \n+
    1465 edge.properties().setInfluences();
    \n+
    1466 typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target(), edge.source());
    \n+
    1467 other.setInfluences();
    \n+
    1468 other.setDepends();
    \n+
    1469 }
    \n+
    1470 }
    \n+
    1471
    \n+
    1472 template<class M, class N>
    \n+\n+
    1474 {
    \n+
    1475 return maxValue_ < beta();
    \n+
    1476 }
    \n+
    1477
    \n+
    1478
    \n+
    1479 template<class M, class N>
    \n+
    1480 inline void Dependency<M,N>::init(const Matrix* matrix)
    \n+
    1481 {
    \n+
    1482 matrix_ = matrix;
    \n+
    1483 }
    \n+
    1484
    \n+
    1485 template<class M, class N>
    \n+
    1486 inline void Dependency<M,N>::initRow([[maybe_unused]] const Row& row, int index)
    \n+
    1487 {
    \n+
    1488 using std::min;
    \n+
    1489 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
    \n+
    1490 row_ = index;
    \n+
    1491 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
    \n+
    1492 }
    \n+
    1493
    \n+
    1494 template<class M, class N>
    \n+
    1495 inline void Dependency<M,N>::examine(const ColIter& col)
    \n+
    1496 {
    \n+
    1497 using std::max;
    \n+
    1498 maxValue_ = max(maxValue_, -norm_(*col));
    \n+
    1499 }
    \n+
    1500
    \n+
    1501 template<class M, class N>
    \n+
    1502 template<class G>
    \n+
    1503 inline void Dependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
    \n+
    1504 {
    \n+
    1505 if(-norm_(*col) >= maxValue_ * alpha()) {
    \n+
    1506 edge.properties().setDepends();
    \n+
    1507 typedef typename G::EdgeDescriptor ED;
    \n+
    1508 ED e= graph.findEdge(edge.target(), edge.source());
    \n+
    1509 if(e!=std::numeric_limits<ED>::max())
    \n+
    1510 {
    \n+
    1511 typename G::EdgeProperties& other = graph.getEdgeProperties(e);
    \n+
    1512 other.setInfluences();
    \n+
    1513 }
    \n+
    1514 }
    \n+
    1515 }
    \n+
    1516
    \n+
    1517 template<class M, class N>
    \n+
    1518 inline bool Dependency<M,N>::isIsolated()
    \n+
    1519 {
    \n+
    1520 return maxValue_ < beta() * diagonal_;
    \n+
    1521 }
    \n+
    1522
    \n+
    1523 template<class G,class S>
    \n+
    1524 Aggregate<G,S>::Aggregate(MatrixGraph& graph, AggregatesMap<Vertex>& aggregates,
    \n+
    1525 VertexSet& connected, std::vector<Vertex>& front)
    \n+
    1526 : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),
    \n+
    1527 connected_(connected), front_(front)
    \n+
    1528 {}
    \n+
    1529
    \n+
    1530 template<class G,class S>
    \n+
    1531 void Aggregate<G,S>::reconstruct(const Vertex& vertex)
    \n+
    1532 {
    \n+
    1533 /*
    \n+
    1534 vertices_.push_back(vertex);
    \n+
    1535 typedef typename VertexList::const_iterator iterator;
    \n+
    1536 iterator begin = vertices_.begin();
    \n+
    1537 iterator end = vertices_.end();*/
    \n+
    1538 throw "Not yet implemented";
    \n+
    1539
    \n+
    1540 // while(begin!=end){
    \n+
    1541 //for();
    \n+
    1542 // }
    \n+
    1543
    \n+
    1544 }
    \n+
    1545
    \n+
    1546 template<class G,class S>
    \n+
    1547 inline void Aggregate<G,S>::seed(const Vertex& vertex)
    \n+
    1548 {
    \n+
    1549 dvverb<<"Connected cleared"<<std::endl;
    \n+
    1550 connected_.clear();
    \n+
    1551 vertices_.clear();
    \n+
    1552 connected_.insert(vertex);
    \n+
    1553 dvverb << " Inserting "<<vertex<<" size="<<connected_.size();
    \n+
    1554 ++id_ ;
    \n+
    1555 add(vertex);
    \n+
    1556 }
    \n+
    1557
    \n+
    1558
    \n+
    1559 template<class G,class S>
    \n+
    1560 inline void Aggregate<G,S>::add(const Vertex& vertex)
    \n+
    1561 {
    \n+
    1562 vertices_.insert(vertex);
    \n+
    1563 aggregates_[vertex]=id_;
    \n+
    1564 if(front_.size())
    \n+
    1565 front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));
    \n+
    1566
    \n+
    1567
    \n+
    1568 typedef typename MatrixGraph::ConstEdgeIterator iterator;
    \n+
    1569 const iterator end = graph_.endEdges(vertex);
    \n+
    1570 for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {
    \n+
    1571 dvverb << " Inserting "<<aggregates_[edge.target()];
    \n+
    1572 connected_.insert(aggregates_[edge.target()]);
    \n+
    1573 dvverb <<" size="<<connected_.size();
    \n+
    1574 if(aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED &&
    \n+
    1575 !graph_.getVertexProperties(edge.target()).front())
    \n+
    1576 {
    \n+
    1577 front_.push_back(edge.target());
    \n+
    1578 graph_.getVertexProperties(edge.target()).setFront();
    \n+
    1579 }
    \n+
    1580 }
    \n+
    1581 dvverb <<std::endl;
    \n+
    1582 std::sort(front_.begin(), front_.end());
    \n+
    1583 }
    \n+
    1584
    \n+
    1585 template<class G,class S>
    \n+
    1586 inline void Aggregate<G,S>::add(std::vector<Vertex>& vertices)
    \n+
    1587 {
    \n+
    1588#ifndef NDEBUG
    \n+
    1589 std::size_t oldsize = vertices_.size();
    \n+
    1590#endif
    \n+
    1591 typedef typename std::vector<Vertex>::iterator Iterator;
    \n+
    1592
    \n+
    1593 typedef typename VertexSet::iterator SIterator;
    \n+
    1594
    \n+
    1595 SIterator pos=vertices_.begin();
    \n+
    1596 std::vector<Vertex> newFront;
    \n+
    1597 newFront.reserve(front_.capacity());
    \n+
    1598
    \n+
    1599 std::set_difference(front_.begin(), front_.end(), vertices.begin(), vertices.end(),
    \n+
    1600 std::back_inserter(newFront));
    \n+
    1601 front_=newFront;
    \n+
    1602
    \n+
    1603 for(Iterator vertex=vertices.begin(); vertex != vertices.end(); ++vertex)
    \n+
    1604 {
    \n+
    1605 pos=vertices_.insert(pos,*vertex);
    \n+
    1606 vertices_.insert(*vertex);
    \n+
    1607 graph_.getVertexProperties(*vertex).resetFront(); // Not a front node any more.
    \n+
    1608 aggregates_[*vertex]=id_;
    \n+
    1609
    \n+
    1610 typedef typename MatrixGraph::ConstEdgeIterator iterator;
    \n+
    1611 const iterator end = graph_.endEdges(*vertex);
    \n+
    1612 for(iterator edge = graph_.beginEdges(*vertex); edge != end; ++edge) {
    \n+
    1613 dvverb << " Inserting "<<aggregates_[edge.target()];
    \n+
    1614 connected_.insert(aggregates_[edge.target()]);
    \n+
    1615 if(aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED &&
    \n+
    1616 !graph_.getVertexProperties(edge.target()).front())
    \n+
    1617 {
    \n+
    1618 front_.push_back(edge.target());
    \n+
    1619 graph_.getVertexProperties(edge.target()).setFront();
    \n+
    1620 }
    \n+
    1621 dvverb <<" size="<<connected_.size();
    \n+
    1622 }
    \n+
    1623 dvverb <<std::endl;
    \n+
    1624 }
    \n+
    1625 std::sort(front_.begin(), front_.end());
    \n+
    1626 assert(oldsize+vertices.size()==vertices_.size());
    \n+
    1627 }
    \n+
    1628 template<class G,class S>
    \n+
    1629 inline void Aggregate<G,S>::clear()
    \n+
    1630 {
    \n+
    1631 vertices_.clear();
    \n+
    1632 connected_.clear();
    \n+
    1633 id_=-1;
    \n+
    1634 }
    \n+
    1635
    \n+
    1636 template<class G,class S>
    \n+
    1637 inline typename Aggregate<G,S>::VertexSet::size_type
    \n+\n+
    1639 {
    \n+
    1640 return vertices_.size();
    \n+
    1641 }
    \n+
    1642
    \n+
    1643 template<class G,class S>
    \n+
    1644 inline typename Aggregate<G,S>::VertexSet::size_type
    \n+\n+
    1646 {
    \n+
    1647 return connected_.size();
    \n+
    1648 }
    \n+
    1649
    \n+
    1650 template<class G,class S>
    \n+
    1651 inline int Aggregate<G,S>::id()
    \n+
    1652 {
    \n+
    1653 return id_;
    \n+
    1654 }
    \n+
    1655
    \n+
    1656 template<class G,class S>
    \n+\n+
    1658 {
    \n+
    1659 return vertices_.begin();
    \n+
    1660 }
    \n+
    1661
    \n+
    1662 template<class G,class S>
    \n+\n+
    1664 {
    \n+
    1665 return vertices_.end();
    \n+
    1666 }
    \n+
    1667
    \n+
    1668 template<class V>
    \n+
    1669 const V AggregatesMap<V>::UNAGGREGATED = std::numeric_limits<V>::max();
    \n+
    1670
    \n+
    1671 template<class V>
    \n+
    1672 const V AggregatesMap<V>::ISOLATED = std::numeric_limits<V>::max()-1;
    \n+
    1673
    \n+
    1674 template<class V>
    \n+\n+
    1676 : aggregates_(0)
    \n+
    1677 {}
    \n+
    1678
    \n+
    1679 template<class V>
    \n+\n+
    1681 {
    \n+
    1682 if(aggregates_!=0)
    \n+
    1683 delete[] aggregates_;
    \n+
    1684 }
    \n+
    1685
    \n+
    1686
    \n+
    1687 template<class V>
    \n+
    1688 inline AggregatesMap<V>::AggregatesMap(std::size_t noVertices)
    \n+
    1689 {
    \n+
    1690 allocate(noVertices);
    \n+
    1691 }
    \n+
    1692
    \n+
    1693 template<class V>
    \n+
    1694 inline std::size_t AggregatesMap<V>::noVertices() const
    \n+
    1695 {
    \n+
    1696 return noVertices_;
    \n+
    1697 }
    \n+
    1698
    \n+
    1699 template<class V>
    \n+
    1700 inline void AggregatesMap<V>::allocate(std::size_t noVertices)
    \n+
    1701 {
    \n+
    1702 aggregates_ = new AggregateDescriptor[noVertices];
    \n+
    1703 noVertices_ = noVertices;
    \n+
    1704
    \n+
    1705 for(std::size_t i=0; i < noVertices; i++)
    \n+
    1706 aggregates_[i]=UNAGGREGATED;
    \n+
    1707 }
    \n+
    1708
    \n+
    1709 template<class V>
    \n+
    1710 inline void AggregatesMap<V>::free()
    \n+
    1711 {
    \n+
    1712 assert(aggregates_ != 0);
    \n+
    1713 delete[] aggregates_;
    \n+
    1714 aggregates_=0;
    \n+
    1715 }
    \n+
    1716
    \n+
    1717 template<class V>
    \n+\n+
    1719 AggregatesMap<V>::operator[](const VertexDescriptor& v)
    \n+
    1720 {
    \n+
    1721 return aggregates_[v];
    \n+
    1722 }
    \n+
    1723
    \n+
    1724 template<class V>
    \n+
    1725 inline const typename AggregatesMap<V>::AggregateDescriptor&
    \n+
    1726 AggregatesMap<V>::operator[](const VertexDescriptor& v) const
    \n+
    1727 {
    \n+
    1728 return aggregates_[v];
    \n+
    1729 }
    \n+
    1730
    \n+
    1731 template<class V>
    \n+
    1732 template<bool reset, class G, class F,class VM>
    \n+
    1733 inline std::size_t AggregatesMap<V>::breadthFirstSearch(const V& start,
    \n+
    1734 const AggregateDescriptor& aggregate,
    \n+
    1735 const G& graph, F& aggregateVisitor,
    \n+
    1736 VM& visitedMap) const
    \n+
    1737 {
    \n+
    1738 VertexList vlist;
    \n+
    1739
    \n+
    1740 DummyEdgeVisitor dummy;
    \n+
    1741 return breadthFirstSearch<true,reset>(start, aggregate, graph, vlist, aggregateVisitor, dummy, visitedMap);
    \n+
    1742 }
    \n+
    1743
    \n+
    1744 template<class V>
    \n+
    1745 template<bool remove, bool reset, class G, class L, class F1, class F2, class VM>
    \n+
    1746 std::size_t AggregatesMap<V>::breadthFirstSearch(const V& start,
    \n+
    1747 const AggregateDescriptor& aggregate,
    \n+
    1748 const G& graph,
    \n+
    1749 L& visited,
    \n+
    1750 F1& aggregateVisitor,
    \n+
    1751 F2& nonAggregateVisitor,
    \n+
    1752 VM& visitedMap) const
    \n+
    1753 {
    \n+
    1754 typedef typename L::const_iterator ListIterator;
    \n+
    1755 int visitedSpheres = 0;
    \n+
    1756
    \n+
    1757 visited.push_back(start);
    \n+
    1758 put(visitedMap, start, true);
    \n+
    1759
    \n+
    1760 ListIterator current = visited.begin();
    \n+
    1761 ListIterator end = visited.end();
    \n+
    1762 std::size_t i=0, size=visited.size();
    \n+
    1763
    \n+
    1764 // visit the neighbours of all vertices of the
    \n+
    1765 // current sphere.
    \n+
    1766 while(current != end) {
    \n+
    1767
    \n+
    1768 for(; i<size; ++current, ++i) {
    \n+
    1769 typedef typename G::ConstEdgeIterator EdgeIterator;
    \n+
    1770 const EdgeIterator endEdge = graph.endEdges(*current);
    \n+
    1771
    \n+
    1772 for(EdgeIterator edge = graph.beginEdges(*current);
    \n+
    1773 edge != endEdge; ++edge) {
    \n+
    1774
    \n+
    1775 if(aggregates_[edge.target()]==aggregate) {
    \n+
    1776 if(!get(visitedMap, edge.target())) {
    \n+
    1777 put(visitedMap, edge.target(), true);
    \n+
    1778 visited.push_back(edge.target());
    \n+
    1779 aggregateVisitor(edge);
    \n+
    1780 }
    \n+
    1781 }else
    \n+
    1782 nonAggregateVisitor(edge);
    \n+
    1783 }
    \n+
    1784 }
    \n+
    1785 end = visited.end();
    \n+
    1786 size = visited.size();
    \n+
    1787 if(current != end)
    \n+
    1788 visitedSpheres++;
    \n+
    1789 }
    \n+
    1790
    \n+
    1791 if(reset)
    \n+
    1792 for(current = visited.begin(); current != end; ++current)
    \n+
    1793 put(visitedMap, *current, false);
    \n+
    1794
    \n+
    1795
    \n+
    1796 if(remove)
    \n+
    1797 visited.clear();
    \n+
    1798
    \n+
    1799 return visitedSpheres;
    \n+
    1800 }
    \n+
    1801
    \n+
    1802 template<class G>
    \n+\n+
    1804 : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)
    \n+
    1805 {}
    \n+
    1806
    \n+
    1807 template<class G>
    \n+\n+
    1809 {
    \n+
    1810 size_=-1;
    \n+
    1811 }
    \n+
    1812
    \n+
    1813 template<class G, class C>
    \n+
    1814 void buildDependency(G& graph,
    \n+
    1815 const typename C::Matrix& matrix,
    \n+
    1816 C criterion, bool firstlevel)
    \n+
    1817 {
    \n+
    1818 // assert(graph.isBuilt());
    \n+
    1819 typedef typename C::Matrix Matrix;
    \n+
    1820 typedef typename G::VertexIterator VertexIterator;
    \n+
    1821
    \n+
    1822 criterion.init(&matrix);
    \n+
    1823
    \n+
    1824 for(VertexIterator vertex = graph.begin(); vertex != graph.end(); ++vertex) {
    \n+
    1825 typedef typename Matrix::row_type Row;
    \n+
    1826
    \n+
    1827 const Row& row = matrix[*vertex];
    \n+
    1828
    \n+
    1829 // Tell the criterion what row we will examine now
    \n+
    1830 // This might for example be used for calculating the
    \n+
    1831 // maximum offdiagonal value
    \n+
    1832 criterion.initRow(row, *vertex);
    \n+
    1833
    \n+
    1834 // On a first path all columns are examined. After this
    \n+
    1835 // the calculator should know whether the vertex is isolated.
    \n+
    1836 typedef typename Matrix::ConstColIterator ColIterator;
    \n+
    1837 ColIterator end = row.end();
    \n+
    1838 typename FieldTraits<typename Matrix::field_type>::real_type absoffdiag=0.;
    \n+
    1839
    \n+
    1840 using std::max;
    \n+
    1841 if(firstlevel) {
    \n+
    1842 for(ColIterator col = row.begin(); col != end; ++col)
    \n+
    1843 if(col.index()!=*vertex) {
    \n+
    1844 criterion.examine(col);
    \n+
    1845 absoffdiag = max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());
    \n+
    1846 }
    \n+
    1847
    \n+
    1848 if(absoffdiag==0)
    \n+
    1849 vertex.properties().setExcludedBorder();
    \n+
    1850 }
    \n+
    1851 else
    \n+
    1852 for(ColIterator col = row.begin(); col != end; ++col)
    \n+
    1853 if(col.index()!=*vertex)
    \n+
    1854 criterion.examine(col);
    \n+
    1855
    \n+
    1856 // reset the vertex properties
    \n+
    1857 //vertex.properties().reset();
    \n+
    1858
    \n+
    1859 // Check whether the vertex is isolated.
    \n+
    1860 if(criterion.isIsolated()) {
    \n+
    1861 //std::cout<<"ISOLATED: "<<*vertex<<std::endl;
    \n+
    1862 vertex.properties().setIsolated();
    \n+
    1863 }else{
    \n+
    1864 // Examine all the edges beginning at this vertex.
    \n+
    1865 auto eEnd = vertex.end();
    \n+
    1866 auto col = matrix[*vertex].begin();
    \n+
    1867
    \n+
    1868 for(auto edge = vertex.begin(); edge!= eEnd; ++edge, ++col) {
    \n+
    1869 // Move to the right column.
    \n+
    1870 while(col.index()!=edge.target())
    \n+
    1871 ++col;
    \n+
    1872 criterion.examine(graph, edge, col);
    \n+
    1873 }
    \n+
    1874 }
    \n+
    1875
    \n+
    1876 }
    \n+
    1877 }
    \n+
    1878
    \n+
    1879
    \n+
    1880 template<class G>
    \n+
    1881 template<class V>
    \n+
    1882 inline Aggregator<G>::AggregateVisitor<V>::AggregateVisitor(const AggregatesMap<Vertex>& aggregates,
    \n+
    1883 const AggregateDescriptor& aggregate, V& visitor)
    \n+
    1884 : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)
    \n+
    1885 {}
    \n+
    1886
    \n+
    1887 template<class G>
    \n+
    1888 template<class V>
    \n+
    1889 inline void Aggregator<G>::AggregateVisitor<V>::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    1890 {
    \n+
    1891 if(aggregates_[edge.target()]==aggregate_)
    \n+
    1892 visitor_->operator()(edge);
    \n+
    1893 }
    \n+
    1894
    \n+
    1895 template<class G>
    \n+
    1896 template<class V>
    \n+
    1897 inline void Aggregator<G>::visitAggregateNeighbours(const Vertex& vertex,
    \n+
    1898 const AggregateDescriptor& aggregate,
    \n+
    1899 const AggregatesMap<Vertex>& aggregates,
    \n+
    1900 V& visitor) const
    \n+
    1901 {
    \n+
    1902 // Only evaluates for edge pointing to the aggregate
    \n+
    1903 AggregateVisitor<V> v(aggregates, aggregate, visitor);
    \n+
    1904 visitNeighbours(*graph_, vertex, v);
    \n+
    1905 }
    \n+
    1906
    \n+
    1907
    \n+
    1908 template<class G>
    \n+
    1909 inline Aggregator<G>::Counter::Counter()
    \n+
    1910 : count_(0)
    \n+
    1911 {}
    \n+
    1912
    \n+
    1913 template<class G>
    \n+
    1914 inline void Aggregator<G>::Counter::increment()
    \n+
    1915 {
    \n+
    1916 ++count_;
    \n+
    1917 }
    \n+
    1918
    \n+
    1919 template<class G>
    \n+
    1920 inline void Aggregator<G>::Counter::decrement()
    \n+
    1921 {
    \n+
    1922 --count_;
    \n+
    1923 }
    \n+
    1924 template<class G>
    \n+
    1925 inline int Aggregator<G>::Counter::value()
    \n+
    1926 {
    \n+
    1927 return count_;
    \n+
    1928 }
    \n+
    1929
    \n+
    1930 template<class G>
    \n+
    1931 inline void Aggregator<G>::TwoWayCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    1932 {
    \n+
    1933 if(edge.properties().isTwoWay())
    \n+
    1934 Counter::increment();
    \n+
    1935 }
    \n+
    1936
    \n+
    1937 template<class G>
    \n+
    1938 int Aggregator<G>::twoWayConnections(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n+
    1939 const AggregatesMap<Vertex>& aggregates) const
    \n+
    1940 {
    \n+
    1941 TwoWayCounter counter;
    \n+
    1942 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n+
    1943 return counter.value();
    \n+
    1944 }
    \n+
    1945
    \n+
    1946 template<class G>
    \n+
    1947 int Aggregator<G>::oneWayConnections(const Vertex& vertex, const AggregateDescriptor& aggregate,
    \n+
    1948 const AggregatesMap<Vertex>& aggregates) const
    \n+
    1949 {
    \n+
    1950 OneWayCounter counter;
    \n+
    1951 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n+
    1952 return counter.value();
    \n+
    1953 }
    \n+
    1954
    \n+
    1955 template<class G>
    \n+
    1956 inline void Aggregator<G>::OneWayCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    1957 {
    \n+
    1958 if(edge.properties().isOneWay())
    \n+
    1959 Counter::increment();
    \n+
    1960 }
    \n+
    1961
    \n+
    1962 template<class G>
    \n+
    1963 inline Aggregator<G>::ConnectivityCounter::ConnectivityCounter(const VertexSet& connected,
    \n+
    1964 const AggregatesMap<Vertex>& aggregates)
    \n+
    1965 : Counter(), connected_(connected), aggregates_(aggregates)
    \n+
    1966 {}
    \n+
    1967
    \n+
    1968
    \n+
    1969 template<class G>
    \n+
    1970 inline void Aggregator<G>::ConnectivityCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    1971 {
    \n+
    1972 if(connected_.find(aggregates_[edge.target()]) == connected_.end() || aggregates_[edge.target()]==AggregatesMap<Vertex>::UNAGGREGATED)
    \n+
    1973 // Would be a new connection
    \n+
    1974 Counter::increment();
    \n+
    1975 else{
    \n+
    1976 Counter::increment();
    \n+
    1977 Counter::increment();
    \n+
    1978 }
    \n+
    1979 }
    \n+
    1980
    \n+
    1981 template<class G>
    \n+
    1982 inline double Aggregator<G>::connectivity(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n+
    1983 {
    \n+
    1984 ConnectivityCounter counter(connected_, aggregates);
    \n+
    1985 double noNeighbours=visitNeighbours(*graph_, vertex, counter);
    \n+
    1986 return (double)counter.value()/noNeighbours;
    \n+
    1987 }
    \n+
    1988
    \n+
    1989 template<class G>
    \n+
    1990 inline Aggregator<G>::DependencyCounter::DependencyCounter()
    \n+
    1991 : Counter()
    \n+
    1992 {}
    \n+
    1993
    \n+
    1994 template<class G>
    \n+
    1995 inline void Aggregator<G>::DependencyCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    1996 {
    \n+
    1997 if(edge.properties().depends())
    \n+
    1998 Counter::increment();
    \n+
    1999 if(edge.properties().influences())
    \n+
    2000 Counter::increment();
    \n+
    2001 }
    \n+
    2002
    \n+
    2003 template<class G>
    \n+
    2004 int Aggregator<G>::unusedNeighbours(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n+
    2005 {
    \n+
    2006 return aggregateNeighbours(vertex, AggregatesMap<Vertex>::UNAGGREGATED, aggregates);
    \n+
    2007 }
    \n+
    2008
    \n+
    2009 template<class G>
    \n+
    2010 std::pair<int,int> Aggregator<G>::neighbours(const Vertex& vertex,
    \n+
    2011 const AggregateDescriptor& aggregate,
    \n+
    2012 const AggregatesMap<Vertex>& aggregates) const
    \n+
    2013 {
    \n+
    2014 DependencyCounter unused, aggregated;
    \n+
    2015 typedef AggregateVisitor<DependencyCounter> CounterT;
    \n+
    2016 typedef std::tuple<CounterT,CounterT> CounterTuple;
    \n+
    2017 CombinedFunctor<CounterTuple> visitors(CounterTuple(CounterT(aggregates, AggregatesMap<Vertex>::UNAGGREGATED, unused), CounterT(aggregates, aggregate, aggregated)));
    \n+
    2018 visitNeighbours(*graph_, vertex, visitors);
    \n+
    2019 return std::make_pair(unused.value(), aggregated.value());
    \n+
    2020 }
    \n+
    2021
    \n+
    2022
    \n+
    2023 template<class G>
    \n+
    2024 int Aggregator<G>::aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const
    \n+
    2025 {
    \n+
    2026 DependencyCounter counter;
    \n+
    2027 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
    \n+
    2028 return counter.value();
    \n+
    2029 }
    \n+
    2030
    \n+
    2031 template<class G>
    \n+
    2032 std::size_t Aggregator<G>::distance(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates)
    \n+
    2033 {
    \n+
    2034 return 0;
    \n+
    2035 typename PropertyMapTypeSelector<VertexVisitedTag,G>::Type visitedMap = get(VertexVisitedTag(), *graph_);
    \n+
    2036 VertexList vlist;
    \n+
    2037 typename AggregatesMap<Vertex>::DummyEdgeVisitor dummy;
    \n+
    2038 return aggregates.template breadthFirstSearch<true,true>(vertex,
    \n+
    2039 aggregate_->id(), *graph_,
    \n+
    2040 vlist, dummy, dummy, visitedMap);
    \n+
    2041 }
    \n+
    2042
    \n+
    2043 template<class G>
    \n+
    2044 inline Aggregator<G>::FrontMarker::FrontMarker(std::vector<Vertex>& front, MatrixGraph& graph)
    \n+
    2045 : front_(front), graph_(graph)
    \n+
    2046 {}
    \n+
    2047
    \n+
    2048 template<class G>
    \n+
    2049 inline void Aggregator<G>::FrontMarker::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    2050 {
    \n+
    2051 Vertex target = edge.target();
    \n+
    2052
    \n+
    2053 if(!graph_.getVertexProperties(target).front()) {
    \n+
    2054 front_.push_back(target);
    \n+
    2055 graph_.getVertexProperties(target).setFront();
    \n+
    2056 }
    \n+
    2057 }
    \n+
    2058
    \n+
    2059 template<class G>
    \n+
    2060 inline bool Aggregator<G>::admissible(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const
    \n+
    2061 {
    \n+
    2062 // Todo
    \n+
    2063 Dune::dvverb<<" Admissible not yet implemented!"<<std::endl;
    \n+
    2064 return true;
    \n+
    2065 //Situation 1: front node depends on two nodes. Then these
    \n+
    2066 // have to be strongly connected to each other
    \n+
    2067
    \n+
    2068 // Iterate over all all neighbours of front node
    \n+
    2069 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n+
    2070 Iterator vend = graph_->endEdges(vertex);
    \n+
    2071 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
    \n+
    2072 // if(edge.properties().depends() && !edge.properties().influences()
    \n+
    2073 if(edge.properties().isStrong()
    \n+
    2074 && aggregates[edge.target()]==aggregate)
    \n+
    2075 {
    \n+
    2076 // Search for another link to the aggregate
    \n+
    2077 Iterator edge1 = edge;
    \n+
    2078 for(++edge1; edge1 != vend; ++edge1) {
    \n+
    2079 //if(edge1.properties().depends() && !edge1.properties().influences()
    \n+
    2080 if(edge1.properties().isStrong()
    \n+
    2081 && aggregates[edge.target()]==aggregate)
    \n+
    2082 {
    \n+
    2083 //Search for an edge connecting the two vertices that is
    \n+
    2084 //strong
    \n+
    2085 bool found=false;
    \n+
    2086 Iterator v2end = graph_->endEdges(edge.target());
    \n+
    2087 for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end; ++edge2) {
    \n+
    2088 if(edge2.target()==edge1.target() &&
    \n+
    2089 edge2.properties().isStrong()) {
    \n+
    2090 found =true;
    \n+
    2091 break;
    \n+
    2092 }
    \n+
    2093 }
    \n+
    2094 if(found)
    \n+
    2095 {
    \n+
    2096 return true;
    \n+
    2097 }
    \n+
    2098 }
    \n+
    2099 }
    \n+
    2100 }
    \n+
    2101 }
    \n+
    2102
    \n+
    2103 // Situation 2: cluster node depends on front node and other cluster node
    \n+
    2105 vend = graph_->endEdges(vertex);
    \n+
    2106 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
    \n+
    2107 //if(!edge.properties().depends() && edge.properties().influences()
    \n+
    2108 if(edge.properties().isStrong()
    \n+
    2109 && aggregates[edge.target()]==aggregate)
    \n+
    2110 {
    \n+
    2111 // Search for a link from target that stays within the aggregate
    \n+
    2112 Iterator v1end = graph_->endEdges(edge.target());
    \n+
    2113
    \n+
    2114 for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end; ++edge1) {
    \n+
    2115 //if(edge1.properties().depends() && !edge1.properties().influences()
    \n+
    2116 if(edge1.properties().isStrong()
    \n+
    2117 && aggregates[edge1.target()]==aggregate)
    \n+
    2118 {
    \n+
    2119 bool found=false;
    \n+
    2120 // Check if front node is also connected to this one
    \n+
    2121 Iterator v2end = graph_->endEdges(vertex);
    \n+
    2122 for(Iterator edge2 = graph_->beginEdges(vertex); edge2 != v2end; ++edge2) {
    \n+
    2123 if(edge2.target()==edge1.target()) {
    \n+
    2124 if(edge2.properties().isStrong())
    \n+
    2125 found=true;
    \n+
    2126 break;
    \n+
    2127 }
    \n+
    2128 }
    \n+
    2129 if(found)
    \n+
    2130 {
    \n+
    2131 return true;
    \n+
    2132 }
    \n+
    2133 }
    \n+
    2134 }
    \n+
    2135 }
    \n+
    2136 }
    \n+
    2137 return false;
    \n+
    2138 }
    \n+
    2139
    \n+
    2140 template<class G>
    \n+
    2141 void Aggregator<G>::unmarkFront()
    \n+
    2142 {
    \n+
    2143 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n+
    2144
    \n+
    2145 for(Iterator vertex=front_.begin(); vertex != front_.end(); ++vertex)
    \n+
    2146 graph_->getVertexProperties(*vertex).resetFront();
    \n+
    2147
    \n+
    2148 front_.clear();
    \n+
    2149 }
    \n+
    2150
    \n+
    2151 template<class G>
    \n+
    2152 inline void
    \n+
    2153 Aggregator<G>::nonisoNeighbourAggregate(const Vertex& vertex,
    \n+
    2154 const AggregatesMap<Vertex>& aggregates,
    \n+
    2155 SLList<Vertex>& neighbours) const
    \n+
    2156 {
    \n+
    2157 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n+
    2158 Iterator end=graph_->beginEdges(vertex);
    \n+
    2159 neighbours.clear();
    \n+
    2160
    \n+
    2161 for(Iterator edge=graph_->beginEdges(vertex); edge!=end; ++edge)
    \n+
    2162 {
    \n+
    2163 if(aggregates[edge.target()]!=AggregatesMap<Vertex>::UNAGGREGATED && graph_->getVertexProperties(edge.target()).isolated())
    \n+
    2164 neighbours.push_back(aggregates[edge.target()]);
    \n+
    2165 }
    \n+
    2166 }
    \n+
    2167
    \n+
    2168 template<class G>
    \n+
    2169 inline typename G::VertexDescriptor Aggregator<G>::mergeNeighbour(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const
    \n+
    2170 {
    \n+
    2171 typedef typename MatrixGraph::ConstEdgeIterator Iterator;
    \n+
    2172
    \n+
    2173 Iterator end = graph_->endEdges(vertex);
    \n+
    2174 for(Iterator edge = graph_->beginEdges(vertex); edge != end; ++edge) {
    \n+
    2175 if(aggregates[edge.target()] != AggregatesMap<Vertex>::UNAGGREGATED &&
    \n+
    2176 graph_->getVertexProperties(edge.target()).isolated() == graph_->getVertexProperties(edge.source()).isolated()) {
    \n+
    2177 if( graph_->getVertexProperties(vertex).isolated() ||
    \n+
    2178 ((edge.properties().depends() || edge.properties().influences())
    \n+
    2179 && admissible(vertex, aggregates[edge.target()], aggregates)))
    \n+
    2180 return edge.target();
    \n+
    2181 }
    \n+
    2182 }
    \n+\n+
    2184 }
    \n+
    2185
    \n+
    2186 template<class G>
    \n+
    2187 Aggregator<G>::FrontNeighbourCounter::FrontNeighbourCounter(const MatrixGraph& graph)
    \n+
    2188 : Counter(), graph_(graph)
    \n+
    2189 {}
    \n+
    2190
    \n+
    2191 template<class G>
    \n+
    2192 void Aggregator<G>::FrontNeighbourCounter::operator()(const typename MatrixGraph::ConstEdgeIterator& edge)
    \n+
    2193 {
    \n+
    2194 if(graph_.getVertexProperties(edge.target()).front())
    \n+
    2195 Counter::increment();
    \n+
    2196 }
    \n+
    2197
    \n+
    2198 template<class G>
    \n+
    2199 int Aggregator<G>::noFrontNeighbours(const Vertex& vertex) const
    \n+
    2200 {
    \n+
    2201 FrontNeighbourCounter counter(*graph_);
    \n+
    2202 visitNeighbours(*graph_, vertex, counter);
    \n+
    2203 return counter.value();
    \n+
    2204 }
    \n+
    2205 template<class G>
    \n+
    2206 inline bool Aggregator<G>::connected(const Vertex& vertex,
    \n+
    2207 const AggregateDescriptor& aggregate,
    \n+
    2208 const AggregatesMap<Vertex>& aggregates) const
    \n+
    2209 {
    \n+
    2210 typedef typename G::ConstEdgeIterator iterator;
    \n+
    2211 const iterator end = graph_->endEdges(vertex);
    \n+
    2212 for(iterator edge = graph_->beginEdges(vertex); edge != end; ++edge)
    \n+
    2213 if(aggregates[edge.target()]==aggregate)
    \n+
    2214 return true;
    \n+
    2215 return false;
    \n+
    2216 }
    \n+
    2217 template<class G>
    \n+
    2218 inline bool Aggregator<G>::connected(const Vertex& vertex,
    \n+
    2219 const SLList<AggregateDescriptor>& aggregateList,
    \n+
    2220 const AggregatesMap<Vertex>& aggregates) const
    \n+
    2221 {
    \n+
    2222 typedef typename SLList<AggregateDescriptor>::const_iterator Iter;
    \n+
    2223 for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)
    \n+
    2224 if(connected(vertex, *i, aggregates))
    \n+
    2225 return true;
    \n+
    2226 return false;
    \n+
    2227 }
    \n+
    2228
    \n+
    2229 template<class G>
    \n+
    2230 template<class C>
    \n+
    2231 void Aggregator<G>::growIsolatedAggregate(const Vertex& seed, const AggregatesMap<Vertex>& aggregates, const C& c)
    \n+
    2232 {
    \n+
    2233 SLList<Vertex> connectedAggregates;
    \n+
    2234 nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);
    \n+
    2235
    \n+
    2236 while(aggregate_->size()< c.minAggregateSize() && aggregate_->connectSize() < c.maxConnectivity()) {
    \n+
    2237 double maxCon=-1;
    \n+
    2238 std::size_t maxFrontNeighbours=0;
    \n+
    2239
    \n+\n+
    2241
    \n+
    2242 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n+
    2243
    \n+
    2244 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n+
    2245 if(distance(*vertex, aggregates)>c.maxDistance())
    \n+
    2246 continue; // distance of proposes aggregate too big
    \n+
    2247
    \n+
    2248 if(connectedAggregates.size()>0) {
    \n+
    2249 // there is already a neighbour cluster
    \n+
    2250 // front node must be connected to same neighbour cluster
    \n+
    2251
    \n+
    2252 if(!connected(*vertex, connectedAggregates, aggregates))
    \n+
    2253 continue;
    \n+
    2254 }
    \n+
    2255
    \n+
    2256 double con = connectivity(*vertex, aggregates);
    \n+
    2257
    \n+
    2258 if(con == maxCon) {
    \n+
    2259 std::size_t frontNeighbours = noFrontNeighbours(*vertex);
    \n+
    2260
    \n+
    2261 if(frontNeighbours >= maxFrontNeighbours) {
    \n+
    2262 maxFrontNeighbours = frontNeighbours;
    \n+
    2263 candidate = *vertex;
    \n+
    2264 }
    \n+
    2265 }else if(con > maxCon) {
    \n+
    2266 maxCon = con;
    \n+
    2267 maxFrontNeighbours = noFrontNeighbours(*vertex);
    \n+
    2268 candidate = *vertex;
    \n+
    2269 }
    \n+
    2270 }
    \n+
    2271
    \n+\n+
    2273 break;
    \n+
    2274
    \n+
    2275 aggregate_->add(candidate);
    \n+
    2276 }
    \n+
    2277 }
    \n+
    2278
    \n+
    2279 template<class G>
    \n+
    2280 template<class C>
    \n+
    2281 void Aggregator<G>::growAggregate(const Vertex& seed, const AggregatesMap<Vertex>& aggregates, const C& c)
    \n+
    2282 {
    \n+
    2283 using std::min;
    \n+
    2284
    \n+
    2285 std::size_t distance_ =0;
    \n+
    2286 while(aggregate_->size() < c.minAggregateSize()&& distance_<c.maxDistance()) {
    \n+
    2287 int maxTwoCons=0, maxOneCons=0, maxNeighbours=-1;
    \n+
    2288 double maxCon=-1;
    \n+
    2289
    \n+
    2290 std::vector<Vertex> candidates;
    \n+
    2291 candidates.reserve(30);
    \n+
    2292
    \n+
    2293 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n+
    2294
    \n+
    2295 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n+
    2296 // Only nonisolated nodes are considered
    \n+
    2297 if(graph_->getVertexProperties(*vertex).isolated())
    \n+
    2298 continue;
    \n+
    2299
    \n+
    2300 int twoWayCons = twoWayConnections(*vertex, aggregate_->id(), aggregates);
    \n+
    2301
    \n+
    2302 /* The case of two way connections. */
    \n+
    2303 if( maxTwoCons == twoWayCons && twoWayCons > 0) {
    \n+
    2304 double con = connectivity(*vertex, aggregates);
    \n+
    2305
    \n+
    2306 if(con == maxCon) {
    \n+
    2307 int neighbours = noFrontNeighbours(*vertex);
    \n+
    2308
    \n+
    2309 if(neighbours > maxNeighbours) {
    \n+
    2310 maxNeighbours = neighbours;
    \n+
    2311 candidates.clear();
    \n+
    2312 candidates.push_back(*vertex);
    \n+
    2313 }else{
    \n+
    2314 candidates.push_back(*vertex);
    \n+
    2315 }
    \n+
    2316 }else if( con > maxCon) {
    \n+
    2317 maxCon = con;
    \n+
    2318 maxNeighbours = noFrontNeighbours(*vertex);
    \n+
    2319 candidates.clear();
    \n+
    2320 candidates.push_back(*vertex);
    \n+
    2321 }
    \n+
    2322 }else if(twoWayCons > maxTwoCons) {
    \n+
    2323 maxTwoCons = twoWayCons;
    \n+
    2324 maxCon = connectivity(*vertex, aggregates);
    \n+
    2325 maxNeighbours = noFrontNeighbours(*vertex);
    \n+
    2326 candidates.clear();
    \n+
    2327 candidates.push_back(*vertex);
    \n+
    2328
    \n+
    2329 // two way connections precede
    \n+
    2330 maxOneCons = std::numeric_limits<int>::max();
    \n+
    2331 }
    \n+
    2332
    \n+
    2333 if(twoWayCons > 0)
    \n+
    2334 {
    \n+
    2335 continue; // THis is a two-way node, skip tests for one way nodes
    \n+
    2336 }
    \n+
    2337
    \n+
    2338 /* The one way case */
    \n+
    2339 int oneWayCons = oneWayConnections(*vertex, aggregate_->id(), aggregates);
    \n+
    2340
    \n+
    2341 if(oneWayCons==0)
    \n+
    2342 continue; // No strong connections, skip the tests.
    \n+
    2343
    \n+
    2344 if(!admissible(*vertex, aggregate_->id(), aggregates))
    \n+
    2345 continue;
    \n+
    2346
    \n+
    2347 if( maxOneCons == oneWayCons && oneWayCons > 0) {
    \n+
    2348 double con = connectivity(*vertex, aggregates);
    \n+
    2349
    \n+
    2350 if(con == maxCon) {
    \n+
    2351 int neighbours = noFrontNeighbours(*vertex);
    \n+
    2352
    \n+
    2353 if(neighbours > maxNeighbours) {
    \n+
    2354 maxNeighbours = neighbours;
    \n+
    2355 candidates.clear();
    \n+
    2356 candidates.push_back(*vertex);
    \n+
    2357 }else{
    \n+
    2358 if(neighbours==maxNeighbours)
    \n+
    2359 {
    \n+
    2360 candidates.push_back(*vertex);
    \n+
    2361 }
    \n+
    2362 }
    \n+
    2363 }else if( con > maxCon) {
    \n+
    2364 maxCon = con;
    \n+
    2365 maxNeighbours = noFrontNeighbours(*vertex);
    \n+
    2366 candidates.clear();
    \n+
    2367 candidates.push_back(*vertex);
    \n+
    2368 }
    \n+
    2369 }else if(oneWayCons > maxOneCons) {
    \n+
    2370 maxOneCons = oneWayCons;
    \n+
    2371 maxCon = connectivity(*vertex, aggregates);
    \n+
    2372 maxNeighbours = noFrontNeighbours(*vertex);
    \n+
    2373 candidates.clear();
    \n+
    2374 candidates.push_back(*vertex);
    \n+
    2375 }
    \n+
    2376 }
    \n+
    2377
    \n+
    2378
    \n+
    2379 if(!candidates.size())
    \n+
    2380 break; // No more candidates found
    \n+
    2381 distance_=distance(seed, aggregates);
    \n+
    2382 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
    \n+
    2383 aggregate_->size()));
    \n+
    2384 aggregate_->add(candidates);
    \n+
    2385 }
    \n+
    2386 }
    \n+
    2387
    \n+
    2388 template<typename V>
    \n+
    2389 template<typename M, typename G, typename C>
    \n+
    2390 std::tuple<int,int,int,int> AggregatesMap<V>::buildAggregates(const M& matrix, G& graph, const C& criterion,
    \n+
    2391 bool finestLevel)
    \n+
    2392 {
    \n+
    2393 Aggregator<G> aggregator;
    \n+
    2394 return aggregator.build(matrix, graph, *this, criterion, finestLevel);
    \n+
    2395 }
    \n+
    2396
    \n+
    2397 template<class G>
    \n+
    2398 template<class M, class C>
    \n+
    2399 std::tuple<int,int,int,int> Aggregator<G>::build(const M& m, G& graph, AggregatesMap<Vertex>& aggregates, const C& c,
    \n+
    2400 bool finestLevel)
    \n+
    2401 {
    \n+
    2402 using std::max;
    \n+
    2403 using std::min;
    \n+
    2404 // Stack for fast vertex access
    \n+
    2405 Stack stack_(graph, *this, aggregates);
    \n+
    2406
    \n+
    2407 graph_ = &graph;
    \n+
    2408
    \n+
    2409 aggregate_ = new Aggregate<G,VertexSet>(graph, aggregates, connected_, front_);
    \n+
    2410
    \n+
    2411 Timer watch;
    \n+
    2412 watch.reset();
    \n+
    2413
    \n+
    2414 buildDependency(graph, m, c, finestLevel);
    \n+
    2415
    \n+
    2416 dverb<<"Build dependency took "<< watch.elapsed()<<" seconds."<<std::endl;
    \n+
    2417 int noAggregates, conAggregates, isoAggregates, oneAggregates;
    \n+
    2418 std::size_t maxA=0, minA=1000000, avg=0;
    \n+
    2419 int skippedAggregates;
    \n+
    2420 noAggregates = conAggregates = isoAggregates = oneAggregates =
    \n+
    2421 skippedAggregates = 0;
    \n+
    2422
    \n+
    2423 while(true) {
    \n+
    2424 Vertex seed = stack_.pop();
    \n+
    2425
    \n+
    2426 if(seed == Stack::NullEntry)
    \n+
    2427 // No more unaggregated vertices. We are finished!
    \n+
    2428 break;
    \n+
    2429
    \n+
    2430 // Debugging output
    \n+
    2431 if((noAggregates+1)%10000 == 0)
    \n+
    2432 Dune::dverb<<"c";
    \n+
    2433 unmarkFront();
    \n+
    2434
    \n+
    2435 if(graph.getVertexProperties(seed).excludedBorder()) {
    \n+
    2436 aggregates[seed]=AggregatesMap<Vertex>::ISOLATED;
    \n+
    2437 ++skippedAggregates;
    \n+
    2438 continue;
    \n+
    2439 }
    \n+
    2440
    \n+
    2441 if(graph.getVertexProperties(seed).isolated()) {
    \n+
    2442 if(c.skipIsolated()) {
    \n+
    2443 // isolated vertices are not aggregated but skipped on the coarser levels.
    \n+
    2444 aggregates[seed]=AggregatesMap<Vertex>::ISOLATED;
    \n+
    2445 ++skippedAggregates;
    \n+
    2446 // skip rest as no agglomeration is done.
    \n+
    2447 continue;
    \n+
    2448 }else{
    \n+
    2449 aggregate_->seed(seed);
    \n+
    2450 growIsolatedAggregate(seed, aggregates, c);
    \n+
    2451 }
    \n+
    2452 }else{
    \n+
    2453 aggregate_->seed(seed);
    \n+
    2454 growAggregate(seed, aggregates, c);
    \n+
    2455 }
    \n+
    2456
    \n+
    2457 /* The rounding step. */
    \n+
    2458 while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->size() < c.maxAggregateSize()) {
    \n+
    2459
    \n+
    2460 std::vector<Vertex> candidates;
    \n+
    2461 candidates.reserve(30);
    \n+
    2462
    \n+
    2463 typedef typename std::vector<Vertex>::const_iterator Iterator;
    \n+
    2464
    \n+
    2465 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
    \n+
    2466
    \n+
    2467 if(graph.getVertexProperties(*vertex).isolated())
    \n+
    2468 continue; // No isolated nodes here
    \n+
    2469
    \n+
    2470 if(twoWayConnections( *vertex, aggregate_->id(), aggregates) == 0 &&
    \n+
    2471 (oneWayConnections( *vertex, aggregate_->id(), aggregates) == 0 ||
    \n+
    2472 !admissible( *vertex, aggregate_->id(), aggregates) ))
    \n+
    2473 continue;
    \n+
    2474
    \n+
    2475 std::pair<int,int> neighbourPair=neighbours(*vertex, aggregate_->id(),
    \n+
    2476 aggregates);
    \n+
    2477
    \n+
    2478 //if(aggregateNeighbours(*vertex, aggregate_->id(), aggregates) <= unusedNeighbours(*vertex, aggregates))
    \n+
    2479 // continue;
    \n+
    2480
    \n+
    2481 if(neighbourPair.first >= neighbourPair.second)
    \n+
    2482 continue;
    \n+
    2483
    \n+
    2484 if(distance(*vertex, aggregates) > c.maxDistance())
    \n+
    2485 continue; // Distance too far
    \n+
    2486 candidates.push_back(*vertex);
    \n+
    2487 break;
    \n+
    2488 }
    \n+
    2489
    \n+
    2490 if(!candidates.size()) break; // no more candidates found.
    \n+
    2491
    \n+
    2492 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
    \n+
    2493 aggregate_->size()));
    \n+
    2494 aggregate_->add(candidates);
    \n+
    2495
    \n+
    2496 }
    \n+
    2497
    \n+
    2498 // try to merge aggregates consisting of only one nonisolated vertex with other aggregates
    \n+
    2499 if(aggregate_->size()==1 && c.maxAggregateSize()>1) {
    \n+
    2500 if(!graph.getVertexProperties(seed).isolated()) {
    \n+
    2501 Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);
    \n+
    2502
    \n+
    2503 if(mergedNeighbour != AggregatesMap<Vertex>::UNAGGREGATED) {
    \n+
    2504 // assign vertex to the neighbouring cluster
    \n+
    2505 aggregates[seed] = aggregates[mergedNeighbour];
    \n+
    2506 aggregate_->invalidate();
    \n+
    2507 }else{
    \n+
    2508 ++avg;
    \n+
    2509 minA=min(minA,static_cast<std::size_t>(1));
    \n+
    2510 maxA=max(maxA,static_cast<std::size_t>(1));
    \n+
    2511 ++oneAggregates;
    \n+
    2512 ++conAggregates;
    \n+
    2513 }
    \n+
    2514 }else{
    \n+
    2515 ++avg;
    \n+
    2516 minA=min(minA,static_cast<std::size_t>(1));
    \n+
    2517 maxA=max(maxA,static_cast<std::size_t>(1));
    \n+
    2518 ++oneAggregates;
    \n+
    2519 ++isoAggregates;
    \n+
    2520 }
    \n+
    2521 ++avg;
    \n+
    2522 }else{
    \n+
    2523 avg+=aggregate_->size();
    \n+
    2524 minA=min(minA,aggregate_->size());
    \n+
    2525 maxA=max(maxA,aggregate_->size());
    \n+
    2526 if(graph.getVertexProperties(seed).isolated())
    \n+
    2527 ++isoAggregates;
    \n+
    2528 else
    \n+
    2529 ++conAggregates;
    \n+
    2530 }
    \n+
    2531
    \n+
    2532 }
    \n+
    2533
    \n+
    2534 Dune::dinfo<<"connected aggregates: "<<conAggregates;
    \n+
    2535 Dune::dinfo<<" isolated aggregates: "<<isoAggregates;
    \n+
    2536 if(conAggregates+isoAggregates>0)
    \n+
    2537 Dune::dinfo<<" one node aggregates: "<<oneAggregates<<" min size="
    \n+
    2538 <<minA<<" max size="<<maxA
    \n+
    2539 <<" avg="<<avg/(conAggregates+isoAggregates)<<std::endl;
    \n+
    2540
    \n+
    2541 delete aggregate_;
    \n+
    2542 return std::make_tuple(conAggregates+isoAggregates,isoAggregates,
    \n+
    2543 oneAggregates,skippedAggregates);
    \n+
    2544 }
    \n+
    2545
    \n+
    2546
    \n+
    2547 template<class G>
    \n+
    2548 Aggregator<G>::Stack::Stack(const MatrixGraph& graph, const Aggregator<G>& aggregatesBuilder,
    \n+
    2549 const AggregatesMap<Vertex>& aggregates)
    \n+
    2550 : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_(aggregates), begin_(graph.begin()), end_(graph.end())
    \n+
    2551 {
    \n+
    2552 //vals_ = new Vertex[N];
    \n+
    2553 }
    \n+
    2554
    \n+
    2555 template<class G>
    \n+
    2556 Aggregator<G>::Stack::~Stack()
    \n+
    2557 {
    \n+
    2558 //Dune::dverb << "Max stack size was "<<maxSize_<<" filled="<<filled_<<std::endl;
    \n+
    2559 //delete[] vals_;
    \n+
    2560 }
    \n+
    2561
    \n+
    2562 template<class G>
    \n+
    2563 const typename Aggregator<G>::Vertex Aggregator<G>::Stack::NullEntry
    \n+
    2564 = std::numeric_limits<typename G::VertexDescriptor>::max();
    \n+
    2565
    \n+
    2566 template<class G>
    \n+
    2567 inline typename G::VertexDescriptor Aggregator<G>::Stack::pop()
    \n+
    2568 {
    \n+
    2569 for(; begin_!=end_ && aggregates_[*begin_] != AggregatesMap<Vertex>::UNAGGREGATED; ++begin_) ;
    \n+
    2570
    \n+
    2571 if(begin_!=end_)
    \n+
    2572 {
    \n+
    2573 typename G::VertexDescriptor current=*begin_;
    \n+
    2574 ++begin_;
    \n+
    2575 return current;
    \n+
    2576 }else
    \n+
    2577 return NullEntry;
    \n+
    2578 }
    \n+
    2579
    \n+
    2580#endif // DOXYGEN
    \n+
    2581
    \n+
    2582 template<class V>
    \n+
    2583 void printAggregates2d(const AggregatesMap<V>& aggregates, int n, int m, std::ostream& os)
    \n+
    2584 {
    \n+
    2585 using std::max;
    \n+
    2586
    \n+
    2587 std::ios_base::fmtflags oldOpts=os.flags();
    \n+
    2588
    \n+
    2589 os.setf(std::ios_base::right, std::ios_base::adjustfield);
    \n+
    2590
    \n+
    2591 V maxVal=0;
    \n+
    2592 int width=1;
    \n+
    2593
    \n+
    2594 for(int i=0; i< n*m; i++)
    \n+
    2595 maxVal=max(maxVal, aggregates[i]);
    \n+
    2596
    \n+
    2597 for(int i=10; i < 1000000; i*=10)
    \n+
    2598 if(maxVal/i>0)
    \n+
    2599 width++;
    \n+
    2600 else
    \n+
    2601 break;
    \n+
    2602
    \n+
    2603 for(int j=0, entry=0; j < m; j++) {
    \n+
    2604 for(int i=0; i<n; i++, entry++) {
    \n+
    2605 os.width(width);
    \n+
    2606 os<<aggregates[entry]<<" ";
    \n+
    2607 }
    \n+
    2608
    \n+
    2609 os<<std::endl;
    \n+
    2610 }
    \n+
    2611 os<<std::endl;
    \n+
    2612 os.flags(oldOpts);
    \n+
    2613 }
    \n+
    2614
    \n+
    2615
    \n+
    2616 } // namespace Amg
    \n+
    2617
    \n+
    2618} // namespace Dune
    \n+
    2619
    \n+
    2620
    \n+
    2621#endif
    \n+
    Provides classes for building the matrix graph.
    \n+\n+
    Provides classes for handling internal properties in a graph.
    \n+
    Parameter classes for customizing AMG.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:273
    \n+
    std::vector< real_type >::iterator valIter_
    Definition: aggregates.hh:189
    \n+
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:154
    \n+
    std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, L &visited, F1 &aggregateVisitor, F2 &nonAggregateVisitor, VM &visitedMap) const
    Breadth first search within an aggregate.
    \n+
    PoolAllocator< VertexDescriptor, 100 > Allocator
    The allocator we use for our lists and the set.
    Definition: aggregates.hh:586
    \n+
    iterator begin()
    Definition: aggregates.hh:737
    \n+
    int id()
    Get the id identifying the aggregate.
    \n+
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:302
    \n+
    MatrixGraph::VertexDescriptor Vertex
    The vertex identifier.
    Definition: aggregates.hh:920
    \n+
    AggregationCriterion()
    Constructor.
    Definition: aggregates.hh:66
    \n+
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:357
    \n+
    auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr) const
    Compute the norm of a scalar.
    Definition: aggregates.hh:406
    \n+
    void initRow(const Row &row, int index)
    \n+
    SymmetricMatrixDependency(const Parameters &parms)
    Definition: aggregates.hh:168
    \n+
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:258
    \n+\n+
    G MatrixGraph
    The matrix graph type used.
    Definition: aggregates.hh:915
    \n+
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:363
    \n+
    void operator()(const EdgeIterator &edge) const
    Definition: aggregates.hh:601
    \n+
    SymmetricCriterion()
    Definition: aggregates.hh:524
    \n+
    Dependency()
    Definition: aggregates.hh:290
    \n+
    void examine(const ColIter &col)
    \n+
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:319
    \n+
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:187
    \n+
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:263
    \n+
    iterator end()
    Definition: aggregates.hh:742
    \n+
    UnSymmetricCriterion(const Parameters &parms)
    Definition: aggregates.hh:541
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    void initRow(const Row &row, int index)
    Definition: aggregates.hh:201
    \n+\n+
    static const Vertex NullEntry
    Definition: aggregates.hh:1008
    \n+
    void examine(const ColIter &col)
    Definition: aggregates.hh:214
    \n+
    Dependency(const Parameters &parms)
    Definition: aggregates.hh:286
    \n+
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:185
    \n+
    friend class Stack
    Definition: aggregates.hh:1036
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    std::tuple< int, int, int, int > build(const M &m, G &graph, AggregatesMap< Vertex > &aggregates, const C &c, bool finestLevel)
    Build the aggregates.
    \n+
    FrontNeighbourCounter(const MatrixGraph &front)
    Constructor.
    \n+
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:329
    \n+
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:296
    \n+
    const AggregateDescriptor & operator[](const VertexDescriptor &v) const
    Get the aggregate a vertex belongs to.
    \n+
    void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
    \n+
    AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const AggregateDescriptor &aggregate, Visitor &visitor)
    Constructor.
    \n+
    Matrix::ConstColIterator ColIter
    Constant column iterator of the matrix.
    Definition: aggregates.hh:334
    \n+
    ~AggregatesMap()
    Destructor.
    \n+
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:179
    \n+
    void decrement()
    Decrement counter.
    \n+
    Aggregate(MatrixGraph &graph, AggregatesMap< Vertex > &aggregates, VertexSet &connectivity, std::vector< Vertex > &front_)
    Constructor.
    \n+
    V Visitor
    The type of the adapted visitor.
    Definition: aggregates.hh:1064
    \n+
    std::size_t * SphereMap
    Type of the mapping of aggregate members onto distance spheres.
    Definition: aggregates.hh:809
    \n+
    AggregationCriterion(const Parameters &parms)
    Definition: aggregates.hh:70
    \n+
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:268
    \n+
    VertexSet::size_type connectSize()
    Get tne number of connections to other aggregates.
    \n+
    std::vector< real_type > vals_
    Definition: aggregates.hh:188
    \n+
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:324
    \n+
    void printAggregates2d(const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)
    Definition: aggregates.hh:2583
    \n+
    void invalidate()
    Definition: aggregates.hh:822
    \n+
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n+
    real_type maxValue_
    Definition: aggregates.hh:181
    \n+
    Norm norm_
    The functor for calculating the norm.
    Definition: aggregates.hh:183
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    VertexSet::const_iterator const_iterator
    Const iterator over a vertex list.
    Definition: aggregates.hh:804
    \n+
    SymmetricCriterion(const Parameters &parms)
    Definition: aggregates.hh:521
    \n+
    MatrixGraph::VertexDescriptor AggregateDescriptor
    The type of the aggregate descriptor.
    Definition: aggregates.hh:923
    \n+
    real_type maxValue_
    Definition: aggregates.hh:361
    \n+
    void init(const Matrix *matrix)
    Definition: aggregates.hh:195
    \n+
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:367
    \n+
    AggregateDescriptor * iterator
    Definition: aggregates.hh:735
    \n+
    SymmetricDependency(const Parameters &parms)
    Definition: aggregates.hh:348
    \n+
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:360
    \n+
    ~Aggregator()
    Destructor.
    \n+
    void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
    \n+
    void add(const Vertex &vertex)
    Add a vertex to the aggregate.
    \n+
    T DependencyPolicy
    The policy for calculating the dependency graph.
    Definition: aggregates.hh:55
    \n+
    void add(std::vector< Vertex > &vertex)
    \n+
    void examine(const ColIter &col)
    \n+
    Aggregator()
    Constructor.
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    Examine an edge.
    \n+
    FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)
    Constructor.
    \n+
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:506
    \n+
    void init(const Matrix *matrix)
    \n+
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n+
    void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an isotropic problem.
    Definition: aggregates.hh:82
    \n+
    const_iterator end() const
    Definition: aggregates.hh:730
    \n+
    V AggregateDescriptor
    The aggregate descriptor type.
    Definition: aggregates.hh:580
    \n+
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n+
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:365
    \n+
    SymmetricMatrixDependency()
    Definition: aggregates.hh:171
    \n+\n+\n+
    real_type diagonal_
    The norm of the current diagonal.
    Definition: aggregates.hh:306
    \n+
    std::size_t noVertices() const
    Get the number of vertices.
    \n+
    void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an aisotropic problem.
    Definition: aggregates.hh:105
    \n+
    AggregatesMap(std::size_t noVertices)
    Constructs with allocating memory.
    \n+
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:359
    \n+
    AggregateDescriptor & operator[](const VertexDescriptor &v)
    Get the aggregate a vertex belongs to.
    \n+
    AggregatesMap()
    Constructs without allocating memory.
    \n+
    int value()
    Access the current count.
    \n+
    SLList< VertexDescriptor, Allocator > VertexList
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:592
    \n+\n+
    ConnectivityCounter(const VertexSet &connected, const AggregatesMap< Vertex > &aggregates)
    Constructor.
    \n+
    VertexSet::size_type size()
    Get the size of the aggregate.
    \n+
    const_iterator end() const
    get an iterator over the vertices of the aggregate.
    \n+
    void init(const Matrix *matrix)
    \n+
    UnSymmetricCriterion()
    Definition: aggregates.hh:544
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    const AggregateDescriptor * const_iterator
    Definition: aggregates.hh:723
    \n+
    int row_
    index of the currently evaluated row.
    Definition: aggregates.hh:304
    \n+
    Stack(const MatrixGraph &graph, const Aggregator< G > &aggregatesBuilder, const AggregatesMap< Vertex > &aggregates)
    \n+
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:180
    \n+
    void initRow(const Row &row, int index)
    \n+
    M Matrix
    The matrix type we build the dependency of.
    Definition: aggregates.hh:139
    \n+
    FieldTraits< field_type >::real_type real_type
    Definition: aggregates.hh:299
    \n+
    const Matrix * matrix_
    The matrix we work on.
    Definition: aggregates.hh:177
    \n+
    S VertexSet
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:801
    \n+
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:490
    \n+
    static const V UNAGGREGATED
    Identifier of not yet aggregated vertices.
    Definition: aggregates.hh:566
    \n+
    std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, F &aggregateVisitor, VM &visitedMap) const
    Breadth first search within an aggregate.
    \n+
    Matrix::field_type field_type
    The current max value.
    Definition: aggregates.hh:298
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T > &criterion)
    Definition: aggregates.hh:113
    \n+
    bool isIsolated()
    Definition: aggregates.hh:240
    \n+
    void allocate(std::size_t noVertices)
    Allocate memory for holding the information.
    \n+
    N Norm
    The norm to use for examining the matrix entries.
    Definition: aggregates.hh:144
    \n+
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
    compute the norm of a matrix.
    Definition: aggregates.hh:473
    \n+
    void reconstruct(const Vertex &vertex)
    Reconstruct the aggregat from an seed node.
    \n+
    const_iterator begin() const
    get an iterator over the vertices of the aggregate.
    \n+
    FieldTraits< typenameM::field_type >::real_type operator()(const M &m, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr) const
    compute the norm of a matrix.
    Definition: aggregates.hh:390
    \n+
    MatrixGraph::VertexDescriptor Vertex
    The vertex descriptor type.
    Definition: aggregates.hh:789
    \n+
    void seed(const Vertex &vertex)
    Initialize the aggregate with one vertex.
    \n+\n+
    SymmetricDependency()
    Definition: aggregates.hh:351
    \n+
    void clear()
    Clear the aggregate.
    \n+
    void free()
    Free the allocated memory.
    \n+
    void increment()
    Increment counter.
    \n+
    void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
    Build the dependency of the matrix graph.
    \n+
    V VertexDescriptor
    The vertex descriptor type.
    Definition: aggregates.hh:575
    \n+
    real_type maxValue_
    Definition: aggregates.hh:300
    \n+
    std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph, const C &criterion, bool finestLevel)
    Build the aggregates.
    \n+
    Matrix::row_type Row
    Constant Row iterator of the matrix.
    Definition: aggregates.hh:149
    \n+
    PoolAllocator< Vertex, 100 > Allocator
    The allocator we use for our lists and the set.
    Definition: aggregates.hh:795
    \n+
    G MatrixGraph
    Definition: aggregates.hh:785
    \n+
    void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
    \n+
    @ is_sign_preserving
    Definition: aggregates.hh:483
    \n+
    @ is_sign_preserving
    Definition: aggregates.hh:382
    \n+
    @ is_sign_preserving
    Definition: aggregates.hh:499
    \n+
    @ is_sign_preserving
    Definition: aggregates.hh:466
    \n
    Definition: allocator.hh:11
    \n-
    Definition: pinfo.hh:28
    \n-
    SequentialInformation()
    Definition: pinfo.hh:91
    \n-
    T globalSum(const T &t) const
    Definition: pinfo.hh:49
    \n-
    void dot(const T1 &, const T1 &, T2 &) const
    Definition: pinfo.hh:74
    \n-
    EmptySet< int > CopyFlags
    Definition: pinfo.hh:31
    \n-
    AllSet< int > OwnerSet
    Definition: pinfo.hh:32
    \n-
    void copyOwnerToAll(V &v, V &v1) const
    Definition: pinfo.hh:66
    \n-
    MPICommunicator communicator() const
    Definition: pinfo.hh:38
    \n-
    void buildGlobalLookup(std::size_t)
    Definition: pinfo.hh:56
    \n-
    FieldTraits< typenameT1::field_type >::real_type norm(const T1 &) const
    Definition: pinfo.hh:81
    \n-
    void project(V &v) const
    Definition: pinfo.hh:70
    \n-
    Communication< void * > MPICommunicator
    Definition: pinfo.hh:30
    \n-
    SequentialInformation(const Communication< T > &)
    Definition: pinfo.hh:88
    \n-
    const GlobalLookupIndexSet & globalLookup() const
    Definition: pinfo.hh:60
    \n-
    SequentialInformation(const SequentialInformation &)
    Definition: pinfo.hh:94
    \n-
    void freeGlobalLookup()
    Definition: pinfo.hh:58
    \n-
    int GlobalLookupIndexSet
    Definition: pinfo.hh:54
    \n-
    SolverCategory::Category category() const
    Definition: pinfo.hh:34
    \n-
    int procs() const
    Definition: pinfo.hh:43
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n+
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n+
    Base class of all aggregation criterions.
    Definition: aggregates.hh:49
    \n+
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:134
    \n+
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:253
    \n+
    Dependency policy for symmetric matrices.
    Definition: aggregates.hh:314
    \n+
    Norm that uses only the [N][N] entry of the block to determine couplings.
    Definition: aggregates.hh:379
    \n+
    Norm that uses only the [0][0] entry of the block to determine couplings.
    Definition: aggregates.hh:455
    \n+
    Functor using the row sum (infinity) norm to determine strong couplings.
    Definition: aggregates.hh:463
    \n+
    Definition: aggregates.hh:480
    \n+
    Definition: aggregates.hh:496
    \n+
    Criterion taking advantage of symmetric matrices.
    Definition: aggregates.hh:519
    \n+
    Criterion suitable for unsymmetric matrices.
    Definition: aggregates.hh:539
    \n+
    Class for building the aggregates.
    Definition: aggregates.hh:909
    \n+
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n+
    A Dummy visitor that does nothing for each visited edge.
    Definition: aggregates.hh:598
    \n+
    A class for temporarily storing the vertices of an aggregate in.
    Definition: aggregates.hh:778
    \n+
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n+
    EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:298
    \n+
    Iterator over all edges starting from a vertex.
    Definition: graph.hh:95
    \n+
    The vertex iterator type of the graph.
    Definition: graph.hh:209
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,184 +5,2666 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-pinfo.hh\n+aggregates.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_PINFO_HH\n- 6#define DUNE_AMG_PINFO_HH\n+ 5#ifndef DUNE_AMG_AGGREGATES_HH\n+ 6#define DUNE_AMG_AGGREGATES_HH\n 7\n- 8#include \n- 9#include \n- 10\n- 11#if HAVE_MPI\n- 12\n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18\n- 19#endif\n+ 8\n+ 9#include \"parameters.hh\"\n+ 10#include \"graph.hh\"\n+ 11#include \"properties.hh\"\n+ 12#include \"combinedfunctor.hh\"\n+ 13\n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n 20\n- 21#include \n- 22namespace Dune\n- 23{\n- 24 namespace Amg\n- 25 {\n- 26\n-27 class SequentialInformation\n- 28 {\n- 29 public:\n-30 typedef Communication MPICommunicator;\n-31 typedef EmptySet CopyFlags;\n-32 typedef AllSet OwnerSet;\n+ 21#include \n+ 22#include \n+ 23#include \n+ 24#include \n+ 25#include \n+ 26#include \n+ 27#include \n+ 28\n+ 29namespace Dune\n+ 30{\n+ 31 namespace Amg\n+ 32 {\n 33\n-34 SolverCategory::Category category () const {\n- 35 return SolverCategory::sequential;\n- 36 }\n- 37\n-38 MPICommunicator communicator() const\n- 39 {\n- 40 return comm_;\n- 41 }\n- 42\n-43 int procs() const\n- 44 {\n- 45 return 1;\n- 46 }\n- 47\n- 48 template\n-49 T globalSum(const T& t) const\n- 50 {\n- 51 return t;\n- 52 }\n- 53\n-54 typedef int GlobalLookupIndexSet;\n- 55\n-56 void buildGlobalLookup(std::size_t){}\n- 57\n-58 void freeGlobalLookup(){}\n- 59\n-60 const GlobalLookupIndexSet& globalLookup() const\n- 61 {\n- 62 return gli;\n- 63 }\n- 64\n- 65 template\n-66 void copyOwnerToAll([[maybe_unused]] V& v, [[maybe_unused]] V& v1) const\n- 67 {}\n- 68\n- 69 template\n-70 void project([[maybe_unused]] V& v) const\n- 71 {}\n- 72\n- 73 template\n-74 void dot (const T1&, const T1&, T2&) const\n- 75 {\n- 76 // This function should never be called\n- 77 std::abort();\n- 78 }\n- 79\n- 80 template\n-81 typename FieldTraits::real_type norm (const T1&)\n-const\n- 82 {\n- 83 // This function should never be called\n- 84 std::abort();\n- 85 }\n+ 47 template\n+48 class AggregationCriterion : public T\n+ 49 {\n+ 50\n+ 51 public:\n+55 typedef T DependencyPolicy;\n+ 56\n+66 AggregationCriterion()\n+ 67 : T()\n+ 68 {}\n+ 69\n+70 AggregationCriterion(const Parameters& parms)\n+ 71 : T(parms)\n+ 72 {}\n+82 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n+ 83 {\n+ 84 this->setMaxDistance(diameter-1);\n+ 85 std::size_t csize=1;\n 86\n- 87 template\n-88 SequentialInformation(const Communication&)\n- 89 {}\n- 90\n-91 SequentialInformation()\n- 92 {}\n- 93\n-94 SequentialInformation(const SequentialInformation&)\n- 95 {}\n- 96 private:\n- 97 MPICommunicator comm_;\n- 98 GlobalLookupIndexSet gli;\n- 99 };\n- 100\n- 101\n- 102 } // namespace Amg\n- 103} //namespace Dune\n- 104#endif\n-solvercategory.hh\n+ 87 for(; dim>0; dim--) {\n+ 88 csize*=diameter;\n+ 89 this->setMaxDistance(this->maxDistance()+diameter-1);\n+ 90 }\n+ 91 this->setMinAggregateSize(csize);\n+ 92 this->setMaxAggregateSize(static_cast(csize*1.5));\n+ 93 }\n+ 94\n+105 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)\n+ 106 {\n+ 107 setDefaultValuesIsotropic(dim, diameter);\n+ 108 this->setMaxDistance(this->maxDistance()+dim-1);\n+ 109 }\n+ 110 };\n+ 111\n+ 112 template\n+113 std::ostream& operator<<(std::ostream& os, const AggregationCriterion&\n+criterion)\n+ 114 {\n+ 115 os<<\"{ maxdistance=\"<\n+133 class SymmetricMatrixDependency : public Dune::Amg::Parameters\n+ 134 {\n+ 135 public:\n+139 typedef M Matrix;\n+ 140\n+144 typedef N Norm;\n+ 145\n+149 typedef typename Matrix::row_type Row;\n+ 150\n+154 typedef typename Matrix::ConstColIterator ColIter;\n+ 155\n+ 156 void init(const Matrix* matrix);\n+ 157\n+ 158 void initRow(const Row& row, int index);\n+ 159\n+ 160 void examine(const ColIter& col);\n+ 161\n+ 162 template\n+ 163 void examine(G& graph, const typename G::EdgeIterator& edge, const\n+ColIter& col);\n+ 164\n+ 165 bool isIsolated();\n+ 166\n+ 167\n+168 SymmetricMatrixDependency(const Parameters& parms)\n+ 169 : Parameters(parms)\n+ 170 {}\n+171 SymmetricMatrixDependency()\n+ 172 : Parameters()\n+ 173 {}\n+ 174\n+ 175 protected:\n+177 const Matrix* matrix_;\n+179 typedef typename Matrix::field_type field_type;\n+180 typedef typename FieldTraits::real_type real_type;\n+181 real_type maxValue_;\n+183 Norm norm_;\n+185 int row_;\n+187 real_type diagonal_;\n+188 std::vector vals_;\n+189 typename std::vector::iterator valIter_;\n+ 190\n+ 191 };\n+ 192\n+ 193\n+ 194 template\n+195 inline void SymmetricMatrixDependency::init(const Matrix* matrix)\n+ 196 {\n+ 197 matrix_ = matrix;\n+ 198 }\n+ 199\n+ 200 template\n+201 inline void SymmetricMatrixDependency::initRow(const Row& row, int\n+index)\n+ 202 {\n+ 203 using std::min;\n+ 204 vals_.assign(row.size(), 0.0);\n+ 205 assert(vals_.size()==row.size());\n+ 206 valIter_=vals_.begin();\n+ 207\n+ 208 maxValue_ = min(- std::numeric_limits::max(), std::\n+numeric_limits::min());\n+ 209 diagonal_=norm_(row[index]);\n+ 210 row_ = index;\n+ 211 }\n+ 212\n+ 213 template\n+214 inline void SymmetricMatrixDependency::examine(const ColIter& col)\n+ 215 {\n+ 216 using std::max;\n+ 217 // skip positive offdiagonals if norm preserves sign of them.\n+ 218 real_type eij = norm_(*col);\n+ 219 if(!N::is_sign_preserving || eij<0) // || eji<0)\n+ 220 {\n+ 221 *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())\n+[col.index()]);\n+ 222 maxValue_ = max(maxValue_, *valIter_);\n+ 223 }else\n+ 224 *valIter_ =0;\n+ 225 ++valIter_;\n+ 226 }\n+ 227\n+ 228 template\n+ 229 template\n+230 inline void SymmetricMatrixDependency::examine(G&, const typename G::\n+EdgeIterator& edge, const ColIter&)\n+ 231 {\n+ 232 if(*valIter_ > alpha() * maxValue_) {\n+ 233 edge.properties().setDepends();\n+ 234 edge.properties().setInfluences();\n+ 235 }\n+ 236 ++valIter_;\n+ 237 }\n+ 238\n+ 239 template\n+240 inline bool SymmetricMatrixDependency::isIsolated()\n+ 241 {\n+ 242 if(diagonal_==0)\n+ 243 DUNE_THROW(Dune::ISTLError, \"No diagonal entry for row \"<\n+252 class Dependency : public Parameters\n+ 253 {\n+ 254 public:\n+258 typedef M Matrix;\n+ 259\n+263 typedef N Norm;\n+ 264\n+268 typedef typename Matrix::row_type Row;\n+ 269\n+273 typedef typename Matrix::ConstColIterator ColIter;\n+ 274\n+275 void init(const Matrix* matrix);\n+ 276\n+277 void initRow(const Row& row, int index);\n+ 278\n+279 void examine(const ColIter& col);\n+ 280\n+ 281 template\n+282 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter&\n+col);\n+ 283\n+284 bool isIsolated();\n+ 285\n+286 Dependency(const Parameters& parms)\n+ 287 : Parameters(parms)\n+ 288 {}\n+ 289\n+290 Dependency()\n+ 291 : Parameters()\n+ 292 {}\n+ 293\n+ 294 protected:\n+296 const Matrix* matrix_;\n+298 typedef typename Matrix::field_type field_type;\n+299 typedef typename FieldTraits::real_type real_type;\n+300 real_type maxValue_;\n+302 Norm norm_;\n+304 int row_;\n+306 real_type diagonal_;\n+ 307 };\n+ 308\n+ 312 template\n+313 class SymmetricDependency : public Parameters\n+ 314 {\n+ 315 public:\n+319 typedef M Matrix;\n+ 320\n+324 typedef N Norm;\n+ 325\n+329 typedef typename Matrix::row_type Row;\n+ 330\n+334 typedef typename Matrix::ConstColIterator ColIter;\n+ 335\n+336 void init(const Matrix* matrix);\n+ 337\n+338 void initRow(const Row& row, int index);\n+ 339\n+340 void examine(const ColIter& col);\n+ 341\n+ 342 template\n+343 void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter&\n+col);\n+ 344\n+345 bool isIsolated();\n+ 346\n+ 347\n+348 SymmetricDependency(const Parameters& parms)\n+ 349 : Parameters(parms)\n+ 350 {}\n+351 SymmetricDependency()\n+ 352 : Parameters()\n+ 353 {}\n+ 354\n+ 355 protected:\n+357 const Matrix* matrix_;\n+359 typedef typename Matrix::field_type field_type;\n+360 typedef typename FieldTraits::real_type real_type;\n+361 real_type maxValue_;\n+363 Norm norm_;\n+365 int row_;\n+367 real_type diagonal_;\n+ 368 private:\n+ 369 void initRow(const Row& row, int index, const std::true_type&);\n+ 370 void initRow(const Row& row, int index, const std::false_type&);\n+ 371 };\n+ 372\n+ 377 template\n+378 class Diagonal\n+ 379 {\n+ 380 public:\n+ 381 enum { /* @brief We preserve the sign.*/\n+ 382 is_sign_preserving = true\n+383 };\n+ 384\n+ 389 template\n+390 typename FieldTraits::real_type operator()(const M&\n+m,\n+ 391 [[maybe_unused]] typename std::enable_if_t::value>*\n+sfinae = nullptr) const\n+ 392 {\n+ 393 typedef typename M::field_type field_type;\n+ 394 typedef typename FieldTraits::real_type real_type;\n+ 395 static_assert( std::is_convertible::value,\n+ 396 \"use of diagonal norm in AMG not implemented for complex field_type\");\n+ 397 return m[N][N];\n+ 398 // possible implementation for complex types: return signed_abs(m[N][N]);\n+ 399 }\n+ 400\n+ 405 template\n+406 auto operator()(const M& m,\n+ 407 typename std::enable_if_t::value>* sfinae = nullptr)\n+const\n+ 408 {\n+ 409 typedef typename FieldTraits::real_type real_type;\n+ 410 static_assert( std::is_convertible::value,\n+ 411 \"use of diagonal norm in AMG not implemented for complex field_type\");\n+ 412 return m;\n+ 413 // possible implementation for complex types: return signed_abs(m[N][N]);\n+ 414 }\n+ 415\n+ 416 private:\n+ 417\n+ 419 template\n+ 420 static T signed_abs(const T & v)\n+ 421 {\n+ 422 return v;\n+ 423 }\n+ 424\n+ 426 template\n+ 427 static T signed_abs(const std::complex & v)\n+ 428 {\n+ 429 // return sign * abs_value\n+ 430 // in case of complex numbers this extends to using the csgn function to\n+determine the sign\n+ 431 return csgn(v) * std::abs(v);\n+ 432 }\n+ 433\n+ 435 template\n+ 436 static T csgn(const T & v)\n+ 437 {\n+ 438 return (T(0) < v) - (v < T(0));\n+ 439 }\n+ 440\n+ 442 template\n+ 443 static T csgn(std::complex a)\n+ 444 {\n+ 445 return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());\n+ 446 }\n+ 447\n+ 448 };\n+ 449\n+454 class FirstDiagonal : public Diagonal<0>\n+ 455 {};\n+ 456\n+462 struct RowSum\n+ 463 {\n+ 464\n+ 465 enum { /* @brief We preserve the sign.*/\n+ 466 is_sign_preserving = false\n+467 };\n+ 472 template\n+473 typename FieldTraits::real_type operator()(const M&\n+m) const\n+ 474 {\n+ 475 return m.infinity_norm();\n+ 476 }\n+ 477 };\n+ 478\n+479 struct FrobeniusNorm\n+ 480 {\n+ 481\n+ 482 enum { /* @brief We preserve the sign.*/\n+ 483 is_sign_preserving = false\n+484 };\n+ 489 template\n+490 typename FieldTraits::real_type operator()(const M&\n+m) const\n+ 491 {\n+ 492 return m.frobenius_norm();\n+ 493 }\n+ 494 };\n+495 struct AlwaysOneNorm\n+ 496 {\n+ 497\n+ 498 enum { /* @brief We preserve the sign.*/\n+ 499 is_sign_preserving = false\n+500 };\n+ 505 template\n+506 typename FieldTraits::real_type operator()(const M&\n+m) const\n+ 507 {\n+ 508 return 1;\n+ 509 }\n+ 510 };\n+ 517 template\n+518 class SymmetricCriterion : public\n+AggregationCriterion >\n+ 519 {\n+ 520 public:\n+521 SymmetricCriterion(const Parameters& parms)\n+ 522 : AggregationCriterion >(parms)\n+ 523 {}\n+524 SymmetricCriterion()\n+ 525 {}\n+ 526 };\n+ 527\n+ 528\n+ 537 template\n+538 class UnSymmetricCriterion : public AggregationCriterion\n+>\n+ 539 {\n+ 540 public:\n+541 UnSymmetricCriterion(const Parameters& parms)\n+ 542 : AggregationCriterion >(parms)\n+ 543 {}\n+544 UnSymmetricCriterion()\n+ 545 {}\n+ 546 };\n+ 547 // forward declaration\n+ 548 template class Aggregator;\n+ 549\n+ 550\n+ 558 template\n+559 class AggregatesMap\n+ 560 {\n+ 561 public:\n+ 562\n+566 static const V UNAGGREGATED;\n+ 567\n+571 static const V ISOLATED;\n+575 typedef V VertexDescriptor;\n+ 576\n+580 typedef V AggregateDescriptor;\n+ 581\n+586 typedef PoolAllocator Allocator;\n+ 587\n+592 typedef SLList VertexList;\n+ 593\n+597 class DummyEdgeVisitor\n+ 598 {\n+ 599 public:\n+ 600 template\n+601 void operator()([[maybe_unused]] const EdgeIterator& edge) const\n+ 602 {}\n+ 603 };\n+ 604\n+ 605\n+609 AggregatesMap();\n+ 610\n+616 AggregatesMap(std::size_t noVertices);\n+ 617\n+621 ~AggregatesMap();\n+ 622\n+ 634 template\n+635 std::tuple buildAggregates(const M& matrix, G& graph,\n+const C& criterion,\n+ 636 bool finestLevel);\n+ 637\n+ 655 template\n+656 std::size_t breadthFirstSearch(const VertexDescriptor& start,\n+ 657 const AggregateDescriptor& aggregate,\n+ 658 const G& graph,\n+ 659 F& aggregateVisitor,\n+ 660 VM& visitedMap) const;\n+ 661\n+ 685 template\n+686 std::size_t breadthFirstSearch(const VertexDescriptor& start,\n+ 687 const AggregateDescriptor& aggregate,\n+ 688 const G& graph, L& visited, F1& aggregateVisitor,\n+ 689 F2& nonAggregateVisitor,\n+ 690 VM& visitedMap) const;\n+ 691\n+697 void allocate(std::size_t noVertices);\n+ 698\n+702 std::size_t noVertices() const;\n+ 703\n+707 void free();\n+ 708\n+714 AggregateDescriptor& operator[](const VertexDescriptor& v);\n+ 715\n+721 const AggregateDescriptor& operator[](const VertexDescriptor& v) const;\n+ 722\n+723 typedef const AggregateDescriptor* const_iterator;\n+ 724\n+725 const_iterator begin() const\n+ 726 {\n+ 727 return aggregates_;\n+ 728 }\n+ 729\n+730 const_iterator end() const\n+ 731 {\n+ 732 return aggregates_+noVertices();\n+ 733 }\n+ 734\n+735 typedef AggregateDescriptor* iterator;\n+ 736\n+737 iterator begin()\n+ 738 {\n+ 739 return aggregates_;\n+ 740 }\n+ 741\n+742 iterator end()\n+ 743 {\n+ 744 return aggregates_+noVertices();\n+ 745 }\n+ 746 private:\n+ 748 AggregatesMap(const AggregatesMap&) = delete;\n+ 750 AggregatesMap& operator=(const AggregatesMap&) = delete;\n+ 751\n+ 755 AggregateDescriptor* aggregates_;\n+ 756\n+ 760 std::size_t noVertices_;\n+ 761 };\n+ 762\n+ 766 template\n+767 void buildDependency(G& graph,\n+ 768 const typename C::Matrix& matrix,\n+ 769 C criterion,\n+ 770 bool finestLevel);\n+ 771\n+ 776 template\n+777 class Aggregate\n+ 778 {\n+ 779\n+ 780 public:\n+ 781\n+ 782 /***\n+ 783 * @brief The type of the matrix graph we work with.\n+ 784 */\n+785 typedef G MatrixGraph;\n+789 typedef typename MatrixGraph::VertexDescriptor Vertex;\n+ 790\n+795 typedef PoolAllocator Allocator;\n+ 796\n+801 typedef S VertexSet;\n+ 802\n+804 typedef typename VertexSet::const_iterator const_iterator;\n+ 805\n+809 typedef std::size_t* SphereMap;\n+ 810\n+819 Aggregate(MatrixGraph& graph, AggregatesMap& aggregates,\n+ 820 VertexSet& connectivity, std::vector& front_);\n+ 821\n+822 void invalidate()\n+ 823 {\n+ 824 --id_;\n+ 825 }\n+ 826\n+833 void reconstruct(const Vertex& vertex);\n+ 834\n+838 void seed(const Vertex& vertex);\n+ 839\n+843 void add(const Vertex& vertex);\n+ 844\n+845 void add(std::vector& vertex);\n+849 void clear();\n+ 850\n+854 typename VertexSet::size_type size();\n+858 typename VertexSet::size_type connectSize();\n+ 859\n+863 int id();\n+ 864\n+866 const_iterator begin() const;\n+ 867\n+869 const_iterator end() const;\n+ 870\n+ 871 private:\n+ 875 VertexSet vertices_;\n+ 876\n+ 881 int id_;\n+ 882\n+ 886 MatrixGraph& graph_;\n+ 887\n+ 891 AggregatesMap& aggregates_;\n+ 892\n+ 896 VertexSet& connected_;\n+ 897\n+ 901 std::vector& front_;\n+ 902 };\n+ 903\n+ 907 template\n+908 class Aggregator\n+ 909 {\n+ 910 public:\n+ 911\n+915 typedef G MatrixGraph;\n+ 916\n+920 typedef typename MatrixGraph::VertexDescriptor Vertex;\n+ 921\n+923 typedef typename MatrixGraph::VertexDescriptor AggregateDescriptor;\n+ 924\n+928 Aggregator();\n+ 929\n+933 ~Aggregator();\n+ 934\n+ 951 template\n+952 std::tuple build(const M& m, G& graph,\n+ 953 AggregatesMap& aggregates, const C& c,\n+ 954 bool finestLevel);\n+ 955 private:\n+ 960 typedef PoolAllocator Allocator;\n+ 961\n+ 965 typedef SLList VertexList;\n+ 966\n+ 970 typedef std::set,Allocator> VertexSet;\n+ 971\n+ 975 typedef std::size_t* SphereMap;\n+ 976\n+ 980 MatrixGraph* graph_;\n+ 981\n+ 985 Aggregate* aggregate_;\n+ 986\n+ 990 std::vector front_;\n+ 991\n+ 995 VertexSet connected_;\n+ 996\n+ 1000 int size_;\n+ 1001\n+ 1005 class Stack\n+ 1006 {\n+ 1007 public:\n+1008 static const Vertex NullEntry;\n+ 1009\n+1010 Stack(const MatrixGraph& graph,\n+ 1011 const Aggregator& aggregatesBuilder,\n+ 1012 const AggregatesMap& aggregates);\n+1013 ~Stack();\n+1014 Vertex pop();\n+ 1015 private:\n+ 1016 enum { N = 1300000 };\n+ 1017\n+ 1019 const MatrixGraph& graph_;\n+ 1021 const Aggregator& aggregatesBuilder_;\n+ 1023 const AggregatesMap& aggregates_;\n+ 1025 int size_;\n+ 1026 Vertex maxSize_;\n+ 1028 typename MatrixGraph::ConstVertexIterator begin_;\n+ 1029 typename MatrixGraph::ConstVertexIterator end_;\n+ 1030\n+ 1032 Vertex* vals_;\n+ 1033\n+ 1034 };\n+ 1035\n+1036 friend class Stack;\n+ 1037\n+ 1048 template\n+ 1049 void visitAggregateNeighbours(const Vertex& vertex, const\n+AggregateDescriptor& aggregate,\n+ 1050 const AggregatesMap& aggregates,\n+ 1051 V& visitor) const;\n+ 1052\n+ 1057 template\n+ 1058 class AggregateVisitor\n+ 1059 {\n+ 1060 public:\n+1064 typedef V Visitor;\n+1072 AggregateVisitor(const AggregatesMap& aggregates, const\n+AggregateDescriptor& aggregate,\n+ 1073 Visitor& visitor);\n+ 1074\n+1081 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1082\n+ 1083 private:\n+ 1085 const AggregatesMap& aggregates_;\n+ 1087 AggregateDescriptor aggregate_;\n+ 1089 Visitor* visitor_;\n+ 1090 };\n+ 1091\n+ 1095 class Counter\n+ 1096 {\n+ 1097 public:\n+1099 Counter();\n+1101 int value();\n+ 1102\n+ 1103 protected:\n+1105 void increment();\n+1107 void decrement();\n+ 1108\n+ 1109 private:\n+ 1110 int count_;\n+ 1111 };\n+ 1112\n+ 1113\n+ 1118 class FrontNeighbourCounter : public Counter\n+ 1119 {\n+ 1120 public:\n+1125 FrontNeighbourCounter(const MatrixGraph& front);\n+ 1126\n+1127 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1128\n+ 1129 private:\n+ 1130 const MatrixGraph& graph_;\n+ 1131 };\n+ 1132\n+ 1137 int noFrontNeighbours(const Vertex& vertex) const;\n+ 1138\n+ 1142 class TwoWayCounter : public Counter\n+ 1143 {\n+ 1144 public:\n+1145 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1146 };\n+ 1147\n+ 1159 int twoWayConnections(const Vertex&, const AggregateDescriptor&\n+aggregate,\n+ 1160 const AggregatesMap& aggregates) const;\n+ 1161\n+ 1165 class OneWayCounter : public Counter\n+ 1166 {\n+ 1167 public:\n+1168 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1169 };\n+ 1170\n+ 1182 int oneWayConnections(const Vertex&, const AggregateDescriptor&\n+aggregate,\n+ 1183 const AggregatesMap& aggregates) const;\n+ 1184\n+ 1191 class ConnectivityCounter : public Counter\n+ 1192 {\n+ 1193 public:\n+1200 ConnectivityCounter(const VertexSet& connected, const\n+AggregatesMap& aggregates);\n+ 1201\n+1202 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1203\n+ 1204 private:\n+ 1206 const VertexSet& connected_;\n+ 1208 const AggregatesMap& aggregates_;\n+ 1209\n+ 1210 };\n+ 1211\n+ 1223 double connectivity(const Vertex& vertex, const AggregatesMap&\n+aggregates) const;\n+ 1231 bool connected(const Vertex& vertex, const AggregateDescriptor&\n+aggregate,\n+ 1232 const AggregatesMap& aggregates) const;\n+ 1233\n+ 1241 bool connected(const Vertex& vertex, const SLList&\n+aggregateList,\n+ 1242 const AggregatesMap& aggregates) const;\n+ 1243\n+ 1251 class DependencyCounter : public Counter\n+ 1252 {\n+ 1253 public:\n+1257 DependencyCounter();\n+ 1258\n+1259 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1260 };\n+ 1261\n+ 1268 class FrontMarker\n+ 1269 {\n+ 1270 public:\n+1277 FrontMarker(std::vector& front, MatrixGraph& graph);\n+ 1278\n+1279 void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);\n+ 1280\n+ 1281 private:\n+ 1283 std::vector& front_;\n+ 1285 MatrixGraph& graph_;\n+ 1286 };\n+ 1287\n+ 1291 void unmarkFront();\n+ 1292\n+ 1307 int unusedNeighbours(const Vertex& vertex, const AggregatesMap&\n+aggregates) const;\n+ 1308\n+ 1322 std::pair neighbours(const Vertex& vertex,\n+ 1323 const AggregateDescriptor& aggregate,\n+ 1324 const AggregatesMap& aggregates) const;\n+ 1341 int aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor&\n+aggregate, const AggregatesMap& aggregates) const;\n+ 1342\n+ 1350 bool admissible(const Vertex& vertex, const AggregateDescriptor&\n+aggregate, const AggregatesMap& aggregates) const;\n+ 1351\n+ 1359 std::size_t distance(const Vertex& vertex, const AggregatesMap&\n+aggregates);\n+ 1360\n+ 1369 Vertex mergeNeighbour(const Vertex& vertex, const AggregatesMap&\n+aggregates) const;\n+ 1370\n+ 1379 void nonisoNeighbourAggregate(const Vertex& vertex,\n+ 1380 const AggregatesMap& aggregates,\n+ 1381 SLList& neighbours) const;\n+ 1382\n+ 1390 template\n+ 1391 void growAggregate(const Vertex& vertex, const AggregatesMap&\n+aggregates, const C& c);\n+ 1392 template\n+ 1393 void growIsolatedAggregate(const Vertex& vertex, const\n+AggregatesMap& aggregates, const C& c);\n+ 1394 };\n+ 1395\n+ 1396#ifndef DOXYGEN\n+ 1397\n+ 1398 template\n+ 1399 inline void SymmetricDependency::init(const Matrix* matrix)\n+ 1400 {\n+ 1401 matrix_ = matrix;\n+ 1402 }\n+ 1403\n+ 1404 template\n+ 1405 inline void SymmetricDependency::initRow(const Row& row, int index)\n+ 1406 {\n+ 1407 initRow(row, index, std::is_convertible());\n+ 1408 }\n+ 1409\n+ 1410 template\n+ 1411 inline void SymmetricDependency::initRow(const Row& row, int index,\n+const std::false_type&)\n+ 1412 {\n+ 1413 DUNE_THROW(InvalidStateException, \"field_type needs to convertible to\n+real_type\");\n+ 1414 }\n+ 1415\n+ 1416 template\n+ 1417 inline void SymmetricDependency::initRow([[maybe_unused]] const Row&\n+row, int index, const std::true_type&)\n+ 1418 {\n+ 1419 using std::min;\n+ 1420 maxValue_ = min(- std::numeric_limits::max\n+(), std::numeric_limits::min());\n+ 1421 row_ = index;\n+ 1422 diagonal_ = norm_(matrix_->operator[](row_)[row_]);\n+ 1423 }\n+ 1424\n+ 1425 template\n+ 1426 inline void SymmetricDependency::examine(const ColIter& col)\n+ 1427 {\n+ 1428 using std::max;\n+ 1429 real_type eij = norm_(*col);\n+ 1430 typename Matrix::ConstColIterator opposite_entry =\n+ 1431 matrix_->operator[](col.index()).find(row_);\n+ 1432 if ( opposite_entry == matrix_->operator[](col.index()).end() )\n+ 1433 {\n+ 1434 // Consider this a weak connection we disregard.\n+ 1435 return;\n+ 1436 }\n+ 1437 real_type eji = norm_(*opposite_entry);\n+ 1438\n+ 1439 // skip positive offdiagonals if norm preserves sign of them.\n+ 1440 if(!N::is_sign_preserving || eij<0 || eji<0)\n+ 1441 maxValue_ = max(maxValue_,\n+ 1442 eij /diagonal_ * eji/\n+ 1443 norm_(matrix_->operator[](col.index())[col.index()]));\n+ 1444 }\n+ 1445\n+ 1446 template\n+ 1447 template\n+ 1448 inline void SymmetricDependency::examine(G& graph, const typename\n+G::EdgeIterator& edge, const ColIter& col)\n+ 1449 {\n+ 1450 real_type eij = norm_(*col);\n+ 1451 typename Matrix::ConstColIterator opposite_entry =\n+ 1452 matrix_->operator[](col.index()).find(row_);\n+ 1453\n+ 1454 if ( opposite_entry == matrix_->operator[](col.index()).end() )\n+ 1455 {\n+ 1456 // Consider this as a weak connection we disregard.\n+ 1457 return;\n+ 1458 }\n+ 1459 real_type eji = norm_(*opposite_entry);\n+ 1460 // skip positve offdiagonals if norm preserves sign of them.\n+ 1461 if(!N::is_sign_preserving || (eij<0 || eji<0))\n+ 1462 if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *\n+ 1463 eij/ diagonal_ > alpha() * maxValue_) {\n+ 1464 edge.properties().setDepends();\n+ 1465 edge.properties().setInfluences();\n+ 1466 typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target\n+(), edge.source());\n+ 1467 other.setInfluences();\n+ 1468 other.setDepends();\n+ 1469 }\n+ 1470 }\n+ 1471\n+ 1472 template\n+ 1473 inline bool SymmetricDependency::isIsolated()\n+ 1474 {\n+ 1475 return maxValue_ < beta();\n+ 1476 }\n+ 1477\n+ 1478\n+ 1479 template\n+ 1480 inline void Dependency::init(const Matrix* matrix)\n+ 1481 {\n+ 1482 matrix_ = matrix;\n+ 1483 }\n+ 1484\n+ 1485 template\n+ 1486 inline void Dependency::initRow([[maybe_unused]] const Row& row, int\n+index)\n+ 1487 {\n+ 1488 using std::min;\n+ 1489 maxValue_ = min(- std::numeric_limits::max(), std::\n+numeric_limits::min());\n+ 1490 row_ = index;\n+ 1491 diagonal_ = norm_(matrix_->operator[](row_)[row_]);\n+ 1492 }\n+ 1493\n+ 1494 template\n+ 1495 inline void Dependency::examine(const ColIter& col)\n+ 1496 {\n+ 1497 using std::max;\n+ 1498 maxValue_ = max(maxValue_, -norm_(*col));\n+ 1499 }\n+ 1500\n+ 1501 template\n+ 1502 template\n+ 1503 inline void Dependency::examine(G& graph, const typename G::\n+EdgeIterator& edge, const ColIter& col)\n+ 1504 {\n+ 1505 if(-norm_(*col) >= maxValue_ * alpha()) {\n+ 1506 edge.properties().setDepends();\n+ 1507 typedef typename G::EdgeDescriptor ED;\n+ 1508 ED e= graph.findEdge(edge.target(), edge.source());\n+ 1509 if(e!=std::numeric_limits::max())\n+ 1510 {\n+ 1511 typename G::EdgeProperties& other = graph.getEdgeProperties(e);\n+ 1512 other.setInfluences();\n+ 1513 }\n+ 1514 }\n+ 1515 }\n+ 1516\n+ 1517 template\n+ 1518 inline bool Dependency::isIsolated()\n+ 1519 {\n+ 1520 return maxValue_ < beta() * diagonal_;\n+ 1521 }\n+ 1522\n+ 1523 template\n+ 1524 Aggregate::Aggregate(MatrixGraph& graph, AggregatesMap&\n+aggregates,\n+ 1525 VertexSet& connected, std::vector& front)\n+ 1526 : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),\n+ 1527 connected_(connected), front_(front)\n+ 1528 {}\n+ 1529\n+ 1530 template\n+ 1531 void Aggregate::reconstruct(const Vertex& vertex)\n+ 1532 {\n+ 1533 /*\n+ 1534 vertices_.push_back(vertex);\n+ 1535 typedef typename VertexList::const_iterator iterator;\n+ 1536 iterator begin = vertices_.begin();\n+ 1537 iterator end = vertices_.end();*/\n+ 1538 throw \"Not yet implemented\";\n+ 1539\n+ 1540 // while(begin!=end){\n+ 1541 //for();\n+ 1542 // }\n+ 1543\n+ 1544 }\n+ 1545\n+ 1546 template\n+ 1547 inline void Aggregate::seed(const Vertex& vertex)\n+ 1548 {\n+ 1549 dvverb<<\"Connected cleared\"<\n+ 1560 inline void Aggregate::add(const Vertex& vertex)\n+ 1561 {\n+ 1562 vertices_.insert(vertex);\n+ 1563 aggregates_[vertex]=id_;\n+ 1564 if(front_.size())\n+ 1565 front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));\n+ 1566\n+ 1567\n+ 1568 typedef typename MatrixGraph::ConstEdgeIterator iterator;\n+ 1569 const iterator end = graph_.endEdges(vertex);\n+ 1570 for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {\n+ 1571 dvverb << \" Inserting \"<::UNAGGREGATED &&\n+ 1575 !graph_.getVertexProperties(edge.target()).front())\n+ 1576 {\n+ 1577 front_.push_back(edge.target());\n+ 1578 graph_.getVertexProperties(edge.target()).setFront();\n+ 1579 }\n+ 1580 }\n+ 1581 dvverb <\n+ 1586 inline void Aggregate::add(std::vector& vertices)\n+ 1587 {\n+ 1588#ifndef NDEBUG\n+ 1589 std::size_t oldsize = vertices_.size();\n+ 1590#endif\n+ 1591 typedef typename std::vector::iterator Iterator;\n+ 1592\n+ 1593 typedef typename VertexSet::iterator SIterator;\n+ 1594\n+ 1595 SIterator pos=vertices_.begin();\n+ 1596 std::vector newFront;\n+ 1597 newFront.reserve(front_.capacity());\n+ 1598\n+ 1599 std::set_difference(front_.begin(), front_.end(), vertices.begin(),\n+vertices.end(),\n+ 1600 std::back_inserter(newFront));\n+ 1601 front_=newFront;\n+ 1602\n+ 1603 for(Iterator vertex=vertices.begin(); vertex != vertices.end(); ++vertex)\n+ 1604 {\n+ 1605 pos=vertices_.insert(pos,*vertex);\n+ 1606 vertices_.insert(*vertex);\n+ 1607 graph_.getVertexProperties(*vertex).resetFront(); // Not a front node any\n+more.\n+ 1608 aggregates_[*vertex]=id_;\n+ 1609\n+ 1610 typedef typename MatrixGraph::ConstEdgeIterator iterator;\n+ 1611 const iterator end = graph_.endEdges(*vertex);\n+ 1612 for(iterator edge = graph_.beginEdges(*vertex); edge != end; ++edge) {\n+ 1613 dvverb << \" Inserting \"<::UNAGGREGATED &&\n+ 1616 !graph_.getVertexProperties(edge.target()).front())\n+ 1617 {\n+ 1618 front_.push_back(edge.target());\n+ 1619 graph_.getVertexProperties(edge.target()).setFront();\n+ 1620 }\n+ 1621 dvverb <<\" size=\"<\n+ 1629 inline void Aggregate::clear()\n+ 1630 {\n+ 1631 vertices_.clear();\n+ 1632 connected_.clear();\n+ 1633 id_=-1;\n+ 1634 }\n+ 1635\n+ 1636 template\n+ 1637 inline typename Aggregate::VertexSet::size_type\n+ 1638 Aggregate::size()\n+ 1639 {\n+ 1640 return vertices_.size();\n+ 1641 }\n+ 1642\n+ 1643 template\n+ 1644 inline typename Aggregate::VertexSet::size_type\n+ 1645 Aggregate::connectSize()\n+ 1646 {\n+ 1647 return connected_.size();\n+ 1648 }\n+ 1649\n+ 1650 template\n+ 1651 inline int Aggregate::id()\n+ 1652 {\n+ 1653 return id_;\n+ 1654 }\n+ 1655\n+ 1656 template\n+ 1657 inline typename Aggregate::const_iterator Aggregate::begin()\n+const\n+ 1658 {\n+ 1659 return vertices_.begin();\n+ 1660 }\n+ 1661\n+ 1662 template\n+ 1663 inline typename Aggregate::const_iterator Aggregate::end()\n+const\n+ 1664 {\n+ 1665 return vertices_.end();\n+ 1666 }\n+ 1667\n+ 1668 template\n+ 1669 const V AggregatesMap::UNAGGREGATED = std::numeric_limits::max();\n+ 1670\n+ 1671 template\n+ 1672 const V AggregatesMap::ISOLATED = std::numeric_limits::max()-1;\n+ 1673\n+ 1674 template\n+ 1675 AggregatesMap::AggregatesMap()\n+ 1676 : aggregates_(0)\n+ 1677 {}\n+ 1678\n+ 1679 template\n+ 1680 AggregatesMap::~AggregatesMap()\n+ 1681 {\n+ 1682 if(aggregates_!=0)\n+ 1683 delete[] aggregates_;\n+ 1684 }\n+ 1685\n+ 1686\n+ 1687 template\n+ 1688 inline AggregatesMap::AggregatesMap(std::size_t noVertices)\n+ 1689 {\n+ 1690 allocate(noVertices);\n+ 1691 }\n+ 1692\n+ 1693 template\n+ 1694 inline std::size_t AggregatesMap::noVertices() const\n+ 1695 {\n+ 1696 return noVertices_;\n+ 1697 }\n+ 1698\n+ 1699 template\n+ 1700 inline void AggregatesMap::allocate(std::size_t noVertices)\n+ 1701 {\n+ 1702 aggregates_ = new AggregateDescriptor[noVertices];\n+ 1703 noVertices_ = noVertices;\n+ 1704\n+ 1705 for(std::size_t i=0; i < noVertices; i++)\n+ 1706 aggregates_[i]=UNAGGREGATED;\n+ 1707 }\n+ 1708\n+ 1709 template\n+ 1710 inline void AggregatesMap::free()\n+ 1711 {\n+ 1712 assert(aggregates_ != 0);\n+ 1713 delete[] aggregates_;\n+ 1714 aggregates_=0;\n+ 1715 }\n+ 1716\n+ 1717 template\n+ 1718 inline typename AggregatesMap::AggregateDescriptor&\n+ 1719 AggregatesMap::operator[](const VertexDescriptor& v)\n+ 1720 {\n+ 1721 return aggregates_[v];\n+ 1722 }\n+ 1723\n+ 1724 template\n+ 1725 inline const typename AggregatesMap::AggregateDescriptor&\n+ 1726 AggregatesMap::operator[](const VertexDescriptor& v) const\n+ 1727 {\n+ 1728 return aggregates_[v];\n+ 1729 }\n+ 1730\n+ 1731 template\n+ 1732 template\n+ 1733 inline std::size_t AggregatesMap::breadthFirstSearch(const V& start,\n+ 1734 const AggregateDescriptor& aggregate,\n+ 1735 const G& graph, F& aggregateVisitor,\n+ 1736 VM& visitedMap) const\n+ 1737 {\n+ 1738 VertexList vlist;\n+ 1739\n+ 1740 DummyEdgeVisitor dummy;\n+ 1741 return breadthFirstSearch(start, aggregate, graph, vlist,\n+aggregateVisitor, dummy, visitedMap);\n+ 1742 }\n+ 1743\n+ 1744 template\n+ 1745 template\n+ 1746 std::size_t AggregatesMap::breadthFirstSearch(const V& start,\n+ 1747 const AggregateDescriptor& aggregate,\n+ 1748 const G& graph,\n+ 1749 L& visited,\n+ 1750 F1& aggregateVisitor,\n+ 1751 F2& nonAggregateVisitor,\n+ 1752 VM& visitedMap) const\n+ 1753 {\n+ 1754 typedef typename L::const_iterator ListIterator;\n+ 1755 int visitedSpheres = 0;\n+ 1756\n+ 1757 visited.push_back(start);\n+ 1758 put(visitedMap, start, true);\n+ 1759\n+ 1760 ListIterator current = visited.begin();\n+ 1761 ListIterator end = visited.end();\n+ 1762 std::size_t i=0, size=visited.size();\n+ 1763\n+ 1764 // visit the neighbours of all vertices of the\n+ 1765 // current sphere.\n+ 1766 while(current != end) {\n+ 1767\n+ 1768 for(; i\n+ 1803 Aggregator::Aggregator()\n+ 1804 : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)\n+ 1805 {}\n+ 1806\n+ 1807 template\n+ 1808 Aggregator::~Aggregator()\n+ 1809 {\n+ 1810 size_=-1;\n+ 1811 }\n+ 1812\n+ 1813 template\n+ 1814 void buildDependency(G& graph,\n+ 1815 const typename C::Matrix& matrix,\n+ 1816 C criterion, bool firstlevel)\n+ 1817 {\n+ 1818 // assert(graph.isBuilt());\n+ 1819 typedef typename C::Matrix Matrix;\n+ 1820 typedef typename G::VertexIterator VertexIterator;\n+ 1821\n+ 1822 criterion.init(&matrix);\n+ 1823\n+ 1824 for(VertexIterator vertex = graph.begin(); vertex != graph.end();\n+++vertex) {\n+ 1825 typedef typename Matrix::row_type Row;\n+ 1826\n+ 1827 const Row& row = matrix[*vertex];\n+ 1828\n+ 1829 // Tell the criterion what row we will examine now\n+ 1830 // This might for example be used for calculating the\n+ 1831 // maximum offdiagonal value\n+ 1832 criterion.initRow(row, *vertex);\n+ 1833\n+ 1834 // On a first path all columns are examined. After this\n+ 1835 // the calculator should know whether the vertex is isolated.\n+ 1836 typedef typename Matrix::ConstColIterator ColIterator;\n+ 1837 ColIterator end = row.end();\n+ 1838 typename FieldTraits::real_type\n+absoffdiag=0.;\n+ 1839\n+ 1840 using std::max;\n+ 1841 if(firstlevel) {\n+ 1842 for(ColIterator col = row.begin(); col != end; ++col)\n+ 1843 if(col.index()!=*vertex) {\n+ 1844 criterion.examine(col);\n+ 1845 absoffdiag = max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());\n+ 1846 }\n+ 1847\n+ 1848 if(absoffdiag==0)\n+ 1849 vertex.properties().setExcludedBorder();\n+ 1850 }\n+ 1851 else\n+ 1852 for(ColIterator col = row.begin(); col != end; ++col)\n+ 1853 if(col.index()!=*vertex)\n+ 1854 criterion.examine(col);\n+ 1855\n+ 1856 // reset the vertex properties\n+ 1857 //vertex.properties().reset();\n+ 1858\n+ 1859 // Check whether the vertex is isolated.\n+ 1860 if(criterion.isIsolated()) {\n+ 1861 //std::cout<<\"ISOLATED: \"<<*vertex<\n+ 1881 template\n+ 1882 inline Aggregator::AggregateVisitor::AggregateVisitor(const\n+AggregatesMap& aggregates,\n+ 1883 const AggregateDescriptor& aggregate, V& visitor)\n+ 1884 : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)\n+ 1885 {}\n+ 1886\n+ 1887 template\n+ 1888 template\n+ 1889 inline void Aggregator::AggregateVisitor::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 1890 {\n+ 1891 if(aggregates_[edge.target()]==aggregate_)\n+ 1892 visitor_->operator()(edge);\n+ 1893 }\n+ 1894\n+ 1895 template\n+ 1896 template\n+ 1897 inline void Aggregator::visitAggregateNeighbours(const Vertex& vertex,\n+ 1898 const AggregateDescriptor& aggregate,\n+ 1899 const AggregatesMap& aggregates,\n+ 1900 V& visitor) const\n+ 1901 {\n+ 1902 // Only evaluates for edge pointing to the aggregate\n+ 1903 AggregateVisitor v(aggregates, aggregate, visitor);\n+ 1904 visitNeighbours(*graph_, vertex, v);\n+ 1905 }\n+ 1906\n+ 1907\n+ 1908 template\n+ 1909 inline Aggregator::Counter::Counter()\n+ 1910 : count_(0)\n+ 1911 {}\n+ 1912\n+ 1913 template\n+ 1914 inline void Aggregator::Counter::increment()\n+ 1915 {\n+ 1916 ++count_;\n+ 1917 }\n+ 1918\n+ 1919 template\n+ 1920 inline void Aggregator::Counter::decrement()\n+ 1921 {\n+ 1922 --count_;\n+ 1923 }\n+ 1924 template\n+ 1925 inline int Aggregator::Counter::value()\n+ 1926 {\n+ 1927 return count_;\n+ 1928 }\n+ 1929\n+ 1930 template\n+ 1931 inline void Aggregator::TwoWayCounter::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 1932 {\n+ 1933 if(edge.properties().isTwoWay())\n+ 1934 Counter::increment();\n+ 1935 }\n+ 1936\n+ 1937 template\n+ 1938 int Aggregator::twoWayConnections(const Vertex& vertex, const\n+AggregateDescriptor& aggregate,\n+ 1939 const AggregatesMap& aggregates) const\n+ 1940 {\n+ 1941 TwoWayCounter counter;\n+ 1942 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n+ 1943 return counter.value();\n+ 1944 }\n+ 1945\n+ 1946 template\n+ 1947 int Aggregator::oneWayConnections(const Vertex& vertex, const\n+AggregateDescriptor& aggregate,\n+ 1948 const AggregatesMap& aggregates) const\n+ 1949 {\n+ 1950 OneWayCounter counter;\n+ 1951 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n+ 1952 return counter.value();\n+ 1953 }\n+ 1954\n+ 1955 template\n+ 1956 inline void Aggregator::OneWayCounter::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 1957 {\n+ 1958 if(edge.properties().isOneWay())\n+ 1959 Counter::increment();\n+ 1960 }\n+ 1961\n+ 1962 template\n+ 1963 inline Aggregator::ConnectivityCounter::ConnectivityCounter(const\n+VertexSet& connected,\n+ 1964 const AggregatesMap& aggregates)\n+ 1965 : Counter(), connected_(connected), aggregates_(aggregates)\n+ 1966 {}\n+ 1967\n+ 1968\n+ 1969 template\n+ 1970 inline void Aggregator::ConnectivityCounter::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 1971 {\n+ 1972 if(connected_.find(aggregates_[edge.target()]) == connected_.end() ||\n+aggregates_[edge.target()]==AggregatesMap::UNAGGREGATED)\n+ 1973 // Would be a new connection\n+ 1974 Counter::increment();\n+ 1975 else{\n+ 1976 Counter::increment();\n+ 1977 Counter::increment();\n+ 1978 }\n+ 1979 }\n+ 1980\n+ 1981 template\n+ 1982 inline double Aggregator::connectivity(const Vertex& vertex, const\n+AggregatesMap& aggregates) const\n+ 1983 {\n+ 1984 ConnectivityCounter counter(connected_, aggregates);\n+ 1985 double noNeighbours=visitNeighbours(*graph_, vertex, counter);\n+ 1986 return (double)counter.value()/noNeighbours;\n+ 1987 }\n+ 1988\n+ 1989 template\n+ 1990 inline Aggregator::DependencyCounter::DependencyCounter()\n+ 1991 : Counter()\n+ 1992 {}\n+ 1993\n+ 1994 template\n+ 1995 inline void Aggregator::DependencyCounter::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 1996 {\n+ 1997 if(edge.properties().depends())\n+ 1998 Counter::increment();\n+ 1999 if(edge.properties().influences())\n+ 2000 Counter::increment();\n+ 2001 }\n+ 2002\n+ 2003 template\n+ 2004 int Aggregator::unusedNeighbours(const Vertex& vertex, const\n+AggregatesMap& aggregates) const\n+ 2005 {\n+ 2006 return aggregateNeighbours(vertex, AggregatesMap::UNAGGREGATED,\n+aggregates);\n+ 2007 }\n+ 2008\n+ 2009 template\n+ 2010 std::pair Aggregator::neighbours(const Vertex& vertex,\n+ 2011 const AggregateDescriptor& aggregate,\n+ 2012 const AggregatesMap& aggregates) const\n+ 2013 {\n+ 2014 DependencyCounter unused, aggregated;\n+ 2015 typedef AggregateVisitor CounterT;\n+ 2016 typedef std::tuple CounterTuple;\n+ 2017 CombinedFunctor visitors(CounterTuple(CounterT(aggregates,\n+AggregatesMap::UNAGGREGATED, unused), CounterT(aggregates, aggregate,\n+aggregated)));\n+ 2018 visitNeighbours(*graph_, vertex, visitors);\n+ 2019 return std::make_pair(unused.value(), aggregated.value());\n+ 2020 }\n+ 2021\n+ 2022\n+ 2023 template\n+ 2024 int Aggregator::aggregateNeighbours(const Vertex& vertex, const\n+AggregateDescriptor& aggregate, const AggregatesMap& aggregates) const\n+ 2025 {\n+ 2026 DependencyCounter counter;\n+ 2027 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);\n+ 2028 return counter.value();\n+ 2029 }\n+ 2030\n+ 2031 template\n+ 2032 std::size_t Aggregator::distance(const Vertex& vertex, const\n+AggregatesMap& aggregates)\n+ 2033 {\n+ 2034 return 0;\n+ 2035 typename PropertyMapTypeSelector::Type visitedMap =\n+get(VertexVisitedTag(), *graph_);\n+ 2036 VertexList vlist;\n+ 2037 typename AggregatesMap::DummyEdgeVisitor dummy;\n+ 2038 return aggregates.template breadthFirstSearch(vertex,\n+ 2039 aggregate_->id(), *graph_,\n+ 2040 vlist, dummy, dummy, visitedMap);\n+ 2041 }\n+ 2042\n+ 2043 template\n+ 2044 inline Aggregator::FrontMarker::FrontMarker(std::vector&\n+front, MatrixGraph& graph)\n+ 2045 : front_(front), graph_(graph)\n+ 2046 {}\n+ 2047\n+ 2048 template\n+ 2049 inline void Aggregator::FrontMarker::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 2050 {\n+ 2051 Vertex target = edge.target();\n+ 2052\n+ 2053 if(!graph_.getVertexProperties(target).front()) {\n+ 2054 front_.push_back(target);\n+ 2055 graph_.getVertexProperties(target).setFront();\n+ 2056 }\n+ 2057 }\n+ 2058\n+ 2059 template\n+ 2060 inline bool Aggregator::admissible(const Vertex& vertex, const\n+AggregateDescriptor& aggregate, const AggregatesMap& aggregates) const\n+ 2061 {\n+ 2062 // Todo\n+ 2063 Dune::dvverb<<\" Admissible not yet implemented!\"<endEdges(vertex);\n+ 2071 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {\n+ 2072 // if(edge.properties().depends() && !edge.properties().influences()\n+ 2073 if(edge.properties().isStrong()\n+ 2074 && aggregates[edge.target()]==aggregate)\n+ 2075 {\n+ 2076 // Search for another link to the aggregate\n+ 2077 Iterator edge1 = edge;\n+ 2078 for(++edge1; edge1 != vend; ++edge1) {\n+ 2079 //if(edge1.properties().depends() && !edge1.properties().influences()\n+ 2080 if(edge1.properties().isStrong()\n+ 2081 && aggregates[edge.target()]==aggregate)\n+ 2082 {\n+ 2083 //Search for an edge connecting the two vertices that is\n+ 2084 //strong\n+ 2085 bool found=false;\n+ 2086 Iterator v2end = graph_->endEdges(edge.target());\n+ 2087 for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end;\n+++edge2) {\n+ 2088 if(edge2.target()==edge1.target() &&\n+ 2089 edge2.properties().isStrong()) {\n+ 2090 found =true;\n+ 2091 break;\n+ 2092 }\n+ 2093 }\n+ 2094 if(found)\n+ 2095 {\n+ 2096 return true;\n+ 2097 }\n+ 2098 }\n+ 2099 }\n+ 2100 }\n+ 2101 }\n+ 2102\n+ 2103 // Situation 2: cluster node depends on front node and other cluster node\n+ 2105 vend = graph_->endEdges(vertex);\n+ 2106 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {\n+ 2107 //if(!edge.properties().depends() && edge.properties().influences()\n+ 2108 if(edge.properties().isStrong()\n+ 2109 && aggregates[edge.target()]==aggregate)\n+ 2110 {\n+ 2111 // Search for a link from target that stays within the aggregate\n+ 2112 Iterator v1end = graph_->endEdges(edge.target());\n+ 2113\n+ 2114 for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end;\n+++edge1) {\n+ 2115 //if(edge1.properties().depends() && !edge1.properties().influences()\n+ 2116 if(edge1.properties().isStrong()\n+ 2117 && aggregates[edge1.target()]==aggregate)\n+ 2118 {\n+ 2119 bool found=false;\n+ 2120 // Check if front node is also connected to this one\n+ 2121 Iterator v2end = graph_->endEdges(vertex);\n+ 2122 for(Iterator edge2 = graph_->beginEdges(vertex); edge2 != v2end; ++edge2)\n+{\n+ 2123 if(edge2.target()==edge1.target()) {\n+ 2124 if(edge2.properties().isStrong())\n+ 2125 found=true;\n+ 2126 break;\n+ 2127 }\n+ 2128 }\n+ 2129 if(found)\n+ 2130 {\n+ 2131 return true;\n+ 2132 }\n+ 2133 }\n+ 2134 }\n+ 2135 }\n+ 2136 }\n+ 2137 return false;\n+ 2138 }\n+ 2139\n+ 2140 template\n+ 2141 void Aggregator::unmarkFront()\n+ 2142 {\n+ 2143 typedef typename std::vector::const_iterator Iterator;\n+ 2144\n+ 2145 for(Iterator vertex=front_.begin(); vertex != front_.end(); ++vertex)\n+ 2146 graph_->getVertexProperties(*vertex).resetFront();\n+ 2147\n+ 2148 front_.clear();\n+ 2149 }\n+ 2150\n+ 2151 template\n+ 2152 inline void\n+ 2153 Aggregator::nonisoNeighbourAggregate(const Vertex& vertex,\n+ 2154 const AggregatesMap& aggregates,\n+ 2155 SLList& neighbours) const\n+ 2156 {\n+ 2157 typedef typename MatrixGraph::ConstEdgeIterator Iterator;\n+ 2158 Iterator end=graph_->beginEdges(vertex);\n+ 2159 neighbours.clear();\n+ 2160\n+ 2161 for(Iterator edge=graph_->beginEdges(vertex); edge!=end; ++edge)\n+ 2162 {\n+ 2163 if(aggregates[edge.target()]!=AggregatesMap::UNAGGREGATED &&\n+graph_->getVertexProperties(edge.target()).isolated())\n+ 2164 neighbours.push_back(aggregates[edge.target()]);\n+ 2165 }\n+ 2166 }\n+ 2167\n+ 2168 template\n+ 2169 inline typename G::VertexDescriptor Aggregator::mergeNeighbour(const\n+Vertex& vertex, const AggregatesMap& aggregates) const\n+ 2170 {\n+ 2171 typedef typename MatrixGraph::ConstEdgeIterator Iterator;\n+ 2172\n+ 2173 Iterator end = graph_->endEdges(vertex);\n+ 2174 for(Iterator edge = graph_->beginEdges(vertex); edge != end; ++edge) {\n+ 2175 if(aggregates[edge.target()] != AggregatesMap::UNAGGREGATED &&\n+ 2176 graph_->getVertexProperties(edge.target()).isolated() == graph_-\n+>getVertexProperties(edge.source()).isolated()) {\n+ 2177 if( graph_->getVertexProperties(vertex).isolated() ||\n+ 2178 ((edge.properties().depends() || edge.properties().influences())\n+ 2179 && admissible(vertex, aggregates[edge.target()], aggregates)))\n+ 2180 return edge.target();\n+ 2181 }\n+ 2182 }\n+ 2183 return AggregatesMap::UNAGGREGATED;\n+ 2184 }\n+ 2185\n+ 2186 template\n+ 2187 Aggregator::FrontNeighbourCounter::FrontNeighbourCounter(const\n+MatrixGraph& graph)\n+ 2188 : Counter(), graph_(graph)\n+ 2189 {}\n+ 2190\n+ 2191 template\n+ 2192 void Aggregator::FrontNeighbourCounter::operator()(const typename\n+MatrixGraph::ConstEdgeIterator& edge)\n+ 2193 {\n+ 2194 if(graph_.getVertexProperties(edge.target()).front())\n+ 2195 Counter::increment();\n+ 2196 }\n+ 2197\n+ 2198 template\n+ 2199 int Aggregator::noFrontNeighbours(const Vertex& vertex) const\n+ 2200 {\n+ 2201 FrontNeighbourCounter counter(*graph_);\n+ 2202 visitNeighbours(*graph_, vertex, counter);\n+ 2203 return counter.value();\n+ 2204 }\n+ 2205 template\n+ 2206 inline bool Aggregator::connected(const Vertex& vertex,\n+ 2207 const AggregateDescriptor& aggregate,\n+ 2208 const AggregatesMap& aggregates) const\n+ 2209 {\n+ 2210 typedef typename G::ConstEdgeIterator iterator;\n+ 2211 const iterator end = graph_->endEdges(vertex);\n+ 2212 for(iterator edge = graph_->beginEdges(vertex); edge != end; ++edge)\n+ 2213 if(aggregates[edge.target()]==aggregate)\n+ 2214 return true;\n+ 2215 return false;\n+ 2216 }\n+ 2217 template\n+ 2218 inline bool Aggregator::connected(const Vertex& vertex,\n+ 2219 const SLList& aggregateList,\n+ 2220 const AggregatesMap& aggregates) const\n+ 2221 {\n+ 2222 typedef typename SLList::const_iterator Iter;\n+ 2223 for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)\n+ 2224 if(connected(vertex, *i, aggregates))\n+ 2225 return true;\n+ 2226 return false;\n+ 2227 }\n+ 2228\n+ 2229 template\n+ 2230 template\n+ 2231 void Aggregator::growIsolatedAggregate(const Vertex& seed, const\n+AggregatesMap& aggregates, const C& c)\n+ 2232 {\n+ 2233 SLList connectedAggregates;\n+ 2234 nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);\n+ 2235\n+ 2236 while(aggregate_->size()< c.minAggregateSize() && aggregate_->connectSize\n+() < c.maxConnectivity()) {\n+ 2237 double maxCon=-1;\n+ 2238 std::size_t maxFrontNeighbours=0;\n+ 2239\n+ 2240 Vertex candidate=AggregatesMap::UNAGGREGATED;\n+ 2241\n+ 2242 typedef typename std::vector::const_iterator Iterator;\n+ 2243\n+ 2244 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n+ 2245 if(distance(*vertex, aggregates)>c.maxDistance())\n+ 2246 continue; // distance of proposes aggregate too big\n+ 2247\n+ 2248 if(connectedAggregates.size()>0) {\n+ 2249 // there is already a neighbour cluster\n+ 2250 // front node must be connected to same neighbour cluster\n+ 2251\n+ 2252 if(!connected(*vertex, connectedAggregates, aggregates))\n+ 2253 continue;\n+ 2254 }\n+ 2255\n+ 2256 double con = connectivity(*vertex, aggregates);\n+ 2257\n+ 2258 if(con == maxCon) {\n+ 2259 std::size_t frontNeighbours = noFrontNeighbours(*vertex);\n+ 2260\n+ 2261 if(frontNeighbours >= maxFrontNeighbours) {\n+ 2262 maxFrontNeighbours = frontNeighbours;\n+ 2263 candidate = *vertex;\n+ 2264 }\n+ 2265 }else if(con > maxCon) {\n+ 2266 maxCon = con;\n+ 2267 maxFrontNeighbours = noFrontNeighbours(*vertex);\n+ 2268 candidate = *vertex;\n+ 2269 }\n+ 2270 }\n+ 2271\n+ 2272 if(candidate==AggregatesMap::UNAGGREGATED)\n+ 2273 break;\n+ 2274\n+ 2275 aggregate_->add(candidate);\n+ 2276 }\n+ 2277 }\n+ 2278\n+ 2279 template\n+ 2280 template\n+ 2281 void Aggregator::growAggregate(const Vertex& seed, const\n+AggregatesMap& aggregates, const C& c)\n+ 2282 {\n+ 2283 using std::min;\n+ 2284\n+ 2285 std::size_t distance_ =0;\n+ 2286 while(aggregate_->size() < c.minAggregateSize()&& distance_ candidates;\n+ 2291 candidates.reserve(30);\n+ 2292\n+ 2293 typedef typename std::vector::const_iterator Iterator;\n+ 2294\n+ 2295 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n+ 2296 // Only nonisolated nodes are considered\n+ 2297 if(graph_->getVertexProperties(*vertex).isolated())\n+ 2298 continue;\n+ 2299\n+ 2300 int twoWayCons = twoWayConnections(*vertex, aggregate_->id(),\n+aggregates);\n+ 2301\n+ 2302 /* The case of two way connections. */\n+ 2303 if( maxTwoCons == twoWayCons && twoWayCons > 0) {\n+ 2304 double con = connectivity(*vertex, aggregates);\n+ 2305\n+ 2306 if(con == maxCon) {\n+ 2307 int neighbours = noFrontNeighbours(*vertex);\n+ 2308\n+ 2309 if(neighbours > maxNeighbours) {\n+ 2310 maxNeighbours = neighbours;\n+ 2311 candidates.clear();\n+ 2312 candidates.push_back(*vertex);\n+ 2313 }else{\n+ 2314 candidates.push_back(*vertex);\n+ 2315 }\n+ 2316 }else if( con > maxCon) {\n+ 2317 maxCon = con;\n+ 2318 maxNeighbours = noFrontNeighbours(*vertex);\n+ 2319 candidates.clear();\n+ 2320 candidates.push_back(*vertex);\n+ 2321 }\n+ 2322 }else if(twoWayCons > maxTwoCons) {\n+ 2323 maxTwoCons = twoWayCons;\n+ 2324 maxCon = connectivity(*vertex, aggregates);\n+ 2325 maxNeighbours = noFrontNeighbours(*vertex);\n+ 2326 candidates.clear();\n+ 2327 candidates.push_back(*vertex);\n+ 2328\n+ 2329 // two way connections precede\n+ 2330 maxOneCons = std::numeric_limits::max();\n+ 2331 }\n+ 2332\n+ 2333 if(twoWayCons > 0)\n+ 2334 {\n+ 2335 continue; // THis is a two-way node, skip tests for one way nodes\n+ 2336 }\n+ 2337\n+ 2338 /* The one way case */\n+ 2339 int oneWayCons = oneWayConnections(*vertex, aggregate_->id(),\n+aggregates);\n+ 2340\n+ 2341 if(oneWayCons==0)\n+ 2342 continue; // No strong connections, skip the tests.\n+ 2343\n+ 2344 if(!admissible(*vertex, aggregate_->id(), aggregates))\n+ 2345 continue;\n+ 2346\n+ 2347 if( maxOneCons == oneWayCons && oneWayCons > 0) {\n+ 2348 double con = connectivity(*vertex, aggregates);\n+ 2349\n+ 2350 if(con == maxCon) {\n+ 2351 int neighbours = noFrontNeighbours(*vertex);\n+ 2352\n+ 2353 if(neighbours > maxNeighbours) {\n+ 2354 maxNeighbours = neighbours;\n+ 2355 candidates.clear();\n+ 2356 candidates.push_back(*vertex);\n+ 2357 }else{\n+ 2358 if(neighbours==maxNeighbours)\n+ 2359 {\n+ 2360 candidates.push_back(*vertex);\n+ 2361 }\n+ 2362 }\n+ 2363 }else if( con > maxCon) {\n+ 2364 maxCon = con;\n+ 2365 maxNeighbours = noFrontNeighbours(*vertex);\n+ 2366 candidates.clear();\n+ 2367 candidates.push_back(*vertex);\n+ 2368 }\n+ 2369 }else if(oneWayCons > maxOneCons) {\n+ 2370 maxOneCons = oneWayCons;\n+ 2371 maxCon = connectivity(*vertex, aggregates);\n+ 2372 maxNeighbours = noFrontNeighbours(*vertex);\n+ 2373 candidates.clear();\n+ 2374 candidates.push_back(*vertex);\n+ 2375 }\n+ 2376 }\n+ 2377\n+ 2378\n+ 2379 if(!candidates.size())\n+ 2380 break; // No more candidates found\n+ 2381 distance_=distance(seed, aggregates);\n+ 2382 candidates.resize(min(candidates.size(), c.maxAggregateSize()-\n+ 2383 aggregate_->size()));\n+ 2384 aggregate_->add(candidates);\n+ 2385 }\n+ 2386 }\n+ 2387\n+ 2388 template\n+ 2389 template\n+ 2390 std::tuple AggregatesMap::buildAggregates(const M&\n+matrix, G& graph, const C& criterion,\n+ 2391 bool finestLevel)\n+ 2392 {\n+ 2393 Aggregator aggregator;\n+ 2394 return aggregator.build(matrix, graph, *this, criterion, finestLevel);\n+ 2395 }\n+ 2396\n+ 2397 template\n+ 2398 template\n+ 2399 std::tuple Aggregator::build(const M& m, G& graph,\n+AggregatesMap& aggregates, const C& c,\n+ 2400 bool finestLevel)\n+ 2401 {\n+ 2402 using std::max;\n+ 2403 using std::min;\n+ 2404 // Stack for fast vertex access\n+ 2405 Stack stack_(graph, *this, aggregates);\n+ 2406\n+ 2407 graph_ = &graph;\n+ 2408\n+ 2409 aggregate_ = new Aggregate(graph, aggregates, connected_,\n+front_);\n+ 2410\n+ 2411 Timer watch;\n+ 2412 watch.reset();\n+ 2413\n+ 2414 buildDependency(graph, m, c, finestLevel);\n+ 2415\n+ 2416 dverb<<\"Build dependency took \"<< watch.elapsed()<<\" seconds.\"<::ISOLATED;\n+ 2437 ++skippedAggregates;\n+ 2438 continue;\n+ 2439 }\n+ 2440\n+ 2441 if(graph.getVertexProperties(seed).isolated()) {\n+ 2442 if(c.skipIsolated()) {\n+ 2443 // isolated vertices are not aggregated but skipped on the coarser\n+levels.\n+ 2444 aggregates[seed]=AggregatesMap::ISOLATED;\n+ 2445 ++skippedAggregates;\n+ 2446 // skip rest as no agglomeration is done.\n+ 2447 continue;\n+ 2448 }else{\n+ 2449 aggregate_->seed(seed);\n+ 2450 growIsolatedAggregate(seed, aggregates, c);\n+ 2451 }\n+ 2452 }else{\n+ 2453 aggregate_->seed(seed);\n+ 2454 growAggregate(seed, aggregates, c);\n+ 2455 }\n+ 2456\n+ 2457 /* The rounding step. */\n+ 2458 while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->size()\n+< c.maxAggregateSize()) {\n+ 2459\n+ 2460 std::vector candidates;\n+ 2461 candidates.reserve(30);\n+ 2462\n+ 2463 typedef typename std::vector::const_iterator Iterator;\n+ 2464\n+ 2465 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {\n+ 2466\n+ 2467 if(graph.getVertexProperties(*vertex).isolated())\n+ 2468 continue; // No isolated nodes here\n+ 2469\n+ 2470 if(twoWayConnections( *vertex, aggregate_->id(), aggregates) == 0 &&\n+ 2471 (oneWayConnections( *vertex, aggregate_->id(), aggregates) == 0 ||\n+ 2472 !admissible( *vertex, aggregate_->id(), aggregates) ))\n+ 2473 continue;\n+ 2474\n+ 2475 std::pair neighbourPair=neighbours(*vertex, aggregate_->id(),\n+ 2476 aggregates);\n+ 2477\n+ 2478 //if(aggregateNeighbours(*vertex, aggregate_->id(), aggregates) <=\n+unusedNeighbours(*vertex, aggregates))\n+ 2479 // continue;\n+ 2480\n+ 2481 if(neighbourPair.first >= neighbourPair.second)\n+ 2482 continue;\n+ 2483\n+ 2484 if(distance(*vertex, aggregates) > c.maxDistance())\n+ 2485 continue; // Distance too far\n+ 2486 candidates.push_back(*vertex);\n+ 2487 break;\n+ 2488 }\n+ 2489\n+ 2490 if(!candidates.size()) break; // no more candidates found.\n+ 2491\n+ 2492 candidates.resize(min(candidates.size(), c.maxAggregateSize()-\n+ 2493 aggregate_->size()));\n+ 2494 aggregate_->add(candidates);\n+ 2495\n+ 2496 }\n+ 2497\n+ 2498 // try to merge aggregates consisting of only one nonisolated vertex with\n+other aggregates\n+ 2499 if(aggregate_->size()==1 && c.maxAggregateSize()>1) {\n+ 2500 if(!graph.getVertexProperties(seed).isolated()) {\n+ 2501 Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);\n+ 2502\n+ 2503 if(mergedNeighbour != AggregatesMap::UNAGGREGATED) {\n+ 2504 // assign vertex to the neighbouring cluster\n+ 2505 aggregates[seed] = aggregates[mergedNeighbour];\n+ 2506 aggregate_->invalidate();\n+ 2507 }else{\n+ 2508 ++avg;\n+ 2509 minA=min(minA,static_cast(1));\n+ 2510 maxA=max(maxA,static_cast(1));\n+ 2511 ++oneAggregates;\n+ 2512 ++conAggregates;\n+ 2513 }\n+ 2514 }else{\n+ 2515 ++avg;\n+ 2516 minA=min(minA,static_cast(1));\n+ 2517 maxA=max(maxA,static_cast(1));\n+ 2518 ++oneAggregates;\n+ 2519 ++isoAggregates;\n+ 2520 }\n+ 2521 ++avg;\n+ 2522 }else{\n+ 2523 avg+=aggregate_->size();\n+ 2524 minA=min(minA,aggregate_->size());\n+ 2525 maxA=max(maxA,aggregate_->size());\n+ 2526 if(graph.getVertexProperties(seed).isolated())\n+ 2527 ++isoAggregates;\n+ 2528 else\n+ 2529 ++conAggregates;\n+ 2530 }\n+ 2531\n+ 2532 }\n+ 2533\n+ 2534 Dune::dinfo<<\"connected aggregates: \"<0)\n+ 2537 Dune::dinfo<<\" one node aggregates: \"<\n+ 2548 Aggregator::Stack::Stack(const MatrixGraph& graph, const\n+Aggregator& aggregatesBuilder,\n+ 2549 const AggregatesMap& aggregates)\n+ 2550 : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_\n+(aggregates), begin_(graph.begin()), end_(graph.end())\n+ 2551 {\n+ 2552 //vals_ = new Vertex[N];\n+ 2553 }\n+ 2554\n+ 2555 template\n+ 2556 Aggregator::Stack::~Stack()\n+ 2557 {\n+ 2558 //Dune::dverb << \"Max stack size was \"<\n+ 2563 const typename Aggregator::Vertex Aggregator::Stack::NullEntry\n+ 2564 = std::numeric_limits::max();\n+ 2565\n+ 2566 template\n+ 2567 inline typename G::VertexDescriptor Aggregator::Stack::pop()\n+ 2568 {\n+ 2569 for(; begin_!=end_ && aggregates_[*begin_] != AggregatesMap::\n+UNAGGREGATED; ++begin_) ;\n+ 2570\n+ 2571 if(begin_!=end_)\n+ 2572 {\n+ 2573 typename G::VertexDescriptor current=*begin_;\n+ 2574 ++begin_;\n+ 2575 return current;\n+ 2576 }else\n+ 2577 return NullEntry;\n+ 2578 }\n+ 2579\n+ 2580#endif // DOXYGEN\n+ 2581\n+ 2582 template\n+2583 void printAggregates2d(const AggregatesMap& aggregates, int n, int m,\n+std::ostream& os)\n+ 2584 {\n+ 2585 using std::max;\n+ 2586\n+ 2587 std::ios_base::fmtflags oldOpts=os.flags();\n+ 2588\n+ 2589 os.setf(std::ios_base::right, std::ios_base::adjustfield);\n+ 2590\n+ 2591 V maxVal=0;\n+ 2592 int width=1;\n+ 2593\n+ 2594 for(int i=0; i< n*m; i++)\n+ 2595 maxVal=max(maxVal, aggregates[i]);\n+ 2596\n+ 2597 for(int i=10; i < 1000000; i*=10)\n+ 2598 if(maxVal/i>0)\n+ 2599 width++;\n+ 2600 else\n+ 2601 break;\n+ 2602\n+ 2603 for(int j=0, entry=0; j < m; j++) {\n+ 2604 for(int i=0; i::iterator valIter_\n+Definition: aggregates.hh:189\n+Dune::Amg::SymmetricMatrixDependency::ColIter\n+Matrix::ConstColIterator ColIter\n+Constant column iterator of the matrix.\n+Definition: aggregates.hh:154\n+Dune::Amg::AggregatesMap::breadthFirstSearch\n+std::size_t breadthFirstSearch(const VertexDescriptor &start, const\n+AggregateDescriptor &aggregate, const G &graph, L &visited, F1\n+&aggregateVisitor, F2 &nonAggregateVisitor, VM &visitedMap) const\n+Breadth first search within an aggregate.\n+Dune::Amg::AggregatesMap::Allocator\n+PoolAllocator< VertexDescriptor, 100 > Allocator\n+The allocator we use for our lists and the set.\n+Definition: aggregates.hh:586\n+Dune::Amg::AggregatesMap::begin\n+iterator begin()\n+Definition: aggregates.hh:737\n+Dune::Amg::Aggregate::id\n+int id()\n+Get the id identifying the aggregate.\n+Dune::Amg::Dependency::norm_\n+Norm norm_\n+The functor for calculating the norm.\n+Definition: aggregates.hh:302\n+Dune::Amg::Aggregator::Vertex\n+MatrixGraph::VertexDescriptor Vertex\n+The vertex identifier.\n+Definition: aggregates.hh:920\n+Dune::Amg::AggregationCriterion::AggregationCriterion\n+AggregationCriterion()\n+Constructor.\n+Definition: aggregates.hh:66\n+Dune::Amg::SymmetricDependency::matrix_\n+const Matrix * matrix_\n+The matrix we work on.\n+Definition: aggregates.hh:357\n+Dune::Amg::Diagonal::operator()\n+auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::\n+value > *sfinae=nullptr) const\n+Compute the norm of a scalar.\n+Definition: aggregates.hh:406\n+Dune::Amg::Dependency::initRow\n+void initRow(const Row &row, int index)\n+Dune::Amg::SymmetricMatrixDependency::SymmetricMatrixDependency\n+SymmetricMatrixDependency(const Parameters &parms)\n+Definition: aggregates.hh:168\n+Dune::Amg::Dependency::Matrix\n+M Matrix\n+The matrix type we build the dependency of.\n+Definition: aggregates.hh:258\n+Dune::Amg::Aggregator::Counter::Counter\n+Counter()\n+Constructor.\n+Dune::Amg::Aggregator::MatrixGraph\n+G MatrixGraph\n+The matrix graph type used.\n+Definition: aggregates.hh:915\n+Dune::Amg::SymmetricDependency::norm_\n+Norm norm_\n+The functor for calculating the norm.\n+Definition: aggregates.hh:363\n+Dune::Amg::AggregatesMap::DummyEdgeVisitor::operator()\n+void operator()(const EdgeIterator &edge) const\n+Definition: aggregates.hh:601\n+Dune::Amg::SymmetricCriterion::SymmetricCriterion\n+SymmetricCriterion()\n+Definition: aggregates.hh:524\n+Dune::Amg::Dependency::Dependency\n+Dependency()\n+Definition: aggregates.hh:290\n+Dune::Amg::SymmetricDependency::examine\n+void examine(const ColIter &col)\n+Dune::Amg::SymmetricDependency::Matrix\n+M Matrix\n+The matrix type we build the dependency of.\n+Definition: aggregates.hh:319\n+Dune::Amg::SymmetricMatrixDependency::diagonal_\n+real_type diagonal_\n+The norm of the current diagonal.\n+Definition: aggregates.hh:187\n+Dune::Amg::Dependency::Norm\n+N Norm\n+The norm to use for examining the matrix entries.\n+Definition: aggregates.hh:263\n+Dune::Amg::AggregatesMap::end\n+iterator end()\n+Definition: aggregates.hh:742\n+Dune::Amg::UnSymmetricCriterion::UnSymmetricCriterion\n+UnSymmetricCriterion(const Parameters &parms)\n+Definition: aggregates.hh:541\n+Dune::Amg::Aggregator::TwoWayCounter::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::SymmetricMatrixDependency::initRow\n+void initRow(const Row &row, int index)\n+Definition: aggregates.hh:201\n+Dune::Amg::Dependency::isIsolated\n+bool isIsolated()\n+Dune::Amg::Aggregator::Stack::NullEntry\n+static const Vertex NullEntry\n+Definition: aggregates.hh:1008\n+Dune::Amg::SymmetricMatrixDependency::examine\n+void examine(const ColIter &col)\n+Definition: aggregates.hh:214\n+Dune::Amg::Dependency::Dependency\n+Dependency(const Parameters &parms)\n+Definition: aggregates.hh:286\n+Dune::Amg::SymmetricMatrixDependency::row_\n+int row_\n+index of the currently evaluated row.\n+Definition: aggregates.hh:185\n+Dune::Amg::Aggregator::Stack\n+friend class Stack\n+Definition: aggregates.hh:1036\n+Dune::Amg::Aggregator::ConnectivityCounter::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::Aggregator::build\n+std::tuple< int, int, int, int > build(const M &m, G &graph, AggregatesMap<\n+Vertex > &aggregates, const C &c, bool finestLevel)\n+Build the aggregates.\n+Dune::Amg::Aggregator::FrontNeighbourCounter::FrontNeighbourCounter\n+FrontNeighbourCounter(const MatrixGraph &front)\n+Constructor.\n+Dune::Amg::SymmetricDependency::Row\n+Matrix::row_type Row\n+Constant Row iterator of the matrix.\n+Definition: aggregates.hh:329\n+Dune::Amg::Dependency::matrix_\n+const Matrix * matrix_\n+The matrix we work on.\n+Definition: aggregates.hh:296\n+Dune::Amg::AggregatesMap::operator[]\n+const AggregateDescriptor & operator[](const VertexDescriptor &v) const\n+Get the aggregate a vertex belongs to.\n+Dune::Amg::SymmetricDependency::examine\n+void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter\n+&col)\n+Dune::Amg::Aggregator::AggregateVisitor::AggregateVisitor\n+AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const\n+AggregateDescriptor &aggregate, Visitor &visitor)\n+Constructor.\n+Dune::Amg::SymmetricDependency::ColIter\n+Matrix::ConstColIterator ColIter\n+Constant column iterator of the matrix.\n+Definition: aggregates.hh:334\n+Dune::Amg::AggregatesMap::~AggregatesMap\n+~AggregatesMap()\n+Destructor.\n+Dune::Amg::SymmetricMatrixDependency::field_type\n+Matrix::field_type field_type\n+The current max value.\n+Definition: aggregates.hh:179\n+Dune::Amg::Aggregator::Counter::decrement\n+void decrement()\n+Decrement counter.\n+Dune::Amg::Aggregate::Aggregate\n+Aggregate(MatrixGraph &graph, AggregatesMap< Vertex > &aggregates, VertexSet\n+&connectivity, std::vector< Vertex > &front_)\n+Constructor.\n+Dune::Amg::Aggregator::AggregateVisitor::Visitor\n+V Visitor\n+The type of the adapted visitor.\n+Definition: aggregates.hh:1064\n+Dune::Amg::Aggregate::SphereMap\n+std::size_t * SphereMap\n+Type of the mapping of aggregate members onto distance spheres.\n+Definition: aggregates.hh:809\n+Dune::Amg::AggregationCriterion::AggregationCriterion\n+AggregationCriterion(const Parameters &parms)\n+Definition: aggregates.hh:70\n+Dune::Amg::Dependency::Row\n+Matrix::row_type Row\n+Constant Row iterator of the matrix.\n+Definition: aggregates.hh:268\n+Dune::Amg::Aggregate::connectSize\n+VertexSet::size_type connectSize()\n+Get tne number of connections to other aggregates.\n+Dune::Amg::SymmetricMatrixDependency::vals_\n+std::vector< real_type > vals_\n+Definition: aggregates.hh:188\n+Dune::Amg::SymmetricDependency::Norm\n+N Norm\n+The norm to use for examining the matrix entries.\n+Definition: aggregates.hh:324\n+Dune::Amg::printAggregates2d\n+void printAggregates2d(const AggregatesMap< V > &aggregates, int n, int m,\n+std::ostream &os)\n+Definition: aggregates.hh:2583\n+Dune::Amg::Aggregate::invalidate\n+void invalidate()\n+Definition: aggregates.hh:822\n+Dune::Amg::AggregatesMap::begin\n+const_iterator begin() const\n+Definition: aggregates.hh:725\n+Dune::Amg::SymmetricMatrixDependency::maxValue_\n+real_type maxValue_\n+Definition: aggregates.hh:181\n+Dune::Amg::SymmetricMatrixDependency::norm_\n+Norm norm_\n+The functor for calculating the norm.\n+Definition: aggregates.hh:183\n+Dune::Amg::Aggregator::FrontMarker::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::Aggregate::const_iterator\n+VertexSet::const_iterator const_iterator\n+Const iterator over a vertex list.\n+Definition: aggregates.hh:804\n+Dune::Amg::SymmetricCriterion::SymmetricCriterion\n+SymmetricCriterion(const Parameters &parms)\n+Definition: aggregates.hh:521\n+Dune::Amg::Aggregator::AggregateDescriptor\n+MatrixGraph::VertexDescriptor AggregateDescriptor\n+The type of the aggregate descriptor.\n+Definition: aggregates.hh:923\n+Dune::Amg::SymmetricDependency::maxValue_\n+real_type maxValue_\n+Definition: aggregates.hh:361\n+Dune::Amg::SymmetricMatrixDependency::init\n+void init(const Matrix *matrix)\n+Definition: aggregates.hh:195\n+Dune::Amg::SymmetricDependency::diagonal_\n+real_type diagonal_\n+The norm of the current diagonal.\n+Definition: aggregates.hh:367\n+Dune::Amg::AggregatesMap::iterator\n+AggregateDescriptor * iterator\n+Definition: aggregates.hh:735\n+Dune::Amg::SymmetricDependency::SymmetricDependency\n+SymmetricDependency(const Parameters &parms)\n+Definition: aggregates.hh:348\n+Dune::Amg::SymmetricDependency::real_type\n+FieldTraits< field_type >::real_type real_type\n+Definition: aggregates.hh:360\n+Dune::Amg::Aggregator::~Aggregator\n+~Aggregator()\n+Destructor.\n+Dune::Amg::Dependency::examine\n+void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter\n+&col)\n+Dune::Amg::Aggregate::add\n+void add(const Vertex &vertex)\n+Add a vertex to the aggregate.\n+Dune::Amg::AggregationCriterion::DependencyPolicy\n+T DependencyPolicy\n+The policy for calculating the dependency graph.\n+Definition: aggregates.hh:55\n+Dune::Amg::Aggregate::add\n+void add(std::vector< Vertex > &vertex)\n+Dune::Amg::Dependency::examine\n+void examine(const ColIter &col)\n+Dune::Amg::Aggregator::Aggregator\n+Aggregator()\n+Constructor.\n+Dune::Amg::Aggregator::AggregateVisitor::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Examine an edge.\n+Dune::Amg::Aggregator::FrontMarker::FrontMarker\n+FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)\n+Constructor.\n+Dune::Amg::AlwaysOneNorm::operator()\n+FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n+compute the norm of a matrix.\n+Definition: aggregates.hh:506\n+Dune::Amg::Dependency::init\n+void init(const Matrix *matrix)\n+Dune::Amg::visitNeighbours\n+int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n+V &visitor)\n+Visit all neighbour vertices of a vertex in a graph.\n+Dune::Amg::AggregationCriterion::setDefaultValuesIsotropic\n+void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n+Sets reasonable default values for an isotropic problem.\n+Definition: aggregates.hh:82\n+Dune::Amg::AggregatesMap::end\n+const_iterator end() const\n+Definition: aggregates.hh:730\n+Dune::Amg::AggregatesMap::AggregateDescriptor\n+V AggregateDescriptor\n+The aggregate descriptor type.\n+Definition: aggregates.hh:580\n+Dune::Amg::AggregatesMap::ISOLATED\n+static const V ISOLATED\n+Identifier of isolated vertices.\n+Definition: aggregates.hh:571\n+Dune::Amg::SymmetricDependency::row_\n+int row_\n+index of the currently evaluated row.\n+Definition: aggregates.hh:365\n+Dune::Amg::SymmetricMatrixDependency::SymmetricMatrixDependency\n+SymmetricMatrixDependency()\n+Definition: aggregates.hh:171\n+Dune::Amg::Aggregator::DependencyCounter::DependencyCounter\n+DependencyCounter()\n+Constructor.\n+Dune::Amg::Aggregator::Stack::pop\n+Vertex pop()\n+Dune::Amg::Dependency::diagonal_\n+real_type diagonal_\n+The norm of the current diagonal.\n+Definition: aggregates.hh:306\n+Dune::Amg::AggregatesMap::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices.\n+Dune::Amg::AggregationCriterion::setDefaultValuesAnisotropic\n+void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)\n+Sets reasonable default values for an aisotropic problem.\n+Definition: aggregates.hh:105\n+Dune::Amg::AggregatesMap::AggregatesMap\n+AggregatesMap(std::size_t noVertices)\n+Constructs with allocating memory.\n+Dune::Amg::SymmetricDependency::field_type\n+Matrix::field_type field_type\n+The current max value.\n+Definition: aggregates.hh:359\n+Dune::Amg::AggregatesMap::operator[]\n+AggregateDescriptor & operator[](const VertexDescriptor &v)\n+Get the aggregate a vertex belongs to.\n+Dune::Amg::AggregatesMap::AggregatesMap\n+AggregatesMap()\n+Constructs without allocating memory.\n+Dune::Amg::Aggregator::Counter::value\n+int value()\n+Access the current count.\n+Dune::Amg::AggregatesMap::VertexList\n+SLList< VertexDescriptor, Allocator > VertexList\n+The type of a single linked list of vertex descriptors.\n+Definition: aggregates.hh:592\n+Dune::Amg::Aggregator::Stack::~Stack\n+~Stack()\n+Dune::Amg::Aggregator::ConnectivityCounter::ConnectivityCounter\n+ConnectivityCounter(const VertexSet &connected, const AggregatesMap< Vertex >\n+&aggregates)\n+Constructor.\n+Dune::Amg::Aggregate::size\n+VertexSet::size_type size()\n+Get the size of the aggregate.\n+Dune::Amg::Aggregate::end\n+const_iterator end() const\n+get an iterator over the vertices of the aggregate.\n+Dune::Amg::SymmetricDependency::init\n+void init(const Matrix *matrix)\n+Dune::Amg::UnSymmetricCriterion::UnSymmetricCriterion\n+UnSymmetricCriterion()\n+Definition: aggregates.hh:544\n+Dune::Amg::Aggregator::FrontNeighbourCounter::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::AggregatesMap::const_iterator\n+const AggregateDescriptor * const_iterator\n+Definition: aggregates.hh:723\n+Dune::Amg::Dependency::row_\n+int row_\n+index of the currently evaluated row.\n+Definition: aggregates.hh:304\n+Dune::Amg::Aggregator::Stack::Stack\n+Stack(const MatrixGraph &graph, const Aggregator< G > &aggregatesBuilder, const\n+AggregatesMap< Vertex > &aggregates)\n+Dune::Amg::SymmetricMatrixDependency::real_type\n+FieldTraits< field_type >::real_type real_type\n+Definition: aggregates.hh:180\n+Dune::Amg::SymmetricDependency::initRow\n+void initRow(const Row &row, int index)\n+Dune::Amg::SymmetricMatrixDependency::Matrix\n+M Matrix\n+The matrix type we build the dependency of.\n+Definition: aggregates.hh:139\n+Dune::Amg::Dependency::real_type\n+FieldTraits< field_type >::real_type real_type\n+Definition: aggregates.hh:299\n+Dune::Amg::SymmetricMatrixDependency::matrix_\n+const Matrix * matrix_\n+The matrix we work on.\n+Definition: aggregates.hh:177\n+Dune::Amg::Aggregate::VertexSet\n+S VertexSet\n+The type of a single linked list of vertex descriptors.\n+Definition: aggregates.hh:801\n+Dune::Amg::FrobeniusNorm::operator()\n+FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n+compute the norm of a matrix.\n+Definition: aggregates.hh:490\n+Dune::Amg::AggregatesMap::UNAGGREGATED\n+static const V UNAGGREGATED\n+Identifier of not yet aggregated vertices.\n+Definition: aggregates.hh:566\n+Dune::Amg::AggregatesMap::breadthFirstSearch\n+std::size_t breadthFirstSearch(const VertexDescriptor &start, const\n+AggregateDescriptor &aggregate, const G &graph, F &aggregateVisitor, VM\n+&visitedMap) const\n+Breadth first search within an aggregate.\n+Dune::Amg::Dependency::field_type\n+Matrix::field_type field_type\n+The current max value.\n+Definition: aggregates.hh:298\n+Dune::Amg::Aggregator::OneWayCounter::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::operator<<\n+std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T >\n+&criterion)\n+Definition: aggregates.hh:113\n+Dune::Amg::SymmetricMatrixDependency::isIsolated\n+bool isIsolated()\n+Definition: aggregates.hh:240\n+Dune::Amg::AggregatesMap::allocate\n+void allocate(std::size_t noVertices)\n+Allocate memory for holding the information.\n+Dune::Amg::SymmetricMatrixDependency::Norm\n+N Norm\n+The norm to use for examining the matrix entries.\n+Definition: aggregates.hh:144\n+Dune::Amg::RowSum::operator()\n+FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const\n+compute the norm of a matrix.\n+Definition: aggregates.hh:473\n+Dune::Amg::Aggregate::reconstruct\n+void reconstruct(const Vertex &vertex)\n+Reconstruct the aggregat from an seed node.\n+Dune::Amg::Aggregate::begin\n+const_iterator begin() const\n+get an iterator over the vertices of the aggregate.\n+Dune::Amg::Diagonal::operator()\n+FieldTraits< typenameM::field_type >::real_type operator()(const M &m, typename\n+std::enable_if_t::value > *sfinae=nullptr) const\n+compute the norm of a matrix.\n+Definition: aggregates.hh:390\n+Dune::Amg::Aggregate::Vertex\n+MatrixGraph::VertexDescriptor Vertex\n+The vertex descriptor type.\n+Definition: aggregates.hh:789\n+Dune::Amg::Aggregate::seed\n+void seed(const Vertex &vertex)\n+Initialize the aggregate with one vertex.\n+Dune::Amg::SymmetricDependency::isIsolated\n+bool isIsolated()\n+Dune::Amg::SymmetricDependency::SymmetricDependency\n+SymmetricDependency()\n+Definition: aggregates.hh:351\n+Dune::Amg::Aggregate::clear\n+void clear()\n+Clear the aggregate.\n+Dune::Amg::AggregatesMap::free\n+void free()\n+Free the allocated memory.\n+Dune::Amg::Aggregator::Counter::increment\n+void increment()\n+Increment counter.\n+Dune::Amg::buildDependency\n+void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion,\n+bool finestLevel)\n+Build the dependency of the matrix graph.\n+Dune::Amg::AggregatesMap::VertexDescriptor\n+V VertexDescriptor\n+The vertex descriptor type.\n+Definition: aggregates.hh:575\n+Dune::Amg::Dependency::maxValue_\n+real_type maxValue_\n+Definition: aggregates.hh:300\n+Dune::Amg::AggregatesMap::buildAggregates\n+std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph,\n+const C &criterion, bool finestLevel)\n+Build the aggregates.\n+Dune::Amg::SymmetricMatrixDependency::Row\n+Matrix::row_type Row\n+Constant Row iterator of the matrix.\n+Definition: aggregates.hh:149\n+Dune::Amg::Aggregate::Allocator\n+PoolAllocator< Vertex, 100 > Allocator\n+The allocator we use for our lists and the set.\n+Definition: aggregates.hh:795\n+Dune::Amg::Aggregate::MatrixGraph\n+G MatrixGraph\n+Definition: aggregates.hh:785\n+Dune::Amg::Aggregator::DependencyCounter::operator()\n+void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)\n+Dune::Amg::FrobeniusNorm::is_sign_preserving\n+@ is_sign_preserving\n+Definition: aggregates.hh:483\n+Dune::Amg::Diagonal::is_sign_preserving\n+@ is_sign_preserving\n+Definition: aggregates.hh:382\n+Dune::Amg::AlwaysOneNorm::is_sign_preserving\n+@ is_sign_preserving\n+Definition: aggregates.hh:499\n+Dune::Amg::RowSum::is_sign_preserving\n+@ is_sign_preserving\n+Definition: aggregates.hh:466\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::SequentialInformation::SequentialInformation\n-SequentialInformation()\n-Definition: pinfo.hh:91\n-Dune::Amg::SequentialInformation::globalSum\n-T globalSum(const T &t) const\n-Definition: pinfo.hh:49\n-Dune::Amg::SequentialInformation::dot\n-void dot(const T1 &, const T1 &, T2 &) const\n-Definition: pinfo.hh:74\n-Dune::Amg::SequentialInformation::CopyFlags\n-EmptySet< int > CopyFlags\n-Definition: pinfo.hh:31\n-Dune::Amg::SequentialInformation::OwnerSet\n-AllSet< int > OwnerSet\n-Definition: pinfo.hh:32\n-Dune::Amg::SequentialInformation::copyOwnerToAll\n-void copyOwnerToAll(V &v, V &v1) const\n-Definition: pinfo.hh:66\n-Dune::Amg::SequentialInformation::communicator\n-MPICommunicator communicator() const\n-Definition: pinfo.hh:38\n-Dune::Amg::SequentialInformation::buildGlobalLookup\n-void buildGlobalLookup(std::size_t)\n-Definition: pinfo.hh:56\n-Dune::Amg::SequentialInformation::norm\n-FieldTraits< typenameT1::field_type >::real_type norm(const T1 &) const\n-Definition: pinfo.hh:81\n-Dune::Amg::SequentialInformation::project\n-void project(V &v) const\n-Definition: pinfo.hh:70\n-Dune::Amg::SequentialInformation::MPICommunicator\n-Communication< void * > MPICommunicator\n-Definition: pinfo.hh:30\n-Dune::Amg::SequentialInformation::SequentialInformation\n-SequentialInformation(const Communication< T > &)\n-Definition: pinfo.hh:88\n-Dune::Amg::SequentialInformation::globalLookup\n-const GlobalLookupIndexSet & globalLookup() const\n-Definition: pinfo.hh:60\n-Dune::Amg::SequentialInformation::SequentialInformation\n-SequentialInformation(const SequentialInformation &)\n-Definition: pinfo.hh:94\n-Dune::Amg::SequentialInformation::freeGlobalLookup\n-void freeGlobalLookup()\n-Definition: pinfo.hh:58\n-Dune::Amg::SequentialInformation::GlobalLookupIndexSet\n-int GlobalLookupIndexSet\n-Definition: pinfo.hh:54\n-Dune::Amg::SequentialInformation::category\n-SolverCategory::Category category() const\n-Definition: pinfo.hh:34\n-Dune::Amg::SequentialInformation::procs\n-int procs() const\n-Definition: pinfo.hh:43\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::field_type\n+typename Imp::BlockTraits< T >::field_type field_type\n+Export the type representing the underlying field.\n+Definition: matrix.hh:565\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::row_type\n+MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n+The type implementing a matrix row.\n+Definition: matrix.hh:574\n+Dune::Amg::AggregationCriterion\n+Base class of all aggregation criterions.\n+Definition: aggregates.hh:49\n+Dune::Amg::SymmetricMatrixDependency\n+Dependency policy for symmetric matrices.\n+Definition: aggregates.hh:134\n+Dune::Amg::Dependency\n+Dependency policy for symmetric matrices.\n+Definition: aggregates.hh:253\n+Dune::Amg::SymmetricDependency\n+Dependency policy for symmetric matrices.\n+Definition: aggregates.hh:314\n+Dune::Amg::Diagonal\n+Norm that uses only the [N][N] entry of the block to determine couplings.\n+Definition: aggregates.hh:379\n+Dune::Amg::FirstDiagonal\n+Norm that uses only the [0][0] entry of the block to determine couplings.\n+Definition: aggregates.hh:455\n+Dune::Amg::RowSum\n+Functor using the row sum (infinity) norm to determine strong couplings.\n+Definition: aggregates.hh:463\n+Dune::Amg::FrobeniusNorm\n+Definition: aggregates.hh:480\n+Dune::Amg::AlwaysOneNorm\n+Definition: aggregates.hh:496\n+Dune::Amg::SymmetricCriterion\n+Criterion taking advantage of symmetric matrices.\n+Definition: aggregates.hh:519\n+Dune::Amg::UnSymmetricCriterion\n+Criterion suitable for unsymmetric matrices.\n+Definition: aggregates.hh:539\n+Dune::Amg::Aggregator\n+Class for building the aggregates.\n+Definition: aggregates.hh:909\n+Dune::Amg::AggregatesMap\n+Class providing information about the mapping of the vertices onto aggregates.\n+Definition: aggregates.hh:560\n+Dune::Amg::AggregatesMap::DummyEdgeVisitor\n+A Dummy visitor that does nothing for each visited edge.\n+Definition: aggregates.hh:598\n+Dune::Amg::Aggregate\n+A class for temporarily storing the vertices of an aggregate in.\n+Definition: aggregates.hh:778\n+Dune::Amg::MatrixGraph::VertexDescriptor\n+M::size_type VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:73\n+Dune::Amg::MatrixGraph::ConstEdgeIterator\n+EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator\n+The constant edge iterator type.\n+Definition: graph.hh:298\n+Dune::Amg::MatrixGraph::EdgeIteratorT\n+Iterator over all edges starting from a vertex.\n+Definition: graph.hh:95\n+Dune::Amg::MatrixGraph::VertexIteratorT\n+The vertex iterator type of the graph.\n+Definition: graph.hh:209\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00134.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00134.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: parameters.hh File Reference\n+dune-istl: graph.hh File Reference\n \n \n \n \n \n \n \n@@ -65,60 +65,93 @@\n
  • dune
  • istl
  • paamg
  • \n \n \n \n+ \n \n
    \n \n-

    Parameter classes for customizing AMG. \n+

    Provides classes for building the matrix graph. \n More...

    \n
    #include <cstddef>
    \n+#include <algorithm>
    \n+#include <vector>
    \n+#include <cassert>
    \n+#include <limits>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/iteratorfacades.hh>
    \n+#include <dune/istl/istlexception.hh>
    \n+#include <dune/common/propertymap.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::DependencyParameters
     Parameters needed to check whether a node depends on another. More...
    class  Dune::Amg::MatrixGraph< M >
     The (undirected) graph of a matrix. More...
     
    class  Dune::Amg::AggregationParameters
     Parameters needed for the aggregation process. More...
    class  Dune::Amg::MatrixGraph< M >::EdgeIteratorT< C >
     Iterator over all edges starting from a vertex. More...
     
    class  Dune::Amg::CoarseningParameters
     Parameters for the complete coarsening process. More...
    class  Dune::Amg::MatrixGraph< M >::VertexIteratorT< C >
     The vertex iterator type of the graph. More...
     
    class  Dune::Amg::Parameters
     All parameters for AMG. More...
    class  Dune::Amg::SubGraph< G, T >
     A subgraph of a graph. More...
     
    class  Dune::Amg::SubGraph< G, T >::EdgeIndexMap
     An index map for mapping the edges to indices. More...
     
    class  Dune::Amg::SubGraph< G, T >::EdgeIterator
     The edge iterator of the graph. More...
     
    class  Dune::Amg::SubGraph< G, T >::VertexIterator
     The vertex iterator of the graph. More...
     
    class  Dune::Amg::VertexPropertiesGraph< G, VP, VM >
     Attaches properties to the vertices of a graph. More...
     
    class  Dune::Amg::VertexPropertiesGraph< G, VP, VM >::VertexIteratorT< C >
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >
     Attaches properties to the edges and vertices of a graph. More...
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::EdgeIteratorT< C >
     
    class  Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::VertexIteratorT< C >
     
    class  Dune::Amg::GraphVertexPropertiesSelector< G >
     Wrapper to access the internal edge properties of a graph via operator[]() More...
     
    class  Dune::Amg::GraphEdgePropertiesSelector< G >
     Wrapper to access the internal vertex properties of a graph via operator[]() More...
     
    \n \n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n-\n+\n+\n+\n+\n+\n

    \n-Enumerations

    enum  Dune::Amg::AccumulationMode { Dune::Amg::noAccu = 0\n-, Dune::Amg::atOnceAccu =1\n-, Dune::Amg::successiveAccu =2\n- }
     Identifiers for the different accumulation modes. More...
     

    \n+Functions

    template<class G , class V >
    int Dune::Amg::visitNeighbours (const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
     Visit all neighbour vertices of a vertex in a graph. More...
     
    \n

    Detailed Description

    \n-

    Parameter classes for customizing AMG.

    \n+

    Provides classes for building the matrix graph.

    \n
    Author
    Markus Blatt
    \n-

    All parameters of the AMG can be set by using the class Parameter, which can be provided to CoarsenCriterion via its constructor.

    \n+

    During the coarsening process in AMG the matrix graph together with the dependencies, what connections in the graph are considered strong or weak, what vertices are isolated, etc., have to build. This information will be contained in the MatrixGraph class.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,46 +5,86 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces | Enumerations\n-parameters.hh File Reference\n+Classes | Namespaces | Functions\n+graph.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n \u00bb Parallel_Algebraic_Multigrid\n-Parameter classes for customizing AMG. More...\n+Provides classes for building the matrix graph. More...\n #include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::DependencyParameters\n-\u00a0 Parameters needed to check whether a node depends on another. More...\n+class \u00a0Dune::Amg::MatrixGraph<_M_>\n+\u00a0 The (undirected) graph of a matrix. More...\n \u00a0\n-class \u00a0Dune::Amg::AggregationParameters\n-\u00a0 Parameters needed for the aggregation process. More...\n+class \u00a0Dune::Amg::MatrixGraph<_M_>::EdgeIteratorT<_C_>\n+\u00a0 Iterator over all edges starting from a vertex. More...\n \u00a0\n-class \u00a0Dune::Amg::CoarseningParameters\n-\u00a0 Parameters for the complete coarsening process. More...\n+class \u00a0Dune::Amg::MatrixGraph<_M_>::VertexIteratorT<_C_>\n+\u00a0 The vertex iterator type of the graph. More...\n \u00a0\n-class \u00a0Dune::Amg::Parameters\n-\u00a0 All parameters for AMG. More...\n+class \u00a0Dune::Amg::SubGraph<_G,_T_>\n+\u00a0 A subgraph of a graph. More...\n+\u00a0\n+class \u00a0Dune::Amg::SubGraph<_G,_T_>::EdgeIndexMap\n+\u00a0 An index map for mapping the edges to indices. More...\n+\u00a0\n+class \u00a0Dune::Amg::SubGraph<_G,_T_>::EdgeIterator\n+\u00a0 The edge iterator of the graph. More...\n+\u00a0\n+class \u00a0Dune::Amg::SubGraph<_G,_T_>::VertexIterator\n+\u00a0 The vertex iterator of the graph. More...\n+\u00a0\n+class \u00a0Dune::Amg::VertexPropertiesGraph<_G,_VP,_VM_>\n+\u00a0 Attaches properties to the vertices of a graph. More...\n+\u00a0\n+class \u00a0Dune::Amg::VertexPropertiesGraph<_G,_VP,_VM_>::VertexIteratorT<_C_>\n+\u00a0\n+class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>\n+\u00a0 Attaches properties to the edges and vertices of a graph. More...\n+\u00a0\n+class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>::EdgeIteratorT<_C_>\n+\u00a0\n+class \u00a0Dune::Amg::PropertiesGraph<_G,_VP,_EP,_VM,_EM_>::VertexIteratorT<_C_>\n+\u00a0\n+class \u00a0Dune::Amg::GraphVertexPropertiesSelector<_G_>\n+\u00a0 Wrapper to access the internal edge properties of a graph via operator\n+ []() More...\n+\u00a0\n+class \u00a0Dune::Amg::GraphEdgePropertiesSelector<_G_>\n+\u00a0 Wrapper to access the internal vertex properties of a graph via\n+ operator[]() More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n- Enumerations\n-enum \u00a0Dune::Amg::AccumulationMode { Dune::Amg::noAccu = 0 , Dune::Amg::\n- atOnceAccu =1 , Dune::Amg::successiveAccu =2 }\n-\u00a0 Identifiers for the different accumulation modes. More...\n+ Functions\n+template\n+int\u00a0Dune::Amg::visitNeighbours (const G &graph, const typename G::\n+ VertexDescriptor &vertex, V &visitor)\n+\u00a0 Visit all neighbour vertices of a vertex in a graph. More...\n \u00a0\n ***** Detailed Description *****\n-Parameter classes for customizing AMG.\n+Provides classes for building the matrix graph.\n Author\n Markus Blatt\n-All parameters of the AMG can be set by using the class Parameter, which can be\n-provided to CoarsenCriterion via its constructor.\n+During the coarsening process in AMG the matrix graph together with the\n+dependencies, what connections in the graph are considered strong or weak, what\n+vertices are isolated, etc., have to build. This information will be contained\n+in the MatrixGraph class.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00134_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00134_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: parameters.hh Source File\n+dune-istl: graph.hh Source File\n \n \n \n \n \n \n \n@@ -62,315 +62,1775 @@\n \n
    \n \n
    \n
    \n
    \n-
    parameters.hh
    \n+
    graph.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_PARAMETERS_HH
    \n-
    6#define DUNE_AMG_PARAMETERS_HH
    \n+
    5#ifndef DUNE_AMG_GRAPH_HH
    \n+
    6#define DUNE_AMG_GRAPH_HH
    \n
    7
    \n
    8#include <cstddef>
    \n-
    9
    \n-
    10namespace Dune
    \n-
    11{
    \n-
    12 namespace Amg
    \n-
    13 {
    \n-\n-
    31 {
    \n-
    32 public:
    \n-\n-
    35 : alpha_(1.0/3.0), beta_(1.0E-5)
    \n-
    36 {}
    \n-
    37
    \n-
    42 void setBeta(double b)
    \n-
    43 {
    \n-
    44 beta_ = b;
    \n-
    45 }
    \n-
    46
    \n-
    52 double beta() const
    \n-
    53 {
    \n-
    54 return beta_;
    \n-
    55 }
    \n-
    56
    \n-
    61 void setAlpha(double a)
    \n-
    62 {
    \n-
    63 alpha_ = a;
    \n-
    64 }
    \n-
    65
    \n-
    70 double alpha() const
    \n-
    71 {
    \n-
    72 return alpha_;
    \n-
    73 }
    \n+
    9#include <algorithm>
    \n+
    10#include <vector>
    \n+
    11#include <cassert>
    \n+
    12#include <limits>
    \n+
    13#include <dune/common/typetraits.hh>
    \n+
    14#include <dune/common/iteratorfacades.hh>
    \n+\n+
    16#include <dune/common/propertymap.hh>
    \n+
    17
    \n+
    18namespace Dune
    \n+
    19{
    \n+
    20 namespace Amg
    \n+
    21 {
    \n+
    49 template<class M>
    \n+\n+
    51 {
    \n+
    52 public:
    \n+
    56 typedef M Matrix;
    \n+
    57
    \n+
    61 typedef typename std::remove_const<M>::type MutableMatrix;
    \n+
    62
    \n+
    66 typedef typename M::block_type Weight;
    \n+
    67
    \n+
    73 typedef typename M::size_type VertexDescriptor;
    \n
    74
    \n-
    75 private:
    \n-
    76 double alpha_, beta_;
    \n-
    77 };
    \n-
    78
    \n-\n-\n-
    84 {
    \n-
    85 public:
    \n-\n-
    96 : maxDistance_(2), minAggregateSize_(4), maxAggregateSize_(6),
    \n-
    97 connectivity_(15), skipiso_(false)
    \n-
    98 {}
    \n-
    99
    \n-
    109 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    \n-
    110 {
    \n-
    111 maxDistance_=diameter-1;
    \n-
    112 std::size_t csize=1;
    \n-
    113
    \n-
    114 for(; dim>0; dim--) {
    \n-
    115 csize*=diameter;
    \n-
    116 maxDistance_+=diameter-1;
    \n-
    117 }
    \n-
    118 minAggregateSize_=csize;
    \n-
    119 maxAggregateSize_=static_cast<std::size_t>(csize*1.5);
    \n-
    120 }
    \n+
    80 typedef std::ptrdiff_t EdgeDescriptor;
    \n+
    81
    \n+
    82 enum {
    \n+
    83 /*
    \n+
    84 * @brief Whether Matrix is mutable.
    \n+
    85 */
    \n+
    86 mutableMatrix = std::is_same<M, typename std::remove_const<M>::type>::value
    \n+
    87 };
    \n+
    88
    \n+
    89
    \n+
    93 template<class C>
    \n+\n+
    95 {
    \n+
    96
    \n+
    97 public:
    \n+
    101 typedef typename std::remove_const<C>::type MutableContainer;
    \n+
    105 typedef const typename std::remove_const<C>::type ConstContainer;
    \n+
    106
    \n+
    107 friend class EdgeIteratorT<MutableContainer>;
    \n+
    108 friend class EdgeIteratorT<ConstContainer>;
    \n+
    109
    \n+
    110 enum {
    \n+
    112 isMutable = std::is_same<C, MutableContainer>::value
    \n+
    113 };
    \n+
    114
    \n+
    118 typedef typename std::conditional<isMutable && C::mutableMatrix,typename Matrix::row_type::Iterator,
    \n+
    119 typename Matrix::row_type::ConstIterator>::type
    \n+\n
    121
    \n-
    132 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)
    \n-
    133 {
    \n-
    134 setDefaultValuesIsotropic(dim, diameter);
    \n-
    135 maxDistance_+=dim-1;
    \n-
    136 }
    \n-
    144 std::size_t maxDistance() const { return maxDistance_;}
    \n-
    145
    \n-
    154 void setMaxDistance(std::size_t distance) { maxDistance_ = distance;}
    \n-
    155
    \n-
    161 bool skipIsolated() const
    \n-
    162 {
    \n-
    163 return skipiso_;
    \n-
    164 }
    \n+
    125 typedef typename std::conditional<isMutable && C::mutableMatrix,typename M::block_type,
    \n+
    126 const typename M::block_type>::type
    \n+\n+
    128
    \n+\n+
    137 const ColIterator& end, const EdgeDescriptor& edge);
    \n+
    138
    \n+\n+
    146
    \n+
    151 template<class C1>
    \n+\n+
    153
    \n+
    154 typedef typename std::conditional<std::is_same<C, typename std::remove_const<C>::type>::value && C::mutableMatrix,
    \n+
    155 typename M::block_type, const typename M::block_type>::type
    \n+\n+
    157
    \n+\n+
    162
    \n+\n
    165
    \n-
    171 void setSkipIsolated(bool skip)
    \n-
    172 {
    \n-
    173 skipiso_=skip;
    \n-
    174 }
    \n-
    175
    \n-
    180 std::size_t minAggregateSize() const { return minAggregateSize_;}
    \n-
    181
    \n-
    188 void setMinAggregateSize(std::size_t size){ minAggregateSize_=size;}
    \n+
    167 bool operator!=(const EdgeIteratorT<typename std::remove_const<C>::type>& other) const;
    \n+
    168
    \n+
    170 bool operator!=(const EdgeIteratorT<const typename std::remove_const<C>::type>& other) const;
    \n+
    171
    \n+
    173 bool operator==(const EdgeIteratorT<typename std::remove_const<C>::type>& other) const;
    \n+
    174
    \n+
    176 bool operator==(const EdgeIteratorT<const typename std::remove_const<C>::type>& other) const;
    \n+
    177
    \n+\n+
    180
    \n+\n+
    183
    \n+
    185 const EdgeDescriptor& operator*() const;
    \n+
    186
    \n+\n
    189
    \n-
    194 std::size_t maxAggregateSize() const { return maxAggregateSize_;}
    \n-
    195
    \n-
    202 void setMaxAggregateSize(std::size_t size){ maxAggregateSize_ = size;}
    \n+
    190 private:
    \n+
    192 VertexDescriptor source_;
    \n+
    194 ColIterator block_;
    \n+
    195 /***
    \n+
    196 * @brief The column iterator positioned at the end of the row
    \n+
    197 * of vertex source_
    \n+
    198 */
    \n+
    199 ColIterator blockEnd_;
    \n+
    201 EdgeDescriptor edge_;
    \n+
    202 };
    \n
    203
    \n-
    211 std::size_t maxConnectivity() const { return connectivity_;}
    \n-
    212
    \n-
    220 void setMaxConnectivity(std::size_t connectivity){ connectivity_ = connectivity;}
    \n-
    221
    \n-
    222 private:
    \n-
    223 std::size_t maxDistance_, minAggregateSize_, maxAggregateSize_, connectivity_;
    \n-
    224 bool skipiso_;
    \n-
    225
    \n-
    226 };
    \n+
    207 template<class C>
    \n+\n+
    209 {
    \n+
    210 public:
    \n+
    214 typedef typename std::remove_const<C>::type MutableContainer;
    \n+
    218 typedef const typename std::remove_const<C>::type ConstContainer;
    \n+
    219
    \n+
    220 friend class VertexIteratorT<MutableContainer>;
    \n+
    221 friend class VertexIteratorT<ConstContainer>;
    \n+
    222
    \n+
    223 enum {
    \n+
    225 isMutable = std::is_same<C, MutableContainer>::value
    \n+
    226 };
    \n
    227
    \n-
    228
    \n-\n-\n-\n-\n-
    249 };
    \n-
    250
    \n+
    233 explicit VertexIteratorT(C* graph, const VertexDescriptor& current);
    \n+
    234
    \n+
    242 explicit VertexIteratorT(const VertexDescriptor& current);
    \n+
    243
    \n+\n+
    245
    \n+\n
    251
    \n-
    252
    \n-
    253
    \n-\n-
    258 {
    \n-
    259 public:
    \n-
    263 void setMaxLevel(int l)
    \n-
    264 {
    \n-
    265 maxLevel_ = l;
    \n-
    266 }
    \n-
    270 int maxLevel() const
    \n-
    271 {
    \n-
    272 return maxLevel_;
    \n-
    273 }
    \n-
    274
    \n-
    278 void setCoarsenTarget(int nodes)
    \n-
    279 {
    \n-
    280 coarsenTarget_ = nodes;
    \n-
    281 }
    \n+\n+
    254
    \n+\n+
    257
    \n+\n+
    260
    \n+\n+
    263
    \n+
    264 typedef typename std::conditional<std::is_same<C, typename std::remove_const<C>::type>::value && C::mutableMatrix,
    \n+
    265 typename M::block_type, const typename M::block_type>::type
    \n+\n+\n+
    269
    \n+\n+
    275
    \n+\n
    282
    \n-
    286 int coarsenTarget() const
    \n-
    287 {
    \n-
    288 return coarsenTarget_;
    \n-
    289 }
    \n-
    290
    \n-
    296 void setMinCoarsenRate(double rate)
    \n-
    297 {
    \n-
    298 minCoarsenRate_ = rate;
    \n-
    299 }
    \n-
    300
    \n-
    304 double minCoarsenRate() const
    \n-
    305 {
    \n-
    306 return minCoarsenRate_;
    \n-
    307 }
    \n-
    308
    \n-\n-
    313 {
    \n-
    314 return accumulate_;
    \n-
    315 }
    \n-\n-
    320 {
    \n-
    321 accumulate_=accu;
    \n-
    322 }
    \n-
    323
    \n-
    324 void setAccumulate(bool accu){
    \n-
    325 accumulate_=accu ? successiveAccu : noAccu;
    \n-
    326 }
    \n-\n-
    333 {
    \n-
    334 dampingFactor_ = d;
    \n-
    335 }
    \n-
    336
    \n-\n-
    343 {
    \n-
    344 return dampingFactor_;
    \n-
    345 }
    \n-\n-
    357 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n-
    358 : maxLevel_(maxLevel), coarsenTarget_(coarsenTarget), minCoarsenRate_(minCoarsenRate),
    \n-
    359 dampingFactor_(prolongDamp), accumulate_( accumulate)
    \n-
    360 {}
    \n-
    361
    \n-
    362 private:
    \n-
    366 int maxLevel_;
    \n-
    370 int coarsenTarget_;
    \n-
    374 double minCoarsenRate_;
    \n-
    378 double dampingFactor_;
    \n-
    383 AccumulationMode accumulate_;
    \n-
    384 };
    \n-
    385
    \n-\n-
    393 {
    \n-
    394 public:
    \n-
    401 void setDebugLevel(int level)
    \n-
    402 {
    \n-
    403 debugLevel_ = level;
    \n-
    404 }
    \n-
    405
    \n-
    411 int debugLevel() const
    \n-
    412 {
    \n-
    413 return debugLevel_;
    \n-
    414 }
    \n-
    415
    \n-
    420 void setNoPreSmoothSteps(std::size_t steps)
    \n-
    421 {
    \n-
    422 preSmoothSteps_=steps;
    \n-
    423 }
    \n-
    428 std::size_t getNoPreSmoothSteps() const
    \n-
    429 {
    \n-
    430 return preSmoothSteps_;
    \n-
    431 }
    \n-
    432
    \n-
    437 void setNoPostSmoothSteps(std::size_t steps)
    \n-
    438 {
    \n-
    439 postSmoothSteps_=steps;
    \n-
    440 }
    \n-
    445 std::size_t getNoPostSmoothSteps() const
    \n-
    446 {
    \n-
    447 return postSmoothSteps_;
    \n-
    448 }
    \n+\n+
    289
    \n+
    290 private:
    \n+
    291 C* graph_;
    \n+
    292 VertexDescriptor current_;
    \n+
    293 };
    \n+
    294
    \n+\n+
    299
    \n+\n+
    304
    \n+\n+
    309
    \n+\n+
    314
    \n+\n+
    320
    \n+\n+
    325
    \n+\n+
    331
    \n+\n+
    337
    \n+\n+
    343
    \n+\n+
    349
    \n+\n+
    357
    \n+\n+
    365
    \n+
    366
    \n+\n+
    374
    \n+\n+
    382
    \n+\n+
    388
    \n+
    393 const Matrix& matrix() const;
    \n+
    394
    \n+
    398 std::size_t noVertices() const;
    \n+
    399
    \n+\n+
    407
    \n+
    411 std::size_t noEdges() const;
    \n+
    412
    \n+\n+
    420 const VertexDescriptor& target) const;
    \n+
    421
    \n+
    422 private:
    \n+
    424 Matrix& matrix_;
    \n+
    426 EdgeDescriptor* start_;
    \n+
    428 MatrixGraph(const MatrixGraph&);
    \n+
    429
    \n+
    430 };
    \n+
    431
    \n+
    441 template<class G, class T>
    \n+\n+
    443 {
    \n+
    444 public:
    \n+
    448 typedef G Graph;
    \n
    449
    \n-
    453 void setGamma(std::size_t gamma)
    \n-
    454 {
    \n-
    455 gamma_=gamma;
    \n-
    456 }
    \n-
    460 std::size_t getGamma() const
    \n-
    461 {
    \n-
    462 return gamma_;
    \n-
    463 }
    \n-
    464
    \n-
    469 void setAdditive(bool additive)
    \n+
    454 typedef T Excluded;
    \n+
    455
    \n+
    459 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n+
    460
    \n+\n+
    462
    \n+\n
    470 {
    \n-
    471 additive_=additive;
    \n-
    472 }
    \n+
    471 public:
    \n+
    472 typedef ReadablePropertyMapTag Category;
    \n
    473
    \n-
    478 bool getAdditive() const
    \n-
    479 {
    \n-
    480 return additive_;
    \n-
    481 }
    \n+
    474 EdgeIndexMap(const EdgeDescriptor& firstEdge)
    \n+
    475 : firstEdge_(firstEdge)
    \n+
    476 {}
    \n+
    477
    \n+\n+
    480 : firstEdge_(emap.firstEdge_)
    \n+
    481 {}
    \n
    482
    \n-
    493 Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,
    \n-
    494 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n-\n-
    496 , debugLevel_(2), preSmoothSteps_(2), postSmoothSteps_(2), gamma_(1),
    \n-
    497 additive_(false)
    \n-
    498 {}
    \n-
    499 private:
    \n-
    500 int debugLevel_;
    \n-
    501 std::size_t preSmoothSteps_;
    \n-
    502 std::size_t postSmoothSteps_;
    \n-
    503 std::size_t gamma_;
    \n-
    504 bool additive_;
    \n-
    505 };
    \n-
    506
    \n-
    507 } //namespace AMG
    \n-
    508
    \n-
    509} //namespace Dune
    \n-
    510#endif
    \n-
    void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an anisotropic problem.
    Definition: parameters.hh:132
    \n-
    void setAdditive(bool additive)
    Set whether to use additive multigrid.
    Definition: parameters.hh:469
    \n-
    void setSkipIsolated(bool skip)
    Set whether isolated aggregates will not be represented on the coarse level.
    Definition: parameters.hh:171
    \n-
    void setProlongationDampingFactor(double d)
    Set the damping factor for the prolongation.
    Definition: parameters.hh:332
    \n-
    double alpha() const
    Get the scaling value for marking connections as strong. Default value is 1/3.
    Definition: parameters.hh:70
    \n-
    void setMaxAggregateSize(std::size_t size)
    Set the maximum number of nodes a aggregate is allowed to have.
    Definition: parameters.hh:202
    \n-
    void setMinCoarsenRate(double rate)
    Set the minimum coarsening rate to be achieved in each coarsening.
    Definition: parameters.hh:296
    \n-
    double minCoarsenRate() const
    Get the minimum coarsening rate to be achieved.
    Definition: parameters.hh:304
    \n-
    std::size_t maxAggregateSize() const
    Get the maximum number of nodes a aggregate is allowed to have.
    Definition: parameters.hh:194
    \n-
    void setAlpha(double a)
    Set the scaling value for marking connections as strong. Default value is 1/3.
    Definition: parameters.hh:61
    \n-
    double beta() const
    Get the threshold for marking nodes as isolated. The default value is 1.0E-5.
    Definition: parameters.hh:52
    \n-
    std::size_t maxConnectivity() const
    Get the maximum number of connections a aggregate is allowed to have.
    Definition: parameters.hh:211
    \n-
    int coarsenTarget() const
    Get the maximum number of unknowns allowed on the coarsest level.
    Definition: parameters.hh:286
    \n-
    void setAccumulate(AccumulationMode accu)
    Set whether he data should be accumulated on fewer processes on coarser levels.
    Definition: parameters.hh:319
    \n-
    double getProlongationDampingFactor() const
    Get the damping factor for the prolongation.
    Definition: parameters.hh:342
    \n-
    AccumulationMode accumulate() const
    Whether the data should be accumulated on fewer processes on coarser levels.
    Definition: parameters.hh:312
    \n-
    void setMaxConnectivity(std::size_t connectivity)
    Set the maximum number of connections a aggregate is allowed to have.
    Definition: parameters.hh:220
    \n-
    std::size_t minAggregateSize() const
    Get the minimum number of nodes a aggregate has to consist of.
    Definition: parameters.hh:180
    \n-
    bool getAdditive() const
    Get whether to use additive multigrid.
    Definition: parameters.hh:478
    \n-
    void setMaxLevel(int l)
    Set the maximum number of levels allowed in the hierarchy.
    Definition: parameters.hh:263
    \n-
    void setDebugLevel(int level)
    Set the debugging level.
    Definition: parameters.hh:401
    \n-
    std::size_t getGamma() const
    Get the value of gamma; 1 for V-cycle, 2 for W-cycle.
    Definition: parameters.hh:460
    \n-
    void setNoPostSmoothSteps(std::size_t steps)
    Set the number of postsmoothing steps to apply.
    Definition: parameters.hh:437
    \n-
    std::size_t getNoPreSmoothSteps() const
    Get the number of presmoothing steps to apply.
    Definition: parameters.hh:428
    \n-
    DependencyParameters()
    Constructor.
    Definition: parameters.hh:34
    \n-
    void setMinAggregateSize(std::size_t size)
    Set the minimum number of nodes a aggregate has to consist of.
    Definition: parameters.hh:188
    \n-
    int maxLevel() const
    Get the maximum number of levels allowed in the hierarchy.
    Definition: parameters.hh:270
    \n-
    void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an isotropic problem.
    Definition: parameters.hh:109
    \n-
    AggregationParameters()
    Constructor.
    Definition: parameters.hh:95
    \n-
    bool skipIsolated() const
    Whether isolated aggregates will not be represented on the coarse level.
    Definition: parameters.hh:161
    \n-
    Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: parameters.hh:493
    \n-
    void setCoarsenTarget(int nodes)
    Set the maximum number of unknowns allowed on the coarsest level.
    Definition: parameters.hh:278
    \n-
    void setNoPreSmoothSteps(std::size_t steps)
    Set the number of presmoothing steps to apply.
    Definition: parameters.hh:420
    \n-
    AccumulationMode
    Identifiers for the different accumulation modes.
    Definition: parameters.hh:232
    \n-
    void setBeta(double b)
    Set threshold for marking nodes as isolated. The default value is 1.0E-5.
    Definition: parameters.hh:42
    \n-
    std::size_t maxDistance() const
    Get the maximal distance allowed between two nodes in a aggregate.
    Definition: parameters.hh:144
    \n-
    CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: parameters.hh:356
    \n-
    void setGamma(std::size_t gamma)
    Set the value of gamma; 1 for V-cycle, 2 for W-cycle.
    Definition: parameters.hh:453
    \n-
    void setAccumulate(bool accu)
    Definition: parameters.hh:324
    \n-
    void setMaxDistance(std::size_t distance)
    Set the maximal distance allowed between two nodes in a aggregate.
    Definition: parameters.hh:154
    \n-
    int debugLevel() const
    Get the debugging Level.
    Definition: parameters.hh:411
    \n-
    std::size_t getNoPostSmoothSteps() const
    Get the number of postsmoothing steps to apply.
    Definition: parameters.hh:445
    \n-
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n-
    @ noAccu
    No data accumulution.
    Definition: parameters.hh:238
    \n-
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n+
    483 std::size_t operator[](const EdgeDescriptor& edge) const
    \n+
    484 {
    \n+
    485 return edge-firstEdge_;
    \n+
    486 }
    \n+
    487 private:
    \n+
    489 EdgeDescriptor firstEdge_;
    \n+\n+
    492 {}
    \n+
    493 };
    \n+
    494
    \n+\n+
    500
    \n+
    504 class EdgeIterator : public RandomAccessIteratorFacade<EdgeIterator,const EdgeDescriptor>
    \n+
    505 {
    \n+
    506 public:
    \n+
    512 explicit EdgeIterator(const VertexDescriptor& source, const EdgeDescriptor& edge);
    \n+
    513
    \n+
    521 explicit EdgeIterator(const EdgeDescriptor& edge);
    \n+
    522
    \n+
    524 bool equals(const EdgeIterator& other) const;
    \n+
    525
    \n+\n+
    528
    \n+\n+
    531
    \n+
    532 EdgeIterator& advance(std::ptrdiff_t n);
    \n+
    533
    \n+\n+
    536
    \n+
    538 const VertexDescriptor& target() const;
    \n+
    539
    \n+
    541 const VertexDescriptor& source() const;
    \n+
    542
    \n+
    543 std::ptrdiff_t distanceTo(const EdgeIterator& other) const;
    \n+
    544
    \n+
    545 private:
    \n+
    547 VertexDescriptor source_;
    \n+
    552 EdgeDescriptor edge_;
    \n+
    553 };
    \n+
    554
    \n+\n+
    559 : public ForwardIteratorFacade<VertexIterator,const VertexDescriptor>
    \n+
    560 {
    \n+
    561 public:
    \n+
    568 explicit VertexIterator(const SubGraph<G,T>* graph, const VertexDescriptor& current,
    \n+
    569 const VertexDescriptor& end);
    \n+
    570
    \n+
    571
    \n+
    578 explicit VertexIterator(const VertexDescriptor& current);
    \n+
    579
    \n+\n+
    582
    \n+
    584 bool equals(const VertexIterator& other) const;
    \n+
    585
    \n+\n+
    591
    \n+\n+
    598
    \n+\n+
    605
    \n+
    606 private:
    \n+
    608 const SubGraph<Graph,T>* graph_;
    \n+
    610 VertexDescriptor current_;
    \n+
    612 VertexDescriptor end_;
    \n+
    613 };
    \n+
    614
    \n+\n+
    619
    \n+\n+
    624
    \n+\n+
    630
    \n+\n+
    636
    \n+\n+
    644
    \n+\n+
    652
    \n+
    656 std::size_t noVertices() const;
    \n+
    657
    \n+\n+
    665
    \n+
    669 std::size_t noEdges() const;
    \n+\n+
    677 const VertexDescriptor& target) const;
    \n+
    685 SubGraph(const Graph& graph, const T& excluded);
    \n+
    686
    \n+\n+
    691
    \n+
    692 private:
    \n+
    694 const T& excluded_;
    \n+
    696 std::size_t noVertices_;
    \n+
    698 VertexDescriptor endVertex_;
    \n+
    700 int noEdges_;
    \n+
    705 VertexDescriptor maxVertex_;
    \n+
    707 VertexDescriptor* edges_;
    \n+
    709 std::ptrdiff_t* start_;
    \n+
    711 std::ptrdiff_t* end_;
    \n+
    713 SubGraph(const SubGraph&)
    \n+
    714 {}
    \n+
    715 };
    \n+
    716
    \n+
    717
    \n+
    721 template<class G, class VP, class VM=IdentityMap>
    \n+\n+
    723 {
    \n+
    724 public:
    \n+
    728 typedef G Graph;
    \n+
    729
    \n+
    733 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n+
    734
    \n+
    738 typedef typename Graph::EdgeDescriptor EdgeDescriptor;
    \n+
    739
    \n+\n+
    744
    \n+
    756 typedef VM VertexMap;
    \n+
    757
    \n+
    761 typedef typename Graph::EdgeIterator EdgeIterator;
    \n+
    762
    \n+
    766 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;
    \n+
    767
    \n+\n+
    774
    \n+\n+
    781
    \n+\n+
    788
    \n+\n+
    795
    \n+
    796
    \n+
    797 template<class C>
    \n+\n+
    799 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    800 C>::value,
    \n+
    801 typename Graph::VertexIterator,
    \n+
    802 typename Graph::ConstVertexIterator>::type
    \n+
    803 {
    \n+
    804 friend class VertexIteratorT<const typename std::remove_const<C>::type>;
    \n+
    805 friend class VertexIteratorT<typename std::remove_const<C>::type>;
    \n+
    806 public:
    \n+
    810 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    811 C>::value,
    \n+
    812 typename Graph::VertexIterator,
    \n+
    813 typename Graph::ConstVertexIterator>::type
    \n+\n+
    815
    \n+
    819 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    820 C>::value,
    \n+
    821 typename Graph::EdgeIterator,
    \n+
    822 typename Graph::ConstEdgeIterator>::type
    \n+\n+
    824
    \n+
    830 explicit VertexIteratorT(const Father& iter,
    \n+
    831 C* graph);
    \n+
    832
    \n+
    833
    \n+
    841 explicit VertexIteratorT(const Father& iter);
    \n+
    842
    \n+
    847 template<class C1>
    \n+
    848 VertexIteratorT(const VertexIteratorT<C1>& other);
    \n+
    849
    \n+
    853 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n+
    854 VertexProperties&,
    \n+
    855 const VertexProperties&>::type
    \n+
    856 properties() const;
    \n+
    857
    \n+\n+
    864
    \n+\n+
    871
    \n+
    872 private:
    \n+
    876 C* graph_;
    \n+
    877 };
    \n+
    878
    \n+
    882 typedef VertexIteratorT<VertexPropertiesGraph<Graph,
    \n+
    883 VertexProperties,VM> > VertexIterator;
    \n+
    884
    \n+
    888 typedef VertexIteratorT<const VertexPropertiesGraph<Graph,
    \n+
    889 VertexProperties,VM> > ConstVertexIterator;
    \n+
    890
    \n+\n+
    896
    \n+\n+
    902
    \n+\n+
    908
    \n+\n+
    914
    \n+
    920 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);
    \n+
    921
    \n+
    927 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex) const;
    \n+
    928
    \n+
    933 const Graph& graph() const;
    \n+
    934
    \n+
    938 std::size_t noVertices() const;
    \n+
    939
    \n+
    943 std::size_t noEdges() const;
    \n+
    944
    \n+\n+
    952
    \n+
    958 VertexPropertiesGraph(Graph& graph, const VertexMap vmap=VertexMap());
    \n+
    959
    \n+
    960 private:
    \n+
    961 VertexPropertiesGraph(const VertexPropertiesGraph&)
    \n+
    962 {}
    \n+
    963
    \n+
    965 Graph& graph_;
    \n+
    967 VertexMap vmap_;
    \n+
    969 std::vector<VertexProperties> vertexProperties_;
    \n+
    970
    \n+
    971 };
    \n+
    972
    \n+
    976 template<class G, class VP, class EP, class VM=IdentityMap, class EM=IdentityMap>
    \n+\n+
    978 {
    \n+
    979 public:
    \n+
    983 typedef G Graph;
    \n+
    984
    \n+
    988 typedef typename Graph::VertexDescriptor VertexDescriptor;
    \n+
    989
    \n+
    993 typedef typename Graph::EdgeDescriptor EdgeDescriptor;
    \n+
    994
    \n+\n+
    999
    \n+
    1011 typedef VM VertexMap;
    \n+
    1012
    \n+
    1016 typedef EP EdgeProperties;
    \n+
    1017
    \n+
    1018
    \n+
    1030 typedef EM EdgeMap;
    \n+
    1031
    \n+
    1032 template<class C>
    \n+\n+
    1034 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    1035 C>::value,
    \n+
    1036 typename Graph::EdgeIterator,
    \n+
    1037 typename Graph::ConstEdgeIterator>::type
    \n+
    1038 {
    \n+
    1039
    \n+
    1040 friend class EdgeIteratorT<const typename std::remove_const<C>::type>;
    \n+
    1041 friend class EdgeIteratorT<typename std::remove_const<C>::type>;
    \n+
    1042 public:
    \n+
    1046 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    1047 C>::value,
    \n+
    1048 typename Graph::EdgeIterator,
    \n+
    1049 typename Graph::ConstEdgeIterator>::type
    \n+\n+
    1051
    \n+
    1057 explicit EdgeIteratorT(const Father& iter,
    \n+
    1058 C* graph);
    \n+
    1059
    \n+
    1067 explicit EdgeIteratorT(const Father& iter);
    \n+
    1068
    \n+
    1073 template<class C1>
    \n+
    1074 EdgeIteratorT(const EdgeIteratorT<C1>& other);
    \n+
    1075
    \n+
    1079 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n+
    1080 EdgeProperties&,
    \n+
    1081 const EdgeProperties&>::type
    \n+
    1082 properties() const;
    \n+
    1083
    \n+
    1084 private:
    \n+
    1088 C* graph_;
    \n+
    1089 };
    \n+
    1090
    \n+
    1094 typedef EdgeIteratorT<PropertiesGraph<Graph,
    \n+
    1095 VertexProperties,
    \n+
    1096 EdgeProperties,VM,EM> > EdgeIterator;
    \n+
    1097
    \n+
    1101 typedef EdgeIteratorT<const PropertiesGraph<Graph,
    \n+
    1102 VertexProperties,
    \n+
    1103 EdgeProperties,VM,EM> > ConstEdgeIterator;
    \n+
    1104
    \n+
    1110 EdgeIterator beginEdges(const VertexDescriptor& source);
    \n+
    1111
    \n+
    1117 EdgeIterator endEdges(const VertexDescriptor& source);
    \n+
    1118
    \n+
    1124 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;
    \n+
    1125
    \n+
    1131 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;
    \n+
    1132
    \n+
    1133
    \n+
    1134 template<class C>
    \n+\n+
    1136 : public std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    1137 C>::value,
    \n+
    1138 typename Graph::VertexIterator,
    \n+
    1139 typename Graph::ConstVertexIterator>::type
    \n+
    1140 {
    \n+
    1141 friend class VertexIteratorT<const typename std::remove_const<C>::type>;
    \n+
    1142 friend class VertexIteratorT<typename std::remove_const<C>::type>;
    \n+
    1143 public:
    \n+
    1147 typedef typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    1148 C>::value,
    \n+
    1149 typename Graph::VertexIterator,
    \n+
    1150 typename Graph::ConstVertexIterator>::type
    \n+\n+
    1152
    \n+
    1158 explicit VertexIteratorT(const Father& iter,
    \n+
    1159 C* graph);
    \n+
    1160
    \n+
    1161
    \n+
    1169 explicit VertexIteratorT(const Father& iter);
    \n+
    1170
    \n+
    1175 template<class C1>
    \n+
    1176 VertexIteratorT(const VertexIteratorT<C1>& other);
    \n+
    1177
    \n+
    1181 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n+
    1182 VertexProperties&,
    \n+
    1183 const VertexProperties&>::type
    \n+
    1184 properties() const;
    \n+
    1185
    \n+\n+
    1192
    \n+
    1198 EdgeIteratorT<C> end() const;
    \n+
    1199
    \n+
    1200 private:
    \n+
    1204 C* graph_;
    \n+
    1205 };
    \n+
    1206
    \n+
    1210 typedef VertexIteratorT<PropertiesGraph<Graph,
    \n+
    1211 VertexProperties,
    \n+
    1212 EdgeProperties,VM,EM> > VertexIterator;
    \n+
    1213
    \n+
    1217 typedef VertexIteratorT<const PropertiesGraph<Graph,
    \n+
    1218 VertexProperties,
    \n+
    1219 EdgeProperties,VM,EM> > ConstVertexIterator;
    \n+
    1220
    \n+\n+
    1226
    \n+\n+
    1232
    \n+\n+
    1238
    \n+\n+
    1244
    \n+
    1250 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);
    \n+
    1251
    \n+
    1257 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex) const;
    \n+
    1258
    \n+
    1265 EdgeDescriptor findEdge(const VertexDescriptor& source,
    \n+
    1266 const VertexDescriptor& target)
    \n+
    1267 {
    \n+
    1268 return graph_.findEdge(source,target);
    \n+
    1269 }
    \n+
    1270
    \n+\n+
    1277
    \n+
    1278
    \n+\n+
    1285
    \n+\n+
    1293 const VertexDescriptor& target);
    \n+
    1294
    \n+\n+
    1302 const VertexDescriptor& target) const;
    \n+
    1303
    \n+
    1308 const Graph& graph() const;
    \n+
    1309
    \n+
    1313 std::size_t noVertices() const;
    \n+
    1314
    \n+
    1318 std::size_t noEdges() const;
    \n+
    1319
    \n+\n+
    1327
    \n+\n+
    1335 const EdgeMap& emap=EdgeMap());
    \n+
    1336
    \n+
    1337 private:
    \n+\n+
    1339 {}
    \n+
    1340
    \n+
    1342 Graph& graph_;
    \n+
    1345 VertexMap vmap_;
    \n+
    1346 std::vector<VertexProperties> vertexProperties_;
    \n+
    1348 EdgeMap emap_;
    \n+
    1350 std::vector<EdgeProperties> edgeProperties_;
    \n+
    1351
    \n+
    1352 };
    \n+
    1353
    \n+
    1354
    \n+
    1359 template<typename G>
    \n+\n+
    1361 {
    \n+
    1362 public:
    \n+
    1366 typedef G Graph;
    \n+
    1370 typedef typename G::VertexProperties VertexProperties;
    \n+
    1374 typedef typename G::VertexDescriptor Vertex;
    \n+
    1375
    \n+\n+
    1381 : graph_(g)
    \n+
    1382 {}
    \n+\n+
    1387 : graph_(0)
    \n+
    1388 {}
    \n+
    1389
    \n+
    1390
    \n+
    1395 VertexProperties& operator[](const Vertex& vertex) const
    \n+
    1396 {
    \n+
    1397 return graph_->getVertexProperties(vertex);
    \n+
    1398 }
    \n+
    1399 private:
    \n+
    1400 Graph* graph_;
    \n+
    1401 };
    \n+
    1402
    \n+
    1407 template<typename G>
    \n+\n+
    1409 {
    \n+
    1410 public:
    \n+
    1414 typedef G Graph;
    \n+
    1418 typedef typename G::EdgeProperties EdgeProperties;
    \n+
    1422 typedef typename G::EdgeDescriptor Edge;
    \n+
    1423
    \n+\n+
    1429 : graph_(g)
    \n+
    1430 {}
    \n+\n+
    1435 : graph_(0)
    \n+
    1436 {}
    \n+
    1437
    \n+
    1442 EdgeProperties& operator[](const Edge& edge) const
    \n+
    1443 {
    \n+
    1444 return graph_->getEdgeProperties(edge);
    \n+
    1445 }
    \n+
    1446 private:
    \n+
    1447 Graph* graph_;
    \n+
    1448 };
    \n+
    1449
    \n+
    1450
    \n+
    1461 template<class G, class V>
    \n+
    1462 int visitNeighbours(const G& graph, const typename G::VertexDescriptor& vertex,
    \n+
    1463 V& visitor);
    \n+
    1464
    \n+
    1465#ifndef DOXYGEN
    \n+
    1466
    \n+
    1467 template<class M>
    \n+\n+
    1469 : matrix_(matrix)
    \n+
    1470 {
    \n+
    1471 if(matrix_.N()!=matrix_.M())
    \n+
    1472 DUNE_THROW(ISTLError, "Matrix has to have as many columns as rows!");
    \n+
    1473
    \n+
    1474 start_ = new EdgeDescriptor[matrix_.N()+1];
    \n+
    1475
    \n+
    1476 typedef typename M::ConstIterator Iterator;
    \n+
    1477 start_[matrix_.begin().index()] = 0;
    \n+
    1478
    \n+
    1479 for(Iterator row=matrix_.begin(); row != matrix_.end(); ++row)
    \n+
    1480 start_[row.index()+1] = start_[row.index()] + row->size();
    \n+
    1481 }
    \n+
    1482
    \n+
    1483 template<class M>
    \n+
    1484 MatrixGraph<M>::~MatrixGraph()
    \n+
    1485 {
    \n+
    1486 delete[] start_;
    \n+
    1487 }
    \n+
    1488
    \n+
    1489 template<class M>
    \n+
    1490 inline std::size_t MatrixGraph<M>::noEdges() const
    \n+
    1491 {
    \n+
    1492 return start_[matrix_.N()];
    \n+
    1493 }
    \n+
    1494
    \n+
    1495 template<class M>
    \n+
    1496 inline std::size_t MatrixGraph<M>::noVertices() const
    \n+
    1497 {
    \n+
    1498 return matrix_.N();
    \n+
    1499 }
    \n+
    1500
    \n+
    1501 template<class M>
    \n+
    1502 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::maxVertex() const
    \n+
    1503 {
    \n+
    1504 return matrix_.N()-1;
    \n+
    1505 }
    \n+
    1506
    \n+
    1507 template<class M>
    \n+
    1508 typename MatrixGraph<M>::EdgeDescriptor
    \n+
    1509 MatrixGraph<M>::findEdge(const VertexDescriptor& source,
    \n+
    1510 const VertexDescriptor& target) const
    \n+
    1511 {
    \n+
    1512 typename M::ConstColIterator found =matrix_[source].find(target);
    \n+
    1513 if(found == matrix_[source].end())
    \n+
    1514 return std::numeric_limits<EdgeDescriptor>::max();
    \n+
    1515 std::size_t offset = found.offset();
    \n+
    1516 if(target>source)
    \n+
    1517 offset--;
    \n+
    1518
    \n+
    1519 assert(offset<noEdges());
    \n+
    1520
    \n+
    1521 return start_[source]+offset;
    \n+
    1522 }
    \n+
    1523
    \n+
    1524
    \n+
    1525 template<class M>
    \n+
    1526 inline M& MatrixGraph<M>::matrix()
    \n+
    1527 {
    \n+
    1528 return matrix_;
    \n+
    1529 }
    \n+
    1530
    \n+
    1531 template<class M>
    \n+
    1532 inline const M& MatrixGraph<M>::matrix() const
    \n+
    1533 {
    \n+
    1534 return matrix_;
    \n+
    1535 }
    \n+
    1536
    \n+
    1537 template<class M>
    \n+
    1538 template<class C>
    \n+
    1539 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const VertexDescriptor& source, const ColIterator& block,
    \n+
    1540 const ColIterator& end, const EdgeDescriptor& edge)
    \n+
    1541 : source_(source), block_(block), blockEnd_(end), edge_(edge)
    \n+
    1542 {
    \n+
    1543 if(block_!=blockEnd_ && block_.index() == source_) {
    \n+
    1544 // This is the edge from the diagonal to the diagonal. Skip it.
    \n+
    1545 ++block_;
    \n+
    1546 }
    \n+
    1547 }
    \n+
    1548
    \n+
    1549 template<class M>
    \n+
    1550 template<class C>
    \n+
    1551 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const ColIterator& block)
    \n+
    1552 : block_(block)
    \n+
    1553 {}
    \n+
    1554
    \n+
    1555 template<class M>
    \n+
    1556 template<class C>
    \n+
    1557 template<class C1>
    \n+
    1558 MatrixGraph<M>::EdgeIteratorT<C>::EdgeIteratorT(const EdgeIteratorT<C1>& other)
    \n+
    1559 : source_(other.source_), block_(other.block_), blockEnd_(other.blockEnd_), edge_(other.edge_)
    \n+
    1560 {}
    \n+
    1561
    \n+
    1562
    \n+
    1563 template<class M>
    \n+
    1564 template<class C>
    \n+
    1565 inline typename MatrixGraph<M>::template EdgeIteratorT<C>::WeightType&
    \n+
    1566 MatrixGraph<M>::EdgeIteratorT<C>::weight() const
    \n+
    1567 {
    \n+
    1568 return *block_;
    \n+
    1569 }
    \n+
    1570
    \n+
    1571 template<class M>
    \n+
    1572 template<class C>
    \n+
    1573 inline typename MatrixGraph<M>::template EdgeIteratorT<C>& MatrixGraph<M>::EdgeIteratorT<C>::operator++()
    \n+
    1574 {
    \n+
    1575 ++block_;
    \n+
    1576 ++edge_;
    \n+
    1577
    \n+
    1578 if(block_!=blockEnd_ && block_.index() == source_) {
    \n+
    1579 // This is the edge from the diagonal to the diagonal. Skip it.
    \n+
    1580 ++block_;
    \n+
    1581 }
    \n+
    1582
    \n+
    1583 return *this;
    \n+
    1584 }
    \n+
    1585
    \n+
    1586 template<class M>
    \n+
    1587 template<class C>
    \n+
    1588 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator!=(const typename MatrixGraph<M>::template EdgeIteratorT<typename std::remove_const<C>::type>& other) const
    \n+
    1589 {
    \n+
    1590 return block_!=other.block_;
    \n+
    1591 }
    \n+
    1592
    \n+
    1593 template<class M>
    \n+
    1594 template<class C>
    \n+
    1595 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator!=(const typename MatrixGraph<M>::template EdgeIteratorT<const typename std::remove_const<C>::type>& other) const
    \n+
    1596 {
    \n+
    1597 return block_!=other.block_;
    \n+
    1598 }
    \n+
    1599
    \n+
    1600 template<class M>
    \n+
    1601 template<class C>
    \n+
    1602 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator==(const typename MatrixGraph<M>::template EdgeIteratorT<typename std::remove_const<C>::type>& other) const
    \n+
    1603 {
    \n+
    1604 return block_==other.block_;
    \n+
    1605 }
    \n+
    1606
    \n+
    1607 template<class M>
    \n+
    1608 template<class C>
    \n+
    1609 inline bool MatrixGraph<M>::EdgeIteratorT<C>::operator==(const typename MatrixGraph<M>::template EdgeIteratorT<const typename std::remove_const<C>::type>& other) const
    \n+
    1610 {
    \n+
    1611 return block_==other.block_;
    \n+
    1612 }
    \n+
    1613
    \n+
    1614 template<class M>
    \n+
    1615 template<class C>
    \n+
    1616 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::EdgeIteratorT<C>::target() const
    \n+
    1617 {
    \n+
    1618 return block_.index();
    \n+
    1619 }
    \n+
    1620
    \n+
    1621 template<class M>
    \n+
    1622 template<class C>
    \n+
    1623 inline typename MatrixGraph<M>::VertexDescriptor MatrixGraph<M>::EdgeIteratorT<C>::source() const
    \n+
    1624 {
    \n+
    1625 return source_;
    \n+
    1626 }
    \n+
    1627
    \n+
    1628 template<class M>
    \n+
    1629 template<class C>
    \n+
    1630 inline const typename MatrixGraph<M>::EdgeDescriptor& MatrixGraph<M>::EdgeIteratorT<C>::operator*() const
    \n+
    1631 {
    \n+
    1632 return edge_;
    \n+
    1633 }
    \n+
    1634
    \n+
    1635 template<class M>
    \n+
    1636 template<class C>
    \n+
    1637 inline const typename MatrixGraph<M>::EdgeDescriptor* MatrixGraph<M>::EdgeIteratorT<C>::operator->() const
    \n+
    1638 {
    \n+
    1639 return &edge_;
    \n+
    1640 }
    \n+
    1641
    \n+
    1642 template<class M>
    \n+
    1643 template<class C>
    \n+
    1644 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(C* graph,
    \n+
    1645 const VertexDescriptor& current)
    \n+
    1646 : graph_(graph), current_(current)
    \n+
    1647 {}
    \n+
    1648
    \n+
    1649
    \n+
    1650 template<class M>
    \n+
    1651 template<class C>
    \n+
    1652 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(const VertexDescriptor& current)
    \n+
    1653 : current_(current)
    \n+
    1654 {}
    \n+
    1655
    \n+
    1656 template<class M>
    \n+
    1657 template<class C>
    \n+
    1658 MatrixGraph<M>::VertexIteratorT<C>::VertexIteratorT(const VertexIteratorT<MutableContainer>& other)
    \n+
    1659 : graph_(other.graph_), current_(other.current_)
    \n+
    1660 {}
    \n+
    1661
    \n+
    1662 template<class M>
    \n+
    1663 template<class C>
    \n+
    1664 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator!=(const VertexIteratorT<MutableContainer>& other) const
    \n+
    1665 {
    \n+
    1666 return current_ != other.current_;
    \n+
    1667 }
    \n+
    1668
    \n+
    1669 template<class M>
    \n+
    1670 template<class C>
    \n+
    1671 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator!=(const VertexIteratorT<ConstContainer>& other) const
    \n+
    1672 {
    \n+
    1673 return current_ != other.current_;
    \n+
    1674 }
    \n+
    1675
    \n+
    1676
    \n+
    1677 template<class M>
    \n+
    1678 template<class C>
    \n+
    1679 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator==(const VertexIteratorT<MutableContainer>& other) const
    \n+
    1680 {
    \n+
    1681 return current_ == other.current_;
    \n+
    1682 }
    \n+
    1683
    \n+
    1684 template<class M>
    \n+
    1685 template<class C>
    \n+
    1686 inline bool MatrixGraph<M>::VertexIteratorT<C>::operator==(const VertexIteratorT<ConstContainer>& other) const
    \n+
    1687 {
    \n+
    1688 return current_ == other.current_;
    \n+
    1689 }
    \n+
    1690
    \n+
    1691 template<class M>
    \n+
    1692 template<class C>
    \n+
    1693 inline typename MatrixGraph<M>::template VertexIteratorT<C>& MatrixGraph<M>::VertexIteratorT<C>::operator++()
    \n+
    1694 {
    \n+
    1695 ++current_;
    \n+
    1696 return *this;
    \n+
    1697 }
    \n+
    1698
    \n+
    1699 template<class M>
    \n+
    1700 template<class C>
    \n+
    1701 inline typename MatrixGraph<M>::template VertexIteratorT<C>::WeightType&
    \n+
    1702 MatrixGraph<M>::VertexIteratorT<C>::weight() const
    \n+
    1703 {
    \n+
    1704 return graph_->matrix()[current_][current_];
    \n+
    1705 }
    \n+
    1706
    \n+
    1707 template<class M>
    \n+
    1708 template<class C>
    \n+
    1709 inline const typename MatrixGraph<M>::VertexDescriptor&
    \n+
    1710 MatrixGraph<M>::VertexIteratorT<C>::operator*() const
    \n+
    1711 {
    \n+
    1712 return current_;
    \n+
    1713 }
    \n+
    1714
    \n+
    1715 template<class M>
    \n+
    1716 template<class C>
    \n+
    1717 inline typename MatrixGraph<M>::template EdgeIteratorT<C>
    \n+
    1718 MatrixGraph<M>::VertexIteratorT<C>::begin() const
    \n+
    1719 {
    \n+
    1720 return graph_->beginEdges(current_);
    \n+
    1721 }
    \n+
    1722
    \n+
    1723 template<class M>
    \n+
    1724 template<class C>
    \n+
    1725 inline typename MatrixGraph<M>::template EdgeIteratorT<C>
    \n+
    1726 MatrixGraph<M>::VertexIteratorT<C>::end() const
    \n+
    1727 {
    \n+
    1728 return graph_->endEdges(current_);
    \n+
    1729 }
    \n+
    1730
    \n+
    1731 template<class M>
    \n+
    1732 inline typename MatrixGraph<M>::template VertexIteratorT<MatrixGraph<M> >
    \n+
    1733 MatrixGraph<M>::begin()
    \n+
    1734 {
    \n+
    1735 return VertexIterator(this,0);
    \n+
    1736 }
    \n+
    1737
    \n+
    1738 template<class M>
    \n+
    1739 inline typename MatrixGraph<M>::template VertexIteratorT<MatrixGraph<M> >
    \n+
    1740 MatrixGraph<M>::end()
    \n+
    1741 {
    \n+
    1742 return VertexIterator(matrix_.N());
    \n+
    1743 }
    \n+
    1744
    \n+
    1745
    \n+
    1746 template<class M>
    \n+
    1747 inline typename MatrixGraph<M>::template VertexIteratorT<const MatrixGraph<M> >
    \n+
    1748 MatrixGraph<M>::begin() const
    \n+
    1749 {
    \n+
    1750 return ConstVertexIterator(this, 0);
    \n+
    1751 }
    \n+
    1752
    \n+
    1753 template<class M>
    \n+
    1754 inline typename MatrixGraph<M>::template VertexIteratorT<const MatrixGraph<M> >
    \n+
    1755 MatrixGraph<M>::end() const
    \n+
    1756 {
    \n+
    1757 return ConstVertexIterator(matrix_.N());
    \n+
    1758 }
    \n+
    1759
    \n+
    1760 template<class M>
    \n+
    1761 inline typename MatrixGraph<M>::template EdgeIteratorT<MatrixGraph<M> >
    \n+
    1762 MatrixGraph<M>::beginEdges(const VertexDescriptor& source)
    \n+
    1763 {
    \n+
    1764 return EdgeIterator(source, matrix_.operator[](source).begin(),
    \n+
    1765 matrix_.operator[](source).end(), start_[source]);
    \n+
    1766 }
    \n+
    1767
    \n+
    1768 template<class M>
    \n+
    1769 inline typename MatrixGraph<M>::template EdgeIteratorT<MatrixGraph<M> >
    \n+
    1770 MatrixGraph<M>::endEdges(const VertexDescriptor& source)
    \n+
    1771 {
    \n+
    1772 return EdgeIterator(matrix_.operator[](source).end());
    \n+
    1773 }
    \n+
    1774
    \n+
    1775
    \n+
    1776 template<class M>
    \n+
    1777 inline typename MatrixGraph<M>::template EdgeIteratorT<const MatrixGraph<M> >
    \n+
    1778 MatrixGraph<M>::beginEdges(const VertexDescriptor& source) const
    \n+
    1779 {
    \n+
    1780 return ConstEdgeIterator(source, matrix_.operator[](source).begin(),
    \n+
    1781 matrix_.operator[](source).end(), start_[source]);
    \n+
    1782 }
    \n+
    1783
    \n+
    1784 template<class M>
    \n+
    1785 inline typename MatrixGraph<M>::template EdgeIteratorT<const MatrixGraph<M> >
    \n+
    1786 MatrixGraph<M>::endEdges(const VertexDescriptor& source) const
    \n+
    1787 {
    \n+
    1788 return ConstEdgeIterator(matrix_.operator[](source).end());
    \n+
    1789 }
    \n+
    1790
    \n+
    1791
    \n+
    1792 template<class G, class T>
    \n+
    1793 SubGraph<G,T>::EdgeIterator::EdgeIterator(const VertexDescriptor& source,
    \n+
    1794 const EdgeDescriptor& edge)
    \n+
    1795 : source_(source), edge_(edge)
    \n+
    1796 {}
    \n+
    1797
    \n+
    1798
    \n+
    1799 template<class G, class T>
    \n+
    1800 SubGraph<G,T>::EdgeIterator::EdgeIterator(const EdgeDescriptor& edge)
    \n+
    1801 : edge_(edge)
    \n+
    1802 {}
    \n+
    1803
    \n+
    1804 template<class G, class T>
    \n+
    1805 typename SubGraph<G,T>::EdgeIndexMap SubGraph<G,T>::getEdgeIndexMap()
    \n+
    1806 {
    \n+
    1807 return EdgeIndexMap(edges_);
    \n+
    1808 }
    \n+
    1809
    \n+
    1810 template<class G, class T>
    \n+
    1811 inline bool SubGraph<G,T>::EdgeIterator::equals(const EdgeIterator & other) const
    \n+
    1812 {
    \n+
    1813 return other.edge_==edge_;
    \n+
    1814 }
    \n+
    1815
    \n+
    1816 template<class G, class T>
    \n+
    1817 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::increment()
    \n+
    1818 {
    \n+
    1819 ++edge_;
    \n+
    1820 return *this;
    \n+
    1821 }
    \n+
    1822
    \n+
    1823 template<class G, class T>
    \n+
    1824 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::decrement()
    \n+
    1825 {
    \n+
    1826 --edge_;
    \n+
    1827 return *this;
    \n+
    1828 }
    \n+
    1829
    \n+
    1830 template<class G, class T>
    \n+
    1831 inline typename SubGraph<G,T>::EdgeIterator& SubGraph<G,T>::EdgeIterator::advance(std::ptrdiff_t n)
    \n+
    1832 {
    \n+
    1833 edge_+=n;
    \n+
    1834 return *this;
    \n+
    1835 }
    \n+
    1836 template<class G, class T>
    \n+
    1837 inline const typename G::VertexDescriptor& SubGraph<G,T>::EdgeIterator::source() const
    \n+
    1838 {
    \n+
    1839 return source_;
    \n+
    1840 }
    \n+
    1841
    \n+
    1842 template<class G, class T>
    \n+
    1843 inline const typename G::VertexDescriptor& SubGraph<G,T>::EdgeIterator::target() const
    \n+
    1844 {
    \n+
    1845 return *edge_;
    \n+
    1846 }
    \n+
    1847
    \n+
    1848
    \n+
    1849 template<class G, class T>
    \n+
    1850 inline const typename SubGraph<G,T>::EdgeDescriptor& SubGraph<G,T>::EdgeIterator::dereference() const
    \n+
    1851 {
    \n+
    1852 return edge_;
    \n+
    1853 }
    \n+
    1854
    \n+
    1855 template<class G, class T>
    \n+
    1856 inline std::ptrdiff_t SubGraph<G,T>::EdgeIterator::distanceTo(const EdgeIterator & other) const
    \n+
    1857 {
    \n+
    1858 return other.edge_-edge_;
    \n+
    1859 }
    \n+
    1860
    \n+
    1861 template<class G, class T>
    \n+
    1862 SubGraph<G,T>::VertexIterator::VertexIterator(const SubGraph<G,T>* graph,
    \n+
    1863 const VertexDescriptor& current,
    \n+
    1864 const VertexDescriptor& end)
    \n+
    1865 : graph_(graph), current_(current), end_(end)
    \n+
    1866 {
    \n+
    1867 // Skip excluded vertices
    \n+
    1868 typedef typename T::const_iterator Iterator;
    \n+
    1869
    \n+
    1870 for(Iterator vertex = graph_->excluded_.begin();
    \n+
    1871 current_ != end_ && *vertex;
    \n+
    1872 ++vertex)
    \n+
    1873 ++current_;
    \n+
    1874 assert(current_ == end_ || !graph_->excluded_[current_]);
    \n+
    1875 }
    \n+
    1876
    \n+
    1877 template<class G, class T>
    \n+
    1878 SubGraph<G,T>::VertexIterator::VertexIterator(const VertexDescriptor& current)
    \n+
    1879 : current_(current)
    \n+
    1880 {}
    \n+
    1881
    \n+
    1882 template<class G, class T>
    \n+
    1883 inline typename SubGraph<G,T>::VertexIterator& SubGraph<G,T>::VertexIterator::increment()
    \n+
    1884 {
    \n+
    1885 ++current_;
    \n+
    1886 //Skip excluded vertices
    \n+
    1887 while(current_ != end_ && graph_->excluded_[current_])
    \n+
    1888 ++current_;
    \n+
    1889
    \n+
    1890 assert(current_ == end_ || !graph_->excluded_[current_]);
    \n+
    1891 return *this;
    \n+
    1892 }
    \n+
    1893
    \n+
    1894 template<class G, class T>
    \n+
    1895 inline bool SubGraph<G,T>::VertexIterator::equals(const VertexIterator & other) const
    \n+
    1896 {
    \n+
    1897 return current_==other.current_;
    \n+
    1898 }
    \n+
    1899
    \n+
    1900 template<class G, class T>
    \n+
    1901 inline const typename G::VertexDescriptor& SubGraph<G,T>::VertexIterator::dereference() const
    \n+
    1902 {
    \n+
    1903 return current_;
    \n+
    1904 }
    \n+
    1905
    \n+
    1906 template<class G, class T>
    \n+
    1907 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::VertexIterator::begin() const
    \n+
    1908 {
    \n+
    1909 return graph_->beginEdges(current_);
    \n+
    1910 }
    \n+
    1911
    \n+
    1912 template<class G, class T>
    \n+
    1913 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::VertexIterator::end() const
    \n+
    1914 {
    \n+
    1915 return graph_->endEdges(current_);
    \n+
    1916 }
    \n+
    1917
    \n+
    1918 template<class G, class T>
    \n+
    1919 inline typename SubGraph<G,T>::VertexIterator SubGraph<G,T>::begin() const
    \n+
    1920 {
    \n+
    1921 return VertexIterator(this, 0, endVertex_);
    \n+
    1922 }
    \n+
    1923
    \n+
    1924
    \n+
    1925 template<class G, class T>
    \n+
    1926 inline typename SubGraph<G,T>::VertexIterator SubGraph<G,T>::end() const
    \n+
    1927 {
    \n+
    1928 return VertexIterator(endVertex_);
    \n+
    1929 }
    \n+
    1930
    \n+
    1931
    \n+
    1932 template<class G, class T>
    \n+
    1933 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::beginEdges(const VertexDescriptor& source) const
    \n+
    1934 {
    \n+
    1935 return EdgeIterator(source, edges_+start_[source]);
    \n+
    1936 }
    \n+
    1937
    \n+
    1938 template<class G, class T>
    \n+
    1939 inline typename SubGraph<G,T>::EdgeIterator SubGraph<G,T>::endEdges(const VertexDescriptor& source) const
    \n+
    1940 {
    \n+
    1941 return EdgeIterator(edges_+end_[source]);
    \n+
    1942 }
    \n+
    1943
    \n+
    1944 template<class G, class T>
    \n+
    1945 std::size_t SubGraph<G,T>::noVertices() const
    \n+
    1946 {
    \n+
    1947 return noVertices_;
    \n+
    1948 }
    \n+
    1949
    \n+
    1950 template<class G, class T>
    \n+
    1951 inline typename SubGraph<G,T>::VertexDescriptor SubGraph<G,T>::maxVertex() const
    \n+
    1952 {
    \n+
    1953 return maxVertex_;
    \n+
    1954 }
    \n+
    1955
    \n+
    1956 template<class G, class T>
    \n+
    1957 inline std::size_t SubGraph<G,T>::noEdges() const
    \n+
    1958 {
    \n+
    1959 return noEdges_;
    \n+
    1960 }
    \n+
    1961
    \n+
    1962 template<class G, class T>
    \n+
    1963 inline typename SubGraph<G,T>::EdgeDescriptor SubGraph<G,T>::findEdge(const VertexDescriptor& source,
    \n+
    1964 const VertexDescriptor& target) const
    \n+
    1965 {
    \n+
    1966 const EdgeDescriptor edge = std::lower_bound(edges_+start_[source], edges_+end_[source], target);
    \n+
    1967 if(edge==edges_+end_[source] || *edge!=target)
    \n+
    1968 return std::numeric_limits<EdgeDescriptor>::max();
    \n+
    1969
    \n+
    1970 return edge;
    \n+
    1971 }
    \n+
    1972
    \n+
    1973 template<class G, class T>
    \n+
    1974 SubGraph<G,T>::~SubGraph()
    \n+
    1975 {
    \n+
    1976 delete[] edges_;
    \n+
    1977 delete[] end_;
    \n+
    1978 delete[] start_;
    \n+
    1979 }
    \n+
    1980
    \n+
    1981 template<class G, class T>
    \n+
    1982 SubGraph<G,T>::SubGraph(const G& graph, const T& excluded)
    \n+
    1983 : excluded_(excluded), noVertices_(0), endVertex_(0), maxVertex_(graph.maxVertex())
    \n+
    1984 {
    \n+
    1985 start_ = new std::ptrdiff_t[graph.noVertices()];
    \n+
    1986 end_ = new std::ptrdiff_t[graph.noVertices()];
    \n+
    1987 edges_ = new VertexDescriptor[graph.noEdges()];
    \n+
    1988
    \n+
    1989 VertexDescriptor* edge=edges_;
    \n+
    1990
    \n+
    1991 // Cater for the case that there are no vertices.
    \n+
    1992 // Otherwise endVertex_ will get 1 below.
    \n+
    1993 if ( graph.noVertices() == 0)
    \n+
    1994 return;
    \n+
    1995
    \n+
    1996 typedef typename Graph::ConstVertexIterator Iterator;
    \n+
    1997 Iterator endVertex=graph.end();
    \n+
    1998
    \n+
    1999 for(Iterator vertex = graph.begin(); vertex != endVertex; ++vertex)
    \n+
    2000 if(excluded_[*vertex])
    \n+
    2001 start_[*vertex]=end_[*vertex]=-1;
    \n+
    2002 else{
    \n+
    2003 ++noVertices_;
    \n+
    2004 endVertex_ = std::max(*vertex, endVertex_);
    \n+
    2005
    \n+
    2006 start_[*vertex] = edge-edges_;
    \n+
    2007
    \n+
    2008 auto endEdge = vertex.end();
    \n+
    2009
    \n+
    2010 for(auto iter=vertex.begin(); iter!= endEdge; ++iter)
    \n+
    2011 if(!excluded[iter.target()]) {
    \n+
    2012 *edge = iter.target();
    \n+
    2013 ++edge;
    \n+
    2014 }
    \n+
    2015
    \n+
    2016 end_[*vertex] = edge - edges_;
    \n+
    2017
    \n+
    2018 // Sort the edges
    \n+
    2019 std::sort(edges_+start_[*vertex], edge);
    \n+
    2020 }
    \n+
    2021 noEdges_ = edge-edges_;
    \n+
    2022 ++endVertex_;
    \n+
    2023 }
    \n+
    2024
    \n+
    2025 template<class G, class V, class VM>
    \n+
    2026 inline std::size_t VertexPropertiesGraph<G,V,VM>::noEdges() const
    \n+
    2027 {
    \n+
    2028 return graph_.noEdges();
    \n+
    2029 }
    \n+
    2030
    \n+
    2031 template<class G, class V, class VM>
    \n+
    2032 inline typename VertexPropertiesGraph<G,V,VM>::EdgeIterator
    \n+
    2033 VertexPropertiesGraph<G,V,VM>::beginEdges(const VertexDescriptor& source)
    \n+
    2034 {
    \n+
    2035 return graph_.beginEdges(source);
    \n+
    2036 }
    \n+
    2037
    \n+
    2038 template<class G, class V, class VM>
    \n+
    2039 inline typename VertexPropertiesGraph<G,V,VM>::EdgeIterator
    \n+
    2040 VertexPropertiesGraph<G,V,VM>::endEdges(const VertexDescriptor& source)
    \n+
    2041 {
    \n+
    2042 return graph_.endEdges(source);
    \n+
    2043 }
    \n+
    2044
    \n+
    2045 template<class G, class V, class VM>
    \n+
    2046 typename VertexPropertiesGraph<G,V,VM>::ConstEdgeIterator
    \n+
    2047 inline VertexPropertiesGraph<G,V,VM>::beginEdges(const VertexDescriptor& source) const
    \n+
    2048 {
    \n+
    2049 return graph_.beginEdges(source);
    \n+
    2050 }
    \n+
    2051
    \n+
    2052 template<class G, class V, class VM>
    \n+
    2053 typename VertexPropertiesGraph<G,V,VM>::ConstEdgeIterator
    \n+
    2054 VertexPropertiesGraph<G,V,VM>::endEdges(const VertexDescriptor& source) const
    \n+
    2055 {
    \n+
    2056 return graph_.endEdges(source);
    \n+
    2057 }
    \n+
    2058
    \n+
    2059 template<class G, class V, class VM>
    \n+
    2060 template<class C>
    \n+
    2061 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n+
    2062 ::VertexIteratorT(const Father& iter,
    \n+
    2063 C* graph)
    \n+
    2064 : Father(iter), graph_(graph)
    \n+
    2065 {}
    \n+
    2066
    \n+
    2067 template<class G, class V, class VM>
    \n+
    2068 template<class C>
    \n+
    2069 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n+
    2070 ::VertexIteratorT(const Father& iter)
    \n+
    2071 : Father(iter)
    \n+
    2072 {}
    \n+
    2073
    \n+
    2074 template<class G, class V, class VM>
    \n+
    2075 template<class C>
    \n+
    2076 template<class C1>
    \n+
    2077 VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>
    \n+
    2078 ::VertexIteratorT(const VertexIteratorT<C1>& other)
    \n+
    2079 : Father(other), graph_(other.graph_)
    \n+
    2080 {}
    \n+
    2081
    \n+
    2082 template<class G, class V, class VM>
    \n+
    2083 template<class C>
    \n+
    2084 typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n+
    2085 V&, const V&>::type
    \n+
    2086 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::properties() const
    \n+
    2087 {
    \n+
    2088 return graph_->getVertexProperties(Father::operator*());
    \n+
    2089 }
    \n+
    2090
    \n+
    2091 template<class G, class V, class VM>
    \n+
    2092 template<class C>
    \n+
    2093 typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    2094 C>::value,
    \n+
    2095 typename G::EdgeIterator,
    \n+
    2096 typename G::ConstEdgeIterator>::type
    \n+
    2097 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::begin() const
    \n+
    2098 {
    \n+
    2099 return graph_->beginEdges(Father::operator*());
    \n+
    2100 }
    \n+
    2101
    \n+
    2102 template<class G, class V, class VM>
    \n+
    2103 template<class C>
    \n+
    2104 typename std::conditional<std::is_same<typename std::remove_const<C>::type,
    \n+
    2105 C>::value,
    \n+
    2106 typename G::EdgeIterator,
    \n+
    2107 typename G::ConstEdgeIterator>::type
    \n+
    2108 inline VertexPropertiesGraph<G,V,VM>::VertexIteratorT<C>::end() const
    \n+
    2109 {
    \n+
    2110 return graph_->endEdges(Father::operator*());
    \n+
    2111 }
    \n+
    2112
    \n+
    2113 template<class G, class V, class VM>
    \n+
    2114 inline typename VertexPropertiesGraph<G,V,VM>::VertexIterator VertexPropertiesGraph<G,V,VM>::begin()
    \n+
    2115 {
    \n+
    2116 return VertexIterator(graph_.begin(), this);
    \n+
    2117 }
    \n+
    2118
    \n+
    2119 template<class G, class V, class VM>
    \n+
    2120 inline typename VertexPropertiesGraph<G,V,VM>::VertexIterator VertexPropertiesGraph<G,V,VM>::end()
    \n+
    2121 {
    \n+
    2122 return VertexIterator(graph_.end());
    \n+
    2123 }
    \n+
    2124
    \n+
    2125
    \n+
    2126 template<class G, class V, class VM>
    \n+
    2127 inline typename VertexPropertiesGraph<G,V,VM>::ConstVertexIterator VertexPropertiesGraph<G,V,VM>::begin() const
    \n+
    2128 {
    \n+
    2129 return ConstVertexIterator(graph_.begin(), this);
    \n+
    2130 }
    \n+
    2131
    \n+
    2132 template<class G, class V, class VM>
    \n+
    2133 inline typename VertexPropertiesGraph<G,V,VM>::ConstVertexIterator VertexPropertiesGraph<G,V,VM>::end() const
    \n+
    2134 {
    \n+
    2135 return ConstVertexIterator(graph_.end());
    \n+
    2136 }
    \n+
    2137
    \n+
    2138 template<class G, class V, class VM>
    \n+
    2139 inline V& VertexPropertiesGraph<G,V,VM>::getVertexProperties(const VertexDescriptor& vertex)
    \n+
    2140 {
    \n+
    2141 return vertexProperties_[vmap_[vertex]];
    \n+
    2142 }
    \n+
    2143
    \n+
    2144 template<class G, class V, class VM>
    \n+
    2145 inline const V& VertexPropertiesGraph<G,V,VM>::getVertexProperties(const VertexDescriptor& vertex) const
    \n+
    2146 {
    \n+
    2147 return vertexProperties_[vmap_[vertex]];
    \n+
    2148 }
    \n+
    2149
    \n+
    2150 template<class G, class V, class VM>
    \n+
    2151 inline const G& VertexPropertiesGraph<G,V,VM>::graph() const
    \n+
    2152 {
    \n+
    2153 return graph_;
    \n+
    2154 }
    \n+
    2155
    \n+
    2156 template<class G, class V, class VM>
    \n+
    2157 inline std::size_t VertexPropertiesGraph<G,V,VM>::noVertices() const
    \n+
    2158 {
    \n+
    2159 return graph_.noVertices();
    \n+
    2160 }
    \n+
    2161
    \n+
    2162
    \n+
    2163 template<class G, class V, class VM>
    \n+
    2164 inline typename VertexPropertiesGraph<G,V,VM>::VertexDescriptor VertexPropertiesGraph<G,V,VM>::maxVertex() const
    \n+
    2165 {
    \n+
    2166 return graph_.maxVertex();
    \n+
    2167 }
    \n+
    2168
    \n+
    2169 template<class G, class V, class VM>
    \n+
    2170 VertexPropertiesGraph<G,V,VM>::VertexPropertiesGraph(Graph& graph, const VM vmap)
    \n+
    2171 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex()+1], V())
    \n+
    2172 {}
    \n+
    2173
    \n+
    2174 template<class G, class V, class E, class VM, class EM>
    \n+
    2175 template<class C>
    \n+
    2176 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const Father& iter,
    \n+
    2177 C* graph)
    \n+
    2178 : Father(iter), graph_(graph)
    \n+
    2179 {}
    \n+
    2180
    \n+
    2181 template<class G, class V, class E, class VM, class EM>
    \n+
    2182 template<class C>
    \n+
    2183 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const Father& iter)
    \n+
    2184 : Father(iter)
    \n+
    2185 {}
    \n+
    2186
    \n+
    2187 template<class G, class V, class E, class VM, class EM>
    \n+
    2188 template<class C>
    \n+
    2189 template<class C1>
    \n+
    2190 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::EdgeIteratorT(const EdgeIteratorT<C1>& other)
    \n+
    2191 : Father(other), graph_(other.graph_)
    \n+
    2192 {}
    \n+
    2193
    \n+
    2194
    \n+
    2195 template<class G, class V, class E, class VM, class EM>
    \n+
    2196 inline std::size_t PropertiesGraph<G,V,E,VM,EM>::noEdges() const
    \n+
    2197 {
    \n+
    2198 return graph_.noEdges();
    \n+
    2199 }
    \n+
    2200
    \n+
    2201 template<class G, class V, class E, class VM, class EM>
    \n+
    2202 template<class C>
    \n+
    2203 inline typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,E&,const E&>::type
    \n+
    2204 PropertiesGraph<G,V,E,VM,EM>::EdgeIteratorT<C>::properties() const
    \n+
    2205 {
    \n+
    2206 return graph_->getEdgeProperties(Father::operator*());
    \n+
    2207 }
    \n+
    2208
    \n+
    2209 template<class G, class V, class E, class VM, class EM>
    \n+
    2210 inline typename PropertiesGraph<G,V,E,VM,EM>::EdgeIterator
    \n+
    2211 PropertiesGraph<G,V,E,VM,EM>::beginEdges(const VertexDescriptor& source)
    \n+
    2212 {
    \n+
    2213 return EdgeIterator(graph_.beginEdges(source), this);
    \n+
    2214 }
    \n+
    2215
    \n+
    2216 template<class G, class V, class E, class VM, class EM>
    \n+
    2217 inline typename PropertiesGraph<G,V,E,VM,EM>::EdgeIterator
    \n+
    2218 PropertiesGraph<G,V,E,VM,EM>::endEdges(const VertexDescriptor& source)
    \n+
    2219 {
    \n+
    2220 return EdgeIterator(graph_.endEdges(source));
    \n+
    2221 }
    \n+
    2222
    \n+
    2223 template<class G, class V, class E, class VM, class EM>
    \n+
    2224 typename PropertiesGraph<G,V,E,VM,EM>::ConstEdgeIterator
    \n+
    2225 inline PropertiesGraph<G,V,E,VM,EM>::beginEdges(const VertexDescriptor& source) const
    \n+
    2226 {
    \n+
    2227 return ConstEdgeIterator(graph_.beginEdges(source), this);
    \n+
    2228 }
    \n+
    2229
    \n+
    2230 template<class G, class V, class E, class VM, class EM>
    \n+
    2231 typename PropertiesGraph<G,V,E,VM,EM>::ConstEdgeIterator
    \n+
    2232 PropertiesGraph<G,V,E,VM,EM>::endEdges(const VertexDescriptor& source) const
    \n+
    2233 {
    \n+
    2234 return ConstEdgeIterator(graph_.endEdges(source));
    \n+
    2235 }
    \n+
    2236
    \n+
    2237 template<class G, class V, class E, class VM, class EM>
    \n+
    2238 template<class C>
    \n+
    2239 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n+
    2240 ::VertexIteratorT(const Father& iter,
    \n+
    2241 C* graph)
    \n+
    2242 : Father(iter), graph_(graph)
    \n+
    2243 {}
    \n+
    2244
    \n+
    2245 template<class G, class V, class E, class VM, class EM>
    \n+
    2246 template<class C>
    \n+
    2247 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n+
    2248 ::VertexIteratorT(const Father& iter)
    \n+
    2249 : Father(iter)
    \n+
    2250 {}
    \n+
    2251
    \n+
    2252 template<class G, class V, class E, class VM, class EM>
    \n+
    2253 template<class C>
    \n+
    2254 template<class C1>
    \n+
    2255 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>
    \n+
    2256 ::VertexIteratorT(const VertexIteratorT<C1>& other)
    \n+
    2257 : Father(other), graph_(other.graph_)
    \n+
    2258 {}
    \n+
    2259
    \n+
    2260 template<class G, class V, class E, class VM, class EM>
    \n+
    2261 template<class C>
    \n+
    2262 inline typename std::conditional<std::is_same<C,typename std::remove_const<C>::type>::value,
    \n+
    2263 V&, const V&>::type
    \n+
    2264 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::properties() const
    \n+
    2265 {
    \n+
    2266 return graph_->getVertexProperties(Father::operator*());
    \n+
    2267 }
    \n+
    2268
    \n+
    2269 template<class G, class V, class E, class VM, class EM>
    \n+
    2270 template<class C>
    \n+
    2271 inline typename PropertiesGraph<G,V,E,VM,EM>::template EdgeIteratorT<C>
    \n+
    2272 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::begin() const
    \n+
    2273 {
    \n+
    2274 return graph_->beginEdges(Father::operator*());
    \n+
    2275 }
    \n+
    2276
    \n+
    2277 template<class G, class V, class E, class VM, class EM>
    \n+
    2278 template<class C>
    \n+
    2279 inline typename PropertiesGraph<G,V,E,VM,EM>::template EdgeIteratorT<C>
    \n+
    2280 PropertiesGraph<G,V,E,VM,EM>::VertexIteratorT<C>::end() const
    \n+
    2281 {
    \n+
    2282 return graph_->endEdges(Father::operator*());
    \n+
    2283 }
    \n+
    2284
    \n+
    2285 template<class G, class V, class E, class VM, class EM>
    \n+
    2286 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexIterator PropertiesGraph<G,V,E,VM,EM>::begin()
    \n+
    2287 {
    \n+
    2288 return VertexIterator(graph_.begin(), this);
    \n+
    2289 }
    \n+
    2290
    \n+
    2291 template<class G, class V, class E, class VM, class EM>
    \n+
    2292 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexIterator PropertiesGraph<G,V,E,VM,EM>::end()
    \n+
    2293 {
    \n+
    2294 return VertexIterator(graph_.end());
    \n+
    2295 }
    \n+
    2296
    \n+
    2297
    \n+
    2298 template<class G, class V, class E, class VM, class EM>
    \n+
    2299 inline typename PropertiesGraph<G,V,E,VM,EM>::ConstVertexIterator PropertiesGraph<G,V,E,VM,EM>::begin() const
    \n+
    2300 {
    \n+
    2301 return ConstVertexIterator(graph_.begin(), this);
    \n+
    2302 }
    \n+
    2303
    \n+
    2304 template<class G, class V, class E, class VM, class EM>
    \n+
    2305 inline typename PropertiesGraph<G,V,E,VM,EM>::ConstVertexIterator PropertiesGraph<G,V,E,VM,EM>::end() const
    \n+
    2306 {
    \n+
    2307 return ConstVertexIterator(graph_.end());
    \n+
    2308 }
    \n+
    2309
    \n+
    2310 template<class G, class V, class E, class VM, class EM>
    \n+
    2311 inline V& PropertiesGraph<G,V,E,VM,EM>::getVertexProperties(const VertexDescriptor& vertex)
    \n+
    2312 {
    \n+
    2313 return vertexProperties_[vmap_[vertex]];
    \n+
    2314 }
    \n+
    2315
    \n+
    2316 template<class G, class V, class E, class VM, class EM>
    \n+
    2317 inline const V& PropertiesGraph<G,V,E,VM,EM>::getVertexProperties(const VertexDescriptor& vertex) const
    \n+
    2318 {
    \n+
    2319 return vertexProperties_[vmap_[vertex]];
    \n+
    2320 }
    \n+
    2321
    \n+
    2322 template<class G, class V, class E, class VM, class EM>
    \n+
    2323 inline E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const EdgeDescriptor& edge)
    \n+
    2324 {
    \n+
    2325 return edgeProperties_[emap_[edge]];
    \n+
    2326 }
    \n+
    2327
    \n+
    2328 template<class G, class V, class E, class VM, class EM>
    \n+
    2329 inline const E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const EdgeDescriptor& edge) const
    \n+
    2330 {
    \n+
    2331 return edgeProperties_[emap_[edge]];
    \n+
    2332 }
    \n+
    2333
    \n+
    2334 template<class G, class V, class E, class VM, class EM>
    \n+
    2335 inline E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const VertexDescriptor& source,
    \n+
    2336 const VertexDescriptor& target)
    \n+
    2337 {
    \n+
    2338 return getEdgeProperties(graph_.findEdge(source,target));
    \n+
    2339 }
    \n+
    2340
    \n+
    2341 template<class G, class V, class E, class VM, class EM>
    \n+
    2342 inline const E& PropertiesGraph<G,V,E,VM,EM>::getEdgeProperties(const VertexDescriptor& source,
    \n+
    2343 const VertexDescriptor& target) const
    \n+
    2344 {
    \n+
    2345 return getEdgeProperties(graph_.findEdge(source,target));
    \n+
    2346 }
    \n+
    2347
    \n+
    2348 template<class G, class V, class E, class VM, class EM>
    \n+
    2349 inline const G& PropertiesGraph<G,V,E,VM,EM>::graph() const
    \n+
    2350 {
    \n+
    2351 return graph_;
    \n+
    2352 }
    \n+
    2353
    \n+
    2354 template<class G, class V, class E, class VM, class EM>
    \n+
    2355 inline std::size_t PropertiesGraph<G,V,E,VM,EM>::noVertices() const
    \n+
    2356 {
    \n+
    2357 return graph_.noVertices();
    \n+
    2358 }
    \n+
    2359
    \n+
    2360
    \n+
    2361 template<class G, class V, class E, class VM, class EM>
    \n+
    2362 inline typename PropertiesGraph<G,V,E,VM,EM>::VertexDescriptor PropertiesGraph<G,V,E,VM,EM>::maxVertex() const
    \n+
    2363 {
    \n+
    2364 return graph_.maxVertex();
    \n+
    2365 }
    \n+
    2366
    \n+
    2367 template<class G, class V, class E, class VM, class EM>
    \n+
    2368 PropertiesGraph<G,V,E,VM,EM>::PropertiesGraph(Graph& graph, const VM& vmap, const EM& emap)
    \n+
    2369 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex()+1], V()),
    \n+
    2370 emap_(emap), edgeProperties_(graph_.noEdges(), E())
    \n+
    2371 {}
    \n+
    2372
    \n+
    2373 template<class G, class V>
    \n+
    2374 inline int visitNeighbours(const G& graph, const typename G::VertexDescriptor& vertex,
    \n+
    2375 V& visitor)
    \n+
    2376 {
    \n+
    2377 typedef typename G::ConstEdgeIterator iterator;
    \n+
    2378 const iterator end = graph.endEdges(vertex);
    \n+
    2379 int noNeighbours=0;
    \n+
    2380 for(iterator edge = graph.beginEdges(vertex); edge != end; ++edge, ++noNeighbours)
    \n+
    2381 visitor(edge);
    \n+
    2382 return noNeighbours;
    \n+
    2383 }
    \n+
    2384
    \n+
    2385#endif // DOXYGEN
    \n+
    2386
    \n+
    2388 }
    \n+
    2389}
    \n+
    2390#endif
    \n+\n+
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    Parameters needed to check whether a node depends on another.
    Definition: parameters.hh:31
    \n-
    Parameters needed for the aggregation process.
    Definition: parameters.hh:84
    \n-
    Parameters for the complete coarsening process.
    Definition: parameters.hh:258
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n+
    MatrixGraph(Matrix &matrix)
    Constructor.
    \n+
    VertexIterator end()
    Get an iterator over the vertices.
    \n+
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n+
    M Matrix
    The type of the matrix we are a graph for.
    Definition: graph.hh:56
    \n+
    ConstVertexIterator begin() const
    Get an iterator over the vertices.
    \n+
    VertexIteratorT< const MatrixGraph< Matrix > > ConstVertexIterator
    The constant vertex iterator type.
    Definition: graph.hh:308
    \n+
    ~MatrixGraph()
    Destructor.
    \n+
    std::ptrdiff_t EdgeDescriptor
    The edge descriptor.
    Definition: graph.hh:80
    \n+
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n+
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n+
    const Matrix & matrix() const
    Get the underlying matrix.
    \n+
    @ mutableMatrix
    Definition: graph.hh:86
    \n+
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n+
    ConstVertexIterator end() const
    Get an iterator over the vertices.
    \n+
    EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:298
    \n+
    EdgeIterator beginEdges(const VertexDescriptor &source)
    Get an iterator over the edges starting at a vertex.
    \n+
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n+
    EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor &target) const
    Find the descriptor of an edge.
    \n+
    M::block_type Weight
    The type of the weights.
    Definition: graph.hh:66
    \n+
    std::remove_const< M >::type MutableMatrix
    The mutable type of the matrix we are a graph for.
    Definition: graph.hh:61
    \n+
    EdgeIteratorT< MatrixGraph< Matrix > > EdgeIterator
    The mutable edge iterator type.
    Definition: graph.hh:303
    \n+
    VertexIteratorT< MatrixGraph< Matrix > > VertexIterator
    The mutable vertex iterator type.
    Definition: graph.hh:313
    \n+
    EdgeIterator endEdges(const VertexDescriptor &source)
    Get an iterator over the edges starting at a vertex.
    \n+
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n+
    Matrix & matrix()
    Get the underlying matrix.
    \n+
    VertexIterator begin()
    Get an iterator over the vertices.
    \n+
    Iterator over all edges starting from a vertex.
    Definition: graph.hh:95
    \n+
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type WeightType
    Definition: graph.hh:156
    \n+
    EdgeIteratorT(const VertexDescriptor &source, const ColIterator &block, const ColIterator &end, const EdgeDescriptor &edge)
    Constructor.
    \n+
    @ isMutable
    whether C is mutable.
    Definition: graph.hh:112
    \n+
    VertexDescriptor target() const
    The index of the target vertex of the current edge.
    \n+
    EdgeIteratorT< C > & operator++()
    preincrement operator.
    \n+
    bool operator!=(const EdgeIteratorT< const typename std::remove_const< C >::type > &other) const
    Inequality operator.
    \n+
    bool operator==(const EdgeIteratorT< const typename std::remove_const< C >::type > &other) const
    Equality operator.
    \n+
    EdgeIteratorT(const EdgeIteratorT< C1 > &other)
    Copy Constructor.
    \n+
    bool operator!=(const EdgeIteratorT< typename std::remove_const< C >::type > &other) const
    Inequality operator.
    \n+
    WeightType & weight() const
    Access the edge weight.
    \n+
    VertexDescriptor source() const
    The index of the source vertex of the current edge.
    \n+
    std::conditional< isMutable &&C::mutableMatrix, typenameMatrix::row_type::Iterator, typenameMatrix::row_type::ConstIterator >::type ColIterator
    The column iterator of the matrix we use.
    Definition: graph.hh:120
    \n+
    const std::remove_const< C >::type ConstContainer
    The constant type of the container type.
    Definition: graph.hh:105
    \n+
    bool operator==(const EdgeIteratorT< typename std::remove_const< C >::type > &other) const
    Equality operator.
    \n+
    EdgeIteratorT(const ColIterator &block)
    Constructor for the end iterator.
    \n+
    std::conditional< isMutable &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type Weight
    The matrix block type we use as weights.
    Definition: graph.hh:127
    \n+
    const EdgeDescriptor & operator*() const
    Get the edge descriptor.
    \n+
    const EdgeDescriptor * operator->() const
    Get the edge descriptor.
    \n+
    std::remove_const< C >::type MutableContainer
    The mutable type of the container type.
    Definition: graph.hh:101
    \n+
    The vertex iterator type of the graph.
    Definition: graph.hh:209
    \n+
    EdgeIteratorT< C > begin() const
    Get an iterator over all edges starting at the current vertex.
    \n+
    const VertexDescriptor & operator*() const
    Get the descriptor of the current vertex.
    \n+
    WeightType & weight() const
    Access the weight of the vertex.
    \n+
    VertexIteratorT(C *graph, const VertexDescriptor &current)
    Constructor.
    \n+
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::type WeightType
    Definition: graph.hh:266
    \n+
    VertexIteratorT(const VertexIteratorT< MutableContainer > &other)
    \n+
    std::remove_const< C >::type MutableContainer
    The mutable type of the container type.
    Definition: graph.hh:214
    \n+
    bool operator!=(const VertexIteratorT< MutableContainer > &other) const
    Inequality operator.
    \n+
    @ isMutable
    whether C is mutable.
    Definition: graph.hh:225
    \n+
    bool operator==(const VertexIteratorT< MutableContainer > &other) const
    Equality operator.
    \n+
    const std::remove_const< C >::type ConstContainer
    The constant type of the container type.
    Definition: graph.hh:218
    \n+
    VertexIteratorT< C > & operator++()
    Move to the next vertex.
    \n+
    EdgeIteratorT< C > end() const
    Get an iterator over all edges starting at the current vertex.
    \n+
    bool operator==(const VertexIteratorT< ConstContainer > &other) const
    Equality operator.
    \n+
    bool operator!=(const VertexIteratorT< ConstContainer > &other) const
    Inequality operator.
    \n+
    VertexIteratorT(const VertexDescriptor &current)
    Constructor for the end iterator.
    \n+
    A subgraph of a graph.
    Definition: graph.hh:443
    \n+
    EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor &target) const
    Find the descriptor of an edge.
    \n+
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n+
    EdgeIndexMap getEdgeIndexMap()
    Get an edge index map for the graph.
    \n+
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n+
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n+
    ConstVertexIterator end() const
    Get an iterator over the vertices.
    \n+
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get an iterator over the edges starting at a vertex.
    \n+
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n+
    T Excluded
    Random access container providing information about which vertices are excluded.
    Definition: graph.hh:454
    \n+
    ~SubGraph()
    Destructor.
    \n+
    EdgeIterator ConstEdgeIterator
    The constant edge iterator type.
    Definition: graph.hh:618
    \n+
    G Graph
    The type of the graph we are a sub graph for.
    Definition: graph.hh:448
    \n+
    VertexIterator ConstVertexIterator
    The constant vertex iterator type.
    Definition: graph.hh:623
    \n+
    SubGraph(const Graph &graph, const T &excluded)
    Constructor.
    \n+
    ConstVertexIterator begin() const
    Get an iterator over the vertices.
    \n+
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:459
    \n+
    VertexDescriptor * EdgeDescriptor
    Definition: graph.hh:461
    \n+
    An index map for mapping the edges to indices.
    Definition: graph.hh:470
    \n+
    EdgeIndexMap(const EdgeIndexMap &emap)
    Protect copy construction.
    Definition: graph.hh:479
    \n+
    ReadablePropertyMapTag Category
    Definition: graph.hh:472
    \n+
    EdgeIndexMap(const EdgeDescriptor &firstEdge)
    Definition: graph.hh:474
    \n+
    std::size_t operator[](const EdgeDescriptor &edge) const
    Definition: graph.hh:483
    \n+
    The edge iterator of the graph.
    Definition: graph.hh:505
    \n+
    const EdgeDescriptor & dereference() const
    The descriptor of the current edge.
    \n+
    EdgeIterator(const EdgeDescriptor &edge)
    Constructor for the end iterator.
    \n+
    bool equals(const EdgeIterator &other) const
    Equality operator.
    \n+
    EdgeIterator & advance(std::ptrdiff_t n)
    \n+
    EdgeIterator & increment()
    Preincrement operator.
    \n+
    const VertexDescriptor & target() const
    The index of the target vertex of the current edge.
    \n+
    const VertexDescriptor & source() const
    The index of the source vertex of the current edge.
    \n+
    EdgeIterator & decrement()
    Preincrement operator.
    \n+
    std::ptrdiff_t distanceTo(const EdgeIterator &other) const
    \n+
    EdgeIterator(const VertexDescriptor &source, const EdgeDescriptor &edge)
    Constructor.
    \n+
    The vertex iterator of the graph.
    Definition: graph.hh:560
    \n+
    VertexIterator(const VertexDescriptor &current)
    Constructor for end iterator.
    \n+
    VertexIterator & increment()
    Preincrement operator.
    \n+
    EdgeIterator begin() const
    Get an iterator over all edges starting at the current vertex.
    \n+
    bool equals(const VertexIterator &other) const
    Equality iterator.
    \n+
    VertexIterator(const SubGraph< G, T > *graph, const VertexDescriptor &current, const VertexDescriptor &end)
    Constructor.
    \n+
    EdgeIterator end() const
    Get an iterator over all edges starting at the current vertex.
    \n+
    const VertexDescriptor & dereference() const
    Get the descriptor of the current vertex.
    \n+
    Attaches properties to the vertices of a graph.
    Definition: graph.hh:723
    \n+
    VertexIterator end()
    Get an iterator over the vertices.
    \n+
    const Graph & graph() const
    Get the graph the properties are attached to.
    \n+
    Graph::ConstEdgeIterator ConstEdgeIterator
    The type of the constant edge iterator.
    Definition: graph.hh:766
    \n+
    VertexProperties & getVertexProperties(const VertexDescriptor &vertex)
    Get the properties associated with a vertex.
    \n+
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n+
    Graph::EdgeDescriptor EdgeDescriptor
    The edge descritor.
    Definition: graph.hh:738
    \n+
    ConstEdgeIterator endEdges(const VertexDescriptor &source) const
    Get the mutable edge iterator over edges starting at a vertex.
    \n+
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:733
    \n+
    G Graph
    The graph we attach properties to.
    Definition: graph.hh:728
    \n+
    VM VertexMap
    The type of the map for converting the VertexDescriptor to std::size_t.
    Definition: graph.hh:756
    \n+
    EdgeIterator endEdges(const VertexDescriptor &source)
    Get the mutable edge iterator over edges starting at a vertex.
    \n+
    EdgeIterator beginEdges(const VertexDescriptor &source)
    Get the mutable edge iterator over edges starting at a vertex.
    \n+
    VP VertexProperties
    The type of the properties of the vertices.
    Definition: graph.hh:743
    \n+
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n+
    ConstEdgeIterator beginEdges(const VertexDescriptor &source) const
    Get the mutable edge iterator over edges starting at a vertex.
    \n+
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n+
    VertexIterator begin()
    Get an iterator over the vertices.
    \n+
    Graph::EdgeIterator EdgeIterator
    The type of the mutable edge iterator.
    Definition: graph.hh:761
    \n+\n+
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type EdgeIterator
    The class of the edge iterator.
    Definition: graph.hh:823
    \n+
    std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::value, VertexProperties &, constVertexProperties & >::type properties() const
    Get the properties of the current Vertex.
    \n+
    EdgeIterator end() const
    Get an iterator over the edges starting from the current vertex.
    \n+
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::type Father
    The father class.
    Definition: graph.hh:814
    \n+
    EdgeIterator begin() const
    Get an iterator over the edges starting from the current vertex.
    \n+
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n+
    std::size_t noVertices() const
    Get the number of vertices in the graph.
    \n+
    Graph::EdgeDescriptor EdgeDescriptor
    The edge descritor.
    Definition: graph.hh:993
    \n+
    const EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const VertexDescriptor &target) const
    Get the properties associated with a edge.
    \n+
    const EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge) const
    Get the properties associated with a edge.
    \n+
    const Graph & graph() const
    Get the graph the properties are attached to.
    \n+
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n+
    G Graph
    The graph we attach properties to.
    Definition: graph.hh:983
    \n+
    EM EdgeMap
    The type of the map for converting the EdgeDescriptor to std::size_t.
    Definition: graph.hh:1030
    \n+
    VM VertexMap
    The type of the map for converting the VertexDescriptor to std::size_t.
    Definition: graph.hh:1011
    \n+
    VP VertexProperties
    The type of the properties of the vertices.
    Definition: graph.hh:998
    \n+
    std::size_t noEdges() const
    Get the number of edges in the graph.
    \n+
    EP EdgeProperties
    The type of the properties of the edges;.
    Definition: graph.hh:1016
    \n+
    EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const VertexDescriptor &target)
    Get the properties associated with a edge.
    \n+
    EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge)
    Get the properties associated with a edge.
    \n+
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:988
    \n+
    PropertiesGraph(Graph &graph, const VertexMap &vmap=VertexMap(), const EdgeMap &emap=EdgeMap())
    Constructor.
    \n+\n+
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type Father
    The father class.
    Definition: graph.hh:1050
    \n+\n+
    std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::type Father
    The father class.
    Definition: graph.hh:1151
    \n+
    Wrapper to access the internal edge properties of a graph via operator[]()
    Definition: graph.hh:1361
    \n+
    GraphVertexPropertiesSelector(G &g)
    Constructor.
    Definition: graph.hh:1380
    \n+
    VertexProperties & operator[](const Vertex &vertex) const
    Get the properties associated to a vertex.
    Definition: graph.hh:1395
    \n+
    G Graph
    The type of the graph with internal properties.
    Definition: graph.hh:1366
    \n+
    G::VertexProperties VertexProperties
    The type of the vertex properties.
    Definition: graph.hh:1370
    \n+
    GraphVertexPropertiesSelector()
    Default constructor.
    Definition: graph.hh:1386
    \n+
    G::VertexDescriptor Vertex
    The vertex descriptor.
    Definition: graph.hh:1374
    \n+
    Wrapper to access the internal vertex properties of a graph via operator[]()
    Definition: graph.hh:1409
    \n+
    EdgeProperties & operator[](const Edge &edge) const
    Get the properties associated to a vertex.
    Definition: graph.hh:1442
    \n+
    G::EdgeProperties EdgeProperties
    The type of the vertex properties.
    Definition: graph.hh:1418
    \n+
    G::EdgeDescriptor Edge
    The edge descriptor.
    Definition: graph.hh:1422
    \n+
    GraphEdgePropertiesSelector()
    Default constructor.
    Definition: graph.hh:1434
    \n+
    G Graph
    The type of the graph with internal properties.
    Definition: graph.hh:1414
    \n+
    GraphEdgePropertiesSelector(G &g)
    Constructor.
    Definition: graph.hh:1428
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,463 +5,2295 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-parameters.hh\n+graph.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_PARAMETERS_HH\n- 6#define DUNE_AMG_PARAMETERS_HH\n+ 5#ifndef DUNE_AMG_GRAPH_HH\n+ 6#define DUNE_AMG_GRAPH_HH\n 7\n 8#include \n- 9\n- 10namespace Dune\n- 11{\n- 12 namespace Amg\n- 13 {\n-30 class DependencyParameters\n- 31 {\n- 32 public:\n-34 DependencyParameters()\n- 35 : alpha_(1.0/3.0), beta_(1.0E-5)\n- 36 {}\n- 37\n-42 void setBeta(double b)\n- 43 {\n- 44 beta_ = b;\n- 45 }\n- 46\n-52 double beta() const\n- 53 {\n- 54 return beta_;\n- 55 }\n- 56\n-61 void setAlpha(double a)\n- 62 {\n- 63 alpha_ = a;\n- 64 }\n- 65\n-70 double alpha() const\n- 71 {\n- 72 return alpha_;\n- 73 }\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17\n+ 18namespace Dune\n+ 19{\n+ 20 namespace Amg\n+ 21 {\n+ 49 template\n+50 class MatrixGraph\n+ 51 {\n+ 52 public:\n+56 typedef M Matrix;\n+ 57\n+61 typedef typename std::remove_const::type MutableMatrix;\n+ 62\n+66 typedef typename M::block_type Weight;\n+ 67\n+73 typedef typename M::size_type VertexDescriptor;\n 74\n- 75 private:\n- 76 double alpha_, beta_;\n- 77 };\n- 78\n-82 class AggregationParameters :\n- 83 public DependencyParameters\n- 84 {\n- 85 public:\n-95 AggregationParameters()\n- 96 : maxDistance_(2), minAggregateSize_(4), maxAggregateSize_(6),\n- 97 connectivity_(15), skipiso_(false)\n- 98 {}\n- 99\n-109 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n- 110 {\n- 111 maxDistance_=diameter-1;\n- 112 std::size_t csize=1;\n- 113\n- 114 for(; dim>0; dim--) {\n- 115 csize*=diameter;\n- 116 maxDistance_+=diameter-1;\n- 117 }\n- 118 minAggregateSize_=csize;\n- 119 maxAggregateSize_=static_cast(csize*1.5);\n- 120 }\n+80 typedef std::ptrdiff_t EdgeDescriptor;\n+ 81\n+ 82 enum {\n+ 83 /*\n+ 84 * @brief Whether Matrix is mutable.\n+ 85 */\n+ 86 mutableMatrix = std::is_same::type>::value\n+87 };\n+ 88\n+ 89\n+ 93 template\n+94 class EdgeIteratorT\n+ 95 {\n+ 96\n+ 97 public:\n+101 typedef typename std::remove_const::type MutableContainer;\n+105 typedef const typename std::remove_const::type ConstContainer;\n+ 106\n+ 107 friend class EdgeIteratorT;\n+ 108 friend class EdgeIteratorT;\n+ 109\n+ 110 enum {\n+ 112 isMutable = std::is_same::value\n+113 };\n+ 114\n+ 118 typedef typename std::conditional::type\n+120 ColIterator;\n 121\n-132 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)\n- 133 {\n- 134 setDefaultValuesIsotropic(dim, diameter);\n- 135 maxDistance_+=dim-1;\n- 136 }\n-144 std::size_t maxDistance() const { return maxDistance_;}\n- 145\n-154 void setMaxDistance(std::size_t distance) { maxDistance_ = distance;}\n- 155\n-161 bool skipIsolated() const\n- 162 {\n- 163 return skipiso_;\n- 164 }\n+ 125 typedef typename std::conditional::type\n+127 Weight;\n+ 128\n+136 EdgeIteratorT(const VertexDescriptor& source, const ColIterator& block,\n+ 137 const ColIterator& end, const EdgeDescriptor& edge);\n+ 138\n+145 EdgeIteratorT(const ColIterator& block);\n+ 146\n+ 151 template\n+152 EdgeIteratorT(const EdgeIteratorT& other);\n+ 153\n+ 154 typedef typename std::conditional::type>::value && C::mutableMatrix,\n+ 155 typename M::block_type, const typename M::block_type>::type\n+156 WeightType;\n+ 157\n+161 WeightType& weight() const;\n+ 162\n+164 EdgeIteratorT& operator++();\n 165\n-171 void setSkipIsolated(bool skip)\n- 172 {\n- 173 skipiso_=skip;\n- 174 }\n- 175\n-180 std::size_t minAggregateSize() const { return minAggregateSize_;}\n- 181\n-188 void setMinAggregateSize(std::size_t size){ minAggregateSize_=size;}\n+167 bool operator!=(const EdgeIteratorT::type>&\n+other) const;\n+ 168\n+170 bool operator!=(const EdgeIteratorT::\n+type>& other) const;\n+ 171\n+173 bool operator==(const EdgeIteratorT::type>&\n+other) const;\n+ 174\n+176 bool operator==(const EdgeIteratorT::\n+type>& other) const;\n+ 177\n+179 VertexDescriptor target() const;\n+ 180\n+182 VertexDescriptor source() const;\n+ 183\n+185 const EdgeDescriptor& operator*() const;\n+ 186\n+188 const EdgeDescriptor* operator->() const;\n 189\n-194 std::size_t maxAggregateSize() const { return maxAggregateSize_;}\n- 195\n-202 void setMaxAggregateSize(std::size_t size){ maxAggregateSize_ = size;}\n+ 190 private:\n+ 192 VertexDescriptor source_;\n+ 194 ColIterator block_;\n+ 195 /***\n+ 196 * @brief The column iterator positioned at the end of the row\n+ 197 * of vertex source_\n+ 198 */\n+ 199 ColIterator blockEnd_;\n+ 201 EdgeDescriptor edge_;\n+ 202 };\n 203\n-211 std::size_t maxConnectivity() const { return connectivity_;}\n- 212\n-220 void setMaxConnectivity(std::size_t connectivity){ connectivity_ =\n-connectivity;}\n- 221\n- 222 private:\n- 223 std::size_t maxDistance_, minAggregateSize_, maxAggregateSize_,\n-connectivity_;\n- 224 bool skipiso_;\n- 225\n- 226 };\n+ 207 template\n+208 class VertexIteratorT\n+ 209 {\n+ 210 public:\n+214 typedef typename std::remove_const::type MutableContainer;\n+218 typedef const typename std::remove_const::type ConstContainer;\n+ 219\n+ 220 friend class VertexIteratorT;\n+ 221 friend class VertexIteratorT;\n+ 222\n+ 223 enum {\n+ 225 isMutable = std::is_same::value\n+226 };\n 227\n- 228\n-232 enum AccumulationMode {\n-238 noAccu = 0,\n-244 atOnceAccu=1,\n- 248 successiveAccu=2\n-249 };\n- 250\n+233 explicit VertexIteratorT(C* graph, const VertexDescriptor& current);\n+ 234\n+242 explicit VertexIteratorT(const VertexDescriptor& current);\n+ 243\n+244 VertexIteratorT(const VertexIteratorT& other);\n+ 245\n+250 VertexIteratorT& operator++();\n 251\n- 252\n- 253\n-257 class CoarseningParameters : public AggregationParameters\n- 258 {\n- 259 public:\n-263 void setMaxLevel(int l)\n- 264 {\n- 265 maxLevel_ = l;\n- 266 }\n-270 int maxLevel() const\n- 271 {\n- 272 return maxLevel_;\n- 273 }\n- 274\n-278 void setCoarsenTarget(int nodes)\n- 279 {\n- 280 coarsenTarget_ = nodes;\n- 281 }\n+253 bool operator!=(const VertexIteratorT& other) const;\n+ 254\n+256 bool operator==(const VertexIteratorT& other) const;\n+ 257\n+259 bool operator!=(const VertexIteratorT& other) const;\n+ 260\n+262 bool operator==(const VertexIteratorT& other) const;\n+ 263\n+ 264 typedef typename std::conditional::type>::value && C::mutableMatrix,\n+ 265 typename M::block_type, const typename M::block_type>::type\n+266 WeightType;\n+268 WeightType& weight() const;\n+ 269\n+274 const VertexDescriptor& operator*() const;\n+ 275\n+281 EdgeIteratorT begin() const;\n 282\n-286 int coarsenTarget() const\n- 287 {\n- 288 return coarsenTarget_;\n- 289 }\n- 290\n-296 void setMinCoarsenRate(double rate)\n- 297 {\n- 298 minCoarsenRate_ = rate;\n- 299 }\n- 300\n-304 double minCoarsenRate() const\n- 305 {\n- 306 return minCoarsenRate_;\n- 307 }\n- 308\n-312 AccumulationMode accumulate() const\n- 313 {\n- 314 return accumulate_;\n- 315 }\n-319 void setAccumulate(AccumulationMode accu)\n- 320 {\n- 321 accumulate_=accu;\n- 322 }\n- 323\n-324 void setAccumulate(bool accu){\n- 325 accumulate_=accu ? successiveAccu : noAccu;\n- 326 }\n-332 void setProlongationDampingFactor(double d)\n- 333 {\n- 334 dampingFactor_ = d;\n- 335 }\n- 336\n-342 double getProlongationDampingFactor() const\n- 343 {\n- 344 return dampingFactor_;\n- 345 }\n-356 CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double\n-minCoarsenRate=1.2,\n- 357 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n- 358 : maxLevel_(maxLevel), coarsenTarget_(coarsenTarget), minCoarsenRate_\n-(minCoarsenRate),\n- 359 dampingFactor_(prolongDamp), accumulate_( accumulate)\n- 360 {}\n- 361\n- 362 private:\n- 366 int maxLevel_;\n- 370 int coarsenTarget_;\n- 374 double minCoarsenRate_;\n- 378 double dampingFactor_;\n- 383 AccumulationMode accumulate_;\n- 384 };\n- 385\n-392 class Parameters : public CoarseningParameters\n- 393 {\n- 394 public:\n-401 void setDebugLevel(int level)\n- 402 {\n- 403 debugLevel_ = level;\n- 404 }\n- 405\n-411 int debugLevel() const\n- 412 {\n- 413 return debugLevel_;\n- 414 }\n- 415\n-420 void setNoPreSmoothSteps(std::size_t steps)\n- 421 {\n- 422 preSmoothSteps_=steps;\n- 423 }\n-428 std::size_t getNoPreSmoothSteps() const\n- 429 {\n- 430 return preSmoothSteps_;\n- 431 }\n- 432\n-437 void setNoPostSmoothSteps(std::size_t steps)\n- 438 {\n- 439 postSmoothSteps_=steps;\n- 440 }\n-445 std::size_t getNoPostSmoothSteps() const\n- 446 {\n- 447 return postSmoothSteps_;\n- 448 }\n+288 EdgeIteratorT end() const;\n+ 289\n+ 290 private:\n+ 291 C* graph_;\n+ 292 VertexDescriptor current_;\n+ 293 };\n+ 294\n+298 typedef EdgeIteratorT > ConstEdgeIterator;\n+ 299\n+303 typedef EdgeIteratorT > EdgeIterator;\n+ 304\n+308 typedef VertexIteratorT > ConstVertexIterator;\n+ 309\n+313 typedef VertexIteratorT > VertexIterator;\n+ 314\n+319 MatrixGraph(Matrix& matrix);\n+ 320\n+324 ~MatrixGraph();\n+ 325\n+330 VertexIterator begin();\n+ 331\n+336 VertexIterator end();\n+ 337\n+342 ConstVertexIterator begin() const;\n+ 343\n+348 ConstVertexIterator end() const;\n+ 349\n+356 EdgeIterator beginEdges(const VertexDescriptor& source);\n+ 357\n+364 EdgeIterator endEdges(const VertexDescriptor& source);\n+ 365\n+ 366\n+373 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n+ 374\n+381 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n+ 382\n+387 Matrix& matrix();\n+ 388\n+393 const Matrix& matrix() const;\n+ 394\n+398 std::size_t noVertices() const;\n+ 399\n+406 VertexDescriptor maxVertex() const;\n+ 407\n+411 std::size_t noEdges() const;\n+ 412\n+419 EdgeDescriptor findEdge(const VertexDescriptor& source,\n+ 420 const VertexDescriptor& target) const;\n+ 421\n+ 422 private:\n+ 424 Matrix& matrix_;\n+ 426 EdgeDescriptor* start_;\n+ 428 MatrixGraph(const MatrixGraph&);\n+ 429\n+ 430 };\n+ 431\n+ 441 template\n+442 class SubGraph\n+ 443 {\n+ 444 public:\n+448 typedef G Graph;\n 449\n-453 void setGamma(std::size_t gamma)\n- 454 {\n- 455 gamma_=gamma;\n- 456 }\n-460 std::size_t getGamma() const\n- 461 {\n- 462 return gamma_;\n- 463 }\n- 464\n-469 void setAdditive(bool additive)\n+454 typedef T Excluded;\n+ 455\n+459 typedef typename Graph::VertexDescriptor VertexDescriptor;\n+ 460\n+461 typedef VertexDescriptor* EdgeDescriptor;\n+ 462\n+469 class EdgeIndexMap\n 470 {\n- 471 additive_=additive;\n- 472 }\n+ 471 public:\n+472 typedef ReadablePropertyMapTag Category;\n 473\n-478 bool getAdditive() const\n- 479 {\n- 480 return additive_;\n- 481 }\n+474 EdgeIndexMap(const EdgeDescriptor& firstEdge)\n+ 475 : firstEdge_(firstEdge)\n+ 476 {}\n+ 477\n+479 EdgeIndexMap(const EdgeIndexMap& emap)\n+ 480 : firstEdge_(emap.firstEdge_)\n+ 481 {}\n 482\n-493 Parameters(int maxLevel=100, int coarsenTarget=1000, double\n-minCoarsenRate=1.2,\n- 494 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n- 495 : CoarseningParameters(maxLevel, coarsenTarget, minCoarsenRate,\n-prolongDamp, accumulate)\n- 496 , debugLevel_(2), preSmoothSteps_(2), postSmoothSteps_(2), gamma_(1),\n- 497 additive_(false)\n- 498 {}\n- 499 private:\n- 500 int debugLevel_;\n- 501 std::size_t preSmoothSteps_;\n- 502 std::size_t postSmoothSteps_;\n- 503 std::size_t gamma_;\n- 504 bool additive_;\n- 505 };\n- 506\n- 507 } //namespace AMG\n- 508\n- 509} //namespace Dune\n- 510#endif\n-Dune::Amg::AggregationParameters::setDefaultValuesAnisotropic\n-void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)\n-Sets reasonable default values for an anisotropic problem.\n-Definition: parameters.hh:132\n-Dune::Amg::Parameters::setAdditive\n-void setAdditive(bool additive)\n-Set whether to use additive multigrid.\n-Definition: parameters.hh:469\n-Dune::Amg::AggregationParameters::setSkipIsolated\n-void setSkipIsolated(bool skip)\n-Set whether isolated aggregates will not be represented on the coarse level.\n-Definition: parameters.hh:171\n-Dune::Amg::CoarseningParameters::setProlongationDampingFactor\n-void setProlongationDampingFactor(double d)\n-Set the damping factor for the prolongation.\n-Definition: parameters.hh:332\n-Dune::Amg::DependencyParameters::alpha\n-double alpha() const\n-Get the scaling value for marking connections as strong. Default value is 1/3.\n-Definition: parameters.hh:70\n-Dune::Amg::AggregationParameters::setMaxAggregateSize\n-void setMaxAggregateSize(std::size_t size)\n-Set the maximum number of nodes a aggregate is allowed to have.\n-Definition: parameters.hh:202\n-Dune::Amg::CoarseningParameters::setMinCoarsenRate\n-void setMinCoarsenRate(double rate)\n-Set the minimum coarsening rate to be achieved in each coarsening.\n-Definition: parameters.hh:296\n-Dune::Amg::CoarseningParameters::minCoarsenRate\n-double minCoarsenRate() const\n-Get the minimum coarsening rate to be achieved.\n-Definition: parameters.hh:304\n-Dune::Amg::AggregationParameters::maxAggregateSize\n-std::size_t maxAggregateSize() const\n-Get the maximum number of nodes a aggregate is allowed to have.\n-Definition: parameters.hh:194\n-Dune::Amg::DependencyParameters::setAlpha\n-void setAlpha(double a)\n-Set the scaling value for marking connections as strong. Default value is 1/3.\n-Definition: parameters.hh:61\n-Dune::Amg::DependencyParameters::beta\n-double beta() const\n-Get the threshold for marking nodes as isolated. The default value is 1.0E-5.\n-Definition: parameters.hh:52\n-Dune::Amg::AggregationParameters::maxConnectivity\n-std::size_t maxConnectivity() const\n-Get the maximum number of connections a aggregate is allowed to have.\n-Definition: parameters.hh:211\n-Dune::Amg::CoarseningParameters::coarsenTarget\n-int coarsenTarget() const\n-Get the maximum number of unknowns allowed on the coarsest level.\n-Definition: parameters.hh:286\n-Dune::Amg::CoarseningParameters::setAccumulate\n-void setAccumulate(AccumulationMode accu)\n-Set whether he data should be accumulated on fewer processes on coarser levels.\n-Definition: parameters.hh:319\n-Dune::Amg::CoarseningParameters::getProlongationDampingFactor\n-double getProlongationDampingFactor() const\n-Get the damping factor for the prolongation.\n-Definition: parameters.hh:342\n-Dune::Amg::CoarseningParameters::accumulate\n-AccumulationMode accumulate() const\n-Whether the data should be accumulated on fewer processes on coarser levels.\n-Definition: parameters.hh:312\n-Dune::Amg::AggregationParameters::setMaxConnectivity\n-void setMaxConnectivity(std::size_t connectivity)\n-Set the maximum number of connections a aggregate is allowed to have.\n-Definition: parameters.hh:220\n-Dune::Amg::AggregationParameters::minAggregateSize\n-std::size_t minAggregateSize() const\n-Get the minimum number of nodes a aggregate has to consist of.\n-Definition: parameters.hh:180\n-Dune::Amg::Parameters::getAdditive\n-bool getAdditive() const\n-Get whether to use additive multigrid.\n-Definition: parameters.hh:478\n-Dune::Amg::CoarseningParameters::setMaxLevel\n-void setMaxLevel(int l)\n-Set the maximum number of levels allowed in the hierarchy.\n-Definition: parameters.hh:263\n-Dune::Amg::Parameters::setDebugLevel\n-void setDebugLevel(int level)\n-Set the debugging level.\n-Definition: parameters.hh:401\n-Dune::Amg::Parameters::getGamma\n-std::size_t getGamma() const\n-Get the value of gamma; 1 for V-cycle, 2 for W-cycle.\n-Definition: parameters.hh:460\n-Dune::Amg::Parameters::setNoPostSmoothSteps\n-void setNoPostSmoothSteps(std::size_t steps)\n-Set the number of postsmoothing steps to apply.\n-Definition: parameters.hh:437\n-Dune::Amg::Parameters::getNoPreSmoothSteps\n-std::size_t getNoPreSmoothSteps() const\n-Get the number of presmoothing steps to apply.\n-Definition: parameters.hh:428\n-Dune::Amg::DependencyParameters::DependencyParameters\n-DependencyParameters()\n+483 std::size_t operator[](const EdgeDescriptor& edge) const\n+ 484 {\n+ 485 return edge-firstEdge_;\n+ 486 }\n+ 487 private:\n+ 489 EdgeDescriptor firstEdge_;\n+ 491 EdgeIndexMap()\n+ 492 {}\n+ 493 };\n+ 494\n+499 EdgeIndexMap getEdgeIndexMap();\n+ 500\n+504 class EdgeIterator : public RandomAccessIteratorFacade\n+ 505 {\n+ 506 public:\n+512 explicit EdgeIterator(const VertexDescriptor& source, const EdgeDescriptor&\n+edge);\n+ 513\n+521 explicit EdgeIterator(const EdgeDescriptor& edge);\n+ 522\n+524 bool equals(const EdgeIterator& other) const;\n+ 525\n+527 EdgeIterator& increment();\n+ 528\n+530 EdgeIterator& decrement();\n+ 531\n+532 EdgeIterator& advance(std::ptrdiff_t n);\n+ 533\n+535 const EdgeDescriptor& dereference() const;\n+ 536\n+538 const VertexDescriptor& target() const;\n+ 539\n+541 const VertexDescriptor& source() const;\n+ 542\n+543 std::ptrdiff_t distanceTo(const EdgeIterator& other) const;\n+ 544\n+ 545 private:\n+ 547 VertexDescriptor source_;\n+ 552 EdgeDescriptor edge_;\n+ 553 };\n+ 554\n+558 class VertexIterator\n+ 559 : public ForwardIteratorFacade\n+ 560 {\n+ 561 public:\n+568 explicit VertexIterator(const SubGraph* graph, const VertexDescriptor&\n+current,\n+ 569 const VertexDescriptor& end);\n+ 570\n+ 571\n+578 explicit VertexIterator(const VertexDescriptor& current);\n+ 579\n+581 VertexIterator& increment();\n+ 582\n+584 bool equals(const VertexIterator& other) const;\n+ 585\n+590 const VertexDescriptor& dereference() const;\n+ 591\n+597 EdgeIterator begin() const;\n+ 598\n+604 EdgeIterator end() const;\n+ 605\n+ 606 private:\n+ 608 const SubGraph* graph_;\n+ 610 VertexDescriptor current_;\n+ 612 VertexDescriptor end_;\n+ 613 };\n+ 614\n+618 typedef EdgeIterator ConstEdgeIterator;\n+ 619\n+623 typedef VertexIterator ConstVertexIterator;\n+ 624\n+629 ConstVertexIterator begin() const;\n+ 630\n+635 ConstVertexIterator end() const;\n+ 636\n+643 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n+ 644\n+651 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n+ 652\n+656 std::size_t noVertices() const;\n+ 657\n+664 VertexDescriptor maxVertex() const;\n+ 665\n+669 std::size_t noEdges() const;\n+676 EdgeDescriptor findEdge(const VertexDescriptor& source,\n+ 677 const VertexDescriptor& target) const;\n+685 SubGraph(const Graph& graph, const T& excluded);\n+ 686\n+690 ~SubGraph();\n+ 691\n+ 692 private:\n+ 694 const T& excluded_;\n+ 696 std::size_t noVertices_;\n+ 698 VertexDescriptor endVertex_;\n+ 700 int noEdges_;\n+ 705 VertexDescriptor maxVertex_;\n+ 707 VertexDescriptor* edges_;\n+ 709 std::ptrdiff_t* start_;\n+ 711 std::ptrdiff_t* end_;\n+ 713 SubGraph(const SubGraph&)\n+ 714 {}\n+ 715 };\n+ 716\n+ 717\n+ 721 template\n+722 class VertexPropertiesGraph\n+ 723 {\n+ 724 public:\n+728 typedef G Graph;\n+ 729\n+733 typedef typename Graph::VertexDescriptor VertexDescriptor;\n+ 734\n+738 typedef typename Graph::EdgeDescriptor EdgeDescriptor;\n+ 739\n+743 typedef VP VertexProperties;\n+ 744\n+756 typedef VM VertexMap;\n+ 757\n+761 typedef typename Graph::EdgeIterator EdgeIterator;\n+ 762\n+766 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;\n+ 767\n+773 EdgeIterator beginEdges(const VertexDescriptor& source);\n+ 774\n+780 EdgeIterator endEdges(const VertexDescriptor& source);\n+ 781\n+787 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n+ 788\n+794 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n+ 795\n+ 796\n+ 797 template\n+798 class VertexIteratorT\n+ 799 : public std::conditional::\n+type,\n+ 800 C>::value,\n+ 801 typename Graph::VertexIterator,\n+ 802 typename Graph::ConstVertexIterator>::type\n+ 803 {\n+ 804 friend class VertexIteratorT::type>;\n+ 805 friend class VertexIteratorT::type>;\n+ 806 public:\n+ 810 typedef typename std::conditional::type,\n+ 811 C>::value,\n+ 812 typename Graph::VertexIterator,\n+ 813 typename Graph::ConstVertexIterator>::type\n+814 Father;\n+ 815\n+ 819 typedef typename std::conditional::type,\n+ 820 C>::value,\n+ 821 typename Graph::EdgeIterator,\n+ 822 typename Graph::ConstEdgeIterator>::type\n+823 EdgeIterator;\n+ 824\n+830 explicit VertexIteratorT(const Father& iter,\n+ 831 C* graph);\n+ 832\n+ 833\n+841 explicit VertexIteratorT(const Father& iter);\n+ 842\n+ 847 template\n+848 VertexIteratorT(const VertexIteratorT& other);\n+ 849\n+ 853 typename std::conditional::\n+type>::value,\n+ 854 VertexProperties&,\n+ 855 const VertexProperties&>::type\n+856 properties() const;\n+ 857\n+863 EdgeIterator begin() const;\n+ 864\n+870 EdgeIterator end() const;\n+ 871\n+ 872 private:\n+ 876 C* graph_;\n+ 877 };\n+ 878\n+ 882 typedef VertexIteratorT > VertexIterator;\n+ 884\n+ 888 typedef VertexIteratorT > ConstVertexIterator;\n+ 890\n+895 VertexIterator begin();\n+ 896\n+901 VertexIterator end();\n+ 902\n+907 ConstVertexIterator begin() const;\n+ 908\n+913 ConstVertexIterator end() const;\n+ 914\n+920 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);\n+ 921\n+927 const VertexProperties& getVertexProperties(const VertexDescriptor& vertex)\n+const;\n+ 928\n+933 const Graph& graph() const;\n+ 934\n+938 std::size_t noVertices() const;\n+ 939\n+943 std::size_t noEdges() const;\n+ 944\n+951 VertexDescriptor maxVertex() const;\n+ 952\n+958 VertexPropertiesGraph(Graph& graph, const VertexMap vmap=VertexMap());\n+ 959\n+ 960 private:\n+ 961 VertexPropertiesGraph(const VertexPropertiesGraph&)\n+ 962 {}\n+ 963\n+ 965 Graph& graph_;\n+ 967 VertexMap vmap_;\n+969 std::vector vertexProperties_;\n+ 970\n+ 971 };\n+ 972\n+ 976 template\n+977 class PropertiesGraph\n+ 978 {\n+ 979 public:\n+983 typedef G Graph;\n+ 984\n+988 typedef typename Graph::VertexDescriptor VertexDescriptor;\n+ 989\n+993 typedef typename Graph::EdgeDescriptor EdgeDescriptor;\n+ 994\n+998 typedef VP VertexProperties;\n+ 999\n+1011 typedef VM VertexMap;\n+ 1012\n+1016 typedef EP EdgeProperties;\n+ 1017\n+ 1018\n+1030 typedef EM EdgeMap;\n+ 1031\n+ 1032 template\n+1033 class EdgeIteratorT\n+ 1034 : public std::conditional::\n+type,\n+ 1035 C>::value,\n+ 1036 typename Graph::EdgeIterator,\n+ 1037 typename Graph::ConstEdgeIterator>::type\n+ 1038 {\n+ 1039\n+ 1040 friend class EdgeIteratorT::type>;\n+ 1041 friend class EdgeIteratorT::type>;\n+ 1042 public:\n+ 1046 typedef typename std::conditional::type,\n+ 1047 C>::value,\n+ 1048 typename Graph::EdgeIterator,\n+ 1049 typename Graph::ConstEdgeIterator>::type\n+1050 Father;\n+ 1051\n+1057 explicit EdgeIteratorT(const Father& iter,\n+ 1058 C* graph);\n+ 1059\n+1067 explicit EdgeIteratorT(const Father& iter);\n+ 1068\n+ 1073 template\n+1074 EdgeIteratorT(const EdgeIteratorT& other);\n+ 1075\n+ 1079 typename std::conditional::\n+type>::value,\n+ 1080 EdgeProperties&,\n+ 1081 const EdgeProperties&>::type\n+1082 properties() const;\n+ 1083\n+ 1084 private:\n+1088 C* graph_;\n+ 1089 };\n+ 1090\n+ 1094 typedef EdgeIteratorT > EdgeIterator;\n+ 1097\n+ 1101 typedef EdgeIteratorT > ConstEdgeIterator;\n+ 1104\n+1110 EdgeIterator beginEdges(const VertexDescriptor& source);\n+ 1111\n+1117 EdgeIterator endEdges(const VertexDescriptor& source);\n+ 1118\n+1124 ConstEdgeIterator beginEdges(const VertexDescriptor& source) const;\n+ 1125\n+1131 ConstEdgeIterator endEdges(const VertexDescriptor& source) const;\n+ 1132\n+ 1133\n+ 1134 template\n+1135 class VertexIteratorT\n+ 1136 : public std::conditional::\n+type,\n+ 1137 C>::value,\n+ 1138 typename Graph::VertexIterator,\n+ 1139 typename Graph::ConstVertexIterator>::type\n+ 1140 {\n+ 1141 friend class VertexIteratorT::type>;\n+ 1142 friend class VertexIteratorT::type>;\n+ 1143 public:\n+ 1147 typedef typename std::conditional::type,\n+ 1148 C>::value,\n+ 1149 typename Graph::VertexIterator,\n+ 1150 typename Graph::ConstVertexIterator>::type\n+1151 Father;\n+ 1152\n+1158 explicit VertexIteratorT(const Father& iter,\n+ 1159 C* graph);\n+ 1160\n+ 1161\n+1169 explicit VertexIteratorT(const Father& iter);\n+ 1170\n+ 1175 template\n+1176 VertexIteratorT(const VertexIteratorT& other);\n+ 1177\n+ 1181 typename std::conditional::\n+type>::value,\n+ 1182 VertexProperties&,\n+ 1183 const VertexProperties&>::type\n+1184 properties() const;\n+ 1185\n+1191 EdgeIteratorT begin() const;\n+ 1192\n+1198 EdgeIteratorT end() const;\n+ 1199\n+ 1200 private:\n+ 1204 C* graph_;\n+ 1205 };\n+ 1206\n+ 1210 typedef VertexIteratorT > VertexIterator;\n+ 1213\n+ 1217 typedef VertexIteratorT > ConstVertexIterator;\n+ 1220\n+1225 VertexIterator begin();\n+ 1226\n+1231 VertexIterator end();\n+ 1232\n+1237 ConstVertexIterator begin() const;\n+ 1238\n+1243 ConstVertexIterator end() const;\n+ 1244\n+1250 VertexProperties& getVertexProperties(const VertexDescriptor& vertex);\n+ 1251\n+1257 const VertexProperties& getVertexProperties(const VertexDescriptor&\n+vertex) const;\n+ 1258\n+1265 EdgeDescriptor findEdge(const VertexDescriptor& source,\n+ 1266 const VertexDescriptor& target)\n+ 1267 {\n+ 1268 return graph_.findEdge(source,target);\n+ 1269 }\n+ 1270\n+1276 EdgeProperties& getEdgeProperties(const EdgeDescriptor& edge);\n+ 1277\n+ 1278\n+1284 const EdgeProperties& getEdgeProperties(const EdgeDescriptor& edge) const;\n+ 1285\n+1292 EdgeProperties& getEdgeProperties(const VertexDescriptor& source,\n+ 1293 const VertexDescriptor& target);\n+ 1294\n+1301 const EdgeProperties& getEdgeProperties(const VertexDescriptor& source,\n+ 1302 const VertexDescriptor& target) const;\n+ 1303\n+1308 const Graph& graph() const;\n+ 1309\n+1313 std::size_t noVertices() const;\n+ 1314\n+1318 std::size_t noEdges() const;\n+ 1319\n+1326 VertexDescriptor maxVertex() const;\n+ 1327\n+1334 PropertiesGraph(Graph& graph, const VertexMap& vmap=VertexMap(),\n+ 1335 const EdgeMap& emap=EdgeMap());\n+ 1336\n+ 1337 private:\n+ 1338 PropertiesGraph(const PropertiesGraph&)\n+ 1339 {}\n+ 1340\n+ 1342 Graph& graph_;\n+ 1345 VertexMap vmap_;\n+ 1346 std::vector vertexProperties_;\n+ 1348 EdgeMap emap_;\n+1350 std::vector edgeProperties_;\n+ 1351\n+ 1352 };\n+ 1353\n+ 1354\n+ 1359 template\n+1360 class GraphVertexPropertiesSelector\n+ 1361 {\n+ 1362 public:\n+1366 typedef G Graph;\n+1370 typedef typename G::VertexProperties VertexProperties;\n+1374 typedef typename G::VertexDescriptor Vertex;\n+ 1375\n+1380 GraphVertexPropertiesSelector(G& g)\n+ 1381 : graph_(g)\n+ 1382 {}\n+1386 GraphVertexPropertiesSelector()\n+ 1387 : graph_(0)\n+ 1388 {}\n+ 1389\n+ 1390\n+1395 VertexProperties& operator[](const Vertex& vertex) const\n+ 1396 {\n+ 1397 return graph_->getVertexProperties(vertex);\n+ 1398 }\n+ 1399 private:\n+ 1400 Graph* graph_;\n+ 1401 };\n+ 1402\n+ 1407 template\n+1408 class GraphEdgePropertiesSelector\n+ 1409 {\n+ 1410 public:\n+1414 typedef G Graph;\n+1418 typedef typename G::EdgeProperties EdgeProperties;\n+1422 typedef typename G::EdgeDescriptor Edge;\n+ 1423\n+1428 GraphEdgePropertiesSelector(G& g)\n+ 1429 : graph_(g)\n+ 1430 {}\n+1434 GraphEdgePropertiesSelector()\n+ 1435 : graph_(0)\n+ 1436 {}\n+ 1437\n+1442 EdgeProperties& operator[](const Edge& edge) const\n+ 1443 {\n+ 1444 return graph_->getEdgeProperties(edge);\n+ 1445 }\n+ 1446 private:\n+ 1447 Graph* graph_;\n+ 1448 };\n+ 1449\n+ 1450\n+ 1461 template\n+1462 int visitNeighbours(const G& graph, const typename G::VertexDescriptor&\n+vertex,\n+ 1463 V& visitor);\n+ 1464\n+ 1465#ifndef DOXYGEN\n+ 1466\n+ 1467 template\n+ 1468 MatrixGraph::MatrixGraph(M& matrix)\n+ 1469 : matrix_(matrix)\n+ 1470 {\n+ 1471 if(matrix_.N()!=matrix_.M())\n+ 1472 DUNE_THROW(ISTLError, \"Matrix has to have as many columns as rows!\");\n+ 1473\n+ 1474 start_ = new EdgeDescriptor[matrix_.N()+1];\n+ 1475\n+ 1476 typedef typename M::ConstIterator Iterator;\n+ 1477 start_[matrix_.begin().index()] = 0;\n+ 1478\n+ 1479 for(Iterator row=matrix_.begin(); row != matrix_.end(); ++row)\n+ 1480 start_[row.index()+1] = start_[row.index()] + row->size();\n+ 1481 }\n+ 1482\n+ 1483 template\n+ 1484 MatrixGraph::~MatrixGraph()\n+ 1485 {\n+ 1486 delete[] start_;\n+ 1487 }\n+ 1488\n+ 1489 template\n+ 1490 inline std::size_t MatrixGraph::noEdges() const\n+ 1491 {\n+ 1492 return start_[matrix_.N()];\n+ 1493 }\n+ 1494\n+ 1495 template\n+ 1496 inline std::size_t MatrixGraph::noVertices() const\n+ 1497 {\n+ 1498 return matrix_.N();\n+ 1499 }\n+ 1500\n+ 1501 template\n+ 1502 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n+maxVertex() const\n+ 1503 {\n+ 1504 return matrix_.N()-1;\n+ 1505 }\n+ 1506\n+ 1507 template\n+ 1508 typename MatrixGraph::EdgeDescriptor\n+ 1509 MatrixGraph::findEdge(const VertexDescriptor& source,\n+ 1510 const VertexDescriptor& target) const\n+ 1511 {\n+ 1512 typename M::ConstColIterator found =matrix_[source].find(target);\n+ 1513 if(found == matrix_[source].end())\n+ 1514 return std::numeric_limits::max();\n+ 1515 std::size_t offset = found.offset();\n+ 1516 if(target>source)\n+ 1517 offset--;\n+ 1518\n+ 1519 assert(offset\n+ 1526 inline M& MatrixGraph::matrix()\n+ 1527 {\n+ 1528 return matrix_;\n+ 1529 }\n+ 1530\n+ 1531 template\n+ 1532 inline const M& MatrixGraph::matrix() const\n+ 1533 {\n+ 1534 return matrix_;\n+ 1535 }\n+ 1536\n+ 1537 template\n+ 1538 template\n+ 1539 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const VertexDescriptor&\n+source, const ColIterator& block,\n+ 1540 const ColIterator& end, const EdgeDescriptor& edge)\n+ 1541 : source_(source), block_(block), blockEnd_(end), edge_(edge)\n+ 1542 {\n+ 1543 if(block_!=blockEnd_ && block_.index() == source_) {\n+ 1544 // This is the edge from the diagonal to the diagonal. Skip it.\n+ 1545 ++block_;\n+ 1546 }\n+ 1547 }\n+ 1548\n+ 1549 template\n+ 1550 template\n+ 1551 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const ColIterator& block)\n+ 1552 : block_(block)\n+ 1553 {}\n+ 1554\n+ 1555 template\n+ 1556 template\n+ 1557 template\n+ 1558 MatrixGraph::EdgeIteratorT::EdgeIteratorT(const EdgeIteratorT&\n+other)\n+ 1559 : source_(other.source_), block_(other.block_), blockEnd_\n+(other.blockEnd_), edge_(other.edge_)\n+ 1560 {}\n+ 1561\n+ 1562\n+ 1563 template\n+ 1564 template\n+ 1565 inline typename MatrixGraph::template EdgeIteratorT::WeightType&\n+ 1566 MatrixGraph::EdgeIteratorT::weight() const\n+ 1567 {\n+ 1568 return *block_;\n+ 1569 }\n+ 1570\n+ 1571 template\n+ 1572 template\n+ 1573 inline typename MatrixGraph::template EdgeIteratorT&\n+MatrixGraph::EdgeIteratorT::operator++()\n+ 1574 {\n+ 1575 ++block_;\n+ 1576 ++edge_;\n+ 1577\n+ 1578 if(block_!=blockEnd_ && block_.index() == source_) {\n+ 1579 // This is the edge from the diagonal to the diagonal. Skip it.\n+ 1580 ++block_;\n+ 1581 }\n+ 1582\n+ 1583 return *this;\n+ 1584 }\n+ 1585\n+ 1586 template\n+ 1587 template\n+ 1588 inline bool MatrixGraph::EdgeIteratorT::operator!=(const typename\n+MatrixGraph::template EdgeIteratorT::type>&\n+other) const\n+ 1589 {\n+ 1590 return block_!=other.block_;\n+ 1591 }\n+ 1592\n+ 1593 template\n+ 1594 template\n+ 1595 inline bool MatrixGraph::EdgeIteratorT::operator!=(const typename\n+MatrixGraph::template EdgeIteratorT::\n+type>& other) const\n+ 1596 {\n+ 1597 return block_!=other.block_;\n+ 1598 }\n+ 1599\n+ 1600 template\n+ 1601 template\n+ 1602 inline bool MatrixGraph::EdgeIteratorT::operator==(const typename\n+MatrixGraph::template EdgeIteratorT::type>&\n+other) const\n+ 1603 {\n+ 1604 return block_==other.block_;\n+ 1605 }\n+ 1606\n+ 1607 template\n+ 1608 template\n+ 1609 inline bool MatrixGraph::EdgeIteratorT::operator==(const typename\n+MatrixGraph::template EdgeIteratorT::\n+type>& other) const\n+ 1610 {\n+ 1611 return block_==other.block_;\n+ 1612 }\n+ 1613\n+ 1614 template\n+ 1615 template\n+ 1616 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n+EdgeIteratorT::target() const\n+ 1617 {\n+ 1618 return block_.index();\n+ 1619 }\n+ 1620\n+ 1621 template\n+ 1622 template\n+ 1623 inline typename MatrixGraph::VertexDescriptor MatrixGraph::\n+EdgeIteratorT::source() const\n+ 1624 {\n+ 1625 return source_;\n+ 1626 }\n+ 1627\n+ 1628 template\n+ 1629 template\n+ 1630 inline const typename MatrixGraph::EdgeDescriptor& MatrixGraph::\n+EdgeIteratorT::operator*() const\n+ 1631 {\n+ 1632 return edge_;\n+ 1633 }\n+ 1634\n+ 1635 template\n+ 1636 template\n+ 1637 inline const typename MatrixGraph::EdgeDescriptor* MatrixGraph::\n+EdgeIteratorT::operator->() const\n+ 1638 {\n+ 1639 return &edge_;\n+ 1640 }\n+ 1641\n+ 1642 template\n+ 1643 template\n+ 1644 MatrixGraph::VertexIteratorT::VertexIteratorT(C* graph,\n+ 1645 const VertexDescriptor& current)\n+ 1646 : graph_(graph), current_(current)\n+ 1647 {}\n+ 1648\n+ 1649\n+ 1650 template\n+ 1651 template\n+ 1652 MatrixGraph::VertexIteratorT::VertexIteratorT(const\n+VertexDescriptor& current)\n+ 1653 : current_(current)\n+ 1654 {}\n+ 1655\n+ 1656 template\n+ 1657 template\n+ 1658 MatrixGraph::VertexIteratorT::VertexIteratorT(const\n+VertexIteratorT& other)\n+ 1659 : graph_(other.graph_), current_(other.current_)\n+ 1660 {}\n+ 1661\n+ 1662 template\n+ 1663 template\n+ 1664 inline bool MatrixGraph::VertexIteratorT::operator!=(const\n+VertexIteratorT& other) const\n+ 1665 {\n+ 1666 return current_ != other.current_;\n+ 1667 }\n+ 1668\n+ 1669 template\n+ 1670 template\n+ 1671 inline bool MatrixGraph::VertexIteratorT::operator!=(const\n+VertexIteratorT& other) const\n+ 1672 {\n+ 1673 return current_ != other.current_;\n+ 1674 }\n+ 1675\n+ 1676\n+ 1677 template\n+ 1678 template\n+ 1679 inline bool MatrixGraph::VertexIteratorT::operator==(const\n+VertexIteratorT& other) const\n+ 1680 {\n+ 1681 return current_ == other.current_;\n+ 1682 }\n+ 1683\n+ 1684 template\n+ 1685 template\n+ 1686 inline bool MatrixGraph::VertexIteratorT::operator==(const\n+VertexIteratorT& other) const\n+ 1687 {\n+ 1688 return current_ == other.current_;\n+ 1689 }\n+ 1690\n+ 1691 template\n+ 1692 template\n+ 1693 inline typename MatrixGraph::template VertexIteratorT&\n+MatrixGraph::VertexIteratorT::operator++()\n+ 1694 {\n+ 1695 ++current_;\n+ 1696 return *this;\n+ 1697 }\n+ 1698\n+ 1699 template\n+ 1700 template\n+ 1701 inline typename MatrixGraph::template VertexIteratorT::WeightType&\n+ 1702 MatrixGraph::VertexIteratorT::weight() const\n+ 1703 {\n+ 1704 return graph_->matrix()[current_][current_];\n+ 1705 }\n+ 1706\n+ 1707 template\n+ 1708 template\n+ 1709 inline const typename MatrixGraph::VertexDescriptor&\n+ 1710 MatrixGraph::VertexIteratorT::operator*() const\n+ 1711 {\n+ 1712 return current_;\n+ 1713 }\n+ 1714\n+ 1715 template\n+ 1716 template\n+ 1717 inline typename MatrixGraph::template EdgeIteratorT\n+ 1718 MatrixGraph::VertexIteratorT::begin() const\n+ 1719 {\n+ 1720 return graph_->beginEdges(current_);\n+ 1721 }\n+ 1722\n+ 1723 template\n+ 1724 template\n+ 1725 inline typename MatrixGraph::template EdgeIteratorT\n+ 1726 MatrixGraph::VertexIteratorT::end() const\n+ 1727 {\n+ 1728 return graph_->endEdges(current_);\n+ 1729 }\n+ 1730\n+ 1731 template\n+ 1732 inline typename MatrixGraph::template VertexIteratorT >\n+ 1733 MatrixGraph::begin()\n+ 1734 {\n+ 1735 return VertexIterator(this,0);\n+ 1736 }\n+ 1737\n+ 1738 template\n+ 1739 inline typename MatrixGraph::template VertexIteratorT >\n+ 1740 MatrixGraph::end()\n+ 1741 {\n+ 1742 return VertexIterator(matrix_.N());\n+ 1743 }\n+ 1744\n+ 1745\n+ 1746 template\n+ 1747 inline typename MatrixGraph::template VertexIteratorT >\n+ 1748 MatrixGraph::begin() const\n+ 1749 {\n+ 1750 return ConstVertexIterator(this, 0);\n+ 1751 }\n+ 1752\n+ 1753 template\n+ 1754 inline typename MatrixGraph::template VertexIteratorT >\n+ 1755 MatrixGraph::end() const\n+ 1756 {\n+ 1757 return ConstVertexIterator(matrix_.N());\n+ 1758 }\n+ 1759\n+ 1760 template\n+ 1761 inline typename MatrixGraph::template EdgeIteratorT >\n+ 1762 MatrixGraph::beginEdges(const VertexDescriptor& source)\n+ 1763 {\n+ 1764 return EdgeIterator(source, matrix_.operator[](source).begin(),\n+ 1765 matrix_.operator[](source).end(), start_[source]);\n+ 1766 }\n+ 1767\n+ 1768 template\n+ 1769 inline typename MatrixGraph::template EdgeIteratorT >\n+ 1770 MatrixGraph::endEdges(const VertexDescriptor& source)\n+ 1771 {\n+ 1772 return EdgeIterator(matrix_.operator[](source).end());\n+ 1773 }\n+ 1774\n+ 1775\n+ 1776 template\n+ 1777 inline typename MatrixGraph::template EdgeIteratorT >\n+ 1778 MatrixGraph::beginEdges(const VertexDescriptor& source) const\n+ 1779 {\n+ 1780 return ConstEdgeIterator(source, matrix_.operator[](source).begin(),\n+ 1781 matrix_.operator[](source).end(), start_[source]);\n+ 1782 }\n+ 1783\n+ 1784 template\n+ 1785 inline typename MatrixGraph::template EdgeIteratorT >\n+ 1786 MatrixGraph::endEdges(const VertexDescriptor& source) const\n+ 1787 {\n+ 1788 return ConstEdgeIterator(matrix_.operator[](source).end());\n+ 1789 }\n+ 1790\n+ 1791\n+ 1792 template\n+ 1793 SubGraph::EdgeIterator::EdgeIterator(const VertexDescriptor& source,\n+ 1794 const EdgeDescriptor& edge)\n+ 1795 : source_(source), edge_(edge)\n+ 1796 {}\n+ 1797\n+ 1798\n+ 1799 template\n+ 1800 SubGraph::EdgeIterator::EdgeIterator(const EdgeDescriptor& edge)\n+ 1801 : edge_(edge)\n+ 1802 {}\n+ 1803\n+ 1804 template\n+ 1805 typename SubGraph::EdgeIndexMap SubGraph::getEdgeIndexMap()\n+ 1806 {\n+ 1807 return EdgeIndexMap(edges_);\n+ 1808 }\n+ 1809\n+ 1810 template\n+ 1811 inline bool SubGraph::EdgeIterator::equals(const EdgeIterator &\n+other) const\n+ 1812 {\n+ 1813 return other.edge_==edge_;\n+ 1814 }\n+ 1815\n+ 1816 template\n+ 1817 inline typename SubGraph::EdgeIterator& SubGraph::\n+EdgeIterator::increment()\n+ 1818 {\n+ 1819 ++edge_;\n+ 1820 return *this;\n+ 1821 }\n+ 1822\n+ 1823 template\n+ 1824 inline typename SubGraph::EdgeIterator& SubGraph::\n+EdgeIterator::decrement()\n+ 1825 {\n+ 1826 --edge_;\n+ 1827 return *this;\n+ 1828 }\n+ 1829\n+ 1830 template\n+ 1831 inline typename SubGraph::EdgeIterator& SubGraph::\n+EdgeIterator::advance(std::ptrdiff_t n)\n+ 1832 {\n+ 1833 edge_+=n;\n+ 1834 return *this;\n+ 1835 }\n+ 1836 template\n+ 1837 inline const typename G::VertexDescriptor& SubGraph::EdgeIterator::\n+source() const\n+ 1838 {\n+ 1839 return source_;\n+ 1840 }\n+ 1841\n+ 1842 template\n+ 1843 inline const typename G::VertexDescriptor& SubGraph::EdgeIterator::\n+target() const\n+ 1844 {\n+ 1845 return *edge_;\n+ 1846 }\n+ 1847\n+ 1848\n+ 1849 template\n+ 1850 inline const typename SubGraph::EdgeDescriptor& SubGraph::\n+EdgeIterator::dereference() const\n+ 1851 {\n+ 1852 return edge_;\n+ 1853 }\n+ 1854\n+ 1855 template\n+ 1856 inline std::ptrdiff_t SubGraph::EdgeIterator::distanceTo(const\n+EdgeIterator & other) const\n+ 1857 {\n+ 1858 return other.edge_-edge_;\n+ 1859 }\n+ 1860\n+ 1861 template\n+ 1862 SubGraph::VertexIterator::VertexIterator(const SubGraph* graph,\n+ 1863 const VertexDescriptor& current,\n+ 1864 const VertexDescriptor& end)\n+ 1865 : graph_(graph), current_(current), end_(end)\n+ 1866 {\n+ 1867 // Skip excluded vertices\n+ 1868 typedef typename T::const_iterator Iterator;\n+ 1869\n+ 1870 for(Iterator vertex = graph_->excluded_.begin();\n+ 1871 current_ != end_ && *vertex;\n+ 1872 ++vertex)\n+ 1873 ++current_;\n+ 1874 assert(current_ == end_ || !graph_->excluded_[current_]);\n+ 1875 }\n+ 1876\n+ 1877 template\n+ 1878 SubGraph::VertexIterator::VertexIterator(const VertexDescriptor&\n+current)\n+ 1879 : current_(current)\n+ 1880 {}\n+ 1881\n+ 1882 template\n+ 1883 inline typename SubGraph::VertexIterator& SubGraph::\n+VertexIterator::increment()\n+ 1884 {\n+ 1885 ++current_;\n+ 1886 //Skip excluded vertices\n+ 1887 while(current_ != end_ && graph_->excluded_[current_])\n+ 1888 ++current_;\n+ 1889\n+ 1890 assert(current_ == end_ || !graph_->excluded_[current_]);\n+ 1891 return *this;\n+ 1892 }\n+ 1893\n+ 1894 template\n+ 1895 inline bool SubGraph::VertexIterator::equals(const VertexIterator &\n+other) const\n+ 1896 {\n+ 1897 return current_==other.current_;\n+ 1898 }\n+ 1899\n+ 1900 template\n+ 1901 inline const typename G::VertexDescriptor& SubGraph::\n+VertexIterator::dereference() const\n+ 1902 {\n+ 1903 return current_;\n+ 1904 }\n+ 1905\n+ 1906 template\n+ 1907 inline typename SubGraph::EdgeIterator SubGraph::\n+VertexIterator::begin() const\n+ 1908 {\n+ 1909 return graph_->beginEdges(current_);\n+ 1910 }\n+ 1911\n+ 1912 template\n+ 1913 inline typename SubGraph::EdgeIterator SubGraph::\n+VertexIterator::end() const\n+ 1914 {\n+ 1915 return graph_->endEdges(current_);\n+ 1916 }\n+ 1917\n+ 1918 template\n+ 1919 inline typename SubGraph::VertexIterator SubGraph::begin()\n+const\n+ 1920 {\n+ 1921 return VertexIterator(this, 0, endVertex_);\n+ 1922 }\n+ 1923\n+ 1924\n+ 1925 template\n+ 1926 inline typename SubGraph::VertexIterator SubGraph::end() const\n+ 1927 {\n+ 1928 return VertexIterator(endVertex_);\n+ 1929 }\n+ 1930\n+ 1931\n+ 1932 template\n+ 1933 inline typename SubGraph::EdgeIterator SubGraph::beginEdges\n+(const VertexDescriptor& source) const\n+ 1934 {\n+ 1935 return EdgeIterator(source, edges_+start_[source]);\n+ 1936 }\n+ 1937\n+ 1938 template\n+ 1939 inline typename SubGraph::EdgeIterator SubGraph::endEdges(const\n+VertexDescriptor& source) const\n+ 1940 {\n+ 1941 return EdgeIterator(edges_+end_[source]);\n+ 1942 }\n+ 1943\n+ 1944 template\n+ 1945 std::size_t SubGraph::noVertices() const\n+ 1946 {\n+ 1947 return noVertices_;\n+ 1948 }\n+ 1949\n+ 1950 template\n+ 1951 inline typename SubGraph::VertexDescriptor SubGraph::maxVertex\n+() const\n+ 1952 {\n+ 1953 return maxVertex_;\n+ 1954 }\n+ 1955\n+ 1956 template\n+ 1957 inline std::size_t SubGraph::noEdges() const\n+ 1958 {\n+ 1959 return noEdges_;\n+ 1960 }\n+ 1961\n+ 1962 template\n+ 1963 inline typename SubGraph::EdgeDescriptor SubGraph::findEdge\n+(const VertexDescriptor& source,\n+ 1964 const VertexDescriptor& target) const\n+ 1965 {\n+ 1966 const EdgeDescriptor edge = std::lower_bound(edges_+start_[source],\n+edges_+end_[source], target);\n+ 1967 if(edge==edges_+end_[source] || *edge!=target)\n+ 1968 return std::numeric_limits::max();\n+ 1969\n+ 1970 return edge;\n+ 1971 }\n+ 1972\n+ 1973 template\n+ 1974 SubGraph::~SubGraph()\n+ 1975 {\n+ 1976 delete[] edges_;\n+ 1977 delete[] end_;\n+ 1978 delete[] start_;\n+ 1979 }\n+ 1980\n+ 1981 template\n+ 1982 SubGraph::SubGraph(const G& graph, const T& excluded)\n+ 1983 : excluded_(excluded), noVertices_(0), endVertex_(0), maxVertex_\n+(graph.maxVertex())\n+ 1984 {\n+ 1985 start_ = new std::ptrdiff_t[graph.noVertices()];\n+ 1986 end_ = new std::ptrdiff_t[graph.noVertices()];\n+ 1987 edges_ = new VertexDescriptor[graph.noEdges()];\n+ 1988\n+ 1989 VertexDescriptor* edge=edges_;\n+ 1990\n+ 1991 // Cater for the case that there are no vertices.\n+ 1992 // Otherwise endVertex_ will get 1 below.\n+ 1993 if ( graph.noVertices() == 0)\n+ 1994 return;\n+ 1995\n+ 1996 typedef typename Graph::ConstVertexIterator Iterator;\n+ 1997 Iterator endVertex=graph.end();\n+ 1998\n+ 1999 for(Iterator vertex = graph.begin(); vertex != endVertex; ++vertex)\n+ 2000 if(excluded_[*vertex])\n+ 2001 start_[*vertex]=end_[*vertex]=-1;\n+ 2002 else{\n+ 2003 ++noVertices_;\n+ 2004 endVertex_ = std::max(*vertex, endVertex_);\n+ 2005\n+ 2006 start_[*vertex] = edge-edges_;\n+ 2007\n+ 2008 auto endEdge = vertex.end();\n+ 2009\n+ 2010 for(auto iter=vertex.begin(); iter!= endEdge; ++iter)\n+ 2011 if(!excluded[iter.target()]) {\n+ 2012 *edge = iter.target();\n+ 2013 ++edge;\n+ 2014 }\n+ 2015\n+ 2016 end_[*vertex] = edge - edges_;\n+ 2017\n+ 2018 // Sort the edges\n+ 2019 std::sort(edges_+start_[*vertex], edge);\n+ 2020 }\n+ 2021 noEdges_ = edge-edges_;\n+ 2022 ++endVertex_;\n+ 2023 }\n+ 2024\n+ 2025 template\n+ 2026 inline std::size_t VertexPropertiesGraph::noEdges() const\n+ 2027 {\n+ 2028 return graph_.noEdges();\n+ 2029 }\n+ 2030\n+ 2031 template\n+ 2032 inline typename VertexPropertiesGraph::EdgeIterator\n+ 2033 VertexPropertiesGraph::beginEdges(const VertexDescriptor& source)\n+ 2034 {\n+ 2035 return graph_.beginEdges(source);\n+ 2036 }\n+ 2037\n+ 2038 template\n+ 2039 inline typename VertexPropertiesGraph::EdgeIterator\n+ 2040 VertexPropertiesGraph::endEdges(const VertexDescriptor& source)\n+ 2041 {\n+ 2042 return graph_.endEdges(source);\n+ 2043 }\n+ 2044\n+ 2045 template\n+ 2046 typename VertexPropertiesGraph::ConstEdgeIterator\n+ 2047 inline VertexPropertiesGraph::beginEdges(const VertexDescriptor&\n+source) const\n+ 2048 {\n+ 2049 return graph_.beginEdges(source);\n+ 2050 }\n+ 2051\n+ 2052 template\n+ 2053 typename VertexPropertiesGraph::ConstEdgeIterator\n+ 2054 VertexPropertiesGraph::endEdges(const VertexDescriptor& source)\n+const\n+ 2055 {\n+ 2056 return graph_.endEdges(source);\n+ 2057 }\n+ 2058\n+ 2059 template\n+ 2060 template\n+ 2061 VertexPropertiesGraph::VertexIteratorT\n+ 2062 ::VertexIteratorT(const Father& iter,\n+ 2063 C* graph)\n+ 2064 : Father(iter), graph_(graph)\n+ 2065 {}\n+ 2066\n+ 2067 template\n+ 2068 template\n+ 2069 VertexPropertiesGraph::VertexIteratorT\n+ 2070 ::VertexIteratorT(const Father& iter)\n+ 2071 : Father(iter)\n+ 2072 {}\n+ 2073\n+ 2074 template\n+ 2075 template\n+ 2076 template\n+ 2077 VertexPropertiesGraph::VertexIteratorT\n+ 2078 ::VertexIteratorT(const VertexIteratorT& other)\n+ 2079 : Father(other), graph_(other.graph_)\n+ 2080 {}\n+ 2081\n+ 2082 template\n+ 2083 template\n+ 2084 typename std::conditional::\n+type>::value,\n+ 2085 V&, const V&>::type\n+ 2086 inline VertexPropertiesGraph::VertexIteratorT::properties()\n+const\n+ 2087 {\n+ 2088 return graph_->getVertexProperties(Father::operator*());\n+ 2089 }\n+ 2090\n+ 2091 template\n+ 2092 template\n+ 2093 typename std::conditional::\n+type,\n+ 2094 C>::value,\n+ 2095 typename G::EdgeIterator,\n+ 2096 typename G::ConstEdgeIterator>::type\n+ 2097 inline VertexPropertiesGraph::VertexIteratorT::begin() const\n+ 2098 {\n+ 2099 return graph_->beginEdges(Father::operator*());\n+ 2100 }\n+ 2101\n+ 2102 template\n+ 2103 template\n+ 2104 typename std::conditional::\n+type,\n+ 2105 C>::value,\n+ 2106 typename G::EdgeIterator,\n+ 2107 typename G::ConstEdgeIterator>::type\n+ 2108 inline VertexPropertiesGraph::VertexIteratorT::end() const\n+ 2109 {\n+ 2110 return graph_->endEdges(Father::operator*());\n+ 2111 }\n+ 2112\n+ 2113 template\n+ 2114 inline typename VertexPropertiesGraph::VertexIterator\n+VertexPropertiesGraph::begin()\n+ 2115 {\n+ 2116 return VertexIterator(graph_.begin(), this);\n+ 2117 }\n+ 2118\n+ 2119 template\n+ 2120 inline typename VertexPropertiesGraph::VertexIterator\n+VertexPropertiesGraph::end()\n+ 2121 {\n+ 2122 return VertexIterator(graph_.end());\n+ 2123 }\n+ 2124\n+ 2125\n+ 2126 template\n+ 2127 inline typename VertexPropertiesGraph::ConstVertexIterator\n+VertexPropertiesGraph::begin() const\n+ 2128 {\n+ 2129 return ConstVertexIterator(graph_.begin(), this);\n+ 2130 }\n+ 2131\n+ 2132 template\n+ 2133 inline typename VertexPropertiesGraph::ConstVertexIterator\n+VertexPropertiesGraph::end() const\n+ 2134 {\n+ 2135 return ConstVertexIterator(graph_.end());\n+ 2136 }\n+ 2137\n+ 2138 template\n+ 2139 inline V& VertexPropertiesGraph::getVertexProperties(const\n+VertexDescriptor& vertex)\n+ 2140 {\n+ 2141 return vertexProperties_[vmap_[vertex]];\n+ 2142 }\n+ 2143\n+ 2144 template\n+ 2145 inline const V& VertexPropertiesGraph::getVertexProperties(const\n+VertexDescriptor& vertex) const\n+ 2146 {\n+ 2147 return vertexProperties_[vmap_[vertex]];\n+ 2148 }\n+ 2149\n+ 2150 template\n+ 2151 inline const G& VertexPropertiesGraph::graph() const\n+ 2152 {\n+ 2153 return graph_;\n+ 2154 }\n+ 2155\n+ 2156 template\n+ 2157 inline std::size_t VertexPropertiesGraph::noVertices() const\n+ 2158 {\n+ 2159 return graph_.noVertices();\n+ 2160 }\n+ 2161\n+ 2162\n+ 2163 template\n+ 2164 inline typename VertexPropertiesGraph::VertexDescriptor\n+VertexPropertiesGraph::maxVertex() const\n+ 2165 {\n+ 2166 return graph_.maxVertex();\n+ 2167 }\n+ 2168\n+ 2169 template\n+ 2170 VertexPropertiesGraph::VertexPropertiesGraph(Graph& graph, const\n+VM vmap)\n+ 2171 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex\n+()+1], V())\n+ 2172 {}\n+ 2173\n+ 2174 template\n+ 2175 template\n+ 2176 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n+Father& iter,\n+ 2177 C* graph)\n+ 2178 : Father(iter), graph_(graph)\n+ 2179 {}\n+ 2180\n+ 2181 template\n+ 2182 template\n+ 2183 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n+Father& iter)\n+ 2184 : Father(iter)\n+ 2185 {}\n+ 2186\n+ 2187 template\n+ 2188 template\n+ 2189 template\n+ 2190 PropertiesGraph::EdgeIteratorT::EdgeIteratorT(const\n+EdgeIteratorT& other)\n+ 2191 : Father(other), graph_(other.graph_)\n+ 2192 {}\n+ 2193\n+ 2194\n+ 2195 template\n+ 2196 inline std::size_t PropertiesGraph::noEdges() const\n+ 2197 {\n+ 2198 return graph_.noEdges();\n+ 2199 }\n+ 2200\n+ 2201 template\n+ 2202 template\n+ 2203 inline typename std::conditional::type>::value,E&,const E&>::type\n+ 2204 PropertiesGraph::EdgeIteratorT::properties() const\n+ 2205 {\n+ 2206 return graph_->getEdgeProperties(Father::operator*());\n+ 2207 }\n+ 2208\n+ 2209 template\n+ 2210 inline typename PropertiesGraph::EdgeIterator\n+ 2211 PropertiesGraph::beginEdges(const VertexDescriptor& source)\n+ 2212 {\n+ 2213 return EdgeIterator(graph_.beginEdges(source), this);\n+ 2214 }\n+ 2215\n+ 2216 template\n+ 2217 inline typename PropertiesGraph::EdgeIterator\n+ 2218 PropertiesGraph::endEdges(const VertexDescriptor& source)\n+ 2219 {\n+ 2220 return EdgeIterator(graph_.endEdges(source));\n+ 2221 }\n+ 2222\n+ 2223 template\n+ 2224 typename PropertiesGraph::ConstEdgeIterator\n+ 2225 inline PropertiesGraph::beginEdges(const VertexDescriptor&\n+source) const\n+ 2226 {\n+ 2227 return ConstEdgeIterator(graph_.beginEdges(source), this);\n+ 2228 }\n+ 2229\n+ 2230 template\n+ 2231 typename PropertiesGraph::ConstEdgeIterator\n+ 2232 PropertiesGraph::endEdges(const VertexDescriptor& source)\n+const\n+ 2233 {\n+ 2234 return ConstEdgeIterator(graph_.endEdges(source));\n+ 2235 }\n+ 2236\n+ 2237 template\n+ 2238 template\n+ 2239 PropertiesGraph::VertexIteratorT\n+ 2240 ::VertexIteratorT(const Father& iter,\n+ 2241 C* graph)\n+ 2242 : Father(iter), graph_(graph)\n+ 2243 {}\n+ 2244\n+ 2245 template\n+ 2246 template\n+ 2247 PropertiesGraph::VertexIteratorT\n+ 2248 ::VertexIteratorT(const Father& iter)\n+ 2249 : Father(iter)\n+ 2250 {}\n+ 2251\n+ 2252 template\n+ 2253 template\n+ 2254 template\n+ 2255 PropertiesGraph::VertexIteratorT\n+ 2256 ::VertexIteratorT(const VertexIteratorT& other)\n+ 2257 : Father(other), graph_(other.graph_)\n+ 2258 {}\n+ 2259\n+ 2260 template\n+ 2261 template\n+ 2262 inline typename std::conditional::type>::value,\n+ 2263 V&, const V&>::type\n+ 2264 PropertiesGraph::VertexIteratorT::properties() const\n+ 2265 {\n+ 2266 return graph_->getVertexProperties(Father::operator*());\n+ 2267 }\n+ 2268\n+ 2269 template\n+ 2270 template\n+ 2271 inline typename PropertiesGraph::template EdgeIteratorT\n+ 2272 PropertiesGraph::VertexIteratorT::begin() const\n+ 2273 {\n+ 2274 return graph_->beginEdges(Father::operator*());\n+ 2275 }\n+ 2276\n+ 2277 template\n+ 2278 template\n+ 2279 inline typename PropertiesGraph::template EdgeIteratorT\n+ 2280 PropertiesGraph::VertexIteratorT::end() const\n+ 2281 {\n+ 2282 return graph_->endEdges(Father::operator*());\n+ 2283 }\n+ 2284\n+ 2285 template\n+ 2286 inline typename PropertiesGraph::VertexIterator\n+PropertiesGraph::begin()\n+ 2287 {\n+ 2288 return VertexIterator(graph_.begin(), this);\n+ 2289 }\n+ 2290\n+ 2291 template\n+ 2292 inline typename PropertiesGraph::VertexIterator\n+PropertiesGraph::end()\n+ 2293 {\n+ 2294 return VertexIterator(graph_.end());\n+ 2295 }\n+ 2296\n+ 2297\n+ 2298 template\n+ 2299 inline typename PropertiesGraph::ConstVertexIterator\n+PropertiesGraph::begin() const\n+ 2300 {\n+ 2301 return ConstVertexIterator(graph_.begin(), this);\n+ 2302 }\n+ 2303\n+ 2304 template\n+ 2305 inline typename PropertiesGraph::ConstVertexIterator\n+PropertiesGraph::end() const\n+ 2306 {\n+ 2307 return ConstVertexIterator(graph_.end());\n+ 2308 }\n+ 2309\n+ 2310 template\n+ 2311 inline V& PropertiesGraph::getVertexProperties(const\n+VertexDescriptor& vertex)\n+ 2312 {\n+ 2313 return vertexProperties_[vmap_[vertex]];\n+ 2314 }\n+ 2315\n+ 2316 template\n+ 2317 inline const V& PropertiesGraph::getVertexProperties(const\n+VertexDescriptor& vertex) const\n+ 2318 {\n+ 2319 return vertexProperties_[vmap_[vertex]];\n+ 2320 }\n+ 2321\n+ 2322 template\n+ 2323 inline E& PropertiesGraph::getEdgeProperties(const\n+EdgeDescriptor& edge)\n+ 2324 {\n+ 2325 return edgeProperties_[emap_[edge]];\n+ 2326 }\n+ 2327\n+ 2328 template\n+ 2329 inline const E& PropertiesGraph::getEdgeProperties(const\n+EdgeDescriptor& edge) const\n+ 2330 {\n+ 2331 return edgeProperties_[emap_[edge]];\n+ 2332 }\n+ 2333\n+ 2334 template\n+ 2335 inline E& PropertiesGraph::getEdgeProperties(const\n+VertexDescriptor& source,\n+ 2336 const VertexDescriptor& target)\n+ 2337 {\n+ 2338 return getEdgeProperties(graph_.findEdge(source,target));\n+ 2339 }\n+ 2340\n+ 2341 template\n+ 2342 inline const E& PropertiesGraph::getEdgeProperties(const\n+VertexDescriptor& source,\n+ 2343 const VertexDescriptor& target) const\n+ 2344 {\n+ 2345 return getEdgeProperties(graph_.findEdge(source,target));\n+ 2346 }\n+ 2347\n+ 2348 template\n+ 2349 inline const G& PropertiesGraph::graph() const\n+ 2350 {\n+ 2351 return graph_;\n+ 2352 }\n+ 2353\n+ 2354 template\n+ 2355 inline std::size_t PropertiesGraph::noVertices() const\n+ 2356 {\n+ 2357 return graph_.noVertices();\n+ 2358 }\n+ 2359\n+ 2360\n+ 2361 template\n+ 2362 inline typename PropertiesGraph::VertexDescriptor\n+PropertiesGraph::maxVertex() const\n+ 2363 {\n+ 2364 return graph_.maxVertex();\n+ 2365 }\n+ 2366\n+ 2367 template\n+ 2368 PropertiesGraph::PropertiesGraph(Graph& graph, const VM&\n+vmap, const EM& emap)\n+ 2369 : graph_(graph), vmap_(vmap), vertexProperties_(vmap_[graph_.maxVertex\n+()+1], V()),\n+ 2370 emap_(emap), edgeProperties_(graph_.noEdges(), E())\n+ 2371 {}\n+ 2372\n+ 2373 template\n+ 2374 inline int visitNeighbours(const G& graph, const typename G::\n+VertexDescriptor& vertex,\n+ 2375 V& visitor)\n+ 2376 {\n+ 2377 typedef typename G::ConstEdgeIterator iterator;\n+ 2378 const iterator end = graph.endEdges(vertex);\n+ 2379 int noNeighbours=0;\n+ 2380 for(iterator edge = graph.beginEdges(vertex); edge != end; ++edge,\n+++noNeighbours)\n+ 2381 visitor(edge);\n+ 2382 return noNeighbours;\n+ 2383 }\n+ 2384\n+ 2385#endif // DOXYGEN\n+ 2386\n+ 2388 }\n+ 2389}\n+ 2390#endif\n+istlexception.hh\n+Dune::Amg::visitNeighbours\n+int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n+V &visitor)\n+Visit all neighbour vertices of a vertex in a graph.\n+std\n+STL namespace.\n+Dune\n+Definition: allocator.hh:11\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::Amg::MatrixGraph\n+The (undirected) graph of a matrix.\n+Definition: graph.hh:51\n+Dune::Amg::MatrixGraph::MatrixGraph\n+MatrixGraph(Matrix &matrix)\n Constructor.\n-Definition: parameters.hh:34\n-Dune::Amg::AggregationParameters::setMinAggregateSize\n-void setMinAggregateSize(std::size_t size)\n-Set the minimum number of nodes a aggregate has to consist of.\n-Definition: parameters.hh:188\n-Dune::Amg::CoarseningParameters::maxLevel\n-int maxLevel() const\n-Get the maximum number of levels allowed in the hierarchy.\n-Definition: parameters.hh:270\n-Dune::Amg::AggregationParameters::setDefaultValuesIsotropic\n-void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n-Sets reasonable default values for an isotropic problem.\n-Definition: parameters.hh:109\n-Dune::Amg::AggregationParameters::AggregationParameters\n-AggregationParameters()\n+Dune::Amg::MatrixGraph::end\n+VertexIterator end()\n+Get an iterator over the vertices.\n+Dune::Amg::MatrixGraph::maxVertex\n+VertexDescriptor maxVertex() const\n+Get the maximal vertex descriptor.\n+Dune::Amg::MatrixGraph::Matrix\n+M Matrix\n+The type of the matrix we are a graph for.\n+Definition: graph.hh:56\n+Dune::Amg::MatrixGraph::begin\n+ConstVertexIterator begin() const\n+Get an iterator over the vertices.\n+Dune::Amg::MatrixGraph::ConstVertexIterator\n+VertexIteratorT< const MatrixGraph< Matrix > > ConstVertexIterator\n+The constant vertex iterator type.\n+Definition: graph.hh:308\n+Dune::Amg::MatrixGraph::~MatrixGraph\n+~MatrixGraph()\n+Destructor.\n+Dune::Amg::MatrixGraph::EdgeDescriptor\n+std::ptrdiff_t EdgeDescriptor\n+The edge descriptor.\n+Definition: graph.hh:80\n+Dune::Amg::MatrixGraph::endEdges\n+ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::MatrixGraph::VertexDescriptor\n+M::size_type VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:73\n+Dune::Amg::MatrixGraph::matrix\n+const Matrix & matrix() const\n+Get the underlying matrix.\n+Dune::Amg::MatrixGraph::mutableMatrix\n+@ mutableMatrix\n+Definition: graph.hh:86\n+Dune::Amg::MatrixGraph::beginEdges\n+ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::MatrixGraph::end\n+ConstVertexIterator end() const\n+Get an iterator over the vertices.\n+Dune::Amg::MatrixGraph::ConstEdgeIterator\n+EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator\n+The constant edge iterator type.\n+Definition: graph.hh:298\n+Dune::Amg::MatrixGraph::beginEdges\n+EdgeIterator beginEdges(const VertexDescriptor &source)\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::MatrixGraph::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices in the graph.\n+Dune::Amg::MatrixGraph::findEdge\n+EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor\n+&target) const\n+Find the descriptor of an edge.\n+Dune::Amg::MatrixGraph::Weight\n+M::block_type Weight\n+The type of the weights.\n+Definition: graph.hh:66\n+Dune::Amg::MatrixGraph::MutableMatrix\n+std::remove_const< M >::type MutableMatrix\n+The mutable type of the matrix we are a graph for.\n+Definition: graph.hh:61\n+Dune::Amg::MatrixGraph::EdgeIterator\n+EdgeIteratorT< MatrixGraph< Matrix > > EdgeIterator\n+The mutable edge iterator type.\n+Definition: graph.hh:303\n+Dune::Amg::MatrixGraph::VertexIterator\n+VertexIteratorT< MatrixGraph< Matrix > > VertexIterator\n+The mutable vertex iterator type.\n+Definition: graph.hh:313\n+Dune::Amg::MatrixGraph::endEdges\n+EdgeIterator endEdges(const VertexDescriptor &source)\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::MatrixGraph::noEdges\n+std::size_t noEdges() const\n+Get the number of edges in the graph.\n+Dune::Amg::MatrixGraph::matrix\n+Matrix & matrix()\n+Get the underlying matrix.\n+Dune::Amg::MatrixGraph::begin\n+VertexIterator begin()\n+Get an iterator over the vertices.\n+Dune::Amg::MatrixGraph::EdgeIteratorT\n+Iterator over all edges starting from a vertex.\n+Definition: graph.hh:95\n+Dune::Amg::MatrixGraph::EdgeIteratorT::WeightType\n+std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n+value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::\n+type WeightType\n+Definition: graph.hh:156\n+Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n+EdgeIteratorT(const VertexDescriptor &source, const ColIterator &block, const\n+ColIterator &end, const EdgeDescriptor &edge)\n Constructor.\n-Definition: parameters.hh:95\n-Dune::Amg::AggregationParameters::skipIsolated\n-bool skipIsolated() const\n-Whether isolated aggregates will not be represented on the coarse level.\n-Definition: parameters.hh:161\n-Dune::Amg::Parameters::Parameters\n-Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,\n-double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n+Dune::Amg::MatrixGraph::EdgeIteratorT::isMutable\n+@ isMutable\n+whether C is mutable.\n+Definition: graph.hh:112\n+Dune::Amg::MatrixGraph::EdgeIteratorT::target\n+VertexDescriptor target() const\n+The index of the target vertex of the current edge.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator++\n+EdgeIteratorT< C > & operator++()\n+preincrement operator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator!=\n+bool operator!=(const EdgeIteratorT< const typename std::remove_const< C >::\n+type > &other) const\n+Inequality operator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator==\n+bool operator==(const EdgeIteratorT< const typename std::remove_const< C >::\n+type > &other) const\n+Equality operator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n+EdgeIteratorT(const EdgeIteratorT< C1 > &other)\n+Copy Constructor.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator!=\n+bool operator!=(const EdgeIteratorT< typename std::remove_const< C >::type >\n+&other) const\n+Inequality operator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::weight\n+WeightType & weight() const\n+Access the edge weight.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::source\n+VertexDescriptor source() const\n+The index of the source vertex of the current edge.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::ColIterator\n+std::conditional< isMutable &&C::mutableMatrix, typenameMatrix::row_type::\n+Iterator, typenameMatrix::row_type::ConstIterator >::type ColIterator\n+The column iterator of the matrix we use.\n+Definition: graph.hh:120\n+Dune::Amg::MatrixGraph::EdgeIteratorT::ConstContainer\n+const std::remove_const< C >::type ConstContainer\n+The constant type of the container type.\n+Definition: graph.hh:105\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator==\n+bool operator==(const EdgeIteratorT< typename std::remove_const< C >::type >\n+&other) const\n+Equality operator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::EdgeIteratorT\n+EdgeIteratorT(const ColIterator &block)\n+Constructor for the end iterator.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::Weight\n+std::conditional< isMutable &&C::mutableMatrix, typenameM::block_type,\n+consttypenameM::block_type >::type Weight\n+The matrix block type we use as weights.\n+Definition: graph.hh:127\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator*\n+const EdgeDescriptor & operator*() const\n+Get the edge descriptor.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::operator->\n+const EdgeDescriptor * operator->() const\n+Get the edge descriptor.\n+Dune::Amg::MatrixGraph::EdgeIteratorT::MutableContainer\n+std::remove_const< C >::type MutableContainer\n+The mutable type of the container type.\n+Definition: graph.hh:101\n+Dune::Amg::MatrixGraph::VertexIteratorT\n+The vertex iterator type of the graph.\n+Definition: graph.hh:209\n+Dune::Amg::MatrixGraph::VertexIteratorT::begin\n+EdgeIteratorT< C > begin() const\n+Get an iterator over all edges starting at the current vertex.\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator*\n+const VertexDescriptor & operator*() const\n+Get the descriptor of the current vertex.\n+Dune::Amg::MatrixGraph::VertexIteratorT::weight\n+WeightType & weight() const\n+Access the weight of the vertex.\n+Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n+VertexIteratorT(C *graph, const VertexDescriptor ¤t)\n Constructor.\n-Definition: parameters.hh:493\n-Dune::Amg::CoarseningParameters::setCoarsenTarget\n-void setCoarsenTarget(int nodes)\n-Set the maximum number of unknowns allowed on the coarsest level.\n-Definition: parameters.hh:278\n-Dune::Amg::Parameters::setNoPreSmoothSteps\n-void setNoPreSmoothSteps(std::size_t steps)\n-Set the number of presmoothing steps to apply.\n-Definition: parameters.hh:420\n-Dune::Amg::AccumulationMode\n-AccumulationMode\n-Identifiers for the different accumulation modes.\n-Definition: parameters.hh:232\n-Dune::Amg::DependencyParameters::setBeta\n-void setBeta(double b)\n-Set threshold for marking nodes as isolated. The default value is 1.0E-5.\n-Definition: parameters.hh:42\n-Dune::Amg::AggregationParameters::maxDistance\n-std::size_t maxDistance() const\n-Get the maximal distance allowed between two nodes in a aggregate.\n-Definition: parameters.hh:144\n-Dune::Amg::CoarseningParameters::CoarseningParameters\n-CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double\n-minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode\n-accumulate=successiveAccu)\n+Dune::Amg::MatrixGraph::VertexIteratorT::WeightType\n+std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n+value &&C::mutableMatrix, typenameM::block_type, consttypenameM::block_type >::\n+type WeightType\n+Definition: graph.hh:266\n+Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n+VertexIteratorT(const VertexIteratorT< MutableContainer > &other)\n+Dune::Amg::MatrixGraph::VertexIteratorT::MutableContainer\n+std::remove_const< C >::type MutableContainer\n+The mutable type of the container type.\n+Definition: graph.hh:214\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator!=\n+bool operator!=(const VertexIteratorT< MutableContainer > &other) const\n+Inequality operator.\n+Dune::Amg::MatrixGraph::VertexIteratorT::isMutable\n+@ isMutable\n+whether C is mutable.\n+Definition: graph.hh:225\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator==\n+bool operator==(const VertexIteratorT< MutableContainer > &other) const\n+Equality operator.\n+Dune::Amg::MatrixGraph::VertexIteratorT::ConstContainer\n+const std::remove_const< C >::type ConstContainer\n+The constant type of the container type.\n+Definition: graph.hh:218\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator++\n+VertexIteratorT< C > & operator++()\n+Move to the next vertex.\n+Dune::Amg::MatrixGraph::VertexIteratorT::end\n+EdgeIteratorT< C > end() const\n+Get an iterator over all edges starting at the current vertex.\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator==\n+bool operator==(const VertexIteratorT< ConstContainer > &other) const\n+Equality operator.\n+Dune::Amg::MatrixGraph::VertexIteratorT::operator!=\n+bool operator!=(const VertexIteratorT< ConstContainer > &other) const\n+Inequality operator.\n+Dune::Amg::MatrixGraph::VertexIteratorT::VertexIteratorT\n+VertexIteratorT(const VertexDescriptor ¤t)\n+Constructor for the end iterator.\n+Dune::Amg::SubGraph\n+A subgraph of a graph.\n+Definition: graph.hh:443\n+Dune::Amg::SubGraph::findEdge\n+EdgeDescriptor findEdge(const VertexDescriptor &source, const VertexDescriptor\n+&target) const\n+Find the descriptor of an edge.\n+Dune::Amg::SubGraph::maxVertex\n+VertexDescriptor maxVertex() const\n+Get the maximal vertex descriptor.\n+Dune::Amg::SubGraph::getEdgeIndexMap\n+EdgeIndexMap getEdgeIndexMap()\n+Get an edge index map for the graph.\n+Dune::Amg::SubGraph::noEdges\n+std::size_t noEdges() const\n+Get the number of edges in the graph.\n+Dune::Amg::SubGraph::endEdges\n+ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::SubGraph::end\n+ConstVertexIterator end() const\n+Get an iterator over the vertices.\n+Dune::Amg::SubGraph::beginEdges\n+ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n+Get an iterator over the edges starting at a vertex.\n+Dune::Amg::SubGraph::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices in the graph.\n+Dune::Amg::SubGraph::Excluded\n+T Excluded\n+Random access container providing information about which vertices are\n+excluded.\n+Definition: graph.hh:454\n+Dune::Amg::SubGraph::~SubGraph\n+~SubGraph()\n+Destructor.\n+Dune::Amg::SubGraph::ConstEdgeIterator\n+EdgeIterator ConstEdgeIterator\n+The constant edge iterator type.\n+Definition: graph.hh:618\n+Dune::Amg::SubGraph::Graph\n+G Graph\n+The type of the graph we are a sub graph for.\n+Definition: graph.hh:448\n+Dune::Amg::SubGraph::ConstVertexIterator\n+VertexIterator ConstVertexIterator\n+The constant vertex iterator type.\n+Definition: graph.hh:623\n+Dune::Amg::SubGraph::SubGraph\n+SubGraph(const Graph &graph, const T &excluded)\n Constructor.\n-Definition: parameters.hh:356\n-Dune::Amg::Parameters::setGamma\n-void setGamma(std::size_t gamma)\n-Set the value of gamma; 1 for V-cycle, 2 for W-cycle.\n-Definition: parameters.hh:453\n-Dune::Amg::CoarseningParameters::setAccumulate\n-void setAccumulate(bool accu)\n-Definition: parameters.hh:324\n-Dune::Amg::AggregationParameters::setMaxDistance\n-void setMaxDistance(std::size_t distance)\n-Set the maximal distance allowed between two nodes in a aggregate.\n-Definition: parameters.hh:154\n-Dune::Amg::Parameters::debugLevel\n-int debugLevel() const\n-Get the debugging Level.\n-Definition: parameters.hh:411\n-Dune::Amg::Parameters::getNoPostSmoothSteps\n-std::size_t getNoPostSmoothSteps() const\n-Get the number of postsmoothing steps to apply.\n-Definition: parameters.hh:445\n-Dune::Amg::atOnceAccu\n-@ atOnceAccu\n-Accumulate data to one process at once.\n-Definition: parameters.hh:244\n-Dune::Amg::noAccu\n-@ noAccu\n-No data accumulution.\n-Definition: parameters.hh:238\n-Dune::Amg::successiveAccu\n-@ successiveAccu\n-Successively accumulate to fewer processes.\n-Definition: parameters.hh:248\n-Dune\n-Definition: allocator.hh:11\n-Dune::Amg::DependencyParameters\n-Parameters needed to check whether a node depends on another.\n-Definition: parameters.hh:31\n-Dune::Amg::AggregationParameters\n-Parameters needed for the aggregation process.\n-Definition: parameters.hh:84\n-Dune::Amg::CoarseningParameters\n-Parameters for the complete coarsening process.\n-Definition: parameters.hh:258\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n+Dune::Amg::SubGraph::begin\n+ConstVertexIterator begin() const\n+Get an iterator over the vertices.\n+Dune::Amg::SubGraph::VertexDescriptor\n+Graph::VertexDescriptor VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:459\n+Dune::Amg::SubGraph::EdgeDescriptor\n+VertexDescriptor * EdgeDescriptor\n+Definition: graph.hh:461\n+Dune::Amg::SubGraph::EdgeIndexMap\n+An index map for mapping the edges to indices.\n+Definition: graph.hh:470\n+Dune::Amg::SubGraph::EdgeIndexMap::EdgeIndexMap\n+EdgeIndexMap(const EdgeIndexMap &emap)\n+Protect copy construction.\n+Definition: graph.hh:479\n+Dune::Amg::SubGraph::EdgeIndexMap::Category\n+ReadablePropertyMapTag Category\n+Definition: graph.hh:472\n+Dune::Amg::SubGraph::EdgeIndexMap::EdgeIndexMap\n+EdgeIndexMap(const EdgeDescriptor &firstEdge)\n+Definition: graph.hh:474\n+Dune::Amg::SubGraph::EdgeIndexMap::operator[]\n+std::size_t operator[](const EdgeDescriptor &edge) const\n+Definition: graph.hh:483\n+Dune::Amg::SubGraph::EdgeIterator\n+The edge iterator of the graph.\n+Definition: graph.hh:505\n+Dune::Amg::SubGraph::EdgeIterator::dereference\n+const EdgeDescriptor & dereference() const\n+The descriptor of the current edge.\n+Dune::Amg::SubGraph::EdgeIterator::EdgeIterator\n+EdgeIterator(const EdgeDescriptor &edge)\n+Constructor for the end iterator.\n+Dune::Amg::SubGraph::EdgeIterator::equals\n+bool equals(const EdgeIterator &other) const\n+Equality operator.\n+Dune::Amg::SubGraph::EdgeIterator::advance\n+EdgeIterator & advance(std::ptrdiff_t n)\n+Dune::Amg::SubGraph::EdgeIterator::increment\n+EdgeIterator & increment()\n+Preincrement operator.\n+Dune::Amg::SubGraph::EdgeIterator::target\n+const VertexDescriptor & target() const\n+The index of the target vertex of the current edge.\n+Dune::Amg::SubGraph::EdgeIterator::source\n+const VertexDescriptor & source() const\n+The index of the source vertex of the current edge.\n+Dune::Amg::SubGraph::EdgeIterator::decrement\n+EdgeIterator & decrement()\n+Preincrement operator.\n+Dune::Amg::SubGraph::EdgeIterator::distanceTo\n+std::ptrdiff_t distanceTo(const EdgeIterator &other) const\n+Dune::Amg::SubGraph::EdgeIterator::EdgeIterator\n+EdgeIterator(const VertexDescriptor &source, const EdgeDescriptor &edge)\n+Constructor.\n+Dune::Amg::SubGraph::VertexIterator\n+The vertex iterator of the graph.\n+Definition: graph.hh:560\n+Dune::Amg::SubGraph::VertexIterator::VertexIterator\n+VertexIterator(const VertexDescriptor ¤t)\n+Constructor for end iterator.\n+Dune::Amg::SubGraph::VertexIterator::increment\n+VertexIterator & increment()\n+Preincrement operator.\n+Dune::Amg::SubGraph::VertexIterator::begin\n+EdgeIterator begin() const\n+Get an iterator over all edges starting at the current vertex.\n+Dune::Amg::SubGraph::VertexIterator::equals\n+bool equals(const VertexIterator &other) const\n+Equality iterator.\n+Dune::Amg::SubGraph::VertexIterator::VertexIterator\n+VertexIterator(const SubGraph< G, T > *graph, const VertexDescriptor ¤t,\n+const VertexDescriptor &end)\n+Constructor.\n+Dune::Amg::SubGraph::VertexIterator::end\n+EdgeIterator end() const\n+Get an iterator over all edges starting at the current vertex.\n+Dune::Amg::SubGraph::VertexIterator::dereference\n+const VertexDescriptor & dereference() const\n+Get the descriptor of the current vertex.\n+Dune::Amg::VertexPropertiesGraph\n+Attaches properties to the vertices of a graph.\n+Definition: graph.hh:723\n+Dune::Amg::VertexPropertiesGraph::end\n+VertexIterator end()\n+Get an iterator over the vertices.\n+Dune::Amg::VertexPropertiesGraph::graph\n+const Graph & graph() const\n+Get the graph the properties are attached to.\n+Dune::Amg::VertexPropertiesGraph::ConstEdgeIterator\n+Graph::ConstEdgeIterator ConstEdgeIterator\n+The type of the constant edge iterator.\n+Definition: graph.hh:766\n+Dune::Amg::VertexPropertiesGraph::getVertexProperties\n+VertexProperties & getVertexProperties(const VertexDescriptor &vertex)\n+Get the properties associated with a vertex.\n+Dune::Amg::VertexPropertiesGraph::noEdges\n+std::size_t noEdges() const\n+Get the number of edges in the graph.\n+Dune::Amg::VertexPropertiesGraph::EdgeDescriptor\n+Graph::EdgeDescriptor EdgeDescriptor\n+The edge descritor.\n+Definition: graph.hh:738\n+Dune::Amg::VertexPropertiesGraph::endEdges\n+ConstEdgeIterator endEdges(const VertexDescriptor &source) const\n+Get the mutable edge iterator over edges starting at a vertex.\n+Dune::Amg::VertexPropertiesGraph::VertexDescriptor\n+Graph::VertexDescriptor VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:733\n+Dune::Amg::VertexPropertiesGraph::Graph\n+G Graph\n+The graph we attach properties to.\n+Definition: graph.hh:728\n+Dune::Amg::VertexPropertiesGraph::VertexMap\n+VM VertexMap\n+The type of the map for converting the VertexDescriptor to std::size_t.\n+Definition: graph.hh:756\n+Dune::Amg::VertexPropertiesGraph::endEdges\n+EdgeIterator endEdges(const VertexDescriptor &source)\n+Get the mutable edge iterator over edges starting at a vertex.\n+Dune::Amg::VertexPropertiesGraph::beginEdges\n+EdgeIterator beginEdges(const VertexDescriptor &source)\n+Get the mutable edge iterator over edges starting at a vertex.\n+Dune::Amg::VertexPropertiesGraph::VertexProperties\n+VP VertexProperties\n+The type of the properties of the vertices.\n+Definition: graph.hh:743\n+Dune::Amg::VertexPropertiesGraph::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices in the graph.\n+Dune::Amg::VertexPropertiesGraph::beginEdges\n+ConstEdgeIterator beginEdges(const VertexDescriptor &source) const\n+Get the mutable edge iterator over edges starting at a vertex.\n+Dune::Amg::VertexPropertiesGraph::maxVertex\n+VertexDescriptor maxVertex() const\n+Get the maximal vertex descriptor.\n+Dune::Amg::VertexPropertiesGraph::begin\n+VertexIterator begin()\n+Get an iterator over the vertices.\n+Dune::Amg::VertexPropertiesGraph::EdgeIterator\n+Graph::EdgeIterator EdgeIterator\n+The type of the mutable edge iterator.\n+Definition: graph.hh:761\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT\n+Definition: graph.hh:803\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT::EdgeIterator\n+std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n+value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type\n+EdgeIterator\n+The class of the edge iterator.\n+Definition: graph.hh:823\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT::properties\n+std::conditional< std::is_same< C, typenamestd::remove_const< C >::type >::\n+value, VertexProperties &, constVertexProperties & >::type properties() const\n+Get the properties of the current Vertex.\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT::end\n+EdgeIterator end() const\n+Get an iterator over the edges starting from the current vertex.\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT::Father\n+std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n+value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::\n+type Father\n+The father class.\n+Definition: graph.hh:814\n+Dune::Amg::VertexPropertiesGraph::VertexIteratorT::begin\n+EdgeIterator begin() const\n+Get an iterator over the edges starting from the current vertex.\n+Dune::Amg::PropertiesGraph\n+Attaches properties to the edges and vertices of a graph.\n+Definition: graph.hh:978\n+Dune::Amg::PropertiesGraph::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices in the graph.\n+Dune::Amg::PropertiesGraph::EdgeDescriptor\n+Graph::EdgeDescriptor EdgeDescriptor\n+The edge descritor.\n+Definition: graph.hh:993\n+Dune::Amg::PropertiesGraph::getEdgeProperties\n+const EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const\n+VertexDescriptor &target) const\n+Get the properties associated with a edge.\n+Dune::Amg::PropertiesGraph::getEdgeProperties\n+const EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge) const\n+Get the properties associated with a edge.\n+Dune::Amg::PropertiesGraph::graph\n+const Graph & graph() const\n+Get the graph the properties are attached to.\n+Dune::Amg::PropertiesGraph::maxVertex\n+VertexDescriptor maxVertex() const\n+Get the maximal vertex descriptor.\n+Dune::Amg::PropertiesGraph::Graph\n+G Graph\n+The graph we attach properties to.\n+Definition: graph.hh:983\n+Dune::Amg::PropertiesGraph::EdgeMap\n+EM EdgeMap\n+The type of the map for converting the EdgeDescriptor to std::size_t.\n+Definition: graph.hh:1030\n+Dune::Amg::PropertiesGraph::VertexMap\n+VM VertexMap\n+The type of the map for converting the VertexDescriptor to std::size_t.\n+Definition: graph.hh:1011\n+Dune::Amg::PropertiesGraph::VertexProperties\n+VP VertexProperties\n+The type of the properties of the vertices.\n+Definition: graph.hh:998\n+Dune::Amg::PropertiesGraph::noEdges\n+std::size_t noEdges() const\n+Get the number of edges in the graph.\n+Dune::Amg::PropertiesGraph::EdgeProperties\n+EP EdgeProperties\n+The type of the properties of the edges;.\n+Definition: graph.hh:1016\n+Dune::Amg::PropertiesGraph::getEdgeProperties\n+EdgeProperties & getEdgeProperties(const VertexDescriptor &source, const\n+VertexDescriptor &target)\n+Get the properties associated with a edge.\n+Dune::Amg::PropertiesGraph::getEdgeProperties\n+EdgeProperties & getEdgeProperties(const EdgeDescriptor &edge)\n+Get the properties associated with a edge.\n+Dune::Amg::PropertiesGraph::VertexDescriptor\n+Graph::VertexDescriptor VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:988\n+Dune::Amg::PropertiesGraph::PropertiesGraph\n+PropertiesGraph(Graph &graph, const VertexMap &vmap=VertexMap(), const EdgeMap\n+&emap=EdgeMap())\n+Constructor.\n+Dune::Amg::PropertiesGraph::EdgeIteratorT\n+Definition: graph.hh:1038\n+Dune::Amg::PropertiesGraph::EdgeIteratorT::Father\n+std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n+value, typenameGraph::EdgeIterator, typenameGraph::ConstEdgeIterator >::type\n+Father\n+The father class.\n+Definition: graph.hh:1050\n+Dune::Amg::PropertiesGraph::VertexIteratorT\n+Definition: graph.hh:1140\n+Dune::Amg::PropertiesGraph::VertexIteratorT::Father\n+std::conditional< std::is_same< typenamestd::remove_const< C >::type, C >::\n+value, typenameGraph::VertexIterator, typenameGraph::ConstVertexIterator >::\n+type Father\n+The father class.\n+Definition: graph.hh:1151\n+Dune::Amg::GraphVertexPropertiesSelector\n+Wrapper to access the internal edge properties of a graph via operator[]()\n+Definition: graph.hh:1361\n+Dune::Amg::GraphVertexPropertiesSelector::GraphVertexPropertiesSelector\n+GraphVertexPropertiesSelector(G &g)\n+Constructor.\n+Definition: graph.hh:1380\n+Dune::Amg::GraphVertexPropertiesSelector::operator[]\n+VertexProperties & operator[](const Vertex &vertex) const\n+Get the properties associated to a vertex.\n+Definition: graph.hh:1395\n+Dune::Amg::GraphVertexPropertiesSelector::Graph\n+G Graph\n+The type of the graph with internal properties.\n+Definition: graph.hh:1366\n+Dune::Amg::GraphVertexPropertiesSelector::VertexProperties\n+G::VertexProperties VertexProperties\n+The type of the vertex properties.\n+Definition: graph.hh:1370\n+Dune::Amg::GraphVertexPropertiesSelector::GraphVertexPropertiesSelector\n+GraphVertexPropertiesSelector()\n+Default constructor.\n+Definition: graph.hh:1386\n+Dune::Amg::GraphVertexPropertiesSelector::Vertex\n+G::VertexDescriptor Vertex\n+The vertex descriptor.\n+Definition: graph.hh:1374\n+Dune::Amg::GraphEdgePropertiesSelector\n+Wrapper to access the internal vertex properties of a graph via operator[]()\n+Definition: graph.hh:1409\n+Dune::Amg::GraphEdgePropertiesSelector::operator[]\n+EdgeProperties & operator[](const Edge &edge) const\n+Get the properties associated to a vertex.\n+Definition: graph.hh:1442\n+Dune::Amg::GraphEdgePropertiesSelector::EdgeProperties\n+G::EdgeProperties EdgeProperties\n+The type of the vertex properties.\n+Definition: graph.hh:1418\n+Dune::Amg::GraphEdgePropertiesSelector::Edge\n+G::EdgeDescriptor Edge\n+The edge descriptor.\n+Definition: graph.hh:1422\n+Dune::Amg::GraphEdgePropertiesSelector::GraphEdgePropertiesSelector\n+GraphEdgePropertiesSelector()\n+Default constructor.\n+Definition: graph.hh:1434\n+Dune::Amg::GraphEdgePropertiesSelector::Graph\n+G Graph\n+The type of the graph with internal properties.\n+Definition: graph.hh:1414\n+Dune::Amg::GraphEdgePropertiesSelector::GraphEdgePropertiesSelector\n+GraphEdgePropertiesSelector(G &g)\n+Constructor.\n+Definition: graph.hh:1428\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00137.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00137.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: indicescoarsener.hh File Reference\n+dune-istl: fastamg.hh File Reference\n \n \n \n \n \n \n \n@@ -64,52 +64,75 @@\n \n \n \n \n+
    fastamg.hh File Reference
    \n \n
    \n \n-

    Provides a class for building the index set and remote indices on the coarse level. \n+

    A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers. \n More...

    \n-
    #include <dune/common/parallel/indicessyncer.hh>
    \n-#include <vector>
    \n-#include "renumberer.hh"
    \n-#include <dune/istl/owneroverlapcopy.hh>
    \n-#include "pinfo.hh"
    \n+
    #include <memory>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/istl/paamg/smoother.hh>
    \n+#include <dune/istl/paamg/transfer.hh>
    \n+#include <dune/istl/paamg/matrixhierarchy.hh>
    \n+#include <dune/istl/solvers.hh>
    \n+#include <dune/istl/scalarproducts.hh>
    \n+#include <dune/istl/superlu.hh>
    \n+#include <dune/istl/umfpack.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/istl/io.hh>
    \n+#include <dune/istl/preconditioners.hh>
    \n+#include "fastamgsmoother.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::Amg::IndicesCoarsener< T, E >
     
    class  Dune::Amg::ParallelIndicesCoarsener< T, E >
     
    class  Dune::Amg::IndicesCoarsener< OwnerOverlapCopyCommunication< G, L >, E >
     Coarsen Indices in the parallel case. More...
     
    class  Dune::Amg::IndicesCoarsener< SequentialInformation, E >
     Coarsen Indices in the sequential case. More...
    class  Dune::Amg::FastAMG< M, X, PI, A >
     A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth. More...
     
    \n \n \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n

    \n+Macros

    #define DIRECTSOLVER   SuperLU
     
    \n

    Detailed Description

    \n-

    Provides a class for building the index set and remote indices on the coarse level.

    \n+

    A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers.

    \n
    Author
    Markus Blatt
    \n-
    \n+

    Macro Definition Documentation

    \n+\n+

    ◆ DIRECTSOLVER

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+
    #define DIRECTSOLVER   SuperLU
    \n+
    \n+\n+
    \n+
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,43 +5,52 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces\n-indicescoarsener.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides a class for building the index set and remote indices on the coarse\n-level. More...\n-#include \n-#include \n-#include \"renumberer.hh\"\n-#include \n-#include \"pinfo.hh\"\n+Classes | Namespaces | Macros\n+fastamg.hh File Reference\n+A fast AMG method, that currently only allows only Gauss-Seidel smoothing and\n+is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep\n+with the defect calculation to reduce memory transfers. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"fastamgsmoother.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::IndicesCoarsener<_T,_E_>\n-\u00a0\n-class \u00a0Dune::Amg::ParallelIndicesCoarsener<_T,_E_>\n-\u00a0\n-class \u00a0Dune::Amg::IndicesCoarsener<_OwnerOverlapCopyCommunication<_G,_L_>,_E_>\n-\u00a0 Coarsen Indices in the parallel case. More...\n-\u00a0\n-class \u00a0Dune::Amg::IndicesCoarsener<_SequentialInformation,_E_>\n-\u00a0 Coarsen Indices in the sequential case. More...\n+class \u00a0Dune::Amg::FastAMG<_M,_X,_PI,_A_>\n+\u00a0 A fast (sequential) algebraic multigrid based on agglomeration that\n+ saves memory bandwidth. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n+ Macros\n+#define\u00a0DIRECTSOLVER\u00a0\u00a0\u00a0SuperLU\n+\u00a0\n ***** Detailed Description *****\n-Provides a class for building the index set and remote indices on the coarse\n-level.\n+A fast AMG method, that currently only allows only Gauss-Seidel smoothing and\n+is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep\n+with the defect calculation to reduce memory transfers.\n Author\n Markus Blatt\n+***** Macro Definition Documentation *****\n+***** \u25c6\u00a0DIRECTSOLVER *****\n+#define DIRECTSOLVER\u00a0\u00a0\u00a0SuperLU\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00137_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00137_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: indicescoarsener.hh Source File\n+dune-istl: fastamg.hh Source File\n \n \n \n \n \n \n \n@@ -62,402 +62,639 @@\n \n
    \n \n
    \n \n
    \n-
    indicescoarsener.hh
    \n+
    fastamg.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_INDICESCOARSENER_HH
    \n-
    6#define DUNE_AMG_INDICESCOARSENER_HH
    \n+
    5#ifndef DUNE_ISTL_FASTAMG_HH
    \n+
    6#define DUNE_ISTL_FASTAMG_HH
    \n
    7
    \n-
    8#include <dune/common/parallel/indicessyncer.hh>
    \n-
    9#include <vector>
    \n-
    10#include "renumberer.hh"
    \n-
    11
    \n-
    12#if HAVE_MPI
    \n-\n-
    14#endif
    \n-
    15
    \n-
    16#include "pinfo.hh"
    \n-
    17
    \n-
    18namespace Dune
    \n-
    19{
    \n-
    20 namespace Amg
    \n-
    21 {
    \n-
    22
    \n-
    34 template<typename T, typename E>
    \n-\n-
    36 {};
    \n-
    37
    \n-
    38
    \n-
    39#if HAVE_MPI
    \n-
    40
    \n-
    41 template<typename T, typename E>
    \n-\n-
    43 {
    \n-
    44 public:
    \n-\n-
    49
    \n-\n-
    54
    \n-
    55 typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;
    \n-
    56
    \n-
    60 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n-
    61
    \n-
    65 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
    \n-
    66
    \n-
    70 typedef typename LocalIndex::Attribute Attribute;
    \n-
    71
    \n-
    75 typedef Dune::RemoteIndices<ParallelIndexSet> RemoteIndices;
    \n-
    76
    \n-
    88 template<typename Graph, typename VM>
    \n-
    89 static typename Graph::VertexDescriptor
    \n-\n-
    91 Graph& fineGraph,
    \n-
    92 VM& visitedMap,
    \n-\n-
    94 ParallelInformation& coarseInfo,
    \n-
    95 typename Graph::VertexDescriptor noAggregates);
    \n-
    96
    \n-
    97 private:
    \n-
    98 template<typename G, typename I>
    \n-
    99 class ParallelAggregateRenumberer : public AggregateRenumberer<G>
    \n-
    100 {
    \n-
    101 typedef typename G::VertexDescriptor Vertex;
    \n-
    102
    \n-
    103 typedef I GlobalLookupIndexSet;
    \n-
    104
    \n-
    105 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
    \n-
    106
    \n-
    107 typedef typename IndexPair::GlobalIndex GlobalIndex;
    \n-
    108
    \n-
    109 public:
    \n-\n-
    111 : AggregateRenumberer<G>(aggregates), isPublic_(false), lookup_(lookup),
    \n-
    112 globalIndex_(std::numeric_limits<GlobalIndex>::max())
    \n-
    113 {}
    \n-
    114
    \n+
    8#include <memory>
    \n+
    9#include <dune/common/exceptions.hh>
    \n+
    10#include <dune/common/typetraits.hh>
    \n+\n+\n+\n+
    14#include <dune/istl/solvers.hh>
    \n+\n+
    16#include <dune/istl/superlu.hh>
    \n+
    17#include <dune/istl/umfpack.hh>
    \n+\n+
    19#include <dune/istl/io.hh>
    \n+\n+
    21
    \n+
    22#include "fastamgsmoother.hh"
    \n+
    23
    \n+
    32namespace Dune
    \n+
    33{
    \n+
    34 namespace Amg
    \n+
    35 {
    \n+
    58 template<class M, class X, class PI=SequentialInformation, class A=std::allocator<X> >
    \n+
    59 class FastAMG : public Preconditioner<X,X>
    \n+
    60 {
    \n+
    61 public:
    \n+
    63 typedef M Operator;
    \n+\n+\n+\n+
    75
    \n+
    77 typedef X Domain;
    \n+
    79 typedef X Range;
    \n+\n+
    82
    \n+
    90 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n+
    91 const Parameters& parms,
    \n+
    92 bool symmetric=true);
    \n+
    93
    \n+
    105 template<class C>
    \n+
    106 FastAMG(const Operator& fineOperator, const C& criterion,
    \n+
    107 const Parameters& parms=Parameters(),
    \n+
    108 bool symmetric=true,
    \n+\n+
    110
    \n+
    114 FastAMG(const FastAMG& amg);
    \n
    115
    \n-
    116 void operator()(const typename G::ConstEdgeIterator& edge)
    \n-
    117 {
    \n-\n-
    119 const IndexPair* pair= lookup_.pair(edge.target());
    \n-
    120 if(pair!=0) {
    \n-
    121 globalIndex(pair->global());
    \n-
    122 attribute(pair->local().attribute());
    \n-
    123 isPublic(pair->local().isPublic());
    \n-
    124 }
    \n-
    125 }
    \n-
    126
    \n-
    127 Vertex operator()([[maybe_unused]] const GlobalIndex& global)
    \n-
    128 {
    \n-
    129 Vertex current = this->number_;
    \n-
    130 this->operator++();
    \n-
    131 return current;
    \n-
    132 }
    \n-
    133
    \n-
    134 bool isPublic()
    \n-
    135 {
    \n-
    136 return isPublic_;
    \n-
    137 }
    \n-
    138
    \n-
    139 void isPublic(bool b)
    \n-
    140 {
    \n-
    141 isPublic_ = isPublic_ || b;
    \n-
    142 }
    \n-
    143
    \n-
    144 void reset()
    \n-
    145 {
    \n-
    146 globalIndex_ = std::numeric_limits<GlobalIndex>::max();
    \n-
    147 isPublic_=false;
    \n-
    148 }
    \n-
    149
    \n-
    150 void attribute(const Attribute& attribute)
    \n-
    151 {
    \n-
    152 attribute_=attribute;
    \n-
    153 }
    \n+
    117 void pre(Domain& x, Range& b);
    \n+
    118
    \n+
    120 void apply(Domain& v, const Range& d);
    \n+
    121
    \n+\n+
    124 {
    \n+\n+
    126 }
    \n+
    127
    \n+
    129 void post(Domain& x);
    \n+
    130
    \n+
    135 template<class A1>
    \n+
    136 void getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont);
    \n+
    137
    \n+
    138 std::size_t levels();
    \n+
    139
    \n+
    140 std::size_t maxlevels();
    \n+
    141
    \n+\n+
    151 {
    \n+
    152 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
    \n+
    153 }
    \n
    154
    \n-\n-
    156 {
    \n-
    157 return attribute_;
    \n-
    158 }
    \n-
    159
    \n-
    160 const GlobalIndex& globalIndex() const
    \n-
    161 {
    \n-
    162 return globalIndex_;
    \n-
    163 }
    \n-
    164
    \n-
    165 void globalIndex(const GlobalIndex& global)
    \n-
    166 {
    \n-
    167 globalIndex_ = global;
    \n-
    168 }
    \n-
    169
    \n-
    170 private:
    \n-
    171 bool isPublic_;
    \n-
    172 Attribute attribute_;
    \n-
    173 const GlobalLookupIndexSet& lookup_;
    \n-
    174 GlobalIndex globalIndex_;
    \n-
    175 };
    \n-
    176
    \n-
    177 template<typename Graph, typename VM, typename I>
    \n-
    178 static void buildCoarseIndexSet(const ParallelInformation& pinfo,
    \n-
    179 Graph& fineGraph,
    \n-
    180 VM& visitedMap,
    \n-\n-
    182 ParallelIndexSet& coarseIndices,
    \n-
    183 ParallelAggregateRenumberer<Graph,I>& renumberer);
    \n-
    184
    \n-
    185 template<typename Graph,typename I>
    \n-
    186 static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
    \n-\n-
    188 ParallelIndexSet& coarseIndices,
    \n-
    189 RemoteIndices& coarseRemote,
    \n-
    190 ParallelAggregateRenumberer<Graph,I>& renumberer);
    \n-
    191
    \n-
    192 };
    \n-
    193
    \n-
    197 template<typename G, typename L, typename E>
    \n-\n-
    199 : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
    \n-
    200 {};
    \n-
    201
    \n-
    202
    \n-
    203#endif
    \n-
    204
    \n-
    211 template<typename E>
    \n-\n-
    213 {
    \n-
    214 public:
    \n-
    215 template<typename Graph, typename VM>
    \n-
    216 static typename Graph::VertexDescriptor
    \n-
    217 coarsen(const SequentialInformation & fineInfo,
    \n-
    218 Graph& fineGraph,
    \n-
    219 VM& visitedMap,
    \n-\n-
    221 SequentialInformation& coarseInfo,
    \n-
    222 typename Graph::VertexDescriptor noAggregates);
    \n-
    223 };
    \n-
    224
    \n-
    225#if HAVE_MPI
    \n-
    226 template<typename T, typename E>
    \n-
    227 template<typename Graph, typename VM>
    \n-
    228 inline typename Graph::VertexDescriptor
    \n-\n-
    230 Graph& fineGraph,
    \n-
    231 VM& visitedMap,
    \n-\n-
    233 ParallelInformation& coarseInfo,
    \n-
    234 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
    \n-
    235 {
    \n-
    236 ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
    \n-
    237 buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,
    \n-
    238 coarseInfo.indexSet(), renumberer);
    \n-
    239 buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(),
    \n-
    240 coarseInfo.remoteIndices(), renumberer);
    \n-
    241
    \n-
    242 return renumberer;
    \n-
    243 }
    \n-
    244
    \n-
    245 template<typename T, typename E>
    \n-
    246 template<typename Graph, typename VM, typename I>
    \n-
    247 void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
    \n-
    248 Graph& fineGraph,
    \n-
    249 VM& visitedMap,
    \n-\n-
    251 ParallelIndexSet& coarseIndices,
    \n-
    252 ParallelAggregateRenumberer<Graph,I>& renumberer)
    \n-
    253 {
    \n-
    254 // fineGraph is the local subgraph corresponding to the vertices the process owns.
    \n-
    255 // i.e. no overlap/copy vertices can be visited traversing the graph
    \n-
    256 typedef typename Graph::ConstVertexIterator Iterator;
    \n-
    257 typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
    \n-
    258
    \n-
    259 Iterator end = fineGraph.end();
    \n-
    260 const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
    \n-
    261
    \n-
    262 coarseIndices.beginResize();
    \n-
    263
    \n-
    264 // Setup the coarse index set and renumber the aggregate consecutively
    \n-
    265 // ascending from zero according to the minimum global index belonging
    \n-
    266 // to the aggregate
    \n-
    267 for(Iterator index = fineGraph.begin(); index != end; ++index) {
    \n-\n-
    269 // Isolated vertices will not be represented on the next level.
    \n-
    270 // These should only be there if skipIsolated is activiated in
    \n-
    271 // the coarsening criterion as otherwise they will be aggregated
    \n-
    272 // and should have real aggregate number in the map right now.
    \n-
    273 if(!get(visitedMap, *index)) {
    \n-
    274 // This vertex was not visited by breadthFirstSearch yet.
    \n-
    275 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
    \n-
    276 const IndexPair* pair= lookup.pair(*index);
    \n-
    277
    \n-
    278 renumberer.reset(); // reset attribute and global index.
    \n-
    279 if(pair!=0) {
    \n-
    280 // vertex is in the index set. Note that not all vertices have
    \n-
    281 // to be in the index set, just the ones where communication
    \n-
    282 // will happen.
    \n-
    283 assert(!ExcludedAttributes::contains(pair->local().attribute()));
    \n-
    284 renumberer.attribute(pair->local().attribute());
    \n-
    285 renumberer.isPublic(pair->local().isPublic());
    \n-
    286 renumberer.globalIndex(pair->global());
    \n-
    287 }
    \n-
    288
    \n-
    289 // Reconstruct aggregate and mark vertices as visited
    \n-
    290 aggregates.template breadthFirstSearch<false>(*index, aggregates[*index],
    \n-
    291 fineGraph, renumberer, visitedMap);
    \n-
    292
    \n-
    293 if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()) {
    \n-
    294 // vertex is in the index set.
    \n-
    295 //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
    \n-
    296 coarseIndices.add(renumberer.globalIndex(),
    \n-
    297 LocalIndex(renumberer, renumberer.attribute(),
    \n-
    298 renumberer.isPublic()));
    \n-
    299 }
    \n-
    300
    \n-
    301 aggregates[*index] = renumberer;
    \n-
    302 ++renumberer;
    \n-
    303 }
    \n-
    304 }
    \n-
    305
    \n-
    306 coarseIndices.endResize();
    \n-
    307
    \n-
    308 assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
    \n-
    309
    \n-
    310 // Reset the visited flags
    \n-
    311 for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
    \n-
    312 put(visitedMap, *vertex, false);
    \n-
    313 }
    \n-
    314
    \n-
    315 template<typename T, typename E>
    \n-
    316 template<typename Graph, typename I>
    \n-
    317 void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
    \n-
    318 const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
    \n-
    319 ParallelIndexSet& coarseIndices,
    \n-
    320 RemoteIndices& coarseRemote,
    \n-
    321 ParallelAggregateRenumberer<Graph,I>& renumberer)
    \n-
    322 {
    \n-
    323 std::vector<char> attributes(static_cast<std::size_t>(renumberer));
    \n-
    324
    \n-
    325 GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
    \n-
    326
    \n-
    327 typedef typename RemoteIndices::const_iterator Iterator;
    \n-
    328 Iterator end = fineRemote.end();
    \n-
    329
    \n-
    330 for(Iterator neighbour = fineRemote.begin();
    \n-
    331 neighbour != end; ++neighbour) {
    \n-
    332 int process = neighbour->first;
    \n-
    333
    \n-
    334 assert(neighbour->second.first==neighbour->second.second);
    \n-
    335
    \n-
    336 // Mark all as not known
    \n-
    337 typedef typename std::vector<char>::iterator CIterator;
    \n-
    338
    \n-
    339 for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
    \n-
    340 *iter = std::numeric_limits<char>::max();
    \n+
    159 bool usesDirectCoarseLevelSolver() const;
    \n+
    160
    \n+
    161 private:
    \n+
    168 template<class C>
    \n+
    169 void createHierarchies(C& criterion,
    \n+
    170 const std::shared_ptr<const Operator>& matrixptr,
    \n+
    171 const PI& pinfo);
    \n+
    172
    \n+
    179 struct LevelContext
    \n+
    180 {
    \n+\n+\n+
    192 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
    \n+
    196 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
    \n+\n+\n+\n+
    212 std::size_t level;
    \n+
    213 };
    \n+
    214
    \n+
    216 void mgc(LevelContext& levelContext, Domain& x, const Range& b);
    \n+
    217
    \n+
    224 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);
    \n+
    225
    \n+
    232 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);
    \n+
    233
    \n+
    240 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,
    \n+
    241 Domain& fineX);
    \n+
    242
    \n+
    247 bool moveToCoarseLevel(LevelContext& levelContext);
    \n+
    248
    \n+
    253 void initIteratorsWithFineLevel(LevelContext& levelContext);
    \n+
    254
    \n+
    256 std::shared_ptr<OperatorHierarchy> matrices_;
    \n+
    258 std::shared_ptr<CoarseSolver> solver_;
    \n+
    260 std::shared_ptr<Hierarchy<Range,A>> rhs_;
    \n+
    262 std::shared_ptr<Hierarchy<Domain,A>> lhs_;
    \n+
    264 std::shared_ptr<Hierarchy<Domain,A>> residual_;
    \n+
    265
    \n+\n+
    269 std::shared_ptr<ScalarProduct> scalarProduct_;
    \n+
    271 std::size_t gamma_;
    \n+
    273 std::size_t preSteps_;
    \n+
    275 std::size_t postSteps_;
    \n+
    276 std::size_t level;
    \n+
    277 bool buildHierarchy_;
    \n+
    278 bool symmetric;
    \n+
    279 bool coarsesolverconverged;
    \n+\n+
    281 typedef std::shared_ptr<Smoother> SmootherPointer;
    \n+
    282 SmootherPointer coarseSmoother_;
    \n+
    284 std::size_t verbosity_;
    \n+
    285 };
    \n+
    286
    \n+
    287 template<class M, class X, class PI, class A>
    \n+\n+
    289 : matrices_(amg.matrices_), solver_(amg.solver_),
    \n+
    290 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),
    \n+
    291 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
    \n+
    292 symmetric(amg.symmetric), coarsesolverconverged(amg.coarsesolverconverged),
    \n+
    293 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)
    \n+
    294 {}
    \n+
    295
    \n+
    296 template<class M, class X, class PI, class A>
    \n+\n+
    298 const Parameters& parms, bool symmetric_)
    \n+
    299 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),
    \n+
    300 rhs_(), lhs_(), residual_(), scalarProduct_(),
    \n+
    301 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
    \n+
    302 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
    \n+
    303 symmetric(symmetric_), coarsesolverconverged(true),
    \n+
    304 coarseSmoother_(), verbosity_(parms.debugLevel())
    \n+
    305 {
    \n+
    306 if(preSteps_>1||postSteps_>1)
    \n+
    307 {
    \n+
    308 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
    \n+
    309 preSteps_=postSteps_=0;
    \n+
    310 }
    \n+
    311 assert(matrices_->isBuilt());
    \n+
    312 static_assert(std::is_same<PI,SequentialInformation>::value,
    \n+
    313 "Currently only sequential runs are supported");
    \n+
    314 }
    \n+
    315 template<class M, class X, class PI, class A>
    \n+
    316 template<class C>
    \n+\n+
    318 const C& criterion,
    \n+
    319 const Parameters& parms,
    \n+
    320 bool symmetric_,
    \n+
    321 const PI& pinfo)
    \n+
    322 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_(parms.getGamma()),
    \n+
    323 preSteps_(parms.getNoPreSmoothSteps()), postSteps_(parms.getNoPostSmoothSteps()),
    \n+
    324 buildHierarchy_(true),
    \n+
    325 symmetric(symmetric_), coarsesolverconverged(true),
    \n+
    326 coarseSmoother_(), verbosity_(criterion.debugLevel())
    \n+
    327 {
    \n+
    328 if(preSteps_>1||postSteps_>1)
    \n+
    329 {
    \n+
    330 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
    \n+
    331 preSteps_=postSteps_=1;
    \n+
    332 }
    \n+
    333 static_assert(std::is_same<PI,SequentialInformation>::value,
    \n+
    334 "Currently only sequential runs are supported");
    \n+
    335 // TODO: reestablish compile time checks.
    \n+
    336 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
    \n+
    337 // "Matrix and Solver must match in terms of category!");
    \n+
    338 auto matrixptr = stackobject_to_shared_ptr(matrix);
    \n+
    339 createHierarchies(criterion, matrixptr, pinfo);
    \n+
    340 }
    \n
    341
    \n-
    342 auto riEnd = neighbour->second.second->end();
    \n-
    343
    \n-
    344 for(auto index = neighbour->second.second->begin();
    \n-
    345 index != riEnd; ++index) {
    \n-
    346 if(!E::contains(index->localIndexPair().local().attribute()) &&
    \n-
    347 aggregates[index->localIndexPair().local()] !=
    \n-\n-
    349 {
    \n-
    350 assert(aggregates[index->localIndexPair().local()]<attributes.size());
    \n-
    351 if (attributes[aggregates[index->localIndexPair().local()]] != 3)
    \n-
    352 attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
    \n-
    353 }
    \n-
    354 }
    \n-
    355
    \n-
    356 // Build remote index list
    \n-
    357 typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
    \n-
    358 typedef typename RemoteIndices::RemoteIndex RemoteIndex;
    \n-
    359 typedef typename ParallelIndexSet::const_iterator IndexIterator;
    \n-
    360
    \n-
    361 Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
    \n-
    362
    \n-
    363 IndexIterator iend = coarseIndices.end();
    \n-
    364 for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
    \n-
    365 if(attributes[index->local()] != std::numeric_limits<char>::max()) {
    \n-
    366 // remote index is present
    \n-
    367 coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
    \n-
    368 }
    \n-
    369 //std::cout<<coarseRemote<<std::endl;
    \n-
    370 }
    \n-
    371
    \n-
    372 // The number of neighbours should not change!
    \n-
    373 assert(coarseRemote.neighbours()==fineRemote.neighbours());
    \n+
    342 template<class M, class X, class PI, class A>
    \n+
    343 template<class C>
    \n+
    344 void FastAMG<M,X,PI,A>::createHierarchies(C& criterion,
    \n+
    345 const std::shared_ptr<const Operator>& matrixptr,
    \n+
    346 const PI& pinfo)
    \n+
    347 {
    \n+
    348 Timer watch;
    \n+
    349 matrices_ = std::make_shared<OperatorHierarchy>(
    \n+
    350 std::const_pointer_cast<Operator>(matrixptr),
    \n+
    351 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
    \n+
    352
    \n+
    353 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
    \n+
    354
    \n+
    355 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n+
    356 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    357
    \n+
    358 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()) {
    \n+
    359 // We have the carsest level. Create the coarse Solver
    \n+
    360 typedef typename SmootherTraits<Smoother>::Arguments SmootherArgs;
    \n+
    361 SmootherArgs sargs;
    \n+
    362 sargs.iterations = 1;
    \n+
    363
    \n+\n+
    365 cargs.setArgs(sargs);
    \n+
    366 if(matrices_->redistributeInformation().back().isSetup()) {
    \n+
    367 // Solve on the redistributed partitioning
    \n+
    368 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
    \n+
    369 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
    \n+
    370 }else{
    \n+
    371 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
    \n+
    372 cargs.setComm(*matrices_->parallelInformation().coarsest());
    \n+
    373 }
    \n
    374
    \n-
    375 // snyc the index set and the remote indices to recompute missing
    \n-
    376 // indices
    \n-
    377 IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
    \n-
    378 syncer.sync(renumberer);
    \n-
    379
    \n-
    380 }
    \n-
    381
    \n-
    382#endif
    \n-
    383
    \n-
    384 template<typename E>
    \n-
    385 template<typename Graph, typename VM>
    \n-
    386 typename Graph::VertexDescriptor
    \n-\n-
    388 [[maybe_unused]] const SequentialInformation& fineInfo,
    \n-
    389 [[maybe_unused]] Graph& fineGraph,
    \n-
    390 [[maybe_unused]] VM& visitedMap,
    \n-
    391 [[maybe_unused]] AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
    \n-
    392 [[maybe_unused]] SequentialInformation& coarseInfo,
    \n-
    393 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
    \n-
    394 {
    \n-
    395 return noAggregates;
    \n-
    396 }
    \n-
    397
    \n-
    398 } //namespace Amg
    \n-
    399} // namespace Dune
    \n-
    400#endif
    \n-\n-\n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-\n-
    LocalIndex::Attribute Attribute
    The type of the attribute.
    Definition: indicescoarsener.hh:70
    \n-
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: indicescoarsener.hh:116
    \n-
    void isPublic(bool b)
    Definition: indicescoarsener.hh:139
    \n-
    ParallelInformation::ParallelIndexSet ParallelIndexSet
    Definition: indicescoarsener.hh:55
    \n-
    bool isPublic()
    Definition: indicescoarsener.hh:134
    \n-
    ParallelIndexSet::LocalIndex LocalIndex
    The type of the local index.
    Definition: indicescoarsener.hh:65
    \n-
    T ParallelInformation
    The type of the parallel information.
    Definition: indicescoarsener.hh:53
    \n-
    Attribute attribute()
    Definition: indicescoarsener.hh:155
    \n-
    Vertex operator()(const GlobalIndex &global)
    Definition: indicescoarsener.hh:127
    \n-
    static Graph::VertexDescriptor coarsen(ParallelInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
    Build the coarse index set after the aggregatio.
    Definition: indicescoarsener.hh:229
    \n-
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n-
    ParallelIndexSet::GlobalIndex GlobalIndex
    The type of the global index.
    Definition: indicescoarsener.hh:60
    \n-
    void attribute(const Attribute &attribute)
    Definition: indicescoarsener.hh:150
    \n-
    E ExcludedAttributes
    The set of excluded attributes.
    Definition: indicescoarsener.hh:48
    \n-
    void globalIndex(const GlobalIndex &global)
    Definition: indicescoarsener.hh:165
    \n-
    Dune::RemoteIndices< ParallelIndexSet > RemoteIndices
    The type of the remote indices.
    Definition: indicescoarsener.hh:75
    \n-
    ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I &lookup)
    Definition: indicescoarsener.hh:110
    \n-
    const GlobalIndex & globalIndex() const
    Definition: indicescoarsener.hh:160
    \n-
    STL namespace.
    \n+
    375 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
    \n+
    376 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
    \n+
    377
    \n+
    378#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
    \n+
    379#if HAVE_SUITESPARSE_UMFPACK
    \n+
    380#define DIRECTSOLVER UMFPack
    \n+
    381#else
    \n+
    382#define DIRECTSOLVER SuperLU
    \n+
    383#endif
    \n+
    384 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
    \n+
    385 if(std::is_same<ParallelInformation,SequentialInformation>::value // sequential mode
    \n+
    386 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
    \n+
    387 || (matrices_->parallelInformation().coarsest().isRedistributed()
    \n+
    388 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
    \n+
    389 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0)) { // redistribute and 1 proc
    \n+
    390 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
    \n+
    391 std::cout<<"Using superlu"<<std::endl;
    \n+
    392 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n+
    393 {
    \n+
    394 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n+
    395 // We are still participating on this level
    \n+
    396 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
    \n+
    397 else
    \n+
    398 solver_.reset();
    \n+
    399 }else
    \n+
    400 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest()->getmat(), false, false));
    \n+
    401 }else
    \n+
    402#undef DIRECTSOLVER
    \n+
    403#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
    \n+
    404 {
    \n+
    405 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n+
    406 {
    \n+
    407 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n+
    408 // We are still participating on this level
    \n+
    409 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
    \n+
    410 *scalarProduct_,
    \n+
    411 *coarseSmoother_, 1E-2, 1000, 0));
    \n+
    412 else
    \n+
    413 solver_.reset();
    \n+
    414 }else
    \n+
    415 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
    \n+
    416 *scalarProduct_,
    \n+
    417 *coarseSmoother_, 1E-2, 1000, 0));
    \n+
    418 }
    \n+
    419 }
    \n+
    420
    \n+
    421 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n+
    422 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    423 }
    \n+
    424
    \n+
    425
    \n+
    426 template<class M, class X, class PI, class A>
    \n+\n+
    428 {
    \n+
    429 Timer watch, watch1;
    \n+
    430 // Detect Matrix rows where all offdiagonal entries are
    \n+
    431 // zero and set x such that A_dd*x_d=b_d
    \n+
    432 // Thus users can be more careless when setting up their linear
    \n+
    433 // systems.
    \n+
    434 typedef typename M::matrix_type Matrix;
    \n+
    435 typedef typename Matrix::ConstRowIterator RowIter;
    \n+
    436 typedef typename Matrix::ConstColIterator ColIter;
    \n+
    437 typedef typename Matrix::block_type Block;
    \n+
    438 Block zero;
    \n+
    439 zero=typename Matrix::field_type();
    \n+
    440
    \n+
    441 const Matrix& mat=matrices_->matrices().finest()->getmat();
    \n+
    442 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {
    \n+
    443 bool isDirichlet = true;
    \n+
    444 bool hasDiagonal = false;
    \n+
    445 ColIter diag;
    \n+
    446 for(ColIter col=row->begin(); col!=row->end(); ++col) {
    \n+
    447 if(row.index()==col.index()) {
    \n+
    448 diag = col;
    \n+
    449 hasDiagonal = (*col != zero);
    \n+
    450 }else{
    \n+
    451 if(*col!=zero)
    \n+
    452 isDirichlet = false;
    \n+
    453 }
    \n+
    454 }
    \n+
    455 if(isDirichlet && hasDiagonal)
    \n+
    456 diag->solve(x[row.index()], b[row.index()]);
    \n+
    457 }
    \n+
    458 if (verbosity_>0)
    \n+
    459 std::cout<<" Preprocessing Dirichlet took "<<watch1.elapsed()<<std::endl;
    \n+
    460 watch1.reset();
    \n+
    461 // No smoother to make x consistent! Do it by hand
    \n+
    462 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
    \n+
    463 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
    \n+
    464 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n+
    465 residual_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n+
    466 matrices_->coarsenVector(*rhs_);
    \n+
    467 matrices_->coarsenVector(*lhs_);
    \n+
    468 matrices_->coarsenVector(*residual_);
    \n+
    469
    \n+
    470 // The preconditioner might change x and b. So we have to
    \n+
    471 // copy the changes to the original vectors.
    \n+
    472 x = *lhs_->finest();
    \n+
    473 b = *rhs_->finest();
    \n+
    474 }
    \n+
    475 template<class M, class X, class PI, class A>
    \n+\n+
    477 {
    \n+
    478 return matrices_->levels();
    \n+
    479 }
    \n+
    480 template<class M, class X, class PI, class A>
    \n+\n+
    482 {
    \n+
    483 return matrices_->maxlevels();
    \n+
    484 }
    \n+
    485
    \n+
    487 template<class M, class X, class PI, class A>
    \n+\n+
    489 {
    \n+
    490 LevelContext levelContext;
    \n+
    491 // Init all iterators for the current level
    \n+
    492 initIteratorsWithFineLevel(levelContext);
    \n+
    493
    \n+
    494 assert(v.two_norm()==0);
    \n+
    495
    \n+
    496 level=0;
    \n+
    497 if(matrices_->maxlevels()==1){
    \n+
    498 // The coarse solver might modify the d!
    \n+
    499 Range b(d);
    \n+
    500 mgc(levelContext, v, b);
    \n+
    501 }else
    \n+
    502 mgc(levelContext, v, d);
    \n+
    503 if(postSteps_==0||matrices_->maxlevels()==1)
    \n+
    504 levelContext.pinfo->copyOwnerToAll(v, v);
    \n+
    505 }
    \n+
    506
    \n+
    507 template<class M, class X, class PI, class A>
    \n+
    508 void FastAMG<M,X,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
    \n+
    509 {
    \n+
    510 levelContext.matrix = matrices_->matrices().finest();
    \n+
    511 levelContext.pinfo = matrices_->parallelInformation().finest();
    \n+
    512 levelContext.redist =
    \n+
    513 matrices_->redistributeInformation().begin();
    \n+
    514 levelContext.aggregates = matrices_->aggregatesMaps().begin();
    \n+
    515 levelContext.lhs = lhs_->finest();
    \n+
    516 levelContext.residual = residual_->finest();
    \n+
    517 levelContext.rhs = rhs_->finest();
    \n+
    518 levelContext.level=0;
    \n+
    519 }
    \n+
    520
    \n+
    521 template<class M, class X, class PI, class A>
    \n+
    522 bool FastAMG<M,X,PI,A>
    \n+
    523 ::moveToCoarseLevel(LevelContext& levelContext)
    \n+
    524 {
    \n+
    525 bool processNextLevel=true;
    \n+
    526
    \n+
    527 if(levelContext.redist->isSetup()) {
    \n+
    528 throw "bla";
    \n+
    529 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.residual),
    \n+
    530 levelContext.residual.getRedistributed());
    \n+
    531 processNextLevel = levelContext.residual.getRedistributed().size()>0;
    \n+
    532 if(processNextLevel) {
    \n+
    533 //restrict defect to coarse level right hand side.
    \n+
    534 ++levelContext.pinfo;
    \n+\n+
    536 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n+
    537 static_cast<const Range&>(levelContext.residual.getRedistributed()),
    \n+
    538 *levelContext.pinfo);
    \n+
    539 }
    \n+
    540 }else{
    \n+
    541 //restrict defect to coarse level right hand side.
    \n+
    542 ++levelContext.rhs;
    \n+
    543 ++levelContext.pinfo;
    \n+\n+
    545 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n+
    546 static_cast<const Range&>(*levelContext.residual), *levelContext.pinfo);
    \n+
    547 }
    \n+
    548
    \n+
    549 if(processNextLevel) {
    \n+
    550 // prepare coarse system
    \n+
    551 ++levelContext.residual;
    \n+
    552 ++levelContext.lhs;
    \n+
    553 ++levelContext.matrix;
    \n+
    554 ++levelContext.level;
    \n+
    555 ++levelContext.redist;
    \n+
    556
    \n+
    557 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n+
    558 // next level is not the globally coarsest one
    \n+
    559 ++levelContext.aggregates;
    \n+
    560 }
    \n+
    561 // prepare the lhs on the next level
    \n+
    562 *levelContext.lhs=0;
    \n+
    563 *levelContext.residual=0;
    \n+
    564 }
    \n+
    565 return processNextLevel;
    \n+
    566 }
    \n+
    567
    \n+
    568 template<class M, class X, class PI, class A>
    \n+
    569 void FastAMG<M,X,PI,A>
    \n+
    570 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel, Domain& x)
    \n+
    571 {
    \n+
    572 if(processNextLevel) {
    \n+
    573 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n+
    574 // previous level is not the globally coarsest one
    \n+
    575 --levelContext.aggregates;
    \n+
    576 }
    \n+
    577 --levelContext.redist;
    \n+
    578 --levelContext.level;
    \n+
    579 //prolongate and add the correction (update is in coarse left hand side)
    \n+
    580 --levelContext.matrix;
    \n+
    581 --levelContext.residual;
    \n+
    582
    \n+
    583 }
    \n+
    584
    \n+
    585 typename Hierarchy<Domain,A>::Iterator coarseLhs = levelContext.lhs--;
    \n+
    586 if(levelContext.redist->isSetup()) {
    \n+
    587
    \n+
    588 // Need to redistribute during prolongate
    \n+\n+
    590 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
    \n+
    591 levelContext.lhs.getRedistributed(),
    \n+
    592 matrices_->getProlongationDampingFactor(),
    \n+
    593 *levelContext.pinfo, *levelContext.redist);
    \n+
    594 }else{
    \n+\n+
    596 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
    \n+
    597 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);
    \n+
    598
    \n+
    599 // printvector(std::cout, *lhs, "prolongated coarse grid correction", "lhs", 10, 10, 10);
    \n+
    600 }
    \n+
    601
    \n+
    602
    \n+
    603 if(processNextLevel) {
    \n+
    604 --levelContext.rhs;
    \n+
    605 }
    \n+
    606
    \n+
    607 }
    \n+
    608
    \n+
    609
    \n+
    610 template<class M, class X, class PI, class A>
    \n+
    611 void FastAMG<M,X,PI,A>
    \n+
    612 ::presmooth(LevelContext& levelContext, Domain& x, const Range& b)
    \n+
    613 {
    \n+
    614 constexpr auto bl = blockLevel<typename M::matrix_type>();
    \n+
    615 GaussSeidelPresmoothDefect<bl>::apply(levelContext.matrix->getmat(),
    \n+
    616 x,
    \n+
    617 *levelContext.residual,
    \n+
    618 b);
    \n+
    619 }
    \n+
    620
    \n+
    621 template<class M, class X, class PI, class A>
    \n+
    622 void FastAMG<M,X,PI,A>
    \n+
    623 ::postsmooth(LevelContext& levelContext, Domain& x, const Range& b)
    \n+
    624 {
    \n+
    625 constexpr auto bl = blockLevel<typename M::matrix_type>();
    \n+\n+
    627 ::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);
    \n+
    628 }
    \n+
    629
    \n+
    630
    \n+
    631 template<class M, class X, class PI, class A>
    \n+\n+
    633 {
    \n+\n+
    635 }
    \n+
    636
    \n+
    637 template<class M, class X, class PI, class A>
    \n+
    638 void FastAMG<M,X,PI,A>::mgc(LevelContext& levelContext, Domain& v, const Range& b){
    \n+
    639
    \n+
    640 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
    \n+
    641 // Solve directly
    \n+\n+
    643 res.converged=true; // If we do not compute this flag will not get updated
    \n+
    644 if(levelContext.redist->isSetup()) {
    \n+
    645 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());
    \n+
    646 if(levelContext.rhs.getRedistributed().size()>0) {
    \n+
    647 // We are still participating in the computation
    \n+
    648 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
    \n+
    649 levelContext.rhs.getRedistributed());
    \n+
    650 solver_->apply(levelContext.lhs.getRedistributed(), levelContext.rhs.getRedistributed(), res);
    \n+
    651 }
    \n+
    652 levelContext.redist->redistributeBackward(v, levelContext.lhs.getRedistributed());
    \n+
    653 levelContext.pinfo->copyOwnerToAll(v, v);
    \n+
    654 }else{
    \n+
    655 levelContext.pinfo->copyOwnerToAll(b, b);
    \n+
    656 solver_->apply(v, const_cast<Range&>(b), res);
    \n+
    657 }
    \n+
    658
    \n+
    659 // printvector(std::cout, *lhs, "coarse level update", "u", 10, 10, 10);
    \n+
    660 // printvector(std::cout, *rhs, "coarse level rhs", "rhs", 10, 10, 10);
    \n+
    661 if (!res.converged)
    \n+
    662 coarsesolverconverged = false;
    \n+
    663 }else{
    \n+
    664 // presmoothing
    \n+
    665 presmooth(levelContext, v, b);
    \n+
    666 // printvector(std::cout, *lhs, "update", "u", 10, 10, 10);
    \n+
    667 // printvector(std::cout, *residual, "post presmooth residual", "r", 10);
    \n+
    668#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n+
    669 bool processNextLevel = moveToCoarseLevel(levelContext);
    \n+
    670
    \n+
    671 if(processNextLevel) {
    \n+
    672 // next level
    \n+
    673 for(std::size_t i=0; i<gamma_; i++)
    \n+
    674 mgc(levelContext, *levelContext.lhs, *levelContext.rhs);
    \n+
    675 }
    \n+
    676
    \n+
    677 moveToFineLevel(levelContext, processNextLevel, v);
    \n+
    678#else
    \n+
    679 *lhs=0;
    \n+
    680#endif
    \n+
    681
    \n+
    682 if(levelContext.matrix == matrices_->matrices().finest()) {
    \n+
    683 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
    \n+
    684 if(!coarsesolverconverged)
    \n+
    685 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n+
    686 }
    \n+
    687
    \n+
    688 postsmooth(levelContext, v, b);
    \n+
    689 }
    \n+
    690 }
    \n+
    691
    \n+
    692
    \n+
    694 template<class M, class X, class PI, class A>
    \n+
    695 void FastAMG<M,X,PI,A>::post([[maybe_unused]] Domain& x)
    \n+
    696 {
    \n+
    697 lhs_=nullptr;
    \n+
    698 rhs_=nullptr;
    \n+
    699 residual_=nullptr;
    \n+
    700 }
    \n+
    701
    \n+
    702 template<class M, class X, class PI, class A>
    \n+
    703 template<class A1>
    \n+
    704 void FastAMG<M,X,PI,A>::getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont)
    \n+
    705 {
    \n+
    706 matrices_->getCoarsestAggregatesOnFinest(cont);
    \n+
    707 }
    \n+
    708
    \n+
    709 } // end namespace Amg
    \n+
    710} // end namespace Dune
    \n+
    711
    \n+
    712#endif
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n+
    Classes for using SuperLU with ISTL matrices.
    \n+
    Define base class for scalar product and norm.
    \n+
    Templates characterizing the type of a solver.
    \n+
    Classes for using UMFPack with ISTL matrices.
    \n+
    Prolongation and restriction for amg.
    \n+\n+
    Provides a classes representing the hierarchies in AMG.
    \n+
    Classes for the generic construction and application of the smoothers.
    \n+
    Implementations of the inverse operator interface.
    \n+
    Define general preconditioner interface.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n+
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n+
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n+
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n+
    OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
    The iterator over the matrices.
    Definition: fastamg.hh:184
    \n+
    void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
    Get the aggregate number of each unknown on the coarsest level.
    Definition: fastamg.hh:704
    \n+
    ParallelInformationHierarchy::Iterator pinfo
    The iterator over the parallel information.
    Definition: fastamg.hh:188
    \n+
    void recalculateHierarchy()
    Recalculate the matrix hierarchy.
    Definition: fastamg.hh:150
    \n+
    void post(Domain &x)
    Clean up.
    Definition: fastamg.hh:695
    \n+
    std::size_t maxlevels()
    Definition: fastamg.hh:481
    \n+
    X Domain
    The domain type.
    Definition: fastamg.hh:77
    \n+
    Hierarchy< Domain, A >::Iterator residual
    The iterator over the residuals.
    Definition: fastamg.hh:204
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: fastamg.hh:123
    \n+
    MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
    The operator hierarchy type.
    Definition: fastamg.hh:72
    \n+
    OperatorHierarchy::RedistributeInfoList::const_iterator redist
    The iterator over the redistribution information.
    Definition: fastamg.hh:192
    \n+
    X Range
    The range type.
    Definition: fastamg.hh:79
    \n+
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: fastamg.hh:70
    \n+
    M Operator
    The matrix operator type.
    Definition: fastamg.hh:63
    \n+
    std::size_t levels()
    Definition: fastamg.hh:476
    \n+
    InverseOperator< X, X > CoarseSolver
    the type of the coarse solver.
    Definition: fastamg.hh:81
    \n+
    bool usesDirectCoarseLevelSolver() const
    Check whether the coarse solver used is a direct solver.
    Definition: fastamg.hh:632
    \n+
    Hierarchy< Domain, A >::Iterator lhs
    The iterator over the left hand side.
    Definition: fastamg.hh:200
    \n+
    Hierarchy< Range, A >::Iterator rhs
    The iterator over the right hand sided.
    Definition: fastamg.hh:208
    \n+
    std::size_t level
    The level index.
    Definition: fastamg.hh:212
    \n+
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: fastamg.hh:488
    \n+
    OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
    The parallal data distribution hierarchy type.
    Definition: fastamg.hh:74
    \n+
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: fastamg.hh:427
    \n+
    FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const Parameters &parms, bool symmetric=true)
    Construct a new amg with a specific coarse solver.
    Definition: fastamg.hh:297
    \n+
    OperatorHierarchy::AggregatesMapList::const_iterator aggregates
    The iterator over the aggregates maps.
    Definition: fastamg.hh:196
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-
    Definition: indicescoarsener.hh:36
    \n-
    Definition: indicescoarsener.hh:43
    \n-
    Definition: pinfo.hh:28
    \n-
    Definition: renumberer.hh:16
    \n-
    void operator++()
    Definition: renumberer.hh:57
    \n-
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: renumberer.hh:51
    \n-
    Vertex number_
    Definition: renumberer.hh:35
    \n+
    @ symmetric
    Definition: matrixmarket.hh:303
    \n+
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n+
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n+
    A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth.
    Definition: fastamg.hh:60
    \n+
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:19
    \n+
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:55
    \n+\n+
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n+
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n+
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n+
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n+
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n+\n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    Definition: solvertype.hh:16
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,486 +5,835 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-indicescoarsener.hh\n+fastamg.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_INDICESCOARSENER_HH\n- 6#define DUNE_AMG_INDICESCOARSENER_HH\n+ 5#ifndef DUNE_ISTL_FASTAMG_HH\n+ 6#define DUNE_ISTL_FASTAMG_HH\n 7\n- 8#include \n- 9#include \n- 10#include \"renumberer.hh\"\n- 11\n- 12#if HAVE_MPI\n- 13#include \n- 14#endif\n- 15\n- 16#include \"pinfo.hh\"\n- 17\n- 18namespace Dune\n- 19{\n- 20 namespace Amg\n- 21 {\n- 22\n- 34 template\n-35 class IndicesCoarsener\n- 36 {};\n- 37\n- 38\n- 39#if HAVE_MPI\n- 40\n- 41 template\n-42 class ParallelIndicesCoarsener\n- 43 {\n- 44 public:\n-48 typedef E ExcludedAttributes;\n- 49\n-53 typedef T ParallelInformation;\n- 54\n-55 typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;\n- 56\n-60 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n- 61\n-65 typedef typename ParallelIndexSet::LocalIndex LocalIndex;\n- 66\n-70 typedef typename LocalIndex::Attribute Attribute;\n- 71\n-75 typedef Dune::RemoteIndices RemoteIndices;\n- 76\n- 88 template\n- 89 static typename Graph::VertexDescriptor\n-90 coarsen(ParallelInformation& fineInfo,\n- 91 Graph& fineGraph,\n- 92 VM& visitedMap,\n- 93 AggregatesMap& aggregates,\n- 94 ParallelInformation& coarseInfo,\n- 95 typename Graph::VertexDescriptor noAggregates);\n- 96\n- 97 private:\n- 98 template\n- 99 class ParallelAggregateRenumberer : public AggregateRenumberer\n- 100 {\n- 101 typedef typename G::VertexDescriptor Vertex;\n- 102\n- 103 typedef I GlobalLookupIndexSet;\n- 104\n- 105 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;\n- 106\n- 107 typedef typename IndexPair::GlobalIndex GlobalIndex;\n- 108\n- 109 public:\n-110 ParallelAggregateRenumberer(AggregatesMap& aggregates, const I&\n-lookup)\n- 111 : AggregateRenumberer(aggregates), isPublic_(false), lookup_(lookup),\n- 112 globalIndex_(std::numeric_limits::max())\n- 113 {}\n- 114\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21\n+ 22#include \"fastamgsmoother.hh\"\n+ 23\n+ 32namespace Dune\n+ 33{\n+ 34 namespace Amg\n+ 35 {\n+ 58 template >\n+59 class FastAMG : public Preconditioner\n+ 60 {\n+ 61 public:\n+63 typedef M Operator;\n+70 typedef PI ParallelInformation;\n+72 typedef MatrixHierarchy OperatorHierarchy;\n+74 typedef typename OperatorHierarchy::ParallelInformationHierarchy\n+ParallelInformationHierarchy;\n+ 75\n+77 typedef X Domain;\n+79 typedef X Range;\n+81 typedef InverseOperator CoarseSolver;\n+ 82\n+ 90 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n+ 91 const Parameters& parms,\n+ 92 bool symmetric=true);\n+ 93\n+ 105 template\n+ 106 FastAMG(const Operator& fineOperator, const C& criterion,\n+ 107 const Parameters& parms=Parameters(),\n+ 108 bool symmetric=true,\n+ 109 const ParallelInformation& pinfo=ParallelInformation());\n+ 110\n+ 114 FastAMG(const FastAMG& amg);\n 115\n-116 void operator()(const typename G::ConstEdgeIterator& edge)\n- 117 {\n- 118 AggregateRenumberer::operator()(edge);\n- 119 const IndexPair* pair= lookup_.pair(edge.target());\n- 120 if(pair!=0) {\n- 121 globalIndex(pair->global());\n- 122 attribute(pair->local().attribute());\n- 123 isPublic(pair->local().isPublic());\n- 124 }\n- 125 }\n- 126\n-127 Vertex operator()([[maybe_unused]] const GlobalIndex& global)\n- 128 {\n- 129 Vertex current = this->number_;\n- 130 this->operator++();\n- 131 return current;\n- 132 }\n- 133\n-134 bool isPublic()\n- 135 {\n- 136 return isPublic_;\n- 137 }\n- 138\n-139 void isPublic(bool b)\n- 140 {\n- 141 isPublic_ = isPublic_ || b;\n- 142 }\n- 143\n-144 void reset()\n- 145 {\n- 146 globalIndex_ = std::numeric_limits::max();\n- 147 isPublic_=false;\n- 148 }\n- 149\n-150 void attribute(const Attribute& attribute)\n+ 117 void pre(Domain& x, Range& b);\n+ 118\n+ 120 void apply(Domain& v, const Range& d);\n+ 121\n+123 virtual SolverCategory::Category category() const\n+ 124 {\n+ 125 return SolverCategory::sequential;\n+ 126 }\n+ 127\n+ 129 void post(Domain& x);\n+ 130\n+ 135 template\n+ 136 void getCoarsestAggregateNumbers(std::vector& cont);\n+ 137\n+ 138 std::size_t levels();\n+ 139\n+ 140 std::size_t maxlevels();\n+ 141\n+150 void recalculateHierarchy()\n 151 {\n- 152 attribute_=attribute;\n+ 152 matrices_->recalculateGalerkin(NegateSet());\n 153 }\n 154\n-155 Attribute attribute()\n- 156 {\n- 157 return attribute_;\n- 158 }\n- 159\n-160 const GlobalIndex& globalIndex() const\n- 161 {\n- 162 return globalIndex_;\n- 163 }\n- 164\n-165 void globalIndex(const GlobalIndex& global)\n- 166 {\n- 167 globalIndex_ = global;\n- 168 }\n- 169\n- 170 private:\n- 171 bool isPublic_;\n- 172 Attribute attribute_;\n- 173 const GlobalLookupIndexSet& lookup_;\n- 174 GlobalIndex globalIndex_;\n- 175 };\n- 176\n- 177 template\n- 178 static void buildCoarseIndexSet(const ParallelInformation& pinfo,\n- 179 Graph& fineGraph,\n- 180 VM& visitedMap,\n- 181 AggregatesMap& aggregates,\n- 182 ParallelIndexSet& coarseIndices,\n- 183 ParallelAggregateRenumberer& renumberer);\n- 184\n- 185 template\n- 186 static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,\n- 187 const AggregatesMap& aggregates,\n- 188 ParallelIndexSet& coarseIndices,\n- 189 RemoteIndices& coarseRemote,\n- 190 ParallelAggregateRenumberer& renumberer);\n- 191\n- 192 };\n- 193\n- 197 template\n-198 class IndicesCoarsener,E>\n- 199 : public ParallelIndicesCoarsener,E>\n- 200 {};\n- 201\n- 202\n- 203#endif\n- 204\n- 211 template\n-212 class IndicesCoarsener\n- 213 {\n- 214 public:\n- 215 template\n- 216 static typename Graph::VertexDescriptor\n- 217 coarsen(const SequentialInformation & fineInfo,\n- 218 Graph& fineGraph,\n- 219 VM& visitedMap,\n- 220 AggregatesMap& aggregates,\n- 221 SequentialInformation& coarseInfo,\n- 222 typename Graph::VertexDescriptor noAggregates);\n- 223 };\n- 224\n- 225#if HAVE_MPI\n- 226 template\n- 227 template\n- 228 inline typename Graph::VertexDescriptor\n-229 ParallelIndicesCoarsener::coarsen(ParallelInformation& fineInfo,\n- 230 Graph& fineGraph,\n- 231 VM& visitedMap,\n- 232 AggregatesMap& aggregates,\n- 233 ParallelInformation& coarseInfo,\n- 234 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)\n- 235 {\n- 236 ParallelAggregateRenumberer renumberer(aggregates, fineInfo.globalLookup());\n- 237 buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,\n- 238 coarseInfo.indexSet(), renumberer);\n- 239 buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates,\n-coarseInfo.indexSet(),\n- 240 coarseInfo.remoteIndices(), renumberer);\n- 241\n- 242 return renumberer;\n- 243 }\n- 244\n- 245 template\n- 246 template\n- 247 void ParallelIndicesCoarsener::buildCoarseIndexSet(const\n-ParallelInformation& pinfo,\n- 248 Graph& fineGraph,\n- 249 VM& visitedMap,\n- 250 AggregatesMap& aggregates,\n- 251 ParallelIndexSet& coarseIndices,\n- 252 ParallelAggregateRenumberer& renumberer)\n- 253 {\n- 254 // fineGraph is the local subgraph corresponding to the vertices the\n-process owns.\n- 255 // i.e. no overlap/copy vertices can be visited traversing the graph\n- 256 typedef typename Graph::ConstVertexIterator Iterator;\n- 257 typedef typename ParallelInformation::GlobalLookupIndexSet\n-GlobalLookupIndexSet;\n- 258\n- 259 Iterator end = fineGraph.end();\n- 260 const GlobalLookupIndexSet& lookup = pinfo.globalLookup();\n- 261\n- 262 coarseIndices.beginResize();\n- 263\n- 264 // Setup the coarse index set and renumber the aggregate consecutively\n- 265 // ascending from zero according to the minimum global index belonging\n- 266 // to the aggregate\n- 267 for(Iterator index = fineGraph.begin(); index != end; ++index) {\n- 268 if(aggregates[*index]!=AggregatesMap::\n-ISOLATED)\n- 269 // Isolated vertices will not be represented on the next level.\n- 270 // These should only be there if skipIsolated is activiated in\n- 271 // the coarsening criterion as otherwise they will be aggregated\n- 272 // and should have real aggregate number in the map right now.\n- 273 if(!get(visitedMap, *index)) {\n- 274 // This vertex was not visited by breadthFirstSearch yet.\n- 275 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;\n- 276 const IndexPair* pair= lookup.pair(*index);\n- 277\n- 278 renumberer.reset(); // reset attribute and global index.\n- 279 if(pair!=0) {\n- 280 // vertex is in the index set. Note that not all vertices have\n- 281 // to be in the index set, just the ones where communication\n- 282 // will happen.\n- 283 assert(!ExcludedAttributes::contains(pair->local().attribute()));\n- 284 renumberer.attribute(pair->local().attribute());\n- 285 renumberer.isPublic(pair->local().isPublic());\n- 286 renumberer.globalIndex(pair->global());\n- 287 }\n- 288\n- 289 // Reconstruct aggregate and mark vertices as visited\n- 290 aggregates.template breadthFirstSearch(*index, aggregates[*index],\n- 291 fineGraph, renumberer, visitedMap);\n- 292\n- 293 if(renumberer.globalIndex()!=std::numeric_limits::max()) {\n- 294 // vertex is in the index set.\n- 295 //std::cout <<\" Adding global=\"<< renumberer.globalIndex()<<\"\n-local=\"<(renumberer)<(renumberer) >= coarseIndices.size());\n- 309\n- 310 // Reset the visited flags\n- 311 for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)\n- 312 put(visitedMap, *vertex, false);\n- 313 }\n- 314\n- 315 template\n- 316 template\n- 317 void ParallelIndicesCoarsener::buildCoarseRemoteIndices(const\n-RemoteIndices& fineRemote,\n- 318 const AggregatesMap& aggregates,\n- 319 ParallelIndexSet& coarseIndices,\n- 320 RemoteIndices& coarseRemote,\n- 321 ParallelAggregateRenumberer& renumberer)\n- 322 {\n- 323 std::vector attributes(static_cast(renumberer));\n- 324\n- 325 GlobalLookupIndexSet coarseLookup(coarseIndices,\n-static_cast(renumberer));\n- 326\n- 327 typedef typename RemoteIndices::const_iterator Iterator;\n- 328 Iterator end = fineRemote.end();\n- 329\n- 330 for(Iterator neighbour = fineRemote.begin();\n- 331 neighbour != end; ++neighbour) {\n- 332 int process = neighbour->first;\n- 333\n- 334 assert(neighbour->second.first==neighbour->second.second);\n- 335\n- 336 // Mark all as not known\n- 337 typedef typename std::vector::iterator CIterator;\n- 338\n- 339 for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)\n- 340 *iter = std::numeric_limits::max();\n+ 159 bool usesDirectCoarseLevelSolver() const;\n+ 160\n+ 161 private:\n+ 168 template\n+ 169 void createHierarchies(C& criterion,\n+ 170 const std::shared_ptr& matrixptr,\n+ 171 const PI& pinfo);\n+ 172\n+ 179 struct LevelContext\n+ 180 {\n+184 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix;\n+188 typename ParallelInformationHierarchy::Iterator pinfo;\n+192 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;\n+196 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;\n+200 typename Hierarchy::Iterator lhs;\n+204 typename Hierarchy::Iterator residual;\n+208 typename Hierarchy::Iterator rhs;\n+212 std::size_t level;\n+ 213 };\n+ 214\n+ 216 void mgc(LevelContext& levelContext, Domain& x, const Range& b);\n+ 217\n+ 224 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);\n+ 225\n+ 232 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);\n+ 233\n+ 240 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,\n+ 241 Domain& fineX);\n+ 242\n+ 247 bool moveToCoarseLevel(LevelContext& levelContext);\n+ 248\n+ 253 void initIteratorsWithFineLevel(LevelContext& levelContext);\n+ 254\n+ 256 std::shared_ptr matrices_;\n+ 258 std::shared_ptr solver_;\n+ 260 std::shared_ptr> rhs_;\n+ 262 std::shared_ptr> lhs_;\n+ 264 std::shared_ptr> residual_;\n+ 265\n+ 267 using ScalarProduct = Dune::ScalarProduct;\n+ 269 std::shared_ptr scalarProduct_;\n+ 271 std::size_t gamma_;\n+ 273 std::size_t preSteps_;\n+ 275 std::size_t postSteps_;\n+ 276 std::size_t level;\n+ 277 bool buildHierarchy_;\n+ 278 bool symmetric;\n+ 279 bool coarsesolverconverged;\n+ 280 typedef SeqSSOR Smoother;\n+ 281 typedef std::shared_ptr SmootherPointer;\n+ 282 SmootherPointer coarseSmoother_;\n+ 284 std::size_t verbosity_;\n+ 285 };\n+ 286\n+ 287 template\n+288 FastAMG::FastAMG(const FastAMG& amg)\n+ 289 : matrices_(amg.matrices_), solver_(amg.solver_),\n+ 290 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),\n+ 291 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),\n+ 292 symmetric(amg.symmetric), coarsesolverconverged\n+(amg.coarsesolverconverged),\n+ 293 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)\n+ 294 {}\n+ 295\n+ 296 template\n+297 FastAMG::FastAMG(OperatorHierarchy& matrices, CoarseSolver&\n+coarseSolver,\n+ 298 const Parameters& parms, bool symmetric_)\n+ 299 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),\n+ 300 rhs_(), lhs_(), residual_(), scalarProduct_(),\n+ 301 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),\n+ 302 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),\n+ 303 symmetric(symmetric_), coarsesolverconverged(true),\n+ 304 coarseSmoother_(), verbosity_(parms.debugLevel())\n+ 305 {\n+ 306 if(preSteps_>1||postSteps_>1)\n+ 307 {\n+ 308 std::cerr<<\"WARNING only one step of smoothing is supported!\"<isBuilt());\n+ 312 static_assert(std::is_same::value,\n+ 313 \"Currently only sequential runs are supported\");\n+ 314 }\n+ 315 template\n+ 316 template\n+317 FastAMG::FastAMG(const Operator& matrix,\n+ 318 const C& criterion,\n+ 319 const Parameters& parms,\n+ 320 bool symmetric_,\n+ 321 const PI& pinfo)\n+ 322 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_\n+(parms.getGamma()),\n+ 323 preSteps_(parms.getNoPreSmoothSteps()), postSteps_\n+(parms.getNoPostSmoothSteps()),\n+ 324 buildHierarchy_(true),\n+ 325 symmetric(symmetric_), coarsesolverconverged(true),\n+ 326 coarseSmoother_(), verbosity_(criterion.debugLevel())\n+ 327 {\n+ 328 if(preSteps_>1||postSteps_>1)\n+ 329 {\n+ 330 std::cerr<<\"WARNING only one step of smoothing is supported!\"<::value,\n+ 334 \"Currently only sequential runs are supported\");\n+ 335 // TODO: reestablish compile time checks.\n+ 336 //static_assert(static_cast(PI::category)==static_cast(S::\n+category),\n+ 337 // \"Matrix and Solver must match in terms of category!\");\n+ 338 auto matrixptr = stackobject_to_shared_ptr(matrix);\n+ 339 createHierarchies(criterion, matrixptr, pinfo);\n+ 340 }\n 341\n- 342 auto riEnd = neighbour->second.second->end();\n- 343\n- 344 for(auto index = neighbour->second.second->begin();\n- 345 index != riEnd; ++index) {\n- 346 if(!E::contains(index->localIndexPair().local().attribute()) &&\n- 347 aggregates[index->localIndexPair().local()] !=\n- 348 AggregatesMap::ISOLATED)\n- 349 {\n- 350 assert(aggregates[index->localIndexPair().local()]localIndexPair().local()]] != 3)\n- 352 attributes[aggregates[index->localIndexPair().local()]] = index->attribute\n-();\n- 353 }\n- 354 }\n- 355\n- 356 // Build remote index list\n- 357 typedef RemoteIndexListModifier Modifier;\n- 358 typedef typename RemoteIndices::RemoteIndex RemoteIndex;\n- 359 typedef typename ParallelIndexSet::const_iterator IndexIterator;\n- 360\n- 361 Modifier coarseList = coarseRemote.template getModifier\n-(process);\n- 362\n- 363 IndexIterator iend = coarseIndices.end();\n- 364 for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)\n- 365 if(attributes[index->local()] != std::numeric_limits::max()) {\n- 366 // remote index is present\n- 367 coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &\n-(*index)));\n- 368 }\n- 369 //std::cout<\n+ 343 template\n+ 344 void FastAMG::createHierarchies(C& criterion,\n+ 345 const std::shared_ptr& matrixptr,\n+ 346 const PI& pinfo)\n+ 347 {\n+ 348 Timer watch;\n+ 349 matrices_ = std::make_shared(\n+ 350 std::const_pointer_cast(matrixptr),\n+ 351 stackobject_to_shared_ptr(const_cast(pinfo)));\n+ 352\n+ 353 matrices_->template build >(criterion);\n+ 354\n+ 355 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n+().rank()==0)\n+ 356 std::cout<<\"Building Hierarchy of \"<maxlevels()<<\" levels took\n+\"<levels()==matrices_->maxlevels()) {\n+ 359 // We have the carsest level. Create the coarse Solver\n+ 360 typedef typename SmootherTraits::Arguments SmootherArgs;\n+ 361 SmootherArgs sargs;\n+ 362 sargs.iterations = 1;\n+ 363\n+ 364 typename ConstructionTraits::Arguments cargs;\n+ 365 cargs.setArgs(sargs);\n+ 366 if(matrices_->redistributeInformation().back().isSetup()) {\n+ 367 // Solve on the redistributed partitioning\n+ 368 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat\n+());\n+ 369 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed\n+());\n+ 370 }else{\n+ 371 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());\n+ 372 cargs.setComm(*matrices_->parallelInformation().coarsest());\n+ 373 }\n 374\n- 375 // snyc the index set and the remote indices to recompute missing\n- 376 // indices\n- 377 IndicesSyncer syncer(coarseIndices, coarseRemote);\n- 378 syncer.sync(renumberer);\n- 379\n- 380 }\n- 381\n- 382#endif\n- 383\n- 384 template\n- 385 template\n- 386 typename Graph::VertexDescriptor\n-387 IndicesCoarsener::coarsen(\n- 388 [[maybe_unused]] const SequentialInformation& fineInfo,\n- 389 [[maybe_unused]] Graph& fineGraph,\n- 390 [[maybe_unused]] VM& visitedMap,\n- 391 [[maybe_unused]] AggregatesMap&\n-aggregates,\n- 392 [[maybe_unused]] SequentialInformation& coarseInfo,\n- 393 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)\n- 394 {\n- 395 return noAggregates;\n- 396 }\n- 397\n- 398 } //namespace Amg\n- 399} // namespace Dune\n- 400#endif\n-renumberer.hh\n-pinfo.hh\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::reset\n-void reset()\n-Definition: indicescoarsener.hh:144\n-Dune::Amg::ParallelIndicesCoarsener::Attribute\n-LocalIndex::Attribute Attribute\n-The type of the attribute.\n-Definition: indicescoarsener.hh:70\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::operator()\n-void operator()(const typename G::ConstEdgeIterator &edge)\n-Definition: indicescoarsener.hh:116\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::isPublic\n-void isPublic(bool b)\n-Definition: indicescoarsener.hh:139\n-Dune::Amg::ParallelIndicesCoarsener::ParallelIndexSet\n-ParallelInformation::ParallelIndexSet ParallelIndexSet\n-Definition: indicescoarsener.hh:55\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::isPublic\n-bool isPublic()\n-Definition: indicescoarsener.hh:134\n-Dune::Amg::ParallelIndicesCoarsener::LocalIndex\n-ParallelIndexSet::LocalIndex LocalIndex\n-The type of the local index.\n-Definition: indicescoarsener.hh:65\n-Dune::Amg::ParallelIndicesCoarsener::ParallelInformation\n-T ParallelInformation\n-The type of the parallel information.\n-Definition: indicescoarsener.hh:53\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::attribute\n-Attribute attribute()\n-Definition: indicescoarsener.hh:155\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::operator()\n-Vertex operator()(const GlobalIndex &global)\n-Definition: indicescoarsener.hh:127\n-Dune::Amg::ParallelIndicesCoarsener::coarsen\n-static Graph::VertexDescriptor coarsen(ParallelInformation &fineInfo, Graph\n-&fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor >\n-&aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor\n-noAggregates)\n-Build the coarse index set after the aggregatio.\n-Definition: indicescoarsener.hh:229\n-Dune::Amg::AggregatesMap::ISOLATED\n-static const V ISOLATED\n-Identifier of isolated vertices.\n-Definition: aggregates.hh:571\n-Dune::Amg::ParallelIndicesCoarsener::GlobalIndex\n-ParallelIndexSet::GlobalIndex GlobalIndex\n-The type of the global index.\n-Definition: indicescoarsener.hh:60\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::attribute\n-void attribute(const Attribute &attribute)\n-Definition: indicescoarsener.hh:150\n-Dune::Amg::ParallelIndicesCoarsener::ExcludedAttributes\n-E ExcludedAttributes\n-The set of excluded attributes.\n-Definition: indicescoarsener.hh:48\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::globalIndex\n-void globalIndex(const GlobalIndex &global)\n-Definition: indicescoarsener.hh:165\n-Dune::Amg::ParallelIndicesCoarsener::RemoteIndices\n-Dune::RemoteIndices< ParallelIndexSet > RemoteIndices\n-The type of the remote indices.\n-Definition: indicescoarsener.hh:75\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::\n-ParallelAggregateRenumberer\n-ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I\n-&lookup)\n-Definition: indicescoarsener.hh:110\n-Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::globalIndex\n-const GlobalIndex & globalIndex() const\n-Definition: indicescoarsener.hh:160\n-std\n-STL namespace.\n+ 375 coarseSmoother_ = ConstructionTraits::construct(cargs);\n+ 376 scalarProduct_ = createScalarProduct(cargs.getComm(),category());\n+ 377\n+ 378#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK\n+ 379#if HAVE_SUITESPARSE_UMFPACK\n+ 380#define DIRECTSOLVER UMFPack\n+ 381#else\n+ 382#define DIRECTSOLVER SuperLU\n+ 383#endif\n+ 384 // Use superlu if we are purely sequential or with only one processor on\n+the coarsest level.\n+ 385 if(std::is_same::value /\n+/ sequential mode\n+ 386 || matrices_->parallelInformation().coarsest()->communicator().size()==1 /\n+/parallel mode and only one processor\n+ 387 || (matrices_->parallelInformation().coarsest().isRedistributed()\n+ 388 && matrices_->parallelInformation().coarsest().getRedistributed\n+().communicator().size()==1\n+ 389 && matrices_->parallelInformation().coarsest().getRedistributed\n+().communicator().size()>0)) { // redistribute and 1 proc\n+ 390 if(verbosity_>0 && matrices_->parallelInformation().coarsest()-\n+>communicator().rank()==0)\n+ 391 std::cout<<\"Using superlu\"<parallelInformation().coarsest().isRedistributed())\n+ 393 {\n+ 394 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n+ 395 // We are still participating on this level\n+ 396 solver_.reset(new DIRECTSOLVER(matrices_-\n+>matrices().coarsest().getRedistributed().getmat(), false, false));\n+ 397 else\n+ 398 solver_.reset();\n+ 399 }else\n+ 400 solver_.reset(new DIRECTSOLVER(matrices_-\n+>matrices().coarsest()->getmat(), false, false));\n+ 401 }else\n+ 402#undef DIRECTSOLVER\n+ 403#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK\n+ 404 {\n+ 405 if(matrices_->parallelInformation().coarsest().isRedistributed())\n+ 406 {\n+ 407 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n+ 408 // We are still participating on this level\n+ 409 solver_.reset(new BiCGSTABSolver(const_cast(matrices_->matrices\n+().coarsest().getRedistributed()),\n+ 410 *scalarProduct_,\n+ 411 *coarseSmoother_, 1E-2, 1000, 0));\n+ 412 else\n+ 413 solver_.reset();\n+ 414 }else\n+ 415 solver_.reset(new BiCGSTABSolver(const_cast(*matrices_->matrices\n+().coarsest()),\n+ 416 *scalarProduct_,\n+ 417 *coarseSmoother_, 1E-2, 1000, 0));\n+ 418 }\n+ 419 }\n+ 420\n+ 421 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n+().rank()==0)\n+ 422 std::cout<<\"Building Hierarchy of \"<maxlevels()<<\" levels took\n+\"<\n+427 void FastAMG::pre(Domain& x, Range& b)\n+ 428 {\n+ 429 Timer watch, watch1;\n+ 430 // Detect Matrix rows where all offdiagonal entries are\n+ 431 // zero and set x such that A_dd*x_d=b_d\n+ 432 // Thus users can be more careless when setting up their linear\n+ 433 // systems.\n+ 434 typedef typename M::matrix_type Matrix;\n+ 435 typedef typename Matrix::ConstRowIterator RowIter;\n+ 436 typedef typename Matrix::ConstColIterator ColIter;\n+ 437 typedef typename Matrix::block_type Block;\n+ 438 Block zero;\n+ 439 zero=typename Matrix::field_type();\n+ 440\n+ 441 const Matrix& mat=matrices_->matrices().finest()->getmat();\n+ 442 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {\n+ 443 bool isDirichlet = true;\n+ 444 bool hasDiagonal = false;\n+ 445 ColIter diag;\n+ 446 for(ColIter col=row->begin(); col!=row->end(); ++col) {\n+ 447 if(row.index()==col.index()) {\n+ 448 diag = col;\n+ 449 hasDiagonal = (*col != zero);\n+ 450 }else{\n+ 451 if(*col!=zero)\n+ 452 isDirichlet = false;\n+ 453 }\n+ 454 }\n+ 455 if(isDirichlet && hasDiagonal)\n+ 456 diag->solve(x[row.index()], b[row.index()]);\n+ 457 }\n+ 458 if (verbosity_>0)\n+ 459 std::cout<<\" Preprocessing Dirichlet took \"<parallelInformation().coarsest()->copyOwnerToAll(x,x);\n+ 463 rhs_ = std::make_shared>(std::make_shared(b));\n+ 464 lhs_ = std::make_shared>(std::make_shared(x));\n+ 465 residual_ = std::make_shared>(std::make_shared\n+(x));\n+ 466 matrices_->coarsenVector(*rhs_);\n+ 467 matrices_->coarsenVector(*lhs_);\n+ 468 matrices_->coarsenVector(*residual_);\n+ 469\n+ 470 // The preconditioner might change x and b. So we have to\n+ 471 // copy the changes to the original vectors.\n+ 472 x = *lhs_->finest();\n+ 473 b = *rhs_->finest();\n+ 474 }\n+ 475 template\n+476 std::size_t FastAMG::levels()\n+ 477 {\n+ 478 return matrices_->levels();\n+ 479 }\n+ 480 template\n+481 std::size_t FastAMG::maxlevels()\n+ 482 {\n+ 483 return matrices_->maxlevels();\n+ 484 }\n+ 485\n+ 487 template\n+488 void FastAMG::apply(Domain& v, const Range& d)\n+ 489 {\n+ 490 LevelContext levelContext;\n+ 491 // Init all iterators for the current level\n+ 492 initIteratorsWithFineLevel(levelContext);\n+ 493\n+ 494 assert(v.two_norm()==0);\n+ 495\n+ 496 level=0;\n+ 497 if(matrices_->maxlevels()==1){\n+ 498 // The coarse solver might modify the d!\n+ 499 Range b(d);\n+ 500 mgc(levelContext, v, b);\n+ 501 }else\n+ 502 mgc(levelContext, v, d);\n+ 503 if(postSteps_==0||matrices_->maxlevels()==1)\n+ 504 levelContext.pinfo->copyOwnerToAll(v, v);\n+ 505 }\n+ 506\n+ 507 template\n+ 508 void FastAMG::initIteratorsWithFineLevel(LevelContext&\n+levelContext)\n+ 509 {\n+ 510 levelContext.matrix = matrices_->matrices().finest();\n+ 511 levelContext.pinfo = matrices_->parallelInformation().finest();\n+ 512 levelContext.redist =\n+ 513 matrices_->redistributeInformation().begin();\n+ 514 levelContext.aggregates = matrices_->aggregatesMaps().begin();\n+ 515 levelContext.lhs = lhs_->finest();\n+ 516 levelContext.residual = residual_->finest();\n+ 517 levelContext.rhs = rhs_->finest();\n+ 518 levelContext.level=0;\n+ 519 }\n+ 520\n+ 521 template\n+ 522 bool FastAMG\n+ 523 ::moveToCoarseLevel(LevelContext& levelContext)\n+ 524 {\n+ 525 bool processNextLevel=true;\n+ 526\n+ 527 if(levelContext.redist->isSetup()) {\n+ 528 throw \"bla\";\n+ 529 levelContext.redist->redistribute(static_cast\n+(*levelContext.residual),\n+ 530 levelContext.residual.getRedistributed());\n+ 531 processNextLevel = levelContext.residual.getRedistributed().size()>0;\n+ 532 if(processNextLevel) {\n+ 533 //restrict defect to coarse level right hand side.\n+ 534 ++levelContext.pinfo;\n+ 535 Transfer\n+ 536::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n+ 537 static_cast(levelContext.residual.getRedistributed()),\n+ 538 *levelContext.pinfo);\n+ 539 }\n+ 540 }else{\n+ 541 //restrict defect to coarse level right hand side.\n+ 542 ++levelContext.rhs;\n+ 543 ++levelContext.pinfo;\n+ 544 Transfer\n+ 545::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n+ 546 static_cast(*levelContext.residual), *levelContext.pinfo);\n+ 547 }\n+ 548\n+ 549 if(processNextLevel) {\n+ 550 // prepare coarse system\n+ 551 ++levelContext.residual;\n+ 552 ++levelContext.lhs;\n+ 553 ++levelContext.matrix;\n+ 554 ++levelContext.level;\n+ 555 ++levelContext.redist;\n+ 556\n+ 557 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n+>levels()maxlevels()) {\n+ 558 // next level is not the globally coarsest one\n+ 559 ++levelContext.aggregates;\n+ 560 }\n+ 561 // prepare the lhs on the next level\n+ 562 *levelContext.lhs=0;\n+ 563 *levelContext.residual=0;\n+ 564 }\n+ 565 return processNextLevel;\n+ 566 }\n+ 567\n+ 568 template\n+ 569 void FastAMG\n+ 570 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel,\n+Domain& x)\n+ 571 {\n+ 572 if(processNextLevel) {\n+ 573 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n+>levels()maxlevels()) {\n+ 574 // previous level is not the globally coarsest one\n+ 575 --levelContext.aggregates;\n+ 576 }\n+ 577 --levelContext.redist;\n+ 578 --levelContext.level;\n+ 579 //prolongate and add the correction (update is in coarse left hand side)\n+ 580 --levelContext.matrix;\n+ 581 --levelContext.residual;\n+ 582\n+ 583 }\n+ 584\n+ 585 typename Hierarchy::Iterator coarseLhs = levelContext.lhs--;\n+ 586 if(levelContext.redist->isSetup()) {\n+ 587\n+ 588 // Need to redistribute during prolongate\n+ 589 Transfer\n+ 590::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,\n+ 591 levelContext.lhs.getRedistributed(),\n+ 592 matrices_->getProlongationDampingFactor(),\n+ 593 *levelContext.pinfo, *levelContext.redist);\n+ 594 }else{\n+ 595 Transfer\n+ 596::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,\n+ 597 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);\n+ 598\n+ 599 // printvector(std::cout, *lhs, \"prolongated coarse grid correction\",\n+\"lhs\", 10, 10, 10);\n+ 600 }\n+ 601\n+ 602\n+ 603 if(processNextLevel) {\n+ 604 --levelContext.rhs;\n+ 605 }\n+ 606\n+ 607 }\n+ 608\n+ 609\n+ 610 template\n+ 611 void FastAMG\n+ 612 ::presmooth(LevelContext& levelContext, Domain& x, const Range& b)\n+ 613 {\n+ 614 constexpr auto bl = blockLevel();\n+ 615 GaussSeidelPresmoothDefect::apply(levelContext.matrix->getmat(),\n+ 616 x,\n+ 617 *levelContext.residual,\n+ 618 b);\n+ 619 }\n+ 620\n+ 621 template\n+ 622 void FastAMG\n+ 623 ::postsmooth(LevelContext& levelContext, Domain& x, const Range& b)\n+ 624 {\n+ 625 constexpr auto bl = blockLevel();\n+ 626 GaussSeidelPostsmoothDefect\n+ 627::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);\n+ 628 }\n+ 629\n+ 630\n+ 631 template\n+632 bool FastAMG::usesDirectCoarseLevelSolver() const\n+ 633 {\n+ 634 return IsDirectSolver<_CoarseSolver>::value;\n+ 635 }\n+ 636\n+ 637 template\n+ 638 void FastAMG::mgc(LevelContext& levelContext, Domain& v, const\n+Range& b){\n+ 639\n+ 640 if(levelContext.matrix == matrices_->matrices().coarsest() && levels\n+()==maxlevels()) {\n+ 641 // Solve directly\n+ 642 InverseOperatorResult res;\n+ 643 res.converged=true; // If we do not compute this flag will not get updated\n+ 644 if(levelContext.redist->isSetup()) {\n+ 645 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());\n+ 646 if(levelContext.rhs.getRedistributed().size()>0) {\n+ 647 // We are still participating in the computation\n+ 648 levelContext.pinfo.getRedistributed().copyOwnerToAll\n+(levelContext.rhs.getRedistributed(),\n+ 649 levelContext.rhs.getRedistributed());\n+ 650 solver_->apply(levelContext.lhs.getRedistributed(),\n+levelContext.rhs.getRedistributed(), res);\n+ 651 }\n+ 652 levelContext.redist->redistributeBackward(v,\n+levelContext.lhs.getRedistributed());\n+ 653 levelContext.pinfo->copyOwnerToAll(v, v);\n+ 654 }else{\n+ 655 levelContext.pinfo->copyOwnerToAll(b, b);\n+ 656 solver_->apply(v, const_cast(b), res);\n+ 657 }\n+ 658\n+ 659 // printvector(std::cout, *lhs, \"coarse level update\", \"u\", 10, 10, 10);\n+ 660 // printvector(std::cout, *rhs, \"coarse level rhs\", \"rhs\", 10, 10, 10);\n+ 661 if (!res.converged)\n+ 662 coarsesolverconverged = false;\n+ 663 }else{\n+ 664 // presmoothing\n+ 665 presmooth(levelContext, v, b);\n+ 666 // printvector(std::cout, *lhs, \"update\", \"u\", 10, 10, 10);\n+ 667 // printvector(std::cout, *residual, \"post presmooth residual\", \"r\", 10);\n+ 668#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n+ 669 bool processNextLevel = moveToCoarseLevel(levelContext);\n+ 670\n+ 671 if(processNextLevel) {\n+ 672 // next level\n+ 673 for(std::size_t i=0; imatrices().finest()) {\n+ 683 coarsesolverconverged = matrices_->parallelInformation().finest()-\n+>communicator().prod(coarsesolverconverged);\n+ 684 if(!coarsesolverconverged)\n+ 685 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n+ 686 }\n+ 687\n+ 688 postsmooth(levelContext, v, b);\n+ 689 }\n+ 690 }\n+ 691\n+ 692\n+ 694 template\n+695 void FastAMG::post([[maybe_unused]] Domain& x)\n+ 696 {\n+ 697 lhs_=nullptr;\n+ 698 rhs_=nullptr;\n+ 699 residual_=nullptr;\n+ 700 }\n+ 701\n+ 702 template\n+ 703 template\n+704 void FastAMG::getCoarsestAggregateNumbers(std::vector& cont)\n+ 705 {\n+ 706 matrices_->getCoarsestAggregatesOnFinest(cont);\n+ 707 }\n+ 708\n+ 709 } // end namespace Amg\n+ 710} // end namespace Dune\n+ 711\n+ 712#endif\n+io.hh\n+Some generic functions for pretty printing vectors and matrices.\n+superlu.hh\n+Classes for using SuperLU with ISTL matrices.\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+solvertype.hh\n+Templates characterizing the type of a solver.\n+umfpack.hh\n+Classes for using UMFPack with ISTL matrices.\n+transfer.hh\n+Prolongation and restriction for amg.\n+fastamgsmoother.hh\n+matrixhierarchy.hh\n+Provides a classes representing the hierarchies in AMG.\n+smoother.hh\n+Classes for the generic construction and application of the smoothers.\n+solvers.hh\n+Implementations of the inverse operator interface.\n+preconditioners.hh\n+Define general preconditioner interface.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::Amg::presmooth\n+void presmooth(LevelContext &levelContext, size_t steps)\n+Apply pre smoothing on the current level.\n+Definition: smoother.hh:406\n+Dune::Amg::ConstructionTraits::Arguments\n+const void * Arguments\n+A type holding all the arguments needed to call the constructor.\n+Definition: construction.hh:44\n+Dune::Amg::ConstructionTraits::construct\n+static std::shared_ptr< T > construct(Arguments &args)\n+Construct an object with the specified arguments.\n+Definition: construction.hh:52\n+Dune::Amg::postsmooth\n+void postsmooth(LevelContext &levelContext, size_t steps)\n+Apply post smoothing on the current level.\n+Definition: smoother.hh:428\n+Dune::Amg::FastAMG::LevelContext::matrix\n+OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix\n+The iterator over the matrices.\n+Definition: fastamg.hh:184\n+Dune::Amg::FastAMG::getCoarsestAggregateNumbers\n+void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)\n+Get the aggregate number of each unknown on the coarsest level.\n+Definition: fastamg.hh:704\n+Dune::Amg::FastAMG::LevelContext::pinfo\n+ParallelInformationHierarchy::Iterator pinfo\n+The iterator over the parallel information.\n+Definition: fastamg.hh:188\n+Dune::Amg::FastAMG::recalculateHierarchy\n+void recalculateHierarchy()\n+Recalculate the matrix hierarchy.\n+Definition: fastamg.hh:150\n+Dune::Amg::FastAMG::post\n+void post(Domain &x)\n+Clean up.\n+Definition: fastamg.hh:695\n+Dune::Amg::FastAMG::maxlevels\n+std::size_t maxlevels()\n+Definition: fastamg.hh:481\n+Dune::Amg::FastAMG::Domain\n+X Domain\n+The domain type.\n+Definition: fastamg.hh:77\n+Dune::Amg::FastAMG::LevelContext::residual\n+Hierarchy< Domain, A >::Iterator residual\n+The iterator over the residuals.\n+Definition: fastamg.hh:204\n+Dune::Amg::FastAMG::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: fastamg.hh:123\n+Dune::Amg::FastAMG::OperatorHierarchy\n+MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy\n+The operator hierarchy type.\n+Definition: fastamg.hh:72\n+Dune::Amg::FastAMG::LevelContext::redist\n+OperatorHierarchy::RedistributeInfoList::const_iterator redist\n+The iterator over the redistribution information.\n+Definition: fastamg.hh:192\n+Dune::Amg::FastAMG::Range\n+X Range\n+The range type.\n+Definition: fastamg.hh:79\n+Dune::Amg::FastAMG::ParallelInformation\n+PI ParallelInformation\n+The type of the parallel information. Either OwnerOverlapCommunication or\n+another type describing the...\n+Definition: fastamg.hh:70\n+Dune::Amg::FastAMG::Operator\n+M Operator\n+The matrix operator type.\n+Definition: fastamg.hh:63\n+Dune::Amg::FastAMG::levels\n+std::size_t levels()\n+Definition: fastamg.hh:476\n+Dune::Amg::FastAMG::CoarseSolver\n+InverseOperator< X, X > CoarseSolver\n+the type of the coarse solver.\n+Definition: fastamg.hh:81\n+Dune::Amg::FastAMG::usesDirectCoarseLevelSolver\n+bool usesDirectCoarseLevelSolver() const\n+Check whether the coarse solver used is a direct solver.\n+Definition: fastamg.hh:632\n+Dune::Amg::FastAMG::LevelContext::lhs\n+Hierarchy< Domain, A >::Iterator lhs\n+The iterator over the left hand side.\n+Definition: fastamg.hh:200\n+Dune::Amg::FastAMG::LevelContext::rhs\n+Hierarchy< Range, A >::Iterator rhs\n+The iterator over the right hand sided.\n+Definition: fastamg.hh:208\n+Dune::Amg::FastAMG::LevelContext::level\n+std::size_t level\n+The level index.\n+Definition: fastamg.hh:212\n+Dune::Amg::FastAMG::apply\n+void apply(Domain &v, const Range &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: fastamg.hh:488\n+Dune::Amg::FastAMG::ParallelInformationHierarchy\n+OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy\n+The parallal data distribution hierarchy type.\n+Definition: fastamg.hh:74\n+Dune::Amg::FastAMG::pre\n+void pre(Domain &x, Range &b)\n+Prepare the preconditioner.\n+Definition: fastamg.hh:427\n+Dune::Amg::FastAMG::FastAMG\n+FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const\n+Parameters &parms, bool symmetric=true)\n+Construct a new amg with a specific coarse solver.\n+Definition: fastamg.hh:297\n+Dune::Amg::FastAMG::LevelContext::aggregates\n+OperatorHierarchy::AggregatesMapList::const_iterator aggregates\n+The iterator over the aggregates maps.\n+Definition: fastamg.hh:196\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::Amg::AggregatesMap\n-Class providing information about the mapping of the vertices onto aggregates.\n-Definition: aggregates.hh:560\n-Dune::Amg::IndicesCoarsener\n-Definition: indicescoarsener.hh:36\n-Dune::Amg::ParallelIndicesCoarsener\n-Definition: indicescoarsener.hh:43\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n-Dune::Amg::AggregateRenumberer\n-Definition: renumberer.hh:16\n-Dune::Amg::AggregateRenumberer::operator++\n-void operator++()\n-Definition: renumberer.hh:57\n-Dune::Amg::AggregateRenumberer::operator()\n-void operator()(const typename G::ConstEdgeIterator &edge)\n-Definition: renumberer.hh:51\n-Dune::Amg::AggregateRenumberer::number_\n-Vertex number_\n-Definition: renumberer.hh:35\n+Dune::MatrixMarketImpl::symmetric\n+@ symmetric\n+Definition: matrixmarket.hh:303\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator\n+ConstIterator class for sequential access.\n+Definition: matrix.hh:404\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::field_type\n+typename Imp::BlockTraits< T >::field_type field_type\n+Export the type representing the underlying field.\n+Definition: matrix.hh:565\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::block_type\n+T block_type\n+Export the type representing the components.\n+Definition: matrix.hh:568\n+Dune::Amg::FastAMG\n+A fast (sequential) algebraic multigrid based on agglomeration that saves\n+memory bandwidth.\n+Definition: fastamg.hh:60\n+Dune::Amg::GaussSeidelPresmoothDefect::apply\n+static void apply(const M &A, X &x, Y &d, const Y &b)\n+Definition: fastamgsmoother.hh:19\n+Dune::Amg::GaussSeidelPostsmoothDefect::apply\n+static void apply(const M &A, X &x, Y &d, const Y &b)\n+Definition: fastamgsmoother.hh:55\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n+LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n+> Iterator\n+Type of the mutable iterator.\n+Definition: hierarchy.hh:216\n+Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n+LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n+MatrixOperator > ConstIterator\n+Type of the const iterator.\n+Definition: hierarchy.hh:219\n+Dune::Amg::MatrixHierarchy\n+The hierarchies build by the coarsening process.\n+Definition: matrixhierarchy.hh:61\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n+Dune::Amg::SmootherTraits\n+Traits class for getting the attribute class of a smoother.\n+Definition: smoother.hh:66\n+Dune::Amg::Transfer::restrictVector\n+static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, const Vector &fine, T &comm)\n+Dune::Amg::Transfer::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::SeqSSOR\n+Sequential SSOR preconditioner.\n+Definition: preconditioners.hh:141\n+Dune::ScalarProduct\n+Base class for scalar product and norm computation.\n+Definition: scalarproducts.hh:52\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperatorResult::converged\n+bool converged\n+True if convergence criterion has been met.\n+Definition: solver.hh:73\n+Dune::InverseOperator<_X,_X_>\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00140.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00140.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: fastamg.hh File Reference\n+dune-istl: hierarchy.hh File Reference\n \n \n \n \n \n \n \n@@ -64,75 +64,50 @@\n \n \n \n
    \n \n-
    fastamg.hh File Reference
    \n+Namespaces
    \n+ \n \n
    \n \n-

    A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers. \n+

    Provides a classes representing the hierarchies in AMG. \n More...

    \n-
    #include <memory>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/istl/paamg/smoother.hh>
    \n-#include <dune/istl/paamg/transfer.hh>
    \n-#include <dune/istl/paamg/matrixhierarchy.hh>
    \n-#include <dune/istl/solvers.hh>
    \n-#include <dune/istl/scalarproducts.hh>
    \n-#include <dune/istl/superlu.hh>
    \n-#include <dune/istl/umfpack.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n-#include <dune/istl/io.hh>
    \n-#include <dune/istl/preconditioners.hh>
    \n-#include "fastamgsmoother.hh"
    \n+
    #include <list>
    \n+#include <memory>
    \n+#include <limits>
    \n+#include <dune/common/stdstreams.hh>
    \n+#include <dune/common/timer.hh>
    \n+#include <dune/common/bigunsignedint.hh>
    \n+#include <dune/istl/paamg/construction.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::FastAMG< M, X, PI, A >
     A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth. More...
    class  Dune::Amg::Hierarchy< T, A >
     A hierarchy of containers (e.g. matrices or vectors) More...
     
    class  Dune::Amg::Hierarchy< T, A >::LevelIterator< C, T1 >
     Iterator over the levels in the hierarchy. More...
     
    \n \n \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n

    \n-Macros

    #define DIRECTSOLVER   SuperLU
     
    \n

    Detailed Description

    \n-

    A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers.

    \n+

    Provides a classes representing the hierarchies in AMG.

    \n
    Author
    Markus Blatt
    \n-

    Macro Definition Documentation

    \n-\n-

    ◆ DIRECTSOLVER

    \n-\n-
    \n-
    \n- \n- \n- \n- \n-
    #define DIRECTSOLVER   SuperLU
    \n-
    \n-\n-
    \n-
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,52 +5,39 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces | Macros\n-fastamg.hh File Reference\n-A fast AMG method, that currently only allows only Gauss-Seidel smoothing and\n-is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep\n-with the defect calculation to reduce memory transfers. More...\n+Classes | Namespaces\n+hierarchy.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides a classes representing the hierarchies in AMG. More...\n+#include \n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"fastamgsmoother.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::FastAMG<_M,_X,_PI,_A_>\n-\u00a0 A fast (sequential) algebraic multigrid based on agglomeration that\n- saves memory bandwidth. More...\n+class \u00a0Dune::Amg::Hierarchy<_T,_A_>\n+\u00a0 A hierarchy of containers (e.g. matrices or vectors) More...\n+\u00a0\n+class \u00a0Dune::Amg::Hierarchy<_T,_A_>::LevelIterator<_C,_T1_>\n+\u00a0 Iterator over the levels in the hierarchy. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n- Macros\n-#define\u00a0DIRECTSOLVER\u00a0\u00a0\u00a0SuperLU\n-\u00a0\n ***** Detailed Description *****\n-A fast AMG method, that currently only allows only Gauss-Seidel smoothing and\n-is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep\n-with the defect calculation to reduce memory transfers.\n+Provides a classes representing the hierarchies in AMG.\n Author\n Markus Blatt\n-***** Macro Definition Documentation *****\n-***** \u25c6\u00a0DIRECTSOLVER *****\n-#define DIRECTSOLVER\u00a0\u00a0\u00a0SuperLU\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00140_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00140_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: fastamg.hh Source File\n+dune-istl: hierarchy.hh Source File\n \n \n \n \n \n \n \n@@ -62,639 +62,347 @@\n \n
    \n \n
    \n \n
    \n-
    fastamg.hh
    \n+
    hierarchy.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_FASTAMG_HH
    \n-
    6#define DUNE_ISTL_FASTAMG_HH
    \n+
    5#ifndef DUNE_AMGHIERARCHY_HH
    \n+
    6#define DUNE_AMGHIERARCHY_HH
    \n
    7
    \n-
    8#include <memory>
    \n-
    9#include <dune/common/exceptions.hh>
    \n-
    10#include <dune/common/typetraits.hh>
    \n-\n-\n-\n-
    14#include <dune/istl/solvers.hh>
    \n-\n-
    16#include <dune/istl/superlu.hh>
    \n-
    17#include <dune/istl/umfpack.hh>
    \n-\n-
    19#include <dune/istl/io.hh>
    \n-\n-
    21
    \n-
    22#include "fastamgsmoother.hh"
    \n-
    23
    \n-
    32namespace Dune
    \n-
    33{
    \n-
    34 namespace Amg
    \n-
    35 {
    \n-
    58 template<class M, class X, class PI=SequentialInformation, class A=std::allocator<X> >
    \n-
    59 class FastAMG : public Preconditioner<X,X>
    \n-
    60 {
    \n-
    61 public:
    \n-
    63 typedef M Operator;
    \n-\n-\n-\n-
    75
    \n-
    77 typedef X Domain;
    \n-
    79 typedef X Range;
    \n-\n-
    82
    \n-
    90 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n-
    91 const Parameters& parms,
    \n-
    92 bool symmetric=true);
    \n-
    93
    \n-
    105 template<class C>
    \n-
    106 FastAMG(const Operator& fineOperator, const C& criterion,
    \n-
    107 const Parameters& parms=Parameters(),
    \n-
    108 bool symmetric=true,
    \n-\n+
    8#include <list>
    \n+
    9#include <memory>
    \n+
    10#include <limits>
    \n+
    11#include <dune/common/stdstreams.hh>
    \n+
    12#include <dune/common/timer.hh>
    \n+
    13#include <dune/common/bigunsignedint.hh>
    \n+\n+
    15
    \n+
    16namespace Dune
    \n+
    17{
    \n+
    18 namespace Amg
    \n+
    19 {
    \n+
    38 template<typename T, typename A=std::allocator<T> >
    \n+\n+
    40 {
    \n+
    41 public:
    \n+
    45 typedef T MemberType;
    \n+
    46
    \n+
    47 template<typename T1, typename T2>
    \n+
    48 class LevelIterator;
    \n+
    49
    \n+
    50 private:
    \n+
    54 struct Element
    \n+
    55 {
    \n+
    56 friend class LevelIterator<Hierarchy<T,A>, T>;
    \n+
    57 friend class LevelIterator<const Hierarchy<T,A>, const T>;
    \n+
    58
    \n+
    60 std::weak_ptr<Element> coarser_;
    \n+
    61
    \n+
    63 std::shared_ptr<Element> finer_;
    \n+
    64
    \n+
    66 std::shared_ptr<MemberType> element_;
    \n+
    67
    \n+
    69 std::shared_ptr<MemberType> redistributed_;
    \n+
    70 };
    \n+
    71 public:
    \n+
    72
    \n+
    76 using Allocator = typename std::allocator_traits<A>::template rebind_alloc<Element>;
    \n+
    77
    \n+\n+
    79
    \n+
    84 Hierarchy(const std::shared_ptr<MemberType> & first);
    \n+
    85
    \n+
    89 Hierarchy() : levels_(0)
    \n+
    90 {}
    \n+
    91
    \n+
    95 Hierarchy(const Hierarchy& other);
    \n+
    96
    \n+\n+
    102
    \n+\n+
    104
    \n+
    109 void addFiner(Arguments& args);
    \n
    110
    \n-
    114 FastAMG(const FastAMG& amg);
    \n-
    115
    \n-
    117 void pre(Domain& x, Range& b);
    \n-
    118
    \n-
    120 void apply(Domain& v, const Range& d);
    \n-
    121
    \n-\n-
    124 {
    \n-\n-
    126 }
    \n-
    127
    \n-
    129 void post(Domain& x);
    \n+
    117 template<class C, class T1>
    \n+\n+
    119 : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
    \n+
    120 {
    \n+
    121 friend class LevelIterator<typename std::remove_const<C>::type,
    \n+
    122 typename std::remove_const<T1>::type >;
    \n+
    123 friend class LevelIterator<const typename std::remove_const<C>::type,
    \n+
    124 const typename std::remove_const<T1>::type >;
    \n+
    125
    \n+
    126 public:
    \n+\n+
    129 {}
    \n
    130
    \n-
    135 template<class A1>
    \n-
    136 void getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont);
    \n-
    137
    \n-
    138 std::size_t levels();
    \n-
    139
    \n-
    140 std::size_t maxlevels();
    \n-
    141
    \n-\n-
    151 {
    \n-
    152 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
    \n-
    153 }
    \n-
    154
    \n-
    159 bool usesDirectCoarseLevelSolver() const;
    \n-
    160
    \n-
    161 private:
    \n-
    168 template<class C>
    \n-
    169 void createHierarchies(C& criterion,
    \n-
    170 const std::shared_ptr<const Operator>& matrixptr,
    \n-
    171 const PI& pinfo);
    \n-
    172
    \n-
    179 struct LevelContext
    \n-
    180 {
    \n-\n-\n-
    192 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
    \n-
    196 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
    \n-\n-\n-\n-
    212 std::size_t level;
    \n+
    131 LevelIterator(std::shared_ptr<Element> element)
    \n+
    132 : element_(element)
    \n+
    133 {}
    \n+
    134
    \n+
    136 LevelIterator(const LevelIterator<typename std::remove_const<C>::type,
    \n+
    137 typename std::remove_const<T1>::type>& other)
    \n+
    138 : element_(other.element_)
    \n+
    139 {}
    \n+
    140
    \n+
    142 LevelIterator(const LevelIterator<const typename std::remove_const<C>::type,
    \n+
    143 const typename std::remove_const<T1>::type>& other)
    \n+
    144 : element_(other.element_)
    \n+
    145 {}
    \n+
    146
    \n+
    150 bool equals(const LevelIterator<typename std::remove_const<C>::type,
    \n+
    151 typename std::remove_const<T1>::type>& other) const
    \n+
    152 {
    \n+
    153 return element_ == other.element_;
    \n+
    154 }
    \n+
    155
    \n+
    159 bool equals(const LevelIterator<const typename std::remove_const<C>::type,
    \n+
    160 const typename std::remove_const<T1>::type>& other) const
    \n+
    161 {
    \n+
    162 return element_ == other.element_;
    \n+
    163 }
    \n+
    164
    \n+
    166 T1& dereference() const
    \n+
    167 {
    \n+
    168 return *(element_->element_);
    \n+
    169 }
    \n+
    170
    \n+\n+
    173 {
    \n+
    174 element_ = element_->coarser_.lock();
    \n+
    175 }
    \n+
    176
    \n+\n+
    179 {
    \n+
    180 element_ = element_->finer_;
    \n+
    181 }
    \n+
    182
    \n+
    187 bool isRedistributed() const
    \n+
    188 {
    \n+
    189 return (bool)element_->redistributed_;
    \n+
    190 }
    \n+
    191
    \n+\n+
    197 {
    \n+
    198 assert(element_->redistributed_);
    \n+
    199 return *element_->redistributed_;
    \n+
    200 }
    \n+
    201 void addRedistributed(std::shared_ptr<T1> t)
    \n+
    202 {
    \n+
    203 element_->redistributed_ = t;
    \n+
    204 }
    \n+
    205
    \n+\n+
    207 {
    \n+
    208 element_->redistributed_ = nullptr;
    \n+
    209 }
    \n+
    210
    \n+
    211 private:
    \n+
    212 std::shared_ptr<Element> element_;
    \n
    213 };
    \n
    214
    \n-
    216 void mgc(LevelContext& levelContext, Domain& x, const Range& b);
    \n+\n
    217
    \n-
    224 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);
    \n-
    225
    \n-
    232 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);
    \n+\n+
    220
    \n+\n+
    226
    \n+\n+
    232
    \n
    233
    \n-
    240 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,
    \n-
    241 Domain& fineX);
    \n-
    242
    \n-
    247 bool moveToCoarseLevel(LevelContext& levelContext);
    \n-
    248
    \n-
    253 void initIteratorsWithFineLevel(LevelContext& levelContext);
    \n-
    254
    \n-
    256 std::shared_ptr<OperatorHierarchy> matrices_;
    \n-
    258 std::shared_ptr<CoarseSolver> solver_;
    \n-
    260 std::shared_ptr<Hierarchy<Range,A>> rhs_;
    \n-
    262 std::shared_ptr<Hierarchy<Domain,A>> lhs_;
    \n-
    264 std::shared_ptr<Hierarchy<Domain,A>> residual_;
    \n-
    265
    \n-\n-
    269 std::shared_ptr<ScalarProduct> scalarProduct_;
    \n-
    271 std::size_t gamma_;
    \n-
    273 std::size_t preSteps_;
    \n-
    275 std::size_t postSteps_;
    \n-
    276 std::size_t level;
    \n-
    277 bool buildHierarchy_;
    \n-
    278 bool symmetric;
    \n-
    279 bool coarsesolverconverged;
    \n-\n-
    281 typedef std::shared_ptr<Smoother> SmootherPointer;
    \n-
    282 SmootherPointer coarseSmoother_;
    \n-
    284 std::size_t verbosity_;
    \n-
    285 };
    \n-
    286
    \n-
    287 template<class M, class X, class PI, class A>
    \n-\n-
    289 : matrices_(amg.matrices_), solver_(amg.solver_),
    \n-
    290 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),
    \n-
    291 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
    \n-
    292 symmetric(amg.symmetric), coarsesolverconverged(amg.coarsesolverconverged),
    \n-
    293 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)
    \n-
    294 {}
    \n+\n+
    239
    \n+\n+
    245
    \n+
    250 std::size_t levels() const;
    \n+
    251
    \n+
    252 private:
    \n+
    258 std::shared_ptr<MemberType> originalFinest_;
    \n+
    260 std::shared_ptr<Element> finest_;
    \n+
    262 std::shared_ptr<Element> coarsest_;
    \n+
    264 Allocator allocator_;
    \n+
    266 int levels_;
    \n+
    267 };
    \n+
    268
    \n+
    269 template<class T, class A>
    \n+
    270 Hierarchy<T,A>::Hierarchy(const std::shared_ptr<MemberType> & first)
    \n+
    271 : originalFinest_(first)
    \n+
    272 {
    \n+
    273 finest_ = std::allocate_shared<Element>(allocator_);
    \n+
    274 finest_->element_ = originalFinest_;
    \n+
    275 coarsest_ = finest_;
    \n+
    276 levels_ = 1;
    \n+
    277 }
    \n+
    278
    \n+
    280 //TODO: do we actually want to support this? This might be very expensive?!
    \n+
    281 template<class T, class A>
    \n+\n+
    283 : allocator_(other.allocator_),
    \n+
    284 levels_(other.levels_)
    \n+
    285 {
    \n+
    286 if(!other.finest_)
    \n+
    287 {
    \n+
    288 finest_=coarsest_=nullptr;
    \n+
    289 return;
    \n+
    290 }
    \n+
    291 finest_ = std::allocate_shared<Element>(allocator_);
    \n+
    292 std::shared_ptr<Element> finer_;
    \n+
    293 std::shared_ptr<Element> current_ = finest_;
    \n+
    294 std::weak_ptr<Element> otherWeak_ = other.finest_;
    \n
    295
    \n-
    296 template<class M, class X, class PI, class A>
    \n-\n-
    298 const Parameters& parms, bool symmetric_)
    \n-
    299 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),
    \n-
    300 rhs_(), lhs_(), residual_(), scalarProduct_(),
    \n-
    301 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
    \n-
    302 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
    \n-
    303 symmetric(symmetric_), coarsesolverconverged(true),
    \n-
    304 coarseSmoother_(), verbosity_(parms.debugLevel())
    \n-
    305 {
    \n-
    306 if(preSteps_>1||postSteps_>1)
    \n-
    307 {
    \n-
    308 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
    \n-
    309 preSteps_=postSteps_=0;
    \n-
    310 }
    \n-
    311 assert(matrices_->isBuilt());
    \n-
    312 static_assert(std::is_same<PI,SequentialInformation>::value,
    \n-
    313 "Currently only sequential runs are supported");
    \n-
    314 }
    \n-
    315 template<class M, class X, class PI, class A>
    \n-
    316 template<class C>
    \n-\n-
    318 const C& criterion,
    \n-
    319 const Parameters& parms,
    \n-
    320 bool symmetric_,
    \n-
    321 const PI& pinfo)
    \n-
    322 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_(parms.getGamma()),
    \n-
    323 preSteps_(parms.getNoPreSmoothSteps()), postSteps_(parms.getNoPostSmoothSteps()),
    \n-
    324 buildHierarchy_(true),
    \n-
    325 symmetric(symmetric_), coarsesolverconverged(true),
    \n-
    326 coarseSmoother_(), verbosity_(criterion.debugLevel())
    \n-
    327 {
    \n-
    328 if(preSteps_>1||postSteps_>1)
    \n-
    329 {
    \n-
    330 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
    \n-
    331 preSteps_=postSteps_=1;
    \n-
    332 }
    \n-
    333 static_assert(std::is_same<PI,SequentialInformation>::value,
    \n-
    334 "Currently only sequential runs are supported");
    \n-
    335 // TODO: reestablish compile time checks.
    \n-
    336 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
    \n-
    337 // "Matrix and Solver must match in terms of category!");
    \n-
    338 auto matrixptr = stackobject_to_shared_ptr(matrix);
    \n-
    339 createHierarchies(criterion, matrixptr, pinfo);
    \n-
    340 }
    \n-
    341
    \n-
    342 template<class M, class X, class PI, class A>
    \n-
    343 template<class C>
    \n-
    344 void FastAMG<M,X,PI,A>::createHierarchies(C& criterion,
    \n-
    345 const std::shared_ptr<const Operator>& matrixptr,
    \n-
    346 const PI& pinfo)
    \n-
    347 {
    \n-
    348 Timer watch;
    \n-
    349 matrices_ = std::make_shared<OperatorHierarchy>(
    \n-
    350 std::const_pointer_cast<Operator>(matrixptr),
    \n-
    351 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
    \n-
    352
    \n-
    353 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
    \n+
    296 while(! otherWeak_.expired())
    \n+
    297 {
    \n+
    298 // create shared_ptr from weak_ptr, we just checked that this is safe
    \n+
    299 std::shared_ptr<Element> otherCurrent_ = std::shared_ptr<Element>(otherWeak_);
    \n+
    300 // clone current level
    \n+
    301 //TODO: should we use the allocator?
    \n+
    302 current_->element_ =
    \n+
    303 std::make_shared<MemberType>(*(otherCurrent_->element_));
    \n+
    304 current_->finer_=finer_;
    \n+
    305 if(otherCurrent_->redistributed_)
    \n+
    306 current_->redistributed_ =
    \n+
    307 std::make_shared<MemberType>(*(otherCurrent_->redistributed_));
    \n+
    308 finer_=current_;
    \n+
    309 if(not otherCurrent_->coarser_.expired())
    \n+
    310 {
    \n+
    311 auto c = std::allocate_shared<Element>(allocator_);
    \n+
    312 current_->coarser_ = c;
    \n+
    313 current_ = c;
    \n+
    314 }
    \n+
    315 // go to coarser level
    \n+
    316 otherWeak_ = otherCurrent_->coarser_;
    \n+
    317 }
    \n+
    318 coarsest_=current_;
    \n+
    319 }
    \n+
    320
    \n+
    321 template<class T, class A>
    \n+
    322 std::size_t Hierarchy<T,A>::levels() const
    \n+
    323 {
    \n+
    324 return levels_;
    \n+
    325 }
    \n+
    326
    \n+
    327 template<class T, class A>
    \n+\n+
    329 {
    \n+
    330 coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
    \n+
    331 }
    \n+
    332
    \n+
    333 template<class T, class A>
    \n+\n+
    335 {
    \n+
    336 if(!coarsest_) {
    \n+
    337 // we have no levels at all...
    \n+
    338 assert(!finest_);
    \n+
    339 // allocate into the shared_ptr
    \n+
    340 originalFinest_ = ConstructionTraits<MemberType>::construct(args);
    \n+
    341 coarsest_ = std::allocate_shared<Element>(allocator_);
    \n+
    342 coarsest_->element_ = originalFinest_;
    \n+
    343 finest_ = coarsest_;
    \n+
    344 }else{
    \n+
    345 auto old_coarsest = coarsest_;
    \n+
    346 coarsest_ = std::allocate_shared<Element>(allocator_);
    \n+
    347 coarsest_->finer_ = old_coarsest;
    \n+
    348 coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
    \n+
    349 old_coarsest->coarser_ = coarsest_;
    \n+
    350 }
    \n+
    351 ++levels_;
    \n+
    352 }
    \n+
    353
    \n
    354
    \n-
    355 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n-
    356 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    357
    \n-
    358 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()) {
    \n-
    359 // We have the carsest level. Create the coarse Solver
    \n-
    360 typedef typename SmootherTraits<Smoother>::Arguments SmootherArgs;
    \n-
    361 SmootherArgs sargs;
    \n-
    362 sargs.iterations = 1;
    \n-
    363
    \n-\n-
    365 cargs.setArgs(sargs);
    \n-
    366 if(matrices_->redistributeInformation().back().isSetup()) {
    \n-
    367 // Solve on the redistributed partitioning
    \n-
    368 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
    \n-
    369 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
    \n-
    370 }else{
    \n-
    371 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
    \n-
    372 cargs.setComm(*matrices_->parallelInformation().coarsest());
    \n-
    373 }
    \n-
    374
    \n-
    375 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
    \n-
    376 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
    \n-
    377
    \n-
    378#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
    \n-
    379#if HAVE_SUITESPARSE_UMFPACK
    \n-
    380#define DIRECTSOLVER UMFPack
    \n-
    381#else
    \n-
    382#define DIRECTSOLVER SuperLU
    \n-
    383#endif
    \n-
    384 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
    \n-
    385 if(std::is_same<ParallelInformation,SequentialInformation>::value // sequential mode
    \n-
    386 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
    \n-
    387 || (matrices_->parallelInformation().coarsest().isRedistributed()
    \n-
    388 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
    \n-
    389 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0)) { // redistribute and 1 proc
    \n-
    390 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
    \n-
    391 std::cout<<"Using superlu"<<std::endl;
    \n-
    392 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n-
    393 {
    \n-
    394 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n-
    395 // We are still participating on this level
    \n-
    396 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
    \n-
    397 else
    \n-
    398 solver_.reset();
    \n-
    399 }else
    \n-
    400 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest()->getmat(), false, false));
    \n-
    401 }else
    \n-
    402#undef DIRECTSOLVER
    \n-
    403#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
    \n-
    404 {
    \n-
    405 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n-
    406 {
    \n-
    407 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n-
    408 // We are still participating on this level
    \n-
    409 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
    \n-
    410 *scalarProduct_,
    \n-
    411 *coarseSmoother_, 1E-2, 1000, 0));
    \n-
    412 else
    \n-
    413 solver_.reset();
    \n-
    414 }else
    \n-
    415 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
    \n-
    416 *scalarProduct_,
    \n-
    417 *coarseSmoother_, 1E-2, 1000, 0));
    \n-
    418 }
    \n-
    419 }
    \n-
    420
    \n-
    421 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n-
    422 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    423 }
    \n-
    424
    \n-
    425
    \n-
    426 template<class M, class X, class PI, class A>
    \n-\n-
    428 {
    \n-
    429 Timer watch, watch1;
    \n-
    430 // Detect Matrix rows where all offdiagonal entries are
    \n-
    431 // zero and set x such that A_dd*x_d=b_d
    \n-
    432 // Thus users can be more careless when setting up their linear
    \n-
    433 // systems.
    \n-
    434 typedef typename M::matrix_type Matrix;
    \n-
    435 typedef typename Matrix::ConstRowIterator RowIter;
    \n-
    436 typedef typename Matrix::ConstColIterator ColIter;
    \n-
    437 typedef typename Matrix::block_type Block;
    \n-
    438 Block zero;
    \n-
    439 zero=typename Matrix::field_type();
    \n-
    440
    \n-
    441 const Matrix& mat=matrices_->matrices().finest()->getmat();
    \n-
    442 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {
    \n-
    443 bool isDirichlet = true;
    \n-
    444 bool hasDiagonal = false;
    \n-
    445 ColIter diag;
    \n-
    446 for(ColIter col=row->begin(); col!=row->end(); ++col) {
    \n-
    447 if(row.index()==col.index()) {
    \n-
    448 diag = col;
    \n-
    449 hasDiagonal = (*col != zero);
    \n-
    450 }else{
    \n-
    451 if(*col!=zero)
    \n-
    452 isDirichlet = false;
    \n-
    453 }
    \n-
    454 }
    \n-
    455 if(isDirichlet && hasDiagonal)
    \n-
    456 diag->solve(x[row.index()], b[row.index()]);
    \n-
    457 }
    \n-
    458 if (verbosity_>0)
    \n-
    459 std::cout<<" Preprocessing Dirichlet took "<<watch1.elapsed()<<std::endl;
    \n-
    460 watch1.reset();
    \n-
    461 // No smoother to make x consistent! Do it by hand
    \n-
    462 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
    \n-
    463 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
    \n-
    464 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n-
    465 residual_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n-
    466 matrices_->coarsenVector(*rhs_);
    \n-
    467 matrices_->coarsenVector(*lhs_);
    \n-
    468 matrices_->coarsenVector(*residual_);
    \n-
    469
    \n-
    470 // The preconditioner might change x and b. So we have to
    \n-
    471 // copy the changes to the original vectors.
    \n-
    472 x = *lhs_->finest();
    \n-
    473 b = *rhs_->finest();
    \n-
    474 }
    \n-
    475 template<class M, class X, class PI, class A>
    \n-\n-
    477 {
    \n-
    478 return matrices_->levels();
    \n-
    479 }
    \n-
    480 template<class M, class X, class PI, class A>
    \n-\n-
    482 {
    \n-
    483 return matrices_->maxlevels();
    \n-
    484 }
    \n-
    485
    \n-
    487 template<class M, class X, class PI, class A>
    \n-\n-
    489 {
    \n-
    490 LevelContext levelContext;
    \n-
    491 // Init all iterators for the current level
    \n-
    492 initIteratorsWithFineLevel(levelContext);
    \n-
    493
    \n-
    494 assert(v.two_norm()==0);
    \n-
    495
    \n-
    496 level=0;
    \n-
    497 if(matrices_->maxlevels()==1){
    \n-
    498 // The coarse solver might modify the d!
    \n-
    499 Range b(d);
    \n-
    500 mgc(levelContext, v, b);
    \n-
    501 }else
    \n-
    502 mgc(levelContext, v, d);
    \n-
    503 if(postSteps_==0||matrices_->maxlevels()==1)
    \n-
    504 levelContext.pinfo->copyOwnerToAll(v, v);
    \n-
    505 }
    \n-
    506
    \n-
    507 template<class M, class X, class PI, class A>
    \n-
    508 void FastAMG<M,X,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
    \n-
    509 {
    \n-
    510 levelContext.matrix = matrices_->matrices().finest();
    \n-
    511 levelContext.pinfo = matrices_->parallelInformation().finest();
    \n-
    512 levelContext.redist =
    \n-
    513 matrices_->redistributeInformation().begin();
    \n-
    514 levelContext.aggregates = matrices_->aggregatesMaps().begin();
    \n-
    515 levelContext.lhs = lhs_->finest();
    \n-
    516 levelContext.residual = residual_->finest();
    \n-
    517 levelContext.rhs = rhs_->finest();
    \n-
    518 levelContext.level=0;
    \n-
    519 }
    \n-
    520
    \n-
    521 template<class M, class X, class PI, class A>
    \n-
    522 bool FastAMG<M,X,PI,A>
    \n-
    523 ::moveToCoarseLevel(LevelContext& levelContext)
    \n-
    524 {
    \n-
    525 bool processNextLevel=true;
    \n-
    526
    \n-
    527 if(levelContext.redist->isSetup()) {
    \n-
    528 throw "bla";
    \n-
    529 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.residual),
    \n-
    530 levelContext.residual.getRedistributed());
    \n-
    531 processNextLevel = levelContext.residual.getRedistributed().size()>0;
    \n-
    532 if(processNextLevel) {
    \n-
    533 //restrict defect to coarse level right hand side.
    \n-
    534 ++levelContext.pinfo;
    \n-\n-
    536 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n-
    537 static_cast<const Range&>(levelContext.residual.getRedistributed()),
    \n-
    538 *levelContext.pinfo);
    \n-
    539 }
    \n-
    540 }else{
    \n-
    541 //restrict defect to coarse level right hand side.
    \n-
    542 ++levelContext.rhs;
    \n-
    543 ++levelContext.pinfo;
    \n-\n-
    545 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n-
    546 static_cast<const Range&>(*levelContext.residual), *levelContext.pinfo);
    \n-
    547 }
    \n-
    548
    \n-
    549 if(processNextLevel) {
    \n-
    550 // prepare coarse system
    \n-
    551 ++levelContext.residual;
    \n-
    552 ++levelContext.lhs;
    \n-
    553 ++levelContext.matrix;
    \n-
    554 ++levelContext.level;
    \n-
    555 ++levelContext.redist;
    \n-
    556
    \n-
    557 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n-
    558 // next level is not the globally coarsest one
    \n-
    559 ++levelContext.aggregates;
    \n-
    560 }
    \n-
    561 // prepare the lhs on the next level
    \n-
    562 *levelContext.lhs=0;
    \n-
    563 *levelContext.residual=0;
    \n-
    564 }
    \n-
    565 return processNextLevel;
    \n-
    566 }
    \n-
    567
    \n-
    568 template<class M, class X, class PI, class A>
    \n-
    569 void FastAMG<M,X,PI,A>
    \n-
    570 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel, Domain& x)
    \n-
    571 {
    \n-
    572 if(processNextLevel) {
    \n-
    573 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n-
    574 // previous level is not the globally coarsest one
    \n-
    575 --levelContext.aggregates;
    \n-
    576 }
    \n-
    577 --levelContext.redist;
    \n-
    578 --levelContext.level;
    \n-
    579 //prolongate and add the correction (update is in coarse left hand side)
    \n-
    580 --levelContext.matrix;
    \n-
    581 --levelContext.residual;
    \n-
    582
    \n-
    583 }
    \n-
    584
    \n-
    585 typename Hierarchy<Domain,A>::Iterator coarseLhs = levelContext.lhs--;
    \n-
    586 if(levelContext.redist->isSetup()) {
    \n-
    587
    \n-
    588 // Need to redistribute during prolongate
    \n-\n-
    590 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
    \n-
    591 levelContext.lhs.getRedistributed(),
    \n-
    592 matrices_->getProlongationDampingFactor(),
    \n-
    593 *levelContext.pinfo, *levelContext.redist);
    \n-
    594 }else{
    \n-\n-
    596 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
    \n-
    597 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);
    \n-
    598
    \n-
    599 // printvector(std::cout, *lhs, "prolongated coarse grid correction", "lhs", 10, 10, 10);
    \n-
    600 }
    \n-
    601
    \n-
    602
    \n-
    603 if(processNextLevel) {
    \n-
    604 --levelContext.rhs;
    \n-
    605 }
    \n-
    606
    \n-
    607 }
    \n-
    608
    \n-
    609
    \n-
    610 template<class M, class X, class PI, class A>
    \n-
    611 void FastAMG<M,X,PI,A>
    \n-
    612 ::presmooth(LevelContext& levelContext, Domain& x, const Range& b)
    \n-
    613 {
    \n-
    614 constexpr auto bl = blockLevel<typename M::matrix_type>();
    \n-
    615 GaussSeidelPresmoothDefect<bl>::apply(levelContext.matrix->getmat(),
    \n-
    616 x,
    \n-
    617 *levelContext.residual,
    \n-
    618 b);
    \n-
    619 }
    \n-
    620
    \n-
    621 template<class M, class X, class PI, class A>
    \n-
    622 void FastAMG<M,X,PI,A>
    \n-
    623 ::postsmooth(LevelContext& levelContext, Domain& x, const Range& b)
    \n-
    624 {
    \n-
    625 constexpr auto bl = blockLevel<typename M::matrix_type>();
    \n-\n-
    627 ::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);
    \n-
    628 }
    \n-
    629
    \n-
    630
    \n-
    631 template<class M, class X, class PI, class A>
    \n-\n-
    633 {
    \n-\n-
    635 }
    \n-
    636
    \n-
    637 template<class M, class X, class PI, class A>
    \n-
    638 void FastAMG<M,X,PI,A>::mgc(LevelContext& levelContext, Domain& v, const Range& b){
    \n-
    639
    \n-
    640 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
    \n-
    641 // Solve directly
    \n-\n-
    643 res.converged=true; // If we do not compute this flag will not get updated
    \n-
    644 if(levelContext.redist->isSetup()) {
    \n-
    645 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());
    \n-
    646 if(levelContext.rhs.getRedistributed().size()>0) {
    \n-
    647 // We are still participating in the computation
    \n-
    648 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
    \n-
    649 levelContext.rhs.getRedistributed());
    \n-
    650 solver_->apply(levelContext.lhs.getRedistributed(), levelContext.rhs.getRedistributed(), res);
    \n-
    651 }
    \n-
    652 levelContext.redist->redistributeBackward(v, levelContext.lhs.getRedistributed());
    \n-
    653 levelContext.pinfo->copyOwnerToAll(v, v);
    \n-
    654 }else{
    \n-
    655 levelContext.pinfo->copyOwnerToAll(b, b);
    \n-
    656 solver_->apply(v, const_cast<Range&>(b), res);
    \n-
    657 }
    \n-
    658
    \n-
    659 // printvector(std::cout, *lhs, "coarse level update", "u", 10, 10, 10);
    \n-
    660 // printvector(std::cout, *rhs, "coarse level rhs", "rhs", 10, 10, 10);
    \n-
    661 if (!res.converged)
    \n-
    662 coarsesolverconverged = false;
    \n-
    663 }else{
    \n-
    664 // presmoothing
    \n-
    665 presmooth(levelContext, v, b);
    \n-
    666 // printvector(std::cout, *lhs, "update", "u", 10, 10, 10);
    \n-
    667 // printvector(std::cout, *residual, "post presmooth residual", "r", 10);
    \n-
    668#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n-
    669 bool processNextLevel = moveToCoarseLevel(levelContext);
    \n-
    670
    \n-
    671 if(processNextLevel) {
    \n-
    672 // next level
    \n-
    673 for(std::size_t i=0; i<gamma_; i++)
    \n-
    674 mgc(levelContext, *levelContext.lhs, *levelContext.rhs);
    \n-
    675 }
    \n-
    676
    \n-
    677 moveToFineLevel(levelContext, processNextLevel, v);
    \n-
    678#else
    \n-
    679 *lhs=0;
    \n-
    680#endif
    \n-
    681
    \n-
    682 if(levelContext.matrix == matrices_->matrices().finest()) {
    \n-
    683 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
    \n-
    684 if(!coarsesolverconverged)
    \n-
    685 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n-
    686 }
    \n-
    687
    \n-
    688 postsmooth(levelContext, v, b);
    \n-
    689 }
    \n-
    690 }
    \n-
    691
    \n-
    692
    \n-
    694 template<class M, class X, class PI, class A>
    \n-
    695 void FastAMG<M,X,PI,A>::post([[maybe_unused]] Domain& x)
    \n-
    696 {
    \n-
    697 lhs_=nullptr;
    \n-
    698 rhs_=nullptr;
    \n-
    699 residual_=nullptr;
    \n-
    700 }
    \n-
    701
    \n-
    702 template<class M, class X, class PI, class A>
    \n-
    703 template<class A1>
    \n-
    704 void FastAMG<M,X,PI,A>::getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont)
    \n-
    705 {
    \n-
    706 matrices_->getCoarsestAggregatesOnFinest(cont);
    \n-
    707 }
    \n-
    708
    \n-
    709 } // end namespace Amg
    \n-
    710} // end namespace Dune
    \n-
    711
    \n-
    712#endif
    \n-
    Templates characterizing the type of a solver.
    \n-
    Implementations of the inverse operator interface.
    \n-
    Define general preconditioner interface.
    \n-\n-
    Prolongation and restriction for amg.
    \n-
    Classes for the generic construction and application of the smoothers.
    \n-
    Provides a classes representing the hierarchies in AMG.
    \n-
    Define base class for scalar product and norm.
    \n-
    Classes for using UMFPack with ISTL matrices.
    \n-
    Classes for using SuperLU with ISTL matrices.
    \n-
    Some generic functions for pretty printing vectors and matrices.
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n+
    355 template<class T, class A>
    \n+\n+
    357 {
    \n+
    358 //TODO: wouldn't it be better to do this in the constructor?'
    \n+
    359 if(!finest_) {
    \n+
    360 // we have no levels at all...
    \n+
    361 assert(!coarsest_);
    \n+
    362 // allocate into the shared_ptr
    \n+
    363 originalFinest_ = ConstructionTraits<MemberType>::construct(args);
    \n+
    364 finest_ = std::allocate_shared<Element>(allocator_);
    \n+
    365 finest_->element = originalFinest_;
    \n+
    366 coarsest_ = finest_;
    \n+
    367 }else{
    \n+
    368 finest_->finer_ = std::allocate_shared<Element>(allocator_);
    \n+
    369 finest_->finer_->coarser_ = finest_;
    \n+
    370 finest_ = finest_->finer_;
    \n+
    371 finest_->element = ConstructionTraits<T>::construct(args);
    \n+
    372 }
    \n+
    373 ++levels_;
    \n+
    374 }
    \n+
    375
    \n+
    376 template<class T, class A>
    \n+\n+
    378 {
    \n+
    379 return Iterator(finest_);
    \n+
    380 }
    \n+
    381
    \n+
    382 template<class T, class A>
    \n+\n+
    384 {
    \n+
    385 return Iterator(coarsest_);
    \n+
    386 }
    \n+
    387
    \n+
    388 template<class T, class A>
    \n+\n+
    390 {
    \n+
    391 return ConstIterator(finest_);
    \n+
    392 }
    \n+
    393
    \n+
    394 template<class T, class A>
    \n+\n+
    396 {
    \n+
    397 return ConstIterator(coarsest_);
    \n+
    398 }
    \n+
    400 } // namespace Amg
    \n+
    401} // namespace Dune
    \n+
    402
    \n+
    403#endif
    \n+
    Helper classes for the construction of classes without empty constructor.
    \n+
    Hierarchy(const Hierarchy &other)
    Copy constructor (deep copy!).
    Definition: hierarchy.hh:282
    \n+
    void addRedistributedOnCoarsest(Arguments &args)
    Definition: hierarchy.hh:328
    \n+
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: hierarchy.hh:322
    \n+
    ConstIterator coarsest() const
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:395
    \n+
    void addCoarser(Arguments &args)
    Add an element on a coarser level.
    Definition: hierarchy.hh:334
    \n+
    void addFiner(Arguments &args)
    Add an element on a finer level.
    Definition: hierarchy.hh:356
    \n+
    Hierarchy(const std::shared_ptr< MemberType > &first)
    Construct a new hierarchy.
    Definition: hierarchy.hh:270
    \n
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n-
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n-
    OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
    The iterator over the matrices.
    Definition: fastamg.hh:184
    \n-
    void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
    Get the aggregate number of each unknown on the coarsest level.
    Definition: fastamg.hh:704
    \n-
    ParallelInformationHierarchy::Iterator pinfo
    The iterator over the parallel information.
    Definition: fastamg.hh:188
    \n-
    void recalculateHierarchy()
    Recalculate the matrix hierarchy.
    Definition: fastamg.hh:150
    \n-
    void post(Domain &x)
    Clean up.
    Definition: fastamg.hh:695
    \n-
    std::size_t maxlevels()
    Definition: fastamg.hh:481
    \n-
    X Domain
    The domain type.
    Definition: fastamg.hh:77
    \n-
    Hierarchy< Domain, A >::Iterator residual
    The iterator over the residuals.
    Definition: fastamg.hh:204
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: fastamg.hh:123
    \n-
    MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
    The operator hierarchy type.
    Definition: fastamg.hh:72
    \n-
    OperatorHierarchy::RedistributeInfoList::const_iterator redist
    The iterator over the redistribution information.
    Definition: fastamg.hh:192
    \n-
    X Range
    The range type.
    Definition: fastamg.hh:79
    \n-
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: fastamg.hh:70
    \n-
    M Operator
    The matrix operator type.
    Definition: fastamg.hh:63
    \n-
    std::size_t levels()
    Definition: fastamg.hh:476
    \n-
    InverseOperator< X, X > CoarseSolver
    the type of the coarse solver.
    Definition: fastamg.hh:81
    \n-
    bool usesDirectCoarseLevelSolver() const
    Check whether the coarse solver used is a direct solver.
    Definition: fastamg.hh:632
    \n-
    Hierarchy< Domain, A >::Iterator lhs
    The iterator over the left hand side.
    Definition: fastamg.hh:200
    \n-
    Hierarchy< Range, A >::Iterator rhs
    The iterator over the right hand sided.
    Definition: fastamg.hh:208
    \n-
    std::size_t level
    The level index.
    Definition: fastamg.hh:212
    \n-
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: fastamg.hh:488
    \n-
    OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
    The parallal data distribution hierarchy type.
    Definition: fastamg.hh:74
    \n-
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: fastamg.hh:427
    \n-
    FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const Parameters &parms, bool symmetric=true)
    Construct a new amg with a specific coarse solver.
    Definition: fastamg.hh:297
    \n-
    OperatorHierarchy::AggregatesMapList::const_iterator aggregates
    The iterator over the aggregates maps.
    Definition: fastamg.hh:196
    \n+
    Iterator coarsest()
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:383
    \n+
    ConstIterator finest() const
    Get an iterator positioned at the finest level.
    Definition: hierarchy.hh:389
    \n+
    Iterator finest()
    Get an iterator positioned at the finest level.
    Definition: hierarchy.hh:377
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    @ symmetric
    Definition: matrixmarket.hh:303
    \n-
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n-
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n-
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n-
    A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth.
    Definition: fastamg.hh:60
    \n-
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:19
    \n-
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:55
    \n-\n-
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n-
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n-
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n-
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n-
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n-
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n-
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n-\n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n-
    Definition: solvertype.hh:16
    \n+
    A hierarchy of containers (e.g. matrices or vectors)
    Definition: hierarchy.hh:40
    \n+
    T MemberType
    The type of the container we store.
    Definition: hierarchy.hh:45
    \n+
    LevelIterator< Hierarchy< T, A >, T > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n+
    LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n+
    ConstructionTraits< T >::Arguments Arguments
    Definition: hierarchy.hh:78
    \n+
    Hierarchy()
    Construct an empty hierarchy.
    Definition: hierarchy.hh:89
    \n+
    typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator
    The allocator to use for the list elements.
    Definition: hierarchy.hh:76
    \n+
    Iterator over the levels in the hierarchy.
    Definition: hierarchy.hh:120
    \n+
    LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
    Copy constructor.
    Definition: hierarchy.hh:136
    \n+
    void addRedistributed(std::shared_ptr< T1 > t)
    Definition: hierarchy.hh:201
    \n+
    T1 & dereference() const
    Dereference the iterator.
    Definition: hierarchy.hh:166
    \n+
    bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
    Equality check.
    Definition: hierarchy.hh:150
    \n+
    bool isRedistributed() const
    Check whether there was a redistribution at the current level.
    Definition: hierarchy.hh:187
    \n+
    bool equals(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other) const
    Equality check.
    Definition: hierarchy.hh:159
    \n+
    void increment()
    Move to the next coarser level.
    Definition: hierarchy.hh:172
    \n+
    LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
    Copy constructor.
    Definition: hierarchy.hh:142
    \n+
    void deleteRedistributed()
    Definition: hierarchy.hh:206
    \n+
    void decrement()
    Move to the next fine level.
    Definition: hierarchy.hh:178
    \n+
    LevelIterator(std::shared_ptr< Element > element)
    Definition: hierarchy.hh:131
    \n+
    T1 & getRedistributed() const
    Get the redistributed container.
    Definition: hierarchy.hh:196
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,835 +5,444 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-fastamg.hh\n+hierarchy.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_FASTAMG_HH\n- 6#define DUNE_ISTL_FASTAMG_HH\n+ 5#ifndef DUNE_AMGHIERARCHY_HH\n+ 6#define DUNE_AMGHIERARCHY_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21\n- 22#include \"fastamgsmoother.hh\"\n- 23\n- 32namespace Dune\n- 33{\n- 34 namespace Amg\n- 35 {\n- 58 template >\n-59 class FastAMG : public Preconditioner\n- 60 {\n- 61 public:\n-63 typedef M Operator;\n-70 typedef PI ParallelInformation;\n-72 typedef MatrixHierarchy OperatorHierarchy;\n-74 typedef typename OperatorHierarchy::ParallelInformationHierarchy\n-ParallelInformationHierarchy;\n- 75\n-77 typedef X Domain;\n-79 typedef X Range;\n-81 typedef InverseOperator CoarseSolver;\n- 82\n- 90 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n- 91 const Parameters& parms,\n- 92 bool symmetric=true);\n- 93\n- 105 template\n- 106 FastAMG(const Operator& fineOperator, const C& criterion,\n- 107 const Parameters& parms=Parameters(),\n- 108 bool symmetric=true,\n- 109 const ParallelInformation& pinfo=ParallelInformation());\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15\n+ 16namespace Dune\n+ 17{\n+ 18 namespace Amg\n+ 19 {\n+ 38 template >\n+39 class Hierarchy\n+ 40 {\n+ 41 public:\n+45 typedef T MemberType;\n+ 46\n+ 47 template\n+ 48 class LevelIterator;\n+ 49\n+ 50 private:\n+ 54 struct Element\n+ 55 {\n+ 56 friend class LevelIterator, T>;\n+ 57 friend class LevelIterator, const T>;\n+ 58\n+ 60 std::weak_ptr coarser_;\n+ 61\n+ 63 std::shared_ptr finer_;\n+ 64\n+ 66 std::shared_ptr element_;\n+ 67\n+69 std::shared_ptr redistributed_;\n+ 70 };\n+ 71 public:\n+ 72\n+76 using Allocator = typename std::allocator_traits::template\n+rebind_alloc;\n+ 77\n+78 typedef typename ConstructionTraits::Arguments Arguments;\n+ 79\n+84 Hierarchy(const std::shared_ptr & first);\n+ 85\n+89 Hierarchy() : levels_(0)\n+ 90 {}\n+ 91\n+95 Hierarchy(const Hierarchy& other);\n+ 96\n+101 void addCoarser(Arguments& args);\n+ 102\n+103 void addRedistributedOnCoarsest(Arguments& args);\n+ 104\n+109 void addFiner(Arguments& args);\n 110\n- 114 FastAMG(const FastAMG& amg);\n- 115\n- 117 void pre(Domain& x, Range& b);\n- 118\n- 120 void apply(Domain& v, const Range& d);\n- 121\n-123 virtual SolverCategory::Category category() const\n- 124 {\n- 125 return SolverCategory::sequential;\n- 126 }\n- 127\n- 129 void post(Domain& x);\n+ 117 template\n+118 class LevelIterator\n+ 119 : public BidirectionalIteratorFacade,T1,T1&>\n+ 120 {\n+ 121 friend class LevelIterator::type,\n+ 122 typename std::remove_const::type >;\n+ 123 friend class LevelIterator::type,\n+ 124 const typename std::remove_const::type >;\n+ 125\n+ 126 public:\n+128 LevelIterator()\n+ 129 {}\n 130\n- 135 template\n- 136 void getCoarsestAggregateNumbers(std::vector& cont);\n- 137\n- 138 std::size_t levels();\n- 139\n- 140 std::size_t maxlevels();\n- 141\n-150 void recalculateHierarchy()\n- 151 {\n- 152 matrices_->recalculateGalerkin(NegateSet());\n- 153 }\n- 154\n- 159 bool usesDirectCoarseLevelSolver() const;\n- 160\n- 161 private:\n- 168 template\n- 169 void createHierarchies(C& criterion,\n- 170 const std::shared_ptr& matrixptr,\n- 171 const PI& pinfo);\n- 172\n- 179 struct LevelContext\n- 180 {\n-184 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix;\n-188 typename ParallelInformationHierarchy::Iterator pinfo;\n-192 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;\n-196 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;\n-200 typename Hierarchy::Iterator lhs;\n-204 typename Hierarchy::Iterator residual;\n-208 typename Hierarchy::Iterator rhs;\n-212 std::size_t level;\n+131 LevelIterator(std::shared_ptr element)\n+ 132 : element_(element)\n+ 133 {}\n+ 134\n+136 LevelIterator(const LevelIterator::type,\n+ 137 typename std::remove_const::type>& other)\n+ 138 : element_(other.element_)\n+ 139 {}\n+ 140\n+142 LevelIterator(const LevelIterator::\n+type,\n+ 143 const typename std::remove_const::type>& other)\n+ 144 : element_(other.element_)\n+ 145 {}\n+ 146\n+150 bool equals(const LevelIterator::type,\n+ 151 typename std::remove_const::type>& other) const\n+ 152 {\n+ 153 return element_ == other.element_;\n+ 154 }\n+ 155\n+159 bool equals(const LevelIterator::type,\n+ 160 const typename std::remove_const::type>& other) const\n+ 161 {\n+ 162 return element_ == other.element_;\n+ 163 }\n+ 164\n+166 T1& dereference() const\n+ 167 {\n+ 168 return *(element_->element_);\n+ 169 }\n+ 170\n+172 void increment()\n+ 173 {\n+ 174 element_ = element_->coarser_.lock();\n+ 175 }\n+ 176\n+178 void decrement()\n+ 179 {\n+ 180 element_ = element_->finer_;\n+ 181 }\n+ 182\n+187 bool isRedistributed() const\n+ 188 {\n+ 189 return (bool)element_->redistributed_;\n+ 190 }\n+ 191\n+196 T1& getRedistributed() const\n+ 197 {\n+ 198 assert(element_->redistributed_);\n+ 199 return *element_->redistributed_;\n+ 200 }\n+201 void addRedistributed(std::shared_ptr t)\n+ 202 {\n+ 203 element_->redistributed_ = t;\n+ 204 }\n+ 205\n+206 void deleteRedistributed()\n+ 207 {\n+ 208 element_->redistributed_ = nullptr;\n+ 209 }\n+ 210\n+ 211 private:\n+ 212 std::shared_ptr element_;\n 213 };\n 214\n- 216 void mgc(LevelContext& levelContext, Domain& x, const Range& b);\n+216 typedef LevelIterator,T> Iterator;\n 217\n- 224 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);\n- 225\n- 232 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);\n+219 typedef LevelIterator, const T> ConstIterator;\n+ 220\n+225 Iterator finest();\n+ 226\n+231 Iterator coarsest();\n+ 232\n 233\n- 240 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,\n- 241 Domain& fineX);\n- 242\n- 247 bool moveToCoarseLevel(LevelContext& levelContext);\n- 248\n- 253 void initIteratorsWithFineLevel(LevelContext& levelContext);\n- 254\n- 256 std::shared_ptr matrices_;\n- 258 std::shared_ptr solver_;\n- 260 std::shared_ptr> rhs_;\n- 262 std::shared_ptr> lhs_;\n- 264 std::shared_ptr> residual_;\n- 265\n- 267 using ScalarProduct = Dune::ScalarProduct;\n- 269 std::shared_ptr scalarProduct_;\n- 271 std::size_t gamma_;\n- 273 std::size_t preSteps_;\n- 275 std::size_t postSteps_;\n- 276 std::size_t level;\n- 277 bool buildHierarchy_;\n- 278 bool symmetric;\n- 279 bool coarsesolverconverged;\n- 280 typedef SeqSSOR Smoother;\n- 281 typedef std::shared_ptr SmootherPointer;\n- 282 SmootherPointer coarseSmoother_;\n- 284 std::size_t verbosity_;\n- 285 };\n- 286\n- 287 template\n-288 FastAMG::FastAMG(const FastAMG& amg)\n- 289 : matrices_(amg.matrices_), solver_(amg.solver_),\n- 290 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),\n- 291 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),\n- 292 symmetric(amg.symmetric), coarsesolverconverged\n-(amg.coarsesolverconverged),\n- 293 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)\n- 294 {}\n+238 ConstIterator finest() const;\n+ 239\n+244 ConstIterator coarsest() const;\n+ 245\n+250 std::size_t levels() const;\n+ 251\n+ 252 private:\n+ 258 std::shared_ptr originalFinest_;\n+ 260 std::shared_ptr finest_;\n+ 262 std::shared_ptr coarsest_;\n+ 264 Allocator allocator_;\n+ 266 int levels_;\n+ 267 };\n+ 268\n+ 269 template\n+270 Hierarchy::Hierarchy(const std::shared_ptr & first)\n+ 271 : originalFinest_(first)\n+ 272 {\n+ 273 finest_ = std::allocate_shared(allocator_);\n+ 274 finest_->element_ = originalFinest_;\n+ 275 coarsest_ = finest_;\n+ 276 levels_ = 1;\n+ 277 }\n+ 278\n+ 280 //TODO: do we actually want to support this? This might be very\n+expensive?!\n+ 281 template\n+282 Hierarchy::Hierarchy(const Hierarchy& other)\n+ 283 : allocator_(other.allocator_),\n+ 284 levels_(other.levels_)\n+ 285 {\n+ 286 if(!other.finest_)\n+ 287 {\n+ 288 finest_=coarsest_=nullptr;\n+ 289 return;\n+ 290 }\n+ 291 finest_ = std::allocate_shared(allocator_);\n+ 292 std::shared_ptr finer_;\n+ 293 std::shared_ptr current_ = finest_;\n+ 294 std::weak_ptr otherWeak_ = other.finest_;\n 295\n- 296 template\n-297 FastAMG::FastAMG(OperatorHierarchy& matrices, CoarseSolver&\n-coarseSolver,\n- 298 const Parameters& parms, bool symmetric_)\n- 299 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),\n- 300 rhs_(), lhs_(), residual_(), scalarProduct_(),\n- 301 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),\n- 302 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),\n- 303 symmetric(symmetric_), coarsesolverconverged(true),\n- 304 coarseSmoother_(), verbosity_(parms.debugLevel())\n- 305 {\n- 306 if(preSteps_>1||postSteps_>1)\n- 307 {\n- 308 std::cerr<<\"WARNING only one step of smoothing is supported!\"<isBuilt());\n- 312 static_assert(std::is_same::value,\n- 313 \"Currently only sequential runs are supported\");\n+ 296 while(! otherWeak_.expired())\n+ 297 {\n+ 298 // create shared_ptr from weak_ptr, we just checked that this is safe\n+ 299 std::shared_ptr otherCurrent_ = std::shared_ptr\n+(otherWeak_);\n+ 300 // clone current level\n+ 301 //TODO: should we use the allocator?\n+ 302 current_->element_ =\n+ 303 std::make_shared(*(otherCurrent_->element_));\n+ 304 current_->finer_=finer_;\n+ 305 if(otherCurrent_->redistributed_)\n+ 306 current_->redistributed_ =\n+ 307 std::make_shared(*(otherCurrent_->redistributed_));\n+ 308 finer_=current_;\n+ 309 if(not otherCurrent_->coarser_.expired())\n+ 310 {\n+ 311 auto c = std::allocate_shared(allocator_);\n+ 312 current_->coarser_ = c;\n+ 313 current_ = c;\n 314 }\n- 315 template\n- 316 template\n-317 FastAMG::FastAMG(const Operator& matrix,\n- 318 const C& criterion,\n- 319 const Parameters& parms,\n- 320 bool symmetric_,\n- 321 const PI& pinfo)\n- 322 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_\n-(parms.getGamma()),\n- 323 preSteps_(parms.getNoPreSmoothSteps()), postSteps_\n-(parms.getNoPostSmoothSteps()),\n- 324 buildHierarchy_(true),\n- 325 symmetric(symmetric_), coarsesolverconverged(true),\n- 326 coarseSmoother_(), verbosity_(criterion.debugLevel())\n- 327 {\n- 328 if(preSteps_>1||postSteps_>1)\n+ 315 // go to coarser level\n+ 316 otherWeak_ = otherCurrent_->coarser_;\n+ 317 }\n+ 318 coarsest_=current_;\n+ 319 }\n+ 320\n+ 321 template\n+322 std::size_t Hierarchy::levels() const\n+ 323 {\n+ 324 return levels_;\n+ 325 }\n+ 326\n+ 327 template\n+328 void Hierarchy::addRedistributedOnCoarsest(Arguments& args)\n 329 {\n- 330 std::cerr<<\"WARNING only one step of smoothing is supported!\"<::value,\n- 334 \"Currently only sequential runs are supported\");\n- 335 // TODO: reestablish compile time checks.\n- 336 //static_assert(static_cast(PI::category)==static_cast(S::\n-category),\n- 337 // \"Matrix and Solver must match in terms of category!\");\n- 338 auto matrixptr = stackobject_to_shared_ptr(matrix);\n- 339 createHierarchies(criterion, matrixptr, pinfo);\n- 340 }\n- 341\n- 342 template\n- 343 template\n- 344 void FastAMG::createHierarchies(C& criterion,\n- 345 const std::shared_ptr& matrixptr,\n- 346 const PI& pinfo)\n- 347 {\n- 348 Timer watch;\n- 349 matrices_ = std::make_shared(\n- 350 std::const_pointer_cast(matrixptr),\n- 351 stackobject_to_shared_ptr(const_cast(pinfo)));\n- 352\n- 353 matrices_->template build >(criterion);\n+ 330 coarsest_->redistributed_ = ConstructionTraits::construct\n+(args);\n+ 331 }\n+ 332\n+ 333 template\n+334 void Hierarchy::addCoarser(Arguments& args)\n+ 335 {\n+ 336 if(!coarsest_) {\n+ 337 // we have no levels at all...\n+ 338 assert(!finest_);\n+ 339 // allocate into the shared_ptr\n+ 340 originalFinest_ = ConstructionTraits::construct(args);\n+ 341 coarsest_ = std::allocate_shared(allocator_);\n+ 342 coarsest_->element_ = originalFinest_;\n+ 343 finest_ = coarsest_;\n+ 344 }else{\n+ 345 auto old_coarsest = coarsest_;\n+ 346 coarsest_ = std::allocate_shared(allocator_);\n+ 347 coarsest_->finer_ = old_coarsest;\n+ 348 coarsest_->element_ = ConstructionTraits::construct(args);\n+ 349 old_coarsest->coarser_ = coarsest_;\n+ 350 }\n+ 351 ++levels_;\n+ 352 }\n+ 353\n 354\n- 355 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n-().rank()==0)\n- 356 std::cout<<\"Building Hierarchy of \"<maxlevels()<<\" levels took\n-\"<levels()==matrices_->maxlevels()) {\n- 359 // We have the carsest level. Create the coarse Solver\n- 360 typedef typename SmootherTraits::Arguments SmootherArgs;\n- 361 SmootherArgs sargs;\n- 362 sargs.iterations = 1;\n- 363\n- 364 typename ConstructionTraits::Arguments cargs;\n- 365 cargs.setArgs(sargs);\n- 366 if(matrices_->redistributeInformation().back().isSetup()) {\n- 367 // Solve on the redistributed partitioning\n- 368 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat\n-());\n- 369 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed\n-());\n- 370 }else{\n- 371 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());\n- 372 cargs.setComm(*matrices_->parallelInformation().coarsest());\n- 373 }\n- 374\n- 375 coarseSmoother_ = ConstructionTraits::construct(cargs);\n- 376 scalarProduct_ = createScalarProduct(cargs.getComm(),category());\n- 377\n- 378#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK\n- 379#if HAVE_SUITESPARSE_UMFPACK\n- 380#define DIRECTSOLVER UMFPack\n- 381#else\n- 382#define DIRECTSOLVER SuperLU\n- 383#endif\n- 384 // Use superlu if we are purely sequential or with only one processor on\n-the coarsest level.\n- 385 if(std::is_same::value /\n-/ sequential mode\n- 386 || matrices_->parallelInformation().coarsest()->communicator().size()==1 /\n-/parallel mode and only one processor\n- 387 || (matrices_->parallelInformation().coarsest().isRedistributed()\n- 388 && matrices_->parallelInformation().coarsest().getRedistributed\n-().communicator().size()==1\n- 389 && matrices_->parallelInformation().coarsest().getRedistributed\n-().communicator().size()>0)) { // redistribute and 1 proc\n- 390 if(verbosity_>0 && matrices_->parallelInformation().coarsest()-\n->communicator().rank()==0)\n- 391 std::cout<<\"Using superlu\"<parallelInformation().coarsest().isRedistributed())\n- 393 {\n- 394 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n- 395 // We are still participating on this level\n- 396 solver_.reset(new DIRECTSOLVER(matrices_-\n->matrices().coarsest().getRedistributed().getmat(), false, false));\n- 397 else\n- 398 solver_.reset();\n- 399 }else\n- 400 solver_.reset(new DIRECTSOLVER(matrices_-\n->matrices().coarsest()->getmat(), false, false));\n- 401 }else\n- 402#undef DIRECTSOLVER\n- 403#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK\n- 404 {\n- 405 if(matrices_->parallelInformation().coarsest().isRedistributed())\n- 406 {\n- 407 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n- 408 // We are still participating on this level\n- 409 solver_.reset(new BiCGSTABSolver(const_cast(matrices_->matrices\n-().coarsest().getRedistributed()),\n- 410 *scalarProduct_,\n- 411 *coarseSmoother_, 1E-2, 1000, 0));\n- 412 else\n- 413 solver_.reset();\n- 414 }else\n- 415 solver_.reset(new BiCGSTABSolver(const_cast(*matrices_->matrices\n-().coarsest()),\n- 416 *scalarProduct_,\n- 417 *coarseSmoother_, 1E-2, 1000, 0));\n- 418 }\n- 419 }\n- 420\n- 421 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n-().rank()==0)\n- 422 std::cout<<\"Building Hierarchy of \"<maxlevels()<<\" levels took\n-\"<\n-427 void FastAMG::pre(Domain& x, Range& b)\n- 428 {\n- 429 Timer watch, watch1;\n- 430 // Detect Matrix rows where all offdiagonal entries are\n- 431 // zero and set x such that A_dd*x_d=b_d\n- 432 // Thus users can be more careless when setting up their linear\n- 433 // systems.\n- 434 typedef typename M::matrix_type Matrix;\n- 435 typedef typename Matrix::ConstRowIterator RowIter;\n- 436 typedef typename Matrix::ConstColIterator ColIter;\n- 437 typedef typename Matrix::block_type Block;\n- 438 Block zero;\n- 439 zero=typename Matrix::field_type();\n- 440\n- 441 const Matrix& mat=matrices_->matrices().finest()->getmat();\n- 442 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {\n- 443 bool isDirichlet = true;\n- 444 bool hasDiagonal = false;\n- 445 ColIter diag;\n- 446 for(ColIter col=row->begin(); col!=row->end(); ++col) {\n- 447 if(row.index()==col.index()) {\n- 448 diag = col;\n- 449 hasDiagonal = (*col != zero);\n- 450 }else{\n- 451 if(*col!=zero)\n- 452 isDirichlet = false;\n- 453 }\n- 454 }\n- 455 if(isDirichlet && hasDiagonal)\n- 456 diag->solve(x[row.index()], b[row.index()]);\n- 457 }\n- 458 if (verbosity_>0)\n- 459 std::cout<<\" Preprocessing Dirichlet took \"<parallelInformation().coarsest()->copyOwnerToAll(x,x);\n- 463 rhs_ = std::make_shared>(std::make_shared(b));\n- 464 lhs_ = std::make_shared>(std::make_shared(x));\n- 465 residual_ = std::make_shared>(std::make_shared\n-(x));\n- 466 matrices_->coarsenVector(*rhs_);\n- 467 matrices_->coarsenVector(*lhs_);\n- 468 matrices_->coarsenVector(*residual_);\n- 469\n- 470 // The preconditioner might change x and b. So we have to\n- 471 // copy the changes to the original vectors.\n- 472 x = *lhs_->finest();\n- 473 b = *rhs_->finest();\n- 474 }\n- 475 template\n-476 std::size_t FastAMG::levels()\n- 477 {\n- 478 return matrices_->levels();\n- 479 }\n- 480 template\n-481 std::size_t FastAMG::maxlevels()\n- 482 {\n- 483 return matrices_->maxlevels();\n- 484 }\n- 485\n- 487 template\n-488 void FastAMG::apply(Domain& v, const Range& d)\n- 489 {\n- 490 LevelContext levelContext;\n- 491 // Init all iterators for the current level\n- 492 initIteratorsWithFineLevel(levelContext);\n- 493\n- 494 assert(v.two_norm()==0);\n- 495\n- 496 level=0;\n- 497 if(matrices_->maxlevels()==1){\n- 498 // The coarse solver might modify the d!\n- 499 Range b(d);\n- 500 mgc(levelContext, v, b);\n- 501 }else\n- 502 mgc(levelContext, v, d);\n- 503 if(postSteps_==0||matrices_->maxlevels()==1)\n- 504 levelContext.pinfo->copyOwnerToAll(v, v);\n- 505 }\n- 506\n- 507 template\n- 508 void FastAMG::initIteratorsWithFineLevel(LevelContext&\n-levelContext)\n- 509 {\n- 510 levelContext.matrix = matrices_->matrices().finest();\n- 511 levelContext.pinfo = matrices_->parallelInformation().finest();\n- 512 levelContext.redist =\n- 513 matrices_->redistributeInformation().begin();\n- 514 levelContext.aggregates = matrices_->aggregatesMaps().begin();\n- 515 levelContext.lhs = lhs_->finest();\n- 516 levelContext.residual = residual_->finest();\n- 517 levelContext.rhs = rhs_->finest();\n- 518 levelContext.level=0;\n- 519 }\n- 520\n- 521 template\n- 522 bool FastAMG\n- 523 ::moveToCoarseLevel(LevelContext& levelContext)\n- 524 {\n- 525 bool processNextLevel=true;\n- 526\n- 527 if(levelContext.redist->isSetup()) {\n- 528 throw \"bla\";\n- 529 levelContext.redist->redistribute(static_cast\n-(*levelContext.residual),\n- 530 levelContext.residual.getRedistributed());\n- 531 processNextLevel = levelContext.residual.getRedistributed().size()>0;\n- 532 if(processNextLevel) {\n- 533 //restrict defect to coarse level right hand side.\n- 534 ++levelContext.pinfo;\n- 535 Transfer\n- 536::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n- 537 static_cast(levelContext.residual.getRedistributed()),\n- 538 *levelContext.pinfo);\n- 539 }\n- 540 }else{\n- 541 //restrict defect to coarse level right hand side.\n- 542 ++levelContext.rhs;\n- 543 ++levelContext.pinfo;\n- 544 Transfer\n- 545::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n- 546 static_cast(*levelContext.residual), *levelContext.pinfo);\n- 547 }\n- 548\n- 549 if(processNextLevel) {\n- 550 // prepare coarse system\n- 551 ++levelContext.residual;\n- 552 ++levelContext.lhs;\n- 553 ++levelContext.matrix;\n- 554 ++levelContext.level;\n- 555 ++levelContext.redist;\n- 556\n- 557 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n->levels()maxlevels()) {\n- 558 // next level is not the globally coarsest one\n- 559 ++levelContext.aggregates;\n- 560 }\n- 561 // prepare the lhs on the next level\n- 562 *levelContext.lhs=0;\n- 563 *levelContext.residual=0;\n- 564 }\n- 565 return processNextLevel;\n- 566 }\n- 567\n- 568 template\n- 569 void FastAMG\n- 570 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel,\n-Domain& x)\n- 571 {\n- 572 if(processNextLevel) {\n- 573 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n->levels()maxlevels()) {\n- 574 // previous level is not the globally coarsest one\n- 575 --levelContext.aggregates;\n- 576 }\n- 577 --levelContext.redist;\n- 578 --levelContext.level;\n- 579 //prolongate and add the correction (update is in coarse left hand side)\n- 580 --levelContext.matrix;\n- 581 --levelContext.residual;\n- 582\n- 583 }\n- 584\n- 585 typename Hierarchy::Iterator coarseLhs = levelContext.lhs--;\n- 586 if(levelContext.redist->isSetup()) {\n- 587\n- 588 // Need to redistribute during prolongate\n- 589 Transfer\n- 590::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,\n- 591 levelContext.lhs.getRedistributed(),\n- 592 matrices_->getProlongationDampingFactor(),\n- 593 *levelContext.pinfo, *levelContext.redist);\n- 594 }else{\n- 595 Transfer\n- 596::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,\n- 597 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);\n- 598\n- 599 // printvector(std::cout, *lhs, \"prolongated coarse grid correction\",\n-\"lhs\", 10, 10, 10);\n- 600 }\n- 601\n- 602\n- 603 if(processNextLevel) {\n- 604 --levelContext.rhs;\n- 605 }\n- 606\n- 607 }\n- 608\n- 609\n- 610 template\n- 611 void FastAMG\n- 612 ::presmooth(LevelContext& levelContext, Domain& x, const Range& b)\n- 613 {\n- 614 constexpr auto bl = blockLevel();\n- 615 GaussSeidelPresmoothDefect::apply(levelContext.matrix->getmat(),\n- 616 x,\n- 617 *levelContext.residual,\n- 618 b);\n- 619 }\n- 620\n- 621 template\n- 622 void FastAMG\n- 623 ::postsmooth(LevelContext& levelContext, Domain& x, const Range& b)\n- 624 {\n- 625 constexpr auto bl = blockLevel();\n- 626 GaussSeidelPostsmoothDefect\n- 627::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);\n- 628 }\n- 629\n- 630\n- 631 template\n-632 bool FastAMG::usesDirectCoarseLevelSolver() const\n- 633 {\n- 634 return IsDirectSolver<_CoarseSolver>::value;\n- 635 }\n- 636\n- 637 template\n- 638 void FastAMG::mgc(LevelContext& levelContext, Domain& v, const\n-Range& b){\n- 639\n- 640 if(levelContext.matrix == matrices_->matrices().coarsest() && levels\n-()==maxlevels()) {\n- 641 // Solve directly\n- 642 InverseOperatorResult res;\n- 643 res.converged=true; // If we do not compute this flag will not get updated\n- 644 if(levelContext.redist->isSetup()) {\n- 645 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());\n- 646 if(levelContext.rhs.getRedistributed().size()>0) {\n- 647 // We are still participating in the computation\n- 648 levelContext.pinfo.getRedistributed().copyOwnerToAll\n-(levelContext.rhs.getRedistributed(),\n- 649 levelContext.rhs.getRedistributed());\n- 650 solver_->apply(levelContext.lhs.getRedistributed(),\n-levelContext.rhs.getRedistributed(), res);\n- 651 }\n- 652 levelContext.redist->redistributeBackward(v,\n-levelContext.lhs.getRedistributed());\n- 653 levelContext.pinfo->copyOwnerToAll(v, v);\n- 654 }else{\n- 655 levelContext.pinfo->copyOwnerToAll(b, b);\n- 656 solver_->apply(v, const_cast(b), res);\n- 657 }\n- 658\n- 659 // printvector(std::cout, *lhs, \"coarse level update\", \"u\", 10, 10, 10);\n- 660 // printvector(std::cout, *rhs, \"coarse level rhs\", \"rhs\", 10, 10, 10);\n- 661 if (!res.converged)\n- 662 coarsesolverconverged = false;\n- 663 }else{\n- 664 // presmoothing\n- 665 presmooth(levelContext, v, b);\n- 666 // printvector(std::cout, *lhs, \"update\", \"u\", 10, 10, 10);\n- 667 // printvector(std::cout, *residual, \"post presmooth residual\", \"r\", 10);\n- 668#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n- 669 bool processNextLevel = moveToCoarseLevel(levelContext);\n- 670\n- 671 if(processNextLevel) {\n- 672 // next level\n- 673 for(std::size_t i=0; imatrices().finest()) {\n- 683 coarsesolverconverged = matrices_->parallelInformation().finest()-\n->communicator().prod(coarsesolverconverged);\n- 684 if(!coarsesolverconverged)\n- 685 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n- 686 }\n- 687\n- 688 postsmooth(levelContext, v, b);\n- 689 }\n- 690 }\n- 691\n- 692\n- 694 template\n-695 void FastAMG::post([[maybe_unused]] Domain& x)\n- 696 {\n- 697 lhs_=nullptr;\n- 698 rhs_=nullptr;\n- 699 residual_=nullptr;\n- 700 }\n- 701\n- 702 template\n- 703 template\n-704 void FastAMG::getCoarsestAggregateNumbers(std::vector& cont)\n- 705 {\n- 706 matrices_->getCoarsestAggregatesOnFinest(cont);\n- 707 }\n- 708\n- 709 } // end namespace Amg\n- 710} // end namespace Dune\n- 711\n- 712#endif\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-preconditioners.hh\n-Define general preconditioner interface.\n-fastamgsmoother.hh\n-transfer.hh\n-Prolongation and restriction for amg.\n-smoother.hh\n-Classes for the generic construction and application of the smoothers.\n-matrixhierarchy.hh\n-Provides a classes representing the hierarchies in AMG.\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n-umfpack.hh\n-Classes for using UMFPack with ISTL matrices.\n-superlu.hh\n-Classes for using SuperLU with ISTL matrices.\n-io.hh\n-Some generic functions for pretty printing vectors and matrices.\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::Amg::presmooth\n-void presmooth(LevelContext &levelContext, size_t steps)\n-Apply pre smoothing on the current level.\n-Definition: smoother.hh:406\n+ 355 template\n+356 void Hierarchy::addFiner(Arguments& args)\n+ 357 {\n+ 358 //TODO: wouldn't it be better to do this in the constructor?'\n+ 359 if(!finest_) {\n+ 360 // we have no levels at all...\n+ 361 assert(!coarsest_);\n+ 362 // allocate into the shared_ptr\n+ 363 originalFinest_ = ConstructionTraits::construct(args);\n+ 364 finest_ = std::allocate_shared(allocator_);\n+ 365 finest_->element = originalFinest_;\n+ 366 coarsest_ = finest_;\n+ 367 }else{\n+ 368 finest_->finer_ = std::allocate_shared(allocator_);\n+ 369 finest_->finer_->coarser_ = finest_;\n+ 370 finest_ = finest_->finer_;\n+ 371 finest_->element = ConstructionTraits::construct(args);\n+ 372 }\n+ 373 ++levels_;\n+ 374 }\n+ 375\n+ 376 template\n+377 typename Hierarchy::Iterator Hierarchy::finest()\n+ 378 {\n+ 379 return Iterator(finest_);\n+ 380 }\n+ 381\n+ 382 template\n+383 typename Hierarchy::Iterator Hierarchy::coarsest()\n+ 384 {\n+ 385 return Iterator(coarsest_);\n+ 386 }\n+ 387\n+ 388 template\n+389 typename Hierarchy::ConstIterator Hierarchy::finest() const\n+ 390 {\n+ 391 return ConstIterator(finest_);\n+ 392 }\n+ 393\n+ 394 template\n+395 typename Hierarchy::ConstIterator Hierarchy::coarsest() const\n+ 396 {\n+ 397 return ConstIterator(coarsest_);\n+ 398 }\n+ 400 } // namespace Amg\n+ 401} // namespace Dune\n+ 402\n+ 403#endif\n+construction.hh\n+Helper classes for the construction of classes without empty constructor.\n+Dune::Amg::Hierarchy::Hierarchy\n+Hierarchy(const Hierarchy &other)\n+Copy constructor (deep copy!).\n+Definition: hierarchy.hh:282\n+Dune::Amg::Hierarchy::addRedistributedOnCoarsest\n+void addRedistributedOnCoarsest(Arguments &args)\n+Definition: hierarchy.hh:328\n+Dune::Amg::Hierarchy::levels\n+std::size_t levels() const\n+Get the number of levels in the hierarchy.\n+Definition: hierarchy.hh:322\n+Dune::Amg::Hierarchy::coarsest\n+ConstIterator coarsest() const\n+Get an iterator positioned at the coarsest level.\n+Definition: hierarchy.hh:395\n+Dune::Amg::Hierarchy::addCoarser\n+void addCoarser(Arguments &args)\n+Add an element on a coarser level.\n+Definition: hierarchy.hh:334\n+Dune::Amg::Hierarchy::addFiner\n+void addFiner(Arguments &args)\n+Add an element on a finer level.\n+Definition: hierarchy.hh:356\n+Dune::Amg::Hierarchy::Hierarchy\n+Hierarchy(const std::shared_ptr< MemberType > &first)\n+Construct a new hierarchy.\n+Definition: hierarchy.hh:270\n Dune::Amg::ConstructionTraits::Arguments\n const void * Arguments\n A type holding all the arguments needed to call the constructor.\n Definition: construction.hh:44\n Dune::Amg::ConstructionTraits::construct\n static std::shared_ptr< T > construct(Arguments &args)\n Construct an object with the specified arguments.\n Definition: construction.hh:52\n-Dune::Amg::postsmooth\n-void postsmooth(LevelContext &levelContext, size_t steps)\n-Apply post smoothing on the current level.\n-Definition: smoother.hh:428\n-Dune::Amg::FastAMG::LevelContext::matrix\n-OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix\n-The iterator over the matrices.\n-Definition: fastamg.hh:184\n-Dune::Amg::FastAMG::getCoarsestAggregateNumbers\n-void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)\n-Get the aggregate number of each unknown on the coarsest level.\n-Definition: fastamg.hh:704\n-Dune::Amg::FastAMG::LevelContext::pinfo\n-ParallelInformationHierarchy::Iterator pinfo\n-The iterator over the parallel information.\n-Definition: fastamg.hh:188\n-Dune::Amg::FastAMG::recalculateHierarchy\n-void recalculateHierarchy()\n-Recalculate the matrix hierarchy.\n-Definition: fastamg.hh:150\n-Dune::Amg::FastAMG::post\n-void post(Domain &x)\n-Clean up.\n-Definition: fastamg.hh:695\n-Dune::Amg::FastAMG::maxlevels\n-std::size_t maxlevels()\n-Definition: fastamg.hh:481\n-Dune::Amg::FastAMG::Domain\n-X Domain\n-The domain type.\n-Definition: fastamg.hh:77\n-Dune::Amg::FastAMG::LevelContext::residual\n-Hierarchy< Domain, A >::Iterator residual\n-The iterator over the residuals.\n-Definition: fastamg.hh:204\n-Dune::Amg::FastAMG::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: fastamg.hh:123\n-Dune::Amg::FastAMG::OperatorHierarchy\n-MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy\n-The operator hierarchy type.\n-Definition: fastamg.hh:72\n-Dune::Amg::FastAMG::LevelContext::redist\n-OperatorHierarchy::RedistributeInfoList::const_iterator redist\n-The iterator over the redistribution information.\n-Definition: fastamg.hh:192\n-Dune::Amg::FastAMG::Range\n-X Range\n-The range type.\n-Definition: fastamg.hh:79\n-Dune::Amg::FastAMG::ParallelInformation\n-PI ParallelInformation\n-The type of the parallel information. Either OwnerOverlapCommunication or\n-another type describing the...\n-Definition: fastamg.hh:70\n-Dune::Amg::FastAMG::Operator\n-M Operator\n-The matrix operator type.\n-Definition: fastamg.hh:63\n-Dune::Amg::FastAMG::levels\n-std::size_t levels()\n-Definition: fastamg.hh:476\n-Dune::Amg::FastAMG::CoarseSolver\n-InverseOperator< X, X > CoarseSolver\n-the type of the coarse solver.\n-Definition: fastamg.hh:81\n-Dune::Amg::FastAMG::usesDirectCoarseLevelSolver\n-bool usesDirectCoarseLevelSolver() const\n-Check whether the coarse solver used is a direct solver.\n-Definition: fastamg.hh:632\n-Dune::Amg::FastAMG::LevelContext::lhs\n-Hierarchy< Domain, A >::Iterator lhs\n-The iterator over the left hand side.\n-Definition: fastamg.hh:200\n-Dune::Amg::FastAMG::LevelContext::rhs\n-Hierarchy< Range, A >::Iterator rhs\n-The iterator over the right hand sided.\n-Definition: fastamg.hh:208\n-Dune::Amg::FastAMG::LevelContext::level\n-std::size_t level\n-The level index.\n-Definition: fastamg.hh:212\n-Dune::Amg::FastAMG::apply\n-void apply(Domain &v, const Range &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: fastamg.hh:488\n-Dune::Amg::FastAMG::ParallelInformationHierarchy\n-OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy\n-The parallal data distribution hierarchy type.\n-Definition: fastamg.hh:74\n-Dune::Amg::FastAMG::pre\n-void pre(Domain &x, Range &b)\n-Prepare the preconditioner.\n-Definition: fastamg.hh:427\n-Dune::Amg::FastAMG::FastAMG\n-FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const\n-Parameters &parms, bool symmetric=true)\n-Construct a new amg with a specific coarse solver.\n-Definition: fastamg.hh:297\n-Dune::Amg::FastAMG::LevelContext::aggregates\n-OperatorHierarchy::AggregatesMapList::const_iterator aggregates\n-The iterator over the aggregates maps.\n-Definition: fastamg.hh:196\n+Dune::Amg::Hierarchy::coarsest\n+Iterator coarsest()\n+Get an iterator positioned at the coarsest level.\n+Definition: hierarchy.hh:383\n+Dune::Amg::Hierarchy::finest\n+ConstIterator finest() const\n+Get an iterator positioned at the finest level.\n+Definition: hierarchy.hh:389\n+Dune::Amg::Hierarchy::finest\n+Iterator finest()\n+Get an iterator positioned at the finest level.\n+Definition: hierarchy.hh:377\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::MatrixMarketImpl::symmetric\n-@ symmetric\n-Definition: matrixmarket.hh:303\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator\n-ConstIterator class for sequential access.\n-Definition: matrix.hh:404\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::field_type\n-typename Imp::BlockTraits< T >::field_type field_type\n-Export the type representing the underlying field.\n-Definition: matrix.hh:565\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n-Dune::Matrix::block_type\n-T block_type\n-Export the type representing the components.\n-Definition: matrix.hh:568\n-Dune::Amg::FastAMG\n-A fast (sequential) algebraic multigrid based on agglomeration that saves\n-memory bandwidth.\n-Definition: fastamg.hh:60\n-Dune::Amg::GaussSeidelPresmoothDefect::apply\n-static void apply(const M &A, X &x, Y &d, const Y &b)\n-Definition: fastamgsmoother.hh:19\n-Dune::Amg::GaussSeidelPostsmoothDefect::apply\n-static void apply(const M &A, X &x, Y &d, const Y &b)\n-Definition: fastamgsmoother.hh:55\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n-LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n-> Iterator\n+Dune::Amg::Hierarchy\n+A hierarchy of containers (e.g. matrices or vectors)\n+Definition: hierarchy.hh:40\n+Dune::Amg::Hierarchy::MemberType\n+T MemberType\n+The type of the container we store.\n+Definition: hierarchy.hh:45\n+Dune::Amg::Hierarchy::Iterator\n+LevelIterator< Hierarchy< T, A >, T > Iterator\n Type of the mutable iterator.\n Definition: hierarchy.hh:216\n-Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n-LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n-MatrixOperator > ConstIterator\n+Dune::Amg::Hierarchy::ConstIterator\n+LevelIterator< const Hierarchy< T, A >, const T > ConstIterator\n Type of the const iterator.\n Definition: hierarchy.hh:219\n-Dune::Amg::MatrixHierarchy\n-The hierarchies build by the coarsening process.\n-Definition: matrixhierarchy.hh:61\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n-Dune::Amg::SmootherTraits\n-Traits class for getting the attribute class of a smoother.\n-Definition: smoother.hh:66\n-Dune::Amg::Transfer::restrictVector\n-static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, const Vector &fine, T &comm)\n-Dune::Amg::Transfer::prolongateVector\n-static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n-&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::SeqSSOR\n-Sequential SSOR preconditioner.\n-Definition: preconditioners.hh:141\n-Dune::ScalarProduct\n-Base class for scalar product and norm computation.\n-Definition: scalarproducts.hh:52\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperatorResult::converged\n-bool converged\n-True if convergence criterion has been met.\n-Definition: solver.hh:73\n-Dune::InverseOperator<_X,_X_>\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n-Dune::IsDirectSolver\n-Definition: solvertype.hh:16\n+Dune::Amg::Hierarchy::Arguments\n+ConstructionTraits< T >::Arguments Arguments\n+Definition: hierarchy.hh:78\n+Dune::Amg::Hierarchy::Hierarchy\n+Hierarchy()\n+Construct an empty hierarchy.\n+Definition: hierarchy.hh:89\n+Dune::Amg::Hierarchy::Allocator\n+typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator\n+The allocator to use for the list elements.\n+Definition: hierarchy.hh:76\n+Dune::Amg::Hierarchy::LevelIterator\n+Iterator over the levels in the hierarchy.\n+Definition: hierarchy.hh:120\n+Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n+LevelIterator(const LevelIterator< typename std::remove_const< C >::type,\n+typename std::remove_const< T1 >::type > &other)\n+Copy constructor.\n+Definition: hierarchy.hh:136\n+Dune::Amg::Hierarchy::LevelIterator::addRedistributed\n+void addRedistributed(std::shared_ptr< T1 > t)\n+Definition: hierarchy.hh:201\n+Dune::Amg::Hierarchy::LevelIterator::dereference\n+T1 & dereference() const\n+Dereference the iterator.\n+Definition: hierarchy.hh:166\n+Dune::Amg::Hierarchy::LevelIterator::equals\n+bool equals(const LevelIterator< typename std::remove_const< C >::type,\n+typename std::remove_const< T1 >::type > &other) const\n+Equality check.\n+Definition: hierarchy.hh:150\n+Dune::Amg::Hierarchy::LevelIterator::isRedistributed\n+bool isRedistributed() const\n+Check whether there was a redistribution at the current level.\n+Definition: hierarchy.hh:187\n+Dune::Amg::Hierarchy::LevelIterator::equals\n+bool equals(const LevelIterator< const typename std::remove_const< C >::type,\n+const typename std::remove_const< T1 >::type > &other) const\n+Equality check.\n+Definition: hierarchy.hh:159\n+Dune::Amg::Hierarchy::LevelIterator::increment\n+void increment()\n+Move to the next coarser level.\n+Definition: hierarchy.hh:172\n+Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n+LevelIterator(const LevelIterator< const typename std::remove_const< C >::type,\n+const typename std::remove_const< T1 >::type > &other)\n+Copy constructor.\n+Definition: hierarchy.hh:142\n+Dune::Amg::Hierarchy::LevelIterator::deleteRedistributed\n+void deleteRedistributed()\n+Definition: hierarchy.hh:206\n+Dune::Amg::Hierarchy::LevelIterator::decrement\n+void decrement()\n+Move to the next fine level.\n+Definition: hierarchy.hh:178\n+Dune::Amg::Hierarchy::LevelIterator::LevelIterator\n+LevelIterator(std::shared_ptr< Element > element)\n+Definition: hierarchy.hh:131\n+Dune::Amg::Hierarchy::LevelIterator::getRedistributed\n+T1 & getRedistributed() const\n+Get the redistributed container.\n+Definition: hierarchy.hh:196\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00143.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00143.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: graphcreator.hh File Reference\n+dune-istl: dependency.hh File Reference\n \n \n \n \n \n \n \n@@ -64,41 +64,63 @@\n \n \n \n
    \n \n-
    graphcreator.hh File Reference
    \n+Namespaces |\n+Functions
    \n+ \n \n
    \n-
    #include <tuple>
    \n-#include "graph.hh"
    \n-#include "dependency.hh"
    \n-#include "pinfo.hh"
    \n-#include <dune/istl/operators.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n+\n+

    Provides classes for initializing the link attributes of a matrix graph. \n+More...

    \n+
    #include <bitset>
    \n+#include <ostream>
    \n+#include "graph.hh"
    \n+#include "properties.hh"
    \n+#include <dune/common/propertymap.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n \n-\n+\n+\n+\n \n

    \n Classes

    struct  Dune::Amg::PropertiesGraphCreator< M, PI >
    class  Dune::Amg::EdgeProperties
     Class representing the properties of an ede in the matrix graph. More...
     
    class  Dune::Amg::VertexProperties
     Class representing a node in the matrix graph. More...
     
    struct  Dune::Amg::PropertiesGraphCreator< M, SequentialInformation >
    class  Dune::Amg::PropertyGraphVertexPropertyMap< G, i >
     
    struct  Dune::PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >
     
    \n \n \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<typename G , typename EP , typename VM , typename EM >
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type Dune::get (const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
     
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const EdgeProperties &props)
     
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const VertexProperties &props)
     
    \n-
    \n+

    Detailed Description

    \n+

    Provides classes for initializing the link attributes of a matrix graph.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,29 +5,70 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces\n-graphcreator.hh File Reference\n-#include \n+Classes | Namespaces | Functions\n+dependency.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides classes for initializing the link attributes of a matrix graph.\n+More...\n+#include \n+#include \n #include \"graph.hh\"\n-#include \"dependency.hh\"\n-#include \"pinfo.hh\"\n-#include \n-#include \n+#include \"properties.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::PropertiesGraphCreator<_M,_PI_>\n+ class \u00a0Dune::Amg::EdgeProperties\n+\u00a0 Class representing the properties of an ede in the matrix graph.\n+ More...\n \u00a0\n-struct \u00a0Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>\n+ class \u00a0Dune::Amg::VertexProperties\n+\u00a0 Class representing a node in the matrix graph. More...\n+\u00a0\n+ class \u00a0Dune::Amg::PropertyGraphVertexPropertyMap<_G,_i_>\n+\u00a0\n+struct \u00a0Dune::PropertyMapTypeSelector<_Amg::VertexVisitedTag,_Amg::\n+ PropertiesGraph<_G,_Amg::VertexProperties,_EP,_VM,_EM_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n+ Functions\n+template\n+ PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg:: Dune::get (const\n+ PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type\u00a0Amg::\n+ VertexVisitedTag\n+ &tag, Amg::\n+ PropertiesGraph<\n+ G, Amg::\n+ VertexProperties,\n+ EP, VM, EM >\n+ &graph)\n+\u00a0\n+ std::ostream &\u00a0Dune::Amg::\n+ operator<< (std::\n+ ostream &os,\n+ const\n+ EdgeProperties\n+ &props)\n+\u00a0\n+ std::ostream &\u00a0Dune::Amg::\n+ operator<< (std::\n+ ostream &os,\n+ const\n+ VertexProperties\n+ &props)\n+\u00a0\n+***** Detailed Description *****\n+Provides classes for initializing the link attributes of a matrix graph.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00143_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00143_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: graphcreator.hh Source File\n+dune-istl: dependency.hh Source File\n \n \n \n \n \n \n \n@@ -62,140 +62,408 @@\n \n
    \n \n
    \n \n
    \n-
    graphcreator.hh
    \n+
    dependency.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_GRAPHCREATOR_HH
    \n-
    6#define DUNE_AMG_GRAPHCREATOR_HH
    \n+
    5#ifndef DUNE_AMG_DEPENDENCY_HH
    \n+
    6#define DUNE_AMG_DEPENDENCY_HH
    \n
    7
    \n-
    8#include <tuple>
    \n-
    9
    \n-
    10#include "graph.hh"
    \n-
    11#include "dependency.hh"
    \n-
    12#include "pinfo.hh"
    \n-\n-\n+
    8
    \n+
    9#include <bitset>
    \n+
    10#include <ostream>
    \n+
    11
    \n+
    12#include "graph.hh"
    \n+
    13#include "properties.hh"
    \n+
    14#include <dune/common/propertymap.hh>
    \n
    15
    \n-
    16namespace Dune
    \n-
    17{
    \n-
    18 namespace Amg
    \n-
    19 {
    \n-
    20 template<class M, class PI>
    \n-\n-
    22 {
    \n-
    23 typedef typename M::matrix_type Matrix;
    \n-\n-\n-
    26 std::vector<bool> > SubGraph;
    \n-\n-\n-\n-
    30 IdentityMap,
    \n-\n-\n-
    33
    \n-
    34 typedef std::tuple<MatrixGraph*,PropertiesGraph*,SubGraph*> GraphTuple;
    \n-
    35
    \n-
    36 template<class OF, class T>
    \n-
    37 static GraphTuple create(const M& matrix, T& excluded,
    \n-
    38 PI& pinfo, const OF& of)
    \n-
    39 {
    \n-
    40 MatrixGraph* mg = new MatrixGraph(matrix.getmat());
    \n-
    41 typedef typename PI::ParallelIndexSet ParallelIndexSet;
    \n-
    42 typedef typename ParallelIndexSet::const_iterator IndexIterator;
    \n-
    43 IndexIterator iend = pinfo.indexSet().end();
    \n+
    16
    \n+
    17namespace Dune
    \n+
    18{
    \n+
    19 namespace Amg
    \n+
    20 {
    \n+\n+
    39 {
    \n+
    40 friend std::ostream& operator<<(std::ostream& os, const EdgeProperties& props);
    \n+
    41 public:
    \n+\n
    44
    \n-
    45 for(IndexIterator index = pinfo.indexSet().begin(); index != iend; ++index)
    \n-
    46 excluded[index->local()] = of.contains(index->local().attribute());
    \n-
    47
    \n-
    48 SubGraph* sg= new SubGraph(*mg, excluded);
    \n-
    49 PropertiesGraph* pg = new PropertiesGraph(*sg, IdentityMap(), sg->getEdgeIndexMap());
    \n-
    50 return GraphTuple(mg,pg,sg);
    \n-
    51 }
    \n-
    52
    \n-
    53 static void free(GraphTuple& graphs)
    \n-
    54 {
    \n-
    55 delete std::get<2>(graphs);
    \n-
    56 delete std::get<1>(graphs);
    \n-
    57 }
    \n-
    58 };
    \n-
    59
    \n-
    60 template<class M>
    \n-\n-
    62 {
    \n-
    63 typedef typename M::matrix_type Matrix;
    \n+
    45 private:
    \n+
    46
    \n+
    47 std::bitset<SIZE> flags_;
    \n+
    48 public:
    \n+\n+
    51
    \n+
    53 std::bitset<SIZE>::reference operator[](std::size_t v);
    \n+
    54
    \n+
    56 bool operator[](std::size_t v) const;
    \n+
    57
    \n+
    63 bool depends() const;
    \n
    64
    \n-\n-
    66
    \n-\n-\n-\n-
    70 IdentityMap,
    \n-
    71 IdentityMap> PropertiesGraph;
    \n-
    72
    \n-
    73 typedef std::tuple<MatrixGraph*,PropertiesGraph*> GraphTuple;
    \n-
    74
    \n-
    75 template<class OF, class T>
    \n-
    76 static GraphTuple create([[maybe_unused]] const M& matrix,
    \n-
    77 [[maybe_unused]] T& excluded,
    \n-
    78 [[maybe_unused]] const SequentialInformation& pinfo,
    \n-
    79 const OF&)
    \n-
    80 {
    \n-
    81 MatrixGraph* mg = new MatrixGraph(matrix.getmat());
    \n-
    82 PropertiesGraph* pg = new PropertiesGraph(*mg, IdentityMap(), IdentityMap());
    \n-
    83 return GraphTuple(mg,pg);
    \n-
    84 }
    \n-
    85
    \n-
    86 static void free(GraphTuple& graphs)
    \n-
    87 {
    \n-
    88 delete std::get<1>(graphs);
    \n-
    89 }
    \n-
    90
    \n-
    91 };
    \n-
    92
    \n-
    93 } //namespace Amg
    \n-
    94} // namespace Dune
    \n-
    95#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Provides classes for building the matrix graph.
    \n-\n-
    Provides classes for initializing the link attributes of a matrix graph.
    \n-
    Implementation of the BCRSMatrix class.
    \n+
    69 void setDepends();
    \n+
    70
    \n+
    74 void resetDepends();
    \n+
    75
    \n+
    80 bool influences() const;
    \n+
    81
    \n+
    85 void setInfluences();
    \n+
    86
    \n+
    90 void resetInfluences();
    \n+
    91
    \n+
    96 bool isOneWay() const;
    \n+
    97
    \n+
    102 bool isTwoWay() const;
    \n+
    103
    \n+
    108 bool isStrong() const;
    \n+
    109
    \n+
    113 void reset();
    \n+
    114
    \n+
    118 void printFlags() const;
    \n+
    119 };
    \n+
    120
    \n+\n+
    127 friend std::ostream& operator<<(std::ostream& os, const VertexProperties& props);
    \n+
    128 public:
    \n+\n+
    130 private:
    \n+
    131
    \n+
    133 std::bitset<SIZE> flags_;
    \n+
    134
    \n+
    135 public:
    \n+\n+
    138
    \n+
    140 std::bitset<SIZE>::reference operator[](std::size_t v);
    \n+
    141
    \n+
    143 bool operator[](std::size_t v) const;
    \n+
    144
    \n+
    151 void setIsolated();
    \n+
    152
    \n+
    156 bool isolated() const;
    \n+
    157
    \n+
    161 void resetIsolated();
    \n+
    162
    \n+
    166 void setVisited();
    \n+
    167
    \n+
    171 bool visited() const;
    \n+
    172
    \n+
    176 void resetVisited();
    \n+
    177
    \n+
    181 void setFront();
    \n+
    182
    \n+
    186 bool front() const;
    \n+
    187
    \n+
    191 void resetFront();
    \n+
    192
    \n+
    196 void setExcludedBorder();
    \n+
    197
    \n+
    202 bool excludedBorder() const;
    \n+
    203
    \n+
    207 void resetExcludedBorder();
    \n+
    208
    \n+
    212 void reset();
    \n+
    213
    \n+
    214 };
    \n+
    215
    \n+
    216 template<typename G, std::size_t i>
    \n+\n+
    218 : public RAPropertyMapHelper<typename std::bitset<VertexProperties::SIZE>::reference,
    \n+
    219 PropertyGraphVertexPropertyMap<G,i> >
    \n+
    220 {
    \n+
    221 public:
    \n+
    222
    \n+
    223 typedef ReadWritePropertyMapTag Category;
    \n+
    224
    \n+
    225 enum {
    \n+
    227 index = i
    \n+
    228 };
    \n+
    229
    \n+
    233 typedef G Graph;
    \n+
    234
    \n+
    238 typedef std::bitset<VertexProperties::SIZE> BitSet;
    \n+
    239
    \n+
    243 typedef typename BitSet::reference Reference;
    \n+
    244
    \n+
    248 typedef bool ValueType;
    \n+
    249
    \n+
    253 typedef typename G::VertexDescriptor Vertex;
    \n+
    254
    \n+\n+
    260 : graph_(&g)
    \n+
    261 {}
    \n+
    262
    \n+\n+
    267 : graph_(0)
    \n+
    268 {}
    \n+
    269
    \n+
    270
    \n+
    275 Reference operator[](const Vertex& vertex) const
    \n+
    276 {
    \n+
    277 return graph_->getVertexProperties(vertex)[index];
    \n+
    278 }
    \n+
    279 private:
    \n+
    280 Graph* graph_;
    \n+
    281 };
    \n+
    282
    \n+
    283 } // end namespace Amg
    \n+
    284
    \n+
    285 template<typename G, typename EP, typename VM, typename EM>
    \n+
    286 struct PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> >
    \n+
    287 {
    \n+\n+
    289 };
    \n+
    290
    \n+
    291 template<typename G, typename EP, typename VM, typename EM>
    \n+
    292 typename PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> >::Type
    \n+\n+
    294 {
    \n+\n+
    296 }
    \n+
    297
    \n+
    298 namespace Amg
    \n+
    299 {
    \n+
    300 inline std::ostream& operator<<(std::ostream& os, const EdgeProperties& props)
    \n+
    301 {
    \n+
    302 return os << props.flags_;
    \n+
    303 }
    \n+
    304
    \n+\n+
    306 : flags_()
    \n+
    307 {}
    \n+
    308
    \n+
    309 inline std::bitset<EdgeProperties::SIZE>::reference
    \n+\n+
    311 {
    \n+
    312 return flags_[v];
    \n+
    313 }
    \n+
    314
    \n+
    315 inline bool EdgeProperties::operator[](std::size_t i) const
    \n+
    316 {
    \n+
    317 return flags_[i];
    \n+
    318 }
    \n+
    319
    \n+\n+
    321 {
    \n+
    322 flags_.reset();
    \n+
    323 }
    \n+
    324
    \n+\n+
    326 {
    \n+
    327 // Set the INFLUENCE bit
    \n+
    328 //flags_ |= (1<<INFLUENCE);
    \n+
    329 flags_.set(INFLUENCE);
    \n+
    330 }
    \n+
    331
    \n+
    332 inline bool EdgeProperties::influences() const
    \n+
    333 {
    \n+
    334 // Test the INFLUENCE bit
    \n+
    335 return flags_.test(INFLUENCE);
    \n+
    336 }
    \n+
    337
    \n+\n+
    339 {
    \n+
    340 // Set the first bit.
    \n+
    341 //flags_ |= (1<<DEPEND);
    \n+
    342 flags_.set(DEPEND);
    \n+
    343 }
    \n+
    344
    \n+\n+
    346 {
    \n+
    347 // reset the first bit.
    \n+
    348 //flags_ &= ~(1<<DEPEND);
    \n+
    349 flags_.reset(DEPEND);
    \n+
    350 }
    \n+
    351
    \n+
    352 inline bool EdgeProperties::depends() const
    \n+
    353 {
    \n+
    354 // Return the first bit.
    \n+
    355 return flags_.test(DEPEND);
    \n+
    356 }
    \n+
    357
    \n+\n+
    359 {
    \n+
    360 // reset the second bit.
    \n+
    361 flags_ &= ~(1<<INFLUENCE);
    \n+
    362 }
    \n+
    363
    \n+
    364 inline bool EdgeProperties::isOneWay() const
    \n+
    365 {
    \n+
    366 // Test whether only the first bit is set
    \n+
    367 //return isStrong() && !isTwoWay();
    \n+
    368 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==(1<<DEPEND);
    \n+
    369 }
    \n+
    370
    \n+
    371 inline bool EdgeProperties::isTwoWay() const
    \n+
    372 {
    \n+
    373 // Test whether the first and second bit is set
    \n+
    374 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==((1<<INFLUENCE)|(1<<DEPEND));
    \n+
    375 }
    \n+
    376
    \n+
    377 inline bool EdgeProperties::isStrong() const
    \n+
    378 {
    \n+
    379 // Test whether the first or second bit is set
    \n+
    380 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND))).to_ulong();
    \n+
    381 }
    \n+
    382
    \n+
    383
    \n+
    384 inline std::ostream& operator<<(std::ostream& os, const VertexProperties& props)
    \n+
    385 {
    \n+
    386 return os << props.flags_;
    \n+
    387 }
    \n+
    388
    \n+\n+
    390 : flags_()
    \n+
    391 {}
    \n+
    392
    \n+
    393
    \n+
    394 inline std::bitset<VertexProperties::SIZE>::reference
    \n+\n+
    396 {
    \n+
    397 return flags_[v];
    \n+
    398 }
    \n+
    399
    \n+
    400 inline bool VertexProperties::operator[](std::size_t v) const
    \n+
    401 {
    \n+
    402 return flags_[v];
    \n+
    403 }
    \n+
    404
    \n+\n+
    406 {
    \n+
    407 flags_.set(ISOLATED);
    \n+
    408 }
    \n+
    409
    \n+
    410 inline bool VertexProperties::isolated() const
    \n+
    411 {
    \n+
    412 return flags_.test(ISOLATED);
    \n+
    413 }
    \n+
    414
    \n+\n+
    416 {
    \n+
    417 flags_.reset(ISOLATED);
    \n+
    418 }
    \n+
    419
    \n+\n+
    421 {
    \n+
    422 flags_.set(VISITED);
    \n+
    423 }
    \n+
    424
    \n+
    425 inline bool VertexProperties::visited() const
    \n+
    426 {
    \n+
    427 return flags_.test(VISITED);
    \n+
    428 }
    \n+
    429
    \n+\n+
    431 {
    \n+
    432 flags_.reset(VISITED);
    \n+
    433 }
    \n+
    434
    \n+\n+
    436 {
    \n+
    437 flags_.set(FRONT);
    \n+
    438 }
    \n+
    439
    \n+
    440 inline bool VertexProperties::front() const
    \n+
    441 {
    \n+
    442 return flags_.test(FRONT);
    \n+
    443 }
    \n+
    444
    \n+\n+
    446 {
    \n+
    447 flags_.reset(FRONT);
    \n+
    448 }
    \n+
    449
    \n+\n+
    451 {
    \n+
    452 flags_.set(BORDER);
    \n+
    453 }
    \n+
    454
    \n+\n+
    456 {
    \n+
    457 return flags_.test(BORDER);
    \n+
    458 }
    \n+
    459
    \n+\n+
    461 {
    \n+
    462 flags_.reset(BORDER);
    \n+
    463 }
    \n+
    464
    \n+\n+
    466 {
    \n+
    467 flags_.reset();
    \n+
    468 }
    \n+
    469
    \n+
    471 }
    \n+
    472}
    \n+
    473#endif
    \n+
    Provides classes for building the matrix graph.
    \n+
    Provides classes for handling internal properties in a graph.
    \n+
    bool depends() const
    Checks wether the vertex the edge points to depends on the vertex the edge starts.
    Definition: dependency.hh:352
    \n+
    void resetFront()
    Resets the front node flag.
    Definition: dependency.hh:445
    \n+
    std::bitset< VertexProperties::SIZE > BitSet
    The type of the bitset.
    Definition: dependency.hh:238
    \n+
    bool isolated() const
    Checks wether the node is isolated.
    Definition: dependency.hh:410
    \n+
    bool ValueType
    The value type.
    Definition: dependency.hh:248
    \n+
    friend std::ostream & operator<<(std::ostream &os, const VertexProperties &props)
    Definition: dependency.hh:384
    \n+
    BitSet::reference Reference
    The reference type.
    Definition: dependency.hh:243
    \n+
    bool isTwoWay() const
    Checks wether the edge is two way. I.e. both the influence flag and the depends flag are that.
    Definition: dependency.hh:371
    \n+
    void setInfluences()
    Marks the edge as one of which the start vertex by the end vertex.
    Definition: dependency.hh:325
    \n+
    VertexProperties()
    Constructor.
    Definition: dependency.hh:389
    \n+
    void setDepends()
    Marks the edge as one of which the end point depends on the starting point.
    Definition: dependency.hh:338
    \n+
    PropertyGraphVertexPropertyMap()
    Default constructor.
    Definition: dependency.hh:266
    \n+
    PropertyGraphVertexPropertyMap(G &g)
    Constructor.
    Definition: dependency.hh:259
    \n+
    G::VertexDescriptor Vertex
    The vertex descriptor.
    Definition: dependency.hh:253
    \n+
    void resetExcludedBorder()
    Marks the vertex as included in the aggregation.
    Definition: dependency.hh:460
    \n+
    void setFront()
    Marks the node as belonging to the current clusters front.
    Definition: dependency.hh:435
    \n+
    void reset()
    Reset all flags.
    Definition: dependency.hh:465
    \n+
    void setVisited()
    Mark the node as already visited.
    Definition: dependency.hh:420
    \n+
    EdgeProperties()
    Constructor.
    Definition: dependency.hh:305
    \n+
    void resetInfluences()
    Resets the influence flag.
    Definition: dependency.hh:358
    \n+
    G Graph
    The type of the graph with internal properties.
    Definition: dependency.hh:233
    \n+
    std::bitset< SIZE >::reference operator[](std::size_t v)
    Access the bits directly.
    Definition: dependency.hh:395
    \n+
    void printFlags() const
    Prints the attributes of the edge for debugging.
    \n+
    friend std::ostream & operator<<(std::ostream &os, const EdgeProperties &props)
    Definition: dependency.hh:300
    \n+
    Amg::PropertyGraphVertexPropertyMap< Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM >, Amg::VertexProperties::VISITED > Type
    Definition: dependency.hh:288
    \n+
    bool influences() const
    Checks wether the start vertex is influenced by the end vertex.
    Definition: dependency.hh:332
    \n+
    void setIsolated()
    Marks that node as being isolated.
    Definition: dependency.hh:405
    \n+
    bool excludedBorder() const
    Tests whether the vertex is excluded from the aggregation.
    Definition: dependency.hh:455
    \n+
    void resetVisited()
    Resets the visited flag.
    Definition: dependency.hh:430
    \n+
    bool visited() const
    Checks wether the node is marked as visited.
    Definition: dependency.hh:425
    \n+
    Reference operator[](const Vertex &vertex) const
    Get the properties associated to a vertex.
    Definition: dependency.hh:275
    \n+
    void reset()
    Reset all flags.
    Definition: dependency.hh:320
    \n+
    void resetDepends()
    Resets the depends flag.
    Definition: dependency.hh:345
    \n+
    ReadWritePropertyMapTag Category
    Definition: dependency.hh:223
    \n+
    void resetIsolated()
    Resets the isolated flag.
    Definition: dependency.hh:415
    \n+
    std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T > &criterion)
    Definition: aggregates.hh:113
    \n+
    bool isStrong() const
    Checks wether the edge is strong. I.e. the influence or depends flag is set.
    Definition: dependency.hh:377
    \n+
    bool front() const
    Checks wether the node is marked as a front node.
    Definition: dependency.hh:440
    \n+
    std::bitset< SIZE >::reference operator[](std::size_t v)
    Access the bits directly.
    Definition: dependency.hh:310
    \n+
    void setExcludedBorder()
    Marks the vertex as excluded from the aggregation.
    Definition: dependency.hh:450
    \n+
    bool isOneWay() const
    Checks wether the edge is one way. I.e. either the influence or the depends flag but is set.
    Definition: dependency.hh:364
    \n+
    @ index
    the index to access in the bitset.
    Definition: dependency.hh:227
    \n+
    @ VISITED
    Definition: dependency.hh:129
    \n+
    @ ISOLATED
    Definition: dependency.hh:129
    \n+
    @ SIZE
    Definition: dependency.hh:129
    \n+
    @ BORDER
    Definition: dependency.hh:129
    \n+
    @ FRONT
    Definition: dependency.hh:129
    \n+
    @ DEPEND
    Definition: dependency.hh:43
    \n+
    @ SIZE
    Definition: dependency.hh:43
    \n+
    @ INFLUENCE
    Definition: dependency.hh:43
    \n
    Definition: allocator.hh:11
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n-
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n-
    A subgraph of a graph.
    Definition: graph.hh:443
    \n-
    EdgeIndexMap getEdgeIndexMap()
    Get an edge index map for the graph.
    \n-
    An index map for mapping the edges to indices.
    Definition: graph.hh:470
    \n+
    Definition: dependency.hh:220
    \n
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n-
    Definition: graphcreator.hh:22
    \n-
    Dune::Amg::SubGraph< MatrixGraph, std::vector< bool > > SubGraph
    Definition: graphcreator.hh:26
    \n-
    Dune::Amg::PropertiesGraph< SubGraph, VertexProperties, EdgeProperties, IdentityMap, typename SubGraph::EdgeIndexMap > PropertiesGraph
    Definition: graphcreator.hh:32
    \n-
    M::matrix_type Matrix
    Definition: graphcreator.hh:23
    \n-
    static GraphTuple create(const M &matrix, T &excluded, PI &pinfo, const OF &of)
    Definition: graphcreator.hh:37
    \n-
    static void free(GraphTuple &graphs)
    Definition: graphcreator.hh:53
    \n-
    Dune::Amg::MatrixGraph< const Matrix > MatrixGraph
    Definition: graphcreator.hh:24
    \n-
    std::tuple< MatrixGraph *, PropertiesGraph *, SubGraph * > GraphTuple
    Definition: graphcreator.hh:34
    \n-
    Dune::Amg::MatrixGraph< const Matrix > MatrixGraph
    Definition: graphcreator.hh:65
    \n-
    M::matrix_type Matrix
    Definition: graphcreator.hh:63
    \n-
    Dune::Amg::PropertiesGraph< MatrixGraph, VertexProperties, EdgeProperties, IdentityMap, IdentityMap > PropertiesGraph
    Definition: graphcreator.hh:71
    \n-
    std::tuple< MatrixGraph *, PropertiesGraph * > GraphTuple
    Definition: graphcreator.hh:73
    \n-
    static GraphTuple create(const M &matrix, T &excluded, const SequentialInformation &pinfo, const OF &)
    Definition: graphcreator.hh:76
    \n-
    static void free(GraphTuple &graphs)
    Definition: graphcreator.hh:86
    \n-
    Definition: pinfo.hh:28
    \n+
    Tag idnetifying the visited property of a vertex.
    Definition: properties.hh:29
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,189 +5,576 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-graphcreator.hh\n+dependency.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_GRAPHCREATOR_HH\n- 6#define DUNE_AMG_GRAPHCREATOR_HH\n+ 5#ifndef DUNE_AMG_DEPENDENCY_HH\n+ 6#define DUNE_AMG_DEPENDENCY_HH\n 7\n- 8#include \n- 9\n- 10#include \"graph.hh\"\n- 11#include \"dependency.hh\"\n- 12#include \"pinfo.hh\"\n- 13#include \n- 14#include \n+ 8\n+ 9#include \n+ 10#include \n+ 11\n+ 12#include \"graph.hh\"\n+ 13#include \"properties.hh\"\n+ 14#include \n 15\n- 16namespace Dune\n- 17{\n- 18 namespace Amg\n- 19 {\n- 20 template\n-21 struct PropertiesGraphCreator\n- 22 {\n-23 typedef typename M::matrix_type Matrix;\n-24 typedef Dune::Amg::MatrixGraph MatrixGraph;\n- 25 typedef Dune::Amg::SubGraph > SubGraph;\n- 27 typedef Dune::Amg::PropertiesGraph\n-32 PropertiesGraph;\n- 33\n-34 typedef std::tuple GraphTuple;\n- 35\n- 36 template\n-37 static GraphTuple create(const M& matrix, T& excluded,\n- 38 PI& pinfo, const OF& of)\n+ 16\n+ 17namespace Dune\n+ 18{\n+ 19 namespace Amg\n+ 20 {\n+38 class EdgeProperties\n 39 {\n- 40 MatrixGraph* mg = new MatrixGraph(matrix.getmat());\n- 41 typedef typename PI::ParallelIndexSet ParallelIndexSet;\n- 42 typedef typename ParallelIndexSet::const_iterator IndexIterator;\n- 43 IndexIterator iend = pinfo.indexSet().end();\n+ 40 friend std::ostream& operator<<(std::ostream& os, const EdgeProperties&\n+props);\n+ 41 public:\n+43 enum {INFLUENCE, DEPEND, SIZE};\n 44\n- 45 for(IndexIterator index = pinfo.indexSet().begin(); index != iend; ++index)\n- 46 excluded[index->local()] = of.contains(index->local().attribute());\n- 47\n- 48 SubGraph* sg= new SubGraph(*mg, excluded);\n- 49 PropertiesGraph* pg = new PropertiesGraph(*sg, IdentityMap(), sg-\n->getEdgeIndexMap());\n- 50 return GraphTuple(mg,pg,sg);\n- 51 }\n- 52\n-53 static void free(GraphTuple& graphs)\n- 54 {\n- 55 delete std::get<2>(graphs);\n- 56 delete std::get<1>(graphs);\n- 57 }\n- 58 };\n- 59\n- 60 template\n-61 struct PropertiesGraphCreator\n- 62 {\n-63 typedef typename M::matrix_type Matrix;\n+ 45 private:\n+ 46\n+ 47 std::bitset flags_;\n+ 48 public:\n+ 50 EdgeProperties();\n+ 51\n+ 53 std::bitset::reference operator[](std::size_t v);\n+ 54\n+ 56 bool operator[](std::size_t v) const;\n+ 57\n+ 63 bool depends() const;\n 64\n-65 typedef Dune::Amg::MatrixGraph MatrixGraph;\n- 66\n- 67 typedef Dune::Amg::PropertiesGraph PropertiesGraph;\n- 72\n-73 typedef std::tuple GraphTuple;\n- 74\n- 75 template\n-76 static GraphTuple create([[maybe_unused]] const M& matrix,\n- 77 [[maybe_unused]] T& excluded,\n- 78 [[maybe_unused]] const SequentialInformation& pinfo,\n- 79 const OF&)\n- 80 {\n- 81 MatrixGraph* mg = new MatrixGraph(matrix.getmat());\n- 82 PropertiesGraph* pg = new PropertiesGraph(*mg, IdentityMap(), IdentityMap\n-());\n- 83 return GraphTuple(mg,pg);\n- 84 }\n- 85\n-86 static void free(GraphTuple& graphs)\n- 87 {\n- 88 delete std::get<1>(graphs);\n- 89 }\n- 90\n- 91 };\n- 92\n- 93 } //namespace Amg\n- 94} // namespace Dune\n- 95#endif\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n+ 69 void setDepends();\n+ 70\n+ 74 void resetDepends();\n+ 75\n+ 80 bool influences() const;\n+ 81\n+ 85 void setInfluences();\n+ 86\n+ 90 void resetInfluences();\n+ 91\n+ 96 bool isOneWay() const;\n+ 97\n+ 102 bool isTwoWay() const;\n+ 103\n+ 108 bool isStrong() const;\n+ 109\n+ 113 void reset();\n+ 114\n+118 void printFlags() const;\n+ 119 };\n+ 120\n+126 class VertexProperties {\n+ 127 friend std::ostream& operator<<(std::ostream& os, const VertexProperties&\n+props);\n+ 128 public:\n+129 enum { ISOLATED, VISITED, FRONT, BORDER, SIZE };\n+ 130 private:\n+ 131\n+ 133 std::bitset flags_;\n+ 134\n+ 135 public:\n+ 137 VertexProperties();\n+ 138\n+ 140 std::bitset::reference operator[](std::size_t v);\n+ 141\n+ 143 bool operator[](std::size_t v) const;\n+ 144\n+ 151 void setIsolated();\n+ 152\n+ 156 bool isolated() const;\n+ 157\n+ 161 void resetIsolated();\n+ 162\n+ 166 void setVisited();\n+ 167\n+ 171 bool visited() const;\n+ 172\n+ 176 void resetVisited();\n+ 177\n+ 181 void setFront();\n+ 182\n+ 186 bool front() const;\n+ 187\n+ 191 void resetFront();\n+ 192\n+ 196 void setExcludedBorder();\n+ 197\n+ 202 bool excludedBorder() const;\n+ 203\n+ 207 void resetExcludedBorder();\n+ 208\n+ 212 void reset();\n+ 213\n+ 214 };\n+ 215\n+ 216 template\n+217 class PropertyGraphVertexPropertyMap\n+ 218 : public RAPropertyMapHelper::reference,\n+ 219 PropertyGraphVertexPropertyMap >\n+ 220 {\n+ 221 public:\n+ 222\n+223 typedef ReadWritePropertyMapTag Category;\n+ 224\n+ 225 enum {\n+ 227 index = i\n+228 };\n+ 229\n+233 typedef G Graph;\n+ 234\n+238 typedef std::bitset BitSet;\n+ 239\n+243 typedef typename BitSet::reference Reference;\n+ 244\n+248 typedef bool ValueType;\n+ 249\n+253 typedef typename G::VertexDescriptor Vertex;\n+ 254\n+259 PropertyGraphVertexPropertyMap(G& g)\n+ 260 : graph_(&g)\n+ 261 {}\n+ 262\n+266 PropertyGraphVertexPropertyMap()\n+ 267 : graph_(0)\n+ 268 {}\n+ 269\n+ 270\n+275 Reference operator[](const Vertex& vertex) const\n+ 276 {\n+ 277 return graph_->getVertexProperties(vertex)[index];\n+ 278 }\n+ 279 private:\n+ 280 Graph* graph_;\n+ 281 };\n+ 282\n+ 283 } // end namespace Amg\n+ 284\n+ 285 template\n+286 struct PropertyMapTypeSelector >\n+ 287 {\n+288 typedef Amg::PropertyGraphVertexPropertyMap, Amg::VertexProperties::VISITED> Type;\n+ 289 };\n+ 290\n+ 291 template\n+ 292 typename PropertyMapTypeSelector >::Type\n+293 get([[maybe_unused]] const Amg::VertexVisitedTag& tag, Amg::\n+PropertiesGraph& graph)\n+ 294 {\n+ 295 return Amg::PropertyGraphVertexPropertyMap, Amg::VertexProperties::VISITED>(graph);\n+ 296 }\n+ 297\n+ 298 namespace Amg\n+ 299 {\n+300 inline std::ostream& operator<<(std::ostream& os, const EdgeProperties&\n+props)\n+ 301 {\n+ 302 return os << props.flags_;\n+ 303 }\n+ 304\n+305 inline EdgeProperties::EdgeProperties()\n+ 306 : flags_()\n+ 307 {}\n+ 308\n+ 309 inline std::bitset::reference\n+310 EdgeProperties::operator[](std::size_t v)\n+ 311 {\n+ 312 return flags_[v];\n+ 313 }\n+ 314\n+315 inline bool EdgeProperties::operator[](std::size_t i) const\n+ 316 {\n+ 317 return flags_[i];\n+ 318 }\n+ 319\n+320 inline void EdgeProperties::reset()\n+ 321 {\n+ 322 flags_.reset();\n+ 323 }\n+ 324\n+325 inline void EdgeProperties::setInfluences()\n+ 326 {\n+ 327 // Set the INFLUENCE bit\n+ 328 //flags_ |= (1<((1<((1<((1<::reference\n+395 VertexProperties::operator[](std::size_t v)\n+ 396 {\n+ 397 return flags_[v];\n+ 398 }\n+ 399\n+400 inline bool VertexProperties::operator[](std::size_t v) const\n+ 401 {\n+ 402 return flags_[v];\n+ 403 }\n+ 404\n+405 inline void VertexProperties::setIsolated()\n+ 406 {\n+ 407 flags_.set(ISOLATED);\n+ 408 }\n+ 409\n+410 inline bool VertexProperties::isolated() const\n+ 411 {\n+ 412 return flags_.test(ISOLATED);\n+ 413 }\n+ 414\n+415 inline void VertexProperties::resetIsolated()\n+ 416 {\n+ 417 flags_.reset(ISOLATED);\n+ 418 }\n+ 419\n+420 inline void VertexProperties::setVisited()\n+ 421 {\n+ 422 flags_.set(VISITED);\n+ 423 }\n+ 424\n+425 inline bool VertexProperties::visited() const\n+ 426 {\n+ 427 return flags_.test(VISITED);\n+ 428 }\n+ 429\n+430 inline void VertexProperties::resetVisited()\n+ 431 {\n+ 432 flags_.reset(VISITED);\n+ 433 }\n+ 434\n+435 inline void VertexProperties::setFront()\n+ 436 {\n+ 437 flags_.set(FRONT);\n+ 438 }\n+ 439\n+440 inline bool VertexProperties::front() const\n+ 441 {\n+ 442 return flags_.test(FRONT);\n+ 443 }\n+ 444\n+445 inline void VertexProperties::resetFront()\n+ 446 {\n+ 447 flags_.reset(FRONT);\n+ 448 }\n+ 449\n+450 inline void VertexProperties::setExcludedBorder()\n+ 451 {\n+ 452 flags_.set(BORDER);\n+ 453 }\n+ 454\n+455 inline bool VertexProperties::excludedBorder() const\n+ 456 {\n+ 457 return flags_.test(BORDER);\n+ 458 }\n+ 459\n+460 inline void VertexProperties::resetExcludedBorder()\n+ 461 {\n+ 462 flags_.reset(BORDER);\n+ 463 }\n+ 464\n+465 inline void VertexProperties::reset()\n+ 466 {\n+ 467 flags_.reset();\n+ 468 }\n+ 469\n+ 471 }\n+ 472}\n+ 473#endif\n graph.hh\n Provides classes for building the matrix graph.\n-pinfo.hh\n-dependency.hh\n-Provides classes for initializing the link attributes of a matrix graph.\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n+properties.hh\n+Provides classes for handling internal properties in a graph.\n+Dune::Amg::EdgeProperties::depends\n+bool depends() const\n+Checks wether the vertex the edge points to depends on the vertex the edge\n+starts.\n+Definition: dependency.hh:352\n+Dune::Amg::VertexProperties::resetFront\n+void resetFront()\n+Resets the front node flag.\n+Definition: dependency.hh:445\n+Dune::Amg::PropertyGraphVertexPropertyMap::BitSet\n+std::bitset< VertexProperties::SIZE > BitSet\n+The type of the bitset.\n+Definition: dependency.hh:238\n+Dune::Amg::VertexProperties::isolated\n+bool isolated() const\n+Checks wether the node is isolated.\n+Definition: dependency.hh:410\n+Dune::Amg::PropertyGraphVertexPropertyMap::ValueType\n+bool ValueType\n+The value type.\n+Definition: dependency.hh:248\n+Dune::Amg::VertexProperties::operator<<\n+friend std::ostream & operator<<(std::ostream &os, const VertexProperties\n+&props)\n+Definition: dependency.hh:384\n+Dune::Amg::PropertyGraphVertexPropertyMap::Reference\n+BitSet::reference Reference\n+The reference type.\n+Definition: dependency.hh:243\n+Dune::Amg::EdgeProperties::isTwoWay\n+bool isTwoWay() const\n+Checks wether the edge is two way. I.e. both the influence flag and the depends\n+flag are that.\n+Definition: dependency.hh:371\n+Dune::Amg::EdgeProperties::setInfluences\n+void setInfluences()\n+Marks the edge as one of which the start vertex by the end vertex.\n+Definition: dependency.hh:325\n+Dune::Amg::VertexProperties::VertexProperties\n+VertexProperties()\n+Constructor.\n+Definition: dependency.hh:389\n+Dune::Amg::EdgeProperties::setDepends\n+void setDepends()\n+Marks the edge as one of which the end point depends on the starting point.\n+Definition: dependency.hh:338\n+Dune::Amg::PropertyGraphVertexPropertyMap::PropertyGraphVertexPropertyMap\n+PropertyGraphVertexPropertyMap()\n+Default constructor.\n+Definition: dependency.hh:266\n+Dune::Amg::PropertyGraphVertexPropertyMap::PropertyGraphVertexPropertyMap\n+PropertyGraphVertexPropertyMap(G &g)\n+Constructor.\n+Definition: dependency.hh:259\n+Dune::Amg::PropertyGraphVertexPropertyMap::Vertex\n+G::VertexDescriptor Vertex\n+The vertex descriptor.\n+Definition: dependency.hh:253\n+Dune::Amg::VertexProperties::resetExcludedBorder\n+void resetExcludedBorder()\n+Marks the vertex as included in the aggregation.\n+Definition: dependency.hh:460\n+Dune::Amg::VertexProperties::setFront\n+void setFront()\n+Marks the node as belonging to the current clusters front.\n+Definition: dependency.hh:435\n+Dune::Amg::VertexProperties::reset\n+void reset()\n+Reset all flags.\n+Definition: dependency.hh:465\n+Dune::Amg::VertexProperties::setVisited\n+void setVisited()\n+Mark the node as already visited.\n+Definition: dependency.hh:420\n+Dune::Amg::EdgeProperties::EdgeProperties\n+EdgeProperties()\n+Constructor.\n+Definition: dependency.hh:305\n+Dune::Amg::EdgeProperties::resetInfluences\n+void resetInfluences()\n+Resets the influence flag.\n+Definition: dependency.hh:358\n+Dune::Amg::PropertyGraphVertexPropertyMap::Graph\n+G Graph\n+The type of the graph with internal properties.\n+Definition: dependency.hh:233\n+Dune::Amg::VertexProperties::operator[]\n+std::bitset< SIZE >::reference operator[](std::size_t v)\n+Access the bits directly.\n+Definition: dependency.hh:395\n+Dune::Amg::EdgeProperties::printFlags\n+void printFlags() const\n+Prints the attributes of the edge for debugging.\n+Dune::Amg::EdgeProperties::operator<<\n+friend std::ostream & operator<<(std::ostream &os, const EdgeProperties &props)\n+Definition: dependency.hh:300\n+Dune::PropertyMapTypeSelector<_Amg::VertexVisitedTag,_Amg::PropertiesGraph<_G,\n+Amg::VertexProperties,_EP,_VM,_EM_>_>::Type\n+Amg::PropertyGraphVertexPropertyMap< Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM >, Amg::VertexProperties::VISITED > Type\n+Definition: dependency.hh:288\n+Dune::Amg::EdgeProperties::influences\n+bool influences() const\n+Checks wether the start vertex is influenced by the end vertex.\n+Definition: dependency.hh:332\n+Dune::Amg::VertexProperties::setIsolated\n+void setIsolated()\n+Marks that node as being isolated.\n+Definition: dependency.hh:405\n+Dune::Amg::VertexProperties::excludedBorder\n+bool excludedBorder() const\n+Tests whether the vertex is excluded from the aggregation.\n+Definition: dependency.hh:455\n+Dune::Amg::VertexProperties::resetVisited\n+void resetVisited()\n+Resets the visited flag.\n+Definition: dependency.hh:430\n+Dune::Amg::VertexProperties::visited\n+bool visited() const\n+Checks wether the node is marked as visited.\n+Definition: dependency.hh:425\n+Dune::Amg::PropertyGraphVertexPropertyMap::operator[]\n+Reference operator[](const Vertex &vertex) const\n+Get the properties associated to a vertex.\n+Definition: dependency.hh:275\n+Dune::Amg::EdgeProperties::reset\n+void reset()\n+Reset all flags.\n+Definition: dependency.hh:320\n+Dune::Amg::EdgeProperties::resetDepends\n+void resetDepends()\n+Resets the depends flag.\n+Definition: dependency.hh:345\n+Dune::Amg::PropertyGraphVertexPropertyMap::Category\n+ReadWritePropertyMapTag Category\n+Definition: dependency.hh:223\n+Dune::Amg::VertexProperties::resetIsolated\n+void resetIsolated()\n+Resets the isolated flag.\n+Definition: dependency.hh:415\n+Dune::Amg::operator<<\n+std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T >\n+&criterion)\n+Definition: aggregates.hh:113\n+Dune::Amg::EdgeProperties::isStrong\n+bool isStrong() const\n+Checks wether the edge is strong. I.e. the influence or depends flag is set.\n+Definition: dependency.hh:377\n+Dune::Amg::VertexProperties::front\n+bool front() const\n+Checks wether the node is marked as a front node.\n+Definition: dependency.hh:440\n+Dune::Amg::EdgeProperties::operator[]\n+std::bitset< SIZE >::reference operator[](std::size_t v)\n+Access the bits directly.\n+Definition: dependency.hh:310\n+Dune::Amg::VertexProperties::setExcludedBorder\n+void setExcludedBorder()\n+Marks the vertex as excluded from the aggregation.\n+Definition: dependency.hh:450\n+Dune::Amg::EdgeProperties::isOneWay\n+bool isOneWay() const\n+Checks wether the edge is one way. I.e. either the influence or the depends\n+flag but is set.\n+Definition: dependency.hh:364\n+Dune::Amg::PropertyGraphVertexPropertyMap::index\n+@ index\n+the index to access in the bitset.\n+Definition: dependency.hh:227\n+Dune::Amg::VertexProperties::VISITED\n+@ VISITED\n+Definition: dependency.hh:129\n+Dune::Amg::VertexProperties::ISOLATED\n+@ ISOLATED\n+Definition: dependency.hh:129\n+Dune::Amg::VertexProperties::SIZE\n+@ SIZE\n+Definition: dependency.hh:129\n+Dune::Amg::VertexProperties::BORDER\n+@ BORDER\n+Definition: dependency.hh:129\n+Dune::Amg::VertexProperties::FRONT\n+@ FRONT\n+Definition: dependency.hh:129\n+Dune::Amg::EdgeProperties::DEPEND\n+@ DEPEND\n+Definition: dependency.hh:43\n+Dune::Amg::EdgeProperties::SIZE\n+@ SIZE\n+Definition: dependency.hh:43\n+Dune::Amg::EdgeProperties::INFLUENCE\n+@ INFLUENCE\n+Definition: dependency.hh:43\n Dune\n Definition: allocator.hh:11\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n Dune::Amg::EdgeProperties\n Class representing the properties of an ede in the matrix graph.\n Definition: dependency.hh:39\n Dune::Amg::VertexProperties\n Class representing a node in the matrix graph.\n Definition: dependency.hh:126\n-Dune::Amg::MatrixGraph\n-The (undirected) graph of a matrix.\n-Definition: graph.hh:51\n-Dune::Amg::SubGraph\n-A subgraph of a graph.\n-Definition: graph.hh:443\n-Dune::Amg::SubGraph::getEdgeIndexMap\n-EdgeIndexMap getEdgeIndexMap()\n-Get an edge index map for the graph.\n-Dune::Amg::SubGraph::EdgeIndexMap\n-An index map for mapping the edges to indices.\n-Definition: graph.hh:470\n+Dune::Amg::PropertyGraphVertexPropertyMap\n+Definition: dependency.hh:220\n Dune::Amg::PropertiesGraph\n Attaches properties to the edges and vertices of a graph.\n Definition: graph.hh:978\n-Dune::Amg::PropertiesGraphCreator\n-Definition: graphcreator.hh:22\n-Dune::Amg::PropertiesGraphCreator::SubGraph\n-Dune::Amg::SubGraph< MatrixGraph, std::vector< bool > > SubGraph\n-Definition: graphcreator.hh:26\n-Dune::Amg::PropertiesGraphCreator::PropertiesGraph\n-Dune::Amg::PropertiesGraph< SubGraph, VertexProperties, EdgeProperties,\n-IdentityMap, typename SubGraph::EdgeIndexMap > PropertiesGraph\n-Definition: graphcreator.hh:32\n-Dune::Amg::PropertiesGraphCreator::Matrix\n-M::matrix_type Matrix\n-Definition: graphcreator.hh:23\n-Dune::Amg::PropertiesGraphCreator::create\n-static GraphTuple create(const M &matrix, T &excluded, PI &pinfo, const OF &of)\n-Definition: graphcreator.hh:37\n-Dune::Amg::PropertiesGraphCreator::free\n-static void free(GraphTuple &graphs)\n-Definition: graphcreator.hh:53\n-Dune::Amg::PropertiesGraphCreator::MatrixGraph\n-Dune::Amg::MatrixGraph< const Matrix > MatrixGraph\n-Definition: graphcreator.hh:24\n-Dune::Amg::PropertiesGraphCreator::GraphTuple\n-std::tuple< MatrixGraph *, PropertiesGraph *, SubGraph * > GraphTuple\n-Definition: graphcreator.hh:34\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::MatrixGraph\n-Dune::Amg::MatrixGraph< const Matrix > MatrixGraph\n-Definition: graphcreator.hh:65\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::Matrix\n-M::matrix_type Matrix\n-Definition: graphcreator.hh:63\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::PropertiesGraph\n-Dune::Amg::PropertiesGraph< MatrixGraph, VertexProperties, EdgeProperties,\n-IdentityMap, IdentityMap > PropertiesGraph\n-Definition: graphcreator.hh:71\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::GraphTuple\n-std::tuple< MatrixGraph *, PropertiesGraph * > GraphTuple\n-Definition: graphcreator.hh:73\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::create\n-static GraphTuple create(const M &matrix, T &excluded, const\n-SequentialInformation &pinfo, const OF &)\n-Definition: graphcreator.hh:76\n-Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::free\n-static void free(GraphTuple &graphs)\n-Definition: graphcreator.hh:86\n-Dune::Amg::SequentialInformation\n-Definition: pinfo.hh:28\n+Dune::Amg::VertexVisitedTag\n+Tag idnetifying the visited property of a vertex.\n+Definition: properties.hh:29\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00146.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00146.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: kamg.hh File Reference\n+dune-istl: transfer.hh File Reference\n \n \n \n \n \n \n \n@@ -65,43 +65,47 @@\n
  • dune
  • istl
  • paamg
  • \n \n \n \n
    \n \n-

    Provides an algebraic multigrid using a Krylov cycle. \n+

    Prolongation and restriction for amg. \n More...

    \n-
    #include <dune/istl/preconditioners.hh>
    \n-#include "amg.hh"
    \n+
    #include <dune/istl/bvector.hh>
    \n+#include <dune/istl/matrixredistribute.hh>
    \n+#include <dune/istl/paamg/pinfo.hh>
    \n+#include <dune/istl/owneroverlapcopy.hh>
    \n+#include <dune/istl/paamg/aggregates.hh>
    \n+#include <dune/common/exceptions.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n-\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::KAmgTwoGrid< AMG >
     Two grid operator for AMG with Krylov cycle. More...
    class  Dune::Amg::Transfer< V1, V2, T >
     
    class  Dune::Amg::KAMG< M, X, S, PI, K, A >
     an algebraic multigrid method using a Krylov-cycle. More...
    class  Dune::Amg::Transfer< V, V1, SequentialInformation >
     
    class  Dune::Amg::Transfer< V, V1, OwnerOverlapCopyCommunication< T1, T2 > >
     
    \n \n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n

    Detailed Description

    \n-

    Provides an algebraic multigrid using a Krylov cycle.

    \n+

    Prolongation and restriction for amg.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -6,33 +6,37 @@\n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n Classes | Namespaces\n-kamg.hh File Reference\n+transfer.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n \u00bb Parallel_Algebraic_Multigrid\n-Provides an algebraic multigrid using a Krylov cycle. More...\n-#include \n-#include \"amg.hh\"\n+Prolongation and restriction for amg. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::Amg::KAmgTwoGrid<_AMG_>\n-\u00a0 Two grid operator for AMG with Krylov cycle. More...\n+class \u00a0Dune::Amg::Transfer<_V1,_V2,_T_>\n \u00a0\n-class \u00a0Dune::Amg::KAMG<_M,_X,_S,_PI,_K,_A_>\n-\u00a0 an algebraic multigrid method using a Krylov-cycle. More...\n+class \u00a0Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>\n+\u00a0\n+class \u00a0Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n ***** Detailed Description *****\n-Provides an algebraic multigrid using a Krylov cycle.\n+Prolongation and restriction for amg.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00146_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00146_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: kamg.hh Source File\n+dune-istl: transfer.hh Source File\n \n \n \n \n \n \n \n@@ -62,298 +62,227 @@\n \n
    \n \n
    \n
    \n
    \n-
    kamg.hh
    \n+
    transfer.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_KAMG_HH
    \n-
    6#define DUNE_AMG_KAMG_HH
    \n+
    5#ifndef DUNE_AMGTRANSFER_HH
    \n+
    6#define DUNE_AMGTRANSFER_HH
    \n
    7
    \n-\n-
    9#include "amg.hh"
    \n-
    10
    \n-
    11namespace Dune
    \n-
    12{
    \n-
    13 namespace Amg
    \n-
    14 {
    \n-
    15
    \n-
    30 template<class AMG>
    \n-\n-
    32 : public Preconditioner<typename AMG::Domain,typename AMG::Range>
    \n-
    33 {
    \n-
    35 typedef typename AMG::Domain Domain;
    \n-
    37 typedef typename AMG::Range Range;
    \n-
    38 public:
    \n-
    39
    \n-\n-
    42 {
    \n-
    43 return amg_.category();
    \n-
    44 };
    \n+\n+\n+\n+\n+\n+
    13#include <dune/common/exceptions.hh>
    \n+
    14
    \n+
    15namespace Dune
    \n+
    16{
    \n+
    17 namespace Amg
    \n+
    18 {
    \n+
    19
    \n+
    30 template<class V1, class V2, class T>
    \n+\n+
    32 {
    \n+
    33
    \n+
    34 public:
    \n+
    35 typedef V1 Vertex;
    \n+
    36 typedef V2 Vector;
    \n+
    37
    \n+
    38 template<typename T1, typename R>
    \n+
    39 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+
    40 Vector& fineRedist,T1 damp, R& redistributor=R());
    \n+
    41
    \n+
    42 template<typename T1, typename R>
    \n+
    43 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+
    44 T1 damp);
    \n
    45
    \n-\n-
    54 : amg_(amg), coarseSolver_(coarseSolver)
    \n-
    55 {}
    \n-
    56
    \n-
    58 void pre([[maybe_unused]] typename AMG::Domain& x, [[maybe_unused]] typename AMG::Range& b)
    \n-
    59 {}
    \n-
    60
    \n-
    62 void post([[maybe_unused]] typename AMG::Domain& x)
    \n-
    63 {}
    \n-
    64
    \n-
    66 void apply(typename AMG::Domain& v, const typename AMG::Range& d)
    \n-
    67 {
    \n-
    68 // Copy data
    \n-
    69 *levelContext_->update=0;
    \n-
    70 *levelContext_->rhs = d;
    \n-
    71 *levelContext_->lhs = v;
    \n-
    72
    \n-
    73 presmooth(*levelContext_, amg_.preSteps_);
    \n-
    74 bool processFineLevel =
    \n-
    75 amg_.moveToCoarseLevel(*levelContext_);
    \n-
    76
    \n-
    77 if(processFineLevel) {
    \n-
    78 typename AMG::Range b=*levelContext_->rhs;
    \n-
    79 typename AMG::Domain x=*levelContext_->update;
    \n-\n-
    81 coarseSolver_->apply(x, b, res);
    \n-
    82 *levelContext_->update=x;
    \n-
    83 }
    \n-
    84
    \n-
    85 amg_.moveToFineLevel(*levelContext_, processFineLevel);
    \n-
    86
    \n-
    87 postsmooth(*levelContext_, amg_.postSteps_);
    \n-
    88 v=*levelContext_->update;
    \n-
    89 }
    \n-
    90
    \n-\n-
    96 {
    \n-
    97 return coarseSolver_;
    \n-
    98 }
    \n-
    99
    \n-
    104 void setLevelContext(std::shared_ptr<typename AMG::LevelContext> p)
    \n-
    105 {
    \n-
    106 levelContext_=p;
    \n-
    107 }
    \n-
    108
    \n-\n-
    111 {}
    \n-
    112
    \n-
    113 private:
    \n-
    115 AMG& amg_;
    \n-
    117 std::shared_ptr<InverseOperator<Domain,Range> > coarseSolver_;
    \n-
    119 std::shared_ptr<typename AMG::LevelContext> levelContext_;
    \n-
    120 };
    \n-
    121
    \n-
    122
    \n+
    46 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n+
    47 T& comm);
    \n+
    48 };
    \n+
    49
    \n+
    50 template<class V,class V1>
    \n+\n+
    52 {
    \n+
    53 public:
    \n+
    54 typedef V Vertex;
    \n+
    55 typedef V1 Vector;
    \n+\n+
    57 template<typename T1>
    \n+
    58 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+
    59 Vector& fineRedist, T1 damp,
    \n+\n+
    61 const Redist& redist=Redist());
    \n+
    62 template<typename T1>
    \n+
    63 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+
    64 T1 damp,
    \n+\n+
    66
    \n+
    67
    \n+
    68 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n+
    69 const SequentialInformation& comm);
    \n+
    70 };
    \n+
    71
    \n+
    72#if HAVE_MPI
    \n+
    73
    \n+
    74 template<class V,class V1, class T1, class T2>
    \n+\n+
    76 {
    \n+
    77 public:
    \n+
    78 typedef V Vertex;
    \n+
    79 typedef V1 Vector;
    \n+\n+
    81 template<typename T3>
    \n+
    82 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+
    83 Vector& fineRedist, T3 damp, OwnerOverlapCopyCommunication<T1,T2>& comm,
    \n+
    84 const Redist& redist);
    \n+
    85 template<typename T3>
    \n+
    86 static void prolongateVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, Vector& fine,
    \n+\n+
    88
    \n+
    89 static void restrictVector(const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector& fine,
    \n+\n+
    91 };
    \n+
    92
    \n+
    93#endif
    \n+
    94
    \n+
    95 template<class V, class V1>
    \n+
    96 template<typename T>
    \n+
    97 inline void
    \n+\n+
    99 Vector& coarse, Vector& fine,
    \n+
    100 [[maybe_unused]] Vector& fineRedist,
    \n+
    101 T damp,
    \n+
    102 [[maybe_unused]] const SequentialInformation& comm,
    \n+
    103 [[maybe_unused]] const Redist& redist)
    \n+
    104 {
    \n+
    105 prolongateVector(aggregates, coarse, fine, damp);
    \n+
    106 }
    \n+
    107 template<class V, class V1>
    \n+
    108 template<typename T>
    \n+
    109 inline void
    \n+\n+
    111 Vector& coarse, Vector& fine,
    \n+
    112 T damp,
    \n+
    113 [[maybe_unused]] const SequentialInformation& comm)
    \n+
    114 {
    \n+
    115 typedef typename Vector::iterator Iterator;
    \n+
    116
    \n+
    117 Iterator end = coarse.end();
    \n+
    118 Iterator begin= coarse.begin();
    \n+
    119 for(; begin!=end; ++begin)
    \n+
    120 *begin*=damp;
    \n+
    121 end=fine.end();
    \n+
    122 begin=fine.begin();
    \n
    123
    \n-
    137 template<class M, class X, class S, class PI=SequentialInformation,
    \n-
    138 class K=GeneralizedPCGSolver<X>, class A=std::allocator<X> >
    \n-
    139 class KAMG : public Preconditioner<X,X>
    \n-
    140 {
    \n-
    141 public:
    \n-\n-
    145 typedef K KrylovSolver;
    \n-\n-\n-\n-\n-
    155 typedef typename Amg::Operator Operator;
    \n-
    157 typedef typename Amg::Domain Domain;
    \n-
    159 typedef typename Amg::Range Range;
    \n-\n-\n-
    164
    \n-\n-
    167 {
    \n-
    168 return amg.category();
    \n-
    169 };
    \n+
    124 for(Iterator block=begin; block != end; ++block) {
    \n+
    125 std::ptrdiff_t index=block-begin;
    \n+
    126 const Vertex& vertex = aggregates[index];
    \n+\n+
    128 *block += coarse[aggregates[index]];
    \n+
    129 }
    \n+
    130 }
    \n+
    131
    \n+
    132 template<class V, class V1>
    \n+
    133 inline void
    \n+\n+
    135 Vector& coarse,
    \n+
    136 const Vector& fine,
    \n+
    137 [[maybe_unused]] const SequentialInformation& comm)
    \n+
    138 {
    \n+
    139 // Set coarse vector to zero
    \n+
    140 coarse=0;
    \n+
    141
    \n+
    142 typedef typename Vector::const_iterator Iterator;
    \n+
    143 Iterator end = fine.end();
    \n+
    144 Iterator begin=fine.begin();
    \n+
    145
    \n+
    146 for(Iterator block=begin; block != end; ++block) {
    \n+
    147 const Vertex& vertex = aggregates[block-begin];
    \n+\n+
    149 coarse[vertex] += *block;
    \n+
    150 }
    \n+
    151 }
    \n+
    152
    \n+
    153#if HAVE_MPI
    \n+
    154 template<class V, class V1, class T1, class T2>
    \n+
    155 template<typename T3>
    \n+
    156 inline void Transfer<V,V1,OwnerOverlapCopyCommunication<T1,T2> >::prolongateVector(const AggregatesMap<Vertex>& aggregates,
    \n+
    157 Vector& coarse, Vector& fine,
    \n+
    158 Vector& fineRedist, T3 damp,
    \n+\n+
    160 const Redist& redist)
    \n+
    161 {
    \n+
    162 if(fineRedist.size()>0)
    \n+
    163 // we operated on the coarse level
    \n+
    164 Transfer<V,V1,SequentialInformation>::prolongateVector(aggregates, coarse, fineRedist, damp);
    \n+
    165
    \n+
    166 // TODO This could be accomplished with one communication, too!
    \n+
    167 redist.redistributeBackward(fine, fineRedist);
    \n+
    168 comm.copyOwnerToAll(fine,fine);
    \n+
    169 }
    \n
    170
    \n-
    182 KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n-
    183 const SmootherArgs& smootherArgs, const Parameters& parms,
    \n-
    184 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1);
    \n-
    185
    \n-
    199 template<class C>
    \n-
    200 KAMG(const Operator& fineOperator, const C& criterion,
    \n-
    201 const SmootherArgs& smootherArgs=SmootherArgs(),
    \n-
    202 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1,
    \n-\n-
    204
    \n-
    206 void pre(Domain& x, Range& b);
    \n-
    208 void post(Domain& x);
    \n-
    210 void apply(Domain& v, const Range& d);
    \n-
    211
    \n-
    212 std::size_t maxlevels();
    \n-
    213
    \n-
    214 private:
    \n-
    216 Amg amg;
    \n-
    217
    \n-
    219 std::size_t maxLevelKrylovSteps;
    \n-
    220
    \n-
    222 double levelDefectReduction;
    \n-
    223
    \n-
    225 std::vector<std::shared_ptr<typename Amg::ScalarProduct> > scalarproducts;
    \n-
    226
    \n-
    228 std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > > ksolvers;
    \n-
    229 };
    \n-
    230
    \n-
    231
    \n-
    232 template<class M, class X, class S, class P, class K, class A>
    \n-\n-
    234 const SmootherArgs& smootherArgs, const Parameters& params,
    \n-
    235 std::size_t ksteps, double reduction)
    \n-
    236 : amg(matrices, coarseSolver, smootherArgs, params),
    \n-
    237 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
    \n-
    238 {}
    \n-
    239
    \n-
    240
    \n-
    241 template<class M, class X, class S, class P, class K, class A>
    \n-
    242 template<class C>
    \n-
    243 KAMG<M,X,S,P,K,A>::KAMG(const Operator& fineOperator, const C& criterion,
    \n-
    244 const SmootherArgs& smootherArgs,
    \n-
    245 std::size_t ksteps, double reduction,
    \n-
    246 const ParallelInformation& pinfo)
    \n-
    247 : amg(fineOperator, criterion, smootherArgs, pinfo),
    \n-
    248 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
    \n-
    249 {}
    \n-
    250
    \n-
    251
    \n-
    252 template<class M, class X, class S, class P, class K, class A>
    \n-\n-
    254 {
    \n-
    255 amg.pre(x,b);
    \n-
    256 scalarproducts.reserve(amg.levels());
    \n-
    257 ksolvers.reserve(amg.levels());
    \n-
    258
    \n-
    259 typename OperatorHierarchy::ParallelMatrixHierarchy::Iterator
    \n-
    260 matrix = amg.matrices_->matrices().coarsest();
    \n-\n-
    262 pinfo = amg.matrices_->parallelInformation().coarsest();
    \n-
    263 bool hasCoarsest=(amg.levels()==amg.maxlevels());
    \n-
    264
    \n-
    265 if(hasCoarsest) {
    \n-
    266 if(matrix==amg.matrices_->matrices().finest())
    \n-
    267 return;
    \n-
    268 --matrix;
    \n-
    269 --pinfo;
    \n-
    270 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, amg.solver_)));
    \n-
    271 }else
    \n-
    272 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, std::shared_ptr<InverseOperator<Domain,Range> >())));
    \n-
    273
    \n-
    274 std::ostringstream s;
    \n-
    275
    \n-
    276 if(matrix!=amg.matrices_->matrices().finest())
    \n-
    277 while(true) {
    \n-
    278 scalarproducts.push_back(createScalarProduct<X>(*pinfo,category()));
    \n-
    279 std::shared_ptr<InverseOperator<Domain,Range> > ks =
    \n-
    280 std::shared_ptr<InverseOperator<Domain,Range> >(new KrylovSolver(*matrix, *(scalarproducts.back()),
    \n-
    281 *(ksolvers.back()), levelDefectReduction,
    \n-
    282 maxLevelKrylovSteps, 0));
    \n-
    283 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, ks)));
    \n-
    284 --matrix;
    \n-
    285 --pinfo;
    \n-
    286 if(matrix==amg.matrices_->matrices().finest())
    \n-
    287 break;
    \n-
    288 }
    \n-
    289 }
    \n-
    290
    \n-
    291
    \n-
    292 template<class M, class X, class S, class P, class K, class A>
    \n-\n-
    294 {
    \n-
    295 amg.post(x);
    \n-
    296
    \n-
    297 }
    \n-
    298
    \n-
    299 template<class M, class X, class S, class P, class K, class A>
    \n-\n-
    301 {
    \n-
    302 if(ksolvers.size()==0)
    \n-
    303 {
    \n-
    304 Range td=d;
    \n-\n-
    306 amg.solver_->apply(v,td,res);
    \n-
    307 }else
    \n-
    308 {
    \n-
    309 typedef typename Amg::LevelContext LevelContext;
    \n-
    310 std::shared_ptr<LevelContext> levelContext(new LevelContext);
    \n-
    311 amg.initIteratorsWithFineLevel(*levelContext);
    \n-
    312 typedef typename std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > >::iterator Iter;
    \n-
    313 for(Iter solver=ksolvers.begin(); solver!=ksolvers.end(); ++solver)
    \n-
    314 (*solver)->setLevelContext(levelContext);
    \n-
    315 ksolvers.back()->apply(v,d);
    \n-
    316 }
    \n-
    317 }
    \n-
    318
    \n-
    319 template<class M, class X, class S, class P, class K, class A>
    \n-\n-
    321 {
    \n-
    322 return amg.maxlevels();
    \n-
    323 }
    \n-
    324
    \n-
    326 } // Amg
    \n-
    327} // Dune
    \n-
    328
    \n-
    329#endif
    \n-
    Define general preconditioner interface.
    \n-
    The AMG preconditioner.
    \n-
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: kamg.hh:300
    \n-
    X Domain
    The domain type.
    Definition: amg.hh:87
    \n-
    KAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms, std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1)
    Construct a new amg with a specific coarse solver.
    Definition: kamg.hh:233
    \n-
    std::size_t maxlevels()
    Definition: kamg.hh:320
    \n-
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n-
    M Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n-
    void post(Domain &x)
    Clean up.
    Definition: kamg.hh:293
    \n-
    X Range
    The range type.
    Definition: amg.hh:89
    \n-
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n-
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n-
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: kamg.hh:253
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: amg.hh:194
    \n-
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: amg.hh:80
    \n+
    171 template<class V, class V1, class T1, class T2>
    \n+
    172 template<typename T3>
    \n+\n+
    174 const AggregatesMap<Vertex>& aggregates,
    \n+
    175 Vector& coarse, Vector& fine, T3 damp,
    \n+
    176 [[maybe_unused]] OwnerOverlapCopyCommunication<T1,T2>& comm)
    \n+
    177 {
    \n+
    178 Transfer<V,V1,SequentialInformation>::prolongateVector(aggregates, coarse, fine, damp);
    \n+
    179 }
    \n+
    180 template<class V, class V1, class T1, class T2>
    \n+
    181 inline void Transfer<V,V1,OwnerOverlapCopyCommunication<T1,T2> >::restrictVector(const AggregatesMap<Vertex>& aggregates,
    \n+
    182 Vector& coarse, const Vector& fine,
    \n+\n+
    184 {
    \n+\n+
    186 // We need this here to avoid it in the smoothers on the coarse level.
    \n+
    187 // There (in the preconditioner d is const.
    \n+
    188 comm.project(coarse);
    \n+
    189 }
    \n+
    190#endif
    \n+
    192 } // namspace Amg
    \n+
    193} // namspace Dune
    \n+
    194#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Functionality for redistributing a sparse matrix.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+
    Provides classes for the Coloring process of AMG.
    \n+\n
    Definition: allocator.hh:11
    \n-
    an algebraic multigrid method using a Krylov-cycle.
    Definition: kamg.hh:140
    \n-
    Amg::Domain Domain
    the type of the domain.
    Definition: kamg.hh:157
    \n-
    Amg::SmootherArgs SmootherArgs
    The type of the arguments for construction of the smoothers.
    Definition: kamg.hh:153
    \n-
    Amg::ParallelInformation ParallelInformation
    the type of the parallelinformation to use.
    Definition: kamg.hh:151
    \n-
    Amg::CoarseSolver CoarseSolver
    The type of the coarse solver.
    Definition: kamg.hh:149
    \n-
    Amg::OperatorHierarchy OperatorHierarchy
    The type of the hierarchy of operators.
    Definition: kamg.hh:147
    \n-
    Amg::Range Range
    The type of the range.
    Definition: kamg.hh:159
    \n-
    Amg::ScalarProduct ScalarProduct
    The type of the scalar product.
    Definition: kamg.hh:163
    \n-
    AMG< M, X, S, PI, A > Amg
    The type of the underlying AMG.
    Definition: kamg.hh:143
    \n-
    Amg::Operator Operator
    the type of the lineatr operator.
    Definition: kamg.hh:155
    \n-
    Amg::ParallelInformationHierarchy ParallelInformationHierarchy
    The type of the hierarchy of parallel information.
    Definition: kamg.hh:161
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: kamg.hh:166
    \n-
    K KrylovSolver
    The type of the Krylov solver for the cycle.
    Definition: kamg.hh:145
    \n-
    Two grid operator for AMG with Krylov cycle.
    Definition: kamg.hh:33
    \n-
    void pre(typename AMG::Domain &x, typename AMG::Range &b)
    Prepare the preconditioner.
    Definition: kamg.hh:58
    \n-
    KAmgTwoGrid(AMG &amg, std::shared_ptr< InverseOperator< Domain, Range > > coarseSolver)
    Constructor.
    Definition: kamg.hh:53
    \n-
    ~KAmgTwoGrid()
    Destructor.
    Definition: kamg.hh:110
    \n-
    void post(typename AMG::Domain &x)
    Clean up.
    Definition: kamg.hh:62
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: kamg.hh:41
    \n-
    void setLevelContext(std::shared_ptr< typename AMG::LevelContext > p)
    Set the level context pointer.
    Definition: kamg.hh:104
    \n-
    InverseOperator< Domain, Range > * coarseSolver()
    Get a pointer to the coarse grid solver.
    Definition: kamg.hh:95
    \n-
    void apply(typename AMG::Domain &v, const typename AMG::Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: kamg.hh:66
    \n-
    Parallel algebraic multigrid based on agglomeration.
    Definition: amg.hh:65
    \n-\n-
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n-
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-\n-
    Category
    Definition: solvercategory.hh:23
    \n-
    Generalized preconditioned conjugate gradient solver.
    Definition: solvers.hh:1307
    \n+
    Definition: matrixredistribute.hh:22
    \n+
    void redistributeBackward(D &from, const D &to) const
    Definition: matrixredistribute.hh:32
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    void project(T1 &x) const
    Set vector to zero at copy dofs.
    Definition: owneroverlapcopy.hh:538
    \n+
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n+\n+
    Definition: pinfo.hh:28
    \n+
    Definition: transfer.hh:32
    \n+
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, T1 damp)
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n+
    V1 Vertex
    Definition: transfer.hh:35
    \n+
    V2 Vector
    Definition: transfer.hh:36
    \n+
    RedistributeInformation< SequentialInformation > Redist
    Definition: transfer.hh:56
    \n+\n+\n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, const SequentialInformation &comm=SequentialInformation(), const Redist &redist=Redist())
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, T1 damp, const SequentialInformation &comm=SequentialInformation())
    \n+\n+
    RedistributeInformation< OwnerOverlapCopyCommunication< T1, T2 > > Redist
    Definition: transfer.hh:80
    \n+\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,432 +5,290 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-kamg.hh\n+transfer.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_KAMG_HH\n- 6#define DUNE_AMG_KAMG_HH\n+ 5#ifndef DUNE_AMGTRANSFER_HH\n+ 6#define DUNE_AMGTRANSFER_HH\n 7\n- 8#include \n- 9#include \"amg.hh\"\n- 10\n- 11namespace Dune\n- 12{\n- 13 namespace Amg\n- 14 {\n- 15\n- 30 template\n-31 class KAmgTwoGrid\n- 32 : public Preconditioner\n- 33 {\n- 35 typedef typename AMG::Domain Domain;\n- 37 typedef typename AMG::Range Range;\n- 38 public:\n- 39\n-41 virtual SolverCategory::Category category() const\n- 42 {\n- 43 return amg_.category();\n- 44 };\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14\n+ 15namespace Dune\n+ 16{\n+ 17 namespace Amg\n+ 18 {\n+ 19\n+ 30 template\n+31 class Transfer\n+ 32 {\n+ 33\n+ 34 public:\n+35 typedef V1 Vertex;\n+36 typedef V2 Vector;\n+ 37\n+ 38 template\n+39 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 40 Vector& fineRedist,T1 damp, R& redistributor=R());\n+ 41\n+ 42 template\n+43 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 44 T1 damp);\n 45\n-53 KAmgTwoGrid(AMG& amg, std::shared_ptr >\n-coarseSolver)\n- 54 : amg_(amg), coarseSolver_(coarseSolver)\n- 55 {}\n- 56\n-58 void pre([[maybe_unused]] typename AMG::Domain& x, [[maybe_unused]] typename\n-AMG::Range& b)\n- 59 {}\n- 60\n-62 void post([[maybe_unused]] typename AMG::Domain& x)\n- 63 {}\n- 64\n-66 void apply(typename AMG::Domain& v, const typename AMG::Range& d)\n- 67 {\n- 68 // Copy data\n- 69 *levelContext_->update=0;\n- 70 *levelContext_->rhs = d;\n- 71 *levelContext_->lhs = v;\n- 72\n- 73 presmooth(*levelContext_, amg_.preSteps_);\n- 74 bool processFineLevel =\n- 75 amg_.moveToCoarseLevel(*levelContext_);\n- 76\n- 77 if(processFineLevel) {\n- 78 typename AMG::Range b=*levelContext_->rhs;\n- 79 typename AMG::Domain x=*levelContext_->update;\n- 80 InverseOperatorResult res;\n- 81 coarseSolver_->apply(x, b, res);\n- 82 *levelContext_->update=x;\n- 83 }\n- 84\n- 85 amg_.moveToFineLevel(*levelContext_, processFineLevel);\n- 86\n- 87 postsmooth(*levelContext_, amg_.postSteps_);\n- 88 v=*levelContext_->update;\n- 89 }\n- 90\n-95 InverseOperator* coarseSolver()\n- 96 {\n- 97 return coarseSolver_;\n- 98 }\n- 99\n-104 void setLevelContext(std::shared_ptr p)\n- 105 {\n- 106 levelContext_=p;\n- 107 }\n- 108\n-110 ~KAmgTwoGrid()\n- 111 {}\n- 112\n- 113 private:\n- 115 AMG& amg_;\n- 117 std::shared_ptr > coarseSolver_;\n- 119 std::shared_ptr levelContext_;\n- 120 };\n- 121\n- 122\n+46 static void restrictVector(const AggregatesMap& aggregates, Vector&\n+coarse, const Vector& fine,\n+ 47 T& comm);\n+ 48 };\n+ 49\n+ 50 template\n+51 class Transfer\n+ 52 {\n+ 53 public:\n+54 typedef V Vertex;\n+55 typedef V1 Vector;\n+56 typedef RedistributeInformation Redist;\n+ 57 template\n+58 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 59 Vector& fineRedist, T1 damp,\n+ 60 const SequentialInformation& comm=SequentialInformation(),\n+ 61 const Redist& redist=Redist());\n+ 62 template\n+63 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 64 T1 damp,\n+ 65 const SequentialInformation& comm=SequentialInformation());\n+ 66\n+ 67\n+ 68 static void restrictVector(const AggregatesMap& aggregates, Vector&\n+coarse, const Vector& fine,\n+ 69 const SequentialInformation& comm);\n+ 70 };\n+ 71\n+ 72#if HAVE_MPI\n+ 73\n+ 74 template\n+75 class Transfer >\n+ 76 {\n+ 77 public:\n+78 typedef V Vertex;\n+79 typedef V1 Vector;\n+80 typedef RedistributeInformation >\n+Redist;\n+ 81 template\n+ 82 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 83 Vector& fineRedist, T3 damp, OwnerOverlapCopyCommunication& comm,\n+ 84 const Redist& redist);\n+ 85 template\n+ 86 static void prolongateVector(const AggregatesMap& aggregates,\n+Vector& coarse, Vector& fine,\n+ 87 T3 damp, OwnerOverlapCopyCommunication& comm);\n+ 88\n+ 89 static void restrictVector(const AggregatesMap& aggregates, Vector&\n+coarse, const Vector& fine,\n+ 90 OwnerOverlapCopyCommunication& comm);\n+ 91 };\n+ 92\n+ 93#endif\n+ 94\n+ 95 template\n+ 96 template\n+ 97 inline void\n+98 Transfer::prolongateVector(const\n+AggregatesMap& aggregates,\n+ 99 Vector& coarse, Vector& fine,\n+ 100 [[maybe_unused]] Vector& fineRedist,\n+ 101 T damp,\n+ 102 [[maybe_unused]] const SequentialInformation& comm,\n+ 103 [[maybe_unused]] const Redist& redist)\n+ 104 {\n+ 105 prolongateVector(aggregates, coarse, fine, damp);\n+ 106 }\n+ 107 template\n+ 108 template\n+ 109 inline void\n+110 Transfer::prolongateVector(const\n+AggregatesMap& aggregates,\n+ 111 Vector& coarse, Vector& fine,\n+ 112 T damp,\n+ 113 [[maybe_unused]] const SequentialInformation& comm)\n+ 114 {\n+ 115 typedef typename Vector::iterator Iterator;\n+ 116\n+ 117 Iterator end = coarse.end();\n+ 118 Iterator begin= coarse.begin();\n+ 119 for(; begin!=end; ++begin)\n+ 120 *begin*=damp;\n+ 121 end=fine.end();\n+ 122 begin=fine.begin();\n 123\n- 137 template, class A=std::allocator >\n-139 class KAMG : public Preconditioner\n- 140 {\n- 141 public:\n-143 typedef AMG Amg;\n-145 typedef K KrylovSolver;\n-147 typedef typename Amg::OperatorHierarchy OperatorHierarchy;\n-149 typedef typename Amg::CoarseSolver CoarseSolver;\n-151 typedef typename Amg::ParallelInformation ParallelInformation;\n-153 typedef typename Amg::SmootherArgs SmootherArgs;\n-155 typedef typename Amg::Operator Operator;\n-157 typedef typename Amg::Domain Domain;\n-159 typedef typename Amg::Range Range;\n-161 typedef typename Amg::ParallelInformationHierarchy\n-ParallelInformationHierarchy;\n-163 typedef typename Amg::ScalarProduct ScalarProduct;\n- 164\n-166 virtual SolverCategory::Category category() const\n- 167 {\n- 168 return amg.category();\n- 169 };\n+ 124 for(Iterator block=begin; block != end; ++block) {\n+ 125 std::ptrdiff_t index=block-begin;\n+ 126 const Vertex& vertex = aggregates[index];\n+ 127 if(vertex != AggregatesMap::ISOLATED)\n+ 128 *block += coarse[aggregates[index]];\n+ 129 }\n+ 130 }\n+ 131\n+ 132 template\n+ 133 inline void\n+134 Transfer::restrictVector(const\n+AggregatesMap& aggregates,\n+ 135 Vector& coarse,\n+ 136 const Vector& fine,\n+ 137 [[maybe_unused]] const SequentialInformation& comm)\n+ 138 {\n+ 139 // Set coarse vector to zero\n+ 140 coarse=0;\n+ 141\n+ 142 typedef typename Vector::const_iterator Iterator;\n+ 143 Iterator end = fine.end();\n+ 144 Iterator begin=fine.begin();\n+ 145\n+ 146 for(Iterator block=begin; block != end; ++block) {\n+ 147 const Vertex& vertex = aggregates[block-begin];\n+ 148 if(vertex != AggregatesMap::ISOLATED)\n+ 149 coarse[vertex] += *block;\n+ 150 }\n+ 151 }\n+ 152\n+ 153#if HAVE_MPI\n+ 154 template\n+ 155 template\n+156 inline void Transfer >::\n+prolongateVector(const AggregatesMap& aggregates,\n+ 157 Vector& coarse, Vector& fine,\n+ 158 Vector& fineRedist, T3 damp,\n+ 159 OwnerOverlapCopyCommunication& comm,\n+ 160 const Redist& redist)\n+ 161 {\n+ 162 if(fineRedist.size()>0)\n+ 163 // we operated on the coarse level\n+ 164 Transfer::prolongateVector(aggregates, coarse,\n+fineRedist, damp);\n+ 165\n+ 166 // TODO This could be accomplished with one communication, too!\n+ 167 redist.redistributeBackward(fine, fineRedist);\n+ 168 comm.copyOwnerToAll(fine,fine);\n+ 169 }\n 170\n- 182 KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n- 183 const SmootherArgs& smootherArgs, const Parameters& parms,\n- 184 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1);\n- 185\n- 199 template\n- 200 KAMG(const Operator& fineOperator, const C& criterion,\n- 201 const SmootherArgs& smootherArgs=SmootherArgs(),\n- 202 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1,\n- 203 const ParallelInformation& pinfo=ParallelInformation());\n- 204\n- 206 void pre(Domain& x, Range& b);\n- 208 void post(Domain& x);\n- 210 void apply(Domain& v, const Range& d);\n- 211\n- 212 std::size_t maxlevels();\n- 213\n- 214 private:\n- 216 Amg amg;\n- 217\n- 219 std::size_t maxLevelKrylovSteps;\n- 220\n- 222 double levelDefectReduction;\n- 223\n- 225 std::vector > scalarproducts;\n- 226\n- 228 std::vector > > ksolvers;\n- 229 };\n- 230\n- 231\n- 232 template\n-233 KAMG::KAMG(OperatorHierarchy& matrices, CoarseSolver&\n-coarseSolver,\n- 234 const SmootherArgs& smootherArgs, const Parameters& params,\n- 235 std::size_t ksteps, double reduction)\n- 236 : amg(matrices, coarseSolver, smootherArgs, params),\n- 237 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)\n- 238 {}\n- 239\n- 240\n- 241 template\n- 242 template\n-243 KAMG::KAMG(const Operator& fineOperator, const C& criterion,\n- 244 const SmootherArgs& smootherArgs,\n- 245 std::size_t ksteps, double reduction,\n- 246 const ParallelInformation& pinfo)\n- 247 : amg(fineOperator, criterion, smootherArgs, pinfo),\n- 248 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)\n- 249 {}\n- 250\n- 251\n- 252 template\n-253 void KAMG::pre(Domain& x, Range& b)\n- 254 {\n- 255 amg.pre(x,b);\n- 256 scalarproducts.reserve(amg.levels());\n- 257 ksolvers.reserve(amg.levels());\n- 258\n- 259 typename OperatorHierarchy::ParallelMatrixHierarchy::Iterator\n- 260 matrix = amg.matrices_->matrices().coarsest();\n- 261 typename ParallelInformationHierarchy::Iterator\n- 262 pinfo = amg.matrices_->parallelInformation().coarsest();\n- 263 bool hasCoarsest=(amg.levels()==amg.maxlevels());\n- 264\n- 265 if(hasCoarsest) {\n- 266 if(matrix==amg.matrices_->matrices().finest())\n- 267 return;\n- 268 --matrix;\n- 269 --pinfo;\n- 270 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n-(amg, amg.solver_)));\n- 271 }else\n- 272 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n-(amg, std::shared_ptr >())));\n- 273\n- 274 std::ostringstream s;\n- 275\n- 276 if(matrix!=amg.matrices_->matrices().finest())\n- 277 while(true) {\n- 278 scalarproducts.push_back(createScalarProduct(*pinfo,category()));\n- 279 std::shared_ptr > ks =\n- 280 std::shared_ptr >(new KrylovSolver(*matrix,\n-*(scalarproducts.back()),\n- 281 *(ksolvers.back()), levelDefectReduction,\n- 282 maxLevelKrylovSteps, 0));\n- 283 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n-(amg, ks)));\n- 284 --matrix;\n- 285 --pinfo;\n- 286 if(matrix==amg.matrices_->matrices().finest())\n- 287 break;\n- 288 }\n- 289 }\n- 290\n- 291\n- 292 template\n-293 void KAMG::post(Domain& x)\n- 294 {\n- 295 amg.post(x);\n- 296\n- 297 }\n- 298\n- 299 template\n-300 void KAMG::apply(Domain& v, const Range& d)\n- 301 {\n- 302 if(ksolvers.size()==0)\n- 303 {\n- 304 Range td=d;\n- 305 InverseOperatorResult res;\n- 306 amg.solver_->apply(v,td,res);\n- 307 }else\n- 308 {\n- 309 typedef typename Amg::LevelContext LevelContext;\n- 310 std::shared_ptr levelContext(new LevelContext);\n- 311 amg.initIteratorsWithFineLevel(*levelContext);\n- 312 typedef typename std::vector > >::\n-iterator Iter;\n- 313 for(Iter solver=ksolvers.begin(); solver!=ksolvers.end(); ++solver)\n- 314 (*solver)->setLevelContext(levelContext);\n- 315 ksolvers.back()->apply(v,d);\n- 316 }\n- 317 }\n- 318\n- 319 template\n-320 std::size_t KAMG::maxlevels()\n- 321 {\n- 322 return amg.maxlevels();\n- 323 }\n- 324\n- 326 } // Amg\n- 327} // Dune\n- 328\n- 329#endif\n-preconditioners.hh\n-Define general preconditioner interface.\n-amg.hh\n-The AMG preconditioner.\n-Dune::Amg::KAMG::apply\n-void apply(Domain &v, const Range &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: kamg.hh:300\n-Dune::Amg::AMG::Domain\n-X Domain\n-The domain type.\n-Definition: amg.hh:87\n-Dune::Amg::KAMG::KAMG\n-KAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const\n-SmootherArgs &smootherArgs, const Parameters &parms, std::size_t\n-maxLevelKrylovSteps=3, double minDefectReduction=1e-1)\n-Construct a new amg with a specific coarse solver.\n-Definition: kamg.hh:233\n-Dune::Amg::KAMG::maxlevels\n-std::size_t maxlevels()\n-Definition: kamg.hh:320\n-Dune::Amg::AMG::SmootherArgs\n-SmootherTraits< Smoother >::Arguments SmootherArgs\n-The argument type for the construction of the smoother.\n-Definition: amg.hh:100\n-Dune::Amg::AMG::Operator\n-M Operator\n-The matrix operator type.\n-Definition: amg.hh:73\n-Dune::Amg::KAMG::post\n-void post(Domain &x)\n-Clean up.\n-Definition: kamg.hh:293\n-Dune::Amg::AMG::Range\n-X Range\n-The range type.\n-Definition: amg.hh:89\n-Dune::Amg::presmooth\n-void presmooth(LevelContext &levelContext, size_t steps)\n-Apply pre smoothing on the current level.\n-Definition: smoother.hh:406\n-Dune::Amg::postsmooth\n-void postsmooth(LevelContext &levelContext, size_t steps)\n-Apply post smoothing on the current level.\n-Definition: smoother.hh:428\n-Dune::Amg::KAMG::pre\n-void pre(Domain &x, Range &b)\n-Prepare the preconditioner.\n-Definition: kamg.hh:253\n-Dune::Amg::AMG::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: amg.hh:194\n-Dune::Amg::AMG::ParallelInformation\n-PI ParallelInformation\n-The type of the parallel information. Either OwnerOverlapCommunication or\n-another type describing the...\n-Definition: amg.hh:80\n+ 171 template\n+ 172 template\n+173 inline void Transfer >::\n+prolongateVector(\n+ 174 const AggregatesMap& aggregates,\n+ 175 Vector& coarse, Vector& fine, T3 damp,\n+ 176 [[maybe_unused]] OwnerOverlapCopyCommunication& comm)\n+ 177 {\n+ 178 Transfer::prolongateVector(aggregates, coarse,\n+fine, damp);\n+ 179 }\n+ 180 template\n+181 inline void Transfer >::\n+restrictVector(const AggregatesMap& aggregates,\n+ 182 Vector& coarse, const Vector& fine,\n+ 183 OwnerOverlapCopyCommunication& comm)\n+ 184 {\n+ 185 Transfer::restrictVector(aggregates, coarse,\n+fine, SequentialInformation());\n+ 186 // We need this here to avoid it in the smoothers on the coarse level.\n+ 187 // There (in the preconditioner d is const.\n+ 188 comm.project(coarse);\n+ 189 }\n+ 190#endif\n+ 192 } // namspace Amg\n+ 193} // namspace Dune\n+ 194#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+matrixredistribute.hh\n+Functionality for redistributing a sparse matrix.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+aggregates.hh\n+Provides classes for the Coloring process of AMG.\n+pinfo.hh\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::KAMG\n-an algebraic multigrid method using a Krylov-cycle.\n-Definition: kamg.hh:140\n-Dune::Amg::KAMG::Domain\n-Amg::Domain Domain\n-the type of the domain.\n-Definition: kamg.hh:157\n-Dune::Amg::KAMG::SmootherArgs\n-Amg::SmootherArgs SmootherArgs\n-The type of the arguments for construction of the smoothers.\n-Definition: kamg.hh:153\n-Dune::Amg::KAMG::ParallelInformation\n-Amg::ParallelInformation ParallelInformation\n-the type of the parallelinformation to use.\n-Definition: kamg.hh:151\n-Dune::Amg::KAMG::CoarseSolver\n-Amg::CoarseSolver CoarseSolver\n-The type of the coarse solver.\n-Definition: kamg.hh:149\n-Dune::Amg::KAMG::OperatorHierarchy\n-Amg::OperatorHierarchy OperatorHierarchy\n-The type of the hierarchy of operators.\n-Definition: kamg.hh:147\n-Dune::Amg::KAMG::Range\n-Amg::Range Range\n-The type of the range.\n-Definition: kamg.hh:159\n-Dune::Amg::KAMG::ScalarProduct\n-Amg::ScalarProduct ScalarProduct\n-The type of the scalar product.\n-Definition: kamg.hh:163\n-Dune::Amg::KAMG::Amg\n-AMG< M, X, S, PI, A > Amg\n-The type of the underlying AMG.\n-Definition: kamg.hh:143\n-Dune::Amg::KAMG::Operator\n-Amg::Operator Operator\n-the type of the lineatr operator.\n-Definition: kamg.hh:155\n-Dune::Amg::KAMG::ParallelInformationHierarchy\n-Amg::ParallelInformationHierarchy ParallelInformationHierarchy\n-The type of the hierarchy of parallel information.\n-Definition: kamg.hh:161\n-Dune::Amg::KAMG::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: kamg.hh:166\n-Dune::Amg::KAMG::KrylovSolver\n-K KrylovSolver\n-The type of the Krylov solver for the cycle.\n-Definition: kamg.hh:145\n-Dune::Amg::KAmgTwoGrid\n-Two grid operator for AMG with Krylov cycle.\n-Definition: kamg.hh:33\n-Dune::Amg::KAmgTwoGrid::pre\n-void pre(typename AMG::Domain &x, typename AMG::Range &b)\n-Prepare the preconditioner.\n-Definition: kamg.hh:58\n-Dune::Amg::KAmgTwoGrid::KAmgTwoGrid\n-KAmgTwoGrid(AMG &amg, std::shared_ptr< InverseOperator< Domain, Range > >\n-coarseSolver)\n-Constructor.\n-Definition: kamg.hh:53\n-Dune::Amg::KAmgTwoGrid::~KAmgTwoGrid\n-~KAmgTwoGrid()\n-Destructor.\n-Definition: kamg.hh:110\n-Dune::Amg::KAmgTwoGrid::post\n-void post(typename AMG::Domain &x)\n-Clean up.\n-Definition: kamg.hh:62\n-Dune::Amg::KAmgTwoGrid::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: kamg.hh:41\n-Dune::Amg::KAmgTwoGrid::setLevelContext\n-void setLevelContext(std::shared_ptr< typename AMG::LevelContext > p)\n-Set the level context pointer.\n-Definition: kamg.hh:104\n-Dune::Amg::KAmgTwoGrid::coarseSolver\n-InverseOperator< Domain, Range > * coarseSolver()\n-Get a pointer to the coarse grid solver.\n-Definition: kamg.hh:95\n-Dune::Amg::KAmgTwoGrid::apply\n-void apply(typename AMG::Domain &v, const typename AMG::Range &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: kamg.hh:66\n-Dune::Amg::AMG\n-Parallel algebraic multigrid based on agglomeration.\n-Definition: amg.hh:65\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n-Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n-LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n-> Iterator\n-Type of the mutable iterator.\n-Definition: hierarchy.hh:216\n-Dune::Amg::MatrixHierarchy\n-The hierarchies build by the coarsening process.\n-Definition: matrixhierarchy.hh:61\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::ScalarProduct\n-Base class for scalar product and norm computation.\n-Definition: scalarproducts.hh:52\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperator<_Domain,_Range_>\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::GeneralizedPCGSolver\n-Generalized preconditioned conjugate gradient solver.\n-Definition: solvers.hh:1307\n+Dune::RedistributeInformation\n+Definition: matrixredistribute.hh:22\n+Dune::RedistributeInformation::redistributeBackward\n+void redistributeBackward(D &from, const D &to) const\n+Definition: matrixredistribute.hh:32\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::project\n+void project(T1 &x) const\n+Set vector to zero at copy dofs.\n+Definition: owneroverlapcopy.hh:538\n+Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n+void copyOwnerToAll(const T &source, T &dest) const\n+Communicate values from owner data points to all other data points.\n+Definition: owneroverlapcopy.hh:311\n+Dune::Amg::AggregatesMap<_Vertex_>\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::Amg::Transfer\n+Definition: transfer.hh:32\n+Dune::Amg::Transfer::restrictVector\n+static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, const Vector &fine, T &comm)\n+Dune::Amg::Transfer::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, T1 damp)\n+Dune::Amg::Transfer::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n+Dune::Amg::Transfer::Vertex\n+V1 Vertex\n+Definition: transfer.hh:35\n+Dune::Amg::Transfer::Vector\n+V2 Vector\n+Definition: transfer.hh:36\n+Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Redist\n+RedistributeInformation< SequentialInformation > Redist\n+Definition: transfer.hh:56\n+Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Vertex\n+V Vertex\n+Definition: transfer.hh:54\n+Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::Vector\n+V1 Vector\n+Definition: transfer.hh:55\n+Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, Vector &fineRedist, T1 damp, const SequentialInformation\n+&comm=SequentialInformation(), const Redist &redist=Redist())\n+Dune::Amg::Transfer<_V,_V1,_SequentialInformation_>::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, T1 damp, const SequentialInformation\n+&comm=SequentialInformation())\n+Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Vertex\n+V Vertex\n+Definition: transfer.hh:78\n+Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Redist\n+RedistributeInformation< OwnerOverlapCopyCommunication< T1, T2 > > Redist\n+Definition: transfer.hh:80\n+Dune::Amg::Transfer<_V,_V1,_OwnerOverlapCopyCommunication<_T1,_T2_>_>::Vector\n+V1 Vector\n+Definition: transfer.hh:79\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00149.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00149.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: combinedfunctor.hh File Reference\n+dune-istl: fastamgsmoother.hh File Reference\n \n \n \n \n \n \n \n@@ -65,28 +65,26 @@\n
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    combinedfunctor.hh File Reference
    \n+
    fastamgsmoother.hh File Reference
    \n
    \n
    \n-
    #include <tuple>
    \n+
    #include <cstddef>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n \n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::Amg::ApplyHelper< i >
    struct  Dune::Amg::GaussSeidelPresmoothDefect< level >
     
    struct  Dune::Amg::ApplyHelper< 0 >
     
    class  Dune::Amg::CombinedFunctor< T >
    struct  Dune::Amg::GaussSeidelPostsmoothDefect< level >
     
    \n \n \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -6,23 +6,21 @@\n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n Classes | Namespaces\n-combinedfunctor.hh File Reference\n-#include \n+fastamgsmoother.hh File Reference\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::ApplyHelper<_i_>\n+struct \u00a0Dune::Amg::GaussSeidelPresmoothDefect<_level_>\n \u00a0\n-struct \u00a0Dune::Amg::ApplyHelper<_0_>\n-\u00a0\n- class \u00a0Dune::Amg::CombinedFunctor<_T_>\n+struct \u00a0Dune::Amg::GaussSeidelPostsmoothDefect<_level_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n \n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00149_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00149_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: combinedfunctor.hh Source File\n+dune-istl: fastamgsmoother.hh Source File\n \n \n \n \n \n \n \n@@ -62,77 +62,119 @@\n \n
    \n \n
    \n \n
    \n-
    combinedfunctor.hh
    \n+
    fastamgsmoother.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_COMBINEDFUNCTOR_HH
    \n-
    6#define DUNE_AMG_COMBINEDFUNCTOR_HH
    \n+
    5#ifndef DUNE_ISTL_FASTAMGSMOOTHER_HH
    \n+
    6#define DUNE_ISTL_FASTAMGSMOOTHER_HH
    \n
    7
    \n-
    8#include <tuple>
    \n+
    8#include <cstddef>
    \n
    9
    \n
    10namespace Dune
    \n
    11{
    \n
    12 namespace Amg
    \n
    13 {
    \n
    14
    \n-
    15 template<std::size_t i>
    \n-\n-
    17 {
    \n-
    18 template<class TT, class T>
    \n-
    19 static void apply(TT tuple, const T& t)
    \n-
    20 {
    \n-
    21 std::get<i-1>(tuple) (t);
    \n-\n-
    23 }
    \n-
    24 };
    \n-
    25 template<>
    \n-
    26 struct ApplyHelper<0>
    \n-
    27 {
    \n-
    28 template<class TT, class T>
    \n-
    29 static void apply([[maybe_unused]] TT tuple, [[maybe_unused]] const T& t)
    \n-
    30 {}
    \n-
    31 };
    \n-
    32
    \n-
    33 template<typename T>
    \n-\n-
    35 public T
    \n-
    36 {
    \n-
    37 public:
    \n-
    38 CombinedFunctor(const T& tuple_)
    \n-
    39 : T(tuple_)
    \n-
    40 {}
    \n-
    41
    \n-
    42 template<class T1>
    \n-
    43 void operator()(const T1& t)
    \n-
    44 {
    \n-\n-
    46 }
    \n-
    47 };
    \n-
    48
    \n-
    49
    \n-
    50 } //namespace Amg
    \n-
    51} // namespace Dune
    \n-
    52#endif
    \n+
    15 template<std::size_t level>
    \n+\n+
    17
    \n+
    18 template<typename M, typename X, typename Y>
    \n+
    19 static void apply(const M& A, X& x, Y& d,
    \n+
    20 const Y& b)
    \n+
    21 {
    \n+
    22 typedef typename M::ConstRowIterator RowIterator;
    \n+
    23 typedef typename M::ConstColIterator ColIterator;
    \n+
    24
    \n+
    25 typename Y::iterator dIter=d.begin();
    \n+
    26 typename Y::const_iterator bIter=b.begin();
    \n+
    27 typename X::iterator xIter=x.begin();
    \n+
    28
    \n+
    29 for(RowIterator row=A.begin(), end=A.end(); row != end;
    \n+
    30 ++row, ++dIter, ++xIter, ++bIter)
    \n+
    31 {
    \n+
    32 ColIterator col=(*row).begin();
    \n+
    33 *dIter = *bIter;
    \n+
    34
    \n+
    35 for (; col.index()<row.index(); ++col)
    \n+
    36 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    37 assert(row.index()==col.index());
    \n+
    38 ColIterator diag=col; // upper diagonal matrix not needed as x was 0 before.
    \n+
    39
    \n+
    40 // Not recursive yet. Just solve with the diagonal
    \n+
    41 diag->solve(*xIter,*dIter);
    \n+
    42 *dIter=0; //as r=v
    \n+
    43
    \n+
    44 // Update residual for the symmetric case
    \n+
    45 for(col=(*row).begin(); col.index()<row.index(); ++col)
    \n+
    46 col->mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i
    \n+
    47 }
    \n+
    48 }
    \n+
    49 };
    \n+
    50
    \n+
    51 template<std::size_t level>
    \n+\n+
    53
    \n+
    54 template<typename M, typename X, typename Y>
    \n+
    55 static void apply(const M& A, X& x, Y& d,
    \n+
    56 const Y& b)
    \n+
    57 {
    \n+
    58 typedef typename M::ConstRowIterator RowIterator;
    \n+
    59 typedef typename M::ConstColIterator ColIterator;
    \n+
    60 typedef typename Y::block_type YBlock;
    \n+
    61
    \n+
    62 typename Y::iterator dIter=d.beforeEnd();
    \n+
    63 typename X::iterator xIter=x.beforeEnd();
    \n+
    64 typename Y::const_iterator bIter=b.beforeEnd();
    \n+
    65
    \n+
    66 for(RowIterator row=A.beforeEnd(), end=A.beforeBegin(); row != end;
    \n+
    67 --row, --dIter, --xIter, --bIter)
    \n+
    68 {
    \n+
    69 ColIterator endCol=(*row).beforeBegin();
    \n+
    70 ColIterator col=(*row).beforeEnd();
    \n+
    71 *dIter = *bIter;
    \n+
    72
    \n+
    73 for (; col.index()>row.index(); --col)
    \n+
    74 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{i>j} a_ij * xnew_j
    \n+
    75 assert(row.index()==col.index());
    \n+
    76 ColIterator diag=col;
    \n+
    77 YBlock v=*dIter;
    \n+
    78 // upper diagonal matrix
    \n+
    79 for (--col; col!=endCol; --col)
    \n+
    80 (*col).mmv(x[col.index()],v); // v -= sum_{j<i} a_ij * xold_j
    \n+
    81
    \n+
    82 // Not recursive yet. Just solve with the diagonal
    \n+
    83 diag->solve(*xIter,v);
    \n+
    84
    \n+
    85 *dIter-=v;
    \n+
    86
    \n+
    87 // Update residual for the symmetric case
    \n+
    88 // Skip residual computation as it is not needed.
    \n+
    89 //for(col=(*row).begin();col.index()<row.index(); ++col)
    \n+
    90 //col.mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i
    \n+
    91 }
    \n+
    92 }
    \n+
    93 };
    \n+
    94 } // end namespace Amg
    \n+
    95} // end namespace Dune
    \n+
    96#endif
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    Definition: combinedfunctor.hh:17
    \n-
    static void apply(TT tuple, const T &t)
    Definition: combinedfunctor.hh:19
    \n-
    static void apply(TT tuple, const T &t)
    Definition: combinedfunctor.hh:29
    \n-
    Definition: combinedfunctor.hh:36
    \n-
    CombinedFunctor(const T &tuple_)
    Definition: combinedfunctor.hh:38
    \n-
    void operator()(const T1 &t)
    Definition: combinedfunctor.hh:43
    \n+
    Definition: fastamgsmoother.hh:16
    \n+
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:19
    \n+
    Definition: fastamgsmoother.hh:52
    \n+
    static void apply(const M &A, X &x, Y &d, const Y &b)
    Definition: fastamgsmoother.hh:55
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,88 +5,125 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-combinedfunctor.hh\n+fastamgsmoother.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_COMBINEDFUNCTOR_HH\n- 6#define DUNE_AMG_COMBINEDFUNCTOR_HH\n+ 5#ifndef DUNE_ISTL_FASTAMGSMOOTHER_HH\n+ 6#define DUNE_ISTL_FASTAMGSMOOTHER_HH\n 7\n- 8#include \n+ 8#include \n 9\n 10namespace Dune\n 11{\n 12 namespace Amg\n 13 {\n 14\n- 15 template\n-16 struct ApplyHelper\n- 17 {\n- 18 template\n-19 static void apply(TT tuple, const T& t)\n- 20 {\n- 21 std::get(tuple) (t);\n- 22 ApplyHelper::apply(tuple, t);\n- 23 }\n- 24 };\n- 25 template<>\n-26 struct ApplyHelper<0>\n- 27 {\n- 28 template\n-29 static void apply([[maybe_unused]] TT tuple, [[maybe_unused]] const T& t)\n- 30 {}\n- 31 };\n- 32\n- 33 template\n-34 class CombinedFunctor :\n- 35 public T\n- 36 {\n- 37 public:\n-38 CombinedFunctor(const T& tuple_)\n- 39 : T(tuple_)\n- 40 {}\n- 41\n- 42 template\n-43 void operator()(const T1& t)\n- 44 {\n- 45 ApplyHelper::value>::apply(*this, t);\n- 46 }\n- 47 };\n- 48\n- 49\n- 50 } //namespace Amg\n- 51} // namespace Dune\n- 52#endif\n+ 15 template\n+16 struct GaussSeidelPresmoothDefect {\n+ 17\n+ 18 template\n+19 static void apply(const M& A, X& x, Y& d,\n+ 20 const Y& b)\n+ 21 {\n+ 22 typedef typename M::ConstRowIterator RowIterator;\n+ 23 typedef typename M::ConstColIterator ColIterator;\n+ 24\n+ 25 typename Y::iterator dIter=d.begin();\n+ 26 typename Y::const_iterator bIter=b.begin();\n+ 27 typename X::iterator xIter=x.begin();\n+ 28\n+ 29 for(RowIterator row=A.begin(), end=A.end(); row != end;\n+ 30 ++row, ++dIter, ++xIter, ++bIter)\n+ 31 {\n+ 32 ColIterator col=(*row).begin();\n+ 33 *dIter = *bIter;\n+ 34\n+ 35 for (; col.index()solve(*xIter,*dIter);\n+ 42 *dIter=0; //as r=v\n+ 43\n+ 44 // Update residual for the symmetric case\n+ 45 for(col=(*row).begin(); col.index()mmv(*xIter, d[col.index()]); //d_j-=A_ij x_i\n+ 47 }\n+ 48 }\n+ 49 };\n+ 50\n+ 51 template\n+52 struct GaussSeidelPostsmoothDefect {\n+ 53\n+ 54 template\n+55 static void apply(const M& A, X& x, Y& d,\n+ 56 const Y& b)\n+ 57 {\n+ 58 typedef typename M::ConstRowIterator RowIterator;\n+ 59 typedef typename M::ConstColIterator ColIterator;\n+ 60 typedef typename Y::block_type YBlock;\n+ 61\n+ 62 typename Y::iterator dIter=d.beforeEnd();\n+ 63 typename X::iterator xIter=x.beforeEnd();\n+ 64 typename Y::const_iterator bIter=b.beforeEnd();\n+ 65\n+ 66 for(RowIterator row=A.beforeEnd(), end=A.beforeBegin(); row != end;\n+ 67 --row, --dIter, --xIter, --bIter)\n+ 68 {\n+ 69 ColIterator endCol=(*row).beforeBegin();\n+ 70 ColIterator col=(*row).beforeEnd();\n+ 71 *dIter = *bIter;\n+ 72\n+ 73 for (; col.index()>row.index(); --col)\n+ 74 (*col).mmv(x[col.index()],*dIter); // rhs -= sum_{i>j} a_ij * xnew_j\n+ 75 assert(row.index()==col.index());\n+ 76 ColIterator diag=col;\n+ 77 YBlock v=*dIter;\n+ 78 // upper diagonal matrix\n+ 79 for (--col; col!=endCol; --col)\n+ 80 (*col).mmv(x[col.index()],v); // v -= sum_{jsolve(*xIter,v);\n+ 84\n+ 85 *dIter-=v;\n+ 86\n+ 87 // Update residual for the symmetric case\n+ 88 // Skip residual computation as it is not needed.\n+ 89 //for(col=(*row).begin();col.index() >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::Amg::ApplyHelper\n-Definition: combinedfunctor.hh:17\n-Dune::Amg::ApplyHelper::apply\n-static void apply(TT tuple, const T &t)\n-Definition: combinedfunctor.hh:19\n-Dune::Amg::ApplyHelper<_0_>::apply\n-static void apply(TT tuple, const T &t)\n-Definition: combinedfunctor.hh:29\n-Dune::Amg::CombinedFunctor\n-Definition: combinedfunctor.hh:36\n-Dune::Amg::CombinedFunctor::CombinedFunctor\n-CombinedFunctor(const T &tuple_)\n-Definition: combinedfunctor.hh:38\n-Dune::Amg::CombinedFunctor::operator()\n-void operator()(const T1 &t)\n-Definition: combinedfunctor.hh:43\n+Dune::Amg::GaussSeidelPresmoothDefect\n+Definition: fastamgsmoother.hh:16\n+Dune::Amg::GaussSeidelPresmoothDefect::apply\n+static void apply(const M &A, X &x, Y &d, const Y &b)\n+Definition: fastamgsmoother.hh:19\n+Dune::Amg::GaussSeidelPostsmoothDefect\n+Definition: fastamgsmoother.hh:52\n+Dune::Amg::GaussSeidelPostsmoothDefect::apply\n+static void apply(const M &A, X &x, Y &d, const Y &b)\n+Definition: fastamgsmoother.hh:55\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00152.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00152.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: smoother.hh File Reference\n+dune-istl: twolevelmethod.hh File Reference\n \n \n \n \n \n \n \n@@ -64,119 +64,52 @@\n \n \n \n \n+ \n \n
    \n \n-

    Classes for the generic construction and application of the smoothers. \n+

    Algebraic twolevel methods. \n More...

    \n-
    #include <dune/istl/paamg/construction.hh>
    \n-#include <dune/istl/paamg/aggregates.hh>
    \n-#include <dune/istl/preconditioners.hh>
    \n-#include <dune/istl/schwarz.hh>
    \n-#include <dune/istl/novlpschwarz.hh>
    \n-#include <dune/common/propertymap.hh>
    \n-#include <dune/common/ftraits.hh>
    \n+
    #include <tuple>
    \n+#include <dune/istl/operators.hh>
    \n+#include "amg.hh"
    \n+#include "galerkin.hh"
    \n+#include <dune/istl/solver.hh>
    \n
    \n

    Go to the source code of this file.

    \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::Amg::DefaultSmootherArgs< T >
     The default class for the smoother arguments. More...
    class  Dune::Amg::LevelTransferPolicy< FO, CO >
     Abstract base class for transfer between levels and creation of the coarse level system. More...
     
    struct  Dune::Amg::SmootherTraits< T >
     Traits class for getting the attribute class of a smoother. More...
    class  Dune::Amg::AggregationLevelTransferPolicy< O, C >
     A LeveTransferPolicy that used aggregation to construct the coarse level system. More...
     
    struct  Dune::Amg::SmootherTraits< Richardson< X, Y > >
    class  Dune::Amg::OneStepAMGCoarseSolverPolicy< O, S, C >
     A policy class for solving the coarse level system using one step of AMG. More...
     
    struct  Dune::Amg::SmootherTraits< BlockPreconditioner< X, Y, C, T > >
     
    struct  Dune::Amg::SmootherTraits< NonoverlappingBlockPreconditioner< C, T > >
     
    class  Dune::Amg::DefaultConstructionArgs< T >
     Construction Arguments for the default smoothers. More...
     
    struct  Dune::Amg::ConstructionArgs< T >
     
    class  Dune::Amg::DefaultParallelConstructionArgs< T, C >
     
    class  Dune::Amg::DefaultConstructionArgs< Richardson< X, Y > >
     
    struct  Dune::Amg::ConstructionTraits< SeqSSOR< M, X, Y, l > >
     Policy for the construction of the SeqSSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< SeqSOR< M, X, Y, l > >
     Policy for the construction of the SeqSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< SeqJac< M, X, Y, l > >
     Policy for the construction of the SeqJac smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< Richardson< X, Y > >
     Policy for the construction of the Richardson smoother. More...
     
    class  Dune::Amg::ConstructionArgs< SeqILU< M, X, Y > >
     
    struct  Dune::Amg::ConstructionTraits< SeqILU< M, X, Y > >
     Policy for the construction of the SeqILU smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< ParSSOR< M, X, Y, C > >
     Policy for the construction of the ParSSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< BlockPreconditioner< X, Y, C, T > >
     
    struct  Dune::Amg::ConstructionTraits< NonoverlappingBlockPreconditioner< C, T > >
     
    struct  Dune::Amg::SmootherApplier< T >
     Helper class for applying the smoothers. More...
     
    struct  Dune::Amg::SmootherApplier< SeqSOR< M, X, Y, l > >
     
    struct  Dune::Amg::SmootherApplier< BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > >
     
    struct  Dune::Amg::SmootherApplier< NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > >
     
    struct  Dune::Amg::SmootherApplier< SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > >
     
    struct  Dune::Amg::SeqOverlappingSchwarzSmootherArgs< T >
     
    struct  Dune::Amg::SmootherTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
     
    class  Dune::Amg::ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
     
    struct  Dune::Amg::ConstructionTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
    class  Dune::Amg::TwoLevelMethod< FO, CSP, S >
     
    \n \n \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<typename LevelContext >
    void Dune::Amg::presmooth (LevelContext &levelContext, size_t steps)
     Apply pre smoothing on the current level. More...
     
    template<typename LevelContext >
    void Dune::Amg::postsmooth (LevelContext &levelContext, size_t steps)
     Apply post smoothing on the current level. More...
     
    \n

    Detailed Description

    \n-

    Classes for the generic construction and application of the smoothers.

    \n+

    Algebraic twolevel methods.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,112 +5,45 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces | Functions\n-smoother.hh File Reference\n+Classes | Namespaces\n+twolevelmethod.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n \u00bb Parallel_Algebraic_Multigrid\n-Classes for the generic construction and application of the smoothers. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Algebraic twolevel methods. More...\n+#include \n+#include \n+#include \"amg.hh\"\n+#include \"galerkin.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::DefaultSmootherArgs<_T_>\n-\u00a0 The default class for the smoother arguments. More...\n+class \u00a0Dune::Amg::LevelTransferPolicy<_FO,_CO_>\n+\u00a0 Abstract base class for transfer between levels and creation of the\n+ coarse level system. More...\n+\u00a0\n+class \u00a0Dune::Amg::AggregationLevelTransferPolicy<_O,_C_>\n+\u00a0 A LeveTransferPolicy that used aggregation to construct the coarse\n+ level system. More...\n+\u00a0\n+class \u00a0Dune::Amg::OneStepAMGCoarseSolverPolicy<_O,_S,_C_>\n+\u00a0 A policy class for solving the coarse level system using one step of\n+ AMG. More...\n \u00a0\n-struct \u00a0Dune::Amg::SmootherTraits<_T_>\n-\u00a0 Traits class for getting the attribute class of a smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherTraits<_Richardson<_X,_Y_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>\n-\u00a0\n- class \u00a0Dune::Amg::DefaultConstructionArgs<_T_>\n-\u00a0 Construction Arguments for the default smoothers. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionArgs<_T_>\n-\u00a0\n- class \u00a0Dune::Amg::DefaultParallelConstructionArgs<_T,_C_>\n-\u00a0\n- class \u00a0Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>\n-\u00a0 Policy for the construction of the SeqSSOR smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>\n-\u00a0 Policy for the construction of the SeqSOR smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>\n-\u00a0 Policy for the construction of the SeqJac smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>\n-\u00a0 Policy for the construction of the Richardson smoother. More...\n-\u00a0\n- class \u00a0Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>\n-\u00a0 Policy for the construction of the SeqILU smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>\n-\u00a0 Policy for the construction of the ParSSOR smoother. More...\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T\n- >_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherApplier<_T_>\n-\u00a0 Helper class for applying the smoothers. More...\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,\n- X,_Y,_l_>_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,\n- SeqSOR<_M,_X,_Y,_l_>_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n- MultiplicativeSchwarzMode,_MS,_TA_>_>\n-\u00a0\n-struct \u00a0Dune::Amg::SeqOverlappingSchwarzSmootherArgs<_T_>\n-\u00a0\n-struct \u00a0Dune::Amg::SmootherTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>\n-\u00a0\n- class \u00a0Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>\n- >\n-\u00a0\n-struct \u00a0Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA\n- >_>\n+class \u00a0Dune::Amg::TwoLevelMethod<_FO,_CSP,_S_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n- Functions\n-template\n-void\u00a0Dune::Amg::presmooth (LevelContext &levelContext, size_t steps)\n-\u00a0 Apply pre smoothing on the current level. More...\n-\u00a0\n-template\n-void\u00a0Dune::Amg::postsmooth (LevelContext &levelContext, size_t steps)\n-\u00a0 Apply post smoothing on the current level. More...\n-\u00a0\n ***** Detailed Description *****\n-Classes for the generic construction and application of the smoothers.\n+Algebraic twolevel methods.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00152_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00152_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: smoother.hh Source File\n+dune-istl: twolevelmethod.hh Source File\n \n \n \n \n \n \n \n@@ -62,956 +62,435 @@\n \n
    \n \n
    \n
    \n
    \n-
    smoother.hh
    \n+
    twolevelmethod.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMGSMOOTHER_HH
    \n-
    6#define DUNE_AMGSMOOTHER_HH
    \n+
    5#ifndef DUNE_ISTL_TWOLEVELMETHOD_HH
    \n+
    6#define DUNE_ISTL_TWOLEVELMETHOD_HH
    \n
    7
    \n-\n-\n-\n-
    11#include <dune/istl/schwarz.hh>
    \n-\n-
    13#include <dune/common/propertymap.hh>
    \n-
    14#include <dune/common/ftraits.hh>
    \n-
    15
    \n-
    16namespace Dune
    \n-
    17{
    \n-
    18 namespace Amg
    \n-
    19 {
    \n-
    20
    \n-
    36 template<class T>
    \n-\n-
    38 {
    \n-
    42 typedef typename FieldTraits<T>::real_type RelaxationFactor;
    \n-
    43
    \n-\n-\n-
    52
    \n-\n-\n-
    58 {}
    \n-
    59 };
    \n-
    60
    \n-
    64 template<class T>
    \n-\n-
    66 {
    \n-\n-
    68
    \n-
    69 };
    \n-
    70
    \n-
    71 template<class X, class Y>
    \n-\n-
    73 {
    \n-\n-
    75
    \n-
    76 };
    \n-
    77
    \n-
    78 template<class X, class Y, class C, class T>
    \n-\n-
    80 : public SmootherTraits<T>
    \n-
    81 {};
    \n+
    8#include <tuple>
    \n+
    9
    \n+\n+
    11#include"amg.hh"
    \n+
    12#include"galerkin.hh"
    \n+
    13#include<dune/istl/solver.hh>
    \n+
    14
    \n+
    22namespace Dune
    \n+
    23{
    \n+
    24namespace Amg
    \n+
    25{
    \n+
    26
    \n+
    36template<class FO, class CO>
    \n+\n+
    38{
    \n+
    39public:
    \n+
    44 typedef FO FineOperatorType;
    \n+
    48 typedef typename FineOperatorType::range_type FineRangeType;
    \n+
    52 typedef typename FineOperatorType::domain_type FineDomainType;
    \n+\n+
    61 typedef typename CoarseOperatorType::range_type CoarseRangeType;
    \n+
    65 typedef typename CoarseOperatorType::domain_type CoarseDomainType;
    \n+
    70 std::shared_ptr<CoarseOperatorType>& getCoarseLevelOperator()
    \n+
    71 {
    \n+
    72 return operator_;
    \n+
    73 }
    \n+\n+
    79 {
    \n+
    80 return rhs_;
    \n+
    81 }
    \n
    82
    \n-
    83 template<class C, class T>
    \n-\n-
    85 : public SmootherTraits<T>
    \n-
    86 {};
    \n-
    87
    \n-
    91 template<class T>
    \n-\n-
    93 {
    \n-
    94 typedef typename T::matrix_type Matrix;
    \n-
    95
    \n-\n-
    97
    \n-\n-
    99
    \n-
    100 public:
    \n-\n-
    102 {}
    \n-
    103
    \n-
    104 void setMatrix(const Matrix& matrix)
    \n-
    105 {
    \n-
    106 matrix_=&matrix;
    \n-
    107 }
    \n-
    108 virtual void setMatrix(const Matrix& matrix, [[maybe_unused]] const AggregatesMap& amap)
    \n-
    109 {
    \n-
    110 setMatrix(matrix);
    \n-
    111 }
    \n-
    112
    \n-
    113
    \n-
    114 const Matrix& getMatrix() const
    \n-
    115 {
    \n-
    116 return *matrix_;
    \n-
    117 }
    \n-
    118
    \n-
    119 void setArgs(const SmootherArgs& args)
    \n-
    120 {
    \n-
    121 args_=&args;
    \n-
    122 }
    \n-
    123
    \n-
    124 template<class T1>
    \n-
    125 void setComm([[maybe_unused]] T1& comm)
    \n-
    126 {}
    \n-
    127
    \n-\n-
    129 {
    \n-
    130 return comm_;
    \n-
    131 }
    \n-
    132
    \n-
    133 const SmootherArgs getArgs() const
    \n-
    134 {
    \n-
    135 return *args_;
    \n-
    136 }
    \n-
    137
    \n-
    138 protected:
    \n-
    139 const Matrix* matrix_;
    \n-
    140 private:
    \n-
    141 const SmootherArgs* args_;
    \n-\n-
    143 };
    \n-
    144
    \n-
    145 template<class T>
    \n-\n-
    147 : public DefaultConstructionArgs<T>
    \n-
    148 {};
    \n+\n+
    88 {
    \n+
    89 return lhs_;
    \n+
    90 }
    \n+
    100 virtual void moveToCoarseLevel(const FineRangeType& fineRhs)=0;
    \n+
    110 virtual void moveToFineLevel(FineDomainType& fineLhs)=0;
    \n+
    118 virtual void createCoarseLevelSystem(const FineOperatorType& fineOperator)=0;
    \n+
    119
    \n+
    121 virtual LevelTransferPolicy* clone() const =0;
    \n+
    122
    \n+\n+
    125
    \n+
    126 protected:
    \n+\n+\n+
    132 std::shared_ptr<CoarseOperatorType> operator_;
    \n+
    133};
    \n+
    134
    \n+
    140template<class O, class C>
    \n+\n+
    142 : public LevelTransferPolicy<O,O>
    \n+
    143{
    \n+\n+
    145public:
    \n+\n+
    147 typedef C Criterion;
    \n+\n
    149
    \n-
    150 template<class T, class C=SequentialInformation>
    \n-\n-
    152 : public ConstructionArgs<T>
    \n-
    153 {
    \n-
    154 public:
    \n-\n-
    156 {}
    \n-
    157
    \n-
    158 void setComm(const C& comm)
    \n-
    159 {
    \n-
    160 comm_ = &comm;
    \n-
    161 }
    \n-
    162
    \n-
    163 const C& getComm() const
    \n-
    164 {
    \n-
    165 return *comm_;
    \n-
    166 }
    \n-
    167 private:
    \n-
    168 const C* comm_;
    \n-
    169 };
    \n-
    170
    \n-
    171
    \n-
    172 template<class X, class Y>
    \n-\n-
    174 {
    \n-
    175 typedef Richardson<X,Y> T;
    \n-
    176
    \n-\n-
    178
    \n-
    179 public:
    \n-\n-
    181 {}
    \n-
    182
    \n-
    183 template <class... Args>
    \n-
    184 void setMatrix(const Args&...)
    \n-
    185 {}
    \n-
    186
    \n-
    187 void setArgs(const SmootherArgs& args)
    \n-
    188 {
    \n-
    189 args_=&args;
    \n-
    190 }
    \n-
    191
    \n-
    192 template<class T1>
    \n-
    193 void setComm([[maybe_unused]] T1& comm)
    \n-
    194 {}
    \n-
    195
    \n-\n-
    197 {
    \n-
    198 return comm_;
    \n-
    199 }
    \n-
    200
    \n-
    201 const SmootherArgs getArgs() const
    \n-
    202 {
    \n-
    203 return *args_;
    \n-
    204 }
    \n-
    205
    \n-
    206 private:
    \n-
    207 const SmootherArgs* args_;
    \n-\n-
    209 };
    \n-
    210
    \n-
    211
    \n-
    212
    \n-
    213 template<class T>
    \n-
    214 struct ConstructionTraits;
    \n-
    215
    \n-
    219 template<class M, class X, class Y, int l>
    \n-
    220 struct ConstructionTraits<SeqSSOR<M,X,Y,l> >
    \n-
    221 {
    \n-\n-
    223
    \n-
    224 static inline std::shared_ptr<SeqSSOR<M,X,Y,l>> construct(Arguments& args)
    \n-
    225 {
    \n-
    226 return std::make_shared<SeqSSOR<M,X,Y,l>>
    \n-
    227 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n-
    228 }
    \n-
    229 };
    \n-
    230
    \n-
    231
    \n-
    235 template<class M, class X, class Y, int l>
    \n-
    236 struct ConstructionTraits<SeqSOR<M,X,Y,l> >
    \n-
    237 {
    \n-\n-
    239
    \n-
    240 static inline std::shared_ptr<SeqSOR<M,X,Y,l>> construct(Arguments& args)
    \n-
    241 {
    \n-
    242 return std::make_shared<SeqSOR<M,X,Y,l>>
    \n-
    243 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n-
    244 }
    \n-
    245 };
    \n-
    246
    \n-
    247
    \n-
    251 template<class M, class X, class Y, int l>
    \n-
    252 struct ConstructionTraits<SeqJac<M,X,Y,l> >
    \n-
    253 {
    \n-\n-
    255
    \n-
    256 static inline std::shared_ptr<SeqJac<M,X,Y,l>> construct(Arguments& args)
    \n-
    257 {
    \n-
    258 return std::make_shared<SeqJac<M,X,Y,l>>
    \n-
    259 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n-
    260 }
    \n-
    261 };
    \n-
    262
    \n-
    266 template<class X, class Y>
    \n-\n-
    268 {
    \n-\n-
    270
    \n-
    271 static inline std::shared_ptr<Richardson<X,Y>> construct(Arguments& args)
    \n-
    272 {
    \n-
    273 return std::make_shared<Richardson<X,Y>>
    \n-
    274 (args.getArgs().relaxationFactor);
    \n-
    275 }
    \n-
    276 };
    \n-
    277
    \n-
    278
    \n-
    279 template<class M, class X, class Y>
    \n-\n-
    281 : public DefaultConstructionArgs<SeqILU<M,X,Y> >
    \n-
    282 {
    \n-
    283 public:
    \n-\n-
    285 : n_(n)
    \n-
    286 {}
    \n-
    287
    \n-
    288 void setN(int n)
    \n-
    289 {
    \n-
    290 n_ = n;
    \n-
    291 }
    \n-
    292
    \n-
    293 int getN()
    \n-
    294 {
    \n-
    295 return n_;
    \n-
    296 }
    \n+\n+
    151 : criterion_(crit)
    \n+
    152 {}
    \n+
    153
    \n+
    154 void createCoarseLevelSystem(const O& fineOperator)
    \n+
    155 {
    \n+
    156 prolongDamp_ = criterion_.getProlongationDampingFactor();
    \n+\n+\n+\n+
    160 Dune::Amg::EdgeProperties,Dune::IdentityMap,Dune::IdentityMap> PropertiesGraph;
    \n+
    161 MatrixGraph mg(fineOperator.getmat());
    \n+
    162 PropertiesGraph pg(mg,Dune::IdentityMap(),Dune::IdentityMap());
    \n+
    163 typedef NegateSet<typename ParallelInformation::OwnerSet> OverlapFlags;
    \n+
    164
    \n+
    165 aggregatesMap_ = std::make_shared<AggregatesMap>(pg.maxVertex()+1);
    \n+
    166
    \n+
    167 int noAggregates, isoAggregates, oneAggregates, skippedAggregates;
    \n+
    168
    \n+
    169 std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =
    \n+
    170 aggregatesMap_->buildAggregates(fineOperator.getmat(), pg, criterion_, true);
    \n+
    171 std::cout<<"no aggregates="<<noAggregates<<" iso="<<isoAggregates<<" one="<<oneAggregates<<" skipped="<<skippedAggregates<<std::endl;
    \n+
    172 // misuse coarsener to renumber aggregates
    \n+\n+
    174 typedef std::vector<bool>::iterator Iterator;
    \n+
    175 typedef Dune::IteratorPropertyMap<Iterator, Dune::IdentityMap> VisitedMap;
    \n+
    176 std::vector<bool> excluded(fineOperator.getmat().N(), false);
    \n+
    177 VisitedMap vm(excluded.begin(), Dune::IdentityMap());
    \n+\n+
    179 std::size_t aggregates = renumberer.coarsen(pinfo, pg, vm,
    \n+
    180 *aggregatesMap_, pinfo,
    \n+
    181 noAggregates);
    \n+
    182 std::vector<bool>& visited=excluded;
    \n+
    183
    \n+
    184 typedef std::vector<bool>::iterator Iterator;
    \n+
    185
    \n+
    186 for(Iterator iter= visited.begin(), end=visited.end();
    \n+
    187 iter != end; ++iter)
    \n+
    188 *iter=false;
    \n+
    189 matrix_.reset(productBuilder.build(mg, vm,
    \n+\n+
    191 *aggregatesMap_,
    \n+
    192 aggregates,
    \n+
    193 OverlapFlags()));
    \n+
    194 productBuilder.calculate(fineOperator.getmat(), *aggregatesMap_, *matrix_, pinfo, OverlapFlags());
    \n+
    195 this->lhs_.resize(this->matrix_->M());
    \n+
    196 this->rhs_.resize(this->matrix_->N());
    \n+
    197 this->operator_ = std::make_shared<O>(*matrix_);
    \n+
    198 }
    \n+
    199
    \n+
    200 void moveToCoarseLevel(const typename FatherType::FineRangeType& fineRhs)
    \n+
    201 {
    \n+\n+
    203 ::restrictVector(*aggregatesMap_, this->rhs_, fineRhs, ParallelInformation());
    \n+
    204 this->lhs_=0;
    \n+
    205 }
    \n+
    206
    \n+\n+
    208 {
    \n+\n+
    210 ::prolongateVector(*aggregatesMap_, this->lhs_, fineLhs,
    \n+
    211 prolongDamp_, ParallelInformation());
    \n+
    212 }
    \n+
    213
    \n+\n+
    215 {
    \n+
    216 return new AggregationLevelTransferPolicy(*this);
    \n+
    217 }
    \n+
    218
    \n+
    219private:
    \n+
    220 typename O::matrix_type::field_type prolongDamp_;
    \n+
    221 std::shared_ptr<AggregatesMap> aggregatesMap_;
    \n+
    222 Criterion criterion_;
    \n+
    223 std::shared_ptr<typename O::matrix_type> matrix_;
    \n+
    224};
    \n+
    225
    \n+
    232template<class O, class S, class C>
    \n+\n+
    234{
    \n+
    235public:
    \n+
    237 typedef O Operator;
    \n+
    239 typedef typename O::range_type X;
    \n+
    241 typedef C Criterion;
    \n+
    243 typedef S Smoother;
    \n+\n+\n+\n+
    254 : smootherArgs_(args), criterion_(c)
    \n+
    255 {}
    \n+\n+
    258 : coarseOperator_(other.coarseOperator_), smootherArgs_(other.smootherArgs_),
    \n+
    259 criterion_(other.criterion_)
    \n+
    260 {}
    \n+
    261private:
    \n+
    268 struct AMGInverseOperator : public InverseOperator<X,X>
    \n+
    269 {
    \n+
    270 AMGInverseOperator(const typename AMGType::Operator& op,
    \n+
    271 const Criterion& crit,
    \n+
    272 const typename AMGType::SmootherArgs& args)
    \n+
    273 : amg_(op, crit,args), first_(true)
    \n+
    274 {}
    \n+
    275
    \n+
    276 void apply(X& x, X& b, [[maybe_unused]] double reduction, [[maybe_unused]] InverseOperatorResult& res)
    \n+
    277 {
    \n+
    278 if(first_)
    \n+
    279 {
    \n+
    280 amg_.pre(x,b);
    \n+
    281 first_=false;
    \n+
    282 x_=x;
    \n+
    283 }
    \n+
    284 amg_.apply(x,b);
    \n+
    285 }
    \n+
    286
    \n+
    287 void apply(X& x, X& b, InverseOperatorResult& res)
    \n+
    288 {
    \n+
    289 return apply(x,b,1e-8,res);
    \n+
    290 }
    \n+
    291
    \n+
    293 virtual SolverCategory::Category category() const
    \n+
    294 {
    \n+
    295 return amg_.category();
    \n+
    296 }
    \n
    297
    \n-
    298 private:
    \n-
    299 int n_;
    \n-
    300 };
    \n-
    301
    \n-
    302
    \n-
    306 template<class M, class X, class Y>
    \n-\n-
    308 {
    \n-\n-
    310
    \n-
    311 static inline std::shared_ptr<SeqILU<M,X,Y>> construct(Arguments& args)
    \n-
    312 {
    \n-
    313 return std::make_shared<SeqILU<M,X,Y>>
    \n-
    314 (args.getMatrix(), args.getN(), args.getArgs().relaxationFactor);
    \n-
    315 }
    \n-
    316 };
    \n-
    317
    \n-
    321 template<class M, class X, class Y, class C>
    \n-
    322 struct ConstructionTraits<ParSSOR<M,X,Y,C> >
    \n-
    323 {
    \n-\n-
    325
    \n-
    326 static inline std::shared_ptr<ParSSOR<M,X,Y,C>> construct(Arguments& args)
    \n-
    327 {
    \n-
    328 return std::make_shared<ParSSOR<M,X,Y,C>>
    \n-
    329 (args.getMatrix(), args.getArgs().iterations,
    \n-
    330 args.getArgs().relaxationFactor, args.getComm());
    \n-
    331 }
    \n-
    332 };
    \n+
    298 ~AMGInverseOperator()
    \n+
    299 {
    \n+
    300 if(!first_)
    \n+
    301 amg_.post(x_);
    \n+
    302 }
    \n+
    303 AMGInverseOperator(const AMGInverseOperator& other)
    \n+
    304 : x_(other.x_), amg_(other.amg_), first_(other.first_)
    \n+
    305 {
    \n+
    306 }
    \n+
    307 private:
    \n+
    308 X x_;
    \n+
    309 AMGType amg_;
    \n+
    310 bool first_;
    \n+
    311 };
    \n+
    312
    \n+
    313public:
    \n+
    315 typedef AMGInverseOperator CoarseLevelSolver;
    \n+
    316
    \n+
    324 template<class P>
    \n+\n+
    326 {
    \n+
    327 coarseOperator_=transferPolicy.getCoarseLevelOperator();
    \n+
    328 AMGInverseOperator* inv = new AMGInverseOperator(*coarseOperator_,
    \n+
    329 criterion_,
    \n+
    330 smootherArgs_);
    \n+
    331
    \n+
    332 return inv; //std::shared_ptr<InverseOperator<X,X> >(inv);
    \n
    333
    \n-
    334 template<class X, class Y, class C, class T>
    \n-\n-
    336 {
    \n-\n-\n-
    339 static inline std::shared_ptr<BlockPreconditioner<X,Y,C,T>> construct(Arguments& args)
    \n-
    340 {
    \n-
    341 auto seqPrec = SeqConstructionTraits::construct(args);
    \n-
    342 return std::make_shared<BlockPreconditioner<X,Y,C,T>> (seqPrec, args.getComm());
    \n-
    343 }
    \n-
    344 };
    \n-
    345
    \n-
    346 template<class C, class T>
    \n-\n-
    348 {
    \n-\n-\n-
    351 static inline std::shared_ptr<NonoverlappingBlockPreconditioner<C,T>> construct(Arguments& args)
    \n-
    352 {
    \n-
    353 auto seqPrec = SeqConstructionTraits::construct(args);
    \n-
    354 return std::make_shared<NonoverlappingBlockPreconditioner<C,T>> (seqPrec, args.getComm());
    \n-
    355 }
    \n-
    356 };
    \n-
    357
    \n-
    368 template<class T>
    \n-\n-
    370 {
    \n-
    371 typedef T Smoother;
    \n-
    372 typedef typename Smoother::range_type Range;
    \n-
    373 typedef typename Smoother::domain_type Domain;
    \n-
    374
    \n-
    382 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n-
    383 {
    \n-
    384 smoother.apply(v,d);
    \n-
    385 }
    \n-
    386
    \n-
    394 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n-
    395 {
    \n-
    396 smoother.apply(v,d);
    \n-
    397 }
    \n-
    398 };
    \n-
    399
    \n-
    405 template<typename LevelContext>
    \n-
    406 void presmooth(LevelContext& levelContext, size_t steps)
    \n-
    407 {
    \n-
    408 for(std::size_t i=0; i < steps; ++i) {
    \n-
    409 *levelContext.lhs=0;
    \n-\n-
    411 ::preSmooth(*levelContext.smoother, *levelContext.lhs,
    \n-
    412 *levelContext.rhs);
    \n-
    413 // Accumulate update
    \n-
    414 *levelContext.update += *levelContext.lhs;
    \n-
    415
    \n-
    416 // update defect
    \n-
    417 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs, *levelContext.rhs);
    \n-
    418 levelContext.pinfo->project(*levelContext.rhs);
    \n-
    419 }
    \n-
    420 }
    \n-
    421
    \n-
    427 template<typename LevelContext>
    \n-
    428 void postsmooth(LevelContext& levelContext, size_t steps)
    \n-
    429 {
    \n-
    430 for(std::size_t i=0; i < steps; ++i) {
    \n-
    431 // update defect
    \n-
    432 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,
    \n-
    433 *levelContext.rhs);
    \n-
    434 *levelContext.lhs=0;
    \n-
    435 levelContext.pinfo->project(*levelContext.rhs);
    \n-\n-
    437 ::postSmooth(*levelContext.smoother, *levelContext.lhs, *levelContext.rhs);
    \n-
    438 // Accumulate update
    \n-
    439 *levelContext.update += *levelContext.lhs;
    \n-
    440 }
    \n-
    441 }
    \n-
    442
    \n-
    443 template<class M, class X, class Y, int l>
    \n-
    444 struct SmootherApplier<SeqSOR<M,X,Y,l> >
    \n-
    445 {
    \n-\n-
    447 typedef typename Smoother::range_type Range;
    \n-\n-
    449
    \n-
    450 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    451 {
    \n-
    452 smoother.template apply<true>(v,d);
    \n-
    453 }
    \n-
    454
    \n-
    455
    \n-
    456 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    457 {
    \n-
    458 smoother.template apply<false>(v,d);
    \n-
    459 }
    \n-
    460 };
    \n-
    461
    \n-
    462 template<class M, class X, class Y, class C, int l>
    \n-\n-
    464 {
    \n-\n-
    466 typedef typename Smoother::range_type Range;
    \n-\n-
    468
    \n-
    469 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    470 {
    \n-
    471 smoother.template apply<true>(v,d);
    \n-
    472 }
    \n-
    473
    \n-
    474
    \n-
    475 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    476 {
    \n-
    477 smoother.template apply<false>(v,d);
    \n-
    478 }
    \n-
    479 };
    \n-
    480
    \n-
    481 template<class M, class X, class Y, class C, int l>
    \n-\n-
    483 {
    \n-\n-
    485 typedef typename Smoother::range_type Range;
    \n-\n-
    487
    \n-
    488 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    489 {
    \n-
    490 smoother.template apply<true>(v,d);
    \n-
    491 }
    \n-
    492
    \n-
    493
    \n-
    494 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n-
    495 {
    \n-
    496 smoother.template apply<false>(v,d);
    \n-
    497 }
    \n-
    498 };
    \n-
    499
    \n-
    500 } // end namespace Amg
    \n-
    501
    \n-
    502 // forward declarations
    \n-
    503 template<class M, class X, class MO, class MS, class A>
    \n-
    504 class SeqOverlappingSchwarz;
    \n-
    505
    \n-
    506 struct MultiplicativeSchwarzMode;
    \n-
    507
    \n-
    508 namespace Amg
    \n-
    509 {
    \n-
    510 template<class M, class X, class MS, class TA>
    \n-\n-
    512 MS,TA> >
    \n-
    513 {
    \n-\n-
    515 typedef typename Smoother::range_type Range;
    \n-\n-
    517
    \n-
    518 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n-
    519 {
    \n-
    520 smoother.template apply<true>(v,d);
    \n-
    521 }
    \n-
    522
    \n-
    523
    \n-
    524 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n-
    525 {
    \n-
    526 smoother.template apply<false>(v,d);
    \n-
    527
    \n-
    528 }
    \n-
    529 };
    \n-
    530
    \n-
    531 // template<class M, class X, class TM, class TA>
    \n-
    532 // class SeqOverlappingSchwarz;
    \n-
    533
    \n-
    534 template<class T>
    \n-\n-
    536 : public DefaultSmootherArgs<T>
    \n-
    537 {
    \n-\n-
    539
    \n-\n-\n-
    542
    \n-\n-
    544 bool onthefly_=false)
    \n-
    545 : overlap(overlap_), onthefly(onthefly_)
    \n-
    546 {}
    \n-
    547 };
    \n-
    548
    \n-
    549 template<class M, class X, class TM, class TS, class TA>
    \n-\n-
    551 {
    \n-\n-
    553 };
    \n-
    554
    \n-
    555 template<class M, class X, class TM, class TS, class TA>
    \n-\n-
    557 : public DefaultConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
    \n-
    558 {
    \n-\n-
    560
    \n-
    561 public:
    \n-\n-\n-\n-\n-
    566 typedef typename Vector::value_type Subdomain;
    \n-
    567
    \n-
    568 virtual void setMatrix(const M& matrix, const AggregatesMap& amap)
    \n-
    569 {
    \n-
    570 Father::setMatrix(matrix);
    \n-
    571
    \n-
    572 std::vector<bool> visited(amap.noVertices(), false);
    \n-
    573 typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
    \n-
    574 VisitedMapType visitedMap(visited.begin());
    \n-
    575
    \n-
    576 MatrixGraph<const M> graph(matrix);
    \n-
    577
    \n-\n-
    579
    \n-
    580 switch(Father::getArgs().overlap) {
    \n-
    581 case SmootherArgs::vertex :
    \n-
    582 {
    \n-
    583 VertexAdder visitor(subdomains, amap);
    \n-
    584 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    585 }
    \n-
    586 break;
    \n-
    587 case SmootherArgs::pairwise :
    \n-
    588 {
    \n-
    589 createPairDomains(graph);
    \n-
    590 }
    \n-
    591 break;
    \n-
    592 case SmootherArgs::aggregate :
    \n-
    593 {
    \n-
    594 AggregateAdder<VisitedMapType> visitor(subdomains, amap, graph, visitedMap);
    \n-
    595 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    596 }
    \n-
    597 break;
    \n-
    598 case SmootherArgs::none :
    \n-
    599 NoneAdder visitor;
    \n-
    600 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    601 break;
    \n-
    602 default :
    \n-
    603 DUNE_THROW(NotImplemented, "This overlapping scheme is not supported!");
    \n-
    604 }
    \n-
    605 }
    \n-
    606 void setMatrix(const M& matrix)
    \n-
    607 {
    \n-
    608 Father::setMatrix(matrix);
    \n-
    609
    \n-
    610 /* Create aggregates map where each aggregate is just one vertex. */
    \n-
    611 AggregatesMap amap(matrix.N());
    \n-\n-
    613 for(typename AggregatesMap::iterator iter=amap.begin();
    \n-
    614 iter!=amap.end(); ++iter)
    \n-
    615 *iter=v++;
    \n-
    616
    \n-
    617 std::vector<bool> visited(amap.noVertices(), false);
    \n-
    618 typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
    \n-
    619 VisitedMapType visitedMap(visited.begin());
    \n-
    620
    \n-
    621 MatrixGraph<const M> graph(matrix);
    \n-
    622
    \n-\n-
    624
    \n-
    625 switch(Father::getArgs().overlap) {
    \n-
    626 case SmootherArgs::vertex :
    \n-
    627 {
    \n-
    628 VertexAdder visitor(subdomains, amap);
    \n-
    629 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    630 }
    \n-
    631 break;
    \n-
    632 case SmootherArgs::aggregate :
    \n-
    633 {
    \n-
    634 DUNE_THROW(NotImplemented, "Aggregate overlap is not supported yet");
    \n-
    635 /*
    \n-
    636 AggregateAdder<VisitedMapType> visitor(subdomains, amap, graph, visitedMap);
    \n-
    637 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    638 */
    \n-
    639 }
    \n-
    640 break;
    \n-
    641 case SmootherArgs::pairwise :
    \n-
    642 {
    \n-
    643 createPairDomains(graph);
    \n-
    644 }
    \n-
    645 break;
    \n-
    646 case SmootherArgs::none :
    \n-
    647 NoneAdder visitor;
    \n-
    648 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n-
    649
    \n-
    650 }
    \n-
    651 }
    \n-
    652
    \n-\n-
    654 {
    \n-
    655 return subdomains;
    \n-
    656 }
    \n-
    657
    \n-
    658 private:
    \n-
    659 struct VertexAdder
    \n-
    660 {
    \n-
    661 VertexAdder(Vector& subdomains_, const AggregatesMap& aggregates_)
    \n-
    662 : subdomains(subdomains_), max(-1), subdomain(-1), aggregates(aggregates_)
    \n-
    663 {}
    \n-
    664 template<class T>
    \n-
    665 void operator()(const T& edge)
    \n-
    666 {
    \n-
    667 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED)
    \n-
    668 subdomains[subdomain].insert(edge.target());
    \n-
    669 }
    \n-
    670 int setAggregate(const AggregateDescriptor& aggregate_)
    \n-
    671 {
    \n-
    672 subdomain=aggregate_;
    \n-
    673 max = std::max(subdomain, aggregate_);
    \n-
    674 return subdomain;
    \n-
    675 }
    \n-
    676 int noSubdomains() const
    \n-
    677 {
    \n-
    678 return max+1;
    \n-
    679 }
    \n-
    680 private:
    \n-
    681 Vector& subdomains;
    \n-\n-
    683 AggregateDescriptor subdomain;
    \n-
    684 const AggregatesMap& aggregates;
    \n-
    685 };
    \n-
    686 struct NoneAdder
    \n-
    687 {
    \n-
    688 template<class T>
    \n-
    689 void operator()(const T& edge)
    \n-
    690 {}
    \n-
    691 int setAggregate(const AggregateDescriptor& aggregate_)
    \n-
    692 {
    \n-
    693 return -1;
    \n-
    694 }
    \n-
    695 int noSubdomains() const
    \n-
    696 {
    \n-
    697 return -1;
    \n-
    698 }
    \n-
    699 };
    \n-
    700
    \n-
    701 template<class VM>
    \n-
    702 struct AggregateAdder
    \n-
    703 {
    \n-
    704 AggregateAdder(Vector& subdomains_, const AggregatesMap& aggregates_,
    \n-
    705 const MatrixGraph<const M>& graph_, VM& visitedMap_)
    \n-
    706 : subdomains(subdomains_), subdomain(-1), aggregates(aggregates_),
    \n-
    707 adder(subdomains_, aggregates_), graph(graph_), visitedMap(visitedMap_)
    \n-
    708 {}
    \n-
    709 template<class T>
    \n-
    710 void operator()(const T& edge)
    \n-
    711 {
    \n-
    712 subdomains[subdomain].insert(edge.target());
    \n-
    713 // If we (the neighbouring vertex of the aggregate)
    \n-
    714 // are not isolated, add the aggregate we belong to
    \n-
    715 // to the same subdomain using the OneOverlapAdder
    \n-
    716 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED) {
    \n-
    717 assert(aggregates[edge.target()]!=aggregate);
    \n-
    718 typename AggregatesMap::VertexList vlist;
    \n-
    719 aggregates.template breadthFirstSearch<true,false>(edge.target(), aggregate,
    \n-
    720 graph, vlist, adder, adder,
    \n-
    721 visitedMap);
    \n-
    722 }
    \n-
    723 }
    \n-
    724
    \n-
    725 int setAggregate(const AggregateDescriptor& aggregate_)
    \n-
    726 {
    \n-
    727 adder.setAggregate(aggregate_);
    \n-
    728 aggregate=aggregate_;
    \n-
    729 return ++subdomain;
    \n-
    730 }
    \n-
    731 int noSubdomains() const
    \n-
    732 {
    \n-
    733 return subdomain+1;
    \n-
    734 }
    \n-
    735
    \n-
    736 private:
    \n-
    737 AggregateDescriptor aggregate;
    \n-
    738 Vector& subdomains;
    \n-
    739 int subdomain;
    \n-
    740 const AggregatesMap& aggregates;
    \n-
    741 VertexAdder adder;
    \n-
    742 const MatrixGraph<const M>& graph;
    \n-
    743 VM& visitedMap;
    \n-
    744 };
    \n-
    745
    \n-
    746 void createPairDomains(const MatrixGraph<const M>& graph)
    \n-
    747 {
    \n-
    748 typedef typename MatrixGraph<const M>::ConstVertexIterator VIter;
    \n-
    749 typedef typename MatrixGraph<const M>::ConstEdgeIterator EIter;
    \n-
    750 typedef typename M::size_type size_type;
    \n-
    751
    \n-
    752 std::set<std::pair<size_type,size_type> > pairs;
    \n-
    753 int total=0;
    \n-
    754 for(VIter v=graph.begin(), ve=graph.end(); ve != v; ++v)
    \n-
    755 for(EIter e = v.begin(), ee=v.end(); ee!=e; ++e)
    \n-
    756 {
    \n-
    757 ++total;
    \n-
    758 if(e.source()<e.target())
    \n-
    759 pairs.insert(std::make_pair(e.source(),e.target()));
    \n-
    760 else
    \n-
    761 pairs.insert(std::make_pair(e.target(),e.source()));
    \n-
    762 }
    \n-
    763
    \n-
    764
    \n-
    765 subdomains.resize(pairs.size());
    \n-
    766 Dune::dinfo <<std::endl<< "Created "<<pairs.size()<<" ("<<total<<") pair domains"<<std::endl<<std::endl;
    \n-
    767 typedef typename std::set<std::pair<size_type,size_type> >::const_iterator SIter;
    \n-
    768 typename Vector::iterator subdomain=subdomains.begin();
    \n-
    769
    \n-
    770 for(SIter s=pairs.begin(), se =pairs.end(); se!=s; ++s)
    \n-
    771 {
    \n-
    772 subdomain->insert(s->first);
    \n-
    773 subdomain->insert(s->second);
    \n-
    774 ++subdomain;
    \n-
    775 }
    \n-
    776 std::size_t minsize=10000;
    \n-
    777 std::size_t maxsize=0;
    \n-
    778 int sum=0;
    \n-
    779 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {
    \n-
    780 sum+=subdomains[i].size();
    \n-
    781 minsize=std::min(minsize, subdomains[i].size());
    \n-
    782 maxsize=std::max(maxsize, subdomains[i].size());
    \n-
    783 }
    \n-
    784 Dune::dinfo<<"Subdomain size: min="<<minsize<<" max="<<maxsize<<" avg="<<(sum/subdomains.size())
    \n-
    785 <<" no="<<subdomains.size()<<std::endl;
    \n-
    786 }
    \n-
    787
    \n-
    788 template<class Visitor>
    \n-
    789 void createSubdomains(const M& matrix, const MatrixGraph<const M>& graph,
    \n-
    790 const AggregatesMap& amap, Visitor& overlapVisitor,
    \n-
    791 IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap>& visitedMap )
    \n-
    792 {
    \n-
    793 // count number ag aggregates. We assume that the
    \n-
    794 // aggregates are numbered consecutively from 0 except
    \n-
    795 // for the isolated ones. All isolated vertices form
    \n-
    796 // one aggregate, here.
    \n-
    797 int isolated=0;
    \n-
    798 AggregateDescriptor maxAggregate=0;
    \n-
    799
    \n-
    800 for(std::size_t i=0; i < amap.noVertices(); ++i)
    \n-
    801 if(amap[i]==AggregatesMap::ISOLATED)
    \n-
    802 isolated++;
    \n-
    803 else
    \n-
    804 maxAggregate = std::max(maxAggregate, amap[i]);
    \n-
    805
    \n-
    806 subdomains.resize(maxAggregate+1+isolated);
    \n-
    807
    \n-
    808 // reset the subdomains
    \n-
    809 for(typename Vector::size_type i=0; i < subdomains.size(); ++i)
    \n-
    810 subdomains[i].clear();
    \n-
    811
    \n-
    812 // Create the subdomains from the aggregates mapping.
    \n-
    813 // For each aggregate we mark all entries and the
    \n-
    814 // neighbouring vertices as belonging to the same subdomain
    \n-
    815 VertexAdder aggregateVisitor(subdomains, amap);
    \n-
    816
    \n-
    817 for(VertexDescriptor i=0; i < amap.noVertices(); ++i)
    \n-
    818 if(!get(visitedMap, i)) {
    \n-
    819 AggregateDescriptor aggregate=amap[i];
    \n-
    820
    \n-
    821 if(amap[i]==AggregatesMap::ISOLATED) {
    \n-
    822 // isolated vertex gets its own aggregate
    \n-
    823 subdomains.push_back(Subdomain());
    \n-
    824 aggregate=subdomains.size()-1;
    \n-
    825 }
    \n-
    826 overlapVisitor.setAggregate(aggregate);
    \n-
    827 aggregateVisitor.setAggregate(aggregate);
    \n-
    828 subdomains[aggregate].insert(i);
    \n-
    829 typename AggregatesMap::VertexList vlist;
    \n-
    830 amap.template breadthFirstSearch<false,false>(i, aggregate, graph, vlist, aggregateVisitor,
    \n-
    831 overlapVisitor, visitedMap);
    \n-
    832 }
    \n-
    833
    \n-
    834 std::size_t minsize=10000;
    \n-
    835 std::size_t maxsize=0;
    \n-
    836 int sum=0;
    \n-
    837 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {
    \n-
    838 sum+=subdomains[i].size();
    \n-
    839 minsize=std::min(minsize, subdomains[i].size());
    \n-
    840 maxsize=std::max(maxsize, subdomains[i].size());
    \n-
    841 }
    \n-
    842 Dune::dinfo<<"Subdomain size: min="<<minsize<<" max="<<maxsize<<" avg="<<(sum/subdomains.size())
    \n-
    843 <<" no="<<subdomains.size()<<" isolated="<<isolated<<std::endl;
    \n-
    844
    \n-
    845
    \n-
    846
    \n-
    847 }
    \n-
    848 Vector subdomains;
    \n-
    849 };
    \n-
    850
    \n-
    851
    \n-
    852 template<class M, class X, class TM, class TS, class TA>
    \n-\n-
    854 {
    \n-\n-
    856
    \n-
    857 static inline std::shared_ptr<SeqOverlappingSchwarz<M,X,TM,TS,TA>> construct(Arguments& args)
    \n-
    858 {
    \n-
    859 return std::make_shared<SeqOverlappingSchwarz<M,X,TM,TS,TA>>
    \n-
    860 (args.getMatrix(),
    \n-
    861 args.getSubDomains(),
    \n-\n-
    863 args.getArgs().onthefly);
    \n-
    864 }
    \n-
    865 };
    \n-
    866
    \n-
    867
    \n-
    868 } // namespace Amg
    \n-
    869} // namespace Dune
    \n-
    870
    \n-
    871
    \n-
    872
    \n-
    873#endif
    \n-
    Define general preconditioner interface.
    \n-
    Provides classes for the Coloring process of AMG.
    \n-
    Helper classes for the construction of classes without empty constructor.
    \n-\n-\n-
    DefaultSmootherArgs< typename X::field_type > Arguments
    Definition: smoother.hh:74
    \n-
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:494
    \n-\n-
    static void preSmooth(Smoother &smoother, Domain &v, const Range &d)
    Definition: smoother.hh:518
    \n-
    static std::shared_ptr< SeqJac< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:256
    \n-
    ConstructionArgs< SeqILU< M, X, Y > > Arguments
    Definition: smoother.hh:309
    \n-
    const Matrix & getMatrix() const
    Definition: smoother.hh:114
    \n-\n-
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:691
    \n-
    DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments
    Definition: smoother.hh:67
    \n-
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:670
    \n-
    ConstructionTraits< T > SeqConstructionTraits
    Definition: smoother.hh:350
    \n-
    void setArgs(const SmootherArgs &args)
    Definition: smoother.hh:119
    \n-
    ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Arguments
    Definition: smoother.hh:855
    \n-
    NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > Smoother
    Definition: smoother.hh:484
    \n-
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:456
    \n-
    AggregateAdder(Vector &subdomains_, const AggregatesMap &aggregates_, const MatrixGraph< const M > &graph_, VM &visitedMap_)
    Definition: smoother.hh:704
    \n-\n-
    void setComm(const C &comm)
    Definition: smoother.hh:158
    \n-
    DefaultConstructionArgs< Richardson< X, Y > > Arguments
    Definition: smoother.hh:269
    \n-
    virtual ~DefaultConstructionArgs()
    Definition: smoother.hh:180
    \n-
    SeqOverlappingSchwarzSmootherArgs< typename M::field_type > Arguments
    Definition: smoother.hh:552
    \n-\n-
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:488
    \n-
    int getN()
    Definition: smoother.hh:293
    \n-\n-
    SeqSOR< M, X, Y, l > Smoother
    Definition: smoother.hh:446
    \n-\n-
    static std::shared_ptr< SeqSSOR< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:224
    \n-
    AggregatesMap::AggregateDescriptor AggregateDescriptor
    Definition: smoother.hh:564
    \n-
    bool onthefly
    Definition: smoother.hh:541
    \n-
    DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments
    Definition: smoother.hh:238
    \n-
    virtual void setMatrix(const M &matrix, const AggregatesMap &amap)
    Definition: smoother.hh:568
    \n-
    void setMatrix(const Args &...)
    Definition: smoother.hh:184
    \n-
    DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments
    Definition: smoother.hh:254
    \n-
    DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments
    Definition: smoother.hh:222
    \n-
    const SmootherArgs getArgs() const
    Definition: smoother.hh:133
    \n-
    VertexAdder(Vector &subdomains_, const AggregatesMap &aggregates_)
    Definition: smoother.hh:661
    \n-\n-
    SeqOverlappingSchwarz< M, X, TM, TS, TA >::subdomain_vector Vector
    Definition: smoother.hh:565
    \n-
    static std::shared_ptr< SeqOverlappingSchwarz< M, X, TM, TS, TA > > construct(Arguments &args)
    Definition: smoother.hh:857
    \n-
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:469
    \n-
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n-
    void setMatrix(const Matrix &matrix)
    Definition: smoother.hh:104
    \n-
    T Smoother
    Definition: smoother.hh:371
    \n-
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:450
    \n-
    BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > Smoother
    Definition: smoother.hh:465
    \n-
    void setComm(T1 &comm)
    Definition: smoother.hh:193
    \n-\n-
    AggregateDescriptor * iterator
    Definition: aggregates.hh:735
    \n+
    334 }
    \n+
    335
    \n+
    336private:
    \n+
    338 std::shared_ptr<Operator> coarseOperator_;
    \n+
    340 SmootherArgs smootherArgs_;
    \n+
    342 Criterion criterion_;
    \n+
    343};
    \n+
    344
    \n+
    350template<class FO, class CSP, class S>
    \n+\n+
    352 public Preconditioner<typename FO::domain_type, typename FO::range_type>
    \n+
    353{
    \n+
    354public:
    \n+\n+
    358 typedef typename CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver;
    \n+\n+
    367 typedef typename FineOperatorType::range_type FineRangeType;
    \n+
    371 typedef typename FineOperatorType::domain_type FineDomainType;
    \n+
    376 typedef typename CSP::Operator CoarseOperatorType;
    \n+
    380 typedef typename CoarseOperatorType::range_type CoarseRangeType;
    \n+
    384 typedef typename CoarseOperatorType::domain_type CoarseDomainType;
    \n+
    388 typedef S SmootherType;
    \n+
    389
    \n+\n+
    405 std::shared_ptr<SmootherType> smoother,
    \n+\n+
    407 CoarseOperatorType>& policy,
    \n+
    408 CoarseLevelSolverPolicy& coarsePolicy,
    \n+
    409 std::size_t preSteps=1, std::size_t postSteps=1)
    \n+
    410 : operator_(&op), smoother_(smoother),
    \n+
    411 preSteps_(preSteps), postSteps_(postSteps)
    \n+
    412 {
    \n+
    413 policy_ = policy.clone();
    \n+
    414 policy_->createCoarseLevelSystem(*operator_);
    \n+
    415 coarseSolver_=coarsePolicy.createCoarseLevelSolver(*policy_);
    \n+
    416 }
    \n+
    417
    \n+\n+
    419 : operator_(other.operator_), coarseSolver_(new CoarseLevelSolver(*other.coarseSolver_)),
    \n+
    420 smoother_(other.smoother_), policy_(other.policy_->clone()),
    \n+
    421 preSteps_(other.preSteps_), postSteps_(other.postSteps_)
    \n+
    422 {}
    \n+
    423
    \n+\n+
    425 {
    \n+
    426 // Each instance has its own policy.
    \n+
    427 delete policy_;
    \n+
    428 delete coarseSolver_;
    \n+
    429 }
    \n+
    430
    \n+\n+
    432 {
    \n+
    433 smoother_->pre(x,b);
    \n+
    434 }
    \n+
    435
    \n+
    436 void post([[maybe_unused]] FineDomainType& x)
    \n+
    437 {}
    \n+
    438
    \n+\n+
    440 {
    \n+
    441 FineDomainType u(v);
    \n+
    442 FineRangeType rhs(d);
    \n+
    443 LevelContext context;
    \n+\n+
    445 context.pinfo=&info;
    \n+
    446 context.lhs=&u;
    \n+
    447 context.update=&v;
    \n+
    448 context.smoother=smoother_;
    \n+
    449 context.rhs=&rhs;
    \n+
    450 context.matrix=operator_;
    \n+
    451 // Presmoothing
    \n+
    452 presmooth(context, preSteps_);
    \n+
    453 //Coarse grid correction
    \n+
    454 policy_->moveToCoarseLevel(*context.rhs);
    \n+\n+
    456 coarseSolver_->apply(policy_->getCoarseLevelLhs(), policy_->getCoarseLevelRhs(), res);
    \n+
    457 *context.lhs=0;
    \n+
    458 policy_->moveToFineLevel(*context.lhs);
    \n+
    459 *context.update += *context.lhs;
    \n+
    460 // Postsmoothing
    \n+
    461 postsmooth(context, postSteps_);
    \n+
    462
    \n+
    463 }
    \n+
    464
    \n+\n+
    467 {
    \n+\n+
    469 }
    \n+
    470
    \n+
    471private:
    \n+
    475 struct LevelContext
    \n+
    476 {
    \n+
    478 typedef S SmootherType;
    \n+
    480 std::shared_ptr<SmootherType> smoother;
    \n+
    482 FineDomainType* lhs;
    \n+
    483 /*
    \n+
    484 * @brief The right hand side holding the current residual.
    \n+
    485 *
    \n+
    486 * This is passed to the smoother as the right hand side.
    \n+
    487 */
    \n+
    488 FineRangeType* rhs;
    \n+
    494 FineDomainType* update;
    \n+\n+
    502 const FineOperatorType* matrix;
    \n+
    503 };
    \n+
    504 const FineOperatorType* operator_;
    \n+
    506 CoarseLevelSolver* coarseSolver_;
    \n+
    508 std::shared_ptr<S> smoother_;
    \n+
    510 LevelTransferPolicy<FO,typename CSP::Operator>* policy_;
    \n+
    512 std::size_t preSteps_;
    \n+
    514 std::size_t postSteps_;
    \n+
    515};
    \n+
    516}// end namespace Amg
    \n+
    517}// end namespace Dune
    \n+
    518
    \n+
    520#endif
    \n+
    Define general, extensible interface for inverse operators.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+
    Provides a class for building the galerkin product based on a aggregation scheme.
    \n+
    The AMG preconditioner.
    \n+
    G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation &pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::Matrix::size_type &size, const Set &copy)
    Calculates the coarse matrix via a Galerkin product.
    Definition: galerkin.hh:563
    \n+
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n+
    Operator Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n-\n-
    SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex, bool onthefly_=false)
    Definition: smoother.hh:543
    \n-
    DefaultParallelConstructionArgs< T, C > Arguments
    Definition: smoother.hh:337
    \n-
    DefaultParallelConstructionArgs< T, C > Arguments
    Definition: smoother.hh:349
    \n-
    const Matrix * matrix_
    Definition: smoother.hh:139
    \n-
    const_iterator end() const
    Definition: aggregates.hh:730
    \n-
    const SequentialInformation & getComm()
    Definition: smoother.hh:128
    \n-
    V AggregateDescriptor
    The aggregate descriptor type.
    Definition: aggregates.hh:580
    \n-
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n-
    DefaultSmootherArgs()
    Default constructor.
    Definition: smoother.hh:56
    \n-
    void setMatrix(const M &matrix)
    Definition: smoother.hh:606
    \n-
    std::size_t noVertices() const
    Get the number of vertices.
    \n-\n-
    static void postSmooth(Smoother &smoother, Domain &v, const Range &d)
    apply post smoothing in forward direction
    Definition: smoother.hh:394
    \n-
    FieldTraits< T >::real_type RelaxationFactor
    The type of the relaxation factor.
    Definition: smoother.hh:42
    \n-\n-
    Smoother::domain_type Domain
    Definition: smoother.hh:373
    \n-
    void setN(int n)
    Definition: smoother.hh:288
    \n-
    static std::shared_ptr< BlockPreconditioner< X, Y, C, T > > construct(Arguments &args)
    Definition: smoother.hh:339
    \n-
    SLList< VertexDescriptor, Allocator > VertexList
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:592
    \n-
    static std::shared_ptr< NonoverlappingBlockPreconditioner< C, T > > construct(Arguments &args)
    Definition: smoother.hh:351
    \n-
    SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > Smoother
    Definition: smoother.hh:514
    \n-
    static std::shared_ptr< ParSSOR< M, X, Y, C > > construct(Arguments &args)
    Definition: smoother.hh:326
    \n-
    MatrixGraph< M >::VertexDescriptor VertexDescriptor
    Definition: smoother.hh:562
    \n-
    static std::shared_ptr< SeqILU< M, X, Y > > construct(Arguments &args)
    Definition: smoother.hh:311
    \n-\n-
    const SequentialInformation & getComm()
    Definition: smoother.hh:196
    \n-
    static std::shared_ptr< SeqSOR< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:240
    \n-
    static std::shared_ptr< Richardson< X, Y > > construct(Arguments &args)
    Definition: smoother.hh:271
    \n-
    virtual void setMatrix(const Matrix &matrix, const AggregatesMap &amap)
    Definition: smoother.hh:108
    \n-\n
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n-
    Dune::Amg::AggregatesMap< VertexDescriptor > AggregatesMap
    Definition: smoother.hh:563
    \n-
    const SmootherArgs getArgs() const
    Definition: smoother.hh:201
    \n-
    void setComm(T1 &comm)
    Definition: smoother.hh:125
    \n-
    static void postSmooth(Smoother &smoother, Domain &v, const Range &d)
    Definition: smoother.hh:524
    \n-
    DefaultParallelConstructionArgs< M, C > Arguments
    Definition: smoother.hh:324
    \n-
    RelaxationFactor relaxationFactor
    The relaxation factor to use.
    Definition: smoother.hh:51
    \n-
    virtual ~DefaultParallelConstructionArgs()
    Definition: smoother.hh:155
    \n-
    Smoother::domain_type Domain
    Definition: smoother.hh:448
    \n-
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:725
    \n-
    Smoother::range_type Range
    Definition: smoother.hh:447
    \n-
    const C & getComm() const
    Definition: smoother.hh:163
    \n-
    virtual ~DefaultConstructionArgs()
    Definition: smoother.hh:101
    \n-
    static void preSmooth(Smoother &smoother, Domain &v, const Range &d)
    apply pre smoothing in forward direction
    Definition: smoother.hh:382
    \n-
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:475
    \n-
    ConstructionTraits< T > SeqConstructionTraits
    Definition: smoother.hh:338
    \n-
    ConstructionArgs(int n=0)
    Definition: smoother.hh:284
    \n-\n-
    void setArgs(const SmootherArgs &args)
    Definition: smoother.hh:187
    \n-
    int iterations
    The numbe of iterations to perform.
    Definition: smoother.hh:47
    \n-
    Smoother::range_type Range
    Definition: smoother.hh:372
    \n-
    Overlap overlap
    Definition: smoother.hh:540
    \n-\n-
    @ aggregate
    Definition: smoother.hh:538
    \n-\n-
    @ pairwise
    Definition: smoother.hh:538
    \n-
    @ vertex
    Definition: smoother.hh:538
    \n+
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n-
    X range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:770
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:765
    \n-
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n-
    Nonoverlapping parallel preconditioner.
    Definition: novlpschwarz.hh:276
    \n-
    P::range_type range_type
    The range type of the preconditioner.
    Definition: novlpschwarz.hh:284
    \n-
    P::domain_type domain_type
    The domain type of the preconditioner.
    Definition: novlpschwarz.hh:282
    \n-
    Tag that tells the Schwarz method to be multiplicative.
    Definition: overlappingschwarz.hh:126
    \n
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-\n-
    VertexIterator end()
    Get an iterator over the vertices.
    \n-
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n-
    VertexIterator begin()
    Get an iterator over the vertices.
    \n+\n+
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n+
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n+
    Definition: galerkin.hh:118
    \n+
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n+
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n+
    VertexDescriptor maxVertex() const
    Get the maximal vertex descriptor.
    \n+
    Definition: indicescoarsener.hh:36
    \n
    Definition: pinfo.hh:28
    \n
    The default class for the smoother arguments.
    Definition: smoother.hh:38
    \n-
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n-
    Construction Arguments for the default smoothers.
    Definition: smoother.hh:93
    \n-
    Definition: smoother.hh:148
    \n-\n-\n-\n-
    Helper class for applying the smoothers.
    Definition: smoother.hh:370
    \n-\n-\n-
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n-
    Sequential SOR preconditioner.
    Definition: preconditioners.hh:261
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:266
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:268
    \n-
    The sequential jacobian preconditioner.
    Definition: preconditioners.hh:412
    \n-
    Sequential ILU preconditioner.
    Definition: preconditioners.hh:532
    \n-
    Richardson preconditioner.
    Definition: preconditioners.hh:713
    \n-
    A parallel SSOR preconditioner.
    Definition: schwarz.hh:175
    \n-
    Block parallel preconditioner.
    Definition: schwarz.hh:278
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:285
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:290
    \n+
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n+
    Abstract base class for transfer between levels and creation of the coarse level system.
    Definition: twolevelmethod.hh:38
    \n+
    CO CoarseOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:57
    \n+
    virtual void moveToCoarseLevel(const FineRangeType &fineRhs)=0
    Transfers the data to the coarse level.
    \n+
    FineOperatorType::range_type FineRangeType
    The type of the range of the fine level operator.
    Definition: twolevelmethod.hh:48
    \n+
    virtual void createCoarseLevelSystem(const FineOperatorType &fineOperator)=0
    Algebraically creates the coarse level system.
    \n+
    CoarseOperatorType::range_type CoarseRangeType
    The type of the range of the coarse level operator.
    Definition: twolevelmethod.hh:61
    \n+
    virtual ~LevelTransferPolicy()
    Destructor.
    Definition: twolevelmethod.hh:124
    \n+
    CoarseDomainType lhs_
    The coarse level lhs.
    Definition: twolevelmethod.hh:130
    \n+
    virtual LevelTransferPolicy * clone() const =0
    Clone the current object.
    \n+
    CoarseDomainType & getCoarseLevelLhs()
    Get the coarse level left hand side.
    Definition: twolevelmethod.hh:87
    \n+
    std::shared_ptr< CoarseOperatorType > operator_
    the coarse level linear operator.
    Definition: twolevelmethod.hh:132
    \n+
    CoarseRangeType rhs_
    The coarse level rhs.
    Definition: twolevelmethod.hh:128
    \n+
    virtual void moveToFineLevel(FineDomainType &fineLhs)=0
    Updates the fine level linear system after the correction of the coarse levels system.
    \n+
    std::shared_ptr< CoarseOperatorType > & getCoarseLevelOperator()
    Get the coarse level operator.
    Definition: twolevelmethod.hh:70
    \n+
    CoarseRangeType & getCoarseLevelRhs()
    Get the coarse level right hand side.
    Definition: twolevelmethod.hh:78
    \n+
    FO FineOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:44
    \n+
    CoarseOperatorType::domain_type CoarseDomainType
    The type of the domain of the coarse level operator.
    Definition: twolevelmethod.hh:65
    \n+
    FineOperatorType::domain_type FineDomainType
    The type of the domain of the fine level operator.
    Definition: twolevelmethod.hh:52
    \n+
    A LeveTransferPolicy that used aggregation to construct the coarse level system.
    Definition: twolevelmethod.hh:143
    \n+
    C Criterion
    Definition: twolevelmethod.hh:147
    \n+
    AggregationLevelTransferPolicy(const Criterion &crit)
    Definition: twolevelmethod.hh:150
    \n+
    AggregationLevelTransferPolicy * clone() const
    Clone the current object.
    Definition: twolevelmethod.hh:214
    \n+
    void moveToFineLevel(typename FatherType::FineDomainType &fineLhs)
    Updates the fine level linear system after the correction of the coarse levels system.
    Definition: twolevelmethod.hh:207
    \n+
    void moveToCoarseLevel(const typename FatherType::FineRangeType &fineRhs)
    Definition: twolevelmethod.hh:200
    \n+
    SequentialInformation ParallelInformation
    Definition: twolevelmethod.hh:148
    \n+
    LevelTransferPolicy< O, O > FatherType
    Definition: twolevelmethod.hh:146
    \n+
    void createCoarseLevelSystem(const O &fineOperator)
    Algebraically creates the coarse level system.
    Definition: twolevelmethod.hh:154
    \n+
    A policy class for solving the coarse level system using one step of AMG.
    Definition: twolevelmethod.hh:234
    \n+
    OneStepAMGCoarseSolverPolicy(const SmootherArgs &args, const Criterion &c)
    Constructs the coarse solver policy.
    Definition: twolevelmethod.hh:253
    \n+
    AMGInverseOperator CoarseLevelSolver
    The type of solver constructed for the coarse level.
    Definition: twolevelmethod.hh:315
    \n+
    OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy &other)
    Copy constructor.
    Definition: twolevelmethod.hh:257
    \n+
    O::range_type X
    The type of the range and domain of the operator.
    Definition: twolevelmethod.hh:239
    \n+
    C Criterion
    The type of the crition used for the aggregation within AMG.
    Definition: twolevelmethod.hh:241
    \n+
    Dune::Amg::SmootherTraits< S >::Arguments SmootherArgs
    The type of the arguments used for constructing the smoother.
    Definition: twolevelmethod.hh:245
    \n+
    O Operator
    The type of the linear operator used.
    Definition: twolevelmethod.hh:237
    \n+
    AMG< Operator, X, Smoother > AMGType
    The type of the AMG construct on the coarse level.
    Definition: twolevelmethod.hh:247
    \n+
    CoarseLevelSolver * createCoarseLevelSolver(P &transferPolicy)
    Constructs a coarse level solver.
    Definition: twolevelmethod.hh:325
    \n+
    S Smoother
    The type of the smoother used in AMG.
    Definition: twolevelmethod.hh:243
    \n+
    Definition: twolevelmethod.hh:353
    \n+
    CoarseOperatorType::range_type CoarseRangeType
    The type of the range of the coarse level operator.
    Definition: twolevelmethod.hh:380
    \n+
    FineOperatorType::domain_type FineDomainType
    The type of the domain of the fine level operator.
    Definition: twolevelmethod.hh:371
    \n+
    TwoLevelMethod(const TwoLevelMethod &other)
    Definition: twolevelmethod.hh:418
    \n+
    void pre(FineDomainType &x, FineRangeType &b)
    Definition: twolevelmethod.hh:431
    \n+
    FO FineOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:363
    \n+
    CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver
    The type of the coarse level solver.
    Definition: twolevelmethod.hh:358
    \n+
    void apply(FineDomainType &v, const FineRangeType &d)
    Definition: twolevelmethod.hh:439
    \n+
    CSP CoarseLevelSolverPolicy
    The type of the policy for constructing the coarse level solver.
    Definition: twolevelmethod.hh:356
    \n+
    CoarseOperatorType::domain_type CoarseDomainType
    The type of the domain of the coarse level operator.
    Definition: twolevelmethod.hh:384
    \n+
    TwoLevelMethod(const FineOperatorType &op, std::shared_ptr< SmootherType > smoother, const LevelTransferPolicy< FineOperatorType, CoarseOperatorType > &policy, CoarseLevelSolverPolicy &coarsePolicy, std::size_t preSteps=1, std::size_t postSteps=1)
    Constructs a two level method.
    Definition: twolevelmethod.hh:404
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: twolevelmethod.hh:466
    \n+
    FineOperatorType::range_type FineRangeType
    The type of the range of the fine level operator.
    Definition: twolevelmethod.hh:367
    \n+
    ~TwoLevelMethod()
    Definition: twolevelmethod.hh:424
    \n+
    CSP::Operator CoarseOperatorType
    The linear operator of the finel level system. Has to be derived from AssembledLinearOperator.
    Definition: twolevelmethod.hh:376
    \n+
    void post(FineDomainType &x)
    Definition: twolevelmethod.hh:436
    \n+
    S SmootherType
    The type of the fine level smoother.
    Definition: twolevelmethod.hh:388
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)=0
    Apply inverse operator,.
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,1334 +5,666 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-smoother.hh\n+twolevelmethod.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMGSMOOTHER_HH\n- 6#define DUNE_AMGSMOOTHER_HH\n+ 5#ifndef DUNE_ISTL_TWOLEVELMETHOD_HH\n+ 6#define DUNE_ISTL_TWOLEVELMETHOD_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15\n- 16namespace Dune\n- 17{\n- 18 namespace Amg\n- 19 {\n- 20\n- 36 template\n-37 struct DefaultSmootherArgs\n- 38 {\n-42 typedef typename FieldTraits::real_type RelaxationFactor;\n- 43\n-47 int iterations;\n-51 RelaxationFactor relaxationFactor;\n- 52\n-56 DefaultSmootherArgs()\n- 57 : iterations(1), relaxationFactor(1.0)\n- 58 {}\n- 59 };\n- 60\n- 64 template\n-65 struct SmootherTraits\n- 66 {\n-67 typedef DefaultSmootherArgs Arguments;\n- 68\n- 69 };\n- 70\n- 71 template\n-72 struct SmootherTraits>\n- 73 {\n-74 typedef DefaultSmootherArgs Arguments;\n- 75\n- 76 };\n- 77\n- 78 template\n-79 struct SmootherTraits >\n- 80 : public SmootherTraits\n- 81 {};\n+ 8#include \n+ 9\n+ 10#include\n+ 11#include\"amg.hh\"\n+ 12#include\"galerkin.hh\"\n+ 13#include\n+ 14\n+ 22namespace Dune\n+ 23{\n+ 24namespace Amg\n+ 25{\n+ 26\n+ 36template\n+37class LevelTransferPolicy\n+ 38{\n+ 39public:\n+44 typedef FO FineOperatorType;\n+48 typedef typename FineOperatorType::range_type FineRangeType;\n+52 typedef typename FineOperatorType::domain_type FineDomainType;\n+57 typedef CO CoarseOperatorType;\n+61 typedef typename CoarseOperatorType::range_type CoarseRangeType;\n+65 typedef typename CoarseOperatorType::domain_type CoarseDomainType;\n+70 std::shared_ptr& getCoarseLevelOperator()\n+ 71 {\n+ 72 return operator_;\n+ 73 }\n+78 CoarseRangeType& getCoarseLevelRhs()\n+ 79 {\n+ 80 return rhs_;\n+ 81 }\n 82\n- 83 template\n-84 struct SmootherTraits >\n- 85 : public SmootherTraits\n- 86 {};\n- 87\n- 91 template\n-92 class DefaultConstructionArgs\n- 93 {\n- 94 typedef typename T::matrix_type Matrix;\n- 95\n- 96 typedef typename SmootherTraits::Arguments SmootherArgs;\n- 97\n- 98 typedef Dune::Amg::AggregatesMap::\n-VertexDescriptor> AggregatesMap;\n- 99\n- 100 public:\n-101 virtual ~DefaultConstructionArgs()\n- 102 {}\n- 103\n-104 void setMatrix(const Matrix& matrix)\n- 105 {\n- 106 matrix_=&matrix;\n- 107 }\n-108 virtual void setMatrix(const Matrix& matrix, [[maybe_unused]] const\n-AggregatesMap& amap)\n- 109 {\n- 110 setMatrix(matrix);\n- 111 }\n- 112\n- 113\n-114 const Matrix& getMatrix() const\n- 115 {\n- 116 return *matrix_;\n- 117 }\n- 118\n-119 void setArgs(const SmootherArgs& args)\n- 120 {\n- 121 args_=&args;\n- 122 }\n- 123\n- 124 template\n-125 void setComm([[maybe_unused]] T1& comm)\n- 126 {}\n- 127\n-128 const SequentialInformation& getComm()\n- 129 {\n- 130 return comm_;\n- 131 }\n- 132\n-133 const SmootherArgs getArgs() const\n- 134 {\n- 135 return *args_;\n- 136 }\n- 137\n- 138 protected:\n-139 const Matrix* matrix_;\n- 140 private:\n- 141 const SmootherArgs* args_;\n- 142 SequentialInformation comm_;\n- 143 };\n- 144\n- 145 template\n-146 struct ConstructionArgs\n- 147 : public DefaultConstructionArgs\n- 148 {};\n+87 CoarseDomainType& getCoarseLevelLhs()\n+ 88 {\n+ 89 return lhs_;\n+ 90 }\n+100 virtual void moveToCoarseLevel(const FineRangeType& fineRhs)=0;\n+110 virtual void moveToFineLevel(FineDomainType& fineLhs)=0;\n+118 virtual void createCoarseLevelSystem(const FineOperatorType&\n+fineOperator)=0;\n+ 119\n+121 virtual LevelTransferPolicy* clone() const =0;\n+ 122\n+124 virtual ~LevelTransferPolicy(){}\n+ 125\n+ 126 protected:\n+128 CoarseRangeType rhs_;\n+130 CoarseDomainType lhs_;\n+132 std::shared_ptr operator_;\n+ 133};\n+ 134\n+ 140template\n+141class AggregationLevelTransferPolicy\n+ 142 : public LevelTransferPolicy\n+ 143{\n+ 144 typedef Dune::Amg::AggregatesMap\n+AggregatesMap;\n+ 145public:\n+146 typedef LevelTransferPolicy FatherType;\n+147 typedef C Criterion;\n+148 typedef SequentialInformation ParallelInformation;\n 149\n- 150 template\n-151 class DefaultParallelConstructionArgs\n- 152 : public ConstructionArgs\n- 153 {\n- 154 public:\n-155 virtual ~DefaultParallelConstructionArgs()\n- 156 {}\n- 157\n-158 void setComm(const C& comm)\n- 159 {\n- 160 comm_ = &comm;\n- 161 }\n- 162\n-163 const C& getComm() const\n- 164 {\n- 165 return *comm_;\n- 166 }\n- 167 private:\n- 168 const C* comm_;\n- 169 };\n- 170\n- 171\n- 172 template\n-173 class DefaultConstructionArgs>\n- 174 {\n- 175 typedef Richardson T;\n- 176\n- 177 typedef typename SmootherTraits::Arguments SmootherArgs;\n- 178\n- 179 public:\n-180 virtual ~DefaultConstructionArgs()\n- 181 {}\n- 182\n- 183 template \n-184 void setMatrix(const Args&...)\n- 185 {}\n- 186\n-187 void setArgs(const SmootherArgs& args)\n- 188 {\n- 189 args_=&args;\n- 190 }\n- 191\n- 192 template\n-193 void setComm([[maybe_unused]] T1& comm)\n- 194 {}\n- 195\n-196 const SequentialInformation& getComm()\n- 197 {\n- 198 return comm_;\n- 199 }\n- 200\n-201 const SmootherArgs getArgs() const\n- 202 {\n- 203 return *args_;\n- 204 }\n- 205\n- 206 private:\n- 207 const SmootherArgs* args_;\n- 208 SequentialInformation comm_;\n- 209 };\n- 210\n- 211\n- 212\n- 213 template\n- 214 struct ConstructionTraits;\n- 215\n- 219 template\n-220 struct ConstructionTraits >\n- 221 {\n-222 typedef DefaultConstructionArgs > Arguments;\n- 223\n-224 static inline std::shared_ptr> construct(Arguments& args)\n- 225 {\n- 226 return std::make_shared>\n- 227 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n-().relaxationFactor);\n- 228 }\n- 229 };\n- 230\n- 231\n- 235 template\n-236 struct ConstructionTraits >\n- 237 {\n-238 typedef DefaultConstructionArgs > Arguments;\n- 239\n-240 static inline std::shared_ptr> construct(Arguments& args)\n- 241 {\n- 242 return std::make_shared>\n- 243 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n-().relaxationFactor);\n- 244 }\n- 245 };\n- 246\n- 247\n- 251 template\n-252 struct ConstructionTraits >\n- 253 {\n-254 typedef DefaultConstructionArgs > Arguments;\n- 255\n-256 static inline std::shared_ptr> construct(Arguments& args)\n- 257 {\n- 258 return std::make_shared>\n- 259 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n-().relaxationFactor);\n- 260 }\n- 261 };\n- 262\n- 266 template\n-267 struct ConstructionTraits >\n- 268 {\n-269 typedef DefaultConstructionArgs > Arguments;\n- 270\n-271 static inline std::shared_ptr> construct(Arguments& args)\n- 272 {\n- 273 return std::make_shared>\n- 274 (args.getArgs().relaxationFactor);\n- 275 }\n- 276 };\n- 277\n- 278\n- 279 template\n-280 class ConstructionArgs >\n- 281 : public DefaultConstructionArgs >\n- 282 {\n- 283 public:\n-284 ConstructionArgs(int n=0)\n- 285 : n_(n)\n- 286 {}\n- 287\n-288 void setN(int n)\n- 289 {\n- 290 n_ = n;\n- 291 }\n- 292\n-293 int getN()\n+150 AggregationLevelTransferPolicy(const Criterion& crit)\n+ 151 : criterion_(crit)\n+ 152 {}\n+ 153\n+154 void createCoarseLevelSystem(const O& fineOperator)\n+ 155 {\n+ 156 prolongDamp_ = criterion_.getProlongationDampingFactor();\n+ 157 GalerkinProduct productBuilder;\n+ 158 typedef typename Dune::Amg::MatrixGraph\n+MatrixGraph;\n+ 159 typedef typename Dune::Amg::PropertiesGraph\n+PropertiesGraph;\n+ 161 MatrixGraph mg(fineOperator.getmat());\n+ 162 PropertiesGraph pg(mg,Dune::IdentityMap(),Dune::IdentityMap());\n+ 163 typedef NegateSet OverlapFlags;\n+ 164\n+ 165 aggregatesMap_ = std::make_shared(pg.maxVertex()+1);\n+ 166\n+ 167 int noAggregates, isoAggregates, oneAggregates, skippedAggregates;\n+ 168\n+ 169 std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =\n+ 170 aggregatesMap_->buildAggregates(fineOperator.getmat(), pg, criterion_,\n+true);\n+ 171 std::cout<<\"no aggregates=\"<\n+renumberer;\n+ 174 typedef std::vector::iterator Iterator;\n+ 175 typedef Dune::IteratorPropertyMap VisitedMap;\n+ 176 std::vector excluded(fineOperator.getmat().N(), false);\n+ 177 VisitedMap vm(excluded.begin(), Dune::IdentityMap());\n+ 178 ParallelInformation pinfo;\n+ 179 std::size_t aggregates = renumberer.coarsen(pinfo, pg, vm,\n+ 180 *aggregatesMap_, pinfo,\n+ 181 noAggregates);\n+ 182 std::vector& visited=excluded;\n+ 183\n+ 184 typedef std::vector::iterator Iterator;\n+ 185\n+ 186 for(Iterator iter= visited.begin(), end=visited.end();\n+ 187 iter != end; ++iter)\n+ 188 *iter=false;\n+ 189 matrix_.reset(productBuilder.build(mg, vm,\n+ 190 SequentialInformation(),\n+ 191 *aggregatesMap_,\n+ 192 aggregates,\n+ 193 OverlapFlags()));\n+ 194 productBuilder.calculate(fineOperator.getmat(), *aggregatesMap_, *matrix_,\n+pinfo, OverlapFlags());\n+ 195 this->lhs_.resize(this->matrix_->M());\n+ 196 this->rhs_.resize(this->matrix_->N());\n+ 197 this->operator_ = std::make_shared(*matrix_);\n+ 198 }\n+ 199\n+200 void moveToCoarseLevel(const typename FatherType::FineRangeType& fineRhs)\n+ 201 {\n+ 202 Transfer\n+ 203::restrictVector(*aggregatesMap_, this->rhs_, fineRhs, ParallelInformation\n+());\n+ 204 this->lhs_=0;\n+ 205 }\n+ 206\n+207 void moveToFineLevel(typename FatherType::FineDomainType& fineLhs)\n+ 208 {\n+ 209 Transfer\n+ 210::prolongateVector(*aggregatesMap_, this->lhs_, fineLhs,\n+ 211 prolongDamp_, ParallelInformation());\n+ 212 }\n+ 213\n+214 AggregationLevelTransferPolicy* clone() const\n+ 215 {\n+ 216 return new AggregationLevelTransferPolicy(*this);\n+ 217 }\n+ 218\n+ 219private:\n+ 220 typename O::matrix_type::field_type prolongDamp_;\n+ 221 std::shared_ptr aggregatesMap_;\n+ 222 Criterion criterion_;\n+ 223 std::shared_ptr matrix_;\n+ 224};\n+ 225\n+ 232template\n+233class OneStepAMGCoarseSolverPolicy\n+ 234{\n+ 235public:\n+237 typedef O Operator;\n+239 typedef typename O::range_type X;\n+241 typedef C Criterion;\n+243 typedef S Smoother;\n+245 typedef typename Dune::Amg::SmootherTraits::Arguments SmootherArgs;\n+247 typedef AMG AMGType;\n+253 OneStepAMGCoarseSolverPolicy(const SmootherArgs& args, const Criterion& c)\n+ 254 : smootherArgs_(args), criterion_(c)\n+ 255 {}\n+257 OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy& other)\n+ 258 : coarseOperator_(other.coarseOperator_), smootherArgs_\n+(other.smootherArgs_),\n+ 259 criterion_(other.criterion_)\n+ 260 {}\n+ 261private:\n+ 268 struct AMGInverseOperator : public InverseOperator\n+ 269 {\n+ 270 AMGInverseOperator(const typename AMGType::Operator& op,\n+ 271 const Criterion& crit,\n+ 272 const typename AMGType::SmootherArgs& args)\n+ 273 : amg_(op, crit,args), first_(true)\n+ 274 {}\n+ 275\n+ 276 void apply(X& x, X& b, [[maybe_unused]] double reduction, [[maybe_unused]]\n+InverseOperatorResult& res)\n+ 277 {\n+ 278 if(first_)\n+ 279 {\n+ 280 amg_.pre(x,b);\n+ 281 first_=false;\n+ 282 x_=x;\n+ 283 }\n+ 284 amg_.apply(x,b);\n+ 285 }\n+ 286\n+ 287 void apply(X& x, X& b, InverseOperatorResult& res)\n+ 288 {\n+ 289 return apply(x,b,1e-8,res);\n+ 290 }\n+ 291\n+ 293 virtual SolverCategory::Category category() const\n 294 {\n- 295 return n_;\n+ 295 return amg_.category();\n 296 }\n 297\n- 298 private:\n- 299 int n_;\n- 300 };\n- 301\n- 302\n- 306 template\n-307 struct ConstructionTraits >\n- 308 {\n-309 typedef ConstructionArgs > Arguments;\n- 310\n-311 static inline std::shared_ptr> construct(Arguments& args)\n- 312 {\n- 313 return std::make_shared>\n- 314 (args.getMatrix(), args.getN(), args.getArgs().relaxationFactor);\n- 315 }\n- 316 };\n- 317\n- 321 template\n-322 struct ConstructionTraits >\n- 323 {\n-324 typedef DefaultParallelConstructionArgs Arguments;\n- 325\n-326 static inline std::shared_ptr> construct(Arguments& args)\n- 327 {\n- 328 return std::make_shared>\n- 329 (args.getMatrix(), args.getArgs().iterations,\n- 330 args.getArgs().relaxationFactor, args.getComm());\n- 331 }\n- 332 };\n+ 298 ~AMGInverseOperator()\n+ 299 {\n+ 300 if(!first_)\n+ 301 amg_.post(x_);\n+ 302 }\n+ 303 AMGInverseOperator(const AMGInverseOperator& other)\n+ 304 : x_(other.x_), amg_(other.amg_), first_(other.first_)\n+ 305 {\n+ 306 }\n+ 307 private:\n+ 308 X x_;\n+ 309 AMGType amg_;\n+ 310 bool first_;\n+ 311 };\n+ 312\n+ 313public:\n+315 typedef AMGInverseOperator CoarseLevelSolver;\n+ 316\n+ 324 template\n+325 CoarseLevelSolver* createCoarseLevelSolver(P& transferPolicy)\n+ 326 {\n+ 327 coarseOperator_=transferPolicy.getCoarseLevelOperator();\n+ 328 AMGInverseOperator* inv = new AMGInverseOperator(*coarseOperator_,\n+ 329 criterion_,\n+ 330 smootherArgs_);\n+ 331\n+ 332 return inv; //std::shared_ptr >(inv);\n 333\n- 334 template\n-335 struct ConstructionTraits >\n- 336 {\n-337 typedef DefaultParallelConstructionArgs Arguments;\n-338 typedef ConstructionTraits SeqConstructionTraits;\n-339 static inline std::shared_ptr> construct\n-(Arguments& args)\n- 340 {\n- 341 auto seqPrec = SeqConstructionTraits::construct(args);\n- 342 return std::make_shared> (seqPrec,\n-args.getComm());\n- 343 }\n- 344 };\n- 345\n- 346 template\n-347 struct ConstructionTraits >\n- 348 {\n-349 typedef DefaultParallelConstructionArgs Arguments;\n-350 typedef ConstructionTraits SeqConstructionTraits;\n-351 static inline std::shared_ptr>\n-construct(Arguments& args)\n- 352 {\n- 353 auto seqPrec = SeqConstructionTraits::construct(args);\n- 354 return std::make_shared> (seqPrec,\n-args.getComm());\n- 355 }\n- 356 };\n- 357\n- 368 template\n-369 struct SmootherApplier\n- 370 {\n-371 typedef T Smoother;\n-372 typedef typename Smoother::range_type Range;\n-373 typedef typename Smoother::domain_type Domain;\n- 374\n-382 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)\n- 383 {\n- 384 smoother.apply(v,d);\n- 385 }\n- 386\n-394 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)\n- 395 {\n- 396 smoother.apply(v,d);\n- 397 }\n- 398 };\n- 399\n- 405 template\n-406 void presmooth(LevelContext& levelContext, size_t steps)\n- 407 {\n- 408 for(std::size_t i=0; i < steps; ++i) {\n- 409 *levelContext.lhs=0;\n- 410 SmootherApplier\n- 411::preSmooth(*levelContext.smoother, *levelContext.lhs,\n- 412 *levelContext.rhs);\n- 413 // Accumulate update\n- 414 *levelContext.update += *levelContext.lhs;\n- 415\n- 416 // update defect\n- 417 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,\n-*levelContext.rhs);\n- 418 levelContext.pinfo->project(*levelContext.rhs);\n- 419 }\n- 420 }\n- 421\n- 427 template\n-428 void postsmooth(LevelContext& levelContext, size_t steps)\n- 429 {\n- 430 for(std::size_t i=0; i < steps; ++i) {\n- 431 // update defect\n- 432 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,\n- 433 *levelContext.rhs);\n- 434 *levelContext.lhs=0;\n- 435 levelContext.pinfo->project(*levelContext.rhs);\n- 436 SmootherApplier\n- 437::postSmooth(*levelContext.smoother, *levelContext.lhs, *levelContext.rhs);\n- 438 // Accumulate update\n- 439 *levelContext.update += *levelContext.lhs;\n- 440 }\n- 441 }\n- 442\n- 443 template\n-444 struct SmootherApplier >\n- 445 {\n-446 typedef SeqSOR Smoother;\n-447 typedef typename Smoother::range_type Range;\n-448 typedef typename Smoother::domain_type Domain;\n- 449\n-450 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n- 451 {\n- 452 smoother.template apply(v,d);\n- 453 }\n- 454\n- 455\n-456 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n- 457 {\n- 458 smoother.template apply(v,d);\n- 459 }\n- 460 };\n- 461\n- 462 template\n-463 struct SmootherApplier > >\n- 464 {\n-465 typedef BlockPreconditioner > Smoother;\n-466 typedef typename Smoother::range_type Range;\n-467 typedef typename Smoother::domain_type Domain;\n- 468\n-469 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n- 470 {\n- 471 smoother.template apply(v,d);\n- 472 }\n- 473\n- 474\n-475 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 334 }\n+ 335\n+ 336private:\n+ 338 std::shared_ptr coarseOperator_;\n+ 340 SmootherArgs smootherArgs_;\n+ 342 Criterion criterion_;\n+ 343};\n+ 344\n+ 350template\n+351class TwoLevelMethod :\n+ 352 public Preconditioner\n+ 353{\n+ 354public:\n+356 typedef CSP CoarseLevelSolverPolicy;\n+358 typedef typename CoarseLevelSolverPolicy::CoarseLevelSolver\n+CoarseLevelSolver;\n+363 typedef FO FineOperatorType;\n+367 typedef typename FineOperatorType::range_type FineRangeType;\n+371 typedef typename FineOperatorType::domain_type FineDomainType;\n+376 typedef typename CSP::Operator CoarseOperatorType;\n+380 typedef typename CoarseOperatorType::range_type CoarseRangeType;\n+384 typedef typename CoarseOperatorType::domain_type CoarseDomainType;\n+388 typedef S SmootherType;\n+ 389\n+404 TwoLevelMethod(const FineOperatorType& op,\n+ 405 std::shared_ptr smoother,\n+ 406 const LevelTransferPolicy& policy,\n+ 408 CoarseLevelSolverPolicy& coarsePolicy,\n+ 409 std::size_t preSteps=1, std::size_t postSteps=1)\n+ 410 : operator_(&op), smoother_(smoother),\n+ 411 preSteps_(preSteps), postSteps_(postSteps)\n+ 412 {\n+ 413 policy_ = policy.clone();\n+ 414 policy_->createCoarseLevelSystem(*operator_);\n+ 415 coarseSolver_=coarsePolicy.createCoarseLevelSolver(*policy_);\n+ 416 }\n+ 417\n+418 TwoLevelMethod(const TwoLevelMethod& other)\n+ 419 : operator_(other.operator_), coarseSolver_(new CoarseLevelSolver\n+(*other.coarseSolver_)),\n+ 420 smoother_(other.smoother_), policy_(other.policy_->clone()),\n+ 421 preSteps_(other.preSteps_), postSteps_(other.postSteps_)\n+ 422 {}\n+ 423\n+424 ~TwoLevelMethod()\n+ 425 {\n+ 426 // Each instance has its own policy.\n+ 427 delete policy_;\n+ 428 delete coarseSolver_;\n+ 429 }\n+ 430\n+431 void pre(FineDomainType& x, FineRangeType& b)\n+ 432 {\n+ 433 smoother_->pre(x,b);\n+ 434 }\n+ 435\n+436 void post([[maybe_unused]] FineDomainType& x)\n+ 437 {}\n+ 438\n+439 void apply(FineDomainType& v, const FineRangeType& d)\n+ 440 {\n+ 441 FineDomainType u(v);\n+ 442 FineRangeType rhs(d);\n+ 443 LevelContext context;\n+ 444 SequentialInformation info;\n+ 445 context.pinfo=&info;\n+ 446 context.lhs=&u;\n+ 447 context.update=&v;\n+ 448 context.smoother=smoother_;\n+ 449 context.rhs=&rhs;\n+ 450 context.matrix=operator_;\n+ 451 // Presmoothing\n+ 452 presmooth(context, preSteps_);\n+ 453 //Coarse grid correction\n+ 454 policy_->moveToCoarseLevel(*context.rhs);\n+ 455 InverseOperatorResult res;\n+ 456 coarseSolver_->apply(policy_->getCoarseLevelLhs(), policy_-\n+>getCoarseLevelRhs(), res);\n+ 457 *context.lhs=0;\n+ 458 policy_->moveToFineLevel(*context.lhs);\n+ 459 *context.update += *context.lhs;\n+ 460 // Postsmoothing\n+ 461 postsmooth(context, postSteps_);\n+ 462\n+ 463 }\n+ 464\n+466 virtual SolverCategory::Category category() const\n+ 467 {\n+ 468 return SolverCategory::sequential;\n+ 469 }\n+ 470\n+ 471private:\n+ 475 struct LevelContext\n 476 {\n- 477 smoother.template apply(v,d);\n- 478 }\n- 479 };\n- 480\n- 481 template\n-482 struct SmootherApplier\n-> >\n- 483 {\n-484 typedef NonoverlappingBlockPreconditioner > Smoother;\n-485 typedef typename Smoother::range_type Range;\n-486 typedef typename Smoother::domain_type Domain;\n- 487\n-488 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n- 489 {\n- 490 smoother.template apply(v,d);\n- 491 }\n- 492\n- 493\n-494 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n- 495 {\n- 496 smoother.template apply(v,d);\n- 497 }\n- 498 };\n- 499\n- 500 } // end namespace Amg\n- 501\n- 502 // forward declarations\n- 503 template\n- 504 class SeqOverlappingSchwarz;\n- 505\n- 506 struct MultiplicativeSchwarzMode;\n- 507\n- 508 namespace Amg\n- 509 {\n- 510 template\n-511 struct SmootherApplier >\n- 513 {\n-514 typedef SeqOverlappingSchwarz\n-Smoother;\n-515 typedef typename Smoother::range_type Range;\n-516 typedef typename Smoother::domain_type Domain;\n- 517\n-518 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)\n- 519 {\n- 520 smoother.template apply(v,d);\n- 521 }\n- 522\n- 523\n-524 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)\n- 525 {\n- 526 smoother.template apply(v,d);\n- 527\n- 528 }\n- 529 };\n- 530\n- 531 // template\n- 532 // class SeqOverlappingSchwarz;\n- 533\n- 534 template\n-535 struct SeqOverlappingSchwarzSmootherArgs\n- 536 : public DefaultSmootherArgs\n- 537 {\n-538 enum Overlap {vertex, aggregate, pairwise, none};\n- 539\n-540 Overlap overlap;\n-541 bool onthefly;\n- 542\n-543 SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex,\n- 544 bool onthefly_=false)\n- 545 : overlap(overlap_), onthefly(onthefly_)\n- 546 {}\n- 547 };\n- 548\n- 549 template\n-550 struct SmootherTraits >\n- 551 {\n-552 typedef SeqOverlappingSchwarzSmootherArgs\n-Arguments;\n- 553 };\n- 554\n- 555 template\n-556 class ConstructionArgs >\n- 557 : public DefaultConstructionArgs >\n- 558 {\n- 559 typedef DefaultConstructionArgs >\n-Father;\n- 560\n- 561 public:\n-562 typedef typename MatrixGraph::VertexDescriptor VertexDescriptor;\n-563 typedef Dune::Amg::AggregatesMap AggregatesMap;\n-564 typedef typename AggregatesMap::AggregateDescriptor AggregateDescriptor;\n-565 typedef typename SeqOverlappingSchwarz::subdomain_vector\n-Vector;\n-566 typedef typename Vector::value_type Subdomain;\n- 567\n-568 virtual void setMatrix(const M& matrix, const AggregatesMap& amap)\n- 569 {\n- 570 Father::setMatrix(matrix);\n- 571\n- 572 std::vector visited(amap.noVertices(), false);\n- 573 typedef IteratorPropertyMap::iterator,IdentityMap>\n-VisitedMapType;\n- 574 VisitedMapType visitedMap(visited.begin());\n- 575\n- 576 MatrixGraph graph(matrix);\n- 577\n- 578 typedef SeqOverlappingSchwarzSmootherArgs\n-SmootherArgs;\n- 579\n- 580 switch(Father::getArgs().overlap) {\n- 581 case SmootherArgs::vertex :\n- 582 {\n- 583 VertexAdder visitor(subdomains, amap);\n- 584 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 585 }\n- 586 break;\n- 587 case SmootherArgs::pairwise :\n- 588 {\n- 589 createPairDomains(graph);\n- 590 }\n- 591 break;\n- 592 case SmootherArgs::aggregate :\n- 593 {\n- 594 AggregateAdder visitor(subdomains, amap, graph,\n-visitedMap);\n- 595 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 596 }\n- 597 break;\n- 598 case SmootherArgs::none :\n- 599 NoneAdder visitor;\n- 600 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 601 break;\n- 602 default :\n- 603 DUNE_THROW(NotImplemented, \"This overlapping scheme is not supported!\");\n- 604 }\n- 605 }\n-606 void setMatrix(const M& matrix)\n- 607 {\n- 608 Father::setMatrix(matrix);\n- 609\n- 610 /* Create aggregates map where each aggregate is just one vertex. */\n- 611 AggregatesMap amap(matrix.N());\n- 612 VertexDescriptor v=0;\n- 613 for(typename AggregatesMap::iterator iter=amap.begin();\n- 614 iter!=amap.end(); ++iter)\n- 615 *iter=v++;\n- 616\n- 617 std::vector visited(amap.noVertices(), false);\n- 618 typedef IteratorPropertyMap::iterator,IdentityMap>\n-VisitedMapType;\n- 619 VisitedMapType visitedMap(visited.begin());\n- 620\n- 621 MatrixGraph graph(matrix);\n- 622\n- 623 typedef SeqOverlappingSchwarzSmootherArgs\n-SmootherArgs;\n- 624\n- 625 switch(Father::getArgs().overlap) {\n- 626 case SmootherArgs::vertex :\n- 627 {\n- 628 VertexAdder visitor(subdomains, amap);\n- 629 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 630 }\n- 631 break;\n- 632 case SmootherArgs::aggregate :\n- 633 {\n- 634 DUNE_THROW(NotImplemented, \"Aggregate overlap is not supported yet\");\n- 635 /*\n- 636 AggregateAdder visitor(subdomains, amap, graph,\n-visitedMap);\n- 637 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 638 */\n- 639 }\n- 640 break;\n- 641 case SmootherArgs::pairwise :\n- 642 {\n- 643 createPairDomains(graph);\n- 644 }\n- 645 break;\n- 646 case SmootherArgs::none :\n- 647 NoneAdder visitor;\n- 648 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n- 649\n- 650 }\n- 651 }\n- 652\n-653 const Vector& getSubDomains()\n- 654 {\n- 655 return subdomains;\n- 656 }\n- 657\n- 658 private:\n- 659 struct VertexAdder\n- 660 {\n-661 VertexAdder(Vector& subdomains_, const AggregatesMap& aggregates_)\n- 662 : subdomains(subdomains_), max(-1), subdomain(-1), aggregates(aggregates_)\n- 663 {}\n- 664 template\n-665 void operator()(const T& edge)\n- 666 {\n- 667 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED)\n- 668 subdomains[subdomain].insert(edge.target());\n- 669 }\n-670 int setAggregate(const AggregateDescriptor& aggregate_)\n- 671 {\n- 672 subdomain=aggregate_;\n- 673 max = std::max(subdomain, aggregate_);\n- 674 return subdomain;\n- 675 }\n-676 int noSubdomains() const\n- 677 {\n- 678 return max+1;\n- 679 }\n- 680 private:\n- 681 Vector& subdomains;\n- 682 AggregateDescriptor max;\n- 683 AggregateDescriptor subdomain;\n- 684 const AggregatesMap& aggregates;\n- 685 };\n- 686 struct NoneAdder\n- 687 {\n- 688 template\n-689 void operator()(const T& edge)\n- 690 {}\n-691 int setAggregate(const AggregateDescriptor& aggregate_)\n- 692 {\n- 693 return -1;\n- 694 }\n-695 int noSubdomains() const\n- 696 {\n- 697 return -1;\n- 698 }\n- 699 };\n- 700\n- 701 template\n- 702 struct AggregateAdder\n- 703 {\n-704 AggregateAdder(Vector& subdomains_, const AggregatesMap& aggregates_,\n- 705 const MatrixGraph& graph_, VM& visitedMap_)\n- 706 : subdomains(subdomains_), subdomain(-1), aggregates(aggregates_),\n- 707 adder(subdomains_, aggregates_), graph(graph_), visitedMap(visitedMap_)\n- 708 {}\n- 709 template\n-710 void operator()(const T& edge)\n- 711 {\n- 712 subdomains[subdomain].insert(edge.target());\n- 713 // If we (the neighbouring vertex of the aggregate)\n- 714 // are not isolated, add the aggregate we belong to\n- 715 // to the same subdomain using the OneOverlapAdder\n- 716 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED) {\n- 717 assert(aggregates[edge.target()]!=aggregate);\n- 718 typename AggregatesMap::VertexList vlist;\n- 719 aggregates.template breadthFirstSearch(edge.target(),\n-aggregate,\n- 720 graph, vlist, adder, adder,\n- 721 visitedMap);\n- 722 }\n- 723 }\n- 724\n-725 int setAggregate(const AggregateDescriptor& aggregate_)\n- 726 {\n- 727 adder.setAggregate(aggregate_);\n- 728 aggregate=aggregate_;\n- 729 return ++subdomain;\n- 730 }\n-731 int noSubdomains() const\n- 732 {\n- 733 return subdomain+1;\n- 734 }\n- 735\n- 736 private:\n- 737 AggregateDescriptor aggregate;\n- 738 Vector& subdomains;\n- 739 int subdomain;\n- 740 const AggregatesMap& aggregates;\n- 741 VertexAdder adder;\n- 742 const MatrixGraph& graph;\n- 743 VM& visitedMap;\n- 744 };\n- 745\n- 746 void createPairDomains(const MatrixGraph& graph)\n- 747 {\n- 748 typedef typename MatrixGraph::ConstVertexIterator VIter;\n- 749 typedef typename MatrixGraph::ConstEdgeIterator EIter;\n- 750 typedef typename M::size_type size_type;\n- 751\n- 752 std::set > pairs;\n- 753 int total=0;\n- 754 for(VIter v=graph.begin(), ve=graph.end(); ve != v; ++v)\n- 755 for(EIter e = v.begin(), ee=v.end(); ee!=e; ++e)\n- 756 {\n- 757 ++total;\n- 758 if(e.source() >::const_iterator\n-SIter;\n- 768 typename Vector::iterator subdomain=subdomains.begin();\n- 769\n- 770 for(SIter s=pairs.begin(), se =pairs.end(); se!=s; ++s)\n- 771 {\n- 772 subdomain->insert(s->first);\n- 773 subdomain->insert(s->second);\n- 774 ++subdomain;\n- 775 }\n- 776 std::size_t minsize=10000;\n- 777 std::size_t maxsize=0;\n- 778 int sum=0;\n- 779 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {\n- 780 sum+=subdomains[i].size();\n- 781 minsize=std::min(minsize, subdomains[i].size());\n- 782 maxsize=std::max(maxsize, subdomains[i].size());\n- 783 }\n- 784 Dune::dinfo<<\"Subdomain size: min=\"<\n- 789 void createSubdomains(const M& matrix, const MatrixGraph& graph,\n- 790 const AggregatesMap& amap, Visitor& overlapVisitor,\n- 791 IteratorPropertyMap::iterator,IdentityMap>& visitedMap )\n- 792 {\n- 793 // count number ag aggregates. We assume that the\n- 794 // aggregates are numbered consecutively from 0 except\n- 795 // for the isolated ones. All isolated vertices form\n- 796 // one aggregate, here.\n- 797 int isolated=0;\n- 798 AggregateDescriptor maxAggregate=0;\n- 799\n- 800 for(std::size_t i=0; i < amap.noVertices(); ++i)\n- 801 if(amap[i]==AggregatesMap::ISOLATED)\n- 802 isolated++;\n- 803 else\n- 804 maxAggregate = std::max(maxAggregate, amap[i]);\n- 805\n- 806 subdomains.resize(maxAggregate+1+isolated);\n- 807\n- 808 // reset the subdomains\n- 809 for(typename Vector::size_type i=0; i < subdomains.size(); ++i)\n- 810 subdomains[i].clear();\n- 811\n- 812 // Create the subdomains from the aggregates mapping.\n- 813 // For each aggregate we mark all entries and the\n- 814 // neighbouring vertices as belonging to the same subdomain\n- 815 VertexAdder aggregateVisitor(subdomains, amap);\n- 816\n- 817 for(VertexDescriptor i=0; i < amap.noVertices(); ++i)\n- 818 if(!get(visitedMap, i)) {\n- 819 AggregateDescriptor aggregate=amap[i];\n- 820\n- 821 if(amap[i]==AggregatesMap::ISOLATED) {\n- 822 // isolated vertex gets its own aggregate\n- 823 subdomains.push_back(Subdomain());\n- 824 aggregate=subdomains.size()-1;\n- 825 }\n- 826 overlapVisitor.setAggregate(aggregate);\n- 827 aggregateVisitor.setAggregate(aggregate);\n- 828 subdomains[aggregate].insert(i);\n- 829 typename AggregatesMap::VertexList vlist;\n- 830 amap.template breadthFirstSearch(i, aggregate, graph, vlist,\n-aggregateVisitor,\n- 831 overlapVisitor, visitedMap);\n- 832 }\n- 833\n- 834 std::size_t minsize=10000;\n- 835 std::size_t maxsize=0;\n- 836 int sum=0;\n- 837 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {\n- 838 sum+=subdomains[i].size();\n- 839 minsize=std::min(minsize, subdomains[i].size());\n- 840 maxsize=std::max(maxsize, subdomains[i].size());\n- 841 }\n- 842 Dune::dinfo<<\"Subdomain size: min=\"<\n-853 struct ConstructionTraits >\n- 854 {\n-855 typedef ConstructionArgs > Arguments;\n- 856\n-857 static inline std::shared_ptr>\n-construct(Arguments& args)\n- 858 {\n- 859 return std::make_shared>\n- 860 (args.getMatrix(),\n- 861 args.getSubDomains(),\n- 862 args.getArgs().relaxationFactor,\n- 863 args.getArgs().onthefly);\n- 864 }\n- 865 };\n- 866\n- 867\n- 868 } // namespace Amg\n- 869} // namespace Dune\n- 870\n- 871\n- 872\n- 873#endif\n-preconditioners.hh\n-Define general preconditioner interface.\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n-construction.hh\n-Helper classes for the construction of classes without empty constructor.\n-schwarz.hh\n-novlpschwarz.hh\n-Dune::Amg::SmootherTraits<_Richardson<_X,_Y_>_>::Arguments\n-DefaultSmootherArgs< typename X::field_type > Arguments\n-Definition: smoother.hh:74\n-Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n-Y,_l_>_>_>::postSmooth\n-static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:494\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-NoneAdder::operator()\n-void operator()(const T &edge)\n-Definition: smoother.hh:689\n-Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n-MultiplicativeSchwarzMode,_MS,_TA_>_>::preSmooth\n-static void preSmooth(Smoother &smoother, Domain &v, const Range &d)\n-Definition: smoother.hh:518\n-Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>::construct\n-static std::shared_ptr< SeqJac< M, X, Y, l > > construct(Arguments &args)\n-Definition: smoother.hh:256\n-Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>::Arguments\n-ConstructionArgs< SeqILU< M, X, Y > > Arguments\n-Definition: smoother.hh:309\n-Dune::Amg::DefaultConstructionArgs::getMatrix\n-const Matrix & getMatrix() const\n-Definition: smoother.hh:114\n-Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n-MultiplicativeSchwarzMode,_MS,_TA_>_>::Range\n-Smoother::range_type Range\n-Definition: smoother.hh:515\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-NoneAdder::setAggregate\n-int setAggregate(const AggregateDescriptor &aggregate_)\n-Definition: smoother.hh:691\n-Dune::Amg::SmootherTraits::Arguments\n-DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments\n-Definition: smoother.hh:67\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-VertexAdder::setAggregate\n-int setAggregate(const AggregateDescriptor &aggregate_)\n-Definition: smoother.hh:670\n-Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n-SeqConstructionTraits\n-ConstructionTraits< T > SeqConstructionTraits\n-Definition: smoother.hh:350\n-Dune::Amg::DefaultConstructionArgs::setArgs\n-void setArgs(const SmootherArgs &args)\n-Definition: smoother.hh:119\n-Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-Arguments\n-ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Arguments\n-Definition: smoother.hh:855\n-Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n-Y,_l_>_>_>::Smoother\n-NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > Smoother\n-Definition: smoother.hh:484\n-Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::postSmooth\n-static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:456\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregateAdder::AggregateAdder\n-AggregateAdder(Vector &subdomains_, const AggregatesMap &aggregates_, const\n-MatrixGraph< const M > &graph_, VM &visitedMap_)\n-Definition: smoother.hh:704\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::Overlap\n-Overlap\n-Definition: smoother.hh:538\n-Dune::Amg::DefaultParallelConstructionArgs::setComm\n-void setComm(const C &comm)\n-Definition: smoother.hh:158\n-Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>::Arguments\n-DefaultConstructionArgs< Richardson< X, Y > > Arguments\n-Definition: smoother.hh:269\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::\n-~DefaultConstructionArgs\n-virtual ~DefaultConstructionArgs()\n-Definition: smoother.hh:180\n-Dune::Amg::SmootherTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-Arguments\n-SeqOverlappingSchwarzSmootherArgs< typename M::field_type > Arguments\n-Definition: smoother.hh:552\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-Subdomain\n-Vector::value_type Subdomain\n-Definition: smoother.hh:566\n-Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n-Y,_l_>_>_>::preSmooth\n-static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:488\n-Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::getN\n-int getN()\n-Definition: smoother.hh:293\n-Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n-Y,_l_>_>_>::Range\n-Smoother::range_type Range\n-Definition: smoother.hh:485\n-Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Smoother\n-SeqSOR< M, X, Y, l > Smoother\n-Definition: smoother.hh:446\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregateAdder::operator()\n-void operator()(const T &edge)\n-Definition: smoother.hh:710\n-Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>::construct\n-static std::shared_ptr< SeqSSOR< M, X, Y, l > > construct(Arguments &args)\n-Definition: smoother.hh:224\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregateDescriptor\n-AggregatesMap::AggregateDescriptor AggregateDescriptor\n-Definition: smoother.hh:564\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::onthefly\n-bool onthefly\n-Definition: smoother.hh:541\n-Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>::Arguments\n-DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments\n-Definition: smoother.hh:238\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-setMatrix\n-virtual void setMatrix(const M &matrix, const AggregatesMap &amap)\n-Definition: smoother.hh:568\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setMatrix\n-void setMatrix(const Args &...)\n-Definition: smoother.hh:184\n-Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>::Arguments\n-DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments\n-Definition: smoother.hh:254\n-Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>::Arguments\n-DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments\n-Definition: smoother.hh:222\n-Dune::Amg::DefaultConstructionArgs::getArgs\n-const SmootherArgs getArgs() const\n-Definition: smoother.hh:133\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-VertexAdder::VertexAdder\n-VertexAdder(Vector &subdomains_, const AggregatesMap &aggregates_)\n-Definition: smoother.hh:661\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-getSubDomains\n-const Vector & getSubDomains()\n-Definition: smoother.hh:653\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-Vector\n-SeqOverlappingSchwarz< M, X, TM, TS, TA >::subdomain_vector Vector\n-Definition: smoother.hh:565\n-Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-construct\n-static std::shared_ptr< SeqOverlappingSchwarz< M, X, TM, TS, TA > > construct\n-(Arguments &args)\n-Definition: smoother.hh:857\n-Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n->_>::preSmooth\n-static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:469\n-Dune::Amg::AggregatesMap::begin\n-const_iterator begin() const\n-Definition: aggregates.hh:725\n-Dune::Amg::DefaultConstructionArgs::setMatrix\n-void setMatrix(const Matrix &matrix)\n-Definition: smoother.hh:104\n-Dune::Amg::SmootherApplier::Smoother\n-T Smoother\n-Definition: smoother.hh:371\n-Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::preSmooth\n-static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:450\n-Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n->_>::Smoother\n-BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > Smoother\n-Definition: smoother.hh:465\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setComm\n-void setComm(T1 &comm)\n-Definition: smoother.hh:193\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-VertexAdder::noSubdomains\n-int noSubdomains() const\n-Definition: smoother.hh:676\n-Dune::Amg::AggregatesMap::iterator\n-AggregateDescriptor * iterator\n-Definition: aggregates.hh:735\n+ 478 typedef S SmootherType;\n+ 480 std::shared_ptr smoother;\n+ 482 FineDomainType* lhs;\n+ 483 /*\n+ 484 * @brief The right hand side holding the current residual.\n+ 485 *\n+ 486 * This is passed to the smoother as the right hand side.\n+ 487 */\n+ 488 FineRangeType* rhs;\n+ 494 FineDomainType* update;\n+ 496 SequentialInformation* pinfo;\n+ 502 const FineOperatorType* matrix;\n+ 503 };\n+ 504 const FineOperatorType* operator_;\n+ 506 CoarseLevelSolver* coarseSolver_;\n+ 508 std::shared_ptr smoother_;\n+ 510 LevelTransferPolicy* policy_;\n+ 512 std::size_t preSteps_;\n+ 514 std::size_t postSteps_;\n+ 515};\n+ 516}// end namespace Amg\n+ 517}// end namespace Dune\n+ 518\n+ 520#endif\n+solver.hh\n+Define general, extensible interface for inverse operators.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n+galerkin.hh\n+Provides a class for building the galerkin product based on a aggregation\n+scheme.\n+amg.hh\n+The AMG preconditioner.\n+Dune::Amg::GalerkinProduct::build\n+G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation\n+&pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const\n+typename G::Matrix::size_type &size, const Set ©)\n+Calculates the coarse matrix via a Galerkin product.\n+Definition: galerkin.hh:563\n+Dune::Amg::AMG<_Operator,_X,_Smoother_>::SmootherArgs\n+SmootherTraits< Smoother >::Arguments SmootherArgs\n+The argument type for the construction of the smoother.\n+Definition: amg.hh:100\n+Dune::Amg::AMG<_Operator,_X,_Smoother_>::Operator\n+Operator Operator\n+The matrix operator type.\n+Definition: amg.hh:73\n Dune::Amg::presmooth\n void presmooth(LevelContext &levelContext, size_t steps)\n Apply pre smoothing on the current level.\n Definition: smoother.hh:406\n-Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n-MultiplicativeSchwarzMode,_MS,_TA_>_>::Domain\n-Smoother::domain_type Domain\n-Definition: smoother.hh:516\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::SeqOverlappingSchwarzSmootherArgs\n-SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex, bool\n-onthefly_=false)\n-Definition: smoother.hh:543\n-Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::Arguments\n-DefaultParallelConstructionArgs< T, C > Arguments\n-Definition: smoother.hh:337\n-Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n-Arguments\n-DefaultParallelConstructionArgs< T, C > Arguments\n-Definition: smoother.hh:349\n-Dune::Amg::DefaultConstructionArgs::matrix_\n-const Matrix * matrix_\n-Definition: smoother.hh:139\n-Dune::Amg::AggregatesMap::end\n-const_iterator end() const\n-Definition: aggregates.hh:730\n-Dune::Amg::DefaultConstructionArgs::getComm\n-const SequentialInformation & getComm()\n-Definition: smoother.hh:128\n-Dune::Amg::AggregatesMap::AggregateDescriptor\n-V AggregateDescriptor\n-The aggregate descriptor type.\n-Definition: aggregates.hh:580\n-Dune::Amg::AggregatesMap::ISOLATED\n-static const V ISOLATED\n-Identifier of isolated vertices.\n-Definition: aggregates.hh:571\n-Dune::Amg::DefaultSmootherArgs::DefaultSmootherArgs\n-DefaultSmootherArgs()\n-Default constructor.\n-Definition: smoother.hh:56\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-setMatrix\n-void setMatrix(const M &matrix)\n-Definition: smoother.hh:606\n-Dune::Amg::AggregatesMap::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices.\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-VertexAdder::operator()\n-void operator()(const T &edge)\n-Definition: smoother.hh:665\n-Dune::Amg::SmootherApplier::postSmooth\n-static void postSmooth(Smoother &smoother, Domain &v, const Range &d)\n-apply post smoothing in forward direction\n-Definition: smoother.hh:394\n-Dune::Amg::DefaultSmootherArgs::RelaxationFactor\n-FieldTraits< T >::real_type RelaxationFactor\n-The type of the relaxation factor.\n-Definition: smoother.hh:42\n-Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n-Y,_l_>_>_>::Domain\n-Smoother::domain_type Domain\n-Definition: smoother.hh:486\n-Dune::Amg::SmootherApplier::Domain\n-Smoother::domain_type Domain\n-Definition: smoother.hh:373\n-Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::setN\n-void setN(int n)\n-Definition: smoother.hh:288\n-Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::construct\n-static std::shared_ptr< BlockPreconditioner< X, Y, C, T > > construct(Arguments\n-&args)\n-Definition: smoother.hh:339\n-Dune::Amg::AggregatesMap::VertexList\n-SLList< VertexDescriptor, Allocator > VertexList\n-The type of a single linked list of vertex descriptors.\n-Definition: aggregates.hh:592\n-Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n-construct\n-static std::shared_ptr< NonoverlappingBlockPreconditioner< C, T > > construct\n-(Arguments &args)\n-Definition: smoother.hh:351\n-Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n-MultiplicativeSchwarzMode,_MS,_TA_>_>::Smoother\n-SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > Smoother\n-Definition: smoother.hh:514\n-Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>::construct\n-static std::shared_ptr< ParSSOR< M, X, Y, C > > construct(Arguments &args)\n-Definition: smoother.hh:326\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-VertexDescriptor\n-MatrixGraph< M >::VertexDescriptor VertexDescriptor\n-Definition: smoother.hh:562\n-Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>::construct\n-static std::shared_ptr< SeqILU< M, X, Y > > construct(Arguments &args)\n-Definition: smoother.hh:311\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregateAdder::noSubdomains\n-int noSubdomains() const\n-Definition: smoother.hh:731\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::getComm\n-const SequentialInformation & getComm()\n-Definition: smoother.hh:196\n-Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>::construct\n-static std::shared_ptr< SeqSOR< M, X, Y, l > > construct(Arguments &args)\n-Definition: smoother.hh:240\n-Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>::construct\n-static std::shared_ptr< Richardson< X, Y > > construct(Arguments &args)\n-Definition: smoother.hh:271\n-Dune::Amg::DefaultConstructionArgs::setMatrix\n-virtual void setMatrix(const Matrix &matrix, const AggregatesMap &amap)\n-Definition: smoother.hh:108\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-NoneAdder::noSubdomains\n-int noSubdomains() const\n-Definition: smoother.hh:695\n Dune::Amg::postsmooth\n void postsmooth(LevelContext &levelContext, size_t steps)\n Apply post smoothing on the current level.\n Definition: smoother.hh:428\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregatesMap\n-Dune::Amg::AggregatesMap< VertexDescriptor > AggregatesMap\n-Definition: smoother.hh:563\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::getArgs\n-const SmootherArgs getArgs() const\n-Definition: smoother.hh:201\n-Dune::Amg::DefaultConstructionArgs::setComm\n-void setComm(T1 &comm)\n-Definition: smoother.hh:125\n-Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n-MultiplicativeSchwarzMode,_MS,_TA_>_>::postSmooth\n-static void postSmooth(Smoother &smoother, Domain &v, const Range &d)\n-Definition: smoother.hh:524\n-Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>::Arguments\n-DefaultParallelConstructionArgs< M, C > Arguments\n-Definition: smoother.hh:324\n-Dune::Amg::DefaultSmootherArgs::relaxationFactor\n-RelaxationFactor relaxationFactor\n-The relaxation factor to use.\n-Definition: smoother.hh:51\n-Dune::Amg::DefaultParallelConstructionArgs::~DefaultParallelConstructionArgs\n-virtual ~DefaultParallelConstructionArgs()\n-Definition: smoother.hh:155\n-Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Domain\n-Smoother::domain_type Domain\n-Definition: smoother.hh:448\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n-AggregateAdder::setAggregate\n-int setAggregate(const AggregateDescriptor &aggregate_)\n-Definition: smoother.hh:725\n-Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Range\n-Smoother::range_type Range\n-Definition: smoother.hh:447\n-Dune::Amg::DefaultParallelConstructionArgs::getComm\n-const C & getComm() const\n-Definition: smoother.hh:163\n-Dune::Amg::DefaultConstructionArgs::~DefaultConstructionArgs\n-virtual ~DefaultConstructionArgs()\n-Definition: smoother.hh:101\n-Dune::Amg::SmootherApplier::preSmooth\n-static void preSmooth(Smoother &smoother, Domain &v, const Range &d)\n-apply pre smoothing in forward direction\n-Definition: smoother.hh:382\n-Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n->_>::postSmooth\n-static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n-Definition: smoother.hh:475\n-Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::\n-SeqConstructionTraits\n-ConstructionTraits< T > SeqConstructionTraits\n-Definition: smoother.hh:338\n-Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::ConstructionArgs\n-ConstructionArgs(int n=0)\n-Definition: smoother.hh:284\n-Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n->_>::Range\n-Smoother::range_type Range\n-Definition: smoother.hh:466\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setArgs\n-void setArgs(const SmootherArgs &args)\n-Definition: smoother.hh:187\n-Dune::Amg::DefaultSmootherArgs::iterations\n-int iterations\n-The numbe of iterations to perform.\n-Definition: smoother.hh:47\n-Dune::Amg::SmootherApplier::Range\n-Smoother::range_type Range\n-Definition: smoother.hh:372\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::overlap\n-Overlap overlap\n-Definition: smoother.hh:540\n-Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n->_>::Domain\n-Smoother::domain_type Domain\n-Definition: smoother.hh:467\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::aggregate\n-@ aggregate\n-Definition: smoother.hh:538\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::none\n-@ none\n-Definition: smoother.hh:538\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::pairwise\n-@ pairwise\n-Definition: smoother.hh:538\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs::vertex\n-@ vertex\n-Definition: smoother.hh:538\n+Dune::Amg::BaseGalerkinProduct::calculate\n+void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n+const I &pinfo, const O ©)\n+Calculate the galerkin product.\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::SeqOverlappingSchwarz\n-Sequential overlapping Schwarz preconditioner.\n-Definition: overlappingschwarz.hh:755\n-Dune::SeqOverlappingSchwarz::range_type\n-X range_type\n-The range type of the preconditioner.\n-Definition: overlappingschwarz.hh:770\n-Dune::SeqOverlappingSchwarz::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: overlappingschwarz.hh:765\n-Dune::Amg::ConstructionTraits\n-Traits class for generically constructing non default constructable types.\n-Definition: construction.hh:39\n-Dune::NonoverlappingBlockPreconditioner\n-Nonoverlapping parallel preconditioner.\n-Definition: novlpschwarz.hh:276\n-Dune::NonoverlappingBlockPreconditioner::range_type\n-P::range_type range_type\n-The range type of the preconditioner.\n-Definition: novlpschwarz.hh:284\n-Dune::NonoverlappingBlockPreconditioner::domain_type\n-P::domain_type domain_type\n-The domain type of the preconditioner.\n-Definition: novlpschwarz.hh:282\n-Dune::MultiplicativeSchwarzMode\n-Tag that tells the Schwarz method to be multiplicative.\n-Definition: overlappingschwarz.hh:126\n Dune::Amg::AggregatesMap\n Class providing information about the mapping of the vertices onto aggregates.\n Definition: aggregates.hh:560\n-Dune::Amg::MatrixGraph<_const_M_>\n-Dune::Amg::MatrixGraph::end\n-VertexIterator end()\n-Get an iterator over the vertices.\n-Dune::Amg::MatrixGraph::VertexDescriptor\n-M::size_type VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:73\n-Dune::Amg::MatrixGraph::begin\n-VertexIterator begin()\n-Get an iterator over the vertices.\n+Dune::Amg::AMG<_Operator,_X,_Smoother_>\n+Dune::Amg::EdgeProperties\n+Class representing the properties of an ede in the matrix graph.\n+Definition: dependency.hh:39\n+Dune::Amg::VertexProperties\n+Class representing a node in the matrix graph.\n+Definition: dependency.hh:126\n+Dune::Amg::GalerkinProduct\n+Definition: galerkin.hh:118\n+Dune::Amg::MatrixGraph\n+The (undirected) graph of a matrix.\n+Definition: graph.hh:51\n+Dune::Amg::PropertiesGraph\n+Attaches properties to the edges and vertices of a graph.\n+Definition: graph.hh:978\n+Dune::Amg::PropertiesGraph::maxVertex\n+VertexDescriptor maxVertex() const\n+Get the maximal vertex descriptor.\n+Dune::Amg::IndicesCoarsener\n+Definition: indicescoarsener.hh:36\n Dune::Amg::SequentialInformation\n Definition: pinfo.hh:28\n Dune::Amg::DefaultSmootherArgs\n The default class for the smoother arguments.\n Definition: smoother.hh:38\n-Dune::Amg::SmootherTraits\n-Traits class for getting the attribute class of a smoother.\n-Definition: smoother.hh:66\n-Dune::Amg::DefaultConstructionArgs\n-Construction Arguments for the default smoothers.\n-Definition: smoother.hh:93\n-Dune::Amg::ConstructionArgs\n-Definition: smoother.hh:148\n-Dune::Amg::DefaultParallelConstructionArgs\n-Definition: smoother.hh:153\n-Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>\n-Definition: smoother.hh:174\n-Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>\n-Definition: smoother.hh:282\n-Dune::Amg::SmootherApplier\n-Helper class for applying the smoothers.\n-Definition: smoother.hh:370\n-Dune::Amg::SeqOverlappingSchwarzSmootherArgs\n-Definition: smoother.hh:537\n-Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>\n-Definition: smoother.hh:558\n-Dune::SeqSSOR\n-Sequential SSOR preconditioner.\n-Definition: preconditioners.hh:141\n-Dune::SeqSOR\n-Sequential SOR preconditioner.\n-Definition: preconditioners.hh:261\n-Dune::SeqSOR::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: preconditioners.hh:266\n-Dune::SeqSOR::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: preconditioners.hh:268\n-Dune::SeqJac\n-The sequential jacobian preconditioner.\n-Definition: preconditioners.hh:412\n-Dune::SeqILU\n-Sequential ILU preconditioner.\n-Definition: preconditioners.hh:532\n-Dune::Richardson\n-Richardson preconditioner.\n-Definition: preconditioners.hh:713\n-Dune::ParSSOR\n-A parallel SSOR preconditioner.\n-Definition: schwarz.hh:175\n-Dune::BlockPreconditioner\n-Block parallel preconditioner.\n-Definition: schwarz.hh:278\n-Dune::BlockPreconditioner::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: schwarz.hh:285\n-Dune::BlockPreconditioner::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: schwarz.hh:290\n+Dune::Amg::Transfer::restrictVector\n+static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, const Vector &fine, T &comm)\n+Dune::Amg::Transfer::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n+Dune::Amg::LevelTransferPolicy\n+Abstract base class for transfer between levels and creation of the coarse\n+level system.\n+Definition: twolevelmethod.hh:38\n+Dune::Amg::LevelTransferPolicy::CoarseOperatorType\n+CO CoarseOperatorType\n+The linear operator of the finel level system. Has to be derived from\n+AssembledLinearOperator.\n+Definition: twolevelmethod.hh:57\n+Dune::Amg::LevelTransferPolicy::moveToCoarseLevel\n+virtual void moveToCoarseLevel(const FineRangeType &fineRhs)=0\n+Transfers the data to the coarse level.\n+Dune::Amg::LevelTransferPolicy::FineRangeType\n+FineOperatorType::range_type FineRangeType\n+The type of the range of the fine level operator.\n+Definition: twolevelmethod.hh:48\n+Dune::Amg::LevelTransferPolicy::createCoarseLevelSystem\n+virtual void createCoarseLevelSystem(const FineOperatorType &fineOperator)=0\n+Algebraically creates the coarse level system.\n+Dune::Amg::LevelTransferPolicy::CoarseRangeType\n+CoarseOperatorType::range_type CoarseRangeType\n+The type of the range of the coarse level operator.\n+Definition: twolevelmethod.hh:61\n+Dune::Amg::LevelTransferPolicy::~LevelTransferPolicy\n+virtual ~LevelTransferPolicy()\n+Destructor.\n+Definition: twolevelmethod.hh:124\n+Dune::Amg::LevelTransferPolicy::lhs_\n+CoarseDomainType lhs_\n+The coarse level lhs.\n+Definition: twolevelmethod.hh:130\n+Dune::Amg::LevelTransferPolicy::clone\n+virtual LevelTransferPolicy * clone() const =0\n+Clone the current object.\n+Dune::Amg::LevelTransferPolicy::getCoarseLevelLhs\n+CoarseDomainType & getCoarseLevelLhs()\n+Get the coarse level left hand side.\n+Definition: twolevelmethod.hh:87\n+Dune::Amg::LevelTransferPolicy::operator_\n+std::shared_ptr< CoarseOperatorType > operator_\n+the coarse level linear operator.\n+Definition: twolevelmethod.hh:132\n+Dune::Amg::LevelTransferPolicy::rhs_\n+CoarseRangeType rhs_\n+The coarse level rhs.\n+Definition: twolevelmethod.hh:128\n+Dune::Amg::LevelTransferPolicy::moveToFineLevel\n+virtual void moveToFineLevel(FineDomainType &fineLhs)=0\n+Updates the fine level linear system after the correction of the coarse levels\n+system.\n+Dune::Amg::LevelTransferPolicy::getCoarseLevelOperator\n+std::shared_ptr< CoarseOperatorType > & getCoarseLevelOperator()\n+Get the coarse level operator.\n+Definition: twolevelmethod.hh:70\n+Dune::Amg::LevelTransferPolicy::getCoarseLevelRhs\n+CoarseRangeType & getCoarseLevelRhs()\n+Get the coarse level right hand side.\n+Definition: twolevelmethod.hh:78\n+Dune::Amg::LevelTransferPolicy::FineOperatorType\n+FO FineOperatorType\n+The linear operator of the finel level system. Has to be derived from\n+AssembledLinearOperator.\n+Definition: twolevelmethod.hh:44\n+Dune::Amg::LevelTransferPolicy::CoarseDomainType\n+CoarseOperatorType::domain_type CoarseDomainType\n+The type of the domain of the coarse level operator.\n+Definition: twolevelmethod.hh:65\n+Dune::Amg::LevelTransferPolicy::FineDomainType\n+FineOperatorType::domain_type FineDomainType\n+The type of the domain of the fine level operator.\n+Definition: twolevelmethod.hh:52\n+Dune::Amg::AggregationLevelTransferPolicy\n+A LeveTransferPolicy that used aggregation to construct the coarse level\n+system.\n+Definition: twolevelmethod.hh:143\n+Dune::Amg::AggregationLevelTransferPolicy::Criterion\n+C Criterion\n+Definition: twolevelmethod.hh:147\n+Dune::Amg::AggregationLevelTransferPolicy::AggregationLevelTransferPolicy\n+AggregationLevelTransferPolicy(const Criterion &crit)\n+Definition: twolevelmethod.hh:150\n+Dune::Amg::AggregationLevelTransferPolicy::clone\n+AggregationLevelTransferPolicy * clone() const\n+Clone the current object.\n+Definition: twolevelmethod.hh:214\n+Dune::Amg::AggregationLevelTransferPolicy::moveToFineLevel\n+void moveToFineLevel(typename FatherType::FineDomainType &fineLhs)\n+Updates the fine level linear system after the correction of the coarse levels\n+system.\n+Definition: twolevelmethod.hh:207\n+Dune::Amg::AggregationLevelTransferPolicy::moveToCoarseLevel\n+void moveToCoarseLevel(const typename FatherType::FineRangeType &fineRhs)\n+Definition: twolevelmethod.hh:200\n+Dune::Amg::AggregationLevelTransferPolicy::ParallelInformation\n+SequentialInformation ParallelInformation\n+Definition: twolevelmethod.hh:148\n+Dune::Amg::AggregationLevelTransferPolicy::FatherType\n+LevelTransferPolicy< O, O > FatherType\n+Definition: twolevelmethod.hh:146\n+Dune::Amg::AggregationLevelTransferPolicy::createCoarseLevelSystem\n+void createCoarseLevelSystem(const O &fineOperator)\n+Algebraically creates the coarse level system.\n+Definition: twolevelmethod.hh:154\n+Dune::Amg::OneStepAMGCoarseSolverPolicy\n+A policy class for solving the coarse level system using one step of AMG.\n+Definition: twolevelmethod.hh:234\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::OneStepAMGCoarseSolverPolicy\n+OneStepAMGCoarseSolverPolicy(const SmootherArgs &args, const Criterion &c)\n+Constructs the coarse solver policy.\n+Definition: twolevelmethod.hh:253\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::CoarseLevelSolver\n+AMGInverseOperator CoarseLevelSolver\n+The type of solver constructed for the coarse level.\n+Definition: twolevelmethod.hh:315\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::OneStepAMGCoarseSolverPolicy\n+OneStepAMGCoarseSolverPolicy(const OneStepAMGCoarseSolverPolicy &other)\n+Copy constructor.\n+Definition: twolevelmethod.hh:257\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::X\n+O::range_type X\n+The type of the range and domain of the operator.\n+Definition: twolevelmethod.hh:239\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::Criterion\n+C Criterion\n+The type of the crition used for the aggregation within AMG.\n+Definition: twolevelmethod.hh:241\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::SmootherArgs\n+Dune::Amg::SmootherTraits< S >::Arguments SmootherArgs\n+The type of the arguments used for constructing the smoother.\n+Definition: twolevelmethod.hh:245\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::Operator\n+O Operator\n+The type of the linear operator used.\n+Definition: twolevelmethod.hh:237\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::AMGType\n+AMG< Operator, X, Smoother > AMGType\n+The type of the AMG construct on the coarse level.\n+Definition: twolevelmethod.hh:247\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::createCoarseLevelSolver\n+CoarseLevelSolver * createCoarseLevelSolver(P &transferPolicy)\n+Constructs a coarse level solver.\n+Definition: twolevelmethod.hh:325\n+Dune::Amg::OneStepAMGCoarseSolverPolicy::Smoother\n+S Smoother\n+The type of the smoother used in AMG.\n+Definition: twolevelmethod.hh:243\n+Dune::Amg::TwoLevelMethod\n+Definition: twolevelmethod.hh:353\n+Dune::Amg::TwoLevelMethod::CoarseRangeType\n+CoarseOperatorType::range_type CoarseRangeType\n+The type of the range of the coarse level operator.\n+Definition: twolevelmethod.hh:380\n+Dune::Amg::TwoLevelMethod::FineDomainType\n+FineOperatorType::domain_type FineDomainType\n+The type of the domain of the fine level operator.\n+Definition: twolevelmethod.hh:371\n+Dune::Amg::TwoLevelMethod::TwoLevelMethod\n+TwoLevelMethod(const TwoLevelMethod &other)\n+Definition: twolevelmethod.hh:418\n+Dune::Amg::TwoLevelMethod::pre\n+void pre(FineDomainType &x, FineRangeType &b)\n+Definition: twolevelmethod.hh:431\n+Dune::Amg::TwoLevelMethod::FineOperatorType\n+FO FineOperatorType\n+The linear operator of the finel level system. Has to be derived from\n+AssembledLinearOperator.\n+Definition: twolevelmethod.hh:363\n+Dune::Amg::TwoLevelMethod::CoarseLevelSolver\n+CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver\n+The type of the coarse level solver.\n+Definition: twolevelmethod.hh:358\n+Dune::Amg::TwoLevelMethod::apply\n+void apply(FineDomainType &v, const FineRangeType &d)\n+Definition: twolevelmethod.hh:439\n+Dune::Amg::TwoLevelMethod::CoarseLevelSolverPolicy\n+CSP CoarseLevelSolverPolicy\n+The type of the policy for constructing the coarse level solver.\n+Definition: twolevelmethod.hh:356\n+Dune::Amg::TwoLevelMethod::CoarseDomainType\n+CoarseOperatorType::domain_type CoarseDomainType\n+The type of the domain of the coarse level operator.\n+Definition: twolevelmethod.hh:384\n+Dune::Amg::TwoLevelMethod::TwoLevelMethod\n+TwoLevelMethod(const FineOperatorType &op, std::shared_ptr< SmootherType >\n+smoother, const LevelTransferPolicy< FineOperatorType, CoarseOperatorType >\n+&policy, CoarseLevelSolverPolicy &coarsePolicy, std::size_t preSteps=1, std::\n+size_t postSteps=1)\n+Constructs a two level method.\n+Definition: twolevelmethod.hh:404\n+Dune::Amg::TwoLevelMethod::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: twolevelmethod.hh:466\n+Dune::Amg::TwoLevelMethod::FineRangeType\n+FineOperatorType::range_type FineRangeType\n+The type of the range of the fine level operator.\n+Definition: twolevelmethod.hh:367\n+Dune::Amg::TwoLevelMethod::~TwoLevelMethod\n+~TwoLevelMethod()\n+Definition: twolevelmethod.hh:424\n+Dune::Amg::TwoLevelMethod::CoarseOperatorType\n+CSP::Operator CoarseOperatorType\n+The linear operator of the finel level system. Has to be derived from\n+AssembledLinearOperator.\n+Definition: twolevelmethod.hh:376\n+Dune::Amg::TwoLevelMethod::post\n+void post(FineDomainType &x)\n+Definition: twolevelmethod.hh:436\n+Dune::Amg::TwoLevelMethod::SmootherType\n+S SmootherType\n+The type of the fine level smoother.\n+Definition: twolevelmethod.hh:388\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperator\n+Abstract base class for all solvers.\n+Definition: solver.hh:99\n+Dune::InverseOperator<_X,_X_>::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)=0\n+Apply inverse operator,.\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00155.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00155.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: properties.hh File Reference\n+dune-istl: pinfo.hh File Reference\n \n \n \n \n \n \n \n@@ -65,43 +65,40 @@\n
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n- \n+
    pinfo.hh File Reference
    \n
    \n
    \n-\n-

    Provides classes for handling internal properties in a graph. \n-More...

    \n-
    #include <dune/common/propertymap.hh>
    \n+
    #include <dune/common/parallel/communication.hh>
    \n+#include <dune/common/enumset.hh>
    \n+#include <dune/common/parallel/mpicommunication.hh>
    \n+#include <dune/common/parallel/mpitraits.hh>
    \n+#include <dune/common/parallel/remoteindices.hh>
    \n+#include <dune/common/parallel/interface.hh>
    \n+#include <dune/common/parallel/communicator.hh>
    \n+#include <dune/istl/solvercategory.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::Amg::VertexVisitedTag
     Tag idnetifying the visited property of a vertex. More...
     
    class  Dune::Amg::RandomAccessBundledPropertyMap< C, K, i, T, R >
     A property map that extracts one property out of a bundle using operator[]() More...
    class  Dune::Amg::SequentialInformation
     
    \n \n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Provides classes for handling internal properties in a graph.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -6,33 +6,28 @@\n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n Classes | Namespaces\n-properties.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-\u00bb Parallel_Algebraic_Multigrid\n-Provides classes for handling internal properties in a graph. More...\n-#include \n+pinfo.hh File Reference\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::Amg::VertexVisitedTag\n-\u00a0 Tag idnetifying the visited property of a vertex. More...\n-\u00a0\n- class \u00a0Dune::Amg::RandomAccessBundledPropertyMap<_C,_K,_i,_T,_R_>\n-\u00a0 A property map that extracts one property out of a bundle using\n- operator[]() More...\n+class \u00a0Dune::Amg::SequentialInformation\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n-***** Detailed Description *****\n-Provides classes for handling internal properties in a graph.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00155_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00155_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: properties.hh Source File\n+dune-istl: pinfo.hh Source File\n \n \n \n \n \n \n \n@@ -62,85 +62,144 @@\n \n
    \n \n
    \n \n
    \n-
    properties.hh
    \n+
    pinfo.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_AMG_PROPERTIES_HH
    \n-
    6#define DUNE_ISTL_AMG_PROPERTIES_HH
    \n+
    5#ifndef DUNE_AMG_PINFO_HH
    \n+
    6#define DUNE_AMG_PINFO_HH
    \n
    7
    \n-
    8#include <dune/common/propertymap.hh>
    \n-
    9
    \n-
    10namespace Dune
    \n-
    11{
    \n+
    8#include <dune/common/parallel/communication.hh>
    \n+
    9#include <dune/common/enumset.hh>
    \n+
    10
    \n+
    11#if HAVE_MPI
    \n
    12
    \n-
    13 namespace Amg
    \n-
    14 {
    \n-\n-
    29 {};
    \n-
    30
    \n-
    31
    \n-
    38 template<typename C, typename K, std::size_t i,typename T=typename C::ValueType,
    \n-
    39 typename R = typename C::Reference>
    \n-\n-
    41 : public RAPropertyMapHelper<R,
    \n-
    42 RandomAccessBundledPropertyMap<C,K,i,T,R> >
    \n-
    43 {
    \n-
    44 public:
    \n-
    46 typedef C Container;
    \n+
    13#include <dune/common/parallel/mpicommunication.hh>
    \n+
    14#include <dune/common/parallel/mpitraits.hh>
    \n+
    15#include <dune/common/parallel/remoteindices.hh>
    \n+
    16#include <dune/common/parallel/interface.hh>
    \n+
    17#include <dune/common/parallel/communicator.hh>
    \n+
    18
    \n+
    19#endif
    \n+
    20
    \n+\n+
    22namespace Dune
    \n+
    23{
    \n+
    24 namespace Amg
    \n+
    25 {
    \n+
    26
    \n+\n+
    28 {
    \n+
    29 public:
    \n+
    30 typedef Communication<void*> MPICommunicator;
    \n+
    31 typedef EmptySet<int> CopyFlags;
    \n+
    32 typedef AllSet<int> OwnerSet;
    \n+
    33
    \n+\n+\n+
    36 }
    \n+
    37
    \n+\n+
    39 {
    \n+
    40 return comm_;
    \n+
    41 }
    \n+
    42
    \n+
    43 int procs() const
    \n+
    44 {
    \n+
    45 return 1;
    \n+
    46 }
    \n
    47
    \n-
    49 typedef R Reference;
    \n-
    50
    \n-
    52 typedef K Key;
    \n+
    48 template<typename T>
    \n+
    49 T globalSum(const T& t) const
    \n+
    50 {
    \n+
    51 return t;
    \n+
    52 }
    \n
    53
    \n-
    57 typedef LvaluePropertyMapTag Category;
    \n-
    58
    \n-
    59 enum {
    \n-
    61 index = i
    \n-
    62 };
    \n-
    63
    \n-
    69 Reference operator[](const Key& key) const
    \n-
    70 {
    \n-
    71 return container_[key][index];
    \n-
    72 }
    \n-
    73
    \n-\n-
    79 : container_(&container)
    \n-
    80 {}
    \n-
    81
    \n-\n-
    84 : container_(0)
    \n-
    85 {}
    \n+\n+
    55
    \n+
    56 void buildGlobalLookup(std::size_t){}
    \n+
    57
    \n+\n+
    59
    \n+\n+
    61 {
    \n+
    62 return gli;
    \n+
    63 }
    \n+
    64
    \n+
    65 template<class V>
    \n+
    66 void copyOwnerToAll([[maybe_unused]] V& v, [[maybe_unused]] V& v1) const
    \n+
    67 {}
    \n+
    68
    \n+
    69 template<class V>
    \n+
    70 void project([[maybe_unused]] V& v) const
    \n+
    71 {}
    \n+
    72
    \n+
    73 template<class T1, class T2>
    \n+
    74 void dot (const T1&, const T1&, T2&) const
    \n+
    75 {
    \n+
    76 // This function should never be called
    \n+
    77 std::abort();
    \n+
    78 }
    \n+
    79
    \n+
    80 template<class T1>
    \n+
    81 typename FieldTraits<typename T1::field_type>::real_type norm (const T1&) const
    \n+
    82 {
    \n+
    83 // This function should never be called
    \n+
    84 std::abort();
    \n+
    85 }
    \n
    86
    \n-
    87 private:
    \n-
    89 Container* container_;
    \n-
    90 };
    \n-
    91 }
    \n-
    92}
    \n+
    87 template<class T>
    \n+
    88 SequentialInformation(const Communication<T>&)
    \n+
    89 {}
    \n+
    90
    \n+\n+
    92 {}
    \n
    93
    \n-
    94#endif
    \n-
    Reference operator[](const Key &key) const
    Get the property for a key.
    Definition: properties.hh:69
    \n-
    RandomAccessBundledPropertyMap()
    The default constructor.
    Definition: properties.hh:83
    \n-
    R Reference
    The reference type of the container.
    Definition: properties.hh:49
    \n-
    RandomAccessBundledPropertyMap(Container &container)
    Constructor.
    Definition: properties.hh:78
    \n-
    K Key
    The key of the property map.
    Definition: properties.hh:52
    \n-
    LvaluePropertyMapTag Category
    The category of the property map.
    Definition: properties.hh:57
    \n-
    C Container
    The container that holds the properties.
    Definition: properties.hh:46
    \n-
    @ index
    The index of the property in the bundle.
    Definition: properties.hh:61
    \n+\n+
    95 {}
    \n+
    96 private:
    \n+
    97 MPICommunicator comm_;
    \n+\n+
    99 };
    \n+
    100
    \n+
    101
    \n+
    102 } // namespace Amg
    \n+
    103} //namespace Dune
    \n+
    104#endif
    \n+\n
    Definition: allocator.hh:11
    \n-
    Tag idnetifying the visited property of a vertex.
    Definition: properties.hh:29
    \n-
    A property map that extracts one property out of a bundle using operator[]()
    Definition: properties.hh:43
    \n+
    Definition: pinfo.hh:28
    \n+
    SequentialInformation()
    Definition: pinfo.hh:91
    \n+
    T globalSum(const T &t) const
    Definition: pinfo.hh:49
    \n+
    void dot(const T1 &, const T1 &, T2 &) const
    Definition: pinfo.hh:74
    \n+
    EmptySet< int > CopyFlags
    Definition: pinfo.hh:31
    \n+
    AllSet< int > OwnerSet
    Definition: pinfo.hh:32
    \n+
    void copyOwnerToAll(V &v, V &v1) const
    Definition: pinfo.hh:66
    \n+
    MPICommunicator communicator() const
    Definition: pinfo.hh:38
    \n+
    void buildGlobalLookup(std::size_t)
    Definition: pinfo.hh:56
    \n+
    FieldTraits< typenameT1::field_type >::real_type norm(const T1 &) const
    Definition: pinfo.hh:81
    \n+
    void project(V &v) const
    Definition: pinfo.hh:70
    \n+
    Communication< void * > MPICommunicator
    Definition: pinfo.hh:30
    \n+
    SequentialInformation(const Communication< T > &)
    Definition: pinfo.hh:88
    \n+
    const GlobalLookupIndexSet & globalLookup() const
    Definition: pinfo.hh:60
    \n+
    SequentialInformation(const SequentialInformation &)
    Definition: pinfo.hh:94
    \n+
    void freeGlobalLookup()
    Definition: pinfo.hh:58
    \n+
    int GlobalLookupIndexSet
    Definition: pinfo.hh:54
    \n+
    SolverCategory::Category category() const
    Definition: pinfo.hh:34
    \n+
    int procs() const
    Definition: pinfo.hh:43
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,111 +5,184 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-properties.hh\n+pinfo.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_AMG_PROPERTIES_HH\n- 6#define DUNE_ISTL_AMG_PROPERTIES_HH\n+ 5#ifndef DUNE_AMG_PINFO_HH\n+ 6#define DUNE_AMG_PINFO_HH\n 7\n- 8#include \n- 9\n- 10namespace Dune\n- 11{\n+ 8#include \n+ 9#include \n+ 10\n+ 11#if HAVE_MPI\n 12\n- 13 namespace Amg\n- 14 {\n-28 struct VertexVisitedTag\n- 29 {};\n- 30\n- 31\n- 38 template\n-40 class RandomAccessBundledPropertyMap\n- 41 : public RAPropertyMapHelper >\n- 43 {\n- 44 public:\n-46 typedef C Container;\n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18\n+ 19#endif\n+ 20\n+ 21#include \n+ 22namespace Dune\n+ 23{\n+ 24 namespace Amg\n+ 25 {\n+ 26\n+27 class SequentialInformation\n+ 28 {\n+ 29 public:\n+30 typedef Communication MPICommunicator;\n+31 typedef EmptySet CopyFlags;\n+32 typedef AllSet OwnerSet;\n+ 33\n+34 SolverCategory::Category category () const {\n+ 35 return SolverCategory::sequential;\n+ 36 }\n+ 37\n+38 MPICommunicator communicator() const\n+ 39 {\n+ 40 return comm_;\n+ 41 }\n+ 42\n+43 int procs() const\n+ 44 {\n+ 45 return 1;\n+ 46 }\n 47\n-49 typedef R Reference;\n- 50\n-52 typedef K Key;\n+ 48 template\n+49 T globalSum(const T& t) const\n+ 50 {\n+ 51 return t;\n+ 52 }\n 53\n-57 typedef LvaluePropertyMapTag Category;\n- 58\n- 59 enum {\n- 61 index = i\n-62 };\n- 63\n-69 Reference operator[](const Key& key) const\n- 70 {\n- 71 return container_[key][index];\n- 72 }\n- 73\n-78 RandomAccessBundledPropertyMap(Container& container)\n- 79 : container_(&container)\n- 80 {}\n- 81\n-83 RandomAccessBundledPropertyMap()\n- 84 : container_(0)\n- 85 {}\n+54 typedef int GlobalLookupIndexSet;\n+ 55\n+56 void buildGlobalLookup(std::size_t){}\n+ 57\n+58 void freeGlobalLookup(){}\n+ 59\n+60 const GlobalLookupIndexSet& globalLookup() const\n+ 61 {\n+ 62 return gli;\n+ 63 }\n+ 64\n+ 65 template\n+66 void copyOwnerToAll([[maybe_unused]] V& v, [[maybe_unused]] V& v1) const\n+ 67 {}\n+ 68\n+ 69 template\n+70 void project([[maybe_unused]] V& v) const\n+ 71 {}\n+ 72\n+ 73 template\n+74 void dot (const T1&, const T1&, T2&) const\n+ 75 {\n+ 76 // This function should never be called\n+ 77 std::abort();\n+ 78 }\n+ 79\n+ 80 template\n+81 typename FieldTraits::real_type norm (const T1&)\n+const\n+ 82 {\n+ 83 // This function should never be called\n+ 84 std::abort();\n+ 85 }\n 86\n- 87 private:\n- 89 Container* container_;\n- 90 };\n- 91 }\n- 92}\n+ 87 template\n+88 SequentialInformation(const Communication&)\n+ 89 {}\n+ 90\n+91 SequentialInformation()\n+ 92 {}\n 93\n- 94#endif\n-Dune::Amg::RandomAccessBundledPropertyMap::operator[]\n-Reference operator[](const Key &key) const\n-Get the property for a key.\n-Definition: properties.hh:69\n-Dune::Amg::RandomAccessBundledPropertyMap::RandomAccessBundledPropertyMap\n-RandomAccessBundledPropertyMap()\n-The default constructor.\n-Definition: properties.hh:83\n-Dune::Amg::RandomAccessBundledPropertyMap::Reference\n-R Reference\n-The reference type of the container.\n-Definition: properties.hh:49\n-Dune::Amg::RandomAccessBundledPropertyMap::RandomAccessBundledPropertyMap\n-RandomAccessBundledPropertyMap(Container &container)\n-Constructor.\n-Definition: properties.hh:78\n-Dune::Amg::RandomAccessBundledPropertyMap::Key\n-K Key\n-The key of the property map.\n-Definition: properties.hh:52\n-Dune::Amg::RandomAccessBundledPropertyMap::Category\n-LvaluePropertyMapTag Category\n-The category of the property map.\n-Definition: properties.hh:57\n-Dune::Amg::RandomAccessBundledPropertyMap::Container\n-C Container\n-The container that holds the properties.\n-Definition: properties.hh:46\n-Dune::Amg::RandomAccessBundledPropertyMap::index\n-@ index\n-The index of the property in the bundle.\n-Definition: properties.hh:61\n+94 SequentialInformation(const SequentialInformation&)\n+ 95 {}\n+ 96 private:\n+ 97 MPICommunicator comm_;\n+ 98 GlobalLookupIndexSet gli;\n+ 99 };\n+ 100\n+ 101\n+ 102 } // namespace Amg\n+ 103} //namespace Dune\n+ 104#endif\n+solvercategory.hh\n Dune\n Definition: allocator.hh:11\n-Dune::Amg::VertexVisitedTag\n-Tag idnetifying the visited property of a vertex.\n-Definition: properties.hh:29\n-Dune::Amg::RandomAccessBundledPropertyMap\n-A property map that extracts one property out of a bundle using operator[]()\n-Definition: properties.hh:43\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::Amg::SequentialInformation::SequentialInformation\n+SequentialInformation()\n+Definition: pinfo.hh:91\n+Dune::Amg::SequentialInformation::globalSum\n+T globalSum(const T &t) const\n+Definition: pinfo.hh:49\n+Dune::Amg::SequentialInformation::dot\n+void dot(const T1 &, const T1 &, T2 &) const\n+Definition: pinfo.hh:74\n+Dune::Amg::SequentialInformation::CopyFlags\n+EmptySet< int > CopyFlags\n+Definition: pinfo.hh:31\n+Dune::Amg::SequentialInformation::OwnerSet\n+AllSet< int > OwnerSet\n+Definition: pinfo.hh:32\n+Dune::Amg::SequentialInformation::copyOwnerToAll\n+void copyOwnerToAll(V &v, V &v1) const\n+Definition: pinfo.hh:66\n+Dune::Amg::SequentialInformation::communicator\n+MPICommunicator communicator() const\n+Definition: pinfo.hh:38\n+Dune::Amg::SequentialInformation::buildGlobalLookup\n+void buildGlobalLookup(std::size_t)\n+Definition: pinfo.hh:56\n+Dune::Amg::SequentialInformation::norm\n+FieldTraits< typenameT1::field_type >::real_type norm(const T1 &) const\n+Definition: pinfo.hh:81\n+Dune::Amg::SequentialInformation::project\n+void project(V &v) const\n+Definition: pinfo.hh:70\n+Dune::Amg::SequentialInformation::MPICommunicator\n+Communication< void * > MPICommunicator\n+Definition: pinfo.hh:30\n+Dune::Amg::SequentialInformation::SequentialInformation\n+SequentialInformation(const Communication< T > &)\n+Definition: pinfo.hh:88\n+Dune::Amg::SequentialInformation::globalLookup\n+const GlobalLookupIndexSet & globalLookup() const\n+Definition: pinfo.hh:60\n+Dune::Amg::SequentialInformation::SequentialInformation\n+SequentialInformation(const SequentialInformation &)\n+Definition: pinfo.hh:94\n+Dune::Amg::SequentialInformation::freeGlobalLookup\n+void freeGlobalLookup()\n+Definition: pinfo.hh:58\n+Dune::Amg::SequentialInformation::GlobalLookupIndexSet\n+int GlobalLookupIndexSet\n+Definition: pinfo.hh:54\n+Dune::Amg::SequentialInformation::category\n+SolverCategory::Category category() const\n+Definition: pinfo.hh:34\n+Dune::Amg::SequentialInformation::procs\n+int procs() const\n+Definition: pinfo.hh:43\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00158.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00158.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixhierarchy.hh File Reference\n+dune-istl: indicescoarsener.hh File Reference\n \n \n \n \n \n \n \n@@ -64,79 +64,51 @@\n \n \n \n \n+ \n \n
    \n \n-

    Provides a classes representing the hierarchies in AMG. \n+

    Provides a class for building the index set and remote indices on the coarse level. \n More...

    \n-
    #include <algorithm>
    \n-#include <tuple>
    \n-#include "aggregates.hh"
    \n-#include "graph.hh"
    \n-#include "galerkin.hh"
    \n-#include "renumberer.hh"
    \n-#include "graphcreator.hh"
    \n-#include "hierarchy.hh"
    \n-#include <dune/istl/bvector.hh>
    \n-#include <dune/common/parallel/indexset.hh>
    \n-#include <dune/istl/matrixutils.hh>
    \n-#include <dune/istl/matrixredistribute.hh>
    \n-#include <dune/istl/paamg/dependency.hh>
    \n-#include <dune/istl/paamg/indicescoarsener.hh>
    \n-#include <dune/istl/paamg/globalaggregates.hh>
    \n-#include <dune/istl/paamg/construction.hh>
    \n-#include <dune/istl/paamg/smoother.hh>
    \n-#include <dune/istl/paamg/transfer.hh>
    \n+
    #include <dune/common/parallel/indicessyncer.hh>
    \n+#include <vector>
    \n+#include "renumberer.hh"
    \n+#include <dune/istl/owneroverlapcopy.hh>
    \n+#include "pinfo.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n+\n \n-\n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::Amg::MatrixHierarchy< M, PI, A >
     The hierarchies build by the coarsening process. More...
    class  Dune::Amg::IndicesCoarsener< T, E >
     
    struct  Dune::Amg::MatrixHierarchy< M, PI, A >::MatrixStats< Matrix, true >::calc
    class  Dune::Amg::ParallelIndicesCoarsener< T, E >
     
    class  Dune::Amg::CoarsenCriterion< T >
     The criterion describing the stop criteria for the coarsening process. More...
    class  Dune::Amg::IndicesCoarsener< OwnerOverlapCopyCommunication< G, L >, E >
     Coarsen Indices in the parallel case. More...
     
    class  Dune::Amg::IndicesCoarsener< SequentialInformation, E >
     Coarsen Indices in the sequential case. More...
     
    \n \n \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-\n-\n-\n-

    \n-Enumerations

    enum  { Dune::Amg::MAX_PROCESSES = 72000\n- }
     
    \n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<typename M , typename C1 >
    bool Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::shared_ptr< M > newMatrix, SequentialInformation &origComm, std::shared_ptr< SequentialInformation > &newComm, RedistributeInformation< SequentialInformation > &ri, int nparts, C1 &criterion)
     
    template<typename M , typename C , typename C1 >
    bool Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::shared_ptr< M > newMatrix, C &origComm, std::shared_ptr< C > &newComm, RedistributeInformation< C > &ri, int nparts, C1 &criterion)
     
    \n

    Detailed Description

    \n-

    Provides a classes representing the hierarchies in AMG.

    \n+

    Provides a class for building the index set and remote indices on the coarse level.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,69 +5,43 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces | Enumerations | Functions\n-matrixhierarchy.hh File Reference\n+Classes | Namespaces\n+indicescoarsener.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n \u00bb Parallel_Algebraic_Multigrid\n-Provides a classes representing the hierarchies in AMG. More...\n-#include \n-#include \n-#include \"aggregates.hh\"\n-#include \"graph.hh\"\n-#include \"galerkin.hh\"\n+Provides a class for building the index set and remote indices on the coarse\n+level. More...\n+#include \n+#include \n #include \"renumberer.hh\"\n-#include \"graphcreator.hh\"\n-#include \"hierarchy.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \n+#include \"pinfo.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::Amg::MatrixHierarchy<_M,_PI,_A_>\n-\u00a0 The hierarchies build by the coarsening process. More...\n+class \u00a0Dune::Amg::IndicesCoarsener<_T,_E_>\n \u00a0\n-struct \u00a0Dune::Amg::MatrixHierarchy<_M,_PI,_A_>::MatrixStats<_Matrix,_true_>::\n- calc\n+class \u00a0Dune::Amg::ParallelIndicesCoarsener<_T,_E_>\n \u00a0\n- class \u00a0Dune::Amg::CoarsenCriterion<_T_>\n-\u00a0 The criterion describing the stop criteria for the coarsening process.\n- More...\n+class \u00a0Dune::Amg::IndicesCoarsener<_OwnerOverlapCopyCommunication<_G,_L_>,_E_>\n+\u00a0 Coarsen Indices in the parallel case. More...\n+\u00a0\n+class \u00a0Dune::Amg::IndicesCoarsener<_SequentialInformation,_E_>\n+\u00a0 Coarsen Indices in the sequential case. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n- Enumerations\n-enum \u00a0{ Dune::Amg::MAX_PROCESSES = 72000 }\n-\u00a0\n- Functions\n-template\n-bool\u00a0Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::\n- shared_ptr< M > newMatrix, SequentialInformation &origComm, std::\n- shared_ptr< SequentialInformation > &newComm, RedistributeInformation<\n- SequentialInformation > &ri, int nparts, C1 &criterion)\n-\u00a0\n-template\n-bool\u00a0Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::\n- shared_ptr< M > newMatrix, C &origComm, std::shared_ptr< C > &newComm,\n- RedistributeInformation< C > &ri, int nparts, C1 &criterion)\n-\u00a0\n ***** Detailed Description *****\n-Provides a classes representing the hierarchies in AMG.\n+Provides a class for building the index set and remote indices on the coarse\n+level.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00158_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00158_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixhierarchy.hh Source File\n+dune-istl: indicescoarsener.hh Source File\n \n \n \n \n \n \n \n@@ -62,953 +62,402 @@\n \n
    \n \n
    \n
    \n
    \n-
    matrixhierarchy.hh
    \n+
    indicescoarsener.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_MATRIXHIERARCHY_HH
    \n-
    6#define DUNE_AMG_MATRIXHIERARCHY_HH
    \n+
    5#ifndef DUNE_AMG_INDICESCOARSENER_HH
    \n+
    6#define DUNE_AMG_INDICESCOARSENER_HH
    \n
    7
    \n-
    8#include <algorithm>
    \n-
    9#include <tuple>
    \n-
    10#include "aggregates.hh"
    \n-
    11#include "graph.hh"
    \n-
    12#include "galerkin.hh"
    \n-
    13#include "renumberer.hh"
    \n-
    14#include "graphcreator.hh"
    \n-
    15#include "hierarchy.hh"
    \n-
    16#include <dune/istl/bvector.hh>
    \n-
    17#include <dune/common/parallel/indexset.hh>
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-
    27
    \n-
    28namespace Dune
    \n-
    29{
    \n-
    30 namespace Amg
    \n-
    31 {
    \n-
    42 enum {
    \n-
    50 MAX_PROCESSES = 72000
    \n-
    51 };
    \n-
    52
    \n-
    59 template<class M, class PI, class A=std::allocator<M> >
    \n-\n-
    61 {
    \n-
    62 public:
    \n-
    64 typedef M MatrixOperator;
    \n-
    65
    \n-
    67 typedef typename MatrixOperator::matrix_type Matrix;
    \n-
    68
    \n-\n+
    8#include <dune/common/parallel/indicessyncer.hh>
    \n+
    9#include <vector>
    \n+
    10#include "renumberer.hh"
    \n+
    11
    \n+
    12#if HAVE_MPI
    \n+\n+
    14#endif
    \n+
    15
    \n+
    16#include "pinfo.hh"
    \n+
    17
    \n+
    18namespace Dune
    \n+
    19{
    \n+
    20 namespace Amg
    \n+
    21 {
    \n+
    22
    \n+
    34 template<typename T, typename E>
    \n+\n+
    36 {};
    \n+
    37
    \n+
    38
    \n+
    39#if HAVE_MPI
    \n+
    40
    \n+
    41 template<typename T, typename E>
    \n+\n+
    43 {
    \n+
    44 public:
    \n+\n+
    49
    \n+\n+
    54
    \n+
    55 typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;
    \n+
    56
    \n+
    60 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n+
    61
    \n+
    65 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
    \n+
    66
    \n+
    70 typedef typename LocalIndex::Attribute Attribute;
    \n
    71
    \n-
    73 typedef A Allocator;
    \n-
    74
    \n-\n-
    77
    \n-\n-
    80
    \n-\n-
    83
    \n-
    85 using AAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<AggregatesMap*>;
    \n-
    86
    \n-
    88 typedef std::list<AggregatesMap*,AAllocator> AggregatesMapList;
    \n-
    89
    \n-\n-
    92
    \n-
    94 using RILAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<RedistributeInfoType>;
    \n-
    95
    \n-
    97 typedef std::list<RedistributeInfoType,RILAllocator> RedistributeInfoList;
    \n-
    98
    \n-
    104 MatrixHierarchy(std::shared_ptr<MatrixOperator> fineMatrix,
    \n-
    105 std::shared_ptr<ParallelInformation> pinfo = std::make_shared<ParallelInformation>());
    \n+
    75 typedef Dune::RemoteIndices<ParallelIndexSet> RemoteIndices;
    \n+
    76
    \n+
    88 template<typename Graph, typename VM>
    \n+
    89 static typename Graph::VertexDescriptor
    \n+\n+
    91 Graph& fineGraph,
    \n+
    92 VM& visitedMap,
    \n+\n+
    94 ParallelInformation& coarseInfo,
    \n+
    95 typename Graph::VertexDescriptor noAggregates);
    \n+
    96
    \n+
    97 private:
    \n+
    98 template<typename G, typename I>
    \n+
    99 class ParallelAggregateRenumberer : public AggregateRenumberer<G>
    \n+
    100 {
    \n+
    101 typedef typename G::VertexDescriptor Vertex;
    \n+
    102
    \n+
    103 typedef I GlobalLookupIndexSet;
    \n+
    104
    \n+
    105 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
    \n
    106
    \n-\n+
    107 typedef typename IndexPair::GlobalIndex GlobalIndex;
    \n
    108
    \n-
    114 template<typename O, typename T>
    \n-
    115 void build(const T& criterion);
    \n-
    116
    \n-
    124 template<class F>
    \n-
    125 void recalculateGalerkin(const F& copyFlags);
    \n+
    109 public:
    \n+\n+
    111 : AggregateRenumberer<G>(aggregates), isPublic_(false), lookup_(lookup),
    \n+
    112 globalIndex_(std::numeric_limits<GlobalIndex>::max())
    \n+
    113 {}
    \n+
    114
    \n+
    115
    \n+
    116 void operator()(const typename G::ConstEdgeIterator& edge)
    \n+
    117 {
    \n+\n+
    119 const IndexPair* pair= lookup_.pair(edge.target());
    \n+
    120 if(pair!=0) {
    \n+
    121 globalIndex(pair->global());
    \n+
    122 attribute(pair->local().attribute());
    \n+
    123 isPublic(pair->local().isPublic());
    \n+
    124 }
    \n+
    125 }
    \n
    126
    \n-
    131 template<class V, class BA, class TA>
    \n-
    132 void coarsenVector(Hierarchy<BlockVector<V,BA>, TA>& hierarchy) const;
    \n+
    127 Vertex operator()([[maybe_unused]] const GlobalIndex& global)
    \n+
    128 {
    \n+
    129 Vertex current = this->number_;
    \n+
    130 this->operator++();
    \n+
    131 return current;
    \n+
    132 }
    \n
    133
    \n-
    139 template<class S, class TA>
    \n-
    140 void coarsenSmoother(Hierarchy<S,TA>& smoothers,
    \n-
    141 const typename SmootherTraits<S>::Arguments& args) const;
    \n-
    142
    \n-
    147 std::size_t levels() const;
    \n-
    148
    \n-
    153 std::size_t maxlevels() const;
    \n+
    134 bool isPublic()
    \n+
    135 {
    \n+
    136 return isPublic_;
    \n+
    137 }
    \n+
    138
    \n+
    139 void isPublic(bool b)
    \n+
    140 {
    \n+
    141 isPublic_ = isPublic_ || b;
    \n+
    142 }
    \n+
    143
    \n+
    144 void reset()
    \n+
    145 {
    \n+
    146 globalIndex_ = std::numeric_limits<GlobalIndex>::max();
    \n+
    147 isPublic_=false;
    \n+
    148 }
    \n+
    149
    \n+
    150 void attribute(const Attribute& attribute)
    \n+
    151 {
    \n+
    152 attribute_=attribute;
    \n+
    153 }
    \n
    154
    \n-
    155 bool hasCoarsest() const;
    \n-
    156
    \n-
    161 bool isBuilt() const;
    \n-
    162
    \n-
    167 const ParallelMatrixHierarchy& matrices() const;
    \n-
    168
    \n-\n-
    174
    \n-
    179 const AggregatesMapList& aggregatesMaps() const;
    \n-
    180
    \n-\n-
    187
    \n-\n-
    189 {
    \n-
    190 return prolongDamp_;
    \n-
    191 }
    \n-
    192
    \n-
    203 void getCoarsestAggregatesOnFinest(std::vector<std::size_t>& data) const;
    \n+\n+
    156 {
    \n+
    157 return attribute_;
    \n+
    158 }
    \n+
    159
    \n+
    160 const GlobalIndex& globalIndex() const
    \n+
    161 {
    \n+
    162 return globalIndex_;
    \n+
    163 }
    \n+
    164
    \n+
    165 void globalIndex(const GlobalIndex& global)
    \n+
    166 {
    \n+
    167 globalIndex_ = global;
    \n+
    168 }
    \n+
    169
    \n+
    170 private:
    \n+
    171 bool isPublic_;
    \n+
    172 Attribute attribute_;
    \n+
    173 const GlobalLookupIndexSet& lookup_;
    \n+
    174 GlobalIndex globalIndex_;
    \n+
    175 };
    \n+
    176
    \n+
    177 template<typename Graph, typename VM, typename I>
    \n+
    178 static void buildCoarseIndexSet(const ParallelInformation& pinfo,
    \n+
    179 Graph& fineGraph,
    \n+
    180 VM& visitedMap,
    \n+\n+
    182 ParallelIndexSet& coarseIndices,
    \n+
    183 ParallelAggregateRenumberer<Graph,I>& renumberer);
    \n+
    184
    \n+
    185 template<typename Graph,typename I>
    \n+
    186 static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
    \n+\n+
    188 ParallelIndexSet& coarseIndices,
    \n+
    189 RemoteIndices& coarseRemote,
    \n+
    190 ParallelAggregateRenumberer<Graph,I>& renumberer);
    \n+
    191
    \n+
    192 };
    \n+
    193
    \n+
    197 template<typename G, typename L, typename E>
    \n+\n+
    199 : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
    \n+
    200 {};
    \n+
    201
    \n+
    202
    \n+
    203#endif
    \n
    204
    \n-
    205 private:
    \n-
    206 typedef typename ConstructionTraits<MatrixOperator>::Arguments MatrixArgs;
    \n-
    207 typedef typename ConstructionTraits<ParallelInformation>::Arguments CommunicationArgs;
    \n-
    209 AggregatesMapList aggregatesMaps_;
    \n-
    211 RedistributeInfoList redistributes_;
    \n-
    213 ParallelMatrixHierarchy matrices_;
    \n-
    215 ParallelInformationHierarchy parallelInformation_;
    \n-
    216
    \n-
    218 bool built_;
    \n-
    219
    \n-
    221 int maxlevels_;
    \n-
    222
    \n-
    223 double prolongDamp_;
    \n+
    211 template<typename E>
    \n+\n+
    213 {
    \n+
    214 public:
    \n+
    215 template<typename Graph, typename VM>
    \n+
    216 static typename Graph::VertexDescriptor
    \n+
    217 coarsen(const SequentialInformation & fineInfo,
    \n+
    218 Graph& fineGraph,
    \n+
    219 VM& visitedMap,
    \n+\n+
    221 SequentialInformation& coarseInfo,
    \n+
    222 typename Graph::VertexDescriptor noAggregates);
    \n+
    223 };
    \n
    224
    \n-
    228 template<class Matrix, bool print>
    \n-
    229 struct MatrixStats
    \n-
    230 {
    \n-
    231
    \n-
    235 static void stats([[maybe_unused]] const Matrix& matrix)
    \n-
    236 {}
    \n-
    237 };
    \n-
    238
    \n-
    239 template<class Matrix>
    \n-
    240 struct MatrixStats<Matrix,true>
    \n-
    241 {
    \n-
    242 struct calc
    \n-
    243 {
    \n-
    244 typedef typename Matrix::size_type size_type;
    \n-
    245 typedef typename Matrix::row_type matrix_row;
    \n-
    246
    \n-\n-
    248 {
    \n-
    249 min=std::numeric_limits<size_type>::max();
    \n-
    250 max=0;
    \n-
    251 sum=0;
    \n-
    252 }
    \n-
    253
    \n-
    254 void operator()(const matrix_row& row)
    \n-
    255 {
    \n-
    256 min=std::min(min, row.size());
    \n-
    257 max=std::max(max, row.size());
    \n-
    258 sum += row.size();
    \n-
    259 }
    \n-
    260
    \n-\n-\n-\n-
    264 };
    \n-
    268 static void stats(const Matrix& matrix)
    \n-
    269 {
    \n-
    270 calc c= for_each(matrix.begin(), matrix.end(), calc());
    \n-
    271 dinfo<<"Matrix row: min="<<c.min<<" max="<<c.max
    \n-
    272 <<" average="<<static_cast<double>(c.sum)/matrix.N()
    \n-
    273 <<std::endl;
    \n-
    274 }
    \n-
    275 };
    \n-
    276 };
    \n+
    225#if HAVE_MPI
    \n+
    226 template<typename T, typename E>
    \n+
    227 template<typename Graph, typename VM>
    \n+
    228 inline typename Graph::VertexDescriptor
    \n+\n+
    230 Graph& fineGraph,
    \n+
    231 VM& visitedMap,
    \n+\n+
    233 ParallelInformation& coarseInfo,
    \n+
    234 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
    \n+
    235 {
    \n+
    236 ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
    \n+
    237 buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,
    \n+
    238 coarseInfo.indexSet(), renumberer);
    \n+
    239 buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(),
    \n+
    240 coarseInfo.remoteIndices(), renumberer);
    \n+
    241
    \n+
    242 return renumberer;
    \n+
    243 }
    \n+
    244
    \n+
    245 template<typename T, typename E>
    \n+
    246 template<typename Graph, typename VM, typename I>
    \n+
    247 void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
    \n+
    248 Graph& fineGraph,
    \n+
    249 VM& visitedMap,
    \n+\n+
    251 ParallelIndexSet& coarseIndices,
    \n+
    252 ParallelAggregateRenumberer<Graph,I>& renumberer)
    \n+
    253 {
    \n+
    254 // fineGraph is the local subgraph corresponding to the vertices the process owns.
    \n+
    255 // i.e. no overlap/copy vertices can be visited traversing the graph
    \n+
    256 typedef typename Graph::ConstVertexIterator Iterator;
    \n+
    257 typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
    \n+
    258
    \n+
    259 Iterator end = fineGraph.end();
    \n+
    260 const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
    \n+
    261
    \n+
    262 coarseIndices.beginResize();
    \n+
    263
    \n+
    264 // Setup the coarse index set and renumber the aggregate consecutively
    \n+
    265 // ascending from zero according to the minimum global index belonging
    \n+
    266 // to the aggregate
    \n+
    267 for(Iterator index = fineGraph.begin(); index != end; ++index) {
    \n+\n+
    269 // Isolated vertices will not be represented on the next level.
    \n+
    270 // These should only be there if skipIsolated is activiated in
    \n+
    271 // the coarsening criterion as otherwise they will be aggregated
    \n+
    272 // and should have real aggregate number in the map right now.
    \n+
    273 if(!get(visitedMap, *index)) {
    \n+
    274 // This vertex was not visited by breadthFirstSearch yet.
    \n+
    275 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
    \n+
    276 const IndexPair* pair= lookup.pair(*index);
    \n
    277
    \n-
    281 template<class T>
    \n-
    282 class CoarsenCriterion : public T
    \n-
    283 {
    \n-
    284 public:
    \n-\n-
    290
    \n-
    301 CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,
    \n-
    302 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n-
    303 : AggregationCriterion(Dune::Amg::Parameters(maxLevel, coarsenTarget, minCoarsenRate, prolongDamp, accumulate))
    \n-
    304 {}
    \n+
    278 renumberer.reset(); // reset attribute and global index.
    \n+
    279 if(pair!=0) {
    \n+
    280 // vertex is in the index set. Note that not all vertices have
    \n+
    281 // to be in the index set, just the ones where communication
    \n+
    282 // will happen.
    \n+
    283 assert(!ExcludedAttributes::contains(pair->local().attribute()));
    \n+
    284 renumberer.attribute(pair->local().attribute());
    \n+
    285 renumberer.isPublic(pair->local().isPublic());
    \n+
    286 renumberer.globalIndex(pair->global());
    \n+
    287 }
    \n+
    288
    \n+
    289 // Reconstruct aggregate and mark vertices as visited
    \n+
    290 aggregates.template breadthFirstSearch<false>(*index, aggregates[*index],
    \n+
    291 fineGraph, renumberer, visitedMap);
    \n+
    292
    \n+
    293 if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()) {
    \n+
    294 // vertex is in the index set.
    \n+
    295 //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
    \n+
    296 coarseIndices.add(renumberer.globalIndex(),
    \n+
    297 LocalIndex(renumberer, renumberer.attribute(),
    \n+
    298 renumberer.isPublic()));
    \n+
    299 }
    \n+
    300
    \n+
    301 aggregates[*index] = renumberer;
    \n+
    302 ++renumberer;
    \n+
    303 }
    \n+
    304 }
    \n
    305
    \n-\n-
    307 : AggregationCriterion(parms)
    \n-
    308 {}
    \n+
    306 coarseIndices.endResize();
    \n+
    307
    \n+
    308 assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
    \n
    309
    \n-
    310 };
    \n-
    311
    \n-
    312 template<typename M, typename C1>
    \n-
    313 bool repartitionAndDistributeMatrix([[maybe_unused]] const M& origMatrix,
    \n-
    314 [[maybe_unused]] std::shared_ptr<M> newMatrix,
    \n-
    315 [[maybe_unused]] SequentialInformation& origComm,
    \n-
    316 [[maybe_unused]] std::shared_ptr<SequentialInformation>& newComm,
    \n-\n-
    318 [[maybe_unused]] int nparts,
    \n-
    319 [[maybe_unused]] C1& criterion)
    \n-
    320 {
    \n-
    321 DUNE_THROW(NotImplemented, "Redistribution does not make sense in sequential code!");
    \n-
    322 }
    \n-
    323
    \n+
    310 // Reset the visited flags
    \n+
    311 for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
    \n+
    312 put(visitedMap, *vertex, false);
    \n+
    313 }
    \n+
    314
    \n+
    315 template<typename T, typename E>
    \n+
    316 template<typename Graph, typename I>
    \n+
    317 void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
    \n+
    318 const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
    \n+
    319 ParallelIndexSet& coarseIndices,
    \n+
    320 RemoteIndices& coarseRemote,
    \n+
    321 ParallelAggregateRenumberer<Graph,I>& renumberer)
    \n+
    322 {
    \n+
    323 std::vector<char> attributes(static_cast<std::size_t>(renumberer));
    \n
    324
    \n-
    325 template<typename M, typename C, typename C1>
    \n-
    326 bool repartitionAndDistributeMatrix(const M& origMatrix,
    \n-
    327 std::shared_ptr<M> newMatrix,
    \n-
    328 C& origComm,
    \n-
    329 std::shared_ptr<C>& newComm,
    \n-\n-
    331 int nparts, C1& criterion)
    \n-
    332 {
    \n-
    333 Timer time;
    \n-
    334#ifdef AMG_REPART_ON_COMM_GRAPH
    \n-
    335 // Done not repartition the matrix graph, but a graph of the communication scheme.
    \n-
    336 bool existentOnRedist=Dune::commGraphRepartition(origMatrix, origComm, nparts, newComm,
    \n-
    337 ri.getInterface(),
    \n-
    338 criterion.debugLevel()>1);
    \n-
    339
    \n-
    340#else
    \n-\n-\n-\n-\n-
    345 IdentityMap,
    \n-
    346 IdentityMap> PropertiesGraph;
    \n-
    347 MatrixGraph graph(origMatrix);
    \n-
    348 PropertiesGraph pgraph(graph);
    \n-
    349 buildDependency(pgraph, origMatrix, criterion, false);
    \n-
    350
    \n-
    351#ifdef DEBUG_REPART
    \n-
    352 if(origComm.communicator().rank()==0)
    \n-
    353 std::cout<<"Original matrix"<<std::endl;
    \n-
    354 origComm.communicator().barrier();
    \n-
    355 printGlobalSparseMatrix(origMatrix, origComm, std::cout);
    \n-
    356#endif
    \n-
    357 bool existentOnRedist=Dune::graphRepartition(pgraph, origComm, nparts,
    \n-
    358 newComm, ri.getInterface(),
    \n-
    359 criterion.debugLevel()>1);
    \n-
    360#endif // if else AMG_REPART
    \n-
    361
    \n-
    362 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)
    \n-
    363 std::cout<<"Repartitioning took "<<time.elapsed()<<" seconds."<<std::endl;
    \n-
    364
    \n-
    365 ri.setSetup();
    \n-
    366
    \n-
    367#ifdef DEBUG_REPART
    \n-
    368 ri.checkInterface(origComm.indexSet(), newComm->indexSet(), origComm.communicator());
    \n-
    369#endif
    \n-
    370
    \n-
    371 redistributeMatrix(const_cast<M&>(origMatrix), *newMatrix, origComm, *newComm, ri);
    \n-
    372
    \n-
    373#ifdef DEBUG_REPART
    \n-
    374 if(origComm.communicator().rank()==0)
    \n-
    375 std::cout<<"Original matrix"<<std::endl;
    \n-
    376 origComm.communicator().barrier();
    \n-
    377 if(newComm->communicator().size()>0)
    \n-
    378 printGlobalSparseMatrix(*newMatrix, *newComm, std::cout);
    \n-
    379 origComm.communicator().barrier();
    \n-
    380#endif
    \n+
    325 GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
    \n+
    326
    \n+
    327 typedef typename RemoteIndices::const_iterator Iterator;
    \n+
    328 Iterator end = fineRemote.end();
    \n+
    329
    \n+
    330 for(Iterator neighbour = fineRemote.begin();
    \n+
    331 neighbour != end; ++neighbour) {
    \n+
    332 int process = neighbour->first;
    \n+
    333
    \n+
    334 assert(neighbour->second.first==neighbour->second.second);
    \n+
    335
    \n+
    336 // Mark all as not known
    \n+
    337 typedef typename std::vector<char>::iterator CIterator;
    \n+
    338
    \n+
    339 for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
    \n+
    340 *iter = std::numeric_limits<char>::max();
    \n+
    341
    \n+
    342 auto riEnd = neighbour->second.second->end();
    \n+
    343
    \n+
    344 for(auto index = neighbour->second.second->begin();
    \n+
    345 index != riEnd; ++index) {
    \n+
    346 if(!E::contains(index->localIndexPair().local().attribute()) &&
    \n+
    347 aggregates[index->localIndexPair().local()] !=
    \n+\n+
    349 {
    \n+
    350 assert(aggregates[index->localIndexPair().local()]<attributes.size());
    \n+
    351 if (attributes[aggregates[index->localIndexPair().local()]] != 3)
    \n+
    352 attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
    \n+
    353 }
    \n+
    354 }
    \n+
    355
    \n+
    356 // Build remote index list
    \n+
    357 typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
    \n+
    358 typedef typename RemoteIndices::RemoteIndex RemoteIndex;
    \n+
    359 typedef typename ParallelIndexSet::const_iterator IndexIterator;
    \n+
    360
    \n+
    361 Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
    \n+
    362
    \n+
    363 IndexIterator iend = coarseIndices.end();
    \n+
    364 for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
    \n+
    365 if(attributes[index->local()] != std::numeric_limits<char>::max()) {
    \n+
    366 // remote index is present
    \n+
    367 coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
    \n+
    368 }
    \n+
    369 //std::cout<<coarseRemote<<std::endl;
    \n+
    370 }
    \n+
    371
    \n+
    372 // The number of neighbours should not change!
    \n+
    373 assert(coarseRemote.neighbours()==fineRemote.neighbours());
    \n+
    374
    \n+
    375 // snyc the index set and the remote indices to recompute missing
    \n+
    376 // indices
    \n+
    377 IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
    \n+
    378 syncer.sync(renumberer);
    \n+
    379
    \n+
    380 }
    \n
    381
    \n-
    382 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)
    \n-
    383 std::cout<<"Redistributing matrix took "<<time.elapsed()<<" seconds."<<std::endl;
    \n-
    384 return existentOnRedist;
    \n-
    385
    \n-
    386 }
    \n-
    387
    \n-
    388 template<class M, class IS, class A>
    \n-
    389 MatrixHierarchy<M,IS,A>::MatrixHierarchy(std::shared_ptr<MatrixOperator> fineMatrix,
    \n-
    390 std::shared_ptr<ParallelInformation> pinfo)
    \n-
    391 : matrices_(fineMatrix),
    \n-
    392 parallelInformation_(pinfo)
    \n-
    393 {
    \n-
    394 if (SolverCategory::category(*fineMatrix) != SolverCategory::category(*pinfo))
    \n-
    395 DUNE_THROW(ISTLError, "MatrixOperator and ParallelInformation must belong to the same category!");
    \n+
    382#endif
    \n+
    383
    \n+
    384 template<typename E>
    \n+
    385 template<typename Graph, typename VM>
    \n+
    386 typename Graph::VertexDescriptor
    \n+\n+
    388 [[maybe_unused]] const SequentialInformation& fineInfo,
    \n+
    389 [[maybe_unused]] Graph& fineGraph,
    \n+
    390 [[maybe_unused]] VM& visitedMap,
    \n+
    391 [[maybe_unused]] AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
    \n+
    392 [[maybe_unused]] SequentialInformation& coarseInfo,
    \n+
    393 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
    \n+
    394 {
    \n+
    395 return noAggregates;
    \n
    396 }
    \n
    397
    \n-
    398 template<class M, class IS, class A>
    \n-
    399 template<typename O, typename T>
    \n-
    400 void MatrixHierarchy<M,IS,A>::build(const T& criterion)
    \n-
    401 {
    \n-
    402 prolongDamp_ = criterion.getProlongationDampingFactor();
    \n-
    403 typedef O OverlapFlags;
    \n-
    404 typedef typename ParallelMatrixHierarchy::Iterator MatIterator;
    \n-
    405 typedef typename ParallelInformationHierarchy::Iterator PInfoIterator;
    \n-
    406
    \n-
    407 static const int noints=(Dune::Amg::MAX_PROCESSES/4096>0) ? (Dune::Amg::MAX_PROCESSES/4096) : 1;
    \n-
    408
    \n-
    409 typedef bigunsignedint<sizeof(int)*8*noints> BIGINT;
    \n-\n-
    411 MatIterator mlevel = matrices_.finest();
    \n-
    412 MatrixStats<typename M::matrix_type,MINIMAL_DEBUG_LEVEL<=INFO_DEBUG_LEVEL>::stats(mlevel->getmat());
    \n-
    413
    \n-
    414 PInfoIterator infoLevel = parallelInformation_.finest();
    \n-
    415 BIGINT finenonzeros=countNonZeros(mlevel->getmat());
    \n-
    416 finenonzeros = infoLevel->communicator().sum(finenonzeros);
    \n-
    417 BIGINT allnonzeros = finenonzeros;
    \n-
    418
    \n-
    419
    \n-
    420 int level = 0;
    \n-
    421 int rank = 0;
    \n-
    422
    \n-
    423 BIGINT unknowns = mlevel->getmat().N();
    \n-
    424
    \n-
    425 unknowns = infoLevel->communicator().sum(unknowns);
    \n-
    426 double dunknowns=unknowns.todouble();
    \n-
    427 infoLevel->buildGlobalLookup(mlevel->getmat().N());
    \n-
    428 redistributes_.push_back(RedistributeInfoType());
    \n-
    429
    \n-
    430 for(; level < criterion.maxLevel(); ++level, ++mlevel) {
    \n-
    431 assert(matrices_.levels()==redistributes_.size());
    \n-
    432 rank = infoLevel->communicator().rank();
    \n-
    433 if(rank==0 && criterion.debugLevel()>1)
    \n-
    434 std::cout<<"Level "<<level<<" has "<<dunknowns<<" unknowns, "<<dunknowns/infoLevel->communicator().size()
    \n-
    435 <<" unknowns per proc (procs="<<infoLevel->communicator().size()<<")"<<std::endl;
    \n-
    436
    \n-
    437 MatrixOperator* matrix=&(*mlevel);
    \n-
    438 ParallelInformation* info =&(*infoLevel);
    \n-
    439
    \n-
    440 if((
    \n-
    441#if HAVE_PARMETIS
    \n-
    442 criterion.accumulate()==successiveAccu
    \n-
    443#else
    \n-
    444 false
    \n-
    445#endif
    \n-
    446 || (criterion.accumulate()==atOnceAccu
    \n-
    447 && dunknowns < 30*infoLevel->communicator().size()))
    \n-
    448 && infoLevel->communicator().size()>1 &&
    \n-
    449 dunknowns/infoLevel->communicator().size() <= criterion.coarsenTarget())
    \n-
    450 {
    \n-
    451 // accumulate to fewer processors
    \n-
    452 std::shared_ptr<Matrix> redistMat = std::make_shared<Matrix>();
    \n-
    453 std::shared_ptr<ParallelInformation> redistComm;
    \n-
    454 std::size_t nodomains = (std::size_t)std::ceil(dunknowns/(criterion.minAggregateSize()
    \n-
    455 *criterion.coarsenTarget()));
    \n-
    456 if( nodomains<=criterion.minAggregateSize()/2 ||
    \n-
    457 dunknowns <= criterion.coarsenTarget() )
    \n-
    458 nodomains=1;
    \n-
    459
    \n-
    460 bool existentOnNextLevel =
    \n-
    461 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,
    \n-
    462 redistComm, redistributes_.back(), nodomains,
    \n-
    463 criterion);
    \n-
    464 BIGINT unknownsRedist = redistMat->N();
    \n-
    465 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);
    \n-
    466 dunknowns= unknownsRedist.todouble();
    \n-
    467 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1)
    \n-
    468 std::cout<<"Level "<<level<<" (redistributed) has "<<dunknowns<<" unknowns, "<<dunknowns/redistComm->communicator().size()
    \n-
    469 <<" unknowns per proc (procs="<<redistComm->communicator().size()<<")"<<std::endl;
    \n-
    470 MatrixArgs args(redistMat, *redistComm);
    \n-
    471 mlevel.addRedistributed(ConstructionTraits<MatrixOperator>::construct(args));
    \n-
    472 assert(mlevel.isRedistributed());
    \n-
    473 infoLevel.addRedistributed(redistComm);
    \n-
    474 infoLevel->freeGlobalLookup();
    \n-
    475
    \n-
    476 if(!existentOnNextLevel)
    \n-
    477 // We do not hold any data on the redistributed partitioning
    \n-
    478 break;
    \n-
    479
    \n-
    480 // Work on the redistributed Matrix from now on
    \n-
    481 matrix = &(mlevel.getRedistributed());
    \n-
    482 info = &(infoLevel.getRedistributed());
    \n-
    483 info->buildGlobalLookup(matrix->getmat().N());
    \n-
    484 }
    \n-
    485
    \n-
    486 rank = info->communicator().rank();
    \n-
    487 if(dunknowns <= criterion.coarsenTarget())
    \n-
    488 // No further coarsening needed
    \n-
    489 break;
    \n-
    490
    \n-\n-
    492 typedef typename GraphCreator::PropertiesGraph PropertiesGraph;
    \n-
    493 typedef typename GraphCreator::GraphTuple GraphTuple;
    \n-
    494
    \n-
    495 typedef typename PropertiesGraph::VertexDescriptor Vertex;
    \n-
    496
    \n-
    497 std::vector<bool> excluded(matrix->getmat().N(), false);
    \n-
    498
    \n-
    499 GraphTuple graphs = GraphCreator::create(*matrix, excluded, *info, OverlapFlags());
    \n-
    500
    \n-
    501 AggregatesMap* aggregatesMap=new AggregatesMap(std::get<1>(graphs)->maxVertex()+1);
    \n-
    502
    \n-
    503 aggregatesMaps_.push_back(aggregatesMap);
    \n-
    504
    \n-
    505 Timer watch;
    \n-
    506 watch.reset();
    \n-
    507 auto [noAggregates, isoAggregates, oneAggregates, skippedAggregates] =
    \n-
    508 aggregatesMap->buildAggregates(matrix->getmat(), *(std::get<1>(graphs)), criterion, level==0);
    \n-
    509
    \n-
    510 if(rank==0 && criterion.debugLevel()>2)
    \n-
    511 std::cout<<" Have built "<<noAggregates<<" aggregates totally ("<<isoAggregates<<" isolated aggregates, "<<
    \n-
    512 oneAggregates<<" aggregates of one vertex, and skipped "<<
    \n-
    513 skippedAggregates<<" aggregates)."<<std::endl;
    \n-
    514#ifdef TEST_AGGLO
    \n-
    515 {
    \n-
    516 // calculate size of local matrix in the distributed direction
    \n-
    517 int start, end, overlapStart, overlapEnd;
    \n-
    518 int procs=info->communicator().rank();
    \n-
    519 int n = UNKNOWNS/procs; // number of unknowns per process
    \n-
    520 int bigger = UNKNOWNS%procs; // number of process with n+1 unknows
    \n-
    521
    \n-
    522 // Compute owner region
    \n-
    523 if(rank<bigger) {
    \n-
    524 start = rank*(n+1);
    \n-
    525 end = (rank+1)*(n+1);
    \n-
    526 }else{
    \n-
    527 start = bigger + rank * n;
    \n-
    528 end = bigger + (rank + 1) * n;
    \n-
    529 }
    \n-
    530
    \n-
    531 // Compute overlap region
    \n-
    532 if(start>0)
    \n-
    533 overlapStart = start - 1;
    \n-
    534 else
    \n-
    535 overlapStart = start;
    \n-
    536
    \n-
    537 if(end<UNKNOWNS)
    \n-
    538 overlapEnd = end + 1;
    \n-
    539 else
    \n-
    540 overlapEnd = end;
    \n-
    541
    \n-
    542 assert((UNKNOWNS)*(overlapEnd-overlapStart)==aggregatesMap->noVertices());
    \n-
    543 for(int j=0; j< UNKNOWNS; ++j)
    \n-
    544 for(int i=0; i < UNKNOWNS; ++i)
    \n-
    545 {
    \n-
    546 if(i>=overlapStart && i<overlapEnd)
    \n-
    547 {
    \n-
    548 int no = (j/2)*((UNKNOWNS)/2)+i/2;
    \n-
    549 (*aggregatesMap)[j*(overlapEnd-overlapStart)+i-overlapStart]=no;
    \n-
    550 }
    \n-
    551 }
    \n-
    552 }
    \n-
    553#endif
    \n-
    554 if(criterion.debugLevel()>1 && info->communicator().rank()==0)
    \n-
    555 std::cout<<"aggregating finished."<<std::endl;
    \n-
    556
    \n-
    557 BIGINT gnoAggregates=noAggregates;
    \n-
    558 gnoAggregates = info->communicator().sum(gnoAggregates);
    \n-
    559 double dgnoAggregates = gnoAggregates.todouble();
    \n-
    560#ifdef TEST_AGGLO
    \n-
    561 BIGINT gnoAggregates=((UNKNOWNS)/2)*((UNKNOWNS)/2);
    \n-
    562#endif
    \n-
    563
    \n-
    564 if(criterion.debugLevel()>2 && rank==0)
    \n-
    565 std::cout << "Building "<<dgnoAggregates<<" aggregates took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    566
    \n-
    567 if(dgnoAggregates==0 || dunknowns/dgnoAggregates<criterion.minCoarsenRate())
    \n-
    568 {
    \n-
    569 if(rank==0)
    \n-
    570 {
    \n-
    571 if(dgnoAggregates>0)
    \n-
    572 std::cerr << "Stopped coarsening because of rate breakdown "<<dunknowns<<"/"<<dgnoAggregates
    \n-
    573 <<"="<<dunknowns/dgnoAggregates<<"<"
    \n-
    574 <<criterion.minCoarsenRate()<<std::endl;
    \n-
    575 else
    \n-
    576 std::cerr<< "Could not build any aggregates. Probably no connected nodes."<<std::endl;
    \n-
    577 }
    \n-
    578 aggregatesMap->free();
    \n-
    579 delete aggregatesMap;
    \n-
    580 aggregatesMaps_.pop_back();
    \n-
    581
    \n-
    582 if(criterion.accumulate() && mlevel.isRedistributed() && info->communicator().size()>1) {
    \n-
    583 // coarse level matrix was already redistributed, but to more than 1 process
    \n-
    584 // Therefore need to delete the redistribution. Further down it will
    \n-
    585 // then be redistributed to 1 process
    \n-
    586 delete &(mlevel.getRedistributed().getmat());
    \n-
    587 mlevel.deleteRedistributed();
    \n-
    588 delete &(infoLevel.getRedistributed());
    \n-
    589 infoLevel.deleteRedistributed();
    \n-
    590 redistributes_.back().resetSetup();
    \n-
    591 }
    \n-
    592
    \n-
    593 break;
    \n-
    594 }
    \n-
    595 unknowns = noAggregates;
    \n-
    596 dunknowns = dgnoAggregates;
    \n-
    597
    \n-
    598 CommunicationArgs commargs(info->communicator(),info->category());
    \n-
    599 parallelInformation_.addCoarser(commargs);
    \n-
    600
    \n-
    601 ++infoLevel; // parallel information on coarse level
    \n-
    602
    \n-
    603 typename PropertyMapTypeSelector<VertexVisitedTag,PropertiesGraph>::Type visitedMap =
    \n-
    604 get(VertexVisitedTag(), *(std::get<1>(graphs)));
    \n-
    605
    \n-
    606 watch.reset();
    \n-\n-
    608 ::coarsen(*info,
    \n-
    609 *(std::get<1>(graphs)),
    \n-
    610 visitedMap,
    \n-
    611 *aggregatesMap,
    \n-
    612 *infoLevel,
    \n-
    613 noAggregates);
    \n-
    614 GraphCreator::free(graphs);
    \n-
    615
    \n-
    616 if(criterion.debugLevel()>2) {
    \n-
    617 if(rank==0)
    \n-
    618 std::cout<<"Coarsening of index sets took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    619 }
    \n-
    620
    \n-
    621 watch.reset();
    \n-
    622
    \n-
    623 infoLevel->buildGlobalLookup(aggregates);
    \n-\n-
    625 *info,
    \n-
    626 infoLevel->globalLookup());
    \n-
    627
    \n-
    628
    \n-
    629 if(criterion.debugLevel()>2) {
    \n-
    630 if(rank==0)
    \n-
    631 std::cout<<"Communicating global aggregate numbers took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    632 }
    \n-
    633
    \n-
    634 watch.reset();
    \n-
    635 std::vector<bool>& visited=excluded;
    \n-
    636
    \n-
    637 typedef std::vector<bool>::iterator Iterator;
    \n-
    638 typedef IteratorPropertyMap<Iterator, IdentityMap> VisitedMap2;
    \n-
    639 Iterator end = visited.end();
    \n-
    640 for(Iterator iter= visited.begin(); iter != end; ++iter)
    \n-
    641 *iter=false;
    \n-
    642
    \n-
    643 VisitedMap2 visitedMap2(visited.begin(), Dune::IdentityMap());
    \n-
    644
    \n-
    645 std::shared_ptr<typename MatrixOperator::matrix_type>
    \n-
    646 coarseMatrix(productBuilder.build(*(std::get<0>(graphs)), visitedMap2,
    \n-
    647 *info,
    \n-
    648 *aggregatesMap,
    \n-
    649 aggregates,
    \n-
    650 OverlapFlags()));
    \n-
    651 dverb<<"Building of sparsity pattern took "<<watch.elapsed()<<std::endl;
    \n-
    652 watch.reset();
    \n-
    653 info->freeGlobalLookup();
    \n-
    654
    \n-
    655 delete std::get<0>(graphs);
    \n-
    656 productBuilder.calculate(matrix->getmat(), *aggregatesMap, *coarseMatrix, *infoLevel, OverlapFlags());
    \n-
    657
    \n-
    658 if(criterion.debugLevel()>2) {
    \n-
    659 if(rank==0)
    \n-
    660 std::cout<<"Calculation entries of Galerkin product took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n-
    661 }
    \n-
    662
    \n-
    663 BIGINT nonzeros = countNonZeros(*coarseMatrix);
    \n-
    664 allnonzeros = allnonzeros + infoLevel->communicator().sum(nonzeros);
    \n-
    665 MatrixArgs args(coarseMatrix, *infoLevel);
    \n-
    666
    \n-
    667 matrices_.addCoarser(args);
    \n-
    668 redistributes_.push_back(RedistributeInfoType());
    \n-
    669 } // end level loop
    \n-
    670
    \n-
    671
    \n-
    672 infoLevel->freeGlobalLookup();
    \n-
    673
    \n-
    674 built_=true;
    \n-
    675 AggregatesMap* aggregatesMap=new AggregatesMap(0);
    \n-
    676 aggregatesMaps_.push_back(aggregatesMap);
    \n-
    677
    \n-
    678 if(criterion.debugLevel()>0) {
    \n-
    679 if(level==criterion.maxLevel()) {
    \n-
    680 BIGINT unknownsLevel = mlevel->getmat().N();
    \n-
    681 unknownsLevel = infoLevel->communicator().sum(unknownsLevel);
    \n-
    682 double dunknownsLevel = unknownsLevel.todouble();
    \n-
    683 if(rank==0 && criterion.debugLevel()>1) {
    \n-
    684 std::cout<<"Level "<<level<<" has "<<dunknownsLevel<<" unknowns, "<<dunknownsLevel/infoLevel->communicator().size()
    \n-
    685 <<" unknowns per proc (procs="<<infoLevel->communicator().size()<<")"<<std::endl;
    \n-
    686 }
    \n-
    687 }
    \n-
    688 }
    \n-
    689
    \n-
    690 if(criterion.accumulate() && !redistributes_.back().isSetup() &&
    \n-
    691 infoLevel->communicator().size()>1) {
    \n-
    692#if HAVE_MPI && !HAVE_PARMETIS
    \n-
    693 if(criterion.accumulate()==successiveAccu &&
    \n-
    694 infoLevel->communicator().rank()==0)
    \n-
    695 std::cerr<<"Successive accumulation of data on coarse levels only works with ParMETIS installed."
    \n-
    696 <<" Fell back to accumulation to one domain on coarsest level"<<std::endl;
    \n-
    697#endif
    \n-
    698
    \n-
    699 // accumulate to fewer processors
    \n-
    700 std::shared_ptr<Matrix> redistMat = std::make_shared<Matrix>();
    \n-
    701 std::shared_ptr<ParallelInformation> redistComm;
    \n-
    702 int nodomains = 1;
    \n-
    703
    \n-
    704 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,
    \n-
    705 redistComm, redistributes_.back(), nodomains,criterion);
    \n-
    706 MatrixArgs args(redistMat, *redistComm);
    \n-
    707 BIGINT unknownsRedist = redistMat->N();
    \n-
    708 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);
    \n-
    709
    \n-
    710 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1) {
    \n-
    711 double dunknownsRedist = unknownsRedist.todouble();
    \n-
    712 std::cout<<"Level "<<level<<" redistributed has "<<dunknownsRedist<<" unknowns, "<<dunknownsRedist/redistComm->communicator().size()
    \n-
    713 <<" unknowns per proc (procs="<<redistComm->communicator().size()<<")"<<std::endl;
    \n-
    714 }
    \n-
    715 mlevel.addRedistributed(ConstructionTraits<MatrixOperator>::construct(args));
    \n-
    716 infoLevel.addRedistributed(redistComm);
    \n-
    717 infoLevel->freeGlobalLookup();
    \n-
    718 }
    \n-
    719
    \n-
    720 int levels = matrices_.levels();
    \n-
    721 maxlevels_ = parallelInformation_.finest()->communicator().max(levels);
    \n-
    722 assert(matrices_.levels()==redistributes_.size());
    \n-
    723 if(hasCoarsest() && rank==0 && criterion.debugLevel()>1)
    \n-
    724 std::cout<<"operator complexity: "<<allnonzeros.todouble()/finenonzeros.todouble()<<std::endl;
    \n-
    725
    \n-
    726 }
    \n-
    727
    \n-
    728 template<class M, class IS, class A>
    \n-\n-\n-
    731 {
    \n-
    732 return matrices_;
    \n-
    733 }
    \n-
    734
    \n-
    735 template<class M, class IS, class A>
    \n-\n-\n-
    738 {
    \n-
    739 return parallelInformation_;
    \n-
    740 }
    \n-
    741
    \n-
    742 template<class M, class IS, class A>
    \n-
    743 void MatrixHierarchy<M,IS,A>::getCoarsestAggregatesOnFinest(std::vector<std::size_t>& data) const
    \n-
    744 {
    \n-
    745 int levels=aggregatesMaps().size();
    \n-
    746 int maxlevels=parallelInformation_.finest()->communicator().max(levels);
    \n-
    747 std::size_t size=(*(aggregatesMaps().begin()))->noVertices();
    \n-
    748 // We need an auxiliary vector for the consecutive prolongation.
    \n-
    749 std::vector<std::size_t> tmp;
    \n-
    750 std::vector<std::size_t> *coarse, *fine;
    \n-
    751
    \n-
    752 // make sure the allocated space suffices.
    \n-
    753 tmp.reserve(size);
    \n-
    754 data.reserve(size);
    \n-
    755
    \n-
    756 // Correctly assign coarse and fine for the first prolongation such that
    \n-
    757 // we end up in data in the end.
    \n-
    758 if(levels%2==0) {
    \n-
    759 coarse=&tmp;
    \n-
    760 fine=&data;
    \n-
    761 }else{
    \n-
    762 coarse=&data;
    \n-
    763 fine=&tmp;
    \n-
    764 }
    \n-
    765
    \n-
    766 // Number the unknowns on the coarsest level consecutively for each process.
    \n-
    767 if(levels==maxlevels) {
    \n-
    768 const AggregatesMap& map = *(*(++aggregatesMaps().rbegin()));
    \n-
    769 std::size_t m=0;
    \n-
    770
    \n-
    771 for(typename AggregatesMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
    \n-
    772 if(*iter< AggregatesMap::ISOLATED)
    \n-
    773 m=std::max(*iter,m);
    \n-
    774
    \n-
    775 coarse->resize(m+1);
    \n-
    776 std::size_t i=0;
    \n-
    777 srand((unsigned)std::clock());
    \n-
    778 std::set<size_t> used;
    \n-
    779 for(typename std::vector<std::size_t>::iterator iter=coarse->begin(); iter != coarse->end();
    \n-
    780 ++iter, ++i)
    \n-
    781 {
    \n-
    782 std::pair<std::set<std::size_t>::iterator,bool> ibpair
    \n-
    783 = used.insert(static_cast<std::size_t>((((double)rand())/(RAND_MAX+1.0)))*coarse->size());
    \n-
    784
    \n-
    785 while(!ibpair.second)
    \n-
    786 ibpair = used.insert(static_cast<std::size_t>((((double)rand())/(RAND_MAX+1.0))*coarse->size()));
    \n-
    787 *iter=*(ibpair.first);
    \n-
    788 }
    \n-
    789 }
    \n-
    790
    \n-
    791 typename ParallelInformationHierarchy::Iterator pinfo = parallelInformation().coarsest();
    \n-
    792 --pinfo;
    \n-
    793
    \n-
    794 // Now consecutively project the numbers to the finest level.
    \n-
    795 for(typename AggregatesMapList::const_reverse_iterator aggregates=++aggregatesMaps().rbegin();
    \n-
    796 aggregates != aggregatesMaps().rend(); ++aggregates,--levels) {
    \n-
    797
    \n-
    798 fine->resize((*aggregates)->noVertices());
    \n-
    799 fine->assign(fine->size(), 0);
    \n-\n-
    801 ::prolongateVector(*(*aggregates), *coarse, *fine, static_cast<std::size_t>(1), *pinfo);
    \n-
    802 --pinfo;
    \n-
    803 std::swap(coarse, fine);
    \n-
    804 }
    \n-
    805
    \n-
    806 // Assertion to check that we really projected to data on the last step.
    \n-
    807 assert(coarse==&data);
    \n-
    808 }
    \n-
    809
    \n-
    810 template<class M, class IS, class A>
    \n-\n-\n-
    813 {
    \n-
    814 return aggregatesMaps_;
    \n-
    815 }
    \n-
    816 template<class M, class IS, class A>
    \n-\n-\n-
    819 {
    \n-
    820 return redistributes_;
    \n-
    821 }
    \n-
    822
    \n-
    823 template<class M, class IS, class A>
    \n-\n-
    825 {
    \n-
    826 typedef typename AggregatesMapList::reverse_iterator AggregatesMapIterator;
    \n-
    827 typedef typename ParallelMatrixHierarchy::Iterator Iterator;
    \n-
    828 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
    \n-
    829
    \n-
    830 AggregatesMapIterator amap = aggregatesMaps_.rbegin();
    \n-
    831 InfoIterator info = parallelInformation_.coarsest();
    \n-
    832 for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level != finest; --level, --info, ++amap) {
    \n-
    833 (*amap)->free();
    \n-
    834 delete *amap;
    \n-
    835 }
    \n-
    836 delete *amap;
    \n-
    837 }
    \n-
    838
    \n-
    839 template<class M, class IS, class A>
    \n-
    840 template<class V, class BA, class TA>
    \n-\n-
    842 {
    \n-
    843 assert(hierarchy.levels()==1);
    \n-
    844 typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;
    \n-
    845 typedef typename RedistributeInfoList::const_iterator RIter;
    \n-
    846 RIter redist = redistributes_.begin();
    \n-
    847
    \n-
    848 Iterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();
    \n-
    849 int level=0;
    \n-
    850 if(redist->isSetup())
    \n-
    851 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N());
    \n-
    852 Dune::dvverb<<"Level "<<level<<" has "<<matrices_.finest()->getmat().N()<<" unknowns!"<<std::endl;
    \n-
    853
    \n-
    854 while(matrix != coarsest) {
    \n-
    855 ++matrix; ++level; ++redist;
    \n-
    856 Dune::dvverb<<"Level "<<level<<" has "<<matrix->getmat().N()<<" unknowns!"<<std::endl;
    \n-
    857
    \n-
    858 hierarchy.addCoarser(matrix->getmat().N());
    \n-
    859 if(redist->isSetup())
    \n-
    860 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N());
    \n-
    861
    \n-
    862 }
    \n-
    863
    \n-
    864 }
    \n-
    865
    \n-
    866 template<class M, class IS, class A>
    \n-
    867 template<class S, class TA>
    \n-\n-
    869 const typename SmootherTraits<S>::Arguments& sargs) const
    \n-
    870 {
    \n-
    871 assert(smoothers.levels()==0);
    \n-
    872 typedef typename ParallelMatrixHierarchy::ConstIterator MatrixIterator;
    \n-
    873 typedef typename ParallelInformationHierarchy::ConstIterator PinfoIterator;
    \n-
    874 typedef typename AggregatesMapList::const_iterator AggregatesIterator;
    \n-
    875
    \n-\n-
    877 cargs.setArgs(sargs);
    \n-
    878 PinfoIterator pinfo = parallelInformation_.finest();
    \n-
    879 AggregatesIterator aggregates = aggregatesMaps_.begin();
    \n-
    880 int level=0;
    \n-
    881 for(MatrixIterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();
    \n-
    882 matrix != coarsest; ++matrix, ++pinfo, ++aggregates, ++level) {
    \n-
    883 cargs.setMatrix(matrix->getmat(), **aggregates);
    \n-
    884 cargs.setComm(*pinfo);
    \n-
    885 smoothers.addCoarser(cargs);
    \n-
    886 }
    \n-
    887 if(maxlevels()>levels()) {
    \n-
    888 // This is not the globally coarsest level and therefore smoothing is needed
    \n-
    889 cargs.setMatrix(matrices_.coarsest()->getmat(), **aggregates);
    \n-
    890 cargs.setComm(*pinfo);
    \n-
    891 smoothers.addCoarser(cargs);
    \n-
    892 ++level;
    \n-
    893 }
    \n-
    894 }
    \n-
    895
    \n-
    896 template<class M, class IS, class A>
    \n-
    897 template<class F>
    \n-\n-
    899 {
    \n-
    900 typedef typename AggregatesMapList::iterator AggregatesMapIterator;
    \n-
    901 typedef typename ParallelMatrixHierarchy::Iterator Iterator;
    \n-
    902 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
    \n-
    903
    \n-
    904 AggregatesMapIterator amap = aggregatesMaps_.begin();
    \n-
    905 BaseGalerkinProduct productBuilder;
    \n-
    906 InfoIterator info = parallelInformation_.finest();
    \n-
    907 typename RedistributeInfoList::iterator riIter = redistributes_.begin();
    \n-
    908 Iterator level = matrices_.finest(), coarsest=matrices_.coarsest();
    \n-
    909 if(level.isRedistributed()) {
    \n-
    910 info->buildGlobalLookup(level->getmat().N());
    \n-
    911 redistributeMatrixEntries(const_cast<Matrix&>(level->getmat()),
    \n-
    912 const_cast<Matrix&>(level.getRedistributed().getmat()),
    \n-
    913 *info,info.getRedistributed(), *riIter);
    \n-
    914 info->freeGlobalLookup();
    \n-
    915 }
    \n-
    916
    \n-
    917 for(; level!=coarsest; ++amap) {
    \n-
    918 const Matrix& fine = (level.isRedistributed() ? level.getRedistributed() : *level).getmat();
    \n-
    919 ++level;
    \n-
    920 ++info;
    \n-
    921 ++riIter;
    \n-
    922 productBuilder.calculate(fine, *(*amap), const_cast<Matrix&>(level->getmat()), *info, copyFlags);
    \n-
    923 if(level.isRedistributed()) {
    \n-
    924 info->buildGlobalLookup(level->getmat().N());
    \n-
    925 redistributeMatrixEntries(const_cast<Matrix&>(level->getmat()),
    \n-
    926 const_cast<Matrix&>(level.getRedistributed().getmat()), *info,
    \n-
    927 info.getRedistributed(), *riIter);
    \n-
    928 info->freeGlobalLookup();
    \n-
    929 }
    \n-
    930 }
    \n-
    931 }
    \n-
    932
    \n-
    933 template<class M, class IS, class A>
    \n-\n-
    935 {
    \n-
    936 return matrices_.levels();
    \n-
    937 }
    \n-
    938
    \n-
    939 template<class M, class IS, class A>
    \n-\n-
    941 {
    \n-
    942 return maxlevels_;
    \n-
    943 }
    \n-
    944
    \n-
    945 template<class M, class IS, class A>
    \n-\n-
    947 {
    \n-
    948 return levels()==maxlevels() &&
    \n-
    949 (!matrices_.coarsest().isRedistributed() ||matrices_.coarsest()->getmat().N()>0);
    \n-
    950 }
    \n-
    951
    \n-
    952 template<class M, class IS, class A>
    \n-\n-
    954 {
    \n-
    955 return built_;
    \n-
    956 }
    \n-
    957
    \n-
    959 } // namespace Amg
    \n-
    960} // namespace Dune
    \n-
    961
    \n-
    962#endif // end DUNE_AMG_MATRIXHIERARCHY_HH
    \n-
    Some handy generic functions for ISTL matrices.
    \n-
    Functionality for redistributing a sparse matrix.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Provides classes for building the matrix graph.
    \n-
    Provides classes for the Coloring process of AMG.
    \n-
    Provides a class for building the galerkin product based on a aggregation scheme.
    \n-
    Provdes class for identifying aggregates globally.
    \n-
    Provides a classes representing the hierarchies in AMG.
    \n-
    Helper classes for the construction of classes without empty constructor.
    \n-\n-
    Prolongation and restriction for amg.
    \n-
    Provides a class for building the index set and remote indices on the coarse level.
    \n-\n-
    Classes for the generic construction and application of the smoothers.
    \n-
    Provides classes for initializing the link attributes of a matrix graph.
    \n-
    auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
    Get the number of nonzero fields in the matrix.
    Definition: matrixutils.hh:119
    \n-
    const AggregatesMapList & aggregatesMaps() const
    Get the hierarchy of the mappings of the nodes onto aggregates.
    Definition: matrixhierarchy.hh:812
    \n-
    bool isBuilt() const
    Whether the hierarchy was built.
    Definition: matrixhierarchy.hh:953
    \n-
    bool hasCoarsest() const
    Definition: matrixhierarchy.hh:946
    \n-
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: hierarchy.hh:322
    \n-
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: matrixhierarchy.hh:934
    \n-
    void addCoarser(Arguments &args)
    Add an element on a coarser level.
    Definition: hierarchy.hh:334
    \n-
    const RedistributeInfoList & redistributeInformation() const
    Get the hierarchy of the information about redistributions,.
    Definition: matrixhierarchy.hh:818
    \n-
    const ParallelInformationHierarchy & parallelInformation() const
    Get the hierarchy of the parallel data distribution information.
    Definition: matrixhierarchy.hh:737
    \n-
    bool repartitionAndDistributeMatrix(const M &origMatrix, std::shared_ptr< M > newMatrix, SequentialInformation &origComm, std::shared_ptr< SequentialInformation > &newComm, RedistributeInformation< SequentialInformation > &ri, int nparts, C1 &criterion)
    Definition: matrixhierarchy.hh:313
    \n-
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n-
    const ParallelMatrixHierarchy & matrices() const
    Get the matrix hierarchy.
    Definition: matrixhierarchy.hh:730
    \n-
    std::size_t maxlevels() const
    Get the max number of levels in the hierarchy of processors.
    Definition: matrixhierarchy.hh:940
    \n-
    const_iterator end() const
    Definition: aggregates.hh:730
    \n+
    398 } //namespace Amg
    \n+
    399} // namespace Dune
    \n+
    400#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+\n+\n+\n+
    LocalIndex::Attribute Attribute
    The type of the attribute.
    Definition: indicescoarsener.hh:70
    \n+
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: indicescoarsener.hh:116
    \n+
    void isPublic(bool b)
    Definition: indicescoarsener.hh:139
    \n+
    ParallelInformation::ParallelIndexSet ParallelIndexSet
    Definition: indicescoarsener.hh:55
    \n+
    bool isPublic()
    Definition: indicescoarsener.hh:134
    \n+
    ParallelIndexSet::LocalIndex LocalIndex
    The type of the local index.
    Definition: indicescoarsener.hh:65
    \n+
    T ParallelInformation
    The type of the parallel information.
    Definition: indicescoarsener.hh:53
    \n+
    Attribute attribute()
    Definition: indicescoarsener.hh:155
    \n+
    Vertex operator()(const GlobalIndex &global)
    Definition: indicescoarsener.hh:127
    \n+
    static Graph::VertexDescriptor coarsen(ParallelInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
    Build the coarse index set after the aggregatio.
    Definition: indicescoarsener.hh:229
    \n
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n-
    void recalculateGalerkin(const F &copyFlags)
    Recalculate the galerkin products.
    Definition: matrixhierarchy.hh:898
    \n-
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n-
    std::size_t noVertices() const
    Get the number of vertices.
    \n-
    void coarsenVector(Hierarchy< BlockVector< V, BA >, TA > &hierarchy) const
    Coarsen the vector hierarchy according to the matrix hierarchy.
    Definition: matrixhierarchy.hh:841
    \n-
    const AggregateDescriptor * const_iterator
    Definition: aggregates.hh:723
    \n-
    MatrixHierarchy(std::shared_ptr< MatrixOperator > fineMatrix, std::shared_ptr< ParallelInformation > pinfo=std::make_shared< ParallelInformation >())
    Constructor.
    Definition: matrixhierarchy.hh:389
    \n-
    AccumulationMode
    Identifiers for the different accumulation modes.
    Definition: parameters.hh:232
    \n-
    void build(const T &criterion)
    Build the matrix hierarchy using aggregation.
    Definition: matrixhierarchy.hh:400
    \n-
    void free()
    Free the allocated memory.
    \n-
    void coarsenSmoother(Hierarchy< S, TA > &smoothers, const typename SmootherTraits< S >::Arguments &args) const
    Coarsen the smoother hierarchy according to the matrix hierarchy.
    Definition: matrixhierarchy.hh:868
    \n-
    void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
    Build the dependency of the matrix graph.
    \n-
    std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph, const C &criterion, bool finestLevel)
    Build the aggregates.
    \n-
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n-
    void getCoarsestAggregatesOnFinest(std::vector< std::size_t > &data) const
    Get the mapping of fine level unknowns to coarse level aggregates.
    Definition: matrixhierarchy.hh:743
    \n-
    ~MatrixHierarchy()
    Definition: matrixhierarchy.hh:824
    \n-
    @ MAX_PROCESSES
    Hard limit for the number of processes allowed.
    Definition: matrixhierarchy.hh:50
    \n-
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n-
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n+
    ParallelIndexSet::GlobalIndex GlobalIndex
    The type of the global index.
    Definition: indicescoarsener.hh:60
    \n+
    void attribute(const Attribute &attribute)
    Definition: indicescoarsener.hh:150
    \n+
    E ExcludedAttributes
    The set of excluded attributes.
    Definition: indicescoarsener.hh:48
    \n+
    void globalIndex(const GlobalIndex &global)
    Definition: indicescoarsener.hh:165
    \n+
    Dune::RemoteIndices< ParallelIndexSet > RemoteIndices
    The type of the remote indices.
    Definition: indicescoarsener.hh:75
    \n+
    ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I &lookup)
    Definition: indicescoarsener.hh:110
    \n+
    const GlobalIndex & globalIndex() const
    Definition: indicescoarsener.hh:160
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)
    Definition: matrixutils.hh:154
    \n
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:757
    \n-
    bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:829
    \n-
    void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Redistribute a matrix according to given domain decompositions.
    Definition: matrixredistribute.hh:820
    \n-
    bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    execute a graph repartition for a giving graph and indexset.
    Definition: repartition.hh:1235
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n-
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n-
    Definition: matrixredistribute.hh:22
    \n-
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n-
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n-
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n-
    Definition: galerkin.hh:99
    \n-
    Definition: galerkin.hh:118
    \n-
    Definition: globalaggregates.hh:131
    \n-\n-
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n-
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:988
    \n-
    Definition: graphcreator.hh:22
    \n-\n-
    LevelIterator< Hierarchy< MatrixOperator, Allocator >, MatrixOperator > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n-
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n
    Definition: indicescoarsener.hh:36
    \n-
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n-
    typename std::allocator_traits< Allocator >::template rebind_alloc< AggregatesMap * > AAllocator
    Allocator for pointers.
    Definition: matrixhierarchy.hh:85
    \n-
    Dune::Amg::Hierarchy< ParallelInformation, Allocator > ParallelInformationHierarchy
    The type of the parallel informarion hierarchy.
    Definition: matrixhierarchy.hh:82
    \n-
    std::list< AggregatesMap *, AAllocator > AggregatesMapList
    The type of the aggregates maps list.
    Definition: matrixhierarchy.hh:88
    \n-
    PI ParallelInformation
    The type of the index set.
    Definition: matrixhierarchy.hh:70
    \n-
    Dune::Amg::Hierarchy< MatrixOperator, Allocator > ParallelMatrixHierarchy
    The type of the parallel matrix hierarchy.
    Definition: matrixhierarchy.hh:79
    \n-
    A Allocator
    The allocator to use.
    Definition: matrixhierarchy.hh:73
    \n-
    RedistributeInformation< ParallelInformation > RedistributeInfoType
    The type of the redistribute information.
    Definition: matrixhierarchy.hh:91
    \n-
    double getProlongationDampingFactor() const
    Definition: matrixhierarchy.hh:188
    \n-
    typename std::allocator_traits< Allocator >::template rebind_alloc< RedistributeInfoType > RILAllocator
    Allocator for RedistributeInfoType.
    Definition: matrixhierarchy.hh:94
    \n-
    std::list< RedistributeInfoType, RILAllocator > RedistributeInfoList
    The type of the list of redistribute information.
    Definition: matrixhierarchy.hh:97
    \n-
    Dune::Amg::AggregatesMap< typename MatrixGraph< Matrix >::VertexDescriptor > AggregatesMap
    The type of the aggregates map we use.
    Definition: matrixhierarchy.hh:76
    \n-
    MatrixOperator::matrix_type Matrix
    The type of the matrix.
    Definition: matrixhierarchy.hh:67
    \n-
    M MatrixOperator
    The type of the matrix operator.
    Definition: matrixhierarchy.hh:64
    \n-
    void operator()(const matrix_row &row)
    Definition: matrixhierarchy.hh:254
    \n-
    Matrix::row_type matrix_row
    Definition: matrixhierarchy.hh:245
    \n-
    size_type min
    Definition: matrixhierarchy.hh:261
    \n-\n-
    size_type max
    Definition: matrixhierarchy.hh:262
    \n-
    size_type sum
    Definition: matrixhierarchy.hh:263
    \n-
    Matrix::size_type size_type
    Definition: matrixhierarchy.hh:244
    \n-
    The criterion describing the stop criteria for the coarsening process.
    Definition: matrixhierarchy.hh:283
    \n-
    CoarsenCriterion(const Dune::Amg::Parameters &parms)
    Definition: matrixhierarchy.hh:306
    \n-
    T AggregationCriterion
    The criterion for tagging connections as strong and nodes as isolated. This might be e....
    Definition: matrixhierarchy.hh:289
    \n-
    CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: matrixhierarchy.hh:301
    \n-
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Definition: indicescoarsener.hh:43
    \n
    Definition: pinfo.hh:28
    \n-
    Tag idnetifying the visited property of a vertex.
    Definition: properties.hh:29
    \n-
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n-
    Definition: transfer.hh:32
    \n-
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    Definition: renumberer.hh:16
    \n+
    void operator++()
    Definition: renumberer.hh:57
    \n+
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: renumberer.hh:51
    \n+
    Vertex number_
    Definition: renumberer.hh:35
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,1282 +5,486 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-matrixhierarchy.hh\n+indicescoarsener.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_MATRIXHIERARCHY_HH\n- 6#define DUNE_AMG_MATRIXHIERARCHY_HH\n+ 5#ifndef DUNE_AMG_INDICESCOARSENER_HH\n+ 6#define DUNE_AMG_INDICESCOARSENER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \"aggregates.hh\"\n- 11#include \"graph.hh\"\n- 12#include \"galerkin.hh\"\n- 13#include \"renumberer.hh\"\n- 14#include \"graphcreator.hh\"\n- 15#include \"hierarchy.hh\"\n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23#include \n- 24#include \n- 25#include \n- 26#include \n- 27\n- 28namespace Dune\n- 29{\n- 30 namespace Amg\n- 31 {\n- 42 enum {\n- 50 MAX_PROCESSES = 72000\n-51 };\n- 52\n- 59 template >\n-60 class MatrixHierarchy\n- 61 {\n- 62 public:\n-64 typedef M MatrixOperator;\n- 65\n-67 typedef typename MatrixOperator::matrix_type Matrix;\n- 68\n-70 typedef PI ParallelInformation;\n+ 8#include \n+ 9#include \n+ 10#include \"renumberer.hh\"\n+ 11\n+ 12#if HAVE_MPI\n+ 13#include \n+ 14#endif\n+ 15\n+ 16#include \"pinfo.hh\"\n+ 17\n+ 18namespace Dune\n+ 19{\n+ 20 namespace Amg\n+ 21 {\n+ 22\n+ 34 template\n+35 class IndicesCoarsener\n+ 36 {};\n+ 37\n+ 38\n+ 39#if HAVE_MPI\n+ 40\n+ 41 template\n+42 class ParallelIndicesCoarsener\n+ 43 {\n+ 44 public:\n+48 typedef E ExcludedAttributes;\n+ 49\n+53 typedef T ParallelInformation;\n+ 54\n+55 typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;\n+ 56\n+60 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n+ 61\n+65 typedef typename ParallelIndexSet::LocalIndex LocalIndex;\n+ 66\n+70 typedef typename LocalIndex::Attribute Attribute;\n 71\n-73 typedef A Allocator;\n- 74\n-76 typedef Dune::Amg::AggregatesMap::\n-VertexDescriptor> AggregatesMap;\n- 77\n-79 typedef Dune::Amg::Hierarchy\n-ParallelMatrixHierarchy;\n- 80\n-82 typedef Dune::Amg::Hierarchy\n-ParallelInformationHierarchy;\n- 83\n-85 using AAllocator = typename std::allocator_traits::template\n-rebind_alloc;\n- 86\n-88 typedef std::list AggregatesMapList;\n- 89\n-91 typedef RedistributeInformation RedistributeInfoType;\n- 92\n-94 using RILAllocator = typename std::allocator_traits::template\n-rebind_alloc;\n- 95\n-97 typedef std::list RedistributeInfoList;\n- 98\n- 104 MatrixHierarchy(std::shared_ptr fineMatrix,\n- 105 std::shared_ptr pinfo = std::\n-make_shared());\n+75 typedef Dune::RemoteIndices RemoteIndices;\n+ 76\n+ 88 template\n+ 89 static typename Graph::VertexDescriptor\n+90 coarsen(ParallelInformation& fineInfo,\n+ 91 Graph& fineGraph,\n+ 92 VM& visitedMap,\n+ 93 AggregatesMap& aggregates,\n+ 94 ParallelInformation& coarseInfo,\n+ 95 typename Graph::VertexDescriptor noAggregates);\n+ 96\n+ 97 private:\n+ 98 template\n+ 99 class ParallelAggregateRenumberer : public AggregateRenumberer\n+ 100 {\n+ 101 typedef typename G::VertexDescriptor Vertex;\n+ 102\n+ 103 typedef I GlobalLookupIndexSet;\n+ 104\n+ 105 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;\n 106\n- 107 ~MatrixHierarchy();\n+ 107 typedef typename IndexPair::GlobalIndex GlobalIndex;\n 108\n- 114 template\n- 115 void build(const T& criterion);\n- 116\n- 124 template\n- 125 void recalculateGalerkin(const F& copyFlags);\n+ 109 public:\n+110 ParallelAggregateRenumberer(AggregatesMap& aggregates, const I&\n+lookup)\n+ 111 : AggregateRenumberer(aggregates), isPublic_(false), lookup_(lookup),\n+ 112 globalIndex_(std::numeric_limits::max())\n+ 113 {}\n+ 114\n+ 115\n+116 void operator()(const typename G::ConstEdgeIterator& edge)\n+ 117 {\n+ 118 AggregateRenumberer::operator()(edge);\n+ 119 const IndexPair* pair= lookup_.pair(edge.target());\n+ 120 if(pair!=0) {\n+ 121 globalIndex(pair->global());\n+ 122 attribute(pair->local().attribute());\n+ 123 isPublic(pair->local().isPublic());\n+ 124 }\n+ 125 }\n 126\n- 131 template\n- 132 void coarsenVector(Hierarchy, TA>& hierarchy) const;\n+127 Vertex operator()([[maybe_unused]] const GlobalIndex& global)\n+ 128 {\n+ 129 Vertex current = this->number_;\n+ 130 this->operator++();\n+ 131 return current;\n+ 132 }\n 133\n- 139 template\n- 140 void coarsenSmoother(Hierarchy& smoothers,\n- 141 const typename SmootherTraits::Arguments& args) const;\n- 142\n- 147 std::size_t levels() const;\n- 148\n- 153 std::size_t maxlevels() const;\n+134 bool isPublic()\n+ 135 {\n+ 136 return isPublic_;\n+ 137 }\n+ 138\n+139 void isPublic(bool b)\n+ 140 {\n+ 141 isPublic_ = isPublic_ || b;\n+ 142 }\n+ 143\n+144 void reset()\n+ 145 {\n+ 146 globalIndex_ = std::numeric_limits::max();\n+ 147 isPublic_=false;\n+ 148 }\n+ 149\n+150 void attribute(const Attribute& attribute)\n+ 151 {\n+ 152 attribute_=attribute;\n+ 153 }\n 154\n- 155 bool hasCoarsest() const;\n- 156\n- 161 bool isBuilt() const;\n- 162\n- 167 const ParallelMatrixHierarchy& matrices() const;\n- 168\n- 173 const ParallelInformationHierarchy& parallelInformation() const;\n- 174\n- 179 const AggregatesMapList& aggregatesMaps() const;\n- 180\n- 186 const RedistributeInfoList& redistributeInformation() const;\n- 187\n-188 double getProlongationDampingFactor() const\n- 189 {\n- 190 return prolongDamp_;\n- 191 }\n- 192\n- 203 void getCoarsestAggregatesOnFinest(std::vector& data) const;\n+155 Attribute attribute()\n+ 156 {\n+ 157 return attribute_;\n+ 158 }\n+ 159\n+160 const GlobalIndex& globalIndex() const\n+ 161 {\n+ 162 return globalIndex_;\n+ 163 }\n+ 164\n+165 void globalIndex(const GlobalIndex& global)\n+ 166 {\n+ 167 globalIndex_ = global;\n+ 168 }\n+ 169\n+ 170 private:\n+ 171 bool isPublic_;\n+ 172 Attribute attribute_;\n+ 173 const GlobalLookupIndexSet& lookup_;\n+ 174 GlobalIndex globalIndex_;\n+ 175 };\n+ 176\n+ 177 template\n+ 178 static void buildCoarseIndexSet(const ParallelInformation& pinfo,\n+ 179 Graph& fineGraph,\n+ 180 VM& visitedMap,\n+ 181 AggregatesMap& aggregates,\n+ 182 ParallelIndexSet& coarseIndices,\n+ 183 ParallelAggregateRenumberer& renumberer);\n+ 184\n+ 185 template\n+ 186 static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,\n+ 187 const AggregatesMap& aggregates,\n+ 188 ParallelIndexSet& coarseIndices,\n+ 189 RemoteIndices& coarseRemote,\n+ 190 ParallelAggregateRenumberer& renumberer);\n+ 191\n+ 192 };\n+ 193\n+ 197 template\n+198 class IndicesCoarsener,E>\n+ 199 : public ParallelIndicesCoarsener,E>\n+ 200 {};\n+ 201\n+ 202\n+ 203#endif\n 204\n- 205 private:\n- 206 typedef typename ConstructionTraits::Arguments MatrixArgs;\n- 207 typedef typename ConstructionTraits::Arguments\n-CommunicationArgs;\n- 209 AggregatesMapList aggregatesMaps_;\n- 211 RedistributeInfoList redistributes_;\n- 213 ParallelMatrixHierarchy matrices_;\n- 215 ParallelInformationHierarchy parallelInformation_;\n- 216\n- 218 bool built_;\n- 219\n- 221 int maxlevels_;\n- 222\n- 223 double prolongDamp_;\n+ 211 template\n+212 class IndicesCoarsener\n+ 213 {\n+ 214 public:\n+ 215 template\n+ 216 static typename Graph::VertexDescriptor\n+ 217 coarsen(const SequentialInformation & fineInfo,\n+ 218 Graph& fineGraph,\n+ 219 VM& visitedMap,\n+ 220 AggregatesMap& aggregates,\n+ 221 SequentialInformation& coarseInfo,\n+ 222 typename Graph::VertexDescriptor noAggregates);\n+ 223 };\n 224\n- 228 template\n- 229 struct MatrixStats\n- 230 {\n- 231\n- 235 static void stats([[maybe_unused]] const Matrix& matrix)\n- 236 {}\n- 237 };\n- 238\n- 239 template\n- 240 struct MatrixStats\n- 241 {\n-242 struct calc\n- 243 {\n-244 typedef typename Matrix::size_type size_type;\n-245 typedef typename Matrix::row_type matrix_row;\n- 246\n-247 calc()\n- 248 {\n- 249 min=std::numeric_limits::max();\n- 250 max=0;\n- 251 sum=0;\n- 252 }\n- 253\n-254 void operator()(const matrix_row& row)\n- 255 {\n- 256 min=std::min(min, row.size());\n- 257 max=std::max(max, row.size());\n- 258 sum += row.size();\n- 259 }\n- 260\n-261 size_type min;\n-262 size_type max;\n-263 size_type sum;\n- 264 };\n- 268 static void stats(const Matrix& matrix)\n- 269 {\n- 270 calc c= for_each(matrix.begin(), matrix.end(), calc());\n- 271 dinfo<<\"Matrix row: min=\"<(c.sum)/matrix.N()\n- 273 <\n+ 227 template\n+ 228 inline typename Graph::VertexDescriptor\n+229 ParallelIndicesCoarsener::coarsen(ParallelInformation& fineInfo,\n+ 230 Graph& fineGraph,\n+ 231 VM& visitedMap,\n+ 232 AggregatesMap& aggregates,\n+ 233 ParallelInformation& coarseInfo,\n+ 234 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)\n+ 235 {\n+ 236 ParallelAggregateRenumberer renumberer(aggregates, fineInfo.globalLookup());\n+ 237 buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,\n+ 238 coarseInfo.indexSet(), renumberer);\n+ 239 buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates,\n+coarseInfo.indexSet(),\n+ 240 coarseInfo.remoteIndices(), renumberer);\n+ 241\n+ 242 return renumberer;\n+ 243 }\n+ 244\n+ 245 template\n+ 246 template\n+ 247 void ParallelIndicesCoarsener::buildCoarseIndexSet(const\n+ParallelInformation& pinfo,\n+ 248 Graph& fineGraph,\n+ 249 VM& visitedMap,\n+ 250 AggregatesMap& aggregates,\n+ 251 ParallelIndexSet& coarseIndices,\n+ 252 ParallelAggregateRenumberer& renumberer)\n+ 253 {\n+ 254 // fineGraph is the local subgraph corresponding to the vertices the\n+process owns.\n+ 255 // i.e. no overlap/copy vertices can be visited traversing the graph\n+ 256 typedef typename Graph::ConstVertexIterator Iterator;\n+ 257 typedef typename ParallelInformation::GlobalLookupIndexSet\n+GlobalLookupIndexSet;\n+ 258\n+ 259 Iterator end = fineGraph.end();\n+ 260 const GlobalLookupIndexSet& lookup = pinfo.globalLookup();\n+ 261\n+ 262 coarseIndices.beginResize();\n+ 263\n+ 264 // Setup the coarse index set and renumber the aggregate consecutively\n+ 265 // ascending from zero according to the minimum global index belonging\n+ 266 // to the aggregate\n+ 267 for(Iterator index = fineGraph.begin(); index != end; ++index) {\n+ 268 if(aggregates[*index]!=AggregatesMap::\n+ISOLATED)\n+ 269 // Isolated vertices will not be represented on the next level.\n+ 270 // These should only be there if skipIsolated is activiated in\n+ 271 // the coarsening criterion as otherwise they will be aggregated\n+ 272 // and should have real aggregate number in the map right now.\n+ 273 if(!get(visitedMap, *index)) {\n+ 274 // This vertex was not visited by breadthFirstSearch yet.\n+ 275 typedef typename GlobalLookupIndexSet::IndexPair IndexPair;\n+ 276 const IndexPair* pair= lookup.pair(*index);\n 277\n- 281 template\n-282 class CoarsenCriterion : public T\n- 283 {\n- 284 public:\n-289 typedef T AggregationCriterion;\n- 290\n-301 CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double\n-minCoarsenRate=1.2,\n- 302 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n- 303 : AggregationCriterion(Dune::Amg::Parameters(maxLevel, coarsenTarget,\n-minCoarsenRate, prolongDamp, accumulate))\n- 304 {}\n+ 278 renumberer.reset(); // reset attribute and global index.\n+ 279 if(pair!=0) {\n+ 280 // vertex is in the index set. Note that not all vertices have\n+ 281 // to be in the index set, just the ones where communication\n+ 282 // will happen.\n+ 283 assert(!ExcludedAttributes::contains(pair->local().attribute()));\n+ 284 renumberer.attribute(pair->local().attribute());\n+ 285 renumberer.isPublic(pair->local().isPublic());\n+ 286 renumberer.globalIndex(pair->global());\n+ 287 }\n+ 288\n+ 289 // Reconstruct aggregate and mark vertices as visited\n+ 290 aggregates.template breadthFirstSearch(*index, aggregates[*index],\n+ 291 fineGraph, renumberer, visitedMap);\n+ 292\n+ 293 if(renumberer.globalIndex()!=std::numeric_limits::max()) {\n+ 294 // vertex is in the index set.\n+ 295 //std::cout <<\" Adding global=\"<< renumberer.globalIndex()<<\"\n+local=\"<(renumberer)<(renumberer) >= coarseIndices.size());\n 309\n- 310 };\n- 311\n- 312 template\n-313 bool repartitionAndDistributeMatrix([[maybe_unused]] const M& origMatrix,\n- 314 [[maybe_unused]] std::shared_ptr newMatrix,\n- 315 [[maybe_unused]] SequentialInformation& origComm,\n- 316 [[maybe_unused]] std::shared_ptr& newComm,\n- 317 [[maybe_unused]] RedistributeInformation& ri,\n- 318 [[maybe_unused]] int nparts,\n- 319 [[maybe_unused]] C1& criterion)\n- 320 {\n- 321 DUNE_THROW(NotImplemented, \"Redistribution does not make sense in\n-sequential code!\");\n- 322 }\n- 323\n+ 310 // Reset the visited flags\n+ 311 for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)\n+ 312 put(visitedMap, *vertex, false);\n+ 313 }\n+ 314\n+ 315 template\n+ 316 template\n+ 317 void ParallelIndicesCoarsener::buildCoarseRemoteIndices(const\n+RemoteIndices& fineRemote,\n+ 318 const AggregatesMap& aggregates,\n+ 319 ParallelIndexSet& coarseIndices,\n+ 320 RemoteIndices& coarseRemote,\n+ 321 ParallelAggregateRenumberer& renumberer)\n+ 322 {\n+ 323 std::vector attributes(static_cast(renumberer));\n 324\n- 325 template\n-326 bool repartitionAndDistributeMatrix(const M& origMatrix,\n- 327 std::shared_ptr newMatrix,\n- 328 C& origComm,\n- 329 std::shared_ptr& newComm,\n- 330 RedistributeInformation& ri,\n- 331 int nparts, C1& criterion)\n- 332 {\n- 333 Timer time;\n- 334#ifdef AMG_REPART_ON_COMM_GRAPH\n- 335 // Done not repartition the matrix graph, but a graph of the communication\n-scheme.\n- 336 bool existentOnRedist=Dune::commGraphRepartition(origMatrix, origComm,\n-nparts, newComm,\n- 337 ri.getInterface(),\n- 338 criterion.debugLevel()>1);\n- 339\n- 340#else\n- 341 typedef Dune::Amg::MatrixGraph MatrixGraph;\n- 342 typedef Dune::Amg::PropertiesGraph PropertiesGraph;\n- 347 MatrixGraph graph(origMatrix);\n- 348 PropertiesGraph pgraph(graph);\n- 349 buildDependency(pgraph, origMatrix, criterion, false);\n- 350\n- 351#ifdef DEBUG_REPART\n- 352 if(origComm.communicator().rank()==0)\n- 353 std::cout<<\"Original matrix\"<1);\n- 360#endif // if else AMG_REPART\n- 361\n- 362 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)\n- 363 std::cout<<\"Repartitioning took \"<indexSet(),\n-origComm.communicator());\n- 369#endif\n- 370\n- 371 redistributeMatrix(const_cast(origMatrix), *newMatrix, origComm,\n-*newComm, ri);\n- 372\n- 373#ifdef DEBUG_REPART\n- 374 if(origComm.communicator().rank()==0)\n- 375 std::cout<<\"Original matrix\"<communicator().size()>0)\n- 378 printGlobalSparseMatrix(*newMatrix, *newComm, std::cout);\n- 379 origComm.communicator().barrier();\n- 380#endif\n+ 325 GlobalLookupIndexSet coarseLookup(coarseIndices,\n+static_cast(renumberer));\n+ 326\n+ 327 typedef typename RemoteIndices::const_iterator Iterator;\n+ 328 Iterator end = fineRemote.end();\n+ 329\n+ 330 for(Iterator neighbour = fineRemote.begin();\n+ 331 neighbour != end; ++neighbour) {\n+ 332 int process = neighbour->first;\n+ 333\n+ 334 assert(neighbour->second.first==neighbour->second.second);\n+ 335\n+ 336 // Mark all as not known\n+ 337 typedef typename std::vector::iterator CIterator;\n+ 338\n+ 339 for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)\n+ 340 *iter = std::numeric_limits::max();\n+ 341\n+ 342 auto riEnd = neighbour->second.second->end();\n+ 343\n+ 344 for(auto index = neighbour->second.second->begin();\n+ 345 index != riEnd; ++index) {\n+ 346 if(!E::contains(index->localIndexPair().local().attribute()) &&\n+ 347 aggregates[index->localIndexPair().local()] !=\n+ 348 AggregatesMap::ISOLATED)\n+ 349 {\n+ 350 assert(aggregates[index->localIndexPair().local()]localIndexPair().local()]] != 3)\n+ 352 attributes[aggregates[index->localIndexPair().local()]] = index->attribute\n+();\n+ 353 }\n+ 354 }\n+ 355\n+ 356 // Build remote index list\n+ 357 typedef RemoteIndexListModifier Modifier;\n+ 358 typedef typename RemoteIndices::RemoteIndex RemoteIndex;\n+ 359 typedef typename ParallelIndexSet::const_iterator IndexIterator;\n+ 360\n+ 361 Modifier coarseList = coarseRemote.template getModifier\n+(process);\n+ 362\n+ 363 IndexIterator iend = coarseIndices.end();\n+ 364 for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)\n+ 365 if(attributes[index->local()] != std::numeric_limits::max()) {\n+ 366 // remote index is present\n+ 367 coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &\n+(*index)));\n+ 368 }\n+ 369 //std::cout< syncer(coarseIndices, coarseRemote);\n+ 378 syncer.sync(renumberer);\n+ 379\n+ 380 }\n 381\n- 382 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)\n- 383 std::cout<<\"Redistributing matrix took \"<\n-389 MatrixHierarchy::MatrixHierarchy(std::shared_ptr\n-fineMatrix,\n- 390 std::shared_ptr pinfo)\n- 391 : matrices_(fineMatrix),\n- 392 parallelInformation_(pinfo)\n- 393 {\n- 394 if (SolverCategory::category(*fineMatrix) != SolverCategory::category\n-(*pinfo))\n- 395 DUNE_THROW(ISTLError, \"MatrixOperator and ParallelInformation must belong\n-to the same category!\");\n+ 382#endif\n+ 383\n+ 384 template\n+ 385 template\n+ 386 typename Graph::VertexDescriptor\n+387 IndicesCoarsener::coarsen(\n+ 388 [[maybe_unused]] const SequentialInformation& fineInfo,\n+ 389 [[maybe_unused]] Graph& fineGraph,\n+ 390 [[maybe_unused]] VM& visitedMap,\n+ 391 [[maybe_unused]] AggregatesMap&\n+aggregates,\n+ 392 [[maybe_unused]] SequentialInformation& coarseInfo,\n+ 393 [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)\n+ 394 {\n+ 395 return noAggregates;\n 396 }\n 397\n- 398 template\n- 399 template\n-400 void MatrixHierarchy::build(const T& criterion)\n- 401 {\n- 402 prolongDamp_ = criterion.getProlongationDampingFactor();\n- 403 typedef O OverlapFlags;\n- 404 typedef typename ParallelMatrixHierarchy::Iterator MatIterator;\n- 405 typedef typename ParallelInformationHierarchy::Iterator PInfoIterator;\n- 406\n- 407 static const int noints=(Dune::Amg::MAX_PROCESSES/4096>0) ? (Dune::Amg::\n-MAX_PROCESSES/4096) : 1;\n- 408\n- 409 typedef bigunsignedint BIGINT;\n- 410 GalerkinProduct productBuilder;\n- 411 MatIterator mlevel = matrices_.finest();\n- 412 MatrixStats::stats(mlevel->getmat());\n- 413\n- 414 PInfoIterator infoLevel = parallelInformation_.finest();\n- 415 BIGINT finenonzeros=countNonZeros(mlevel->getmat());\n- 416 finenonzeros = infoLevel->communicator().sum(finenonzeros);\n- 417 BIGINT allnonzeros = finenonzeros;\n- 418\n- 419\n- 420 int level = 0;\n- 421 int rank = 0;\n- 422\n- 423 BIGINT unknowns = mlevel->getmat().N();\n- 424\n- 425 unknowns = infoLevel->communicator().sum(unknowns);\n- 426 double dunknowns=unknowns.todouble();\n- 427 infoLevel->buildGlobalLookup(mlevel->getmat().N());\n- 428 redistributes_.push_back(RedistributeInfoType());\n- 429\n- 430 for(; level < criterion.maxLevel(); ++level, ++mlevel) {\n- 431 assert(matrices_.levels()==redistributes_.size());\n- 432 rank = infoLevel->communicator().rank();\n- 433 if(rank==0 && criterion.debugLevel()>1)\n- 434 std::cout<<\"Level \"<communicator().size()\n- 435 <<\" unknowns per proc (procs=\"<communicator().size\n-()<<\")\"<communicator().size()))\n- 448 && infoLevel->communicator().size()>1 &&\n- 449 dunknowns/infoLevel->communicator().size() <= criterion.coarsenTarget())\n- 450 {\n- 451 // accumulate to fewer processors\n- 452 std::shared_ptr redistMat = std::make_shared();\n- 453 std::shared_ptr redistComm;\n- 454 std::size_t nodomains = (std::size_t)std::ceil(dunknowns/\n-(criterion.minAggregateSize()\n- 455 *criterion.coarsenTarget()));\n- 456 if( nodomains<=criterion.minAggregateSize()/2 ||\n- 457 dunknowns <= criterion.coarsenTarget() )\n- 458 nodomains=1;\n- 459\n- 460 bool existentOnNextLevel =\n- 461 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,\n- 462 redistComm, redistributes_.back(), nodomains,\n- 463 criterion);\n- 464 BIGINT unknownsRedist = redistMat->N();\n- 465 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);\n- 466 dunknowns= unknownsRedist.todouble();\n- 467 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1)\n- 468 std::cout<<\"Level \"<communicator().size()\n- 469 <<\" unknowns per proc (procs=\"<communicator().size\n-()<<\")\"<::construct\n-(args));\n- 472 assert(mlevel.isRedistributed());\n- 473 infoLevel.addRedistributed(redistComm);\n- 474 infoLevel->freeGlobalLookup();\n- 475\n- 476 if(!existentOnNextLevel)\n- 477 // We do not hold any data on the redistributed partitioning\n- 478 break;\n- 479\n- 480 // Work on the redistributed Matrix from now on\n- 481 matrix = &(mlevel.getRedistributed());\n- 482 info = &(infoLevel.getRedistributed());\n- 483 info->buildGlobalLookup(matrix->getmat().N());\n- 484 }\n- 485\n- 486 rank = info->communicator().rank();\n- 487 if(dunknowns <= criterion.coarsenTarget())\n- 488 // No further coarsening needed\n- 489 break;\n- 490\n- 491 typedef PropertiesGraphCreator\n-GraphCreator;\n- 492 typedef typename GraphCreator::PropertiesGraph PropertiesGraph;\n- 493 typedef typename GraphCreator::GraphTuple GraphTuple;\n- 494\n- 495 typedef typename PropertiesGraph::VertexDescriptor Vertex;\n- 496\n- 497 std::vector excluded(matrix->getmat().N(), false);\n- 498\n- 499 GraphTuple graphs = GraphCreator::create(*matrix, excluded, *info,\n-OverlapFlags());\n- 500\n- 501 AggregatesMap* aggregatesMap=new AggregatesMap(std::get<1>(graphs)-\n->maxVertex()+1);\n- 502\n- 503 aggregatesMaps_.push_back(aggregatesMap);\n- 504\n- 505 Timer watch;\n- 506 watch.reset();\n- 507 auto [noAggregates, isoAggregates, oneAggregates, skippedAggregates] =\n- 508 aggregatesMap->buildAggregates(matrix->getmat(), *(std::get<1>(graphs)),\n-criterion, level==0);\n- 509\n- 510 if(rank==0 && criterion.debugLevel()>2)\n- 511 std::cout<<\" Have built \"<communicator().rank();\n- 519 int n = UNKNOWNS/procs; // number of unknowns per process\n- 520 int bigger = UNKNOWNS%procs; // number of process with n+1 unknows\n- 521\n- 522 // Compute owner region\n- 523 if(rank0)\n- 533 overlapStart = start - 1;\n- 534 else\n- 535 overlapStart = start;\n- 536\n- 537 if(endnoVertices());\n- 543 for(int j=0; j< UNKNOWNS; ++j)\n- 544 for(int i=0; i < UNKNOWNS; ++i)\n- 545 {\n- 546 if(i>=overlapStart && i1 && info->communicator().rank()==0)\n- 555 std::cout<<\"aggregating finished.\"<communicator().sum(gnoAggregates);\n- 559 double dgnoAggregates = gnoAggregates.todouble();\n- 560#ifdef TEST_AGGLO\n- 561 BIGINT gnoAggregates=((UNKNOWNS)/2)*((UNKNOWNS)/2);\n- 562#endif\n- 563\n- 564 if(criterion.debugLevel()>2 && rank==0)\n- 565 std::cout << \"Building \"<0)\n- 572 std::cerr << \"Stopped coarsening because of rate breakdown\n-\"<free();\n- 579 delete aggregatesMap;\n- 580 aggregatesMaps_.pop_back();\n- 581\n- 582 if(criterion.accumulate() && mlevel.isRedistributed() && info-\n->communicator().size()>1) {\n- 583 // coarse level matrix was already redistributed, but to more than 1\n-process\n- 584 // Therefore need to delete the redistribution. Further down it will\n- 585 // then be redistributed to 1 process\n- 586 delete &(mlevel.getRedistributed().getmat());\n- 587 mlevel.deleteRedistributed();\n- 588 delete &(infoLevel.getRedistributed());\n- 589 infoLevel.deleteRedistributed();\n- 590 redistributes_.back().resetSetup();\n- 591 }\n- 592\n- 593 break;\n- 594 }\n- 595 unknowns = noAggregates;\n- 596 dunknowns = dgnoAggregates;\n- 597\n- 598 CommunicationArgs commargs(info->communicator(),info->category());\n- 599 parallelInformation_.addCoarser(commargs);\n- 600\n- 601 ++infoLevel; // parallel information on coarse level\n- 602\n- 603 typename PropertyMapTypeSelector::Type\n-visitedMap =\n- 604 get(VertexVisitedTag(), *(std::get<1>(graphs)));\n- 605\n- 606 watch.reset();\n- 607 int aggregates = IndicesCoarsener\n- 608::coarsen(*info,\n- 609 *(std::get<1>(graphs)),\n- 610 visitedMap,\n- 611 *aggregatesMap,\n- 612 *infoLevel,\n- 613 noAggregates);\n- 614 GraphCreator::free(graphs);\n- 615\n- 616 if(criterion.debugLevel()>2) {\n- 617 if(rank==0)\n- 618 std::cout<<\"Coarsening of index sets took \"<buildGlobalLookup(aggregates);\n- 624 AggregatesPublisher::publish\n-(*aggregatesMap,\n- 625 *info,\n- 626 infoLevel->globalLookup());\n- 627\n- 628\n- 629 if(criterion.debugLevel()>2) {\n- 630 if(rank==0)\n- 631 std::cout<<\"Communicating global aggregate numbers took \"<& visited=excluded;\n- 636\n- 637 typedef std::vector::iterator Iterator;\n- 638 typedef IteratorPropertyMap VisitedMap2;\n- 639 Iterator end = visited.end();\n- 640 for(Iterator iter= visited.begin(); iter != end; ++iter)\n- 641 *iter=false;\n- 642\n- 643 VisitedMap2 visitedMap2(visited.begin(), Dune::IdentityMap());\n- 644\n- 645 std::shared_ptr\n- 646 coarseMatrix(productBuilder.build(*(std::get<0>(graphs)), visitedMap2,\n- 647 *info,\n- 648 *aggregatesMap,\n- 649 aggregates,\n- 650 OverlapFlags()));\n- 651 dverb<<\"Building of sparsity pattern took \"<freeGlobalLookup();\n- 654\n- 655 delete std::get<0>(graphs);\n- 656 productBuilder.calculate(matrix->getmat(), *aggregatesMap, *coarseMatrix,\n-*infoLevel, OverlapFlags());\n- 657\n- 658 if(criterion.debugLevel()>2) {\n- 659 if(rank==0)\n- 660 std::cout<<\"Calculation entries of Galerkin product took \"<communicator().sum(nonzeros);\n- 665 MatrixArgs args(coarseMatrix, *infoLevel);\n- 666\n- 667 matrices_.addCoarser(args);\n- 668 redistributes_.push_back(RedistributeInfoType());\n- 669 } // end level loop\n- 670\n- 671\n- 672 infoLevel->freeGlobalLookup();\n- 673\n- 674 built_=true;\n- 675 AggregatesMap* aggregatesMap=new AggregatesMap(0);\n- 676 aggregatesMaps_.push_back(aggregatesMap);\n- 677\n- 678 if(criterion.debugLevel()>0) {\n- 679 if(level==criterion.maxLevel()) {\n- 680 BIGINT unknownsLevel = mlevel->getmat().N();\n- 681 unknownsLevel = infoLevel->communicator().sum(unknownsLevel);\n- 682 double dunknownsLevel = unknownsLevel.todouble();\n- 683 if(rank==0 && criterion.debugLevel()>1) {\n- 684 std::cout<<\"Level \"<communicator().size()\n- 685 <<\" unknowns per proc (procs=\"<communicator().size\n-()<<\")\"<communicator().size()>1) {\n- 692#if HAVE_MPI && !HAVE_PARMETIS\n- 693 if(criterion.accumulate()==successiveAccu &&\n- 694 infoLevel->communicator().rank()==0)\n- 695 std::cerr<<\"Successive accumulation of data on coarse levels only works\n-with ParMETIS installed.\"\n- 696 <<\" Fell back to accumulation to one domain on coarsest level\"< redistMat = std::make_shared();\n- 701 std::shared_ptr redistComm;\n- 702 int nodomains = 1;\n- 703\n- 704 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,\n- 705 redistComm, redistributes_.back(), nodomains,criterion);\n- 706 MatrixArgs args(redistMat, *redistComm);\n- 707 BIGINT unknownsRedist = redistMat->N();\n- 708 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);\n- 709\n- 710 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1) {\n- 711 double dunknownsRedist = unknownsRedist.todouble();\n- 712 std::cout<<\"Level \"<communicator().size()\n- 713 <<\" unknowns per proc (procs=\"<communicator().size\n-()<<\")\"<::construct\n-(args));\n- 716 infoLevel.addRedistributed(redistComm);\n- 717 infoLevel->freeGlobalLookup();\n- 718 }\n- 719\n- 720 int levels = matrices_.levels();\n- 721 maxlevels_ = parallelInformation_.finest()->communicator().max(levels);\n- 722 assert(matrices_.levels()==redistributes_.size());\n- 723 if(hasCoarsest() && rank==0 && criterion.debugLevel()>1)\n- 724 std::cout<<\"operator complexity: \"<\n- 729 const typename MatrixHierarchy::ParallelMatrixHierarchy&\n-730 MatrixHierarchy::matrices() const\n- 731 {\n- 732 return matrices_;\n- 733 }\n- 734\n- 735 template\n- 736 const typename MatrixHierarchy::ParallelInformationHierarchy&\n-737 MatrixHierarchy::parallelInformation() const\n- 738 {\n- 739 return parallelInformation_;\n- 740 }\n- 741\n- 742 template\n-743 void MatrixHierarchy::getCoarsestAggregatesOnFinest(std::\n-vector& data) const\n- 744 {\n- 745 int levels=aggregatesMaps().size();\n- 746 int maxlevels=parallelInformation_.finest()->communicator().max(levels);\n- 747 std::size_t size=(*(aggregatesMaps().begin()))->noVertices();\n- 748 // We need an auxiliary vector for the consecutive prolongation.\n- 749 std::vector tmp;\n- 750 std::vector *coarse, *fine;\n- 751\n- 752 // make sure the allocated space suffices.\n- 753 tmp.reserve(size);\n- 754 data.reserve(size);\n- 755\n- 756 // Correctly assign coarse and fine for the first prolongation such that\n- 757 // we end up in data in the end.\n- 758 if(levels%2==0) {\n- 759 coarse=&tmp;\n- 760 fine=&data;\n- 761 }else{\n- 762 coarse=&data;\n- 763 fine=&tmp;\n- 764 }\n- 765\n- 766 // Number the unknowns on the coarsest level consecutively for each\n-process.\n- 767 if(levels==maxlevels) {\n- 768 const AggregatesMap& map = *(*(++aggregatesMaps().rbegin()));\n- 769 std::size_t m=0;\n- 770\n- 771 for(typename AggregatesMap::const_iterator iter = map.begin(); iter !=\n-map.end(); ++iter)\n- 772 if(*iter< AggregatesMap::ISOLATED)\n- 773 m=std::max(*iter,m);\n- 774\n- 775 coarse->resize(m+1);\n- 776 std::size_t i=0;\n- 777 srand((unsigned)std::clock());\n- 778 std::set used;\n- 779 for(typename std::vector::iterator iter=coarse->begin(); iter\n-!= coarse->end();\n- 780 ++iter, ++i)\n- 781 {\n- 782 std::pair::iterator,bool> ibpair\n- 783 = used.insert(static_cast((((double)rand())/\n-(RAND_MAX+1.0)))*coarse->size());\n- 784\n- 785 while(!ibpair.second)\n- 786 ibpair = used.insert(static_cast((((double)rand())/\n-(RAND_MAX+1.0))*coarse->size()));\n- 787 *iter=*(ibpair.first);\n- 788 }\n- 789 }\n- 790\n- 791 typename ParallelInformationHierarchy::Iterator pinfo =\n-parallelInformation().coarsest();\n- 792 --pinfo;\n- 793\n- 794 // Now consecutively project the numbers to the finest level.\n- 795 for(typename AggregatesMapList::const_reverse_iterator\n-aggregates=++aggregatesMaps().rbegin();\n- 796 aggregates != aggregatesMaps().rend(); ++aggregates,--levels) {\n- 797\n- 798 fine->resize((*aggregates)->noVertices());\n- 799 fine->assign(fine->size(), 0);\n- 800 Transfer, ParallelInformation>\n- 801 ::prolongateVector(*(*aggregates), *coarse, *fine, static_cast(1), *pinfo);\n- 802 --pinfo;\n- 803 std::swap(coarse, fine);\n- 804 }\n- 805\n- 806 // Assertion to check that we really projected to data on the last step.\n- 807 assert(coarse==&data);\n- 808 }\n- 809\n- 810 template\n- 811 const typename MatrixHierarchy::AggregatesMapList&\n-812 MatrixHierarchy::aggregatesMaps() const\n- 813 {\n- 814 return aggregatesMaps_;\n- 815 }\n- 816 template\n- 817 const typename MatrixHierarchy::RedistributeInfoList&\n-818 MatrixHierarchy::redistributeInformation() const\n- 819 {\n- 820 return redistributes_;\n- 821 }\n- 822\n- 823 template\n-824 MatrixHierarchy::~MatrixHierarchy()\n- 825 {\n- 826 typedef typename AggregatesMapList::reverse_iterator\n-AggregatesMapIterator;\n- 827 typedef typename ParallelMatrixHierarchy::Iterator Iterator;\n- 828 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;\n- 829\n- 830 AggregatesMapIterator amap = aggregatesMaps_.rbegin();\n- 831 InfoIterator info = parallelInformation_.coarsest();\n- 832 for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level\n-!= finest; --level, --info, ++amap) {\n- 833 (*amap)->free();\n- 834 delete *amap;\n- 835 }\n- 836 delete *amap;\n- 837 }\n- 838\n- 839 template\n- 840 template\n-841 void MatrixHierarchy::coarsenVector(Hierarchy,\n-TA>& hierarchy) const\n- 842 {\n- 843 assert(hierarchy.levels()==1);\n- 844 typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;\n- 845 typedef typename RedistributeInfoList::const_iterator RIter;\n- 846 RIter redist = redistributes_.begin();\n- 847\n- 848 Iterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();\n- 849 int level=0;\n- 850 if(redist->isSetup())\n- 851 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N\n-());\n- 852 Dune::dvverb<<\"Level \"<getmat().N\n-()<<\" unknowns!\"<getmat().N()<<\"\n-unknowns!\"<getmat().N());\n- 859 if(redist->isSetup())\n- 860 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N\n-());\n- 861\n- 862 }\n- 863\n- 864 }\n- 865\n- 866 template\n- 867 template\n-868 void MatrixHierarchy::coarsenSmoother(Hierarchy& smoothers,\n- 869 const typename SmootherTraits::Arguments& sargs) const\n- 870 {\n- 871 assert(smoothers.levels()==0);\n- 872 typedef typename ParallelMatrixHierarchy::ConstIterator MatrixIterator;\n- 873 typedef typename ParallelInformationHierarchy::ConstIterator\n-PinfoIterator;\n- 874 typedef typename AggregatesMapList::const_iterator AggregatesIterator;\n- 875\n- 876 typename ConstructionTraits::Arguments cargs;\n- 877 cargs.setArgs(sargs);\n- 878 PinfoIterator pinfo = parallelInformation_.finest();\n- 879 AggregatesIterator aggregates = aggregatesMaps_.begin();\n- 880 int level=0;\n- 881 for(MatrixIterator matrix = matrices_.finest(), coarsest =\n-matrices_.coarsest();\n- 882 matrix != coarsest; ++matrix, ++pinfo, ++aggregates, ++level) {\n- 883 cargs.setMatrix(matrix->getmat(), **aggregates);\n- 884 cargs.setComm(*pinfo);\n- 885 smoothers.addCoarser(cargs);\n- 886 }\n- 887 if(maxlevels()>levels()) {\n- 888 // This is not the globally coarsest level and therefore smoothing is\n-needed\n- 889 cargs.setMatrix(matrices_.coarsest()->getmat(), **aggregates);\n- 890 cargs.setComm(*pinfo);\n- 891 smoothers.addCoarser(cargs);\n- 892 ++level;\n- 893 }\n- 894 }\n- 895\n- 896 template\n- 897 template\n-898 void MatrixHierarchy::recalculateGalerkin(const F& copyFlags)\n- 899 {\n- 900 typedef typename AggregatesMapList::iterator AggregatesMapIterator;\n- 901 typedef typename ParallelMatrixHierarchy::Iterator Iterator;\n- 902 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;\n- 903\n- 904 AggregatesMapIterator amap = aggregatesMaps_.begin();\n- 905 BaseGalerkinProduct productBuilder;\n- 906 InfoIterator info = parallelInformation_.finest();\n- 907 typename RedistributeInfoList::iterator riIter = redistributes_.begin();\n- 908 Iterator level = matrices_.finest(), coarsest=matrices_.coarsest();\n- 909 if(level.isRedistributed()) {\n- 910 info->buildGlobalLookup(level->getmat().N());\n- 911 redistributeMatrixEntries(const_cast(level->getmat()),\n- 912 const_cast(level.getRedistributed().getmat()),\n- 913 *info,info.getRedistributed(), *riIter);\n- 914 info->freeGlobalLookup();\n- 915 }\n- 916\n- 917 for(; level!=coarsest; ++amap) {\n- 918 const Matrix& fine = (level.isRedistributed() ? level.getRedistributed() :\n-*level).getmat();\n- 919 ++level;\n- 920 ++info;\n- 921 ++riIter;\n- 922 productBuilder.calculate(fine, *(*amap), const_cast(level->getmat\n-()), *info, copyFlags);\n- 923 if(level.isRedistributed()) {\n- 924 info->buildGlobalLookup(level->getmat().N());\n- 925 redistributeMatrixEntries(const_cast(level->getmat()),\n- 926 const_cast(level.getRedistributed().getmat()), *info,\n- 927 info.getRedistributed(), *riIter);\n- 928 info->freeGlobalLookup();\n- 929 }\n- 930 }\n- 931 }\n- 932\n- 933 template\n-934 std::size_t MatrixHierarchy::levels() const\n- 935 {\n- 936 return matrices_.levels();\n- 937 }\n- 938\n- 939 template\n-940 std::size_t MatrixHierarchy::maxlevels() const\n- 941 {\n- 942 return maxlevels_;\n- 943 }\n- 944\n- 945 template\n-946 bool MatrixHierarchy::hasCoarsest() const\n- 947 {\n- 948 return levels()==maxlevels() &&\n- 949 (!matrices_.coarsest().isRedistributed() ||matrices_.coarsest()->getmat\n-().N()>0);\n- 950 }\n- 951\n- 952 template\n-953 bool MatrixHierarchy::isBuilt() const\n- 954 {\n- 955 return built_;\n- 956 }\n- 957\n- 959 } // namespace Amg\n- 960} // namespace Dune\n- 961\n- 962#endif // end DUNE_AMG_MATRIXHIERARCHY_HH\n-matrixutils.hh\n-Some handy generic functions for ISTL matrices.\n-matrixredistribute.hh\n-Functionality for redistributing a sparse matrix.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-graph.hh\n-Provides classes for building the matrix graph.\n-aggregates.hh\n-Provides classes for the Coloring process of AMG.\n-galerkin.hh\n-Provides a class for building the galerkin product based on a aggregation\n-scheme.\n-globalaggregates.hh\n-Provdes class for identifying aggregates globally.\n-hierarchy.hh\n-Provides a classes representing the hierarchies in AMG.\n-construction.hh\n-Helper classes for the construction of classes without empty constructor.\n+ 398 } //namespace Amg\n+ 399} // namespace Dune\n+ 400#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n+pinfo.hh\n renumberer.hh\n-transfer.hh\n-Prolongation and restriction for amg.\n-indicescoarsener.hh\n-Provides a class for building the index set and remote indices on the coarse\n-level.\n-graphcreator.hh\n-smoother.hh\n-Classes for the generic construction and application of the smoothers.\n-dependency.hh\n-Provides classes for initializing the link attributes of a matrix graph.\n-Dune::countNonZeros\n-auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n-value > *sfinae=nullptr)\n-Get the number of nonzero fields in the matrix.\n-Definition: matrixutils.hh:119\n-Dune::Amg::MatrixHierarchy::aggregatesMaps\n-const AggregatesMapList & aggregatesMaps() const\n-Get the hierarchy of the mappings of the nodes onto aggregates.\n-Definition: matrixhierarchy.hh:812\n-Dune::Amg::MatrixHierarchy::isBuilt\n-bool isBuilt() const\n-Whether the hierarchy was built.\n-Definition: matrixhierarchy.hh:953\n-Dune::Amg::MatrixHierarchy::hasCoarsest\n-bool hasCoarsest() const\n-Definition: matrixhierarchy.hh:946\n-Dune::Amg::Hierarchy::levels\n-std::size_t levels() const\n-Get the number of levels in the hierarchy.\n-Definition: hierarchy.hh:322\n-Dune::Amg::MatrixHierarchy::levels\n-std::size_t levels() const\n-Get the number of levels in the hierarchy.\n-Definition: matrixhierarchy.hh:934\n-Dune::Amg::Hierarchy::addCoarser\n-void addCoarser(Arguments &args)\n-Add an element on a coarser level.\n-Definition: hierarchy.hh:334\n-Dune::Amg::MatrixHierarchy::redistributeInformation\n-const RedistributeInfoList & redistributeInformation() const\n-Get the hierarchy of the information about redistributions,.\n-Definition: matrixhierarchy.hh:818\n-Dune::Amg::MatrixHierarchy::parallelInformation\n-const ParallelInformationHierarchy & parallelInformation() const\n-Get the hierarchy of the parallel data distribution information.\n-Definition: matrixhierarchy.hh:737\n-Dune::Amg::repartitionAndDistributeMatrix\n-bool repartitionAndDistributeMatrix(const M &origMatrix, std::shared_ptr< M >\n-newMatrix, SequentialInformation &origComm, std::shared_ptr<\n-SequentialInformation > &newComm, RedistributeInformation<\n-SequentialInformation > &ri, int nparts, C1 &criterion)\n-Definition: matrixhierarchy.hh:313\n-Dune::Amg::AggregatesMap::begin\n-const_iterator begin() const\n-Definition: aggregates.hh:725\n-Dune::Amg::MatrixHierarchy::matrices\n-const ParallelMatrixHierarchy & matrices() const\n-Get the matrix hierarchy.\n-Definition: matrixhierarchy.hh:730\n-Dune::Amg::MatrixHierarchy::maxlevels\n-std::size_t maxlevels() const\n-Get the max number of levels in the hierarchy of processors.\n-Definition: matrixhierarchy.hh:940\n-Dune::Amg::AggregatesMap::end\n-const_iterator end() const\n-Definition: aggregates.hh:730\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::reset\n+void reset()\n+Definition: indicescoarsener.hh:144\n+Dune::Amg::ParallelIndicesCoarsener::Attribute\n+LocalIndex::Attribute Attribute\n+The type of the attribute.\n+Definition: indicescoarsener.hh:70\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::operator()\n+void operator()(const typename G::ConstEdgeIterator &edge)\n+Definition: indicescoarsener.hh:116\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::isPublic\n+void isPublic(bool b)\n+Definition: indicescoarsener.hh:139\n+Dune::Amg::ParallelIndicesCoarsener::ParallelIndexSet\n+ParallelInformation::ParallelIndexSet ParallelIndexSet\n+Definition: indicescoarsener.hh:55\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::isPublic\n+bool isPublic()\n+Definition: indicescoarsener.hh:134\n+Dune::Amg::ParallelIndicesCoarsener::LocalIndex\n+ParallelIndexSet::LocalIndex LocalIndex\n+The type of the local index.\n+Definition: indicescoarsener.hh:65\n+Dune::Amg::ParallelIndicesCoarsener::ParallelInformation\n+T ParallelInformation\n+The type of the parallel information.\n+Definition: indicescoarsener.hh:53\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::attribute\n+Attribute attribute()\n+Definition: indicescoarsener.hh:155\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::operator()\n+Vertex operator()(const GlobalIndex &global)\n+Definition: indicescoarsener.hh:127\n+Dune::Amg::ParallelIndicesCoarsener::coarsen\n+static Graph::VertexDescriptor coarsen(ParallelInformation &fineInfo, Graph\n+&fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor >\n+&aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor\n+noAggregates)\n+Build the coarse index set after the aggregatio.\n+Definition: indicescoarsener.hh:229\n Dune::Amg::AggregatesMap::ISOLATED\n static const V ISOLATED\n Identifier of isolated vertices.\n Definition: aggregates.hh:571\n-Dune::Amg::MatrixHierarchy::recalculateGalerkin\n-void recalculateGalerkin(const F ©Flags)\n-Recalculate the galerkin products.\n-Definition: matrixhierarchy.hh:898\n-Dune::Amg::ConstructionTraits::Arguments\n-const void * Arguments\n-A type holding all the arguments needed to call the constructor.\n-Definition: construction.hh:44\n-Dune::Amg::AggregatesMap::noVertices\n-std::size_t noVertices() const\n-Get the number of vertices.\n-Dune::Amg::MatrixHierarchy::coarsenVector\n-void coarsenVector(Hierarchy< BlockVector< V, BA >, TA > &hierarchy) const\n-Coarsen the vector hierarchy according to the matrix hierarchy.\n-Definition: matrixhierarchy.hh:841\n-Dune::Amg::AggregatesMap::const_iterator\n-const AggregateDescriptor * const_iterator\n-Definition: aggregates.hh:723\n-Dune::Amg::MatrixHierarchy::MatrixHierarchy\n-MatrixHierarchy(std::shared_ptr< MatrixOperator > fineMatrix, std::shared_ptr<\n-ParallelInformation > pinfo=std::make_shared< ParallelInformation >())\n-Constructor.\n-Definition: matrixhierarchy.hh:389\n-Dune::Amg::AccumulationMode\n-AccumulationMode\n-Identifiers for the different accumulation modes.\n-Definition: parameters.hh:232\n-Dune::Amg::MatrixHierarchy::build\n-void build(const T &criterion)\n-Build the matrix hierarchy using aggregation.\n-Definition: matrixhierarchy.hh:400\n-Dune::Amg::AggregatesMap::free\n-void free()\n-Free the allocated memory.\n-Dune::Amg::MatrixHierarchy::coarsenSmoother\n-void coarsenSmoother(Hierarchy< S, TA > &smoothers, const typename\n-SmootherTraits< S >::Arguments &args) const\n-Coarsen the smoother hierarchy according to the matrix hierarchy.\n-Definition: matrixhierarchy.hh:868\n-Dune::Amg::buildDependency\n-void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion,\n-bool finestLevel)\n-Build the dependency of the matrix graph.\n-Dune::Amg::AggregatesMap::buildAggregates\n-std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph,\n-const C &criterion, bool finestLevel)\n-Build the aggregates.\n-Dune::Amg::BaseGalerkinProduct::calculate\n-void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n-const I &pinfo, const O ©)\n-Calculate the galerkin product.\n-Dune::Amg::MatrixHierarchy::getCoarsestAggregatesOnFinest\n-void getCoarsestAggregatesOnFinest(std::vector< std::size_t > &data) const\n-Get the mapping of fine level unknowns to coarse level aggregates.\n-Definition: matrixhierarchy.hh:743\n-Dune::Amg::MatrixHierarchy::~MatrixHierarchy\n-~MatrixHierarchy()\n-Definition: matrixhierarchy.hh:824\n-Dune::Amg::MAX_PROCESSES\n-@ MAX_PROCESSES\n-Hard limit for the number of processes allowed.\n-Definition: matrixhierarchy.hh:50\n-Dune::Amg::atOnceAccu\n-@ atOnceAccu\n-Accumulate data to one process at once.\n-Definition: parameters.hh:244\n-Dune::Amg::successiveAccu\n-@ successiveAccu\n-Successively accumulate to fewer processes.\n-Definition: parameters.hh:248\n+Dune::Amg::ParallelIndicesCoarsener::GlobalIndex\n+ParallelIndexSet::GlobalIndex GlobalIndex\n+The type of the global index.\n+Definition: indicescoarsener.hh:60\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::attribute\n+void attribute(const Attribute &attribute)\n+Definition: indicescoarsener.hh:150\n+Dune::Amg::ParallelIndicesCoarsener::ExcludedAttributes\n+E ExcludedAttributes\n+The set of excluded attributes.\n+Definition: indicescoarsener.hh:48\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::globalIndex\n+void globalIndex(const GlobalIndex &global)\n+Definition: indicescoarsener.hh:165\n+Dune::Amg::ParallelIndicesCoarsener::RemoteIndices\n+Dune::RemoteIndices< ParallelIndexSet > RemoteIndices\n+The type of the remote indices.\n+Definition: indicescoarsener.hh:75\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::\n+ParallelAggregateRenumberer\n+ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I\n+&lookup)\n+Definition: indicescoarsener.hh:110\n+Dune::Amg::ParallelIndicesCoarsener::ParallelAggregateRenumberer::globalIndex\n+const GlobalIndex & globalIndex() const\n+Definition: indicescoarsener.hh:160\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::printGlobalSparseMatrix\n-void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)\n-Definition: matrixutils.hh:154\n Dune::get\n PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n Definition: dependency.hh:293\n-Dune::redistributeMatrixEntries\n-void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C\n-&newComm, RedistributeInformation< C > &ri)\n-Definition: matrixredistribute.hh:757\n-Dune::commGraphRepartition\n-bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication<\n-T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n-&redistInf, bool verbose=false)\n-Definition: repartition.hh:829\n-Dune::redistributeMatrix\n-void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm,\n-RedistributeInformation< C > &ri)\n-Redistribute a matrix according to given domain decompositions.\n-Definition: matrixredistribute.hh:820\n-Dune::graphRepartition\n-bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n-T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n-OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n-&redistInf, bool verbose=false)\n-execute a graph repartition for a giving graph and indexset.\n-Definition: repartition.hh:1235\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::size_type\n-A::size_type size_type\n-Type for indices and sizes.\n-Definition: matrix.hh:577\n-Dune::Matrix::row_type\n-MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n-The type implementing a matrix row.\n-Definition: matrix.hh:574\n-Dune::RedistributeInformation\n-Definition: matrixredistribute.hh:22\n-Dune::Amg::ConstructionTraits\n-Traits class for generically constructing non default constructable types.\n-Definition: construction.hh:39\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n Dune::Amg::AggregatesMap\n Class providing information about the mapping of the vertices onto aggregates.\n Definition: aggregates.hh:560\n-Dune::Amg::EdgeProperties\n-Class representing the properties of an ede in the matrix graph.\n-Definition: dependency.hh:39\n-Dune::Amg::VertexProperties\n-Class representing a node in the matrix graph.\n-Definition: dependency.hh:126\n-Dune::Amg::BaseGalerkinProduct\n-Definition: galerkin.hh:99\n-Dune::Amg::GalerkinProduct\n-Definition: galerkin.hh:118\n-Dune::Amg::AggregatesPublisher\n-Definition: globalaggregates.hh:131\n-Dune::Amg::MatrixGraph<_const_M_>\n-Dune::Amg::PropertiesGraph\n-Attaches properties to the edges and vertices of a graph.\n-Definition: graph.hh:978\n-Dune::Amg::PropertiesGraph::VertexDescriptor\n-Graph::VertexDescriptor VertexDescriptor\n-The vertex descriptor.\n-Definition: graph.hh:988\n-Dune::Amg::PropertiesGraphCreator\n-Definition: graphcreator.hh:22\n-Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>\n-Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::Iterator\n-LevelIterator< Hierarchy< MatrixOperator, Allocator >, MatrixOperator >\n-Iterator\n-Type of the mutable iterator.\n-Definition: hierarchy.hh:216\n-Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n-LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n-MatrixOperator > ConstIterator\n-Type of the const iterator.\n-Definition: hierarchy.hh:219\n Dune::Amg::IndicesCoarsener\n Definition: indicescoarsener.hh:36\n-Dune::Amg::MatrixHierarchy\n-The hierarchies build by the coarsening process.\n-Definition: matrixhierarchy.hh:61\n-Dune::Amg::MatrixHierarchy::AAllocator\n-typename std::allocator_traits< Allocator >::template rebind_alloc<\n-AggregatesMap * > AAllocator\n-Allocator for pointers.\n-Definition: matrixhierarchy.hh:85\n-Dune::Amg::MatrixHierarchy::ParallelInformationHierarchy\n-Dune::Amg::Hierarchy< ParallelInformation, Allocator >\n-ParallelInformationHierarchy\n-The type of the parallel informarion hierarchy.\n-Definition: matrixhierarchy.hh:82\n-Dune::Amg::MatrixHierarchy::AggregatesMapList\n-std::list< AggregatesMap *, AAllocator > AggregatesMapList\n-The type of the aggregates maps list.\n-Definition: matrixhierarchy.hh:88\n-Dune::Amg::MatrixHierarchy::ParallelInformation\n-PI ParallelInformation\n-The type of the index set.\n-Definition: matrixhierarchy.hh:70\n-Dune::Amg::MatrixHierarchy::ParallelMatrixHierarchy\n-Dune::Amg::Hierarchy< MatrixOperator, Allocator > ParallelMatrixHierarchy\n-The type of the parallel matrix hierarchy.\n-Definition: matrixhierarchy.hh:79\n-Dune::Amg::MatrixHierarchy::Allocator\n-A Allocator\n-The allocator to use.\n-Definition: matrixhierarchy.hh:73\n-Dune::Amg::MatrixHierarchy::RedistributeInfoType\n-RedistributeInformation< ParallelInformation > RedistributeInfoType\n-The type of the redistribute information.\n-Definition: matrixhierarchy.hh:91\n-Dune::Amg::MatrixHierarchy::getProlongationDampingFactor\n-double getProlongationDampingFactor() const\n-Definition: matrixhierarchy.hh:188\n-Dune::Amg::MatrixHierarchy::RILAllocator\n-typename std::allocator_traits< Allocator >::template rebind_alloc<\n-RedistributeInfoType > RILAllocator\n-Allocator for RedistributeInfoType.\n-Definition: matrixhierarchy.hh:94\n-Dune::Amg::MatrixHierarchy::RedistributeInfoList\n-std::list< RedistributeInfoType, RILAllocator > RedistributeInfoList\n-The type of the list of redistribute information.\n-Definition: matrixhierarchy.hh:97\n-Dune::Amg::MatrixHierarchy::AggregatesMap\n-Dune::Amg::AggregatesMap< typename MatrixGraph< Matrix >::VertexDescriptor >\n-AggregatesMap\n-The type of the aggregates map we use.\n-Definition: matrixhierarchy.hh:76\n-Dune::Amg::MatrixHierarchy::Matrix\n-MatrixOperator::matrix_type Matrix\n-The type of the matrix.\n-Definition: matrixhierarchy.hh:67\n-Dune::Amg::MatrixHierarchy::MatrixOperator\n-M MatrixOperator\n-The type of the matrix operator.\n-Definition: matrixhierarchy.hh:64\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::operator()\n-void operator()(const matrix_row &row)\n-Definition: matrixhierarchy.hh:254\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::matrix_row\n-Matrix::row_type matrix_row\n-Definition: matrixhierarchy.hh:245\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::min\n-size_type min\n-Definition: matrixhierarchy.hh:261\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::calc\n-calc()\n-Definition: matrixhierarchy.hh:247\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::max\n-size_type max\n-Definition: matrixhierarchy.hh:262\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::sum\n-size_type sum\n-Definition: matrixhierarchy.hh:263\n-Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::size_type\n-Matrix::size_type size_type\n-Definition: matrixhierarchy.hh:244\n-Dune::Amg::CoarsenCriterion\n-The criterion describing the stop criteria for the coarsening process.\n-Definition: matrixhierarchy.hh:283\n-Dune::Amg::CoarsenCriterion::CoarsenCriterion\n-CoarsenCriterion(const Dune::Amg::Parameters &parms)\n-Definition: matrixhierarchy.hh:306\n-Dune::Amg::CoarsenCriterion::AggregationCriterion\n-T AggregationCriterion\n-The criterion for tagging connections as strong and nodes as isolated. This\n-might be e....\n-Definition: matrixhierarchy.hh:289\n-Dune::Amg::CoarsenCriterion::CoarsenCriterion\n-CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double\n-minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode\n-accumulate=successiveAccu)\n-Constructor.\n-Definition: matrixhierarchy.hh:301\n-Dune::Amg::Parameters\n-All parameters for AMG.\n-Definition: parameters.hh:393\n+Dune::Amg::ParallelIndicesCoarsener\n+Definition: indicescoarsener.hh:43\n Dune::Amg::SequentialInformation\n Definition: pinfo.hh:28\n-Dune::Amg::VertexVisitedTag\n-Tag idnetifying the visited property of a vertex.\n-Definition: properties.hh:29\n-Dune::Amg::SmootherTraits\n-Traits class for getting the attribute class of a smoother.\n-Definition: smoother.hh:66\n-Dune::Amg::Transfer\n-Definition: transfer.hh:32\n-Dune::SolverCategory::category\n-static Category category(const OP &op, decltype(op.category()) *=nullptr)\n-Helperfunction to extract the solver category either from an enum, or from the\n-newly introduced virtu...\n-Definition: solvercategory.hh:34\n+Dune::Amg::AggregateRenumberer\n+Definition: renumberer.hh:16\n+Dune::Amg::AggregateRenumberer::operator++\n+void operator++()\n+Definition: renumberer.hh:57\n+Dune::Amg::AggregateRenumberer::operator()\n+void operator()(const typename G::ConstEdgeIterator &edge)\n+Definition: renumberer.hh:51\n+Dune::Amg::AggregateRenumberer::number_\n+Vertex number_\n+Definition: renumberer.hh:35\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00161.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00161.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: dependency.hh File Reference\n+dune-istl: matrixhierarchy.hh File Reference\n \n \n \n \n \n \n \n@@ -65,61 +65,78 @@\n
  • dune
  • istl
  • paamg
  • \n
    \n \n \n
    \n \n-

    Provides classes for initializing the link attributes of a matrix graph. \n+

    Provides a classes representing the hierarchies in AMG. \n More...

    \n-
    #include <bitset>
    \n-#include <ostream>
    \n-#include "graph.hh"
    \n-#include "properties.hh"
    \n-#include <dune/common/propertymap.hh>
    \n+
    #include <algorithm>
    \n+#include <tuple>
    \n+#include "aggregates.hh"
    \n+#include "graph.hh"
    \n+#include "galerkin.hh"
    \n+#include "renumberer.hh"
    \n+#include "graphcreator.hh"
    \n+#include "hierarchy.hh"
    \n+#include <dune/istl/bvector.hh>
    \n+#include <dune/common/parallel/indexset.hh>
    \n+#include <dune/istl/matrixutils.hh>
    \n+#include <dune/istl/matrixredistribute.hh>
    \n+#include <dune/istl/paamg/dependency.hh>
    \n+#include <dune/istl/paamg/indicescoarsener.hh>
    \n+#include <dune/istl/paamg/globalaggregates.hh>
    \n+#include <dune/istl/paamg/construction.hh>
    \n+#include <dune/istl/paamg/smoother.hh>
    \n+#include <dune/istl/paamg/transfer.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::Amg::EdgeProperties
     Class representing the properties of an ede in the matrix graph. More...
    class  Dune::Amg::MatrixHierarchy< M, PI, A >
     The hierarchies build by the coarsening process. More...
     
    class  Dune::Amg::VertexProperties
     Class representing a node in the matrix graph. More...
    struct  Dune::Amg::MatrixHierarchy< M, PI, A >::MatrixStats< Matrix, true >::calc
     
    class  Dune::Amg::PropertyGraphVertexPropertyMap< G, i >
     
    struct  Dune::PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >
    class  Dune::Amg::CoarsenCriterion< T >
     The criterion describing the stop criteria for the coarsening process. More...
     
    \n \n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+

    \n+Enumerations

    enum  { Dune::Amg::MAX_PROCESSES = 72000\n+ }
     
    \n \n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<typename G , typename EP , typename VM , typename EM >
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type Dune::get (const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
     
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const EdgeProperties &props)
     
    std::ostream & Dune::Amg::operator<< (std::ostream &os, const VertexProperties &props)
     
    template<typename M , typename C1 >
    bool Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::shared_ptr< M > newMatrix, SequentialInformation &origComm, std::shared_ptr< SequentialInformation > &newComm, RedistributeInformation< SequentialInformation > &ri, int nparts, C1 &criterion)
     
    template<typename M , typename C , typename C1 >
    bool Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::shared_ptr< M > newMatrix, C &origComm, std::shared_ptr< C > &newComm, RedistributeInformation< C > &ri, int nparts, C1 &criterion)
     
    \n

    Detailed Description

    \n-

    Provides classes for initializing the link attributes of a matrix graph.

    \n+

    Provides a classes representing the hierarchies in AMG.

    \n
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,70 +5,69 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-Classes | Namespaces | Functions\n-dependency.hh File Reference\n+Classes | Namespaces | Enumerations | Functions\n+matrixhierarchy.hh File Reference\n Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n \u00bb Parallel_Algebraic_Multigrid\n-Provides classes for initializing the link attributes of a matrix graph.\n-More...\n-#include \n-#include \n+Provides a classes representing the hierarchies in AMG. More...\n+#include \n+#include \n+#include \"aggregates.hh\"\n #include \"graph.hh\"\n-#include \"properties.hh\"\n-#include \n+#include \"galerkin.hh\"\n+#include \"renumberer.hh\"\n+#include \"graphcreator.hh\"\n+#include \"hierarchy.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::Amg::EdgeProperties\n-\u00a0 Class representing the properties of an ede in the matrix graph.\n- More...\n-\u00a0\n- class \u00a0Dune::Amg::VertexProperties\n-\u00a0 Class representing a node in the matrix graph. More...\n+ class \u00a0Dune::Amg::MatrixHierarchy<_M,_PI,_A_>\n+\u00a0 The hierarchies build by the coarsening process. More...\n \u00a0\n- class \u00a0Dune::Amg::PropertyGraphVertexPropertyMap<_G,_i_>\n+struct \u00a0Dune::Amg::MatrixHierarchy<_M,_PI,_A_>::MatrixStats<_Matrix,_true_>::\n+ calc\n \u00a0\n-struct \u00a0Dune::PropertyMapTypeSelector<_Amg::VertexVisitedTag,_Amg::\n- PropertiesGraph<_G,_Amg::VertexProperties,_EP,_VM,_EM_>_>\n+ class \u00a0Dune::Amg::CoarsenCriterion<_T_>\n+\u00a0 The criterion describing the stop criteria for the coarsening process.\n+ More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n+ Enumerations\n+enum \u00a0{ Dune::Amg::MAX_PROCESSES = 72000 }\n+\u00a0\n Functions\n-template\n- PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg:: Dune::get (const\n- PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type\u00a0Amg::\n- VertexVisitedTag\n- &tag, Amg::\n- PropertiesGraph<\n- G, Amg::\n- VertexProperties,\n- EP, VM, EM >\n- &graph)\n-\u00a0\n- std::ostream &\u00a0Dune::Amg::\n- operator<< (std::\n- ostream &os,\n- const\n- EdgeProperties\n- &props)\n-\u00a0\n- std::ostream &\u00a0Dune::Amg::\n- operator<< (std::\n- ostream &os,\n- const\n- VertexProperties\n- &props)\n+template\n+bool\u00a0Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::\n+ shared_ptr< M > newMatrix, SequentialInformation &origComm, std::\n+ shared_ptr< SequentialInformation > &newComm, RedistributeInformation<\n+ SequentialInformation > &ri, int nparts, C1 &criterion)\n+\u00a0\n+template\n+bool\u00a0Dune::Amg::repartitionAndDistributeMatrix (const M &origMatrix, std::\n+ shared_ptr< M > newMatrix, C &origComm, std::shared_ptr< C > &newComm,\n+ RedistributeInformation< C > &ri, int nparts, C1 &criterion)\n \u00a0\n ***** Detailed Description *****\n-Provides classes for initializing the link attributes of a matrix graph.\n+Provides a classes representing the hierarchies in AMG.\n Author\n Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00161_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00161_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: dependency.hh Source File\n+dune-istl: matrixhierarchy.hh Source File\n \n \n \n \n \n \n \n@@ -62,408 +62,953 @@\n \n
    \n \n
    \n
    \n
    \n-
    dependency.hh
    \n+
    matrixhierarchy.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_AMG_DEPENDENCY_HH
    \n-
    6#define DUNE_AMG_DEPENDENCY_HH
    \n+
    5#ifndef DUNE_AMG_MATRIXHIERARCHY_HH
    \n+
    6#define DUNE_AMG_MATRIXHIERARCHY_HH
    \n
    7
    \n-
    8
    \n-
    9#include <bitset>
    \n-
    10#include <ostream>
    \n-
    11
    \n-
    12#include "graph.hh"
    \n-
    13#include "properties.hh"
    \n-
    14#include <dune/common/propertymap.hh>
    \n-
    15
    \n-
    16
    \n-
    17namespace Dune
    \n-
    18{
    \n-
    19 namespace Amg
    \n-
    20 {
    \n-\n-
    39 {
    \n-
    40 friend std::ostream& operator<<(std::ostream& os, const EdgeProperties& props);
    \n-
    41 public:
    \n-\n-
    44
    \n-
    45 private:
    \n-
    46
    \n-
    47 std::bitset<SIZE> flags_;
    \n-
    48 public:
    \n-\n-
    51
    \n-
    53 std::bitset<SIZE>::reference operator[](std::size_t v);
    \n-
    54
    \n-
    56 bool operator[](std::size_t v) const;
    \n-
    57
    \n-
    63 bool depends() const;
    \n-
    64
    \n-
    69 void setDepends();
    \n-
    70
    \n-
    74 void resetDepends();
    \n-
    75
    \n-
    80 bool influences() const;
    \n-
    81
    \n-
    85 void setInfluences();
    \n+
    8#include <algorithm>
    \n+
    9#include <tuple>
    \n+
    10#include "aggregates.hh"
    \n+
    11#include "graph.hh"
    \n+
    12#include "galerkin.hh"
    \n+
    13#include "renumberer.hh"
    \n+
    14#include "graphcreator.hh"
    \n+
    15#include "hierarchy.hh"
    \n+
    16#include <dune/istl/bvector.hh>
    \n+
    17#include <dune/common/parallel/indexset.hh>
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+
    27
    \n+
    28namespace Dune
    \n+
    29{
    \n+
    30 namespace Amg
    \n+
    31 {
    \n+
    42 enum {
    \n+
    50 MAX_PROCESSES = 72000
    \n+
    51 };
    \n+
    52
    \n+
    59 template<class M, class PI, class A=std::allocator<M> >
    \n+\n+
    61 {
    \n+
    62 public:
    \n+
    64 typedef M MatrixOperator;
    \n+
    65
    \n+
    67 typedef typename MatrixOperator::matrix_type Matrix;
    \n+
    68
    \n+\n+
    71
    \n+
    73 typedef A Allocator;
    \n+
    74
    \n+\n+
    77
    \n+\n+
    80
    \n+\n+
    83
    \n+
    85 using AAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<AggregatesMap*>;
    \n
    86
    \n-
    90 void resetInfluences();
    \n-
    91
    \n-
    96 bool isOneWay() const;
    \n-
    97
    \n-
    102 bool isTwoWay() const;
    \n-
    103
    \n-
    108 bool isStrong() const;
    \n-
    109
    \n-
    113 void reset();
    \n-
    114
    \n-
    118 void printFlags() const;
    \n-
    119 };
    \n-
    120
    \n-\n-
    127 friend std::ostream& operator<<(std::ostream& os, const VertexProperties& props);
    \n-
    128 public:
    \n-\n-
    130 private:
    \n-
    131
    \n-
    133 std::bitset<SIZE> flags_;
    \n-
    134
    \n-
    135 public:
    \n-\n-
    138
    \n-
    140 std::bitset<SIZE>::reference operator[](std::size_t v);
    \n-
    141
    \n-
    143 bool operator[](std::size_t v) const;
    \n-
    144
    \n-
    151 void setIsolated();
    \n-
    152
    \n-
    156 bool isolated() const;
    \n-
    157
    \n-
    161 void resetIsolated();
    \n+
    88 typedef std::list<AggregatesMap*,AAllocator> AggregatesMapList;
    \n+
    89
    \n+\n+
    92
    \n+
    94 using RILAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<RedistributeInfoType>;
    \n+
    95
    \n+
    97 typedef std::list<RedistributeInfoType,RILAllocator> RedistributeInfoList;
    \n+
    98
    \n+
    104 MatrixHierarchy(std::shared_ptr<MatrixOperator> fineMatrix,
    \n+
    105 std::shared_ptr<ParallelInformation> pinfo = std::make_shared<ParallelInformation>());
    \n+
    106
    \n+\n+
    108
    \n+
    114 template<typename O, typename T>
    \n+
    115 void build(const T& criterion);
    \n+
    116
    \n+
    124 template<class F>
    \n+
    125 void recalculateGalerkin(const F& copyFlags);
    \n+
    126
    \n+
    131 template<class V, class BA, class TA>
    \n+
    132 void coarsenVector(Hierarchy<BlockVector<V,BA>, TA>& hierarchy) const;
    \n+
    133
    \n+
    139 template<class S, class TA>
    \n+
    140 void coarsenSmoother(Hierarchy<S,TA>& smoothers,
    \n+
    141 const typename SmootherTraits<S>::Arguments& args) const;
    \n+
    142
    \n+
    147 std::size_t levels() const;
    \n+
    148
    \n+
    153 std::size_t maxlevels() const;
    \n+
    154
    \n+
    155 bool hasCoarsest() const;
    \n+
    156
    \n+
    161 bool isBuilt() const;
    \n
    162
    \n-
    166 void setVisited();
    \n-
    167
    \n-
    171 bool visited() const;
    \n-
    172
    \n-
    176 void resetVisited();
    \n-
    177
    \n-
    181 void setFront();
    \n-
    182
    \n-
    186 bool front() const;
    \n+
    167 const ParallelMatrixHierarchy& matrices() const;
    \n+
    168
    \n+\n+
    174
    \n+
    179 const AggregatesMapList& aggregatesMaps() const;
    \n+
    180
    \n+\n
    187
    \n-
    191 void resetFront();
    \n+\n+
    189 {
    \n+
    190 return prolongDamp_;
    \n+
    191 }
    \n
    192
    \n-
    196 void setExcludedBorder();
    \n-
    197
    \n-
    202 bool excludedBorder() const;
    \n-
    203
    \n-
    207 void resetExcludedBorder();
    \n-
    208
    \n-
    212 void reset();
    \n-
    213
    \n-
    214 };
    \n-
    215
    \n-
    216 template<typename G, std::size_t i>
    \n-\n-
    218 : public RAPropertyMapHelper<typename std::bitset<VertexProperties::SIZE>::reference,
    \n-
    219 PropertyGraphVertexPropertyMap<G,i> >
    \n-
    220 {
    \n-
    221 public:
    \n+
    203 void getCoarsestAggregatesOnFinest(std::vector<std::size_t>& data) const;
    \n+
    204
    \n+
    205 private:
    \n+
    206 typedef typename ConstructionTraits<MatrixOperator>::Arguments MatrixArgs;
    \n+
    207 typedef typename ConstructionTraits<ParallelInformation>::Arguments CommunicationArgs;
    \n+
    209 AggregatesMapList aggregatesMaps_;
    \n+
    211 RedistributeInfoList redistributes_;
    \n+
    213 ParallelMatrixHierarchy matrices_;
    \n+
    215 ParallelInformationHierarchy parallelInformation_;
    \n+
    216
    \n+
    218 bool built_;
    \n+
    219
    \n+
    221 int maxlevels_;
    \n
    222
    \n-
    223 typedef ReadWritePropertyMapTag Category;
    \n+
    223 double prolongDamp_;
    \n
    224
    \n-
    225 enum {
    \n-
    227 index = i
    \n-
    228 };
    \n-
    229
    \n-
    233 typedef G Graph;
    \n-
    234
    \n-
    238 typedef std::bitset<VertexProperties::SIZE> BitSet;
    \n-
    239
    \n-
    243 typedef typename BitSet::reference Reference;
    \n-
    244
    \n-
    248 typedef bool ValueType;
    \n-
    249
    \n-
    253 typedef typename G::VertexDescriptor Vertex;
    \n-
    254
    \n-\n-
    260 : graph_(&g)
    \n-
    261 {}
    \n-
    262
    \n-\n-
    267 : graph_(0)
    \n-
    268 {}
    \n-
    269
    \n-
    270
    \n-
    275 Reference operator[](const Vertex& vertex) const
    \n-
    276 {
    \n-
    277 return graph_->getVertexProperties(vertex)[index];
    \n-
    278 }
    \n-
    279 private:
    \n-
    280 Graph* graph_;
    \n-
    281 };
    \n-
    282
    \n-
    283 } // end namespace Amg
    \n-
    284
    \n-
    285 template<typename G, typename EP, typename VM, typename EM>
    \n-
    286 struct PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> >
    \n-
    287 {
    \n-\n-
    289 };
    \n+
    228 template<class Matrix, bool print>
    \n+
    229 struct MatrixStats
    \n+
    230 {
    \n+
    231
    \n+
    235 static void stats([[maybe_unused]] const Matrix& matrix)
    \n+
    236 {}
    \n+
    237 };
    \n+
    238
    \n+
    239 template<class Matrix>
    \n+
    240 struct MatrixStats<Matrix,true>
    \n+
    241 {
    \n+
    242 struct calc
    \n+
    243 {
    \n+
    244 typedef typename Matrix::size_type size_type;
    \n+
    245 typedef typename Matrix::row_type matrix_row;
    \n+
    246
    \n+\n+
    248 {
    \n+
    249 min=std::numeric_limits<size_type>::max();
    \n+
    250 max=0;
    \n+
    251 sum=0;
    \n+
    252 }
    \n+
    253
    \n+
    254 void operator()(const matrix_row& row)
    \n+
    255 {
    \n+
    256 min=std::min(min, row.size());
    \n+
    257 max=std::max(max, row.size());
    \n+
    258 sum += row.size();
    \n+
    259 }
    \n+
    260
    \n+\n+\n+\n+
    264 };
    \n+
    268 static void stats(const Matrix& matrix)
    \n+
    269 {
    \n+
    270 calc c= for_each(matrix.begin(), matrix.end(), calc());
    \n+
    271 dinfo<<"Matrix row: min="<<c.min<<" max="<<c.max
    \n+
    272 <<" average="<<static_cast<double>(c.sum)/matrix.N()
    \n+
    273 <<std::endl;
    \n+
    274 }
    \n+
    275 };
    \n+
    276 };
    \n+
    277
    \n+
    281 template<class T>
    \n+
    282 class CoarsenCriterion : public T
    \n+
    283 {
    \n+
    284 public:
    \n+\n
    290
    \n-
    291 template<typename G, typename EP, typename VM, typename EM>
    \n-
    292 typename PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> >::Type
    \n-\n-
    294 {
    \n-\n-
    296 }
    \n-
    297
    \n-
    298 namespace Amg
    \n-
    299 {
    \n-
    300 inline std::ostream& operator<<(std::ostream& os, const EdgeProperties& props)
    \n-
    301 {
    \n-
    302 return os << props.flags_;
    \n-
    303 }
    \n-
    304
    \n-\n-
    306 : flags_()
    \n-
    307 {}
    \n-
    308
    \n-
    309 inline std::bitset<EdgeProperties::SIZE>::reference
    \n-\n-
    311 {
    \n-
    312 return flags_[v];
    \n-
    313 }
    \n-
    314
    \n-
    315 inline bool EdgeProperties::operator[](std::size_t i) const
    \n-
    316 {
    \n-
    317 return flags_[i];
    \n-
    318 }
    \n-
    319
    \n-\n-
    321 {
    \n-
    322 flags_.reset();
    \n-
    323 }
    \n+
    301 CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,
    \n+
    302 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n+
    303 : AggregationCriterion(Dune::Amg::Parameters(maxLevel, coarsenTarget, minCoarsenRate, prolongDamp, accumulate))
    \n+
    304 {}
    \n+
    305
    \n+\n+
    307 : AggregationCriterion(parms)
    \n+
    308 {}
    \n+
    309
    \n+
    310 };
    \n+
    311
    \n+
    312 template<typename M, typename C1>
    \n+
    313 bool repartitionAndDistributeMatrix([[maybe_unused]] const M& origMatrix,
    \n+
    314 [[maybe_unused]] std::shared_ptr<M> newMatrix,
    \n+
    315 [[maybe_unused]] SequentialInformation& origComm,
    \n+
    316 [[maybe_unused]] std::shared_ptr<SequentialInformation>& newComm,
    \n+\n+
    318 [[maybe_unused]] int nparts,
    \n+
    319 [[maybe_unused]] C1& criterion)
    \n+
    320 {
    \n+
    321 DUNE_THROW(NotImplemented, "Redistribution does not make sense in sequential code!");
    \n+
    322 }
    \n+
    323
    \n
    324
    \n-\n-
    326 {
    \n-
    327 // Set the INFLUENCE bit
    \n-
    328 //flags_ |= (1<<INFLUENCE);
    \n-
    329 flags_.set(INFLUENCE);
    \n-
    330 }
    \n-
    331
    \n-
    332 inline bool EdgeProperties::influences() const
    \n-
    333 {
    \n-
    334 // Test the INFLUENCE bit
    \n-
    335 return flags_.test(INFLUENCE);
    \n-
    336 }
    \n-
    337
    \n-\n-
    339 {
    \n-
    340 // Set the first bit.
    \n-
    341 //flags_ |= (1<<DEPEND);
    \n-
    342 flags_.set(DEPEND);
    \n-
    343 }
    \n-
    344
    \n-\n-
    346 {
    \n-
    347 // reset the first bit.
    \n-
    348 //flags_ &= ~(1<<DEPEND);
    \n-
    349 flags_.reset(DEPEND);
    \n-
    350 }
    \n-
    351
    \n-
    352 inline bool EdgeProperties::depends() const
    \n-
    353 {
    \n-
    354 // Return the first bit.
    \n-
    355 return flags_.test(DEPEND);
    \n-
    356 }
    \n-
    357
    \n-\n-
    359 {
    \n-
    360 // reset the second bit.
    \n-
    361 flags_ &= ~(1<<INFLUENCE);
    \n-
    362 }
    \n-
    363
    \n-
    364 inline bool EdgeProperties::isOneWay() const
    \n-
    365 {
    \n-
    366 // Test whether only the first bit is set
    \n-
    367 //return isStrong() && !isTwoWay();
    \n-
    368 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==(1<<DEPEND);
    \n-
    369 }
    \n+
    325 template<typename M, typename C, typename C1>
    \n+
    326 bool repartitionAndDistributeMatrix(const M& origMatrix,
    \n+
    327 std::shared_ptr<M> newMatrix,
    \n+
    328 C& origComm,
    \n+
    329 std::shared_ptr<C>& newComm,
    \n+\n+
    331 int nparts, C1& criterion)
    \n+
    332 {
    \n+
    333 Timer time;
    \n+
    334#ifdef AMG_REPART_ON_COMM_GRAPH
    \n+
    335 // Done not repartition the matrix graph, but a graph of the communication scheme.
    \n+
    336 bool existentOnRedist=Dune::commGraphRepartition(origMatrix, origComm, nparts, newComm,
    \n+
    337 ri.getInterface(),
    \n+
    338 criterion.debugLevel()>1);
    \n+
    339
    \n+
    340#else
    \n+\n+\n+\n+\n+
    345 IdentityMap,
    \n+
    346 IdentityMap> PropertiesGraph;
    \n+
    347 MatrixGraph graph(origMatrix);
    \n+
    348 PropertiesGraph pgraph(graph);
    \n+
    349 buildDependency(pgraph, origMatrix, criterion, false);
    \n+
    350
    \n+
    351#ifdef DEBUG_REPART
    \n+
    352 if(origComm.communicator().rank()==0)
    \n+
    353 std::cout<<"Original matrix"<<std::endl;
    \n+
    354 origComm.communicator().barrier();
    \n+
    355 printGlobalSparseMatrix(origMatrix, origComm, std::cout);
    \n+
    356#endif
    \n+
    357 bool existentOnRedist=Dune::graphRepartition(pgraph, origComm, nparts,
    \n+
    358 newComm, ri.getInterface(),
    \n+
    359 criterion.debugLevel()>1);
    \n+
    360#endif // if else AMG_REPART
    \n+
    361
    \n+
    362 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)
    \n+
    363 std::cout<<"Repartitioning took "<<time.elapsed()<<" seconds."<<std::endl;
    \n+
    364
    \n+
    365 ri.setSetup();
    \n+
    366
    \n+
    367#ifdef DEBUG_REPART
    \n+
    368 ri.checkInterface(origComm.indexSet(), newComm->indexSet(), origComm.communicator());
    \n+
    369#endif
    \n
    370
    \n-
    371 inline bool EdgeProperties::isTwoWay() const
    \n-
    372 {
    \n-
    373 // Test whether the first and second bit is set
    \n-
    374 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==((1<<INFLUENCE)|(1<<DEPEND));
    \n-
    375 }
    \n-
    376
    \n-
    377 inline bool EdgeProperties::isStrong() const
    \n-
    378 {
    \n-
    379 // Test whether the first or second bit is set
    \n-
    380 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND))).to_ulong();
    \n-
    381 }
    \n-
    382
    \n-
    383
    \n-
    384 inline std::ostream& operator<<(std::ostream& os, const VertexProperties& props)
    \n-
    385 {
    \n-
    386 return os << props.flags_;
    \n-
    387 }
    \n-
    388
    \n-\n-
    390 : flags_()
    \n-
    391 {}
    \n-
    392
    \n-
    393
    \n-
    394 inline std::bitset<VertexProperties::SIZE>::reference
    \n-\n-
    396 {
    \n-
    397 return flags_[v];
    \n-
    398 }
    \n-
    399
    \n-
    400 inline bool VertexProperties::operator[](std::size_t v) const
    \n-
    401 {
    \n-
    402 return flags_[v];
    \n-
    403 }
    \n-
    404
    \n-\n-
    406 {
    \n-
    407 flags_.set(ISOLATED);
    \n-
    408 }
    \n-
    409
    \n-
    410 inline bool VertexProperties::isolated() const
    \n-
    411 {
    \n-
    412 return flags_.test(ISOLATED);
    \n-
    413 }
    \n-
    414
    \n-\n-
    416 {
    \n-
    417 flags_.reset(ISOLATED);
    \n-
    418 }
    \n+
    371 redistributeMatrix(const_cast<M&>(origMatrix), *newMatrix, origComm, *newComm, ri);
    \n+
    372
    \n+
    373#ifdef DEBUG_REPART
    \n+
    374 if(origComm.communicator().rank()==0)
    \n+
    375 std::cout<<"Original matrix"<<std::endl;
    \n+
    376 origComm.communicator().barrier();
    \n+
    377 if(newComm->communicator().size()>0)
    \n+
    378 printGlobalSparseMatrix(*newMatrix, *newComm, std::cout);
    \n+
    379 origComm.communicator().barrier();
    \n+
    380#endif
    \n+
    381
    \n+
    382 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)
    \n+
    383 std::cout<<"Redistributing matrix took "<<time.elapsed()<<" seconds."<<std::endl;
    \n+
    384 return existentOnRedist;
    \n+
    385
    \n+
    386 }
    \n+
    387
    \n+
    388 template<class M, class IS, class A>
    \n+
    389 MatrixHierarchy<M,IS,A>::MatrixHierarchy(std::shared_ptr<MatrixOperator> fineMatrix,
    \n+
    390 std::shared_ptr<ParallelInformation> pinfo)
    \n+
    391 : matrices_(fineMatrix),
    \n+
    392 parallelInformation_(pinfo)
    \n+
    393 {
    \n+
    394 if (SolverCategory::category(*fineMatrix) != SolverCategory::category(*pinfo))
    \n+
    395 DUNE_THROW(ISTLError, "MatrixOperator and ParallelInformation must belong to the same category!");
    \n+
    396 }
    \n+
    397
    \n+
    398 template<class M, class IS, class A>
    \n+
    399 template<typename O, typename T>
    \n+
    400 void MatrixHierarchy<M,IS,A>::build(const T& criterion)
    \n+
    401 {
    \n+
    402 prolongDamp_ = criterion.getProlongationDampingFactor();
    \n+
    403 typedef O OverlapFlags;
    \n+
    404 typedef typename ParallelMatrixHierarchy::Iterator MatIterator;
    \n+
    405 typedef typename ParallelInformationHierarchy::Iterator PInfoIterator;
    \n+
    406
    \n+
    407 static const int noints=(Dune::Amg::MAX_PROCESSES/4096>0) ? (Dune::Amg::MAX_PROCESSES/4096) : 1;
    \n+
    408
    \n+
    409 typedef bigunsignedint<sizeof(int)*8*noints> BIGINT;
    \n+\n+
    411 MatIterator mlevel = matrices_.finest();
    \n+
    412 MatrixStats<typename M::matrix_type,MINIMAL_DEBUG_LEVEL<=INFO_DEBUG_LEVEL>::stats(mlevel->getmat());
    \n+
    413
    \n+
    414 PInfoIterator infoLevel = parallelInformation_.finest();
    \n+
    415 BIGINT finenonzeros=countNonZeros(mlevel->getmat());
    \n+
    416 finenonzeros = infoLevel->communicator().sum(finenonzeros);
    \n+
    417 BIGINT allnonzeros = finenonzeros;
    \n+
    418
    \n
    419
    \n-\n-
    421 {
    \n-
    422 flags_.set(VISITED);
    \n-
    423 }
    \n+
    420 int level = 0;
    \n+
    421 int rank = 0;
    \n+
    422
    \n+
    423 BIGINT unknowns = mlevel->getmat().N();
    \n
    424
    \n-
    425 inline bool VertexProperties::visited() const
    \n-
    426 {
    \n-
    427 return flags_.test(VISITED);
    \n-
    428 }
    \n+
    425 unknowns = infoLevel->communicator().sum(unknowns);
    \n+
    426 double dunknowns=unknowns.todouble();
    \n+
    427 infoLevel->buildGlobalLookup(mlevel->getmat().N());
    \n+
    428 redistributes_.push_back(RedistributeInfoType());
    \n
    429
    \n-\n-
    431 {
    \n-
    432 flags_.reset(VISITED);
    \n-
    433 }
    \n-
    434
    \n-\n-
    436 {
    \n-
    437 flags_.set(FRONT);
    \n-
    438 }
    \n+
    430 for(; level < criterion.maxLevel(); ++level, ++mlevel) {
    \n+
    431 assert(matrices_.levels()==redistributes_.size());
    \n+
    432 rank = infoLevel->communicator().rank();
    \n+
    433 if(rank==0 && criterion.debugLevel()>1)
    \n+
    434 std::cout<<"Level "<<level<<" has "<<dunknowns<<" unknowns, "<<dunknowns/infoLevel->communicator().size()
    \n+
    435 <<" unknowns per proc (procs="<<infoLevel->communicator().size()<<")"<<std::endl;
    \n+
    436
    \n+
    437 MatrixOperator* matrix=&(*mlevel);
    \n+
    438 ParallelInformation* info =&(*infoLevel);
    \n
    439
    \n-
    440 inline bool VertexProperties::front() const
    \n-
    441 {
    \n-
    442 return flags_.test(FRONT);
    \n-
    443 }
    \n-
    444
    \n-\n-
    446 {
    \n-
    447 flags_.reset(FRONT);
    \n-
    448 }
    \n-
    449
    \n-\n-
    451 {
    \n-
    452 flags_.set(BORDER);
    \n-
    453 }
    \n-
    454
    \n-\n-
    456 {
    \n-
    457 return flags_.test(BORDER);
    \n-
    458 }
    \n+
    440 if((
    \n+
    441#if HAVE_PARMETIS
    \n+
    442 criterion.accumulate()==successiveAccu
    \n+
    443#else
    \n+
    444 false
    \n+
    445#endif
    \n+
    446 || (criterion.accumulate()==atOnceAccu
    \n+
    447 && dunknowns < 30*infoLevel->communicator().size()))
    \n+
    448 && infoLevel->communicator().size()>1 &&
    \n+
    449 dunknowns/infoLevel->communicator().size() <= criterion.coarsenTarget())
    \n+
    450 {
    \n+
    451 // accumulate to fewer processors
    \n+
    452 std::shared_ptr<Matrix> redistMat = std::make_shared<Matrix>();
    \n+
    453 std::shared_ptr<ParallelInformation> redistComm;
    \n+
    454 std::size_t nodomains = (std::size_t)std::ceil(dunknowns/(criterion.minAggregateSize()
    \n+
    455 *criterion.coarsenTarget()));
    \n+
    456 if( nodomains<=criterion.minAggregateSize()/2 ||
    \n+
    457 dunknowns <= criterion.coarsenTarget() )
    \n+
    458 nodomains=1;
    \n
    459
    \n-\n-
    461 {
    \n-
    462 flags_.reset(BORDER);
    \n-
    463 }
    \n-
    464
    \n-\n-
    466 {
    \n-
    467 flags_.reset();
    \n-
    468 }
    \n-
    469
    \n-
    471 }
    \n-
    472}
    \n-
    473#endif
    \n-
    Provides classes for building the matrix graph.
    \n-
    Provides classes for handling internal properties in a graph.
    \n-
    bool depends() const
    Checks wether the vertex the edge points to depends on the vertex the edge starts.
    Definition: dependency.hh:352
    \n-
    void resetFront()
    Resets the front node flag.
    Definition: dependency.hh:445
    \n-
    std::bitset< VertexProperties::SIZE > BitSet
    The type of the bitset.
    Definition: dependency.hh:238
    \n-
    bool isolated() const
    Checks wether the node is isolated.
    Definition: dependency.hh:410
    \n-
    bool ValueType
    The value type.
    Definition: dependency.hh:248
    \n-
    friend std::ostream & operator<<(std::ostream &os, const VertexProperties &props)
    Definition: dependency.hh:384
    \n-
    BitSet::reference Reference
    The reference type.
    Definition: dependency.hh:243
    \n-
    bool isTwoWay() const
    Checks wether the edge is two way. I.e. both the influence flag and the depends flag are that.
    Definition: dependency.hh:371
    \n-
    void setInfluences()
    Marks the edge as one of which the start vertex by the end vertex.
    Definition: dependency.hh:325
    \n-
    VertexProperties()
    Constructor.
    Definition: dependency.hh:389
    \n-
    void setDepends()
    Marks the edge as one of which the end point depends on the starting point.
    Definition: dependency.hh:338
    \n-
    PropertyGraphVertexPropertyMap()
    Default constructor.
    Definition: dependency.hh:266
    \n-
    PropertyGraphVertexPropertyMap(G &g)
    Constructor.
    Definition: dependency.hh:259
    \n-
    G::VertexDescriptor Vertex
    The vertex descriptor.
    Definition: dependency.hh:253
    \n-
    void resetExcludedBorder()
    Marks the vertex as included in the aggregation.
    Definition: dependency.hh:460
    \n-
    void setFront()
    Marks the node as belonging to the current clusters front.
    Definition: dependency.hh:435
    \n-
    void reset()
    Reset all flags.
    Definition: dependency.hh:465
    \n-
    void setVisited()
    Mark the node as already visited.
    Definition: dependency.hh:420
    \n-
    EdgeProperties()
    Constructor.
    Definition: dependency.hh:305
    \n-
    void resetInfluences()
    Resets the influence flag.
    Definition: dependency.hh:358
    \n-
    G Graph
    The type of the graph with internal properties.
    Definition: dependency.hh:233
    \n-
    std::bitset< SIZE >::reference operator[](std::size_t v)
    Access the bits directly.
    Definition: dependency.hh:395
    \n-
    void printFlags() const
    Prints the attributes of the edge for debugging.
    \n-
    friend std::ostream & operator<<(std::ostream &os, const EdgeProperties &props)
    Definition: dependency.hh:300
    \n-
    Amg::PropertyGraphVertexPropertyMap< Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM >, Amg::VertexProperties::VISITED > Type
    Definition: dependency.hh:288
    \n-
    bool influences() const
    Checks wether the start vertex is influenced by the end vertex.
    Definition: dependency.hh:332
    \n-
    void setIsolated()
    Marks that node as being isolated.
    Definition: dependency.hh:405
    \n-
    bool excludedBorder() const
    Tests whether the vertex is excluded from the aggregation.
    Definition: dependency.hh:455
    \n-
    void resetVisited()
    Resets the visited flag.
    Definition: dependency.hh:430
    \n-
    bool visited() const
    Checks wether the node is marked as visited.
    Definition: dependency.hh:425
    \n-
    Reference operator[](const Vertex &vertex) const
    Get the properties associated to a vertex.
    Definition: dependency.hh:275
    \n-
    void reset()
    Reset all flags.
    Definition: dependency.hh:320
    \n-
    void resetDepends()
    Resets the depends flag.
    Definition: dependency.hh:345
    \n-
    ReadWritePropertyMapTag Category
    Definition: dependency.hh:223
    \n-
    void resetIsolated()
    Resets the isolated flag.
    Definition: dependency.hh:415
    \n-
    std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T > &criterion)
    Definition: aggregates.hh:113
    \n-
    bool isStrong() const
    Checks wether the edge is strong. I.e. the influence or depends flag is set.
    Definition: dependency.hh:377
    \n-
    bool front() const
    Checks wether the node is marked as a front node.
    Definition: dependency.hh:440
    \n-
    std::bitset< SIZE >::reference operator[](std::size_t v)
    Access the bits directly.
    Definition: dependency.hh:310
    \n-
    void setExcludedBorder()
    Marks the vertex as excluded from the aggregation.
    Definition: dependency.hh:450
    \n-
    bool isOneWay() const
    Checks wether the edge is one way. I.e. either the influence or the depends flag but is set.
    Definition: dependency.hh:364
    \n-
    @ index
    the index to access in the bitset.
    Definition: dependency.hh:227
    \n-
    @ VISITED
    Definition: dependency.hh:129
    \n-
    @ ISOLATED
    Definition: dependency.hh:129
    \n-
    @ SIZE
    Definition: dependency.hh:129
    \n-
    @ BORDER
    Definition: dependency.hh:129
    \n-
    @ FRONT
    Definition: dependency.hh:129
    \n-
    @ DEPEND
    Definition: dependency.hh:43
    \n-
    @ SIZE
    Definition: dependency.hh:43
    \n-
    @ INFLUENCE
    Definition: dependency.hh:43
    \n+
    460 bool existentOnNextLevel =
    \n+
    461 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,
    \n+
    462 redistComm, redistributes_.back(), nodomains,
    \n+
    463 criterion);
    \n+
    464 BIGINT unknownsRedist = redistMat->N();
    \n+
    465 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);
    \n+
    466 dunknowns= unknownsRedist.todouble();
    \n+
    467 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1)
    \n+
    468 std::cout<<"Level "<<level<<" (redistributed) has "<<dunknowns<<" unknowns, "<<dunknowns/redistComm->communicator().size()
    \n+
    469 <<" unknowns per proc (procs="<<redistComm->communicator().size()<<")"<<std::endl;
    \n+
    470 MatrixArgs args(redistMat, *redistComm);
    \n+
    471 mlevel.addRedistributed(ConstructionTraits<MatrixOperator>::construct(args));
    \n+
    472 assert(mlevel.isRedistributed());
    \n+
    473 infoLevel.addRedistributed(redistComm);
    \n+
    474 infoLevel->freeGlobalLookup();
    \n+
    475
    \n+
    476 if(!existentOnNextLevel)
    \n+
    477 // We do not hold any data on the redistributed partitioning
    \n+
    478 break;
    \n+
    479
    \n+
    480 // Work on the redistributed Matrix from now on
    \n+
    481 matrix = &(mlevel.getRedistributed());
    \n+
    482 info = &(infoLevel.getRedistributed());
    \n+
    483 info->buildGlobalLookup(matrix->getmat().N());
    \n+
    484 }
    \n+
    485
    \n+
    486 rank = info->communicator().rank();
    \n+
    487 if(dunknowns <= criterion.coarsenTarget())
    \n+
    488 // No further coarsening needed
    \n+
    489 break;
    \n+
    490
    \n+\n+
    492 typedef typename GraphCreator::PropertiesGraph PropertiesGraph;
    \n+
    493 typedef typename GraphCreator::GraphTuple GraphTuple;
    \n+
    494
    \n+
    495 typedef typename PropertiesGraph::VertexDescriptor Vertex;
    \n+
    496
    \n+
    497 std::vector<bool> excluded(matrix->getmat().N(), false);
    \n+
    498
    \n+
    499 GraphTuple graphs = GraphCreator::create(*matrix, excluded, *info, OverlapFlags());
    \n+
    500
    \n+
    501 AggregatesMap* aggregatesMap=new AggregatesMap(std::get<1>(graphs)->maxVertex()+1);
    \n+
    502
    \n+
    503 aggregatesMaps_.push_back(aggregatesMap);
    \n+
    504
    \n+
    505 Timer watch;
    \n+
    506 watch.reset();
    \n+
    507 auto [noAggregates, isoAggregates, oneAggregates, skippedAggregates] =
    \n+
    508 aggregatesMap->buildAggregates(matrix->getmat(), *(std::get<1>(graphs)), criterion, level==0);
    \n+
    509
    \n+
    510 if(rank==0 && criterion.debugLevel()>2)
    \n+
    511 std::cout<<" Have built "<<noAggregates<<" aggregates totally ("<<isoAggregates<<" isolated aggregates, "<<
    \n+
    512 oneAggregates<<" aggregates of one vertex, and skipped "<<
    \n+
    513 skippedAggregates<<" aggregates)."<<std::endl;
    \n+
    514#ifdef TEST_AGGLO
    \n+
    515 {
    \n+
    516 // calculate size of local matrix in the distributed direction
    \n+
    517 int start, end, overlapStart, overlapEnd;
    \n+
    518 int procs=info->communicator().rank();
    \n+
    519 int n = UNKNOWNS/procs; // number of unknowns per process
    \n+
    520 int bigger = UNKNOWNS%procs; // number of process with n+1 unknows
    \n+
    521
    \n+
    522 // Compute owner region
    \n+
    523 if(rank<bigger) {
    \n+
    524 start = rank*(n+1);
    \n+
    525 end = (rank+1)*(n+1);
    \n+
    526 }else{
    \n+
    527 start = bigger + rank * n;
    \n+
    528 end = bigger + (rank + 1) * n;
    \n+
    529 }
    \n+
    530
    \n+
    531 // Compute overlap region
    \n+
    532 if(start>0)
    \n+
    533 overlapStart = start - 1;
    \n+
    534 else
    \n+
    535 overlapStart = start;
    \n+
    536
    \n+
    537 if(end<UNKNOWNS)
    \n+
    538 overlapEnd = end + 1;
    \n+
    539 else
    \n+
    540 overlapEnd = end;
    \n+
    541
    \n+
    542 assert((UNKNOWNS)*(overlapEnd-overlapStart)==aggregatesMap->noVertices());
    \n+
    543 for(int j=0; j< UNKNOWNS; ++j)
    \n+
    544 for(int i=0; i < UNKNOWNS; ++i)
    \n+
    545 {
    \n+
    546 if(i>=overlapStart && i<overlapEnd)
    \n+
    547 {
    \n+
    548 int no = (j/2)*((UNKNOWNS)/2)+i/2;
    \n+
    549 (*aggregatesMap)[j*(overlapEnd-overlapStart)+i-overlapStart]=no;
    \n+
    550 }
    \n+
    551 }
    \n+
    552 }
    \n+
    553#endif
    \n+
    554 if(criterion.debugLevel()>1 && info->communicator().rank()==0)
    \n+
    555 std::cout<<"aggregating finished."<<std::endl;
    \n+
    556
    \n+
    557 BIGINT gnoAggregates=noAggregates;
    \n+
    558 gnoAggregates = info->communicator().sum(gnoAggregates);
    \n+
    559 double dgnoAggregates = gnoAggregates.todouble();
    \n+
    560#ifdef TEST_AGGLO
    \n+
    561 BIGINT gnoAggregates=((UNKNOWNS)/2)*((UNKNOWNS)/2);
    \n+
    562#endif
    \n+
    563
    \n+
    564 if(criterion.debugLevel()>2 && rank==0)
    \n+
    565 std::cout << "Building "<<dgnoAggregates<<" aggregates took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    566
    \n+
    567 if(dgnoAggregates==0 || dunknowns/dgnoAggregates<criterion.minCoarsenRate())
    \n+
    568 {
    \n+
    569 if(rank==0)
    \n+
    570 {
    \n+
    571 if(dgnoAggregates>0)
    \n+
    572 std::cerr << "Stopped coarsening because of rate breakdown "<<dunknowns<<"/"<<dgnoAggregates
    \n+
    573 <<"="<<dunknowns/dgnoAggregates<<"<"
    \n+
    574 <<criterion.minCoarsenRate()<<std::endl;
    \n+
    575 else
    \n+
    576 std::cerr<< "Could not build any aggregates. Probably no connected nodes."<<std::endl;
    \n+
    577 }
    \n+
    578 aggregatesMap->free();
    \n+
    579 delete aggregatesMap;
    \n+
    580 aggregatesMaps_.pop_back();
    \n+
    581
    \n+
    582 if(criterion.accumulate() && mlevel.isRedistributed() && info->communicator().size()>1) {
    \n+
    583 // coarse level matrix was already redistributed, but to more than 1 process
    \n+
    584 // Therefore need to delete the redistribution. Further down it will
    \n+
    585 // then be redistributed to 1 process
    \n+
    586 delete &(mlevel.getRedistributed().getmat());
    \n+
    587 mlevel.deleteRedistributed();
    \n+
    588 delete &(infoLevel.getRedistributed());
    \n+
    589 infoLevel.deleteRedistributed();
    \n+
    590 redistributes_.back().resetSetup();
    \n+
    591 }
    \n+
    592
    \n+
    593 break;
    \n+
    594 }
    \n+
    595 unknowns = noAggregates;
    \n+
    596 dunknowns = dgnoAggregates;
    \n+
    597
    \n+
    598 CommunicationArgs commargs(info->communicator(),info->category());
    \n+
    599 parallelInformation_.addCoarser(commargs);
    \n+
    600
    \n+
    601 ++infoLevel; // parallel information on coarse level
    \n+
    602
    \n+
    603 typename PropertyMapTypeSelector<VertexVisitedTag,PropertiesGraph>::Type visitedMap =
    \n+
    604 get(VertexVisitedTag(), *(std::get<1>(graphs)));
    \n+
    605
    \n+
    606 watch.reset();
    \n+\n+
    608 ::coarsen(*info,
    \n+
    609 *(std::get<1>(graphs)),
    \n+
    610 visitedMap,
    \n+
    611 *aggregatesMap,
    \n+
    612 *infoLevel,
    \n+
    613 noAggregates);
    \n+
    614 GraphCreator::free(graphs);
    \n+
    615
    \n+
    616 if(criterion.debugLevel()>2) {
    \n+
    617 if(rank==0)
    \n+
    618 std::cout<<"Coarsening of index sets took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    619 }
    \n+
    620
    \n+
    621 watch.reset();
    \n+
    622
    \n+
    623 infoLevel->buildGlobalLookup(aggregates);
    \n+\n+
    625 *info,
    \n+
    626 infoLevel->globalLookup());
    \n+
    627
    \n+
    628
    \n+
    629 if(criterion.debugLevel()>2) {
    \n+
    630 if(rank==0)
    \n+
    631 std::cout<<"Communicating global aggregate numbers took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    632 }
    \n+
    633
    \n+
    634 watch.reset();
    \n+
    635 std::vector<bool>& visited=excluded;
    \n+
    636
    \n+
    637 typedef std::vector<bool>::iterator Iterator;
    \n+
    638 typedef IteratorPropertyMap<Iterator, IdentityMap> VisitedMap2;
    \n+
    639 Iterator end = visited.end();
    \n+
    640 for(Iterator iter= visited.begin(); iter != end; ++iter)
    \n+
    641 *iter=false;
    \n+
    642
    \n+
    643 VisitedMap2 visitedMap2(visited.begin(), Dune::IdentityMap());
    \n+
    644
    \n+
    645 std::shared_ptr<typename MatrixOperator::matrix_type>
    \n+
    646 coarseMatrix(productBuilder.build(*(std::get<0>(graphs)), visitedMap2,
    \n+
    647 *info,
    \n+
    648 *aggregatesMap,
    \n+
    649 aggregates,
    \n+
    650 OverlapFlags()));
    \n+
    651 dverb<<"Building of sparsity pattern took "<<watch.elapsed()<<std::endl;
    \n+
    652 watch.reset();
    \n+
    653 info->freeGlobalLookup();
    \n+
    654
    \n+
    655 delete std::get<0>(graphs);
    \n+
    656 productBuilder.calculate(matrix->getmat(), *aggregatesMap, *coarseMatrix, *infoLevel, OverlapFlags());
    \n+
    657
    \n+
    658 if(criterion.debugLevel()>2) {
    \n+
    659 if(rank==0)
    \n+
    660 std::cout<<"Calculation entries of Galerkin product took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    661 }
    \n+
    662
    \n+
    663 BIGINT nonzeros = countNonZeros(*coarseMatrix);
    \n+
    664 allnonzeros = allnonzeros + infoLevel->communicator().sum(nonzeros);
    \n+
    665 MatrixArgs args(coarseMatrix, *infoLevel);
    \n+
    666
    \n+
    667 matrices_.addCoarser(args);
    \n+
    668 redistributes_.push_back(RedistributeInfoType());
    \n+
    669 } // end level loop
    \n+
    670
    \n+
    671
    \n+
    672 infoLevel->freeGlobalLookup();
    \n+
    673
    \n+
    674 built_=true;
    \n+
    675 AggregatesMap* aggregatesMap=new AggregatesMap(0);
    \n+
    676 aggregatesMaps_.push_back(aggregatesMap);
    \n+
    677
    \n+
    678 if(criterion.debugLevel()>0) {
    \n+
    679 if(level==criterion.maxLevel()) {
    \n+
    680 BIGINT unknownsLevel = mlevel->getmat().N();
    \n+
    681 unknownsLevel = infoLevel->communicator().sum(unknownsLevel);
    \n+
    682 double dunknownsLevel = unknownsLevel.todouble();
    \n+
    683 if(rank==0 && criterion.debugLevel()>1) {
    \n+
    684 std::cout<<"Level "<<level<<" has "<<dunknownsLevel<<" unknowns, "<<dunknownsLevel/infoLevel->communicator().size()
    \n+
    685 <<" unknowns per proc (procs="<<infoLevel->communicator().size()<<")"<<std::endl;
    \n+
    686 }
    \n+
    687 }
    \n+
    688 }
    \n+
    689
    \n+
    690 if(criterion.accumulate() && !redistributes_.back().isSetup() &&
    \n+
    691 infoLevel->communicator().size()>1) {
    \n+
    692#if HAVE_MPI && !HAVE_PARMETIS
    \n+
    693 if(criterion.accumulate()==successiveAccu &&
    \n+
    694 infoLevel->communicator().rank()==0)
    \n+
    695 std::cerr<<"Successive accumulation of data on coarse levels only works with ParMETIS installed."
    \n+
    696 <<" Fell back to accumulation to one domain on coarsest level"<<std::endl;
    \n+
    697#endif
    \n+
    698
    \n+
    699 // accumulate to fewer processors
    \n+
    700 std::shared_ptr<Matrix> redistMat = std::make_shared<Matrix>();
    \n+
    701 std::shared_ptr<ParallelInformation> redistComm;
    \n+
    702 int nodomains = 1;
    \n+
    703
    \n+
    704 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,
    \n+
    705 redistComm, redistributes_.back(), nodomains,criterion);
    \n+
    706 MatrixArgs args(redistMat, *redistComm);
    \n+
    707 BIGINT unknownsRedist = redistMat->N();
    \n+
    708 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);
    \n+
    709
    \n+
    710 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1) {
    \n+
    711 double dunknownsRedist = unknownsRedist.todouble();
    \n+
    712 std::cout<<"Level "<<level<<" redistributed has "<<dunknownsRedist<<" unknowns, "<<dunknownsRedist/redistComm->communicator().size()
    \n+
    713 <<" unknowns per proc (procs="<<redistComm->communicator().size()<<")"<<std::endl;
    \n+
    714 }
    \n+
    715 mlevel.addRedistributed(ConstructionTraits<MatrixOperator>::construct(args));
    \n+
    716 infoLevel.addRedistributed(redistComm);
    \n+
    717 infoLevel->freeGlobalLookup();
    \n+
    718 }
    \n+
    719
    \n+
    720 int levels = matrices_.levels();
    \n+
    721 maxlevels_ = parallelInformation_.finest()->communicator().max(levels);
    \n+
    722 assert(matrices_.levels()==redistributes_.size());
    \n+
    723 if(hasCoarsest() && rank==0 && criterion.debugLevel()>1)
    \n+
    724 std::cout<<"operator complexity: "<<allnonzeros.todouble()/finenonzeros.todouble()<<std::endl;
    \n+
    725
    \n+
    726 }
    \n+
    727
    \n+
    728 template<class M, class IS, class A>
    \n+\n+\n+
    731 {
    \n+
    732 return matrices_;
    \n+
    733 }
    \n+
    734
    \n+
    735 template<class M, class IS, class A>
    \n+\n+\n+
    738 {
    \n+
    739 return parallelInformation_;
    \n+
    740 }
    \n+
    741
    \n+
    742 template<class M, class IS, class A>
    \n+
    743 void MatrixHierarchy<M,IS,A>::getCoarsestAggregatesOnFinest(std::vector<std::size_t>& data) const
    \n+
    744 {
    \n+
    745 int levels=aggregatesMaps().size();
    \n+
    746 int maxlevels=parallelInformation_.finest()->communicator().max(levels);
    \n+
    747 std::size_t size=(*(aggregatesMaps().begin()))->noVertices();
    \n+
    748 // We need an auxiliary vector for the consecutive prolongation.
    \n+
    749 std::vector<std::size_t> tmp;
    \n+
    750 std::vector<std::size_t> *coarse, *fine;
    \n+
    751
    \n+
    752 // make sure the allocated space suffices.
    \n+
    753 tmp.reserve(size);
    \n+
    754 data.reserve(size);
    \n+
    755
    \n+
    756 // Correctly assign coarse and fine for the first prolongation such that
    \n+
    757 // we end up in data in the end.
    \n+
    758 if(levels%2==0) {
    \n+
    759 coarse=&tmp;
    \n+
    760 fine=&data;
    \n+
    761 }else{
    \n+
    762 coarse=&data;
    \n+
    763 fine=&tmp;
    \n+
    764 }
    \n+
    765
    \n+
    766 // Number the unknowns on the coarsest level consecutively for each process.
    \n+
    767 if(levels==maxlevels) {
    \n+
    768 const AggregatesMap& map = *(*(++aggregatesMaps().rbegin()));
    \n+
    769 std::size_t m=0;
    \n+
    770
    \n+
    771 for(typename AggregatesMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
    \n+
    772 if(*iter< AggregatesMap::ISOLATED)
    \n+
    773 m=std::max(*iter,m);
    \n+
    774
    \n+
    775 coarse->resize(m+1);
    \n+
    776 std::size_t i=0;
    \n+
    777 srand((unsigned)std::clock());
    \n+
    778 std::set<size_t> used;
    \n+
    779 for(typename std::vector<std::size_t>::iterator iter=coarse->begin(); iter != coarse->end();
    \n+
    780 ++iter, ++i)
    \n+
    781 {
    \n+
    782 std::pair<std::set<std::size_t>::iterator,bool> ibpair
    \n+
    783 = used.insert(static_cast<std::size_t>((((double)rand())/(RAND_MAX+1.0)))*coarse->size());
    \n+
    784
    \n+
    785 while(!ibpair.second)
    \n+
    786 ibpair = used.insert(static_cast<std::size_t>((((double)rand())/(RAND_MAX+1.0))*coarse->size()));
    \n+
    787 *iter=*(ibpair.first);
    \n+
    788 }
    \n+
    789 }
    \n+
    790
    \n+
    791 typename ParallelInformationHierarchy::Iterator pinfo = parallelInformation().coarsest();
    \n+
    792 --pinfo;
    \n+
    793
    \n+
    794 // Now consecutively project the numbers to the finest level.
    \n+
    795 for(typename AggregatesMapList::const_reverse_iterator aggregates=++aggregatesMaps().rbegin();
    \n+
    796 aggregates != aggregatesMaps().rend(); ++aggregates,--levels) {
    \n+
    797
    \n+
    798 fine->resize((*aggregates)->noVertices());
    \n+
    799 fine->assign(fine->size(), 0);
    \n+\n+
    801 ::prolongateVector(*(*aggregates), *coarse, *fine, static_cast<std::size_t>(1), *pinfo);
    \n+
    802 --pinfo;
    \n+
    803 std::swap(coarse, fine);
    \n+
    804 }
    \n+
    805
    \n+
    806 // Assertion to check that we really projected to data on the last step.
    \n+
    807 assert(coarse==&data);
    \n+
    808 }
    \n+
    809
    \n+
    810 template<class M, class IS, class A>
    \n+\n+\n+
    813 {
    \n+
    814 return aggregatesMaps_;
    \n+
    815 }
    \n+
    816 template<class M, class IS, class A>
    \n+\n+\n+
    819 {
    \n+
    820 return redistributes_;
    \n+
    821 }
    \n+
    822
    \n+
    823 template<class M, class IS, class A>
    \n+\n+
    825 {
    \n+
    826 typedef typename AggregatesMapList::reverse_iterator AggregatesMapIterator;
    \n+
    827 typedef typename ParallelMatrixHierarchy::Iterator Iterator;
    \n+
    828 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
    \n+
    829
    \n+
    830 AggregatesMapIterator amap = aggregatesMaps_.rbegin();
    \n+
    831 InfoIterator info = parallelInformation_.coarsest();
    \n+
    832 for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level != finest; --level, --info, ++amap) {
    \n+
    833 (*amap)->free();
    \n+
    834 delete *amap;
    \n+
    835 }
    \n+
    836 delete *amap;
    \n+
    837 }
    \n+
    838
    \n+
    839 template<class M, class IS, class A>
    \n+
    840 template<class V, class BA, class TA>
    \n+\n+
    842 {
    \n+
    843 assert(hierarchy.levels()==1);
    \n+
    844 typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;
    \n+
    845 typedef typename RedistributeInfoList::const_iterator RIter;
    \n+
    846 RIter redist = redistributes_.begin();
    \n+
    847
    \n+
    848 Iterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();
    \n+
    849 int level=0;
    \n+
    850 if(redist->isSetup())
    \n+
    851 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N());
    \n+
    852 Dune::dvverb<<"Level "<<level<<" has "<<matrices_.finest()->getmat().N()<<" unknowns!"<<std::endl;
    \n+
    853
    \n+
    854 while(matrix != coarsest) {
    \n+
    855 ++matrix; ++level; ++redist;
    \n+
    856 Dune::dvverb<<"Level "<<level<<" has "<<matrix->getmat().N()<<" unknowns!"<<std::endl;
    \n+
    857
    \n+
    858 hierarchy.addCoarser(matrix->getmat().N());
    \n+
    859 if(redist->isSetup())
    \n+
    860 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N());
    \n+
    861
    \n+
    862 }
    \n+
    863
    \n+
    864 }
    \n+
    865
    \n+
    866 template<class M, class IS, class A>
    \n+
    867 template<class S, class TA>
    \n+\n+
    869 const typename SmootherTraits<S>::Arguments& sargs) const
    \n+
    870 {
    \n+
    871 assert(smoothers.levels()==0);
    \n+
    872 typedef typename ParallelMatrixHierarchy::ConstIterator MatrixIterator;
    \n+
    873 typedef typename ParallelInformationHierarchy::ConstIterator PinfoIterator;
    \n+
    874 typedef typename AggregatesMapList::const_iterator AggregatesIterator;
    \n+
    875
    \n+\n+
    877 cargs.setArgs(sargs);
    \n+
    878 PinfoIterator pinfo = parallelInformation_.finest();
    \n+
    879 AggregatesIterator aggregates = aggregatesMaps_.begin();
    \n+
    880 int level=0;
    \n+
    881 for(MatrixIterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();
    \n+
    882 matrix != coarsest; ++matrix, ++pinfo, ++aggregates, ++level) {
    \n+
    883 cargs.setMatrix(matrix->getmat(), **aggregates);
    \n+
    884 cargs.setComm(*pinfo);
    \n+
    885 smoothers.addCoarser(cargs);
    \n+
    886 }
    \n+
    887 if(maxlevels()>levels()) {
    \n+
    888 // This is not the globally coarsest level and therefore smoothing is needed
    \n+
    889 cargs.setMatrix(matrices_.coarsest()->getmat(), **aggregates);
    \n+
    890 cargs.setComm(*pinfo);
    \n+
    891 smoothers.addCoarser(cargs);
    \n+
    892 ++level;
    \n+
    893 }
    \n+
    894 }
    \n+
    895
    \n+
    896 template<class M, class IS, class A>
    \n+
    897 template<class F>
    \n+\n+
    899 {
    \n+
    900 typedef typename AggregatesMapList::iterator AggregatesMapIterator;
    \n+
    901 typedef typename ParallelMatrixHierarchy::Iterator Iterator;
    \n+
    902 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
    \n+
    903
    \n+
    904 AggregatesMapIterator amap = aggregatesMaps_.begin();
    \n+
    905 BaseGalerkinProduct productBuilder;
    \n+
    906 InfoIterator info = parallelInformation_.finest();
    \n+
    907 typename RedistributeInfoList::iterator riIter = redistributes_.begin();
    \n+
    908 Iterator level = matrices_.finest(), coarsest=matrices_.coarsest();
    \n+
    909 if(level.isRedistributed()) {
    \n+
    910 info->buildGlobalLookup(level->getmat().N());
    \n+
    911 redistributeMatrixEntries(const_cast<Matrix&>(level->getmat()),
    \n+
    912 const_cast<Matrix&>(level.getRedistributed().getmat()),
    \n+
    913 *info,info.getRedistributed(), *riIter);
    \n+
    914 info->freeGlobalLookup();
    \n+
    915 }
    \n+
    916
    \n+
    917 for(; level!=coarsest; ++amap) {
    \n+
    918 const Matrix& fine = (level.isRedistributed() ? level.getRedistributed() : *level).getmat();
    \n+
    919 ++level;
    \n+
    920 ++info;
    \n+
    921 ++riIter;
    \n+
    922 productBuilder.calculate(fine, *(*amap), const_cast<Matrix&>(level->getmat()), *info, copyFlags);
    \n+
    923 if(level.isRedistributed()) {
    \n+
    924 info->buildGlobalLookup(level->getmat().N());
    \n+
    925 redistributeMatrixEntries(const_cast<Matrix&>(level->getmat()),
    \n+
    926 const_cast<Matrix&>(level.getRedistributed().getmat()), *info,
    \n+
    927 info.getRedistributed(), *riIter);
    \n+
    928 info->freeGlobalLookup();
    \n+
    929 }
    \n+
    930 }
    \n+
    931 }
    \n+
    932
    \n+
    933 template<class M, class IS, class A>
    \n+\n+
    935 {
    \n+
    936 return matrices_.levels();
    \n+
    937 }
    \n+
    938
    \n+
    939 template<class M, class IS, class A>
    \n+\n+
    941 {
    \n+
    942 return maxlevels_;
    \n+
    943 }
    \n+
    944
    \n+
    945 template<class M, class IS, class A>
    \n+\n+
    947 {
    \n+
    948 return levels()==maxlevels() &&
    \n+
    949 (!matrices_.coarsest().isRedistributed() ||matrices_.coarsest()->getmat().N()>0);
    \n+
    950 }
    \n+
    951
    \n+
    952 template<class M, class IS, class A>
    \n+\n+
    954 {
    \n+
    955 return built_;
    \n+
    956 }
    \n+
    957
    \n+
    959 } // namespace Amg
    \n+
    960} // namespace Dune
    \n+
    961
    \n+
    962#endif // end DUNE_AMG_MATRIXHIERARCHY_HH
    \n+
    Some handy generic functions for ISTL matrices.
    \n+
    Functionality for redistributing a sparse matrix.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+
    Provides classes for the Coloring process of AMG.
    \n+
    Provides classes for building the matrix graph.
    \n+
    Provides a classes representing the hierarchies in AMG.
    \n+
    Provides classes for initializing the link attributes of a matrix graph.
    \n+
    Prolongation and restriction for amg.
    \n+
    Provides a class for building the index set and remote indices on the coarse level.
    \n+\n+\n+
    Helper classes for the construction of classes without empty constructor.
    \n+
    Classes for the generic construction and application of the smoothers.
    \n+
    Provides a class for building the galerkin product based on a aggregation scheme.
    \n+
    Provdes class for identifying aggregates globally.
    \n+
    auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
    Get the number of nonzero fields in the matrix.
    Definition: matrixutils.hh:119
    \n+
    const AggregatesMapList & aggregatesMaps() const
    Get the hierarchy of the mappings of the nodes onto aggregates.
    Definition: matrixhierarchy.hh:812
    \n+
    bool isBuilt() const
    Whether the hierarchy was built.
    Definition: matrixhierarchy.hh:953
    \n+
    bool hasCoarsest() const
    Definition: matrixhierarchy.hh:946
    \n+
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: hierarchy.hh:322
    \n+
    std::size_t levels() const
    Get the number of levels in the hierarchy.
    Definition: matrixhierarchy.hh:934
    \n+
    void addCoarser(Arguments &args)
    Add an element on a coarser level.
    Definition: hierarchy.hh:334
    \n+
    const RedistributeInfoList & redistributeInformation() const
    Get the hierarchy of the information about redistributions,.
    Definition: matrixhierarchy.hh:818
    \n+
    const ParallelInformationHierarchy & parallelInformation() const
    Get the hierarchy of the parallel data distribution information.
    Definition: matrixhierarchy.hh:737
    \n+
    bool repartitionAndDistributeMatrix(const M &origMatrix, std::shared_ptr< M > newMatrix, SequentialInformation &origComm, std::shared_ptr< SequentialInformation > &newComm, RedistributeInformation< SequentialInformation > &ri, int nparts, C1 &criterion)
    Definition: matrixhierarchy.hh:313
    \n+
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n+
    const ParallelMatrixHierarchy & matrices() const
    Get the matrix hierarchy.
    Definition: matrixhierarchy.hh:730
    \n+
    std::size_t maxlevels() const
    Get the max number of levels in the hierarchy of processors.
    Definition: matrixhierarchy.hh:940
    \n+
    const_iterator end() const
    Definition: aggregates.hh:730
    \n+
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n+
    void recalculateGalerkin(const F &copyFlags)
    Recalculate the galerkin products.
    Definition: matrixhierarchy.hh:898
    \n+
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n+
    std::size_t noVertices() const
    Get the number of vertices.
    \n+
    void coarsenVector(Hierarchy< BlockVector< V, BA >, TA > &hierarchy) const
    Coarsen the vector hierarchy according to the matrix hierarchy.
    Definition: matrixhierarchy.hh:841
    \n+
    const AggregateDescriptor * const_iterator
    Definition: aggregates.hh:723
    \n+
    MatrixHierarchy(std::shared_ptr< MatrixOperator > fineMatrix, std::shared_ptr< ParallelInformation > pinfo=std::make_shared< ParallelInformation >())
    Constructor.
    Definition: matrixhierarchy.hh:389
    \n+
    AccumulationMode
    Identifiers for the different accumulation modes.
    Definition: parameters.hh:232
    \n+
    void build(const T &criterion)
    Build the matrix hierarchy using aggregation.
    Definition: matrixhierarchy.hh:400
    \n+
    void free()
    Free the allocated memory.
    \n+
    void coarsenSmoother(Hierarchy< S, TA > &smoothers, const typename SmootherTraits< S >::Arguments &args) const
    Coarsen the smoother hierarchy according to the matrix hierarchy.
    Definition: matrixhierarchy.hh:868
    \n+
    void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
    Build the dependency of the matrix graph.
    \n+
    std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph, const C &criterion, bool finestLevel)
    Build the aggregates.
    \n+
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n+
    void getCoarsestAggregatesOnFinest(std::vector< std::size_t > &data) const
    Get the mapping of fine level unknowns to coarse level aggregates.
    Definition: matrixhierarchy.hh:743
    \n+
    ~MatrixHierarchy()
    Definition: matrixhierarchy.hh:824
    \n+
    @ MAX_PROCESSES
    Hard limit for the number of processes allowed.
    Definition: matrixhierarchy.hh:50
    \n+
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n+
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n
    Definition: allocator.hh:11
    \n+
    void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)
    Definition: matrixutils.hh:154
    \n
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Definition: matrixredistribute.hh:757
    \n+
    bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    Definition: repartition.hh:829
    \n+
    void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm, RedistributeInformation< C > &ri)
    Redistribute a matrix according to given domain decompositions.
    Definition: matrixredistribute.hh:820
    \n+
    bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)
    execute a graph repartition for a giving graph and indexset.
    Definition: repartition.hh:1235
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n+
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n+
    Definition: matrixredistribute.hh:22
    \n+
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n+
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n-
    Definition: dependency.hh:220
    \n+
    Definition: galerkin.hh:99
    \n+
    Definition: galerkin.hh:118
    \n+
    Definition: globalaggregates.hh:131
    \n+\n
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n+
    Graph::VertexDescriptor VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:988
    \n+
    Definition: graphcreator.hh:22
    \n+\n+
    LevelIterator< Hierarchy< MatrixOperator, Allocator >, MatrixOperator > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n+
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n+
    Definition: indicescoarsener.hh:36
    \n+
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n+
    typename std::allocator_traits< Allocator >::template rebind_alloc< AggregatesMap * > AAllocator
    Allocator for pointers.
    Definition: matrixhierarchy.hh:85
    \n+
    Dune::Amg::Hierarchy< ParallelInformation, Allocator > ParallelInformationHierarchy
    The type of the parallel informarion hierarchy.
    Definition: matrixhierarchy.hh:82
    \n+
    std::list< AggregatesMap *, AAllocator > AggregatesMapList
    The type of the aggregates maps list.
    Definition: matrixhierarchy.hh:88
    \n+
    PI ParallelInformation
    The type of the index set.
    Definition: matrixhierarchy.hh:70
    \n+
    Dune::Amg::Hierarchy< MatrixOperator, Allocator > ParallelMatrixHierarchy
    The type of the parallel matrix hierarchy.
    Definition: matrixhierarchy.hh:79
    \n+
    A Allocator
    The allocator to use.
    Definition: matrixhierarchy.hh:73
    \n+
    RedistributeInformation< ParallelInformation > RedistributeInfoType
    The type of the redistribute information.
    Definition: matrixhierarchy.hh:91
    \n+
    double getProlongationDampingFactor() const
    Definition: matrixhierarchy.hh:188
    \n+
    typename std::allocator_traits< Allocator >::template rebind_alloc< RedistributeInfoType > RILAllocator
    Allocator for RedistributeInfoType.
    Definition: matrixhierarchy.hh:94
    \n+
    std::list< RedistributeInfoType, RILAllocator > RedistributeInfoList
    The type of the list of redistribute information.
    Definition: matrixhierarchy.hh:97
    \n+
    Dune::Amg::AggregatesMap< typename MatrixGraph< Matrix >::VertexDescriptor > AggregatesMap
    The type of the aggregates map we use.
    Definition: matrixhierarchy.hh:76
    \n+
    MatrixOperator::matrix_type Matrix
    The type of the matrix.
    Definition: matrixhierarchy.hh:67
    \n+
    M MatrixOperator
    The type of the matrix operator.
    Definition: matrixhierarchy.hh:64
    \n+
    void operator()(const matrix_row &row)
    Definition: matrixhierarchy.hh:254
    \n+
    Matrix::row_type matrix_row
    Definition: matrixhierarchy.hh:245
    \n+
    size_type min
    Definition: matrixhierarchy.hh:261
    \n+\n+
    size_type max
    Definition: matrixhierarchy.hh:262
    \n+
    size_type sum
    Definition: matrixhierarchy.hh:263
    \n+
    Matrix::size_type size_type
    Definition: matrixhierarchy.hh:244
    \n+
    The criterion describing the stop criteria for the coarsening process.
    Definition: matrixhierarchy.hh:283
    \n+
    CoarsenCriterion(const Dune::Amg::Parameters &parms)
    Definition: matrixhierarchy.hh:306
    \n+
    T AggregationCriterion
    The criterion for tagging connections as strong and nodes as isolated. This might be e....
    Definition: matrixhierarchy.hh:289
    \n+
    CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: matrixhierarchy.hh:301
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Definition: pinfo.hh:28
    \n
    Tag idnetifying the visited property of a vertex.
    Definition: properties.hh:29
    \n+
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n+
    Definition: transfer.hh:32
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -5,576 +5,1282 @@\n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n * paamg\n-dependency.hh\n+matrixhierarchy.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_AMG_DEPENDENCY_HH\n- 6#define DUNE_AMG_DEPENDENCY_HH\n+ 5#ifndef DUNE_AMG_MATRIXHIERARCHY_HH\n+ 6#define DUNE_AMG_MATRIXHIERARCHY_HH\n 7\n- 8\n- 9#include \n- 10#include \n- 11\n- 12#include \"graph.hh\"\n- 13#include \"properties.hh\"\n- 14#include \n- 15\n- 16\n- 17namespace Dune\n- 18{\n- 19 namespace Amg\n- 20 {\n-38 class EdgeProperties\n- 39 {\n- 40 friend std::ostream& operator<<(std::ostream& os, const EdgeProperties&\n-props);\n- 41 public:\n-43 enum {INFLUENCE, DEPEND, SIZE};\n- 44\n- 45 private:\n- 46\n- 47 std::bitset flags_;\n- 48 public:\n- 50 EdgeProperties();\n- 51\n- 53 std::bitset::reference operator[](std::size_t v);\n- 54\n- 56 bool operator[](std::size_t v) const;\n- 57\n- 63 bool depends() const;\n- 64\n- 69 void setDepends();\n- 70\n- 74 void resetDepends();\n- 75\n- 80 bool influences() const;\n- 81\n- 85 void setInfluences();\n+ 8#include \n+ 9#include \n+ 10#include \"aggregates.hh\"\n+ 11#include \"graph.hh\"\n+ 12#include \"galerkin.hh\"\n+ 13#include \"renumberer.hh\"\n+ 14#include \"graphcreator.hh\"\n+ 15#include \"hierarchy.hh\"\n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23#include \n+ 24#include \n+ 25#include \n+ 26#include \n+ 27\n+ 28namespace Dune\n+ 29{\n+ 30 namespace Amg\n+ 31 {\n+ 42 enum {\n+ 50 MAX_PROCESSES = 72000\n+51 };\n+ 52\n+ 59 template >\n+60 class MatrixHierarchy\n+ 61 {\n+ 62 public:\n+64 typedef M MatrixOperator;\n+ 65\n+67 typedef typename MatrixOperator::matrix_type Matrix;\n+ 68\n+70 typedef PI ParallelInformation;\n+ 71\n+73 typedef A Allocator;\n+ 74\n+76 typedef Dune::Amg::AggregatesMap::\n+VertexDescriptor> AggregatesMap;\n+ 77\n+79 typedef Dune::Amg::Hierarchy\n+ParallelMatrixHierarchy;\n+ 80\n+82 typedef Dune::Amg::Hierarchy\n+ParallelInformationHierarchy;\n+ 83\n+85 using AAllocator = typename std::allocator_traits::template\n+rebind_alloc;\n 86\n- 90 void resetInfluences();\n- 91\n- 96 bool isOneWay() const;\n- 97\n- 102 bool isTwoWay() const;\n- 103\n- 108 bool isStrong() const;\n- 109\n- 113 void reset();\n- 114\n-118 void printFlags() const;\n- 119 };\n- 120\n-126 class VertexProperties {\n- 127 friend std::ostream& operator<<(std::ostream& os, const VertexProperties&\n-props);\n- 128 public:\n-129 enum { ISOLATED, VISITED, FRONT, BORDER, SIZE };\n- 130 private:\n- 131\n- 133 std::bitset flags_;\n- 134\n- 135 public:\n- 137 VertexProperties();\n- 138\n- 140 std::bitset::reference operator[](std::size_t v);\n- 141\n- 143 bool operator[](std::size_t v) const;\n- 144\n- 151 void setIsolated();\n- 152\n- 156 bool isolated() const;\n- 157\n- 161 void resetIsolated();\n+88 typedef std::list AggregatesMapList;\n+ 89\n+91 typedef RedistributeInformation RedistributeInfoType;\n+ 92\n+94 using RILAllocator = typename std::allocator_traits::template\n+rebind_alloc;\n+ 95\n+97 typedef std::list RedistributeInfoList;\n+ 98\n+ 104 MatrixHierarchy(std::shared_ptr fineMatrix,\n+ 105 std::shared_ptr pinfo = std::\n+make_shared());\n+ 106\n+ 107 ~MatrixHierarchy();\n+ 108\n+ 114 template\n+ 115 void build(const T& criterion);\n+ 116\n+ 124 template\n+ 125 void recalculateGalerkin(const F& copyFlags);\n+ 126\n+ 131 template\n+ 132 void coarsenVector(Hierarchy, TA>& hierarchy) const;\n+ 133\n+ 139 template\n+ 140 void coarsenSmoother(Hierarchy& smoothers,\n+ 141 const typename SmootherTraits::Arguments& args) const;\n+ 142\n+ 147 std::size_t levels() const;\n+ 148\n+ 153 std::size_t maxlevels() const;\n+ 154\n+ 155 bool hasCoarsest() const;\n+ 156\n+ 161 bool isBuilt() const;\n 162\n- 166 void setVisited();\n- 167\n- 171 bool visited() const;\n- 172\n- 176 void resetVisited();\n- 177\n- 181 void setFront();\n- 182\n- 186 bool front() const;\n+ 167 const ParallelMatrixHierarchy& matrices() const;\n+ 168\n+ 173 const ParallelInformationHierarchy& parallelInformation() const;\n+ 174\n+ 179 const AggregatesMapList& aggregatesMaps() const;\n+ 180\n+ 186 const RedistributeInfoList& redistributeInformation() const;\n 187\n- 191 void resetFront();\n+188 double getProlongationDampingFactor() const\n+ 189 {\n+ 190 return prolongDamp_;\n+ 191 }\n 192\n- 196 void setExcludedBorder();\n- 197\n- 202 bool excludedBorder() const;\n- 203\n- 207 void resetExcludedBorder();\n- 208\n- 212 void reset();\n- 213\n- 214 };\n- 215\n- 216 template\n-217 class PropertyGraphVertexPropertyMap\n- 218 : public RAPropertyMapHelper::reference,\n- 219 PropertyGraphVertexPropertyMap >\n- 220 {\n- 221 public:\n+ 203 void getCoarsestAggregatesOnFinest(std::vector& data) const;\n+ 204\n+ 205 private:\n+ 206 typedef typename ConstructionTraits::Arguments MatrixArgs;\n+ 207 typedef typename ConstructionTraits::Arguments\n+CommunicationArgs;\n+ 209 AggregatesMapList aggregatesMaps_;\n+ 211 RedistributeInfoList redistributes_;\n+ 213 ParallelMatrixHierarchy matrices_;\n+ 215 ParallelInformationHierarchy parallelInformation_;\n+ 216\n+ 218 bool built_;\n+ 219\n+ 221 int maxlevels_;\n 222\n-223 typedef ReadWritePropertyMapTag Category;\n+ 223 double prolongDamp_;\n 224\n- 225 enum {\n- 227 index = i\n-228 };\n- 229\n-233 typedef G Graph;\n- 234\n-238 typedef std::bitset BitSet;\n- 239\n-243 typedef typename BitSet::reference Reference;\n- 244\n-248 typedef bool ValueType;\n- 249\n-253 typedef typename G::VertexDescriptor Vertex;\n- 254\n-259 PropertyGraphVertexPropertyMap(G& g)\n- 260 : graph_(&g)\n- 261 {}\n- 262\n-266 PropertyGraphVertexPropertyMap()\n- 267 : graph_(0)\n- 268 {}\n- 269\n- 270\n-275 Reference operator[](const Vertex& vertex) const\n- 276 {\n- 277 return graph_->getVertexProperties(vertex)[index];\n- 278 }\n- 279 private:\n- 280 Graph* graph_;\n- 281 };\n- 282\n- 283 } // end namespace Amg\n- 284\n- 285 template\n-286 struct PropertyMapTypeSelector >\n- 287 {\n-288 typedef Amg::PropertyGraphVertexPropertyMap, Amg::VertexProperties::VISITED> Type;\n- 289 };\n+ 228 template\n+ 229 struct MatrixStats\n+ 230 {\n+ 231\n+ 235 static void stats([[maybe_unused]] const Matrix& matrix)\n+ 236 {}\n+ 237 };\n+ 238\n+ 239 template\n+ 240 struct MatrixStats\n+ 241 {\n+242 struct calc\n+ 243 {\n+244 typedef typename Matrix::size_type size_type;\n+245 typedef typename Matrix::row_type matrix_row;\n+ 246\n+247 calc()\n+ 248 {\n+ 249 min=std::numeric_limits::max();\n+ 250 max=0;\n+ 251 sum=0;\n+ 252 }\n+ 253\n+254 void operator()(const matrix_row& row)\n+ 255 {\n+ 256 min=std::min(min, row.size());\n+ 257 max=std::max(max, row.size());\n+ 258 sum += row.size();\n+ 259 }\n+ 260\n+261 size_type min;\n+262 size_type max;\n+263 size_type sum;\n+ 264 };\n+ 268 static void stats(const Matrix& matrix)\n+ 269 {\n+ 270 calc c= for_each(matrix.begin(), matrix.end(), calc());\n+ 271 dinfo<<\"Matrix row: min=\"<(c.sum)/matrix.N()\n+ 273 <\n+282 class CoarsenCriterion : public T\n+ 283 {\n+ 284 public:\n+289 typedef T AggregationCriterion;\n 290\n- 291 template\n- 292 typename PropertyMapTypeSelector >::Type\n-293 get([[maybe_unused]] const Amg::VertexVisitedTag& tag, Amg::\n-PropertiesGraph& graph)\n- 294 {\n- 295 return Amg::PropertyGraphVertexPropertyMap, Amg::VertexProperties::VISITED>(graph);\n- 296 }\n- 297\n- 298 namespace Amg\n- 299 {\n-300 inline std::ostream& operator<<(std::ostream& os, const EdgeProperties&\n-props)\n- 301 {\n- 302 return os << props.flags_;\n- 303 }\n- 304\n-305 inline EdgeProperties::EdgeProperties()\n- 306 : flags_()\n- 307 {}\n- 308\n- 309 inline std::bitset::reference\n-310 EdgeProperties::operator[](std::size_t v)\n- 311 {\n- 312 return flags_[v];\n- 313 }\n- 314\n-315 inline bool EdgeProperties::operator[](std::size_t i) const\n- 316 {\n- 317 return flags_[i];\n- 318 }\n- 319\n-320 inline void EdgeProperties::reset()\n- 321 {\n- 322 flags_.reset();\n- 323 }\n+301 CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double\n+minCoarsenRate=1.2,\n+ 302 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n+ 303 : AggregationCriterion(Dune::Amg::Parameters(maxLevel, coarsenTarget,\n+minCoarsenRate, prolongDamp, accumulate))\n+ 304 {}\n+ 305\n+306 CoarsenCriterion(const Dune::Amg::Parameters& parms)\n+ 307 : AggregationCriterion(parms)\n+ 308 {}\n+ 309\n+ 310 };\n+ 311\n+ 312 template\n+313 bool repartitionAndDistributeMatrix([[maybe_unused]] const M& origMatrix,\n+ 314 [[maybe_unused]] std::shared_ptr newMatrix,\n+ 315 [[maybe_unused]] SequentialInformation& origComm,\n+ 316 [[maybe_unused]] std::shared_ptr& newComm,\n+ 317 [[maybe_unused]] RedistributeInformation& ri,\n+ 318 [[maybe_unused]] int nparts,\n+ 319 [[maybe_unused]] C1& criterion)\n+ 320 {\n+ 321 DUNE_THROW(NotImplemented, \"Redistribution does not make sense in\n+sequential code!\");\n+ 322 }\n+ 323\n 324\n-325 inline void EdgeProperties::setInfluences()\n- 326 {\n- 327 // Set the INFLUENCE bit\n- 328 //flags_ |= (1<((1<\n+326 bool repartitionAndDistributeMatrix(const M& origMatrix,\n+ 327 std::shared_ptr newMatrix,\n+ 328 C& origComm,\n+ 329 std::shared_ptr& newComm,\n+ 330 RedistributeInformation& ri,\n+ 331 int nparts, C1& criterion)\n+ 332 {\n+ 333 Timer time;\n+ 334#ifdef AMG_REPART_ON_COMM_GRAPH\n+ 335 // Done not repartition the matrix graph, but a graph of the communication\n+scheme.\n+ 336 bool existentOnRedist=Dune::commGraphRepartition(origMatrix, origComm,\n+nparts, newComm,\n+ 337 ri.getInterface(),\n+ 338 criterion.debugLevel()>1);\n+ 339\n+ 340#else\n+ 341 typedef Dune::Amg::MatrixGraph MatrixGraph;\n+ 342 typedef Dune::Amg::PropertiesGraph PropertiesGraph;\n+ 347 MatrixGraph graph(origMatrix);\n+ 348 PropertiesGraph pgraph(graph);\n+ 349 buildDependency(pgraph, origMatrix, criterion, false);\n+ 350\n+ 351#ifdef DEBUG_REPART\n+ 352 if(origComm.communicator().rank()==0)\n+ 353 std::cout<<\"Original matrix\"<1);\n+ 360#endif // if else AMG_REPART\n+ 361\n+ 362 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)\n+ 363 std::cout<<\"Repartitioning took \"<indexSet(),\n+origComm.communicator());\n+ 369#endif\n 370\n-371 inline bool EdgeProperties::isTwoWay() const\n- 372 {\n- 373 // Test whether the first and second bit is set\n- 374 return ((flags_) & std::bitset((1<((1<::reference\n-395 VertexProperties::operator[](std::size_t v)\n- 396 {\n- 397 return flags_[v];\n- 398 }\n- 399\n-400 inline bool VertexProperties::operator[](std::size_t v) const\n+ 371 redistributeMatrix(const_cast(origMatrix), *newMatrix, origComm,\n+*newComm, ri);\n+ 372\n+ 373#ifdef DEBUG_REPART\n+ 374 if(origComm.communicator().rank()==0)\n+ 375 std::cout<<\"Original matrix\"<communicator().size()>0)\n+ 378 printGlobalSparseMatrix(*newMatrix, *newComm, std::cout);\n+ 379 origComm.communicator().barrier();\n+ 380#endif\n+ 381\n+ 382 if(origComm.communicator().rank()==0 && criterion.debugLevel()>1)\n+ 383 std::cout<<\"Redistributing matrix took \"<\n+389 MatrixHierarchy::MatrixHierarchy(std::shared_ptr\n+fineMatrix,\n+ 390 std::shared_ptr pinfo)\n+ 391 : matrices_(fineMatrix),\n+ 392 parallelInformation_(pinfo)\n+ 393 {\n+ 394 if (SolverCategory::category(*fineMatrix) != SolverCategory::category\n+(*pinfo))\n+ 395 DUNE_THROW(ISTLError, \"MatrixOperator and ParallelInformation must belong\n+to the same category!\");\n+ 396 }\n+ 397\n+ 398 template\n+ 399 template\n+400 void MatrixHierarchy::build(const T& criterion)\n 401 {\n- 402 return flags_[v];\n- 403 }\n- 404\n-405 inline void VertexProperties::setIsolated()\n- 406 {\n- 407 flags_.set(ISOLATED);\n- 408 }\n- 409\n-410 inline bool VertexProperties::isolated() const\n- 411 {\n- 412 return flags_.test(ISOLATED);\n- 413 }\n- 414\n-415 inline void VertexProperties::resetIsolated()\n- 416 {\n- 417 flags_.reset(ISOLATED);\n- 418 }\n+ 402 prolongDamp_ = criterion.getProlongationDampingFactor();\n+ 403 typedef O OverlapFlags;\n+ 404 typedef typename ParallelMatrixHierarchy::Iterator MatIterator;\n+ 405 typedef typename ParallelInformationHierarchy::Iterator PInfoIterator;\n+ 406\n+ 407 static const int noints=(Dune::Amg::MAX_PROCESSES/4096>0) ? (Dune::Amg::\n+MAX_PROCESSES/4096) : 1;\n+ 408\n+ 409 typedef bigunsignedint BIGINT;\n+ 410 GalerkinProduct productBuilder;\n+ 411 MatIterator mlevel = matrices_.finest();\n+ 412 MatrixStats::stats(mlevel->getmat());\n+ 413\n+ 414 PInfoIterator infoLevel = parallelInformation_.finest();\n+ 415 BIGINT finenonzeros=countNonZeros(mlevel->getmat());\n+ 416 finenonzeros = infoLevel->communicator().sum(finenonzeros);\n+ 417 BIGINT allnonzeros = finenonzeros;\n+ 418\n 419\n-420 inline void VertexProperties::setVisited()\n- 421 {\n- 422 flags_.set(VISITED);\n- 423 }\n+ 420 int level = 0;\n+ 421 int rank = 0;\n+ 422\n+ 423 BIGINT unknowns = mlevel->getmat().N();\n 424\n-425 inline bool VertexProperties::visited() const\n- 426 {\n- 427 return flags_.test(VISITED);\n- 428 }\n+ 425 unknowns = infoLevel->communicator().sum(unknowns);\n+ 426 double dunknowns=unknowns.todouble();\n+ 427 infoLevel->buildGlobalLookup(mlevel->getmat().N());\n+ 428 redistributes_.push_back(RedistributeInfoType());\n 429\n-430 inline void VertexProperties::resetVisited()\n- 431 {\n- 432 flags_.reset(VISITED);\n- 433 }\n- 434\n-435 inline void VertexProperties::setFront()\n- 436 {\n- 437 flags_.set(FRONT);\n- 438 }\n+ 430 for(; level < criterion.maxLevel(); ++level, ++mlevel) {\n+ 431 assert(matrices_.levels()==redistributes_.size());\n+ 432 rank = infoLevel->communicator().rank();\n+ 433 if(rank==0 && criterion.debugLevel()>1)\n+ 434 std::cout<<\"Level \"<communicator().size()\n+ 435 <<\" unknowns per proc (procs=\"<communicator().size\n+()<<\")\"<communicator().size()))\n+ 448 && infoLevel->communicator().size()>1 &&\n+ 449 dunknowns/infoLevel->communicator().size() <= criterion.coarsenTarget())\n+ 450 {\n+ 451 // accumulate to fewer processors\n+ 452 std::shared_ptr redistMat = std::make_shared();\n+ 453 std::shared_ptr redistComm;\n+ 454 std::size_t nodomains = (std::size_t)std::ceil(dunknowns/\n+(criterion.minAggregateSize()\n+ 455 *criterion.coarsenTarget()));\n+ 456 if( nodomains<=criterion.minAggregateSize()/2 ||\n+ 457 dunknowns <= criterion.coarsenTarget() )\n+ 458 nodomains=1;\n 459\n-460 inline void VertexProperties::resetExcludedBorder()\n- 461 {\n- 462 flags_.reset(BORDER);\n- 463 }\n- 464\n-465 inline void VertexProperties::reset()\n- 466 {\n- 467 flags_.reset();\n- 468 }\n- 469\n- 471 }\n- 472}\n- 473#endif\n+ 460 bool existentOnNextLevel =\n+ 461 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,\n+ 462 redistComm, redistributes_.back(), nodomains,\n+ 463 criterion);\n+ 464 BIGINT unknownsRedist = redistMat->N();\n+ 465 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);\n+ 466 dunknowns= unknownsRedist.todouble();\n+ 467 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1)\n+ 468 std::cout<<\"Level \"<communicator().size()\n+ 469 <<\" unknowns per proc (procs=\"<communicator().size\n+()<<\")\"<::construct\n+(args));\n+ 472 assert(mlevel.isRedistributed());\n+ 473 infoLevel.addRedistributed(redistComm);\n+ 474 infoLevel->freeGlobalLookup();\n+ 475\n+ 476 if(!existentOnNextLevel)\n+ 477 // We do not hold any data on the redistributed partitioning\n+ 478 break;\n+ 479\n+ 480 // Work on the redistributed Matrix from now on\n+ 481 matrix = &(mlevel.getRedistributed());\n+ 482 info = &(infoLevel.getRedistributed());\n+ 483 info->buildGlobalLookup(matrix->getmat().N());\n+ 484 }\n+ 485\n+ 486 rank = info->communicator().rank();\n+ 487 if(dunknowns <= criterion.coarsenTarget())\n+ 488 // No further coarsening needed\n+ 489 break;\n+ 490\n+ 491 typedef PropertiesGraphCreator\n+GraphCreator;\n+ 492 typedef typename GraphCreator::PropertiesGraph PropertiesGraph;\n+ 493 typedef typename GraphCreator::GraphTuple GraphTuple;\n+ 494\n+ 495 typedef typename PropertiesGraph::VertexDescriptor Vertex;\n+ 496\n+ 497 std::vector excluded(matrix->getmat().N(), false);\n+ 498\n+ 499 GraphTuple graphs = GraphCreator::create(*matrix, excluded, *info,\n+OverlapFlags());\n+ 500\n+ 501 AggregatesMap* aggregatesMap=new AggregatesMap(std::get<1>(graphs)-\n+>maxVertex()+1);\n+ 502\n+ 503 aggregatesMaps_.push_back(aggregatesMap);\n+ 504\n+ 505 Timer watch;\n+ 506 watch.reset();\n+ 507 auto [noAggregates, isoAggregates, oneAggregates, skippedAggregates] =\n+ 508 aggregatesMap->buildAggregates(matrix->getmat(), *(std::get<1>(graphs)),\n+criterion, level==0);\n+ 509\n+ 510 if(rank==0 && criterion.debugLevel()>2)\n+ 511 std::cout<<\" Have built \"<communicator().rank();\n+ 519 int n = UNKNOWNS/procs; // number of unknowns per process\n+ 520 int bigger = UNKNOWNS%procs; // number of process with n+1 unknows\n+ 521\n+ 522 // Compute owner region\n+ 523 if(rank0)\n+ 533 overlapStart = start - 1;\n+ 534 else\n+ 535 overlapStart = start;\n+ 536\n+ 537 if(endnoVertices());\n+ 543 for(int j=0; j< UNKNOWNS; ++j)\n+ 544 for(int i=0; i < UNKNOWNS; ++i)\n+ 545 {\n+ 546 if(i>=overlapStart && i1 && info->communicator().rank()==0)\n+ 555 std::cout<<\"aggregating finished.\"<communicator().sum(gnoAggregates);\n+ 559 double dgnoAggregates = gnoAggregates.todouble();\n+ 560#ifdef TEST_AGGLO\n+ 561 BIGINT gnoAggregates=((UNKNOWNS)/2)*((UNKNOWNS)/2);\n+ 562#endif\n+ 563\n+ 564 if(criterion.debugLevel()>2 && rank==0)\n+ 565 std::cout << \"Building \"<0)\n+ 572 std::cerr << \"Stopped coarsening because of rate breakdown\n+\"<free();\n+ 579 delete aggregatesMap;\n+ 580 aggregatesMaps_.pop_back();\n+ 581\n+ 582 if(criterion.accumulate() && mlevel.isRedistributed() && info-\n+>communicator().size()>1) {\n+ 583 // coarse level matrix was already redistributed, but to more than 1\n+process\n+ 584 // Therefore need to delete the redistribution. Further down it will\n+ 585 // then be redistributed to 1 process\n+ 586 delete &(mlevel.getRedistributed().getmat());\n+ 587 mlevel.deleteRedistributed();\n+ 588 delete &(infoLevel.getRedistributed());\n+ 589 infoLevel.deleteRedistributed();\n+ 590 redistributes_.back().resetSetup();\n+ 591 }\n+ 592\n+ 593 break;\n+ 594 }\n+ 595 unknowns = noAggregates;\n+ 596 dunknowns = dgnoAggregates;\n+ 597\n+ 598 CommunicationArgs commargs(info->communicator(),info->category());\n+ 599 parallelInformation_.addCoarser(commargs);\n+ 600\n+ 601 ++infoLevel; // parallel information on coarse level\n+ 602\n+ 603 typename PropertyMapTypeSelector::Type\n+visitedMap =\n+ 604 get(VertexVisitedTag(), *(std::get<1>(graphs)));\n+ 605\n+ 606 watch.reset();\n+ 607 int aggregates = IndicesCoarsener\n+ 608::coarsen(*info,\n+ 609 *(std::get<1>(graphs)),\n+ 610 visitedMap,\n+ 611 *aggregatesMap,\n+ 612 *infoLevel,\n+ 613 noAggregates);\n+ 614 GraphCreator::free(graphs);\n+ 615\n+ 616 if(criterion.debugLevel()>2) {\n+ 617 if(rank==0)\n+ 618 std::cout<<\"Coarsening of index sets took \"<buildGlobalLookup(aggregates);\n+ 624 AggregatesPublisher::publish\n+(*aggregatesMap,\n+ 625 *info,\n+ 626 infoLevel->globalLookup());\n+ 627\n+ 628\n+ 629 if(criterion.debugLevel()>2) {\n+ 630 if(rank==0)\n+ 631 std::cout<<\"Communicating global aggregate numbers took \"<& visited=excluded;\n+ 636\n+ 637 typedef std::vector::iterator Iterator;\n+ 638 typedef IteratorPropertyMap VisitedMap2;\n+ 639 Iterator end = visited.end();\n+ 640 for(Iterator iter= visited.begin(); iter != end; ++iter)\n+ 641 *iter=false;\n+ 642\n+ 643 VisitedMap2 visitedMap2(visited.begin(), Dune::IdentityMap());\n+ 644\n+ 645 std::shared_ptr\n+ 646 coarseMatrix(productBuilder.build(*(std::get<0>(graphs)), visitedMap2,\n+ 647 *info,\n+ 648 *aggregatesMap,\n+ 649 aggregates,\n+ 650 OverlapFlags()));\n+ 651 dverb<<\"Building of sparsity pattern took \"<freeGlobalLookup();\n+ 654\n+ 655 delete std::get<0>(graphs);\n+ 656 productBuilder.calculate(matrix->getmat(), *aggregatesMap, *coarseMatrix,\n+*infoLevel, OverlapFlags());\n+ 657\n+ 658 if(criterion.debugLevel()>2) {\n+ 659 if(rank==0)\n+ 660 std::cout<<\"Calculation entries of Galerkin product took \"<communicator().sum(nonzeros);\n+ 665 MatrixArgs args(coarseMatrix, *infoLevel);\n+ 666\n+ 667 matrices_.addCoarser(args);\n+ 668 redistributes_.push_back(RedistributeInfoType());\n+ 669 } // end level loop\n+ 670\n+ 671\n+ 672 infoLevel->freeGlobalLookup();\n+ 673\n+ 674 built_=true;\n+ 675 AggregatesMap* aggregatesMap=new AggregatesMap(0);\n+ 676 aggregatesMaps_.push_back(aggregatesMap);\n+ 677\n+ 678 if(criterion.debugLevel()>0) {\n+ 679 if(level==criterion.maxLevel()) {\n+ 680 BIGINT unknownsLevel = mlevel->getmat().N();\n+ 681 unknownsLevel = infoLevel->communicator().sum(unknownsLevel);\n+ 682 double dunknownsLevel = unknownsLevel.todouble();\n+ 683 if(rank==0 && criterion.debugLevel()>1) {\n+ 684 std::cout<<\"Level \"<communicator().size()\n+ 685 <<\" unknowns per proc (procs=\"<communicator().size\n+()<<\")\"<communicator().size()>1) {\n+ 692#if HAVE_MPI && !HAVE_PARMETIS\n+ 693 if(criterion.accumulate()==successiveAccu &&\n+ 694 infoLevel->communicator().rank()==0)\n+ 695 std::cerr<<\"Successive accumulation of data on coarse levels only works\n+with ParMETIS installed.\"\n+ 696 <<\" Fell back to accumulation to one domain on coarsest level\"< redistMat = std::make_shared();\n+ 701 std::shared_ptr redistComm;\n+ 702 int nodomains = 1;\n+ 703\n+ 704 repartitionAndDistributeMatrix(mlevel->getmat(), redistMat, *infoLevel,\n+ 705 redistComm, redistributes_.back(), nodomains,criterion);\n+ 706 MatrixArgs args(redistMat, *redistComm);\n+ 707 BIGINT unknownsRedist = redistMat->N();\n+ 708 unknownsRedist = infoLevel->communicator().sum(unknownsRedist);\n+ 709\n+ 710 if(redistComm->communicator().rank()==0 && criterion.debugLevel()>1) {\n+ 711 double dunknownsRedist = unknownsRedist.todouble();\n+ 712 std::cout<<\"Level \"<communicator().size()\n+ 713 <<\" unknowns per proc (procs=\"<communicator().size\n+()<<\")\"<::construct\n+(args));\n+ 716 infoLevel.addRedistributed(redistComm);\n+ 717 infoLevel->freeGlobalLookup();\n+ 718 }\n+ 719\n+ 720 int levels = matrices_.levels();\n+ 721 maxlevels_ = parallelInformation_.finest()->communicator().max(levels);\n+ 722 assert(matrices_.levels()==redistributes_.size());\n+ 723 if(hasCoarsest() && rank==0 && criterion.debugLevel()>1)\n+ 724 std::cout<<\"operator complexity: \"<\n+ 729 const typename MatrixHierarchy::ParallelMatrixHierarchy&\n+730 MatrixHierarchy::matrices() const\n+ 731 {\n+ 732 return matrices_;\n+ 733 }\n+ 734\n+ 735 template\n+ 736 const typename MatrixHierarchy::ParallelInformationHierarchy&\n+737 MatrixHierarchy::parallelInformation() const\n+ 738 {\n+ 739 return parallelInformation_;\n+ 740 }\n+ 741\n+ 742 template\n+743 void MatrixHierarchy::getCoarsestAggregatesOnFinest(std::\n+vector& data) const\n+ 744 {\n+ 745 int levels=aggregatesMaps().size();\n+ 746 int maxlevels=parallelInformation_.finest()->communicator().max(levels);\n+ 747 std::size_t size=(*(aggregatesMaps().begin()))->noVertices();\n+ 748 // We need an auxiliary vector for the consecutive prolongation.\n+ 749 std::vector tmp;\n+ 750 std::vector *coarse, *fine;\n+ 751\n+ 752 // make sure the allocated space suffices.\n+ 753 tmp.reserve(size);\n+ 754 data.reserve(size);\n+ 755\n+ 756 // Correctly assign coarse and fine for the first prolongation such that\n+ 757 // we end up in data in the end.\n+ 758 if(levels%2==0) {\n+ 759 coarse=&tmp;\n+ 760 fine=&data;\n+ 761 }else{\n+ 762 coarse=&data;\n+ 763 fine=&tmp;\n+ 764 }\n+ 765\n+ 766 // Number the unknowns on the coarsest level consecutively for each\n+process.\n+ 767 if(levels==maxlevels) {\n+ 768 const AggregatesMap& map = *(*(++aggregatesMaps().rbegin()));\n+ 769 std::size_t m=0;\n+ 770\n+ 771 for(typename AggregatesMap::const_iterator iter = map.begin(); iter !=\n+map.end(); ++iter)\n+ 772 if(*iter< AggregatesMap::ISOLATED)\n+ 773 m=std::max(*iter,m);\n+ 774\n+ 775 coarse->resize(m+1);\n+ 776 std::size_t i=0;\n+ 777 srand((unsigned)std::clock());\n+ 778 std::set used;\n+ 779 for(typename std::vector::iterator iter=coarse->begin(); iter\n+!= coarse->end();\n+ 780 ++iter, ++i)\n+ 781 {\n+ 782 std::pair::iterator,bool> ibpair\n+ 783 = used.insert(static_cast((((double)rand())/\n+(RAND_MAX+1.0)))*coarse->size());\n+ 784\n+ 785 while(!ibpair.second)\n+ 786 ibpair = used.insert(static_cast((((double)rand())/\n+(RAND_MAX+1.0))*coarse->size()));\n+ 787 *iter=*(ibpair.first);\n+ 788 }\n+ 789 }\n+ 790\n+ 791 typename ParallelInformationHierarchy::Iterator pinfo =\n+parallelInformation().coarsest();\n+ 792 --pinfo;\n+ 793\n+ 794 // Now consecutively project the numbers to the finest level.\n+ 795 for(typename AggregatesMapList::const_reverse_iterator\n+aggregates=++aggregatesMaps().rbegin();\n+ 796 aggregates != aggregatesMaps().rend(); ++aggregates,--levels) {\n+ 797\n+ 798 fine->resize((*aggregates)->noVertices());\n+ 799 fine->assign(fine->size(), 0);\n+ 800 Transfer, ParallelInformation>\n+ 801 ::prolongateVector(*(*aggregates), *coarse, *fine, static_cast(1), *pinfo);\n+ 802 --pinfo;\n+ 803 std::swap(coarse, fine);\n+ 804 }\n+ 805\n+ 806 // Assertion to check that we really projected to data on the last step.\n+ 807 assert(coarse==&data);\n+ 808 }\n+ 809\n+ 810 template\n+ 811 const typename MatrixHierarchy::AggregatesMapList&\n+812 MatrixHierarchy::aggregatesMaps() const\n+ 813 {\n+ 814 return aggregatesMaps_;\n+ 815 }\n+ 816 template\n+ 817 const typename MatrixHierarchy::RedistributeInfoList&\n+818 MatrixHierarchy::redistributeInformation() const\n+ 819 {\n+ 820 return redistributes_;\n+ 821 }\n+ 822\n+ 823 template\n+824 MatrixHierarchy::~MatrixHierarchy()\n+ 825 {\n+ 826 typedef typename AggregatesMapList::reverse_iterator\n+AggregatesMapIterator;\n+ 827 typedef typename ParallelMatrixHierarchy::Iterator Iterator;\n+ 828 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;\n+ 829\n+ 830 AggregatesMapIterator amap = aggregatesMaps_.rbegin();\n+ 831 InfoIterator info = parallelInformation_.coarsest();\n+ 832 for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level\n+!= finest; --level, --info, ++amap) {\n+ 833 (*amap)->free();\n+ 834 delete *amap;\n+ 835 }\n+ 836 delete *amap;\n+ 837 }\n+ 838\n+ 839 template\n+ 840 template\n+841 void MatrixHierarchy::coarsenVector(Hierarchy,\n+TA>& hierarchy) const\n+ 842 {\n+ 843 assert(hierarchy.levels()==1);\n+ 844 typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;\n+ 845 typedef typename RedistributeInfoList::const_iterator RIter;\n+ 846 RIter redist = redistributes_.begin();\n+ 847\n+ 848 Iterator matrix = matrices_.finest(), coarsest = matrices_.coarsest();\n+ 849 int level=0;\n+ 850 if(redist->isSetup())\n+ 851 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N\n+());\n+ 852 Dune::dvverb<<\"Level \"<getmat().N\n+()<<\" unknowns!\"<getmat().N()<<\"\n+unknowns!\"<getmat().N());\n+ 859 if(redist->isSetup())\n+ 860 hierarchy.addRedistributedOnCoarsest(matrix.getRedistributed().getmat().N\n+());\n+ 861\n+ 862 }\n+ 863\n+ 864 }\n+ 865\n+ 866 template\n+ 867 template\n+868 void MatrixHierarchy::coarsenSmoother(Hierarchy& smoothers,\n+ 869 const typename SmootherTraits::Arguments& sargs) const\n+ 870 {\n+ 871 assert(smoothers.levels()==0);\n+ 872 typedef typename ParallelMatrixHierarchy::ConstIterator MatrixIterator;\n+ 873 typedef typename ParallelInformationHierarchy::ConstIterator\n+PinfoIterator;\n+ 874 typedef typename AggregatesMapList::const_iterator AggregatesIterator;\n+ 875\n+ 876 typename ConstructionTraits::Arguments cargs;\n+ 877 cargs.setArgs(sargs);\n+ 878 PinfoIterator pinfo = parallelInformation_.finest();\n+ 879 AggregatesIterator aggregates = aggregatesMaps_.begin();\n+ 880 int level=0;\n+ 881 for(MatrixIterator matrix = matrices_.finest(), coarsest =\n+matrices_.coarsest();\n+ 882 matrix != coarsest; ++matrix, ++pinfo, ++aggregates, ++level) {\n+ 883 cargs.setMatrix(matrix->getmat(), **aggregates);\n+ 884 cargs.setComm(*pinfo);\n+ 885 smoothers.addCoarser(cargs);\n+ 886 }\n+ 887 if(maxlevels()>levels()) {\n+ 888 // This is not the globally coarsest level and therefore smoothing is\n+needed\n+ 889 cargs.setMatrix(matrices_.coarsest()->getmat(), **aggregates);\n+ 890 cargs.setComm(*pinfo);\n+ 891 smoothers.addCoarser(cargs);\n+ 892 ++level;\n+ 893 }\n+ 894 }\n+ 895\n+ 896 template\n+ 897 template\n+898 void MatrixHierarchy::recalculateGalerkin(const F& copyFlags)\n+ 899 {\n+ 900 typedef typename AggregatesMapList::iterator AggregatesMapIterator;\n+ 901 typedef typename ParallelMatrixHierarchy::Iterator Iterator;\n+ 902 typedef typename ParallelInformationHierarchy::Iterator InfoIterator;\n+ 903\n+ 904 AggregatesMapIterator amap = aggregatesMaps_.begin();\n+ 905 BaseGalerkinProduct productBuilder;\n+ 906 InfoIterator info = parallelInformation_.finest();\n+ 907 typename RedistributeInfoList::iterator riIter = redistributes_.begin();\n+ 908 Iterator level = matrices_.finest(), coarsest=matrices_.coarsest();\n+ 909 if(level.isRedistributed()) {\n+ 910 info->buildGlobalLookup(level->getmat().N());\n+ 911 redistributeMatrixEntries(const_cast(level->getmat()),\n+ 912 const_cast(level.getRedistributed().getmat()),\n+ 913 *info,info.getRedistributed(), *riIter);\n+ 914 info->freeGlobalLookup();\n+ 915 }\n+ 916\n+ 917 for(; level!=coarsest; ++amap) {\n+ 918 const Matrix& fine = (level.isRedistributed() ? level.getRedistributed() :\n+*level).getmat();\n+ 919 ++level;\n+ 920 ++info;\n+ 921 ++riIter;\n+ 922 productBuilder.calculate(fine, *(*amap), const_cast(level->getmat\n+()), *info, copyFlags);\n+ 923 if(level.isRedistributed()) {\n+ 924 info->buildGlobalLookup(level->getmat().N());\n+ 925 redistributeMatrixEntries(const_cast(level->getmat()),\n+ 926 const_cast(level.getRedistributed().getmat()), *info,\n+ 927 info.getRedistributed(), *riIter);\n+ 928 info->freeGlobalLookup();\n+ 929 }\n+ 930 }\n+ 931 }\n+ 932\n+ 933 template\n+934 std::size_t MatrixHierarchy::levels() const\n+ 935 {\n+ 936 return matrices_.levels();\n+ 937 }\n+ 938\n+ 939 template\n+940 std::size_t MatrixHierarchy::maxlevels() const\n+ 941 {\n+ 942 return maxlevels_;\n+ 943 }\n+ 944\n+ 945 template\n+946 bool MatrixHierarchy::hasCoarsest() const\n+ 947 {\n+ 948 return levels()==maxlevels() &&\n+ 949 (!matrices_.coarsest().isRedistributed() ||matrices_.coarsest()->getmat\n+().N()>0);\n+ 950 }\n+ 951\n+ 952 template\n+953 bool MatrixHierarchy::isBuilt() const\n+ 954 {\n+ 955 return built_;\n+ 956 }\n+ 957\n+ 959 } // namespace Amg\n+ 960} // namespace Dune\n+ 961\n+ 962#endif // end DUNE_AMG_MATRIXHIERARCHY_HH\n+matrixutils.hh\n+Some handy generic functions for ISTL matrices.\n+matrixredistribute.hh\n+Functionality for redistributing a sparse matrix.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+aggregates.hh\n+Provides classes for the Coloring process of AMG.\n graph.hh\n Provides classes for building the matrix graph.\n-properties.hh\n-Provides classes for handling internal properties in a graph.\n-Dune::Amg::EdgeProperties::depends\n-bool depends() const\n-Checks wether the vertex the edge points to depends on the vertex the edge\n-starts.\n-Definition: dependency.hh:352\n-Dune::Amg::VertexProperties::resetFront\n-void resetFront()\n-Resets the front node flag.\n-Definition: dependency.hh:445\n-Dune::Amg::PropertyGraphVertexPropertyMap::BitSet\n-std::bitset< VertexProperties::SIZE > BitSet\n-The type of the bitset.\n-Definition: dependency.hh:238\n-Dune::Amg::VertexProperties::isolated\n-bool isolated() const\n-Checks wether the node is isolated.\n-Definition: dependency.hh:410\n-Dune::Amg::PropertyGraphVertexPropertyMap::ValueType\n-bool ValueType\n-The value type.\n-Definition: dependency.hh:248\n-Dune::Amg::VertexProperties::operator<<\n-friend std::ostream & operator<<(std::ostream &os, const VertexProperties\n-&props)\n-Definition: dependency.hh:384\n-Dune::Amg::PropertyGraphVertexPropertyMap::Reference\n-BitSet::reference Reference\n-The reference type.\n-Definition: dependency.hh:243\n-Dune::Amg::EdgeProperties::isTwoWay\n-bool isTwoWay() const\n-Checks wether the edge is two way. I.e. both the influence flag and the depends\n-flag are that.\n-Definition: dependency.hh:371\n-Dune::Amg::EdgeProperties::setInfluences\n-void setInfluences()\n-Marks the edge as one of which the start vertex by the end vertex.\n-Definition: dependency.hh:325\n-Dune::Amg::VertexProperties::VertexProperties\n-VertexProperties()\n-Constructor.\n-Definition: dependency.hh:389\n-Dune::Amg::EdgeProperties::setDepends\n-void setDepends()\n-Marks the edge as one of which the end point depends on the starting point.\n-Definition: dependency.hh:338\n-Dune::Amg::PropertyGraphVertexPropertyMap::PropertyGraphVertexPropertyMap\n-PropertyGraphVertexPropertyMap()\n-Default constructor.\n-Definition: dependency.hh:266\n-Dune::Amg::PropertyGraphVertexPropertyMap::PropertyGraphVertexPropertyMap\n-PropertyGraphVertexPropertyMap(G &g)\n-Constructor.\n-Definition: dependency.hh:259\n-Dune::Amg::PropertyGraphVertexPropertyMap::Vertex\n-G::VertexDescriptor Vertex\n-The vertex descriptor.\n-Definition: dependency.hh:253\n-Dune::Amg::VertexProperties::resetExcludedBorder\n-void resetExcludedBorder()\n-Marks the vertex as included in the aggregation.\n-Definition: dependency.hh:460\n-Dune::Amg::VertexProperties::setFront\n-void setFront()\n-Marks the node as belonging to the current clusters front.\n-Definition: dependency.hh:435\n-Dune::Amg::VertexProperties::reset\n-void reset()\n-Reset all flags.\n-Definition: dependency.hh:465\n-Dune::Amg::VertexProperties::setVisited\n-void setVisited()\n-Mark the node as already visited.\n-Definition: dependency.hh:420\n-Dune::Amg::EdgeProperties::EdgeProperties\n-EdgeProperties()\n+hierarchy.hh\n+Provides a classes representing the hierarchies in AMG.\n+dependency.hh\n+Provides classes for initializing the link attributes of a matrix graph.\n+transfer.hh\n+Prolongation and restriction for amg.\n+indicescoarsener.hh\n+Provides a class for building the index set and remote indices on the coarse\n+level.\n+graphcreator.hh\n+renumberer.hh\n+construction.hh\n+Helper classes for the construction of classes without empty constructor.\n+smoother.hh\n+Classes for the generic construction and application of the smoothers.\n+galerkin.hh\n+Provides a class for building the galerkin product based on a aggregation\n+scheme.\n+globalaggregates.hh\n+Provdes class for identifying aggregates globally.\n+Dune::countNonZeros\n+auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::\n+value > *sfinae=nullptr)\n+Get the number of nonzero fields in the matrix.\n+Definition: matrixutils.hh:119\n+Dune::Amg::MatrixHierarchy::aggregatesMaps\n+const AggregatesMapList & aggregatesMaps() const\n+Get the hierarchy of the mappings of the nodes onto aggregates.\n+Definition: matrixhierarchy.hh:812\n+Dune::Amg::MatrixHierarchy::isBuilt\n+bool isBuilt() const\n+Whether the hierarchy was built.\n+Definition: matrixhierarchy.hh:953\n+Dune::Amg::MatrixHierarchy::hasCoarsest\n+bool hasCoarsest() const\n+Definition: matrixhierarchy.hh:946\n+Dune::Amg::Hierarchy::levels\n+std::size_t levels() const\n+Get the number of levels in the hierarchy.\n+Definition: hierarchy.hh:322\n+Dune::Amg::MatrixHierarchy::levels\n+std::size_t levels() const\n+Get the number of levels in the hierarchy.\n+Definition: matrixhierarchy.hh:934\n+Dune::Amg::Hierarchy::addCoarser\n+void addCoarser(Arguments &args)\n+Add an element on a coarser level.\n+Definition: hierarchy.hh:334\n+Dune::Amg::MatrixHierarchy::redistributeInformation\n+const RedistributeInfoList & redistributeInformation() const\n+Get the hierarchy of the information about redistributions,.\n+Definition: matrixhierarchy.hh:818\n+Dune::Amg::MatrixHierarchy::parallelInformation\n+const ParallelInformationHierarchy & parallelInformation() const\n+Get the hierarchy of the parallel data distribution information.\n+Definition: matrixhierarchy.hh:737\n+Dune::Amg::repartitionAndDistributeMatrix\n+bool repartitionAndDistributeMatrix(const M &origMatrix, std::shared_ptr< M >\n+newMatrix, SequentialInformation &origComm, std::shared_ptr<\n+SequentialInformation > &newComm, RedistributeInformation<\n+SequentialInformation > &ri, int nparts, C1 &criterion)\n+Definition: matrixhierarchy.hh:313\n+Dune::Amg::AggregatesMap::begin\n+const_iterator begin() const\n+Definition: aggregates.hh:725\n+Dune::Amg::MatrixHierarchy::matrices\n+const ParallelMatrixHierarchy & matrices() const\n+Get the matrix hierarchy.\n+Definition: matrixhierarchy.hh:730\n+Dune::Amg::MatrixHierarchy::maxlevels\n+std::size_t maxlevels() const\n+Get the max number of levels in the hierarchy of processors.\n+Definition: matrixhierarchy.hh:940\n+Dune::Amg::AggregatesMap::end\n+const_iterator end() const\n+Definition: aggregates.hh:730\n+Dune::Amg::AggregatesMap::ISOLATED\n+static const V ISOLATED\n+Identifier of isolated vertices.\n+Definition: aggregates.hh:571\n+Dune::Amg::MatrixHierarchy::recalculateGalerkin\n+void recalculateGalerkin(const F ©Flags)\n+Recalculate the galerkin products.\n+Definition: matrixhierarchy.hh:898\n+Dune::Amg::ConstructionTraits::Arguments\n+const void * Arguments\n+A type holding all the arguments needed to call the constructor.\n+Definition: construction.hh:44\n+Dune::Amg::AggregatesMap::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices.\n+Dune::Amg::MatrixHierarchy::coarsenVector\n+void coarsenVector(Hierarchy< BlockVector< V, BA >, TA > &hierarchy) const\n+Coarsen the vector hierarchy according to the matrix hierarchy.\n+Definition: matrixhierarchy.hh:841\n+Dune::Amg::AggregatesMap::const_iterator\n+const AggregateDescriptor * const_iterator\n+Definition: aggregates.hh:723\n+Dune::Amg::MatrixHierarchy::MatrixHierarchy\n+MatrixHierarchy(std::shared_ptr< MatrixOperator > fineMatrix, std::shared_ptr<\n+ParallelInformation > pinfo=std::make_shared< ParallelInformation >())\n Constructor.\n-Definition: dependency.hh:305\n-Dune::Amg::EdgeProperties::resetInfluences\n-void resetInfluences()\n-Resets the influence flag.\n-Definition: dependency.hh:358\n-Dune::Amg::PropertyGraphVertexPropertyMap::Graph\n-G Graph\n-The type of the graph with internal properties.\n-Definition: dependency.hh:233\n-Dune::Amg::VertexProperties::operator[]\n-std::bitset< SIZE >::reference operator[](std::size_t v)\n-Access the bits directly.\n-Definition: dependency.hh:395\n-Dune::Amg::EdgeProperties::printFlags\n-void printFlags() const\n-Prints the attributes of the edge for debugging.\n-Dune::Amg::EdgeProperties::operator<<\n-friend std::ostream & operator<<(std::ostream &os, const EdgeProperties &props)\n-Definition: dependency.hh:300\n-Dune::PropertyMapTypeSelector<_Amg::VertexVisitedTag,_Amg::PropertiesGraph<_G,\n-Amg::VertexProperties,_EP,_VM,_EM_>_>::Type\n-Amg::PropertyGraphVertexPropertyMap< Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM >, Amg::VertexProperties::VISITED > Type\n-Definition: dependency.hh:288\n-Dune::Amg::EdgeProperties::influences\n-bool influences() const\n-Checks wether the start vertex is influenced by the end vertex.\n-Definition: dependency.hh:332\n-Dune::Amg::VertexProperties::setIsolated\n-void setIsolated()\n-Marks that node as being isolated.\n-Definition: dependency.hh:405\n-Dune::Amg::VertexProperties::excludedBorder\n-bool excludedBorder() const\n-Tests whether the vertex is excluded from the aggregation.\n-Definition: dependency.hh:455\n-Dune::Amg::VertexProperties::resetVisited\n-void resetVisited()\n-Resets the visited flag.\n-Definition: dependency.hh:430\n-Dune::Amg::VertexProperties::visited\n-bool visited() const\n-Checks wether the node is marked as visited.\n-Definition: dependency.hh:425\n-Dune::Amg::PropertyGraphVertexPropertyMap::operator[]\n-Reference operator[](const Vertex &vertex) const\n-Get the properties associated to a vertex.\n-Definition: dependency.hh:275\n-Dune::Amg::EdgeProperties::reset\n-void reset()\n-Reset all flags.\n-Definition: dependency.hh:320\n-Dune::Amg::EdgeProperties::resetDepends\n-void resetDepends()\n-Resets the depends flag.\n-Definition: dependency.hh:345\n-Dune::Amg::PropertyGraphVertexPropertyMap::Category\n-ReadWritePropertyMapTag Category\n-Definition: dependency.hh:223\n-Dune::Amg::VertexProperties::resetIsolated\n-void resetIsolated()\n-Resets the isolated flag.\n-Definition: dependency.hh:415\n-Dune::Amg::operator<<\n-std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T >\n-&criterion)\n-Definition: aggregates.hh:113\n-Dune::Amg::EdgeProperties::isStrong\n-bool isStrong() const\n-Checks wether the edge is strong. I.e. the influence or depends flag is set.\n-Definition: dependency.hh:377\n-Dune::Amg::VertexProperties::front\n-bool front() const\n-Checks wether the node is marked as a front node.\n-Definition: dependency.hh:440\n-Dune::Amg::EdgeProperties::operator[]\n-std::bitset< SIZE >::reference operator[](std::size_t v)\n-Access the bits directly.\n-Definition: dependency.hh:310\n-Dune::Amg::VertexProperties::setExcludedBorder\n-void setExcludedBorder()\n-Marks the vertex as excluded from the aggregation.\n-Definition: dependency.hh:450\n-Dune::Amg::EdgeProperties::isOneWay\n-bool isOneWay() const\n-Checks wether the edge is one way. I.e. either the influence or the depends\n-flag but is set.\n-Definition: dependency.hh:364\n-Dune::Amg::PropertyGraphVertexPropertyMap::index\n-@ index\n-the index to access in the bitset.\n-Definition: dependency.hh:227\n-Dune::Amg::VertexProperties::VISITED\n-@ VISITED\n-Definition: dependency.hh:129\n-Dune::Amg::VertexProperties::ISOLATED\n-@ ISOLATED\n-Definition: dependency.hh:129\n-Dune::Amg::VertexProperties::SIZE\n-@ SIZE\n-Definition: dependency.hh:129\n-Dune::Amg::VertexProperties::BORDER\n-@ BORDER\n-Definition: dependency.hh:129\n-Dune::Amg::VertexProperties::FRONT\n-@ FRONT\n-Definition: dependency.hh:129\n-Dune::Amg::EdgeProperties::DEPEND\n-@ DEPEND\n-Definition: dependency.hh:43\n-Dune::Amg::EdgeProperties::SIZE\n-@ SIZE\n-Definition: dependency.hh:43\n-Dune::Amg::EdgeProperties::INFLUENCE\n-@ INFLUENCE\n-Definition: dependency.hh:43\n+Definition: matrixhierarchy.hh:389\n+Dune::Amg::AccumulationMode\n+AccumulationMode\n+Identifiers for the different accumulation modes.\n+Definition: parameters.hh:232\n+Dune::Amg::MatrixHierarchy::build\n+void build(const T &criterion)\n+Build the matrix hierarchy using aggregation.\n+Definition: matrixhierarchy.hh:400\n+Dune::Amg::AggregatesMap::free\n+void free()\n+Free the allocated memory.\n+Dune::Amg::MatrixHierarchy::coarsenSmoother\n+void coarsenSmoother(Hierarchy< S, TA > &smoothers, const typename\n+SmootherTraits< S >::Arguments &args) const\n+Coarsen the smoother hierarchy according to the matrix hierarchy.\n+Definition: matrixhierarchy.hh:868\n+Dune::Amg::buildDependency\n+void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion,\n+bool finestLevel)\n+Build the dependency of the matrix graph.\n+Dune::Amg::AggregatesMap::buildAggregates\n+std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph,\n+const C &criterion, bool finestLevel)\n+Build the aggregates.\n+Dune::Amg::BaseGalerkinProduct::calculate\n+void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n+const I &pinfo, const O ©)\n+Calculate the galerkin product.\n+Dune::Amg::MatrixHierarchy::getCoarsestAggregatesOnFinest\n+void getCoarsestAggregatesOnFinest(std::vector< std::size_t > &data) const\n+Get the mapping of fine level unknowns to coarse level aggregates.\n+Definition: matrixhierarchy.hh:743\n+Dune::Amg::MatrixHierarchy::~MatrixHierarchy\n+~MatrixHierarchy()\n+Definition: matrixhierarchy.hh:824\n+Dune::Amg::MAX_PROCESSES\n+@ MAX_PROCESSES\n+Hard limit for the number of processes allowed.\n+Definition: matrixhierarchy.hh:50\n+Dune::Amg::atOnceAccu\n+@ atOnceAccu\n+Accumulate data to one process at once.\n+Definition: parameters.hh:244\n+Dune::Amg::successiveAccu\n+@ successiveAccu\n+Successively accumulate to fewer processes.\n+Definition: parameters.hh:248\n Dune\n Definition: allocator.hh:11\n+Dune::printGlobalSparseMatrix\n+void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)\n+Definition: matrixutils.hh:154\n Dune::get\n PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n Definition: dependency.hh:293\n+Dune::redistributeMatrixEntries\n+void redistributeMatrixEntries(M &origMatrix, M &newMatrix, C &origComm, C\n+&newComm, RedistributeInformation< C > &ri)\n+Definition: matrixredistribute.hh:757\n+Dune::commGraphRepartition\n+bool commGraphRepartition(const M &mat, Dune::OwnerOverlapCopyCommunication<\n+T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n+&redistInf, bool verbose=false)\n+Definition: repartition.hh:829\n+Dune::redistributeMatrix\n+void redistributeMatrix(M &origMatrix, M &newMatrix, C &origComm, C &newComm,\n+RedistributeInformation< C > &ri)\n+Redistribute a matrix according to given domain decompositions.\n+Definition: matrixredistribute.hh:820\n+Dune::graphRepartition\n+bool graphRepartition(const G &graph, Dune::OwnerOverlapCopyCommunication< T1,\n+T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::\n+OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface\n+&redistInf, bool verbose=false)\n+execute a graph repartition for a giving graph and indexset.\n+Definition: repartition.hh:1235\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::size_type\n+A::size_type size_type\n+Type for indices and sizes.\n+Definition: matrix.hh:577\n+Dune::Matrix::row_type\n+MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n+The type implementing a matrix row.\n+Definition: matrix.hh:574\n+Dune::RedistributeInformation\n+Definition: matrixredistribute.hh:22\n+Dune::Amg::ConstructionTraits\n+Traits class for generically constructing non default constructable types.\n+Definition: construction.hh:39\n+Dune::Amg::AggregatesMap\n+Class providing information about the mapping of the vertices onto aggregates.\n+Definition: aggregates.hh:560\n Dune::Amg::EdgeProperties\n Class representing the properties of an ede in the matrix graph.\n Definition: dependency.hh:39\n Dune::Amg::VertexProperties\n Class representing a node in the matrix graph.\n Definition: dependency.hh:126\n-Dune::Amg::PropertyGraphVertexPropertyMap\n-Definition: dependency.hh:220\n+Dune::Amg::BaseGalerkinProduct\n+Definition: galerkin.hh:99\n+Dune::Amg::GalerkinProduct\n+Definition: galerkin.hh:118\n+Dune::Amg::AggregatesPublisher\n+Definition: globalaggregates.hh:131\n+Dune::Amg::MatrixGraph<_const_M_>\n Dune::Amg::PropertiesGraph\n Attaches properties to the edges and vertices of a graph.\n Definition: graph.hh:978\n+Dune::Amg::PropertiesGraph::VertexDescriptor\n+Graph::VertexDescriptor VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:988\n+Dune::Amg::PropertiesGraphCreator\n+Definition: graphcreator.hh:22\n+Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>\n+Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::Iterator\n+LevelIterator< Hierarchy< MatrixOperator, Allocator >, MatrixOperator >\n+Iterator\n+Type of the mutable iterator.\n+Definition: hierarchy.hh:216\n+Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n+LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n+MatrixOperator > ConstIterator\n+Type of the const iterator.\n+Definition: hierarchy.hh:219\n+Dune::Amg::IndicesCoarsener\n+Definition: indicescoarsener.hh:36\n+Dune::Amg::MatrixHierarchy\n+The hierarchies build by the coarsening process.\n+Definition: matrixhierarchy.hh:61\n+Dune::Amg::MatrixHierarchy::AAllocator\n+typename std::allocator_traits< Allocator >::template rebind_alloc<\n+AggregatesMap * > AAllocator\n+Allocator for pointers.\n+Definition: matrixhierarchy.hh:85\n+Dune::Amg::MatrixHierarchy::ParallelInformationHierarchy\n+Dune::Amg::Hierarchy< ParallelInformation, Allocator >\n+ParallelInformationHierarchy\n+The type of the parallel informarion hierarchy.\n+Definition: matrixhierarchy.hh:82\n+Dune::Amg::MatrixHierarchy::AggregatesMapList\n+std::list< AggregatesMap *, AAllocator > AggregatesMapList\n+The type of the aggregates maps list.\n+Definition: matrixhierarchy.hh:88\n+Dune::Amg::MatrixHierarchy::ParallelInformation\n+PI ParallelInformation\n+The type of the index set.\n+Definition: matrixhierarchy.hh:70\n+Dune::Amg::MatrixHierarchy::ParallelMatrixHierarchy\n+Dune::Amg::Hierarchy< MatrixOperator, Allocator > ParallelMatrixHierarchy\n+The type of the parallel matrix hierarchy.\n+Definition: matrixhierarchy.hh:79\n+Dune::Amg::MatrixHierarchy::Allocator\n+A Allocator\n+The allocator to use.\n+Definition: matrixhierarchy.hh:73\n+Dune::Amg::MatrixHierarchy::RedistributeInfoType\n+RedistributeInformation< ParallelInformation > RedistributeInfoType\n+The type of the redistribute information.\n+Definition: matrixhierarchy.hh:91\n+Dune::Amg::MatrixHierarchy::getProlongationDampingFactor\n+double getProlongationDampingFactor() const\n+Definition: matrixhierarchy.hh:188\n+Dune::Amg::MatrixHierarchy::RILAllocator\n+typename std::allocator_traits< Allocator >::template rebind_alloc<\n+RedistributeInfoType > RILAllocator\n+Allocator for RedistributeInfoType.\n+Definition: matrixhierarchy.hh:94\n+Dune::Amg::MatrixHierarchy::RedistributeInfoList\n+std::list< RedistributeInfoType, RILAllocator > RedistributeInfoList\n+The type of the list of redistribute information.\n+Definition: matrixhierarchy.hh:97\n+Dune::Amg::MatrixHierarchy::AggregatesMap\n+Dune::Amg::AggregatesMap< typename MatrixGraph< Matrix >::VertexDescriptor >\n+AggregatesMap\n+The type of the aggregates map we use.\n+Definition: matrixhierarchy.hh:76\n+Dune::Amg::MatrixHierarchy::Matrix\n+MatrixOperator::matrix_type Matrix\n+The type of the matrix.\n+Definition: matrixhierarchy.hh:67\n+Dune::Amg::MatrixHierarchy::MatrixOperator\n+M MatrixOperator\n+The type of the matrix operator.\n+Definition: matrixhierarchy.hh:64\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::operator()\n+void operator()(const matrix_row &row)\n+Definition: matrixhierarchy.hh:254\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::matrix_row\n+Matrix::row_type matrix_row\n+Definition: matrixhierarchy.hh:245\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::min\n+size_type min\n+Definition: matrixhierarchy.hh:261\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::calc\n+calc()\n+Definition: matrixhierarchy.hh:247\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::max\n+size_type max\n+Definition: matrixhierarchy.hh:262\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::sum\n+size_type sum\n+Definition: matrixhierarchy.hh:263\n+Dune::Amg::MatrixHierarchy::MatrixStats<_Matrix,_true_>::calc::size_type\n+Matrix::size_type size_type\n+Definition: matrixhierarchy.hh:244\n+Dune::Amg::CoarsenCriterion\n+The criterion describing the stop criteria for the coarsening process.\n+Definition: matrixhierarchy.hh:283\n+Dune::Amg::CoarsenCriterion::CoarsenCriterion\n+CoarsenCriterion(const Dune::Amg::Parameters &parms)\n+Definition: matrixhierarchy.hh:306\n+Dune::Amg::CoarsenCriterion::AggregationCriterion\n+T AggregationCriterion\n+The criterion for tagging connections as strong and nodes as isolated. This\n+might be e....\n+Definition: matrixhierarchy.hh:289\n+Dune::Amg::CoarsenCriterion::CoarsenCriterion\n+CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double\n+minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode\n+accumulate=successiveAccu)\n+Constructor.\n+Definition: matrixhierarchy.hh:301\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n Dune::Amg::VertexVisitedTag\n Tag idnetifying the visited property of a vertex.\n Definition: properties.hh:29\n+Dune::Amg::SmootherTraits\n+Traits class for getting the attribute class of a smoother.\n+Definition: smoother.hh:66\n+Dune::Amg::Transfer\n+Definition: transfer.hh:32\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00164.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00164.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: scalarproducts.hh File Reference\n+dune-istl: graphcreator.hh File Reference\n \n \n \n \n \n \n \n@@ -58,77 +58,47 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n \n+
    graphcreator.hh File Reference
    \n \n
    \n-\n-

    Define base class for scalar product and norm. \n-More...

    \n-
    #include <cmath>
    \n-#include <complex>
    \n-#include <iostream>
    \n-#include <iomanip>
    \n-#include <string>
    \n-#include <memory>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/shared_ptr.hh>
    \n-#include "bvector.hh"
    \n-#include "solvercategory.hh"
    \n+
    #include <tuple>
    \n+#include "graph.hh"
    \n+#include "dependency.hh"
    \n+#include "pinfo.hh"
    \n+#include <dune/istl/operators.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::ScalarProduct< X >
     Base class for scalar product and norm computation. More...
     
    class  Dune::ParallelScalarProduct< X, C >
     Scalar product for overlapping Schwarz methods. More...
     
    class  Dune::SeqScalarProduct< X >
     Default implementation for the scalar case. More...
    struct  Dune::Amg::PropertiesGraphCreator< M, PI >
     
    class  Dune::NonoverlappingSchwarzScalarProduct< X, C >
     Nonoverlapping Scalar Product with communication object. More...
     
    class  Dune::OverlappingSchwarzScalarProduct< X, C >
     Scalar product for overlapping Schwarz methods. More...
    struct  Dune::Amg::PropertiesGraphCreator< M, SequentialInformation >
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n

    \n-Functions

    template<class X , class Comm >
    std::shared_ptr< ScalarProduct< X > > Dune::makeScalarProduct (std::shared_ptr< const Comm > comm, SolverCategory::Category category)
     Choose the approriate scalar product for a solver category. More...
     
    template<class X , class Comm >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const Comm &comm, SolverCategory::Category category)
     
    namespace  Dune::Amg
     
    \n-

    Detailed Description

    \n-

    Define base class for scalar product and norm.

    \n-

    These classes have to be implemented differently for different data partitioning strategies. Default implementations for the sequential case are provided.

    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,62 +4,30 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-scalarproducts.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Scalar_products\n-Define base class for scalar product and norm. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"bvector.hh\"\n-#include \"solvercategory.hh\"\n+ * paamg\n+Classes | Namespaces\n+graphcreator.hh File Reference\n+#include \n+#include \"graph.hh\"\n+#include \"dependency.hh\"\n+#include \"pinfo.hh\"\n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::ScalarProduct<_X_>\n-\u00a0 Base class for scalar product and norm computation. More...\n+struct \u00a0Dune::Amg::PropertiesGraphCreator<_M,_PI_>\n \u00a0\n-class \u00a0Dune::ParallelScalarProduct<_X,_C_>\n-\u00a0 Scalar product for overlapping Schwarz methods. More...\n-\u00a0\n-class \u00a0Dune::SeqScalarProduct<_X_>\n-\u00a0 Default implementation for the scalar case. More...\n-\u00a0\n-class \u00a0Dune::NonoverlappingSchwarzScalarProduct<_X,_C_>\n-\u00a0 Nonoverlapping Scalar Product with communication object. More...\n-\u00a0\n-class \u00a0Dune::OverlappingSchwarzScalarProduct<_X,_C_>\n-\u00a0 Scalar product for overlapping Schwarz methods. More...\n+struct \u00a0Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-template\n-std::shared_ptr< ScalarProduct< X > >\u00a0Dune::makeScalarProduct (std::\n- shared_ptr< const Comm > comm,\n- SolverCategory::Category category)\n-\u00a0 Choose the approriate scalar product for\n- a solver category. More...\n-\u00a0\n-template\n-std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const Comm\n- &comm, SolverCategory::Category\n- category)\n+namespace \u00a0Dune::Amg\n \u00a0\n-***** Detailed Description *****\n-Define base class for scalar product and norm.\n-These classes have to be implemented differently for different data\n-partitioning strategies. Default implementations for the sequential case are\n-provided.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00164_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00164_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: scalarproducts.hh Source File\n+dune-istl: graphcreator.hh Source File\n \n \n \n \n \n \n \n@@ -58,190 +58,144 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    scalarproducts.hh
    \n+
    graphcreator.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SCALARPRODUCTS_HH
    \n-
    6#define DUNE_ISTL_SCALARPRODUCTS_HH
    \n+
    5#ifndef DUNE_AMG_GRAPHCREATOR_HH
    \n+
    6#define DUNE_AMG_GRAPHCREATOR_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <complex>
    \n-
    10#include <iostream>
    \n-
    11#include <iomanip>
    \n-
    12#include <string>
    \n-
    13#include <memory>
    \n-
    14
    \n-
    15#include <dune/common/exceptions.hh>
    \n-
    16#include <dune/common/shared_ptr.hh>
    \n-
    17
    \n-
    18#include "bvector.hh"
    \n-
    19#include "solvercategory.hh"
    \n-
    20
    \n-
    21
    \n-
    22namespace Dune {
    \n-
    51 template<class X>
    \n-\n-
    53 public:
    \n-
    55 typedef X domain_type;
    \n-
    56 typedef typename X::field_type field_type;
    \n-
    57 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-
    58
    \n-
    63 virtual field_type dot (const X& x, const X& y) const
    \n-
    64 {
    \n-
    65 return x.dot(y);
    \n-
    66 }
    \n-
    67
    \n-
    71 virtual real_type norm (const X& x) const
    \n-
    72 {
    \n-
    73 return x.two_norm();
    \n-
    74 }
    \n-
    75
    \n-\n-
    78 {
    \n-\n-
    80 }
    \n-
    81
    \n-
    83 virtual ~ScalarProduct () {}
    \n-
    84 };
    \n+
    8#include <tuple>
    \n+
    9
    \n+
    10#include "graph.hh"
    \n+
    11#include "dependency.hh"
    \n+
    12#include "pinfo.hh"
    \n+\n+\n+
    15
    \n+
    16namespace Dune
    \n+
    17{
    \n+
    18 namespace Amg
    \n+
    19 {
    \n+
    20 template<class M, class PI>
    \n+\n+
    22 {
    \n+
    23 typedef typename M::matrix_type Matrix;
    \n+\n+\n+
    26 std::vector<bool> > SubGraph;
    \n+\n+\n+\n+
    30 IdentityMap,
    \n+\n+\n+
    33
    \n+
    34 typedef std::tuple<MatrixGraph*,PropertiesGraph*,SubGraph*> GraphTuple;
    \n+
    35
    \n+
    36 template<class OF, class T>
    \n+
    37 static GraphTuple create(const M& matrix, T& excluded,
    \n+
    38 PI& pinfo, const OF& of)
    \n+
    39 {
    \n+
    40 MatrixGraph* mg = new MatrixGraph(matrix.getmat());
    \n+
    41 typedef typename PI::ParallelIndexSet ParallelIndexSet;
    \n+
    42 typedef typename ParallelIndexSet::const_iterator IndexIterator;
    \n+
    43 IndexIterator iend = pinfo.indexSet().end();
    \n+
    44
    \n+
    45 for(IndexIterator index = pinfo.indexSet().begin(); index != iend; ++index)
    \n+
    46 excluded[index->local()] = of.contains(index->local().attribute());
    \n+
    47
    \n+
    48 SubGraph* sg= new SubGraph(*mg, excluded);
    \n+
    49 PropertiesGraph* pg = new PropertiesGraph(*sg, IdentityMap(), sg->getEdgeIndexMap());
    \n+
    50 return GraphTuple(mg,pg,sg);
    \n+
    51 }
    \n+
    52
    \n+
    53 static void free(GraphTuple& graphs)
    \n+
    54 {
    \n+
    55 delete std::get<2>(graphs);
    \n+
    56 delete std::get<1>(graphs);
    \n+
    57 }
    \n+
    58 };
    \n+
    59
    \n+
    60 template<class M>
    \n+\n+
    62 {
    \n+
    63 typedef typename M::matrix_type Matrix;
    \n+
    64
    \n+\n+
    66
    \n+\n+\n+\n+
    70 IdentityMap,
    \n+
    71 IdentityMap> PropertiesGraph;
    \n+
    72
    \n+
    73 typedef std::tuple<MatrixGraph*,PropertiesGraph*> GraphTuple;
    \n+
    74
    \n+
    75 template<class OF, class T>
    \n+
    76 static GraphTuple create([[maybe_unused]] const M& matrix,
    \n+
    77 [[maybe_unused]] T& excluded,
    \n+
    78 [[maybe_unused]] const SequentialInformation& pinfo,
    \n+
    79 const OF&)
    \n+
    80 {
    \n+
    81 MatrixGraph* mg = new MatrixGraph(matrix.getmat());
    \n+
    82 PropertiesGraph* pg = new PropertiesGraph(*mg, IdentityMap(), IdentityMap());
    \n+
    83 return GraphTuple(mg,pg);
    \n+
    84 }
    \n
    85
    \n-
    97 template<class X, class C>
    \n-\n-
    99 {
    \n-
    100 public:
    \n-
    105 typedef X domain_type;
    \n-
    107 typedef typename X::field_type field_type;
    \n-
    108 typedef typename FieldTraits<field_type>::real_type real_type;
    \n-\n-
    114
    \n-
    120 ParallelScalarProduct (std::shared_ptr<const communication_type> com, SolverCategory::Category cat)
    \n-
    121 : _communication(com), _category(cat)
    \n-
    122 {}
    \n-
    123
    \n-\n-
    131 : ParallelScalarProduct(stackobject_to_shared_ptr(com), cat)
    \n-
    132 {}
    \n-
    133
    \n-
    134
    \n-
    139 virtual field_type dot (const X& x, const X& y) const override
    \n-
    140 {
    \n-
    141 field_type result(0);
    \n-
    142 _communication->dot(x,y,result); // explicitly loop and apply masking
    \n-
    143 return result;
    \n-
    144 }
    \n-
    145
    \n-
    149 virtual real_type norm (const X& x) const override
    \n-
    150 {
    \n-
    151 return _communication->norm(x);
    \n-
    152 }
    \n-
    153
    \n-
    155 virtual SolverCategory::Category category() const override
    \n-
    156 {
    \n-
    157 return _category;
    \n-
    158 }
    \n-
    159
    \n-
    160 private:
    \n-
    161 std::shared_ptr<const communication_type> _communication;
    \n-
    162 SolverCategory::Category _category;
    \n-
    163 };
    \n-
    164
    \n-
    166 template<class X>
    \n-\n-
    168 {
    \n-
    169 using ScalarProduct<X>::ScalarProduct;
    \n-
    170 };
    \n-
    171
    \n-
    177 template<class X, class C>
    \n-\n-
    179 {
    \n-
    180 public:
    \n-
    181 NonoverlappingSchwarzScalarProduct (std::shared_ptr<const C> comm) :
    \n-
    182 ParallelScalarProduct<X,C>(comm,SolverCategory::nonoverlapping) {}
    \n-
    183
    \n-\n-
    185 ParallelScalarProduct<X,C>(comm,SolverCategory::nonoverlapping) {}
    \n-
    186 };
    \n-
    187
    \n-
    199 template<class X, class C>
    \n-\n-
    201 {
    \n-
    202 public:
    \n-
    203 OverlappingSchwarzScalarProduct (std::shared_ptr<const C> comm) :
    \n-
    204 ParallelScalarProduct<X,C>(comm, SolverCategory::overlapping) {}
    \n-
    205
    \n-\n-
    207 ParallelScalarProduct<X,C>(comm,SolverCategory::overlapping) {}
    \n-
    208 };
    \n-
    209
    \n-
    223 template<class X, class Comm>
    \n-
    224 std::shared_ptr<ScalarProduct<X>> makeScalarProduct(std::shared_ptr<const Comm> comm, SolverCategory::Category category)
    \n-
    225 {
    \n-
    226 switch(category)
    \n-
    227 {
    \n-\n-
    229 return
    \n-
    230 std::make_shared<ScalarProduct<X>>();
    \n-
    231 default:
    \n-
    232 return
    \n-
    233 std::make_shared<ParallelScalarProduct<X,Comm>>(comm,category);
    \n-
    234 }
    \n-
    235 }
    \n-
    236
    \n-
    241 template<class X, class Comm>
    \n-
    242 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const Comm& comm, SolverCategory::Category category)
    \n-
    243 { return makeScalarProduct<X>(stackobject_to_shared_ptr(comm), category); }
    \n-
    244
    \n-
    245} // end namespace Dune
    \n-
    246
    \n-
    247#endif
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n+
    86 static void free(GraphTuple& graphs)
    \n+
    87 {
    \n+
    88 delete std::get<1>(graphs);
    \n+
    89 }
    \n+
    90
    \n+
    91 };
    \n+
    92
    \n+
    93 } //namespace Amg
    \n+
    94} // namespace Dune
    \n+
    95#endif
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+
    Provides classes for building the matrix graph.
    \n+
    Provides classes for initializing the link attributes of a matrix graph.
    \n+\n
    Definition: allocator.hh:11
    \n-
    std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm, SolverCategory::Category category)
    Definition: scalarproducts.hh:242
    \n-
    std::shared_ptr< ScalarProduct< X > > makeScalarProduct(std::shared_ptr< const Comm > comm, SolverCategory::Category category)
    Choose the approriate scalar product for a solver category.
    Definition: scalarproducts.hh:224
    \n-
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n-
    virtual field_type dot(const X &x, const X &y) const
    Dot product of two vectors. It is assumed that the vectors are consistent on the interior+border part...
    Definition: scalarproducts.hh:63
    \n-
    virtual SolverCategory::Category category() const
    Category of the scalar product (see SolverCategory::Category)
    Definition: scalarproducts.hh:77
    \n-
    X::field_type field_type
    Definition: scalarproducts.hh:56
    \n-
    X domain_type
    export types, they come from the derived class
    Definition: scalarproducts.hh:55
    \n-
    virtual ~ScalarProduct()
    every abstract base class has a virtual destructor
    Definition: scalarproducts.hh:83
    \n-
    FieldTraits< field_type >::real_type real_type
    Definition: scalarproducts.hh:57
    \n-
    virtual real_type norm(const X &x) const
    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
    Definition: scalarproducts.hh:71
    \n-
    Scalar product for overlapping Schwarz methods.
    Definition: scalarproducts.hh:99
    \n-
    virtual field_type dot(const X &x, const X &y) const override
    Dot product of two vectors. It is assumed that the vectors are consistent on the interior+border part...
    Definition: scalarproducts.hh:139
    \n-
    virtual SolverCategory::Category category() const override
    Category of the scalar product (see SolverCategory::Category)
    Definition: scalarproducts.hh:155
    \n-
    FieldTraits< field_type >::real_type real_type
    Definition: scalarproducts.hh:108
    \n-
    C communication_type
    The type of the communication object.
    Definition: scalarproducts.hh:113
    \n-
    ParallelScalarProduct(const communication_type &com, SolverCategory::Category cat)
    Definition: scalarproducts.hh:130
    \n-
    X domain_type
    The type of the vector to compute the scalar product on.
    Definition: scalarproducts.hh:105
    \n-
    ParallelScalarProduct(std::shared_ptr< const communication_type > com, SolverCategory::Category cat)
    Definition: scalarproducts.hh:120
    \n-
    X::field_type field_type
    The field type used by the vector type domain_type.
    Definition: scalarproducts.hh:107
    \n-
    virtual real_type norm(const X &x) const override
    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
    Definition: scalarproducts.hh:149
    \n-
    Default implementation for the scalar case.
    Definition: scalarproducts.hh:168
    \n-
    Nonoverlapping Scalar Product with communication object.
    Definition: scalarproducts.hh:179
    \n-
    NonoverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)
    Definition: scalarproducts.hh:181
    \n-
    NonoverlappingSchwarzScalarProduct(const C &comm)
    Definition: scalarproducts.hh:184
    \n-
    Scalar product for overlapping Schwarz methods.
    Definition: scalarproducts.hh:201
    \n-
    OverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)
    Definition: scalarproducts.hh:203
    \n-
    OverlappingSchwarzScalarProduct(const C &comm)
    Definition: scalarproducts.hh:206
    \n-
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    Class representing the properties of an ede in the matrix graph.
    Definition: dependency.hh:39
    \n+
    Class representing a node in the matrix graph.
    Definition: dependency.hh:126
    \n+
    The (undirected) graph of a matrix.
    Definition: graph.hh:51
    \n+
    A subgraph of a graph.
    Definition: graph.hh:443
    \n+
    EdgeIndexMap getEdgeIndexMap()
    Get an edge index map for the graph.
    \n+
    An index map for mapping the edges to indices.
    Definition: graph.hh:470
    \n+
    Attaches properties to the edges and vertices of a graph.
    Definition: graph.hh:978
    \n+
    Definition: graphcreator.hh:22
    \n+
    Dune::Amg::SubGraph< MatrixGraph, std::vector< bool > > SubGraph
    Definition: graphcreator.hh:26
    \n+
    Dune::Amg::PropertiesGraph< SubGraph, VertexProperties, EdgeProperties, IdentityMap, typename SubGraph::EdgeIndexMap > PropertiesGraph
    Definition: graphcreator.hh:32
    \n+
    M::matrix_type Matrix
    Definition: graphcreator.hh:23
    \n+
    static GraphTuple create(const M &matrix, T &excluded, PI &pinfo, const OF &of)
    Definition: graphcreator.hh:37
    \n+
    static void free(GraphTuple &graphs)
    Definition: graphcreator.hh:53
    \n+
    Dune::Amg::MatrixGraph< const Matrix > MatrixGraph
    Definition: graphcreator.hh:24
    \n+
    std::tuple< MatrixGraph *, PropertiesGraph *, SubGraph * > GraphTuple
    Definition: graphcreator.hh:34
    \n+
    Dune::Amg::MatrixGraph< const Matrix > MatrixGraph
    Definition: graphcreator.hh:65
    \n+
    M::matrix_type Matrix
    Definition: graphcreator.hh:63
    \n+
    Dune::Amg::PropertiesGraph< MatrixGraph, VertexProperties, EdgeProperties, IdentityMap, IdentityMap > PropertiesGraph
    Definition: graphcreator.hh:71
    \n+
    std::tuple< MatrixGraph *, PropertiesGraph * > GraphTuple
    Definition: graphcreator.hh:73
    \n+
    static GraphTuple create(const M &matrix, T &excluded, const SequentialInformation &pinfo, const OF &)
    Definition: graphcreator.hh:76
    \n+
    static void free(GraphTuple &graphs)
    Definition: graphcreator.hh:86
    \n+
    Definition: pinfo.hh:28
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,272 +4,190 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-scalarproducts.hh\n+ * paamg\n+graphcreator.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SCALARPRODUCTS_HH\n- 6#define DUNE_ISTL_SCALARPRODUCTS_HH\n+ 5#ifndef DUNE_AMG_GRAPHCREATOR_HH\n+ 6#define DUNE_AMG_GRAPHCREATOR_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14\n- 15#include \n- 16#include \n- 17\n- 18#include \"bvector.hh\"\n- 19#include \"solvercategory.hh\"\n- 20\n- 21\n- 22namespace Dune {\n- 51 template\n-52 class ScalarProduct {\n- 53 public:\n-55 typedef X domain_type;\n-56 typedef typename X::field_type field_type;\n-57 typedef typename FieldTraits::real_type real_type;\n- 58\n-63 virtual field_type dot (const X& x, const X& y) const\n- 64 {\n- 65 return x.dot(y);\n- 66 }\n- 67\n-71 virtual real_type norm (const X& x) const\n- 72 {\n- 73 return x.two_norm();\n- 74 }\n- 75\n-77 virtual SolverCategory::Category category() const\n- 78 {\n- 79 return SolverCategory::sequential;\n- 80 }\n- 81\n-83 virtual ~ScalarProduct () {}\n- 84 };\n+ 8#include \n+ 9\n+ 10#include \"graph.hh\"\n+ 11#include \"dependency.hh\"\n+ 12#include \"pinfo.hh\"\n+ 13#include \n+ 14#include \n+ 15\n+ 16namespace Dune\n+ 17{\n+ 18 namespace Amg\n+ 19 {\n+ 20 template\n+21 struct PropertiesGraphCreator\n+ 22 {\n+23 typedef typename M::matrix_type Matrix;\n+24 typedef Dune::Amg::MatrixGraph MatrixGraph;\n+ 25 typedef Dune::Amg::SubGraph > SubGraph;\n+ 27 typedef Dune::Amg::PropertiesGraph\n+32 PropertiesGraph;\n+ 33\n+34 typedef std::tuple GraphTuple;\n+ 35\n+ 36 template\n+37 static GraphTuple create(const M& matrix, T& excluded,\n+ 38 PI& pinfo, const OF& of)\n+ 39 {\n+ 40 MatrixGraph* mg = new MatrixGraph(matrix.getmat());\n+ 41 typedef typename PI::ParallelIndexSet ParallelIndexSet;\n+ 42 typedef typename ParallelIndexSet::const_iterator IndexIterator;\n+ 43 IndexIterator iend = pinfo.indexSet().end();\n+ 44\n+ 45 for(IndexIterator index = pinfo.indexSet().begin(); index != iend; ++index)\n+ 46 excluded[index->local()] = of.contains(index->local().attribute());\n+ 47\n+ 48 SubGraph* sg= new SubGraph(*mg, excluded);\n+ 49 PropertiesGraph* pg = new PropertiesGraph(*sg, IdentityMap(), sg-\n+>getEdgeIndexMap());\n+ 50 return GraphTuple(mg,pg,sg);\n+ 51 }\n+ 52\n+53 static void free(GraphTuple& graphs)\n+ 54 {\n+ 55 delete std::get<2>(graphs);\n+ 56 delete std::get<1>(graphs);\n+ 57 }\n+ 58 };\n+ 59\n+ 60 template\n+61 struct PropertiesGraphCreator\n+ 62 {\n+63 typedef typename M::matrix_type Matrix;\n+ 64\n+65 typedef Dune::Amg::MatrixGraph MatrixGraph;\n+ 66\n+ 67 typedef Dune::Amg::PropertiesGraph PropertiesGraph;\n+ 72\n+73 typedef std::tuple GraphTuple;\n+ 74\n+ 75 template\n+76 static GraphTuple create([[maybe_unused]] const M& matrix,\n+ 77 [[maybe_unused]] T& excluded,\n+ 78 [[maybe_unused]] const SequentialInformation& pinfo,\n+ 79 const OF&)\n+ 80 {\n+ 81 MatrixGraph* mg = new MatrixGraph(matrix.getmat());\n+ 82 PropertiesGraph* pg = new PropertiesGraph(*mg, IdentityMap(), IdentityMap\n+());\n+ 83 return GraphTuple(mg,pg);\n+ 84 }\n 85\n- 97 template\n-98 class ParallelScalarProduct : public ScalarProduct\n- 99 {\n- 100 public:\n-105 typedef X domain_type;\n-107 typedef typename X::field_type field_type;\n-108 typedef typename FieldTraits::real_type real_type;\n-113 typedef C communication_type;\n- 114\n-120 ParallelScalarProduct (std::shared_ptr com,\n-SolverCategory::Category cat)\n- 121 : _communication(com), _category(cat)\n- 122 {}\n- 123\n-130 ParallelScalarProduct (const communication_type& com, SolverCategory::\n-Category cat)\n- 131 : ParallelScalarProduct(stackobject_to_shared_ptr(com), cat)\n- 132 {}\n- 133\n- 134\n-139 virtual field_type dot (const X& x, const X& y) const override\n- 140 {\n- 141 field_type result(0);\n- 142 _communication->dot(x,y,result); // explicitly loop and apply masking\n- 143 return result;\n- 144 }\n- 145\n-149 virtual real_type norm (const X& x) const override\n- 150 {\n- 151 return _communication->norm(x);\n- 152 }\n- 153\n-155 virtual SolverCategory::Category category() const override\n- 156 {\n- 157 return _category;\n- 158 }\n- 159\n- 160 private:\n- 161 std::shared_ptr _communication;\n- 162 SolverCategory::Category _category;\n- 163 };\n- 164\n- 166 template\n-167 class SeqScalarProduct : public ScalarProduct\n- 168 {\n- 169 using ScalarProduct::ScalarProduct;\n- 170 };\n- 171\n- 177 template\n-178 class NonoverlappingSchwarzScalarProduct : public\n-ParallelScalarProduct\n- 179 {\n- 180 public:\n-181 NonoverlappingSchwarzScalarProduct (std::shared_ptr comm) :\n- 182 ParallelScalarProduct(comm,SolverCategory::nonoverlapping) {}\n- 183\n-184 NonoverlappingSchwarzScalarProduct (const C& comm) :\n- 185 ParallelScalarProduct(comm,SolverCategory::nonoverlapping) {}\n- 186 };\n- 187\n- 199 template\n-200 class OverlappingSchwarzScalarProduct : public ParallelScalarProduct\n- 201 {\n- 202 public:\n-203 OverlappingSchwarzScalarProduct (std::shared_ptr comm) :\n- 204 ParallelScalarProduct(comm, SolverCategory::overlapping) {}\n- 205\n-206 OverlappingSchwarzScalarProduct (const C& comm) :\n- 207 ParallelScalarProduct(comm,SolverCategory::overlapping) {}\n- 208 };\n- 209\n- 223 template\n-224 std::shared_ptr> makeScalarProduct(std::shared_ptr comm, SolverCategory::Category category)\n- 225 {\n- 226 switch(category)\n- 227 {\n- 228 case SolverCategory::sequential:\n- 229 return\n- 230 std::make_shared>();\n- 231 default:\n- 232 return\n- 233 std::make_shared>(comm,category);\n- 234 }\n- 235 }\n- 236\n- 241 template\n-242 std::shared_ptr> createScalarProduct(const Comm& comm,\n-SolverCategory::Category category)\n- 243 { return makeScalarProduct(stackobject_to_shared_ptr(comm), category);\n-}\n- 244\n- 245} // end namespace Dune\n- 246\n- 247#endif\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-solvercategory.hh\n+86 static void free(GraphTuple& graphs)\n+ 87 {\n+ 88 delete std::get<1>(graphs);\n+ 89 }\n+ 90\n+ 91 };\n+ 92\n+ 93 } //namespace Amg\n+ 94} // namespace Dune\n+ 95#endif\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n+graph.hh\n+Provides classes for building the matrix graph.\n+dependency.hh\n+Provides classes for initializing the link attributes of a matrix graph.\n+pinfo.hh\n Dune\n Definition: allocator.hh:11\n-Dune::createScalarProduct\n-std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm,\n-SolverCategory::Category category)\n-Definition: scalarproducts.hh:242\n-Dune::makeScalarProduct\n-std::shared_ptr< ScalarProduct< X > > makeScalarProduct(std::shared_ptr< const\n-Comm > comm, SolverCategory::Category category)\n-Choose the approriate scalar product for a solver category.\n-Definition: scalarproducts.hh:224\n-Dune::ScalarProduct\n-Base class for scalar product and norm computation.\n-Definition: scalarproducts.hh:52\n-Dune::ScalarProduct::dot\n-virtual field_type dot(const X &x, const X &y) const\n-Dot product of two vectors. It is assumed that the vectors are consistent on\n-the interior+border part...\n-Definition: scalarproducts.hh:63\n-Dune::ScalarProduct::category\n-virtual SolverCategory::Category category() const\n-Category of the scalar product (see SolverCategory::Category)\n-Definition: scalarproducts.hh:77\n-Dune::ScalarProduct::field_type\n-X::field_type field_type\n-Definition: scalarproducts.hh:56\n-Dune::ScalarProduct::domain_type\n-X domain_type\n-export types, they come from the derived class\n-Definition: scalarproducts.hh:55\n-Dune::ScalarProduct::~ScalarProduct\n-virtual ~ScalarProduct()\n-every abstract base class has a virtual destructor\n-Definition: scalarproducts.hh:83\n-Dune::ScalarProduct::real_type\n-FieldTraits< field_type >::real_type real_type\n-Definition: scalarproducts.hh:57\n-Dune::ScalarProduct::norm\n-virtual real_type norm(const X &x) const\n-Norm of a right-hand side vector. The vector must be consistent on the\n-interior+border partition.\n-Definition: scalarproducts.hh:71\n-Dune::ParallelScalarProduct\n-Scalar product for overlapping Schwarz methods.\n-Definition: scalarproducts.hh:99\n-Dune::ParallelScalarProduct::dot\n-virtual field_type dot(const X &x, const X &y) const override\n-Dot product of two vectors. It is assumed that the vectors are consistent on\n-the interior+border part...\n-Definition: scalarproducts.hh:139\n-Dune::ParallelScalarProduct::category\n-virtual SolverCategory::Category category() const override\n-Category of the scalar product (see SolverCategory::Category)\n-Definition: scalarproducts.hh:155\n-Dune::ParallelScalarProduct::real_type\n-FieldTraits< field_type >::real_type real_type\n-Definition: scalarproducts.hh:108\n-Dune::ParallelScalarProduct::communication_type\n-C communication_type\n-The type of the communication object.\n-Definition: scalarproducts.hh:113\n-Dune::ParallelScalarProduct::ParallelScalarProduct\n-ParallelScalarProduct(const communication_type &com, SolverCategory::Category\n-cat)\n-Definition: scalarproducts.hh:130\n-Dune::ParallelScalarProduct::domain_type\n-X domain_type\n-The type of the vector to compute the scalar product on.\n-Definition: scalarproducts.hh:105\n-Dune::ParallelScalarProduct::ParallelScalarProduct\n-ParallelScalarProduct(std::shared_ptr< const communication_type > com,\n-SolverCategory::Category cat)\n-Definition: scalarproducts.hh:120\n-Dune::ParallelScalarProduct::field_type\n-X::field_type field_type\n-The field type used by the vector type domain_type.\n-Definition: scalarproducts.hh:107\n-Dune::ParallelScalarProduct::norm\n-virtual real_type norm(const X &x) const override\n-Norm of a right-hand side vector. The vector must be consistent on the\n-interior+border partition.\n-Definition: scalarproducts.hh:149\n-Dune::SeqScalarProduct\n-Default implementation for the scalar case.\n-Definition: scalarproducts.hh:168\n-Dune::NonoverlappingSchwarzScalarProduct\n-Nonoverlapping Scalar Product with communication object.\n-Definition: scalarproducts.hh:179\n-Dune::NonoverlappingSchwarzScalarProduct::NonoverlappingSchwarzScalarProduct\n-NonoverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)\n-Definition: scalarproducts.hh:181\n-Dune::NonoverlappingSchwarzScalarProduct::NonoverlappingSchwarzScalarProduct\n-NonoverlappingSchwarzScalarProduct(const C &comm)\n-Definition: scalarproducts.hh:184\n-Dune::OverlappingSchwarzScalarProduct\n-Scalar product for overlapping Schwarz methods.\n-Definition: scalarproducts.hh:201\n-Dune::OverlappingSchwarzScalarProduct::OverlappingSchwarzScalarProduct\n-OverlappingSchwarzScalarProduct(std::shared_ptr< const C > comm)\n-Definition: scalarproducts.hh:203\n-Dune::OverlappingSchwarzScalarProduct::OverlappingSchwarzScalarProduct\n-OverlappingSchwarzScalarProduct(const C &comm)\n-Definition: scalarproducts.hh:206\n-Dune::SolverCategory\n-Categories for the solvers.\n-Definition: solvercategory.hh:22\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n+Dune::Amg::EdgeProperties\n+Class representing the properties of an ede in the matrix graph.\n+Definition: dependency.hh:39\n+Dune::Amg::VertexProperties\n+Class representing a node in the matrix graph.\n+Definition: dependency.hh:126\n+Dune::Amg::MatrixGraph\n+The (undirected) graph of a matrix.\n+Definition: graph.hh:51\n+Dune::Amg::SubGraph\n+A subgraph of a graph.\n+Definition: graph.hh:443\n+Dune::Amg::SubGraph::getEdgeIndexMap\n+EdgeIndexMap getEdgeIndexMap()\n+Get an edge index map for the graph.\n+Dune::Amg::SubGraph::EdgeIndexMap\n+An index map for mapping the edges to indices.\n+Definition: graph.hh:470\n+Dune::Amg::PropertiesGraph\n+Attaches properties to the edges and vertices of a graph.\n+Definition: graph.hh:978\n+Dune::Amg::PropertiesGraphCreator\n+Definition: graphcreator.hh:22\n+Dune::Amg::PropertiesGraphCreator::SubGraph\n+Dune::Amg::SubGraph< MatrixGraph, std::vector< bool > > SubGraph\n+Definition: graphcreator.hh:26\n+Dune::Amg::PropertiesGraphCreator::PropertiesGraph\n+Dune::Amg::PropertiesGraph< SubGraph, VertexProperties, EdgeProperties,\n+IdentityMap, typename SubGraph::EdgeIndexMap > PropertiesGraph\n+Definition: graphcreator.hh:32\n+Dune::Amg::PropertiesGraphCreator::Matrix\n+M::matrix_type Matrix\n+Definition: graphcreator.hh:23\n+Dune::Amg::PropertiesGraphCreator::create\n+static GraphTuple create(const M &matrix, T &excluded, PI &pinfo, const OF &of)\n+Definition: graphcreator.hh:37\n+Dune::Amg::PropertiesGraphCreator::free\n+static void free(GraphTuple &graphs)\n+Definition: graphcreator.hh:53\n+Dune::Amg::PropertiesGraphCreator::MatrixGraph\n+Dune::Amg::MatrixGraph< const Matrix > MatrixGraph\n+Definition: graphcreator.hh:24\n+Dune::Amg::PropertiesGraphCreator::GraphTuple\n+std::tuple< MatrixGraph *, PropertiesGraph *, SubGraph * > GraphTuple\n+Definition: graphcreator.hh:34\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::MatrixGraph\n+Dune::Amg::MatrixGraph< const Matrix > MatrixGraph\n+Definition: graphcreator.hh:65\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::Matrix\n+M::matrix_type Matrix\n+Definition: graphcreator.hh:63\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::PropertiesGraph\n+Dune::Amg::PropertiesGraph< MatrixGraph, VertexProperties, EdgeProperties,\n+IdentityMap, IdentityMap > PropertiesGraph\n+Definition: graphcreator.hh:71\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::GraphTuple\n+std::tuple< MatrixGraph *, PropertiesGraph * > GraphTuple\n+Definition: graphcreator.hh:73\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::create\n+static GraphTuple create(const M &matrix, T &excluded, const\n+SequentialInformation &pinfo, const OF &)\n+Definition: graphcreator.hh:76\n+Dune::Amg::PropertiesGraphCreator<_M,_SequentialInformation_>::free\n+static void free(GraphTuple &graphs)\n+Definition: graphcreator.hh:86\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00167.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00167.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ilu.hh File Reference\n+dune-istl: renumberer.hh File Reference\n \n \n \n \n \n \n \n@@ -58,85 +58,47 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    ilu.hh File Reference
    \n+
    renumberer.hh File Reference
    \n
    \n
    \n-\n-

    The incomplete LU factorization kernels. \n-More...

    \n-
    #include <cmath>
    \n-#include <complex>
    \n-#include <map>
    \n-#include <vector>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include "istlexception.hh"
    \n+
    #include "aggregates.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n

    \n Classes

    struct  Dune::ILU::CRS< B, Alloc >
     a simple compressed row storage matrix class More...
    class  Dune::Amg::AggregateRenumberer< G >
     
    \n \n \n \n-\n+\n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::ILU
    namespace  Dune::Amg
     
    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n

    \n Functions

    template<class M >
    void Dune::ILU::blockILU0Decomposition (M &A)
     compute ILU decomposition of A. A is overwritten by its decomposition More...
     
    template<class M , class X , class Y >
    void Dune::ILU::blockILUBacksolve (const M &A, X &v, const Y &d)
     LU backsolve with stored inverse. More...
     
    template<class M >
    M::field_type & Dune::ILU::firstMatrixElement (M &A, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
     
    template<class K >
    K & Dune::ILU::firstMatrixElement (K &A, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
     
    template<class K , int n, int m>
    K & Dune::ILU::firstMatrixElement (FieldMatrix< K, n, m > &A)
     
    template<class M >
    void Dune::ILU::blockILUDecomposition (const M &A, int n, M &ILU)
     
    template<class M , class CRS , class InvVector >
    void Dune::ILU::convertToCRS (const M &A, CRS &lower, CRS &upper, InvVector &inv)
     convert ILU decomposition into CRS format for lower and upper triangular and inverse. More...
     
    template<class CRS , class InvVector , class X , class Y >
    void Dune::ILU::blockILUBacksolve (const CRS &lower, const CRS &upper, const InvVector &inv, X &v, const Y &d)
     LU backsolve with stored inverse in CRS format for lower and upper triangular. More...
     
    template<class G , class I , class V >
    void Dune::Amg::renumberAggregates (const G &graph, I index, I endIndex, V &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)
     
    \n-

    Detailed Description

    \n-

    The incomplete LU factorization kernels.

    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,69 +4,28 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * paamg\n Classes | Namespaces | Functions\n-ilu.hh File Reference\n-The incomplete LU factorization kernels. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"istlexception.hh\"\n+renumberer.hh File Reference\n+#include \"aggregates.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::ILU::CRS<_B,_Alloc_>\n-\u00a0 a simple compressed row storage matrix class More...\n+class \u00a0Dune::Amg::AggregateRenumberer<_G_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::ILU\n+namespace \u00a0Dune::Amg\n \u00a0\n Functions\n-template\n- void\u00a0Dune::ILU::blockILU0Decomposition (M &A)\n-\u00a0 compute ILU decomposition of A. A is overwritten by its\n- decomposition More...\n+template\n+void\u00a0Dune::Amg::renumberAggregates (const G &graph, I index, I endIndex, V\n+ &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)\n \u00a0\n-template\n- void\u00a0Dune::ILU::blockILUBacksolve (const M &A, X &v, const Y &d)\n-\u00a0 LU backsolve with stored inverse. More...\n-\u00a0\n-template\n-M::field_type &\u00a0Dune::ILU::firstMatrixElement (M &A, typename std::\n- enable_if_t::value > *sfinae=nullptr)\n-\u00a0\n-template\n- K &\u00a0Dune::ILU::firstMatrixElement (K &A, typename std::\n- enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n-\u00a0\n-template\n- K &\u00a0Dune::ILU::firstMatrixElement (FieldMatrix< K, n, m > &A)\n-\u00a0\n-template\n- void\u00a0Dune::ILU::blockILUDecomposition (const M &A, int n, M &ILU)\n-\u00a0\n-template\n- void\u00a0Dune::ILU::convertToCRS (const M &A, CRS &lower, CRS &upper,\n- InvVector &inv)\n-\u00a0 convert ILU decomposition into CRS format for lower and upper\n- triangular and inverse. More...\n-\u00a0\n-template\n- void\u00a0Dune::ILU::blockILUBacksolve (const CRS &lower, const CRS\n- &upper, const InvVector &inv, X &v, const Y &d)\n-\u00a0 LU backsolve with stored inverse in CRS format for lower and\n- upper triangular. More...\n-\u00a0\n-***** Detailed Description *****\n-The incomplete LU factorization kernels.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00167_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00167_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ilu.hh Source File\n+dune-istl: renumberer.hh Source File\n \n \n \n \n \n \n \n@@ -58,452 +58,110 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    ilu.hh
    \n+
    renumberer.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_ILU_HH
    \n-
    6#define DUNE_ISTL_ILU_HH
    \n+
    5#ifndef DUNE_AMG_RENUMBERER_HH
    \n+
    6#define DUNE_AMG_RENUMBERER_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <complex>
    \n-
    10#include <map>
    \n-
    11#include <vector>
    \n-
    12
    \n-
    13#include <dune/common/fmatrix.hh>
    \n-
    14#include <dune/common/scalarvectorview.hh>
    \n-
    15#include <dune/common/scalarmatrixview.hh>
    \n-
    16
    \n-
    17#include "istlexception.hh"
    \n-
    18
    \n-
    23namespace Dune {
    \n-
    24
    \n-
    29 namespace ILU {
    \n-
    30
    \n-
    32 template<class M>
    \n-\n-
    34 {
    \n-
    35 // iterator types
    \n-
    36 typedef typename M::RowIterator rowiterator;
    \n-
    37 typedef typename M::ColIterator coliterator;
    \n-
    38 typedef typename M::block_type block;
    \n-
    39
    \n-
    40 // implement left looking variant with stored inverse
    \n-
    41 rowiterator endi=A.end();
    \n-
    42 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    43 {
    \n-
    44 // coliterator is diagonal after the following loop
    \n-
    45 coliterator endij=(*i).end(); // end of row i
    \n-
    46 coliterator ij;
    \n-
    47
    \n-
    48 // eliminate entries left of diagonal; store L factor
    \n-
    49 for (ij=(*i).begin(); ij.index()<i.index(); ++ij)
    \n-
    50 {
    \n-
    51 // find A_jj which eliminates A_ij
    \n-
    52 coliterator jj = A[ij.index()].find(ij.index());
    \n-
    53
    \n-
    54 // compute L_ij = A_jj^-1 * A_ij
    \n-
    55 Impl::asMatrix(*ij).rightmultiply(Impl::asMatrix(*jj));
    \n-
    56
    \n-
    57 // modify row
    \n-
    58 coliterator endjk=A[ij.index()].end(); // end of row j
    \n-
    59 coliterator jk=jj; ++jk;
    \n-
    60 coliterator ik=ij; ++ik;
    \n-
    61 while (ik!=endij && jk!=endjk)
    \n-
    62 if (ik.index()==jk.index())
    \n-
    63 {
    \n-
    64 block B(*jk);
    \n-
    65 Impl::asMatrix(B).leftmultiply(Impl::asMatrix(*ij));
    \n-
    66 *ik -= B;
    \n-
    67 ++ik; ++jk;
    \n-
    68 }
    \n-
    69 else
    \n-
    70 {
    \n-
    71 if (ik.index()<jk.index())
    \n-
    72 ++ik;
    \n-
    73 else
    \n-
    74 ++jk;
    \n-
    75 }
    \n+
    8#include "aggregates.hh"
    \n+
    9
    \n+
    10namespace Dune
    \n+
    11{
    \n+
    12 namespace Amg
    \n+
    13 {
    \n+
    14 template<class G>
    \n+\n+
    16 {
    \n+
    17 public:
    \n+
    19 typedef typename G::VertexDescriptor Vertex;
    \n+
    20
    \n+\n+
    26
    \n+
    28 operator Vertex() const;
    \n+
    29
    \n+
    30 void operator()(const typename G::ConstEdgeIterator& edge);
    \n+
    31
    \n+
    32 void operator++();
    \n+
    33
    \n+
    34 protected:
    \n+\n+\n+
    37 };
    \n+
    38
    \n+
    39 template<class G>
    \n+\n+
    41 : number_(0), aggregates_(aggregates)
    \n+
    42 {}
    \n+
    43
    \n+
    44 template<class G>
    \n+\n+
    46 {
    \n+
    47 return number_;
    \n+
    48 }
    \n+
    49
    \n+
    50 template<class G>
    \n+
    51 void AggregateRenumberer<G>::operator()(const typename G::ConstEdgeIterator& edge)
    \n+
    52 {
    \n+
    53 aggregates_[edge.target()]=number_;
    \n+
    54 }
    \n+
    55
    \n+
    56 template<class G>
    \n+\n+
    58 {
    \n+
    59 ++number_;
    \n+
    60 }
    \n+
    61
    \n+
    62 template<class G, class I, class V>
    \n+
    63 void renumberAggregates(const G& graph, I index, I endIndex, V& visitedMap,
    \n+\n+
    65 {
    \n+
    66 AggregateRenumberer<G> renumberer(aggregates);
    \n+
    67
    \n+
    68 for(I index1=index; index1 != endIndex; ++index1)
    \n+
    69 if(aggregates[index1.index()]!=AggregatesMap<typename G::VertexDescriptor>::ISOLATED &&
    \n+
    70 !get(visitedMap, index1.index())) {
    \n+
    71
    \n+
    72 aggregates.template breadthFirstSearch<false>(index1.index(), aggregates[index1.index()],
    \n+
    73 graph, renumberer, visitedMap);
    \n+
    74 aggregates[index1.index()] = renumberer;
    \n+
    75 ++renumberer;
    \n
    76 }
    \n-
    77
    \n-
    78 // invert pivot and store it in A
    \n-
    79 if (ij.index()!=i.index())
    \n-
    80 DUNE_THROW(ISTLError,"diagonal entry missing");
    \n-
    81 try {
    \n-
    82 Impl::asMatrix(*ij).invert(); // compute inverse of diagonal block
    \n-
    83 }
    \n-
    84 catch (Dune::FMatrixError & e) {
    \n-
    85 DUNE_THROW(MatrixBlockError, "ILU failed to invert matrix block A["
    \n-
    86 << i.index() << "][" << ij.index() << "]" << e.what();
    \n-
    87 th__ex.r=i.index(); th__ex.c=ij.index(););
    \n-
    88 }
    \n-
    89 }
    \n-
    90 }
    \n-
    91
    \n-
    93 template<class M, class X, class Y>
    \n-
    94 void blockILUBacksolve (const M& A, X& v, const Y& d)
    \n-
    95 {
    \n-
    96 // iterator types
    \n-
    97 typedef typename M::ConstRowIterator rowiterator;
    \n-
    98 typedef typename M::ConstColIterator coliterator;
    \n-
    99 typedef typename Y::block_type dblock;
    \n-
    100 typedef typename X::block_type vblock;
    \n-
    101
    \n-
    102 // lower triangular solve
    \n-
    103 rowiterator endi=A.end();
    \n-
    104 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    105 {
    \n-
    106 // We need to be careful here: Directly using
    \n-
    107 // auto rhs = Impl::asVector(d[ i.index() ]);
    \n-
    108 // is not OK in case this is a proxy. Hence
    \n-
    109 // we first have to copy the value. Notice that
    \n-
    110 // this is still not OK, if the vector type itself returns
    \n-
    111 // proxy references.
    \n-
    112 dblock rhsValue(d[i.index()]);
    \n-
    113 auto&& rhs = Impl::asVector(rhsValue);
    \n-
    114 for (coliterator j=(*i).begin(); j.index()<i.index(); ++j)
    \n-
    115 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);
    \n-
    116 Impl::asVector(v[i.index()]) = rhs; // Lii = I
    \n-
    117 }
    \n-
    118
    \n-
    119 // upper triangular solve
    \n-
    120 rowiterator rendi=A.beforeBegin();
    \n-
    121 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n-
    122 {
    \n-
    123 // We need to be careful here: Directly using
    \n-
    124 // auto rhs = Impl::asVector(v[ i.index() ]);
    \n-
    125 // is not OK in case this is a proxy. Hence
    \n-
    126 // we first have to copy the value. Notice that
    \n-
    127 // this is still not OK, if the vector type itself returns
    \n-
    128 // proxy references.
    \n-
    129 vblock rhsValue(v[i.index()]);
    \n-
    130 auto&& rhs = Impl::asVector(rhsValue);
    \n-
    131 coliterator j;
    \n-
    132 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)
    \n-
    133 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);
    \n-
    134 auto&& vi = Impl::asVector(v[i.index()]);
    \n-
    135 Impl::asMatrix(*j).mv(rhs,vi); // diagonal stores inverse!
    \n-
    136 }
    \n-
    137 }
    \n-
    138
    \n-
    139 // recursive function template to access first entry of a matrix
    \n-
    140 template<class M>
    \n-
    141 typename M::field_type& firstMatrixElement (M& A,
    \n-
    142 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
    \n-
    143 {
    \n-
    144 return firstMatrixElement(*(A.begin()->begin()));
    \n-
    145 }
    \n-
    146
    \n-
    147 template<class K>
    \n-\n-
    149 [[maybe_unused]] typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr)
    \n-
    150 {
    \n-
    151 return A;
    \n-
    152 }
    \n-
    153
    \n-
    154 template<class K, int n, int m>
    \n-\n-
    156 {
    \n-
    157 return A[0][0];
    \n-
    158 }
    \n-
    159
    \n-
    166 template<class M>
    \n-
    167 void blockILUDecomposition (const M& A, int n, M& ILU)
    \n-
    168 {
    \n-
    169 // iterator types
    \n-
    170 typedef typename M::ColIterator coliterator;
    \n-
    171 typedef typename M::ConstRowIterator crowiterator;
    \n-
    172 typedef typename M::ConstColIterator ccoliterator;
    \n-
    173 typedef typename M::CreateIterator createiterator;
    \n-
    174 typedef typename M::field_type K;
    \n-
    175 typedef std::map<size_t, int> map;
    \n-
    176 typedef typename map::iterator mapiterator;
    \n-
    177
    \n-
    178 // symbolic factorization phase, store generation number in first matrix element
    \n-
    179 crowiterator endi=A.end();
    \n-
    180 createiterator ci=ILU.createbegin();
    \n-
    181 for (crowiterator i=A.begin(); i!=endi; ++i)
    \n-
    182 {
    \n-
    183 map rowpattern; // maps column index to generation
    \n-
    184
    \n-
    185 // initialize pattern with row of A
    \n-
    186 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)
    \n-
    187 rowpattern[j.index()] = 0;
    \n-
    188
    \n-
    189 // eliminate entries in row which are to the left of the diagonal
    \n-
    190 for (mapiterator ik=rowpattern.begin(); (*ik).first<i.index(); ++ik)
    \n-
    191 {
    \n-
    192 if ((*ik).second<n)
    \n-
    193 {
    \n-
    194 coliterator endk = ILU[(*ik).first].end(); // end of row k
    \n-
    195 coliterator kj = ILU[(*ik).first].find((*ik).first); // diagonal in k
    \n-
    196 for (++kj; kj!=endk; ++kj) // row k eliminates in row i
    \n-
    197 {
    \n-
    198 // we misuse the storage to store an int. If the field_type is std::complex, we have to access the real/abs part
    \n-
    199 // starting from C++11, we can use std::abs to always return a real value, even if it is double/float
    \n-
    200 using std::abs;
    \n-
    201 int generation = (int) Simd::lane(0, abs( firstMatrixElement(*kj) ));
    \n-
    202 if (generation<n)
    \n-
    203 {
    \n-
    204 mapiterator ij = rowpattern.find(kj.index());
    \n-
    205 if (ij==rowpattern.end())
    \n-
    206 {
    \n-
    207 rowpattern[kj.index()] = generation+1;
    \n-
    208 }
    \n-
    209 }
    \n-
    210 }
    \n-
    211 }
    \n-
    212 }
    \n-
    213
    \n-
    214 // create row
    \n-
    215 for (mapiterator ik=rowpattern.begin(); ik!=rowpattern.end(); ++ik)
    \n-
    216 ci.insert((*ik).first);
    \n-
    217 ++ci; // now row i exist
    \n-
    218
    \n-
    219 // write generation index into entries
    \n-
    220 coliterator endILUij = ILU[i.index()].end();;
    \n-
    221 for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
    \n-
    222 Simd::lane(0, firstMatrixElement(*ILUij)) = (Simd::Scalar<K>) rowpattern[ILUij.index()];
    \n-
    223 }
    \n-
    224
    \n-
    225 // copy entries of A
    \n-
    226 for (crowiterator i=A.begin(); i!=endi; ++i)
    \n-
    227 {
    \n-
    228 coliterator ILUij;
    \n-
    229 coliterator endILUij = ILU[i.index()].end();;
    \n-
    230 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
    \n-
    231 (*ILUij) = 0; // clear row
    \n-
    232 ccoliterator Aij = (*i).begin();
    \n-
    233 ccoliterator endAij = (*i).end();
    \n-
    234 ILUij = ILU[i.index()].begin();
    \n-
    235 while (Aij!=endAij && ILUij!=endILUij)
    \n-
    236 {
    \n-
    237 if (Aij.index()==ILUij.index())
    \n-
    238 {
    \n-
    239 *ILUij = *Aij;
    \n-
    240 ++Aij; ++ILUij;
    \n-
    241 }
    \n-
    242 else
    \n-
    243 {
    \n-
    244 if (Aij.index()<ILUij.index())
    \n-
    245 ++Aij;
    \n-
    246 else
    \n-
    247 ++ILUij;
    \n-
    248 }
    \n-
    249 }
    \n-
    250 }
    \n-
    251
    \n-
    252 // call decomposition on pattern
    \n-\n-
    254 }
    \n-
    255
    \n-
    257 template <class B, class Alloc = std::allocator<B>>
    \n-
    258 struct CRS
    \n-
    259 {
    \n-
    260 typedef B block_type;
    \n-
    261 typedef size_t size_type;
    \n-
    262
    \n-
    263 CRS() : nRows_( 0 ) {}
    \n-
    264
    \n-
    265 size_type rows() const { return nRows_; }
    \n-
    266
    \n-\n-
    268 {
    \n-
    269 assert( rows_[ rows() ] != size_type(-1) );
    \n-
    270 return rows_[ rows() ];
    \n-
    271 }
    \n-
    272
    \n-
    273 void resize( const size_type nRows )
    \n-
    274 {
    \n-
    275 if( nRows_ != nRows )
    \n-
    276 {
    \n-
    277 nRows_ = nRows ;
    \n-
    278 rows_.resize( nRows_+1, size_type(-1) );
    \n-
    279 }
    \n-
    280 }
    \n-
    281
    \n-\n-
    283 {
    \n-
    284 const size_type needed = values_.size() + nonZeros ;
    \n-
    285 if( values_.capacity() < needed )
    \n-
    286 {
    \n-
    287 const size_type estimate = needed * 1.1;
    \n-
    288 values_.reserve( estimate );
    \n-
    289 cols_.reserve( estimate );
    \n-
    290 }
    \n-
    291 }
    \n-
    292
    \n-
    293 void push_back( const block_type& value, const size_type index )
    \n-
    294 {
    \n-
    295 values_.push_back( value );
    \n-
    296 cols_.push_back( index );
    \n-
    297 }
    \n-
    298
    \n-
    299 std::vector< size_type > rows_;
    \n-
    300 std::vector< block_type, Alloc> values_;
    \n-
    301 std::vector< size_type > cols_;
    \n-\n-
    303 };
    \n-
    304
    \n-
    306 template<class M, class CRS, class InvVector>
    \n-
    307 void convertToCRS(const M& A, CRS& lower, CRS& upper, InvVector& inv )
    \n-
    308 {
    \n-
    309 typedef typename M :: size_type size_type;
    \n-
    310
    \n-
    311 lower.resize( A.N() );
    \n-
    312 upper.resize( A.N() );
    \n-
    313 inv.resize( A.N() );
    \n-
    314
    \n-
    315 // lower and upper triangular should store half of non zeros minus diagonal
    \n-
    316 const size_t memEstimate = (A.nonzeroes() - A.N())/2;
    \n-
    317
    \n-
    318 assert( A.nonzeroes() != 0 );
    \n-
    319 lower.reserveAdditional( memEstimate );
    \n-
    320 upper.reserveAdditional( memEstimate );
    \n-
    321
    \n-
    322 const auto endi = A.end();
    \n-
    323 size_type row = 0;
    \n-
    324 size_type colcount = 0;
    \n-
    325 lower.rows_[ 0 ] = colcount;
    \n-
    326 for (auto i=A.begin(); i!=endi; ++i, ++row)
    \n-
    327 {
    \n-
    328 const size_type iIndex = i.index();
    \n-
    329
    \n-
    330 // store entries left of diagonal
    \n-
    331 for (auto j=(*i).begin(); j.index() < iIndex; ++j )
    \n-
    332 {
    \n-
    333 lower.push_back( (*j), j.index() );
    \n-
    334 ++colcount;
    \n-
    335 }
    \n-
    336 lower.rows_[ iIndex+1 ] = colcount;
    \n-
    337 }
    \n-
    338
    \n-
    339 const auto rendi = A.beforeBegin();
    \n-
    340 row = 0;
    \n-
    341 colcount = 0;
    \n-
    342 upper.rows_[ 0 ] = colcount ;
    \n-
    343
    \n-
    344 // NOTE: upper and inv store entries in reverse row and col order,
    \n-
    345 // reverse here relative to ILU
    \n-
    346 for (auto i=A.beforeEnd(); i!=rendi; --i, ++ row )
    \n-
    347 {
    \n-
    348 const auto endij=(*i).beforeBegin(); // end of row i
    \n-
    349
    \n-
    350 const size_type iIndex = i.index();
    \n-
    351
    \n-
    352 // store in reverse row order for faster access during backsolve
    \n-
    353 for (auto j=(*i).beforeEnd(); j != endij; --j )
    \n-
    354 {
    \n-
    355 const size_type jIndex = j.index();
    \n-
    356 if( j.index() == iIndex )
    \n-
    357 {
    \n-
    358 inv[ row ] = (*j);
    \n-
    359 break; // assuming consecutive ordering of A
    \n-
    360 }
    \n-
    361 else if ( j.index() >= i.index() )
    \n-
    362 {
    \n-
    363 upper.push_back( (*j), jIndex );
    \n-
    364 ++colcount ;
    \n-
    365 }
    \n-
    366 }
    \n-
    367 upper.rows_[ row+1 ] = colcount;
    \n-
    368 }
    \n-
    369 } // end convertToCRS
    \n-
    370
    \n-
    372 template<class CRS, class InvVector, class X, class Y>
    \n-
    373 void blockILUBacksolve (const CRS& lower,
    \n-
    374 const CRS& upper,
    \n-
    375 const InvVector& inv,
    \n-
    376 X& v, const Y& d)
    \n-
    377 {
    \n-
    378 // iterator types
    \n-
    379 typedef typename Y :: block_type dblock;
    \n-
    380 typedef typename X :: block_type vblock;
    \n-
    381 typedef typename X :: size_type size_type ;
    \n-
    382
    \n-
    383 const size_type iEnd = lower.rows();
    \n-
    384 const size_type lastRow = iEnd - 1;
    \n-
    385 if( iEnd != upper.rows() )
    \n-
    386 {
    \n-
    387 DUNE_THROW(ISTLError,"ILU::blockILUBacksolve: lower and upper rows must be the same");
    \n-
    388 }
    \n-
    389
    \n-
    390 // lower triangular solve
    \n-
    391 for( size_type i=0; i<iEnd; ++ i )
    \n-
    392 {
    \n-
    393 dblock rhsValue( d[ i ] );
    \n-
    394 auto&& rhs = Impl::asVector(rhsValue);
    \n-
    395 const size_type rowI = lower.rows_[ i ];
    \n-
    396 const size_type rowINext = lower.rows_[ i+1 ];
    \n-
    397
    \n-
    398 for( size_type col = rowI; col < rowINext; ++ col )
    \n-
    399 Impl::asMatrix(lower.values_[ col ]).mmv( Impl::asVector(v[ lower.cols_[ col ] ] ), rhs );
    \n-
    400
    \n-
    401 Impl::asVector(v[ i ]) = rhs; // Lii = I
    \n-
    402 }
    \n-
    403
    \n-
    404 // upper triangular solve
    \n-
    405 for( size_type i=0; i<iEnd; ++ i )
    \n-
    406 {
    \n-
    407 auto&& vBlock = Impl::asVector(v[ lastRow - i ]);
    \n-
    408 vblock rhsValue ( v[ lastRow - i ] );
    \n-
    409 auto&& rhs = Impl::asVector(rhsValue);
    \n-
    410 const size_type rowI = upper.rows_[ i ];
    \n-
    411 const size_type rowINext = upper.rows_[ i+1 ];
    \n-
    412
    \n-
    413 for( size_type col = rowI; col < rowINext; ++ col )
    \n-
    414 Impl::asMatrix(upper.values_[ col ]).mmv( Impl::asVector(v[ upper.cols_[ col ] ]), rhs );
    \n-
    415
    \n-
    416 // apply inverse and store result
    \n-
    417 Impl::asMatrix(inv[ i ]).mv(rhs, vBlock);
    \n-
    418 }
    \n-
    419 }
    \n-
    420
    \n-
    421 } // end namespace ILU
    \n-
    422
    \n-
    425} // end namespace
    \n-
    426
    \n-
    427#endif
    \n-\n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    77 for(; index != endIndex; ++index)
    \n+
    78 put(visitedMap, index.index(), false);
    \n+
    79 }
    \n+
    80
    \n+
    81 } // namespace AMG
    \n+
    82} // namespace Dune
    \n+
    83#endif
    \n+
    Provides classes for the Coloring process of AMG.
    \n
    Definition: allocator.hh:11
    \n-
    void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)
    convert ILU decomposition into CRS format for lower and upper triangular and inverse.
    Definition: ilu.hh:307
    \n-
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n-
    M::field_type & firstMatrixElement(M &A, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
    Definition: ilu.hh:141
    \n-
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n-
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n-
    a simple compressed row storage matrix class
    Definition: ilu.hh:259
    \n-
    std::vector< size_type > cols_
    Definition: ilu.hh:301
    \n-
    size_type nonZeros() const
    Definition: ilu.hh:267
    \n-
    void resize(const size_type nRows)
    Definition: ilu.hh:273
    \n-
    size_type rows() const
    Definition: ilu.hh:265
    \n-
    CRS()
    Definition: ilu.hh:263
    \n-
    void reserveAdditional(const size_type nonZeros)
    Definition: ilu.hh:282
    \n-
    B block_type
    Definition: ilu.hh:260
    \n-
    std::vector< block_type, Alloc > values_
    Definition: ilu.hh:300
    \n-
    size_type nRows_
    Definition: ilu.hh:302
    \n-
    size_t size_type
    Definition: ilu.hh:261
    \n-
    std::vector< size_type > rows_
    Definition: ilu.hh:299
    \n-
    void push_back(const block_type &value, const size_type index)
    Definition: ilu.hh:293
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Error when performing an operation on a matrix block.
    Definition: istlexception.hh:52
    \n-
    int r
    Definition: istlexception.hh:54
    \n-
    Definition: matrixutils.hh:27
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    void renumberAggregates(const G &graph, I index, I endIndex, V &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)
    Definition: renumberer.hh:63
    \n+\n+
    Definition: renumberer.hh:16
    \n+
    void operator++()
    Definition: renumberer.hh:57
    \n+
    G::VertexDescriptor Vertex
    The vertex type.
    Definition: renumberer.hh:19
    \n+
    void operator()(const typename G::ConstEdgeIterator &edge)
    Definition: renumberer.hh:51
    \n+
    AggregatesMap< Vertex > & aggregates_
    Definition: renumberer.hh:36
    \n+
    AggregateRenumberer(AggregatesMap< Vertex > &aggregates)
    Constructor.
    Definition: renumberer.hh:40
    \n+
    Vertex number_
    Definition: renumberer.hh:35
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,505 +4,131 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-ilu.hh\n+ * paamg\n+renumberer.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_ILU_HH\n- 6#define DUNE_ISTL_ILU_HH\n+ 5#ifndef DUNE_AMG_RENUMBERER_HH\n+ 6#define DUNE_AMG_RENUMBERER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12\n- 13#include \n- 14#include \n- 15#include \n- 16\n- 17#include \"istlexception.hh\"\n- 18\n- 23namespace Dune {\n- 24\n-29 namespace ILU {\n- 30\n- 32 template\n-33 void blockILU0Decomposition (M& A)\n- 34 {\n- 35 // iterator types\n- 36 typedef typename M::RowIterator rowiterator;\n- 37 typedef typename M::ColIterator coliterator;\n- 38 typedef typename M::block_type block;\n- 39\n- 40 // implement left looking variant with stored inverse\n- 41 rowiterator endi=A.end();\n- 42 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 43 {\n- 44 // coliterator is diagonal after the following loop\n- 45 coliterator endij=(*i).end(); // end of row i\n- 46 coliterator ij;\n- 47\n- 48 // eliminate entries left of diagonal; store L factor\n- 49 for (ij=(*i).begin(); ij.index()\n+15 class AggregateRenumberer\n+ 16 {\n+ 17 public:\n+19 typedef typename G::VertexDescriptor Vertex;\n+ 20\n+ 25 AggregateRenumberer(AggregatesMap& aggregates);\n+ 26\n+ 28 operator Vertex() const;\n+ 29\n+ 30 void operator()(const typename G::ConstEdgeIterator& edge);\n+ 31\n+ 32 void operator++();\n+ 33\n+ 34 protected:\n+35 Vertex number_;\n+36 AggregatesMap& aggregates_;\n+ 37 };\n+ 38\n+ 39 template\n+40 AggregateRenumberer::AggregateRenumberer(AggregatesMap&\n+aggregates)\n+ 41 : number_(0), aggregates_(aggregates)\n+ 42 {}\n+ 43\n+ 44 template\n+45 AggregateRenumberer::operator Vertex() const\n+ 46 {\n+ 47 return number_;\n+ 48 }\n+ 49\n+ 50 template\n+51 void AggregateRenumberer::operator()(const typename G::ConstEdgeIterator&\n+edge)\n+ 52 {\n+ 53 aggregates_[edge.target()]=number_;\n+ 54 }\n+ 55\n+ 56 template\n+57 void AggregateRenumberer::operator++()\n+ 58 {\n+ 59 ++number_;\n+ 60 }\n+ 61\n+ 62 template\n+63 void renumberAggregates(const G& graph, I index, I endIndex, V& visitedMap,\n+ 64 AggregatesMap& aggregates)\n+ 65 {\n+ 66 AggregateRenumberer renumberer(aggregates);\n+ 67\n+ 68 for(I index1=index; index1 != endIndex; ++index1)\n+ 69 if(aggregates[index1.index()]!=AggregatesMap::ISOLATED &&\n+ 70 !get(visitedMap, index1.index())) {\n+ 71\n+ 72 aggregates.template breadthFirstSearch(index1.index(), aggregates\n+[index1.index()],\n+ 73 graph, renumberer, visitedMap);\n+ 74 aggregates[index1.index()] = renumberer;\n+ 75 ++renumberer;\n 76 }\n- 77\n- 78 // invert pivot and store it in A\n- 79 if (ij.index()!=i.index())\n- 80 DUNE_THROW(ISTLError,\"diagonal entry missing\");\n- 81 try {\n- 82 Impl::asMatrix(*ij).invert(); // compute inverse of diagonal block\n- 83 }\n- 84 catch (Dune::FMatrixError & e) {\n- 85 DUNE_THROW(MatrixBlockError, \"ILU failed to invert matrix block A[\"\n- 86 << i.index() << \"][\" << ij.index() << \"]\" << e.what();\n- 87 th__ex.r=i.index(); th__ex.c=ij.index(););\n- 88 }\n- 89 }\n- 90 }\n- 91\n- 93 template\n-94 void blockILUBacksolve (const M& A, X& v, const Y& d)\n- 95 {\n- 96 // iterator types\n- 97 typedef typename M::ConstRowIterator rowiterator;\n- 98 typedef typename M::ConstColIterator coliterator;\n- 99 typedef typename Y::block_type dblock;\n- 100 typedef typename X::block_type vblock;\n- 101\n- 102 // lower triangular solve\n- 103 rowiterator endi=A.end();\n- 104 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 105 {\n- 106 // We need to be careful here: Directly using\n- 107 // auto rhs = Impl::asVector(d[ i.index() ]);\n- 108 // is not OK in case this is a proxy. Hence\n- 109 // we first have to copy the value. Notice that\n- 110 // this is still not OK, if the vector type itself returns\n- 111 // proxy references.\n- 112 dblock rhsValue(d[i.index()]);\n- 113 auto&& rhs = Impl::asVector(rhsValue);\n- 114 for (coliterator j=(*i).begin(); j.index()i.index(); --j)\n- 133 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);\n- 134 auto&& vi = Impl::asVector(v[i.index()]);\n- 135 Impl::asMatrix(*j).mv(rhs,vi); // diagonal stores inverse!\n- 136 }\n- 137 }\n- 138\n- 139 // recursive function template to access first entry of a matrix\n- 140 template\n-141 typename M::field_type& firstMatrixElement (M& A,\n- 142 [[maybe_unused]] typename std::enable_if_t::value>*\n-sfinae = nullptr)\n- 143 {\n- 144 return firstMatrixElement(*(A.begin()->begin()));\n- 145 }\n- 146\n- 147 template\n-148 K& firstMatrixElement (K& A,\n- 149 [[maybe_unused]] typename std::enable_if_t::value>*\n-sfinae = nullptr)\n- 150 {\n- 151 return A;\n- 152 }\n- 153\n- 154 template\n-155 K& firstMatrixElement (FieldMatrix& A)\n- 156 {\n- 157 return A[0][0];\n- 158 }\n- 159\n- 166 template\n-167 void blockILUDecomposition (const M& A, int n, M& ILU)\n- 168 {\n- 169 // iterator types\n- 170 typedef typename M::ColIterator coliterator;\n- 171 typedef typename M::ConstRowIterator crowiterator;\n- 172 typedef typename M::ConstColIterator ccoliterator;\n- 173 typedef typename M::CreateIterator createiterator;\n- 174 typedef typename M::field_type K;\n- 175 typedef std::map map;\n- 176 typedef typename map::iterator mapiterator;\n- 177\n- 178 // symbolic factorization phase, store generation number in first matrix\n-element\n- 179 crowiterator endi=A.end();\n- 180 createiterator ci=ILU.createbegin();\n- 181 for (crowiterator i=A.begin(); i!=endi; ++i)\n- 182 {\n- 183 map rowpattern; // maps column index to generation\n- 184\n- 185 // initialize pattern with row of A\n- 186 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)\n- 187 rowpattern[j.index()] = 0;\n- 188\n- 189 // eliminate entries in row which are to the left of the diagonal\n- 190 for (mapiterator ik=rowpattern.begin(); (*ik).first) rowpattern\n-[ILUij.index()];\n- 223 }\n- 224\n- 225 // copy entries of A\n- 226 for (crowiterator i=A.begin(); i!=endi; ++i)\n- 227 {\n- 228 coliterator ILUij;\n- 229 coliterator endILUij = ILU[i.index()].end();;\n- 230 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)\n- 231 (*ILUij) = 0; // clear row\n- 232 ccoliterator Aij = (*i).begin();\n- 233 ccoliterator endAij = (*i).end();\n- 234 ILUij = ILU[i.index()].begin();\n- 235 while (Aij!=endAij && ILUij!=endILUij)\n- 236 {\n- 237 if (Aij.index()==ILUij.index())\n- 238 {\n- 239 *ILUij = *Aij;\n- 240 ++Aij; ++ILUij;\n- 241 }\n- 242 else\n- 243 {\n- 244 if (Aij.index()>\n-258 struct CRS\n- 259 {\n-260 typedef B block_type;\n-261 typedef size_t size_type;\n- 262\n-263 CRS() : nRows_( 0 ) {}\n- 264\n-265 size_type rows() const { return nRows_; }\n- 266\n-267 size_type nonZeros() const\n- 268 {\n- 269 assert( rows_[ rows() ] != size_type(-1) );\n- 270 return rows_[ rows() ];\n- 271 }\n- 272\n-273 void resize( const size_type nRows )\n- 274 {\n- 275 if( nRows_ != nRows )\n- 276 {\n- 277 nRows_ = nRows ;\n- 278 rows_.resize( nRows_+1, size_type(-1) );\n- 279 }\n- 280 }\n- 281\n-282 void reserveAdditional( const size_type nonZeros )\n- 283 {\n- 284 const size_type needed = values_.size() + nonZeros ;\n- 285 if( values_.capacity() < needed )\n- 286 {\n- 287 const size_type estimate = needed * 1.1;\n- 288 values_.reserve( estimate );\n- 289 cols_.reserve( estimate );\n- 290 }\n- 291 }\n- 292\n-293 void push_back( const block_type& value, const size_type index )\n- 294 {\n- 295 values_.push_back( value );\n- 296 cols_.push_back( index );\n- 297 }\n- 298\n-299 std::vector< size_type > rows_;\n-300 std::vector< block_type, Alloc> values_;\n-301 std::vector< size_type > cols_;\n-302 size_type nRows_;\n- 303 };\n- 304\n- 306 template\n-307 void convertToCRS(const M& A, CRS& lower, CRS& upper, InvVector& inv )\n- 308 {\n- 309 typedef typename M :: size_type size_type;\n- 310\n- 311 lower.resize( A.N() );\n- 312 upper.resize( A.N() );\n- 313 inv.resize( A.N() );\n- 314\n- 315 // lower and upper triangular should store half of non zeros minus\n-diagonal\n- 316 const size_t memEstimate = (A.nonzeroes() - A.N())/2;\n- 317\n- 318 assert( A.nonzeroes() != 0 );\n- 319 lower.reserveAdditional( memEstimate );\n- 320 upper.reserveAdditional( memEstimate );\n- 321\n- 322 const auto endi = A.end();\n- 323 size_type row = 0;\n- 324 size_type colcount = 0;\n- 325 lower.rows_[ 0 ] = colcount;\n- 326 for (auto i=A.begin(); i!=endi; ++i, ++row)\n- 327 {\n- 328 const size_type iIndex = i.index();\n- 329\n- 330 // store entries left of diagonal\n- 331 for (auto j=(*i).begin(); j.index() < iIndex; ++j )\n- 332 {\n- 333 lower.push_back( (*j), j.index() );\n- 334 ++colcount;\n- 335 }\n- 336 lower.rows_[ iIndex+1 ] = colcount;\n- 337 }\n- 338\n- 339 const auto rendi = A.beforeBegin();\n- 340 row = 0;\n- 341 colcount = 0;\n- 342 upper.rows_[ 0 ] = colcount ;\n- 343\n- 344 // NOTE: upper and inv store entries in reverse row and col order,\n- 345 // reverse here relative to ILU\n- 346 for (auto i=A.beforeEnd(); i!=rendi; --i, ++ row )\n- 347 {\n- 348 const auto endij=(*i).beforeBegin(); // end of row i\n- 349\n- 350 const size_type iIndex = i.index();\n- 351\n- 352 // store in reverse row order for faster access during backsolve\n- 353 for (auto j=(*i).beforeEnd(); j != endij; --j )\n- 354 {\n- 355 const size_type jIndex = j.index();\n- 356 if( j.index() == iIndex )\n- 357 {\n- 358 inv[ row ] = (*j);\n- 359 break; // assuming consecutive ordering of A\n- 360 }\n- 361 else if ( j.index() >= i.index() )\n- 362 {\n- 363 upper.push_back( (*j), jIndex );\n- 364 ++colcount ;\n- 365 }\n- 366 }\n- 367 upper.rows_[ row+1 ] = colcount;\n- 368 }\n- 369 } // end convertToCRS\n- 370\n- 372 template\n-373 void blockILUBacksolve (const CRS& lower,\n- 374 const CRS& upper,\n- 375 const InvVector& inv,\n- 376 X& v, const Y& d)\n- 377 {\n- 378 // iterator types\n- 379 typedef typename Y :: block_type dblock;\n- 380 typedef typename X :: block_type vblock;\n- 381 typedef typename X :: size_type size_type ;\n- 382\n- 383 const size_type iEnd = lower.rows();\n- 384 const size_type lastRow = iEnd - 1;\n- 385 if( iEnd != upper.rows() )\n- 386 {\n- 387 DUNE_THROW(ISTLError,\"ILU::blockILUBacksolve: lower and upper rows must be\n-the same\");\n- 388 }\n- 389\n- 390 // lower triangular solve\n- 391 for( size_type i=0; i::value > *sfinae=nullptr)\n-Definition: ilu.hh:141\n-Dune::ILU::blockILU0Decomposition\n-void blockILU0Decomposition(M &A)\n-compute ILU decomposition of A. A is overwritten by its decomposition\n-Definition: ilu.hh:33\n-Dune::ILU::blockILUDecomposition\n-void blockILUDecomposition(const M &A, int n, M &ILU)\n-Definition: ilu.hh:167\n-Dune::ILU::CRS\n-a simple compressed row storage matrix class\n-Definition: ilu.hh:259\n-Dune::ILU::CRS::cols_\n-std::vector< size_type > cols_\n-Definition: ilu.hh:301\n-Dune::ILU::CRS::nonZeros\n-size_type nonZeros() const\n-Definition: ilu.hh:267\n-Dune::ILU::CRS::resize\n-void resize(const size_type nRows)\n-Definition: ilu.hh:273\n-Dune::ILU::CRS::rows\n-size_type rows() const\n-Definition: ilu.hh:265\n-Dune::ILU::CRS::CRS\n-CRS()\n-Definition: ilu.hh:263\n-Dune::ILU::CRS::reserveAdditional\n-void reserveAdditional(const size_type nonZeros)\n-Definition: ilu.hh:282\n-Dune::ILU::CRS::block_type\n-B block_type\n-Definition: ilu.hh:260\n-Dune::ILU::CRS::values_\n-std::vector< block_type, Alloc > values_\n-Definition: ilu.hh:300\n-Dune::ILU::CRS::nRows_\n-size_type nRows_\n-Definition: ilu.hh:302\n-Dune::ILU::CRS::size_type\n-size_t size_type\n-Definition: ilu.hh:261\n-Dune::ILU::CRS::rows_\n-std::vector< size_type > rows_\n-Definition: ilu.hh:299\n-Dune::ILU::CRS::push_back\n-void push_back(const block_type &value, const size_type index)\n-Definition: ilu.hh:293\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::MatrixBlockError\n-Error when performing an operation on a matrix block.\n-Definition: istlexception.hh:52\n-Dune::MatrixBlockError::r\n-int r\n-Definition: istlexception.hh:54\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::Amg::renumberAggregates\n+void renumberAggregates(const G &graph, I index, I endIndex, V &visitedMap,\n+AggregatesMap< typename G::VertexDescriptor > &aggregates)\n+Definition: renumberer.hh:63\n+Dune::Amg::AggregatesMap<_Vertex_>\n+Dune::Amg::AggregateRenumberer\n+Definition: renumberer.hh:16\n+Dune::Amg::AggregateRenumberer::operator++\n+void operator++()\n+Definition: renumberer.hh:57\n+Dune::Amg::AggregateRenumberer::Vertex\n+G::VertexDescriptor Vertex\n+The vertex type.\n+Definition: renumberer.hh:19\n+Dune::Amg::AggregateRenumberer::operator()\n+void operator()(const typename G::ConstEdgeIterator &edge)\n+Definition: renumberer.hh:51\n+Dune::Amg::AggregateRenumberer::aggregates_\n+AggregatesMap< Vertex > & aggregates_\n+Definition: renumberer.hh:36\n+Dune::Amg::AggregateRenumberer::AggregateRenumberer\n+AggregateRenumberer(AggregatesMap< Vertex > &aggregates)\n+Constructor.\n+Definition: renumberer.hh:40\n+Dune::Amg::AggregateRenumberer::number_\n+Vertex number_\n+Definition: renumberer.hh:35\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00170.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00170.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: istlexception.hh File Reference\n+dune-istl: combinedfunctor.hh File Reference\n \n \n \n \n \n \n \n@@ -58,51 +58,43 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    istlexception.hh File Reference
    \n+
    combinedfunctor.hh File Reference
    \n
    \n
    \n-
    #include <dune/common/exceptions.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n+
    #include <tuple>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::ISTLError
     derive error class from the base class in common More...
    struct  Dune::Amg::ApplyHelper< i >
     
    class  Dune::BCRSMatrixError
     Error specific to BCRSMatrix. More...
    struct  Dune::Amg::ApplyHelper< 0 >
     
    class  Dune::ImplicitModeCompressionBufferExhausted
     Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted. More...
     
    class  Dune::SolverAbort
     Thrown when a solver aborts due to some problem. More...
     
    class  Dune::MatrixBlockError
     Error when performing an operation on a matrix block. More...
    class  Dune::Amg::CombinedFunctor< T >
     
    \n \n \n \n+\n+\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,35 +4,27 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * paamg\n Classes | Namespaces\n-istlexception.hh File Reference\n-#include \n-#include \n+combinedfunctor.hh File Reference\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::ISTLError\n-\u00a0 derive error class from the base class in common More...\n+struct \u00a0Dune::Amg::ApplyHelper<_i_>\n \u00a0\n-class \u00a0Dune::BCRSMatrixError\n-\u00a0 Error specific to BCRSMatrix. More...\n+struct \u00a0Dune::Amg::ApplyHelper<_0_>\n \u00a0\n-class \u00a0Dune::ImplicitModeCompressionBufferExhausted\n-\u00a0 Thrown when the compression buffer used by the implicit BCRSMatrix\n- construction is exhausted. More...\n-\u00a0\n-class \u00a0Dune::SolverAbort\n-\u00a0 Thrown when a solver aborts due to some problem. More...\n-\u00a0\n-class \u00a0Dune::MatrixBlockError\n-\u00a0 Error when performing an operation on a matrix block. More...\n+ class \u00a0Dune::Amg::CombinedFunctor<_T_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::Amg\n+\u00a0\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00170_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00170_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: istlexception.hh Source File\n+dune-istl: combinedfunctor.hh Source File\n \n \n \n \n \n \n \n@@ -58,63 +58,81 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    istlexception.hh
    \n+
    combinedfunctor.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_ISTLEXCEPTION_HH
    \n-
    6#define DUNE_ISTL_ISTLEXCEPTION_HH
    \n+
    5#ifndef DUNE_AMG_COMBINEDFUNCTOR_HH
    \n+
    6#define DUNE_AMG_COMBINEDFUNCTOR_HH
    \n
    7
    \n-
    8#include <dune/common/exceptions.hh>
    \n-
    9#include <dune/common/fmatrix.hh>
    \n-
    10
    \n-
    11namespace Dune {
    \n-
    12
    \n-
    19 class ISTLError : public Dune::MathError {};
    \n-
    20
    \n-\n-
    23 : public ISTLError
    \n-
    24 {};
    \n-
    25
    \n-\n-
    36 : public BCRSMatrixError
    \n-
    37 {};
    \n-
    38
    \n-
    40
    \n-
    46 class SolverAbort : public ISTLError {};
    \n-
    47
    \n+
    8#include <tuple>
    \n+
    9
    \n+
    10namespace Dune
    \n+
    11{
    \n+
    12 namespace Amg
    \n+
    13 {
    \n+
    14
    \n+
    15 template<std::size_t i>
    \n+\n+
    17 {
    \n+
    18 template<class TT, class T>
    \n+
    19 static void apply(TT tuple, const T& t)
    \n+
    20 {
    \n+
    21 std::get<i-1>(tuple) (t);
    \n+\n+
    23 }
    \n+
    24 };
    \n+
    25 template<>
    \n+
    26 struct ApplyHelper<0>
    \n+
    27 {
    \n+
    28 template<class TT, class T>
    \n+
    29 static void apply([[maybe_unused]] TT tuple, [[maybe_unused]] const T& t)
    \n+
    30 {}
    \n+
    31 };
    \n+
    32
    \n+
    33 template<typename T>
    \n+\n+
    35 public T
    \n+
    36 {
    \n+
    37 public:
    \n+
    38 CombinedFunctor(const T& tuple_)
    \n+
    39 : T(tuple_)
    \n+
    40 {}
    \n+
    41
    \n+
    42 template<class T1>
    \n+
    43 void operator()(const T1& t)
    \n+
    44 {
    \n+\n+
    46 }
    \n+
    47 };
    \n+
    48
    \n
    49
    \n-
    52 class MatrixBlockError : public virtual Dune::FMatrixError {
    \n-
    53 public:
    \n-
    54 int r, c; // row and column index of the entry from which the error resulted
    \n-
    55 };
    \n-
    56
    \n-
    59} // end namespace
    \n-
    60
    \n-
    61#endif
    \n+
    50 } //namespace Amg
    \n+
    51} // namespace Dune
    \n+
    52#endif
    \n
    Definition: allocator.hh:11
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Error specific to BCRSMatrix.
    Definition: istlexception.hh:24
    \n-
    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted.
    Definition: istlexception.hh:37
    \n-
    Thrown when a solver aborts due to some problem.
    Definition: istlexception.hh:46
    \n-
    Error when performing an operation on a matrix block.
    Definition: istlexception.hh:52
    \n-
    int c
    Definition: istlexception.hh:54
    \n-
    int r
    Definition: istlexception.hh:54
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    Definition: combinedfunctor.hh:17
    \n+
    static void apply(TT tuple, const T &t)
    Definition: combinedfunctor.hh:19
    \n+
    static void apply(TT tuple, const T &t)
    Definition: combinedfunctor.hh:29
    \n+
    Definition: combinedfunctor.hh:36
    \n+
    CombinedFunctor(const T &tuple_)
    Definition: combinedfunctor.hh:38
    \n+
    void operator()(const T1 &t)
    Definition: combinedfunctor.hh:43
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,71 +4,89 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-istlexception.hh\n+ * paamg\n+combinedfunctor.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_ISTLEXCEPTION_HH\n- 6#define DUNE_ISTL_ISTLEXCEPTION_HH\n+ 5#ifndef DUNE_AMG_COMBINEDFUNCTOR_HH\n+ 6#define DUNE_AMG_COMBINEDFUNCTOR_HH\n 7\n- 8#include \n- 9#include \n- 10\n- 11namespace Dune {\n- 12\n-19 class ISTLError : public Dune::MathError {};\n- 20\n-22 class BCRSMatrixError\n- 23 : public ISTLError\n- 24 {};\n- 25\n-35 class ImplicitModeCompressionBufferExhausted\n- 36 : public BCRSMatrixError\n- 37 {};\n- 38\n- 40\n-46 class SolverAbort : public ISTLError {};\n- 47\n+ 8#include \n+ 9\n+ 10namespace Dune\n+ 11{\n+ 12 namespace Amg\n+ 13 {\n+ 14\n+ 15 template\n+16 struct ApplyHelper\n+ 17 {\n+ 18 template\n+19 static void apply(TT tuple, const T& t)\n+ 20 {\n+ 21 std::get(tuple) (t);\n+ 22 ApplyHelper::apply(tuple, t);\n+ 23 }\n+ 24 };\n+ 25 template<>\n+26 struct ApplyHelper<0>\n+ 27 {\n+ 28 template\n+29 static void apply([[maybe_unused]] TT tuple, [[maybe_unused]] const T& t)\n+ 30 {}\n+ 31 };\n+ 32\n+ 33 template\n+34 class CombinedFunctor :\n+ 35 public T\n+ 36 {\n+ 37 public:\n+38 CombinedFunctor(const T& tuple_)\n+ 39 : T(tuple_)\n+ 40 {}\n+ 41\n+ 42 template\n+43 void operator()(const T1& t)\n+ 44 {\n+ 45 ApplyHelper::value>::apply(*this, t);\n+ 46 }\n+ 47 };\n+ 48\n 49\n-52 class MatrixBlockError : public virtual Dune::FMatrixError {\n- 53 public:\n-54 int r, c; // row and column index of the entry from which the error resulted\n- 55 };\n- 56\n- 59} // end namespace\n- 60\n- 61#endif\n+ 50 } //namespace Amg\n+ 51} // namespace Dune\n+ 52#endif\n Dune\n Definition: allocator.hh:11\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::BCRSMatrixError\n-Error specific to BCRSMatrix.\n-Definition: istlexception.hh:24\n-Dune::ImplicitModeCompressionBufferExhausted\n-Thrown when the compression buffer used by the implicit BCRSMatrix construction\n-is exhausted.\n-Definition: istlexception.hh:37\n-Dune::SolverAbort\n-Thrown when a solver aborts due to some problem.\n-Definition: istlexception.hh:46\n-Dune::MatrixBlockError\n-Error when performing an operation on a matrix block.\n-Definition: istlexception.hh:52\n-Dune::MatrixBlockError::c\n-int c\n-Definition: istlexception.hh:54\n-Dune::MatrixBlockError::r\n-int r\n-Definition: istlexception.hh:54\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::Amg::ApplyHelper\n+Definition: combinedfunctor.hh:17\n+Dune::Amg::ApplyHelper::apply\n+static void apply(TT tuple, const T &t)\n+Definition: combinedfunctor.hh:19\n+Dune::Amg::ApplyHelper<_0_>::apply\n+static void apply(TT tuple, const T &t)\n+Definition: combinedfunctor.hh:29\n+Dune::Amg::CombinedFunctor\n+Definition: combinedfunctor.hh:36\n+Dune::Amg::CombinedFunctor::CombinedFunctor\n+CombinedFunctor(const T &tuple_)\n+Definition: combinedfunctor.hh:38\n+Dune::Amg::CombinedFunctor::operator()\n+void operator()(const T1 &t)\n+Definition: combinedfunctor.hh:43\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00173.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00173.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ldl.hh File Reference\n+dune-istl: properties.hh File Reference\n \n \n \n \n \n \n \n@@ -58,71 +58,50 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n \n+ \n \n
    \n \n-

    Class for using LDL with ISTL matrices. \n+

    Provides classes for handling internal properties in a graph. \n More...

    \n-
    #include <iostream>
    \n-#include <memory>
    \n-#include <type_traits>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/istl/bccsmatrixinitializer.hh>
    \n-#include <dune/istl/solvers.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n-#include <dune/istl/solverfactory.hh>
    \n+
    #include <dune/common/propertymap.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::LDL< Matrix >
     Use the LDL package to directly solve linear systems – empty default class. More...
    struct  Dune::Amg::VertexVisitedTag
     Tag idnetifying the visited property of a vertex. More...
     
    class  Dune::LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > >
     The LDL direct sparse solver for matrices of type BCRSMatrix. More...
     
    struct  Dune::IsDirectSolver< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::StoresColumnCompressed< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::LDLCreator
     
    struct  Dune::LDLCreator::isValidBlock< F >
     
    struct  Dune::LDLCreator::isValidBlock< FieldVector< double, k > >
    class  Dune::Amg::RandomAccessBundledPropertyMap< C, K, i, T, R >
     A property map that extracts one property out of a bundle using operator[]() More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n+\n+\n

    \n-Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("ldl", Dune::LDLCreator())
     
    namespace  Dune::Amg
     
    \n

    Detailed Description

    \n-

    Class for using LDL with ISTL matrices.

    \n-
    Author
    Marco Agnese, Andrea Sacconi
    \n+

    Provides classes for handling internal properties in a graph.

    \n+
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,58 +4,35 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-ldl.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL)\n-Class for using LDL with ISTL matrices. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+ * paamg\n+Classes | Namespaces\n+properties.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides classes for handling internal properties in a graph. More...\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class\n- \u00a0Dune::LDL<_Matrix_>\n-\u00a0 Use the LDL package to directly solve linear systems \u2013 empty default class.\n- More...\n+struct \u00a0Dune::Amg::VertexVisitedTag\n+\u00a0 Tag idnetifying the visited property of a vertex. More...\n \u00a0\n- class\n- \u00a0Dune::LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n-\u00a0 The LDL direct sparse solver for matrices of type BCRSMatrix. More...\n-\u00a0\n-struct\n- \u00a0Dune::IsDirectSolver<_LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>_>\n-\u00a0\n-struct Dune::StoresColumnCompressed<_LDL<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>_>\n- \u00a0>\n-\u00a0\n-struct\n- \u00a0Dune::LDLCreator\n-\u00a0\n-struct\n- \u00a0Dune::LDLCreator::isValidBlock<_F_>\n-\u00a0\n-struct\n- \u00a0Dune::LDLCreator::isValidBlock<_FieldVector<_double,_k_>_>\n+ class \u00a0Dune::Amg::RandomAccessBundledPropertyMap<_C,_K,_i,_T,_R_>\n+\u00a0 A property map that extracts one property out of a bundle using\n+ operator[]() More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"ldl\", Dune::LDLCreator())\n+namespace \u00a0Dune::Amg\n \u00a0\n ***** Detailed Description *****\n-Class for using LDL with ISTL matrices.\n+Provides classes for handling internal properties in a graph.\n Author\n- Marco Agnese, Andrea Sacconi\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00173_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00173_source.html", "has_internal_linenos": true, "unified_diff": "@@ -21,4704 +21,1015 @@\n 00000140: 6f6e 7465 6e74 3d22 446f 7879 6765 6e20 ontent=\"Doxygen \n 00000150: 312e 392e 3422 2f3e 0a3c 6d65 7461 206e 1.9.4\"/>..<\n 000001a0: 7469 746c 653e 6475 6e65 2d69 7374 6c3a title>dune-istl:\n-000001b0: 206c 646c 2e68 6820 536f 7572 6365 2046 ldl.hh Source F\n-000001c0: 696c 653c 2f74 6974 6c65 3e0a 3c6c 696e ile.......<\n-00000620: 2f73 6372 6970 743e 0a3c 7363 7269 7074 /script>..\n-00000660: 3c73 6372 6970 7420 7479 7065 3d22 7465 .\n+00000630: 3c73 6372 6970 7420 7479 7065 3d22 7465 .\n+00000790: 3c2f 6469 763e 0a3c 212d 2d20 7769 6e64
    ..
    .\n
    \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n
    \n
    \n \n-
    schwarz.hh File Reference
    \n+ \n
    \n
    \n-
    #include <iostream>
    \n-#include <fstream>
    \n-#include <vector>
    \n-#include <sstream>
    \n-#include <cmath>
    \n-#include <dune/common/timer.hh>
    \n-#include "io.hh"
    \n-#include "bvector.hh"
    \n-#include "vbvector.hh"
    \n-#include "bcrsmatrix.hh"
    \n-#include "gsetc.hh"
    \n-#include "ilu.hh"
    \n-#include "operators.hh"
    \n-#include "solvers.hh"
    \n-#include "preconditioners.hh"
    \n-#include "scalarproducts.hh"
    \n-#include "owneroverlapcopy.hh"
    \n+\n+

    Helper classes for the construction of classes without empty constructor. \n+More...

    \n+\n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n \n

    \n Classes

    class  Dune::OverlappingSchwarzOperator< M, X, Y, C >
     An overlapping Schwarz operator. More...
    struct  Dune::Amg::ConstructionTraits< T >
     Traits class for generically constructing non default constructable types. More...
     
    struct  Dune::Amg::ConstructionTraits< BlockVector< T, A > >
     
    struct  Dune::Amg::ParallelOperatorArgs< M, C >
     
    struct  Dune::Amg::OwnerOverlapCopyCommunicationArgs
     
    struct  Dune::Amg::SequentialCommunicationArgs
     
    struct  Dune::Amg::ConstructionTraits< OverlappingSchwarzOperator< M, X, Y, C > >
     
    struct  Dune::Amg::ConstructionTraits< NonoverlappingSchwarzOperator< M, X, Y, C > >
     
    struct  Dune::Amg::MatrixAdapterArgs< M, X, Y >
     
    struct  Dune::Amg::ConstructionTraits< MatrixAdapter< M, X, Y > >
     
    class  Dune::ParSSOR< M, X, Y, C >
     A parallel SSOR preconditioner. More...
    struct  Dune::Amg::ConstructionTraits< SequentialInformation >
     
    class  Dune::BlockPreconditioner< X, Y, C, P >
     Block parallel preconditioner. More...
    struct  Dune::Amg::ConstructionTraits< OwnerOverlapCopyCommunication< T1, T2 > >
     
    \n \n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-
    \n+

    Detailed Description

    \n+

    Helper classes for the construction of classes without empty constructor.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,45 +4,60 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * paamg\n Classes | Namespaces\n-schwarz.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"io.hh\"\n-#include \"bvector.hh\"\n-#include \"vbvector.hh\"\n-#include \"bcrsmatrix.hh\"\n-#include \"gsetc.hh\"\n-#include \"ilu.hh\"\n-#include \"operators.hh\"\n-#include \"solvers.hh\"\n-#include \"preconditioners.hh\"\n-#include \"scalarproducts.hh\"\n-#include \"owneroverlapcopy.hh\"\n+construction.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Helper classes for the construction of classes without empty constructor.\n+More...\n+#include \n+#include \n+#include \n+#include \n+#include \"pinfo.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::OverlappingSchwarzOperator<_M,_X,_Y,_C_>\n-\u00a0 An overlapping Schwarz operator. More...\n+struct \u00a0Dune::Amg::ConstructionTraits<_T_>\n+\u00a0 Traits class for generically constructing non default constructable\n+ types. More...\n \u00a0\n-class \u00a0Dune::ParSSOR<_M,_X,_Y,_C_>\n-\u00a0 A parallel SSOR preconditioner. More...\n+struct \u00a0Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>\n \u00a0\n-class \u00a0Dune::BlockPreconditioner<_X,_Y,_C,_P_>\n-\u00a0 Block parallel preconditioner. More...\n+struct \u00a0Dune::Amg::ParallelOperatorArgs<_M,_C_>\n+\u00a0\n+struct \u00a0Dune::Amg::OwnerOverlapCopyCommunicationArgs\n+\u00a0\n+struct \u00a0Dune::Amg::SequentialCommunicationArgs\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C\n+ >_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,\n+ C_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::MatrixAdapterArgs<_M,_X,_Y_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SequentialInformation_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>\n+ >\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n namespace \u00a0Dune::Amg\n \u00a0\n+***** Detailed Description *****\n+Helper classes for the construction of classes without empty constructor.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00176_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00176_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: schwarz.hh Source File\n+dune-istl: construction.hh Source File\n \n \n \n \n \n \n \n@@ -58,267 +58,219 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    schwarz.hh
    \n+
    construction.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SCHWARZ_HH
    \n-
    6#define DUNE_ISTL_SCHWARZ_HH
    \n+
    5#ifndef DUNE_AMGCONSTRUCTION_HH
    \n+
    6#define DUNE_AMGCONSTRUCTION_HH
    \n
    7
    \n-
    8#include <iostream> // for input/output to shell
    \n-
    9#include <fstream> // for input/output to files
    \n-
    10#include <vector> // STL vector class
    \n-
    11#include <sstream>
    \n-
    12
    \n-
    13#include <cmath> // Yes, we do some math here
    \n-
    14
    \n-
    15#include <dune/common/timer.hh>
    \n-
    16
    \n-
    17#include "io.hh"
    \n-
    18#include "bvector.hh"
    \n-
    19#include "vbvector.hh"
    \n-
    20#include "bcrsmatrix.hh"
    \n-
    21#include "io.hh"
    \n-
    22#include "gsetc.hh"
    \n-
    23#include "ilu.hh"
    \n-
    24#include "operators.hh"
    \n-
    25#include "solvers.hh"
    \n-
    26#include "preconditioners.hh"
    \n-
    27#include "scalarproducts.hh"
    \n-
    28#include "owneroverlapcopy.hh"
    \n-
    29
    \n-
    30namespace Dune {
    \n-
    31
    \n-
    73 template<class M, class X, class Y, class C>
    \n-\n-
    75 {
    \n-
    76 public:
    \n-
    81 typedef M matrix_type;
    \n-
    86 typedef X domain_type;
    \n-
    91 typedef Y range_type;
    \n-
    93 typedef typename X::field_type field_type;
    \n-\n+\n+\n+\n+\n+
    12#include "pinfo.hh"
    \n+
    13
    \n+
    14namespace Dune
    \n+
    15{
    \n+
    16 namespace Amg
    \n+
    17 {
    \n+
    18
    \n+
    37 template<typename T>
    \n+\n+
    39 {
    \n+
    44 typedef const void* Arguments;
    \n+
    45
    \n+
    52 static inline std::shared_ptr<T> construct(Arguments& args)
    \n+
    53 {
    \n+
    54 return std::make_shared<T>();
    \n+
    55 }
    \n+
    56 };
    \n+
    57
    \n+
    58 template<class T, class A>
    \n+\n+
    60 {
    \n+
    61 typedef const int Arguments;
    \n+
    62 static inline std::shared_ptr<BlockVector<T,A>> construct(Arguments& n)
    \n+
    63 {
    \n+
    64 return std::make_shared<BlockVector<T,A>>(n);
    \n+
    65 }
    \n+
    66 };
    \n+
    67
    \n+
    68 template<class M, class C>
    \n+\n+
    70 {
    \n+
    71 ParallelOperatorArgs(std::shared_ptr<M> matrix, const C& comm)
    \n+
    72 : matrix_(matrix), comm_(comm)
    \n+
    73 {}
    \n+
    74
    \n+
    75 std::shared_ptr<M> matrix_;
    \n+
    76 const C& comm_;
    \n+
    77 };
    \n+
    78
    \n+
    79#if HAVE_MPI
    \n+\n+
    81 {
    \n+\n+
    83 : comm_(comm), cat_(cat)
    \n+
    84 {}
    \n+
    85
    \n+
    86 MPI_Comm comm_;
    \n+\n+
    88 };
    \n+
    89#endif
    \n+
    90
    \n+\n+
    92 {
    \n+
    93 SequentialCommunicationArgs(Communication<void*> comm, [[maybe_unused]] int cat)
    \n+
    94 : comm_(comm)
    \n+
    95 {}
    \n+
    96
    \n+
    97 Communication<void*> comm_;
    \n+
    98 };
    \n
    99
    \n-\n-
    108 : _A_(stackobject_to_shared_ptr(A)), communication(com)
    \n-
    109 {}
    \n-
    110
    \n-
    111 OverlappingSchwarzOperator (const std::shared_ptr<matrix_type> A, const communication_type& com)
    \n-
    112 : _A_(A), communication(com)
    \n-
    113 {}
    \n-
    114
    \n-
    116 virtual void apply (const X& x, Y& y) const
    \n-
    117 {
    \n-
    118 y = 0;
    \n-
    119 _A_->umv(x,y); // result is consistent on interior+border
    \n-
    120 communication.project(y); // we want this here to avoid it before the preconditioner
    \n-
    121 // since there d is const!
    \n-
    122 }
    \n-
    123
    \n-
    125 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n-
    126 {
    \n-
    127 _A_->usmv(alpha,x,y); // result is consistent on interior+border
    \n-
    128 communication.project(y); // we want this here to avoid it before the preconditioner
    \n-
    129 // since there d is const!
    \n-
    130 }
    \n-
    131
    \n-
    133 virtual const matrix_type& getmat () const
    \n-
    134 {
    \n-
    135 return *_A_;
    \n-
    136 }
    \n-
    137
    \n-\n-
    140 {
    \n-\n-
    142 }
    \n-
    143
    \n+
    100 } // end Amg namspace
    \n+
    101
    \n+
    102 // forward declaration
    \n+
    103 template<class M, class X, class Y, class C>
    \n+\n+
    105
    \n+
    106 template<class M, class X, class Y, class C>
    \n+\n+
    108
    \n+
    109 namespace Amg
    \n+
    110 {
    \n+
    111 template<class M, class X, class Y, class C>
    \n+\n+
    113 {
    \n+\n+
    115
    \n+
    116 static inline std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C>> construct(const Arguments& args)
    \n+
    117 {
    \n+
    118 return std::make_shared<OverlappingSchwarzOperator<M,X,Y,C>>
    \n+
    119 (args.matrix_, args.comm_);
    \n+
    120 }
    \n+
    121 };
    \n+
    122
    \n+
    123 template<class M, class X, class Y, class C>
    \n+\n+
    125 {
    \n+\n+
    127
    \n+
    128 static inline std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C>> construct(const Arguments& args)
    \n+
    129 {
    \n+
    130 return std::make_shared<NonoverlappingSchwarzOperator<M,X,Y,C>>
    \n+
    131 (args.matrix_, args.comm_);
    \n+
    132 }
    \n+
    133 };
    \n+
    134
    \n+
    135 template<class M, class X, class Y>
    \n+\n+
    137 {
    \n+
    138 MatrixAdapterArgs(std::shared_ptr<M> matrix, const SequentialInformation)
    \n+
    139 : matrix_(matrix)
    \n+
    140 {}
    \n+
    141
    \n+
    142 std::shared_ptr<M> matrix_;
    \n+
    143 };
    \n
    144
    \n-\n-
    147 {
    \n-
    148 return communication;
    \n-
    149 }
    \n-
    150 private:
    \n-
    151 const std::shared_ptr<const matrix_type>_A_;
    \n-
    152 const communication_type& communication;
    \n-
    153 };
    \n-
    154
    \n-
    157 /*
    \n-
    158 * @addtogroup ISTL_Prec
    \n-
    159 * @{
    \n-
    160 */
    \n-
    174 template<class M, class X, class Y, class C>
    \n-
    175 class ParSSOR : public Preconditioner<X,Y> {
    \n-
    176 public:
    \n-
    178 typedef M matrix_type;
    \n-
    180 typedef X domain_type;
    \n-
    182 typedef Y range_type;
    \n-
    184 typedef typename X::field_type field_type;
    \n-\n-
    187
    \n-
    197 ParSSOR (const matrix_type& A, int n, field_type w, const communication_type& c)
    \n-
    198 : _A_(A), _n(n), _w(w), communication(c)
    \n-
    199 { }
    \n-
    200
    \n-
    206 virtual void pre (X& x, [[maybe_unused]] Y& b)
    \n-
    207 {
    \n-
    208 communication.copyOwnerToAll(x,x); // make dirichlet values consistent
    \n-
    209 }
    \n-
    210
    \n-
    216 virtual void apply (X& v, const Y& d)
    \n-
    217 {
    \n-
    218 for (int i=0; i<_n; i++) {
    \n-
    219 bsorf(_A_,v,d,_w);
    \n-
    220 bsorb(_A_,v,d,_w);
    \n-
    221 }
    \n-
    222 communication.copyOwnerToAll(v,v);
    \n-
    223 }
    \n-
    224
    \n-
    230 virtual void post ([[maybe_unused]] X& x) {}
    \n-
    231
    \n-\n-
    234 {
    \n-\n-
    236 }
    \n-
    237
    \n-
    238 private:
    \n-
    240 const matrix_type& _A_;
    \n-
    242 int _n;
    \n-
    244 field_type _w;
    \n-
    246 const communication_type& communication;
    \n-
    247 };
    \n-
    248
    \n-
    249 namespace Amg
    \n-
    250 {
    \n-
    251 template<class T> struct ConstructionTraits;
    \n-
    252 }
    \n-
    253
    \n-
    277 template<class X, class Y, class C, class P=Preconditioner<X,Y> >
    \n-\n-
    279 friend struct Amg::ConstructionTraits<BlockPreconditioner<X,Y,C,P> >;
    \n-
    280 public:
    \n-
    285 typedef X domain_type;
    \n-
    290 typedef Y range_type;
    \n-
    292 typedef typename X::field_type field_type;
    \n-\n-
    298
    \n-\n-
    307 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)
    \n-
    308 { }
    \n-
    309
    \n-
    317 BlockPreconditioner (const std::shared_ptr<P>& p, const communication_type& c)
    \n-
    318 : _preconditioner(p), _communication(c)
    \n-
    319 { }
    \n-
    320
    \n-
    326 virtual void pre (X& x, Y& b)
    \n-
    327 {
    \n-
    328 _communication.copyOwnerToAll(x,x); // make dirichlet values consistent
    \n-
    329 _preconditioner->pre(x,b);
    \n-
    330 }
    \n-
    331
    \n-
    337 virtual void apply (X& v, const Y& d)
    \n-
    338 {
    \n-
    339 _preconditioner->apply(v,d);
    \n-
    340 _communication.copyOwnerToAll(v,v);
    \n-
    341 }
    \n-
    342
    \n-
    343 template<bool forward>
    \n-
    344 void apply (X& v, const Y& d)
    \n-
    345 {
    \n-
    346 _preconditioner->template apply<forward>(v,d);
    \n-
    347 _communication.copyOwnerToAll(v,v);
    \n-
    348 }
    \n-
    349
    \n-
    355 virtual void post (X& x)
    \n-
    356 {
    \n-
    357 _preconditioner->post(x);
    \n-
    358 }
    \n-
    359
    \n-\n-
    362 {
    \n-\n-
    364 }
    \n-
    365
    \n-
    366 private:
    \n-
    368 std::shared_ptr<P> _preconditioner;
    \n-
    369
    \n-
    371 const communication_type& _communication;
    \n-
    372 };
    \n-
    373
    \n-
    376} // end namespace
    \n-
    377
    \n-
    378#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Implementations of the inverse operator interface.
    \n-
    Define general preconditioner interface.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Define base class for scalar product and norm.
    \n-
    The incomplete LU factorization kernels.
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-\n-
    Some generic functions for pretty printing vectors and matrices.
    \n-
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n-
    void bsorb(const M &A, X &x, const Y &b, const K &w)
    SSOR step.
    Definition: gsetc.hh:646
    \n-
    void bsorf(const M &A, X &x, const Y &b, const K &w)
    SOR step.
    Definition: gsetc.hh:634
    \n+
    145 template<class M, class X, class Y>
    \n+\n+
    147 {
    \n+\n+
    149
    \n+
    150 static inline std::shared_ptr<MatrixAdapter<M,X,Y>> construct(Arguments& args)
    \n+
    151 {
    \n+
    152 return std::make_shared<MatrixAdapter<M,X,Y>>(args.matrix_);
    \n+
    153 }
    \n+
    154 };
    \n+
    155
    \n+
    156 template<>
    \n+\n+
    158 {
    \n+\n+
    160 static inline std::shared_ptr<SequentialInformation> construct(Arguments& args)
    \n+
    161 {
    \n+
    162 return std::make_shared<SequentialInformation>(args.comm_);
    \n+
    163 }
    \n+
    164 };
    \n+
    165
    \n+
    166
    \n+
    167#if HAVE_MPI
    \n+
    168
    \n+
    169 template<class T1, class T2>
    \n+\n+
    171 {
    \n+\n+
    173
    \n+
    174 static inline std::shared_ptr<OwnerOverlapCopyCommunication<T1,T2>> construct(Arguments& args)
    \n+
    175 {
    \n+
    176 return std::make_shared<OwnerOverlapCopyCommunication<T1,T2>>(args.comm_, args.cat_);
    \n+
    177 }
    \n+
    178 };
    \n+
    179
    \n+
    180#endif
    \n+
    181
    \n+
    183 } // namespace Amg
    \n+
    184} // namespace Dune
    \n+
    185#endif
    \n+
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+\n+
    const int Arguments
    Definition: construction.hh:61
    \n+
    SequentialCommunicationArgs(Communication< void * > comm, int cat)
    Definition: construction.hh:93
    \n+
    OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category cat)
    Definition: construction.hh:82
    \n+
    MPI_Comm comm_
    Definition: construction.hh:86
    \n+
    SolverCategory::Category cat_
    Definition: construction.hh:87
    \n+
    const C & comm_
    Definition: construction.hh:76
    \n+
    ParallelOperatorArgs(std::shared_ptr< M > matrix, const C &comm)
    Definition: construction.hh:71
    \n+
    std::shared_ptr< M > matrix_
    Definition: construction.hh:75
    \n+
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n+
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n+
    Communication< void * > comm_
    Definition: construction.hh:97
    \n+
    static std::shared_ptr< BlockVector< T, A > > construct(Arguments &n)
    Definition: construction.hh:62
    \n
    Definition: allocator.hh:11
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n-
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n-
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n+
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    Definition: construction.hh:70
    \n+
    Definition: construction.hh:81
    \n+
    Definition: construction.hh:92
    \n
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n-
    const communication_type & getCommunication() const
    Get the object responsible for communication.
    Definition: schwarz.hh:146
    \n-
    virtual const matrix_type & getmat() const
    get the sequential assembled linear operator.
    Definition: schwarz.hh:133
    \n-
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const
    apply operator to x, scale and add:
    Definition: schwarz.hh:125
    \n-
    virtual void apply(const X &x, Y &y) const
    apply operator to x:
    Definition: schwarz.hh:116
    \n-
    C communication_type
    The type of the communication object.
    Definition: schwarz.hh:98
    \n-
    X domain_type
    The type of the domain.
    Definition: schwarz.hh:86
    \n-
    M matrix_type
    The type of the matrix we operate on.
    Definition: schwarz.hh:81
    \n-
    Y range_type
    The type of the range.
    Definition: schwarz.hh:91
    \n-
    X::field_type field_type
    The field type of the range.
    Definition: schwarz.hh:93
    \n-
    OverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)
    constructor: just store a reference to a matrix.
    Definition: schwarz.hh:107
    \n-
    OverlappingSchwarzOperator(const std::shared_ptr< matrix_type > A, const communication_type &com)
    Definition: schwarz.hh:111
    \n-
    virtual SolverCategory::Category category() const
    Category of the linear operator (see SolverCategory::Category)
    Definition: schwarz.hh:139
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n-
    A parallel SSOR preconditioner.
    Definition: schwarz.hh:175
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: schwarz.hh:184
    \n-
    C communication_type
    The type of the communication object.
    Definition: schwarz.hh:186
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: schwarz.hh:233
    \n-
    ParSSOR(const matrix_type &A, int n, field_type w, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:197
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: schwarz.hh:230
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:180
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:182
    \n-
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: schwarz.hh:178
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the precondtioner.
    Definition: schwarz.hh:216
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: schwarz.hh:206
    \n-
    Block parallel preconditioner.
    Definition: schwarz.hh:278
    \n-
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: schwarz.hh:326
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:285
    \n-
    BlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:317
    \n-
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: schwarz.hh:337
    \n-
    BlockPreconditioner(P &p, const communication_type &c)
    Constructor.
    Definition: schwarz.hh:306
    \n-
    void apply(X &v, const Y &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: schwarz.hh:344
    \n-
    C communication_type
    The type of the communication object..
    Definition: schwarz.hh:297
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: schwarz.hh:292
    \n-
    virtual void post(X &x)
    Clean up.
    Definition: schwarz.hh:355
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:290
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: schwarz.hh:361
    \n+
    ParallelOperatorArgs< M, C > Arguments
    Definition: construction.hh:114
    \n+
    static std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > construct(const Arguments &args)
    Definition: construction.hh:116
    \n+
    ParallelOperatorArgs< M, C > Arguments
    Definition: construction.hh:126
    \n+
    static std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > construct(const Arguments &args)
    Definition: construction.hh:128
    \n+
    Definition: construction.hh:137
    \n+
    MatrixAdapterArgs(std::shared_ptr< M > matrix, const SequentialInformation)
    Definition: construction.hh:138
    \n+
    std::shared_ptr< M > matrix_
    Definition: construction.hh:142
    \n+
    static std::shared_ptr< MatrixAdapter< M, X, Y > > construct(Arguments &args)
    Definition: construction.hh:150
    \n+
    const MatrixAdapterArgs< M, X, Y > Arguments
    Definition: construction.hh:148
    \n+
    const SequentialCommunicationArgs Arguments
    Definition: construction.hh:159
    \n+
    static std::shared_ptr< SequentialInformation > construct(Arguments &args)
    Definition: construction.hh:160
    \n+
    static std::shared_ptr< OwnerOverlapCopyCommunication< T1, T2 > > construct(Arguments &args)
    Definition: construction.hh:174
    \n+
    const OwnerOverlapCopyCommunicationArgs Arguments
    Definition: construction.hh:172
    \n+
    Definition: pinfo.hh:28
    \n
    Category
    Definition: solvercategory.hh:23
    \n-
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,408 +4,305 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-schwarz.hh\n+ * paamg\n+construction.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SCHWARZ_HH\n- 6#define DUNE_ISTL_SCHWARZ_HH\n+ 5#ifndef DUNE_AMGCONSTRUCTION_HH\n+ 6#define DUNE_AMGCONSTRUCTION_HH\n 7\n- 8#include // for input/output to shell\n- 9#include // for input/output to files\n- 10#include // STL vector class\n- 11#include \n- 12\n- 13#include // Yes, we do some math here\n- 14\n- 15#include \n- 16\n- 17#include \"io.hh\"\n- 18#include \"bvector.hh\"\n- 19#include \"vbvector.hh\"\n- 20#include \"bcrsmatrix.hh\"\n- 21#include \"io.hh\"\n- 22#include \"gsetc.hh\"\n- 23#include \"ilu.hh\"\n- 24#include \"operators.hh\"\n- 25#include \"solvers.hh\"\n- 26#include \"preconditioners.hh\"\n- 27#include \"scalarproducts.hh\"\n- 28#include \"owneroverlapcopy.hh\"\n- 29\n- 30namespace Dune {\n- 31\n- 73 template\n-74 class OverlappingSchwarzOperator : public AssembledLinearOperator\n- 75 {\n- 76 public:\n-81 typedef M matrix_type;\n-86 typedef X domain_type;\n-91 typedef Y range_type;\n-93 typedef typename X::field_type field_type;\n-98 typedef C communication_type;\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \"pinfo.hh\"\n+ 13\n+ 14namespace Dune\n+ 15{\n+ 16 namespace Amg\n+ 17 {\n+ 18\n+ 37 template\n+38 struct ConstructionTraits\n+ 39 {\n+44 typedef const void* Arguments;\n+ 45\n+52 static inline std::shared_ptr construct(Arguments& args)\n+ 53 {\n+ 54 return std::make_shared();\n+ 55 }\n+ 56 };\n+ 57\n+ 58 template\n+59 struct ConstructionTraits >\n+ 60 {\n+61 typedef const int Arguments;\n+62 static inline std::shared_ptr> construct(Arguments& n)\n+ 63 {\n+ 64 return std::make_shared>(n);\n+ 65 }\n+ 66 };\n+ 67\n+ 68 template\n+69 struct ParallelOperatorArgs\n+ 70 {\n+71 ParallelOperatorArgs(std::shared_ptr matrix, const C& comm)\n+ 72 : matrix_(matrix), comm_(comm)\n+ 73 {}\n+ 74\n+75 std::shared_ptr matrix_;\n+76 const C& comm_;\n+ 77 };\n+ 78\n+ 79#if HAVE_MPI\n+80 struct OwnerOverlapCopyCommunicationArgs\n+ 81 {\n+82 OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category\n+cat)\n+ 83 : comm_(comm), cat_(cat)\n+ 84 {}\n+ 85\n+86 MPI_Comm comm_;\n+87 SolverCategory::Category cat_;\n+ 88 };\n+ 89#endif\n+ 90\n+91 struct SequentialCommunicationArgs\n+ 92 {\n+93 SequentialCommunicationArgs(Communication comm, [[maybe_unused]] int\n+cat)\n+ 94 : comm_(comm)\n+ 95 {}\n+ 96\n+97 Communication comm_;\n+ 98 };\n 99\n-107 OverlappingSchwarzOperator (const matrix_type& A, const communication_type&\n-com)\n- 108 : _A_(stackobject_to_shared_ptr(A)), communication(com)\n- 109 {}\n- 110\n-111 OverlappingSchwarzOperator (const std::shared_ptr A, const\n-communication_type& com)\n- 112 : _A_(A), communication(com)\n- 113 {}\n- 114\n-116 virtual void apply (const X& x, Y& y) const\n+ 100 } // end Amg namspace\n+ 101\n+ 102 // forward declaration\n+ 103 template\n+ 104 class OverlappingSchwarzOperator;\n+ 105\n+ 106 template\n+ 107 class NonoverlappingSchwarzOperator;\n+ 108\n+ 109 namespace Amg\n+ 110 {\n+ 111 template\n+112 struct ConstructionTraits >\n+ 113 {\n+114 typedef ParallelOperatorArgs Arguments;\n+ 115\n+116 static inline std::shared_ptr>\n+construct(const Arguments& args)\n 117 {\n- 118 y = 0;\n- 119 _A_->umv(x,y); // result is consistent on interior+border\n- 120 communication.project(y); // we want this here to avoid it before the\n-preconditioner\n- 121 // since there d is const!\n- 122 }\n- 123\n-125 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n- 126 {\n- 127 _A_->usmv(alpha,x,y); // result is consistent on interior+border\n- 128 communication.project(y); // we want this here to avoid it before the\n-preconditioner\n- 129 // since there d is const!\n- 130 }\n- 131\n-133 virtual const matrix_type& getmat () const\n- 134 {\n- 135 return *_A_;\n- 136 }\n- 137\n-139 virtual SolverCategory::Category category() const\n- 140 {\n- 141 return SolverCategory::overlapping;\n- 142 }\n- 143\n+ 118 return std::make_shared>\n+ 119 (args.matrix_, args.comm_);\n+ 120 }\n+ 121 };\n+ 122\n+ 123 template\n+124 struct ConstructionTraits >\n+ 125 {\n+126 typedef ParallelOperatorArgs Arguments;\n+ 127\n+128 static inline std::shared_ptr>\n+construct(const Arguments& args)\n+ 129 {\n+ 130 return std::make_shared>\n+ 131 (args.matrix_, args.comm_);\n+ 132 }\n+ 133 };\n+ 134\n+ 135 template\n+136 struct MatrixAdapterArgs\n+ 137 {\n+138 MatrixAdapterArgs(std::shared_ptr matrix, const SequentialInformation)\n+ 139 : matrix_(matrix)\n+ 140 {}\n+ 141\n+142 std::shared_ptr matrix_;\n+ 143 };\n 144\n-146 const communication_type& getCommunication() const\n+ 145 template\n+146 struct ConstructionTraits >\n 147 {\n- 148 return communication;\n- 149 }\n- 150 private:\n- 151 const std::shared_ptr_A_;\n- 152 const communication_type& communication;\n- 153 };\n- 154\n- 157 /*\n- 158 * @addtogroup ISTL_Prec\n- 159 * @{\n- 160 */\n- 174 template\n-175 class ParSSOR : public Preconditioner {\n- 176 public:\n-178 typedef M matrix_type;\n-180 typedef X domain_type;\n-182 typedef Y range_type;\n-184 typedef typename X::field_type field_type;\n-186 typedef C communication_type;\n- 187\n-197 ParSSOR (const matrix_type& A, int n, field_type w, const\n-communication_type& c)\n- 198 : _A_(A), _n(n), _w(w), communication(c)\n- 199 { }\n- 200\n-206 virtual void pre (X& x, [[maybe_unused]] Y& b)\n- 207 {\n- 208 communication.copyOwnerToAll(x,x); // make dirichlet values consistent\n- 209 }\n- 210\n-216 virtual void apply (X& v, const Y& d)\n- 217 {\n- 218 for (int i=0; i<_n; i++) {\n- 219 bsorf(_A_,v,d,_w);\n- 220 bsorb(_A_,v,d,_w);\n- 221 }\n- 222 communication.copyOwnerToAll(v,v);\n- 223 }\n- 224\n-230 virtual void post ([[maybe_unused]] X& x) {}\n- 231\n-233 virtual SolverCategory::Category category() const\n- 234 {\n- 235 return SolverCategory::overlapping;\n- 236 }\n- 237\n- 238 private:\n- 240 const matrix_type& _A_;\n- 242 int _n;\n- 244 field_type _w;\n-246 const communication_type& communication;\n- 247 };\n- 248\n- 249 namespace Amg\n- 250 {\n- 251 template struct ConstructionTraits;\n- 252 }\n- 253\n- 277 template >\n-278 class BlockPreconditioner : public Preconditioner {\n- 279 friend struct Amg::ConstructionTraits >;\n- 280 public:\n-285 typedef X domain_type;\n-290 typedef Y range_type;\n-292 typedef typename X::field_type field_type;\n-297 typedef C communication_type;\n- 298\n-306 BlockPreconditioner (P& p, const communication_type& c)\n- 307 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)\n- 308 { }\n- 309\n-317 BlockPreconditioner (const std::shared_ptr

    & p, const communication_type&\n-c)\n- 318 : _preconditioner(p), _communication(c)\n- 319 { }\n- 320\n-326 virtual void pre (X& x, Y& b)\n- 327 {\n- 328 _communication.copyOwnerToAll(x,x); // make dirichlet values consistent\n- 329 _preconditioner->pre(x,b);\n- 330 }\n- 331\n-337 virtual void apply (X& v, const Y& d)\n- 338 {\n- 339 _preconditioner->apply(v,d);\n- 340 _communication.copyOwnerToAll(v,v);\n- 341 }\n- 342\n- 343 template\n-344 void apply (X& v, const Y& d)\n- 345 {\n- 346 _preconditioner->template apply(v,d);\n- 347 _communication.copyOwnerToAll(v,v);\n- 348 }\n- 349\n-355 virtual void post (X& x)\n- 356 {\n- 357 _preconditioner->post(x);\n- 358 }\n- 359\n-361 virtual SolverCategory::Category category() const\n- 362 {\n- 363 return SolverCategory::overlapping;\n- 364 }\n- 365\n- 366 private:\n- 368 std::shared_ptr

    _preconditioner;\n- 369\n- 371 const communication_type& _communication;\n- 372 };\n- 373\n- 376} // end namespace\n- 377\n- 378#endif\n+148 typedef const MatrixAdapterArgs Arguments;\n+ 149\n+150 static inline std::shared_ptr> construct(Arguments&\n+args)\n+ 151 {\n+ 152 return std::make_shared>(args.matrix_);\n+ 153 }\n+ 154 };\n+ 155\n+ 156 template<>\n+157 struct ConstructionTraits\n+ 158 {\n+159 typedef const SequentialCommunicationArgs Arguments;\n+160 static inline std::shared_ptr construct(Arguments&\n+args)\n+ 161 {\n+ 162 return std::make_shared(args.comm_);\n+ 163 }\n+ 164 };\n+ 165\n+ 166\n+ 167#if HAVE_MPI\n+ 168\n+ 169 template\n+170 struct ConstructionTraits >\n+ 171 {\n+172 typedef const OwnerOverlapCopyCommunicationArgs Arguments;\n+ 173\n+174 static inline std::shared_ptr>\n+construct(Arguments& args)\n+ 175 {\n+ 176 return std::make_shared>(args.comm_,\n+args.cat_);\n+ 177 }\n+ 178 };\n+ 179\n+ 180#endif\n+ 181\n+ 183 } // namespace Amg\n+ 184} // namespace Dune\n+ 185#endif\n+owneroverlapcopy.hh\n+Classes providing communication interfaces for overlapping Schwarz methods.\n operators.hh\n Define general, extensible interface for operators. The available\n implementation wraps a matrix.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-preconditioners.hh\n-Define general preconditioner interface.\n bvector.hh\n This file implements a vector space as a tensor product of a given vector\n space. The number of compon...\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n-ilu.hh\n-The incomplete LU factorization kernels.\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-vbvector.hh\n-???\n-io.hh\n-Some generic functions for pretty printing vectors and matrices.\n-gsetc.hh\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way.\n-Dune::bsorb\n-void bsorb(const M &A, X &x, const Y &b, const K &w)\n-SSOR step.\n-Definition: gsetc.hh:646\n-Dune::bsorf\n-void bsorf(const M &A, X &x, const Y &b, const K &w)\n-SOR step.\n-Definition: gsetc.hh:634\n+pinfo.hh\n+solvercategory.hh\n+Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>::Arguments\n+const int Arguments\n+Definition: construction.hh:61\n+Dune::Amg::SequentialCommunicationArgs::SequentialCommunicationArgs\n+SequentialCommunicationArgs(Communication< void * > comm, int cat)\n+Definition: construction.hh:93\n+Dune::Amg::OwnerOverlapCopyCommunicationArgs::OwnerOverlapCopyCommunicationArgs\n+OwnerOverlapCopyCommunicationArgs(MPI_Comm comm, SolverCategory::Category cat)\n+Definition: construction.hh:82\n+Dune::Amg::OwnerOverlapCopyCommunicationArgs::comm_\n+MPI_Comm comm_\n+Definition: construction.hh:86\n+Dune::Amg::OwnerOverlapCopyCommunicationArgs::cat_\n+SolverCategory::Category cat_\n+Definition: construction.hh:87\n+Dune::Amg::ParallelOperatorArgs::comm_\n+const C & comm_\n+Definition: construction.hh:76\n+Dune::Amg::ParallelOperatorArgs::ParallelOperatorArgs\n+ParallelOperatorArgs(std::shared_ptr< M > matrix, const C &comm)\n+Definition: construction.hh:71\n+Dune::Amg::ParallelOperatorArgs::matrix_\n+std::shared_ptr< M > matrix_\n+Definition: construction.hh:75\n+Dune::Amg::ConstructionTraits::Arguments\n+const void * Arguments\n+A type holding all the arguments needed to call the constructor.\n+Definition: construction.hh:44\n+Dune::Amg::ConstructionTraits::construct\n+static std::shared_ptr< T > construct(Arguments &args)\n+Construct an object with the specified arguments.\n+Definition: construction.hh:52\n+Dune::Amg::SequentialCommunicationArgs::comm_\n+Communication< void * > comm_\n+Definition: construction.hh:97\n+Dune::Amg::ConstructionTraits<_BlockVector<_T,_A_>_>::construct\n+static std::shared_ptr< BlockVector< T, A > > construct(Arguments &n)\n+Definition: construction.hh:62\n Dune\n Definition: allocator.hh:11\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::NonoverlappingSchwarzOperator\n+A nonoverlapping operator with communication object.\n+Definition: novlpschwarz.hh:61\n Dune::Amg::ConstructionTraits\n Traits class for generically constructing non default constructable types.\n Definition: construction.hh:39\n-Dune::LinearOperator::field_type\n-X::field_type field_type\n-The field type of the operator.\n-Definition: operators.hh:74\n-Dune::AssembledLinearOperator\n-A linear operator exporting itself in matrix form.\n-Definition: operators.hh:109\n+Dune::MatrixAdapter\n+Adapter to turn a matrix into a linear operator.\n+Definition: operators.hh:137\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::Amg::ParallelOperatorArgs\n+Definition: construction.hh:70\n+Dune::Amg::OwnerOverlapCopyCommunicationArgs\n+Definition: construction.hh:81\n+Dune::Amg::SequentialCommunicationArgs\n+Definition: construction.hh:92\n Dune::OverlappingSchwarzOperator\n An overlapping Schwarz operator.\n Definition: schwarz.hh:75\n-Dune::OverlappingSchwarzOperator::getCommunication\n-const communication_type & getCommunication() const\n-Get the object responsible for communication.\n-Definition: schwarz.hh:146\n-Dune::OverlappingSchwarzOperator::getmat\n-virtual const matrix_type & getmat() const\n-get the sequential assembled linear operator.\n-Definition: schwarz.hh:133\n-Dune::OverlappingSchwarzOperator::applyscaleadd\n-virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const\n-apply operator to x, scale and add:\n-Definition: schwarz.hh:125\n-Dune::OverlappingSchwarzOperator::apply\n-virtual void apply(const X &x, Y &y) const\n-apply operator to x:\n-Definition: schwarz.hh:116\n-Dune::OverlappingSchwarzOperator::communication_type\n-C communication_type\n-The type of the communication object.\n-Definition: schwarz.hh:98\n-Dune::OverlappingSchwarzOperator::domain_type\n-X domain_type\n-The type of the domain.\n-Definition: schwarz.hh:86\n-Dune::OverlappingSchwarzOperator::matrix_type\n-M matrix_type\n-The type of the matrix we operate on.\n-Definition: schwarz.hh:81\n-Dune::OverlappingSchwarzOperator::range_type\n-Y range_type\n-The type of the range.\n-Definition: schwarz.hh:91\n-Dune::OverlappingSchwarzOperator::field_type\n-X::field_type field_type\n-The field type of the range.\n-Definition: schwarz.hh:93\n-Dune::OverlappingSchwarzOperator::OverlappingSchwarzOperator\n-OverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)\n-constructor: just store a reference to a matrix.\n-Definition: schwarz.hh:107\n-Dune::OverlappingSchwarzOperator::OverlappingSchwarzOperator\n-OverlappingSchwarzOperator(const std::shared_ptr< matrix_type > A, const\n-communication_type &com)\n-Definition: schwarz.hh:111\n-Dune::OverlappingSchwarzOperator::category\n-virtual SolverCategory::Category category() const\n-Category of the linear operator (see SolverCategory::Category)\n-Definition: schwarz.hh:139\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::Preconditioner::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: preconditioner.hh:39\n-Dune::ParSSOR\n-A parallel SSOR preconditioner.\n-Definition: schwarz.hh:175\n-Dune::ParSSOR::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: schwarz.hh:184\n-Dune::ParSSOR::communication_type\n-C communication_type\n-The type of the communication object.\n-Definition: schwarz.hh:186\n-Dune::ParSSOR::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: schwarz.hh:233\n-Dune::ParSSOR::ParSSOR\n-ParSSOR(const matrix_type &A, int n, field_type w, const communication_type &c)\n-Constructor.\n-Definition: schwarz.hh:197\n-Dune::ParSSOR::post\n-virtual void post(X &x)\n-Clean up.\n-Definition: schwarz.hh:230\n-Dune::ParSSOR::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: schwarz.hh:180\n-Dune::ParSSOR::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: schwarz.hh:182\n-Dune::ParSSOR::matrix_type\n-M matrix_type\n-The matrix type the preconditioner is for.\n-Definition: schwarz.hh:178\n-Dune::ParSSOR::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the precondtioner.\n-Definition: schwarz.hh:216\n-Dune::ParSSOR::pre\n-virtual void pre(X &x, Y &b)\n-Prepare the preconditioner.\n-Definition: schwarz.hh:206\n-Dune::BlockPreconditioner\n-Block parallel preconditioner.\n-Definition: schwarz.hh:278\n-Dune::BlockPreconditioner::pre\n-virtual void pre(X &x, Y &b)\n-Prepare the preconditioner.\n-Definition: schwarz.hh:326\n-Dune::BlockPreconditioner::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: schwarz.hh:285\n-Dune::BlockPreconditioner::BlockPreconditioner\n-BlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)\n-Constructor.\n-Definition: schwarz.hh:317\n-Dune::BlockPreconditioner::apply\n-virtual void apply(X &v, const Y &d)\n-Apply the preconditioner.\n-Definition: schwarz.hh:337\n-Dune::BlockPreconditioner::BlockPreconditioner\n-BlockPreconditioner(P &p, const communication_type &c)\n-Constructor.\n-Definition: schwarz.hh:306\n-Dune::BlockPreconditioner::apply\n-void apply(X &v, const Y &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: schwarz.hh:344\n-Dune::BlockPreconditioner::communication_type\n-C communication_type\n-The type of the communication object..\n-Definition: schwarz.hh:297\n-Dune::BlockPreconditioner::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: schwarz.hh:292\n-Dune::BlockPreconditioner::post\n-virtual void post(X &x)\n-Clean up.\n-Definition: schwarz.hh:355\n-Dune::BlockPreconditioner::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: schwarz.hh:290\n-Dune::BlockPreconditioner::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: schwarz.hh:361\n+Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n+Arguments\n+ParallelOperatorArgs< M, C > Arguments\n+Definition: construction.hh:114\n+Dune::Amg::ConstructionTraits<_OverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n+construct\n+static std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > construct\n+(const Arguments &args)\n+Definition: construction.hh:116\n+Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n+Arguments\n+ParallelOperatorArgs< M, C > Arguments\n+Definition: construction.hh:126\n+Dune::Amg::ConstructionTraits<_NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>_>::\n+construct\n+static std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > construct\n+(const Arguments &args)\n+Definition: construction.hh:128\n+Dune::Amg::MatrixAdapterArgs\n+Definition: construction.hh:137\n+Dune::Amg::MatrixAdapterArgs::MatrixAdapterArgs\n+MatrixAdapterArgs(std::shared_ptr< M > matrix, const SequentialInformation)\n+Definition: construction.hh:138\n+Dune::Amg::MatrixAdapterArgs::matrix_\n+std::shared_ptr< M > matrix_\n+Definition: construction.hh:142\n+Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>::construct\n+static std::shared_ptr< MatrixAdapter< M, X, Y > > construct(Arguments &args)\n+Definition: construction.hh:150\n+Dune::Amg::ConstructionTraits<_MatrixAdapter<_M,_X,_Y_>_>::Arguments\n+const MatrixAdapterArgs< M, X, Y > Arguments\n+Definition: construction.hh:148\n+Dune::Amg::ConstructionTraits<_SequentialInformation_>::Arguments\n+const SequentialCommunicationArgs Arguments\n+Definition: construction.hh:159\n+Dune::Amg::ConstructionTraits<_SequentialInformation_>::construct\n+static std::shared_ptr< SequentialInformation > construct(Arguments &args)\n+Definition: construction.hh:160\n+Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>_>::\n+construct\n+static std::shared_ptr< OwnerOverlapCopyCommunication< T1, T2 > > construct\n+(Arguments &args)\n+Definition: construction.hh:174\n+Dune::Amg::ConstructionTraits<_OwnerOverlapCopyCommunication<_T1,_T2_>_>::\n+Arguments\n+const OwnerOverlapCopyCommunicationArgs Arguments\n+Definition: construction.hh:172\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n Dune::SolverCategory::Category\n Category\n Definition: solvercategory.hh:23\n-Dune::SolverCategory::overlapping\n-@ overlapping\n-Category for overlapping solvers.\n-Definition: solvercategory.hh:29\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00179.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00179.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: multitypeblockvector.hh File Reference\n+dune-istl: smoother.hh File Reference\n \n \n \n \n \n \n \n@@ -58,64 +58,126 @@\n \n \n \n

    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    multitypeblockvector.hh File Reference
    \n+ \n
    \n
    \n-
    #include <cmath>
    \n-#include <iostream>
    \n-#include <tuple>
    \n-#include <dune/common/dotproduct.hh>
    \n+\n+

    Classes for the generic construction and application of the smoothers. \n+More...

    \n+
    #include <dune/istl/paamg/construction.hh>
    \n+#include <dune/istl/paamg/aggregates.hh>
    \n+#include <dune/istl/preconditioners.hh>
    \n+#include <dune/istl/schwarz.hh>
    \n+#include <dune/istl/novlpschwarz.hh>
    \n+#include <dune/common/propertymap.hh>
    \n #include <dune/common/ftraits.hh>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/std/type_traits.hh>
    \n-#include "istlexception.hh"
    \n-#include "gsetc.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n \n

    \n Classes

    struct  Dune::FieldTraits< MultiTypeBlockVector< Args... > >
    struct  Dune::Amg::DefaultSmootherArgs< T >
     The default class for the smoother arguments. More...
     
    struct  Dune::Amg::SmootherTraits< T >
     Traits class for getting the attribute class of a smoother. More...
     
    struct  Dune::Amg::SmootherTraits< Richardson< X, Y > >
     
    struct  Dune::Amg::SmootherTraits< BlockPreconditioner< X, Y, C, T > >
     
    struct  Dune::Amg::SmootherTraits< NonoverlappingBlockPreconditioner< C, T > >
     
    class  Dune::Amg::DefaultConstructionArgs< T >
     Construction Arguments for the default smoothers. More...
     
    struct  Dune::Amg::ConstructionArgs< T >
     
    class  Dune::Amg::DefaultParallelConstructionArgs< T, C >
     
    class  Dune::Amg::DefaultConstructionArgs< Richardson< X, Y > >
     
    struct  Dune::Amg::ConstructionTraits< SeqSSOR< M, X, Y, l > >
     Policy for the construction of the SeqSSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< SeqSOR< M, X, Y, l > >
     Policy for the construction of the SeqSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< SeqJac< M, X, Y, l > >
     Policy for the construction of the SeqJac smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< Richardson< X, Y > >
     Policy for the construction of the Richardson smoother. More...
     
    class  Dune::Amg::ConstructionArgs< SeqILU< M, X, Y > >
     
    struct  Dune::Amg::ConstructionTraits< SeqILU< M, X, Y > >
     Policy for the construction of the SeqILU smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< ParSSOR< M, X, Y, C > >
     Policy for the construction of the ParSSOR smoother. More...
     
    struct  Dune::Amg::ConstructionTraits< BlockPreconditioner< X, Y, C, T > >
     
    struct  Dune::Amg::ConstructionTraits< NonoverlappingBlockPreconditioner< C, T > >
     
    struct  Dune::Amg::SmootherApplier< T >
     Helper class for applying the smoothers. More...
     
    struct  Dune::Amg::SmootherApplier< SeqSOR< M, X, Y, l > >
     
    struct  Dune::Amg::SmootherApplier< BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > >
     
    struct  Dune::Amg::SmootherApplier< NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > >
     
    struct  Dune::Amg::SmootherApplier< SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > >
     
    struct  Dune::Amg::SeqOverlappingSchwarzSmootherArgs< T >
     
    struct  Dune::Amg::SmootherTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
     
    class  Dune::MultiTypeBlockVector< Args >
     A Vector class to support different block types. More...
    class  Dune::Amg::ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
     
    struct  std::tuple_element< i, Dune::MultiTypeBlockVector< Args... > >
     Make std::tuple_element work for MultiTypeBlockVector. More...
    struct  Dune::Amg::ConstructionTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > >
     
    \n \n \n \n-\n-\n+\n \n

    \n Namespaces

    namespace  Dune
     
    namespace  std
     STL namespace.
    namespace  Dune::Amg
     
    \n \n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<typename... Args>
    std::ostream & Dune::operator<< (std::ostream &s, const MultiTypeBlockVector< Args... > &v)
     Send MultiTypeBlockVector to an outstream. More...
     
    template<typename LevelContext >
    void Dune::Amg::presmooth (LevelContext &levelContext, size_t steps)
     Apply pre smoothing on the current level. More...
     
    template<typename LevelContext >
    void Dune::Amg::postsmooth (LevelContext &levelContext, size_t steps)
     Apply post smoothing on the current level. More...
     
    \n-
    \n+

    Detailed Description

    \n+

    Classes for the generic construction and application of the smoothers.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,44 +4,113 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * paamg\n Classes | Namespaces | Functions\n-multitypeblockvector.hh File Reference\n-#include \n-#include \n-#include \n-#include \n+smoother.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Classes for the generic construction and application of the smoothers. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n #include \n-#include \n-#include \n-#include \n-#include \"istlexception.hh\"\n-#include \"gsetc.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>\n+struct \u00a0Dune::Amg::DefaultSmootherArgs<_T_>\n+\u00a0 The default class for the smoother arguments. More...\n \u00a0\n- class \u00a0Dune::MultiTypeBlockVector<_Args_>\n-\u00a0 A Vector class to support different block types. More...\n+struct \u00a0Dune::Amg::SmootherTraits<_T_>\n+\u00a0 Traits class for getting the attribute class of a smoother. More...\n \u00a0\n-struct \u00a0std::tuple_element<_i,_Dune::MultiTypeBlockVector<_Args..._>_>\n-\u00a0 Make std::tuple_element work for MultiTypeBlockVector. More...\n+struct \u00a0Dune::Amg::SmootherTraits<_Richardson<_X,_Y_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>\n+\u00a0\n+ class \u00a0Dune::Amg::DefaultConstructionArgs<_T_>\n+\u00a0 Construction Arguments for the default smoothers. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionArgs<_T_>\n+\u00a0\n+ class \u00a0Dune::Amg::DefaultParallelConstructionArgs<_T,_C_>\n+\u00a0\n+ class \u00a0Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>\n+\u00a0 Policy for the construction of the SeqSSOR smoother. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>\n+\u00a0 Policy for the construction of the SeqSOR smoother. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>\n+\u00a0 Policy for the construction of the SeqJac smoother. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>\n+\u00a0 Policy for the construction of the Richardson smoother. More...\n+\u00a0\n+ class \u00a0Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>\n+\u00a0 Policy for the construction of the SeqILU smoother. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>\n+\u00a0 Policy for the construction of the ParSSOR smoother. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T\n+ >_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherApplier<_T_>\n+\u00a0 Helper class for applying the smoothers. More...\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,\n+ X,_Y,_l_>_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,\n+ SeqSOR<_M,_X,_Y,_l_>_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+ MultiplicativeSchwarzMode,_MS,_TA_>_>\n+\u00a0\n+struct \u00a0Dune::Amg::SeqOverlappingSchwarzSmootherArgs<_T_>\n+\u00a0\n+struct \u00a0Dune::Amg::SmootherTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>\n+\u00a0\n+ class \u00a0Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>\n+ >\n+\u00a0\n+struct \u00a0Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA\n+ >_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0std\n-\u00a0 STL namespace.\n+namespace \u00a0Dune::Amg\n \u00a0\n Functions\n-template\n-std::ostream &\u00a0Dune::operator<< (std::ostream &s, const MultiTypeBlockVector<\n- Args... > &v)\n-\u00a0 Send MultiTypeBlockVector to an outstream. More...\n-\u00a0\n+template\n+void\u00a0Dune::Amg::presmooth (LevelContext &levelContext, size_t steps)\n+\u00a0 Apply pre smoothing on the current level. More...\n+\u00a0\n+template\n+void\u00a0Dune::Amg::postsmooth (LevelContext &levelContext, size_t steps)\n+\u00a0 Apply post smoothing on the current level. More...\n+\u00a0\n+***** Detailed Description *****\n+Classes for the generic construction and application of the smoothers.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00179_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00179_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: multitypeblockvector.hh Source File\n+dune-istl: smoother.hh Source File\n \n \n \n \n \n \n \n@@ -58,312 +58,960 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    multitypeblockvector.hh
    \n+
    smoother.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
    \n-
    6#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
    \n+
    5#ifndef DUNE_AMGSMOOTHER_HH
    \n+
    6#define DUNE_AMGSMOOTHER_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <iostream>
    \n-
    10#include <tuple>
    \n-
    11
    \n-
    12#include <dune/common/dotproduct.hh>
    \n-
    13#include <dune/common/ftraits.hh>
    \n-
    14#include <dune/common/hybridutilities.hh>
    \n-
    15#include <dune/common/typetraits.hh>
    \n-
    16#include <dune/common/std/type_traits.hh>
    \n-
    17
    \n-
    18#include "istlexception.hh"
    \n-
    19
    \n-
    20// forward declaration
    \n-
    21namespace Dune {
    \n-
    22 template < typename... Args >
    \n-
    23 class MultiTypeBlockVector;
    \n-
    24}
    \n-
    25
    \n-
    26#include "gsetc.hh"
    \n-
    27
    \n-
    28namespace Dune {
    \n-
    29
    \n-
    41 template <typename... Args>
    \n-
    42 struct FieldTraits< MultiTypeBlockVector<Args...> >
    \n-
    43 {
    \n-
    44 using field_type = typename MultiTypeBlockVector<Args...>::field_type;
    \n-
    45 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    46 };
    \n-
    56 template < typename... Args >
    \n-\n-
    58 : public std::tuple<Args...>
    \n-
    59 {
    \n-
    61 typedef std::tuple<Args...> TupleType;
    \n-
    62 public:
    \n-
    63
    \n-
    65 using size_type = std::size_t;
    \n-
    66
    \n-
    70 using TupleType::TupleType;
    \n-
    71
    \n-
    75 typedef MultiTypeBlockVector<Args...> type;
    \n-
    76
    \n-
    82 using field_type = Std::detected_t<std::common_type_t, typename FieldTraits< std::decay_t<Args> >::field_type...>;
    \n-
    83
    \n-
    84 // make sure that we have an std::common_type: using an assertion produces a more readable error message
    \n-
    85 // than a compiler template instantiation error
    \n-
    86 static_assert ( sizeof...(Args) == 0 or not std::is_same_v<field_type, Std::nonesuch>,
    \n-
    87 "No std::common_type implemented for the given field_types of the Args. Please provide an implementation and check that a FieldTraits class is present for your type.");
    \n-
    88
    \n-
    89
    \n-
    95 static constexpr size_type size()
    \n-
    96 {
    \n-
    97 return sizeof...(Args);
    \n-
    98 }
    \n+\n+\n+\n+
    11#include <dune/istl/schwarz.hh>
    \n+\n+
    13#include <dune/common/propertymap.hh>
    \n+
    14#include <dune/common/ftraits.hh>
    \n+
    15
    \n+
    16namespace Dune
    \n+
    17{
    \n+
    18 namespace Amg
    \n+
    19 {
    \n+
    20
    \n+
    36 template<class T>
    \n+\n+
    38 {
    \n+
    42 typedef typename FieldTraits<T>::real_type RelaxationFactor;
    \n+
    43
    \n+\n+\n+
    52
    \n+\n+\n+
    58 {}
    \n+
    59 };
    \n+
    60
    \n+
    64 template<class T>
    \n+\n+
    66 {
    \n+\n+
    68
    \n+
    69 };
    \n+
    70
    \n+
    71 template<class X, class Y>
    \n+\n+
    73 {
    \n+\n+
    75
    \n+
    76 };
    \n+
    77
    \n+
    78 template<class X, class Y, class C, class T>
    \n+\n+
    80 : public SmootherTraits<T>
    \n+
    81 {};
    \n+
    82
    \n+
    83 template<class C, class T>
    \n+\n+
    85 : public SmootherTraits<T>
    \n+
    86 {};
    \n+
    87
    \n+
    91 template<class T>
    \n+\n+
    93 {
    \n+
    94 typedef typename T::matrix_type Matrix;
    \n+
    95
    \n+\n+
    97
    \n+\n
    99
    \n-
    102 static constexpr size_type N()
    \n-
    103 {
    \n-
    104 return sizeof...(Args);
    \n-
    105 }
    \n-
    106
    \n-
    113 [[deprecated("Use method 'N' instead")]]
    \n-
    114 int count() const
    \n-
    115 {
    \n-
    116 return sizeof...(Args);
    \n-
    117 }
    \n+
    100 public:
    \n+\n+
    102 {}
    \n+
    103
    \n+
    104 void setMatrix(const Matrix& matrix)
    \n+
    105 {
    \n+
    106 matrix_=&matrix;
    \n+
    107 }
    \n+
    108 virtual void setMatrix(const Matrix& matrix, [[maybe_unused]] const AggregatesMap& amap)
    \n+
    109 {
    \n+
    110 setMatrix(matrix);
    \n+
    111 }
    \n+
    112
    \n+
    113
    \n+
    114 const Matrix& getMatrix() const
    \n+
    115 {
    \n+
    116 return *matrix_;
    \n+
    117 }
    \n
    118
    \n-\n-
    121 {
    \n-
    122 size_type result = 0;
    \n-
    123 Hybrid::forEach(std::make_index_sequence<N()>{},
    \n-
    124 [&](auto i){result += std::get<i>(*this).dim();});
    \n-
    125
    \n-
    126 return result;
    \n-
    127 }
    \n-
    128
    \n-
    147 template< size_type index >
    \n-
    148 typename std::tuple_element<index,TupleType>::type&
    \n-
    149 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable)
    \n-
    150 {
    \n-
    151 return std::get<index>(*this);
    \n-
    152 }
    \n-
    153
    \n-
    159 template< size_type index >
    \n-
    160 const typename std::tuple_element<index,TupleType>::type&
    \n-
    161 operator[] ([[maybe_unused]] const std::integral_constant< size_type, index > indexVariable) const
    \n-
    162 {
    \n-
    163 return std::get<index>(*this);
    \n-
    164 }
    \n-
    165
    \n-
    168 template<typename T>
    \n-
    169 void operator= (const T& newval) {
    \n-
    170 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
    \n-
    171 entry = newval;
    \n-
    172 });
    \n-
    173 }
    \n-
    174
    \n-
    178 void operator+= (const type& newv) {
    \n-
    179 using namespace Dune::Hybrid;
    \n-
    180 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n-
    181 (*this)[i] += newv[i];
    \n-
    182 });
    \n-
    183 }
    \n-
    184
    \n-
    188 void operator-= (const type& newv) {
    \n-
    189 using namespace Dune::Hybrid;
    \n-
    190 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n-
    191 (*this)[i] -= newv[i];
    \n-
    192 });
    \n-
    193 }
    \n-
    194
    \n-
    196 template<class T,
    \n-
    197 std::enable_if_t< IsNumber<T>::value, int> = 0>
    \n-
    198 void operator*= (const T& w) {
    \n-
    199 Hybrid::forEach(*this, [&](auto&& entry) {
    \n-
    200 entry *= w;
    \n-
    201 });
    \n-
    202 }
    \n-
    203
    \n-
    205 template<class T,
    \n-
    206 std::enable_if_t< IsNumber<T>::value, int> = 0>
    \n-
    207 void operator/= (const T& w) {
    \n-
    208 Hybrid::forEach(*this, [&](auto&& entry) {
    \n-
    209 entry /= w;
    \n-
    210 });
    \n-
    211 }
    \n+
    119 void setArgs(const SmootherArgs& args)
    \n+
    120 {
    \n+
    121 args_=&args;
    \n+
    122 }
    \n+
    123
    \n+
    124 template<class T1>
    \n+
    125 void setComm([[maybe_unused]] T1& comm)
    \n+
    126 {}
    \n+
    127
    \n+\n+
    129 {
    \n+
    130 return comm_;
    \n+
    131 }
    \n+
    132
    \n+
    133 const SmootherArgs getArgs() const
    \n+
    134 {
    \n+
    135 return *args_;
    \n+
    136 }
    \n+
    137
    \n+
    138 protected:
    \n+
    139 const Matrix* matrix_;
    \n+
    140 private:
    \n+
    141 const SmootherArgs* args_;
    \n+\n+
    143 };
    \n+
    144
    \n+
    145 template<class T>
    \n+\n+
    147 : public DefaultConstructionArgs<T>
    \n+
    148 {};
    \n+
    149
    \n+
    150 template<class T, class C=SequentialInformation>
    \n+\n+
    152 : public ConstructionArgs<T>
    \n+
    153 {
    \n+
    154 public:
    \n+\n+
    156 {}
    \n+
    157
    \n+
    158 void setComm(const C& comm)
    \n+
    159 {
    \n+
    160 comm_ = &comm;
    \n+
    161 }
    \n+
    162
    \n+
    163 const C& getComm() const
    \n+
    164 {
    \n+
    165 return *comm_;
    \n+
    166 }
    \n+
    167 private:
    \n+
    168 const C* comm_;
    \n+
    169 };
    \n+
    170
    \n+
    171
    \n+
    172 template<class X, class Y>
    \n+\n+
    174 {
    \n+
    175 typedef Richardson<X,Y> T;
    \n+
    176
    \n+\n+
    178
    \n+
    179 public:
    \n+\n+
    181 {}
    \n+
    182
    \n+
    183 template <class... Args>
    \n+
    184 void setMatrix(const Args&...)
    \n+
    185 {}
    \n+
    186
    \n+
    187 void setArgs(const SmootherArgs& args)
    \n+
    188 {
    \n+
    189 args_=&args;
    \n+
    190 }
    \n+
    191
    \n+
    192 template<class T1>
    \n+
    193 void setComm([[maybe_unused]] T1& comm)
    \n+
    194 {}
    \n+
    195
    \n+\n+
    197 {
    \n+
    198 return comm_;
    \n+
    199 }
    \n+
    200
    \n+
    201 const SmootherArgs getArgs() const
    \n+
    202 {
    \n+
    203 return *args_;
    \n+
    204 }
    \n+
    205
    \n+
    206 private:
    \n+
    207 const SmootherArgs* args_;
    \n+\n+
    209 };
    \n+
    210
    \n+
    211
    \n
    212
    \n-
    213 field_type operator* (const type& newv) const {
    \n-
    214 using namespace Dune::Hybrid;
    \n-
    215 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
    \n-
    216 return a + (*this)[i]*newv[i];
    \n-
    217 });
    \n-
    218 }
    \n-
    219
    \n-
    220 field_type dot (const type& newv) const {
    \n-
    221 using namespace Dune::Hybrid;
    \n-
    222 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
    \n-
    223 return a + (*this)[i].dot(newv[i]);
    \n-
    224 });
    \n-
    225 }
    \n-
    226
    \n-
    229 auto one_norm() const {
    \n-
    230 using namespace Dune::Hybrid;
    \n-
    231 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n-
    232 return a + entry.one_norm();
    \n-
    233 });
    \n-
    234 }
    \n-
    235
    \n-
    238 auto one_norm_real() const {
    \n-
    239 using namespace Dune::Hybrid;
    \n-
    240 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n-
    241 return a + entry.one_norm_real();
    \n-
    242 });
    \n-
    243 }
    \n-
    244
    \n-
    247 typename FieldTraits<field_type>::real_type two_norm2() const {
    \n-
    248 using namespace Dune::Hybrid;
    \n-
    249 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
    \n-
    250 return a + entry.two_norm2();
    \n-
    251 });
    \n-
    252 }
    \n-
    253
    \n-
    256 typename FieldTraits<field_type>::real_type two_norm() const {return sqrt(this->two_norm2());}
    \n-
    257
    \n-
    260 typename FieldTraits<field_type>::real_type infinity_norm() const
    \n-
    261 {
    \n-
    262 using namespace Dune::Hybrid;
    \n-
    263 using std::max;
    \n-
    264 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    265
    \n-
    266 real_type result = 0.0;
    \n-
    267 // Compute max norm tracking appearing nan values
    \n-
    268 // if the field type supports nan.
    \n-
    269 if constexpr (HasNaN<field_type>()) {
    \n-
    270 // This variable will preserve any nan value
    \n-
    271 real_type nanTracker = 1.0;
    \n-
    272 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    273 forEach(*this, [&](auto&& entry) {
    \n-
    274 real_type entryNorm = entry.infinity_norm();
    \n-
    275 result = max(entryNorm, result);
    \n-
    276 nanTracker += entryNorm;
    \n-
    277 });
    \n-
    278 // Incorporate possible nan value into result
    \n-
    279 result *= (nanTracker / nanTracker);
    \n-
    280 } else {
    \n-
    281 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    282 forEach(*this, [&](auto&& entry) {
    \n-
    283 result = max(entry.infinity_norm(), result);
    \n-
    284 });
    \n-
    285 }
    \n-
    286 return result;
    \n-
    287 }
    \n-
    288
    \n-
    291 typename FieldTraits<field_type>::real_type infinity_norm_real() const
    \n-
    292 {
    \n-
    293 using namespace Dune::Hybrid;
    \n-
    294 using std::max;
    \n-
    295 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    296
    \n-
    297 real_type result = 0.0;
    \n-
    298 // Compute max norm tracking appearing nan values
    \n-
    299 // if the field type supports nan.
    \n-
    300 if constexpr (HasNaN<field_type>()) {
    \n-
    301 // This variable will preserve any nan value
    \n-
    302 real_type nanTracker = 1.0;
    \n-
    303 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    304 forEach(*this, [&](auto&& entry) {
    \n-
    305 real_type entryNorm = entry.infinity_norm_real();
    \n-
    306 result = max(entryNorm, result);
    \n-
    307 nanTracker += entryNorm;
    \n-
    308 });
    \n-
    309 // Incorporate possible nan value into result
    \n-
    310 result *= (nanTracker / nanTracker);
    \n-
    311 } else {
    \n-
    312 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n-
    313 forEach(*this, [&](auto&& entry) {
    \n-
    314 result = max(entry.infinity_norm_real(), result);
    \n-
    315 });
    \n-
    316 }
    \n-
    317 return result;
    \n-
    318 }
    \n-
    319
    \n-
    324 template<typename Ta>
    \n-
    325 void axpy (const Ta& a, const type& y) {
    \n-
    326 using namespace Dune::Hybrid;
    \n-
    327 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
    \n-
    328 (*this)[i].axpy(a, y[i]);
    \n-
    329 });
    \n-
    330 }
    \n-
    331
    \n-
    332 };
    \n+
    213 template<class T>
    \n+
    214 struct ConstructionTraits;
    \n+
    215
    \n+
    219 template<class M, class X, class Y, int l>
    \n+
    220 struct ConstructionTraits<SeqSSOR<M,X,Y,l> >
    \n+
    221 {
    \n+\n+
    223
    \n+
    224 static inline std::shared_ptr<SeqSSOR<M,X,Y,l>> construct(Arguments& args)
    \n+
    225 {
    \n+
    226 return std::make_shared<SeqSSOR<M,X,Y,l>>
    \n+
    227 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n+
    228 }
    \n+
    229 };
    \n+
    230
    \n+
    231
    \n+
    235 template<class M, class X, class Y, int l>
    \n+
    236 struct ConstructionTraits<SeqSOR<M,X,Y,l> >
    \n+
    237 {
    \n+\n+
    239
    \n+
    240 static inline std::shared_ptr<SeqSOR<M,X,Y,l>> construct(Arguments& args)
    \n+
    241 {
    \n+
    242 return std::make_shared<SeqSOR<M,X,Y,l>>
    \n+
    243 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n+
    244 }
    \n+
    245 };
    \n+
    246
    \n+
    247
    \n+
    251 template<class M, class X, class Y, int l>
    \n+
    252 struct ConstructionTraits<SeqJac<M,X,Y,l> >
    \n+
    253 {
    \n+\n+
    255
    \n+
    256 static inline std::shared_ptr<SeqJac<M,X,Y,l>> construct(Arguments& args)
    \n+
    257 {
    \n+
    258 return std::make_shared<SeqJac<M,X,Y,l>>
    \n+
    259 (args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor);
    \n+
    260 }
    \n+
    261 };
    \n+
    262
    \n+
    266 template<class X, class Y>
    \n+\n+
    268 {
    \n+\n+
    270
    \n+
    271 static inline std::shared_ptr<Richardson<X,Y>> construct(Arguments& args)
    \n+
    272 {
    \n+
    273 return std::make_shared<Richardson<X,Y>>
    \n+
    274 (args.getArgs().relaxationFactor);
    \n+
    275 }
    \n+
    276 };
    \n+
    277
    \n+
    278
    \n+
    279 template<class M, class X, class Y>
    \n+\n+
    281 : public DefaultConstructionArgs<SeqILU<M,X,Y> >
    \n+
    282 {
    \n+
    283 public:
    \n+\n+
    285 : n_(n)
    \n+
    286 {}
    \n+
    287
    \n+
    288 void setN(int n)
    \n+
    289 {
    \n+
    290 n_ = n;
    \n+
    291 }
    \n+
    292
    \n+
    293 int getN()
    \n+
    294 {
    \n+
    295 return n_;
    \n+
    296 }
    \n+
    297
    \n+
    298 private:
    \n+
    299 int n_;
    \n+
    300 };
    \n+
    301
    \n+
    302
    \n+
    306 template<class M, class X, class Y>
    \n+\n+
    308 {
    \n+\n+
    310
    \n+
    311 static inline std::shared_ptr<SeqILU<M,X,Y>> construct(Arguments& args)
    \n+
    312 {
    \n+
    313 return std::make_shared<SeqILU<M,X,Y>>
    \n+
    314 (args.getMatrix(), args.getN(), args.getArgs().relaxationFactor);
    \n+
    315 }
    \n+
    316 };
    \n+
    317
    \n+
    321 template<class M, class X, class Y, class C>
    \n+
    322 struct ConstructionTraits<ParSSOR<M,X,Y,C> >
    \n+
    323 {
    \n+\n+
    325
    \n+
    326 static inline std::shared_ptr<ParSSOR<M,X,Y,C>> construct(Arguments& args)
    \n+
    327 {
    \n+
    328 return std::make_shared<ParSSOR<M,X,Y,C>>
    \n+
    329 (args.getMatrix(), args.getArgs().iterations,
    \n+
    330 args.getArgs().relaxationFactor, args.getComm());
    \n+
    331 }
    \n+
    332 };
    \n
    333
    \n-
    334
    \n-
    335
    \n-
    338 template <typename... Args>
    \n-
    339 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockVector<Args...>& v) {
    \n-
    340 using namespace Dune::Hybrid;
    \n-
    341 forEach(integralRange(Dune::Hybrid::size(v)), [&](auto&& i) {
    \n-
    342 s << "\\t(" << i << "):\\n" << v[i] << "\\n";
    \n-
    343 });
    \n-
    344 return s;
    \n-
    345 }
    \n-
    346
    \n-
    347} // end namespace Dune
    \n-
    348
    \n-
    349namespace std
    \n-
    350{
    \n-
    355 template <size_t i, typename... Args>
    \n-
    356 struct tuple_element<i,Dune::MultiTypeBlockVector<Args...> >
    \n-
    357 {
    \n-
    358 using type = typename std::tuple_element<i, std::tuple<Args...> >::type;
    \n-
    359 };
    \n-
    360}
    \n-
    361
    \n-
    362#endif
    \n-\n-
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n-
    void operator=(const T &newval)
    Assignment operator.
    Definition: multitypeblockvector.hh:169
    \n-
    std::size_t size_type
    Type used for vector sizes.
    Definition: multitypeblockvector.hh:65
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: multitypeblockvector.hh:45
    \n-
    int count() const
    Definition: multitypeblockvector.hh:114
    \n-
    static constexpr size_type N()
    Number of elements.
    Definition: multitypeblockvector.hh:102
    \n-
    Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args > >::field_type... > field_type
    The type used for scalars.
    Definition: multitypeblockvector.hh:82
    \n-
    static constexpr size_type size()
    Return the number of non-zero vector entries.
    Definition: multitypeblockvector.hh:95
    \n-
    std::tuple_element< index, TupleType >::type & operator[](const std::integral_constant< size_type, index > indexVariable)
    Random-access operator.
    Definition: multitypeblockvector.hh:149
    \n-
    FieldTraits< field_type >::real_type two_norm() const
    Compute the Euclidean norm.
    Definition: multitypeblockvector.hh:256
    \n-
    typename MultiTypeBlockVector< Args... >::field_type field_type
    Definition: multitypeblockvector.hh:44
    \n-
    size_type dim() const
    Number of scalar elements.
    Definition: multitypeblockvector.hh:120
    \n-
    field_type dot(const type &newv) const
    Definition: multitypeblockvector.hh:220
    \n-
    void operator*=(const T &w)
    Multiplication with a scalar.
    Definition: multitypeblockvector.hh:198
    \n-
    void axpy(const Ta &a, const type &y)
    Axpy operation on this vector (*this += a * y)
    Definition: multitypeblockvector.hh:325
    \n-
    void operator/=(const T &w)
    Division by a scalar.
    Definition: multitypeblockvector.hh:207
    \n-
    MultiTypeBlockVector< Args... > type
    Definition: multitypeblockvector.hh:75
    \n-
    FieldTraits< field_type >::real_type infinity_norm_real() const
    Compute the simplified maximum norm (uses 1-norm for complex values)
    Definition: multitypeblockvector.hh:291
    \n-
    auto one_norm() const
    Compute the 1-norm.
    Definition: multitypeblockvector.hh:229
    \n-
    void operator-=(const type &newv)
    Definition: multitypeblockvector.hh:188
    \n-
    field_type operator*(const type &newv) const
    Definition: multitypeblockvector.hh:213
    \n-
    void operator+=(const type &newv)
    Definition: multitypeblockvector.hh:178
    \n-
    typename std::tuple_element< i, std::tuple< Args... > >::type type
    Definition: multitypeblockvector.hh:358
    \n-
    FieldTraits< field_type >::real_type infinity_norm() const
    Compute the maximum norm.
    Definition: multitypeblockvector.hh:260
    \n-
    auto one_norm_real() const
    Compute the simplified 1-norm (uses 1-norm also for complex values)
    Definition: multitypeblockvector.hh:238
    \n-
    FieldTraits< field_type >::real_type two_norm2() const
    Compute the squared Euclidean norm.
    Definition: multitypeblockvector.hh:247
    \n-
    STL namespace.
    \n+
    334 template<class X, class Y, class C, class T>
    \n+\n+
    336 {
    \n+\n+\n+
    339 static inline std::shared_ptr<BlockPreconditioner<X,Y,C,T>> construct(Arguments& args)
    \n+
    340 {
    \n+
    341 auto seqPrec = SeqConstructionTraits::construct(args);
    \n+
    342 return std::make_shared<BlockPreconditioner<X,Y,C,T>> (seqPrec, args.getComm());
    \n+
    343 }
    \n+
    344 };
    \n+
    345
    \n+
    346 template<class C, class T>
    \n+\n+
    348 {
    \n+\n+\n+
    351 static inline std::shared_ptr<NonoverlappingBlockPreconditioner<C,T>> construct(Arguments& args)
    \n+
    352 {
    \n+
    353 auto seqPrec = SeqConstructionTraits::construct(args);
    \n+
    354 return std::make_shared<NonoverlappingBlockPreconditioner<C,T>> (seqPrec, args.getComm());
    \n+
    355 }
    \n+
    356 };
    \n+
    357
    \n+
    368 template<class T>
    \n+\n+
    370 {
    \n+
    371 typedef T Smoother;
    \n+
    372 typedef typename Smoother::range_type Range;
    \n+
    373 typedef typename Smoother::domain_type Domain;
    \n+
    374
    \n+
    382 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n+
    383 {
    \n+
    384 smoother.apply(v,d);
    \n+
    385 }
    \n+
    386
    \n+
    394 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n+
    395 {
    \n+
    396 smoother.apply(v,d);
    \n+
    397 }
    \n+
    398 };
    \n+
    399
    \n+
    405 template<typename LevelContext>
    \n+
    406 void presmooth(LevelContext& levelContext, size_t steps)
    \n+
    407 {
    \n+
    408 for(std::size_t i=0; i < steps; ++i) {
    \n+
    409 *levelContext.lhs=0;
    \n+\n+
    411 ::preSmooth(*levelContext.smoother, *levelContext.lhs,
    \n+
    412 *levelContext.rhs);
    \n+
    413 // Accumulate update
    \n+
    414 *levelContext.update += *levelContext.lhs;
    \n+
    415
    \n+
    416 // update defect
    \n+
    417 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs, *levelContext.rhs);
    \n+
    418 levelContext.pinfo->project(*levelContext.rhs);
    \n+
    419 }
    \n+
    420 }
    \n+
    421
    \n+
    427 template<typename LevelContext>
    \n+
    428 void postsmooth(LevelContext& levelContext, size_t steps)
    \n+
    429 {
    \n+
    430 for(std::size_t i=0; i < steps; ++i) {
    \n+
    431 // update defect
    \n+
    432 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,
    \n+
    433 *levelContext.rhs);
    \n+
    434 *levelContext.lhs=0;
    \n+
    435 levelContext.pinfo->project(*levelContext.rhs);
    \n+\n+
    437 ::postSmooth(*levelContext.smoother, *levelContext.lhs, *levelContext.rhs);
    \n+
    438 // Accumulate update
    \n+
    439 *levelContext.update += *levelContext.lhs;
    \n+
    440 }
    \n+
    441 }
    \n+
    442
    \n+
    443 template<class M, class X, class Y, int l>
    \n+
    444 struct SmootherApplier<SeqSOR<M,X,Y,l> >
    \n+
    445 {
    \n+\n+
    447 typedef typename Smoother::range_type Range;
    \n+\n+
    449
    \n+
    450 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    451 {
    \n+
    452 smoother.template apply<true>(v,d);
    \n+
    453 }
    \n+
    454
    \n+
    455
    \n+
    456 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    457 {
    \n+
    458 smoother.template apply<false>(v,d);
    \n+
    459 }
    \n+
    460 };
    \n+
    461
    \n+
    462 template<class M, class X, class Y, class C, int l>
    \n+\n+
    464 {
    \n+\n+
    466 typedef typename Smoother::range_type Range;
    \n+\n+
    468
    \n+
    469 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    470 {
    \n+
    471 smoother.template apply<true>(v,d);
    \n+
    472 }
    \n+
    473
    \n+
    474
    \n+
    475 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    476 {
    \n+
    477 smoother.template apply<false>(v,d);
    \n+
    478 }
    \n+
    479 };
    \n+
    480
    \n+
    481 template<class M, class X, class Y, class C, int l>
    \n+\n+
    483 {
    \n+\n+
    485 typedef typename Smoother::range_type Range;
    \n+\n+
    487
    \n+
    488 static void preSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    489 {
    \n+
    490 smoother.template apply<true>(v,d);
    \n+
    491 }
    \n+
    492
    \n+
    493
    \n+
    494 static void postSmooth(Smoother& smoother, Domain& v, Range& d)
    \n+
    495 {
    \n+
    496 smoother.template apply<false>(v,d);
    \n+
    497 }
    \n+
    498 };
    \n+
    499
    \n+
    500 } // end namespace Amg
    \n+
    501
    \n+
    502 // forward declarations
    \n+
    503 template<class M, class X, class MO, class MS, class A>
    \n+
    504 class SeqOverlappingSchwarz;
    \n+
    505
    \n+
    506 struct MultiplicativeSchwarzMode;
    \n+
    507
    \n+
    508 namespace Amg
    \n+
    509 {
    \n+
    510 template<class M, class X, class MS, class TA>
    \n+\n+
    512 MS,TA> >
    \n+
    513 {
    \n+\n+
    515 typedef typename Smoother::range_type Range;
    \n+\n+
    517
    \n+
    518 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n+
    519 {
    \n+
    520 smoother.template apply<true>(v,d);
    \n+
    521 }
    \n+
    522
    \n+
    523
    \n+
    524 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)
    \n+
    525 {
    \n+
    526 smoother.template apply<false>(v,d);
    \n+
    527
    \n+
    528 }
    \n+
    529 };
    \n+
    530
    \n+
    531 // template<class M, class X, class TM, class TA>
    \n+
    532 // class SeqOverlappingSchwarz;
    \n+
    533
    \n+
    534 template<class T>
    \n+\n+
    536 : public DefaultSmootherArgs<T>
    \n+
    537 {
    \n+\n+
    539
    \n+\n+\n+
    542
    \n+\n+
    544 bool onthefly_=false)
    \n+
    545 : overlap(overlap_), onthefly(onthefly_)
    \n+
    546 {}
    \n+
    547 };
    \n+
    548
    \n+
    549 template<class M, class X, class TM, class TS, class TA>
    \n+\n+
    551 {
    \n+\n+
    553 };
    \n+
    554
    \n+
    555 template<class M, class X, class TM, class TS, class TA>
    \n+\n+
    557 : public DefaultConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
    \n+
    558 {
    \n+\n+
    560
    \n+
    561 public:
    \n+\n+\n+\n+\n+
    566 typedef typename Vector::value_type Subdomain;
    \n+
    567
    \n+
    568 virtual void setMatrix(const M& matrix, const AggregatesMap& amap)
    \n+
    569 {
    \n+
    570 Father::setMatrix(matrix);
    \n+
    571
    \n+
    572 std::vector<bool> visited(amap.noVertices(), false);
    \n+
    573 typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
    \n+
    574 VisitedMapType visitedMap(visited.begin());
    \n+
    575
    \n+
    576 MatrixGraph<const M> graph(matrix);
    \n+
    577
    \n+\n+
    579
    \n+
    580 switch(Father::getArgs().overlap) {
    \n+
    581 case SmootherArgs::vertex :
    \n+
    582 {
    \n+
    583 VertexAdder visitor(subdomains, amap);
    \n+
    584 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    585 }
    \n+
    586 break;
    \n+
    587 case SmootherArgs::pairwise :
    \n+
    588 {
    \n+
    589 createPairDomains(graph);
    \n+
    590 }
    \n+
    591 break;
    \n+
    592 case SmootherArgs::aggregate :
    \n+
    593 {
    \n+
    594 AggregateAdder<VisitedMapType> visitor(subdomains, amap, graph, visitedMap);
    \n+
    595 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    596 }
    \n+
    597 break;
    \n+
    598 case SmootherArgs::none :
    \n+
    599 NoneAdder visitor;
    \n+
    600 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    601 break;
    \n+
    602 default :
    \n+
    603 DUNE_THROW(NotImplemented, "This overlapping scheme is not supported!");
    \n+
    604 }
    \n+
    605 }
    \n+
    606 void setMatrix(const M& matrix)
    \n+
    607 {
    \n+
    608 Father::setMatrix(matrix);
    \n+
    609
    \n+
    610 /* Create aggregates map where each aggregate is just one vertex. */
    \n+
    611 AggregatesMap amap(matrix.N());
    \n+\n+
    613 for(typename AggregatesMap::iterator iter=amap.begin();
    \n+
    614 iter!=amap.end(); ++iter)
    \n+
    615 *iter=v++;
    \n+
    616
    \n+
    617 std::vector<bool> visited(amap.noVertices(), false);
    \n+
    618 typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
    \n+
    619 VisitedMapType visitedMap(visited.begin());
    \n+
    620
    \n+
    621 MatrixGraph<const M> graph(matrix);
    \n+
    622
    \n+\n+
    624
    \n+
    625 switch(Father::getArgs().overlap) {
    \n+
    626 case SmootherArgs::vertex :
    \n+
    627 {
    \n+
    628 VertexAdder visitor(subdomains, amap);
    \n+
    629 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    630 }
    \n+
    631 break;
    \n+
    632 case SmootherArgs::aggregate :
    \n+
    633 {
    \n+
    634 DUNE_THROW(NotImplemented, "Aggregate overlap is not supported yet");
    \n+
    635 /*
    \n+
    636 AggregateAdder<VisitedMapType> visitor(subdomains, amap, graph, visitedMap);
    \n+
    637 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    638 */
    \n+
    639 }
    \n+
    640 break;
    \n+
    641 case SmootherArgs::pairwise :
    \n+
    642 {
    \n+
    643 createPairDomains(graph);
    \n+
    644 }
    \n+
    645 break;
    \n+
    646 case SmootherArgs::none :
    \n+
    647 NoneAdder visitor;
    \n+
    648 createSubdomains(matrix, graph, amap, visitor, visitedMap);
    \n+
    649
    \n+
    650 }
    \n+
    651 }
    \n+
    652
    \n+\n+
    654 {
    \n+
    655 return subdomains;
    \n+
    656 }
    \n+
    657
    \n+
    658 private:
    \n+
    659 struct VertexAdder
    \n+
    660 {
    \n+
    661 VertexAdder(Vector& subdomains_, const AggregatesMap& aggregates_)
    \n+
    662 : subdomains(subdomains_), max(-1), subdomain(-1), aggregates(aggregates_)
    \n+
    663 {}
    \n+
    664 template<class T>
    \n+
    665 void operator()(const T& edge)
    \n+
    666 {
    \n+
    667 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED)
    \n+
    668 subdomains[subdomain].insert(edge.target());
    \n+
    669 }
    \n+
    670 int setAggregate(const AggregateDescriptor& aggregate_)
    \n+
    671 {
    \n+
    672 subdomain=aggregate_;
    \n+
    673 max = std::max(subdomain, aggregate_);
    \n+
    674 return subdomain;
    \n+
    675 }
    \n+
    676 int noSubdomains() const
    \n+
    677 {
    \n+
    678 return max+1;
    \n+
    679 }
    \n+
    680 private:
    \n+
    681 Vector& subdomains;
    \n+\n+
    683 AggregateDescriptor subdomain;
    \n+
    684 const AggregatesMap& aggregates;
    \n+
    685 };
    \n+
    686 struct NoneAdder
    \n+
    687 {
    \n+
    688 template<class T>
    \n+
    689 void operator()(const T& edge)
    \n+
    690 {}
    \n+
    691 int setAggregate(const AggregateDescriptor& aggregate_)
    \n+
    692 {
    \n+
    693 return -1;
    \n+
    694 }
    \n+
    695 int noSubdomains() const
    \n+
    696 {
    \n+
    697 return -1;
    \n+
    698 }
    \n+
    699 };
    \n+
    700
    \n+
    701 template<class VM>
    \n+
    702 struct AggregateAdder
    \n+
    703 {
    \n+
    704 AggregateAdder(Vector& subdomains_, const AggregatesMap& aggregates_,
    \n+
    705 const MatrixGraph<const M>& graph_, VM& visitedMap_)
    \n+
    706 : subdomains(subdomains_), subdomain(-1), aggregates(aggregates_),
    \n+
    707 adder(subdomains_, aggregates_), graph(graph_), visitedMap(visitedMap_)
    \n+
    708 {}
    \n+
    709 template<class T>
    \n+
    710 void operator()(const T& edge)
    \n+
    711 {
    \n+
    712 subdomains[subdomain].insert(edge.target());
    \n+
    713 // If we (the neighbouring vertex of the aggregate)
    \n+
    714 // are not isolated, add the aggregate we belong to
    \n+
    715 // to the same subdomain using the OneOverlapAdder
    \n+
    716 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED) {
    \n+
    717 assert(aggregates[edge.target()]!=aggregate);
    \n+
    718 typename AggregatesMap::VertexList vlist;
    \n+
    719 aggregates.template breadthFirstSearch<true,false>(edge.target(), aggregate,
    \n+
    720 graph, vlist, adder, adder,
    \n+
    721 visitedMap);
    \n+
    722 }
    \n+
    723 }
    \n+
    724
    \n+
    725 int setAggregate(const AggregateDescriptor& aggregate_)
    \n+
    726 {
    \n+
    727 adder.setAggregate(aggregate_);
    \n+
    728 aggregate=aggregate_;
    \n+
    729 return ++subdomain;
    \n+
    730 }
    \n+
    731 int noSubdomains() const
    \n+
    732 {
    \n+
    733 return subdomain+1;
    \n+
    734 }
    \n+
    735
    \n+
    736 private:
    \n+
    737 AggregateDescriptor aggregate;
    \n+
    738 Vector& subdomains;
    \n+
    739 int subdomain;
    \n+
    740 const AggregatesMap& aggregates;
    \n+
    741 VertexAdder adder;
    \n+
    742 const MatrixGraph<const M>& graph;
    \n+
    743 VM& visitedMap;
    \n+
    744 };
    \n+
    745
    \n+
    746 void createPairDomains(const MatrixGraph<const M>& graph)
    \n+
    747 {
    \n+
    748 typedef typename MatrixGraph<const M>::ConstVertexIterator VIter;
    \n+
    749 typedef typename MatrixGraph<const M>::ConstEdgeIterator EIter;
    \n+
    750 typedef typename M::size_type size_type;
    \n+
    751
    \n+
    752 std::set<std::pair<size_type,size_type> > pairs;
    \n+
    753 int total=0;
    \n+
    754 for(VIter v=graph.begin(), ve=graph.end(); ve != v; ++v)
    \n+
    755 for(EIter e = v.begin(), ee=v.end(); ee!=e; ++e)
    \n+
    756 {
    \n+
    757 ++total;
    \n+
    758 if(e.source()<e.target())
    \n+
    759 pairs.insert(std::make_pair(e.source(),e.target()));
    \n+
    760 else
    \n+
    761 pairs.insert(std::make_pair(e.target(),e.source()));
    \n+
    762 }
    \n+
    763
    \n+
    764
    \n+
    765 subdomains.resize(pairs.size());
    \n+
    766 Dune::dinfo <<std::endl<< "Created "<<pairs.size()<<" ("<<total<<") pair domains"<<std::endl<<std::endl;
    \n+
    767 typedef typename std::set<std::pair<size_type,size_type> >::const_iterator SIter;
    \n+
    768 typename Vector::iterator subdomain=subdomains.begin();
    \n+
    769
    \n+
    770 for(SIter s=pairs.begin(), se =pairs.end(); se!=s; ++s)
    \n+
    771 {
    \n+
    772 subdomain->insert(s->first);
    \n+
    773 subdomain->insert(s->second);
    \n+
    774 ++subdomain;
    \n+
    775 }
    \n+
    776 std::size_t minsize=10000;
    \n+
    777 std::size_t maxsize=0;
    \n+
    778 int sum=0;
    \n+
    779 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {
    \n+
    780 sum+=subdomains[i].size();
    \n+
    781 minsize=std::min(minsize, subdomains[i].size());
    \n+
    782 maxsize=std::max(maxsize, subdomains[i].size());
    \n+
    783 }
    \n+
    784 Dune::dinfo<<"Subdomain size: min="<<minsize<<" max="<<maxsize<<" avg="<<(sum/subdomains.size())
    \n+
    785 <<" no="<<subdomains.size()<<std::endl;
    \n+
    786 }
    \n+
    787
    \n+
    788 template<class Visitor>
    \n+
    789 void createSubdomains(const M& matrix, const MatrixGraph<const M>& graph,
    \n+
    790 const AggregatesMap& amap, Visitor& overlapVisitor,
    \n+
    791 IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap>& visitedMap )
    \n+
    792 {
    \n+
    793 // count number ag aggregates. We assume that the
    \n+
    794 // aggregates are numbered consecutively from 0 except
    \n+
    795 // for the isolated ones. All isolated vertices form
    \n+
    796 // one aggregate, here.
    \n+
    797 int isolated=0;
    \n+
    798 AggregateDescriptor maxAggregate=0;
    \n+
    799
    \n+
    800 for(std::size_t i=0; i < amap.noVertices(); ++i)
    \n+
    801 if(amap[i]==AggregatesMap::ISOLATED)
    \n+
    802 isolated++;
    \n+
    803 else
    \n+
    804 maxAggregate = std::max(maxAggregate, amap[i]);
    \n+
    805
    \n+
    806 subdomains.resize(maxAggregate+1+isolated);
    \n+
    807
    \n+
    808 // reset the subdomains
    \n+
    809 for(typename Vector::size_type i=0; i < subdomains.size(); ++i)
    \n+
    810 subdomains[i].clear();
    \n+
    811
    \n+
    812 // Create the subdomains from the aggregates mapping.
    \n+
    813 // For each aggregate we mark all entries and the
    \n+
    814 // neighbouring vertices as belonging to the same subdomain
    \n+
    815 VertexAdder aggregateVisitor(subdomains, amap);
    \n+
    816
    \n+
    817 for(VertexDescriptor i=0; i < amap.noVertices(); ++i)
    \n+
    818 if(!get(visitedMap, i)) {
    \n+
    819 AggregateDescriptor aggregate=amap[i];
    \n+
    820
    \n+
    821 if(amap[i]==AggregatesMap::ISOLATED) {
    \n+
    822 // isolated vertex gets its own aggregate
    \n+
    823 subdomains.push_back(Subdomain());
    \n+
    824 aggregate=subdomains.size()-1;
    \n+
    825 }
    \n+
    826 overlapVisitor.setAggregate(aggregate);
    \n+
    827 aggregateVisitor.setAggregate(aggregate);
    \n+
    828 subdomains[aggregate].insert(i);
    \n+
    829 typename AggregatesMap::VertexList vlist;
    \n+
    830 amap.template breadthFirstSearch<false,false>(i, aggregate, graph, vlist, aggregateVisitor,
    \n+
    831 overlapVisitor, visitedMap);
    \n+
    832 }
    \n+
    833
    \n+
    834 std::size_t minsize=10000;
    \n+
    835 std::size_t maxsize=0;
    \n+
    836 int sum=0;
    \n+
    837 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {
    \n+
    838 sum+=subdomains[i].size();
    \n+
    839 minsize=std::min(minsize, subdomains[i].size());
    \n+
    840 maxsize=std::max(maxsize, subdomains[i].size());
    \n+
    841 }
    \n+
    842 Dune::dinfo<<"Subdomain size: min="<<minsize<<" max="<<maxsize<<" avg="<<(sum/subdomains.size())
    \n+
    843 <<" no="<<subdomains.size()<<" isolated="<<isolated<<std::endl;
    \n+
    844
    \n+
    845
    \n+
    846
    \n+
    847 }
    \n+
    848 Vector subdomains;
    \n+
    849 };
    \n+
    850
    \n+
    851
    \n+
    852 template<class M, class X, class TM, class TS, class TA>
    \n+\n+
    854 {
    \n+\n+
    856
    \n+
    857 static inline std::shared_ptr<SeqOverlappingSchwarz<M,X,TM,TS,TA>> construct(Arguments& args)
    \n+
    858 {
    \n+
    859 return std::make_shared<SeqOverlappingSchwarz<M,X,TM,TS,TA>>
    \n+
    860 (args.getMatrix(),
    \n+
    861 args.getSubDomains(),
    \n+\n+
    863 args.getArgs().onthefly);
    \n+
    864 }
    \n+
    865 };
    \n+
    866
    \n+
    867
    \n+
    868 } // namespace Amg
    \n+
    869} // namespace Dune
    \n+
    870
    \n+
    871
    \n+
    872
    \n+
    873#endif
    \n+\n+\n+
    Provides classes for the Coloring process of AMG.
    \n+
    Helper classes for the construction of classes without empty constructor.
    \n+
    Define general preconditioner interface.
    \n+
    DefaultSmootherArgs< typename X::field_type > Arguments
    Definition: smoother.hh:74
    \n+
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:494
    \n+\n+
    static void preSmooth(Smoother &smoother, Domain &v, const Range &d)
    Definition: smoother.hh:518
    \n+
    static std::shared_ptr< SeqJac< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:256
    \n+
    ConstructionArgs< SeqILU< M, X, Y > > Arguments
    Definition: smoother.hh:309
    \n+
    const Matrix & getMatrix() const
    Definition: smoother.hh:114
    \n+\n+
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:691
    \n+
    DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments
    Definition: smoother.hh:67
    \n+
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:670
    \n+
    ConstructionTraits< T > SeqConstructionTraits
    Definition: smoother.hh:350
    \n+
    void setArgs(const SmootherArgs &args)
    Definition: smoother.hh:119
    \n+
    ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Arguments
    Definition: smoother.hh:855
    \n+
    NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > Smoother
    Definition: smoother.hh:484
    \n+
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:456
    \n+
    AggregateAdder(Vector &subdomains_, const AggregatesMap &aggregates_, const MatrixGraph< const M > &graph_, VM &visitedMap_)
    Definition: smoother.hh:704
    \n+\n+
    void setComm(const C &comm)
    Definition: smoother.hh:158
    \n+
    DefaultConstructionArgs< Richardson< X, Y > > Arguments
    Definition: smoother.hh:269
    \n+
    virtual ~DefaultConstructionArgs()
    Definition: smoother.hh:180
    \n+
    SeqOverlappingSchwarzSmootherArgs< typename M::field_type > Arguments
    Definition: smoother.hh:552
    \n+\n+
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:488
    \n+
    int getN()
    Definition: smoother.hh:293
    \n+\n+
    SeqSOR< M, X, Y, l > Smoother
    Definition: smoother.hh:446
    \n+\n+
    static std::shared_ptr< SeqSSOR< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:224
    \n+
    AggregatesMap::AggregateDescriptor AggregateDescriptor
    Definition: smoother.hh:564
    \n+
    bool onthefly
    Definition: smoother.hh:541
    \n+
    DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments
    Definition: smoother.hh:238
    \n+
    virtual void setMatrix(const M &matrix, const AggregatesMap &amap)
    Definition: smoother.hh:568
    \n+
    void setMatrix(const Args &...)
    Definition: smoother.hh:184
    \n+
    DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments
    Definition: smoother.hh:254
    \n+
    DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments
    Definition: smoother.hh:222
    \n+
    const SmootherArgs getArgs() const
    Definition: smoother.hh:133
    \n+
    VertexAdder(Vector &subdomains_, const AggregatesMap &aggregates_)
    Definition: smoother.hh:661
    \n+\n+
    SeqOverlappingSchwarz< M, X, TM, TS, TA >::subdomain_vector Vector
    Definition: smoother.hh:565
    \n+
    static std::shared_ptr< SeqOverlappingSchwarz< M, X, TM, TS, TA > > construct(Arguments &args)
    Definition: smoother.hh:857
    \n+
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:469
    \n+
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n+
    void setMatrix(const Matrix &matrix)
    Definition: smoother.hh:104
    \n+
    T Smoother
    Definition: smoother.hh:371
    \n+
    static void preSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:450
    \n+
    BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > Smoother
    Definition: smoother.hh:465
    \n+
    void setComm(T1 &comm)
    Definition: smoother.hh:193
    \n+\n+
    AggregateDescriptor * iterator
    Definition: aggregates.hh:735
    \n+
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n+\n+
    SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex, bool onthefly_=false)
    Definition: smoother.hh:543
    \n+
    DefaultParallelConstructionArgs< T, C > Arguments
    Definition: smoother.hh:337
    \n+
    DefaultParallelConstructionArgs< T, C > Arguments
    Definition: smoother.hh:349
    \n+
    const Matrix * matrix_
    Definition: smoother.hh:139
    \n+
    const_iterator end() const
    Definition: aggregates.hh:730
    \n+
    const SequentialInformation & getComm()
    Definition: smoother.hh:128
    \n+
    V AggregateDescriptor
    The aggregate descriptor type.
    Definition: aggregates.hh:580
    \n+
    static const V ISOLATED
    Identifier of isolated vertices.
    Definition: aggregates.hh:571
    \n+
    DefaultSmootherArgs()
    Default constructor.
    Definition: smoother.hh:56
    \n+
    void setMatrix(const M &matrix)
    Definition: smoother.hh:606
    \n+
    std::size_t noVertices() const
    Get the number of vertices.
    \n+\n+
    static void postSmooth(Smoother &smoother, Domain &v, const Range &d)
    apply post smoothing in forward direction
    Definition: smoother.hh:394
    \n+
    FieldTraits< T >::real_type RelaxationFactor
    The type of the relaxation factor.
    Definition: smoother.hh:42
    \n+\n+
    Smoother::domain_type Domain
    Definition: smoother.hh:373
    \n+
    void setN(int n)
    Definition: smoother.hh:288
    \n+
    static std::shared_ptr< BlockPreconditioner< X, Y, C, T > > construct(Arguments &args)
    Definition: smoother.hh:339
    \n+
    SLList< VertexDescriptor, Allocator > VertexList
    The type of a single linked list of vertex descriptors.
    Definition: aggregates.hh:592
    \n+
    static std::shared_ptr< NonoverlappingBlockPreconditioner< C, T > > construct(Arguments &args)
    Definition: smoother.hh:351
    \n+
    SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > Smoother
    Definition: smoother.hh:514
    \n+
    static std::shared_ptr< ParSSOR< M, X, Y, C > > construct(Arguments &args)
    Definition: smoother.hh:326
    \n+
    MatrixGraph< M >::VertexDescriptor VertexDescriptor
    Definition: smoother.hh:562
    \n+
    static std::shared_ptr< SeqILU< M, X, Y > > construct(Arguments &args)
    Definition: smoother.hh:311
    \n+\n+
    const SequentialInformation & getComm()
    Definition: smoother.hh:196
    \n+
    static std::shared_ptr< SeqSOR< M, X, Y, l > > construct(Arguments &args)
    Definition: smoother.hh:240
    \n+
    static std::shared_ptr< Richardson< X, Y > > construct(Arguments &args)
    Definition: smoother.hh:271
    \n+
    virtual void setMatrix(const Matrix &matrix, const AggregatesMap &amap)
    Definition: smoother.hh:108
    \n+\n+
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n+
    Dune::Amg::AggregatesMap< VertexDescriptor > AggregatesMap
    Definition: smoother.hh:563
    \n+
    const SmootherArgs getArgs() const
    Definition: smoother.hh:201
    \n+
    void setComm(T1 &comm)
    Definition: smoother.hh:125
    \n+
    static void postSmooth(Smoother &smoother, Domain &v, const Range &d)
    Definition: smoother.hh:524
    \n+
    DefaultParallelConstructionArgs< M, C > Arguments
    Definition: smoother.hh:324
    \n+
    RelaxationFactor relaxationFactor
    The relaxation factor to use.
    Definition: smoother.hh:51
    \n+
    virtual ~DefaultParallelConstructionArgs()
    Definition: smoother.hh:155
    \n+
    Smoother::domain_type Domain
    Definition: smoother.hh:448
    \n+
    int setAggregate(const AggregateDescriptor &aggregate_)
    Definition: smoother.hh:725
    \n+
    Smoother::range_type Range
    Definition: smoother.hh:447
    \n+
    const C & getComm() const
    Definition: smoother.hh:163
    \n+
    virtual ~DefaultConstructionArgs()
    Definition: smoother.hh:101
    \n+
    static void preSmooth(Smoother &smoother, Domain &v, const Range &d)
    apply pre smoothing in forward direction
    Definition: smoother.hh:382
    \n+
    static void postSmooth(Smoother &smoother, Domain &v, Range &d)
    Definition: smoother.hh:475
    \n+
    ConstructionTraits< T > SeqConstructionTraits
    Definition: smoother.hh:338
    \n+
    ConstructionArgs(int n=0)
    Definition: smoother.hh:284
    \n+\n+
    void setArgs(const SmootherArgs &args)
    Definition: smoother.hh:187
    \n+
    int iterations
    The numbe of iterations to perform.
    Definition: smoother.hh:47
    \n+
    Smoother::range_type Range
    Definition: smoother.hh:372
    \n+
    Overlap overlap
    Definition: smoother.hh:540
    \n+\n+
    @ aggregate
    Definition: smoother.hh:538
    \n+\n+
    @ pairwise
    Definition: smoother.hh:538
    \n+
    @ vertex
    Definition: smoother.hh:538
    \n
    Definition: allocator.hh:11
    \n-
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n-
    A Vector class to support different block types.
    Definition: multitypeblockvector.hh:59
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n+
    X range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:770
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:765
    \n+
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n+
    Nonoverlapping parallel preconditioner.
    Definition: novlpschwarz.hh:276
    \n+
    P::range_type range_type
    The range type of the preconditioner.
    Definition: novlpschwarz.hh:284
    \n+
    P::domain_type domain_type
    The domain type of the preconditioner.
    Definition: novlpschwarz.hh:282
    \n+
    Tag that tells the Schwarz method to be multiplicative.
    Definition: overlappingschwarz.hh:126
    \n+
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n+\n+
    VertexIterator end()
    Get an iterator over the vertices.
    \n+
    M::size_type VertexDescriptor
    The vertex descriptor.
    Definition: graph.hh:73
    \n+
    VertexIterator begin()
    Get an iterator over the vertices.
    \n+
    Definition: pinfo.hh:28
    \n+
    The default class for the smoother arguments.
    Definition: smoother.hh:38
    \n+
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n+
    Construction Arguments for the default smoothers.
    Definition: smoother.hh:93
    \n+
    Definition: smoother.hh:148
    \n+\n+\n+\n+
    Helper class for applying the smoothers.
    Definition: smoother.hh:370
    \n+\n+\n+
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n+
    Sequential SOR preconditioner.
    Definition: preconditioners.hh:261
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:266
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:268
    \n+
    The sequential jacobian preconditioner.
    Definition: preconditioners.hh:412
    \n+
    Sequential ILU preconditioner.
    Definition: preconditioners.hh:532
    \n+
    Richardson preconditioner.
    Definition: preconditioners.hh:713
    \n+
    A parallel SSOR preconditioner.
    Definition: schwarz.hh:175
    \n+
    Block parallel preconditioner.
    Definition: schwarz.hh:278
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: schwarz.hh:285
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: schwarz.hh:290
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,395 +4,1335 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-multitypeblockvector.hh\n+ * paamg\n+smoother.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH\n- 6#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH\n+ 5#ifndef DUNE_AMGSMOOTHER_HH\n+ 6#define DUNE_AMGSMOOTHER_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11\n- 12#include \n- 13#include \n- 14#include \n- 15#include \n- 16#include \n- 17\n- 18#include \"istlexception.hh\"\n- 19\n- 20// forward declaration\n- 21namespace Dune {\n- 22 template < typename... Args >\n- 23 class MultiTypeBlockVector;\n- 24}\n- 25\n- 26#include \"gsetc.hh\"\n- 27\n- 28namespace Dune {\n- 29\n- 41 template \n-42 struct FieldTraits< MultiTypeBlockVector >\n- 43 {\n-44 using field_type = typename MultiTypeBlockVector::field_type;\n-45 using real_type = typename FieldTraits::real_type;\n- 46 };\n- 56 template < typename... Args >\n-57 class MultiTypeBlockVector\n- 58 : public std::tuple\n- 59 {\n- 61 typedef std::tuple TupleType;\n- 62 public:\n- 63\n-65 using size_type = std::size_t;\n- 66\n- 70 using TupleType::TupleType;\n- 71\n-75 typedef MultiTypeBlockVector type;\n- 76\n-82 using field_type = Std::detected_t >::field_type...>;\n- 83\n- 84 // make sure that we have an std::common_type: using an assertion produces\n-a more readable error message\n- 85 // than a compiler template instantiation error\n- 86 static_assert ( sizeof...(Args) == 0 or not std::is_same_v,\n- 87 \"No std::common_type implemented for the given field_types of the Args.\n-Please provide an implementation and check that a FieldTraits class is present\n-for your type.\");\n- 88\n- 89\n-95 static constexpr size_type size()\n- 96 {\n- 97 return sizeof...(Args);\n- 98 }\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15\n+ 16namespace Dune\n+ 17{\n+ 18 namespace Amg\n+ 19 {\n+ 20\n+ 36 template\n+37 struct DefaultSmootherArgs\n+ 38 {\n+42 typedef typename FieldTraits::real_type RelaxationFactor;\n+ 43\n+47 int iterations;\n+51 RelaxationFactor relaxationFactor;\n+ 52\n+56 DefaultSmootherArgs()\n+ 57 : iterations(1), relaxationFactor(1.0)\n+ 58 {}\n+ 59 };\n+ 60\n+ 64 template\n+65 struct SmootherTraits\n+ 66 {\n+67 typedef DefaultSmootherArgs Arguments;\n+ 68\n+ 69 };\n+ 70\n+ 71 template\n+72 struct SmootherTraits>\n+ 73 {\n+74 typedef DefaultSmootherArgs Arguments;\n+ 75\n+ 76 };\n+ 77\n+ 78 template\n+79 struct SmootherTraits >\n+ 80 : public SmootherTraits\n+ 81 {};\n+ 82\n+ 83 template\n+84 struct SmootherTraits >\n+ 85 : public SmootherTraits\n+ 86 {};\n+ 87\n+ 91 template\n+92 class DefaultConstructionArgs\n+ 93 {\n+ 94 typedef typename T::matrix_type Matrix;\n+ 95\n+ 96 typedef typename SmootherTraits::Arguments SmootherArgs;\n+ 97\n+ 98 typedef Dune::Amg::AggregatesMap::\n+VertexDescriptor> AggregatesMap;\n 99\n-102 static constexpr size_type N()\n- 103 {\n- 104 return sizeof...(Args);\n- 105 }\n- 106\n- 113 [[deprecated(\"Use method 'N' instead\")]]\n-114 int count() const\n+ 100 public:\n+101 virtual ~DefaultConstructionArgs()\n+ 102 {}\n+ 103\n+104 void setMatrix(const Matrix& matrix)\n+ 105 {\n+ 106 matrix_=&matrix;\n+ 107 }\n+108 virtual void setMatrix(const Matrix& matrix, [[maybe_unused]] const\n+AggregatesMap& amap)\n+ 109 {\n+ 110 setMatrix(matrix);\n+ 111 }\n+ 112\n+ 113\n+114 const Matrix& getMatrix() const\n 115 {\n- 116 return sizeof...(Args);\n+ 116 return *matrix_;\n 117 }\n 118\n-120 size_type dim() const\n- 121 {\n- 122 size_type result = 0;\n- 123 Hybrid::forEach(std::make_index_sequence{},\n- 124 [&](auto i){result += std::get(*this).dim();});\n- 125\n- 126 return result;\n- 127 }\n- 128\n- 147 template< size_type index >\n- 148 typename std::tuple_element::type&\n-149 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n-> indexVariable)\n- 150 {\n- 151 return std::get(*this);\n- 152 }\n- 153\n- 159 template< size_type index >\n- 160 const typename std::tuple_element::type&\n-161 operator[]([[maybe_unused]] const std::integral_constant< size_type, index\n-> indexVariable) const\n- 162 {\n- 163 return std::get(*this);\n- 164 }\n- 165\n- 168 template\n-169 void operator=(const T& newval) {\n- 170 Dune::Hybrid::forEach(*this, [&](auto&& entry) {\n- 171 entry = newval;\n- 172 });\n- 173 }\n- 174\n-178 void operator+=(const type& newv) {\n- 179 using namespace Dune::Hybrid;\n- 180 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n- 181 (*this)[i] += newv[i];\n- 182 });\n- 183 }\n- 184\n-188 void operator-=(const type& newv) {\n- 189 using namespace Dune::Hybrid;\n- 190 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n- 191 (*this)[i] -= newv[i];\n- 192 });\n- 193 }\n- 194\n- 196 template::value, int> = 0>\n-198 void operator*=(const T& w) {\n- 199 Hybrid::forEach(*this, [&](auto&& entry) {\n- 200 entry *= w;\n- 201 });\n- 202 }\n- 203\n- 205 template::value, int> = 0>\n-207 void operator/=(const T& w) {\n- 208 Hybrid::forEach(*this, [&](auto&& entry) {\n- 209 entry /= w;\n- 210 });\n- 211 }\n+119 void setArgs(const SmootherArgs& args)\n+ 120 {\n+ 121 args_=&args;\n+ 122 }\n+ 123\n+ 124 template\n+125 void setComm([[maybe_unused]] T1& comm)\n+ 126 {}\n+ 127\n+128 const SequentialInformation& getComm()\n+ 129 {\n+ 130 return comm_;\n+ 131 }\n+ 132\n+133 const SmootherArgs getArgs() const\n+ 134 {\n+ 135 return *args_;\n+ 136 }\n+ 137\n+ 138 protected:\n+139 const Matrix* matrix_;\n+ 140 private:\n+ 141 const SmootherArgs* args_;\n+ 142 SequentialInformation comm_;\n+ 143 };\n+ 144\n+ 145 template\n+146 struct ConstructionArgs\n+ 147 : public DefaultConstructionArgs\n+ 148 {};\n+ 149\n+ 150 template\n+151 class DefaultParallelConstructionArgs\n+ 152 : public ConstructionArgs\n+ 153 {\n+ 154 public:\n+155 virtual ~DefaultParallelConstructionArgs()\n+ 156 {}\n+ 157\n+158 void setComm(const C& comm)\n+ 159 {\n+ 160 comm_ = &comm;\n+ 161 }\n+ 162\n+163 const C& getComm() const\n+ 164 {\n+ 165 return *comm_;\n+ 166 }\n+ 167 private:\n+ 168 const C* comm_;\n+ 169 };\n+ 170\n+ 171\n+ 172 template\n+173 class DefaultConstructionArgs>\n+ 174 {\n+ 175 typedef Richardson T;\n+ 176\n+ 177 typedef typename SmootherTraits::Arguments SmootherArgs;\n+ 178\n+ 179 public:\n+180 virtual ~DefaultConstructionArgs()\n+ 181 {}\n+ 182\n+ 183 template \n+184 void setMatrix(const Args&...)\n+ 185 {}\n+ 186\n+187 void setArgs(const SmootherArgs& args)\n+ 188 {\n+ 189 args_=&args;\n+ 190 }\n+ 191\n+ 192 template\n+193 void setComm([[maybe_unused]] T1& comm)\n+ 194 {}\n+ 195\n+196 const SequentialInformation& getComm()\n+ 197 {\n+ 198 return comm_;\n+ 199 }\n+ 200\n+201 const SmootherArgs getArgs() const\n+ 202 {\n+ 203 return *args_;\n+ 204 }\n+ 205\n+ 206 private:\n+ 207 const SmootherArgs* args_;\n+ 208 SequentialInformation comm_;\n+ 209 };\n+ 210\n+ 211\n 212\n-213 field_type operator*(const type& newv) const {\n- 214 using namespace Dune::Hybrid;\n- 215 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&]\n-(auto&& a, auto&& i) {\n- 216 return a + (*this)[i]*newv[i];\n- 217 });\n- 218 }\n- 219\n-220 field_type dot (const type& newv) const {\n- 221 using namespace Dune::Hybrid;\n- 222 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&]\n-(auto&& a, auto&& i) {\n- 223 return a + (*this)[i].dot(newv[i]);\n- 224 });\n- 225 }\n- 226\n-229 auto one_norm() const {\n- 230 using namespace Dune::Hybrid;\n- 231 return accumulate(*this, typename FieldTraits::real_type(0),\n-[&](auto&& a, auto&& entry) {\n- 232 return a + entry.one_norm();\n- 233 });\n- 234 }\n- 235\n-238 auto one_norm_real() const {\n- 239 using namespace Dune::Hybrid;\n- 240 return accumulate(*this, typename FieldTraits::real_type(0),\n-[&](auto&& a, auto&& entry) {\n- 241 return a + entry.one_norm_real();\n- 242 });\n- 243 }\n- 244\n-247 typename FieldTraits::real_type two_norm2() const {\n- 248 using namespace Dune::Hybrid;\n- 249 return accumulate(*this, typename FieldTraits::real_type(0),\n-[&](auto&& a, auto&& entry) {\n- 250 return a + entry.two_norm2();\n- 251 });\n- 252 }\n- 253\n-256 typename FieldTraits::real_type two_norm() const {return sqrt\n-(this->two_norm2());}\n- 257\n-260 typename FieldTraits::real_type infinity_norm() const\n- 261 {\n- 262 using namespace Dune::Hybrid;\n- 263 using std::max;\n- 264 using real_type = typename FieldTraits::real_type;\n- 265\n- 266 real_type result = 0.0;\n- 267 // Compute max norm tracking appearing nan values\n- 268 // if the field type supports nan.\n- 269 if constexpr (HasNaN()) {\n- 270 // This variable will preserve any nan value\n- 271 real_type nanTracker = 1.0;\n- 272 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 273 forEach(*this, [&](auto&& entry) {\n- 274 real_type entryNorm = entry.infinity_norm();\n- 275 result = max(entryNorm, result);\n- 276 nanTracker += entryNorm;\n- 277 });\n- 278 // Incorporate possible nan value into result\n- 279 result *= (nanTracker / nanTracker);\n- 280 } else {\n- 281 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 282 forEach(*this, [&](auto&& entry) {\n- 283 result = max(entry.infinity_norm(), result);\n- 284 });\n- 285 }\n- 286 return result;\n- 287 }\n- 288\n-291 typename FieldTraits::real_type infinity_norm_real() const\n- 292 {\n- 293 using namespace Dune::Hybrid;\n- 294 using std::max;\n- 295 using real_type = typename FieldTraits::real_type;\n- 296\n- 297 real_type result = 0.0;\n- 298 // Compute max norm tracking appearing nan values\n- 299 // if the field type supports nan.\n- 300 if constexpr (HasNaN()) {\n- 301 // This variable will preserve any nan value\n- 302 real_type nanTracker = 1.0;\n- 303 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 304 forEach(*this, [&](auto&& entry) {\n- 305 real_type entryNorm = entry.infinity_norm_real();\n- 306 result = max(entryNorm, result);\n- 307 nanTracker += entryNorm;\n- 308 });\n- 309 // Incorporate possible nan value into result\n- 310 result *= (nanTracker / nanTracker);\n- 311 } else {\n- 312 using namespace Dune::Hybrid; // needed for icc, see issue #31\n- 313 forEach(*this, [&](auto&& entry) {\n- 314 result = max(entry.infinity_norm_real(), result);\n- 315 });\n- 316 }\n- 317 return result;\n- 318 }\n- 319\n- 324 template\n-325 void axpy (const Ta& a, const type& y) {\n- 326 using namespace Dune::Hybrid;\n- 327 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {\n- 328 (*this)[i].axpy(a, y[i]);\n- 329 });\n- 330 }\n- 331\n+ 213 template\n+ 214 struct ConstructionTraits;\n+ 215\n+ 219 template\n+220 struct ConstructionTraits >\n+ 221 {\n+222 typedef DefaultConstructionArgs > Arguments;\n+ 223\n+224 static inline std::shared_ptr> construct(Arguments& args)\n+ 225 {\n+ 226 return std::make_shared>\n+ 227 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n+().relaxationFactor);\n+ 228 }\n+ 229 };\n+ 230\n+ 231\n+ 235 template\n+236 struct ConstructionTraits >\n+ 237 {\n+238 typedef DefaultConstructionArgs > Arguments;\n+ 239\n+240 static inline std::shared_ptr> construct(Arguments& args)\n+ 241 {\n+ 242 return std::make_shared>\n+ 243 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n+().relaxationFactor);\n+ 244 }\n+ 245 };\n+ 246\n+ 247\n+ 251 template\n+252 struct ConstructionTraits >\n+ 253 {\n+254 typedef DefaultConstructionArgs > Arguments;\n+ 255\n+256 static inline std::shared_ptr> construct(Arguments& args)\n+ 257 {\n+ 258 return std::make_shared>\n+ 259 (args.getMatrix(), args.getArgs().iterations, args.getArgs\n+().relaxationFactor);\n+ 260 }\n+ 261 };\n+ 262\n+ 266 template\n+267 struct ConstructionTraits >\n+ 268 {\n+269 typedef DefaultConstructionArgs > Arguments;\n+ 270\n+271 static inline std::shared_ptr> construct(Arguments& args)\n+ 272 {\n+ 273 return std::make_shared>\n+ 274 (args.getArgs().relaxationFactor);\n+ 275 }\n+ 276 };\n+ 277\n+ 278\n+ 279 template\n+280 class ConstructionArgs >\n+ 281 : public DefaultConstructionArgs >\n+ 282 {\n+ 283 public:\n+284 ConstructionArgs(int n=0)\n+ 285 : n_(n)\n+ 286 {}\n+ 287\n+288 void setN(int n)\n+ 289 {\n+ 290 n_ = n;\n+ 291 }\n+ 292\n+293 int getN()\n+ 294 {\n+ 295 return n_;\n+ 296 }\n+ 297\n+ 298 private:\n+ 299 int n_;\n+ 300 };\n+ 301\n+ 302\n+ 306 template\n+307 struct ConstructionTraits >\n+ 308 {\n+309 typedef ConstructionArgs > Arguments;\n+ 310\n+311 static inline std::shared_ptr> construct(Arguments& args)\n+ 312 {\n+ 313 return std::make_shared>\n+ 314 (args.getMatrix(), args.getN(), args.getArgs().relaxationFactor);\n+ 315 }\n+ 316 };\n+ 317\n+ 321 template\n+322 struct ConstructionTraits >\n+ 323 {\n+324 typedef DefaultParallelConstructionArgs Arguments;\n+ 325\n+326 static inline std::shared_ptr> construct(Arguments& args)\n+ 327 {\n+ 328 return std::make_shared>\n+ 329 (args.getMatrix(), args.getArgs().iterations,\n+ 330 args.getArgs().relaxationFactor, args.getComm());\n+ 331 }\n 332 };\n 333\n- 334\n- 335\n- 338 template \n-339 std::ostream& operator<<(std::ostream& s, const\n-MultiTypeBlockVector& v) {\n- 340 using namespace Dune::Hybrid;\n- 341 forEach(integralRange(Dune::Hybrid::size(v)), [&](auto&& i) {\n- 342 s << \"\\t(\" << i << \"):\\n\" << v[i] << \"\\n\";\n- 343 });\n- 344 return s;\n- 345 }\n- 346\n- 347} // end namespace Dune\n- 348\n- 349namespace std\n- 350{\n- 355 template \n-356 struct tuple_element >\n- 357 {\n-358 using type = typename std::tuple_element >::type;\n- 359 };\n- 360}\n- 361\n- 362#endif\n-istlexception.hh\n-gsetc.hh\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way.\n-Dune::MultiTypeBlockVector::operator=\n-void operator=(const T &newval)\n-Assignment operator.\n-Definition: multitypeblockvector.hh:169\n-Dune::MultiTypeBlockVector::size_type\n-std::size_t size_type\n-Type used for vector sizes.\n-Definition: multitypeblockvector.hh:65\n-Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>::real_type\n-typename FieldTraits< field_type >::real_type real_type\n-Definition: multitypeblockvector.hh:45\n-Dune::MultiTypeBlockVector::count\n-int count() const\n-Definition: multitypeblockvector.hh:114\n-Dune::MultiTypeBlockVector::N\n-static constexpr size_type N()\n-Number of elements.\n-Definition: multitypeblockvector.hh:102\n-Dune::MultiTypeBlockVector::field_type\n-Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args >\n->::field_type... > field_type\n-The type used for scalars.\n-Definition: multitypeblockvector.hh:82\n-Dune::MultiTypeBlockVector::size\n-static constexpr size_type size()\n-Return the number of non-zero vector entries.\n-Definition: multitypeblockvector.hh:95\n-Dune::MultiTypeBlockVector::operator[]\n-std::tuple_element< index, TupleType >::type & operator[](const std::\n-integral_constant< size_type, index > indexVariable)\n-Random-access operator.\n-Definition: multitypeblockvector.hh:149\n-Dune::MultiTypeBlockVector::two_norm\n-FieldTraits< field_type >::real_type two_norm() const\n-Compute the Euclidean norm.\n-Definition: multitypeblockvector.hh:256\n-Dune::FieldTraits<_MultiTypeBlockVector<_Args..._>_>::field_type\n-typename MultiTypeBlockVector< Args... >::field_type field_type\n-Definition: multitypeblockvector.hh:44\n-Dune::MultiTypeBlockVector::dim\n-size_type dim() const\n-Number of scalar elements.\n-Definition: multitypeblockvector.hh:120\n-Dune::MultiTypeBlockVector::dot\n-field_type dot(const type &newv) const\n-Definition: multitypeblockvector.hh:220\n-Dune::MultiTypeBlockVector::operator*=\n-void operator*=(const T &w)\n-Multiplication with a scalar.\n-Definition: multitypeblockvector.hh:198\n-Dune::MultiTypeBlockVector::axpy\n-void axpy(const Ta &a, const type &y)\n-Axpy operation on this vector (*this += a * y)\n-Definition: multitypeblockvector.hh:325\n-Dune::MultiTypeBlockVector::operator/=\n-void operator/=(const T &w)\n-Division by a scalar.\n-Definition: multitypeblockvector.hh:207\n-Dune::MultiTypeBlockVector::type\n-MultiTypeBlockVector< Args... > type\n-Definition: multitypeblockvector.hh:75\n-Dune::MultiTypeBlockVector::infinity_norm_real\n-FieldTraits< field_type >::real_type infinity_norm_real() const\n-Compute the simplified maximum norm (uses 1-norm for complex values)\n-Definition: multitypeblockvector.hh:291\n-Dune::MultiTypeBlockVector::one_norm\n-auto one_norm() const\n-Compute the 1-norm.\n-Definition: multitypeblockvector.hh:229\n-Dune::MultiTypeBlockVector::operator-=\n-void operator-=(const type &newv)\n-Definition: multitypeblockvector.hh:188\n-Dune::MultiTypeBlockVector::operator*\n-field_type operator*(const type &newv) const\n-Definition: multitypeblockvector.hh:213\n-Dune::MultiTypeBlockVector::operator+=\n-void operator+=(const type &newv)\n-Definition: multitypeblockvector.hh:178\n-std::tuple_element<_i,_Dune::MultiTypeBlockVector<_Args..._>_>::type\n-typename std::tuple_element< i, std::tuple< Args... > >::type type\n-Definition: multitypeblockvector.hh:358\n-Dune::MultiTypeBlockVector::infinity_norm\n-FieldTraits< field_type >::real_type infinity_norm() const\n-Compute the maximum norm.\n-Definition: multitypeblockvector.hh:260\n-Dune::MultiTypeBlockVector::one_norm_real\n-auto one_norm_real() const\n-Compute the simplified 1-norm (uses 1-norm also for complex values)\n-Definition: multitypeblockvector.hh:238\n-Dune::MultiTypeBlockVector::two_norm2\n-FieldTraits< field_type >::real_type two_norm2() const\n-Compute the squared Euclidean norm.\n-Definition: multitypeblockvector.hh:247\n-std\n-STL namespace.\n+ 334 template\n+335 struct ConstructionTraits >\n+ 336 {\n+337 typedef DefaultParallelConstructionArgs Arguments;\n+338 typedef ConstructionTraits SeqConstructionTraits;\n+339 static inline std::shared_ptr> construct\n+(Arguments& args)\n+ 340 {\n+ 341 auto seqPrec = SeqConstructionTraits::construct(args);\n+ 342 return std::make_shared> (seqPrec,\n+args.getComm());\n+ 343 }\n+ 344 };\n+ 345\n+ 346 template\n+347 struct ConstructionTraits >\n+ 348 {\n+349 typedef DefaultParallelConstructionArgs Arguments;\n+350 typedef ConstructionTraits SeqConstructionTraits;\n+351 static inline std::shared_ptr>\n+construct(Arguments& args)\n+ 352 {\n+ 353 auto seqPrec = SeqConstructionTraits::construct(args);\n+ 354 return std::make_shared> (seqPrec,\n+args.getComm());\n+ 355 }\n+ 356 };\n+ 357\n+ 368 template\n+369 struct SmootherApplier\n+ 370 {\n+371 typedef T Smoother;\n+372 typedef typename Smoother::range_type Range;\n+373 typedef typename Smoother::domain_type Domain;\n+ 374\n+382 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)\n+ 383 {\n+ 384 smoother.apply(v,d);\n+ 385 }\n+ 386\n+394 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)\n+ 395 {\n+ 396 smoother.apply(v,d);\n+ 397 }\n+ 398 };\n+ 399\n+ 405 template\n+406 void presmooth(LevelContext& levelContext, size_t steps)\n+ 407 {\n+ 408 for(std::size_t i=0; i < steps; ++i) {\n+ 409 *levelContext.lhs=0;\n+ 410 SmootherApplier\n+ 411::preSmooth(*levelContext.smoother, *levelContext.lhs,\n+ 412 *levelContext.rhs);\n+ 413 // Accumulate update\n+ 414 *levelContext.update += *levelContext.lhs;\n+ 415\n+ 416 // update defect\n+ 417 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,\n+*levelContext.rhs);\n+ 418 levelContext.pinfo->project(*levelContext.rhs);\n+ 419 }\n+ 420 }\n+ 421\n+ 427 template\n+428 void postsmooth(LevelContext& levelContext, size_t steps)\n+ 429 {\n+ 430 for(std::size_t i=0; i < steps; ++i) {\n+ 431 // update defect\n+ 432 levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,\n+ 433 *levelContext.rhs);\n+ 434 *levelContext.lhs=0;\n+ 435 levelContext.pinfo->project(*levelContext.rhs);\n+ 436 SmootherApplier\n+ 437::postSmooth(*levelContext.smoother, *levelContext.lhs, *levelContext.rhs);\n+ 438 // Accumulate update\n+ 439 *levelContext.update += *levelContext.lhs;\n+ 440 }\n+ 441 }\n+ 442\n+ 443 template\n+444 struct SmootherApplier >\n+ 445 {\n+446 typedef SeqSOR Smoother;\n+447 typedef typename Smoother::range_type Range;\n+448 typedef typename Smoother::domain_type Domain;\n+ 449\n+450 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 451 {\n+ 452 smoother.template apply(v,d);\n+ 453 }\n+ 454\n+ 455\n+456 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 457 {\n+ 458 smoother.template apply(v,d);\n+ 459 }\n+ 460 };\n+ 461\n+ 462 template\n+463 struct SmootherApplier > >\n+ 464 {\n+465 typedef BlockPreconditioner > Smoother;\n+466 typedef typename Smoother::range_type Range;\n+467 typedef typename Smoother::domain_type Domain;\n+ 468\n+469 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 470 {\n+ 471 smoother.template apply(v,d);\n+ 472 }\n+ 473\n+ 474\n+475 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 476 {\n+ 477 smoother.template apply(v,d);\n+ 478 }\n+ 479 };\n+ 480\n+ 481 template\n+482 struct SmootherApplier\n+> >\n+ 483 {\n+484 typedef NonoverlappingBlockPreconditioner > Smoother;\n+485 typedef typename Smoother::range_type Range;\n+486 typedef typename Smoother::domain_type Domain;\n+ 487\n+488 static void preSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 489 {\n+ 490 smoother.template apply(v,d);\n+ 491 }\n+ 492\n+ 493\n+494 static void postSmooth(Smoother& smoother, Domain& v, Range& d)\n+ 495 {\n+ 496 smoother.template apply(v,d);\n+ 497 }\n+ 498 };\n+ 499\n+ 500 } // end namespace Amg\n+ 501\n+ 502 // forward declarations\n+ 503 template\n+ 504 class SeqOverlappingSchwarz;\n+ 505\n+ 506 struct MultiplicativeSchwarzMode;\n+ 507\n+ 508 namespace Amg\n+ 509 {\n+ 510 template\n+511 struct SmootherApplier >\n+ 513 {\n+514 typedef SeqOverlappingSchwarz\n+Smoother;\n+515 typedef typename Smoother::range_type Range;\n+516 typedef typename Smoother::domain_type Domain;\n+ 517\n+518 static void preSmooth(Smoother& smoother, Domain& v, const Range& d)\n+ 519 {\n+ 520 smoother.template apply(v,d);\n+ 521 }\n+ 522\n+ 523\n+524 static void postSmooth(Smoother& smoother, Domain& v, const Range& d)\n+ 525 {\n+ 526 smoother.template apply(v,d);\n+ 527\n+ 528 }\n+ 529 };\n+ 530\n+ 531 // template\n+ 532 // class SeqOverlappingSchwarz;\n+ 533\n+ 534 template\n+535 struct SeqOverlappingSchwarzSmootherArgs\n+ 536 : public DefaultSmootherArgs\n+ 537 {\n+538 enum Overlap {vertex, aggregate, pairwise, none};\n+ 539\n+540 Overlap overlap;\n+541 bool onthefly;\n+ 542\n+543 SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex,\n+ 544 bool onthefly_=false)\n+ 545 : overlap(overlap_), onthefly(onthefly_)\n+ 546 {}\n+ 547 };\n+ 548\n+ 549 template\n+550 struct SmootherTraits >\n+ 551 {\n+552 typedef SeqOverlappingSchwarzSmootherArgs\n+Arguments;\n+ 553 };\n+ 554\n+ 555 template\n+556 class ConstructionArgs >\n+ 557 : public DefaultConstructionArgs >\n+ 558 {\n+ 559 typedef DefaultConstructionArgs >\n+Father;\n+ 560\n+ 561 public:\n+562 typedef typename MatrixGraph::VertexDescriptor VertexDescriptor;\n+563 typedef Dune::Amg::AggregatesMap AggregatesMap;\n+564 typedef typename AggregatesMap::AggregateDescriptor AggregateDescriptor;\n+565 typedef typename SeqOverlappingSchwarz::subdomain_vector\n+Vector;\n+566 typedef typename Vector::value_type Subdomain;\n+ 567\n+568 virtual void setMatrix(const M& matrix, const AggregatesMap& amap)\n+ 569 {\n+ 570 Father::setMatrix(matrix);\n+ 571\n+ 572 std::vector visited(amap.noVertices(), false);\n+ 573 typedef IteratorPropertyMap::iterator,IdentityMap>\n+VisitedMapType;\n+ 574 VisitedMapType visitedMap(visited.begin());\n+ 575\n+ 576 MatrixGraph graph(matrix);\n+ 577\n+ 578 typedef SeqOverlappingSchwarzSmootherArgs\n+SmootherArgs;\n+ 579\n+ 580 switch(Father::getArgs().overlap) {\n+ 581 case SmootherArgs::vertex :\n+ 582 {\n+ 583 VertexAdder visitor(subdomains, amap);\n+ 584 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 585 }\n+ 586 break;\n+ 587 case SmootherArgs::pairwise :\n+ 588 {\n+ 589 createPairDomains(graph);\n+ 590 }\n+ 591 break;\n+ 592 case SmootherArgs::aggregate :\n+ 593 {\n+ 594 AggregateAdder visitor(subdomains, amap, graph,\n+visitedMap);\n+ 595 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 596 }\n+ 597 break;\n+ 598 case SmootherArgs::none :\n+ 599 NoneAdder visitor;\n+ 600 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 601 break;\n+ 602 default :\n+ 603 DUNE_THROW(NotImplemented, \"This overlapping scheme is not supported!\");\n+ 604 }\n+ 605 }\n+606 void setMatrix(const M& matrix)\n+ 607 {\n+ 608 Father::setMatrix(matrix);\n+ 609\n+ 610 /* Create aggregates map where each aggregate is just one vertex. */\n+ 611 AggregatesMap amap(matrix.N());\n+ 612 VertexDescriptor v=0;\n+ 613 for(typename AggregatesMap::iterator iter=amap.begin();\n+ 614 iter!=amap.end(); ++iter)\n+ 615 *iter=v++;\n+ 616\n+ 617 std::vector visited(amap.noVertices(), false);\n+ 618 typedef IteratorPropertyMap::iterator,IdentityMap>\n+VisitedMapType;\n+ 619 VisitedMapType visitedMap(visited.begin());\n+ 620\n+ 621 MatrixGraph graph(matrix);\n+ 622\n+ 623 typedef SeqOverlappingSchwarzSmootherArgs\n+SmootherArgs;\n+ 624\n+ 625 switch(Father::getArgs().overlap) {\n+ 626 case SmootherArgs::vertex :\n+ 627 {\n+ 628 VertexAdder visitor(subdomains, amap);\n+ 629 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 630 }\n+ 631 break;\n+ 632 case SmootherArgs::aggregate :\n+ 633 {\n+ 634 DUNE_THROW(NotImplemented, \"Aggregate overlap is not supported yet\");\n+ 635 /*\n+ 636 AggregateAdder visitor(subdomains, amap, graph,\n+visitedMap);\n+ 637 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 638 */\n+ 639 }\n+ 640 break;\n+ 641 case SmootherArgs::pairwise :\n+ 642 {\n+ 643 createPairDomains(graph);\n+ 644 }\n+ 645 break;\n+ 646 case SmootherArgs::none :\n+ 647 NoneAdder visitor;\n+ 648 createSubdomains(matrix, graph, amap, visitor, visitedMap);\n+ 649\n+ 650 }\n+ 651 }\n+ 652\n+653 const Vector& getSubDomains()\n+ 654 {\n+ 655 return subdomains;\n+ 656 }\n+ 657\n+ 658 private:\n+ 659 struct VertexAdder\n+ 660 {\n+661 VertexAdder(Vector& subdomains_, const AggregatesMap& aggregates_)\n+ 662 : subdomains(subdomains_), max(-1), subdomain(-1), aggregates(aggregates_)\n+ 663 {}\n+ 664 template\n+665 void operator()(const T& edge)\n+ 666 {\n+ 667 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED)\n+ 668 subdomains[subdomain].insert(edge.target());\n+ 669 }\n+670 int setAggregate(const AggregateDescriptor& aggregate_)\n+ 671 {\n+ 672 subdomain=aggregate_;\n+ 673 max = std::max(subdomain, aggregate_);\n+ 674 return subdomain;\n+ 675 }\n+676 int noSubdomains() const\n+ 677 {\n+ 678 return max+1;\n+ 679 }\n+ 680 private:\n+ 681 Vector& subdomains;\n+ 682 AggregateDescriptor max;\n+ 683 AggregateDescriptor subdomain;\n+ 684 const AggregatesMap& aggregates;\n+ 685 };\n+ 686 struct NoneAdder\n+ 687 {\n+ 688 template\n+689 void operator()(const T& edge)\n+ 690 {}\n+691 int setAggregate(const AggregateDescriptor& aggregate_)\n+ 692 {\n+ 693 return -1;\n+ 694 }\n+695 int noSubdomains() const\n+ 696 {\n+ 697 return -1;\n+ 698 }\n+ 699 };\n+ 700\n+ 701 template\n+ 702 struct AggregateAdder\n+ 703 {\n+704 AggregateAdder(Vector& subdomains_, const AggregatesMap& aggregates_,\n+ 705 const MatrixGraph& graph_, VM& visitedMap_)\n+ 706 : subdomains(subdomains_), subdomain(-1), aggregates(aggregates_),\n+ 707 adder(subdomains_, aggregates_), graph(graph_), visitedMap(visitedMap_)\n+ 708 {}\n+ 709 template\n+710 void operator()(const T& edge)\n+ 711 {\n+ 712 subdomains[subdomain].insert(edge.target());\n+ 713 // If we (the neighbouring vertex of the aggregate)\n+ 714 // are not isolated, add the aggregate we belong to\n+ 715 // to the same subdomain using the OneOverlapAdder\n+ 716 if(aggregates[edge.target()]!=AggregatesMap::ISOLATED) {\n+ 717 assert(aggregates[edge.target()]!=aggregate);\n+ 718 typename AggregatesMap::VertexList vlist;\n+ 719 aggregates.template breadthFirstSearch(edge.target(),\n+aggregate,\n+ 720 graph, vlist, adder, adder,\n+ 721 visitedMap);\n+ 722 }\n+ 723 }\n+ 724\n+725 int setAggregate(const AggregateDescriptor& aggregate_)\n+ 726 {\n+ 727 adder.setAggregate(aggregate_);\n+ 728 aggregate=aggregate_;\n+ 729 return ++subdomain;\n+ 730 }\n+731 int noSubdomains() const\n+ 732 {\n+ 733 return subdomain+1;\n+ 734 }\n+ 735\n+ 736 private:\n+ 737 AggregateDescriptor aggregate;\n+ 738 Vector& subdomains;\n+ 739 int subdomain;\n+ 740 const AggregatesMap& aggregates;\n+ 741 VertexAdder adder;\n+ 742 const MatrixGraph& graph;\n+ 743 VM& visitedMap;\n+ 744 };\n+ 745\n+ 746 void createPairDomains(const MatrixGraph& graph)\n+ 747 {\n+ 748 typedef typename MatrixGraph::ConstVertexIterator VIter;\n+ 749 typedef typename MatrixGraph::ConstEdgeIterator EIter;\n+ 750 typedef typename M::size_type size_type;\n+ 751\n+ 752 std::set > pairs;\n+ 753 int total=0;\n+ 754 for(VIter v=graph.begin(), ve=graph.end(); ve != v; ++v)\n+ 755 for(EIter e = v.begin(), ee=v.end(); ee!=e; ++e)\n+ 756 {\n+ 757 ++total;\n+ 758 if(e.source() >::const_iterator\n+SIter;\n+ 768 typename Vector::iterator subdomain=subdomains.begin();\n+ 769\n+ 770 for(SIter s=pairs.begin(), se =pairs.end(); se!=s; ++s)\n+ 771 {\n+ 772 subdomain->insert(s->first);\n+ 773 subdomain->insert(s->second);\n+ 774 ++subdomain;\n+ 775 }\n+ 776 std::size_t minsize=10000;\n+ 777 std::size_t maxsize=0;\n+ 778 int sum=0;\n+ 779 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {\n+ 780 sum+=subdomains[i].size();\n+ 781 minsize=std::min(minsize, subdomains[i].size());\n+ 782 maxsize=std::max(maxsize, subdomains[i].size());\n+ 783 }\n+ 784 Dune::dinfo<<\"Subdomain size: min=\"<\n+ 789 void createSubdomains(const M& matrix, const MatrixGraph& graph,\n+ 790 const AggregatesMap& amap, Visitor& overlapVisitor,\n+ 791 IteratorPropertyMap::iterator,IdentityMap>& visitedMap )\n+ 792 {\n+ 793 // count number ag aggregates. We assume that the\n+ 794 // aggregates are numbered consecutively from 0 except\n+ 795 // for the isolated ones. All isolated vertices form\n+ 796 // one aggregate, here.\n+ 797 int isolated=0;\n+ 798 AggregateDescriptor maxAggregate=0;\n+ 799\n+ 800 for(std::size_t i=0; i < amap.noVertices(); ++i)\n+ 801 if(amap[i]==AggregatesMap::ISOLATED)\n+ 802 isolated++;\n+ 803 else\n+ 804 maxAggregate = std::max(maxAggregate, amap[i]);\n+ 805\n+ 806 subdomains.resize(maxAggregate+1+isolated);\n+ 807\n+ 808 // reset the subdomains\n+ 809 for(typename Vector::size_type i=0; i < subdomains.size(); ++i)\n+ 810 subdomains[i].clear();\n+ 811\n+ 812 // Create the subdomains from the aggregates mapping.\n+ 813 // For each aggregate we mark all entries and the\n+ 814 // neighbouring vertices as belonging to the same subdomain\n+ 815 VertexAdder aggregateVisitor(subdomains, amap);\n+ 816\n+ 817 for(VertexDescriptor i=0; i < amap.noVertices(); ++i)\n+ 818 if(!get(visitedMap, i)) {\n+ 819 AggregateDescriptor aggregate=amap[i];\n+ 820\n+ 821 if(amap[i]==AggregatesMap::ISOLATED) {\n+ 822 // isolated vertex gets its own aggregate\n+ 823 subdomains.push_back(Subdomain());\n+ 824 aggregate=subdomains.size()-1;\n+ 825 }\n+ 826 overlapVisitor.setAggregate(aggregate);\n+ 827 aggregateVisitor.setAggregate(aggregate);\n+ 828 subdomains[aggregate].insert(i);\n+ 829 typename AggregatesMap::VertexList vlist;\n+ 830 amap.template breadthFirstSearch(i, aggregate, graph, vlist,\n+aggregateVisitor,\n+ 831 overlapVisitor, visitedMap);\n+ 832 }\n+ 833\n+ 834 std::size_t minsize=10000;\n+ 835 std::size_t maxsize=0;\n+ 836 int sum=0;\n+ 837 for(typename Vector::size_type i=0; i < subdomains.size(); ++i) {\n+ 838 sum+=subdomains[i].size();\n+ 839 minsize=std::min(minsize, subdomains[i].size());\n+ 840 maxsize=std::max(maxsize, subdomains[i].size());\n+ 841 }\n+ 842 Dune::dinfo<<\"Subdomain size: min=\"<\n+853 struct ConstructionTraits >\n+ 854 {\n+855 typedef ConstructionArgs > Arguments;\n+ 856\n+857 static inline std::shared_ptr>\n+construct(Arguments& args)\n+ 858 {\n+ 859 return std::make_shared>\n+ 860 (args.getMatrix(),\n+ 861 args.getSubDomains(),\n+ 862 args.getArgs().relaxationFactor,\n+ 863 args.getArgs().onthefly);\n+ 864 }\n+ 865 };\n+ 866\n+ 867\n+ 868 } // namespace Amg\n+ 869} // namespace Dune\n+ 870\n+ 871\n+ 872\n+ 873#endif\n+novlpschwarz.hh\n+schwarz.hh\n+aggregates.hh\n+Provides classes for the Coloring process of AMG.\n+construction.hh\n+Helper classes for the construction of classes without empty constructor.\n+preconditioners.hh\n+Define general preconditioner interface.\n+Dune::Amg::SmootherTraits<_Richardson<_X,_Y_>_>::Arguments\n+DefaultSmootherArgs< typename X::field_type > Arguments\n+Definition: smoother.hh:74\n+Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n+Y,_l_>_>_>::postSmooth\n+static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:494\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+NoneAdder::operator()\n+void operator()(const T &edge)\n+Definition: smoother.hh:689\n+Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+MultiplicativeSchwarzMode,_MS,_TA_>_>::preSmooth\n+static void preSmooth(Smoother &smoother, Domain &v, const Range &d)\n+Definition: smoother.hh:518\n+Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>::construct\n+static std::shared_ptr< SeqJac< M, X, Y, l > > construct(Arguments &args)\n+Definition: smoother.hh:256\n+Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>::Arguments\n+ConstructionArgs< SeqILU< M, X, Y > > Arguments\n+Definition: smoother.hh:309\n+Dune::Amg::DefaultConstructionArgs::getMatrix\n+const Matrix & getMatrix() const\n+Definition: smoother.hh:114\n+Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+MultiplicativeSchwarzMode,_MS,_TA_>_>::Range\n+Smoother::range_type Range\n+Definition: smoother.hh:515\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+NoneAdder::setAggregate\n+int setAggregate(const AggregateDescriptor &aggregate_)\n+Definition: smoother.hh:691\n+Dune::Amg::SmootherTraits::Arguments\n+DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments\n+Definition: smoother.hh:67\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+VertexAdder::setAggregate\n+int setAggregate(const AggregateDescriptor &aggregate_)\n+Definition: smoother.hh:670\n+Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n+SeqConstructionTraits\n+ConstructionTraits< T > SeqConstructionTraits\n+Definition: smoother.hh:350\n+Dune::Amg::DefaultConstructionArgs::setArgs\n+void setArgs(const SmootherArgs &args)\n+Definition: smoother.hh:119\n+Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+Arguments\n+ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Arguments\n+Definition: smoother.hh:855\n+Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n+Y,_l_>_>_>::Smoother\n+NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > Smoother\n+Definition: smoother.hh:484\n+Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::postSmooth\n+static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:456\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregateAdder::AggregateAdder\n+AggregateAdder(Vector &subdomains_, const AggregatesMap &aggregates_, const\n+MatrixGraph< const M > &graph_, VM &visitedMap_)\n+Definition: smoother.hh:704\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::Overlap\n+Overlap\n+Definition: smoother.hh:538\n+Dune::Amg::DefaultParallelConstructionArgs::setComm\n+void setComm(const C &comm)\n+Definition: smoother.hh:158\n+Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>::Arguments\n+DefaultConstructionArgs< Richardson< X, Y > > Arguments\n+Definition: smoother.hh:269\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::\n+~DefaultConstructionArgs\n+virtual ~DefaultConstructionArgs()\n+Definition: smoother.hh:180\n+Dune::Amg::SmootherTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+Arguments\n+SeqOverlappingSchwarzSmootherArgs< typename M::field_type > Arguments\n+Definition: smoother.hh:552\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+Subdomain\n+Vector::value_type Subdomain\n+Definition: smoother.hh:566\n+Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n+Y,_l_>_>_>::preSmooth\n+static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:488\n+Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::getN\n+int getN()\n+Definition: smoother.hh:293\n+Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n+Y,_l_>_>_>::Range\n+Smoother::range_type Range\n+Definition: smoother.hh:485\n+Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Smoother\n+SeqSOR< M, X, Y, l > Smoother\n+Definition: smoother.hh:446\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregateAdder::operator()\n+void operator()(const T &edge)\n+Definition: smoother.hh:710\n+Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>::construct\n+static std::shared_ptr< SeqSSOR< M, X, Y, l > > construct(Arguments &args)\n+Definition: smoother.hh:224\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregateDescriptor\n+AggregatesMap::AggregateDescriptor AggregateDescriptor\n+Definition: smoother.hh:564\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::onthefly\n+bool onthefly\n+Definition: smoother.hh:541\n+Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>::Arguments\n+DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments\n+Definition: smoother.hh:238\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+setMatrix\n+virtual void setMatrix(const M &matrix, const AggregatesMap &amap)\n+Definition: smoother.hh:568\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setMatrix\n+void setMatrix(const Args &...)\n+Definition: smoother.hh:184\n+Dune::Amg::ConstructionTraits<_SeqJac<_M,_X,_Y,_l_>_>::Arguments\n+DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments\n+Definition: smoother.hh:254\n+Dune::Amg::ConstructionTraits<_SeqSSOR<_M,_X,_Y,_l_>_>::Arguments\n+DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments\n+Definition: smoother.hh:222\n+Dune::Amg::DefaultConstructionArgs::getArgs\n+const SmootherArgs getArgs() const\n+Definition: smoother.hh:133\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+VertexAdder::VertexAdder\n+VertexAdder(Vector &subdomains_, const AggregatesMap &aggregates_)\n+Definition: smoother.hh:661\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+getSubDomains\n+const Vector & getSubDomains()\n+Definition: smoother.hh:653\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+Vector\n+SeqOverlappingSchwarz< M, X, TM, TS, TA >::subdomain_vector Vector\n+Definition: smoother.hh:565\n+Dune::Amg::ConstructionTraits<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+construct\n+static std::shared_ptr< SeqOverlappingSchwarz< M, X, TM, TS, TA > > construct\n+(Arguments &args)\n+Definition: smoother.hh:857\n+Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n+>_>::preSmooth\n+static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:469\n+Dune::Amg::AggregatesMap::begin\n+const_iterator begin() const\n+Definition: aggregates.hh:725\n+Dune::Amg::DefaultConstructionArgs::setMatrix\n+void setMatrix(const Matrix &matrix)\n+Definition: smoother.hh:104\n+Dune::Amg::SmootherApplier::Smoother\n+T Smoother\n+Definition: smoother.hh:371\n+Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::preSmooth\n+static void preSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:450\n+Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n+>_>::Smoother\n+BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > Smoother\n+Definition: smoother.hh:465\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setComm\n+void setComm(T1 &comm)\n+Definition: smoother.hh:193\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+VertexAdder::noSubdomains\n+int noSubdomains() const\n+Definition: smoother.hh:676\n+Dune::Amg::AggregatesMap::iterator\n+AggregateDescriptor * iterator\n+Definition: aggregates.hh:735\n+Dune::Amg::presmooth\n+void presmooth(LevelContext &levelContext, size_t steps)\n+Apply pre smoothing on the current level.\n+Definition: smoother.hh:406\n+Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+MultiplicativeSchwarzMode,_MS,_TA_>_>::Domain\n+Smoother::domain_type Domain\n+Definition: smoother.hh:516\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::SeqOverlappingSchwarzSmootherArgs\n+SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=vertex, bool\n+onthefly_=false)\n+Definition: smoother.hh:543\n+Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::Arguments\n+DefaultParallelConstructionArgs< T, C > Arguments\n+Definition: smoother.hh:337\n+Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n+Arguments\n+DefaultParallelConstructionArgs< T, C > Arguments\n+Definition: smoother.hh:349\n+Dune::Amg::DefaultConstructionArgs::matrix_\n+const Matrix * matrix_\n+Definition: smoother.hh:139\n+Dune::Amg::AggregatesMap::end\n+const_iterator end() const\n+Definition: aggregates.hh:730\n+Dune::Amg::DefaultConstructionArgs::getComm\n+const SequentialInformation & getComm()\n+Definition: smoother.hh:128\n+Dune::Amg::AggregatesMap::AggregateDescriptor\n+V AggregateDescriptor\n+The aggregate descriptor type.\n+Definition: aggregates.hh:580\n+Dune::Amg::AggregatesMap::ISOLATED\n+static const V ISOLATED\n+Identifier of isolated vertices.\n+Definition: aggregates.hh:571\n+Dune::Amg::DefaultSmootherArgs::DefaultSmootherArgs\n+DefaultSmootherArgs()\n+Default constructor.\n+Definition: smoother.hh:56\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+setMatrix\n+void setMatrix(const M &matrix)\n+Definition: smoother.hh:606\n+Dune::Amg::AggregatesMap::noVertices\n+std::size_t noVertices() const\n+Get the number of vertices.\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+VertexAdder::operator()\n+void operator()(const T &edge)\n+Definition: smoother.hh:665\n+Dune::Amg::SmootherApplier::postSmooth\n+static void postSmooth(Smoother &smoother, Domain &v, const Range &d)\n+apply post smoothing in forward direction\n+Definition: smoother.hh:394\n+Dune::Amg::DefaultSmootherArgs::RelaxationFactor\n+FieldTraits< T >::real_type RelaxationFactor\n+The type of the relaxation factor.\n+Definition: smoother.hh:42\n+Dune::Amg::SmootherApplier<_NonoverlappingBlockPreconditioner<_C,_SeqSOR<_M,_X,\n+Y,_l_>_>_>::Domain\n+Smoother::domain_type Domain\n+Definition: smoother.hh:486\n+Dune::Amg::SmootherApplier::Domain\n+Smoother::domain_type Domain\n+Definition: smoother.hh:373\n+Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::setN\n+void setN(int n)\n+Definition: smoother.hh:288\n+Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::construct\n+static std::shared_ptr< BlockPreconditioner< X, Y, C, T > > construct(Arguments\n+&args)\n+Definition: smoother.hh:339\n+Dune::Amg::AggregatesMap::VertexList\n+SLList< VertexDescriptor, Allocator > VertexList\n+The type of a single linked list of vertex descriptors.\n+Definition: aggregates.hh:592\n+Dune::Amg::ConstructionTraits<_NonoverlappingBlockPreconditioner<_C,_T_>_>::\n+construct\n+static std::shared_ptr< NonoverlappingBlockPreconditioner< C, T > > construct\n+(Arguments &args)\n+Definition: smoother.hh:351\n+Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+MultiplicativeSchwarzMode,_MS,_TA_>_>::Smoother\n+SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > Smoother\n+Definition: smoother.hh:514\n+Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>::construct\n+static std::shared_ptr< ParSSOR< M, X, Y, C > > construct(Arguments &args)\n+Definition: smoother.hh:326\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+VertexDescriptor\n+MatrixGraph< M >::VertexDescriptor VertexDescriptor\n+Definition: smoother.hh:562\n+Dune::Amg::ConstructionTraits<_SeqILU<_M,_X,_Y_>_>::construct\n+static std::shared_ptr< SeqILU< M, X, Y > > construct(Arguments &args)\n+Definition: smoother.hh:311\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregateAdder::noSubdomains\n+int noSubdomains() const\n+Definition: smoother.hh:731\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::getComm\n+const SequentialInformation & getComm()\n+Definition: smoother.hh:196\n+Dune::Amg::ConstructionTraits<_SeqSOR<_M,_X,_Y,_l_>_>::construct\n+static std::shared_ptr< SeqSOR< M, X, Y, l > > construct(Arguments &args)\n+Definition: smoother.hh:240\n+Dune::Amg::ConstructionTraits<_Richardson<_X,_Y_>_>::construct\n+static std::shared_ptr< Richardson< X, Y > > construct(Arguments &args)\n+Definition: smoother.hh:271\n+Dune::Amg::DefaultConstructionArgs::setMatrix\n+virtual void setMatrix(const Matrix &matrix, const AggregatesMap &amap)\n+Definition: smoother.hh:108\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+NoneAdder::noSubdomains\n+int noSubdomains() const\n+Definition: smoother.hh:695\n+Dune::Amg::postsmooth\n+void postsmooth(LevelContext &levelContext, size_t steps)\n+Apply post smoothing on the current level.\n+Definition: smoother.hh:428\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregatesMap\n+Dune::Amg::AggregatesMap< VertexDescriptor > AggregatesMap\n+Definition: smoother.hh:563\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::getArgs\n+const SmootherArgs getArgs() const\n+Definition: smoother.hh:201\n+Dune::Amg::DefaultConstructionArgs::setComm\n+void setComm(T1 &comm)\n+Definition: smoother.hh:125\n+Dune::Amg::SmootherApplier<_SeqOverlappingSchwarz<_M,_X,\n+MultiplicativeSchwarzMode,_MS,_TA_>_>::postSmooth\n+static void postSmooth(Smoother &smoother, Domain &v, const Range &d)\n+Definition: smoother.hh:524\n+Dune::Amg::ConstructionTraits<_ParSSOR<_M,_X,_Y,_C_>_>::Arguments\n+DefaultParallelConstructionArgs< M, C > Arguments\n+Definition: smoother.hh:324\n+Dune::Amg::DefaultSmootherArgs::relaxationFactor\n+RelaxationFactor relaxationFactor\n+The relaxation factor to use.\n+Definition: smoother.hh:51\n+Dune::Amg::DefaultParallelConstructionArgs::~DefaultParallelConstructionArgs\n+virtual ~DefaultParallelConstructionArgs()\n+Definition: smoother.hh:155\n+Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Domain\n+Smoother::domain_type Domain\n+Definition: smoother.hh:448\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>::\n+AggregateAdder::setAggregate\n+int setAggregate(const AggregateDescriptor &aggregate_)\n+Definition: smoother.hh:725\n+Dune::Amg::SmootherApplier<_SeqSOR<_M,_X,_Y,_l_>_>::Range\n+Smoother::range_type Range\n+Definition: smoother.hh:447\n+Dune::Amg::DefaultParallelConstructionArgs::getComm\n+const C & getComm() const\n+Definition: smoother.hh:163\n+Dune::Amg::DefaultConstructionArgs::~DefaultConstructionArgs\n+virtual ~DefaultConstructionArgs()\n+Definition: smoother.hh:101\n+Dune::Amg::SmootherApplier::preSmooth\n+static void preSmooth(Smoother &smoother, Domain &v, const Range &d)\n+apply pre smoothing in forward direction\n+Definition: smoother.hh:382\n+Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n+>_>::postSmooth\n+static void postSmooth(Smoother &smoother, Domain &v, Range &d)\n+Definition: smoother.hh:475\n+Dune::Amg::ConstructionTraits<_BlockPreconditioner<_X,_Y,_C,_T_>_>::\n+SeqConstructionTraits\n+ConstructionTraits< T > SeqConstructionTraits\n+Definition: smoother.hh:338\n+Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>::ConstructionArgs\n+ConstructionArgs(int n=0)\n+Definition: smoother.hh:284\n+Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n+>_>::Range\n+Smoother::range_type Range\n+Definition: smoother.hh:466\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>::setArgs\n+void setArgs(const SmootherArgs &args)\n+Definition: smoother.hh:187\n+Dune::Amg::DefaultSmootherArgs::iterations\n+int iterations\n+The numbe of iterations to perform.\n+Definition: smoother.hh:47\n+Dune::Amg::SmootherApplier::Range\n+Smoother::range_type Range\n+Definition: smoother.hh:372\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::overlap\n+Overlap overlap\n+Definition: smoother.hh:540\n+Dune::Amg::SmootherApplier<_BlockPreconditioner<_X,_Y,_C,_SeqSOR<_M,_X,_Y,_l_>\n+>_>::Domain\n+Smoother::domain_type Domain\n+Definition: smoother.hh:467\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::aggregate\n+@ aggregate\n+Definition: smoother.hh:538\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::none\n+@ none\n+Definition: smoother.hh:538\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::pairwise\n+@ pairwise\n+Definition: smoother.hh:538\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs::vertex\n+@ vertex\n+Definition: smoother.hh:538\n Dune\n Definition: allocator.hh:11\n-Dune::operator<<\n-std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n-Send BlockVector to an output stream.\n-Definition: bvector.hh:590\n-Dune::MultiTypeBlockVector\n-A Vector class to support different block types.\n-Definition: multitypeblockvector.hh:59\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::SeqOverlappingSchwarz\n+Sequential overlapping Schwarz preconditioner.\n+Definition: overlappingschwarz.hh:755\n+Dune::SeqOverlappingSchwarz::range_type\n+X range_type\n+The range type of the preconditioner.\n+Definition: overlappingschwarz.hh:770\n+Dune::SeqOverlappingSchwarz::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: overlappingschwarz.hh:765\n+Dune::Amg::ConstructionTraits\n+Traits class for generically constructing non default constructable types.\n+Definition: construction.hh:39\n+Dune::NonoverlappingBlockPreconditioner\n+Nonoverlapping parallel preconditioner.\n+Definition: novlpschwarz.hh:276\n+Dune::NonoverlappingBlockPreconditioner::range_type\n+P::range_type range_type\n+The range type of the preconditioner.\n+Definition: novlpschwarz.hh:284\n+Dune::NonoverlappingBlockPreconditioner::domain_type\n+P::domain_type domain_type\n+The domain type of the preconditioner.\n+Definition: novlpschwarz.hh:282\n+Dune::MultiplicativeSchwarzMode\n+Tag that tells the Schwarz method to be multiplicative.\n+Definition: overlappingschwarz.hh:126\n+Dune::Amg::AggregatesMap\n+Class providing information about the mapping of the vertices onto aggregates.\n+Definition: aggregates.hh:560\n+Dune::Amg::MatrixGraph<_const_M_>\n+Dune::Amg::MatrixGraph::end\n+VertexIterator end()\n+Get an iterator over the vertices.\n+Dune::Amg::MatrixGraph::VertexDescriptor\n+M::size_type VertexDescriptor\n+The vertex descriptor.\n+Definition: graph.hh:73\n+Dune::Amg::MatrixGraph::begin\n+VertexIterator begin()\n+Get an iterator over the vertices.\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::Amg::DefaultSmootherArgs\n+The default class for the smoother arguments.\n+Definition: smoother.hh:38\n+Dune::Amg::SmootherTraits\n+Traits class for getting the attribute class of a smoother.\n+Definition: smoother.hh:66\n+Dune::Amg::DefaultConstructionArgs\n+Construction Arguments for the default smoothers.\n+Definition: smoother.hh:93\n+Dune::Amg::ConstructionArgs\n+Definition: smoother.hh:148\n+Dune::Amg::DefaultParallelConstructionArgs\n+Definition: smoother.hh:153\n+Dune::Amg::DefaultConstructionArgs<_Richardson<_X,_Y_>_>\n+Definition: smoother.hh:174\n+Dune::Amg::ConstructionArgs<_SeqILU<_M,_X,_Y_>_>\n+Definition: smoother.hh:282\n+Dune::Amg::SmootherApplier\n+Helper class for applying the smoothers.\n+Definition: smoother.hh:370\n+Dune::Amg::SeqOverlappingSchwarzSmootherArgs\n+Definition: smoother.hh:537\n+Dune::Amg::ConstructionArgs<_SeqOverlappingSchwarz<_M,_X,_TM,_TS,_TA_>_>\n+Definition: smoother.hh:558\n+Dune::SeqSSOR\n+Sequential SSOR preconditioner.\n+Definition: preconditioners.hh:141\n+Dune::SeqSOR\n+Sequential SOR preconditioner.\n+Definition: preconditioners.hh:261\n+Dune::SeqSOR::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:266\n+Dune::SeqSOR::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:268\n+Dune::SeqJac\n+The sequential jacobian preconditioner.\n+Definition: preconditioners.hh:412\n+Dune::SeqILU\n+Sequential ILU preconditioner.\n+Definition: preconditioners.hh:532\n+Dune::Richardson\n+Richardson preconditioner.\n+Definition: preconditioners.hh:713\n+Dune::ParSSOR\n+A parallel SSOR preconditioner.\n+Definition: schwarz.hh:175\n+Dune::BlockPreconditioner\n+Block parallel preconditioner.\n+Definition: schwarz.hh:278\n+Dune::BlockPreconditioner::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: schwarz.hh:285\n+Dune::BlockPreconditioner::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: schwarz.hh:290\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00182.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00182.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solverfactory.hh File Reference\n+dune-istl: galerkin.hh File Reference\n \n \n \n \n \n \n \n@@ -58,95 +58,74 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    solverfactory.hh File Reference
    \n+Namespaces
    \n+ \n \n
    \n-
    #include <unordered_map>
    \n-#include <functional>
    \n-#include <memory>
    \n-#include <dune/common/parametertree.hh>
    \n-#include <dune/common/singleton.hh>
    \n-#include "solverregistry.hh"
    \n-#include <dune/istl/solver.hh>
    \n-#include <dune/istl/schwarz.hh>
    \n-#include <dune/istl/novlpschwarz.hh>
    \n+\n+

    Provides a class for building the galerkin product based on a aggregation scheme. \n+More...

    \n+
    #include "aggregates.hh"
    \n+#include "pinfo.hh"
    \n+#include <dune/common/poolallocator.hh>
    \n+#include <dune/common/enumset.hh>
    \n+#include <set>
    \n+#include <limits>
    \n+#include <algorithm>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::SolverFactory< Operator >
     Factory to assembly solvers configured by a ParameterTree. More...
    struct  Dune::Amg::OverlapVertex< T >
     
    class  Dune::Amg::SparsityBuilder< M >
     Functor for building the sparsity pattern of the matrix using examineConnectivity. More...
     
    class  Dune::Amg::BaseGalerkinProduct
     
    class  Dune::Amg::GalerkinProduct< T >
     
    class  Dune::Amg::GalerkinProduct< SequentialInformation >
     
    struct  Dune::Amg::BaseConnectivityConstructor
     
    class  Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder< G, S, V >
     Visitor for identifying connected aggregates during a breadthFirstSearch. More...
     
    struct  Dune::Amg::ConnectivityConstructor< G, T >
     
    struct  Dune::Amg::ConnectivityConstructor< G, SequentialInformation >
     
    struct  Dune::Amg::DirichletBoundarySetter< T >
     
    struct  Dune::Amg::DirichletBoundarySetter< SequentialInformation >
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-

    \n-Typedefs

    template<class M , class X , class Y >
    using Dune::DirectSolverSignature = std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &)
     
    template<class M , class X , class Y >
    using Dune::DirectSolverFactory = Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > >
     
    template<class M , class X , class Y >
    using Dune::PreconditionerSignature = std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const ParameterTree &)
     
    template<class M , class X , class Y >
    using Dune::PreconditionerFactory = Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > >
     
    template<class X , class Y >
    using Dune::IterativeSolverSignature = std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &, const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &)
     
    template<class X , class Y >
    using Dune::IterativeSolverFactory = Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > >
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n

    \n-Functions

    template<class O , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const O &)
     
    template<class M , class X , class Y , class C , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y , class C , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< MatrixAdapter< M, X, Y > > &)
     
    template<class M , class X , class Y , class C >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y , class C >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class Operator >
    std::shared_ptr< InverseOperator< typename Operator::domain_type, typename Operator::range_type > > Dune::getSolverFromFactory (std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > prec=nullptr)
     Instantiates an InverseOperator from an Operator and a configuration given as a ParameterTree. More...
     
    namespace  Dune::Amg
     
    \n-
    \n+

    Detailed Description

    \n+

    Provides a class for building the galerkin product based on a aggregation scheme.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,103 +4,62 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Typedefs | Functions\n-solverfactory.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"solverregistry.hh\"\n-#include \n-#include \n-#include \n+ * paamg\n+Classes | Namespaces\n+galerkin.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides a class for building the galerkin product based on a aggregation\n+scheme. More...\n+#include \"aggregates.hh\"\n+#include \"pinfo.hh\"\n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::SolverFactory<_Operator_>\n-\u00a0 Factory to assembly solvers configured by a ParameterTree. More...\n+struct \u00a0Dune::Amg::OverlapVertex<_T_>\n+\u00a0\n+ class \u00a0Dune::Amg::SparsityBuilder<_M_>\n+\u00a0 Functor for building the sparsity pattern of the matrix using\n+ examineConnectivity. More...\n+\u00a0\n+ class \u00a0Dune::Amg::BaseGalerkinProduct\n+\u00a0\n+ class \u00a0Dune::Amg::GalerkinProduct<_T_>\n+\u00a0\n+ class \u00a0Dune::Amg::GalerkinProduct<_SequentialInformation_>\n+\u00a0\n+struct \u00a0Dune::Amg::BaseConnectivityConstructor\n+\u00a0\n+ class \u00a0Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder<_G,_S,_V_>\n+\u00a0 Visitor for identifying connected aggregates during a\n+ breadthFirstSearch. More...\n+\u00a0\n+struct \u00a0Dune::Amg::ConnectivityConstructor<_G,_T_>\n+\u00a0\n+struct \u00a0Dune::Amg::ConnectivityConstructor<_G,_SequentialInformation_>\n+\u00a0\n+struct \u00a0Dune::Amg::DirichletBoundarySetter<_T_>\n+\u00a0\n+struct \u00a0Dune::Amg::DirichletBoundarySetter<_SequentialInformation_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Typedefs\n-template\n-using\u00a0Dune::DirectSolverSignature = std::shared_ptr< InverseOperator< X, Y > >\n- (const M &, const ParameterTree &)\n-\u00a0\n-template\n-using\u00a0Dune::DirectSolverFactory = Singleton< ParameterizedObjectFactory<\n- DirectSolverSignature< M, X, Y > > >\n-\u00a0\n-template\n-using\u00a0Dune::PreconditionerSignature = std::shared_ptr< Preconditioner< X, Y >\n- >(const std::shared_ptr< M > &, const ParameterTree &)\n-\u00a0\n-template\n-using\u00a0Dune::PreconditionerFactory = Singleton< ParameterizedObjectFactory<\n- PreconditionerSignature< M, X, Y > > >\n-\u00a0\n-template\n-using\u00a0Dune::IterativeSolverSignature = std::shared_ptr< InverseOperator< X, Y\n- > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::\n- shared_ptr< ScalarProduct< X > > &, const std::shared_ptr<\n- Preconditioner< X, Y > >, const ParameterTree &)\n-\u00a0\n-template\n-using\u00a0Dune::IterativeSolverFactory = Singleton< ParameterizedObjectFactory<\n- IterativeSolverSignature< X, Y > > >\n-\u00a0\n- Functions\n-template\n- std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n- std::shared_ptr< Preconditioner > &prec,\n- const O &)\n-\u00a0\n-template\n- std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n- std::shared_ptr< Preconditioner > &prec,\n- const std::shared_ptr<\n- OverlappingSchwarzOperator< M, X, Y, C >\n- > &op)\n-\u00a0\n-template\n- std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n- std::shared_ptr< Preconditioner > &prec,\n- const std::shared_ptr<\n- NonoverlappingSchwarzOperator< M, X, Y,\n- C > > &op)\n-\u00a0\n-template\n-std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n- shared_ptr< MatrixAdapter< M, X, Y > >\n- &)\n-\u00a0\n-template\n-std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n- shared_ptr< OverlappingSchwarzOperator<\n- M, X, Y, C > > &op)\n-\u00a0\n-template\n-std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n- shared_ptr<\n- NonoverlappingSchwarzOperator< M, X, Y,\n- C > > &op)\n-\u00a0\n-template\n- std::shared_ptr< InverseOperator< Dune::getSolverFromFactory (std::\n- typename Operator::domain_type, shared_ptr< Operator > op, const\n- typename Operator::range_type > >\u00a0ParameterTree &config, std::shared_ptr<\n- Preconditioner< typename Operator::\n- domain_type, typename Operator::\n- range_type > > prec=nullptr)\n- Instantiates an InverseOperator from an\n-\u00a0 Operator and a configuration given as a\n- ParameterTree. More...\n+namespace \u00a0Dune::Amg\n \u00a0\n+***** Detailed Description *****\n+Provides a class for building the galerkin product based on a aggregation\n+scheme.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00182_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00182_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solverfactory.hh Source File\n+dune-istl: galerkin.hh Source File\n \n \n \n \n \n \n \n@@ -58,229 +58,681 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    solverfactory.hh
    \n+
    galerkin.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5
    \n-
    6#ifndef DUNE_ISTL_SOLVERFACTORY_HH
    \n-
    7#define DUNE_ISTL_SOLVERFACTORY_HH
    \n-
    8
    \n-
    9#include <unordered_map>
    \n-
    10#include <functional>
    \n-
    11#include <memory>
    \n-
    12
    \n-
    13#include <dune/common/parametertree.hh>
    \n-
    14#include <dune/common/singleton.hh>
    \n+
    5#ifndef DUNE_GALERKIN_HH
    \n+
    6#define DUNE_GALERKIN_HH
    \n+
    7
    \n+
    8#include "aggregates.hh"
    \n+
    9#include "pinfo.hh"
    \n+
    10#include <dune/common/poolallocator.hh>
    \n+
    11#include <dune/common/enumset.hh>
    \n+
    12#include <set>
    \n+
    13#include <limits>
    \n+
    14#include <algorithm>
    \n
    15
    \n-
    16#include "solverregistry.hh"
    \n-
    17#include <dune/istl/solver.hh>
    \n-
    18#include <dune/istl/schwarz.hh>
    \n-\n-
    20
    \n-
    21namespace Dune{
    \n-
    26 // Direct solver factory:
    \n-
    27 template<class M, class X, class Y>
    \n-
    28 using DirectSolverSignature = std::shared_ptr<InverseOperator<X,Y>>(const M&, const ParameterTree&);
    \n-
    29 template<class M, class X, class Y>
    \n-
    30 using DirectSolverFactory = Singleton<ParameterizedObjectFactory<DirectSolverSignature<M,X,Y>>>;
    \n-
    31
    \n-
    32 // Preconditioner factory:
    \n-
    33 template<class M, class X, class Y>
    \n-
    34 using PreconditionerSignature = std::shared_ptr<Preconditioner<X,Y>>(const std::shared_ptr<M>&, const ParameterTree&);
    \n-
    35 template<class M, class X, class Y>
    \n-
    36 using PreconditionerFactory = Singleton<ParameterizedObjectFactory<PreconditionerSignature<M,X,Y>>>;
    \n-
    37
    \n-
    38 // Iterative solver factory
    \n-
    39 template<class X, class Y>
    \n-
    40 using IterativeSolverSignature = std::shared_ptr<InverseOperator<X,Y>>(const std::shared_ptr<LinearOperator<X,Y>>&, const std::shared_ptr<ScalarProduct<X>>&, const std::shared_ptr<Preconditioner<X,Y>>, const ParameterTree&);
    \n-
    41 template<class X, class Y>
    \n-
    42 using IterativeSolverFactory = Singleton<ParameterizedObjectFactory<IterativeSolverSignature<X,Y>>>;
    \n+
    16namespace Dune
    \n+
    17{
    \n+
    18 namespace Amg
    \n+
    19 {
    \n+
    31 template<class T>
    \n+\n+
    33 {
    \n+
    37 typedef T Aggregate;
    \n+
    38
    \n+
    42 typedef T Vertex;
    \n
    43
    \n-
    44 // initSolverFactories differs in different compilation units, so we have it
    \n-
    45 // in an anonymous namespace
    \n-
    46 namespace {
    \n-
    47
    \n-
    53 template<class O>
    \n-
    54 int initSolverFactories(){
    \n-
    55 using M = typename O::matrix_type;
    \n-
    56 using X = typename O::range_type;
    \n-
    57 using Y = typename O::domain_type;
    \n-
    58 using TL = Dune::TypeList<M,X,Y>;
    \n-\n-
    60 addRegistryToFactory<TL>(dsfac, DirectSolverTag{});
    \n-\n-
    62 addRegistryToFactory<TL>(pfac, PreconditionerTag{});
    \n-
    63 using TLS = Dune::TypeList<X,Y>;
    \n-\n-
    65 return addRegistryToFactory<TLS>(isfac, IterativeSolverTag{});
    \n-
    66 }
    \n-
    77 template<class O, class X, class Y>
    \n-
    78 [[deprecated("Use method 'initSolverFactories<O>' instead")]]
    \n-
    79 int initSolverFactories() {
    \n-
    80 return initSolverFactories<O>();
    \n-
    81 }
    \n-
    82 } // end anonymous namespace
    \n-
    83
    \n-
    84
    \n-
    85 template<class O, class Preconditioner>
    \n-
    86 std::shared_ptr<Preconditioner> wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n-
    87 const O&)
    \n-
    88 {
    \n-
    89 return prec;
    \n-
    90 }
    \n-
    91
    \n-
    92 template<class M, class X, class Y, class C, class Preconditioner>
    \n-
    93 std::shared_ptr<Preconditioner>
    \n-
    94 wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n-
    95 const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n-
    96 {
    \n-
    97 return std::make_shared<BlockPreconditioner<X,Y,C,Preconditioner> >(prec, op->getCommunication());
    \n-
    98 }
    \n-
    99
    \n-
    100 template<class M, class X, class Y, class C, class Preconditioner>
    \n-
    101 std::shared_ptr<Preconditioner>
    \n-
    102 wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n-
    103 const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n-
    104 {
    \n-
    105 return std::make_shared<NonoverlappingBlockPreconditioner<C,Preconditioner> >(prec, op->getCommunication());
    \n-
    106 }
    \n-
    107
    \n-
    108 template<class M, class X, class Y>
    \n-
    109 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<MatrixAdapter<M,X,Y> >&)
    \n-
    110 {
    \n-
    111 return std::make_shared<SeqScalarProduct<X>>();
    \n-
    112 }
    \n-
    113 template<class M, class X, class Y, class C>
    \n-
    114 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n-
    115 {
    \n-
    116 return createScalarProduct<X>(op->getCommunication(), op->category());
    \n-
    117 }
    \n-
    118
    \n-
    119 template<class M, class X, class Y, class C>
    \n-
    120 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n-
    121 {
    \n-
    122 return createScalarProduct<X>(op->getCommunication(), op->category());
    \n-
    123 }
    \n-
    124
    \n-
    144 template<class Operator>
    \n-\n-
    146 using Domain = typename Operator::domain_type;
    \n-
    147 using Range = typename Operator::range_type;
    \n-\n-\n-
    150
    \n-
    151 template<class O>
    \n-
    152 using _matrix_type = typename O::matrix_type;
    \n-
    153 using matrix_type = Std::detected_or_t<int, _matrix_type, Operator>;
    \n-
    154 static constexpr bool isAssembled = !std::is_same<matrix_type, int>::value;
    \n-
    155
    \n-
    156 static const matrix_type* getmat(std::shared_ptr<Operator> op){
    \n-
    157 std::shared_ptr<AssembledLinearOperator<matrix_type, Domain, Range>> aop
    \n-
    158 = std::dynamic_pointer_cast<AssembledLinearOperator<matrix_type, Domain, Range>>(op);
    \n-
    159 if(aop)
    \n-
    160 return &aop->getmat();
    \n-
    161 return nullptr;
    \n-
    162 }
    \n-
    163
    \n-
    164 public:
    \n-
    165
    \n-
    168 static std::shared_ptr<Solver> get(std::shared_ptr<Operator> op,
    \n-
    169 const ParameterTree& config,
    \n-
    170 std::shared_ptr<Preconditioner> prec = nullptr){
    \n-
    171 std::string type = config.get<std::string>("type");
    \n-
    172 std::shared_ptr<Solver> result;
    \n-
    173 const matrix_type* mat = getmat(op);
    \n-
    174 if(mat){
    \n-\n-
    176 if(op->category()!=SolverCategory::sequential){
    \n-
    177 DUNE_THROW(NotImplemented, "The solver factory does not support parallel direct solvers!");
    \n-
    178 }
    \n-
    179 result = DirectSolverFactory<matrix_type, Domain, Range>::instance().create(type, *mat, config);
    \n-
    180 return result;
    \n-
    181 }
    \n-
    182 }
    \n-
    183 // if no direct solver is found it might be an iterative solver
    \n-\n-
    185 DUNE_THROW(Dune::InvalidStateException, "Solver not found in the factory.");
    \n-
    186 }
    \n-
    187 if(!prec){
    \n-
    188 const ParameterTree& precConfig = config.sub("preconditioner");
    \n-
    189 std::string prec_type = precConfig.get<std::string>("type");
    \n-
    190 prec = PreconditionerFactory<Operator, Domain, Range>::instance().create(prec_type, op, precConfig);
    \n-
    191 if (prec->category() != op->category() && prec->category() == SolverCategory::sequential)
    \n-
    192 // try to wrap to a parallel preconditioner
    \n-
    193 prec = wrapPreconditioner4Parallel(prec, op);
    \n-
    194 }
    \n-
    195 std::shared_ptr<ScalarProduct<Domain>> sp = createScalarProduct(op);
    \n-
    196 result = IterativeSolverFactory<Domain, Range>::instance().create(type, op, sp, prec, config);
    \n-
    197 return result;
    \n-
    198 }
    \n+\n+
    48
    \n+\n+
    53 };
    \n+
    54
    \n+
    55
    \n+
    56
    \n+
    61 template<class M>
    \n+\n+
    63 {
    \n+
    64 public:
    \n+
    70 SparsityBuilder(M& matrix);
    \n+
    71
    \n+
    72 void insert(const typename M::size_type& index);
    \n+
    73
    \n+
    74 void operator++();
    \n+
    75
    \n+
    76 std::size_t minRowSize();
    \n+
    77
    \n+
    78 std::size_t maxRowSize();
    \n+
    79
    \n+
    80 std::size_t sumRowSize();
    \n+
    81 std::size_t index()
    \n+
    82 {
    \n+
    83 return row_.index();
    \n+
    84 }
    \n+
    85 private:
    \n+
    87 typename M::CreateIterator row_;
    \n+
    89 std::size_t minRowSize_;
    \n+
    91 std::size_t maxRowSize_;
    \n+
    92 std::size_t sumRowSize_;
    \n+
    93#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    94 bool diagonalInserted;
    \n+
    95#endif
    \n+
    96 };
    \n+
    97
    \n+\n+
    99 {
    \n+
    100 public:
    \n+
    109 template<class M, class V, class I, class O>
    \n+
    110 void calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
    \n+
    111 const I& pinfo, const O& copy);
    \n+
    112
    \n+
    113 };
    \n+
    114
    \n+
    115 template<class T>
    \n+\n+
    117 : public BaseGalerkinProduct
    \n+
    118 {
    \n+
    119 public:
    \n+\n+
    121
    \n+
    131 template<class G, class V, class Set>
    \n+
    132 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
    \n+
    133 const ParallelInformation& pinfo,
    \n+\n+
    135 const typename G::Matrix::size_type& size,
    \n+
    136 const Set& copy);
    \n+
    137 private:
    \n+
    138
    \n+
    145 template<class G, class I, class Set>
    \n+\n+
    147 buildOverlapVertices(const G& graph, const I& pinfo,
    \n+\n+
    149 const Set& overlap,
    \n+
    150 std::size_t& overlapCount);
    \n+
    151
    \n+
    152 template<class A>
    \n+
    153 struct OVLess
    \n+
    154 {
    \n+\n+
    156 {
    \n+
    157 return *o1.aggregate < *o2.aggregate;
    \n+
    158 }
    \n+
    159 };
    \n+
    160 };
    \n+
    161
    \n+
    162 template<>
    \n+\n+
    164 : public BaseGalerkinProduct
    \n+
    165 {
    \n+
    166 public:
    \n+
    176 template<class G, class V, class Set>
    \n+
    177 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
    \n+
    178 const SequentialInformation& pinfo,
    \n+\n+
    180 const typename G::Matrix::size_type& size,
    \n+
    181 const Set& copy);
    \n+
    182 };
    \n+
    183
    \n+\n+
    185 {
    \n+
    186 template<class R, class G, class V>
    \n+
    187 static void constructOverlapConnectivity(R& row, G& graph, V& visitedMap,
    \n+\n+\n+\n+
    191
    \n+
    195 template<class R, class G, class V>
    \n+
    196 static void constructNonOverlapConnectivity(R& row, G& graph, V& visitedMap,
    \n+\n+
    198 const typename G::VertexDescriptor& seed);
    \n
    199
    \n-
    203 static std::shared_ptr<Preconditioner> getPreconditioner(std::shared_ptr<Operator> op,
    \n-
    204 const ParameterTree& config){
    \n-
    205 const matrix_type* mat = getmat(op);
    \n-
    206 if(mat){
    \n-
    207 std::string prec_type = config.get<std::string>("type");
    \n-
    208 return PreconditionerFactory<Operator, Domain, Range>::instance().create(prec_type, op, config);
    \n-
    209 }else{
    \n-
    210 DUNE_THROW(InvalidStateException, "Could not obtain matrix from operator. Please pass in an AssembledLinearOperator.");
    \n-
    211 }
    \n-
    212 }
    \n-
    213 };
    \n-
    214
    \n-
    225 template<class Operator>
    \n-
    226 std::shared_ptr<InverseOperator<typename Operator::domain_type,
    \n-
    227 typename Operator::range_type>> getSolverFromFactory(std::shared_ptr<Operator> op,
    \n-
    228 const ParameterTree& config,
    \n-
    229 std::shared_ptr<Preconditioner<typename Operator::domain_type,
    \n-
    230 typename Operator::range_type>> prec = nullptr){
    \n-
    231 return SolverFactory<Operator>::get(op, config, prec);
    \n-
    232 }
    \n-
    233
    \n-
    237} // end namespace Dune
    \n-
    238
    \n-
    239
    \n-
    240#endif
    \n-
    Define general, extensible interface for inverse operators.
    \n-\n-\n-\n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > > PreconditionerFactory
    Definition: solverfactory.hh:36
    \n-
    Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > > DirectSolverFactory
    Definition: solverfactory.hh:30
    \n-
    std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &, const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &) IterativeSolverSignature
    Definition: solverfactory.hh:40
    \n-
    std::shared_ptr< Preconditioner > wrapPreconditioner4Parallel(const std::shared_ptr< Preconditioner > &prec, const O &)
    Definition: solverfactory.hh:86
    \n-
    std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &) DirectSolverSignature
    Definition: solverfactory.hh:28
    \n-
    std::shared_ptr< InverseOperator< typename Operator::domain_type, typename Operator::range_type > > getSolverFromFactory(std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > prec=nullptr)
    Instantiates an InverseOperator from an Operator and a configuration given as a ParameterTree.
    Definition: solverfactory.hh:227
    \n-
    Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > > IterativeSolverFactory
    Definition: solverfactory.hh:42
    \n-
    std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const ParameterTree &) PreconditionerSignature
    Definition: solverfactory.hh:34
    \n+
    200
    \n+
    204 template<class G, class S, class V>
    \n+\n+
    206 {
    \n+
    207 public:
    \n+
    211 typedef G Graph;
    \n+
    215 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;
    \n+
    216
    \n+
    220 typedef S Set;
    \n+
    221
    \n+
    225 typedef V VisitedMap;
    \n+
    226
    \n+
    230 typedef typename Graph::VertexDescriptor Vertex;
    \n+
    231
    \n+
    239 ConnectedBuilder(const AggregatesMap<Vertex>& aggregates, Graph& graph,
    \n+
    240 VisitedMap& visitedMap, Set& connected);
    \n+
    241
    \n+
    246 void operator()(const ConstEdgeIterator& edge);
    \n+
    247
    \n+
    248 private:
    \n+
    252 const AggregatesMap<Vertex>& aggregates_;
    \n+
    253
    \n+
    254 Graph& graph_;
    \n+
    255
    \n+
    259 VisitedMap& visitedMap_;
    \n+
    260
    \n+
    264 Set& connected_;
    \n+
    265 };
    \n+
    266
    \n+
    267 };
    \n+
    268
    \n+
    269 template<class G, class T>
    \n+\n+
    271 {
    \n+
    272 typedef typename G::VertexDescriptor Vertex;
    \n+
    273
    \n+
    274 template<class V, class O, class R>
    \n+
    275 static void examine(G& graph,
    \n+
    276 V& visitedMap,
    \n+
    277 const T& pinfo,
    \n+
    278 const AggregatesMap<Vertex>& aggregates,
    \n+
    279 const O& overlap,
    \n+
    280 const OverlapVertex<Vertex>* overlapVertices,
    \n+
    281 const OverlapVertex<Vertex>* overlapEnd,
    \n+
    282 R& row);
    \n+
    283 };
    \n+
    284
    \n+
    285 template<class G>
    \n+\n+
    287 {
    \n+
    288 typedef typename G::VertexDescriptor Vertex;
    \n+
    289
    \n+
    290 template<class V, class R>
    \n+
    291 static void examine(G& graph,
    \n+
    292 V& visitedMap,
    \n+
    293 const SequentialInformation& pinfo,
    \n+
    294 const AggregatesMap<Vertex>& aggregates,
    \n+
    295 R& row);
    \n+
    296 };
    \n+
    297
    \n+
    298 template<class T>
    \n+\n+
    300 {
    \n+
    301 template<class M, class O>
    \n+
    302 static void set(M& coarse, const T& pinfo, const O& copy);
    \n+
    303 };
    \n+
    304
    \n+
    305 template<>
    \n+\n+
    307 {
    \n+
    308 template<class M, class O>
    \n+
    309 static void set(M& coarse, const SequentialInformation& pinfo, const O& copy);
    \n+
    310 };
    \n+
    311
    \n+
    312 template<class R, class G, class V>
    \n+\n+\n+
    315 const typename G::VertexDescriptor& seed)
    \n+
    316 {
    \n+
    317 assert(row.index()==aggregates[seed]);
    \n+
    318 row.insert(aggregates[seed]);
    \n+
    319 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
    \n+
    320 typedef typename G::VertexDescriptor Vertex;
    \n+
    321 typedef std::allocator<Vertex> Allocator;
    \n+
    322 typedef SLList<Vertex,Allocator> VertexList;
    \n+
    323 typedef typename AggregatesMap<Vertex>::DummyEdgeVisitor DummyVisitor;
    \n+
    324 VertexList vlist;
    \n+
    325 DummyVisitor dummy;
    \n+
    326 aggregates.template breadthFirstSearch<true,false>(seed,aggregates[seed], graph, vlist, dummy,
    \n+
    327 conBuilder, visitedMap);
    \n+
    328 }
    \n+
    329
    \n+
    330 template<class R, class G, class V>
    \n+\n+\n+\n+\n+
    335 {
    \n+
    336 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
    \n+
    337 const typename G::VertexDescriptor aggregate=*seed->aggregate;
    \n+
    338
    \n+
    339 if (row.index()==*seed->aggregate) {
    \n+
    340 while(seed != overlapEnd && aggregate == *seed->aggregate) {
    \n+
    341 row.insert(*seed->aggregate);
    \n+
    342 // Walk over all neighbours and add them to the connected array.
    \n+
    343 visitNeighbours(graph, seed->vertex, conBuilder);
    \n+
    344 // Mark vertex as visited
    \n+
    345 put(visitedMap, seed->vertex, true);
    \n+
    346 ++seed;
    \n+
    347 }
    \n+
    348 }
    \n+
    349 }
    \n+
    350
    \n+
    351 template<class G, class S, class V>
    \n+\n+
    353 Graph& graph, VisitedMap& visitedMap,
    \n+
    354 Set& connected)
    \n+
    355 : aggregates_(aggregates), graph_(graph), visitedMap_(visitedMap), connected_(connected)
    \n+
    356 {}
    \n+
    357
    \n+
    358 template<class G, class S, class V>
    \n+\n+
    360 {
    \n+
    361 const Vertex& vertex = aggregates_[edge.target()];
    \n+\n+\n+
    364 connected_.insert(vertex);
    \n+
    365 }
    \n+
    366
    \n+
    367 template<class T>
    \n+
    368 template<class G, class I, class Set>
    \n+\n+
    370 GalerkinProduct<T>::buildOverlapVertices(const G& graph, const I& pinfo,
    \n+\n+
    372 const Set& overlap,
    \n+
    373 std::size_t& overlapCount)
    \n+
    374 {
    \n+
    375 // count the overlap vertices.
    \n+
    376 typedef typename G::ConstVertexIterator ConstIterator;
    \n+
    377 typedef typename I::GlobalLookupIndexSet GlobalLookup;
    \n+
    378 typedef typename GlobalLookup::IndexPair IndexPair;
    \n+
    379
    \n+
    380 const ConstIterator end = graph.end();
    \n+
    381 overlapCount = 0;
    \n+
    382
    \n+
    383 const GlobalLookup& lookup=pinfo.globalLookup();
    \n+
    384
    \n+
    385 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
    \n+
    386 const IndexPair* pair = lookup.pair(*vertex);
    \n+
    387
    \n+
    388 if(pair!=0 && overlap.contains(pair->local().attribute()))
    \n+
    389 ++overlapCount;
    \n+
    390 }
    \n+
    391 // Allocate space
    \n+
    392 typedef typename G::VertexDescriptor Vertex;
    \n+
    393
    \n+
    394 OverlapVertex<Vertex>* overlapVertices = new OverlapVertex<Vertex>[overlapCount=0 ? 1 : overlapCount];
    \n+
    395 if(overlapCount==0)
    \n+
    396 return overlapVertices;
    \n+
    397
    \n+
    398 // Initialize them
    \n+
    399 overlapCount=0;
    \n+
    400 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
    \n+
    401 const IndexPair* pair = lookup.pair(*vertex);
    \n+
    402
    \n+
    403 if(pair!=0 && overlap.contains(pair->local().attribute())) {
    \n+
    404 overlapVertices[overlapCount].aggregate = &aggregates[pair->local()];
    \n+
    405 overlapVertices[overlapCount].vertex = pair->local();
    \n+
    406 ++overlapCount;
    \n+
    407 }
    \n+
    408 }
    \n+
    409
    \n+
    410 dverb << overlapCount<<" overlap vertices"<<std::endl;
    \n+
    411
    \n+
    412 std::sort(overlapVertices, overlapVertices+overlapCount, OVLess<Vertex>());
    \n+
    413 // due to the sorting the isolated aggregates (to be skipped) are at the end.
    \n+
    414
    \n+
    415 return overlapVertices;
    \n+
    416 }
    \n+
    417
    \n+
    418 template<class G, class T>
    \n+
    419 template<class V, class O, class R>
    \n+\n+
    421 V& visitedMap,
    \n+
    422 const T& pinfo,
    \n+
    423 const AggregatesMap<Vertex>& aggregates,
    \n+
    424 const O& overlap,
    \n+
    425 const OverlapVertex<Vertex>* overlapVertices,
    \n+
    426 const OverlapVertex<Vertex>* overlapEnd,
    \n+
    427 R& row)
    \n+
    428 {
    \n+
    429 typedef typename T::GlobalLookupIndexSet GlobalLookup;
    \n+
    430 const GlobalLookup& lookup = pinfo.globalLookup();
    \n+
    431
    \n+
    432 typedef typename G::VertexIterator VertexIterator;
    \n+
    433
    \n+
    434 VertexIterator vend=graph.end();
    \n+
    435
    \n+
    436#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    437 std::set<Vertex> examined;
    \n+
    438#endif
    \n+
    439
    \n+
    440 // The aggregates owned by the process have lower local indices
    \n+
    441 // then those not owned. We process them in the first pass.
    \n+
    442 // They represent the rows 0, 1, ..., n of the coarse matrix
    \n+
    443 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex)
    \n+
    444 if(!get(visitedMap, *vertex)) {
    \n+
    445 // In the first pass we only process owner nodes
    \n+
    446 typedef typename GlobalLookup::IndexPair IndexPair;
    \n+
    447 const IndexPair* pair = lookup.pair(*vertex);
    \n+
    448 if(pair==0 || !overlap.contains(pair->local().attribute())) {
    \n+
    449#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    450 assert(examined.find(aggregates[*vertex])==examined.end());
    \n+
    451 examined.insert(aggregates[*vertex]);
    \n+
    452#endif
    \n+
    453 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
    \n+
    454
    \n+
    455 // only needed for ALU
    \n+
    456 // (ghosts with same global id as owners on the same process)
    \n+
    457 if (SolverCategory::category(pinfo) == static_cast<int>(SolverCategory::nonoverlapping)) {
    \n+
    458 if(overlapVertices != overlapEnd) {
    \n+
    459 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
    \n+
    460 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
    \n+
    461 }
    \n+
    462 else{
    \n+
    463 ++overlapVertices;
    \n+
    464 }
    \n+
    465 }
    \n+
    466 }
    \n+
    467 ++row;
    \n+
    468 }
    \n+
    469 }
    \n+
    470
    \n+
    471 dvverb<<"constructed "<<row.index()<<" non-overlapping rows"<<std::endl;
    \n+
    472
    \n+
    473 // Now come the aggregates not owned by use.
    \n+
    474 // They represent the rows n+1, ..., N
    \n+
    475 while(overlapVertices != overlapEnd)
    \n+
    476 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
    \n+
    477
    \n+
    478#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    479 typedef typename GlobalLookup::IndexPair IndexPair;
    \n+
    480 const IndexPair* pair = lookup.pair(overlapVertices->vertex);
    \n+
    481 assert(pair!=0 && overlap.contains(pair->local().attribute()));
    \n+
    482 assert(examined.find(aggregates[overlapVertices->vertex])==examined.end());
    \n+
    483 examined.insert(aggregates[overlapVertices->vertex]);
    \n+
    484#endif
    \n+
    485 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
    \n+
    486 ++row;
    \n+
    487 }else{
    \n+
    488 ++overlapVertices;
    \n+
    489 }
    \n+
    490 }
    \n+
    491
    \n+
    492 template<class G>
    \n+
    493 template<class V, class R>
    \n+\n+
    495 V& visitedMap,
    \n+
    496 [[maybe_unused]] const SequentialInformation& pinfo,
    \n+
    497 const AggregatesMap<Vertex>& aggregates,
    \n+
    498 R& row)
    \n+
    499 {
    \n+
    500 typedef typename G::VertexIterator VertexIterator;
    \n+
    501
    \n+
    502 VertexIterator vend=graph.end();
    \n+
    503 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex) {
    \n+
    504 if(!get(visitedMap, *vertex)) {
    \n+
    505 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
    \n+
    506 ++row;
    \n+
    507 }
    \n+
    508 }
    \n+
    509
    \n+
    510 }
    \n+
    511
    \n+
    512 template<class M>
    \n+\n+
    514 : row_(matrix.createbegin()),
    \n+
    515 minRowSize_(std::numeric_limits<std::size_t>::max()),
    \n+
    516 maxRowSize_(0), sumRowSize_(0)
    \n+
    517 {
    \n+
    518#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    519 diagonalInserted = false;
    \n+
    520#endif
    \n+
    521 }
    \n+
    522 template<class M>
    \n+\n+
    524 {
    \n+
    525 return maxRowSize_;
    \n+
    526 }
    \n+
    527 template<class M>
    \n+\n+
    529 {
    \n+
    530 return minRowSize_;
    \n+
    531 }
    \n+
    532
    \n+
    533 template<class M>
    \n+\n+
    535 {
    \n+
    536 return sumRowSize_;
    \n+
    537 }
    \n+
    538 template<class M>
    \n+\n+
    540 {
    \n+
    541 sumRowSize_ += row_.size();
    \n+
    542 minRowSize_=std::min(minRowSize_, row_.size());
    \n+
    543 maxRowSize_=std::max(maxRowSize_, row_.size());
    \n+
    544 ++row_;
    \n+
    545#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    546 assert(diagonalInserted);
    \n+
    547 diagonalInserted = false;
    \n+
    548#endif
    \n+
    549 }
    \n+
    550
    \n+
    551 template<class M>
    \n+
    552 void SparsityBuilder<M>::insert(const typename M::size_type& index)
    \n+
    553 {
    \n+
    554 row_.insert(index);
    \n+
    555#ifdef DUNE_ISTL_WITH_CHECKING
    \n+
    556 diagonalInserted = diagonalInserted || row_.index()==index;
    \n+
    557#endif
    \n+
    558 }
    \n+
    559
    \n+
    560 template<class T>
    \n+
    561 template<class G, class V, class Set>
    \n+
    562 typename G::MutableMatrix*
    \n+
    563 GalerkinProduct<T>::build(G& fineGraph, V& visitedMap,
    \n+
    564 const ParallelInformation& pinfo,
    \n+\n+
    566 const typename G::Matrix::size_type& size,
    \n+
    567 const Set& overlap)
    \n+
    568 {
    \n+\n+
    570
    \n+
    571 std::size_t count;
    \n+
    572
    \n+
    573 const OverlapVertex* overlapVertices = buildOverlapVertices(fineGraph,
    \n+
    574 pinfo,
    \n+
    575 aggregates,
    \n+
    576 overlap,
    \n+
    577 count);
    \n+
    578 typedef typename G::MutableMatrix M;
    \n+
    579 M* coarseMatrix = new M(size, size, M::row_wise);
    \n+
    580
    \n+
    581 // Reset the visited flags of all vertices.
    \n+
    582 // As the isolated nodes will be skipped we simply mark them as visited
    \n+
    583
    \n+
    584 typedef typename G::VertexIterator Vertex;
    \n+
    585 Vertex vend = fineGraph.end();
    \n+
    586 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
    \n+\n+
    588 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
    \n+
    589 }
    \n+
    590
    \n+
    591 typedef typename G::MutableMatrix M;
    \n+
    592 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
    \n+
    593
    \n+
    594 ConnectivityConstructor<G,T>::examine(fineGraph, visitedMap, pinfo,
    \n+
    595 aggregates, overlap,
    \n+
    596 overlapVertices,
    \n+
    597 overlapVertices+count,
    \n+
    598 sparsityBuilder);
    \n+
    599
    \n+
    600 dinfo<<pinfo.communicator().rank()<<": Matrix ("<<coarseMatrix->N()<<"x"<<coarseMatrix->M()<<" row: min="<<sparsityBuilder.minRowSize()<<" max="
    \n+
    601 <<sparsityBuilder.maxRowSize()<<" avg="
    \n+
    602 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()
    \n+
    603 <<std::endl;
    \n+
    604
    \n+
    605 delete[] overlapVertices;
    \n+
    606
    \n+
    607 return coarseMatrix;
    \n+
    608 }
    \n+
    609
    \n+
    610 template<class G, class V, class Set>
    \n+
    611 typename G::MutableMatrix*
    \n+\n+
    613 const SequentialInformation& pinfo,
    \n+\n+
    615 const typename G::Matrix::size_type& size,
    \n+
    616 [[maybe_unused]] const Set& overlap)
    \n+
    617 {
    \n+
    618 typedef typename G::MutableMatrix M;
    \n+
    619 M* coarseMatrix = new M(size, size, M::row_wise);
    \n+
    620
    \n+
    621 // Reset the visited flags of all vertices.
    \n+
    622 // As the isolated nodes will be skipped we simply mark them as visited
    \n+
    623
    \n+
    624 typedef typename G::VertexIterator Vertex;
    \n+
    625 Vertex vend = fineGraph.end();
    \n+
    626 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
    \n+\n+
    628 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
    \n+
    629 }
    \n+
    630
    \n+
    631 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
    \n+
    632
    \n+\n+
    634 aggregates, sparsityBuilder);
    \n+
    635 dinfo<<"Matrix row: min="<<sparsityBuilder.minRowSize()<<" max="
    \n+
    636 <<sparsityBuilder.maxRowSize()<<" average="
    \n+
    637 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()<<std::endl;
    \n+
    638 return coarseMatrix;
    \n+
    639 }
    \n+
    640
    \n+
    641 template<class M, class V, class P, class O>
    \n+
    642 void BaseGalerkinProduct::calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
    \n+
    643 const P& pinfo, [[maybe_unused]] const O& copy)
    \n+
    644 {
    \n+
    645 coarse = static_cast<typename M::field_type>(0);
    \n+
    646
    \n+
    647 typedef typename M::ConstIterator RowIterator;
    \n+
    648 RowIterator endRow = fine.end();
    \n+
    649
    \n+
    650 for(RowIterator row = fine.begin(); row != endRow; ++row)
    \n+
    651 if(aggregates[row.index()] != AggregatesMap<V>::ISOLATED) {
    \n+
    652 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
    \n+
    653 typedef typename M::ConstColIterator ColIterator;
    \n+
    654 ColIterator endCol = row->end();
    \n+
    655
    \n+
    656 for(ColIterator col = row->begin(); col != endCol; ++col)
    \n+
    657 if(aggregates[col.index()] != AggregatesMap<V>::ISOLATED) {
    \n+
    658 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
    \n+
    659 coarse[aggregates[row.index()]][aggregates[col.index()]]+=*col;
    \n+
    660 }
    \n+
    661 }
    \n+
    662
    \n+
    663 // get the right diagonal matrix values on copy lines from owner processes
    \n+
    664 typedef typename M::block_type BlockType;
    \n+
    665 std::vector<BlockType> rowsize(coarse.N(),BlockType(0));
    \n+
    666 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
    \n+
    667 rowsize[row.index()]=coarse[row.index()][row.index()];
    \n+
    668 pinfo.copyOwnerToAll(rowsize,rowsize);
    \n+
    669 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
    \n+
    670 coarse[row.index()][row.index()] = rowsize[row.index()];
    \n+
    671
    \n+
    672 // don't set dirichlet boundaries for copy lines to make novlp case work,
    \n+
    673 // the preconditioner yields slightly different results now.
    \n+
    674
    \n+
    675 // Set the dirichlet border
    \n+
    676 //DirichletBoundarySetter<P>::template set<M>(coarse, pinfo, copy);
    \n+
    677
    \n+
    678 }
    \n+
    679
    \n+
    680 template<class T>
    \n+
    681 template<class M, class O>
    \n+
    682 void DirichletBoundarySetter<T>::set(M& coarse, const T& pinfo, const O& copy)
    \n+
    683 {
    \n+
    684 typedef typename T::ParallelIndexSet::const_iterator ConstIterator;
    \n+
    685 ConstIterator end = pinfo.indexSet().end();
    \n+
    686 typedef typename M::block_type Block;
    \n+
    687 Block identity=Block(0.0);
    \n+
    688 for(typename Block::RowIterator b=identity.begin(); b != identity.end(); ++b)
    \n+
    689 b->operator[](b.index())=1.0;
    \n+
    690
    \n+
    691 for(ConstIterator index = pinfo.indexSet().begin();
    \n+
    692 index != end; ++index) {
    \n+
    693 if(copy.contains(index->local().attribute())) {
    \n+
    694 typedef typename M::ColIterator ColIterator;
    \n+
    695 typedef typename M::row_type Row;
    \n+
    696 Row row = coarse[index->local()];
    \n+
    697 ColIterator cend = row.find(index->local());
    \n+
    698 ColIterator col = row.begin();
    \n+
    699 for(; col != cend; ++col)
    \n+
    700 *col = 0;
    \n+
    701
    \n+
    702 cend = row.end();
    \n+
    703
    \n+
    704 assert(col != cend); // There should be a diagonal entry
    \n+
    705 *col = identity;
    \n+
    706
    \n+
    707 for(++col; col != cend; ++col)
    \n+
    708 *col = 0;
    \n+
    709 }
    \n+
    710 }
    \n+
    711 }
    \n+
    712
    \n+
    713 template<class M, class O>
    \n+\n+
    715 const SequentialInformation& pinfo,
    \n+
    716 const O& overlap)
    \n+
    717 {}
    \n+
    718
    \n+
    719 } // namespace Amg
    \n+
    720} // namespace Dune
    \n+
    721#endif
    \n+
    Provides classes for the Coloring process of AMG.
    \n+\n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    bool operator()(const OverlapVertex< A > &o1, const OverlapVertex< A > &o2)
    Definition: galerkin.hh:155
    \n+
    static void constructNonOverlapConnectivity(R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::VertexDescriptor &seed)
    Construct the connectivity of an aggregate in the overlap.
    Definition: galerkin.hh:313
    \n+
    G Graph
    The type of the graph.
    Definition: galerkin.hh:211
    \n+
    void operator++()
    Definition: galerkin.hh:539
    \n+
    void operator()(const ConstEdgeIterator &edge)
    Process an edge pointing to another aggregate.
    Definition: galerkin.hh:359
    \n+
    void insert(const typename M::size_type &index)
    Definition: galerkin.hh:552
    \n+
    static void constructOverlapConnectivity(R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const OverlapVertex< typename G::VertexDescriptor > *&seed, const OverlapVertex< typename G::VertexDescriptor > *overlapEnd)
    Definition: galerkin.hh:331
    \n+
    G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation &pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::Matrix::size_type &size, const Set &copy)
    Calculates the coarse matrix via a Galerkin product.
    Definition: galerkin.hh:563
    \n+
    std::size_t index()
    Definition: galerkin.hh:81
    \n+
    T ParallelInformation
    Definition: galerkin.hh:120
    \n+
    G::VertexDescriptor Vertex
    Definition: galerkin.hh:272
    \n+
    T Aggregate
    The aggregate descriptor.
    Definition: galerkin.hh:37
    \n+
    SparsityBuilder(M &matrix)
    Constructor.
    Definition: galerkin.hh:513
    \n+
    ConnectedBuilder(const AggregatesMap< Vertex > &aggregates, Graph &graph, VisitedMap &visitedMap, Set &connected)
    Constructor.
    Definition: galerkin.hh:352
    \n+
    Graph::ConstEdgeIterator ConstEdgeIterator
    The constant edge iterator.
    Definition: galerkin.hh:215
    \n+
    T Vertex
    The vertex descriptor.
    Definition: galerkin.hh:42
    \n+
    G::VertexDescriptor Vertex
    Definition: galerkin.hh:288
    \n+
    static void examine(G &graph, V &visitedMap, const T &pinfo, const AggregatesMap< Vertex > &aggregates, const O &overlap, const OverlapVertex< Vertex > *overlapVertices, const OverlapVertex< Vertex > *overlapEnd, R &row)
    Definition: galerkin.hh:420
    \n+
    V VisitedMap
    The type of the map for marking vertices as visited.
    Definition: galerkin.hh:225
    \n+
    int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
    Visit all neighbour vertices of a vertex in a graph.
    \n+
    S Set
    The type of the connected set.
    Definition: galerkin.hh:220
    \n+
    Aggregate * aggregate
    The aggregate the vertex belongs to.
    Definition: galerkin.hh:47
    \n+
    std::size_t sumRowSize()
    Definition: galerkin.hh:534
    \n+
    Vertex vertex
    The vertex descriptor.
    Definition: galerkin.hh:52
    \n+
    std::size_t minRowSize()
    Definition: galerkin.hh:528
    \n+
    static void set(M &coarse, const T &pinfo, const O &copy)
    Definition: galerkin.hh:682
    \n+
    Graph::VertexDescriptor Vertex
    The vertex descriptor of the graph.
    Definition: galerkin.hh:230
    \n+
    void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
    Calculate the galerkin product.
    \n+
    std::size_t maxRowSize()
    Definition: galerkin.hh:523
    \n+
    STL namespace.
    \n
    Definition: allocator.hh:11
    \n-
    std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm, SolverCategory::Category category)
    Definition: scalarproducts.hh:242
    \n-
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n-
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n-
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-\n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n-
    Factory to assembly solvers configured by a ParameterTree.
    Definition: solverfactory.hh:145
    \n-
    static std::shared_ptr< Solver > get(std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner > prec=nullptr)
    get a solver from the factory
    Definition: solverfactory.hh:168
    \n-
    static std::shared_ptr< Preconditioner > getPreconditioner(std::shared_ptr< Operator > op, const ParameterTree &config)
    Construct a Preconditioner for a given Operator.
    Definition: solverfactory.hh:203
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    Class providing information about the mapping of the vertices onto aggregates.
    Definition: aggregates.hh:560
    \n+
    Definition: galerkin.hh:33
    \n+
    Functor for building the sparsity pattern of the matrix using examineConnectivity.
    Definition: galerkin.hh:63
    \n+
    Definition: galerkin.hh:99
    \n+
    Definition: galerkin.hh:118
    \n+
    Definition: galerkin.hh:185
    \n+
    Visitor for identifying connected aggregates during a breadthFirstSearch.
    Definition: galerkin.hh:206
    \n+
    Definition: galerkin.hh:271
    \n+
    Definition: galerkin.hh:300
    \n+
    Definition: pinfo.hh:28
    \n+
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,308 +4,817 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solverfactory.hh\n+ * paamg\n+galerkin.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5\n- 6#ifndef DUNE_ISTL_SOLVERFACTORY_HH\n- 7#define DUNE_ISTL_SOLVERFACTORY_HH\n- 8\n- 9#include \n- 10#include \n- 11#include \n- 12\n- 13#include \n- 14#include \n+ 5#ifndef DUNE_GALERKIN_HH\n+ 6#define DUNE_GALERKIN_HH\n+ 7\n+ 8#include \"aggregates.hh\"\n+ 9#include \"pinfo.hh\"\n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n 15\n- 16#include \"solverregistry.hh\"\n- 17#include \n- 18#include \n- 19#include \n- 20\n- 21namespace Dune{\n- 26 // Direct solver factory:\n- 27 template\n-28 using DirectSolverSignature = std::shared_ptr>(const\n-M&, const ParameterTree&);\n- 29 template\n-30 using DirectSolverFactory =\n-Singleton>>;\n- 31\n- 32 // Preconditioner factory:\n- 33 template\n-34 using PreconditionerSignature = std::shared_ptr>(const\n-std::shared_ptr&, const ParameterTree&);\n- 35 template\n-36 using PreconditionerFactory =\n-Singleton>>;\n- 37\n- 38 // Iterative solver factory\n- 39 template\n-40 using IterativeSolverSignature = std::shared_ptr>(const\n-std::shared_ptr>&, const std::\n-shared_ptr>&, const std::shared_ptr>,\n-const ParameterTree&);\n- 41 template\n-42 using IterativeSolverFactory =\n-Singleton>>;\n+ 16namespace Dune\n+ 17{\n+ 18 namespace Amg\n+ 19 {\n+ 31 template\n+32 struct OverlapVertex\n+ 33 {\n+37 typedef T Aggregate;\n+ 38\n+42 typedef T Vertex;\n 43\n- 44 // initSolverFactories differs in different compilation units, so we have\n-it\n- 45 // in an anonymous namespace\n- 46 namespace {\n- 47\n- 53 template\n- 54 int initSolverFactories(){\n- 55 using M = typename O::matrix_type;\n- 56 using X = typename O::range_type;\n- 57 using Y = typename O::domain_type;\n- 58 using TL = Dune::TypeList;\n- 59 auto& dsfac=Dune::DirectSolverFactory::instance();\n- 60 addRegistryToFactory(dsfac, DirectSolverTag{});\n- 61 auto& pfac=Dune::PreconditionerFactory::instance();\n- 62 addRegistryToFactory(pfac, PreconditionerTag{});\n- 63 using TLS = Dune::TypeList;\n- 64 auto& isfac=Dune::IterativeSolverFactory::instance();\n- 65 return addRegistryToFactory(isfac, IterativeSolverTag{});\n- 66 }\n- 77 template\n- 78 [[deprecated(\"Use method 'initSolverFactories' instead\")]]\n- 79 int initSolverFactories() {\n- 80 return initSolverFactories();\n- 81 }\n- 82 } // end anonymous namespace\n- 83\n- 84\n- 85 template\n-86 std::shared_ptr wrapPreconditioner4Parallel(const std::\n-shared_ptr& prec,\n- 87 const O&)\n- 88 {\n- 89 return prec;\n- 90 }\n- 91\n- 92 template\n- 93 std::shared_ptr\n-94 wrapPreconditioner4Parallel(const std::shared_ptr& prec,\n- 95 const std::shared_ptr >& op)\n- 96 {\n- 97 return std::make_shared >(prec,\n-op->getCommunication());\n- 98 }\n- 99\n- 100 template\n- 101 std::shared_ptr\n-102 wrapPreconditioner4Parallel(const std::shared_ptr& prec,\n- 103 const std::shared_ptr >& op)\n- 104 {\n- 105 return std::\n-make_shared >(prec, op-\n->getCommunication());\n- 106 }\n- 107\n- 108 template\n-109 std::shared_ptr> createScalarProduct(const std::\n-shared_ptr >&)\n- 110 {\n- 111 return std::make_shared>();\n- 112 }\n- 113 template\n-114 std::shared_ptr> createScalarProduct(const std::\n-shared_ptr >& op)\n- 115 {\n- 116 return createScalarProduct(op->getCommunication(), op->category());\n- 117 }\n- 118\n- 119 template\n-120 std::shared_ptr> createScalarProduct(const std::\n-shared_ptr >& op)\n- 121 {\n- 122 return createScalarProduct(op->getCommunication(), op->category());\n- 123 }\n- 124\n- 144 template\n-145 class SolverFactory {\n- 146 using Domain = typename Operator::domain_type;\n- 147 using Range = typename Operator::range_type;\n- 148 using Solver = Dune::InverseOperator;\n- 149 using Preconditioner = Dune::Preconditioner;\n- 150\n- 151 template\n- 152 using _matrix_type = typename O::matrix_type;\n- 153 using matrix_type = Std::detected_or_t;\n- 154 static constexpr bool isAssembled = !std::is_same::\n-value;\n- 155\n- 156 static const matrix_type* getmat(std::shared_ptr op){\n- 157 std::shared_ptr> aop\n- 158 = std::dynamic_pointer_cast>(op);\n- 159 if(aop)\n- 160 return &aop->getmat();\n- 161 return nullptr;\n- 162 }\n- 163\n- 164 public:\n- 165\n-168 static std::shared_ptr get(std::shared_ptr op,\n- 169 const ParameterTree& config,\n- 170 std::shared_ptr prec = nullptr){\n- 171 std::string type = config.get(\"type\");\n- 172 std::shared_ptr result;\n- 173 const matrix_type* mat = getmat(op);\n- 174 if(mat){\n- 175 if (DirectSolverFactory::instance().contains\n-(type)) {\n- 176 if(op->category()!=SolverCategory::sequential){\n- 177 DUNE_THROW(NotImplemented, \"The solver factory does not support parallel\n-direct solvers!\");\n- 178 }\n- 179 result = DirectSolverFactory::instance\n-().create(type, *mat, config);\n- 180 return result;\n- 181 }\n- 182 }\n- 183 // if no direct solver is found it might be an iterative solver\n- 184 if (!IterativeSolverFactory::instance().contains(type)) {\n- 185 DUNE_THROW(Dune::InvalidStateException, \"Solver not found in the\n-factory.\");\n- 186 }\n- 187 if(!prec){\n- 188 const ParameterTree& precConfig = config.sub(\"preconditioner\");\n- 189 std::string prec_type = precConfig.get(\"type\");\n- 190 prec = PreconditionerFactory::instance().create\n-(prec_type, op, precConfig);\n- 191 if (prec->category() != op->category() && prec->category() ==\n-SolverCategory::sequential)\n- 192 // try to wrap to a parallel preconditioner\n- 193 prec = wrapPreconditioner4Parallel(prec, op);\n- 194 }\n- 195 std::shared_ptr> sp = createScalarProduct(op);\n- 196 result = IterativeSolverFactory::instance().create(type,\n-op, sp, prec, config);\n- 197 return result;\n- 198 }\n+47 Aggregate* aggregate;\n+ 48\n+52 Vertex vertex;\n+ 53 };\n+ 54\n+ 55\n+ 56\n+ 61 template\n+62 class SparsityBuilder\n+ 63 {\n+ 64 public:\n+ 70 SparsityBuilder(M& matrix);\n+ 71\n+ 72 void insert(const typename M::size_type& index);\n+ 73\n+ 74 void operator++();\n+ 75\n+ 76 std::size_t minRowSize();\n+ 77\n+ 78 std::size_t maxRowSize();\n+ 79\n+ 80 std::size_t sumRowSize();\n+81 std::size_t index()\n+ 82 {\n+ 83 return row_.index();\n+ 84 }\n+ 85 private:\n+ 87 typename M::CreateIterator row_;\n+ 89 std::size_t minRowSize_;\n+ 91 std::size_t maxRowSize_;\n+ 92 std::size_t sumRowSize_;\n+ 93#ifdef DUNE_ISTL_WITH_CHECKING\n+ 94 bool diagonalInserted;\n+ 95#endif\n+ 96 };\n+ 97\n+98 class BaseGalerkinProduct\n+ 99 {\n+ 100 public:\n+ 109 template\n+110 void calculate(const M& fine, const AggregatesMap& aggregates, M&\n+coarse,\n+ 111 const I& pinfo, const O& copy);\n+ 112\n+ 113 };\n+ 114\n+ 115 template\n+116 class GalerkinProduct\n+ 117 : public BaseGalerkinProduct\n+ 118 {\n+ 119 public:\n+120 typedef T ParallelInformation;\n+ 121\n+ 131 template\n+ 132 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,\n+ 133 const ParallelInformation& pinfo,\n+ 134 AggregatesMap& aggregates,\n+ 135 const typename G::Matrix::size_type& size,\n+ 136 const Set& copy);\n+ 137 private:\n+ 138\n+ 145 template\n+ 146 const OverlapVertex*\n+ 147 buildOverlapVertices(const G& graph, const I& pinfo,\n+ 148 AggregatesMap& aggregates,\n+ 149 const Set& overlap,\n+ 150 std::size_t& overlapCount);\n+ 151\n+ 152 template\n+ 153 struct OVLess\n+ 154 {\n+155 bool operator()(const OverlapVertex& o1, const OverlapVertex& o2)\n+ 156 {\n+ 157 return *o1.aggregate < *o2.aggregate;\n+ 158 }\n+ 159 };\n+ 160 };\n+ 161\n+ 162 template<>\n+163 class GalerkinProduct\n+ 164 : public BaseGalerkinProduct\n+ 165 {\n+ 166 public:\n+ 176 template\n+ 177 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,\n+ 178 const SequentialInformation& pinfo,\n+ 179 const AggregatesMap& aggregates,\n+ 180 const typename G::Matrix::size_type& size,\n+ 181 const Set& copy);\n+ 182 };\n+ 183\n+184 struct BaseConnectivityConstructor\n+ 185 {\n+ 186 template\n+ 187 static void constructOverlapConnectivity(R& row, G& graph, V& visitedMap,\n+ 188 const AggregatesMap& aggregates,\n+ 189 const OverlapVertex*& seed,\n+ 190 const OverlapVertex* overlapEnd);\n+ 191\n+ 195 template\n+ 196 static void constructNonOverlapConnectivity(R& row, G& graph, V&\n+visitedMap,\n+ 197 const AggregatesMap& aggregates,\n+ 198 const typename G::VertexDescriptor& seed);\n 199\n-203 static std::shared_ptr getPreconditioner(std::\n-shared_ptr op,\n- 204 const ParameterTree& config){\n- 205 const matrix_type* mat = getmat(op);\n- 206 if(mat){\n- 207 std::string prec_type = config.get(\"type\");\n- 208 return PreconditionerFactory::instance().create\n-(prec_type, op, config);\n- 209 }else{\n- 210 DUNE_THROW(InvalidStateException, \"Could not obtain matrix from operator.\n-Please pass in an AssembledLinearOperator.\");\n- 211 }\n- 212 }\n- 213 };\n- 214\n- 225 template\n- 226 std::shared_ptr> getSolverFromFactory(std::\n-shared_ptr op,\n- 228 const ParameterTree& config,\n- 229 std::shared_ptr> prec = nullptr){\n- 231 return SolverFactory::get(op, config, prec);\n- 232 }\n- 233\n- 237} // end namespace Dune\n- 238\n- 239\n- 240#endif\n-solver.hh\n-Define general, extensible interface for inverse operators.\n-solverregistry.hh\n-schwarz.hh\n-novlpschwarz.hh\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::PreconditionerFactory\n-Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > >\n-PreconditionerFactory\n-Definition: solverfactory.hh:36\n-Dune::DirectSolverFactory\n-Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > >\n-DirectSolverFactory\n-Definition: solverfactory.hh:30\n-Dune::IterativeSolverSignature\n-std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr<\n-LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &,\n-const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &)\n-IterativeSolverSignature\n-Definition: solverfactory.hh:40\n-Dune::wrapPreconditioner4Parallel\n-std::shared_ptr< Preconditioner > wrapPreconditioner4Parallel(const std::\n-shared_ptr< Preconditioner > &prec, const O &)\n-Definition: solverfactory.hh:86\n-Dune::DirectSolverSignature\n-std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &)\n-DirectSolverSignature\n-Definition: solverfactory.hh:28\n-Dune::getSolverFromFactory\n-std::shared_ptr< InverseOperator< typename Operator::domain_type, typename\n-Operator::range_type > > getSolverFromFactory(std::shared_ptr< Operator > op,\n-const ParameterTree &config, std::shared_ptr< Preconditioner< typename\n-Operator::domain_type, typename Operator::range_type > > prec=nullptr)\n-Instantiates an InverseOperator from an Operator and a configuration given as a\n-ParameterTree.\n-Definition: solverfactory.hh:227\n-Dune::IterativeSolverFactory\n-Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > >\n-IterativeSolverFactory\n-Definition: solverfactory.hh:42\n-Dune::PreconditionerSignature\n-std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const\n-ParameterTree &) PreconditionerSignature\n-Definition: solverfactory.hh:34\n+ 200\n+ 204 template\n+205 class ConnectedBuilder\n+ 206 {\n+ 207 public:\n+211 typedef G Graph;\n+215 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;\n+ 216\n+220 typedef S Set;\n+ 221\n+225 typedef V VisitedMap;\n+ 226\n+230 typedef typename Graph::VertexDescriptor Vertex;\n+ 231\n+ 239 ConnectedBuilder(const AggregatesMap& aggregates, Graph& graph,\n+ 240 VisitedMap& visitedMap, Set& connected);\n+ 241\n+ 246 void operator()(const ConstEdgeIterator& edge);\n+ 247\n+ 248 private:\n+ 252 const AggregatesMap& aggregates_;\n+ 253\n+ 254 Graph& graph_;\n+ 255\n+ 259 VisitedMap& visitedMap_;\n+ 260\n+ 264 Set& connected_;\n+ 265 };\n+ 266\n+ 267 };\n+ 268\n+ 269 template\n+270 struct ConnectivityConstructor : public BaseConnectivityConstructor\n+ 271 {\n+272 typedef typename G::VertexDescriptor Vertex;\n+ 273\n+ 274 template\n+ 275 static void examine(G& graph,\n+ 276 V& visitedMap,\n+ 277 const T& pinfo,\n+ 278 const AggregatesMap& aggregates,\n+ 279 const O& overlap,\n+ 280 const OverlapVertex* overlapVertices,\n+ 281 const OverlapVertex* overlapEnd,\n+ 282 R& row);\n+ 283 };\n+ 284\n+ 285 template\n+286 struct ConnectivityConstructor : public\n+BaseConnectivityConstructor\n+ 287 {\n+288 typedef typename G::VertexDescriptor Vertex;\n+ 289\n+ 290 template\n+ 291 static void examine(G& graph,\n+ 292 V& visitedMap,\n+ 293 const SequentialInformation& pinfo,\n+ 294 const AggregatesMap& aggregates,\n+ 295 R& row);\n+ 296 };\n+ 297\n+ 298 template\n+299 struct DirichletBoundarySetter\n+ 300 {\n+ 301 template\n+ 302 static void set(M& coarse, const T& pinfo, const O& copy);\n+ 303 };\n+ 304\n+ 305 template<>\n+306 struct DirichletBoundarySetter\n+ 307 {\n+ 308 template\n+ 309 static void set(M& coarse, const SequentialInformation& pinfo, const O&\n+copy);\n+ 310 };\n+ 311\n+ 312 template\n+313 void BaseConnectivityConstructor::constructNonOverlapConnectivity(R& row,\n+G& graph, V& visitedMap,\n+ 314 const AggregatesMap& aggregates,\n+ 315 const typename G::VertexDescriptor& seed)\n+ 316 {\n+ 317 assert(row.index()==aggregates[seed]);\n+ 318 row.insert(aggregates[seed]);\n+ 319 ConnectedBuilder conBuilder(aggregates, graph, visitedMap, row);\n+ 320 typedef typename G::VertexDescriptor Vertex;\n+ 321 typedef std::allocator Allocator;\n+ 322 typedef SLList VertexList;\n+ 323 typedef typename AggregatesMap::DummyEdgeVisitor DummyVisitor;\n+ 324 VertexList vlist;\n+ 325 DummyVisitor dummy;\n+ 326 aggregates.template breadthFirstSearch(seed,aggregates[seed],\n+graph, vlist, dummy,\n+ 327 conBuilder, visitedMap);\n+ 328 }\n+ 329\n+ 330 template\n+331 void BaseConnectivityConstructor::constructOverlapConnectivity(R& row, G&\n+graph, V& visitedMap,\n+ 332 const AggregatesMap& aggregates,\n+ 333 const OverlapVertex*& seed,\n+ 334 const OverlapVertex* overlapEnd)\n+ 335 {\n+ 336 ConnectedBuilder conBuilder(aggregates, graph, visitedMap, row);\n+ 337 const typename G::VertexDescriptor aggregate=*seed->aggregate;\n+ 338\n+ 339 if (row.index()==*seed->aggregate) {\n+ 340 while(seed != overlapEnd && aggregate == *seed->aggregate) {\n+ 341 row.insert(*seed->aggregate);\n+ 342 // Walk over all neighbours and add them to the connected array.\n+ 343 visitNeighbours(graph, seed->vertex, conBuilder);\n+ 344 // Mark vertex as visited\n+ 345 put(visitedMap, seed->vertex, true);\n+ 346 ++seed;\n+ 347 }\n+ 348 }\n+ 349 }\n+ 350\n+ 351 template\n+352 BaseConnectivityConstructor::ConnectedBuilder::ConnectedBuilder\n+(const AggregatesMap& aggregates,\n+ 353 Graph& graph, VisitedMap& visitedMap,\n+ 354 Set& connected)\n+ 355 : aggregates_(aggregates), graph_(graph), visitedMap_(visitedMap),\n+connected_(connected)\n+ 356 {}\n+ 357\n+ 358 template\n+359 void BaseConnectivityConstructor::ConnectedBuilder::operator()(const\n+ConstEdgeIterator& edge)\n+ 360 {\n+ 361 const Vertex& vertex = aggregates_[edge.target()];\n+ 362 assert(vertex!= AggregatesMap::UNAGGREGATED);\n+ 363 if(vertex!= AggregatesMap::ISOLATED)\n+ 364 connected_.insert(vertex);\n+ 365 }\n+ 366\n+ 367 template\n+ 368 template\n+ 369 const OverlapVertex*\n+ 370 GalerkinProduct::buildOverlapVertices(const G& graph, const I& pinfo,\n+ 371 AggregatesMap& aggregates,\n+ 372 const Set& overlap,\n+ 373 std::size_t& overlapCount)\n+ 374 {\n+ 375 // count the overlap vertices.\n+ 376 typedef typename G::ConstVertexIterator ConstIterator;\n+ 377 typedef typename I::GlobalLookupIndexSet GlobalLookup;\n+ 378 typedef typename GlobalLookup::IndexPair IndexPair;\n+ 379\n+ 380 const ConstIterator end = graph.end();\n+ 381 overlapCount = 0;\n+ 382\n+ 383 const GlobalLookup& lookup=pinfo.globalLookup();\n+ 384\n+ 385 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {\n+ 386 const IndexPair* pair = lookup.pair(*vertex);\n+ 387\n+ 388 if(pair!=0 && overlap.contains(pair->local().attribute()))\n+ 389 ++overlapCount;\n+ 390 }\n+ 391 // Allocate space\n+ 392 typedef typename G::VertexDescriptor Vertex;\n+ 393\n+ 394 OverlapVertex* overlapVertices = new OverlapVertex\n+[overlapCount=0 ? 1 : overlapCount];\n+ 395 if(overlapCount==0)\n+ 396 return overlapVertices;\n+ 397\n+ 398 // Initialize them\n+ 399 overlapCount=0;\n+ 400 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {\n+ 401 const IndexPair* pair = lookup.pair(*vertex);\n+ 402\n+ 403 if(pair!=0 && overlap.contains(pair->local().attribute())) {\n+ 404 overlapVertices[overlapCount].aggregate = &aggregates[pair->local()];\n+ 405 overlapVertices[overlapCount].vertex = pair->local();\n+ 406 ++overlapCount;\n+ 407 }\n+ 408 }\n+ 409\n+ 410 dverb << overlapCount<<\" overlap vertices\"<\n+());\n+ 413 // due to the sorting the isolated aggregates (to be skipped) are at the\n+end.\n+ 414\n+ 415 return overlapVertices;\n+ 416 }\n+ 417\n+ 418 template\n+ 419 template\n+420 void ConnectivityConstructor::examine(G& graph,\n+ 421 V& visitedMap,\n+ 422 const T& pinfo,\n+ 423 const AggregatesMap& aggregates,\n+ 424 const O& overlap,\n+ 425 const OverlapVertex* overlapVertices,\n+ 426 const OverlapVertex* overlapEnd,\n+ 427 R& row)\n+ 428 {\n+ 429 typedef typename T::GlobalLookupIndexSet GlobalLookup;\n+ 430 const GlobalLookup& lookup = pinfo.globalLookup();\n+ 431\n+ 432 typedef typename G::VertexIterator VertexIterator;\n+ 433\n+ 434 VertexIterator vend=graph.end();\n+ 435\n+ 436#ifdef DUNE_ISTL_WITH_CHECKING\n+ 437 std::set examined;\n+ 438#endif\n+ 439\n+ 440 // The aggregates owned by the process have lower local indices\n+ 441 // then those not owned. We process them in the first pass.\n+ 442 // They represent the rows 0, 1, ..., n of the coarse matrix\n+ 443 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex)\n+ 444 if(!get(visitedMap, *vertex)) {\n+ 445 // In the first pass we only process owner nodes\n+ 446 typedef typename GlobalLookup::IndexPair IndexPair;\n+ 447 const IndexPair* pair = lookup.pair(*vertex);\n+ 448 if(pair==0 || !overlap.contains(pair->local().attribute())) {\n+ 449#ifdef DUNE_ISTL_WITH_CHECKING\n+ 450 assert(examined.find(aggregates[*vertex])==examined.end());\n+ 451 examined.insert(aggregates[*vertex]);\n+ 452#endif\n+ 453 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates,\n+*vertex);\n+ 454\n+ 455 // only needed for ALU\n+ 456 // (ghosts with same global id as owners on the same process)\n+ 457 if (SolverCategory::category(pinfo) == static_cast(SolverCategory::\n+nonoverlapping)) {\n+ 458 if(overlapVertices != overlapEnd) {\n+ 459 if(*overlapVertices->aggregate!=AggregatesMap::ISOLATED) {\n+ 460 constructOverlapConnectivity(row, graph, visitedMap, aggregates,\n+overlapVertices, overlapEnd);\n+ 461 }\n+ 462 else{\n+ 463 ++overlapVertices;\n+ 464 }\n+ 465 }\n+ 466 }\n+ 467 ++row;\n+ 468 }\n+ 469 }\n+ 470\n+ 471 dvverb<<\"constructed \"<aggregate!=AggregatesMap::ISOLATED) {\n+ 477\n+ 478#ifdef DUNE_ISTL_WITH_CHECKING\n+ 479 typedef typename GlobalLookup::IndexPair IndexPair;\n+ 480 const IndexPair* pair = lookup.pair(overlapVertices->vertex);\n+ 481 assert(pair!=0 && overlap.contains(pair->local().attribute()));\n+ 482 assert(examined.find(aggregates[overlapVertices->vertex])==examined.end\n+());\n+ 483 examined.insert(aggregates[overlapVertices->vertex]);\n+ 484#endif\n+ 485 constructOverlapConnectivity(row, graph, visitedMap, aggregates,\n+overlapVertices, overlapEnd);\n+ 486 ++row;\n+ 487 }else{\n+ 488 ++overlapVertices;\n+ 489 }\n+ 490 }\n+ 491\n+ 492 template\n+ 493 template\n+494 void ConnectivityConstructor::examine(G& graph,\n+ 495 V& visitedMap,\n+ 496 [[maybe_unused]] const SequentialInformation& pinfo,\n+ 497 const AggregatesMap& aggregates,\n+ 498 R& row)\n+ 499 {\n+ 500 typedef typename G::VertexIterator VertexIterator;\n+ 501\n+ 502 VertexIterator vend=graph.end();\n+ 503 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex) {\n+ 504 if(!get(visitedMap, *vertex)) {\n+ 505 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates,\n+*vertex);\n+ 506 ++row;\n+ 507 }\n+ 508 }\n+ 509\n+ 510 }\n+ 511\n+ 512 template\n+513 SparsityBuilder::SparsityBuilder(M& matrix)\n+ 514 : row_(matrix.createbegin()),\n+ 515 minRowSize_(std::numeric_limits::max()),\n+ 516 maxRowSize_(0), sumRowSize_(0)\n+ 517 {\n+ 518#ifdef DUNE_ISTL_WITH_CHECKING\n+ 519 diagonalInserted = false;\n+ 520#endif\n+ 521 }\n+ 522 template\n+523 std::size_t SparsityBuilder::maxRowSize()\n+ 524 {\n+ 525 return maxRowSize_;\n+ 526 }\n+ 527 template\n+528 std::size_t SparsityBuilder::minRowSize()\n+ 529 {\n+ 530 return minRowSize_;\n+ 531 }\n+ 532\n+ 533 template\n+534 std::size_t SparsityBuilder::sumRowSize()\n+ 535 {\n+ 536 return sumRowSize_;\n+ 537 }\n+ 538 template\n+539 void SparsityBuilder::operator++()\n+ 540 {\n+ 541 sumRowSize_ += row_.size();\n+ 542 minRowSize_=std::min(minRowSize_, row_.size());\n+ 543 maxRowSize_=std::max(maxRowSize_, row_.size());\n+ 544 ++row_;\n+ 545#ifdef DUNE_ISTL_WITH_CHECKING\n+ 546 assert(diagonalInserted);\n+ 547 diagonalInserted = false;\n+ 548#endif\n+ 549 }\n+ 550\n+ 551 template\n+552 void SparsityBuilder::insert(const typename M::size_type& index)\n+ 553 {\n+ 554 row_.insert(index);\n+ 555#ifdef DUNE_ISTL_WITH_CHECKING\n+ 556 diagonalInserted = diagonalInserted || row_.index()==index;\n+ 557#endif\n+ 558 }\n+ 559\n+ 560 template\n+ 561 template\n+ 562 typename G::MutableMatrix*\n+563 GalerkinProduct::build(G& fineGraph, V& visitedMap,\n+ 564 const ParallelInformation& pinfo,\n+ 565 AggregatesMap& aggregates,\n+ 566 const typename G::Matrix::size_type& size,\n+ 567 const Set& overlap)\n+ 568 {\n+ 569 typedef OverlapVertex OverlapVertex;\n+ 570\n+ 571 std::size_t count;\n+ 572\n+ 573 const OverlapVertex* overlapVertices = buildOverlapVertices(fineGraph,\n+ 574 pinfo,\n+ 575 aggregates,\n+ 576 overlap,\n+ 577 count);\n+ 578 typedef typename G::MutableMatrix M;\n+ 579 M* coarseMatrix = new M(size, size, M::row_wise);\n+ 580\n+ 581 // Reset the visited flags of all vertices.\n+ 582 // As the isolated nodes will be skipped we simply mark them as visited\n+ 583\n+ 584 typedef typename G::VertexIterator Vertex;\n+ 585 Vertex vend = fineGraph.end();\n+ 586 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {\n+ 587 assert(aggregates[*vertex] != AggregatesMap::UNAGGREGATED);\n+ 588 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap::ISOLATED);\n+ 589 }\n+ 590\n+ 591 typedef typename G::MutableMatrix M;\n+ 592 SparsityBuilder sparsityBuilder(*coarseMatrix);\n+ 593\n+ 594 ConnectivityConstructor::examine(fineGraph, visitedMap, pinfo,\n+ 595 aggregates, overlap,\n+ 596 overlapVertices,\n+ 597 overlapVertices+count,\n+ 598 sparsityBuilder);\n+ 599\n+ 600 dinfo<N\n+()<<\"x\"<M()<<\" row: min=\"<(sparsityBuilder.sumRowSize())/coarseMatrix->N()\n+ 603 <\n+ 611 typename G::MutableMatrix*\n+612 GalerkinProduct::build(G& fineGraph, V& visitedMap,\n+ 613 const SequentialInformation& pinfo,\n+ 614 const AggregatesMap& aggregates,\n+ 615 const typename G::Matrix::size_type& size,\n+ 616 [[maybe_unused]] const Set& overlap)\n+ 617 {\n+ 618 typedef typename G::MutableMatrix M;\n+ 619 M* coarseMatrix = new M(size, size, M::row_wise);\n+ 620\n+ 621 // Reset the visited flags of all vertices.\n+ 622 // As the isolated nodes will be skipped we simply mark them as visited\n+ 623\n+ 624 typedef typename G::VertexIterator Vertex;\n+ 625 Vertex vend = fineGraph.end();\n+ 626 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {\n+ 627 assert(aggregates[*vertex] != AggregatesMap::UNAGGREGATED);\n+ 628 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap::ISOLATED);\n+ 629 }\n+ 630\n+ 631 SparsityBuilder sparsityBuilder(*coarseMatrix);\n+ 632\n+ 633 ConnectivityConstructor::examine(fineGraph,\n+visitedMap, pinfo,\n+ 634 aggregates, sparsityBuilder);\n+ 635 dinfo<<\"Matrix row: min=\"<(sparsityBuilder.sumRowSize())/coarseMatrix->N\n+()<\n+642 void BaseGalerkinProduct::calculate(const M& fine, const AggregatesMap&\n+aggregates, M& coarse,\n+ 643 const P& pinfo, [[maybe_unused]] const O& copy)\n+ 644 {\n+ 645 coarse = static_cast(0);\n+ 646\n+ 647 typedef typename M::ConstIterator RowIterator;\n+ 648 RowIterator endRow = fine.end();\n+ 649\n+ 650 for(RowIterator row = fine.begin(); row != endRow; ++row)\n+ 651 if(aggregates[row.index()] != AggregatesMap::ISOLATED) {\n+ 652 assert(aggregates[row.index()]!=AggregatesMap::UNAGGREGATED);\n+ 653 typedef typename M::ConstColIterator ColIterator;\n+ 654 ColIterator endCol = row->end();\n+ 655\n+ 656 for(ColIterator col = row->begin(); col != endCol; ++col)\n+ 657 if(aggregates[col.index()] != AggregatesMap::ISOLATED) {\n+ 658 assert(aggregates[row.index()]!=AggregatesMap::UNAGGREGATED);\n+ 659 coarse[aggregates[row.index()]][aggregates[col.index()]]+=*col;\n+ 660 }\n+ 661 }\n+ 662\n+ 663 // get the right diagonal matrix values on copy lines from owner processes\n+ 664 typedef typename M::block_type BlockType;\n+ 665 std::vector rowsize(coarse.N(),BlockType(0));\n+ 666 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)\n+ 667 rowsize[row.index()]=coarse[row.index()][row.index()];\n+ 668 pinfo.copyOwnerToAll(rowsize,rowsize);\n+ 669 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)\n+ 670 coarse[row.index()][row.index()] = rowsize[row.index()];\n+ 671\n+ 672 // don't set dirichlet boundaries for copy lines to make novlp case work,\n+ 673 // the preconditioner yields slightly different results now.\n+ 674\n+ 675 // Set the dirichlet border\n+ 676 //DirichletBoundarySetter

    ::template set(coarse, pinfo, copy);\n+ 677\n+ 678 }\n+ 679\n+ 680 template\n+ 681 template\n+682 void DirichletBoundarySetter::set(M& coarse, const T& pinfo, const O&\n+copy)\n+ 683 {\n+ 684 typedef typename T::ParallelIndexSet::const_iterator ConstIterator;\n+ 685 ConstIterator end = pinfo.indexSet().end();\n+ 686 typedef typename M::block_type Block;\n+ 687 Block identity=Block(0.0);\n+ 688 for(typename Block::RowIterator b=identity.begin(); b != identity.end();\n+++b)\n+ 689 b->operator[](b.index())=1.0;\n+ 690\n+ 691 for(ConstIterator index = pinfo.indexSet().begin();\n+ 692 index != end; ++index) {\n+ 693 if(copy.contains(index->local().attribute())) {\n+ 694 typedef typename M::ColIterator ColIterator;\n+ 695 typedef typename M::row_type Row;\n+ 696 Row row = coarse[index->local()];\n+ 697 ColIterator cend = row.find(index->local());\n+ 698 ColIterator col = row.begin();\n+ 699 for(; col != cend; ++col)\n+ 700 *col = 0;\n+ 701\n+ 702 cend = row.end();\n+ 703\n+ 704 assert(col != cend); // There should be a diagonal entry\n+ 705 *col = identity;\n+ 706\n+ 707 for(++col; col != cend; ++col)\n+ 708 *col = 0;\n+ 709 }\n+ 710 }\n+ 711 }\n+ 712\n+ 713 template\n+714 void DirichletBoundarySetter::set(M& coarse,\n+ 715 const SequentialInformation& pinfo,\n+ 716 const O& overlap)\n+ 717 {}\n+ 718\n+ 719 } // namespace Amg\n+ 720} // namespace Dune\n+ 721#endif\n+aggregates.hh\n+Provides classes for the Coloring process of AMG.\n+pinfo.hh\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+Dune::Amg::GalerkinProduct::OVLess::operator()\n+bool operator()(const OverlapVertex< A > &o1, const OverlapVertex< A > &o2)\n+Definition: galerkin.hh:155\n+Dune::Amg::BaseConnectivityConstructor::constructNonOverlapConnectivity\n+static void constructNonOverlapConnectivity(R &row, G &graph, V &visitedMap,\n+const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename\n+G::VertexDescriptor &seed)\n+Construct the connectivity of an aggregate in the overlap.\n+Definition: galerkin.hh:313\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Graph\n+G Graph\n+The type of the graph.\n+Definition: galerkin.hh:211\n+Dune::Amg::SparsityBuilder::operator++\n+void operator++()\n+Definition: galerkin.hh:539\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::operator()\n+void operator()(const ConstEdgeIterator &edge)\n+Process an edge pointing to another aggregate.\n+Definition: galerkin.hh:359\n+Dune::Amg::SparsityBuilder::insert\n+void insert(const typename M::size_type &index)\n+Definition: galerkin.hh:552\n+Dune::Amg::BaseConnectivityConstructor::constructOverlapConnectivity\n+static void constructOverlapConnectivity(R &row, G &graph, V &visitedMap, const\n+AggregatesMap< typename G::VertexDescriptor > &aggregates, const OverlapVertex<\n+typename G::VertexDescriptor > *&seed, const OverlapVertex< typename G::\n+VertexDescriptor > *overlapEnd)\n+Definition: galerkin.hh:331\n+Dune::Amg::GalerkinProduct::build\n+G::MutableMatrix * build(G &fineGraph, V &visitedMap, const ParallelInformation\n+&pinfo, AggregatesMap< typename G::VertexDescriptor > &aggregates, const\n+typename G::Matrix::size_type &size, const Set ©)\n+Calculates the coarse matrix via a Galerkin product.\n+Definition: galerkin.hh:563\n+Dune::Amg::SparsityBuilder::index\n+std::size_t index()\n+Definition: galerkin.hh:81\n+Dune::Amg::GalerkinProduct::ParallelInformation\n+T ParallelInformation\n+Definition: galerkin.hh:120\n+Dune::Amg::ConnectivityConstructor::Vertex\n+G::VertexDescriptor Vertex\n+Definition: galerkin.hh:272\n+Dune::Amg::OverlapVertex::Aggregate\n+T Aggregate\n+The aggregate descriptor.\n+Definition: galerkin.hh:37\n+Dune::Amg::SparsityBuilder::SparsityBuilder\n+SparsityBuilder(M &matrix)\n+Constructor.\n+Definition: galerkin.hh:513\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::ConnectedBuilder\n+ConnectedBuilder(const AggregatesMap< Vertex > &aggregates, Graph &graph,\n+VisitedMap &visitedMap, Set &connected)\n+Constructor.\n+Definition: galerkin.hh:352\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::ConstEdgeIterator\n+Graph::ConstEdgeIterator ConstEdgeIterator\n+The constant edge iterator.\n+Definition: galerkin.hh:215\n+Dune::Amg::OverlapVertex::Vertex\n+T Vertex\n+The vertex descriptor.\n+Definition: galerkin.hh:42\n+Dune::Amg::ConnectivityConstructor<_G,_SequentialInformation_>::Vertex\n+G::VertexDescriptor Vertex\n+Definition: galerkin.hh:288\n+Dune::Amg::ConnectivityConstructor::examine\n+static void examine(G &graph, V &visitedMap, const T &pinfo, const\n+AggregatesMap< Vertex > &aggregates, const O &overlap, const OverlapVertex<\n+Vertex > *overlapVertices, const OverlapVertex< Vertex > *overlapEnd, R &row)\n+Definition: galerkin.hh:420\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::VisitedMap\n+V VisitedMap\n+The type of the map for marking vertices as visited.\n+Definition: galerkin.hh:225\n+Dune::Amg::visitNeighbours\n+int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex,\n+V &visitor)\n+Visit all neighbour vertices of a vertex in a graph.\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Set\n+S Set\n+The type of the connected set.\n+Definition: galerkin.hh:220\n+Dune::Amg::OverlapVertex::aggregate\n+Aggregate * aggregate\n+The aggregate the vertex belongs to.\n+Definition: galerkin.hh:47\n+Dune::Amg::SparsityBuilder::sumRowSize\n+std::size_t sumRowSize()\n+Definition: galerkin.hh:534\n+Dune::Amg::OverlapVertex::vertex\n+Vertex vertex\n+The vertex descriptor.\n+Definition: galerkin.hh:52\n+Dune::Amg::SparsityBuilder::minRowSize\n+std::size_t minRowSize()\n+Definition: galerkin.hh:528\n+Dune::Amg::DirichletBoundarySetter::set\n+static void set(M &coarse, const T &pinfo, const O ©)\n+Definition: galerkin.hh:682\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder::Vertex\n+Graph::VertexDescriptor Vertex\n+The vertex descriptor of the graph.\n+Definition: galerkin.hh:230\n+Dune::Amg::BaseGalerkinProduct::calculate\n+void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse,\n+const I &pinfo, const O ©)\n+Calculate the galerkin product.\n+Dune::Amg::SparsityBuilder::maxRowSize\n+std::size_t maxRowSize()\n+Definition: galerkin.hh:523\n+std\n+STL namespace.\n Dune\n Definition: allocator.hh:11\n-Dune::createScalarProduct\n-std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm,\n-SolverCategory::Category category)\n-Definition: scalarproducts.hh:242\n-Dune::NonoverlappingSchwarzOperator\n-A nonoverlapping operator with communication object.\n-Definition: novlpschwarz.hh:61\n-Dune::MatrixAdapter\n-Adapter to turn a matrix into a linear operator.\n-Definition: operators.hh:137\n-Dune::OverlappingSchwarzOperator\n-An overlapping Schwarz operator.\n-Definition: schwarz.hh:75\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::InverseOperator<_Domain,_Range_>\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n-Dune::SolverFactory\n-Factory to assembly solvers configured by a ParameterTree.\n-Definition: solverfactory.hh:145\n-Dune::SolverFactory::get\n-static std::shared_ptr< Solver > get(std::shared_ptr< Operator > op, const\n-ParameterTree &config, std::shared_ptr< Preconditioner > prec=nullptr)\n-get a solver from the factory\n-Definition: solverfactory.hh:168\n-Dune::SolverFactory::getPreconditioner\n-static std::shared_ptr< Preconditioner > getPreconditioner(std::shared_ptr<\n-Operator > op, const ParameterTree &config)\n-Construct a Preconditioner for a given Operator.\n-Definition: solverfactory.hh:203\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::Amg::AggregatesMap\n+Class providing information about the mapping of the vertices onto aggregates.\n+Definition: aggregates.hh:560\n+Dune::Amg::OverlapVertex\n+Definition: galerkin.hh:33\n+Dune::Amg::SparsityBuilder\n+Functor for building the sparsity pattern of the matrix using\n+examineConnectivity.\n+Definition: galerkin.hh:63\n+Dune::Amg::BaseGalerkinProduct\n+Definition: galerkin.hh:99\n+Dune::Amg::GalerkinProduct\n+Definition: galerkin.hh:118\n+Dune::Amg::BaseConnectivityConstructor\n+Definition: galerkin.hh:185\n+Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder\n+Visitor for identifying connected aggregates during a breadthFirstSearch.\n+Definition: galerkin.hh:206\n+Dune::Amg::ConnectivityConstructor\n+Definition: galerkin.hh:271\n+Dune::Amg::DirichletBoundarySetter\n+Definition: galerkin.hh:300\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::SolverCategory::nonoverlapping\n+@ nonoverlapping\n+Category for non-overlapping solvers.\n+Definition: solvercategory.hh:27\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00185.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00185.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: scaledidmatrix.hh File Reference\n+dune-istl: parameters.hh File Reference\n \n \n \n \n \n \n \n@@ -58,55 +58,67 @@\n \n \n \n

    \n \n
    \n \n-
    scaledidmatrix.hh File Reference
    \n+Namespaces |\n+Enumerations
    \n+ \n \n
    \n \n-

    This file implements a quadratic matrix of fixed size which is a multiple of the identity. \n+

    Parameter classes for customizing AMG. \n More...

    \n-
    #include <cmath>
    \n-#include <cstddef>
    \n-#include <complex>
    \n-#include <iostream>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/diagonalmatrix.hh>
    \n-#include <dune/common/ftraits.hh>
    \n+
    #include <cstddef>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n+\n+\n \n-\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::ScaledIdentityMatrix< K, n >
     A multiple of the identity matrix of static size. More...
    class  Dune::Amg::DependencyParameters
     Parameters needed to check whether a node depends on another. More...
     
    struct  Dune::DenseMatrixAssigner< DenseMatrix, ScaledIdentityMatrix< field, N > >
    class  Dune::Amg::AggregationParameters
     Parameters needed for the aggregation process. More...
     
    struct  Dune::FieldTraits< ScaledIdentityMatrix< K, n > >
    class  Dune::Amg::CoarseningParameters
     Parameters for the complete coarsening process. More...
     
    class  Dune::Amg::Parameters
     All parameters for AMG. More...
     
    \n \n \n \n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n

    \n+Enumerations

    enum  Dune::Amg::AccumulationMode { Dune::Amg::noAccu = 0\n+, Dune::Amg::atOnceAccu =1\n+, Dune::Amg::successiveAccu =2\n+ }
     Identifiers for the different accumulation modes. More...
     
    \n

    Detailed Description

    \n-

    This file implements a quadratic matrix of fixed size which is a multiple of the identity.

    \n+

    Parameter classes for customizing AMG.

    \n+
    Author
    Markus Blatt
    \n+

    All parameters of the AMG can be set by using the class Parameter, which can be provided to CoarsenCriterion via its constructor.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,38 +4,47 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-scaledidmatrix.hh File Reference\n-This file implements a quadratic matrix of fixed size which is a multiple of\n-the identity. More...\n-#include \n+ * paamg\n+Classes | Namespaces | Enumerations\n+parameters.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Parameter classes for customizing AMG. More...\n #include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::ScaledIdentityMatrix<_K,_n_>\n-\u00a0 A multiple of the identity matrix of static size. More...\n+class \u00a0Dune::Amg::DependencyParameters\n+\u00a0 Parameters needed to check whether a node depends on another. More...\n \u00a0\n-struct \u00a0Dune::DenseMatrixAssigner<_DenseMatrix,_ScaledIdentityMatrix<_field,_N\n- >_>\n+class \u00a0Dune::Amg::AggregationParameters\n+\u00a0 Parameters needed for the aggregation process. More...\n \u00a0\n-struct \u00a0Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>\n+class \u00a0Dune::Amg::CoarseningParameters\n+\u00a0 Parameters for the complete coarsening process. More...\n+\u00a0\n+class \u00a0Dune::Amg::Parameters\n+\u00a0 All parameters for AMG. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::Amg\n+\u00a0\n+ Enumerations\n+enum \u00a0Dune::Amg::AccumulationMode { Dune::Amg::noAccu = 0 , Dune::Amg::\n+ atOnceAccu =1 , Dune::Amg::successiveAccu =2 }\n+\u00a0 Identifiers for the different accumulation modes. More...\n+\u00a0\n ***** Detailed Description *****\n-This file implements a quadratic matrix of fixed size which is a multiple of\n-the identity.\n+Parameter classes for customizing AMG.\n+ Author\n+ Markus Blatt\n+All parameters of the AMG can be set by using the class Parameter, which can be\n+provided to CoarsenCriterion via its constructor.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00185_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00185_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: scaledidmatrix.hh Source File\n+dune-istl: parameters.hh Source File\n \n \n \n \n \n \n \n@@ -58,524 +58,319 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n
    \n
    \n-
    scaledidmatrix.hh
    \n+
    parameters.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SCALEDIDMATRIX_HH
    \n-
    6#define DUNE_ISTL_SCALEDIDMATRIX_HH
    \n+
    5#ifndef DUNE_AMG_PARAMETERS_HH
    \n+
    6#define DUNE_AMG_PARAMETERS_HH
    \n
    7
    \n-
    14#include <cmath>
    \n-
    15#include <cstddef>
    \n-
    16#include <complex>
    \n-
    17#include <iostream>
    \n-
    18#include <dune/common/exceptions.hh>
    \n-
    19#include <dune/common/fmatrix.hh>
    \n-
    20#include <dune/common/diagonalmatrix.hh>
    \n-
    21#include <dune/common/ftraits.hh>
    \n-
    22
    \n-
    23namespace Dune {
    \n-
    24
    \n-
    28 template<class K, int n>
    \n-\n-
    30 {
    \n-
    31 typedef DiagonalMatrixWrapper< ScaledIdentityMatrix<K,n> > WrapperType;
    \n-
    32
    \n-
    33 public:
    \n-
    34 //===== type definitions and constants
    \n-
    35
    \n-
    37 typedef K field_type;
    \n-
    38
    \n-
    40 typedef K block_type;
    \n-
    41
    \n-
    43 typedef std::size_t size_type;
    \n-
    44
    \n-
    46 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    47 static constexpr std::size_t blocklevel = 1;
    \n-
    48
    \n-
    50 typedef DiagonalRowVector<K,n> row_type;
    \n-\n-
    52 typedef DiagonalRowVectorConst<K,n> const_row_type;
    \n-\n-
    54
    \n-
    56 enum {
    \n-
    58 rows = n,
    \n-
    60 cols = n
    \n-
    61 };
    \n-
    62
    \n-
    63 //===== constructors
    \n-\n-
    67
    \n-\n-
    71 : p_(k)
    \n-
    72 {}
    \n-
    73
    \n-
    74 //===== assignment from scalar
    \n-\n-
    76 {
    \n-
    77 p_ = k;
    \n-
    78 return *this;
    \n-
    79 }
    \n-
    80
    \n-
    81 // check if matrix is identical to other matrix (not only identical values)
    \n-
    82 bool identical(const ScaledIdentityMatrix<K,n>& other) const
    \n-
    83 {
    \n-
    84 return (this==&other);
    \n-
    85 }
    \n-
    86
    \n-
    87 //===== iterator interface to rows of the matrix
    \n-
    89 typedef ContainerWrapperIterator<const WrapperType, reference, reference> Iterator;
    \n-\n-\n-
    95 typedef typename row_type::Iterator ColIterator;
    \n-
    96
    \n-\n-
    99 {
    \n-
    100 return Iterator(WrapperType(this),0);
    \n-
    101 }
    \n-
    102
    \n-\n-
    105 {
    \n-
    106 return Iterator(WrapperType(this),n);
    \n-
    107 }
    \n-
    108
    \n-\n-
    112 {
    \n-
    113 return Iterator(WrapperType(this),n-1);
    \n-
    114 }
    \n-
    115
    \n-\n-
    119 {
    \n-
    120 return Iterator(WrapperType(this),-1);
    \n-
    121 }
    \n-
    122
    \n-
    123
    \n-
    125 typedef ContainerWrapperIterator<const WrapperType, const_reference, const_reference> ConstIterator;
    \n-\n-\n-
    131 typedef typename const_row_type::ConstIterator ConstColIterator;
    \n-
    132
    \n-\n-
    135 {
    \n-
    136 return ConstIterator(WrapperType(this),0);
    \n-
    137 }
    \n-
    138
    \n-\n-
    141 {
    \n-
    142 return ConstIterator(WrapperType(this),n);
    \n-
    143 }
    \n-
    144
    \n-\n-
    148 {
    \n-
    149 return ConstIterator(WrapperType(this),n-1);
    \n-
    150 }
    \n-
    151
    \n-\n-
    155 {
    \n-
    156 return ConstIterator(WrapperType(this),-1);
    \n-
    157 }
    \n-
    158
    \n-
    159 //===== vector space arithmetic
    \n-
    160
    \n-\n-
    163 {
    \n-
    164 p_ += y.p_;
    \n-
    165 return *this;
    \n-
    166 }
    \n-
    167
    \n-\n-
    170 {
    \n-
    171 p_ -= y.p_;
    \n-
    172 return *this;
    \n-
    173 }
    \n-
    174
    \n-\n-
    177 {
    \n-
    178 p_ += k;
    \n-
    179 return *this;
    \n-
    180 }
    \n+
    8#include <cstddef>
    \n+
    9
    \n+
    10namespace Dune
    \n+
    11{
    \n+
    12 namespace Amg
    \n+
    13 {
    \n+\n+
    31 {
    \n+
    32 public:
    \n+\n+
    35 : alpha_(1.0/3.0), beta_(1.0E-5)
    \n+
    36 {}
    \n+
    37
    \n+
    42 void setBeta(double b)
    \n+
    43 {
    \n+
    44 beta_ = b;
    \n+
    45 }
    \n+
    46
    \n+
    52 double beta() const
    \n+
    53 {
    \n+
    54 return beta_;
    \n+
    55 }
    \n+
    56
    \n+
    61 void setAlpha(double a)
    \n+
    62 {
    \n+
    63 alpha_ = a;
    \n+
    64 }
    \n+
    65
    \n+
    70 double alpha() const
    \n+
    71 {
    \n+
    72 return alpha_;
    \n+
    73 }
    \n+
    74
    \n+
    75 private:
    \n+
    76 double alpha_, beta_;
    \n+
    77 };
    \n+
    78
    \n+\n+\n+
    84 {
    \n+
    85 public:
    \n+\n+
    96 : maxDistance_(2), minAggregateSize_(4), maxAggregateSize_(6),
    \n+
    97 connectivity_(15), skipiso_(false)
    \n+
    98 {}
    \n+
    99
    \n+
    109 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    \n+
    110 {
    \n+
    111 maxDistance_=diameter-1;
    \n+
    112 std::size_t csize=1;
    \n+
    113
    \n+
    114 for(; dim>0; dim--) {
    \n+
    115 csize*=diameter;
    \n+
    116 maxDistance_+=diameter-1;
    \n+
    117 }
    \n+
    118 minAggregateSize_=csize;
    \n+
    119 maxAggregateSize_=static_cast<std::size_t>(csize*1.5);
    \n+
    120 }
    \n+
    121
    \n+
    132 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)
    \n+
    133 {
    \n+
    134 setDefaultValuesIsotropic(dim, diameter);
    \n+
    135 maxDistance_+=dim-1;
    \n+
    136 }
    \n+
    144 std::size_t maxDistance() const { return maxDistance_;}
    \n+
    145
    \n+
    154 void setMaxDistance(std::size_t distance) { maxDistance_ = distance;}
    \n+
    155
    \n+
    161 bool skipIsolated() const
    \n+
    162 {
    \n+
    163 return skipiso_;
    \n+
    164 }
    \n+
    165
    \n+
    171 void setSkipIsolated(bool skip)
    \n+
    172 {
    \n+
    173 skipiso_=skip;
    \n+
    174 }
    \n+
    175
    \n+
    180 std::size_t minAggregateSize() const { return minAggregateSize_;}
    \n
    181
    \n-\n-
    184 {
    \n-
    185 p_ -= k;
    \n-
    186 return *this;
    \n-
    187 }
    \n-\n-
    190 {
    \n-
    191 p_ *= k;
    \n-
    192 return *this;
    \n-
    193 }
    \n-
    194
    \n-\n-
    197 {
    \n-
    198 p_ /= k;
    \n-
    199 return *this;
    \n-
    200 }
    \n-
    201
    \n-
    202 //===== binary operators
    \n+
    188 void setMinAggregateSize(std::size_t size){ minAggregateSize_=size;}
    \n+
    189
    \n+
    194 std::size_t maxAggregateSize() const { return maxAggregateSize_;}
    \n+
    195
    \n+
    202 void setMaxAggregateSize(std::size_t size){ maxAggregateSize_ = size;}
    \n
    203
    \n-
    205 template <class Scalar,
    \n-
    206 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
    \n-
    207 friend auto operator* ( const ScaledIdentityMatrix& matrix, Scalar scalar)
    \n-
    208 {
    \n-\n-
    210 }
    \n-
    211
    \n-
    213 template <class Scalar,
    \n-
    214 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
    \n-
    215 friend auto operator* (Scalar scalar, const ScaledIdentityMatrix& matrix)
    \n-
    216 {
    \n-\n-
    218 }
    \n-
    219
    \n-
    220 //===== comparison ops
    \n+
    211 std::size_t maxConnectivity() const { return connectivity_;}
    \n+
    212
    \n+
    220 void setMaxConnectivity(std::size_t connectivity){ connectivity_ = connectivity;}
    \n
    221
    \n-
    223 bool operator==(const ScaledIdentityMatrix& other) const
    \n-
    224 {
    \n-
    225 return p_==other.scalar();
    \n-
    226 }
    \n+
    222 private:
    \n+
    223 std::size_t maxDistance_, minAggregateSize_, maxAggregateSize_, connectivity_;
    \n+
    224 bool skipiso_;
    \n+
    225
    \n+
    226 };
    \n
    227
    \n-
    229 bool operator!=(const ScaledIdentityMatrix& other) const
    \n-
    230 {
    \n-
    231 return p_!=other.scalar();
    \n-
    232 }
    \n-
    233
    \n-
    234 //===== linear maps
    \n-
    235
    \n-
    237 template<class X, class Y>
    \n-
    238 void mv (const X& x, Y& y) const
    \n-
    239 {
    \n-
    240#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    241 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    242 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    243#endif
    \n-
    244 for (size_type i=0; i<n; ++i)
    \n-
    245 y[i] = p_ * x[i];
    \n-
    246 }
    \n-
    247
    \n-
    249 template<class X, class Y>
    \n-
    250 void mtv (const X& x, Y& y) const
    \n-
    251 {
    \n-
    252 mv(x, y);
    \n-
    253 }
    \n-
    254
    \n-
    256 template<class X, class Y>
    \n-
    257 void umv (const X& x, Y& y) const
    \n-
    258 {
    \n-
    259#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    260 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    261 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    262#endif
    \n-
    263 for (size_type i=0; i<n; ++i)
    \n-
    264 y[i] += p_ * x[i];
    \n-
    265 }
    \n-
    266
    \n-
    268 template<class X, class Y>
    \n-
    269 void umtv (const X& x, Y& y) const
    \n-
    270 {
    \n-
    271#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    272 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    273 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    274#endif
    \n-
    275 for (size_type i=0; i<n; ++i)
    \n-
    276 y[i] += p_ * x[i];
    \n-
    277 }
    \n-
    278
    \n-
    280 template<class X, class Y>
    \n-
    281 void umhv (const X& x, Y& y) const
    \n-
    282 {
    \n-
    283#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    284 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    285 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    286#endif
    \n-
    287 for (size_type i=0; i<n; i++)
    \n-
    288 y[i] += conjugateComplex(p_)*x[i];
    \n-
    289 }
    \n+
    228
    \n+\n+\n+\n+\n+
    249 };
    \n+
    250
    \n+
    251
    \n+
    252
    \n+
    253
    \n+\n+
    258 {
    \n+
    259 public:
    \n+
    263 void setMaxLevel(int l)
    \n+
    264 {
    \n+
    265 maxLevel_ = l;
    \n+
    266 }
    \n+
    270 int maxLevel() const
    \n+
    271 {
    \n+
    272 return maxLevel_;
    \n+
    273 }
    \n+
    274
    \n+
    278 void setCoarsenTarget(int nodes)
    \n+
    279 {
    \n+
    280 coarsenTarget_ = nodes;
    \n+
    281 }
    \n+
    282
    \n+
    286 int coarsenTarget() const
    \n+
    287 {
    \n+
    288 return coarsenTarget_;
    \n+
    289 }
    \n
    290
    \n-
    292 template<class X, class Y>
    \n-
    293 void mmv (const X& x, Y& y) const
    \n-
    294 {
    \n-
    295#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    296 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    297 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    298#endif
    \n-
    299 for (size_type i=0; i<n; ++i)
    \n-
    300 y[i] -= p_ * x[i];
    \n-
    301 }
    \n-
    302
    \n-
    304 template<class X, class Y>
    \n-
    305 void mmtv (const X& x, Y& y) const
    \n-
    306 {
    \n-
    307#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    308 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    309 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    310#endif
    \n-
    311 for (size_type i=0; i<n; ++i)
    \n-
    312 y[i] -= p_ * x[i];
    \n-
    313 }
    \n-
    314
    \n-
    316 template<class X, class Y>
    \n-
    317 void mmhv (const X& x, Y& y) const
    \n-
    318 {
    \n-
    319#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    320 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    321 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    322#endif
    \n-
    323 for (size_type i=0; i<n; i++)
    \n-
    324 y[i] -= conjugateComplex(p_)*x[i];
    \n-
    325 }
    \n-
    326
    \n-
    328 template<class X, class Y>
    \n-
    329 void usmv (const K& alpha, const X& x, Y& y) const
    \n-
    330 {
    \n-
    331#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    332 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    333 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    334#endif
    \n-
    335 for (size_type i=0; i<n; i++)
    \n-
    336 y[i] += alpha * p_ * x[i];
    \n-
    337 }
    \n-
    338
    \n-
    340 template<class X, class Y>
    \n-
    341 void usmtv (const K& alpha, const X& x, Y& y) const
    \n-
    342 {
    \n-
    343#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    344 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    345 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    346#endif
    \n-
    347 for (size_type i=0; i<n; i++)
    \n-
    348 y[i] += alpha * p_ * x[i];
    \n-
    349 }
    \n-
    350
    \n-
    352 template<class X, class Y>
    \n-
    353 void usmhv (const K& alpha, const X& x, Y& y) const
    \n-
    354 {
    \n-
    355#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    356 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    357 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
    \n-
    358#endif
    \n-
    359 for (size_type i=0; i<n; i++)
    \n-
    360 y[i] += alpha * conjugateComplex(p_) * x[i];
    \n-
    361 }
    \n-
    362
    \n-
    363 //===== norms
    \n-
    364
    \n-
    366 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n-
    367 {
    \n-
    368 return fvmeta::sqrt(n*p_*p_);
    \n-
    369 }
    \n-
    370
    \n-
    372 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n-
    373 {
    \n-
    374 return n*p_*p_;
    \n-
    375 }
    \n-
    376
    \n-
    378 typename FieldTraits<field_type>::real_type infinity_norm () const
    \n-
    379 {
    \n-
    380 return std::abs(p_);
    \n-
    381 }
    \n-
    382
    \n-
    384 typename FieldTraits<field_type>::real_type infinity_norm_real () const
    \n-
    385 {
    \n-
    386 return fvmeta::absreal(p_);
    \n-
    387 }
    \n-
    388
    \n-
    389 //===== solve
    \n-
    390
    \n-
    393 template<class V>
    \n-
    394 void solve (V& x, const V& b) const
    \n-
    395 {
    \n-
    396 for (int i=0; i<n; i++)
    \n-
    397 x[i] = b[i]/p_;
    \n-
    398 }
    \n-
    399
    \n-
    402 void invert()
    \n-
    403 {
    \n-
    404 p_ = 1/p_;
    \n-
    405 }
    \n-
    406
    \n-
    408 K determinant () const {
    \n-
    409 return std::pow(p_,n);
    \n-
    410 }
    \n-
    411
    \n-
    412 //===== sizes
    \n-
    413
    \n-
    415 size_type N () const
    \n-
    416 {
    \n-
    417 return n;
    \n-
    418 }
    \n-
    419
    \n-
    421 size_type M () const
    \n-
    422 {
    \n-
    423 return n;
    \n-
    424 }
    \n-
    425
    \n-
    426 //===== query
    \n-
    427
    \n-
    429 bool exists (size_type i, size_type j) const
    \n-
    430 {
    \n-
    431#ifdef DUNE_FMatrix_WITH_CHECKING
    \n-
    432 if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
    \n-
    433 if (j<0 || j>=n) DUNE_THROW(FMatrixError,"column index out of range");
    \n-
    434#endif
    \n-
    435 return i==j;
    \n-
    436 }
    \n-
    437
    \n-
    438 //===== conversion operator
    \n-
    439
    \n-
    441 friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
    \n-
    442 {
    \n-
    443 for (size_type i=0; i<n; i++) {
    \n-
    444 for (size_type j=0; j<n; j++)
    \n-
    445 s << ((i==j) ? a.p_ : 0) << " ";
    \n-
    446 s << std::endl;
    \n-
    447 }
    \n-
    448 return s;
    \n-
    449 }
    \n-
    450
    \n-\n-
    453 {
    \n-
    454 return reference(const_cast<K*>(&p_), i);
    \n-
    455 }
    \n-
    456
    \n-\n-
    459 {
    \n-
    460 return const_reference(const_cast<K*>(&p_), i);
    \n-
    461 }
    \n-
    462
    \n-
    464 const K& diagonal(size_type /*i*/) const
    \n-
    465 {
    \n-
    466 return p_;
    \n-
    467 }
    \n-
    468
    \n-\n-
    471 {
    \n-
    472 return p_;
    \n-
    473 }
    \n-
    474
    \n-
    477 const K& scalar() const
    \n-
    478 {
    \n-
    479 return p_;
    \n-
    480 }
    \n-
    481
    \n-\n-
    485 {
    \n-
    486 return p_;
    \n-
    487 }
    \n-
    488
    \n-
    489 private:
    \n-
    490 // the data, very simply a single number
    \n-
    491 K p_;
    \n-
    492
    \n-
    493 };
    \n-
    494
    \n-
    495 template <class DenseMatrix, class field, int N>
    \n-
    496 struct DenseMatrixAssigner<DenseMatrix, ScaledIdentityMatrix<field, N>> {
    \n-
    497 static void apply(DenseMatrix& denseMatrix,
    \n-\n-
    499 assert(denseMatrix.M() == N);
    \n-
    500 assert(denseMatrix.N() == N);
    \n-
    501 denseMatrix = field(0);
    \n-
    502 for (int i = 0; i < N; ++i)
    \n-
    503 denseMatrix[i][i] = rhs.scalar();
    \n-
    504 }
    \n-
    505 };
    \n+
    296 void setMinCoarsenRate(double rate)
    \n+
    297 {
    \n+
    298 minCoarsenRate_ = rate;
    \n+
    299 }
    \n+
    300
    \n+
    304 double minCoarsenRate() const
    \n+
    305 {
    \n+
    306 return minCoarsenRate_;
    \n+
    307 }
    \n+
    308
    \n+\n+
    313 {
    \n+
    314 return accumulate_;
    \n+
    315 }
    \n+\n+
    320 {
    \n+
    321 accumulate_=accu;
    \n+
    322 }
    \n+
    323
    \n+
    324 void setAccumulate(bool accu){
    \n+
    325 accumulate_=accu ? successiveAccu : noAccu;
    \n+
    326 }
    \n+\n+
    333 {
    \n+
    334 dampingFactor_ = d;
    \n+
    335 }
    \n+
    336
    \n+\n+
    343 {
    \n+
    344 return dampingFactor_;
    \n+
    345 }
    \n+\n+
    357 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n+
    358 : maxLevel_(maxLevel), coarsenTarget_(coarsenTarget), minCoarsenRate_(minCoarsenRate),
    \n+
    359 dampingFactor_(prolongDamp), accumulate_( accumulate)
    \n+
    360 {}
    \n+
    361
    \n+
    362 private:
    \n+
    366 int maxLevel_;
    \n+
    370 int coarsenTarget_;
    \n+
    374 double minCoarsenRate_;
    \n+
    378 double dampingFactor_;
    \n+
    383 AccumulationMode accumulate_;
    \n+
    384 };
    \n+
    385
    \n+\n+
    393 {
    \n+
    394 public:
    \n+
    401 void setDebugLevel(int level)
    \n+
    402 {
    \n+
    403 debugLevel_ = level;
    \n+
    404 }
    \n+
    405
    \n+
    411 int debugLevel() const
    \n+
    412 {
    \n+
    413 return debugLevel_;
    \n+
    414 }
    \n+
    415
    \n+
    420 void setNoPreSmoothSteps(std::size_t steps)
    \n+
    421 {
    \n+
    422 preSmoothSteps_=steps;
    \n+
    423 }
    \n+
    428 std::size_t getNoPreSmoothSteps() const
    \n+
    429 {
    \n+
    430 return preSmoothSteps_;
    \n+
    431 }
    \n+
    432
    \n+
    437 void setNoPostSmoothSteps(std::size_t steps)
    \n+
    438 {
    \n+
    439 postSmoothSteps_=steps;
    \n+
    440 }
    \n+
    445 std::size_t getNoPostSmoothSteps() const
    \n+
    446 {
    \n+
    447 return postSmoothSteps_;
    \n+
    448 }
    \n+
    449
    \n+
    453 void setGamma(std::size_t gamma)
    \n+
    454 {
    \n+
    455 gamma_=gamma;
    \n+
    456 }
    \n+
    460 std::size_t getGamma() const
    \n+
    461 {
    \n+
    462 return gamma_;
    \n+
    463 }
    \n+
    464
    \n+
    469 void setAdditive(bool additive)
    \n+
    470 {
    \n+
    471 additive_=additive;
    \n+
    472 }
    \n+
    473
    \n+
    478 bool getAdditive() const
    \n+
    479 {
    \n+
    480 return additive_;
    \n+
    481 }
    \n+
    482
    \n+
    493 Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,
    \n+
    494 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    \n+\n+
    496 , debugLevel_(2), preSmoothSteps_(2), postSmoothSteps_(2), gamma_(1),
    \n+
    497 additive_(false)
    \n+
    498 {}
    \n+
    499 private:
    \n+
    500 int debugLevel_;
    \n+
    501 std::size_t preSmoothSteps_;
    \n+
    502 std::size_t postSmoothSteps_;
    \n+
    503 std::size_t gamma_;
    \n+
    504 bool additive_;
    \n+
    505 };
    \n
    506
    \n-
    507 template<class K, int n>
    \n-
    508 struct FieldTraits< ScaledIdentityMatrix<K, n> >
    \n-
    509 {
    \n-\n-
    511 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    512 };
    \n-
    513
    \n-
    514} // end namespace
    \n-
    515
    \n-
    516#endif
    \n+
    507 } //namespace AMG
    \n+
    508
    \n+
    509} //namespace Dune
    \n+
    510#endif
    \n+
    void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an anisotropic problem.
    Definition: parameters.hh:132
    \n+
    void setAdditive(bool additive)
    Set whether to use additive multigrid.
    Definition: parameters.hh:469
    \n+
    void setSkipIsolated(bool skip)
    Set whether isolated aggregates will not be represented on the coarse level.
    Definition: parameters.hh:171
    \n+
    void setProlongationDampingFactor(double d)
    Set the damping factor for the prolongation.
    Definition: parameters.hh:332
    \n+
    double alpha() const
    Get the scaling value for marking connections as strong. Default value is 1/3.
    Definition: parameters.hh:70
    \n+
    void setMaxAggregateSize(std::size_t size)
    Set the maximum number of nodes a aggregate is allowed to have.
    Definition: parameters.hh:202
    \n+
    void setMinCoarsenRate(double rate)
    Set the minimum coarsening rate to be achieved in each coarsening.
    Definition: parameters.hh:296
    \n+
    double minCoarsenRate() const
    Get the minimum coarsening rate to be achieved.
    Definition: parameters.hh:304
    \n+
    std::size_t maxAggregateSize() const
    Get the maximum number of nodes a aggregate is allowed to have.
    Definition: parameters.hh:194
    \n+
    void setAlpha(double a)
    Set the scaling value for marking connections as strong. Default value is 1/3.
    Definition: parameters.hh:61
    \n+
    double beta() const
    Get the threshold for marking nodes as isolated. The default value is 1.0E-5.
    Definition: parameters.hh:52
    \n+
    std::size_t maxConnectivity() const
    Get the maximum number of connections a aggregate is allowed to have.
    Definition: parameters.hh:211
    \n+
    int coarsenTarget() const
    Get the maximum number of unknowns allowed on the coarsest level.
    Definition: parameters.hh:286
    \n+
    void setAccumulate(AccumulationMode accu)
    Set whether he data should be accumulated on fewer processes on coarser levels.
    Definition: parameters.hh:319
    \n+
    double getProlongationDampingFactor() const
    Get the damping factor for the prolongation.
    Definition: parameters.hh:342
    \n+
    AccumulationMode accumulate() const
    Whether the data should be accumulated on fewer processes on coarser levels.
    Definition: parameters.hh:312
    \n+
    void setMaxConnectivity(std::size_t connectivity)
    Set the maximum number of connections a aggregate is allowed to have.
    Definition: parameters.hh:220
    \n+
    std::size_t minAggregateSize() const
    Get the minimum number of nodes a aggregate has to consist of.
    Definition: parameters.hh:180
    \n+
    bool getAdditive() const
    Get whether to use additive multigrid.
    Definition: parameters.hh:478
    \n+
    void setMaxLevel(int l)
    Set the maximum number of levels allowed in the hierarchy.
    Definition: parameters.hh:263
    \n+
    void setDebugLevel(int level)
    Set the debugging level.
    Definition: parameters.hh:401
    \n+
    std::size_t getGamma() const
    Get the value of gamma; 1 for V-cycle, 2 for W-cycle.
    Definition: parameters.hh:460
    \n+
    void setNoPostSmoothSteps(std::size_t steps)
    Set the number of postsmoothing steps to apply.
    Definition: parameters.hh:437
    \n+
    std::size_t getNoPreSmoothSteps() const
    Get the number of presmoothing steps to apply.
    Definition: parameters.hh:428
    \n+
    DependencyParameters()
    Constructor.
    Definition: parameters.hh:34
    \n+
    void setMinAggregateSize(std::size_t size)
    Set the minimum number of nodes a aggregate has to consist of.
    Definition: parameters.hh:188
    \n+
    int maxLevel() const
    Get the maximum number of levels allowed in the hierarchy.
    Definition: parameters.hh:270
    \n+
    void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
    Sets reasonable default values for an isotropic problem.
    Definition: parameters.hh:109
    \n+
    AggregationParameters()
    Constructor.
    Definition: parameters.hh:95
    \n+
    bool skipIsolated() const
    Whether isolated aggregates will not be represented on the coarse level.
    Definition: parameters.hh:161
    \n+
    Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: parameters.hh:493
    \n+
    void setCoarsenTarget(int nodes)
    Set the maximum number of unknowns allowed on the coarsest level.
    Definition: parameters.hh:278
    \n+
    void setNoPreSmoothSteps(std::size_t steps)
    Set the number of presmoothing steps to apply.
    Definition: parameters.hh:420
    \n+
    AccumulationMode
    Identifiers for the different accumulation modes.
    Definition: parameters.hh:232
    \n+
    void setBeta(double b)
    Set threshold for marking nodes as isolated. The default value is 1.0E-5.
    Definition: parameters.hh:42
    \n+
    std::size_t maxDistance() const
    Get the maximal distance allowed between two nodes in a aggregate.
    Definition: parameters.hh:144
    \n+
    CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)
    Constructor.
    Definition: parameters.hh:356
    \n+
    void setGamma(std::size_t gamma)
    Set the value of gamma; 1 for V-cycle, 2 for W-cycle.
    Definition: parameters.hh:453
    \n+
    void setAccumulate(bool accu)
    Definition: parameters.hh:324
    \n+
    void setMaxDistance(std::size_t distance)
    Set the maximal distance allowed between two nodes in a aggregate.
    Definition: parameters.hh:154
    \n+
    int debugLevel() const
    Get the debugging Level.
    Definition: parameters.hh:411
    \n+
    std::size_t getNoPostSmoothSteps() const
    Get the number of postsmoothing steps to apply.
    Definition: parameters.hh:445
    \n+
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n+
    @ noAccu
    No data accumulution.
    Definition: parameters.hh:238
    \n+
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n
    Definition: allocator.hh:11
    \n-
    A multiple of the identity matrix of static size.
    Definition: scaledidmatrix.hh:30
    \n-
    void usmhv(const K &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: scaledidmatrix.hh:353
    \n-
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: scaledidmatrix.hh:305
    \n-
    ScaledIdentityMatrix & operator-=(const ScaledIdentityMatrix &y)
    vector space subtraction
    Definition: scaledidmatrix.hh:169
    \n-
    const_row_type::ConstIterator ConstColIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:131
    \n-
    ConstIterator end() const
    end iterator
    Definition: scaledidmatrix.hh:140
    \n-
    Iterator beforeBegin()
    Definition: scaledidmatrix.hh:118
    \n-
    bool operator!=(const ScaledIdentityMatrix &other) const
    incomparison operator
    Definition: scaledidmatrix.hh:229
    \n-
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: scaledidmatrix.hh:293
    \n-
    std::size_t size_type
    The type used for the index access and size operations.
    Definition: scaledidmatrix.hh:43
    \n-
    void usmv(const K &alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: scaledidmatrix.hh:329
    \n-
    row_type::Iterator ColIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:95
    \n-
    const_row_type const_reference
    Definition: scaledidmatrix.hh:53
    \n-
    void mv(const X &x, Y &y) const
    y = A x
    Definition: scaledidmatrix.hh:238
    \n-
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: scaledidmatrix.hh:269
    \n-
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: scaledidmatrix.hh:281
    \n-
    DiagonalRowVector< K, n > row_type
    Each row is implemented by a field vector.
    Definition: scaledidmatrix.hh:50
    \n-
    ContainerWrapperIterator< const WrapperType, reference, reference > Iterator
    Iterator class for sequential access.
    Definition: scaledidmatrix.hh:89
    \n-
    Iterator beforeEnd()
    Definition: scaledidmatrix.hh:111
    \n-
    K determinant() const
    calculates the determinant of this matrix
    Definition: scaledidmatrix.hh:408
    \n-
    K field_type
    export the type representing the field
    Definition: scaledidmatrix.hh:37
    \n-
    void usmtv(const K &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: scaledidmatrix.hh:341
    \n-
    Iterator end()
    end iterator
    Definition: scaledidmatrix.hh:104
    \n-
    Iterator iterator
    typedef for stl compliant access
    Definition: scaledidmatrix.hh:91
    \n-
    const K & scalar() const
    Get const reference to the scalar diagonal value.
    Definition: scaledidmatrix.hh:477
    \n-
    void umv(const X &x, Y &y) const
    y += A x
    Definition: scaledidmatrix.hh:257
    \n-
    static constexpr std::size_t blocklevel
    We are at the leaf of the block recursion.
    Definition: scaledidmatrix.hh:47
    \n-
    const K & diagonal(size_type) const
    Get const reference to diagonal entry.
    Definition: scaledidmatrix.hh:464
    \n-
    @ rows
    The number of rows.
    Definition: scaledidmatrix.hh:58
    \n-
    @ cols
    The number of columns.
    Definition: scaledidmatrix.hh:60
    \n-
    ScaledIdentityMatrix & operator=(const K &k)
    Definition: scaledidmatrix.hh:75
    \n-
    ContainerWrapperIterator< const WrapperType, const_reference, const_reference > ConstIterator
    Iterator class for sequential access.
    Definition: scaledidmatrix.hh:125
    \n-
    K & diagonal(size_type)
    Get reference to diagonal entry.
    Definition: scaledidmatrix.hh:470
    \n-
    void solve(V &x, const V &b) const
    Solve system A x = b.
    Definition: scaledidmatrix.hh:394
    \n-
    bool exists(size_type i, size_type j) const
    return true when (i,j) is in pattern
    Definition: scaledidmatrix.hh:429
    \n-
    Iterator RowIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:93
    \n-
    ConstIterator const_iterator
    typedef for stl compliant access
    Definition: scaledidmatrix.hh:127
    \n-
    ScaledIdentityMatrix()
    Default constructor.
    Definition: scaledidmatrix.hh:66
    \n-
    bool operator==(const ScaledIdentityMatrix &other) const
    comparison operator
    Definition: scaledidmatrix.hh:223
    \n-
    ConstIterator beforeBegin() const
    Definition: scaledidmatrix.hh:154
    \n-
    ScaledIdentityMatrix & operator/=(const K &k)
    vector space division by scalar
    Definition: scaledidmatrix.hh:196
    \n-
    friend std::ostream & operator<<(std::ostream &s, const ScaledIdentityMatrix< K, n > &a)
    Sends the matrix to an output stream.
    Definition: scaledidmatrix.hh:441
    \n-
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: scaledidmatrix.hh:372
    \n-
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: scaledidmatrix.hh:366
    \n-
    FieldTraits< field_type >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: scaledidmatrix.hh:378
    \n-
    ConstIterator ConstRowIterator
    rename the iterators for easier access
    Definition: scaledidmatrix.hh:129
    \n-
    ConstIterator beforeEnd() const
    Definition: scaledidmatrix.hh:147
    \n-
    size_type M() const
    number of blocks in column direction
    Definition: scaledidmatrix.hh:421
    \n-
    const_reference operator[](size_type i) const
    Return const_reference object as row replacement.
    Definition: scaledidmatrix.hh:458
    \n-
    ScaledIdentityMatrix(const K &k)
    Constructor initializing the whole matrix with a scalar.
    Definition: scaledidmatrix.hh:70
    \n-
    friend auto operator*(const ScaledIdentityMatrix &matrix, Scalar scalar)
    vector space multiplication with scalar
    Definition: scaledidmatrix.hh:207
    \n-
    FieldTraits< field_type >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: scaledidmatrix.hh:384
    \n-
    ScaledIdentityMatrix & operator*=(const K &k)
    vector space multiplication with scalar
    Definition: scaledidmatrix.hh:189
    \n-
    bool identical(const ScaledIdentityMatrix< K, n > &other) const
    Definition: scaledidmatrix.hh:82
    \n-
    void invert()
    Compute inverse.
    Definition: scaledidmatrix.hh:402
    \n-
    Iterator begin()
    begin iterator
    Definition: scaledidmatrix.hh:98
    \n-
    K & scalar()
    Get reference to the scalar diagonal value.
    Definition: scaledidmatrix.hh:484
    \n-
    row_type reference
    Definition: scaledidmatrix.hh:51
    \n-
    K block_type
    export the type representing the components
    Definition: scaledidmatrix.hh:40
    \n-
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: scaledidmatrix.hh:317
    \n-
    ScaledIdentityMatrix & operator+=(const ScaledIdentityMatrix &y)
    vector space addition
    Definition: scaledidmatrix.hh:162
    \n-
    DiagonalRowVectorConst< K, n > const_row_type
    Definition: scaledidmatrix.hh:52
    \n-
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: scaledidmatrix.hh:250
    \n-
    reference operator[](size_type i)
    Return reference object as row replacement.
    Definition: scaledidmatrix.hh:452
    \n-
    ConstIterator begin() const
    begin iterator
    Definition: scaledidmatrix.hh:134
    \n-
    size_type N() const
    number of blocks in row direction
    Definition: scaledidmatrix.hh:415
    \n-
    static void apply(DenseMatrix &denseMatrix, ScaledIdentityMatrix< field, N > const &rhs)
    Definition: scaledidmatrix.hh:497
    \n-
    typename ScaledIdentityMatrix< K, n >::field_type field_type
    Definition: scaledidmatrix.hh:510
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: scaledidmatrix.hh:511
    \n+
    Parameters needed to check whether a node depends on another.
    Definition: parameters.hh:31
    \n+
    Parameters needed for the aggregation process.
    Definition: parameters.hh:84
    \n+
    Parameters for the complete coarsening process.
    Definition: parameters.hh:258
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,721 +4,464 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-scaledidmatrix.hh\n+ * paamg\n+parameters.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SCALEDIDMATRIX_HH\n- 6#define DUNE_ISTL_SCALEDIDMATRIX_HH\n+ 5#ifndef DUNE_AMG_PARAMETERS_HH\n+ 6#define DUNE_AMG_PARAMETERS_HH\n 7\n- 14#include \n- 15#include \n- 16#include \n- 17#include \n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22\n- 23namespace Dune {\n- 24\n- 28 template\n-29 class ScaledIdentityMatrix\n- 30 {\n- 31 typedef DiagonalMatrixWrapper< ScaledIdentityMatrix > WrapperType;\n- 32\n- 33 public:\n- 34 //===== type definitions and constants\n- 35\n-37 typedef K field_type;\n- 38\n-40 typedef K block_type;\n- 41\n-43 typedef std::size_t size_type;\n- 44\n- 46 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-47 static constexpr std::size_t blocklevel = 1;\n- 48\n-50 typedef DiagonalRowVector row_type;\n-51 typedef row_type reference;\n-52 typedef DiagonalRowVectorConst const_row_type;\n-53 typedef const_row_type const_reference;\n- 54\n- 56 enum {\n-58 rows = n,\n- 60 cols = n\n-61 };\n- 62\n- 63 //===== constructors\n-66 ScaledIdentityMatrix () {}\n- 67\n-70 ScaledIdentityMatrix (const K& k)\n- 71 : p_(k)\n- 72 {}\n- 73\n- 74 //===== assignment from scalar\n-75 ScaledIdentityMatrix& operator=(const K& k)\n- 76 {\n- 77 p_ = k;\n- 78 return *this;\n- 79 }\n- 80\n- 81 // check if matrix is identical to other matrix (not only identical values)\n-82 bool identical(const ScaledIdentityMatrix& other) const\n- 83 {\n- 84 return (this==&other);\n- 85 }\n- 86\n- 87 //===== iterator interface to rows of the matrix\n-89 typedef ContainerWrapperIterator\n-Iterator;\n-91 typedef Iterator iterator;\n-93 typedef Iterator RowIterator;\n-95 typedef typename row_type::Iterator ColIterator;\n- 96\n-98 Iterator begin ()\n- 99 {\n- 100 return Iterator(WrapperType(this),0);\n- 101 }\n- 102\n-104 Iterator end ()\n- 105 {\n- 106 return Iterator(WrapperType(this),n);\n- 107 }\n- 108\n-111 Iterator beforeEnd ()\n- 112 {\n- 113 return Iterator(WrapperType(this),n-1);\n- 114 }\n- 115\n-118 Iterator beforeBegin ()\n- 119 {\n- 120 return Iterator(WrapperType(this),-1);\n- 121 }\n- 122\n- 123\n-125 typedef ContainerWrapperIterator ConstIterator;\n-127 typedef ConstIterator const_iterator;\n-129 typedef ConstIterator ConstRowIterator;\n-131 typedef typename const_row_type::ConstIterator ConstColIterator;\n- 132\n-134 ConstIterator begin () const\n- 135 {\n- 136 return ConstIterator(WrapperType(this),0);\n- 137 }\n- 138\n-140 ConstIterator end () const\n- 141 {\n- 142 return ConstIterator(WrapperType(this),n);\n- 143 }\n- 144\n-147 ConstIterator beforeEnd() const\n- 148 {\n- 149 return ConstIterator(WrapperType(this),n-1);\n- 150 }\n- 151\n-154 ConstIterator beforeBegin () const\n- 155 {\n- 156 return ConstIterator(WrapperType(this),-1);\n- 157 }\n- 158\n- 159 //===== vector space arithmetic\n- 160\n-162 ScaledIdentityMatrix& operator+=(const ScaledIdentityMatrix& y)\n- 163 {\n- 164 p_ += y.p_;\n- 165 return *this;\n- 166 }\n- 167\n-169 ScaledIdentityMatrix& operator-=(const ScaledIdentityMatrix& y)\n- 170 {\n- 171 p_ -= y.p_;\n- 172 return *this;\n- 173 }\n- 174\n-176 ScaledIdentityMatrix& operator+=(const K& k)\n- 177 {\n- 178 p_ += k;\n- 179 return *this;\n- 180 }\n+ 8#include \n+ 9\n+ 10namespace Dune\n+ 11{\n+ 12 namespace Amg\n+ 13 {\n+30 class DependencyParameters\n+ 31 {\n+ 32 public:\n+34 DependencyParameters()\n+ 35 : alpha_(1.0/3.0), beta_(1.0E-5)\n+ 36 {}\n+ 37\n+42 void setBeta(double b)\n+ 43 {\n+ 44 beta_ = b;\n+ 45 }\n+ 46\n+52 double beta() const\n+ 53 {\n+ 54 return beta_;\n+ 55 }\n+ 56\n+61 void setAlpha(double a)\n+ 62 {\n+ 63 alpha_ = a;\n+ 64 }\n+ 65\n+70 double alpha() const\n+ 71 {\n+ 72 return alpha_;\n+ 73 }\n+ 74\n+ 75 private:\n+ 76 double alpha_, beta_;\n+ 77 };\n+ 78\n+82 class AggregationParameters :\n+ 83 public DependencyParameters\n+ 84 {\n+ 85 public:\n+95 AggregationParameters()\n+ 96 : maxDistance_(2), minAggregateSize_(4), maxAggregateSize_(6),\n+ 97 connectivity_(15), skipiso_(false)\n+ 98 {}\n+ 99\n+109 void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n+ 110 {\n+ 111 maxDistance_=diameter-1;\n+ 112 std::size_t csize=1;\n+ 113\n+ 114 for(; dim>0; dim--) {\n+ 115 csize*=diameter;\n+ 116 maxDistance_+=diameter-1;\n+ 117 }\n+ 118 minAggregateSize_=csize;\n+ 119 maxAggregateSize_=static_cast(csize*1.5);\n+ 120 }\n+ 121\n+132 void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)\n+ 133 {\n+ 134 setDefaultValuesIsotropic(dim, diameter);\n+ 135 maxDistance_+=dim-1;\n+ 136 }\n+144 std::size_t maxDistance() const { return maxDistance_;}\n+ 145\n+154 void setMaxDistance(std::size_t distance) { maxDistance_ = distance;}\n+ 155\n+161 bool skipIsolated() const\n+ 162 {\n+ 163 return skipiso_;\n+ 164 }\n+ 165\n+171 void setSkipIsolated(bool skip)\n+ 172 {\n+ 173 skipiso_=skip;\n+ 174 }\n+ 175\n+180 std::size_t minAggregateSize() const { return minAggregateSize_;}\n 181\n-183 ScaledIdentityMatrix& operator-=(const K& k)\n- 184 {\n- 185 p_ -= k;\n- 186 return *this;\n- 187 }\n-189 ScaledIdentityMatrix& operator*=(const K& k)\n- 190 {\n- 191 p_ *= k;\n- 192 return *this;\n- 193 }\n- 194\n-196 ScaledIdentityMatrix& operator/=(const K& k)\n- 197 {\n- 198 p_ /= k;\n- 199 return *this;\n- 200 }\n- 201\n- 202 //===== binary operators\n+188 void setMinAggregateSize(std::size_t size){ minAggregateSize_=size;}\n+ 189\n+194 std::size_t maxAggregateSize() const { return maxAggregateSize_;}\n+ 195\n+202 void setMaxAggregateSize(std::size_t size){ maxAggregateSize_ = size;}\n 203\n- 205 template ::value, int> = 0>\n-207 friend auto operator*( const ScaledIdentityMatrix& matrix, Scalar scalar)\n- 208 {\n- 209 return ScaledIdentityMatrix::\n-PromotedType, n>{matrix.scalar()*scalar};\n- 210 }\n- 211\n- 213 template ::value, int> = 0>\n-215 friend auto operator*(Scalar scalar, const ScaledIdentityMatrix& matrix)\n- 216 {\n- 217 return ScaledIdentityMatrix::\n-PromotedType, n>{scalar*matrix.scalar()};\n- 218 }\n- 219\n- 220 //===== comparison ops\n+211 std::size_t maxConnectivity() const { return connectivity_;}\n+ 212\n+220 void setMaxConnectivity(std::size_t connectivity){ connectivity_ =\n+connectivity;}\n 221\n-223 bool operator==(const ScaledIdentityMatrix& other) const\n- 224 {\n- 225 return p_==other.scalar();\n- 226 }\n+ 222 private:\n+ 223 std::size_t maxDistance_, minAggregateSize_, maxAggregateSize_,\n+connectivity_;\n+ 224 bool skipiso_;\n+ 225\n+ 226 };\n 227\n-229 bool operator!=(const ScaledIdentityMatrix& other) const\n- 230 {\n- 231 return p_!=other.scalar();\n- 232 }\n- 233\n- 234 //===== linear maps\n- 235\n- 237 template\n-238 void mv (const X& x, Y& y) const\n- 239 {\n- 240#ifdef DUNE_FMatrix_WITH_CHECKING\n- 241 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 242 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 243#endif\n- 244 for (size_type i=0; i\n-250 void mtv (const X& x, Y& y) const\n- 251 {\n- 252 mv(x, y);\n- 253 }\n- 254\n- 256 template\n-257 void umv (const X& x, Y& y) const\n+ 228\n+232 enum AccumulationMode {\n+238 noAccu = 0,\n+244 atOnceAccu=1,\n+ 248 successiveAccu=2\n+249 };\n+ 250\n+ 251\n+ 252\n+ 253\n+257 class CoarseningParameters : public AggregationParameters\n 258 {\n- 259#ifdef DUNE_FMatrix_WITH_CHECKING\n- 260 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 261 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 262#endif\n- 263 for (size_type i=0; i\n-269 void umtv (const X& x, Y& y) const\n- 270 {\n- 271#ifdef DUNE_FMatrix_WITH_CHECKING\n- 272 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 273 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 274#endif\n- 275 for (size_type i=0; i\n-281 void umhv (const X& x, Y& y) const\n- 282 {\n- 283#ifdef DUNE_FMatrix_WITH_CHECKING\n- 284 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 285 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 286#endif\n- 287 for (size_type i=0; i\n-293 void mmv (const X& x, Y& y) const\n- 294 {\n- 295#ifdef DUNE_FMatrix_WITH_CHECKING\n- 296 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 297 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 298#endif\n- 299 for (size_type i=0; i\n-305 void mmtv (const X& x, Y& y) const\n- 306 {\n- 307#ifdef DUNE_FMatrix_WITH_CHECKING\n- 308 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 309 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 310#endif\n- 311 for (size_type i=0; i\n-317 void mmhv (const X& x, Y& y) const\n- 318 {\n- 319#ifdef DUNE_FMatrix_WITH_CHECKING\n- 320 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 321 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 322#endif\n- 323 for (size_type i=0; i\n-329 void usmv (const K& alpha, const X& x, Y& y) const\n- 330 {\n- 331#ifdef DUNE_FMatrix_WITH_CHECKING\n- 332 if (x.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 333 if (y.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 334#endif\n- 335 for (size_type i=0; i\n-341 void usmtv (const K& alpha, const X& x, Y& y) const\n- 342 {\n- 343#ifdef DUNE_FMatrix_WITH_CHECKING\n- 344 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 345 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 346#endif\n- 347 for (size_type i=0; i\n-353 void usmhv (const K& alpha, const X& x, Y& y) const\n- 354 {\n- 355#ifdef DUNE_FMatrix_WITH_CHECKING\n- 356 if (x.N()!=N()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 357 if (y.N()!=M()) DUNE_THROW(FMatrixError,\"index out of range\");\n- 358#endif\n- 359 for (size_type i=0; i::real_type frobenius_norm () const\n- 367 {\n- 368 return fvmeta::sqrt(n*p_*p_);\n- 369 }\n- 370\n-372 typename FieldTraits::real_type frobenius_norm2 () const\n- 373 {\n- 374 return n*p_*p_;\n- 375 }\n- 376\n-378 typename FieldTraits::real_type infinity_norm () const\n- 379 {\n- 380 return std::abs(p_);\n- 381 }\n- 382\n-384 typename FieldTraits::real_type infinity_norm_real () const\n- 385 {\n- 386 return fvmeta::absreal(p_);\n- 387 }\n- 388\n- 389 //===== solve\n- 390\n- 393 template\n-394 void solve (V& x, const V& b) const\n- 395 {\n- 396 for (int i=0; i=n) DUNE_THROW(FMatrixError,\"row index out of range\");\n- 433 if (j<0 || j>=n) DUNE_THROW(FMatrixError,\"column index out of range\");\n- 434#endif\n- 435 return i==j;\n- 436 }\n- 437\n- 438 //===== conversion operator\n- 439\n-441 friend std::ostream& operator<<(std::ostream& s, const\n-ScaledIdentityMatrix& a)\n- 442 {\n- 443 for (size_type i=0; i(&p_), i);\n- 455 }\n- 456\n-458 const_reference operator[](size_type i) const\n- 459 {\n- 460 return const_reference(const_cast(&p_), i);\n- 461 }\n- 462\n-464 const K& diagonal(size_type /*i*/) const\n- 465 {\n- 466 return p_;\n- 467 }\n- 468\n-470 K& diagonal(size_type /*i*/)\n- 471 {\n- 472 return p_;\n- 473 }\n- 474\n-477 const K& scalar() const\n- 478 {\n- 479 return p_;\n- 480 }\n- 481\n-484 K& scalar()\n- 485 {\n- 486 return p_;\n- 487 }\n- 488\n- 489 private:\n- 490 // the data, very simply a single number\n- 491 K p_;\n- 492\n- 493 };\n- 494\n- 495 template \n-496 struct DenseMatrixAssigner> {\n-497 static void apply(DenseMatrix& denseMatrix,\n- 498 ScaledIdentityMatrix const& rhs) {\n- 499 assert(denseMatrix.M() == N);\n- 500 assert(denseMatrix.N() == N);\n- 501 denseMatrix = field(0);\n- 502 for (int i = 0; i < N; ++i)\n- 503 denseMatrix[i][i] = rhs.scalar();\n- 504 }\n+296 void setMinCoarsenRate(double rate)\n+ 297 {\n+ 298 minCoarsenRate_ = rate;\n+ 299 }\n+ 300\n+304 double minCoarsenRate() const\n+ 305 {\n+ 306 return minCoarsenRate_;\n+ 307 }\n+ 308\n+312 AccumulationMode accumulate() const\n+ 313 {\n+ 314 return accumulate_;\n+ 315 }\n+319 void setAccumulate(AccumulationMode accu)\n+ 320 {\n+ 321 accumulate_=accu;\n+ 322 }\n+ 323\n+324 void setAccumulate(bool accu){\n+ 325 accumulate_=accu ? successiveAccu : noAccu;\n+ 326 }\n+332 void setProlongationDampingFactor(double d)\n+ 333 {\n+ 334 dampingFactor_ = d;\n+ 335 }\n+ 336\n+342 double getProlongationDampingFactor() const\n+ 343 {\n+ 344 return dampingFactor_;\n+ 345 }\n+356 CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double\n+minCoarsenRate=1.2,\n+ 357 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n+ 358 : maxLevel_(maxLevel), coarsenTarget_(coarsenTarget), minCoarsenRate_\n+(minCoarsenRate),\n+ 359 dampingFactor_(prolongDamp), accumulate_( accumulate)\n+ 360 {}\n+ 361\n+ 362 private:\n+ 366 int maxLevel_;\n+ 370 int coarsenTarget_;\n+ 374 double minCoarsenRate_;\n+ 378 double dampingFactor_;\n+ 383 AccumulationMode accumulate_;\n+ 384 };\n+ 385\n+392 class Parameters : public CoarseningParameters\n+ 393 {\n+ 394 public:\n+401 void setDebugLevel(int level)\n+ 402 {\n+ 403 debugLevel_ = level;\n+ 404 }\n+ 405\n+411 int debugLevel() const\n+ 412 {\n+ 413 return debugLevel_;\n+ 414 }\n+ 415\n+420 void setNoPreSmoothSteps(std::size_t steps)\n+ 421 {\n+ 422 preSmoothSteps_=steps;\n+ 423 }\n+428 std::size_t getNoPreSmoothSteps() const\n+ 429 {\n+ 430 return preSmoothSteps_;\n+ 431 }\n+ 432\n+437 void setNoPostSmoothSteps(std::size_t steps)\n+ 438 {\n+ 439 postSmoothSteps_=steps;\n+ 440 }\n+445 std::size_t getNoPostSmoothSteps() const\n+ 446 {\n+ 447 return postSmoothSteps_;\n+ 448 }\n+ 449\n+453 void setGamma(std::size_t gamma)\n+ 454 {\n+ 455 gamma_=gamma;\n+ 456 }\n+460 std::size_t getGamma() const\n+ 461 {\n+ 462 return gamma_;\n+ 463 }\n+ 464\n+469 void setAdditive(bool additive)\n+ 470 {\n+ 471 additive_=additive;\n+ 472 }\n+ 473\n+478 bool getAdditive() const\n+ 479 {\n+ 480 return additive_;\n+ 481 }\n+ 482\n+493 Parameters(int maxLevel=100, int coarsenTarget=1000, double\n+minCoarsenRate=1.2,\n+ 494 double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n+ 495 : CoarseningParameters(maxLevel, coarsenTarget, minCoarsenRate,\n+prolongDamp, accumulate)\n+ 496 , debugLevel_(2), preSmoothSteps_(2), postSmoothSteps_(2), gamma_(1),\n+ 497 additive_(false)\n+ 498 {}\n+ 499 private:\n+ 500 int debugLevel_;\n+ 501 std::size_t preSmoothSteps_;\n+ 502 std::size_t postSmoothSteps_;\n+ 503 std::size_t gamma_;\n+ 504 bool additive_;\n 505 };\n 506\n- 507 template\n-508 struct FieldTraits< ScaledIdentityMatrix >\n- 509 {\n-510 using field_type = typename ScaledIdentityMatrix::field_type;\n-511 using real_type = typename FieldTraits::real_type;\n- 512 };\n- 513\n- 514} // end namespace\n- 515\n- 516#endif\n+ 507 } //namespace AMG\n+ 508\n+ 509} //namespace Dune\n+ 510#endif\n+Dune::Amg::AggregationParameters::setDefaultValuesAnisotropic\n+void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)\n+Sets reasonable default values for an anisotropic problem.\n+Definition: parameters.hh:132\n+Dune::Amg::Parameters::setAdditive\n+void setAdditive(bool additive)\n+Set whether to use additive multigrid.\n+Definition: parameters.hh:469\n+Dune::Amg::AggregationParameters::setSkipIsolated\n+void setSkipIsolated(bool skip)\n+Set whether isolated aggregates will not be represented on the coarse level.\n+Definition: parameters.hh:171\n+Dune::Amg::CoarseningParameters::setProlongationDampingFactor\n+void setProlongationDampingFactor(double d)\n+Set the damping factor for the prolongation.\n+Definition: parameters.hh:332\n+Dune::Amg::DependencyParameters::alpha\n+double alpha() const\n+Get the scaling value for marking connections as strong. Default value is 1/3.\n+Definition: parameters.hh:70\n+Dune::Amg::AggregationParameters::setMaxAggregateSize\n+void setMaxAggregateSize(std::size_t size)\n+Set the maximum number of nodes a aggregate is allowed to have.\n+Definition: parameters.hh:202\n+Dune::Amg::CoarseningParameters::setMinCoarsenRate\n+void setMinCoarsenRate(double rate)\n+Set the minimum coarsening rate to be achieved in each coarsening.\n+Definition: parameters.hh:296\n+Dune::Amg::CoarseningParameters::minCoarsenRate\n+double minCoarsenRate() const\n+Get the minimum coarsening rate to be achieved.\n+Definition: parameters.hh:304\n+Dune::Amg::AggregationParameters::maxAggregateSize\n+std::size_t maxAggregateSize() const\n+Get the maximum number of nodes a aggregate is allowed to have.\n+Definition: parameters.hh:194\n+Dune::Amg::DependencyParameters::setAlpha\n+void setAlpha(double a)\n+Set the scaling value for marking connections as strong. Default value is 1/3.\n+Definition: parameters.hh:61\n+Dune::Amg::DependencyParameters::beta\n+double beta() const\n+Get the threshold for marking nodes as isolated. The default value is 1.0E-5.\n+Definition: parameters.hh:52\n+Dune::Amg::AggregationParameters::maxConnectivity\n+std::size_t maxConnectivity() const\n+Get the maximum number of connections a aggregate is allowed to have.\n+Definition: parameters.hh:211\n+Dune::Amg::CoarseningParameters::coarsenTarget\n+int coarsenTarget() const\n+Get the maximum number of unknowns allowed on the coarsest level.\n+Definition: parameters.hh:286\n+Dune::Amg::CoarseningParameters::setAccumulate\n+void setAccumulate(AccumulationMode accu)\n+Set whether he data should be accumulated on fewer processes on coarser levels.\n+Definition: parameters.hh:319\n+Dune::Amg::CoarseningParameters::getProlongationDampingFactor\n+double getProlongationDampingFactor() const\n+Get the damping factor for the prolongation.\n+Definition: parameters.hh:342\n+Dune::Amg::CoarseningParameters::accumulate\n+AccumulationMode accumulate() const\n+Whether the data should be accumulated on fewer processes on coarser levels.\n+Definition: parameters.hh:312\n+Dune::Amg::AggregationParameters::setMaxConnectivity\n+void setMaxConnectivity(std::size_t connectivity)\n+Set the maximum number of connections a aggregate is allowed to have.\n+Definition: parameters.hh:220\n+Dune::Amg::AggregationParameters::minAggregateSize\n+std::size_t minAggregateSize() const\n+Get the minimum number of nodes a aggregate has to consist of.\n+Definition: parameters.hh:180\n+Dune::Amg::Parameters::getAdditive\n+bool getAdditive() const\n+Get whether to use additive multigrid.\n+Definition: parameters.hh:478\n+Dune::Amg::CoarseningParameters::setMaxLevel\n+void setMaxLevel(int l)\n+Set the maximum number of levels allowed in the hierarchy.\n+Definition: parameters.hh:263\n+Dune::Amg::Parameters::setDebugLevel\n+void setDebugLevel(int level)\n+Set the debugging level.\n+Definition: parameters.hh:401\n+Dune::Amg::Parameters::getGamma\n+std::size_t getGamma() const\n+Get the value of gamma; 1 for V-cycle, 2 for W-cycle.\n+Definition: parameters.hh:460\n+Dune::Amg::Parameters::setNoPostSmoothSteps\n+void setNoPostSmoothSteps(std::size_t steps)\n+Set the number of postsmoothing steps to apply.\n+Definition: parameters.hh:437\n+Dune::Amg::Parameters::getNoPreSmoothSteps\n+std::size_t getNoPreSmoothSteps() const\n+Get the number of presmoothing steps to apply.\n+Definition: parameters.hh:428\n+Dune::Amg::DependencyParameters::DependencyParameters\n+DependencyParameters()\n+Constructor.\n+Definition: parameters.hh:34\n+Dune::Amg::AggregationParameters::setMinAggregateSize\n+void setMinAggregateSize(std::size_t size)\n+Set the minimum number of nodes a aggregate has to consist of.\n+Definition: parameters.hh:188\n+Dune::Amg::CoarseningParameters::maxLevel\n+int maxLevel() const\n+Get the maximum number of levels allowed in the hierarchy.\n+Definition: parameters.hh:270\n+Dune::Amg::AggregationParameters::setDefaultValuesIsotropic\n+void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)\n+Sets reasonable default values for an isotropic problem.\n+Definition: parameters.hh:109\n+Dune::Amg::AggregationParameters::AggregationParameters\n+AggregationParameters()\n+Constructor.\n+Definition: parameters.hh:95\n+Dune::Amg::AggregationParameters::skipIsolated\n+bool skipIsolated() const\n+Whether isolated aggregates will not be represented on the coarse level.\n+Definition: parameters.hh:161\n+Dune::Amg::Parameters::Parameters\n+Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2,\n+double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu)\n+Constructor.\n+Definition: parameters.hh:493\n+Dune::Amg::CoarseningParameters::setCoarsenTarget\n+void setCoarsenTarget(int nodes)\n+Set the maximum number of unknowns allowed on the coarsest level.\n+Definition: parameters.hh:278\n+Dune::Amg::Parameters::setNoPreSmoothSteps\n+void setNoPreSmoothSteps(std::size_t steps)\n+Set the number of presmoothing steps to apply.\n+Definition: parameters.hh:420\n+Dune::Amg::AccumulationMode\n+AccumulationMode\n+Identifiers for the different accumulation modes.\n+Definition: parameters.hh:232\n+Dune::Amg::DependencyParameters::setBeta\n+void setBeta(double b)\n+Set threshold for marking nodes as isolated. The default value is 1.0E-5.\n+Definition: parameters.hh:42\n+Dune::Amg::AggregationParameters::maxDistance\n+std::size_t maxDistance() const\n+Get the maximal distance allowed between two nodes in a aggregate.\n+Definition: parameters.hh:144\n+Dune::Amg::CoarseningParameters::CoarseningParameters\n+CoarseningParameters(int maxLevel=100, int coarsenTarget=1000, double\n+minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode\n+accumulate=successiveAccu)\n+Constructor.\n+Definition: parameters.hh:356\n+Dune::Amg::Parameters::setGamma\n+void setGamma(std::size_t gamma)\n+Set the value of gamma; 1 for V-cycle, 2 for W-cycle.\n+Definition: parameters.hh:453\n+Dune::Amg::CoarseningParameters::setAccumulate\n+void setAccumulate(bool accu)\n+Definition: parameters.hh:324\n+Dune::Amg::AggregationParameters::setMaxDistance\n+void setMaxDistance(std::size_t distance)\n+Set the maximal distance allowed between two nodes in a aggregate.\n+Definition: parameters.hh:154\n+Dune::Amg::Parameters::debugLevel\n+int debugLevel() const\n+Get the debugging Level.\n+Definition: parameters.hh:411\n+Dune::Amg::Parameters::getNoPostSmoothSteps\n+std::size_t getNoPostSmoothSteps() const\n+Get the number of postsmoothing steps to apply.\n+Definition: parameters.hh:445\n+Dune::Amg::atOnceAccu\n+@ atOnceAccu\n+Accumulate data to one process at once.\n+Definition: parameters.hh:244\n+Dune::Amg::noAccu\n+@ noAccu\n+No data accumulution.\n+Definition: parameters.hh:238\n+Dune::Amg::successiveAccu\n+@ successiveAccu\n+Successively accumulate to fewer processes.\n+Definition: parameters.hh:248\n Dune\n Definition: allocator.hh:11\n-Dune::ScaledIdentityMatrix\n-A multiple of the identity matrix of static size.\n-Definition: scaledidmatrix.hh:30\n-Dune::ScaledIdentityMatrix::usmhv\n-void usmhv(const K &alpha, const X &x, Y &y) const\n-y += alpha A^H x\n-Definition: scaledidmatrix.hh:353\n-Dune::ScaledIdentityMatrix::mmtv\n-void mmtv(const X &x, Y &y) const\n-y -= A^T x\n-Definition: scaledidmatrix.hh:305\n-Dune::ScaledIdentityMatrix::operator-=\n-ScaledIdentityMatrix & operator-=(const ScaledIdentityMatrix &y)\n-vector space subtraction\n-Definition: scaledidmatrix.hh:169\n-Dune::ScaledIdentityMatrix::ConstColIterator\n-const_row_type::ConstIterator ConstColIterator\n-rename the iterators for easier access\n-Definition: scaledidmatrix.hh:131\n-Dune::ScaledIdentityMatrix::end\n-ConstIterator end() const\n-end iterator\n-Definition: scaledidmatrix.hh:140\n-Dune::ScaledIdentityMatrix::beforeBegin\n-Iterator beforeBegin()\n-Definition: scaledidmatrix.hh:118\n-Dune::ScaledIdentityMatrix::operator!=\n-bool operator!=(const ScaledIdentityMatrix &other) const\n-incomparison operator\n-Definition: scaledidmatrix.hh:229\n-Dune::ScaledIdentityMatrix::mmv\n-void mmv(const X &x, Y &y) const\n-y -= A x\n-Definition: scaledidmatrix.hh:293\n-Dune::ScaledIdentityMatrix::size_type\n-std::size_t size_type\n-The type used for the index access and size operations.\n-Definition: scaledidmatrix.hh:43\n-Dune::ScaledIdentityMatrix::usmv\n-void usmv(const K &alpha, const X &x, Y &y) const\n-y += alpha A x\n-Definition: scaledidmatrix.hh:329\n-Dune::ScaledIdentityMatrix::ColIterator\n-row_type::Iterator ColIterator\n-rename the iterators for easier access\n-Definition: scaledidmatrix.hh:95\n-Dune::ScaledIdentityMatrix::const_reference\n-const_row_type const_reference\n-Definition: scaledidmatrix.hh:53\n-Dune::ScaledIdentityMatrix::mv\n-void mv(const X &x, Y &y) const\n-y = A x\n-Definition: scaledidmatrix.hh:238\n-Dune::ScaledIdentityMatrix::umtv\n-void umtv(const X &x, Y &y) const\n-y += A^T x\n-Definition: scaledidmatrix.hh:269\n-Dune::ScaledIdentityMatrix::umhv\n-void umhv(const X &x, Y &y) const\n-y += A^H x\n-Definition: scaledidmatrix.hh:281\n-Dune::ScaledIdentityMatrix::row_type\n-DiagonalRowVector< K, n > row_type\n-Each row is implemented by a field vector.\n-Definition: scaledidmatrix.hh:50\n-Dune::ScaledIdentityMatrix::Iterator\n-ContainerWrapperIterator< const WrapperType, reference, reference > Iterator\n-Iterator class for sequential access.\n-Definition: scaledidmatrix.hh:89\n-Dune::ScaledIdentityMatrix::beforeEnd\n-Iterator beforeEnd()\n-Definition: scaledidmatrix.hh:111\n-Dune::ScaledIdentityMatrix::determinant\n-K determinant() const\n-calculates the determinant of this matrix\n-Definition: scaledidmatrix.hh:408\n-Dune::ScaledIdentityMatrix::field_type\n-K field_type\n-export the type representing the field\n-Definition: scaledidmatrix.hh:37\n-Dune::ScaledIdentityMatrix::usmtv\n-void usmtv(const K &alpha, const X &x, Y &y) const\n-y += alpha A^T x\n-Definition: scaledidmatrix.hh:341\n-Dune::ScaledIdentityMatrix::end\n-Iterator end()\n-end iterator\n-Definition: scaledidmatrix.hh:104\n-Dune::ScaledIdentityMatrix::iterator\n-Iterator iterator\n-typedef for stl compliant access\n-Definition: scaledidmatrix.hh:91\n-Dune::ScaledIdentityMatrix::scalar\n-const K & scalar() const\n-Get const reference to the scalar diagonal value.\n-Definition: scaledidmatrix.hh:477\n-Dune::ScaledIdentityMatrix::umv\n-void umv(const X &x, Y &y) const\n-y += A x\n-Definition: scaledidmatrix.hh:257\n-Dune::ScaledIdentityMatrix::blocklevel\n-static constexpr std::size_t blocklevel\n-We are at the leaf of the block recursion.\n-Definition: scaledidmatrix.hh:47\n-Dune::ScaledIdentityMatrix::diagonal\n-const K & diagonal(size_type) const\n-Get const reference to diagonal entry.\n-Definition: scaledidmatrix.hh:464\n-Dune::ScaledIdentityMatrix::rows\n-@ rows\n-The number of rows.\n-Definition: scaledidmatrix.hh:58\n-Dune::ScaledIdentityMatrix::cols\n-@ cols\n-The number of columns.\n-Definition: scaledidmatrix.hh:60\n-Dune::ScaledIdentityMatrix::operator=\n-ScaledIdentityMatrix & operator=(const K &k)\n-Definition: scaledidmatrix.hh:75\n-Dune::ScaledIdentityMatrix::ConstIterator\n-ContainerWrapperIterator< const WrapperType, const_reference, const_reference >\n-ConstIterator\n-Iterator class for sequential access.\n-Definition: scaledidmatrix.hh:125\n-Dune::ScaledIdentityMatrix::diagonal\n-K & diagonal(size_type)\n-Get reference to diagonal entry.\n-Definition: scaledidmatrix.hh:470\n-Dune::ScaledIdentityMatrix::solve\n-void solve(V &x, const V &b) const\n-Solve system A x = b.\n-Definition: scaledidmatrix.hh:394\n-Dune::ScaledIdentityMatrix::exists\n-bool exists(size_type i, size_type j) const\n-return true when (i,j) is in pattern\n-Definition: scaledidmatrix.hh:429\n-Dune::ScaledIdentityMatrix::RowIterator\n-Iterator RowIterator\n-rename the iterators for easier access\n-Definition: scaledidmatrix.hh:93\n-Dune::ScaledIdentityMatrix::const_iterator\n-ConstIterator const_iterator\n-typedef for stl compliant access\n-Definition: scaledidmatrix.hh:127\n-Dune::ScaledIdentityMatrix::ScaledIdentityMatrix\n-ScaledIdentityMatrix()\n-Default constructor.\n-Definition: scaledidmatrix.hh:66\n-Dune::ScaledIdentityMatrix::operator==\n-bool operator==(const ScaledIdentityMatrix &other) const\n-comparison operator\n-Definition: scaledidmatrix.hh:223\n-Dune::ScaledIdentityMatrix::beforeBegin\n-ConstIterator beforeBegin() const\n-Definition: scaledidmatrix.hh:154\n-Dune::ScaledIdentityMatrix::operator/=\n-ScaledIdentityMatrix & operator/=(const K &k)\n-vector space division by scalar\n-Definition: scaledidmatrix.hh:196\n-Dune::ScaledIdentityMatrix::operator<<\n-friend std::ostream & operator<<(std::ostream &s, const ScaledIdentityMatrix<\n-K, n > &a)\n-Sends the matrix to an output stream.\n-Definition: scaledidmatrix.hh:441\n-Dune::ScaledIdentityMatrix::frobenius_norm2\n-FieldTraits< field_type >::real_type frobenius_norm2() const\n-square of frobenius norm, need for block recursion\n-Definition: scaledidmatrix.hh:372\n-Dune::ScaledIdentityMatrix::frobenius_norm\n-FieldTraits< field_type >::real_type frobenius_norm() const\n-frobenius norm: sqrt(sum over squared values of entries)\n-Definition: scaledidmatrix.hh:366\n-Dune::ScaledIdentityMatrix::infinity_norm\n-FieldTraits< field_type >::real_type infinity_norm() const\n-infinity norm (row sum norm, how to generalize for blocks?)\n-Definition: scaledidmatrix.hh:378\n-Dune::ScaledIdentityMatrix::ConstRowIterator\n-ConstIterator ConstRowIterator\n-rename the iterators for easier access\n-Definition: scaledidmatrix.hh:129\n-Dune::ScaledIdentityMatrix::beforeEnd\n-ConstIterator beforeEnd() const\n-Definition: scaledidmatrix.hh:147\n-Dune::ScaledIdentityMatrix::M\n-size_type M() const\n-number of blocks in column direction\n-Definition: scaledidmatrix.hh:421\n-Dune::ScaledIdentityMatrix::operator[]\n-const_reference operator[](size_type i) const\n-Return const_reference object as row replacement.\n-Definition: scaledidmatrix.hh:458\n-Dune::ScaledIdentityMatrix::ScaledIdentityMatrix\n-ScaledIdentityMatrix(const K &k)\n-Constructor initializing the whole matrix with a scalar.\n-Definition: scaledidmatrix.hh:70\n-Dune::ScaledIdentityMatrix::operator*\n-friend auto operator*(const ScaledIdentityMatrix &matrix, Scalar scalar)\n-vector space multiplication with scalar\n-Definition: scaledidmatrix.hh:207\n-Dune::ScaledIdentityMatrix::infinity_norm_real\n-FieldTraits< field_type >::real_type infinity_norm_real() const\n-simplified infinity norm (uses Manhattan norm for complex values)\n-Definition: scaledidmatrix.hh:384\n-Dune::ScaledIdentityMatrix::operator*=\n-ScaledIdentityMatrix & operator*=(const K &k)\n-vector space multiplication with scalar\n-Definition: scaledidmatrix.hh:189\n-Dune::ScaledIdentityMatrix::identical\n-bool identical(const ScaledIdentityMatrix< K, n > &other) const\n-Definition: scaledidmatrix.hh:82\n-Dune::ScaledIdentityMatrix::invert\n-void invert()\n-Compute inverse.\n-Definition: scaledidmatrix.hh:402\n-Dune::ScaledIdentityMatrix::begin\n-Iterator begin()\n-begin iterator\n-Definition: scaledidmatrix.hh:98\n-Dune::ScaledIdentityMatrix::scalar\n-K & scalar()\n-Get reference to the scalar diagonal value.\n-Definition: scaledidmatrix.hh:484\n-Dune::ScaledIdentityMatrix::reference\n-row_type reference\n-Definition: scaledidmatrix.hh:51\n-Dune::ScaledIdentityMatrix::block_type\n-K block_type\n-export the type representing the components\n-Definition: scaledidmatrix.hh:40\n-Dune::ScaledIdentityMatrix::mmhv\n-void mmhv(const X &x, Y &y) const\n-y -= A^H x\n-Definition: scaledidmatrix.hh:317\n-Dune::ScaledIdentityMatrix::operator+=\n-ScaledIdentityMatrix & operator+=(const ScaledIdentityMatrix &y)\n-vector space addition\n-Definition: scaledidmatrix.hh:162\n-Dune::ScaledIdentityMatrix::const_row_type\n-DiagonalRowVectorConst< K, n > const_row_type\n-Definition: scaledidmatrix.hh:52\n-Dune::ScaledIdentityMatrix::mtv\n-void mtv(const X &x, Y &y) const\n-y = A^T x\n-Definition: scaledidmatrix.hh:250\n-Dune::ScaledIdentityMatrix::operator[]\n-reference operator[](size_type i)\n-Return reference object as row replacement.\n-Definition: scaledidmatrix.hh:452\n-Dune::ScaledIdentityMatrix::begin\n-ConstIterator begin() const\n-begin iterator\n-Definition: scaledidmatrix.hh:134\n-Dune::ScaledIdentityMatrix::N\n-size_type N() const\n-number of blocks in row direction\n-Definition: scaledidmatrix.hh:415\n-Dune::DenseMatrixAssigner<_DenseMatrix,_ScaledIdentityMatrix<_field,_N_>_>::\n-apply\n-static void apply(DenseMatrix &denseMatrix, ScaledIdentityMatrix< field, N >\n-const &rhs)\n-Definition: scaledidmatrix.hh:497\n-Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>::field_type\n-typename ScaledIdentityMatrix< K, n >::field_type field_type\n-Definition: scaledidmatrix.hh:510\n-Dune::FieldTraits<_ScaledIdentityMatrix<_K,_n_>_>::real_type\n-typename FieldTraits< field_type >::real_type real_type\n-Definition: scaledidmatrix.hh:511\n+Dune::Amg::DependencyParameters\n+Parameters needed to check whether a node depends on another.\n+Definition: parameters.hh:31\n+Dune::Amg::AggregationParameters\n+Parameters needed for the aggregation process.\n+Definition: parameters.hh:84\n+Dune::Amg::CoarseningParameters\n+Parameters for the complete coarsening process.\n+Definition: parameters.hh:258\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00188.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00188.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixindexset.hh File Reference\n+dune-istl: amg.hh File Reference\n \n \n \n \n \n \n \n@@ -58,40 +58,79 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n \n-
    matrixindexset.hh File Reference
    \n+Namespaces |\n+Functions
    \n+ \n \n
    \n-
    #include <vector>
    \n-#include <set>
    \n+\n+

    The AMG preconditioner. \n+More...

    \n+
    #include <memory>
    \n+#include <sstream>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/istl/paamg/smoother.hh>
    \n+#include <dune/istl/paamg/transfer.hh>
    \n+#include <dune/istl/paamg/matrixhierarchy.hh>
    \n+#include <dune/istl/solvers.hh>
    \n+#include <dune/istl/scalarproducts.hh>
    \n+#include <dune/istl/superlu.hh>
    \n+#include <dune/istl/umfpack.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/common/typetraits.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include <dune/common/parametertree.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    class  Dune::MatrixIndexSet
     Stores the nonzero entries in a sparse matrix. More...
    class  Dune::Amg::AMG< M, X, S, PI, A >
     Parallel algebraic multigrid based on agglomeration. More...
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, SolverType >
     
    struct  Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, superlu >
     
    struct  Dune::AMGCreator
     
    struct  Dune::AMGCreator::isValidBlockType< class >
     
    struct  Dune::AMGCreator::isValidBlockType< FieldMatrix< T, n, m > >
     
    \n \n \n \n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n

    \n+Functions

     Dune::DUNE_REGISTER_PRECONDITIONER ("amg", AMGCreator())
     
    \n-
    \n+

    Detailed Description

    \n+

    The AMG preconditioner.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,22 +4,62 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-matrixindexset.hh File Reference\n-#include \n-#include \n+ * paamg\n+Classes | Namespaces | Functions\n+amg.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+The AMG preconditioner. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::MatrixIndexSet\n-\u00a0 Stores the nonzero entries in a sparse matrix. More...\n+ class \u00a0Dune::Amg::AMG<_M,_X,_S,_PI,_A_>\n+\u00a0 Parallel algebraic multigrid based on agglomeration. More...\n+\u00a0\n+struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>\n+\u00a0\n+struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>::Solver<_M,\n+ SolverType_>\n+\u00a0\n+struct \u00a0Dune::Amg::DirectSolverSelector<_Matrix,_Vector_>::Solver<_M,_superlu\n+ >\n+\u00a0\n+struct \u00a0Dune::AMGCreator\n+\u00a0\n+struct \u00a0Dune::AMGCreator::isValidBlockType<_class_>\n+\u00a0\n+struct \u00a0Dune::AMGCreator::isValidBlockType<_FieldMatrix<_T,_n,_m_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::Amg\n+\u00a0\n+ Functions\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"amg\", AMGCreator())\n+\u00a0\n+***** Detailed Description *****\n+The AMG preconditioner.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00188_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00188_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: matrixindexset.hh Source File\n+dune-istl: amg.hh Source File\n \n \n \n \n \n \n \n@@ -58,136 +58,1207 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    matrixindexset.hh
    \n+
    amg.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_MATRIXINDEXSET_HH
    \n-
    6#define DUNE_ISTL_MATRIXINDEXSET_HH
    \n+
    5#ifndef DUNE_AMG_AMG_HH
    \n+
    6#define DUNE_AMG_AMG_HH
    \n
    7
    \n-
    8#include <vector>
    \n-
    9#include <set>
    \n-
    10
    \n-
    11namespace Dune {
    \n-
    12
    \n-
    13
    \n-\n-
    16 {
    \n-
    17
    \n-
    18 public:
    \n-
    19 typedef std::size_t size_type;
    \n-
    20
    \n-
    22 MatrixIndexSet() : rows_(0), cols_(0)
    \n-
    23 {}
    \n+
    8#include <memory>
    \n+
    9#include <sstream>
    \n+
    10#include <dune/common/exceptions.hh>
    \n+\n+\n+\n+
    14#include <dune/istl/solvers.hh>
    \n+\n+
    16#include <dune/istl/superlu.hh>
    \n+
    17#include <dune/istl/umfpack.hh>
    \n+\n+
    19#include <dune/common/typetraits.hh>
    \n+
    20#include <dune/common/exceptions.hh>
    \n+
    21#include <dune/common/scalarvectorview.hh>
    \n+
    22#include <dune/common/scalarmatrixview.hh>
    \n+
    23#include <dune/common/parametertree.hh>
    \n
    24
    \n-
    26 MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) {
    \n-
    27 indices_.resize(rows_);
    \n-
    28 }
    \n-
    29
    \n-\n-
    32 rows_ = rows;
    \n-
    33 cols_ = cols;
    \n-
    34 indices_.resize(rows_);
    \n-
    35 }
    \n-
    36
    \n-
    38 void add(size_type i, size_type j) {
    \n-
    39 indices_[i].insert(j);
    \n-
    40 }
    \n-
    41
    \n-
    43 size_type size() const {
    \n-
    44 size_type entries = 0;
    \n-
    45 for (size_type i=0; i<rows_; i++)
    \n-
    46 entries += indices_[i].size();
    \n-
    47
    \n-
    48 return entries;
    \n-
    49 }
    \n-
    50
    \n-
    52 size_type rows() const {return rows_;}
    \n-
    53
    \n-
    54
    \n-
    56 size_type rowsize(size_type row) const {return indices_[row].size();}
    \n-
    57
    \n-
    64 template <class MatrixType>
    \n-
    65 void import(const MatrixType& m, size_type rowOffset=0, size_type colOffset=0) {
    \n-
    66
    \n-
    67 typedef typename MatrixType::row_type RowType;
    \n-
    68 typedef typename RowType::ConstIterator ColumnIterator;
    \n-
    69
    \n-
    70 for (size_type rowIdx=0; rowIdx<m.N(); rowIdx++) {
    \n-
    71
    \n-
    72 const RowType& row = m[rowIdx];
    \n-
    73
    \n-
    74 ColumnIterator cIt = row.begin();
    \n-
    75 ColumnIterator cEndIt = row.end();
    \n-
    76
    \n-
    77 for(; cIt!=cEndIt; ++cIt)
    \n-
    78 add(rowIdx+rowOffset, cIt.index()+colOffset);
    \n-
    79
    \n-
    80 }
    \n-
    81
    \n-
    82 }
    \n-
    83
    \n-
    89 template <class MatrixType>
    \n-
    90 void exportIdx(MatrixType& matrix) const {
    \n-
    91
    \n-
    92 matrix.setSize(rows_, cols_);
    \n-
    93 matrix.setBuildMode(MatrixType::random);
    \n-
    94
    \n-
    95 for (size_type i=0; i<rows_; i++)
    \n-
    96 matrix.setrowsize(i, indices_[i].size());
    \n-
    97
    \n-
    98 matrix.endrowsizes();
    \n-
    99
    \n-
    100 for (size_type i=0; i<rows_; i++) {
    \n+
    25namespace Dune
    \n+
    26{
    \n+
    27 namespace Amg
    \n+
    28 {
    \n+
    46 template<class M, class X, class S, class P, class K, class A>
    \n+
    47 class KAMG;
    \n+
    48
    \n+
    49 template<class T>
    \n+
    50 class KAmgTwoGrid;
    \n+
    51
    \n+
    62 template<class M, class X, class S, class PI=SequentialInformation,
    \n+
    63 class A=std::allocator<X> >
    \n+
    64 class AMG : public Preconditioner<X,X>
    \n+
    65 {
    \n+
    66 template<class M1, class X1, class S1, class P1, class K1, class A1>
    \n+
    67 friend class KAMG;
    \n+
    68
    \n+
    69 friend class KAmgTwoGrid<AMG>;
    \n+
    70
    \n+
    71 public:
    \n+
    73 typedef M Operator;
    \n+\n+\n+\n+
    85
    \n+
    87 typedef X Domain;
    \n+
    89 typedef X Range;
    \n+\n+
    97 typedef S Smoother;
    \n+
    98
    \n+\n
    101
    \n-
    102 typename std::set<size_type>::iterator it = indices_[i].begin();
    \n-
    103 for (; it!=indices_[i].end(); ++it)
    \n-
    104 matrix.addindex(i, *it);
    \n-
    105
    \n-
    106 }
    \n-
    107
    \n-
    108 matrix.endindices();
    \n-
    109
    \n-
    110 }
    \n-
    111
    \n-
    112 private:
    \n+
    111 AMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n+
    112 const SmootherArgs& smootherArgs, const Parameters& parms);
    \n
    113
    \n-
    114 std::vector<std::set<size_type> > indices_;
    \n-
    115
    \n-
    116 size_type rows_, cols_;
    \n-
    117
    \n-
    118 };
    \n-
    119
    \n-
    120
    \n-
    121} // end namespace Dune
    \n-
    122
    \n-
    123#endif
    \n+
    125 template<class C>
    \n+
    126 AMG(const Operator& fineOperator, const C& criterion,
    \n+
    127 const SmootherArgs& smootherArgs=SmootherArgs(),
    \n+\n+
    129
    \n+
    180 AMG(std::shared_ptr<const Operator> fineOperator, const ParameterTree& configuration, const ParallelInformation& pinfo=ParallelInformation());
    \n+
    181
    \n+
    185 AMG(const AMG& amg);
    \n+
    186
    \n+
    188 void pre(Domain& x, Range& b);
    \n+
    189
    \n+
    191 void apply(Domain& v, const Range& d);
    \n+
    192
    \n+\n+
    195 {
    \n+
    196 return category_;
    \n+
    197 }
    \n+
    198
    \n+
    200 void post(Domain& x);
    \n+
    201
    \n+
    206 template<class A1>
    \n+
    207 void getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont);
    \n+
    208
    \n+
    209 std::size_t levels();
    \n+
    210
    \n+
    211 std::size_t maxlevels();
    \n+
    212
    \n+\n+
    222 {
    \n+
    223 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
    \n+
    224 }
    \n+
    225
    \n+\n+
    231
    \n+
    232 private:
    \n+
    233 /*
    \n+
    234 * @brief Helper function to create hierarchies with parameter tree.
    \n+
    235 *
    \n+
    236 * Will create the coarsen criterion with the norm and create the
    \n+
    237 * Hierarchies
    \n+
    238 * \\tparam Norm Type of the norm to use.
    \n+
    239 */
    \n+
    240 template<class Norm>
    \n+
    241 void createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr,
    \n+
    242 const PI& pinfo, const Norm&,
    \n+
    243 const ParameterTree& configuration,
    \n+
    244 std::true_type compiles = std::true_type());
    \n+
    245 template<class Norm>
    \n+
    246 void createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr,
    \n+
    247 const PI& pinfo, const Norm&,
    \n+
    248 const ParameterTree& configuration,
    \n+
    249 std::false_type);
    \n+
    254 template<class C>
    \n+
    255 void createHierarchies(C& criterion, std::shared_ptr<const Operator> matrixptr,
    \n+
    256 const PI& pinfo, const ParameterTree& configuration);
    \n+
    263 template<class C>
    \n+
    264 void createHierarchies(C& criterion,
    \n+
    265 const std::shared_ptr<const Operator>& matrixptr,
    \n+
    266 const PI& pinfo);
    \n+
    273 struct LevelContext
    \n+
    274 {
    \n+\n+\n+\n+\n+
    291 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
    \n+
    295 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
    \n+\n+\n+\n+
    311 std::size_t level;
    \n+
    312 };
    \n+
    313
    \n+
    314
    \n+
    319 void mgc(LevelContext& levelContext);
    \n+
    320
    \n+
    321 void additiveMgc();
    \n+
    322
    \n+
    329 void moveToFineLevel(LevelContext& levelContext,bool processedFineLevel);
    \n+
    330
    \n+
    335 bool moveToCoarseLevel(LevelContext& levelContext);
    \n+
    336
    \n+
    341 void initIteratorsWithFineLevel(LevelContext& levelContext);
    \n+
    342
    \n+
    344 std::shared_ptr<OperatorHierarchy> matrices_;
    \n+
    346 SmootherArgs smootherArgs_;
    \n+
    348 std::shared_ptr<Hierarchy<Smoother,A> > smoothers_;
    \n+
    350 std::shared_ptr<CoarseSolver> solver_;
    \n+
    352 std::shared_ptr<Hierarchy<Range,A>> rhs_;
    \n+
    354 std::shared_ptr<Hierarchy<Domain,A>> lhs_;
    \n+
    356 std::shared_ptr<Hierarchy<Domain,A>> update_;
    \n+\n+
    360 std::shared_ptr<ScalarProduct> scalarProduct_;
    \n+
    362 std::size_t gamma_;
    \n+
    364 std::size_t preSteps_;
    \n+
    366 std::size_t postSteps_;
    \n+
    367 bool buildHierarchy_;
    \n+
    368 bool additive;
    \n+
    369 bool coarsesolverconverged;
    \n+
    370 std::shared_ptr<Smoother> coarseSmoother_;
    \n+
    372 SolverCategory::Category category_;
    \n+
    374 std::size_t verbosity_;
    \n+
    375
    \n+
    376 struct ToLower
    \n+
    377 {
    \n+
    378 std::string operator()(const std::string& str)
    \n+
    379 {
    \n+
    380 std::stringstream retval;
    \n+
    381 std::ostream_iterator<char> out(retval);
    \n+
    382 std::transform(str.begin(), str.end(), out,
    \n+
    383 [](char c){
    \n+
    384 return std::tolower(c, std::locale::classic());
    \n+
    385 });
    \n+
    386 return retval.str();
    \n+
    387 }
    \n+
    388 };
    \n+
    389 };
    \n+
    390
    \n+
    391 template<class M, class X, class S, class PI, class A>
    \n+
    392 inline AMG<M,X,S,PI,A>::AMG(const AMG& amg)
    \n+
    393 : matrices_(amg.matrices_), smootherArgs_(amg.smootherArgs_),
    \n+
    394 smoothers_(amg.smoothers_), solver_(amg.solver_),
    \n+
    395 rhs_(), lhs_(), update_(),
    \n+
    396 scalarProduct_(amg.scalarProduct_), gamma_(amg.gamma_),
    \n+
    397 preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
    \n+
    398 buildHierarchy_(amg.buildHierarchy_),
    \n+
    399 additive(amg.additive), coarsesolverconverged(amg.coarsesolverconverged),
    \n+
    400 coarseSmoother_(amg.coarseSmoother_),
    \n+
    401 category_(amg.category_),
    \n+
    402 verbosity_(amg.verbosity_)
    \n+
    403 {}
    \n+
    404
    \n+
    405 template<class M, class X, class S, class PI, class A>
    \n+\n+
    407 const SmootherArgs& smootherArgs,
    \n+
    408 const Parameters& parms)
    \n+
    409 : matrices_(stackobject_to_shared_ptr(matrices)), smootherArgs_(smootherArgs),
    \n+
    410 smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver),
    \n+
    411 rhs_(), lhs_(), update_(), scalarProduct_(0),
    \n+
    412 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
    \n+
    413 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
    \n+
    414 additive(parms.getAdditive()), coarsesolverconverged(true),
    \n+
    415 coarseSmoother_(),
    \n+
    416// #warning should category be retrieved from matrices?
    \n+
    417 category_(SolverCategory::category(*smoothers_->coarsest())),
    \n+
    418 verbosity_(parms.debugLevel())
    \n+
    419 {
    \n+
    420 assert(matrices_->isBuilt());
    \n+
    421
    \n+
    422 // build the necessary smoother hierarchies
    \n+
    423 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);
    \n+
    424 }
    \n+
    425
    \n+
    426 template<class M, class X, class S, class PI, class A>
    \n+
    427 template<class C>
    \n+\n+
    429 const C& criterion,
    \n+
    430 const SmootherArgs& smootherArgs,
    \n+
    431 const PI& pinfo)
    \n+
    432 : smootherArgs_(smootherArgs),
    \n+
    433 smoothers_(new Hierarchy<Smoother,A>), solver_(),
    \n+
    434 rhs_(), lhs_(), update_(), scalarProduct_(),
    \n+
    435 gamma_(criterion.getGamma()), preSteps_(criterion.getNoPreSmoothSteps()),
    \n+
    436 postSteps_(criterion.getNoPostSmoothSteps()), buildHierarchy_(true),
    \n+
    437 additive(criterion.getAdditive()), coarsesolverconverged(true),
    \n+
    438 coarseSmoother_(),
    \n+
    439 category_(SolverCategory::category(pinfo)),
    \n+
    440 verbosity_(criterion.debugLevel())
    \n+
    441 {
    \n+\n+
    443 DUNE_THROW(InvalidSolverCategory, "Matrix and Communication must have the same SolverCategory!");
    \n+
    444 // TODO: reestablish compile time checks.
    \n+
    445 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
    \n+
    446 // "Matrix and Solver must match in terms of category!");
    \n+
    447 auto matrixptr = stackobject_to_shared_ptr(matrix);
    \n+
    448 createHierarchies(criterion, matrixptr, pinfo);
    \n+
    449 }
    \n+
    450
    \n+
    451 template<class M, class X, class S, class PI, class A>
    \n+
    452 AMG<M,X,S,PI,A>::AMG(std::shared_ptr<const Operator> matrixptr,
    \n+
    453 const ParameterTree& configuration,
    \n+
    454 const ParallelInformation& pinfo) :
    \n+
    455 smoothers_(new Hierarchy<Smoother,A>),
    \n+
    456 solver_(), rhs_(), lhs_(), update_(), scalarProduct_(), buildHierarchy_(true),
    \n+
    457 coarsesolverconverged(true), coarseSmoother_(),
    \n+
    458 category_(SolverCategory::category(pinfo))
    \n+
    459 {
    \n+
    460
    \n+
    461 if (configuration.hasKey ("smootherIterations"))
    \n+
    462 smootherArgs_.iterations = configuration.get<int>("smootherIterations");
    \n+
    463
    \n+
    464 if (configuration.hasKey ("smootherRelaxation"))
    \n+
    465 smootherArgs_.relaxationFactor = configuration.get<typename SmootherArgs::RelaxationFactor>("smootherRelaxation");
    \n+
    466
    \n+
    467 auto normName = ToLower()(configuration.get("strengthMeasure", "diagonal"));
    \n+
    468 auto index = configuration.get<int>("diagonalRowIndex", 0);
    \n+
    469
    \n+
    470 if ( normName == "diagonal")
    \n+
    471 {
    \n+
    472 using field_type = typename M::field_type;
    \n+
    473 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    474 std::is_convertible<field_type, real_type> compiles;
    \n+
    475
    \n+
    476 switch (index)
    \n+
    477 {
    \n+
    478 case 0:
    \n+
    479 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<0>(), configuration, compiles);
    \n+
    480 break;
    \n+
    481 case 1:
    \n+
    482 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<1>(), configuration, compiles);
    \n+
    483 break;
    \n+
    484 case 2:
    \n+
    485 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<2>(), configuration, compiles);
    \n+
    486 break;
    \n+
    487 case 3:
    \n+
    488 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<3>(), configuration, compiles);
    \n+
    489 break;
    \n+
    490 case 4:
    \n+
    491 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<4>(), configuration, compiles);
    \n+
    492 break;
    \n+
    493 default:
    \n+
    494 DUNE_THROW(InvalidStateException, "Currently strengthIndex>4 is not supported.");
    \n+
    495 }
    \n+
    496 }
    \n+
    497 else if (normName == "rowsum")
    \n+
    498 createCriterionAndHierarchies(matrixptr, pinfo, RowSum(), configuration);
    \n+
    499 else if (normName == "frobenius")
    \n+
    500 createCriterionAndHierarchies(matrixptr, pinfo, FrobeniusNorm(), configuration);
    \n+
    501 else if (normName == "one")
    \n+
    502 createCriterionAndHierarchies(matrixptr, pinfo, AlwaysOneNorm(), configuration);
    \n+
    503 else
    \n+
    504 DUNE_THROW(Dune::NotImplemented, "Wrong config file: strengthMeasure "<<normName<<" is not supported by AMG");
    \n+
    505 }
    \n+
    506
    \n+
    507 template<class M, class X, class S, class PI, class A>
    \n+
    508 template<class Norm>
    \n+
    509 void AMG<M,X,S,PI,A>::createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const Norm&, const ParameterTree& configuration, std::false_type)
    \n+
    510 {
    \n+
    511 DUNE_THROW(InvalidStateException, "Strength of connection measure does not support this type ("
    \n+
    512 << className<typename M::field_type>() << ") as it is lacking a conversion to"
    \n+
    513 << className<typename FieldTraits<typename M::field_type>::real_type>() << ".");
    \n+
    514 }
    \n+
    515
    \n+
    516 template<class M, class X, class S, class PI, class A>
    \n+
    517 template<class Norm>
    \n+
    518 void AMG<M,X,S,PI,A>::createCriterionAndHierarchies(std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const Norm&, const ParameterTree& configuration, std::true_type)
    \n+
    519 {
    \n+
    520 if (configuration.get<bool>("criterionSymmetric", true))
    \n+
    521 {
    \n+
    522 using Criterion = Dune::Amg::CoarsenCriterion<
    \n+\n+
    524 Criterion criterion;
    \n+
    525 createHierarchies(criterion, matrixptr, pinfo, configuration);
    \n+
    526 }
    \n+
    527 else
    \n+
    528 {
    \n+
    529 using Criterion = Dune::Amg::CoarsenCriterion<
    \n+\n+
    531 Criterion criterion;
    \n+
    532 createHierarchies(criterion, matrixptr, pinfo, configuration);
    \n+
    533 }
    \n+
    534 }
    \n+
    535
    \n+
    536 template<class M, class X, class S, class PI, class A>
    \n+
    537 template<class C>
    \n+
    538 void AMG<M,X,S,PI,A>::createHierarchies(C& criterion, std::shared_ptr<const Operator> matrixptr, const PI& pinfo, const ParameterTree& configuration)
    \n+
    539 {
    \n+
    540 if (configuration.hasKey ("maxLevel"))
    \n+
    541 criterion.setMaxLevel(configuration.get<int>("maxLevel"));
    \n+
    542
    \n+
    543 if (configuration.hasKey ("minCoarseningRate"))
    \n+
    544 criterion.setMinCoarsenRate(configuration.get<int>("minCoarseningRate"));
    \n+
    545
    \n+
    546 if (configuration.hasKey ("coarsenTarget"))
    \n+
    547 criterion.setCoarsenTarget (configuration.get<int>("coarsenTarget"));
    \n+
    548
    \n+
    549 if (configuration.hasKey ("accumulationMode"))
    \n+
    550 {
    \n+
    551 std::string mode = ToLower()(configuration.get<std::string>("accumulationMode"));
    \n+
    552 if ( mode == "none")
    \n+
    553 criterion.setAccumulate(AccumulationMode::noAccu);
    \n+
    554 else if ( mode == "atonce" )
    \n+
    555 criterion.setAccumulate(AccumulationMode::atOnceAccu);
    \n+
    556 else if ( mode == "successive")
    \n+
    557 criterion.setCoarsenTarget (AccumulationMode::successiveAccu);
    \n+
    558 else
    \n+
    559 DUNE_THROW(InvalidSolverFactoryConfiguration, "Parameter accumulationMode does not allow value "
    \n+
    560 << mode <<".");
    \n+
    561 }
    \n+
    562
    \n+
    563 if (configuration.hasKey ("prolongationDampingFactor"))
    \n+
    564 criterion.setProlongationDampingFactor (configuration.get<double>("prolongationDampingFactor"));
    \n+
    565
    \n+
    566 if (configuration.hasKey("defaultAggregationSizeMode"))
    \n+
    567 {
    \n+
    568 auto mode = ToLower()(configuration.get<std::string>("defaultAggregationSizeMode"));
    \n+
    569 auto dim = configuration.get<std::size_t>("defaultAggregationDimension");
    \n+
    570 std::size_t maxDistance = 2;
    \n+
    571 if (configuration.hasKey("MaxAggregateDistance"))
    \n+
    572 maxDistance = configuration.get<std::size_t>("maxAggregateDistance");
    \n+
    573 if (mode == "isotropic")
    \n+
    574 criterion.setDefaultValuesIsotropic(dim, maxDistance);
    \n+
    575 else if(mode == "anisotropic")
    \n+
    576 criterion.setDefaultValuesAnisotropic(dim, maxDistance);
    \n+
    577 else
    \n+
    578 DUNE_THROW(InvalidSolverFactoryConfiguration, "Parameter accumulationMode does not allow value "
    \n+
    579 << mode <<".");
    \n+
    580 }
    \n+
    581
    \n+
    582 if (configuration.hasKey("maxAggregateDistance"))
    \n+
    583 criterion.setMaxDistance(configuration.get<std::size_t>("maxAggregateDistance"));
    \n+
    584
    \n+
    585 if (configuration.hasKey("minAggregateSize"))
    \n+
    586 criterion.setMinAggregateSize(configuration.get<std::size_t>("minAggregateSize"));
    \n+
    587
    \n+
    588 if (configuration.hasKey("maxAggregateSize"))
    \n+
    589 criterion.setMaxAggregateSize(configuration.get<std::size_t>("maxAggregateSize"));
    \n+
    590
    \n+
    591 if (configuration.hasKey("maxAggregateConnectivity"))
    \n+
    592 criterion.setMaxConnectivity(configuration.get<std::size_t>("maxAggregateConnectivity"));
    \n+
    593
    \n+
    594 if (configuration.hasKey ("alpha"))
    \n+
    595 criterion.setAlpha (configuration.get<double> ("alpha"));
    \n+
    596
    \n+
    597 if (configuration.hasKey ("beta"))
    \n+
    598 criterion.setBeta (configuration.get<double> ("beta"));
    \n+
    599
    \n+
    600 if (configuration.hasKey ("gamma"))
    \n+
    601 criterion.setGamma (configuration.get<std::size_t> ("gamma"));
    \n+
    602 gamma_ = criterion.getGamma();
    \n+
    603
    \n+
    604 if (configuration.hasKey ("additive"))
    \n+
    605 criterion.setAdditive (configuration.get<bool>("additive"));
    \n+
    606 additive = criterion.getAdditive();
    \n+
    607
    \n+
    608 if (configuration.hasKey ("preSteps"))
    \n+
    609 criterion.setNoPreSmoothSteps (configuration.get<std::size_t> ("preSteps"));
    \n+
    610 preSteps_ = criterion.getNoPreSmoothSteps ();
    \n+
    611
    \n+
    612 if (configuration.hasKey ("postSteps"))
    \n+
    613 criterion.setNoPostSmoothSteps (configuration.get<std::size_t> ("postSteps"));
    \n+
    614 postSteps_ = criterion.getNoPostSmoothSteps ();
    \n+
    615
    \n+
    616 verbosity_ = configuration.get("verbosity", 0);
    \n+
    617 criterion.setDebugLevel (verbosity_);
    \n+
    618
    \n+
    619 createHierarchies(criterion, matrixptr, pinfo);
    \n+
    620 }
    \n+
    621
    \n+
    622 template <class Matrix,
    \n+
    623 class Vector>
    \n+\n+
    625 {
    \n+\n+\n+
    628
    \n+
    629 static constexpr SolverType solver =
    \n+
    630#if DISABLE_AMG_DIRECTSOLVER
    \n+
    631 none;
    \n+
    632#elif HAVE_SUITESPARSE_UMFPACK
    \n+\n+
    634#elif HAVE_SUPERLU
    \n+
    635 superlu ;
    \n+
    636#else
    \n+
    637 none;
    \n+
    638#endif
    \n+
    639
    \n+
    640 template <class M, SolverType>
    \n+
    641 struct Solver
    \n+
    642 {
    \n+\n+
    644 static type* create(const M& mat, bool verbose, bool reusevector )
    \n+
    645 {
    \n+
    646 DUNE_THROW(NotImplemented,"DirectSolver not selected");
    \n+
    647 return nullptr;
    \n+
    648 }
    \n+
    649 static std::string name () { return "None"; }
    \n+
    650 };
    \n+
    651#if HAVE_SUITESPARSE_UMFPACK
    \n+
    652 template <class M>
    \n+
    653 struct Solver< M, umfpack >
    \n+
    654 {
    \n+
    655 typedef UMFPack< M > type;
    \n+
    656 static type* create(const M& mat, bool verbose, bool reusevector )
    \n+
    657 {
    \n+
    658 return new type(mat, verbose, reusevector );
    \n+
    659 }
    \n+
    660 static std::string name () { return "UMFPack"; }
    \n+
    661 };
    \n+
    662#endif
    \n+
    663#if HAVE_SUPERLU
    \n+
    664 template <class M>
    \n+
    665 struct Solver< M, superlu >
    \n+
    666 {
    \n+\n+
    668 static type* create(const M& mat, bool verbose, bool reusevector )
    \n+
    669 {
    \n+
    670 return new type(mat, verbose, reusevector );
    \n+
    671 }
    \n+
    672 static std::string name () { return "SuperLU"; }
    \n+
    673 };
    \n+
    674#endif
    \n+
    675
    \n+
    676 // define direct solver type to be used
    \n+\n+\n+
    679 static constexpr bool isDirectSolver = solver != none;
    \n+
    680 static std::string name() { return SelectedSolver :: name (); }
    \n+
    681 static DirectSolver* create(const Matrix& mat, bool verbose, bool reusevector )
    \n+
    682 {
    \n+
    683 return SelectedSolver :: create( mat, verbose, reusevector );
    \n+
    684 }
    \n+
    685 };
    \n+
    686
    \n+
    687 template<class M, class X, class S, class PI, class A>
    \n+
    688 template<class C>
    \n+
    689 void AMG<M,X,S,PI,A>::createHierarchies(C& criterion,
    \n+
    690 const std::shared_ptr<const Operator>& matrixptr,
    \n+
    691 const PI& pinfo)
    \n+
    692 {
    \n+
    693 Timer watch;
    \n+
    694 matrices_ = std::make_shared<OperatorHierarchy>(
    \n+
    695 std::const_pointer_cast<Operator>(matrixptr),
    \n+
    696 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
    \n+
    697
    \n+
    698 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
    \n+
    699
    \n+
    700 // build the necessary smoother hierarchies
    \n+
    701 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);
    \n+
    702
    \n+
    703 // test whether we should solve on the coarse level. That is the case if we
    \n+
    704 // have that level and if there was a redistribution on this level then our
    \n+
    705 // communicator has to be valid (size()>0) as the smoother might try to communicate
    \n+
    706 // in the constructor.
    \n+
    707 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()
    \n+
    708 && ( ! matrices_->redistributeInformation().back().isSetup() ||
    \n+
    709 matrices_->parallelInformation().coarsest().getRedistributed().communicator().size() ) )
    \n+
    710 {
    \n+
    711 // We have the carsest level. Create the coarse Solver
    \n+
    712 SmootherArgs sargs(smootherArgs_);
    \n+
    713 sargs.iterations = 1;
    \n+
    714
    \n+\n+
    716 cargs.setArgs(sargs);
    \n+
    717 if(matrices_->redistributeInformation().back().isSetup()) {
    \n+
    718 // Solve on the redistributed partitioning
    \n+
    719 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
    \n+
    720 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
    \n+
    721 }else{
    \n+
    722 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
    \n+
    723 cargs.setComm(*matrices_->parallelInformation().coarsest());
    \n+
    724 }
    \n+
    725
    \n+
    726 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
    \n+
    727 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
    \n+
    728
    \n+
    729 typedef DirectSolverSelector< typename M::matrix_type, X > SolverSelector;
    \n+
    730
    \n+
    731 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
    \n+
    732 if( SolverSelector::isDirectSolver &&
    \n+
    733 (std::is_same<ParallelInformation,SequentialInformation>::value // sequential mode
    \n+
    734 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
    \n+
    735 || (matrices_->parallelInformation().coarsest().isRedistributed()
    \n+
    736 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
    \n+
    737 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0) )
    \n+
    738 )
    \n+
    739 { // redistribute and 1 proc
    \n+
    740 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n+
    741 {
    \n+
    742 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n+
    743 {
    \n+
    744 // We are still participating on this level
    \n+
    745 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
    \n+
    746 }
    \n+
    747 else
    \n+
    748 solver_.reset();
    \n+
    749 }
    \n+
    750 else
    \n+
    751 {
    \n+
    752 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest()->getmat(), false, false));
    \n+
    753 }
    \n+
    754 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
    \n+
    755 std::cout<< "Using a direct coarse solver (" << SolverSelector::name() << ")" << std::endl;
    \n+
    756 }
    \n+
    757 else
    \n+
    758 {
    \n+
    759 if(matrices_->parallelInformation().coarsest().isRedistributed())
    \n+
    760 {
    \n+
    761 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
    \n+
    762 // We are still participating on this level
    \n+
    763
    \n+
    764 // we have to allocate these types using the rebound allocator
    \n+
    765 // in order to ensure that we fulfill the alignment requirements
    \n+
    766 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
    \n+
    767 *scalarProduct_,
    \n+
    768 *coarseSmoother_, 1E-2, 1000, 0));
    \n+
    769 else
    \n+
    770 solver_.reset();
    \n+
    771 }else
    \n+
    772 {
    \n+
    773 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
    \n+
    774 *scalarProduct_,
    \n+
    775 *coarseSmoother_, 1E-2, 1000, 0));
    \n+
    776 // // we have to allocate these types using the rebound allocator
    \n+
    777 // // in order to ensure that we fulfill the alignment requirements
    \n+
    778 // using Alloc = typename std::allocator_traits<A>::template rebind_alloc<BiCGSTABSolver<X>>;
    \n+
    779 // Alloc alloc;
    \n+
    780 // auto p = alloc.allocate(1);
    \n+
    781 // std::allocator_traits<Alloc>::construct(alloc, p,
    \n+
    782 // const_cast<M&>(*matrices_->matrices().coarsest()),
    \n+
    783 // *scalarProduct_,
    \n+
    784 // *coarseSmoother_, 1E-2, 1000, 0);
    \n+
    785 // solver_.reset(p,[](BiCGSTABSolver<X>* p){
    \n+
    786 // Alloc alloc;
    \n+
    787 // std::allocator_traits<Alloc>::destroy(alloc, p);
    \n+
    788 // alloc.deallocate(p,1);
    \n+
    789 // });
    \n+
    790 }
    \n+
    791 }
    \n+
    792 }
    \n+
    793
    \n+
    794 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
    \n+
    795 std::cout<<"Building hierarchy of "<<matrices_->maxlevels()<<" levels "
    \n+
    796 <<"(including coarse solver) took "<<watch.elapsed()<<" seconds."<<std::endl;
    \n+
    797 }
    \n+
    798
    \n+
    799
    \n+
    800 template<class M, class X, class S, class PI, class A>
    \n+\n+
    802 {
    \n+
    803 // Detect Matrix rows where all offdiagonal entries are
    \n+
    804 // zero and set x such that A_dd*x_d=b_d
    \n+
    805 // Thus users can be more careless when setting up their linear
    \n+
    806 // systems.
    \n+
    807 typedef typename M::matrix_type Matrix;
    \n+
    808 typedef typename Matrix::ConstRowIterator RowIter;
    \n+
    809 typedef typename Matrix::ConstColIterator ColIter;
    \n+
    810 typedef typename Matrix::block_type Block;
    \n+
    811 Block zero;
    \n+
    812 zero=typename Matrix::field_type();
    \n+
    813
    \n+
    814 const Matrix& mat=matrices_->matrices().finest()->getmat();
    \n+
    815 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {
    \n+
    816 bool isDirichlet = true;
    \n+
    817 bool hasDiagonal = false;
    \n+
    818 Block diagonal{};
    \n+
    819 for(ColIter col=row->begin(); col!=row->end(); ++col) {
    \n+
    820 if(row.index()==col.index()) {
    \n+
    821 diagonal = *col;
    \n+
    822 hasDiagonal = true;
    \n+
    823 }else{
    \n+
    824 if(*col!=zero)
    \n+
    825 isDirichlet = false;
    \n+
    826 }
    \n+
    827 }
    \n+
    828 if(isDirichlet && hasDiagonal)
    \n+
    829 {
    \n+
    830 auto&& xEntry = Impl::asVector(x[row.index()]);
    \n+
    831 auto&& bEntry = Impl::asVector(b[row.index()]);
    \n+
    832 Impl::asMatrix(diagonal).solve(xEntry, bEntry);
    \n+
    833 }
    \n+
    834 }
    \n+
    835
    \n+
    836 if(smoothers_->levels()>0)
    \n+
    837 smoothers_->finest()->pre(x,b);
    \n+
    838 else
    \n+
    839 // No smoother to make x consistent! Do it by hand
    \n+
    840 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
    \n+
    841 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
    \n+
    842 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n+
    843 update_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
    \n+
    844 matrices_->coarsenVector(*rhs_);
    \n+
    845 matrices_->coarsenVector(*lhs_);
    \n+
    846 matrices_->coarsenVector(*update_);
    \n+
    847
    \n+
    848 // Preprocess all smoothers
    \n+
    849 typedef typename Hierarchy<Smoother,A>::Iterator Iterator;
    \n+
    850 typedef typename Hierarchy<Range,A>::Iterator RIterator;
    \n+
    851 typedef typename Hierarchy<Domain,A>::Iterator DIterator;
    \n+
    852 Iterator coarsest = smoothers_->coarsest();
    \n+
    853 Iterator smoother = smoothers_->finest();
    \n+
    854 RIterator rhs = rhs_->finest();
    \n+
    855 DIterator lhs = lhs_->finest();
    \n+
    856 if(smoothers_->levels()>1) {
    \n+
    857
    \n+
    858 assert(lhs_->levels()==rhs_->levels());
    \n+
    859 assert(smoothers_->levels()==lhs_->levels() || matrices_->levels()==matrices_->maxlevels());
    \n+
    860 assert(smoothers_->levels()+1==lhs_->levels() || matrices_->levels()<matrices_->maxlevels());
    \n+
    861
    \n+
    862 if(smoother!=coarsest)
    \n+
    863 for(++smoother, ++lhs, ++rhs; smoother != coarsest; ++smoother, ++lhs, ++rhs)
    \n+
    864 smoother->pre(*lhs,*rhs);
    \n+
    865 smoother->pre(*lhs,*rhs);
    \n+
    866 }
    \n+
    867
    \n+
    868
    \n+
    869 // The preconditioner might change x and b. So we have to
    \n+
    870 // copy the changes to the original vectors.
    \n+
    871 x = *lhs_->finest();
    \n+
    872 b = *rhs_->finest();
    \n+
    873
    \n+
    874 }
    \n+
    875 template<class M, class X, class S, class PI, class A>
    \n+\n+
    877 {
    \n+
    878 return matrices_->levels();
    \n+
    879 }
    \n+
    880 template<class M, class X, class S, class PI, class A>
    \n+\n+
    882 {
    \n+
    883 return matrices_->maxlevels();
    \n+
    884 }
    \n+
    885
    \n+
    887 template<class M, class X, class S, class PI, class A>
    \n+\n+
    889 {
    \n+
    890 LevelContext levelContext;
    \n+
    891
    \n+
    892 if(additive) {
    \n+
    893 *(rhs_->finest())=d;
    \n+
    894 additiveMgc();
    \n+
    895 v=*lhs_->finest();
    \n+
    896 }else{
    \n+
    897 // Init all iterators for the current level
    \n+
    898 initIteratorsWithFineLevel(levelContext);
    \n+
    899
    \n+
    900
    \n+
    901 *levelContext.lhs = v;
    \n+
    902 *levelContext.rhs = d;
    \n+
    903 *levelContext.update=0;
    \n+
    904 levelContext.level=0;
    \n+
    905
    \n+
    906 mgc(levelContext);
    \n+
    907
    \n+
    908 if(postSteps_==0||matrices_->maxlevels()==1)
    \n+
    909 levelContext.pinfo->copyOwnerToAll(*levelContext.update, *levelContext.update);
    \n+
    910
    \n+
    911 v=*levelContext.update;
    \n+
    912 }
    \n+
    913
    \n+
    914 }
    \n+
    915
    \n+
    916 template<class M, class X, class S, class PI, class A>
    \n+
    917 void AMG<M,X,S,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
    \n+
    918 {
    \n+
    919 levelContext.smoother = smoothers_->finest();
    \n+
    920 levelContext.matrix = matrices_->matrices().finest();
    \n+
    921 levelContext.pinfo = matrices_->parallelInformation().finest();
    \n+
    922 levelContext.redist =
    \n+
    923 matrices_->redistributeInformation().begin();
    \n+
    924 levelContext.aggregates = matrices_->aggregatesMaps().begin();
    \n+
    925 levelContext.lhs = lhs_->finest();
    \n+
    926 levelContext.update = update_->finest();
    \n+
    927 levelContext.rhs = rhs_->finest();
    \n+
    928 }
    \n+
    929
    \n+
    930 template<class M, class X, class S, class PI, class A>
    \n+
    931 bool AMG<M,X,S,PI,A>
    \n+
    932 ::moveToCoarseLevel(LevelContext& levelContext)
    \n+
    933 {
    \n+
    934
    \n+
    935 bool processNextLevel=true;
    \n+
    936
    \n+
    937 if(levelContext.redist->isSetup()) {
    \n+
    938 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.rhs),
    \n+
    939 levelContext.rhs.getRedistributed());
    \n+
    940 processNextLevel = levelContext.rhs.getRedistributed().size()>0;
    \n+
    941 if(processNextLevel) {
    \n+
    942 //restrict defect to coarse level right hand side.
    \n+
    943 typename Hierarchy<Range,A>::Iterator fineRhs = levelContext.rhs++;
    \n+
    944 ++levelContext.pinfo;
    \n+\n+
    946 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
    \n+
    947 static_cast<const Range&>(fineRhs.getRedistributed()),
    \n+
    948 *levelContext.pinfo);
    \n+
    949 }
    \n+
    950 }else{
    \n+
    951 //restrict defect to coarse level right hand side.
    \n+
    952 typename Hierarchy<Range,A>::Iterator fineRhs = levelContext.rhs++;
    \n+
    953 ++levelContext.pinfo;
    \n+\n+
    955 ::restrictVector(*(*levelContext.aggregates),
    \n+
    956 *levelContext.rhs, static_cast<const Range&>(*fineRhs),
    \n+
    957 *levelContext.pinfo);
    \n+
    958 }
    \n+
    959
    \n+
    960 if(processNextLevel) {
    \n+
    961 // prepare coarse system
    \n+
    962 ++levelContext.lhs;
    \n+
    963 ++levelContext.update;
    \n+
    964 ++levelContext.matrix;
    \n+
    965 ++levelContext.level;
    \n+
    966 ++levelContext.redist;
    \n+
    967
    \n+
    968 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n+
    969 // next level is not the globally coarsest one
    \n+
    970 ++levelContext.smoother;
    \n+
    971 ++levelContext.aggregates;
    \n+
    972 }
    \n+
    973 // prepare the update on the next level
    \n+
    974 *levelContext.update=0;
    \n+
    975 }
    \n+
    976 return processNextLevel;
    \n+
    977 }
    \n+
    978
    \n+
    979 template<class M, class X, class S, class PI, class A>
    \n+
    980 void AMG<M,X,S,PI,A>
    \n+
    981 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel)
    \n+
    982 {
    \n+
    983 if(processNextLevel) {
    \n+
    984 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
    \n+
    985 // previous level is not the globally coarsest one
    \n+
    986 --levelContext.smoother;
    \n+
    987 --levelContext.aggregates;
    \n+
    988 }
    \n+
    989 --levelContext.redist;
    \n+
    990 --levelContext.level;
    \n+
    991 //prolongate and add the correction (update is in coarse left hand side)
    \n+
    992 --levelContext.matrix;
    \n+
    993
    \n+
    994 //typename Hierarchy<Domain,A>::Iterator coarseLhs = lhs--;
    \n+
    995 --levelContext.lhs;
    \n+
    996 --levelContext.pinfo;
    \n+
    997 }
    \n+
    998 if(levelContext.redist->isSetup()) {
    \n+
    999 // Need to redistribute during prolongateVector
    \n+
    1000 levelContext.lhs.getRedistributed()=0;
    \n+\n+
    1002 ::prolongateVector(*(*levelContext.aggregates), *levelContext.update, *levelContext.lhs,
    \n+
    1003 levelContext.lhs.getRedistributed(),
    \n+
    1004 matrices_->getProlongationDampingFactor(),
    \n+
    1005 *levelContext.pinfo, *levelContext.redist);
    \n+
    1006 }else{
    \n+
    1007 *levelContext.lhs=0;
    \n+\n+
    1009 ::prolongateVector(*(*levelContext.aggregates), *levelContext.update, *levelContext.lhs,
    \n+
    1010 matrices_->getProlongationDampingFactor(),
    \n+
    1011 *levelContext.pinfo);
    \n+
    1012 }
    \n+
    1013
    \n+
    1014
    \n+
    1015 if(processNextLevel) {
    \n+
    1016 --levelContext.update;
    \n+
    1017 --levelContext.rhs;
    \n+
    1018 }
    \n+
    1019
    \n+
    1020 *levelContext.update += *levelContext.lhs;
    \n+
    1021 }
    \n+
    1022
    \n+
    1023 template<class M, class X, class S, class PI, class A>
    \n+\n+
    1025 {
    \n+\n+
    1027 }
    \n+
    1028
    \n+
    1029 template<class M, class X, class S, class PI, class A>
    \n+
    1030 void AMG<M,X,S,PI,A>::mgc(LevelContext& levelContext){
    \n+
    1031 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
    \n+
    1032 // Solve directly
    \n+\n+
    1034 res.converged=true; // If we do not compute this flag will not get updated
    \n+
    1035 if(levelContext.redist->isSetup()) {
    \n+
    1036 levelContext.redist->redistribute(*levelContext.rhs, levelContext.rhs.getRedistributed());
    \n+
    1037 if(levelContext.rhs.getRedistributed().size()>0) {
    \n+
    1038 // We are still participating in the computation
    \n+
    1039 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
    \n+
    1040 levelContext.rhs.getRedistributed());
    \n+
    1041 solver_->apply(levelContext.update.getRedistributed(),
    \n+
    1042 levelContext.rhs.getRedistributed(), res);
    \n+
    1043 }
    \n+
    1044 levelContext.redist->redistributeBackward(*levelContext.update, levelContext.update.getRedistributed());
    \n+
    1045 levelContext.pinfo->copyOwnerToAll(*levelContext.update, *levelContext.update);
    \n+
    1046 }else{
    \n+
    1047 levelContext.pinfo->copyOwnerToAll(*levelContext.rhs, *levelContext.rhs);
    \n+
    1048 solver_->apply(*levelContext.update, *levelContext.rhs, res);
    \n+
    1049 }
    \n+
    1050
    \n+
    1051 if (!res.converged)
    \n+
    1052 coarsesolverconverged = false;
    \n+
    1053 }else{
    \n+
    1054 // presmoothing
    \n+
    1055 presmooth(levelContext, preSteps_);
    \n+
    1056
    \n+
    1057#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n+
    1058 bool processNextLevel = moveToCoarseLevel(levelContext);
    \n+
    1059
    \n+
    1060 if(processNextLevel) {
    \n+
    1061 // next level
    \n+
    1062 for(std::size_t i=0; i<gamma_; i++){
    \n+
    1063 mgc(levelContext);
    \n+
    1064 if (levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels())
    \n+
    1065 break;
    \n+
    1066 if(i+1 < gamma_){
    \n+
    1067 levelContext.matrix->applyscaleadd(-1., *levelContext.lhs, *levelContext.rhs);
    \n+
    1068 }
    \n+
    1069 }
    \n+
    1070 }
    \n+
    1071
    \n+
    1072 moveToFineLevel(levelContext, processNextLevel);
    \n+
    1073#else
    \n+
    1074 *lhs=0;
    \n+
    1075#endif
    \n+
    1076
    \n+
    1077 if(levelContext.matrix == matrices_->matrices().finest()) {
    \n+
    1078 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
    \n+
    1079 if(!coarsesolverconverged)
    \n+
    1080 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n+
    1081 }
    \n+
    1082 // postsmoothing
    \n+
    1083 postsmooth(levelContext, postSteps_);
    \n+
    1084
    \n+
    1085 }
    \n+
    1086 }
    \n+
    1087
    \n+
    1088 template<class M, class X, class S, class PI, class A>
    \n+
    1089 void AMG<M,X,S,PI,A>::additiveMgc(){
    \n+
    1090
    \n+
    1091 // restrict residual to all levels
    \n+
    1092 typename ParallelInformationHierarchy::Iterator pinfo=matrices_->parallelInformation().finest();
    \n+
    1093 typename Hierarchy<Range,A>::Iterator rhs=rhs_->finest();
    \n+
    1094 typename Hierarchy<Domain,A>::Iterator lhs = lhs_->finest();
    \n+
    1095 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates=matrices_->aggregatesMaps().begin();
    \n+
    1096
    \n+
    1097 for(typename Hierarchy<Range,A>::Iterator fineRhs=rhs++; fineRhs != rhs_->coarsest(); fineRhs=rhs++, ++aggregates) {
    \n+
    1098 ++pinfo;
    \n+\n+
    1100 ::restrictVector(*(*aggregates), *rhs, static_cast<const Range&>(*fineRhs), *pinfo);
    \n+
    1101 }
    \n+
    1102
    \n+
    1103 // pinfo is invalid, set to coarsest level
    \n+
    1104 //pinfo = matrices_->parallelInformation().coarsest
    \n+
    1105 // calculate correction for all levels
    \n+
    1106 lhs = lhs_->finest();
    \n+
    1107 typename Hierarchy<Smoother,A>::Iterator smoother = smoothers_->finest();
    \n+
    1108
    \n+
    1109 for(rhs=rhs_->finest(); rhs != rhs_->coarsest(); ++lhs, ++rhs, ++smoother) {
    \n+
    1110 // presmoothing
    \n+
    1111 *lhs=0;
    \n+
    1112 smoother->apply(*lhs, *rhs);
    \n+
    1113 }
    \n+
    1114
    \n+
    1115 // Coarse level solve
    \n+
    1116#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
    \n+
    1117 InverseOperatorResult res;
    \n+
    1118 pinfo->copyOwnerToAll(*rhs, *rhs);
    \n+
    1119 solver_->apply(*lhs, *rhs, res);
    \n+
    1120
    \n+
    1121 if(!res.converged)
    \n+
    1122 DUNE_THROW(MathError, "Coarse solver did not converge");
    \n+
    1123#else
    \n+
    1124 *lhs=0;
    \n+
    1125#endif
    \n+
    1126 // Prologate and add up corrections from all levels
    \n+
    1127 --pinfo;
    \n+
    1128 --aggregates;
    \n+
    1129
    \n+
    1130 for(typename Hierarchy<Domain,A>::Iterator coarseLhs = lhs--; coarseLhs != lhs_->finest(); coarseLhs = lhs--, --aggregates, --pinfo) {
    \n+\n+
    1132 ::prolongateVector(*(*aggregates), *coarseLhs, *lhs, 1.0, *pinfo);
    \n+
    1133 }
    \n+
    1134 }
    \n+
    1135
    \n+
    1136
    \n+
    1138 template<class M, class X, class S, class PI, class A>
    \n+
    1139 void AMG<M,X,S,PI,A>::post([[maybe_unused]] Domain& x)
    \n+
    1140 {
    \n+
    1141 // Postprocess all smoothers
    \n+
    1142 typedef typename Hierarchy<Smoother,A>::Iterator Iterator;
    \n+
    1143 typedef typename Hierarchy<Domain,A>::Iterator DIterator;
    \n+
    1144 Iterator coarsest = smoothers_->coarsest();
    \n+
    1145 Iterator smoother = smoothers_->finest();
    \n+
    1146 DIterator lhs = lhs_->finest();
    \n+
    1147 if(smoothers_->levels()>0) {
    \n+
    1148 if(smoother != coarsest || matrices_->levels()<matrices_->maxlevels())
    \n+
    1149 smoother->post(*lhs);
    \n+
    1150 if(smoother!=coarsest)
    \n+
    1151 for(++smoother, ++lhs; smoother != coarsest; ++smoother, ++lhs)
    \n+
    1152 smoother->post(*lhs);
    \n+
    1153 smoother->post(*lhs);
    \n+
    1154 }
    \n+
    1155 lhs_ = nullptr;
    \n+
    1156 update_ = nullptr;
    \n+
    1157 rhs_ = nullptr;
    \n+
    1158 }
    \n+
    1159
    \n+
    1160 template<class M, class X, class S, class PI, class A>
    \n+
    1161 template<class A1>
    \n+
    1162 void AMG<M,X,S,PI,A>::getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont)
    \n+
    1163 {
    \n+
    1164 matrices_->getCoarsestAggregatesOnFinest(cont);
    \n+
    1165 }
    \n+
    1166
    \n+
    1167 } // end namespace Amg
    \n+
    1168
    \n+\n+
    1170 template<class> struct isValidBlockType : std::false_type{};
    \n+
    1171 template<class T, int n, int m> struct isValidBlockType<FieldMatrix<T,n,m>> : std::true_type{};
    \n+
    1172
    \n+
    1173 template<class OP>
    \n+
    1174 std::shared_ptr<Dune::Preconditioner<typename OP::element_type::domain_type, typename OP::element_type::range_type> >
    \n+
    1175 makeAMG(const OP& op, const std::string& smoother, const Dune::ParameterTree& config) const
    \n+
    1176 {
    \n+
    1177 DUNE_THROW(Dune::Exception, "Operator type not supported by AMG");
    \n+
    1178 }
    \n+
    1179
    \n+
    1180 template<class M, class X, class Y>
    \n+
    1181 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n+
    1182 makeAMG(const std::shared_ptr<MatrixAdapter<M,X,Y>>& op, const std::string& smoother,
    \n+
    1183 const Dune::ParameterTree& config) const
    \n+
    1184 {
    \n+
    1185 using OP = MatrixAdapter<M,X,Y>;
    \n+
    1186
    \n+
    1187 if(smoother == "ssor")
    \n+
    1188 return std::make_shared<Amg::AMG<OP, X, SeqSSOR<M,X,Y>>>(op, config);
    \n+
    1189 if(smoother == "sor")
    \n+
    1190 return std::make_shared<Amg::AMG<OP, X, SeqSOR<M,X,Y>>>(op, config);
    \n+
    1191 if(smoother == "jac")
    \n+
    1192 return std::make_shared<Amg::AMG<OP, X, SeqJac<M,X,Y>>>(op, config);
    \n+
    1193 if(smoother == "gs")
    \n+
    1194 return std::make_shared<Amg::AMG<OP, X, SeqGS<M,X,Y>>>(op, config);
    \n+
    1195 if(smoother == "ilu")
    \n+
    1196 return std::make_shared<Amg::AMG<OP, X, SeqILU<M,X,Y>>>(op, config);
    \n+
    1197 else
    \n+
    1198 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n+
    1199 }
    \n+
    1200
    \n+
    1201 template<class M, class X, class Y, class C>
    \n+
    1202 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n+
    1203 makeAMG(const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C>>& op, const std::string& smoother,
    \n+
    1204 const Dune::ParameterTree& config) const
    \n+
    1205 {
    \n+\n+
    1207
    \n+
    1208 auto cop = std::static_pointer_cast<const OP>(op);
    \n+
    1209
    \n+
    1210 if(smoother == "ssor")
    \n+
    1211 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqSSOR<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n+
    1212 if(smoother == "sor")
    \n+
    1213 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqSOR<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n+
    1214 if(smoother == "jac")
    \n+
    1215 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqJac<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n+
    1216 if(smoother == "gs")
    \n+
    1217 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqGS<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n+
    1218 if(smoother == "ilu")
    \n+
    1219 return std::make_shared<Amg::AMG<OP, X, BlockPreconditioner<X,Y,C,SeqILU<M,X,Y>>,C>>(cop, config, op->getCommunication());
    \n+
    1220 else
    \n+
    1221 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n+
    1222 }
    \n+
    1223
    \n+
    1224 template<class M, class X, class Y, class C>
    \n+
    1225 std::shared_ptr<Dune::Preconditioner<X,Y> >
    \n+
    1226 makeAMG(const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C>>& op, const std::string& smoother,
    \n+
    1227 const Dune::ParameterTree& config) const
    \n+
    1228 {
    \n+\n+
    1230
    \n+
    1231 if(smoother == "ssor")
    \n+
    1232 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqSSOR<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n+
    1233 if(smoother == "sor")
    \n+
    1234 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqSOR<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n+
    1235 if(smoother == "jac")
    \n+
    1236 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqJac<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n+
    1237 if(smoother == "gs")
    \n+
    1238 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqGS<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n+
    1239 if(smoother == "ilu")
    \n+
    1240 return std::make_shared<Amg::AMG<OP, X, NonoverlappingBlockPreconditioner<C,SeqILU<M,X,Y>>,C>>(op, config, op->getCommunication());
    \n+
    1241 else
    \n+
    1242 DUNE_THROW(Dune::Exception, "Unknown smoother for AMG");
    \n+
    1243 }
    \n+
    1244
    \n+
    1245 template<typename TL, typename OP>
    \n+
    1246 std::shared_ptr<Dune::Preconditioner<typename Dune::TypeListElement<1, TL>::type,
    \n+
    1247 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    1248 operator() (TL tl, const std::shared_ptr<OP>& op, const Dune::ParameterTree& config,
    \n+\n+
    1250 {
    \n+
    1251 using field_type = typename OP::matrix_type::field_type;
    \n+
    1252 using real_type = typename FieldTraits<field_type>::real_type;
    \n+
    1253 if (!std::is_convertible<field_type, real_type>())
    \n+
    1254 DUNE_THROW(UnsupportedType, "AMG needs field_type(" <<
    \n+
    1255 className<field_type>() <<
    \n+
    1256 ") to be convertible to its real_type (" <<
    \n+
    1257 className<real_type>() <<
    \n+
    1258 ").");
    \n+
    1259 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;
    \n+
    1260 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;
    \n+
    1261 std::shared_ptr<Preconditioner<D,R>> amg;
    \n+
    1262 std::string smoother = config.get("smoother", "ssor");
    \n+
    1263 return makeAMG(op, smoother, config);
    \n+
    1264 }
    \n+
    1265
    \n+
    1266 template<typename TL, typename OP>
    \n+
    1267 std::shared_ptr<Dune::Preconditioner<typename Dune::TypeListElement<1, TL>::type,
    \n+
    1268 typename Dune::TypeListElement<2, TL>::type>>
    \n+
    1269 operator() (TL /*tl*/, const std::shared_ptr<OP>& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n+\n+
    1271 {
    \n+
    1272 DUNE_THROW(UnsupportedType, "AMG needs a FieldMatrix as Matrix block_type");
    \n+
    1273 }
    \n+
    1274 };
    \n+
    1275
    \n+\n+
    1277} // end namespace Dune
    \n+
    1278
    \n+
    1279#endif
    \n+
    Classes for using SuperLU with ISTL matrices.
    \n+
    Define base class for scalar product and norm.
    \n+
    Templates characterizing the type of a solver.
    \n+
    Classes for using UMFPack with ISTL matrices.
    \n+
    Prolongation and restriction for amg.
    \n+
    Provides a classes representing the hierarchies in AMG.
    \n+
    Classes for the generic construction and application of the smoothers.
    \n+
    Implementations of the inverse operator interface.
    \n+
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    AMG(const AMG &amg)
    Copy constructor.
    Definition: amg.hh:392
    \n+
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: amg.hh:801
    \n+
    static DirectSolver * create(const Matrix &mat, bool verbose, bool reusevector)
    Definition: amg.hh:681
    \n+
    static std::string name()
    Definition: amg.hh:680
    \n+
    Hierarchy< Domain, A >::Iterator update
    The iterator over the updates.
    Definition: amg.hh:303
    \n+
    Hierarchy< Range, A >::Iterator rhs
    The iterator over the right hand sided.
    Definition: amg.hh:307
    \n+
    static std::string name()
    Definition: amg.hh:672
    \n+
    bool usesDirectCoarseLevelSolver() const
    Check whether the coarse solver used is a direct solver.
    Definition: amg.hh:1024
    \n+
    X Domain
    The domain type.
    Definition: amg.hh:87
    \n+
    static type * create(const M &mat, bool verbose, bool reusevector)
    Definition: amg.hh:644
    \n+
    AMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms)
    Construct a new amg with a specific coarse solver.
    Definition: amg.hh:406
    \n+
    AMG(std::shared_ptr< const Operator > fineOperator, const ParameterTree &configuration, const ParallelInformation &pinfo=ParallelInformation())
    Constructor an AMG via ParameterTree.
    Definition: amg.hh:452
    \n+
    ParallelInformationHierarchy::Iterator pinfo
    The iterator over the parallel information.
    Definition: amg.hh:287
    \n+
    SolverType
    Definition: amg.hh:627
    \n+
    OperatorHierarchy::AggregatesMapList::const_iterator aggregates
    The iterator over the aggregates maps.
    Definition: amg.hh:295
    \n+
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n+
    Solver< Matrix, solver > SelectedSolver
    Definition: amg.hh:677
    \n+
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< MatrixAdapter< M, X, Y > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1182
    \n+
    std::string operator()(const std::string &str)
    Definition: amg.hh:378
    \n+
    std::shared_ptr< Dune::Preconditioner< typename OP::element_type::domain_type, typename OP::element_type::range_type > > makeAMG(const OP &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1175
    \n+
    S Smoother
    The type of the smoother.
    Definition: amg.hh:97
    \n+
    static std::string name()
    Definition: amg.hh:649
    \n+
    Hierarchy< Smoother, A >::Iterator smoother
    The iterator over the smoothers.
    Definition: amg.hh:279
    \n+
    M Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n+
    OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
    The iterator over the matrices.
    Definition: amg.hh:283
    \n+\n+
    static type * create(const M &mat, bool verbose, bool reusevector)
    Definition: amg.hh:668
    \n+
    OperatorHierarchy::RedistributeInfoList::const_iterator redist
    The iterator over the redistribution information.
    Definition: amg.hh:291
    \n+
    X Range
    The range type.
    Definition: amg.hh:89
    \n+
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n+
    void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
    Get the aggregate number of each unknown on the coarsest level.
    Definition: amg.hh:1162
    \n+
    std::size_t levels()
    Definition: amg.hh:876
    \n+
    InverseOperator< Vector, Vector > type
    Definition: amg.hh:643
    \n+
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1203
    \n+
    Hierarchy< Domain, A >::Iterator lhs
    The iterator over the left hand side.
    Definition: amg.hh:299
    \n+
    const void * Arguments
    A type holding all the arguments needed to call the constructor.
    Definition: construction.hh:44
    \n+
    static constexpr SolverType solver
    Definition: amg.hh:629
    \n+
    static std::shared_ptr< T > construct(Arguments &args)
    Construct an object with the specified arguments.
    Definition: construction.hh:52
    \n+
    static constexpr bool isDirectSolver
    Definition: amg.hh:679
    \n+
    void recalculateHierarchy()
    Recalculate the matrix hierarchy.
    Definition: amg.hh:221
    \n+
    Iterator coarsest()
    Get an iterator positioned at the coarsest level.
    Definition: hierarchy.hh:383
    \n+
    Matrix::field_type field_type
    Definition: amg.hh:626
    \n+
    SelectedSolver::type DirectSolver
    Definition: amg.hh:678
    \n+
    std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL tl, const std::shared_ptr< OP > &op, const Dune::ParameterTree &config, std::enable_if_t< isValidBlockType< typename OP::matrix_type::block_type >::value, int >=0) const
    Definition: amg.hh:1248
    \n+
    OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
    The parallal data distribution hierarchy type.
    Definition: amg.hh:84
    \n+
    InverseOperator< X, X > CoarseSolver
    the type of the coarse solver.
    Definition: amg.hh:91
    \n+
    void post(Domain &x)
    Clean up.
    Definition: amg.hh:1139
    \n+
    std::size_t maxlevels()
    Definition: amg.hh:881
    \n+
    std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother, const Dune::ParameterTree &config) const
    Definition: amg.hh:1226
    \n+
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n+
    std::size_t level
    The level index.
    Definition: amg.hh:311
    \n+
    AMG(const Operator &fineOperator, const C &criterion, const SmootherArgs &smootherArgs=SmootherArgs(), const ParallelInformation &pinfo=ParallelInformation())
    Construct an AMG with an inexact coarse solver based on the smoother.
    Definition: amg.hh:428
    \n+
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: amg.hh:888
    \n+
    Smoother SmootherType
    Definition: amg.hh:275
    \n+
    MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
    The operator hierarchy type.
    Definition: amg.hh:82
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: amg.hh:194
    \n+
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: amg.hh:80
    \n+
    @ none
    Definition: amg.hh:627
    \n+
    @ umfpack
    Definition: amg.hh:627
    \n+
    @ superlu
    Definition: amg.hh:627
    \n+
    @ atOnceAccu
    Accumulate data to one process at once.
    Definition: parameters.hh:244
    \n+
    @ noAccu
    No data accumulution.
    Definition: parameters.hh:238
    \n+
    @ successiveAccu
    Successively accumulate to fewer processes.
    Definition: parameters.hh:248
    \n
    Definition: allocator.hh:11
    \n-
    Stores the nonzero entries in a sparse matrix.
    Definition: matrixindexset.hh:16
    \n-
    void resize(size_type rows, size_type cols)
    Reset the size of an index set.
    Definition: matrixindexset.hh:31
    \n-
    MatrixIndexSet()
    Default constructor.
    Definition: matrixindexset.hh:22
    \n-
    void add(size_type i, size_type j)
    Add an index to the index set.
    Definition: matrixindexset.hh:38
    \n-
    size_type rows() const
    Return the number of rows.
    Definition: matrixindexset.hh:52
    \n-
    std::size_t size_type
    Definition: matrixindexset.hh:19
    \n-
    void exportIdx(MatrixType &matrix) const
    Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.
    Definition: matrixindexset.hh:90
    \n-
    MatrixIndexSet(size_type rows, size_type cols)
    Constructor setting the matrix size.
    Definition: matrixindexset.hh:26
    \n-
    size_type rowsize(size_type row) const
    Return the number of entries in a given row.
    Definition: matrixindexset.hh:56
    \n-
    size_type size() const
    Return the number of entries.
    Definition: matrixindexset.hh:43
    \n+
    DUNE_REGISTER_PRECONDITIONER("amg", AMGCreator())
    \n+
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n+
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n+
    typename Imp::BlockTraits< T >::field_type field_type
    Export the type representing the underlying field.
    Definition: matrix.hh:565
    \n+
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n+
    Definition: matrixutils.hh:27
    \n+
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n+
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n+\n+
    Functor using the row sum (infinity) norm to determine strong couplings.
    Definition: aggregates.hh:463
    \n+
    Definition: aggregates.hh:480
    \n+
    Definition: aggregates.hh:496
    \n+
    Criterion taking advantage of symmetric matrices.
    Definition: aggregates.hh:519
    \n+
    Criterion suitable for unsymmetric matrices.
    Definition: aggregates.hh:539
    \n+
    an algebraic multigrid method using a Krylov-cycle.
    Definition: kamg.hh:140
    \n+
    Two grid operator for AMG with Krylov cycle.
    Definition: kamg.hh:33
    \n+
    Parallel algebraic multigrid based on agglomeration.
    Definition: amg.hh:65
    \n+
    Definition: amg.hh:625
    \n+\n+
    Definition: amg.hh:1169
    \n+
    Definition: amg.hh:1170
    \n+
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n+\n+
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n+
    LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
    Type of the const iterator.
    Definition: hierarchy.hh:219
    \n+
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n+
    The criterion describing the stop criteria for the coarsening process.
    Definition: matrixhierarchy.hh:283
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Definition: pinfo.hh:28
    \n+
    Traits class for getting the attribute class of a smoother.
    Definition: smoother.hh:66
    \n+
    static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, const Vector &fine, T &comm)
    \n+
    static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector &coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioner.hh:39
    \n+
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n+\n+
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    Definition: solvercategory.hh:54
    \n+
    Definition: solverregistry.hh:77
    \n+
    Definition: solvertype.hh:16
    \n+
    SuperLu Solver.
    Definition: superlu.hh:271
    \n+
    Definition: umfpack.hh:49
    \n+
    The UMFPack direct sparse solver.
    Definition: umfpack.hh:215
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,158 +4,1609 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-matrixindexset.hh\n+ * paamg\n+amg.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_MATRIXINDEXSET_HH\n- 6#define DUNE_ISTL_MATRIXINDEXSET_HH\n+ 5#ifndef DUNE_AMG_AMG_HH\n+ 6#define DUNE_AMG_AMG_HH\n 7\n- 8#include \n- 9#include \n- 10\n- 11namespace Dune {\n- 12\n- 13\n-15 class MatrixIndexSet\n- 16 {\n- 17\n- 18 public:\n-19 typedef std::size_t size_type;\n- 20\n-22 MatrixIndexSet() : rows_(0), cols_(0)\n- 23 {}\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14#include \n+ 15#include \n+ 16#include \n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23#include \n 24\n-26 MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) {\n- 27 indices_.resize(rows_);\n- 28 }\n- 29\n-31 void resize(size_type rows, size_type cols) {\n- 32 rows_ = rows;\n- 33 cols_ = cols;\n- 34 indices_.resize(rows_);\n- 35 }\n- 36\n-38 void add(size_type i, size_type j) {\n- 39 indices_[i].insert(j);\n- 40 }\n- 41\n-43 size_type size() const {\n- 44 size_type entries = 0;\n- 45 for (size_type i=0; i\n-65 void import(const MatrixType& m, size_type rowOffset=0, size_type\n-colOffset=0) {\n- 66\n- 67 typedef typename MatrixType::row_type RowType;\n- 68 typedef typename RowType::ConstIterator ColumnIterator;\n- 69\n- 70 for (size_type rowIdx=0; rowIdx\n-90 void exportIdx(MatrixType& matrix) const {\n- 91\n- 92 matrix.setSize(rows_, cols_);\n- 93 matrix.setBuildMode(MatrixType::random);\n- 94\n- 95 for (size_type i=0; i\n+ 47 class KAMG;\n+ 48\n+ 49 template\n+ 50 class KAmgTwoGrid;\n+ 51\n+ 62 template >\n+64 class AMG : public Preconditioner\n+ 65 {\n+ 66 template\n+67 friend class KAMG;\n+ 68\n+ 69 friend class KAmgTwoGrid;\n+ 70\n+ 71 public:\n+73 typedef M Operator;\n+80 typedef PI ParallelInformation;\n+82 typedef MatrixHierarchy OperatorHierarchy;\n+84 typedef typename OperatorHierarchy::ParallelInformationHierarchy\n+ParallelInformationHierarchy;\n+ 85\n+87 typedef X Domain;\n+89 typedef X Range;\n+91 typedef InverseOperator CoarseSolver;\n+97 typedef S Smoother;\n+ 98\n+100 typedef typename SmootherTraits::Arguments SmootherArgs;\n 101\n- 102 typename std::set::iterator it = indices_[i].begin();\n- 103 for (; it!=indices_[i].end(); ++it)\n- 104 matrix.addindex(i, *it);\n- 105\n- 106 }\n- 107\n- 108 matrix.endindices();\n- 109\n- 110 }\n- 111\n- 112 private:\n+111 AMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n+ 112 const SmootherArgs& smootherArgs, const Parameters& parms);\n 113\n- 114 std::vector > indices_;\n- 115\n- 116 size_type rows_, cols_;\n- 117\n- 118 };\n- 119\n- 120\n- 121} // end namespace Dune\n- 122\n- 123#endif\n+ 125 template\n+126 AMG(const Operator& fineOperator, const C& criterion,\n+ 127 const SmootherArgs& smootherArgs=SmootherArgs(),\n+ 128 const ParallelInformation& pinfo=ParallelInformation());\n+ 129\n+180 AMG(std::shared_ptr fineOperator, const ParameterTree&\n+configuration, const ParallelInformation& pinfo=ParallelInformation());\n+ 181\n+185 AMG(const AMG& amg);\n+ 186\n+188 void pre(Domain& x, Range& b);\n+ 189\n+191 void apply(Domain& v, const Range& d);\n+ 192\n+194 virtual SolverCategory::Category category() const\n+ 195 {\n+ 196 return category_;\n+ 197 }\n+ 198\n+200 void post(Domain& x);\n+ 201\n+ 206 template\n+207 void getCoarsestAggregateNumbers(std::vector& cont);\n+ 208\n+209 std::size_t levels();\n+ 210\n+211 std::size_t maxlevels();\n+ 212\n+221 void recalculateHierarchy()\n+ 222 {\n+ 223 matrices_->recalculateGalerkin(NegateSet());\n+ 224 }\n+ 225\n+230 bool usesDirectCoarseLevelSolver() const;\n+ 231\n+ 232 private:\n+ 233 /*\n+ 234 * @brief Helper function to create hierarchies with parameter tree.\n+ 235 *\n+ 236 * Will create the coarsen criterion with the norm and create the\n+ 237 * Hierarchies\n+ 238 * \\tparam Norm Type of the norm to use.\n+ 239 */\n+ 240 template\n+ 241 void createCriterionAndHierarchies(std::shared_ptr\n+matrixptr,\n+ 242 const PI& pinfo, const Norm&,\n+ 243 const ParameterTree& configuration,\n+ 244 std::true_type compiles = std::true_type());\n+ 245 template\n+ 246 void createCriterionAndHierarchies(std::shared_ptr\n+matrixptr,\n+ 247 const PI& pinfo, const Norm&,\n+ 248 const ParameterTree& configuration,\n+ 249 std::false_type);\n+ 254 template\n+ 255 void createHierarchies(C& criterion, std::shared_ptr\n+matrixptr,\n+ 256 const PI& pinfo, const ParameterTree& configuration);\n+ 263 template\n+ 264 void createHierarchies(C& criterion,\n+ 265 const std::shared_ptr& matrixptr,\n+ 266 const PI& pinfo);\n+ 273 struct LevelContext\n+ 274 {\n+275 typedef Smoother SmootherType;\n+279 typename Hierarchy::Iterator smoother;\n+283 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix;\n+287 typename ParallelInformationHierarchy::Iterator pinfo;\n+291 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;\n+295 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;\n+299 typename Hierarchy::Iterator lhs;\n+303 typename Hierarchy::Iterator update;\n+307 typename Hierarchy::Iterator rhs;\n+311 std::size_t level;\n+ 312 };\n+ 313\n+ 314\n+ 319 void mgc(LevelContext& levelContext);\n+ 320\n+ 321 void additiveMgc();\n+ 322\n+ 329 void moveToFineLevel(LevelContext& levelContext,bool processedFineLevel);\n+ 330\n+ 335 bool moveToCoarseLevel(LevelContext& levelContext);\n+ 336\n+ 341 void initIteratorsWithFineLevel(LevelContext& levelContext);\n+ 342\n+ 344 std::shared_ptr matrices_;\n+ 346 SmootherArgs smootherArgs_;\n+ 348 std::shared_ptr > smoothers_;\n+ 350 std::shared_ptr solver_;\n+ 352 std::shared_ptr> rhs_;\n+ 354 std::shared_ptr> lhs_;\n+ 356 std::shared_ptr> update_;\n+ 358 using ScalarProduct = Dune::ScalarProduct;\n+ 360 std::shared_ptr scalarProduct_;\n+ 362 std::size_t gamma_;\n+ 364 std::size_t preSteps_;\n+ 366 std::size_t postSteps_;\n+ 367 bool buildHierarchy_;\n+ 368 bool additive;\n+ 369 bool coarsesolverconverged;\n+ 370 std::shared_ptr coarseSmoother_;\n+ 372 SolverCategory::Category category_;\n+ 374 std::size_t verbosity_;\n+ 375\n+ 376 struct ToLower\n+ 377 {\n+378 std::string operator()(const std::string& str)\n+ 379 {\n+ 380 std::stringstream retval;\n+ 381 std::ostream_iterator out(retval);\n+ 382 std::transform(str.begin(), str.end(), out,\n+ 383 [](char c){\n+ 384 return std::tolower(c, std::locale::classic());\n+ 385 });\n+ 386 return retval.str();\n+ 387 }\n+ 388 };\n+ 389 };\n+ 390\n+ 391 template\n+392 inline AMG::AMG(const AMG& amg)\n+ 393 : matrices_(amg.matrices_), smootherArgs_(amg.smootherArgs_),\n+ 394 smoothers_(amg.smoothers_), solver_(amg.solver_),\n+ 395 rhs_(), lhs_(), update_(),\n+ 396 scalarProduct_(amg.scalarProduct_), gamma_(amg.gamma_),\n+ 397 preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),\n+ 398 buildHierarchy_(amg.buildHierarchy_),\n+ 399 additive(amg.additive), coarsesolverconverged(amg.coarsesolverconverged),\n+ 400 coarseSmoother_(amg.coarseSmoother_),\n+ 401 category_(amg.category_),\n+ 402 verbosity_(amg.verbosity_)\n+ 403 {}\n+ 404\n+ 405 template\n+406 AMG::AMG(OperatorHierarchy& matrices, CoarseSolver&\n+coarseSolver,\n+ 407 const SmootherArgs& smootherArgs,\n+ 408 const Parameters& parms)\n+ 409 : matrices_(stackobject_to_shared_ptr(matrices)), smootherArgs_\n+(smootherArgs),\n+ 410 smoothers_(new Hierarchy), solver_(&coarseSolver),\n+ 411 rhs_(), lhs_(), update_(), scalarProduct_(0),\n+ 412 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),\n+ 413 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),\n+ 414 additive(parms.getAdditive()), coarsesolverconverged(true),\n+ 415 coarseSmoother_(),\n+ 416// #warning should category be retrieved from matrices?\n+ 417 category_(SolverCategory::category(*smoothers_->coarsest())),\n+ 418 verbosity_(parms.debugLevel())\n+ 419 {\n+ 420 assert(matrices_->isBuilt());\n+ 421\n+ 422 // build the necessary smoother hierarchies\n+ 423 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);\n+ 424 }\n+ 425\n+ 426 template\n+ 427 template\n+428 AMG::AMG(const Operator& matrix,\n+ 429 const C& criterion,\n+ 430 const SmootherArgs& smootherArgs,\n+ 431 const PI& pinfo)\n+ 432 : smootherArgs_(smootherArgs),\n+ 433 smoothers_(new Hierarchy), solver_(),\n+ 434 rhs_(), lhs_(), update_(), scalarProduct_(),\n+ 435 gamma_(criterion.getGamma()), preSteps_(criterion.getNoPreSmoothSteps()),\n+ 436 postSteps_(criterion.getNoPostSmoothSteps()), buildHierarchy_(true),\n+ 437 additive(criterion.getAdditive()), coarsesolverconverged(true),\n+ 438 coarseSmoother_(),\n+ 439 category_(SolverCategory::category(pinfo)),\n+ 440 verbosity_(criterion.debugLevel())\n+ 441 {\n+ 442 if(SolverCategory::category(matrix) != SolverCategory::category(pinfo))\n+ 443 DUNE_THROW(InvalidSolverCategory, \"Matrix and Communication must have the\n+same SolverCategory!\");\n+ 444 // TODO: reestablish compile time checks.\n+ 445 //static_assert(static_cast(PI::category)==static_cast(S::\n+category),\n+ 446 // \"Matrix and Solver must match in terms of category!\");\n+ 447 auto matrixptr = stackobject_to_shared_ptr(matrix);\n+ 448 createHierarchies(criterion, matrixptr, pinfo);\n+ 449 }\n+ 450\n+ 451 template\n+452 AMG::AMG(std::shared_ptr matrixptr,\n+ 453 const ParameterTree& configuration,\n+ 454 const ParallelInformation& pinfo) :\n+ 455 smoothers_(new Hierarchy),\n+ 456 solver_(), rhs_(), lhs_(), update_(), scalarProduct_(), buildHierarchy_\n+(true),\n+ 457 coarsesolverconverged(true), coarseSmoother_(),\n+ 458 category_(SolverCategory::category(pinfo))\n+ 459 {\n+ 460\n+ 461 if (configuration.hasKey (\"smootherIterations\"))\n+ 462 smootherArgs_.iterations = configuration.get(\"smootherIterations\");\n+ 463\n+ 464 if (configuration.hasKey (\"smootherRelaxation\"))\n+ 465 smootherArgs_.relaxationFactor = configuration.get(\"smootherRelaxation\");\n+ 466\n+ 467 auto normName = ToLower()(configuration.get(\"strengthMeasure\",\n+\"diagonal\"));\n+ 468 auto index = configuration.get(\"diagonalRowIndex\", 0);\n+ 469\n+ 470 if ( normName == \"diagonal\")\n+ 471 {\n+ 472 using field_type = typename M::field_type;\n+ 473 using real_type = typename FieldTraits::real_type;\n+ 474 std::is_convertible compiles;\n+ 475\n+ 476 switch (index)\n+ 477 {\n+ 478 case 0:\n+ 479 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<0>(),\n+configuration, compiles);\n+ 480 break;\n+ 481 case 1:\n+ 482 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<1>(),\n+configuration, compiles);\n+ 483 break;\n+ 484 case 2:\n+ 485 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<2>(),\n+configuration, compiles);\n+ 486 break;\n+ 487 case 3:\n+ 488 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<3>(),\n+configuration, compiles);\n+ 489 break;\n+ 490 case 4:\n+ 491 createCriterionAndHierarchies(matrixptr, pinfo, Diagonal<4>(),\n+configuration, compiles);\n+ 492 break;\n+ 493 default:\n+ 494 DUNE_THROW(InvalidStateException, \"Currently strengthIndex>4 is not\n+supported.\");\n+ 495 }\n+ 496 }\n+ 497 else if (normName == \"rowsum\")\n+ 498 createCriterionAndHierarchies(matrixptr, pinfo, RowSum(), configuration);\n+ 499 else if (normName == \"frobenius\")\n+ 500 createCriterionAndHierarchies(matrixptr, pinfo, FrobeniusNorm(),\n+configuration);\n+ 501 else if (normName == \"one\")\n+ 502 createCriterionAndHierarchies(matrixptr, pinfo, AlwaysOneNorm(),\n+configuration);\n+ 503 else\n+ 504 DUNE_THROW(Dune::NotImplemented, \"Wrong config file: strengthMeasure\n+\"<\n+ 508 template\n+ 509 void AMG::createCriterionAndHierarchies(std::shared_ptr matrixptr, const PI& pinfo, const Norm&, const ParameterTree&\n+configuration, std::false_type)\n+ 510 {\n+ 511 DUNE_THROW(InvalidStateException, \"Strength of connection measure does not\n+support this type (\"\n+ 512 << className() << \") as it is lacking a conversion\n+to\"\n+ 513 << className::real_type>() <<\n+\".\");\n+ 514 }\n+ 515\n+ 516 template\n+ 517 template\n+ 518 void AMG::createCriterionAndHierarchies(std::shared_ptr matrixptr, const PI& pinfo, const Norm&, const ParameterTree&\n+configuration, std::true_type)\n+ 519 {\n+ 520 if (configuration.get(\"criterionSymmetric\", true))\n+ 521 {\n+ 522 using Criterion = Dune::Amg::CoarsenCriterion<\n+ 523 Dune::Amg::SymmetricCriterion >;\n+ 524 Criterion criterion;\n+ 525 createHierarchies(criterion, matrixptr, pinfo, configuration);\n+ 526 }\n+ 527 else\n+ 528 {\n+ 529 using Criterion = Dune::Amg::CoarsenCriterion<\n+ 530 Dune::Amg::UnSymmetricCriterion >;\n+ 531 Criterion criterion;\n+ 532 createHierarchies(criterion, matrixptr, pinfo, configuration);\n+ 533 }\n+ 534 }\n+ 535\n+ 536 template\n+ 537 template\n+ 538 void AMG::createHierarchies(C& criterion, std::\n+shared_ptr matrixptr, const PI& pinfo, const ParameterTree&\n+configuration)\n+ 539 {\n+ 540 if (configuration.hasKey (\"maxLevel\"))\n+ 541 criterion.setMaxLevel(configuration.get(\"maxLevel\"));\n+ 542\n+ 543 if (configuration.hasKey (\"minCoarseningRate\"))\n+ 544 criterion.setMinCoarsenRate(configuration.get(\"minCoarseningRate\"));\n+ 545\n+ 546 if (configuration.hasKey (\"coarsenTarget\"))\n+ 547 criterion.setCoarsenTarget (configuration.get(\"coarsenTarget\"));\n+ 548\n+ 549 if (configuration.hasKey (\"accumulationMode\"))\n+ 550 {\n+ 551 std::string mode = ToLower()(configuration.get\n+(\"accumulationMode\"));\n+ 552 if ( mode == \"none\")\n+ 553 criterion.setAccumulate(AccumulationMode::noAccu);\n+ 554 else if ( mode == \"atonce\" )\n+ 555 criterion.setAccumulate(AccumulationMode::atOnceAccu);\n+ 556 else if ( mode == \"successive\")\n+ 557 criterion.setCoarsenTarget (AccumulationMode::successiveAccu);\n+ 558 else\n+ 559 DUNE_THROW(InvalidSolverFactoryConfiguration, \"Parameter accumulationMode\n+does not allow value \"\n+ 560 << mode <<\".\");\n+ 561 }\n+ 562\n+ 563 if (configuration.hasKey (\"prolongationDampingFactor\"))\n+ 564 criterion.setProlongationDampingFactor (configuration.get\n+(\"prolongationDampingFactor\"));\n+ 565\n+ 566 if (configuration.hasKey(\"defaultAggregationSizeMode\"))\n+ 567 {\n+ 568 auto mode = ToLower()(configuration.get\n+(\"defaultAggregationSizeMode\"));\n+ 569 auto dim = configuration.get(\"defaultAggregationDimension\");\n+ 570 std::size_t maxDistance = 2;\n+ 571 if (configuration.hasKey(\"MaxAggregateDistance\"))\n+ 572 maxDistance = configuration.get(\"maxAggregateDistance\");\n+ 573 if (mode == \"isotropic\")\n+ 574 criterion.setDefaultValuesIsotropic(dim, maxDistance);\n+ 575 else if(mode == \"anisotropic\")\n+ 576 criterion.setDefaultValuesAnisotropic(dim, maxDistance);\n+ 577 else\n+ 578 DUNE_THROW(InvalidSolverFactoryConfiguration, \"Parameter accumulationMode\n+does not allow value \"\n+ 579 << mode <<\".\");\n+ 580 }\n+ 581\n+ 582 if (configuration.hasKey(\"maxAggregateDistance\"))\n+ 583 criterion.setMaxDistance(configuration.get\n+(\"maxAggregateDistance\"));\n+ 584\n+ 585 if (configuration.hasKey(\"minAggregateSize\"))\n+ 586 criterion.setMinAggregateSize(configuration.get\n+(\"minAggregateSize\"));\n+ 587\n+ 588 if (configuration.hasKey(\"maxAggregateSize\"))\n+ 589 criterion.setMaxAggregateSize(configuration.get\n+(\"maxAggregateSize\"));\n+ 590\n+ 591 if (configuration.hasKey(\"maxAggregateConnectivity\"))\n+ 592 criterion.setMaxConnectivity(configuration.get\n+(\"maxAggregateConnectivity\"));\n+ 593\n+ 594 if (configuration.hasKey (\"alpha\"))\n+ 595 criterion.setAlpha (configuration.get (\"alpha\"));\n+ 596\n+ 597 if (configuration.hasKey (\"beta\"))\n+ 598 criterion.setBeta (configuration.get (\"beta\"));\n+ 599\n+ 600 if (configuration.hasKey (\"gamma\"))\n+ 601 criterion.setGamma (configuration.get (\"gamma\"));\n+ 602 gamma_ = criterion.getGamma();\n+ 603\n+ 604 if (configuration.hasKey (\"additive\"))\n+ 605 criterion.setAdditive (configuration.get(\"additive\"));\n+ 606 additive = criterion.getAdditive();\n+ 607\n+ 608 if (configuration.hasKey (\"preSteps\"))\n+ 609 criterion.setNoPreSmoothSteps (configuration.get\n+(\"preSteps\"));\n+ 610 preSteps_ = criterion.getNoPreSmoothSteps ();\n+ 611\n+ 612 if (configuration.hasKey (\"postSteps\"))\n+ 613 criterion.setNoPostSmoothSteps (configuration.get\n+(\"postSteps\"));\n+ 614 postSteps_ = criterion.getNoPostSmoothSteps ();\n+ 615\n+ 616 verbosity_ = configuration.get(\"verbosity\", 0);\n+ 617 criterion.setDebugLevel (verbosity_);\n+ 618\n+ 619 createHierarchies(criterion, matrixptr, pinfo);\n+ 620 }\n+ 621\n+ 622 template \n+624 struct DirectSolverSelector\n+ 625 {\n+626 typedef typename Matrix_::_field_type field_type;\n+627 enum SolverType { umfpack, superlu, none };\n+ 628\n+629 static constexpr SolverType solver =\n+ 630#if DISABLE_AMG_DIRECTSOLVER\n+ 631 none;\n+ 632#elif HAVE_SUITESPARSE_UMFPACK\n+ 633 UMFPackMethodChooser<_field_type_> :: valid ? umfpack : none ;\n+ 634#elif HAVE_SUPERLU\n+ 635 superlu ;\n+ 636#else\n+ 637 none;\n+ 638#endif\n+ 639\n+ 640 template \n+641 struct Solver\n+ 642 {\n+643 typedef InverseOperator type;\n+644 static type* create(const M& mat, bool verbose, bool reusevector )\n+ 645 {\n+ 646 DUNE_THROW(NotImplemented,\"DirectSolver not selected\");\n+ 647 return nullptr;\n+ 648 }\n+649 static std::string name () { return \"None\"; }\n+ 650 };\n+ 651#if HAVE_SUITESPARSE_UMFPACK\n+ 652 template \n+ 653 struct Solver< M, umfpack >\n+ 654 {\n+ 655 typedef UMFPack<_M_> type;\n+ 656 static type* create(const M& mat, bool verbose, bool reusevector )\n+ 657 {\n+ 658 return new type(mat, verbose, reusevector );\n+ 659 }\n+ 660 static std::string name () { return \"UMFPack\"; }\n+ 661 };\n+ 662#endif\n+ 663#if HAVE_SUPERLU\n+ 664 template \n+665 struct Solver< M, superlu >\n+ 666 {\n+667 typedef SuperLU<_M_> type;\n+668 static type* create(const M& mat, bool verbose, bool reusevector )\n+ 669 {\n+ 670 return new type(mat, verbose, reusevector );\n+ 671 }\n+672 static std::string name () { return \"SuperLU\"; }\n+ 673 };\n+ 674#endif\n+ 675\n+ 676 // define direct solver type to be used\n+677 typedef Solver<_Matrix,_solver_> SelectedSolver ;\n+678 typedef typename SelectedSolver_::_type DirectSolver;\n+679 static constexpr bool isDirectSolver = solver != none;\n+680 static std::string name() { return SelectedSolver_::_name (); }\n+681 static DirectSolver* create(const Matrix& mat, bool verbose, bool\n+reusevector )\n+ 682 {\n+ 683 return SelectedSolver_::_create( mat, verbose, reusevector );\n+ 684 }\n+ 685 };\n+ 686\n+ 687 template\n+ 688 template\n+ 689 void AMG::createHierarchies(C& criterion,\n+ 690 const std::shared_ptr& matrixptr,\n+ 691 const PI& pinfo)\n+ 692 {\n+ 693 Timer watch;\n+ 694 matrices_ = std::make_shared(\n+ 695 std::const_pointer_cast(matrixptr),\n+ 696 stackobject_to_shared_ptr(const_cast(pinfo)));\n+ 697\n+ 698 matrices_->template build >(criterion);\n+ 699\n+ 700 // build the necessary smoother hierarchies\n+ 701 matrices_->coarsenSmoother(*smoothers_, smootherArgs_);\n+ 702\n+ 703 // test whether we should solve on the coarse level. That is the case if\n+we\n+ 704 // have that level and if there was a redistribution on this level then\n+our\n+ 705 // communicator has to be valid (size()>0) as the smoother might try to\n+communicate\n+ 706 // in the constructor.\n+ 707 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()\n+ 708 && ( ! matrices_->redistributeInformation().back().isSetup() ||\n+ 709 matrices_->parallelInformation().coarsest().getRedistributed\n+().communicator().size() ) )\n+ 710 {\n+ 711 // We have the carsest level. Create the coarse Solver\n+ 712 SmootherArgs sargs(smootherArgs_);\n+ 713 sargs.iterations = 1;\n+ 714\n+ 715 typename ConstructionTraits::Arguments cargs;\n+ 716 cargs.setArgs(sargs);\n+ 717 if(matrices_->redistributeInformation().back().isSetup()) {\n+ 718 // Solve on the redistributed partitioning\n+ 719 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat\n+());\n+ 720 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed\n+());\n+ 721 }else{\n+ 722 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());\n+ 723 cargs.setComm(*matrices_->parallelInformation().coarsest());\n+ 724 }\n+ 725\n+ 726 coarseSmoother_ = ConstructionTraits::construct(cargs);\n+ 727 scalarProduct_ = createScalarProduct(cargs.getComm(),category());\n+ 728\n+ 729 typedef DirectSolverSelector< typename M::matrix_type, X > SolverSelector;\n+ 730\n+ 731 // Use superlu if we are purely sequential or with only one processor on\n+the coarsest level.\n+ 732 if( SolverSelector::isDirectSolver &&\n+ 733 (std::is_same::value /\n+/ sequential mode\n+ 734 || matrices_->parallelInformation().coarsest()->communicator().size()==1 /\n+/parallel mode and only one processor\n+ 735 || (matrices_->parallelInformation().coarsest().isRedistributed()\n+ 736 && matrices_->parallelInformation().coarsest().getRedistributed\n+().communicator().size()==1\n+ 737 && matrices_->parallelInformation().coarsest().getRedistributed\n+().communicator().size()>0) )\n+ 738 )\n+ 739 { // redistribute and 1 proc\n+ 740 if(matrices_->parallelInformation().coarsest().isRedistributed())\n+ 741 {\n+ 742 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n+ 743 {\n+ 744 // We are still participating on this level\n+ 745 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest\n+().getRedistributed().getmat(), false, false));\n+ 746 }\n+ 747 else\n+ 748 solver_.reset();\n+ 749 }\n+ 750 else\n+ 751 {\n+ 752 solver_.reset(SolverSelector::create(matrices_->matrices().coarsest()-\n+>getmat(), false, false));\n+ 753 }\n+ 754 if(verbosity_>0 && matrices_->parallelInformation().coarsest()-\n+>communicator().rank()==0)\n+ 755 std::cout<< \"Using a direct coarse solver (\" << SolverSelector::name() <<\n+\")\" << std::endl;\n+ 756 }\n+ 757 else\n+ 758 {\n+ 759 if(matrices_->parallelInformation().coarsest().isRedistributed())\n+ 760 {\n+ 761 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)\n+ 762 // We are still participating on this level\n+ 763\n+ 764 // we have to allocate these types using the rebound allocator\n+ 765 // in order to ensure that we fulfill the alignment requirements\n+ 766 solver_.reset(new BiCGSTABSolver(const_cast(matrices_->matrices\n+().coarsest().getRedistributed()),\n+ 767 *scalarProduct_,\n+ 768 *coarseSmoother_, 1E-2, 1000, 0));\n+ 769 else\n+ 770 solver_.reset();\n+ 771 }else\n+ 772 {\n+ 773 solver_.reset(new BiCGSTABSolver(const_cast(*matrices_->matrices\n+().coarsest()),\n+ 774 *scalarProduct_,\n+ 775 *coarseSmoother_, 1E-2, 1000, 0));\n+ 776 // // we have to allocate these types using the rebound allocator\n+ 777 // // in order to ensure that we fulfill the alignment requirements\n+ 778 // using Alloc = typename std::allocator_traits::template\n+rebind_alloc>;\n+ 779 // Alloc alloc;\n+ 780 // auto p = alloc.allocate(1);\n+ 781 // std::allocator_traits::construct(alloc, p,\n+ 782 // const_cast(*matrices_->matrices().coarsest()),\n+ 783 // *scalarProduct_,\n+ 784 // *coarseSmoother_, 1E-2, 1000, 0);\n+ 785 // solver_.reset(p,[](BiCGSTABSolver* p){\n+ 786 // Alloc alloc;\n+ 787 // std::allocator_traits::destroy(alloc, p);\n+ 788 // alloc.deallocate(p,1);\n+ 789 // });\n+ 790 }\n+ 791 }\n+ 792 }\n+ 793\n+ 794 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator\n+().rank()==0)\n+ 795 std::cout<<\"Building hierarchy of \"<maxlevels()<<\" levels \"\n+ 796 <<\"(including coarse solver) took \"<\n+801 void AMG::pre(Domain& x, Range& b)\n+ 802 {\n+ 803 // Detect Matrix rows where all offdiagonal entries are\n+ 804 // zero and set x such that A_dd*x_d=b_d\n+ 805 // Thus users can be more careless when setting up their linear\n+ 806 // systems.\n+ 807 typedef typename M::matrix_type Matrix;\n+ 808 typedef typename Matrix::ConstRowIterator RowIter;\n+ 809 typedef typename Matrix::ConstColIterator ColIter;\n+ 810 typedef typename Matrix::block_type Block;\n+ 811 Block zero;\n+ 812 zero=typename Matrix::field_type();\n+ 813\n+ 814 const Matrix& mat=matrices_->matrices().finest()->getmat();\n+ 815 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {\n+ 816 bool isDirichlet = true;\n+ 817 bool hasDiagonal = false;\n+ 818 Block diagonal{};\n+ 819 for(ColIter col=row->begin(); col!=row->end(); ++col) {\n+ 820 if(row.index()==col.index()) {\n+ 821 diagonal = *col;\n+ 822 hasDiagonal = true;\n+ 823 }else{\n+ 824 if(*col!=zero)\n+ 825 isDirichlet = false;\n+ 826 }\n+ 827 }\n+ 828 if(isDirichlet && hasDiagonal)\n+ 829 {\n+ 830 auto&& xEntry = Impl::asVector(x[row.index()]);\n+ 831 auto&& bEntry = Impl::asVector(b[row.index()]);\n+ 832 Impl::asMatrix(diagonal).solve(xEntry, bEntry);\n+ 833 }\n+ 834 }\n+ 835\n+ 836 if(smoothers_->levels()>0)\n+ 837 smoothers_->finest()->pre(x,b);\n+ 838 else\n+ 839 // No smoother to make x consistent! Do it by hand\n+ 840 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);\n+ 841 rhs_ = std::make_shared>(std::make_shared(b));\n+ 842 lhs_ = std::make_shared>(std::make_shared(x));\n+ 843 update_ = std::make_shared>(std::make_shared\n+(x));\n+ 844 matrices_->coarsenVector(*rhs_);\n+ 845 matrices_->coarsenVector(*lhs_);\n+ 846 matrices_->coarsenVector(*update_);\n+ 847\n+ 848 // Preprocess all smoothers\n+ 849 typedef typename Hierarchy::Iterator Iterator;\n+ 850 typedef typename Hierarchy::Iterator RIterator;\n+ 851 typedef typename Hierarchy::Iterator DIterator;\n+ 852 Iterator coarsest = smoothers_->coarsest();\n+ 853 Iterator smoother = smoothers_->finest();\n+ 854 RIterator rhs = rhs_->finest();\n+ 855 DIterator lhs = lhs_->finest();\n+ 856 if(smoothers_->levels()>1) {\n+ 857\n+ 858 assert(lhs_->levels()==rhs_->levels());\n+ 859 assert(smoothers_->levels()==lhs_->levels() || matrices_->levels\n+()==matrices_->maxlevels());\n+ 860 assert(smoothers_->levels()+1==lhs_->levels() || matrices_->levels\n+()maxlevels());\n+ 861\n+ 862 if(smoother!=coarsest)\n+ 863 for(++smoother, ++lhs, ++rhs; smoother != coarsest; ++smoother, ++lhs,\n+++rhs)\n+ 864 smoother->pre(*lhs,*rhs);\n+ 865 smoother->pre(*lhs,*rhs);\n+ 866 }\n+ 867\n+ 868\n+ 869 // The preconditioner might change x and b. So we have to\n+ 870 // copy the changes to the original vectors.\n+ 871 x = *lhs_->finest();\n+ 872 b = *rhs_->finest();\n+ 873\n+ 874 }\n+ 875 template\n+876 std::size_t AMG::levels()\n+ 877 {\n+ 878 return matrices_->levels();\n+ 879 }\n+ 880 template\n+881 std::size_t AMG::maxlevels()\n+ 882 {\n+ 883 return matrices_->maxlevels();\n+ 884 }\n+ 885\n+ 887 template\n+888 void AMG::apply(Domain& v, const Range& d)\n+ 889 {\n+ 890 LevelContext levelContext;\n+ 891\n+ 892 if(additive) {\n+ 893 *(rhs_->finest())=d;\n+ 894 additiveMgc();\n+ 895 v=*lhs_->finest();\n+ 896 }else{\n+ 897 // Init all iterators for the current level\n+ 898 initIteratorsWithFineLevel(levelContext);\n+ 899\n+ 900\n+ 901 *levelContext.lhs = v;\n+ 902 *levelContext.rhs = d;\n+ 903 *levelContext.update=0;\n+ 904 levelContext.level=0;\n+ 905\n+ 906 mgc(levelContext);\n+ 907\n+ 908 if(postSteps_==0||matrices_->maxlevels()==1)\n+ 909 levelContext.pinfo->copyOwnerToAll(*levelContext.update,\n+*levelContext.update);\n+ 910\n+ 911 v=*levelContext.update;\n+ 912 }\n+ 913\n+ 914 }\n+ 915\n+ 916 template\n+ 917 void AMG::initIteratorsWithFineLevel(LevelContext&\n+levelContext)\n+ 918 {\n+ 919 levelContext.smoother = smoothers_->finest();\n+ 920 levelContext.matrix = matrices_->matrices().finest();\n+ 921 levelContext.pinfo = matrices_->parallelInformation().finest();\n+ 922 levelContext.redist =\n+ 923 matrices_->redistributeInformation().begin();\n+ 924 levelContext.aggregates = matrices_->aggregatesMaps().begin();\n+ 925 levelContext.lhs = lhs_->finest();\n+ 926 levelContext.update = update_->finest();\n+ 927 levelContext.rhs = rhs_->finest();\n+ 928 }\n+ 929\n+ 930 template\n+ 931 bool AMG\n+ 932 ::moveToCoarseLevel(LevelContext& levelContext)\n+ 933 {\n+ 934\n+ 935 bool processNextLevel=true;\n+ 936\n+ 937 if(levelContext.redist->isSetup()) {\n+ 938 levelContext.redist->redistribute(static_cast\n+(*levelContext.rhs),\n+ 939 levelContext.rhs.getRedistributed());\n+ 940 processNextLevel = levelContext.rhs.getRedistributed().size()>0;\n+ 941 if(processNextLevel) {\n+ 942 //restrict defect to coarse level right hand side.\n+ 943 typename Hierarchy::Iterator fineRhs = levelContext.rhs++;\n+ 944 ++levelContext.pinfo;\n+ 945 Transfer\n+ 946::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,\n+ 947 static_cast(fineRhs.getRedistributed()),\n+ 948 *levelContext.pinfo);\n+ 949 }\n+ 950 }else{\n+ 951 //restrict defect to coarse level right hand side.\n+ 952 typename Hierarchy::Iterator fineRhs = levelContext.rhs++;\n+ 953 ++levelContext.pinfo;\n+ 954 Transfer\n+ 955::restrictVector(*(*levelContext.aggregates),\n+ 956 *levelContext.rhs, static_cast(*fineRhs),\n+ 957 *levelContext.pinfo);\n+ 958 }\n+ 959\n+ 960 if(processNextLevel) {\n+ 961 // prepare coarse system\n+ 962 ++levelContext.lhs;\n+ 963 ++levelContext.update;\n+ 964 ++levelContext.matrix;\n+ 965 ++levelContext.level;\n+ 966 ++levelContext.redist;\n+ 967\n+ 968 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n+>levels()maxlevels()) {\n+ 969 // next level is not the globally coarsest one\n+ 970 ++levelContext.smoother;\n+ 971 ++levelContext.aggregates;\n+ 972 }\n+ 973 // prepare the update on the next level\n+ 974 *levelContext.update=0;\n+ 975 }\n+ 976 return processNextLevel;\n+ 977 }\n+ 978\n+ 979 template\n+ 980 void AMG\n+ 981 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel)\n+ 982 {\n+ 983 if(processNextLevel) {\n+ 984 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_-\n+>levels()maxlevels()) {\n+ 985 // previous level is not the globally coarsest one\n+ 986 --levelContext.smoother;\n+ 987 --levelContext.aggregates;\n+ 988 }\n+ 989 --levelContext.redist;\n+ 990 --levelContext.level;\n+ 991 //prolongate and add the correction (update is in coarse left hand side)\n+ 992 --levelContext.matrix;\n+ 993\n+ 994 //typename Hierarchy::Iterator coarseLhs = lhs--;\n+ 995 --levelContext.lhs;\n+ 996 --levelContext.pinfo;\n+ 997 }\n+ 998 if(levelContext.redist->isSetup()) {\n+ 999 // Need to redistribute during prolongateVector\n+ 1000 levelContext.lhs.getRedistributed()=0;\n+ 1001 Transfer\n+ 1002::prolongateVector(*(*levelContext.aggregates), *levelContext.update,\n+*levelContext.lhs,\n+ 1003 levelContext.lhs.getRedistributed(),\n+ 1004 matrices_->getProlongationDampingFactor(),\n+ 1005 *levelContext.pinfo, *levelContext.redist);\n+ 1006 }else{\n+ 1007 *levelContext.lhs=0;\n+ 1008 Transfer\n+ 1009::prolongateVector(*(*levelContext.aggregates), *levelContext.update,\n+*levelContext.lhs,\n+ 1010 matrices_->getProlongationDampingFactor(),\n+ 1011 *levelContext.pinfo);\n+ 1012 }\n+ 1013\n+ 1014\n+ 1015 if(processNextLevel) {\n+ 1016 --levelContext.update;\n+ 1017 --levelContext.rhs;\n+ 1018 }\n+ 1019\n+ 1020 *levelContext.update += *levelContext.lhs;\n+ 1021 }\n+ 1022\n+ 1023 template\n+1024 bool AMG::usesDirectCoarseLevelSolver() const\n+ 1025 {\n+ 1026 return IsDirectSolver<_CoarseSolver>::value;\n+ 1027 }\n+ 1028\n+ 1029 template\n+ 1030 void AMG::mgc(LevelContext& levelContext){\n+ 1031 if(levelContext.matrix == matrices_->matrices().coarsest() && levels\n+()==maxlevels()) {\n+ 1032 // Solve directly\n+ 1033 InverseOperatorResult res;\n+ 1034 res.converged=true; // If we do not compute this flag will not get\n+updated\n+ 1035 if(levelContext.redist->isSetup()) {\n+ 1036 levelContext.redist->redistribute(*levelContext.rhs,\n+levelContext.rhs.getRedistributed());\n+ 1037 if(levelContext.rhs.getRedistributed().size()>0) {\n+ 1038 // We are still participating in the computation\n+ 1039 levelContext.pinfo.getRedistributed().copyOwnerToAll\n+(levelContext.rhs.getRedistributed(),\n+ 1040 levelContext.rhs.getRedistributed());\n+ 1041 solver_->apply(levelContext.update.getRedistributed(),\n+ 1042 levelContext.rhs.getRedistributed(), res);\n+ 1043 }\n+ 1044 levelContext.redist->redistributeBackward(*levelContext.update,\n+levelContext.update.getRedistributed());\n+ 1045 levelContext.pinfo->copyOwnerToAll(*levelContext.update,\n+*levelContext.update);\n+ 1046 }else{\n+ 1047 levelContext.pinfo->copyOwnerToAll(*levelContext.rhs, *levelContext.rhs);\n+ 1048 solver_->apply(*levelContext.update, *levelContext.rhs, res);\n+ 1049 }\n+ 1050\n+ 1051 if (!res.converged)\n+ 1052 coarsesolverconverged = false;\n+ 1053 }else{\n+ 1054 // presmoothing\n+ 1055 presmooth(levelContext, preSteps_);\n+ 1056\n+ 1057#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n+ 1058 bool processNextLevel = moveToCoarseLevel(levelContext);\n+ 1059\n+ 1060 if(processNextLevel) {\n+ 1061 // next level\n+ 1062 for(std::size_t i=0; imatrices().coarsest() && levels\n+()==maxlevels())\n+ 1065 break;\n+ 1066 if(i+1 < gamma_){\n+ 1067 levelContext.matrix->applyscaleadd(-1., *levelContext.lhs,\n+*levelContext.rhs);\n+ 1068 }\n+ 1069 }\n+ 1070 }\n+ 1071\n+ 1072 moveToFineLevel(levelContext, processNextLevel);\n+ 1073#else\n+ 1074 *lhs=0;\n+ 1075#endif\n+ 1076\n+ 1077 if(levelContext.matrix == matrices_->matrices().finest()) {\n+ 1078 coarsesolverconverged = matrices_->parallelInformation().finest()-\n+>communicator().prod(coarsesolverconverged);\n+ 1079 if(!coarsesolverconverged)\n+ 1080 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n+ 1081 }\n+ 1082 // postsmoothing\n+ 1083 postsmooth(levelContext, postSteps_);\n+ 1084\n+ 1085 }\n+ 1086 }\n+ 1087\n+ 1088 template\n+ 1089 void AMG::additiveMgc(){\n+ 1090\n+ 1091 // restrict residual to all levels\n+ 1092 typename ParallelInformationHierarchy::Iterator pinfo=matrices_-\n+>parallelInformation().finest();\n+ 1093 typename Hierarchy::Iterator rhs=rhs_->finest();\n+ 1094 typename Hierarchy::Iterator lhs = lhs_->finest();\n+ 1095 typename OperatorHierarchy::AggregatesMapList::const_iterator\n+aggregates=matrices_->aggregatesMaps().begin();\n+ 1096\n+ 1097 for(typename Hierarchy::Iterator fineRhs=rhs++; fineRhs != rhs_-\n+>coarsest(); fineRhs=rhs++, ++aggregates) {\n+ 1098 ++pinfo;\n+ 1099 Transfer\n+ 1100::restrictVector(*(*aggregates), *rhs, static_cast\n+(*fineRhs), *pinfo);\n+ 1101 }\n+ 1102\n+ 1103 // pinfo is invalid, set to coarsest level\n+ 1104 //pinfo = matrices_->parallelInformation().coarsest\n+ 1105 // calculate correction for all levels\n+ 1106 lhs = lhs_->finest();\n+ 1107 typename Hierarchy::Iterator smoother = smoothers_->finest();\n+ 1108\n+ 1109 for(rhs=rhs_->finest(); rhs != rhs_->coarsest(); ++lhs, ++rhs,\n+++smoother) {\n+ 1110 // presmoothing\n+ 1111 *lhs=0;\n+ 1112 smoother->apply(*lhs, *rhs);\n+ 1113 }\n+ 1114\n+ 1115 // Coarse level solve\n+ 1116#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION\n+ 1117 InverseOperatorResult res;\n+ 1118 pinfo->copyOwnerToAll(*rhs, *rhs);\n+ 1119 solver_->apply(*lhs, *rhs, res);\n+ 1120\n+ 1121 if(!res.converged)\n+ 1122 DUNE_THROW(MathError, \"Coarse solver did not converge\");\n+ 1123#else\n+ 1124 *lhs=0;\n+ 1125#endif\n+ 1126 // Prologate and add up corrections from all levels\n+ 1127 --pinfo;\n+ 1128 --aggregates;\n+ 1129\n+ 1130 for(typename Hierarchy::Iterator coarseLhs = lhs--; coarseLhs\n+!= lhs_->finest(); coarseLhs = lhs--, --aggregates, --pinfo) {\n+ 1131 Transfer\n+ 1132::prolongateVector(*(*aggregates), *coarseLhs, *lhs, 1.0, *pinfo);\n+ 1133 }\n+ 1134 }\n+ 1135\n+ 1136\n+ 1138 template\n+1139 void AMG::post([[maybe_unused]] Domain& x)\n+ 1140 {\n+ 1141 // Postprocess all smoothers\n+ 1142 typedef typename Hierarchy::Iterator Iterator;\n+ 1143 typedef typename Hierarchy::Iterator DIterator;\n+ 1144 Iterator coarsest = smoothers_->coarsest();\n+ 1145 Iterator smoother = smoothers_->finest();\n+ 1146 DIterator lhs = lhs_->finest();\n+ 1147 if(smoothers_->levels()>0) {\n+ 1148 if(smoother != coarsest || matrices_->levels()maxlevels())\n+ 1149 smoother->post(*lhs);\n+ 1150 if(smoother!=coarsest)\n+ 1151 for(++smoother, ++lhs; smoother != coarsest; ++smoother, ++lhs)\n+ 1152 smoother->post(*lhs);\n+ 1153 smoother->post(*lhs);\n+ 1154 }\n+ 1155 lhs_ = nullptr;\n+ 1156 update_ = nullptr;\n+ 1157 rhs_ = nullptr;\n+ 1158 }\n+ 1159\n+ 1160 template\n+ 1161 template\n+1162 void AMG::getCoarsestAggregateNumbers(std::vector& cont)\n+ 1163 {\n+ 1164 matrices_->getCoarsestAggregatesOnFinest(cont);\n+ 1165 }\n+ 1166\n+ 1167 } // end namespace Amg\n+ 1168\n+1169 struct AMGCreator{\n+1170 template struct isValidBlockType : std::false_type{};\n+1171 template struct\n+isValidBlockType> : std::true_type{};\n+ 1172\n+ 1173 template\n+ 1174 std::shared_ptr >\n+1175 makeAMG(const OP& op, const std::string& smoother, const Dune::\n+ParameterTree& config) const\n+ 1176 {\n+ 1177 DUNE_THROW(Dune::Exception, \"Operator type not supported by AMG\");\n+ 1178 }\n+ 1179\n+ 1180 template\n+ 1181 std::shared_ptr >\n+1182 makeAMG(const std::shared_ptr>& op, const std::\n+string& smoother,\n+ 1183 const Dune::ParameterTree& config) const\n+ 1184 {\n+ 1185 using OP = MatrixAdapter;\n+ 1186\n+ 1187 if(smoother == \"ssor\")\n+ 1188 return std::make_shared>>(op, config);\n+ 1189 if(smoother == \"sor\")\n+ 1190 return std::make_shared>>(op, config);\n+ 1191 if(smoother == \"jac\")\n+ 1192 return std::make_shared>>(op, config);\n+ 1193 if(smoother == \"gs\")\n+ 1194 return std::make_shared>>(op, config);\n+ 1195 if(smoother == \"ilu\")\n+ 1196 return std::make_shared>>(op, config);\n+ 1197 else\n+ 1198 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n+ 1199 }\n+ 1200\n+ 1201 template\n+ 1202 std::shared_ptr >\n+1203 makeAMG(const std::shared_ptr>& op,\n+const std::string& smoother,\n+ 1204 const Dune::ParameterTree& config) const\n+ 1205 {\n+ 1206 using OP = OverlappingSchwarzOperator;\n+ 1207\n+ 1208 auto cop = std::static_pointer_cast(op);\n+ 1209\n+ 1210 if(smoother == \"ssor\")\n+ 1211 return std::make_shared>,C>>(cop, config, op->getCommunication\n+());\n+ 1212 if(smoother == \"sor\")\n+ 1213 return std::make_shared>,C>>(cop, config, op->getCommunication\n+());\n+ 1214 if(smoother == \"jac\")\n+ 1215 return std::make_shared>,C>>(cop, config, op->getCommunication\n+());\n+ 1216 if(smoother == \"gs\")\n+ 1217 return std::make_shared>,C>>(cop, config, op->getCommunication\n+());\n+ 1218 if(smoother == \"ilu\")\n+ 1219 return std::make_shared>,C>>(cop, config, op->getCommunication\n+());\n+ 1220 else\n+ 1221 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n+ 1222 }\n+ 1223\n+ 1224 template\n+ 1225 std::shared_ptr >\n+1226 makeAMG(const std::shared_ptr>& op,\n+const std::string& smoother,\n+ 1227 const Dune::ParameterTree& config) const\n+ 1228 {\n+ 1229 using OP = NonoverlappingSchwarzOperator;\n+ 1230\n+ 1231 if(smoother == \"ssor\")\n+ 1232 return std::make_shared>,C>>(op, config, op-\n+>getCommunication());\n+ 1233 if(smoother == \"sor\")\n+ 1234 return std::make_shared>,C>>(op, config, op-\n+>getCommunication());\n+ 1235 if(smoother == \"jac\")\n+ 1236 return std::make_shared>,C>>(op, config, op-\n+>getCommunication());\n+ 1237 if(smoother == \"gs\")\n+ 1238 return std::make_shared>,C>>(op, config, op-\n+>getCommunication());\n+ 1239 if(smoother == \"ilu\")\n+ 1240 return std::make_shared>,C>>(op, config, op-\n+>getCommunication());\n+ 1241 else\n+ 1242 DUNE_THROW(Dune::Exception, \"Unknown smoother for AMG\");\n+ 1243 }\n+ 1244\n+ 1245 template\n+ 1246 std::shared_ptr::type,\n+ 1247 typename Dune::TypeListElement<2, TL>::type>>\n+1248 operator()(TL tl, const std::shared_ptr& op, const Dune::\n+ParameterTree& config,\n+ 1249 std::enable_if_t::\n+value,int> = 0) const\n+ 1250 {\n+ 1251 using field_type = typename OP::matrix_type::field_type;\n+ 1252 using real_type = typename FieldTraits::real_type;\n+ 1253 if (!std::is_convertible())\n+ 1254 DUNE_THROW(UnsupportedType, \"AMG needs field_type(\" <<\n+ 1255 className() <<\n+ 1256 \") to be convertible to its real_type (\" <<\n+ 1257 className() <<\n+ 1258 \").\");\n+ 1259 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;\n+ 1260 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;\n+ 1261 std::shared_ptr> amg;\n+ 1262 std::string smoother = config.get(\"smoother\", \"ssor\");\n+ 1263 return makeAMG(op, smoother, config);\n+ 1264 }\n+ 1265\n+ 1266 template\n+ 1267 std::shared_ptr::type,\n+ 1268 typename Dune::TypeListElement<2, TL>::type>>\n+1269 operator()(TL /*tl*/, const std::shared_ptr& /*mat*/, const Dune::\n+ParameterTree& /*config*/,\n+ 1270 std::enable_if_t::value,int> = 0) const\n+ 1271 {\n+ 1272 DUNE_THROW(UnsupportedType, \"AMG needs a FieldMatrix as Matrix\n+block_type\");\n+ 1273 }\n+ 1274 };\n+ 1275\n+1276 DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator());\n+ 1277} // end namespace Dune\n+ 1278\n+ 1279#endif\n+superlu.hh\n+Classes for using SuperLU with ISTL matrices.\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+solvertype.hh\n+Templates characterizing the type of a solver.\n+umfpack.hh\n+Classes for using UMFPack with ISTL matrices.\n+transfer.hh\n+Prolongation and restriction for amg.\n+matrixhierarchy.hh\n+Provides a classes representing the hierarchies in AMG.\n+smoother.hh\n+Classes for the generic construction and application of the smoothers.\n+solvers.hh\n+Implementations of the inverse operator interface.\n+col\n+Col col\n+Definition: matrixmatrix.hh:351\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::Amg::AMG::AMG\n+AMG(const AMG &amg)\n+Copy constructor.\n+Definition: amg.hh:392\n+Dune::Amg::AMG::pre\n+void pre(Domain &x, Range &b)\n+Prepare the preconditioner.\n+Definition: amg.hh:801\n+Dune::Amg::DirectSolverSelector::create\n+static DirectSolver * create(const Matrix &mat, bool verbose, bool reusevector)\n+Definition: amg.hh:681\n+Dune::Amg::DirectSolverSelector::name\n+static std::string name()\n+Definition: amg.hh:680\n+Dune::Amg::AMG::LevelContext::update\n+Hierarchy< Domain, A >::Iterator update\n+The iterator over the updates.\n+Definition: amg.hh:303\n+Dune::Amg::AMG::LevelContext::rhs\n+Hierarchy< Range, A >::Iterator rhs\n+The iterator over the right hand sided.\n+Definition: amg.hh:307\n+Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::name\n+static std::string name()\n+Definition: amg.hh:672\n+Dune::Amg::AMG::usesDirectCoarseLevelSolver\n+bool usesDirectCoarseLevelSolver() const\n+Check whether the coarse solver used is a direct solver.\n+Definition: amg.hh:1024\n+Dune::Amg::AMG::Domain\n+X Domain\n+The domain type.\n+Definition: amg.hh:87\n+Dune::Amg::DirectSolverSelector::Solver::create\n+static type * create(const M &mat, bool verbose, bool reusevector)\n+Definition: amg.hh:644\n+Dune::Amg::AMG::AMG\n+AMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs\n+&smootherArgs, const Parameters &parms)\n+Construct a new amg with a specific coarse solver.\n+Definition: amg.hh:406\n+Dune::Amg::AMG::AMG\n+AMG(std::shared_ptr< const Operator > fineOperator, const ParameterTree\n+&configuration, const ParallelInformation &pinfo=ParallelInformation())\n+Constructor an AMG via ParameterTree.\n+Definition: amg.hh:452\n+Dune::Amg::AMG::LevelContext::pinfo\n+ParallelInformationHierarchy::Iterator pinfo\n+The iterator over the parallel information.\n+Definition: amg.hh:287\n+Dune::Amg::DirectSolverSelector::SolverType\n+SolverType\n+Definition: amg.hh:627\n+Dune::Amg::AMG::LevelContext::aggregates\n+OperatorHierarchy::AggregatesMapList::const_iterator aggregates\n+The iterator over the aggregates maps.\n+Definition: amg.hh:295\n+Dune::Amg::AMG::SmootherArgs\n+SmootherTraits< Smoother >::Arguments SmootherArgs\n+The argument type for the construction of the smoother.\n+Definition: amg.hh:100\n+Dune::Amg::DirectSolverSelector::SelectedSolver\n+Solver< Matrix, solver > SelectedSolver\n+Definition: amg.hh:677\n+Dune::AMGCreator::makeAMG\n+std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n+MatrixAdapter< M, X, Y > > &op, const std::string &smoother, const Dune::\n+ParameterTree &config) const\n+Definition: amg.hh:1182\n+Dune::Amg::AMG::ToLower::operator()\n+std::string operator()(const std::string &str)\n+Definition: amg.hh:378\n+Dune::AMGCreator::makeAMG\n+std::shared_ptr< Dune::Preconditioner< typename OP::element_type::domain_type,\n+typename OP::element_type::range_type > > makeAMG(const OP &op, const std::\n+string &smoother, const Dune::ParameterTree &config) const\n+Definition: amg.hh:1175\n+Dune::Amg::AMG::Smoother\n+S Smoother\n+The type of the smoother.\n+Definition: amg.hh:97\n+Dune::Amg::DirectSolverSelector::Solver::name\n+static std::string name()\n+Definition: amg.hh:649\n+Dune::Amg::AMG::LevelContext::smoother\n+Hierarchy< Smoother, A >::Iterator smoother\n+The iterator over the smoothers.\n+Definition: amg.hh:279\n+Dune::Amg::AMG::Operator\n+M Operator\n+The matrix operator type.\n+Definition: amg.hh:73\n+Dune::Amg::AMG::LevelContext::matrix\n+OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix\n+The iterator over the matrices.\n+Definition: amg.hh:283\n+Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::type\n+SuperLU< M > type\n+Definition: amg.hh:667\n+Dune::Amg::DirectSolverSelector::Solver<_M,_superlu_>::create\n+static type * create(const M &mat, bool verbose, bool reusevector)\n+Definition: amg.hh:668\n+Dune::Amg::AMG::LevelContext::redist\n+OperatorHierarchy::RedistributeInfoList::const_iterator redist\n+The iterator over the redistribution information.\n+Definition: amg.hh:291\n+Dune::Amg::AMG::Range\n+X Range\n+The range type.\n+Definition: amg.hh:89\n+Dune::Amg::presmooth\n+void presmooth(LevelContext &levelContext, size_t steps)\n+Apply pre smoothing on the current level.\n+Definition: smoother.hh:406\n+Dune::Amg::AMG::getCoarsestAggregateNumbers\n+void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)\n+Get the aggregate number of each unknown on the coarsest level.\n+Definition: amg.hh:1162\n+Dune::Amg::AMG::levels\n+std::size_t levels()\n+Definition: amg.hh:876\n+Dune::Amg::DirectSolverSelector::Solver::type\n+InverseOperator< Vector, Vector > type\n+Definition: amg.hh:643\n+Dune::AMGCreator::makeAMG\n+std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n+OverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother,\n+const Dune::ParameterTree &config) const\n+Definition: amg.hh:1203\n+Dune::Amg::AMG::LevelContext::lhs\n+Hierarchy< Domain, A >::Iterator lhs\n+The iterator over the left hand side.\n+Definition: amg.hh:299\n+Dune::Amg::ConstructionTraits::Arguments\n+const void * Arguments\n+A type holding all the arguments needed to call the constructor.\n+Definition: construction.hh:44\n+Dune::Amg::DirectSolverSelector::solver\n+static constexpr SolverType solver\n+Definition: amg.hh:629\n+Dune::Amg::ConstructionTraits::construct\n+static std::shared_ptr< T > construct(Arguments &args)\n+Construct an object with the specified arguments.\n+Definition: construction.hh:52\n+Dune::Amg::DirectSolverSelector::isDirectSolver\n+static constexpr bool isDirectSolver\n+Definition: amg.hh:679\n+Dune::Amg::AMG::recalculateHierarchy\n+void recalculateHierarchy()\n+Recalculate the matrix hierarchy.\n+Definition: amg.hh:221\n+Dune::Amg::Hierarchy::coarsest\n+Iterator coarsest()\n+Get an iterator positioned at the coarsest level.\n+Definition: hierarchy.hh:383\n+Dune::Amg::DirectSolverSelector::field_type\n+Matrix::field_type field_type\n+Definition: amg.hh:626\n+Dune::Amg::DirectSolverSelector::DirectSolver\n+SelectedSolver::type DirectSolver\n+Definition: amg.hh:678\n+Dune::AMGCreator::operator()\n+std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL\n+>::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL tl,\n+const std::shared_ptr< OP > &op, const Dune::ParameterTree &config, std::\n+enable_if_t< isValidBlockType< typename OP::matrix_type::block_type >::value,\n+int >=0) const\n+Definition: amg.hh:1248\n+Dune::Amg::AMG::ParallelInformationHierarchy\n+OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy\n+The parallal data distribution hierarchy type.\n+Definition: amg.hh:84\n+Dune::Amg::AMG::CoarseSolver\n+InverseOperator< X, X > CoarseSolver\n+the type of the coarse solver.\n+Definition: amg.hh:91\n+Dune::Amg::AMG::post\n+void post(Domain &x)\n+Clean up.\n+Definition: amg.hh:1139\n+Dune::Amg::AMG::maxlevels\n+std::size_t maxlevels()\n+Definition: amg.hh:881\n+Dune::AMGCreator::makeAMG\n+std::shared_ptr< Dune::Preconditioner< X, Y > > makeAMG(const std::shared_ptr<\n+NonoverlappingSchwarzOperator< M, X, Y, C > > &op, const std::string &smoother,\n+const Dune::ParameterTree &config) const\n+Definition: amg.hh:1226\n+Dune::Amg::postsmooth\n+void postsmooth(LevelContext &levelContext, size_t steps)\n+Apply post smoothing on the current level.\n+Definition: smoother.hh:428\n+Dune::Amg::AMG::LevelContext::level\n+std::size_t level\n+The level index.\n+Definition: amg.hh:311\n+Dune::Amg::AMG::AMG\n+AMG(const Operator &fineOperator, const C &criterion, const SmootherArgs\n+&smootherArgs=SmootherArgs(), const ParallelInformation\n+&pinfo=ParallelInformation())\n+Construct an AMG with an inexact coarse solver based on the smoother.\n+Definition: amg.hh:428\n+Dune::Amg::AMG::apply\n+void apply(Domain &v, const Range &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: amg.hh:888\n+Dune::Amg::AMG::LevelContext::SmootherType\n+Smoother SmootherType\n+Definition: amg.hh:275\n+Dune::Amg::AMG::OperatorHierarchy\n+MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy\n+The operator hierarchy type.\n+Definition: amg.hh:82\n+Dune::Amg::AMG::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: amg.hh:194\n+Dune::Amg::AMG::ParallelInformation\n+PI ParallelInformation\n+The type of the parallel information. Either OwnerOverlapCommunication or\n+another type describing the...\n+Definition: amg.hh:80\n+Dune::Amg::DirectSolverSelector::none\n+@ none\n+Definition: amg.hh:627\n+Dune::Amg::DirectSolverSelector::umfpack\n+@ umfpack\n+Definition: amg.hh:627\n+Dune::Amg::DirectSolverSelector::superlu\n+@ superlu\n+Definition: amg.hh:627\n+Dune::Amg::atOnceAccu\n+@ atOnceAccu\n+Accumulate data to one process at once.\n+Definition: parameters.hh:244\n+Dune::Amg::noAccu\n+@ noAccu\n+No data accumulution.\n+Definition: parameters.hh:238\n+Dune::Amg::successiveAccu\n+@ successiveAccu\n+Successively accumulate to fewer processes.\n+Definition: parameters.hh:248\n Dune\n Definition: allocator.hh:11\n-Dune::MatrixIndexSet\n-Stores the nonzero entries in a sparse matrix.\n-Definition: matrixindexset.hh:16\n-Dune::MatrixIndexSet::resize\n-void resize(size_type rows, size_type cols)\n-Reset the size of an index set.\n-Definition: matrixindexset.hh:31\n-Dune::MatrixIndexSet::MatrixIndexSet\n-MatrixIndexSet()\n-Default constructor.\n-Definition: matrixindexset.hh:22\n-Dune::MatrixIndexSet::add\n-void add(size_type i, size_type j)\n-Add an index to the index set.\n-Definition: matrixindexset.hh:38\n-Dune::MatrixIndexSet::rows\n-size_type rows() const\n-Return the number of rows.\n-Definition: matrixindexset.hh:52\n-Dune::MatrixIndexSet::size_type\n-std::size_t size_type\n-Definition: matrixindexset.hh:19\n-Dune::MatrixIndexSet::exportIdx\n-void exportIdx(MatrixType &matrix) const\n-Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.\n-Definition: matrixindexset.hh:90\n-Dune::MatrixIndexSet::MatrixIndexSet\n-MatrixIndexSet(size_type rows, size_type cols)\n-Constructor setting the matrix size.\n-Definition: matrixindexset.hh:26\n-Dune::MatrixIndexSet::rowsize\n-size_type rowsize(size_type row) const\n-Return the number of entries in a given row.\n-Definition: matrixindexset.hh:56\n-Dune::MatrixIndexSet::size\n-size_type size() const\n-Return the number of entries.\n-Definition: matrixindexset.hh:43\n+Dune::DUNE_REGISTER_PRECONDITIONER\n+DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator())\n+Dune::MatrixImp::DenseMatrixBase::ConstIterator\n+ConstIterator class for sequential access.\n+Definition: matrix.hh:404\n+Dune::Matrix\n+A generic dynamic dense matrix.\n+Definition: matrix.hh:561\n+Dune::Matrix::field_type\n+typename Imp::BlockTraits< T >::field_type field_type\n+Export the type representing the underlying field.\n+Definition: matrix.hh:565\n+Dune::Matrix::ConstColIterator\n+row_type::const_iterator ConstColIterator\n+Const iterator for the entries of each row.\n+Definition: matrix.hh:589\n+Dune::Matrix::block_type\n+T block_type\n+Export the type representing the components.\n+Definition: matrix.hh:568\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n+Dune::NonoverlappingSchwarzOperator\n+A nonoverlapping operator with communication object.\n+Definition: novlpschwarz.hh:61\n+Dune::MatrixAdapter\n+Adapter to turn a matrix into a linear operator.\n+Definition: operators.hh:137\n+Dune::Amg::Diagonal<_0_>\n+Dune::Amg::RowSum\n+Functor using the row sum (infinity) norm to determine strong couplings.\n+Definition: aggregates.hh:463\n+Dune::Amg::FrobeniusNorm\n+Definition: aggregates.hh:480\n+Dune::Amg::AlwaysOneNorm\n+Definition: aggregates.hh:496\n+Dune::Amg::SymmetricCriterion\n+Criterion taking advantage of symmetric matrices.\n+Definition: aggregates.hh:519\n+Dune::Amg::UnSymmetricCriterion\n+Criterion suitable for unsymmetric matrices.\n+Definition: aggregates.hh:539\n+Dune::Amg::KAMG\n+an algebraic multigrid method using a Krylov-cycle.\n+Definition: kamg.hh:140\n+Dune::Amg::KAmgTwoGrid\n+Two grid operator for AMG with Krylov cycle.\n+Definition: kamg.hh:33\n+Dune::Amg::AMG\n+Parallel algebraic multigrid based on agglomeration.\n+Definition: amg.hh:65\n+Dune::Amg::DirectSolverSelector\n+Definition: amg.hh:625\n+Dune::Amg::DirectSolverSelector::Solver\n+Definition: amg.hh:642\n+Dune::AMGCreator\n+Definition: amg.hh:1169\n+Dune::AMGCreator::isValidBlockType\n+Definition: amg.hh:1170\n+Dune::OverlappingSchwarzOperator\n+An overlapping Schwarz operator.\n+Definition: schwarz.hh:75\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n+LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n+> Iterator\n+Type of the mutable iterator.\n+Definition: hierarchy.hh:216\n+Dune::Amg::Hierarchy<_MatrixOperator,_Allocator_>::ConstIterator\n+LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const\n+MatrixOperator > ConstIterator\n+Type of the const iterator.\n+Definition: hierarchy.hh:219\n+Dune::Amg::MatrixHierarchy\n+The hierarchies build by the coarsening process.\n+Definition: matrixhierarchy.hh:61\n+Dune::Amg::CoarsenCriterion\n+The criterion describing the stop criteria for the coarsening process.\n+Definition: matrixhierarchy.hh:283\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::Amg::SmootherTraits\n+Traits class for getting the attribute class of a smoother.\n+Definition: smoother.hh:66\n+Dune::Amg::Transfer::restrictVector\n+static void restrictVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, const Vector &fine, T &comm)\n+Dune::Amg::Transfer::prolongateVector\n+static void prolongateVector(const AggregatesMap< Vertex > &aggregates, Vector\n+&coarse, Vector &fine, Vector &fineRedist, T1 damp, R &redistributor=R())\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::Preconditioner<_X,_X_>::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioner.hh:39\n+Dune::ScalarProduct\n+Base class for scalar product and norm computation.\n+Definition: scalarproducts.hh:52\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperatorResult::converged\n+bool converged\n+True if convergence criterion has been met.\n+Definition: solver.hh:73\n+Dune::InverseOperator<_X,_X_>\n+Dune::SolverCategory\n+Categories for the solvers.\n+Definition: solvercategory.hh:22\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n+Dune::InvalidSolverCategory\n+Definition: solvercategory.hh:54\n+Dune::UnsupportedType\n+Definition: solverregistry.hh:77\n+Dune::IsDirectSolver\n+Definition: solvertype.hh:16\n+Dune::SuperLU\n+SuperLu Solver.\n+Definition: superlu.hh:271\n+Dune::UMFPackMethodChooser\n+Definition: umfpack.hh:49\n+Dune::UMFPack\n+The UMFPack direct sparse solver.\n+Definition: umfpack.hh:215\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00191.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00191.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvercategory.hh File Reference\n+dune-istl: globalaggregates.hh File Reference\n \n \n \n \n \n \n \n@@ -58,41 +58,61 @@\n \n \n \n \n \n
    \n \n-
    solvercategory.hh File Reference
    \n+ \n
    \n
    \n-
    #include <dune/common/exceptions.hh>
    \n+\n+

    Provdes class for identifying aggregates globally. \n+More...

    \n+
    #include "aggregates.hh"
    \n+#include "pinfo.hh"
    \n+#include <dune/common/parallel/indexset.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n \n-\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::SolverCategory
     Categories for the solvers. More...
    struct  Dune::Amg::GlobalAggregatesMap< T, TI >
     
    class  Dune::Amg::GlobalAggregatesMap< T, TI >::Proxy
     
    struct  Dune::Amg::AggregatesGatherScatter< T, TI >
     
    struct  Dune::Amg::AggregatesPublisher< T, O, I >
     
    class  Dune::InvalidSolverCategory
    struct  Dune::Amg::AggregatesPublisher< T, O, OwnerOverlapCopyCommunication< T1, T2 > >
     Utility class for publishing the aggregate number of the DOFs in the overlap to other processors and convert them to local indices. More...
     
    struct  Dune::Amg::AggregatesPublisher< T, O, SequentialInformation >
     
    struct  Dune::CommPolicy< Amg::GlobalAggregatesMap< T, TI > >
     
    \n \n \n \n+\n+\n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n-
    \n+

    Detailed Description

    \n+

    Provdes class for identifying aggregates globally.

    \n+
    Author
    Markus Blatt
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,23 +4,47 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * paamg\n Classes | Namespaces\n-solvercategory.hh File Reference\n-#include \n+globalaggregates.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provdes class for identifying aggregates globally. More...\n+#include \"aggregates.hh\"\n+#include \"pinfo.hh\"\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::SolverCategory\n-\u00a0 Categories for the solvers. More...\n+struct \u00a0Dune::Amg::GlobalAggregatesMap<_T,_TI_>\n \u00a0\n- class \u00a0Dune::InvalidSolverCategory\n+ class \u00a0Dune::Amg::GlobalAggregatesMap<_T,_TI_>::Proxy\n+\u00a0\n+struct \u00a0Dune::Amg::AggregatesGatherScatter<_T,_TI_>\n+\u00a0\n+struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_I_>\n+\u00a0\n+struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<\n+ T1,_T2_>_>\n+\u00a0 Utility class for publishing the aggregate number of the DOFs in the\n+ overlap to other processors and convert them to local indices. More...\n+\u00a0\n+struct \u00a0Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>\n+\u00a0\n+struct \u00a0Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::Amg\n+\u00a0\n+***** Detailed Description *****\n+Provdes class for identifying aggregates globally.\n+ Author\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00191_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00191_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: solvercategory.hh Source File\n+dune-istl: globalaggregates.hh Source File\n \n \n \n \n \n \n \n@@ -58,75 +58,304 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n
    \n-
    solvercategory.hh
    \n+
    globalaggregates.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SOLVERCATEGORY_HH
    \n-
    6#define DUNE_ISTL_SOLVERCATEGORY_HH
    \n+
    5#ifndef DUNE_GLOBALAGGREGATES_HH
    \n+
    6#define DUNE_GLOBALAGGREGATES_HH
    \n
    7
    \n-
    8#include <dune/common/exceptions.hh>
    \n-
    9
    \n-
    10
    \n-
    11namespace Dune {
    \n-
    12
    \n-\n-
    22 {
    \n-
    23 enum Category {
    \n-\n-\n-\n-
    30 };
    \n-
    31
    \n-
    33 template<typename OP>
    \n-
    34 static Category category(const OP& op, decltype(op.category())* = nullptr)
    \n-
    35 {
    \n-
    36 return op.category();
    \n-
    37 }
    \n+
    18#include "aggregates.hh"
    \n+
    19#include "pinfo.hh"
    \n+
    20#include <dune/common/parallel/indexset.hh>
    \n+
    21
    \n+
    22namespace Dune
    \n+
    23{
    \n+
    24 namespace Amg
    \n+
    25 {
    \n+
    26
    \n+
    27 template<typename T, typename TI>
    \n+\n+
    29 {
    \n+
    30 public:
    \n+
    31 typedef TI ParallelIndexSet;
    \n+
    32
    \n+
    33 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n+
    34
    \n+
    35 typedef typename ParallelIndexSet::GlobalIndex IndexedType;
    \n+
    36
    \n+
    37 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
    \n
    38
    \n-
    39#ifndef DOXYGEN
    \n-
    40 // template<typename OP>
    \n-
    41 // static Category category(const OP& op, decltype(op.getSolverCategory())* = nullptr)
    \n-
    42 // {
    \n-
    43 // return op.getSolverCategory();
    \n-
    44 // }
    \n+
    39 typedef T Vertex;
    \n+
    40
    \n+\n+
    42 const GlobalLookupIndexSet<ParallelIndexSet>& indexset)
    \n+
    43 : aggregates_(aggregates), indexset_(indexset)
    \n+
    44 {}
    \n
    45
    \n-
    46 template<typename OP>
    \n-
    47 static Category category(const OP& op, decltype(op.category)* = nullptr)
    \n-
    48 {
    \n-
    49 return OP::category;
    \n-
    50 }
    \n-
    51#endif
    \n-
    52 };
    \n-
    53
    \n-
    54 class InvalidSolverCategory : public InvalidStateException{};
    \n-
    55
    \n-
    58} // end namespace
    \n+
    46 inline const GlobalIndex& operator[](std::size_t index) const
    \n+
    47 {
    \n+
    48 const Vertex& aggregate = aggregates_[index];
    \n+
    49 if(aggregate >= AggregatesMap<Vertex>::ISOLATED) {
    \n+
    50 assert(aggregate != AggregatesMap<Vertex>::UNAGGREGATED);
    \n+
    51 return isolatedMarker;
    \n+
    52 }else{
    \n+
    53 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
    \n+
    54 assert(pair!=0);
    \n+
    55 return pair->global();
    \n+
    56 }
    \n+
    57 }
    \n+
    58
    \n
    59
    \n-
    60#endif
    \n+
    60 inline GlobalIndex& get(std::size_t index)
    \n+
    61 {
    \n+
    62 const Vertex& aggregate = aggregates_[index];
    \n+
    63 assert(aggregate < AggregatesMap<Vertex>::ISOLATED);
    \n+
    64 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
    \n+
    65 assert(pair!=0);
    \n+
    66 return const_cast<GlobalIndex&>(pair->global());
    \n+
    67 }
    \n+
    68
    \n+
    69 class Proxy
    \n+
    70 {
    \n+
    71 public:
    \n+
    72 Proxy(const GlobalLookupIndexSet<ParallelIndexSet>& indexset, Vertex& aggregate)
    \n+
    73 : indexset_(&indexset), aggregate_(&aggregate)
    \n+
    74 {}
    \n+
    75
    \n+
    76 Proxy& operator=(const GlobalIndex& global)
    \n+
    77 {
    \n+
    78 if(global==isolatedMarker)
    \n+\n+
    80 else{
    \n+
    81 //assert(global < AggregatesMap<Vertex>::ISOLATED);
    \n+
    82 *aggregate_ = indexset_->operator[](global).local();
    \n+
    83 }
    \n+
    84 return *this;
    \n+
    85 }
    \n+
    86 private:
    \n+
    87 const GlobalLookupIndexSet<ParallelIndexSet>* indexset_;
    \n+
    88 Vertex* aggregate_;
    \n+
    89 };
    \n+
    90
    \n+
    91 inline Proxy operator[](std::size_t index)
    \n+
    92 {
    \n+
    93 return Proxy(indexset_, aggregates_[index]);
    \n+
    94 }
    \n+
    95
    \n+
    96 inline void put(const GlobalIndex& global, size_t i)
    \n+
    97 {
    \n+
    98 aggregates_[i]=indexset_[global].local();
    \n+
    99
    \n+
    100 }
    \n+
    101
    \n+
    102 private:
    \n+
    103 AggregatesMap<Vertex>& aggregates_;
    \n+
    104 const GlobalLookupIndexSet<ParallelIndexSet>& indexset_;
    \n+
    105 static const GlobalIndex isolatedMarker;
    \n+
    106 };
    \n+
    107
    \n+
    108 template<typename T, typename TI>
    \n+
    109 const typename TI::GlobalIndex GlobalAggregatesMap<T,TI>::isolatedMarker =
    \n+
    110 std::numeric_limits<typename TI::GlobalIndex>::max();
    \n+
    111
    \n+
    112 template<typename T, typename TI>
    \n+\n+
    114 {
    \n+\n+
    116 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
    \n+
    117
    \n+
    118 static const GlobalIndex& gather(const GlobalAggregatesMap<T,TI>& ga, size_t i)
    \n+
    119 {
    \n+
    120 return ga[i];
    \n+
    121 }
    \n+
    122
    \n+
    123 static void scatter(GlobalAggregatesMap<T,TI>& ga, GlobalIndex global, size_t i)
    \n+
    124 {
    \n+
    125 ga[i]=global;
    \n+
    126 }
    \n+
    127 };
    \n+
    128
    \n+
    129 template<typename T, typename O, typename I>
    \n+\n+
    131 {};
    \n+
    132
    \n+
    133#if HAVE_MPI
    \n+
    134
    \n+
    135#endif
    \n+
    136
    \n+
    137 } // namespace Amg
    \n+
    138
    \n+
    139#if HAVE_MPI
    \n+
    140 // forward declaration
    \n+
    141 template<class T1, class T2>
    \n+\n+
    143#endif
    \n+
    144
    \n+
    145 namespace Amg
    \n+
    146 {
    \n+
    147
    \n+
    148#if HAVE_MPI
    \n+
    158 template<typename T, typename O, typename T1, typename T2>
    \n+\n+
    160 {
    \n+
    161 typedef T Vertex;
    \n+
    162 typedef O OverlapFlags;
    \n+\n+\n+\n+
    166
    \n+
    167 static void publish(AggregatesMap<Vertex>& aggregates,
    \n+
    168 ParallelInformation& pinfo,
    \n+
    169 const GlobalLookupIndexSet& globalLookup)
    \n+
    170 {
    \n+\n+
    172 GlobalMap gmap(aggregates, globalLookup);
    \n+
    173 pinfo.copyOwnerToAll(gmap,gmap);
    \n+
    174 // communication only needed for ALU
    \n+
    175 // (ghosts with same global id as owners on the same process)
    \n+
    176 if (SolverCategory::category(pinfo) == static_cast<int>(SolverCategory::nonoverlapping))
    \n+
    177 pinfo.copyCopyToAll(gmap,gmap);
    \n+
    178
    \n+
    179 typedef typename ParallelInformation::RemoteIndices::const_iterator Lists;
    \n+
    180 Lists lists = pinfo.remoteIndices().find(pinfo.communicator().rank());
    \n+
    181 if(lists!=pinfo.remoteIndices().end()) {
    \n+
    182
    \n+
    183 // For periodic boundary conditions we must renumber
    \n+
    184 // the aggregates of vertices in the overlap whose owners are
    \n+
    185 // on the same process
    \n+
    186 Vertex maxAggregate =0;
    \n+
    187 typedef typename AggregatesMap<Vertex>::const_iterator Iter;
    \n+
    188 for(Iter i=aggregates.begin(), end=aggregates.end(); i!=end; ++i)
    \n+
    189 maxAggregate = std::max(maxAggregate, *i);
    \n+
    190
    \n+
    191 // Compute new mapping of aggregates in the overlap that we also own
    \n+
    192 std::map<Vertex,Vertex> newMapping;
    \n+
    193
    \n+
    194 // insert all elements into map
    \n+
    195 typedef typename ParallelInformation::RemoteIndices::RemoteIndexList
    \n+
    196 ::const_iterator RIter;
    \n+
    197 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end();
    \n+
    198 ri!=rend; ++ri)
    \n+
    199 if(O::contains(ri->localIndexPair().local().attribute()))
    \n+
    200 newMapping.insert(std::make_pair(aggregates[ri->localIndexPair().local()],
    \n+
    201 maxAggregate));
    \n+
    202 // renumber
    \n+
    203 typedef typename std::map<Vertex,Vertex>::iterator MIter;
    \n+
    204 for(MIter mi=newMapping.begin(), mend=newMapping.end();
    \n+
    205 mi != mend; ++mi)
    \n+
    206 mi->second=++maxAggregate;
    \n+
    207
    \n+
    208
    \n+
    209 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end();
    \n+
    210 ri!=rend; ++ri)
    \n+
    211 if(O::contains(ri->localIndexPair().local().attribute()))
    \n+
    212 aggregates[ri->localIndexPair().local()] =
    \n+
    213 newMapping[aggregates[ri->localIndexPair().local()]];
    \n+
    214 }
    \n+
    215 }
    \n+
    216 };
    \n+
    217#endif
    \n+
    218
    \n+
    219 template<typename T, typename O>
    \n+\n+
    221 {
    \n+
    222 typedef T Vertex;
    \n+\n+\n+
    225
    \n+
    226 static void publish([[maybe_unused]] AggregatesMap<Vertex>& aggregates,
    \n+
    227 [[maybe_unused]] ParallelInformation& pinfo,
    \n+
    228 [[maybe_unused]] const GlobalLookupIndexSet& globalLookup)
    \n+
    229 {}
    \n+
    230 };
    \n+
    231
    \n+
    232 } // end Amg namespace
    \n+
    233
    \n+
    234
    \n+
    235#if HAVE_MPI
    \n+
    236 template<typename T, typename TI>
    \n+
    237 struct CommPolicy<Amg::GlobalAggregatesMap<T,TI> >
    \n+
    238 {
    \n+\n+\n+
    241 typedef SizeOne IndexedTypeFlag;
    \n+
    242 static int getSize(const Type&, int)
    \n+
    243 {
    \n+
    244 return 1;
    \n+
    245 }
    \n+
    246 };
    \n+
    247#endif
    \n+
    248
    \n+
    249} // end Dune namespace
    \n+
    250 /* @} */
    \n+
    251#endif
    \n+
    Provides classes for the Coloring process of AMG.
    \n+\n+
    ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet
    Definition: globalaggregates.hh:164
    \n+
    const GlobalIndex & operator[](std::size_t index) const
    Definition: globalaggregates.hh:46
    \n+\n+
    static int getSize(const Type &, int)
    Definition: globalaggregates.hh:242
    \n+
    Amg::GlobalAggregatesMap< T, TI >::IndexedType IndexedType
    Definition: globalaggregates.hh:240
    \n+
    GlobalIndex & get(std::size_t index)
    Definition: globalaggregates.hh:60
    \n+\n+
    static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation &pinfo, const GlobalLookupIndexSet &globalLookup)
    Definition: globalaggregates.hh:226
    \n+
    SequentialInformation ParallelInformation
    Definition: globalaggregates.hh:223
    \n+
    ParallelIndexSet::GlobalIndex GlobalIndex
    Definition: globalaggregates.hh:33
    \n+
    ParallelInformation::ParallelIndexSet IndexSet
    Definition: globalaggregates.hh:165
    \n+
    void put(const GlobalIndex &global, size_t i)
    Definition: globalaggregates.hh:96
    \n+
    T Vertex
    Definition: globalaggregates.hh:39
    \n+
    GlobalAggregatesMap(AggregatesMap< Vertex > &aggregates, const GlobalLookupIndexSet< ParallelIndexSet > &indexset)
    Definition: globalaggregates.hh:41
    \n+
    TI ParallelIndexSet
    Definition: globalaggregates.hh:31
    \n+
    Amg::AggregatesMap< T > Type
    Definition: globalaggregates.hh:239
    \n+
    static void scatter(GlobalAggregatesMap< T, TI > &ga, GlobalIndex global, size_t i)
    Definition: globalaggregates.hh:123
    \n+
    OwnerOverlapCopyCommunication< T1, T2 > ParallelInformation
    Definition: globalaggregates.hh:163
    \n+
    const_iterator begin() const
    Definition: aggregates.hh:725
    \n+
    SizeOne IndexedTypeFlag
    Definition: globalaggregates.hh:241
    \n+
    Proxy(const GlobalLookupIndexSet< ParallelIndexSet > &indexset, Vertex &aggregate)
    Definition: globalaggregates.hh:72
    \n+
    const_iterator end() const
    Definition: aggregates.hh:730
    \n+
    static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation &pinfo, const GlobalLookupIndexSet &globalLookup)
    Definition: globalaggregates.hh:167
    \n+
    ParallelIndexSet::GlobalIndex GlobalIndex
    Definition: globalaggregates.hh:116
    \n+
    ParallelIndexSet::LocalIndex LocalIndex
    Definition: globalaggregates.hh:37
    \n+
    TI ParallelIndexSet
    Definition: globalaggregates.hh:115
    \n+\n+
    ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet
    Definition: globalaggregates.hh:224
    \n+
    static const GlobalIndex & gather(const GlobalAggregatesMap< T, TI > &ga, size_t i)
    Definition: globalaggregates.hh:118
    \n+
    Proxy & operator=(const GlobalIndex &global)
    Definition: globalaggregates.hh:76
    \n+
    ParallelIndexSet::GlobalIndex IndexedType
    Definition: globalaggregates.hh:35
    \n+
    Proxy operator[](std::size_t index)
    Definition: globalaggregates.hh:91
    \n
    Definition: allocator.hh:11
    \n-
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n+
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n+
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n+
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n+
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n+
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n+
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n+\n+
    Definition: globalaggregates.hh:29
    \n+
    Definition: globalaggregates.hh:70
    \n+
    Definition: globalaggregates.hh:114
    \n+
    Definition: globalaggregates.hh:131
    \n+
    Definition: pinfo.hh:28
    \n+
    int GlobalLookupIndexSet
    Definition: pinfo.hh:54
    \n
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n-
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n-
    Definition: solvercategory.hh:54
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,87 +4,421 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-solvercategory.hh\n+ * paamg\n+globalaggregates.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SOLVERCATEGORY_HH\n- 6#define DUNE_ISTL_SOLVERCATEGORY_HH\n+ 5#ifndef DUNE_GLOBALAGGREGATES_HH\n+ 6#define DUNE_GLOBALAGGREGATES_HH\n 7\n- 8#include \n- 9\n- 10\n- 11namespace Dune {\n- 12\n-21 struct SolverCategory\n- 22 {\n-23 enum Category {\n-25 sequential,\n-27 nonoverlapping,\n- 29 overlapping\n-30 };\n- 31\n- 33 template\n-34 static Category category(const OP& op, decltype(op.category())* = nullptr)\n- 35 {\n- 36 return op.category();\n- 37 }\n+ 18#include \"aggregates.hh\"\n+ 19#include \"pinfo.hh\"\n+ 20#include \n+ 21\n+ 22namespace Dune\n+ 23{\n+ 24 namespace Amg\n+ 25 {\n+ 26\n+ 27 template\n+28 struct GlobalAggregatesMap\n+ 29 {\n+ 30 public:\n+31 typedef TI ParallelIndexSet;\n+ 32\n+33 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n+ 34\n+35 typedef typename ParallelIndexSet::GlobalIndex IndexedType;\n+ 36\n+37 typedef typename ParallelIndexSet::LocalIndex LocalIndex;\n 38\n- 39#ifndef DOXYGEN\n- 40 // template\n- 41 // static Category category(const OP& op, decltype(op.getSolverCategory())*\n-= nullptr)\n- 42 // {\n- 43 // return op.getSolverCategory();\n- 44 // }\n+39 typedef T Vertex;\n+ 40\n+41 GlobalAggregatesMap(AggregatesMap& aggregates,\n+ 42 const GlobalLookupIndexSet& indexset)\n+ 43 : aggregates_(aggregates), indexset_(indexset)\n+ 44 {}\n 45\n- 46 template\n- 47 static Category category(const OP& op, decltype(op.category)* = nullptr)\n- 48 {\n- 49 return OP::category;\n- 50 }\n- 51#endif\n- 52 };\n- 53\n-54 class InvalidSolverCategory : public InvalidStateException{};\n- 55\n- 58} // end namespace\n+46 inline const GlobalIndex& operator[](std::size_t index) const\n+ 47 {\n+ 48 const Vertex& aggregate = aggregates_[index];\n+ 49 if(aggregate >= AggregatesMap::ISOLATED) {\n+ 50 assert(aggregate != AggregatesMap::UNAGGREGATED);\n+ 51 return isolatedMarker;\n+ 52 }else{\n+ 53 const Dune::IndexPair* pair = indexset_.pair\n+(aggregate);\n+ 54 assert(pair!=0);\n+ 55 return pair->global();\n+ 56 }\n+ 57 }\n+ 58\n 59\n- 60#endif\n+60 inline GlobalIndex& get(std::size_t index)\n+ 61 {\n+ 62 const Vertex& aggregate = aggregates_[index];\n+ 63 assert(aggregate < AggregatesMap::ISOLATED);\n+ 64 const Dune::IndexPair* pair = indexset_.pair\n+(aggregate);\n+ 65 assert(pair!=0);\n+ 66 return const_cast(pair->global());\n+ 67 }\n+ 68\n+69 class Proxy\n+ 70 {\n+ 71 public:\n+72 Proxy(const GlobalLookupIndexSet& indexset, Vertex&\n+aggregate)\n+ 73 : indexset_(&indexset), aggregate_(&aggregate)\n+ 74 {}\n+ 75\n+76 Proxy& operator=(const GlobalIndex& global)\n+ 77 {\n+ 78 if(global==isolatedMarker)\n+ 79 *aggregate_ = AggregatesMap::ISOLATED;\n+ 80 else{\n+ 81 //assert(global < AggregatesMap::ISOLATED);\n+ 82 *aggregate_ = indexset_->operator[](global).local();\n+ 83 }\n+ 84 return *this;\n+ 85 }\n+ 86 private:\n+ 87 const GlobalLookupIndexSet* indexset_;\n+ 88 Vertex* aggregate_;\n+ 89 };\n+ 90\n+91 inline Proxy operator[](std::size_t index)\n+ 92 {\n+ 93 return Proxy(indexset_, aggregates_[index]);\n+ 94 }\n+ 95\n+96 inline void put(const GlobalIndex& global, size_t i)\n+ 97 {\n+ 98 aggregates_[i]=indexset_[global].local();\n+ 99\n+ 100 }\n+ 101\n+ 102 private:\n+ 103 AggregatesMap& aggregates_;\n+ 104 const GlobalLookupIndexSet& indexset_;\n+ 105 static const GlobalIndex isolatedMarker;\n+ 106 };\n+ 107\n+ 108 template\n+ 109 const typename TI::GlobalIndex GlobalAggregatesMap::isolatedMarker =\n+ 110 std::numeric_limits::max();\n+ 111\n+ 112 template\n+113 struct AggregatesGatherScatter\n+ 114 {\n+115 typedef TI ParallelIndexSet;\n+116 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;\n+ 117\n+118 static const GlobalIndex& gather(const GlobalAggregatesMap& ga,\n+size_t i)\n+ 119 {\n+ 120 return ga[i];\n+ 121 }\n+ 122\n+123 static void scatter(GlobalAggregatesMap& ga, GlobalIndex global,\n+size_t i)\n+ 124 {\n+ 125 ga[i]=global;\n+ 126 }\n+ 127 };\n+ 128\n+ 129 template\n+130 struct AggregatesPublisher\n+ 131 {};\n+ 132\n+ 133#if HAVE_MPI\n+ 134\n+ 135#endif\n+ 136\n+ 137 } // namespace Amg\n+ 138\n+ 139#if HAVE_MPI\n+ 140 // forward declaration\n+ 141 template\n+ 142 class OwnerOverlapCopyCommunication;\n+ 143#endif\n+ 144\n+ 145 namespace Amg\n+ 146 {\n+ 147\n+ 148#if HAVE_MPI\n+ 158 template\n+159 struct AggregatesPublisher >\n+ 160 {\n+161 typedef T Vertex;\n+162 typedef O OverlapFlags;\n+163 typedef OwnerOverlapCopyCommunication ParallelInformation;\n+164 typedef typename ParallelInformation::GlobalLookupIndexSet\n+GlobalLookupIndexSet;\n+165 typedef typename ParallelInformation::ParallelIndexSet IndexSet;\n+ 166\n+167 static void publish(AggregatesMap& aggregates,\n+ 168 ParallelInformation& pinfo,\n+ 169 const GlobalLookupIndexSet& globalLookup)\n+ 170 {\n+ 171 typedef Dune::Amg::GlobalAggregatesMap GlobalMap;\n+ 172 GlobalMap gmap(aggregates, globalLookup);\n+ 173 pinfo.copyOwnerToAll(gmap,gmap);\n+ 174 // communication only needed for ALU\n+ 175 // (ghosts with same global id as owners on the same process)\n+ 176 if (SolverCategory::category(pinfo) == static_cast(SolverCategory::\n+nonoverlapping))\n+ 177 pinfo.copyCopyToAll(gmap,gmap);\n+ 178\n+ 179 typedef typename ParallelInformation::RemoteIndices::const_iterator Lists;\n+ 180 Lists lists = pinfo.remoteIndices().find(pinfo.communicator().rank());\n+ 181 if(lists!=pinfo.remoteIndices().end()) {\n+ 182\n+ 183 // For periodic boundary conditions we must renumber\n+ 184 // the aggregates of vertices in the overlap whose owners are\n+ 185 // on the same process\n+ 186 Vertex maxAggregate =0;\n+ 187 typedef typename AggregatesMap::const_iterator Iter;\n+ 188 for(Iter i=aggregates.begin(), end=aggregates.end(); i!=end; ++i)\n+ 189 maxAggregate = std::max(maxAggregate, *i);\n+ 190\n+ 191 // Compute new mapping of aggregates in the overlap that we also own\n+ 192 std::map newMapping;\n+ 193\n+ 194 // insert all elements into map\n+ 195 typedef typename ParallelInformation::RemoteIndices::RemoteIndexList\n+ 196 ::const_iterator RIter;\n+ 197 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end\n+();\n+ 198 ri!=rend; ++ri)\n+ 199 if(O::contains(ri->localIndexPair().local().attribute()))\n+ 200 newMapping.insert(std::make_pair(aggregates[ri->localIndexPair().local()],\n+ 201 maxAggregate));\n+ 202 // renumber\n+ 203 typedef typename std::map::iterator MIter;\n+ 204 for(MIter mi=newMapping.begin(), mend=newMapping.end();\n+ 205 mi != mend; ++mi)\n+ 206 mi->second=++maxAggregate;\n+ 207\n+ 208\n+ 209 for(RIter ri=lists->second.first->begin(), rend = lists->second.first->end\n+();\n+ 210 ri!=rend; ++ri)\n+ 211 if(O::contains(ri->localIndexPair().local().attribute()))\n+ 212 aggregates[ri->localIndexPair().local()] =\n+ 213 newMapping[aggregates[ri->localIndexPair().local()]];\n+ 214 }\n+ 215 }\n+ 216 };\n+ 217#endif\n+ 218\n+ 219 template\n+220 struct AggregatesPublisher\n+ 221 {\n+222 typedef T Vertex;\n+223 typedef SequentialInformation ParallelInformation;\n+224 typedef typename ParallelInformation::GlobalLookupIndexSet\n+GlobalLookupIndexSet;\n+ 225\n+226 static void publish([[maybe_unused]] AggregatesMap& aggregates,\n+ 227 [[maybe_unused]] ParallelInformation& pinfo,\n+ 228 [[maybe_unused]] const GlobalLookupIndexSet& globalLookup)\n+ 229 {}\n+ 230 };\n+ 231\n+ 232 } // end Amg namespace\n+ 233\n+ 234\n+ 235#if HAVE_MPI\n+ 236 template\n+237 struct CommPolicy >\n+ 238 {\n+239 typedef Amg::AggregatesMap Type;\n+240 typedef typename Amg::GlobalAggregatesMap::IndexedType IndexedType;\n+241 typedef SizeOne IndexedTypeFlag;\n+242 static int getSize(const Type&, int)\n+ 243 {\n+ 244 return 1;\n+ 245 }\n+ 246 };\n+ 247#endif\n+ 248\n+ 249} // end Dune namespace\n+ 250 /* @} */\n+ 251#endif\n+aggregates.hh\n+Provides classes for the Coloring process of AMG.\n+pinfo.hh\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::GlobalLookupIndexSet\n+ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet\n+Definition: globalaggregates.hh:164\n+Dune::Amg::GlobalAggregatesMap::operator[]\n+const GlobalIndex & operator[](std::size_t index) const\n+Definition: globalaggregates.hh:46\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::OverlapFlags\n+O OverlapFlags\n+Definition: globalaggregates.hh:162\n+Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::getSize\n+static int getSize(const Type &, int)\n+Definition: globalaggregates.hh:242\n+Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::IndexedType\n+Amg::GlobalAggregatesMap< T, TI >::IndexedType IndexedType\n+Definition: globalaggregates.hh:240\n+Dune::Amg::GlobalAggregatesMap::get\n+GlobalIndex & get(std::size_t index)\n+Definition: globalaggregates.hh:60\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::Vertex\n+T Vertex\n+Definition: globalaggregates.hh:161\n+Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::publish\n+static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation\n+&pinfo, const GlobalLookupIndexSet &globalLookup)\n+Definition: globalaggregates.hh:226\n+Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::\n+ParallelInformation\n+SequentialInformation ParallelInformation\n+Definition: globalaggregates.hh:223\n+Dune::Amg::GlobalAggregatesMap::GlobalIndex\n+ParallelIndexSet::GlobalIndex GlobalIndex\n+Definition: globalaggregates.hh:33\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::IndexSet\n+ParallelInformation::ParallelIndexSet IndexSet\n+Definition: globalaggregates.hh:165\n+Dune::Amg::GlobalAggregatesMap::put\n+void put(const GlobalIndex &global, size_t i)\n+Definition: globalaggregates.hh:96\n+Dune::Amg::GlobalAggregatesMap::Vertex\n+T Vertex\n+Definition: globalaggregates.hh:39\n+Dune::Amg::GlobalAggregatesMap::GlobalAggregatesMap\n+GlobalAggregatesMap(AggregatesMap< Vertex > &aggregates, const\n+GlobalLookupIndexSet< ParallelIndexSet > &indexset)\n+Definition: globalaggregates.hh:41\n+Dune::Amg::GlobalAggregatesMap::ParallelIndexSet\n+TI ParallelIndexSet\n+Definition: globalaggregates.hh:31\n+Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::Type\n+Amg::AggregatesMap< T > Type\n+Definition: globalaggregates.hh:239\n+Dune::Amg::AggregatesGatherScatter::scatter\n+static void scatter(GlobalAggregatesMap< T, TI > &ga, GlobalIndex global,\n+size_t i)\n+Definition: globalaggregates.hh:123\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::ParallelInformation\n+OwnerOverlapCopyCommunication< T1, T2 > ParallelInformation\n+Definition: globalaggregates.hh:163\n+Dune::Amg::AggregatesMap::begin\n+const_iterator begin() const\n+Definition: aggregates.hh:725\n+Dune::CommPolicy<_Amg::GlobalAggregatesMap<_T,_TI_>_>::IndexedTypeFlag\n+SizeOne IndexedTypeFlag\n+Definition: globalaggregates.hh:241\n+Dune::Amg::GlobalAggregatesMap::Proxy::Proxy\n+Proxy(const GlobalLookupIndexSet< ParallelIndexSet > &indexset, Vertex\n+&aggregate)\n+Definition: globalaggregates.hh:72\n+Dune::Amg::AggregatesMap::end\n+const_iterator end() const\n+Definition: aggregates.hh:730\n+Dune::Amg::AggregatesPublisher<_T,_O,_OwnerOverlapCopyCommunication<_T1,_T2_>\n+>::publish\n+static void publish(AggregatesMap< Vertex > &aggregates, ParallelInformation\n+&pinfo, const GlobalLookupIndexSet &globalLookup)\n+Definition: globalaggregates.hh:167\n+Dune::Amg::AggregatesGatherScatter::GlobalIndex\n+ParallelIndexSet::GlobalIndex GlobalIndex\n+Definition: globalaggregates.hh:116\n+Dune::Amg::GlobalAggregatesMap::LocalIndex\n+ParallelIndexSet::LocalIndex LocalIndex\n+Definition: globalaggregates.hh:37\n+Dune::Amg::AggregatesGatherScatter::ParallelIndexSet\n+TI ParallelIndexSet\n+Definition: globalaggregates.hh:115\n+Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::Vertex\n+T Vertex\n+Definition: globalaggregates.hh:222\n+Dune::Amg::AggregatesPublisher<_T,_O,_SequentialInformation_>::\n+GlobalLookupIndexSet\n+ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet\n+Definition: globalaggregates.hh:224\n+Dune::Amg::AggregatesGatherScatter::gather\n+static const GlobalIndex & gather(const GlobalAggregatesMap< T, TI > &ga,\n+size_t i)\n+Definition: globalaggregates.hh:118\n+Dune::Amg::GlobalAggregatesMap::Proxy::operator=\n+Proxy & operator=(const GlobalIndex &global)\n+Definition: globalaggregates.hh:76\n+Dune::Amg::GlobalAggregatesMap::IndexedType\n+ParallelIndexSet::GlobalIndex IndexedType\n+Definition: globalaggregates.hh:35\n+Dune::Amg::GlobalAggregatesMap::operator[]\n+Proxy operator[](std::size_t index)\n+Definition: globalaggregates.hh:91\n Dune\n Definition: allocator.hh:11\n-Dune::SolverCategory\n-Categories for the solvers.\n-Definition: solvercategory.hh:22\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n+Dune::OwnerOverlapCopyCommunication\n+A class setting up standard communication for a two-valued attribute set with\n+owner/overlap/copy sema...\n+Definition: owneroverlapcopy.hh:174\n+Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n+void copyCopyToAll(const T &source, T &dest) const\n+Communicate values from copy data points to all other data points.\n+Definition: owneroverlapcopy.hh:328\n+Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n+Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n+The type of the reverse lookup of indices.\n+Definition: owneroverlapcopy.hh:456\n+Dune::OwnerOverlapCopyCommunication::communicator\n+const Communication< MPI_Comm > & communicator() const\n+Definition: owneroverlapcopy.hh:299\n+Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n+void copyOwnerToAll(const T &source, T &dest) const\n+Communicate values from owner data points to all other data points.\n+Definition: owneroverlapcopy.hh:311\n+Dune::OwnerOverlapCopyCommunication::remoteIndices\n+const RemoteIndices & remoteIndices() const\n+Get the underlying remote indices.\n+Definition: owneroverlapcopy.hh:471\n+Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n+Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n+The type of the parallel index set.\n+Definition: owneroverlapcopy.hh:449\n+Dune::Amg::AggregatesMap<_Vertex_>\n+Dune::Amg::GlobalAggregatesMap\n+Definition: globalaggregates.hh:29\n+Dune::Amg::GlobalAggregatesMap::Proxy\n+Definition: globalaggregates.hh:70\n+Dune::Amg::AggregatesGatherScatter\n+Definition: globalaggregates.hh:114\n+Dune::Amg::AggregatesPublisher\n+Definition: globalaggregates.hh:131\n+Dune::Amg::SequentialInformation\n+Definition: pinfo.hh:28\n+Dune::Amg::SequentialInformation::GlobalLookupIndexSet\n+int GlobalLookupIndexSet\n+Definition: pinfo.hh:54\n Dune::SolverCategory::nonoverlapping\n @ nonoverlapping\n Category for non-overlapping solvers.\n Definition: solvercategory.hh:27\n-Dune::SolverCategory::overlapping\n-@ overlapping\n-Category for overlapping solvers.\n-Definition: solvercategory.hh:29\n Dune::SolverCategory::category\n static Category category(const OP &op, decltype(op.category()) *=nullptr)\n Helperfunction to extract the solver category either from an enum, or from the\n newly introduced virtu...\n Definition: solvercategory.hh:34\n-Dune::InvalidSolverCategory\n-Definition: solvercategory.hh:54\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00194.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00194.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: umfpack.hh File Reference\n+dune-istl: kamg.hh File Reference\n \n \n \n \n \n \n \n@@ -58,77 +58,51 @@\n \n \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n \n \n+ \n \n
    \n \n-

    Classes for using UMFPack with ISTL matrices. \n+

    Provides an algebraic multigrid using a Krylov cycle. \n More...

    \n-
    #include <complex>
    \n-#include <type_traits>
    \n-#include <umfpack.h>
    \n-#include <dune/common/exceptions.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/istl/bccsmatrixinitializer.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/solvers.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n-#include <dune/istl/solverfactory.hh>
    \n+
    #include <dune/istl/preconditioners.hh>
    \n+#include "amg.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    struct  Dune::UMFPackMethodChooser< T >
    class  Dune::Amg::KAmgTwoGrid< AMG >
     Two grid operator for AMG with Krylov cycle. More...
     
    struct  Dune::UMFPackMethodChooser< double >
     
    struct  Dune::UMFPackMethodChooser< std::complex< double > >
     
    class  Dune::UMFPack< M >
     The UMFPack direct sparse solver. More...
     
    struct  Dune::IsDirectSolver< UMFPack< BCRSMatrix< FieldMatrix< T, n, m >, A > > >
     
    struct  Dune::StoresColumnCompressed< UMFPack< BCRSMatrix< T, A > > >
     
    struct  Dune::UMFPackCreator
     
    struct  Dune::UMFPackCreator::isValidBlock< F, class >
     
    struct  Dune::UMFPackCreator::isValidBlock< B, std::enable_if_t< std::is_same< typename FieldTraits< B >::real_type, double >::value > >
    class  Dune::Amg::KAMG< M, X, S, PI, K, A >
     an algebraic multigrid method using a Krylov-cycle. More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n+\n+\n

    \n-Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("umfpack", Dune::UMFPackCreator())
     
    namespace  Dune::Amg
     
    \n

    Detailed Description

    \n-

    Classes for using UMFPack with ISTL matrices.

    \n-
    Author
    Dominic Kempf
    \n+

    Provides an algebraic multigrid using a Krylov cycle.

    \n+
    Author
    Markus Blatt
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,58 +4,35 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-umfpack.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL)\n-Classes for using UMFPack with ISTL matrices. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+ * paamg\n+Classes | Namespaces\n+kamg.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+\u00bb Parallel_Algebraic_Multigrid\n+Provides an algebraic multigrid using a Krylov cycle. More...\n+#include \n+#include \"amg.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::UMFPackMethodChooser<_T_>\n+class \u00a0Dune::Amg::KAmgTwoGrid<_AMG_>\n+\u00a0 Two grid operator for AMG with Krylov cycle. More...\n \u00a0\n-struct \u00a0Dune::UMFPackMethodChooser<_double_>\n-\u00a0\n-struct \u00a0Dune::UMFPackMethodChooser<_std::complex<_double_>_>\n-\u00a0\n- class \u00a0Dune::UMFPack<_M_>\n-\u00a0 The UMFPack direct sparse solver. More...\n-\u00a0\n-struct \u00a0Dune::IsDirectSolver<_UMFPack<_BCRSMatrix<_FieldMatrix<_T,_n,_m_>,_A_>\n- >_>\n-\u00a0\n-struct \u00a0Dune::StoresColumnCompressed<_UMFPack<_BCRSMatrix<_T,_A_>_>_>\n-\u00a0\n-struct \u00a0Dune::UMFPackCreator\n-\u00a0\n-struct \u00a0Dune::UMFPackCreator::isValidBlock<_F,_class_>\n-\u00a0\n-struct \u00a0Dune::UMFPackCreator::isValidBlock<_B,_std::enable_if_t<_std::is_same<\n- typename_FieldTraits<_B_>::real_type,_double_>::value_>_>\n+class \u00a0Dune::Amg::KAMG<_M,_X,_S,_PI,_K,_A_>\n+\u00a0 an algebraic multigrid method using a Krylov-cycle. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"umfpack\", Dune::UMFPackCreator())\n+namespace \u00a0Dune::Amg\n \u00a0\n ***** Detailed Description *****\n-Classes for using UMFPack with ISTL matrices.\n+Provides an algebraic multigrid using a Krylov cycle.\n Author\n- Dominic Kempf\n+ Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00194_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00194_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: umfpack.hh Source File\n+dune-istl: kamg.hh Source File\n \n \n \n \n \n \n \n@@ -58,618 +58,302 @@\n \n
    \n \n
    \n \n+
  • dune
  • istl
  • paamg
  • \n
    \n
    \n
    \n-
    umfpack.hh
    \n+
    kamg.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_UMFPACK_HH
    \n-
    6#define DUNE_ISTL_UMFPACK_HH
    \n+
    5#ifndef DUNE_AMG_KAMG_HH
    \n+
    6#define DUNE_AMG_KAMG_HH
    \n
    7
    \n-
    8#if HAVE_SUITESPARSE_UMFPACK || defined DOXYGEN
    \n-
    9
    \n-
    10#include<complex>
    \n-
    11#include<type_traits>
    \n-
    12
    \n-
    13#include<umfpack.h>
    \n-
    14
    \n-
    15#include<dune/common/exceptions.hh>
    \n-
    16#include<dune/common/fmatrix.hh>
    \n-
    17#include<dune/common/fvector.hh>
    \n-\n-\n-\n-\n-\n-
    23
    \n-
    24
    \n-
    25
    \n-
    26namespace Dune {
    \n-
    38 // FORWARD DECLARATIONS
    \n-
    39 template<class M, class T, class TM, class TD, class TA>
    \n-
    40 class SeqOverlappingSchwarz;
    \n-
    41
    \n-
    42 template<class T, bool tag>
    \n-
    43 struct SeqOverlappingSchwarzAssemblerHelper;
    \n-
    44
    \n-
    45 // wrapper class for C-Function Calls in the backend. Choose the right function namespace
    \n-
    46 // depending on the template parameter used.
    \n-
    47 template<typename T>
    \n-\n-
    49 {
    \n-
    50 static constexpr bool valid = false ;
    \n-
    51 };
    \n-
    52
    \n-
    53 template<>
    \n-
    54 struct UMFPackMethodChooser<double>
    \n-
    55 {
    \n-
    56 static constexpr bool valid = true ;
    \n-
    57
    \n-
    58 template<typename... A>
    \n-
    59 static void defaults(A... args)
    \n-
    60 {
    \n-
    61 umfpack_dl_defaults(args...);
    \n-
    62 }
    \n-
    63 template<typename... A>
    \n-
    64 static void free_numeric(A... args)
    \n-
    65 {
    \n-
    66 umfpack_dl_free_numeric(args...);
    \n-
    67 }
    \n-
    68 template<typename... A>
    \n-
    69 static void free_symbolic(A... args)
    \n-
    70 {
    \n-
    71 umfpack_dl_free_symbolic(args...);
    \n-
    72 }
    \n-
    73 template<typename... A>
    \n-
    74 static int load_numeric(A... args)
    \n-
    75 {
    \n-
    76 return umfpack_dl_load_numeric(args...);
    \n-
    77 }
    \n-
    78 template<typename... A>
    \n-
    79 static void numeric(A... args)
    \n-
    80 {
    \n-
    81 umfpack_dl_numeric(args...);
    \n-
    82 }
    \n-
    83 template<typename... A>
    \n-
    84 static void report_info(A... args)
    \n-
    85 {
    \n-
    86 umfpack_dl_report_info(args...);
    \n-
    87 }
    \n-
    88 template<typename... A>
    \n-
    89 static void report_status(A... args)
    \n-
    90 {
    \n-
    91 umfpack_dl_report_status(args...);
    \n-
    92 }
    \n-
    93 template<typename... A>
    \n-
    94 static int save_numeric(A... args)
    \n-
    95 {
    \n-
    96 return umfpack_dl_save_numeric(args...);
    \n-
    97 }
    \n-
    98 template<typename... A>
    \n-
    99 static void solve(A... args)
    \n-
    100 {
    \n-
    101 umfpack_dl_solve(args...);
    \n-
    102 }
    \n-
    103 template<typename... A>
    \n-
    104 static void symbolic(A... args)
    \n-
    105 {
    \n-
    106 umfpack_dl_symbolic(args...);
    \n-
    107 }
    \n-
    108 };
    \n-
    109
    \n-
    110 template<>
    \n-
    111 struct UMFPackMethodChooser<std::complex<double> >
    \n-
    112 {
    \n-
    113 static constexpr bool valid = true ;
    \n-
    114
    \n-
    115 template<typename... A>
    \n-
    116 static void defaults(A... args)
    \n-
    117 {
    \n-
    118 umfpack_zl_defaults(args...);
    \n-
    119 }
    \n-
    120 template<typename... A>
    \n-
    121 static void free_numeric(A... args)
    \n-
    122 {
    \n-
    123 umfpack_zl_free_numeric(args...);
    \n-
    124 }
    \n-
    125 template<typename... A>
    \n-
    126 static void free_symbolic(A... args)
    \n-
    127 {
    \n-
    128 umfpack_zl_free_symbolic(args...);
    \n-
    129 }
    \n-
    130 template<typename... A>
    \n-
    131 static int load_numeric(A... args)
    \n-
    132 {
    \n-
    133 return umfpack_zl_load_numeric(args...);
    \n-
    134 }
    \n-
    135 template<typename... A>
    \n-
    136 static void numeric(const long int* cs, const long int* ri, const double* val, A... args)
    \n-
    137 {
    \n-
    138 umfpack_zl_numeric(cs,ri,val,NULL,args...);
    \n-
    139 }
    \n-
    140 template<typename... A>
    \n-
    141 static void report_info(A... args)
    \n-
    142 {
    \n-
    143 umfpack_zl_report_info(args...);
    \n-
    144 }
    \n-
    145 template<typename... A>
    \n-
    146 static void report_status(A... args)
    \n-
    147 {
    \n-
    148 umfpack_zl_report_status(args...);
    \n-
    149 }
    \n-
    150 template<typename... A>
    \n-
    151 static int save_numeric(A... args)
    \n-
    152 {
    \n-
    153 return umfpack_zl_save_numeric(args...);
    \n-
    154 }
    \n-
    155 template<typename... A>
    \n-
    156 static void solve(long int m, const long int* cs, const long int* ri, std::complex<double>* val, double* x, const double* b,A... args)
    \n-
    157 {
    \n-
    158 const double* cval = reinterpret_cast<const double*>(val);
    \n-
    159 umfpack_zl_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);
    \n-
    160 }
    \n-
    161 template<typename... A>
    \n-
    162 static void symbolic(long int m, long int n, const long int* cs, const long int* ri, const double* val, A... args)
    \n-
    163 {
    \n-
    164 umfpack_zl_symbolic(m,n,cs,ri,val,NULL,args...);
    \n-
    165 }
    \n-
    166 };
    \n-
    167
    \n-
    168 namespace Impl
    \n-
    169 {
    \n-
    170 template<class M>
    \n-
    171 struct UMFPackVectorChooser
    \n-
    172 {};
    \n-
    173
    \n-
    174 template<typename T, typename A, int n, int m>
    \n-
    175 struct UMFPackVectorChooser<BCRSMatrix<FieldMatrix<T,n,m>,A > >
    \n-
    176 {
    \n-
    178 using domain_type = BlockVector<
    \n-
    179 FieldVector<T,m>,
    \n-
    180 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,m> > >;
    \n-
    182 using range_type = BlockVector<
    \n-
    183 FieldVector<T,n>,
    \n-
    184 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,n> > >;
    \n-
    185 };
    \n-
    186
    \n-
    187 template<typename T, typename A>
    \n-
    188 struct UMFPackVectorChooser<BCRSMatrix<T,A> >
    \n-
    189 {
    \n-
    191 using domain_type = BlockVector<T, A>;
    \n-
    193 using range_type = BlockVector<T, A>;
    \n-
    194 };
    \n-
    195 }
    \n-
    196
    \n-
    210 template<typename M>
    \n-\n-
    212 : public InverseOperator<
    \n-
    213 typename Impl::UMFPackVectorChooser<M>::domain_type,
    \n-
    214 typename Impl::UMFPackVectorChooser<M>::range_type >
    \n-
    215 {
    \n-
    216 using T = typename M::field_type;
    \n+\n+
    9#include "amg.hh"
    \n+
    10
    \n+
    11namespace Dune
    \n+
    12{
    \n+
    13 namespace Amg
    \n+
    14 {
    \n+
    15
    \n+
    30 template<class AMG>
    \n+\n+
    32 : public Preconditioner<typename AMG::Domain,typename AMG::Range>
    \n+
    33 {
    \n+
    35 typedef typename AMG::Domain Domain;
    \n+
    37 typedef typename AMG::Range Range;
    \n+
    38 public:
    \n+
    39
    \n+\n+
    42 {
    \n+
    43 return amg_.category();
    \n+
    44 };
    \n+
    45
    \n+\n+
    54 : amg_(amg), coarseSolver_(coarseSolver)
    \n+
    55 {}
    \n+
    56
    \n+
    58 void pre([[maybe_unused]] typename AMG::Domain& x, [[maybe_unused]] typename AMG::Range& b)
    \n+
    59 {}
    \n+
    60
    \n+
    62 void post([[maybe_unused]] typename AMG::Domain& x)
    \n+
    63 {}
    \n+
    64
    \n+
    66 void apply(typename AMG::Domain& v, const typename AMG::Range& d)
    \n+
    67 {
    \n+
    68 // Copy data
    \n+
    69 *levelContext_->update=0;
    \n+
    70 *levelContext_->rhs = d;
    \n+
    71 *levelContext_->lhs = v;
    \n+
    72
    \n+
    73 presmooth(*levelContext_, amg_.preSteps_);
    \n+
    74 bool processFineLevel =
    \n+
    75 amg_.moveToCoarseLevel(*levelContext_);
    \n+
    76
    \n+
    77 if(processFineLevel) {
    \n+
    78 typename AMG::Range b=*levelContext_->rhs;
    \n+
    79 typename AMG::Domain x=*levelContext_->update;
    \n+\n+
    81 coarseSolver_->apply(x, b, res);
    \n+
    82 *levelContext_->update=x;
    \n+
    83 }
    \n+
    84
    \n+
    85 amg_.moveToFineLevel(*levelContext_, processFineLevel);
    \n+
    86
    \n+
    87 postsmooth(*levelContext_, amg_.postSteps_);
    \n+
    88 v=*levelContext_->update;
    \n+
    89 }
    \n+
    90
    \n+\n+
    96 {
    \n+
    97 return coarseSolver_;
    \n+
    98 }
    \n+
    99
    \n+
    104 void setLevelContext(std::shared_ptr<typename AMG::LevelContext> p)
    \n+
    105 {
    \n+
    106 levelContext_=p;
    \n+
    107 }
    \n+
    108
    \n+\n+
    111 {}
    \n+
    112
    \n+
    113 private:
    \n+
    115 AMG& amg_;
    \n+
    117 std::shared_ptr<InverseOperator<Domain,Range> > coarseSolver_;
    \n+
    119 std::shared_ptr<typename AMG::LevelContext> levelContext_;
    \n+
    120 };
    \n+
    121
    \n+
    122
    \n+
    123
    \n+
    137 template<class M, class X, class S, class PI=SequentialInformation,
    \n+
    138 class K=GeneralizedPCGSolver<X>, class A=std::allocator<X> >
    \n+
    139 class KAMG : public Preconditioner<X,X>
    \n+
    140 {
    \n+
    141 public:
    \n+\n+
    145 typedef K KrylovSolver;
    \n+\n+\n+\n+\n+
    155 typedef typename Amg::Operator Operator;
    \n+
    157 typedef typename Amg::Domain Domain;
    \n+
    159 typedef typename Amg::Range Range;
    \n+\n+\n+
    164
    \n+\n+
    167 {
    \n+
    168 return amg.category();
    \n+
    169 };
    \n+
    170
    \n+
    182 KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
    \n+
    183 const SmootherArgs& smootherArgs, const Parameters& parms,
    \n+
    184 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1);
    \n+
    185
    \n+
    199 template<class C>
    \n+
    200 KAMG(const Operator& fineOperator, const C& criterion,
    \n+
    201 const SmootherArgs& smootherArgs=SmootherArgs(),
    \n+
    202 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1,
    \n+\n+
    204
    \n+
    206 void pre(Domain& x, Range& b);
    \n+
    208 void post(Domain& x);
    \n+
    210 void apply(Domain& v, const Range& d);
    \n+
    211
    \n+
    212 std::size_t maxlevels();
    \n+
    213
    \n+
    214 private:
    \n+
    216 Amg amg;
    \n
    217
    \n-
    218 public:
    \n-
    220 using Matrix = M;
    \n-
    221 using matrix_type = M;
    \n-
    223 typedef ISTL::Impl::BCCSMatrix<typename Matrix::field_type, long int> UMFPackMatrix;
    \n-
    225 typedef ISTL::Impl::BCCSMatrixInitializer<M, long int> MatrixInitializer;
    \n-
    227 using domain_type = typename Impl::UMFPackVectorChooser<M>::domain_type;
    \n-
    229 using range_type = typename Impl::UMFPackVectorChooser<M>::range_type;
    \n+
    219 std::size_t maxLevelKrylovSteps;
    \n+
    220
    \n+
    222 double levelDefectReduction;
    \n+
    223
    \n+
    225 std::vector<std::shared_ptr<typename Amg::ScalarProduct> > scalarproducts;
    \n+
    226
    \n+
    228 std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > > ksolvers;
    \n+
    229 };
    \n
    230
    \n-\n-
    233 {
    \n-
    234 return SolverCategory::Category::sequential;
    \n-
    235 }
    \n-
    236
    \n-
    245 UMFPack(const Matrix& matrix, int verbose=0) : matrixIsLoaded_(false)
    \n-
    246 {
    \n-
    247 //check whether T is a supported type
    \n-
    248 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n-
    249 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    250 Caller::defaults(UMF_Control);
    \n-
    251 setVerbosity(verbose);
    \n-
    252 setMatrix(matrix);
    \n-
    253 }
    \n-
    254
    \n-
    263 UMFPack(const Matrix& matrix, int verbose, bool) : matrixIsLoaded_(false)
    \n-
    264 {
    \n-
    265 //check whether T is a supported type
    \n-
    266 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n-
    267 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    268 Caller::defaults(UMF_Control);
    \n-
    269 setVerbosity(verbose);
    \n-
    270 setMatrix(matrix);
    \n-
    271 }
    \n-
    272
    \n-
    282 UMFPack(const Matrix& mat_, const ParameterTree& config)
    \n-
    283 : UMFPack(mat_, config.get<int>("verbose", 0))
    \n-
    284 {}
    \n-
    285
    \n-
    288 UMFPack() : matrixIsLoaded_(false), verbosity_(0)
    \n-
    289 {
    \n-
    290 //check whether T is a supported type
    \n-
    291 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n-
    292 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    293 Caller::defaults(UMF_Control);
    \n-
    294 }
    \n-
    295
    \n-
    306 UMFPack(const Matrix& mat_, const char* file, int verbose=0)
    \n-
    307 {
    \n-
    308 //check whether T is a supported type
    \n-
    309 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n-
    310 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    311 Caller::defaults(UMF_Control);
    \n-
    312 setVerbosity(verbose);
    \n-
    313 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast<char*>(file));
    \n-
    314 if ((errcode == UMFPACK_ERROR_out_of_memory) || (errcode == UMFPACK_ERROR_file_IO))
    \n-
    315 {
    \n-
    316 matrixIsLoaded_ = false;
    \n-
    317 setMatrix(mat_);
    \n-
    318 saveDecomposition(file);
    \n-
    319 }
    \n-
    320 else
    \n-
    321 {
    \n-
    322 matrixIsLoaded_ = true;
    \n-
    323 std::cout << "UMFPack decomposition successfully loaded from " << file << std::endl;
    \n-
    324 }
    \n-
    325 }
    \n-
    326
    \n-
    333 UMFPack(const char* file, int verbose=0)
    \n-
    334 {
    \n-
    335 //check whether T is a supported type
    \n-
    336 static_assert((std::is_same<T,double>::value) || (std::is_same<T,std::complex<double> >::value),
    \n-
    337 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    338 Caller::defaults(UMF_Control);
    \n-
    339 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast<char*>(file));
    \n-
    340 if (errcode == UMFPACK_ERROR_out_of_memory)
    \n-
    341 DUNE_THROW(Dune::Exception, "ran out of memory while loading UMFPack decomposition");
    \n-
    342 if (errcode == UMFPACK_ERROR_file_IO)
    \n-
    343 DUNE_THROW(Dune::Exception, "IO error while loading UMFPack decomposition");
    \n-
    344 matrixIsLoaded_ = true;
    \n-
    345 std::cout << "UMFPack decomposition successfully loaded from " << file << std::endl;
    \n-
    346 setVerbosity(verbose);
    \n-
    347 }
    \n-
    348
    \n-
    349 virtual ~UMFPack()
    \n-
    350 {
    \n-
    351 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n-
    352 free();
    \n-
    353 }
    \n-
    354
    \n-\n-
    359 {
    \n-
    360 if (umfpackMatrix_.N() != b.dim())
    \n-
    361 DUNE_THROW(Dune::ISTLError, "Size of right-hand-side vector b does not match the number of matrix rows!");
    \n-
    362 if (umfpackMatrix_.M() != x.dim())
    \n-
    363 DUNE_THROW(Dune::ISTLError, "Size of solution vector x does not match the number of matrix columns!");
    \n-
    364 if (b.size() == 0)
    \n-
    365 return;
    \n-
    366
    \n-
    367 double UMF_Apply_Info[UMFPACK_INFO];
    \n-
    368 Caller::solve(UMFPACK_A,
    \n-
    369 umfpackMatrix_.getColStart(),
    \n-
    370 umfpackMatrix_.getRowIndex(),
    \n-
    371 umfpackMatrix_.getValues(),
    \n-
    372 reinterpret_cast<double*>(&x[0]),
    \n-
    373 reinterpret_cast<double*>(&b[0]),
    \n-
    374 UMF_Numeric,
    \n-
    375 UMF_Control,
    \n-
    376 UMF_Apply_Info);
    \n-
    377
    \n-
    378 //this is a direct solver
    \n-
    379 res.iterations = 1;
    \n-
    380 res.converged = true;
    \n-
    381 res.elapsed = UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME];
    \n-
    382
    \n-
    383 printOnApply(UMF_Apply_Info);
    \n-
    384 }
    \n-
    385
    \n-
    389 virtual void apply (domain_type& x, range_type& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n-
    390 {
    \n-
    391 apply(x,b,res);
    \n-
    392 }
    \n-
    393
    \n-
    399 void apply(T* x, T* b)
    \n-
    400 {
    \n-
    401 double UMF_Apply_Info[UMFPACK_INFO];
    \n-
    402 Caller::solve(UMFPACK_A,
    \n-
    403 umfpackMatrix_.getColStart(),
    \n-
    404 umfpackMatrix_.getRowIndex(),
    \n-
    405 umfpackMatrix_.getValues(),
    \n-
    406 x,
    \n-
    407 b,
    \n-
    408 UMF_Numeric,
    \n-
    409 UMF_Control,
    \n-
    410 UMF_Apply_Info);
    \n-
    411 printOnApply(UMF_Apply_Info);
    \n-
    412 }
    \n-
    413
    \n-
    425 void setOption(unsigned int option, double value)
    \n-
    426 {
    \n-
    427 if (option >= UMFPACK_CONTROL)
    \n-
    428 DUNE_THROW(RangeError, "Requested non-existing UMFPack option");
    \n-
    429
    \n-
    430 UMF_Control[option] = value;
    \n-
    431 }
    \n-
    432
    \n-
    436 void saveDecomposition(const char* file)
    \n-
    437 {
    \n-
    438 int errcode = Caller::save_numeric(UMF_Numeric, const_cast<char*>(file));
    \n-
    439 if (errcode != UMFPACK_OK)
    \n-
    440 DUNE_THROW(Dune::Exception,"IO ERROR while trying to save UMFPack decomposition");
    \n-
    441 }
    \n-
    442
    \n-
    444 void setMatrix(const Matrix& matrix)
    \n-
    445 {
    \n-
    446 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n-
    447 free();
    \n-
    448 if (matrix.N() == 0 or matrix.M() == 0)
    \n-
    449 return;
    \n-
    450
    \n-
    451 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes() != 0)
    \n-
    452 umfpackMatrix_.free();
    \n-
    453 umfpackMatrix_.setSize(MatrixDimension<Matrix>::rowdim(matrix),
    \n-\n-
    455 ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
    \n-
    456
    \n-
    457 copyToBCCSMatrix(initializer, matrix);
    \n-
    458
    \n-
    459 decompose();
    \n-
    460 }
    \n-
    461
    \n-
    462 template<class S>
    \n-
    463 void setSubMatrix(const Matrix& _mat, const S& rowIndexSet)
    \n-
    464 {
    \n-
    465 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)
    \n-
    466 free();
    \n-
    467
    \n-
    468 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes() != 0)
    \n-
    469 umfpackMatrix_.free();
    \n-
    470
    \n-
    471 umfpackMatrix_.setSize(rowIndexSet.size()*MatrixDimension<Matrix>::rowdim(_mat) / _mat.N(),
    \n-
    472 rowIndexSet.size()*MatrixDimension<Matrix>::coldim(_mat) / _mat.M());
    \n-
    473 ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
    \n-
    474
    \n-
    475 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset<Matrix,std::set<std::size_t> >(_mat,rowIndexSet));
    \n-
    476
    \n-
    477 decompose();
    \n-
    478 }
    \n-
    479
    \n-
    487 void setVerbosity(int v)
    \n-
    488 {
    \n-
    489 verbosity_ = v;
    \n-
    490 // set the verbosity level in UMFPack
    \n-
    491 if (verbosity_ == 0)
    \n-
    492 UMF_Control[UMFPACK_PRL] = 1;
    \n-
    493 if (verbosity_ == 1)
    \n-
    494 UMF_Control[UMFPACK_PRL] = 2;
    \n-
    495 if (verbosity_ == 2)
    \n-
    496 UMF_Control[UMFPACK_PRL] = 4;
    \n-
    497 }
    \n-
    498
    \n-\n-
    504 {
    \n-
    505 return UMF_Numeric;
    \n-
    506 }
    \n-
    507
    \n-\n-
    513 {
    \n-
    514 return umfpackMatrix_;
    \n-
    515 }
    \n-
    516
    \n-
    521 void free()
    \n-
    522 {
    \n-
    523 if (!matrixIsLoaded_)
    \n-
    524 {
    \n-
    525 Caller::free_symbolic(&UMF_Symbolic);
    \n-
    526 umfpackMatrix_.free();
    \n-
    527 }
    \n-
    528 Caller::free_numeric(&UMF_Numeric);
    \n-
    529 matrixIsLoaded_ = false;
    \n-
    530 }
    \n-
    531
    \n-
    532 const char* name() { return "UMFPACK"; }
    \n-
    533
    \n-
    534 private:
    \n-
    535 typedef typename Dune::UMFPackMethodChooser<T> Caller;
    \n-
    536
    \n-
    537 template<class Mat,class X, class TM, class TD, class T1>
    \n-\n-\n-
    540
    \n-
    542 void decompose()
    \n-
    543 {
    \n-
    544 double UMF_Decomposition_Info[UMFPACK_INFO];
    \n-
    545 Caller::symbolic(static_cast<int>(umfpackMatrix_.N()),
    \n-
    546 static_cast<int>(umfpackMatrix_.N()),
    \n-
    547 umfpackMatrix_.getColStart(),
    \n-
    548 umfpackMatrix_.getRowIndex(),
    \n-
    549 reinterpret_cast<double*>(umfpackMatrix_.getValues()),
    \n-
    550 &UMF_Symbolic,
    \n-
    551 UMF_Control,
    \n-
    552 UMF_Decomposition_Info);
    \n-
    553 Caller::numeric(umfpackMatrix_.getColStart(),
    \n-
    554 umfpackMatrix_.getRowIndex(),
    \n-
    555 reinterpret_cast<double*>(umfpackMatrix_.getValues()),
    \n-
    556 UMF_Symbolic,
    \n-
    557 &UMF_Numeric,
    \n-
    558 UMF_Control,
    \n-
    559 UMF_Decomposition_Info);
    \n-
    560 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);
    \n-
    561 if (verbosity_ == 1)
    \n-
    562 {
    \n-
    563 std::cout << "[UMFPack Decomposition]" << std::endl;
    \n-
    564 std::cout << "Wallclock Time taken: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_WALLTIME] << " (CPU Time: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_TIME] << ")" << std::endl;
    \n-
    565 std::cout << "Flops taken: " << UMF_Decomposition_Info[UMFPACK_FLOPS] << std::endl;
    \n-
    566 std::cout << "Peak Memory Usage: " << UMF_Decomposition_Info[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT] << " bytes" << std::endl;
    \n-
    567 std::cout << "Condition number estimate: " << 1./UMF_Decomposition_Info[UMFPACK_RCOND] << std::endl;
    \n-
    568 std::cout << "Numbers of non-zeroes in decomposition: L: " << UMF_Decomposition_Info[UMFPACK_LNZ] << " U: " << UMF_Decomposition_Info[UMFPACK_UNZ] << std::endl;
    \n-
    569 }
    \n-
    570 if (verbosity_ == 2)
    \n-
    571 {
    \n-
    572 Caller::report_info(UMF_Control,UMF_Decomposition_Info);
    \n-
    573 }
    \n-
    574 }
    \n-
    575
    \n-
    576 void printOnApply(double* UMF_Info)
    \n-
    577 {
    \n-
    578 Caller::report_status(UMF_Control,UMF_Info[UMFPACK_STATUS]);
    \n-
    579 if (verbosity_ > 0)
    \n-
    580 {
    \n-
    581 std::cout << "[UMFPack Solve]" << std::endl;
    \n-
    582 std::cout << "Wallclock Time: " << UMF_Info[UMFPACK_SOLVE_WALLTIME] << " (CPU Time: " << UMF_Info[UMFPACK_SOLVE_TIME] << ")" << std::endl;
    \n-
    583 std::cout << "Flops Taken: " << UMF_Info[UMFPACK_SOLVE_FLOPS] << std::endl;
    \n-
    584 std::cout << "Iterative Refinement steps taken: " << UMF_Info[UMFPACK_IR_TAKEN] << std::endl;
    \n-
    585 std::cout << "Error Estimate: " << UMF_Info[UMFPACK_OMEGA1] << " resp. " << UMF_Info[UMFPACK_OMEGA2] << std::endl;
    \n-
    586 }
    \n-
    587 }
    \n-
    588
    \n-
    589 UMFPackMatrix umfpackMatrix_;
    \n-
    590 bool matrixIsLoaded_;
    \n-
    591 int verbosity_;
    \n-
    592 void *UMF_Symbolic;
    \n-
    593 void *UMF_Numeric;
    \n-
    594 double UMF_Control[UMFPACK_CONTROL];
    \n-
    595 };
    \n-
    596
    \n-
    597 template<typename T, typename A, int n, int m>
    \n-\n-
    599 {
    \n-
    600 enum { value=true};
    \n-
    601 };
    \n-
    602
    \n-
    603 template<typename T, typename A>
    \n-\n-
    605 {
    \n-
    606 enum { value = true };
    \n-
    607 };
    \n-
    608
    \n-\n-
    610 template<class F,class=void> struct isValidBlock : std::false_type{};
    \n-
    611 template<class B> struct isValidBlock<B, std::enable_if_t<std::is_same<typename FieldTraits<B>::real_type,double>::value>> : std::true_type {};
    \n-
    612
    \n-
    613 template<typename TL, typename M>
    \n-
    614 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    615 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    616 operator() (TL /*tl*/, const M& mat, const Dune::ParameterTree& config,
    \n-
    617 std::enable_if_t<
    \n-
    618 isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    619 {
    \n-
    620 int verbose = config.get("verbose", 0);
    \n-
    621 return std::make_shared<Dune::UMFPack<M>>(mat,verbose);
    \n-
    622 }
    \n-
    623
    \n-
    624 // second version with SFINAE to validate the template parameters of UMFPack
    \n-
    625 template<typename TL, typename M>
    \n-
    626 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    627 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    628 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n-
    629 std::enable_if_t<
    \n-
    630 !isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    631 {
    \n-
    632 DUNE_THROW(UnsupportedType,
    \n-
    633 "Unsupported Type in UMFPack (only double and std::complex<double> supported)");
    \n-
    634 }
    \n-
    635 };
    \n-\n-
    637} // end namespace Dune
    \n-
    638
    \n-
    639#endif // HAVE_SUITESPARSE_UMFPACK
    \n-
    640
    \n-
    641#endif //DUNE_ISTL_UMFPACK_HH
    \n-
    Templates characterizing the type of a solver.
    \n-
    Implementations of the inverse operator interface.
    \n-\n-
    Implementation of the BCRSMatrix class.
    \n-\n-
    void free()
    free allocated space.
    Definition: umfpack.hh:521
    \n-
    virtual void apply(domain_type &x, range_type &b, InverseOperatorResult &res)
    Apply inverse operator,.
    Definition: umfpack.hh:358
    \n-
    virtual SolverCategory::Category category() const
    Category of the solver (see SolverCategory::Category)
    Definition: umfpack.hh:232
    \n-
    M matrix_type
    Definition: umfpack.hh:221
    \n-
    static void solve(long int m, const long int *cs, const long int *ri, std::complex< double > *val, double *x, const double *b, A... args)
    Definition: umfpack.hh:156
    \n-
    void setMatrix(const Matrix &matrix)
    Initialize data from given matrix.
    Definition: umfpack.hh:444
    \n-
    static void report_info(A... args)
    Definition: umfpack.hh:141
    \n-
    UMFPack(const Matrix &mat_, const ParameterTree &config)
    Construct a solver object from a matrix.
    Definition: umfpack.hh:282
    \n-
    static int load_numeric(A... args)
    Definition: umfpack.hh:131
    \n-
    static int load_numeric(A... args)
    Definition: umfpack.hh:74
    \n-
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
    Definition: umfpack.hh:616
    \n-
    ISTL::Impl::BCCSMatrix< typename Matrix::field_type, long int > UMFPackMatrix
    The corresponding UMFPack matrix type.
    Definition: umfpack.hh:223
    \n-
    static void report_status(A... args)
    Definition: umfpack.hh:89
    \n-
    UMFPack(const Matrix &mat_, const char *file, int verbose=0)
    Try loading a decomposition from file and do a decomposition if unsuccessful.
    Definition: umfpack.hh:306
    \n-
    typename Impl::UMFPackVectorChooser< M >::range_type range_type
    The type of the range of the solver.
    Definition: umfpack.hh:229
    \n-
    DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
    \n-
    UMFPack()
    default constructor
    Definition: umfpack.hh:288
    \n-
    static void symbolic(A... args)
    Definition: umfpack.hh:104
    \n-
    static void report_info(A... args)
    Definition: umfpack.hh:84
    \n-
    static void symbolic(long int m, long int n, const long int *cs, const long int *ri, const double *val, A... args)
    Definition: umfpack.hh:162
    \n-
    static void free_symbolic(A... args)
    Definition: umfpack.hh:69
    \n-
    static int save_numeric(A... args)
    Definition: umfpack.hh:151
    \n-
    static void free_numeric(A... args)
    Definition: umfpack.hh:121
    \n-
    void setSubMatrix(const Matrix &_mat, const S &rowIndexSet)
    Definition: umfpack.hh:463
    \n-
    static int save_numeric(A... args)
    Definition: umfpack.hh:94
    \n-
    static void report_status(A... args)
    Definition: umfpack.hh:146
    \n-
    ISTL::Impl::BCCSMatrixInitializer< M, long int > MatrixInitializer
    Type of an associated initializer class.
    Definition: umfpack.hh:225
    \n-
    void apply(T *x, T *b)
    additional apply method with c-arrays in analogy to superlu
    Definition: umfpack.hh:399
    \n-
    static void defaults(A... args)
    Definition: umfpack.hh:116
    \n-
    static void free_numeric(A... args)
    Definition: umfpack.hh:64
    \n-
    void setVerbosity(int v)
    sets the verbosity level for the UMFPack solver
    Definition: umfpack.hh:487
    \n-
    UMFPack(const char *file, int verbose=0)
    try loading a decomposition from file
    Definition: umfpack.hh:333
    \n-
    static void numeric(A... args)
    Definition: umfpack.hh:79
    \n-
    static constexpr bool valid
    Definition: umfpack.hh:50
    \n-
    virtual ~UMFPack()
    Definition: umfpack.hh:349
    \n-
    const char * name()
    Definition: umfpack.hh:532
    \n-
    void saveDecomposition(const char *file)
    saves a decomposition to a file
    Definition: umfpack.hh:436
    \n-
    UMFPackMatrix & getInternalMatrix()
    Return the column compress matrix from UMFPack.
    Definition: umfpack.hh:512
    \n-
    typename Impl::UMFPackVectorChooser< M >::domain_type domain_type
    The type of the domain of the solver.
    Definition: umfpack.hh:227
    \n-
    UMFPack(const Matrix &matrix, int verbose=0)
    Construct a solver object from a matrix.
    Definition: umfpack.hh:245
    \n-
    virtual void apply(domain_type &x, range_type &b, double reduction, InverseOperatorResult &res)
    apply inverse operator, with given convergence criteria.
    Definition: umfpack.hh:389
    \n-
    void setOption(unsigned int option, double value)
    Set UMFPack-specific options.
    Definition: umfpack.hh:425
    \n-
    static void free_symbolic(A... args)
    Definition: umfpack.hh:126
    \n-
    M Matrix
    The matrix type.
    Definition: umfpack.hh:220
    \n-
    static void numeric(const long int *cs, const long int *ri, const double *val, A... args)
    Definition: umfpack.hh:136
    \n-
    static void defaults(A... args)
    Definition: umfpack.hh:59
    \n-
    static void solve(A... args)
    Definition: umfpack.hh:99
    \n-
    UMFPack(const Matrix &matrix, int verbose, bool)
    Constructor for compatibility with SuperLU standard constructor.
    Definition: umfpack.hh:263
    \n-
    void * getFactorization()
    Return the matrix factorization.
    Definition: umfpack.hh:503
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    STL namespace.
    \n+
    231
    \n+
    232 template<class M, class X, class S, class P, class K, class A>
    \n+\n+
    234 const SmootherArgs& smootherArgs, const Parameters& params,
    \n+
    235 std::size_t ksteps, double reduction)
    \n+
    236 : amg(matrices, coarseSolver, smootherArgs, params),
    \n+
    237 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
    \n+
    238 {}
    \n+
    239
    \n+
    240
    \n+
    241 template<class M, class X, class S, class P, class K, class A>
    \n+
    242 template<class C>
    \n+
    243 KAMG<M,X,S,P,K,A>::KAMG(const Operator& fineOperator, const C& criterion,
    \n+
    244 const SmootherArgs& smootherArgs,
    \n+
    245 std::size_t ksteps, double reduction,
    \n+
    246 const ParallelInformation& pinfo)
    \n+
    247 : amg(fineOperator, criterion, smootherArgs, pinfo),
    \n+
    248 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
    \n+
    249 {}
    \n+
    250
    \n+
    251
    \n+
    252 template<class M, class X, class S, class P, class K, class A>
    \n+\n+
    254 {
    \n+
    255 amg.pre(x,b);
    \n+
    256 scalarproducts.reserve(amg.levels());
    \n+
    257 ksolvers.reserve(amg.levels());
    \n+
    258
    \n+
    259 typename OperatorHierarchy::ParallelMatrixHierarchy::Iterator
    \n+
    260 matrix = amg.matrices_->matrices().coarsest();
    \n+\n+
    262 pinfo = amg.matrices_->parallelInformation().coarsest();
    \n+
    263 bool hasCoarsest=(amg.levels()==amg.maxlevels());
    \n+
    264
    \n+
    265 if(hasCoarsest) {
    \n+
    266 if(matrix==amg.matrices_->matrices().finest())
    \n+
    267 return;
    \n+
    268 --matrix;
    \n+
    269 --pinfo;
    \n+
    270 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, amg.solver_)));
    \n+
    271 }else
    \n+
    272 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, std::shared_ptr<InverseOperator<Domain,Range> >())));
    \n+
    273
    \n+
    274 std::ostringstream s;
    \n+
    275
    \n+
    276 if(matrix!=amg.matrices_->matrices().finest())
    \n+
    277 while(true) {
    \n+
    278 scalarproducts.push_back(createScalarProduct<X>(*pinfo,category()));
    \n+
    279 std::shared_ptr<InverseOperator<Domain,Range> > ks =
    \n+
    280 std::shared_ptr<InverseOperator<Domain,Range> >(new KrylovSolver(*matrix, *(scalarproducts.back()),
    \n+
    281 *(ksolvers.back()), levelDefectReduction,
    \n+
    282 maxLevelKrylovSteps, 0));
    \n+
    283 ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, ks)));
    \n+
    284 --matrix;
    \n+
    285 --pinfo;
    \n+
    286 if(matrix==amg.matrices_->matrices().finest())
    \n+
    287 break;
    \n+
    288 }
    \n+
    289 }
    \n+
    290
    \n+
    291
    \n+
    292 template<class M, class X, class S, class P, class K, class A>
    \n+\n+
    294 {
    \n+
    295 amg.post(x);
    \n+
    296
    \n+
    297 }
    \n+
    298
    \n+
    299 template<class M, class X, class S, class P, class K, class A>
    \n+\n+
    301 {
    \n+
    302 if(ksolvers.size()==0)
    \n+
    303 {
    \n+
    304 Range td=d;
    \n+\n+
    306 amg.solver_->apply(v,td,res);
    \n+
    307 }else
    \n+
    308 {
    \n+
    309 typedef typename Amg::LevelContext LevelContext;
    \n+
    310 std::shared_ptr<LevelContext> levelContext(new LevelContext);
    \n+
    311 amg.initIteratorsWithFineLevel(*levelContext);
    \n+
    312 typedef typename std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > >::iterator Iter;
    \n+
    313 for(Iter solver=ksolvers.begin(); solver!=ksolvers.end(); ++solver)
    \n+
    314 (*solver)->setLevelContext(levelContext);
    \n+
    315 ksolvers.back()->apply(v,d);
    \n+
    316 }
    \n+
    317 }
    \n+
    318
    \n+
    319 template<class M, class X, class S, class P, class K, class A>
    \n+\n+
    321 {
    \n+
    322 return amg.maxlevels();
    \n+
    323 }
    \n+
    324
    \n+
    326 } // Amg
    \n+
    327} // Dune
    \n+
    328
    \n+
    329#endif
    \n+
    The AMG preconditioner.
    \n+
    Define general preconditioner interface.
    \n+
    void apply(Domain &v, const Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: kamg.hh:300
    \n+
    X Domain
    The domain type.
    Definition: amg.hh:87
    \n+
    KAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms, std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1)
    Construct a new amg with a specific coarse solver.
    Definition: kamg.hh:233
    \n+
    std::size_t maxlevels()
    Definition: kamg.hh:320
    \n+
    SmootherTraits< Smoother >::Arguments SmootherArgs
    The argument type for the construction of the smoother.
    Definition: amg.hh:100
    \n+
    M Operator
    The matrix operator type.
    Definition: amg.hh:73
    \n+
    void post(Domain &x)
    Clean up.
    Definition: kamg.hh:293
    \n+
    X Range
    The range type.
    Definition: amg.hh:89
    \n+
    void presmooth(LevelContext &levelContext, size_t steps)
    Apply pre smoothing on the current level.
    Definition: smoother.hh:406
    \n+
    void postsmooth(LevelContext &levelContext, size_t steps)
    Apply post smoothing on the current level.
    Definition: smoother.hh:428
    \n+
    void pre(Domain &x, Range &b)
    Prepare the preconditioner.
    Definition: kamg.hh:253
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: amg.hh:194
    \n+
    PI ParallelInformation
    The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
    Definition: amg.hh:80
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    Definition: matrixutils.hh:211
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n-
    Definition: overlappingschwarz.hh:694
    \n-
    Definition: matrixutils.hh:27
    \n+
    an algebraic multigrid method using a Krylov-cycle.
    Definition: kamg.hh:140
    \n+
    Amg::Domain Domain
    the type of the domain.
    Definition: kamg.hh:157
    \n+
    Amg::SmootherArgs SmootherArgs
    The type of the arguments for construction of the smoothers.
    Definition: kamg.hh:153
    \n+
    Amg::ParallelInformation ParallelInformation
    the type of the parallelinformation to use.
    Definition: kamg.hh:151
    \n+
    Amg::CoarseSolver CoarseSolver
    The type of the coarse solver.
    Definition: kamg.hh:149
    \n+
    Amg::OperatorHierarchy OperatorHierarchy
    The type of the hierarchy of operators.
    Definition: kamg.hh:147
    \n+
    Amg::Range Range
    The type of the range.
    Definition: kamg.hh:159
    \n+
    Amg::ScalarProduct ScalarProduct
    The type of the scalar product.
    Definition: kamg.hh:163
    \n+
    AMG< M, X, S, PI, A > Amg
    The type of the underlying AMG.
    Definition: kamg.hh:143
    \n+
    Amg::Operator Operator
    the type of the lineatr operator.
    Definition: kamg.hh:155
    \n+
    Amg::ParallelInformationHierarchy ParallelInformationHierarchy
    The type of the hierarchy of parallel information.
    Definition: kamg.hh:161
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: kamg.hh:166
    \n+
    K KrylovSolver
    The type of the Krylov solver for the cycle.
    Definition: kamg.hh:145
    \n+
    Two grid operator for AMG with Krylov cycle.
    Definition: kamg.hh:33
    \n+
    void pre(typename AMG::Domain &x, typename AMG::Range &b)
    Prepare the preconditioner.
    Definition: kamg.hh:58
    \n+
    KAmgTwoGrid(AMG &amg, std::shared_ptr< InverseOperator< Domain, Range > > coarseSolver)
    Constructor.
    Definition: kamg.hh:53
    \n+
    ~KAmgTwoGrid()
    Destructor.
    Definition: kamg.hh:110
    \n+
    void post(typename AMG::Domain &x)
    Clean up.
    Definition: kamg.hh:62
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: kamg.hh:41
    \n+
    void setLevelContext(std::shared_ptr< typename AMG::LevelContext > p)
    Set the level context pointer.
    Definition: kamg.hh:104
    \n+
    InverseOperator< Domain, Range > * coarseSolver()
    Get a pointer to the coarse grid solver.
    Definition: kamg.hh:95
    \n+
    void apply(typename AMG::Domain &v, const typename AMG::Range &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: kamg.hh:66
    \n+
    Parallel algebraic multigrid based on agglomeration.
    Definition: amg.hh:65
    \n+\n+
    LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
    Type of the mutable iterator.
    Definition: hierarchy.hh:216
    \n+
    The hierarchies build by the coarsening process.
    Definition: matrixhierarchy.hh:61
    \n+
    All parameters for AMG.
    Definition: parameters.hh:393
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    double elapsed
    Elapsed time in seconds.
    Definition: solver.hh:82
    \n-
    int iterations
    Number of iterations.
    Definition: solver.hh:67
    \n-
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n-
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n+\n
    Category
    Definition: solvercategory.hh:23
    \n-
    Definition: solverregistry.hh:77
    \n-
    Definition: solvertype.hh:16
    \n-
    @ value
    Whether this is a direct solver.
    Definition: solvertype.hh:24
    \n-
    Definition: solvertype.hh:30
    \n-
    @ value
    whether the solver internally uses column compressed storage
    Definition: solvertype.hh:36
    \n-
    Definition: umfpack.hh:49
    \n-
    The UMFPack direct sparse solver.
    Definition: umfpack.hh:215
    \n-
    Definition: umfpack.hh:609
    \n-
    Definition: umfpack.hh:610
    \n+
    Generalized preconditioned conjugate gradient solver.
    Definition: solvers.hh:1307
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,840 +4,433 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-umfpack.hh\n+ * paamg\n+kamg.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_UMFPACK_HH\n- 6#define DUNE_ISTL_UMFPACK_HH\n+ 5#ifndef DUNE_AMG_KAMG_HH\n+ 6#define DUNE_AMG_KAMG_HH\n 7\n- 8#if HAVE_SUITESPARSE_UMFPACK || defined DOXYGEN\n- 9\n- 10#include\n- 11#include\n- 12\n- 13#include\n- 14\n- 15#include\n- 16#include\n- 17#include\n- 18#include\n- 19#include\n- 20#include\n- 21#include\n- 22#include \n- 23\n- 24\n- 25\n- 26namespace Dune {\n- 38 // FORWARD DECLARATIONS\n- 39 template\n- 40 class SeqOverlappingSchwarz;\n- 41\n- 42 template\n- 43 struct SeqOverlappingSchwarzAssemblerHelper;\n- 44\n- 45 // wrapper class for C-Function Calls in the backend. Choose the right\n-function namespace\n- 46 // depending on the template parameter used.\n- 47 template\n-48 struct UMFPackMethodChooser\n- 49 {\n-50 static constexpr bool valid = false ;\n- 51 };\n- 52\n- 53 template<>\n-54 struct UMFPackMethodChooser\n- 55 {\n-56 static constexpr bool valid = true ;\n- 57\n- 58 template\n-59 static void defaults(A... args)\n- 60 {\n- 61 umfpack_dl_defaults(args...);\n- 62 }\n- 63 template\n-64 static void free_numeric(A... args)\n- 65 {\n- 66 umfpack_dl_free_numeric(args...);\n- 67 }\n- 68 template\n-69 static void free_symbolic(A... args)\n- 70 {\n- 71 umfpack_dl_free_symbolic(args...);\n- 72 }\n- 73 template\n-74 static int load_numeric(A... args)\n- 75 {\n- 76 return umfpack_dl_load_numeric(args...);\n- 77 }\n- 78 template\n-79 static void numeric(A... args)\n- 80 {\n- 81 umfpack_dl_numeric(args...);\n- 82 }\n- 83 template\n-84 static void report_info(A... args)\n- 85 {\n- 86 umfpack_dl_report_info(args...);\n- 87 }\n- 88 template\n-89 static void report_status(A... args)\n- 90 {\n- 91 umfpack_dl_report_status(args...);\n- 92 }\n- 93 template\n-94 static int save_numeric(A... args)\n- 95 {\n- 96 return umfpack_dl_save_numeric(args...);\n- 97 }\n- 98 template\n-99 static void solve(A... args)\n- 100 {\n- 101 umfpack_dl_solve(args...);\n- 102 }\n- 103 template\n-104 static void symbolic(A... args)\n+ 8#include \n+ 9#include \"amg.hh\"\n+ 10\n+ 11namespace Dune\n+ 12{\n+ 13 namespace Amg\n+ 14 {\n+ 15\n+ 30 template\n+31 class KAmgTwoGrid\n+ 32 : public Preconditioner\n+ 33 {\n+ 35 typedef typename AMG::Domain Domain;\n+ 37 typedef typename AMG::Range Range;\n+ 38 public:\n+ 39\n+41 virtual SolverCategory::Category category() const\n+ 42 {\n+ 43 return amg_.category();\n+ 44 };\n+ 45\n+53 KAmgTwoGrid(AMG& amg, std::shared_ptr >\n+coarseSolver)\n+ 54 : amg_(amg), coarseSolver_(coarseSolver)\n+ 55 {}\n+ 56\n+58 void pre([[maybe_unused]] typename AMG::Domain& x, [[maybe_unused]] typename\n+AMG::Range& b)\n+ 59 {}\n+ 60\n+62 void post([[maybe_unused]] typename AMG::Domain& x)\n+ 63 {}\n+ 64\n+66 void apply(typename AMG::Domain& v, const typename AMG::Range& d)\n+ 67 {\n+ 68 // Copy data\n+ 69 *levelContext_->update=0;\n+ 70 *levelContext_->rhs = d;\n+ 71 *levelContext_->lhs = v;\n+ 72\n+ 73 presmooth(*levelContext_, amg_.preSteps_);\n+ 74 bool processFineLevel =\n+ 75 amg_.moveToCoarseLevel(*levelContext_);\n+ 76\n+ 77 if(processFineLevel) {\n+ 78 typename AMG::Range b=*levelContext_->rhs;\n+ 79 typename AMG::Domain x=*levelContext_->update;\n+ 80 InverseOperatorResult res;\n+ 81 coarseSolver_->apply(x, b, res);\n+ 82 *levelContext_->update=x;\n+ 83 }\n+ 84\n+ 85 amg_.moveToFineLevel(*levelContext_, processFineLevel);\n+ 86\n+ 87 postsmooth(*levelContext_, amg_.postSteps_);\n+ 88 v=*levelContext_->update;\n+ 89 }\n+ 90\n+95 InverseOperator* coarseSolver()\n+ 96 {\n+ 97 return coarseSolver_;\n+ 98 }\n+ 99\n+104 void setLevelContext(std::shared_ptr p)\n 105 {\n- 106 umfpack_dl_symbolic(args...);\n+ 106 levelContext_=p;\n 107 }\n- 108 };\n- 109\n- 110 template<>\n-111 struct UMFPackMethodChooser >\n- 112 {\n-113 static constexpr bool valid = true ;\n- 114\n- 115 template\n-116 static void defaults(A... args)\n- 117 {\n- 118 umfpack_zl_defaults(args...);\n- 119 }\n- 120 template\n-121 static void free_numeric(A... args)\n- 122 {\n- 123 umfpack_zl_free_numeric(args...);\n- 124 }\n- 125 template\n-126 static void free_symbolic(A... args)\n- 127 {\n- 128 umfpack_zl_free_symbolic(args...);\n- 129 }\n- 130 template\n-131 static int load_numeric(A... args)\n- 132 {\n- 133 return umfpack_zl_load_numeric(args...);\n- 134 }\n- 135 template\n-136 static void numeric(const long int* cs, const long int* ri, const double*\n-val, A... args)\n- 137 {\n- 138 umfpack_zl_numeric(cs,ri,val,NULL,args...);\n- 139 }\n- 140 template\n-141 static void report_info(A... args)\n- 142 {\n- 143 umfpack_zl_report_info(args...);\n- 144 }\n- 145 template\n-146 static void report_status(A... args)\n- 147 {\n- 148 umfpack_zl_report_status(args...);\n- 149 }\n- 150 template\n-151 static int save_numeric(A... args)\n- 152 {\n- 153 return umfpack_zl_save_numeric(args...);\n- 154 }\n- 155 template\n-156 static void solve(long int m, const long int* cs, const long int* ri, std::\n-complex* val, double* x, const double* b,A... args)\n- 157 {\n- 158 const double* cval = reinterpret_cast(val);\n- 159 umfpack_zl_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);\n- 160 }\n- 161 template\n-162 static void symbolic(long int m, long int n, const long int* cs, const long\n-int* ri, const double* val, A... args)\n- 163 {\n- 164 umfpack_zl_symbolic(m,n,cs,ri,val,NULL,args...);\n- 165 }\n- 166 };\n- 167\n- 168 namespace Impl\n- 169 {\n- 170 template\n- 171 struct UMFPackVectorChooser\n- 172 {};\n- 173\n- 174 template\n- 175 struct UMFPackVectorChooser,A > >\n- 176 {\n- 178 using domain_type = BlockVector<\n- 179 FieldVector,\n- 180 typename std::allocator_traits::template rebind_alloc\n-> >;\n- 182 using range_type = BlockVector<\n- 183 FieldVector,\n- 184 typename std::allocator_traits::template rebind_alloc\n-> >;\n- 185 };\n- 186\n- 187 template\n- 188 struct UMFPackVectorChooser >\n- 189 {\n- 191 using domain_type = BlockVector;\n- 193 using range_type = BlockVector;\n- 194 };\n- 195 }\n- 196\n- 210 template\n-211 class UMFPack\n- 212 : public InverseOperator<\n- 213 typename Impl::UMFPackVectorChooser::domain_type,\n- 214 typename Impl::UMFPackVectorChooser::range_type >\n- 215 {\n- 216 using T = typename M::field_type;\n+ 108\n+110 ~KAmgTwoGrid()\n+ 111 {}\n+ 112\n+ 113 private:\n+ 115 AMG& amg_;\n+ 117 std::shared_ptr > coarseSolver_;\n+ 119 std::shared_ptr levelContext_;\n+ 120 };\n+ 121\n+ 122\n+ 123\n+ 137 template, class A=std::allocator >\n+139 class KAMG : public Preconditioner\n+ 140 {\n+ 141 public:\n+143 typedef AMG Amg;\n+145 typedef K KrylovSolver;\n+147 typedef typename Amg::OperatorHierarchy OperatorHierarchy;\n+149 typedef typename Amg::CoarseSolver CoarseSolver;\n+151 typedef typename Amg::ParallelInformation ParallelInformation;\n+153 typedef typename Amg::SmootherArgs SmootherArgs;\n+155 typedef typename Amg::Operator Operator;\n+157 typedef typename Amg::Domain Domain;\n+159 typedef typename Amg::Range Range;\n+161 typedef typename Amg::ParallelInformationHierarchy\n+ParallelInformationHierarchy;\n+163 typedef typename Amg::ScalarProduct ScalarProduct;\n+ 164\n+166 virtual SolverCategory::Category category() const\n+ 167 {\n+ 168 return amg.category();\n+ 169 };\n+ 170\n+ 182 KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,\n+ 183 const SmootherArgs& smootherArgs, const Parameters& parms,\n+ 184 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1);\n+ 185\n+ 199 template\n+ 200 KAMG(const Operator& fineOperator, const C& criterion,\n+ 201 const SmootherArgs& smootherArgs=SmootherArgs(),\n+ 202 std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1,\n+ 203 const ParallelInformation& pinfo=ParallelInformation());\n+ 204\n+ 206 void pre(Domain& x, Range& b);\n+ 208 void post(Domain& x);\n+ 210 void apply(Domain& v, const Range& d);\n+ 211\n+ 212 std::size_t maxlevels();\n+ 213\n+ 214 private:\n+ 216 Amg amg;\n 217\n- 218 public:\n-220 using Matrix = M;\n-221 using matrix_type = M;\n-223 typedef ISTL::Impl::BCCSMatrix\n-UMFPackMatrix;\n-225 typedef ISTL::Impl::BCCSMatrixInitializer MatrixInitializer;\n-227 using domain_type = typename Impl::UMFPackVectorChooser::domain_type;\n-229 using range_type = typename Impl::UMFPackVectorChooser::range_type;\n+ 219 std::size_t maxLevelKrylovSteps;\n+ 220\n+ 222 double levelDefectReduction;\n+ 223\n+ 225 std::vector > scalarproducts;\n+ 226\n+ 228 std::vector > > ksolvers;\n+ 229 };\n 230\n-232 virtual SolverCategory::Category category() const\n- 233 {\n- 234 return SolverCategory::Category::sequential;\n- 235 }\n- 236\n-245 UMFPack(const Matrix& matrix, int verbose=0) : matrixIsLoaded_(false)\n- 246 {\n- 247 //check whether T is a supported type\n- 248 static_assert((std::is_same::value) || (std::is_same >::value),\n- 249 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 250 Caller::defaults(UMF_Control);\n- 251 setVerbosity(verbose);\n- 252 setMatrix(matrix);\n- 253 }\n- 254\n-263 UMFPack(const Matrix& matrix, int verbose, bool) : matrixIsLoaded_(false)\n- 264 {\n- 265 //check whether T is a supported type\n- 266 static_assert((std::is_same::value) || (std::is_same >::value),\n- 267 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 268 Caller::defaults(UMF_Control);\n- 269 setVerbosity(verbose);\n- 270 setMatrix(matrix);\n- 271 }\n- 272\n-282 UMFPack(const Matrix& mat_, const ParameterTree& config)\n- 283 : UMFPack(mat_, config.get(\"verbose\", 0))\n- 284 {}\n- 285\n-288 UMFPack() : matrixIsLoaded_(false), verbosity_(0)\n- 289 {\n- 290 //check whether T is a supported type\n- 291 static_assert((std::is_same::value) || (std::is_same >::value),\n- 292 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 293 Caller::defaults(UMF_Control);\n- 294 }\n- 295\n-306 UMFPack(const Matrix& mat_, const char* file, int verbose=0)\n- 307 {\n- 308 //check whether T is a supported type\n- 309 static_assert((std::is_same::value) || (std::is_same >::value),\n- 310 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 311 Caller::defaults(UMF_Control);\n- 312 setVerbosity(verbose);\n- 313 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast(file));\n- 314 if ((errcode == UMFPACK_ERROR_out_of_memory) || (errcode ==\n-UMFPACK_ERROR_file_IO))\n- 315 {\n- 316 matrixIsLoaded_ = false;\n- 317 setMatrix(mat_);\n- 318 saveDecomposition(file);\n- 319 }\n- 320 else\n+ 231\n+ 232 template\n+233 KAMG::KAMG(OperatorHierarchy& matrices, CoarseSolver&\n+coarseSolver,\n+ 234 const SmootherArgs& smootherArgs, const Parameters& params,\n+ 235 std::size_t ksteps, double reduction)\n+ 236 : amg(matrices, coarseSolver, smootherArgs, params),\n+ 237 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)\n+ 238 {}\n+ 239\n+ 240\n+ 241 template\n+ 242 template\n+243 KAMG::KAMG(const Operator& fineOperator, const C& criterion,\n+ 244 const SmootherArgs& smootherArgs,\n+ 245 std::size_t ksteps, double reduction,\n+ 246 const ParallelInformation& pinfo)\n+ 247 : amg(fineOperator, criterion, smootherArgs, pinfo),\n+ 248 maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)\n+ 249 {}\n+ 250\n+ 251\n+ 252 template\n+253 void KAMG::pre(Domain& x, Range& b)\n+ 254 {\n+ 255 amg.pre(x,b);\n+ 256 scalarproducts.reserve(amg.levels());\n+ 257 ksolvers.reserve(amg.levels());\n+ 258\n+ 259 typename OperatorHierarchy::ParallelMatrixHierarchy::Iterator\n+ 260 matrix = amg.matrices_->matrices().coarsest();\n+ 261 typename ParallelInformationHierarchy::Iterator\n+ 262 pinfo = amg.matrices_->parallelInformation().coarsest();\n+ 263 bool hasCoarsest=(amg.levels()==amg.maxlevels());\n+ 264\n+ 265 if(hasCoarsest) {\n+ 266 if(matrix==amg.matrices_->matrices().finest())\n+ 267 return;\n+ 268 --matrix;\n+ 269 --pinfo;\n+ 270 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n+(amg, amg.solver_)));\n+ 271 }else\n+ 272 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n+(amg, std::shared_ptr >())));\n+ 273\n+ 274 std::ostringstream s;\n+ 275\n+ 276 if(matrix!=amg.matrices_->matrices().finest())\n+ 277 while(true) {\n+ 278 scalarproducts.push_back(createScalarProduct(*pinfo,category()));\n+ 279 std::shared_ptr > ks =\n+ 280 std::shared_ptr >(new KrylovSolver(*matrix,\n+*(scalarproducts.back()),\n+ 281 *(ksolvers.back()), levelDefectReduction,\n+ 282 maxLevelKrylovSteps, 0));\n+ 283 ksolvers.push_back(std::shared_ptr >(new KAmgTwoGrid\n+(amg, ks)));\n+ 284 --matrix;\n+ 285 --pinfo;\n+ 286 if(matrix==amg.matrices_->matrices().finest())\n+ 287 break;\n+ 288 }\n+ 289 }\n+ 290\n+ 291\n+ 292 template\n+293 void KAMG::post(Domain& x)\n+ 294 {\n+ 295 amg.post(x);\n+ 296\n+ 297 }\n+ 298\n+ 299 template\n+300 void KAMG::apply(Domain& v, const Range& d)\n+ 301 {\n+ 302 if(ksolvers.size()==0)\n+ 303 {\n+ 304 Range td=d;\n+ 305 InverseOperatorResult res;\n+ 306 amg.solver_->apply(v,td,res);\n+ 307 }else\n+ 308 {\n+ 309 typedef typename Amg::LevelContext LevelContext;\n+ 310 std::shared_ptr levelContext(new LevelContext);\n+ 311 amg.initIteratorsWithFineLevel(*levelContext);\n+ 312 typedef typename std::vector > >::\n+iterator Iter;\n+ 313 for(Iter solver=ksolvers.begin(); solver!=ksolvers.end(); ++solver)\n+ 314 (*solver)->setLevelContext(levelContext);\n+ 315 ksolvers.back()->apply(v,d);\n+ 316 }\n+ 317 }\n+ 318\n+ 319 template\n+320 std::size_t KAMG::maxlevels()\n 321 {\n- 322 matrixIsLoaded_ = true;\n- 323 std::cout << \"UMFPack decomposition successfully loaded from \" << file <<\n-std::endl;\n- 324 }\n- 325 }\n- 326\n-333 UMFPack(const char* file, int verbose=0)\n- 334 {\n- 335 //check whether T is a supported type\n- 336 static_assert((std::is_same::value) || (std::is_same >::value),\n- 337 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 338 Caller::defaults(UMF_Control);\n- 339 int errcode = Caller::load_numeric(&UMF_Numeric, const_cast(file));\n- 340 if (errcode == UMFPACK_ERROR_out_of_memory)\n- 341 DUNE_THROW(Dune::Exception, \"ran out of memory while loading UMFPack\n-decomposition\");\n- 342 if (errcode == UMFPACK_ERROR_file_IO)\n- 343 DUNE_THROW(Dune::Exception, \"IO error while loading UMFPack\n-decomposition\");\n- 344 matrixIsLoaded_ = true;\n- 345 std::cout << \"UMFPack decomposition successfully loaded from \" << file <<\n-std::endl;\n- 346 setVerbosity(verbose);\n- 347 }\n- 348\n-349 virtual ~UMFPack()\n- 350 {\n- 351 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n- 352 free();\n- 353 }\n- 354\n-358 virtual void apply(domain_type& x, range_type& b, InverseOperatorResult&\n-res)\n- 359 {\n- 360 if (umfpackMatrix_.N() != b.dim())\n- 361 DUNE_THROW(Dune::ISTLError, \"Size of right-hand-side vector b does not\n-match the number of matrix rows!\");\n- 362 if (umfpackMatrix_.M() != x.dim())\n- 363 DUNE_THROW(Dune::ISTLError, \"Size of solution vector x does not match the\n-number of matrix columns!\");\n- 364 if (b.size() == 0)\n- 365 return;\n- 366\n- 367 double UMF_Apply_Info[UMFPACK_INFO];\n- 368 Caller::solve(UMFPACK_A,\n- 369 umfpackMatrix_.getColStart(),\n- 370 umfpackMatrix_.getRowIndex(),\n- 371 umfpackMatrix_.getValues(),\n- 372 reinterpret_cast(&x[0]),\n- 373 reinterpret_cast(&b[0]),\n- 374 UMF_Numeric,\n- 375 UMF_Control,\n- 376 UMF_Apply_Info);\n- 377\n- 378 //this is a direct solver\n- 379 res.iterations = 1;\n- 380 res.converged = true;\n- 381 res.elapsed = UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME];\n- 382\n- 383 printOnApply(UMF_Apply_Info);\n- 384 }\n- 385\n-389 virtual void apply (domain_type& x, range_type& b, [[maybe_unused]] double\n-reduction, InverseOperatorResult& res)\n- 390 {\n- 391 apply(x,b,res);\n- 392 }\n- 393\n-399 void apply(T* x, T* b)\n- 400 {\n- 401 double UMF_Apply_Info[UMFPACK_INFO];\n- 402 Caller::solve(UMFPACK_A,\n- 403 umfpackMatrix_.getColStart(),\n- 404 umfpackMatrix_.getRowIndex(),\n- 405 umfpackMatrix_.getValues(),\n- 406 x,\n- 407 b,\n- 408 UMF_Numeric,\n- 409 UMF_Control,\n- 410 UMF_Apply_Info);\n- 411 printOnApply(UMF_Apply_Info);\n- 412 }\n- 413\n-425 void setOption(unsigned int option, double value)\n- 426 {\n- 427 if (option >= UMFPACK_CONTROL)\n- 428 DUNE_THROW(RangeError, \"Requested non-existing UMFPack option\");\n- 429\n- 430 UMF_Control[option] = value;\n- 431 }\n- 432\n-436 void saveDecomposition(const char* file)\n- 437 {\n- 438 int errcode = Caller::save_numeric(UMF_Numeric, const_cast(file));\n- 439 if (errcode != UMFPACK_OK)\n- 440 DUNE_THROW(Dune::Exception,\"IO ERROR while trying to save UMFPack\n-decomposition\");\n- 441 }\n- 442\n-444 void setMatrix(const Matrix& matrix)\n- 445 {\n- 446 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n- 447 free();\n- 448 if (matrix.N() == 0 or matrix.M() == 0)\n- 449 return;\n- 450\n- 451 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes()\n-!= 0)\n- 452 umfpackMatrix_.free();\n- 453 umfpackMatrix_.setSize(MatrixDimension::rowdim(matrix),\n- 454 MatrixDimension::coldim(matrix));\n- 455 ISTL::Impl::BCCSMatrixInitializer initializer\n-(umfpackMatrix_);\n- 456\n- 457 copyToBCCSMatrix(initializer, matrix);\n- 458\n- 459 decompose();\n- 460 }\n- 461\n- 462 template\n-463 void setSubMatrix(const Matrix& _mat, const S& rowIndexSet)\n- 464 {\n- 465 if ((umfpackMatrix_.N() + umfpackMatrix_.M() > 0) || matrixIsLoaded_)\n- 466 free();\n- 467\n- 468 if (umfpackMatrix_.N() + umfpackMatrix_.M() + umfpackMatrix_.nonzeroes()\n-!= 0)\n- 469 umfpackMatrix_.free();\n- 470\n- 471 umfpackMatrix_.setSize(rowIndexSet.size()*MatrixDimension::rowdim\n-(_mat) / _mat.N(),\n- 472 rowIndexSet.size()*MatrixDimension::coldim(_mat) / _mat.M());\n- 473 ISTL::Impl::BCCSMatrixInitializer initializer\n-(umfpackMatrix_);\n- 474\n- 475 copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset >(_mat,rowIndexSet));\n- 476\n- 477 decompose();\n- 478 }\n- 479\n-487 void setVerbosity(int v)\n- 488 {\n- 489 verbosity_ = v;\n- 490 // set the verbosity level in UMFPack\n- 491 if (verbosity_ == 0)\n- 492 UMF_Control[UMFPACK_PRL] = 1;\n- 493 if (verbosity_ == 1)\n- 494 UMF_Control[UMFPACK_PRL] = 2;\n- 495 if (verbosity_ == 2)\n- 496 UMF_Control[UMFPACK_PRL] = 4;\n- 497 }\n- 498\n-503 void* getFactorization()\n- 504 {\n- 505 return UMF_Numeric;\n- 506 }\n- 507\n-512 UMFPackMatrix& getInternalMatrix()\n- 513 {\n- 514 return umfpackMatrix_;\n- 515 }\n- 516\n-521 void free()\n- 522 {\n- 523 if (!matrixIsLoaded_)\n- 524 {\n- 525 Caller::free_symbolic(&UMF_Symbolic);\n- 526 umfpackMatrix_.free();\n- 527 }\n- 528 Caller::free_numeric(&UMF_Numeric);\n- 529 matrixIsLoaded_ = false;\n- 530 }\n- 531\n-532 const char* name() { return \"UMFPACK\"; }\n- 533\n- 534 private:\n- 535 typedef typename Dune::UMFPackMethodChooser Caller;\n- 536\n- 537 template\n-538 friend class SeqOverlappingSchwarz;\n- 539 friend struct SeqOverlappingSchwarzAssemblerHelper,true>;\n- 540\n- 542 void decompose()\n- 543 {\n- 544 double UMF_Decomposition_Info[UMFPACK_INFO];\n- 545 Caller::symbolic(static_cast(umfpackMatrix_.N()),\n- 546 static_cast(umfpackMatrix_.N()),\n- 547 umfpackMatrix_.getColStart(),\n- 548 umfpackMatrix_.getRowIndex(),\n- 549 reinterpret_cast(umfpackMatrix_.getValues()),\n- 550 &UMF_Symbolic,\n- 551 UMF_Control,\n- 552 UMF_Decomposition_Info);\n- 553 Caller::numeric(umfpackMatrix_.getColStart(),\n- 554 umfpackMatrix_.getRowIndex(),\n- 555 reinterpret_cast(umfpackMatrix_.getValues()),\n- 556 UMF_Symbolic,\n- 557 &UMF_Numeric,\n- 558 UMF_Control,\n- 559 UMF_Decomposition_Info);\n- 560 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);\n- 561 if (verbosity_ == 1)\n- 562 {\n- 563 std::cout << \"[UMFPack Decomposition]\" << std::endl;\n- 564 std::cout << \"Wallclock Time taken: \" << UMF_Decomposition_Info\n-[UMFPACK_NUMERIC_WALLTIME] << \" (CPU Time: \" << UMF_Decomposition_Info\n-[UMFPACK_NUMERIC_TIME] << \")\" << std::endl;\n- 565 std::cout << \"Flops taken: \" << UMF_Decomposition_Info[UMFPACK_FLOPS] <<\n-std::endl;\n- 566 std::cout << \"Peak Memory Usage: \" << UMF_Decomposition_Info\n-[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT] << \" bytes\"\n-<< std::endl;\n- 567 std::cout << \"Condition number estimate: \" << 1./UMF_Decomposition_Info\n-[UMFPACK_RCOND] << std::endl;\n- 568 std::cout << \"Numbers of non-zeroes in decomposition: L: \" <<\n-UMF_Decomposition_Info[UMFPACK_LNZ] << \" U: \" << UMF_Decomposition_Info\n-[UMFPACK_UNZ] << std::endl;\n- 569 }\n- 570 if (verbosity_ == 2)\n- 571 {\n- 572 Caller::report_info(UMF_Control,UMF_Decomposition_Info);\n- 573 }\n- 574 }\n- 575\n- 576 void printOnApply(double* UMF_Info)\n- 577 {\n- 578 Caller::report_status(UMF_Control,UMF_Info[UMFPACK_STATUS]);\n- 579 if (verbosity_ > 0)\n- 580 {\n- 581 std::cout << \"[UMFPack Solve]\" << std::endl;\n- 582 std::cout << \"Wallclock Time: \" << UMF_Info[UMFPACK_SOLVE_WALLTIME] << \"\n-(CPU Time: \" << UMF_Info[UMFPACK_SOLVE_TIME] << \")\" << std::endl;\n- 583 std::cout << \"Flops Taken: \" << UMF_Info[UMFPACK_SOLVE_FLOPS] << std::\n-endl;\n- 584 std::cout << \"Iterative Refinement steps taken: \" << UMF_Info\n-[UMFPACK_IR_TAKEN] << std::endl;\n- 585 std::cout << \"Error Estimate: \" << UMF_Info[UMFPACK_OMEGA1] << \" resp. \"\n-<< UMF_Info[UMFPACK_OMEGA2] << std::endl;\n- 586 }\n- 587 }\n- 588\n- 589 UMFPackMatrix umfpackMatrix_;\n- 590 bool matrixIsLoaded_;\n- 591 int verbosity_;\n- 592 void *UMF_Symbolic;\n- 593 void *UMF_Numeric;\n- 594 double UMF_Control[UMFPACK_CONTROL];\n- 595 };\n- 596\n- 597 template\n-598 struct IsDirectSolver,A> > >\n- 599 {\n-600 enum { value=true};\n- 601 };\n- 602\n- 603 template\n-604 struct StoresColumnCompressed > >\n- 605 {\n-606 enum { value = true };\n- 607 };\n- 608\n-609 struct UMFPackCreator {\n-610 template struct isValidBlock : std::false_type{};\n-611 template struct isValidBlock::real_type,double>::value>> : std::true_type\n-{};\n- 612\n- 613 template\n- 614 std::shared_ptr::type,\n- 615 typename Dune::TypeListElement<2, TL>::type>>\n-616 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& config,\n- 617 std::enable_if_t<\n- 618 isValidBlock::type::block_type>::\n-value,int> = 0) const\n- 619 {\n- 620 int verbose = config.get(\"verbose\", 0);\n- 621 return std::make_shared>(mat,verbose);\n- 622 }\n- 623\n- 624 // second version with SFINAE to validate the template parameters of\n-UMFPack\n- 625 template\n- 626 std::shared_ptr::type,\n- 627 typename Dune::TypeListElement<2, TL>::type>>\n-628 operator()(TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n-*config*/,\n- 629 std::enable_if_t<\n- 630 !isValidBlock::type::block_type>::\n-value,int> = 0) const\n- 631 {\n- 632 DUNE_THROW(UnsupportedType,\n- 633 \"Unsupported Type in UMFPack (only double and std::complex\n-supported)\");\n- 634 }\n- 635 };\n-636 DUNE_REGISTER_DIRECT_SOLVER(\"umfpack\",Dune::UMFPackCreator());\n- 637} // end namespace Dune\n- 638\n- 639#endif // HAVE_SUITESPARSE_UMFPACK\n- 640\n- 641#endif //DUNE_ISTL_UMFPACK_HH\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-solverfactory.hh\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-bccsmatrixinitializer.hh\n-Dune::UMFPack::free\n-void free()\n-free allocated space.\n-Definition: umfpack.hh:521\n-Dune::UMFPack::apply\n-virtual void apply(domain_type &x, range_type &b, InverseOperatorResult &res)\n-Apply inverse operator,.\n-Definition: umfpack.hh:358\n-Dune::UMFPack::category\n+ 322 return amg.maxlevels();\n+ 323 }\n+ 324\n+ 326 } // Amg\n+ 327} // Dune\n+ 328\n+ 329#endif\n+amg.hh\n+The AMG preconditioner.\n+preconditioners.hh\n+Define general preconditioner interface.\n+Dune::Amg::KAMG::apply\n+void apply(Domain &v, const Range &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: kamg.hh:300\n+Dune::Amg::AMG::Domain\n+X Domain\n+The domain type.\n+Definition: amg.hh:87\n+Dune::Amg::KAMG::KAMG\n+KAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const\n+SmootherArgs &smootherArgs, const Parameters &parms, std::size_t\n+maxLevelKrylovSteps=3, double minDefectReduction=1e-1)\n+Construct a new amg with a specific coarse solver.\n+Definition: kamg.hh:233\n+Dune::Amg::KAMG::maxlevels\n+std::size_t maxlevels()\n+Definition: kamg.hh:320\n+Dune::Amg::AMG::SmootherArgs\n+SmootherTraits< Smoother >::Arguments SmootherArgs\n+The argument type for the construction of the smoother.\n+Definition: amg.hh:100\n+Dune::Amg::AMG::Operator\n+M Operator\n+The matrix operator type.\n+Definition: amg.hh:73\n+Dune::Amg::KAMG::post\n+void post(Domain &x)\n+Clean up.\n+Definition: kamg.hh:293\n+Dune::Amg::AMG::Range\n+X Range\n+The range type.\n+Definition: amg.hh:89\n+Dune::Amg::presmooth\n+void presmooth(LevelContext &levelContext, size_t steps)\n+Apply pre smoothing on the current level.\n+Definition: smoother.hh:406\n+Dune::Amg::postsmooth\n+void postsmooth(LevelContext &levelContext, size_t steps)\n+Apply post smoothing on the current level.\n+Definition: smoother.hh:428\n+Dune::Amg::KAMG::pre\n+void pre(Domain &x, Range &b)\n+Prepare the preconditioner.\n+Definition: kamg.hh:253\n+Dune::Amg::AMG::category\n virtual SolverCategory::Category category() const\n-Category of the solver (see SolverCategory::Category)\n-Definition: umfpack.hh:232\n-Dune::UMFPack::matrix_type\n-M matrix_type\n-Definition: umfpack.hh:221\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::solve\n-static void solve(long int m, const long int *cs, const long int *ri, std::\n-complex< double > *val, double *x, const double *b, A... args)\n-Definition: umfpack.hh:156\n-Dune::UMFPack::setMatrix\n-void setMatrix(const Matrix &matrix)\n-Initialize data from given matrix.\n-Definition: umfpack.hh:444\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::report_info\n-static void report_info(A... args)\n-Definition: umfpack.hh:141\n-Dune::UMFPack::UMFPack\n-UMFPack(const Matrix &mat_, const ParameterTree &config)\n-Construct a solver object from a matrix.\n-Definition: umfpack.hh:282\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::load_numeric\n-static int load_numeric(A... args)\n-Definition: umfpack.hh:131\n-Dune::UMFPackMethodChooser<_double_>::load_numeric\n-static int load_numeric(A... args)\n-Definition: umfpack.hh:74\n-Dune::UMFPackCreator::operator()\n-std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL\n->::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const\n-M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock<\n-typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0)\n-const\n-Definition: umfpack.hh:616\n-Dune::UMFPack::UMFPackMatrix\n-ISTL::Impl::BCCSMatrix< typename Matrix::field_type, long int > UMFPackMatrix\n-The corresponding UMFPack matrix type.\n-Definition: umfpack.hh:223\n-Dune::UMFPackMethodChooser<_double_>::report_status\n-static void report_status(A... args)\n-Definition: umfpack.hh:89\n-Dune::UMFPack::UMFPack\n-UMFPack(const Matrix &mat_, const char *file, int verbose=0)\n-Try loading a decomposition from file and do a decomposition if unsuccessful.\n-Definition: umfpack.hh:306\n-Dune::UMFPack::range_type\n-typename Impl::UMFPackVectorChooser< M >::range_type range_type\n-The type of the range of the solver.\n-Definition: umfpack.hh:229\n-Dune::DUNE_REGISTER_DIRECT_SOLVER\n-DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n-Dune::UMFPack::UMFPack\n-UMFPack()\n-default constructor\n-Definition: umfpack.hh:288\n-Dune::UMFPackMethodChooser<_double_>::symbolic\n-static void symbolic(A... args)\n-Definition: umfpack.hh:104\n-Dune::UMFPackMethodChooser<_double_>::report_info\n-static void report_info(A... args)\n-Definition: umfpack.hh:84\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::symbolic\n-static void symbolic(long int m, long int n, const long int *cs, const long int\n-*ri, const double *val, A... args)\n-Definition: umfpack.hh:162\n-Dune::UMFPackMethodChooser<_double_>::free_symbolic\n-static void free_symbolic(A... args)\n-Definition: umfpack.hh:69\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::save_numeric\n-static int save_numeric(A... args)\n-Definition: umfpack.hh:151\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::free_numeric\n-static void free_numeric(A... args)\n-Definition: umfpack.hh:121\n-Dune::UMFPack::setSubMatrix\n-void setSubMatrix(const Matrix &_mat, const S &rowIndexSet)\n-Definition: umfpack.hh:463\n-Dune::UMFPackMethodChooser<_double_>::save_numeric\n-static int save_numeric(A... args)\n-Definition: umfpack.hh:94\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::report_status\n-static void report_status(A... args)\n-Definition: umfpack.hh:146\n-Dune::UMFPack::MatrixInitializer\n-ISTL::Impl::BCCSMatrixInitializer< M, long int > MatrixInitializer\n-Type of an associated initializer class.\n-Definition: umfpack.hh:225\n-Dune::UMFPack::apply\n-void apply(T *x, T *b)\n-additional apply method with c-arrays in analogy to superlu\n-Definition: umfpack.hh:399\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::defaults\n-static void defaults(A... args)\n-Definition: umfpack.hh:116\n-Dune::UMFPackMethodChooser<_double_>::free_numeric\n-static void free_numeric(A... args)\n-Definition: umfpack.hh:64\n-Dune::UMFPack::setVerbosity\n-void setVerbosity(int v)\n-sets the verbosity level for the UMFPack solver\n-Definition: umfpack.hh:487\n-Dune::UMFPack::UMFPack\n-UMFPack(const char *file, int verbose=0)\n-try loading a decomposition from file\n-Definition: umfpack.hh:333\n-Dune::UMFPackMethodChooser<_double_>::numeric\n-static void numeric(A... args)\n-Definition: umfpack.hh:79\n-Dune::UMFPackMethodChooser::valid\n-static constexpr bool valid\n-Definition: umfpack.hh:50\n-Dune::UMFPack::~UMFPack\n-virtual ~UMFPack()\n-Definition: umfpack.hh:349\n-Dune::UMFPack::name\n-const char * name()\n-Definition: umfpack.hh:532\n-Dune::UMFPack::saveDecomposition\n-void saveDecomposition(const char *file)\n-saves a decomposition to a file\n-Definition: umfpack.hh:436\n-Dune::UMFPack::getInternalMatrix\n-UMFPackMatrix & getInternalMatrix()\n-Return the column compress matrix from UMFPack.\n-Definition: umfpack.hh:512\n-Dune::UMFPack::domain_type\n-typename Impl::UMFPackVectorChooser< M >::domain_type domain_type\n-The type of the domain of the solver.\n-Definition: umfpack.hh:227\n-Dune::UMFPack::UMFPack\n-UMFPack(const Matrix &matrix, int verbose=0)\n-Construct a solver object from a matrix.\n-Definition: umfpack.hh:245\n-Dune::UMFPack::apply\n-virtual void apply(domain_type &x, range_type &b, double reduction,\n-InverseOperatorResult &res)\n-apply inverse operator, with given convergence criteria.\n-Definition: umfpack.hh:389\n-Dune::UMFPack::setOption\n-void setOption(unsigned int option, double value)\n-Set UMFPack-specific options.\n-Definition: umfpack.hh:425\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::free_symbolic\n-static void free_symbolic(A... args)\n-Definition: umfpack.hh:126\n-Dune::UMFPack::Matrix\n-M Matrix\n-The matrix type.\n-Definition: umfpack.hh:220\n-Dune::UMFPackMethodChooser<_std::complex<_double_>_>::numeric\n-static void numeric(const long int *cs, const long int *ri, const double *val,\n-A... args)\n-Definition: umfpack.hh:136\n-Dune::UMFPackMethodChooser<_double_>::defaults\n-static void defaults(A... args)\n-Definition: umfpack.hh:59\n-Dune::UMFPackMethodChooser<_double_>::solve\n-static void solve(A... args)\n-Definition: umfpack.hh:99\n-Dune::UMFPack::UMFPack\n-UMFPack(const Matrix &matrix, int verbose, bool)\n-Constructor for compatibility with SuperLU standard constructor.\n-Definition: umfpack.hh:263\n-Dune::UMFPack::getFactorization\n-void * getFactorization()\n-Return the matrix factorization.\n-Definition: umfpack.hh:503\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-std\n-STL namespace.\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: amg.hh:194\n+Dune::Amg::AMG::ParallelInformation\n+PI ParallelInformation\n+The type of the parallel information. Either OwnerOverlapCommunication or\n+another type describing the...\n+Definition: amg.hh:80\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::MatrixDimension\n-Definition: matrixutils.hh:211\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::SeqOverlappingSchwarz\n-Sequential overlapping Schwarz preconditioner.\n-Definition: overlappingschwarz.hh:755\n-Dune::SeqOverlappingSchwarzAssemblerHelper\n-Definition: overlappingschwarz.hh:694\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n+Dune::Amg::KAMG\n+an algebraic multigrid method using a Krylov-cycle.\n+Definition: kamg.hh:140\n+Dune::Amg::KAMG::Domain\n+Amg::Domain Domain\n+the type of the domain.\n+Definition: kamg.hh:157\n+Dune::Amg::KAMG::SmootherArgs\n+Amg::SmootherArgs SmootherArgs\n+The type of the arguments for construction of the smoothers.\n+Definition: kamg.hh:153\n+Dune::Amg::KAMG::ParallelInformation\n+Amg::ParallelInformation ParallelInformation\n+the type of the parallelinformation to use.\n+Definition: kamg.hh:151\n+Dune::Amg::KAMG::CoarseSolver\n+Amg::CoarseSolver CoarseSolver\n+The type of the coarse solver.\n+Definition: kamg.hh:149\n+Dune::Amg::KAMG::OperatorHierarchy\n+Amg::OperatorHierarchy OperatorHierarchy\n+The type of the hierarchy of operators.\n+Definition: kamg.hh:147\n+Dune::Amg::KAMG::Range\n+Amg::Range Range\n+The type of the range.\n+Definition: kamg.hh:159\n+Dune::Amg::KAMG::ScalarProduct\n+Amg::ScalarProduct ScalarProduct\n+The type of the scalar product.\n+Definition: kamg.hh:163\n+Dune::Amg::KAMG::Amg\n+AMG< M, X, S, PI, A > Amg\n+The type of the underlying AMG.\n+Definition: kamg.hh:143\n+Dune::Amg::KAMG::Operator\n+Amg::Operator Operator\n+the type of the lineatr operator.\n+Definition: kamg.hh:155\n+Dune::Amg::KAMG::ParallelInformationHierarchy\n+Amg::ParallelInformationHierarchy ParallelInformationHierarchy\n+The type of the hierarchy of parallel information.\n+Definition: kamg.hh:161\n+Dune::Amg::KAMG::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: kamg.hh:166\n+Dune::Amg::KAMG::KrylovSolver\n+K KrylovSolver\n+The type of the Krylov solver for the cycle.\n+Definition: kamg.hh:145\n+Dune::Amg::KAmgTwoGrid\n+Two grid operator for AMG with Krylov cycle.\n+Definition: kamg.hh:33\n+Dune::Amg::KAmgTwoGrid::pre\n+void pre(typename AMG::Domain &x, typename AMG::Range &b)\n+Prepare the preconditioner.\n+Definition: kamg.hh:58\n+Dune::Amg::KAmgTwoGrid::KAmgTwoGrid\n+KAmgTwoGrid(AMG &amg, std::shared_ptr< InverseOperator< Domain, Range > >\n+coarseSolver)\n+Constructor.\n+Definition: kamg.hh:53\n+Dune::Amg::KAmgTwoGrid::~KAmgTwoGrid\n+~KAmgTwoGrid()\n+Destructor.\n+Definition: kamg.hh:110\n+Dune::Amg::KAmgTwoGrid::post\n+void post(typename AMG::Domain &x)\n+Clean up.\n+Definition: kamg.hh:62\n+Dune::Amg::KAmgTwoGrid::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: kamg.hh:41\n+Dune::Amg::KAmgTwoGrid::setLevelContext\n+void setLevelContext(std::shared_ptr< typename AMG::LevelContext > p)\n+Set the level context pointer.\n+Definition: kamg.hh:104\n+Dune::Amg::KAmgTwoGrid::coarseSolver\n+InverseOperator< Domain, Range > * coarseSolver()\n+Get a pointer to the coarse grid solver.\n+Definition: kamg.hh:95\n+Dune::Amg::KAmgTwoGrid::apply\n+void apply(typename AMG::Domain &v, const typename AMG::Range &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: kamg.hh:66\n+Dune::Amg::AMG\n+Parallel algebraic multigrid based on agglomeration.\n+Definition: amg.hh:65\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>\n+Dune::Amg::Hierarchy<_ParallelInformation,_Allocator_>::Iterator\n+LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation\n+> Iterator\n+Type of the mutable iterator.\n+Definition: hierarchy.hh:216\n+Dune::Amg::MatrixHierarchy\n+The hierarchies build by the coarsening process.\n+Definition: matrixhierarchy.hh:61\n+Dune::Amg::Parameters\n+All parameters for AMG.\n+Definition: parameters.hh:393\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::ScalarProduct\n+Base class for scalar product and norm computation.\n+Definition: scalarproducts.hh:52\n Dune::InverseOperatorResult\n Statistics about the application of an inverse operator.\n Definition: solver.hh:48\n-Dune::InverseOperatorResult::elapsed\n-double elapsed\n-Elapsed time in seconds.\n-Definition: solver.hh:82\n-Dune::InverseOperatorResult::iterations\n-int iterations\n-Number of iterations.\n-Definition: solver.hh:67\n-Dune::InverseOperatorResult::converged\n-bool converged\n-True if convergence criterion has been met.\n-Definition: solver.hh:73\n-Dune::InverseOperator\n-Abstract base class for all solvers.\n-Definition: solver.hh:99\n+Dune::InverseOperator<_Domain,_Range_>\n Dune::SolverCategory::Category\n Category\n Definition: solvercategory.hh:23\n-Dune::UnsupportedType\n-Definition: solverregistry.hh:77\n-Dune::IsDirectSolver\n-Definition: solvertype.hh:16\n-Dune::IsDirectSolver::value\n-@ value\n-Whether this is a direct solver.\n-Definition: solvertype.hh:24\n-Dune::StoresColumnCompressed\n-Definition: solvertype.hh:30\n-Dune::StoresColumnCompressed::value\n-@ value\n-whether the solver internally uses column compressed storage\n-Definition: solvertype.hh:36\n-Dune::UMFPackMethodChooser\n-Definition: umfpack.hh:49\n-Dune::UMFPack\n-The UMFPack direct sparse solver.\n-Definition: umfpack.hh:215\n-Dune::UMFPackCreator\n-Definition: umfpack.hh:609\n-Dune::UMFPackCreator::isValidBlock\n-Definition: umfpack.hh:610\n+Dune::GeneralizedPCGSolver\n+Generalized preconditioned conjugate gradient solver.\n+Definition: solvers.hh:1307\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00197.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00197.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bcrsmatrix.hh File Reference\n+dune-istl: solvers.hh File Reference\n \n \n \n \n \n \n \n@@ -64,73 +64,111 @@\n \n \n \n
    \n \n-
    bcrsmatrix.hh File Reference
    \n+Namespaces |\n+Functions
    \n+ \n \n
    \n \n-

    Implementation of the BCRSMatrix class. \n+

    Implementations of the inverse operator interface. \n More...

    \n-
    #include <cmath>
    \n+
    #include <array>
    \n+#include <cmath>
    \n #include <complex>
    \n-#include <set>
    \n #include <iostream>
    \n-#include <algorithm>
    \n-#include <numeric>
    \n-#include <vector>
    \n-#include <map>
    \n #include <memory>
    \n-#include "istlexception.hh"
    \n-#include "bvector.hh"
    \n-#include "matrixutils.hh"
    \n-#include <dune/common/stdstreams.hh>
    \n-#include <dune/common/iteratorfacades.hh>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/ftraits.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n+#include <type_traits>
    \n+#include <vector>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/common/math.hh>
    \n+#include <dune/common/simd/io.hh>
    \n+#include <dune/common/simd/simd.hh>
    \n+#include <dune/common/std/type_traits.hh>
    \n+#include <dune/common/timer.hh>
    \n+#include <dune/istl/allocator.hh>
    \n+#include <dune/istl/bcrsmatrix.hh>
    \n+#include <dune/istl/eigenvalue/arpackpp.hh>
    \n+#include <dune/istl/istlexception.hh>
    \n+#include <dune/istl/operators.hh>
    \n+#include <dune/istl/preconditioner.hh>
    \n+#include <dune/istl/scalarproducts.hh>
    \n+#include <dune/istl/solver.hh>
    \n+#include <dune/istl/solverregistry.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::CompressionStatistics< size_type >
     Statistics about compression achieved in implicit mode. More...
    class  Dune::LoopSolver< X >
     Preconditioned loop solver. More...
     
    class  Dune::GradientSolver< X >
     gradient method More...
     
    class  Dune::ImplicitMatrixBuilder< M_ >
     A wrapper for uniform access to the BCRSMatrix during and after the build stage in implicit build mode. More...
    class  Dune::CGSolver< X >
     conjugate gradient method More...
     
    class  Dune::ImplicitMatrixBuilder< M_ >::row_object
     Proxy row object for entry access. More...
    class  Dune::BiCGSTABSolver< X >
     Bi-conjugate Gradient Stabilized (BiCG-STAB) More...
     
    class  Dune::BCRSMatrix< B, A >
     A sparse block matrix with compressed row storage. More...
    class  Dune::MINRESSolver< X >
     Minimal Residual Method (MINRES) More...
     
    class  Dune::BCRSMatrix< B, A >::RealRowIterator< T >
     Iterator access to matrix rows More...
    class  Dune::RestartedGMResSolver< X, Y, F >
     implements the Generalized Minimal Residual (GMRes) method More...
     
    class  Dune::BCRSMatrix< B, A >::CreateIterator
     Iterator class for sequential creation of blocks More...
    class  Dune::RestartedFlexibleGMResSolver< X, Y, F >
     implements the Flexible Generalized Minimal Residual (FGMRes) method (right preconditioned) More...
     
    struct  Dune::FieldTraits< BCRSMatrix< B, A > >
    class  Dune::GeneralizedPCGSolver< X >
     Generalized preconditioned conjugate gradient solver. More...
     
    class  Dune::RestartedFCGSolver< X >
     Accelerated flexible conjugate gradient method. More...
     
    class  Dune::CompleteFCGSolver< X >
     Complete flexible conjugate gradient method. More...
     
    \n \n \n \n+

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("loopsolver", defaultIterativeSolverCreator< Dune::LoopSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("gradientsolver", defaultIterativeSolverCreator< Dune::GradientSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("cgsolver", defaultIterativeSolverCreator< Dune::CGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("bicgstabsolver", defaultIterativeSolverCreator< Dune::BiCGSTABSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("minressolver", defaultIterativeSolverCreator< Dune::MINRESSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedgmressolver", defaultIterativeSolverCreator< Dune::RestartedGMResSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedflexiblegmressolver", defaultIterativeSolverCreator< Dune::RestartedFlexibleGMResSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("generalizedpcgsolver", defaultIterativeSolverCreator< Dune::GeneralizedPCGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("restartedfcgsolver", defaultIterativeSolverCreator< Dune::RestartedFCGSolver >())
     
     Dune::DUNE_REGISTER_ITERATIVE_SOLVER ("completefcgsolver", defaultIterativeSolverCreator< Dune::CompleteFCGSolver >())
     
    \n

    Detailed Description

    \n-

    Implementation of the BCRSMatrix class.

    \n+

    Implementations of the inverse operator interface.

    \n+

    This file provides various preconditioned Krylov methods.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,60 +4,106 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-bcrsmatrix.hh File Reference\n-Implementation of the BCRSMatrix class. More...\n+Classes | Namespaces | Functions\n+solvers.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers\n+Implementations of the inverse operator interface. More...\n+#include \n #include \n #include \n-#include \n #include \n-#include \n-#include \n-#include \n-#include \n #include \n-#include \"istlexception.hh\"\n-#include \"bvector.hh\"\n-#include \"matrixutils.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::CompressionStatistics<_size_type_>\n-\u00a0 Statistics about compression achieved in implicit mode. More...\n+class \u00a0Dune::LoopSolver<_X_>\n+\u00a0 Preconditioned loop solver. More...\n+\u00a0\n+class \u00a0Dune::GradientSolver<_X_>\n+\u00a0 gradient method More...\n+\u00a0\n+class \u00a0Dune::CGSolver<_X_>\n+\u00a0 conjugate gradient method More...\n \u00a0\n- class \u00a0Dune::ImplicitMatrixBuilder<_M__>\n-\u00a0 A wrapper for uniform access to the BCRSMatrix during and after the\n- build stage in implicit build mode. More...\n+class \u00a0Dune::BiCGSTABSolver<_X_>\n+\u00a0 Bi-conjugate Gradient Stabilized (BiCG-STAB) More...\n \u00a0\n- class \u00a0Dune::ImplicitMatrixBuilder<_M__>::row_object\n-\u00a0 Proxy row object for entry access. More...\n+class \u00a0Dune::MINRESSolver<_X_>\n+\u00a0 Minimal Residual Method (MINRES) More...\n \u00a0\n- class \u00a0Dune::BCRSMatrix<_B,_A_>\n-\u00a0 A sparse block matrix with compressed row storage. More...\n+class \u00a0Dune::RestartedGMResSolver<_X,_Y,_F_>\n+\u00a0 implements the Generalized Minimal Residual (GMRes) method More...\n \u00a0\n- class \u00a0Dune::BCRSMatrix<_B,_A_>::RealRowIterator<_T_>\n-\u00a0 Iterator access to matrix rows More...\n+class \u00a0Dune::RestartedFlexibleGMResSolver<_X,_Y,_F_>\n+\u00a0 implements the Flexible Generalized Minimal Residual (FGMRes) method\n+ (right preconditioned) More...\n \u00a0\n- class \u00a0Dune::BCRSMatrix<_B,_A_>::CreateIterator\n-\u00a0 Iterator class for sequential creation of blocks More...\n+class \u00a0Dune::GeneralizedPCGSolver<_X_>\n+\u00a0 Generalized preconditioned conjugate gradient solver. More...\n \u00a0\n-struct \u00a0Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>\n+class \u00a0Dune::RestartedFCGSolver<_X_>\n+\u00a0 Accelerated flexible conjugate gradient method. More...\n+\u00a0\n+class \u00a0Dune::CompleteFCGSolver<_X_>\n+\u00a0 Complete flexible conjugate gradient method. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Functions\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"loopsolver\",\n+ defaultIterativeSolverCreator< Dune::LoopSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"gradientsolver\",\n+ defaultIterativeSolverCreator< Dune::GradientSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"cgsolver\",\n+ defaultIterativeSolverCreator< Dune::CGSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"bicgstabsolver\",\n+ defaultIterativeSolverCreator< Dune::BiCGSTABSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"minressolver\",\n+ defaultIterativeSolverCreator< Dune::MINRESSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedgmressolver\",\n+ defaultIterativeSolverCreator< Dune::RestartedGMResSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedflexiblegmressolver\",\n+ defaultIterativeSolverCreator< Dune::RestartedFlexibleGMResSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"generalizedpcgsolver\",\n+ defaultIterativeSolverCreator< Dune::GeneralizedPCGSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"restartedfcgsolver\",\n+ defaultIterativeSolverCreator< Dune::RestartedFCGSolver >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_ITERATIVE_SOLVER (\"completefcgsolver\",\n+ defaultIterativeSolverCreator< Dune::CompleteFCGSolver >())\n+\u00a0\n ***** Detailed Description *****\n-Implementation of the BCRSMatrix class.\n+Implementations of the inverse operator interface.\n+This file provides various preconditioned Krylov methods.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00197_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00197_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bcrsmatrix.hh Source File\n+dune-istl: solvers.hh Source File\n \n \n \n \n \n \n \n@@ -62,1875 +62,1584 @@\n \n
    \n \n
    \n
    \n
    \n-
    bcrsmatrix.hh
    \n+
    solvers.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n
    5
    \n-
    6#ifndef DUNE_ISTL_BCRSMATRIX_HH
    \n-
    7#define DUNE_ISTL_BCRSMATRIX_HH
    \n+
    6#ifndef DUNE_ISTL_SOLVERS_HH
    \n+
    7#define DUNE_ISTL_SOLVERS_HH
    \n
    8
    \n-
    9#include <cmath>
    \n-
    10#include <complex>
    \n-
    11#include <set>
    \n+
    9#include <array>
    \n+
    10#include <cmath>
    \n+
    11#include <complex>
    \n
    12#include <iostream>
    \n-
    13#include <algorithm>
    \n-
    14#include <numeric>
    \n+
    13#include <memory>
    \n+
    14#include <type_traits>
    \n
    15#include <vector>
    \n-
    16#include <map>
    \n-
    17#include <memory>
    \n-
    18
    \n-
    19#include "istlexception.hh"
    \n-
    20#include "bvector.hh"
    \n-
    21#include "matrixutils.hh"
    \n-
    22#include <dune/common/stdstreams.hh>
    \n-
    23#include <dune/common/iteratorfacades.hh>
    \n-
    24#include <dune/common/typetraits.hh>
    \n-
    25#include <dune/common/ftraits.hh>
    \n-
    26#include <dune/common/scalarvectorview.hh>
    \n-
    27#include <dune/common/scalarmatrixview.hh>
    \n-
    28
    \n-\n-
    30
    \n-
    35namespace Dune {
    \n-
    36
    \n-
    76 template<typename M>
    \n-
    77 struct MatrixDimension;
    \n-
    78
    \n+
    16
    \n+
    17#include <dune/common/exceptions.hh>
    \n+
    18#include <dune/common/math.hh>
    \n+
    19#include <dune/common/simd/io.hh>
    \n+
    20#include <dune/common/simd/simd.hh>
    \n+
    21#include <dune/common/std/type_traits.hh>
    \n+
    22#include <dune/common/timer.hh>
    \n+
    23
    \n+\n+\n+\n+\n+\n+\n+\n+
    31#include <dune/istl/solver.hh>
    \n+\n+
    33
    \n+
    34namespace Dune {
    \n+
    46 //=====================================================================
    \n+
    47 // Implementation of this interface
    \n+
    48 //=====================================================================
    \n+
    49
    \n+
    58 template<class X>
    \n+
    59 class LoopSolver : public IterativeSolver<X,X> {
    \n+
    60 public:
    \n+\n+\n+\n+\n+
    65
    \n+
    66 // copy base class constructors
    \n+\n+
    68
    \n+
    69 // don't shadow four-argument version of apply defined in the base class
    \n+
    70 using IterativeSolver<X,X>::apply;
    \n+
    71
    \n+
    73 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    74 {
    \n+
    75 Iteration iteration(*this, res);
    \n+
    76 _prec->pre(x,b);
    \n+
    77
    \n+
    78 // overwrite b with defect
    \n+
    79 _op->applyscaleadd(-1,x,b);
    \n
    80
    \n-
    86 template<typename size_type>
    \n-\n-
    88 {
    \n-
    90 double avg;
    \n-
    92 size_type maximum;
    \n-
    94 size_type overflow_total;
    \n-
    96
    \n-
    99 double mem_ratio;
    \n-
    100 };
    \n-
    101
    \n-
    103
    \n-
    115 template<class M_>
    \n-\n-
    117 {
    \n-
    118
    \n-
    119 public:
    \n+
    81 // compute norm, \\todo parallelization
    \n+
    82 real_type def = _sp->norm(b);
    \n+
    83 if(iteration.step(0, def)){
    \n+
    84 _prec->post(x);
    \n+
    85 return;
    \n+
    86 }
    \n+
    87 // prepare preconditioner
    \n+
    88
    \n+
    89 // allocate correction vector
    \n+
    90 X v(x);
    \n+
    91
    \n+
    92 // iteration loop
    \n+
    93 int i=1;
    \n+
    94 for ( ; i<=_maxit; i++ )
    \n+
    95 {
    \n+
    96 v = 0; // clear correction
    \n+
    97 _prec->apply(v,b); // apply preconditioner
    \n+
    98 x += v; // update solution
    \n+
    99 _op->applyscaleadd(-1,v,b); // update defect
    \n+
    100 def=_sp->norm(b); // comp defect norm
    \n+
    101 if(iteration.step(i, def))
    \n+
    102 break;
    \n+
    103 }
    \n+
    104
    \n+
    105 // postprocess preconditioner
    \n+
    106 _prec->post(x);
    \n+
    107 }
    \n+
    108
    \n+
    109 protected:
    \n+
    110 using IterativeSolver<X,X>::_op;
    \n+
    111 using IterativeSolver<X,X>::_prec;
    \n+
    112 using IterativeSolver<X,X>::_sp;
    \n+\n+
    114 using IterativeSolver<X,X>::_maxit;
    \n+
    115 using IterativeSolver<X,X>::_verbose;
    \n+\n+
    117 };
    \n+
    118 DUNE_REGISTER_ITERATIVE_SOLVER("loopsolver", defaultIterativeSolverCreator<Dune::LoopSolver>());
    \n+
    119
    \n
    120
    \n-
    122 typedef M_ Matrix;
    \n-
    123
    \n-\n-
    126
    \n-
    128 typedef typename Matrix::size_type size_type;
    \n-
    129
    \n-
    131
    \n-\n-
    137 {
    \n-
    138
    \n-
    139 public:
    \n-
    140
    \n-\n-
    143 {
    \n-
    144 return _m.entry(_i,j);
    \n-
    145 }
    \n+
    121 // all these solvers are taken from the SUMO library
    \n+
    123 template<class X>
    \n+
    124 class GradientSolver : public IterativeSolver<X,X> {
    \n+
    125 public:
    \n+\n+\n+\n+
    129 using typename IterativeSolver<X,X>::real_type;
    \n+
    130
    \n+
    131 // copy base class constructors
    \n+\n+
    133
    \n+
    134 // don't shadow four-argument version of apply defined in the base class
    \n+
    135 using IterativeSolver<X,X>::apply;
    \n+
    136
    \n+
    142 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    143 {
    \n+
    144 Iteration iteration(*this, res);
    \n+
    145 _prec->pre(x,b); // prepare preconditioner
    \n
    146
    \n-
    147#ifndef DOXYGEN
    \n+
    147 _op->applyscaleadd(-1,x,b); // overwrite b with defec
    \n
    148
    \n-\n-
    150 : _m(m)
    \n-
    151 , _i(i)
    \n-
    152 {}
    \n-
    153
    \n-
    154#endif
    \n-
    155
    \n-
    156 private:
    \n+
    149 real_type def = _sp->norm(b); // compute norm
    \n+
    150 if(iteration.step(0, def)){
    \n+
    151 _prec->post(x);
    \n+
    152 return;
    \n+
    153 }
    \n+
    154
    \n+
    155 X p(x); // create local vectors
    \n+
    156 X q(b);
    \n
    157
    \n-
    158 Matrix& _m;
    \n-\n-
    160
    \n-
    161 };
    \n-
    162
    \n-
    164
    \n-\n-
    171 : _m(m)
    \n-
    172 {
    \n-
    173 if (m.buildMode() != Matrix::implicit)
    \n-
    174 DUNE_THROW(BCRSMatrixError,"You can only create an ImplicitBuilder for a matrix in implicit build mode");
    \n-
    175 if (m.buildStage() != Matrix::building)
    \n-
    176 DUNE_THROW(BCRSMatrixError,"You can only create an ImplicitBuilder for a matrix with set size that has not been compressed() yet");
    \n-
    177 }
    \n-
    178
    \n-
    180
    \n-
    194 ImplicitMatrixBuilder(Matrix& m, size_type rows, size_type cols, size_type avg_cols_per_row, double overflow_fraction)
    \n-
    195 : _m(m)
    \n-
    196 {
    \n-
    197 if (m.buildStage() != Matrix::notAllocated)
    \n-
    198 DUNE_THROW(BCRSMatrixError,"You can only set up a matrix for this ImplicitBuilder if it has no memory allocated yet");
    \n-
    199 m.setBuildMode(Matrix::implicit);
    \n-
    200 m.setImplicitBuildModeParameters(avg_cols_per_row,overflow_fraction);
    \n-
    201 m.setSize(rows,cols);
    \n-
    202 }
    \n-
    203
    \n-\n-
    206 {
    \n-
    207 return row_object(_m,i);
    \n-
    208 }
    \n+
    158 int i=1; // loop variables
    \n+
    159 field_type lambda;
    \n+
    160 for ( ; i<=_maxit; i++ )
    \n+
    161 {
    \n+
    162 p = 0; // clear correction
    \n+
    163 _prec->apply(p,b); // apply preconditioner
    \n+
    164 _op->apply(p,q); // q=Ap
    \n+
    165 auto alpha = _sp->dot(q,p);
    \n+
    166 lambda = Simd::cond(def==field_type(0.),
    \n+
    167 field_type(0.), // no need for minimization if def is already 0
    \n+
    168 _sp->dot(p,b)/alpha); // minimization
    \n+
    169 x.axpy(lambda,p); // update solution
    \n+
    170 b.axpy(-lambda,q); // update defect
    \n+
    171
    \n+
    172 def =_sp->norm(b); // comp defect norm
    \n+
    173 if(iteration.step(i, def))
    \n+
    174 break;
    \n+
    175 }
    \n+
    176 // postprocess preconditioner
    \n+
    177 _prec->post(x);
    \n+
    178 }
    \n+
    179
    \n+
    180 protected:
    \n+
    181 using IterativeSolver<X,X>::_op;
    \n+
    182 using IterativeSolver<X,X>::_prec;
    \n+
    183 using IterativeSolver<X,X>::_sp;
    \n+\n+
    185 using IterativeSolver<X,X>::_maxit;
    \n+
    186 using IterativeSolver<X,X>::_verbose;
    \n+\n+
    188 };
    \n+
    189 DUNE_REGISTER_ITERATIVE_SOLVER("gradientsolver", defaultIterativeSolverCreator<Dune::GradientSolver>());
    \n+
    190
    \n+
    192 template<class X>
    \n+
    193 class CGSolver : public IterativeSolver<X,X> {
    \n+
    194 public:
    \n+\n+\n+\n+
    198 using typename IterativeSolver<X,X>::real_type;
    \n+
    199
    \n+
    200 // copy base class constructors
    \n+\n+
    202
    \n+
    203 private:
    \n+\n+
    205
    \n+
    206 protected:
    \n+
    207
    \n+
    208 static constexpr bool enableConditionEstimate = (std::is_same_v<field_type,float> || std::is_same_v<field_type,double>);
    \n
    209
    \n-
    211 size_type N() const
    \n-
    212 {
    \n-
    213 return _m.N();
    \n-
    214 }
    \n-
    215
    \n-
    217 size_type M() const
    \n-
    218 {
    \n-
    219 return _m.M();
    \n-
    220 }
    \n-
    221
    \n-
    222 private:
    \n-
    223
    \n-
    224 Matrix& _m;
    \n-
    225
    \n-
    226 };
    \n-
    227
    \n-
    464 template<class B, class A=std::allocator<B> >
    \n-\n-
    466 {
    \n-
    467 friend struct MatrixDimension<BCRSMatrix>;
    \n-
    468 public:
    \n-\n-\n-\n-\n-\n-
    482 built=3
    \n-
    483 };
    \n-
    484
    \n-
    485 //===== type definitions and constants
    \n-
    486
    \n-
    488 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    489
    \n-
    491 typedef B block_type;
    \n-
    492
    \n-
    494 typedef A allocator_type;
    \n-
    495
    \n-
    497 typedef Imp::CompressedBlockVectorWindow<B,A> row_type;
    \n-
    498
    \n-
    500 typedef typename A::size_type size_type;
    \n-
    501
    \n-
    503 typedef ::Dune::CompressionStatistics<size_type> CompressionStatistics;
    \n+
    210 public:
    \n+
    211
    \n+
    212 // don't shadow four-argument version of apply defined in the base class
    \n+
    213 using IterativeSolver<X,X>::apply;
    \n+
    214
    \n+\n+
    223 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate) : IterativeSolver<X,X>(op, prec, reduction, maxit, verbose),
    \n+
    224 condition_estimate_(condition_estimate)
    \n+
    225 {
    \n+
    226 if (condition_estimate && !enableConditionEstimate) {
    \n+
    227 condition_estimate_ = false;
    \n+
    228 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n+
    229 }
    \n+
    230 }
    \n+
    231
    \n+\n+
    240 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate) : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose),
    \n+
    241 condition_estimate_(condition_estimate)
    \n+
    242 {
    \n+
    243 if (condition_estimate && !(std::is_same<field_type,float>::value || std::is_same<field_type,double>::value)) {
    \n+
    244 condition_estimate_ = false;
    \n+
    245 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n+
    246 }
    \n+
    247 }
    \n+
    248
    \n+
    256 CGSolver (std::shared_ptr<const LinearOperator<X,X>> op, std::shared_ptr<ScalarProduct<X>> sp,
    \n+
    257 std::shared_ptr<Preconditioner<X,X>> prec,
    \n+
    258 scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    \n+
    259 : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose),
    \n+
    260 condition_estimate_(condition_estimate)
    \n+
    261 {
    \n+
    262 if (condition_estimate && !(std::is_same<field_type,float>::value || std::is_same<field_type,double>::value)) {
    \n+
    263 condition_estimate_ = false;
    \n+
    264 std::cerr << "WARNING: Condition estimate was disabled. It is only available for double and float field types!" << std::endl;
    \n+
    265 }
    \n+
    266 }
    \n+
    267
    \n+
    279 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    280 {
    \n+
    281 Iteration iteration(*this,res);
    \n+
    282 _prec->pre(x,b); // prepare preconditioner
    \n+
    283
    \n+
    284 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n+
    285
    \n+
    286 real_type def = _sp->norm(b); // compute norm
    \n+
    287 if(iteration.step(0, def)){
    \n+
    288 _prec->post(x);
    \n+
    289 return;
    \n+
    290 }
    \n+
    291
    \n+
    292 X p(x); // the search direction
    \n+
    293 X q(x); // a temporary vector
    \n+
    294
    \n+
    295 // Remember lambda and beta values for condition estimate
    \n+
    296 std::vector<real_type> lambdas(0);
    \n+
    297 std::vector<real_type> betas(0);
    \n+
    298
    \n+
    299 // some local variables
    \n+
    300 field_type rho,rholast,lambda,alpha,beta;
    \n+
    301
    \n+
    302 // determine initial search direction
    \n+
    303 p = 0; // clear correction
    \n+
    304 _prec->apply(p,b); // apply preconditioner
    \n+
    305 rholast = _sp->dot(p,b); // orthogonalization
    \n+
    306
    \n+
    307 // the loop
    \n+
    308 int i=1;
    \n+
    309 for ( ; i<=_maxit; i++ )
    \n+
    310 {
    \n+
    311 // minimize in given search direction p
    \n+
    312 _op->apply(p,q); // q=Ap
    \n+
    313 alpha = _sp->dot(p,q); // scalar product
    \n+
    314 lambda = Simd::cond(def==field_type(0.), field_type(0.), rholast/alpha); // minimization
    \n+
    315 if constexpr (enableConditionEstimate)
    \n+
    316 if (condition_estimate_)
    \n+
    317 lambdas.push_back(std::real(lambda));
    \n+
    318 x.axpy(lambda,p); // update solution
    \n+
    319 b.axpy(-lambda,q); // update defect
    \n+
    320
    \n+
    321 // convergence test
    \n+
    322 def=_sp->norm(b); // comp defect norm
    \n+
    323 if(iteration.step(i, def))
    \n+
    324 break;
    \n+
    325
    \n+
    326 // determine new search direction
    \n+
    327 q = 0; // clear correction
    \n+
    328 _prec->apply(q,b); // apply preconditioner
    \n+
    329 rho = _sp->dot(q,b); // orthogonalization
    \n+
    330 beta = Simd::cond(def==field_type(0.), field_type(0.), rho/rholast); // scaling factor
    \n+
    331 if constexpr (enableConditionEstimate)
    \n+
    332 if (condition_estimate_)
    \n+
    333 betas.push_back(std::real(beta));
    \n+
    334 p *= beta; // scale old search direction
    \n+
    335 p += q; // orthogonalization with correction
    \n+
    336 rholast = rho; // remember rho for recurrence
    \n+
    337 }
    \n+
    338
    \n+
    339 _prec->post(x); // postprocess preconditioner
    \n+
    340
    \n+
    341 if (condition_estimate_) {
    \n+
    342#if HAVE_ARPACKPP
    \n+
    343 if constexpr (enableConditionEstimate) {
    \n+
    344 using std::sqrt;
    \n+
    345
    \n+
    346 // Build T matrix which has extreme eigenvalues approximating
    \n+
    347 // those of the original system
    \n+
    348 // (see Y. Saad, Iterative methods for sparse linear systems)
    \n+
    349
    \n+\n+
    351
    \n+
    352 for (auto row = T.createbegin(); row != T.createend(); ++row) {
    \n+
    353 if (row.index() > 0)
    \n+
    354 row.insert(row.index()-1);
    \n+
    355 row.insert(row.index());
    \n+
    356 if (row.index() < T.N() - 1)
    \n+
    357 row.insert(row.index()+1);
    \n+
    358 }
    \n+
    359 for (int row = 0; row < i; ++row) {
    \n+
    360 if (row > 0) {
    \n+
    361 T[row][row-1] = sqrt(betas[row-1]) / lambdas[row-1];
    \n+
    362 }
    \n+
    363
    \n+
    364 T[row][row] = 1.0 / lambdas[row];
    \n+
    365 if (row > 0) {
    \n+
    366 T[row][row] += betas[row-1] / lambdas[row-1];
    \n+
    367 }
    \n+
    368
    \n+
    369 if (row < i - 1) {
    \n+
    370 T[row][row+1] = sqrt(betas[row]) / lambdas[row];
    \n+
    371 }
    \n+
    372 }
    \n+
    373
    \n+
    374 // Compute largest and smallest eigenvalue of T matrix and return as estimate
    \n+\n+
    376
    \n+
    377 real_type eps = 0.0;
    \n+
    378 COND_VEC eigv;
    \n+
    379 real_type min_eigv, max_eigv;
    \n+
    380 arpack.computeSymMinMagnitude (eps, eigv, min_eigv);
    \n+
    381 arpack.computeSymMaxMagnitude (eps, eigv, max_eigv);
    \n+
    382
    \n+
    383 res.condition_estimate = max_eigv / min_eigv;
    \n+
    384
    \n+
    385 if (this->_verbose > 0) {
    \n+
    386 std::cout << "Min eigv estimate: " << Simd::io(min_eigv) << '\\n';
    \n+
    387 std::cout << "Max eigv estimate: " << Simd::io(max_eigv) << '\\n';
    \n+
    388 std::cout << "Condition estimate: "
    \n+
    389 << Simd::io(max_eigv / min_eigv) << std::endl;
    \n+
    390 }
    \n+
    391 }
    \n+
    392#else
    \n+
    393 std::cerr << "WARNING: Condition estimate was requested. This requires ARPACK, but ARPACK was not found!" << std::endl;
    \n+
    394#endif
    \n+
    395 }
    \n+
    396 }
    \n+
    397
    \n+
    398 private:
    \n+
    399 bool condition_estimate_ = false;
    \n+
    400
    \n+
    401 // Matrix and vector types used for condition estimate
    \n+\n+\n+
    404
    \n+
    405 protected:
    \n+
    406 using IterativeSolver<X,X>::_op;
    \n+
    407 using IterativeSolver<X,X>::_prec;
    \n+
    408 using IterativeSolver<X,X>::_sp;
    \n+\n+
    410 using IterativeSolver<X,X>::_maxit;
    \n+
    411 using IterativeSolver<X,X>::_verbose;
    \n+\n+
    413 };
    \n+
    414 DUNE_REGISTER_ITERATIVE_SOLVER("cgsolver", defaultIterativeSolverCreator<Dune::CGSolver>());
    \n+
    415
    \n+
    416 // Ronald Kriemanns BiCG-STAB implementation from Sumo
    \n+
    418 template<class X>
    \n+
    419 class BiCGSTABSolver : public IterativeSolver<X,X> {
    \n+
    420 public:
    \n+\n+\n+\n+
    424 using typename IterativeSolver<X,X>::real_type;
    \n+
    425
    \n+
    426 // copy base class constructors
    \n+\n+
    428
    \n+
    429 // don't shadow four-argument version of apply defined in the base class
    \n+
    430 using IterativeSolver<X,X>::apply;
    \n+
    431
    \n+
    439 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    440 {
    \n+
    441 using std::abs;
    \n+
    442 const Simd::Scalar<real_type> EPSILON=1e-80;
    \n+
    443 using std::abs;
    \n+
    444 double it;
    \n+
    445 field_type rho, rho_new, alpha, beta, h, omega;
    \n+
    446 real_type norm;
    \n+
    447
    \n+
    448 //
    \n+
    449 // get vectors and matrix
    \n+
    450 //
    \n+
    451 X& r=b;
    \n+
    452 X p(x);
    \n+
    453 X v(x);
    \n+
    454 X t(x);
    \n+
    455 X y(x);
    \n+
    456 X rt(x);
    \n+
    457
    \n+
    458 //
    \n+
    459 // begin iteration
    \n+
    460 //
    \n+
    461
    \n+
    462 // r = r - Ax; rt = r
    \n+
    463 Iteration<double> iteration(*this,res);
    \n+
    464 _prec->pre(x,r); // prepare preconditioner
    \n+
    465
    \n+
    466 _op->applyscaleadd(-1,x,r); // overwrite b with defect
    \n+
    467
    \n+
    468 rt=r;
    \n+
    469
    \n+
    470 norm = _sp->norm(r);
    \n+
    471 if(iteration.step(0, norm)){
    \n+
    472 _prec->post(x);
    \n+
    473 return;
    \n+
    474 }
    \n+
    475 p=0;
    \n+
    476 v=0;
    \n+
    477
    \n+
    478 rho = 1;
    \n+
    479 alpha = 1;
    \n+
    480 omega = 1;
    \n+
    481
    \n+
    482 //
    \n+
    483 // iteration
    \n+
    484 //
    \n+
    485
    \n+
    486 for (it = 0.5; it < _maxit; it+=.5)
    \n+
    487 {
    \n+
    488 //
    \n+
    489 // preprocess, set vecsizes etc.
    \n+
    490 //
    \n+
    491
    \n+
    492 // rho_new = < rt , r >
    \n+
    493 rho_new = _sp->dot(rt,r);
    \n+
    494
    \n+
    495 // look if breakdown occurred
    \n+
    496 if (Simd::allTrue(abs(rho) <= EPSILON))
    \n+
    497 DUNE_THROW(SolverAbort,"breakdown in BiCGSTAB - rho "
    \n+
    498 << Simd::io(rho) << " <= EPSILON " << EPSILON
    \n+
    499 << " after " << it << " iterations");
    \n+
    500 if (Simd::allTrue(abs(omega) <= EPSILON))
    \n+
    501 DUNE_THROW(SolverAbort,"breakdown in BiCGSTAB - omega "
    \n+
    502 << Simd::io(omega) << " <= EPSILON " << EPSILON
    \n+
    503 << " after " << it << " iterations");
    \n
    504
    \n-
    506 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    507 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
    \n-
    508
    \n-\n-\n-\n-\n-
    543 unknown
    \n-
    544 };
    \n-
    545
    \n-
    546 //===== random access interface to rows of the matrix
    \n+
    505
    \n+
    506 if (it<1)
    \n+
    507 p = r;
    \n+
    508 else
    \n+
    509 {
    \n+
    510 beta = Simd::cond(norm==field_type(0.),
    \n+
    511 field_type(0.), // no need for orthogonalization if norm is already 0
    \n+
    512 ( rho_new / rho ) * ( alpha / omega ));
    \n+
    513 p.axpy(-omega,v); // p = r + beta (p - omega*v)
    \n+
    514 p *= beta;
    \n+
    515 p += r;
    \n+
    516 }
    \n+
    517
    \n+
    518 // y = W^-1 * p
    \n+
    519 y = 0;
    \n+
    520 _prec->apply(y,p); // apply preconditioner
    \n+
    521
    \n+
    522 // v = A * y
    \n+
    523 _op->apply(y,v);
    \n+
    524
    \n+
    525 // alpha = rho_new / < rt, v >
    \n+
    526 h = _sp->dot(rt,v);
    \n+
    527
    \n+
    528 if ( Simd::allTrue(abs(h) < EPSILON) )
    \n+
    529 DUNE_THROW(SolverAbort,"abs(h) < EPSILON in BiCGSTAB - abs(h) "
    \n+
    530 << Simd::io(abs(h)) << " < EPSILON " << EPSILON
    \n+
    531 << " after " << it << " iterations");
    \n+
    532
    \n+
    533 alpha = Simd::cond(norm==field_type(0.),
    \n+
    534 field_type(0.),
    \n+
    535 rho_new / h);
    \n+
    536
    \n+
    537 // apply first correction to x
    \n+
    538 // x <- x + alpha y
    \n+
    539 x.axpy(alpha,y);
    \n+
    540
    \n+
    541 // r = r - alpha*v
    \n+
    542 r.axpy(-alpha,v);
    \n+
    543
    \n+
    544 //
    \n+
    545 // test stop criteria
    \n+
    546 //
    \n
    547
    \n-\n-
    550 {
    \n-
    551#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    552 if (build_mode == implicit && ready != built)
    \n-
    553 DUNE_THROW(BCRSMatrixError,"You cannot use operator[] in implicit build mode before calling compress()");
    \n-
    554 if (r==0) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n-
    555 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    556#endif
    \n-
    557 return r[i];
    \n-
    558 }
    \n-
    559
    \n-\n-
    562 {
    \n-
    563#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    564 if (build_mode == implicit && ready != built)
    \n-
    565 DUNE_THROW(BCRSMatrixError,"You cannot use operator[] in implicit build mode before calling compress()");
    \n-
    566 if (built!=ready) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n-
    567 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    568#endif
    \n-
    569 return r[i];
    \n-
    570 }
    \n+
    548 norm = _sp->norm(r);
    \n+
    549 if(iteration.step(it, norm)){
    \n+
    550 break;
    \n+
    551 }
    \n+
    552
    \n+
    553 it+=.5;
    \n+
    554
    \n+
    555 // y = W^-1 * r
    \n+
    556 y = 0;
    \n+
    557 _prec->apply(y,r);
    \n+
    558
    \n+
    559 // t = A * y
    \n+
    560 _op->apply(y,t);
    \n+
    561
    \n+
    562 // omega = < t, r > / < t, t >
    \n+
    563 h = _sp->dot(t,t);
    \n+
    564 omega = Simd::cond(norm==field_type(0.),
    \n+
    565 field_type(0.),
    \n+
    566 _sp->dot(t,r)/h);
    \n+
    567
    \n+
    568 // apply second correction to x
    \n+
    569 // x <- x + omega y
    \n+
    570 x.axpy(omega,y);
    \n
    571
    \n-
    572
    \n-
    573 //===== iterator interface to rows of the matrix
    \n+
    572 // r = s - omega*t (remember : r = s)
    \n+
    573 r.axpy(-omega,t);
    \n
    574
    \n-
    576 template<class T>
    \n-\n-
    578 : public RandomAccessIteratorFacade<RealRowIterator<T>, T>
    \n-
    579 {
    \n+
    575 rho = rho_new;
    \n+
    576
    \n+
    577 //
    \n+
    578 // test stop criteria
    \n+
    579 //
    \n
    580
    \n-
    581 public:
    \n-
    583 typedef typename std::remove_const<T>::type ValueType;
    \n-
    584
    \n-
    585 friend class RandomAccessIteratorFacade<RealRowIterator<const ValueType>, const ValueType>;
    \n-
    586 friend class RandomAccessIteratorFacade<RealRowIterator<ValueType>, ValueType>;
    \n-
    587 friend class RealRowIterator<const ValueType>;
    \n-
    588 friend class RealRowIterator<ValueType>;
    \n+
    581 norm = _sp->norm(r);
    \n+
    582 if(iteration.step(it, norm)){
    \n+
    583 break;
    \n+
    584 }
    \n+
    585 } // end for
    \n+
    586
    \n+
    587 _prec->post(x); // postprocess preconditioner
    \n+
    588 }
    \n
    589
    \n-\n-
    592 : p(_p), i(_i)
    \n-
    593 {}
    \n-
    594
    \n-\n-
    597 : p(0), i(0)
    \n-
    598 {}
    \n-
    599
    \n-\n-
    601 : p(it.p), i(it.i)
    \n-
    602 {}
    \n-
    603
    \n-
    604
    \n-\n-
    607 {
    \n-
    608 return i;
    \n-
    609 }
    \n-
    610
    \n-
    611 std::ptrdiff_t distanceTo(const RealRowIterator<ValueType>& other) const
    \n-
    612 {
    \n-
    613 assert(other.p==p);
    \n-
    614 return (other.i-i);
    \n-
    615 }
    \n-
    616
    \n-
    617 std::ptrdiff_t distanceTo(const RealRowIterator<const ValueType>& other) const
    \n-
    618 {
    \n-
    619 assert(other.p==p);
    \n-
    620 return (other.i-i);
    \n-
    621 }
    \n-
    622
    \n-
    624 bool equals (const RealRowIterator<ValueType>& other) const
    \n-
    625 {
    \n-
    626 assert(other.p==p);
    \n-
    627 return i==other.i;
    \n-
    628 }
    \n-
    629
    \n-
    631 bool equals (const RealRowIterator<const ValueType>& other) const
    \n-
    632 {
    \n-
    633 assert(other.p==p);
    \n-
    634 return i==other.i;
    \n-
    635 }
    \n-
    636
    \n-
    637 private:
    \n-
    639 void increment()
    \n-
    640 {
    \n-
    641 ++i;
    \n-
    642 }
    \n-
    643
    \n-
    645 void decrement()
    \n-
    646 {
    \n-
    647 --i;
    \n+
    590 protected:
    \n+
    591 using IterativeSolver<X,X>::_op;
    \n+
    592 using IterativeSolver<X,X>::_prec;
    \n+
    593 using IterativeSolver<X,X>::_sp;
    \n+\n+
    595 using IterativeSolver<X,X>::_maxit;
    \n+
    596 using IterativeSolver<X,X>::_verbose;
    \n+
    597 template<class CountType>
    \n+\n+
    599 };
    \n+
    600 DUNE_REGISTER_ITERATIVE_SOLVER("bicgstabsolver", defaultIterativeSolverCreator<Dune::BiCGSTABSolver>());
    \n+
    601
    \n+
    608 template<class X>
    \n+
    609 class MINRESSolver : public IterativeSolver<X,X> {
    \n+
    610 public:
    \n+\n+\n+\n+
    614 using typename IterativeSolver<X,X>::real_type;
    \n+
    615
    \n+
    616 // copy base class constructors
    \n+\n+
    618
    \n+
    619 // don't shadow four-argument version of apply defined in the base class
    \n+
    620 using IterativeSolver<X,X>::apply;
    \n+
    621
    \n+
    627 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    628 {
    \n+
    629 using std::sqrt;
    \n+
    630 using std::abs;
    \n+
    631 Iteration iteration(*this, res);
    \n+
    632 // prepare preconditioner
    \n+
    633 _prec->pre(x,b);
    \n+
    634
    \n+
    635 // overwrite rhs with defect
    \n+
    636 _op->applyscaleadd(-1.0,x,b); // b -= Ax
    \n+
    637
    \n+
    638 // some temporary vectors
    \n+
    639 X z(b), dummy(b);
    \n+
    640 z = 0.0;
    \n+
    641
    \n+
    642 // calculate preconditioned defect
    \n+
    643 _prec->apply(z,b); // r = W^-1 (b - Ax)
    \n+
    644 real_type def = _sp->norm(z);
    \n+
    645 if (iteration.step(0, def)){
    \n+
    646 _prec->post(x);
    \n+
    647 return;
    \n
    648 }
    \n
    649
    \n-
    650 void advance(std::ptrdiff_t diff)
    \n-
    651 {
    \n-
    652 i+=diff;
    \n-
    653 }
    \n-
    654
    \n-
    655 T& elementAt(std::ptrdiff_t diff) const
    \n-
    656 {
    \n-
    657 return p[i+diff];
    \n-
    658 }
    \n+
    650 // recurrence coefficients as computed in Lanczos algorithm
    \n+
    651 field_type alpha, beta;
    \n+
    652 // diagonal entries of givens rotation
    \n+
    653 std::array<real_type,2> c{{0.0,0.0}};
    \n+
    654 // off-diagonal entries of givens rotation
    \n+
    655 std::array<field_type,2> s{{0.0,0.0}};
    \n+
    656
    \n+
    657 // recurrence coefficients (column k of tridiag matrix T_k)
    \n+
    658 std::array<field_type,3> T{{0.0,0.0,0.0}};
    \n
    659
    \n-
    661 row_type& dereference () const
    \n-
    662 {
    \n-
    663 return p[i];
    \n-
    664 }
    \n-
    665
    \n-
    666 row_type* p;
    \n-
    667 size_type i;
    \n-
    668 };
    \n-
    669
    \n-\n-\n+
    660 // the rhs vector of the min problem
    \n+
    661 std::array<field_type,2> xi{{1.0,0.0}};
    \n+
    662
    \n+
    663 // beta is real and positive in exact arithmetic
    \n+
    664 // since it is the norm of the basis vectors (in unpreconditioned case)
    \n+
    665 beta = sqrt(_sp->dot(b,z));
    \n+
    666 field_type beta0 = beta;
    \n+
    667
    \n+
    668 // the search directions
    \n+
    669 std::array<X,3> p{{b,b,b}};
    \n+
    670 p[0] = 0.0;
    \n+
    671 p[1] = 0.0;
    \n+
    672 p[2] = 0.0;
    \n
    673
    \n-\n-
    676 {
    \n-
    677 return Iterator(r,0);
    \n-
    678 }
    \n-
    679
    \n-\n-
    682 {
    \n-
    683 return Iterator(r,n);
    \n-
    684 }
    \n+
    674 // orthonormal basis vectors (in unpreconditioned case)
    \n+
    675 std::array<X,3> q{{b,b,b}};
    \n+
    676 q[0] = 0.0;
    \n+
    677 q[1] *= Simd::cond(def==field_type(0.),
    \n+
    678 field_type(0.),
    \n+
    679 real_type(1.0)/beta);
    \n+
    680 q[2] = 0.0;
    \n+
    681
    \n+
    682 z *= Simd::cond(def==field_type(0.),
    \n+
    683 field_type(0.),
    \n+
    684 real_type(1.0)/beta);
    \n
    685
    \n-\n-
    689 {
    \n-
    690 return Iterator(r,n-1);
    \n-
    691 }
    \n-
    692
    \n-\n-
    696 {
    \n-
    697 return Iterator(r,-1);
    \n-
    698 }
    \n-
    699
    \n-\n-
    702
    \n-
    704 typedef typename row_type::Iterator ColIterator;
    \n-
    705
    \n-\n-\n-
    709
    \n+
    686 // the loop
    \n+
    687 int i = 1;
    \n+
    688 for( ; i<=_maxit; i++) {
    \n+
    689
    \n+
    690 dummy = z;
    \n+
    691 int i1 = i%3,
    \n+
    692 i0 = (i1+2)%3,
    \n+
    693 i2 = (i1+1)%3;
    \n+
    694
    \n+
    695 // symmetrically preconditioned Lanczos algorithm (see Greenbaum p.121)
    \n+
    696 _op->apply(z,q[i2]); // q[i2] = Az
    \n+
    697 q[i2].axpy(-beta,q[i0]);
    \n+
    698 // alpha is real since it is the diagonal entry of the hermitian tridiagonal matrix
    \n+
    699 // from the Lanczos Algorithm
    \n+
    700 // so the order in the scalar product doesn't matter even for the complex case
    \n+
    701 alpha = _sp->dot(z,q[i2]);
    \n+
    702 q[i2].axpy(-alpha,q[i1]);
    \n+
    703
    \n+
    704 z = 0.0;
    \n+
    705 _prec->apply(z,q[i2]);
    \n+
    706
    \n+
    707 // beta is real and positive in exact arithmetic
    \n+
    708 // since it is the norm of the basis vectors (in unpreconditioned case)
    \n+
    709 beta = sqrt(_sp->dot(q[i2],z));
    \n
    710
    \n-\n-
    713 {
    \n-
    714 return ConstIterator(r,0);
    \n-
    715 }
    \n-
    716
    \n-\n-
    719 {
    \n-
    720 return ConstIterator(r,n);
    \n-
    721 }
    \n-
    722
    \n-\n-
    726 {
    \n-
    727 return ConstIterator(r,n-1);
    \n-
    728 }
    \n-
    729
    \n-\n-
    733 {
    \n-
    734 return ConstIterator(r,-1);
    \n-
    735 }
    \n-
    736
    \n-\n+
    711 q[i2] *= Simd::cond(def==field_type(0.),
    \n+
    712 field_type(0.),
    \n+
    713 real_type(1.0)/beta);
    \n+
    714 z *= Simd::cond(def==field_type(0.),
    \n+
    715 field_type(0.),
    \n+
    716 real_type(1.0)/beta);
    \n+
    717
    \n+
    718 // QR Factorization of recurrence coefficient matrix
    \n+
    719 // apply previous givens rotations to last column of T
    \n+
    720 T[1] = T[2];
    \n+
    721 if(i>2) {
    \n+
    722 T[0] = s[i%2]*T[1];
    \n+
    723 T[1] = c[i%2]*T[1];
    \n+
    724 }
    \n+
    725 if(i>1) {
    \n+
    726 T[2] = c[(i+1)%2]*alpha - s[(i+1)%2]*T[1];
    \n+
    727 T[1] = c[(i+1)%2]*T[1] + s[(i+1)%2]*alpha;
    \n+
    728 }
    \n+
    729 else
    \n+
    730 T[2] = alpha;
    \n+
    731
    \n+
    732 // update QR factorization
    \n+
    733 generateGivensRotation(T[2],beta,c[i%2],s[i%2]);
    \n+
    734 // to last column of T_k
    \n+
    735 T[2] = c[i%2]*T[2] + s[i%2]*beta;
    \n+
    736 // and to the rhs xi of the min problem
    \n+
    737 xi[i%2] = -s[i%2]*xi[(i+1)%2];
    \n+
    738 xi[(i+1)%2] *= c[i%2];
    \n
    739
    \n-
    741 typedef typename row_type::ConstIterator ConstColIterator;
    \n-
    742
    \n-
    743 //===== constructors & resizers
    \n-
    744
    \n-
    745 // we use a negative compressionBufferSize to indicate that the implicit
    \n-
    746 // mode parameters have not been set yet
    \n-
    747
    \n-\n-
    750 : build_mode(unknown), ready(notAllocated), n(0), m(0), nnz_(0),
    \n-
    751 allocationSize_(0), r(0), a(0),
    \n-\n-
    753 {}
    \n-
    754
    \n-\n-
    757 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n-
    758 allocationSize_(0), r(0), a(0),
    \n-\n-
    760 {
    \n-
    761 allocate(_n, _m, _nnz,true,false);
    \n+
    740 // compute correction direction
    \n+
    741 p[i2] = dummy;
    \n+
    742 p[i2].axpy(-T[1],p[i1]);
    \n+
    743 p[i2].axpy(-T[0],p[i0]);
    \n+
    744 p[i2] *= real_type(1.0)/T[2];
    \n+
    745
    \n+
    746 // apply correction/update solution
    \n+
    747 x.axpy(beta0*xi[(i+1)%2],p[i2]);
    \n+
    748
    \n+
    749 // remember beta_old
    \n+
    750 T[2] = beta;
    \n+
    751
    \n+
    752 // check for convergence
    \n+
    753 // the last entry in the rhs of the min-problem is the residual
    \n+
    754 def = abs(beta0*xi[i%2]);
    \n+
    755 if(iteration.step(i, def)){
    \n+
    756 break;
    \n+
    757 }
    \n+
    758 } // end for
    \n+
    759
    \n+
    760 // postprocess preconditioner
    \n+
    761 _prec->post(x);
    \n
    762 }
    \n
    763
    \n-\n-
    766 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n-
    767 allocationSize_(0), r(0), a(0),
    \n-\n-
    769 {
    \n-
    770 allocate(_n, _m,0,true,false);
    \n-
    771 }
    \n-
    772
    \n-
    774
    \n-
    784 BCRSMatrix (size_type _n, size_type _m, size_type _avg, double compressionBufferSize, BuildMode bm)
    \n-
    785 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),
    \n-
    786 allocationSize_(0), r(0), a(0),
    \n-
    787 avg(_avg), compressionBufferSize_(compressionBufferSize)
    \n-
    788 {
    \n-
    789 if (bm != implicit)
    \n-
    790 DUNE_THROW(BCRSMatrixError,"Only call this constructor when using the implicit build mode");
    \n-
    791 // Prevent user from setting a negative compression buffer size:
    \n-
    792 // 1) It doesn't make sense
    \n-
    793 // 2) We use a negative value to indicate that the parameters
    \n-
    794 // have not been set yet
    \n-
    795 if (compressionBufferSize_ < 0.0)
    \n-
    796 DUNE_THROW(BCRSMatrixError,"You cannot set a negative overflow fraction");
    \n-
    797 implicit_allocate(_n,_m);
    \n-
    798 }
    \n-
    799
    \n-\n-
    806 : build_mode(Mat.build_mode), ready(notAllocated), n(0), m(0), nnz_(0),
    \n-
    807 allocationSize_(0), r(0), a(0),
    \n-\n-
    809 {
    \n-
    810 if (!(Mat.ready == notAllocated || Mat.ready == built))
    \n-
    811 DUNE_THROW(InvalidStateException,"BCRSMatrix can only be copy-constructed when source matrix is completely empty (size not set) or fully built)");
    \n-
    812
    \n-
    813 // deep copy in global array
    \n-
    814 size_type _nnz = Mat.nonzeroes();
    \n-
    815
    \n-
    816 j_ = Mat.j_; // enable column index sharing, release array in case of row-wise allocation
    \n-
    817 allocate(Mat.n, Mat.m, _nnz, true, true);
    \n-
    818
    \n-
    819 // build window structure
    \n-\n-
    821 }
    \n-
    822
    \n-\n-
    825 {
    \n-
    826 deallocate();
    \n-
    827 }
    \n-
    828
    \n-\n-
    834 {
    \n-
    835 if (ready == notAllocated)
    \n-
    836 {
    \n-
    837 build_mode = bm;
    \n-
    838 return;
    \n-
    839 }
    \n-
    840 if (ready == building && (build_mode == unknown || build_mode == random || build_mode == row_wise) && (bm == row_wise || bm == random))
    \n-
    841 build_mode = bm;
    \n-
    842 else
    \n-
    843 DUNE_THROW(InvalidStateException, "Matrix structure cannot be changed at this stage anymore (ready == "<<ready<<").");
    \n-
    844 }
    \n-
    845
    \n-
    861 void setSize(size_type rows, size_type columns, size_type nnz=0)
    \n-
    862 {
    \n-
    863 // deallocate already setup memory
    \n-
    864 deallocate();
    \n+
    764 private:
    \n+
    765
    \n+
    766 void generateGivensRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    \n+
    767 {
    \n+
    768 using std::sqrt;
    \n+
    769 using std::abs;
    \n+
    770 using std::max;
    \n+
    771 using std::min;
    \n+
    772 const real_type eps = 1e-15;
    \n+
    773 real_type norm_dx = abs(dx);
    \n+
    774 real_type norm_dy = abs(dy);
    \n+
    775 real_type norm_max = max(norm_dx, norm_dy);
    \n+
    776 real_type norm_min = min(norm_dx, norm_dy);
    \n+
    777 real_type temp = norm_min/norm_max;
    \n+
    778 // we rewrite the code in a vectorizable fashion
    \n+
    779 cs = Simd::cond(norm_dy < eps,
    \n+
    780 real_type(1.0),
    \n+
    781 Simd::cond(norm_dx < eps,
    \n+
    782 real_type(0.0),
    \n+
    783 Simd::cond(norm_dy > norm_dx,
    \n+
    784 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,
    \n+
    785 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)
    \n+
    786 )));
    \n+
    787 sn = Simd::cond(norm_dy < eps,
    \n+
    788 field_type(0.0),
    \n+
    789 Simd::cond(norm_dx < eps,
    \n+
    790 field_type(1.0),
    \n+
    791 Simd::cond(norm_dy > norm_dx,
    \n+
    792 // dy and dx are real in exact arithmetic
    \n+
    793 // thus dx*dy is real so we can explicitly enforce it
    \n+
    794 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*dy/norm_dx/norm_dy,
    \n+
    795 // dy and dx is real in exact arithmetic
    \n+
    796 // so we don't have to conjugate both of them
    \n+
    797 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dy/dx
    \n+
    798 )));
    \n+
    799 }
    \n+
    800
    \n+
    801 protected:
    \n+
    802 using IterativeSolver<X,X>::_op;
    \n+
    803 using IterativeSolver<X,X>::_prec;
    \n+
    804 using IterativeSolver<X,X>::_sp;
    \n+\n+
    806 using IterativeSolver<X,X>::_maxit;
    \n+
    807 using IterativeSolver<X,X>::_verbose;
    \n+\n+
    809 };
    \n+
    810 DUNE_REGISTER_ITERATIVE_SOLVER("minressolver", defaultIterativeSolverCreator<Dune::MINRESSolver>());
    \n+
    811
    \n+
    825 template<class X, class Y=X, class F = Y>
    \n+\n+
    827 {
    \n+
    828 public:
    \n+\n+\n+\n+
    832 using typename IterativeSolver<X,Y>::real_type;
    \n+
    833
    \n+
    834 protected:
    \n+\n+
    836
    \n+\n+\n+
    841
    \n+
    842 public:
    \n+
    843
    \n+
    850 RestartedGMResSolver (const LinearOperator<X,Y>& op, Preconditioner<X,Y>& prec, scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n+
    851 IterativeSolver<X,Y>::IterativeSolver(op,prec,reduction,maxit,verbose),
    \n+
    852 _restart(restart)
    \n+
    853 {}
    \n+
    854
    \n+
    861 RestartedGMResSolver (const LinearOperator<X,Y>& op, const ScalarProduct<X>& sp, Preconditioner<X,Y>& prec, scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n+
    862 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n+
    863 _restart(restart)
    \n+
    864 {}
    \n
    865
    \n-
    866 if (build_mode == implicit)
    \n-
    867 {
    \n-
    868 if (nnz>0)
    \n-
    869 DUNE_THROW(Dune::BCRSMatrixError,"number of non-zeroes may not be set in implicit mode, use setImplicitBuildModeParameters() instead");
    \n-
    870
    \n-
    871 // implicit allocates differently
    \n-
    872 implicit_allocate(rows,columns);
    \n-
    873 }
    \n-
    874 else
    \n-
    875 {
    \n-
    876 // allocate matrix memory
    \n-
    877 allocate(rows, columns, nnz, true, false);
    \n-
    878 }
    \n-
    879 }
    \n-
    880
    \n-
    889 void setImplicitBuildModeParameters(size_type _avg, double compressionBufferSize)
    \n-
    890 {
    \n-
    891 // Prevent user from setting a negative compression buffer size:
    \n-
    892 // 1) It doesn't make sense
    \n-
    893 // 2) We use a negative value to indicate that the parameters
    \n-
    894 // have not been set yet
    \n-
    895 if (compressionBufferSize < 0.0)
    \n-
    896 DUNE_THROW(BCRSMatrixError,"You cannot set a negative compressionBufferSize value");
    \n-
    897
    \n-
    898 // make sure the parameters aren't changed after memory has been allocated
    \n-
    899 if (ready != notAllocated)
    \n-
    900 DUNE_THROW(InvalidStateException,"You cannot modify build mode parameters at this stage anymore");
    \n-
    901 avg = _avg;
    \n-
    902 compressionBufferSize_ = compressionBufferSize;
    \n-
    903 }
    \n-
    904
    \n-\n-
    912 {
    \n-
    913 // return immediately when self-assignment
    \n-
    914 if (&Mat==this) return *this;
    \n-
    915
    \n-
    916 if (!((ready == notAllocated || ready == built) && (Mat.ready == notAllocated || Mat.ready == built)))
    \n-
    917 DUNE_THROW(InvalidStateException,"BCRSMatrix can only be copied when both target and source are empty or fully built)");
    \n-
    918
    \n-
    919 // make it simple: ALWAYS throw away memory for a and j_
    \n-
    920 // and deallocate rows only if n != Mat.n
    \n-
    921 deallocate(n!=Mat.n);
    \n-
    922
    \n-
    923 // reallocate the rows if required
    \n-
    924 if (n>0 && n!=Mat.n) {
    \n-
    925 // free rows
    \n-
    926 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)
    \n-
    927 std::allocator_traits<decltype(rowAllocator_)>::destroy(rowAllocator_, riter);
    \n-
    928 rowAllocator_.deallocate(r,n);
    \n-
    929 }
    \n-
    930
    \n-
    931 nnz_ = Mat.nonzeroes();
    \n-
    932
    \n-
    933 // allocate a, share j_
    \n-
    934 j_ = Mat.j_;
    \n-
    935 allocate(Mat.n, Mat.m, nnz_, n!=Mat.n, true);
    \n-
    936
    \n-
    937 // build window structure
    \n-\n-
    939 return *this;
    \n-
    940 }
    \n-
    941
    \n-\n-
    944 {
    \n-
    945
    \n-
    946 if (!(ready == notAllocated || ready == built))
    \n-
    947 DUNE_THROW(InvalidStateException,"Scalar assignment only works on fully built BCRSMatrix)");
    \n-
    948
    \n-
    949 for (size_type i=0; i<n; i++) r[i] = k;
    \n-
    950 return *this;
    \n-
    951 }
    \n-
    952
    \n-
    953 //===== row-wise creation interface
    \n-
    954
    \n-\n-
    957 {
    \n-
    958 public:
    \n-\n-
    961 : Mat(_Mat), i(_i), nnz(0), current_row(nullptr, Mat.j_.get(), 0)
    \n-
    962 {
    \n-
    963 if (Mat.build_mode == unknown && Mat.ready == building)
    \n-
    964 {
    \n-
    965 Mat.build_mode = row_wise;
    \n-
    966 }
    \n-
    967 if (i==0 && Mat.ready != building)
    \n-
    968 DUNE_THROW(BCRSMatrixError,"creation only allowed for uninitialized matrix");
    \n-
    969 if(Mat.build_mode!=row_wise)
    \n-
    970 DUNE_THROW(BCRSMatrixError,"creation only allowed if row wise allocation was requested in the constructor");
    \n-
    971 if(i==0 && _Mat.N()==0)
    \n-
    972 // empty Matrix is always built.
    \n-
    973 Mat.ready = built;
    \n-
    974 }
    \n-
    975
    \n-\n-
    978 {
    \n-
    979 // this should only be called if matrix is in creation
    \n-
    980 if (Mat.ready != building)
    \n-
    981 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n-
    982
    \n-
    983 // row i is defined through the pattern
    \n-
    984 // get memory for the row and initialize the j_ array
    \n-
    985 // this depends on the allocation mode
    \n-
    986
    \n-
    987 // compute size of the row
    \n-
    988 size_type s = pattern.size();
    \n-
    989
    \n-
    990 if(s>0) {
    \n-
    991 // update number of nonzeroes including this row
    \n-
    992 nnz += s;
    \n-
    993
    \n-
    994 // alloc memory / set window
    \n-
    995 if (Mat.nnz_ > 0)
    \n-
    996 {
    \n-
    997 // memory is allocated in one long array
    \n-
    998
    \n-
    999 // check if that memory is sufficient
    \n-
    1000 if (nnz > Mat.nnz_)
    \n-
    1001 DUNE_THROW(BCRSMatrixError,"allocated nnz too small");
    \n-
    1002
    \n-
    1003 // set row i
    \n-
    1004 Mat.r[i].set(s,nullptr,current_row.getindexptr());
    \n-
    1005 current_row.setindexptr(current_row.getindexptr()+s);
    \n-
    1006 }else{
    \n-
    1007 // memory is allocated individually per row
    \n-
    1008 // allocate and set row i
    \n-
    1009 B* b = Mat.allocator_.allocate(s);
    \n-
    1010 // use placement new to call constructor that allocates
    \n-
    1011 // additional memory.
    \n-
    1012 new (b) B[s];
    \n-
    1013 size_type* j = Mat.sizeAllocator_.allocate(s);
    \n-
    1014 Mat.r[i].set(s,b,j);
    \n-
    1015 }
    \n-
    1016 }else
    \n-
    1017 // setup empty row
    \n-
    1018 Mat.r[i].set(0,nullptr,nullptr);
    \n-
    1019
    \n-
    1020 // initialize the j array for row i from pattern
    \n-
    1021 std::copy(pattern.cbegin(), pattern.cend(), Mat.r[i].getindexptr());
    \n-
    1022
    \n-
    1023 // now go to next row
    \n-
    1024 i++;
    \n-
    1025 pattern.clear();
    \n-
    1026
    \n-
    1027 // check if this was last row
    \n-
    1028 if (i==Mat.n)
    \n-
    1029 {
    \n-
    1030 Mat.ready = built;
    \n-
    1031 if(Mat.nnz_ > 0)
    \n-
    1032 {
    \n-
    1033 // Set nnz to the exact number of nonzero blocks inserted
    \n-
    1034 // as some methods rely on it
    \n-
    1035 Mat.nnz_ = nnz;
    \n-
    1036 // allocate data array
    \n-
    1037 Mat.allocateData();
    \n-
    1038 Mat.setDataPointers();
    \n-
    1039 }
    \n-
    1040 }
    \n-
    1041 // done
    \n-
    1042 return *this;
    \n-
    1043 }
    \n-
    1044
    \n-
    1046 bool operator!= (const CreateIterator& it) const
    \n-
    1047 {
    \n-
    1048 return (i!=it.i) || (&Mat!=&it.Mat);
    \n-
    1049 }
    \n-
    1050
    \n-
    1052 bool operator== (const CreateIterator& it) const
    \n-
    1053 {
    \n-
    1054 return (i==it.i) && (&Mat==&it.Mat);
    \n-
    1055 }
    \n-
    1056
    \n-\n-
    1059 {
    \n-
    1060 return i;
    \n-
    1061 }
    \n-
    1062
    \n-\n-
    1065 {
    \n-
    1066 pattern.insert(j);
    \n-
    1067 }
    \n-
    1068
    \n-\n-
    1071 {
    \n-
    1072 return pattern.find(j) != pattern.end();
    \n-
    1073 }
    \n-\n-
    1080 {
    \n-
    1081 return pattern.size();
    \n-
    1082 }
    \n-
    1083
    \n-
    1084 private:
    \n-
    1085 BCRSMatrix& Mat; // the matrix we are defining
    \n-
    1086 size_type i; // current row to be defined
    \n-
    1087 size_type nnz; // count total number of nonzeros
    \n-
    1088 typedef std::set<size_type,std::less<size_type> > PatternType;
    \n-
    1089 PatternType pattern; // used to compile entries in a row
    \n-
    1090 row_type current_row; // row pointing to the current row to setup
    \n-
    1091 };
    \n-
    1092
    \n-
    1094 friend class CreateIterator;
    \n-
    1095
    \n-\n-
    1098 {
    \n-
    1099 return CreateIterator(*this,0);
    \n-
    1100 }
    \n-
    1101
    \n-\n-
    1104 {
    \n-
    1105 return CreateIterator(*this,n);
    \n-
    1106 }
    \n-
    1107
    \n-
    1108
    \n-
    1109 //===== random creation interface
    \n-
    1110
    \n-\n-
    1118 {
    \n-
    1119 if (build_mode!=random)
    \n-
    1120 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n-
    1121 if (ready != building)
    \n-
    1122 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n+
    878 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    879 IterativeSolver<X,Y>::IterativeSolver(op,prec,configuration),
    \n+
    880 _restart(configuration.get<int>("restart"))
    \n+
    881 {}
    \n+
    882
    \n+
    883 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    884 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,configuration),
    \n+
    885 _restart(configuration.get<int>("restart"))
    \n+
    886 {}
    \n+
    887
    \n+
    894 RestartedGMResSolver (std::shared_ptr<const LinearOperator<X,Y>> op,
    \n+
    895 std::shared_ptr<const ScalarProduct<X>> sp,
    \n+
    896 std::shared_ptr<Preconditioner<X,Y>> prec,
    \n+
    897 scalar_real_type reduction, int restart, int maxit, int verbose) :
    \n+
    898 IterativeSolver<X,Y>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n+
    899 _restart(restart)
    \n+
    900 {}
    \n+
    901
    \n+
    910 virtual void apply (X& x, Y& b, InverseOperatorResult& res)
    \n+
    911 {
    \n+
    912 apply(x,b,Simd::max(_reduction),res);
    \n+
    913 }
    \n+
    914
    \n+
    923 virtual void apply (X& x, Y& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n+
    924 {
    \n+
    925 using std::abs;
    \n+
    926 const Simd::Scalar<real_type> EPSILON = 1e-80;
    \n+
    927 const int m = _restart;
    \n+
    928 real_type norm = 0.0;
    \n+
    929 int j = 1;
    \n+
    930 std::vector<field_type,fAlloc> s(m+1), sn(m);
    \n+
    931 std::vector<real_type,rAlloc> cs(m);
    \n+
    932 // need copy of rhs if GMRes has to be restarted
    \n+
    933 Y b2(b);
    \n+
    934 // helper vector
    \n+
    935 Y w(b);
    \n+
    936 std::vector< std::vector<field_type,fAlloc> > H(m+1,s);
    \n+
    937 std::vector<F> v(m+1,b);
    \n+
    938
    \n+
    939 Iteration iteration(*this,res);
    \n+
    940
    \n+
    941 // clear solver statistics and set res.converged to false
    \n+
    942 _prec->pre(x,b);
    \n+
    943
    \n+
    944 // calculate defect and overwrite rhs with it
    \n+
    945 _op->applyscaleadd(-1.0,x,b); // b -= Ax
    \n+
    946 // calculate preconditioned defect
    \n+
    947 v[0] = 0.0; _prec->apply(v[0],b); // r = W^-1 b
    \n+
    948 norm = _sp->norm(v[0]);
    \n+
    949 if(iteration.step(0, norm)){
    \n+
    950 _prec->post(x);
    \n+
    951 return;
    \n+
    952 }
    \n+
    953
    \n+
    954 while(j <= _maxit && res.converged != true) {
    \n+
    955
    \n+
    956 int i = 0;
    \n+
    957 v[0] *= Simd::cond(norm==real_type(0.),
    \n+
    958 real_type(0.),
    \n+
    959 real_type(1.0)/norm);
    \n+
    960 s[0] = norm;
    \n+
    961 for(i=1; i<m+1; i++)
    \n+
    962 s[i] = 0.0;
    \n+
    963
    \n+
    964 for(i=0; i < m && j <= _maxit && res.converged != true; i++, j++) {
    \n+
    965 w = 0.0;
    \n+
    966 // use v[i+1] as temporary vector
    \n+
    967 v[i+1] = 0.0;
    \n+
    968 // do Arnoldi algorithm
    \n+
    969 _op->apply(v[i],v[i+1]);
    \n+
    970 _prec->apply(w,v[i+1]);
    \n+
    971 for(int k=0; k<i+1; k++) {
    \n+
    972 // notice that _sp->dot(v[k],w) = v[k]\\adjoint w
    \n+
    973 // so one has to pay attention to the order
    \n+
    974 // in the scalar product for the complex case
    \n+
    975 // doing the modified Gram-Schmidt algorithm
    \n+
    976 H[k][i] = _sp->dot(v[k],w);
    \n+
    977 // w -= H[k][i] * v[k]
    \n+
    978 w.axpy(-H[k][i],v[k]);
    \n+
    979 }
    \n+
    980 H[i+1][i] = _sp->norm(w);
    \n+
    981 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))
    \n+
    982 DUNE_THROW(SolverAbort,
    \n+
    983 "breakdown in GMRes - |w| == 0.0 after " << j << " iterations");
    \n+
    984
    \n+
    985 // normalize new vector
    \n+
    986 v[i+1] = w;
    \n+
    987 v[i+1] *= Simd::cond(norm==real_type(0.),
    \n+
    988 field_type(0.),
    \n+
    989 real_type(1.0)/H[i+1][i]);
    \n+
    990
    \n+
    991 // update QR factorization
    \n+
    992 for(int k=0; k<i; k++)
    \n+
    993 applyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);
    \n+
    994
    \n+
    995 // compute new givens rotation
    \n+
    996 generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n+
    997 // finish updating QR factorization
    \n+
    998 applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n+
    999 applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);
    \n+
    1000
    \n+
    1001 // norm of the defect is the last component the vector s
    \n+
    1002 norm = abs(s[i+1]);
    \n+
    1003
    \n+
    1004 iteration.step(j, norm);
    \n+
    1005
    \n+
    1006 } // end for
    \n+
    1007
    \n+
    1008 // calculate update vector
    \n+
    1009 w = 0.0;
    \n+
    1010 update(w,i,H,s,v);
    \n+
    1011 // and current iterate
    \n+
    1012 x += w;
    \n+
    1013
    \n+
    1014 // restart GMRes if convergence was not achieved,
    \n+
    1015 // i.e. linear defect has not reached desired reduction
    \n+
    1016 // and if j < _maxit (do not restart on last iteration)
    \n+
    1017 if( res.converged != true && j < _maxit ) {
    \n+
    1018
    \n+
    1019 if(_verbose > 0)
    \n+
    1020 std::cout << "=== GMRes::restart" << std::endl;
    \n+
    1021 // get saved rhs
    \n+
    1022 b = b2;
    \n+
    1023 // calculate new defect
    \n+
    1024 _op->applyscaleadd(-1.0,x,b); // b -= Ax;
    \n+
    1025 // calculate preconditioned defect
    \n+
    1026 v[0] = 0.0;
    \n+
    1027 _prec->apply(v[0],b);
    \n+
    1028 norm = _sp->norm(v[0]);
    \n+
    1029 }
    \n+
    1030
    \n+
    1031 } //end while
    \n+
    1032
    \n+
    1033 // postprocess preconditioner
    \n+
    1034 _prec->post(x);
    \n+
    1035 }
    \n+
    1036
    \n+
    1037 protected :
    \n+
    1038
    \n+
    1039 void update(X& w, int i,
    \n+
    1040 const std::vector<std::vector<field_type,fAlloc> >& H,
    \n+
    1041 const std::vector<field_type,fAlloc>& s,
    \n+
    1042 const std::vector<X>& v) {
    \n+
    1043 // solution vector of the upper triangular system
    \n+
    1044 std::vector<field_type,fAlloc> y(s);
    \n+
    1045
    \n+
    1046 // backsolve
    \n+
    1047 for(int a=i-1; a>=0; a--) {
    \n+
    1048 field_type rhs(s[a]);
    \n+
    1049 for(int b=a+1; b<i; b++)
    \n+
    1050 rhs -= H[a][b]*y[b];
    \n+
    1051 y[a] = Simd::cond(rhs==field_type(0.),
    \n+
    1052 field_type(0.),
    \n+
    1053 rhs/H[a][a]);
    \n+
    1054
    \n+
    1055 // compute update on the fly
    \n+
    1056 // w += y[a]*v[a]
    \n+
    1057 w.axpy(y[a],v[a]);
    \n+
    1058 }
    \n+
    1059 }
    \n+
    1060
    \n+
    1061 template<typename T>
    \n+
    1062 typename std::enable_if<std::is_same<field_type,real_type>::value,T>::type conjugate(const T& t) {
    \n+
    1063 return t;
    \n+
    1064 }
    \n+
    1065
    \n+
    1066 template<typename T>
    \n+
    1067 typename std::enable_if<!std::is_same<field_type,real_type>::value,T>::type conjugate(const T& t) {
    \n+
    1068 using std::conj;
    \n+
    1069 return conj(t);
    \n+
    1070 }
    \n+
    1071
    \n+
    1072 void
    \n+\n+
    1074 {
    \n+
    1075 using std::sqrt;
    \n+
    1076 using std::abs;
    \n+
    1077 using std::max;
    \n+
    1078 using std::min;
    \n+
    1079 const real_type eps = 1e-15;
    \n+
    1080 real_type norm_dx = abs(dx);
    \n+
    1081 real_type norm_dy = abs(dy);
    \n+
    1082 real_type norm_max = max(norm_dx, norm_dy);
    \n+
    1083 real_type norm_min = min(norm_dx, norm_dy);
    \n+
    1084 real_type temp = norm_min/norm_max;
    \n+
    1085 // we rewrite the code in a vectorizable fashion
    \n+
    1086 cs = Simd::cond(norm_dy < eps,
    \n+
    1087 real_type(1.0),
    \n+
    1088 Simd::cond(norm_dx < eps,
    \n+
    1089 real_type(0.0),
    \n+
    1090 Simd::cond(norm_dy > norm_dx,
    \n+
    1091 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,
    \n+
    1092 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)
    \n+
    1093 )));
    \n+
    1094 sn = Simd::cond(norm_dy < eps,
    \n+
    1095 field_type(0.0),
    \n+
    1096 Simd::cond(norm_dx < eps,
    \n+
    1097 field_type(1.0),
    \n+
    1098 Simd::cond(norm_dy > norm_dx,
    \n+
    1099 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*conjugate(dy)/norm_dx/norm_dy,
    \n+
    1100 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*conjugate(dy/dx)
    \n+
    1101 )));
    \n+
    1102 }
    \n+
    1103
    \n+
    1104
    \n+
    1105 void
    \n+\n+
    1107 {
    \n+
    1108 field_type temp = cs * dx + sn * dy;
    \n+
    1109 dy = -conjugate(sn) * dx + cs * dy;
    \n+
    1110 dx = temp;
    \n+
    1111 }
    \n+
    1112
    \n+
    1113 using IterativeSolver<X,Y>::_op;
    \n+
    1114 using IterativeSolver<X,Y>::_prec;
    \n+
    1115 using IterativeSolver<X,Y>::_sp;
    \n+
    1116 using IterativeSolver<X,Y>::_reduction;
    \n+
    1117 using IterativeSolver<X,Y>::_maxit;
    \n+
    1118 using IterativeSolver<X,Y>::_verbose;
    \n+\n+\n+
    1121 };
    \n+
    1122 DUNE_REGISTER_ITERATIVE_SOLVER("restartedgmressolver", defaultIterativeSolverCreator<Dune::RestartedGMResSolver>());
    \n
    1123
    \n-
    1124 r[i].setsize(s);
    \n-
    1125 }
    \n-
    1126
    \n-\n-
    1129 {
    \n-
    1130#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1131 if (r==0) DUNE_THROW(BCRSMatrixError,"row not initialized yet");
    \n-
    1132 if (i>=n) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1133#endif
    \n-
    1134 return r[i].getsize();
    \n-
    1135 }
    \n-
    1136
    \n-\n-
    1139 {
    \n-
    1140 if (build_mode!=random)
    \n-
    1141 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n-
    1142 if (ready != building)
    \n-
    1143 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n-
    1144
    \n-
    1145 r[i].setsize(r[i].getsize()+s);
    \n-
    1146 }
    \n-
    1147
    \n-\n-
    1150 {
    \n-
    1151 if (build_mode!=random)
    \n-
    1152 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n-
    1153 if (ready != building)
    \n-
    1154 DUNE_THROW(BCRSMatrixError,"matrix row sizes already built up");
    \n-
    1155
    \n-
    1156 // compute total size, check positivity
    \n-
    1157 size_type total=0;
    \n-
    1158 for (size_type i=0; i<n; i++)
    \n-
    1159 {
    \n-
    1160 total += r[i].getsize();
    \n-
    1161 }
    \n-
    1162
    \n-
    1163 if(nnz_ == 0)
    \n-
    1164 // allocate/check memory
    \n-
    1165 allocate(n,m,total,false,false);
    \n-
    1166 else if(nnz_ < total)
    \n-
    1167 DUNE_THROW(BCRSMatrixError,"Specified number of nonzeros ("<<nnz_<<") not "
    \n-
    1168 <<"sufficient for calculated nonzeros ("<<total<<"! ");
    \n-
    1169
    \n-
    1170 // set the window pointers correctly
    \n-\n-
    1172
    \n-
    1173 // initialize j_ array with m (an invalid column index)
    \n-
    1174 // this indicates an unused entry
    \n-
    1175 for (size_type k=0; k<nnz_; k++)
    \n-
    1176 j_.get()[k] = m;
    \n-\n-
    1178 }
    \n-
    1179
    \n-
    1181
    \n-\n-
    1192 {
    \n-
    1193 if (build_mode!=random)
    \n-
    1194 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n-
    1195 if (ready==built)
    \n-
    1196 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n-
    1197 if (ready==building)
    \n-
    1198 DUNE_THROW(BCRSMatrixError,"matrix row sizes not built up yet");
    \n-
    1199 if (ready==notAllocated)
    \n-
    1200 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n-
    1201
    \n-
    1202 if (col >= m)
    \n-
    1203 DUNE_THROW(BCRSMatrixError,"column index exceeds matrix size");
    \n-
    1204
    \n-
    1205 // get row range
    \n-
    1206 size_type* const first = r[row].getindexptr();
    \n-
    1207 size_type* const last = first + r[row].getsize();
    \n-
    1208
    \n-
    1209 // find correct insertion position for new column index
    \n-
    1210 size_type* pos = std::lower_bound(first,last,col);
    \n-
    1211
    \n-
    1212 // check if index is already in row
    \n-
    1213 if (pos!=last && *pos == col) return;
    \n-
    1214
    \n-
    1215 // find end of already inserted column indices
    \n-
    1216 size_type* end = std::lower_bound(pos,last,m);
    \n-
    1217 if (end==last)
    \n-
    1218 DUNE_THROW(BCRSMatrixError,"row is too small");
    \n-
    1219
    \n-
    1220 // insert new column index at correct position
    \n-
    1221 std::copy_backward(pos,end,end+1);
    \n-
    1222 *pos = col;
    \n-
    1223 }
    \n-
    1224
    \n-
    1226
    \n-
    1233 template<typename It>
    \n-
    1234 void setIndices(size_type row, It begin, It end)
    \n-
    1235 {
    \n-
    1236 size_type row_size = r[row].size();
    \n-
    1237 size_type* col_begin = r[row].getindexptr();
    \n-
    1238 size_type* col_end;
    \n-
    1239 // consistency check between allocated row size and number of passed column indices
    \n-
    1240 if ((col_end = std::copy(begin,end,r[row].getindexptr())) != col_begin + row_size)
    \n-
    1241 DUNE_THROW(BCRSMatrixError,"Given size of row " << row
    \n-
    1242 << " (" << row_size
    \n-
    1243 << ") does not match number of passed entries (" << (col_end - col_begin) << ")");
    \n-
    1244 std::sort(col_begin,col_end);
    \n-
    1245 }
    \n+
    1137 template<class X, class Y=X, class F = Y>
    \n+\n+
    1139 {
    \n+
    1140 public:
    \n+\n+\n+\n+\n+
    1145
    \n+
    1146 private:
    \n+\n+
    1148
    \n+
    1150 using fAlloc = typename RestartedGMResSolver<X,Y>::fAlloc;
    \n+
    1152 using rAlloc = typename RestartedGMResSolver<X,Y>::rAlloc;
    \n+
    1153
    \n+
    1154 public:
    \n+
    1155 // copy base class constructors
    \n+\n+
    1157
    \n+
    1158 // don't shadow four-argument version of apply defined in the base class
    \n+
    1159 using RestartedGMResSolver<X,Y>::apply;
    \n+
    1160
    \n+
    1169 void apply (X& x, Y& b, [[maybe_unused]] double reduction, InverseOperatorResult& res) override
    \n+
    1170 {
    \n+
    1171 using std::abs;
    \n+
    1172 const Simd::Scalar<real_type> EPSILON = 1e-80;
    \n+
    1173 const int m = _restart;
    \n+
    1174 real_type norm = 0.0;
    \n+
    1175 int i, j = 1, k;
    \n+
    1176 std::vector<field_type,fAlloc> s(m+1), sn(m);
    \n+
    1177 std::vector<real_type,rAlloc> cs(m);
    \n+
    1178 // helper vector
    \n+
    1179 Y tmp(b);
    \n+
    1180 std::vector< std::vector<field_type,fAlloc> > H(m+1,s);
    \n+
    1181 std::vector<F> v(m+1,b);
    \n+
    1182 std::vector<X> w(m+1,b);
    \n+
    1183
    \n+
    1184 Iteration iteration(*this,res);
    \n+
    1185 // setup preconditioner if it does something in pre
    \n+
    1186
    \n+
    1187 // calculate residual and overwrite a copy of the rhs with it
    \n+
    1188 _prec->pre(x, b);
    \n+
    1189 v[0] = b;
    \n+
    1190 _op->applyscaleadd(-1.0, x, v[0]); // b -= Ax
    \n+
    1191
    \n+
    1192 norm = _sp->norm(v[0]); // the residual norm
    \n+
    1193 if(iteration.step(0, norm)){
    \n+
    1194 _prec->post(x);
    \n+
    1195 return;
    \n+
    1196 }
    \n+
    1197
    \n+
    1198 // start iterations
    \n+
    1199 res.converged = false;;
    \n+
    1200 while(j <= _maxit && res.converged != true)
    \n+
    1201 {
    \n+
    1202 v[0] *= (1.0 / norm);
    \n+
    1203 s[0] = norm;
    \n+
    1204 for(i=1; i<m+1; ++i)
    \n+
    1205 s[i] = 0.0;
    \n+
    1206
    \n+
    1207 // inner loop
    \n+
    1208 for(i=0; i < m && j <= _maxit && res.converged != true; i++, j++)
    \n+
    1209 {
    \n+
    1210 w[i] = 0.0;
    \n+
    1211 // compute wi = M^-1*vi (also called zi)
    \n+
    1212 _prec->apply(w[i], v[i]);
    \n+
    1213 // compute vi = A*wi
    \n+
    1214 // use v[i+1] as temporary vector for w
    \n+
    1215 _op->apply(w[i], v[i+1]);
    \n+
    1216 // do Arnoldi algorithm
    \n+
    1217 for(int kk=0; kk<i+1; kk++)
    \n+
    1218 {
    \n+
    1219 // notice that _sp->dot(v[k],v[i+1]) = v[k]\\adjoint v[i+1]
    \n+
    1220 // so one has to pay attention to the order
    \n+
    1221 // in the scalar product for the complex case
    \n+
    1222 // doing the modified Gram-Schmidt algorithm
    \n+
    1223 H[kk][i] = _sp->dot(v[kk],v[i+1]);
    \n+
    1224 // w -= H[k][i] * v[kk]
    \n+
    1225 v[i+1].axpy(-H[kk][i], v[kk]);
    \n+
    1226 }
    \n+
    1227 H[i+1][i] = _sp->norm(v[i+1]);
    \n+
    1228 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))
    \n+
    1229 DUNE_THROW(SolverAbort, "breakdown in fGMRes - |w| (-> "
    \n+
    1230 << w[i] << ") == 0.0 after "
    \n+
    1231 << j << " iterations");
    \n+
    1232
    \n+
    1233 // v[i+1] = w*1/H[i+1][i]
    \n+
    1234 v[i+1] *= real_type(1.0)/H[i+1][i];
    \n+
    1235
    \n+
    1236 // update QR factorization
    \n+
    1237 for(k=0; k<i; k++)
    \n+
    1238 this->applyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);
    \n+
    1239
    \n+
    1240 // compute new givens rotation
    \n+
    1241 this->generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n+
    1242
    \n+
    1243 // finish updating QR factorization
    \n+
    1244 this->applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);
    \n+
    1245 this->applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);
    \n
    1246
    \n-\n-
    1249 {
    \n-
    1250 if (build_mode!=random)
    \n-
    1251 DUNE_THROW(BCRSMatrixError,"requires random build mode");
    \n-
    1252 if (ready==built)
    \n-
    1253 DUNE_THROW(BCRSMatrixError,"matrix already built up");
    \n-
    1254 if (ready==building)
    \n-
    1255 DUNE_THROW(BCRSMatrixError,"row sizes are not built up yet");
    \n-
    1256 if (ready==notAllocated)
    \n-
    1257 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n+
    1247 // norm of the residual is the last component of vector s
    \n+
    1248 using std::abs;
    \n+
    1249 norm = abs(s[i+1]);
    \n+
    1250 iteration.step(j, norm);
    \n+
    1251 } // end inner for loop
    \n+
    1252
    \n+
    1253 // calculate update vector
    \n+
    1254 tmp = 0.0;
    \n+
    1255 this->update(tmp, i, H, s, w);
    \n+
    1256 // and update current iterate
    \n+
    1257 x += tmp;
    \n
    1258
    \n-
    1259 // check if there are undefined indices
    \n-
    1260 RowIterator endi=end();
    \n-
    1261 for (RowIterator i=begin(); i!=endi; ++i)
    \n-
    1262 {
    \n-
    1263 ColIterator endj = (*i).end();
    \n-
    1264 for (ColIterator j=(*i).begin(); j!=endj; ++j) {
    \n-
    1265 if (j.index() >= m) {
    \n-
    1266 dwarn << "WARNING: size of row "<< i.index()<<" is "<<j.offset()<<". But was specified as being "<< (*i).end().offset()
    \n-
    1267 <<". This means you are wasting valuable space and creating additional cache misses!"<<std::endl;
    \n-
    1268 nnz_ -= ((*i).end().offset() - j.offset());
    \n-
    1269 r[i.index()].setsize(j.offset());
    \n-
    1270 break;
    \n-
    1271 }
    \n+
    1259 // restart fGMRes if convergence was not achieved,
    \n+
    1260 // i.e. linear residual has not reached desired reduction
    \n+
    1261 // and if still j < _maxit (do not restart on last iteration)
    \n+
    1262 if( res.converged != true && j < _maxit)
    \n+
    1263 {
    \n+
    1264 if (_verbose > 0)
    \n+
    1265 std::cout << "=== fGMRes::restart" << std::endl;
    \n+
    1266 // get rhs
    \n+
    1267 v[0] = b;
    \n+
    1268 // calculate new defect
    \n+
    1269 _op->applyscaleadd(-1.0, x,v[0]); // b -= Ax;
    \n+
    1270 // calculate preconditioned defect
    \n+
    1271 norm = _sp->norm(v[0]); // update the residual norm
    \n
    1272 }
    \n-
    1273 }
    \n-
    1274
    \n-
    1275 allocateData();
    \n-\n-
    1277
    \n-
    1278 // if not, set matrix to built
    \n-
    1279 ready = built;
    \n-
    1280 }
    \n-
    1281
    \n-
    1282 //===== implicit creation interface
    \n-
    1283
    \n-
    1285
    \n-\n-
    1297 {
    \n-
    1298#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1299 if (build_mode!=implicit)
    \n-
    1300 DUNE_THROW(BCRSMatrixError,"requires implicit build mode");
    \n-
    1301 if (ready==built)
    \n-
    1302 DUNE_THROW(BCRSMatrixError,"matrix already built up, use operator[] for entry access now");
    \n-
    1303 if (ready==notAllocated)
    \n-
    1304 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n-
    1305 if (ready!=building)
    \n-
    1306 DUNE_THROW(InvalidStateException,"You may only use entry() during the 'building' stage");
    \n-
    1307
    \n-
    1308 if (row >= n)
    \n-
    1309 DUNE_THROW(BCRSMatrixError,"row index exceeds matrix size");
    \n-
    1310 if (col >= m)
    \n-
    1311 DUNE_THROW(BCRSMatrixError,"column index exceeds matrix size");
    \n-
    1312#endif
    \n+
    1273
    \n+
    1274 } // end outer while loop
    \n+
    1275
    \n+
    1276 // post-process preconditioner
    \n+
    1277 _prec->post(x);
    \n+
    1278 }
    \n+
    1279
    \n+
    1280private:
    \n+
    1281 using RestartedGMResSolver<X,Y>::_op;
    \n+
    1282 using RestartedGMResSolver<X,Y>::_prec;
    \n+
    1283 using RestartedGMResSolver<X,Y>::_sp;
    \n+\n+\n+\n+\n+
    1288 using Iteration = typename IterativeSolver<X,X>::template Iteration<unsigned int>;
    \n+
    1289 };
    \n+
    1290 DUNE_REGISTER_ITERATIVE_SOLVER("restartedflexiblegmressolver", defaultIterativeSolverCreator<Dune::RestartedFlexibleGMResSolver>());
    \n+
    1291
    \n+
    1305 template<class X>
    \n+\n+
    1307 {
    \n+
    1308 public:
    \n+
    1309 using typename IterativeSolver<X,X>::domain_type;
    \n+
    1310 using typename IterativeSolver<X,X>::range_type;
    \n+
    1311 using typename IterativeSolver<X,X>::field_type;
    \n+
    1312 using typename IterativeSolver<X,X>::real_type;
    \n
    1313
    \n-
    1314 size_type* begin = r[row].getindexptr();
    \n-
    1315 size_type* end = begin + r[row].getsize();
    \n+
    1314 private:
    \n+\n
    1316
    \n-
    1317 size_type* pos = std::find(begin, end, col);
    \n-
    1318
    \n-
    1319 //treat the case that there was a match in the array
    \n-
    1320 if (pos != end)
    \n-
    1321 if (*pos == col)
    \n-
    1322 {
    \n-
    1323 std::ptrdiff_t offset = pos - r[row].getindexptr();
    \n-
    1324 B* aptr = r[row].getptr() + offset;
    \n-
    1325
    \n-
    1326 return *aptr;
    \n-
    1327 }
    \n-
    1328
    \n-
    1329 //determine whether overflow has to be taken into account or not
    \n-
    1330 if (r[row].getsize() == avg)
    \n-
    1331 return overflow[std::make_pair(row,col)];
    \n-
    1332 else
    \n-
    1333 {
    \n-
    1334 //modify index array
    \n-
    1335 *end = col;
    \n-
    1336
    \n-
    1337 //do simultaneous operations on data array a
    \n-
    1338 std::ptrdiff_t offset = end - r[row].getindexptr();
    \n-
    1339 B* apos = r[row].getptr() + offset;
    \n-
    1340
    \n-
    1341 //increase rowsize
    \n-
    1342 r[row].setsize(r[row].getsize()+1);
    \n-
    1343
    \n-
    1344 //return reference to the newly created entry
    \n-
    1345 return *apos;
    \n-
    1346 }
    \n-
    1347 }
    \n+\n+
    1319
    \n+
    1320 public:
    \n+
    1321
    \n+
    1322 // don't shadow four-argument version of apply defined in the base class
    \n+
    1323 using IterativeSolver<X,X>::apply;
    \n+
    1324
    \n+
    1331 GeneralizedPCGSolver (const LinearOperator<X,X>& op, Preconditioner<X,X>& prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :
    \n+
    1332 IterativeSolver<X,X>::IterativeSolver(op,prec,reduction,maxit,verbose),
    \n+
    1333 _restart(restart)
    \n+
    1334 {}
    \n+
    1335
    \n+
    1343 GeneralizedPCGSolver (const LinearOperator<X,X>& op, const ScalarProduct<X>& sp, Preconditioner<X,X>& prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :
    \n+
    1344 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n+
    1345 _restart(restart)
    \n+
    1346 {}
    \n+
    1347
    \n
    1348
    \n-
    1350
    \n-\n-
    1361 {
    \n-
    1362 if (build_mode!=implicit)
    \n-
    1363 DUNE_THROW(BCRSMatrixError,"requires implicit build mode");
    \n-
    1364 if (ready==built)
    \n-
    1365 DUNE_THROW(BCRSMatrixError,"matrix already built up, no more need for compression");
    \n-
    1366 if (ready==notAllocated)
    \n-
    1367 DUNE_THROW(BCRSMatrixError,"matrix size not set and no memory allocated yet");
    \n-
    1368 if (ready!=building)
    \n-
    1369 DUNE_THROW(InvalidStateException,"You may only call compress() at the end of the 'building' stage");
    \n-
    1370
    \n-
    1371 //calculate statistics
    \n-\n-
    1373 stats.overflow_total = overflow.size();
    \n-
    1374 stats.maximum = 0;
    \n-
    1375
    \n-
    1376 //get insertion iterators pointing to one before start (for later use of ++it)
    \n-
    1377 size_type* jiit = j_.get();
    \n-
    1378 B* aiit = a;
    \n-
    1379
    \n-
    1380 //get iterator to the smallest overflow element
    \n-
    1381 typename OverflowType::iterator oit = overflow.begin();
    \n-
    1382
    \n-
    1383 //store a copy of index pointers on which to perform sorting
    \n-
    1384 std::vector<size_type*> perm;
    \n+
    1361 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X> > op, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    1362 IterativeSolver<X,X>::IterativeSolver(op,prec,configuration),
    \n+
    1363 _restart(configuration.get<int>("restart"))
    \n+
    1364 {}
    \n+
    1365
    \n+
    1366 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X> > op, std::shared_ptr<const ScalarProduct<X> > sp, std::shared_ptr<Preconditioner<X,X> > prec, const ParameterTree& configuration) :
    \n+
    1367 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,configuration),
    \n+
    1368 _restart(configuration.get<int>("restart"))
    \n+
    1369 {}
    \n+
    1377 GeneralizedPCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n+
    1378 std::shared_ptr<const ScalarProduct<X>> sp,
    \n+
    1379 std::shared_ptr<Preconditioner<X,X>> prec,
    \n+
    1380 scalar_real_type reduction, int maxit, int verbose,
    \n+
    1381 int restart = 10) :
    \n+
    1382 IterativeSolver<X,X>::IterativeSolver(op,sp,prec,reduction,maxit,verbose),
    \n+
    1383 _restart(restart)
    \n+
    1384 {}
    \n
    1385
    \n-
    1386 //iterate over all rows and copy elements into their position in the compressed array
    \n-
    1387 for (size_type i=0; i<n; i++)
    \n-
    1388 {
    \n-
    1389 //get old pointers into a and j and size without overflow changes
    \n-
    1390 size_type* begin = r[i].getindexptr();
    \n-
    1391 //B* apos = r[i].getptr();
    \n-
    1392 size_type size = r[i].getsize();
    \n-
    1393
    \n-
    1394 perm.resize(size);
    \n-
    1395
    \n-
    1396 typename std::vector<size_type*>::iterator it = perm.begin();
    \n-
    1397 for (size_type* iit = begin; iit < begin + size; ++iit, ++it)
    \n-
    1398 *it = iit;
    \n-
    1399
    \n-
    1400 //sort permutation array
    \n-
    1401 std::sort(perm.begin(),perm.end(),PointerCompare<size_type>());
    \n-
    1402
    \n-
    1403 //change row window pointer to their new positions
    \n-
    1404 r[i].setindexptr(jiit);
    \n-
    1405 r[i].setptr(aiit);
    \n-
    1406
    \n-
    1407 for (it = perm.begin(); it != perm.end(); ++it)
    \n-
    1408 {
    \n-
    1409 //check whether there are elements in the overflow area which take precedence
    \n-
    1410 while ((oit!=overflow.end()) && (oit->first < std::make_pair(i,**it)))
    \n-
    1411 {
    \n-
    1412 //check whether there is enough memory to write to
    \n-
    1413 if (jiit > begin)
    \n-\n-
    1415 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n-
    1416 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n-
    1417 );
    \n-
    1418 //copy an element from the overflow area to the insertion position in a and j
    \n-
    1419 *jiit = oit->first.second;
    \n-
    1420 ++jiit;
    \n-
    1421 *aiit = oit->second;
    \n-
    1422 ++aiit;
    \n-
    1423 ++oit;
    \n-
    1424 r[i].setsize(r[i].getsize()+1);
    \n-
    1425 }
    \n-
    1426
    \n-
    1427 //check whether there is enough memory to write to
    \n-
    1428 if (jiit > begin)
    \n-\n-
    1430 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n-
    1431 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n-
    1432 );
    \n-
    1433
    \n-
    1434 //copy element from array
    \n-
    1435 *jiit = **it;
    \n-
    1436 ++jiit;
    \n-
    1437 B* apos = *it - j_.get() + a;
    \n-
    1438 *aiit = *apos;
    \n-
    1439 ++aiit;
    \n-
    1440 }
    \n+
    1391 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    1392 {
    \n+
    1393 Iteration iteration(*this, res);
    \n+
    1394 _prec->pre(x,b); // prepare preconditioner
    \n+
    1395 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n+
    1396
    \n+
    1397 std::vector<std::shared_ptr<X> > p(_restart);
    \n+
    1398 std::vector<field_type,fAlloc> pp(_restart);
    \n+
    1399 X q(x); // a temporary vector
    \n+
    1400 X prec_res(x); // a temporary vector for preconditioner output
    \n+
    1401
    \n+
    1402 p[0].reset(new X(x));
    \n+
    1403
    \n+
    1404 real_type def = _sp->norm(b); // compute norm
    \n+
    1405 if(iteration.step(0, def)){
    \n+
    1406 _prec->post(x);
    \n+
    1407 return;
    \n+
    1408 }
    \n+
    1409 // some local variables
    \n+
    1410 field_type rho, lambda;
    \n+
    1411
    \n+
    1412 int i=0;
    \n+
    1413 int ii=0;
    \n+
    1414 // determine initial search direction
    \n+
    1415 *(p[0]) = 0; // clear correction
    \n+
    1416 _prec->apply(*(p[0]),b); // apply preconditioner
    \n+
    1417 rho = _sp->dot(*(p[0]),b); // orthogonalization
    \n+
    1418 _op->apply(*(p[0]),q); // q=Ap
    \n+
    1419 pp[0] = _sp->dot(*(p[0]),q); // scalar product
    \n+
    1420 lambda = rho/pp[0]; // minimization
    \n+
    1421 x.axpy(lambda,*(p[0])); // update solution
    \n+
    1422 b.axpy(-lambda,q); // update defect
    \n+
    1423
    \n+
    1424 // convergence test
    \n+
    1425 def=_sp->norm(b); // comp defect norm
    \n+
    1426 ++i;
    \n+
    1427 if(iteration.step(i, def)){
    \n+
    1428 _prec->post(x);
    \n+
    1429 return;
    \n+
    1430 }
    \n+
    1431
    \n+
    1432 while(i<_maxit) {
    \n+
    1433 // the loop
    \n+
    1434 int end=std::min(_restart, _maxit-i+1);
    \n+
    1435 for (ii=1; ii<end; ++ii )
    \n+
    1436 {
    \n+
    1437 //std::cout<<" ii="<<ii<<" i="<<i<<std::endl;
    \n+
    1438 // compute next conjugate direction
    \n+
    1439 prec_res = 0; // clear correction
    \n+
    1440 _prec->apply(prec_res,b); // apply preconditioner
    \n
    1441
    \n-
    1442 //copy remaining elements from the overflow area
    \n-
    1443 while ((oit!=overflow.end()) && (oit->first.first == i))
    \n-
    1444 {
    \n-
    1445 //check whether there is enough memory to write to
    \n-
    1446 if (jiit > begin)
    \n-\n-
    1448 "Allocated memory for BCRSMatrix exhausted during compress()!"
    \n-
    1449 "Please increase either the average number of entries per row or the compressionBufferSize value."
    \n-
    1450 );
    \n-
    1451
    \n-
    1452 //copy and element from the overflow area to the insertion position in a and j
    \n-
    1453 *jiit = oit->first.second;
    \n-
    1454 ++jiit;
    \n-
    1455 *aiit = oit->second;
    \n-
    1456 ++aiit;
    \n-
    1457 ++oit;
    \n-
    1458 r[i].setsize(r[i].getsize()+1);
    \n-
    1459 }
    \n+
    1442 p[ii].reset(new X(prec_res));
    \n+
    1443 _op->apply(prec_res, q);
    \n+
    1444
    \n+
    1445 for(int j=0; j<ii; ++j) {
    \n+
    1446 rho =_sp->dot(q,*(p[j]))/pp[j];
    \n+
    1447 p[ii]->axpy(-rho, *(p[j]));
    \n+
    1448 }
    \n+
    1449
    \n+
    1450 // minimize in given search direction
    \n+
    1451 _op->apply(*(p[ii]),q); // q=Ap
    \n+
    1452 pp[ii] = _sp->dot(*(p[ii]),q); // scalar product
    \n+
    1453 rho = _sp->dot(*(p[ii]),b); // orthogonalization
    \n+
    1454 lambda = rho/pp[ii]; // minimization
    \n+
    1455 x.axpy(lambda,*(p[ii])); // update solution
    \n+
    1456 b.axpy(-lambda,q); // update defect
    \n+
    1457
    \n+
    1458 // convergence test
    \n+
    1459 def = _sp->norm(b); // comp defect norm
    \n
    1460
    \n-
    1461 // update maximum row size
    \n-
    1462 if (r[i].getsize()>stats.maximum)
    \n-
    1463 stats.maximum = r[i].getsize();
    \n-
    1464 }
    \n-
    1465
    \n-
    1466 // overflow area may be cleared
    \n-
    1467 overflow.clear();
    \n-
    1468
    \n-
    1469 //determine average number of entries and memory usage
    \n-
    1470 std::ptrdiff_t diff = (r[n-1].getindexptr() + r[n-1].getsize() - j_.get());
    \n-
    1471 nnz_ = diff;
    \n-
    1472 stats.avg = (double) (nnz_) / (double) n;
    \n-
    1473 stats.mem_ratio = (double) (nnz_) / (double) allocationSize_;
    \n+
    1461 ++i;
    \n+
    1462 iteration.step(i, def);
    \n+
    1463 }
    \n+
    1464 if(res.converged)
    \n+
    1465 break;
    \n+
    1466 if(end==_restart) {
    \n+
    1467 *(p[0])=*(p[_restart-1]);
    \n+
    1468 pp[0]=pp[_restart-1];
    \n+
    1469 }
    \n+
    1470 }
    \n+
    1471
    \n+
    1472 // postprocess preconditioner
    \n+
    1473 _prec->post(x);
    \n
    1474
    \n-
    1475 //matrix is now built
    \n-
    1476 ready = built;
    \n-
    1477
    \n-
    1478 return stats;
    \n-
    1479 }
    \n-
    1480
    \n-
    1481 //===== vector space arithmetic
    \n-
    1482
    \n-\n-
    1485 {
    \n-
    1486#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1487 if (ready != built)
    \n-
    1488 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1489#endif
    \n-
    1490
    \n-
    1491 if (nnz_ > 0)
    \n-
    1492 {
    \n-
    1493 // process 1D array
    \n-
    1494 for (size_type i=0; i<nnz_; i++)
    \n-
    1495 a[i] *= k;
    \n-
    1496 }
    \n-
    1497 else
    \n-
    1498 {
    \n-
    1499 RowIterator endi=end();
    \n-
    1500 for (RowIterator i=begin(); i!=endi; ++i)
    \n-
    1501 {
    \n-
    1502 ColIterator endj = (*i).end();
    \n-
    1503 for (ColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1504 (*j) *= k;
    \n-
    1505 }
    \n-
    1506 }
    \n+
    1475 }
    \n+
    1476
    \n+
    1477 private:
    \n+
    1478 using IterativeSolver<X,X>::_op;
    \n+
    1479 using IterativeSolver<X,X>::_prec;
    \n+
    1480 using IterativeSolver<X,X>::_sp;
    \n+
    1481 using IterativeSolver<X,X>::_reduction;
    \n+
    1482 using IterativeSolver<X,X>::_maxit;
    \n+
    1483 using IterativeSolver<X,X>::_verbose;
    \n+
    1484 using Iteration = typename IterativeSolver<X,X>::template Iteration<unsigned int>;
    \n+
    1485 int _restart;
    \n+
    1486 };
    \n+
    1487 DUNE_REGISTER_ITERATIVE_SOLVER("generalizedpcgsolver", defaultIterativeSolverCreator<Dune::GeneralizedPCGSolver>());
    \n+
    1488
    \n+
    1500 template<class X>
    \n+\n+
    1502 public:
    \n+
    1503 using typename IterativeSolver<X,X>::domain_type;
    \n+
    1504 using typename IterativeSolver<X,X>::range_type;
    \n+
    1505 using typename IterativeSolver<X,X>::field_type;
    \n+
    1506 using typename IterativeSolver<X,X>::real_type;
    \n
    1507
    \n-
    1508 return *this;
    \n-
    1509 }
    \n+
    1508 private:
    \n+\n
    1510
    \n-\n-
    1513 {
    \n-
    1514#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1515 if (ready != built)
    \n-
    1516 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1517#endif
    \n-
    1518
    \n-
    1519 if (nnz_ > 0)
    \n-
    1520 {
    \n-
    1521 // process 1D array
    \n-
    1522 for (size_type i=0; i<nnz_; i++)
    \n-
    1523 a[i] /= k;
    \n-
    1524 }
    \n-
    1525 else
    \n-
    1526 {
    \n-
    1527 RowIterator endi=end();
    \n-
    1528 for (RowIterator i=begin(); i!=endi; ++i)
    \n-
    1529 {
    \n-
    1530 ColIterator endj = (*i).end();
    \n-
    1531 for (ColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1532 (*j) /= k;
    \n-
    1533 }
    \n-
    1534 }
    \n-
    1535
    \n-
    1536 return *this;
    \n-
    1537 }
    \n-
    1538
    \n-
    1539
    \n-\n-
    1546 {
    \n-
    1547#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1548 if (ready != built || b.ready != built)
    \n-
    1549 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1550 if(N()!=b.N() || M() != b.M())
    \n-
    1551 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n-
    1552#endif
    \n-
    1553 RowIterator endi=end();
    \n-
    1554 ConstRowIterator j=b.begin();
    \n-
    1555 for (RowIterator i=begin(); i!=endi; ++i, ++j) {
    \n-
    1556 i->operator+=(*j);
    \n-
    1557 }
    \n-
    1558
    \n-
    1559 return *this;
    \n-
    1560 }
    \n-
    1561
    \n-\n-
    1568 {
    \n-
    1569#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1570 if (ready != built || b.ready != built)
    \n-
    1571 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1572 if(N()!=b.N() || M() != b.M())
    \n-
    1573 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n-
    1574#endif
    \n-
    1575 RowIterator endi=end();
    \n-
    1576 ConstRowIterator j=b.begin();
    \n-
    1577 for (RowIterator i=begin(); i!=endi; ++i, ++j) {
    \n-
    1578 i->operator-=(*j);
    \n-
    1579 }
    \n-
    1580
    \n-
    1581 return *this;
    \n-
    1582 }
    \n-
    1583
    \n-\n-
    1593 {
    \n-
    1594#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1595 if (ready != built || b.ready != built)
    \n-
    1596 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1597 if(N()!=b.N() || M() != b.M())
    \n-
    1598 DUNE_THROW(RangeError, "Matrix sizes do not match!");
    \n-
    1599#endif
    \n-
    1600 RowIterator endi=end();
    \n-
    1601 ConstRowIterator j=b.begin();
    \n-
    1602 for(RowIterator i=begin(); i!=endi; ++i, ++j)
    \n-
    1603 i->axpy(alpha, *j);
    \n-
    1604
    \n-
    1605 return *this;
    \n-
    1606 }
    \n-
    1607
    \n-
    1608 //===== linear maps
    \n-
    1609
    \n-
    1611 template<class X, class Y>
    \n-
    1612 void mv (const X& x, Y& y) const
    \n-
    1613 {
    \n-
    1614#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1615 if (ready != built)
    \n-
    1616 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1617 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,
    \n-
    1618 "Size mismatch: M: " << N() << "x" << M() << " x: " << x.N());
    \n-
    1619 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,
    \n-
    1620 "Size mismatch: M: " << N() << "x" << M() << " y: " << y.N());
    \n-
    1621#endif
    \n-
    1622 ConstRowIterator endi=end();
    \n-
    1623 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1624 {
    \n-
    1625 y[i.index()]=0;
    \n-
    1626 ConstColIterator endj = (*i).end();
    \n-
    1627 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1628 {
    \n-
    1629 auto&& xj = Impl::asVector(x[j.index()]);
    \n-
    1630 auto&& yi = Impl::asVector(y[i.index()]);
    \n-
    1631 Impl::asMatrix(*j).umv(xj, yi);
    \n+
    1511 public:
    \n+
    1512 // don't shadow four-argument version of apply defined in the base class
    \n+
    1513 using IterativeSolver<X,X>::apply;
    \n+\n+
    1520 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) : IterativeSolver<X,X>(op, prec, reduction, maxit, verbose), _mmax(mmax)
    \n+
    1521 {
    \n+
    1522 }
    \n+
    1523
    \n+\n+
    1530 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)
    \n+
    1531 {
    \n+
    1532 }
    \n+
    1533
    \n+
    1539 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n+
    1540 std::shared_ptr<const ScalarProduct<X>> sp,
    \n+
    1541 std::shared_ptr<Preconditioner<X,X>> prec,
    \n+
    1542 scalar_real_type reduction, int maxit, int verbose,
    \n+
    1543 int mmax = 10)
    \n+
    1544 : IterativeSolver<X,X>(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)
    \n+
    1545 {}
    \n+
    1546
    \n+
    1559 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n+
    1560 std::shared_ptr<Preconditioner<X,X>> prec,
    \n+
    1561 const ParameterTree& config)
    \n+
    1562 : IterativeSolver<X,X>(op, prec, config), _mmax(config.get("mmax", 10))
    \n+
    1563 {}
    \n+
    1564
    \n+
    1565 RestartedFCGSolver (std::shared_ptr<const LinearOperator<X,X>> op,
    \n+
    1566 std::shared_ptr<const ScalarProduct<X>> sp,
    \n+
    1567 std::shared_ptr<Preconditioner<X,X>> prec,
    \n+
    1568 const ParameterTree& config)
    \n+
    1569 : IterativeSolver<X,X>(op, sp, prec, config), _mmax(config.get("mmax", 10))
    \n+
    1570 {}
    \n+
    1571
    \n+
    1584 virtual void apply (X& x, X& b, InverseOperatorResult& res)
    \n+
    1585 {
    \n+\n+
    1587 res.clear();
    \n+
    1588 Iteration iteration(*this,res);
    \n+
    1589 _prec->pre(x,b); // prepare preconditioner
    \n+
    1590 _op->applyscaleadd(-1,x,b); // overwrite b with defect
    \n+
    1591
    \n+
    1592 //arrays for interim values:
    \n+
    1593 std::vector<X> d(_mmax+1, x); // array for directions
    \n+
    1594 std::vector<X> Ad(_mmax+1, x); // array for Ad[i]
    \n+
    1595 std::vector<field_type,rAlloc> ddotAd(_mmax+1,0); // array for <d[i],Ad[i]>
    \n+
    1596 X w(x);
    \n+
    1597
    \n+
    1598 real_type def = _sp->norm(b); // compute norm
    \n+
    1599 if(iteration.step(0, def)){
    \n+
    1600 _prec->post(x);
    \n+
    1601 return;
    \n+
    1602 }
    \n+
    1603
    \n+
    1604 // some local variables
    \n+
    1605 field_type alpha;
    \n+
    1606
    \n+
    1607 // the loop
    \n+
    1608 int i=1;
    \n+
    1609 int i_bounded=0;
    \n+
    1610 while(i<=_maxit && !res.converged) {
    \n+
    1611 for (; i_bounded <= _mmax && i<= _maxit; i_bounded++) {
    \n+
    1612 d[i_bounded] = 0; // reset search direction
    \n+
    1613 _prec->apply(d[i_bounded], b); // apply preconditioner
    \n+
    1614 w = d[i_bounded]; // copy of current d[i]
    \n+
    1615 // orthogonalization with previous directions
    \n+
    1616 orthogonalizations(i_bounded,Ad,w,ddotAd,d);
    \n+
    1617
    \n+
    1618 //saving interim values for future calculating
    \n+
    1619 _op->apply(d[i_bounded], Ad[i_bounded]); // save Ad[i]
    \n+
    1620 ddotAd[i_bounded]=_sp->dot(d[i_bounded],Ad[i_bounded]); // save <d[i],Ad[i]>
    \n+
    1621 alpha = _sp->dot(d[i_bounded], b)/ddotAd[i_bounded]; // <d[i],b>/<d[i],Ad[i]>
    \n+
    1622
    \n+
    1623 //update solution and defect
    \n+
    1624 x.axpy(alpha, d[i_bounded]);
    \n+
    1625 b.axpy(-alpha, Ad[i_bounded]);
    \n+
    1626
    \n+
    1627 // convergence test
    \n+
    1628 def = _sp->norm(b); // comp defect norm
    \n+
    1629
    \n+
    1630 iteration.step(i, def);
    \n+
    1631 i++;
    \n
    1632 }
    \n-
    1633 }
    \n-
    1634 }
    \n-
    1635
    \n-
    1637 template<class X, class Y>
    \n-
    1638 void umv (const X& x, Y& y) const
    \n-
    1639 {
    \n-
    1640#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1641 if (ready != built)
    \n-
    1642 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1643 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1644 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1645#endif
    \n-
    1646 ConstRowIterator endi=end();
    \n-
    1647 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1648 {
    \n-
    1649 ConstColIterator endj = (*i).end();
    \n-
    1650 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1651 {
    \n-
    1652 auto&& xj = Impl::asVector(x[j.index()]);
    \n-
    1653 auto&& yi = Impl::asVector(y[i.index()]);
    \n-
    1654 Impl::asMatrix(*j).umv(xj,yi);
    \n-
    1655 }
    \n-
    1656 }
    \n-
    1657 }
    \n-
    1658
    \n-
    1660 template<class X, class Y>
    \n-
    1661 void mmv (const X& x, Y& y) const
    \n-
    1662 {
    \n-
    1663#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1664 if (ready != built)
    \n-
    1665 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1666 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1667 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1668#endif
    \n-
    1669 ConstRowIterator endi=end();
    \n-
    1670 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1671 {
    \n-
    1672 ConstColIterator endj = (*i).end();
    \n-
    1673 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1674 {
    \n-
    1675 auto&& xj = Impl::asVector(x[j.index()]);
    \n-
    1676 auto&& yi = Impl::asVector(y[i.index()]);
    \n-
    1677 Impl::asMatrix(*j).mmv(xj,yi);
    \n-
    1678 }
    \n-
    1679 }
    \n-
    1680 }
    \n-
    1681
    \n-
    1683 template<class X, class Y, class F>
    \n-
    1684 void usmv (F&& alpha, const X& x, Y& y) const
    \n-
    1685 {
    \n-
    1686#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1687 if (ready != built)
    \n-
    1688 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1689 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1690 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1691#endif
    \n-
    1692 ConstRowIterator endi=end();
    \n-
    1693 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1694 {
    \n-
    1695 ConstColIterator endj = (*i).end();
    \n-
    1696 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1697 {
    \n-
    1698 auto&& xj = Impl::asVector(x[j.index()]);
    \n-
    1699 auto&& yi = Impl::asVector(y[i.index()]);
    \n-
    1700 Impl::asMatrix(*j).usmv(alpha,xj,yi);
    \n-
    1701 }
    \n-
    1702 }
    \n-
    1703 }
    \n-
    1704
    \n-
    1706 template<class X, class Y>
    \n-
    1707 void mtv (const X& x, Y& y) const
    \n-
    1708 {
    \n-
    1709#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1710 if (ready != built)
    \n-
    1711 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1712 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1713 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1714#endif
    \n-
    1715 for(size_type i=0; i<y.N(); ++i)
    \n-
    1716 y[i]=0;
    \n-
    1717 umtv(x,y);
    \n-
    1718 }
    \n-
    1719
    \n-
    1721 template<class X, class Y>
    \n-
    1722 void umtv (const X& x, Y& y) const
    \n-
    1723 {
    \n-
    1724#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1725 if (ready != built)
    \n-
    1726 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1727 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1728 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1729#endif
    \n-
    1730 ConstRowIterator endi=end();
    \n-
    1731 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1732 {
    \n-
    1733 ConstColIterator endj = (*i).end();
    \n-
    1734 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1735 {
    \n-
    1736 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1737 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1738 Impl::asMatrix(*j).umtv(xi,yj);
    \n-
    1739 }
    \n-
    1740 }
    \n-
    1741 }
    \n-
    1742
    \n-
    1744 template<class X, class Y>
    \n-
    1745 void mmtv (const X& x, Y& y) const
    \n-
    1746 {
    \n-
    1747#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1748 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1749 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1750#endif
    \n-
    1751 ConstRowIterator endi=end();
    \n-
    1752 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1753 {
    \n-
    1754 ConstColIterator endj = (*i).end();
    \n-
    1755 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1756 {
    \n-
    1757 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1758 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1759 Impl::asMatrix(*j).mmtv(xi,yj);
    \n-
    1760 }
    \n-
    1761 }
    \n-
    1762 }
    \n-
    1763
    \n-
    1765 template<class X, class Y>
    \n-
    1766 void usmtv (const field_type& alpha, const X& x, Y& y) const
    \n-
    1767 {
    \n-
    1768#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1769 if (ready != built)
    \n-
    1770 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1771 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1772 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1773#endif
    \n-
    1774 ConstRowIterator endi=end();
    \n-
    1775 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1776 {
    \n-
    1777 ConstColIterator endj = (*i).end();
    \n-
    1778 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1779 {
    \n-
    1780 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1781 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1782 Impl::asMatrix(*j).usmtv(alpha,xi,yj);
    \n-
    1783 }
    \n-
    1784 }
    \n-
    1785 }
    \n-
    1786
    \n-
    1788 template<class X, class Y>
    \n-
    1789 void umhv (const X& x, Y& y) const
    \n-
    1790 {
    \n-
    1791#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1792 if (ready != built)
    \n-
    1793 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1794 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1795 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1796#endif
    \n-
    1797 ConstRowIterator endi=end();
    \n-
    1798 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1799 {
    \n-
    1800 ConstColIterator endj = (*i).end();
    \n-
    1801 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1802 {
    \n-
    1803 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1804 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1805 Impl::asMatrix(*j).umhv(xi,yj);
    \n-
    1806 }
    \n-
    1807 }
    \n-
    1808 }
    \n-
    1809
    \n-
    1811 template<class X, class Y>
    \n-
    1812 void mmhv (const X& x, Y& y) const
    \n-
    1813 {
    \n-
    1814#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1815 if (ready != built)
    \n-
    1816 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1817 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1818 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1819#endif
    \n-
    1820 ConstRowIterator endi=end();
    \n-
    1821 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1822 {
    \n-
    1823 ConstColIterator endj = (*i).end();
    \n-
    1824 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1825 {
    \n-
    1826 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1827 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1828 Impl::asMatrix(*j).mmhv(xi,yj);
    \n-
    1829 }
    \n-
    1830 }
    \n-
    1831 }
    \n-
    1832
    \n-
    1834 template<class X, class Y>
    \n-
    1835 void usmhv (const field_type& alpha, const X& x, Y& y) const
    \n-
    1836 {
    \n-
    1837#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1838 if (ready != built)
    \n-
    1839 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1840 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1841 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,"index out of range");
    \n-
    1842#endif
    \n-
    1843 ConstRowIterator endi=end();
    \n-
    1844 for (ConstRowIterator i=this->begin(); i!=endi; ++i)
    \n-
    1845 {
    \n-
    1846 ConstColIterator endj = (*i).end();
    \n-
    1847 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
    \n-
    1848 {
    \n-
    1849 auto&& xi = Impl::asVector(x[i.index()]);
    \n-
    1850 auto&& yj = Impl::asVector(y[j.index()]);
    \n-
    1851 Impl::asMatrix(*j).usmhv(alpha,xi,yj);
    \n-
    1852 }
    \n-
    1853 }
    \n-
    1854 }
    \n-
    1855
    \n-
    1856
    \n-
    1857 //===== norms
    \n-
    1858
    \n-
    1860 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
    \n-
    1861 {
    \n-
    1862#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1863 if (ready != built)
    \n-
    1864 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1865#endif
    \n-
    1866
    \n-
    1867 typename FieldTraits<field_type>::real_type sum=0;
    \n-
    1868
    \n-
    1869 for (auto&& row : (*this))
    \n-
    1870 for (auto&& entry : row)
    \n-
    1871 sum += Impl::asMatrix(entry).frobenius_norm2();
    \n-
    1872
    \n-
    1873 return sum;
    \n-
    1874 }
    \n-
    1875
    \n-
    1877 typename FieldTraits<field_type>::real_type frobenius_norm () const
    \n-
    1878 {
    \n-
    1879 return sqrt(frobenius_norm2());
    \n-
    1880 }
    \n-
    1881
    \n-
    1883 template <typename ft = field_type,
    \n-
    1884 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    1885 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    1886 if (ready != built)
    \n-
    1887 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1888
    \n-
    1889 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1890 using std::max;
    \n-
    1891
    \n-
    1892 real_type norm = 0;
    \n-
    1893 for (auto const &x : *this) {
    \n-
    1894 real_type sum = 0;
    \n-
    1895 for (auto const &y : x)
    \n-
    1896 sum += Impl::asMatrix(y).infinity_norm();
    \n-
    1897 norm = max(sum, norm);
    \n-
    1898 }
    \n-
    1899 return norm;
    \n-
    1900 }
    \n-
    1901
    \n-
    1903 template <typename ft = field_type,
    \n-
    1904 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
    \n-
    1905 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    1906 if (ready != built)
    \n-
    1907 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1908
    \n-
    1909 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1910 using std::max;
    \n-
    1911
    \n-
    1912 real_type norm = 0;
    \n-
    1913 for (auto const &x : *this) {
    \n-
    1914 real_type sum = 0;
    \n-
    1915 for (auto const &y : x)
    \n-
    1916 sum += Impl::asMatrix(y).infinity_norm_real();
    \n-
    1917 norm = max(sum, norm);
    \n-
    1918 }
    \n-
    1919 return norm;
    \n-
    1920 }
    \n-
    1921
    \n-
    1923 template <typename ft = field_type,
    \n-
    1924 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    1925 typename FieldTraits<ft>::real_type infinity_norm() const {
    \n-
    1926 if (ready != built)
    \n-
    1927 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1928
    \n-
    1929 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1930 using std::max;
    \n-
    1931
    \n-
    1932 real_type norm = 0;
    \n-
    1933 real_type isNaN = 1;
    \n-
    1934 for (auto const &x : *this) {
    \n-
    1935 real_type sum = 0;
    \n-
    1936 for (auto const &y : x)
    \n-
    1937 sum += Impl::asMatrix(y).infinity_norm();
    \n-
    1938 norm = max(sum, norm);
    \n-
    1939 isNaN += sum;
    \n-
    1940 }
    \n-
    1941
    \n-
    1942 return norm * (isNaN / isNaN);
    \n-
    1943 }
    \n-
    1944
    \n-
    1946 template <typename ft = field_type,
    \n-
    1947 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
    \n-
    1948 typename FieldTraits<ft>::real_type infinity_norm_real() const {
    \n-
    1949 if (ready != built)
    \n-
    1950 DUNE_THROW(BCRSMatrixError,"You can only call arithmetic operations on fully built BCRSMatrix instances");
    \n-
    1951
    \n-
    1952 using real_type = typename FieldTraits<ft>::real_type;
    \n-
    1953 using std::max;
    \n-
    1954
    \n-
    1955 real_type norm = 0;
    \n-
    1956 real_type isNaN = 1;
    \n-
    1957
    \n-
    1958 for (auto const &x : *this) {
    \n-
    1959 real_type sum = 0;
    \n-
    1960 for (auto const &y : x)
    \n-
    1961 sum += Impl::asMatrix(y).infinity_norm_real();
    \n-
    1962 norm = max(sum, norm);
    \n-
    1963 isNaN += sum;
    \n-
    1964 }
    \n-
    1965
    \n-
    1966 return norm * (isNaN / isNaN);
    \n-
    1967 }
    \n-
    1968
    \n-
    1969 //===== sizes
    \n-
    1970
    \n-
    1972 size_type N () const
    \n-
    1973 {
    \n-
    1974 return n;
    \n-
    1975 }
    \n-
    1976
    \n-
    1978 size_type M () const
    \n-
    1979 {
    \n-
    1980 return m;
    \n-
    1981 }
    \n-
    1982
    \n-\n-
    1985 {
    \n-
    1986 // in case of row-wise allocation
    \n-
    1987 if( nnz_ <= 0 )
    \n-
    1988 nnz_ = std::accumulate( begin(), end(), size_type( 0 ), [] ( size_type s, const row_type &row ) { return s+row.getsize(); } );
    \n-
    1989 return nnz_;
    \n-
    1990 }
    \n-
    1991
    \n-\n-
    1994 {
    \n-
    1995 return ready;
    \n-
    1996 }
    \n-
    1997
    \n-\n-
    2000 {
    \n-
    2001 return build_mode;
    \n-
    2002 }
    \n-
    2003
    \n-
    2004 //===== query
    \n-
    2005
    \n-
    2007 bool exists (size_type i, size_type j) const
    \n-
    2008 {
    \n-
    2009#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    2010 if (i<0 || i>=n) DUNE_THROW(BCRSMatrixError,"row index out of range");
    \n-
    2011 if (j<0 || j>=m) DUNE_THROW(BCRSMatrixError,"column index out of range");
    \n-
    2012#endif
    \n-
    2013 return (r[i].size() && r[i].find(j) != r[i].end());
    \n-
    2014 }
    \n-
    2015
    \n-
    2016
    \n-
    2017 protected:
    \n-
    2018 // state information
    \n-
    2019 BuildMode build_mode; // row wise or whole matrix
    \n-
    2020 BuildStage ready; // indicate the stage the matrix building is in
    \n-
    2021
    \n-
    2022 // The allocator used for memory management
    \n-
    2023 typename std::allocator_traits<A>::template rebind_alloc<B> allocator_;
    \n-
    2024
    \n-
    2025 typename std::allocator_traits<A>::template rebind_alloc<row_type> rowAllocator_;
    \n-
    2026
    \n-
    2027 typename std::allocator_traits<A>::template rebind_alloc<size_type> sizeAllocator_;
    \n-
    2028
    \n-
    2029 // size of the matrix
    \n-
    2030 size_type n; // number of rows
    \n-
    2031 size_type m; // number of columns
    \n-
    2032 mutable size_type nnz_; // number of nonzeroes contained in the matrix
    \n-
    2033 size_type allocationSize_; //allocated size of a and j arrays, except in implicit mode: nnz_==allocationsSize_
    \n-
    2034 // zero means that memory is allocated separately for each row.
    \n-
    2035
    \n-
    2036 // the rows are dynamically allocated
    \n-
    2037 row_type* r; // [n] the individual rows having pointers into a,j arrays
    \n-
    2038
    \n-
    2039 // dynamically allocated memory
    \n-
    2040 B* a; // [allocationSize] non-zero entries of the matrix in row-wise ordering
    \n-
    2041 // If a single array of column indices is used, it can be shared
    \n-
    2042 // between different matrices with the same sparsity pattern
    \n-
    2043 std::shared_ptr<size_type> j_; // [allocationSize] column indices of entries
    \n-
    2044
    \n-
    2045 // additional data is needed in implicit buildmode
    \n-\n-\n-
    2048
    \n-
    2049 typedef std::map<std::pair<size_type,size_type>, B> OverflowType;
    \n-\n-
    2051
    \n-\n-
    2053 {
    \n-
    2054 row_type current_row(a,j_.get(),0); // Pointers to current row data
    \n-
    2055 for (size_type i=0; i<n; i++, ++row) {
    \n-
    2056 // set row i
    \n-
    2057 size_type s = row->getsize();
    \n-
    2058
    \n-
    2059 if (s>0) {
    \n-
    2060 // setup pointers and size
    \n-
    2061 r[i].set(s,current_row.getptr(), current_row.getindexptr());
    \n-
    2062 // update pointer for next row
    \n-
    2063 current_row.setptr(current_row.getptr()+s);
    \n-
    2064 current_row.setindexptr(current_row.getindexptr()+s);
    \n-
    2065 } else{
    \n-
    2066 // empty row
    \n-
    2067 r[i].set(0,nullptr,nullptr);
    \n-
    2068 }
    \n-
    2069 }
    \n-
    2070 }
    \n-
    2071
    \n-
    2073
    \n-\n-
    2078 {
    \n-
    2079 size_type* jptr = j_.get();
    \n-
    2080 for (size_type i=0; i<n; ++i, ++row) {
    \n-
    2081 // set row i
    \n-
    2082 size_type s = row->getsize();
    \n-
    2083
    \n-
    2084 if (s>0) {
    \n-
    2085 // setup pointers and size
    \n-
    2086 r[i].setsize(s);
    \n-
    2087 r[i].setindexptr(jptr);
    \n-
    2088 } else{
    \n-
    2089 // empty row
    \n-
    2090 r[i].set(0,nullptr,nullptr);
    \n-
    2091 }
    \n-
    2092
    \n-
    2093 // advance position in global array
    \n-
    2094 jptr += s;
    \n-
    2095 }
    \n-
    2096 }
    \n-
    2097
    \n-
    2099
    \n-\n-
    2104 {
    \n-
    2105 B* aptr = a;
    \n-
    2106 for (size_type i=0; i<n; ++i) {
    \n-
    2107 // set row i
    \n-
    2108 if (r[i].getsize() > 0) {
    \n-
    2109 // setup pointers and size
    \n-
    2110 r[i].setptr(aptr);
    \n-
    2111 } else{
    \n-
    2112 // empty row
    \n-
    2113 r[i].set(0,nullptr,nullptr);
    \n-
    2114 }
    \n-
    2115
    \n-
    2116 // advance position in global array
    \n-
    2117 aptr += r[i].getsize();
    \n-
    2118 }
    \n-
    2119 }
    \n-
    2120
    \n-\n-
    2123 {
    \n-
    2124 setWindowPointers(Mat.begin());
    \n-
    2125
    \n-
    2126 // copy data
    \n-
    2127 for (size_type i=0; i<n; i++) r[i] = Mat.r[i];
    \n-
    2128
    \n-
    2129 // finish off
    \n-
    2130 build_mode = row_wise; // dummy
    \n-
    2131 ready = built;
    \n-
    2132 }
    \n-
    2133
    \n-
    2139 void deallocate(bool deallocateRows=true)
    \n-
    2140 {
    \n-
    2141
    \n-
    2142 if (notAllocated)
    \n-
    2143 return;
    \n-
    2144
    \n-
    2145 if (allocationSize_>0)
    \n-
    2146 {
    \n-
    2147 // a,j_ have been allocated as one long vector
    \n-
    2148 j_.reset();
    \n-
    2149 if (a)
    \n-
    2150 {
    \n-
    2151 for(B *aiter=a+(allocationSize_-1), *aend=a-1; aiter!=aend; --aiter)
    \n-
    2152 std::allocator_traits<decltype(allocator_)>::destroy(allocator_, aiter);
    \n-
    2153 allocator_.deallocate(a,allocationSize_);
    \n-
    2154 a = nullptr;
    \n-
    2155 }
    \n-
    2156 }
    \n-
    2157 else if (r)
    \n-
    2158 {
    \n-
    2159 // check if memory for rows have been allocated individually
    \n-
    2160 for (size_type i=0; i<n; i++)
    \n-
    2161 if (r[i].getsize()>0)
    \n-
    2162 {
    \n-
    2163 for (B *col=r[i].getptr()+(r[i].getsize()-1),
    \n-
    2164 *colend = r[i].getptr()-1; col!=colend; --col) {
    \n-
    2165 std::allocator_traits<decltype(allocator_)>::destroy(allocator_, col);
    \n-
    2166 }
    \n-
    2167 sizeAllocator_.deallocate(r[i].getindexptr(),1);
    \n-
    2168 allocator_.deallocate(r[i].getptr(),1);
    \n-
    2169 // clear out row data in case we don't want to deallocate the rows
    \n-
    2170 // otherwise we might run into a double free problem here later
    \n-
    2171 r[i].set(0,nullptr,nullptr);
    \n-
    2172 }
    \n-
    2173 }
    \n-
    2174
    \n-
    2175 // deallocate the rows
    \n-
    2176 if (n>0 && deallocateRows && r) {
    \n-
    2177 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)
    \n-
    2178 std::allocator_traits<decltype(rowAllocator_)>::destroy(rowAllocator_, riter);
    \n-
    2179 rowAllocator_.deallocate(r,n);
    \n-
    2180 r = nullptr;
    \n-
    2181 }
    \n-
    2182
    \n-
    2183 // Mark matrix as not built at all.
    \n-\n-
    2185
    \n-
    2186 }
    \n-
    2187
    \n-
    2205 void allocate(size_type rows, size_type columns, size_type allocationSize, bool allocateRows, bool allocate_data)
    \n-
    2206 {
    \n-
    2207 // Store size
    \n-
    2208 n = rows;
    \n-
    2209 m = columns;
    \n-
    2210 nnz_ = allocationSize;
    \n-
    2211 allocationSize_ = allocationSize;
    \n-
    2212
    \n-
    2213 // allocate rows
    \n-
    2214 if(allocateRows) {
    \n-
    2215 if (n>0) {
    \n-
    2216 if (r)
    \n-
    2217 DUNE_THROW(InvalidStateException,"Rows have already been allocated, cannot allocate a second time");
    \n-
    2218 r = rowAllocator_.allocate(rows);
    \n-
    2219 // initialize row entries
    \n-
    2220 for(row_type* ri=r; ri!=r+rows; ++ri)
    \n-
    2221 std::allocator_traits<decltype(rowAllocator_)>::construct(rowAllocator_, ri, row_type());
    \n-
    2222 }else{
    \n-
    2223 r = 0;
    \n-
    2224 }
    \n-
    2225 }
    \n-
    2226
    \n-
    2227 // allocate a and j_ array
    \n-
    2228 if (allocate_data)
    \n-
    2229 allocateData();
    \n-
    2230 // allocate column indices only if not yet present (enable sharing)
    \n-
    2231 if (allocationSize_>0) {
    \n-
    2232 // we copy allocator and size to the deleter since _j may outlive this class
    \n-
    2233 if (!j_.get())
    \n-
    2234 j_.reset(sizeAllocator_.allocate(allocationSize_),
    \n-
    2235 [alloc = sizeAllocator_, size = allocationSize_](auto ptr) mutable {
    \n-
    2236 alloc.deallocate(ptr, size);
    \n-
    2237 });
    \n-
    2238 }else{
    \n-
    2239 j_.reset();
    \n-
    2240 }
    \n-
    2241
    \n-
    2242 // Mark the matrix as not built.
    \n-
    2243 ready = building;
    \n-
    2244 }
    \n-
    2245
    \n-\n-
    2247 {
    \n-
    2248 if (a)
    \n-
    2249 DUNE_THROW(InvalidStateException,"Cannot allocate data array (already allocated)");
    \n-
    2250 if (allocationSize_>0) {
    \n-
    2251 a = allocator_.allocate(allocationSize_);
    \n-
    2252 // use placement new to call constructor that allocates
    \n-
    2253 // additional memory.
    \n-
    2254 new (a) B[allocationSize_];
    \n-
    2255 } else {
    \n-
    2256 a = nullptr;
    \n-
    2257 }
    \n-
    2258 }
    \n-
    2259
    \n-\n-
    2266 {
    \n-
    2267 if (build_mode != implicit)
    \n-
    2268 DUNE_THROW(InvalidStateException,"implicit_allocate() may only be called in implicit build mode");
    \n-
    2269 if (ready != notAllocated)
    \n-
    2270 DUNE_THROW(InvalidStateException,"memory has already been allocated");
    \n-
    2271
    \n-
    2272 // check to make sure the user has actually set the parameters
    \n-
    2273 if (compressionBufferSize_ < 0)
    \n-
    2274 DUNE_THROW(InvalidStateException,"You have to set the implicit build mode parameters before starting to build the matrix");
    \n-
    2275 //calculate size of overflow region, add buffer for row sort!
    \n-\n-
    2277 allocationSize_ = _n*avg + osize;
    \n-
    2278
    \n-
    2279 allocate(_n, _m, allocationSize_,true,true);
    \n-
    2280
    \n-
    2281 //set row pointers correctly
    \n-
    2282 size_type* jptr = j_.get() + osize;
    \n-
    2283 B* aptr = a + osize;
    \n-
    2284 for (size_type i=0; i<n; i++)
    \n-
    2285 {
    \n-
    2286 r[i].set(0,aptr,jptr);
    \n-
    2287 jptr = jptr + avg;
    \n-
    2288 aptr = aptr + avg;
    \n-
    2289 }
    \n-
    2290
    \n-
    2291 ready = building;
    \n-
    2292 }
    \n-
    2293 };
    \n-
    2294
    \n-
    2295
    \n-
    2296 template<class B, class A>
    \n-
    2297 struct FieldTraits< BCRSMatrix<B, A> >
    \n-
    2298 {
    \n-\n-
    2300 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    2301 };
    \n-
    2302
    \n-
    2305} // end namespace
    \n-
    2306
    \n-
    2307#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Some handy generic functions for ISTL matrices.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    1633 //restart: exchange first and last stored values
    \n+
    1634 cycle(Ad,d,ddotAd,i_bounded);
    \n+
    1635 }
    \n+
    1636
    \n+
    1637 //correct i which is wrong if convergence was not achieved.
    \n+
    1638 i=std::min(_maxit,i);
    \n+
    1639
    \n+
    1640 _prec->post(x); // postprocess preconditioner
    \n+
    1641 }
    \n+
    1642
    \n+
    1643 private:
    \n+
    1644 //This function is called every iteration to orthogonalize against the last search directions
    \n+
    1645 virtual void orthogonalizations(const int& i_bounded,const std::vector<X>& Ad, const X& w, const std::vector<field_type,ReboundAllocatorType<X,field_type>>& ddotAd,std::vector<X>& d) {
    \n+
    1646 // The RestartedFCGSolver uses only values with lower array index;
    \n+
    1647 for (int k = 0; k < i_bounded; k++) {
    \n+
    1648 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= <<Ad[k],w>/<d[k],Ad[k]>>d[k]
    \n+
    1649 }
    \n+
    1650 }
    \n+
    1651
    \n+
    1652 // This function is called every mmax iterations to handle limited array sizes.
    \n+
    1653 virtual void cycle(std::vector<X>& Ad,std::vector<X>& d,std::vector<field_type,ReboundAllocatorType<X,field_type> >& ddotAd,int& i_bounded) {
    \n+
    1654 // Reset loop index and exchange the first and last arrays
    \n+
    1655 i_bounded = 1;
    \n+
    1656 std::swap(Ad[0], Ad[_mmax]);
    \n+
    1657 std::swap(d[0], d[_mmax]);
    \n+
    1658 std::swap(ddotAd[0], ddotAd[_mmax]);
    \n+
    1659 }
    \n+
    1660
    \n+
    1661 protected:
    \n+\n+
    1663 using IterativeSolver<X,X>::_op;
    \n+
    1664 using IterativeSolver<X,X>::_prec;
    \n+
    1665 using IterativeSolver<X,X>::_sp;
    \n+
    1666 using IterativeSolver<X,X>::_reduction;
    \n+
    1667 using IterativeSolver<X,X>::_maxit;
    \n+
    1668 using IterativeSolver<X,X>::_verbose;
    \n+\n+
    1670 };
    \n+
    1671 DUNE_REGISTER_ITERATIVE_SOLVER("restartedfcgsolver", defaultIterativeSolverCreator<Dune::RestartedFCGSolver>());
    \n+
    1672
    \n+
    1679 template<class X>
    \n+\n+
    1681 public:
    \n+\n+
    1683 using typename RestartedFCGSolver<X>::range_type;
    \n+
    1684 using typename RestartedFCGSolver<X>::field_type;
    \n+
    1685 using typename RestartedFCGSolver<X>::real_type;
    \n+
    1686
    \n+
    1687 // copy base class constructors
    \n+\n+
    1689
    \n+
    1690 // don't shadow four-argument version of apply defined in the base class
    \n+\n+
    1692
    \n+
    1693 // just a minor part of the RestartedFCGSolver apply method will be modified
    \n+
    1694 virtual void apply (X& x, X& b, InverseOperatorResult& res) override {
    \n+
    1695 // reset limiter of orthogonalization loop
    \n+
    1696 _k_limit = 0;
    \n+
    1697 this->RestartedFCGSolver<X>::apply(x,b,res);
    \n+
    1698 };
    \n+
    1699
    \n+
    1700 private:
    \n+
    1701 // This function is called every iteration to orthogonalize against the last search directions.
    \n+
    1702 virtual void orthogonalizations(const int& i_bounded,const std::vector<X>& Ad, const X& w, const std::vector<field_type,ReboundAllocatorType<X,field_type>>& ddotAd,std::vector<X>& d) override {
    \n+
    1703 // This FCGSolver uses values with higher array indexes too, if existent.
    \n+
    1704 for (int k = 0; k < _k_limit; k++) {
    \n+
    1705 if(i_bounded!=k)
    \n+
    1706 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= <<Ad[k],w>/<d[k],Ad[k]>>d[k]
    \n+
    1707 }
    \n+
    1708 // The loop limit increase, if array is not completely filled.
    \n+
    1709 if(_k_limit<=i_bounded)
    \n+
    1710 _k_limit++;
    \n+
    1711
    \n+
    1712 };
    \n+
    1713
    \n+
    1714 // This function is called every mmax iterations to handle limited array sizes.
    \n+
    1715 virtual void cycle(std::vector<X>& Ad, [[maybe_unused]] std::vector<X>& d, [[maybe_unused]] std::vector<field_type,ReboundAllocatorType<X,field_type> >& ddotAd,int& i_bounded) override {
    \n+
    1716 // Only the loop index i_bounded return to 0, if it reached mmax.
    \n+
    1717 i_bounded = 0;
    \n+
    1718 // Now all arrays are filled and the loop in void orthogonalizations can use the whole arrays.
    \n+
    1719 _k_limit = Ad.size();
    \n+
    1720 };
    \n+
    1721
    \n+
    1722 int _k_limit = 0;
    \n+
    1723
    \n+
    1724 protected:
    \n+\n+
    1726 using RestartedFCGSolver<X>::_op;
    \n+\n+
    1728 using RestartedFCGSolver<X>::_sp;
    \n+\n+\n+\n+
    1732 };
    \n+
    1733 DUNE_REGISTER_ITERATIVE_SOLVER("completefcgsolver", defaultIterativeSolverCreator<Dune::CompleteFCGSolver>());
    \n+
    1735} // end namespace
    \n+
    1736
    \n+
    1737#endif
    \n+
    Define base class for scalar product and norm.
    \n+\n+
    Define general, extensible interface for inverse operators.
    \n+
    Implementation of the BCRSMatrix class.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+\n+\n+\n+\n+
    DUNE_REGISTER_ITERATIVE_SOLVER("loopsolver", defaultIterativeSolverCreator< Dune::LoopSolver >())
    \n
    Definition: allocator.hh:11
    \n
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    Definition: matrixutils.hh:211
    \n-
    Statistics about compression achieved in implicit mode.
    Definition: bcrsmatrix.hh:88
    \n-
    size_type overflow_total
    total number of elements written to the overflow area during construction.
    Definition: bcrsmatrix.hh:94
    \n-
    size_type maximum
    maximum number of non-zeroes per row.
    Definition: bcrsmatrix.hh:92
    \n-
    double avg
    average number of non-zeroes per row.
    Definition: bcrsmatrix.hh:90
    \n-
    double mem_ratio
    fraction of wasted memory resulting from non-used overflow area.
    Definition: bcrsmatrix.hh:99
    \n-
    A wrapper for uniform access to the BCRSMatrix during and after the build stage in implicit build mod...
    Definition: bcrsmatrix.hh:117
    \n-
    Matrix::block_type block_type
    The block_type of the underlying matrix.
    Definition: bcrsmatrix.hh:125
    \n-
    ImplicitMatrixBuilder(Matrix &m)
    Creates an ImplicitMatrixBuilder for matrix m.
    Definition: bcrsmatrix.hh:170
    \n-
    M_ Matrix
    The underlying matrix.
    Definition: bcrsmatrix.hh:122
    \n-
    ImplicitMatrixBuilder(Matrix &m, size_type rows, size_type cols, size_type avg_cols_per_row, double overflow_fraction)
    Sets up matrix m for implicit construction using the given parameters and creates an ImplicitBmatrixu...
    Definition: bcrsmatrix.hh:194
    \n-
    size_type M() const
    The number of columns in the matrix.
    Definition: bcrsmatrix.hh:217
    \n-
    Matrix::size_type size_type
    The size_type of the underlying matrix.
    Definition: bcrsmatrix.hh:128
    \n-
    row_object operator[](size_type i) const
    Returns a proxy for entries in row i.
    Definition: bcrsmatrix.hh:205
    \n-
    size_type N() const
    The number of rows in the matrix.
    Definition: bcrsmatrix.hh:211
    \n-
    Proxy row object for entry access.
    Definition: bcrsmatrix.hh:137
    \n-
    block_type & operator[](size_type j) const
    Returns entry in column j.
    Definition: bcrsmatrix.hh:142
    \n+
    typename std::allocator_traits< typename AllocatorTraits< T >::type >::template rebind_alloc< X > ReboundAllocatorType
    Definition: allocator.hh:37
    \n+
    std::enable_if_t<!is_complex< T >::value, T > conj(const T &r)
    Definition: matrixmarket.hh:733
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bcrsmatrix.hh:488
    \n-
    std::allocator_traits< A >::template rebind_alloc< row_type > rowAllocator_
    Definition: bcrsmatrix.hh:2025
    \n-
    bool exists(size_type i, size_type j) const
    return true if (i,j) is in pattern
    Definition: bcrsmatrix.hh:2007
    \n-
    BuildStage buildStage() const
    The current build stage of the matrix.
    Definition: bcrsmatrix.hh:1993
    \n-
    Iterator begin()
    Get iterator to first row.
    Definition: bcrsmatrix.hh:675
    \n-
    friend class CreateIterator
    allow CreateIterator to access internal data
    Definition: bcrsmatrix.hh:1094
    \n-
    void copyWindowStructure(const BCRSMatrix &Mat)
    Copy the window structure from another matrix.
    Definition: bcrsmatrix.hh:2122
    \n-
    B & entry(size_type row, size_type col)
    Returns reference to entry (row,col) of the matrix.
    Definition: bcrsmatrix.hh:1296
    \n-
    void mmhv(const X &x, Y &y) const
    y -= A^H x
    Definition: bcrsmatrix.hh:1812
    \n-
    void usmhv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^H x
    Definition: bcrsmatrix.hh:1835
    \n-
    void umtv(const X &x, Y &y) const
    y += A^T x
    Definition: bcrsmatrix.hh:1722
    \n-
    double compressionBufferSize_
    Definition: bcrsmatrix.hh:2047
    \n-
    size_type m
    Definition: bcrsmatrix.hh:2031
    \n-
    RealRowIterator< const row_type > const_iterator
    The const iterator over the matrix rows.
    Definition: bcrsmatrix.hh:707
    \n-
    static constexpr unsigned int blocklevel
    increment block level counter
    Definition: bcrsmatrix.hh:507
    \n-
    void allocate(size_type rows, size_type columns, size_type allocationSize, bool allocateRows, bool allocate_data)
    Allocate memory for the matrix structure.
    Definition: bcrsmatrix.hh:2205
    \n-
    BCRSMatrix & axpy(field_type alpha, const BCRSMatrix &b)
    Add the scaled entries of another matrix to this one.
    Definition: bcrsmatrix.hh:1592
    \n-
    FieldTraits< ft >::real_type infinity_norm_real() const
    simplified infinity norm (uses Manhattan norm for complex values)
    Definition: bcrsmatrix.hh:1905
    \n-
    ~BCRSMatrix()
    destructor
    Definition: bcrsmatrix.hh:824
    \n-
    void allocateData()
    Definition: bcrsmatrix.hh:2246
    \n-
    void deallocate(bool deallocateRows=true)
    deallocate memory of the matrix.
    Definition: bcrsmatrix.hh:2139
    \n-
    Iterator RowIterator
    rename the iterators for easier access
    Definition: bcrsmatrix.hh:701
    \n-
    row_type & operator[](size_type i)
    random access to the rows
    Definition: bcrsmatrix.hh:549
    \n-
    BCRSMatrix()
    an empty matrix
    Definition: bcrsmatrix.hh:749
    \n-
    void endrowsizes()
    indicate that size of all rows is defined
    Definition: bcrsmatrix.hh:1149
    \n-
    void incrementrowsize(size_type i, size_type s=1)
    increment size of row i by s (1 by default)
    Definition: bcrsmatrix.hh:1138
    \n-
    void mtv(const X &x, Y &y) const
    y = A^T x
    Definition: bcrsmatrix.hh:1707
    \n-
    void umhv(const X &x, Y &y) const
    y += A^H x
    Definition: bcrsmatrix.hh:1789
    \n-
    size_type nonzeroes() const
    number of blocks that are stored (the number of blocks that possibly are nonzero)
    Definition: bcrsmatrix.hh:1984
    \n-
    size_type allocationSize_
    Definition: bcrsmatrix.hh:2033
    \n-
    ConstIterator ConstRowIterator
    rename the const row iterator for easier access
    Definition: bcrsmatrix.hh:738
    \n-
    BuildStage ready
    Definition: bcrsmatrix.hh:2020
    \n-
    BuildMode build_mode
    Definition: bcrsmatrix.hh:2019
    \n-
    void setrowsize(size_type i, size_type s)
    Set number of indices in row i to s.
    Definition: bcrsmatrix.hh:1117
    \n-
    RealRowIterator< row_type > Iterator
    Definition: bcrsmatrix.hh:672
    \n-
    size_type nnz_
    Definition: bcrsmatrix.hh:2032
    \n-
    BCRSMatrix & operator*=(const field_type &k)
    vector space multiplication with scalar
    Definition: bcrsmatrix.hh:1484
    \n-
    std::allocator_traits< A >::template rebind_alloc< size_type > sizeAllocator_
    Definition: bcrsmatrix.hh:2027
    \n-
    RealRowIterator< row_type > iterator
    The iterator over the (mutable matrix rows.
    Definition: bcrsmatrix.hh:671
    \n-
    void usmtv(const field_type &alpha, const X &x, Y &y) const
    y += alpha A^T x
    Definition: bcrsmatrix.hh:1766
    \n-
    ConstIterator beforeBegin() const
    Definition: bcrsmatrix.hh:732
    \n-
    RealRowIterator< const row_type > ConstIterator
    Definition: bcrsmatrix.hh:708
    \n-
    Iterator beforeBegin()
    Definition: bcrsmatrix.hh:695
    \n-
    B * a
    Definition: bcrsmatrix.hh:2040
    \n-
    BuildMode
    we support two modes
    Definition: bcrsmatrix.hh:510
    \n-
    @ implicit
    Build entries randomly with an educated guess for the number of entries per row.
    Definition: bcrsmatrix.hh:539
    \n-
    @ unknown
    Build mode not set!
    Definition: bcrsmatrix.hh:543
    \n-
    @ random
    Build entries randomly.
    Definition: bcrsmatrix.hh:530
    \n
    @ row_wise
    Build in a row-wise manner.
    Definition: bcrsmatrix.hh:521
    \n-
    BCRSMatrix(size_type _n, size_type _m, size_type _nnz, BuildMode bm)
    matrix with known number of nonzeroes
    Definition: bcrsmatrix.hh:756
    \n-
    ::Dune::CompressionStatistics< size_type > CompressionStatistics
    The type for the statistics object returned by compress()
    Definition: bcrsmatrix.hh:503
    \n-
    BCRSMatrix & operator-=(const BCRSMatrix &b)
    Subtract the entries of another matrix from this one.
    Definition: bcrsmatrix.hh:1567
    \n-
    BCRSMatrix(const BCRSMatrix &Mat)
    copy constructor
    Definition: bcrsmatrix.hh:805
    \n-
    Iterator end()
    Get iterator to one beyond last row.
    Definition: bcrsmatrix.hh:681
    \n-
    row_type * r
    Definition: bcrsmatrix.hh:2037
    \n-
    void setIndices(size_type row, It begin, It end)
    Set all column indices for row from the given iterator range.
    Definition: bcrsmatrix.hh:1234
    \n-
    void addindex(size_type row, size_type col)
    add index (row,col) to the matrix
    Definition: bcrsmatrix.hh:1191
    \n-
    std::map< std::pair< size_type, size_type >, B > OverflowType
    Definition: bcrsmatrix.hh:2049
    \n-
    row_type::Iterator ColIterator
    Iterator for the entries of each row.
    Definition: bcrsmatrix.hh:704
    \n-
    FieldTraits< field_type >::real_type frobenius_norm() const
    frobenius norm: sqrt(sum over squared values of entries)
    Definition: bcrsmatrix.hh:1877
    \n-
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n-
    BCRSMatrix & operator/=(const field_type &k)
    vector space division by scalar
    Definition: bcrsmatrix.hh:1512
    \n-
    OverflowType overflow
    Definition: bcrsmatrix.hh:2050
    \n-
    BCRSMatrix & operator+=(const BCRSMatrix &b)
    Add the entries of another matrix to this one.
    Definition: bcrsmatrix.hh:1545
    \n-
    BCRSMatrix(size_type _n, size_type _m, size_type _avg, double compressionBufferSize, BuildMode bm)
    construct matrix with a known average number of entries per row
    Definition: bcrsmatrix.hh:784
    \n
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: bcrsmatrix.hh:1103
    \n-
    FieldTraits< field_type >::real_type frobenius_norm2() const
    square of frobenius norm, need for block recursion
    Definition: bcrsmatrix.hh:1860
    \n-
    Iterator beforeEnd()
    Definition: bcrsmatrix.hh:688
    \n-
    row_type::ConstIterator ConstColIterator
    Const iterator to the entries of a row.
    Definition: bcrsmatrix.hh:741
    \n-
    void usmv(F &&alpha, const X &x, Y &y) const
    y += alpha A x
    Definition: bcrsmatrix.hh:1684
    \n-
    size_type getrowsize(size_type i) const
    get current number of indices in row i
    Definition: bcrsmatrix.hh:1128
    \n-
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n-
    size_type n
    Definition: bcrsmatrix.hh:2030
    \n-
    Imp::CompressedBlockVectorWindow< B, A > row_type
    implement row_type with compressed vector
    Definition: bcrsmatrix.hh:497
    \n
    CreateIterator createbegin()
    get initial create iterator
    Definition: bcrsmatrix.hh:1097
    \n-
    BuildStage
    Definition: bcrsmatrix.hh:469
    \n-
    @ rowSizesBuilt
    The row sizes of the matrix are known.
    Definition: bcrsmatrix.hh:480
    \n-
    @ built
    The matrix structure is fully built.
    Definition: bcrsmatrix.hh:482
    \n-
    @ notbuilt
    Matrix is not built at all, no memory has been allocated, build mode and size can still be set.
    Definition: bcrsmatrix.hh:471
    \n-
    @ notAllocated
    Matrix is not built at all, no memory has been allocated, build mode and size can still be set.
    Definition: bcrsmatrix.hh:473
    \n-
    @ building
    Matrix is currently being built, some memory has been allocated, build mode and size are fixed.
    Definition: bcrsmatrix.hh:475
    \n-
    BuildMode buildMode() const
    The currently selected build mode of the matrix.
    Definition: bcrsmatrix.hh:1999
    \n-
    void mmv(const X &x, Y &y) const
    y -= A x
    Definition: bcrsmatrix.hh:1661
    \n-
    FieldTraits< ft >::real_type infinity_norm() const
    infinity norm (row sum norm, how to generalize for blocks?)
    Definition: bcrsmatrix.hh:1885
    \n-
    void mv(const X &x, Y &y) const
    y = A x
    Definition: bcrsmatrix.hh:1612
    \n-
    B block_type
    export the type representing the components
    Definition: bcrsmatrix.hh:491
    \n-
    void mmtv(const X &x, Y &y) const
    y -= A^T x
    Definition: bcrsmatrix.hh:1745
    \n-
    size_type avg
    Definition: bcrsmatrix.hh:2046
    \n-
    void umv(const X &x, Y &y) const
    y += A x
    Definition: bcrsmatrix.hh:1638
    \n-
    void implicit_allocate(size_type _n, size_type _m)
    organizes allocation implicit mode calculates correct array size to be allocated and sets the the win...
    Definition: bcrsmatrix.hh:2265
    \n-
    void setImplicitBuildModeParameters(size_type _avg, double compressionBufferSize)
    Set parameters needed for creation in implicit build mode.
    Definition: bcrsmatrix.hh:889
    \n-
    BCRSMatrix(size_type _n, size_type _m, BuildMode bm)
    matrix with unknown number of nonzeroes
    Definition: bcrsmatrix.hh:765
    \n-
    void endindices()
    indicate that all indices are defined, check consistency
    Definition: bcrsmatrix.hh:1248
    \n-
    CompressionStatistics compress()
    Finishes the buildstage in implicit mode.
    Definition: bcrsmatrix.hh:1360
    \n-
    void setDataPointers()
    Set data pointers for all rows.
    Definition: bcrsmatrix.hh:2103
    \n-
    std::allocator_traits< A >::template rebind_alloc< B > allocator_
    Definition: bcrsmatrix.hh:2023
    \n
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n-
    void setBuildMode(BuildMode bm)
    Sets the build mode of the matrix.
    Definition: bcrsmatrix.hh:833
    \n-
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n-
    std::shared_ptr< size_type > j_
    Definition: bcrsmatrix.hh:2043
    \n-
    void setWindowPointers(ConstRowIterator row)
    Definition: bcrsmatrix.hh:2052
    \n-
    BCRSMatrix & operator=(const BCRSMatrix &Mat)
    assignment
    Definition: bcrsmatrix.hh:911
    \n-
    void setColumnPointers(ConstRowIterator row)
    Copy row sizes from iterator range starting at row and set column index pointers for all rows.
    Definition: bcrsmatrix.hh:2077
    \n-
    ConstIterator end() const
    Get const iterator to one beyond last row.
    Definition: bcrsmatrix.hh:718
    \n-
    ConstIterator begin() const
    Get const iterator to first row.
    Definition: bcrsmatrix.hh:712
    \n-
    A allocator_type
    export the allocator type
    Definition: bcrsmatrix.hh:494
    \n-
    ConstIterator beforeEnd() const
    Definition: bcrsmatrix.hh:725
    \n-
    Iterator access to matrix rows
    Definition: bcrsmatrix.hh:579
    \n-
    RealRowIterator()
    empty constructor, use with care!
    Definition: bcrsmatrix.hh:596
    \n-
    bool equals(const RealRowIterator< ValueType > &other) const
    equality
    Definition: bcrsmatrix.hh:624
    \n-
    std::remove_const< T >::type ValueType
    The unqualified value type.
    Definition: bcrsmatrix.hh:583
    \n-
    RealRowIterator(const RealRowIterator< ValueType > &it)
    Definition: bcrsmatrix.hh:600
    \n-
    bool equals(const RealRowIterator< const ValueType > &other) const
    equality
    Definition: bcrsmatrix.hh:631
    \n-
    RealRowIterator(row_type *_p, size_type _i)
    constructor
    Definition: bcrsmatrix.hh:591
    \n-
    std::ptrdiff_t distanceTo(const RealRowIterator< const ValueType > &other) const
    Definition: bcrsmatrix.hh:617
    \n-
    size_type index() const
    return index
    Definition: bcrsmatrix.hh:606
    \n-
    std::ptrdiff_t distanceTo(const RealRowIterator< ValueType > &other) const
    Definition: bcrsmatrix.hh:611
    \n-
    Iterator class for sequential creation of blocks
    Definition: bcrsmatrix.hh:957
    \n-
    bool operator==(const CreateIterator &it) const
    equality
    Definition: bcrsmatrix.hh:1052
    \n-
    CreateIterator & operator++()
    prefix increment
    Definition: bcrsmatrix.hh:977
    \n-
    size_type index() const
    The number of the row that the iterator currently points to.
    Definition: bcrsmatrix.hh:1058
    \n-
    bool operator!=(const CreateIterator &it) const
    inequality
    Definition: bcrsmatrix.hh:1046
    \n-
    CreateIterator(BCRSMatrix &_Mat, size_type _i)
    constructor
    Definition: bcrsmatrix.hh:960
    \n-
    void insert(size_type j)
    put column index in row
    Definition: bcrsmatrix.hh:1064
    \n-
    bool contains(size_type j)
    return true if column index is in row
    Definition: bcrsmatrix.hh:1070
    \n-
    size_type size() const
    Get the current row size.
    Definition: bcrsmatrix.hh:1079
    \n-
    typename BCRSMatrix< B, A >::field_type field_type
    Definition: bcrsmatrix.hh:2299
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: bcrsmatrix.hh:2300
    \n-
    Error specific to BCRSMatrix.
    Definition: istlexception.hh:24
    \n-
    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted.
    Definition: istlexception.hh:37
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n-
    T block_type
    Export the type representing the components.
    Definition: matrix.hh:568
    \n-
    Definition: matrixutils.hh:538
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    Wrapper to use a range of ARPACK++ eigenvalue solvers.
    Definition: arpackpp.hh:245
    \n+
    void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:289
    \n+
    void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:391
    \n+
    Thrown when a solver aborts due to some problem.
    Definition: istlexception.hh:46
    \n+\n+\n+
    Base class for scalar product and norm computation.
    Definition: scalarproducts.hh:52
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    double condition_estimate
    Estimate of condition number.
    Definition: solver.hh:79
    \n+
    void clear()
    Resets all data.
    Definition: solver.hh:56
    \n+
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n+
    Simd::Scalar< real_type > scalar_real_type
    scalar type underlying the field_type
    Definition: solver.hh:114
    \n+
    Y range_type
    Type of the range of the operator to be inverted.
    Definition: solver.hh:105
    \n+
    X domain_type
    Type of the domain of the operator to be inverted.
    Definition: solver.hh:102
    \n+
    X::field_type field_type
    The field type of the operator.
    Definition: solver.hh:108
    \n+
    FieldTraits< field_type >::real_type real_type
    The real type of the field type (is the same if using real numbers, but differs for std::complex)
    Definition: solver.hh:111
    \n+
    Base class for all implementations of iterative solvers.
    Definition: solver.hh:203
    \n+
    std::shared_ptr< const ScalarProduct< X > > _sp
    Definition: solver.hh:506
    \n+
    IterativeSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose)
    General constructor to initialize an iterative solver.
    Definition: solver.hh:230
    \n+
    std::shared_ptr< const LinearOperator< X, X > > _op
    Definition: solver.hh:504
    \n+
    int _maxit
    Definition: solver.hh:508
    \n+
    int _verbose
    Definition: solver.hh:509
    \n+
    scalar_real_type _reduction
    Definition: solver.hh:507
    \n+
    std::shared_ptr< Preconditioner< X, X > > _prec
    Definition: solver.hh:505
    \n+
    Preconditioned loop solver.
    Definition: solvers.hh:59
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator,.
    Definition: solvers.hh:73
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:116
    \n+
    gradient method
    Definition: solvers.hh:124
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:142
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:187
    \n+
    conjugate gradient method
    Definition: solvers.hh:193
    \n+
    CGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:256
    \n+
    static constexpr bool enableConditionEstimate
    Definition: solvers.hh:208
    \n+
    CGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:239
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:279
    \n+
    CGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)
    Constructor to initialize a CG solver.
    Definition: solvers.hh:222
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:412
    \n+
    Bi-conjugate Gradient Stabilized (BiCG-STAB)
    Definition: solvers.hh:419
    \n+
    typename IterativeSolver< X, X >::template Iteration< CountType > Iteration
    Definition: solvers.hh:598
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:439
    \n+
    Minimal Residual Method (MINRES)
    Definition: solvers.hh:609
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:627
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:808
    \n+
    implements the Generalized Minimal Residual (GMRes) method
    Definition: solvers.hh:827
    \n+
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solvers.hh:878
    \n+
    std::enable_if<!std::is_same< field_type, real_type >::value, T >::type conjugate(const T &t)
    Definition: solvers.hh:1067
    \n+
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Definition: solvers.hh:883
    \n+
    void update(X &w, int i, const std::vector< std::vector< field_type, fAlloc > > &H, const std::vector< field_type, fAlloc > &s, const std::vector< X > &v)
    Definition: solvers.hh:1039
    \n+
    std::enable_if< std::is_same< field_type, real_type >::value, T >::type conjugate(const T &t)
    Definition: solvers.hh:1062
    \n+
    ReboundAllocatorType< X, field_type > fAlloc
    field_type Allocator retrieved from domain type
    Definition: solvers.hh:838
    \n+
    int _restart
    Definition: solvers.hh:1120
    \n+
    ReboundAllocatorType< X, real_type > rAlloc
    real_type Allocator retrieved from domain type
    Definition: solvers.hh:840
    \n+
    virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:923
    \n+
    RestartedGMResSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:850
    \n+
    RestartedGMResSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X > &sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:861
    \n+
    void generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    Definition: solvers.hh:1073
    \n+
    RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, Y > > prec, scalar_real_type reduction, int restart, int maxit, int verbose)
    Set up RestartedGMResSolver solver.
    Definition: solvers.hh:894
    \n+
    virtual void apply(X &x, Y &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:910
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:1119
    \n+
    void applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs, field_type &sn)
    Definition: solvers.hh:1106
    \n+
    implements the Flexible Generalized Minimal Residual (FGMRes) method (right preconditioned)
    Definition: solvers.hh:1139
    \n+
    void apply(X &x, Y &b, double reduction, InverseOperatorResult &res) override
    Apply inverse operator.
    Definition: solvers.hh:1169
    \n+
    Generalized preconditioned conjugate gradient solver.
    Definition: solvers.hh:1307
    \n+
    GeneralizedPCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1343
    \n+
    GeneralizedPCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1331
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:1391
    \n+
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Constructor.
    Definition: solvers.hh:1361
    \n+
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)
    Set up nonlinear preconditioned conjugate gradient solver.
    Definition: solvers.hh:1377
    \n+
    GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)
    Definition: solvers.hh:1366
    \n+
    Accelerated flexible conjugate gradient method.
    Definition: solvers.hh:1501
    \n+
    RestartedFCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1519
    \n+
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)
    Constructor.
    Definition: solvers.hh:1559
    \n+
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1539
    \n+
    int _mmax
    Definition: solvers.hh:1662
    \n+
    RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)
    Definition: solvers.hh:1565
    \n+
    typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration
    Definition: solvers.hh:1669
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res)
    Apply inverse operator.
    Definition: solvers.hh:1584
    \n+
    RestartedFCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)
    Constructor to initialize a RestartedFCG solver.
    Definition: solvers.hh:1529
    \n+
    Complete flexible conjugate gradient method.
    Definition: solvers.hh:1680
    \n+
    virtual void apply(X &x, X &b, InverseOperatorResult &res) override
    Apply inverse operator.
    Definition: solvers.hh:1694
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,2393 +4,1937 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-bcrsmatrix.hh\n+solvers.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n 5\n- 6#ifndef DUNE_ISTL_BCRSMATRIX_HH\n- 7#define DUNE_ISTL_BCRSMATRIX_HH\n+ 6#ifndef DUNE_ISTL_SOLVERS_HH\n+ 7#define DUNE_ISTL_SOLVERS_HH\n 8\n- 9#include \n- 10#include \n- 11#include \n+ 9#include \n+ 10#include \n+ 11#include \n 12#include \n- 13#include \n- 14#include \n+ 13#include \n+ 14#include \n 15#include \n- 16#include \n- 17#include \n- 18\n- 19#include \"istlexception.hh\"\n- 20#include \"bvector.hh\"\n- 21#include \"matrixutils.hh\"\n- 22#include \n- 23#include \n- 24#include \n- 25#include \n- 26#include \n- 27#include \n- 28\n- 29#include \n- 30\n- 35namespace Dune {\n- 36\n- 76 template\n- 77 struct MatrixDimension;\n- 78\n+ 16\n+ 17#include \n+ 18#include \n+ 19#include \n+ 20#include \n+ 21#include \n+ 22#include \n+ 23\n+ 24#include \n+ 25#include \n+ 26#include \n+ 27#include \n+ 28#include \n+ 29#include \n+ 30#include \n+ 31#include \n+ 32#include \n+ 33\n+ 34namespace Dune {\n+ 46 //=====================================================================\n+ 47 // Implementation of this interface\n+ 48 //=====================================================================\n+ 49\n+ 58 template\n+59 class LoopSolver : public IterativeSolver {\n+ 60 public:\n+ 61 using typename IterativeSolver::domain_type;\n+ 62 using typename IterativeSolver::range_type;\n+ 63 using typename IterativeSolver::field_type;\n+ 64 using typename IterativeSolver::real_type;\n+ 65\n+ 66 // copy base class constructors\n+ 67 using IterativeSolver::IterativeSolver;\n+ 68\n+ 69 // don't shadow four-argument version of apply defined in the base class\n+ 70 using IterativeSolver::apply;\n+ 71\n+73 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 74 {\n+ 75 Iteration iteration(*this, res);\n+ 76 _prec->pre(x,b);\n+ 77\n+ 78 // overwrite b with defect\n+ 79 _op->applyscaleadd(-1,x,b);\n 80\n- 86 template\n-87 struct CompressionStatistics\n- 88 {\n-90 double avg;\n-92 size_type maximum;\n-94 size_type overflow_total;\n- 96\n-99 double mem_ratio;\n- 100 };\n- 101\n- 103\n- 115 template\n-116 class ImplicitMatrixBuilder\n- 117 {\n- 118\n- 119 public:\n+ 81 // compute norm, \\todo parallelization\n+ 82 real_type def = _sp->norm(b);\n+ 83 if(iteration.step(0, def)){\n+ 84 _prec->post(x);\n+ 85 return;\n+ 86 }\n+ 87 // prepare preconditioner\n+ 88\n+ 89 // allocate correction vector\n+ 90 X v(x);\n+ 91\n+ 92 // iteration loop\n+ 93 int i=1;\n+ 94 for ( ; i<=_maxit; i++ )\n+ 95 {\n+ 96 v = 0; // clear correction\n+ 97 _prec->apply(v,b); // apply preconditioner\n+ 98 x += v; // update solution\n+ 99 _op->applyscaleadd(-1,v,b); // update defect\n+ 100 def=_sp->norm(b); // comp defect norm\n+ 101 if(iteration.step(i, def))\n+ 102 break;\n+ 103 }\n+ 104\n+ 105 // postprocess preconditioner\n+ 106 _prec->post(x);\n+ 107 }\n+ 108\n+ 109 protected:\n+ 110 using IterativeSolver::_op;\n+ 111 using IterativeSolver::_prec;\n+ 112 using IterativeSolver::_sp;\n+ 113 using IterativeSolver::_reduction;\n+ 114 using IterativeSolver::_maxit;\n+ 115 using IterativeSolver::_verbose;\n+116 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 117 };\n+118 DUNE_REGISTER_ITERATIVE_SOLVER(\"loopsolver\",\n+defaultIterativeSolverCreator());\n+ 119\n 120\n-122 typedef M_ Matrix;\n- 123\n-125 typedef typename Matrix::block_type block_type;\n- 126\n-128 typedef typename Matrix::size_type size_type;\n- 129\n- 131\n-136 class row_object\n- 137 {\n- 138\n- 139 public:\n- 140\n-142 block_type& operator[](size_type j) const\n+ 121 // all these solvers are taken from the SUMO library\n+ 123 template\n+124 class GradientSolver : public IterativeSolver {\n+ 125 public:\n+ 126 using typename IterativeSolver::domain_type;\n+ 127 using typename IterativeSolver::range_type;\n+ 128 using typename IterativeSolver::field_type;\n+ 129 using typename IterativeSolver::real_type;\n+ 130\n+ 131 // copy base class constructors\n+ 132 using IterativeSolver::IterativeSolver;\n+ 133\n+ 134 // don't shadow four-argument version of apply defined in the base class\n+ 135 using IterativeSolver::apply;\n+ 136\n+142 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n 143 {\n- 144 return _m.entry(_i,j);\n- 145 }\n+ 144 Iteration iteration(*this, res);\n+ 145 _prec->pre(x,b); // prepare preconditioner\n 146\n- 147#ifndef DOXYGEN\n+ 147 _op->applyscaleadd(-1,x,b); // overwrite b with defec\n 148\n- 149 row_object(Matrix& m, size_type i)\n- 150 : _m(m)\n- 151 , _i(i)\n- 152 {}\n- 153\n- 154#endif\n- 155\n- 156 private:\n+ 149 real_type def = _sp->norm(b); // compute norm\n+ 150 if(iteration.step(0, def)){\n+ 151 _prec->post(x);\n+ 152 return;\n+ 153 }\n+ 154\n+ 155 X p(x); // create local vectors\n+ 156 X q(b);\n 157\n- 158 Matrix& _m;\n-159 size_type _i;\n- 160\n- 161 };\n- 162\n- 164\n-170 ImplicitMatrixBuilder(Matrix& m)\n- 171 : _m(m)\n- 172 {\n- 173 if (m.buildMode() != Matrix::implicit)\n- 174 DUNE_THROW(BCRSMatrixError,\"You can only create an ImplicitBuilder for a\n-matrix in implicit build mode\");\n- 175 if (m.buildStage() != Matrix::building)\n- 176 DUNE_THROW(BCRSMatrixError,\"You can only create an ImplicitBuilder for a\n-matrix with set size that has not been compressed() yet\");\n- 177 }\n- 178\n- 180\n-194 ImplicitMatrixBuilder(Matrix& m, size_type rows, size_type cols, size_type\n-avg_cols_per_row, double overflow_fraction)\n- 195 : _m(m)\n- 196 {\n- 197 if (m.buildStage() != Matrix::notAllocated)\n- 198 DUNE_THROW(BCRSMatrixError,\"You can only set up a matrix for this\n-ImplicitBuilder if it has no memory allocated yet\");\n- 199 m.setBuildMode(Matrix::implicit);\n- 200 m.setImplicitBuildModeParameters(avg_cols_per_row,overflow_fraction);\n- 201 m.setSize(rows,cols);\n- 202 }\n- 203\n-205 row_object operator[](size_type i) const\n- 206 {\n- 207 return row_object(_m,i);\n- 208 }\n+ 158 int i=1; // loop variables\n+ 159 field_type lambda;\n+ 160 for ( ; i<=_maxit; i++ )\n+ 161 {\n+ 162 p = 0; // clear correction\n+ 163 _prec->apply(p,b); // apply preconditioner\n+ 164 _op->apply(p,q); // q=Ap\n+ 165 auto alpha = _sp->dot(q,p);\n+ 166 lambda = Simd::cond(def==field_type(0.),\n+ 167 field_type(0.), // no need for minimization if def is already 0\n+ 168 _sp->dot(p,b)/alpha); // minimization\n+ 169 x.axpy(lambda,p); // update solution\n+ 170 b.axpy(-lambda,q); // update defect\n+ 171\n+ 172 def =_sp->norm(b); // comp defect norm\n+ 173 if(iteration.step(i, def))\n+ 174 break;\n+ 175 }\n+ 176 // postprocess preconditioner\n+ 177 _prec->post(x);\n+ 178 }\n+ 179\n+ 180 protected:\n+ 181 using IterativeSolver::_op;\n+ 182 using IterativeSolver::_prec;\n+ 183 using IterativeSolver::_sp;\n+ 184 using IterativeSolver::_reduction;\n+ 185 using IterativeSolver::_maxit;\n+ 186 using IterativeSolver::_verbose;\n+187 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 188 };\n+189 DUNE_REGISTER_ITERATIVE_SOLVER(\"gradientsolver\",\n+defaultIterativeSolverCreator());\n+ 190\n+ 192 template\n+193 class CGSolver : public IterativeSolver {\n+ 194 public:\n+ 195 using typename IterativeSolver::domain_type;\n+ 196 using typename IterativeSolver::range_type;\n+ 197 using typename IterativeSolver::field_type;\n+ 198 using typename IterativeSolver::real_type;\n+ 199\n+ 200 // copy base class constructors\n+ 201 using IterativeSolver::IterativeSolver;\n+ 202\n+ 203 private:\n+ 204 using typename IterativeSolver::scalar_real_type;\n+ 205\n+ 206 protected:\n+ 207\n+208 static constexpr bool enableConditionEstimate = (std::\n+is_same_v || std::is_same_v);\n 209\n-211 size_type N() const\n- 212 {\n- 213 return _m.N();\n- 214 }\n- 215\n-217 size_type M() const\n- 218 {\n- 219 return _m.M();\n- 220 }\n- 221\n- 222 private:\n- 223\n- 224 Matrix& _m;\n- 225\n- 226 };\n- 227\n- 464 template >\n-465 class BCRSMatrix\n- 466 {\n- 467 friend struct MatrixDimension;\n- 468 public:\n-469 enum BuildStage {\n-471 notbuilt=0,\n-473 notAllocated=0,\n-475 building=1,\n-480 rowSizesBuilt=2,\n- 482 built=3\n-483 };\n- 484\n- 485 //===== type definitions and constants\n- 486\n-488 using field_type = typename Imp::BlockTraits::field_type;\n- 489\n-491 typedef B block_type;\n- 492\n-494 typedef A allocator_type;\n- 495\n-497 typedef Imp::CompressedBlockVectorWindow row_type;\n- 498\n-500 typedef typename A::size_type size_type;\n- 501\n-503 typedef ::Dune::CompressionStatistics CompressionStatistics;\n+ 210 public:\n+ 211\n+ 212 // don't shadow four-argument version of apply defined in the base class\n+ 213 using IterativeSolver::apply;\n+ 214\n+222 CGSolver (const LinearOperator& op, Preconditioner& prec,\n+ 223 scalar_real_type reduction, int maxit, int verbose, bool\n+condition_estimate) : IterativeSolver(op, prec, reduction, maxit,\n+verbose),\n+ 224 condition_estimate_(condition_estimate)\n+ 225 {\n+ 226 if (condition_estimate && !enableConditionEstimate) {\n+ 227 condition_estimate_ = false;\n+ 228 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n+available for double and float field types!\" << std::endl;\n+ 229 }\n+ 230 }\n+ 231\n+239 CGSolver (const LinearOperator& op, const ScalarProduct& sp,\n+Preconditioner& prec,\n+ 240 scalar_real_type reduction, int maxit, int verbose, bool\n+condition_estimate) : IterativeSolver(op, sp, prec, reduction, maxit,\n+verbose),\n+ 241 condition_estimate_(condition_estimate)\n+ 242 {\n+ 243 if (condition_estimate && !(std::is_same::value || std::\n+is_same::value)) {\n+ 244 condition_estimate_ = false;\n+ 245 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n+available for double and float field types!\" << std::endl;\n+ 246 }\n+ 247 }\n+ 248\n+256 CGSolver (std::shared_ptr> op, std::\n+shared_ptr> sp,\n+ 257 std::shared_ptr> prec,\n+ 258 scalar_real_type reduction, int maxit, int verbose, bool\n+condition_estimate)\n+ 259 : IterativeSolver(op, sp, prec, reduction, maxit, verbose),\n+ 260 condition_estimate_(condition_estimate)\n+ 261 {\n+ 262 if (condition_estimate && !(std::is_same::value || std::\n+is_same::value)) {\n+ 263 condition_estimate_ = false;\n+ 264 std::cerr << \"WARNING: Condition estimate was disabled. It is only\n+available for double and float field types!\" << std::endl;\n+ 265 }\n+ 266 }\n+ 267\n+279 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 280 {\n+ 281 Iteration iteration(*this,res);\n+ 282 _prec->pre(x,b); // prepare preconditioner\n+ 283\n+ 284 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n+ 285\n+ 286 real_type def = _sp->norm(b); // compute norm\n+ 287 if(iteration.step(0, def)){\n+ 288 _prec->post(x);\n+ 289 return;\n+ 290 }\n+ 291\n+ 292 X p(x); // the search direction\n+ 293 X q(x); // a temporary vector\n+ 294\n+ 295 // Remember lambda and beta values for condition estimate\n+ 296 std::vector lambdas(0);\n+ 297 std::vector betas(0);\n+ 298\n+ 299 // some local variables\n+ 300 field_type rho,rholast,lambda,alpha,beta;\n+ 301\n+ 302 // determine initial search direction\n+ 303 p = 0; // clear correction\n+ 304 _prec->apply(p,b); // apply preconditioner\n+ 305 rholast = _sp->dot(p,b); // orthogonalization\n+ 306\n+ 307 // the loop\n+ 308 int i=1;\n+ 309 for ( ; i<=_maxit; i++ )\n+ 310 {\n+ 311 // minimize in given search direction p\n+ 312 _op->apply(p,q); // q=Ap\n+ 313 alpha = _sp->dot(p,q); // scalar product\n+ 314 lambda = Simd::cond(def==field_type(0.), field_type(0.), rholast/alpha); /\n+/ minimization\n+ 315 if constexpr (enableConditionEstimate)\n+ 316 if (condition_estimate_)\n+ 317 lambdas.push_back(std::real(lambda));\n+ 318 x.axpy(lambda,p); // update solution\n+ 319 b.axpy(-lambda,q); // update defect\n+ 320\n+ 321 // convergence test\n+ 322 def=_sp->norm(b); // comp defect norm\n+ 323 if(iteration.step(i, def))\n+ 324 break;\n+ 325\n+ 326 // determine new search direction\n+ 327 q = 0; // clear correction\n+ 328 _prec->apply(q,b); // apply preconditioner\n+ 329 rho = _sp->dot(q,b); // orthogonalization\n+ 330 beta = Simd::cond(def==field_type(0.), field_type(0.), rho/rholast); /\n+/ scaling factor\n+ 331 if constexpr (enableConditionEstimate)\n+ 332 if (condition_estimate_)\n+ 333 betas.push_back(std::real(beta));\n+ 334 p *= beta; // scale old search direction\n+ 335 p += q; // orthogonalization with correction\n+ 336 rholast = rho; // remember rho for recurrence\n+ 337 }\n+ 338\n+ 339 _prec->post(x); // postprocess preconditioner\n+ 340\n+ 341 if (condition_estimate_) {\n+ 342#if HAVE_ARPACKPP\n+ 343 if constexpr (enableConditionEstimate) {\n+ 344 using std::sqrt;\n+ 345\n+ 346 // Build T matrix which has extreme eigenvalues approximating\n+ 347 // those of the original system\n+ 348 // (see Y. Saad, Iterative methods for sparse linear systems)\n+ 349\n+ 350 COND_MAT T(i, i, COND_MAT::row_wise);\n+ 351\n+ 352 for (auto row = T.createbegin(); row != T.createend(); ++row) {\n+ 353 if (row.index() > 0)\n+ 354 row.insert(row.index()-1);\n+ 355 row.insert(row.index());\n+ 356 if (row.index() < T.N() - 1)\n+ 357 row.insert(row.index()+1);\n+ 358 }\n+ 359 for (int row = 0; row < i; ++row) {\n+ 360 if (row > 0) {\n+ 361 T[row][row-1] = sqrt(betas[row-1]) / lambdas[row-1];\n+ 362 }\n+ 363\n+ 364 T[row][row] = 1.0 / lambdas[row];\n+ 365 if (row > 0) {\n+ 366 T[row][row] += betas[row-1] / lambdas[row-1];\n+ 367 }\n+ 368\n+ 369 if (row < i - 1) {\n+ 370 T[row][row+1] = sqrt(betas[row]) / lambdas[row];\n+ 371 }\n+ 372 }\n+ 373\n+ 374 // Compute largest and smallest eigenvalue of T matrix and return as\n+estimate\n+ 375 Dune::ArPackPlusPlus_Algorithms arpack(T);\n+ 376\n+ 377 real_type eps = 0.0;\n+ 378 COND_VEC eigv;\n+ 379 real_type min_eigv, max_eigv;\n+ 380 arpack.computeSymMinMagnitude (eps, eigv, min_eigv);\n+ 381 arpack.computeSymMaxMagnitude (eps, eigv, max_eigv);\n+ 382\n+ 383 res.condition_estimate = max_eigv / min_eigv;\n+ 384\n+ 385 if (this->_verbose > 0) {\n+ 386 std::cout << \"Min eigv estimate: \" << Simd::io(min_eigv) << '\\n';\n+ 387 std::cout << \"Max eigv estimate: \" << Simd::io(max_eigv) << '\\n';\n+ 388 std::cout << \"Condition estimate: \"\n+ 389 << Simd::io(max_eigv / min_eigv) << std::endl;\n+ 390 }\n+ 391 }\n+ 392#else\n+ 393 std::cerr << \"WARNING: Condition estimate was requested. This requires\n+ARPACK, but ARPACK was not found!\" << std::endl;\n+ 394#endif\n+ 395 }\n+ 396 }\n+ 397\n+ 398 private:\n+ 399 bool condition_estimate_ = false;\n+ 400\n+ 401 // Matrix and vector types used for condition estimate\n+ 402 typedef Dune::BCRSMatrix > COND_MAT;\n+ 403 typedef Dune::BlockVector > COND_VEC;\n+ 404\n+ 405 protected:\n+ 406 using IterativeSolver::_op;\n+ 407 using IterativeSolver::_prec;\n+ 408 using IterativeSolver::_sp;\n+ 409 using IterativeSolver::_reduction;\n+ 410 using IterativeSolver::_maxit;\n+ 411 using IterativeSolver::_verbose;\n+412 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 413 };\n+414 DUNE_REGISTER_ITERATIVE_SOLVER(\"cgsolver\",\n+defaultIterativeSolverCreator());\n+ 415\n+ 416 // Ronald Kriemanns BiCG-STAB implementation from Sumo\n+ 418 template\n+419 class BiCGSTABSolver : public IterativeSolver {\n+ 420 public:\n+ 421 using typename IterativeSolver::domain_type;\n+ 422 using typename IterativeSolver::range_type;\n+ 423 using typename IterativeSolver::field_type;\n+ 424 using typename IterativeSolver::real_type;\n+ 425\n+ 426 // copy base class constructors\n+ 427 using IterativeSolver::IterativeSolver;\n+ 428\n+ 429 // don't shadow four-argument version of apply defined in the base class\n+ 430 using IterativeSolver::apply;\n+ 431\n+439 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 440 {\n+ 441 using std::abs;\n+ 442 const Simd::Scalar EPSILON=1e-80;\n+ 443 using std::abs;\n+ 444 double it;\n+ 445 field_type rho, rho_new, alpha, beta, h, omega;\n+ 446 real_type norm;\n+ 447\n+ 448 //\n+ 449 // get vectors and matrix\n+ 450 //\n+ 451 X& r=b;\n+ 452 X p(x);\n+ 453 X v(x);\n+ 454 X t(x);\n+ 455 X y(x);\n+ 456 X rt(x);\n+ 457\n+ 458 //\n+ 459 // begin iteration\n+ 460 //\n+ 461\n+ 462 // r = r - Ax; rt = r\n+ 463 Iteration iteration(*this,res);\n+ 464 _prec->pre(x,r); // prepare preconditioner\n+ 465\n+ 466 _op->applyscaleadd(-1,x,r); // overwrite b with defect\n+ 467\n+ 468 rt=r;\n+ 469\n+ 470 norm = _sp->norm(r);\n+ 471 if(iteration.step(0, norm)){\n+ 472 _prec->post(x);\n+ 473 return;\n+ 474 }\n+ 475 p=0;\n+ 476 v=0;\n+ 477\n+ 478 rho = 1;\n+ 479 alpha = 1;\n+ 480 omega = 1;\n+ 481\n+ 482 //\n+ 483 // iteration\n+ 484 //\n+ 485\n+ 486 for (it = 0.5; it < _maxit; it+=.5)\n+ 487 {\n+ 488 //\n+ 489 // preprocess, set vecsizes etc.\n+ 490 //\n+ 491\n+ 492 // rho_new = < rt , r >\n+ 493 rho_new = _sp->dot(rt,r);\n+ 494\n+ 495 // look if breakdown occurred\n+ 496 if (Simd::allTrue(abs(rho) <= EPSILON))\n+ 497 DUNE_THROW(SolverAbort,\"breakdown in BiCGSTAB - rho \"\n+ 498 << Simd::io(rho) << \" <= EPSILON \" << EPSILON\n+ 499 << \" after \" << it << \" iterations\");\n+ 500 if (Simd::allTrue(abs(omega) <= EPSILON))\n+ 501 DUNE_THROW(SolverAbort,\"breakdown in BiCGSTAB - omega \"\n+ 502 << Simd::io(omega) << \" <= EPSILON \" << EPSILON\n+ 503 << \" after \" << it << \" iterations\");\n 504\n- 506 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-507 static constexpr unsigned int blocklevel = blockLevel()+1;\n- 508\n-510 enum BuildMode {\n-521 row_wise,\n-530 random,\n-539 implicit,\n- 543 unknown\n-544 };\n- 545\n- 546 //===== random access interface to rows of the matrix\n+ 505\n+ 506 if (it<1)\n+ 507 p = r;\n+ 508 else\n+ 509 {\n+ 510 beta = Simd::cond(norm==field_type(0.),\n+ 511 field_type(0.), // no need for orthogonalization if norm is already 0\n+ 512 ( rho_new / rho ) * ( alpha / omega ));\n+ 513 p.axpy(-omega,v); // p = r + beta (p - omega*v)\n+ 514 p *= beta;\n+ 515 p += r;\n+ 516 }\n+ 517\n+ 518 // y = W^-1 * p\n+ 519 y = 0;\n+ 520 _prec->apply(y,p); // apply preconditioner\n+ 521\n+ 522 // v = A * y\n+ 523 _op->apply(y,v);\n+ 524\n+ 525 // alpha = rho_new / < rt, v >\n+ 526 h = _sp->dot(rt,v);\n+ 527\n+ 528 if ( Simd::allTrue(abs(h) < EPSILON) )\n+ 529 DUNE_THROW(SolverAbort,\"abs(h) < EPSILON in BiCGSTAB - abs(h) \"\n+ 530 << Simd::io(abs(h)) << \" < EPSILON \" << EPSILON\n+ 531 << \" after \" << it << \" iterations\");\n+ 532\n+ 533 alpha = Simd::cond(norm==field_type(0.),\n+ 534 field_type(0.),\n+ 535 rho_new / h);\n+ 536\n+ 537 // apply first correction to x\n+ 538 // x <- x + alpha y\n+ 539 x.axpy(alpha,y);\n+ 540\n+ 541 // r = r - alpha*v\n+ 542 r.axpy(-alpha,v);\n+ 543\n+ 544 //\n+ 545 // test stop criteria\n+ 546 //\n 547\n-549 row_type& operator[](size_type i)\n- 550 {\n- 551#ifdef DUNE_ISTL_WITH_CHECKING\n- 552 if (build_mode == implicit && ready != built)\n- 553 DUNE_THROW(BCRSMatrixError,\"You cannot use operator[] in implicit build\n-mode before calling compress()\");\n- 554 if (r==0) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n- 555 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 556#endif\n- 557 return r[i];\n- 558 }\n- 559\n-561 const row_type& operator[](size_type i) const\n- 562 {\n- 563#ifdef DUNE_ISTL_WITH_CHECKING\n- 564 if (build_mode == implicit && ready != built)\n- 565 DUNE_THROW(BCRSMatrixError,\"You cannot use operator[] in implicit build\n-mode before calling compress()\");\n- 566 if (built!=ready) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n- 567 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 568#endif\n- 569 return r[i];\n- 570 }\n+ 548 norm = _sp->norm(r);\n+ 549 if(iteration.step(it, norm)){\n+ 550 break;\n+ 551 }\n+ 552\n+ 553 it+=.5;\n+ 554\n+ 555 // y = W^-1 * r\n+ 556 y = 0;\n+ 557 _prec->apply(y,r);\n+ 558\n+ 559 // t = A * y\n+ 560 _op->apply(y,t);\n+ 561\n+ 562 // omega = < t, r > / < t, t >\n+ 563 h = _sp->dot(t,t);\n+ 564 omega = Simd::cond(norm==field_type(0.),\n+ 565 field_type(0.),\n+ 566 _sp->dot(t,r)/h);\n+ 567\n+ 568 // apply second correction to x\n+ 569 // x <- x + omega y\n+ 570 x.axpy(omega,y);\n 571\n- 572\n- 573 //===== iterator interface to rows of the matrix\n+ 572 // r = s - omega*t (remember : r = s)\n+ 573 r.axpy(-omega,t);\n 574\n- 576 template\n-577 class RealRowIterator\n- 578 : public RandomAccessIteratorFacade, T>\n- 579 {\n+ 575 rho = rho_new;\n+ 576\n+ 577 //\n+ 578 // test stop criteria\n+ 579 //\n 580\n- 581 public:\n-583 typedef typename std::remove_const::type ValueType;\n- 584\n- 585 friend class RandomAccessIteratorFacade,\n-const ValueType>;\n- 586 friend class RandomAccessIteratorFacade,\n-ValueType>;\n- 587 friend class RealRowIterator;\n- 588 friend class RealRowIterator;\n+ 581 norm = _sp->norm(r);\n+ 582 if(iteration.step(it, norm)){\n+ 583 break;\n+ 584 }\n+ 585 } // end for\n+ 586\n+ 587 _prec->post(x); // postprocess preconditioner\n+ 588 }\n 589\n-591 RealRowIterator (row_type* _p, size_type _i)\n- 592 : p(_p), i(_i)\n- 593 {}\n- 594\n-596 RealRowIterator ()\n- 597 : p(0), i(0)\n- 598 {}\n- 599\n-600 RealRowIterator(const RealRowIterator& it)\n- 601 : p(it.p), i(it.i)\n- 602 {}\n- 603\n- 604\n-606 size_type index () const\n- 607 {\n- 608 return i;\n- 609 }\n- 610\n-611 std::ptrdiff_t distanceTo(const RealRowIterator& other) const\n- 612 {\n- 613 assert(other.p==p);\n- 614 return (other.i-i);\n- 615 }\n- 616\n-617 std::ptrdiff_t distanceTo(const RealRowIterator& other)\n-const\n- 618 {\n- 619 assert(other.p==p);\n- 620 return (other.i-i);\n- 621 }\n- 622\n-624 bool equals (const RealRowIterator& other) const\n- 625 {\n- 626 assert(other.p==p);\n- 627 return i==other.i;\n- 628 }\n- 629\n-631 bool equals (const RealRowIterator& other) const\n- 632 {\n- 633 assert(other.p==p);\n- 634 return i==other.i;\n- 635 }\n- 636\n- 637 private:\n- 639 void increment()\n- 640 {\n- 641 ++i;\n- 642 }\n- 643\n- 645 void decrement()\n- 646 {\n- 647 --i;\n+ 590 protected:\n+ 591 using IterativeSolver::_op;\n+ 592 using IterativeSolver::_prec;\n+ 593 using IterativeSolver::_sp;\n+ 594 using IterativeSolver::_reduction;\n+ 595 using IterativeSolver::_maxit;\n+ 596 using IterativeSolver::_verbose;\n+ 597 template\n+598 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 599 };\n+600 DUNE_REGISTER_ITERATIVE_SOLVER(\"bicgstabsolver\",\n+defaultIterativeSolverCreator());\n+ 601\n+ 608 template\n+609 class MINRESSolver : public IterativeSolver {\n+ 610 public:\n+ 611 using typename IterativeSolver::domain_type;\n+ 612 using typename IterativeSolver::range_type;\n+ 613 using typename IterativeSolver::field_type;\n+ 614 using typename IterativeSolver::real_type;\n+ 615\n+ 616 // copy base class constructors\n+ 617 using IterativeSolver::IterativeSolver;\n+ 618\n+ 619 // don't shadow four-argument version of apply defined in the base class\n+ 620 using IterativeSolver::apply;\n+ 621\n+627 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 628 {\n+ 629 using std::sqrt;\n+ 630 using std::abs;\n+ 631 Iteration iteration(*this, res);\n+ 632 // prepare preconditioner\n+ 633 _prec->pre(x,b);\n+ 634\n+ 635 // overwrite rhs with defect\n+ 636 _op->applyscaleadd(-1.0,x,b); // b -= Ax\n+ 637\n+ 638 // some temporary vectors\n+ 639 X z(b), dummy(b);\n+ 640 z = 0.0;\n+ 641\n+ 642 // calculate preconditioned defect\n+ 643 _prec->apply(z,b); // r = W^-1 (b - Ax)\n+ 644 real_type def = _sp->norm(z);\n+ 645 if (iteration.step(0, def)){\n+ 646 _prec->post(x);\n+ 647 return;\n 648 }\n 649\n- 650 void advance(std::ptrdiff_t diff)\n- 651 {\n- 652 i+=diff;\n- 653 }\n- 654\n- 655 T& elementAt(std::ptrdiff_t diff) const\n- 656 {\n- 657 return p[i+diff];\n- 658 }\n+ 650 // recurrence coefficients as computed in Lanczos algorithm\n+ 651 field_type alpha, beta;\n+ 652 // diagonal entries of givens rotation\n+ 653 std::array c{{0.0,0.0}};\n+ 654 // off-diagonal entries of givens rotation\n+ 655 std::array s{{0.0,0.0}};\n+ 656\n+ 657 // recurrence coefficients (column k of tridiag matrix T_k)\n+ 658 std::array T{{0.0,0.0,0.0}};\n 659\n- 661 row_type& dereference () const\n- 662 {\n- 663 return p[i];\n- 664 }\n- 665\n- 666 row_type* p;\n- 667 size_type i;\n- 668 };\n- 669\n-671 typedef RealRowIterator iterator;\n-672 typedef RealRowIterator Iterator;\n+ 660 // the rhs vector of the min problem\n+ 661 std::array xi{{1.0,0.0}};\n+ 662\n+ 663 // beta is real and positive in exact arithmetic\n+ 664 // since it is the norm of the basis vectors (in unpreconditioned case)\n+ 665 beta = sqrt(_sp->dot(b,z));\n+ 666 field_type beta0 = beta;\n+ 667\n+ 668 // the search directions\n+ 669 std::array p{{b,b,b}};\n+ 670 p[0] = 0.0;\n+ 671 p[1] = 0.0;\n+ 672 p[2] = 0.0;\n 673\n-675 Iterator begin ()\n- 676 {\n- 677 return Iterator(r,0);\n- 678 }\n- 679\n-681 Iterator end ()\n- 682 {\n- 683 return Iterator(r,n);\n- 684 }\n+ 674 // orthonormal basis vectors (in unpreconditioned case)\n+ 675 std::array q{{b,b,b}};\n+ 676 q[0] = 0.0;\n+ 677 q[1] *= Simd::cond(def==field_type(0.),\n+ 678 field_type(0.),\n+ 679 real_type(1.0)/beta);\n+ 680 q[2] = 0.0;\n+ 681\n+ 682 z *= Simd::cond(def==field_type(0.),\n+ 683 field_type(0.),\n+ 684 real_type(1.0)/beta);\n 685\n-688 Iterator beforeEnd ()\n- 689 {\n- 690 return Iterator(r,n-1);\n- 691 }\n- 692\n-695 Iterator beforeBegin ()\n- 696 {\n- 697 return Iterator(r,-1);\n- 698 }\n- 699\n-701 typedef Iterator RowIterator;\n- 702\n-704 typedef typename row_type::Iterator ColIterator;\n- 705\n-707 typedef RealRowIterator const_iterator;\n-708 typedef RealRowIterator ConstIterator;\n- 709\n+ 686 // the loop\n+ 687 int i = 1;\n+ 688 for( ; i<=_maxit; i++) {\n+ 689\n+ 690 dummy = z;\n+ 691 int i1 = i%3,\n+ 692 i0 = (i1+2)%3,\n+ 693 i2 = (i1+1)%3;\n+ 694\n+ 695 // symmetrically preconditioned Lanczos algorithm (see Greenbaum p.121)\n+ 696 _op->apply(z,q[i2]); // q[i2] = Az\n+ 697 q[i2].axpy(-beta,q[i0]);\n+ 698 // alpha is real since it is the diagonal entry of the hermitian\n+tridiagonal matrix\n+ 699 // from the Lanczos Algorithm\n+ 700 // so the order in the scalar product doesn't matter even for the complex\n+case\n+ 701 alpha = _sp->dot(z,q[i2]);\n+ 702 q[i2].axpy(-alpha,q[i1]);\n+ 703\n+ 704 z = 0.0;\n+ 705 _prec->apply(z,q[i2]);\n+ 706\n+ 707 // beta is real and positive in exact arithmetic\n+ 708 // since it is the norm of the basis vectors (in unpreconditioned case)\n+ 709 beta = sqrt(_sp->dot(q[i2],z));\n 710\n-712 ConstIterator begin () const\n- 713 {\n- 714 return ConstIterator(r,0);\n- 715 }\n- 716\n-718 ConstIterator end () const\n- 719 {\n- 720 return ConstIterator(r,n);\n- 721 }\n- 722\n-725 ConstIterator beforeEnd() const\n- 726 {\n- 727 return ConstIterator(r,n-1);\n+ 711 q[i2] *= Simd::cond(def==field_type(0.),\n+ 712 field_type(0.),\n+ 713 real_type(1.0)/beta);\n+ 714 z *= Simd::cond(def==field_type(0.),\n+ 715 field_type(0.),\n+ 716 real_type(1.0)/beta);\n+ 717\n+ 718 // QR Factorization of recurrence coefficient matrix\n+ 719 // apply previous givens rotations to last column of T\n+ 720 T[1] = T[2];\n+ 721 if(i>2) {\n+ 722 T[0] = s[i%2]*T[1];\n+ 723 T[1] = c[i%2]*T[1];\n+ 724 }\n+ 725 if(i>1) {\n+ 726 T[2] = c[(i+1)%2]*alpha - s[(i+1)%2]*T[1];\n+ 727 T[1] = c[(i+1)%2]*T[1] + s[(i+1)%2]*alpha;\n 728 }\n- 729\n-732 ConstIterator beforeBegin () const\n- 733 {\n- 734 return ConstIterator(r,-1);\n- 735 }\n- 736\n-738 typedef ConstIterator ConstRowIterator;\n+ 729 else\n+ 730 T[2] = alpha;\n+ 731\n+ 732 // update QR factorization\n+ 733 generateGivensRotation(T[2],beta,c[i%2],s[i%2]);\n+ 734 // to last column of T_k\n+ 735 T[2] = c[i%2]*T[2] + s[i%2]*beta;\n+ 736 // and to the rhs xi of the min problem\n+ 737 xi[i%2] = -s[i%2]*xi[(i+1)%2];\n+ 738 xi[(i+1)%2] *= c[i%2];\n 739\n-741 typedef typename row_type::ConstIterator ConstColIterator;\n- 742\n- 743 //===== constructors & resizers\n- 744\n- 745 // we use a negative compressionBufferSize to indicate that the implicit\n- 746 // mode parameters have not been set yet\n- 747\n-749 BCRSMatrix ()\n- 750 : build_mode(unknown), ready(notAllocated), n(0), m(0), nnz_(0),\n- 751 allocationSize_(0), r(0), a(0),\n- 752 avg(0), compressionBufferSize_(-1.0)\n- 753 {}\n- 754\n-756 BCRSMatrix (size_type _n, size_type _m, size_type _nnz, BuildMode bm)\n- 757 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n- 758 allocationSize_(0), r(0), a(0),\n- 759 avg(0), compressionBufferSize_(-1.0)\n- 760 {\n- 761 allocate(_n, _m, _nnz,true,false);\n+ 740 // compute correction direction\n+ 741 p[i2] = dummy;\n+ 742 p[i2].axpy(-T[1],p[i1]);\n+ 743 p[i2].axpy(-T[0],p[i0]);\n+ 744 p[i2] *= real_type(1.0)/T[2];\n+ 745\n+ 746 // apply correction/update solution\n+ 747 x.axpy(beta0*xi[(i+1)%2],p[i2]);\n+ 748\n+ 749 // remember beta_old\n+ 750 T[2] = beta;\n+ 751\n+ 752 // check for convergence\n+ 753 // the last entry in the rhs of the min-problem is the residual\n+ 754 def = abs(beta0*xi[i%2]);\n+ 755 if(iteration.step(i, def)){\n+ 756 break;\n+ 757 }\n+ 758 } // end for\n+ 759\n+ 760 // postprocess preconditioner\n+ 761 _prec->post(x);\n 762 }\n 763\n-765 BCRSMatrix (size_type _n, size_type _m, BuildMode bm)\n- 766 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n- 767 allocationSize_(0), r(0), a(0),\n- 768 avg(0), compressionBufferSize_(-1.0)\n- 769 {\n- 770 allocate(_n, _m,0,true,false);\n- 771 }\n- 772\n- 774\n-784 BCRSMatrix (size_type _n, size_type _m, size_type _avg, double\n-compressionBufferSize, BuildMode bm)\n- 785 : build_mode(bm), ready(notAllocated), n(0), m(0), nnz_(0),\n- 786 allocationSize_(0), r(0), a(0),\n- 787 avg(_avg), compressionBufferSize_(compressionBufferSize)\n- 788 {\n- 789 if (bm != implicit)\n- 790 DUNE_THROW(BCRSMatrixError,\"Only call this constructor when using the\n-implicit build mode\");\n- 791 // Prevent user from setting a negative compression buffer size:\n- 792 // 1) It doesn't make sense\n- 793 // 2) We use a negative value to indicate that the parameters\n- 794 // have not been set yet\n- 795 if (compressionBufferSize_ < 0.0)\n- 796 DUNE_THROW(BCRSMatrixError,\"You cannot set a negative overflow fraction\");\n- 797 implicit_allocate(_n,_m);\n- 798 }\n- 799\n-805 BCRSMatrix (const BCRSMatrix& Mat)\n- 806 : build_mode(Mat.build_mode), ready(notAllocated), n(0), m(0), nnz_(0),\n- 807 allocationSize_(0), r(0), a(0),\n- 808 avg(Mat.avg), compressionBufferSize_(Mat.compressionBufferSize_)\n- 809 {\n- 810 if (!(Mat.ready == notAllocated || Mat.ready == built))\n- 811 DUNE_THROW(InvalidStateException,\"BCRSMatrix can only be copy-constructed\n-when source matrix is completely empty (size not set) or fully built)\");\n- 812\n- 813 // deep copy in global array\n- 814 size_type _nnz = Mat.nonzeroes();\n- 815\n- 816 j_ = Mat.j_; // enable column index sharing, release array in case of row-\n-wise allocation\n- 817 allocate(Mat.n, Mat.m, _nnz, true, true);\n- 818\n- 819 // build window structure\n- 820 copyWindowStructure(Mat);\n- 821 }\n- 822\n-824 ~BCRSMatrix ()\n- 825 {\n- 826 deallocate();\n- 827 }\n- 828\n-833 void setBuildMode(BuildMode bm)\n- 834 {\n- 835 if (ready == notAllocated)\n- 836 {\n- 837 build_mode = bm;\n- 838 return;\n- 839 }\n- 840 if (ready == building && (build_mode == unknown || build_mode == random ||\n-build_mode == row_wise) && (bm == row_wise || bm == random))\n- 841 build_mode = bm;\n- 842 else\n- 843 DUNE_THROW(InvalidStateException, \"Matrix structure cannot be changed at\n-this stage anymore (ready == \"< norm_dx,\n+ 784 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,\n+ 785 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)\n+ 786 )));\n+ 787 sn = Simd::cond(norm_dy < eps,\n+ 788 field_type(0.0),\n+ 789 Simd::cond(norm_dx < eps,\n+ 790 field_type(1.0),\n+ 791 Simd::cond(norm_dy > norm_dx,\n+ 792 // dy and dx are real in exact arithmetic\n+ 793 // thus dx*dy is real so we can explicitly enforce it\n+ 794 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*dy/norm_dx/norm_dy,\n+ 795 // dy and dx is real in exact arithmetic\n+ 796 // so we don't have to conjugate both of them\n+ 797 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dy/dx\n+ 798 )));\n+ 799 }\n+ 800\n+ 801 protected:\n+ 802 using IterativeSolver::_op;\n+ 803 using IterativeSolver::_prec;\n+ 804 using IterativeSolver::_sp;\n+ 805 using IterativeSolver::_reduction;\n+ 806 using IterativeSolver::_maxit;\n+ 807 using IterativeSolver::_verbose;\n+808 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 809 };\n+810 DUNE_REGISTER_ITERATIVE_SOLVER(\"minressolver\",\n+defaultIterativeSolverCreator());\n+ 811\n+ 825 template\n+826 class RestartedGMResSolver : public IterativeSolver\n+ 827 {\n+ 828 public:\n+ 829 using typename IterativeSolver::domain_type;\n+ 830 using typename IterativeSolver::range_type;\n+ 831 using typename IterativeSolver::field_type;\n+ 832 using typename IterativeSolver::real_type;\n+ 833\n+ 834 protected:\n+ 835 using typename IterativeSolver::scalar_real_type;\n+ 836\n+838 using fAlloc = ReboundAllocatorType;\n+840 using rAlloc = ReboundAllocatorType;\n+ 841\n+ 842 public:\n+ 843\n+850 RestartedGMResSolver (const LinearOperator& op, Preconditioner&\n+prec, scalar_real_type reduction, int restart, int maxit, int verbose) :\n+ 851 IterativeSolver::IterativeSolver(op,prec,reduction,maxit,verbose),\n+ 852 _restart(restart)\n+ 853 {}\n+ 854\n+861 RestartedGMResSolver (const LinearOperator& op, const\n+ScalarProduct& sp, Preconditioner& prec, scalar_real_type reduction,\n+int restart, int maxit, int verbose) :\n+ 862 IterativeSolver::IterativeSolver(op,sp,prec,reduction,maxit,verbose),\n+ 863 _restart(restart)\n+ 864 {}\n 865\n- 866 if (build_mode == implicit)\n- 867 {\n- 868 if (nnz>0)\n- 869 DUNE_THROW(Dune::BCRSMatrixError,\"number of non-zeroes may not be set in\n-implicit mode, use setImplicitBuildModeParameters() instead\");\n- 870\n- 871 // implicit allocates differently\n- 872 implicit_allocate(rows,columns);\n- 873 }\n- 874 else\n- 875 {\n- 876 // allocate matrix memory\n- 877 allocate(rows, columns, nnz, true, false);\n- 878 }\n- 879 }\n- 880\n-889 void setImplicitBuildModeParameters(size_type _avg, double\n-compressionBufferSize)\n- 890 {\n- 891 // Prevent user from setting a negative compression buffer size:\n- 892 // 1) It doesn't make sense\n- 893 // 2) We use a negative value to indicate that the parameters\n- 894 // have not been set yet\n- 895 if (compressionBufferSize < 0.0)\n- 896 DUNE_THROW(BCRSMatrixError,\"You cannot set a negative\n-compressionBufferSize value\");\n- 897\n- 898 // make sure the parameters aren't changed after memory has been allocated\n- 899 if (ready != notAllocated)\n- 900 DUNE_THROW(InvalidStateException,\"You cannot modify build mode parameters\n-at this stage anymore\");\n- 901 avg = _avg;\n- 902 compressionBufferSize_ = compressionBufferSize;\n- 903 }\n- 904\n-911 BCRSMatrix& operator=(const BCRSMatrix& Mat)\n- 912 {\n- 913 // return immediately when self-assignment\n- 914 if (&Mat==this) return *this;\n- 915\n- 916 if (!((ready == notAllocated || ready == built) && (Mat.ready ==\n-notAllocated || Mat.ready == built)))\n- 917 DUNE_THROW(InvalidStateException,\"BCRSMatrix can only be copied when both\n-target and source are empty or fully built)\");\n- 918\n- 919 // make it simple: ALWAYS throw away memory for a and j_\n- 920 // and deallocate rows only if n != Mat.n\n- 921 deallocate(n!=Mat.n);\n- 922\n- 923 // reallocate the rows if required\n- 924 if (n>0 && n!=Mat.n) {\n- 925 // free rows\n- 926 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)\n- 927 std::allocator_traits::destroy(rowAllocator_,\n-riter);\n- 928 rowAllocator_.deallocate(r,n);\n- 929 }\n- 930\n- 931 nnz_ = Mat.nonzeroes();\n- 932\n- 933 // allocate a, share j_\n- 934 j_ = Mat.j_;\n- 935 allocate(Mat.n, Mat.m, nnz_, n!=Mat.n, true);\n- 936\n- 937 // build window structure\n- 938 copyWindowStructure(Mat);\n- 939 return *this;\n- 940 }\n- 941\n-943 BCRSMatrix& operator=(const field_type& k)\n- 944 {\n- 945\n- 946 if (!(ready == notAllocated || ready == built))\n- 947 DUNE_THROW(InvalidStateException,\"Scalar assignment only works on fully\n-built BCRSMatrix)\");\n- 948\n- 949 for (size_type i=0; i0) {\n- 991 // update number of nonzeroes including this row\n- 992 nnz += s;\n- 993\n- 994 // alloc memory / set window\n- 995 if (Mat.nnz_ > 0)\n- 996 {\n- 997 // memory is allocated in one long array\n- 998\n- 999 // check if that memory is sufficient\n- 1000 if (nnz > Mat.nnz_)\n- 1001 DUNE_THROW(BCRSMatrixError,\"allocated nnz too small\");\n- 1002\n- 1003 // set row i\n- 1004 Mat.r[i].set(s,nullptr,current_row.getindexptr());\n- 1005 current_row.setindexptr(current_row.getindexptr()+s);\n- 1006 }else{\n- 1007 // memory is allocated individually per row\n- 1008 // allocate and set row i\n- 1009 B* b = Mat.allocator_.allocate(s);\n- 1010 // use placement new to call constructor that allocates\n- 1011 // additional memory.\n- 1012 new (b) B[s];\n- 1013 size_type* j = Mat.sizeAllocator_.allocate(s);\n- 1014 Mat.r[i].set(s,b,j);\n- 1015 }\n- 1016 }else\n- 1017 // setup empty row\n- 1018 Mat.r[i].set(0,nullptr,nullptr);\n- 1019\n- 1020 // initialize the j array for row i from pattern\n- 1021 std::copy(pattern.cbegin(), pattern.cend(), Mat.r[i].getindexptr());\n- 1022\n- 1023 // now go to next row\n- 1024 i++;\n- 1025 pattern.clear();\n- 1026\n- 1027 // check if this was last row\n- 1028 if (i==Mat.n)\n- 1029 {\n- 1030 Mat.ready = built;\n- 1031 if(Mat.nnz_ > 0)\n- 1032 {\n- 1033 // Set nnz to the exact number of nonzero blocks inserted\n- 1034 // as some methods rely on it\n- 1035 Mat.nnz_ = nnz;\n- 1036 // allocate data array\n- 1037 Mat.allocateData();\n- 1038 Mat.setDataPointers();\n- 1039 }\n- 1040 }\n- 1041 // done\n- 1042 return *this;\n- 1043 }\n- 1044\n-1046 bool operator!=(const CreateIterator& it) const\n- 1047 {\n- 1048 return (i!=it.i) || (&Mat!=&it.Mat);\n- 1049 }\n- 1050\n-1052 bool operator==(const CreateIterator& it) const\n- 1053 {\n- 1054 return (i==it.i) && (&Mat==&it.Mat);\n- 1055 }\n- 1056\n-1058 size_type index () const\n- 1059 {\n- 1060 return i;\n- 1061 }\n- 1062\n-1064 void insert (size_type j)\n- 1065 {\n- 1066 pattern.insert(j);\n- 1067 }\n- 1068\n-1070 bool contains (size_type j)\n- 1071 {\n- 1072 return pattern.find(j) != pattern.end();\n- 1073 }\n-1079 size_type size() const\n- 1080 {\n- 1081 return pattern.size();\n- 1082 }\n- 1083\n- 1084 private:\n- 1085 BCRSMatrix& Mat; // the matrix we are defining\n- 1086 size_type i; // current row to be defined\n- 1087 size_type nnz; // count total number of nonzeros\n- 1088 typedef std::set > PatternType;\n- 1089 PatternType pattern; // used to compile entries in a row\n- 1090 row_type current_row; // row pointing to the current row to setup\n- 1091 };\n- 1092\n-1094 friend class CreateIterator;\n- 1095\n-1097 CreateIterator createbegin ()\n- 1098 {\n- 1099 return CreateIterator(*this,0);\n- 1100 }\n- 1101\n-1103 CreateIterator createend ()\n- 1104 {\n- 1105 return CreateIterator(*this,n);\n- 1106 }\n- 1107\n- 1108\n- 1109 //===== random creation interface\n- 1110\n-1117 void setrowsize (size_type i, size_type s)\n- 1118 {\n- 1119 if (build_mode!=random)\n- 1120 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n- 1121 if (ready != building)\n- 1122 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n+878 RestartedGMResSolver (std::shared_ptr > op, std::\n+shared_ptr > prec, const ParameterTree& configuration) :\n+ 879 IterativeSolver::IterativeSolver(op,prec,configuration),\n+ 880 _restart(configuration.get(\"restart\"))\n+ 881 {}\n+ 882\n+883 RestartedGMResSolver (std::shared_ptr > op, std::\n+shared_ptr > sp, std::shared_ptr >\n+prec, const ParameterTree& configuration) :\n+ 884 IterativeSolver::IterativeSolver(op,sp,prec,configuration),\n+ 885 _restart(configuration.get(\"restart\"))\n+ 886 {}\n+ 887\n+894 RestartedGMResSolver (std::shared_ptr> op,\n+ 895 std::shared_ptr> sp,\n+ 896 std::shared_ptr> prec,\n+ 897 scalar_real_type reduction, int restart, int maxit, int verbose) :\n+ 898 IterativeSolver::IterativeSolver(op,sp,prec,reduction,maxit,verbose),\n+ 899 _restart(restart)\n+ 900 {}\n+ 901\n+910 virtual void apply (X& x, Y& b, InverseOperatorResult& res)\n+ 911 {\n+ 912 apply(x,b,Simd::max(_reduction),res);\n+ 913 }\n+ 914\n+923 virtual void apply (X& x, Y& b, [[maybe_unused]] double reduction,\n+InverseOperatorResult& res)\n+ 924 {\n+ 925 using std::abs;\n+ 926 const Simd::Scalar EPSILON = 1e-80;\n+ 927 const int m = _restart;\n+ 928 real_type norm = 0.0;\n+ 929 int j = 1;\n+ 930 std::vector s(m+1), sn(m);\n+ 931 std::vector cs(m);\n+ 932 // need copy of rhs if GMRes has to be restarted\n+ 933 Y b2(b);\n+ 934 // helper vector\n+ 935 Y w(b);\n+ 936 std::vector< std::vector > H(m+1,s);\n+ 937 std::vector v(m+1,b);\n+ 938\n+ 939 Iteration iteration(*this,res);\n+ 940\n+ 941 // clear solver statistics and set res.converged to false\n+ 942 _prec->pre(x,b);\n+ 943\n+ 944 // calculate defect and overwrite rhs with it\n+ 945 _op->applyscaleadd(-1.0,x,b); // b -= Ax\n+ 946 // calculate preconditioned defect\n+ 947 v[0] = 0.0; _prec->apply(v[0],b); // r = W^-1 b\n+ 948 norm = _sp->norm(v[0]);\n+ 949 if(iteration.step(0, norm)){\n+ 950 _prec->post(x);\n+ 951 return;\n+ 952 }\n+ 953\n+ 954 while(j <= _maxit && res.converged != true) {\n+ 955\n+ 956 int i = 0;\n+ 957 v[0] *= Simd::cond(norm==real_type(0.),\n+ 958 real_type(0.),\n+ 959 real_type(1.0)/norm);\n+ 960 s[0] = norm;\n+ 961 for(i=1; iapply(v[i],v[i+1]);\n+ 970 _prec->apply(w,v[i+1]);\n+ 971 for(int k=0; kdot(v[k],w) = v[k]\\adjoint w\n+ 973 // so one has to pay attention to the order\n+ 974 // in the scalar product for the complex case\n+ 975 // doing the modified Gram-Schmidt algorithm\n+ 976 H[k][i] = _sp->dot(v[k],w);\n+ 977 // w -= H[k][i] * v[k]\n+ 978 w.axpy(-H[k][i],v[k]);\n+ 979 }\n+ 980 H[i+1][i] = _sp->norm(w);\n+ 981 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))\n+ 982 DUNE_THROW(SolverAbort,\n+ 983 \"breakdown in GMRes - |w| == 0.0 after \" << j << \" iterations\");\n+ 984\n+ 985 // normalize new vector\n+ 986 v[i+1] = w;\n+ 987 v[i+1] *= Simd::cond(norm==real_type(0.),\n+ 988 field_type(0.),\n+ 989 real_type(1.0)/H[i+1][i]);\n+ 990\n+ 991 // update QR factorization\n+ 992 for(int k=0; k 0)\n+ 1020 std::cout << \"=== GMRes::restart\" << std::endl;\n+ 1021 // get saved rhs\n+ 1022 b = b2;\n+ 1023 // calculate new defect\n+ 1024 _op->applyscaleadd(-1.0,x,b); // b -= Ax;\n+ 1025 // calculate preconditioned defect\n+ 1026 v[0] = 0.0;\n+ 1027 _prec->apply(v[0],b);\n+ 1028 norm = _sp->norm(v[0]);\n+ 1029 }\n+ 1030\n+ 1031 } //end while\n+ 1032\n+ 1033 // postprocess preconditioner\n+ 1034 _prec->post(x);\n+ 1035 }\n+ 1036\n+ 1037 protected :\n+ 1038\n+1039 void update(X& w, int i,\n+ 1040 const std::vector >& H,\n+ 1041 const std::vector& s,\n+ 1042 const std::vector& v) {\n+ 1043 // solution vector of the upper triangular system\n+ 1044 std::vector y(s);\n+ 1045\n+ 1046 // backsolve\n+ 1047 for(int a=i-1; a>=0; a--) {\n+ 1048 field_type rhs(s[a]);\n+ 1049 for(int b=a+1; b\n+1062 typename std::enable_if::value,T>::type\n+conjugate(const T& t) {\n+ 1063 return t;\n+ 1064 }\n+ 1065\n+ 1066 template\n+1067 typename std::enable_if::value,T>::\n+type conjugate(const T& t) {\n+ 1068 using std::conj;\n+ 1069 return conj(t);\n+ 1070 }\n+ 1071\n+ 1072 void\n+1073 generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n+field_type &sn)\n+ 1074 {\n+ 1075 using std::sqrt;\n+ 1076 using std::abs;\n+ 1077 using std::max;\n+ 1078 using std::min;\n+ 1079 const real_type eps = 1e-15;\n+ 1080 real_type norm_dx = abs(dx);\n+ 1081 real_type norm_dy = abs(dy);\n+ 1082 real_type norm_max = max(norm_dx, norm_dy);\n+ 1083 real_type norm_min = min(norm_dx, norm_dy);\n+ 1084 real_type temp = norm_min/norm_max;\n+ 1085 // we rewrite the code in a vectorizable fashion\n+ 1086 cs = Simd::cond(norm_dy < eps,\n+ 1087 real_type(1.0),\n+ 1088 Simd::cond(norm_dx < eps,\n+ 1089 real_type(0.0),\n+ 1090 Simd::cond(norm_dy > norm_dx,\n+ 1091 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)*temp,\n+ 1092 real_type(1.0)/sqrt(real_type(1.0) + temp*temp)\n+ 1093 )));\n+ 1094 sn = Simd::cond(norm_dy < eps,\n+ 1095 field_type(0.0),\n+ 1096 Simd::cond(norm_dx < eps,\n+ 1097 field_type(1.0),\n+ 1098 Simd::cond(norm_dy > norm_dx,\n+ 1099 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*dx*conjugate(dy)/\n+norm_dx/norm_dy,\n+ 1100 field_type(1.0)/sqrt(real_type(1.0) + temp*temp)*conjugate(dy/dx)\n+ 1101 )));\n+ 1102 }\n+ 1103\n+ 1104\n+ 1105 void\n+1106 applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n+field_type &sn)\n+ 1107 {\n+ 1108 field_type temp = cs * dx + sn * dy;\n+ 1109 dy = -conjugate(sn) * dx + cs * dy;\n+ 1110 dx = temp;\n+ 1111 }\n+ 1112\n+ 1113 using IterativeSolver::_op;\n+ 1114 using IterativeSolver::_prec;\n+ 1115 using IterativeSolver::_sp;\n+ 1116 using IterativeSolver::_reduction;\n+ 1117 using IterativeSolver::_maxit;\n+ 1118 using IterativeSolver::_verbose;\n+1119 using Iteration = typename IterativeSolver::template\n+Iteration;\n+1120 int _restart;\n+ 1121 };\n+1122 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedgmressolver\",\n+defaultIterativeSolverCreator());\n 1123\n- 1124 r[i].setsize(s);\n- 1125 }\n- 1126\n-1128 size_type getrowsize (size_type i) const\n- 1129 {\n- 1130#ifdef DUNE_ISTL_WITH_CHECKING\n- 1131 if (r==0) DUNE_THROW(BCRSMatrixError,\"row not initialized yet\");\n- 1132 if (i>=n) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1133#endif\n- 1134 return r[i].getsize();\n- 1135 }\n- 1136\n-1138 void incrementrowsize (size_type i, size_type s = 1)\n+ 1137 template\n+1138 class RestartedFlexibleGMResSolver : public RestartedGMResSolver\n 1139 {\n- 1140 if (build_mode!=random)\n- 1141 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n- 1142 if (ready != building)\n- 1143 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n- 1144\n- 1145 r[i].setsize(r[i].getsize()+s);\n- 1146 }\n- 1147\n-1149 void endrowsizes ()\n- 1150 {\n- 1151 if (build_mode!=random)\n- 1152 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n- 1153 if (ready != building)\n- 1154 DUNE_THROW(BCRSMatrixError,\"matrix row sizes already built up\");\n- 1155\n- 1156 // compute total size, check positivity\n- 1157 size_type total=0;\n- 1158 for (size_type i=0; i= m)\n- 1203 DUNE_THROW(BCRSMatrixError,\"column index exceeds matrix size\");\n- 1204\n- 1205 // get row range\n- 1206 size_type* const first = r[row].getindexptr();\n- 1207 size_type* const last = first + r[row].getsize();\n- 1208\n- 1209 // find correct insertion position for new column index\n- 1210 size_type* pos = std::lower_bound(first,last,col);\n- 1211\n- 1212 // check if index is already in row\n- 1213 if (pos!=last && *pos == col) return;\n- 1214\n- 1215 // find end of already inserted column indices\n- 1216 size_type* end = std::lower_bound(pos,last,m);\n- 1217 if (end==last)\n- 1218 DUNE_THROW(BCRSMatrixError,\"row is too small\");\n- 1219\n- 1220 // insert new column index at correct position\n- 1221 std::copy_backward(pos,end,end+1);\n- 1222 *pos = col;\n- 1223 }\n- 1224\n- 1226\n- 1233 template\n-1234 void setIndices(size_type row, It begin, It end)\n- 1235 {\n- 1236 size_type row_size = r[row].size();\n- 1237 size_type* col_begin = r[row].getindexptr();\n- 1238 size_type* col_end;\n- 1239 // consistency check between allocated row size and number of passed\n-column indices\n- 1240 if ((col_end = std::copy(begin,end,r[row].getindexptr())) != col_begin +\n-row_size)\n- 1241 DUNE_THROW(BCRSMatrixError,\"Given size of row \" << row\n- 1242 << \" (\" << row_size\n- 1243 << \") does not match number of passed entries (\" << (col_end - col_begin)\n-<< \")\");\n- 1244 std::sort(col_begin,col_end);\n- 1245 }\n+ 1140 public:\n+ 1141 using typename RestartedGMResSolver::domain_type;\n+ 1142 using typename RestartedGMResSolver::range_type;\n+ 1143 using typename RestartedGMResSolver::field_type;\n+ 1144 using typename RestartedGMResSolver::real_type;\n+ 1145\n+ 1146 private:\n+ 1147 using typename RestartedGMResSolver::scalar_real_type;\n+ 1148\n+ 1150 using fAlloc = typename RestartedGMResSolver::fAlloc;\n+ 1152 using rAlloc = typename RestartedGMResSolver::rAlloc;\n+ 1153\n+ 1154 public:\n+ 1155 // copy base class constructors\n+ 1156 using RestartedGMResSolver::RestartedGMResSolver;\n+ 1157\n+ 1158 // don't shadow four-argument version of apply defined in the base class\n+ 1159 using RestartedGMResSolver::apply;\n+ 1160\n+1169 void apply (X& x, Y& b, [[maybe_unused]] double reduction,\n+InverseOperatorResult& res) override\n+ 1170 {\n+ 1171 using std::abs;\n+ 1172 const Simd::Scalar EPSILON = 1e-80;\n+ 1173 const int m = _restart;\n+ 1174 real_type norm = 0.0;\n+ 1175 int i, j = 1, k;\n+ 1176 std::vector s(m+1), sn(m);\n+ 1177 std::vector cs(m);\n+ 1178 // helper vector\n+ 1179 Y tmp(b);\n+ 1180 std::vector< std::vector > H(m+1,s);\n+ 1181 std::vector v(m+1,b);\n+ 1182 std::vector w(m+1,b);\n+ 1183\n+ 1184 Iteration iteration(*this,res);\n+ 1185 // setup preconditioner if it does something in pre\n+ 1186\n+ 1187 // calculate residual and overwrite a copy of the rhs with it\n+ 1188 _prec->pre(x, b);\n+ 1189 v[0] = b;\n+ 1190 _op->applyscaleadd(-1.0, x, v[0]); // b -= Ax\n+ 1191\n+ 1192 norm = _sp->norm(v[0]); // the residual norm\n+ 1193 if(iteration.step(0, norm)){\n+ 1194 _prec->post(x);\n+ 1195 return;\n+ 1196 }\n+ 1197\n+ 1198 // start iterations\n+ 1199 res.converged = false;;\n+ 1200 while(j <= _maxit && res.converged != true)\n+ 1201 {\n+ 1202 v[0] *= (1.0 / norm);\n+ 1203 s[0] = norm;\n+ 1204 for(i=1; iapply(w[i], v[i]);\n+ 1213 // compute vi = A*wi\n+ 1214 // use v[i+1] as temporary vector for w\n+ 1215 _op->apply(w[i], v[i+1]);\n+ 1216 // do Arnoldi algorithm\n+ 1217 for(int kk=0; kkdot(v[k],v[i+1]) = v[k]\\adjoint v[i+1]\n+ 1220 // so one has to pay attention to the order\n+ 1221 // in the scalar product for the complex case\n+ 1222 // doing the modified Gram-Schmidt algorithm\n+ 1223 H[kk][i] = _sp->dot(v[kk],v[i+1]);\n+ 1224 // w -= H[k][i] * v[kk]\n+ 1225 v[i+1].axpy(-H[kk][i], v[kk]);\n+ 1226 }\n+ 1227 H[i+1][i] = _sp->norm(v[i+1]);\n+ 1228 if(Simd::allTrue(abs(H[i+1][i]) < EPSILON))\n+ 1229 DUNE_THROW(SolverAbort, \"breakdown in fGMRes - |w| (-> \"\n+ 1230 << w[i] << \") == 0.0 after \"\n+ 1231 << j << \" iterations\");\n+ 1232\n+ 1233 // v[i+1] = w*1/H[i+1][i]\n+ 1234 v[i+1] *= real_type(1.0)/H[i+1][i];\n+ 1235\n+ 1236 // update QR factorization\n+ 1237 for(k=0; kapplyPlaneRotation(H[k][i],H[k+1][i],cs[k],sn[k]);\n+ 1239\n+ 1240 // compute new givens rotation\n+ 1241 this->generatePlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);\n+ 1242\n+ 1243 // finish updating QR factorization\n+ 1244 this->applyPlaneRotation(H[i][i],H[i+1][i],cs[i],sn[i]);\n+ 1245 this->applyPlaneRotation(s[i],s[i+1],cs[i],sn[i]);\n 1246\n-1248 void endindices ()\n- 1249 {\n- 1250 if (build_mode!=random)\n- 1251 DUNE_THROW(BCRSMatrixError,\"requires random build mode\");\n- 1252 if (ready==built)\n- 1253 DUNE_THROW(BCRSMatrixError,\"matrix already built up\");\n- 1254 if (ready==building)\n- 1255 DUNE_THROW(BCRSMatrixError,\"row sizes are not built up yet\");\n- 1256 if (ready==notAllocated)\n- 1257 DUNE_THROW(BCRSMatrixError,\"matrix size not set and no memory allocated\n-yet\");\n+ 1247 // norm of the residual is the last component of vector s\n+ 1248 using std::abs;\n+ 1249 norm = abs(s[i+1]);\n+ 1250 iteration.step(j, norm);\n+ 1251 } // end inner for loop\n+ 1252\n+ 1253 // calculate update vector\n+ 1254 tmp = 0.0;\n+ 1255 this->update(tmp, i, H, s, w);\n+ 1256 // and update current iterate\n+ 1257 x += tmp;\n 1258\n- 1259 // check if there are undefined indices\n- 1260 RowIterator endi=end();\n- 1261 for (RowIterator i=begin(); i!=endi; ++i)\n- 1262 {\n- 1263 ColIterator endj = (*i).end();\n- 1264 for (ColIterator j=(*i).begin(); j!=endj; ++j) {\n- 1265 if (j.index() >= m) {\n- 1266 dwarn << \"WARNING: size of row \"<< i.index()<<\" is \"< 0)\n+ 1265 std::cout << \"=== fGMRes::restart\" << std::endl;\n+ 1266 // get rhs\n+ 1267 v[0] = b;\n+ 1268 // calculate new defect\n+ 1269 _op->applyscaleadd(-1.0, x,v[0]); // b -= Ax;\n+ 1270 // calculate preconditioned defect\n+ 1271 norm = _sp->norm(v[0]); // update the residual norm\n 1272 }\n- 1273 }\n- 1274\n- 1275 allocateData();\n- 1276 setDataPointers();\n- 1277\n- 1278 // if not, set matrix to built\n- 1279 ready = built;\n- 1280 }\n- 1281\n- 1282 //===== implicit creation interface\n- 1283\n- 1285\n-1296 B& entry(size_type row, size_type col)\n- 1297 {\n- 1298#ifdef DUNE_ISTL_WITH_CHECKING\n- 1299 if (build_mode!=implicit)\n- 1300 DUNE_THROW(BCRSMatrixError,\"requires implicit build mode\");\n- 1301 if (ready==built)\n- 1302 DUNE_THROW(BCRSMatrixError,\"matrix already built up, use operator[] for\n-entry access now\");\n- 1303 if (ready==notAllocated)\n- 1304 DUNE_THROW(BCRSMatrixError,\"matrix size not set and no memory allocated\n-yet\");\n- 1305 if (ready!=building)\n- 1306 DUNE_THROW(InvalidStateException,\"You may only use entry() during the\n-'building' stage\");\n- 1307\n- 1308 if (row >= n)\n- 1309 DUNE_THROW(BCRSMatrixError,\"row index exceeds matrix size\");\n- 1310 if (col >= m)\n- 1311 DUNE_THROW(BCRSMatrixError,\"column index exceeds matrix size\");\n- 1312#endif\n+ 1273\n+ 1274 } // end outer while loop\n+ 1275\n+ 1276 // post-process preconditioner\n+ 1277 _prec->post(x);\n+ 1278 }\n+ 1279\n+ 1280private:\n+ 1281 using RestartedGMResSolver::_op;\n+ 1282 using RestartedGMResSolver::_prec;\n+ 1283 using RestartedGMResSolver::_sp;\n+ 1284 using RestartedGMResSolver::_reduction;\n+ 1285 using RestartedGMResSolver::_maxit;\n+ 1286 using RestartedGMResSolver::_verbose;\n+ 1287 using RestartedGMResSolver::_restart;\n+ 1288 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 1289 };\n+1290 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedflexiblegmressolver\",\n+defaultIterativeSolverCreator());\n+ 1291\n+ 1305 template\n+1306 class GeneralizedPCGSolver : public IterativeSolver\n+ 1307 {\n+ 1308 public:\n+ 1309 using typename IterativeSolver::domain_type;\n+ 1310 using typename IterativeSolver::range_type;\n+ 1311 using typename IterativeSolver::field_type;\n+ 1312 using typename IterativeSolver::real_type;\n 1313\n- 1314 size_type* begin = r[row].getindexptr();\n- 1315 size_type* end = begin + r[row].getsize();\n+ 1314 private:\n+ 1315 using typename IterativeSolver::scalar_real_type;\n 1316\n- 1317 size_type* pos = std::find(begin, end, col);\n- 1318\n- 1319 //treat the case that there was a match in the array\n- 1320 if (pos != end)\n- 1321 if (*pos == col)\n- 1322 {\n- 1323 std::ptrdiff_t offset = pos - r[row].getindexptr();\n- 1324 B* aptr = r[row].getptr() + offset;\n- 1325\n- 1326 return *aptr;\n- 1327 }\n- 1328\n- 1329 //determine whether overflow has to be taken into account or not\n- 1330 if (r[row].getsize() == avg)\n- 1331 return overflow[std::make_pair(row,col)];\n- 1332 else\n- 1333 {\n- 1334 //modify index array\n- 1335 *end = col;\n- 1336\n- 1337 //do simultaneous operations on data array a\n- 1338 std::ptrdiff_t offset = end - r[row].getindexptr();\n- 1339 B* apos = r[row].getptr() + offset;\n- 1340\n- 1341 //increase rowsize\n- 1342 r[row].setsize(r[row].getsize()+1);\n- 1343\n- 1344 //return reference to the newly created entry\n- 1345 return *apos;\n- 1346 }\n- 1347 }\n+ 1318 using fAlloc = ReboundAllocatorType;\n+ 1319\n+ 1320 public:\n+ 1321\n+ 1322 // don't shadow four-argument version of apply defined in the base class\n+ 1323 using IterativeSolver::apply;\n+ 1324\n+1331 GeneralizedPCGSolver (const LinearOperator& op, Preconditioner&\n+prec, scalar_real_type reduction, int maxit, int verbose, int restart = 10) :\n+ 1332 IterativeSolver::IterativeSolver(op,prec,reduction,maxit,verbose),\n+ 1333 _restart(restart)\n+ 1334 {}\n+ 1335\n+1343 GeneralizedPCGSolver (const LinearOperator& op, const\n+ScalarProduct& sp, Preconditioner& prec, scalar_real_type reduction,\n+int maxit, int verbose, int restart = 10) :\n+ 1344 IterativeSolver::IterativeSolver\n+(op,sp,prec,reduction,maxit,verbose),\n+ 1345 _restart(restart)\n+ 1346 {}\n+ 1347\n 1348\n- 1350\n-1360 CompressionStatistics compress()\n- 1361 {\n- 1362 if (build_mode!=implicit)\n- 1363 DUNE_THROW(BCRSMatrixError,\"requires implicit build mode\");\n- 1364 if (ready==built)\n- 1365 DUNE_THROW(BCRSMatrixError,\"matrix already built up, no more need for\n-compression\");\n- 1366 if (ready==notAllocated)\n- 1367 DUNE_THROW(BCRSMatrixError,\"matrix size not set and no memory allocated\n-yet\");\n- 1368 if (ready!=building)\n- 1369 DUNE_THROW(InvalidStateException,\"You may only call compress() at the end\n-of the 'building' stage\");\n- 1370\n- 1371 //calculate statistics\n- 1372 CompressionStatistics stats;\n- 1373 stats.overflow_total = overflow.size();\n- 1374 stats.maximum = 0;\n- 1375\n- 1376 //get insertion iterators pointing to one before start (for later use of\n-++it)\n- 1377 size_type* jiit = j_.get();\n- 1378 B* aiit = a;\n- 1379\n- 1380 //get iterator to the smallest overflow element\n- 1381 typename OverflowType::iterator oit = overflow.begin();\n- 1382\n- 1383 //store a copy of index pointers on which to perform sorting\n- 1384 std::vector perm;\n+1361 GeneralizedPCGSolver (std::shared_ptr > op,\n+std::shared_ptr > prec, const ParameterTree& configuration)\n+:\n+ 1362 IterativeSolver::IterativeSolver(op,prec,configuration),\n+ 1363 _restart(configuration.get(\"restart\"))\n+ 1364 {}\n+ 1365\n+1366 GeneralizedPCGSolver (std::shared_ptr > op,\n+std::shared_ptr > sp, std::\n+shared_ptr > prec, const ParameterTree& configuration) :\n+ 1367 IterativeSolver::IterativeSolver(op,sp,prec,configuration),\n+ 1368 _restart(configuration.get(\"restart\"))\n+ 1369 {}\n+1377 GeneralizedPCGSolver (std::shared_ptr> op,\n+ 1378 std::shared_ptr> sp,\n+ 1379 std::shared_ptr> prec,\n+ 1380 scalar_real_type reduction, int maxit, int verbose,\n+ 1381 int restart = 10) :\n+ 1382 IterativeSolver::IterativeSolver\n+(op,sp,prec,reduction,maxit,verbose),\n+ 1383 _restart(restart)\n+ 1384 {}\n 1385\n- 1386 //iterate over all rows and copy elements into their position in the\n-compressed array\n- 1387 for (size_type i=0; i::iterator it = perm.begin();\n- 1397 for (size_type* iit = begin; iit < begin + size; ++iit, ++it)\n- 1398 *it = iit;\n- 1399\n- 1400 //sort permutation array\n- 1401 std::sort(perm.begin(),perm.end(),PointerCompare());\n- 1402\n- 1403 //change row window pointer to their new positions\n- 1404 r[i].setindexptr(jiit);\n- 1405 r[i].setptr(aiit);\n- 1406\n- 1407 for (it = perm.begin(); it != perm.end(); ++it)\n- 1408 {\n- 1409 //check whether there are elements in the overflow area which take\n-precedence\n- 1410 while ((oit!=overflow.end()) && (oit->first < std::make_pair(i,**it)))\n- 1411 {\n- 1412 //check whether there is enough memory to write to\n- 1413 if (jiit > begin)\n- 1414 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n- 1415 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n- 1416 \"Please increase either the average number of entries per row or the\n-compressionBufferSize value.\"\n- 1417 );\n- 1418 //copy an element from the overflow area to the insertion position in a\n-and j\n- 1419 *jiit = oit->first.second;\n- 1420 ++jiit;\n- 1421 *aiit = oit->second;\n- 1422 ++aiit;\n- 1423 ++oit;\n- 1424 r[i].setsize(r[i].getsize()+1);\n- 1425 }\n- 1426\n- 1427 //check whether there is enough memory to write to\n- 1428 if (jiit > begin)\n- 1429 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n- 1430 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n- 1431 \"Please increase either the average number of entries per row or the\n-compressionBufferSize value.\"\n- 1432 );\n- 1433\n- 1434 //copy element from array\n- 1435 *jiit = **it;\n- 1436 ++jiit;\n- 1437 B* apos = *it - j_.get() + a;\n- 1438 *aiit = *apos;\n- 1439 ++aiit;\n- 1440 }\n+1391 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 1392 {\n+ 1393 Iteration iteration(*this, res);\n+ 1394 _prec->pre(x,b); // prepare preconditioner\n+ 1395 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n+ 1396\n+ 1397 std::vector > p(_restart);\n+ 1398 std::vector pp(_restart);\n+ 1399 X q(x); // a temporary vector\n+ 1400 X prec_res(x); // a temporary vector for preconditioner output\n+ 1401\n+ 1402 p[0].reset(new X(x));\n+ 1403\n+ 1404 real_type def = _sp->norm(b); // compute norm\n+ 1405 if(iteration.step(0, def)){\n+ 1406 _prec->post(x);\n+ 1407 return;\n+ 1408 }\n+ 1409 // some local variables\n+ 1410 field_type rho, lambda;\n+ 1411\n+ 1412 int i=0;\n+ 1413 int ii=0;\n+ 1414 // determine initial search direction\n+ 1415 *(p[0]) = 0; // clear correction\n+ 1416 _prec->apply(*(p[0]),b); // apply preconditioner\n+ 1417 rho = _sp->dot(*(p[0]),b); // orthogonalization\n+ 1418 _op->apply(*(p[0]),q); // q=Ap\n+ 1419 pp[0] = _sp->dot(*(p[0]),q); // scalar product\n+ 1420 lambda = rho/pp[0]; // minimization\n+ 1421 x.axpy(lambda,*(p[0])); // update solution\n+ 1422 b.axpy(-lambda,q); // update defect\n+ 1423\n+ 1424 // convergence test\n+ 1425 def=_sp->norm(b); // comp defect norm\n+ 1426 ++i;\n+ 1427 if(iteration.step(i, def)){\n+ 1428 _prec->post(x);\n+ 1429 return;\n+ 1430 }\n+ 1431\n+ 1432 while(i<_maxit) {\n+ 1433 // the loop\n+ 1434 int end=std::min(_restart, _maxit-i+1);\n+ 1435 for (ii=1; iiapply(prec_res,b); // apply preconditioner\n 1441\n- 1442 //copy remaining elements from the overflow area\n- 1443 while ((oit!=overflow.end()) && (oit->first.first == i))\n- 1444 {\n- 1445 //check whether there is enough memory to write to\n- 1446 if (jiit > begin)\n- 1447 DUNE_THROW(Dune::ImplicitModeCompressionBufferExhausted,\n- 1448 \"Allocated memory for BCRSMatrix exhausted during compress()!\"\n- 1449 \"Please increase either the average number of entries per row or the\n-compressionBufferSize value.\"\n- 1450 );\n- 1451\n- 1452 //copy and element from the overflow area to the insertion position in a\n-and j\n- 1453 *jiit = oit->first.second;\n- 1454 ++jiit;\n- 1455 *aiit = oit->second;\n- 1456 ++aiit;\n- 1457 ++oit;\n- 1458 r[i].setsize(r[i].getsize()+1);\n- 1459 }\n+ 1442 p[ii].reset(new X(prec_res));\n+ 1443 _op->apply(prec_res, q);\n+ 1444\n+ 1445 for(int j=0; jdot(q,*(p[j]))/pp[j];\n+ 1447 p[ii]->axpy(-rho, *(p[j]));\n+ 1448 }\n+ 1449\n+ 1450 // minimize in given search direction\n+ 1451 _op->apply(*(p[ii]),q); // q=Ap\n+ 1452 pp[ii] = _sp->dot(*(p[ii]),q); // scalar product\n+ 1453 rho = _sp->dot(*(p[ii]),b); // orthogonalization\n+ 1454 lambda = rho/pp[ii]; // minimization\n+ 1455 x.axpy(lambda,*(p[ii])); // update solution\n+ 1456 b.axpy(-lambda,q); // update defect\n+ 1457\n+ 1458 // convergence test\n+ 1459 def = _sp->norm(b); // comp defect norm\n 1460\n- 1461 // update maximum row size\n- 1462 if (r[i].getsize()>stats.maximum)\n- 1463 stats.maximum = r[i].getsize();\n- 1464 }\n- 1465\n- 1466 // overflow area may be cleared\n- 1467 overflow.clear();\n- 1468\n- 1469 //determine average number of entries and memory usage\n- 1470 std::ptrdiff_t diff = (r[n-1].getindexptr() + r[n-1].getsize() - j_.get\n-());\n- 1471 nnz_ = diff;\n- 1472 stats.avg = (double) (nnz_) / (double) n;\n- 1473 stats.mem_ratio = (double) (nnz_) / (double) allocationSize_;\n+ 1461 ++i;\n+ 1462 iteration.step(i, def);\n+ 1463 }\n+ 1464 if(res.converged)\n+ 1465 break;\n+ 1466 if(end==_restart) {\n+ 1467 *(p[0])=*(p[_restart-1]);\n+ 1468 pp[0]=pp[_restart-1];\n+ 1469 }\n+ 1470 }\n+ 1471\n+ 1472 // postprocess preconditioner\n+ 1473 _prec->post(x);\n 1474\n- 1475 //matrix is now built\n- 1476 ready = built;\n- 1477\n- 1478 return stats;\n- 1479 }\n- 1480\n- 1481 //===== vector space arithmetic\n- 1482\n-1484 BCRSMatrix& operator*=(const field_type& k)\n- 1485 {\n- 1486#ifdef DUNE_ISTL_WITH_CHECKING\n- 1487 if (ready != built)\n- 1488 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1489#endif\n- 1490\n- 1491 if (nnz_ > 0)\n- 1492 {\n- 1493 // process 1D array\n- 1494 for (size_type i=0; i::_op;\n+ 1479 using IterativeSolver::_prec;\n+ 1480 using IterativeSolver::_sp;\n+ 1481 using IterativeSolver::_reduction;\n+ 1482 using IterativeSolver::_maxit;\n+ 1483 using IterativeSolver::_verbose;\n+ 1484 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 1485 int _restart;\n+ 1486 };\n+1487 DUNE_REGISTER_ITERATIVE_SOLVER(\"generalizedpcgsolver\",\n+defaultIterativeSolverCreator());\n+ 1488\n+ 1500 template\n+1501 class RestartedFCGSolver : public IterativeSolver {\n+ 1502 public:\n+ 1503 using typename IterativeSolver::domain_type;\n+ 1504 using typename IterativeSolver::range_type;\n+ 1505 using typename IterativeSolver::field_type;\n+ 1506 using typename IterativeSolver::real_type;\n 1507\n- 1508 return *this;\n- 1509 }\n+ 1508 private:\n+ 1509 using typename IterativeSolver::scalar_real_type;\n 1510\n-1512 BCRSMatrix& operator/=(const field_type& k)\n- 1513 {\n- 1514#ifdef DUNE_ISTL_WITH_CHECKING\n- 1515 if (ready != built)\n- 1516 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1517#endif\n- 1518\n- 1519 if (nnz_ > 0)\n- 1520 {\n- 1521 // process 1D array\n- 1522 for (size_type i=0; ioperator+=(*j);\n- 1557 }\n- 1558\n- 1559 return *this;\n- 1560 }\n- 1561\n-1567 BCRSMatrix& operator-=(const BCRSMatrix& b)\n- 1568 {\n- 1569#ifdef DUNE_ISTL_WITH_CHECKING\n- 1570 if (ready != built || b.ready != built)\n- 1571 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1572 if(N()!=b.N() || M() != b.M())\n- 1573 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n- 1574#endif\n- 1575 RowIterator endi=end();\n- 1576 ConstRowIterator j=b.begin();\n- 1577 for (RowIterator i=begin(); i!=endi; ++i, ++j) {\n- 1578 i->operator-=(*j);\n- 1579 }\n- 1580\n- 1581 return *this;\n- 1582 }\n- 1583\n-1592 BCRSMatrix& axpy(field_type alpha, const BCRSMatrix& b)\n- 1593 {\n- 1594#ifdef DUNE_ISTL_WITH_CHECKING\n- 1595 if (ready != built || b.ready != built)\n- 1596 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1597 if(N()!=b.N() || M() != b.M())\n- 1598 DUNE_THROW(RangeError, \"Matrix sizes do not match!\");\n- 1599#endif\n- 1600 RowIterator endi=end();\n- 1601 ConstRowIterator j=b.begin();\n- 1602 for(RowIterator i=begin(); i!=endi; ++i, ++j)\n- 1603 i->axpy(alpha, *j);\n- 1604\n- 1605 return *this;\n- 1606 }\n- 1607\n- 1608 //===== linear maps\n- 1609\n- 1611 template\n-1612 void mv (const X& x, Y& y) const\n- 1613 {\n- 1614#ifdef DUNE_ISTL_WITH_CHECKING\n- 1615 if (ready != built)\n- 1616 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1617 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\n- 1618 \"Size mismatch: M: \" << N() << \"x\" << M() << \" x: \" << x.N());\n- 1619 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\n- 1620 \"Size mismatch: M: \" << N() << \"x\" << M() << \" y: \" << y.N());\n- 1621#endif\n- 1622 ConstRowIterator endi=end();\n- 1623 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1624 {\n- 1625 y[i.index()]=0;\n- 1626 ConstColIterator endj = (*i).end();\n- 1627 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1628 {\n- 1629 auto&& xj = Impl::asVector(x[j.index()]);\n- 1630 auto&& yi = Impl::asVector(y[i.index()]);\n- 1631 Impl::asMatrix(*j).umv(xj, yi);\n+ 1511 public:\n+ 1512 // don't shadow four-argument version of apply defined in the base class\n+ 1513 using IterativeSolver::apply;\n+1519 RestartedFCGSolver (const LinearOperator& op, Preconditioner&\n+prec,\n+ 1520 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) :\n+IterativeSolver(op, prec, reduction, maxit, verbose), _mmax(mmax)\n+ 1521 {\n+ 1522 }\n+ 1523\n+1529 RestartedFCGSolver (const LinearOperator& op, const ScalarProduct&\n+sp, Preconditioner& prec,\n+ 1530 scalar_real_type reduction, int maxit, int verbose, int mmax = 10) :\n+IterativeSolver(op, sp, prec, reduction, maxit, verbose), _mmax(mmax)\n+ 1531 {\n+ 1532 }\n+ 1533\n+1539 RestartedFCGSolver (std::shared_ptr> op,\n+ 1540 std::shared_ptr> sp,\n+ 1541 std::shared_ptr> prec,\n+ 1542 scalar_real_type reduction, int maxit, int verbose,\n+ 1543 int mmax = 10)\n+ 1544 : IterativeSolver(op, sp, prec, reduction, maxit, verbose), _mmax\n+(mmax)\n+ 1545 {}\n+ 1546\n+1559 RestartedFCGSolver (std::shared_ptr> op,\n+ 1560 std::shared_ptr> prec,\n+ 1561 const ParameterTree& config)\n+ 1562 : IterativeSolver(op, prec, config), _mmax(config.get(\"mmax\", 10))\n+ 1563 {}\n+ 1564\n+1565 RestartedFCGSolver (std::shared_ptr> op,\n+ 1566 std::shared_ptr> sp,\n+ 1567 std::shared_ptr> prec,\n+ 1568 const ParameterTree& config)\n+ 1569 : IterativeSolver(op, sp, prec, config), _mmax(config.get(\"mmax\",\n+10))\n+ 1570 {}\n+ 1571\n+1584 virtual void apply (X& x, X& b, InverseOperatorResult& res)\n+ 1585 {\n+ 1586 using rAlloc = ReboundAllocatorType;\n+ 1587 res.clear();\n+ 1588 Iteration iteration(*this,res);\n+ 1589 _prec->pre(x,b); // prepare preconditioner\n+ 1590 _op->applyscaleadd(-1,x,b); // overwrite b with defect\n+ 1591\n+ 1592 //arrays for interim values:\n+ 1593 std::vector d(_mmax+1, x); // array for directions\n+ 1594 std::vector Ad(_mmax+1, x); // array for Ad[i]\n+ 1595 std::vector ddotAd(_mmax+1,0); // array for \n+ 1596 X w(x);\n+ 1597\n+ 1598 real_type def = _sp->norm(b); // compute norm\n+ 1599 if(iteration.step(0, def)){\n+ 1600 _prec->post(x);\n+ 1601 return;\n+ 1602 }\n+ 1603\n+ 1604 // some local variables\n+ 1605 field_type alpha;\n+ 1606\n+ 1607 // the loop\n+ 1608 int i=1;\n+ 1609 int i_bounded=0;\n+ 1610 while(i<=_maxit && !res.converged) {\n+ 1611 for (; i_bounded <= _mmax && i<= _maxit; i_bounded++) {\n+ 1612 d[i_bounded] = 0; // reset search direction\n+ 1613 _prec->apply(d[i_bounded], b); // apply preconditioner\n+ 1614 w = d[i_bounded]; // copy of current d[i]\n+ 1615 // orthogonalization with previous directions\n+ 1616 orthogonalizations(i_bounded,Ad,w,ddotAd,d);\n+ 1617\n+ 1618 //saving interim values for future calculating\n+ 1619 _op->apply(d[i_bounded], Ad[i_bounded]); // save Ad[i]\n+ 1620 ddotAd[i_bounded]=_sp->dot(d[i_bounded],Ad[i_bounded]); // save \n+ 1621 alpha = _sp->dot(d[i_bounded], b)/ddotAd[i_bounded]; // /\n+ 1622\n+ 1623 //update solution and defect\n+ 1624 x.axpy(alpha, d[i_bounded]);\n+ 1625 b.axpy(-alpha, Ad[i_bounded]);\n+ 1626\n+ 1627 // convergence test\n+ 1628 def = _sp->norm(b); // comp defect norm\n+ 1629\n+ 1630 iteration.step(i, def);\n+ 1631 i++;\n 1632 }\n- 1633 }\n- 1634 }\n- 1635\n- 1637 template\n-1638 void umv (const X& x, Y& y) const\n- 1639 {\n- 1640#ifdef DUNE_ISTL_WITH_CHECKING\n- 1641 if (ready != built)\n- 1642 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1643 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1644 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1645#endif\n- 1646 ConstRowIterator endi=end();\n- 1647 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1648 {\n- 1649 ConstColIterator endj = (*i).end();\n- 1650 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1651 {\n- 1652 auto&& xj = Impl::asVector(x[j.index()]);\n- 1653 auto&& yi = Impl::asVector(y[i.index()]);\n- 1654 Impl::asMatrix(*j).umv(xj,yi);\n- 1655 }\n- 1656 }\n- 1657 }\n- 1658\n- 1660 template\n-1661 void mmv (const X& x, Y& y) const\n- 1662 {\n- 1663#ifdef DUNE_ISTL_WITH_CHECKING\n- 1664 if (ready != built)\n- 1665 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1666 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1667 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1668#endif\n- 1669 ConstRowIterator endi=end();\n- 1670 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1671 {\n- 1672 ConstColIterator endj = (*i).end();\n- 1673 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1674 {\n- 1675 auto&& xj = Impl::asVector(x[j.index()]);\n- 1676 auto&& yi = Impl::asVector(y[i.index()]);\n- 1677 Impl::asMatrix(*j).mmv(xj,yi);\n- 1678 }\n- 1679 }\n- 1680 }\n- 1681\n- 1683 template\n-1684 void usmv (F&& alpha, const X& x, Y& y) const\n- 1685 {\n- 1686#ifdef DUNE_ISTL_WITH_CHECKING\n- 1687 if (ready != built)\n- 1688 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1689 if (x.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1690 if (y.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1691#endif\n- 1692 ConstRowIterator endi=end();\n- 1693 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1694 {\n- 1695 ConstColIterator endj = (*i).end();\n- 1696 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1697 {\n- 1698 auto&& xj = Impl::asVector(x[j.index()]);\n- 1699 auto&& yi = Impl::asVector(y[i.index()]);\n- 1700 Impl::asMatrix(*j).usmv(alpha,xj,yi);\n- 1701 }\n- 1702 }\n- 1703 }\n- 1704\n- 1706 template\n-1707 void mtv (const X& x, Y& y) const\n- 1708 {\n- 1709#ifdef DUNE_ISTL_WITH_CHECKING\n- 1710 if (ready != built)\n- 1711 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1712 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1713 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1714#endif\n- 1715 for(size_type i=0; i\n-1722 void umtv (const X& x, Y& y) const\n- 1723 {\n- 1724#ifdef DUNE_ISTL_WITH_CHECKING\n- 1725 if (ready != built)\n- 1726 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1727 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1728 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1729#endif\n- 1730 ConstRowIterator endi=end();\n- 1731 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1732 {\n- 1733 ConstColIterator endj = (*i).end();\n- 1734 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1735 {\n- 1736 auto&& xi = Impl::asVector(x[i.index()]);\n- 1737 auto&& yj = Impl::asVector(y[j.index()]);\n- 1738 Impl::asMatrix(*j).umtv(xi,yj);\n- 1739 }\n- 1740 }\n- 1741 }\n- 1742\n- 1744 template\n-1745 void mmtv (const X& x, Y& y) const\n- 1746 {\n- 1747#ifdef DUNE_ISTL_WITH_CHECKING\n- 1748 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1749 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1750#endif\n- 1751 ConstRowIterator endi=end();\n- 1752 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1753 {\n- 1754 ConstColIterator endj = (*i).end();\n- 1755 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1756 {\n- 1757 auto&& xi = Impl::asVector(x[i.index()]);\n- 1758 auto&& yj = Impl::asVector(y[j.index()]);\n- 1759 Impl::asMatrix(*j).mmtv(xi,yj);\n- 1760 }\n- 1761 }\n- 1762 }\n- 1763\n- 1765 template\n-1766 void usmtv (const field_type& alpha, const X& x, Y& y) const\n- 1767 {\n- 1768#ifdef DUNE_ISTL_WITH_CHECKING\n- 1769 if (ready != built)\n- 1770 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1771 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1772 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1773#endif\n- 1774 ConstRowIterator endi=end();\n- 1775 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1776 {\n- 1777 ConstColIterator endj = (*i).end();\n- 1778 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1779 {\n- 1780 auto&& xi = Impl::asVector(x[i.index()]);\n- 1781 auto&& yj = Impl::asVector(y[j.index()]);\n- 1782 Impl::asMatrix(*j).usmtv(alpha,xi,yj);\n- 1783 }\n- 1784 }\n- 1785 }\n- 1786\n- 1788 template\n-1789 void umhv (const X& x, Y& y) const\n- 1790 {\n- 1791#ifdef DUNE_ISTL_WITH_CHECKING\n- 1792 if (ready != built)\n- 1793 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1794 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1795 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1796#endif\n- 1797 ConstRowIterator endi=end();\n- 1798 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1799 {\n- 1800 ConstColIterator endj = (*i).end();\n- 1801 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1802 {\n- 1803 auto&& xi = Impl::asVector(x[i.index()]);\n- 1804 auto&& yj = Impl::asVector(y[j.index()]);\n- 1805 Impl::asMatrix(*j).umhv(xi,yj);\n- 1806 }\n- 1807 }\n- 1808 }\n- 1809\n- 1811 template\n-1812 void mmhv (const X& x, Y& y) const\n- 1813 {\n- 1814#ifdef DUNE_ISTL_WITH_CHECKING\n- 1815 if (ready != built)\n- 1816 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1817 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1818 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1819#endif\n- 1820 ConstRowIterator endi=end();\n- 1821 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1822 {\n- 1823 ConstColIterator endj = (*i).end();\n- 1824 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1825 {\n- 1826 auto&& xi = Impl::asVector(x[i.index()]);\n- 1827 auto&& yj = Impl::asVector(y[j.index()]);\n- 1828 Impl::asMatrix(*j).mmhv(xi,yj);\n- 1829 }\n- 1830 }\n- 1831 }\n- 1832\n- 1834 template\n-1835 void usmhv (const field_type& alpha, const X& x, Y& y) const\n- 1836 {\n- 1837#ifdef DUNE_ISTL_WITH_CHECKING\n- 1838 if (ready != built)\n- 1839 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1840 if (x.N()!=N()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1841 if (y.N()!=M()) DUNE_THROW(BCRSMatrixError,\"index out of range\");\n- 1842#endif\n- 1843 ConstRowIterator endi=end();\n- 1844 for (ConstRowIterator i=this->begin(); i!=endi; ++i)\n- 1845 {\n- 1846 ConstColIterator endj = (*i).end();\n- 1847 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)\n- 1848 {\n- 1849 auto&& xi = Impl::asVector(x[i.index()]);\n- 1850 auto&& yj = Impl::asVector(y[j.index()]);\n- 1851 Impl::asMatrix(*j).usmhv(alpha,xi,yj);\n- 1852 }\n- 1853 }\n- 1854 }\n- 1855\n- 1856\n- 1857 //===== norms\n- 1858\n-1860 typename FieldTraits::real_type frobenius_norm2 () const\n- 1861 {\n- 1862#ifdef DUNE_ISTL_WITH_CHECKING\n- 1863 if (ready != built)\n- 1864 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1865#endif\n- 1866\n- 1867 typename FieldTraits::real_type sum=0;\n- 1868\n- 1869 for (auto&& row : (*this))\n- 1870 for (auto&& entry : row)\n- 1871 sum += Impl::asMatrix(entry).frobenius_norm2();\n- 1872\n- 1873 return sum;\n- 1874 }\n- 1875\n-1877 typename FieldTraits::real_type frobenius_norm () const\n- 1878 {\n- 1879 return sqrt(frobenius_norm2());\n- 1880 }\n- 1881\n- 1883 template ::value, int>::type = 0>\n-1885 typename FieldTraits::real_type infinity_norm() const {\n- 1886 if (ready != built)\n- 1887 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1888\n- 1889 using real_type = typename FieldTraits::real_type;\n- 1890 using std::max;\n- 1891\n- 1892 real_type norm = 0;\n- 1893 for (auto const &x : *this) {\n- 1894 real_type sum = 0;\n- 1895 for (auto const &y : x)\n- 1896 sum += Impl::asMatrix(y).infinity_norm();\n- 1897 norm = max(sum, norm);\n- 1898 }\n- 1899 return norm;\n- 1900 }\n- 1901\n- 1903 template ::value, int>::type = 0>\n-1905 typename FieldTraits::real_type infinity_norm_real() const {\n- 1906 if (ready != built)\n- 1907 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1908\n- 1909 using real_type = typename FieldTraits::real_type;\n- 1910 using std::max;\n- 1911\n- 1912 real_type norm = 0;\n- 1913 for (auto const &x : *this) {\n- 1914 real_type sum = 0;\n- 1915 for (auto const &y : x)\n- 1916 sum += Impl::asMatrix(y).infinity_norm_real();\n- 1917 norm = max(sum, norm);\n- 1918 }\n- 1919 return norm;\n- 1920 }\n- 1921\n- 1923 template ::value, int>::type = 0>\n-1925 typename FieldTraits::real_type infinity_norm() const {\n- 1926 if (ready != built)\n- 1927 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1928\n- 1929 using real_type = typename FieldTraits::real_type;\n- 1930 using std::max;\n- 1931\n- 1932 real_type norm = 0;\n- 1933 real_type isNaN = 1;\n- 1934 for (auto const &x : *this) {\n- 1935 real_type sum = 0;\n- 1936 for (auto const &y : x)\n- 1937 sum += Impl::asMatrix(y).infinity_norm();\n- 1938 norm = max(sum, norm);\n- 1939 isNaN += sum;\n- 1940 }\n- 1941\n- 1942 return norm * (isNaN / isNaN);\n- 1943 }\n- 1944\n- 1946 template ::value, int>::type = 0>\n-1948 typename FieldTraits::real_type infinity_norm_real() const {\n- 1949 if (ready != built)\n- 1950 DUNE_THROW(BCRSMatrixError,\"You can only call arithmetic operations on\n-fully built BCRSMatrix instances\");\n- 1951\n- 1952 using real_type = typename FieldTraits::real_type;\n- 1953 using std::max;\n- 1954\n- 1955 real_type norm = 0;\n- 1956 real_type isNaN = 1;\n- 1957\n- 1958 for (auto const &x : *this) {\n- 1959 real_type sum = 0;\n- 1960 for (auto const &y : x)\n- 1961 sum += Impl::asMatrix(y).infinity_norm_real();\n- 1962 norm = max(sum, norm);\n- 1963 isNaN += sum;\n- 1964 }\n- 1965\n- 1966 return norm * (isNaN / isNaN);\n- 1967 }\n- 1968\n- 1969 //===== sizes\n- 1970\n-1972 size_type N () const\n- 1973 {\n- 1974 return n;\n- 1975 }\n- 1976\n-1978 size_type M () const\n- 1979 {\n- 1980 return m;\n- 1981 }\n- 1982\n-1984 size_type nonzeroes () const\n- 1985 {\n- 1986 // in case of row-wise allocation\n- 1987 if( nnz_ <= 0 )\n- 1988 nnz_ = std::accumulate( begin(), end(), size_type( 0 ), [] ( size_type s,\n-const row_type &row ) { return s+row.getsize(); } );\n- 1989 return nnz_;\n- 1990 }\n- 1991\n-1993 BuildStage buildStage() const\n- 1994 {\n- 1995 return ready;\n- 1996 }\n- 1997\n-1999 BuildMode buildMode() const\n- 2000 {\n- 2001 return build_mode;\n- 2002 }\n- 2003\n- 2004 //===== query\n- 2005\n-2007 bool exists (size_type i, size_type j) const\n- 2008 {\n- 2009#ifdef DUNE_ISTL_WITH_CHECKING\n- 2010 if (i<0 || i>=n) DUNE_THROW(BCRSMatrixError,\"row index out of range\");\n- 2011 if (j<0 || j>=m) DUNE_THROW(BCRSMatrixError,\"column index out of range\");\n- 2012#endif\n- 2013 return (r[i].size() && r[i].find(j) != r[i].end());\n- 2014 }\n- 2015\n- 2016\n- 2017 protected:\n- 2018 // state information\n-2019 BuildMode build_mode; // row wise or whole matrix\n-2020 BuildStage ready; // indicate the stage the matrix building is in\n- 2021\n- 2022 // The allocator used for memory management\n-2023 typename std::allocator_traits::template rebind_alloc allocator_;\n- 2024\n-2025 typename std::allocator_traits::template rebind_alloc\n-rowAllocator_;\n- 2026\n-2027 typename std::allocator_traits::template rebind_alloc\n-sizeAllocator_;\n- 2028\n- 2029 // size of the matrix\n-2030 size_type n; // number of rows\n-2031 size_type m; // number of columns\n-2032 mutable size_type nnz_; // number of nonzeroes contained in the matrix\n-2033 size_type allocationSize_; //allocated size of a and j arrays, except in\n-implicit mode: nnz_==allocationsSize_\n- 2034 // zero means that memory is allocated separately for each row.\n- 2035\n- 2036 // the rows are dynamically allocated\n-2037 row_type* r; // [n] the individual rows having pointers into a,j arrays\n- 2038\n- 2039 // dynamically allocated memory\n-2040 B* a; // [allocationSize] non-zero entries of the matrix in row-wise\n-ordering\n- 2041 // If a single array of column indices is used, it can be shared\n- 2042 // between different matrices with the same sparsity pattern\n-2043 std::shared_ptr j_; // [allocationSize] column indices of\n-entries\n- 2044\n- 2045 // additional data is needed in implicit buildmode\n-2046 size_type avg;\n-2047 double compressionBufferSize_;\n- 2048\n-2049 typedef std::map, B> OverflowType;\n-2050 OverflowType overflow;\n- 2051\n-2052 void setWindowPointers(ConstRowIterator row)\n- 2053 {\n- 2054 row_type current_row(a,j_.get(),0); // Pointers to current row data\n- 2055 for (size_type i=0; igetsize();\n- 2058\n- 2059 if (s>0) {\n- 2060 // setup pointers and size\n- 2061 r[i].set(s,current_row.getptr(), current_row.getindexptr());\n- 2062 // update pointer for next row\n- 2063 current_row.setptr(current_row.getptr()+s);\n- 2064 current_row.setindexptr(current_row.getindexptr()+s);\n- 2065 } else{\n- 2066 // empty row\n- 2067 r[i].set(0,nullptr,nullptr);\n- 2068 }\n- 2069 }\n- 2070 }\n- 2071\n- 2073\n-2077 void setColumnPointers(ConstRowIterator row)\n- 2078 {\n- 2079 size_type* jptr = j_.get();\n- 2080 for (size_type i=0; igetsize();\n- 2083\n- 2084 if (s>0) {\n- 2085 // setup pointers and size\n- 2086 r[i].setsize(s);\n- 2087 r[i].setindexptr(jptr);\n- 2088 } else{\n- 2089 // empty row\n- 2090 r[i].set(0,nullptr,nullptr);\n- 2091 }\n- 2092\n- 2093 // advance position in global array\n- 2094 jptr += s;\n- 2095 }\n- 2096 }\n- 2097\n- 2099\n-2103 void setDataPointers()\n- 2104 {\n- 2105 B* aptr = a;\n- 2106 for (size_type i=0; i 0) {\n- 2109 // setup pointers and size\n- 2110 r[i].setptr(aptr);\n- 2111 } else{\n- 2112 // empty row\n- 2113 r[i].set(0,nullptr,nullptr);\n- 2114 }\n- 2115\n- 2116 // advance position in global array\n- 2117 aptr += r[i].getsize();\n- 2118 }\n- 2119 }\n- 2120\n-2122 void copyWindowStructure(const BCRSMatrix& Mat)\n- 2123 {\n- 2124 setWindowPointers(Mat.begin());\n- 2125\n- 2126 // copy data\n- 2127 for (size_type i=0; i0)\n- 2146 {\n- 2147 // a,j_ have been allocated as one long vector\n- 2148 j_.reset();\n- 2149 if (a)\n- 2150 {\n- 2151 for(B *aiter=a+(allocationSize_-1), *aend=a-1; aiter!=aend; --aiter)\n- 2152 std::allocator_traits::destroy(allocator_, aiter);\n- 2153 allocator_.deallocate(a,allocationSize_);\n- 2154 a = nullptr;\n- 2155 }\n- 2156 }\n- 2157 else if (r)\n- 2158 {\n- 2159 // check if memory for rows have been allocated individually\n- 2160 for (size_type i=0; i0)\n- 2162 {\n- 2163 for (B *col=r[i].getptr()+(r[i].getsize()-1),\n- 2164 *colend = r[i].getptr()-1; col!=colend; --col) {\n- 2165 std::allocator_traits::destroy(allocator_, col);\n- 2166 }\n- 2167 sizeAllocator_.deallocate(r[i].getindexptr(),1);\n- 2168 allocator_.deallocate(r[i].getptr(),1);\n- 2169 // clear out row data in case we don't want to deallocate the rows\n- 2170 // otherwise we might run into a double free problem here later\n- 2171 r[i].set(0,nullptr,nullptr);\n- 2172 }\n- 2173 }\n- 2174\n- 2175 // deallocate the rows\n- 2176 if (n>0 && deallocateRows && r) {\n- 2177 for(row_type *riter=r+(n-1), *rend=r-1; riter!=rend; --riter)\n- 2178 std::allocator_traits::destroy(rowAllocator_,\n-riter);\n- 2179 rowAllocator_.deallocate(r,n);\n- 2180 r = nullptr;\n- 2181 }\n- 2182\n- 2183 // Mark matrix as not built at all.\n- 2184 ready=notAllocated;\n- 2185\n- 2186 }\n- 2187\n-2205 void allocate(size_type rows, size_type columns, size_type allocationSize,\n-bool allocateRows, bool allocate_data)\n- 2206 {\n- 2207 // Store size\n- 2208 n = rows;\n- 2209 m = columns;\n- 2210 nnz_ = allocationSize;\n- 2211 allocationSize_ = allocationSize;\n- 2212\n- 2213 // allocate rows\n- 2214 if(allocateRows) {\n- 2215 if (n>0) {\n- 2216 if (r)\n- 2217 DUNE_THROW(InvalidStateException,\"Rows have already been allocated,\n-cannot allocate a second time\");\n- 2218 r = rowAllocator_.allocate(rows);\n- 2219 // initialize row entries\n- 2220 for(row_type* ri=r; ri!=r+rows; ++ri)\n- 2221 std::allocator_traits::construct(rowAllocator_,\n-ri, row_type());\n- 2222 }else{\n- 2223 r = 0;\n- 2224 }\n- 2225 }\n- 2226\n- 2227 // allocate a and j_ array\n- 2228 if (allocate_data)\n- 2229 allocateData();\n- 2230 // allocate column indices only if not yet present (enable sharing)\n- 2231 if (allocationSize_>0) {\n- 2232 // we copy allocator and size to the deleter since _j may outlive this\n-class\n- 2233 if (!j_.get())\n- 2234 j_.reset(sizeAllocator_.allocate(allocationSize_),\n- 2235 [alloc = sizeAllocator_, size = allocationSize_](auto ptr) mutable {\n- 2236 alloc.deallocate(ptr, size);\n- 2237 });\n- 2238 }else{\n- 2239 j_.reset();\n- 2240 }\n- 2241\n- 2242 // Mark the matrix as not built.\n- 2243 ready = building;\n- 2244 }\n- 2245\n-2246 void allocateData()\n- 2247 {\n- 2248 if (a)\n- 2249 DUNE_THROW(InvalidStateException,\"Cannot allocate data array (already\n-allocated)\");\n- 2250 if (allocationSize_>0) {\n- 2251 a = allocator_.allocate(allocationSize_);\n- 2252 // use placement new to call constructor that allocates\n- 2253 // additional memory.\n- 2254 new (a) B[allocationSize_];\n- 2255 } else {\n- 2256 a = nullptr;\n- 2257 }\n- 2258 }\n- 2259\n-2265 void implicit_allocate(size_type _n, size_type _m)\n- 2266 {\n- 2267 if (build_mode != implicit)\n- 2268 DUNE_THROW(InvalidStateException,\"implicit_allocate() may only be called\n-in implicit build mode\");\n- 2269 if (ready != notAllocated)\n- 2270 DUNE_THROW(InvalidStateException,\"memory has already been allocated\");\n- 2271\n- 2272 // check to make sure the user has actually set the parameters\n- 2273 if (compressionBufferSize_ < 0)\n- 2274 DUNE_THROW(InvalidStateException,\"You have to set the implicit build mode\n-parameters before starting to build the matrix\");\n- 2275 //calculate size of overflow region, add buffer for row sort!\n- 2276 size_type osize = (size_type) (_n*avg)*compressionBufferSize_ + 4*avg;\n- 2277 allocationSize_ = _n*avg + osize;\n- 2278\n- 2279 allocate(_n, _m, allocationSize_,true,true);\n- 2280\n- 2281 //set row pointers correctly\n- 2282 size_type* jptr = j_.get() + osize;\n- 2283 B* aptr = a + osize;\n- 2284 for (size_type i=0; i\n-2297 struct FieldTraits< BCRSMatrix >\n- 2298 {\n-2299 using field_type = typename BCRSMatrix::field_type;\n-2300 using real_type = typename FieldTraits::real_type;\n- 2301 };\n- 2302\n- 2305} // end namespace\n- 2306\n- 2307#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n-matrixutils.hh\n-Some handy generic functions for ISTL matrices.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n+ 1633 //restart: exchange first and last stored values\n+ 1634 cycle(Ad,d,ddotAd,i_bounded);\n+ 1635 }\n+ 1636\n+ 1637 //correct i which is wrong if convergence was not achieved.\n+ 1638 i=std::min(_maxit,i);\n+ 1639\n+ 1640 _prec->post(x); // postprocess preconditioner\n+ 1641 }\n+ 1642\n+ 1643 private:\n+ 1644 //This function is called every iteration to orthogonalize against the\n+last search directions\n+ 1645 virtual void orthogonalizations(const int& i_bounded,const std::\n+vector& Ad, const X& w, const std::\n+vector>& ddotAd,std::vector&\n+d) {\n+ 1646 // The RestartedFCGSolver uses only values with lower array index;\n+ 1647 for (int k = 0; k < i_bounded; k++) {\n+ 1648 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= </>d[k]\n+ 1649 }\n+ 1650 }\n+ 1651\n+ 1652 // This function is called every mmax iterations to handle limited array\n+sizes.\n+ 1653 virtual void cycle(std::vector& Ad,std::vector& d,std::\n+vector >& ddotAd,int& i_bounded)\n+{\n+ 1654 // Reset loop index and exchange the first and last arrays\n+ 1655 i_bounded = 1;\n+ 1656 std::swap(Ad[0], Ad[_mmax]);\n+ 1657 std::swap(d[0], d[_mmax]);\n+ 1658 std::swap(ddotAd[0], ddotAd[_mmax]);\n+ 1659 }\n+ 1660\n+ 1661 protected:\n+1662 int _mmax;\n+ 1663 using IterativeSolver::_op;\n+ 1664 using IterativeSolver::_prec;\n+ 1665 using IterativeSolver::_sp;\n+ 1666 using IterativeSolver::_reduction;\n+ 1667 using IterativeSolver::_maxit;\n+ 1668 using IterativeSolver::_verbose;\n+1669 using Iteration = typename IterativeSolver::template\n+Iteration;\n+ 1670 };\n+1671 DUNE_REGISTER_ITERATIVE_SOLVER(\"restartedfcgsolver\",\n+defaultIterativeSolverCreator());\n+ 1672\n+ 1679 template\n+1680 class CompleteFCGSolver : public RestartedFCGSolver {\n+ 1681 public:\n+ 1682 using typename RestartedFCGSolver::domain_type;\n+ 1683 using typename RestartedFCGSolver::range_type;\n+ 1684 using typename RestartedFCGSolver::field_type;\n+ 1685 using typename RestartedFCGSolver::real_type;\n+ 1686\n+ 1687 // copy base class constructors\n+ 1688 using RestartedFCGSolver::RestartedFCGSolver;\n+ 1689\n+ 1690 // don't shadow four-argument version of apply defined in the base class\n+ 1691 using RestartedFCGSolver::apply;\n+ 1692\n+ 1693 // just a minor part of the RestartedFCGSolver apply method will be\n+modified\n+1694 virtual void apply (X& x, X& b, InverseOperatorResult& res) override {\n+ 1695 // reset limiter of orthogonalization loop\n+ 1696 _k_limit = 0;\n+ 1697 this->RestartedFCGSolver::apply(x,b,res);\n+ 1698 };\n+ 1699\n+ 1700 private:\n+ 1701 // This function is called every iteration to orthogonalize against the\n+last search directions.\n+ 1702 virtual void orthogonalizations(const int& i_bounded,const std::\n+vector& Ad, const X& w, const std::\n+vector>& ddotAd,std::vector&\n+d) override {\n+ 1703 // This FCGSolver uses values with higher array indexes too, if existent.\n+ 1704 for (int k = 0; k < _k_limit; k++) {\n+ 1705 if(i_bounded!=k)\n+ 1706 d[i_bounded].axpy(-_sp->dot(Ad[k], w) / ddotAd[k], d[k]); // d[i] -= </>d[k]\n+ 1707 }\n+ 1708 // The loop limit increase, if array is not completely filled.\n+ 1709 if(_k_limit<=i_bounded)\n+ 1710 _k_limit++;\n+ 1711\n+ 1712 };\n+ 1713\n+ 1714 // This function is called every mmax iterations to handle limited array\n+sizes.\n+ 1715 virtual void cycle(std::vector& Ad, [[maybe_unused]] std::vector&\n+d, [[maybe_unused]] std::vector\n+>& ddotAd,int& i_bounded) override {\n+ 1716 // Only the loop index i_bounded return to 0, if it reached mmax.\n+ 1717 i_bounded = 0;\n+ 1718 // Now all arrays are filled and the loop in void orthogonalizations can\n+use the whole arrays.\n+ 1719 _k_limit = Ad.size();\n+ 1720 };\n+ 1721\n+ 1722 int _k_limit = 0;\n+ 1723\n+ 1724 protected:\n+ 1725 using RestartedFCGSolver::_mmax;\n+ 1726 using RestartedFCGSolver::_op;\n+ 1727 using RestartedFCGSolver::_prec;\n+ 1728 using RestartedFCGSolver::_sp;\n+ 1729 using RestartedFCGSolver::_reduction;\n+ 1730 using RestartedFCGSolver::_maxit;\n+ 1731 using RestartedFCGSolver::_verbose;\n+ 1732 };\n+1733 DUNE_REGISTER_ITERATIVE_SOLVER(\"completefcgsolver\",\n+defaultIterativeSolverCreator());\n+ 1735} // end namespace\n+ 1736\n+ 1737#endif\n+scalarproducts.hh\n+Define base class for scalar product and norm.\n+solverregistry.hh\n+solver.hh\n+Define general, extensible interface for inverse operators.\n+bcrsmatrix.hh\n+Implementation of the BCRSMatrix class.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n+allocator.hh\n+preconditioner.hh\n istlexception.hh\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+arpackpp.hh\n+Dune::DUNE_REGISTER_ITERATIVE_SOLVER\n+DUNE_REGISTER_ITERATIVE_SOLVER(\"loopsolver\", defaultIterativeSolverCreator<\n+Dune::LoopSolver >())\n Dune\n Definition: allocator.hh:11\n Dune::get\n PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n Definition: dependency.hh:293\n-Dune::MatrixDimension\n-Definition: matrixutils.hh:211\n-Dune::CompressionStatistics\n-Statistics about compression achieved in implicit mode.\n-Definition: bcrsmatrix.hh:88\n-Dune::CompressionStatistics::overflow_total\n-size_type overflow_total\n-total number of elements written to the overflow area during construction.\n-Definition: bcrsmatrix.hh:94\n-Dune::CompressionStatistics::maximum\n-size_type maximum\n-maximum number of non-zeroes per row.\n-Definition: bcrsmatrix.hh:92\n-Dune::CompressionStatistics::avg\n-double avg\n-average number of non-zeroes per row.\n-Definition: bcrsmatrix.hh:90\n-Dune::CompressionStatistics::mem_ratio\n-double mem_ratio\n-fraction of wasted memory resulting from non-used overflow area.\n-Definition: bcrsmatrix.hh:99\n-Dune::ImplicitMatrixBuilder\n-A wrapper for uniform access to the BCRSMatrix during and after the build stage\n-in implicit build mod...\n-Definition: bcrsmatrix.hh:117\n-Dune::ImplicitMatrixBuilder::block_type\n-Matrix::block_type block_type\n-The block_type of the underlying matrix.\n-Definition: bcrsmatrix.hh:125\n-Dune::ImplicitMatrixBuilder::ImplicitMatrixBuilder\n-ImplicitMatrixBuilder(Matrix &m)\n-Creates an ImplicitMatrixBuilder for matrix m.\n-Definition: bcrsmatrix.hh:170\n-Dune::ImplicitMatrixBuilder::Matrix\n-M_ Matrix\n-The underlying matrix.\n-Definition: bcrsmatrix.hh:122\n-Dune::ImplicitMatrixBuilder::ImplicitMatrixBuilder\n-ImplicitMatrixBuilder(Matrix &m, size_type rows, size_type cols, size_type\n-avg_cols_per_row, double overflow_fraction)\n-Sets up matrix m for implicit construction using the given parameters and\n-creates an ImplicitBmatrixu...\n-Definition: bcrsmatrix.hh:194\n-Dune::ImplicitMatrixBuilder::M\n-size_type M() const\n-The number of columns in the matrix.\n-Definition: bcrsmatrix.hh:217\n-Dune::ImplicitMatrixBuilder::size_type\n-Matrix::size_type size_type\n-The size_type of the underlying matrix.\n-Definition: bcrsmatrix.hh:128\n-Dune::ImplicitMatrixBuilder::operator[]\n-row_object operator[](size_type i) const\n-Returns a proxy for entries in row i.\n-Definition: bcrsmatrix.hh:205\n-Dune::ImplicitMatrixBuilder::N\n-size_type N() const\n-The number of rows in the matrix.\n-Definition: bcrsmatrix.hh:211\n-Dune::ImplicitMatrixBuilder::row_object\n-Proxy row object for entry access.\n-Definition: bcrsmatrix.hh:137\n-Dune::ImplicitMatrixBuilder::row_object::operator[]\n-block_type & operator[](size_type j) const\n-Returns entry in column j.\n-Definition: bcrsmatrix.hh:142\n+Dune::ReboundAllocatorType\n+typename std::allocator_traits< typename AllocatorTraits< T >::type >::template\n+rebind_alloc< X > ReboundAllocatorType\n+Definition: allocator.hh:37\n+Dune::MatrixMarketImpl::conj\n+std::enable_if_t::value, T > conj(const T &r)\n+Definition: matrixmarket.hh:733\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: bcrsmatrix.hh:488\n-Dune::BCRSMatrix::rowAllocator_\n-std::allocator_traits< A >::template rebind_alloc< row_type > rowAllocator_\n-Definition: bcrsmatrix.hh:2025\n-Dune::BCRSMatrix::exists\n-bool exists(size_type i, size_type j) const\n-return true if (i,j) is in pattern\n-Definition: bcrsmatrix.hh:2007\n-Dune::BCRSMatrix::buildStage\n-BuildStage buildStage() const\n-The current build stage of the matrix.\n-Definition: bcrsmatrix.hh:1993\n-Dune::BCRSMatrix::begin\n-Iterator begin()\n-Get iterator to first row.\n-Definition: bcrsmatrix.hh:675\n-Dune::BCRSMatrix::CreateIterator\n-friend class CreateIterator\n-allow CreateIterator to access internal data\n-Definition: bcrsmatrix.hh:1094\n-Dune::BCRSMatrix::copyWindowStructure\n-void copyWindowStructure(const BCRSMatrix &Mat)\n-Copy the window structure from another matrix.\n-Definition: bcrsmatrix.hh:2122\n-Dune::BCRSMatrix::entry\n-B & entry(size_type row, size_type col)\n-Returns reference to entry (row,col) of the matrix.\n-Definition: bcrsmatrix.hh:1296\n-Dune::BCRSMatrix::mmhv\n-void mmhv(const X &x, Y &y) const\n-y -= A^H x\n-Definition: bcrsmatrix.hh:1812\n-Dune::BCRSMatrix::usmhv\n-void usmhv(const field_type &alpha, const X &x, Y &y) const\n-y += alpha A^H x\n-Definition: bcrsmatrix.hh:1835\n-Dune::BCRSMatrix::umtv\n-void umtv(const X &x, Y &y) const\n-y += A^T x\n-Definition: bcrsmatrix.hh:1722\n-Dune::BCRSMatrix::compressionBufferSize_\n-double compressionBufferSize_\n-Definition: bcrsmatrix.hh:2047\n-Dune::BCRSMatrix::m\n-size_type m\n-Definition: bcrsmatrix.hh:2031\n-Dune::BCRSMatrix::const_iterator\n-RealRowIterator< const row_type > const_iterator\n-The const iterator over the matrix rows.\n-Definition: bcrsmatrix.hh:707\n-Dune::BCRSMatrix::blocklevel\n-static constexpr unsigned int blocklevel\n-increment block level counter\n-Definition: bcrsmatrix.hh:507\n-Dune::BCRSMatrix::allocate\n-void allocate(size_type rows, size_type columns, size_type allocationSize, bool\n-allocateRows, bool allocate_data)\n-Allocate memory for the matrix structure.\n-Definition: bcrsmatrix.hh:2205\n-Dune::BCRSMatrix::axpy\n-BCRSMatrix & axpy(field_type alpha, const BCRSMatrix &b)\n-Add the scaled entries of another matrix to this one.\n-Definition: bcrsmatrix.hh:1592\n-Dune::BCRSMatrix::infinity_norm_real\n-FieldTraits< ft >::real_type infinity_norm_real() const\n-simplified infinity norm (uses Manhattan norm for complex values)\n-Definition: bcrsmatrix.hh:1905\n-Dune::BCRSMatrix::~BCRSMatrix\n-~BCRSMatrix()\n-destructor\n-Definition: bcrsmatrix.hh:824\n-Dune::BCRSMatrix::allocateData\n-void allocateData()\n-Definition: bcrsmatrix.hh:2246\n-Dune::BCRSMatrix::deallocate\n-void deallocate(bool deallocateRows=true)\n-deallocate memory of the matrix.\n-Definition: bcrsmatrix.hh:2139\n-Dune::BCRSMatrix::RowIterator\n-Iterator RowIterator\n-rename the iterators for easier access\n-Definition: bcrsmatrix.hh:701\n-Dune::BCRSMatrix::operator[]\n-row_type & operator[](size_type i)\n-random access to the rows\n-Definition: bcrsmatrix.hh:549\n-Dune::BCRSMatrix::BCRSMatrix\n-BCRSMatrix()\n-an empty matrix\n-Definition: bcrsmatrix.hh:749\n-Dune::BCRSMatrix::endrowsizes\n-void endrowsizes()\n-indicate that size of all rows is defined\n-Definition: bcrsmatrix.hh:1149\n-Dune::BCRSMatrix::incrementrowsize\n-void incrementrowsize(size_type i, size_type s=1)\n-increment size of row i by s (1 by default)\n-Definition: bcrsmatrix.hh:1138\n-Dune::BCRSMatrix::mtv\n-void mtv(const X &x, Y &y) const\n-y = A^T x\n-Definition: bcrsmatrix.hh:1707\n-Dune::BCRSMatrix::umhv\n-void umhv(const X &x, Y &y) const\n-y += A^H x\n-Definition: bcrsmatrix.hh:1789\n-Dune::BCRSMatrix::nonzeroes\n-size_type nonzeroes() const\n-number of blocks that are stored (the number of blocks that possibly are\n-nonzero)\n-Definition: bcrsmatrix.hh:1984\n-Dune::BCRSMatrix::allocationSize_\n-size_type allocationSize_\n-Definition: bcrsmatrix.hh:2033\n-Dune::BCRSMatrix::ConstRowIterator\n-ConstIterator ConstRowIterator\n-rename the const row iterator for easier access\n-Definition: bcrsmatrix.hh:738\n-Dune::BCRSMatrix::ready\n-BuildStage ready\n-Definition: bcrsmatrix.hh:2020\n-Dune::BCRSMatrix::build_mode\n-BuildMode build_mode\n-Definition: bcrsmatrix.hh:2019\n-Dune::BCRSMatrix::setrowsize\n-void setrowsize(size_type i, size_type s)\n-Set number of indices in row i to s.\n-Definition: bcrsmatrix.hh:1117\n-Dune::BCRSMatrix::Iterator\n-RealRowIterator< row_type > Iterator\n-Definition: bcrsmatrix.hh:672\n-Dune::BCRSMatrix::nnz_\n-size_type nnz_\n-Definition: bcrsmatrix.hh:2032\n-Dune::BCRSMatrix::operator*=\n-BCRSMatrix & operator*=(const field_type &k)\n-vector space multiplication with scalar\n-Definition: bcrsmatrix.hh:1484\n-Dune::BCRSMatrix::sizeAllocator_\n-std::allocator_traits< A >::template rebind_alloc< size_type > sizeAllocator_\n-Definition: bcrsmatrix.hh:2027\n-Dune::BCRSMatrix::iterator\n-RealRowIterator< row_type > iterator\n-The iterator over the (mutable matrix rows.\n-Definition: bcrsmatrix.hh:671\n-Dune::BCRSMatrix::usmtv\n-void usmtv(const field_type &alpha, const X &x, Y &y) const\n-y += alpha A^T x\n-Definition: bcrsmatrix.hh:1766\n-Dune::BCRSMatrix::beforeBegin\n-ConstIterator beforeBegin() const\n-Definition: bcrsmatrix.hh:732\n-Dune::BCRSMatrix::ConstIterator\n-RealRowIterator< const row_type > ConstIterator\n-Definition: bcrsmatrix.hh:708\n-Dune::BCRSMatrix::beforeBegin\n-Iterator beforeBegin()\n-Definition: bcrsmatrix.hh:695\n-Dune::BCRSMatrix::a\n-B * a\n-Definition: bcrsmatrix.hh:2040\n-Dune::BCRSMatrix::BuildMode\n-BuildMode\n-we support two modes\n-Definition: bcrsmatrix.hh:510\n-Dune::BCRSMatrix::implicit\n-@ implicit\n-Build entries randomly with an educated guess for the number of entries per\n-row.\n-Definition: bcrsmatrix.hh:539\n-Dune::BCRSMatrix::unknown\n-@ unknown\n-Build mode not set!\n-Definition: bcrsmatrix.hh:543\n-Dune::BCRSMatrix::random\n-@ random\n-Build entries randomly.\n-Definition: bcrsmatrix.hh:530\n Dune::BCRSMatrix::row_wise\n @ row_wise\n Build in a row-wise manner.\n Definition: bcrsmatrix.hh:521\n-Dune::BCRSMatrix::BCRSMatrix\n-BCRSMatrix(size_type _n, size_type _m, size_type _nnz, BuildMode bm)\n-matrix with known number of nonzeroes\n-Definition: bcrsmatrix.hh:756\n-Dune::BCRSMatrix::CompressionStatistics\n-::Dune::CompressionStatistics< size_type > CompressionStatistics\n-The type for the statistics object returned by compress()\n-Definition: bcrsmatrix.hh:503\n-Dune::BCRSMatrix::operator-=\n-BCRSMatrix & operator-=(const BCRSMatrix &b)\n-Subtract the entries of another matrix from this one.\n-Definition: bcrsmatrix.hh:1567\n-Dune::BCRSMatrix::BCRSMatrix\n-BCRSMatrix(const BCRSMatrix &Mat)\n-copy constructor\n-Definition: bcrsmatrix.hh:805\n-Dune::BCRSMatrix::end\n-Iterator end()\n-Get iterator to one beyond last row.\n-Definition: bcrsmatrix.hh:681\n-Dune::BCRSMatrix::r\n-row_type * r\n-Definition: bcrsmatrix.hh:2037\n-Dune::BCRSMatrix::setIndices\n-void setIndices(size_type row, It begin, It end)\n-Set all column indices for row from the given iterator range.\n-Definition: bcrsmatrix.hh:1234\n-Dune::BCRSMatrix::addindex\n-void addindex(size_type row, size_type col)\n-add index (row,col) to the matrix\n-Definition: bcrsmatrix.hh:1191\n-Dune::BCRSMatrix::OverflowType\n-std::map< std::pair< size_type, size_type >, B > OverflowType\n-Definition: bcrsmatrix.hh:2049\n-Dune::BCRSMatrix::ColIterator\n-row_type::Iterator ColIterator\n-Iterator for the entries of each row.\n-Definition: bcrsmatrix.hh:704\n-Dune::BCRSMatrix::frobenius_norm\n-FieldTraits< field_type >::real_type frobenius_norm() const\n-frobenius norm: sqrt(sum over squared values of entries)\n-Definition: bcrsmatrix.hh:1877\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n-Dune::BCRSMatrix::operator/=\n-BCRSMatrix & operator/=(const field_type &k)\n-vector space division by scalar\n-Definition: bcrsmatrix.hh:1512\n-Dune::BCRSMatrix::overflow\n-OverflowType overflow\n-Definition: bcrsmatrix.hh:2050\n-Dune::BCRSMatrix::operator+=\n-BCRSMatrix & operator+=(const BCRSMatrix &b)\n-Add the entries of another matrix to this one.\n-Definition: bcrsmatrix.hh:1545\n-Dune::BCRSMatrix::BCRSMatrix\n-BCRSMatrix(size_type _n, size_type _m, size_type _avg, double\n-compressionBufferSize, BuildMode bm)\n-construct matrix with a known average number of entries per row\n-Definition: bcrsmatrix.hh:784\n Dune::BCRSMatrix::createend\n CreateIterator createend()\n get create iterator pointing to one after the last block\n Definition: bcrsmatrix.hh:1103\n-Dune::BCRSMatrix::frobenius_norm2\n-FieldTraits< field_type >::real_type frobenius_norm2() const\n-square of frobenius norm, need for block recursion\n-Definition: bcrsmatrix.hh:1860\n-Dune::BCRSMatrix::beforeEnd\n-Iterator beforeEnd()\n-Definition: bcrsmatrix.hh:688\n-Dune::BCRSMatrix::ConstColIterator\n-row_type::ConstIterator ConstColIterator\n-Const iterator to the entries of a row.\n-Definition: bcrsmatrix.hh:741\n-Dune::BCRSMatrix::usmv\n-void usmv(F &&alpha, const X &x, Y &y) const\n-y += alpha A x\n-Definition: bcrsmatrix.hh:1684\n-Dune::BCRSMatrix::getrowsize\n-size_type getrowsize(size_type i) const\n-get current number of indices in row i\n-Definition: bcrsmatrix.hh:1128\n-Dune::BCRSMatrix::M\n-size_type M() const\n-number of columns (counted in blocks)\n-Definition: bcrsmatrix.hh:1978\n-Dune::BCRSMatrix::n\n-size_type n\n-Definition: bcrsmatrix.hh:2030\n-Dune::BCRSMatrix::row_type\n-Imp::CompressedBlockVectorWindow< B, A > row_type\n-implement row_type with compressed vector\n-Definition: bcrsmatrix.hh:497\n Dune::BCRSMatrix::createbegin\n CreateIterator createbegin()\n get initial create iterator\n Definition: bcrsmatrix.hh:1097\n-Dune::BCRSMatrix::BuildStage\n-BuildStage\n-Definition: bcrsmatrix.hh:469\n-Dune::BCRSMatrix::rowSizesBuilt\n-@ rowSizesBuilt\n-The row sizes of the matrix are known.\n-Definition: bcrsmatrix.hh:480\n-Dune::BCRSMatrix::built\n-@ built\n-The matrix structure is fully built.\n-Definition: bcrsmatrix.hh:482\n-Dune::BCRSMatrix::notbuilt\n-@ notbuilt\n-Matrix is not built at all, no memory has been allocated, build mode and size\n-can still be set.\n-Definition: bcrsmatrix.hh:471\n-Dune::BCRSMatrix::notAllocated\n-@ notAllocated\n-Matrix is not built at all, no memory has been allocated, build mode and size\n-can still be set.\n-Definition: bcrsmatrix.hh:473\n-Dune::BCRSMatrix::building\n-@ building\n-Matrix is currently being built, some memory has been allocated, build mode and\n-size are fixed.\n-Definition: bcrsmatrix.hh:475\n-Dune::BCRSMatrix::buildMode\n-BuildMode buildMode() const\n-The currently selected build mode of the matrix.\n-Definition: bcrsmatrix.hh:1999\n-Dune::BCRSMatrix::mmv\n-void mmv(const X &x, Y &y) const\n-y -= A x\n-Definition: bcrsmatrix.hh:1661\n-Dune::BCRSMatrix::infinity_norm\n-FieldTraits< ft >::real_type infinity_norm() const\n-infinity norm (row sum norm, how to generalize for blocks?)\n-Definition: bcrsmatrix.hh:1885\n-Dune::BCRSMatrix::mv\n-void mv(const X &x, Y &y) const\n-y = A x\n-Definition: bcrsmatrix.hh:1612\n-Dune::BCRSMatrix::block_type\n-B block_type\n-export the type representing the components\n-Definition: bcrsmatrix.hh:491\n-Dune::BCRSMatrix::mmtv\n-void mmtv(const X &x, Y &y) const\n-y -= A^T x\n-Definition: bcrsmatrix.hh:1745\n-Dune::BCRSMatrix::avg\n-size_type avg\n-Definition: bcrsmatrix.hh:2046\n-Dune::BCRSMatrix::umv\n-void umv(const X &x, Y &y) const\n-y += A x\n-Definition: bcrsmatrix.hh:1638\n-Dune::BCRSMatrix::implicit_allocate\n-void implicit_allocate(size_type _n, size_type _m)\n-organizes allocation implicit mode calculates correct array size to be\n-allocated and sets the the win...\n-Definition: bcrsmatrix.hh:2265\n-Dune::BCRSMatrix::setImplicitBuildModeParameters\n-void setImplicitBuildModeParameters(size_type _avg, double\n-compressionBufferSize)\n-Set parameters needed for creation in implicit build mode.\n-Definition: bcrsmatrix.hh:889\n-Dune::BCRSMatrix::BCRSMatrix\n-BCRSMatrix(size_type _n, size_type _m, BuildMode bm)\n-matrix with unknown number of nonzeroes\n-Definition: bcrsmatrix.hh:765\n-Dune::BCRSMatrix::endindices\n-void endindices()\n-indicate that all indices are defined, check consistency\n-Definition: bcrsmatrix.hh:1248\n-Dune::BCRSMatrix::compress\n-CompressionStatistics compress()\n-Finishes the buildstage in implicit mode.\n-Definition: bcrsmatrix.hh:1360\n-Dune::BCRSMatrix::setDataPointers\n-void setDataPointers()\n-Set data pointers for all rows.\n-Definition: bcrsmatrix.hh:2103\n-Dune::BCRSMatrix::allocator_\n-std::allocator_traits< A >::template rebind_alloc< B > allocator_\n-Definition: bcrsmatrix.hh:2023\n Dune::BCRSMatrix::N\n size_type N() const\n number of rows (counted in blocks)\n Definition: bcrsmatrix.hh:1972\n-Dune::BCRSMatrix::setBuildMode\n-void setBuildMode(BuildMode bm)\n-Sets the build mode of the matrix.\n-Definition: bcrsmatrix.hh:833\n-Dune::BCRSMatrix::setSize\n-void setSize(size_type rows, size_type columns, size_type nnz=0)\n-Set the size of the matrix.\n-Definition: bcrsmatrix.hh:861\n-Dune::BCRSMatrix::j_\n-std::shared_ptr< size_type > j_\n-Definition: bcrsmatrix.hh:2043\n-Dune::BCRSMatrix::setWindowPointers\n-void setWindowPointers(ConstRowIterator row)\n-Definition: bcrsmatrix.hh:2052\n-Dune::BCRSMatrix::operator=\n-BCRSMatrix & operator=(const BCRSMatrix &Mat)\n-assignment\n-Definition: bcrsmatrix.hh:911\n-Dune::BCRSMatrix::setColumnPointers\n-void setColumnPointers(ConstRowIterator row)\n-Copy row sizes from iterator range starting at row and set column index\n-pointers for all rows.\n-Definition: bcrsmatrix.hh:2077\n-Dune::BCRSMatrix::end\n-ConstIterator end() const\n-Get const iterator to one beyond last row.\n-Definition: bcrsmatrix.hh:718\n-Dune::BCRSMatrix::begin\n-ConstIterator begin() const\n-Get const iterator to first row.\n-Definition: bcrsmatrix.hh:712\n-Dune::BCRSMatrix::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: bcrsmatrix.hh:494\n-Dune::BCRSMatrix::beforeEnd\n-ConstIterator beforeEnd() const\n-Definition: bcrsmatrix.hh:725\n-Dune::BCRSMatrix::RealRowIterator\n-Iterator access to matrix rows\n-Definition: bcrsmatrix.hh:579\n-Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n-RealRowIterator()\n-empty constructor, use with care!\n-Definition: bcrsmatrix.hh:596\n-Dune::BCRSMatrix::RealRowIterator::equals\n-bool equals(const RealRowIterator< ValueType > &other) const\n-equality\n-Definition: bcrsmatrix.hh:624\n-Dune::BCRSMatrix::RealRowIterator::ValueType\n-std::remove_const< T >::type ValueType\n-The unqualified value type.\n-Definition: bcrsmatrix.hh:583\n-Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n-RealRowIterator(const RealRowIterator< ValueType > &it)\n-Definition: bcrsmatrix.hh:600\n-Dune::BCRSMatrix::RealRowIterator::equals\n-bool equals(const RealRowIterator< const ValueType > &other) const\n-equality\n-Definition: bcrsmatrix.hh:631\n-Dune::BCRSMatrix::RealRowIterator::RealRowIterator\n-RealRowIterator(row_type *_p, size_type _i)\n-constructor\n-Definition: bcrsmatrix.hh:591\n-Dune::BCRSMatrix::RealRowIterator::distanceTo\n-std::ptrdiff_t distanceTo(const RealRowIterator< const ValueType > &other)\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::ArPackPlusPlus_Algorithms\n+Wrapper to use a range of ARPACK++ eigenvalue solvers.\n+Definition: arpackpp.hh:245\n+Dune::ArPackPlusPlus_Algorithms::computeSymMaxMagnitude\n+void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n+const\n+Assume the matrix to be square, symmetric and perform IRLM to compute an\n+approximation lambda of its ...\n+Definition: arpackpp.hh:289\n+Dune::ArPackPlusPlus_Algorithms::computeSymMinMagnitude\n+void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n const\n-Definition: bcrsmatrix.hh:617\n-Dune::BCRSMatrix::RealRowIterator::index\n-size_type index() const\n-return index\n-Definition: bcrsmatrix.hh:606\n-Dune::BCRSMatrix::RealRowIterator::distanceTo\n-std::ptrdiff_t distanceTo(const RealRowIterator< ValueType > &other) const\n-Definition: bcrsmatrix.hh:611\n-Dune::BCRSMatrix::CreateIterator\n-Iterator class for sequential creation of blocks\n-Definition: bcrsmatrix.hh:957\n-Dune::BCRSMatrix::CreateIterator::operator==\n-bool operator==(const CreateIterator &it) const\n-equality\n-Definition: bcrsmatrix.hh:1052\n-Dune::BCRSMatrix::CreateIterator::operator++\n-CreateIterator & operator++()\n-prefix increment\n-Definition: bcrsmatrix.hh:977\n-Dune::BCRSMatrix::CreateIterator::index\n-size_type index() const\n-The number of the row that the iterator currently points to.\n-Definition: bcrsmatrix.hh:1058\n-Dune::BCRSMatrix::CreateIterator::operator!=\n-bool operator!=(const CreateIterator &it) const\n-inequality\n-Definition: bcrsmatrix.hh:1046\n-Dune::BCRSMatrix::CreateIterator::CreateIterator\n-CreateIterator(BCRSMatrix &_Mat, size_type _i)\n-constructor\n-Definition: bcrsmatrix.hh:960\n-Dune::BCRSMatrix::CreateIterator::insert\n-void insert(size_type j)\n-put column index in row\n-Definition: bcrsmatrix.hh:1064\n-Dune::BCRSMatrix::CreateIterator::contains\n-bool contains(size_type j)\n-return true if column index is in row\n-Definition: bcrsmatrix.hh:1070\n-Dune::BCRSMatrix::CreateIterator::size\n-size_type size() const\n-Get the current row size.\n-Definition: bcrsmatrix.hh:1079\n-Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>::field_type\n-typename BCRSMatrix< B, A >::field_type field_type\n-Definition: bcrsmatrix.hh:2299\n-Dune::FieldTraits<_BCRSMatrix<_B,_A_>_>::real_type\n-typename FieldTraits< field_type >::real_type real_type\n-Definition: bcrsmatrix.hh:2300\n-Dune::BCRSMatrixError\n-Error specific to BCRSMatrix.\n-Definition: istlexception.hh:24\n-Dune::ImplicitModeCompressionBufferExhausted\n-Thrown when the compression buffer used by the implicit BCRSMatrix construction\n-is exhausted.\n-Definition: istlexception.hh:37\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::size_type\n-A::size_type size_type\n-Type for indices and sizes.\n-Definition: matrix.hh:577\n-Dune::Matrix::block_type\n-T block_type\n-Export the type representing the components.\n-Definition: matrix.hh:568\n-Dune::PointerCompare\n-Definition: matrixutils.hh:538\n+Assume the matrix to be square, symmetric and perform IRLM to compute an\n+approximation lambda of its ...\n+Definition: arpackpp.hh:391\n+Dune::SolverAbort\n+Thrown when a solver aborts due to some problem.\n+Definition: istlexception.hh:46\n+Dune::LinearOperator<_X,_X_>\n+Dune::Preconditioner<_X,_X_>\n+Dune::ScalarProduct\n+Base class for scalar product and norm computation.\n+Definition: scalarproducts.hh:52\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperatorResult::condition_estimate\n+double condition_estimate\n+Estimate of condition number.\n+Definition: solver.hh:79\n+Dune::InverseOperatorResult::clear\n+void clear()\n+Resets all data.\n+Definition: solver.hh:56\n+Dune::InverseOperatorResult::converged\n+bool converged\n+True if convergence criterion has been met.\n+Definition: solver.hh:73\n+Dune::InverseOperator<_X,_X_>::scalar_real_type\n+Simd::Scalar< real_type > scalar_real_type\n+scalar type underlying the field_type\n+Definition: solver.hh:114\n+Dune::InverseOperator::range_type\n+Y range_type\n+Type of the range of the operator to be inverted.\n+Definition: solver.hh:105\n+Dune::InverseOperator::domain_type\n+X domain_type\n+Type of the domain of the operator to be inverted.\n+Definition: solver.hh:102\n+Dune::InverseOperator<_X,_X_>::field_type\n+X::field_type field_type\n+The field type of the operator.\n+Definition: solver.hh:108\n+Dune::InverseOperator<_X,_X_>::real_type\n+FieldTraits< field_type >::real_type real_type\n+The real type of the field type (is the same if using real numbers, but differs\n+for std::complex)\n+Definition: solver.hh:111\n+Dune::IterativeSolver\n+Base class for all implementations of iterative solvers.\n+Definition: solver.hh:203\n+Dune::IterativeSolver<_X,_X_>::_sp\n+std::shared_ptr< const ScalarProduct< X > > _sp\n+Definition: solver.hh:506\n+Dune::IterativeSolver<_X,_X_>::IterativeSolver\n+IterativeSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec,\n+scalar_real_type reduction, int maxit, int verbose)\n+General constructor to initialize an iterative solver.\n+Definition: solver.hh:230\n+Dune::IterativeSolver<_X,_X_>::_op\n+std::shared_ptr< const LinearOperator< X, X > > _op\n+Definition: solver.hh:504\n+Dune::IterativeSolver<_X,_X_>::_maxit\n+int _maxit\n+Definition: solver.hh:508\n+Dune::IterativeSolver<_X,_X_>::_verbose\n+int _verbose\n+Definition: solver.hh:509\n+Dune::IterativeSolver<_X,_X_>::_reduction\n+scalar_real_type _reduction\n+Definition: solver.hh:507\n+Dune::IterativeSolver<_X,_X_>::_prec\n+std::shared_ptr< Preconditioner< X, X > > _prec\n+Definition: solver.hh:505\n+Dune::LoopSolver\n+Preconditioned loop solver.\n+Definition: solvers.hh:59\n+Dune::LoopSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator,.\n+Definition: solvers.hh:73\n+Dune::LoopSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:116\n+Dune::GradientSolver\n+gradient method\n+Definition: solvers.hh:124\n+Dune::GradientSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:142\n+Dune::GradientSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:187\n+Dune::CGSolver\n+conjugate gradient method\n+Definition: solvers.hh:193\n+Dune::CGSolver::CGSolver\n+CGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::shared_ptr<\n+ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X, X > > prec,\n+scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)\n+Constructor to initialize a CG solver.\n+Definition: solvers.hh:256\n+Dune::CGSolver::enableConditionEstimate\n+static constexpr bool enableConditionEstimate\n+Definition: solvers.hh:208\n+Dune::CGSolver::CGSolver\n+CGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X > &sp,\n+Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n+verbose, bool condition_estimate)\n+Constructor to initialize a CG solver.\n+Definition: solvers.hh:239\n+Dune::CGSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:279\n+Dune::CGSolver::CGSolver\n+CGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X > &prec,\n+scalar_real_type reduction, int maxit, int verbose, bool condition_estimate)\n+Constructor to initialize a CG solver.\n+Definition: solvers.hh:222\n+Dune::CGSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:412\n+Dune::BiCGSTABSolver\n+Bi-conjugate Gradient Stabilized (BiCG-STAB)\n+Definition: solvers.hh:419\n+Dune::BiCGSTABSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< CountType > Iteration\n+Definition: solvers.hh:598\n+Dune::BiCGSTABSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:439\n+Dune::MINRESSolver\n+Minimal Residual Method (MINRES)\n+Definition: solvers.hh:609\n+Dune::MINRESSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:627\n+Dune::MINRESSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:808\n+Dune::RestartedGMResSolver\n+implements the Generalized Minimal Residual (GMRes) method\n+Definition: solvers.hh:827\n+Dune::RestartedGMResSolver::RestartedGMResSolver\n+RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n+Constructor.\n+Definition: solvers.hh:878\n+Dune::RestartedGMResSolver::conjugate\n+std::enable_if::value, T >::type\n+conjugate(const T &t)\n+Definition: solvers.hh:1067\n+Dune::RestartedGMResSolver::RestartedGMResSolver\n+RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, const ParameterTree &configuration)\n+Definition: solvers.hh:883\n+Dune::RestartedGMResSolver::update\n+void update(X &w, int i, const std::vector< std::vector< field_type, fAlloc > >\n+&H, const std::vector< field_type, fAlloc > &s, const std::vector< X > &v)\n+Definition: solvers.hh:1039\n+Dune::RestartedGMResSolver::conjugate\n+std::enable_if< std::is_same< field_type, real_type >::value, T >::type\n+conjugate(const T &t)\n+Definition: solvers.hh:1062\n+Dune::RestartedGMResSolver::fAlloc\n+ReboundAllocatorType< X, field_type > fAlloc\n+field_type Allocator retrieved from domain type\n+Definition: solvers.hh:838\n+Dune::RestartedGMResSolver::_restart\n+int _restart\n+Definition: solvers.hh:1120\n+Dune::RestartedGMResSolver::rAlloc\n+ReboundAllocatorType< X, real_type > rAlloc\n+real_type Allocator retrieved from domain type\n+Definition: solvers.hh:840\n+Dune::RestartedGMResSolver::apply\n+virtual void apply(X &x, Y &b, double reduction, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:923\n+Dune::RestartedGMResSolver::RestartedGMResSolver\n+RestartedGMResSolver(const LinearOperator< X, Y > &op, Preconditioner< X, Y >\n+&prec, scalar_real_type reduction, int restart, int maxit, int verbose)\n+Set up RestartedGMResSolver solver.\n+Definition: solvers.hh:850\n+Dune::RestartedGMResSolver::RestartedGMResSolver\n+RestartedGMResSolver(const LinearOperator< X, Y > &op, const ScalarProduct< X >\n+&sp, Preconditioner< X, Y > &prec, scalar_real_type reduction, int restart, int\n+maxit, int verbose)\n+Set up RestartedGMResSolver solver.\n+Definition: solvers.hh:861\n+Dune::RestartedGMResSolver::generatePlaneRotation\n+void generatePlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n+field_type &sn)\n+Definition: solvers.hh:1073\n+Dune::RestartedGMResSolver::RestartedGMResSolver\n+RestartedGMResSolver(std::shared_ptr< const LinearOperator< X, Y > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+Y > > prec, scalar_real_type reduction, int restart, int maxit, int verbose)\n+Set up RestartedGMResSolver solver.\n+Definition: solvers.hh:894\n+Dune::RestartedGMResSolver::apply\n+virtual void apply(X &x, Y &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:910\n+Dune::RestartedGMResSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:1119\n+Dune::RestartedGMResSolver::applyPlaneRotation\n+void applyPlaneRotation(field_type &dx, field_type &dy, real_type &cs,\n+field_type &sn)\n+Definition: solvers.hh:1106\n+Dune::RestartedFlexibleGMResSolver\n+implements the Flexible Generalized Minimal Residual (FGMRes) method (right\n+preconditioned)\n+Definition: solvers.hh:1139\n+Dune::RestartedFlexibleGMResSolver::apply\n+void apply(X &x, Y &b, double reduction, InverseOperatorResult &res) override\n+Apply inverse operator.\n+Definition: solvers.hh:1169\n+Dune::GeneralizedPCGSolver\n+Generalized preconditioned conjugate gradient solver.\n+Definition: solvers.hh:1307\n+Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n+GeneralizedPCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X >\n+&sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n+verbose, int restart=10)\n+Set up nonlinear preconditioned conjugate gradient solver.\n+Definition: solvers.hh:1343\n+Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n+GeneralizedPCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X >\n+&prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)\n+Set up nonlinear preconditioned conjugate gradient solver.\n+Definition: solvers.hh:1331\n+Dune::GeneralizedPCGSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:1391\n+Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n+GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &configuration)\n+Constructor.\n+Definition: solvers.hh:1361\n+Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n+GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, scalar_real_type reduction, int maxit, int verbose, int restart=10)\n+Set up nonlinear preconditioned conjugate gradient solver.\n+Definition: solvers.hh:1377\n+Dune::GeneralizedPCGSolver::GeneralizedPCGSolver\n+GeneralizedPCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, const ParameterTree &configuration)\n+Definition: solvers.hh:1366\n+Dune::RestartedFCGSolver\n+Accelerated flexible conjugate gradient method.\n+Definition: solvers.hh:1501\n+Dune::RestartedFCGSolver::RestartedFCGSolver\n+RestartedFCGSolver(const LinearOperator< X, X > &op, Preconditioner< X, X >\n+&prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)\n+Constructor to initialize a RestartedFCG solver.\n+Definition: solvers.hh:1519\n+Dune::RestartedFCGSolver::RestartedFCGSolver\n+RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< Preconditioner< X, X > > prec, const ParameterTree &config)\n+Constructor.\n+Definition: solvers.hh:1559\n+Dune::RestartedFCGSolver::RestartedFCGSolver\n+RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, scalar_real_type reduction, int maxit, int verbose, int mmax=10)\n+Constructor to initialize a RestartedFCG solver.\n+Definition: solvers.hh:1539\n+Dune::RestartedFCGSolver::_mmax\n+int _mmax\n+Definition: solvers.hh:1662\n+Dune::RestartedFCGSolver::RestartedFCGSolver\n+RestartedFCGSolver(std::shared_ptr< const LinearOperator< X, X > > op, std::\n+shared_ptr< const ScalarProduct< X > > sp, std::shared_ptr< Preconditioner< X,\n+X > > prec, const ParameterTree &config)\n+Definition: solvers.hh:1565\n+Dune::RestartedFCGSolver::Iteration\n+typename IterativeSolver< X, X >::template Iteration< unsigned int > Iteration\n+Definition: solvers.hh:1669\n+Dune::RestartedFCGSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res)\n+Apply inverse operator.\n+Definition: solvers.hh:1584\n+Dune::RestartedFCGSolver::RestartedFCGSolver\n+RestartedFCGSolver(const LinearOperator< X, X > &op, const ScalarProduct< X >\n+&sp, Preconditioner< X, X > &prec, scalar_real_type reduction, int maxit, int\n+verbose, int mmax=10)\n+Constructor to initialize a RestartedFCG solver.\n+Definition: solvers.hh:1529\n+Dune::CompleteFCGSolver\n+Complete flexible conjugate gradient method.\n+Definition: solvers.hh:1680\n+Dune::CompleteFCGSolver::apply\n+virtual void apply(X &x, X &b, InverseOperatorResult &res) override\n+Apply inverse operator.\n+Definition: solvers.hh:1694\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00200.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00200.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: btdmatrix.hh File Reference\n+dune-istl: arpackpp.hh File Reference\n \n \n \n \n \n \n \n@@ -58,51 +58,48 @@\n \n
    \n \n \n \n
    \n \n-
    btdmatrix.hh File Reference
    \n+
    arpackpp.hh File Reference
    \n
    \n
    \n-\n-

    Implementation of the BTDMatrix class. \n-More...

    \n-
    #include <dune/common/fmatrix.hh>
    \n-#include <dune/common/scalarvectorview.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n+
    #include <cmath>
    \n+#include <iostream>
    \n+#include <string>
    \n+#include <dune/common/fvector.hh>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n+#include <dune/istl/bvector.hh>
    \n+#include <dune/istl/istlexception.hh>
    \n+#include <dune/istl/io.hh>
    \n+#include "arssym.h"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::BTDMatrix< B, A >
     A block-tridiagonal matrix. More...
     
    struct  Dune::FieldTraits< BTDMatrix< B, A > >
    class  Dune::ArPackPlusPlus_Algorithms< BCRSMatrix, BlockVector >
     Wrapper to use a range of ARPACK++ eigenvalue solvers. More...
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-

    Detailed Description

    \n-

    Implementation of the BTDMatrix class.

    \n-
    Author
    Oliver Sander
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,32 +4,31 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * eigenvalue\n Classes | Namespaces\n-btdmatrix.hh File Reference\n-Implementation of the BTDMatrix class. More...\n-#include \n-#include \n-#include \n-#include \n+arpackpp.hh File Reference\n+#include \n+#include \n+#include \n+#include \n+#include \n #include \n+#include \n+#include \n+#include \n+#include \"arssym.h\"\n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::BTDMatrix<_B,_A_>\n-\u00a0 A block-tridiagonal matrix. More...\n-\u00a0\n-struct \u00a0Dune::FieldTraits<_BTDMatrix<_B,_A_>_>\n+class \u00a0Dune::ArPackPlusPlus_Algorithms<_BCRSMatrix,_BlockVector_>\n+\u00a0 Wrapper to use a range of ARPACK++ eigenvalue solvers. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-***** Detailed Description *****\n-Implementation of the BTDMatrix class.\n- Author\n- Oliver Sander\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00200_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00200_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: btdmatrix.hh Source File\n+dune-istl: arpackpp.hh Source File\n \n \n \n \n \n \n \n@@ -58,230 +58,863 @@\n \n \n \n \n \n
    \n-
    btdmatrix.hh
    \n+
    arpackpp.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_BTDMATRIX_HH
    \n-
    6#define DUNE_ISTL_BTDMATRIX_HH
    \n+
    5#ifndef DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n+
    6#define DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n
    7
    \n-
    8#include <dune/common/fmatrix.hh>
    \n-
    9#include <dune/common/scalarvectorview.hh>
    \n-
    10#include <dune/common/scalarmatrixview.hh>
    \n-\n-\n-
    13
    \n-
    19namespace Dune {
    \n-
    29 template <class B, class A=std::allocator<B> >
    \n-
    30 class BTDMatrix : public BCRSMatrix<B,A>
    \n-
    31 {
    \n-
    32 public:
    \n-
    33
    \n-
    34 //===== type definitions and constants
    \n-
    35
    \n-
    37 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n-
    38
    \n-
    40 typedef B block_type;
    \n-
    41
    \n-
    43 typedef A allocator_type;
    \n-
    44
    \n-
    46 //typedef BCRSMatrix<B,A>::row_type row_type;
    \n-
    47
    \n-
    49 typedef typename A::size_type size_type;
    \n-
    50
    \n-
    52 [[deprecated("Use free blockLevel function. Will be removed after 2.8.")]]
    \n-
    53 static constexpr auto blocklevel = blockLevel<B>()+1;
    \n-
    54
    \n-
    56 BTDMatrix() : BCRSMatrix<B,A>() {}
    \n-
    57
    \n-
    58 explicit BTDMatrix(size_type size)
    \n-
    59 : BCRSMatrix<B,A>(size, size, BCRSMatrix<B,A>::random)
    \n-
    60 {
    \n-
    61 // Set number of entries for each row
    \n-
    62 // All rows get three entries, except for the first and the last one
    \n-
    63 for (size_t i=0; i<size; i++)
    \n-
    64 this->BCRSMatrix<B,A>::setrowsize(i, 3 - (i==0) - (i==(size-1)));
    \n-
    65
    \n-\n-
    67
    \n-
    68 // The actual entries for each row
    \n-
    69 for (size_t i=0; i<size; i++) {
    \n-
    70 if (i>0)
    \n-
    71 this->BCRSMatrix<B,A>::addindex(i, i-1);
    \n-
    72 this->BCRSMatrix<B,A>::addindex(i, i );
    \n-
    73 if (i<size-1)
    \n-
    74 this->BCRSMatrix<B,A>::addindex(i, i+1);
    \n-
    75 }
    \n-
    76
    \n-\n-
    78 }
    \n-
    79
    \n-
    81 void setSize(size_type size)
    \n-
    82 {
    \n-
    83 auto nonZeros = (size==0) ? 0 : size + 2*(size-1);
    \n-
    84 this->BCRSMatrix<B,A>::setSize(size, // rows
    \n-
    85 size, // columns
    \n-
    86 nonZeros);
    \n+
    8#if HAVE_ARPACKPP || defined DOXYGEN
    \n+
    9
    \n+
    10#include <cmath> // provides std::abs, std::pow, std::sqrt
    \n+
    11
    \n+
    12#include <iostream> // provides std::cout, std::endl
    \n+
    13#include <string> // provides std::string
    \n+
    14
    \n+
    15#include <dune/common/fvector.hh> // provides Dune::FieldVector
    \n+
    16#include <dune/common/exceptions.hh> // provides DUNE_THROW(...)
    \n+
    17
    \n+
    18#include <dune/istl/blocklevel.hh> // provides Dune::blockLevel
    \n+
    19#include <dune/istl/bvector.hh> // provides Dune::BlockVector
    \n+
    20#include <dune/istl/istlexception.hh> // provides Dune::ISTLError
    \n+
    21#include <dune/istl/io.hh> // provides Dune::printvector(...)
    \n+
    22
    \n+
    23#ifdef Status
    \n+
    24#undef Status // prevent preprocessor from damaging the ARPACK++
    \n+
    25 // code when "X11/Xlib.h" is included (the latter
    \n+
    26 // defines Status as "#define Status int" and
    \n+
    27 // ARPACK++ provides a class with a method called
    \n+
    28 // Status)
    \n+
    29#endif
    \n+
    30#include "arssym.h" // provides ARSymStdEig
    \n+
    31
    \n+
    32namespace Dune
    \n+
    33{
    \n+
    34
    \n+
    39 namespace Impl {
    \n+
    55 template <class BCRSMatrix>
    \n+
    56 class ArPackPlusPlus_BCRSMatrixWrapper
    \n+
    57 {
    \n+
    58 public:
    \n+
    60 typedef typename BCRSMatrix::field_type Real;
    \n+
    61
    \n+
    62 public:
    \n+
    64 ArPackPlusPlus_BCRSMatrixWrapper (const BCRSMatrix& A)
    \n+
    65 : A_(A),
    \n+
    66 m_(A_.M() * mBlock), n_(A_.N() * nBlock)
    \n+
    67 {
    \n+
    68 // assert that BCRSMatrix type has blocklevel 2
    \n+
    69 static_assert
    \n+
    70 (blockLevel<BCRSMatrix>() == 2,
    \n+
    71 "Only BCRSMatrices with blocklevel 2 are supported.");
    \n+
    72
    \n+
    73 // allocate memory for auxiliary block vector objects
    \n+
    74 // which are compatible to matrix rows / columns
    \n+
    75 domainBlockVector.resize(A_.N());
    \n+
    76 rangeBlockVector.resize(A_.M());
    \n+
    77 }
    \n+
    78
    \n+
    80 inline void multMv (Real* v, Real* w)
    \n+
    81 {
    \n+
    82 // get vector v as an object of appropriate type
    \n+
    83 arrayToDomainBlockVector(v,domainBlockVector);
    \n+
    84
    \n+
    85 // perform matrix-vector product
    \n+
    86 A_.mv(domainBlockVector,rangeBlockVector);
    \n
    87
    \n-
    88 // Set number of entries for each row
    \n-
    89 // All rows get three entries, except for the first and the last one
    \n-
    90 for (size_t i=0; i<size; i++)
    \n-
    91 this->BCRSMatrix<B,A>::setrowsize(i, 3 - (i==0) - (i==(size-1)));
    \n-
    92
    \n-\n-
    94
    \n-
    95 // The actual entries for each row
    \n-
    96 for (size_t i=0; i<size; i++) {
    \n-
    97 if (i>0)
    \n-
    98 this->BCRSMatrix<B,A>::addindex(i, i-1);
    \n-
    99 this->BCRSMatrix<B,A>::addindex(i, i );
    \n-
    100 if (i<size-1)
    \n-
    101 this->BCRSMatrix<B,A>::addindex(i, i+1);
    \n-
    102 }
    \n-
    103
    \n-\n-
    105 }
    \n-
    106
    \n-\n-
    109 this->BCRSMatrix<B,A>::operator=(other);
    \n-
    110 return *this;
    \n-
    111 }
    \n-
    112
    \n-\n-\n-
    116 return *this;
    \n-
    117 }
    \n-
    118
    \n-
    124 template <class V>
    \n-
    125 void solve (V& x, const V& rhs) const {
    \n-
    126
    \n-
    127 // special handling for 1x1 matrices. The generic algorithm doesn't work for them
    \n-
    128 if (this->N()==1) {
    \n-
    129 auto&& x0 = Impl::asVector(x[0]);
    \n-
    130 auto&& rhs0 = Impl::asVector(rhs[0]);
    \n-
    131 Impl::asMatrix((*this)[0][0]).solve(x0, rhs0);
    \n-
    132 return;
    \n-
    133 }
    \n-
    134
    \n-
    135 // Make copies of the rhs and the right matrix band
    \n-
    136 V d = rhs;
    \n-
    137 std::vector<block_type> c(this->N()-1);
    \n-
    138 for (size_t i=0; i<this->N()-1; i++)
    \n-
    139 c[i] = (*this)[i][i+1];
    \n-
    140
    \n-
    141 /* Modify the coefficients. */
    \n-
    142 block_type a_00_inv = (*this)[0][0];
    \n-
    143 Impl::asMatrix(a_00_inv).invert();
    \n-
    144
    \n-
    145 //c[0] /= (*this)[0][0]; /* Division by zero risk. */
    \n-
    146 block_type tmp = a_00_inv;
    \n-
    147 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[0]));
    \n-
    148 c[0] = tmp;
    \n-
    149
    \n-
    150 // d = a^{-1} d /* Division by zero would imply a singular matrix. */
    \n-
    151 auto d_0_tmp = d[0];
    \n-
    152 auto&& d_0 = Impl::asVector(d[0]);
    \n-
    153 Impl::asMatrix(a_00_inv).mv(Impl::asVector(d_0_tmp),d_0);
    \n-
    154
    \n-
    155 for (unsigned int i = 1; i < this->N(); i++) {
    \n-
    156
    \n-
    157 // id = ( a_ii - c_{i-1} a_{i, i-1} ) ^{-1}
    \n-
    158 block_type tmp;
    \n-
    159 tmp = (*this)[i][i-1];
    \n-
    160 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[i-1]));
    \n-
    161
    \n-
    162 block_type id = (*this)[i][i];
    \n-
    163 id -= tmp;
    \n-
    164 Impl::asMatrix(id).invert(); /* Division by zero risk. */
    \n-
    165
    \n-
    166 if (i<c.size()) {
    \n-
    167 Impl::asMatrix(c[i]).leftmultiply(Impl::asMatrix(id)); /* Last value calculated is redundant. */
    \n-
    168 }
    \n-
    169
    \n-
    170 // d[i] = (d[i] - d[i-1] * (*this)[i][i-1]) * id;
    \n-
    171 auto&& d_i = Impl::asVector(d[i]);
    \n-
    172 Impl::asMatrix((*this)[i][i-1]).mmv(Impl::asVector(d[i-1]), d_i);
    \n-
    173 auto tmpVec = d[i];
    \n-
    174 Impl::asMatrix(id).mv(Impl::asVector(tmpVec), d_i);
    \n-
    175 }
    \n-
    176
    \n-
    177 /* Now back substitute. */
    \n-
    178 x[this->N() - 1] = d[this->N() - 1];
    \n-
    179 for (int i = this->N() - 2; i >= 0; i--) {
    \n-
    180 //x[i] = d[i] - c[i] * x[i + 1];
    \n-
    181 x[i] = d[i];
    \n-
    182 auto&& x_i = Impl::asVector(x[i]);
    \n-
    183 Impl::asMatrix(c[i]).mmv(Impl::asVector(x[i+1]), x_i);
    \n-
    184 }
    \n-
    185
    \n-
    186 }
    \n-
    187
    \n-
    188 private:
    \n+
    88 // get vector w from object of appropriate type
    \n+
    89 rangeBlockVectorToArray(rangeBlockVector,w);
    \n+
    90 };
    \n+
    91
    \n+
    93 inline void multMtMv (Real* v, Real* w)
    \n+
    94 {
    \n+
    95 // get vector v as an object of appropriate type
    \n+
    96 arrayToDomainBlockVector(v,domainBlockVector);
    \n+
    97
    \n+
    98 // perform matrix-vector product
    \n+
    99 A_.mv(domainBlockVector,rangeBlockVector);
    \n+
    100 A_.mtv(rangeBlockVector,domainBlockVector);
    \n+
    101
    \n+
    102 // get vector w from object of appropriate type
    \n+
    103 domainBlockVectorToArray(domainBlockVector,w);
    \n+
    104 };
    \n+
    105
    \n+
    107 inline void multMMtv (Real* v, Real* w)
    \n+
    108 {
    \n+
    109 // get vector v as an object of appropriate type
    \n+
    110 arrayToRangeBlockVector(v,rangeBlockVector);
    \n+
    111
    \n+
    112 // perform matrix-vector product
    \n+
    113 A_.mtv(rangeBlockVector,domainBlockVector);
    \n+
    114 A_.mv(domainBlockVector,rangeBlockVector);
    \n+
    115
    \n+
    116 // get vector w from object of appropriate type
    \n+
    117 rangeBlockVectorToArray(rangeBlockVector,w);
    \n+
    118 };
    \n+
    119
    \n+
    121 inline int nrows () const { return m_; }
    \n+
    122
    \n+
    124 inline int ncols () const { return n_; }
    \n+
    125
    \n+
    126 protected:
    \n+
    127 // Number of rows and columns in each block of the matrix
    \n+
    128 constexpr static int mBlock = BCRSMatrix::block_type::rows;
    \n+
    129 constexpr static int nBlock = BCRSMatrix::block_type::cols;
    \n+
    130
    \n+
    131 // Type of vectors in the domain of the linear map associated with
    \n+
    132 // the matrix, i.e. block vectors compatible to matrix rows
    \n+
    133 constexpr static int dbvBlockSize = nBlock;
    \n+
    134 typedef Dune::FieldVector<Real,dbvBlockSize> DomainBlockVectorBlock;
    \n+
    135 typedef Dune::BlockVector<DomainBlockVectorBlock> DomainBlockVector;
    \n+
    136
    \n+
    137 // Type of vectors in the range of the linear map associated with
    \n+
    138 // the matrix, i.e. block vectors compatible to matrix columns
    \n+
    139 constexpr static int rbvBlockSize = mBlock;
    \n+
    140 typedef Dune::FieldVector<Real,rbvBlockSize> RangeBlockVectorBlock;
    \n+
    141 typedef Dune::BlockVector<RangeBlockVectorBlock> RangeBlockVector;
    \n+
    142
    \n+
    143 // Types for vector index access
    \n+
    144 typedef typename DomainBlockVector::size_type dbv_size_type;
    \n+
    145 typedef typename RangeBlockVector::size_type rbv_size_type;
    \n+
    146 typedef typename DomainBlockVectorBlock::size_type dbvb_size_type;
    \n+
    147 typedef typename RangeBlockVectorBlock::size_type rbvb_size_type;
    \n+
    148
    \n+
    149 // Get vector v from a block vector object which is compatible to
    \n+
    150 // matrix rows
    \n+
    151 static inline void
    \n+
    152 domainBlockVectorToArray (const DomainBlockVector& dbv, Real* v)
    \n+
    153 {
    \n+
    154 for (dbv_size_type block = 0; block < dbv.N(); ++block)
    \n+
    155 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
    \n+
    156 v[block*dbvBlockSize + iBlock] = dbv[block][iBlock];
    \n+
    157 }
    \n+
    158
    \n+
    159 // Get vector v from a block vector object which is compatible to
    \n+
    160 // matrix columns
    \n+
    161 static inline void
    \n+
    162 rangeBlockVectorToArray (const RangeBlockVector& rbv, Real* v)
    \n+
    163 {
    \n+
    164 for (rbv_size_type block = 0; block < rbv.N(); ++block)
    \n+
    165 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
    \n+
    166 v[block*rbvBlockSize + iBlock] = rbv[block][iBlock];
    \n+
    167 }
    \n+
    168
    \n+
    169 public:
    \n+
    172 static inline void arrayToDomainBlockVector (const Real* v,
    \n+
    173 DomainBlockVector& dbv)
    \n+
    174 {
    \n+
    175 for (dbv_size_type block = 0; block < dbv.N(); ++block)
    \n+
    176 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
    \n+
    177 dbv[block][iBlock] = v[block*dbvBlockSize + iBlock];
    \n+
    178 }
    \n+
    179
    \n+
    182 static inline void arrayToRangeBlockVector (const Real* v,
    \n+
    183 RangeBlockVector& rbv)
    \n+
    184 {
    \n+
    185 for (rbv_size_type block = 0; block < rbv.N(); ++block)
    \n+
    186 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
    \n+
    187 rbv[block][iBlock] = v[block*rbvBlockSize + iBlock];
    \n+
    188 }
    \n
    189
    \n-
    190 // ////////////////////////////////////////////////////////////////////////////
    \n-
    191 // The following methods from the base class should now actually be called
    \n-
    192 // ////////////////////////////////////////////////////////////////////////////
    \n+
    190 protected:
    \n+
    191 // The DUNE-ISTL BCRSMatrix
    \n+
    192 const BCRSMatrix& A_;
    \n
    193
    \n-
    194 // createbegin and createend should be in there, too, but I can't get it to compile
    \n-
    195 // BCRSMatrix<B,A>::CreateIterator createbegin () {}
    \n-
    196 // BCRSMatrix<B,A>::CreateIterator createend () {}
    \n-
    197 void setrowsize (size_type i, size_type s) {}
    \n-
    198 void incrementrowsize (size_type i) {}
    \n-
    199 void endrowsizes () {}
    \n-
    200 void addindex (size_type row, size_type col) {}
    \n-
    201 void endindices () {}
    \n-
    202 };
    \n+
    194 // Number of rows and columns in the matrix
    \n+
    195 const int m_, n_;
    \n+
    196
    \n+
    197 // Auxiliary block vector objects which are
    \n+
    198 // compatible to matrix rows / columns
    \n+
    199 mutable DomainBlockVector domainBlockVector;
    \n+
    200 mutable RangeBlockVector rangeBlockVector;
    \n+
    201 };
    \n+
    202 } // end namespace Impl
    \n
    203
    \n-
    204 template<typename B, typename A>
    \n-
    205 struct FieldTraits< BTDMatrix<B, A> >
    \n-
    206 {
    \n-\n-
    208 using real_type = typename FieldTraits<field_type>::real_type;
    \n-
    209 };
    \n-
    210
    \n-
    213} // end namespace Dune
    \n-
    214
    \n-
    215#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+
    243 template <typename BCRSMatrix, typename BlockVector>
    \n+\n+
    245 {
    \n+
    246 public:
    \n+\n+
    248
    \n+
    249 public:
    \n+\n+
    269 const unsigned int nIterationsMax = 100000,
    \n+
    270 const unsigned int verbosity_level = 0)
    \n+
    271 : m_(m), nIterationsMax_(nIterationsMax),
    \n+
    272 verbosity_level_(verbosity_level),
    \n+
    273 nIterations_(0),
    \n+
    274 title_(" ArPackPlusPlus_Algorithms: "),
    \n+
    275 blank_(title_.length(),' ')
    \n+
    276 {}
    \n+
    277
    \n+
    289 inline void computeSymMaxMagnitude (const Real& epsilon,
    \n+
    290 BlockVector& x, Real& lambda) const
    \n+
    291 {
    \n+
    292 // print verbosity information
    \n+
    293 if (verbosity_level_ > 0)
    \n+
    294 std::cout << title_ << "Computing an approximation of "
    \n+
    295 << "the dominant eigenvalue of a matrix which "
    \n+
    296 << "is assumed to be symmetric." << std::endl;
    \n+
    297
    \n+
    298 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    299 // and to perform the product A*v (LU decomposition is not used)
    \n+
    300 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    301 WrappedMatrix A(m_);
    \n+
    302
    \n+
    303 // get number of rows and columns in A
    \n+
    304 const int nrows = A.nrows();
    \n+
    305 const int ncols = A.ncols();
    \n+
    306
    \n+
    307 // assert that A is square
    \n+
    308 if (nrows != ncols)
    \n+
    309 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n+
    310 << nrows << "x" << ncols << ").");
    \n+
    311
    \n+
    312 // allocate memory for variables, set parameters
    \n+
    313 const int nev = 1; // Number of eigenvalues to compute
    \n+
    314 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    315 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    316 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    317 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n+
    318 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    319 int nconv; // Number of converged eigenvalues
    \n+
    320
    \n+
    321 // define what we need: eigenvalues with largest magnitude
    \n+
    322 char which[] = "LM";
    \n+
    323 ARSymStdEig<Real,WrappedMatrix>
    \n+
    324 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n+
    325
    \n+
    326 // set ARPACK verbosity mode if requested
    \n+
    327 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    328
    \n+
    329 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n+
    330 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    331
    \n+
    332 // obtain approximated dominant eigenvalue of A
    \n+
    333 lambda = ev[nev-1];
    \n+
    334
    \n+
    335 // obtain associated approximated eigenvector of A
    \n+
    336 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n+
    337 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n+
    338
    \n+
    339 // obtain number of Arnoldi update iterations actually taken
    \n+
    340 nIterations_ = dprob.GetIter();
    \n+
    341
    \n+
    342 // compute residual norm
    \n+
    343 BlockVector r(x);
    \n+
    344 Real* Ax_raw = new Real[nrows];
    \n+
    345 A.multMv(x_raw,Ax_raw);
    \n+
    346 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
    \n+
    347 r.axpy(-lambda,x);
    \n+
    348 const Real r_norm = r.two_norm();
    \n+
    349
    \n+
    350 // print verbosity information
    \n+
    351 if (verbosity_level_ > 0)
    \n+
    352 {
    \n+
    353 if (verbosity_level_ > 1)
    \n+
    354 {
    \n+
    355 // print some information about the problem
    \n+
    356 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n+
    357 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n+
    358 << "StdEig:" << std::endl;
    \n+
    359 std::cout << blank_ << " converged eigenvalues of A: "
    \n+
    360 << nconv << " / " << nev << std::endl;
    \n+
    361 std::cout << blank_ << " dominant eigenvalue of A: "
    \n+
    362 << lambda << std::endl;
    \n+
    363 }
    \n+
    364 std::cout << blank_ << "Result ("
    \n+
    365 << "#iterations = " << nIterations_ << ", "
    \n+
    366 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    367 << "\u03bb = " << lambda << std::endl;
    \n+
    368 if (verbosity_level_ > 2)
    \n+
    369 {
    \n+
    370 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    371 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    372 }
    \n+
    373 }
    \n+
    374
    \n+
    375 // free dynamically allocated memory
    \n+
    376 delete[] Ax_raw;
    \n+
    377 delete[] ev;
    \n+
    378 }
    \n+
    379
    \n+
    391 inline void computeSymMinMagnitude (const Real& epsilon,
    \n+
    392 BlockVector& x, Real& lambda) const
    \n+
    393 {
    \n+
    394 // print verbosity information
    \n+
    395 if (verbosity_level_ > 0)
    \n+
    396 std::cout << title_ << "Computing an approximation of the "
    \n+
    397 << "least dominant eigenvalue of a matrix which "
    \n+
    398 << "is assumed to be symmetric." << std::endl;
    \n+
    399
    \n+
    400 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    401 // and to perform the product A*v (LU decomposition is not used)
    \n+
    402 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    403 WrappedMatrix A(m_);
    \n+
    404
    \n+
    405 // get number of rows and columns in A
    \n+
    406 const int nrows = A.nrows();
    \n+
    407 const int ncols = A.ncols();
    \n+
    408
    \n+
    409 // assert that A is square
    \n+
    410 if (nrows != ncols)
    \n+
    411 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n+
    412 << nrows << "x" << ncols << ").");
    \n+
    413
    \n+
    414 // allocate memory for variables, set parameters
    \n+
    415 const int nev = 1; // Number of eigenvalues to compute
    \n+
    416 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    417 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    418 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    419 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n+
    420 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    421 int nconv; // Number of converged eigenvalues
    \n+
    422
    \n+
    423 // define what we need: eigenvalues with smallest magnitude
    \n+
    424 char which[] = "SM";
    \n+
    425 ARSymStdEig<Real,WrappedMatrix>
    \n+
    426 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n+
    427
    \n+
    428 // set ARPACK verbosity mode if requested
    \n+
    429 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    430
    \n+
    431 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n+
    432 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    433
    \n+
    434 // obtain approximated least dominant eigenvalue of A
    \n+
    435 lambda = ev[nev-1];
    \n+
    436
    \n+
    437 // obtain associated approximated eigenvector of A
    \n+
    438 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n+
    439 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n+
    440
    \n+
    441 // obtain number of Arnoldi update iterations actually taken
    \n+
    442 nIterations_ = dprob.GetIter();
    \n+
    443
    \n+
    444 // compute residual norm
    \n+
    445 BlockVector r(x);
    \n+
    446 Real* Ax_raw = new Real[nrows];
    \n+
    447 A.multMv(x_raw,Ax_raw);
    \n+
    448 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
    \n+
    449 r.axpy(-lambda,x);
    \n+
    450 const Real r_norm = r.two_norm();
    \n+
    451
    \n+
    452 // print verbosity information
    \n+
    453 if (verbosity_level_ > 0)
    \n+
    454 {
    \n+
    455 if (verbosity_level_ > 1)
    \n+
    456 {
    \n+
    457 // print some information about the problem
    \n+
    458 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n+
    459 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n+
    460 << "StdEig:" << std::endl;
    \n+
    461 std::cout << blank_ << " converged eigenvalues of A: "
    \n+
    462 << nconv << " / " << nev << std::endl;
    \n+
    463 std::cout << blank_ << " least dominant eigenvalue of A: "
    \n+
    464 << lambda << std::endl;
    \n+
    465 }
    \n+
    466 std::cout << blank_ << "Result ("
    \n+
    467 << "#iterations = " << nIterations_ << ", "
    \n+
    468 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    469 << "\u03bb = " << lambda << std::endl;
    \n+
    470 if (verbosity_level_ > 2)
    \n+
    471 {
    \n+
    472 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    473 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    474 }
    \n+
    475 }
    \n+
    476
    \n+
    477 // free dynamically allocated memory
    \n+
    478 delete[] Ax_raw;
    \n+
    479 delete[] ev;
    \n+
    480 }
    \n+
    481
    \n+
    493 inline void computeSymCond2 (const Real& epsilon, Real& cond_2) const
    \n+
    494 {
    \n+
    495 // print verbosity information
    \n+
    496 if (verbosity_level_ > 0)
    \n+
    497 std::cout << title_ << "Computing an approximation of the "
    \n+
    498 << "spectral condition number of a matrix which "
    \n+
    499 << "is assumed to be symmetric." << std::endl;
    \n+
    500
    \n+
    501 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    502 // and to perform the product A*v (LU decomposition is not used)
    \n+
    503 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    504 WrappedMatrix A(m_);
    \n+
    505
    \n+
    506 // get number of rows and columns in A
    \n+
    507 const int nrows = A.nrows();
    \n+
    508 const int ncols = A.ncols();
    \n+
    509
    \n+
    510 // assert that A is square
    \n+
    511 if (nrows != ncols)
    \n+
    512 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n+
    513 << nrows << "x" << ncols << ").");
    \n+
    514
    \n+
    515 // allocate memory for variables, set parameters
    \n+
    516 const int nev = 2; // Number of eigenvalues to compute
    \n+
    517 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    518 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    519 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    520 Real* ev = new Real[nev]; // Computed eigenvalues of A
    \n+
    521 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    522 int nconv; // Number of converged eigenvalues
    \n+
    523
    \n+
    524 // define what we need: eigenvalues from both ends of the spectrum
    \n+
    525 char which[] = "BE";
    \n+
    526 ARSymStdEig<Real,WrappedMatrix>
    \n+
    527 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
    \n+
    528
    \n+
    529 // set ARPACK verbosity mode if requested
    \n+
    530 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    531
    \n+
    532 // find eigenvalues and eigenvectors of A, obtain the eigenvalues
    \n+
    533 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    534
    \n+
    535 // obtain approximated dominant and least dominant eigenvalue of A
    \n+
    536 const Real& lambda_max = ev[nev-1];
    \n+
    537 const Real& lambda_min = ev[0];
    \n+
    538
    \n+
    539 // obtain associated approximated eigenvectors of A
    \n+
    540 Real* x_max_raw = dprob.RawEigenvector(nev-1);
    \n+
    541 Real* x_min_raw = dprob.RawEigenvector(0);
    \n+
    542
    \n+
    543 // obtain approximated spectral condition number of A
    \n+
    544 cond_2 = std::abs(lambda_max / lambda_min);
    \n+
    545
    \n+
    546 // obtain number of Arnoldi update iterations actually taken
    \n+
    547 nIterations_ = dprob.GetIter();
    \n+
    548
    \n+
    549 // compute each residual norm
    \n+
    550 Real* Ax_max_raw = new Real[nrows];
    \n+
    551 Real* Ax_min_raw = new Real[nrows];
    \n+
    552 A.multMv(x_max_raw,Ax_max_raw);
    \n+
    553 A.multMv(x_min_raw,Ax_min_raw);
    \n+
    554 Real r_max_norm = 0.0;
    \n+
    555 Real r_min_norm = 0.0;
    \n+
    556 for (int i = 0; i < nrows; ++i)
    \n+
    557 {
    \n+
    558 r_max_norm += std::pow(Ax_max_raw[i] - lambda_max * x_max_raw[i],2);
    \n+
    559 r_min_norm += std::pow(Ax_min_raw[i] - lambda_min * x_min_raw[i],2);
    \n+
    560 }
    \n+
    561 r_max_norm = std::sqrt(r_max_norm);
    \n+
    562 r_min_norm = std::sqrt(r_min_norm);
    \n+
    563
    \n+
    564 // print verbosity information
    \n+
    565 if (verbosity_level_ > 0)
    \n+
    566 {
    \n+
    567 if (verbosity_level_ > 1)
    \n+
    568 {
    \n+
    569 // print some information about the problem
    \n+
    570 std::cout << blank_ << "Obtained eigenvalues of A by solving "
    \n+
    571 << "A*x = \u03bb*x using the ARPACK++ class ARSym"
    \n+
    572 << "StdEig:" << std::endl;
    \n+
    573 std::cout << blank_ << " converged eigenvalues of A: "
    \n+
    574 << nconv << " / " << nev << std::endl;
    \n+
    575 std::cout << blank_ << " dominant eigenvalue of A: "
    \n+
    576 << lambda_max << std::endl;
    \n+
    577 std::cout << blank_ << " least dominant eigenvalue of A: "
    \n+
    578 << lambda_min << std::endl;
    \n+
    579 std::cout << blank_ << " spectral condition number of A: "
    \n+
    580 << cond_2 << std::endl;
    \n+
    581 }
    \n+
    582 std::cout << blank_ << "Result ("
    \n+
    583 << "#iterations = " << nIterations_ << ", "
    \n+
    584 << "\u2551residual\u2551_2 = {" << r_max_norm << ","
    \n+
    585 << r_min_norm << "}, " << "\u03bb = {"
    \n+
    586 << lambda_max << "," << lambda_min
    \n+
    587 << "}): cond_2 = " << cond_2 << std::endl;
    \n+
    588 }
    \n+
    589
    \n+
    590 // free dynamically allocated memory
    \n+
    591 delete[] Ax_min_raw;
    \n+
    592 delete[] Ax_max_raw;
    \n+
    593 delete[] ev;
    \n+
    594 }
    \n+
    595
    \n+
    609 inline void computeNonSymMax (const Real& epsilon,
    \n+
    610 BlockVector& x, Real& sigma) const
    \n+
    611 {
    \n+
    612 // print verbosity information
    \n+
    613 if (verbosity_level_ > 0)
    \n+
    614 std::cout << title_ << "Computing an approximation of the "
    \n+
    615 << "largest singular value of a matrix which "
    \n+
    616 << "is assumed to be nonsymmetric." << std::endl;
    \n+
    617
    \n+
    618 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    619 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n+
    620 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    621 WrappedMatrix A(m_);
    \n+
    622
    \n+
    623 // get number of rows and columns in A
    \n+
    624 const int nrows = A.nrows();
    \n+
    625 const int ncols = A.ncols();
    \n+
    626
    \n+
    627 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n+
    628 if (nrows < ncols)
    \n+
    629 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n+
    630 << "columns (" << nrows << "x" << ncols << ")."
    \n+
    631 << " This case is not implemented, yet.");
    \n+
    632
    \n+
    633 // allocate memory for variables, set parameters
    \n+
    634 const int nev = 1; // Number of eigenvalues to compute
    \n+
    635 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    636 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    637 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    638 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n+
    639 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    640 int nconv; // Number of converged eigenvalues
    \n+
    641
    \n+
    642 // define what we need: eigenvalues with largest algebraic value
    \n+
    643 char which[] = "LA";
    \n+
    644 ARSymStdEig<Real,WrappedMatrix>
    \n+
    645 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n+
    646
    \n+
    647 // set ARPACK verbosity mode if requested
    \n+
    648 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    649
    \n+
    650 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n+
    651 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    652
    \n+
    653 // obtain approximated largest eigenvalue of A^T*A
    \n+
    654 const Real& lambda = ev[nev-1];
    \n+
    655
    \n+
    656 // obtain associated approximated eigenvector of A^T*A
    \n+
    657 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n+
    658 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n+
    659
    \n+
    660 // obtain number of Arnoldi update iterations actually taken
    \n+
    661 nIterations_ = dprob.GetIter();
    \n+
    662
    \n+
    663 // compute residual norm
    \n+
    664 BlockVector r(x);
    \n+
    665 Real* AtAx_raw = new Real[ncols];
    \n+
    666 A.multMtMv(x_raw,AtAx_raw);
    \n+
    667 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
    \n+
    668 r.axpy(-lambda,x);
    \n+
    669 const Real r_norm = r.two_norm();
    \n+
    670
    \n+
    671 // calculate largest singular value of A (note that
    \n+
    672 // x is right-singular / left-singular vector of A)
    \n+
    673 sigma = std::sqrt(lambda);
    \n+
    674
    \n+
    675 // print verbosity information
    \n+
    676 if (verbosity_level_ > 0)
    \n+
    677 {
    \n+
    678 if (verbosity_level_ > 1)
    \n+
    679 {
    \n+
    680 // print some information about the problem
    \n+
    681 std::cout << blank_ << "Obtained singular values of A by sol"
    \n+
    682 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n+
    683 << "class ARSymStdEig:" << std::endl;
    \n+
    684 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n+
    685 << nconv << " / " << nev << std::endl;
    \n+
    686 std::cout << blank_ << " largest eigenvalue of A^T*A: "
    \n+
    687 << lambda << std::endl;
    \n+
    688 std::cout << blank_ << " => largest singular value of A: "
    \n+
    689 << sigma << std::endl;
    \n+
    690 }
    \n+
    691 std::cout << blank_ << "Result ("
    \n+
    692 << "#iterations = " << nIterations_ << ", "
    \n+
    693 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    694 << "\u03c3 = " << sigma << std::endl;
    \n+
    695 if (verbosity_level_ > 2)
    \n+
    696 {
    \n+
    697 // print approximated right-singular / left-singular vector
    \n+
    698 // via DUNE-ISTL I/O methods
    \n+
    699 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    700 }
    \n+
    701 }
    \n+
    702
    \n+
    703 // free dynamically allocated memory
    \n+
    704 delete[] AtAx_raw;
    \n+
    705 delete[] ev;
    \n+
    706 }
    \n+
    707
    \n+
    721 inline void computeNonSymMin (const Real& epsilon,
    \n+
    722 BlockVector& x, Real& sigma) const
    \n+
    723 {
    \n+
    724 // print verbosity information
    \n+
    725 if (verbosity_level_ > 0)
    \n+
    726 std::cout << title_ << "Computing an approximation of the "
    \n+
    727 << "smallest singular value of a matrix which "
    \n+
    728 << "is assumed to be nonsymmetric." << std::endl;
    \n+
    729
    \n+
    730 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    731 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n+
    732 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    733 WrappedMatrix A(m_);
    \n+
    734
    \n+
    735 // get number of rows and columns in A
    \n+
    736 const int nrows = A.nrows();
    \n+
    737 const int ncols = A.ncols();
    \n+
    738
    \n+
    739 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n+
    740 if (nrows < ncols)
    \n+
    741 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n+
    742 << "columns (" << nrows << "x" << ncols << ")."
    \n+
    743 << " This case is not implemented, yet.");
    \n+
    744
    \n+
    745 // allocate memory for variables, set parameters
    \n+
    746 const int nev = 1; // Number of eigenvalues to compute
    \n+
    747 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    748 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    749 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    750 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n+
    751 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    752 int nconv; // Number of converged eigenvalues
    \n+
    753
    \n+
    754 // define what we need: eigenvalues with smallest algebraic value
    \n+
    755 char which[] = "SA";
    \n+
    756 ARSymStdEig<Real,WrappedMatrix>
    \n+
    757 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n+
    758
    \n+
    759 // set ARPACK verbosity mode if requested
    \n+
    760 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    761
    \n+
    762 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n+
    763 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    764
    \n+
    765 // obtain approximated smallest eigenvalue of A^T*A
    \n+
    766 const Real& lambda = ev[nev-1];
    \n+
    767
    \n+
    768 // obtain associated approximated eigenvector of A^T*A
    \n+
    769 Real* x_raw = dprob.RawEigenvector(nev-1);
    \n+
    770 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
    \n+
    771
    \n+
    772 // obtain number of Arnoldi update iterations actually taken
    \n+
    773 nIterations_ = dprob.GetIter();
    \n+
    774
    \n+
    775 // compute residual norm
    \n+
    776 BlockVector r(x);
    \n+
    777 Real* AtAx_raw = new Real[ncols];
    \n+
    778 A.multMtMv(x_raw,AtAx_raw);
    \n+
    779 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
    \n+
    780 r.axpy(-lambda,x);
    \n+
    781 const Real r_norm = r.two_norm();
    \n+
    782
    \n+
    783 // calculate smallest singular value of A (note that
    \n+
    784 // x is right-singular / left-singular vector of A)
    \n+
    785 sigma = std::sqrt(lambda);
    \n+
    786
    \n+
    787 // print verbosity information
    \n+
    788 if (verbosity_level_ > 0)
    \n+
    789 {
    \n+
    790 if (verbosity_level_ > 1)
    \n+
    791 {
    \n+
    792 // print some information about the problem
    \n+
    793 std::cout << blank_ << "Obtained singular values of A by sol"
    \n+
    794 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n+
    795 << "class ARSymStdEig:" << std::endl;
    \n+
    796 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n+
    797 << nconv << " / " << nev << std::endl;
    \n+
    798 std::cout << blank_ << " smallest eigenvalue of A^T*A: "
    \n+
    799 << lambda << std::endl;
    \n+
    800 std::cout << blank_ << " => smallest singular value of A: "
    \n+
    801 << sigma << std::endl;
    \n+
    802 }
    \n+
    803 std::cout << blank_ << "Result ("
    \n+
    804 << "#iterations = " << nIterations_ << ", "
    \n+
    805 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    806 << "\u03c3 = " << sigma << std::endl;
    \n+
    807 if (verbosity_level_ > 2)
    \n+
    808 {
    \n+
    809 // print approximated right-singular / left-singular vector
    \n+
    810 // via DUNE-ISTL I/O methods
    \n+
    811 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    812 }
    \n+
    813 }
    \n+
    814
    \n+
    815 // free dynamically allocated memory
    \n+
    816 delete[] AtAx_raw;
    \n+
    817 delete[] ev;
    \n+
    818 }
    \n+
    819
    \n+
    830 inline void computeNonSymCond2 (const Real& epsilon, Real& cond_2) const
    \n+
    831 {
    \n+
    832 // print verbosity information
    \n+
    833 if (verbosity_level_ > 0)
    \n+
    834 std::cout << title_ << "Computing an approximation of the "
    \n+
    835 << "spectral condition number of a matrix which "
    \n+
    836 << "is assumed to be nonsymmetric." << std::endl;
    \n+
    837
    \n+
    838 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information
    \n+
    839 // and to perform the product A^T*A*v (LU decomposition is not used)
    \n+
    840 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
    \n+
    841 WrappedMatrix A(m_);
    \n+
    842
    \n+
    843 // get number of rows and columns in A
    \n+
    844 const int nrows = A.nrows();
    \n+
    845 const int ncols = A.ncols();
    \n+
    846
    \n+
    847 // assert that A has more rows than columns (extend code later to the opposite case!)
    \n+
    848 if (nrows < ncols)
    \n+
    849 DUNE_THROW(Dune::ISTLError,"Matrix has less rows than "
    \n+
    850 << "columns (" << nrows << "x" << ncols << ")."
    \n+
    851 << " This case is not implemented, yet.");
    \n+
    852
    \n+
    853 // allocate memory for variables, set parameters
    \n+
    854 const int nev = 2; // Number of eigenvalues to compute
    \n+
    855 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at each iteration (0 == auto)
    \n+
    856 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz values) (0 == machine precision)
    \n+
    857 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update iterations allowed (0 == 100*nev)
    \n+
    858 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A
    \n+
    859 const bool ivec = true; // Flag deciding if eigenvectors shall be determined
    \n+
    860 int nconv; // Number of converged eigenvalues
    \n+
    861
    \n+
    862 // define what we need: eigenvalues from both ends of the spectrum
    \n+
    863 char which[] = "BE";
    \n+
    864 ARSymStdEig<Real,WrappedMatrix>
    \n+
    865 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
    \n+
    866
    \n+
    867 // set ARPACK verbosity mode if requested
    \n+
    868 if (verbosity_level_ > 3) dprob.Trace();
    \n+
    869
    \n+
    870 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues
    \n+
    871 nconv = dprob.Eigenvalues(ev,ivec);
    \n+
    872
    \n+
    873 // obtain approximated largest and smallest eigenvalue of A^T*A
    \n+
    874 const Real& lambda_max = ev[nev-1];
    \n+
    875 const Real& lambda_min = ev[0];
    \n+
    876
    \n+
    877 // obtain associated approximated eigenvectors of A^T*A
    \n+
    878 Real* x_max_raw = dprob.RawEigenvector(nev-1);
    \n+
    879 Real* x_min_raw = dprob.RawEigenvector(0);
    \n+
    880
    \n+
    881 // obtain number of Arnoldi update iterations actually taken
    \n+
    882 nIterations_ = dprob.GetIter();
    \n+
    883
    \n+
    884 // compute each residual norm
    \n+
    885 Real* AtAx_max_raw = new Real[ncols];
    \n+
    886 Real* AtAx_min_raw = new Real[ncols];
    \n+
    887 A.multMtMv(x_max_raw,AtAx_max_raw);
    \n+
    888 A.multMtMv(x_min_raw,AtAx_min_raw);
    \n+
    889 Real r_max_norm = 0.0;
    \n+
    890 Real r_min_norm = 0.0;
    \n+
    891 for (int i = 0; i < ncols; ++i)
    \n+
    892 {
    \n+
    893 r_max_norm += std::pow(AtAx_max_raw[i] - lambda_max * x_max_raw[i],2);
    \n+
    894 r_min_norm += std::pow(AtAx_min_raw[i] - lambda_min * x_min_raw[i],2);
    \n+
    895 }
    \n+
    896 r_max_norm = std::sqrt(r_max_norm);
    \n+
    897 r_min_norm = std::sqrt(r_min_norm);
    \n+
    898
    \n+
    899 // calculate largest and smallest singular value of A
    \n+
    900 const Real sigma_max = std::sqrt(lambda_max);
    \n+
    901 const Real sigma_min = std::sqrt(lambda_min);
    \n+
    902
    \n+
    903 // obtain approximated spectral condition number of A
    \n+
    904 cond_2 = sigma_max / sigma_min;
    \n+
    905
    \n+
    906 // print verbosity information
    \n+
    907 if (verbosity_level_ > 0)
    \n+
    908 {
    \n+
    909 if (verbosity_level_ > 1)
    \n+
    910 {
    \n+
    911 // print some information about the problem
    \n+
    912 std::cout << blank_ << "Obtained singular values of A by sol"
    \n+
    913 << "ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ "
    \n+
    914 << "class ARSymStdEig:" << std::endl;
    \n+
    915 std::cout << blank_ << " converged eigenvalues of A^T*A: "
    \n+
    916 << nconv << " / " << nev << std::endl;
    \n+
    917 std::cout << blank_ << " largest eigenvalue of A^T*A: "
    \n+
    918 << lambda_max << std::endl;
    \n+
    919 std::cout << blank_ << " smallest eigenvalue of A^T*A: "
    \n+
    920 << lambda_min << std::endl;
    \n+
    921 std::cout << blank_ << " => largest singular value of A: "
    \n+
    922 << sigma_max << std::endl;
    \n+
    923 std::cout << blank_ << " => smallest singular value of A: "
    \n+
    924 << sigma_min << std::endl;
    \n+
    925 }
    \n+
    926 std::cout << blank_ << "Result ("
    \n+
    927 << "#iterations = " << nIterations_ << ", "
    \n+
    928 << "\u2551residual\u2551_2 = {" << r_max_norm << ","
    \n+
    929 << r_min_norm << "}, " << "\u03c3 = {"
    \n+
    930 << sigma_max << "," << sigma_min
    \n+
    931 << "}): cond_2 = " << cond_2 << std::endl;
    \n+
    932 }
    \n+
    933
    \n+
    934 // free dynamically allocated memory
    \n+
    935 delete[] AtAx_min_raw;
    \n+
    936 delete[] AtAx_max_raw;
    \n+
    937 delete[] ev;
    \n+
    938 }
    \n+
    939
    \n+
    944 inline unsigned int getIterationCount () const
    \n+
    945 {
    \n+
    946 if (nIterations_ == 0)
    \n+
    947 DUNE_THROW(Dune::ISTLError,"No algorithm applied, yet.");
    \n+
    948
    \n+
    949 return nIterations_;
    \n+
    950 }
    \n+
    951
    \n+
    952 protected:
    \n+
    953 // parameters related to iterative eigenvalue algorithms
    \n+\n+
    955 const unsigned int nIterationsMax_;
    \n+
    956
    \n+
    957 // verbosity setting
    \n+
    958 const unsigned int verbosity_level_;
    \n+
    959
    \n+
    960 // memory for storing temporary variables (mutable as they shall
    \n+
    961 // just be effectless auxiliary variables of the const apply*(...)
    \n+
    962 // methods)
    \n+
    963 mutable unsigned int nIterations_;
    \n+
    964
    \n+
    965 // constants for printing verbosity information
    \n+
    966 const std::string title_;
    \n+
    967 const std::string blank_;
    \n+
    968 };
    \n+
    969
    \n+
    972} // namespace Dune
    \n+
    973
    \n+
    974#endif // HAVE_ARPACKPP
    \n+
    975
    \n+
    976#endif // DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n+
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n+\n+
    Helper functions for determining the vector/matrix block level.
    \n+
    void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
    Print an ISTL vector.
    Definition: io.hh:89
    \n
    Definition: allocator.hh:11
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    void endrowsizes()
    indicate that size of all rows is defined
    Definition: bcrsmatrix.hh:1149
    \n-
    @ random
    Build entries randomly.
    Definition: bcrsmatrix.hh:530
    \n-
    void addindex(size_type row, size_type col)
    add index (row,col) to the matrix
    Definition: bcrsmatrix.hh:1191
    \n-
    void endindices()
    indicate that all indices are defined, check consistency
    Definition: bcrsmatrix.hh:1248
    \n-
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n-
    void setSize(size_type rows, size_type columns, size_type nnz=0)
    Set the size of the matrix.
    Definition: bcrsmatrix.hh:861
    \n-
    BCRSMatrix & operator=(const BCRSMatrix &Mat)
    assignment
    Definition: bcrsmatrix.hh:911
    \n-
    A block-tridiagonal matrix.
    Definition: btdmatrix.hh:31
    \n-
    static constexpr auto blocklevel
    increment block level counter
    Definition: btdmatrix.hh:53
    \n-
    BTDMatrix(size_type size)
    Definition: btdmatrix.hh:58
    \n-
    void solve(V &x, const V &rhs) const
    Use the Thomas algorithm to solve the system Ax=b in O(n) time.
    Definition: btdmatrix.hh:125
    \n-
    A::size_type size_type
    implement row_type with compressed vector
    Definition: btdmatrix.hh:49
    \n-
    A allocator_type
    export the allocator type
    Definition: btdmatrix.hh:43
    \n-
    B block_type
    export the type representing the components
    Definition: btdmatrix.hh:40
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: btdmatrix.hh:37
    \n-
    BTDMatrix & operator=(const BTDMatrix &other)
    assignment
    Definition: btdmatrix.hh:108
    \n-
    BTDMatrix()
    Default constructor.
    Definition: btdmatrix.hh:56
    \n-
    void setSize(size_type size)
    Resize the matrix. Invalidates the content!
    Definition: btdmatrix.hh:81
    \n-
    typename FieldTraits< field_type >::real_type real_type
    Definition: btdmatrix.hh:208
    \n-
    typename BTDMatrix< B, A >::field_type field_type
    Definition: btdmatrix.hh:207
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bcrsmatrix.hh:488
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n+
    A::size_type size_type
    The type for the index access.
    Definition: bvector.hh:410
    \n+
    Wrapper to use a range of ARPACK++ eigenvalue solvers.
    Definition: arpackpp.hh:245
    \n+
    const unsigned int verbosity_level_
    Definition: arpackpp.hh:958
    \n+
    unsigned int getIterationCount() const
    Return the number of iterations in last application of an algorithm.
    Definition: arpackpp.hh:944
    \n+
    const std::string title_
    Definition: arpackpp.hh:966
    \n+
    BlockVector::field_type Real
    Definition: arpackpp.hh:247
    \n+
    void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:289
    \n+
    void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
    Definition: arpackpp.hh:391
    \n+
    const BCRSMatrix & m_
    Definition: arpackpp.hh:954
    \n+
    const unsigned int nIterationsMax_
    Definition: arpackpp.hh:955
    \n+
    const std::string blank_
    Definition: arpackpp.hh:967
    \n+
    ArPackPlusPlus_Algorithms(const BCRSMatrix &m, const unsigned int nIterationsMax=100000, const unsigned int verbosity_level=0)
    Construct from required parameters.
    Definition: arpackpp.hh:268
    \n+
    void computeSymCond2(const Real &epsilon, Real &cond_2) const
    Assume the matrix to be square, symmetric and perform IRLM to compute an approximation of its spectra...
    Definition: arpackpp.hh:493
    \n+
    unsigned int nIterations_
    Definition: arpackpp.hh:963
    \n+
    void computeNonSymMin(const Real &epsilon, BlockVector &x, Real &sigma) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its smalle...
    Definition: arpackpp.hh:721
    \n+
    void computeNonSymCond2(const Real &epsilon, Real &cond_2) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation of its spectral con...
    Definition: arpackpp.hh:830
    \n+
    void computeNonSymMax(const Real &epsilon, BlockVector &x, Real &sigma) const
    Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its larges...
    Definition: arpackpp.hh:609
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-us-ascii\n+utf-8\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,290 +4,956 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-btdmatrix.hh\n+ * eigenvalue\n+arpackpp.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_BTDMATRIX_HH\n- 6#define DUNE_ISTL_BTDMATRIX_HH\n+ 5#ifndef DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n+ 6#define DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13\n- 19namespace Dune {\n- 29 template >\n-30 class BTDMatrix : public BCRSMatrix\n- 31 {\n- 32 public:\n- 33\n- 34 //===== type definitions and constants\n- 35\n-37 using field_type = typename Imp::BlockTraits::field_type;\n- 38\n-40 typedef B block_type;\n- 41\n-43 typedef A allocator_type;\n- 44\n- 46 //typedef BCRSMatrix::row_type row_type;\n- 47\n-49 typedef typename A::size_type size_type;\n- 50\n- 52 [[deprecated(\"Use free blockLevel function. Will be removed after 2.8.\")]]\n-53 static constexpr auto blocklevel = blockLevel()+1;\n- 54\n-56 BTDMatrix() : BCRSMatrix() {}\n- 57\n-58 explicit BTDMatrix(size_type size)\n- 59 : BCRSMatrix(size, size, BCRSMatrix::random)\n- 60 {\n- 61 // Set number of entries for each row\n- 62 // All rows get three entries, except for the first and the last one\n- 63 for (size_t i=0; iBCRSMatrix::setrowsize(i, 3 - (i==0) - (i==(size-1)));\n- 65\n- 66 this->BCRSMatrix::endrowsizes();\n- 67\n- 68 // The actual entries for each row\n- 69 for (size_t i=0; i0)\n- 71 this->BCRSMatrix::addindex(i, i-1);\n- 72 this->BCRSMatrix::addindex(i, i );\n- 73 if (iBCRSMatrix::addindex(i, i+1);\n- 75 }\n- 76\n- 77 this->BCRSMatrix::endindices();\n- 78 }\n- 79\n-81 void setSize(size_type size)\n- 82 {\n- 83 auto nonZeros = (size==0) ? 0 : size + 2*(size-1);\n- 84 this->BCRSMatrix::setSize(size, // rows\n- 85 size, // columns\n- 86 nonZeros);\n+ 8#if HAVE_ARPACKPP || defined DOXYGEN\n+ 9\n+ 10#include // provides std::abs, std::pow, std::sqrt\n+ 11\n+ 12#include // provides std::cout, std::endl\n+ 13#include // provides std::string\n+ 14\n+ 15#include // provides Dune::FieldVector\n+ 16#include // provides DUNE_THROW(...)\n+ 17\n+ 18#include // provides Dune::blockLevel\n+ 19#include // provides Dune::BlockVector\n+ 20#include // provides Dune::ISTLError\n+ 21#include // provides Dune::printvector(...)\n+ 22\n+ 23#ifdef Status\n+ 24#undef Status // prevent preprocessor from damaging the ARPACK++\n+ 25 // code when \"X11/Xlib.h\" is included (the latter\n+ 26 // defines Status as \"#define Status int\" and\n+ 27 // ARPACK++ provides a class with a method called\n+ 28 // Status)\n+ 29#endif\n+ 30#include \"arssym.h\" // provides ARSymStdEig\n+ 31\n+ 32namespace Dune\n+ 33{\n+ 34\n+ 39 namespace Impl {\n+ 55 template \n+ 56 class ArPackPlusPlus_BCRSMatrixWrapper\n+ 57 {\n+ 58 public:\n+ 60 typedef typename BCRSMatrix::field_type Real;\n+ 61\n+ 62 public:\n+ 64 ArPackPlusPlus_BCRSMatrixWrapper (const BCRSMatrix& A)\n+ 65 : A_(A),\n+ 66 m_(A_.M() * mBlock), n_(A_.N() * nBlock)\n+ 67 {\n+ 68 // assert that BCRSMatrix type has blocklevel 2\n+ 69 static_assert\n+ 70 (blockLevel() == 2,\n+ 71 \"Only BCRSMatrices with blocklevel 2 are supported.\");\n+ 72\n+ 73 // allocate memory for auxiliary block vector objects\n+ 74 // which are compatible to matrix rows / columns\n+ 75 domainBlockVector.resize(A_.N());\n+ 76 rangeBlockVector.resize(A_.M());\n+ 77 }\n+ 78\n+ 80 inline void multMv (Real* v, Real* w)\n+ 81 {\n+ 82 // get vector v as an object of appropriate type\n+ 83 arrayToDomainBlockVector(v,domainBlockVector);\n+ 84\n+ 85 // perform matrix-vector product\n+ 86 A_.mv(domainBlockVector,rangeBlockVector);\n 87\n- 88 // Set number of entries for each row\n- 89 // All rows get three entries, except for the first and the last one\n- 90 for (size_t i=0; iBCRSMatrix::setrowsize(i, 3 - (i==0) - (i==(size-1)));\n- 92\n- 93 this->BCRSMatrix::endrowsizes();\n- 94\n- 95 // The actual entries for each row\n- 96 for (size_t i=0; i0)\n- 98 this->BCRSMatrix::addindex(i, i-1);\n- 99 this->BCRSMatrix::addindex(i, i );\n- 100 if (iBCRSMatrix::addindex(i, i+1);\n- 102 }\n- 103\n- 104 this->BCRSMatrix::endindices();\n- 105 }\n- 106\n-108 BTDMatrix& operator=(const BTDMatrix& other) {\n- 109 this->BCRSMatrix::operator=(other);\n- 110 return *this;\n- 111 }\n- 112\n-114 BTDMatrix& operator=(const field_type& k) {\n- 115 this->BCRSMatrix::operator=(k);\n- 116 return *this;\n- 117 }\n- 118\n- 124 template \n-125 void solve (V& x, const V& rhs) const {\n- 126\n- 127 // special handling for 1x1 matrices. The generic algorithm doesn't work\n-for them\n- 128 if (this->N()==1) {\n- 129 auto&& x0 = Impl::asVector(x[0]);\n- 130 auto&& rhs0 = Impl::asVector(rhs[0]);\n- 131 Impl::asMatrix((*this)[0][0]).solve(x0, rhs0);\n- 132 return;\n- 133 }\n- 134\n- 135 // Make copies of the rhs and the right matrix band\n- 136 V d = rhs;\n- 137 std::vector c(this->N()-1);\n- 138 for (size_t i=0; iN()-1; i++)\n- 139 c[i] = (*this)[i][i+1];\n- 140\n- 141 /* Modify the coefficients. */\n- 142 block_type a_00_inv = (*this)[0][0];\n- 143 Impl::asMatrix(a_00_inv).invert();\n- 144\n- 145 //c[0] /= (*this)[0][0]; /* Division by zero risk. */\n- 146 block_type tmp = a_00_inv;\n- 147 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[0]));\n- 148 c[0] = tmp;\n- 149\n- 150 // d = a^{-1} d /* Division by zero would imply a singular matrix. */\n- 151 auto d_0_tmp = d[0];\n- 152 auto&& d_0 = Impl::asVector(d[0]);\n- 153 Impl::asMatrix(a_00_inv).mv(Impl::asVector(d_0_tmp),d_0);\n- 154\n- 155 for (unsigned int i = 1; i < this->N(); i++) {\n- 156\n- 157 // id = ( a_ii - c_{i-1} a_{i, i-1} ) ^{-1}\n- 158 block_type tmp;\n- 159 tmp = (*this)[i][i-1];\n- 160 Impl::asMatrix(tmp).rightmultiply(Impl::asMatrix(c[i-1]));\n- 161\n- 162 block_type id = (*this)[i][i];\n- 163 id -= tmp;\n- 164 Impl::asMatrix(id).invert(); /* Division by zero risk. */\n- 165\n- 166 if (iN() - 1] = d[this->N() - 1];\n- 179 for (int i = this->N() - 2; i >= 0; i--) {\n- 180 //x[i] = d[i] - c[i] * x[i + 1];\n- 181 x[i] = d[i];\n- 182 auto&& x_i = Impl::asVector(x[i]);\n- 183 Impl::asMatrix(c[i]).mmv(Impl::asVector(x[i+1]), x_i);\n- 184 }\n- 185\n- 186 }\n- 187\n- 188 private:\n+ 88 // get vector w from object of appropriate type\n+ 89 rangeBlockVectorToArray(rangeBlockVector,w);\n+ 90 };\n+ 91\n+ 93 inline void multMtMv (Real* v, Real* w)\n+ 94 {\n+ 95 // get vector v as an object of appropriate type\n+ 96 arrayToDomainBlockVector(v,domainBlockVector);\n+ 97\n+ 98 // perform matrix-vector product\n+ 99 A_.mv(domainBlockVector,rangeBlockVector);\n+ 100 A_.mtv(rangeBlockVector,domainBlockVector);\n+ 101\n+ 102 // get vector w from object of appropriate type\n+ 103 domainBlockVectorToArray(domainBlockVector,w);\n+ 104 };\n+ 105\n+ 107 inline void multMMtv (Real* v, Real* w)\n+ 108 {\n+ 109 // get vector v as an object of appropriate type\n+ 110 arrayToRangeBlockVector(v,rangeBlockVector);\n+ 111\n+ 112 // perform matrix-vector product\n+ 113 A_.mtv(rangeBlockVector,domainBlockVector);\n+ 114 A_.mv(domainBlockVector,rangeBlockVector);\n+ 115\n+ 116 // get vector w from object of appropriate type\n+ 117 rangeBlockVectorToArray(rangeBlockVector,w);\n+ 118 };\n+ 119\n+ 121 inline int nrows () const { return m_; }\n+ 122\n+ 124 inline int ncols () const { return n_; }\n+ 125\n+ 126 protected:\n+ 127 // Number of rows and columns in each block of the matrix\n+ 128 constexpr static int mBlock = BCRSMatrix::block_type::rows;\n+ 129 constexpr static int nBlock = BCRSMatrix::block_type::cols;\n+ 130\n+ 131 // Type of vectors in the domain of the linear map associated with\n+ 132 // the matrix, i.e. block vectors compatible to matrix rows\n+ 133 constexpr static int dbvBlockSize = nBlock;\n+ 134 typedef Dune::FieldVector DomainBlockVectorBlock;\n+ 135 typedef Dune::BlockVector DomainBlockVector;\n+ 136\n+ 137 // Type of vectors in the range of the linear map associated with\n+ 138 // the matrix, i.e. block vectors compatible to matrix columns\n+ 139 constexpr static int rbvBlockSize = mBlock;\n+ 140 typedef Dune::FieldVector RangeBlockVectorBlock;\n+ 141 typedef Dune::BlockVector RangeBlockVector;\n+ 142\n+ 143 // Types for vector index access\n+ 144 typedef typename DomainBlockVector::size_type dbv_size_type;\n+ 145 typedef typename RangeBlockVector::size_type rbv_size_type;\n+ 146 typedef typename DomainBlockVectorBlock::size_type dbvb_size_type;\n+ 147 typedef typename RangeBlockVectorBlock::size_type rbvb_size_type;\n+ 148\n+ 149 // Get vector v from a block vector object which is compatible to\n+ 150 // matrix rows\n+ 151 static inline void\n+ 152 domainBlockVectorToArray (const DomainBlockVector& dbv, Real* v)\n+ 153 {\n+ 154 for (dbv_size_type block = 0; block < dbv.N(); ++block)\n+ 155 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)\n+ 156 v[block*dbvBlockSize + iBlock] = dbv[block][iBlock];\n+ 157 }\n+ 158\n+ 159 // Get vector v from a block vector object which is compatible to\n+ 160 // matrix columns\n+ 161 static inline void\n+ 162 rangeBlockVectorToArray (const RangeBlockVector& rbv, Real* v)\n+ 163 {\n+ 164 for (rbv_size_type block = 0; block < rbv.N(); ++block)\n+ 165 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)\n+ 166 v[block*rbvBlockSize + iBlock] = rbv[block][iBlock];\n+ 167 }\n+ 168\n+ 169 public:\n+ 172 static inline void arrayToDomainBlockVector (const Real* v,\n+ 173 DomainBlockVector& dbv)\n+ 174 {\n+ 175 for (dbv_size_type block = 0; block < dbv.N(); ++block)\n+ 176 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)\n+ 177 dbv[block][iBlock] = v[block*dbvBlockSize + iBlock];\n+ 178 }\n+ 179\n+ 182 static inline void arrayToRangeBlockVector (const Real* v,\n+ 183 RangeBlockVector& rbv)\n+ 184 {\n+ 185 for (rbv_size_type block = 0; block < rbv.N(); ++block)\n+ 186 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)\n+ 187 rbv[block][iBlock] = v[block*rbvBlockSize + iBlock];\n+ 188 }\n 189\n- 190 // ///////////////////////////////////////////////////////////////////////\n-/////\n- 191 // The following methods from the base class should now actually be called\n- 192 // ///////////////////////////////////////////////////////////////////////\n-/////\n+ 190 protected:\n+ 191 // The DUNE-ISTL BCRSMatrix\n+ 192 const BCRSMatrix& A_;\n 193\n- 194 // createbegin and createend should be in there, too, but I can't get it\n-to compile\n- 195 // BCRSMatrix::CreateIterator createbegin () {}\n- 196 // BCRSMatrix::CreateIterator createend () {}\n- 197 void setrowsize (size_type i, size_type s) {}\n- 198 void incrementrowsize (size_type i) {}\n- 199 void endrowsizes () {}\n- 200 void addindex (size_type row, size_type col) {}\n- 201 void endindices () {}\n- 202 };\n+ 194 // Number of rows and columns in the matrix\n+ 195 const int m_, n_;\n+ 196\n+ 197 // Auxiliary block vector objects which are\n+ 198 // compatible to matrix rows / columns\n+ 199 mutable DomainBlockVector domainBlockVector;\n+ 200 mutable RangeBlockVector rangeBlockVector;\n+ 201 };\n+ 202 } // end namespace Impl\n 203\n- 204 template\n-205 struct FieldTraits< BTDMatrix >\n- 206 {\n-207 using field_type = typename BTDMatrix::field_type;\n-208 using real_type = typename FieldTraits::real_type;\n- 209 };\n- 210\n- 213} // end namespace Dune\n- 214\n- 215#endif\n+ 243 template \n+244 class ArPackPlusPlus_Algorithms\n+ 245 {\n+ 246 public:\n+247 typedef typename BlockVector::field_type Real;\n+ 248\n+ 249 public:\n+268 ArPackPlusPlus_Algorithms (const BCRSMatrix& m,\n+ 269 const unsigned int nIterationsMax = 100000,\n+ 270 const unsigned int verbosity_level = 0)\n+ 271 : m_(m), nIterationsMax_(nIterationsMax),\n+ 272 verbosity_level_(verbosity_level),\n+ 273 nIterations_(0),\n+ 274 title_(\" ArPackPlusPlus_Algorithms: \"),\n+ 275 blank_(title_.length(),' ')\n+ 276 {}\n+ 277\n+289 inline void computeSymMaxMagnitude (const Real& epsilon,\n+ 290 BlockVector& x, Real& lambda) const\n+ 291 {\n+ 292 // print verbosity information\n+ 293 if (verbosity_level_ > 0)\n+ 294 std::cout << title_ << \"Computing an approximation of \"\n+ 295 << \"the dominant eigenvalue of a matrix which \"\n+ 296 << \"is assumed to be symmetric.\" << std::endl;\n+ 297\n+ 298 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 299 // and to perform the product A*v (LU decomposition is not used)\n+ 300 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 301 WrappedMatrix A(m_);\n+ 302\n+ 303 // get number of rows and columns in A\n+ 304 const int nrows = A.nrows();\n+ 305 const int ncols = A.ncols();\n+ 306\n+ 307 // assert that A is square\n+ 308 if (nrows != ncols)\n+ 309 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n+ 310 << nrows << \"x\" << ncols << \").\");\n+ 311\n+ 312 // allocate memory for variables, set parameters\n+ 313 const int nev = 1; // Number of eigenvalues to compute\n+ 314 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 315 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 316 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 317 Real* ev = new Real[nev]; // Computed eigenvalues of A\n+ 318 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 319 int nconv; // Number of converged eigenvalues\n+ 320\n+ 321 // define what we need: eigenvalues with largest magnitude\n+ 322 char which[] = \"LM\";\n+ 323 ARSymStdEig\n+ 324 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n+ 325\n+ 326 // set ARPACK verbosity mode if requested\n+ 327 if (verbosity_level_ > 3) dprob.Trace();\n+ 328\n+ 329 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n+ 330 nconv = dprob.Eigenvalues(ev,ivec);\n+ 331\n+ 332 // obtain approximated dominant eigenvalue of A\n+ 333 lambda = ev[nev-1];\n+ 334\n+ 335 // obtain associated approximated eigenvector of A\n+ 336 Real* x_raw = dprob.RawEigenvector(nev-1);\n+ 337 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n+ 338\n+ 339 // obtain number of Arnoldi update iterations actually taken\n+ 340 nIterations_ = dprob.GetIter();\n+ 341\n+ 342 // compute residual norm\n+ 343 BlockVector r(x);\n+ 344 Real* Ax_raw = new Real[nrows];\n+ 345 A.multMv(x_raw,Ax_raw);\n+ 346 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);\n+ 347 r.axpy(-lambda,x);\n+ 348 const Real r_norm = r.two_norm();\n+ 349\n+ 350 // print verbosity information\n+ 351 if (verbosity_level_ > 0)\n+ 352 {\n+ 353 if (verbosity_level_ > 1)\n+ 354 {\n+ 355 // print some information about the problem\n+ 356 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n+ 357 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n+ 358 << \"StdEig:\" << std::endl;\n+ 359 std::cout << blank_ << \" converged eigenvalues of A: \"\n+ 360 << nconv << \" / \" << nev << std::endl;\n+ 361 std::cout << blank_ << \" dominant eigenvalue of A: \"\n+ 362 << lambda << std::endl;\n+ 363 }\n+ 364 std::cout << blank_ << \"Result (\"\n+ 365 << \"#iterations = \" << nIterations_ << \", \"\n+ 366 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 367 << \"\u03bb = \" << lambda << std::endl;\n+ 368 if (verbosity_level_ > 2)\n+ 369 {\n+ 370 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 371 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 372 }\n+ 373 }\n+ 374\n+ 375 // free dynamically allocated memory\n+ 376 delete[] Ax_raw;\n+ 377 delete[] ev;\n+ 378 }\n+ 379\n+391 inline void computeSymMinMagnitude (const Real& epsilon,\n+ 392 BlockVector& x, Real& lambda) const\n+ 393 {\n+ 394 // print verbosity information\n+ 395 if (verbosity_level_ > 0)\n+ 396 std::cout << title_ << \"Computing an approximation of the \"\n+ 397 << \"least dominant eigenvalue of a matrix which \"\n+ 398 << \"is assumed to be symmetric.\" << std::endl;\n+ 399\n+ 400 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 401 // and to perform the product A*v (LU decomposition is not used)\n+ 402 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 403 WrappedMatrix A(m_);\n+ 404\n+ 405 // get number of rows and columns in A\n+ 406 const int nrows = A.nrows();\n+ 407 const int ncols = A.ncols();\n+ 408\n+ 409 // assert that A is square\n+ 410 if (nrows != ncols)\n+ 411 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n+ 412 << nrows << \"x\" << ncols << \").\");\n+ 413\n+ 414 // allocate memory for variables, set parameters\n+ 415 const int nev = 1; // Number of eigenvalues to compute\n+ 416 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 417 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 418 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 419 Real* ev = new Real[nev]; // Computed eigenvalues of A\n+ 420 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 421 int nconv; // Number of converged eigenvalues\n+ 422\n+ 423 // define what we need: eigenvalues with smallest magnitude\n+ 424 char which[] = \"SM\";\n+ 425 ARSymStdEig\n+ 426 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n+ 427\n+ 428 // set ARPACK verbosity mode if requested\n+ 429 if (verbosity_level_ > 3) dprob.Trace();\n+ 430\n+ 431 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n+ 432 nconv = dprob.Eigenvalues(ev,ivec);\n+ 433\n+ 434 // obtain approximated least dominant eigenvalue of A\n+ 435 lambda = ev[nev-1];\n+ 436\n+ 437 // obtain associated approximated eigenvector of A\n+ 438 Real* x_raw = dprob.RawEigenvector(nev-1);\n+ 439 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n+ 440\n+ 441 // obtain number of Arnoldi update iterations actually taken\n+ 442 nIterations_ = dprob.GetIter();\n+ 443\n+ 444 // compute residual norm\n+ 445 BlockVector r(x);\n+ 446 Real* Ax_raw = new Real[nrows];\n+ 447 A.multMv(x_raw,Ax_raw);\n+ 448 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);\n+ 449 r.axpy(-lambda,x);\n+ 450 const Real r_norm = r.two_norm();\n+ 451\n+ 452 // print verbosity information\n+ 453 if (verbosity_level_ > 0)\n+ 454 {\n+ 455 if (verbosity_level_ > 1)\n+ 456 {\n+ 457 // print some information about the problem\n+ 458 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n+ 459 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n+ 460 << \"StdEig:\" << std::endl;\n+ 461 std::cout << blank_ << \" converged eigenvalues of A: \"\n+ 462 << nconv << \" / \" << nev << std::endl;\n+ 463 std::cout << blank_ << \" least dominant eigenvalue of A: \"\n+ 464 << lambda << std::endl;\n+ 465 }\n+ 466 std::cout << blank_ << \"Result (\"\n+ 467 << \"#iterations = \" << nIterations_ << \", \"\n+ 468 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 469 << \"\u03bb = \" << lambda << std::endl;\n+ 470 if (verbosity_level_ > 2)\n+ 471 {\n+ 472 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 473 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 474 }\n+ 475 }\n+ 476\n+ 477 // free dynamically allocated memory\n+ 478 delete[] Ax_raw;\n+ 479 delete[] ev;\n+ 480 }\n+ 481\n+493 inline void computeSymCond2 (const Real& epsilon, Real& cond_2) const\n+ 494 {\n+ 495 // print verbosity information\n+ 496 if (verbosity_level_ > 0)\n+ 497 std::cout << title_ << \"Computing an approximation of the \"\n+ 498 << \"spectral condition number of a matrix which \"\n+ 499 << \"is assumed to be symmetric.\" << std::endl;\n+ 500\n+ 501 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 502 // and to perform the product A*v (LU decomposition is not used)\n+ 503 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 504 WrappedMatrix A(m_);\n+ 505\n+ 506 // get number of rows and columns in A\n+ 507 const int nrows = A.nrows();\n+ 508 const int ncols = A.ncols();\n+ 509\n+ 510 // assert that A is square\n+ 511 if (nrows != ncols)\n+ 512 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n+ 513 << nrows << \"x\" << ncols << \").\");\n+ 514\n+ 515 // allocate memory for variables, set parameters\n+ 516 const int nev = 2; // Number of eigenvalues to compute\n+ 517 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 518 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 519 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 520 Real* ev = new Real[nev]; // Computed eigenvalues of A\n+ 521 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 522 int nconv; // Number of converged eigenvalues\n+ 523\n+ 524 // define what we need: eigenvalues from both ends of the spectrum\n+ 525 char which[] = \"BE\";\n+ 526 ARSymStdEig\n+ 527 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);\n+ 528\n+ 529 // set ARPACK verbosity mode if requested\n+ 530 if (verbosity_level_ > 3) dprob.Trace();\n+ 531\n+ 532 // find eigenvalues and eigenvectors of A, obtain the eigenvalues\n+ 533 nconv = dprob.Eigenvalues(ev,ivec);\n+ 534\n+ 535 // obtain approximated dominant and least dominant eigenvalue of A\n+ 536 const Real& lambda_max = ev[nev-1];\n+ 537 const Real& lambda_min = ev[0];\n+ 538\n+ 539 // obtain associated approximated eigenvectors of A\n+ 540 Real* x_max_raw = dprob.RawEigenvector(nev-1);\n+ 541 Real* x_min_raw = dprob.RawEigenvector(0);\n+ 542\n+ 543 // obtain approximated spectral condition number of A\n+ 544 cond_2 = std::abs(lambda_max / lambda_min);\n+ 545\n+ 546 // obtain number of Arnoldi update iterations actually taken\n+ 547 nIterations_ = dprob.GetIter();\n+ 548\n+ 549 // compute each residual norm\n+ 550 Real* Ax_max_raw = new Real[nrows];\n+ 551 Real* Ax_min_raw = new Real[nrows];\n+ 552 A.multMv(x_max_raw,Ax_max_raw);\n+ 553 A.multMv(x_min_raw,Ax_min_raw);\n+ 554 Real r_max_norm = 0.0;\n+ 555 Real r_min_norm = 0.0;\n+ 556 for (int i = 0; i < nrows; ++i)\n+ 557 {\n+ 558 r_max_norm += std::pow(Ax_max_raw[i] - lambda_max * x_max_raw[i],2);\n+ 559 r_min_norm += std::pow(Ax_min_raw[i] - lambda_min * x_min_raw[i],2);\n+ 560 }\n+ 561 r_max_norm = std::sqrt(r_max_norm);\n+ 562 r_min_norm = std::sqrt(r_min_norm);\n+ 563\n+ 564 // print verbosity information\n+ 565 if (verbosity_level_ > 0)\n+ 566 {\n+ 567 if (verbosity_level_ > 1)\n+ 568 {\n+ 569 // print some information about the problem\n+ 570 std::cout << blank_ << \"Obtained eigenvalues of A by solving \"\n+ 571 << \"A*x = \u03bb*x using the ARPACK++ class ARSym\"\n+ 572 << \"StdEig:\" << std::endl;\n+ 573 std::cout << blank_ << \" converged eigenvalues of A: \"\n+ 574 << nconv << \" / \" << nev << std::endl;\n+ 575 std::cout << blank_ << \" dominant eigenvalue of A: \"\n+ 576 << lambda_max << std::endl;\n+ 577 std::cout << blank_ << \" least dominant eigenvalue of A: \"\n+ 578 << lambda_min << std::endl;\n+ 579 std::cout << blank_ << \" spectral condition number of A: \"\n+ 580 << cond_2 << std::endl;\n+ 581 }\n+ 582 std::cout << blank_ << \"Result (\"\n+ 583 << \"#iterations = \" << nIterations_ << \", \"\n+ 584 << \"\u2551residual\u2551_2 = {\" << r_max_norm << \",\"\n+ 585 << r_min_norm << \"}, \" << \"\u03bb = {\"\n+ 586 << lambda_max << \",\" << lambda_min\n+ 587 << \"}): cond_2 = \" << cond_2 << std::endl;\n+ 588 }\n+ 589\n+ 590 // free dynamically allocated memory\n+ 591 delete[] Ax_min_raw;\n+ 592 delete[] Ax_max_raw;\n+ 593 delete[] ev;\n+ 594 }\n+ 595\n+609 inline void computeNonSymMax (const Real& epsilon,\n+ 610 BlockVector& x, Real& sigma) const\n+ 611 {\n+ 612 // print verbosity information\n+ 613 if (verbosity_level_ > 0)\n+ 614 std::cout << title_ << \"Computing an approximation of the \"\n+ 615 << \"largest singular value of a matrix which \"\n+ 616 << \"is assumed to be nonsymmetric.\" << std::endl;\n+ 617\n+ 618 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 619 // and to perform the product A^T*A*v (LU decomposition is not used)\n+ 620 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 621 WrappedMatrix A(m_);\n+ 622\n+ 623 // get number of rows and columns in A\n+ 624 const int nrows = A.nrows();\n+ 625 const int ncols = A.ncols();\n+ 626\n+ 627 // assert that A has more rows than columns (extend code later to the\n+opposite case!)\n+ 628 if (nrows < ncols)\n+ 629 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n+ 630 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n+ 631 << \" This case is not implemented, yet.\");\n+ 632\n+ 633 // allocate memory for variables, set parameters\n+ 634 const int nev = 1; // Number of eigenvalues to compute\n+ 635 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 636 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 637 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 638 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n+ 639 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 640 int nconv; // Number of converged eigenvalues\n+ 641\n+ 642 // define what we need: eigenvalues with largest algebraic value\n+ 643 char which[] = \"LA\";\n+ 644 ARSymStdEig\n+ 645 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n+ 646\n+ 647 // set ARPACK verbosity mode if requested\n+ 648 if (verbosity_level_ > 3) dprob.Trace();\n+ 649\n+ 650 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n+ 651 nconv = dprob.Eigenvalues(ev,ivec);\n+ 652\n+ 653 // obtain approximated largest eigenvalue of A^T*A\n+ 654 const Real& lambda = ev[nev-1];\n+ 655\n+ 656 // obtain associated approximated eigenvector of A^T*A\n+ 657 Real* x_raw = dprob.RawEigenvector(nev-1);\n+ 658 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n+ 659\n+ 660 // obtain number of Arnoldi update iterations actually taken\n+ 661 nIterations_ = dprob.GetIter();\n+ 662\n+ 663 // compute residual norm\n+ 664 BlockVector r(x);\n+ 665 Real* AtAx_raw = new Real[ncols];\n+ 666 A.multMtMv(x_raw,AtAx_raw);\n+ 667 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);\n+ 668 r.axpy(-lambda,x);\n+ 669 const Real r_norm = r.two_norm();\n+ 670\n+ 671 // calculate largest singular value of A (note that\n+ 672 // x is right-singular / left-singular vector of A)\n+ 673 sigma = std::sqrt(lambda);\n+ 674\n+ 675 // print verbosity information\n+ 676 if (verbosity_level_ > 0)\n+ 677 {\n+ 678 if (verbosity_level_ > 1)\n+ 679 {\n+ 680 // print some information about the problem\n+ 681 std::cout << blank_ << \"Obtained singular values of A by sol\"\n+ 682 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n+ 683 << \"class ARSymStdEig:\" << std::endl;\n+ 684 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n+ 685 << nconv << \" / \" << nev << std::endl;\n+ 686 std::cout << blank_ << \" largest eigenvalue of A^T*A: \"\n+ 687 << lambda << std::endl;\n+ 688 std::cout << blank_ << \" => largest singular value of A: \"\n+ 689 << sigma << std::endl;\n+ 690 }\n+ 691 std::cout << blank_ << \"Result (\"\n+ 692 << \"#iterations = \" << nIterations_ << \", \"\n+ 693 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 694 << \"\u03c3 = \" << sigma << std::endl;\n+ 695 if (verbosity_level_ > 2)\n+ 696 {\n+ 697 // print approximated right-singular / left-singular vector\n+ 698 // via DUNE-ISTL I/O methods\n+ 699 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 700 }\n+ 701 }\n+ 702\n+ 703 // free dynamically allocated memory\n+ 704 delete[] AtAx_raw;\n+ 705 delete[] ev;\n+ 706 }\n+ 707\n+721 inline void computeNonSymMin (const Real& epsilon,\n+ 722 BlockVector& x, Real& sigma) const\n+ 723 {\n+ 724 // print verbosity information\n+ 725 if (verbosity_level_ > 0)\n+ 726 std::cout << title_ << \"Computing an approximation of the \"\n+ 727 << \"smallest singular value of a matrix which \"\n+ 728 << \"is assumed to be nonsymmetric.\" << std::endl;\n+ 729\n+ 730 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 731 // and to perform the product A^T*A*v (LU decomposition is not used)\n+ 732 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 733 WrappedMatrix A(m_);\n+ 734\n+ 735 // get number of rows and columns in A\n+ 736 const int nrows = A.nrows();\n+ 737 const int ncols = A.ncols();\n+ 738\n+ 739 // assert that A has more rows than columns (extend code later to the\n+opposite case!)\n+ 740 if (nrows < ncols)\n+ 741 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n+ 742 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n+ 743 << \" This case is not implemented, yet.\");\n+ 744\n+ 745 // allocate memory for variables, set parameters\n+ 746 const int nev = 1; // Number of eigenvalues to compute\n+ 747 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 748 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 749 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 750 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n+ 751 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 752 int nconv; // Number of converged eigenvalues\n+ 753\n+ 754 // define what we need: eigenvalues with smallest algebraic value\n+ 755 char which[] = \"SA\";\n+ 756 ARSymStdEig\n+ 757 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n+ 758\n+ 759 // set ARPACK verbosity mode if requested\n+ 760 if (verbosity_level_ > 3) dprob.Trace();\n+ 761\n+ 762 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n+ 763 nconv = dprob.Eigenvalues(ev,ivec);\n+ 764\n+ 765 // obtain approximated smallest eigenvalue of A^T*A\n+ 766 const Real& lambda = ev[nev-1];\n+ 767\n+ 768 // obtain associated approximated eigenvector of A^T*A\n+ 769 Real* x_raw = dprob.RawEigenvector(nev-1);\n+ 770 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);\n+ 771\n+ 772 // obtain number of Arnoldi update iterations actually taken\n+ 773 nIterations_ = dprob.GetIter();\n+ 774\n+ 775 // compute residual norm\n+ 776 BlockVector r(x);\n+ 777 Real* AtAx_raw = new Real[ncols];\n+ 778 A.multMtMv(x_raw,AtAx_raw);\n+ 779 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);\n+ 780 r.axpy(-lambda,x);\n+ 781 const Real r_norm = r.two_norm();\n+ 782\n+ 783 // calculate smallest singular value of A (note that\n+ 784 // x is right-singular / left-singular vector of A)\n+ 785 sigma = std::sqrt(lambda);\n+ 786\n+ 787 // print verbosity information\n+ 788 if (verbosity_level_ > 0)\n+ 789 {\n+ 790 if (verbosity_level_ > 1)\n+ 791 {\n+ 792 // print some information about the problem\n+ 793 std::cout << blank_ << \"Obtained singular values of A by sol\"\n+ 794 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n+ 795 << \"class ARSymStdEig:\" << std::endl;\n+ 796 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n+ 797 << nconv << \" / \" << nev << std::endl;\n+ 798 std::cout << blank_ << \" smallest eigenvalue of A^T*A: \"\n+ 799 << lambda << std::endl;\n+ 800 std::cout << blank_ << \" => smallest singular value of A: \"\n+ 801 << sigma << std::endl;\n+ 802 }\n+ 803 std::cout << blank_ << \"Result (\"\n+ 804 << \"#iterations = \" << nIterations_ << \", \"\n+ 805 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 806 << \"\u03c3 = \" << sigma << std::endl;\n+ 807 if (verbosity_level_ > 2)\n+ 808 {\n+ 809 // print approximated right-singular / left-singular vector\n+ 810 // via DUNE-ISTL I/O methods\n+ 811 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 812 }\n+ 813 }\n+ 814\n+ 815 // free dynamically allocated memory\n+ 816 delete[] AtAx_raw;\n+ 817 delete[] ev;\n+ 818 }\n+ 819\n+830 inline void computeNonSymCond2 (const Real& epsilon, Real& cond_2) const\n+ 831 {\n+ 832 // print verbosity information\n+ 833 if (verbosity_level_ > 0)\n+ 834 std::cout << title_ << \"Computing an approximation of the \"\n+ 835 << \"spectral condition number of a matrix which \"\n+ 836 << \"is assumed to be nonsymmetric.\" << std::endl;\n+ 837\n+ 838 // use type ArPackPlusPlus_BCRSMatrixWrapper to store matrix information\n+ 839 // and to perform the product A^T*A*v (LU decomposition is not used)\n+ 840 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper WrappedMatrix;\n+ 841 WrappedMatrix A(m_);\n+ 842\n+ 843 // get number of rows and columns in A\n+ 844 const int nrows = A.nrows();\n+ 845 const int ncols = A.ncols();\n+ 846\n+ 847 // assert that A has more rows than columns (extend code later to the\n+opposite case!)\n+ 848 if (nrows < ncols)\n+ 849 DUNE_THROW(Dune::ISTLError,\"Matrix has less rows than \"\n+ 850 << \"columns (\" << nrows << \"x\" << ncols << \").\"\n+ 851 << \" This case is not implemented, yet.\");\n+ 852\n+ 853 // allocate memory for variables, set parameters\n+ 854 const int nev = 2; // Number of eigenvalues to compute\n+ 855 int ncv = std::min(20, nrows); // Number of Arnoldi vectors generated at\n+each iteration (0 == auto)\n+ 856 const Real tol = epsilon; // Stopping tolerance (relative accuracy of Ritz\n+values) (0 == machine precision)\n+ 857 const int maxit = nIterationsMax_*nev; // Maximum number of Arnoldi update\n+iterations allowed (0 == 100*nev)\n+ 858 Real* ev = new Real[nev]; // Computed eigenvalues of A^T*A\n+ 859 const bool ivec = true; // Flag deciding if eigenvectors shall be\n+determined\n+ 860 int nconv; // Number of converged eigenvalues\n+ 861\n+ 862 // define what we need: eigenvalues from both ends of the spectrum\n+ 863 char which[] = \"BE\";\n+ 864 ARSymStdEig\n+ 865 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);\n+ 866\n+ 867 // set ARPACK verbosity mode if requested\n+ 868 if (verbosity_level_ > 3) dprob.Trace();\n+ 869\n+ 870 // find eigenvalues and eigenvectors of A^T*A, obtain the eigenvalues\n+ 871 nconv = dprob.Eigenvalues(ev,ivec);\n+ 872\n+ 873 // obtain approximated largest and smallest eigenvalue of A^T*A\n+ 874 const Real& lambda_max = ev[nev-1];\n+ 875 const Real& lambda_min = ev[0];\n+ 876\n+ 877 // obtain associated approximated eigenvectors of A^T*A\n+ 878 Real* x_max_raw = dprob.RawEigenvector(nev-1);\n+ 879 Real* x_min_raw = dprob.RawEigenvector(0);\n+ 880\n+ 881 // obtain number of Arnoldi update iterations actually taken\n+ 882 nIterations_ = dprob.GetIter();\n+ 883\n+ 884 // compute each residual norm\n+ 885 Real* AtAx_max_raw = new Real[ncols];\n+ 886 Real* AtAx_min_raw = new Real[ncols];\n+ 887 A.multMtMv(x_max_raw,AtAx_max_raw);\n+ 888 A.multMtMv(x_min_raw,AtAx_min_raw);\n+ 889 Real r_max_norm = 0.0;\n+ 890 Real r_min_norm = 0.0;\n+ 891 for (int i = 0; i < ncols; ++i)\n+ 892 {\n+ 893 r_max_norm += std::pow(AtAx_max_raw[i] - lambda_max * x_max_raw[i],2);\n+ 894 r_min_norm += std::pow(AtAx_min_raw[i] - lambda_min * x_min_raw[i],2);\n+ 895 }\n+ 896 r_max_norm = std::sqrt(r_max_norm);\n+ 897 r_min_norm = std::sqrt(r_min_norm);\n+ 898\n+ 899 // calculate largest and smallest singular value of A\n+ 900 const Real sigma_max = std::sqrt(lambda_max);\n+ 901 const Real sigma_min = std::sqrt(lambda_min);\n+ 902\n+ 903 // obtain approximated spectral condition number of A\n+ 904 cond_2 = sigma_max / sigma_min;\n+ 905\n+ 906 // print verbosity information\n+ 907 if (verbosity_level_ > 0)\n+ 908 {\n+ 909 if (verbosity_level_ > 1)\n+ 910 {\n+ 911 // print some information about the problem\n+ 912 std::cout << blank_ << \"Obtained singular values of A by sol\"\n+ 913 << \"ving (A^T*A)*x = \u03c3\u00b2*x using the ARPACK++ \"\n+ 914 << \"class ARSymStdEig:\" << std::endl;\n+ 915 std::cout << blank_ << \" converged eigenvalues of A^T*A: \"\n+ 916 << nconv << \" / \" << nev << std::endl;\n+ 917 std::cout << blank_ << \" largest eigenvalue of A^T*A: \"\n+ 918 << lambda_max << std::endl;\n+ 919 std::cout << blank_ << \" smallest eigenvalue of A^T*A: \"\n+ 920 << lambda_min << std::endl;\n+ 921 std::cout << blank_ << \" => largest singular value of A: \"\n+ 922 << sigma_max << std::endl;\n+ 923 std::cout << blank_ << \" => smallest singular value of A: \"\n+ 924 << sigma_min << std::endl;\n+ 925 }\n+ 926 std::cout << blank_ << \"Result (\"\n+ 927 << \"#iterations = \" << nIterations_ << \", \"\n+ 928 << \"\u2551residual\u2551_2 = {\" << r_max_norm << \",\"\n+ 929 << r_min_norm << \"}, \" << \"\u03c3 = {\"\n+ 930 << sigma_max << \",\" << sigma_min\n+ 931 << \"}): cond_2 = \" << cond_2 << std::endl;\n+ 932 }\n+ 933\n+ 934 // free dynamically allocated memory\n+ 935 delete[] AtAx_min_raw;\n+ 936 delete[] AtAx_max_raw;\n+ 937 delete[] ev;\n+ 938 }\n+ 939\n+944 inline unsigned int getIterationCount () const\n+ 945 {\n+ 946 if (nIterations_ == 0)\n+ 947 DUNE_THROW(Dune::ISTLError,\"No algorithm applied, yet.\");\n+ 948\n+ 949 return nIterations_;\n+ 950 }\n+ 951\n+ 952 protected:\n+ 953 // parameters related to iterative eigenvalue algorithms\n+954 const BCRSMatrix& m_;\n+955 const unsigned int nIterationsMax_;\n+ 956\n+ 957 // verbosity setting\n+958 const unsigned int verbosity_level_;\n+ 959\n+ 960 // memory for storing temporary variables (mutable as they shall\n+ 961 // just be effectless auxiliary variables of the const apply*(...)\n+ 962 // methods)\n+963 mutable unsigned int nIterations_;\n+ 964\n+ 965 // constants for printing verbosity information\n+966 const std::string title_;\n+967 const std::string blank_;\n+ 968 };\n+ 969\n+ 972} // namespace Dune\n+ 973\n+ 974#endif // HAVE_ARPACKPP\n+ 975\n+ 976#endif // DUNE_ISTL_EIGENVALUE_ARPACKPP_HH\n+io.hh\n+Some generic functions for pretty printing vectors and matrices.\n+bvector.hh\n+This file implements a vector space as a tensor product of a given vector\n+space. The number of compon...\n+istlexception.hh\n blocklevel.hh\n Helper functions for determining the vector/matrix block level.\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+Dune::printvector\n+void printvector(std::ostream &s, const V &v, std::string title, std::string\n+rowtext, int columns=1, int width=10, int precision=2)\n+Print an ISTL vector.\n+Definition: io.hh:89\n Dune\n Definition: allocator.hh:11\n Dune::BCRSMatrix\n A sparse block matrix with compressed row storage.\n Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::endrowsizes\n-void endrowsizes()\n-indicate that size of all rows is defined\n-Definition: bcrsmatrix.hh:1149\n-Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::random\n-@ random\n-Build entries randomly.\n-Definition: bcrsmatrix.hh:530\n-Dune::BCRSMatrix::addindex\n-void addindex(size_type row, size_type col)\n-add index (row,col) to the matrix\n-Definition: bcrsmatrix.hh:1191\n-Dune::BCRSMatrix::endindices\n-void endindices()\n-indicate that all indices are defined, check consistency\n-Definition: bcrsmatrix.hh:1248\n-Dune::BCRSMatrix<_B,_std::allocator<_B_>_>::N\n-size_type N() const\n-number of rows (counted in blocks)\n-Definition: bcrsmatrix.hh:1972\n-Dune::BCRSMatrix::setSize\n-void setSize(size_type rows, size_type columns, size_type nnz=0)\n-Set the size of the matrix.\n-Definition: bcrsmatrix.hh:861\n-Dune::BCRSMatrix::operator=\n-BCRSMatrix & operator=(const BCRSMatrix &Mat)\n-assignment\n-Definition: bcrsmatrix.hh:911\n-Dune::BTDMatrix\n-A block-tridiagonal matrix.\n-Definition: btdmatrix.hh:31\n-Dune::BTDMatrix::blocklevel\n-static constexpr auto blocklevel\n-increment block level counter\n-Definition: btdmatrix.hh:53\n-Dune::BTDMatrix::BTDMatrix\n-BTDMatrix(size_type size)\n-Definition: btdmatrix.hh:58\n-Dune::BTDMatrix::solve\n-void solve(V &x, const V &rhs) const\n-Use the Thomas algorithm to solve the system Ax=b in O(n) time.\n-Definition: btdmatrix.hh:125\n-Dune::BTDMatrix::size_type\n-A::size_type size_type\n-implement row_type with compressed vector\n-Definition: btdmatrix.hh:49\n-Dune::BTDMatrix::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: btdmatrix.hh:43\n-Dune::BTDMatrix::block_type\n-B block_type\n-export the type representing the components\n-Definition: btdmatrix.hh:40\n-Dune::BTDMatrix::field_type\n+Dune::BCRSMatrix::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: bcrsmatrix.hh:488\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::BlockVector::field_type\n typename Imp::BlockTraits< B >::field_type field_type\n export the type representing the field\n-Definition: btdmatrix.hh:37\n-Dune::BTDMatrix::operator=\n-BTDMatrix & operator=(const BTDMatrix &other)\n-assignment\n-Definition: btdmatrix.hh:108\n-Dune::BTDMatrix::BTDMatrix\n-BTDMatrix()\n-Default constructor.\n-Definition: btdmatrix.hh:56\n-Dune::BTDMatrix::setSize\n-void setSize(size_type size)\n-Resize the matrix. Invalidates the content!\n-Definition: btdmatrix.hh:81\n-Dune::FieldTraits<_BTDMatrix<_B,_A_>_>::real_type\n-typename FieldTraits< field_type >::real_type real_type\n-Definition: btdmatrix.hh:208\n-Dune::FieldTraits<_BTDMatrix<_B,_A_>_>::field_type\n-typename BTDMatrix< B, A >::field_type field_type\n-Definition: btdmatrix.hh:207\n+Definition: bvector.hh:401\n+Dune::BlockVector::size_type\n+A::size_type size_type\n+The type for the index access.\n+Definition: bvector.hh:410\n+Dune::ArPackPlusPlus_Algorithms\n+Wrapper to use a range of ARPACK++ eigenvalue solvers.\n+Definition: arpackpp.hh:245\n+Dune::ArPackPlusPlus_Algorithms::verbosity_level_\n+const unsigned int verbosity_level_\n+Definition: arpackpp.hh:958\n+Dune::ArPackPlusPlus_Algorithms::getIterationCount\n+unsigned int getIterationCount() const\n+Return the number of iterations in last application of an algorithm.\n+Definition: arpackpp.hh:944\n+Dune::ArPackPlusPlus_Algorithms::title_\n+const std::string title_\n+Definition: arpackpp.hh:966\n+Dune::ArPackPlusPlus_Algorithms::Real\n+BlockVector::field_type Real\n+Definition: arpackpp.hh:247\n+Dune::ArPackPlusPlus_Algorithms::computeSymMaxMagnitude\n+void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n+const\n+Assume the matrix to be square, symmetric and perform IRLM to compute an\n+approximation lambda of its ...\n+Definition: arpackpp.hh:289\n+Dune::ArPackPlusPlus_Algorithms::computeSymMinMagnitude\n+void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda)\n+const\n+Assume the matrix to be square, symmetric and perform IRLM to compute an\n+approximation lambda of its ...\n+Definition: arpackpp.hh:391\n+Dune::ArPackPlusPlus_Algorithms::m_\n+const BCRSMatrix & m_\n+Definition: arpackpp.hh:954\n+Dune::ArPackPlusPlus_Algorithms::nIterationsMax_\n+const unsigned int nIterationsMax_\n+Definition: arpackpp.hh:955\n+Dune::ArPackPlusPlus_Algorithms::blank_\n+const std::string blank_\n+Definition: arpackpp.hh:967\n+Dune::ArPackPlusPlus_Algorithms::ArPackPlusPlus_Algorithms\n+ArPackPlusPlus_Algorithms(const BCRSMatrix &m, const unsigned int\n+nIterationsMax=100000, const unsigned int verbosity_level=0)\n+Construct from required parameters.\n+Definition: arpackpp.hh:268\n+Dune::ArPackPlusPlus_Algorithms::computeSymCond2\n+void computeSymCond2(const Real &epsilon, Real &cond_2) const\n+Assume the matrix to be square, symmetric and perform IRLM to compute an\n+approximation of its spectra...\n+Definition: arpackpp.hh:493\n+Dune::ArPackPlusPlus_Algorithms::nIterations_\n+unsigned int nIterations_\n+Definition: arpackpp.hh:963\n+Dune::ArPackPlusPlus_Algorithms::computeNonSymMin\n+void computeNonSymMin(const Real &epsilon, BlockVector &x, Real &sigma) const\n+Assume the matrix to be nonsymmetric and perform IRLM to compute an\n+approximation sigma of its smalle...\n+Definition: arpackpp.hh:721\n+Dune::ArPackPlusPlus_Algorithms::computeNonSymCond2\n+void computeNonSymCond2(const Real &epsilon, Real &cond_2) const\n+Assume the matrix to be nonsymmetric and perform IRLM to compute an\n+approximation of its spectral con...\n+Definition: arpackpp.hh:830\n+Dune::ArPackPlusPlus_Algorithms::computeNonSymMax\n+void computeNonSymMax(const Real &epsilon, BlockVector &x, Real &sigma) const\n+Assume the matrix to be nonsymmetric and perform IRLM to compute an\n+approximation sigma of its larges...\n+Definition: arpackpp.hh:609\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00203.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00203.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ilusubdomainsolver.hh File Reference\n+dune-istl: poweriteration.hh File Reference\n \n \n \n \n \n \n \n@@ -58,55 +58,55 @@\n \n \n \n \n \n
    \n \n-
    ilusubdomainsolver.hh File Reference
    \n+
    poweriteration.hh File Reference
    \n
    \n
    \n-\n-

    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz. \n-More...

    \n-
    #include <map>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/istl/preconditioners.hh>
    \n-#include "matrix.hh"
    \n+
    #include <cstddef>
    \n #include <cmath>
    \n-#include <cstdlib>
    \n+#include <type_traits>
    \n+#include <iostream>
    \n+#include <limits>
    \n+#include <ios>
    \n+#include <iomanip>
    \n+#include <memory>
    \n+#include <string>
    \n+#include <dune/common/exceptions.hh>
    \n+#include <dune/istl/blocklevel.hh>
    \n+#include <dune/istl/operators.hh>
    \n+#include <dune/istl/solvercategory.hh>
    \n+#include <dune/istl/solvertype.hh>
    \n+#include <dune/istl/istlexception.hh>
    \n+#include <dune/istl/io.hh>
    \n+#include <dune/istl/solvers.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::ILUSubdomainSolver< M, X, Y >
     base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver. More...
     
    class  Dune::ILU0SubdomainSolver< M, X, Y >
     Exact subdomain solver using ILU(p) with appropriate p. More...
     
    class  Dune::ILUNSubdomainSolver< M, X, Y >
    class  Dune::PowerIteration_Algorithms< BCRSMatrix, BlockVector >
     Iterative eigenvalue algorithms based on power iteration. More...
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-

    Detailed Description

    \n-

    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,37 +4,38 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n+ * eigenvalue\n Classes | Namespaces\n-ilusubdomainsolver.hh File Reference\n-Various local subdomain solvers based on ILU for SeqOverlappingSchwarz. More...\n-#include \n-#include \n-#include \n-#include \"matrix.hh\"\n+poweriteration.hh File Reference\n+#include \n #include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::ILUSubdomainSolver<_M,_X,_Y_>\n-\u00a0 base class encapsulating common algorithms of ILU0SubdomainSolver and\n- ILUNSubdomainSolver. More...\n-\u00a0\n-class \u00a0Dune::ILU0SubdomainSolver<_M,_X,_Y_>\n-\u00a0 Exact subdomain solver using ILU(p) with appropriate p. More...\n-\u00a0\n-class \u00a0Dune::ILUNSubdomainSolver<_M,_X,_Y_>\n+class \u00a0Dune::PowerIteration_Algorithms<_BCRSMatrix,_BlockVector_>\n+\u00a0 Iterative eigenvalue algorithms based on power iteration. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-***** Detailed Description *****\n-Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00203_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00203_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: ilusubdomainsolver.hh Source File\n+dune-istl: poweriteration.hh Source File\n \n \n \n \n \n \n \n@@ -58,220 +58,853 @@\n \n \n \n \n \n
    \n-
    ilusubdomainsolver.hh
    \n+
    poweriteration.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_ILUSUBDOMAINSOLVER_HH
    \n-
    6#define DUNE_ISTL_ILUSUBDOMAINSOLVER_HH
    \n+
    5#ifndef DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n+
    6#define DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n
    7
    \n-
    8#include <map>
    \n-
    9#include <dune/common/typetraits.hh>
    \n-\n-
    11#include "matrix.hh"
    \n-
    12#include <cmath>
    \n-
    13#include <cstdlib>
    \n-
    14
    \n-
    15namespace Dune {
    \n-
    16
    \n-
    35 template<class M, class X, class Y>
    \n-\n-
    37 public:
    \n-
    39 typedef typename std::remove_const<M>::type matrix_type;
    \n-
    41 typedef X domain_type;
    \n-
    43 typedef Y range_type;
    \n-
    44
    \n-
    51 virtual void apply (X& v, const Y& d) =0;
    \n+
    8#include <cstddef> // provides std::size_t
    \n+
    9#include <cmath> // provides std::sqrt, std::abs
    \n+
    10
    \n+
    11#include <type_traits> // provides std::is_same
    \n+
    12#include <iostream> // provides std::cout, std::endl
    \n+
    13#include <limits> // provides std::numeric_limits
    \n+
    14#include <ios> // provides std::left, std::ios::left
    \n+
    15#include <iomanip> // provides std::setw, std::resetiosflags
    \n+
    16#include <memory> // provides std::unique_ptr
    \n+
    17#include <string> // provides std::string
    \n+
    18
    \n+
    19#include <dune/common/exceptions.hh> // provides DUNE_THROW(...)
    \n+
    20
    \n+
    21#include <dune/istl/blocklevel.hh> // provides Dune::blockLevel
    \n+
    22#include <dune/istl/operators.hh> // provides Dune::LinearOperator
    \n+
    23#include <dune/istl/solvercategory.hh> // provides Dune::SolverCategory::sequential
    \n+
    24#include <dune/istl/solvertype.hh> // provides Dune::IsDirectSolver
    \n+
    25#include <dune/istl/operators.hh> // provides Dune::MatrixAdapter
    \n+
    26#include <dune/istl/istlexception.hh> // provides Dune::ISTLError
    \n+
    27#include <dune/istl/io.hh> // provides Dune::printvector(...)
    \n+
    28#include <dune/istl/solvers.hh> // provides Dune::InverseOperatorResult
    \n+
    29
    \n+
    30namespace Dune
    \n+
    31{
    \n+
    32
    \n+
    37 namespace Impl {
    \n+
    45 template <class X, class Y = X>
    \n+
    46 class ScalingLinearOperator : public Dune::LinearOperator<X,Y>
    \n+
    47 {
    \n+
    48 public:
    \n+
    49 typedef X domain_type;
    \n+
    50 typedef Y range_type;
    \n+
    51 typedef typename X::field_type field_type;
    \n
    52
    \n-\n-
    54 {}
    \n-
    55
    \n-
    56 protected:
    \n-
    62 template<class S>
    \n-
    63 std::size_t copyToLocalMatrix(const M& A, S& rowset);
    \n+
    53 ScalingLinearOperator (field_type immutable_scaling,
    \n+
    54 const field_type& mutable_scaling)
    \n+
    55 : immutable_scaling_(immutable_scaling),
    \n+
    56 mutable_scaling_(mutable_scaling)
    \n+
    57 {}
    \n+
    58
    \n+
    59 virtual void apply (const X& x, Y& y) const
    \n+
    60 {
    \n+
    61 y = x;
    \n+
    62 y *= immutable_scaling_*mutable_scaling_;
    \n+
    63 }
    \n
    64
    \n-
    66 // for ILUN
    \n-\n-
    68 };
    \n-
    69
    \n-
    76 template<class M, class X, class Y>
    \n-\n-
    78 : public ILUSubdomainSolver<M,X,Y>{
    \n-
    79 public:
    \n-
    81 typedef typename std::remove_const<M>::type matrix_type;
    \n-
    82 typedef typename std::remove_const<M>::type rilu_type;
    \n-
    84 typedef X domain_type;
    \n-
    86 typedef Y range_type;
    \n-
    87
    \n-
    88
    \n-
    93 void apply (X& v, const Y& d)
    \n-
    94 {
    \n-
    95 ILU::blockILUBacksolve(this->ILU,v,d);
    \n-
    96 }
    \n-
    104 template<class S>
    \n-
    105 void setSubMatrix(const M& A, S& rowset);
    \n-
    106
    \n-
    107 };
    \n-
    108
    \n-
    109 template<class M, class X, class Y>
    \n-\n-
    111 : public ILUSubdomainSolver<M,X,Y>{
    \n-
    112 public:
    \n-
    114 typedef typename std::remove_const<M>::type matrix_type;
    \n-
    115 typedef typename std::remove_const<M>::type rilu_type;
    \n-
    117 typedef X domain_type;
    \n-
    119 typedef Y range_type;
    \n-
    120
    \n-
    125 void apply (X& v, const Y& d)
    \n-
    126 {
    \n-
    127 ILU::blockILUBacksolve(RILU,v,d);
    \n-
    128 }
    \n-
    129
    \n-
    137 template<class S>
    \n-
    138 void setSubMatrix(const M& A, S& rowset);
    \n-
    139
    \n-
    140 private:
    \n-
    144 rilu_type RILU;
    \n-
    145 };
    \n-
    146
    \n-
    147
    \n-
    148
    \n-
    149 template<class M, class X, class Y>
    \n-
    150 template<class S>
    \n-
    151 std::size_t ILUSubdomainSolver<M,X,Y>::copyToLocalMatrix(const M& A, S& rowSet)
    \n-
    152 {
    \n-
    153 // Calculate consecutive indices for local problem
    \n-
    154 // while perserving the ordering
    \n-
    155 typedef typename M::size_type size_type;
    \n-
    156 typedef std::map<typename S::value_type,size_type> IndexMap;
    \n-
    157 typedef typename IndexMap::iterator IMIter;
    \n-
    158 IndexMap indexMap;
    \n-
    159 IMIter guess = indexMap.begin();
    \n-
    160 size_type localIndex=0;
    \n-
    161
    \n-
    162 typedef typename S::const_iterator SIter;
    \n-
    163 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n-
    164 rowIdx!= rowEnd; ++rowIdx, ++localIndex)
    \n-
    165 guess = indexMap.insert(guess,
    \n-
    166 std::make_pair(*rowIdx,localIndex));
    \n-
    167
    \n-
    168
    \n-
    169 // Build Matrix for local subproblem
    \n-
    170 ILU.setSize(rowSet.size(),rowSet.size());
    \n-
    171 ILU.setBuildMode(matrix_type::row_wise);
    \n-
    172
    \n-
    173 // Create sparsity pattern
    \n-
    174 typedef typename matrix_type::CreateIterator CIter;
    \n-
    175 CIter rowCreator = ILU.createbegin();
    \n-
    176 std::size_t offset=0;
    \n-
    177 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n-
    178 rowIdx!= rowEnd; ++rowIdx, ++rowCreator) {
    \n-
    179 // See which row entries are in our subset and add them to
    \n-
    180 // the sparsity pattern
    \n-
    181 guess = indexMap.begin();
    \n-
    182
    \n-
    183 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),
    \n-
    184 endcol=A[*rowIdx].end(); col != endcol; ++col) {
    \n-
    185 // search for the entry in the row set
    \n-
    186 guess = indexMap.find(col.index());
    \n-
    187 if(guess!=indexMap.end()) {
    \n-
    188 // add local index to row
    \n-
    189 rowCreator.insert(guess->second);
    \n-
    190 offset=std::max(offset,(std::size_t)std::abs((int)(guess->second-rowCreator.index())));
    \n-
    191 }
    \n-
    192 }
    \n-
    193
    \n-
    194 }
    \n-
    195
    \n-
    196 // Insert the matrix values for the local problem
    \n-
    197 typename matrix_type::iterator iluRow=ILU.begin();
    \n-
    198
    \n-
    199 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();
    \n-
    200 rowIdx!= rowEnd; ++rowIdx, ++iluRow) {
    \n-
    201 // See which row entries are in our subset and add them to
    \n-
    202 // the sparsity pattern
    \n-
    203 typename matrix_type::ColIterator localCol=iluRow->begin();
    \n-
    204 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),
    \n-
    205 endcol=A[*rowIdx].end(); col != endcol; ++col) {
    \n-
    206 // search for the entry in the row set
    \n-
    207 guess = indexMap.find(col.index());
    \n-
    208 if(guess!=indexMap.end()) {
    \n-
    209 // set local value
    \n-
    210 (*localCol)=(*col);
    \n-
    211 ++localCol;
    \n-
    212 }
    \n-
    213 }
    \n-
    214 }
    \n-
    215 return offset;
    \n-
    216 }
    \n-
    217
    \n-
    218
    \n-
    219 template<class M, class X, class Y>
    \n-
    220 template<class S>
    \n-\n-
    222 {
    \n-
    223 this->copyToLocalMatrix(A,rowSet);
    \n-\n-
    225 }
    \n-
    226
    \n-
    227 template<class M, class X, class Y>
    \n-
    228 template<class S>
    \n-\n-
    230 {
    \n-
    231 std::size_t offset=copyToLocalMatrix(A,rowSet);
    \n-
    232 RILU.setSize(rowSet.size(),rowSet.size(), (1+2*offset)*rowSet.size());
    \n-
    233 RILU.setBuildMode(matrix_type::row_wise);
    \n-
    234 ILU::blockILUDecomposition(this->ILU, (offset+1)/2, RILU);
    \n-
    235 }
    \n+
    65 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n+
    66 {
    \n+
    67 X temp(x);
    \n+
    68 temp *= immutable_scaling_*mutable_scaling_;
    \n+
    69 y.axpy(alpha,temp);
    \n+
    70 }
    \n+
    71
    \n+\n+
    74 {
    \n+\n+
    76 }
    \n+
    77
    \n+
    78 protected:
    \n+
    79 const field_type immutable_scaling_;
    \n+
    80 const field_type& mutable_scaling_;
    \n+
    81 };
    \n+
    82
    \n+
    83
    \n+
    92 template <class OP1, class OP2>
    \n+
    93 class LinearOperatorSum
    \n+
    94 : public Dune::LinearOperator<typename OP1::domain_type,
    \n+
    95 typename OP1::range_type>
    \n+
    96 {
    \n+
    97 public:
    \n+
    98 typedef typename OP1::domain_type domain_type;
    \n+
    99 typedef typename OP1::range_type range_type;
    \n+
    100 typedef typename domain_type::field_type field_type;
    \n+
    101
    \n+
    102 LinearOperatorSum (const OP1& op1, const OP2& op2)
    \n+
    103 : op1_(op1), op2_(op2)
    \n+
    104 {
    \n+
    105 static_assert(std::is_same<typename OP2::domain_type,domain_type>::value,
    \n+
    106 "Domain type of both operators doesn't match!");
    \n+
    107 static_assert(std::is_same<typename OP2::range_type,range_type>::value,
    \n+
    108 "Range type of both operators doesn't match!");
    \n+
    109 }
    \n+
    110
    \n+
    111 virtual void apply (const domain_type& x, range_type& y) const
    \n+
    112 {
    \n+
    113 op1_.apply(x,y);
    \n+
    114 op2_.applyscaleadd(1.0,x,y);
    \n+
    115 }
    \n+
    116
    \n+
    117 virtual void applyscaleadd (field_type alpha,
    \n+
    118 const domain_type& x, range_type& y) const
    \n+
    119 {
    \n+
    120 range_type temp(y);
    \n+
    121 op1_.apply(x,temp);
    \n+
    122 op2_.applyscaleadd(1.0,x,temp);
    \n+
    123 y.axpy(alpha,temp);
    \n+
    124 }
    \n+
    125
    \n+
    127 virtual SolverCategory::Category category() const
    \n+
    128 {
    \n+\n+
    130 }
    \n+
    131
    \n+
    132 protected:
    \n+
    133 const OP1& op1_;
    \n+
    134 const OP2& op2_;
    \n+
    135 };
    \n+
    136 } // end namespace Impl
    \n+
    137
    \n+
    174 template <typename BCRSMatrix, typename BlockVector>
    \n+\n+
    176 {
    \n+
    177 protected:
    \n+
    178 // Type definitions for type of iteration operator (m_ - mu_*I)
    \n+\n+\n+
    181 typedef Impl::ScalingLinearOperator<BlockVector> ScalingOperator;
    \n+
    182 typedef Impl::LinearOperatorSum<MatrixOperator,ScalingOperator> OperatorSum;
    \n+
    183
    \n+
    184 public:
    \n+\n+
    187
    \n+\n+
    190
    \n+
    191 public:
    \n+\n+
    207 const unsigned int nIterationsMax = 1000,
    \n+
    208 const unsigned int verbosity_level = 0)
    \n+
    209 : m_(m), nIterationsMax_(nIterationsMax),
    \n+
    210 verbosity_level_(verbosity_level),
    \n+
    211 mu_(0.0),
    \n+\n+
    213 scalingOperator_(-1.0,mu_),
    \n+\n+
    215 nIterations_(0),
    \n+
    216 title_(" PowerIteration_Algorithms: "),
    \n+
    217 blank_(title_.length(),' ')
    \n+
    218 {
    \n+
    219 // assert that BCRSMatrix type has blocklevel 2
    \n+
    220 static_assert
    \n+
    221 (blockLevel<BCRSMatrix>() == 2,
    \n+
    222 "Only BCRSMatrices with blocklevel 2 are supported.");
    \n+
    223
    \n+
    224 // assert that BCRSMatrix type has square blocks
    \n+
    225 static_assert
    \n+
    226 (BCRSMatrix::block_type::rows == BCRSMatrix::block_type::cols,
    \n+
    227 "Only BCRSMatrices with square blocks are supported.");
    \n+
    228
    \n+
    229 // assert that m_ is square
    \n+
    230 const int nrows = m_.M() * BCRSMatrix::block_type::rows;
    \n+
    231 const int ncols = m_.N() * BCRSMatrix::block_type::cols;
    \n+
    232 if (nrows != ncols)
    \n+
    233 DUNE_THROW(Dune::ISTLError,"Matrix is not square ("
    \n+
    234 << nrows << "x" << ncols << ").");
    \n+
    235 }
    \n
    236
    \n-
    238} // end name space DUNE
    \n-
    239
    \n-
    240
    \n-
    241#endif
    \n-
    A dynamic dense block matrix class.
    \n-
    Define general preconditioner interface.
    \n-
    std::size_t copyToLocalMatrix(const M &A, S &rowset)
    Copy the local part of the global matrix to ILU.
    Definition: ilusubdomainsolver.hh:151
    \n-
    void setSubMatrix(const M &A, S &rowset)
    Set the data of the local problem.
    Definition: ilusubdomainsolver.hh:229
    \n-
    void setSubMatrix(const M &A, S &rowset)
    Set the data of the local problem.
    Definition: ilusubdomainsolver.hh:221
    \n-
    Col col
    Definition: matrixmatrix.hh:351
    \n+\n+
    241
    \n+\n+\n+
    247
    \n+
    260 inline void applyPowerIteration (const Real& epsilon,
    \n+
    261 BlockVector& x, Real& lambda) const
    \n+
    262 {
    \n+
    263 // print verbosity information
    \n+
    264 if (verbosity_level_ > 0)
    \n+
    265 std::cout << title_
    \n+
    266 << "Performing power iteration approximating "
    \n+
    267 << "the dominant eigenvalue." << std::endl;
    \n+
    268
    \n+
    269 // allocate memory for auxiliary variables
    \n+
    270 BlockVector y(x);
    \n+
    271 BlockVector temp(x);
    \n+
    272
    \n+
    273 // perform power iteration
    \n+
    274 x *= (1.0 / x.two_norm());
    \n+
    275 m_.mv(x,y);
    \n+
    276 Real r_norm = std::numeric_limits<Real>::max();
    \n+
    277 nIterations_ = 0;
    \n+
    278 while (r_norm > epsilon)
    \n+
    279 {
    \n+
    280 // update and check number of iterations
    \n+\n+
    282 DUNE_THROW(Dune::ISTLError,"Power iteration did not converge "
    \n+
    283 << "in " << nIterationsMax_ << " iterations "
    \n+
    284 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n+
    285 << epsilon << ").");
    \n+
    286
    \n+
    287 // do one iteration of the power iteration algorithm
    \n+
    288 // (use that y = m_ * x)
    \n+
    289 x = y;
    \n+
    290 x *= (1.0 / y.two_norm());
    \n+
    291
    \n+
    292 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n+
    293 m_.mv(x,y);
    \n+
    294 lambda = x * y;
    \n+
    295
    \n+
    296 // get norm of residual (use that y = m_ * x)
    \n+
    297 temp = y;
    \n+
    298 temp.axpy(-lambda,x);
    \n+
    299 r_norm = temp.two_norm();
    \n+
    300
    \n+
    301 // print verbosity information
    \n+
    302 if (verbosity_level_ > 1)
    \n+
    303 std::cout << blank_ << std::left
    \n+
    304 << "iteration " << std::setw(3) << nIterations_
    \n+
    305 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n+
    306 << "): \u03bb = " << lambda << std::endl
    \n+
    307 << std::resetiosflags(std::ios::left);
    \n+
    308 }
    \n+
    309
    \n+
    310 // print verbosity information
    \n+
    311 if (verbosity_level_ > 0)
    \n+
    312 {
    \n+
    313 std::cout << blank_ << "Result ("
    \n+
    314 << "#iterations = " << nIterations_ << ", "
    \n+
    315 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    316 << "\u03bb = " << lambda << std::endl;
    \n+
    317 if (verbosity_level_ > 2)
    \n+
    318 {
    \n+
    319 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    320 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    321 }
    \n+
    322 }
    \n+
    323 }
    \n+
    324
    \n+
    353 template <typename ISTLLinearSolver,
    \n+
    354 bool avoidLinSolverCrime = false>
    \n+
    355 inline void applyInverseIteration (const Real& epsilon,
    \n+
    356 ISTLLinearSolver& solver,
    \n+
    357 BlockVector& x, Real& lambda) const
    \n+
    358 {
    \n+
    359 constexpr Real gamma = 0.0;
    \n+
    360 applyInverseIteration(gamma,epsilon,solver,x,lambda);
    \n+
    361 }
    \n+
    362
    \n+
    392 template <typename ISTLLinearSolver,
    \n+
    393 bool avoidLinSolverCrime = false>
    \n+
    394 inline void applyInverseIteration (const Real& gamma,
    \n+
    395 const Real& epsilon,
    \n+
    396 ISTLLinearSolver& solver,
    \n+
    397 BlockVector& x, Real& lambda) const
    \n+
    398 {
    \n+
    399 // print verbosity information
    \n+
    400 if (verbosity_level_ > 0)
    \n+
    401 {
    \n+
    402 std::cout << title_;
    \n+
    403 if (gamma == 0.0)
    \n+
    404 std::cout << "Performing inverse iteration approximating "
    \n+
    405 << "the least dominant eigenvalue." << std::endl;
    \n+
    406 else
    \n+
    407 std::cout << "Performing inverse iteration with shift "
    \n+
    408 << "gamma = " << gamma << " approximating the "
    \n+
    409 << "eigenvalue closest to gamma." << std::endl;
    \n+
    410 }
    \n+
    411
    \n+
    412 // initialize iteration operator,
    \n+
    413 // initialize iteration matrix when needed
    \n+
    414 updateShiftMu(gamma,solver);
    \n+
    415
    \n+
    416 // allocate memory for linear solver statistics
    \n+
    417 Dune::InverseOperatorResult solver_statistics;
    \n+
    418
    \n+
    419 // allocate memory for auxiliary variables
    \n+
    420 BlockVector y(x);
    \n+
    421 Real y_norm;
    \n+
    422 BlockVector temp(x);
    \n+
    423
    \n+
    424 // perform inverse iteration with shift
    \n+
    425 x *= (1.0 / x.two_norm());
    \n+
    426 Real r_norm = std::numeric_limits<Real>::max();
    \n+
    427 nIterations_ = 0;
    \n+
    428 while (r_norm > epsilon)
    \n+
    429 {
    \n+
    430 // update and check number of iterations
    \n+\n+
    432 DUNE_THROW(Dune::ISTLError,"Inverse iteration "
    \n+
    433 << (gamma != 0.0 ? "with shift " : "") << "did not "
    \n+
    434 << "converge in " << nIterationsMax_ << " iterations "
    \n+
    435 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n+
    436 << epsilon << ").");
    \n+
    437
    \n+
    438 // do one iteration of the inverse iteration with shift algorithm,
    \n+
    439 // part 1: solve (m_ - gamma*I) * y = x for y
    \n+
    440 // (protect x from being changed)
    \n+
    441 temp = x;
    \n+
    442 solver.apply(y,temp,solver_statistics);
    \n+
    443
    \n+
    444 // get norm of y
    \n+
    445 y_norm = y.two_norm();
    \n+
    446
    \n+
    447 // compile time switch between accuracy and efficiency
    \n+
    448 if (avoidLinSolverCrime)
    \n+
    449 {
    \n+
    450 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n+
    451 // (use that x_new = y / y_norm)
    \n+
    452 m_.mv(y,temp);
    \n+
    453 lambda = (y * temp) / (y_norm * y_norm);
    \n+
    454
    \n+
    455 // get norm of residual
    \n+
    456 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)
    \n+
    457 temp.axpy(-lambda,y);
    \n+
    458 r_norm = temp.two_norm() / y_norm;
    \n+
    459 }
    \n+
    460 else
    \n+
    461 {
    \n+
    462 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n+
    463 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)
    \n+
    464 lambda = gamma + (y * x) / (y_norm * y_norm);
    \n+
    465
    \n+
    466 // get norm of residual
    \n+
    467 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)
    \n+
    468 temp = x; temp.axpy(gamma-lambda,y);
    \n+
    469 r_norm = temp.two_norm() / y_norm;
    \n+
    470 }
    \n+
    471
    \n+
    472 // do one iteration of the inverse iteration with shift algorithm,
    \n+
    473 // part 2: update x
    \n+
    474 x = y;
    \n+
    475 x *= (1.0 / y_norm);
    \n+
    476
    \n+
    477 // print verbosity information
    \n+
    478 if (verbosity_level_ > 1)
    \n+
    479 std::cout << blank_ << std::left
    \n+
    480 << "iteration " << std::setw(3) << nIterations_
    \n+
    481 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n+
    482 << "): \u03bb = " << lambda << std::endl
    \n+
    483 << std::resetiosflags(std::ios::left);
    \n+
    484 }
    \n+
    485
    \n+
    486 // print verbosity information
    \n+
    487 if (verbosity_level_ > 0)
    \n+
    488 {
    \n+
    489 std::cout << blank_ << "Result ("
    \n+
    490 << "#iterations = " << nIterations_ << ", "
    \n+
    491 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    492 << "\u03bb = " << lambda << std::endl;
    \n+
    493 if (verbosity_level_ > 2)
    \n+
    494 {
    \n+
    495 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    496 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    497 }
    \n+
    498 }
    \n+
    499 }
    \n+
    500
    \n+
    531 template <typename ISTLLinearSolver,
    \n+
    532 bool avoidLinSolverCrime = false>
    \n+
    533 inline void applyRayleighQuotientIteration (const Real& epsilon,
    \n+
    534 ISTLLinearSolver& solver,
    \n+
    535 BlockVector& x, Real& lambda) const
    \n+
    536 {
    \n+
    537 // print verbosity information
    \n+
    538 if (verbosity_level_ > 0)
    \n+
    539 std::cout << title_
    \n+
    540 << "Performing Rayleigh quotient iteration for "
    \n+
    541 << "estimated eigenvalue " << lambda << "." << std::endl;
    \n+
    542
    \n+
    543 // allocate memory for linear solver statistics
    \n+
    544 Dune::InverseOperatorResult solver_statistics;
    \n+
    545
    \n+
    546 // allocate memory for auxiliary variables
    \n+
    547 BlockVector y(x);
    \n+
    548 Real y_norm;
    \n+
    549 Real lambda_update;
    \n+
    550 BlockVector temp(x);
    \n+
    551
    \n+
    552 // perform Rayleigh quotient iteration
    \n+
    553 x *= (1.0 / x.two_norm());
    \n+
    554 Real r_norm = std::numeric_limits<Real>::max();
    \n+
    555 nIterations_ = 0;
    \n+
    556 while (r_norm > epsilon)
    \n+
    557 {
    \n+
    558 // update and check number of iterations
    \n+\n+
    560 DUNE_THROW(Dune::ISTLError,"Rayleigh quotient iteration did not "
    \n+
    561 << "converge in " << nIterationsMax_ << " iterations "
    \n+
    562 << "(\u2551residual\u2551_2 = " << r_norm << ", epsilon = "
    \n+
    563 << epsilon << ").");
    \n+
    564
    \n+
    565 // update iteration operator,
    \n+
    566 // update iteration matrix when needed
    \n+
    567 updateShiftMu(lambda,solver);
    \n+
    568
    \n+
    569 // do one iteration of the Rayleigh quotient iteration algorithm,
    \n+
    570 // part 1: solve (m_ - lambda*I) * y = x for y
    \n+
    571 // (protect x from being changed)
    \n+
    572 temp = x;
    \n+
    573 solver.apply(y,temp,solver_statistics);
    \n+
    574
    \n+
    575 // get norm of y
    \n+
    576 y_norm = y.two_norm();
    \n+
    577
    \n+
    578 // compile time switch between accuracy and efficiency
    \n+
    579 if (avoidLinSolverCrime)
    \n+
    580 {
    \n+
    581 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n+
    582 // (use that x_new = y / y_norm)
    \n+
    583 m_.mv(y,temp);
    \n+
    584 lambda = (y * temp) / (y_norm * y_norm);
    \n+
    585
    \n+
    586 // get norm of residual
    \n+
    587 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)
    \n+
    588 temp.axpy(-lambda,y);
    \n+
    589 r_norm = temp.two_norm() / y_norm;
    \n+
    590 }
    \n+
    591 else
    \n+
    592 {
    \n+
    593 // get approximated eigenvalue lambda via the Rayleigh quotient
    \n+
    594 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)
    \n+
    595 lambda_update = (y * x) / (y_norm * y_norm);
    \n+
    596 lambda += lambda_update;
    \n+
    597
    \n+
    598 // get norm of residual
    \n+
    599 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)
    \n+
    600 temp = x; temp.axpy(-lambda_update,y);
    \n+
    601 r_norm = temp.two_norm() / y_norm;
    \n+
    602 }
    \n+
    603
    \n+
    604 // do one iteration of the Rayleigh quotient iteration algorithm,
    \n+
    605 // part 2: update x
    \n+
    606 x = y;
    \n+
    607 x *= (1.0 / y_norm);
    \n+
    608
    \n+
    609 // print verbosity information
    \n+
    610 if (verbosity_level_ > 1)
    \n+
    611 std::cout << blank_ << std::left
    \n+
    612 << "iteration " << std::setw(3) << nIterations_
    \n+
    613 << " (\u2551residual\u2551_2 = " << std::setw(11) << r_norm
    \n+
    614 << "): \u03bb = " << lambda << std::endl
    \n+
    615 << std::resetiosflags(std::ios::left);
    \n+
    616 }
    \n+
    617
    \n+
    618 // print verbosity information
    \n+
    619 if (verbosity_level_ > 0)
    \n+
    620 {
    \n+
    621 std::cout << blank_ << "Result ("
    \n+
    622 << "#iterations = " << nIterations_ << ", "
    \n+
    623 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    624 << "\u03bb = " << lambda << std::endl;
    \n+
    625 if (verbosity_level_ > 2)
    \n+
    626 {
    \n+
    627 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    628 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    629 }
    \n+
    630 }
    \n+
    631 }
    \n+
    632
    \n+
    689 template <typename ISTLLinearSolver,
    \n+
    690 bool avoidLinSolverCrime = false>
    \n+
    691 inline void applyTLIMEIteration (const Real& gamma, const Real& eta,
    \n+
    692 const Real& epsilon,
    \n+
    693 ISTLLinearSolver& solver,
    \n+
    694 const Real& delta, const std::size_t& m,
    \n+
    695 bool& extrnl,
    \n+
    696 BlockVector& x, Real& lambda) const
    \n+
    697 {
    \n+
    698 // use same variable names as in [Szyld, 1988]
    \n+
    699 BlockVector& x_s = x;
    \n+
    700 Real& mu_s = lambda;
    \n+
    701
    \n+
    702 // print verbosity information
    \n+
    703 if (verbosity_level_ > 0)
    \n+
    704 std::cout << title_
    \n+
    705 << "Performing TLIME iteration for "
    \n+
    706 << "estimated eigenvalue in the "
    \n+
    707 << "interval (" << gamma - eta << ","
    \n+
    708 << gamma + eta << ")." << std::endl;
    \n+
    709
    \n+
    710 // allocate memory for linear solver statistics
    \n+
    711 Dune::InverseOperatorResult solver_statistics;
    \n+
    712
    \n+
    713 // allocate memory for auxiliary variables
    \n+
    714 bool doRQI;
    \n+
    715 Real mu;
    \n+
    716 BlockVector y(x_s);
    \n+
    717 Real omega;
    \n+
    718 Real mu_s_old;
    \n+
    719 Real mu_s_update;
    \n+
    720 BlockVector temp(x_s);
    \n+
    721 Real q_norm, r_norm;
    \n+
    722
    \n+
    723 // perform TLIME iteration
    \n+
    724 x_s *= (1.0 / x_s.two_norm());
    \n+
    725 extrnl = true;
    \n+
    726 doRQI = false;
    \n+
    727 r_norm = std::numeric_limits<Real>::max();
    \n+
    728 nIterations_ = 0;
    \n+
    729 while (r_norm > epsilon)
    \n+
    730 {
    \n+
    731 // update and check number of iterations
    \n+\n+
    733 DUNE_THROW(Dune::ISTLError,"TLIME iteration did not "
    \n+
    734 << "converge in " << nIterationsMax_
    \n+
    735 << " iterations (\u2551residual\u2551_2 = " << r_norm
    \n+
    736 << ", epsilon = " << epsilon << ").");
    \n+
    737
    \n+
    738 // set shift for next iteration according to inverse iteration
    \n+
    739 // with shift (II) resp. Rayleigh quotient iteration (RQI)
    \n+
    740 if (doRQI)
    \n+
    741 mu = mu_s;
    \n+
    742 else
    \n+
    743 mu = gamma;
    \n+
    744
    \n+
    745 // update II/RQI iteration operator,
    \n+
    746 // update II/RQI iteration matrix when needed
    \n+
    747 updateShiftMu(mu,solver);
    \n+
    748
    \n+
    749 // do one iteration of the II/RQI algorithm,
    \n+
    750 // part 1: solve (m_ - mu*I) * y = x for y
    \n+
    751 temp = x_s;
    \n+
    752 solver.apply(y,temp,solver_statistics);
    \n+
    753
    \n+
    754 // do one iteration of the II/RQI algorithm,
    \n+
    755 // part 2: compute omega
    \n+
    756 omega = (1.0 / y.two_norm());
    \n+
    757
    \n+
    758 // backup the old Rayleigh quotient
    \n+
    759 mu_s_old = mu_s;
    \n+
    760
    \n+
    761 // compile time switch between accuracy and efficiency
    \n+
    762 if (avoidLinSolverCrime)
    \n+
    763 {
    \n+
    764 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue
    \n+
    765 // (use that x_new = y * omega)
    \n+
    766 m_.mv(y,temp);
    \n+
    767 mu_s = (y * temp) * (omega * omega);
    \n+
    768
    \n+
    769 // get norm of "the residual with respect to the shift used by II",
    \n+
    770 // use normal representation of q
    \n+
    771 // (use that x_new = y * omega, use that temp = m_ * y)
    \n+
    772 temp.axpy(-gamma,y);
    \n+
    773 q_norm = temp.two_norm() * omega;
    \n+
    774
    \n+
    775 // get norm of "the residual with respect to the Rayleigh quotient"
    \n+
    776 r_norm = q_norm*q_norm - (gamma-mu_s)*(gamma-mu_s);
    \n+
    777 // prevent that truncation errors invalidate the norm
    \n+
    778 // (we don't want to calculate sqrt of a negative number)
    \n+
    779 if (r_norm >= 0)
    \n+
    780 {
    \n+
    781 // use relation between the norms of r and q for efficiency
    \n+
    782 r_norm = std::sqrt(r_norm);
    \n+
    783 }
    \n+
    784 else
    \n+
    785 {
    \n+
    786 // use relation between r and q
    \n+
    787 // (use that x_new = y * omega, use that temp = (m_ - gamma*I) * y = q / omega)
    \n+
    788 temp.axpy(gamma-mu_s,y);
    \n+
    789 r_norm = temp.two_norm() * omega;
    \n+
    790 }
    \n+
    791 }
    \n+
    792 else
    \n+
    793 {
    \n+
    794 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue
    \n+
    795 if (!doRQI)
    \n+
    796 {
    \n+
    797 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y = x_s)
    \n+
    798 mu_s = gamma + (y * x_s) * (omega * omega);
    \n+
    799 }
    \n+
    800 else
    \n+
    801 {
    \n+
    802 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) * y = x_s)
    \n+
    803 mu_s_update = (y * x_s) * (omega * omega);
    \n+
    804 mu_s += mu_s_update;
    \n+
    805 }
    \n+
    806
    \n+
    807 // get norm of "the residual with respect to the shift used by II"
    \n+
    808 if (!doRQI)
    \n+
    809 {
    \n+
    810 // use special representation of q in the II case
    \n+
    811 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y = x_s)
    \n+
    812 q_norm = omega;
    \n+
    813 }
    \n+
    814 else
    \n+
    815 {
    \n+
    816 // use special representation of q in the RQI case
    \n+
    817 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) * y = x_s)
    \n+
    818 temp = x_s; temp.axpy(mu_s-gamma,y);
    \n+
    819 q_norm = temp.two_norm() * omega;
    \n+
    820 }
    \n+
    821
    \n+
    822 // get norm of "the residual with respect to the Rayleigh quotient"
    \n+
    823 // don't use efficient relation between the norms of r and q, as
    \n+
    824 // this relation seems to yield a less accurate r_norm in the case
    \n+
    825 // where linear solver crime is admitted
    \n+
    826 if (!doRQI)
    \n+
    827 {
    \n+
    828 // (use that x_new = y * omega and use that (m_ - gamma*I) * y = x_s)
    \n+
    829 temp = x_s; temp.axpy(gamma-lambda,y);
    \n+
    830 r_norm = temp.two_norm() * omega;
    \n+
    831 }
    \n+
    832 else
    \n+
    833 {
    \n+
    834 // (use that x_new = y * omega and use that (m_ - mu_s_old*I) * y = x_s)
    \n+
    835 temp = x_s; temp.axpy(-mu_s_update,y);
    \n+
    836 r_norm = temp.two_norm() * omega;
    \n+
    837 }
    \n+
    838 }
    \n+
    839
    \n+
    840 // do one iteration of the II/RQI algorithm,
    \n+
    841 // part 3: update x
    \n+
    842 x_s = y; x_s *= omega;
    \n+
    843
    \n+
    844 // // for relative residual norm mode, scale with mu_s^{-1}
    \n+
    845 // r_norm /= std::abs(mu_s);
    \n+
    846
    \n+
    847 // print verbosity information
    \n+
    848 if (verbosity_level_ > 1)
    \n+
    849 std::cout << blank_ << "iteration "
    \n+
    850 << std::left << std::setw(3) << nIterations_
    \n+
    851 << " (" << (doRQI ? "RQI," : "II, ")
    \n+
    852 << " " << (doRQI ? "\u2014>" : " ") << " "
    \n+
    853 << "\u2551r\u2551_2 = " << std::setw(11) << r_norm
    \n+
    854 << ", " << (doRQI ? " " : "\u2014>") << " "
    \n+
    855 << "\u2551q\u2551_2 = " << std::setw(11) << q_norm
    \n+
    856 << "): \u03bb = " << lambda << std::endl
    \n+
    857 << std::resetiosflags(std::ios::left);
    \n+
    858
    \n+
    859 // check if the eigenvalue closest to gamma lies in J
    \n+
    860 if (!doRQI && q_norm < eta)
    \n+
    861 {
    \n+
    862 // J is not free of eigenvalues
    \n+
    863 extrnl = false;
    \n+
    864
    \n+
    865 // by theory we know now that mu_s also lies in J
    \n+
    866 assert(std::abs(mu_s-gamma) < eta);
    \n+
    867
    \n+
    868 // switch to RQI
    \n+
    869 doRQI = true;
    \n+
    870 }
    \n+
    871
    \n+
    872 // revert to II if J is not free of eigenvalues but
    \n+
    873 // at some point mu_s falls back again outside J
    \n+
    874 if (!extrnl && doRQI && std::abs(mu_s-gamma) >= eta)
    \n+
    875 doRQI = false;
    \n+
    876
    \n+
    877 // if eigenvalue closest to gamma does not lie in J use RQI
    \n+
    878 // solely to accelerate the convergence to this eigenvalue
    \n+
    879 // when II has become stationary
    \n+
    880 if (extrnl && !doRQI)
    \n+
    881 {
    \n+
    882 // switch to RQI if the relative change of the Rayleigh
    \n+
    883 // quotient indicates that II has become stationary
    \n+
    884 if (nIterations_ >= m &&
    \n+
    885 std::abs(mu_s - mu_s_old) / std::abs(mu_s) < delta)
    \n+
    886 doRQI = true;
    \n+
    887 }
    \n+
    888 }
    \n+
    889
    \n+
    890 // // compute final residual and lambda again (paranoia....)
    \n+
    891 // m_.mv(x_s,temp);
    \n+
    892 // mu_s = x_s * temp;
    \n+
    893 // temp.axpy(-mu_s,x_s);
    \n+
    894 // r_norm = temp.two_norm();
    \n+
    895 // // r_norm /= std::abs(mu_s);
    \n+
    896
    \n+
    897 // print verbosity information
    \n+
    898 if (verbosity_level_ > 0)
    \n+
    899 {
    \n+
    900 if (extrnl)
    \n+
    901 std::cout << blank_ << "Interval "
    \n+
    902 << "(" << gamma - eta << "," << gamma + eta
    \n+
    903 << ") is free of eigenvalues, approximating "
    \n+
    904 << "the closest eigenvalue." << std::endl;
    \n+
    905 std::cout << blank_ << "Result ("
    \n+
    906 << "#iterations = " << nIterations_ << ", "
    \n+
    907 << "\u2551residual\u2551_2 = " << r_norm << "): "
    \n+
    908 << "\u03bb = " << lambda << std::endl;
    \n+
    909 if (verbosity_level_ > 2)
    \n+
    910 {
    \n+
    911 // print approximated eigenvector via DUNE-ISTL I/O methods
    \n+
    912 Dune::printvector(std::cout,x,blank_+"x",blank_+"row");
    \n+
    913 }
    \n+
    914 }
    \n+
    915 }
    \n+
    916
    \n+\n+
    926 {
    \n+
    927 // return iteration operator
    \n+
    928 return itOperator_;
    \n+
    929 }
    \n+
    930
    \n+
    945 inline const BCRSMatrix& getIterationMatrix () const
    \n+
    946 {
    \n+
    947 // create iteration matrix on demand
    \n+
    948 if (!itMatrix_)
    \n+
    949 itMatrix_ = std::make_unique<BCRSMatrix>(m_);
    \n+
    950
    \n+
    951 // return iteration matrix
    \n+
    952 return *itMatrix_;
    \n+
    953 }
    \n+
    954
    \n+
    959 inline unsigned int getIterationCount () const
    \n+
    960 {
    \n+
    961 if (nIterations_ == 0)
    \n+
    962 DUNE_THROW(Dune::ISTLError,"No algorithm applied, yet.");
    \n+
    963
    \n+
    964 return nIterations_;
    \n+
    965 }
    \n+
    966
    \n+
    967 protected:
    \n+
    982 template <typename ISTLLinearSolver>
    \n+
    983 inline void updateShiftMu (const Real& mu,
    \n+
    984 ISTLLinearSolver& solver) const
    \n+
    985 {
    \n+
    986 // do nothing if new shift equals the old one
    \n+
    987 if (mu == mu_) return;
    \n+
    988
    \n+
    989 // update shift mu_, i.e. update iteration operator
    \n+
    990 mu_ = mu;
    \n+
    991
    \n+
    992 // update iteration matrix when needed
    \n+
    993 if (itMatrix_)
    \n+
    994 {
    \n+
    995 // iterate over entries in iteration matrix diagonal
    \n+
    996 constexpr int rowBlockSize = BCRSMatrix::block_type::rows;
    \n+
    997 constexpr int colBlockSize = BCRSMatrix::block_type::cols;
    \n+
    998 for (typename BCRSMatrix::size_type i = 0;
    \n+
    999 i < itMatrix_->M()*rowBlockSize; ++i)
    \n+
    1000 {
    \n+
    1001 // access m_[i,i] where i is the flat index of a row/column
    \n+
    1002 const Real& m_entry = m_
    \n+
    1003 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];
    \n+
    1004 // access *itMatrix[i,i] where i is the flat index of a row/column
    \n+
    1005 Real& entry = (*itMatrix_)
    \n+
    1006 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];
    \n+
    1007 // change current entry in iteration matrix diagonal
    \n+
    1008 entry = m_entry - mu_;
    \n+
    1009 }
    \n+
    1010 // notify linear solver about change of the iteration matrix object
    \n+\n+
    1012 (solver,*itMatrix_);
    \n+
    1013 }
    \n+
    1014 }
    \n+
    1015
    \n+
    1016 protected:
    \n+
    1017 // parameters related to iterative eigenvalue algorithms
    \n+\n+
    1019 const unsigned int nIterationsMax_;
    \n+
    1020
    \n+
    1021 // verbosity setting
    \n+
    1022 const unsigned int verbosity_level_;
    \n+
    1023
    \n+
    1024 // shift mu_ used by iteration operator/matrix (m_ - mu_*I)
    \n+
    1025 mutable Real mu_;
    \n+
    1026
    \n+
    1027 // iteration operator (m_ - mu_*I), passing shift mu_ by reference
    \n+\n+\n+\n+
    1031
    \n+
    1032 // iteration matrix (m_ - mu_*I), provided on demand when needed
    \n+
    1033 // (e.g. for preconditioning)
    \n+
    1034 mutable std::unique_ptr<BCRSMatrix> itMatrix_;
    \n+
    1035
    \n+
    1036 // memory for storing temporary variables (mutable as they shall
    \n+
    1037 // just be effectless auxiliary variables of the const apply*(...)
    \n+
    1038 // methods)
    \n+
    1039 mutable unsigned int nIterations_;
    \n+
    1040
    \n+
    1041 // constants for printing verbosity information
    \n+
    1042 const std::string title_;
    \n+
    1043 const std::string blank_;
    \n+
    1044 };
    \n+
    1045
    \n+
    1048} // namespace Dune
    \n+
    1049
    \n+
    1050#endif // DUNE_ISTL_EIGENVALUE_POWERITERATION_HH
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n+
    Templates characterizing the type of a solver.
    \n+
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n+\n+
    Implementations of the inverse operator interface.
    \n+
    Helper functions for determining the vector/matrix block level.
    \n+\n+
    void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
    Print an ISTL vector.
    Definition: io.hh:89
    \n
    Definition: allocator.hh:11
    \n-
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n-
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n-
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n-
    base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver.
    Definition: ilusubdomainsolver.hh:36
    \n-
    matrix_type ILU
    The ILU0 decomposition of the matrix, or the local matrix.
    Definition: ilusubdomainsolver.hh:67
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:41
    \n-
    virtual ~ILUSubdomainSolver()
    Definition: ilusubdomainsolver.hh:53
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:43
    \n-
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:39
    \n-
    virtual void apply(X &v, const Y &d)=0
    Apply the subdomain solver.
    \n-
    Exact subdomain solver using ILU(p) with appropriate p.
    Definition: ilusubdomainsolver.hh:78
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:84
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:86
    \n-
    std::remove_const< M >::type rilu_type
    Definition: ilusubdomainsolver.hh:82
    \n-
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:81
    \n-
    void apply(X &v, const Y &d)
    Apply the subdomain solver.
    Definition: ilusubdomainsolver.hh:93
    \n-
    Definition: ilusubdomainsolver.hh:111
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: ilusubdomainsolver.hh:117
    \n-
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: ilusubdomainsolver.hh:114
    \n-
    std::remove_const< M >::type rilu_type
    Definition: ilusubdomainsolver.hh:115
    \n-
    void apply(X &v, const Y &d)
    Apply the subdomain solver.
    Definition: ilusubdomainsolver.hh:125
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: ilusubdomainsolver.hh:119
    \n+
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n+
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n+
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n+
    void mv(const X &x, Y &y) const
    y = A x
    Definition: bcrsmatrix.hh:1612
    \n+
    size_type N() const
    number of rows (counted in blocks)
    Definition: bcrsmatrix.hh:1972
    \n+
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: bvector.hh:401
    \n+
    Iterative eigenvalue algorithms based on power iteration.
    Definition: poweriteration.hh:176
    \n+
    std::unique_ptr< BCRSMatrix > itMatrix_
    Definition: poweriteration.hh:1034
    \n+
    PowerIteration_Algorithms(const PowerIteration_Algorithms &)=delete
    \n+
    Impl::ScalingLinearOperator< BlockVector > ScalingOperator
    Definition: poweriteration.hh:181
    \n+
    const std::string blank_
    Definition: poweriteration.hh:1043
    \n+
    Impl::LinearOperatorSum< MatrixOperator, ScalingOperator > OperatorSum
    Definition: poweriteration.hh:182
    \n+
    Dune::MatrixAdapter< BCRSMatrix, BlockVector, BlockVector > MatrixOperator
    Definition: poweriteration.hh:180
    \n+
    void applyInverseIteration(const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the inverse iteration algorithm to compute an approximation lambda of the least dominant (i....
    Definition: poweriteration.hh:355
    \n+
    void applyTLIMEIteration(const Real &gamma, const Real &eta, const Real &epsilon, ISTLLinearSolver &solver, const Real &delta, const std::size_t &m, bool &extrnl, BlockVector &x, Real &lambda) const
    Perform the "two-level iterative method for eigenvalue calculations (TLIME)" iteration algorit...
    Definition: poweriteration.hh:691
    \n+
    IterationOperator & getIterationOperator()
    Return the iteration operator (m_ - mu_*I).
    Definition: poweriteration.hh:925
    \n+
    OperatorSum itOperator_
    Definition: poweriteration.hh:1030
    \n+
    const BCRSMatrix & m_
    Definition: poweriteration.hh:1018
    \n+
    PowerIteration_Algorithms(const BCRSMatrix &m, const unsigned int nIterationsMax=1000, const unsigned int verbosity_level=0)
    Construct from required parameters.
    Definition: poweriteration.hh:206
    \n+
    const unsigned int nIterationsMax_
    Definition: poweriteration.hh:1019
    \n+
    void applyPowerIteration(const Real &epsilon, BlockVector &x, Real &lambda) const
    Perform the power iteration algorithm to compute an approximation lambda of the dominant (i....
    Definition: poweriteration.hh:260
    \n+
    OperatorSum IterationOperator
    Type of iteration operator (m_ - mu_*I)
    Definition: poweriteration.hh:189
    \n+
    void applyRayleighQuotientIteration(const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the Rayleigh quotient iteration algorithm to compute an approximation lambda of an eigenvalue...
    Definition: poweriteration.hh:533
    \n+
    void applyInverseIteration(const Real &gamma, const Real &epsilon, ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const
    Perform the inverse iteration with shift algorithm to compute an approximation lambda of the eigenval...
    Definition: poweriteration.hh:394
    \n+
    const ScalingOperator scalingOperator_
    Definition: poweriteration.hh:1029
    \n+
    void updateShiftMu(const Real &mu, ISTLLinearSolver &solver) const
    Update shift mu_, i.e. update iteration operator/matrix (m_ - mu_*I).
    Definition: poweriteration.hh:983
    \n+
    PowerIteration_Algorithms & operator=(const PowerIteration_Algorithms &)=delete
    \n+
    unsigned int getIterationCount() const
    Return the number of iterations in last application of an algorithm.
    Definition: poweriteration.hh:959
    \n+
    const MatrixOperator matrixOperator_
    Definition: poweriteration.hh:1028
    \n+
    const BCRSMatrix & getIterationMatrix() const
    Return the iteration matrix (m_ - mu_*I), provided on demand when needed (e.g. for direct solvers or ...
    Definition: poweriteration.hh:945
    \n+
    unsigned int nIterations_
    Definition: poweriteration.hh:1039
    \n+
    const unsigned int verbosity_level_
    Definition: poweriteration.hh:1022
    \n+
    const std::string title_
    Definition: poweriteration.hh:1042
    \n+
    BlockVector::field_type Real
    Type of underlying field.
    Definition: poweriteration.hh:186
    \n+
    Real mu_
    Definition: poweriteration.hh:1025
    \n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n+
    A linear operator.
    Definition: operators.hh:67
    \n+
    X::field_type field_type
    The field type of the operator.
    Definition: operators.hh:74
    \n+
    virtual void applyscaleadd(field_type alpha, const X &x, X &y) const=0
    apply operator to x, scale and add:
    \n+
    virtual SolverCategory::Category category() const=0
    Category of the linear operator (see SolverCategory::Category)
    \n+
    X range_type
    The type of the range of the operator.
    Definition: operators.hh:72
    \n+
    virtual void apply(const X &x, X &y) const=0
    apply operator to x: The input vector is consistent and the output must also be consistent on the in...
    \n+
    X domain_type
    The type of the domain of the operator.
    Definition: operators.hh:70
    \n+
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)
    Definition: solver.hh:524
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-us-ascii\n+utf-8\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,286 +4,995 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-ilusubdomainsolver.hh\n+ * eigenvalue\n+poweriteration.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_ILUSUBDOMAINSOLVER_HH\n- 6#define DUNE_ISTL_ILUSUBDOMAINSOLVER_HH\n+ 5#ifndef DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n+ 6#define DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \"matrix.hh\"\n- 12#include \n- 13#include \n- 14\n- 15namespace Dune {\n- 16\n- 35 template\n-36 class ILUSubdomainSolver {\n- 37 public:\n-39 typedef typename std::remove_const::type matrix_type;\n-41 typedef X domain_type;\n-43 typedef Y range_type;\n- 44\n-51 virtual void apply (X& v, const Y& d) =0;\n+ 8#include // provides std::size_t\n+ 9#include // provides std::sqrt, std::abs\n+ 10\n+ 11#include // provides std::is_same\n+ 12#include // provides std::cout, std::endl\n+ 13#include // provides std::numeric_limits\n+ 14#include // provides std::left, std::ios::left\n+ 15#include // provides std::setw, std::resetiosflags\n+ 16#include // provides std::unique_ptr\n+ 17#include // provides std::string\n+ 18\n+ 19#include // provides DUNE_THROW(...)\n+ 20\n+ 21#include // provides Dune::blockLevel\n+ 22#include // provides Dune::LinearOperator\n+ 23#include // provides Dune::SolverCategory::\n+sequential\n+ 24#include // provides Dune::IsDirectSolver\n+ 25#include // provides Dune::MatrixAdapter\n+ 26#include // provides Dune::ISTLError\n+ 27#include // provides Dune::printvector(...)\n+ 28#include // provides Dune::InverseOperatorResult\n+ 29\n+ 30namespace Dune\n+ 31{\n+ 32\n+ 37 namespace Impl {\n+ 45 template \n+ 46 class ScalingLinearOperator : public Dune::LinearOperator\n+ 47 {\n+ 48 public:\n+ 49 typedef X domain_type;\n+ 50 typedef Y range_type;\n+ 51 typedef typename X::field_type field_type;\n 52\n-53 virtual ~ILUSubdomainSolver()\n- 54 {}\n- 55\n- 56 protected:\n- 62 template\n- 63 std::size_t copyToLocalMatrix(const M& A, S& rowset);\n+ 53 ScalingLinearOperator (field_type immutable_scaling,\n+ 54 const field_type& mutable_scaling)\n+ 55 : immutable_scaling_(immutable_scaling),\n+ 56 mutable_scaling_(mutable_scaling)\n+ 57 {}\n+ 58\n+ 59 virtual void apply (const X& x, Y& y) const\n+ 60 {\n+ 61 y = x;\n+ 62 y *= immutable_scaling_*mutable_scaling_;\n+ 63 }\n 64\n- 66 // for ILUN\n-67 matrix_type ILU;\n- 68 };\n- 69\n- 76 template\n-77 class ILU0SubdomainSolver\n- 78 : public ILUSubdomainSolver{\n- 79 public:\n-81 typedef typename std::remove_const::type matrix_type;\n-82 typedef typename std::remove_const::type rilu_type;\n-84 typedef X domain_type;\n-86 typedef Y range_type;\n- 87\n- 88\n-93 void apply (X& v, const Y& d)\n- 94 {\n- 95 ILU::blockILUBacksolve(this->ILU,v,d);\n- 96 }\n- 104 template\n- 105 void setSubMatrix(const M& A, S& rowset);\n- 106\n- 107 };\n- 108\n- 109 template\n-110 class ILUNSubdomainSolver\n- 111 : public ILUSubdomainSolver{\n- 112 public:\n-114 typedef typename std::remove_const::type matrix_type;\n-115 typedef typename std::remove_const::type rilu_type;\n-117 typedef X domain_type;\n-119 typedef Y range_type;\n- 120\n-125 void apply (X& v, const Y& d)\n- 126 {\n- 127 ILU::blockILUBacksolve(RILU,v,d);\n- 128 }\n- 129\n- 137 template\n- 138 void setSubMatrix(const M& A, S& rowset);\n- 139\n- 140 private:\n- 144 rilu_type RILU;\n- 145 };\n- 146\n- 147\n- 148\n- 149 template\n- 150 template\n-151 std::size_t ILUSubdomainSolver::copyToLocalMatrix(const M& A, S&\n-rowSet)\n- 152 {\n- 153 // Calculate consecutive indices for local problem\n- 154 // while perserving the ordering\n- 155 typedef typename M::size_type size_type;\n- 156 typedef std::map IndexMap;\n- 157 typedef typename IndexMap::iterator IMIter;\n- 158 IndexMap indexMap;\n- 159 IMIter guess = indexMap.begin();\n- 160 size_type localIndex=0;\n- 161\n- 162 typedef typename S::const_iterator SIter;\n- 163 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n- 164 rowIdx!= rowEnd; ++rowIdx, ++localIndex)\n- 165 guess = indexMap.insert(guess,\n- 166 std::make_pair(*rowIdx,localIndex));\n- 167\n- 168\n- 169 // Build Matrix for local subproblem\n- 170 ILU.setSize(rowSet.size(),rowSet.size());\n- 171 ILU.setBuildMode(matrix_type::row_wise);\n- 172\n- 173 // Create sparsity pattern\n- 174 typedef typename matrix_type::CreateIterator CIter;\n- 175 CIter rowCreator = ILU.createbegin();\n- 176 std::size_t offset=0;\n- 177 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n- 178 rowIdx!= rowEnd; ++rowIdx, ++rowCreator) {\n- 179 // See which row entries are in our subset and add them to\n- 180 // the sparsity pattern\n- 181 guess = indexMap.begin();\n- 182\n- 183 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),\n- 184 endcol=A[*rowIdx].end(); col != endcol; ++col) {\n- 185 // search for the entry in the row set\n- 186 guess = indexMap.find(col.index());\n- 187 if(guess!=indexMap.end()) {\n- 188 // add local index to row\n- 189 rowCreator.insert(guess->second);\n- 190 offset=std::max(offset,(std::size_t)std::abs((int)(guess->second-\n-rowCreator.index())));\n- 191 }\n- 192 }\n- 193\n- 194 }\n- 195\n- 196 // Insert the matrix values for the local problem\n- 197 typename matrix_type::iterator iluRow=ILU.begin();\n- 198\n- 199 for(SIter rowIdx = rowSet.begin(), rowEnd=rowSet.end();\n- 200 rowIdx!= rowEnd; ++rowIdx, ++iluRow) {\n- 201 // See which row entries are in our subset and add them to\n- 202 // the sparsity pattern\n- 203 typename matrix_type::ColIterator localCol=iluRow->begin();\n- 204 for(typename matrix_type::ConstColIterator col=A[*rowIdx].begin(),\n- 205 endcol=A[*rowIdx].end(); col != endcol; ++col) {\n- 206 // search for the entry in the row set\n- 207 guess = indexMap.find(col.index());\n- 208 if(guess!=indexMap.end()) {\n- 209 // set local value\n- 210 (*localCol)=(*col);\n- 211 ++localCol;\n- 212 }\n- 213 }\n- 214 }\n- 215 return offset;\n- 216 }\n- 217\n- 218\n- 219 template\n- 220 template\n-221 void ILU0SubdomainSolver::setSubMatrix(const M& A, S& rowSet)\n- 222 {\n- 223 this->copyToLocalMatrix(A,rowSet);\n- 224 ILU::blockILU0Decomposition(this->ILU);\n- 225 }\n- 226\n- 227 template\n- 228 template\n-229 void ILUNSubdomainSolver::setSubMatrix(const M& A, S& rowSet)\n- 230 {\n- 231 std::size_t offset=copyToLocalMatrix(A,rowSet);\n- 232 RILU.setSize(rowSet.size(),rowSet.size(), (1+2*offset)*rowSet.size());\n- 233 RILU.setBuildMode(matrix_type::row_wise);\n- 234 ILU::blockILUDecomposition(this->ILU, (offset+1)/2, RILU);\n+ 65 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n+ 66 {\n+ 67 X temp(x);\n+ 68 temp *= immutable_scaling_*mutable_scaling_;\n+ 69 y.axpy(alpha,temp);\n+ 70 }\n+ 71\n+ 73 virtual SolverCategory::Category category() const\n+ 74 {\n+ 75 return SolverCategory::sequential;\n+ 76 }\n+ 77\n+ 78 protected:\n+ 79 const field_type immutable_scaling_;\n+ 80 const field_type& mutable_scaling_;\n+ 81 };\n+ 82\n+ 83\n+ 92 template \n+ 93 class LinearOperatorSum\n+ 94 : public Dune::LinearOperator\n+ 96 {\n+ 97 public:\n+ 98 typedef typename OP1::domain_type domain_type;\n+ 99 typedef typename OP1::range_type range_type;\n+ 100 typedef typename domain_type::field_type field_type;\n+ 101\n+ 102 LinearOperatorSum (const OP1& op1, const OP2& op2)\n+ 103 : op1_(op1), op2_(op2)\n+ 104 {\n+ 105 static_assert(std::is_same::value,\n+ 106 \"Domain type of both operators doesn't match!\");\n+ 107 static_assert(std::is_same::value,\n+ 108 \"Range type of both operators doesn't match!\");\n+ 109 }\n+ 110\n+ 111 virtual void apply (const domain_type& x, range_type& y) const\n+ 112 {\n+ 113 op1_.apply(x,y);\n+ 114 op2_.applyscaleadd(1.0,x,y);\n+ 115 }\n+ 116\n+ 117 virtual void applyscaleadd (field_type alpha,\n+ 118 const domain_type& x, range_type& y) const\n+ 119 {\n+ 120 range_type temp(y);\n+ 121 op1_.apply(x,temp);\n+ 122 op2_.applyscaleadd(1.0,x,temp);\n+ 123 y.axpy(alpha,temp);\n+ 124 }\n+ 125\n+ 127 virtual SolverCategory::Category category() const\n+ 128 {\n+ 129 return SolverCategory::sequential;\n+ 130 }\n+ 131\n+ 132 protected:\n+ 133 const OP1& op1_;\n+ 134 const OP2& op2_;\n+ 135 };\n+ 136 } // end namespace Impl\n+ 137\n+ 174 template \n+175 class PowerIteration_Algorithms\n+ 176 {\n+ 177 protected:\n+ 178 // Type definitions for type of iteration operator (m_ - mu_*I)\n+ 179 typedef typename Dune::MatrixAdapter\n+180 MatrixOperator;\n+181 typedef Impl::ScalingLinearOperator ScalingOperator;\n+182 typedef Impl::LinearOperatorSum\n+OperatorSum;\n+ 183\n+ 184 public:\n+186 typedef typename BlockVector::field_type Real;\n+ 187\n+189 typedef OperatorSum IterationOperator;\n+ 190\n+ 191 public:\n+206 PowerIteration_Algorithms (const BCRSMatrix& m,\n+ 207 const unsigned int nIterationsMax = 1000,\n+ 208 const unsigned int verbosity_level = 0)\n+ 209 : m_(m), nIterationsMax_(nIterationsMax),\n+ 210 verbosity_level_(verbosity_level),\n+ 211 mu_(0.0),\n+ 212 matrixOperator_(m_),\n+ 213 scalingOperator_(-1.0,mu_),\n+ 214 itOperator_(matrixOperator_,scalingOperator_),\n+ 215 nIterations_(0),\n+ 216 title_(\" PowerIteration_Algorithms: \"),\n+ 217 blank_(title_.length(),' ')\n+ 218 {\n+ 219 // assert that BCRSMatrix type has blocklevel 2\n+ 220 static_assert\n+ 221 (blockLevel() == 2,\n+ 222 \"Only BCRSMatrices with blocklevel 2 are supported.\");\n+ 223\n+ 224 // assert that BCRSMatrix type has square blocks\n+ 225 static_assert\n+ 226 (BCRSMatrix::block_type::rows == BCRSMatrix::block_type::cols,\n+ 227 \"Only BCRSMatrices with square blocks are supported.\");\n+ 228\n+ 229 // assert that m_ is square\n+ 230 const int nrows = m_.M() * BCRSMatrix::block_type::rows;\n+ 231 const int ncols = m_.N() * BCRSMatrix::block_type::cols;\n+ 232 if (nrows != ncols)\n+ 233 DUNE_THROW(Dune::ISTLError,\"Matrix is not square (\"\n+ 234 << nrows << \"x\" << ncols << \").\");\n 235 }\n 236\n- 238} // end name space DUNE\n- 239\n- 240\n- 241#endif\n-matrix.hh\n-A dynamic dense block matrix class.\n-preconditioners.hh\n-Define general preconditioner interface.\n-Dune::ILUSubdomainSolver::copyToLocalMatrix\n-std::size_t copyToLocalMatrix(const M &A, S &rowset)\n-Copy the local part of the global matrix to ILU.\n-Definition: ilusubdomainsolver.hh:151\n-Dune::ILUNSubdomainSolver::setSubMatrix\n-void setSubMatrix(const M &A, S &rowset)\n-Set the data of the local problem.\n-Definition: ilusubdomainsolver.hh:229\n-Dune::ILU0SubdomainSolver::setSubMatrix\n-void setSubMatrix(const M &A, S &rowset)\n-Set the data of the local problem.\n-Definition: ilusubdomainsolver.hh:221\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n+240 PowerIteration_Algorithms (const PowerIteration_Algorithms&) = delete;\n+ 241\n+ 245 PowerIteration_Algorithms&\n+246 operator=(const PowerIteration_Algorithms&) = delete;\n+ 247\n+260 inline void applyPowerIteration (const Real& epsilon,\n+ 261 BlockVector& x, Real& lambda) const\n+ 262 {\n+ 263 // print verbosity information\n+ 264 if (verbosity_level_ > 0)\n+ 265 std::cout << title_\n+ 266 << \"Performing power iteration approximating \"\n+ 267 << \"the dominant eigenvalue.\" << std::endl;\n+ 268\n+ 269 // allocate memory for auxiliary variables\n+ 270 BlockVector y(x);\n+ 271 BlockVector temp(x);\n+ 272\n+ 273 // perform power iteration\n+ 274 x *= (1.0 / x.two_norm());\n+ 275 m_.mv(x,y);\n+ 276 Real r_norm = std::numeric_limits::max();\n+ 277 nIterations_ = 0;\n+ 278 while (r_norm > epsilon)\n+ 279 {\n+ 280 // update and check number of iterations\n+ 281 if (++nIterations_ > nIterationsMax_)\n+ 282 DUNE_THROW(Dune::ISTLError,\"Power iteration did not converge \"\n+ 283 << \"in \" << nIterationsMax_ << \" iterations \"\n+ 284 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n+ 285 << epsilon << \").\");\n+ 286\n+ 287 // do one iteration of the power iteration algorithm\n+ 288 // (use that y = m_ * x)\n+ 289 x = y;\n+ 290 x *= (1.0 / y.two_norm());\n+ 291\n+ 292 // get approximated eigenvalue lambda via the Rayleigh quotient\n+ 293 m_.mv(x,y);\n+ 294 lambda = x * y;\n+ 295\n+ 296 // get norm of residual (use that y = m_ * x)\n+ 297 temp = y;\n+ 298 temp.axpy(-lambda,x);\n+ 299 r_norm = temp.two_norm();\n+ 300\n+ 301 // print verbosity information\n+ 302 if (verbosity_level_ > 1)\n+ 303 std::cout << blank_ << std::left\n+ 304 << \"iteration \" << std::setw(3) << nIterations_\n+ 305 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n+ 306 << \"): \u03bb = \" << lambda << std::endl\n+ 307 << std::resetiosflags(std::ios::left);\n+ 308 }\n+ 309\n+ 310 // print verbosity information\n+ 311 if (verbosity_level_ > 0)\n+ 312 {\n+ 313 std::cout << blank_ << \"Result (\"\n+ 314 << \"#iterations = \" << nIterations_ << \", \"\n+ 315 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 316 << \"\u03bb = \" << lambda << std::endl;\n+ 317 if (verbosity_level_ > 2)\n+ 318 {\n+ 319 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 320 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 321 }\n+ 322 }\n+ 323 }\n+ 324\n+ 353 template \n+355 inline void applyInverseIteration (const Real& epsilon,\n+ 356 ISTLLinearSolver& solver,\n+ 357 BlockVector& x, Real& lambda) const\n+ 358 {\n+ 359 constexpr Real gamma = 0.0;\n+ 360 applyInverseIteration(gamma,epsilon,solver,x,lambda);\n+ 361 }\n+ 362\n+ 392 template \n+394 inline void applyInverseIteration (const Real& gamma,\n+ 395 const Real& epsilon,\n+ 396 ISTLLinearSolver& solver,\n+ 397 BlockVector& x, Real& lambda) const\n+ 398 {\n+ 399 // print verbosity information\n+ 400 if (verbosity_level_ > 0)\n+ 401 {\n+ 402 std::cout << title_;\n+ 403 if (gamma == 0.0)\n+ 404 std::cout << \"Performing inverse iteration approximating \"\n+ 405 << \"the least dominant eigenvalue.\" << std::endl;\n+ 406 else\n+ 407 std::cout << \"Performing inverse iteration with shift \"\n+ 408 << \"gamma = \" << gamma << \" approximating the \"\n+ 409 << \"eigenvalue closest to gamma.\" << std::endl;\n+ 410 }\n+ 411\n+ 412 // initialize iteration operator,\n+ 413 // initialize iteration matrix when needed\n+ 414 updateShiftMu(gamma,solver);\n+ 415\n+ 416 // allocate memory for linear solver statistics\n+ 417 Dune::InverseOperatorResult solver_statistics;\n+ 418\n+ 419 // allocate memory for auxiliary variables\n+ 420 BlockVector y(x);\n+ 421 Real y_norm;\n+ 422 BlockVector temp(x);\n+ 423\n+ 424 // perform inverse iteration with shift\n+ 425 x *= (1.0 / x.two_norm());\n+ 426 Real r_norm = std::numeric_limits::max();\n+ 427 nIterations_ = 0;\n+ 428 while (r_norm > epsilon)\n+ 429 {\n+ 430 // update and check number of iterations\n+ 431 if (++nIterations_ > nIterationsMax_)\n+ 432 DUNE_THROW(Dune::ISTLError,\"Inverse iteration \"\n+ 433 << (gamma != 0.0 ? \"with shift \" : \"\") << \"did not \"\n+ 434 << \"converge in \" << nIterationsMax_ << \" iterations \"\n+ 435 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n+ 436 << epsilon << \").\");\n+ 437\n+ 438 // do one iteration of the inverse iteration with shift algorithm,\n+ 439 // part 1: solve (m_ - gamma*I) * y = x for y\n+ 440 // (protect x from being changed)\n+ 441 temp = x;\n+ 442 solver.apply(y,temp,solver_statistics);\n+ 443\n+ 444 // get norm of y\n+ 445 y_norm = y.two_norm();\n+ 446\n+ 447 // compile time switch between accuracy and efficiency\n+ 448 if (avoidLinSolverCrime)\n+ 449 {\n+ 450 // get approximated eigenvalue lambda via the Rayleigh quotient\n+ 451 // (use that x_new = y / y_norm)\n+ 452 m_.mv(y,temp);\n+ 453 lambda = (y * temp) / (y_norm * y_norm);\n+ 454\n+ 455 // get norm of residual\n+ 456 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)\n+ 457 temp.axpy(-lambda,y);\n+ 458 r_norm = temp.two_norm() / y_norm;\n+ 459 }\n+ 460 else\n+ 461 {\n+ 462 // get approximated eigenvalue lambda via the Rayleigh quotient\n+ 463 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)\n+ 464 lambda = gamma + (y * x) / (y_norm * y_norm);\n+ 465\n+ 466 // get norm of residual\n+ 467 // (use that x_new = y / y_norm and use that (m_ - gamma*I) * y = x)\n+ 468 temp = x; temp.axpy(gamma-lambda,y);\n+ 469 r_norm = temp.two_norm() / y_norm;\n+ 470 }\n+ 471\n+ 472 // do one iteration of the inverse iteration with shift algorithm,\n+ 473 // part 2: update x\n+ 474 x = y;\n+ 475 x *= (1.0 / y_norm);\n+ 476\n+ 477 // print verbosity information\n+ 478 if (verbosity_level_ > 1)\n+ 479 std::cout << blank_ << std::left\n+ 480 << \"iteration \" << std::setw(3) << nIterations_\n+ 481 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n+ 482 << \"): \u03bb = \" << lambda << std::endl\n+ 483 << std::resetiosflags(std::ios::left);\n+ 484 }\n+ 485\n+ 486 // print verbosity information\n+ 487 if (verbosity_level_ > 0)\n+ 488 {\n+ 489 std::cout << blank_ << \"Result (\"\n+ 490 << \"#iterations = \" << nIterations_ << \", \"\n+ 491 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 492 << \"\u03bb = \" << lambda << std::endl;\n+ 493 if (verbosity_level_ > 2)\n+ 494 {\n+ 495 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 496 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 497 }\n+ 498 }\n+ 499 }\n+ 500\n+ 531 template \n+533 inline void applyRayleighQuotientIteration (const Real& epsilon,\n+ 534 ISTLLinearSolver& solver,\n+ 535 BlockVector& x, Real& lambda) const\n+ 536 {\n+ 537 // print verbosity information\n+ 538 if (verbosity_level_ > 0)\n+ 539 std::cout << title_\n+ 540 << \"Performing Rayleigh quotient iteration for \"\n+ 541 << \"estimated eigenvalue \" << lambda << \".\" << std::endl;\n+ 542\n+ 543 // allocate memory for linear solver statistics\n+ 544 Dune::InverseOperatorResult solver_statistics;\n+ 545\n+ 546 // allocate memory for auxiliary variables\n+ 547 BlockVector y(x);\n+ 548 Real y_norm;\n+ 549 Real lambda_update;\n+ 550 BlockVector temp(x);\n+ 551\n+ 552 // perform Rayleigh quotient iteration\n+ 553 x *= (1.0 / x.two_norm());\n+ 554 Real r_norm = std::numeric_limits::max();\n+ 555 nIterations_ = 0;\n+ 556 while (r_norm > epsilon)\n+ 557 {\n+ 558 // update and check number of iterations\n+ 559 if (++nIterations_ > nIterationsMax_)\n+ 560 DUNE_THROW(Dune::ISTLError,\"Rayleigh quotient iteration did not \"\n+ 561 << \"converge in \" << nIterationsMax_ << \" iterations \"\n+ 562 << \"(\u2551residual\u2551_2 = \" << r_norm << \", epsilon = \"\n+ 563 << epsilon << \").\");\n+ 564\n+ 565 // update iteration operator,\n+ 566 // update iteration matrix when needed\n+ 567 updateShiftMu(lambda,solver);\n+ 568\n+ 569 // do one iteration of the Rayleigh quotient iteration algorithm,\n+ 570 // part 1: solve (m_ - lambda*I) * y = x for y\n+ 571 // (protect x from being changed)\n+ 572 temp = x;\n+ 573 solver.apply(y,temp,solver_statistics);\n+ 574\n+ 575 // get norm of y\n+ 576 y_norm = y.two_norm();\n+ 577\n+ 578 // compile time switch between accuracy and efficiency\n+ 579 if (avoidLinSolverCrime)\n+ 580 {\n+ 581 // get approximated eigenvalue lambda via the Rayleigh quotient\n+ 582 // (use that x_new = y / y_norm)\n+ 583 m_.mv(y,temp);\n+ 584 lambda = (y * temp) / (y_norm * y_norm);\n+ 585\n+ 586 // get norm of residual\n+ 587 // (use that x_new = y / y_norm, additionally use that temp = m_ * y)\n+ 588 temp.axpy(-lambda,y);\n+ 589 r_norm = temp.two_norm() / y_norm;\n+ 590 }\n+ 591 else\n+ 592 {\n+ 593 // get approximated eigenvalue lambda via the Rayleigh quotient\n+ 594 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)\n+ 595 lambda_update = (y * x) / (y_norm * y_norm);\n+ 596 lambda += lambda_update;\n+ 597\n+ 598 // get norm of residual\n+ 599 // (use that x_new = y / y_norm and use that (m_ - lambda_old*I) * y = x)\n+ 600 temp = x; temp.axpy(-lambda_update,y);\n+ 601 r_norm = temp.two_norm() / y_norm;\n+ 602 }\n+ 603\n+ 604 // do one iteration of the Rayleigh quotient iteration algorithm,\n+ 605 // part 2: update x\n+ 606 x = y;\n+ 607 x *= (1.0 / y_norm);\n+ 608\n+ 609 // print verbosity information\n+ 610 if (verbosity_level_ > 1)\n+ 611 std::cout << blank_ << std::left\n+ 612 << \"iteration \" << std::setw(3) << nIterations_\n+ 613 << \" (\u2551residual\u2551_2 = \" << std::setw(11) << r_norm\n+ 614 << \"): \u03bb = \" << lambda << std::endl\n+ 615 << std::resetiosflags(std::ios::left);\n+ 616 }\n+ 617\n+ 618 // print verbosity information\n+ 619 if (verbosity_level_ > 0)\n+ 620 {\n+ 621 std::cout << blank_ << \"Result (\"\n+ 622 << \"#iterations = \" << nIterations_ << \", \"\n+ 623 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 624 << \"\u03bb = \" << lambda << std::endl;\n+ 625 if (verbosity_level_ > 2)\n+ 626 {\n+ 627 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 628 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 629 }\n+ 630 }\n+ 631 }\n+ 632\n+ 689 template \n+691 inline void applyTLIMEIteration (const Real& gamma, const Real& eta,\n+ 692 const Real& epsilon,\n+ 693 ISTLLinearSolver& solver,\n+ 694 const Real& delta, const std::size_t& m,\n+ 695 bool& extrnl,\n+ 696 BlockVector& x, Real& lambda) const\n+ 697 {\n+ 698 // use same variable names as in [Szyld, 1988]\n+ 699 BlockVector& x_s = x;\n+ 700 Real& mu_s = lambda;\n+ 701\n+ 702 // print verbosity information\n+ 703 if (verbosity_level_ > 0)\n+ 704 std::cout << title_\n+ 705 << \"Performing TLIME iteration for \"\n+ 706 << \"estimated eigenvalue in the \"\n+ 707 << \"interval (\" << gamma - eta << \",\"\n+ 708 << gamma + eta << \").\" << std::endl;\n+ 709\n+ 710 // allocate memory for linear solver statistics\n+ 711 Dune::InverseOperatorResult solver_statistics;\n+ 712\n+ 713 // allocate memory for auxiliary variables\n+ 714 bool doRQI;\n+ 715 Real mu;\n+ 716 BlockVector y(x_s);\n+ 717 Real omega;\n+ 718 Real mu_s_old;\n+ 719 Real mu_s_update;\n+ 720 BlockVector temp(x_s);\n+ 721 Real q_norm, r_norm;\n+ 722\n+ 723 // perform TLIME iteration\n+ 724 x_s *= (1.0 / x_s.two_norm());\n+ 725 extrnl = true;\n+ 726 doRQI = false;\n+ 727 r_norm = std::numeric_limits::max();\n+ 728 nIterations_ = 0;\n+ 729 while (r_norm > epsilon)\n+ 730 {\n+ 731 // update and check number of iterations\n+ 732 if (++nIterations_ > nIterationsMax_)\n+ 733 DUNE_THROW(Dune::ISTLError,\"TLIME iteration did not \"\n+ 734 << \"converge in \" << nIterationsMax_\n+ 735 << \" iterations (\u2551residual\u2551_2 = \" << r_norm\n+ 736 << \", epsilon = \" << epsilon << \").\");\n+ 737\n+ 738 // set shift for next iteration according to inverse iteration\n+ 739 // with shift (II) resp. Rayleigh quotient iteration (RQI)\n+ 740 if (doRQI)\n+ 741 mu = mu_s;\n+ 742 else\n+ 743 mu = gamma;\n+ 744\n+ 745 // update II/RQI iteration operator,\n+ 746 // update II/RQI iteration matrix when needed\n+ 747 updateShiftMu(mu,solver);\n+ 748\n+ 749 // do one iteration of the II/RQI algorithm,\n+ 750 // part 1: solve (m_ - mu*I) * y = x for y\n+ 751 temp = x_s;\n+ 752 solver.apply(y,temp,solver_statistics);\n+ 753\n+ 754 // do one iteration of the II/RQI algorithm,\n+ 755 // part 2: compute omega\n+ 756 omega = (1.0 / y.two_norm());\n+ 757\n+ 758 // backup the old Rayleigh quotient\n+ 759 mu_s_old = mu_s;\n+ 760\n+ 761 // compile time switch between accuracy and efficiency\n+ 762 if (avoidLinSolverCrime)\n+ 763 {\n+ 764 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue\n+ 765 // (use that x_new = y * omega)\n+ 766 m_.mv(y,temp);\n+ 767 mu_s = (y * temp) * (omega * omega);\n+ 768\n+ 769 // get norm of \"the residual with respect to the shift used by II\",\n+ 770 // use normal representation of q\n+ 771 // (use that x_new = y * omega, use that temp = m_ * y)\n+ 772 temp.axpy(-gamma,y);\n+ 773 q_norm = temp.two_norm() * omega;\n+ 774\n+ 775 // get norm of \"the residual with respect to the Rayleigh quotient\"\n+ 776 r_norm = q_norm*q_norm - (gamma-mu_s)*(gamma-mu_s);\n+ 777 // prevent that truncation errors invalidate the norm\n+ 778 // (we don't want to calculate sqrt of a negative number)\n+ 779 if (r_norm >= 0)\n+ 780 {\n+ 781 // use relation between the norms of r and q for efficiency\n+ 782 r_norm = std::sqrt(r_norm);\n+ 783 }\n+ 784 else\n+ 785 {\n+ 786 // use relation between r and q\n+ 787 // (use that x_new = y * omega, use that temp = (m_ - gamma*I) * y = q /\n+omega)\n+ 788 temp.axpy(gamma-mu_s,y);\n+ 789 r_norm = temp.two_norm() * omega;\n+ 790 }\n+ 791 }\n+ 792 else\n+ 793 {\n+ 794 // update the Rayleigh quotient mu_s, i.e. the approximated eigenvalue\n+ 795 if (!doRQI)\n+ 796 {\n+ 797 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y =\n+x_s)\n+ 798 mu_s = gamma + (y * x_s) * (omega * omega);\n+ 799 }\n+ 800 else\n+ 801 {\n+ 802 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) *\n+y = x_s)\n+ 803 mu_s_update = (y * x_s) * (omega * omega);\n+ 804 mu_s += mu_s_update;\n+ 805 }\n+ 806\n+ 807 // get norm of \"the residual with respect to the shift used by II\"\n+ 808 if (!doRQI)\n+ 809 {\n+ 810 // use special representation of q in the II case\n+ 811 // (use that x_new = y * omega, additionally use that (m_ - gamma*I) * y =\n+x_s)\n+ 812 q_norm = omega;\n+ 813 }\n+ 814 else\n+ 815 {\n+ 816 // use special representation of q in the RQI case\n+ 817 // (use that x_new = y * omega, additionally use that (m_ - mu_s_old*I) *\n+y = x_s)\n+ 818 temp = x_s; temp.axpy(mu_s-gamma,y);\n+ 819 q_norm = temp.two_norm() * omega;\n+ 820 }\n+ 821\n+ 822 // get norm of \"the residual with respect to the Rayleigh quotient\"\n+ 823 // don't use efficient relation between the norms of r and q, as\n+ 824 // this relation seems to yield a less accurate r_norm in the case\n+ 825 // where linear solver crime is admitted\n+ 826 if (!doRQI)\n+ 827 {\n+ 828 // (use that x_new = y * omega and use that (m_ - gamma*I) * y = x_s)\n+ 829 temp = x_s; temp.axpy(gamma-lambda,y);\n+ 830 r_norm = temp.two_norm() * omega;\n+ 831 }\n+ 832 else\n+ 833 {\n+ 834 // (use that x_new = y * omega and use that (m_ - mu_s_old*I) * y = x_s)\n+ 835 temp = x_s; temp.axpy(-mu_s_update,y);\n+ 836 r_norm = temp.two_norm() * omega;\n+ 837 }\n+ 838 }\n+ 839\n+ 840 // do one iteration of the II/RQI algorithm,\n+ 841 // part 3: update x\n+ 842 x_s = y; x_s *= omega;\n+ 843\n+ 844 // // for relative residual norm mode, scale with mu_s^{-1}\n+ 845 // r_norm /= std::abs(mu_s);\n+ 846\n+ 847 // print verbosity information\n+ 848 if (verbosity_level_ > 1)\n+ 849 std::cout << blank_ << \"iteration \"\n+ 850 << std::left << std::setw(3) << nIterations_\n+ 851 << \" (\" << (doRQI ? \"RQI,\" : \"II, \")\n+ 852 << \" \" << (doRQI ? \"\u2014>\" : \" \") << \" \"\n+ 853 << \"\u2551r\u2551_2 = \" << std::setw(11) << r_norm\n+ 854 << \", \" << (doRQI ? \" \" : \"\u2014>\") << \" \"\n+ 855 << \"\u2551q\u2551_2 = \" << std::setw(11) << q_norm\n+ 856 << \"): \u03bb = \" << lambda << std::endl\n+ 857 << std::resetiosflags(std::ios::left);\n+ 858\n+ 859 // check if the eigenvalue closest to gamma lies in J\n+ 860 if (!doRQI && q_norm < eta)\n+ 861 {\n+ 862 // J is not free of eigenvalues\n+ 863 extrnl = false;\n+ 864\n+ 865 // by theory we know now that mu_s also lies in J\n+ 866 assert(std::abs(mu_s-gamma) < eta);\n+ 867\n+ 868 // switch to RQI\n+ 869 doRQI = true;\n+ 870 }\n+ 871\n+ 872 // revert to II if J is not free of eigenvalues but\n+ 873 // at some point mu_s falls back again outside J\n+ 874 if (!extrnl && doRQI && std::abs(mu_s-gamma) >= eta)\n+ 875 doRQI = false;\n+ 876\n+ 877 // if eigenvalue closest to gamma does not lie in J use RQI\n+ 878 // solely to accelerate the convergence to this eigenvalue\n+ 879 // when II has become stationary\n+ 880 if (extrnl && !doRQI)\n+ 881 {\n+ 882 // switch to RQI if the relative change of the Rayleigh\n+ 883 // quotient indicates that II has become stationary\n+ 884 if (nIterations_ >= m &&\n+ 885 std::abs(mu_s - mu_s_old) / std::abs(mu_s) < delta)\n+ 886 doRQI = true;\n+ 887 }\n+ 888 }\n+ 889\n+ 890 // // compute final residual and lambda again (paranoia....)\n+ 891 // m_.mv(x_s,temp);\n+ 892 // mu_s = x_s * temp;\n+ 893 // temp.axpy(-mu_s,x_s);\n+ 894 // r_norm = temp.two_norm();\n+ 895 // // r_norm /= std::abs(mu_s);\n+ 896\n+ 897 // print verbosity information\n+ 898 if (verbosity_level_ > 0)\n+ 899 {\n+ 900 if (extrnl)\n+ 901 std::cout << blank_ << \"Interval \"\n+ 902 << \"(\" << gamma - eta << \",\" << gamma + eta\n+ 903 << \") is free of eigenvalues, approximating \"\n+ 904 << \"the closest eigenvalue.\" << std::endl;\n+ 905 std::cout << blank_ << \"Result (\"\n+ 906 << \"#iterations = \" << nIterations_ << \", \"\n+ 907 << \"\u2551residual\u2551_2 = \" << r_norm << \"): \"\n+ 908 << \"\u03bb = \" << lambda << std::endl;\n+ 909 if (verbosity_level_ > 2)\n+ 910 {\n+ 911 // print approximated eigenvector via DUNE-ISTL I/O methods\n+ 912 Dune::printvector(std::cout,x,blank_+\"x\",blank_+\"row\");\n+ 913 }\n+ 914 }\n+ 915 }\n+ 916\n+925 inline IterationOperator& getIterationOperator ()\n+ 926 {\n+ 927 // return iteration operator\n+ 928 return itOperator_;\n+ 929 }\n+ 930\n+945 inline const BCRSMatrix& getIterationMatrix () const\n+ 946 {\n+ 947 // create iteration matrix on demand\n+ 948 if (!itMatrix_)\n+ 949 itMatrix_ = std::make_unique(m_);\n+ 950\n+ 951 // return iteration matrix\n+ 952 return *itMatrix_;\n+ 953 }\n+ 954\n+959 inline unsigned int getIterationCount () const\n+ 960 {\n+ 961 if (nIterations_ == 0)\n+ 962 DUNE_THROW(Dune::ISTLError,\"No algorithm applied, yet.\");\n+ 963\n+ 964 return nIterations_;\n+ 965 }\n+ 966\n+ 967 protected:\n+ 982 template \n+983 inline void updateShiftMu (const Real& mu,\n+ 984 ISTLLinearSolver& solver) const\n+ 985 {\n+ 986 // do nothing if new shift equals the old one\n+ 987 if (mu == mu_) return;\n+ 988\n+ 989 // update shift mu_, i.e. update iteration operator\n+ 990 mu_ = mu;\n+ 991\n+ 992 // update iteration matrix when needed\n+ 993 if (itMatrix_)\n+ 994 {\n+ 995 // iterate over entries in iteration matrix diagonal\n+ 996 constexpr int rowBlockSize = BCRSMatrix::block_type::rows;\n+ 997 constexpr int colBlockSize = BCRSMatrix::block_type::cols;\n+ 998 for (typename BCRSMatrix::size_type i = 0;\n+ 999 i < itMatrix_->M()*rowBlockSize; ++i)\n+ 1000 {\n+ 1001 // access m_[i,i] where i is the flat index of a row/column\n+ 1002 const Real& m_entry = m_\n+ 1003 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];\n+ 1004 // access *itMatrix[i,i] where i is the flat index of a row/column\n+ 1005 Real& entry = (*itMatrix_)\n+ 1006 [i/rowBlockSize][i/colBlockSize][i%rowBlockSize][i%colBlockSize];\n+ 1007 // change current entry in iteration matrix diagonal\n+ 1008 entry = m_entry - mu_;\n+ 1009 }\n+ 1010 // notify linear solver about change of the iteration matrix object\n+ 1011 SolverHelper::setMatrix\n+ 1012 (solver,*itMatrix_);\n+ 1013 }\n+ 1014 }\n+ 1015\n+ 1016 protected:\n+ 1017 // parameters related to iterative eigenvalue algorithms\n+1018 const BCRSMatrix& m_;\n+1019 const unsigned int nIterationsMax_;\n+ 1020\n+ 1021 // verbosity setting\n+1022 const unsigned int verbosity_level_;\n+ 1023\n+ 1024 // shift mu_ used by iteration operator/matrix (m_ - mu_*I)\n+1025 mutable Real mu_;\n+ 1026\n+ 1027 // iteration operator (m_ - mu_*I), passing shift mu_ by reference\n+1028 const MatrixOperator matrixOperator_;\n+1029 const ScalingOperator scalingOperator_;\n+1030 OperatorSum itOperator_;\n+ 1031\n+ 1032 // iteration matrix (m_ - mu_*I), provided on demand when needed\n+ 1033 // (e.g. for preconditioning)\n+1034 mutable std::unique_ptr itMatrix_;\n+ 1035\n+ 1036 // memory for storing temporary variables (mutable as they shall\n+ 1037 // just be effectless auxiliary variables of the const apply*(...)\n+ 1038 // methods)\n+1039 mutable unsigned int nIterations_;\n+ 1040\n+ 1041 // constants for printing verbosity information\n+1042 const std::string title_;\n+1043 const std::string blank_;\n+ 1044 };\n+ 1045\n+ 1048} // namespace Dune\n+ 1049\n+ 1050#endif // DUNE_ISTL_EIGENVALUE_POWERITERATION_HH\n+io.hh\n+Some generic functions for pretty printing vectors and matrices.\n+solvertype.hh\n+Templates characterizing the type of a solver.\n+operators.hh\n+Define general, extensible interface for operators. The available\n+implementation wraps a matrix.\n+istlexception.hh\n+solvers.hh\n+Implementations of the inverse operator interface.\n+blocklevel.hh\n+Helper functions for determining the vector/matrix block level.\n+solvercategory.hh\n+Dune::printvector\n+void printvector(std::ostream &s, const V &v, std::string title, std::string\n+rowtext, int columns=1, int width=10, int precision=2)\n+Print an ISTL vector.\n+Definition: io.hh:89\n Dune\n Definition: allocator.hh:11\n-Dune::ILU::blockILUBacksolve\n-void blockILUBacksolve(const M &A, X &v, const Y &d)\n-LU backsolve with stored inverse.\n-Definition: ilu.hh:94\n-Dune::ILU::blockILU0Decomposition\n-void blockILU0Decomposition(M &A)\n-compute ILU decomposition of A. A is overwritten by its decomposition\n-Definition: ilu.hh:33\n-Dune::ILU::blockILUDecomposition\n-void blockILUDecomposition(const M &A, int n, M &ILU)\n-Definition: ilu.hh:167\n-Dune::ILUSubdomainSolver\n-base class encapsulating common algorithms of ILU0SubdomainSolver and\n-ILUNSubdomainSolver.\n-Definition: ilusubdomainsolver.hh:36\n-Dune::ILUSubdomainSolver::ILU\n-matrix_type ILU\n-The ILU0 decomposition of the matrix, or the local matrix.\n-Definition: ilusubdomainsolver.hh:67\n-Dune::ILUSubdomainSolver::domain_type\n+Dune::BCRSMatrix\n+A sparse block matrix with compressed row storage.\n+Definition: bcrsmatrix.hh:466\n+Dune::BCRSMatrix::size_type\n+A::size_type size_type\n+The type for the index access and the size.\n+Definition: bcrsmatrix.hh:500\n+Dune::BCRSMatrix::M\n+size_type M() const\n+number of columns (counted in blocks)\n+Definition: bcrsmatrix.hh:1978\n+Dune::BCRSMatrix::mv\n+void mv(const X &x, Y &y) const\n+y = A x\n+Definition: bcrsmatrix.hh:1612\n+Dune::BCRSMatrix::N\n+size_type N() const\n+number of rows (counted in blocks)\n+Definition: bcrsmatrix.hh:1972\n+Dune::BlockVector\n+A vector of blocks with memory management.\n+Definition: bvector.hh:395\n+Dune::BlockVector::field_type\n+typename Imp::BlockTraits< B >::field_type field_type\n+export the type representing the field\n+Definition: bvector.hh:401\n+Dune::PowerIteration_Algorithms\n+Iterative eigenvalue algorithms based on power iteration.\n+Definition: poweriteration.hh:176\n+Dune::PowerIteration_Algorithms::itMatrix_\n+std::unique_ptr< BCRSMatrix > itMatrix_\n+Definition: poweriteration.hh:1034\n+Dune::PowerIteration_Algorithms::PowerIteration_Algorithms\n+PowerIteration_Algorithms(const PowerIteration_Algorithms &)=delete\n+Dune::PowerIteration_Algorithms::ScalingOperator\n+Impl::ScalingLinearOperator< BlockVector > ScalingOperator\n+Definition: poweriteration.hh:181\n+Dune::PowerIteration_Algorithms::blank_\n+const std::string blank_\n+Definition: poweriteration.hh:1043\n+Dune::PowerIteration_Algorithms::OperatorSum\n+Impl::LinearOperatorSum< MatrixOperator, ScalingOperator > OperatorSum\n+Definition: poweriteration.hh:182\n+Dune::PowerIteration_Algorithms::MatrixOperator\n+Dune::MatrixAdapter< BCRSMatrix, BlockVector, BlockVector > MatrixOperator\n+Definition: poweriteration.hh:180\n+Dune::PowerIteration_Algorithms::applyInverseIteration\n+void applyInverseIteration(const Real &epsilon, ISTLLinearSolver &solver,\n+BlockVector &x, Real &lambda) const\n+Perform the inverse iteration algorithm to compute an approximation lambda of\n+the least dominant (i....\n+Definition: poweriteration.hh:355\n+Dune::PowerIteration_Algorithms::applyTLIMEIteration\n+void applyTLIMEIteration(const Real &gamma, const Real &eta, const Real\n+&epsilon, ISTLLinearSolver &solver, const Real &delta, const std::size_t &m,\n+bool &extrnl, BlockVector &x, Real &lambda) const\n+Perform the \"two-level iterative method for eigenvalue calculations (TLIME)\"\n+iteration algorit...\n+Definition: poweriteration.hh:691\n+Dune::PowerIteration_Algorithms::getIterationOperator\n+IterationOperator & getIterationOperator()\n+Return the iteration operator (m_ - mu_*I).\n+Definition: poweriteration.hh:925\n+Dune::PowerIteration_Algorithms::itOperator_\n+OperatorSum itOperator_\n+Definition: poweriteration.hh:1030\n+Dune::PowerIteration_Algorithms::m_\n+const BCRSMatrix & m_\n+Definition: poweriteration.hh:1018\n+Dune::PowerIteration_Algorithms::PowerIteration_Algorithms\n+PowerIteration_Algorithms(const BCRSMatrix &m, const unsigned int\n+nIterationsMax=1000, const unsigned int verbosity_level=0)\n+Construct from required parameters.\n+Definition: poweriteration.hh:206\n+Dune::PowerIteration_Algorithms::nIterationsMax_\n+const unsigned int nIterationsMax_\n+Definition: poweriteration.hh:1019\n+Dune::PowerIteration_Algorithms::applyPowerIteration\n+void applyPowerIteration(const Real &epsilon, BlockVector &x, Real &lambda)\n+const\n+Perform the power iteration algorithm to compute an approximation lambda of the\n+dominant (i....\n+Definition: poweriteration.hh:260\n+Dune::PowerIteration_Algorithms::IterationOperator\n+OperatorSum IterationOperator\n+Type of iteration operator (m_ - mu_*I)\n+Definition: poweriteration.hh:189\n+Dune::PowerIteration_Algorithms::applyRayleighQuotientIteration\n+void applyRayleighQuotientIteration(const Real &epsilon, ISTLLinearSolver\n+&solver, BlockVector &x, Real &lambda) const\n+Perform the Rayleigh quotient iteration algorithm to compute an approximation\n+lambda of an eigenvalue...\n+Definition: poweriteration.hh:533\n+Dune::PowerIteration_Algorithms::applyInverseIteration\n+void applyInverseIteration(const Real &gamma, const Real &epsilon,\n+ISTLLinearSolver &solver, BlockVector &x, Real &lambda) const\n+Perform the inverse iteration with shift algorithm to compute an approximation\n+lambda of the eigenval...\n+Definition: poweriteration.hh:394\n+Dune::PowerIteration_Algorithms::scalingOperator_\n+const ScalingOperator scalingOperator_\n+Definition: poweriteration.hh:1029\n+Dune::PowerIteration_Algorithms::updateShiftMu\n+void updateShiftMu(const Real &mu, ISTLLinearSolver &solver) const\n+Update shift mu_, i.e. update iteration operator/matrix (m_ - mu_*I).\n+Definition: poweriteration.hh:983\n+Dune::PowerIteration_Algorithms::operator=\n+PowerIteration_Algorithms & operator=(const PowerIteration_Algorithms &)=delete\n+Dune::PowerIteration_Algorithms::getIterationCount\n+unsigned int getIterationCount() const\n+Return the number of iterations in last application of an algorithm.\n+Definition: poweriteration.hh:959\n+Dune::PowerIteration_Algorithms::matrixOperator_\n+const MatrixOperator matrixOperator_\n+Definition: poweriteration.hh:1028\n+Dune::PowerIteration_Algorithms::getIterationMatrix\n+const BCRSMatrix & getIterationMatrix() const\n+Return the iteration matrix (m_ - mu_*I), provided on demand when needed (e.g.\n+for direct solvers or ...\n+Definition: poweriteration.hh:945\n+Dune::PowerIteration_Algorithms::nIterations_\n+unsigned int nIterations_\n+Definition: poweriteration.hh:1039\n+Dune::PowerIteration_Algorithms::verbosity_level_\n+const unsigned int verbosity_level_\n+Definition: poweriteration.hh:1022\n+Dune::PowerIteration_Algorithms::title_\n+const std::string title_\n+Definition: poweriteration.hh:1042\n+Dune::PowerIteration_Algorithms::Real\n+BlockVector::field_type Real\n+Type of underlying field.\n+Definition: poweriteration.hh:186\n+Dune::PowerIteration_Algorithms::mu_\n+Real mu_\n+Definition: poweriteration.hh:1025\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n+Dune::LinearOperator\n+A linear operator.\n+Definition: operators.hh:67\n+Dune::LinearOperator<_X,_X_>::field_type\n+X::field_type field_type\n+The field type of the operator.\n+Definition: operators.hh:74\n+Dune::LinearOperator<_X,_X_>::applyscaleadd\n+virtual void applyscaleadd(field_type alpha, const X &x, X &y) const=0\n+apply operator to x, scale and add:\n+Dune::LinearOperator<_X,_X_>::category\n+virtual SolverCategory::Category category() const=0\n+Category of the linear operator (see SolverCategory::Category)\n+Dune::LinearOperator<_X,_X_>::range_type\n+X range_type\n+The type of the range of the operator.\n+Definition: operators.hh:72\n+Dune::LinearOperator<_X,_X_>::apply\n+virtual void apply(const X &x, X &y) const=0\n+apply operator to x: The input vector is consistent and the output must also be\n+consistent on the in...\n+Dune::LinearOperator<_X,_X_>::domain_type\n X domain_type\n-The domain type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:41\n-Dune::ILUSubdomainSolver::~ILUSubdomainSolver\n-virtual ~ILUSubdomainSolver()\n-Definition: ilusubdomainsolver.hh:53\n-Dune::ILUSubdomainSolver::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:43\n-Dune::ILUSubdomainSolver::matrix_type\n-std::remove_const< M >::type matrix_type\n-The matrix type the preconditioner is for.\n-Definition: ilusubdomainsolver.hh:39\n-Dune::ILUSubdomainSolver::apply\n-virtual void apply(X &v, const Y &d)=0\n-Apply the subdomain solver.\n-Dune::ILU0SubdomainSolver\n-Exact subdomain solver using ILU(p) with appropriate p.\n-Definition: ilusubdomainsolver.hh:78\n-Dune::ILU0SubdomainSolver::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:84\n-Dune::ILU0SubdomainSolver::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:86\n-Dune::ILU0SubdomainSolver::rilu_type\n-std::remove_const< M >::type rilu_type\n-Definition: ilusubdomainsolver.hh:82\n-Dune::ILU0SubdomainSolver::matrix_type\n-std::remove_const< M >::type matrix_type\n-The matrix type the preconditioner is for.\n-Definition: ilusubdomainsolver.hh:81\n-Dune::ILU0SubdomainSolver::apply\n-void apply(X &v, const Y &d)\n-Apply the subdomain solver.\n-Definition: ilusubdomainsolver.hh:93\n-Dune::ILUNSubdomainSolver\n-Definition: ilusubdomainsolver.hh:111\n-Dune::ILUNSubdomainSolver::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:117\n-Dune::ILUNSubdomainSolver::matrix_type\n-std::remove_const< M >::type matrix_type\n-The matrix type the preconditioner is for.\n-Definition: ilusubdomainsolver.hh:114\n-Dune::ILUNSubdomainSolver::rilu_type\n-std::remove_const< M >::type rilu_type\n-Definition: ilusubdomainsolver.hh:115\n-Dune::ILUNSubdomainSolver::apply\n-void apply(X &v, const Y &d)\n-Apply the subdomain solver.\n-Definition: ilusubdomainsolver.hh:125\n-Dune::ILUNSubdomainSolver::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: ilusubdomainsolver.hh:119\n+The type of the domain of the operator.\n+Definition: operators.hh:70\n+Dune::MatrixAdapter\n+Adapter to turn a matrix into a linear operator.\n+Definition: operators.hh:137\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::SolverHelper::setMatrix\n+static void setMatrix(ISTLLinearSolver &solver, const BCRSMatrix &matrix)\n+Definition: solver.hh:524\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00206.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00206.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: superlu.hh File Reference\n+dune-istl: matrixindexset.hh File Reference\n \n \n \n \n \n \n \n@@ -64,81 +64,34 @@\n \n \n \n \n+
    matrixindexset.hh File Reference
    \n \n
    \n-\n-

    Classes for using SuperLU with ISTL matrices. \n-More...

    \n-
    #include "superlufunctions.hh"
    \n-#include "solvers.hh"
    \n-#include "supermatrix.hh"
    \n-#include <algorithm>
    \n-#include <functional>
    \n-#include "bcrsmatrix.hh"
    \n-#include "bvector.hh"
    \n-#include "istlexception.hh"
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/stdstreams.hh>
    \n-#include <dune/istl/solvertype.hh>
    \n-#include <dune/istl/solverfactory.hh>
    \n+
    #include <vector>
    \n+#include <set>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    struct  Dune::SuperLUSolveChooser< T >
     
    struct  Dune::SuperLUDenseMatChooser< T >
     
    struct  Dune::SuperLUQueryChooser< T >
     
    struct  Dune::QuerySpaceChooser< T >
     
    class  Dune::SuperLU< M >
     SuperLu Solver. More...
     
    struct  Dune::IsDirectSolver< SuperLU< BCRSMatrix< T, A > > >
     
    struct  Dune::StoresColumnCompressed< SuperLU< BCRSMatrix< T, A > > >
     
    struct  Dune::SuperLUCreator
     
    struct  Dune::SuperLUCreator::isValidBlock< class >
     
    struct  Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< double, k > >
     
    struct  Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< std::complex< double >, k > >
     
    struct  Dune::SuperLUCreator::isValidBlock< double >
     
    struct  Dune::SuperLUCreator::isValidBlock< std::complex< double > >
    class  Dune::MatrixIndexSet
     Stores the nonzero entries in a sparse matrix. More...
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n

    \n-Functions

     Dune::DUNE_REGISTER_DIRECT_SOLVER ("superlu", SuperLUCreator())
     
    \n-

    Detailed Description

    \n-

    Classes for using SuperLU with ISTL matrices.

    \n-
    Author
    Markus Blatt
    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,67 +4,22 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-superlu.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL)\n-Classes for using SuperLU with ISTL matrices. More...\n-#include \"superlufunctions.hh\"\n-#include \"solvers.hh\"\n-#include \"supermatrix.hh\"\n-#include \n-#include \n-#include \"bcrsmatrix.hh\"\n-#include \"bvector.hh\"\n-#include \"istlexception.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n+Classes | Namespaces\n+matrixindexset.hh File Reference\n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::SuperLUSolveChooser<_T_>\n-\u00a0\n-struct \u00a0Dune::SuperLUDenseMatChooser<_T_>\n-\u00a0\n-struct \u00a0Dune::SuperLUQueryChooser<_T_>\n-\u00a0\n-struct \u00a0Dune::QuerySpaceChooser<_T_>\n-\u00a0\n- class \u00a0Dune::SuperLU<_M_>\n-\u00a0 SuperLu Solver. More...\n-\u00a0\n-struct \u00a0Dune::IsDirectSolver<_SuperLU<_BCRSMatrix<_T,_A_>_>_>\n-\u00a0\n-struct \u00a0Dune::StoresColumnCompressed<_SuperLU<_BCRSMatrix<_T,_A_>_>_>\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator::isValidBlock<_class_>\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator::isValidBlock<_Dune::FieldVector<_double,_k_>_>\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator::isValidBlock<_Dune::FieldVector<_std::complex<\n- double_>,_k_>_>\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator::isValidBlock<_double_>\n-\u00a0\n-struct \u00a0Dune::SuperLUCreator::isValidBlock<_std::complex<_double_>_>\n+class \u00a0Dune::MatrixIndexSet\n+\u00a0 Stores the nonzero entries in a sparse matrix. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Functions\n-\u00a0Dune::DUNE_REGISTER_DIRECT_SOLVER (\"superlu\", SuperLUCreator())\n-\u00a0\n-***** Detailed Description *****\n-Classes for using SuperLU with ISTL matrices.\n- Author\n- Markus Blatt\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00206_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00206_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: superlu.hh Source File\n+dune-istl: matrixindexset.hh Source File\n \n \n \n \n \n \n \n@@ -62,786 +62,132 @@\n \n
    \n \n
    \n \n
    \n-
    superlu.hh
    \n+
    matrixindexset.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_SUPERLU_HH
    \n-
    6#define DUNE_ISTL_SUPERLU_HH
    \n+
    5#ifndef DUNE_ISTL_MATRIXINDEXSET_HH
    \n+
    6#define DUNE_ISTL_MATRIXINDEXSET_HH
    \n
    7
    \n-
    8#if HAVE_SUPERLU
    \n-
    9
    \n-
    10#include "superlufunctions.hh"
    \n-
    11#include "solvers.hh"
    \n-
    12#include "supermatrix.hh"
    \n-
    13#include <algorithm>
    \n-
    14#include <functional>
    \n-
    15#include "bcrsmatrix.hh"
    \n-
    16#include "bvector.hh"
    \n-
    17#include "istlexception.hh"
    \n-
    18#include <dune/common/fmatrix.hh>
    \n-
    19#include <dune/common/fvector.hh>
    \n-
    20#include <dune/common/stdstreams.hh>
    \n-\n-\n-
    23
    \n-
    24namespace Dune
    \n-
    25{
    \n-
    26
    \n-
    37 template<class M, class T, class TM, class TD, class TA>
    \n-
    38 class SeqOverlappingSchwarz;
    \n-
    39
    \n-
    40 template<class T, bool tag>
    \n-
    41 struct SeqOverlappingSchwarzAssemblerHelper;
    \n-
    42
    \n-
    43 template<class T>
    \n-\n-
    45 {};
    \n-
    46
    \n-
    47 template<class T>
    \n-\n-
    49 {};
    \n+
    8#include <vector>
    \n+
    9#include <set>
    \n+
    10
    \n+
    11namespace Dune {
    \n+
    12
    \n+
    13
    \n+\n+
    16 {
    \n+
    17
    \n+
    18 public:
    \n+
    19 typedef std::size_t size_type;
    \n+
    20
    \n+
    22 MatrixIndexSet() : rows_(0), cols_(0)
    \n+
    23 {}
    \n+
    24
    \n+
    26 MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) {
    \n+
    27 indices_.resize(rows_);
    \n+
    28 }
    \n+
    29
    \n+\n+
    32 rows_ = rows;
    \n+
    33 cols_ = cols;
    \n+
    34 indices_.resize(rows_);
    \n+
    35 }
    \n+
    36
    \n+
    38 void add(size_type i, size_type j) {
    \n+
    39 indices_[i].insert(j);
    \n+
    40 }
    \n+
    41
    \n+
    43 size_type size() const {
    \n+
    44 size_type entries = 0;
    \n+
    45 for (size_type i=0; i<rows_; i++)
    \n+
    46 entries += indices_[i].size();
    \n+
    47
    \n+
    48 return entries;
    \n+
    49 }
    \n
    50
    \n-
    51 template<class T>
    \n-\n-
    53 {};
    \n+
    52 size_type rows() const {return rows_;}
    \n+
    53
    \n
    54
    \n-
    55 template<class T>
    \n-\n-
    57 {};
    \n-
    58
    \n-
    59#if __has_include("slu_sdefs.h")
    \n-
    60 template<>
    \n-
    61 struct SuperLUDenseMatChooser<float>
    \n-
    62 {
    \n-
    63 static void create(SuperMatrix *mat, int n, int m, float *dat, int n1,
    \n-
    64 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n-
    65 {
    \n-
    66 sCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
    \n-
    67
    \n-
    68 }
    \n+
    56 size_type rowsize(size_type row) const {return indices_[row].size();}
    \n+
    57
    \n+
    64 template <class MatrixType>
    \n+
    65 void import(const MatrixType& m, size_type rowOffset=0, size_type colOffset=0) {
    \n+
    66
    \n+
    67 typedef typename MatrixType::row_type RowType;
    \n+
    68 typedef typename RowType::ConstIterator ColumnIterator;
    \n
    69
    \n-
    70 static void destroy(SuperMatrix*)
    \n-
    71 {}
    \n-
    72
    \n-
    73 };
    \n-
    74 template<>
    \n-
    75 struct SuperLUSolveChooser<float>
    \n-
    76 {
    \n-
    77 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
    \n-
    78 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
    \n-
    79 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
    \n-
    80 float *rpg, float *rcond, float *ferr, float *berr,
    \n-
    81 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
    \n-
    82 {
    \n-
    83 GlobalLU_t gLU;
    \n-
    84 sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
    \n-
    85 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
    \n-
    86 &gLU, memusage, stat, info);
    \n-
    87 }
    \n-
    88 };
    \n-
    89
    \n-
    90 template<>
    \n-
    91 struct QuerySpaceChooser<float>
    \n-
    92 {
    \n-
    93 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
    \n-
    94 {
    \n-
    95 sQuerySpace(L,U,memusage);
    \n-
    96 }
    \n-
    97 };
    \n-
    98
    \n-
    99#endif
    \n-
    100
    \n-
    101#if __has_include("slu_ddefs.h")
    \n-
    102
    \n-
    103 template<>
    \n-
    104 struct SuperLUDenseMatChooser<double>
    \n-
    105 {
    \n-
    106 static void create(SuperMatrix *mat, int n, int m, double *dat, int n1,
    \n-
    107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n-
    108 {
    \n-
    109 dCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
    \n-
    110
    \n-
    111 }
    \n-
    112
    \n-
    113 static void destroy(SuperMatrix * /* mat */)
    \n-
    114 {}
    \n-
    115 };
    \n-
    116 template<>
    \n-
    117 struct SuperLUSolveChooser<double>
    \n-
    118 {
    \n-
    119 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
    \n-
    120 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
    \n-
    121 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
    \n-
    122 double *rpg, double *rcond, double *ferr, double *berr,
    \n-
    123 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
    \n-
    124 {
    \n-
    125 GlobalLU_t gLU;
    \n-
    126 dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
    \n-
    127 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
    \n-
    128 &gLU, memusage, stat, info);
    \n-
    129 }
    \n-
    130 };
    \n-
    131
    \n-
    132 template<>
    \n-
    133 struct QuerySpaceChooser<double>
    \n-
    134 {
    \n-
    135 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
    \n-
    136 {
    \n-
    137 dQuerySpace(L,U,memusage);
    \n-
    138 }
    \n-
    139 };
    \n-
    140#endif
    \n-
    141
    \n-
    142#if __has_include("slu_zdefs.h")
    \n-
    143 template<>
    \n-
    144 struct SuperLUDenseMatChooser<std::complex<double> >
    \n-
    145 {
    \n-
    146 static void create(SuperMatrix *mat, int n, int m, std::complex<double> *dat, int n1,
    \n-
    147 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n-
    148 {
    \n-
    149 zCreate_Dense_Matrix(mat, n, m, reinterpret_cast<doublecomplex*>(dat), n1, stype, dtype, mtype);
    \n-
    150
    \n-
    151 }
    \n-
    152
    \n-
    153 static void destroy(SuperMatrix*)
    \n-
    154 {}
    \n-
    155 };
    \n-
    156
    \n-
    157 template<>
    \n-
    158 struct SuperLUSolveChooser<std::complex<double> >
    \n-
    159 {
    \n-
    160 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
    \n-
    161 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
    \n-
    162 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
    \n-
    163 double *rpg, double *rcond, double *ferr, double *berr,
    \n-
    164 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
    \n-
    165 {
    \n-
    166 GlobalLU_t gLU;
    \n-
    167 zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
    \n-
    168 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
    \n-
    169 &gLU, memusage, stat, info);
    \n-
    170 }
    \n-
    171 };
    \n-
    172
    \n-
    173 template<>
    \n-
    174 struct QuerySpaceChooser<std::complex<double> >
    \n-
    175 {
    \n-
    176 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
    \n-
    177 {
    \n-
    178 zQuerySpace(L,U,memusage);
    \n-
    179 }
    \n-
    180 };
    \n-
    181#endif
    \n-
    182
    \n-
    183#if __has_include("slu_cdefs.h")
    \n-
    184 template<>
    \n-
    185 struct SuperLUDenseMatChooser<std::complex<float> >
    \n-
    186 {
    \n-
    187 static void create(SuperMatrix *mat, int n, int m, std::complex<float> *dat, int n1,
    \n-
    188 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
    \n-
    189 {
    \n-
    190 cCreate_Dense_Matrix(mat, n, m, reinterpret_cast< ::complex*>(dat), n1, stype, dtype, mtype);
    \n-
    191
    \n-
    192 }
    \n-
    193
    \n-
    194 static void destroy(SuperMatrix* /* mat */)
    \n-
    195 {}
    \n-
    196 };
    \n-
    197
    \n-
    198 template<>
    \n-
    199 struct SuperLUSolveChooser<std::complex<float> >
    \n-
    200 {
    \n-
    201 static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
    \n-
    202 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
    \n-
    203 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
    \n-
    204 float *rpg, float *rcond, float *ferr, float *berr,
    \n-
    205 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
    \n-
    206 {
    \n-
    207 GlobalLU_t gLU;
    \n-
    208 cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
    \n-
    209 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
    \n-
    210 &gLU, memusage, stat, info);
    \n-
    211 }
    \n-
    212 };
    \n-
    213
    \n-
    214 template<>
    \n-
    215 struct QuerySpaceChooser<std::complex<float> >
    \n-
    216 {
    \n-
    217 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
    \n-
    218 {
    \n-
    219 cQuerySpace(L,U,memusage);
    \n-
    220 }
    \n-
    221 };
    \n-
    222#endif
    \n-
    223
    \n-
    224 namespace Impl
    \n-
    225 {
    \n-
    226 template<class M>
    \n-
    227 struct SuperLUVectorChooser
    \n-
    228 {};
    \n-
    229
    \n-
    230 template<typename T, typename A, int n, int m>
    \n-
    231 struct SuperLUVectorChooser<BCRSMatrix<FieldMatrix<T,n,m>,A > >
    \n-
    232 {
    \n-
    234 using domain_type = BlockVector<
    \n-
    235 FieldVector<T,m>,
    \n-
    236 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,m> > >;
    \n-
    238 using range_type = BlockVector<
    \n-
    239 FieldVector<T,n>,
    \n-
    240 typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,n> > >;
    \n-
    241 };
    \n-
    242
    \n-
    243 template<typename T, typename A>
    \n-
    244 struct SuperLUVectorChooser<BCRSMatrix<T,A> >
    \n-
    245 {
    \n-
    247 using domain_type = BlockVector<T, A>;
    \n-
    249 using range_type = BlockVector<T, A>;
    \n-
    250 };
    \n-
    251 }
    \n-
    252
    \n-
    266 template<typename M>
    \n-\n-
    268 : public InverseOperator<
    \n-
    269 typename Impl::SuperLUVectorChooser<M>::domain_type,
    \n-
    270 typename Impl::SuperLUVectorChooser<M>::range_type >
    \n-
    271 {
    \n-
    272 using T = typename M::field_type;
    \n-
    273 public:
    \n-
    275 using Matrix = M;
    \n-
    276 using matrix_type = M;
    \n-\n-\n-
    282 using domain_type = typename Impl::SuperLUVectorChooser<M>::domain_type;
    \n-
    284 using range_type = typename Impl::SuperLUVectorChooser<M>::range_type;
    \n-
    285
    \n-\n-
    288 {
    \n-
    289 return SolverCategory::Category::sequential;
    \n-
    290 }
    \n-
    291
    \n-
    306 explicit SuperLU(const Matrix& mat, bool verbose=false,
    \n-
    307 bool reusevector=true);
    \n-
    308
    \n-
    309
    \n-
    320 SuperLU(const Matrix& mat, const ParameterTree& config)
    \n-
    321 : SuperLU(mat, config.get<bool>("verbose", false), config.get<bool>("reuseVector", true))
    \n-
    322 {}
    \n-
    323
    \n-
    330 SuperLU();
    \n-
    331
    \n-
    332 ~SuperLU();
    \n-
    333
    \n-\n-
    338
    \n-
    342 void apply (domain_type& x, range_type& b, [[maybe_unused]] double reduction, InverseOperatorResult& res)
    \n-
    343 {
    \n-
    344 apply(x,b,res);
    \n-
    345 }
    \n-
    346
    \n-
    350 void apply(T* x, T* b);
    \n-
    351
    \n-
    353 void setMatrix(const Matrix& mat);
    \n-
    354
    \n-
    355 typename SuperLUMatrix::size_type nnz() const
    \n-
    356 {
    \n-
    357 return mat.nonzeroes();
    \n-
    358 }
    \n-
    359
    \n-
    360 template<class S>
    \n-
    361 void setSubMatrix(const Matrix& mat, const S& rowIndexSet);
    \n-
    362
    \n-
    363 void setVerbosity(bool v);
    \n-
    364
    \n-
    369 void free();
    \n-
    370
    \n-
    371 const char* name() { return "SuperLU"; }
    \n-
    372 private:
    \n-
    373 template<class Mat,class X, class TM, class TD, class T1>
    \n-\n-\n-
    376
    \n-
    377 SuperLUMatrix& getInternalMatrix() { return mat; }
    \n-
    378
    \n-
    380 void decompose();
    \n-
    381
    \n-\n-
    383 SuperMatrix L, U, B, X;
    \n-
    384 int *perm_c, *perm_r, *etree;
    \n-
    385 typename GetSuperLUType<T>::float_type *R, *C;
    \n-
    386 T *bstore;
    \n-
    387 superlu_options_t options;
    \n-
    388 char equed;
    \n-
    389 void *work;
    \n-
    390 int lwork;
    \n-
    391 bool first, verbose, reusevector;
    \n-
    392 };
    \n-
    393
    \n-
    394 template<typename M>
    \n-\n-\n-
    397 {
    \n-
    398 if(mat.N()+mat.M()>0)
    \n-
    399 free();
    \n-
    400 }
    \n-
    401
    \n-
    402 template<typename M>
    \n-\n-
    404 {
    \n-
    405 delete[] perm_c;
    \n-
    406 delete[] perm_r;
    \n-
    407 delete[] etree;
    \n-
    408 delete[] R;
    \n-
    409 delete[] C;
    \n-
    410 if(lwork>=0) {
    \n-
    411 Destroy_SuperNode_Matrix(&L);
    \n-
    412 Destroy_CompCol_Matrix(&U);
    \n-
    413 }
    \n-
    414 lwork=0;
    \n-
    415 if(!first && reusevector) {
    \n-
    416 SUPERLU_FREE(B.Store);
    \n-
    417 SUPERLU_FREE(X.Store);
    \n-
    418 }
    \n-
    419 mat.free();
    \n-
    420 }
    \n-
    421
    \n-
    422 template<typename M>
    \n-\n-
    424 ::SuperLU(const Matrix& mat_, bool verbose_, bool reusevector_)
    \n-
    425 : work(0), lwork(0), first(true), verbose(verbose_),
    \n-
    426 reusevector(reusevector_)
    \n-
    427 {
    \n-
    428 setMatrix(mat_);
    \n-
    429
    \n-
    430 }
    \n-
    431 template<typename M>
    \n-\n-
    433 : work(0), lwork(0),verbose(false),
    \n-
    434 reusevector(false)
    \n-
    435 {}
    \n-
    436 template<typename M>
    \n-\n-
    438 {
    \n-
    439 verbose=v;
    \n-
    440 }
    \n-
    441
    \n-
    442 template<typename M>
    \n-\n-
    444 {
    \n-
    445 if(mat.N()+mat.M()>0) {
    \n-
    446 free();
    \n-
    447 }
    \n-
    448 lwork=0;
    \n-
    449 work=0;
    \n-
    450 //a=&mat_;
    \n-
    451 mat=mat_;
    \n-
    452 decompose();
    \n-
    453 }
    \n-
    454
    \n-
    455 template<typename M>
    \n-
    456 template<class S>
    \n-\n-
    458 const S& mrs)
    \n-
    459 {
    \n-
    460 if(mat.N()+mat.M()>0) {
    \n-
    461 free();
    \n-
    462 }
    \n-
    463 lwork=0;
    \n-
    464 work=0;
    \n-
    465 //a=&mat_;
    \n-
    466 mat.setMatrix(mat_,mrs);
    \n-
    467 decompose();
    \n-
    468 }
    \n-
    469
    \n-
    470 template<typename M>
    \n-\n-
    472 {
    \n-
    473
    \n-
    474 first = true;
    \n-
    475 perm_c = new int[mat.M()];
    \n-
    476 perm_r = new int[mat.N()];
    \n-
    477 etree = new int[mat.M()];
    \n-
    478 R = new typename GetSuperLUType<T>::float_type[mat.N()];
    \n-
    479 C = new typename GetSuperLUType<T>::float_type[mat.M()];
    \n-
    480
    \n-
    481 set_default_options(&options);
    \n-
    482 // Do the factorization
    \n-
    483 B.ncol=0;
    \n-
    484 B.Stype=SLU_DN;
    \n-\n-
    486 B.Mtype= SLU_GE;
    \n-
    487 DNformat fakeFormat;
    \n-
    488 fakeFormat.lda=mat.N();
    \n-
    489 B.Store=&fakeFormat;
    \n-
    490 X.Stype=SLU_DN;
    \n-\n-
    492 X.Mtype= SLU_GE;
    \n-
    493 X.ncol=0;
    \n-
    494 X.Store=&fakeFormat;
    \n-
    495
    \n-
    496 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr=1e10;
    \n-
    497 int info;
    \n-
    498 mem_usage_t memusage;
    \n-
    499 SuperLUStat_t stat;
    \n-
    500
    \n-
    501 StatInit(&stat);
    \n-
    502 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
    \n-
    503 &L, &U, work, lwork, &B, &X, &rpg, &rcond, &ferr,
    \n-
    504 &berr, &memusage, &stat, &info);
    \n-
    505
    \n-
    506 if(verbose) {
    \n-
    507 dinfo<<"LU factorization: dgssvx() returns info "<< info<<std::endl;
    \n-
    508
    \n-
    509 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
    \n-
    510
    \n-
    511 if ( info == 0 || info == nSuperLUCol+1 ) {
    \n-
    512
    \n-
    513 if ( options.PivotGrowth )
    \n-
    514 dinfo<<"Recip. pivot growth = "<<rpg<<std::endl;
    \n-
    515 if ( options.ConditionNumber )
    \n-
    516 dinfo<<"Recip. condition number = %e\\n"<< rcond<<std::endl;
    \n-
    517 SCformat* Lstore = (SCformat *) L.Store;
    \n-
    518 NCformat* Ustore = (NCformat *) U.Store;
    \n-
    519 dinfo<<"No of nonzeros in factor L = "<< Lstore->nnz<<std::endl;
    \n-
    520 dinfo<<"No of nonzeros in factor U = "<< Ustore->nnz<<std::endl;
    \n-
    521 dinfo<<"No of nonzeros in L+U = "<< Lstore->nnz + Ustore->nnz - nSuperLUCol<<std::endl;
    \n-
    522 QuerySpaceChooser<T>::querySpace(&L, &U, &memusage);
    \n-
    523 dinfo<<"L\\\\U MB "<<memusage.for_lu/1e6<<" \\ttotal MB needed "<<memusage.total_needed/1e6
    \n-
    524 <<" \\texpansions ";
    \n-
    525 std::cout<<stat.expansions<<std::endl;
    \n-
    526
    \n-
    527 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
    \n-
    528 dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<std::endl;
    \n-
    529 }
    \n-
    530 if ( options.PrintStat ) StatPrint(&stat);
    \n-
    531 }
    \n-
    532 StatFree(&stat);
    \n-
    533 /*
    \n-
    534 NCformat* Ustore = (NCformat *) U.Store;
    \n-
    535 int k=0;
    \n-
    536 dPrint_CompCol_Matrix("U", &U);
    \n-
    537 for(int i=0; i < U.ncol; ++i, ++k){
    \n-
    538 std::cout<<i<<": ";
    \n-
    539 for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
    \n-
    540 //if(Ustore->rowind[c]==i)
    \n-
    541 std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
    \n-
    542 if(k==0){
    \n-
    543 //
    \n-
    544 k=-1;
    \n-
    545 }std::cout<<std::endl;
    \n-
    546 }
    \n-
    547 dPrint_SuperNode_Matrix("L", &L);
    \n-
    548 for(int i=0; i < U.ncol; ++i, ++k){
    \n-
    549 std::cout<<i<<": ";
    \n-
    550 for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
    \n-
    551 //if(Ustore->rowind[c]==i)
    \n-
    552 std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
    \n-
    553 if(k==0){
    \n-
    554 //
    \n-
    555 k=-1;
    \n-
    556 }std::cout<<std::endl;
    \n-
    557 } */
    \n-
    558 options.Fact = FACTORED;
    \n-
    559 }
    \n-
    560
    \n-
    561 template<typename M>
    \n-
    562 void SuperLU<M>
    \n-\n-
    564 {
    \n-
    565 if (mat.N() != b.dim())
    \n-
    566 DUNE_THROW(ISTLError, "Size of right-hand-side vector b does not match the number of matrix rows!");
    \n-
    567 if (mat.M() != x.dim())
    \n-
    568 DUNE_THROW(ISTLError, "Size of solution vector x does not match the number of matrix columns!");
    \n-
    569 if (mat.M()+mat.N()==0)
    \n-
    570 DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
    \n-
    571
    \n-
    572 SuperMatrix* mB = &B;
    \n-
    573 SuperMatrix* mX = &X;
    \n-
    574 SuperMatrix rB, rX;
    \n-
    575 if (reusevector) {
    \n-
    576 if(first) {
    \n-
    577 SuperLUDenseMatChooser<T>::create(&B, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    578 SuperLUDenseMatChooser<T>::create(&X, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    579 first=false;
    \n-
    580 }else{
    \n-
    581 ((DNformat*)B.Store)->nzval=&b[0];
    \n-
    582 ((DNformat*)X.Store)->nzval=&x[0];
    \n-
    583 }
    \n-
    584 } else {
    \n-
    585 SuperLUDenseMatChooser<T>::create(&rB, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    586 SuperLUDenseMatChooser<T>::create(&rX, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    587 mB = &rB;
    \n-
    588 mX = &rX;
    \n-
    589 }
    \n-
    590 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
    \n-
    591 int info;
    \n-
    592 mem_usage_t memusage;
    \n-
    593 SuperLUStat_t stat;
    \n-
    594 /* Initialize the statistics variables. */
    \n-
    595 StatInit(&stat);
    \n-
    596 /*
    \n-
    597 range_type d=b;
    \n-
    598 a->usmv(-1, x, d);
    \n-
    599
    \n-
    600 double def0=d.two_norm();
    \n-
    601 */
    \n-
    602 options.IterRefine=SLU_DOUBLE;
    \n-
    603
    \n-
    604 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
    \n-
    605 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
    \n-
    606 &memusage, &stat, &info);
    \n-
    607
    \n-
    608 res.iterations=1;
    \n-
    609
    \n-
    610 /*
    \n-
    611 if(options.Equil==YES)
    \n-
    612 // undo scaling of right hand side
    \n-
    613 std::transform(reinterpret_cast<T*>(&b[0]),reinterpret_cast<T*>(&b[0])+mat.M(),
    \n-
    614 C, reinterpret_cast<T*>(&d[0]), std::divides<T>());
    \n-
    615 else
    \n-
    616 d=b;
    \n-
    617 a->usmv(-1, x, d);
    \n-
    618 res.reduction=d.two_norm()/def0;
    \n-
    619 res.conv_rate = res.reduction;
    \n-
    620 res.converged=(res.reduction<1e-10||d.two_norm()<1e-18);
    \n-
    621 */
    \n-
    622 res.converged=true;
    \n-
    623
    \n-
    624 if(verbose) {
    \n-
    625
    \n-
    626 dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
    \n-
    627
    \n-
    628 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
    \n-
    629
    \n-
    630 if ( info == 0 || info == nSuperLUCol+1 ) {
    \n-
    631
    \n-
    632 if ( options.IterRefine ) {
    \n-
    633 std::cout<<"Iterative Refinement: steps="
    \n-
    634 <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
    \n-
    635 }else
    \n-
    636 std::cout<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
    \n-
    637 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
    \n-
    638 std::cout<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
    \n-
    639 }
    \n-
    640
    \n-
    641 if ( options.PrintStat ) StatPrint(&stat);
    \n-
    642 }
    \n-
    643 StatFree(&stat);
    \n-
    644 if (!reusevector) {
    \n-
    645 SUPERLU_FREE(rB.Store);
    \n-
    646 SUPERLU_FREE(rX.Store);
    \n-
    647 }
    \n-
    648 }
    \n-
    649
    \n-
    650 template<typename M>
    \n-
    651 void SuperLU<M>
    \n-
    652 ::apply(T* x, T* b)
    \n-
    653 {
    \n-
    654 if(mat.N()+mat.M()==0)
    \n-
    655 DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
    \n-
    656
    \n-
    657 SuperMatrix* mB = &B;
    \n-
    658 SuperMatrix* mX = &X;
    \n-
    659 SuperMatrix rB, rX;
    \n-
    660 if (reusevector) {
    \n-
    661 if(first) {
    \n-
    662 SuperLUDenseMatChooser<T>::create(&B, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    663 SuperLUDenseMatChooser<T>::create(&X, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    664 first=false;
    \n-
    665 }else{
    \n-
    666 ((DNformat*) B.Store)->nzval=b;
    \n-
    667 ((DNformat*)X.Store)->nzval=x;
    \n-
    668 }
    \n-
    669 } else {
    \n-
    670 SuperLUDenseMatChooser<T>::create(&rB, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    671 SuperLUDenseMatChooser<T>::create(&rX, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
    \n-
    672 mB = &rB;
    \n-
    673 mX = &rX;
    \n-
    674 }
    \n-
    675
    \n-
    676 typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
    \n-
    677 int info;
    \n-
    678 mem_usage_t memusage;
    \n-
    679 SuperLUStat_t stat;
    \n-
    680 /* Initialize the statistics variables. */
    \n-
    681 StatInit(&stat);
    \n-
    682
    \n-
    683 options.IterRefine=SLU_DOUBLE;
    \n-
    684
    \n-
    685 SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
    \n-
    686 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
    \n-
    687 &memusage, &stat, &info);
    \n-
    688
    \n-
    689 if(verbose) {
    \n-
    690 dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
    \n-
    691
    \n-
    692 auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
    \n-
    693
    \n-
    694 if ( info == 0 || info == nSuperLUCol+1 ) { // Factorization has succeeded
    \n-
    695
    \n-
    696 if ( options.IterRefine ) {
    \n-
    697 dinfo<<"Iterative Refinement: steps="
    \n-
    698 <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
    \n-
    699 }else
    \n-
    700 dinfo<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
    \n-
    701 } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
    \n-
    702 dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
    \n-
    703 }
    \n-
    704 if ( options.PrintStat ) StatPrint(&stat);
    \n-
    705 }
    \n-
    706
    \n-
    707 StatFree(&stat);
    \n-
    708 if (!reusevector) {
    \n-
    709 SUPERLU_FREE(rB.Store);
    \n-
    710 SUPERLU_FREE(rX.Store);
    \n-
    711 }
    \n-
    712 }
    \n-
    715 template<typename T, typename A>
    \n-\n-
    717 {
    \n-
    718 enum { value=true};
    \n-
    719 };
    \n-
    720
    \n-
    721 template<typename T, typename A>
    \n-\n-
    723 {
    \n-
    724 enum { value = true };
    \n-
    725 };
    \n-
    726
    \n-\n-
    728 template<class> struct isValidBlock : std::false_type{};
    \n-
    729 template<int k> struct isValidBlock<Dune::FieldVector<double,k>> : std::true_type{};
    \n-
    730 template<int k> struct isValidBlock<Dune::FieldVector<std::complex<double>,k>> : std::true_type{};
    \n-
    731 template<typename TL, typename M>
    \n-
    732 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    733 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    734 operator() (TL /*tl*/, const M& mat, const Dune::ParameterTree& config,
    \n-
    735 std::enable_if_t<isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    736 {
    \n-
    737 int verbose = config.get("verbose", 0);
    \n-
    738 return std::make_shared<Dune::SuperLU<M>>(mat,verbose);
    \n-
    739 }
    \n-
    740
    \n-
    741 // second version with SFINAE to validate the template parameters of SuperLU
    \n-
    742 template<typename TL, typename M>
    \n-
    743 std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
    \n-
    744 typename Dune::TypeListElement<2, TL>::type>>
    \n-
    745 operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
    \n-
    746 std::enable_if_t<!isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
    \n-
    747 {
    \n-
    748 DUNE_THROW(UnsupportedType,
    \n-
    749 "Unsupported Type in SuperLU (only double and std::complex<double> supported)");
    \n-
    750 }
    \n-
    751 };
    \n-
    752 template<> struct SuperLUCreator::isValidBlock<double> : std::true_type{};
    \n-
    753 template<> struct SuperLUCreator::isValidBlock<std::complex<double>> : std::true_type{};
    \n-
    754
    \n-\n-
    756} // end namespace DUNE
    \n-
    757
    \n-
    758// undefine macros from SuperLU's slu_util.h
    \n-
    759#undef FIRSTCOL_OF_SNODE
    \n-
    760#undef NO_MARKER
    \n-
    761#undef NUM_TEMPV
    \n-
    762#undef USER_ABORT
    \n-
    763#undef USER_MALLOC
    \n-
    764#undef SUPERLU_MALLOC
    \n-
    765#undef USER_FREE
    \n-
    766#undef SUPERLU_FREE
    \n-
    767#undef CHECK_MALLOC
    \n-
    768#undef SUPERLU_MAX
    \n-
    769#undef SUPERLU_MIN
    \n-
    770#undef L_SUB_START
    \n-
    771#undef L_SUB
    \n-
    772#undef L_NZ_START
    \n-
    773#undef L_FST_SUPC
    \n-
    774#undef U_NZ_START
    \n-
    775#undef U_SUB
    \n-
    776#undef TRUE
    \n-
    777#undef FALSE
    \n-
    778#undef EMPTY
    \n-
    779#undef NODROP
    \n-
    780#undef DROP_BASIC
    \n-
    781#undef DROP_PROWS
    \n-
    782#undef DROP_COLUMN
    \n-
    783#undef DROP_AREA
    \n-
    784#undef DROP_SECONDARY
    \n-
    785#undef DROP_DYNAMIC
    \n-
    786#undef DROP_INTERP
    \n-
    787#undef MILU_ALPHA
    \n-
    788
    \n-
    789#endif // HAVE_SUPERLU
    \n-
    790#endif // DUNE_SUPERLU_HH
    \n-\n-
    Templates characterizing the type of a solver.
    \n-
    Implementations of the inverse operator interface.
    \n-\n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n-\n-
    Implementation of the BCRSMatrix class.
    \n-
    void setSubMatrix(const Matrix &mat, const S &rowIndexSet)
    Definition: superlu.hh:457
    \n-
    void apply(domain_type &x, range_type &b, InverseOperatorResult &res)
    Apply inverse operator,.
    Definition: superlu.hh:563
    \n-
    DUNE_REGISTER_DIRECT_SOLVER("ldl", Dune::LDLCreator())
    \n-
    void setVerbosity(bool v)
    Definition: superlu.hh:437
    \n-
    void free()
    free allocated space.
    Definition: superlu.hh:403
    \n-
    ~SuperLU()
    Definition: superlu.hh:396
    \n-
    SuperLU()
    Empty default constructor.
    Definition: superlu.hh:432
    \n-
    void setMatrix(const Matrix &mat)
    Initialize data from given matrix.
    Definition: superlu.hh:443
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    STL namespace.
    \n+
    70 for (size_type rowIdx=0; rowIdx<m.N(); rowIdx++) {
    \n+
    71
    \n+
    72 const RowType& row = m[rowIdx];
    \n+
    73
    \n+
    74 ColumnIterator cIt = row.begin();
    \n+
    75 ColumnIterator cEndIt = row.end();
    \n+
    76
    \n+
    77 for(; cIt!=cEndIt; ++cIt)
    \n+
    78 add(rowIdx+rowOffset, cIt.index()+colOffset);
    \n+
    79
    \n+
    80 }
    \n+
    81
    \n+
    82 }
    \n+
    83
    \n+
    89 template <class MatrixType>
    \n+
    90 void exportIdx(MatrixType& matrix) const {
    \n+
    91
    \n+
    92 matrix.setSize(rows_, cols_);
    \n+
    93 matrix.setBuildMode(MatrixType::random);
    \n+
    94
    \n+
    95 for (size_type i=0; i<rows_; i++)
    \n+
    96 matrix.setrowsize(i, indices_[i].size());
    \n+
    97
    \n+
    98 matrix.endrowsizes();
    \n+
    99
    \n+
    100 for (size_type i=0; i<rows_; i++) {
    \n+
    101
    \n+
    102 typename std::set<size_type>::iterator it = indices_[i].begin();
    \n+
    103 for (; it!=indices_[i].end(); ++it)
    \n+
    104 matrix.addindex(i, *it);
    \n+
    105
    \n+
    106 }
    \n+
    107
    \n+
    108 matrix.endindices();
    \n+
    109
    \n+
    110 }
    \n+
    111
    \n+
    112 private:
    \n+
    113
    \n+
    114 std::vector<std::set<size_type> > indices_;
    \n+
    115
    \n+
    116 size_type rows_, cols_;
    \n+
    117
    \n+
    118 };
    \n+
    119
    \n+
    120
    \n+
    121} // end namespace Dune
    \n+
    122
    \n+
    123#endif
    \n
    Definition: allocator.hh:11
    \n-
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n-
    Definition: overlappingschwarz.hh:694
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    size_type M() const
    Return the number of columns.
    Definition: matrix.hh:700
    \n-
    size_type N() const
    Return the number of rows.
    Definition: matrix.hh:695
    \n-
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n-
    int iterations
    Number of iterations.
    Definition: solver.hh:67
    \n-
    bool converged
    True if convergence criterion has been met.
    Definition: solver.hh:73
    \n-
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    Definition: solverregistry.hh:77
    \n-
    Definition: solvertype.hh:16
    \n-
    @ value
    Whether this is a direct solver.
    Definition: solvertype.hh:24
    \n-
    Definition: solvertype.hh:30
    \n-
    @ value
    whether the solver internally uses column compressed storage
    Definition: solvertype.hh:36
    \n-
    Definition: superlu.hh:45
    \n-
    Definition: superlu.hh:49
    \n-
    Definition: superlu.hh:53
    \n-
    Definition: superlu.hh:57
    \n-
    SuperLu Solver.
    Definition: superlu.hh:271
    \n-
    SuperLUMatrix::size_type nnz() const
    Definition: superlu.hh:355
    \n-
    void apply(domain_type &x, range_type &b, double reduction, InverseOperatorResult &res)
    apply inverse operator, with given convergence criteria.
    Definition: superlu.hh:342
    \n-
    typename Impl::SuperLUVectorChooser< M >::range_type range_type
    The type of the range of the solver.
    Definition: superlu.hh:284
    \n-
    M matrix_type
    Definition: superlu.hh:276
    \n-
    SuperMatrixInitializer< Matrix > MatrixInitializer
    Type of an associated initializer class.
    Definition: superlu.hh:280
    \n-
    M Matrix
    The matrix type.
    Definition: superlu.hh:275
    \n-
    typename Impl::SuperLUVectorChooser< M >::domain_type domain_type
    The type of the domain of the solver.
    Definition: superlu.hh:282
    \n-
    const char * name()
    Definition: superlu.hh:371
    \n-
    virtual SolverCategory::Category category() const
    Category of the solver (see SolverCategory::Category)
    Definition: superlu.hh:287
    \n-
    Dune::SuperLUMatrix< Matrix > SuperLUMatrix
    The corresponding SuperLU Matrix type.
    Definition: superlu.hh:278
    \n-
    SuperLU(const Matrix &mat, const ParameterTree &config)
    Constructs the SuperLU solver.
    Definition: superlu.hh:320
    \n-
    Definition: superlu.hh:727
    \n-
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
    Definition: superlu.hh:734
    \n-
    Definition: superlu.hh:728
    \n-
    Definition: supermatrix.hh:132
    \n-\n-
    Definition: supermatrix.hh:179
    \n+
    Stores the nonzero entries in a sparse matrix.
    Definition: matrixindexset.hh:16
    \n+
    void resize(size_type rows, size_type cols)
    Reset the size of an index set.
    Definition: matrixindexset.hh:31
    \n+
    MatrixIndexSet()
    Default constructor.
    Definition: matrixindexset.hh:22
    \n+
    void add(size_type i, size_type j)
    Add an index to the index set.
    Definition: matrixindexset.hh:38
    \n+
    size_type rows() const
    Return the number of rows.
    Definition: matrixindexset.hh:52
    \n+
    std::size_t size_type
    Definition: matrixindexset.hh:19
    \n+
    void exportIdx(MatrixType &matrix) const
    Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.
    Definition: matrixindexset.hh:90
    \n+
    MatrixIndexSet(size_type rows, size_type cols)
    Constructor setting the matrix size.
    Definition: matrixindexset.hh:26
    \n+
    size_type rowsize(size_type row) const
    Return the number of entries in a given row.
    Definition: matrixindexset.hh:56
    \n+
    size_type size() const
    Return the number of entries.
    Definition: matrixindexset.hh:43
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,944 +4,158 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-superlu.hh\n+matrixindexset.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_SUPERLU_HH\n- 6#define DUNE_ISTL_SUPERLU_HH\n+ 5#ifndef DUNE_ISTL_MATRIXINDEXSET_HH\n+ 6#define DUNE_ISTL_MATRIXINDEXSET_HH\n 7\n- 8#if HAVE_SUPERLU\n- 9\n- 10#include \"superlufunctions.hh\"\n- 11#include \"solvers.hh\"\n- 12#include \"supermatrix.hh\"\n- 13#include \n- 14#include \n- 15#include \"bcrsmatrix.hh\"\n- 16#include \"bvector.hh\"\n- 17#include \"istlexception.hh\"\n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22#include \n- 23\n- 24namespace Dune\n- 25{\n- 26\n- 37 template\n- 38 class SeqOverlappingSchwarz;\n- 39\n- 40 template\n- 41 struct SeqOverlappingSchwarzAssemblerHelper;\n- 42\n- 43 template\n-44 struct SuperLUSolveChooser\n- 45 {};\n- 46\n- 47 template\n-48 struct SuperLUDenseMatChooser\n- 49 {};\n+ 8#include \n+ 9#include \n+ 10\n+ 11namespace Dune {\n+ 12\n+ 13\n+15 class MatrixIndexSet\n+ 16 {\n+ 17\n+ 18 public:\n+19 typedef std::size_t size_type;\n+ 20\n+22 MatrixIndexSet() : rows_(0), cols_(0)\n+ 23 {}\n+ 24\n+26 MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) {\n+ 27 indices_.resize(rows_);\n+ 28 }\n+ 29\n+31 void resize(size_type rows, size_type cols) {\n+ 32 rows_ = rows;\n+ 33 cols_ = cols;\n+ 34 indices_.resize(rows_);\n+ 35 }\n+ 36\n+38 void add(size_type i, size_type j) {\n+ 39 indices_[i].insert(j);\n+ 40 }\n+ 41\n+43 size_type size() const {\n+ 44 size_type entries = 0;\n+ 45 for (size_type i=0; i\n-52 struct SuperLUQueryChooser\n- 53 {};\n+52 size_type rows() const {return rows_;}\n+ 53\n 54\n- 55 template\n-56 struct QuerySpaceChooser\n- 57 {};\n- 58\n- 59#if __has_include(\"slu_sdefs.h\")\n- 60 template<>\n- 61 struct SuperLUDenseMatChooser\n- 62 {\n- 63 static void create(SuperMatrix *mat, int n, int m, float *dat, int n1,\n- 64 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 65 {\n- 66 sCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);\n- 67\n- 68 }\n+56 size_type rowsize(size_type row) const {return indices_[row].size();}\n+ 57\n+ 64 template \n+65 void import(const MatrixType& m, size_type rowOffset=0, size_type\n+colOffset=0) {\n+ 66\n+ 67 typedef typename MatrixType::row_type RowType;\n+ 68 typedef typename RowType::ConstIterator ColumnIterator;\n 69\n- 70 static void destroy(SuperMatrix*)\n- 71 {}\n- 72\n- 73 };\n- 74 template<>\n- 75 struct SuperLUSolveChooser\n- 76 {\n- 77 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n-*perm_c, int *perm_r, int *etree,\n- 78 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,\n- 79 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n- 80 float *rpg, float *rcond, float *ferr, float *berr,\n- 81 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n- 82 {\n- 83 GlobalLU_t gLU;\n- 84 sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n- 85 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n- 86 &gLU, memusage, stat, info);\n- 87 }\n- 88 };\n- 89\n- 90 template<>\n- 91 struct QuerySpaceChooser\n- 92 {\n- 93 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n-memusage)\n- 94 {\n- 95 sQuerySpace(L,U,memusage);\n- 96 }\n- 97 };\n- 98\n- 99#endif\n- 100\n- 101#if __has_include(\"slu_ddefs.h\")\n- 102\n- 103 template<>\n- 104 struct SuperLUDenseMatChooser\n- 105 {\n- 106 static void create(SuperMatrix *mat, int n, int m, double *dat, int n1,\n- 107 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 108 {\n- 109 dCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);\n- 110\n- 111 }\n- 112\n- 113 static void destroy(SuperMatrix * /* mat */)\n- 114 {}\n- 115 };\n- 116 template<>\n- 117 struct SuperLUSolveChooser\n- 118 {\n- 119 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n-*perm_c, int *perm_r, int *etree,\n- 120 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,\n- 121 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n- 122 double *rpg, double *rcond, double *ferr, double *berr,\n- 123 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n- 124 {\n- 125 GlobalLU_t gLU;\n- 126 dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n- 127 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n- 128 &gLU, memusage, stat, info);\n- 129 }\n- 130 };\n- 131\n- 132 template<>\n- 133 struct QuerySpaceChooser\n- 134 {\n- 135 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n-memusage)\n- 136 {\n- 137 dQuerySpace(L,U,memusage);\n- 138 }\n- 139 };\n- 140#endif\n- 141\n- 142#if __has_include(\"slu_zdefs.h\")\n- 143 template<>\n- 144 struct SuperLUDenseMatChooser >\n- 145 {\n- 146 static void create(SuperMatrix *mat, int n, int m, std::complex\n-*dat, int n1,\n- 147 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 148 {\n- 149 zCreate_Dense_Matrix(mat, n, m, reinterpret_cast(dat), n1,\n-stype, dtype, mtype);\n- 150\n- 151 }\n- 152\n- 153 static void destroy(SuperMatrix*)\n- 154 {}\n- 155 };\n- 156\n- 157 template<>\n- 158 struct SuperLUSolveChooser >\n- 159 {\n- 160 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n-*perm_c, int *perm_r, int *etree,\n- 161 char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,\n- 162 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n- 163 double *rpg, double *rcond, double *ferr, double *berr,\n- 164 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n- 165 {\n- 166 GlobalLU_t gLU;\n- 167 zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n- 168 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n- 169 &gLU, memusage, stat, info);\n- 170 }\n- 171 };\n- 172\n- 173 template<>\n- 174 struct QuerySpaceChooser >\n- 175 {\n- 176 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n-memusage)\n- 177 {\n- 178 zQuerySpace(L,U,memusage);\n- 179 }\n- 180 };\n- 181#endif\n- 182\n- 183#if __has_include(\"slu_cdefs.h\")\n- 184 template<>\n- 185 struct SuperLUDenseMatChooser >\n- 186 {\n- 187 static void create(SuperMatrix *mat, int n, int m, std::complex\n-*dat, int n1,\n- 188 Stype_t stype, Dtype_t dtype, Mtype_t mtype)\n- 189 {\n- 190 cCreate_Dense_Matrix(mat, n, m, reinterpret_cast< ::complex*>(dat), n1,\n-stype, dtype, mtype);\n- 191\n- 192 }\n- 193\n- 194 static void destroy(SuperMatrix* /* mat */)\n- 195 {}\n- 196 };\n- 197\n- 198 template<>\n- 199 struct SuperLUSolveChooser >\n- 200 {\n- 201 static void solve(superlu_options_t *options, SuperMatrix *mat, int\n-*perm_c, int *perm_r, int *etree,\n- 202 char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,\n- 203 void *work, int lwork, SuperMatrix *B, SuperMatrix *X,\n- 204 float *rpg, float *rcond, float *ferr, float *berr,\n- 205 mem_usage_t *memusage, SuperLUStat_t *stat, int *info)\n- 206 {\n- 207 GlobalLU_t gLU;\n- 208 cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,\n- 209 L, U, work, lwork, B, X, rpg, rcond, ferr, berr,\n- 210 &gLU, memusage, stat, info);\n- 211 }\n- 212 };\n- 213\n- 214 template<>\n- 215 struct QuerySpaceChooser >\n- 216 {\n- 217 static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t*\n-memusage)\n- 218 {\n- 219 cQuerySpace(L,U,memusage);\n- 220 }\n- 221 };\n- 222#endif\n- 223\n- 224 namespace Impl\n- 225 {\n- 226 template\n- 227 struct SuperLUVectorChooser\n- 228 {};\n- 229\n- 230 template\n- 231 struct SuperLUVectorChooser,A > >\n- 232 {\n- 234 using domain_type = BlockVector<\n- 235 FieldVector,\n- 236 typename std::allocator_traits::template rebind_alloc\n-> >;\n- 238 using range_type = BlockVector<\n- 239 FieldVector,\n- 240 typename std::allocator_traits::template rebind_alloc\n-> >;\n- 241 };\n- 242\n- 243 template\n- 244 struct SuperLUVectorChooser >\n- 245 {\n- 247 using domain_type = BlockVector;\n- 249 using range_type = BlockVector;\n- 250 };\n- 251 }\n- 252\n- 266 template\n-267 class SuperLU\n- 268 : public InverseOperator<\n- 269 typename Impl::SuperLUVectorChooser::domain_type,\n- 270 typename Impl::SuperLUVectorChooser::range_type >\n- 271 {\n- 272 using T = typename M::field_type;\n- 273 public:\n-275 using Matrix = M;\n-276 using matrix_type = M;\n-278 typedef Dune::SuperLUMatrix SuperLUMatrix;\n-280 typedef SuperMatrixInitializer MatrixInitializer;\n-282 using domain_type = typename Impl::SuperLUVectorChooser::domain_type;\n-284 using range_type = typename Impl::SuperLUVectorChooser::range_type;\n- 285\n-287 virtual SolverCategory::Category category() const\n- 288 {\n- 289 return SolverCategory::Category::sequential;\n- 290 }\n- 291\n- 306 explicit SuperLU(const Matrix& mat, bool verbose=false,\n- 307 bool reusevector=true);\n- 308\n- 309\n-320 SuperLU(const Matrix& mat, const ParameterTree& config)\n- 321 : SuperLU(mat, config.get(\"verbose\", false), config.get\n-(\"reuseVector\", true))\n- 322 {}\n- 323\n- 330 SuperLU();\n- 331\n- 332 ~SuperLU();\n- 333\n- 337 void apply(domain_type& x, range_type& b, InverseOperatorResult& res);\n- 338\n-342 void apply (domain_type& x, range_type& b, [[maybe_unused]] double\n-reduction, InverseOperatorResult& res)\n- 343 {\n- 344 apply(x,b,res);\n- 345 }\n- 346\n- 350 void apply(T* x, T* b);\n- 351\n- 353 void setMatrix(const Matrix& mat);\n- 354\n-355 typename SuperLUMatrix::size_type nnz() const\n- 356 {\n- 357 return mat.nonzeroes();\n- 358 }\n- 359\n- 360 template\n- 361 void setSubMatrix(const Matrix& mat, const S& rowIndexSet);\n- 362\n- 363 void setVerbosity(bool v);\n- 364\n- 369 void free();\n- 370\n-371 const char* name() { return \"SuperLU\"; }\n- 372 private:\n- 373 template\n-374 friend class SeqOverlappingSchwarz;\n- 375 friend struct SeqOverlappingSchwarzAssemblerHelper,true>;\n- 376\n- 377 SuperLUMatrix& getInternalMatrix() { return mat; }\n- 378\n- 380 void decompose();\n- 381\n- 382 SuperLUMatrix mat;\n- 383 SuperMatrix L, U, B, X;\n- 384 int *perm_c, *perm_r, *etree;\n- 385 typename GetSuperLUType::float_type *R, *C;\n- 386 T *bstore;\n- 387 superlu_options_t options;\n- 388 char equed;\n- 389 void *work;\n- 390 int lwork;\n- 391 bool first, verbose, reusevector;\n- 392 };\n- 393\n- 394 template\n- 395 SuperLU\n-396::~SuperLU()\n- 397 {\n- 398 if(mat.N()+mat.M()>0)\n- 399 free();\n- 400 }\n- 401\n- 402 template\n-403 void SuperLU::free()\n- 404 {\n- 405 delete[] perm_c;\n- 406 delete[] perm_r;\n- 407 delete[] etree;\n- 408 delete[] R;\n- 409 delete[] C;\n- 410 if(lwork>=0) {\n- 411 Destroy_SuperNode_Matrix(&L);\n- 412 Destroy_CompCol_Matrix(&U);\n- 413 }\n- 414 lwork=0;\n- 415 if(!first && reusevector) {\n- 416 SUPERLU_FREE(B.Store);\n- 417 SUPERLU_FREE(X.Store);\n- 418 }\n- 419 mat.free();\n- 420 }\n- 421\n- 422 template\n- 423 SuperLU\n-424::SuperLU(const Matrix& mat_, bool verbose_, bool reusevector_)\n- 425 : work(0), lwork(0), first(true), verbose(verbose_),\n- 426 reusevector(reusevector_)\n- 427 {\n- 428 setMatrix(mat_);\n- 429\n- 430 }\n- 431 template\n-432 SuperLU::SuperLU()\n- 433 : work(0), lwork(0),verbose(false),\n- 434 reusevector(false)\n- 435 {}\n- 436 template\n-437 void SuperLU::setVerbosity(bool v)\n- 438 {\n- 439 verbose=v;\n- 440 }\n- 441\n- 442 template\n-443 void SuperLU::setMatrix(const Matrix& mat_)\n- 444 {\n- 445 if(mat.N()+mat.M()>0) {\n- 446 free();\n- 447 }\n- 448 lwork=0;\n- 449 work=0;\n- 450 //a=&mat_;\n- 451 mat=mat_;\n- 452 decompose();\n- 453 }\n- 454\n- 455 template\n- 456 template\n-457 void SuperLU::setSubMatrix(const Matrix& mat_,\n- 458 const S& mrs)\n- 459 {\n- 460 if(mat.N()+mat.M()>0) {\n- 461 free();\n- 462 }\n- 463 lwork=0;\n- 464 work=0;\n- 465 //a=&mat_;\n- 466 mat.setMatrix(mat_,mrs);\n- 467 decompose();\n- 468 }\n- 469\n- 470 template\n- 471 void SuperLU::decompose()\n- 472 {\n- 473\n- 474 first = true;\n- 475 perm_c = new int[mat.M()];\n- 476 perm_r = new int[mat.N()];\n- 477 etree = new int[mat.M()];\n- 478 R = new typename GetSuperLUType::float_type[mat.N()];\n- 479 C = new typename GetSuperLUType::float_type[mat.M()];\n- 480\n- 481 set_default_options(&options);\n- 482 // Do the factorization\n- 483 B.ncol=0;\n- 484 B.Stype=SLU_DN;\n- 485 B.Dtype=GetSuperLUType::type;\n- 486 B.Mtype= SLU_GE;\n- 487 DNformat fakeFormat;\n- 488 fakeFormat.lda=mat.N();\n- 489 B.Store=&fakeFormat;\n- 490 X.Stype=SLU_DN;\n- 491 X.Dtype=GetSuperLUType::type;\n- 492 X.Mtype= SLU_GE;\n- 493 X.ncol=0;\n- 494 X.Store=&fakeFormat;\n- 495\n- 496 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr=1e10;\n- 497 int info;\n- 498 mem_usage_t memusage;\n- 499 SuperLUStat_t stat;\n- 500\n- 501 StatInit(&stat);\n- 502 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n-perm_c, perm_r, etree, &equed, R, C,\n- 503 &L, &U, work, lwork, &B, &X, &rpg, &rcond, &ferr,\n- 504 &berr, &memusage, &stat, &info);\n- 505\n- 506 if(verbose) {\n- 507 dinfo<<\"LU factorization: dgssvx() returns info \"<< info<(mat).ncol;\n- 510\n- 511 if ( info == 0 || info == nSuperLUCol+1 ) {\n- 512\n- 513 if ( options.PivotGrowth )\n- 514 dinfo<<\"Recip. pivot growth = \"<nnz<nnz<nnz + Ustore->nnz -\n-nSuperLUCol<::querySpace(&L, &U, &memusage);\n- 523 dinfo<<\"L\\\\U MB \"< 0 && lwork == -1 ) { // Memory allocation failed\n- 528 dinfo<<\"** Estimated memory: \"<< info - nSuperLUCol<colptr[i]; c < Ustore->colptr[i+1]; ++c)\n- 540 //if(Ustore->rowind[c]==i)\n- 541 std::cout<rowind[c]<<\"->\"<<((double*)Ustore->nzval)[c]<<\" \";\n- 542 if(k==0){\n- 543 //\n- 544 k=-1;\n- 545 }std::cout<colptr[i]; c < Ustore->colptr[i+1]; ++c)\n- 551 //if(Ustore->rowind[c]==i)\n- 552 std::cout<rowind[c]<<\"->\"<<((double*)Ustore->nzval)[c]<<\" \";\n- 553 if(k==0){\n- 554 //\n- 555 k=-1;\n- 556 }std::cout<\n- 562 void SuperLU\n-563::apply(domain_type& x, range_type& b, InverseOperatorResult& res)\n- 564 {\n- 565 if (mat.N() != b.dim())\n- 566 DUNE_THROW(ISTLError, \"Size of right-hand-side vector b does not match the\n-number of matrix rows!\");\n- 567 if (mat.M() != x.dim())\n- 568 DUNE_THROW(ISTLError, \"Size of solution vector x does not match the number\n-of matrix columns!\");\n- 569 if (mat.M()+mat.N()==0)\n- 570 DUNE_THROW(ISTLError, \"Matrix of SuperLU is null!\");\n- 571\n- 572 SuperMatrix* mB = &B;\n- 573 SuperMatrix* mX = &X;\n- 574 SuperMatrix rB, rX;\n- 575 if (reusevector) {\n- 576 if(first) {\n- 577 SuperLUDenseMatChooser::create(&B, (int)mat.N(), 1,\n-reinterpret_cast(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n-SLU_GE);\n- 578 SuperLUDenseMatChooser::create(&X, (int)mat.N(), 1,\n-reinterpret_cast(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n-SLU_GE);\n- 579 first=false;\n- 580 }else{\n- 581 ((DNformat*)B.Store)->nzval=&b[0];\n- 582 ((DNformat*)X.Store)->nzval=&x[0];\n- 583 }\n- 584 } else {\n- 585 SuperLUDenseMatChooser::create(&rB, (int)mat.N(), 1,\n-reinterpret_cast(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n-SLU_GE);\n- 586 SuperLUDenseMatChooser::create(&rX, (int)mat.N(), 1,\n-reinterpret_cast(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType::type,\n-SLU_GE);\n- 587 mB = &rB;\n- 588 mX = &rX;\n- 589 }\n- 590 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr;\n- 591 int info;\n- 592 mem_usage_t memusage;\n- 593 SuperLUStat_t stat;\n- 594 /* Initialize the statistics variables. */\n- 595 StatInit(&stat);\n- 596 /*\n- 597 range_type d=b;\n- 598 a->usmv(-1, x, d);\n- 599\n- 600 double def0=d.two_norm();\n- 601 */\n- 602 options.IterRefine=SLU_DOUBLE;\n- 603\n- 604 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n-perm_c, perm_r, etree, &equed, R, C,\n- 605 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,\n- 606 &memusage, &stat, &info);\n- 607\n- 608 res.iterations=1;\n- 609\n- 610 /*\n- 611 if(options.Equil==YES)\n- 612 // undo scaling of right hand side\n- 613 std::transform(reinterpret_cast(&b[0]),reinterpret_cast(&b\n-[0])+mat.M(),\n- 614 C, reinterpret_cast(&d[0]), std::divides());\n- 615 else\n- 616 d=b;\n- 617 a->usmv(-1, x, d);\n- 618 res.reduction=d.two_norm()/def0;\n- 619 res.conv_rate = res.reduction;\n- 620 res.converged=(res.reduction<1e-10||d.two_norm()<1e-18);\n- 621 */\n- 622 res.converged=true;\n- 623\n- 624 if(verbose) {\n- 625\n- 626 dinfo<<\"Triangular solve: dgssvx() returns info \"<< info<(mat).ncol;\n- 629\n- 630 if ( info == 0 || info == nSuperLUCol+1 ) {\n- 631\n- 632 if ( options.IterRefine ) {\n- 633 std::cout<<\"Iterative Refinement: steps=\"\n- 634 < 0 && lwork == -1 ) { // Memory allocation failed\n- 638 std::cout<<\"** Estimated memory: \"<< info - nSuperLUCol<<\" bytes\"<\n- 651 void SuperLU\n-652::apply(T* x, T* b)\n- 653 {\n- 654 if(mat.N()+mat.M()==0)\n- 655 DUNE_THROW(ISTLError, \"Matrix of SuperLU is null!\");\n- 656\n- 657 SuperMatrix* mB = &B;\n- 658 SuperMatrix* mX = &X;\n- 659 SuperMatrix rB, rX;\n- 660 if (reusevector) {\n- 661 if(first) {\n- 662 SuperLUDenseMatChooser::create(&B, mat.N(), 1, b, mat.N(), SLU_DN,\n-GetSuperLUType::type, SLU_GE);\n- 663 SuperLUDenseMatChooser::create(&X, mat.N(), 1, x, mat.N(), SLU_DN,\n-GetSuperLUType::type, SLU_GE);\n- 664 first=false;\n- 665 }else{\n- 666 ((DNformat*) B.Store)->nzval=b;\n- 667 ((DNformat*)X.Store)->nzval=x;\n- 668 }\n- 669 } else {\n- 670 SuperLUDenseMatChooser::create(&rB, mat.N(), 1, b, mat.N(), SLU_DN,\n-GetSuperLUType::type, SLU_GE);\n- 671 SuperLUDenseMatChooser::create(&rX, mat.N(), 1, x, mat.N(), SLU_DN,\n-GetSuperLUType::type, SLU_GE);\n- 672 mB = &rB;\n- 673 mX = &rX;\n- 674 }\n- 675\n- 676 typename GetSuperLUType::float_type rpg, rcond, ferr=1e10, berr;\n- 677 int info;\n- 678 mem_usage_t memusage;\n- 679 SuperLUStat_t stat;\n- 680 /* Initialize the statistics variables. */\n- 681 StatInit(&stat);\n- 682\n- 683 options.IterRefine=SLU_DOUBLE;\n- 684\n- 685 SuperLUSolveChooser::solve(&options, &static_cast(mat),\n-perm_c, perm_r, etree, &equed, R, C,\n- 686 &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,\n- 687 &memusage, &stat, &info);\n- 688\n- 689 if(verbose) {\n- 690 dinfo<<\"Triangular solve: dgssvx() returns info \"<< info<(mat).ncol;\n- 693\n- 694 if ( info == 0 || info == nSuperLUCol+1 ) { // Factorization has succeeded\n- 695\n- 696 if ( options.IterRefine ) {\n- 697 dinfo<<\"Iterative Refinement: steps=\"\n- 698 < 0 && lwork == -1 ) { // Memory allocation failed\n- 702 dinfo<<\"** Estimated memory: \"<< info - nSuperLUCol<<\" bytes\"<\n-716 struct IsDirectSolver > >\n- 717 {\n-718 enum { value=true};\n- 719 };\n- 720\n- 721 template\n-722 struct StoresColumnCompressed > >\n- 723 {\n-724 enum { value = true };\n- 725 };\n- 726\n-727 struct SuperLUCreator {\n-728 template struct isValidBlock : std::false_type{};\n-729 template struct isValidBlock> : std::\n-true_type{};\n-730 template struct isValidBlock,k>> : std::true_type{};\n- 731 template\n- 732 std::shared_ptr::type,\n- 733 typename Dune::TypeListElement<2, TL>::type>>\n-734 operator()(TL /*tl*/, const M& mat, const Dune::ParameterTree& config,\n- 735 std::enable_if_t::\n-type::block_type>::value,int> = 0) const\n- 736 {\n- 737 int verbose = config.get(\"verbose\", 0);\n- 738 return std::make_shared>(mat,verbose);\n- 739 }\n- 740\n- 741 // second version with SFINAE to validate the template parameters of\n-SuperLU\n- 742 template\n- 743 std::shared_ptr::type,\n- 744 typename Dune::TypeListElement<2, TL>::type>>\n-745 operator()(TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /\n-*config*/,\n- 746 std::enable_if_t::\n-type::block_type>::value,int> = 0) const\n- 747 {\n- 748 DUNE_THROW(UnsupportedType,\n- 749 \"Unsupported Type in SuperLU (only double and std::complex\n-supported)\");\n- 750 }\n- 751 };\n-752 template<> struct SuperLUCreator::isValidBlock : std::true_type{};\n-753 template<> struct SuperLUCreator::isValidBlock> :\n-std::true_type{};\n- 754\n-755 DUNE_REGISTER_DIRECT_SOLVER(\"superlu\", SuperLUCreator());\n- 756} // end namespace DUNE\n- 757\n- 758// undefine macros from SuperLU's slu_util.h\n- 759#undef FIRSTCOL_OF_SNODE\n- 760#undef NO_MARKER\n- 761#undef NUM_TEMPV\n- 762#undef USER_ABORT\n- 763#undef USER_MALLOC\n- 764#undef SUPERLU_MALLOC\n- 765#undef USER_FREE\n- 766#undef SUPERLU_FREE\n- 767#undef CHECK_MALLOC\n- 768#undef SUPERLU_MAX\n- 769#undef SUPERLU_MIN\n- 770#undef L_SUB_START\n- 771#undef L_SUB\n- 772#undef L_NZ_START\n- 773#undef L_FST_SUPC\n- 774#undef U_NZ_START\n- 775#undef U_SUB\n- 776#undef TRUE\n- 777#undef FALSE\n- 778#undef EMPTY\n- 779#undef NODROP\n- 780#undef DROP_BASIC\n- 781#undef DROP_PROWS\n- 782#undef DROP_COLUMN\n- 783#undef DROP_AREA\n- 784#undef DROP_SECONDARY\n- 785#undef DROP_DYNAMIC\n- 786#undef DROP_INTERP\n- 787#undef MILU_ALPHA\n- 788\n- 789#endif // HAVE_SUPERLU\n- 790#endif // DUNE_SUPERLU_HH\n-superlufunctions.hh\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-supermatrix.hh\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-istlexception.hh\n-solverfactory.hh\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-Dune::SuperLU::setSubMatrix\n-void setSubMatrix(const Matrix &mat, const S &rowIndexSet)\n-Definition: superlu.hh:457\n-Dune::SuperLU::apply\n-void apply(domain_type &x, range_type &b, InverseOperatorResult &res)\n-Apply inverse operator,.\n-Definition: superlu.hh:563\n-Dune::DUNE_REGISTER_DIRECT_SOLVER\n-DUNE_REGISTER_DIRECT_SOLVER(\"ldl\", Dune::LDLCreator())\n-Dune::SuperLU::setVerbosity\n-void setVerbosity(bool v)\n-Definition: superlu.hh:437\n-Dune::SuperLU::free\n-void free()\n-free allocated space.\n-Definition: superlu.hh:403\n-Dune::SuperLU::~SuperLU\n-~SuperLU()\n-Definition: superlu.hh:396\n-Dune::SuperLU::SuperLU\n-SuperLU()\n-Empty default constructor.\n-Definition: superlu.hh:432\n-Dune::SuperLU::setMatrix\n-void setMatrix(const Matrix &mat)\n-Initialize data from given matrix.\n-Definition: superlu.hh:443\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-std\n-STL namespace.\n+ 70 for (size_type rowIdx=0; rowIdx\n+90 void exportIdx(MatrixType& matrix) const {\n+ 91\n+ 92 matrix.setSize(rows_, cols_);\n+ 93 matrix.setBuildMode(MatrixType::random);\n+ 94\n+ 95 for (size_type i=0; i::iterator it = indices_[i].begin();\n+ 103 for (; it!=indices_[i].end(); ++it)\n+ 104 matrix.addindex(i, *it);\n+ 105\n+ 106 }\n+ 107\n+ 108 matrix.endindices();\n+ 109\n+ 110 }\n+ 111\n+ 112 private:\n+ 113\n+ 114 std::vector > indices_;\n+ 115\n+ 116 size_type rows_, cols_;\n+ 117\n+ 118 };\n+ 119\n+ 120\n+ 121} // end namespace Dune\n+ 122\n+ 123#endif\n Dune\n Definition: allocator.hh:11\n-Dune::get\n-PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n-VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n-Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n-Definition: dependency.hh:293\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::SeqOverlappingSchwarz\n-Sequential overlapping Schwarz preconditioner.\n-Definition: overlappingschwarz.hh:755\n-Dune::SeqOverlappingSchwarzAssemblerHelper\n-Definition: overlappingschwarz.hh:694\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::M\n-size_type M() const\n-Return the number of columns.\n-Definition: matrix.hh:700\n-Dune::Matrix::N\n-size_type N() const\n+Dune::MatrixIndexSet\n+Stores the nonzero entries in a sparse matrix.\n+Definition: matrixindexset.hh:16\n+Dune::MatrixIndexSet::resize\n+void resize(size_type rows, size_type cols)\n+Reset the size of an index set.\n+Definition: matrixindexset.hh:31\n+Dune::MatrixIndexSet::MatrixIndexSet\n+MatrixIndexSet()\n+Default constructor.\n+Definition: matrixindexset.hh:22\n+Dune::MatrixIndexSet::add\n+void add(size_type i, size_type j)\n+Add an index to the index set.\n+Definition: matrixindexset.hh:38\n+Dune::MatrixIndexSet::rows\n+size_type rows() const\n Return the number of rows.\n-Definition: matrix.hh:695\n-Dune::InverseOperatorResult\n-Statistics about the application of an inverse operator.\n-Definition: solver.hh:48\n-Dune::InverseOperatorResult::iterations\n-int iterations\n-Number of iterations.\n-Definition: solver.hh:67\n-Dune::InverseOperatorResult::converged\n-bool converged\n-True if convergence criterion has been met.\n-Definition: solver.hh:73\n-Dune::InverseOperator\n-Abstract base class for all solvers.\n-Definition: solver.hh:99\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::UnsupportedType\n-Definition: solverregistry.hh:77\n-Dune::IsDirectSolver\n-Definition: solvertype.hh:16\n-Dune::IsDirectSolver::value\n-@ value\n-Whether this is a direct solver.\n-Definition: solvertype.hh:24\n-Dune::StoresColumnCompressed\n-Definition: solvertype.hh:30\n-Dune::StoresColumnCompressed::value\n-@ value\n-whether the solver internally uses column compressed storage\n-Definition: solvertype.hh:36\n-Dune::SuperLUSolveChooser\n-Definition: superlu.hh:45\n-Dune::SuperLUDenseMatChooser\n-Definition: superlu.hh:49\n-Dune::SuperLUQueryChooser\n-Definition: superlu.hh:53\n-Dune::QuerySpaceChooser\n-Definition: superlu.hh:57\n-Dune::SuperLU\n-SuperLu Solver.\n-Definition: superlu.hh:271\n-Dune::SuperLU::nnz\n-SuperLUMatrix::size_type nnz() const\n-Definition: superlu.hh:355\n-Dune::SuperLU::apply\n-void apply(domain_type &x, range_type &b, double reduction,\n-InverseOperatorResult &res)\n-apply inverse operator, with given convergence criteria.\n-Definition: superlu.hh:342\n-Dune::SuperLU::range_type\n-typename Impl::SuperLUVectorChooser< M >::range_type range_type\n-The type of the range of the solver.\n-Definition: superlu.hh:284\n-Dune::SuperLU::matrix_type\n-M matrix_type\n-Definition: superlu.hh:276\n-Dune::SuperLU::MatrixInitializer\n-SuperMatrixInitializer< Matrix > MatrixInitializer\n-Type of an associated initializer class.\n-Definition: superlu.hh:280\n-Dune::SuperLU::Matrix\n-M Matrix\n-The matrix type.\n-Definition: superlu.hh:275\n-Dune::SuperLU::domain_type\n-typename Impl::SuperLUVectorChooser< M >::domain_type domain_type\n-The type of the domain of the solver.\n-Definition: superlu.hh:282\n-Dune::SuperLU::name\n-const char * name()\n-Definition: superlu.hh:371\n-Dune::SuperLU::category\n-virtual SolverCategory::Category category() const\n-Category of the solver (see SolverCategory::Category)\n-Definition: superlu.hh:287\n-Dune::SuperLU::SuperLUMatrix\n-Dune::SuperLUMatrix< Matrix > SuperLUMatrix\n-The corresponding SuperLU Matrix type.\n-Definition: superlu.hh:278\n-Dune::SuperLU::SuperLU\n-SuperLU(const Matrix &mat, const ParameterTree &config)\n-Constructs the SuperLU solver.\n-Definition: superlu.hh:320\n-Dune::SuperLUCreator\n-Definition: superlu.hh:727\n-Dune::SuperLUCreator::operator()\n-std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL\n->::type, typename Dune::TypeListElement< 2, TL >::type > > operator()(TL, const\n-M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock<\n-typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0)\n-const\n-Definition: superlu.hh:734\n-Dune::SuperLUCreator::isValidBlock\n-Definition: superlu.hh:728\n-Dune::GetSuperLUType\n-Definition: supermatrix.hh:132\n-Dune::SuperLUMatrix<_Matrix_>\n-Dune::SuperMatrixInitializer\n-Definition: supermatrix.hh:179\n+Definition: matrixindexset.hh:52\n+Dune::MatrixIndexSet::size_type\n+std::size_t size_type\n+Definition: matrixindexset.hh:19\n+Dune::MatrixIndexSet::exportIdx\n+void exportIdx(MatrixType &matrix) const\n+Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.\n+Definition: matrixindexset.hh:90\n+Dune::MatrixIndexSet::MatrixIndexSet\n+MatrixIndexSet(size_type rows, size_type cols)\n+Constructor setting the matrix size.\n+Definition: matrixindexset.hh:26\n+Dune::MatrixIndexSet::rowsize\n+size_type rowsize(size_type row) const\n+Return the number of entries in a given row.\n+Definition: matrixindexset.hh:56\n+Dune::MatrixIndexSet::size\n+size_type size() const\n+Return the number of entries.\n+Definition: matrixindexset.hh:43\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00209.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00209.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: overlappingschwarz.hh File Reference\n+dune-istl: gsetc.hh File Reference\n \n \n \n \n \n \n \n@@ -65,132 +65,195 @@\n
  • dune
  • istl
  • \n \n \n \n+
    gsetc.hh File Reference
    \n \n
    \n \n-

    Contains one level overlapping Schwarz preconditioners. \n+

    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way. \n More...

    \n-
    #include <cassert>
    \n-#include <algorithm>
    \n-#include <functional>
    \n-#include <memory>
    \n-#include <vector>
    \n-#include <set>
    \n-#include <dune/common/dynmatrix.hh>
    \n-#include <dune/common/sllist.hh>
    \n-#include <dune/istl/bccsmatrixinitializer.hh>
    \n-#include "preconditioners.hh"
    \n-#include "superlu.hh"
    \n-#include "umfpack.hh"
    \n-#include "bvector.hh"
    \n-#include "bcrsmatrix.hh"
    \n-#include "ilusubdomainsolver.hh"
    \n-#include <dune/istl/solvertype.hh>
    \n+
    #include <cmath>
    \n+#include <complex>
    \n+#include <iostream>
    \n+#include <iomanip>
    \n+#include <string>
    \n+#include <dune/common/hybridutilities.hh>
    \n+#include "multitypeblockvector.hh"
    \n+#include "multitypeblockmatrix.hh"
    \n+#include "istlexception.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    class  Dune::OverlappingSchwarzInitializer< I, S, D >
     Initializer for SuperLU Matrices representing the subdomains. More...
    struct  Dune::BL< l >
     compile-time parameter for block recursion depth More...
     
    struct  Dune::AdditiveSchwarzMode
     Tag that the tells the Schwarz method to be additive. More...
    struct  Dune::algmeta_btsolve< I, diag, relax >
     
    struct  Dune::MultiplicativeSchwarzMode
     Tag that tells the Schwarz method to be multiplicative. More...
    struct  Dune::algmeta_btsolve< 0, withdiag, withrelax >
     
    struct  Dune::SymmetricMultiplicativeSchwarzMode
     Tag that tells the Schwarz method to be multiplicative and symmetric. More...
    struct  Dune::algmeta_btsolve< 0, withdiag, norelax >
     
    class  Dune::DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >
    struct  Dune::algmeta_btsolve< 0, nodiag, withrelax >
     
    class  Dune::OverlappingAssignerHelper< T, tag >
    struct  Dune::algmeta_btsolve< 0, nodiag, norelax >
     
    class  Dune::OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false >
    struct  Dune::algmeta_bdsolve< I, relax >
     
    struct  Dune::OverlappingAssignerHelper< S< BCRSMatrix< T, A > >, true >
    struct  Dune::algmeta_bdsolve< 0, withrelax >
     
    class  Dune::OverlappingAssignerILUBase< M, X, Y >
    struct  Dune::algmeta_bdsolve< 0, norelax >
     
    class  Dune::OverlappingAssignerHelper< ILU0SubdomainSolver< M, X, Y >, false >
    struct  Dune::algmeta_itsteps< I, M >
     
    class  Dune::OverlappingAssignerHelper< ILUNSubdomainSolver< M, X, Y >, false >
    struct  Dune::algmeta_itsteps< 0, M >
     
    struct  Dune::AdditiveAdder< S, T >
     
    struct  Dune::AdditiveAdder< S, BlockVector< T, A > >
     
    struct  Dune::MultiplicativeAdder< S, T >
     
    struct  Dune::MultiplicativeAdder< S, BlockVector< T, A > >
     
    struct  Dune::AdderSelector< T, X, S >
     template meta program for choosing how to add the correction. More...
     
    struct  Dune::AdderSelector< AdditiveSchwarzMode, X, S >
     
    struct  Dune::AdderSelector< MultiplicativeSchwarzMode, X, S >
     
    struct  Dune::AdderSelector< SymmetricMultiplicativeSchwarzMode, X, S >
     
    struct  Dune::IteratorDirectionSelector< T1, T2, forward >
     Helper template meta program for application of overlapping Schwarz. More...
     
    struct  Dune::IteratorDirectionSelector< T1, T2, false >
     
    struct  Dune::SeqOverlappingSchwarzApplier< T >
     Helper template meta program for application of overlapping Schwarz. More...
     
    struct  Dune::SeqOverlappingSchwarzApplier< SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< T, tag >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< S< BCRSMatrix< T, A > >, true >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerILUBase< M, X, Y >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< ILU0SubdomainSolver< M, X, Y >, false >
     
    struct  Dune::SeqOverlappingSchwarzAssemblerHelper< ILUNSubdomainSolver< M, X, Y >, false >
     
    class  Dune::SeqOverlappingSchwarz< M, X, TM, TD, TA >
     Sequential overlapping Schwarz preconditioner. More...
     
    struct  Dune::SeqOverlappingSchwarzDomainSize< M >
     
    struct  Dune::SeqOverlappingSchwarzDomainSize< BCRSMatrix< T, A > >
    struct  Dune::algmeta_itsteps< I, MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > >
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+

    \n-Typedefs

    template<typename T >
    using Dune::OverlappingAssigner = OverlappingAssignerHelper< T, Dune::StoresColumnCompressed< T >::value >
     
    template<class T >
    using Dune::SeqOverlappingSchwarzAssembler = SeqOverlappingSchwarzAssemblerHelper< T, Dune::StoresColumnCompressed< T >::value >
     

    \n+Enumerations

    enum  Dune::WithDiagType { Dune::withdiag =1\n+, Dune::nodiag =0\n+ }
     
    enum  Dune::WithRelaxType { Dune::withrelax =1\n+, Dune::norelax =0\n+ }
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<class M , class X , class Y >
    void Dune::bltsolve (const M &A, X &v, const Y &d)
     block lower triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::bltsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed block lower triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::ubltsolve (const M &A, X &v, const Y &d)
     unit block lower triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed unit block lower triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::butsolve (const M &A, X &v, const Y &d)
     block upper triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::butsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed block upper triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::ubutsolve (const M &A, X &v, const Y &d)
     unit block upper triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed unit block upper triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::bltsolve (const M &A, X &v, const Y &d, BL< l >)
     block lower triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     relaxed block lower triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::ubltsolve (const M &A, X &v, const Y &d, BL< l >)
     unit block lower triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     relaxed unit block lower triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::butsolve (const M &A, X &v, const Y &d, BL< l > bl)
     block upper triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::butsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)
     relaxed block upper triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::ubutsolve (const M &A, X &v, const Y &d, BL< l > bl)
     unit block upper triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)
     relaxed unit block upper triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::bdsolve (const M &A, X &v, const Y &d)
     block diagonal solve, no relaxation More...
     
    template<class M , class X , class Y , class K >
    void Dune::bdsolve (const M &A, X &v, const Y &d, const K &w)
     block diagonal solve, with relaxation More...
     
    template<class M , class X , class Y , int l>
    void Dune::bdsolve (const M &A, X &v, const Y &d, BL< l >)
     block diagonal solve, no relaxation More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bdsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     block diagonal solve, with relaxation More...
     
    template<class M , class X , class Y , class K >
    void Dune::dbgs (const M &A, X &x, const Y &b, const K &w)
     GS step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::dbgs (const M &A, X &x, const Y &b, const K &w, BL< l >)
     GS step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::bsorf (const M &A, X &x, const Y &b, const K &w)
     SOR step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bsorf (const M &A, X &x, const Y &b, const K &w, BL< l >)
     SOR step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::bsorb (const M &A, X &x, const Y &b, const K &w)
     SSOR step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bsorb (const M &A, X &x, const Y &b, const K &w, BL< l >)
     Backward SOR step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::dbjac (const M &A, X &x, const Y &b, const K &w)
     Jacobi step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::dbjac (const M &A, X &x, const Y &b, const K &w, BL< l >)
     Jacobi step. More...
     
    \n

    Detailed Description

    \n-

    Contains one level overlapping Schwarz preconditioners.

    \n-
    Author
    Markus Blatt
    \n+

    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,132 +4,175 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Typedefs\n-overlappingschwarz.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n-Contains one level overlapping Schwarz preconditioners. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"preconditioners.hh\"\n-#include \"superlu.hh\"\n-#include \"umfpack.hh\"\n-#include \"bvector.hh\"\n-#include \"bcrsmatrix.hh\"\n-#include \"ilusubdomainsolver.hh\"\n-#include \n+Classes | Namespaces | Enumerations | Functions\n+gsetc.hh File Reference\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way. More...\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"multitypeblockvector.hh\"\n+#include \"multitypeblockmatrix.hh\"\n+#include \"istlexception.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n- class \u00a0Dune::OverlappingSchwarzInitializer<_I,_S,_D_>\n-\u00a0 Initializer for SuperLU Matrices representing the subdomains. More...\n+struct \u00a0Dune::BL<_l_>\n+\u00a0 compile-time parameter for block recursion depth More...\n \u00a0\n-struct \u00a0Dune::AdditiveSchwarzMode\n-\u00a0 Tag that the tells the Schwarz method to be additive. More...\n+struct \u00a0Dune::algmeta_btsolve<_I,_diag,_relax_>\n \u00a0\n-struct \u00a0Dune::MultiplicativeSchwarzMode\n-\u00a0 Tag that tells the Schwarz method to be multiplicative. More...\n+struct \u00a0Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>\n \u00a0\n-struct \u00a0Dune::SymmetricMultiplicativeSchwarzMode\n-\u00a0 Tag that tells the Schwarz method to be multiplicative and symmetric.\n- More...\n+struct \u00a0Dune::algmeta_btsolve<_0,_withdiag,_norelax_>\n \u00a0\n- class \u00a0Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>\n+struct \u00a0Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>\n \u00a0\n- class \u00a0Dune::OverlappingAssignerHelper<_T,_tag_>\n+struct \u00a0Dune::algmeta_btsolve<_0,_nodiag,_norelax_>\n \u00a0\n- class \u00a0Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<\n- BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>\n+struct \u00a0Dune::algmeta_bdsolve<_I,_relax_>\n \u00a0\n-struct \u00a0Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>\n+struct \u00a0Dune::algmeta_bdsolve<_0,_withrelax_>\n \u00a0\n- class \u00a0Dune::OverlappingAssignerILUBase<_M,_X,_Y_>\n+struct \u00a0Dune::algmeta_bdsolve<_0,_norelax_>\n \u00a0\n- class \u00a0Dune::OverlappingAssignerHelper<_ILU0SubdomainSolver<_M,_X,_Y_>,_false\n- >\n+struct \u00a0Dune::algmeta_itsteps<_I,_M_>\n \u00a0\n- class \u00a0Dune::OverlappingAssignerHelper<_ILUNSubdomainSolver<_M,_X,_Y_>,_false\n- >\n+struct \u00a0Dune::algmeta_itsteps<_0,_M_>\n \u00a0\n-struct \u00a0Dune::AdditiveAdder<_S,_T_>\n-\u00a0\n-struct \u00a0Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>\n-\u00a0\n-struct \u00a0Dune::MultiplicativeAdder<_S,_T_>\n-\u00a0\n-struct \u00a0Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>\n-\u00a0\n-struct \u00a0Dune::AdderSelector<_T,_X,_S_>\n-\u00a0 template meta program for choosing how to add the correction. More...\n-\u00a0\n-struct \u00a0Dune::AdderSelector<_AdditiveSchwarzMode,_X,_S_>\n-\u00a0\n-struct \u00a0Dune::AdderSelector<_MultiplicativeSchwarzMode,_X,_S_>\n-\u00a0\n-struct \u00a0Dune::AdderSelector<_SymmetricMultiplicativeSchwarzMode,_X,_S_>\n-\u00a0\n-struct \u00a0Dune::IteratorDirectionSelector<_T1,_T2,_forward_>\n-\u00a0 Helper template meta program for application of overlapping Schwarz.\n- More...\n-\u00a0\n-struct \u00a0Dune::IteratorDirectionSelector<_T1,_T2,_false_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzApplier<_T_>\n-\u00a0 Helper template meta program for application of overlapping Schwarz.\n- More...\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n- SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_T,_tag_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<\n- DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_S<_BCRSMatrix<_T,_A_>_>,\n- true_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerILUBase<_M,_X,_Y_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_ILU0SubdomainSolver<_M,_X,\n- Y_>,_false_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzAssemblerHelper<_ILUNSubdomainSolver<_M,_X,\n- Y_>,_false_>\n-\u00a0\n- class \u00a0Dune::SeqOverlappingSchwarz<_M,_X,_TM,_TD,_TA_>\n-\u00a0 Sequential overlapping Schwarz preconditioner. More...\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzDomainSize<_M_>\n-\u00a0\n-struct \u00a0Dune::SeqOverlappingSchwarzDomainSize<_BCRSMatrix<_T,_A_>_>\n+struct \u00a0Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,\n+ MultiTypeMatrixArgs..._>_>\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Typedefs\n-template\n-using\u00a0Dune::OverlappingAssigner = OverlappingAssignerHelper< T, Dune::\n- StoresColumnCompressed< T >::value >\n-\u00a0\n-template\n-using\u00a0Dune::SeqOverlappingSchwarzAssembler =\n- SeqOverlappingSchwarzAssemblerHelper< T, Dune::StoresColumnCompressed< T\n- >::value >\n+ Enumerations\n+enum \u00a0Dune::WithDiagType { Dune::withdiag =1 , Dune::nodiag =0 }\n+\u00a0\n+enum \u00a0Dune::WithRelaxType { Dune::withrelax =1 , Dune::norelax =0 }\n+\u00a0\n+ Functions\n+template\n+void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d)\n+\u00a0 block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, const K &w)\n+\u00a0 relaxed block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d)\n+\u00a0 unit block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w)\n+\u00a0 relaxed unit block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::butsolve (const M &A, X &v, const Y &d)\n+\u00a0 block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, const K &w)\n+\u00a0 relaxed block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d)\n+\u00a0 unit block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w)\n+\u00a0 relaxed unit block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, BL< l >)\n+\u00a0 block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n+\u00a0 relaxed block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, BL< l >)\n+\u00a0 unit block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n+\u00a0 relaxed unit block lower triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, BL< l > bl)\n+\u00a0 block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)\n+\u00a0 relaxed block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, BL< l > bl)\n+\u00a0 unit block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)\n+\u00a0 relaxed unit block upper triangular solve More...\n+\u00a0\n+template\n+void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d)\n+\u00a0 block diagonal solve, no relaxation More...\n+\u00a0\n+template\n+void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, const K &w)\n+\u00a0 block diagonal solve, with relaxation More...\n+\u00a0\n+template\n+void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, BL< l >)\n+\u00a0 block diagonal solve, no relaxation More...\n+\u00a0\n+template\n+void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n+\u00a0 block diagonal solve, with relaxation More...\n+\u00a0\n+template\n+void\u00a0Dune::dbgs (const M &A, X &x, const Y &b, const K &w)\n+\u00a0 GS step. More...\n+\u00a0\n+template\n+void\u00a0Dune::dbgs (const M &A, X &x, const Y &b, const K &w, BL< l >)\n+\u00a0 GS step. More...\n+\u00a0\n+template\n+void\u00a0Dune::bsorf (const M &A, X &x, const Y &b, const K &w)\n+\u00a0 SOR step. More...\n+\u00a0\n+template\n+void\u00a0Dune::bsorf (const M &A, X &x, const Y &b, const K &w, BL< l >)\n+\u00a0 SOR step. More...\n+\u00a0\n+template\n+void\u00a0Dune::bsorb (const M &A, X &x, const Y &b, const K &w)\n+\u00a0 SSOR step. More...\n+\u00a0\n+template\n+void\u00a0Dune::bsorb (const M &A, X &x, const Y &b, const K &w, BL< l >)\n+\u00a0 Backward SOR step. More...\n+\u00a0\n+template\n+void\u00a0Dune::dbjac (const M &A, X &x, const Y &b, const K &w)\n+\u00a0 Jacobi step. More...\n+\u00a0\n+template\n+void\u00a0Dune::dbjac (const M &A, X &x, const Y &b, const K &w, BL< l >)\n+\u00a0 Jacobi step. More...\n \u00a0\n ***** Detailed Description *****\n-Contains one level overlapping Schwarz preconditioners.\n- Author\n- Markus Blatt\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00209_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00209_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: overlappingschwarz.hh Source File\n+dune-istl: gsetc.hh Source File\n \n \n \n \n \n \n \n@@ -62,1450 +62,701 @@\n \n
    \n \n
    \n
    \n
    \n-
    overlappingschwarz.hh
    \n+
    gsetc.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_OVERLAPPINGSCHWARZ_HH
    \n-
    6#define DUNE_ISTL_OVERLAPPINGSCHWARZ_HH
    \n-
    7#include <cassert>
    \n-
    8#include <algorithm>
    \n-
    9#include <functional>
    \n-
    10#include <memory>
    \n-
    11#include <vector>
    \n-
    12#include <set>
    \n-
    13#include <dune/common/dynmatrix.hh>
    \n-
    14#include <dune/common/sllist.hh>
    \n+
    5#ifndef DUNE_ISTL_GSETC_HH
    \n+
    6#define DUNE_ISTL_GSETC_HH
    \n+
    7
    \n+
    8#include <cmath>
    \n+
    9#include <complex>
    \n+
    10#include <iostream>
    \n+
    11#include <iomanip>
    \n+
    12#include <string>
    \n+
    13
    \n+
    14#include <dune/common/hybridutilities.hh>
    \n
    15
    \n-\n-
    17#include "preconditioners.hh"
    \n-
    18#include "superlu.hh"
    \n-
    19#include "umfpack.hh"
    \n-
    20#include "bvector.hh"
    \n-
    21#include "bcrsmatrix.hh"
    \n-
    22#include "ilusubdomainsolver.hh"
    \n-\n-
    24
    \n-
    25namespace Dune
    \n-
    26{
    \n-
    27
    \n-
    39 template<class M, class X, class TM, class TD, class TA>
    \n-
    40 class SeqOverlappingSchwarz;
    \n-
    41
    \n-
    45 template<class I, class S, class D>
    \n-\n-
    47 {
    \n-
    48 public:
    \n-\n-
    51
    \n-
    52 typedef I InitializerList;
    \n-
    53 typedef typename InitializerList::value_type AtomInitializer;
    \n-
    54 typedef typename AtomInitializer::Matrix Matrix;
    \n-
    55 typedef typename Matrix::const_iterator Iter;
    \n-
    56 typedef typename Matrix::row_type::const_iterator CIter;
    \n-
    57
    \n-
    58 typedef S IndexSet;
    \n-
    59 typedef typename IndexSet::size_type size_type;
    \n-
    60
    \n-\n-
    62 const IndexSet& indices,
    \n-
    63 const subdomain_vector& domains);
    \n-
    64
    \n-
    65
    \n-
    66 void addRowNnz(const Iter& row);
    \n-
    67
    \n-
    68 void allocate();
    \n-
    69
    \n-
    70 void countEntries(const Iter& row, const CIter& col) const;
    \n-
    71
    \n-
    72 void calcColstart() const;
    \n-
    73
    \n-
    74 void copyValue(const Iter& row, const CIter& col) const;
    \n-
    75
    \n-
    76 void createMatrix() const;
    \n-
    77 private:
    \n-
    78 class IndexMap
    \n-
    79 {
    \n-
    80 public:
    \n-
    81 typedef typename S::size_type size_type;
    \n-
    82 typedef std::map<size_type,size_type> Map;
    \n-
    83 typedef typename Map::iterator iterator;
    \n-
    84 typedef typename Map::const_iterator const_iterator;
    \n-
    85
    \n-
    86 IndexMap();
    \n-
    87
    \n-
    88 void insert(size_type grow);
    \n-
    89
    \n-
    90 const_iterator find(size_type grow) const;
    \n-
    91
    \n-
    92 iterator find(size_type grow);
    \n-
    93
    \n-
    94 iterator begin();
    \n-
    95
    \n-
    96 const_iterator begin() const;
    \n-
    97
    \n-
    98 iterator end();
    \n-
    99
    \n-
    100 const_iterator end() const;
    \n-
    101
    \n-
    102 private:
    \n-
    103 std::map<size_type,size_type> map_;
    \n-
    104 size_type row;
    \n-
    105 };
    \n-
    106
    \n-
    107
    \n-
    108 typedef typename InitializerList::iterator InitIterator;
    \n-
    109 typedef typename IndexSet::const_iterator IndexIteratur;
    \n-
    110 InitializerList* initializers;
    \n-
    111 const IndexSet *indices;
    \n-
    112 mutable std::vector<IndexMap> indexMaps;
    \n-
    113 const subdomain_vector& domains;
    \n-
    114 };
    \n-
    115
    \n-\n-
    120 {};
    \n-
    121
    \n-\n-
    126 {};
    \n-
    127
    \n-\n-
    133 {};
    \n-
    134
    \n-
    139 template<class M, class X, class Y>
    \n-\n-
    141
    \n-
    142 // Specialization for BCRSMatrix
    \n-
    143 template<class K, class Al, class X, class Y>
    \n-\n-
    145 {
    \n-
    146 typedef BCRSMatrix< K, Al> M;
    \n-
    147 public:
    \n-
    149 typedef typename std::remove_const<M>::type matrix_type;
    \n-
    150 typedef typename X::field_type field_type;
    \n-
    151 typedef typename std::remove_const<M>::type rilu_type;
    \n-
    153 typedef X domain_type;
    \n-
    155 typedef Y range_type;
    \n-
    156 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n-
    157
    \n-
    162 void apply (DynamicVector<field_type>& v, DynamicVector<field_type>& d)
    \n+\n+\n+
    18
    \n+
    19#include "istlexception.hh"
    \n+
    20
    \n+
    21
    \n+
    27namespace Dune {
    \n+
    28
    \n+
    39 //============================================================
    \n+
    40 // parameter types
    \n+
    41 //============================================================
    \n+
    42
    \n+
    44 template<int l>
    \n+
    45 struct BL {
    \n+
    46 enum {recursion_level = l};
    \n+
    47 };
    \n+
    48
    \n+\n+\n+
    51 nodiag=0
    \n+
    52 };
    \n+
    53
    \n+\n+\n+
    56 norelax=0
    \n+
    57 };
    \n+
    58
    \n+
    59 //============================================================
    \n+
    60 // generic triangular solves
    \n+
    61 // consider block decomposition A = L + D + U
    \n+
    62 // we can invert L, L+D, U, U+D
    \n+
    63 // we can apply relaxation or not
    \n+
    64 // we can recurse over a fixed number of levels
    \n+
    65 //============================================================
    \n+
    66
    \n+
    67 // template meta program for triangular solves
    \n+
    68 template<int I, WithDiagType diag, WithRelaxType relax>
    \n+\n+
    70 template<class M, class X, class Y, class K>
    \n+
    71 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    72 {
    \n+
    73 // iterator types
    \n+
    74 typedef typename M::ConstRowIterator rowiterator;
    \n+
    75 typedef typename M::ConstColIterator coliterator;
    \n+
    76 typedef typename Y::block_type bblock;
    \n+
    77
    \n+
    78 // local solve at each block and immediate update
    \n+
    79 rowiterator endi=A.end();
    \n+
    80 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    81 {
    \n+
    82 bblock rhs(d[i.index()]);
    \n+
    83 coliterator j;
    \n+
    84 for (j=(*i).begin(); j.index()<i.index(); ++j)
    \n+
    85 (*j).mmv(v[j.index()],rhs);
    \n+
    86 algmeta_btsolve<I-1,diag,relax>::bltsolve(*j,v[i.index()],rhs,w);
    \n+
    87 }
    \n+
    88 }
    \n+
    89 template<class M, class X, class Y, class K>
    \n+
    90 static void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    91 {
    \n+
    92 // iterator types
    \n+
    93 typedef typename M::ConstRowIterator rowiterator;
    \n+
    94 typedef typename M::ConstColIterator coliterator;
    \n+
    95 typedef typename Y::block_type bblock;
    \n+
    96
    \n+
    97 // local solve at each block and immediate update
    \n+
    98 rowiterator rendi=A.beforeBegin();
    \n+
    99 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n+
    100 {
    \n+
    101 bblock rhs(d[i.index()]);
    \n+
    102 coliterator j;
    \n+
    103 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)
    \n+
    104 (*j).mmv(v[j.index()],rhs);
    \n+
    105 algmeta_btsolve<I-1,diag,relax>::butsolve(*j,v[i.index()],rhs,w);
    \n+
    106 }
    \n+
    107 }
    \n+
    108 };
    \n+
    109
    \n+
    110 // recursion end ...
    \n+
    111 template<>
    \n+\n+
    113 template<class M, class X, class Y, class K>
    \n+
    114 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    115 {
    \n+
    116 A.solve(v,d);
    \n+
    117 v *= w;
    \n+
    118 }
    \n+
    119 template<class M, class X, class Y, class K>
    \n+
    120 static void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    121 {
    \n+
    122 A.solve(v,d);
    \n+
    123 v *= w;
    \n+
    124 }
    \n+
    125 };
    \n+
    126 template<>
    \n+\n+
    128 template<class M, class X, class Y, class K>
    \n+
    129 static void bltsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n+
    130 {
    \n+
    131 A.solve(v,d);
    \n+
    132 }
    \n+
    133 template<class M, class X, class Y, class K>
    \n+
    134 static void butsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n+
    135 {
    \n+
    136 A.solve(v,d);
    \n+
    137 }
    \n+
    138 };
    \n+
    139 template<>
    \n+\n+
    141 template<class M, class X, class Y, class K>
    \n+
    142 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& w)
    \n+
    143 {
    \n+
    144 v = d;
    \n+
    145 v *= w;
    \n+
    146 }
    \n+
    147 template<class M, class X, class Y, class K>
    \n+
    148 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& w)
    \n+
    149 {
    \n+
    150 v = d;
    \n+
    151 v *= w;
    \n+
    152 }
    \n+
    153 };
    \n+
    154 template<>
    \n+\n+
    156 template<class M, class X, class Y, class K>
    \n+
    157 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
    \n+
    158 {
    \n+
    159 v = d;
    \n+
    160 }
    \n+
    161 template<class M, class X, class Y, class K>
    \n+
    162 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
    \n
    163 {
    \n-
    164 assert(v.size() > 0);
    \n-
    165 assert(v.size() == d.size());
    \n-
    166 assert(A.rows() <= v.size());
    \n-
    167 assert(A.cols() <= v.size());
    \n-
    168 size_t sz = A.rows();
    \n-
    169 v.resize(sz);
    \n-
    170 d.resize(sz);
    \n-
    171 A.solve(v,d);
    \n-
    172 v.resize(v.capacity());
    \n-
    173 d.resize(d.capacity());
    \n-
    174 }
    \n-
    175
    \n-
    183 template<class S>
    \n-
    184 void setSubMatrix(const M& BCRS, S& rowset)
    \n-
    185 {
    \n-
    186 size_t sz = rowset.size();
    \n-
    187 A.resize(sz*n,sz*n);
    \n-
    188 typedef typename S::const_iterator SIter;
    \n-
    189 size_t r = 0, c = 0;
    \n-
    190 for(SIter rowIdx = rowset.begin(), rowEnd=rowset.end();
    \n-
    191 rowIdx!= rowEnd; ++rowIdx, r++)
    \n-
    192 {
    \n-
    193 c = 0;
    \n-
    194 for(SIter colIdx = rowset.begin(), colEnd=rowset.end();
    \n-
    195 colIdx!= colEnd; ++colIdx, c++)
    \n-
    196 {
    \n-
    197 if (BCRS[*rowIdx].find(*colIdx) == BCRS[*rowIdx].end())
    \n-
    198 continue;
    \n-
    199 for (size_t i=0; i<n; i++)
    \n-
    200 {
    \n-
    201 for (size_t j=0; j<n; j++)
    \n-
    202 {
    \n-
    203 A[r*n+i][c*n+j] = Impl::asMatrix(BCRS[*rowIdx][*colIdx])[i][j];
    \n-
    204 }
    \n-
    205 }
    \n-
    206 }
    \n-
    207 }
    \n-
    208 }
    \n-
    209 private:
    \n-
    210 DynamicMatrix<K> A;
    \n-
    211 };
    \n-
    212
    \n-
    213 template<typename T, bool tag>
    \n-\n-
    215 {};
    \n-
    216
    \n-
    217 template<typename T>
    \n-\n-
    219
    \n-
    220 // specialization for DynamicMatrix
    \n-
    221 template<class K, class Al, class X, class Y>
    \n-\n+
    164 v = d;
    \n+
    165 }
    \n+
    166 };
    \n+
    167
    \n+
    168
    \n+
    169 // user calls
    \n+
    170
    \n+
    171 // default block recursion level = 1
    \n+
    172
    \n+
    174 template<class M, class X, class Y>
    \n+
    175 void bltsolve (const M& A, X& v, const Y& d)
    \n+
    176 {
    \n+
    177 typename X::field_type w=1;
    \n+\n+
    179 }
    \n+
    181 template<class M, class X, class Y, class K>
    \n+
    182 void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    183 {
    \n+\n+
    185 }
    \n+
    187 template<class M, class X, class Y>
    \n+
    188 void ubltsolve (const M& A, X& v, const Y& d)
    \n+
    189 {
    \n+
    190 typename X::field_type w=1;
    \n+\n+
    192 }
    \n+
    194 template<class M, class X, class Y, class K>
    \n+
    195 void ubltsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    196 {
    \n+\n+
    198 }
    \n+
    199
    \n+
    201 template<class M, class X, class Y>
    \n+
    202 void butsolve (const M& A, X& v, const Y& d)
    \n+
    203 {
    \n+
    204 typename X::field_type w=1;
    \n+\n+
    206 }
    \n+
    208 template<class M, class X, class Y, class K>
    \n+
    209 void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    210 {
    \n+\n+
    212 }
    \n+
    214 template<class M, class X, class Y>
    \n+
    215 void ubutsolve (const M& A, X& v, const Y& d)
    \n+
    216 {
    \n+
    217 typename X::field_type w=1;
    \n+\n+
    219 }
    \n+
    221 template<class M, class X, class Y, class K>
    \n+
    222 void ubutsolve (const M& A, X& v, const Y& d, const K& w)
    \n
    223 {
    \n-
    224 public:
    \n-\n-
    226 typedef typename X::field_type field_type;
    \n-
    227 typedef Y range_type;
    \n-
    228 typedef typename range_type::block_type block_type;
    \n-\n-
    230 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n-
    238 OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix<K, Al>& mat_, const X& b_, Y& x_);
    \n-
    239
    \n-
    243 inline
    \n-
    244 void deallocate();
    \n-
    245
    \n-
    249 inline
    \n-
    250 void resetIndexForNextDomain();
    \n-
    251
    \n-
    256 inline
    \n-
    257 DynamicVector<field_type> & lhs();
    \n-
    258
    \n-
    263 inline
    \n-
    264 DynamicVector<field_type> & rhs();
    \n-
    265
    \n-
    270 inline
    \n-
    271 void relaxResult(field_type relax);
    \n-
    272
    \n-
    277 void operator()(const size_type& domainIndex);
    \n-
    278
    \n-
    286 inline
    \n-
    287 void assignResult(block_type& res);
    \n-
    288
    \n-
    289 private:
    \n-
    293 const matrix_type* mat;
    \n-
    295 // we need a pointer, because we have to avoid deep copies
    \n-
    296 DynamicVector<field_type> * rhs_;
    \n-
    298 // we need a pointer, because we have to avoid deep copies
    \n-
    299 DynamicVector<field_type> * lhs_;
    \n-
    301 const range_type* b;
    \n-
    303 range_type* x;
    \n-
    305 std::size_t i;
    \n-
    307 std::size_t maxlength_;
    \n-
    308 };
    \n-
    309
    \n-
    310#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    311 template<template<class> class S, typename T, typename A>
    \n-\n-
    313 {
    \n-\n-
    315 typedef typename S<BCRSMatrix<T, A>>::range_type range_type;
    \n-
    316 typedef typename range_type::field_type field_type;
    \n-
    317 typedef typename range_type::block_type block_type;
    \n-
    318
    \n-\n-
    320
    \n-
    321 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n-
    322 static constexpr size_t m = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::cols;
    \n-
    330 OverlappingAssignerHelper(std::size_t maxlength, const matrix_type& mat,
    \n-
    331 const range_type& b, range_type& x);
    \n-
    337 void deallocate();
    \n-
    338
    \n-
    339 /*
    \n-
    340 * @brief Resets the local index to zero.
    \n-
    341 */
    \n-
    342 void resetIndexForNextDomain();
    \n-
    343
    \n-
    348 field_type* lhs();
    \n-
    349
    \n-
    354 field_type* rhs();
    \n-
    355
    \n-
    360 void relaxResult(field_type relax);
    \n-
    361
    \n-
    366 void operator()(const size_type& domain);
    \n-
    367
    \n-
    375 void assignResult(block_type& res);
    \n+\n+
    225 }
    \n+
    226
    \n+
    227 // general block recursion level >= 0
    \n+
    228
    \n+
    230 template<class M, class X, class Y, int l>
    \n+
    231 void bltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n+
    232 {
    \n+
    233 typename X::field_type w=1;
    \n+\n+
    235 }
    \n+
    237 template<class M, class X, class Y, class K, int l>
    \n+
    238 void bltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n+
    239 {
    \n+\n+
    241 }
    \n+
    243 template<class M, class X, class Y, int l>
    \n+
    244 void ubltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n+
    245 {
    \n+
    246 typename X::field_type w=1;
    \n+\n+
    248 }
    \n+
    250 template<class M, class X, class Y, class K, int l>
    \n+
    251 void ubltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n+
    252 {
    \n+\n+
    254 }
    \n+
    255
    \n+
    257 template<class M, class X, class Y, int l>
    \n+
    258 void butsolve (const M& A, X& v, const Y& d, BL<l> bl)
    \n+
    259 {
    \n+
    260 typename X::field_type w=1;
    \n+\n+
    262 }
    \n+
    264 template<class M, class X, class Y, class K, int l>
    \n+
    265 void butsolve (const M& A, X& v, const Y& d, const K& w, BL<l> bl)
    \n+
    266 {
    \n+\n+
    268 }
    \n+
    270 template<class M, class X, class Y, int l>
    \n+
    271 void ubutsolve (const M& A, X& v, const Y& d, BL<l> bl)
    \n+
    272 {
    \n+
    273 typename X::field_type w=1;
    \n+\n+
    275 }
    \n+
    277 template<class M, class X, class Y, class K, int l>
    \n+
    278 void ubutsolve (const M& A, X& v, const Y& d, const K& w, BL<l> bl)
    \n+
    279 {
    \n+\n+
    281 }
    \n+
    282
    \n+
    283
    \n+
    284
    \n+
    285 //============================================================
    \n+
    286 // generic block diagonal solves
    \n+
    287 // consider block decomposition A = L + D + U
    \n+
    288 // we can apply relaxation or not
    \n+
    289 // we can recurse over a fixed number of levels
    \n+
    290 //============================================================
    \n+
    291
    \n+
    292 // template meta program for diagonal solves
    \n+
    293 template<int I, WithRelaxType relax>
    \n+\n+
    295 template<class M, class X, class Y, class K>
    \n+
    296 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    297 {
    \n+
    298 // iterator types
    \n+
    299 typedef typename M::ConstRowIterator rowiterator;
    \n+
    300 typedef typename M::ConstColIterator coliterator;
    \n+
    301
    \n+
    302 // local solve at each block and immediate update
    \n+
    303 rowiterator rendi=A.beforeBegin();
    \n+
    304 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n+
    305 {
    \n+
    306 coliterator ii=(*i).find(i.index());
    \n+
    307 algmeta_bdsolve<I-1,relax>::bdsolve(*ii,v[i.index()],d[i.index()],w);
    \n+
    308 }
    \n+
    309 }
    \n+
    310 };
    \n+
    311
    \n+
    312 // recursion end ...
    \n+
    313 template<>
    \n+\n+
    315 template<class M, class X, class Y, class K>
    \n+
    316 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    317 {
    \n+
    318 A.solve(v,d);
    \n+
    319 v *= w;
    \n+
    320 }
    \n+
    321 };
    \n+
    322 template<>
    \n+\n+
    324 template<class M, class X, class Y, class K>
    \n+
    325 static void bdsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n+
    326 {
    \n+
    327 A.solve(v,d);
    \n+
    328 }
    \n+
    329 };
    \n+
    330
    \n+
    331 // user calls
    \n+
    332
    \n+
    333 // default block recursion level = 1
    \n+
    334
    \n+
    336 template<class M, class X, class Y>
    \n+
    337 void bdsolve (const M& A, X& v, const Y& d)
    \n+
    338 {
    \n+
    339 typename X::field_type w=1;
    \n+\n+
    341 }
    \n+
    343 template<class M, class X, class Y, class K>
    \n+
    344 void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n+
    345 {
    \n+\n+
    347 }
    \n+
    348
    \n+
    349 // general block recursion level >= 0
    \n+
    350
    \n+
    352 template<class M, class X, class Y, int l>
    \n+
    353 void bdsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n+
    354 {
    \n+
    355 typename X::field_type w=1;
    \n+\n+
    357 }
    \n+
    359 template<class M, class X, class Y, class K, int l>
    \n+
    360 void bdsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n+
    361 {
    \n+\n+
    363 }
    \n+
    364
    \n+
    365
    \n+
    366 //============================================================
    \n+
    367 // generic steps of iteration methods
    \n+
    368 // Jacobi, Gauss-Seidel, SOR, SSOR
    \n+
    369 // work directly on Ax=b, ie solve M(x^{i+1}-x^i) = w (b-Ax^i)
    \n+
    370 // we can recurse over a fixed number of levels
    \n+
    371 //============================================================
    \n+
    372
    \n+
    373 // template meta program for iterative solver steps
    \n+
    374 template<int I, typename M>
    \n+\n
    376
    \n-
    377 private:
    \n-
    381 const matrix_type* mat;
    \n-
    383 field_type* rhs_;
    \n-
    385 field_type* lhs_;
    \n-
    387 const range_type* b;
    \n-
    389 range_type* x;
    \n-
    391 std::size_t i;
    \n-
    393 std::size_t maxlength_;
    \n-
    394 };
    \n-
    395
    \n-
    396#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    397
    \n-
    398 template<class M, class X, class Y>
    \n-\n-
    400 {
    \n-
    401 public:
    \n-
    402 typedef M matrix_type;
    \n-
    403
    \n-
    404 typedef typename Y::field_type field_type;
    \n-
    405
    \n-
    406 typedef typename Y::block_type block_type;
    \n-
    407
    \n-
    408 typedef typename matrix_type::size_type size_type;
    \n-
    416 OverlappingAssignerILUBase(std::size_t maxlength, const M& mat,
    \n-
    417 const Y& b, X& x);
    \n-
    423 void deallocate();
    \n-
    424
    \n-\n-
    429
    \n-
    434 X& lhs();
    \n-
    435
    \n-
    440 Y& rhs();
    \n-
    441
    \n-
    446 void relaxResult(field_type relax);
    \n-
    447
    \n-
    452 void operator()(const size_type& domain);
    \n-
    453
    \n-
    461 void assignResult(block_type& res);
    \n-
    462
    \n-
    463 private:
    \n-
    467 const M* mat;
    \n-
    469 X* lhs_;
    \n-
    471 Y* rhs_;
    \n-
    473 const Y* b;
    \n-
    475 X* x;
    \n-
    477 size_type i;
    \n-
    478 };
    \n-
    479
    \n-
    480 // specialization for ILU0
    \n-
    481 template<class M, class X, class Y>
    \n-\n-
    483 : public OverlappingAssignerILUBase<M,X,Y>
    \n-
    484 {
    \n-
    485 public:
    \n-
    493 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,
    \n-
    494 const Y& b, X& x)
    \n-
    495 : OverlappingAssignerILUBase<M,X,Y>(maxlength, mat,b,x)
    \n-
    496 {}
    \n-
    497 };
    \n-
    498
    \n-
    499 // specialization for ILUN
    \n-
    500 template<class M, class X, class Y>
    \n-\n-
    502 : public OverlappingAssignerILUBase<M,X,Y>
    \n-
    503 {
    \n-
    504 public:
    \n-
    512 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,
    \n-
    513 const Y& b, X& x)
    \n-
    514 : OverlappingAssignerILUBase<M,X,Y>(maxlength, mat,b,x)
    \n-
    515 {}
    \n-
    516 };
    \n-
    517
    \n-
    518 template<typename S, typename T>
    \n-\n-
    520 {};
    \n-
    521
    \n-
    522 template<typename S, typename T, typename A>
    \n-
    523 struct AdditiveAdder<S, BlockVector<T,A> >
    \n-
    524 {
    \n-
    525 typedef typename A::size_type size_type;
    \n-
    526 typedef typename std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::field_type field_type;
    \n-\n-
    528 OverlappingAssigner<S>& assigner, const field_type& relax_);
    \n-
    529 void operator()(const size_type& domain);
    \n-
    530 void axpy();
    \n-
    531 static constexpr size_t n = std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::dimension;
    \n-
    532
    \n-
    533 private:
    \n-\n-\n-
    536 OverlappingAssigner<S>* assigner;
    \n-
    537 field_type relax;
    \n-
    538 };
    \n-
    539
    \n-
    540 template<typename S,typename T>
    \n-\n-
    542 {};
    \n-
    543
    \n-
    544 template<typename S, typename T, typename A>
    \n-\n-
    546 {
    \n-
    547 typedef typename A::size_type size_type;
    \n-
    548 typedef typename std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::field_type field_type;
    \n-\n-
    550 OverlappingAssigner<S>& assigner_, const field_type& relax_);
    \n-
    551 void operator()(const size_type& domain);
    \n-
    552 void axpy();
    \n-
    553 static constexpr size_t n = std::decay_t<decltype(Impl::asVector(std::declval<T>()))>::dimension;
    \n-
    554
    \n-
    555 private:
    \n-\n-
    557 OverlappingAssigner<S>* assigner;
    \n-
    558 field_type relax;
    \n-
    559 };
    \n-
    560
    \n-
    570 template<typename T, class X, class S>
    \n-\n-
    572 {};
    \n-
    573
    \n-
    574 template<class X, class S>
    \n-\n-
    576 {
    \n-\n-
    578 };
    \n+
    377 template<class X, class Y, class K>
    \n+
    378 static void dbgs (const M& A, X& x, const Y& b, const K& w)
    \n+
    379 {
    \n+
    380 typedef typename M::ConstRowIterator rowiterator;
    \n+
    381 typedef typename M::ConstColIterator coliterator;
    \n+
    382 typedef typename Y::block_type bblock;
    \n+
    383 bblock rhs;
    \n+
    384
    \n+
    385 X xold(x); // remember old x
    \n+
    386
    \n+
    387 rowiterator endi=A.end();
    \n+
    388 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    389 {
    \n+
    390 rhs = b[i.index()]; // rhs = b_i
    \n+
    391 coliterator endj=(*i).end();
    \n+
    392 coliterator j=(*i).begin();
    \n+
    393 if constexpr (IsNumber<typename M::block_type>())
    \n+
    394 {
    \n+
    395 for (; j.index()<i.index(); ++j)
    \n+
    396 rhs -= (*j) * x[j.index()];
    \n+
    397 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
    \n+
    398 for (; j != endj; ++j)
    \n+
    399 rhs -= (*j) * x[j.index()];
    \n+
    400 x[i.index()] = rhs / (*diag);
    \n+
    401 }
    \n+
    402 else
    \n+
    403 {
    \n+
    404 for (; j.index()<i.index(); ++j) // iterate over a_ij with j < i
    \n+
    405 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    406 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
    \n+
    407 for (; j != endj; ++j) // iterate over a_ij with j > i
    \n+
    408 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j>i} a_ij * xold_j
    \n+
    409 algmeta_itsteps<I-1,typename M::block_type>::dbgs(*diag,x[i.index()],rhs,w); // if I==1: xnew_i = rhs/a_ii
    \n+
    410 }
    \n+
    411 }
    \n+
    412 // next two lines: xnew_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j) + (1-w)*xold;
    \n+
    413 x *= w;
    \n+
    414 x.axpy(K(1)-w,xold);
    \n+
    415 }
    \n+
    416
    \n+
    417 template<class X, class Y, class K>
    \n+
    418 static void bsorf (const M& A, X& x, const Y& b, const K& w)
    \n+
    419 {
    \n+
    420 typedef typename M::ConstRowIterator rowiterator;
    \n+
    421 typedef typename M::ConstColIterator coliterator;
    \n+
    422 typedef typename Y::block_type bblock;
    \n+
    423 typedef typename X::block_type xblock;
    \n+
    424 bblock rhs;
    \n+
    425 xblock v;
    \n+
    426
    \n+
    427 // Initialize nested data structure if there are entries
    \n+
    428 if(A.begin()!=A.end())
    \n+
    429 v=x[0];
    \n+
    430
    \n+
    431 rowiterator endi=A.end();
    \n+
    432 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    433 {
    \n+
    434 rhs = b[i.index()]; // rhs = b_i
    \n+
    435 coliterator endj=(*i).end(); // iterate over a_ij with j < i
    \n+
    436 coliterator j=(*i).begin();
    \n+
    437 if constexpr (IsNumber<typename M::block_type>())
    \n+
    438 {
    \n+
    439 for (; j.index()<i.index(); ++j)
    \n+
    440 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    441 coliterator diag=j; // *diag = a_ii
    \n+
    442 for (; j!=endj; ++j)
    \n+
    443 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    444 v = rhs / (*diag);
    \n+
    445 x[i.index()] += w*v; // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
    \n+
    446 }
    \n+
    447 else
    \n+
    448 {
    \n+
    449 for (; j.index()<i.index(); ++j)
    \n+
    450 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    451 coliterator diag=j; // *diag = a_ii
    \n+
    452 for (; j!=endj; ++j)
    \n+
    453 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n+
    454 algmeta_itsteps<I-1,typename M::block_type>::bsorf(*diag,v,rhs,w); // if blocksize I==1: v = rhs/a_ii
    \n+
    455 x[i.index()].axpy(w,v); // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
    \n+
    456 }
    \n+
    457 }
    \n+
    458 }
    \n+
    459
    \n+
    460 template<class X, class Y, class K>
    \n+
    461 static void bsorb (const M& A, X& x, const Y& b, const K& w)
    \n+
    462 {
    \n+
    463 typedef typename M::ConstRowIterator rowiterator;
    \n+
    464 typedef typename M::ConstColIterator coliterator;
    \n+
    465 typedef typename Y::block_type bblock;
    \n+
    466 typedef typename X::block_type xblock;
    \n+
    467 bblock rhs;
    \n+
    468 xblock v;
    \n+
    469
    \n+
    470 // Initialize nested data structure if there are entries
    \n+
    471 if(A.begin()!=A.end())
    \n+
    472 v=x[0];
    \n+
    473
    \n+
    474 rowiterator endi=A.beforeBegin();
    \n+
    475 for (rowiterator i=A.beforeEnd(); i!=endi; --i)
    \n+
    476 {
    \n+
    477 rhs = b[i.index()];
    \n+
    478 coliterator endj=(*i).end();
    \n+
    479 coliterator j=(*i).begin();
    \n+
    480 if constexpr (IsNumber<typename M::block_type>())
    \n+
    481 {
    \n+
    482 for (; j.index()<i.index(); ++j)
    \n+
    483 rhs -= (*j) * x[j.index()];
    \n+
    484 coliterator diag=j;
    \n+
    485 for (; j!=endj; ++j)
    \n+
    486 rhs -= (*j) * x[j.index()];
    \n+
    487 v = rhs / (*diag);
    \n+
    488 x[i.index()] += w*v;
    \n+
    489 }
    \n+
    490 else
    \n+
    491 {
    \n+
    492 for (; j.index()<i.index(); ++j)
    \n+
    493 j->mmv(x[j.index()],rhs);
    \n+
    494 coliterator diag=j;
    \n+
    495 for (; j!=endj; ++j)
    \n+
    496 j->mmv(x[j.index()],rhs);
    \n+\n+
    498 x[i.index()].axpy(w,v);
    \n+
    499 }
    \n+
    500 }
    \n+
    501 }
    \n+
    502
    \n+
    503 template<class X, class Y, class K>
    \n+
    504 static void dbjac (const M& A, X& x, const Y& b, const K& w)
    \n+
    505 {
    \n+
    506 typedef typename M::ConstRowIterator rowiterator;
    \n+
    507 typedef typename M::ConstColIterator coliterator;
    \n+
    508 typedef typename Y::block_type bblock;
    \n+
    509 bblock rhs;
    \n+
    510
    \n+
    511 X v(x); // allocate with same size
    \n+
    512
    \n+
    513 rowiterator endi=A.end();
    \n+
    514 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    515 {
    \n+
    516 rhs = b[i.index()];
    \n+
    517 coliterator endj=(*i).end();
    \n+
    518 coliterator j=(*i).begin();
    \n+
    519 if constexpr (IsNumber<typename M::block_type>())
    \n+
    520 {
    \n+
    521 for (; j.index()<i.index(); ++j)
    \n+
    522 rhs -= (*j) * x[j.index()];
    \n+
    523 coliterator diag=j;
    \n+
    524 for (; j!=endj; ++j)
    \n+
    525 rhs -= (*j) * x[j.index()];
    \n+
    526 v[i.index()] = rhs / (*diag);
    \n+
    527 }
    \n+
    528 else
    \n+
    529 {
    \n+
    530 for (; j.index()<i.index(); ++j)
    \n+
    531 j->mmv(x[j.index()],rhs);
    \n+
    532 coliterator diag=j;
    \n+
    533 for (; j!=endj; ++j)
    \n+
    534 j->mmv(x[j.index()],rhs);
    \n+\n+
    536 }
    \n+
    537 }
    \n+
    538 x.axpy(w,v);
    \n+
    539 }
    \n+
    540 };
    \n+
    541 // end of recursion
    \n+
    542 template<typename M>
    \n+
    543 struct algmeta_itsteps<0,M> {
    \n+
    544 template<class X, class Y, class K>
    \n+
    545 static void dbgs (const M& A, X& x, const Y& b, const K& /*w*/)
    \n+
    546 {
    \n+
    547 A.solve(x,b);
    \n+
    548 }
    \n+
    549 template<class X, class Y, class K>
    \n+
    550 static void bsorf (const M& A, X& x, const Y& b, const K& /*w*/)
    \n+
    551 {
    \n+
    552 A.solve(x,b);
    \n+
    553 }
    \n+
    554 template<class X, class Y, class K>
    \n+
    555 static void bsorb (const M& A, X& x, const Y& b, const K& /*w*/)
    \n+
    556 {
    \n+
    557 A.solve(x,b);
    \n+
    558 }
    \n+
    559 template<class X, class Y, class K>
    \n+
    560 static void dbjac (const M& A, X& x, const Y& b, const K& /*w*/)
    \n+
    561 {
    \n+
    562 A.solve(x,b);
    \n+
    563 }
    \n+
    564 };
    \n+
    565
    \n+
    566 template<int I, typename T1, typename... MultiTypeMatrixArgs>
    \n+
    567 struct algmeta_itsteps<I,MultiTypeBlockMatrix<T1, MultiTypeMatrixArgs...>> {
    \n+
    568 template<
    \n+
    569 typename... MultiTypeVectorArgs,
    \n+
    570 class K>
    \n+\n+\n+\n+
    574 const K& w)
    \n+
    575 {
    \n+\n+\n+
    578 }
    \n
    579
    \n-
    580 template<class X, class S>
    \n-\n-
    582 {
    \n-\n-
    584 };
    \n-
    585
    \n-
    586 template<class X, class S>
    \n-\n-
    588 {
    \n-\n-
    590 };
    \n+
    580 template<
    \n+
    581 typename... MultiTypeVectorArgs,
    \n+
    582 class K>
    \n+\n+\n+\n+
    586 const K& w)
    \n+
    587 {
    \n+\n+\n+
    590 }
    \n
    591
    \n-
    603 template<typename T1, typename T2, bool forward>
    \n-\n-
    605 {
    \n-
    606 typedef T1 solver_vector;
    \n-
    607 typedef typename solver_vector::iterator solver_iterator;
    \n-\n-
    609 typedef typename subdomain_vector::const_iterator domain_iterator;
    \n-
    610
    \n-\n+
    592 template<
    \n+
    593 typename... MultiTypeVectorArgs,
    \n+
    594 class K>
    \n+\n+\n+\n+
    598 const K& w)
    \n+
    599 {
    \n+\n+\n+
    602 }
    \n+
    603
    \n+
    604 template<
    \n+
    605 typename... MultiTypeVectorArgs,
    \n+
    606 class K
    \n+
    607 >
    \n+\n+\n+\n+
    611 const K& w)
    \n
    612 {
    \n-
    613 return sv.begin();
    \n-
    614 }
    \n-
    615
    \n-\n-
    617 {
    \n-
    618 return sv.end();
    \n-
    619 }
    \n-\n-
    621 {
    \n-
    622 return sv.begin();
    \n-
    623 }
    \n-
    624
    \n-\n-
    626 {
    \n-
    627 return sv.end();
    \n-
    628 }
    \n-
    629 };
    \n-
    630
    \n-
    631 template<typename T1, typename T2>
    \n-
    632 struct IteratorDirectionSelector<T1,T2,false>
    \n-
    633 {
    \n-
    634 typedef T1 solver_vector;
    \n-
    635 typedef typename solver_vector::reverse_iterator solver_iterator;
    \n-\n-
    637 typedef typename subdomain_vector::const_reverse_iterator domain_iterator;
    \n-
    638
    \n-\n-
    640 {
    \n-
    641 return sv.rbegin();
    \n-
    642 }
    \n-
    643
    \n-\n-
    645 {
    \n-
    646 return sv.rend();
    \n-
    647 }
    \n-\n-
    649 {
    \n-
    650 return sv.rbegin();
    \n-
    651 }
    \n-
    652
    \n-\n-
    654 {
    \n-
    655 return sv.rend();
    \n-
    656 }
    \n-
    657 };
    \n-
    658
    \n-
    667 template<class T>
    \n-\n-
    669 {
    \n-
    670 typedef T smoother;
    \n-
    671 typedef typename smoother::range_type range_type;
    \n-
    672
    \n-
    673 static void apply(smoother& sm, range_type& v, const range_type& b)
    \n-
    674 {
    \n-
    675 sm.template apply<true>(v, b);
    \n-
    676 }
    \n-
    677 };
    \n-
    678
    \n-
    679 template<class M, class X, class TD, class TA>
    \n-\n-
    681 {
    \n-\n-\n-
    684
    \n-
    685 static void apply(smoother& sm, range_type& v, const range_type& b)
    \n-
    686 {
    \n-
    687 sm.template apply<true>(v, b);
    \n-
    688 sm.template apply<false>(v, b);
    \n-
    689 }
    \n-
    690 };
    \n-
    691
    \n-
    692 template<class T, bool tag>
    \n-\n-
    694 {};
    \n-
    695
    \n-
    696 template<class T>
    \n-\n-
    698
    \n-
    699 template<class K, class Al, class X, class Y>
    \n-\n-
    701 {
    \n-\n-
    703 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<K>()))>::rows;
    \n-
    704 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    705 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n-
    706 Solvers& solvers, const SubDomains& domains,
    \n-
    707 bool onTheFly);
    \n-
    708 };
    \n-
    709
    \n-
    710 template<template<class> class S, typename T, typename A>
    \n-\n-
    712 {
    \n-\n-
    714 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n-
    715 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    716 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n-
    717 Solvers& solvers, const SubDomains& domains,
    \n-
    718 bool onTheFly);
    \n-
    719 };
    \n-
    720
    \n-
    721 template<class M,class X, class Y>
    \n-\n-
    723 {
    \n-
    724 typedef M matrix_type;
    \n-
    725 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    726 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain, const matrix_type& mat,
    \n-
    727 Solvers& solvers, const SubDomains& domains,
    \n-
    728 bool onTheFly);
    \n-
    729 };
    \n-
    730
    \n-
    731 template<class M,class X, class Y>
    \n-\n-\n-
    734 {};
    \n-
    735
    \n-
    736 template<class M,class X, class Y>
    \n-\n-\n-
    739 {};
    \n-
    740
    \n-
    751 template<class M, class X, class TM=AdditiveSchwarzMode,
    \n-
    752 class TD=ILU0SubdomainSolver<M,X,X>, class TA=std::allocator<X> >
    \n-\n-
    754 : public Preconditioner<X,X>
    \n-
    755 {
    \n-
    756 public:
    \n-
    760 typedef M matrix_type;
    \n-
    761
    \n-
    765 typedef X domain_type;
    \n-
    766
    \n-
    770 typedef X range_type;
    \n-
    771
    \n-
    778 typedef TM Mode;
    \n-
    779
    \n-
    783 typedef typename X::field_type field_type;
    \n-
    784
    \n-
    786 typedef typename matrix_type::size_type size_type;
    \n-
    787
    \n-
    789 typedef TA allocator;
    \n-
    790
    \n-
    792 typedef std::set<size_type, std::less<size_type>,
    \n-
    793 typename std::allocator_traits<TA>::template rebind_alloc<size_type> >
    \n-\n-
    795
    \n-
    797 typedef std::vector<subdomain_type, typename std::allocator_traits<TA>::template rebind_alloc<subdomain_type> > subdomain_vector;
    \n-
    798
    \n-
    800 typedef SLList<size_type, typename std::allocator_traits<TA>::template rebind_alloc<size_type> > subdomain_list;
    \n-
    801
    \n-
    803 typedef std::vector<subdomain_list, typename std::allocator_traits<TA>::template rebind_alloc<subdomain_list> > rowtodomain_vector;
    \n-
    804
    \n-
    806 typedef TD slu;
    \n-
    807
    \n-
    809 typedef std::vector<slu, typename std::allocator_traits<TA>::template rebind_alloc<slu> > slu_vector;
    \n-
    810
    \n-\n-
    825 field_type relaxationFactor=1, bool onTheFly_=true);
    \n-
    826
    \n-\n-
    839 field_type relaxationFactor=1, bool onTheFly_=true);
    \n-
    840
    \n-
    846 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] X& b)
    \n-
    847 {}
    \n-
    848
    \n-
    854 virtual void apply (X& v, const X& d);
    \n-
    855
    \n-
    861 virtual void post ([[maybe_unused]] X& x)
    \n-
    862 {}
    \n-
    863
    \n-
    864 template<bool forward>
    \n-
    865 void apply(X& v, const X& d);
    \n-
    866
    \n-\n-
    869 {
    \n-\n-
    871 }
    \n-
    872
    \n-
    873 private:
    \n-
    874 const M& mat;
    \n-
    875 slu_vector solvers;
    \n-
    876 subdomain_vector subDomains;
    \n-
    877 field_type relax;
    \n-
    878
    \n-
    879 typename M::size_type maxlength;
    \n-
    880
    \n-
    881 bool onTheFly;
    \n-
    882 };
    \n-
    883
    \n-
    884
    \n-
    885
    \n-
    886 template<class I, class S, class D>
    \n-\n-
    888 const IndexSet& idx,
    \n-
    889 const subdomain_vector& domains_)
    \n-
    890 : initializers(&il), indices(&idx), indexMaps(il.size()), domains(domains_)
    \n-
    891 {}
    \n-
    892
    \n-
    893
    \n-
    894 template<class I, class S, class D>
    \n-\n-
    896 {
    \n-
    897 typedef typename IndexSet::value_type::const_iterator iterator;
    \n-
    898 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)[row.index()].end(); ++domain) {
    \n-
    899 (*initializers)[*domain].addRowNnz(row, domains[*domain]);
    \n-
    900 indexMaps[*domain].insert(row.index());
    \n-
    901 }
    \n-
    902 }
    \n-
    903
    \n-
    904 template<class I, class S, class D>
    \n-\n-
    906 {
    \n-
    907 for(auto&& i: *initializers)
    \n-
    908 i.allocateMatrixStorage();
    \n-
    909 for(auto&& i: *initializers)
    \n-
    910 i.allocateMarker();
    \n-
    911 }
    \n-
    912
    \n-
    913 template<class I, class S, class D>
    \n-\n-
    915 {
    \n-
    916 typedef typename IndexSet::value_type::const_iterator iterator;
    \n-
    917 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)[row.index()].end(); ++domain) {
    \n-
    918 typename std::map<size_type,size_type>::const_iterator v = indexMaps[*domain].find(col.index());
    \n-
    919 if(v!= indexMaps[*domain].end()) {
    \n-
    920 (*initializers)[*domain].countEntries(indexMaps[*domain].find(col.index())->second);
    \n-
    921 }
    \n-
    922 }
    \n-
    923 }
    \n-
    924
    \n-
    925 template<class I, class S, class D>
    \n-\n-
    927 {
    \n-
    928 for(auto&& i : *initializers)
    \n-
    929 i.calcColstart();
    \n-
    930 }
    \n-
    931
    \n-
    932 template<class I, class S, class D>
    \n-\n-
    934 {
    \n-
    935 typedef typename IndexSet::value_type::const_iterator iterator;
    \n-
    936 for(iterator domain=(*indices)[row.index()].begin(); domain!= (*indices)[row.index()].end(); ++domain) {
    \n-
    937 typename std::map<size_type,size_type>::const_iterator v = indexMaps[*domain].find(col.index());
    \n-
    938 if(v!= indexMaps[*domain].end()) {
    \n-
    939 assert(indexMaps[*domain].end()!=indexMaps[*domain].find(row.index()));
    \n-
    940 (*initializers)[*domain].copyValue(col, indexMaps[*domain].find(row.index())->second,
    \n-
    941 v->second);
    \n-
    942 }
    \n-
    943 }
    \n-
    944 }
    \n-
    945
    \n-
    946 template<class I, class S, class D>
    \n-\n-
    948 {
    \n-
    949 std::vector<IndexMap>().swap(indexMaps);
    \n-
    950 for(auto&& i: *initializers)
    \n-
    951 i.createMatrix();
    \n-
    952 }
    \n-
    953
    \n-
    954 template<class I, class S, class D>
    \n-\n-
    956 : row(0)
    \n-
    957 {}
    \n-
    958
    \n-
    959 template<class I, class S, class D>
    \n-\n-
    961 {
    \n-
    962 assert(map_.find(grow)==map_.end());
    \n-
    963 map_.insert(std::make_pair(grow, row++));
    \n-
    964 }
    \n-
    965
    \n-
    966 template<class I, class S, class D>
    \n-
    967 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n-\n-
    969 {
    \n-
    970 return map_.find(grow);
    \n-
    971 }
    \n-
    972
    \n-
    973 template<class I, class S, class D>
    \n-
    974 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n-\n-
    976 {
    \n-
    977 return map_.find(grow);
    \n-
    978 }
    \n-
    979
    \n-
    980 template<class I, class S, class D>
    \n-
    981 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n-\n-
    983 {
    \n-
    984 return map_.end();
    \n-
    985 }
    \n-
    986
    \n-
    987 template<class I, class S, class D>
    \n-
    988 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n-\n-
    990 {
    \n-
    991 return map_.end();
    \n-
    992 }
    \n-
    993
    \n-
    994 template<class I, class S, class D>
    \n-
    995 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::const_iterator
    \n-\n-
    997 {
    \n-
    998 return map_.begin();
    \n-
    999 }
    \n-
    1000
    \n-
    1001 template<class I, class S, class D>
    \n-
    1002 typename OverlappingSchwarzInitializer<I,S,D>::IndexMap::iterator
    \n-\n-
    1004 {
    \n-
    1005 return map_.begin();
    \n-
    1006 }
    \n-
    1007
    \n-
    1008 template<class M, class X, class TM, class TD, class TA>
    \n-\n-
    1010 field_type relaxationFactor, bool fly)
    \n-
    1011 : mat(mat_), relax(relaxationFactor), onTheFly(fly)
    \n-
    1012 {
    \n-
    1013 typedef typename rowtodomain_vector::const_iterator RowDomainIterator;
    \n-
    1014 typedef typename subdomain_list::const_iterator DomainIterator;
    \n-
    1015#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1016 assert(rowToDomain.size()==mat.N());
    \n-
    1017 assert(rowToDomain.size()==mat.M());
    \n-
    1018
    \n-
    1019 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter)
    \n-
    1020 assert(iter->size()>0);
    \n-
    1021
    \n-
    1022#endif
    \n-
    1023 // calculate the number of domains
    \n-
    1024 size_type domains=0;
    \n-
    1025 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter)
    \n-
    1026 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)
    \n-
    1027 domains=std::max(domains, *d);
    \n-
    1028 ++domains;
    \n-
    1029
    \n-
    1030 solvers.resize(domains);
    \n-
    1031 subDomains.resize(domains);
    \n-
    1032
    \n-
    1033 // initialize subdomains to row mapping from row to subdomain mapping
    \n-
    1034 size_type row=0;
    \n-
    1035 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end(); ++iter, ++row)
    \n-
    1036 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)
    \n-
    1037 subDomains[*d].insert(row);
    \n-
    1038
    \n-
    1039#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1040 size_type i=0;
    \n-
    1041 typedef typename subdomain_vector::const_iterator iterator;
    \n-
    1042 for(iterator iter=subDomains.begin(); iter != subDomains.end(); ++iter) {
    \n-
    1043 typedef typename subdomain_type::const_iterator entry_iterator;
    \n-
    1044 Dune::dvverb<<"domain "<<i++<<":";
    \n-
    1045 for(entry_iterator entry = iter->begin(); entry != iter->end(); ++entry) {
    \n-
    1046 Dune::dvverb<<" "<<*entry;
    \n-
    1047 }
    \n-
    1048 Dune::dvverb<<std::endl;
    \n-
    1049 }
    \n-
    1050#endif
    \n-\n-
    1052 ::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);
    \n-
    1053 }
    \n-
    1054
    \n-
    1055 template<class M, class X, class TM, class TD, class TA>
    \n-\n-
    1057 const subdomain_vector& sd,
    \n-
    1058 field_type relaxationFactor,
    \n-
    1059 bool fly)
    \n-
    1060 : mat(mat_), solvers(sd.size()), subDomains(sd), relax(relaxationFactor),
    \n-
    1061 onTheFly(fly)
    \n-
    1062 {
    \n-
    1063 typedef typename subdomain_vector::const_iterator DomainIterator;
    \n-
    1064
    \n-
    1065#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    1066 size_type i=0;
    \n-
    1067
    \n-
    1068 for(DomainIterator d=sd.begin(); d != sd.end(); ++d,++i) {
    \n-
    1069 //std::cout<<i<<": "<<d->size()<<std::endl;
    \n-
    1070 assert(d->size()>0);
    \n-
    1071 typedef typename DomainIterator::value_type::const_iterator entry_iterator;
    \n-
    1072 Dune::dvverb<<"domain "<<i<<":";
    \n-
    1073 for(entry_iterator entry = d->begin(); entry != d->end(); ++entry) {
    \n-
    1074 Dune::dvverb<<" "<<*entry;
    \n-
    1075 }
    \n-
    1076 Dune::dvverb<<std::endl;
    \n-
    1077 }
    \n-
    1078
    \n-
    1079#endif
    \n-
    1080
    \n-
    1081 // Create a row to subdomain mapping
    \n-
    1082 rowtodomain_vector rowToDomain(mat.N());
    \n-
    1083
    \n-
    1084 size_type domainId=0;
    \n-
    1085
    \n-
    1086 for(DomainIterator domain=sd.begin(); domain != sd.end(); ++domain, ++domainId) {
    \n-
    1087 typedef typename subdomain_type::const_iterator iterator;
    \n-
    1088 for(iterator row=domain->begin(); row != domain->end(); ++row)
    \n-
    1089 rowToDomain[*row].push_back(domainId);
    \n-
    1090 }
    \n-
    1091
    \n-\n-
    1093 ::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);
    \n-
    1094 }
    \n-
    1095
    \n-
    1102 template<class M>
    \n-\n-
    1104
    \n-
    1105 template<typename T, typename A>
    \n-\n-
    1107 {
    \n-
    1108 static constexpr size_t n = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::rows;
    \n-
    1109 static constexpr size_t m = std::decay_t<decltype(Impl::asMatrix(std::declval<T>()))>::cols;
    \n-
    1110 template<class Domain>
    \n-
    1111 static int size(const Domain & d)
    \n-
    1112 {
    \n-
    1113 assert(n==m);
    \n-
    1114 return m*d.size();
    \n-
    1115 }
    \n-
    1116 };
    \n-
    1117
    \n-
    1118 template<class K, class Al, class X, class Y>
    \n-
    1119 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    1120 std::size_t
    \n-\n-
    1122 assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,
    \n-
    1123 [[maybe_unused]] const matrix_type& mat,
    \n-
    1124 [[maybe_unused]] Solvers& solvers,
    \n-
    1125 const SubDomains& subDomains,
    \n-
    1126 [[maybe_unused]] bool onTheFly)
    \n-
    1127 {
    \n-
    1128 typedef typename SubDomains::const_iterator DomainIterator;
    \n-
    1129 std::size_t maxlength = 0;
    \n-
    1130
    \n-
    1131 assert(onTheFly);
    \n-
    1132
    \n-
    1133 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n-
    1134 maxlength=std::max(maxlength, domain->size());
    \n-
    1135 maxlength*=n;
    \n-
    1136
    \n-
    1137 return maxlength;
    \n-
    1138 }
    \n-
    1139
    \n-
    1140#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    1141 template<template<class> class S, typename T, typename A>
    \n-
    1142 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    1143 std::size_t SeqOverlappingSchwarzAssemblerHelper<S<BCRSMatrix<T,A>>,true>::assembleLocalProblems(const RowToDomain& rowToDomain,
    \n-
    1144 const matrix_type& mat,
    \n-
    1145 Solvers& solvers,
    \n-
    1146 const SubDomains& subDomains,
    \n-
    1147 bool onTheFly)
    \n-
    1148 {
    \n-
    1149 typedef typename S<BCRSMatrix<T,A>>::MatrixInitializer MatrixInitializer;
    \n-
    1150 typedef typename std::vector<MatrixInitializer>::iterator InitializerIterator;
    \n-
    1151 typedef typename SubDomains::const_iterator DomainIterator;
    \n-
    1152 typedef typename Solvers::iterator SolverIterator;
    \n-
    1153 std::size_t maxlength = 0;
    \n-
    1154
    \n-
    1155 if(onTheFly) {
    \n-
    1156 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n-
    1157 maxlength=std::max(maxlength, domain->size());
    \n-
    1158 maxlength*=Impl::asMatrix(*mat[0].begin()).N();
    \n-
    1159 }else{
    \n-
    1160 // initialize the initializers
    \n-
    1161 DomainIterator domain=subDomains.begin();
    \n-
    1162
    \n-
    1163 // Create the initializers list.
    \n-
    1164 std::vector<MatrixInitializer> initializers(subDomains.size());
    \n-
    1165
    \n-
    1166 SolverIterator solver=solvers.begin();
    \n-
    1167 for(InitializerIterator initializer=initializers.begin(); initializer!=initializers.end();
    \n-
    1168 ++initializer, ++solver, ++domain) {
    \n-
    1169 solver->getInternalMatrix().N_=SeqOverlappingSchwarzDomainSize<matrix_type>::size(*domain);
    \n-
    1170 solver->getInternalMatrix().M_=SeqOverlappingSchwarzDomainSize<matrix_type>::size(*domain);
    \n-
    1171 //solver->setVerbosity(true);
    \n-
    1172 *initializer=MatrixInitializer(solver->getInternalMatrix());
    \n-
    1173 }
    \n-
    1174
    \n-
    1175 // Set up the supermatrices according to the subdomains
    \n-\n-
    1177 RowToDomain, SubDomains> Initializer;
    \n-
    1178
    \n-
    1179 Initializer initializer(initializers, rowToDomain, subDomains);
    \n-
    1180 copyToBCCSMatrix(initializer, mat);
    \n-
    1181
    \n-
    1182 // Calculate the LU decompositions
    \n-
    1183 for(auto&& s: solvers)
    \n-
    1184 s.decompose();
    \n-
    1185 for (SolverIterator solverIt = solvers.begin(); solverIt != solvers.end(); ++solverIt)
    \n-
    1186 {
    \n-
    1187 assert(solverIt->getInternalMatrix().N() == solverIt->getInternalMatrix().M());
    \n-
    1188 maxlength = std::max(maxlength, solverIt->getInternalMatrix().N());
    \n-
    1189 }
    \n-
    1190 }
    \n-
    1191 return maxlength;
    \n-
    1192 }
    \n-
    1193
    \n-
    1194#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    1195
    \n-
    1196 template<class M,class X,class Y>
    \n-
    1197 template<class RowToDomain, class Solvers, class SubDomains>
    \n-
    1198 std::size_t SeqOverlappingSchwarzAssemblerILUBase<M,X,Y>::assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,
    \n-
    1199 const matrix_type& mat,
    \n-
    1200 Solvers& solvers,
    \n-
    1201 const SubDomains& subDomains,
    \n-
    1202 bool onTheFly)
    \n-
    1203 {
    \n-
    1204 typedef typename SubDomains::const_iterator DomainIterator;
    \n-
    1205 typedef typename Solvers::iterator SolverIterator;
    \n-
    1206 std::size_t maxlength = 0;
    \n-
    1207
    \n-
    1208 if(onTheFly) {
    \n-
    1209 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end(); ++domain)
    \n-
    1210 maxlength=std::max(maxlength, domain->size());
    \n-
    1211 }else{
    \n-
    1212 // initialize the solvers of the local prolems.
    \n-
    1213 SolverIterator solver=solvers.begin();
    \n-
    1214 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();
    \n-
    1215 ++domain, ++solver) {
    \n-
    1216 solver->setSubMatrix(mat, *domain);
    \n-
    1217 maxlength=std::max(maxlength, domain->size());
    \n-
    1218 }
    \n-
    1219 }
    \n-
    1220
    \n-
    1221 return maxlength;
    \n-
    1222
    \n-
    1223 }
    \n-
    1224
    \n-
    1225
    \n-
    1226 template<class M, class X, class TM, class TD, class TA>
    \n-\n-
    1228 {
    \n-\n-
    1230 }
    \n-
    1231
    \n-
    1232 template<class M, class X, class TM, class TD, class TA>
    \n-
    1233 template<bool forward>
    \n-
    1234 void SeqOverlappingSchwarz<M,X,TM,TD,TA>::apply(X& x, const X& b)
    \n-
    1235 {
    \n-
    1236 typedef slu_vector solver_vector;
    \n-\n-\n-
    1239 domain_iterator;
    \n-
    1240
    \n-
    1241 OverlappingAssigner<TD> assigner(maxlength, mat, b, x);
    \n-
    1242
    \n-\n-\n-
    1245 X v(x); // temporary for the update
    \n-
    1246 v=0;
    \n-
    1247
    \n-
    1248 typedef typename AdderSelector<TM,X,TD >::Adder Adder;
    \n-
    1249 Adder adder(v, x, assigner, relax);
    \n-
    1250
    \n-
    1251 for(; domain != IteratorDirectionSelector<solver_vector,subdomain_vector,forward>::end(subDomains); ++domain) {
    \n-
    1252 //Copy rhs to C-array for SuperLU
    \n-
    1253 std::for_each(domain->begin(), domain->end(), assigner);
    \n-
    1254 assigner.resetIndexForNextDomain();
    \n-
    1255 if(onTheFly) {
    \n-
    1256 // Create the subdomain solver
    \n-
    1257 slu sdsolver;
    \n-
    1258 sdsolver.setSubMatrix(mat, *domain);
    \n-
    1259 // Apply
    \n-
    1260 sdsolver.apply(assigner.lhs(), assigner.rhs());
    \n-
    1261 }else{
    \n-
    1262 solver->apply(assigner.lhs(), assigner.rhs());
    \n-
    1263 ++solver;
    \n-
    1264 }
    \n-
    1265
    \n-
    1266 //Add relaxed correction to from SuperLU to v
    \n-
    1267 std::for_each(domain->begin(), domain->end(), adder);
    \n-
    1268 assigner.resetIndexForNextDomain();
    \n-
    1269
    \n-
    1270 }
    \n-
    1271
    \n-
    1272 adder.axpy();
    \n-
    1273 assigner.deallocate();
    \n-
    1274 }
    \n-
    1275
    \n-
    1276 template<class K, class Al, class X, class Y>
    \n-
    1277 OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al>, X, Y >,false>
    \n-
    1278 ::OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix<K, Al>& mat_,
    \n-
    1279 const X& b_, Y& x_) :
    \n-
    1280 mat(&mat_),
    \n-
    1281 rhs_( new DynamicVector<field_type>(maxlength, 42) ),
    \n-
    1282 lhs_( new DynamicVector<field_type>(maxlength, -42) ),
    \n-
    1283 b(&b_),
    \n-
    1284 x(&x_),
    \n-
    1285 i(0),
    \n-
    1286 maxlength_(maxlength)
    \n-
    1287 {}
    \n-
    1288
    \n-
    1289 template<class K, class Al, class X, class Y>
    \n-
    1290 void
    \n-\n-
    1292 ::deallocate()
    \n-
    1293 {
    \n-
    1294 delete rhs_;
    \n-
    1295 delete lhs_;
    \n-
    1296 }
    \n-
    1297
    \n-
    1298 template<class K, class Al, class X, class Y>
    \n-
    1299 void
    \n-\n-
    1301 ::resetIndexForNextDomain()
    \n-
    1302 {
    \n-
    1303 i=0;
    \n-
    1304 }
    \n-
    1305
    \n-
    1306 template<class K, class Al, class X, class Y>
    \n-
    1307 DynamicVector<typename X::field_type> &
    \n-\n-
    1309 ::lhs()
    \n-
    1310 {
    \n-
    1311 return *lhs_;
    \n-
    1312 }
    \n-
    1313
    \n-
    1314 template<class K, class Al, class X, class Y>
    \n-
    1315 DynamicVector<typename X::field_type> &
    \n-\n-
    1317 ::rhs()
    \n-
    1318 {
    \n-
    1319 return *rhs_;
    \n-
    1320 }
    \n-
    1321
    \n-
    1322 template<class K, class Al, class X, class Y>
    \n-
    1323 void
    \n-\n-
    1325 ::relaxResult(field_type relax)
    \n-
    1326 {
    \n-
    1327 lhs() *= relax;
    \n-
    1328 }
    \n-
    1329
    \n-
    1330 template<class K, class Al, class X, class Y>
    \n-
    1331 void
    \n-\n-
    1333 ::operator()(const size_type& domainIndex)
    \n-
    1334 {
    \n-
    1335 lhs() = 0.0;
    \n-
    1336#if 0
    \n-
    1337 //assign right hand side of current domainindex block
    \n-
    1338 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1339 assert(i<maxlength_);
    \n-
    1340 rhs()[i]=(*b)[domainIndex][j];
    \n-
    1341 }
    \n-
    1342
    \n-
    1343 // loop over all Matrix row entries and calculate defect.
    \n-
    1344 typedef typename matrix_type::ConstColIterator col_iterator;
    \n-
    1345
    \n-
    1346 // calculate defect for current row index block
    \n-
    1347 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n-
    1348 block_type tmp(0.0);
    \n-
    1349 (*col).mv((*x)[col.index()], tmp);
    \n-
    1350 i-=n;
    \n-
    1351 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1352 assert(i<maxlength_);
    \n-
    1353 rhs()[i]-=tmp[j];
    \n-
    1354 }
    \n-
    1355 }
    \n-
    1356#else
    \n-
    1357 //assign right hand side of current domainindex block
    \n-
    1358 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1359 assert(i<maxlength_);
    \n-
    1360 rhs()[i]=Impl::asVector((*b)[domainIndex])[j];
    \n-
    1361
    \n-
    1362 // loop over all Matrix row entries and calculate defect.
    \n-
    1363 typedef typename matrix_type::ConstColIterator col_iterator;
    \n-
    1364
    \n-
    1365 // calculate defect for current row index block
    \n-
    1366 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n-
    1367 for(size_type k=0; k<n; ++k) {
    \n-
    1368 rhs()[i]-=Impl::asMatrix(*col)[j][k] * Impl::asVector((*x)[col.index()])[k];
    \n-
    1369 }
    \n-
    1370 }
    \n-
    1371 }
    \n-
    1372#endif
    \n-
    1373 }
    \n-
    1374
    \n-
    1375 template<class K, class Al, class X, class Y>
    \n-
    1376 void
    \n-\n-
    1378 ::assignResult(block_type& res)
    \n-
    1379 {
    \n-
    1380 // assign the result of the local solve to the global vector
    \n-
    1381 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1382 assert(i<maxlength_);
    \n-
    1383 Impl::asVector(res)[j]+=lhs()[i];
    \n-
    1384 }
    \n-
    1385 }
    \n-
    1386
    \n-
    1387#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    1388
    \n-
    1389 template<template<class> class S, typename T, typename A>
    \n-\n-
    1391 ::OverlappingAssignerHelper(std::size_t maxlength,
    \n-
    1392 const BCRSMatrix<T,A>& mat_,
    \n-
    1393 const range_type& b_,
    \n-
    1394 range_type& x_)
    \n-
    1395 : mat(&mat_),
    \n-
    1396 b(&b_),
    \n-
    1397 x(&x_), i(0), maxlength_(maxlength)
    \n-
    1398 {
    \n-
    1399 rhs_ = new field_type[maxlength];
    \n-
    1400 lhs_ = new field_type[maxlength];
    \n-
    1401
    \n-
    1402 }
    \n-
    1403
    \n-
    1404 template<template<class> class S, typename T, typename A>
    \n-\n-
    1406 {
    \n-
    1407 delete[] rhs_;
    \n-
    1408 delete[] lhs_;
    \n-
    1409 }
    \n-
    1410
    \n-
    1411 template<template<class> class S, typename T, typename A>
    \n-
    1412 void OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::operator()(const size_type& domainIndex)
    \n-
    1413 {
    \n-
    1414 //assign right hand side of current domainindex block
    \n-
    1415 // rhs is an array of doubles!
    \n-
    1416 // rhs[starti] = b[domainindex]
    \n-
    1417 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1418 assert(i<maxlength_);
    \n-
    1419 rhs_[i]=Impl::asVector((*b)[domainIndex])[j];
    \n-
    1420 }
    \n-
    1421
    \n-
    1422
    \n-
    1423 // loop over all Matrix row entries and calculate defect.
    \n-
    1424 typedef typename matrix_type::ConstColIterator col_iterator;
    \n-
    1425
    \n-
    1426 // calculate defect for current row index block
    \n-
    1427 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n-
    1428 block_type tmp;
    \n-
    1429 Impl::asMatrix(*col).mv((*x)[col.index()], tmp);
    \n-
    1430 i-=n;
    \n-
    1431 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1432 assert(i<maxlength_);
    \n-
    1433 rhs_[i]-=Impl::asVector(tmp)[j];
    \n-
    1434 }
    \n-
    1435
    \n-
    1436 }
    \n-
    1437
    \n-
    1438 }
    \n-
    1439
    \n-
    1440 template<template<class> class S, typename T, typename A>
    \n-\n-
    1442 {
    \n-
    1443 for(size_type j=i+n; i<j; ++i) {
    \n-
    1444 assert(i<maxlength_);
    \n-
    1445 lhs_[i]*=relax;
    \n-
    1446 }
    \n-
    1447 i-=n;
    \n-
    1448 }
    \n-
    1449
    \n-
    1450 template<template<class> class S, typename T, typename A>
    \n-\n-
    1452 {
    \n-
    1453 // assign the result of the local solve to the global vector
    \n-
    1454 for(size_type j=0; j<n; ++j, ++i) {
    \n-
    1455 assert(i<maxlength_);
    \n-
    1456 Impl::asVector(res)[j]+=lhs_[i];
    \n-
    1457 }
    \n-
    1458 }
    \n-
    1459
    \n-
    1460 template<template<class> class S, typename T, typename A>
    \n-
    1461 void OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::resetIndexForNextDomain()
    \n-
    1462 {
    \n-
    1463 i=0;
    \n-
    1464 }
    \n-
    1465
    \n-
    1466 template<template<class> class S, typename T, typename A>
    \n-
    1467 typename OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::field_type*
    \n-\n-
    1469 {
    \n-
    1470 return lhs_;
    \n-
    1471 }
    \n-
    1472
    \n-
    1473 template<template<class> class S, typename T, typename A>
    \n-
    1474 typename OverlappingAssignerHelper<S<BCRSMatrix<T,A>>,true>::field_type*
    \n-\n-
    1476 {
    \n-
    1477 return rhs_;
    \n-
    1478 }
    \n-
    1479
    \n-
    1480#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK
    \n-
    1481
    \n-
    1482 template<class M, class X, class Y>
    \n-\n-
    1484 const M& mat_,
    \n-
    1485 const Y& b_,
    \n-
    1486 X& x_)
    \n-
    1487 : mat(&mat_),
    \n-
    1488 b(&b_),
    \n-
    1489 x(&x_), i(0)
    \n-
    1490 {
    \n-
    1491 rhs_= new Y(maxlength);
    \n-
    1492 lhs_ = new X(maxlength);
    \n-
    1493 }
    \n-
    1494
    \n-
    1495 template<class M, class X, class Y>
    \n-\n-
    1497 {
    \n-
    1498 delete rhs_;
    \n-
    1499 delete lhs_;
    \n-
    1500 }
    \n-
    1501
    \n-
    1502 template<class M, class X, class Y>
    \n-\n-
    1504 {
    \n-
    1505 (*rhs_)[i]=(*b)[domainIndex];
    \n-
    1506
    \n-
    1507 // loop over all Matrix row entries and calculate defect.
    \n-
    1508 typedef typename matrix_type::ConstColIterator col_iterator;
    \n-
    1509
    \n-
    1510 // calculate defect for current row index block
    \n-
    1511 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)[domainIndex].end(); ++col) {
    \n-
    1512 Impl::asMatrix(*col).mmv((*x)[col.index()], (*rhs_)[i]);
    \n-
    1513 }
    \n-
    1514 // Goto next local index
    \n-
    1515 ++i;
    \n-
    1516 }
    \n-
    1517
    \n-
    1518 template<class M, class X, class Y>
    \n-\n-
    1520 {
    \n-
    1521 (*lhs_)[i]*=relax;
    \n-
    1522 }
    \n-
    1523
    \n-
    1524 template<class M, class X, class Y>
    \n-\n-
    1526 {
    \n-
    1527 res+=(*lhs_)[i++];
    \n-
    1528 }
    \n-
    1529
    \n-
    1530 template<class M, class X, class Y>
    \n-\n-
    1532 {
    \n-
    1533 return *lhs_;
    \n-
    1534 }
    \n-
    1535
    \n-
    1536 template<class M, class X, class Y>
    \n-\n-
    1538 {
    \n-
    1539 return *rhs_;
    \n-
    1540 }
    \n-
    1541
    \n-
    1542 template<class M, class X, class Y>
    \n-\n-
    1544 {
    \n-
    1545 i=0;
    \n-
    1546 }
    \n-
    1547
    \n-
    1548 template<typename S, typename T, typename A>
    \n-\n-
    1550 BlockVector<T,A>& x_,
    \n-
    1551 OverlappingAssigner<S>& assigner_,
    \n-
    1552 const field_type& relax_)
    \n-
    1553 : v(&v_), x(&x_), assigner(&assigner_), relax(relax_)
    \n-
    1554 {}
    \n-
    1555
    \n-
    1556 template<typename S, typename T, typename A>
    \n-
    1557 void AdditiveAdder<S,BlockVector<T,A> >::operator()(const size_type& domainIndex)
    \n-
    1558 {
    \n-
    1559 // add the result of the local solve to the current update
    \n-
    1560 assigner->assignResult((*v)[domainIndex]);
    \n-
    1561 }
    \n-
    1562
    \n-
    1563
    \n-
    1564 template<typename S, typename T, typename A>
    \n-\n-
    1566 {
    \n-
    1567 // relax the update and add it to the current guess.
    \n-
    1568 x->axpy(relax,*v);
    \n-
    1569 }
    \n-
    1570
    \n-
    1571
    \n-
    1572 template<typename S, typename T, typename A>
    \n-\n-
    1574 ::MultiplicativeAdder([[maybe_unused]] BlockVector<T,A>& v_,
    \n-
    1575 BlockVector<T,A>& x_,
    \n-
    1576 OverlappingAssigner<S>& assigner_, const field_type& relax_)
    \n-
    1577 : x(&x_), assigner(&assigner_), relax(relax_)
    \n-
    1578 {}
    \n-
    1579
    \n-
    1580
    \n-
    1581 template<typename S,typename T, typename A>
    \n-
    1582 void MultiplicativeAdder<S,BlockVector<T,A> >::operator()(const size_type& domainIndex)
    \n-
    1583 {
    \n-
    1584 // add the result of the local solve to the current guess
    \n-
    1585 assigner->relaxResult(relax);
    \n-
    1586 assigner->assignResult((*x)[domainIndex]);
    \n-
    1587 }
    \n-
    1588
    \n-
    1589
    \n-
    1590 template<typename S,typename T, typename A>
    \n-\n-
    1592 {
    \n-
    1593 // nothing to do, as the corrections already relaxed and added in operator()
    \n-
    1594 }
    \n-
    1595
    \n-
    1596
    \n-
    1598}
    \n-
    1599
    \n-
    1600#endif
    \n-
    Templates characterizing the type of a solver.
    \n-
    Define general preconditioner interface.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Classes for using UMFPack with ISTL matrices.
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.
    \n-
    Classes for using SuperLU with ISTL matrices.
    \n-\n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    void addRowNnz(const Iter &row)
    Definition: overlappingschwarz.hh:895
    \n-
    X & lhs()
    Get the local left hand side.
    Definition: overlappingschwarz.hh:1531
    \n-
    void calcColstart() const
    Definition: overlappingschwarz.hh:926
    \n-
    Y & rhs()
    Get the local right hand side.
    Definition: overlappingschwarz.hh:1537
    \n-
    void resetIndexForNextDomain()
    Resets the local index to zero.
    Definition: overlappingschwarz.hh:1543
    \n-
    void copyValue(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:933
    \n-
    void createMatrix() const
    Definition: overlappingschwarz.hh:947
    \n-
    OverlappingSchwarzInitializer(InitializerList &il, const IndexSet &indices, const subdomain_vector &domains)
    Definition: overlappingschwarz.hh:887
    \n-
    virtual void apply(X &v, const X &d)
    Apply the precondtioner.
    Definition: overlappingschwarz.hh:1227
    \n-
    OverlappingAssignerILUBase(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:1483
    \n-
    void operator()(const size_type &domain)
    calculate one entry of the local defect.
    Definition: overlappingschwarz.hh:1503
    \n-
    SeqOverlappingSchwarz(const matrix_type &mat, const subdomain_vector &subDomains, field_type relaxationFactor=1, bool onTheFly_=true)
    Construct the overlapping Schwarz method.
    Definition: overlappingschwarz.hh:1056
    \n-
    void allocate()
    Definition: overlappingschwarz.hh:905
    \n-
    void deallocate()
    Deallocates memory of the local vector.
    Definition: overlappingschwarz.hh:1496
    \n-
    void countEntries(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:914
    \n-
    static std::size_t assembleLocalProblems(const RowToDomain &rowToDomain, const matrix_type &mat, Solvers &solvers, const SubDomains &domains, bool onTheFly)
    Definition: overlappingschwarz.hh:1198
    \n-
    void relaxResult(field_type relax)
    relax the result.
    Definition: overlappingschwarz.hh:1519
    \n-
    void assignResult(block_type &res)
    Assigns the block to the current local index. At the same time the local defect is calculated for the...
    Definition: overlappingschwarz.hh:1525
    \n-
    SeqOverlappingSchwarz(const matrix_type &mat, const rowtodomain_vector &rowToDomain, field_type relaxationFactor=1, bool onTheFly_=true)
    Definition: overlappingschwarz.hh:1009
    \n+\n+\n+
    615 }
    \n+
    616 };
    \n+
    617
    \n+
    618 // user calls
    \n+
    619
    \n+
    621 template<class M, class X, class Y, class K>
    \n+
    622 void dbgs (const M& A, X& x, const Y& b, const K& w)
    \n+
    623 {
    \n+\n+
    625 }
    \n+
    627 template<class M, class X, class Y, class K, int l>
    \n+
    628 void dbgs (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n+
    629 {
    \n+\n+
    631 }
    \n+
    633 template<class M, class X, class Y, class K>
    \n+
    634 void bsorf (const M& A, X& x, const Y& b, const K& w)
    \n+
    635 {
    \n+\n+
    637 }
    \n+
    639 template<class M, class X, class Y, class K, int l>
    \n+
    640 void bsorf (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n+
    641 {
    \n+\n+
    643 }
    \n+
    645 template<class M, class X, class Y, class K>
    \n+
    646 void bsorb (const M& A, X& x, const Y& b, const K& w)
    \n+
    647 {
    \n+\n+
    649 }
    \n+
    651 template<class M, class X, class Y, class K, int l>
    \n+
    652 void bsorb (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n+
    653 {
    \n+\n+
    655 }
    \n+
    657 template<class M, class X, class Y, class K>
    \n+
    658 void dbjac (const M& A, X& x, const Y& b, const K& w)
    \n+
    659 {
    \n+\n+
    661 }
    \n+
    663 template<class M, class X, class Y, class K, int l>
    \n+
    664 void dbjac (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n+
    665 {
    \n+\n+
    667 }
    \n+
    668
    \n+
    669
    \n+
    672} // end namespace
    \n+
    673
    \n+
    674#endif
    \n+\n+\n+\n+
    static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:568
    \n+
    static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:484
    \n+
    static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:540
    \n+
    static constexpr size_type N()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:64
    \n+
    static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:513
    \n+
    void bltsolve(const M &A, X &v, const Y &d)
    block lower triangular solve
    Definition: gsetc.hh:175
    \n+
    WithDiagType
    Definition: gsetc.hh:49
    \n+
    void bsorb(const M &A, X &x, const Y &b, const K &w)
    SSOR step.
    Definition: gsetc.hh:646
    \n+
    void ubltsolve(const M &A, X &v, const Y &d)
    unit block lower triangular solve
    Definition: gsetc.hh:188
    \n+
    void dbjac(const M &A, X &x, const Y &b, const K &w)
    Jacobi step.
    Definition: gsetc.hh:658
    \n+
    void dbgs(const M &A, X &x, const Y &b, const K &w)
    GS step.
    Definition: gsetc.hh:622
    \n+
    WithRelaxType
    Definition: gsetc.hh:54
    \n+
    void bdsolve(const M &A, X &v, const Y &d)
    block diagonal solve, no relaxation
    Definition: gsetc.hh:337
    \n+
    void butsolve(const M &A, X &v, const Y &d)
    block upper triangular solve
    Definition: gsetc.hh:202
    \n+
    void bsorf(const M &A, X &x, const Y &b, const K &w)
    SOR step.
    Definition: gsetc.hh:634
    \n+
    void ubutsolve(const M &A, X &v, const Y &d)
    unit block upper triangular solve
    Definition: gsetc.hh:215
    \n+
    @ nodiag
    Definition: gsetc.hh:51
    \n+
    @ withdiag
    Definition: gsetc.hh:50
    \n+
    @ norelax
    Definition: gsetc.hh:56
    \n+
    @ withrelax
    Definition: gsetc.hh:55
    \n
    Definition: allocator.hh:11
    \n-
    Initializer for SuperLU Matrices representing the subdomains.
    Definition: overlappingschwarz.hh:47
    \n-
    Matrix::row_type::const_iterator CIter
    Definition: overlappingschwarz.hh:56
    \n-
    S IndexSet
    Definition: overlappingschwarz.hh:58
    \n-
    Matrix::const_iterator Iter
    Definition: overlappingschwarz.hh:55
    \n-
    IndexSet::size_type size_type
    Definition: overlappingschwarz.hh:59
    \n-
    I InitializerList
    Definition: overlappingschwarz.hh:52
    \n-
    AtomInitializer::Matrix Matrix
    Definition: overlappingschwarz.hh:54
    \n-
    InitializerList::value_type AtomInitializer
    Definition: overlappingschwarz.hh:53
    \n-
    D subdomain_vector
    The vector type containing the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:50
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    A::size_type size_type
    The type for the index access and the size.
    Definition: bcrsmatrix.hh:500
    \n-
    row_type::ConstIterator ConstColIterator
    Const iterator to the entries of a row.
    Definition: bcrsmatrix.hh:741
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n-
    Exact subdomain solver using ILU(p) with appropriate p.
    Definition: ilusubdomainsolver.hh:78
    \n-
    Definition: ilusubdomainsolver.hh:111
    \n-
    Sequential overlapping Schwarz preconditioner.
    Definition: overlappingschwarz.hh:755
    \n-
    X::field_type field_type
    The field type of the preconditioner.
    Definition: overlappingschwarz.hh:783
    \n-
    void apply(X &v, const X &d)
    Apply one step of the preconditioner to the system A(v)=d.
    \n-
    SLList< size_type, typename std::allocator_traits< TA >::template rebind_alloc< size_type > > subdomain_list
    The type for the row to subdomain mapping.
    Definition: overlappingschwarz.hh:800
    \n-
    std::vector< slu, typename std::allocator_traits< TA >::template rebind_alloc< slu > > slu_vector
    The vector type containing subdomain solvers.
    Definition: overlappingschwarz.hh:809
    \n-
    M matrix_type
    The type of the matrix to precondition.
    Definition: overlappingschwarz.hh:760
    \n-
    TM Mode
    The mode (additive or multiplicative) of the Schwarz method.
    Definition: overlappingschwarz.hh:778
    \n-
    X range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:770
    \n-
    std::set< size_type, std::less< size_type >, typename std::allocator_traits< TA >::template rebind_alloc< size_type > > subdomain_type
    The type for the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:794
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:765
    \n-
    TD slu
    The type for the subdomain solver in use.
    Definition: overlappingschwarz.hh:806
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: overlappingschwarz.hh:868
    \n-
    virtual void pre(X &x, X &b)
    Prepare the preconditioner.
    Definition: overlappingschwarz.hh:846
    \n-
    virtual void post(X &x)
    Postprocess the preconditioner.
    Definition: overlappingschwarz.hh:861
    \n-
    TA allocator
    The allocator to use.
    Definition: overlappingschwarz.hh:789
    \n-
    std::vector< subdomain_type, typename std::allocator_traits< TA >::template rebind_alloc< subdomain_type > > subdomain_vector
    The vector type containing the subdomain to row index mapping.
    Definition: overlappingschwarz.hh:797
    \n-
    std::vector< subdomain_list, typename std::allocator_traits< TA >::template rebind_alloc< subdomain_list > > rowtodomain_vector
    The vector type containing the row index to subdomain mapping.
    Definition: overlappingschwarz.hh:803
    \n-
    matrix_type::size_type size_type
    The return type of the size method.
    Definition: overlappingschwarz.hh:786
    \n-
    Definition: overlappingschwarz.hh:694
    \n-
    Tag that the tells the Schwarz method to be additive.
    Definition: overlappingschwarz.hh:120
    \n-
    Tag that tells the Schwarz method to be multiplicative.
    Definition: overlappingschwarz.hh:126
    \n-
    Tag that tells the Schwarz method to be multiplicative and symmetric.
    Definition: overlappingschwarz.hh:133
    \n-
    Exact subdomain solver using Dune::DynamicMatrix<T>::solve.
    Definition: overlappingschwarz.hh:140
    \n-
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: overlappingschwarz.hh:149
    \n-
    X::field_type field_type
    Definition: overlappingschwarz.hh:150
    \n-
    X domain_type
    The domain type of the preconditioner.
    Definition: overlappingschwarz.hh:153
    \n-
    Y range_type
    The range type of the preconditioner.
    Definition: overlappingschwarz.hh:155
    \n-
    void setSubMatrix(const M &BCRS, S &rowset)
    Set the data of the local problem.
    Definition: overlappingschwarz.hh:184
    \n-
    void apply(DynamicVector< field_type > &v, DynamicVector< field_type > &d)
    Apply the subdomain solver.
    Definition: overlappingschwarz.hh:162
    \n-
    std::remove_const< M >::type rilu_type
    Definition: overlappingschwarz.hh:151
    \n-
    Definition: overlappingschwarz.hh:215
    \n-\n-\n-\n-\n-\n-
    S< BCRSMatrix< T, A > >::range_type range_type
    Definition: overlappingschwarz.hh:315
    \n-
    range_type::block_type block_type
    Definition: overlappingschwarz.hh:317
    \n-
    range_type::field_type field_type
    Definition: overlappingschwarz.hh:316
    \n-
    matrix_type::size_type size_type
    Definition: overlappingschwarz.hh:319
    \n-
    BCRSMatrix< T, A > matrix_type
    Definition: overlappingschwarz.hh:314
    \n-
    Definition: overlappingschwarz.hh:400
    \n-
    matrix_type::size_type size_type
    Definition: overlappingschwarz.hh:408
    \n-
    Y::field_type field_type
    Definition: overlappingschwarz.hh:404
    \n-
    Y::block_type block_type
    Definition: overlappingschwarz.hh:406
    \n-
    M matrix_type
    Definition: overlappingschwarz.hh:402
    \n-
    OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:493
    \n-
    OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X &x)
    Constructor.
    Definition: overlappingschwarz.hh:512
    \n-
    Definition: overlappingschwarz.hh:520
    \n-
    std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
    Definition: overlappingschwarz.hh:526
    \n-
    A::size_type size_type
    Definition: overlappingschwarz.hh:525
    \n-
    Definition: overlappingschwarz.hh:542
    \n-
    A::size_type size_type
    Definition: overlappingschwarz.hh:547
    \n-
    std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
    Definition: overlappingschwarz.hh:548
    \n-
    template meta program for choosing how to add the correction.
    Definition: overlappingschwarz.hh:572
    \n-
    AdditiveAdder< S, X > Adder
    Definition: overlappingschwarz.hh:577
    \n-
    MultiplicativeAdder< S, X > Adder
    Definition: overlappingschwarz.hh:583
    \n-
    MultiplicativeAdder< S, X > Adder
    Definition: overlappingschwarz.hh:589
    \n-
    Helper template meta program for application of overlapping Schwarz.
    Definition: overlappingschwarz.hh:605
    \n-
    static solver_iterator begin(solver_vector &sv)
    Definition: overlappingschwarz.hh:611
    \n-
    solver_vector::iterator solver_iterator
    Definition: overlappingschwarz.hh:607
    \n-
    static domain_iterator end(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:625
    \n-
    subdomain_vector::const_iterator domain_iterator
    Definition: overlappingschwarz.hh:609
    \n-
    T1 solver_vector
    Definition: overlappingschwarz.hh:606
    \n-
    static domain_iterator begin(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:620
    \n-
    T2 subdomain_vector
    Definition: overlappingschwarz.hh:608
    \n-
    static solver_iterator end(solver_vector &sv)
    Definition: overlappingschwarz.hh:616
    \n-
    T2 subdomain_vector
    Definition: overlappingschwarz.hh:636
    \n-
    static solver_iterator end(solver_vector &sv)
    Definition: overlappingschwarz.hh:644
    \n-
    solver_vector::reverse_iterator solver_iterator
    Definition: overlappingschwarz.hh:635
    \n-
    subdomain_vector::const_reverse_iterator domain_iterator
    Definition: overlappingschwarz.hh:637
    \n-
    static solver_iterator begin(solver_vector &sv)
    Definition: overlappingschwarz.hh:639
    \n-
    T1 solver_vector
    Definition: overlappingschwarz.hh:634
    \n-
    static domain_iterator begin(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:648
    \n-
    static domain_iterator end(const subdomain_vector &sv)
    Definition: overlappingschwarz.hh:653
    \n-
    Helper template meta program for application of overlapping Schwarz.
    Definition: overlappingschwarz.hh:669
    \n-
    smoother::range_type range_type
    Definition: overlappingschwarz.hh:671
    \n-
    T smoother
    Definition: overlappingschwarz.hh:670
    \n-
    static void apply(smoother &sm, range_type &v, const range_type &b)
    Definition: overlappingschwarz.hh:673
    \n-
    static void apply(smoother &sm, range_type &v, const range_type &b)
    Definition: overlappingschwarz.hh:685
    \n-
    SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > smoother
    Definition: overlappingschwarz.hh:682
    \n-\n-\n-
    BCRSMatrix< T, A > matrix_type
    Definition: overlappingschwarz.hh:713
    \n-
    Definition: overlappingschwarz.hh:723
    \n-
    M matrix_type
    Definition: overlappingschwarz.hh:724
    \n-
    Definition: overlappingschwarz.hh:1103
    \n-
    static int size(const Domain &d)
    Definition: overlappingschwarz.hh:1111
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    A Vector class to support different block types.
    Definition: multitypeblockvector.hh:59
    \n+
    A Matrix class to support different block types.
    Definition: multitypeblockmatrix.hh:46
    \n+
    compile-time parameter for block recursion depth
    Definition: gsetc.hh:45
    \n+
    @ recursion_level
    Definition: gsetc.hh:46
    \n+
    Definition: gsetc.hh:69
    \n+
    static void butsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:90
    \n+
    static void bltsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:71
    \n+
    static void bltsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:114
    \n+
    static void butsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:120
    \n+
    static void bltsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:129
    \n+
    static void butsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:134
    \n+
    static void bltsolve(const M &, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:142
    \n+
    static void butsolve(const M &, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:148
    \n+
    static void bltsolve(const M &, X &v, const Y &d, const K &)
    Definition: gsetc.hh:157
    \n+
    static void butsolve(const M &, X &v, const Y &d, const K &)
    Definition: gsetc.hh:162
    \n+
    Definition: gsetc.hh:294
    \n+
    static void bdsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:296
    \n+
    static void bdsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:316
    \n+
    static void bdsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:325
    \n+
    Definition: gsetc.hh:375
    \n+
    static void bsorb(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:461
    \n+
    static void bsorf(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:418
    \n+
    static void dbjac(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:504
    \n+
    static void dbgs(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:378
    \n+
    static void dbgs(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:545
    \n+
    static void dbjac(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:560
    \n+
    static void bsorf(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:550
    \n+
    static void bsorb(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:555
    \n+
    static void dbgs(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:571
    \n+
    static void dbjac(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:608
    \n+
    static void bsorf(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:583
    \n+
    static void bsorb(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:595
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,1862 +4,838 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-overlappingschwarz.hh\n+gsetc.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_OVERLAPPINGSCHWARZ_HH\n- 6#define DUNE_ISTL_OVERLAPPINGSCHWARZ_HH\n- 7#include \n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n+ 5#ifndef DUNE_ISTL_GSETC_HH\n+ 6#define DUNE_ISTL_GSETC_HH\n+ 7\n+ 8#include \n+ 9#include \n+ 10#include \n+ 11#include \n+ 12#include \n+ 13\n+ 14#include \n 15\n- 16#include \n- 17#include \"preconditioners.hh\"\n- 18#include \"superlu.hh\"\n- 19#include \"umfpack.hh\"\n- 20#include \"bvector.hh\"\n- 21#include \"bcrsmatrix.hh\"\n- 22#include \"ilusubdomainsolver.hh\"\n- 23#include \n- 24\n- 25namespace Dune\n- 26{\n- 27\n- 39 template\n- 40 class SeqOverlappingSchwarz;\n- 41\n- 45 template\n-46 class OverlappingSchwarzInitializer\n- 47 {\n- 48 public:\n-50 typedef D subdomain_vector;\n- 51\n-52 typedef I InitializerList;\n-53 typedef typename InitializerList::value_type AtomInitializer;\n-54 typedef typename AtomInitializer::Matrix Matrix;\n-55 typedef typename Matrix::const_iterator Iter;\n-56 typedef typename Matrix::row_type::const_iterator CIter;\n- 57\n-58 typedef S IndexSet;\n-59 typedef typename IndexSet::size_type size_type;\n- 60\n- 61 OverlappingSchwarzInitializer(InitializerList& il,\n- 62 const IndexSet& indices,\n- 63 const subdomain_vector& domains);\n- 64\n- 65\n- 66 void addRowNnz(const Iter& row);\n- 67\n- 68 void allocate();\n- 69\n- 70 void countEntries(const Iter& row, const CIter& col) const;\n- 71\n- 72 void calcColstart() const;\n- 73\n- 74 void copyValue(const Iter& row, const CIter& col) const;\n- 75\n- 76 void createMatrix() const;\n- 77 private:\n- 78 class IndexMap\n- 79 {\n- 80 public:\n- 81 typedef typename S::size_type size_type;\n- 82 typedef std::map Map;\n- 83 typedef typename Map::iterator iterator;\n- 84 typedef typename Map::const_iterator const_iterator;\n- 85\n- 86 IndexMap();\n- 87\n- 88 void insert(size_type grow);\n- 89\n- 90 const_iterator find(size_type grow) const;\n- 91\n- 92 iterator find(size_type grow);\n- 93\n- 94 iterator begin();\n- 95\n- 96 const_iterator begin() const;\n- 97\n- 98 iterator end();\n- 99\n- 100 const_iterator end() const;\n- 101\n- 102 private:\n- 103 std::map map_;\n- 104 size_type row;\n- 105 };\n- 106\n- 107\n- 108 typedef typename InitializerList::iterator InitIterator;\n- 109 typedef typename IndexSet::const_iterator IndexIteratur;\n- 110 InitializerList* initializers;\n- 111 const IndexSet *indices;\n- 112 mutable std::vector indexMaps;\n- 113 const subdomain_vector& domains;\n- 114 };\n- 115\n-119 struct AdditiveSchwarzMode\n- 120 {};\n- 121\n-125 struct MultiplicativeSchwarzMode\n- 126 {};\n- 127\n-132 struct SymmetricMultiplicativeSchwarzMode\n- 133 {};\n- 134\n- 139 template\n-140 class DynamicMatrixSubdomainSolver;\n- 141\n- 142 // Specialization for BCRSMatrix\n- 143 template\n-144 class DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al>, X, Y >\n- 145 {\n- 146 typedef BCRSMatrix<_K,_Al> M;\n- 147 public:\n-149 typedef typename std::remove_const::type matrix_type;\n-150 typedef typename X::field_type field_type;\n-151 typedef typename std::remove_const::type rilu_type;\n-153 typedef X domain_type;\n-155 typedef Y range_type;\n-156 static constexpr size_t n = std::decay_t()))>::rows;\n- 157\n-162 void apply (DynamicVector& v, DynamicVector& d)\n+ 16#include \"multitypeblockvector.hh\"\n+ 17#include \"multitypeblockmatrix.hh\"\n+ 18\n+ 19#include \"istlexception.hh\"\n+ 20\n+ 21\n+ 27namespace Dune {\n+ 28\n+ 39 //============================================================\n+ 40 // parameter types\n+ 41 //============================================================\n+ 42\n+ 44 template\n+45 struct BL {\n+46 enum {recursion_level = l};\n+ 47 };\n+ 48\n+49 enum WithDiagType {\n+50 withdiag=1,\n+ 51 nodiag=0\n+52 };\n+ 53\n+54 enum WithRelaxType {\n+55 withrelax=1,\n+ 56 norelax=0\n+57 };\n+ 58\n+ 59 //============================================================\n+ 60 // generic triangular solves\n+ 61 // consider block decomposition A = L + D + U\n+ 62 // we can invert L, L+D, U, U+D\n+ 63 // we can apply relaxation or not\n+ 64 // we can recurse over a fixed number of levels\n+ 65 //============================================================\n+ 66\n+ 67 // template meta program for triangular solves\n+ 68 template\n+69 struct algmeta_btsolve {\n+ 70 template\n+71 static void bltsolve (const M& A, X& v, const Y& d, const K& w)\n+ 72 {\n+ 73 // iterator types\n+ 74 typedef typename M::ConstRowIterator rowiterator;\n+ 75 typedef typename M::ConstColIterator coliterator;\n+ 76 typedef typename Y::block_type bblock;\n+ 77\n+ 78 // local solve at each block and immediate update\n+ 79 rowiterator endi=A.end();\n+ 80 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 81 {\n+ 82 bblock rhs(d[i.index()]);\n+ 83 coliterator j;\n+ 84 for (j=(*i).begin(); j.index()::bltsolve(*j,v[i.index()],rhs,w);\n+ 87 }\n+ 88 }\n+ 89 template\n+90 static void butsolve (const M& A, X& v, const Y& d, const K& w)\n+ 91 {\n+ 92 // iterator types\n+ 93 typedef typename M::ConstRowIterator rowiterator;\n+ 94 typedef typename M::ConstColIterator coliterator;\n+ 95 typedef typename Y::block_type bblock;\n+ 96\n+ 97 // local solve at each block and immediate update\n+ 98 rowiterator rendi=A.beforeBegin();\n+ 99 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)\n+ 100 {\n+ 101 bblock rhs(d[i.index()]);\n+ 102 coliterator j;\n+ 103 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)\n+ 104 (*j).mmv(v[j.index()],rhs);\n+ 105 algmeta_btsolve::butsolve(*j,v[i.index()],rhs,w);\n+ 106 }\n+ 107 }\n+ 108 };\n+ 109\n+ 110 // recursion end ...\n+ 111 template<>\n+112 struct algmeta_btsolve<0,withdiag,withrelax> {\n+ 113 template\n+114 static void bltsolve (const M& A, X& v, const Y& d, const K& w)\n+ 115 {\n+ 116 A.solve(v,d);\n+ 117 v *= w;\n+ 118 }\n+ 119 template\n+120 static void butsolve (const M& A, X& v, const Y& d, const K& w)\n+ 121 {\n+ 122 A.solve(v,d);\n+ 123 v *= w;\n+ 124 }\n+ 125 };\n+ 126 template<>\n+127 struct algmeta_btsolve<0,withdiag,norelax> {\n+ 128 template\n+129 static void bltsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n+ 130 {\n+ 131 A.solve(v,d);\n+ 132 }\n+ 133 template\n+134 static void butsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n+ 135 {\n+ 136 A.solve(v,d);\n+ 137 }\n+ 138 };\n+ 139 template<>\n+140 struct algmeta_btsolve<0,nodiag,withrelax> {\n+ 141 template\n+142 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& w)\n+ 143 {\n+ 144 v = d;\n+ 145 v *= w;\n+ 146 }\n+ 147 template\n+148 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& w)\n+ 149 {\n+ 150 v = d;\n+ 151 v *= w;\n+ 152 }\n+ 153 };\n+ 154 template<>\n+155 struct algmeta_btsolve<0,nodiag,norelax> {\n+ 156 template\n+157 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)\n+ 158 {\n+ 159 v = d;\n+ 160 }\n+ 161 template\n+162 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)\n 163 {\n- 164 assert(v.size() > 0);\n- 165 assert(v.size() == d.size());\n- 166 assert(A.rows() <= v.size());\n- 167 assert(A.cols() <= v.size());\n- 168 size_t sz = A.rows();\n- 169 v.resize(sz);\n- 170 d.resize(sz);\n- 171 A.solve(v,d);\n- 172 v.resize(v.capacity());\n- 173 d.resize(d.capacity());\n- 174 }\n- 175\n- 183 template\n-184 void setSubMatrix(const M& BCRS, S& rowset)\n- 185 {\n- 186 size_t sz = rowset.size();\n- 187 A.resize(sz*n,sz*n);\n- 188 typedef typename S::const_iterator SIter;\n- 189 size_t r = 0, c = 0;\n- 190 for(SIter rowIdx = rowset.begin(), rowEnd=rowset.end();\n- 191 rowIdx!= rowEnd; ++rowIdx, r++)\n- 192 {\n- 193 c = 0;\n- 194 for(SIter colIdx = rowset.begin(), colEnd=rowset.end();\n- 195 colIdx!= colEnd; ++colIdx, c++)\n+ 164 v = d;\n+ 165 }\n+ 166 };\n+ 167\n+ 168\n+ 169 // user calls\n+ 170\n+ 171 // default block recursion level = 1\n+ 172\n+ 174 template\n+175 void bltsolve (const M& A, X& v, const Y& d)\n+ 176 {\n+ 177 typename X::field_type w=1;\n+ 178 algmeta_btsolve<1,withdiag,norelax>::bltsolve(A,v,d,w);\n+ 179 }\n+ 181 template\n+182 void bltsolve (const M& A, X& v, const Y& d, const K& w)\n+ 183 {\n+ 184 algmeta_btsolve<1,withdiag,withrelax>::bltsolve(A,v,d,w);\n+ 185 }\n+ 187 template\n+188 void ubltsolve (const M& A, X& v, const Y& d)\n+ 189 {\n+ 190 typename X::field_type w=1;\n+ 191 algmeta_btsolve<1,nodiag,norelax>::bltsolve(A,v,d,w);\n+ 192 }\n+ 194 template\n+195 void ubltsolve (const M& A, X& v, const Y& d, const K& w)\n 196 {\n- 197 if (BCRS[*rowIdx].find(*colIdx) == BCRS[*rowIdx].end())\n- 198 continue;\n- 199 for (size_t i=0; i::bltsolve(A,v,d,w);\n+ 198 }\n+ 199\n+ 201 template\n+202 void butsolve (const M& A, X& v, const Y& d)\n+ 203 {\n+ 204 typename X::field_type w=1;\n+ 205 algmeta_btsolve<1,withdiag,norelax>::butsolve(A,v,d,w);\n 206 }\n- 207 }\n- 208 }\n- 209 private:\n- 210 DynamicMatrix A;\n- 211 };\n- 212\n- 213 template\n-214 class OverlappingAssignerHelper\n- 215 {};\n- 216\n- 217 template\n-218 using OverlappingAssigner = OverlappingAssignerHelper::value>;\n- 219\n- 220 // specialization for DynamicMatrix\n- 221 template\n-222 class OverlappingAssignerHelper< DynamicMatrixSubdomainSolver<\n-BCRSMatrix, X, Y >,false>\n+ 208 template\n+209 void butsolve (const M& A, X& v, const Y& d, const K& w)\n+ 210 {\n+ 211 algmeta_btsolve<1,withdiag,withrelax>::butsolve(A,v,d,w);\n+ 212 }\n+ 214 template\n+215 void ubutsolve (const M& A, X& v, const Y& d)\n+ 216 {\n+ 217 typename X::field_type w=1;\n+ 218 algmeta_btsolve<1,nodiag,norelax>::butsolve(A,v,d,w);\n+ 219 }\n+ 221 template\n+222 void ubutsolve (const M& A, X& v, const Y& d, const K& w)\n 223 {\n- 224 public:\n-225 typedef BCRSMatrix<_K,_Al> matrix_type;\n-226 typedef typename X::field_type field_type;\n-227 typedef Y range_type;\n-228 typedef typename range_type::block_type block_type;\n-229 typedef typename matrix_type::size_type size_type;\n-230 static constexpr size_t n = std::decay_t()))>::rows;\n- 238 OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix&\n-mat_, const X& b_, Y& x_);\n- 239\n- 243 inline\n- 244 void deallocate();\n- 245\n- 249 inline\n- 250 void resetIndexForNextDomain();\n- 251\n- 256 inline\n- 257 DynamicVector & lhs();\n- 258\n- 263 inline\n- 264 DynamicVector & rhs();\n- 265\n- 270 inline\n- 271 void relaxResult(field_type relax);\n- 272\n- 277 void operator()(const size_type& domainIndex);\n- 278\n- 286 inline\n- 287 void assignResult(block_type& res);\n- 288\n- 289 private:\n- 293 const matrix_type* mat;\n- 295 // we need a pointer, because we have to avoid deep copies\n- 296 DynamicVector * rhs_;\n- 298 // we need a pointer, because we have to avoid deep copies\n- 299 DynamicVector * lhs_;\n- 301 const range_type* b;\n- 303 range_type* x;\n- 305 std::size_t i;\n- 307 std::size_t maxlength_;\n- 308 };\n- 309\n- 310#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n- 311 template class S, typename T, typename A>\n-312 struct OverlappingAssignerHelper>, true>\n- 313 {\n-314 typedef BCRSMatrix matrix_type;\n-315 typedef typename S>::range_type range_type;\n-316 typedef typename range_type::field_type field_type;\n-317 typedef typename range_type::block_type block_type;\n- 318\n-319 typedef typename matrix_type::size_type size_type;\n- 320\n-321 static constexpr size_t n = std::decay_t()))>::rows;\n-322 static constexpr size_t m = std::decay_t()))>::cols;\n- 330 OverlappingAssignerHelper(std::size_t maxlength, const matrix_type& mat,\n- 331 const range_type& b, range_type& x);\n- 337 void deallocate();\n- 338\n- 339 /*\n- 340 * @brief Resets the local index to zero.\n- 341 */\n- 342 void resetIndexForNextDomain();\n- 343\n- 348 field_type* lhs();\n- 349\n- 354 field_type* rhs();\n- 355\n- 360 void relaxResult(field_type relax);\n- 361\n- 366 void operator()(const size_type& domain);\n- 367\n- 375 void assignResult(block_type& res);\n+ 224 algmeta_btsolve<1,nodiag,withrelax>::butsolve(A,v,d,w);\n+ 225 }\n+ 226\n+ 227 // general block recursion level >= 0\n+ 228\n+ 230 template\n+231 void bltsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n+ 232 {\n+ 233 typename X::field_type w=1;\n+ 234 algmeta_btsolve::bltsolve(A,v,d,w);\n+ 235 }\n+ 237 template\n+238 void bltsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n+ 239 {\n+ 240 algmeta_btsolve::bltsolve(A,v,d,w);\n+ 241 }\n+ 243 template\n+244 void ubltsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n+ 245 {\n+ 246 typename X::field_type w=1;\n+ 247 algmeta_btsolve::bltsolve(A,v,d,w);\n+ 248 }\n+ 250 template\n+251 void ubltsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n+ 252 {\n+ 253 algmeta_btsolve::bltsolve(A,v,d,w);\n+ 254 }\n+ 255\n+ 257 template\n+258 void butsolve (const M& A, X& v, const Y& d, BL bl)\n+ 259 {\n+ 260 typename X::field_type w=1;\n+ 261 algmeta_btsolve::butsolve(A,v,d,w);\n+ 262 }\n+ 264 template\n+265 void butsolve (const M& A, X& v, const Y& d, const K& w, BL bl)\n+ 266 {\n+ 267 algmeta_btsolve::butsolve(A,v,d,w);\n+ 268 }\n+ 270 template\n+271 void ubutsolve (const M& A, X& v, const Y& d, BL bl)\n+ 272 {\n+ 273 typename X::field_type w=1;\n+ 274 algmeta_btsolve::butsolve(A,v,d,w);\n+ 275 }\n+ 277 template\n+278 void ubutsolve (const M& A, X& v, const Y& d, const K& w, BL bl)\n+ 279 {\n+ 280 algmeta_btsolve::butsolve(A,v,d,w);\n+ 281 }\n+ 282\n+ 283\n+ 284\n+ 285 //============================================================\n+ 286 // generic block diagonal solves\n+ 287 // consider block decomposition A = L + D + U\n+ 288 // we can apply relaxation or not\n+ 289 // we can recurse over a fixed number of levels\n+ 290 //============================================================\n+ 291\n+ 292 // template meta program for diagonal solves\n+ 293 template\n+294 struct algmeta_bdsolve {\n+ 295 template\n+296 static void bdsolve (const M& A, X& v, const Y& d, const K& w)\n+ 297 {\n+ 298 // iterator types\n+ 299 typedef typename M::ConstRowIterator rowiterator;\n+ 300 typedef typename M::ConstColIterator coliterator;\n+ 301\n+ 302 // local solve at each block and immediate update\n+ 303 rowiterator rendi=A.beforeBegin();\n+ 304 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)\n+ 305 {\n+ 306 coliterator ii=(*i).find(i.index());\n+ 307 algmeta_bdsolve::bdsolve(*ii,v[i.index()],d[i.index()],w);\n+ 308 }\n+ 309 }\n+ 310 };\n+ 311\n+ 312 // recursion end ...\n+ 313 template<>\n+314 struct algmeta_bdsolve<0,withrelax> {\n+ 315 template\n+316 static void bdsolve (const M& A, X& v, const Y& d, const K& w)\n+ 317 {\n+ 318 A.solve(v,d);\n+ 319 v *= w;\n+ 320 }\n+ 321 };\n+ 322 template<>\n+323 struct algmeta_bdsolve<0,norelax> {\n+ 324 template\n+325 static void bdsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n+ 326 {\n+ 327 A.solve(v,d);\n+ 328 }\n+ 329 };\n+ 330\n+ 331 // user calls\n+ 332\n+ 333 // default block recursion level = 1\n+ 334\n+ 336 template\n+337 void bdsolve (const M& A, X& v, const Y& d)\n+ 338 {\n+ 339 typename X::field_type w=1;\n+ 340 algmeta_bdsolve<1,norelax>::bdsolve(A,v,d,w);\n+ 341 }\n+ 343 template\n+344 void bdsolve (const M& A, X& v, const Y& d, const K& w)\n+ 345 {\n+ 346 algmeta_bdsolve<1,withrelax>::bdsolve(A,v,d,w);\n+ 347 }\n+ 348\n+ 349 // general block recursion level >= 0\n+ 350\n+ 352 template\n+353 void bdsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n+ 354 {\n+ 355 typename X::field_type w=1;\n+ 356 algmeta_bdsolve::bdsolve(A,v,d,w);\n+ 357 }\n+ 359 template\n+360 void bdsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n+ 361 {\n+ 362 algmeta_bdsolve::bdsolve(A,v,d,w);\n+ 363 }\n+ 364\n+ 365\n+ 366 //============================================================\n+ 367 // generic steps of iteration methods\n+ 368 // Jacobi, Gauss-Seidel, SOR, SSOR\n+ 369 // work directly on Ax=b, ie solve M(x^{i+1}-x^i) = w (b-Ax^i)\n+ 370 // we can recurse over a fixed number of levels\n+ 371 //============================================================\n+ 372\n+ 373 // template meta program for iterative solver steps\n+ 374 template\n+375 struct algmeta_itsteps {\n 376\n- 377 private:\n- 381 const matrix_type* mat;\n- 383 field_type* rhs_;\n- 385 field_type* lhs_;\n- 387 const range_type* b;\n- 389 range_type* x;\n- 391 std::size_t i;\n- 393 std::size_t maxlength_;\n- 394 };\n- 395\n- 396#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n- 397\n- 398 template\n-399 class OverlappingAssignerILUBase\n- 400 {\n- 401 public:\n-402 typedef M matrix_type;\n- 403\n-404 typedef typename Y::field_type field_type;\n- 405\n-406 typedef typename Y::block_type block_type;\n- 407\n-408 typedef typename matrix_type::size_type size_type;\n- 416 OverlappingAssignerILUBase(std::size_t maxlength, const M& mat,\n- 417 const Y& b, X& x);\n- 423 void deallocate();\n- 424\n- 428 void resetIndexForNextDomain();\n- 429\n- 434 X& lhs();\n- 435\n- 440 Y& rhs();\n- 441\n- 446 void relaxResult(field_type relax);\n- 447\n- 452 void operator()(const size_type& domain);\n- 453\n- 461 void assignResult(block_type& res);\n- 462\n- 463 private:\n- 467 const M* mat;\n- 469 X* lhs_;\n- 471 Y* rhs_;\n- 473 const Y* b;\n- 475 X* x;\n- 477 size_type i;\n- 478 };\n- 479\n- 480 // specialization for ILU0\n- 481 template\n-482 class OverlappingAssignerHelper, false>\n- 483 : public OverlappingAssignerILUBase\n- 484 {\n- 485 public:\n-493 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,\n- 494 const Y& b, X& x)\n- 495 : OverlappingAssignerILUBase(maxlength, mat,b,x)\n- 496 {}\n- 497 };\n- 498\n- 499 // specialization for ILUN\n- 500 template\n-501 class OverlappingAssignerHelper,false>\n- 502 : public OverlappingAssignerILUBase\n- 503 {\n- 504 public:\n-512 OverlappingAssignerHelper(std::size_t maxlength, const M& mat,\n- 513 const Y& b, X& x)\n- 514 : OverlappingAssignerILUBase(maxlength, mat,b,x)\n- 515 {}\n- 516 };\n- 517\n- 518 template\n-519 struct AdditiveAdder\n- 520 {};\n- 521\n- 522 template\n-523 struct AdditiveAdder >\n- 524 {\n-525 typedef typename A::size_type size_type;\n-526 typedef typename std::decay_t\n-()))>::field_type field_type;\n- 527 AdditiveAdder(BlockVector& v, BlockVector& x,\n- 528 OverlappingAssigner& assigner, const field_type& relax_);\n- 529 void operator()(const size_type& domain);\n- 530 void axpy();\n-531 static constexpr size_t n = std::decay_t()))>::dimension;\n- 532\n- 533 private:\n- 534 BlockVector* v;\n- 535 BlockVector* x;\n- 536 OverlappingAssigner* assigner;\n- 537 field_type relax;\n- 538 };\n- 539\n- 540 template\n-541 struct MultiplicativeAdder\n- 542 {};\n- 543\n- 544 template\n-545 struct MultiplicativeAdder >\n+ 377 template\n+378 static void dbgs (const M& A, X& x, const Y& b, const K& w)\n+ 379 {\n+ 380 typedef typename M::ConstRowIterator rowiterator;\n+ 381 typedef typename M::ConstColIterator coliterator;\n+ 382 typedef typename Y::block_type bblock;\n+ 383 bblock rhs;\n+ 384\n+ 385 X xold(x); // remember old x\n+ 386\n+ 387 rowiterator endi=A.end();\n+ 388 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 389 {\n+ 390 rhs = b[i.index()]; // rhs = b_i\n+ 391 coliterator endj=(*i).end();\n+ 392 coliterator j=(*i).begin();\n+ 393 if constexpr (IsNumber())\n+ 394 {\n+ 395 for (; j.index() i\n+ 408 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j>i} a_ij * xold_j\n+ 409 algmeta_itsteps::dbgs(*diag,x[i.index\n+()],rhs,w); // if I==1: xnew_i = rhs/a_ii\n+ 410 }\n+ 411 }\n+ 412 // next two lines: xnew_i = w / a_ii * (b_i - sum_{j=i} a_ij * xold_j) + (1-w)*xold;\n+ 413 x *= w;\n+ 414 x.axpy(K(1)-w,xold);\n+ 415 }\n+ 416\n+ 417 template\n+418 static void bsorf (const M& A, X& x, const Y& b, const K& w)\n+ 419 {\n+ 420 typedef typename M::ConstRowIterator rowiterator;\n+ 421 typedef typename M::ConstColIterator coliterator;\n+ 422 typedef typename Y::block_type bblock;\n+ 423 typedef typename X::block_type xblock;\n+ 424 bblock rhs;\n+ 425 xblock v;\n+ 426\n+ 427 // Initialize nested data structure if there are entries\n+ 428 if(A.begin()!=A.end())\n+ 429 v=x[0];\n+ 430\n+ 431 rowiterator endi=A.end();\n+ 432 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 433 {\n+ 434 rhs = b[i.index()]; // rhs = b_i\n+ 435 coliterator endj=(*i).end(); // iterate over a_ij with j < i\n+ 436 coliterator j=(*i).begin();\n+ 437 if constexpr (IsNumber())\n+ 438 {\n+ 439 for (; j.index()=i} a_ij * xold_j)\n+ 446 }\n+ 447 else\n+ 448 {\n+ 449 for (; j.index()::bsorf(*diag,v,rhs,w); // if\n+blocksize I==1: v = rhs/a_ii\n+ 455 x[i.index()].axpy(w,v); // x_i = w / a_ii * (b_i - sum_{j=i} a_ij * xold_j)\n+ 456 }\n+ 457 }\n+ 458 }\n+ 459\n+ 460 template\n+461 static void bsorb (const M& A, X& x, const Y& b, const K& w)\n+ 462 {\n+ 463 typedef typename M::ConstRowIterator rowiterator;\n+ 464 typedef typename M::ConstColIterator coliterator;\n+ 465 typedef typename Y::block_type bblock;\n+ 466 typedef typename X::block_type xblock;\n+ 467 bblock rhs;\n+ 468 xblock v;\n+ 469\n+ 470 // Initialize nested data structure if there are entries\n+ 471 if(A.begin()!=A.end())\n+ 472 v=x[0];\n+ 473\n+ 474 rowiterator endi=A.beforeBegin();\n+ 475 for (rowiterator i=A.beforeEnd(); i!=endi; --i)\n+ 476 {\n+ 477 rhs = b[i.index()];\n+ 478 coliterator endj=(*i).end();\n+ 479 coliterator j=(*i).begin();\n+ 480 if constexpr (IsNumber())\n+ 481 {\n+ 482 for (; j.index()mmv(x[j.index()],rhs);\n+ 494 coliterator diag=j;\n+ 495 for (; j!=endj; ++j)\n+ 496 j->mmv(x[j.index()],rhs);\n+ 497 algmeta_itsteps::bsorb(*diag,v,rhs,w);\n+ 498 x[i.index()].axpy(w,v);\n+ 499 }\n+ 500 }\n+ 501 }\n+ 502\n+ 503 template\n+504 static void dbjac (const M& A, X& x, const Y& b, const K& w)\n+ 505 {\n+ 506 typedef typename M::ConstRowIterator rowiterator;\n+ 507 typedef typename M::ConstColIterator coliterator;\n+ 508 typedef typename Y::block_type bblock;\n+ 509 bblock rhs;\n+ 510\n+ 511 X v(x); // allocate with same size\n+ 512\n+ 513 rowiterator endi=A.end();\n+ 514 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 515 {\n+ 516 rhs = b[i.index()];\n+ 517 coliterator endj=(*i).end();\n+ 518 coliterator j=(*i).begin();\n+ 519 if constexpr (IsNumber())\n+ 520 {\n+ 521 for (; j.index()mmv(x[j.index()],rhs);\n+ 532 coliterator diag=j;\n+ 533 for (; j!=endj; ++j)\n+ 534 j->mmv(x[j.index()],rhs);\n+ 535 algmeta_itsteps::dbjac(*diag,v[i.index\n+()],rhs,w);\n+ 536 }\n+ 537 }\n+ 538 x.axpy(w,v);\n+ 539 }\n+ 540 };\n+ 541 // end of recursion\n+ 542 template\n+543 struct algmeta_itsteps<0,M> {\n+ 544 template\n+545 static void dbgs (const M& A, X& x, const Y& b, const K& /*w*/)\n 546 {\n-547 typedef typename A::size_type size_type;\n-548 typedef typename std::decay_t\n-()))>::field_type field_type;\n- 549 MultiplicativeAdder(BlockVector& v, BlockVector& x,\n- 550 OverlappingAssigner& assigner_, const field_type& relax_);\n- 551 void operator()(const size_type& domain);\n- 552 void axpy();\n-553 static constexpr size_t n = std::decay_t()))>::dimension;\n- 554\n- 555 private:\n- 556 BlockVector* x;\n- 557 OverlappingAssigner* assigner;\n- 558 field_type relax;\n- 559 };\n- 560\n- 570 template\n-571 struct AdderSelector\n- 572 {};\n- 573\n- 574 template\n-575 struct AdderSelector\n- 576 {\n-577 typedef AdditiveAdder Adder;\n- 578 };\n+ 547 A.solve(x,b);\n+ 548 }\n+ 549 template\n+550 static void bsorf (const M& A, X& x, const Y& b, const K& /*w*/)\n+ 551 {\n+ 552 A.solve(x,b);\n+ 553 }\n+ 554 template\n+555 static void bsorb (const M& A, X& x, const Y& b, const K& /*w*/)\n+ 556 {\n+ 557 A.solve(x,b);\n+ 558 }\n+ 559 template\n+560 static void dbjac (const M& A, X& x, const Y& b, const K& /*w*/)\n+ 561 {\n+ 562 A.solve(x,b);\n+ 563 }\n+ 564 };\n+ 565\n+ 566 template\n+567 struct algmeta_itsteps>\n+{\n+ 568 template<\n+ 569 typename... MultiTypeVectorArgs,\n+ 570 class K>\n+571 static void dbgs (const MultiTypeBlockMatrix&\n+A,\n+ 572 MultiTypeBlockVector& x,\n+ 573 const MultiTypeBlockVector& b,\n+ 574 const K& w)\n+ 575 {\n+ 576 static const int N = MultiTypeBlockMatrix::N\n+();\n+ 577 Dune::MultiTypeBlockMatrix_Solver::dbgs(A, x, b, w);\n+ 578 }\n 579\n- 580 template\n-581 struct AdderSelector\n- 582 {\n-583 typedef MultiplicativeAdder Adder;\n- 584 };\n- 585\n- 586 template\n-587 struct AdderSelector\n- 588 {\n-589 typedef MultiplicativeAdder Adder;\n- 590 };\n+ 580 template<\n+ 581 typename... MultiTypeVectorArgs,\n+ 582 class K>\n+583 static void bsorf (const MultiTypeBlockMatrix&\n+A,\n+ 584 MultiTypeBlockVector& x,\n+ 585 const MultiTypeBlockVector& b,\n+ 586 const K& w)\n+ 587 {\n+ 588 static const int N = MultiTypeBlockMatrix::N\n+();\n+ 589 Dune::MultiTypeBlockMatrix_Solver::bsorf(A, x, b, w);\n+ 590 }\n 591\n- 603 template\n-604 struct IteratorDirectionSelector\n- 605 {\n-606 typedef T1 solver_vector;\n-607 typedef typename solver_vector::iterator solver_iterator;\n-608 typedef T2 subdomain_vector;\n-609 typedef typename subdomain_vector::const_iterator domain_iterator;\n- 610\n-611 static solver_iterator begin(solver_vector& sv)\n+ 592 template<\n+ 593 typename... MultiTypeVectorArgs,\n+ 594 class K>\n+595 static void bsorb (const MultiTypeBlockMatrix&\n+A,\n+ 596 MultiTypeBlockVector& x,\n+ 597 const MultiTypeBlockVector& b,\n+ 598 const K& w)\n+ 599 {\n+ 600 static const int N = MultiTypeBlockMatrix::N\n+();\n+ 601 Dune::MultiTypeBlockMatrix_Solver::bsorb(A, x, b, w);\n+ 602 }\n+ 603\n+ 604 template<\n+ 605 typename... MultiTypeVectorArgs,\n+ 606 class K\n+ 607 >\n+608 static void dbjac (const MultiTypeBlockMatrix&\n+A,\n+ 609 MultiTypeBlockVector& x,\n+ 610 const MultiTypeBlockVector& b,\n+ 611 const K& w)\n 612 {\n- 613 return sv.begin();\n- 614 }\n- 615\n-616 static solver_iterator end(solver_vector& sv)\n- 617 {\n- 618 return sv.end();\n- 619 }\n-620 static domain_iterator begin(const subdomain_vector& sv)\n- 621 {\n- 622 return sv.begin();\n- 623 }\n- 624\n-625 static domain_iterator end(const subdomain_vector& sv)\n- 626 {\n- 627 return sv.end();\n- 628 }\n- 629 };\n- 630\n- 631 template\n-632 struct IteratorDirectionSelector\n- 633 {\n-634 typedef T1 solver_vector;\n-635 typedef typename solver_vector::reverse_iterator solver_iterator;\n-636 typedef T2 subdomain_vector;\n-637 typedef typename subdomain_vector::const_reverse_iterator domain_iterator;\n- 638\n-639 static solver_iterator begin(solver_vector& sv)\n- 640 {\n- 641 return sv.rbegin();\n- 642 }\n- 643\n-644 static solver_iterator end(solver_vector& sv)\n- 645 {\n- 646 return sv.rend();\n- 647 }\n-648 static domain_iterator begin(const subdomain_vector& sv)\n- 649 {\n- 650 return sv.rbegin();\n- 651 }\n- 652\n-653 static domain_iterator end(const subdomain_vector& sv)\n- 654 {\n- 655 return sv.rend();\n- 656 }\n- 657 };\n- 658\n- 667 template\n-668 struct SeqOverlappingSchwarzApplier\n- 669 {\n-670 typedef T smoother;\n-671 typedef typename smoother::range_type range_type;\n- 672\n-673 static void apply(smoother& sm, range_type& v, const range_type& b)\n- 674 {\n- 675 sm.template apply(v, b);\n- 676 }\n- 677 };\n- 678\n- 679 template\n-680 struct\n-SeqOverlappingSchwarzApplier\n->\n- 681 {\n-682 typedef SeqOverlappingSchwarz\n-smoother;\n-683 typedef typename smoother::range_type range_type;\n- 684\n-685 static void apply(smoother& sm, range_type& v, const range_type& b)\n- 686 {\n- 687 sm.template apply(v, b);\n- 688 sm.template apply(v, b);\n- 689 }\n- 690 };\n- 691\n- 692 template\n-693 struct SeqOverlappingSchwarzAssemblerHelper\n- 694 {};\n- 695\n- 696 template\n-697 using SeqOverlappingSchwarzAssembler =\n-SeqOverlappingSchwarzAssemblerHelper::value>;\n- 698\n- 699 template\n-700 struct SeqOverlappingSchwarzAssemblerHelper< DynamicMatrixSubdomainSolver<\n-BCRSMatrix< K, Al>, X, Y >,false>\n- 701 {\n-702 typedef BCRSMatrix<_K,_Al> matrix_type;\n-703 static constexpr size_t n = std::decay_t()))>::rows;\n- 704 template\n- 705 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n-const matrix_type& mat,\n- 706 Solvers& solvers, const SubDomains& domains,\n- 707 bool onTheFly);\n- 708 };\n- 709\n- 710 template class S, typename T, typename A>\n-711 struct SeqOverlappingSchwarzAssemblerHelper>,true>\n- 712 {\n-713 typedef BCRSMatrix matrix_type;\n-714 static constexpr size_t n = std::decay_t()))>::rows;\n- 715 template\n- 716 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n-const matrix_type& mat,\n- 717 Solvers& solvers, const SubDomains& domains,\n- 718 bool onTheFly);\n- 719 };\n- 720\n- 721 template\n-722 struct SeqOverlappingSchwarzAssemblerILUBase\n- 723 {\n-724 typedef M matrix_type;\n- 725 template\n- 726 static std::size_t assembleLocalProblems(const RowToDomain& rowToDomain,\n-const matrix_type& mat,\n- 727 Solvers& solvers, const SubDomains& domains,\n- 728 bool onTheFly);\n- 729 };\n- 730\n- 731 template\n-732 struct\n-SeqOverlappingSchwarzAssemblerHelper,false>\n- 733 : public SeqOverlappingSchwarzAssemblerILUBase\n- 734 {};\n- 735\n- 736 template\n-737 struct\n-SeqOverlappingSchwarzAssemblerHelper,false>\n- 738 : public SeqOverlappingSchwarzAssemblerILUBase\n- 739 {};\n- 740\n- 751 template, class TA=std::allocator >\n-753 class SeqOverlappingSchwarz\n- 754 : public Preconditioner\n- 755 {\n- 756 public:\n-760 typedef M matrix_type;\n- 761\n-765 typedef X domain_type;\n- 766\n-770 typedef X range_type;\n- 771\n-778 typedef TM Mode;\n- 779\n-783 typedef typename X::field_type field_type;\n- 784\n-786 typedef typename matrix_type::size_type size_type;\n- 787\n-789 typedef TA allocator;\n- 790\n- 792 typedef std::set,\n- 793 typename std::allocator_traits::template rebind_alloc >\n-794 subdomain_type;\n- 795\n-797 typedef std::vector::\n-template rebind_alloc > subdomain_vector;\n- 798\n-800 typedef SLList::template\n-rebind_alloc > subdomain_list;\n- 801\n-803 typedef std::vector::\n-template rebind_alloc > rowtodomain_vector;\n- 804\n-806 typedef TD slu;\n- 807\n-809 typedef std::vector::template\n-rebind_alloc > slu_vector;\n- 810\n-824 SeqOverlappingSchwarz(const matrix_type& mat, const subdomain_vector&\n-subDomains,\n- 825 field_type relaxationFactor=1, bool onTheFly_=true);\n- 826\n-838 SeqOverlappingSchwarz(const matrix_type& mat, const rowtodomain_vector&\n-rowToDomain,\n- 839 field_type relaxationFactor=1, bool onTheFly_=true);\n- 840\n-846 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] X& b)\n- 847 {}\n- 848\n-854 virtual void apply (X& v, const X& d);\n- 855\n-861 virtual void post ([[maybe_unused]] X& x)\n- 862 {}\n- 863\n- 864 template\n-865 void apply(X& v, const X& d);\n- 866\n-868 virtual SolverCategory::Category category() const\n- 869 {\n- 870 return SolverCategory::sequential;\n- 871 }\n- 872\n- 873 private:\n- 874 const M& mat;\n- 875 slu_vector solvers;\n- 876 subdomain_vector subDomains;\n- 877 field_type relax;\n- 878\n- 879 typename M::size_type maxlength;\n- 880\n- 881 bool onTheFly;\n- 882 };\n- 883\n- 884\n- 885\n- 886 template\n-887 OverlappingSchwarzInitializer::OverlappingSchwarzInitializer\n-(InitializerList& il,\n- 888 const IndexSet& idx,\n- 889 const subdomain_vector& domains_)\n- 890 : initializers(&il), indices(&idx), indexMaps(il.size()), domains\n-(domains_)\n- 891 {}\n- 892\n- 893\n- 894 template\n-895 void OverlappingSchwarzInitializer::addRowNnz(const Iter& row)\n- 896 {\n- 897 typedef typename IndexSet::value_type::const_iterator iterator;\n- 898 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)\n-[row.index()].end(); ++domain) {\n- 899 (*initializers)[*domain].addRowNnz(row, domains[*domain]);\n- 900 indexMaps[*domain].insert(row.index());\n- 901 }\n- 902 }\n- 903\n- 904 template\n-905 void OverlappingSchwarzInitializer::allocate()\n- 906 {\n- 907 for(auto&& i: *initializers)\n- 908 i.allocateMatrixStorage();\n- 909 for(auto&& i: *initializers)\n- 910 i.allocateMarker();\n- 911 }\n- 912\n- 913 template\n-914 void OverlappingSchwarzInitializer::countEntries(const Iter& row,\n-const CIter& col) const\n- 915 {\n- 916 typedef typename IndexSet::value_type::const_iterator iterator;\n- 917 for(iterator domain=(*indices)[row.index()].begin(); domain != (*indices)\n-[row.index()].end(); ++domain) {\n- 918 typename std::map::const_iterator v = indexMaps\n-[*domain].find(col.index());\n- 919 if(v!= indexMaps[*domain].end()) {\n- 920 (*initializers)[*domain].countEntries(indexMaps[*domain].find(col.index\n-())->second);\n- 921 }\n- 922 }\n- 923 }\n- 924\n- 925 template\n-926 void OverlappingSchwarzInitializer::calcColstart() const\n- 927 {\n- 928 for(auto&& i : *initializers)\n- 929 i.calcColstart();\n- 930 }\n- 931\n- 932 template\n-933 void OverlappingSchwarzInitializer::copyValue(const Iter& row, const\n-CIter& col) const\n- 934 {\n- 935 typedef typename IndexSet::value_type::const_iterator iterator;\n- 936 for(iterator domain=(*indices)[row.index()].begin(); domain!= (*indices)\n-[row.index()].end(); ++domain) {\n- 937 typename std::map::const_iterator v = indexMaps\n-[*domain].find(col.index());\n- 938 if(v!= indexMaps[*domain].end()) {\n- 939 assert(indexMaps[*domain].end()!=indexMaps[*domain].find(row.index()));\n- 940 (*initializers)[*domain].copyValue(col, indexMaps[*domain].find(row.index\n-())->second,\n- 941 v->second);\n- 942 }\n- 943 }\n- 944 }\n- 945\n- 946 template\n-947 void OverlappingSchwarzInitializer::createMatrix() const\n- 948 {\n- 949 std::vector().swap(indexMaps);\n- 950 for(auto&& i: *initializers)\n- 951 i.createMatrix();\n- 952 }\n- 953\n- 954 template\n-955 OverlappingSchwarzInitializer::IndexMap::IndexMap()\n- 956 : row(0)\n- 957 {}\n- 958\n- 959 template\n-960 void OverlappingSchwarzInitializer::IndexMap::insert(size_type grow)\n- 961 {\n- 962 assert(map_.find(grow)==map_.end());\n- 963 map_.insert(std::make_pair(grow, row++));\n- 964 }\n- 965\n- 966 template\n- 967 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n-968 OverlappingSchwarzInitializer::IndexMap::find(size_type grow) const\n- 969 {\n- 970 return map_.find(grow);\n- 971 }\n- 972\n- 973 template\n- 974 typename OverlappingSchwarzInitializer::IndexMap::iterator\n-975 OverlappingSchwarzInitializer::IndexMap::find(size_type grow)\n- 976 {\n- 977 return map_.find(grow);\n- 978 }\n- 979\n- 980 template\n- 981 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n-982 OverlappingSchwarzInitializer::IndexMap::end() const\n- 983 {\n- 984 return map_.end();\n- 985 }\n- 986\n- 987 template\n- 988 typename OverlappingSchwarzInitializer::IndexMap::iterator\n-989 OverlappingSchwarzInitializer::IndexMap::end()\n- 990 {\n- 991 return map_.end();\n- 992 }\n- 993\n- 994 template\n- 995 typename OverlappingSchwarzInitializer::IndexMap::const_iterator\n-996 OverlappingSchwarzInitializer::IndexMap::begin() const\n- 997 {\n- 998 return map_.begin();\n- 999 }\n- 1000\n- 1001 template\n- 1002 typename OverlappingSchwarzInitializer::IndexMap::iterator\n-1003 OverlappingSchwarzInitializer::IndexMap::begin()\n- 1004 {\n- 1005 return map_.begin();\n- 1006 }\n- 1007\n- 1008 template\n-1009 SeqOverlappingSchwarz::SeqOverlappingSchwarz(const\n-matrix_type& mat_, const rowtodomain_vector& rowToDomain,\n- 1010 field_type relaxationFactor, bool fly)\n- 1011 : mat(mat_), relax(relaxationFactor), onTheFly(fly)\n- 1012 {\n- 1013 typedef typename rowtodomain_vector::const_iterator RowDomainIterator;\n- 1014 typedef typename subdomain_list::const_iterator DomainIterator;\n- 1015#ifdef DUNE_ISTL_WITH_CHECKING\n- 1016 assert(rowToDomain.size()==mat.N());\n- 1017 assert(rowToDomain.size()==mat.M());\n- 1018\n- 1019 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n-(); ++iter)\n- 1020 assert(iter->size()>0);\n- 1021\n- 1022#endif\n- 1023 // calculate the number of domains\n- 1024 size_type domains=0;\n- 1025 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n-(); ++iter)\n- 1026 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)\n- 1027 domains=std::max(domains, *d);\n- 1028 ++domains;\n- 1029\n- 1030 solvers.resize(domains);\n- 1031 subDomains.resize(domains);\n- 1032\n- 1033 // initialize subdomains to row mapping from row to subdomain mapping\n- 1034 size_type row=0;\n- 1035 for(RowDomainIterator iter=rowToDomain.begin(); iter != rowToDomain.end\n-(); ++iter, ++row)\n- 1036 for(DomainIterator d=iter->begin(); d != iter->end(); ++d)\n- 1037 subDomains[*d].insert(row);\n- 1038\n- 1039#ifdef DUNE_ISTL_WITH_CHECKING\n- 1040 size_type i=0;\n- 1041 typedef typename subdomain_vector::const_iterator iterator;\n- 1042 for(iterator iter=subDomains.begin(); iter != subDomains.end(); ++iter) {\n- 1043 typedef typename subdomain_type::const_iterator entry_iterator;\n- 1044 Dune::dvverb<<\"domain \"<begin(); entry != iter->end(); ++entry)\n-{\n- 1046 Dune::dvverb<<\" \"<<*entry;\n- 1047 }\n- 1048 Dune::dvverb<\n- 1052::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);\n- 1053 }\n- 1054\n- 1055 template\n-1056 SeqOverlappingSchwarz::SeqOverlappingSchwarz(const\n-matrix_type& mat_,\n- 1057 const subdomain_vector& sd,\n- 1058 field_type relaxationFactor,\n- 1059 bool fly)\n- 1060 : mat(mat_), solvers(sd.size()), subDomains(sd), relax(relaxationFactor),\n- 1061 onTheFly(fly)\n- 1062 {\n- 1063 typedef typename subdomain_vector::const_iterator DomainIterator;\n- 1064\n- 1065#ifdef DUNE_ISTL_WITH_CHECKING\n- 1066 size_type i=0;\n- 1067\n- 1068 for(DomainIterator d=sd.begin(); d != sd.end(); ++d,++i) {\n- 1069 //std::cout<size()<size()>0);\n- 1071 typedef typename DomainIterator::value_type::const_iterator\n-entry_iterator;\n- 1072 Dune::dvverb<<\"domain \"<begin(); entry != d->end(); ++entry) {\n- 1074 Dune::dvverb<<\" \"<<*entry;\n- 1075 }\n- 1076 Dune::dvverb<begin(); row != domain->end(); ++row)\n- 1089 rowToDomain[*row].push_back(domainId);\n- 1090 }\n- 1091\n- 1092 maxlength = SeqOverlappingSchwarzAssembler\n- 1093::assembleLocalProblems(rowToDomain, mat, solvers, subDomains, onTheFly);\n- 1094 }\n- 1095\n- 1102 template\n-1103 struct SeqOverlappingSchwarzDomainSize {};\n- 1104\n- 1105 template\n-1106 struct SeqOverlappingSchwarzDomainSize >\n- 1107 {\n-1108 static constexpr size_t n = std::decay_t()))>::rows;\n-1109 static constexpr size_t m = std::decay_t()))>::cols;\n- 1110 template\n-1111 static int size(const Domain & d)\n- 1112 {\n- 1113 assert(n==m);\n- 1114 return m*d.size();\n- 1115 }\n- 1116 };\n- 1117\n- 1118 template\n- 1119 template\n- 1120 std::size_t\n-1121 SeqOverlappingSchwarzAssemblerHelper<_DynamicMatrixSubdomainSolver<\n-BCRSMatrix<_K,_Al>, X, Y >,false>::\n- 1122 assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,\n- 1123 [[maybe_unused]] const matrix_type& mat,\n- 1124 [[maybe_unused]] Solvers& solvers,\n- 1125 const SubDomains& subDomains,\n- 1126 [[maybe_unused]] bool onTheFly)\n- 1127 {\n- 1128 typedef typename SubDomains::const_iterator DomainIterator;\n- 1129 std::size_t maxlength = 0;\n- 1130\n- 1131 assert(onTheFly);\n- 1132\n- 1133 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n-++domain)\n- 1134 maxlength=std::max(maxlength, domain->size());\n- 1135 maxlength*=n;\n- 1136\n- 1137 return maxlength;\n- 1138 }\n- 1139\n- 1140#if HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n- 1141 template class S, typename T, typename A>\n- 1142 template\n-1143 std::size_t\n-SeqOverlappingSchwarzAssemblerHelper>,true>::\n-assembleLocalProblems(const RowToDomain& rowToDomain,\n- 1144 const matrix_type& mat,\n- 1145 Solvers& solvers,\n- 1146 const SubDomains& subDomains,\n- 1147 bool onTheFly)\n- 1148 {\n- 1149 typedef typename S>::MatrixInitializer MatrixInitializer;\n- 1150 typedef typename std::vector::iterator\n-InitializerIterator;\n- 1151 typedef typename SubDomains::const_iterator DomainIterator;\n- 1152 typedef typename Solvers::iterator SolverIterator;\n- 1153 std::size_t maxlength = 0;\n- 1154\n- 1155 if(onTheFly) {\n- 1156 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n-++domain)\n- 1157 maxlength=std::max(maxlength, domain->size());\n- 1158 maxlength*=Impl::asMatrix(*mat[0].begin()).N();\n- 1159 }else{\n- 1160 // initialize the initializers\n- 1161 DomainIterator domain=subDomains.begin();\n- 1162\n- 1163 // Create the initializers list.\n- 1164 std::vector initializers(subDomains.size());\n- 1165\n- 1166 SolverIterator solver=solvers.begin();\n- 1167 for(InitializerIterator initializer=initializers.begin();\n-initializer!=initializers.end();\n- 1168 ++initializer, ++solver, ++domain) {\n- 1169 solver->getInternalMatrix\n-().N_=SeqOverlappingSchwarzDomainSize::size(*domain);\n- 1170 solver->getInternalMatrix\n-().M_=SeqOverlappingSchwarzDomainSize::size(*domain);\n- 1171 //solver->setVerbosity(true);\n- 1172 *initializer=MatrixInitializer(solver->getInternalMatrix());\n- 1173 }\n- 1174\n- 1175 // Set up the supermatrices according to the subdomains\n- 1176 typedef OverlappingSchwarzInitializer,\n- 1177 RowToDomain, SubDomains> Initializer;\n- 1178\n- 1179 Initializer initializer(initializers, rowToDomain, subDomains);\n- 1180 copyToBCCSMatrix(initializer, mat);\n- 1181\n- 1182 // Calculate the LU decompositions\n- 1183 for(auto&& s: solvers)\n- 1184 s.decompose();\n- 1185 for (SolverIterator solverIt = solvers.begin(); solverIt != solvers.end\n-(); ++solverIt)\n- 1186 {\n- 1187 assert(solverIt->getInternalMatrix().N() == solverIt->getInternalMatrix\n-().M());\n- 1188 maxlength = std::max(maxlength, solverIt->getInternalMatrix().N());\n- 1189 }\n- 1190 }\n- 1191 return maxlength;\n- 1192 }\n- 1193\n- 1194#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n- 1195\n- 1196 template\n- 1197 template\n-1198 std::size_t SeqOverlappingSchwarzAssemblerILUBase::\n-assembleLocalProblems([[maybe_unused]] const RowToDomain& rowToDomain,\n- 1199 const matrix_type& mat,\n- 1200 Solvers& solvers,\n- 1201 const SubDomains& subDomains,\n- 1202 bool onTheFly)\n- 1203 {\n- 1204 typedef typename SubDomains::const_iterator DomainIterator;\n- 1205 typedef typename Solvers::iterator SolverIterator;\n- 1206 std::size_t maxlength = 0;\n- 1207\n- 1208 if(onTheFly) {\n- 1209 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n-++domain)\n- 1210 maxlength=std::max(maxlength, domain->size());\n- 1211 }else{\n- 1212 // initialize the solvers of the local prolems.\n- 1213 SolverIterator solver=solvers.begin();\n- 1214 for(DomainIterator domain=subDomains.begin(); domain!=subDomains.end();\n- 1215 ++domain, ++solver) {\n- 1216 solver->setSubMatrix(mat, *domain);\n- 1217 maxlength=std::max(maxlength, domain->size());\n- 1218 }\n- 1219 }\n- 1220\n- 1221 return maxlength;\n- 1222\n- 1223 }\n- 1224\n- 1225\n- 1226 template\n-1227 void SeqOverlappingSchwarz::apply(X& x, const X& b)\n- 1228 {\n- 1229 SeqOverlappingSchwarzApplier::apply(*this, x, b);\n- 1230 }\n- 1231\n- 1232 template\n- 1233 template\n- 1234 void SeqOverlappingSchwarz::apply(X& x, const X& b)\n- 1235 {\n- 1236 typedef slu_vector solver_vector;\n- 1237 typedef typename\n-IteratorDirectionSelector::\n-solver_iterator iterator;\n- 1238 typedef typename\n-IteratorDirectionSelector::\n-domain_iterator\n- 1239 domain_iterator;\n- 1240\n- 1241 OverlappingAssigner assigner(maxlength, mat, b, x);\n- 1242\n- 1243 domain_iterator\n-domain=IteratorDirectionSelector::begin\n-(subDomains);\n- 1244 iterator solver =\n-IteratorDirectionSelector::begin\n-(solvers);\n- 1245 X v(x); // temporary for the update\n- 1246 v=0;\n- 1247\n- 1248 typedef typename AdderSelector::Adder Adder;\n- 1249 Adder adder(v, x, assigner, relax);\n- 1250\n- 1251 for(; domain !=\n-IteratorDirectionSelector::end\n-(subDomains); ++domain) {\n- 1252 //Copy rhs to C-array for SuperLU\n- 1253 std::for_each(domain->begin(), domain->end(), assigner);\n- 1254 assigner.resetIndexForNextDomain();\n- 1255 if(onTheFly) {\n- 1256 // Create the subdomain solver\n- 1257 slu sdsolver;\n- 1258 sdsolver.setSubMatrix(mat, *domain);\n- 1259 // Apply\n- 1260 sdsolver.apply(assigner.lhs(), assigner.rhs());\n- 1261 }else{\n- 1262 solver->apply(assigner.lhs(), assigner.rhs());\n- 1263 ++solver;\n- 1264 }\n- 1265\n- 1266 //Add relaxed correction to from SuperLU to v\n- 1267 std::for_each(domain->begin(), domain->end(), adder);\n- 1268 assigner.resetIndexForNextDomain();\n- 1269\n- 1270 }\n- 1271\n- 1272 adder.axpy();\n- 1273 assigner.deallocate();\n- 1274 }\n- 1275\n- 1276 template\n- 1277 OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K,\n-Al>, X, Y >,false>\n-1278 ::OverlappingAssignerHelper(std::size_t maxlength, const BCRSMatrix& mat_,\n- 1279 const X& b_, Y& x_) :\n- 1280 mat(&mat_),\n- 1281 rhs_( new DynamicVector(maxlength, 42) ),\n- 1282 lhs_( new DynamicVector(maxlength, -42) ),\n- 1283 b(&b_),\n- 1284 x(&x_),\n- 1285 i(0),\n- 1286 maxlength_(maxlength)\n- 1287 {}\n- 1288\n- 1289 template\n- 1290 void\n- 1291 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1292 ::deallocate()\n- 1293 {\n- 1294 delete rhs_;\n- 1295 delete lhs_;\n- 1296 }\n- 1297\n- 1298 template\n- 1299 void\n- 1300 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1301 ::resetIndexForNextDomain()\n- 1302 {\n- 1303 i=0;\n- 1304 }\n- 1305\n- 1306 template\n- 1307 DynamicVector &\n- 1308 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1309 ::lhs()\n- 1310 {\n- 1311 return *lhs_;\n- 1312 }\n- 1313\n- 1314 template\n- 1315 DynamicVector &\n- 1316 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1317 ::rhs()\n- 1318 {\n- 1319 return *rhs_;\n- 1320 }\n- 1321\n- 1322 template\n- 1323 void\n- 1324 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1325 ::relaxResult(field_type relax)\n- 1326 {\n- 1327 lhs() *= relax;\n- 1328 }\n- 1329\n- 1330 template\n- 1331 void\n- 1332 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1333 ::operator()(const size_type& domainIndex)\n- 1334 {\n- 1335 lhs() = 0.0;\n- 1336#if 0\n- 1337 //assign right hand side of current domainindex block\n- 1338 for(size_type j=0; j\n- 1376 void\n- 1377 OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al>, X, Y >,false>\n-1378 ::assignResult(block_type& res)\n- 1379 {\n- 1380 // assign the result of the local solve to the global vector\n- 1381 for(size_type j=0; j class S, typename T, typename A>\n- 1390 OverlappingAssignerHelper>,true>\n-1391 ::OverlappingAssignerHelper(std::size_t maxlength,\n- 1392 const BCRSMatrix& mat_,\n- 1393 const range_type& b_,\n- 1394 range_type& x_)\n- 1395 : mat(&mat_),\n- 1396 b(&b_),\n- 1397 x(&x_), i(0), maxlength_(maxlength)\n- 1398 {\n- 1399 rhs_ = new field_type[maxlength];\n- 1400 lhs_ = new field_type[maxlength];\n- 1401\n- 1402 }\n- 1403\n- 1404 template class S, typename T, typename A>\n-1405 void OverlappingAssignerHelper >,true>::deallocate()\n- 1406 {\n- 1407 delete[] rhs_;\n- 1408 delete[] lhs_;\n- 1409 }\n- 1410\n- 1411 template class S, typename T, typename A>\n-1412 void OverlappingAssignerHelper>,true>::operator()(const\n-size_type& domainIndex)\n- 1413 {\n- 1414 //assign right hand side of current domainindex block\n- 1415 // rhs is an array of doubles!\n- 1416 // rhs[starti] = b[domainindex]\n- 1417 for(size_type j=0; j class S, typename T, typename A>\n-1441 void OverlappingAssignerHelper>,true>::relaxResult\n-(field_type relax)\n- 1442 {\n- 1443 for(size_type j=i+n; i class S, typename T, typename A>\n-1451 void OverlappingAssignerHelper>,true>::assignResult\n-(block_type& res)\n- 1452 {\n- 1453 // assign the result of the local solve to the global vector\n- 1454 for(size_type j=0; j class S, typename T, typename A>\n-1461 void OverlappingAssignerHelper>,true>::\n-resetIndexForNextDomain()\n- 1462 {\n- 1463 i=0;\n- 1464 }\n- 1465\n- 1466 template class S, typename T, typename A>\n- 1467 typename OverlappingAssignerHelper>,true>::field_type*\n-1468 OverlappingAssignerHelper>,true>::lhs()\n- 1469 {\n- 1470 return lhs_;\n- 1471 }\n- 1472\n- 1473 template class S, typename T, typename A>\n- 1474 typename OverlappingAssignerHelper>,true>::field_type*\n-1475 OverlappingAssignerHelper>,true>::rhs()\n- 1476 {\n- 1477 return rhs_;\n- 1478 }\n- 1479\n- 1480#endif // HAVE_SUPERLU || HAVE_SUITESPARSE_UMFPACK\n- 1481\n- 1482 template\n-1483 OverlappingAssignerILUBase::OverlappingAssignerILUBase(std::size_t\n-maxlength,\n- 1484 const M& mat_,\n- 1485 const Y& b_,\n- 1486 X& x_)\n- 1487 : mat(&mat_),\n- 1488 b(&b_),\n- 1489 x(&x_), i(0)\n- 1490 {\n- 1491 rhs_= new Y(maxlength);\n- 1492 lhs_ = new X(maxlength);\n- 1493 }\n- 1494\n- 1495 template\n-1496 void OverlappingAssignerILUBase::deallocate()\n- 1497 {\n- 1498 delete rhs_;\n- 1499 delete lhs_;\n- 1500 }\n- 1501\n- 1502 template\n-1503 void OverlappingAssignerILUBase::operator()(const size_type&\n-domainIndex)\n- 1504 {\n- 1505 (*rhs_)[i]=(*b)[domainIndex];\n- 1506\n- 1507 // loop over all Matrix row entries and calculate defect.\n- 1508 typedef typename matrix_type::ConstColIterator col_iterator;\n- 1509\n- 1510 // calculate defect for current row index block\n- 1511 for(col_iterator col=(*mat)[domainIndex].begin(); col!=(*mat)\n-[domainIndex].end(); ++col) {\n- 1512 Impl::asMatrix(*col).mmv((*x)[col.index()], (*rhs_)[i]);\n- 1513 }\n- 1514 // Goto next local index\n- 1515 ++i;\n- 1516 }\n- 1517\n- 1518 template\n-1519 void OverlappingAssignerILUBase::relaxResult(field_type relax)\n- 1520 {\n- 1521 (*lhs_)[i]*=relax;\n- 1522 }\n- 1523\n- 1524 template\n-1525 void OverlappingAssignerILUBase::assignResult(block_type& res)\n- 1526 {\n- 1527 res+=(*lhs_)[i++];\n- 1528 }\n- 1529\n- 1530 template\n-1531 X& OverlappingAssignerILUBase::lhs()\n- 1532 {\n- 1533 return *lhs_;\n- 1534 }\n- 1535\n- 1536 template\n-1537 Y& OverlappingAssignerILUBase::rhs()\n- 1538 {\n- 1539 return *rhs_;\n- 1540 }\n- 1541\n- 1542 template\n-1543 void OverlappingAssignerILUBase::resetIndexForNextDomain()\n- 1544 {\n- 1545 i=0;\n- 1546 }\n- 1547\n- 1548 template\n-1549 AdditiveAdder >::AdditiveAdder(BlockVector& v_,\n- 1550 BlockVector& x_,\n- 1551 OverlappingAssigner& assigner_,\n- 1552 const field_type& relax_)\n- 1553 : v(&v_), x(&x_), assigner(&assigner_), relax(relax_)\n- 1554 {}\n- 1555\n- 1556 template\n-1557 void AdditiveAdder >::operator()(const size_type&\n-domainIndex)\n- 1558 {\n- 1559 // add the result of the local solve to the current update\n- 1560 assigner->assignResult((*v)[domainIndex]);\n- 1561 }\n- 1562\n- 1563\n- 1564 template\n-1565 void AdditiveAdder >::axpy()\n- 1566 {\n- 1567 // relax the update and add it to the current guess.\n- 1568 x->axpy(relax,*v);\n- 1569 }\n- 1570\n- 1571\n- 1572 template\n- 1573 MultiplicativeAdder >\n-1574 ::MultiplicativeAdder([[maybe_unused]] BlockVector& v_,\n- 1575 BlockVector& x_,\n- 1576 OverlappingAssigner& assigner_, const field_type& relax_)\n- 1577 : x(&x_), assigner(&assigner_), relax(relax_)\n- 1578 {}\n- 1579\n- 1580\n- 1581 template\n-1582 void MultiplicativeAdder >::operator()(const size_type&\n-domainIndex)\n- 1583 {\n- 1584 // add the result of the local solve to the current guess\n- 1585 assigner->relaxResult(relax);\n- 1586 assigner->assignResult((*x)[domainIndex]);\n- 1587 }\n- 1588\n- 1589\n- 1590 template\n-1591 void MultiplicativeAdder >::axpy()\n- 1592 {\n- 1593 // nothing to do, as the corrections already relaxed and added in\n-operator()\n- 1594 }\n- 1595\n- 1596\n- 1598}\n- 1599\n- 1600#endif\n-solvertype.hh\n-Templates characterizing the type of a solver.\n-preconditioners.hh\n-Define general preconditioner interface.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-umfpack.hh\n-Classes for using UMFPack with ISTL matrices.\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-ilusubdomainsolver.hh\n-Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.\n-superlu.hh\n-Classes for using SuperLU with ISTL matrices.\n-bccsmatrixinitializer.hh\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::OverlappingSchwarzInitializer::addRowNnz\n-void addRowNnz(const Iter &row)\n-Definition: overlappingschwarz.hh:895\n-Dune::OverlappingAssignerILUBase::lhs\n-X & lhs()\n-Get the local left hand side.\n-Definition: overlappingschwarz.hh:1531\n-Dune::OverlappingSchwarzInitializer::calcColstart\n-void calcColstart() const\n-Definition: overlappingschwarz.hh:926\n-Dune::OverlappingAssignerILUBase::rhs\n-Y & rhs()\n-Get the local right hand side.\n-Definition: overlappingschwarz.hh:1537\n-Dune::OverlappingAssignerILUBase::resetIndexForNextDomain\n-void resetIndexForNextDomain()\n-Resets the local index to zero.\n-Definition: overlappingschwarz.hh:1543\n-Dune::OverlappingSchwarzInitializer::copyValue\n-void copyValue(const Iter &row, const CIter &col) const\n-Definition: overlappingschwarz.hh:933\n-Dune::OverlappingSchwarzInitializer::createMatrix\n-void createMatrix() const\n-Definition: overlappingschwarz.hh:947\n-Dune::OverlappingSchwarzInitializer::OverlappingSchwarzInitializer\n-OverlappingSchwarzInitializer(InitializerList &il, const IndexSet &indices,\n-const subdomain_vector &domains)\n-Definition: overlappingschwarz.hh:887\n-Dune::SeqOverlappingSchwarz::apply\n-virtual void apply(X &v, const X &d)\n-Apply the precondtioner.\n-Definition: overlappingschwarz.hh:1227\n-Dune::OverlappingAssignerILUBase::OverlappingAssignerILUBase\n-OverlappingAssignerILUBase(std::size_t maxlength, const M &mat, const Y &b, X\n-&x)\n-Constructor.\n-Definition: overlappingschwarz.hh:1483\n-Dune::OverlappingAssignerILUBase::operator()\n-void operator()(const size_type &domain)\n-calculate one entry of the local defect.\n-Definition: overlappingschwarz.hh:1503\n-Dune::SeqOverlappingSchwarz::SeqOverlappingSchwarz\n-SeqOverlappingSchwarz(const matrix_type &mat, const subdomain_vector\n-&subDomains, field_type relaxationFactor=1, bool onTheFly_=true)\n-Construct the overlapping Schwarz method.\n-Definition: overlappingschwarz.hh:1056\n-Dune::OverlappingSchwarzInitializer::allocate\n-void allocate()\n-Definition: overlappingschwarz.hh:905\n-Dune::OverlappingAssignerILUBase::deallocate\n-void deallocate()\n-Deallocates memory of the local vector.\n-Definition: overlappingschwarz.hh:1496\n-Dune::OverlappingSchwarzInitializer::countEntries\n-void countEntries(const Iter &row, const CIter &col) const\n-Definition: overlappingschwarz.hh:914\n-Dune::SeqOverlappingSchwarzAssemblerILUBase::assembleLocalProblems\n-static std::size_t assembleLocalProblems(const RowToDomain &rowToDomain, const\n-matrix_type &mat, Solvers &solvers, const SubDomains &domains, bool onTheFly)\n-Definition: overlappingschwarz.hh:1198\n-Dune::OverlappingAssignerILUBase::relaxResult\n-void relaxResult(field_type relax)\n-relax the result.\n-Definition: overlappingschwarz.hh:1519\n-Dune::OverlappingAssignerILUBase::assignResult\n-void assignResult(block_type &res)\n-Assigns the block to the current local index. At the same time the local defect\n-is calculated for the...\n-Definition: overlappingschwarz.hh:1525\n-Dune::SeqOverlappingSchwarz::SeqOverlappingSchwarz\n-SeqOverlappingSchwarz(const matrix_type &mat, const rowtodomain_vector\n-&rowToDomain, field_type relaxationFactor=1, bool onTheFly_=true)\n-Definition: overlappingschwarz.hh:1009\n+ 613 static const int N = MultiTypeBlockMatrix::N\n+();\n+ 614 Dune::MultiTypeBlockMatrix_Solver::dbjac(A, x, b, w);\n+ 615 }\n+ 616 };\n+ 617\n+ 618 // user calls\n+ 619\n+ 621 template\n+622 void dbgs (const M& A, X& x, const Y& b, const K& w)\n+ 623 {\n+ 624 algmeta_itsteps<1,M>::dbgs(A,x,b,w);\n+ 625 }\n+ 627 template\n+628 void dbgs (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n+ 629 {\n+ 630 algmeta_itsteps::dbgs(A,x,b,w);\n+ 631 }\n+ 633 template\n+634 void bsorf (const M& A, X& x, const Y& b, const K& w)\n+ 635 {\n+ 636 algmeta_itsteps<1,M>::bsorf(A,x,b,w);\n+ 637 }\n+ 639 template\n+640 void bsorf (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n+ 641 {\n+ 642 algmeta_itsteps::bsorf(A,x,b,w);\n+ 643 }\n+ 645 template\n+646 void bsorb (const M& A, X& x, const Y& b, const K& w)\n+ 647 {\n+ 648 algmeta_itsteps<1,M>::bsorb(A,x,b,w);\n+ 649 }\n+ 651 template\n+652 void bsorb (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n+ 653 {\n+ 654 algmeta_itsteps::type>::bsorb(A,x,b,w);\n+ 655 }\n+ 657 template\n+658 void dbjac (const M& A, X& x, const Y& b, const K& w)\n+ 659 {\n+ 660 algmeta_itsteps<1,M>::dbjac(A,x,b,w);\n+ 661 }\n+ 663 template\n+664 void dbjac (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n+ 665 {\n+ 666 algmeta_itsteps::dbjac(A,x,b,w);\n+ 667 }\n+ 668\n+ 669\n+ 672} // end namespace\n+ 673\n+ 674#endif\n+multitypeblockmatrix.hh\n+multitypeblockvector.hh\n+istlexception.hh\n+Dune::MultiTypeBlockMatrix_Solver::dbjac\n+static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:568\n+Dune::MultiTypeBlockMatrix_Solver::dbgs\n+static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:484\n+Dune::MultiTypeBlockMatrix_Solver::bsorb\n+static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:540\n+Dune::MultiTypeBlockMatrix::N\n+static constexpr size_type N()\n+Return the number of matrix rows.\n+Definition: multitypeblockmatrix.hh:64\n+Dune::MultiTypeBlockMatrix_Solver::bsorf\n+static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n+Definition: multitypeblockmatrix.hh:513\n+Dune::bltsolve\n+void bltsolve(const M &A, X &v, const Y &d)\n+block lower triangular solve\n+Definition: gsetc.hh:175\n+Dune::WithDiagType\n+WithDiagType\n+Definition: gsetc.hh:49\n+Dune::bsorb\n+void bsorb(const M &A, X &x, const Y &b, const K &w)\n+SSOR step.\n+Definition: gsetc.hh:646\n+Dune::ubltsolve\n+void ubltsolve(const M &A, X &v, const Y &d)\n+unit block lower triangular solve\n+Definition: gsetc.hh:188\n+Dune::dbjac\n+void dbjac(const M &A, X &x, const Y &b, const K &w)\n+Jacobi step.\n+Definition: gsetc.hh:658\n+Dune::dbgs\n+void dbgs(const M &A, X &x, const Y &b, const K &w)\n+GS step.\n+Definition: gsetc.hh:622\n+Dune::WithRelaxType\n+WithRelaxType\n+Definition: gsetc.hh:54\n+Dune::bdsolve\n+void bdsolve(const M &A, X &v, const Y &d)\n+block diagonal solve, no relaxation\n+Definition: gsetc.hh:337\n+Dune::butsolve\n+void butsolve(const M &A, X &v, const Y &d)\n+block upper triangular solve\n+Definition: gsetc.hh:202\n+Dune::bsorf\n+void bsorf(const M &A, X &x, const Y &b, const K &w)\n+SOR step.\n+Definition: gsetc.hh:634\n+Dune::ubutsolve\n+void ubutsolve(const M &A, X &v, const Y &d)\n+unit block upper triangular solve\n+Definition: gsetc.hh:215\n+Dune::nodiag\n+@ nodiag\n+Definition: gsetc.hh:51\n+Dune::withdiag\n+@ withdiag\n+Definition: gsetc.hh:50\n+Dune::norelax\n+@ norelax\n+Definition: gsetc.hh:56\n+Dune::withrelax\n+@ withrelax\n+Definition: gsetc.hh:55\n Dune\n Definition: allocator.hh:11\n-Dune::OverlappingSchwarzInitializer\n-Initializer for SuperLU Matrices representing the subdomains.\n-Definition: overlappingschwarz.hh:47\n-Dune::OverlappingSchwarzInitializer::CIter\n-Matrix::row_type::const_iterator CIter\n-Definition: overlappingschwarz.hh:56\n-Dune::OverlappingSchwarzInitializer::IndexSet\n-S IndexSet\n-Definition: overlappingschwarz.hh:58\n-Dune::OverlappingSchwarzInitializer::Iter\n-Matrix::const_iterator Iter\n-Definition: overlappingschwarz.hh:55\n-Dune::OverlappingSchwarzInitializer::size_type\n-IndexSet::size_type size_type\n-Definition: overlappingschwarz.hh:59\n-Dune::OverlappingSchwarzInitializer::InitializerList\n-I InitializerList\n-Definition: overlappingschwarz.hh:52\n-Dune::OverlappingSchwarzInitializer::Matrix\n-AtomInitializer::Matrix Matrix\n-Definition: overlappingschwarz.hh:54\n-Dune::OverlappingSchwarzInitializer::AtomInitializer\n-InitializerList::value_type AtomInitializer\n-Definition: overlappingschwarz.hh:53\n-Dune::OverlappingSchwarzInitializer::subdomain_vector\n-D subdomain_vector\n-The vector type containing the subdomain to row index mapping.\n-Definition: overlappingschwarz.hh:50\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::BCRSMatrix::size_type\n-A::size_type size_type\n-The type for the index access and the size.\n-Definition: bcrsmatrix.hh:500\n-Dune::BCRSMatrix::ConstColIterator\n-row_type::ConstIterator ConstColIterator\n-Const iterator to the entries of a row.\n-Definition: bcrsmatrix.hh:741\n-Dune::BlockVector\n-A vector of blocks with memory management.\n-Definition: bvector.hh:395\n-Dune::ILU0SubdomainSolver\n-Exact subdomain solver using ILU(p) with appropriate p.\n-Definition: ilusubdomainsolver.hh:78\n-Dune::ILUNSubdomainSolver\n-Definition: ilusubdomainsolver.hh:111\n-Dune::SeqOverlappingSchwarz\n-Sequential overlapping Schwarz preconditioner.\n-Definition: overlappingschwarz.hh:755\n-Dune::SeqOverlappingSchwarz::field_type\n-X::field_type field_type\n-The field type of the preconditioner.\n-Definition: overlappingschwarz.hh:783\n-Dune::SeqOverlappingSchwarz::apply\n-void apply(X &v, const X &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Dune::SeqOverlappingSchwarz::subdomain_list\n-SLList< size_type, typename std::allocator_traits< TA >::template rebind_alloc<\n-size_type > > subdomain_list\n-The type for the row to subdomain mapping.\n-Definition: overlappingschwarz.hh:800\n-Dune::SeqOverlappingSchwarz::slu_vector\n-std::vector< slu, typename std::allocator_traits< TA >::template rebind_alloc<\n-slu > > slu_vector\n-The vector type containing subdomain solvers.\n-Definition: overlappingschwarz.hh:809\n-Dune::SeqOverlappingSchwarz::matrix_type\n-M matrix_type\n-The type of the matrix to precondition.\n-Definition: overlappingschwarz.hh:760\n-Dune::SeqOverlappingSchwarz::Mode\n-TM Mode\n-The mode (additive or multiplicative) of the Schwarz method.\n-Definition: overlappingschwarz.hh:778\n-Dune::SeqOverlappingSchwarz::range_type\n-X range_type\n-The range type of the preconditioner.\n-Definition: overlappingschwarz.hh:770\n-Dune::SeqOverlappingSchwarz::subdomain_type\n-std::set< size_type, std::less< size_type >, typename std::allocator_traits< TA\n->::template rebind_alloc< size_type > > subdomain_type\n-The type for the subdomain to row index mapping.\n-Definition: overlappingschwarz.hh:794\n-Dune::SeqOverlappingSchwarz::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: overlappingschwarz.hh:765\n-Dune::SeqOverlappingSchwarz::slu\n-TD slu\n-The type for the subdomain solver in use.\n-Definition: overlappingschwarz.hh:806\n-Dune::SeqOverlappingSchwarz::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: overlappingschwarz.hh:868\n-Dune::SeqOverlappingSchwarz::pre\n-virtual void pre(X &x, X &b)\n-Prepare the preconditioner.\n-Definition: overlappingschwarz.hh:846\n-Dune::SeqOverlappingSchwarz::post\n-virtual void post(X &x)\n-Postprocess the preconditioner.\n-Definition: overlappingschwarz.hh:861\n-Dune::SeqOverlappingSchwarz::allocator\n-TA allocator\n-The allocator to use.\n-Definition: overlappingschwarz.hh:789\n-Dune::SeqOverlappingSchwarz::subdomain_vector\n-std::vector< subdomain_type, typename std::allocator_traits< TA >::template\n-rebind_alloc< subdomain_type > > subdomain_vector\n-The vector type containing the subdomain to row index mapping.\n-Definition: overlappingschwarz.hh:797\n-Dune::SeqOverlappingSchwarz::rowtodomain_vector\n-std::vector< subdomain_list, typename std::allocator_traits< TA >::template\n-rebind_alloc< subdomain_list > > rowtodomain_vector\n-The vector type containing the row index to subdomain mapping.\n-Definition: overlappingschwarz.hh:803\n-Dune::SeqOverlappingSchwarz::size_type\n-matrix_type::size_type size_type\n-The return type of the size method.\n-Definition: overlappingschwarz.hh:786\n-Dune::SeqOverlappingSchwarzAssemblerHelper\n-Definition: overlappingschwarz.hh:694\n-Dune::AdditiveSchwarzMode\n-Tag that the tells the Schwarz method to be additive.\n-Definition: overlappingschwarz.hh:120\n-Dune::MultiplicativeSchwarzMode\n-Tag that tells the Schwarz method to be multiplicative.\n-Definition: overlappingschwarz.hh:126\n-Dune::SymmetricMultiplicativeSchwarzMode\n-Tag that tells the Schwarz method to be multiplicative and symmetric.\n-Definition: overlappingschwarz.hh:133\n-Dune::DynamicMatrixSubdomainSolver\n-Exact subdomain solver using Dune::DynamicMatrix::solve.\n-Definition: overlappingschwarz.hh:140\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::matrix_type\n-std::remove_const< M >::type matrix_type\n-The matrix type the preconditioner is for.\n-Definition: overlappingschwarz.hh:149\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::field_type\n-X::field_type field_type\n-Definition: overlappingschwarz.hh:150\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::domain_type\n-X domain_type\n-The domain type of the preconditioner.\n-Definition: overlappingschwarz.hh:153\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::range_type\n-Y range_type\n-The range type of the preconditioner.\n-Definition: overlappingschwarz.hh:155\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::setSubMatrix\n-void setSubMatrix(const M &BCRS, S &rowset)\n-Set the data of the local problem.\n-Definition: overlappingschwarz.hh:184\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::apply\n-void apply(DynamicVector< field_type > &v, DynamicVector< field_type > &d)\n-Apply the subdomain solver.\n-Definition: overlappingschwarz.hh:162\n-Dune::DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,_Al_>,_X,_Y_>::rilu_type\n-std::remove_const< M >::type rilu_type\n-Definition: overlappingschwarz.hh:151\n-Dune::OverlappingAssignerHelper\n-Definition: overlappingschwarz.hh:215\n-Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al_>,_X,_Y_>,_false_>::size_type\n-matrix_type::size_type size_type\n-Definition: overlappingschwarz.hh:229\n-Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al_>,_X,_Y_>,_false_>::field_type\n-X::field_type field_type\n-Definition: overlappingschwarz.hh:226\n-Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al_>,_X,_Y_>,_false_>::matrix_type\n-BCRSMatrix< K, Al > matrix_type\n-Definition: overlappingschwarz.hh:225\n-Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al_>,_X,_Y_>,_false_>::range_type\n-Y range_type\n-Definition: overlappingschwarz.hh:227\n-Dune::OverlappingAssignerHelper<_DynamicMatrixSubdomainSolver<_BCRSMatrix<_K,\n-Al_>,_X,_Y_>,_false_>::block_type\n-range_type::block_type block_type\n-Definition: overlappingschwarz.hh:228\n-Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::range_type\n-S< BCRSMatrix< T, A > >::range_type range_type\n-Definition: overlappingschwarz.hh:315\n-Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::block_type\n-range_type::block_type block_type\n-Definition: overlappingschwarz.hh:317\n-Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::field_type\n-range_type::field_type field_type\n-Definition: overlappingschwarz.hh:316\n-Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::size_type\n-matrix_type::size_type size_type\n-Definition: overlappingschwarz.hh:319\n-Dune::OverlappingAssignerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::matrix_type\n-BCRSMatrix< T, A > matrix_type\n-Definition: overlappingschwarz.hh:314\n-Dune::OverlappingAssignerILUBase\n-Definition: overlappingschwarz.hh:400\n-Dune::OverlappingAssignerILUBase::size_type\n-matrix_type::size_type size_type\n-Definition: overlappingschwarz.hh:408\n-Dune::OverlappingAssignerILUBase::field_type\n-Y::field_type field_type\n-Definition: overlappingschwarz.hh:404\n-Dune::OverlappingAssignerILUBase::block_type\n-Y::block_type block_type\n-Definition: overlappingschwarz.hh:406\n-Dune::OverlappingAssignerILUBase::matrix_type\n-M matrix_type\n-Definition: overlappingschwarz.hh:402\n-Dune::OverlappingAssignerHelper<_ILU0SubdomainSolver<_M,_X,_Y_>,_false_>::\n-OverlappingAssignerHelper\n-OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X\n-&x)\n-Constructor.\n-Definition: overlappingschwarz.hh:493\n-Dune::OverlappingAssignerHelper<_ILUNSubdomainSolver<_M,_X,_Y_>,_false_>::\n-OverlappingAssignerHelper\n-OverlappingAssignerHelper(std::size_t maxlength, const M &mat, const Y &b, X\n-&x)\n-Constructor.\n-Definition: overlappingschwarz.hh:512\n-Dune::AdditiveAdder\n-Definition: overlappingschwarz.hh:520\n-Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>::field_type\n-std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type\n-field_type\n-Definition: overlappingschwarz.hh:526\n-Dune::AdditiveAdder<_S,_BlockVector<_T,_A_>_>::size_type\n-A::size_type size_type\n-Definition: overlappingschwarz.hh:525\n-Dune::MultiplicativeAdder\n-Definition: overlappingschwarz.hh:542\n-Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>::size_type\n-A::size_type size_type\n-Definition: overlappingschwarz.hh:547\n-Dune::MultiplicativeAdder<_S,_BlockVector<_T,_A_>_>::field_type\n-std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type\n-field_type\n-Definition: overlappingschwarz.hh:548\n-Dune::AdderSelector\n-template meta program for choosing how to add the correction.\n-Definition: overlappingschwarz.hh:572\n-Dune::AdderSelector<_AdditiveSchwarzMode,_X,_S_>::Adder\n-AdditiveAdder< S, X > Adder\n-Definition: overlappingschwarz.hh:577\n-Dune::AdderSelector<_MultiplicativeSchwarzMode,_X,_S_>::Adder\n-MultiplicativeAdder< S, X > Adder\n-Definition: overlappingschwarz.hh:583\n-Dune::AdderSelector<_SymmetricMultiplicativeSchwarzMode,_X,_S_>::Adder\n-MultiplicativeAdder< S, X > Adder\n-Definition: overlappingschwarz.hh:589\n-Dune::IteratorDirectionSelector\n-Helper template meta program for application of overlapping Schwarz.\n-Definition: overlappingschwarz.hh:605\n-Dune::IteratorDirectionSelector::begin\n-static solver_iterator begin(solver_vector &sv)\n-Definition: overlappingschwarz.hh:611\n-Dune::IteratorDirectionSelector::solver_iterator\n-solver_vector::iterator solver_iterator\n-Definition: overlappingschwarz.hh:607\n-Dune::IteratorDirectionSelector::end\n-static domain_iterator end(const subdomain_vector &sv)\n-Definition: overlappingschwarz.hh:625\n-Dune::IteratorDirectionSelector::domain_iterator\n-subdomain_vector::const_iterator domain_iterator\n-Definition: overlappingschwarz.hh:609\n-Dune::IteratorDirectionSelector::solver_vector\n-T1 solver_vector\n-Definition: overlappingschwarz.hh:606\n-Dune::IteratorDirectionSelector::begin\n-static domain_iterator begin(const subdomain_vector &sv)\n-Definition: overlappingschwarz.hh:620\n-Dune::IteratorDirectionSelector::subdomain_vector\n-T2 subdomain_vector\n-Definition: overlappingschwarz.hh:608\n-Dune::IteratorDirectionSelector::end\n-static solver_iterator end(solver_vector &sv)\n-Definition: overlappingschwarz.hh:616\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::subdomain_vector\n-T2 subdomain_vector\n-Definition: overlappingschwarz.hh:636\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::end\n-static solver_iterator end(solver_vector &sv)\n-Definition: overlappingschwarz.hh:644\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::solver_iterator\n-solver_vector::reverse_iterator solver_iterator\n-Definition: overlappingschwarz.hh:635\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::domain_iterator\n-subdomain_vector::const_reverse_iterator domain_iterator\n-Definition: overlappingschwarz.hh:637\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::begin\n-static solver_iterator begin(solver_vector &sv)\n-Definition: overlappingschwarz.hh:639\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::solver_vector\n-T1 solver_vector\n-Definition: overlappingschwarz.hh:634\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::begin\n-static domain_iterator begin(const subdomain_vector &sv)\n-Definition: overlappingschwarz.hh:648\n-Dune::IteratorDirectionSelector<_T1,_T2,_false_>::end\n-static domain_iterator end(const subdomain_vector &sv)\n-Definition: overlappingschwarz.hh:653\n-Dune::SeqOverlappingSchwarzApplier\n-Helper template meta program for application of overlapping Schwarz.\n-Definition: overlappingschwarz.hh:669\n-Dune::SeqOverlappingSchwarzApplier::range_type\n-smoother::range_type range_type\n-Definition: overlappingschwarz.hh:671\n-Dune::SeqOverlappingSchwarzApplier::smoother\n-T smoother\n-Definition: overlappingschwarz.hh:670\n-Dune::SeqOverlappingSchwarzApplier::apply\n-static void apply(smoother &sm, range_type &v, const range_type &b)\n-Definition: overlappingschwarz.hh:673\n-Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n-SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::apply\n-static void apply(smoother &sm, range_type &v, const range_type &b)\n-Definition: overlappingschwarz.hh:685\n-Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n-SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::smoother\n-SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA >\n-smoother\n-Definition: overlappingschwarz.hh:682\n-Dune::SeqOverlappingSchwarzApplier<_SeqOverlappingSchwarz<_M,_X,\n-SymmetricMultiplicativeSchwarzMode,_TD,_TA_>_>::range_type\n-smoother::range_type range_type\n-Definition: overlappingschwarz.hh:683\n-Dune::SeqOverlappingSchwarzAssemblerHelper<_DynamicMatrixSubdomainSolver<\n-BCRSMatrix<_K,_Al_>,_X,_Y_>,_false_>::matrix_type\n-BCRSMatrix< K, Al > matrix_type\n-Definition: overlappingschwarz.hh:702\n-Dune::SeqOverlappingSchwarzAssemblerHelper<_S<_BCRSMatrix<_T,_A_>_>,_true_>::\n-matrix_type\n-BCRSMatrix< T, A > matrix_type\n-Definition: overlappingschwarz.hh:713\n-Dune::SeqOverlappingSchwarzAssemblerILUBase\n-Definition: overlappingschwarz.hh:723\n-Dune::SeqOverlappingSchwarzAssemblerILUBase::matrix_type\n-M matrix_type\n-Definition: overlappingschwarz.hh:724\n-Dune::SeqOverlappingSchwarzDomainSize\n-Definition: overlappingschwarz.hh:1103\n-Dune::SeqOverlappingSchwarzDomainSize<_BCRSMatrix<_T,_A_>_>::size\n-static int size(const Domain &d)\n-Definition: overlappingschwarz.hh:1111\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::sequential\n-@ sequential\n-Category for sequential solvers.\n-Definition: solvercategory.hh:25\n+Dune::MultiTypeBlockVector\n+A Vector class to support different block types.\n+Definition: multitypeblockvector.hh:59\n+Dune::MultiTypeBlockMatrix\n+A Matrix class to support different block types.\n+Definition: multitypeblockmatrix.hh:46\n+Dune::BL\n+compile-time parameter for block recursion depth\n+Definition: gsetc.hh:45\n+Dune::BL::recursion_level\n+@ recursion_level\n+Definition: gsetc.hh:46\n+Dune::algmeta_btsolve\n+Definition: gsetc.hh:69\n+Dune::algmeta_btsolve::butsolve\n+static void butsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:90\n+Dune::algmeta_btsolve::bltsolve\n+static void bltsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:71\n+Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>::bltsolve\n+static void bltsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:114\n+Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>::butsolve\n+static void butsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:120\n+Dune::algmeta_btsolve<_0,_withdiag,_norelax_>::bltsolve\n+static void bltsolve(const M &A, X &v, const Y &d, const K &)\n+Definition: gsetc.hh:129\n+Dune::algmeta_btsolve<_0,_withdiag,_norelax_>::butsolve\n+static void butsolve(const M &A, X &v, const Y &d, const K &)\n+Definition: gsetc.hh:134\n+Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>::bltsolve\n+static void bltsolve(const M &, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:142\n+Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>::butsolve\n+static void butsolve(const M &, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:148\n+Dune::algmeta_btsolve<_0,_nodiag,_norelax_>::bltsolve\n+static void bltsolve(const M &, X &v, const Y &d, const K &)\n+Definition: gsetc.hh:157\n+Dune::algmeta_btsolve<_0,_nodiag,_norelax_>::butsolve\n+static void butsolve(const M &, X &v, const Y &d, const K &)\n+Definition: gsetc.hh:162\n+Dune::algmeta_bdsolve\n+Definition: gsetc.hh:294\n+Dune::algmeta_bdsolve::bdsolve\n+static void bdsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:296\n+Dune::algmeta_bdsolve<_0,_withrelax_>::bdsolve\n+static void bdsolve(const M &A, X &v, const Y &d, const K &w)\n+Definition: gsetc.hh:316\n+Dune::algmeta_bdsolve<_0,_norelax_>::bdsolve\n+static void bdsolve(const M &A, X &v, const Y &d, const K &)\n+Definition: gsetc.hh:325\n+Dune::algmeta_itsteps\n+Definition: gsetc.hh:375\n+Dune::algmeta_itsteps::bsorb\n+static void bsorb(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:461\n+Dune::algmeta_itsteps::bsorf\n+static void bsorf(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:418\n+Dune::algmeta_itsteps::dbjac\n+static void dbjac(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:504\n+Dune::algmeta_itsteps::dbgs\n+static void dbgs(const M &A, X &x, const Y &b, const K &w)\n+Definition: gsetc.hh:378\n+Dune::algmeta_itsteps<_0,_M_>::dbgs\n+static void dbgs(const M &A, X &x, const Y &b, const K &)\n+Definition: gsetc.hh:545\n+Dune::algmeta_itsteps<_0,_M_>::dbjac\n+static void dbjac(const M &A, X &x, const Y &b, const K &)\n+Definition: gsetc.hh:560\n+Dune::algmeta_itsteps<_0,_M_>::bsorf\n+static void bsorf(const M &A, X &x, const Y &b, const K &)\n+Definition: gsetc.hh:550\n+Dune::algmeta_itsteps<_0,_M_>::bsorb\n+static void bsorb(const M &A, X &x, const Y &b, const K &)\n+Definition: gsetc.hh:555\n+Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n+>::dbgs\n+static void dbgs(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n+MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n+MultiTypeVectorArgs... > &b, const K &w)\n+Definition: gsetc.hh:571\n+Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n+>::dbjac\n+static void dbjac(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n+MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n+MultiTypeVectorArgs... > &b, const K &w)\n+Definition: gsetc.hh:608\n+Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n+>::bsorf\n+static void bsorf(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n+MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n+MultiTypeVectorArgs... > &b, const K &w)\n+Definition: gsetc.hh:583\n+Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n+>::bsorb\n+static void bsorb(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n+MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n+MultiTypeVectorArgs... > &b, const K &w)\n+Definition: gsetc.hh:595\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00212.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00212.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: novlpschwarz.hh File Reference\n+dune-istl: blocklevel.hh File Reference\n \n \n \n \n \n \n \n@@ -63,56 +63,56 @@\n
    \n \n
    \n
    \n
    \n \n-
    novlpschwarz.hh File Reference
    \n+Namespaces |\n+Functions
    \n+
    blocklevel.hh File Reference
    \n \n
    \n-
    #include <iostream>
    \n-#include <fstream>
    \n-#include <vector>
    \n-#include <sstream>
    \n-#include <cmath>
    \n-#include <dune/common/timer.hh>
    \n+\n+

    Helper functions for determining the vector/matrix block level. \n+More...

    \n+
    #include <algorithm>
    \n+#include <type_traits>
    \n+#include <dune/common/indices.hh>
    \n+#include <dune/common/typetraits.hh>
    \n #include <dune/common/hybridutilities.hh>
    \n-#include "io.hh"
    \n-#include "bvector.hh"
    \n-#include "vbvector.hh"
    \n-#include "bcrsmatrix.hh"
    \n-#include "gsetc.hh"
    \n-#include "ilu.hh"
    \n-#include "operators.hh"
    \n-#include "solvers.hh"
    \n-#include "preconditioners.hh"
    \n-#include "scalarproducts.hh"
    \n-#include "owneroverlapcopy.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n-\n-\n-

    \n-Classes

    class  Dune::NonoverlappingSchwarzOperator< M, X, Y, C >
     A nonoverlapping operator with communication object. More...
     
    class  Dune::NonoverlappingBlockPreconditioner< C, P >
     Nonoverlapping parallel preconditioner. More...
     
    \n \n \n \n-\n-\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<typename T >
    constexpr std::size_t Dune::maxBlockLevel ()
     Determine the maximum block level of a possibly nested vector/matrix type. More...
     
    template<typename T >
    constexpr std::size_t Dune::minBlockLevel ()
     Determine the minimum block level of a possibly nested vector/matrix type. More...
     
    template<typename T >
    constexpr bool Dune::hasUniqueBlockLevel ()
     Determine if a vector/matrix has a uniquely determinable block level. More...
     
    template<typename T >
    constexpr std::size_t Dune::blockLevel ()
     Determine the block level of a possibly nested vector/matrix type. More...
     
    \n-
    \n+

    Detailed Description

    \n+

    Helper functions for determining the vector/matrix block level.

    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,43 +4,45 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-novlpschwarz.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+Namespaces | Functions\n+blocklevel.hh File Reference\n+Helper functions for determining the vector/matrix block level. More...\n+#include \n+#include \n+#include \n+#include \n #include \n-#include \"io.hh\"\n-#include \"bvector.hh\"\n-#include \"vbvector.hh\"\n-#include \"bcrsmatrix.hh\"\n-#include \"gsetc.hh\"\n-#include \"ilu.hh\"\n-#include \"operators.hh\"\n-#include \"solvers.hh\"\n-#include \"preconditioners.hh\"\n-#include \"scalarproducts.hh\"\n-#include \"owneroverlapcopy.hh\"\n Go_to_the_source_code_of_this_file.\n- Classes\n-class \u00a0Dune::NonoverlappingSchwarzOperator<_M,_X,_Y,_C_>\n-\u00a0 A nonoverlapping operator with communication object. More...\n-\u00a0\n-class \u00a0Dune::NonoverlappingBlockPreconditioner<_C,_P_>\n-\u00a0 Nonoverlapping parallel preconditioner. More...\n-\u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n-namespace \u00a0Dune::Amg\n+ Functions\n+template\n+constexpr std::size_t\u00a0Dune::maxBlockLevel ()\n+\u00a0 Determine the maximum block level of a possibly nested\n+ vector/matrix type. More...\n+\u00a0\n+template\n+constexpr std::size_t\u00a0Dune::minBlockLevel ()\n+\u00a0 Determine the minimum block level of a possibly nested\n+ vector/matrix type. More...\n+\u00a0\n+template\n+ constexpr bool\u00a0Dune::hasUniqueBlockLevel ()\n+\u00a0 Determine if a vector/matrix has a uniquely determinable\n+ block level. More...\n+\u00a0\n+template\n+constexpr std::size_t\u00a0Dune::blockLevel ()\n+\u00a0 Determine the block level of a possibly nested vector/\n+ matrix type. More...\n \u00a0\n+***** Detailed Description *****\n+Helper functions for determining the vector/matrix block level.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00212_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00212_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: novlpschwarz.hh Source File\n+dune-istl: blocklevel.hh Source File\n \n \n \n \n \n \n \n@@ -62,346 +62,195 @@\n \n
    \n \n
    \n \n
    \n-
    novlpschwarz.hh
    \n+
    blocklevel.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_NOVLPSCHWARZ_HH
    \n-
    6#define DUNE_ISTL_NOVLPSCHWARZ_HH
    \n-
    7
    \n-
    8#include <iostream> // for input/output to shell
    \n-
    9#include <fstream> // for input/output to files
    \n-
    10#include <vector> // STL vector class
    \n-
    11#include <sstream>
    \n-
    12
    \n-
    13#include <cmath> // Yes, we do some math here
    \n-
    14
    \n-
    15#include <dune/common/timer.hh>
    \n-
    16
    \n-
    17#include <dune/common/hybridutilities.hh>
    \n-
    18
    \n-
    19#include "io.hh"
    \n-
    20#include "bvector.hh"
    \n-
    21#include "vbvector.hh"
    \n-
    22#include "bcrsmatrix.hh"
    \n-
    23#include "io.hh"
    \n-
    24#include "gsetc.hh"
    \n-
    25#include "ilu.hh"
    \n-
    26#include "operators.hh"
    \n-
    27#include "solvers.hh"
    \n-
    28#include "preconditioners.hh"
    \n-
    29#include "scalarproducts.hh"
    \n-
    30#include "owneroverlapcopy.hh"
    \n-
    31
    \n-
    32namespace Dune {
    \n-
    33
    \n-
    59 template<class M, class X, class Y, class C>
    \n-\n-
    61 {
    \n-
    62 public:
    \n-
    64 typedef M matrix_type;
    \n-
    66 typedef X domain_type;
    \n-
    68 typedef Y range_type;
    \n-
    70 typedef typename X::field_type field_type;
    \n-\n-
    73
    \n-
    74 typedef typename C::PIS PIS;
    \n-
    75 typedef typename C::RI RI;
    \n-
    76 typedef typename RI::RemoteIndexList RIL;
    \n-
    77 typedef typename RI::const_iterator RIIterator;
    \n-
    78 typedef typename RIL::const_iterator RILIterator;
    \n-
    79 typedef typename M::ConstColIterator ColIterator;
    \n-
    80 typedef typename M::ConstRowIterator RowIterator;
    \n-
    81 typedef std::multimap<int,int> MM;
    \n-
    82 typedef std::multimap<int,std::pair<int,RILIterator> > RIMap;
    \n-
    83 typedef typename RIMap::iterator RIMapit;
    \n-
    84
    \n-\n-
    93 : _A_(stackobject_to_shared_ptr(A)), communication(com), buildcomm(true)
    \n-
    94 {}
    \n-
    95
    \n-
    96 NonoverlappingSchwarzOperator (std::shared_ptr<const matrix_type> A, const communication_type& com)
    \n-
    97 : _A_(A), communication(com), buildcomm(true)
    \n-
    98 {}
    \n-
    99
    \n-
    101 virtual void apply (const X& x, Y& y) const
    \n-
    102 {
    \n-
    103 y = 0;
    \n-
    104 novlp_op_apply(x,y,1);
    \n-
    105 communication.addOwnerCopyToOwnerCopy(y,y);
    \n-
    106 }
    \n-
    107
    \n-
    109 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
    \n-
    110 {
    \n-
    111 // only apply communication to alpha*A*x to make it consistent,
    \n-
    112 // y already has to be consistent.
    \n-
    113 Y y1(y);
    \n-
    114 y = 0;
    \n-
    115 novlp_op_apply(x,y,alpha);
    \n-
    116 communication.addOwnerCopyToOwnerCopy(y,y);
    \n-
    117 y += y1;
    \n-
    118 }
    \n-
    119
    \n-
    121 virtual const matrix_type& getmat () const
    \n-
    122 {
    \n-
    123 return *_A_;
    \n-
    124 }
    \n-
    125
    \n-
    126 void novlp_op_apply (const X& x, Y& y, field_type alpha) const
    \n-
    127 {
    \n-
    128 //get index sets
    \n-
    129 const PIS& pis=communication.indexSet();
    \n-
    130 const RI& ri = communication.remoteIndices();
    \n-
    131
    \n-
    132 // at the beginning make a multimap "bordercontribution".
    \n-
    133 // process has i and j as border dofs but is not the owner
    \n-
    134 // => only contribute to Ax if i,j is in bordercontribution
    \n-
    135 if (buildcomm == true) {
    \n-
    136
    \n-
    137 // set up mask vector
    \n-
    138 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size())) {
    \n-
    139 mask.resize(x.size());
    \n-
    140 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n-
    141 mask[i] = 1;
    \n-
    142 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n-
    143 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
    \n-
    144 mask[i->local().local()] = 0;
    \n-
    145 else if (i->local().attribute()==OwnerOverlapCopyAttributeSet::overlap)
    \n-
    146 mask[i->local().local()] = 2;
    \n-
    147 }
    \n-
    148
    \n-
    149 for (MM::iterator iter = bordercontribution.begin();
    \n-
    150 iter != bordercontribution.end(); ++iter)
    \n-
    151 bordercontribution.erase(iter);
    \n-
    152 std::map<int,int> owner; //key: local index i, value: process, that owns i
    \n-
    153 RIMap rimap;
    \n+
    5
    \n+
    6#ifndef DUNE_ISTL_BLOCKLEVEL_HH
    \n+
    7#define DUNE_ISTL_BLOCKLEVEL_HH
    \n+
    8
    \n+
    9#include <algorithm>
    \n+
    10#include <type_traits>
    \n+
    11
    \n+
    12#include <dune/common/indices.hh>
    \n+
    13#include <dune/common/typetraits.hh>
    \n+
    14#include <dune/common/hybridutilities.hh>
    \n+
    15
    \n+
    21// forward declaration
    \n+
    22namespace Dune {
    \n+
    23template<typename... Args>
    \n+
    24class MultiTypeBlockVector;
    \n+
    25template<typename FirstRow, typename... Args>
    \n+
    26class MultiTypeBlockMatrix;
    \n+
    27} // end namespace Dune
    \n+
    28
    \n+
    29namespace Dune { namespace Impl {
    \n+
    30
    \n+
    31// forward declaration
    \n+
    32template<typename T> struct MaxBlockLevel;
    \n+
    33template<typename T> struct MinBlockLevel;
    \n+
    34
    \n+
    36template<typename M, template<typename B> typename BlockLevel, typename Op>
    \n+
    37constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)
    \n+
    38{
    \n+
    39 // inialize with zeroth diagonal block
    \n+
    40 using namespace Dune::Indices;
    \n+
    41 using Block00 = typename std::decay_t<decltype(std::declval<M>()[_0][_0])>;
    \n+
    42 std::size_t blockLevel = BlockLevel<Block00>::value() + 1;
    \n+
    43 // iterate over all blocks to determine min/max block level
    \n+
    44 using namespace Dune::Hybrid;
    \n+
    45 forEach(integralRange(index_constant<M::N()>()), [&](auto&& i) {
    \n+
    46 using namespace Dune::Hybrid; // needed for icc, see issue #31
    \n+
    47 forEach(integralRange(index_constant<M::M()>()), [&](auto&& j) {
    \n+
    48 using Block = typename std::decay_t<decltype(std::declval<M>()[i][j])>;
    \n+
    49 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
    \n+
    50 });
    \n+
    51 });
    \n+
    52 return blockLevel;
    \n+
    53}
    \n+
    54
    \n+
    56template<typename V, template<typename B> typename BlockLevel, typename Op>
    \n+
    57constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)
    \n+
    58{
    \n+
    59 // inialize with zeroth block
    \n+
    60 using namespace Dune::Indices;
    \n+
    61 using Block0 = typename std::decay_t<decltype(std::declval<V>()[_0])>;
    \n+
    62 std::size_t blockLevel = BlockLevel<Block0>::value() + 1;
    \n+
    63 // iterate over all blocks to determine min/max block level
    \n+
    64 using namespace Dune::Hybrid;
    \n+
    65 forEach(integralRange(index_constant<V::size()>()), [&](auto&& i) {
    \n+
    66 using Block = typename std::decay_t<decltype(std::declval<V>()[i])>;
    \n+
    67 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
    \n+
    68 });
    \n+
    69 return blockLevel;
    \n+
    70}
    \n+
    71
    \n+
    72template<typename T>
    \n+
    73struct MaxBlockLevel
    \n+
    74{
    \n+
    75 static constexpr std::size_t value(){
    \n+
    76 if constexpr (IsNumber<T>::value)
    \n+
    77 return 0;
    \n+
    78 else
    \n+
    79 return MaxBlockLevel<typename T::block_type>::value() + 1;
    \n+
    80 }
    \n+
    81};
    \n+
    82
    \n+
    83template<typename T>
    \n+
    84struct MinBlockLevel
    \n+
    85{
    \n+
    86 // the default implementation assumes minBlockLevel == maxBlockLevel
    \n+
    87 static constexpr std::size_t value()
    \n+
    88 { return MaxBlockLevel<T>::value(); }
    \n+
    89};
    \n+
    90
    \n+
    91// max block level for MultiTypeBlockMatrix
    \n+
    92template<typename FirstRow, typename... Args>
    \n+
    93struct MaxBlockLevel<Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
    \n+
    94{
    \n+
    95 static constexpr std::size_t value()
    \n+
    96 {
    \n+
    97 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
    \n+
    98 constexpr auto max = [](const auto& a, const auto& b){ return std::max(a,b); };
    \n+
    99 return blockLevelMultiTypeBlockMatrix<M, MaxBlockLevel>(max);
    \n+
    100 }
    \n+
    101};
    \n+
    102
    \n+
    103// min block level for MultiTypeBlockMatrix
    \n+
    104template<typename FirstRow, typename... Args>
    \n+
    105struct MinBlockLevel<Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
    \n+
    106{
    \n+
    107 static constexpr std::size_t value()
    \n+
    108 {
    \n+
    109 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
    \n+
    110 constexpr auto min = [](const auto& a, const auto& b){ return std::min(a,b); };
    \n+
    111 return blockLevelMultiTypeBlockMatrix<M, MinBlockLevel>(min);
    \n+
    112 }
    \n+
    113};
    \n+
    114
    \n+
    115// max block level for MultiTypeBlockVector
    \n+
    116template<typename... Args>
    \n+
    117struct MaxBlockLevel<Dune::MultiTypeBlockVector<Args...>>
    \n+
    118{
    \n+
    119 static constexpr std::size_t value()
    \n+
    120 {
    \n+
    121 using V = MultiTypeBlockVector<Args...>;
    \n+
    122 constexpr auto max = [](const auto& a, const auto& b){ return std::max(a,b); };
    \n+
    123 return blockLevelMultiTypeBlockVector<V, MaxBlockLevel>(max);
    \n+
    124 }
    \n+
    125};
    \n+
    126
    \n+
    127// min block level for MultiTypeBlockVector
    \n+
    128template<typename... Args>
    \n+
    129struct MinBlockLevel<Dune::MultiTypeBlockVector<Args...>>
    \n+
    130{
    \n+
    131 static constexpr std::size_t value()
    \n+
    132 {
    \n+
    133 using V = MultiTypeBlockVector<Args...>;
    \n+
    134 constexpr auto min = [](const auto& a, const auto& b){ return std::min(a,b); };
    \n+
    135 return blockLevelMultiTypeBlockVector<V, MinBlockLevel>(min);
    \n+
    136 }
    \n+
    137};
    \n+
    138
    \n+
    139// special case: empty MultiTypeBlockVector
    \n+
    140template<>
    \n+
    141struct MaxBlockLevel<Dune::MultiTypeBlockVector<>>
    \n+
    142{
    \n+
    143 static constexpr std::size_t value()
    \n+
    144 { return 0; };
    \n+
    145};
    \n+
    146
    \n+
    147// special case: empty MultiTypeBlockVector
    \n+
    148template<>
    \n+
    149struct MinBlockLevel<Dune::MultiTypeBlockVector<>>
    \n+
    150{
    \n+
    151 static constexpr std::size_t value()
    \n+
    152 { return 0; };
    \n+
    153};
    \n
    154
    \n-
    155 // for each local index make multimap rimap:
    \n-
    156 // key: local index i, data: pair of process that knows i and pointer to RI entry
    \n-
    157 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i)
    \n-
    158 if (mask[i.index()] == 0)
    \n-
    159 for (RIIterator remote = ri.begin(); remote != ri.end(); ++remote) {
    \n-
    160 RIL& ril = *(remote->second.first);
    \n-
    161 for (RILIterator rindex = ril.begin(); rindex != ril.end(); ++rindex)
    \n-
    162 if (rindex->attribute() != OwnerOverlapCopyAttributeSet::overlap)
    \n-
    163 if (rindex->localIndexPair().local().local() == i.index()) {
    \n-
    164 rimap.insert
    \n-
    165 (std::make_pair(i.index(),
    \n-
    166 std::pair<int,RILIterator>(remote->first, rindex)));
    \n-
    167 if(rindex->attribute()==OwnerOverlapCopyAttributeSet::owner)
    \n-
    168 owner.insert(std::make_pair(i.index(),remote->first));
    \n-
    169 }
    \n-
    170 }
    \n-
    171
    \n-
    172 int iowner = 0;
    \n-
    173 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {
    \n-
    174 if (mask[i.index()] == 0) {
    \n-
    175 std::map<int,int>::iterator it = owner.find(i.index());
    \n-
    176 iowner = it->second;
    \n-
    177 std::pair<RIMapit, RIMapit> foundiit = rimap.equal_range(i.index());
    \n-
    178 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j) {
    \n-
    179 if (mask[j.index()] == 0) {
    \n-
    180 bool flag = true;
    \n-
    181 for (RIMapit foundi = foundiit.first; foundi != foundiit.second; ++foundi) {
    \n-
    182 std::pair<RIMapit, RIMapit> foundjit = rimap.equal_range(j.index());
    \n-
    183 for (RIMapit foundj = foundjit.first; foundj != foundjit.second; ++foundj)
    \n-
    184 if (foundj->second.first == foundi->second.first)
    \n-
    185 if (foundj->second.second->attribute() == OwnerOverlapCopyAttributeSet::owner
    \n-
    186 || foundj->second.first == iowner
    \n-
    187 || foundj->second.first < communication.communicator().rank()) {
    \n-
    188 flag = false;
    \n-
    189 continue;
    \n-
    190 }
    \n-
    191 if (flag == false)
    \n-
    192 continue;
    \n-
    193 }
    \n-
    194 // don\u00b4t contribute to Ax if
    \n-
    195 // 1. the owner of j has i as interior/border dof
    \n-
    196 // 2. iowner has j as interior/border dof
    \n-
    197 // 3. there is another process with smaller rank that has i and j
    \n-
    198 // as interor/border dofs
    \n-
    199 // if the owner of j does not have i as interior/border dof,
    \n-
    200 // it will not be taken into account
    \n-
    201 if (flag==true)
    \n-
    202 bordercontribution.insert(std::pair<int,int>(i.index(),j.index()));
    \n-
    203 }
    \n-
    204 }
    \n-
    205 }
    \n-
    206 }
    \n-
    207 buildcomm = false;
    \n-
    208 }
    \n-
    209
    \n-
    210 //compute alpha*A*x nonoverlapping case
    \n-
    211 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {
    \n-
    212 if (mask[i.index()] == 0) {
    \n-
    213 //dof doesn't belong to process but is border (not ghost)
    \n-
    214 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j) {
    \n-
    215 if (mask[j.index()] == 1) //j is owner => then sum entries
    \n-
    216 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n-
    217 else if (mask[j.index()] == 0) {
    \n-
    218 std::pair<MM::iterator, MM::iterator> itp =
    \n-
    219 bordercontribution.equal_range(i.index());
    \n-
    220 for (MM::iterator it = itp.first; it != itp.second; ++it)
    \n-
    221 if ((*it).second == (int)j.index())
    \n-
    222 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n-
    223 }
    \n-
    224 }
    \n-
    225 }
    \n-
    226 else if (mask[i.index()] == 1) {
    \n-
    227 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end(); ++j)
    \n-
    228 if (mask[j.index()] != 2)
    \n-
    229 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);
    \n-
    230 }
    \n-
    231 }
    \n-
    232 }
    \n-
    233
    \n-\n-
    236 {
    \n-\n-
    238 }
    \n-
    239
    \n-\n-
    242 {
    \n-
    243 return communication;
    \n-
    244 }
    \n-
    245 private:
    \n-
    246 std::shared_ptr<const matrix_type> _A_;
    \n-
    247 const communication_type& communication;
    \n-
    248 mutable bool buildcomm;
    \n-
    249 mutable std::vector<double> mask;
    \n-
    250 mutable std::multimap<int,int> bordercontribution;
    \n-
    251 };
    \n-
    252
    \n-
    255 namespace Amg
    \n-
    256 {
    \n-
    257 template<class T> struct ConstructionTraits;
    \n-
    258 }
    \n-
    259
    \n-
    274 template<class C, class P>
    \n-\n-
    276 : public Preconditioner<typename P::domain_type,typename P::range_type> {
    \n-\n-
    278 using X = typename P::domain_type;
    \n-
    279 using Y = typename P::range_type;
    \n-
    280 public:
    \n-
    282 typedef typename P::domain_type domain_type;
    \n-
    284 typedef typename P::range_type range_type;
    \n-\n-
    287
    \n-\n-
    303 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)
    \n-
    304 { }
    \n-
    305
    \n-
    313 NonoverlappingBlockPreconditioner (const std::shared_ptr<P>& p, const communication_type& c)
    \n-
    314 : _preconditioner(p), _communication(c)
    \n-
    315 { }
    \n-
    316
    \n-
    322 virtual void pre (domain_type& x, range_type& b)
    \n-
    323 {
    \n-
    324 _preconditioner->pre(x,b);
    \n-
    325 }
    \n-
    326
    \n-
    332 virtual void apply (domain_type& v, const range_type& d)
    \n-
    333 {
    \n-
    334 // block preconditioner equivalent to WrappedPreconditioner from
    \n-
    335 // pdelab/backend/ovlpistsolverbackend.hh,
    \n-
    336 // but not to BlockPreconditioner from schwarz.hh
    \n-
    337 _preconditioner->apply(v,d);
    \n-
    338 _communication.addOwnerCopyToOwnerCopy(v,v);
    \n-
    339 }
    \n-
    340
    \n-
    341 template<bool forward>
    \n-
    342 void apply (X& v, const Y& d)
    \n-
    343 {
    \n-
    344 _preconditioner->template apply<forward>(v,d);
    \n-
    345 _communication.addOwnerCopyToOwnerCopy(v,v);
    \n-
    346 }
    \n-
    347
    \n-
    353 virtual void post (domain_type& x)
    \n-
    354 {
    \n-
    355 _preconditioner->post(x);
    \n-
    356 }
    \n-
    357
    \n-\n-
    360 {
    \n-\n-
    362 }
    \n-
    363
    \n-
    364 private:
    \n-
    366 std::shared_ptr<P> _preconditioner;
    \n-
    367
    \n-
    369 const communication_type& _communication;
    \n-
    370 };
    \n-
    371
    \n-
    374} // end namespace
    \n-
    375
    \n-
    376#endif
    \n-
    Define general, extensible interface for operators. The available implementation wraps a matrix.
    \n-
    Implementations of the inverse operator interface.
    \n-
    Define general preconditioner interface.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-
    Define base class for scalar product and norm.
    \n-
    The incomplete LU factorization kernels.
    \n-
    Implementation of the BCRSMatrix class.
    \n-
    Classes providing communication interfaces for overlapping Schwarz methods.
    \n-\n-
    Some generic functions for pretty printing vectors and matrices.
    \n-
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    155}} // end namespace Dune::Impl
    \n+
    156
    \n+
    157namespace Dune {
    \n+
    158
    \n+
    160template<typename T>
    \n+
    161constexpr std::size_t maxBlockLevel()
    \n+
    162{ return Impl::MaxBlockLevel<T>::value(); }
    \n+
    163
    \n+
    165template<typename T>
    \n+
    166constexpr std::size_t minBlockLevel()
    \n+
    167{ return Impl::MinBlockLevel<T>::value(); }
    \n+
    168
    \n+
    170template<typename T>
    \n+
    171constexpr bool hasUniqueBlockLevel()
    \n+
    172{ return maxBlockLevel<T>() == minBlockLevel<T>(); }
    \n+
    173
    \n+
    175template<typename T>
    \n+
    176constexpr std::size_t blockLevel()
    \n+
    177{
    \n+
    178 static_assert(hasUniqueBlockLevel<T>(), "Block level cannot be uniquely determined!");
    \n+
    179 return Impl::MaxBlockLevel<T>::value();
    \n+
    180}
    \n+
    181
    \n+
    182} // end namespace Dune
    \n+
    183
    \n+
    184#endif
    \n
    Definition: allocator.hh:11
    \n-
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n-
    C::PIS PIS
    Definition: novlpschwarz.hh:74
    \n-
    C communication_type
    The type of the communication object.
    Definition: novlpschwarz.hh:72
    \n-
    std::multimap< int, std::pair< int, RILIterator > > RIMap
    Definition: novlpschwarz.hh:82
    \n-
    C::RI RI
    Definition: novlpschwarz.hh:75
    \n-
    void novlp_op_apply(const X &x, Y &y, field_type alpha) const
    Definition: novlpschwarz.hh:126
    \n-
    NonoverlappingSchwarzOperator(std::shared_ptr< const matrix_type > A, const communication_type &com)
    Definition: novlpschwarz.hh:96
    \n-
    M::ConstColIterator ColIterator
    Definition: novlpschwarz.hh:79
    \n-
    virtual void apply(const X &x, Y &y) const
    apply operator to x:
    Definition: novlpschwarz.hh:101
    \n-
    X domain_type
    The type of the domain.
    Definition: novlpschwarz.hh:66
    \n-
    virtual SolverCategory::Category category() const
    Category of the linear operator (see SolverCategory::Category)
    Definition: novlpschwarz.hh:235
    \n-
    RIMap::iterator RIMapit
    Definition: novlpschwarz.hh:83
    \n-
    virtual const matrix_type & getmat() const
    get matrix via *
    Definition: novlpschwarz.hh:121
    \n-
    RIL::const_iterator RILIterator
    Definition: novlpschwarz.hh:78
    \n-
    std::multimap< int, int > MM
    Definition: novlpschwarz.hh:81
    \n-
    Y range_type
    The type of the range.
    Definition: novlpschwarz.hh:68
    \n-
    M matrix_type
    The type of the matrix we operate on.
    Definition: novlpschwarz.hh:64
    \n-
    M::ConstRowIterator RowIterator
    Definition: novlpschwarz.hh:80
    \n-
    const communication_type & getCommunication() const
    Get the object responsible for communication.
    Definition: novlpschwarz.hh:241
    \n-
    virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const
    apply operator to x, scale and add:
    Definition: novlpschwarz.hh:109
    \n-
    RI::RemoteIndexList RIL
    Definition: novlpschwarz.hh:76
    \n-
    X::field_type field_type
    The field type of the range.
    Definition: novlpschwarz.hh:70
    \n-
    NonoverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)
    constructor: just store a reference to a matrix.
    Definition: novlpschwarz.hh:92
    \n-
    RI::const_iterator RIIterator
    Definition: novlpschwarz.hh:77
    \n-
    Traits class for generically constructing non default constructable types.
    Definition: construction.hh:39
    \n-
    Nonoverlapping parallel preconditioner.
    Definition: novlpschwarz.hh:276
    \n-
    NonoverlappingBlockPreconditioner(P &p, const communication_type &c)
    Constructor.
    Definition: novlpschwarz.hh:302
    \n-
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: novlpschwarz.hh:359
    \n-
    virtual void apply(domain_type &v, const range_type &d)
    Apply the preconditioner.
    Definition: novlpschwarz.hh:332
    \n-
    P::range_type range_type
    The range type of the preconditioner.
    Definition: novlpschwarz.hh:284
    \n-
    NonoverlappingBlockPreconditioner(const std::shared_ptr< P > &p, const communication_type &c)
    Constructor.
    Definition: novlpschwarz.hh:313
    \n-
    virtual void post(domain_type &x)
    Clean up.
    Definition: novlpschwarz.hh:353
    \n-
    C communication_type
    The type of the communication object.
    Definition: novlpschwarz.hh:286
    \n-
    virtual void pre(domain_type &x, range_type &b)
    Prepare the preconditioner.
    Definition: novlpschwarz.hh:322
    \n-
    void apply(X &v, const Y &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: novlpschwarz.hh:342
    \n-
    P::domain_type domain_type
    The domain type of the preconditioner.
    Definition: novlpschwarz.hh:282
    \n-
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n-
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n-
    @ copy
    Definition: owneroverlapcopy.hh:61
    \n-
    @ overlap
    Definition: owneroverlapcopy.hh:61
    \n-
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n+
    constexpr bool hasUniqueBlockLevel()
    Determine if a vector/matrix has a uniquely determinable block level.
    Definition: blocklevel.hh:171
    \n+
    constexpr std::size_t maxBlockLevel()
    Determine the maximum block level of a possibly nested vector/matrix type.
    Definition: blocklevel.hh:161
    \n+
    constexpr std::size_t blockLevel()
    Determine the block level of a possibly nested vector/matrix type.
    Definition: blocklevel.hh:176
    \n+
    constexpr std::size_t minBlockLevel()
    Determine the minimum block level of a possibly nested vector/matrix type.
    Definition: blocklevel.hh:166
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "encoding", "source2": "encoding", "unified_diff": "@@ -1 +1 @@\n-utf-8\n+us-ascii\n"}, {"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,479 +4,209 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-novlpschwarz.hh\n+blocklevel.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_NOVLPSCHWARZ_HH\n- 6#define DUNE_ISTL_NOVLPSCHWARZ_HH\n- 7\n- 8#include // for input/output to shell\n- 9#include // for input/output to files\n- 10#include // STL vector class\n- 11#include \n- 12\n- 13#include // Yes, we do some math here\n- 14\n- 15#include \n- 16\n- 17#include \n- 18\n- 19#include \"io.hh\"\n- 20#include \"bvector.hh\"\n- 21#include \"vbvector.hh\"\n- 22#include \"bcrsmatrix.hh\"\n- 23#include \"io.hh\"\n- 24#include \"gsetc.hh\"\n- 25#include \"ilu.hh\"\n- 26#include \"operators.hh\"\n- 27#include \"solvers.hh\"\n- 28#include \"preconditioners.hh\"\n- 29#include \"scalarproducts.hh\"\n- 30#include \"owneroverlapcopy.hh\"\n- 31\n- 32namespace Dune {\n- 33\n- 59 template\n-60 class NonoverlappingSchwarzOperator : public AssembledLinearOperator\n- 61 {\n- 62 public:\n-64 typedef M matrix_type;\n-66 typedef X domain_type;\n-68 typedef Y range_type;\n-70 typedef typename X::field_type field_type;\n-72 typedef C communication_type;\n- 73\n-74 typedef typename C::PIS PIS;\n-75 typedef typename C::RI RI;\n-76 typedef typename RI::RemoteIndexList RIL;\n-77 typedef typename RI::const_iterator RIIterator;\n-78 typedef typename RIL::const_iterator RILIterator;\n-79 typedef typename M::ConstColIterator ColIterator;\n-80 typedef typename M::ConstRowIterator RowIterator;\n-81 typedef std::multimap MM;\n-82 typedef std::multimap > RIMap;\n-83 typedef typename RIMap::iterator RIMapit;\n- 84\n-92 NonoverlappingSchwarzOperator (const matrix_type& A, const\n-communication_type& com)\n- 93 : _A_(stackobject_to_shared_ptr(A)), communication(com), buildcomm(true)\n- 94 {}\n- 95\n-96 NonoverlappingSchwarzOperator (std::shared_ptr A, const\n-communication_type& com)\n- 97 : _A_(A), communication(com), buildcomm(true)\n- 98 {}\n- 99\n-101 virtual void apply (const X& x, Y& y) const\n- 102 {\n- 103 y = 0;\n- 104 novlp_op_apply(x,y,1);\n- 105 communication.addOwnerCopyToOwnerCopy(y,y);\n- 106 }\n- 107\n-109 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const\n- 110 {\n- 111 // only apply communication to alpha*A*x to make it consistent,\n- 112 // y already has to be consistent.\n- 113 Y y1(y);\n- 114 y = 0;\n- 115 novlp_op_apply(x,y,alpha);\n- 116 communication.addOwnerCopyToOwnerCopy(y,y);\n- 117 y += y1;\n- 118 }\n- 119\n-121 virtual const matrix_type& getmat () const\n- 122 {\n- 123 return *_A_;\n+ 5\n+ 6#ifndef DUNE_ISTL_BLOCKLEVEL_HH\n+ 7#define DUNE_ISTL_BLOCKLEVEL_HH\n+ 8\n+ 9#include \n+ 10#include \n+ 11\n+ 12#include \n+ 13#include \n+ 14#include \n+ 15\n+ 21// forward declaration\n+ 22namespace Dune {\n+ 23template\n+ 24class MultiTypeBlockVector;\n+ 25template\n+ 26class MultiTypeBlockMatrix;\n+ 27} // end namespace Dune\n+ 28\n+ 29namespace Dune { namespace Impl {\n+ 30\n+ 31// forward declaration\n+ 32template struct MaxBlockLevel;\n+ 33template struct MinBlockLevel;\n+ 34\n+ 36template typename BlockLevel, typename Op>\n+ 37constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)\n+ 38{\n+ 39 // inialize with zeroth diagonal block\n+ 40 using namespace Dune::Indices;\n+ 41 using Block00 = typename std::decay_t()[_0][_0])>;\n+ 42 std::size_t blockLevel = BlockLevel::value() + 1;\n+ 43 // iterate over all blocks to determine min/max block level\n+ 44 using namespace Dune::Hybrid;\n+ 45 forEach(integralRange(index_constant()), [&](auto&& i) {\n+ 46 using namespace Dune::Hybrid; // needed for icc, see issue #31\n+ 47 forEach(integralRange(index_constant()), [&](auto&& j) {\n+ 48 using Block = typename std::decay_t()[i][j])>;\n+ 49 blockLevel = op(blockLevel, BlockLevel::value() + 1);\n+ 50 });\n+ 51 });\n+ 52 return blockLevel;\n+ 53}\n+ 54\n+ 56template typename BlockLevel, typename Op>\n+ 57constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)\n+ 58{\n+ 59 // inialize with zeroth block\n+ 60 using namespace Dune::Indices;\n+ 61 using Block0 = typename std::decay_t()[_0])>;\n+ 62 std::size_t blockLevel = BlockLevel::value() + 1;\n+ 63 // iterate over all blocks to determine min/max block level\n+ 64 using namespace Dune::Hybrid;\n+ 65 forEach(integralRange(index_constant()), [&](auto&& i) {\n+ 66 using Block = typename std::decay_t()[i])>;\n+ 67 blockLevel = op(blockLevel, BlockLevel::value() + 1);\n+ 68 });\n+ 69 return blockLevel;\n+ 70}\n+ 71\n+ 72template\n+ 73struct MaxBlockLevel\n+ 74{\n+ 75 static constexpr std::size_t value(){\n+ 76 if constexpr (IsNumber::value)\n+ 77 return 0;\n+ 78 else\n+ 79 return MaxBlockLevel::value() + 1;\n+ 80 }\n+ 81};\n+ 82\n+ 83template\n+ 84struct MinBlockLevel\n+ 85{\n+ 86 // the default implementation assumes minBlockLevel == maxBlockLevel\n+ 87 static constexpr std::size_t value()\n+ 88 { return MaxBlockLevel::value(); }\n+ 89};\n+ 90\n+ 91// max block level for MultiTypeBlockMatrix\n+ 92template\n+ 93struct MaxBlockLevel>\n+ 94{\n+ 95 static constexpr std::size_t value()\n+ 96 {\n+ 97 using M = MultiTypeBlockMatrix;\n+ 98 constexpr auto max = [](const auto& a, const auto& b){ return std::max\n+(a,b); };\n+ 99 return blockLevelMultiTypeBlockMatrix(max);\n+ 100 }\n+ 101};\n+ 102\n+ 103// min block level for MultiTypeBlockMatrix\n+ 104template\n+ 105struct MinBlockLevel>\n+ 106{\n+ 107 static constexpr std::size_t value()\n+ 108 {\n+ 109 using M = MultiTypeBlockMatrix;\n+ 110 constexpr auto min = [](const auto& a, const auto& b){ return std::min\n+(a,b); };\n+ 111 return blockLevelMultiTypeBlockMatrix(min);\n+ 112 }\n+ 113};\n+ 114\n+ 115// max block level for MultiTypeBlockVector\n+ 116template\n+ 117struct MaxBlockLevel>\n+ 118{\n+ 119 static constexpr std::size_t value()\n+ 120 {\n+ 121 using V = MultiTypeBlockVector;\n+ 122 constexpr auto max = [](const auto& a, const auto& b){ return std::max\n+(a,b); };\n+ 123 return blockLevelMultiTypeBlockVector(max);\n 124 }\n- 125\n-126 void novlp_op_apply (const X& x, Y& y, field_type alpha) const\n- 127 {\n- 128 //get index sets\n- 129 const PIS& pis=communication.indexSet();\n- 130 const RI& ri = communication.remoteIndices();\n- 131\n- 132 // at the beginning make a multimap \"bordercontribution\".\n- 133 // process has i and j as border dofs but is not the owner\n- 134 // => only contribute to Ax if i,j is in bordercontribution\n- 135 if (buildcomm == true) {\n- 136\n- 137 // set up mask vector\n- 138 if (mask.size()!=static_cast::size_type>\n-(x.size())) {\n- 139 mask.resize(x.size());\n- 140 for (typename std::vector::size_type i=0; ilocal().attribute()==OwnerOverlapCopyAttributeSet::copy)\n- 144 mask[i->local().local()] = 0;\n- 145 else if (i->local().attribute()==OwnerOverlapCopyAttributeSet::overlap)\n- 146 mask[i->local().local()] = 2;\n- 147 }\n- 148\n- 149 for (MM::iterator iter = bordercontribution.begin();\n- 150 iter != bordercontribution.end(); ++iter)\n- 151 bordercontribution.erase(iter);\n- 152 std::map owner; //key: local index i, value: process, that owns i\n- 153 RIMap rimap;\n+ 125};\n+ 126\n+ 127// min block level for MultiTypeBlockVector\n+ 128template\n+ 129struct MinBlockLevel>\n+ 130{\n+ 131 static constexpr std::size_t value()\n+ 132 {\n+ 133 using V = MultiTypeBlockVector;\n+ 134 constexpr auto min = [](const auto& a, const auto& b){ return std::min\n+(a,b); };\n+ 135 return blockLevelMultiTypeBlockVector(min);\n+ 136 }\n+ 137};\n+ 138\n+ 139// special case: empty MultiTypeBlockVector\n+ 140template<>\n+ 141struct MaxBlockLevel>\n+ 142{\n+ 143 static constexpr std::size_t value()\n+ 144 { return 0; };\n+ 145};\n+ 146\n+ 147// special case: empty MultiTypeBlockVector\n+ 148template<>\n+ 149struct MinBlockLevel>\n+ 150{\n+ 151 static constexpr std::size_t value()\n+ 152 { return 0; };\n+ 153};\n 154\n- 155 // for each local index make multimap rimap:\n- 156 // key: local index i, data: pair of process that knows i and pointer to\n-RI entry\n- 157 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i)\n- 158 if (mask[i.index()] == 0)\n- 159 for (RIIterator remote = ri.begin(); remote != ri.end(); ++remote) {\n- 160 RIL& ril = *(remote->second.first);\n- 161 for (RILIterator rindex = ril.begin(); rindex != ril.end(); ++rindex)\n- 162 if (rindex->attribute() != OwnerOverlapCopyAttributeSet::overlap)\n- 163 if (rindex->localIndexPair().local().local() == i.index()) {\n- 164 rimap.insert\n- 165 (std::make_pair(i.index(),\n- 166 std::pair(remote->first, rindex)));\n- 167 if(rindex->attribute()==OwnerOverlapCopyAttributeSet::owner)\n- 168 owner.insert(std::make_pair(i.index(),remote->first));\n- 169 }\n- 170 }\n- 171\n- 172 int iowner = 0;\n- 173 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {\n- 174 if (mask[i.index()] == 0) {\n- 175 std::map::iterator it = owner.find(i.index());\n- 176 iowner = it->second;\n- 177 std::pair foundiit = rimap.equal_range(i.index());\n- 178 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n-(); ++j) {\n- 179 if (mask[j.index()] == 0) {\n- 180 bool flag = true;\n- 181 for (RIMapit foundi = foundiit.first; foundi != foundiit.second; ++foundi)\n-{\n- 182 std::pair foundjit = rimap.equal_range(j.index());\n- 183 for (RIMapit foundj = foundjit.first; foundj != foundjit.second; ++foundj)\n- 184 if (foundj->second.first == foundi->second.first)\n- 185 if (foundj->second.second->attribute() == OwnerOverlapCopyAttributeSet::\n-owner\n- 186 || foundj->second.first == iowner\n- 187 || foundj->second.first < communication.communicator().rank()) {\n- 188 flag = false;\n- 189 continue;\n- 190 }\n- 191 if (flag == false)\n- 192 continue;\n- 193 }\n- 194 // don\u00b4t contribute to Ax if\n- 195 // 1. the owner of j has i as interior/border dof\n- 196 // 2. iowner has j as interior/border dof\n- 197 // 3. there is another process with smaller rank that has i and j\n- 198 // as interor/border dofs\n- 199 // if the owner of j does not have i as interior/border dof,\n- 200 // it will not be taken into account\n- 201 if (flag==true)\n- 202 bordercontribution.insert(std::pair(i.index(),j.index()));\n- 203 }\n- 204 }\n- 205 }\n- 206 }\n- 207 buildcomm = false;\n- 208 }\n- 209\n- 210 //compute alpha*A*x nonoverlapping case\n- 211 for (RowIterator i = _A_->begin(); i != _A_->end(); ++i) {\n- 212 if (mask[i.index()] == 0) {\n- 213 //dof doesn't belong to process but is border (not ghost)\n- 214 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n-(); ++j) {\n- 215 if (mask[j.index()] == 1) //j is owner => then sum entries\n- 216 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n- 217 else if (mask[j.index()] == 0) {\n- 218 std::pair itp =\n- 219 bordercontribution.equal_range(i.index());\n- 220 for (MM::iterator it = itp.first; it != itp.second; ++it)\n- 221 if ((*it).second == (int)j.index())\n- 222 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n- 223 }\n- 224 }\n- 225 }\n- 226 else if (mask[i.index()] == 1) {\n- 227 for (ColIterator j = (*_A_)[i.index()].begin(); j != (*_A_)[i.index()].end\n-(); ++j)\n- 228 if (mask[j.index()] != 2)\n- 229 Impl::asMatrix(*j).usmv(alpha,x[j.index()],y[i.index()]);\n- 230 }\n- 231 }\n- 232 }\n- 233\n-235 virtual SolverCategory::Category category() const\n- 236 {\n- 237 return SolverCategory::nonoverlapping;\n- 238 }\n- 239\n-241 const communication_type& getCommunication() const\n- 242 {\n- 243 return communication;\n- 244 }\n- 245 private:\n- 246 std::shared_ptr _A_;\n- 247 const communication_type& communication;\n- 248 mutable bool buildcomm;\n- 249 mutable std::vector mask;\n-250 mutable std::multimap bordercontribution;\n- 251 };\n- 252\n-255 namespace Amg\n- 256 {\n- 257 template struct ConstructionTraits;\n- 258 }\n- 259\n- 274 template\n-275 class NonoverlappingBlockPreconditioner\n- 276 : public Preconditioner {\n- 277 friend struct Amg::\n-ConstructionTraits >;\n- 278 using X = typename P::domain_type;\n- 279 using Y = typename P::range_type;\n- 280 public:\n-282 typedef typename P::domain_type domain_type;\n-284 typedef typename P::range_type range_type;\n-286 typedef C communication_type;\n- 287\n-302 NonoverlappingBlockPreconditioner (P& p, const communication_type& c)\n- 303 : _preconditioner(stackobject_to_shared_ptr(p)), _communication(c)\n- 304 { }\n- 305\n-313 NonoverlappingBlockPreconditioner (const std::shared_ptr

    & p, const\n-communication_type& c)\n- 314 : _preconditioner(p), _communication(c)\n- 315 { }\n- 316\n-322 virtual void pre (domain_type& x, range_type& b)\n- 323 {\n- 324 _preconditioner->pre(x,b);\n- 325 }\n- 326\n-332 virtual void apply (domain_type& v, const range_type& d)\n- 333 {\n- 334 // block preconditioner equivalent to WrappedPreconditioner from\n- 335 // pdelab/backend/ovlpistsolverbackend.hh,\n- 336 // but not to BlockPreconditioner from schwarz.hh\n- 337 _preconditioner->apply(v,d);\n- 338 _communication.addOwnerCopyToOwnerCopy(v,v);\n- 339 }\n- 340\n- 341 template\n-342 void apply (X& v, const Y& d)\n- 343 {\n- 344 _preconditioner->template apply(v,d);\n- 345 _communication.addOwnerCopyToOwnerCopy(v,v);\n- 346 }\n- 347\n-353 virtual void post (domain_type& x)\n- 354 {\n- 355 _preconditioner->post(x);\n- 356 }\n- 357\n-359 virtual SolverCategory::Category category() const\n- 360 {\n- 361 return SolverCategory::nonoverlapping;\n- 362 }\n- 363\n- 364 private:\n- 366 std::shared_ptr

    _preconditioner;\n- 367\n- 369 const communication_type& _communication;\n- 370 };\n- 371\n- 374} // end namespace\n- 375\n- 376#endif\n-operators.hh\n-Define general, extensible interface for operators. The available\n-implementation wraps a matrix.\n-solvers.hh\n-Implementations of the inverse operator interface.\n-preconditioners.hh\n-Define general preconditioner interface.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n-scalarproducts.hh\n-Define base class for scalar product and norm.\n-ilu.hh\n-The incomplete LU factorization kernels.\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n-owneroverlapcopy.hh\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-vbvector.hh\n-???\n-io.hh\n-Some generic functions for pretty printing vectors and matrices.\n-gsetc.hh\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way.\n+ 155}} // end namespace Dune::Impl\n+ 156\n+ 157namespace Dune {\n+ 158\n+ 160template\n+161constexpr std::size_t maxBlockLevel()\n+ 162{ return Impl::MaxBlockLevel::value(); }\n+ 163\n+ 165template\n+166constexpr std::size_t minBlockLevel()\n+ 167{ return Impl::MinBlockLevel::value(); }\n+ 168\n+ 170template\n+171constexpr bool hasUniqueBlockLevel()\n+ 172{ return maxBlockLevel() == minBlockLevel(); }\n+ 173\n+ 175template\n+176constexpr std::size_t blockLevel()\n+ 177{\n+ 178 static_assert(hasUniqueBlockLevel(), \"Block level cannot be uniquely\n+determined!\");\n+ 179 return Impl::MaxBlockLevel::value();\n+ 180}\n+ 181\n+ 182} // end namespace Dune\n+ 183\n+ 184#endif\n Dune\n Definition: allocator.hh:11\n-Dune::NonoverlappingSchwarzOperator\n-A nonoverlapping operator with communication object.\n-Definition: novlpschwarz.hh:61\n-Dune::NonoverlappingSchwarzOperator::PIS\n-C::PIS PIS\n-Definition: novlpschwarz.hh:74\n-Dune::NonoverlappingSchwarzOperator::communication_type\n-C communication_type\n-The type of the communication object.\n-Definition: novlpschwarz.hh:72\n-Dune::NonoverlappingSchwarzOperator::RIMap\n-std::multimap< int, std::pair< int, RILIterator > > RIMap\n-Definition: novlpschwarz.hh:82\n-Dune::NonoverlappingSchwarzOperator::RI\n-C::RI RI\n-Definition: novlpschwarz.hh:75\n-Dune::NonoverlappingSchwarzOperator::novlp_op_apply\n-void novlp_op_apply(const X &x, Y &y, field_type alpha) const\n-Definition: novlpschwarz.hh:126\n-Dune::NonoverlappingSchwarzOperator::NonoverlappingSchwarzOperator\n-NonoverlappingSchwarzOperator(std::shared_ptr< const matrix_type > A, const\n-communication_type &com)\n-Definition: novlpschwarz.hh:96\n-Dune::NonoverlappingSchwarzOperator::ColIterator\n-M::ConstColIterator ColIterator\n-Definition: novlpschwarz.hh:79\n-Dune::NonoverlappingSchwarzOperator::apply\n-virtual void apply(const X &x, Y &y) const\n-apply operator to x:\n-Definition: novlpschwarz.hh:101\n-Dune::NonoverlappingSchwarzOperator::domain_type\n-X domain_type\n-The type of the domain.\n-Definition: novlpschwarz.hh:66\n-Dune::NonoverlappingSchwarzOperator::category\n-virtual SolverCategory::Category category() const\n-Category of the linear operator (see SolverCategory::Category)\n-Definition: novlpschwarz.hh:235\n-Dune::NonoverlappingSchwarzOperator::RIMapit\n-RIMap::iterator RIMapit\n-Definition: novlpschwarz.hh:83\n-Dune::NonoverlappingSchwarzOperator::getmat\n-virtual const matrix_type & getmat() const\n-get matrix via *\n-Definition: novlpschwarz.hh:121\n-Dune::NonoverlappingSchwarzOperator::RILIterator\n-RIL::const_iterator RILIterator\n-Definition: novlpschwarz.hh:78\n-Dune::NonoverlappingSchwarzOperator::MM\n-std::multimap< int, int > MM\n-Definition: novlpschwarz.hh:81\n-Dune::NonoverlappingSchwarzOperator::range_type\n-Y range_type\n-The type of the range.\n-Definition: novlpschwarz.hh:68\n-Dune::NonoverlappingSchwarzOperator::matrix_type\n-M matrix_type\n-The type of the matrix we operate on.\n-Definition: novlpschwarz.hh:64\n-Dune::NonoverlappingSchwarzOperator::RowIterator\n-M::ConstRowIterator RowIterator\n-Definition: novlpschwarz.hh:80\n-Dune::NonoverlappingSchwarzOperator::getCommunication\n-const communication_type & getCommunication() const\n-Get the object responsible for communication.\n-Definition: novlpschwarz.hh:241\n-Dune::NonoverlappingSchwarzOperator::applyscaleadd\n-virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const\n-apply operator to x, scale and add:\n-Definition: novlpschwarz.hh:109\n-Dune::NonoverlappingSchwarzOperator::RIL\n-RI::RemoteIndexList RIL\n-Definition: novlpschwarz.hh:76\n-Dune::NonoverlappingSchwarzOperator::field_type\n-X::field_type field_type\n-The field type of the range.\n-Definition: novlpschwarz.hh:70\n-Dune::NonoverlappingSchwarzOperator::NonoverlappingSchwarzOperator\n-NonoverlappingSchwarzOperator(const matrix_type &A, const communication_type\n-&com)\n-constructor: just store a reference to a matrix.\n-Definition: novlpschwarz.hh:92\n-Dune::NonoverlappingSchwarzOperator::RIIterator\n-RI::const_iterator RIIterator\n-Definition: novlpschwarz.hh:77\n-Dune::Amg::ConstructionTraits\n-Traits class for generically constructing non default constructable types.\n-Definition: construction.hh:39\n-Dune::NonoverlappingBlockPreconditioner\n-Nonoverlapping parallel preconditioner.\n-Definition: novlpschwarz.hh:276\n-Dune::NonoverlappingBlockPreconditioner::NonoverlappingBlockPreconditioner\n-NonoverlappingBlockPreconditioner(P &p, const communication_type &c)\n-Constructor.\n-Definition: novlpschwarz.hh:302\n-Dune::NonoverlappingBlockPreconditioner::category\n-virtual SolverCategory::Category category() const\n-Category of the preconditioner (see SolverCategory::Category)\n-Definition: novlpschwarz.hh:359\n-Dune::NonoverlappingBlockPreconditioner::apply\n-virtual void apply(domain_type &v, const range_type &d)\n-Apply the preconditioner.\n-Definition: novlpschwarz.hh:332\n-Dune::NonoverlappingBlockPreconditioner::range_type\n-P::range_type range_type\n-The range type of the preconditioner.\n-Definition: novlpschwarz.hh:284\n-Dune::NonoverlappingBlockPreconditioner::NonoverlappingBlockPreconditioner\n-NonoverlappingBlockPreconditioner(const std::shared_ptr< P > &p, const\n-communication_type &c)\n-Constructor.\n-Definition: novlpschwarz.hh:313\n-Dune::NonoverlappingBlockPreconditioner::post\n-virtual void post(domain_type &x)\n-Clean up.\n-Definition: novlpschwarz.hh:353\n-Dune::NonoverlappingBlockPreconditioner::communication_type\n-C communication_type\n-The type of the communication object.\n-Definition: novlpschwarz.hh:286\n-Dune::NonoverlappingBlockPreconditioner::pre\n-virtual void pre(domain_type &x, range_type &b)\n-Prepare the preconditioner.\n-Definition: novlpschwarz.hh:322\n-Dune::NonoverlappingBlockPreconditioner::apply\n-void apply(X &v, const Y &d)\n-Apply one step of the preconditioner to the system A(v)=d.\n-Definition: novlpschwarz.hh:342\n-Dune::NonoverlappingBlockPreconditioner::domain_type\n-P::domain_type domain_type\n-The domain type of the preconditioner.\n-Definition: novlpschwarz.hh:282\n-Dune::AssembledLinearOperator\n-A linear operator exporting itself in matrix form.\n-Definition: operators.hh:109\n-Dune::OwnerOverlapCopyAttributeSet::owner\n-@ owner\n-Definition: owneroverlapcopy.hh:61\n-Dune::OwnerOverlapCopyAttributeSet::copy\n-@ copy\n-Definition: owneroverlapcopy.hh:61\n-Dune::OwnerOverlapCopyAttributeSet::overlap\n-@ overlap\n-Definition: owneroverlapcopy.hh:61\n-Dune::Preconditioner\n-Base class for matrix free definition of preconditioners.\n-Definition: preconditioner.hh:32\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::nonoverlapping\n-@ nonoverlapping\n-Category for non-overlapping solvers.\n-Definition: solvercategory.hh:27\n+Dune::hasUniqueBlockLevel\n+constexpr bool hasUniqueBlockLevel()\n+Determine if a vector/matrix has a uniquely determinable block level.\n+Definition: blocklevel.hh:171\n+Dune::maxBlockLevel\n+constexpr std::size_t maxBlockLevel()\n+Determine the maximum block level of a possibly nested vector/matrix type.\n+Definition: blocklevel.hh:161\n+Dune::blockLevel\n+constexpr std::size_t blockLevel()\n+Determine the block level of a possibly nested vector/matrix type.\n+Definition: blocklevel.hh:176\n+Dune::minBlockLevel\n+constexpr std::size_t minBlockLevel()\n+Determine the minimum block level of a possibly nested vector/matrix type.\n+Definition: blocklevel.hh:166\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00215.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00215.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: owneroverlapcopy.hh File Reference\n+dune-istl: solverfactory.hh File Reference\n \n \n \n \n \n \n \n@@ -65,94 +65,88 @@\n

  • dune
  • istl
  • \n \n \n
    \n \n- \n+
    solverfactory.hh File Reference
    \n
    \n
    \n-\n-

    Classes providing communication interfaces for overlapping Schwarz methods. \n-More...

    \n-
    #include <new>
    \n-#include <iostream>
    \n-#include <vector>
    \n-#include <list>
    \n-#include <map>
    \n-#include <set>
    \n-#include <tuple>
    \n-#include "cmath"
    \n-#include <mpi.h>
    \n-#include <dune/common/enumset.hh>
    \n-#include <dune/common/parallel/indexset.hh>
    \n-#include <dune/common/parallel/communicator.hh>
    \n-#include <dune/common/parallel/remoteindices.hh>
    \n-#include <dune/common/parallel/mpicommunication.hh>
    \n-#include "solvercategory.hh"
    \n-#include "istlexception.hh"
    \n-#include <dune/common/parallel/communication.hh>
    \n-#include <dune/istl/matrixmarket.hh>
    \n+
    #include <unordered_map>
    \n+#include <functional>
    \n+#include <memory>
    \n+#include <dune/common/parametertree.hh>
    \n+#include <dune/common/singleton.hh>
    \n+#include "solverregistry.hh"
    \n+#include <dune/istl/solver.hh>
    \n+#include <dune/istl/schwarz.hh>
    \n+#include <dune/istl/novlpschwarz.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    struct  Dune::OwnerOverlapCopyAttributeSet
     Attribute set for overlapping Schwarz. More...
     
    class  Dune::IndexInfoFromGrid< G, L >
     Information about the index distribution. More...
     
    class  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >
     A class setting up standard communication for a two-valued attribute set with owner/overlap/copy semantics. More...
     
    struct  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::CopyGatherScatter< T >
     gather/scatter callback for communcation More...
     
    struct  Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::AddGatherScatter< T >
    class  Dune::SolverFactory< Operator >
     Factory to assembly solvers configured by a ParameterTree. More...
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+

    \n+Typedefs

    template<class M , class X , class Y >
    using Dune::DirectSolverSignature = std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &)
     
    template<class M , class X , class Y >
    using Dune::DirectSolverFactory = Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > >
     
    template<class M , class X , class Y >
    using Dune::PreconditionerSignature = std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const ParameterTree &)
     
    template<class M , class X , class Y >
    using Dune::PreconditionerFactory = Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > >
     
    template<class X , class Y >
    using Dune::IterativeSolverSignature = std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &, const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &)
     
    template<class X , class Y >
    using Dune::IterativeSolverFactory = Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > >
     
    \n \n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<int dim, template< class, class > class Comm>
    void testRedistributed (int s)
     
    template<class O , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const O &)
     
    template<class M , class X , class Y , class C , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y , class C , class Preconditioner >
    std::shared_ptr< Preconditioner > Dune::wrapPreconditioner4Parallel (const std::shared_ptr< Preconditioner > &prec, const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< MatrixAdapter< M, X, Y > > &)
     
    template<class M , class X , class Y , class C >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< OverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class M , class X , class Y , class C >
    std::shared_ptr< ScalarProduct< X > > Dune::createScalarProduct (const std::shared_ptr< NonoverlappingSchwarzOperator< M, X, Y, C > > &op)
     
    template<class Operator >
    std::shared_ptr< InverseOperator< typename Operator::domain_type, typename Operator::range_type > > Dune::getSolverFromFactory (std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > prec=nullptr)
     Instantiates an InverseOperator from an Operator and a configuration given as a ParameterTree. More...
     
    \n-

    Detailed Description

    \n-

    Classes providing communication interfaces for overlapping Schwarz methods.

    \n-
    Author
    Peter Bastian
    \n-

    Function Documentation

    \n-\n-

    ◆ testRedistributed()

    \n-\n-
    \n-
    \n-
    \n-template<int dim, template< class, class > class Comm>
    \n- \n- \n- \n- \n- \n- \n- \n- \n-
    void testRedistributed (int s)
    \n-
    \n-\n-
    \n-
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,67 +4,103 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-owneroverlapcopy.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Communication_Interface\n-Classes providing communication interfaces for overlapping Schwarz methods.\n-More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"cmath\"\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"solvercategory.hh\"\n-#include \"istlexception.hh\"\n-#include \n-#include \n+Classes | Namespaces | Typedefs | Functions\n+solverfactory.hh File Reference\n+#include \n+#include \n+#include \n+#include \n+#include \n+#include \"solverregistry.hh\"\n+#include \n+#include \n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::OwnerOverlapCopyAttributeSet\n-\u00a0 Attribute set for overlapping Schwarz. More...\n-\u00a0\n- class \u00a0Dune::IndexInfoFromGrid<_G,_L_>\n-\u00a0 Information about the index distribution. More...\n-\u00a0\n- class \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>\n-\u00a0 A class setting up standard communication for a two-valued attribute\n- set with owner/overlap/copy semantics. More...\n-\u00a0\n-struct \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>::\n- CopyGatherScatter<_T_>\n-\u00a0 gather/scatter callback for communcation More...\n-\u00a0\n-struct \u00a0Dune::OwnerOverlapCopyCommunication<_GlobalIdType,_LocalIdType_>::\n- AddGatherScatter<_T_>\n+class \u00a0Dune::SolverFactory<_Operator_>\n+\u00a0 Factory to assembly solvers configured by a ParameterTree. More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Typedefs\n+template\n+using\u00a0Dune::DirectSolverSignature = std::shared_ptr< InverseOperator< X, Y > >\n+ (const M &, const ParameterTree &)\n+\u00a0\n+template\n+using\u00a0Dune::DirectSolverFactory = Singleton< ParameterizedObjectFactory<\n+ DirectSolverSignature< M, X, Y > > >\n+\u00a0\n+template\n+using\u00a0Dune::PreconditionerSignature = std::shared_ptr< Preconditioner< X, Y >\n+ >(const std::shared_ptr< M > &, const ParameterTree &)\n+\u00a0\n+template\n+using\u00a0Dune::PreconditionerFactory = Singleton< ParameterizedObjectFactory<\n+ PreconditionerSignature< M, X, Y > > >\n+\u00a0\n+template\n+using\u00a0Dune::IterativeSolverSignature = std::shared_ptr< InverseOperator< X, Y\n+ > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::\n+ shared_ptr< ScalarProduct< X > > &, const std::shared_ptr<\n+ Preconditioner< X, Y > >, const ParameterTree &)\n+\u00a0\n+template\n+using\u00a0Dune::IterativeSolverFactory = Singleton< ParameterizedObjectFactory<\n+ IterativeSolverSignature< X, Y > > >\n+\u00a0\n Functions\n-template class Comm>\n-void\u00a0testRedistributed (int s)\n+template\n+ std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n+ std::shared_ptr< Preconditioner > &prec,\n+ const O &)\n+\u00a0\n+template\n+ std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n+ std::shared_ptr< Preconditioner > &prec,\n+ const std::shared_ptr<\n+ OverlappingSchwarzOperator< M, X, Y, C >\n+ > &op)\n+\u00a0\n+template\n+ std::shared_ptr< Preconditioner >\u00a0Dune::wrapPreconditioner4Parallel (const\n+ std::shared_ptr< Preconditioner > &prec,\n+ const std::shared_ptr<\n+ NonoverlappingSchwarzOperator< M, X, Y,\n+ C > > &op)\n+\u00a0\n+template\n+std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n+ shared_ptr< MatrixAdapter< M, X, Y > >\n+ &)\n+\u00a0\n+template\n+std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n+ shared_ptr< OverlappingSchwarzOperator<\n+ M, X, Y, C > > &op)\n+\u00a0\n+template\n+std::shared_ptr< ScalarProduct< X > >\u00a0Dune::createScalarProduct (const std::\n+ shared_ptr<\n+ NonoverlappingSchwarzOperator< M, X, Y,\n+ C > > &op)\n+\u00a0\n+template\n+ std::shared_ptr< InverseOperator< Dune::getSolverFromFactory (std::\n+ typename Operator::domain_type, shared_ptr< Operator > op, const\n+ typename Operator::range_type > >\u00a0ParameterTree &config, std::shared_ptr<\n+ Preconditioner< typename Operator::\n+ domain_type, typename Operator::\n+ range_type > > prec=nullptr)\n+ Instantiates an InverseOperator from an\n+\u00a0 Operator and a configuration given as a\n+ ParameterTree. More...\n \u00a0\n-***** Detailed Description *****\n-Classes providing communication interfaces for overlapping Schwarz methods.\n- Author\n- Peter Bastian\n-***** Function Documentation *****\n-***** \u25c6\u00a0testRedistributed() *****\n-template class Comm>\n-void testRedistributed ( int\u00a0s )\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00215_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00215_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: owneroverlapcopy.hh Source File\n+dune-istl: solverfactory.hh Source File\n \n \n \n \n \n \n \n@@ -62,628 +62,225 @@\n \n
    \n \n
    \n
    \n
    \n-
    owneroverlapcopy.hh
    \n+
    solverfactory.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_OWNEROVERLAPCOPY_HH
    \n-
    6#define DUNE_ISTL_OWNEROVERLAPCOPY_HH
    \n-
    7
    \n-
    8#include <new>
    \n-
    9#include <iostream>
    \n-
    10#include <vector>
    \n-
    11#include <list>
    \n-
    12#include <map>
    \n-
    13#include <set>
    \n-
    14#include <tuple>
    \n+
    5
    \n+
    6#ifndef DUNE_ISTL_SOLVERFACTORY_HH
    \n+
    7#define DUNE_ISTL_SOLVERFACTORY_HH
    \n+
    8
    \n+
    9#include <unordered_map>
    \n+
    10#include <functional>
    \n+
    11#include <memory>
    \n+
    12
    \n+
    13#include <dune/common/parametertree.hh>
    \n+
    14#include <dune/common/singleton.hh>
    \n
    15
    \n-
    16#include "cmath"
    \n-
    17
    \n-
    18// MPI header
    \n-
    19#if HAVE_MPI
    \n-
    20#include <mpi.h>
    \n-
    21#endif
    \n-
    22
    \n-
    23#include <dune/common/enumset.hh>
    \n-
    24
    \n-
    25#if HAVE_MPI
    \n-
    26#include <dune/common/parallel/indexset.hh>
    \n-
    27#include <dune/common/parallel/communicator.hh>
    \n-
    28#include <dune/common/parallel/remoteindices.hh>
    \n-
    29#include <dune/common/parallel/mpicommunication.hh>
    \n-
    30#endif
    \n+
    16#include "solverregistry.hh"
    \n+
    17#include <dune/istl/solver.hh>
    \n+
    18#include <dune/istl/schwarz.hh>
    \n+\n+
    20
    \n+
    21namespace Dune{
    \n+
    26 // Direct solver factory:
    \n+
    27 template<class M, class X, class Y>
    \n+
    28 using DirectSolverSignature = std::shared_ptr<InverseOperator<X,Y>>(const M&, const ParameterTree&);
    \n+
    29 template<class M, class X, class Y>
    \n+
    30 using DirectSolverFactory = Singleton<ParameterizedObjectFactory<DirectSolverSignature<M,X,Y>>>;
    \n
    31
    \n-
    32#include "solvercategory.hh"
    \n-
    33#include "istlexception.hh"
    \n-
    34#include <dune/common/parallel/communication.hh>
    \n-\n-
    36
    \n-
    37template<int dim, template<class,class> class Comm>
    \n-\n-
    39
    \n-
    40
    \n-
    41namespace Dune {
    \n-
    42
    \n-\n-
    59 {
    \n-\n-\n-
    62 };
    \n-
    63 };
    \n-
    64
    \n-
    76 template <class G, class L>
    \n-\n-
    78 {
    \n-
    79 public:
    \n-
    81 typedef G GlobalIdType;
    \n-
    82
    \n-
    84 typedef L LocalIdType;
    \n-
    85
    \n-
    92 typedef std::tuple<GlobalIdType,LocalIdType,int> IndexTripel;
    \n-
    99 typedef std::tuple<int,GlobalIdType,int> RemoteIndexTripel;
    \n-
    100
    \n-\n-
    107 {
    \n-
    108 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
    \n-\n-\n-
    111 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n-
    112 localindices.insert(x);
    \n-
    113 }
    \n-
    114
    \n-\n-
    121 {
    \n-
    122 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
    \n-\n-\n-
    125 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n-
    126 remoteindices.insert(x);
    \n-
    127 }
    \n-
    128
    \n-
    133 const std::set<IndexTripel>& localIndices () const
    \n-
    134 {
    \n-
    135 return localindices;
    \n-
    136 }
    \n-
    137
    \n-
    142 const std::set<RemoteIndexTripel>& remoteIndices () const
    \n-
    143 {
    \n-
    144 return remoteindices;
    \n-
    145 }
    \n-
    146
    \n-
    150 void clear ()
    \n-
    151 {
    \n-
    152 localindices.clear();
    \n-
    153 remoteindices.clear();
    \n-
    154 }
    \n+
    32 // Preconditioner factory:
    \n+
    33 template<class M, class X, class Y>
    \n+
    34 using PreconditionerSignature = std::shared_ptr<Preconditioner<X,Y>>(const std::shared_ptr<M>&, const ParameterTree&);
    \n+
    35 template<class M, class X, class Y>
    \n+
    36 using PreconditionerFactory = Singleton<ParameterizedObjectFactory<PreconditionerSignature<M,X,Y>>>;
    \n+
    37
    \n+
    38 // Iterative solver factory
    \n+
    39 template<class X, class Y>
    \n+
    40 using IterativeSolverSignature = std::shared_ptr<InverseOperator<X,Y>>(const std::shared_ptr<LinearOperator<X,Y>>&, const std::shared_ptr<ScalarProduct<X>>&, const std::shared_ptr<Preconditioner<X,Y>>, const ParameterTree&);
    \n+
    41 template<class X, class Y>
    \n+
    42 using IterativeSolverFactory = Singleton<ParameterizedObjectFactory<IterativeSolverSignature<X,Y>>>;
    \n+
    43
    \n+
    44 // initSolverFactories differs in different compilation units, so we have it
    \n+
    45 // in an anonymous namespace
    \n+
    46 namespace {
    \n+
    47
    \n+
    53 template<class O>
    \n+
    54 int initSolverFactories(){
    \n+
    55 using M = typename O::matrix_type;
    \n+
    56 using X = typename O::range_type;
    \n+
    57 using Y = typename O::domain_type;
    \n+
    58 using TL = Dune::TypeList<M,X,Y>;
    \n+\n+
    60 addRegistryToFactory<TL>(dsfac, DirectSolverTag{});
    \n+\n+
    62 addRegistryToFactory<TL>(pfac, PreconditionerTag{});
    \n+
    63 using TLS = Dune::TypeList<X,Y>;
    \n+\n+
    65 return addRegistryToFactory<TLS>(isfac, IterativeSolverTag{});
    \n+
    66 }
    \n+
    77 template<class O, class X, class Y>
    \n+
    78 [[deprecated("Use method 'initSolverFactories<O>' instead")]]
    \n+
    79 int initSolverFactories() {
    \n+
    80 return initSolverFactories<O>();
    \n+
    81 }
    \n+
    82 } // end anonymous namespace
    \n+
    83
    \n+
    84
    \n+
    85 template<class O, class Preconditioner>
    \n+
    86 std::shared_ptr<Preconditioner> wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n+
    87 const O&)
    \n+
    88 {
    \n+
    89 return prec;
    \n+
    90 }
    \n+
    91
    \n+
    92 template<class M, class X, class Y, class C, class Preconditioner>
    \n+
    93 std::shared_ptr<Preconditioner>
    \n+
    94 wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n+
    95 const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n+
    96 {
    \n+
    97 return std::make_shared<BlockPreconditioner<X,Y,C,Preconditioner> >(prec, op->getCommunication());
    \n+
    98 }
    \n+
    99
    \n+
    100 template<class M, class X, class Y, class C, class Preconditioner>
    \n+
    101 std::shared_ptr<Preconditioner>
    \n+
    102 wrapPreconditioner4Parallel(const std::shared_ptr<Preconditioner>& prec,
    \n+
    103 const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n+
    104 {
    \n+
    105 return std::make_shared<NonoverlappingBlockPreconditioner<C,Preconditioner> >(prec, op->getCommunication());
    \n+
    106 }
    \n+
    107
    \n+
    108 template<class M, class X, class Y>
    \n+
    109 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<MatrixAdapter<M,X,Y> >&)
    \n+
    110 {
    \n+
    111 return std::make_shared<SeqScalarProduct<X>>();
    \n+
    112 }
    \n+
    113 template<class M, class X, class Y, class C>
    \n+
    114 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<OverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n+
    115 {
    \n+
    116 return createScalarProduct<X>(op->getCommunication(), op->category());
    \n+
    117 }
    \n+
    118
    \n+
    119 template<class M, class X, class Y, class C>
    \n+
    120 std::shared_ptr<ScalarProduct<X>> createScalarProduct(const std::shared_ptr<NonoverlappingSchwarzOperator<M,X,Y,C> >& op)
    \n+
    121 {
    \n+
    122 return createScalarProduct<X>(op->getCommunication(), op->category());
    \n+
    123 }
    \n+
    124
    \n+
    144 template<class Operator>
    \n+\n+
    146 using Domain = typename Operator::domain_type;
    \n+
    147 using Range = typename Operator::range_type;
    \n+\n+\n+
    150
    \n+
    151 template<class O>
    \n+
    152 using _matrix_type = typename O::matrix_type;
    \n+
    153 using matrix_type = Std::detected_or_t<int, _matrix_type, Operator>;
    \n+
    154 static constexpr bool isAssembled = !std::is_same<matrix_type, int>::value;
    \n
    155
    \n-
    156 private:
    \n-
    158 std::set<IndexTripel> localindices;
    \n-
    160 std::set<RemoteIndexTripel> remoteindices;
    \n-
    161 };
    \n-
    162
    \n+
    156 static const matrix_type* getmat(std::shared_ptr<Operator> op){
    \n+
    157 std::shared_ptr<AssembledLinearOperator<matrix_type, Domain, Range>> aop
    \n+
    158 = std::dynamic_pointer_cast<AssembledLinearOperator<matrix_type, Domain, Range>>(op);
    \n+
    159 if(aop)
    \n+
    160 return &aop->getmat();
    \n+
    161 return nullptr;
    \n+
    162 }
    \n
    163
    \n-
    164#if HAVE_MPI
    \n+
    164 public:
    \n
    165
    \n-
    172 template <class GlobalIdType, class LocalIdType=int>
    \n-\n-
    174 {
    \n-
    175 template<typename M, typename G, typename L>
    \n-
    176 friend void loadMatrixMarket(M&,
    \n-
    177 const std::string&,
    \n-\n-
    179 bool);
    \n-
    180 // used types
    \n-\n-\n-
    183 typedef typename std::set<IndexTripel>::const_iterator localindex_iterator;
    \n-
    184 typedef typename std::set<RemoteIndexTripel>::const_iterator remoteindex_iterator;
    \n-\n-
    186 typedef Dune::ParallelLocalIndex<AttributeSet> LI;
    \n-
    187 public:
    \n-
    188 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> PIS;
    \n-
    189 typedef Dune::RemoteIndices<PIS> RI;
    \n-
    190 typedef Dune::RemoteIndexListModifier<PIS,typename RI::Allocator,false> RILM;
    \n-
    191 typedef typename RI::RemoteIndex RX;
    \n-
    192 typedef Dune::BufferedCommunicator BC;
    \n-
    193 typedef Dune::Interface IF;
    \n-
    194 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner> OwnerSet;
    \n-
    195 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopySet;
    \n-
    196 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> OwnerOverlapSet;
    \n-
    197 typedef Dune::AllSet<AttributeSet> AllSet;
    \n-
    198 protected:
    \n+
    168 static std::shared_ptr<Solver> get(std::shared_ptr<Operator> op,
    \n+
    169 const ParameterTree& config,
    \n+
    170 std::shared_ptr<Preconditioner> prec = nullptr){
    \n+
    171 std::string type = config.get<std::string>("type");
    \n+
    172 std::shared_ptr<Solver> result;
    \n+
    173 const matrix_type* mat = getmat(op);
    \n+
    174 if(mat){
    \n+\n+
    176 if(op->category()!=SolverCategory::sequential){
    \n+
    177 DUNE_THROW(NotImplemented, "The solver factory does not support parallel direct solvers!");
    \n+
    178 }
    \n+
    179 result = DirectSolverFactory<matrix_type, Domain, Range>::instance().create(type, *mat, config);
    \n+
    180 return result;
    \n+
    181 }
    \n+
    182 }
    \n+
    183 // if no direct solver is found it might be an iterative solver
    \n+\n+
    185 DUNE_THROW(Dune::InvalidStateException, "Solver not found in the factory.");
    \n+
    186 }
    \n+
    187 if(!prec){
    \n+
    188 const ParameterTree& precConfig = config.sub("preconditioner");
    \n+
    189 std::string prec_type = precConfig.get<std::string>("type");
    \n+
    190 prec = PreconditionerFactory<Operator, Domain, Range>::instance().create(prec_type, op, precConfig);
    \n+
    191 if (prec->category() != op->category() && prec->category() == SolverCategory::sequential)
    \n+
    192 // try to wrap to a parallel preconditioner
    \n+
    193 prec = wrapPreconditioner4Parallel(prec, op);
    \n+
    194 }
    \n+
    195 std::shared_ptr<ScalarProduct<Domain>> sp = createScalarProduct(op);
    \n+
    196 result = IterativeSolverFactory<Domain, Range>::instance().create(type, op, sp, prec, config);
    \n+
    197 return result;
    \n+
    198 }
    \n
    199
    \n-
    200
    \n-
    202 template<typename T>
    \n-\n-
    204 {
    \n-
    205 typedef typename CommPolicy<T>::IndexedType V;
    \n-
    206
    \n-
    207 static V gather(const T& a, std::size_t i)
    \n-
    208 {
    \n-
    209 return a[i];
    \n-
    210 }
    \n-
    211
    \n-
    212 static void scatter(T& a, V v, std::size_t i)
    \n-
    213 {
    \n-
    214 a[i] = v;
    \n-
    215 }
    \n-
    216 };
    \n-
    217 template<typename T>
    \n-\n-
    219 {
    \n-
    220 typedef typename CommPolicy<T>::IndexedType V;
    \n-
    221
    \n-
    222 static V gather(const T& a, std::size_t i)
    \n-
    223 {
    \n-
    224 return a[i];
    \n-
    225 }
    \n-
    226
    \n-
    227 static void scatter(T& a, V v, std::size_t i)
    \n-
    228 {
    \n-
    229 a[i] += v;
    \n-
    230 }
    \n-
    231 };
    \n-
    232
    \n-\n-
    234 {
    \n-
    235 if (OwnerOverlapToAllInterfaceBuilt)
    \n-
    236 OwnerOverlapToAllInterface.free();
    \n-
    237 OwnerOverlapSet sourceFlags;
    \n-
    238 Combine<OwnerOverlapSet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet>
    \n-
    239 destFlags;
    \n-
    240 OwnerOverlapToAllInterface.build(ri,sourceFlags,destFlags);
    \n-
    241 OwnerOverlapToAllInterfaceBuilt = true;
    \n-
    242 }
    \n-
    243
    \n-\n-
    245 {
    \n-
    246 if (OwnerToAllInterfaceBuilt)
    \n-
    247 OwnerToAllInterface.free();
    \n-
    248 OwnerSet sourceFlags;
    \n-
    249 AllSet destFlags;
    \n-
    250 OwnerToAllInterface.build(ri,sourceFlags,destFlags);
    \n-
    251 OwnerToAllInterfaceBuilt = true;
    \n-
    252 }
    \n-
    253
    \n-\n-
    255 {
    \n-
    256 if (OwnerCopyToAllInterfaceBuilt)
    \n-
    257 OwnerCopyToAllInterface.free();
    \n-
    258
    \n-
    259 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
    \n-
    260 OwnerCopySet sourceFlags;
    \n-
    261 Combine<OwnerCopySet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> destFlags;
    \n-
    262 OwnerCopyToAllInterface.build(ri,sourceFlags,destFlags);
    \n-
    263 OwnerCopyToAllInterfaceBuilt = true;
    \n-
    264 }
    \n-
    265
    \n-\n-
    267 {
    \n-
    268 if (OwnerCopyToOwnerCopyInterfaceBuilt)
    \n-
    269 OwnerCopyToOwnerCopyInterface.free();
    \n-
    270
    \n-
    271
    \n-
    272 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
    \n-
    273 OwnerCopySet sourceFlags;
    \n-
    274 OwnerCopySet destFlags;
    \n-
    275 OwnerCopyToOwnerCopyInterface.build(ri,sourceFlags,destFlags);
    \n-
    276 OwnerCopyToOwnerCopyInterfaceBuilt = true;
    \n-
    277 }
    \n-
    278
    \n-\n-
    280 {
    \n-
    281 if (CopyToAllInterfaceBuilt)
    \n-
    282 CopyToAllInterface.free();
    \n-
    283 CopySet sourceFlags;
    \n-
    284 AllSet destFlags;
    \n-
    285 CopyToAllInterface.build(ri,sourceFlags,destFlags);
    \n-
    286 CopyToAllInterfaceBuilt = true;
    \n-
    287 }
    \n-
    288
    \n-
    289 public:
    \n-
    290
    \n-\n-
    296 return category_;
    \n-
    297 }
    \n-
    298
    \n-
    299 const Communication<MPI_Comm>& communicator() const
    \n-
    300 {
    \n-
    301 return cc;
    \n-
    302 }
    \n-
    303
    \n-
    310 template<class T>
    \n-
    311 void copyOwnerToAll (const T& source, T& dest) const
    \n-
    312 {
    \n-
    313 if (!OwnerToAllInterfaceBuilt)
    \n-\n-\n-
    316 communicator.template build<T>(OwnerToAllInterface);
    \n-
    317 communicator.template forward<CopyGatherScatter<T> >(source,dest);
    \n-
    318 communicator.free();
    \n-
    319 }
    \n-
    320
    \n-
    327 template<class T>
    \n-
    328 void copyCopyToAll (const T& source, T& dest) const
    \n-
    329 {
    \n-
    330 if (!CopyToAllInterfaceBuilt)
    \n-\n-\n-
    333 communicator.template build<T>(CopyToAllInterface);
    \n-
    334 communicator.template forward<CopyGatherScatter<T> >(source,dest);
    \n-
    335 communicator.free();
    \n-
    336 }
    \n-
    337
    \n-
    344 template<class T>
    \n-
    345 void addOwnerOverlapToAll (const T& source, T& dest) const
    \n-
    346 {
    \n-
    347 if (!OwnerOverlapToAllInterfaceBuilt)
    \n-\n-\n-
    350 communicator.template build<T>(OwnerOverlapToAllInterface);
    \n-
    351 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n-
    352 communicator.free();
    \n-
    353 }
    \n-
    354
    \n-
    361 template<class T>
    \n-
    362 void addOwnerCopyToAll (const T& source, T& dest) const
    \n-
    363 {
    \n-
    364 if (!OwnerCopyToAllInterfaceBuilt)
    \n-\n-\n-
    367 communicator.template build<T>(OwnerCopyToAllInterface);
    \n-
    368 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n-
    369 communicator.free();
    \n-
    370 }
    \n-
    371
    \n-
    378 template<class T>
    \n-
    379 void addOwnerCopyToOwnerCopy (const T& source, T& dest) const
    \n-
    380 {
    \n-
    381 if (!OwnerCopyToOwnerCopyInterfaceBuilt)
    \n-\n-\n-
    384 communicator.template build<T>(OwnerCopyToOwnerCopyInterface);
    \n-
    385 communicator.template forward<AddGatherScatter<T> >(source,dest);
    \n-
    386 communicator.free();
    \n-
    387 }
    \n-
    388
    \n-
    389
    \n-
    397 template<class T1, class T2>
    \n-
    398 void dot (const T1& x, const T1& y, T2& result) const
    \n-
    399 {
    \n-
    400 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
    \n-
    401 // set up mask vector
    \n-
    402 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size()))
    \n-
    403 {
    \n-
    404 mask.resize(x.size());
    \n-
    405 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n-
    406 mask[i] = 1;
    \n-
    407 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n-
    408 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
    \n-
    409 mask[i->local().local()] = 0;
    \n-
    410 }
    \n-
    411 result = T2(0.0);
    \n-
    412
    \n-
    413 for (typename T1::size_type i=0; i<x.size(); i++)
    \n-
    414 result += (x[i]*(y[i]))*static_cast<real_type>(mask[i]);
    \n-
    415 result = cc.sum(result);
    \n-
    416 }
    \n-
    417
    \n-
    424 template<class T1>
    \n-
    425 typename FieldTraits<typename T1::field_type>::real_type norm (const T1& x) const
    \n-
    426 {
    \n-
    427 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
    \n-
    428
    \n-
    429 // set up mask vector
    \n-
    430 if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size()))
    \n-
    431 {
    \n-
    432 mask.resize(x.size());
    \n-
    433 for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
    \n-
    434 mask[i] = 1;
    \n-
    435 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n-
    436 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
    \n-
    437 mask[i->local().local()] = 0;
    \n-
    438 }
    \n-
    439 auto result = real_type(0.0);
    \n-
    440 for (typename T1::size_type i=0; i<x.size(); i++)
    \n-
    441 result += Impl::asVector(x[i]).two_norm2()*mask[i];
    \n-
    442 using std::sqrt;
    \n-
    443 return sqrt(cc.sum(result));
    \n-
    444 }
    \n-
    445
    \n-
    446 typedef Dune::EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopyFlags;
    \n-
    447
    \n-
    449 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> ParallelIndexSet;
    \n-
    450
    \n-
    452 typedef Dune::RemoteIndices<PIS> RemoteIndices;
    \n-
    453
    \n-
    456 typedef Dune::GlobalLookupIndexSet<ParallelIndexSet> GlobalLookupIndexSet;
    \n-
    457
    \n-\n-
    463 {
    \n-
    464 return pis;
    \n-
    465 }
    \n-
    466
    \n-\n-
    472 {
    \n-
    473 return ri;
    \n-
    474 }
    \n-
    475
    \n-\n-
    481 {
    \n-
    482 return pis;
    \n-
    483 }
    \n-
    484
    \n-
    485
    \n-\n-
    491 {
    \n-
    492 return ri;
    \n-
    493 }
    \n-
    494
    \n-\n-
    496 {
    \n-
    497 if(globalLookup_) {
    \n-
    498 if(pis.seqNo()==oldseqNo)
    \n-
    499 // Nothing changed!
    \n-
    500 return;
    \n-
    501 delete globalLookup_;
    \n-
    502 }
    \n-
    503
    \n-
    504 globalLookup_ = new GlobalLookupIndexSet(pis);
    \n-
    505 oldseqNo = pis.seqNo();
    \n-
    506 }
    \n-
    507
    \n-
    508 void buildGlobalLookup(std::size_t size)
    \n-
    509 {
    \n-
    510 if(globalLookup_) {
    \n-
    511 if(pis.seqNo()==oldseqNo)
    \n-
    512 // Nothing changed!
    \n-
    513 return;
    \n-
    514 delete globalLookup_;
    \n-
    515 }
    \n-
    516 globalLookup_ = new GlobalLookupIndexSet(pis, size);
    \n-
    517 oldseqNo = pis.seqNo();
    \n-
    518 }
    \n-
    519
    \n-\n-
    521 {
    \n-
    522 delete globalLookup_;
    \n-
    523 globalLookup_=0;
    \n-
    524 }
    \n-
    525
    \n-\n-
    527 {
    \n-
    528 assert(globalLookup_ != 0);
    \n-
    529 return *globalLookup_;
    \n-
    530 }
    \n-
    531
    \n-
    537 template<class T1>
    \n-
    538 void project (T1& x) const
    \n-
    539 {
    \n-
    540 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
    \n-
    541 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
    \n-
    542 x[i->local().local()] = 0;
    \n-
    543 }
    \n-
    544
    \n-\n-\n-
    556 bool freecomm_ = false)
    \n-
    557 : comm(comm_), cc(comm_), pis(), ri(pis,pis,comm_),
    \n-
    558 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
    \n-
    559 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
    \n-
    560 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),
    \n-
    561 freecomm(freecomm_)
    \n-
    562 {}
    \n-
    563
    \n-\n-
    573 : comm(MPI_COMM_WORLD), cc(MPI_COMM_WORLD), pis(), ri(pis,pis,MPI_COMM_WORLD),
    \n-
    574 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
    \n-
    575 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
    \n-
    576 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_), freecomm(false)
    \n-
    577 {}
    \n-
    578
    \n-\n-
    587 MPI_Comm comm_,
    \n-\n-
    589 bool freecomm_ = false)
    \n-
    590 : comm(comm_), cc(comm_), OwnerToAllInterfaceBuilt(false),
    \n-
    591 OwnerOverlapToAllInterfaceBuilt(false), OwnerCopyToAllInterfaceBuilt(false),
    \n-
    592 OwnerCopyToOwnerCopyInterfaceBuilt(false), CopyToAllInterfaceBuilt(false),
    \n-
    593 globalLookup_(0), category_(cat_), freecomm(freecomm_)
    \n-
    594 {
    \n-
    595 // set up an ISTL index set
    \n-
    596 pis.beginResize();
    \n-
    597 for (localindex_iterator i=indexinfo.localIndices().begin(); i!=indexinfo.localIndices().end(); ++i)
    \n-
    598 {
    \n-
    599 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
    \n-
    600 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::owner,true));
    \n-
    601 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
    \n-
    602 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::overlap,true));
    \n-
    603 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
    \n-
    604 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::copy,true));
    \n-
    605 // std::cout << cc.rank() << ": adding index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
    \n-
    606 }
    \n-
    607 pis.endResize();
    \n-
    608
    \n-
    609 // build remote indices WITHOUT communication
    \n-
    610 // std::cout << cc.rank() << ": build remote indices" << std::endl;
    \n-
    611 ri.setIndexSets(pis,pis,cc);
    \n-
    612 if (indexinfo.remoteIndices().size()>0)
    \n-
    613 {
    \n-
    614 remoteindex_iterator i=indexinfo.remoteIndices().begin();
    \n-
    615 int p = std::get<0>(*i);
    \n-
    616 RILM modifier = ri.template getModifier<false,true>(p);
    \n-
    617 typename PIS::const_iterator pi=pis.begin();
    \n-
    618 for ( ; i!=indexinfo.remoteIndices().end(); ++i)
    \n-
    619 {
    \n-
    620 // handle processor change
    \n-
    621 if (p!=std::get<0>(*i))
    \n-
    622 {
    \n-
    623 p = std::get<0>(*i);
    \n-
    624 modifier = ri.template getModifier<false,true>(p);
    \n-
    625 pi=pis.begin();
    \n-
    626 }
    \n-
    627
    \n-
    628 // position to correct entry in parallel index set
    \n-
    629 while (pi->global()!=std::get<1>(*i) && pi!=pis.end())
    \n-
    630 ++pi;
    \n-
    631 if (pi==pis.end())
    \n-
    632 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
    \n-
    633
    \n-
    634 // insert entry
    \n-
    635 // std::cout << cc.rank() << ": adding remote index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
    \n-
    636 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
    \n-
    637 modifier.insert(RX(OwnerOverlapCopyAttributeSet::owner,&(*pi)));
    \n-
    638 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
    \n-
    639 modifier.insert(RX(OwnerOverlapCopyAttributeSet::overlap,&(*pi)));
    \n-
    640 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
    \n-
    641 modifier.insert(RX(OwnerOverlapCopyAttributeSet::copy,&(*pi)));
    \n-
    642 }
    \n-
    643 }else{
    \n-
    644 // Force remote indices to be synced!
    \n-
    645 ri.template getModifier<false,true>(0);
    \n-
    646 }
    \n-
    647 }
    \n-
    648
    \n-
    649 // destructor: free memory in some objects
    \n-\n-
    651 {
    \n-
    652 ri.free();
    \n-
    653 if (OwnerToAllInterfaceBuilt) OwnerToAllInterface.free();
    \n-
    654 if (OwnerOverlapToAllInterfaceBuilt) OwnerOverlapToAllInterface.free();
    \n-
    655 if (OwnerCopyToAllInterfaceBuilt) OwnerCopyToAllInterface.free();
    \n-
    656 if (OwnerCopyToOwnerCopyInterfaceBuilt) OwnerCopyToOwnerCopyInterface.free();
    \n-
    657 if (CopyToAllInterfaceBuilt) CopyToAllInterface.free();
    \n-
    658 if (globalLookup_) delete globalLookup_;
    \n-
    659 if (freecomm==true)
    \n-
    660 if(comm!=MPI_COMM_NULL)
    \n-
    661 {
    \n-
    662#ifdef MPI_2
    \n-
    663 // If it is possible to query whether MPI_Finalize
    \n-
    664 // was called, only free the communicator before
    \n-
    665 // calling MPI_Finalize.
    \n-
    666 int wasFinalized = 0;
    \n-
    667 MPI_Finalized( &wasFinalized );
    \n-
    668 if(!wasFinalized)
    \n-
    669#endif
    \n-
    670 MPI_Comm_free(&comm);
    \n-
    671 }
    \n-
    672 }
    \n-
    673
    \n-
    674 private:
    \n-\n-
    676 {}
    \n-
    677 MPI_Comm comm;
    \n-
    678 Communication<MPI_Comm> cc;
    \n-
    679 PIS pis;
    \n-
    680 RI ri;
    \n-
    681 mutable IF OwnerToAllInterface;
    \n-
    682 mutable bool OwnerToAllInterfaceBuilt;
    \n-
    683 mutable IF OwnerOverlapToAllInterface;
    \n-
    684 mutable bool OwnerOverlapToAllInterfaceBuilt;
    \n-
    685 mutable IF OwnerCopyToAllInterface;
    \n-
    686 mutable bool OwnerCopyToAllInterfaceBuilt;
    \n-
    687 mutable IF OwnerCopyToOwnerCopyInterface;
    \n-
    688 mutable bool OwnerCopyToOwnerCopyInterfaceBuilt;
    \n-
    689 mutable IF CopyToAllInterface;
    \n-
    690 mutable bool CopyToAllInterfaceBuilt;
    \n-
    691 mutable std::vector<double> mask;
    \n-
    692 int oldseqNo;
    \n-
    693 GlobalLookupIndexSet* globalLookup_;
    \n-
    694 const SolverCategory::Category category_;
    \n-
    695 bool freecomm;
    \n-
    696 };
    \n-
    697
    \n-
    698#endif
    \n-
    699
    \n-
    700
    \n-
    703} // end namespace
    \n-
    704
    \n-
    705#endif
    \n-
    Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
    \n-\n-\n-
    void testRedistributed(int s)
    \n+
    203 static std::shared_ptr<Preconditioner> getPreconditioner(std::shared_ptr<Operator> op,
    \n+
    204 const ParameterTree& config){
    \n+
    205 const matrix_type* mat = getmat(op);
    \n+
    206 if(mat){
    \n+
    207 std::string prec_type = config.get<std::string>("type");
    \n+
    208 return PreconditionerFactory<Operator, Domain, Range>::instance().create(prec_type, op, config);
    \n+
    209 }else{
    \n+
    210 DUNE_THROW(InvalidStateException, "Could not obtain matrix from operator. Please pass in an AssembledLinearOperator.");
    \n+
    211 }
    \n+
    212 }
    \n+
    213 };
    \n+
    214
    \n+
    225 template<class Operator>
    \n+
    226 std::shared_ptr<InverseOperator<typename Operator::domain_type,
    \n+
    227 typename Operator::range_type>> getSolverFromFactory(std::shared_ptr<Operator> op,
    \n+
    228 const ParameterTree& config,
    \n+
    229 std::shared_ptr<Preconditioner<typename Operator::domain_type,
    \n+
    230 typename Operator::range_type>> prec = nullptr){
    \n+
    231 return SolverFactory<Operator>::get(op, config, prec);
    \n+
    232 }
    \n+
    233
    \n+
    237} // end namespace Dune
    \n+
    238
    \n+
    239
    \n+
    240#endif
    \n+\n+\n+
    Define general, extensible interface for inverse operators.
    \n+\n+
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n+
    Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > > PreconditionerFactory
    Definition: solverfactory.hh:36
    \n+
    Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > > DirectSolverFactory
    Definition: solverfactory.hh:30
    \n+
    std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr< LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &, const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &) IterativeSolverSignature
    Definition: solverfactory.hh:40
    \n+
    std::shared_ptr< Preconditioner > wrapPreconditioner4Parallel(const std::shared_ptr< Preconditioner > &prec, const O &)
    Definition: solverfactory.hh:86
    \n+
    std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &) DirectSolverSignature
    Definition: solverfactory.hh:28
    \n+
    std::shared_ptr< InverseOperator< typename Operator::domain_type, typename Operator::range_type > > getSolverFromFactory(std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > prec=nullptr)
    Instantiates an InverseOperator from an Operator and a configuration given as a ParameterTree.
    Definition: solverfactory.hh:227
    \n+
    Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > > IterativeSolverFactory
    Definition: solverfactory.hh:42
    \n+
    std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const ParameterTree &) PreconditionerSignature
    Definition: solverfactory.hh:34
    \n
    Definition: allocator.hh:11
    \n-
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    Attribute set for overlapping Schwarz.
    Definition: owneroverlapcopy.hh:59
    \n-
    AttributeSet
    Definition: owneroverlapcopy.hh:60
    \n-
    @ owner
    Definition: owneroverlapcopy.hh:61
    \n-
    @ copy
    Definition: owneroverlapcopy.hh:61
    \n-
    @ overlap
    Definition: owneroverlapcopy.hh:61
    \n-
    Information about the index distribution.
    Definition: owneroverlapcopy.hh:78
    \n-
    std::tuple< GlobalIdType, LocalIdType, int > IndexTripel
    A triple describing a local index.
    Definition: owneroverlapcopy.hh:92
    \n-
    void addRemoteIndex(const RemoteIndexTripel &x)
    Add a new remote index triple to the set of remote indices.
    Definition: owneroverlapcopy.hh:120
    \n-
    G GlobalIdType
    The type of the global index.
    Definition: owneroverlapcopy.hh:81
    \n-
    const std::set< IndexTripel > & localIndices() const
    Get the set of indices local to the process.
    Definition: owneroverlapcopy.hh:133
    \n-
    const std::set< RemoteIndexTripel > & remoteIndices() const
    Get the set of remote indices.
    Definition: owneroverlapcopy.hh:142
    \n-
    L LocalIdType
    The type of the local index.
    Definition: owneroverlapcopy.hh:84
    \n-
    void clear()
    Remove all indices from the sets.
    Definition: owneroverlapcopy.hh:150
    \n-
    void addLocalIndex(const IndexTripel &x)
    Add a new index triple to the set of local indices.
    Definition: owneroverlapcopy.hh:106
    \n-
    std::tuple< int, GlobalIdType, int > RemoteIndexTripel
    A triple describing a remote index.
    Definition: owneroverlapcopy.hh:99
    \n-
    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
    Definition: owneroverlapcopy.hh:174
    \n-
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopySet
    Definition: owneroverlapcopy.hh:195
    \n-
    const GlobalLookupIndexSet & globalLookup() const
    Definition: owneroverlapcopy.hh:526
    \n-
    FieldTraits< typenameT1::field_type >::real_type norm(const T1 &x) const
    Compute the global Euclidean norm of a vector.
    Definition: owneroverlapcopy.hh:425
    \n-
    void buildOwnerOverlapToAllInterface() const
    Definition: owneroverlapcopy.hh:233
    \n-
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > PIS
    Definition: owneroverlapcopy.hh:188
    \n-
    void buildOwnerCopyToAllInterface() const
    Definition: owneroverlapcopy.hh:254
    \n-
    void buildOwnerCopyToOwnerCopyInterface() const
    Definition: owneroverlapcopy.hh:266
    \n-
    OwnerOverlapCopyCommunication(const IndexInfoFromGrid< GlobalIdType, LocalIdType > &indexinfo, MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
    Constructor.
    Definition: owneroverlapcopy.hh:586
    \n-
    SolverCategory::Category category() const
    Get Solver Category.
    Definition: owneroverlapcopy.hh:295
    \n-
    void addOwnerCopyToOwnerCopy(const T &source, T &dest) const
    Communicate values from owner and copy data points to owner and copy data points and add them to thos...
    Definition: owneroverlapcopy.hh:379
    \n-
    void buildCopyToAllInterface() const
    Definition: owneroverlapcopy.hh:279
    \n-
    Dune::EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopyFlags
    Definition: owneroverlapcopy.hh:446
    \n-
    RemoteIndices & remoteIndices()
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:490
    \n-
    const ParallelIndexSet & indexSet() const
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:462
    \n-
    Dune::RemoteIndices< PIS > RI
    Definition: owneroverlapcopy.hh:189
    \n-
    void buildGlobalLookup(std::size_t size)
    Definition: owneroverlapcopy.hh:508
    \n-
    void addOwnerOverlapToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points and add them to those values.
    Definition: owneroverlapcopy.hh:345
    \n-
    Dune::RemoteIndices< PIS > RemoteIndices
    The type of the remote indices.
    Definition: owneroverlapcopy.hh:452
    \n-
    void project(T1 &x) const
    Set vector to zero at copy dofs.
    Definition: owneroverlapcopy.hh:538
    \n-
    Dune::AllSet< AttributeSet > AllSet
    Definition: owneroverlapcopy.hh:197
    \n-
    Combine< EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner >, EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::overlap >, AttributeSet > OwnerOverlapSet
    Definition: owneroverlapcopy.hh:196
    \n-
    void copyCopyToAll(const T &source, T &dest) const
    Communicate values from copy data points to all other data points.
    Definition: owneroverlapcopy.hh:328
    \n-
    Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
    The type of the reverse lookup of indices.
    Definition: owneroverlapcopy.hh:456
    \n-
    Dune::Interface IF
    Definition: owneroverlapcopy.hh:193
    \n-
    ~OwnerOverlapCopyCommunication()
    Definition: owneroverlapcopy.hh:650
    \n-
    void buildGlobalLookup()
    Definition: owneroverlapcopy.hh:495
    \n-
    Dune::BufferedCommunicator BC
    Definition: owneroverlapcopy.hh:192
    \n-
    OwnerOverlapCopyCommunication(MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
    Construct the communication without any indices.
    Definition: owneroverlapcopy.hh:554
    \n-
    ParallelIndexSet & indexSet()
    Get the underlying parallel index set.
    Definition: owneroverlapcopy.hh:480
    \n-
    void dot(const T1 &x, const T1 &y, T2 &result) const
    Compute a global dot product of two vectors.
    Definition: owneroverlapcopy.hh:398
    \n-
    const Communication< MPI_Comm > & communicator() const
    Definition: owneroverlapcopy.hh:299
    \n-
    OwnerOverlapCopyCommunication(SolverCategory::Category cat_=SolverCategory::overlapping)
    Construct the communication without any indices using MPI_COMM_WORLD.
    Definition: owneroverlapcopy.hh:572
    \n-
    EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet
    Definition: owneroverlapcopy.hh:194
    \n-
    void copyOwnerToAll(const T &source, T &dest) const
    Communicate values from owner data points to all other data points.
    Definition: owneroverlapcopy.hh:311
    \n-
    const RemoteIndices & remoteIndices() const
    Get the underlying remote indices.
    Definition: owneroverlapcopy.hh:471
    \n-
    friend void loadMatrixMarket(M &, const std::string &, OwnerOverlapCopyCommunication< G, L > &, bool)
    Load a parallel matrix/vector stored in matrix market format.
    Definition: matrixmarket.hh:1269
    \n-
    RI::RemoteIndex RX
    Definition: owneroverlapcopy.hh:191
    \n-
    void addOwnerCopyToAll(const T &source, T &dest) const
    Communicate values from owner and copy data points to all other data points and add them to those val...
    Definition: owneroverlapcopy.hh:362
    \n-
    void freeGlobalLookup()
    Definition: owneroverlapcopy.hh:520
    \n-
    Dune::RemoteIndexListModifier< PIS, typename RI::Allocator, false > RILM
    Definition: owneroverlapcopy.hh:190
    \n-
    Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
    The type of the parallel index set.
    Definition: owneroverlapcopy.hh:449
    \n-
    void buildOwnerToAllInterface() const
    Definition: owneroverlapcopy.hh:244
    \n-
    gather/scatter callback for communcation
    Definition: owneroverlapcopy.hh:204
    \n-
    static V gather(const T &a, std::size_t i)
    Definition: owneroverlapcopy.hh:207
    \n-
    static void scatter(T &a, V v, std::size_t i)
    Definition: owneroverlapcopy.hh:212
    \n-
    CommPolicy< T >::IndexedType V
    Definition: owneroverlapcopy.hh:205
    \n-\n-
    CommPolicy< T >::IndexedType V
    Definition: owneroverlapcopy.hh:220
    \n-
    static V gather(const T &a, std::size_t i)
    Definition: owneroverlapcopy.hh:222
    \n-
    static void scatter(T &a, V v, std::size_t i)
    Definition: owneroverlapcopy.hh:227
    \n-
    Category
    Definition: solvercategory.hh:23
    \n-
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n+
    std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm, SolverCategory::Category category)
    Definition: scalarproducts.hh:242
    \n+
    A nonoverlapping operator with communication object.
    Definition: novlpschwarz.hh:61
    \n+
    Adapter to turn a matrix into a linear operator.
    Definition: operators.hh:137
    \n+
    An overlapping Schwarz operator.
    Definition: schwarz.hh:75
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+\n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    Factory to assembly solvers configured by a ParameterTree.
    Definition: solverfactory.hh:145
    \n+
    static std::shared_ptr< Solver > get(std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner > prec=nullptr)
    get a solver from the factory
    Definition: solverfactory.hh:168
    \n+
    static std::shared_ptr< Preconditioner > getPreconditioner(std::shared_ptr< Operator > op, const ParameterTree &config)
    Construct a Preconditioner for a given Operator.
    Definition: solverfactory.hh:203
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,844 +4,308 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-owneroverlapcopy.hh\n+solverfactory.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_OWNEROVERLAPCOPY_HH\n- 6#define DUNE_ISTL_OWNEROVERLAPCOPY_HH\n- 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n+ 5\n+ 6#ifndef DUNE_ISTL_SOLVERFACTORY_HH\n+ 7#define DUNE_ISTL_SOLVERFACTORY_HH\n+ 8\n+ 9#include \n+ 10#include \n+ 11#include \n+ 12\n+ 13#include \n+ 14#include \n 15\n- 16#include \"cmath\"\n- 17\n- 18// MPI header\n- 19#if HAVE_MPI\n- 20#include \n- 21#endif\n- 22\n- 23#include \n- 24\n- 25#if HAVE_MPI\n- 26#include \n- 27#include \n- 28#include \n- 29#include \n- 30#endif\n+ 16#include \"solverregistry.hh\"\n+ 17#include \n+ 18#include \n+ 19#include \n+ 20\n+ 21namespace Dune{\n+ 26 // Direct solver factory:\n+ 27 template\n+28 using DirectSolverSignature = std::shared_ptr>(const\n+M&, const ParameterTree&);\n+ 29 template\n+30 using DirectSolverFactory =\n+Singleton>>;\n 31\n- 32#include \"solvercategory.hh\"\n- 33#include \"istlexception.hh\"\n- 34#include \n- 35#include \n- 36\n- 37template class Comm>\n-38void testRedistributed(int s);\n- 39\n- 40\n- 41namespace Dune {\n- 42\n-58 struct OwnerOverlapCopyAttributeSet\n- 59 {\n-60 enum AttributeSet {\n-61 owner=1, overlap=2, copy=3\n-62 };\n- 63 };\n- 64\n- 76 template \n-77 class IndexInfoFromGrid\n- 78 {\n- 79 public:\n-81 typedef G GlobalIdType;\n- 82\n-84 typedef L LocalIdType;\n- 85\n-92 typedef std::tuple IndexTripel;\n-99 typedef std::tuple RemoteIndexTripel;\n- 100\n-106 void addLocalIndex (const IndexTripel& x)\n- 107 {\n- 108 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&\n- 109 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&\n- 110 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)\n- 111 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n-index set\");\n- 112 localindices.insert(x);\n- 113 }\n- 114\n-120 void addRemoteIndex (const RemoteIndexTripel& x)\n+ 32 // Preconditioner factory:\n+ 33 template\n+34 using PreconditionerSignature = std::shared_ptr>(const\n+std::shared_ptr&, const ParameterTree&);\n+ 35 template\n+36 using PreconditionerFactory =\n+Singleton>>;\n+ 37\n+ 38 // Iterative solver factory\n+ 39 template\n+40 using IterativeSolverSignature = std::shared_ptr>(const\n+std::shared_ptr>&, const std::\n+shared_ptr>&, const std::shared_ptr>,\n+const ParameterTree&);\n+ 41 template\n+42 using IterativeSolverFactory =\n+Singleton>>;\n+ 43\n+ 44 // initSolverFactories differs in different compilation units, so we have\n+it\n+ 45 // in an anonymous namespace\n+ 46 namespace {\n+ 47\n+ 53 template\n+ 54 int initSolverFactories(){\n+ 55 using M = typename O::matrix_type;\n+ 56 using X = typename O::range_type;\n+ 57 using Y = typename O::domain_type;\n+ 58 using TL = Dune::TypeList;\n+ 59 auto& dsfac=Dune::DirectSolverFactory::instance();\n+ 60 addRegistryToFactory(dsfac, DirectSolverTag{});\n+ 61 auto& pfac=Dune::PreconditionerFactory::instance();\n+ 62 addRegistryToFactory(pfac, PreconditionerTag{});\n+ 63 using TLS = Dune::TypeList;\n+ 64 auto& isfac=Dune::IterativeSolverFactory::instance();\n+ 65 return addRegistryToFactory(isfac, IterativeSolverTag{});\n+ 66 }\n+ 77 template\n+ 78 [[deprecated(\"Use method 'initSolverFactories' instead\")]]\n+ 79 int initSolverFactories() {\n+ 80 return initSolverFactories();\n+ 81 }\n+ 82 } // end anonymous namespace\n+ 83\n+ 84\n+ 85 template\n+86 std::shared_ptr wrapPreconditioner4Parallel(const std::\n+shared_ptr& prec,\n+ 87 const O&)\n+ 88 {\n+ 89 return prec;\n+ 90 }\n+ 91\n+ 92 template\n+ 93 std::shared_ptr\n+94 wrapPreconditioner4Parallel(const std::shared_ptr& prec,\n+ 95 const std::shared_ptr >& op)\n+ 96 {\n+ 97 return std::make_shared >(prec,\n+op->getCommunication());\n+ 98 }\n+ 99\n+ 100 template\n+ 101 std::shared_ptr\n+102 wrapPreconditioner4Parallel(const std::shared_ptr& prec,\n+ 103 const std::shared_ptr >& op)\n+ 104 {\n+ 105 return std::\n+make_shared >(prec, op-\n+>getCommunication());\n+ 106 }\n+ 107\n+ 108 template\n+109 std::shared_ptr> createScalarProduct(const std::\n+shared_ptr >&)\n+ 110 {\n+ 111 return std::make_shared>();\n+ 112 }\n+ 113 template\n+114 std::shared_ptr> createScalarProduct(const std::\n+shared_ptr >& op)\n+ 115 {\n+ 116 return createScalarProduct(op->getCommunication(), op->category());\n+ 117 }\n+ 118\n+ 119 template\n+120 std::shared_ptr> createScalarProduct(const std::\n+shared_ptr >& op)\n 121 {\n- 122 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&\n- 123 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&\n- 124 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)\n- 125 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n-index set\");\n- 126 remoteindices.insert(x);\n- 127 }\n- 128\n-133 const std::set& localIndices () const\n- 134 {\n- 135 return localindices;\n- 136 }\n- 137\n-142 const std::set& remoteIndices () const\n- 143 {\n- 144 return remoteindices;\n- 145 }\n- 146\n-150 void clear ()\n- 151 {\n- 152 localindices.clear();\n- 153 remoteindices.clear();\n- 154 }\n+ 122 return createScalarProduct(op->getCommunication(), op->category());\n+ 123 }\n+ 124\n+ 144 template\n+145 class SolverFactory {\n+ 146 using Domain = typename Operator::domain_type;\n+ 147 using Range = typename Operator::range_type;\n+ 148 using Solver = Dune::InverseOperator;\n+ 149 using Preconditioner = Dune::Preconditioner;\n+ 150\n+ 151 template\n+ 152 using _matrix_type = typename O::matrix_type;\n+ 153 using matrix_type = Std::detected_or_t;\n+ 154 static constexpr bool isAssembled = !std::is_same::\n+value;\n 155\n- 156 private:\n- 158 std::set localindices;\n- 160 std::set remoteindices;\n- 161 };\n- 162\n+ 156 static const matrix_type* getmat(std::shared_ptr op){\n+ 157 std::shared_ptr> aop\n+ 158 = std::dynamic_pointer_cast>(op);\n+ 159 if(aop)\n+ 160 return &aop->getmat();\n+ 161 return nullptr;\n+ 162 }\n 163\n- 164#if HAVE_MPI\n+ 164 public:\n 165\n- 172 template \n-173 class OwnerOverlapCopyCommunication\n- 174 {\n- 175 template\n- 176 friend void loadMatrixMarket(M&,\n- 177 const std::string&,\n- 178 OwnerOverlapCopyCommunication&,\n- 179 bool);\n- 180 // used types\n- 181 typedef typename IndexInfoFromGrid::IndexTripel\n-IndexTripel;\n- 182 typedef typename IndexInfoFromGrid::\n-RemoteIndexTripel RemoteIndexTripel;\n- 183 typedef typename std::set::const_iterator\n-localindex_iterator;\n- 184 typedef typename std::set::const_iterator\n-remoteindex_iterator;\n- 185 typedef typename OwnerOverlapCopyAttributeSet::AttributeSet AttributeSet;\n- 186 typedef Dune::ParallelLocalIndex LI;\n- 187 public:\n-188 typedef Dune::ParallelIndexSet PIS;\n-189 typedef Dune::RemoteIndices RI;\n-190 typedef Dune::RemoteIndexListModifier\n-RILM;\n-191 typedef typename RI::RemoteIndex RX;\n-192 typedef Dune::BufferedCommunicator BC;\n-193 typedef Dune::Interface IF;\n-194 typedef EnumItem\n-OwnerSet;\n-195 typedef EnumItem CopySet;\n-196 typedef Combine,EnumItem,AttributeSet> OwnerOverlapSet;\n-197 typedef Dune::AllSet AllSet;\n- 198 protected:\n+168 static std::shared_ptr get(std::shared_ptr op,\n+ 169 const ParameterTree& config,\n+ 170 std::shared_ptr prec = nullptr){\n+ 171 std::string type = config.get(\"type\");\n+ 172 std::shared_ptr result;\n+ 173 const matrix_type* mat = getmat(op);\n+ 174 if(mat){\n+ 175 if (DirectSolverFactory::instance().contains\n+(type)) {\n+ 176 if(op->category()!=SolverCategory::sequential){\n+ 177 DUNE_THROW(NotImplemented, \"The solver factory does not support parallel\n+direct solvers!\");\n+ 178 }\n+ 179 result = DirectSolverFactory::instance\n+().create(type, *mat, config);\n+ 180 return result;\n+ 181 }\n+ 182 }\n+ 183 // if no direct solver is found it might be an iterative solver\n+ 184 if (!IterativeSolverFactory::instance().contains(type)) {\n+ 185 DUNE_THROW(Dune::InvalidStateException, \"Solver not found in the\n+factory.\");\n+ 186 }\n+ 187 if(!prec){\n+ 188 const ParameterTree& precConfig = config.sub(\"preconditioner\");\n+ 189 std::string prec_type = precConfig.get(\"type\");\n+ 190 prec = PreconditionerFactory::instance().create\n+(prec_type, op, precConfig);\n+ 191 if (prec->category() != op->category() && prec->category() ==\n+SolverCategory::sequential)\n+ 192 // try to wrap to a parallel preconditioner\n+ 193 prec = wrapPreconditioner4Parallel(prec, op);\n+ 194 }\n+ 195 std::shared_ptr> sp = createScalarProduct(op);\n+ 196 result = IterativeSolverFactory::instance().create(type,\n+op, sp, prec, config);\n+ 197 return result;\n+ 198 }\n 199\n- 200\n- 202 template\n-203 struct CopyGatherScatter\n- 204 {\n-205 typedef typename CommPolicy::IndexedType V;\n- 206\n-207 static V gather(const T& a, std::size_t i)\n- 208 {\n- 209 return a[i];\n- 210 }\n- 211\n-212 static void scatter(T& a, V v, std::size_t i)\n- 213 {\n- 214 a[i] = v;\n- 215 }\n- 216 };\n- 217 template\n-218 struct AddGatherScatter\n- 219 {\n-220 typedef typename CommPolicy::IndexedType V;\n- 221\n-222 static V gather(const T& a, std::size_t i)\n- 223 {\n- 224 return a[i];\n- 225 }\n- 226\n-227 static void scatter(T& a, V v, std::size_t i)\n- 228 {\n- 229 a[i] += v;\n- 230 }\n- 231 };\n- 232\n-233 void buildOwnerOverlapToAllInterface () const\n- 234 {\n- 235 if (OwnerOverlapToAllInterfaceBuilt)\n- 236 OwnerOverlapToAllInterface.free();\n- 237 OwnerOverlapSet sourceFlags;\n+203 static std::shared_ptr getPreconditioner(std::\n+shared_ptr op,\n+ 204 const ParameterTree& config){\n+ 205 const matrix_type* mat = getmat(op);\n+ 206 if(mat){\n+ 207 std::string prec_type = config.get(\"type\");\n+ 208 return PreconditionerFactory::instance().create\n+(prec_type, op, config);\n+ 209 }else{\n+ 210 DUNE_THROW(InvalidStateException, \"Could not obtain matrix from operator.\n+Please pass in an AssembledLinearOperator.\");\n+ 211 }\n+ 212 }\n+ 213 };\n+ 214\n+ 225 template\n+ 226 std::shared_ptr> getSolverFromFactory(std::\n+shared_ptr op,\n+ 228 const ParameterTree& config,\n+ 229 std::shared_ptr> prec = nullptr){\n+ 231 return SolverFactory::get(op, config, prec);\n+ 232 }\n+ 233\n+ 237} // end namespace Dune\n 238\n-Combine,AttributeSet>\n- 239 destFlags;\n- 240 OwnerOverlapToAllInterface.build(ri,sourceFlags,destFlags);\n- 241 OwnerOverlapToAllInterfaceBuilt = true;\n- 242 }\n- 243\n-244 void buildOwnerToAllInterface () const\n- 245 {\n- 246 if (OwnerToAllInterfaceBuilt)\n- 247 OwnerToAllInterface.free();\n- 248 OwnerSet sourceFlags;\n- 249 AllSet destFlags;\n- 250 OwnerToAllInterface.build(ri,sourceFlags,destFlags);\n- 251 OwnerToAllInterfaceBuilt = true;\n- 252 }\n- 253\n-254 void buildOwnerCopyToAllInterface () const\n- 255 {\n- 256 if (OwnerCopyToAllInterfaceBuilt)\n- 257 OwnerCopyToAllInterface.free();\n- 258\n- 259 typedef Combine,EnumItem,AttributeSet>\n-OwnerCopySet;\n- 260 OwnerCopySet sourceFlags;\n- 261 Combine,AttributeSet> destFlags;\n- 262 OwnerCopyToAllInterface.build(ri,sourceFlags,destFlags);\n- 263 OwnerCopyToAllInterfaceBuilt = true;\n- 264 }\n- 265\n-266 void buildOwnerCopyToOwnerCopyInterface () const\n- 267 {\n- 268 if (OwnerCopyToOwnerCopyInterfaceBuilt)\n- 269 OwnerCopyToOwnerCopyInterface.free();\n- 270\n- 271\n- 272 typedef Combine,EnumItem,AttributeSet>\n-OwnerCopySet;\n- 273 OwnerCopySet sourceFlags;\n- 274 OwnerCopySet destFlags;\n- 275 OwnerCopyToOwnerCopyInterface.build(ri,sourceFlags,destFlags);\n- 276 OwnerCopyToOwnerCopyInterfaceBuilt = true;\n- 277 }\n- 278\n-279 void buildCopyToAllInterface () const\n- 280 {\n- 281 if (CopyToAllInterfaceBuilt)\n- 282 CopyToAllInterface.free();\n- 283 CopySet sourceFlags;\n- 284 AllSet destFlags;\n- 285 CopyToAllInterface.build(ri,sourceFlags,destFlags);\n- 286 CopyToAllInterfaceBuilt = true;\n- 287 }\n- 288\n- 289 public:\n- 290\n-295 SolverCategory::Category category () const {\n- 296 return category_;\n- 297 }\n- 298\n-299 const Communication& communicator() const\n- 300 {\n- 301 return cc;\n- 302 }\n- 303\n- 310 template\n-311 void copyOwnerToAll (const T& source, T& dest) const\n- 312 {\n- 313 if (!OwnerToAllInterfaceBuilt)\n- 314 buildOwnerToAllInterface ();\n- 315 BC communicator;\n- 316 communicator.template build(OwnerToAllInterface);\n- 317 communicator.template forward >(source,dest);\n- 318 communicator.free();\n- 319 }\n- 320\n- 327 template\n-328 void copyCopyToAll (const T& source, T& dest) const\n- 329 {\n- 330 if (!CopyToAllInterfaceBuilt)\n- 331 buildCopyToAllInterface ();\n- 332 BC communicator;\n- 333 communicator.template build(CopyToAllInterface);\n- 334 communicator.template forward >(source,dest);\n- 335 communicator.free();\n- 336 }\n- 337\n- 344 template\n-345 void addOwnerOverlapToAll (const T& source, T& dest) const\n- 346 {\n- 347 if (!OwnerOverlapToAllInterfaceBuilt)\n- 348 buildOwnerOverlapToAllInterface ();\n- 349 BC communicator;\n- 350 communicator.template build(OwnerOverlapToAllInterface);\n- 351 communicator.template forward >(source,dest);\n- 352 communicator.free();\n- 353 }\n- 354\n- 361 template\n-362 void addOwnerCopyToAll (const T& source, T& dest) const\n- 363 {\n- 364 if (!OwnerCopyToAllInterfaceBuilt)\n- 365 buildOwnerCopyToAllInterface ();\n- 366 BC communicator;\n- 367 communicator.template build(OwnerCopyToAllInterface);\n- 368 communicator.template forward >(source,dest);\n- 369 communicator.free();\n- 370 }\n- 371\n- 378 template\n-379 void addOwnerCopyToOwnerCopy (const T& source, T& dest) const\n- 380 {\n- 381 if (!OwnerCopyToOwnerCopyInterfaceBuilt)\n- 382 buildOwnerCopyToOwnerCopyInterface ();\n- 383 BC communicator;\n- 384 communicator.template build(OwnerCopyToOwnerCopyInterface);\n- 385 communicator.template forward >(source,dest);\n- 386 communicator.free();\n- 387 }\n- 388\n- 389\n- 397 template\n-398 void dot (const T1& x, const T1& y, T2& result) const\n- 399 {\n- 400 using real_type = typename FieldTraits::\n-real_type;\n- 401 // set up mask vector\n- 402 if (mask.size()!=static_cast::size_type>\n-(x.size()))\n- 403 {\n- 404 mask.resize(x.size());\n- 405 for (typename std::vector::size_type i=0; ilocal().attribute()!=OwnerOverlapCopyAttributeSet::owner)\n- 409 mask[i->local().local()] = 0;\n- 410 }\n- 411 result = T2(0.0);\n- 412\n- 413 for (typename T1::size_type i=0; i(mask[i]);\n- 415 result = cc.sum(result);\n- 416 }\n- 417\n- 424 template\n-425 typename FieldTraits::real_type norm (const T1& x)\n-const\n- 426 {\n- 427 using real_type = typename FieldTraits::\n-real_type;\n- 428\n- 429 // set up mask vector\n- 430 if (mask.size()!=static_cast::size_type>\n-(x.size()))\n- 431 {\n- 432 mask.resize(x.size());\n- 433 for (typename std::vector::size_type i=0; ilocal().attribute()!=OwnerOverlapCopyAttributeSet::owner)\n- 437 mask[i->local().local()] = 0;\n- 438 }\n- 439 auto result = real_type(0.0);\n- 440 for (typename T1::size_type i=0; i\n-CopyFlags;\n- 447\n-449 typedef Dune::ParallelIndexSet ParallelIndexSet;\n- 450\n-452 typedef Dune::RemoteIndices RemoteIndices;\n- 453\n-456 typedef Dune::GlobalLookupIndexSet GlobalLookupIndexSet;\n- 457\n-462 const ParallelIndexSet& indexSet() const\n- 463 {\n- 464 return pis;\n- 465 }\n- 466\n-471 const RemoteIndices& remoteIndices() const\n- 472 {\n- 473 return ri;\n- 474 }\n- 475\n-480 ParallelIndexSet& indexSet()\n- 481 {\n- 482 return pis;\n- 483 }\n- 484\n- 485\n-490 RemoteIndices& remoteIndices()\n- 491 {\n- 492 return ri;\n- 493 }\n- 494\n-495 void buildGlobalLookup()\n- 496 {\n- 497 if(globalLookup_) {\n- 498 if(pis.seqNo()==oldseqNo)\n- 499 // Nothing changed!\n- 500 return;\n- 501 delete globalLookup_;\n- 502 }\n- 503\n- 504 globalLookup_ = new GlobalLookupIndexSet(pis);\n- 505 oldseqNo = pis.seqNo();\n- 506 }\n- 507\n-508 void buildGlobalLookup(std::size_t size)\n- 509 {\n- 510 if(globalLookup_) {\n- 511 if(pis.seqNo()==oldseqNo)\n- 512 // Nothing changed!\n- 513 return;\n- 514 delete globalLookup_;\n- 515 }\n- 516 globalLookup_ = new GlobalLookupIndexSet(pis, size);\n- 517 oldseqNo = pis.seqNo();\n- 518 }\n- 519\n-520 void freeGlobalLookup()\n- 521 {\n- 522 delete globalLookup_;\n- 523 globalLookup_=0;\n- 524 }\n- 525\n-526 const GlobalLookupIndexSet& globalLookup() const\n- 527 {\n- 528 assert(globalLookup_ != 0);\n- 529 return *globalLookup_;\n- 530 }\n- 531\n- 537 template\n-538 void project (T1& x) const\n- 539 {\n- 540 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)\n- 541 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)\n- 542 x[i->local().local()] = 0;\n- 543 }\n- 544\n-554 OwnerOverlapCopyCommunication (MPI_Comm comm_,\n- 555 SolverCategory::Category cat_ = SolverCategory::overlapping,\n- 556 bool freecomm_ = false)\n- 557 : comm(comm_), cc(comm_), pis(), ri(pis,pis,comm_),\n- 558 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),\n- 559 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt\n-(false),\n- 560 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),\n- 561 freecomm(freecomm_)\n- 562 {}\n- 563\n-572 OwnerOverlapCopyCommunication (SolverCategory::Category cat_ =\n-SolverCategory::overlapping)\n- 573 : comm(MPI_COMM_WORLD), cc(MPI_COMM_WORLD), pis(), ri\n-(pis,pis,MPI_COMM_WORLD),\n- 574 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),\n- 575 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt\n-(false),\n- 576 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),\n-freecomm(false)\n- 577 {}\n- 578\n-586 OwnerOverlapCopyCommunication (const IndexInfoFromGrid& indexinfo,\n- 587 MPI_Comm comm_,\n- 588 SolverCategory::Category cat_ = SolverCategory::overlapping,\n- 589 bool freecomm_ = false)\n- 590 : comm(comm_), cc(comm_), OwnerToAllInterfaceBuilt(false),\n- 591 OwnerOverlapToAllInterfaceBuilt(false), OwnerCopyToAllInterfaceBuilt\n-(false),\n- 592 OwnerCopyToOwnerCopyInterfaceBuilt(false), CopyToAllInterfaceBuilt(false),\n- 593 globalLookup_(0), category_(cat_), freecomm(freecomm_)\n- 594 {\n- 595 // set up an ISTL index set\n- 596 pis.beginResize();\n- 597 for (localindex_iterator i=indexinfo.localIndices().begin();\n-i!=indexinfo.localIndices().end(); ++i)\n- 598 {\n- 599 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)\n- 600 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n-owner,true));\n- 601 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)\n- 602 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n-overlap,true));\n- 603 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)\n- 604 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::\n-copy,true));\n- 605 // std::cout << cc.rank() << \": adding index \" << std::get<0>(*i) << \" \"\n-<< std::get<1>(*i) << \" \" << std::get<2>(*i) << std::endl;\n- 606 }\n- 607 pis.endResize();\n- 608\n- 609 // build remote indices WITHOUT communication\n- 610 // std::cout << cc.rank() << \": build remote indices\" << std::endl;\n- 611 ri.setIndexSets(pis,pis,cc);\n- 612 if (indexinfo.remoteIndices().size()>0)\n- 613 {\n- 614 remoteindex_iterator i=indexinfo.remoteIndices().begin();\n- 615 int p = std::get<0>(*i);\n- 616 RILM modifier = ri.template getModifier(p);\n- 617 typename PIS::const_iterator pi=pis.begin();\n- 618 for ( ; i!=indexinfo.remoteIndices().end(); ++i)\n- 619 {\n- 620 // handle processor change\n- 621 if (p!=std::get<0>(*i))\n- 622 {\n- 623 p = std::get<0>(*i);\n- 624 modifier = ri.template getModifier(p);\n- 625 pi=pis.begin();\n- 626 }\n- 627\n- 628 // position to correct entry in parallel index set\n- 629 while (pi->global()!=std::get<1>(*i) && pi!=pis.end())\n- 630 ++pi;\n- 631 if (pi==pis.end())\n- 632 DUNE_THROW(ISTLError,\"OwnerOverlapCopyCommunication: global index not in\n-index set\");\n- 633\n- 634 // insert entry\n- 635 // std::cout << cc.rank() << \": adding remote index \" << std::get<0>(*i)\n-<< \" \" << std::get<1>(*i) << \" \" << std::get<2>(*i) << std::endl;\n- 636 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)\n- 637 modifier.insert(RX(OwnerOverlapCopyAttributeSet::owner,&(*pi)));\n- 638 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)\n- 639 modifier.insert(RX(OwnerOverlapCopyAttributeSet::overlap,&(*pi)));\n- 640 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)\n- 641 modifier.insert(RX(OwnerOverlapCopyAttributeSet::copy,&(*pi)));\n- 642 }\n- 643 }else{\n- 644 // Force remote indices to be synced!\n- 645 ri.template getModifier(0);\n- 646 }\n- 647 }\n- 648\n- 649 // destructor: free memory in some objects\n-650 ~OwnerOverlapCopyCommunication ()\n- 651 {\n- 652 ri.free();\n- 653 if (OwnerToAllInterfaceBuilt) OwnerToAllInterface.free();\n- 654 if (OwnerOverlapToAllInterfaceBuilt) OwnerOverlapToAllInterface.free();\n- 655 if (OwnerCopyToAllInterfaceBuilt) OwnerCopyToAllInterface.free();\n- 656 if (OwnerCopyToOwnerCopyInterfaceBuilt) OwnerCopyToOwnerCopyInterface.free\n-();\n- 657 if (CopyToAllInterfaceBuilt) CopyToAllInterface.free();\n- 658 if (globalLookup_) delete globalLookup_;\n- 659 if (freecomm==true)\n- 660 if(comm!=MPI_COMM_NULL)\n- 661 {\n- 662#ifdef MPI_2\n- 663 // If it is possible to query whether MPI_Finalize\n- 664 // was called, only free the communicator before\n- 665 // calling MPI_Finalize.\n- 666 int wasFinalized = 0;\n- 667 MPI_Finalized( &wasFinalized );\n- 668 if(!wasFinalized)\n- 669#endif\n- 670 MPI_Comm_free(&comm);\n- 671 }\n- 672 }\n- 673\n- 674 private:\n- 675 OwnerOverlapCopyCommunication (const OwnerOverlapCopyCommunication&)\n- 676 {}\n- 677 MPI_Comm comm;\n- 678 Communication cc;\n- 679 PIS pis;\n- 680 RI ri;\n- 681 mutable IF OwnerToAllInterface;\n- 682 mutable bool OwnerToAllInterfaceBuilt;\n- 683 mutable IF OwnerOverlapToAllInterface;\n- 684 mutable bool OwnerOverlapToAllInterfaceBuilt;\n- 685 mutable IF OwnerCopyToAllInterface;\n- 686 mutable bool OwnerCopyToAllInterfaceBuilt;\n- 687 mutable IF OwnerCopyToOwnerCopyInterface;\n- 688 mutable bool OwnerCopyToOwnerCopyInterfaceBuilt;\n- 689 mutable IF CopyToAllInterface;\n- 690 mutable bool CopyToAllInterfaceBuilt;\n- 691 mutable std::vector mask;\n- 692 int oldseqNo;\n- 693 GlobalLookupIndexSet* globalLookup_;\n- 694 const SolverCategory::Category category_;\n- 695 bool freecomm;\n- 696 };\n- 697\n- 698#endif\n- 699\n- 700\n- 703} // end namespace\n- 704\n- 705#endif\n-matrixmarket.hh\n-Provides classes for reading and writing MatrixMarket Files with an extension\n-for parallel matrices.\n-istlexception.hh\n-solvercategory.hh\n-testRedistributed\n-void testRedistributed(int s)\n+ 239\n+ 240#endif\n+solverregistry.hh\n+novlpschwarz.hh\n+solver.hh\n+Define general, extensible interface for inverse operators.\n+schwarz.hh\n+mat\n+Matrix & mat\n+Definition: matrixmatrix.hh:347\n+Dune::PreconditionerFactory\n+Singleton< ParameterizedObjectFactory< PreconditionerSignature< M, X, Y > > >\n+PreconditionerFactory\n+Definition: solverfactory.hh:36\n+Dune::DirectSolverFactory\n+Singleton< ParameterizedObjectFactory< DirectSolverSignature< M, X, Y > > >\n+DirectSolverFactory\n+Definition: solverfactory.hh:30\n+Dune::IterativeSolverSignature\n+std::shared_ptr< InverseOperator< X, Y > >(const std::shared_ptr<\n+LinearOperator< X, Y > > &, const std::shared_ptr< ScalarProduct< X > > &,\n+const std::shared_ptr< Preconditioner< X, Y > >, const ParameterTree &)\n+IterativeSolverSignature\n+Definition: solverfactory.hh:40\n+Dune::wrapPreconditioner4Parallel\n+std::shared_ptr< Preconditioner > wrapPreconditioner4Parallel(const std::\n+shared_ptr< Preconditioner > &prec, const O &)\n+Definition: solverfactory.hh:86\n+Dune::DirectSolverSignature\n+std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &)\n+DirectSolverSignature\n+Definition: solverfactory.hh:28\n+Dune::getSolverFromFactory\n+std::shared_ptr< InverseOperator< typename Operator::domain_type, typename\n+Operator::range_type > > getSolverFromFactory(std::shared_ptr< Operator > op,\n+const ParameterTree &config, std::shared_ptr< Preconditioner< typename\n+Operator::domain_type, typename Operator::range_type > > prec=nullptr)\n+Instantiates an InverseOperator from an Operator and a configuration given as a\n+ParameterTree.\n+Definition: solverfactory.hh:227\n+Dune::IterativeSolverFactory\n+Singleton< ParameterizedObjectFactory< IterativeSolverSignature< X, Y > > >\n+IterativeSolverFactory\n+Definition: solverfactory.hh:42\n+Dune::PreconditionerSignature\n+std::shared_ptr< Preconditioner< X, Y > >(const std::shared_ptr< M > &, const\n+ParameterTree &) PreconditionerSignature\n+Definition: solverfactory.hh:34\n Dune\n Definition: allocator.hh:11\n-Dune::ISTLError\n-derive error class from the base class in common\n-Definition: istlexception.hh:19\n-Dune::OwnerOverlapCopyAttributeSet\n-Attribute set for overlapping Schwarz.\n-Definition: owneroverlapcopy.hh:59\n-Dune::OwnerOverlapCopyAttributeSet::AttributeSet\n-AttributeSet\n-Definition: owneroverlapcopy.hh:60\n-Dune::OwnerOverlapCopyAttributeSet::owner\n-@ owner\n-Definition: owneroverlapcopy.hh:61\n-Dune::OwnerOverlapCopyAttributeSet::copy\n-@ copy\n-Definition: owneroverlapcopy.hh:61\n-Dune::OwnerOverlapCopyAttributeSet::overlap\n-@ overlap\n-Definition: owneroverlapcopy.hh:61\n-Dune::IndexInfoFromGrid\n-Information about the index distribution.\n-Definition: owneroverlapcopy.hh:78\n-Dune::IndexInfoFromGrid::IndexTripel\n-std::tuple< GlobalIdType, LocalIdType, int > IndexTripel\n-A triple describing a local index.\n-Definition: owneroverlapcopy.hh:92\n-Dune::IndexInfoFromGrid::addRemoteIndex\n-void addRemoteIndex(const RemoteIndexTripel &x)\n-Add a new remote index triple to the set of remote indices.\n-Definition: owneroverlapcopy.hh:120\n-Dune::IndexInfoFromGrid::GlobalIdType\n-G GlobalIdType\n-The type of the global index.\n-Definition: owneroverlapcopy.hh:81\n-Dune::IndexInfoFromGrid::localIndices\n-const std::set< IndexTripel > & localIndices() const\n-Get the set of indices local to the process.\n-Definition: owneroverlapcopy.hh:133\n-Dune::IndexInfoFromGrid::remoteIndices\n-const std::set< RemoteIndexTripel > & remoteIndices() const\n-Get the set of remote indices.\n-Definition: owneroverlapcopy.hh:142\n-Dune::IndexInfoFromGrid::LocalIdType\n-L LocalIdType\n-The type of the local index.\n-Definition: owneroverlapcopy.hh:84\n-Dune::IndexInfoFromGrid::clear\n-void clear()\n-Remove all indices from the sets.\n-Definition: owneroverlapcopy.hh:150\n-Dune::IndexInfoFromGrid::addLocalIndex\n-void addLocalIndex(const IndexTripel &x)\n-Add a new index triple to the set of local indices.\n-Definition: owneroverlapcopy.hh:106\n-Dune::IndexInfoFromGrid::RemoteIndexTripel\n-std::tuple< int, GlobalIdType, int > RemoteIndexTripel\n-A triple describing a remote index.\n-Definition: owneroverlapcopy.hh:99\n-Dune::OwnerOverlapCopyCommunication\n-A class setting up standard communication for a two-valued attribute set with\n-owner/overlap/copy sema...\n-Definition: owneroverlapcopy.hh:174\n-Dune::OwnerOverlapCopyCommunication::CopySet\n-EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopySet\n-Definition: owneroverlapcopy.hh:195\n-Dune::OwnerOverlapCopyCommunication::globalLookup\n-const GlobalLookupIndexSet & globalLookup() const\n-Definition: owneroverlapcopy.hh:526\n-Dune::OwnerOverlapCopyCommunication::norm\n-FieldTraits< typenameT1::field_type >::real_type norm(const T1 &x) const\n-Compute the global Euclidean norm of a vector.\n-Definition: owneroverlapcopy.hh:425\n-Dune::OwnerOverlapCopyCommunication::buildOwnerOverlapToAllInterface\n-void buildOwnerOverlapToAllInterface() const\n-Definition: owneroverlapcopy.hh:233\n-Dune::OwnerOverlapCopyCommunication::PIS\n-Dune::ParallelIndexSet< GlobalIdType, LI, 512 > PIS\n-Definition: owneroverlapcopy.hh:188\n-Dune::OwnerOverlapCopyCommunication::buildOwnerCopyToAllInterface\n-void buildOwnerCopyToAllInterface() const\n-Definition: owneroverlapcopy.hh:254\n-Dune::OwnerOverlapCopyCommunication::buildOwnerCopyToOwnerCopyInterface\n-void buildOwnerCopyToOwnerCopyInterface() const\n-Definition: owneroverlapcopy.hh:266\n-Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n-OwnerOverlapCopyCommunication(const IndexInfoFromGrid< GlobalIdType,\n-LocalIdType > &indexinfo, MPI_Comm comm_, SolverCategory::Category\n-cat_=SolverCategory::overlapping, bool freecomm_=false)\n-Constructor.\n-Definition: owneroverlapcopy.hh:586\n-Dune::OwnerOverlapCopyCommunication::category\n-SolverCategory::Category category() const\n-Get Solver Category.\n-Definition: owneroverlapcopy.hh:295\n-Dune::OwnerOverlapCopyCommunication::addOwnerCopyToOwnerCopy\n-void addOwnerCopyToOwnerCopy(const T &source, T &dest) const\n-Communicate values from owner and copy data points to owner and copy data\n-points and add them to thos...\n-Definition: owneroverlapcopy.hh:379\n-Dune::OwnerOverlapCopyCommunication::buildCopyToAllInterface\n-void buildCopyToAllInterface() const\n-Definition: owneroverlapcopy.hh:279\n-Dune::OwnerOverlapCopyCommunication::CopyFlags\n-Dune::EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::copy > CopyFlags\n-Definition: owneroverlapcopy.hh:446\n-Dune::OwnerOverlapCopyCommunication::remoteIndices\n-RemoteIndices & remoteIndices()\n-Get the underlying remote indices.\n-Definition: owneroverlapcopy.hh:490\n-Dune::OwnerOverlapCopyCommunication::indexSet\n-const ParallelIndexSet & indexSet() const\n-Get the underlying parallel index set.\n-Definition: owneroverlapcopy.hh:462\n-Dune::OwnerOverlapCopyCommunication::RI\n-Dune::RemoteIndices< PIS > RI\n-Definition: owneroverlapcopy.hh:189\n-Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n-void buildGlobalLookup(std::size_t size)\n-Definition: owneroverlapcopy.hh:508\n-Dune::OwnerOverlapCopyCommunication::addOwnerOverlapToAll\n-void addOwnerOverlapToAll(const T &source, T &dest) const\n-Communicate values from owner data points to all other data points and add them\n-to those values.\n-Definition: owneroverlapcopy.hh:345\n-Dune::OwnerOverlapCopyCommunication::RemoteIndices\n-Dune::RemoteIndices< PIS > RemoteIndices\n-The type of the remote indices.\n-Definition: owneroverlapcopy.hh:452\n-Dune::OwnerOverlapCopyCommunication::project\n-void project(T1 &x) const\n-Set vector to zero at copy dofs.\n-Definition: owneroverlapcopy.hh:538\n-Dune::OwnerOverlapCopyCommunication::AllSet\n-Dune::AllSet< AttributeSet > AllSet\n-Definition: owneroverlapcopy.hh:197\n-Dune::OwnerOverlapCopyCommunication::OwnerOverlapSet\n-Combine< EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner >,\n-EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::overlap >, AttributeSet >\n-OwnerOverlapSet\n-Definition: owneroverlapcopy.hh:196\n-Dune::OwnerOverlapCopyCommunication::copyCopyToAll\n-void copyCopyToAll(const T &source, T &dest) const\n-Communicate values from copy data points to all other data points.\n-Definition: owneroverlapcopy.hh:328\n-Dune::OwnerOverlapCopyCommunication::GlobalLookupIndexSet\n-Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet\n-The type of the reverse lookup of indices.\n-Definition: owneroverlapcopy.hh:456\n-Dune::OwnerOverlapCopyCommunication::IF\n-Dune::Interface IF\n-Definition: owneroverlapcopy.hh:193\n-Dune::OwnerOverlapCopyCommunication::~OwnerOverlapCopyCommunication\n-~OwnerOverlapCopyCommunication()\n-Definition: owneroverlapcopy.hh:650\n-Dune::OwnerOverlapCopyCommunication::buildGlobalLookup\n-void buildGlobalLookup()\n-Definition: owneroverlapcopy.hh:495\n-Dune::OwnerOverlapCopyCommunication::BC\n-Dune::BufferedCommunicator BC\n-Definition: owneroverlapcopy.hh:192\n-Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n-OwnerOverlapCopyCommunication(MPI_Comm comm_, SolverCategory::Category\n-cat_=SolverCategory::overlapping, bool freecomm_=false)\n-Construct the communication without any indices.\n-Definition: owneroverlapcopy.hh:554\n-Dune::OwnerOverlapCopyCommunication::indexSet\n-ParallelIndexSet & indexSet()\n-Get the underlying parallel index set.\n-Definition: owneroverlapcopy.hh:480\n-Dune::OwnerOverlapCopyCommunication::dot\n-void dot(const T1 &x, const T1 &y, T2 &result) const\n-Compute a global dot product of two vectors.\n-Definition: owneroverlapcopy.hh:398\n-Dune::OwnerOverlapCopyCommunication::communicator\n-const Communication< MPI_Comm > & communicator() const\n-Definition: owneroverlapcopy.hh:299\n-Dune::OwnerOverlapCopyCommunication::OwnerOverlapCopyCommunication\n-OwnerOverlapCopyCommunication(SolverCategory::Category cat_=SolverCategory::\n-overlapping)\n-Construct the communication without any indices using MPI_COMM_WORLD.\n-Definition: owneroverlapcopy.hh:572\n-Dune::OwnerOverlapCopyCommunication::OwnerSet\n-EnumItem< AttributeSet, OwnerOverlapCopyAttributeSet::owner > OwnerSet\n-Definition: owneroverlapcopy.hh:194\n-Dune::OwnerOverlapCopyCommunication::copyOwnerToAll\n-void copyOwnerToAll(const T &source, T &dest) const\n-Communicate values from owner data points to all other data points.\n-Definition: owneroverlapcopy.hh:311\n-Dune::OwnerOverlapCopyCommunication::remoteIndices\n-const RemoteIndices & remoteIndices() const\n-Get the underlying remote indices.\n-Definition: owneroverlapcopy.hh:471\n-Dune::OwnerOverlapCopyCommunication::loadMatrixMarket\n-friend void loadMatrixMarket(M &, const std::string &,\n-OwnerOverlapCopyCommunication< G, L > &, bool)\n-Load a parallel matrix/vector stored in matrix market format.\n-Definition: matrixmarket.hh:1269\n-Dune::OwnerOverlapCopyCommunication::RX\n-RI::RemoteIndex RX\n-Definition: owneroverlapcopy.hh:191\n-Dune::OwnerOverlapCopyCommunication::addOwnerCopyToAll\n-void addOwnerCopyToAll(const T &source, T &dest) const\n-Communicate values from owner and copy data points to all other data points and\n-add them to those val...\n-Definition: owneroverlapcopy.hh:362\n-Dune::OwnerOverlapCopyCommunication::freeGlobalLookup\n-void freeGlobalLookup()\n-Definition: owneroverlapcopy.hh:520\n-Dune::OwnerOverlapCopyCommunication::RILM\n-Dune::RemoteIndexListModifier< PIS, typename RI::Allocator, false > RILM\n-Definition: owneroverlapcopy.hh:190\n-Dune::OwnerOverlapCopyCommunication::ParallelIndexSet\n-Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet\n-The type of the parallel index set.\n-Definition: owneroverlapcopy.hh:449\n-Dune::OwnerOverlapCopyCommunication::buildOwnerToAllInterface\n-void buildOwnerToAllInterface() const\n-Definition: owneroverlapcopy.hh:244\n-Dune::OwnerOverlapCopyCommunication::CopyGatherScatter\n-gather/scatter callback for communcation\n-Definition: owneroverlapcopy.hh:204\n-Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::gather\n-static V gather(const T &a, std::size_t i)\n-Definition: owneroverlapcopy.hh:207\n-Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::scatter\n-static void scatter(T &a, V v, std::size_t i)\n-Definition: owneroverlapcopy.hh:212\n-Dune::OwnerOverlapCopyCommunication::CopyGatherScatter::V\n-CommPolicy< T >::IndexedType V\n-Definition: owneroverlapcopy.hh:205\n-Dune::OwnerOverlapCopyCommunication::AddGatherScatter\n-Definition: owneroverlapcopy.hh:219\n-Dune::OwnerOverlapCopyCommunication::AddGatherScatter::V\n-CommPolicy< T >::IndexedType V\n-Definition: owneroverlapcopy.hh:220\n-Dune::OwnerOverlapCopyCommunication::AddGatherScatter::gather\n-static V gather(const T &a, std::size_t i)\n-Definition: owneroverlapcopy.hh:222\n-Dune::OwnerOverlapCopyCommunication::AddGatherScatter::scatter\n-static void scatter(T &a, V v, std::size_t i)\n-Definition: owneroverlapcopy.hh:227\n-Dune::SolverCategory::Category\n-Category\n-Definition: solvercategory.hh:23\n-Dune::SolverCategory::overlapping\n-@ overlapping\n-Category for overlapping solvers.\n-Definition: solvercategory.hh:29\n+Dune::createScalarProduct\n+std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm,\n+SolverCategory::Category category)\n+Definition: scalarproducts.hh:242\n+Dune::NonoverlappingSchwarzOperator\n+A nonoverlapping operator with communication object.\n+Definition: novlpschwarz.hh:61\n+Dune::MatrixAdapter\n+Adapter to turn a matrix into a linear operator.\n+Definition: operators.hh:137\n+Dune::OverlappingSchwarzOperator\n+An overlapping Schwarz operator.\n+Definition: schwarz.hh:75\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::InverseOperator<_Domain,_Range_>\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n+Dune::SolverFactory\n+Factory to assembly solvers configured by a ParameterTree.\n+Definition: solverfactory.hh:145\n+Dune::SolverFactory::get\n+static std::shared_ptr< Solver > get(std::shared_ptr< Operator > op, const\n+ParameterTree &config, std::shared_ptr< Preconditioner > prec=nullptr)\n+get a solver from the factory\n+Definition: solverfactory.hh:168\n+Dune::SolverFactory::getPreconditioner\n+static std::shared_ptr< Preconditioner > getPreconditioner(std::shared_ptr<\n+Operator > op, const ParameterTree &config)\n+Construct a Preconditioner for a given Operator.\n+Definition: solverfactory.hh:203\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00218.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00218.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: vbvector.hh File Reference\n+dune-istl: ilu.hh File Reference\n \n \n \n \n \n \n \n@@ -64,52 +64,79 @@\n \n \n \n
    \n \n-
    vbvector.hh File Reference
    \n+Namespaces |\n+Functions
    \n+
    ilu.hh File Reference
    \n \n
    \n \n-

    ??? \n+

    The incomplete LU factorization kernels. \n More...

    \n
    #include <cmath>
    \n #include <complex>
    \n-#include <iostream>
    \n-#include <iterator>
    \n-#include <memory>
    \n-#include <dune/common/iteratorfacades.hh>
    \n-#include "istlexception.hh"
    \n-#include "bvector.hh"
    \n-#include <dune/istl/blocklevel.hh>
    \n+#include <map>
    \n+#include <vector>
    \n+#include <dune/common/fmatrix.hh>
    \n+#include <dune/common/scalarvectorview.hh>
    \n+#include <dune/common/scalarmatrixview.hh>
    \n+#include "istlexception.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n

    \n Classes

    class  Dune::VariableBlockVector< B, A >
     A Vector of blocks with different blocksizes. More...
     
    class  Dune::VariableBlockVector< B, A >::CreateIterator
     Iterator class for sequential creation of blocks. More...
     
    class  Dune::VariableBlockVector< B, A >::RealIterator< T, R >
     Iterator class for sequential access. More...
    struct  Dune::ILU::CRS< B, Alloc >
     a simple compressed row storage matrix class More...
     
    \n \n \n \n+\n+\n+

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::ILU
     
    \n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n+Functions

    template<class M >
    void Dune::ILU::blockILU0Decomposition (M &A)
     compute ILU decomposition of A. A is overwritten by its decomposition More...
     
    template<class M , class X , class Y >
    void Dune::ILU::blockILUBacksolve (const M &A, X &v, const Y &d)
     LU backsolve with stored inverse. More...
     
    template<class M >
    M::field_type & Dune::ILU::firstMatrixElement (M &A, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
     
    template<class K >
    K & Dune::ILU::firstMatrixElement (K &A, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
     
    template<class K , int n, int m>
    K & Dune::ILU::firstMatrixElement (FieldMatrix< K, n, m > &A)
     
    template<class M >
    void Dune::ILU::blockILUDecomposition (const M &A, int n, M &ILU)
     
    template<class M , class CRS , class InvVector >
    void Dune::ILU::convertToCRS (const M &A, CRS &lower, CRS &upper, InvVector &inv)
     convert ILU decomposition into CRS format for lower and upper triangular and inverse. More...
     
    template<class CRS , class InvVector , class X , class Y >
    void Dune::ILU::blockILUBacksolve (const CRS &lower, const CRS &upper, const InvVector &inv, X &v, const Y &d)
     LU backsolve with stored inverse in CRS format for lower and upper triangular. More...
     
    \n

    Detailed Description

    \n-

    ???

    \n+

    The incomplete LU factorization kernels.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,38 +4,69 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces\n-vbvector.hh File Reference\n-??? More...\n+Classes | Namespaces | Functions\n+ilu.hh File Reference\n+The incomplete LU factorization kernels. More...\n #include \n #include \n-#include \n-#include \n-#include \n-#include \n+#include \n+#include \n+#include \n+#include \n+#include \n #include \"istlexception.hh\"\n-#include \"bvector.hh\"\n-#include \n Go_to_the_source_code_of_this_file.\n Classes\n-class \u00a0Dune::VariableBlockVector<_B,_A_>\n-\u00a0 A Vector of blocks with different blocksizes. More...\n-\u00a0\n-class \u00a0Dune::VariableBlockVector<_B,_A_>::CreateIterator\n-\u00a0 Iterator class for sequential creation of blocks. More...\n-\u00a0\n-class \u00a0Dune::VariableBlockVector<_B,_A_>::RealIterator<_T,_R_>\n-\u00a0 Iterator class for sequential access. More...\n+struct \u00a0Dune::ILU::CRS<_B,_Alloc_>\n+\u00a0 a simple compressed row storage matrix class More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+namespace \u00a0Dune::ILU\n+\u00a0\n+ Functions\n+template\n+ void\u00a0Dune::ILU::blockILU0Decomposition (M &A)\n+\u00a0 compute ILU decomposition of A. A is overwritten by its\n+ decomposition More...\n+\u00a0\n+template\n+ void\u00a0Dune::ILU::blockILUBacksolve (const M &A, X &v, const Y &d)\n+\u00a0 LU backsolve with stored inverse. More...\n+\u00a0\n+template\n+M::field_type &\u00a0Dune::ILU::firstMatrixElement (M &A, typename std::\n+ enable_if_t::value > *sfinae=nullptr)\n+\u00a0\n+template\n+ K &\u00a0Dune::ILU::firstMatrixElement (K &A, typename std::\n+ enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n+\u00a0\n+template\n+ K &\u00a0Dune::ILU::firstMatrixElement (FieldMatrix< K, n, m > &A)\n+\u00a0\n+template\n+ void\u00a0Dune::ILU::blockILUDecomposition (const M &A, int n, M &ILU)\n+\u00a0\n+template\n+ void\u00a0Dune::ILU::convertToCRS (const M &A, CRS &lower, CRS &upper,\n+ InvVector &inv)\n+\u00a0 convert ILU decomposition into CRS format for lower and upper\n+ triangular and inverse. More...\n+\u00a0\n+template\n+ void\u00a0Dune::ILU::blockILUBacksolve (const CRS &lower, const CRS\n+ &upper, const InvVector &inv, X &v, const Y &d)\n+\u00a0 LU backsolve with stored inverse in CRS format for lower and\n+ upper triangular. More...\n+\u00a0\n ***** Detailed Description *****\n-???\n+The incomplete LU factorization kernels.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00218_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00218_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: vbvector.hh Source File\n+dune-istl: ilu.hh Source File\n \n \n \n \n \n \n \n@@ -62,760 +62,448 @@\n \n
    \n \n
    \n
    \n
    \n-
    vbvector.hh
    \n+
    ilu.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_VBVECTOR_HH
    \n-
    6#define DUNE_ISTL_VBVECTOR_HH
    \n+
    5#ifndef DUNE_ISTL_ILU_HH
    \n+
    6#define DUNE_ISTL_ILU_HH
    \n
    7
    \n
    8#include <cmath>
    \n
    9#include <complex>
    \n-
    10#include <iostream>
    \n-
    11#include <iterator>
    \n-
    12#include <memory>
    \n-
    13
    \n-
    14#include <dune/common/iteratorfacades.hh>
    \n-
    15#include "istlexception.hh"
    \n-
    16#include "bvector.hh"
    \n-
    17
    \n-\n-
    19
    \n-
    24namespace Dune {
    \n-
    25
    \n-
    41 template<class B, class A=std::allocator<B> >
    \n-
    42 class VariableBlockVector : public Imp::block_vector_unmanaged<B,A>
    \n-
    43 // this derivation gives us all the blas level 1 and norms
    \n-
    44 // on the large array. However, access operators have to be
    \n-
    45 // overwritten.
    \n-
    46 {
    \n-
    47 // just a shorthand
    \n-
    48 typedef Imp::BlockVectorWindow<B,A> window_type;
    \n-
    49
    \n-
    50 public:
    \n-
    51
    \n-
    52 //===== type definitions and constants
    \n+
    10#include <map>
    \n+
    11#include <vector>
    \n+
    12
    \n+
    13#include <dune/common/fmatrix.hh>
    \n+
    14#include <dune/common/scalarvectorview.hh>
    \n+
    15#include <dune/common/scalarmatrixview.hh>
    \n+
    16
    \n+
    17#include "istlexception.hh"
    \n+
    18
    \n+
    23namespace Dune {
    \n+
    24
    \n+
    29 namespace ILU {
    \n+
    30
    \n+
    32 template<class M>
    \n+\n+
    34 {
    \n+
    35 // iterator types
    \n+
    36 typedef typename M::RowIterator rowiterator;
    \n+
    37 typedef typename M::ColIterator coliterator;
    \n+
    38 typedef typename M::block_type block;
    \n+
    39
    \n+
    40 // implement left looking variant with stored inverse
    \n+
    41 rowiterator endi=A.end();
    \n+
    42 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    43 {
    \n+
    44 // coliterator is diagonal after the following loop
    \n+
    45 coliterator endij=(*i).end(); // end of row i
    \n+
    46 coliterator ij;
    \n+
    47
    \n+
    48 // eliminate entries left of diagonal; store L factor
    \n+
    49 for (ij=(*i).begin(); ij.index()<i.index(); ++ij)
    \n+
    50 {
    \n+
    51 // find A_jj which eliminates A_ij
    \n+
    52 coliterator jj = A[ij.index()].find(ij.index());
    \n
    53
    \n-
    55 using field_type = typename Imp::BlockTraits<B>::field_type;
    \n+
    54 // compute L_ij = A_jj^-1 * A_ij
    \n+
    55 Impl::asMatrix(*ij).rightmultiply(Impl::asMatrix(*jj));
    \n
    56
    \n-
    58 typedef A allocator_type;
    \n-
    59
    \n-
    64 typedef window_type& reference;
    \n-
    65
    \n-
    70 typedef const window_type& const_reference;
    \n-
    71
    \n-
    73 typedef typename A::size_type size_type;
    \n-
    74
    \n-\n-
    81
    \n-\n-
    85
    \n-
    89 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
    \n-
    90 static constexpr auto blocklevel = blockLevel<B>()+2;
    \n+
    57 // modify row
    \n+
    58 coliterator endjk=A[ij.index()].end(); // end of row j
    \n+
    59 coliterator jk=jj; ++jk;
    \n+
    60 coliterator ik=ij; ++ik;
    \n+
    61 while (ik!=endij && jk!=endjk)
    \n+
    62 if (ik.index()==jk.index())
    \n+
    63 {
    \n+
    64 block B(*jk);
    \n+
    65 Impl::asMatrix(B).leftmultiply(Impl::asMatrix(*ij));
    \n+
    66 *ik -= B;
    \n+
    67 ++ik; ++jk;
    \n+
    68 }
    \n+
    69 else
    \n+
    70 {
    \n+
    71 if (ik.index()<jk.index())
    \n+
    72 ++ik;
    \n+
    73 else
    \n+
    74 ++jk;
    \n+
    75 }
    \n+
    76 }
    \n+
    77
    \n+
    78 // invert pivot and store it in A
    \n+
    79 if (ij.index()!=i.index())
    \n+
    80 DUNE_THROW(ISTLError,"diagonal entry missing");
    \n+
    81 try {
    \n+
    82 Impl::asMatrix(*ij).invert(); // compute inverse of diagonal block
    \n+
    83 }
    \n+
    84 catch (Dune::FMatrixError & e) {
    \n+
    85 DUNE_THROW(MatrixBlockError, "ILU failed to invert matrix block A["
    \n+
    86 << i.index() << "][" << ij.index() << "]" << e.what();
    \n+
    87 th__ex.r=i.index(); th__ex.c=ij.index(););
    \n+
    88 }
    \n+
    89 }
    \n+
    90 }
    \n
    91
    \n-
    92 //===== constructors and such
    \n-
    93
    \n-
    97 VariableBlockVector () : Imp::block_vector_unmanaged<B,A>()
    \n-
    98 {
    \n-
    99 // nothing is known ...
    \n-
    100 nblocks = 0;
    \n-
    101 block = nullptr;
    \n-
    102 initialized = false;
    \n-
    103 }
    \n-
    104
    \n-
    108 explicit VariableBlockVector (size_type _nblocks) : Imp::block_vector_unmanaged<B,A>()
    \n-
    109 {
    \n-
    110 // we can allocate the windows now
    \n-
    111 nblocks = _nblocks;
    \n-
    112 if (nblocks>0)
    \n-
    113 {
    \n-
    114 block = windowAllocator_.allocate(nblocks);
    \n-
    115 new (block) window_type[nblocks];
    \n-
    116 }
    \n-
    117 else
    \n-
    118 {
    \n-
    119 nblocks = 0;
    \n-
    120 block = nullptr;
    \n-
    121 }
    \n-
    122
    \n-
    123 // Note: memory in base class still not allocated
    \n-
    124 // the vector not usable
    \n-
    125 initialized = false;
    \n-
    126 }
    \n-
    127
    \n-
    134 VariableBlockVector (size_type _nblocks, size_type m) : Imp::block_vector_unmanaged<B,A>()
    \n-
    135 {
    \n-
    136 // and we can allocate the big array in the base class
    \n-
    137 this->n = _nblocks*m;
    \n-
    138 if (this->n>0)
    \n-
    139 {
    \n-
    140 this->p = allocator_.allocate(this->n);
    \n-
    141 new (this->p)B[this->n];
    \n-
    142 }
    \n-
    143 else
    \n-
    144 {
    \n-
    145 this->n = 0;
    \n-
    146 this->p = nullptr;
    \n-
    147 }
    \n-
    148
    \n-
    149 // we can allocate the windows now
    \n-
    150 nblocks = _nblocks;
    \n-
    151 if (nblocks>0)
    \n-
    152 {
    \n-
    153 // allocate and construct the windows
    \n-
    154 block = windowAllocator_.allocate(nblocks);
    \n-
    155 new (block) window_type[nblocks];
    \n-
    156
    \n-
    157 // set the windows into the big array
    \n-
    158 for (size_type i=0; i<nblocks; ++i)
    \n-
    159 block[i].set(m,this->p+(i*m));
    \n-
    160 }
    \n-
    161 else
    \n-
    162 {
    \n-
    163 nblocks = 0;
    \n-
    164 block = nullptr;
    \n-
    165 }
    \n-
    166
    \n-
    167 // and the vector is usable
    \n-
    168 initialized = true;
    \n-
    169 }
    \n-
    170
    \n-\n-
    173 {
    \n-
    174 // allocate the big array in the base class
    \n-
    175 this->n = a.n;
    \n-
    176 if (this->n>0)
    \n-
    177 {
    \n-
    178 // allocate and construct objects
    \n-
    179 this->p = allocator_.allocate(this->n);
    \n-
    180 new (this->p)B[this->n];
    \n-
    181
    \n-
    182 // copy data
    \n-
    183 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n-
    184 }
    \n-
    185 else
    \n-
    186 {
    \n-
    187 this->n = 0;
    \n-
    188 this->p = nullptr;
    \n-
    189 }
    \n-
    190
    \n-
    191 // we can allocate the windows now
    \n-
    192 nblocks = a.nblocks;
    \n-
    193 if (nblocks>0)
    \n-
    194 {
    \n-
    195 // alloc
    \n-
    196 block = windowAllocator_.allocate(nblocks);
    \n-
    197 new (block) window_type[nblocks];
    \n-
    198
    \n-
    199 // and we must set the windows
    \n-
    200 block[0].set(a.block[0].getsize(),this->p); // first block
    \n-
    201 for (size_type i=1; i<nblocks; ++i) // and the rest
    \n-
    202 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
    \n-
    203 }
    \n-
    204 else
    \n-
    205 {
    \n-
    206 nblocks = 0;
    \n-
    207 block = nullptr;
    \n-
    208 }
    \n-
    209
    \n-
    210 // and we have a usable vector
    \n-
    211 initialized = true;
    \n-
    212 }
    \n+
    93 template<class M, class X, class Y>
    \n+
    94 void blockILUBacksolve (const M& A, X& v, const Y& d)
    \n+
    95 {
    \n+
    96 // iterator types
    \n+
    97 typedef typename M::ConstRowIterator rowiterator;
    \n+
    98 typedef typename M::ConstColIterator coliterator;
    \n+
    99 typedef typename Y::block_type dblock;
    \n+
    100 typedef typename X::block_type vblock;
    \n+
    101
    \n+
    102 // lower triangular solve
    \n+
    103 rowiterator endi=A.end();
    \n+
    104 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n+
    105 {
    \n+
    106 // We need to be careful here: Directly using
    \n+
    107 // auto rhs = Impl::asVector(d[ i.index() ]);
    \n+
    108 // is not OK in case this is a proxy. Hence
    \n+
    109 // we first have to copy the value. Notice that
    \n+
    110 // this is still not OK, if the vector type itself returns
    \n+
    111 // proxy references.
    \n+
    112 dblock rhsValue(d[i.index()]);
    \n+
    113 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    114 for (coliterator j=(*i).begin(); j.index()<i.index(); ++j)
    \n+
    115 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);
    \n+
    116 Impl::asVector(v[i.index()]) = rhs; // Lii = I
    \n+
    117 }
    \n+
    118
    \n+
    119 // upper triangular solve
    \n+
    120 rowiterator rendi=A.beforeBegin();
    \n+
    121 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n+
    122 {
    \n+
    123 // We need to be careful here: Directly using
    \n+
    124 // auto rhs = Impl::asVector(v[ i.index() ]);
    \n+
    125 // is not OK in case this is a proxy. Hence
    \n+
    126 // we first have to copy the value. Notice that
    \n+
    127 // this is still not OK, if the vector type itself returns
    \n+
    128 // proxy references.
    \n+
    129 vblock rhsValue(v[i.index()]);
    \n+
    130 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    131 coliterator j;
    \n+
    132 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)
    \n+
    133 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);
    \n+
    134 auto&& vi = Impl::asVector(v[i.index()]);
    \n+
    135 Impl::asMatrix(*j).mv(rhs,vi); // diagonal stores inverse!
    \n+
    136 }
    \n+
    137 }
    \n+
    138
    \n+
    139 // recursive function template to access first entry of a matrix
    \n+
    140 template<class M>
    \n+
    141 typename M::field_type& firstMatrixElement (M& A,
    \n+
    142 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
    \n+
    143 {
    \n+
    144 return firstMatrixElement(*(A.begin()->begin()));
    \n+
    145 }
    \n+
    146
    \n+
    147 template<class K>
    \n+\n+
    149 [[maybe_unused]] typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr)
    \n+
    150 {
    \n+
    151 return A;
    \n+
    152 }
    \n+
    153
    \n+
    154 template<class K, int n, int m>
    \n+\n+
    156 {
    \n+
    157 return A[0][0];
    \n+
    158 }
    \n+
    159
    \n+
    166 template<class M>
    \n+
    167 void blockILUDecomposition (const M& A, int n, M& ILU)
    \n+
    168 {
    \n+
    169 // iterator types
    \n+
    170 typedef typename M::ColIterator coliterator;
    \n+
    171 typedef typename M::ConstRowIterator crowiterator;
    \n+
    172 typedef typename M::ConstColIterator ccoliterator;
    \n+
    173 typedef typename M::CreateIterator createiterator;
    \n+
    174 typedef typename M::field_type K;
    \n+
    175 typedef std::map<size_t, int> map;
    \n+
    176 typedef typename map::iterator mapiterator;
    \n+
    177
    \n+
    178 // symbolic factorization phase, store generation number in first matrix element
    \n+
    179 crowiterator endi=A.end();
    \n+
    180 createiterator ci=ILU.createbegin();
    \n+
    181 for (crowiterator i=A.begin(); i!=endi; ++i)
    \n+
    182 {
    \n+
    183 map rowpattern; // maps column index to generation
    \n+
    184
    \n+
    185 // initialize pattern with row of A
    \n+
    186 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)
    \n+
    187 rowpattern[j.index()] = 0;
    \n+
    188
    \n+
    189 // eliminate entries in row which are to the left of the diagonal
    \n+
    190 for (mapiterator ik=rowpattern.begin(); (*ik).first<i.index(); ++ik)
    \n+
    191 {
    \n+
    192 if ((*ik).second<n)
    \n+
    193 {
    \n+
    194 coliterator endk = ILU[(*ik).first].end(); // end of row k
    \n+
    195 coliterator kj = ILU[(*ik).first].find((*ik).first); // diagonal in k
    \n+
    196 for (++kj; kj!=endk; ++kj) // row k eliminates in row i
    \n+
    197 {
    \n+
    198 // we misuse the storage to store an int. If the field_type is std::complex, we have to access the real/abs part
    \n+
    199 // starting from C++11, we can use std::abs to always return a real value, even if it is double/float
    \n+
    200 using std::abs;
    \n+
    201 int generation = (int) Simd::lane(0, abs( firstMatrixElement(*kj) ));
    \n+
    202 if (generation<n)
    \n+
    203 {
    \n+
    204 mapiterator ij = rowpattern.find(kj.index());
    \n+
    205 if (ij==rowpattern.end())
    \n+
    206 {
    \n+
    207 rowpattern[kj.index()] = generation+1;
    \n+
    208 }
    \n+
    209 }
    \n+
    210 }
    \n+
    211 }
    \n+
    212 }
    \n
    213
    \n-\n-
    216 {
    \n-
    217 if (this->n>0) {
    \n-
    218 size_type i=this->n;
    \n-
    219 while (i)
    \n-
    220 this->p[--i].~B();
    \n-
    221 allocator_.deallocate(this->p,this->n);
    \n-
    222 }
    \n-
    223 if (nblocks>0) {
    \n-
    224 size_type i=nblocks;
    \n-
    225 while (i)
    \n-
    226 block[--i].~window_type();
    \n-
    227 windowAllocator_.deallocate(block,nblocks);
    \n-
    228 }
    \n-
    229
    \n-
    230 }
    \n-
    231
    \n-
    232
    \n-
    234 void resize (size_type _nblocks)
    \n-
    235 {
    \n-
    236 // deconstruct objects and deallocate memory if necessary
    \n-
    237 if (this->n>0) {
    \n-
    238 size_type i=this->n;
    \n-
    239 while (i)
    \n-
    240 this->p[--i].~B();
    \n-
    241 allocator_.deallocate(this->p,this->n);
    \n-
    242 }
    \n-
    243 if (nblocks>0) {
    \n-
    244 size_type i=nblocks;
    \n-
    245 while (i)
    \n-
    246 block[--i].~window_type();
    \n-
    247 windowAllocator_.deallocate(block,nblocks);
    \n-
    248 }
    \n-
    249 this->n = 0;
    \n-
    250 this->p = nullptr;
    \n+
    214 // create row
    \n+
    215 for (mapiterator ik=rowpattern.begin(); ik!=rowpattern.end(); ++ik)
    \n+
    216 ci.insert((*ik).first);
    \n+
    217 ++ci; // now row i exist
    \n+
    218
    \n+
    219 // write generation index into entries
    \n+
    220 coliterator endILUij = ILU[i.index()].end();;
    \n+
    221 for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
    \n+
    222 Simd::lane(0, firstMatrixElement(*ILUij)) = (Simd::Scalar<K>) rowpattern[ILUij.index()];
    \n+
    223 }
    \n+
    224
    \n+
    225 // copy entries of A
    \n+
    226 for (crowiterator i=A.begin(); i!=endi; ++i)
    \n+
    227 {
    \n+
    228 coliterator ILUij;
    \n+
    229 coliterator endILUij = ILU[i.index()].end();;
    \n+
    230 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
    \n+
    231 (*ILUij) = 0; // clear row
    \n+
    232 ccoliterator Aij = (*i).begin();
    \n+
    233 ccoliterator endAij = (*i).end();
    \n+
    234 ILUij = ILU[i.index()].begin();
    \n+
    235 while (Aij!=endAij && ILUij!=endILUij)
    \n+
    236 {
    \n+
    237 if (Aij.index()==ILUij.index())
    \n+
    238 {
    \n+
    239 *ILUij = *Aij;
    \n+
    240 ++Aij; ++ILUij;
    \n+
    241 }
    \n+
    242 else
    \n+
    243 {
    \n+
    244 if (Aij.index()<ILUij.index())
    \n+
    245 ++Aij;
    \n+
    246 else
    \n+
    247 ++ILUij;
    \n+
    248 }
    \n+
    249 }
    \n+
    250 }
    \n
    251
    \n-
    252 // we can allocate the windows now
    \n-
    253 nblocks = _nblocks;
    \n-
    254 if (nblocks>0)
    \n-
    255 {
    \n-
    256 block = windowAllocator_.allocate(nblocks);
    \n-
    257 new (block) window_type[nblocks];
    \n-
    258 }
    \n-
    259 else
    \n-
    260 {
    \n-
    261 nblocks = 0;
    \n-
    262 block = nullptr;
    \n-
    263 }
    \n+
    252 // call decomposition on pattern
    \n+\n+
    254 }
    \n+
    255
    \n+
    257 template <class B, class Alloc = std::allocator<B>>
    \n+
    258 struct CRS
    \n+
    259 {
    \n+
    260 typedef B block_type;
    \n+
    261 typedef size_t size_type;
    \n+
    262
    \n+
    263 CRS() : nRows_( 0 ) {}
    \n
    264
    \n-
    265 // and the vector not fully usable
    \n-
    266 initialized = false;
    \n-
    267 }
    \n-
    268
    \n-
    270 void resize (size_type _nblocks, size_type m)
    \n-
    271 {
    \n-
    272 // deconstruct objects and deallocate memory if necessary
    \n-
    273 if (this->n>0) {
    \n-
    274 size_type i=this->n;
    \n-
    275 while (i)
    \n-
    276 this->p[--i].~B();
    \n-
    277 allocator_.deallocate(this->p,this->n);
    \n-
    278 }
    \n-
    279 if (nblocks>0) {
    \n-
    280 size_type i=nblocks;
    \n-
    281 while (i)
    \n-
    282 block[--i].~window_type();
    \n-
    283 windowAllocator_.deallocate(block,nblocks);
    \n-
    284 }
    \n-
    285
    \n-
    286 // and we can allocate the big array in the base class
    \n-
    287 this->n = _nblocks*m;
    \n-
    288 if (this->n>0)
    \n-
    289 {
    \n-
    290 this->p = allocator_.allocate(this->n);
    \n-
    291 new (this->p)B[this->n];
    \n-
    292 }
    \n-
    293 else
    \n+
    265 size_type rows() const { return nRows_; }
    \n+
    266
    \n+\n+
    268 {
    \n+
    269 assert( rows_[ rows() ] != size_type(-1) );
    \n+
    270 return rows_[ rows() ];
    \n+
    271 }
    \n+
    272
    \n+
    273 void resize( const size_type nRows )
    \n+
    274 {
    \n+
    275 if( nRows_ != nRows )
    \n+
    276 {
    \n+
    277 nRows_ = nRows ;
    \n+
    278 rows_.resize( nRows_+1, size_type(-1) );
    \n+
    279 }
    \n+
    280 }
    \n+
    281
    \n+\n+
    283 {
    \n+
    284 const size_type needed = values_.size() + nonZeros ;
    \n+
    285 if( values_.capacity() < needed )
    \n+
    286 {
    \n+
    287 const size_type estimate = needed * 1.1;
    \n+
    288 values_.reserve( estimate );
    \n+
    289 cols_.reserve( estimate );
    \n+
    290 }
    \n+
    291 }
    \n+
    292
    \n+
    293 void push_back( const block_type& value, const size_type index )
    \n
    294 {
    \n-
    295 this->n = 0;
    \n-
    296 this->p = nullptr;
    \n+
    295 values_.push_back( value );
    \n+
    296 cols_.push_back( index );
    \n
    297 }
    \n
    298
    \n-
    299 // we can allocate the windows now
    \n-
    300 nblocks = _nblocks;
    \n-
    301 if (nblocks>0)
    \n-
    302 {
    \n-
    303 // allocate and construct objects
    \n-
    304 block = windowAllocator_.allocate(nblocks);
    \n-
    305 new (block) window_type[nblocks];
    \n-
    306
    \n-
    307 // set the windows into the big array
    \n-
    308 for (size_type i=0; i<nblocks; ++i)
    \n-
    309 block[i].set(m,this->p+(i*m));
    \n-
    310 }
    \n-
    311 else
    \n-
    312 {
    \n-
    313 nblocks = 0;
    \n-
    314 block = nullptr;
    \n-
    315 }
    \n-
    316
    \n-
    317 // and the vector is usable
    \n-
    318 initialized = true;
    \n-
    319 }
    \n-
    320
    \n-\n-
    323 {
    \n-
    324 if (&a!=this) // check if this and a are different objects
    \n-
    325 {
    \n-
    326 // reallocate arrays if necessary
    \n-
    327 // Note: still the block sizes may vary !
    \n-
    328 if (this->n!=a.n || nblocks!=a.nblocks)
    \n-
    329 {
    \n-
    330 // deconstruct objects and deallocate memory if necessary
    \n-
    331 if (this->n>0) {
    \n-
    332 size_type i=this->n;
    \n-
    333 while (i)
    \n-
    334 this->p[--i].~B();
    \n-
    335 allocator_.deallocate(this->p,this->n);
    \n-
    336 }
    \n-
    337 if (nblocks>0) {
    \n-
    338 size_type i=nblocks;
    \n-
    339 while (i)
    \n-
    340 block[--i].~window_type();
    \n-
    341 windowAllocator_.deallocate(block,nblocks);
    \n-
    342 }
    \n+
    299 std::vector< size_type > rows_;
    \n+
    300 std::vector< block_type, Alloc> values_;
    \n+
    301 std::vector< size_type > cols_;
    \n+\n+
    303 };
    \n+
    304
    \n+
    306 template<class M, class CRS, class InvVector>
    \n+
    307 void convertToCRS(const M& A, CRS& lower, CRS& upper, InvVector& inv )
    \n+
    308 {
    \n+
    309 typedef typename M :: size_type size_type;
    \n+
    310
    \n+
    311 lower.resize( A.N() );
    \n+
    312 upper.resize( A.N() );
    \n+
    313 inv.resize( A.N() );
    \n+
    314
    \n+
    315 // lower and upper triangular should store half of non zeros minus diagonal
    \n+
    316 const size_t memEstimate = (A.nonzeroes() - A.N())/2;
    \n+
    317
    \n+
    318 assert( A.nonzeroes() != 0 );
    \n+
    319 lower.reserveAdditional( memEstimate );
    \n+
    320 upper.reserveAdditional( memEstimate );
    \n+
    321
    \n+
    322 const auto endi = A.end();
    \n+
    323 size_type row = 0;
    \n+
    324 size_type colcount = 0;
    \n+
    325 lower.rows_[ 0 ] = colcount;
    \n+
    326 for (auto i=A.begin(); i!=endi; ++i, ++row)
    \n+
    327 {
    \n+
    328 const size_type iIndex = i.index();
    \n+
    329
    \n+
    330 // store entries left of diagonal
    \n+
    331 for (auto j=(*i).begin(); j.index() < iIndex; ++j )
    \n+
    332 {
    \n+
    333 lower.push_back( (*j), j.index() );
    \n+
    334 ++colcount;
    \n+
    335 }
    \n+
    336 lower.rows_[ iIndex+1 ] = colcount;
    \n+
    337 }
    \n+
    338
    \n+
    339 const auto rendi = A.beforeBegin();
    \n+
    340 row = 0;
    \n+
    341 colcount = 0;
    \n+
    342 upper.rows_[ 0 ] = colcount ;
    \n
    343
    \n-
    344 // allocate the big array in the base class
    \n-
    345 this->n = a.n;
    \n-
    346 if (this->n>0)
    \n-
    347 {
    \n-
    348 // allocate and construct objects
    \n-
    349 this->p = allocator_.allocate(this->n);
    \n-
    350 new (this->p)B[this->n];
    \n-
    351 }
    \n-
    352 else
    \n-
    353 {
    \n-
    354 this->n = 0;
    \n-
    355 this->p = nullptr;
    \n-
    356 }
    \n-
    357
    \n-
    358 // we can allocate the windows now
    \n-
    359 nblocks = a.nblocks;
    \n-
    360 if (nblocks>0)
    \n-
    361 {
    \n-
    362 // alloc
    \n-
    363 block = windowAllocator_.allocate(nblocks);
    \n-
    364 new (block) window_type[nblocks];
    \n+
    344 // NOTE: upper and inv store entries in reverse row and col order,
    \n+
    345 // reverse here relative to ILU
    \n+
    346 for (auto i=A.beforeEnd(); i!=rendi; --i, ++ row )
    \n+
    347 {
    \n+
    348 const auto endij=(*i).beforeBegin(); // end of row i
    \n+
    349
    \n+
    350 const size_type iIndex = i.index();
    \n+
    351
    \n+
    352 // store in reverse row order for faster access during backsolve
    \n+
    353 for (auto j=(*i).beforeEnd(); j != endij; --j )
    \n+
    354 {
    \n+
    355 const size_type jIndex = j.index();
    \n+
    356 if( j.index() == iIndex )
    \n+
    357 {
    \n+
    358 inv[ row ] = (*j);
    \n+
    359 break; // assuming consecutive ordering of A
    \n+
    360 }
    \n+
    361 else if ( j.index() >= i.index() )
    \n+
    362 {
    \n+
    363 upper.push_back( (*j), jIndex );
    \n+
    364 ++colcount ;
    \n
    365 }
    \n-
    366 else
    \n-
    367 {
    \n-
    368 nblocks = 0;
    \n-
    369 block = nullptr;
    \n-
    370 }
    \n-
    371 }
    \n-
    372
    \n-
    373 // copy block structure, might be different although
    \n-
    374 // sizes are the same !
    \n-
    375 if (nblocks>0)
    \n-
    376 {
    \n-
    377 block[0].set(a.block[0].getsize(),this->p); // first block
    \n-
    378 for (size_type i=1; i<nblocks; ++i) // and the rest
    \n-
    379 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
    \n-
    380 }
    \n-
    381
    \n-
    382 // and copy the data
    \n-
    383 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
    \n-
    384 }
    \n-
    385
    \n-
    386 // and we have a usable vector
    \n-
    387 initialized = true;
    \n-
    388
    \n-
    389 return *this; // Gebe Referenz zurueck damit a=b=c; klappt
    \n-
    390 }
    \n-
    391
    \n-
    392
    \n-
    393 //===== assignment from scalar
    \n-
    394
    \n-\n-
    397 {
    \n-
    398 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
    \n-
    399 return *this;
    \n-
    400 }
    \n-
    401
    \n-
    402
    \n-
    403 //===== the creation interface
    \n-
    404
    \n-
    405 class CreateIterator;
    \n-
    406
    \n-
    407#ifndef DOXYGEN
    \n-
    408
    \n-
    409 // The window_type does not hand out a reference to its size,
    \n-
    410 // so in order to provide a valid iterator, we need a workaround
    \n-
    411 // to make assignment possible. This proxy enables just that by
    \n-
    412 // implicitly converting to the stored size for read access and
    \n-
    413 // tunneling assignment to the accessor method of the window.
    \n-
    414 struct SizeProxy
    \n-
    415 {
    \n-
    416
    \n-
    417 operator size_type() const
    \n-
    418 {
    \n-
    419 return target->getsize();
    \n-
    420 }
    \n-
    421
    \n-
    422 SizeProxy& operator=(size_type size)
    \n-
    423 {
    \n-
    424 target->setsize(size);
    \n-
    425 return *this;
    \n-
    426 }
    \n-
    427
    \n-
    428 private:
    \n-
    429
    \n-
    430 friend class CreateIterator;
    \n-
    431
    \n-
    432 SizeProxy(window_type& t)
    \n-
    433 : target(&t)
    \n-
    434 {}
    \n-
    435
    \n-
    436 window_type* target;
    \n-
    437 };
    \n-
    438
    \n-
    439#endif // DOXYGEN
    \n-
    440
    \n-\n-
    443 {
    \n-
    444 public:
    \n-
    446 using iterator_category = std::output_iterator_tag;
    \n-
    447
    \n-\n-
    450
    \n-
    457 using difference_type = void;
    \n-
    458
    \n-\n-
    461
    \n-
    463 using reference = SizeProxy;
    \n-
    464
    \n-
    466 CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
    \n-
    467 v(_v),
    \n-
    468 i(_i),
    \n-
    469 isEnd(_isEnd) {}
    \n-
    470
    \n-\n-
    472 // When the iterator gets destructed, we allocate the memory
    \n-
    473 // for the VariableBlockVector if
    \n-
    474 // 1. the current iterator was not created as enditerator
    \n-
    475 // 2. we're at the last block
    \n-
    476 // 3. the vector hasn't been initialized earlier
    \n-
    477 if (not isEnd && i==v.nblocks && not v.initialized)
    \n-
    478 v.allocate();
    \n-
    479 }
    \n-
    480
    \n-\n-
    483 {
    \n-
    484 // go to next block
    \n-
    485 ++i;
    \n-
    486
    \n-
    487 return *this;
    \n-
    488 }
    \n-
    489
    \n-\n-
    492 {
    \n-
    493 CreateIterator tmp(*this);
    \n-
    494 this->operator++();
    \n-
    495 return tmp;
    \n-
    496 }
    \n-
    497
    \n-
    499 bool operator!= (const CreateIterator& it) const
    \n-
    500 {
    \n-
    501 return (i!=it.i) || (&v!=&it.v);
    \n-
    502 }
    \n-
    503
    \n-
    505 bool operator== (const CreateIterator& it) const
    \n-
    506 {
    \n-
    507 return (i==it.i) && (&v==&it.v);
    \n-
    508 }
    \n-
    509
    \n-\n-
    512 {
    \n-
    513 return i;
    \n-
    514 }
    \n-
    515
    \n-\n-
    518 {
    \n-
    519 v.block[i].setsize(_k);
    \n-
    520 }
    \n-
    521
    \n-
    523#ifdef DOXYGEN
    \n-
    524 size_type&
    \n-
    525#else
    \n-
    526 SizeProxy
    \n-
    527#endif
    \n-\n-
    529 {
    \n-
    530 return {v.block[i]};
    \n-
    531 }
    \n-
    532
    \n-
    533 private:
    \n-
    534 VariableBlockVector& v; // my vector
    \n-
    535 size_type i; // current block to be defined
    \n-
    536 const bool isEnd; // flag if this object was created as the end iterator.
    \n-
    537 };
    \n-
    538
    \n-
    539 // CreateIterator wants to set all the arrays ...
    \n-
    540 friend class CreateIterator;
    \n-
    541
    \n-\n-
    544 {
    \n-
    545#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    546 if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
    \n-
    547#endif
    \n-
    548 return CreateIterator(*this,0, false);
    \n-
    549 }
    \n-
    550
    \n-\n-
    553 {
    \n-
    554 return CreateIterator(*this,nblocks, true);
    \n-
    555 }
    \n-
    556
    \n-
    557
    \n-
    558 //===== access to components
    \n-
    559 // has to be overwritten from base class because it must
    \n-
    560 // return access to the windows
    \n-
    561
    \n-
    563 window_type& operator[] (size_type i)
    \n-
    564 {
    \n-
    565#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    566 if (i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
    \n-
    567#endif
    \n-
    568 return block[i];
    \n-
    569 }
    \n-
    570
    \n-
    572 const window_type& operator[] (size_type i) const
    \n-
    573 {
    \n-
    574#ifdef DUNE_ISTL_WITH_CHECKING
    \n-
    575 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
    \n-
    576#endif
    \n-
    577 return block[i];
    \n-
    578 }
    \n-
    579
    \n-
    581 template <class T, class R>
    \n-\n-
    583 : public RandomAccessIteratorFacade<RealIterator<T,R>, T, R>
    \n-
    584 {
    \n-
    585 public:
    \n-\n-
    588 {
    \n-
    589 p = nullptr;
    \n-
    590 i = 0;
    \n-
    591 }
    \n-
    592
    \n-
    594 RealIterator (window_type* _p, size_type _i)
    \n-
    595 : p(_p), i(_i)
    \n-
    596 {}
    \n-
    597
    \n-\n-
    600 {
    \n-
    601 ++i;
    \n-
    602 }
    \n-
    603
    \n-\n-
    606 {
    \n-
    607 --i;
    \n-
    608 }
    \n-
    609
    \n-
    611 bool equals (const RealIterator& it) const
    \n-
    612 {
    \n-
    613 return (p+i)==(it.p+it.i);
    \n-
    614 }
    \n-
    615
    \n-
    617 window_type& dereference () const
    \n-
    618 {
    \n-
    619 return p[i];
    \n-
    620 }
    \n-
    621
    \n-
    622 void advance(std::ptrdiff_t d)
    \n-
    623 {
    \n-
    624 i+=d;
    \n-
    625 }
    \n-
    626
    \n-
    627 std::ptrdiff_t distanceTo(const RealIterator& o) const
    \n-
    628 {
    \n-
    629 return o.i-i;
    \n-
    630 }
    \n-
    631
    \n-
    632 // Needed for operator[] of the iterator
    \n-
    633 window_type& elementAt (std::ptrdiff_t offset) const
    \n-
    634 {
    \n-
    635 return p[i+offset];
    \n-
    636 }
    \n-
    637
    \n-\n-
    640 {
    \n-
    641 return i;
    \n-
    642 }
    \n-
    643
    \n-
    644 private:
    \n-
    645 window_type* p;
    \n-
    646 size_type i;
    \n-
    647 };
    \n-
    648
    \n-\n-
    650
    \n-\n-
    653 {
    \n-
    654 return Iterator(block,0);
    \n-
    655 }
    \n-
    656
    \n-\n-
    659 {
    \n-
    660 return Iterator(block,nblocks);
    \n-
    661 }
    \n-
    662
    \n-\n-
    666 {
    \n-
    667 return Iterator(block,nblocks-1);
    \n-
    668 }
    \n-
    669
    \n-\n-
    673 {
    \n-
    674 return Iterator(block,-1);
    \n-
    675 }
    \n-
    676
    \n-\n-
    679
    \n-\n-
    682
    \n-\n-
    685
    \n-\n-
    688 {
    \n-
    689 return ConstIterator(block,0);
    \n-
    690 }
    \n-
    691
    \n-\n-
    694 {
    \n-
    695 return ConstIterator(block,nblocks);
    \n-
    696 }
    \n-
    697
    \n-\n-
    701 {
    \n-
    702 return ConstIterator(block,nblocks-1);
    \n-
    703 }
    \n-
    704
    \n-\n-
    707 {
    \n-
    708 return ConstIterator(block,-1);
    \n-
    709 }
    \n-
    710
    \n-\n-
    713 {
    \n-
    714 return Iterator(block,std::min(i,nblocks));
    \n-
    715 }
    \n-
    716
    \n-\n-
    719 {
    \n-
    720 return ConstIterator(block,std::min(i,nblocks));
    \n-
    721 }
    \n-
    722
    \n-
    723 //===== sizes
    \n-
    724
    \n-
    726 size_type N () const
    \n-
    727 {
    \n-
    728 return nblocks;
    \n-
    729 }
    \n-
    730
    \n-\n-
    736 {
    \n-
    737 return nblocks;
    \n-
    738 }
    \n-
    739
    \n-
    740
    \n-
    741 private:
    \n-
    742
    \n-
    743 void allocate() {
    \n-
    744 if (this->initialized)
    \n-
    745 DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
    \n-
    746
    \n-
    747 // calculate space needed:
    \n-
    748 this->n=0;
    \n-
    749 for(size_type i = 0; i < nblocks; i++) {
    \n-
    750 this->n += block[i].size();
    \n-
    751 }
    \n-
    752
    \n-
    753 // now we can allocate the big array in the base class of v
    \n-
    754 if (this->n>0)
    \n-
    755 {
    \n-
    756 // allocate and construct objects
    \n-
    757 this->p = allocator_.allocate(this->n);
    \n-
    758 new (this->p)B[this->n];
    \n-
    759 }
    \n-
    760 else
    \n-
    761 {
    \n-
    762 this->p = nullptr;
    \n-
    763 }
    \n-
    764
    \n-
    765 // and we set the window pointers
    \n-
    766 this->block[0].setptr(this->p); // pointer to first block
    \n-
    767 for (size_type j=1; j<nblocks; ++j) // and the rest
    \n-
    768 block[j].setptr(block[j-1].getptr()+block[j-1].getsize());
    \n-
    769
    \n-
    770 // and the vector is ready
    \n-
    771 this->initialized = true;
    \n-
    772 }
    \n-
    773
    \n-
    774 size_type nblocks; // number of blocks in vector
    \n-
    775 window_type* block; // array of blocks pointing to the array in the base class
    \n-
    776 bool initialized; // true if vector has been initialized
    \n-
    777
    \n-
    778 A allocator_;
    \n-
    779
    \n-
    780 typename std::allocator_traits<A>::template rebind_alloc<window_type> windowAllocator_;
    \n-
    781 };
    \n-
    782
    \n-
    783
    \n-
    784
    \n-
    787} // end namespace
    \n-
    788
    \n-
    789#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    This file implements a vector space as a tensor product of a given vector space. The number of compon...
    \n-\n+
    366 }
    \n+
    367 upper.rows_[ row+1 ] = colcount;
    \n+
    368 }
    \n+
    369 } // end convertToCRS
    \n+
    370
    \n+
    372 template<class CRS, class InvVector, class X, class Y>
    \n+
    373 void blockILUBacksolve (const CRS& lower,
    \n+
    374 const CRS& upper,
    \n+
    375 const InvVector& inv,
    \n+
    376 X& v, const Y& d)
    \n+
    377 {
    \n+
    378 // iterator types
    \n+
    379 typedef typename Y :: block_type dblock;
    \n+
    380 typedef typename X :: block_type vblock;
    \n+
    381 typedef typename X :: size_type size_type ;
    \n+
    382
    \n+
    383 const size_type iEnd = lower.rows();
    \n+
    384 const size_type lastRow = iEnd - 1;
    \n+
    385 if( iEnd != upper.rows() )
    \n+
    386 {
    \n+
    387 DUNE_THROW(ISTLError,"ILU::blockILUBacksolve: lower and upper rows must be the same");
    \n+
    388 }
    \n+
    389
    \n+
    390 // lower triangular solve
    \n+
    391 for( size_type i=0; i<iEnd; ++ i )
    \n+
    392 {
    \n+
    393 dblock rhsValue( d[ i ] );
    \n+
    394 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    395 const size_type rowI = lower.rows_[ i ];
    \n+
    396 const size_type rowINext = lower.rows_[ i+1 ];
    \n+
    397
    \n+
    398 for( size_type col = rowI; col < rowINext; ++ col )
    \n+
    399 Impl::asMatrix(lower.values_[ col ]).mmv( Impl::asVector(v[ lower.cols_[ col ] ] ), rhs );
    \n+
    400
    \n+
    401 Impl::asVector(v[ i ]) = rhs; // Lii = I
    \n+
    402 }
    \n+
    403
    \n+
    404 // upper triangular solve
    \n+
    405 for( size_type i=0; i<iEnd; ++ i )
    \n+
    406 {
    \n+
    407 auto&& vBlock = Impl::asVector(v[ lastRow - i ]);
    \n+
    408 vblock rhsValue ( v[ lastRow - i ] );
    \n+
    409 auto&& rhs = Impl::asVector(rhsValue);
    \n+
    410 const size_type rowI = upper.rows_[ i ];
    \n+
    411 const size_type rowINext = upper.rows_[ i+1 ];
    \n+
    412
    \n+
    413 for( size_type col = rowI; col < rowINext; ++ col )
    \n+
    414 Impl::asMatrix(upper.values_[ col ]).mmv( Impl::asVector(v[ upper.cols_[ col ] ]), rhs );
    \n+
    415
    \n+
    416 // apply inverse and store result
    \n+
    417 Impl::asMatrix(inv[ i ]).mv(rhs, vBlock);
    \n+
    418 }
    \n+
    419 }
    \n+
    420
    \n+
    421 } // end namespace ILU
    \n+
    422
    \n+
    425} // end namespace
    \n+
    426
    \n+
    427#endif
    \n+\n+
    Col col
    Definition: matrixmatrix.hh:351
    \n
    Definition: allocator.hh:11
    \n-
    A vector of blocks with memory management.
    Definition: bvector.hh:395
    \n+
    void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)
    convert ILU decomposition into CRS format for lower and upper triangular and inverse.
    Definition: ilu.hh:307
    \n+
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n+
    M::field_type & firstMatrixElement(M &A, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
    Definition: ilu.hh:141
    \n+
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n+
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n+
    a simple compressed row storage matrix class
    Definition: ilu.hh:259
    \n+
    std::vector< size_type > cols_
    Definition: ilu.hh:301
    \n+
    size_type nonZeros() const
    Definition: ilu.hh:267
    \n+
    void resize(const size_type nRows)
    Definition: ilu.hh:273
    \n+
    size_type rows() const
    Definition: ilu.hh:265
    \n+
    CRS()
    Definition: ilu.hh:263
    \n+
    void reserveAdditional(const size_type nonZeros)
    Definition: ilu.hh:282
    \n+
    B block_type
    Definition: ilu.hh:260
    \n+
    std::vector< block_type, Alloc > values_
    Definition: ilu.hh:300
    \n+
    size_type nRows_
    Definition: ilu.hh:302
    \n+
    size_t size_type
    Definition: ilu.hh:261
    \n+
    std::vector< size_type > rows_
    Definition: ilu.hh:299
    \n+
    void push_back(const block_type &value, const size_type index)
    Definition: ilu.hh:293
    \n
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n-
    A Vector of blocks with different blocksizes.
    Definition: vbvector.hh:46
    \n-
    RealIterator< value_type, window_type & > Iterator
    Definition: vbvector.hh:649
    \n-
    VariableBlockVector()
    Definition: vbvector.hh:97
    \n-
    friend class CreateIterator
    Definition: vbvector.hh:540
    \n-
    typename Imp::BlockTraits< B >::field_type field_type
    export the type representing the field
    Definition: vbvector.hh:55
    \n-
    A allocator_type
    export the allocator type
    Definition: vbvector.hh:58
    \n-
    VariableBlockVector(size_type _nblocks, size_type m)
    Definition: vbvector.hh:134
    \n-
    size_type size() const
    Definition: vbvector.hh:735
    \n-
    size_type N() const
    number of blocks in the vector (are of variable size here)
    Definition: vbvector.hh:726
    \n-
    VariableBlockVector(const VariableBlockVector &a)
    copy constructor, has copy semantics
    Definition: vbvector.hh:172
    \n-
    VariableBlockVector(size_type _nblocks)
    Definition: vbvector.hh:108
    \n-
    ~VariableBlockVector()
    free dynamic memory
    Definition: vbvector.hh:215
    \n-
    window_type & operator[](size_type i)
    random access to blocks
    Definition: vbvector.hh:563
    \n-
    CreateIterator createend()
    get create iterator pointing to one after the last block
    Definition: vbvector.hh:552
    \n-
    Iterator beforeBegin() const
    Definition: vbvector.hh:672
    \n-
    CreateIterator createbegin()
    get initial create iterator
    Definition: vbvector.hh:543
    \n-
    VariableBlockVector & operator=(const VariableBlockVector &a)
    assignment
    Definition: vbvector.hh:322
    \n-
    static constexpr auto blocklevel
    Definition: vbvector.hh:90
    \n-
    ConstIterator rend() const
    end ConstIterator
    Definition: vbvector.hh:706
    \n-
    A::size_type size_type
    The size type for the index access.
    Definition: vbvector.hh:73
    \n-
    ConstIterator find(size_type i) const
    random access returning iterator (end if not contained)
    Definition: vbvector.hh:718
    \n-
    ConstIterator beforeEnd() const
    Definition: vbvector.hh:700
    \n-
    Iterator find(size_type i)
    random access returning iterator (end if not contained)
    Definition: vbvector.hh:712
    \n-
    const window_type & const_reference
    Export type used for const references to container entries.
    Definition: vbvector.hh:70
    \n-
    RealIterator< const value_type, const window_type & > ConstIterator
    Const iterator.
    Definition: vbvector.hh:681
    \n-
    Iterator end()
    end Iterator
    Definition: vbvector.hh:658
    \n-
    ConstIterator begin() const
    begin ConstIterator
    Definition: vbvector.hh:687
    \n-
    BlockVector< B, A > value_type
    Type of the elements of the outer vector, i.e., dynamic vectors of B.
    Definition: vbvector.hh:80
    \n-
    ConstIterator end() const
    end ConstIterator
    Definition: vbvector.hh:693
    \n-
    BlockVector< B, A > block_type
    Same as value_type, here for historical reasons.
    Definition: vbvector.hh:84
    \n-
    void resize(size_type _nblocks, size_type m)
    same effect as constructor with same argument
    Definition: vbvector.hh:270
    \n-
    window_type & reference
    Export type used for references to container entries.
    Definition: vbvector.hh:64
    \n-
    void resize(size_type _nblocks)
    same effect as constructor with same argument
    Definition: vbvector.hh:234
    \n-
    Iterator beforeEnd()
    Definition: vbvector.hh:665
    \n-
    Iterator begin()
    begin Iterator
    Definition: vbvector.hh:652
    \n-
    Iterator class for sequential creation of blocks.
    Definition: vbvector.hh:443
    \n-
    bool operator==(const CreateIterator &it) const
    equality
    Definition: vbvector.hh:505
    \n-
    size_type index() const
    dereferencing
    Definition: vbvector.hh:511
    \n-
    SizeProxy reference
    reference type
    Definition: vbvector.hh:463
    \n-
    size_type * pointer
    pointer type
    Definition: vbvector.hh:460
    \n-
    bool operator!=(const CreateIterator &it) const
    inequality
    Definition: vbvector.hh:499
    \n-
    ~CreateIterator()
    Definition: vbvector.hh:471
    \n-
    size_type value_type
    value type
    Definition: vbvector.hh:449
    \n-
    CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)
    constructor
    Definition: vbvector.hh:466
    \n-
    void setblocksize(size_type _k)
    set size of current block
    Definition: vbvector.hh:517
    \n-
    size_type & operator*()
    Access size of current block.
    Definition: vbvector.hh:528
    \n-
    std::output_iterator_tag iterator_category
    iterator category
    Definition: vbvector.hh:446
    \n-
    CreateIterator & operator++()
    prefix increment
    Definition: vbvector.hh:482
    \n-
    void difference_type
    difference type (unused)
    Definition: vbvector.hh:457
    \n-
    Iterator class for sequential access.
    Definition: vbvector.hh:584
    \n-
    RealIterator(window_type *_p, size_type _i)
    constructor
    Definition: vbvector.hh:594
    \n-
    bool equals(const RealIterator &it) const
    equality
    Definition: vbvector.hh:611
    \n-
    size_type index() const
    Return the index of the entry this iterator is pointing to.
    Definition: vbvector.hh:639
    \n-
    window_type & elementAt(std::ptrdiff_t offset) const
    Definition: vbvector.hh:633
    \n-
    void decrement()
    prefix decrement
    Definition: vbvector.hh:605
    \n-
    void advance(std::ptrdiff_t d)
    Definition: vbvector.hh:622
    \n-
    void increment()
    prefix increment
    Definition: vbvector.hh:599
    \n-
    RealIterator()
    constructor, no arguments
    Definition: vbvector.hh:587
    \n-
    std::ptrdiff_t distanceTo(const RealIterator &o) const
    Definition: vbvector.hh:627
    \n-
    window_type & dereference() const
    dereferencing
    Definition: vbvector.hh:617
    \n+
    Error when performing an operation on a matrix block.
    Definition: istlexception.hh:52
    \n+
    int r
    Definition: istlexception.hh:54
    \n+
    Definition: matrixutils.hh:27
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,936 +4,505 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-vbvector.hh\n+ilu.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_VBVECTOR_HH\n- 6#define DUNE_ISTL_VBVECTOR_HH\n+ 5#ifndef DUNE_ISTL_ILU_HH\n+ 6#define DUNE_ISTL_ILU_HH\n 7\n 8#include \n 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13\n- 14#include \n- 15#include \"istlexception.hh\"\n- 16#include \"bvector.hh\"\n- 17\n- 18#include \n- 19\n- 24namespace Dune {\n- 25\n- 41 template >\n-42 class VariableBlockVector : public Imp::block_vector_unmanaged\n- 43 // this derivation gives us all the blas level 1 and norms\n- 44 // on the large array. However, access operators have to be\n- 45 // overwritten.\n- 46 {\n- 47 // just a shorthand\n- 48 typedef Imp::BlockVectorWindow window_type;\n- 49\n- 50 public:\n- 51\n- 52 //===== type definitions and constants\n+ 10#include \n+ 11#include \n+ 12\n+ 13#include \n+ 14#include \n+ 15#include \n+ 16\n+ 17#include \"istlexception.hh\"\n+ 18\n+ 23namespace Dune {\n+ 24\n+29 namespace ILU {\n+ 30\n+ 32 template\n+33 void blockILU0Decomposition (M& A)\n+ 34 {\n+ 35 // iterator types\n+ 36 typedef typename M::RowIterator rowiterator;\n+ 37 typedef typename M::ColIterator coliterator;\n+ 38 typedef typename M::block_type block;\n+ 39\n+ 40 // implement left looking variant with stored inverse\n+ 41 rowiterator endi=A.end();\n+ 42 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 43 {\n+ 44 // coliterator is diagonal after the following loop\n+ 45 coliterator endij=(*i).end(); // end of row i\n+ 46 coliterator ij;\n+ 47\n+ 48 // eliminate entries left of diagonal; store L factor\n+ 49 for (ij=(*i).begin(); ij.index()::field_type;\n+ 54 // compute L_ij = A_jj^-1 * A_ij\n+ 55 Impl::asMatrix(*ij).rightmultiply(Impl::asMatrix(*jj));\n 56\n-58 typedef A allocator_type;\n- 59\n-64 typedef window_type& reference;\n- 65\n-70 typedef const window_type& const_reference;\n- 71\n-73 typedef typename A::size_type size_type;\n- 74\n-80 typedef BlockVector value_type;\n- 81\n-84 typedef BlockVector block_type;\n- 85\n- 89 [[deprecated(\"Use free function blockLevel(). Will be removed after\n-2.8.\")]]\n-90 static constexpr auto blocklevel = blockLevel()+2;\n+ 57 // modify row\n+ 58 coliterator endjk=A[ij.index()].end(); // end of row j\n+ 59 coliterator jk=jj; ++jk;\n+ 60 coliterator ik=ij; ++ik;\n+ 61 while (ik!=endij && jk!=endjk)\n+ 62 if (ik.index()==jk.index())\n+ 63 {\n+ 64 block B(*jk);\n+ 65 Impl::asMatrix(B).leftmultiply(Impl::asMatrix(*ij));\n+ 66 *ik -= B;\n+ 67 ++ik; ++jk;\n+ 68 }\n+ 69 else\n+ 70 {\n+ 71 if (ik.index()()\n- 98 {\n- 99 // nothing is known ...\n- 100 nblocks = 0;\n- 101 block = nullptr;\n- 102 initialized = false;\n- 103 }\n- 104\n-108 explicit VariableBlockVector (size_type _nblocks) : Imp::\n-block_vector_unmanaged()\n- 109 {\n- 110 // we can allocate the windows now\n- 111 nblocks = _nblocks;\n- 112 if (nblocks>0)\n- 113 {\n- 114 block = windowAllocator_.allocate(nblocks);\n- 115 new (block) window_type[nblocks];\n- 116 }\n- 117 else\n- 118 {\n- 119 nblocks = 0;\n- 120 block = nullptr;\n- 121 }\n- 122\n- 123 // Note: memory in base class still not allocated\n- 124 // the vector not usable\n- 125 initialized = false;\n- 126 }\n- 127\n-134 VariableBlockVector (size_type _nblocks, size_type m) : Imp::\n-block_vector_unmanaged()\n- 135 {\n- 136 // and we can allocate the big array in the base class\n- 137 this->n = _nblocks*m;\n- 138 if (this->n>0)\n- 139 {\n- 140 this->p = allocator_.allocate(this->n);\n- 141 new (this->p)B[this->n];\n- 142 }\n- 143 else\n- 144 {\n- 145 this->n = 0;\n- 146 this->p = nullptr;\n- 147 }\n- 148\n- 149 // we can allocate the windows now\n- 150 nblocks = _nblocks;\n- 151 if (nblocks>0)\n- 152 {\n- 153 // allocate and construct the windows\n- 154 block = windowAllocator_.allocate(nblocks);\n- 155 new (block) window_type[nblocks];\n- 156\n- 157 // set the windows into the big array\n- 158 for (size_type i=0; ip+(i*m));\n- 160 }\n- 161 else\n- 162 {\n- 163 nblocks = 0;\n- 164 block = nullptr;\n- 165 }\n- 166\n- 167 // and the vector is usable\n- 168 initialized = true;\n- 169 }\n- 170\n-172 VariableBlockVector (const VariableBlockVector& a)\n- 173 {\n- 174 // allocate the big array in the base class\n- 175 this->n = a.n;\n- 176 if (this->n>0)\n- 177 {\n- 178 // allocate and construct objects\n- 179 this->p = allocator_.allocate(this->n);\n- 180 new (this->p)B[this->n];\n- 181\n- 182 // copy data\n- 183 for (size_type i=0; in; i++) this->p[i]=a.p[i];\n- 184 }\n- 185 else\n- 186 {\n- 187 this->n = 0;\n- 188 this->p = nullptr;\n- 189 }\n- 190\n- 191 // we can allocate the windows now\n- 192 nblocks = a.nblocks;\n- 193 if (nblocks>0)\n- 194 {\n- 195 // alloc\n- 196 block = windowAllocator_.allocate(nblocks);\n- 197 new (block) window_type[nblocks];\n- 198\n- 199 // and we must set the windows\n- 200 block[0].set(a.block[0].getsize(),this->p); // first block\n- 201 for (size_type i=1; i\n+94 void blockILUBacksolve (const M& A, X& v, const Y& d)\n+ 95 {\n+ 96 // iterator types\n+ 97 typedef typename M::ConstRowIterator rowiterator;\n+ 98 typedef typename M::ConstColIterator coliterator;\n+ 99 typedef typename Y::block_type dblock;\n+ 100 typedef typename X::block_type vblock;\n+ 101\n+ 102 // lower triangular solve\n+ 103 rowiterator endi=A.end();\n+ 104 for (rowiterator i=A.begin(); i!=endi; ++i)\n+ 105 {\n+ 106 // We need to be careful here: Directly using\n+ 107 // auto rhs = Impl::asVector(d[ i.index() ]);\n+ 108 // is not OK in case this is a proxy. Hence\n+ 109 // we first have to copy the value. Notice that\n+ 110 // this is still not OK, if the vector type itself returns\n+ 111 // proxy references.\n+ 112 dblock rhsValue(d[i.index()]);\n+ 113 auto&& rhs = Impl::asVector(rhsValue);\n+ 114 for (coliterator j=(*i).begin(); j.index()i.index(); --j)\n+ 133 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);\n+ 134 auto&& vi = Impl::asVector(v[i.index()]);\n+ 135 Impl::asMatrix(*j).mv(rhs,vi); // diagonal stores inverse!\n+ 136 }\n+ 137 }\n+ 138\n+ 139 // recursive function template to access first entry of a matrix\n+ 140 template\n+141 typename M::field_type& firstMatrixElement (M& A,\n+ 142 [[maybe_unused]] typename std::enable_if_t::value>*\n+sfinae = nullptr)\n+ 143 {\n+ 144 return firstMatrixElement(*(A.begin()->begin()));\n+ 145 }\n+ 146\n+ 147 template\n+148 K& firstMatrixElement (K& A,\n+ 149 [[maybe_unused]] typename std::enable_if_t::value>*\n+sfinae = nullptr)\n+ 150 {\n+ 151 return A;\n+ 152 }\n+ 153\n+ 154 template\n+155 K& firstMatrixElement (FieldMatrix& A)\n+ 156 {\n+ 157 return A[0][0];\n+ 158 }\n+ 159\n+ 166 template\n+167 void blockILUDecomposition (const M& A, int n, M& ILU)\n+ 168 {\n+ 169 // iterator types\n+ 170 typedef typename M::ColIterator coliterator;\n+ 171 typedef typename M::ConstRowIterator crowiterator;\n+ 172 typedef typename M::ConstColIterator ccoliterator;\n+ 173 typedef typename M::CreateIterator createiterator;\n+ 174 typedef typename M::field_type K;\n+ 175 typedef std::map map;\n+ 176 typedef typename map::iterator mapiterator;\n+ 177\n+ 178 // symbolic factorization phase, store generation number in first matrix\n+element\n+ 179 crowiterator endi=A.end();\n+ 180 createiterator ci=ILU.createbegin();\n+ 181 for (crowiterator i=A.begin(); i!=endi; ++i)\n+ 182 {\n+ 183 map rowpattern; // maps column index to generation\n+ 184\n+ 185 // initialize pattern with row of A\n+ 186 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)\n+ 187 rowpattern[j.index()] = 0;\n+ 188\n+ 189 // eliminate entries in row which are to the left of the diagonal\n+ 190 for (mapiterator ik=rowpattern.begin(); (*ik).firstn>0) {\n- 218 size_type i=this->n;\n- 219 while (i)\n- 220 this->p[--i].~B();\n- 221 allocator_.deallocate(this->p,this->n);\n- 222 }\n- 223 if (nblocks>0) {\n- 224 size_type i=nblocks;\n- 225 while (i)\n- 226 block[--i].~window_type();\n- 227 windowAllocator_.deallocate(block,nblocks);\n- 228 }\n- 229\n- 230 }\n- 231\n- 232\n-234 void resize (size_type _nblocks)\n- 235 {\n- 236 // deconstruct objects and deallocate memory if necessary\n- 237 if (this->n>0) {\n- 238 size_type i=this->n;\n- 239 while (i)\n- 240 this->p[--i].~B();\n- 241 allocator_.deallocate(this->p,this->n);\n- 242 }\n- 243 if (nblocks>0) {\n- 244 size_type i=nblocks;\n- 245 while (i)\n- 246 block[--i].~window_type();\n- 247 windowAllocator_.deallocate(block,nblocks);\n+ 214 // create row\n+ 215 for (mapiterator ik=rowpattern.begin(); ik!=rowpattern.end(); ++ik)\n+ 216 ci.insert((*ik).first);\n+ 217 ++ci; // now row i exist\n+ 218\n+ 219 // write generation index into entries\n+ 220 coliterator endILUij = ILU[i.index()].end();;\n+ 221 for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)\n+ 222 Simd::lane(0, firstMatrixElement(*ILUij)) = (Simd::Scalar) rowpattern\n+[ILUij.index()];\n+ 223 }\n+ 224\n+ 225 // copy entries of A\n+ 226 for (crowiterator i=A.begin(); i!=endi; ++i)\n+ 227 {\n+ 228 coliterator ILUij;\n+ 229 coliterator endILUij = ILU[i.index()].end();;\n+ 230 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)\n+ 231 (*ILUij) = 0; // clear row\n+ 232 ccoliterator Aij = (*i).begin();\n+ 233 ccoliterator endAij = (*i).end();\n+ 234 ILUij = ILU[i.index()].begin();\n+ 235 while (Aij!=endAij && ILUij!=endILUij)\n+ 236 {\n+ 237 if (Aij.index()==ILUij.index())\n+ 238 {\n+ 239 *ILUij = *Aij;\n+ 240 ++Aij; ++ILUij;\n+ 241 }\n+ 242 else\n+ 243 {\n+ 244 if (Aij.index()n = 0;\n- 250 this->p = nullptr;\n+ 249 }\n+ 250 }\n 251\n- 252 // we can allocate the windows now\n- 253 nblocks = _nblocks;\n- 254 if (nblocks>0)\n- 255 {\n- 256 block = windowAllocator_.allocate(nblocks);\n- 257 new (block) window_type[nblocks];\n- 258 }\n- 259 else\n- 260 {\n- 261 nblocks = 0;\n- 262 block = nullptr;\n- 263 }\n+ 252 // call decomposition on pattern\n+ 253 blockILU0Decomposition(ILU);\n+ 254 }\n+ 255\n+ 257 template >\n+258 struct CRS\n+ 259 {\n+260 typedef B block_type;\n+261 typedef size_t size_type;\n+ 262\n+263 CRS() : nRows_( 0 ) {}\n 264\n- 265 // and the vector not fully usable\n- 266 initialized = false;\n- 267 }\n- 268\n-270 void resize (size_type _nblocks, size_type m)\n- 271 {\n- 272 // deconstruct objects and deallocate memory if necessary\n- 273 if (this->n>0) {\n- 274 size_type i=this->n;\n- 275 while (i)\n- 276 this->p[--i].~B();\n- 277 allocator_.deallocate(this->p,this->n);\n- 278 }\n- 279 if (nblocks>0) {\n- 280 size_type i=nblocks;\n- 281 while (i)\n- 282 block[--i].~window_type();\n- 283 windowAllocator_.deallocate(block,nblocks);\n- 284 }\n- 285\n- 286 // and we can allocate the big array in the base class\n- 287 this->n = _nblocks*m;\n- 288 if (this->n>0)\n- 289 {\n- 290 this->p = allocator_.allocate(this->n);\n- 291 new (this->p)B[this->n];\n- 292 }\n- 293 else\n+265 size_type rows() const { return nRows_; }\n+ 266\n+267 size_type nonZeros() const\n+ 268 {\n+ 269 assert( rows_[ rows() ] != size_type(-1) );\n+ 270 return rows_[ rows() ];\n+ 271 }\n+ 272\n+273 void resize( const size_type nRows )\n+ 274 {\n+ 275 if( nRows_ != nRows )\n+ 276 {\n+ 277 nRows_ = nRows ;\n+ 278 rows_.resize( nRows_+1, size_type(-1) );\n+ 279 }\n+ 280 }\n+ 281\n+282 void reserveAdditional( const size_type nonZeros )\n+ 283 {\n+ 284 const size_type needed = values_.size() + nonZeros ;\n+ 285 if( values_.capacity() < needed )\n+ 286 {\n+ 287 const size_type estimate = needed * 1.1;\n+ 288 values_.reserve( estimate );\n+ 289 cols_.reserve( estimate );\n+ 290 }\n+ 291 }\n+ 292\n+293 void push_back( const block_type& value, const size_type index )\n 294 {\n- 295 this->n = 0;\n- 296 this->p = nullptr;\n+ 295 values_.push_back( value );\n+ 296 cols_.push_back( index );\n 297 }\n 298\n- 299 // we can allocate the windows now\n- 300 nblocks = _nblocks;\n- 301 if (nblocks>0)\n- 302 {\n- 303 // allocate and construct objects\n- 304 block = windowAllocator_.allocate(nblocks);\n- 305 new (block) window_type[nblocks];\n- 306\n- 307 // set the windows into the big array\n- 308 for (size_type i=0; ip+(i*m));\n- 310 }\n- 311 else\n- 312 {\n- 313 nblocks = 0;\n- 314 block = nullptr;\n- 315 }\n- 316\n- 317 // and the vector is usable\n- 318 initialized = true;\n- 319 }\n- 320\n-322 VariableBlockVector& operator=(const VariableBlockVector& a)\n- 323 {\n- 324 if (&a!=this) // check if this and a are different objects\n- 325 {\n- 326 // reallocate arrays if necessary\n- 327 // Note: still the block sizes may vary !\n- 328 if (this->n!=a.n || nblocks!=a.nblocks)\n- 329 {\n- 330 // deconstruct objects and deallocate memory if necessary\n- 331 if (this->n>0) {\n- 332 size_type i=this->n;\n- 333 while (i)\n- 334 this->p[--i].~B();\n- 335 allocator_.deallocate(this->p,this->n);\n- 336 }\n- 337 if (nblocks>0) {\n- 338 size_type i=nblocks;\n- 339 while (i)\n- 340 block[--i].~window_type();\n- 341 windowAllocator_.deallocate(block,nblocks);\n- 342 }\n+299 std::vector< size_type > rows_;\n+300 std::vector< block_type, Alloc> values_;\n+301 std::vector< size_type > cols_;\n+302 size_type nRows_;\n+ 303 };\n+ 304\n+ 306 template\n+307 void convertToCRS(const M& A, CRS& lower, CRS& upper, InvVector& inv )\n+ 308 {\n+ 309 typedef typename M :: size_type size_type;\n+ 310\n+ 311 lower.resize( A.N() );\n+ 312 upper.resize( A.N() );\n+ 313 inv.resize( A.N() );\n+ 314\n+ 315 // lower and upper triangular should store half of non zeros minus\n+diagonal\n+ 316 const size_t memEstimate = (A.nonzeroes() - A.N())/2;\n+ 317\n+ 318 assert( A.nonzeroes() != 0 );\n+ 319 lower.reserveAdditional( memEstimate );\n+ 320 upper.reserveAdditional( memEstimate );\n+ 321\n+ 322 const auto endi = A.end();\n+ 323 size_type row = 0;\n+ 324 size_type colcount = 0;\n+ 325 lower.rows_[ 0 ] = colcount;\n+ 326 for (auto i=A.begin(); i!=endi; ++i, ++row)\n+ 327 {\n+ 328 const size_type iIndex = i.index();\n+ 329\n+ 330 // store entries left of diagonal\n+ 331 for (auto j=(*i).begin(); j.index() < iIndex; ++j )\n+ 332 {\n+ 333 lower.push_back( (*j), j.index() );\n+ 334 ++colcount;\n+ 335 }\n+ 336 lower.rows_[ iIndex+1 ] = colcount;\n+ 337 }\n+ 338\n+ 339 const auto rendi = A.beforeBegin();\n+ 340 row = 0;\n+ 341 colcount = 0;\n+ 342 upper.rows_[ 0 ] = colcount ;\n 343\n- 344 // allocate the big array in the base class\n- 345 this->n = a.n;\n- 346 if (this->n>0)\n+ 344 // NOTE: upper and inv store entries in reverse row and col order,\n+ 345 // reverse here relative to ILU\n+ 346 for (auto i=A.beforeEnd(); i!=rendi; --i, ++ row )\n 347 {\n- 348 // allocate and construct objects\n- 349 this->p = allocator_.allocate(this->n);\n- 350 new (this->p)B[this->n];\n- 351 }\n- 352 else\n- 353 {\n- 354 this->n = 0;\n- 355 this->p = nullptr;\n- 356 }\n- 357\n- 358 // we can allocate the windows now\n- 359 nblocks = a.nblocks;\n- 360 if (nblocks>0)\n- 361 {\n- 362 // alloc\n- 363 block = windowAllocator_.allocate(nblocks);\n- 364 new (block) window_type[nblocks];\n+ 348 const auto endij=(*i).beforeBegin(); // end of row i\n+ 349\n+ 350 const size_type iIndex = i.index();\n+ 351\n+ 352 // store in reverse row order for faster access during backsolve\n+ 353 for (auto j=(*i).beforeEnd(); j != endij; --j )\n+ 354 {\n+ 355 const size_type jIndex = j.index();\n+ 356 if( j.index() == iIndex )\n+ 357 {\n+ 358 inv[ row ] = (*j);\n+ 359 break; // assuming consecutive ordering of A\n+ 360 }\n+ 361 else if ( j.index() >= i.index() )\n+ 362 {\n+ 363 upper.push_back( (*j), jIndex );\n+ 364 ++colcount ;\n 365 }\n- 366 else\n- 367 {\n- 368 nblocks = 0;\n- 369 block = nullptr;\n- 370 }\n- 371 }\n- 372\n- 373 // copy block structure, might be different although\n- 374 // sizes are the same !\n- 375 if (nblocks>0)\n- 376 {\n- 377 block[0].set(a.block[0].getsize(),this->p); // first block\n- 378 for (size_type i=1; in; i++) this->p[i]=a.p[i];\n- 384 }\n- 385\n- 386 // and we have a usable vector\n- 387 initialized = true;\n- 388\n- 389 return *this; // Gebe Referenz zurueck damit a=b=c; klappt\n- 390 }\n- 391\n- 392\n- 393 //===== assignment from scalar\n- 394\n-396 VariableBlockVector& operator=(const field_type& k)\n- 397 {\n- 398 (static_cast&>(*this)) = k;\n- 399 return *this;\n- 400 }\n- 401\n- 402\n- 403 //===== the creation interface\n- 404\n- 405 class CreateIterator;\n- 406\n- 407#ifndef DOXYGEN\n- 408\n- 409 // The window_type does not hand out a reference to its size,\n- 410 // so in order to provide a valid iterator, we need a workaround\n- 411 // to make assignment possible. This proxy enables just that by\n- 412 // implicitly converting to the stored size for read access and\n- 413 // tunneling assignment to the accessor method of the window.\n- 414 struct SizeProxy\n- 415 {\n- 416\n- 417 operator size_type() const\n- 418 {\n- 419 return target->getsize();\n- 420 }\n- 421\n- 422 SizeProxy& operator=(size_type size)\n- 423 {\n- 424 target->setsize(size);\n- 425 return *this;\n- 426 }\n- 427\n- 428 private:\n- 429\n- 430 friend class CreateIterator;\n- 431\n- 432 SizeProxy(window_type& t)\n- 433 : target(&t)\n- 434 {}\n- 435\n- 436 window_type* target;\n- 437 };\n- 438\n- 439#endif // DOXYGEN\n- 440\n-442 class CreateIterator\n- 443 {\n- 444 public:\n-446 using iterator_category = std::output_iterator_tag;\n- 447\n-449 using value_type = size_type;\n- 450\n-457 using difference_type = void;\n- 458\n-460 using pointer = size_type*;\n- 461\n-463 using reference = SizeProxy;\n- 464\n-466 CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :\n- 467 v(_v),\n- 468 i(_i),\n- 469 isEnd(_isEnd) {}\n- 470\n-471 ~CreateIterator() {\n- 472 // When the iterator gets destructed, we allocate the memory\n- 473 // for the VariableBlockVector if\n- 474 // 1. the current iterator was not created as enditerator\n- 475 // 2. we're at the last block\n- 476 // 3. the vector hasn't been initialized earlier\n- 477 if (not isEnd && i==v.nblocks && not v.initialized)\n- 478 v.allocate();\n- 479 }\n- 480\n-482 CreateIterator& operator++()\n- 483 {\n- 484 // go to next block\n- 485 ++i;\n- 486\n- 487 return *this;\n- 488 }\n- 489\n-491 CreateIterator operator++(int)\n- 492 {\n- 493 CreateIterator tmp(*this);\n- 494 this->operator++();\n- 495 return tmp;\n- 496 }\n- 497\n-499 bool operator!=(const CreateIterator& it) const\n- 500 {\n- 501 return (i!=it.i) || (&v!=&it.v);\n- 502 }\n- 503\n-505 bool operator==(const CreateIterator& it) const\n- 506 {\n- 507 return (i==it.i) && (&v==&it.v);\n- 508 }\n- 509\n-511 size_type index () const\n- 512 {\n- 513 return i;\n- 514 }\n- 515\n-517 void setblocksize (size_type _k)\n- 518 {\n- 519 v.block[i].setsize(_k);\n- 520 }\n- 521\n- 523#ifdef DOXYGEN\n- 524 size_type&\n- 525#else\n- 526 SizeProxy\n- 527#endif\n-528 operator*()\n- 529 {\n- 530 return {v.block[i]};\n- 531 }\n- 532\n- 533 private:\n- 534 VariableBlockVector& v; // my vector\n- 535 size_type i; // current block to be defined\n- 536 const bool isEnd; // flag if this object was created as the end iterator.\n- 537 };\n- 538\n- 539 // CreateIterator wants to set all the arrays ...\n-540 friend class CreateIterator;\n- 541\n-543 CreateIterator createbegin ()\n- 544 {\n- 545#ifdef DUNE_ISTL_WITH_CHECKING\n- 546 if (initialized) DUNE_THROW(ISTLError,\"no CreateIterator in initialized\n-state\");\n- 547#endif\n- 548 return CreateIterator(*this,0, false);\n- 549 }\n- 550\n-552 CreateIterator createend ()\n- 553 {\n- 554 return CreateIterator(*this,nblocks, true);\n- 555 }\n- 556\n- 557\n- 558 //===== access to components\n- 559 // has to be overwritten from base class because it must\n- 560 // return access to the windows\n- 561\n-563 window_type& operator[](size_type i)\n- 564 {\n- 565#ifdef DUNE_ISTL_WITH_CHECKING\n- 566 if (i>=nblocks) DUNE_THROW(ISTLError,\"index out of range\");\n- 567#endif\n- 568 return block[i];\n- 569 }\n- 570\n-572 const window_type& operator[](size_type i) const\n- 573 {\n- 574#ifdef DUNE_ISTL_WITH_CHECKING\n- 575 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,\"index out of range\");\n- 576#endif\n- 577 return block[i];\n- 578 }\n- 579\n- 581 template \n-582 class RealIterator\n- 583 : public RandomAccessIteratorFacade, T, R>\n- 584 {\n- 585 public:\n-587 RealIterator ()\n- 588 {\n- 589 p = nullptr;\n- 590 i = 0;\n- 591 }\n- 592\n-594 RealIterator (window_type* _p, size_type _i)\n- 595 : p(_p), i(_i)\n- 596 {}\n- 597\n-599 void increment()\n- 600 {\n- 601 ++i;\n- 602 }\n- 603\n-605 void decrement()\n- 606 {\n- 607 --i;\n- 608 }\n- 609\n-611 bool equals (const RealIterator& it) const\n- 612 {\n- 613 return (p+i)==(it.p+it.i);\n- 614 }\n- 615\n-617 window_type& dereference () const\n- 618 {\n- 619 return p[i];\n- 620 }\n- 621\n-622 void advance(std::ptrdiff_t d)\n- 623 {\n- 624 i+=d;\n- 625 }\n- 626\n-627 std::ptrdiff_t distanceTo(const RealIterator& o) const\n- 628 {\n- 629 return o.i-i;\n- 630 }\n- 631\n- 632 // Needed for operator[] of the iterator\n-633 window_type& elementAt (std::ptrdiff_t offset) const\n- 634 {\n- 635 return p[i+offset];\n- 636 }\n- 637\n-639 size_type index() const\n- 640 {\n- 641 return i;\n- 642 }\n- 643\n- 644 private:\n- 645 window_type* p;\n- 646 size_type i;\n- 647 };\n- 648\n-649 using Iterator = RealIterator;\n- 650\n-652 Iterator begin ()\n- 653 {\n- 654 return Iterator(block,0);\n- 655 }\n- 656\n-658 Iterator end ()\n- 659 {\n- 660 return Iterator(block,nblocks);\n- 661 }\n- 662\n-665 Iterator beforeEnd ()\n- 666 {\n- 667 return Iterator(block,nblocks-1);\n- 668 }\n- 669\n-672 Iterator beforeBegin () const\n- 673 {\n- 674 return Iterator(block,-1);\n- 675 }\n- 676\n-678 using iterator = Iterator;\n- 679\n-681 using ConstIterator = RealIterator;\n- 682\n-684 using const_iterator = ConstIterator;\n- 685\n-687 ConstIterator begin () const\n- 688 {\n- 689 return ConstIterator(block,0);\n- 690 }\n- 691\n-693 ConstIterator end () const\n- 694 {\n- 695 return ConstIterator(block,nblocks);\n- 696 }\n- 697\n-700 ConstIterator beforeEnd() const\n- 701 {\n- 702 return ConstIterator(block,nblocks-1);\n- 703 }\n- 704\n-706 ConstIterator rend () const\n- 707 {\n- 708 return ConstIterator(block,-1);\n- 709 }\n- 710\n-712 Iterator find (size_type i)\n- 713 {\n- 714 return Iterator(block,std::min(i,nblocks));\n- 715 }\n- 716\n-718 ConstIterator find (size_type i) const\n- 719 {\n- 720 return ConstIterator(block,std::min(i,nblocks));\n- 721 }\n- 722\n- 723 //===== sizes\n- 724\n-726 size_type N () const\n- 727 {\n- 728 return nblocks;\n- 729 }\n- 730\n-735 size_type size () const\n- 736 {\n- 737 return nblocks;\n- 738 }\n- 739\n- 740\n- 741 private:\n- 742\n- 743 void allocate() {\n- 744 if (this->initialized)\n- 745 DUNE_THROW(ISTLError, \"Attempt to re-allocate already initialized\n-VariableBlockVector\");\n- 746\n- 747 // calculate space needed:\n- 748 this->n=0;\n- 749 for(size_type i = 0; i < nblocks; i++) {\n- 750 this->n += block[i].size();\n- 751 }\n- 752\n- 753 // now we can allocate the big array in the base class of v\n- 754 if (this->n>0)\n- 755 {\n- 756 // allocate and construct objects\n- 757 this->p = allocator_.allocate(this->n);\n- 758 new (this->p)B[this->n];\n- 759 }\n- 760 else\n- 761 {\n- 762 this->p = nullptr;\n- 763 }\n- 764\n- 765 // and we set the window pointers\n- 766 this->block[0].setptr(this->p); // pointer to first block\n- 767 for (size_type j=1; jinitialized = true;\n- 772 }\n- 773\n- 774 size_type nblocks; // number of blocks in vector\n- 775 window_type* block; // array of blocks pointing to the array in the base\n-class\n- 776 bool initialized; // true if vector has been initialized\n- 777\n- 778 A allocator_;\n- 779\n- 780 typename std::allocator_traits::template rebind_alloc\n-windowAllocator_;\n- 781 };\n- 782\n- 783\n- 784\n- 787} // end namespace\n- 788\n- 789#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n-bvector.hh\n-This file implements a vector space as a tensor product of a given vector\n-space. The number of compon...\n+ 366 }\n+ 367 upper.rows_[ row+1 ] = colcount;\n+ 368 }\n+ 369 } // end convertToCRS\n+ 370\n+ 372 template\n+373 void blockILUBacksolve (const CRS& lower,\n+ 374 const CRS& upper,\n+ 375 const InvVector& inv,\n+ 376 X& v, const Y& d)\n+ 377 {\n+ 378 // iterator types\n+ 379 typedef typename Y :: block_type dblock;\n+ 380 typedef typename X :: block_type vblock;\n+ 381 typedef typename X :: size_type size_type ;\n+ 382\n+ 383 const size_type iEnd = lower.rows();\n+ 384 const size_type lastRow = iEnd - 1;\n+ 385 if( iEnd != upper.rows() )\n+ 386 {\n+ 387 DUNE_THROW(ISTLError,\"ILU::blockILUBacksolve: lower and upper rows must be\n+the same\");\n+ 388 }\n+ 389\n+ 390 // lower triangular solve\n+ 391 for( size_type i=0; i::value > *sfinae=nullptr)\n+Definition: ilu.hh:141\n+Dune::ILU::blockILU0Decomposition\n+void blockILU0Decomposition(M &A)\n+compute ILU decomposition of A. A is overwritten by its decomposition\n+Definition: ilu.hh:33\n+Dune::ILU::blockILUDecomposition\n+void blockILUDecomposition(const M &A, int n, M &ILU)\n+Definition: ilu.hh:167\n+Dune::ILU::CRS\n+a simple compressed row storage matrix class\n+Definition: ilu.hh:259\n+Dune::ILU::CRS::cols_\n+std::vector< size_type > cols_\n+Definition: ilu.hh:301\n+Dune::ILU::CRS::nonZeros\n+size_type nonZeros() const\n+Definition: ilu.hh:267\n+Dune::ILU::CRS::resize\n+void resize(const size_type nRows)\n+Definition: ilu.hh:273\n+Dune::ILU::CRS::rows\n+size_type rows() const\n+Definition: ilu.hh:265\n+Dune::ILU::CRS::CRS\n+CRS()\n+Definition: ilu.hh:263\n+Dune::ILU::CRS::reserveAdditional\n+void reserveAdditional(const size_type nonZeros)\n+Definition: ilu.hh:282\n+Dune::ILU::CRS::block_type\n+B block_type\n+Definition: ilu.hh:260\n+Dune::ILU::CRS::values_\n+std::vector< block_type, Alloc > values_\n+Definition: ilu.hh:300\n+Dune::ILU::CRS::nRows_\n+size_type nRows_\n+Definition: ilu.hh:302\n+Dune::ILU::CRS::size_type\n+size_t size_type\n+Definition: ilu.hh:261\n+Dune::ILU::CRS::rows_\n+std::vector< size_type > rows_\n+Definition: ilu.hh:299\n+Dune::ILU::CRS::push_back\n+void push_back(const block_type &value, const size_type index)\n+Definition: ilu.hh:293\n Dune::ISTLError\n derive error class from the base class in common\n Definition: istlexception.hh:19\n-Dune::VariableBlockVector\n-A Vector of blocks with different blocksizes.\n-Definition: vbvector.hh:46\n-Dune::VariableBlockVector::Iterator\n-RealIterator< value_type, window_type & > Iterator\n-Definition: vbvector.hh:649\n-Dune::VariableBlockVector::VariableBlockVector\n-VariableBlockVector()\n-Definition: vbvector.hh:97\n-Dune::VariableBlockVector::CreateIterator\n-friend class CreateIterator\n-Definition: vbvector.hh:540\n-Dune::VariableBlockVector::field_type\n-typename Imp::BlockTraits< B >::field_type field_type\n-export the type representing the field\n-Definition: vbvector.hh:55\n-Dune::VariableBlockVector::allocator_type\n-A allocator_type\n-export the allocator type\n-Definition: vbvector.hh:58\n-Dune::VariableBlockVector::VariableBlockVector\n-VariableBlockVector(size_type _nblocks, size_type m)\n-Definition: vbvector.hh:134\n-Dune::VariableBlockVector::size\n-size_type size() const\n-Definition: vbvector.hh:735\n-Dune::VariableBlockVector::N\n-size_type N() const\n-number of blocks in the vector (are of variable size here)\n-Definition: vbvector.hh:726\n-Dune::VariableBlockVector::VariableBlockVector\n-VariableBlockVector(const VariableBlockVector &a)\n-copy constructor, has copy semantics\n-Definition: vbvector.hh:172\n-Dune::VariableBlockVector::VariableBlockVector\n-VariableBlockVector(size_type _nblocks)\n-Definition: vbvector.hh:108\n-Dune::VariableBlockVector::~VariableBlockVector\n-~VariableBlockVector()\n-free dynamic memory\n-Definition: vbvector.hh:215\n-Dune::VariableBlockVector::operator[]\n-window_type & operator[](size_type i)\n-random access to blocks\n-Definition: vbvector.hh:563\n-Dune::VariableBlockVector::createend\n-CreateIterator createend()\n-get create iterator pointing to one after the last block\n-Definition: vbvector.hh:552\n-Dune::VariableBlockVector::beforeBegin\n-Iterator beforeBegin() const\n-Definition: vbvector.hh:672\n-Dune::VariableBlockVector::createbegin\n-CreateIterator createbegin()\n-get initial create iterator\n-Definition: vbvector.hh:543\n-Dune::VariableBlockVector::operator=\n-VariableBlockVector & operator=(const VariableBlockVector &a)\n-assignment\n-Definition: vbvector.hh:322\n-Dune::VariableBlockVector::blocklevel\n-static constexpr auto blocklevel\n-Definition: vbvector.hh:90\n-Dune::VariableBlockVector::rend\n-ConstIterator rend() const\n-end ConstIterator\n-Definition: vbvector.hh:706\n-Dune::VariableBlockVector::size_type\n-A::size_type size_type\n-The size type for the index access.\n-Definition: vbvector.hh:73\n-Dune::VariableBlockVector::find\n-ConstIterator find(size_type i) const\n-random access returning iterator (end if not contained)\n-Definition: vbvector.hh:718\n-Dune::VariableBlockVector::beforeEnd\n-ConstIterator beforeEnd() const\n-Definition: vbvector.hh:700\n-Dune::VariableBlockVector::find\n-Iterator find(size_type i)\n-random access returning iterator (end if not contained)\n-Definition: vbvector.hh:712\n-Dune::VariableBlockVector::const_reference\n-const window_type & const_reference\n-Export type used for const references to container entries.\n-Definition: vbvector.hh:70\n-Dune::VariableBlockVector::ConstIterator\n-RealIterator< const value_type, const window_type & > ConstIterator\n-Const iterator.\n-Definition: vbvector.hh:681\n-Dune::VariableBlockVector::end\n-Iterator end()\n-end Iterator\n-Definition: vbvector.hh:658\n-Dune::VariableBlockVector::begin\n-ConstIterator begin() const\n-begin ConstIterator\n-Definition: vbvector.hh:687\n-Dune::VariableBlockVector::value_type\n-BlockVector< B, A > value_type\n-Type of the elements of the outer vector, i.e., dynamic vectors of B.\n-Definition: vbvector.hh:80\n-Dune::VariableBlockVector::end\n-ConstIterator end() const\n-end ConstIterator\n-Definition: vbvector.hh:693\n-Dune::VariableBlockVector::block_type\n-BlockVector< B, A > block_type\n-Same as value_type, here for historical reasons.\n-Definition: vbvector.hh:84\n-Dune::VariableBlockVector::resize\n-void resize(size_type _nblocks, size_type m)\n-same effect as constructor with same argument\n-Definition: vbvector.hh:270\n-Dune::VariableBlockVector::reference\n-window_type & reference\n-Export type used for references to container entries.\n-Definition: vbvector.hh:64\n-Dune::VariableBlockVector::resize\n-void resize(size_type _nblocks)\n-same effect as constructor with same argument\n-Definition: vbvector.hh:234\n-Dune::VariableBlockVector::beforeEnd\n-Iterator beforeEnd()\n-Definition: vbvector.hh:665\n-Dune::VariableBlockVector::begin\n-Iterator begin()\n-begin Iterator\n-Definition: vbvector.hh:652\n-Dune::VariableBlockVector::CreateIterator\n-Iterator class for sequential creation of blocks.\n-Definition: vbvector.hh:443\n-Dune::VariableBlockVector::CreateIterator::operator==\n-bool operator==(const CreateIterator &it) const\n-equality\n-Definition: vbvector.hh:505\n-Dune::VariableBlockVector::CreateIterator::index\n-size_type index() const\n-dereferencing\n-Definition: vbvector.hh:511\n-Dune::VariableBlockVector::CreateIterator::reference\n-SizeProxy reference\n-reference type\n-Definition: vbvector.hh:463\n-Dune::VariableBlockVector::CreateIterator::pointer\n-size_type * pointer\n-pointer type\n-Definition: vbvector.hh:460\n-Dune::VariableBlockVector::CreateIterator::operator!=\n-bool operator!=(const CreateIterator &it) const\n-inequality\n-Definition: vbvector.hh:499\n-Dune::VariableBlockVector::CreateIterator::~CreateIterator\n-~CreateIterator()\n-Definition: vbvector.hh:471\n-Dune::VariableBlockVector::CreateIterator::value_type\n-size_type value_type\n-value type\n-Definition: vbvector.hh:449\n-Dune::VariableBlockVector::CreateIterator::CreateIterator\n-CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)\n-constructor\n-Definition: vbvector.hh:466\n-Dune::VariableBlockVector::CreateIterator::setblocksize\n-void setblocksize(size_type _k)\n-set size of current block\n-Definition: vbvector.hh:517\n-Dune::VariableBlockVector::CreateIterator::operator*\n-size_type & operator*()\n-Access size of current block.\n-Definition: vbvector.hh:528\n-Dune::VariableBlockVector::CreateIterator::iterator_category\n-std::output_iterator_tag iterator_category\n-iterator category\n-Definition: vbvector.hh:446\n-Dune::VariableBlockVector::CreateIterator::operator++\n-CreateIterator & operator++()\n-prefix increment\n-Definition: vbvector.hh:482\n-Dune::VariableBlockVector::CreateIterator::difference_type\n-void difference_type\n-difference type (unused)\n-Definition: vbvector.hh:457\n-Dune::VariableBlockVector::RealIterator\n-Iterator class for sequential access.\n-Definition: vbvector.hh:584\n-Dune::VariableBlockVector::RealIterator::RealIterator\n-RealIterator(window_type *_p, size_type _i)\n-constructor\n-Definition: vbvector.hh:594\n-Dune::VariableBlockVector::RealIterator::equals\n-bool equals(const RealIterator &it) const\n-equality\n-Definition: vbvector.hh:611\n-Dune::VariableBlockVector::RealIterator::index\n-size_type index() const\n-Return the index of the entry this iterator is pointing to.\n-Definition: vbvector.hh:639\n-Dune::VariableBlockVector::RealIterator::elementAt\n-window_type & elementAt(std::ptrdiff_t offset) const\n-Definition: vbvector.hh:633\n-Dune::VariableBlockVector::RealIterator::decrement\n-void decrement()\n-prefix decrement\n-Definition: vbvector.hh:605\n-Dune::VariableBlockVector::RealIterator::advance\n-void advance(std::ptrdiff_t d)\n-Definition: vbvector.hh:622\n-Dune::VariableBlockVector::RealIterator::increment\n-void increment()\n-prefix increment\n-Definition: vbvector.hh:599\n-Dune::VariableBlockVector::RealIterator::RealIterator\n-RealIterator()\n-constructor, no arguments\n-Definition: vbvector.hh:587\n-Dune::VariableBlockVector::RealIterator::distanceTo\n-std::ptrdiff_t distanceTo(const RealIterator &o) const\n-Definition: vbvector.hh:627\n-Dune::VariableBlockVector::RealIterator::dereference\n-window_type & dereference() const\n-dereferencing\n-Definition: vbvector.hh:617\n+Dune::MatrixBlockError\n+Error when performing an operation on a matrix block.\n+Definition: istlexception.hh:52\n+Dune::MatrixBlockError::r\n+int r\n+Definition: istlexception.hh:54\n+Dune::FieldMatrix\n+Definition: matrixutils.hh:27\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00221.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00221.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: io.hh File Reference\n+dune-istl: preconditioners.hh File Reference\n \n \n \n \n \n \n \n@@ -65,105 +65,98 @@\n
  • dune
  • istl
  • \n \n \n \n
    \n \n-

    Some generic functions for pretty printing vectors and matrices. \n+

    Define general preconditioner interface. \n More...

    \n
    #include <cmath>
    \n #include <complex>
    \n-#include <limits>
    \n-#include <ios>
    \n+#include <iostream>
    \n #include <iomanip>
    \n-#include <fstream>
    \n+#include <memory>
    \n #include <string>
    \n-#include "matrixutils.hh"
    \n-#include "istlexception.hh"
    \n-#include <dune/common/fvector.hh>
    \n-#include <dune/common/fmatrix.hh>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include <dune/common/reservedvector.hh>
    \n-#include <dune/istl/bcrsmatrix.hh>
    \n-#include <dune/istl/blocklevel.hh>
    \n+#include <dune/common/simd/simd.hh>
    \n+#include <dune/common/parametertree.hh>
    \n+#include <dune/istl/solverregistry.hh>
    \n+#include "preconditioner.hh"
    \n+#include "solver.hh"
    \n+#include "solvercategory.hh"
    \n+#include "istlexception.hh"
    \n+#include "matrixutils.hh"
    \n+#include "gsetc.hh"
    \n+#include "ildl.hh"
    \n+#include "ilu.hh"
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n

    \n Classes

    struct  Dune::DefaultSVGMatrixOptions
     Default options class to write SVG matrices. More...
    class  Dune::InverseOperator2Preconditioner< O, c >
     Turns an InverseOperator into a Preconditioner. More...
     
    class  Dune::SeqSSOR< M, X, Y, l >
     Sequential SSOR preconditioner. More...
     
    class  Dune::SeqSOR< M, X, Y, l >
     Sequential SOR preconditioner. More...
     
    class  Dune::SeqJac< M, X, Y, l >
     The sequential jacobian preconditioner. More...
     
    class  Dune::SeqILU< M, X, Y, l >
     Sequential ILU preconditioner. More...
     
    class  Dune::Richardson< X, Y >
     Richardson preconditioner. More...
     
    class  Dune::SeqILDL< M, X, Y >
     sequential ILDL preconditioner More...
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    \n+\n+\n+\n+\n+\n+

    \n+Typedefs

    template<class M , class X , class Y , int l = 1>
    using Dune::SeqGS = SeqSOR< M, X, Y, l >
     Sequential Gauss Seidel preconditioner. More...
     
    \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n

    \n Functions

    template<class V >
    void Dune::recursive_printvector (std::ostream &s, const V &v, std::string rowtext, int &counter, int columns, int width)
     Recursively print a vector. More...
     
    template<class V >
    void Dune::printvector (std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
     Print an ISTL vector. More...
     
    void Dune::fill_row (std::ostream &s, int m, int width, int precision)
     Print a row of zeros for a non-existing block. More...
     
    template<class K >
    void Dune::print_row (std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
     Print one row of a matrix, specialization for number types. More...
     
    template<class M >
    void Dune::print_row (std::ostream &s, const M &A, typename M::size_type I, typename M::size_type J, typename M::size_type therow, int width, int precision, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
     Print one row of a matrix. More...
     
    template<class M >
    void Dune::printmatrix (std::ostream &s, const M &A, std::string title, std::string rowtext, int width=10, int precision=2)
     Print a generic block matrix. More...
     
    template<class B , int n, int m, class A >
    void Dune::printSparseMatrix (std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3, int precision=2)
     Prints a BCRSMatrix with fixed sized blocks. More...
     
    template<class FieldType >
    void Dune::writeMatrixToMatlabHelper (const FieldType &value, int rowOffset, int colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber< FieldType >::value > *sfinae=nullptr)
     Helper method for the writeMatrixToMatlab routine. More...
     
    template<class MatrixType >
    void Dune::writeMatrixToMatlabHelper (const MatrixType &matrix, int externalRowOffset, int externalColOffset, std::ostream &s, typename std::enable_if_t<!Dune::IsNumber< MatrixType >::value > *sfinae=nullptr)
     Helper method for the writeMatrixToMatlab routine. More...
     
    template<class MatrixType >
    void Dune::writeMatrixToMatlab (const MatrixType &matrix, const std::string &filename, int outputPrecision=18)
     Writes sparse matrix in a Matlab-readable format. More...
     
    template<class V >
    void Dune::writeVectorToMatlabHelper (const V &v, std::ostream &stream)
     
    template<class VectorType >
    void Dune::writeVectorToMatlab (const VectorType &vector, const std::string &filename, int outputPrecision=18)
     Writes vectors in a Matlab-readable format. More...
     
    template<class Mat , class SVGOptions = DefaultSVGMatrixOptions>
    void Dune::writeSVGMatrix (const Mat &mat, std::ostream &out, SVGOptions opts={})
     Writes the visualization of matrix in the SVG format. More...
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("ssor", defaultPreconditionerBlockLevelCreator< Dune::SeqSSOR >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("sor", defaultPreconditionerBlockLevelCreator< Dune::SeqSOR >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("gs", defaultPreconditionerBlockLevelCreator< Dune::SeqGS >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("jac", defaultPreconditionerBlockLevelCreator< Dune::SeqJac >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("ilu", defaultPreconditionerBlockLevelCreator< Dune::SeqILU >())
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("richardson", [](auto tl, const auto &, const ParameterTree &config){ using D=typename Dune::TypeListElement< 1, decltype(tl)>::type;using R=typename Dune::TypeListElement< 2, decltype(tl)>::type;return std::make_shared< Richardson< D, R > >(config);})
     
     Dune::DUNE_REGISTER_PRECONDITIONER ("ildl", defaultPreconditionerCreator< Dune::SeqILDL >())
     
    \n

    Detailed Description

    \n-

    Some generic functions for pretty printing vectors and matrices.

    \n+

    Define general preconditioner interface.

    \n+

    Wrap the methods implemented by ISTL in this interface. However, the interface is extensible such that new preconditioners can be implemented and used with the solvers.

    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,110 +4,91 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Functions\n-io.hh File Reference\n-Iterative_Solvers_Template_Library_(ISTL) \u00bb Sparse_Matrix_and_Vector_classes \u00bb\n-IO_for_matrices_and_vectors.\n-Some generic functions for pretty printing vectors and matrices. More...\n+Classes | Namespaces | Typedefs | Functions\n+preconditioners.hh File Reference\n+Iterative_Solvers_Template_Library_(ISTL) \u00bb Iterative_Solvers \u00bb Preconditioners\n+Define general preconditioner interface. More...\n #include \n #include \n-#include \n-#include \n+#include \n #include \n-#include \n+#include \n #include \n-#include \"matrixutils.hh\"\n+#include \n+#include \n+#include \n+#include \"preconditioner.hh\"\n+#include \"solver.hh\"\n+#include \"solvercategory.hh\"\n #include \"istlexception.hh\"\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n+#include \"matrixutils.hh\"\n+#include \"gsetc.hh\"\n+#include \"ildl.hh\"\n+#include \"ilu.hh\"\n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::DefaultSVGMatrixOptions\n-\u00a0 Default options class to write SVG matrices. More...\n+class \u00a0Dune::InverseOperator2Preconditioner<_O,_c_>\n+\u00a0 Turns an InverseOperator into a Preconditioner. More...\n+\u00a0\n+class \u00a0Dune::SeqSSOR<_M,_X,_Y,_l_>\n+\u00a0 Sequential SSOR preconditioner. More...\n+\u00a0\n+class \u00a0Dune::SeqSOR<_M,_X,_Y,_l_>\n+\u00a0 Sequential SOR preconditioner. More...\n+\u00a0\n+class \u00a0Dune::SeqJac<_M,_X,_Y,_l_>\n+\u00a0 The sequential jacobian preconditioner. More...\n+\u00a0\n+class \u00a0Dune::SeqILU<_M,_X,_Y,_l_>\n+\u00a0 Sequential ILU preconditioner. More...\n+\u00a0\n+class \u00a0Dune::Richardson<_X,_Y_>\n+\u00a0 Richardson preconditioner. More...\n+\u00a0\n+class \u00a0Dune::SeqILDL<_M,_X,_Y_>\n+\u00a0 sequential ILDL preconditioner More...\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n+ Typedefs\n+template\n+using\u00a0Dune::SeqGS = SeqSOR< M, X, Y, l >\n+\u00a0 Sequential Gauss Seidel preconditioner. More...\n+\u00a0\n Functions\n-template\n-void\u00a0Dune::recursive_printvector (std::ostream &s, const V &v, std::string\n- rowtext, int &counter, int columns, int width)\n-\u00a0 Recursively print a vector. More...\n-\u00a0\n-template\n-void\u00a0Dune::printvector (std::ostream &s, const V &v, std::string title, std::\n- string rowtext, int columns=1, int width=10, int precision=2)\n-\u00a0 Print an ISTL vector. More...\n-\u00a0\n-void\u00a0Dune::fill_row (std::ostream &s, int m, int width, int precision)\n-\u00a0 Print a row of zeros for a non-existing block. More...\n-\u00a0\n-template\n-void\u00a0Dune::print_row (std::ostream &s, const K &value, typename FieldMatrix<\n- K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J,\n- typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int\n- precision, typename std::enable_if_t< Dune::IsNumber< K >::value >\n- *sfinae=nullptr)\n-\u00a0 Print one row of a matrix, specialization for number types. More...\n-\u00a0\n-template\n-void\u00a0Dune::print_row (std::ostream &s, const M &A, typename M::size_type I,\n- typename M::size_type J, typename M::size_type therow, int width, int\n- precision, typename std::enable_if_t::value >\n- *sfinae=nullptr)\n-\u00a0 Print one row of a matrix. More...\n-\u00a0\n-template\n-void\u00a0Dune::printmatrix (std::ostream &s, const M &A, std::string title, std::\n- string rowtext, int width=10, int precision=2)\n-\u00a0 Print a generic block matrix. More...\n-\u00a0\n-template\n-void\u00a0Dune::printSparseMatrix (std::ostream &s, const BCRSMatrix< FieldMatrix<\n- B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3,\n- int precision=2)\n-\u00a0 Prints a BCRSMatrix with fixed sized blocks. More...\n-\u00a0\n-template\n-void\u00a0Dune::writeMatrixToMatlabHelper (const FieldType &value, int rowOffset,\n- int colOffset, std::ostream &s, typename std::enable_if_t< Dune::\n- IsNumber< FieldType >::value > *sfinae=nullptr)\n-\u00a0 Helper method for the writeMatrixToMatlab routine. More...\n-\u00a0\n-template\n-void\u00a0Dune::writeMatrixToMatlabHelper (const MatrixType &matrix, int\n- externalRowOffset, int externalColOffset, std::ostream &s, typename std::\n- enable_if_t::value > *sfinae=nullptr)\n-\u00a0 Helper method for the writeMatrixToMatlab routine. More...\n-\u00a0\n-template\n-void\u00a0Dune::writeMatrixToMatlab (const MatrixType &matrix, const std::string\n- &filename, int outputPrecision=18)\n-\u00a0 Writes sparse matrix in a Matlab-readable format. More...\n-\u00a0\n-template\n-void\u00a0Dune::writeVectorToMatlabHelper (const V &v, std::ostream &stream)\n-\u00a0\n-template\n-void\u00a0Dune::writeVectorToMatlab (const VectorType &vector, const std::string\n- &filename, int outputPrecision=18)\n-\u00a0 Writes vectors in a Matlab-readable format. More...\n-\u00a0\n-template\n-void\u00a0Dune::writeSVGMatrix (const Mat &mat, std::ostream &out, SVGOptions opts=\n- {})\n-\u00a0 Writes the visualization of matrix in the SVG format. More...\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ssor\",\n+ defaultPreconditionerBlockLevelCreator< Dune::SeqSSOR >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"sor\",\n+ defaultPreconditionerBlockLevelCreator< Dune::SeqSOR >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"gs\",\n+ defaultPreconditionerBlockLevelCreator< Dune::SeqGS >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"jac\",\n+ defaultPreconditionerBlockLevelCreator< Dune::SeqJac >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ilu\",\n+ defaultPreconditionerBlockLevelCreator< Dune::SeqILU >())\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"richardson\", [](auto tl, const auto &,\n+ const ParameterTree &config){ using D=typename Dune::TypeListElement< 1,\n+ decltype(tl)>::type;using R=typename Dune::TypeListElement< 2, decltype\n+ (tl)>::type;return std::make_shared< Richardson< D, R > >(config);})\n+\u00a0\n+\u00a0Dune::DUNE_REGISTER_PRECONDITIONER (\"ildl\", defaultPreconditionerCreator<\n+ Dune::SeqILDL >())\n \u00a0\n ***** Detailed Description *****\n-Some generic functions for pretty printing vectors and matrices.\n+Define general preconditioner interface.\n+Wrap the methods implemented by ISTL in this interface. However, the interface\n+is extensible such that new preconditioners can be implemented and used with\n+the solvers.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00221_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00221_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: io.hh Source File\n+dune-istl: preconditioners.hh Source File\n \n \n \n \n \n \n \n@@ -62,677 +62,630 @@\n \n
    \n \n
    \n
    \n
    \n-
    io.hh
    \n+
    preconditioners.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_IO_HH
    \n-
    6#define DUNE_ISTL_IO_HH
    \n+
    5#ifndef DUNE_ISTL_PRECONDITIONERS_HH
    \n+
    6#define DUNE_ISTL_PRECONDITIONERS_HH
    \n
    7
    \n
    8#include <cmath>
    \n
    9#include <complex>
    \n-
    10#include <limits>
    \n-
    11#include <ios>
    \n-
    12#include <iomanip>
    \n-
    13#include <fstream>
    \n-
    14#include <string>
    \n-
    15
    \n-
    16#include "matrixutils.hh"
    \n-
    17#include "istlexception.hh"
    \n-
    18#include <dune/common/fvector.hh>
    \n-
    19#include <dune/common/fmatrix.hh>
    \n-
    20#include <dune/common/hybridutilities.hh>
    \n-
    21#include <dune/common/reservedvector.hh>
    \n-
    22
    \n-\n-\n-
    25
    \n-
    26namespace Dune {
    \n+
    10#include <iostream>
    \n+
    11#include <iomanip>
    \n+
    12#include <memory>
    \n+
    13#include <string>
    \n+
    14
    \n+
    15#include <dune/common/simd/simd.hh>
    \n+
    16#include <dune/common/parametertree.hh>
    \n+
    17
    \n+\n+
    19#include "preconditioner.hh"
    \n+
    20#include "solver.hh"
    \n+
    21#include "solvercategory.hh"
    \n+
    22#include "istlexception.hh"
    \n+
    23#include "matrixutils.hh"
    \n+
    24#include "gsetc.hh"
    \n+
    25#include "ildl.hh"
    \n+
    26#include "ilu.hh"
    \n
    27
    \n-
    40 //
    \n-
    41 // pretty printing of vectors
    \n-
    42 //
    \n-
    43
    \n-
    51 template<class V>
    \n-
    52 void recursive_printvector (std::ostream& s, const V& v, std::string rowtext,
    \n-
    53 int& counter, int columns, int width)
    \n-
    54 {
    \n-
    55 if constexpr (IsNumber<V>())
    \n-
    56 {
    \n-
    57 // Print one number
    \n-
    58 if (counter%columns==0)
    \n-
    59 {
    \n-
    60 s << rowtext; // start a new row
    \n-
    61 s << " "; // space in front of each entry
    \n-
    62 s.width(4); // set width for counter
    \n-
    63 s << counter; // number of first entry in a line
    \n-
    64 }
    \n-
    65 s << " "; // space in front of each entry
    \n-
    66 s.width(width); // set width for each entry anew
    \n-
    67 s << v; // yeah, the number !
    \n-
    68 counter++; // increment the counter
    \n-
    69 if (counter%columns==0)
    \n-
    70 s << std::endl; // start a new line
    \n-
    71 }
    \n-
    72 else
    \n-
    73 {
    \n-
    74 // Recursively print a vector
    \n-
    75 for (const auto& entry : v)
    \n-
    76 recursive_printvector(s,entry,rowtext,counter,columns,width);
    \n-
    77 }
    \n-
    78 }
    \n-
    79
    \n-
    80
    \n-
    88 template<class V>
    \n-
    89 void printvector (std::ostream& s, const V& v, std::string title,
    \n-
    90 std::string rowtext, int columns=1, int width=10,
    \n-
    91 int precision=2)
    \n-
    92 {
    \n-
    93 // count the numbers printed to make columns
    \n-
    94 int counter=0;
    \n-
    95
    \n-
    96 // remember old flags
    \n-
    97 std::ios_base::fmtflags oldflags = s.flags();
    \n-
    98
    \n-
    99 // set the output format
    \n-
    100 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
    \n-
    101 int oldprec = s.precision();
    \n-
    102 s.precision(precision);
    \n+
    28
    \n+
    29namespace Dune {
    \n+
    72 template<class O, int c = -1>
    \n+\n+
    74 public Preconditioner<typename O::domain_type, typename O::range_type>
    \n+
    75 {
    \n+
    76 public:
    \n+
    78 typedef typename O::domain_type domain_type;
    \n+
    80 typedef typename O::range_type range_type;
    \n+
    82 typedef typename range_type::field_type field_type;
    \n+
    84 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    86 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    88 typedef O InverseOperator;
    \n+
    89
    \n+\n+
    95 : inverse_operator_(inverse_operator)
    \n+
    96 {
    \n+
    97 if(c != -1 && SolverCategory::category(inverse_operator_) != c)
    \n+
    98 DUNE_THROW(InvalidStateException, "User-supplied solver category does not match that of the given inverse operator");
    \n+
    99 }
    \n+
    100
    \n+
    101 virtual void pre(domain_type&,range_type&)
    \n+
    102 {}
    \n
    103
    \n-
    104 // print title
    \n-
    105 s << title << " [blocks=" << v.N() << ",dimension=" << v.dim() << "]"
    \n-
    106 << std::endl;
    \n-
    107
    \n-
    108 // print data from all blocks
    \n-
    109 recursive_printvector(s,v,rowtext,counter,columns,width);
    \n+
    104 virtual void apply(domain_type& v, const range_type& d)
    \n+
    105 {
    \n+\n+
    107 range_type copy(d);
    \n+
    108 inverse_operator_.apply(v, copy, res);
    \n+
    109 }
    \n
    110
    \n-
    111 // check if new line is required
    \n-
    112 if (counter%columns!=0)
    \n-
    113 s << std::endl;
    \n-
    114
    \n-
    115 // reset the output format
    \n-
    116 s.flags(oldflags);
    \n-
    117 s.precision(oldprec);
    \n-
    118 }
    \n+
    111 virtual void post(domain_type&)
    \n+
    112 {}
    \n+
    113
    \n+\n+
    116 {
    \n+
    117 return SolverCategory::category(inverse_operator_);
    \n+
    118 }
    \n
    119
    \n-
    120
    \n-
    122 //
    \n-
    123 // pretty printing of matrices
    \n-
    124 //
    \n-
    125
    \n-
    133 inline void fill_row (std::ostream& s, int m, int width, [[maybe_unused]] int precision)
    \n-
    134 {
    \n-
    135 for (int j=0; j<m; j++)
    \n-
    136 {
    \n-
    137 s << " "; // space in front of each entry
    \n-
    138 s.width(width); // set width for each entry anew
    \n-
    139 s << "."; // yeah, the number !
    \n-
    140 }
    \n-
    141 }
    \n-
    142
    \n-
    150 template<class K>
    \n-
    151 void print_row (std::ostream& s, const K& value,
    \n-
    152 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type I,
    \n-
    153 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type J,
    \n-
    154 [[maybe_unused]] typename FieldMatrix<K,1,1>::size_type therow,
    \n-
    155 int width,
    \n-
    156 [[maybe_unused]] int precision,
    \n-
    157 typename std::enable_if_t<Dune::IsNumber<K>::value>* sfinae = nullptr)
    \n-
    158 {
    \n-
    159 s << " "; // space in front of each entry
    \n-
    160 s.width(width); // set width for each entry anew
    \n-
    161 s << value;
    \n-
    162 }
    \n-
    163
    \n-
    171 template<class M>
    \n-
    172 void print_row (std::ostream& s, const M& A, typename M::size_type I,
    \n-
    173 typename M::size_type J, typename M::size_type therow,
    \n-
    174 int width, int precision,
    \n-
    175 typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
    \n-
    176 {
    \n-
    177 typename M::size_type i0=I;
    \n-
    178 for (typename M::size_type i=0; i<A.N(); i++)
    \n-
    179 {
    \n-
    180 if (therow>=i0 && therow<i0+MatrixDimension<M>::rowdim(A,i))
    \n-
    181 {
    \n-
    182 // the row is in this block row !
    \n-
    183 typename M::size_type j0=J;
    \n-
    184 for (typename M::size_type j=0; j<A.M(); j++)
    \n-
    185 {
    \n-
    186 // find this block
    \n-
    187 typename M::ConstColIterator it = A[i].find(j);
    \n-
    188
    \n-
    189 // print row or filler
    \n-
    190 if (it!=A[i].end())
    \n-
    191 print_row(s,*it,i0,j0,therow,width,precision);
    \n-
    192 else
    \n-
    193 fill_row(s,MatrixDimension<M>::coldim(A,j),width,precision);
    \n-
    194
    \n-
    195 // advance columns
    \n-\n-
    197 }
    \n-
    198 }
    \n-
    199 // advance rows
    \n-\n-
    201 }
    \n-
    202 }
    \n-
    203
    \n-
    212 template<class M>
    \n-
    213 void printmatrix (std::ostream& s, const M& A, std::string title,
    \n-
    214 std::string rowtext, int width=10, int precision=2)
    \n-
    215 {
    \n-
    216
    \n-
    217 // remember old flags
    \n-
    218 std::ios_base::fmtflags oldflags = s.flags();
    \n-
    219
    \n-
    220 // set the output format
    \n-
    221 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
    \n-
    222 int oldprec = s.precision();
    \n-
    223 s.precision(precision);
    \n-
    224
    \n-
    225 // print title
    \n-
    226 s << title
    \n-
    227 << " [n=" << A.N()
    \n-
    228 << ",m=" << A.M()
    \n-
    229 << ",rowdim=" << MatrixDimension<M>::rowdim(A)
    \n-
    230 << ",coldim=" << MatrixDimension<M>::coldim(A)
    \n-
    231 << "]" << std::endl;
    \n-
    232
    \n-
    233 // print all rows
    \n-
    234 for (typename M::size_type i=0; i<MatrixDimension<M>::rowdim(A); i++)
    \n-
    235 {
    \n-
    236 s << rowtext; // start a new row
    \n-
    237 s << " "; // space in front of each entry
    \n-
    238 s.width(4); // set width for counter
    \n-
    239 s << i; // number of first entry in a line
    \n-
    240 print_row(s,A,0,0,i,width,precision); // generic print
    \n-
    241 s << std::endl; // start a new line
    \n-
    242 }
    \n-
    243
    \n-
    244 // reset the output format
    \n-
    245 s.flags(oldflags);
    \n-
    246 s.precision(oldprec);
    \n-
    247 }
    \n+
    120 private:
    \n+
    121 InverseOperator& inverse_operator_;
    \n+
    122 };
    \n+
    123
    \n+
    124 //=====================================================================
    \n+
    125 // Implementation of this interface for sequential ISTL-preconditioners
    \n+
    126 //=====================================================================
    \n+
    127
    \n+
    128
    \n+
    140 template<class M, class X, class Y, int l=1>
    \n+
    141 class SeqSSOR : public Preconditioner<X,Y> {
    \n+
    142 public:
    \n+
    144 typedef M matrix_type;
    \n+
    146 typedef X domain_type;
    \n+
    148 typedef Y range_type;
    \n+
    150 typedef typename X::field_type field_type;
    \n+
    152 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    154 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    155
    \n+
    163 SeqSSOR (const M& A, int n, real_field_type w)
    \n+
    164 : _A_(A), _n(n), _w(w)
    \n+
    165 {
    \n+\n+
    167 }
    \n+
    168
    \n+
    182 SeqSSOR (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n+
    183 : SeqSSOR(A->getmat(), configuration)
    \n+
    184 {}
    \n+
    185
    \n+
    199 SeqSSOR (const M& A, const ParameterTree& configuration)
    \n+
    200 : SeqSSOR(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n+
    201 {}
    \n+
    202
    \n+
    208 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n+
    209 {}
    \n+
    210
    \n+
    216 virtual void apply (X& v, const Y& d)
    \n+
    217 {
    \n+
    218 for (int i=0; i<_n; i++) {
    \n+
    219 bsorf(_A_,v,d,_w,BL<l>());
    \n+
    220 bsorb(_A_,v,d,_w,BL<l>());
    \n+
    221 }
    \n+
    222 }
    \n+
    223
    \n+
    229 virtual void post ([[maybe_unused]] X& x)
    \n+
    230 {}
    \n+
    231
    \n+\n+
    234 {
    \n+\n+
    236 }
    \n+
    237
    \n+
    238 private:
    \n+
    240 const M& _A_;
    \n+
    242 int _n;
    \n+\n+
    245 };
    \n+
    246 DUNE_REGISTER_PRECONDITIONER("ssor", defaultPreconditionerBlockLevelCreator<Dune::SeqSSOR>());
    \n+
    247
    \n
    248
    \n-
    270 template<class B, int n, int m, class A>
    \n-
    271 void printSparseMatrix(std::ostream& s,
    \n-\n-
    273 std::string title, std::string rowtext,
    \n-
    274 int width=3, int precision=2)
    \n-
    275 {
    \n-\n-
    277 // remember old flags
    \n-
    278 std::ios_base::fmtflags oldflags = s.flags();
    \n-
    279 // set the output format
    \n-
    280 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
    \n-
    281 int oldprec = s.precision();
    \n-
    282 s.precision(precision);
    \n-
    283 // print title
    \n-
    284 s << title
    \n-
    285 << " [n=" << mat.N()
    \n-
    286 << ",m=" << mat.M()
    \n-
    287 << ",rowdim=" << MatrixDimension<Matrix>::rowdim(mat)
    \n-
    288 << ",coldim=" << MatrixDimension<Matrix>::coldim(mat)
    \n-
    289 << "]" << std::endl;
    \n-
    290
    \n-
    291 typedef typename Matrix::ConstRowIterator Row;
    \n-
    292
    \n-
    293 for(Row row=mat.begin(); row != mat.end(); ++row) {
    \n-
    294 int skipcols=0;
    \n-
    295 bool reachedEnd=false;
    \n-
    296
    \n-
    297 while(!reachedEnd) {
    \n-
    298 for(int innerrow=0; innerrow<n; ++innerrow) {
    \n-
    299 int count=0;
    \n-
    300 typedef typename Matrix::ConstColIterator Col;
    \n-
    301 Col col=row->begin();
    \n-
    302 for(; col != row->end(); ++col,++count) {
    \n-
    303 if(count<skipcols)
    \n-
    304 continue;
    \n-
    305 if(count>=skipcols+width)
    \n-
    306 break;
    \n-
    307 if(innerrow==0) {
    \n-
    308 if(count==skipcols) {
    \n-
    309 s << rowtext; // start a new row
    \n-
    310 s << " "; // space in front of each entry
    \n-
    311 s.width(4); // set width for counter
    \n-
    312 s << row.index()<<": "; // number of first entry in a line
    \n-
    313 }
    \n-
    314 s.width(4);
    \n-
    315 s<<col.index()<<": |";
    \n-
    316 } else {
    \n-
    317 if(count==skipcols) {
    \n-
    318 for(typename std::string::size_type i=0; i < rowtext.length(); i++)
    \n-
    319 s<<" ";
    \n-
    320 s<<" ";
    \n-
    321 }
    \n-
    322 s<<" |";
    \n-
    323 }
    \n-
    324 for(int innercol=0; innercol < m; ++innercol) {
    \n-
    325 s.width(9);
    \n-
    326 s<<(*col)[innerrow][innercol]<<" ";
    \n-
    327 }
    \n-
    328
    \n-
    329 s<<"|";
    \n-
    330 }
    \n-
    331 if(innerrow==n-1 && col==row->end())
    \n-
    332 reachedEnd = true;
    \n-
    333 else
    \n-
    334 s << std::endl;
    \n-
    335 }
    \n-
    336 skipcols += width;
    \n-
    337 s << std::endl;
    \n-
    338 }
    \n-
    339 s << std::endl;
    \n-
    340 }
    \n-
    341
    \n-
    342 // reset the output format
    \n-
    343 s.flags(oldflags);
    \n-
    344 s.precision(oldprec);
    \n-
    345 }
    \n-
    346
    \n-
    347 namespace
    \n-
    348 {
    \n-
    349 template<typename T>
    \n-
    350 struct MatlabPODWriter
    \n+
    260 template<class M, class X, class Y, int l=1>
    \n+
    261 class SeqSOR : public Preconditioner<X,Y> {
    \n+
    262 public:
    \n+
    264 typedef M matrix_type;
    \n+
    266 typedef X domain_type;
    \n+
    268 typedef Y range_type;
    \n+
    270 typedef typename X::field_type field_type;
    \n+
    272 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    274 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    275
    \n+
    283 SeqSOR (const M& A, int n, real_field_type w)
    \n+
    284 : _A_(A), _n(n), _w(w)
    \n+
    285 {
    \n+\n+
    287 }
    \n+
    288
    \n+
    302 SeqSOR (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n+
    303 : SeqSOR(A->getmat(), configuration)
    \n+
    304 {}
    \n+
    305
    \n+
    319 SeqSOR (const M& A, const ParameterTree& configuration)
    \n+
    320 : SeqSOR(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n+
    321 {}
    \n+
    322
    \n+
    328 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n+
    329 {}
    \n+
    330
    \n+
    336 virtual void apply (X& v, const Y& d)
    \n+
    337 {
    \n+
    338 this->template apply<true>(v,d);
    \n+
    339 }
    \n+
    340
    \n+
    349 template<bool forward>
    \n+
    350 void apply(X& v, const Y& d)
    \n
    351 {
    \n-
    352 static std::ostream& write(const T& t, std::ostream& s)
    \n-
    353 {
    \n-
    354 s << t;
    \n-
    355 return s;
    \n-
    356 }
    \n-
    357 };
    \n-
    358 template<typename T>
    \n-
    359 struct MatlabPODWriter<std::complex<T> >
    \n-
    360 {
    \n-
    361 static std::ostream& write(const std::complex<T>& t, std::ostream& s)
    \n-
    362 {
    \n-
    363 s << t.real() << " " << t.imag();
    \n-
    364 return s;
    \n-
    365 }
    \n-
    366 };
    \n-
    367 } // anonymous namespace
    \n-
    368
    \n-
    378 template <class FieldType>
    \n-
    379 void writeMatrixToMatlabHelper(const FieldType& value,
    \n-
    380 int rowOffset, int colOffset,
    \n-
    381 std::ostream& s,
    \n-
    382 typename std::enable_if_t<Dune::IsNumber<FieldType>::value>* sfinae = nullptr)
    \n-
    383 {
    \n-
    384 //+1 for Matlab numbering
    \n-
    385 s << rowOffset + 1 << " " << colOffset + 1 << " ";
    \n-
    386 MatlabPODWriter<FieldType>::write(value, s)<< std::endl;
    \n-
    387 }
    \n-
    388
    \n-
    396 template <class MatrixType>
    \n-
    397 void writeMatrixToMatlabHelper(const MatrixType& matrix,
    \n-
    398 int externalRowOffset, int externalColOffset,
    \n-
    399 std::ostream& s,
    \n-
    400 typename std::enable_if_t<!Dune::IsNumber<MatrixType>::value>* sfinae = nullptr)
    \n-
    401 {
    \n-
    402 // Precompute the accumulated sizes of the columns
    \n-
    403 std::vector<typename MatrixType::size_type> colOffset(matrix.M());
    \n-
    404 if (colOffset.size() > 0)
    \n-
    405 colOffset[0] = 0;
    \n-
    406
    \n-
    407 for (typename MatrixType::size_type i=0; i<matrix.M()-1; i++)
    \n-
    408 colOffset[i+1] = colOffset[i] +
    \n-\n-
    410
    \n-
    411 typename MatrixType::size_type rowOffset = 0;
    \n-
    412
    \n-
    413 // Loop over all matrix rows
    \n-
    414 for (typename MatrixType::size_type rowIdx=0; rowIdx<matrix.N(); rowIdx++)
    \n-
    415 {
    \n-
    416 auto cIt = matrix[rowIdx].begin();
    \n-
    417 auto cEndIt = matrix[rowIdx].end();
    \n-
    418
    \n-
    419 // Loop over all columns in this row
    \n-
    420 for (; cIt!=cEndIt; ++cIt)
    \n-\n-
    422 externalRowOffset+rowOffset,
    \n-
    423 externalColOffset + colOffset[cIt.index()],
    \n-
    424 s);
    \n-
    425
    \n-
    426 rowOffset += MatrixDimension<MatrixType>::rowdim(matrix, rowIdx);
    \n-
    427 }
    \n-
    428
    \n-
    429 }
    \n-
    430
    \n-
    450 template <class MatrixType>
    \n-
    451 void writeMatrixToMatlab(const MatrixType& matrix,
    \n-
    452 const std::string& filename, int outputPrecision = 18)
    \n-
    453 {
    \n-
    454 std::ofstream outStream(filename.c_str());
    \n-
    455 int oldPrecision = outStream.precision();
    \n-
    456 outStream.precision(outputPrecision);
    \n-
    457
    \n-
    458 writeMatrixToMatlabHelper(matrix, 0, 0, outStream);
    \n-
    459 outStream.precision(oldPrecision);
    \n-
    460 }
    \n-
    461
    \n-
    462 // Recursively write vector entries to a stream
    \n-
    463 template<class V>
    \n-
    464 void writeVectorToMatlabHelper (const V& v, std::ostream& stream)
    \n-
    465 {
    \n-
    466 if constexpr (IsNumber<V>()) {
    \n-
    467 stream << v << std::endl;
    \n-
    468 } else {
    \n-
    469 for (const auto& entry : v)
    \n-
    470 writeVectorToMatlabHelper(entry, stream);
    \n-
    471 }
    \n-
    472 }
    \n+
    352 if(forward)
    \n+
    353 for (int i=0; i<_n; i++) {
    \n+
    354 bsorf(_A_,v,d,_w,BL<l>());
    \n+
    355 }
    \n+
    356 else
    \n+
    357 for (int i=0; i<_n; i++) {
    \n+
    358 bsorb(_A_,v,d,_w,BL<l>());
    \n+
    359 }
    \n+
    360 }
    \n+
    361
    \n+
    367 virtual void post ([[maybe_unused]] X& x)
    \n+
    368 {}
    \n+
    369
    \n+\n+
    372 {
    \n+\n+
    374 }
    \n+
    375
    \n+
    376 private:
    \n+
    378 const M& _A_;
    \n+
    380 int _n;
    \n+\n+
    383 };
    \n+
    384 DUNE_REGISTER_PRECONDITIONER("sor", defaultPreconditionerBlockLevelCreator<Dune::SeqSOR>());
    \n+
    385
    \n+
    386
    \n+
    397 template<class M, class X, class Y, int l=1>
    \n+\n+
    399 DUNE_REGISTER_PRECONDITIONER("gs", defaultPreconditionerBlockLevelCreator<Dune::SeqGS>());
    \n+
    400
    \n+
    411 template<class M, class X, class Y, int l=1>
    \n+\n+
    413 public:
    \n+
    415 typedef M matrix_type;
    \n+
    417 typedef X domain_type;
    \n+
    419 typedef Y range_type;
    \n+
    421 typedef typename X::field_type field_type;
    \n+
    423 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    425 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    426
    \n+
    434 SeqJac (const M& A, int n, real_field_type w)
    \n+
    435 : _A_(A), _n(n), _w(w)
    \n+
    436 {
    \n+\n+
    438 }
    \n+
    439
    \n+
    453 SeqJac (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n+
    454 : SeqJac(A->getmat(), configuration)
    \n+
    455 {}
    \n+
    456
    \n+
    470 SeqJac (const M& A, const ParameterTree& configuration)
    \n+
    471 : SeqJac(A, configuration.get<int>("iterations",1), configuration.get<real_field_type>("relaxation",1.0))
    \n+
    472 {}
    \n
    473
    \n-
    491 template <class VectorType>
    \n-
    492 void writeVectorToMatlab(const VectorType& vector,
    \n-
    493 const std::string& filename, int outputPrecision = 18)
    \n-
    494 {
    \n-
    495 std::ofstream outStream(filename.c_str());
    \n-
    496 int oldPrecision = outStream.precision();
    \n-
    497 outStream.precision(outputPrecision);
    \n-
    498
    \n-
    499 writeVectorToMatlabHelper(vector, outStream);
    \n-
    500 outStream.precision(oldPrecision);
    \n-
    501 }
    \n-
    502
    \n-
    503 namespace Impl {
    \n-
    504
    \n-
    506 struct NullStream {
    \n-
    507 template <class Any>
    \n-
    508 friend NullStream &operator<<(NullStream &dev0, Any &&) {
    \n-
    509 return dev0;
    \n-
    510 }
    \n-
    511 };
    \n-
    512
    \n-
    514 // svg shall be closed with a group and an svg. i.e. "</g></svg>"
    \n-
    515 template <class Stream, class SVGMatrixOptions>
    \n-
    516 void writeSVGMatrixHeader(Stream &out, const SVGMatrixOptions &opts,
    \n-
    517 std::pair<std::size_t, size_t> offsets) {
    \n-
    518 auto [col_offset, row_offset] = offsets;
    \n-
    519 double width = opts.width;
    \n-
    520 double height = opts.height;
    \n-
    521 // if empty, we try to figure out a sensible value of width and height
    \n-
    522 if (opts.width == 0 and opts.height == 0)
    \n-
    523 width = height = 500;
    \n-
    524 if (opts.width == 0)
    \n-
    525 width = opts.height * (double(col_offset) / row_offset);
    \n-
    526 if (opts.height == 0)
    \n-
    527 height = opts.width * (double(row_offset) / col_offset);
    \n-
    528
    \n-
    529 // scale group w.r.t final offsets
    \n-
    530 double scale_width = width / col_offset;
    \n-
    531 double scale_height = height / row_offset;
    \n-
    532
    \n-
    533 // write the header text
    \n-
    534 out << "<svg xmlns='http://www.w3.org/2000/svg' width='" << std::ceil(width)
    \n-
    535 << "' height='" << std::ceil(height) << "' version='1.1'>\\n"
    \n-
    536 << "<style>\\n"
    \n-
    537 << opts.style << "</style>\\n"
    \n-
    538 << "<g transform='scale(" << scale_width << " " << scale_height
    \n-
    539 << ")'>\\n";
    \n-
    540 }
    \n-
    541
    \n-
    543 template <class Mat, class Stream, class SVGMatrixOptions,
    \n-
    544 class RowPrefix, class ColPrefix>
    \n-
    545 std::pair<std::size_t, size_t>
    \n-
    546 writeSVGMatrix(const Mat &mat, Stream &out, SVGMatrixOptions opts,
    \n-
    547 RowPrefix row_prefix, ColPrefix col_prefix) {
    \n-
    548 // get values to fill the offests
    \n-
    549 const auto& block_size = opts.block_size;
    \n-
    550 const auto& interspace = opts.interspace;
    \n-
    551
    \n-
    552 const std::size_t rows = mat.N();
    \n-
    553 const std::size_t cols = mat.M();
    \n-
    554
    \n-
    555 // disable header write for recursive calls
    \n-
    556 const bool write_header = opts.write_header;
    \n-
    557 opts.write_header = false;
    \n-
    558
    \n-
    559 // counter of offsets for every block
    \n-
    560 std::size_t row_offset = interspace;
    \n-
    561 std::size_t col_offset = interspace;
    \n-
    562
    \n-
    563 // lambda helper: for-each value
    \n-
    564 auto for_each_entry = [&mat](const auto &call_back) {
    \n-
    565 for (auto row_it = mat.begin(); row_it != mat.end(); ++row_it) {
    \n-
    566 for (auto col_it = row_it->begin(); col_it != row_it->end(); ++col_it) {
    \n-
    567 call_back(row_it.index(), col_it.index(), *col_it);
    \n-
    568 }
    \n-
    569 }
    \n-
    570 };
    \n-
    571
    \n-
    572 // accumulate content in another stream so that we write in correct order
    \n-
    573 std::stringstream ss;
    \n-
    574
    \n-
    575 // we need to append current row and col values to the prefixes
    \n-
    576 row_prefix.push_back(0);
    \n-
    577 col_prefix.push_back(0);
    \n-
    578
    \n-
    579 // do we need to write nested matrix blocks?
    \n-
    580 if constexpr (Dune::blockLevel<typename Mat::block_type>() == 0) {
    \n-
    581 // simple case: write svg block content to stream for each value
    \n-
    582 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
    \n-
    583 std::size_t x_off = interspace + col * (interspace + block_size);
    \n-
    584 std::size_t y_off = interspace + row * (interspace + block_size);
    \n-
    585 row_prefix.back() = row;
    \n-
    586 col_prefix.back() = col;
    \n-
    587 opts.writeSVGBlock(ss, row_prefix, col_prefix, val,
    \n-
    588 {x_off, y_off, block_size, block_size});
    \n-
    589 });
    \n-
    590 col_offset += cols * (block_size + interspace);
    \n-
    591 row_offset += rows * (block_size + interspace);
    \n-
    592 } else {
    \n-
    593 // before we write anything, we need to calculate the
    \n-
    594 // offset for every {row,col} index
    \n-
    595 const auto null_offset = std::numeric_limits<std::size_t>::max();
    \n-
    596 std::vector<std::size_t> col_offsets(cols + 1, null_offset);
    \n-
    597 std::vector<std::size_t> row_offsets(rows + 1, null_offset);
    \n-
    598 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
    \n-
    599 NullStream dev0;
    \n-
    600 // get size of sub-block
    \n-
    601 auto sub_size =
    \n-
    602 writeSVGMatrix(val, dev0, opts, row_prefix, col_prefix);
    \n+
    479 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n+
    480 {}
    \n+
    481
    \n+
    487 virtual void apply (X& v, const Y& d)
    \n+
    488 {
    \n+
    489 for (int i=0; i<_n; i++) {
    \n+
    490 dbjac(_A_,v,d,_w,BL<l>());
    \n+
    491 }
    \n+
    492 }
    \n+
    493
    \n+
    499 virtual void post ([[maybe_unused]] X& x)
    \n+
    500 {}
    \n+
    501
    \n+\n+
    504 {
    \n+\n+
    506 }
    \n+
    507
    \n+
    508 private:
    \n+
    510 const M& _A_;
    \n+
    512 int _n;
    \n+
    514 real_field_type _w;
    \n+
    515 };
    \n+
    516 DUNE_REGISTER_PRECONDITIONER("jac", defaultPreconditionerBlockLevelCreator<Dune::SeqJac>());
    \n+
    517
    \n+
    518
    \n+
    519
    \n+
    531 template<class M, class X, class Y, int l=1>
    \n+\n+
    533 public:
    \n+
    535 typedef typename std::remove_const<M>::type matrix_type;
    \n+
    537 typedef typename matrix_type :: block_type block_type;
    \n+
    539 typedef X domain_type;
    \n+
    541 typedef Y range_type;
    \n+
    542
    \n+
    544 typedef typename X::field_type field_type;
    \n+
    545
    \n+
    547 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    549 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    550
    \n+\n+
    553
    \n+
    561 SeqILU (const M& A, real_field_type w, const bool resort = false )
    \n+
    562 : SeqILU( A, 0, w, resort ) // construct ILU(0)
    \n+
    563 {
    \n+
    564 }
    \n+
    565
    \n+
    580 SeqILU (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n+
    581 : SeqILU(A->getmat(), configuration)
    \n+
    582 {}
    \n+
    583
    \n+
    598 SeqILU(const M& A, const ParameterTree& config)
    \n+
    599 : SeqILU(A, config.get("n", 0),
    \n+
    600 config.get<real_field_type>("relaxation", 1.0),
    \n+
    601 config.get("resort", false))
    \n+
    602 {}
    \n
    603
    \n-
    604 // if we didn't see col size before
    \n-
    605 if (col_offsets[col + 1] == null_offset) // write it in the offset vector
    \n-
    606 col_offsets[col + 1] = sub_size.first;
    \n-
    607
    \n-
    608 // repeat proces for row sizes
    \n-
    609 if (row_offsets[row + 1] == null_offset)
    \n-
    610 row_offsets[row + 1] = sub_size.second;
    \n-
    611 });
    \n-
    612
    \n-
    613 // if some rows/cols were not visited, make an educated guess with the minimum offset
    \n-
    614 auto min_row_offset = *std::min_element(begin(row_offsets), end(row_offsets));
    \n-
    615 std::replace(begin(row_offsets), end(row_offsets), null_offset, min_row_offset);
    \n-
    616 auto min_col_offset = *std::min_element(begin(col_offsets), end(col_offsets));
    \n-
    617 std::replace(begin(col_offsets), end(col_offsets), null_offset, min_col_offset);
    \n-
    618
    \n-
    619 // we have sizes for every block: to get offsets we make a partial sum
    \n-
    620 col_offsets[0] = interspace;
    \n-
    621 row_offsets[0] = interspace;
    \n-
    622 for (std::size_t i = 1; i < col_offsets.size(); i++)
    \n-
    623 col_offsets[i] += col_offsets[i - 1] + interspace;
    \n-
    624 for (std::size_t i = 1; i < row_offsets.size(); i++)
    \n-
    625 row_offsets[i] += row_offsets[i - 1] + interspace;
    \n-
    626
    \n-
    627 for_each_entry([&](const auto &row, const auto &col, const auto &val) {
    \n-
    628 // calculate svg view from offsets
    \n-
    629 std::size_t width =
    \n-
    630 col_offsets[col + 1] - col_offsets[col] - interspace;
    \n-
    631 std::size_t height =
    \n-
    632 row_offsets[row + 1] - row_offsets[row] - interspace;
    \n-
    633 row_prefix.back() = row;
    \n-
    634 col_prefix.back() = col;
    \n-
    635 // content of the sub-block has origin at {0,0}: shift it to the correct place
    \n-
    636 ss << "<svg x='" << col_offsets[col] << "' y='" << row_offsets[row]
    \n-
    637 << "' width='" << width << "' height='" << height << "'>\\n";
    \n-
    638 // write a nested svg with the contents of the sub-block
    \n-
    639 writeSVGMatrix(val, ss, opts, row_prefix, col_prefix);
    \n-
    640 ss << "</svg>\\n";
    \n-
    641 });
    \n-
    642 col_offset = col_offsets.back();
    \n-
    643 row_offset = row_offsets.back();
    \n-
    644 }
    \n-
    645
    \n-
    646 // write content in order!
    \n-
    647 // (i) if required, first header
    \n-
    648 if (write_header)
    \n-
    649 writeSVGMatrixHeader(out, opts, {col_offset, row_offset});
    \n+
    612 SeqILU (const M& A, int n, real_field_type w, const bool resort = false )
    \n+
    613 : ILU_(),
    \n+
    614 lower_(),
    \n+
    615 upper_(),
    \n+
    616 inv_(),
    \n+
    617 w_(w),
    \n+
    618 wNotIdentity_([w]{using std::abs; return abs(w - real_field_type(1)) > 1e-15;}() )
    \n+
    619 {
    \n+
    620 if( n == 0 )
    \n+
    621 {
    \n+
    622 // copy A
    \n+
    623 ILU_.reset( new matrix_type( A ) );
    \n+
    624 // create ILU(0) decomposition
    \n+\n+
    626 }
    \n+
    627 else
    \n+
    628 {
    \n+
    629 // create matrix in build mode
    \n+
    630 ILU_.reset( new matrix_type( A.N(), A.M(), matrix_type::row_wise) );
    \n+
    631 // create ILU(n) decomposition
    \n+
    632 ILU::blockILUDecomposition( A, n, *ILU_ );
    \n+
    633 }
    \n+
    634
    \n+
    635 if( resort )
    \n+
    636 {
    \n+
    637 // store ILU in simple CRS format
    \n+
    638 ILU::convertToCRS( *ILU_, lower_, upper_, inv_ );
    \n+
    639 ILU_.reset();
    \n+
    640 }
    \n+
    641 }
    \n+
    642
    \n+
    648 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n+
    649 {}
    \n
    650
    \n-
    651 col_prefix.pop_back();
    \n-
    652 row_prefix.pop_back();
    \n-
    653 // (ii) an svg block for this level
    \n-
    654 opts.writeSVGBlock(out, row_prefix, col_prefix, mat,
    \n-
    655 {0, 0, col_offset, row_offset});
    \n-
    656 // (iii) the content of the matrix
    \n-
    657 out << ss.str();
    \n-
    658 // (iv) if required, close the header
    \n-
    659 if (write_header)
    \n-
    660 out << "</g>\\n</svg>\\n";
    \n-
    661
    \n-
    662 // return the total required for this block
    \n-
    663 return {col_offset, row_offset};
    \n-
    664 }
    \n-
    665 } // namespace Impl
    \n+
    656 virtual void apply (X& v, const Y& d)
    \n+
    657 {
    \n+
    658 if( ILU_ )
    \n+
    659 {
    \n+
    660 ILU::blockILUBacksolve( *ILU_, v, d);
    \n+
    661 }
    \n+
    662 else
    \n+
    663 {
    \n+
    664 ILU::blockILUBacksolve(lower_, upper_, inv_, v, d);
    \n+
    665 }
    \n
    666
    \n-
    667
    \n-\n-
    676 std::size_t block_size = 10;
    \n-
    678 std::size_t interspace = 5;
    \n-
    680 std::size_t width = 500;
    \n-
    682 std::size_t height = 0;
    \n-
    684 bool write_header = true;
    \n-
    686 std::string style = " .matrix-block {\\n"
    \n-
    687 " fill: cornflowerblue;\\n"
    \n-
    688 " fill-opacity: 0.4;\\n"
    \n-
    689 " stroke-width: 2;\\n"
    \n-
    690 " stroke: black;\\n"
    \n-
    691 " stroke-opacity: 0.5;\\n"
    \n-
    692 " }\\n"
    \n-
    693 " .matrix-block:hover {\\n"
    \n-
    694 " fill: lightcoral;\\n"
    \n-
    695 " fill-opacity: 0.4;\\n"
    \n-
    696 " stroke-opacity: 1;\\n"
    \n-
    697 " }\\n";
    \n-
    698
    \n-
    710 std::function<std::string(const double&)> color_fill;
    \n-
    711
    \n-
    717 template <class RowPrefix, class ColPrefix>
    \n-
    718 std::string blockStyleClass(const RowPrefix &row_prefix,
    \n-
    719 const ColPrefix &col_prefix) const {
    \n-
    720 // here, you can potentially give a different style to each block
    \n-
    721 return "matrix-block";
    \n-
    722 }
    \n-
    723
    \n-
    725 bool write_block_title = true;
    \n-
    726
    \n-
    732 template <class Stream, class RowPrefix, class ColPrefix, class Block>
    \n-
    733 void writeBlockTitle(Stream& out, const RowPrefix &row_prefix,
    \n-
    734 const ColPrefix &col_prefix,
    \n-
    735 const Block &block) const {
    \n-
    736 if (this->write_block_title) {
    \n-
    737 out << "<title>";
    \n-
    738 assert(row_prefix.size() == col_prefix.size());
    \n-
    739 for (std::size_t i = 0; i < row_prefix.size(); ++i)
    \n-
    740 out << "[" << row_prefix[i] << ", "<< col_prefix[i] << "]";
    \n-
    741 if constexpr (Dune::blockLevel<Block>() == 0)
    \n-
    742 out << ": " << block;
    \n-
    743 out << "</title>\\n";
    \n-
    744 }
    \n-
    745 }
    \n-
    746
    \n-
    768 template <class Stream, class RowPrefix, class ColPrefix, class Block>
    \n-
    769 void writeSVGBlock(Stream &out,
    \n-
    770 const RowPrefix &row_prefix,
    \n-
    771 const ColPrefix &col_prefix, const Block block,
    \n-
    772 const std::array<std::size_t, 4> &svg_box) const {
    \n-
    773 // get bounding box values
    \n-
    774 auto &[x_off, y_off, width, height] = svg_box;
    \n-
    775 // get style class
    \n-
    776 std::string block_class = this->blockStyleClass(row_prefix, col_prefix);
    \n-
    777 // write a rectangle on the bounding box
    \n-
    778 out << "<rect class='" << block_class << "' x='" << x_off << "' y='"
    \n-
    779 << y_off << "' width='" << width << "' height='" << height << "'";
    \n-
    780 if constexpr (Dune::blockLevel<Block>() == 0 and std::is_convertible<Block,double>{})
    \n-
    781 if (color_fill)
    \n-
    782 out << " style='fill-opacity: 1;fill:" << color_fill(double(block)) << "'";
    \n-
    783
    \n-
    784 out << ">\\n";
    \n-
    785 // give the rectangle a title (in html this shows info about the block)
    \n-
    786 this->writeBlockTitle(out,row_prefix, col_prefix, block);
    \n-
    787 // close rectangle
    \n-
    788 out << "</rect>\\n";
    \n-
    789 }
    \n-
    790 };
    \n-
    791
    \n-
    806 template <class Mat, class SVGOptions = DefaultSVGMatrixOptions>
    \n-
    807 void writeSVGMatrix(const Mat &mat, std::ostream &out,
    \n-
    808 SVGOptions opts = {}) {
    \n-
    809 // We need a vector that can fit all the multi-indices for rows and colums
    \n-
    810 using IndexPrefix = Dune::ReservedVector<std::size_t, blockLevel<Mat>()>;
    \n-
    811 // Call overload for Mat type
    \n-
    812 Impl::writeSVGMatrix(mat, out, opts, IndexPrefix{}, IndexPrefix{});
    \n-
    813 }
    \n-
    814
    \n-
    817} // namespace Dune
    \n-
    818
    \n-
    819#endif
    \n-
    Helper functions for determining the vector/matrix block level.
    \n-
    Some handy generic functions for ISTL matrices.
    \n-\n-
    Implementation of the BCRSMatrix class.
    \n+
    667 if( wNotIdentity_ )
    \n+
    668 {
    \n+
    669 v *= w_;
    \n+
    670 }
    \n+
    671 }
    \n+
    672
    \n+
    678 virtual void post ([[maybe_unused]] X& x)
    \n+
    679 {}
    \n+
    680
    \n+\n+
    683 {
    \n+\n+
    685 }
    \n+
    686
    \n+
    687 protected:
    \n+
    689 std::unique_ptr< matrix_type > ILU_;
    \n+
    690
    \n+\n+\n+
    694 std::vector< block_type, typename matrix_type::allocator_type > inv_;
    \n+
    695
    \n+\n+
    699 const bool wNotIdentity_;
    \n+
    700 };
    \n+
    701 DUNE_REGISTER_PRECONDITIONER("ilu", defaultPreconditionerBlockLevelCreator<Dune::SeqILU>());
    \n+
    702
    \n+
    703
    \n+
    712 template<class X, class Y>
    \n+
    713 class Richardson : public Preconditioner<X,Y> {
    \n+
    714 public:
    \n+
    716 typedef X domain_type;
    \n+
    718 typedef Y range_type;
    \n+
    720 typedef typename X::field_type field_type;
    \n+
    722 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    724 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    725
    \n+\n+
    732 _w(w)
    \n+
    733 {}
    \n+
    734
    \n+
    746 Richardson (const ParameterTree& configuration)
    \n+
    747 : Richardson(configuration.get<real_field_type>("relaxation", 1.0))
    \n+
    748 {}
    \n+
    749
    \n+
    755 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)
    \n+
    756 {}
    \n+
    757
    \n+
    763 virtual void apply (X& v, const Y& d)
    \n+
    764 {
    \n+
    765 v = d;
    \n+
    766 v *= _w;
    \n+
    767 }
    \n+
    768
    \n+
    774 virtual void post ([[maybe_unused]] X& x)
    \n+
    775 {}
    \n+
    776
    \n+\n+
    779 {
    \n+\n+
    781 }
    \n+
    782
    \n+
    783 private:
    \n+\n+
    786 };
    \n+
    787 DUNE_REGISTER_PRECONDITIONER("richardson", [](auto tl, const auto& /* mat */, const ParameterTree& config){
    \n+
    788 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;
    \n+
    789 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;
    \n+
    790 return std::make_shared<Richardson<D,R>>(config);
    \n+
    791 });
    \n+
    792
    \n+
    793
    \n+
    804 template< class M, class X, class Y >
    \n+\n+
    806 : public Preconditioner< X, Y >
    \n+
    807 {
    \n+
    808 typedef SeqILDL< M, X, Y > This;
    \n+\n+
    810
    \n+
    811 public:
    \n+
    813 typedef std::remove_const_t< M > matrix_type;
    \n+
    815 typedef X domain_type;
    \n+
    817 typedef Y range_type;
    \n+
    819 typedef typename X::field_type field_type;
    \n+
    821 typedef Simd::Scalar<field_type> scalar_field_type;
    \n+
    823 typedef typename FieldTraits<scalar_field_type>::real_type real_field_type;
    \n+
    824
    \n+
    837 SeqILDL (const std::shared_ptr<const AssembledLinearOperator<M,X,Y>>& A, const ParameterTree& configuration)
    \n+
    838 : SeqILDL(A->getmat(), configuration)
    \n+
    839 {}
    \n+
    840
    \n+
    853 SeqILDL(const matrix_type& A, const ParameterTree& config)
    \n+
    854 : SeqILDL(A, config.get<real_field_type>("relaxation", 1.0))
    \n+
    855 {}
    \n+
    856
    \n+
    865 explicit SeqILDL ( const matrix_type &A, real_field_type relax = real_field_type( 1 ) )
    \n+
    866 : decomposition_( A.N(), A.M(), matrix_type::random ),
    \n+
    867 relax_( relax )
    \n+
    868 {
    \n+
    869 // setup row sizes for lower triangular matrix
    \n+
    870 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    871 {
    \n+
    872 const auto &A_i = *i;
    \n+
    873 const auto ij = A_i.find( i.index() );
    \n+
    874 if( ij != A_i.end() )
    \n+
    875 decomposition_.setrowsize( i.index(), ij.offset()+1 );
    \n+
    876 else
    \n+
    877 DUNE_THROW( ISTLError, "diagonal entry missing" );
    \n+
    878 }
    \n+
    879 decomposition_.endrowsizes();
    \n+
    880
    \n+
    881 // setup row indices for lower triangular matrix
    \n+
    882 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )
    \n+
    883 {
    \n+
    884 const auto &A_i = *i;
    \n+
    885 for( auto ij = A_i.begin(); ij.index() < i.index() ; ++ij )
    \n+
    886 decomposition_.addindex( i.index(), ij.index() );
    \n+
    887 decomposition_.addindex( i.index(), i.index() );
    \n+
    888 }
    \n+
    889 decomposition_.endindices();
    \n+
    890
    \n+
    891 // copy values of lower triangular matrix
    \n+
    892 auto i = A.begin();
    \n+
    893 for( auto row = decomposition_.begin(), rowend = decomposition_.end(); row != rowend; ++row, ++i )
    \n+
    894 {
    \n+
    895 auto ij = i->begin();
    \n+
    896 for( auto col = row->begin(), colend = row->end(); col != colend; ++col, ++ij )
    \n+
    897 *col = *ij;
    \n+
    898 }
    \n+
    899
    \n+
    900 // perform ILDL decomposition
    \n+
    901 bildl_decompose( decomposition_ );
    \n+
    902 }
    \n+
    903
    \n+
    905 void pre ([[maybe_unused]] X &x, [[maybe_unused]] Y &b) override
    \n+
    906 {}
    \n+
    907
    \n+
    909 void apply ( X &v, const Y &d ) override
    \n+
    910 {
    \n+
    911 bildl_backsolve( decomposition_, v, d, true );
    \n+
    912 v *= relax_;
    \n+
    913 }
    \n+
    914
    \n+
    916 void post ([[maybe_unused]] X &x) override
    \n+
    917 {}
    \n+
    918
    \n+\n+
    921
    \n+
    922 private:
    \n+
    923 matrix_type decomposition_;
    \n+
    924 real_field_type relax_;
    \n+
    925 };
    \n+
    926 DUNE_REGISTER_PRECONDITIONER("ildl", defaultPreconditionerCreator<Dune::SeqILDL>());
    \n+
    927
    \n+
    930} // end namespace
    \n+
    931
    \n+
    932
    \n+
    933#endif
    \n+\n+
    Incomplete LDL decomposition.
    \n+
    Define general, extensible interface for inverse operators.
    \n+
    Some handy generic functions for ISTL matrices.
    \n+\n+\n+
    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    \n+
    The incomplete LU factorization kernels.
    \n+\n
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    void writeSVGMatrix(const Mat &mat, std::ostream &out, SVGOptions opts={})
    Writes the visualization of matrix in the SVG format.
    Definition: io.hh:807
    \n-
    void writeMatrixToMatlab(const MatrixType &matrix, const std::string &filename, int outputPrecision=18)
    Writes sparse matrix in a Matlab-readable format.
    Definition: io.hh:451
    \n-
    void print_row(std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1 >::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)
    Print one row of a matrix, specialization for number types.
    Definition: io.hh:151
    \n-
    void printmatrix(std::ostream &s, const M &A, std::string title, std::string rowtext, int width=10, int precision=2)
    Print a generic block matrix.
    Definition: io.hh:213
    \n-
    void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
    Print an ISTL vector.
    Definition: io.hh:89
    \n-
    void writeMatrixToMatlabHelper(const FieldType &value, int rowOffset, int colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber< FieldType >::value > *sfinae=nullptr)
    Helper method for the writeMatrixToMatlab routine.
    Definition: io.hh:379
    \n-
    void writeVectorToMatlabHelper(const V &v, std::ostream &stream)
    Definition: io.hh:464
    \n-
    void writeVectorToMatlab(const VectorType &vector, const std::string &filename, int outputPrecision=18)
    Writes vectors in a Matlab-readable format.
    Definition: io.hh:492
    \n-
    void recursive_printvector(std::ostream &s, const V &v, std::string rowtext, int &counter, int columns, int width)
    Recursively print a vector.
    Definition: io.hh:52
    \n-
    void printSparseMatrix(std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m >, A > &mat, std::string title, std::string rowtext, int width=3, int precision=2)
    Prints a BCRSMatrix with fixed sized blocks.
    Definition: io.hh:271
    \n-
    void fill_row(std::ostream &s, int m, int width, int precision)
    Print a row of zeros for a non-existing block.
    Definition: io.hh:133
    \n-
    STL namespace.
    \n+
    void bsorb(const M &A, X &x, const Y &b, const K &w)
    SSOR step.
    Definition: gsetc.hh:646
    \n+
    void dbjac(const M &A, X &x, const Y &b, const K &w)
    Jacobi step.
    Definition: gsetc.hh:658
    \n+
    void bsorf(const M &A, X &x, const Y &b, const K &w)
    SOR step.
    Definition: gsetc.hh:634
    \n
    Definition: allocator.hh:11
    \n-
    std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
    Send BlockVector to an output stream.
    Definition: bvector.hh:590
    \n-
    Definition: matrixutils.hh:211
    \n-
    static auto coldim(const M &A)
    Definition: matrixutils.hh:219
    \n-
    static auto rowdim(const M &A)
    Definition: matrixutils.hh:214
    \n-
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n-
    Default options class to write SVG matrices.
    Definition: io.hh:674
    \n-
    std::string style
    CSS style block to write in header.
    Definition: io.hh:686
    \n-
    std::size_t width
    Final width size (pixels) of the SVG header. If 0, size is automatic.
    Definition: io.hh:680
    \n-
    std::function< std::string(const double &)> color_fill
    Color fill for default options.
    Definition: io.hh:710
    \n-
    std::size_t block_size
    size (pixels) of the deepst block/value of the matrix
    Definition: io.hh:676
    \n-
    void writeSVGBlock(Stream &out, const RowPrefix &row_prefix, const ColPrefix &col_prefix, const Block block, const std::array< std::size_t, 4 > &svg_box) const
    Write an SVG object for a given block/value in the matrix.
    Definition: io.hh:769
    \n-
    void writeBlockTitle(Stream &out, const RowPrefix &row_prefix, const ColPrefix &col_prefix, const Block &block) const
    Helper function writes a title for a given block and prefix.
    Definition: io.hh:733
    \n-
    std::size_t interspace
    size (pixels) of the interspace between blocks
    Definition: io.hh:678
    \n-
    bool write_block_title
    (Helper) Whether to write a title on the rectangle value
    Definition: io.hh:725
    \n-
    std::size_t height
    Final height size (pixels) of the SVG header. If 0, size is automatic.
    Definition: io.hh:682
    \n-
    bool write_header
    Whether to write the SVG header.
    Definition: io.hh:684
    \n-
    std::string blockStyleClass(const RowPrefix &row_prefix, const ColPrefix &col_prefix) const
    Helper function that returns an style class for a given prefix.
    Definition: io.hh:718
    \n-
    ConstIterator class for sequential access.
    Definition: matrix.hh:404
    \n-
    A generic dynamic dense matrix.
    Definition: matrix.hh:561
    \n-
    RowIterator end()
    Get iterator to one beyond last row.
    Definition: matrix.hh:620
    \n-
    RowIterator begin()
    Get iterator to first row.
    Definition: matrix.hh:614
    \n-
    row_type::const_iterator ConstColIterator
    Const iterator for the entries of each row.
    Definition: matrix.hh:589
    \n+
    void bildl_decompose(Matrix &A)
    compute ILDL decomposition of a symmetric matrix A
    Definition: ildl.hh:88
    \n+
    PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
    Definition: dependency.hh:293
    \n+
    DUNE_REGISTER_PRECONDITIONER("amg", AMGCreator())
    \n+
    void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)
    Definition: ildl.hh:149
    \n+
    void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)
    convert ILU decomposition into CRS format for lower and upper triangular and inverse.
    Definition: ilu.hh:307
    \n+
    void blockILUBacksolve(const M &A, X &v, const Y &d)
    LU backsolve with stored inverse.
    Definition: ilu.hh:94
    \n+
    void blockILU0Decomposition(M &A)
    compute ILU decomposition of A. A is overwritten by its decomposition
    Definition: ilu.hh:33
    \n+
    void blockILUDecomposition(const M &A, int n, M &ILU)
    Definition: ilu.hh:167
    \n+
    compile-time parameter for block recursion depth
    Definition: gsetc.hh:45
    \n+\n+
    derive error class from the base class in common
    Definition: istlexception.hh:19
    \n
    size_type M() const
    Return the number of columns.
    Definition: matrix.hh:700
    \n
    size_type N() const
    Return the number of rows.
    Definition: matrix.hh:695
    \n-
    Definition: matrixutils.hh:27
    \n+
    static void check(const Matrix &mat)
    Check whether the a matrix has diagonal values on blocklevel recursion levels.
    Definition: matrixutils.hh:53
    \n+
    A linear operator exporting itself in matrix form.
    Definition: operators.hh:109
    \n+
    Base class for matrix free definition of preconditioners.
    Definition: preconditioner.hh:32
    \n+
    Turns an InverseOperator into a Preconditioner.
    Definition: preconditioners.hh:75
    \n+
    O::range_type range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:80
    \n+
    O::domain_type domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:78
    \n+
    virtual void post(domain_type &)
    Clean up.
    Definition: preconditioners.hh:111
    \n+
    range_type::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:82
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:86
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:84
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:115
    \n+
    virtual void pre(domain_type &, range_type &)
    Prepare the preconditioner.
    Definition: preconditioners.hh:101
    \n+
    InverseOperator2Preconditioner(InverseOperator &inverse_operator)
    Construct the preconditioner from the solver.
    Definition: preconditioners.hh:94
    \n+
    O InverseOperator
    type of the wrapped inverse operator
    Definition: preconditioners.hh:88
    \n+
    virtual void apply(domain_type &v, const range_type &d)
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: preconditioners.hh:104
    \n+
    Sequential SSOR preconditioner.
    Definition: preconditioners.hh:141
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:229
    \n+
    SeqSSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:182
    \n+
    SeqSSOR(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:199
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:233
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:150
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:152
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:146
    \n+
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:144
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:216
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:208
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:148
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:154
    \n+
    SeqSSOR(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:163
    \n+
    Sequential SOR preconditioner.
    Definition: preconditioners.hh:261
    \n+
    SeqSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:302
    \n+
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:264
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:274
    \n+
    void apply(X &v, const Y &d)
    Apply the preconditioner in a special direction.
    Definition: preconditioners.hh:350
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:266
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:367
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:328
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:272
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:371
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:336
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:268
    \n+
    SeqSOR(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:319
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:270
    \n+
    SeqSOR(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:283
    \n+
    The sequential jacobian preconditioner.
    Definition: preconditioners.hh:412
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:499
    \n+
    SeqJac(const M &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:470
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:487
    \n+
    M matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:415
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:423
    \n+
    SeqJac(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:453
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:421
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:479
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:417
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:425
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:503
    \n+
    SeqJac(const M &A, int n, real_field_type w)
    Constructor.
    Definition: preconditioners.hh:434
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:419
    \n+
    Sequential ILU preconditioner.
    Definition: preconditioners.hh:532
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:678
    \n+
    SeqILU(const M &A, int n, real_field_type w, const bool resort=false)
    Constructor.
    Definition: preconditioners.hh:612
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:648
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the preconditioner.
    Definition: preconditioners.hh:656
    \n+
    ILU::CRS< block_type, typename M::allocator_type > CRS
    type of ILU storage
    Definition: preconditioners.hh:552
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:541
    \n+
    CRS lower_
    The ILU(n) decomposition of the matrix. As storage a CRS structure is used.
    Definition: preconditioners.hh:692
    \n+
    const bool wNotIdentity_
    true if w != 1.0
    Definition: preconditioners.hh:699
    \n+
    SeqILU(const M &A, const ParameterTree &config)
    Constructor.
    Definition: preconditioners.hh:598
    \n+
    std::remove_const< M >::type matrix_type
    The matrix type the preconditioner is for.
    Definition: preconditioners.hh:535
    \n+
    matrix_type::block_type block_type
    block type of matrix
    Definition: preconditioners.hh:537
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:549
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:544
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:682
    \n+
    SeqILU(const M &A, real_field_type w, const bool resort=false)
    Constructor.
    Definition: preconditioners.hh:561
    \n+
    const real_field_type w_
    The relaxation factor to use.
    Definition: preconditioners.hh:697
    \n+
    SeqILU(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:580
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:539
    \n+
    std::vector< block_type, typename matrix_type::allocator_type > inv_
    Definition: preconditioners.hh:694
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:547
    \n+
    std::unique_ptr< matrix_type > ILU_
    The ILU(n) decomposition of the matrix. As storage a BCRSMatrix is used.
    Definition: preconditioners.hh:689
    \n+
    CRS upper_
    Definition: preconditioners.hh:693
    \n+
    Richardson preconditioner.
    Definition: preconditioners.hh:713
    \n+
    X::field_type field_type
    The field type of the preconditioner.
    Definition: preconditioners.hh:720
    \n+
    virtual SolverCategory::Category category() const
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:778
    \n+
    Y range_type
    The range type of the preconditioner.
    Definition: preconditioners.hh:718
    \n+
    virtual void pre(X &x, Y &b)
    Prepare the preconditioner.
    Definition: preconditioners.hh:755
    \n+
    Richardson(real_field_type w=1.0)
    Constructor.
    Definition: preconditioners.hh:731
    \n+
    virtual void post(X &x)
    Clean up.
    Definition: preconditioners.hh:774
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:724
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:722
    \n+
    Richardson(const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:746
    \n+
    X domain_type
    The domain type of the preconditioner.
    Definition: preconditioners.hh:716
    \n+
    virtual void apply(X &v, const Y &d)
    Apply the precondioner.
    Definition: preconditioners.hh:763
    \n+
    sequential ILDL preconditioner
    Definition: preconditioners.hh:807
    \n+
    SeqILDL(const matrix_type &A, const ParameterTree &config)
    Constructor.
    Definition: preconditioners.hh:853
    \n+
    SeqILDL(const matrix_type &A, real_field_type relax=real_field_type(1))
    constructor
    Definition: preconditioners.hh:865
    \n+
    X domain_type
    domain type of the preconditioner
    Definition: preconditioners.hh:815
    \n+
    void post(X &x) override
    Clean up.
    Definition: preconditioners.hh:916
    \n+
    Y range_type
    range type of the preconditioner
    Definition: preconditioners.hh:817
    \n+
    std::remove_const_t< M > matrix_type
    type of matrix the preconditioner is for
    Definition: preconditioners.hh:813
    \n+
    void apply(X &v, const Y &d) override
    Apply one step of the preconditioner to the system A(v)=d.
    Definition: preconditioners.hh:909
    \n+
    FieldTraits< scalar_field_type >::real_type real_field_type
    real scalar type underlying the field_type
    Definition: preconditioners.hh:823
    \n+
    SeqILDL(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A, const ParameterTree &configuration)
    Constructor.
    Definition: preconditioners.hh:837
    \n+
    void pre(X &x, Y &b) override
    Prepare the preconditioner.
    Definition: preconditioners.hh:905
    \n+
    Simd::Scalar< field_type > scalar_field_type
    scalar type underlying the field_type
    Definition: preconditioners.hh:821
    \n+
    X::field_type field_type
    field type of the preconditioner
    Definition: preconditioners.hh:819
    \n+
    SolverCategory::Category category() const override
    Category of the preconditioner (see SolverCategory::Category)
    Definition: preconditioners.hh:920
    \n+
    Statistics about the application of an inverse operator.
    Definition: solver.hh:48
    \n+
    Abstract base class for all solvers.
    Definition: solver.hh:99
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,808 +4,1026 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-io.hh\n+preconditioners.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_IO_HH\n- 6#define DUNE_ISTL_IO_HH\n+ 5#ifndef DUNE_ISTL_PRECONDITIONERS_HH\n+ 6#define DUNE_ISTL_PRECONDITIONERS_HH\n 7\n 8#include \n 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13#include \n- 14#include \n- 15\n- 16#include \"matrixutils.hh\"\n- 17#include \"istlexception.hh\"\n- 18#include \n- 19#include \n- 20#include \n- 21#include \n- 22\n- 23#include \n- 24#include \n- 25\n- 26namespace Dune {\n+ 10#include \n+ 11#include \n+ 12#include \n+ 13#include \n+ 14\n+ 15#include \n+ 16#include \n+ 17\n+ 18#include \n+ 19#include \"preconditioner.hh\"\n+ 20#include \"solver.hh\"\n+ 21#include \"solvercategory.hh\"\n+ 22#include \"istlexception.hh\"\n+ 23#include \"matrixutils.hh\"\n+ 24#include \"gsetc.hh\"\n+ 25#include \"ildl.hh\"\n+ 26#include \"ilu.hh\"\n 27\n- 40 //\n- 41 // pretty printing of vectors\n- 42 //\n- 43\n- 51 template\n-52 void recursive_printvector (std::ostream& s, const V& v, std::string\n-rowtext,\n- 53 int& counter, int columns, int width)\n- 54 {\n- 55 if constexpr (IsNumber())\n- 56 {\n- 57 // Print one number\n- 58 if (counter%columns==0)\n- 59 {\n- 60 s << rowtext; // start a new row\n- 61 s << \" \"; // space in front of each entry\n- 62 s.width(4); // set width for counter\n- 63 s << counter; // number of first entry in a line\n- 64 }\n- 65 s << \" \"; // space in front of each entry\n- 66 s.width(width); // set width for each entry anew\n- 67 s << v; // yeah, the number !\n- 68 counter++; // increment the counter\n- 69 if (counter%columns==0)\n- 70 s << std::endl; // start a new line\n- 71 }\n- 72 else\n- 73 {\n- 74 // Recursively print a vector\n- 75 for (const auto& entry : v)\n- 76 recursive_printvector(s,entry,rowtext,counter,columns,width);\n- 77 }\n- 78 }\n- 79\n- 80\n- 88 template\n-89 void printvector (std::ostream& s, const V& v, std::string title,\n- 90 std::string rowtext, int columns=1, int width=10,\n- 91 int precision=2)\n- 92 {\n- 93 // count the numbers printed to make columns\n- 94 int counter=0;\n- 95\n- 96 // remember old flags\n- 97 std::ios_base::fmtflags oldflags = s.flags();\n- 98\n- 99 // set the output format\n- 100 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n- 101 int oldprec = s.precision();\n- 102 s.precision(precision);\n+ 28\n+ 29namespace Dune {\n+ 72 template\n+73 class InverseOperator2Preconditioner :\n+ 74 public Preconditioner\n+ 75 {\n+ 76 public:\n+78 typedef typename O::domain_type domain_type;\n+80 typedef typename O::range_type range_type;\n+82 typedef typename range_type::field_type field_type;\n+84 typedef Simd::Scalar scalar_field_type;\n+86 typedef typename FieldTraits::real_type real_field_type;\n+88 typedef O InverseOperator;\n+ 89\n+94 InverseOperator2Preconditioner(InverseOperator& inverse_operator)\n+ 95 : inverse_operator_(inverse_operator)\n+ 96 {\n+ 97 if(c != -1 && SolverCategory::category(inverse_operator_) != c)\n+ 98 DUNE_THROW(InvalidStateException, \"User-supplied solver category does not\n+match that of the given inverse operator\");\n+ 99 }\n+ 100\n+101 virtual void pre(domain_type&,range_type&)\n+ 102 {}\n 103\n- 104 // print title\n- 105 s << title << \" [blocks=\" << v.N() << \",dimension=\" << v.dim() << \"]\"\n- 106 << std::endl;\n- 107\n- 108 // print data from all blocks\n- 109 recursive_printvector(s,v,rowtext,counter,columns,width);\n+104 virtual void apply(domain_type& v, const range_type& d)\n+ 105 {\n+ 106 InverseOperatorResult res;\n+ 107 range_type copy(d);\n+ 108 inverse_operator_.apply(v, copy, res);\n+ 109 }\n 110\n- 111 // check if new line is required\n- 112 if (counter%columns!=0)\n- 113 s << std::endl;\n- 114\n- 115 // reset the output format\n- 116 s.flags(oldflags);\n- 117 s.precision(oldprec);\n+111 virtual void post(domain_type&)\n+ 112 {}\n+ 113\n+115 virtual SolverCategory::Category category() const\n+ 116 {\n+ 117 return SolverCategory::category(inverse_operator_);\n 118 }\n 119\n- 120\n- 122 //\n- 123 // pretty printing of matrices\n- 124 //\n- 125\n-133 inline void fill_row (std::ostream& s, int m, int width, [[maybe_unused]]\n-int precision)\n- 134 {\n- 135 for (int j=0; j\n-151 void print_row (std::ostream& s, const K& value,\n- 152 [[maybe_unused]] typename FieldMatrix::size_type I,\n- 153 [[maybe_unused]] typename FieldMatrix::size_type J,\n- 154 [[maybe_unused]] typename FieldMatrix::size_type therow,\n- 155 int width,\n- 156 [[maybe_unused]] int precision,\n- 157 typename std::enable_if_t::value>* sfinae = nullptr)\n- 158 {\n- 159 s << \" \"; // space in front of each entry\n- 160 s.width(width); // set width for each entry anew\n- 161 s << value;\n- 162 }\n- 163\n- 171 template\n-172 void print_row (std::ostream& s, const M& A, typename M::size_type I,\n- 173 typename M::size_type J, typename M::size_type therow,\n- 174 int width, int precision,\n- 175 typename std::enable_if_t::value>* sfinae = nullptr)\n- 176 {\n- 177 typename M::size_type i0=I;\n- 178 for (typename M::size_type i=0; i=i0 && therow::rowdim(A,i))\n- 181 {\n- 182 // the row is in this block row !\n- 183 typename M::size_type j0=J;\n- 184 for (typename M::size_type j=0; j::coldim(A,j),width,precision);\n- 194\n- 195 // advance columns\n- 196 j0 += MatrixDimension::coldim(A,j);\n- 197 }\n- 198 }\n- 199 // advance rows\n- 200 i0 += MatrixDimension::rowdim(A,i);\n- 201 }\n- 202 }\n- 203\n- 212 template\n-213 void printmatrix (std::ostream& s, const M& A, std::string title,\n- 214 std::string rowtext, int width=10, int precision=2)\n- 215 {\n- 216\n- 217 // remember old flags\n- 218 std::ios_base::fmtflags oldflags = s.flags();\n- 219\n- 220 // set the output format\n- 221 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n- 222 int oldprec = s.precision();\n- 223 s.precision(precision);\n- 224\n- 225 // print title\n- 226 s << title\n- 227 << \" [n=\" << A.N()\n- 228 << \",m=\" << A.M()\n- 229 << \",rowdim=\" << MatrixDimension::rowdim(A)\n- 230 << \",coldim=\" << MatrixDimension::coldim(A)\n- 231 << \"]\" << std::endl;\n- 232\n- 233 // print all rows\n- 234 for (typename M::size_type i=0; i::rowdim(A); i++)\n- 235 {\n- 236 s << rowtext; // start a new row\n- 237 s << \" \"; // space in front of each entry\n- 238 s.width(4); // set width for counter\n- 239 s << i; // number of first entry in a line\n- 240 print_row(s,A,0,0,i,width,precision); // generic print\n- 241 s << std::endl; // start a new line\n- 242 }\n- 243\n- 244 // reset the output format\n- 245 s.flags(oldflags);\n- 246 s.precision(oldprec);\n- 247 }\n+ 120 private:\n+ 121 InverseOperator& inverse_operator_;\n+ 122 };\n+ 123\n+ 124 //=====================================================================\n+ 125 // Implementation of this interface for sequential ISTL-preconditioners\n+ 126 //=====================================================================\n+ 127\n+ 128\n+ 140 template\n+141 class SeqSSOR : public Preconditioner {\n+ 142 public:\n+144 typedef M matrix_type;\n+146 typedef X domain_type;\n+148 typedef Y range_type;\n+150 typedef typename X::field_type field_type;\n+152 typedef Simd::Scalar scalar_field_type;\n+154 typedef typename FieldTraits::real_type real_field_type;\n+ 155\n+163 SeqSSOR (const M& A, int n, real_field_type w)\n+ 164 : _A_(A), _n(n), _w(w)\n+ 165 {\n+ 166 CheckIfDiagonalPresent::check(_A_);\n+ 167 }\n+ 168\n+182 SeqSSOR (const std::shared_ptr>& A,\n+const ParameterTree& configuration)\n+ 183 : SeqSSOR(A->getmat(), configuration)\n+ 184 {}\n+ 185\n+199 SeqSSOR (const M& A, const ParameterTree& configuration)\n+ 200 : SeqSSOR(A, configuration.get(\"iterations\",1),\n+configuration.get(\"relaxation\",1.0))\n+ 201 {}\n+ 202\n+208 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n+ 209 {}\n+ 210\n+216 virtual void apply (X& v, const Y& d)\n+ 217 {\n+ 218 for (int i=0; i<_n; i++) {\n+ 219 bsorf(_A_,v,d,_w,BL());\n+ 220 bsorb(_A_,v,d,_w,BL());\n+ 221 }\n+ 222 }\n+ 223\n+229 virtual void post ([[maybe_unused]] X& x)\n+ 230 {}\n+ 231\n+233 virtual SolverCategory::Category category() const\n+ 234 {\n+ 235 return SolverCategory::sequential;\n+ 236 }\n+ 237\n+ 238 private:\n+ 240 const M& _A_;\n+ 242 int _n;\n+ 244 real_field_type _w;\n+ 245 };\n+246 DUNE_REGISTER_PRECONDITIONER(\"ssor\",\n+defaultPreconditionerBlockLevelCreator());\n+ 247\n 248\n- 270 template\n-271 void printSparseMatrix(std::ostream& s,\n- 272 const BCRSMatrix,A>& mat,\n- 273 std::string title, std::string rowtext,\n- 274 int width=3, int precision=2)\n- 275 {\n- 276 typedef BCRSMatrix,A> Matrix;\n- 277 // remember old flags\n- 278 std::ios_base::fmtflags oldflags = s.flags();\n- 279 // set the output format\n- 280 s.setf(std::ios_base::scientific, std::ios_base::floatfield);\n- 281 int oldprec = s.precision();\n- 282 s.precision(precision);\n- 283 // print title\n- 284 s << title\n- 285 << \" [n=\" << mat.N()\n- 286 << \",m=\" << mat.M()\n- 287 << \",rowdim=\" << MatrixDimension::rowdim(mat)\n- 288 << \",coldim=\" << MatrixDimension::coldim(mat)\n- 289 << \"]\" << std::endl;\n- 290\n- 291 typedef typename Matrix::ConstRowIterator Row;\n- 292\n- 293 for(Row row=mat.begin(); row != mat.end(); ++row) {\n- 294 int skipcols=0;\n- 295 bool reachedEnd=false;\n- 296\n- 297 while(!reachedEnd) {\n- 298 for(int innerrow=0; innerrowbegin();\n- 302 for(; col != row->end(); ++col,++count) {\n- 303 if(count=skipcols+width)\n- 306 break;\n- 307 if(innerrow==0) {\n- 308 if(count==skipcols) {\n- 309 s << rowtext; // start a new row\n- 310 s << \" \"; // space in front of each entry\n- 311 s.width(4); // set width for counter\n- 312 s << row.index()<<\": \"; // number of first entry in a line\n- 313 }\n- 314 s.width(4);\n- 315 s<end())\n- 332 reachedEnd = true;\n- 333 else\n- 334 s << std::endl;\n- 335 }\n- 336 skipcols += width;\n- 337 s << std::endl;\n- 338 }\n- 339 s << std::endl;\n- 340 }\n- 341\n- 342 // reset the output format\n- 343 s.flags(oldflags);\n- 344 s.precision(oldprec);\n- 345 }\n- 346\n- 347 namespace\n- 348 {\n- 349 template\n- 350 struct MatlabPODWriter\n+ 260 template\n+261 class SeqSOR : public Preconditioner {\n+ 262 public:\n+264 typedef M matrix_type;\n+266 typedef X domain_type;\n+268 typedef Y range_type;\n+270 typedef typename X::field_type field_type;\n+272 typedef Simd::Scalar scalar_field_type;\n+274 typedef typename FieldTraits::real_type real_field_type;\n+ 275\n+283 SeqSOR (const M& A, int n, real_field_type w)\n+ 284 : _A_(A), _n(n), _w(w)\n+ 285 {\n+ 286 CheckIfDiagonalPresent::check(_A_);\n+ 287 }\n+ 288\n+302 SeqSOR (const std::shared_ptr>& A,\n+const ParameterTree& configuration)\n+ 303 : SeqSOR(A->getmat(), configuration)\n+ 304 {}\n+ 305\n+319 SeqSOR (const M& A, const ParameterTree& configuration)\n+ 320 : SeqSOR(A, configuration.get(\"iterations\",1),\n+configuration.get(\"relaxation\",1.0))\n+ 321 {}\n+ 322\n+328 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n+ 329 {}\n+ 330\n+336 virtual void apply (X& v, const Y& d)\n+ 337 {\n+ 338 this->template apply(v,d);\n+ 339 }\n+ 340\n+ 349 template\n+350 void apply(X& v, const Y& d)\n 351 {\n- 352 static std::ostream& write(const T& t, std::ostream& s)\n- 353 {\n- 354 s << t;\n- 355 return s;\n- 356 }\n- 357 };\n- 358 template\n- 359 struct MatlabPODWriter >\n- 360 {\n- 361 static std::ostream& write(const std::complex& t, std::ostream& s)\n- 362 {\n- 363 s << t.real() << \" \" << t.imag();\n- 364 return s;\n- 365 }\n- 366 };\n- 367 } // anonymous namespace\n- 368\n- 378 template \n-379 void writeMatrixToMatlabHelper(const FieldType& value,\n- 380 int rowOffset, int colOffset,\n- 381 std::ostream& s,\n- 382 typename std::enable_if_t::value>* sfinae =\n-nullptr)\n- 383 {\n- 384 //+1 for Matlab numbering\n- 385 s << rowOffset + 1 << \" \" << colOffset + 1 << \" \";\n- 386 MatlabPODWriter::write(value, s)<< std::endl;\n- 387 }\n- 388\n- 396 template \n-397 void writeMatrixToMatlabHelper(const MatrixType& matrix,\n- 398 int externalRowOffset, int externalColOffset,\n- 399 std::ostream& s,\n- 400 typename std::enable_if_t::value>* sfinae =\n-nullptr)\n- 401 {\n- 402 // Precompute the accumulated sizes of the columns\n- 403 std::vector colOffset(matrix.M());\n- 404 if (colOffset.size() > 0)\n- 405 colOffset[0] = 0;\n- 406\n- 407 for (typename MatrixType::size_type i=0; i::coldim(matrix,i);\n- 410\n- 411 typename MatrixType::size_type rowOffset = 0;\n- 412\n- 413 // Loop over all matrix rows\n- 414 for (typename MatrixType::size_type rowIdx=0; rowIdx::rowdim(matrix, rowIdx);\n- 427 }\n- 428\n- 429 }\n- 430\n- 450 template \n-451 void writeMatrixToMatlab(const MatrixType& matrix,\n- 452 const std::string& filename, int outputPrecision = 18)\n- 453 {\n- 454 std::ofstream outStream(filename.c_str());\n- 455 int oldPrecision = outStream.precision();\n- 456 outStream.precision(outputPrecision);\n- 457\n- 458 writeMatrixToMatlabHelper(matrix, 0, 0, outStream);\n- 459 outStream.precision(oldPrecision);\n- 460 }\n- 461\n- 462 // Recursively write vector entries to a stream\n- 463 template\n-464 void writeVectorToMatlabHelper (const V& v, std::ostream& stream)\n- 465 {\n- 466 if constexpr (IsNumber()) {\n- 467 stream << v << std::endl;\n- 468 } else {\n- 469 for (const auto& entry : v)\n- 470 writeVectorToMatlabHelper(entry, stream);\n- 471 }\n- 472 }\n+ 352 if(forward)\n+ 353 for (int i=0; i<_n; i++) {\n+ 354 bsorf(_A_,v,d,_w,BL());\n+ 355 }\n+ 356 else\n+ 357 for (int i=0; i<_n; i++) {\n+ 358 bsorb(_A_,v,d,_w,BL());\n+ 359 }\n+ 360 }\n+ 361\n+367 virtual void post ([[maybe_unused]] X& x)\n+ 368 {}\n+ 369\n+371 virtual SolverCategory::Category category() const\n+ 372 {\n+ 373 return SolverCategory::sequential;\n+ 374 }\n+ 375\n+ 376 private:\n+ 378 const M& _A_;\n+ 380 int _n;\n+ 382 real_field_type _w;\n+ 383 };\n+384 DUNE_REGISTER_PRECONDITIONER(\"sor\",\n+defaultPreconditionerBlockLevelCreator());\n+ 385\n+ 386\n+ 397 template\n+398 using SeqGS = SeqSOR;\n+399 DUNE_REGISTER_PRECONDITIONER(\"gs\",\n+defaultPreconditionerBlockLevelCreator());\n+ 400\n+ 411 template\n+412 class SeqJac : public Preconditioner {\n+ 413 public:\n+415 typedef M matrix_type;\n+417 typedef X domain_type;\n+419 typedef Y range_type;\n+421 typedef typename X::field_type field_type;\n+423 typedef Simd::Scalar scalar_field_type;\n+425 typedef typename FieldTraits::real_type real_field_type;\n+ 426\n+434 SeqJac (const M& A, int n, real_field_type w)\n+ 435 : _A_(A), _n(n), _w(w)\n+ 436 {\n+ 437 CheckIfDiagonalPresent::check(_A_);\n+ 438 }\n+ 439\n+453 SeqJac (const std::shared_ptr>& A,\n+const ParameterTree& configuration)\n+ 454 : SeqJac(A->getmat(), configuration)\n+ 455 {}\n+ 456\n+470 SeqJac (const M& A, const ParameterTree& configuration)\n+ 471 : SeqJac(A, configuration.get(\"iterations\",1),\n+configuration.get(\"relaxation\",1.0))\n+ 472 {}\n 473\n- 491 template \n-492 void writeVectorToMatlab(const VectorType& vector,\n- 493 const std::string& filename, int outputPrecision = 18)\n- 494 {\n- 495 std::ofstream outStream(filename.c_str());\n- 496 int oldPrecision = outStream.precision();\n- 497 outStream.precision(outputPrecision);\n- 498\n- 499 writeVectorToMatlabHelper(vector, outStream);\n- 500 outStream.precision(oldPrecision);\n- 501 }\n- 502\n- 503 namespace Impl {\n- 504\n- 506 struct NullStream {\n- 507 template \n- 508 friend NullStream &operator<<(NullStream &dev0, Any &&) {\n- 509 return dev0;\n- 510 }\n- 511 };\n- 512\n- 514 // svg shall be closed with a group and an svg. i.e. \"
    \"\n- 515 template \n- 516 void writeSVGMatrixHeader(Stream &out, const SVGMatrixOptions &opts,\n- 517 std::pair offsets) {\n- 518 auto [col_offset, row_offset] = offsets;\n- 519 double width = opts.width;\n- 520 double height = opts.height;\n- 521 // if empty, we try to figure out a sensible value of width and height\n- 522 if (opts.width == 0 and opts.height == 0)\n- 523 width = height = 500;\n- 524 if (opts.width == 0)\n- 525 width = opts.height * (double(col_offset) / row_offset);\n- 526 if (opts.height == 0)\n- 527 height = opts.width * (double(row_offset) / col_offset);\n- 528\n- 529 // scale group w.r.t final offsets\n- 530 double scale_width = width / col_offset;\n- 531 double scale_height = height / row_offset;\n- 532\n- 533 // write the header text\n- 534 out << \"\\n\"\n- 536 << \"\\n\"\n- 538 << \"\\n\";\n- 540 }\n- 541\n- 543 template \n- 545 std::pair\n- 546 writeSVGMatrix(const Mat &mat, Stream &out, SVGMatrixOptions opts,\n- 547 RowPrefix row_prefix, ColPrefix col_prefix) {\n- 548 // get values to fill the offests\n- 549 const auto& block_size = opts.block_size;\n- 550 const auto& interspace = opts.interspace;\n- 551\n- 552 const std::size_t rows = mat.N();\n- 553 const std::size_t cols = mat.M();\n- 554\n- 555 // disable header write for recursive calls\n- 556 const bool write_header = opts.write_header;\n- 557 opts.write_header = false;\n- 558\n- 559 // counter of offsets for every block\n- 560 std::size_t row_offset = interspace;\n- 561 std::size_t col_offset = interspace;\n- 562\n- 563 // lambda helper: for-each value\n- 564 auto for_each_entry = [&mat](const auto &call_back) {\n- 565 for (auto row_it = mat.begin(); row_it != mat.end(); ++row_it) {\n- 566 for (auto col_it = row_it->begin(); col_it != row_it->end(); ++col_it) {\n- 567 call_back(row_it.index(), col_it.index(), *col_it);\n- 568 }\n- 569 }\n- 570 };\n- 571\n- 572 // accumulate content in another stream so that we write in correct order\n- 573 std::stringstream ss;\n- 574\n- 575 // we need to append current row and col values to the prefixes\n- 576 row_prefix.push_back(0);\n- 577 col_prefix.push_back(0);\n- 578\n- 579 // do we need to write nested matrix blocks?\n- 580 if constexpr (Dune::blockLevel() == 0) {\n- 581 // simple case: write svg block content to stream for each value\n- 582 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n- 583 std::size_t x_off = interspace + col * (interspace + block_size);\n- 584 std::size_t y_off = interspace + row * (interspace + block_size);\n- 585 row_prefix.back() = row;\n- 586 col_prefix.back() = col;\n- 587 opts.writeSVGBlock(ss, row_prefix, col_prefix, val,\n- 588 {x_off, y_off, block_size, block_size});\n- 589 });\n- 590 col_offset += cols * (block_size + interspace);\n- 591 row_offset += rows * (block_size + interspace);\n- 592 } else {\n- 593 // before we write anything, we need to calculate the\n- 594 // offset for every {row,col} index\n- 595 const auto null_offset = std::numeric_limits::max();\n- 596 std::vector col_offsets(cols + 1, null_offset);\n- 597 std::vector row_offsets(rows + 1, null_offset);\n- 598 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n- 599 NullStream dev0;\n- 600 // get size of sub-block\n- 601 auto sub_size =\n- 602 writeSVGMatrix(val, dev0, opts, row_prefix, col_prefix);\n+479 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n+ 480 {}\n+ 481\n+487 virtual void apply (X& v, const Y& d)\n+ 488 {\n+ 489 for (int i=0; i<_n; i++) {\n+ 490 dbjac(_A_,v,d,_w,BL());\n+ 491 }\n+ 492 }\n+ 493\n+499 virtual void post ([[maybe_unused]] X& x)\n+ 500 {}\n+ 501\n+503 virtual SolverCategory::Category category() const\n+ 504 {\n+ 505 return SolverCategory::sequential;\n+ 506 }\n+ 507\n+ 508 private:\n+ 510 const M& _A_;\n+ 512 int _n;\n+ 514 real_field_type _w;\n+ 515 };\n+516 DUNE_REGISTER_PRECONDITIONER(\"jac\",\n+defaultPreconditionerBlockLevelCreator());\n+ 517\n+ 518\n+ 519\n+ 531 template\n+532 class SeqILU : public Preconditioner {\n+ 533 public:\n+535 typedef typename std::remove_const::type matrix_type;\n+537 typedef typename matrix_type :: block_type block_type;\n+539 typedef X domain_type;\n+541 typedef Y range_type;\n+ 542\n+544 typedef typename X::field_type field_type;\n+ 545\n+547 typedef Simd::Scalar scalar_field_type;\n+549 typedef typename FieldTraits::real_type real_field_type;\n+ 550\n+552 typedef typename ILU::CRS<_block_type_,_typename_M::allocator_type> CRS;\n+ 553\n+561 SeqILU (const M& A, real_field_type w, const bool resort = false )\n+ 562 : SeqILU( A, 0, w, resort ) // construct ILU(0)\n+ 563 {\n+ 564 }\n+ 565\n+580 SeqILU (const std::shared_ptr>& A,\n+const ParameterTree& configuration)\n+ 581 : SeqILU(A->getmat(), configuration)\n+ 582 {}\n+ 583\n+598 SeqILU(const M& A, const ParameterTree& config)\n+ 599 : SeqILU(A, config.get(\"n\", 0),\n+ 600 config.get(\"relaxation\", 1.0),\n+ 601 config.get(\"resort\", false))\n+ 602 {}\n 603\n- 604 // if we didn't see col size before\n- 605 if (col_offsets[col + 1] == null_offset) // write it in the offset vector\n- 606 col_offsets[col + 1] = sub_size.first;\n- 607\n- 608 // repeat proces for row sizes\n- 609 if (row_offsets[row + 1] == null_offset)\n- 610 row_offsets[row + 1] = sub_size.second;\n- 611 });\n- 612\n- 613 // if some rows/cols were not visited, make an educated guess with the\n-minimum offset\n- 614 auto min_row_offset = *std::min_element(begin(row_offsets), end\n-(row_offsets));\n- 615 std::replace(begin(row_offsets), end(row_offsets), null_offset,\n-min_row_offset);\n- 616 auto min_col_offset = *std::min_element(begin(col_offsets), end\n-(col_offsets));\n- 617 std::replace(begin(col_offsets), end(col_offsets), null_offset,\n-min_col_offset);\n- 618\n- 619 // we have sizes for every block: to get offsets we make a partial sum\n- 620 col_offsets[0] = interspace;\n- 621 row_offsets[0] = interspace;\n- 622 for (std::size_t i = 1; i < col_offsets.size(); i++)\n- 623 col_offsets[i] += col_offsets[i - 1] + interspace;\n- 624 for (std::size_t i = 1; i < row_offsets.size(); i++)\n- 625 row_offsets[i] += row_offsets[i - 1] + interspace;\n- 626\n- 627 for_each_entry([&](const auto &row, const auto &col, const auto &val) {\n- 628 // calculate svg view from offsets\n- 629 std::size_t width =\n- 630 col_offsets[col + 1] - col_offsets[col] - interspace;\n- 631 std::size_t height =\n- 632 row_offsets[row + 1] - row_offsets[row] - interspace;\n- 633 row_prefix.back() = row;\n- 634 col_prefix.back() = col;\n- 635 // content of the sub-block has origin at {0,0}: shift it to the correct\n-place\n- 636 ss << \"\\n\";\n- 638 // write a nested svg with the contents of the sub-block\n- 639 writeSVGMatrix(val, ss, opts, row_prefix, col_prefix);\n- 640 ss << \"\\n\";\n- 641 });\n- 642 col_offset = col_offsets.back();\n- 643 row_offset = row_offsets.back();\n- 644 }\n- 645\n- 646 // write content in order!\n- 647 // (i) if required, first header\n- 648 if (write_header)\n- 649 writeSVGMatrixHeader(out, opts, {col_offset, row_offset});\n+612 SeqILU (const M& A, int n, real_field_type w, const bool resort = false )\n+ 613 : ILU_(),\n+ 614 lower_(),\n+ 615 upper_(),\n+ 616 inv_(),\n+ 617 w_(w),\n+ 618 wNotIdentity_([w]{using std::abs; return abs(w - real_field_type(1)) > 1e-\n+15;}() )\n+ 619 {\n+ 620 if( n == 0 )\n+ 621 {\n+ 622 // copy A\n+ 623 ILU_.reset( new matrix_type( A ) );\n+ 624 // create ILU(0) decomposition\n+ 625 ILU::blockILU0Decomposition( *ILU_ );\n+ 626 }\n+ 627 else\n+ 628 {\n+ 629 // create matrix in build mode\n+ 630 ILU_.reset( new matrix_type( A.N(), A.M(), matrix_type::row_wise) );\n+ 631 // create ILU(n) decomposition\n+ 632 ILU::blockILUDecomposition( A, n, *ILU_ );\n+ 633 }\n+ 634\n+ 635 if( resort )\n+ 636 {\n+ 637 // store ILU in simple CRS format\n+ 638 ILU::convertToCRS( *ILU_, lower_, upper_, inv_ );\n+ 639 ILU_.reset();\n+ 640 }\n+ 641 }\n+ 642\n+648 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n+ 649 {}\n 650\n- 651 col_prefix.pop_back();\n- 652 row_prefix.pop_back();\n- 653 // (ii) an svg block for this level\n- 654 opts.writeSVGBlock(out, row_prefix, col_prefix, mat,\n- 655 {0, 0, col_offset, row_offset});\n- 656 // (iii) the content of the matrix\n- 657 out << ss.str();\n- 658 // (iv) if required, close the header\n- 659 if (write_header)\n- 660 out << \"\\n\\n\";\n- 661\n- 662 // return the total required for this block\n- 663 return {col_offset, row_offset};\n- 664 }\n- 665 } // namespace Impl\n+656 virtual void apply (X& v, const Y& d)\n+ 657 {\n+ 658 if( ILU_ )\n+ 659 {\n+ 660 ILU::blockILUBacksolve( *ILU_, v, d);\n+ 661 }\n+ 662 else\n+ 663 {\n+ 664 ILU::blockILUBacksolve(lower_, upper_, inv_, v, d);\n+ 665 }\n 666\n- 667\n-674 struct DefaultSVGMatrixOptions {\n-676 std::size_t block_size = 10;\n-678 std::size_t interspace = 5;\n-680 std::size_t width = 500;\n-682 std::size_t height = 0;\n-684 bool write_header = true;\n-686 std::string style = \" .matrix-block {\\n\"\n- 687 \" fill: cornflowerblue;\\n\"\n- 688 \" fill-opacity: 0.4;\\n\"\n- 689 \" stroke-width: 2;\\n\"\n- 690 \" stroke: black;\\n\"\n- 691 \" stroke-opacity: 0.5;\\n\"\n- 692 \" }\\n\"\n- 693 \" .matrix-block:hover {\\n\"\n- 694 \" fill: lightcoral;\\n\"\n- 695 \" fill-opacity: 0.4;\\n\"\n- 696 \" stroke-opacity: 1;\\n\"\n- 697 \" }\\n\";\n- 698\n-710 std::function color_fill;\n- 711\n- 717 template \n-718 std::string blockStyleClass(const RowPrefix &row_prefix,\n- 719 const ColPrefix &col_prefix) const {\n- 720 // here, you can potentially give a different style to each block\n- 721 return \"matrix-block\";\n- 722 }\n- 723\n-725 bool write_block_title = true;\n- 726\n- 732 template \n-733 void writeBlockTitle(Stream& out, const RowPrefix &row_prefix,\n- 734 const ColPrefix &col_prefix,\n- 735 const Block &block) const {\n- 736 if (this->write_block_title) {\n- 737 out << \"\";\n- 738 assert(row_prefix.size() == col_prefix.size());\n- 739 for (std::size_t i = 0; i < row_prefix.size(); ++i)\n- 740 out << \"[\" << row_prefix[i] << \", \"<< col_prefix[i] << \"]\";\n- 741 if constexpr (Dune::blockLevel<Block>() == 0)\n- 742 out << \": \" << block;\n- 743 out << \"\\n\";\n- 744 }\n- 745 }\n- 746\n- 768 template \n-769 void writeSVGBlock(Stream &out,\n- 770 const RowPrefix &row_prefix,\n- 771 const ColPrefix &col_prefix, const Block block,\n- 772 const std::array &svg_box) const {\n- 773 // get bounding box values\n- 774 auto &[x_off, y_off, width, height] = svg_box;\n- 775 // get style class\n- 776 std::string block_class = this->blockStyleClass(row_prefix, col_prefix);\n- 777 // write a rectangle on the bounding box\n- 778 out << \"() == 0 and std::\n-is_convertible{})\n- 781 if (color_fill)\n- 782 out << \" style='fill-opacity: 1;fill:\" << color_fill(double(block)) <<\n-\"'\";\n- 783\n- 784 out << \">\\n\";\n- 785 // give the rectangle a title (in html this shows info about the block)\n- 786 this->writeBlockTitle(out,row_prefix, col_prefix, block);\n- 787 // close rectangle\n- 788 out << \"\\n\";\n- 789 }\n- 790 };\n- 791\n- 806 template \n-807 void writeSVGMatrix(const Mat &mat, std::ostream &out,\n- 808 SVGOptions opts = {}) {\n- 809 // We need a vector that can fit all the multi-indices for rows and colums\n- 810 using IndexPrefix = Dune::ReservedVector()>;\n- 811 // Call overload for Mat type\n- 812 Impl::writeSVGMatrix(mat, out, opts, IndexPrefix{}, IndexPrefix{});\n- 813 }\n- 814\n- 817} // namespace Dune\n- 818\n- 819#endif\n-blocklevel.hh\n-Helper functions for determining the vector/matrix block level.\n+ 667 if( wNotIdentity_ )\n+ 668 {\n+ 669 v *= w_;\n+ 670 }\n+ 671 }\n+ 672\n+678 virtual void post ([[maybe_unused]] X& x)\n+ 679 {}\n+ 680\n+682 virtual SolverCategory::Category category() const\n+ 683 {\n+ 684 return SolverCategory::sequential;\n+ 685 }\n+ 686\n+ 687 protected:\n+689 std::unique_ptr< matrix_type > ILU_;\n+ 690\n+692 CRS lower_;\n+693 CRS upper_;\n+694 std::vector< block_type, typename matrix_type::allocator_type > inv_;\n+ 695\n+697 const real_field_type w_;\n+699 const bool wNotIdentity_;\n+ 700 };\n+701 DUNE_REGISTER_PRECONDITIONER(\"ilu\",\n+defaultPreconditionerBlockLevelCreator());\n+ 702\n+ 703\n+ 712 template\n+713 class Richardson : public Preconditioner {\n+ 714 public:\n+716 typedef X domain_type;\n+718 typedef Y range_type;\n+720 typedef typename X::field_type field_type;\n+722 typedef Simd::Scalar scalar_field_type;\n+724 typedef typename FieldTraits::real_type real_field_type;\n+ 725\n+731 Richardson (real_field_type w=1.0) :\n+ 732 _w(w)\n+ 733 {}\n+ 734\n+746 Richardson (const ParameterTree& configuration)\n+ 747 : Richardson(configuration.get(\"relaxation\", 1.0))\n+ 748 {}\n+ 749\n+755 virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& b)\n+ 756 {}\n+ 757\n+763 virtual void apply (X& v, const Y& d)\n+ 764 {\n+ 765 v = d;\n+ 766 v *= _w;\n+ 767 }\n+ 768\n+774 virtual void post ([[maybe_unused]] X& x)\n+ 775 {}\n+ 776\n+778 virtual SolverCategory::Category category() const\n+ 779 {\n+ 780 return SolverCategory::sequential;\n+ 781 }\n+ 782\n+ 783 private:\n+ 785 real_field_type _w;\n+ 786 };\n+787 DUNE_REGISTER_PRECONDITIONER(\"richardson\", [](auto tl, const auto& /* mat\n+*/, const ParameterTree& config){\n+ 788 using D = typename Dune::TypeListElement<1, decltype(tl)>::type;\n+ 789 using R = typename Dune::TypeListElement<2, decltype(tl)>::type;\n+ 790 return std::make_shared>(config);\n+ 791 });\n+ 792\n+ 793\n+ 804 template< class M, class X, class Y >\n+805 class SeqILDL\n+ 806 : public Preconditioner< X, Y >\n+ 807 {\n+ 808 typedef SeqILDL<_M,_X,_Y_> This;\n+ 809 typedef Preconditioner<_X,_Y_> Base;\n+ 810\n+ 811 public:\n+813 typedef std::remove_const_t< M > matrix_type;\n+815 typedef X domain_type;\n+817 typedef Y range_type;\n+819 typedef typename X::field_type field_type;\n+821 typedef Simd::Scalar scalar_field_type;\n+823 typedef typename FieldTraits::real_type real_field_type;\n+ 824\n+837 SeqILDL (const std::shared_ptr>& A,\n+const ParameterTree& configuration)\n+ 838 : SeqILDL(A->getmat(), configuration)\n+ 839 {}\n+ 840\n+853 SeqILDL(const matrix_type& A, const ParameterTree& config)\n+ 854 : SeqILDL(A, config.get(\"relaxation\", 1.0))\n+ 855 {}\n+ 856\n+865 explicit SeqILDL ( const matrix_type &A, real_field_type relax =\n+real_field_type( 1 ) )\n+ 866 : decomposition_( A.N(), A.M(), matrix_type::random ),\n+ 867 relax_( relax )\n+ 868 {\n+ 869 // setup row sizes for lower triangular matrix\n+ 870 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 871 {\n+ 872 const auto &A_i = *i;\n+ 873 const auto ij = A_i.find( i.index() );\n+ 874 if( ij != A_i.end() )\n+ 875 decomposition_.setrowsize( i.index(), ij.offset()+1 );\n+ 876 else\n+ 877 DUNE_THROW( ISTLError, \"diagonal entry missing\" );\n+ 878 }\n+ 879 decomposition_.endrowsizes();\n+ 880\n+ 881 // setup row indices for lower triangular matrix\n+ 882 for( auto i = A.begin(), iend = A.end(); i != iend; ++i )\n+ 883 {\n+ 884 const auto &A_i = *i;\n+ 885 for( auto ij = A_i.begin(); ij.index() < i.index() ; ++ij )\n+ 886 decomposition_.addindex( i.index(), ij.index() );\n+ 887 decomposition_.addindex( i.index(), i.index() );\n+ 888 }\n+ 889 decomposition_.endindices();\n+ 890\n+ 891 // copy values of lower triangular matrix\n+ 892 auto i = A.begin();\n+ 893 for( auto row = decomposition_.begin(), rowend = decomposition_.end(); row\n+!= rowend; ++row, ++i )\n+ 894 {\n+ 895 auto ij = i->begin();\n+ 896 for( auto col = row->begin(), colend = row->end(); col != colend; ++col,\n+++ij )\n+ 897 *col = *ij;\n+ 898 }\n+ 899\n+ 900 // perform ILDL decomposition\n+ 901 bildl_decompose( decomposition_ );\n+ 902 }\n+ 903\n+905 void pre ([[maybe_unused]] X &x, [[maybe_unused]] Y &b) override\n+ 906 {}\n+ 907\n+909 void apply ( X &v, const Y &d ) override\n+ 910 {\n+ 911 bildl_backsolve( decomposition_, v, d, true );\n+ 912 v *= relax_;\n+ 913 }\n+ 914\n+916 void post ([[maybe_unused]] X &x) override\n+ 917 {}\n+ 918\n+920 SolverCategory::Category category () const override { return\n+SolverCategory::sequential; }\n+ 921\n+ 922 private:\n+ 923 matrix_type decomposition_;\n+ 924 real_field_type relax_;\n+ 925 };\n+926 DUNE_REGISTER_PRECONDITIONER(\"ildl\", defaultPreconditionerCreator());\n+ 927\n+ 930} // end namespace\n+ 931\n+ 932\n+ 933#endif\n+solverregistry.hh\n+ildl.hh\n+Incomplete LDL decomposition.\n+solver.hh\n+Define general, extensible interface for inverse operators.\n matrixutils.hh\n Some handy generic functions for ISTL matrices.\n+preconditioner.hh\n istlexception.hh\n-bcrsmatrix.hh\n-Implementation of the BCRSMatrix class.\n+gsetc.hh\n+Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n+generic way.\n+ilu.hh\n+The incomplete LU factorization kernels.\n+solvercategory.hh\n col\n Col col\n Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::writeSVGMatrix\n-void writeSVGMatrix(const Mat &mat, std::ostream &out, SVGOptions opts={})\n-Writes the visualization of matrix in the SVG format.\n-Definition: io.hh:807\n-Dune::writeMatrixToMatlab\n-void writeMatrixToMatlab(const MatrixType &matrix, const std::string &filename,\n-int outputPrecision=18)\n-Writes sparse matrix in a Matlab-readable format.\n-Definition: io.hh:451\n-Dune::print_row\n-void print_row(std::ostream &s, const K &value, typename FieldMatrix< K, 1, 1\n->::size_type I, typename FieldMatrix< K, 1, 1 >::size_type J, typename\n-FieldMatrix< K, 1, 1 >::size_type therow, int width, int precision, typename\n-std::enable_if_t< Dune::IsNumber< K >::value > *sfinae=nullptr)\n-Print one row of a matrix, specialization for number types.\n-Definition: io.hh:151\n-Dune::printmatrix\n-void printmatrix(std::ostream &s, const M &A, std::string title, std::string\n-rowtext, int width=10, int precision=2)\n-Print a generic block matrix.\n-Definition: io.hh:213\n-Dune::printvector\n-void printvector(std::ostream &s, const V &v, std::string title, std::string\n-rowtext, int columns=1, int width=10, int precision=2)\n-Print an ISTL vector.\n-Definition: io.hh:89\n-Dune::writeMatrixToMatlabHelper\n-void writeMatrixToMatlabHelper(const FieldType &value, int rowOffset, int\n-colOffset, std::ostream &s, typename std::enable_if_t< Dune::IsNumber<\n-FieldType >::value > *sfinae=nullptr)\n-Helper method for the writeMatrixToMatlab routine.\n-Definition: io.hh:379\n-Dune::writeVectorToMatlabHelper\n-void writeVectorToMatlabHelper(const V &v, std::ostream &stream)\n-Definition: io.hh:464\n-Dune::writeVectorToMatlab\n-void writeVectorToMatlab(const VectorType &vector, const std::string &filename,\n-int outputPrecision=18)\n-Writes vectors in a Matlab-readable format.\n-Definition: io.hh:492\n-Dune::recursive_printvector\n-void recursive_printvector(std::ostream &s, const V &v, std::string rowtext,\n-int &counter, int columns, int width)\n-Recursively print a vector.\n-Definition: io.hh:52\n-Dune::printSparseMatrix\n-void printSparseMatrix(std::ostream &s, const BCRSMatrix< FieldMatrix< B, n, m\n->, A > &mat, std::string title, std::string rowtext, int width=3, int\n-precision=2)\n-Prints a BCRSMatrix with fixed sized blocks.\n-Definition: io.hh:271\n-Dune::fill_row\n-void fill_row(std::ostream &s, int m, int width, int precision)\n-Print a row of zeros for a non-existing block.\n-Definition: io.hh:133\n-std\n-STL namespace.\n+Dune::bsorb\n+void bsorb(const M &A, X &x, const Y &b, const K &w)\n+SSOR step.\n+Definition: gsetc.hh:646\n+Dune::dbjac\n+void dbjac(const M &A, X &x, const Y &b, const K &w)\n+Jacobi step.\n+Definition: gsetc.hh:658\n+Dune::bsorf\n+void bsorf(const M &A, X &x, const Y &b, const K &w)\n+SOR step.\n+Definition: gsetc.hh:634\n Dune\n Definition: allocator.hh:11\n-Dune::operator<<\n-std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)\n-Send BlockVector to an output stream.\n-Definition: bvector.hh:590\n-Dune::MatrixDimension\n-Definition: matrixutils.hh:211\n-Dune::MatrixDimension::coldim\n-static auto coldim(const M &A)\n-Definition: matrixutils.hh:219\n-Dune::MatrixDimension::rowdim\n-static auto rowdim(const M &A)\n-Definition: matrixutils.hh:214\n-Dune::BCRSMatrix\n-A sparse block matrix with compressed row storage.\n-Definition: bcrsmatrix.hh:466\n-Dune::DefaultSVGMatrixOptions\n-Default options class to write SVG matrices.\n-Definition: io.hh:674\n-Dune::DefaultSVGMatrixOptions::style\n-std::string style\n-CSS style block to write in header.\n-Definition: io.hh:686\n-Dune::DefaultSVGMatrixOptions::width\n-std::size_t width\n-Final width size (pixels) of the SVG header. If 0, size is automatic.\n-Definition: io.hh:680\n-Dune::DefaultSVGMatrixOptions::color_fill\n-std::function< std::string(const double &)> color_fill\n-Color fill for default options.\n-Definition: io.hh:710\n-Dune::DefaultSVGMatrixOptions::block_size\n-std::size_t block_size\n-size (pixels) of the deepst block/value of the matrix\n-Definition: io.hh:676\n-Dune::DefaultSVGMatrixOptions::writeSVGBlock\n-void writeSVGBlock(Stream &out, const RowPrefix &row_prefix, const ColPrefix\n-&col_prefix, const Block block, const std::array< std::size_t, 4 > &svg_box)\n-const\n-Write an SVG object for a given block/value in the matrix.\n-Definition: io.hh:769\n-Dune::DefaultSVGMatrixOptions::writeBlockTitle\n-void writeBlockTitle(Stream &out, const RowPrefix &row_prefix, const ColPrefix\n-&col_prefix, const Block &block) const\n-Helper function writes a title for a given block and prefix.\n-Definition: io.hh:733\n-Dune::DefaultSVGMatrixOptions::interspace\n-std::size_t interspace\n-size (pixels) of the interspace between blocks\n-Definition: io.hh:678\n-Dune::DefaultSVGMatrixOptions::write_block_title\n-bool write_block_title\n-(Helper) Whether to write a title on the rectangle value\n-Definition: io.hh:725\n-Dune::DefaultSVGMatrixOptions::height\n-std::size_t height\n-Final height size (pixels) of the SVG header. If 0, size is automatic.\n-Definition: io.hh:682\n-Dune::DefaultSVGMatrixOptions::write_header\n-bool write_header\n-Whether to write the SVG header.\n-Definition: io.hh:684\n-Dune::DefaultSVGMatrixOptions::blockStyleClass\n-std::string blockStyleClass(const RowPrefix &row_prefix, const ColPrefix\n-&col_prefix) const\n-Helper function that returns an style class for a given prefix.\n-Definition: io.hh:718\n-Dune::MatrixImp::DenseMatrixBase::ConstIterator\n-ConstIterator class for sequential access.\n-Definition: matrix.hh:404\n-Dune::Matrix\n-A generic dynamic dense matrix.\n-Definition: matrix.hh:561\n-Dune::Matrix::end\n-RowIterator end()\n-Get iterator to one beyond last row.\n-Definition: matrix.hh:620\n-Dune::Matrix::begin\n-RowIterator begin()\n-Get iterator to first row.\n-Definition: matrix.hh:614\n-Dune::Matrix::ConstColIterator\n-row_type::const_iterator ConstColIterator\n-Const iterator for the entries of each row.\n-Definition: matrix.hh:589\n+Dune::bildl_decompose\n+void bildl_decompose(Matrix &A)\n+compute ILDL decomposition of a symmetric matrix A\n+Definition: ildl.hh:88\n+Dune::get\n+PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::\n+VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag,\n+Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)\n+Definition: dependency.hh:293\n+Dune::DUNE_REGISTER_PRECONDITIONER\n+DUNE_REGISTER_PRECONDITIONER(\"amg\", AMGCreator())\n+Dune::bildl_backsolve\n+void bildl_backsolve(const Matrix &A, X &v, const Y &d, bool\n+isLowerTriangular=false)\n+Definition: ildl.hh:149\n+Dune::ILU::convertToCRS\n+void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)\n+convert ILU decomposition into CRS format for lower and upper triangular and\n+inverse.\n+Definition: ilu.hh:307\n+Dune::ILU::blockILUBacksolve\n+void blockILUBacksolve(const M &A, X &v, const Y &d)\n+LU backsolve with stored inverse.\n+Definition: ilu.hh:94\n+Dune::ILU::blockILU0Decomposition\n+void blockILU0Decomposition(M &A)\n+compute ILU decomposition of A. A is overwritten by its decomposition\n+Definition: ilu.hh:33\n+Dune::ILU::blockILUDecomposition\n+void blockILUDecomposition(const M &A, int n, M &ILU)\n+Definition: ilu.hh:167\n+Dune::BL\n+compile-time parameter for block recursion depth\n+Definition: gsetc.hh:45\n+Dune::ILU::CRS<_block_type,_typename_M::allocator_type_>\n+Dune::ISTLError\n+derive error class from the base class in common\n+Definition: istlexception.hh:19\n Dune::Matrix::M\n size_type M() const\n Return the number of columns.\n Definition: matrix.hh:700\n Dune::Matrix::N\n size_type N() const\n Return the number of rows.\n Definition: matrix.hh:695\n-Dune::FieldMatrix\n-Definition: matrixutils.hh:27\n+Dune::CheckIfDiagonalPresent::check\n+static void check(const Matrix &mat)\n+Check whether the a matrix has diagonal values on blocklevel recursion levels.\n+Definition: matrixutils.hh:53\n+Dune::AssembledLinearOperator\n+A linear operator exporting itself in matrix form.\n+Definition: operators.hh:109\n+Dune::Preconditioner\n+Base class for matrix free definition of preconditioners.\n+Definition: preconditioner.hh:32\n+Dune::InverseOperator2Preconditioner\n+Turns an InverseOperator into a Preconditioner.\n+Definition: preconditioners.hh:75\n+Dune::InverseOperator2Preconditioner::range_type\n+O::range_type range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:80\n+Dune::InverseOperator2Preconditioner::domain_type\n+O::domain_type domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:78\n+Dune::InverseOperator2Preconditioner::post\n+virtual void post(domain_type &)\n+Clean up.\n+Definition: preconditioners.hh:111\n+Dune::InverseOperator2Preconditioner::field_type\n+range_type::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:82\n+Dune::InverseOperator2Preconditioner::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:86\n+Dune::InverseOperator2Preconditioner::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:84\n+Dune::InverseOperator2Preconditioner::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:115\n+Dune::InverseOperator2Preconditioner::pre\n+virtual void pre(domain_type &, range_type &)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:101\n+Dune::InverseOperator2Preconditioner::InverseOperator2Preconditioner\n+InverseOperator2Preconditioner(InverseOperator &inverse_operator)\n+Construct the preconditioner from the solver.\n+Definition: preconditioners.hh:94\n+Dune::InverseOperator2Preconditioner::InverseOperator\n+O InverseOperator\n+type of the wrapped inverse operator\n+Definition: preconditioners.hh:88\n+Dune::InverseOperator2Preconditioner::apply\n+virtual void apply(domain_type &v, const range_type &d)\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: preconditioners.hh:104\n+Dune::SeqSSOR\n+Sequential SSOR preconditioner.\n+Definition: preconditioners.hh:141\n+Dune::SeqSSOR::post\n+virtual void post(X &x)\n+Clean up.\n+Definition: preconditioners.hh:229\n+Dune::SeqSSOR::SeqSSOR\n+SeqSSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n+const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:182\n+Dune::SeqSSOR::SeqSSOR\n+SeqSSOR(const M &A, const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:199\n+Dune::SeqSSOR::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:233\n+Dune::SeqSSOR::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:150\n+Dune::SeqSSOR::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:152\n+Dune::SeqSSOR::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:146\n+Dune::SeqSSOR::matrix_type\n+M matrix_type\n+The matrix type the preconditioner is for.\n+Definition: preconditioners.hh:144\n+Dune::SeqSSOR::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the preconditioner.\n+Definition: preconditioners.hh:216\n+Dune::SeqSSOR::pre\n+virtual void pre(X &x, Y &b)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:208\n+Dune::SeqSSOR::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:148\n+Dune::SeqSSOR::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:154\n+Dune::SeqSSOR::SeqSSOR\n+SeqSSOR(const M &A, int n, real_field_type w)\n+Constructor.\n+Definition: preconditioners.hh:163\n+Dune::SeqSOR\n+Sequential SOR preconditioner.\n+Definition: preconditioners.hh:261\n+Dune::SeqSOR::SeqSOR\n+SeqSOR(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n+const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:302\n+Dune::SeqSOR::matrix_type\n+M matrix_type\n+The matrix type the preconditioner is for.\n+Definition: preconditioners.hh:264\n+Dune::SeqSOR::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:274\n+Dune::SeqSOR::apply\n+void apply(X &v, const Y &d)\n+Apply the preconditioner in a special direction.\n+Definition: preconditioners.hh:350\n+Dune::SeqSOR::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:266\n+Dune::SeqSOR::post\n+virtual void post(X &x)\n+Clean up.\n+Definition: preconditioners.hh:367\n+Dune::SeqSOR::pre\n+virtual void pre(X &x, Y &b)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:328\n+Dune::SeqSOR::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:272\n+Dune::SeqSOR::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:371\n+Dune::SeqSOR::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the preconditioner.\n+Definition: preconditioners.hh:336\n+Dune::SeqSOR::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:268\n+Dune::SeqSOR::SeqSOR\n+SeqSOR(const M &A, const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:319\n+Dune::SeqSOR::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:270\n+Dune::SeqSOR::SeqSOR\n+SeqSOR(const M &A, int n, real_field_type w)\n+Constructor.\n+Definition: preconditioners.hh:283\n+Dune::SeqJac\n+The sequential jacobian preconditioner.\n+Definition: preconditioners.hh:412\n+Dune::SeqJac::post\n+virtual void post(X &x)\n+Clean up.\n+Definition: preconditioners.hh:499\n+Dune::SeqJac::SeqJac\n+SeqJac(const M &A, const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:470\n+Dune::SeqJac::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the preconditioner.\n+Definition: preconditioners.hh:487\n+Dune::SeqJac::matrix_type\n+M matrix_type\n+The matrix type the preconditioner is for.\n+Definition: preconditioners.hh:415\n+Dune::SeqJac::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:423\n+Dune::SeqJac::SeqJac\n+SeqJac(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n+const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:453\n+Dune::SeqJac::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:421\n+Dune::SeqJac::pre\n+virtual void pre(X &x, Y &b)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:479\n+Dune::SeqJac::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:417\n+Dune::SeqJac::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:425\n+Dune::SeqJac::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:503\n+Dune::SeqJac::SeqJac\n+SeqJac(const M &A, int n, real_field_type w)\n+Constructor.\n+Definition: preconditioners.hh:434\n+Dune::SeqJac::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:419\n+Dune::SeqILU\n+Sequential ILU preconditioner.\n+Definition: preconditioners.hh:532\n+Dune::SeqILU::post\n+virtual void post(X &x)\n+Clean up.\n+Definition: preconditioners.hh:678\n+Dune::SeqILU::SeqILU\n+SeqILU(const M &A, int n, real_field_type w, const bool resort=false)\n+Constructor.\n+Definition: preconditioners.hh:612\n+Dune::SeqILU::pre\n+virtual void pre(X &x, Y &b)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:648\n+Dune::SeqILU::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the preconditioner.\n+Definition: preconditioners.hh:656\n+Dune::SeqILU::CRS\n+ILU::CRS< block_type, typename M::allocator_type > CRS\n+type of ILU storage\n+Definition: preconditioners.hh:552\n+Dune::SeqILU::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:541\n+Dune::SeqILU::lower_\n+CRS lower_\n+The ILU(n) decomposition of the matrix. As storage a CRS structure is used.\n+Definition: preconditioners.hh:692\n+Dune::SeqILU::wNotIdentity_\n+const bool wNotIdentity_\n+true if w != 1.0\n+Definition: preconditioners.hh:699\n+Dune::SeqILU::SeqILU\n+SeqILU(const M &A, const ParameterTree &config)\n+Constructor.\n+Definition: preconditioners.hh:598\n+Dune::SeqILU::matrix_type\n+std::remove_const< M >::type matrix_type\n+The matrix type the preconditioner is for.\n+Definition: preconditioners.hh:535\n+Dune::SeqILU::block_type\n+matrix_type::block_type block_type\n+block type of matrix\n+Definition: preconditioners.hh:537\n+Dune::SeqILU::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:549\n+Dune::SeqILU::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:544\n+Dune::SeqILU::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:682\n+Dune::SeqILU::SeqILU\n+SeqILU(const M &A, real_field_type w, const bool resort=false)\n+Constructor.\n+Definition: preconditioners.hh:561\n+Dune::SeqILU::w_\n+const real_field_type w_\n+The relaxation factor to use.\n+Definition: preconditioners.hh:697\n+Dune::SeqILU::SeqILU\n+SeqILU(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n+const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:580\n+Dune::SeqILU::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:539\n+Dune::SeqILU::inv_\n+std::vector< block_type, typename matrix_type::allocator_type > inv_\n+Definition: preconditioners.hh:694\n+Dune::SeqILU::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:547\n+Dune::SeqILU::ILU_\n+std::unique_ptr< matrix_type > ILU_\n+The ILU(n) decomposition of the matrix. As storage a BCRSMatrix is used.\n+Definition: preconditioners.hh:689\n+Dune::SeqILU::upper_\n+CRS upper_\n+Definition: preconditioners.hh:693\n+Dune::Richardson\n+Richardson preconditioner.\n+Definition: preconditioners.hh:713\n+Dune::Richardson::field_type\n+X::field_type field_type\n+The field type of the preconditioner.\n+Definition: preconditioners.hh:720\n+Dune::Richardson::category\n+virtual SolverCategory::Category category() const\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:778\n+Dune::Richardson::range_type\n+Y range_type\n+The range type of the preconditioner.\n+Definition: preconditioners.hh:718\n+Dune::Richardson::pre\n+virtual void pre(X &x, Y &b)\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:755\n+Dune::Richardson::Richardson\n+Richardson(real_field_type w=1.0)\n+Constructor.\n+Definition: preconditioners.hh:731\n+Dune::Richardson::post\n+virtual void post(X &x)\n+Clean up.\n+Definition: preconditioners.hh:774\n+Dune::Richardson::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:724\n+Dune::Richardson::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:722\n+Dune::Richardson::Richardson\n+Richardson(const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:746\n+Dune::Richardson::domain_type\n+X domain_type\n+The domain type of the preconditioner.\n+Definition: preconditioners.hh:716\n+Dune::Richardson::apply\n+virtual void apply(X &v, const Y &d)\n+Apply the precondioner.\n+Definition: preconditioners.hh:763\n+Dune::SeqILDL\n+sequential ILDL preconditioner\n+Definition: preconditioners.hh:807\n+Dune::SeqILDL::SeqILDL\n+SeqILDL(const matrix_type &A, const ParameterTree &config)\n+Constructor.\n+Definition: preconditioners.hh:853\n+Dune::SeqILDL::SeqILDL\n+SeqILDL(const matrix_type &A, real_field_type relax=real_field_type(1))\n+constructor\n+Definition: preconditioners.hh:865\n+Dune::SeqILDL::domain_type\n+X domain_type\n+domain type of the preconditioner\n+Definition: preconditioners.hh:815\n+Dune::SeqILDL::post\n+void post(X &x) override\n+Clean up.\n+Definition: preconditioners.hh:916\n+Dune::SeqILDL::range_type\n+Y range_type\n+range type of the preconditioner\n+Definition: preconditioners.hh:817\n+Dune::SeqILDL::matrix_type\n+std::remove_const_t< M > matrix_type\n+type of matrix the preconditioner is for\n+Definition: preconditioners.hh:813\n+Dune::SeqILDL::apply\n+void apply(X &v, const Y &d) override\n+Apply one step of the preconditioner to the system A(v)=d.\n+Definition: preconditioners.hh:909\n+Dune::SeqILDL::real_field_type\n+FieldTraits< scalar_field_type >::real_type real_field_type\n+real scalar type underlying the field_type\n+Definition: preconditioners.hh:823\n+Dune::SeqILDL::SeqILDL\n+SeqILDL(const std::shared_ptr< const AssembledLinearOperator< M, X, Y > > &A,\n+const ParameterTree &configuration)\n+Constructor.\n+Definition: preconditioners.hh:837\n+Dune::SeqILDL::pre\n+void pre(X &x, Y &b) override\n+Prepare the preconditioner.\n+Definition: preconditioners.hh:905\n+Dune::SeqILDL::scalar_field_type\n+Simd::Scalar< field_type > scalar_field_type\n+scalar type underlying the field_type\n+Definition: preconditioners.hh:821\n+Dune::SeqILDL::field_type\n+X::field_type field_type\n+field type of the preconditioner\n+Definition: preconditioners.hh:819\n+Dune::SeqILDL::category\n+SolverCategory::Category category() const override\n+Category of the preconditioner (see SolverCategory::Category)\n+Definition: preconditioners.hh:920\n+Dune::InverseOperatorResult\n+Statistics about the application of an inverse operator.\n+Definition: solver.hh:48\n+Dune::InverseOperator\n+Abstract base class for all solvers.\n+Definition: solver.hh:99\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00224.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00224.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: gsetc.hh File Reference\n+dune-istl: solvercategory.hh File Reference\n \n \n \n \n \n \n \n@@ -64,196 +64,35 @@\n \n \n \n
    \n \n-
    gsetc.hh File Reference
    \n+Namespaces
    \n+
    solvercategory.hh File Reference
    \n \n
    \n-\n-

    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way. \n-More...

    \n-
    #include <cmath>
    \n-#include <complex>
    \n-#include <iostream>
    \n-#include <iomanip>
    \n-#include <string>
    \n-#include <dune/common/hybridutilities.hh>
    \n-#include "multitypeblockvector.hh"
    \n-#include "multitypeblockmatrix.hh"
    \n-#include "istlexception.hh"
    \n+
    #include <dune/common/exceptions.hh>
    \n
    \n

    Go to the source code of this file.

    \n \n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n \n

    \n Classes

    struct  Dune::BL< l >
     compile-time parameter for block recursion depth More...
     
    struct  Dune::algmeta_btsolve< I, diag, relax >
     
    struct  Dune::algmeta_btsolve< 0, withdiag, withrelax >
     
    struct  Dune::algmeta_btsolve< 0, withdiag, norelax >
     
    struct  Dune::algmeta_btsolve< 0, nodiag, withrelax >
     
    struct  Dune::algmeta_btsolve< 0, nodiag, norelax >
     
    struct  Dune::algmeta_bdsolve< I, relax >
    struct  Dune::SolverCategory
     Categories for the solvers. More...
     
    struct  Dune::algmeta_bdsolve< 0, withrelax >
     
    struct  Dune::algmeta_bdsolve< 0, norelax >
     
    struct  Dune::algmeta_itsteps< I, M >
     
    struct  Dune::algmeta_itsteps< 0, M >
     
    struct  Dune::algmeta_itsteps< I, MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > >
    class  Dune::InvalidSolverCategory
     
    \n \n \n \n-

    \n Namespaces

    namespace  Dune
     
    \n-\n-\n-\n-\n-\n-

    \n-Enumerations

    enum  Dune::WithDiagType { Dune::withdiag =1\n-, Dune::nodiag =0\n- }
     
    enum  Dune::WithRelaxType { Dune::withrelax =1\n-, Dune::norelax =0\n- }
     
    \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n

    \n-Functions

    template<class M , class X , class Y >
    void Dune::bltsolve (const M &A, X &v, const Y &d)
     block lower triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::bltsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed block lower triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::ubltsolve (const M &A, X &v, const Y &d)
     unit block lower triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed unit block lower triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::butsolve (const M &A, X &v, const Y &d)
     block upper triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::butsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed block upper triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::ubutsolve (const M &A, X &v, const Y &d)
     unit block upper triangular solve More...
     
    template<class M , class X , class Y , class K >
    void Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w)
     relaxed unit block upper triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::bltsolve (const M &A, X &v, const Y &d, BL< l >)
     block lower triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     relaxed block lower triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::ubltsolve (const M &A, X &v, const Y &d, BL< l >)
     unit block lower triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     relaxed unit block lower triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::butsolve (const M &A, X &v, const Y &d, BL< l > bl)
     block upper triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::butsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)
     relaxed block upper triangular solve More...
     
    template<class M , class X , class Y , int l>
    void Dune::ubutsolve (const M &A, X &v, const Y &d, BL< l > bl)
     unit block upper triangular solve More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)
     relaxed unit block upper triangular solve More...
     
    template<class M , class X , class Y >
    void Dune::bdsolve (const M &A, X &v, const Y &d)
     block diagonal solve, no relaxation More...
     
    template<class M , class X , class Y , class K >
    void Dune::bdsolve (const M &A, X &v, const Y &d, const K &w)
     block diagonal solve, with relaxation More...
     
    template<class M , class X , class Y , int l>
    void Dune::bdsolve (const M &A, X &v, const Y &d, BL< l >)
     block diagonal solve, no relaxation More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bdsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)
     block diagonal solve, with relaxation More...
     
    template<class M , class X , class Y , class K >
    void Dune::dbgs (const M &A, X &x, const Y &b, const K &w)
     GS step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::dbgs (const M &A, X &x, const Y &b, const K &w, BL< l >)
     GS step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::bsorf (const M &A, X &x, const Y &b, const K &w)
     SOR step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bsorf (const M &A, X &x, const Y &b, const K &w, BL< l >)
     SOR step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::bsorb (const M &A, X &x, const Y &b, const K &w)
     SSOR step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::bsorb (const M &A, X &x, const Y &b, const K &w, BL< l >)
     Backward SOR step. More...
     
    template<class M , class X , class Y , class K >
    void Dune::dbjac (const M &A, X &x, const Y &b, const K &w)
     Jacobi step. More...
     
    template<class M , class X , class Y , class K , int l>
    void Dune::dbjac (const M &A, X &x, const Y &b, const K &w, BL< l >)
     Jacobi step. More...
     
    \n-

    Detailed Description

    \n-

    Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.

    \n-
    \n+
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,175 +4,23 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Classes | Namespaces | Enumerations | Functions\n-gsetc.hh File Reference\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way. More...\n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \n-#include \"multitypeblockvector.hh\"\n-#include \"multitypeblockmatrix.hh\"\n-#include \"istlexception.hh\"\n+Classes | Namespaces\n+solvercategory.hh File Reference\n+#include \n Go_to_the_source_code_of_this_file.\n Classes\n-struct \u00a0Dune::BL<_l_>\n-\u00a0 compile-time parameter for block recursion depth More...\n+struct \u00a0Dune::SolverCategory\n+\u00a0 Categories for the solvers. More...\n \u00a0\n-struct \u00a0Dune::algmeta_btsolve<_I,_diag,_relax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_btsolve<_0,_withdiag,_norelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_btsolve<_0,_nodiag,_norelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_bdsolve<_I,_relax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_bdsolve<_0,_withrelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_bdsolve<_0,_norelax_>\n-\u00a0\n-struct \u00a0Dune::algmeta_itsteps<_I,_M_>\n-\u00a0\n-struct \u00a0Dune::algmeta_itsteps<_0,_M_>\n-\u00a0\n-struct \u00a0Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,\n- MultiTypeMatrixArgs..._>_>\n+ class \u00a0Dune::InvalidSolverCategory\n \u00a0\n Namespaces\n namespace \u00a0Dune\n \u00a0\n- Enumerations\n-enum \u00a0Dune::WithDiagType { Dune::withdiag =1 , Dune::nodiag =0 }\n-\u00a0\n-enum \u00a0Dune::WithRelaxType { Dune::withrelax =1 , Dune::norelax =0 }\n-\u00a0\n- Functions\n-template\n-void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d)\n-\u00a0 block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, const K &w)\n-\u00a0 relaxed block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d)\n-\u00a0 unit block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w)\n-\u00a0 relaxed unit block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::butsolve (const M &A, X &v, const Y &d)\n-\u00a0 block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, const K &w)\n-\u00a0 relaxed block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d)\n-\u00a0 unit block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w)\n-\u00a0 relaxed unit block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, BL< l >)\n-\u00a0 block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::bltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n-\u00a0 relaxed block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, BL< l >)\n-\u00a0 unit block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubltsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n-\u00a0 relaxed unit block lower triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, BL< l > bl)\n-\u00a0 block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::butsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)\n-\u00a0 relaxed block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, BL< l > bl)\n-\u00a0 unit block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::ubutsolve (const M &A, X &v, const Y &d, const K &w, BL< l > bl)\n-\u00a0 relaxed unit block upper triangular solve More...\n-\u00a0\n-template\n-void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d)\n-\u00a0 block diagonal solve, no relaxation More...\n-\u00a0\n-template\n-void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, const K &w)\n-\u00a0 block diagonal solve, with relaxation More...\n-\u00a0\n-template\n-void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, BL< l >)\n-\u00a0 block diagonal solve, no relaxation More...\n-\u00a0\n-template\n-void\u00a0Dune::bdsolve (const M &A, X &v, const Y &d, const K &w, BL< l >)\n-\u00a0 block diagonal solve, with relaxation More...\n-\u00a0\n-template\n-void\u00a0Dune::dbgs (const M &A, X &x, const Y &b, const K &w)\n-\u00a0 GS step. More...\n-\u00a0\n-template\n-void\u00a0Dune::dbgs (const M &A, X &x, const Y &b, const K &w, BL< l >)\n-\u00a0 GS step. More...\n-\u00a0\n-template\n-void\u00a0Dune::bsorf (const M &A, X &x, const Y &b, const K &w)\n-\u00a0 SOR step. More...\n-\u00a0\n-template\n-void\u00a0Dune::bsorf (const M &A, X &x, const Y &b, const K &w, BL< l >)\n-\u00a0 SOR step. More...\n-\u00a0\n-template\n-void\u00a0Dune::bsorb (const M &A, X &x, const Y &b, const K &w)\n-\u00a0 SSOR step. More...\n-\u00a0\n-template\n-void\u00a0Dune::bsorb (const M &A, X &x, const Y &b, const K &w, BL< l >)\n-\u00a0 Backward SOR step. More...\n-\u00a0\n-template\n-void\u00a0Dune::dbjac (const M &A, X &x, const Y &b, const K &w)\n-\u00a0 Jacobi step. More...\n-\u00a0\n-template\n-void\u00a0Dune::dbjac (const M &A, X &x, const Y &b, const K &w, BL< l >)\n-\u00a0 Jacobi step. More...\n-\u00a0\n-***** Detailed Description *****\n-Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a\n-generic way.\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00224_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00224_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: gsetc.hh Source File\n+dune-istl: solvercategory.hh Source File\n \n \n \n \n \n \n \n@@ -62,701 +62,71 @@\n \n
    \n \n
    \n \n
    \n-
    gsetc.hh
    \n+
    solvercategory.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_GSETC_HH
    \n-
    6#define DUNE_ISTL_GSETC_HH
    \n+
    5#ifndef DUNE_ISTL_SOLVERCATEGORY_HH
    \n+
    6#define DUNE_ISTL_SOLVERCATEGORY_HH
    \n
    7
    \n-
    8#include <cmath>
    \n-
    9#include <complex>
    \n-
    10#include <iostream>
    \n-
    11#include <iomanip>
    \n-
    12#include <string>
    \n-
    13
    \n-
    14#include <dune/common/hybridutilities.hh>
    \n-
    15
    \n-\n-\n-
    18
    \n-
    19#include "istlexception.hh"
    \n-
    20
    \n-
    21
    \n-
    27namespace Dune {
    \n-
    28
    \n-
    39 //============================================================
    \n-
    40 // parameter types
    \n-
    41 //============================================================
    \n-
    42
    \n-
    44 template<int l>
    \n-
    45 struct BL {
    \n-
    46 enum {recursion_level = l};
    \n-
    47 };
    \n-
    48
    \n-\n-\n-
    51 nodiag=0
    \n-
    52 };
    \n+
    8#include <dune/common/exceptions.hh>
    \n+
    9
    \n+
    10
    \n+
    11namespace Dune {
    \n+
    12
    \n+\n+
    22 {
    \n+
    23 enum Category {
    \n+\n+\n+\n+
    30 };
    \n+
    31
    \n+
    33 template<typename OP>
    \n+
    34 static Category category(const OP& op, decltype(op.category())* = nullptr)
    \n+
    35 {
    \n+
    36 return op.category();
    \n+
    37 }
    \n+
    38
    \n+
    39#ifndef DOXYGEN
    \n+
    40 // template<typename OP>
    \n+
    41 // static Category category(const OP& op, decltype(op.getSolverCategory())* = nullptr)
    \n+
    42 // {
    \n+
    43 // return op.getSolverCategory();
    \n+
    44 // }
    \n+
    45
    \n+
    46 template<typename OP>
    \n+
    47 static Category category(const OP& op, decltype(op.category)* = nullptr)
    \n+
    48 {
    \n+
    49 return OP::category;
    \n+
    50 }
    \n+
    51#endif
    \n+
    52 };
    \n
    53
    \n-\n-\n-
    56 norelax=0
    \n-
    57 };
    \n-
    58
    \n-
    59 //============================================================
    \n-
    60 // generic triangular solves
    \n-
    61 // consider block decomposition A = L + D + U
    \n-
    62 // we can invert L, L+D, U, U+D
    \n-
    63 // we can apply relaxation or not
    \n-
    64 // we can recurse over a fixed number of levels
    \n-
    65 //============================================================
    \n-
    66
    \n-
    67 // template meta program for triangular solves
    \n-
    68 template<int I, WithDiagType diag, WithRelaxType relax>
    \n-\n-
    70 template<class M, class X, class Y, class K>
    \n-
    71 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    72 {
    \n-
    73 // iterator types
    \n-
    74 typedef typename M::ConstRowIterator rowiterator;
    \n-
    75 typedef typename M::ConstColIterator coliterator;
    \n-
    76 typedef typename Y::block_type bblock;
    \n-
    77
    \n-
    78 // local solve at each block and immediate update
    \n-
    79 rowiterator endi=A.end();
    \n-
    80 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    81 {
    \n-
    82 bblock rhs(d[i.index()]);
    \n-
    83 coliterator j;
    \n-
    84 for (j=(*i).begin(); j.index()<i.index(); ++j)
    \n-
    85 (*j).mmv(v[j.index()],rhs);
    \n-
    86 algmeta_btsolve<I-1,diag,relax>::bltsolve(*j,v[i.index()],rhs,w);
    \n-
    87 }
    \n-
    88 }
    \n-
    89 template<class M, class X, class Y, class K>
    \n-
    90 static void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    91 {
    \n-
    92 // iterator types
    \n-
    93 typedef typename M::ConstRowIterator rowiterator;
    \n-
    94 typedef typename M::ConstColIterator coliterator;
    \n-
    95 typedef typename Y::block_type bblock;
    \n-
    96
    \n-
    97 // local solve at each block and immediate update
    \n-
    98 rowiterator rendi=A.beforeBegin();
    \n-
    99 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n-
    100 {
    \n-
    101 bblock rhs(d[i.index()]);
    \n-
    102 coliterator j;
    \n-
    103 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)
    \n-
    104 (*j).mmv(v[j.index()],rhs);
    \n-
    105 algmeta_btsolve<I-1,diag,relax>::butsolve(*j,v[i.index()],rhs,w);
    \n-
    106 }
    \n-
    107 }
    \n-
    108 };
    \n-
    109
    \n-
    110 // recursion end ...
    \n-
    111 template<>
    \n-\n-
    113 template<class M, class X, class Y, class K>
    \n-
    114 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    115 {
    \n-
    116 A.solve(v,d);
    \n-
    117 v *= w;
    \n-
    118 }
    \n-
    119 template<class M, class X, class Y, class K>
    \n-
    120 static void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    121 {
    \n-
    122 A.solve(v,d);
    \n-
    123 v *= w;
    \n-
    124 }
    \n-
    125 };
    \n-
    126 template<>
    \n-\n-
    128 template<class M, class X, class Y, class K>
    \n-
    129 static void bltsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n-
    130 {
    \n-
    131 A.solve(v,d);
    \n-
    132 }
    \n-
    133 template<class M, class X, class Y, class K>
    \n-
    134 static void butsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n-
    135 {
    \n-
    136 A.solve(v,d);
    \n-
    137 }
    \n-
    138 };
    \n-
    139 template<>
    \n-\n-
    141 template<class M, class X, class Y, class K>
    \n-
    142 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& w)
    \n-
    143 {
    \n-
    144 v = d;
    \n-
    145 v *= w;
    \n-
    146 }
    \n-
    147 template<class M, class X, class Y, class K>
    \n-
    148 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& w)
    \n-
    149 {
    \n-
    150 v = d;
    \n-
    151 v *= w;
    \n-
    152 }
    \n-
    153 };
    \n-
    154 template<>
    \n-\n-
    156 template<class M, class X, class Y, class K>
    \n-
    157 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
    \n-
    158 {
    \n-
    159 v = d;
    \n-
    160 }
    \n-
    161 template<class M, class X, class Y, class K>
    \n-
    162 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
    \n-
    163 {
    \n-
    164 v = d;
    \n-
    165 }
    \n-
    166 };
    \n-
    167
    \n-
    168
    \n-
    169 // user calls
    \n-
    170
    \n-
    171 // default block recursion level = 1
    \n-
    172
    \n-
    174 template<class M, class X, class Y>
    \n-
    175 void bltsolve (const M& A, X& v, const Y& d)
    \n-
    176 {
    \n-
    177 typename X::field_type w=1;
    \n-\n-
    179 }
    \n-
    181 template<class M, class X, class Y, class K>
    \n-
    182 void bltsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    183 {
    \n-\n-
    185 }
    \n-
    187 template<class M, class X, class Y>
    \n-
    188 void ubltsolve (const M& A, X& v, const Y& d)
    \n-
    189 {
    \n-
    190 typename X::field_type w=1;
    \n-\n-
    192 }
    \n-
    194 template<class M, class X, class Y, class K>
    \n-
    195 void ubltsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    196 {
    \n-\n-
    198 }
    \n-
    199
    \n-
    201 template<class M, class X, class Y>
    \n-
    202 void butsolve (const M& A, X& v, const Y& d)
    \n-
    203 {
    \n-
    204 typename X::field_type w=1;
    \n-\n-
    206 }
    \n-
    208 template<class M, class X, class Y, class K>
    \n-
    209 void butsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    210 {
    \n-\n-
    212 }
    \n-
    214 template<class M, class X, class Y>
    \n-
    215 void ubutsolve (const M& A, X& v, const Y& d)
    \n-
    216 {
    \n-
    217 typename X::field_type w=1;
    \n-\n-
    219 }
    \n-
    221 template<class M, class X, class Y, class K>
    \n-
    222 void ubutsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    223 {
    \n-\n-
    225 }
    \n-
    226
    \n-
    227 // general block recursion level >= 0
    \n-
    228
    \n-
    230 template<class M, class X, class Y, int l>
    \n-
    231 void bltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n-
    232 {
    \n-
    233 typename X::field_type w=1;
    \n-\n-
    235 }
    \n-
    237 template<class M, class X, class Y, class K, int l>
    \n-
    238 void bltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n-
    239 {
    \n-\n-
    241 }
    \n-
    243 template<class M, class X, class Y, int l>
    \n-
    244 void ubltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n-
    245 {
    \n-
    246 typename X::field_type w=1;
    \n-\n-
    248 }
    \n-
    250 template<class M, class X, class Y, class K, int l>
    \n-
    251 void ubltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n-
    252 {
    \n-\n-
    254 }
    \n-
    255
    \n-
    257 template<class M, class X, class Y, int l>
    \n-
    258 void butsolve (const M& A, X& v, const Y& d, BL<l> bl)
    \n-
    259 {
    \n-
    260 typename X::field_type w=1;
    \n-\n-
    262 }
    \n-
    264 template<class M, class X, class Y, class K, int l>
    \n-
    265 void butsolve (const M& A, X& v, const Y& d, const K& w, BL<l> bl)
    \n-
    266 {
    \n-\n-
    268 }
    \n-
    270 template<class M, class X, class Y, int l>
    \n-
    271 void ubutsolve (const M& A, X& v, const Y& d, BL<l> bl)
    \n-
    272 {
    \n-
    273 typename X::field_type w=1;
    \n-\n-
    275 }
    \n-
    277 template<class M, class X, class Y, class K, int l>
    \n-
    278 void ubutsolve (const M& A, X& v, const Y& d, const K& w, BL<l> bl)
    \n-
    279 {
    \n-\n-
    281 }
    \n-
    282
    \n-
    283
    \n-
    284
    \n-
    285 //============================================================
    \n-
    286 // generic block diagonal solves
    \n-
    287 // consider block decomposition A = L + D + U
    \n-
    288 // we can apply relaxation or not
    \n-
    289 // we can recurse over a fixed number of levels
    \n-
    290 //============================================================
    \n-
    291
    \n-
    292 // template meta program for diagonal solves
    \n-
    293 template<int I, WithRelaxType relax>
    \n-\n-
    295 template<class M, class X, class Y, class K>
    \n-
    296 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    297 {
    \n-
    298 // iterator types
    \n-
    299 typedef typename M::ConstRowIterator rowiterator;
    \n-
    300 typedef typename M::ConstColIterator coliterator;
    \n-
    301
    \n-
    302 // local solve at each block and immediate update
    \n-
    303 rowiterator rendi=A.beforeBegin();
    \n-
    304 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)
    \n-
    305 {
    \n-
    306 coliterator ii=(*i).find(i.index());
    \n-
    307 algmeta_bdsolve<I-1,relax>::bdsolve(*ii,v[i.index()],d[i.index()],w);
    \n-
    308 }
    \n-
    309 }
    \n-
    310 };
    \n-
    311
    \n-
    312 // recursion end ...
    \n-
    313 template<>
    \n-\n-
    315 template<class M, class X, class Y, class K>
    \n-
    316 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    317 {
    \n-
    318 A.solve(v,d);
    \n-
    319 v *= w;
    \n-
    320 }
    \n-
    321 };
    \n-
    322 template<>
    \n-\n-
    324 template<class M, class X, class Y, class K>
    \n-
    325 static void bdsolve (const M& A, X& v, const Y& d, const K& /*w*/)
    \n-
    326 {
    \n-
    327 A.solve(v,d);
    \n-
    328 }
    \n-
    329 };
    \n-
    330
    \n-
    331 // user calls
    \n-
    332
    \n-
    333 // default block recursion level = 1
    \n-
    334
    \n-
    336 template<class M, class X, class Y>
    \n-
    337 void bdsolve (const M& A, X& v, const Y& d)
    \n-
    338 {
    \n-
    339 typename X::field_type w=1;
    \n-\n-
    341 }
    \n-
    343 template<class M, class X, class Y, class K>
    \n-
    344 void bdsolve (const M& A, X& v, const Y& d, const K& w)
    \n-
    345 {
    \n-\n-
    347 }
    \n-
    348
    \n-
    349 // general block recursion level >= 0
    \n-
    350
    \n-
    352 template<class M, class X, class Y, int l>
    \n-
    353 void bdsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
    \n-
    354 {
    \n-
    355 typename X::field_type w=1;
    \n-\n-
    357 }
    \n-
    359 template<class M, class X, class Y, class K, int l>
    \n-
    360 void bdsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
    \n-
    361 {
    \n-\n-
    363 }
    \n-
    364
    \n-
    365
    \n-
    366 //============================================================
    \n-
    367 // generic steps of iteration methods
    \n-
    368 // Jacobi, Gauss-Seidel, SOR, SSOR
    \n-
    369 // work directly on Ax=b, ie solve M(x^{i+1}-x^i) = w (b-Ax^i)
    \n-
    370 // we can recurse over a fixed number of levels
    \n-
    371 //============================================================
    \n-
    372
    \n-
    373 // template meta program for iterative solver steps
    \n-
    374 template<int I, typename M>
    \n-\n-
    376
    \n-
    377 template<class X, class Y, class K>
    \n-
    378 static void dbgs (const M& A, X& x, const Y& b, const K& w)
    \n-
    379 {
    \n-
    380 typedef typename M::ConstRowIterator rowiterator;
    \n-
    381 typedef typename M::ConstColIterator coliterator;
    \n-
    382 typedef typename Y::block_type bblock;
    \n-
    383 bblock rhs;
    \n-
    384
    \n-
    385 X xold(x); // remember old x
    \n-
    386
    \n-
    387 rowiterator endi=A.end();
    \n-
    388 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    389 {
    \n-
    390 rhs = b[i.index()]; // rhs = b_i
    \n-
    391 coliterator endj=(*i).end();
    \n-
    392 coliterator j=(*i).begin();
    \n-
    393 if constexpr (IsNumber<typename M::block_type>())
    \n-
    394 {
    \n-
    395 for (; j.index()<i.index(); ++j)
    \n-
    396 rhs -= (*j) * x[j.index()];
    \n-
    397 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
    \n-
    398 for (; j != endj; ++j)
    \n-
    399 rhs -= (*j) * x[j.index()];
    \n-
    400 x[i.index()] = rhs / (*diag);
    \n-
    401 }
    \n-
    402 else
    \n-
    403 {
    \n-
    404 for (; j.index()<i.index(); ++j) // iterate over a_ij with j < i
    \n-
    405 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    406 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
    \n-
    407 for (; j != endj; ++j) // iterate over a_ij with j > i
    \n-
    408 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j>i} a_ij * xold_j
    \n-
    409 algmeta_itsteps<I-1,typename M::block_type>::dbgs(*diag,x[i.index()],rhs,w); // if I==1: xnew_i = rhs/a_ii
    \n-
    410 }
    \n-
    411 }
    \n-
    412 // next two lines: xnew_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j) + (1-w)*xold;
    \n-
    413 x *= w;
    \n-
    414 x.axpy(K(1)-w,xold);
    \n-
    415 }
    \n-
    416
    \n-
    417 template<class X, class Y, class K>
    \n-
    418 static void bsorf (const M& A, X& x, const Y& b, const K& w)
    \n-
    419 {
    \n-
    420 typedef typename M::ConstRowIterator rowiterator;
    \n-
    421 typedef typename M::ConstColIterator coliterator;
    \n-
    422 typedef typename Y::block_type bblock;
    \n-
    423 typedef typename X::block_type xblock;
    \n-
    424 bblock rhs;
    \n-
    425 xblock v;
    \n-
    426
    \n-
    427 // Initialize nested data structure if there are entries
    \n-
    428 if(A.begin()!=A.end())
    \n-
    429 v=x[0];
    \n-
    430
    \n-
    431 rowiterator endi=A.end();
    \n-
    432 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    433 {
    \n-
    434 rhs = b[i.index()]; // rhs = b_i
    \n-
    435 coliterator endj=(*i).end(); // iterate over a_ij with j < i
    \n-
    436 coliterator j=(*i).begin();
    \n-
    437 if constexpr (IsNumber<typename M::block_type>())
    \n-
    438 {
    \n-
    439 for (; j.index()<i.index(); ++j)
    \n-
    440 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    441 coliterator diag=j; // *diag = a_ii
    \n-
    442 for (; j!=endj; ++j)
    \n-
    443 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    444 v = rhs / (*diag);
    \n-
    445 x[i.index()] += w*v; // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
    \n-
    446 }
    \n-
    447 else
    \n-
    448 {
    \n-
    449 for (; j.index()<i.index(); ++j)
    \n-
    450 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    451 coliterator diag=j; // *diag = a_ii
    \n-
    452 for (; j!=endj; ++j)
    \n-
    453 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
    \n-
    454 algmeta_itsteps<I-1,typename M::block_type>::bsorf(*diag,v,rhs,w); // if blocksize I==1: v = rhs/a_ii
    \n-
    455 x[i.index()].axpy(w,v); // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
    \n-
    456 }
    \n-
    457 }
    \n-
    458 }
    \n-
    459
    \n-
    460 template<class X, class Y, class K>
    \n-
    461 static void bsorb (const M& A, X& x, const Y& b, const K& w)
    \n-
    462 {
    \n-
    463 typedef typename M::ConstRowIterator rowiterator;
    \n-
    464 typedef typename M::ConstColIterator coliterator;
    \n-
    465 typedef typename Y::block_type bblock;
    \n-
    466 typedef typename X::block_type xblock;
    \n-
    467 bblock rhs;
    \n-
    468 xblock v;
    \n-
    469
    \n-
    470 // Initialize nested data structure if there are entries
    \n-
    471 if(A.begin()!=A.end())
    \n-
    472 v=x[0];
    \n-
    473
    \n-
    474 rowiterator endi=A.beforeBegin();
    \n-
    475 for (rowiterator i=A.beforeEnd(); i!=endi; --i)
    \n-
    476 {
    \n-
    477 rhs = b[i.index()];
    \n-
    478 coliterator endj=(*i).end();
    \n-
    479 coliterator j=(*i).begin();
    \n-
    480 if constexpr (IsNumber<typename M::block_type>())
    \n-
    481 {
    \n-
    482 for (; j.index()<i.index(); ++j)
    \n-
    483 rhs -= (*j) * x[j.index()];
    \n-
    484 coliterator diag=j;
    \n-
    485 for (; j!=endj; ++j)
    \n-
    486 rhs -= (*j) * x[j.index()];
    \n-
    487 v = rhs / (*diag);
    \n-
    488 x[i.index()] += w*v;
    \n-
    489 }
    \n-
    490 else
    \n-
    491 {
    \n-
    492 for (; j.index()<i.index(); ++j)
    \n-
    493 j->mmv(x[j.index()],rhs);
    \n-
    494 coliterator diag=j;
    \n-
    495 for (; j!=endj; ++j)
    \n-
    496 j->mmv(x[j.index()],rhs);
    \n-\n-
    498 x[i.index()].axpy(w,v);
    \n-
    499 }
    \n-
    500 }
    \n-
    501 }
    \n-
    502
    \n-
    503 template<class X, class Y, class K>
    \n-
    504 static void dbjac (const M& A, X& x, const Y& b, const K& w)
    \n-
    505 {
    \n-
    506 typedef typename M::ConstRowIterator rowiterator;
    \n-
    507 typedef typename M::ConstColIterator coliterator;
    \n-
    508 typedef typename Y::block_type bblock;
    \n-
    509 bblock rhs;
    \n-
    510
    \n-
    511 X v(x); // allocate with same size
    \n-
    512
    \n-
    513 rowiterator endi=A.end();
    \n-
    514 for (rowiterator i=A.begin(); i!=endi; ++i)
    \n-
    515 {
    \n-
    516 rhs = b[i.index()];
    \n-
    517 coliterator endj=(*i).end();
    \n-
    518 coliterator j=(*i).begin();
    \n-
    519 if constexpr (IsNumber<typename M::block_type>())
    \n-
    520 {
    \n-
    521 for (; j.index()<i.index(); ++j)
    \n-
    522 rhs -= (*j) * x[j.index()];
    \n-
    523 coliterator diag=j;
    \n-
    524 for (; j!=endj; ++j)
    \n-
    525 rhs -= (*j) * x[j.index()];
    \n-
    526 v[i.index()] = rhs / (*diag);
    \n-
    527 }
    \n-
    528 else
    \n-
    529 {
    \n-
    530 for (; j.index()<i.index(); ++j)
    \n-
    531 j->mmv(x[j.index()],rhs);
    \n-
    532 coliterator diag=j;
    \n-
    533 for (; j!=endj; ++j)
    \n-
    534 j->mmv(x[j.index()],rhs);
    \n-\n-
    536 }
    \n-
    537 }
    \n-
    538 x.axpy(w,v);
    \n-
    539 }
    \n-
    540 };
    \n-
    541 // end of recursion
    \n-
    542 template<typename M>
    \n-
    543 struct algmeta_itsteps<0,M> {
    \n-
    544 template<class X, class Y, class K>
    \n-
    545 static void dbgs (const M& A, X& x, const Y& b, const K& /*w*/)
    \n-
    546 {
    \n-
    547 A.solve(x,b);
    \n-
    548 }
    \n-
    549 template<class X, class Y, class K>
    \n-
    550 static void bsorf (const M& A, X& x, const Y& b, const K& /*w*/)
    \n-
    551 {
    \n-
    552 A.solve(x,b);
    \n-
    553 }
    \n-
    554 template<class X, class Y, class K>
    \n-
    555 static void bsorb (const M& A, X& x, const Y& b, const K& /*w*/)
    \n-
    556 {
    \n-
    557 A.solve(x,b);
    \n-
    558 }
    \n-
    559 template<class X, class Y, class K>
    \n-
    560 static void dbjac (const M& A, X& x, const Y& b, const K& /*w*/)
    \n-
    561 {
    \n-
    562 A.solve(x,b);
    \n-
    563 }
    \n-
    564 };
    \n-
    565
    \n-
    566 template<int I, typename T1, typename... MultiTypeMatrixArgs>
    \n-
    567 struct algmeta_itsteps<I,MultiTypeBlockMatrix<T1, MultiTypeMatrixArgs...>> {
    \n-
    568 template<
    \n-
    569 typename... MultiTypeVectorArgs,
    \n-
    570 class K>
    \n-\n-\n-\n-
    574 const K& w)
    \n-
    575 {
    \n-\n-\n-
    578 }
    \n-
    579
    \n-
    580 template<
    \n-
    581 typename... MultiTypeVectorArgs,
    \n-
    582 class K>
    \n-\n-\n-\n-
    586 const K& w)
    \n-
    587 {
    \n-\n-\n-
    590 }
    \n-
    591
    \n-
    592 template<
    \n-
    593 typename... MultiTypeVectorArgs,
    \n-
    594 class K>
    \n-\n-\n-\n-
    598 const K& w)
    \n-
    599 {
    \n-\n-\n-
    602 }
    \n-
    603
    \n-
    604 template<
    \n-
    605 typename... MultiTypeVectorArgs,
    \n-
    606 class K
    \n-
    607 >
    \n-\n-\n-\n-
    611 const K& w)
    \n-
    612 {
    \n-\n-\n-
    615 }
    \n-
    616 };
    \n-
    617
    \n-
    618 // user calls
    \n-
    619
    \n-
    621 template<class M, class X, class Y, class K>
    \n-
    622 void dbgs (const M& A, X& x, const Y& b, const K& w)
    \n-
    623 {
    \n-\n-
    625 }
    \n-
    627 template<class M, class X, class Y, class K, int l>
    \n-
    628 void dbgs (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n-
    629 {
    \n-\n-
    631 }
    \n-
    633 template<class M, class X, class Y, class K>
    \n-
    634 void bsorf (const M& A, X& x, const Y& b, const K& w)
    \n-
    635 {
    \n-\n-
    637 }
    \n-
    639 template<class M, class X, class Y, class K, int l>
    \n-
    640 void bsorf (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n-
    641 {
    \n-\n-
    643 }
    \n-
    645 template<class M, class X, class Y, class K>
    \n-
    646 void bsorb (const M& A, X& x, const Y& b, const K& w)
    \n-
    647 {
    \n-\n-
    649 }
    \n-
    651 template<class M, class X, class Y, class K, int l>
    \n-
    652 void bsorb (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n-
    653 {
    \n-\n-
    655 }
    \n-
    657 template<class M, class X, class Y, class K>
    \n-
    658 void dbjac (const M& A, X& x, const Y& b, const K& w)
    \n-
    659 {
    \n-\n-
    661 }
    \n-
    663 template<class M, class X, class Y, class K, int l>
    \n-
    664 void dbjac (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
    \n-
    665 {
    \n-\n-
    667 }
    \n-
    668
    \n-
    669
    \n-
    672} // end namespace
    \n-
    673
    \n-
    674#endif
    \n-\n-\n-\n-
    static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:568
    \n-
    static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:484
    \n-
    static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:540
    \n-
    static constexpr size_type N()
    Return the number of matrix rows.
    Definition: multitypeblockmatrix.hh:64
    \n-
    static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)
    Definition: multitypeblockmatrix.hh:513
    \n-
    void bltsolve(const M &A, X &v, const Y &d)
    block lower triangular solve
    Definition: gsetc.hh:175
    \n-
    WithDiagType
    Definition: gsetc.hh:49
    \n-
    void bsorb(const M &A, X &x, const Y &b, const K &w)
    SSOR step.
    Definition: gsetc.hh:646
    \n-
    void ubltsolve(const M &A, X &v, const Y &d)
    unit block lower triangular solve
    Definition: gsetc.hh:188
    \n-
    void dbjac(const M &A, X &x, const Y &b, const K &w)
    Jacobi step.
    Definition: gsetc.hh:658
    \n-
    void dbgs(const M &A, X &x, const Y &b, const K &w)
    GS step.
    Definition: gsetc.hh:622
    \n-
    WithRelaxType
    Definition: gsetc.hh:54
    \n-
    void bdsolve(const M &A, X &v, const Y &d)
    block diagonal solve, no relaxation
    Definition: gsetc.hh:337
    \n-
    void butsolve(const M &A, X &v, const Y &d)
    block upper triangular solve
    Definition: gsetc.hh:202
    \n-
    void bsorf(const M &A, X &x, const Y &b, const K &w)
    SOR step.
    Definition: gsetc.hh:634
    \n-
    void ubutsolve(const M &A, X &v, const Y &d)
    unit block upper triangular solve
    Definition: gsetc.hh:215
    \n-
    @ nodiag
    Definition: gsetc.hh:51
    \n-
    @ withdiag
    Definition: gsetc.hh:50
    \n-
    @ norelax
    Definition: gsetc.hh:56
    \n-
    @ withrelax
    Definition: gsetc.hh:55
    \n+
    54 class InvalidSolverCategory : public InvalidStateException{};
    \n+
    55
    \n+
    58} // end namespace
    \n+
    59
    \n+
    60#endif
    \n
    Definition: allocator.hh:11
    \n-
    A Vector class to support different block types.
    Definition: multitypeblockvector.hh:59
    \n-
    A Matrix class to support different block types.
    Definition: multitypeblockmatrix.hh:46
    \n-
    compile-time parameter for block recursion depth
    Definition: gsetc.hh:45
    \n-
    @ recursion_level
    Definition: gsetc.hh:46
    \n-
    Definition: gsetc.hh:69
    \n-
    static void butsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:90
    \n-
    static void bltsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:71
    \n-
    static void bltsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:114
    \n-
    static void butsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:120
    \n-
    static void bltsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:129
    \n-
    static void butsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:134
    \n-
    static void bltsolve(const M &, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:142
    \n-
    static void butsolve(const M &, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:148
    \n-
    static void bltsolve(const M &, X &v, const Y &d, const K &)
    Definition: gsetc.hh:157
    \n-
    static void butsolve(const M &, X &v, const Y &d, const K &)
    Definition: gsetc.hh:162
    \n-
    Definition: gsetc.hh:294
    \n-
    static void bdsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:296
    \n-
    static void bdsolve(const M &A, X &v, const Y &d, const K &w)
    Definition: gsetc.hh:316
    \n-
    static void bdsolve(const M &A, X &v, const Y &d, const K &)
    Definition: gsetc.hh:325
    \n-
    Definition: gsetc.hh:375
    \n-
    static void bsorb(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:461
    \n-
    static void bsorf(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:418
    \n-
    static void dbjac(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:504
    \n-
    static void dbgs(const M &A, X &x, const Y &b, const K &w)
    Definition: gsetc.hh:378
    \n-
    static void dbgs(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:545
    \n-
    static void dbjac(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:560
    \n-
    static void bsorf(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:550
    \n-
    static void bsorb(const M &A, X &x, const Y &b, const K &)
    Definition: gsetc.hh:555
    \n-
    static void dbgs(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:571
    \n-
    static void dbjac(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:608
    \n-
    static void bsorf(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:583
    \n-
    static void bsorb(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
    Definition: gsetc.hh:595
    \n+
    Categories for the solvers.
    Definition: solvercategory.hh:22
    \n+
    Category
    Definition: solvercategory.hh:23
    \n+
    @ sequential
    Category for sequential solvers.
    Definition: solvercategory.hh:25
    \n+
    @ nonoverlapping
    Category for non-overlapping solvers.
    Definition: solvercategory.hh:27
    \n+
    @ overlapping
    Category for overlapping solvers.
    Definition: solvercategory.hh:29
    \n+
    static Category category(const OP &op, decltype(op.category()) *=nullptr)
    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtu...
    Definition: solvercategory.hh:34
    \n+
    Definition: solvercategory.hh:54
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,838 +4,87 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-gsetc.hh\n+solvercategory.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_GSETC_HH\n- 6#define DUNE_ISTL_GSETC_HH\n+ 5#ifndef DUNE_ISTL_SOLVERCATEGORY_HH\n+ 6#define DUNE_ISTL_SOLVERCATEGORY_HH\n 7\n- 8#include \n- 9#include \n- 10#include \n- 11#include \n- 12#include \n- 13\n- 14#include \n- 15\n- 16#include \"multitypeblockvector.hh\"\n- 17#include \"multitypeblockmatrix.hh\"\n- 18\n- 19#include \"istlexception.hh\"\n- 20\n- 21\n- 27namespace Dune {\n- 28\n- 39 //============================================================\n- 40 // parameter types\n- 41 //============================================================\n- 42\n- 44 template\n-45 struct BL {\n-46 enum {recursion_level = l};\n- 47 };\n- 48\n-49 enum WithDiagType {\n-50 withdiag=1,\n- 51 nodiag=0\n-52 };\n+ 8#include \n+ 9\n+ 10\n+ 11namespace Dune {\n+ 12\n+21 struct SolverCategory\n+ 22 {\n+23 enum Category {\n+25 sequential,\n+27 nonoverlapping,\n+ 29 overlapping\n+30 };\n+ 31\n+ 33 template\n+34 static Category category(const OP& op, decltype(op.category())* = nullptr)\n+ 35 {\n+ 36 return op.category();\n+ 37 }\n+ 38\n+ 39#ifndef DOXYGEN\n+ 40 // template\n+ 41 // static Category category(const OP& op, decltype(op.getSolverCategory())*\n+= nullptr)\n+ 42 // {\n+ 43 // return op.getSolverCategory();\n+ 44 // }\n+ 45\n+ 46 template\n+ 47 static Category category(const OP& op, decltype(op.category)* = nullptr)\n+ 48 {\n+ 49 return OP::category;\n+ 50 }\n+ 51#endif\n+ 52 };\n 53\n-54 enum WithRelaxType {\n-55 withrelax=1,\n- 56 norelax=0\n-57 };\n- 58\n- 59 //============================================================\n- 60 // generic triangular solves\n- 61 // consider block decomposition A = L + D + U\n- 62 // we can invert L, L+D, U, U+D\n- 63 // we can apply relaxation or not\n- 64 // we can recurse over a fixed number of levels\n- 65 //============================================================\n- 66\n- 67 // template meta program for triangular solves\n- 68 template\n-69 struct algmeta_btsolve {\n- 70 template\n-71 static void bltsolve (const M& A, X& v, const Y& d, const K& w)\n- 72 {\n- 73 // iterator types\n- 74 typedef typename M::ConstRowIterator rowiterator;\n- 75 typedef typename M::ConstColIterator coliterator;\n- 76 typedef typename Y::block_type bblock;\n- 77\n- 78 // local solve at each block and immediate update\n- 79 rowiterator endi=A.end();\n- 80 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 81 {\n- 82 bblock rhs(d[i.index()]);\n- 83 coliterator j;\n- 84 for (j=(*i).begin(); j.index()::bltsolve(*j,v[i.index()],rhs,w);\n- 87 }\n- 88 }\n- 89 template\n-90 static void butsolve (const M& A, X& v, const Y& d, const K& w)\n- 91 {\n- 92 // iterator types\n- 93 typedef typename M::ConstRowIterator rowiterator;\n- 94 typedef typename M::ConstColIterator coliterator;\n- 95 typedef typename Y::block_type bblock;\n- 96\n- 97 // local solve at each block and immediate update\n- 98 rowiterator rendi=A.beforeBegin();\n- 99 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)\n- 100 {\n- 101 bblock rhs(d[i.index()]);\n- 102 coliterator j;\n- 103 for (j=(*i).beforeEnd(); j.index()>i.index(); --j)\n- 104 (*j).mmv(v[j.index()],rhs);\n- 105 algmeta_btsolve::butsolve(*j,v[i.index()],rhs,w);\n- 106 }\n- 107 }\n- 108 };\n- 109\n- 110 // recursion end ...\n- 111 template<>\n-112 struct algmeta_btsolve<0,withdiag,withrelax> {\n- 113 template\n-114 static void bltsolve (const M& A, X& v, const Y& d, const K& w)\n- 115 {\n- 116 A.solve(v,d);\n- 117 v *= w;\n- 118 }\n- 119 template\n-120 static void butsolve (const M& A, X& v, const Y& d, const K& w)\n- 121 {\n- 122 A.solve(v,d);\n- 123 v *= w;\n- 124 }\n- 125 };\n- 126 template<>\n-127 struct algmeta_btsolve<0,withdiag,norelax> {\n- 128 template\n-129 static void bltsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n- 130 {\n- 131 A.solve(v,d);\n- 132 }\n- 133 template\n-134 static void butsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n- 135 {\n- 136 A.solve(v,d);\n- 137 }\n- 138 };\n- 139 template<>\n-140 struct algmeta_btsolve<0,nodiag,withrelax> {\n- 141 template\n-142 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& w)\n- 143 {\n- 144 v = d;\n- 145 v *= w;\n- 146 }\n- 147 template\n-148 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& w)\n- 149 {\n- 150 v = d;\n- 151 v *= w;\n- 152 }\n- 153 };\n- 154 template<>\n-155 struct algmeta_btsolve<0,nodiag,norelax> {\n- 156 template\n-157 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)\n- 158 {\n- 159 v = d;\n- 160 }\n- 161 template\n-162 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)\n- 163 {\n- 164 v = d;\n- 165 }\n- 166 };\n- 167\n- 168\n- 169 // user calls\n- 170\n- 171 // default block recursion level = 1\n- 172\n- 174 template\n-175 void bltsolve (const M& A, X& v, const Y& d)\n- 176 {\n- 177 typename X::field_type w=1;\n- 178 algmeta_btsolve<1,withdiag,norelax>::bltsolve(A,v,d,w);\n- 179 }\n- 181 template\n-182 void bltsolve (const M& A, X& v, const Y& d, const K& w)\n- 183 {\n- 184 algmeta_btsolve<1,withdiag,withrelax>::bltsolve(A,v,d,w);\n- 185 }\n- 187 template\n-188 void ubltsolve (const M& A, X& v, const Y& d)\n- 189 {\n- 190 typename X::field_type w=1;\n- 191 algmeta_btsolve<1,nodiag,norelax>::bltsolve(A,v,d,w);\n- 192 }\n- 194 template\n-195 void ubltsolve (const M& A, X& v, const Y& d, const K& w)\n- 196 {\n- 197 algmeta_btsolve<1,nodiag,withrelax>::bltsolve(A,v,d,w);\n- 198 }\n- 199\n- 201 template\n-202 void butsolve (const M& A, X& v, const Y& d)\n- 203 {\n- 204 typename X::field_type w=1;\n- 205 algmeta_btsolve<1,withdiag,norelax>::butsolve(A,v,d,w);\n- 206 }\n- 208 template\n-209 void butsolve (const M& A, X& v, const Y& d, const K& w)\n- 210 {\n- 211 algmeta_btsolve<1,withdiag,withrelax>::butsolve(A,v,d,w);\n- 212 }\n- 214 template\n-215 void ubutsolve (const M& A, X& v, const Y& d)\n- 216 {\n- 217 typename X::field_type w=1;\n- 218 algmeta_btsolve<1,nodiag,norelax>::butsolve(A,v,d,w);\n- 219 }\n- 221 template\n-222 void ubutsolve (const M& A, X& v, const Y& d, const K& w)\n- 223 {\n- 224 algmeta_btsolve<1,nodiag,withrelax>::butsolve(A,v,d,w);\n- 225 }\n- 226\n- 227 // general block recursion level >= 0\n- 228\n- 230 template\n-231 void bltsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n- 232 {\n- 233 typename X::field_type w=1;\n- 234 algmeta_btsolve::bltsolve(A,v,d,w);\n- 235 }\n- 237 template\n-238 void bltsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n- 239 {\n- 240 algmeta_btsolve::bltsolve(A,v,d,w);\n- 241 }\n- 243 template\n-244 void ubltsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n- 245 {\n- 246 typename X::field_type w=1;\n- 247 algmeta_btsolve::bltsolve(A,v,d,w);\n- 248 }\n- 250 template\n-251 void ubltsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n- 252 {\n- 253 algmeta_btsolve::bltsolve(A,v,d,w);\n- 254 }\n- 255\n- 257 template\n-258 void butsolve (const M& A, X& v, const Y& d, BL bl)\n- 259 {\n- 260 typename X::field_type w=1;\n- 261 algmeta_btsolve::butsolve(A,v,d,w);\n- 262 }\n- 264 template\n-265 void butsolve (const M& A, X& v, const Y& d, const K& w, BL bl)\n- 266 {\n- 267 algmeta_btsolve::butsolve(A,v,d,w);\n- 268 }\n- 270 template\n-271 void ubutsolve (const M& A, X& v, const Y& d, BL bl)\n- 272 {\n- 273 typename X::field_type w=1;\n- 274 algmeta_btsolve::butsolve(A,v,d,w);\n- 275 }\n- 277 template\n-278 void ubutsolve (const M& A, X& v, const Y& d, const K& w, BL bl)\n- 279 {\n- 280 algmeta_btsolve::butsolve(A,v,d,w);\n- 281 }\n- 282\n- 283\n- 284\n- 285 //============================================================\n- 286 // generic block diagonal solves\n- 287 // consider block decomposition A = L + D + U\n- 288 // we can apply relaxation or not\n- 289 // we can recurse over a fixed number of levels\n- 290 //============================================================\n- 291\n- 292 // template meta program for diagonal solves\n- 293 template\n-294 struct algmeta_bdsolve {\n- 295 template\n-296 static void bdsolve (const M& A, X& v, const Y& d, const K& w)\n- 297 {\n- 298 // iterator types\n- 299 typedef typename M::ConstRowIterator rowiterator;\n- 300 typedef typename M::ConstColIterator coliterator;\n- 301\n- 302 // local solve at each block and immediate update\n- 303 rowiterator rendi=A.beforeBegin();\n- 304 for (rowiterator i=A.beforeEnd(); i!=rendi; --i)\n- 305 {\n- 306 coliterator ii=(*i).find(i.index());\n- 307 algmeta_bdsolve::bdsolve(*ii,v[i.index()],d[i.index()],w);\n- 308 }\n- 309 }\n- 310 };\n- 311\n- 312 // recursion end ...\n- 313 template<>\n-314 struct algmeta_bdsolve<0,withrelax> {\n- 315 template\n-316 static void bdsolve (const M& A, X& v, const Y& d, const K& w)\n- 317 {\n- 318 A.solve(v,d);\n- 319 v *= w;\n- 320 }\n- 321 };\n- 322 template<>\n-323 struct algmeta_bdsolve<0,norelax> {\n- 324 template\n-325 static void bdsolve (const M& A, X& v, const Y& d, const K& /*w*/)\n- 326 {\n- 327 A.solve(v,d);\n- 328 }\n- 329 };\n- 330\n- 331 // user calls\n- 332\n- 333 // default block recursion level = 1\n- 334\n- 336 template\n-337 void bdsolve (const M& A, X& v, const Y& d)\n- 338 {\n- 339 typename X::field_type w=1;\n- 340 algmeta_bdsolve<1,norelax>::bdsolve(A,v,d,w);\n- 341 }\n- 343 template\n-344 void bdsolve (const M& A, X& v, const Y& d, const K& w)\n- 345 {\n- 346 algmeta_bdsolve<1,withrelax>::bdsolve(A,v,d,w);\n- 347 }\n- 348\n- 349 // general block recursion level >= 0\n- 350\n- 352 template\n-353 void bdsolve (const M& A, X& v, const Y& d, BL /*bl*/)\n- 354 {\n- 355 typename X::field_type w=1;\n- 356 algmeta_bdsolve::bdsolve(A,v,d,w);\n- 357 }\n- 359 template\n-360 void bdsolve (const M& A, X& v, const Y& d, const K& w, BL /*bl*/)\n- 361 {\n- 362 algmeta_bdsolve::bdsolve(A,v,d,w);\n- 363 }\n- 364\n- 365\n- 366 //============================================================\n- 367 // generic steps of iteration methods\n- 368 // Jacobi, Gauss-Seidel, SOR, SSOR\n- 369 // work directly on Ax=b, ie solve M(x^{i+1}-x^i) = w (b-Ax^i)\n- 370 // we can recurse over a fixed number of levels\n- 371 //============================================================\n- 372\n- 373 // template meta program for iterative solver steps\n- 374 template\n-375 struct algmeta_itsteps {\n- 376\n- 377 template\n-378 static void dbgs (const M& A, X& x, const Y& b, const K& w)\n- 379 {\n- 380 typedef typename M::ConstRowIterator rowiterator;\n- 381 typedef typename M::ConstColIterator coliterator;\n- 382 typedef typename Y::block_type bblock;\n- 383 bblock rhs;\n- 384\n- 385 X xold(x); // remember old x\n- 386\n- 387 rowiterator endi=A.end();\n- 388 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 389 {\n- 390 rhs = b[i.index()]; // rhs = b_i\n- 391 coliterator endj=(*i).end();\n- 392 coliterator j=(*i).begin();\n- 393 if constexpr (IsNumber())\n- 394 {\n- 395 for (; j.index() i\n- 408 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j>i} a_ij * xold_j\n- 409 algmeta_itsteps::dbgs(*diag,x[i.index\n-()],rhs,w); // if I==1: xnew_i = rhs/a_ii\n- 410 }\n- 411 }\n- 412 // next two lines: xnew_i = w / a_ii * (b_i - sum_{j=i} a_ij * xold_j) + (1-w)*xold;\n- 413 x *= w;\n- 414 x.axpy(K(1)-w,xold);\n- 415 }\n- 416\n- 417 template\n-418 static void bsorf (const M& A, X& x, const Y& b, const K& w)\n- 419 {\n- 420 typedef typename M::ConstRowIterator rowiterator;\n- 421 typedef typename M::ConstColIterator coliterator;\n- 422 typedef typename Y::block_type bblock;\n- 423 typedef typename X::block_type xblock;\n- 424 bblock rhs;\n- 425 xblock v;\n- 426\n- 427 // Initialize nested data structure if there are entries\n- 428 if(A.begin()!=A.end())\n- 429 v=x[0];\n- 430\n- 431 rowiterator endi=A.end();\n- 432 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 433 {\n- 434 rhs = b[i.index()]; // rhs = b_i\n- 435 coliterator endj=(*i).end(); // iterate over a_ij with j < i\n- 436 coliterator j=(*i).begin();\n- 437 if constexpr (IsNumber())\n- 438 {\n- 439 for (; j.index()=i} a_ij * xold_j)\n- 446 }\n- 447 else\n- 448 {\n- 449 for (; j.index()::bsorf(*diag,v,rhs,w); // if\n-blocksize I==1: v = rhs/a_ii\n- 455 x[i.index()].axpy(w,v); // x_i = w / a_ii * (b_i - sum_{j=i} a_ij * xold_j)\n- 456 }\n- 457 }\n- 458 }\n- 459\n- 460 template\n-461 static void bsorb (const M& A, X& x, const Y& b, const K& w)\n- 462 {\n- 463 typedef typename M::ConstRowIterator rowiterator;\n- 464 typedef typename M::ConstColIterator coliterator;\n- 465 typedef typename Y::block_type bblock;\n- 466 typedef typename X::block_type xblock;\n- 467 bblock rhs;\n- 468 xblock v;\n- 469\n- 470 // Initialize nested data structure if there are entries\n- 471 if(A.begin()!=A.end())\n- 472 v=x[0];\n- 473\n- 474 rowiterator endi=A.beforeBegin();\n- 475 for (rowiterator i=A.beforeEnd(); i!=endi; --i)\n- 476 {\n- 477 rhs = b[i.index()];\n- 478 coliterator endj=(*i).end();\n- 479 coliterator j=(*i).begin();\n- 480 if constexpr (IsNumber())\n- 481 {\n- 482 for (; j.index()mmv(x[j.index()],rhs);\n- 494 coliterator diag=j;\n- 495 for (; j!=endj; ++j)\n- 496 j->mmv(x[j.index()],rhs);\n- 497 algmeta_itsteps::bsorb(*diag,v,rhs,w);\n- 498 x[i.index()].axpy(w,v);\n- 499 }\n- 500 }\n- 501 }\n- 502\n- 503 template\n-504 static void dbjac (const M& A, X& x, const Y& b, const K& w)\n- 505 {\n- 506 typedef typename M::ConstRowIterator rowiterator;\n- 507 typedef typename M::ConstColIterator coliterator;\n- 508 typedef typename Y::block_type bblock;\n- 509 bblock rhs;\n- 510\n- 511 X v(x); // allocate with same size\n- 512\n- 513 rowiterator endi=A.end();\n- 514 for (rowiterator i=A.begin(); i!=endi; ++i)\n- 515 {\n- 516 rhs = b[i.index()];\n- 517 coliterator endj=(*i).end();\n- 518 coliterator j=(*i).begin();\n- 519 if constexpr (IsNumber())\n- 520 {\n- 521 for (; j.index()mmv(x[j.index()],rhs);\n- 532 coliterator diag=j;\n- 533 for (; j!=endj; ++j)\n- 534 j->mmv(x[j.index()],rhs);\n- 535 algmeta_itsteps::dbjac(*diag,v[i.index\n-()],rhs,w);\n- 536 }\n- 537 }\n- 538 x.axpy(w,v);\n- 539 }\n- 540 };\n- 541 // end of recursion\n- 542 template\n-543 struct algmeta_itsteps<0,M> {\n- 544 template\n-545 static void dbgs (const M& A, X& x, const Y& b, const K& /*w*/)\n- 546 {\n- 547 A.solve(x,b);\n- 548 }\n- 549 template\n-550 static void bsorf (const M& A, X& x, const Y& b, const K& /*w*/)\n- 551 {\n- 552 A.solve(x,b);\n- 553 }\n- 554 template\n-555 static void bsorb (const M& A, X& x, const Y& b, const K& /*w*/)\n- 556 {\n- 557 A.solve(x,b);\n- 558 }\n- 559 template\n-560 static void dbjac (const M& A, X& x, const Y& b, const K& /*w*/)\n- 561 {\n- 562 A.solve(x,b);\n- 563 }\n- 564 };\n- 565\n- 566 template\n-567 struct algmeta_itsteps>\n-{\n- 568 template<\n- 569 typename... MultiTypeVectorArgs,\n- 570 class K>\n-571 static void dbgs (const MultiTypeBlockMatrix&\n-A,\n- 572 MultiTypeBlockVector& x,\n- 573 const MultiTypeBlockVector& b,\n- 574 const K& w)\n- 575 {\n- 576 static const int N = MultiTypeBlockMatrix::N\n-();\n- 577 Dune::MultiTypeBlockMatrix_Solver::dbgs(A, x, b, w);\n- 578 }\n- 579\n- 580 template<\n- 581 typename... MultiTypeVectorArgs,\n- 582 class K>\n-583 static void bsorf (const MultiTypeBlockMatrix&\n-A,\n- 584 MultiTypeBlockVector& x,\n- 585 const MultiTypeBlockVector& b,\n- 586 const K& w)\n- 587 {\n- 588 static const int N = MultiTypeBlockMatrix::N\n-();\n- 589 Dune::MultiTypeBlockMatrix_Solver::bsorf(A, x, b, w);\n- 590 }\n- 591\n- 592 template<\n- 593 typename... MultiTypeVectorArgs,\n- 594 class K>\n-595 static void bsorb (const MultiTypeBlockMatrix&\n-A,\n- 596 MultiTypeBlockVector& x,\n- 597 const MultiTypeBlockVector& b,\n- 598 const K& w)\n- 599 {\n- 600 static const int N = MultiTypeBlockMatrix::N\n-();\n- 601 Dune::MultiTypeBlockMatrix_Solver::bsorb(A, x, b, w);\n- 602 }\n- 603\n- 604 template<\n- 605 typename... MultiTypeVectorArgs,\n- 606 class K\n- 607 >\n-608 static void dbjac (const MultiTypeBlockMatrix&\n-A,\n- 609 MultiTypeBlockVector& x,\n- 610 const MultiTypeBlockVector& b,\n- 611 const K& w)\n- 612 {\n- 613 static const int N = MultiTypeBlockMatrix::N\n-();\n- 614 Dune::MultiTypeBlockMatrix_Solver::dbjac(A, x, b, w);\n- 615 }\n- 616 };\n- 617\n- 618 // user calls\n- 619\n- 621 template\n-622 void dbgs (const M& A, X& x, const Y& b, const K& w)\n- 623 {\n- 624 algmeta_itsteps<1,M>::dbgs(A,x,b,w);\n- 625 }\n- 627 template\n-628 void dbgs (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n- 629 {\n- 630 algmeta_itsteps::dbgs(A,x,b,w);\n- 631 }\n- 633 template\n-634 void bsorf (const M& A, X& x, const Y& b, const K& w)\n- 635 {\n- 636 algmeta_itsteps<1,M>::bsorf(A,x,b,w);\n- 637 }\n- 639 template\n-640 void bsorf (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n- 641 {\n- 642 algmeta_itsteps::bsorf(A,x,b,w);\n- 643 }\n- 645 template\n-646 void bsorb (const M& A, X& x, const Y& b, const K& w)\n- 647 {\n- 648 algmeta_itsteps<1,M>::bsorb(A,x,b,w);\n- 649 }\n- 651 template\n-652 void bsorb (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n- 653 {\n- 654 algmeta_itsteps::type>::bsorb(A,x,b,w);\n- 655 }\n- 657 template\n-658 void dbjac (const M& A, X& x, const Y& b, const K& w)\n- 659 {\n- 660 algmeta_itsteps<1,M>::dbjac(A,x,b,w);\n- 661 }\n- 663 template\n-664 void dbjac (const M& A, X& x, const Y& b, const K& w, BL /*bl*/)\n- 665 {\n- 666 algmeta_itsteps::dbjac(A,x,b,w);\n- 667 }\n- 668\n- 669\n- 672} // end namespace\n- 673\n- 674#endif\n-multitypeblockmatrix.hh\n-istlexception.hh\n-multitypeblockvector.hh\n-Dune::MultiTypeBlockMatrix_Solver::dbjac\n-static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:568\n-Dune::MultiTypeBlockMatrix_Solver::dbgs\n-static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:484\n-Dune::MultiTypeBlockMatrix_Solver::bsorb\n-static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:540\n-Dune::MultiTypeBlockMatrix::N\n-static constexpr size_type N()\n-Return the number of matrix rows.\n-Definition: multitypeblockmatrix.hh:64\n-Dune::MultiTypeBlockMatrix_Solver::bsorf\n-static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)\n-Definition: multitypeblockmatrix.hh:513\n-Dune::bltsolve\n-void bltsolve(const M &A, X &v, const Y &d)\n-block lower triangular solve\n-Definition: gsetc.hh:175\n-Dune::WithDiagType\n-WithDiagType\n-Definition: gsetc.hh:49\n-Dune::bsorb\n-void bsorb(const M &A, X &x, const Y &b, const K &w)\n-SSOR step.\n-Definition: gsetc.hh:646\n-Dune::ubltsolve\n-void ubltsolve(const M &A, X &v, const Y &d)\n-unit block lower triangular solve\n-Definition: gsetc.hh:188\n-Dune::dbjac\n-void dbjac(const M &A, X &x, const Y &b, const K &w)\n-Jacobi step.\n-Definition: gsetc.hh:658\n-Dune::dbgs\n-void dbgs(const M &A, X &x, const Y &b, const K &w)\n-GS step.\n-Definition: gsetc.hh:622\n-Dune::WithRelaxType\n-WithRelaxType\n-Definition: gsetc.hh:54\n-Dune::bdsolve\n-void bdsolve(const M &A, X &v, const Y &d)\n-block diagonal solve, no relaxation\n-Definition: gsetc.hh:337\n-Dune::butsolve\n-void butsolve(const M &A, X &v, const Y &d)\n-block upper triangular solve\n-Definition: gsetc.hh:202\n-Dune::bsorf\n-void bsorf(const M &A, X &x, const Y &b, const K &w)\n-SOR step.\n-Definition: gsetc.hh:634\n-Dune::ubutsolve\n-void ubutsolve(const M &A, X &v, const Y &d)\n-unit block upper triangular solve\n-Definition: gsetc.hh:215\n-Dune::nodiag\n-@ nodiag\n-Definition: gsetc.hh:51\n-Dune::withdiag\n-@ withdiag\n-Definition: gsetc.hh:50\n-Dune::norelax\n-@ norelax\n-Definition: gsetc.hh:56\n-Dune::withrelax\n-@ withrelax\n-Definition: gsetc.hh:55\n+54 class InvalidSolverCategory : public InvalidStateException{};\n+ 55\n+ 58} // end namespace\n+ 59\n+ 60#endif\n Dune\n Definition: allocator.hh:11\n-Dune::MultiTypeBlockVector\n-A Vector class to support different block types.\n-Definition: multitypeblockvector.hh:59\n-Dune::MultiTypeBlockMatrix\n-A Matrix class to support different block types.\n-Definition: multitypeblockmatrix.hh:46\n-Dune::BL\n-compile-time parameter for block recursion depth\n-Definition: gsetc.hh:45\n-Dune::BL::recursion_level\n-@ recursion_level\n-Definition: gsetc.hh:46\n-Dune::algmeta_btsolve\n-Definition: gsetc.hh:69\n-Dune::algmeta_btsolve::butsolve\n-static void butsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:90\n-Dune::algmeta_btsolve::bltsolve\n-static void bltsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:71\n-Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>::bltsolve\n-static void bltsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:114\n-Dune::algmeta_btsolve<_0,_withdiag,_withrelax_>::butsolve\n-static void butsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:120\n-Dune::algmeta_btsolve<_0,_withdiag,_norelax_>::bltsolve\n-static void bltsolve(const M &A, X &v, const Y &d, const K &)\n-Definition: gsetc.hh:129\n-Dune::algmeta_btsolve<_0,_withdiag,_norelax_>::butsolve\n-static void butsolve(const M &A, X &v, const Y &d, const K &)\n-Definition: gsetc.hh:134\n-Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>::bltsolve\n-static void bltsolve(const M &, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:142\n-Dune::algmeta_btsolve<_0,_nodiag,_withrelax_>::butsolve\n-static void butsolve(const M &, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:148\n-Dune::algmeta_btsolve<_0,_nodiag,_norelax_>::bltsolve\n-static void bltsolve(const M &, X &v, const Y &d, const K &)\n-Definition: gsetc.hh:157\n-Dune::algmeta_btsolve<_0,_nodiag,_norelax_>::butsolve\n-static void butsolve(const M &, X &v, const Y &d, const K &)\n-Definition: gsetc.hh:162\n-Dune::algmeta_bdsolve\n-Definition: gsetc.hh:294\n-Dune::algmeta_bdsolve::bdsolve\n-static void bdsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:296\n-Dune::algmeta_bdsolve<_0,_withrelax_>::bdsolve\n-static void bdsolve(const M &A, X &v, const Y &d, const K &w)\n-Definition: gsetc.hh:316\n-Dune::algmeta_bdsolve<_0,_norelax_>::bdsolve\n-static void bdsolve(const M &A, X &v, const Y &d, const K &)\n-Definition: gsetc.hh:325\n-Dune::algmeta_itsteps\n-Definition: gsetc.hh:375\n-Dune::algmeta_itsteps::bsorb\n-static void bsorb(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:461\n-Dune::algmeta_itsteps::bsorf\n-static void bsorf(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:418\n-Dune::algmeta_itsteps::dbjac\n-static void dbjac(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:504\n-Dune::algmeta_itsteps::dbgs\n-static void dbgs(const M &A, X &x, const Y &b, const K &w)\n-Definition: gsetc.hh:378\n-Dune::algmeta_itsteps<_0,_M_>::dbgs\n-static void dbgs(const M &A, X &x, const Y &b, const K &)\n-Definition: gsetc.hh:545\n-Dune::algmeta_itsteps<_0,_M_>::dbjac\n-static void dbjac(const M &A, X &x, const Y &b, const K &)\n-Definition: gsetc.hh:560\n-Dune::algmeta_itsteps<_0,_M_>::bsorf\n-static void bsorf(const M &A, X &x, const Y &b, const K &)\n-Definition: gsetc.hh:550\n-Dune::algmeta_itsteps<_0,_M_>::bsorb\n-static void bsorb(const M &A, X &x, const Y &b, const K &)\n-Definition: gsetc.hh:555\n-Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n->::dbgs\n-static void dbgs(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n-MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n-MultiTypeVectorArgs... > &b, const K &w)\n-Definition: gsetc.hh:571\n-Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n->::dbjac\n-static void dbjac(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n-MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n-MultiTypeVectorArgs... > &b, const K &w)\n-Definition: gsetc.hh:608\n-Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n->::bsorf\n-static void bsorf(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n-MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n-MultiTypeVectorArgs... > &b, const K &w)\n-Definition: gsetc.hh:583\n-Dune::algmeta_itsteps<_I,_MultiTypeBlockMatrix<_T1,_MultiTypeMatrixArgs..._>\n->::bsorb\n-static void bsorb(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A,\n-MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector<\n-MultiTypeVectorArgs... > &b, const K &w)\n-Definition: gsetc.hh:595\n+Dune::SolverCategory\n+Categories for the solvers.\n+Definition: solvercategory.hh:22\n+Dune::SolverCategory::Category\n+Category\n+Definition: solvercategory.hh:23\n+Dune::SolverCategory::sequential\n+@ sequential\n+Category for sequential solvers.\n+Definition: solvercategory.hh:25\n+Dune::SolverCategory::nonoverlapping\n+@ nonoverlapping\n+Category for non-overlapping solvers.\n+Definition: solvercategory.hh:27\n+Dune::SolverCategory::overlapping\n+@ overlapping\n+Category for overlapping solvers.\n+Definition: solvercategory.hh:29\n+Dune::SolverCategory::category\n+static Category category(const OP &op, decltype(op.category()) *=nullptr)\n+Helperfunction to extract the solver category either from an enum, or from the\n+newly introduced virtu...\n+Definition: solvercategory.hh:34\n+Dune::InvalidSolverCategory\n+Definition: solvercategory.hh:54\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00227.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00227.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bccsmatrixinitializer.hh File Reference\n+dune-istl: superlufunctions.hh File Reference\n \n \n \n \n \n \n \n@@ -63,33 +63,43 @@\n
    \n \n
    \n \n
    \n \n-
    bccsmatrixinitializer.hh File Reference
    \n+Macros
    \n+
    superlufunctions.hh File Reference
    \n \n
    \n-
    #include <limits>
    \n-#include <set>
    \n-#include <dune/common/typetraits.hh>
    \n-#include <dune/common/scalarmatrixview.hh>
    \n-#include <dune/istl/bccsmatrix.hh>
    \n+
    #include "supermatrix.h"
    \n+#include "slu_util.h"
    \n
    \n

    Go to the source code of this file.

    \n \n-\n-\n-\n-\n-\n+\n+\n+\n

    \n-Namespaces

    namespace  Dune
     
    namespace  Dune::ISTL
     

    \n+Macros

    #define int_t   SUPERLU_INT_TYPE
     
    \n+

    Macro Definition Documentation

    \n+\n+

    ◆ int_t

    \n+\n+
    \n+
    \n+ \n+ \n+ \n+ \n+
    #define int_t   SUPERLU_INT_TYPE
    \n+
    \n+\n+
    \n+
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,23 +4,21 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-Namespaces\n-bccsmatrixinitializer.hh File Reference\n-#include \n-#include \n-#include \n-#include \n-#include \n+Macros\n+superlufunctions.hh File Reference\n+#include \"supermatrix.h\"\n+#include \"slu_util.h\"\n Go_to_the_source_code_of_this_file.\n- Namespaces\n-namespace \u00a0Dune\n-\u00a0\n-namespace \u00a0Dune::ISTL\n+ Macros\n+#define\u00a0int_t\u00a0\u00a0\u00a0SUPERLU_INT_TYPE\n \u00a0\n+***** Macro Definition Documentation *****\n+***** \u25c6\u00a0int_t *****\n+#define int_t\u00a0\u00a0\u00a0SUPERLU_INT_TYPE\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00227_source.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00227_source.html", "unified_diff": "@@ -1,15 +1,15 @@\n \n \n \n \n \n \n \n-dune-istl: bccsmatrixinitializer.hh Source File\n+dune-istl: superlufunctions.hh Source File\n \n \n \n \n \n \n \n@@ -62,344 +62,130 @@\n \n
    \n \n
    \n
    \n
    \n-
    bccsmatrixinitializer.hh
    \n+
    superlufunctions.hh
    \n
    \n
    \n Go to the documentation of this file.
    1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
    \n
    2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    \n
    3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    \n
    4// vi: set et ts=4 sw=2 sts=2:
    \n-
    5#ifndef DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH
    \n-
    6#define DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH
    \n-
    7
    \n-
    8#include <limits>
    \n-
    9#include <set>
    \n-
    10
    \n-
    11#include <dune/common/typetraits.hh>
    \n-
    12#include <dune/common/scalarmatrixview.hh>
    \n-
    13
    \n-\n-
    15
    \n-
    16namespace Dune
    \n-
    17{
    \n-
    18 template<class I, class S, class D>
    \n-
    19 class OverlappingSchwarzInitializer;
    \n-
    20}
    \n-
    21
    \n-
    22namespace Dune::ISTL::Impl
    \n-
    23{
    \n-
    31 template<class M, class S>
    \n-
    32 class MatrixRowSubset
    \n-
    33 {
    \n-
    34 public:
    \n-
    36 typedef M Matrix;
    \n-
    38 typedef S RowIndexSet;
    \n-
    39
    \n-
    45 MatrixRowSubset(const Matrix& m, const RowIndexSet& s)
    \n-
    46 : m_(m), s_(s)
    \n-
    47 {}
    \n+
    5#ifndef DUNE_ISTL_SUPERLUFUNCTIONS_HH
    \n+
    6#define DUNE_ISTL_SUPERLUFUNCTIONS_HH
    \n+
    7#if HAVE_SUPERLU
    \n+
    8
    \n+
    9
    \n+
    10#define int_t SUPERLU_INT_TYPE
    \n+
    11#include "supermatrix.h"
    \n+
    12#include "slu_util.h"
    \n+
    13#undef int_t
    \n+
    14
    \n+
    15#if __has_include("slu_sdefs.h")
    \n+
    16extern "C" {
    \n+
    17 extern void
    \n+
    18 sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
    \n+
    19 char *, float *, float *, SuperMatrix *, SuperMatrix *,
    \n+
    20 void *, int, SuperMatrix *, SuperMatrix *,
    \n+
    21 float *, float *, float *, float *,
    \n+
    22 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
    \n+
    23
    \n+
    24 extern void
    \n+
    25 sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int,
    \n+
    26 Stype_t, Dtype_t, Mtype_t);
    \n+
    27 extern void
    \n+
    28 sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *,
    \n+
    29 int *, int *, Stype_t, Dtype_t, Mtype_t);
    \n+
    30 extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
    \n+
    31
    \n+
    32 extern void sPrint_CompCol_Matrix(char *, SuperMatrix *);
    \n+
    33}
    \n+
    34#endif
    \n+
    35
    \n+
    36#if __has_include("slu_ddefs.h")
    \n+
    37extern "C" {
    \n+
    38 extern void
    \n+
    39 dgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
    \n+
    40 char *, double *, double *, SuperMatrix *, SuperMatrix *,
    \n+
    41 void *, int, SuperMatrix *, SuperMatrix *,
    \n+
    42 double *, double *, double *, double *,
    \n+
    43 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
    \n+
    44
    \n+
    45 extern void
    \n+
    46 dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *,
    \n+
    47 int *, int *, Stype_t, Dtype_t, Mtype_t);
    \n
    48
    \n-
    49 const Matrix& matrix() const
    \n-
    50 {
    \n-
    51 return m_;
    \n-
    52 }
    \n-
    53
    \n-
    54 const RowIndexSet& rowIndexSet() const
    \n-
    55 {
    \n-
    56 return s_;
    \n-
    57 }
    \n+
    49 extern void
    \n+
    50 dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int,
    \n+
    51 Stype_t, Dtype_t, Mtype_t);
    \n+
    52
    \n+
    53 extern int dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
    \n+
    54
    \n+
    55 extern void dPrint_CompCol_Matrix(char *, SuperMatrix *);
    \n+
    56}
    \n+
    57#endif
    \n
    58
    \n-
    60 class const_iterator
    \n-
    61 : public ForwardIteratorFacade<const_iterator, const typename Matrix::row_type>
    \n-
    62 {
    \n-
    63 public:
    \n-
    64 const_iterator(typename Matrix::const_iterator firstRow,
    \n-
    65 typename RowIndexSet::const_iterator pos)
    \n-
    66 : firstRow_(firstRow), pos_(pos)
    \n-
    67 {}
    \n-
    68
    \n+
    59#if __has_include("slu_cdefs.h")
    \n+
    60#include "slu_scomplex.h"
    \n+
    61
    \n+
    62extern "C" {
    \n+
    63 extern void
    \n+
    64 cgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
    \n+
    65 char *, float *, float *, SuperMatrix *, SuperMatrix *,
    \n+
    66 void *, int, SuperMatrix *, SuperMatrix *,
    \n+
    67 float *, float *, float *, float *,
    \n+
    68 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
    \n
    69
    \n-
    70 const typename Matrix::row_type& dereference() const
    \n-
    71 {
    \n-
    72 return *(firstRow_+ *pos_);
    \n-
    73 }
    \n-
    74 bool equals(const const_iterator& o) const
    \n-
    75 {
    \n-
    76 return pos_==o.pos_;
    \n-
    77 }
    \n-
    78 void increment()
    \n-
    79 {
    \n-
    80 ++pos_;
    \n-
    81 }
    \n-
    82 typename RowIndexSet::value_type index() const
    \n-
    83 {
    \n-
    84 return *pos_;
    \n-
    85 }
    \n-
    86
    \n-
    87 private:
    \n-
    89 typename Matrix::const_iterator firstRow_;
    \n-
    91 typename RowIndexSet::const_iterator pos_;
    \n-
    92 };
    \n-
    93
    \n-
    95 const_iterator begin() const
    \n-
    96 {
    \n-
    97 return const_iterator(m_.begin(), s_.begin());
    \n-
    98 }
    \n-
    100 const_iterator end() const
    \n-
    101 {
    \n-
    102 return const_iterator(m_.begin(), s_.end());
    \n-
    103 }
    \n+
    70
    \n+
    71 extern void
    \n+
    72 cCreate_Dense_Matrix(SuperMatrix *, int, int, ::complex *, int,
    \n+
    73 Stype_t, Dtype_t, Mtype_t);
    \n+
    74
    \n+
    75
    \n+
    76 extern void
    \n+
    77 cCreate_CompCol_Matrix(SuperMatrix *, int, int, int, ::complex *,
    \n+
    78 int *, int *, Stype_t, Dtype_t, Mtype_t);
    \n+
    79
    \n+
    80 extern int cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
    \n+
    81
    \n+
    82 extern void cPrint_CompCol_Matrix(char *, SuperMatrix *);
    \n+
    83}
    \n+
    84#endif
    \n+
    85
    \n+
    86#if __has_include("slu_zdefs.h")
    \n+
    87#include "slu_dcomplex.h"
    \n+
    88extern "C" {
    \n+
    89 extern void
    \n+
    90 zgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
    \n+
    91 char *, double *, double *, SuperMatrix *, SuperMatrix *,
    \n+
    92 void *, int, SuperMatrix *, SuperMatrix *,
    \n+
    93 double *, double *, double *, double *,
    \n+
    94 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);
    \n+
    95
    \n+
    96
    \n+
    97 extern void
    \n+
    98 zCreate_CompCol_Matrix(SuperMatrix *, int, int, int, doublecomplex *,
    \n+
    99 int *, int *, Stype_t, Dtype_t, Mtype_t);
    \n+
    100
    \n+
    101 extern void
    \n+
    102 zCreate_Dense_Matrix(SuperMatrix *, int, int, doublecomplex *, int,
    \n+
    103 Stype_t, Dtype_t, Mtype_t);
    \n
    104
    \n-
    105 private:
    \n-
    107 const Matrix& m_;
    \n-
    109 const RowIndexSet& s_;
    \n-
    110 };
    \n+
    105 extern int zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
    \n+
    106
    \n+
    107 extern void zPrint_CompCol_Matrix(char *, SuperMatrix *);
    \n+
    108}
    \n+
    109#endif
    \n+
    110
    \n
    111
    \n-
    118 template<class M, class I = typename M::size_type>
    \n-
    119 class BCCSMatrixInitializer
    \n-
    120 {
    \n-
    121 template<class IList, class S, class D>
    \n-\n-
    123 public:
    \n-
    124 using Matrix = M;
    \n-
    125 using Index = I;
    \n-
    126 typedef Dune::ISTL::Impl::BCCSMatrix<typename Matrix::field_type, I> OutputMatrix;
    \n-
    127 typedef typename Matrix::size_type size_type;
    \n-
    128
    \n-
    131 BCCSMatrixInitializer(OutputMatrix& mat_)
    \n-
    132 : mat(&mat_), cols(mat_.M())
    \n-
    133 {
    \n-
    134 if constexpr (Dune::IsNumber<typename M::block_type>::value)
    \n-
    135 {
    \n-
    136 n = m = 1;
    \n-
    137 }
    \n-
    138 else
    \n-
    139 {
    \n-
    140 // WARNING: This assumes that all blocks are dense and identical
    \n-
    141 n = M::block_type::rows;
    \n-
    142 m = M::block_type::cols;
    \n-
    143 }
    \n-
    144
    \n-
    145 mat->Nnz_=0;
    \n-
    146 }
    \n-
    147
    \n-
    148 BCCSMatrixInitializer()
    \n-
    149 : mat(0), cols(0), n(0), m(0)
    \n-
    150 {}
    \n-
    151
    \n-
    152 virtual ~BCCSMatrixInitializer()
    \n-
    153 {}
    \n-
    154
    \n-
    155 template<typename Iter>
    \n-
    156 void addRowNnz(const Iter& row) const
    \n-
    157 {
    \n-
    158 mat->Nnz_+=row->getsize();
    \n-
    159 }
    \n-
    160
    \n-
    161 template<typename Iter, typename FullMatrixIndex>
    \n-
    162 void addRowNnz(const Iter& row, const std::set<FullMatrixIndex>& indices) const
    \n-
    163 {
    \n-
    164 auto siter =indices.begin();
    \n-
    165 for (auto entry=row->begin(); entry!=row->end(); ++entry)
    \n-
    166 {
    \n-
    167 for(; siter!=indices.end() && *siter<entry.index(); ++siter) ;
    \n-
    168 if(siter==indices.end())
    \n-
    169 break;
    \n-
    170 if(*siter==entry.index())
    \n-
    171 // index is in subdomain
    \n-
    172 ++mat->Nnz_;
    \n-
    173 }
    \n-
    174 }
    \n-
    175
    \n-
    176 template<typename Iter, typename SubMatrixIndex>
    \n-
    177 void addRowNnz(const Iter& row, const std::vector<SubMatrixIndex>& indices) const
    \n-
    178 {
    \n-
    179 for (auto entry=row->begin(); entry!=row->end(); ++entry)
    \n-
    180 if (indices[entry.index()]!=std::numeric_limits<SubMatrixIndex>::max())
    \n-
    181 ++mat->Nnz_;
    \n-
    182 }
    \n-
    183
    \n-
    184 void allocate()
    \n-
    185 {
    \n-
    186 allocateMatrixStorage();
    \n-
    187 allocateMarker();
    \n-
    188 }
    \n-
    189
    \n-
    190 template<typename Iter, typename CIter>
    \n-
    191 void countEntries([[maybe_unused]] const Iter& row, const CIter& col) const
    \n-
    192 {
    \n-
    193 countEntries(col.index());
    \n-
    194 }
    \n-
    195
    \n-
    196 void countEntries(size_type colindex) const
    \n-
    197 {
    \n-
    198 for(size_type i=0; i < m; ++i)
    \n-
    199 {
    \n-
    200 assert(colindex*m+i<cols);
    \n-
    201 marker[colindex*m+i]+=n;
    \n-
    202 }
    \n-
    203 }
    \n-
    204
    \n-
    205 void calcColstart() const
    \n-
    206 {
    \n-
    207 mat->colstart[0]=0;
    \n-
    208 for(size_type i=0; i < cols; ++i) {
    \n-
    209 assert(i<cols);
    \n-
    210 mat->colstart[i+1]=mat->colstart[i]+marker[i];
    \n-
    211 marker[i]=mat->colstart[i];
    \n-
    212 }
    \n-
    213 }
    \n-
    214
    \n-
    215 template<typename Iter, typename CIter>
    \n-
    216 void copyValue(const Iter& row, const CIter& col) const
    \n-
    217 {
    \n-
    218 copyValue(col, row.index(), col.index());
    \n-
    219 }
    \n-
    220
    \n-
    221 template<typename CIter>
    \n-
    222 void copyValue(const CIter& col, size_type rowindex, size_type colindex) const
    \n-
    223 {
    \n-
    224 for(size_type i=0; i<n; i++) {
    \n-
    225 for(size_type j=0; j<m; j++) {
    \n-
    226 assert(colindex*m+j<cols-1 || (size_type)marker[colindex*m+j]<(size_type)mat->colstart[colindex*m+j+1]);
    \n-
    227 assert((size_type)marker[colindex*m+j]<mat->Nnz_);
    \n-
    228 mat->rowindex[marker[colindex*m+j]]=rowindex*n+i;
    \n-
    229 mat->values[marker[colindex*m+j]] = Dune::Impl::asMatrix(*col)[i][j];
    \n-
    230 ++marker[colindex*m+j]; // index for next entry in column
    \n-
    231 }
    \n-
    232 }
    \n-
    233 }
    \n-
    234
    \n-
    235 virtual void createMatrix() const
    \n-
    236 {
    \n-
    237 marker.clear();
    \n-
    238 }
    \n-
    239
    \n-
    240 protected:
    \n-
    241
    \n-
    242 void allocateMatrixStorage() const
    \n-
    243 {
    \n-
    244 mat->Nnz_*=n*m;
    \n-
    245 // initialize data
    \n-
    246 mat->values=new typename M::field_type[mat->Nnz_];
    \n-
    247 mat->rowindex=new I[mat->Nnz_];
    \n-
    248 mat->colstart=new I[cols+1];
    \n-
    249 }
    \n-
    250
    \n-
    251 void allocateMarker()
    \n-
    252 {
    \n-
    253 marker.resize(cols);
    \n-
    254 std::fill(marker.begin(), marker.end(), 0);
    \n-
    255 }
    \n-
    256
    \n-
    257 OutputMatrix* mat;
    \n-
    258 size_type cols;
    \n-
    259
    \n-
    260 // Number of rows/columns of the matrix entries
    \n-
    261 // (assumed to be scalars or dense matrices)
    \n-
    262 size_type n, m;
    \n-
    263
    \n-
    264 mutable std::vector<size_type> marker;
    \n-
    265 };
    \n-
    266
    \n-
    267 template<class F, class Matrix>
    \n-
    268 void copyToBCCSMatrix(F& initializer, const Matrix& matrix)
    \n-
    269 {
    \n-
    270 for (auto row=matrix.begin(); row!= matrix.end(); ++row)
    \n-
    271 initializer.addRowNnz(row);
    \n-
    272
    \n-
    273 initializer.allocate();
    \n-
    274
    \n-
    275 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {
    \n-
    276
    \n-
    277 for (auto col=row->begin(); col != row->end(); ++col)
    \n-
    278 initializer.countEntries(row, col);
    \n-
    279 }
    \n-
    280
    \n-
    281 initializer.calcColstart();
    \n-
    282
    \n-
    283 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {
    \n-
    284 for (auto col=row->begin(); col != row->end(); ++col) {
    \n-
    285 initializer.copyValue(row, col);
    \n-
    286 }
    \n-
    287
    \n-
    288 }
    \n-
    289 initializer.createMatrix();
    \n-
    290 }
    \n-
    291
    \n-
    292 template<class F, class M,class S>
    \n-
    293 void copyToBCCSMatrix(F& initializer, const MatrixRowSubset<M,S>& mrs)
    \n-
    294 {
    \n-
    295 typedef MatrixRowSubset<M,S> MRS;
    \n-
    296 typedef typename MRS::RowIndexSet SIS;
    \n-
    297 typedef typename SIS::const_iterator SIter;
    \n-
    298 typedef typename MRS::const_iterator Iter;
    \n-
    299 typedef typename std::iterator_traits<Iter>::value_type row_type;
    \n-
    300 typedef typename row_type::const_iterator CIter;
    \n-
    301
    \n-
    302 typedef typename MRS::Matrix::size_type size_type;
    \n-
    303
    \n-
    304 // A vector containing the corresponding indices in
    \n-
    305 // the to create submatrix.
    \n-
    306 // If an entry is the maximum of size_type then this index will not appear in
    \n-
    307 // the submatrix.
    \n-
    308 std::vector<size_type> subMatrixIndex(mrs.matrix().N(),
    \n-
    309 std::numeric_limits<size_type>::max());
    \n-
    310 size_type s=0;
    \n-
    311 for(SIter index = mrs.rowIndexSet().begin(); index!=mrs.rowIndexSet().end(); ++index)
    \n-
    312 subMatrixIndex[*index]=s++;
    \n-
    313
    \n-
    314 // Calculate upper Bound for nonzeros
    \n-
    315 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n-
    316 initializer.addRowNnz(row, subMatrixIndex);
    \n-
    317
    \n-
    318 initializer.allocate();
    \n-
    319
    \n-
    320 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n-
    321 for(CIter col=row->begin(); col != row->end(); ++col) {
    \n-
    322 if(subMatrixIndex[col.index()]!=std::numeric_limits<size_type>::max())
    \n-
    323 // This column is in our subset (use submatrix column index)
    \n-
    324 initializer.countEntries(subMatrixIndex[col.index()]);
    \n-
    325 }
    \n-
    326
    \n-
    327 initializer.calcColstart();
    \n-
    328
    \n-
    329 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)
    \n-
    330 for(CIter col=row->begin(); col != row->end(); ++col) {
    \n-
    331 if(subMatrixIndex[col.index()]!=std::numeric_limits<size_type>::max())
    \n-
    332 // This value is in our submatrix -> copy (use submatrix indices
    \n-
    333 initializer.copyValue(col, subMatrixIndex[row.index()], subMatrixIndex[col.index()]);
    \n-
    334 }
    \n-
    335 initializer.createMatrix();
    \n-
    336 }
    \n-
    337
    \n-
    338}
    \n-
    339#endif
    \n-\n-
    Col col
    Definition: matrixmatrix.hh:351
    \n-
    Matrix & mat
    Definition: matrixmatrix.hh:347
    \n-
    void addRowNnz(const Iter &row)
    Definition: overlappingschwarz.hh:895
    \n-
    void calcColstart() const
    Definition: overlappingschwarz.hh:926
    \n-
    void copyValue(const Iter &row, const CIter &col) const
    Definition: overlappingschwarz.hh:933
    \n-
    void createMatrix() const
    Definition: overlappingschwarz.hh:947
    \n-
    void allocate()
    Definition: overlappingschwarz.hh:905
    \n-
    std::size_t countEntries(const BlockVector< T, A > &vector)
    Definition: matrixmarket.hh:1076
    \n-
    Definition: allocator.hh:11
    \n-
    Initializer for SuperLU Matrices representing the subdomains.
    Definition: overlappingschwarz.hh:47
    \n-
    Matrix::row_type::const_iterator CIter
    Definition: overlappingschwarz.hh:56
    \n-
    Matrix::const_iterator Iter
    Definition: overlappingschwarz.hh:55
    \n-
    IndexSet::size_type size_type
    Definition: overlappingschwarz.hh:59
    \n-
    AtomInitializer::Matrix Matrix
    Definition: overlappingschwarz.hh:54
    \n-
    A::size_type size_type
    Type for indices and sizes.
    Definition: matrix.hh:577
    \n-
    MatrixImp::DenseMatrixBase< T, A >::window_type row_type
    The type implementing a matrix row.
    Definition: matrix.hh:574
    \n+
    112#endif
    \n+
    113#endif
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n", "details": [{"source1": "html2text {}", "source2": "html2text {}", "unified_diff": "@@ -4,383 +4,126 @@\n \n \n dune-istl\u00a02.9.0\n \n \n * dune\n * istl\n-bccsmatrixinitializer.hh\n+superlufunctions.hh\n Go_to_the_documentation_of_this_file.\n 1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file\n LICENSE.md in module root\n 2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception\n 3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n 4// vi: set et ts=4 sw=2 sts=2:\n- 5#ifndef DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH\n- 6#define DUNE_ISTL_BCCSMATRIX_INITIALIZER_HH\n- 7\n- 8#include \n- 9#include \n- 10\n- 11#include \n- 12#include \n- 13\n- 14#include \n- 15\n- 16namespace Dune\n- 17{\n- 18 template\n- 19 class OverlappingSchwarzInitializer;\n- 20}\n- 21\n- 22namespace Dune::ISTL::Impl\n- 23{\n- 31 template\n- 32 class MatrixRowSubset\n- 33 {\n- 34 public:\n- 36 typedef M Matrix;\n- 38 typedef S RowIndexSet;\n- 39\n- 45 MatrixRowSubset(const Matrix& m, const RowIndexSet& s)\n- 46 : m_(m), s_(s)\n- 47 {}\n+ 5#ifndef DUNE_ISTL_SUPERLUFUNCTIONS_HH\n+ 6#define DUNE_ISTL_SUPERLUFUNCTIONS_HH\n+ 7#if HAVE_SUPERLU\n+ 8\n+ 9\n+10#define int_t SUPERLU_INT_TYPE\n+ 11#include \"supermatrix.h\"\n+ 12#include \"slu_util.h\"\n+ 13#undef int_t\n+ 14\n+ 15#if __has_include(\"slu_sdefs.h\")\n+ 16extern \"C\" {\n+ 17 extern void\n+ 18 sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n+ 19 char *, float *, float *, SuperMatrix *, SuperMatrix *,\n+ 20 void *, int, SuperMatrix *, SuperMatrix *,\n+ 21 float *, float *, float *, float *,\n+ 22 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n+ 23\n+ 24 extern void\n+ 25 sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int,\n+ 26 Stype_t, Dtype_t, Mtype_t);\n+ 27 extern void\n+ 28 sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *,\n+ 29 int *, int *, Stype_t, Dtype_t, Mtype_t);\n+ 30 extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n+ 31\n+ 32 extern void sPrint_CompCol_Matrix(char *, SuperMatrix *);\n+ 33}\n+ 34#endif\n+ 35\n+ 36#if __has_include(\"slu_ddefs.h\")\n+ 37extern \"C\" {\n+ 38 extern void\n+ 39 dgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n+ 40 char *, double *, double *, SuperMatrix *, SuperMatrix *,\n+ 41 void *, int, SuperMatrix *, SuperMatrix *,\n+ 42 double *, double *, double *, double *,\n+ 43 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n+ 44\n+ 45 extern void\n+ 46 dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *,\n+ 47 int *, int *, Stype_t, Dtype_t, Mtype_t);\n 48\n- 49 const Matrix& matrix() const\n- 50 {\n- 51 return m_;\n- 52 }\n- 53\n- 54 const RowIndexSet& rowIndexSet() const\n- 55 {\n- 56 return s_;\n- 57 }\n+ 49 extern void\n+ 50 dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int,\n+ 51 Stype_t, Dtype_t, Mtype_t);\n+ 52\n+ 53 extern int dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n+ 54\n+ 55 extern void dPrint_CompCol_Matrix(char *, SuperMatrix *);\n+ 56}\n+ 57#endif\n 58\n- 60 class const_iterator\n- 61 : public ForwardIteratorFacade\n- 62 {\n- 63 public:\n- 64 const_iterator(typename Matrix::const_iterator firstRow,\n- 65 typename RowIndexSet::const_iterator pos)\n- 66 : firstRow_(firstRow), pos_(pos)\n- 67 {}\n- 68\n+ 59#if __has_include(\"slu_cdefs.h\")\n+ 60#include \"slu_scomplex.h\"\n+ 61\n+ 62extern \"C\" {\n+ 63 extern void\n+ 64 cgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n+ 65 char *, float *, float *, SuperMatrix *, SuperMatrix *,\n+ 66 void *, int, SuperMatrix *, SuperMatrix *,\n+ 67 float *, float *, float *, float *,\n+ 68 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n 69\n- 70 const typename Matrix::row_type& dereference() const\n- 71 {\n- 72 return *(firstRow_+ *pos_);\n- 73 }\n- 74 bool equals(const const_iterator& o) const\n- 75 {\n- 76 return pos_==o.pos_;\n- 77 }\n- 78 void increment()\n- 79 {\n- 80 ++pos_;\n- 81 }\n- 82 typename RowIndexSet::value_type index() const\n- 83 {\n- 84 return *pos_;\n- 85 }\n- 86\n- 87 private:\n- 89 typename Matrix::const_iterator firstRow_;\n- 91 typename RowIndexSet::const_iterator pos_;\n- 92 };\n- 93\n- 95 const_iterator begin() const\n- 96 {\n- 97 return const_iterator(m_.begin(), s_.begin());\n- 98 }\n- 100 const_iterator end() const\n- 101 {\n- 102 return const_iterator(m_.begin(), s_.end());\n- 103 }\n+ 70\n+ 71 extern void\n+ 72 cCreate_Dense_Matrix(SuperMatrix *, int, int, ::complex *, int,\n+ 73 Stype_t, Dtype_t, Mtype_t);\n+ 74\n+ 75\n+ 76 extern void\n+ 77 cCreate_CompCol_Matrix(SuperMatrix *, int, int, int, ::complex *,\n+ 78 int *, int *, Stype_t, Dtype_t, Mtype_t);\n+ 79\n+ 80 extern int cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n+ 81\n+ 82 extern void cPrint_CompCol_Matrix(char *, SuperMatrix *);\n+ 83}\n+ 84#endif\n+ 85\n+ 86#if __has_include(\"slu_zdefs.h\")\n+ 87#include \"slu_dcomplex.h\"\n+ 88extern \"C\" {\n+ 89 extern void\n+ 90 zgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,\n+ 91 char *, double *, double *, SuperMatrix *, SuperMatrix *,\n+ 92 void *, int, SuperMatrix *, SuperMatrix *,\n+ 93 double *, double *, double *, double *,\n+ 94 GlobalLU_t*, mem_usage_t *, SuperLUStat_t *, int *);\n+ 95\n+ 96\n+ 97 extern void\n+ 98 zCreate_CompCol_Matrix(SuperMatrix *, int, int, int, doublecomplex *,\n+ 99 int *, int *, Stype_t, Dtype_t, Mtype_t);\n+ 100\n+ 101 extern void\n+ 102 zCreate_Dense_Matrix(SuperMatrix *, int, int, doublecomplex *, int,\n+ 103 Stype_t, Dtype_t, Mtype_t);\n 104\n- 105 private:\n- 107 const Matrix& m_;\n- 109 const RowIndexSet& s_;\n- 110 };\n+ 105 extern int zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);\n+ 106\n+ 107 extern void zPrint_CompCol_Matrix(char *, SuperMatrix *);\n+ 108}\n+ 109#endif\n+ 110\n 111\n- 118 template\n- 119 class BCCSMatrixInitializer\n- 120 {\n- 121 template\n- 122 friend class Dune::OverlappingSchwarzInitializer;\n- 123 public:\n- 124 using Matrix = M;\n- 125 using Index = I;\n- 126 typedef Dune::ISTL::Impl::BCCSMatrix\n-OutputMatrix;\n- 127 typedef typename Matrix::size_type size_type;\n- 128\n- 131 BCCSMatrixInitializer(OutputMatrix& mat_)\n- 132 : mat(&mat_), cols(mat_.M())\n- 133 {\n- 134 if constexpr (Dune::IsNumber::value)\n- 135 {\n- 136 n = m = 1;\n- 137 }\n- 138 else\n- 139 {\n- 140 // WARNING: This assumes that all blocks are dense and identical\n- 141 n = M::block_type::rows;\n- 142 m = M::block_type::cols;\n- 143 }\n- 144\n- 145 mat->Nnz_=0;\n- 146 }\n- 147\n- 148 BCCSMatrixInitializer()\n- 149 : mat(0), cols(0), n(0), m(0)\n- 150 {}\n- 151\n- 152 virtual ~BCCSMatrixInitializer()\n- 153 {}\n- 154\n- 155 template\n- 156 void addRowNnz(const Iter& row) const\n- 157 {\n- 158 mat->Nnz_+=row->getsize();\n- 159 }\n- 160\n- 161 template\n- 162 void addRowNnz(const Iter& row, const std::set& indices)\n-const\n- 163 {\n- 164 auto siter =indices.begin();\n- 165 for (auto entry=row->begin(); entry!=row->end(); ++entry)\n- 166 {\n- 167 for(; siter!=indices.end() && *siterNnz_;\n- 173 }\n- 174 }\n- 175\n- 176 template\n- 177 void addRowNnz(const Iter& row, const std::vector&\n-indices) const\n- 178 {\n- 179 for (auto entry=row->begin(); entry!=row->end(); ++entry)\n- 180 if (indices[entry.index()]!=std::numeric_limits::max())\n- 181 ++mat->Nnz_;\n- 182 }\n- 183\n- 184 void allocate()\n- 185 {\n- 186 allocateMatrixStorage();\n- 187 allocateMarker();\n- 188 }\n- 189\n- 190 template\n- 191 void countEntries([[maybe_unused]] const Iter& row, const CIter& col)\n-const\n- 192 {\n- 193 countEntries(col.index());\n- 194 }\n- 195\n- 196 void countEntries(size_type colindex) const\n- 197 {\n- 198 for(size_type i=0; i < m; ++i)\n- 199 {\n- 200 assert(colindex*m+icolstart[0]=0;\n- 208 for(size_type i=0; i < cols; ++i) {\n- 209 assert(icolstart[i+1]=mat->colstart[i]+marker[i];\n- 211 marker[i]=mat->colstart[i];\n- 212 }\n- 213 }\n- 214\n- 215 template\n- 216 void copyValue(const Iter& row, const CIter& col) const\n- 217 {\n- 218 copyValue(col, row.index(), col.index());\n- 219 }\n- 220\n- 221 template\n- 222 void copyValue(const CIter& col, size_type rowindex, size_type colindex)\n-const\n- 223 {\n- 224 for(size_type i=0; icolstart[colindex*m+j+1]);\n- 227 assert((size_type)marker[colindex*m+j]Nnz_);\n- 228 mat->rowindex[marker[colindex*m+j]]=rowindex*n+i;\n- 229 mat->values[marker[colindex*m+j]] = Dune::Impl::asMatrix(*col)[i][j];\n- 230 ++marker[colindex*m+j]; // index for next entry in column\n- 231 }\n- 232 }\n- 233 }\n- 234\n- 235 virtual void createMatrix() const\n- 236 {\n- 237 marker.clear();\n- 238 }\n- 239\n- 240 protected:\n- 241\n- 242 void allocateMatrixStorage() const\n- 243 {\n- 244 mat->Nnz_*=n*m;\n- 245 // initialize data\n- 246 mat->values=new typename M::field_type[mat->Nnz_];\n- 247 mat->rowindex=new I[mat->Nnz_];\n- 248 mat->colstart=new I[cols+1];\n- 249 }\n- 250\n- 251 void allocateMarker()\n- 252 {\n- 253 marker.resize(cols);\n- 254 std::fill(marker.begin(), marker.end(), 0);\n- 255 }\n- 256\n- 257 OutputMatrix* mat;\n- 258 size_type cols;\n- 259\n- 260 // Number of rows/columns of the matrix entries\n- 261 // (assumed to be scalars or dense matrices)\n- 262 size_type n, m;\n- 263\n- 264 mutable std::vector marker;\n- 265 };\n- 266\n- 267 template\n- 268 void copyToBCCSMatrix(F& initializer, const Matrix& matrix)\n- 269 {\n- 270 for (auto row=matrix.begin(); row!= matrix.end(); ++row)\n- 271 initializer.addRowNnz(row);\n- 272\n- 273 initializer.allocate();\n- 274\n- 275 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {\n- 276\n- 277 for (auto col=row->begin(); col != row->end(); ++col)\n- 278 initializer.countEntries(row, col);\n- 279 }\n- 280\n- 281 initializer.calcColstart();\n- 282\n- 283 for (auto row=matrix.begin(); row!= matrix.end(); ++row) {\n- 284 for (auto col=row->begin(); col != row->end(); ++col) {\n- 285 initializer.copyValue(row, col);\n- 286 }\n- 287\n- 288 }\n- 289 initializer.createMatrix();\n- 290 }\n- 291\n- 292 template\n- 293 void copyToBCCSMatrix(F& initializer, const MatrixRowSubset& mrs)\n- 294 {\n- 295 typedef MatrixRowSubset MRS;\n- 296 typedef typename MRS::RowIndexSet SIS;\n- 297 typedef typename SIS::const_iterator SIter;\n- 298 typedef typename MRS::const_iterator Iter;\n- 299 typedef typename std::iterator_traits::value_type row_type;\n- 300 typedef typename row_type::const_iterator CIter;\n- 301\n- 302 typedef typename MRS::Matrix::size_type size_type;\n- 303\n- 304 // A vector containing the corresponding indices in\n- 305 // the to create submatrix.\n- 306 // If an entry is the maximum of size_type then this index will not appear\n-in\n- 307 // the submatrix.\n- 308 std::vector subMatrixIndex(mrs.matrix().N(),\n- 309 std::numeric_limits::max());\n- 310 size_type s=0;\n- 311 for(SIter index = mrs.rowIndexSet().begin(); index!=mrs.rowIndexSet().end\n-(); ++index)\n- 312 subMatrixIndex[*index]=s++;\n- 313\n- 314 // Calculate upper Bound for nonzeros\n- 315 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n- 316 initializer.addRowNnz(row, subMatrixIndex);\n- 317\n- 318 initializer.allocate();\n- 319\n- 320 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n- 321 for(CIter col=row->begin(); col != row->end(); ++col) {\n- 322 if(subMatrixIndex[col.index()]!=std::numeric_limits::max())\n- 323 // This column is in our subset (use submatrix column index)\n- 324 initializer.countEntries(subMatrixIndex[col.index()]);\n- 325 }\n- 326\n- 327 initializer.calcColstart();\n- 328\n- 329 for(Iter row=mrs.begin(); row!= mrs.end(); ++row)\n- 330 for(CIter col=row->begin(); col != row->end(); ++col) {\n- 331 if(subMatrixIndex[col.index()]!=std::numeric_limits::max())\n- 332 // This value is in our submatrix -> copy (use submatrix indices\n- 333 initializer.copyValue(col, subMatrixIndex[row.index()], subMatrixIndex\n-[col.index()]);\n- 334 }\n- 335 initializer.createMatrix();\n- 336 }\n- 337\n- 338}\n- 339#endif\n-bccsmatrix.hh\n-col\n-Col col\n-Definition: matrixmatrix.hh:351\n-mat\n-Matrix & mat\n-Definition: matrixmatrix.hh:347\n-Dune::OverlappingSchwarzInitializer::addRowNnz\n-void addRowNnz(const Iter &row)\n-Definition: overlappingschwarz.hh:895\n-Dune::OverlappingSchwarzInitializer::calcColstart\n-void calcColstart() const\n-Definition: overlappingschwarz.hh:926\n-Dune::OverlappingSchwarzInitializer::copyValue\n-void copyValue(const Iter &row, const CIter &col) const\n-Definition: overlappingschwarz.hh:933\n-Dune::OverlappingSchwarzInitializer::createMatrix\n-void createMatrix() const\n-Definition: overlappingschwarz.hh:947\n-Dune::OverlappingSchwarzInitializer::allocate\n-void allocate()\n-Definition: overlappingschwarz.hh:905\n-Dune::countEntries\n-std::size_t countEntries(const BlockVector< T, A > &vector)\n-Definition: matrixmarket.hh:1076\n-Dune\n-Definition: allocator.hh:11\n-Dune::OverlappingSchwarzInitializer\n-Initializer for SuperLU Matrices representing the subdomains.\n-Definition: overlappingschwarz.hh:47\n-Dune::OverlappingSchwarzInitializer::CIter\n-Matrix::row_type::const_iterator CIter\n-Definition: overlappingschwarz.hh:56\n-Dune::OverlappingSchwarzInitializer::Iter\n-Matrix::const_iterator Iter\n-Definition: overlappingschwarz.hh:55\n-Dune::OverlappingSchwarzInitializer::size_type\n-IndexSet::size_type size_type\n-Definition: overlappingschwarz.hh:59\n-Dune::OverlappingSchwarzInitializer::Matrix\n-AtomInitializer::Matrix Matrix\n-Definition: overlappingschwarz.hh:54\n-Dune::Matrix::size_type\n-A::size_type size_type\n-Type for indices and sizes.\n-Definition: matrix.hh:577\n-Dune::Matrix::row_type\n-MatrixImp::DenseMatrixBase< T, A >::window_type row_type\n-The type implementing a matrix row.\n-Definition: matrix.hh:574\n+ 112#endif\n+ 113#endif\n \n ===============================================================================\n Generated by\u00a0[doxygen] 1.9.4\n"}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00233.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00233.html", "unified_diff": "@@ -98,25 +98,25 @@\n  \n  Sparse Matrix and Vector classes\n  Matrix and Vector classes that support a block recursive structure capable of representing the natural structure from Finite Element discretisations.
    \n  \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  ldl.hh
     Class for using LDL with ISTL matrices.
    file  ldl.hh
     Class for using LDL with ISTL matrices.
     
    file  spqr.hh
     Class for using SPQR with ISTL matrices.
    file  spqr.hh
     Class for using SPQR with ISTL matrices.
     
    file  superlu.hh
     Classes for using SuperLU with ISTL matrices.
    file  superlu.hh
     Classes for using SuperLU with ISTL matrices.
     
    file  umfpack.hh
     Classes for using UMFPack with ISTL matrices.
    file  umfpack.hh
     Classes for using UMFPack with ISTL matrices.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00234.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00234.html", "unified_diff": "@@ -97,19 +97,19 @@\n \n \n \n \n

    \n Classes

    class  Dune::ILUSubdomainSolver< M, X, Y >
     base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver. More...
     
     
     Scalar products
     Scalar products for the use in iterative solvers.
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  solver.hh
     Define general, extensible interface for inverse operators.
    file  solver.hh
     Define general, extensible interface for inverse operators.
     
    file  solvers.hh
     Implementations of the inverse operator interface.
    file  solvers.hh
     Implementations of the inverse operator interface.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00236.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00236.html", "unified_diff": "@@ -77,16 +77,16 @@\n \"\"\n \"\"\n \n \n

    \n Classes

    struct  Dune::InverseOperatorResult
     Statistics about the application of an inverse operator. More...
     
    \n \n-\n-\n+\n+\n \n

    \n Files

    file  owneroverlapcopy.hh
     Classes providing communication interfaces for overlapping Schwarz methods.
    file  owneroverlapcopy.hh
     Classes providing communication interfaces for overlapping Schwarz methods.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00237.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00237.html", "unified_diff": "@@ -98,19 +98,19 @@\n \n \n \n \n

    \n Classes

    struct  Dune::OwnerOverlapCopyAttributeSet
     Attribute set for overlapping Schwarz. More...
     
     Provides methods for reading and writing matrices and vectors in various formats.
     
     DenseMatVec
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  matrixmatrix.hh
     provides functions for sparse matrix matrix multiplication.
    file  matrixmatrix.hh
     provides functions for sparse matrix matrix multiplication.
     
    file  matrixutils.hh
     Some handy generic functions for ISTL matrices.
    file  matrixutils.hh
     Some handy generic functions for ISTL matrices.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00239.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00239.html", "unified_diff": "@@ -76,16 +76,16 @@\n \"\"\n \"\"\n \n \n

    \n Classes

    struct  Dune::MatrixDimension< M >
     
    struct  Dune::CompressionStatistics< size_type >
    \n \n-\n-\n+\n+\n \n

    \n Files

    file  operators.hh
     Define general, extensible interface for operators. The available implementation wraps a matrix.
    file  operators.hh
     Define general, extensible interface for operators. The available implementation wraps a matrix.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00240.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00240.html", "unified_diff": "@@ -86,61 +86,61 @@\n \"\"\n \"\"\n \n \n

    \n Classes

    class  Dune::NonoverlappingSchwarzOperator< M, X, Y, C >
     A nonoverlapping operator with communication object. More...
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  aggregates.hh
     Provides classes for the Coloring process of AMG.
    file  aggregates.hh
     Provides classes for the Coloring process of AMG.
     
    file  amg.hh
     The AMG preconditioner.
    file  amg.hh
     The AMG preconditioner.
     
    file  construction.hh
     Helper classes for the construction of classes without empty constructor.
    file  construction.hh
     Helper classes for the construction of classes without empty constructor.
     
    file  dependency.hh
     Provides classes for initializing the link attributes of a matrix graph.
    file  dependency.hh
     Provides classes for initializing the link attributes of a matrix graph.
     
    file  galerkin.hh
     Provides a class for building the galerkin product based on a aggregation scheme.
    file  galerkin.hh
     Provides a class for building the galerkin product based on a aggregation scheme.
     
    file  globalaggregates.hh
     Provdes class for identifying aggregates globally.
    file  globalaggregates.hh
     Provdes class for identifying aggregates globally.
     
    file  graph.hh
     Provides classes for building the matrix graph.
    file  graph.hh
     Provides classes for building the matrix graph.
     
    file  hierarchy.hh
     Provides a classes representing the hierarchies in AMG.
    file  hierarchy.hh
     Provides a classes representing the hierarchies in AMG.
     
    file  indicescoarsener.hh
     Provides a class for building the index set and remote indices on the coarse level.
    file  indicescoarsener.hh
     Provides a class for building the index set and remote indices on the coarse level.
     
    file  kamg.hh
     Provides an algebraic multigrid using a Krylov cycle.
    file  kamg.hh
     Provides an algebraic multigrid using a Krylov cycle.
     
    file  matrixhierarchy.hh
     Provides a classes representing the hierarchies in AMG.
    file  matrixhierarchy.hh
     Provides a classes representing the hierarchies in AMG.
     
    file  parameters.hh
     Parameter classes for customizing AMG.
    file  parameters.hh
     Parameter classes for customizing AMG.
     
    file  properties.hh
     Provides classes for handling internal properties in a graph.
    file  properties.hh
     Provides classes for handling internal properties in a graph.
     
    file  smoother.hh
     Classes for the generic construction and application of the smoothers.
    file  smoother.hh
     Classes for the generic construction and application of the smoothers.
     
    file  transfer.hh
     Prolongation and restriction for amg.
    file  transfer.hh
     Prolongation and restriction for amg.
     
    file  twolevelmethod.hh
     Algebraic twolevel methods.
    file  twolevelmethod.hh
     Algebraic twolevel methods.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00242.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00242.html", "unified_diff": "@@ -91,19 +91,19 @@\n \n \n \n \n

    \n Namespaces

    namespace  Dune
     
    namespace  Dune::Amg
     
     Fast (sequential) Algebraic Multigrid
     An Algebraic Multigrid based on Agglomeration that saves memory bandwidth.
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  overlappingschwarz.hh
     Contains one level overlapping Schwarz preconditioners.
    file  overlappingschwarz.hh
     Contains one level overlapping Schwarz preconditioners.
     
    file  preconditioners.hh
     Define general preconditioner interface.
    file  preconditioners.hh
     Define general preconditioner interface.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00243.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00243.html", "unified_diff": "@@ -79,16 +79,16 @@\n \"\"\n \"\"\n \n \n

    \n Classes

    class  Dune::NonoverlappingBlockPreconditioner< C, P >
     Nonoverlapping parallel preconditioner. More...
     
    \n \n-\n-\n+\n+\n \n

    \n Files

    file  scalarproducts.hh
     Define base class for scalar product and norm.
    file  scalarproducts.hh
     Define base class for scalar product and norm.
     
    \n \n \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a00246.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a00246.html", "unified_diff": "@@ -82,19 +82,19 @@\n \"\"\n \"\"\n \n \n

    \n Classes

    class  Dune::ScalarProduct< X >
     Base class for scalar product and norm computation. More...
     
    \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  io.hh
     Some generic functions for pretty printing vectors and matrices.
    file  io.hh
     Some generic functions for pretty printing vectors and matrices.
     
    file  matrixmarket.hh
     Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
    file  matrixmarket.hh
     Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
     
    \n \n \n \n

    \n Namespaces

    namespace  Dune::MatrixMarketImpl
     
    \n@@ -308,16 +308,16 @@\n \n \n
    \n inline
    \n
    \n \n

    Print a row of zeros for a non-existing block.

    \n-
    #include <dune/istl/io.hh>
    \n-
    Some generic functions for pretty printing vectors and matrices.
    \n+
    #include <dune/istl/io.hh>
    \n+
    Some generic functions for pretty printing vectors and matrices.
    \n
    \n
    \n
    \n \n

    ◆ loadMatrixMarket() [1/2]

    \n \n
    \n@@ -736,15 +736,15 @@\n )\n \n \n \n
    \n \n

    Print one row of a matrix, specialization for number types.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    \n
    \n
    \n \n

    ◆ print_row() [2/2]

    \n \n
    \n@@ -805,15 +805,15 @@\n )\n \n \n \n
    \n \n

    Print one row of a matrix.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    \n
    \n
    \n \n

    ◆ printmatrix()

    \n \n
    \n@@ -862,15 +862,15 @@\n )\n \n \n \n
    \n \n

    Print a generic block matrix.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    Bug:
    Empty rows and columns are omitted by this method. (FlySpray #7)
    \n \n
    \n
    \n \n

    ◆ printSparseMatrix()

    \n \n@@ -920,15 +920,15 @@\n )\n \n \n \n
    \n \n

    Prints a BCRSMatrix with fixed sized blocks.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n

    Only the nonzero entries will be printed as matrix blocks together with their corresponding column index and all others will be omitted.

    \n

    This might be preferable over printmatrix in the case of big sparse matrices with nonscalar blocks.

    \n
    Parameters
    \n \n \n \n \n@@ -996,15 +996,15 @@\n \n \n \n
    sThe ostream to print to.
    matThe matrix to print.
    titleThe title for the matrix.
    )
    \n
    \n \n

    Print an ISTL vector.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    \n
    \n
    \n \n

    ◆ readMatrixMarket() [1/2]

    \n \n
    \n@@ -1133,15 +1133,15 @@\n )\n \n \n \n
    \n \n

    Recursively print a vector.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    \n
    \n
    \n \n

    ◆ storeMatrixMarket() [1/2]

    \n \n
    \n@@ -1384,15 +1384,15 @@\n )\n \n \n \n
    \n \n

    Writes sparse matrix in a Matlab-readable format.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n

    This routine writes the argument BCRSMatrix to a file with the name given by the filename argument. The file format is ASCII, with no header, and three data columns. Each row describes a scalar matrix entry and consists of the matrix row and column numbers (both counted starting from 1), and the matrix entry. Such a file can be read from Matlab using the command

    new_mat = spconvert(load('filename'));
    \n
    Parameters
    \n \n \n \n \n
    matrixreference to matrix
    filename
    outputPrecision(number of digits) which is used to write the output file
    \n@@ -1444,15 +1444,15 @@\n )\n \n \n \n
    \n \n

    Helper method for the writeMatrixToMatlab routine.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n

    This specialization for numbers ends the recursion

    \n \n
    \n
    \n \n

    ◆ writeMatrixToMatlabHelper() [2/2]

    \n \n@@ -1496,15 +1496,15 @@\n )\n \n \n \n
    \n \n

    Helper method for the writeMatrixToMatlab routine.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n
    \n
    \n
    \n \n

    ◆ writeSVGMatrix()

    \n \n
    \n@@ -1589,15 +1589,15 @@\n )\n \n \n \n
    \n \n

    Writes vectors in a Matlab-readable format.

    \n-
    #include <dune/istl/io.hh>
    \n+
    #include <dune/istl/io.hh>
    \n

    This routine writes the argument block vector to a file with the name given by the filename argument. The file format is ASCII, with no header, and a single data column. Such a file can be read from Matlab using the command

    new_vec = load('filename');
    \n
    Parameters
    \n \n \n \n \n
    vectorreference to vector to be printed to output file
    filenamefilename of output file
    outputPrecision(number of digits) which is used to write the output file
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01084.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01084.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::exists< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/allocator.hh>

    \n+

    #include <dune/istl/allocator.hh>

    \n \n \n \n \n

    \n Static Public Attributes

    static const bool value = true
     
    \n

    Member Data Documentation

    \n@@ -102,15 +102,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01088.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01088.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::DefaultAllocatorTraits< T, typename > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/allocator.hh>

    \n+

    #include <dune/istl/allocator.hh>

    \n
    \n Inheritance diagram for Dune::DefaultAllocatorTraits< T, typename >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -103,15 +103,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01092.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01092.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::DefaultAllocatorTraits< T, std::void_t< typename T::allocator_type > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/allocator.hh>

    \n+

    #include <dune/istl/allocator.hh>

    \n \n \n \n \n

    \n Public Types

    using type = typename T::allocator_type
     
    \n

    Member Typedef Documentation

    \n@@ -94,15 +94,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01096.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01096.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::AllocatorTraits< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/allocator.hh>

    \n+

    #include <dune/istl/allocator.hh>

    \n
    \n Inheritance diagram for Dune::AllocatorTraits< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -111,15 +111,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01120.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01120.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::OverlappingSchwarzInitializer< I, S, D > Class Template Reference
    \n \n
    \n \n

    Initializer for SuperLU Matrices representing the subdomains. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -248,16 +248,16 @@\n
    \n \n

    The vector type containing the subdomain to row index mapping.

    \n \n
    \n \n
    The documentation for this class was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01136.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01136.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixDimension< M > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n

    \n Public Types

    typedef D subdomain_vector
     The vector type containing the subdomain to row index mapping. More...
     
    typedef I InitializerList
    \n \n \n \n \n \n@@ -136,16 +136,16 @@\n \n

    \n Static Public Member Functions

    static auto rowdim (const M &A)
     
    static auto coldim (const M &A)
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01140.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01140.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::CompressionStatistics< size_type > Struct Template Reference
    \n \n
    \n \n

    Statistics about compression achieved in implicit mode. \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n \n \n \n \n \n \n@@ -168,15 +168,15 @@\n
    \n \n

    total number of elements written to the overflow area during construction.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01144.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01144.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::ImplicitMatrixBuilder< M_ > Class Template Reference
    \n \n
    \n \n

    A wrapper for uniform access to the BCRSMatrix during and after the build stage in implicit build mode. \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n

    \n Public Attributes

    double avg
     average number of non-zeroes per row. More...
     
    size_type maximum
    \n \n \n \n \n

    \n Classes

    class  row_object
     Proxy row object for entry access. More...
     
    \n@@ -369,15 +369,15 @@\n
    \n \n

    Returns a proxy for entries in row i.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01148.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01148.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::ImplicitMatrixBuilder< M_ >::row_object Class Reference
    \n \n
    \n \n

    Proxy row object for entry access. \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n
    \n \n \n \n \n

    \n Public Member Functions

    block_typeoperator[] (size_type j) const
     Returns entry in column j. More...
     
    \n@@ -116,15 +116,15 @@\n
    \n \n

    Returns entry in column j.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01152.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01152.html", "unified_diff": "@@ -78,15 +78,15 @@\n
    Dune::BCRSMatrix< B, A > Class Template Reference
    \n \n
    \n \n

    A sparse block matrix with compressed row storage. \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n
    \n Inheritance diagram for Dune::BCRSMatrix< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -441,15 +441,15 @@\n

    Error checking: no error checking is provided normally. Setting the compile time switch DUNE_ISTL_WITH_CHECKING enables error checking.

    \n

    Details:

    \n
      \n
    1. Row-wise scheme
    2. \n
    \n

    Rows are built up in sequential order. Size of the row and the column indices are defined. A row can be used as soon as it is initialized. With respect to memory there are two variants of this scheme: (a) number of non-zeroes known in advance (application finite difference schemes), (b) number of non-zeroes not known in advance (application: Sparse LU, ILU(n)).

    \n
    #include<dune/common/fmatrix.hh>
    \n-\n+\n
    \n
    ...
    \n
    \n \n
    // third parameter is an optional upper bound for the number
    \n
    // of nonzeros. If given the matrix will use one array for all values
    \n
    // as opposed to one for each row.
    \n@@ -466,25 +466,25 @@\n
    row.insert(row.index()+1);
    \n
    }
    \n
    \n
    // Now the sparsity pattern is fully set up and we can add values
    \n
    \n
    B[0][0]=2;
    \n
    ...
    \n-
    Implementation of the BCRSMatrix class.
    \n+
    Implementation of the BCRSMatrix class.
    \n
    A sparse block matrix with compressed row storage.
    Definition: bcrsmatrix.hh:466
    \n
    size_type M() const
    number of columns (counted in blocks)
    Definition: bcrsmatrix.hh:1978
    \n
    Iterator class for sequential creation of blocks
    Definition: bcrsmatrix.hh:957
    \n
    Definition: matrixutils.hh:27
    \n
      \n
    1. Random scheme
    2. \n
    \n

    For general finite element implementations the number of rows n is known, the number of non-zeroes might also be known (e.g. #edges + #nodes for P2) but the size of a row and the indices of a row can not be defined in sequential order.

    \n
    #include<dune/common/fmatrix.hh>
    \n-\n+\n
    \n
    ...
    \n
    \n \n \n
    \n
    // initially set row size for each row
    \n@@ -544,15 +544,15 @@\n M_i = \\textrm{avg} + A + \\sum_{j<i} (\\textrm{avg} - \\textrm{nnz}_j)\n \\]\" src=\"form_23.png\" width=\"178\" height=\"29\"/>\n

    \n

    for all \"$i$\", where \"$ is the total size of the compression buffer determined by the parameters explained above.

    \n

    The data of the matrix is now located at the beginning of the allocated area, and covers what used to be the compression buffer. In exchange, there is now unused space at the end of the large allocated piece of memory. This will go unused and cannot be freed during the lifetime of the matrix, but it has no negative impact on run-time performance. No matrix entries may be added after the compression step.

    \n

    The compress() method returns a value of type Dune::CompressionStatistics, which you can inspect to tune the construction parameters _avg and compressionBufferSize.

    \n

    Use of copy constructor, assignment operator and matrix vector arithmetics are not supported until the matrix is fully built.

    \n-

    The following sample code constructs a \"$ matrix, with an expected number of two entries per matrix row. The compression buffer size is set to 0.4. Hence the main chunk of allocated memory will be able to hold 10 * 2 entries in the matrix rows, and 10 * 2 * 0.4 entries in the compression buffer. In total that's 28 entries.

    \n+

    The following sample code constructs a \"$ matrix, with an expected number of two entries per matrix row. The compression buffer size is set to 0.4. Hence the main chunk of allocated memory will be able to hold 10 * 2 entries in the matrix rows, and 10 * 2 * 0.4 entries in the compression buffer. In total that's 28 entries.

    \n
    \n \n
    M m(10, 10, 2, 0.4, M::implicit);
    \n
    \n
    // Fill in some arbitrary entries; the order is irrelevant.
    \n
    // Even operations on these would be possible, you get a reference to the entry!
    \n
    m.entry(0,0) = 0.;
    \n@@ -3751,15 +3751,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01156.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01156.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::BCRSMatrix< B, A >::RealRowIterator< T > Class Template Reference
    \n
    \n
    \n \n

    Iterator access to matrix rows \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n
    \n Inheritance diagram for Dune::BCRSMatrix< B, A >::RealRowIterator< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -400,15 +400,15 @@\n
    \n \n

    return index

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01160.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01160.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::BCRSMatrix< B, A >::CreateIterator Class Reference
    \n \n
    \n \n

    Iterator class for sequential creation of blocks \n More...

    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n \n \n \n \n \n \n@@ -355,15 +355,15 @@\n \n

    Get the current row size.

    \n
    Returns
    The number of indices already inserted for the current row.
    \n \n \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01164.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01164.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< BCRSMatrix< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/bcrsmatrix.hh>

    \n+

    #include <dune/istl/bcrsmatrix.hh>

    \n

    \n Public Member Functions

     CreateIterator (BCRSMatrix &_Mat, size_type _i)
     constructor More...
     
    CreateIteratoroperator++ ()
    \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    using field_type = typename BCRSMatrix< B, A >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01168.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01168.html", "unified_diff": "@@ -77,15 +77,15 @@\n
    Dune::BDMatrix< B, A > Class Template Reference
    \n \n
    \n \n

    A block-diagonal matrix. \n More...

    \n \n-

    #include <dune/istl/bdmatrix.hh>

    \n+

    #include <dune/istl/bdmatrix.hh>

    \n
    \n Inheritance diagram for Dune::BDMatrix< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -3224,15 +3224,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01172.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01172.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< BDMatrix< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/bdmatrix.hh>

    \n+

    #include <dune/istl/bdmatrix.hh>

    \n \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    using field_type = typename BDMatrix< B, A >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01176.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01176.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::MultiTypeBlockVector< Args > Class Template Reference
    \n \n
    \n \n

    A Vector class to support different block types. \n More...

    \n \n-

    #include <dune/istl/multitypeblockvector.hh>

    \n+

    #include <dune/istl/multitypeblockvector.hh>

    \n
    \n Inheritance diagram for Dune::MultiTypeBlockVector< Args >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -168,16 +168,16 @@\n  \n \n

    Detailed Description

    \n
    template<typename... Args>
    \n class Dune::MultiTypeBlockVector< Args >

    A Vector class to support different block types.

    \n

    This vector class combines elements of different types known at compile-time.

    \n

    The documentation for this class was generated from the following files:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01180.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01180.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::MultiTypeBlockMatrix< FirstRow, Args > Class Template Reference
    \n
    \n
    \n \n

    A Matrix class to support different block types. \n More...

    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n
    \n Inheritance diagram for Dune::MultiTypeBlockMatrix< FirstRow, Args >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -194,16 +194,16 @@\n  \n \n

    Detailed Description

    \n
    template<typename FirstRow, typename... Args>
    \n class Dune::MultiTypeBlockMatrix< FirstRow, Args >

    A Matrix class to support different block types.

    \n

    This matrix class combines MultiTypeBlockVector elements as rows.

    \n

    The documentation for this class was generated from the following files:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01216.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01216.html", "unified_diff": "@@ -77,15 +77,15 @@\n
    Dune::BTDMatrix< B, A > Class Template Reference
    \n
    \n
    \n \n

    A block-tridiagonal matrix. \n More...

    \n \n-

    #include <dune/istl/btdmatrix.hh>

    \n+

    #include <dune/istl/btdmatrix.hh>

    \n
    \n Inheritance diagram for Dune::BTDMatrix< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -3159,15 +3159,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01220.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01220.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< BTDMatrix< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/btdmatrix.hh>

    \n+

    #include <dune/istl/btdmatrix.hh>

    \n \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    using field_type = typename BTDMatrix< B, A >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01244.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01244.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::BlockVector< B, A > Class Template Reference
    \n \n
    \n \n

    A vector of blocks with memory management. \n More...

    \n \n-

    #include <dune/istl/bvector.hh>

    \n+

    #include <dune/istl/bvector.hh>

    \n
    \n Inheritance diagram for Dune::BlockVector< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -722,15 +722,15 @@\n
    \n \n

    increment block level counter

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01248.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01248.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< BlockVector< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/bvector.hh>

    \n+

    #include <dune/istl/bvector.hh>

    \n \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    typedef FieldTraits< B >::field_type field_type
     
    typedef FieldTraits< B >::real_type real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01280.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01280.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::ArPackPlusPlus_Algorithms< BCRSMatrix, BlockVector > Class Template Reference
    \n \n
    \n \n

    Wrapper to use a range of ARPACK++ eigenvalue solvers. \n More...

    \n \n-

    #include <dune/istl/eigenvalue/arpackpp.hh>

    \n+

    #include <dune/istl/eigenvalue/arpackpp.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BlockVector::field_type Real
     
    \n \n

    \n@@ -708,15 +708,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01292.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01292.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::PowerIteration_Algorithms< BCRSMatrix, BlockVector > Class Template Reference
    \n \n
    \n \n

    Iterative eigenvalue algorithms based on power iteration. \n More...

    \n \n-

    #include <dune/istl/eigenvalue/poweriteration.hh>

    \n+

    #include <dune/istl/eigenvalue/poweriteration.hh>

    \n \n \n \n \n \n \n@@ -1196,15 +1196,15 @@\n \n

    \n Public Types

    typedef BlockVector::field_type Real
     Type of underlying field. More...
     
    typedef OperatorSum IterationOperator
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01312.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01312.html", "unified_diff": "@@ -72,15 +72,15 @@\n \n \n
    \n \n

    compile-time parameter for block recursion depth \n More...

    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { recursion_level = l\n }
     
    \n@@ -104,15 +104,15 @@\n \n \n
    Enumerator
    recursion_level 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01316.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01316.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::algmeta_btsolve< I, diag, relax > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -186,15 +186,15 @@\n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bltsolve (const M &A, X &v, const Y &d, const K &w)
     
    template<class M , class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01320.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01320.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::algmeta_btsolve< 0, withdiag, withrelax > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -182,15 +182,15 @@\n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bltsolve (const M &A, X &v, const Y &d, const K &w)
     
    template<class M , class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01324.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01324.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -182,15 +182,15 @@\n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bltsolve (const M &A, X &v, const Y &d, const K &)
     
    template<class M , class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01328.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01328.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -182,15 +182,15 @@\n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bltsolve (const M &, X &v, const Y &d, const K &w)
     
    template<class M , class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01332.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01332.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -182,15 +182,15 @@\n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bltsolve (const M &, X &v, const Y &d, const K &)
     
    template<class M , class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01336.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01336.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bdsolve (const M &A, X &v, const Y &d, const K &w)
     
    \n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01340.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01340.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bdsolve (const M &A, X &v, const Y &d, const K &w)
     
    \n@@ -129,15 +129,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01344.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01344.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class M , class X , class Y , class K >
    static void bdsolve (const M &A, X &v, const Y &d, const K &)
     
    \n@@ -129,15 +129,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01348.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01348.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -296,15 +296,15 @@\n \n

    \n Static Public Member Functions

    template<class X , class Y , class K >
    static void dbgs (const M &A, X &x, const Y &b, const K &w)
     
    template<class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01352.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01352.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -296,15 +296,15 @@\n \n

    \n Static Public Member Functions

    template<class X , class Y , class K >
    static void dbgs (const M &A, X &x, const Y &b, const K &)
     
    template<class X , class Y , class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01356.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01356.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::algmeta_itsteps< I, MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/gsetc.hh>

    \n+

    #include <dune/istl/gsetc.hh>

    \n \n \n \n \n \n \n@@ -296,15 +296,15 @@\n \n

    \n Static Public Member Functions

    template<typename... MultiTypeVectorArgs, class K >
    static void dbgs (const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
     
    template<typename... MultiTypeVectorArgs, class K >
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01360.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01360.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::ILU::CRS< B, Alloc > Struct Template Reference
    \n \n
    \n \n

    a simple compressed row storage matrix class \n More...

    \n \n-

    #include <dune/istl/ilu.hh>

    \n+

    #include <dune/istl/ilu.hh>

    \n
    \n Inheritance diagram for Dune::ILU::CRS< B, Alloc >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -397,15 +397,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01364.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01364.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::ILUSubdomainSolver< M, X, Y > Class Template Referenceabstract
    \n \n
    \n \n

    base class encapsulating common algorithms of ILU0SubdomainSolver and ILUNSubdomainSolver. \n More...

    \n \n-

    #include <dune/istl/ilusubdomainsolver.hh>

    \n+

    #include <dune/istl/ilusubdomainsolver.hh>

    \n
    \n Inheritance diagram for Dune::ILUSubdomainSolver< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -286,15 +286,15 @@\n
    \n \n

    The ILU0 decomposition of the matrix, or the local matrix.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01368.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01368.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::ILU0SubdomainSolver< M, X, Y > Class Template Reference
    \n \n
    \n \n

    Exact subdomain solver using ILU(p) with appropriate p. \n More...

    \n \n-

    #include <dune/istl/ilusubdomainsolver.hh>

    \n+

    #include <dune/istl/ilusubdomainsolver.hh>

    \n
    \n Inheritance diagram for Dune::ILU0SubdomainSolver< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -278,15 +278,15 @@\n
    \n \n

    The ILU0 decomposition of the matrix, or the local matrix.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01372.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01372.html", "unified_diff": "@@ -72,15 +72,15 @@\n Protected Member Functions |\n Protected Attributes |\n List of all members \n
    Dune::ILUNSubdomainSolver< M, X, Y > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/ilusubdomainsolver.hh>

    \n+

    #include <dune/istl/ilusubdomainsolver.hh>

    \n
    \n Inheritance diagram for Dune::ILUNSubdomainSolver< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -264,15 +264,15 @@\n
    \n \n

    The ILU0 decomposition of the matrix, or the local matrix.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01388.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01388.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n \n
    \n \n

    Default options class to write SVG matrices. \n More...

    \n \n-

    #include <dune/istl/io.hh>

    \n+

    #include <dune/istl/io.hh>

    \n \n \n \n \n \n \n@@ -440,15 +440,15 @@\n
    \n \n

    Whether to write the SVG header.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01392.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01392.html", "unified_diff": "@@ -69,15 +69,15 @@\n
    Dune::ISTLError Class Reference
    \n \n
    \n \n

    derive error class from the base class in common \n More...

    \n \n-

    #include <dune/istl/istlexception.hh>

    \n+

    #include <dune/istl/istlexception.hh>

    \n
    \n Inheritance diagram for Dune::ISTLError:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -85,15 +85,15 @@\n \"\"\n \"\"\n \n
    \n

    Detailed Description

    \n

    derive error class from the base class in common

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01396.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01396.html", "unified_diff": "@@ -69,30 +69,30 @@\n
    Dune::BCRSMatrixError Class Reference
    \n \n
    \n \n

    Error specific to BCRSMatrix. \n More...

    \n \n-

    #include <dune/istl/istlexception.hh>

    \n+

    #include <dune/istl/istlexception.hh>

    \n
    \n Inheritance diagram for Dune::BCRSMatrixError:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \"\"\n \"\"\n \n
    \n

    Detailed Description

    \n

    Error specific to BCRSMatrix.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01400.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01400.html", "unified_diff": "@@ -69,15 +69,15 @@\n
    Dune::ImplicitModeCompressionBufferExhausted Class Reference
    \n \n
    \n \n

    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted. \n More...

    \n \n-

    #include <dune/istl/istlexception.hh>

    \n+

    #include <dune/istl/istlexception.hh>

    \n
    \n Inheritance diagram for Dune::ImplicitModeCompressionBufferExhausted:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -86,15 +86,15 @@\n \n
    \n

    Detailed Description

    \n

    Thrown when the compression buffer used by the implicit BCRSMatrix construction is exhausted.

    \n

    This error occurs if the compression buffer of the BCRSMatrix did not have room for another non-zero entry during implicit mode construction.

    \n

    You can fix this problem by either increasing the average row size or the compressionBufferSize value.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01404.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01404.html", "unified_diff": "@@ -69,30 +69,30 @@\n
    Dune::SolverAbort Class Reference
    \n \n
    \n \n

    Thrown when a solver aborts due to some problem. \n More...

    \n \n-

    #include <dune/istl/istlexception.hh>

    \n+

    #include <dune/istl/istlexception.hh>

    \n
    \n Inheritance diagram for Dune::SolverAbort:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \"\"\n \n
    \n

    Detailed Description

    \n

    Thrown when a solver aborts due to some problem.

    \n

    Problems that may cause the solver to abort include a NaN detected during the convergence check (which may be caused by invalid input data), or breakdown conditions (which can happen e.g. in BiCGSTABSolver or RestartedGMResSolver).

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01408.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01408.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MatrixBlockError Class Reference
    \n \n
    \n \n

    Error when performing an operation on a matrix block. \n More...

    \n \n-

    #include <dune/istl/istlexception.hh>

    \n+

    #include <dune/istl/istlexception.hh>

    \n
    \n Inheritance diagram for Dune::MatrixBlockError:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -123,15 +123,15 @@\n \n

    \n Public Member Functions

    template<class RowPrefix , class ColPrefix >
    std::string blockStyleClass (const RowPrefix &row_prefix, const ColPrefix &col_prefix) const
     Helper function that returns an style class for a given prefix. More...
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01412.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01412.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqOverlappingSchwarz< M, X, TM, TD, TA > Class Template Reference
    \n \n
    \n \n

    Sequential overlapping Schwarz preconditioner. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::SeqOverlappingSchwarz< M, X, TM, TD, TA >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -584,16 +584,16 @@\n \n \n

    Implements Dune::Preconditioner< X, X >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01416.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01416.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SeqOverlappingSchwarzAssemblerHelper< T, tag > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01420.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01420.html", "unified_diff": "@@ -69,26 +69,26 @@\n
    Dune::LDL< Matrix > Class Template Reference
    \n \n
    \n \n

    Use the LDL package to directly solve linear systems – empty default class. \n More...

    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n

    Detailed Description

    \n
    template<class Matrix>
    \n class Dune::LDL< Matrix >

    Use the LDL package to directly solve linear systems – empty default class.

    \n
    Template Parameters
    \n \n \n
    Matrixthe matrix type defining the system Details on UMFPack can be found on http://www.cise.ufl.edu/research/sparse/ldl/
    \n
    \n
    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01424.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01424.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > Class Template Referenceabstract
    \n \n
    \n \n

    The LDL direct sparse solver for matrices of type BCRSMatrix. \n More...

    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n
    \n Inheritance diagram for Dune::LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -560,15 +560,15 @@\n
    \n \n

    helper function for printing solver output

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01428.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01428.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::IsDirectSolver< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01432.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01432.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::StoresColumnCompressed< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01436.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01436.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Public Member Functions |\n List of all members \n
    Dune::LDLCreator Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n \n \n \n \n \n

    \n Classes

    struct  isValidBlock
     
    struct  isValidBlock< FieldVector< double, k > >
     
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    template<typename TL , typename M >
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &, const Dune::ParameterTree &, std::enable_if_t< !isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01440.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01440.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::LDLCreator::isValidBlock< F > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n
    \n Inheritance diagram for Dune::LDLCreator::isValidBlock< F >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01444.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01444.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::LDLCreator::isValidBlock< FieldVector< double, k > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/ldl.hh>

    \n+

    #include <dune/istl/ldl.hh>

    \n
    \n Inheritance diagram for Dune::LDLCreator::isValidBlock< FieldVector< double, k > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01448.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01448.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::MatrixImp::DenseMatrixBase< B, A > Class Template Reference
    \n \n
    \n \n

    A Vector of blocks with different blocksizes. \n More...

    \n \n-

    #include <dune/istl/matrix.hh>

    \n+

    #include <dune/istl/matrix.hh>

    \n
    \n Inheritance diagram for Dune::MatrixImp::DenseMatrixBase< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -980,15 +980,15 @@\n
    \n \n

    same effect as constructor with same argument

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01452.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01452.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MatrixImp::DenseMatrixBase< B, A >::Iterator Class Reference
    \n \n
    \n \n

    Iterator class for sequential access. \n More...

    \n \n-

    #include <dune/istl/matrix.hh>

    \n+

    #include <dune/istl/matrix.hh>

    \n \n \n \n \n \n \n@@ -579,15 +579,15 @@\n
    \n \n

    equality

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01456.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01456.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MatrixImp::DenseMatrixBase< B, A >::ConstIterator Class Reference
    \n \n
    \n \n

    ConstIterator class for sequential access. \n More...

    \n \n-

    #include <dune/istl/matrix.hh>

    \n+

    #include <dune/istl/matrix.hh>

    \n

    \n Public Member Functions

     Iterator ()
     constructor, no arguments More...
     
     Iterator (Iterator &other)=default
    \n \n \n \n \n \n@@ -546,15 +546,15 @@\n
    \n \n

    equality

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01460.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01460.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::Matrix< T, A > Class Template Reference
    \n \n
    \n \n

    A generic dynamic dense matrix. \n More...

    \n \n-

    #include <dune/istl/matrix.hh>

    \n+

    #include <dune/istl/matrix.hh>

    \n

    \n Public Member Functions

     ConstIterator ()
     constructor More...
     
     ConstIterator (const B *data, size_type columns, size_type _i)
    \n \n \n \n \n \n@@ -1851,15 +1851,15 @@\n
    \n \n

    Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01464.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01464.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< Matrix< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrix.hh>

    \n+

    #include <dune/istl/matrix.hh>

    \n

    \n Public Types

    using field_type = typename Imp::BlockTraits< T >::field_type
     Export the type representing the underlying field. More...
     
    typedef T block_type
    \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    using field_type = typename Matrix< T, A >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01468.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01468.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::MatrixIndexSet Class Reference
    \n \n
    \n \n

    Stores the nonzero entries in a sparse matrix. \n More...

    \n \n-

    #include <dune/istl/matrixindexset.hh>

    \n+

    #include <dune/istl/matrixindexset.hh>

    \n \n \n \n \n

    \n Public Types

    typedef std::size_t size_type
     
    \n \n

    \n@@ -457,15 +457,15 @@\n
    \n \n

    Return the number of entries.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01472.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01472.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MatrixMarketImpl::mm_numeric_type< T > Struct Template Reference
    \n \n
    \n \n

    Helper metaprogram to get the matrix market string representation of the numeric type. \n More...

    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =false\n }
     
    \n@@ -106,15 +106,15 @@\n

    Enumerator
    is_numeric 

    Whether T is a supported numeric type.

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01476.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01476.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_numeric_type< int > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =true\n }
     
    \n@@ -129,15 +129,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01480.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01480.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_numeric_type< double > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =true\n }
     
    \n@@ -129,15 +129,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01484.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01484.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_numeric_type< float > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =true\n }
     
    \n@@ -129,15 +129,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01488.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01488.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_numeric_type< std::complex< double > > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =true\n }
     
    \n@@ -129,15 +129,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01492.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01492.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_numeric_type< std::complex< float > > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_numeric =true\n }
     
    \n@@ -129,15 +129,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01496.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01496.html", "unified_diff": "@@ -79,15 +79,15 @@\n
    Template Parameters
    \n \n \n
    MThe matrix type.
    \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01500.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01500.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_header_printer< BCRSMatrix< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void print (std::ostream &os)
     
    \n

    Member Function Documentation

    \n@@ -106,15 +106,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01504.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01504.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_header_printer< BlockVector< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void print (std::ostream &os)
     
    \n

    Member Function Documentation

    \n@@ -106,15 +106,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01508.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01508.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_header_printer< FieldVector< T, j > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void print (std::ostream &os)
     
    \n

    Member Function Documentation

    \n@@ -106,15 +106,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01512.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01512.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_header_printer< FieldMatrix< T, i, j > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void print (std::ostream &os)
     
    \n

    Member Function Documentation

    \n@@ -106,15 +106,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01516.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01516.html", "unified_diff": "@@ -78,15 +78,15 @@\n

    Member function mm_block_structure_header::print(os, mat) writes the corresponding header to the specified ostream.

    Template Parameters
    \n \n \n
    Thetype of the matrix to generate the header for.
    \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01520.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01520.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BlockVector< T, A > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01524.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01524.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< BlockVector< FieldVector< T, i >, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BlockVector< FieldVector< T, i >, A > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01528.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01528.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< T, A > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01532.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01532.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< BCRSMatrix< FieldMatrix< T, i, j >, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< FieldMatrix< T, i, j >, A > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01536.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01536.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< FieldMatrix< T, i, j > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef FieldMatrix< T, i, j > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01540.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01540.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixMarketImpl::mm_block_structure_header< FieldVector< T, i > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Types

    typedef FieldVector< T, i > M
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01544.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01544.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::MatrixMarketImpl::MMHeader Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Member Functions

     MMHeader ()
     
    \n \n

    \n@@ -156,15 +156,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01548.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01548.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::IndexData< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    \n Inheritance diagram for Dune::MatrixMarketImpl::IndexData< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -103,15 +103,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01552.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01552.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::MatrixMarketImpl::NumericWrapper< T > Struct Template Reference
    \n \n
    \n \n

    a wrapper class of numeric values. \n More...

    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n

    \n Public Member Functions

     operator T& ()
     
    \n \n

    \n@@ -141,15 +141,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01556.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01556.html", "unified_diff": "@@ -69,19 +69,19 @@\n
    Dune::MatrixMarketImpl::PatternDummy Struct Reference
    \n \n
    \n \n

    Utility class for marking the pattern type of the MatrixMarket matrices. \n More...

    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n

    Detailed Description

    \n

    Utility class for marking the pattern type of the MatrixMarket matrices.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01560.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01560.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::MatrixMarketImpl::NumericWrapper< PatternDummy > Struct Reference
    \n
    \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01564.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01564.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MatrixMarketImpl::MatrixValuesSetter< D, brows, bcols > Struct Template Reference
    \n \n
    \n \n

    Functor to the data values of the matrix. \n More...

    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n \n \n@@ -189,15 +189,15 @@\n

    \n Public Member Functions

    template<typename T >
    void operator() (const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< T > &matrix)
     Sets the matrix values. More...
     
    \n \n \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01568.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01568.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::MatrixValuesSetter< PatternDummy, brows, bcols > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n \n

    \n Public Member Functions

    template<typename M >
    void operator() (const std::vector< std::set< IndexData< PatternDummy > > > &rows, M &matrix)
     
    \n@@ -119,15 +119,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01572.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01572.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::MatrixMarketImpl::is_complex< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    \n Inheritance diagram for Dune::MatrixMarketImpl::is_complex< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01576.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01576.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::MatrixMarketImpl::is_complex< std::complex< T > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    \n Inheritance diagram for Dune::MatrixMarketImpl::is_complex< std::complex< T > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01580.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01580.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::MatrixMarketImpl::mm_multipliers< M > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01584.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01584.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< B, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n@@ -100,15 +100,15 @@\n \n \n

    \n Public Types

    enum  { rows = 1\n , cols = 1\n }
     
    Enumerator
    rows 
    cols 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01588.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01588.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MatrixMarketImpl::mm_multipliers< BCRSMatrix< FieldMatrix< B, i, j >, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n \n \n \n \n@@ -100,15 +100,15 @@\n \n \n

    \n Public Types

    enum  { rows = i\n , cols = j\n }
     
    Enumerator
    rows 
    cols 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01592.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01592.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n \n
    \n \n-

    #include <dune/istl/matrixmarket.hh>

    \n+

    #include <dune/istl/matrixmarket.hh>

    \n
    \n Inheritance diagram for Dune::MatrixMarketFormatError:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01664.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01664.html", "unified_diff": "@@ -69,27 +69,27 @@\n
    Dune::MatMultMatResult< M1, M2 > Struct Template Reference
    \n \n
    \n \n

    Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") \n More...

    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n

    Detailed Description

    \n
    template<typename M1, typename M2>
    \n struct Dune::MatMultMatResult< M1, M2 >

    Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\")

    \n

    The type of matrix C will be stored as the associated type MatMultMatResult::type.

    Template Parameters
    \n \n \n \n
    M1The type of matrix A.
    M2The type of matrix B.
    \n
    \n
    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01668.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01668.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n \n \n \n \n

    \n Public Types

    typedef FieldMatrix< T, n, m > type
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01672.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01672.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::MatMultMatResult< BCRSMatrix< FieldMatrix< T, n, k >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01676.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01676.html", "unified_diff": "@@ -69,27 +69,27 @@\n
    Dune::TransposedMatMultMatResult< M1, M2 > Struct Template Reference
    \n \n
    \n \n

    Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\") \n More...

    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n

    Detailed Description

    \n
    template<typename M1, typename M2>
    \n struct Dune::TransposedMatMultMatResult< M1, M2 >

    Helper TMP to get the result type of a sparse matrix matrix multiplication ( \"$C=A*B$\")

    \n

    The type of matrix C will be stored as the associated type MatMultMatResult::type.

    Template Parameters
    \n \n \n \n
    M1The type of matrix A.
    M2The type of matrix B.
    \n
    \n
    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01680.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01680.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::TransposedMatMultMatResult< FieldMatrix< T, k, n >, FieldMatrix< T, k, m > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n \n \n \n \n

    \n Public Types

    typedef FieldMatrix< T, n, m > type
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01684.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01684.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::TransposedMatMultMatResult< BCRSMatrix< FieldMatrix< T, k, n >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixmatrix.hh>

    \n+

    #include <dune/istl/matrixmatrix.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type, std::allocator< typename MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >::type > > type
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01688.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01688.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::RedistributeInformation< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -400,15 +400,15 @@\n \n

    \n Public Member Functions

    bool isSetup () const
     
    template<class D >
    void redistribute (const D &from, D &to) const
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01692.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01692.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::RedistributeInformation< OwnerOverlapCopyCommunication< T, T1 > > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n

    \n Public Types

    typedef OwnerOverlapCopyCommunication< T, T1 > Comm
     
    \n \n

    \n@@ -766,15 +766,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01696.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01696.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::CommMatrixRowSize< M, RI > Struct Template Reference
    \n \n
    \n \n

    Utility class to communicate and set the row sizes of a redistributed matrix. \n More...

    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -221,15 +221,15 @@\n \n

    \n Public Types

    typedef M::size_type value_type
     
    typedef M::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01700.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01700.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::CommMatrixSparsityPattern< M, I > Struct Template Reference
    \n \n
    \n \n

    Utility class to communicate and build the sparsity pattern of a redistributed matrix. \n More...

    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -425,15 +425,15 @@\n \n

    \n Public Types

    typedef M::size_type size_type
     
    typedef Dune::GlobalLookupIndexSet< I > LookupIndexSet
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01704.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01704.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::CommPolicy< CommMatrixSparsityPattern< M, I > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -181,15 +181,15 @@\n \n

    \n Public Types

    typedef CommMatrixSparsityPattern< M, I > Type
     
    typedef I::GlobalIndex IndexedType
     The indexed type we send. This is the global index indentitfying the column. More...
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01708.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01708.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::CommMatrixRow< M, I > Struct Template Reference
    \n \n
    \n \n

    Utility class for comunicating the matrix entries. \n More...

    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -324,15 +324,15 @@\n
    \n \n

    row size information for the receiving side.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01712.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01712.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members\n
    Dune::CommPolicy< CommMatrixRow< M, I > > Struct Template Reference
    \n \n

    \n Public Member Functions

     CommMatrixRow (M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_)
     Constructor. More...
     
     CommMatrixRow (M &m_, const Dune::GlobalLookupIndexSet< I > &idxset_, const I &aggidxset_, std::vector< size_t > &rowsize_)
    \n \n \n \n \n \n@@ -181,15 +181,15 @@\n \n

    \n Public Types

    typedef CommMatrixRow< M, I > Type
     
    typedef std::pair< typename I::GlobalIndex, typename M::block_type > IndexedType
     The indexed type we send. This is the pair of global index indentitfying the column and the value itself. More...
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01716.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01716.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixRowSizeGatherScatter< M, I, RI > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n

    \n Public Types

    typedef CommMatrixRowSize< M, RI > Container
     
    \n \n

    \n@@ -185,15 +185,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01720.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01720.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixCopyRowSizeGatherScatter< M, I, RI > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n

    \n Public Types

    typedef CommMatrixRowSize< M, RI > Container
     
    \n \n

    \n@@ -185,15 +185,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01724.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01724.html", "unified_diff": "@@ -71,15 +71,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::MatrixSparsityPatternGatherScatter< M, I > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -290,15 +290,15 @@\n \n

    \n Public Types

    typedef I::GlobalIndex GlobalIndex
     
    typedef CommMatrixSparsityPattern< M, I > Container
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01728.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01728.html", "unified_diff": "@@ -71,15 +71,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::MatrixRowGatherScatter< M, I > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixredistribute.hh>

    \n+

    #include <dune/istl/matrixredistribute.hh>

    \n \n \n \n \n \n \n@@ -334,15 +334,15 @@\n \n

    \n Public Types

    typedef I::GlobalIndex GlobalIndex
     
    typedef CommMatrixRow< M, I > Container
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01732.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01732.html", "unified_diff": "@@ -66,15 +66,15 @@\n \n \n
    \n
    Dune::FieldMatrix< K, n, m > Class Template Reference
    \n
    \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01736.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01736.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::CheckIfDiagonalPresent< Matrix, blocklevel, l > Struct Template Reference
    \n \n
    \n \n

    Check whether the a matrix has diagonal values on blocklevel recursion levels. \n More...

    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    static void check (const Matrix &mat)
     Check whether the a matrix has diagonal values on blocklevel recursion levels. More...
     
    \n@@ -115,15 +115,15 @@\n
    \n \n

    Check whether the a matrix has diagonal values on blocklevel recursion levels.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01740.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01740.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::CheckIfDiagonalPresent< Matrix, 0, l > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void check (const Matrix &mat)
     
    \n

    Member Function Documentation

    \n@@ -106,15 +106,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01744.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01744.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::CheckIfDiagonalPresent< MultiTypeBlockMatrix< T1, Args... >, blocklevel, l > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Public Types

    typedef MultiTypeBlockMatrix< T1, Args... > Matrix
     
    \n \n

    \n@@ -132,15 +132,15 @@\n
    \n \n

    Check whether the a matrix has diagonal values on blocklevel recursion levels.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01752.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01752.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< Matrix< B, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    using block_type = typename Matrix< B, TA >::block_type
     
    using size_type = typename Matrix< B, TA >::size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01756.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01756.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< BCRSMatrix< B, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -275,15 +275,15 @@\n \n

    \n Public Types

    typedef BCRSMatrix< B, TA > Matrix
     
    typedef Matrix::block_type block_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01760.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01760.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< BCRSMatrix< FieldMatrix< B, n, m >, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix
     
    typedef Matrix::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01764.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01764.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< FieldMatrix< K, n, m > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef FieldMatrix< K, n, m > Matrix
     
    typedef Matrix::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01768.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01768.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< Dune::DynamicMatrix< T > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef Dune::DynamicMatrix< T > MatrixType
     
    typedef MatrixType::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01772.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01772.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< Matrix< FieldMatrix< K, n, m >, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix
     
    typedef ThisMatrix::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01776.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01776.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< DiagonalMatrix< K, n > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef DiagonalMatrix< K, n > Matrix
     
    typedef Matrix::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01780.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01780.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::MatrixDimension< ScaledIdentityMatrix< K, n > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n \n \n@@ -257,15 +257,15 @@\n \n

    \n Public Types

    typedef ScaledIdentityMatrix< K, n > Matrix
     
    typedef Matrix::size_type size_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01784.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01784.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::IsMatrix< T > Struct Template Reference
    \n \n
    \n \n

    Test whether a type is an ISTL Matrix. \n More...

    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = false\n }
     
    \n@@ -105,15 +105,15 @@\n

    Enumerator
    value 

    True if T is an ISTL matrix.

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01788.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01788.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::IsMatrix< DenseMatrix< T > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n@@ -99,15 +99,15 @@\n Enumeratorvalue 

    True if T is an ISTL matrix.

    \n \n \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01792.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01792.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::IsMatrix< BCRSMatrix< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n@@ -99,15 +99,15 @@\n Enumeratorvalue 

    True if T is an ISTL matrix.

    \n \n \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01796.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01796.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::PointerCompare< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/matrixutils.hh>

    \n+

    #include <dune/istl/matrixutils.hh>

    \n \n \n \n \n

    \n Public Member Functions

    bool operator() (const T *l, const T *r)
     
    \n

    Member Function Documentation

    \n@@ -116,15 +116,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01800.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01800.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::MultiTypeBlockMatrix_Solver< I, crow, remain_row > Class Template Reference
    \n \n
    \n \n

    solver for MultiTypeBlockVector & MultiTypeBlockMatrix types \n More...

    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n \n \n \n \n \n \n@@ -106,15 +106,15 @@\n \n

    \n Static Public Member Functions

    template<typename TVector , typename TMatrix , typename K >
    static void dbgs (const TMatrix &A, TVector &x, const TVector &b, const K &w)
     
    template<typename TVector , typename TMatrix , typename K >
     
    \n

    Detailed Description

    \n
    template<int I, int crow, int remain_row>
    \n class Dune::MultiTypeBlockMatrix_Solver< I, crow, remain_row >

    solver for MultiTypeBlockVector & MultiTypeBlockMatrix types

    \n

    The methods of this class are called by the solver specializations for MultiTypeBlockVector & MultiTypeBlockMatrix types (dbgs, bsorf, bsorb, dbjac).

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01804.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01804.html", "unified_diff": "@@ -72,28 +72,28 @@\n
    Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, remain_col > Class Template Reference
    \n \n
    \n \n

    part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types \n More...

    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename Trhs , typename TVector , typename TMatrix , typename K >
    static void calc_rhs (const TMatrix &A, TVector &x, TVector &v, Trhs &b, const K &w)
     
    \n

    Detailed Description

    \n
    template<int I, int crow, int ccol, int remain_col>
    \n class Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, remain_col >

    part of solvers for MultiTypeBlockVector & MultiTypeBlockMatrix types

    \n

    For the given row (index \"crow\") each element is used to calculate the equation's right side.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01808.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01808.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, 0 > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename Trhs , typename TVector , typename TMatrix , typename K >
    static void calc_rhs (const TMatrix &, TVector &, TVector &, Trhs &, const K &)
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01812.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01812.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::MultiTypeBlockMatrix_Solver< I, crow, 0 > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n \n \n \n \n \n \n@@ -87,15 +87,15 @@\n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename TVector , typename TMatrix , typename K >
    static void dbgs (const TMatrix &, TVector &, TVector &, const TVector &, const K &)
     
    template<typename TVector , typename TMatrix , typename K >
    static void bsorb (const TMatrix &, TVector &, TVector &, const TVector &, const K &)
     
    template<typename TVector , typename TMatrix , typename K >
    static void dbjac (const TMatrix &, TVector &, TVector &, const TVector &, const K &)
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01816.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01816.html", "unified_diff": "@@ -72,27 +72,27 @@\n
    std::tuple_element< i, Dune::MultiTypeBlockMatrix< Args... > > Struct Template Reference
    \n \n
    \n \n

    Make std::tuple_element work for MultiTypeBlockMatrix. \n More...

    \n \n-

    #include <dune/istl/multitypeblockmatrix.hh>

    \n+

    #include <dune/istl/multitypeblockmatrix.hh>

    \n \n \n \n \n

    \n Public Types

    using type = typename std::tuple_element< i, std::tuple< Args... > >::type
     
    \n

    Detailed Description

    \n
    template<size_t i, typename... Args>
    \n struct std::tuple_element< i, Dune::MultiTypeBlockMatrix< Args... > >

    Make std::tuple_element work for MultiTypeBlockMatrix.

    \n

    It derives from std::tuple after all.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01820.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01820.html", "unified_diff": "@@ -69,25 +69,25 @@\n \n
    Dune::FieldTraits< MultiTypeBlockVector< Args... > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/multitypeblockvector.hh>

    \n+

    #include <dune/istl/multitypeblockvector.hh>

    \n \n \n \n \n \n \n

    \n Public Types

    using field_type = typename MultiTypeBlockVector< Args... >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01824.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01824.html", "unified_diff": "@@ -72,27 +72,27 @@\n
    std::tuple_element< i, Dune::MultiTypeBlockVector< Args... > > Struct Template Reference
    \n \n
    \n \n

    Make std::tuple_element work for MultiTypeBlockVector. \n More...

    \n \n-

    #include <dune/istl/multitypeblockvector.hh>

    \n+

    #include <dune/istl/multitypeblockvector.hh>

    \n \n \n \n \n

    \n Public Types

    using type = typename std::tuple_element< i, std::tuple< Args... > >::type
     
    \n

    Detailed Description

    \n
    template<size_t i, typename... Args>
    \n struct std::tuple_element< i, Dune::MultiTypeBlockVector< Args... > >

    Make std::tuple_element work for MultiTypeBlockVector.

    \n

    It derives from std::tuple after all.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01828.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01828.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::NonoverlappingSchwarzOperator< M, X, Y, C > Class Template Reference
    \n \n
    \n \n

    A nonoverlapping operator with communication object. \n More...

    \n \n-

    #include <dune/istl/novlpschwarz.hh>

    \n+

    #include <dune/istl/novlpschwarz.hh>

    \n
    \n Inheritance diagram for Dune::NonoverlappingSchwarzOperator< M, X, Y, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -715,15 +715,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01832.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01832.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< T > Struct Template Reference
    \n \n
    \n \n

    Traits class for generically constructing non default constructable types. \n More...

    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n \n

    \n Public Types

    typedef const void * Arguments
     A type holding all the arguments needed to call the constructor. More...
     
    \n@@ -92,16 +92,16 @@\n \n
     
    \n

    Detailed Description

    \n
    template<typename T>
    \n struct Dune::Amg::ConstructionTraits< T >

    Traits class for generically constructing non default constructable types.

    \n

    Needed because BCRSMatrix and Vector do a deep copy which is too expensive.

    \n

    The documentation for this struct was generated from the following files:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01836.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01836.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::NonoverlappingBlockPreconditioner< C, P > Class Template Reference
    \n \n
    \n \n

    Nonoverlapping parallel preconditioner. \n More...

    \n \n-

    #include <dune/istl/novlpschwarz.hh>

    \n+

    #include <dune/istl/novlpschwarz.hh>

    \n
    \n Inheritance diagram for Dune::NonoverlappingBlockPreconditioner< C, P >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -544,15 +544,15 @@\n \n \n

    Implements Dune::Preconditioner< P::domain_type, P::range_type >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01840.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01840.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::LinearOperator< X, Y > Class Template Referenceabstract
    \n \n
    \n \n

    A linear operator. \n More...

    \n \n-

    #include <dune/istl/operators.hh>

    \n+

    #include <dune/istl/operators.hh>

    \n
    \n Inheritance diagram for Dune::LinearOperator< X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -335,15 +335,15 @@\n

    Category of the linear operator (see SolverCategory::Category)

    \n \n

    Implemented in Dune::NonoverlappingSchwarzOperator< M, X, Y, C >, Dune::OverlappingSchwarzOperator< M, X, Y, C >, and Dune::MatrixAdapter< M, X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01844.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01844.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::AssembledLinearOperator< M, X, Y > Class Template Referenceabstract
    \n \n
    \n \n

    A linear operator exporting itself in matrix form. \n More...

    \n \n-

    #include <dune/istl/operators.hh>

    \n+

    #include <dune/istl/operators.hh>

    \n
    \n Inheritance diagram for Dune::AssembledLinearOperator< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -372,15 +372,15 @@\n

    get matrix via *

    \n \n

    Implemented in Dune::NonoverlappingSchwarzOperator< M, X, Y, C >, Dune::OverlappingSchwarzOperator< M, X, Y, C >, and Dune::MatrixAdapter< M, X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01848.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01848.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::MatrixAdapter< M, X, Y > Class Template Reference
    \n \n
    \n \n

    Adapter to turn a matrix into a linear operator. \n More...

    \n \n-

    #include <dune/istl/operators.hh>

    \n+

    #include <dune/istl/operators.hh>

    \n
    \n Inheritance diagram for Dune::MatrixAdapter< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -404,15 +404,15 @@\n

    get matrix via *

    \n \n

    Implements Dune::AssembledLinearOperator< M, X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01856.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01856.html", "unified_diff": "@@ -69,19 +69,19 @@\n
    Dune::AdditiveSchwarzMode Struct Reference
    \n \n
    \n \n

    Tag that the tells the Schwarz method to be additive. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n

    Detailed Description

    \n

    Tag that the tells the Schwarz method to be additive.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01860.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01860.html", "unified_diff": "@@ -69,19 +69,19 @@\n
    Dune::MultiplicativeSchwarzMode Struct Reference
    \n \n
    \n \n

    Tag that tells the Schwarz method to be multiplicative. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n

    Detailed Description

    \n

    Tag that tells the Schwarz method to be multiplicative.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01864.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01864.html", "unified_diff": "@@ -69,19 +69,19 @@\n
    Dune::SymmetricMultiplicativeSchwarzMode Struct Reference
    \n \n
    \n \n

    Tag that tells the Schwarz method to be multiplicative and symmetric. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n

    Detailed Description

    \n

    Tag that tells the Schwarz method to be multiplicative and symmetric.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01868.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01868.html", "unified_diff": "@@ -78,15 +78,15 @@\n
    Template Parameters
    \n \n \n
    MThe type of the matrix.
    \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01872.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01872.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -315,15 +315,15 @@\n \n

    \n Public Types

    typedef std::remove_const< M >::type matrix_type
     The matrix type the preconditioner is for. More...
     
    typedef X::field_type field_type
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01876.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01876.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::OverlappingAssignerHelper< T, tag > Class Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingAssignerHelper< T, tag >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01880.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01880.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -225,15 +225,15 @@\n \n

    \n Public Types

    typedef BCRSMatrix< K, Al > matrix_type
     
    typedef X::field_type field_type
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01884.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01884.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::OverlappingAssignerHelper< S< BCRSMatrix< T, A > >, true > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -250,15 +250,15 @@\n \n

    \n Public Types

    typedef BCRSMatrix< T, A > matrix_type
     
    typedef S< BCRSMatrix< T, A > >::range_type range_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01888.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01888.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::OverlappingAssignerILUBase< M, X, Y > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingAssignerILUBase< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -186,15 +186,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01892.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01892.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::OverlappingAssignerHelper< ILU0SubdomainSolver< M, X, Y >, false > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingAssignerHelper< ILU0SubdomainSolver< M, X, Y >, false >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -279,15 +279,15 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01896.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01896.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::OverlappingAssignerHelper< ILUNSubdomainSolver< M, X, Y >, false > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingAssignerHelper< ILUNSubdomainSolver< M, X, Y >, false >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -279,15 +279,15 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01900.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01900.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::AdditiveAdder< S, T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01904.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01904.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::AdditiveAdder< S, BlockVector< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -153,15 +153,15 @@\n \n

    \n Public Types

    typedef A::size_type size_type
     
    typedef std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01908.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01908.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::MultiplicativeAdder< S, T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01912.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01912.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::MultiplicativeAdder< S, BlockVector< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -153,15 +153,15 @@\n \n

    \n Public Types

    typedef A::size_type size_type
     
    typedef std::decay_t< decltype(Impl::asVector(std::declval< T >()))>::field_type field_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01916.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01916.html", "unified_diff": "@@ -69,28 +69,28 @@\n
    Dune::AdderSelector< T, X, S > Struct Template Reference
    \n \n
    \n \n

    template meta program for choosing how to add the correction. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n

    Detailed Description

    \n
    template<typename T, class X, class S>
    \n struct Dune::AdderSelector< T, X, S >

    template meta program for choosing how to add the correction.

    \n

    There are specialization for the additive, the multiplicative, and the symmetric multiplicative mode.

    \n
    Template Parameters
    \n \n \n \n
    TThe Schwarz mode (either AdditiveSchwarzMode or MuliplicativeSchwarzMode or SymmetricMultiplicativeSchwarzMode)
    XThe vector field type
    \n
    \n
    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01920.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01920.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::AdderSelector< AdditiveSchwarzMode, X, S > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n

    \n Public Types

    typedef AdditiveAdder< S, X > Adder
     
    \n

    Member Typedef Documentation

    \n@@ -94,15 +94,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01924.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01924.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::AdderSelector< MultiplicativeSchwarzMode, X, S > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n

    \n Public Types

    typedef MultiplicativeAdder< S, X > Adder
     
    \n

    Member Typedef Documentation

    \n@@ -94,15 +94,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01928.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01928.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::AdderSelector< SymmetricMultiplicativeSchwarzMode, X, S > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n

    \n Public Types

    typedef MultiplicativeAdder< S, X > Adder
     
    \n

    Member Typedef Documentation

    \n@@ -94,15 +94,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01932.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01932.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::IteratorDirectionSelector< T1, T2, forward > Struct Template Reference
    \n \n
    \n \n

    Helper template meta program for application of overlapping Schwarz. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -288,15 +288,15 @@\n \n

    \n Public Types

    typedef T1 solver_vector
     
    typedef solver_vector::iterator solver_iterator
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01936.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01936.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::IteratorDirectionSelector< T1, T2, false > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -273,15 +273,15 @@\n \n

    \n Public Types

    typedef T1 solver_vector
     
    typedef solver_vector::reverse_iterator solver_iterator
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01940.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01940.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqOverlappingSchwarzApplier< T > Struct Template Reference
    \n \n
    \n \n

    Helper template meta program for application of overlapping Schwarz. \n More...

    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -175,15 +175,15 @@\n \n

    \n Public Types

    typedef T smoother
     
    typedef smoother::range_type range_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01944.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01944.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::SeqOverlappingSchwarzApplier< SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n \n@@ -163,15 +163,15 @@\n \n

    \n Public Types

    typedef SeqOverlappingSchwarz< M, X, SymmetricMultiplicativeSchwarzMode, TD, TA > smoother
     
    typedef smoother::range_type range_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01948.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01948.html", "unified_diff": "@@ -71,15 +71,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::SeqOverlappingSchwarzAssemblerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< K, Al > matrix_type
     
    \n \n

    \n@@ -132,15 +132,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01952.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01952.html", "unified_diff": "@@ -71,15 +71,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::SeqOverlappingSchwarzAssemblerHelper< S< BCRSMatrix< T, A > >, true > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n

    \n Public Types

    typedef BCRSMatrix< T, A > matrix_type
     
    \n \n

    \n@@ -132,15 +132,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01956.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01956.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::SeqOverlappingSchwarzAssemblerILUBase< M, X, Y > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::SeqOverlappingSchwarzAssemblerILUBase< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -111,15 +111,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01960.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01960.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::SeqOverlappingSchwarzAssemblerHelper< ILU0SubdomainSolver< M, X, Y >, false > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::SeqOverlappingSchwarzAssemblerHelper< ILU0SubdomainSolver< M, X, Y >, false >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -118,15 +118,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01964.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01964.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::SeqOverlappingSchwarzAssemblerHelper< ILUNSubdomainSolver< M, X, Y >, false > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n
    \n Inheritance diagram for Dune::SeqOverlappingSchwarzAssemblerHelper< ILUNSubdomainSolver< M, X, Y >, false >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -118,15 +118,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01968.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01968.html", "unified_diff": "@@ -66,21 +66,21 @@\n \n \n
    \n
    Dune::SeqOverlappingSchwarzDomainSize< M > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n

    Detailed Description

    \n
    template<class M>
    \n struct Dune::SeqOverlappingSchwarzDomainSize< M >

    template helper struct to determine the size of a domain for the SeqOverlappingSchwarz solver

    \n

    only implemented for BCRSMatrix<T>

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01972.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01972.html", "unified_diff": "@@ -70,15 +70,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::SeqOverlappingSchwarzDomainSize< BCRSMatrix< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/overlappingschwarz.hh>

    \n+

    #include <dune/istl/overlappingschwarz.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class Domain >
    static int size (const Domain &d)
     
    \n@@ -166,15 +166,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01976.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01976.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::OwnerOverlapCopyAttributeSet Struct Reference
    \n \n
    \n \n

    Attribute set for overlapping Schwarz. \n More...

    \n \n-

    #include <dune/istl/owneroverlapcopy.hh>

    \n+

    #include <dune/istl/owneroverlapcopy.hh>

    \n \n \n \n@@ -105,15 +105,15 @@\n \n \n

    \n Public Types

    enum  AttributeSet { owner =1\n , overlap =2\n , copy =3\n }
    overlap 
    copy 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01980.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01980.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::IndexInfoFromGrid< G, L > Class Template Reference
    \n \n
    \n \n

    Information about the index distribution. \n More...

    \n \n-

    #include <dune/istl/owneroverlapcopy.hh>

    \n+

    #include <dune/istl/owneroverlapcopy.hh>

    \n \n \n \n \n \n \n@@ -351,15 +351,15 @@\n \n

    Get the set of remote indices.

    \n
    Returns
    the set of remote indices.
    \n \n \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01984.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01984.html", "unified_diff": "@@ -75,15 +75,15 @@\n \n \n
    \n \n

    A class setting up standard communication for a two-valued attribute set with owner/overlap/copy semantics. \n More...

    \n \n-

    #include <dune/istl/owneroverlapcopy.hh>

    \n+

    #include <dune/istl/owneroverlapcopy.hh>

    \n

    \n Public Types

    typedef G GlobalIdType
     The type of the global index. More...
     
    typedef L LocalIdType
    \n \n \n \n \n \n@@ -1393,15 +1393,15 @@\n \n

    Get the underlying remote indices.

    \n
    Returns
    The underlying remote indices.
    \n \n \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01988.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01988.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::CopyGatherScatter< T > Struct Template Reference
    \n \n
    \n \n

    gather/scatter callback for communcation \n More...

    \n \n-

    #include <dune/istl/owneroverlapcopy.hh>

    \n+

    #include <dune/istl/owneroverlapcopy.hh>

    \n

    \n Classes

    struct  AddGatherScatter
     
    struct  CopyGatherScatter
     gather/scatter callback for communcation More...
    \n \n \n \n

    \n Public Types

    typedef CommPolicy< T >::IndexedType V
     
    \n \n

    \n@@ -198,15 +198,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01992.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01992.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::OwnerOverlapCopyCommunication< GlobalIdType, LocalIdType >::AddGatherScatter< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/owneroverlapcopy.hh>

    \n+

    #include <dune/istl/owneroverlapcopy.hh>

    \n \n \n \n \n

    \n Public Types

    typedef CommPolicy< T >::IndexedType V
     
    \n \n

    \n@@ -191,15 +191,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a01996.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a01996.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::AggregationCriterion< T > Class Template Reference
    \n \n
    \n \n

    Base class of all aggregation criterions. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::AggregationCriterion< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -112,15 +112,15 @@\n  Sets reasonable default values for an aisotropic problem. More...
    \n  \n \n

    Detailed Description

    \n
    template<class T>
    \n class Dune::Amg::AggregationCriterion< T >

    Base class of all aggregation criterions.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02000.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02000.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::Amg::SymmetricMatrixDependency< M, N > Class Template Reference
    \n
    \n
    \n \n

    Dependency policy for symmetric matrices. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SymmetricMatrixDependency< M, N >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -273,15 +273,15 @@\n \n \n \n
    MThe type of the matrix
    NThe type of the metric that turns matrix blocks into field values
    \n \n \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02004.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02004.html", "unified_diff": "@@ -75,15 +75,15 @@\n \n \n
    \n \n

    Dependency policy for symmetric matrices. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Dependency< M, N >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -264,15 +264,15 @@\n  The norm of the current diagonal. More...
    \n  \n \n

    Detailed Description

    \n
    template<class M, class N>
    \n class Dune::Amg::Dependency< M, N >

    Dependency policy for symmetric matrices.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02008.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02008.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::Amg::SymmetricDependency< M, N > Class Template Reference
    \n
    \n
    \n \n

    Dependency policy for symmetric matrices. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SymmetricDependency< M, N >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -264,15 +264,15 @@\n  The norm of the current diagonal. More...
    \n  \n \n

    Detailed Description

    \n
    template<class M, class N>
    \n class Dune::Amg::SymmetricDependency< M, N >

    Dependency policy for symmetric matrices.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02012.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02012.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n
    \n
    \n \n

    Norm that uses only the [N][N] entry of the block to determine couplings. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Diagonal< N >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -106,15 +106,15 @@\n  Compute the norm of a scalar. More...
    \n  \n \n

    Detailed Description

    \n
    template<int N>
    \n class Dune::Amg::Diagonal< N >

    Norm that uses only the [N][N] entry of the block to determine couplings.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02016.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02016.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n
    \n
    \n \n

    Norm that uses only the [0][0] entry of the block to determine couplings. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::FirstDiagonal:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -214,15 +214,15 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02020.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02020.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n \n
    \n \n

    Functor using the row sum (infinity) norm to determine strong couplings. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_sign_preserving = false\n }
     
    \n@@ -92,15 +92,15 @@\n \n \n
     compute the norm of a matrix. More...
     
    \n

    Detailed Description

    \n

    Functor using the row sum (infinity) norm to determine strong couplings.

    \n

    The is proposed by several people for elasticity problems.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02024.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02024.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n \n \n
    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_sign_preserving = false\n }
     
    \n@@ -86,15 +86,15 @@\n Public Member Functions\n \n \n \n \n
    template<class M >
    FieldTraits< typenameM::field_type >::real_type operator() (const M &m) const
     compute the norm of a matrix. More...
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02028.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02028.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n \n \n
    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { is_sign_preserving = false\n }
     
    \n@@ -86,15 +86,15 @@\n Public Member Functions\n \n \n \n \n
    template<class M >
    FieldTraits< typenameM::field_type >::real_type operator() (const M &m) const
     compute the norm of a matrix. More...
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02032.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02032.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::Amg::SymmetricCriterion< M, Norm > Class Template Reference
    \n \n
    \n \n

    Criterion taking advantage of symmetric matrices. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SymmetricCriterion< M, Norm >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -809,15 +809,15 @@\n
    \n \n

    index of the currently evaluated row.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02036.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02036.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::Amg::UnSymmetricCriterion< M, Norm > Class Template Reference
    \n \n
    \n \n

    Criterion suitable for unsymmetric matrices. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::UnSymmetricCriterion< M, Norm >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -810,15 +810,15 @@\n
    \n \n

    index of the currently evaluated row.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02040.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02040.html", "unified_diff": "@@ -74,15 +74,15 @@\n \n \n
    \n \n

    Class for building the aggregates. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n \n \n \n \n \n \n@@ -105,15 +105,15 @@\n \n \n

    \n Public Types

    typedef G MatrixGraph
     The matrix graph type used. More...
     
    typedef MatrixGraph::VertexDescriptor Vertex
     Build the aggregates. More...
     
    \n

    Detailed Description

    \n
    template<class G>
    \n class Dune::Amg::Aggregator< G >

    Class for building the aggregates.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02044.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02044.html", "unified_diff": "@@ -75,15 +75,15 @@\n \n \n
    \n \n

    Class providing information about the mapping of the vertices onto aggregates. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::AggregatesMap< V >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -172,15 +172,15 @@\n  \n \n

    Detailed Description

    \n
    template<class V>
    \n class Dune::Amg::AggregatesMap< V >

    Class providing information about the mapping of the vertices onto aggregates.

    \n

    It is assumed that the vertices are consecutively numbered from 0 to the maximum vertex number.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02048.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02048.html", "unified_diff": "@@ -72,27 +72,27 @@\n
    Dune::Amg::AggregatesMap< V >::DummyEdgeVisitor Class Reference
    \n
    \n
    \n \n

    A Dummy visitor that does nothing for each visited edge. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n \n \n \n \n \n

    \n Public Member Functions

    template<class EdgeIterator >
    void operator() (const EdgeIterator &edge) const
     
    \n

    Detailed Description

    \n
    template<class V>
    \n class Dune::Amg::AggregatesMap< V >::DummyEdgeVisitor

    A Dummy visitor that does nothing for each visited edge.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02052.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02052.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n \n
    \n \n

    A class for temporarily storing the vertices of an aggregate in. \n More...

    \n \n-

    #include <dune/istl/paamg/aggregates.hh>

    \n+

    #include <dune/istl/paamg/aggregates.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Aggregate< G, S >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -145,15 +145,15 @@\n  get an iterator over the vertices of the aggregate. More...
    \n  \n \n

    Detailed Description

    \n
    template<class G, class S>
    \n class Dune::Amg::Aggregate< G, S >

    A class for temporarily storing the vertices of an aggregate in.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02092.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02092.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::KAMG< M, X, S, PI, K, A > Class Template Reference
    \n
    \n
    \n \n

    an algebraic multigrid method using a Krylov-cycle. \n More...

    \n \n-

    #include <dune/istl/paamg/kamg.hh>

    \n+

    #include <dune/istl/paamg/kamg.hh>

    \n
    \n Inheritance diagram for Dune::Amg::KAMG< M, X, S, PI, K, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -472,16 +472,16 @@\n

    Category of the preconditioner (see SolverCategory::Category)

    \n \n

    Implements Dune::Preconditioner< X, X >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02096.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02096.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::KAmgTwoGrid< AMG > Class Template Referenceabstract
    \n \n
    \n \n

    Two grid operator for AMG with Krylov cycle. \n More...

    \n \n-

    #include <dune/istl/paamg/kamg.hh>

    \n+

    #include <dune/istl/paamg/kamg.hh>

    \n
    \n Inheritance diagram for Dune::Amg::KAmgTwoGrid< AMG >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -665,16 +665,16 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02100.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02100.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::AMG< M, X, S, PI, A > Class Template Reference
    \n \n
    \n \n

    Parallel algebraic multigrid based on agglomeration. \n More...

    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n
    \n Inheritance diagram for Dune::Amg::AMG< M, X, S, PI, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -256,15 +256,15 @@\n
    \n \n

    The range type of the preconditioner.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02112.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02112.html", "unified_diff": "@@ -72,15 +72,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::Amg::DirectSolverSelector< Matrix, Vector > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n \n \n \n \n \n \n@@ -110,15 +110,15 @@\n Static Public Attributes\n \n \n \n \n

    \n Classes

    struct  Solver
     
    struct  Solver< M, superlu >
     
    static constexpr SolverType solver
     
    static constexpr bool isDirectSolver = solver != none
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02116.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02116.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, SolverType > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n \n \n \n \n

    \n Public Types

    typedef InverseOperator< Vector, Vector > type
     
    \n \n \n \n \n \n

    \n Static Public Member Functions

    static typecreate (const M &mat, bool verbose, bool reusevector)
     
    static std::string name ()
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02120.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02120.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::DirectSolverSelector< Matrix, Vector >::Solver< M, superlu > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n \n \n \n \n

    \n Public Types

    typedef SuperLU< M > type
     
    \n \n \n \n \n \n

    \n Static Public Member Functions

    static typecreate (const M &mat, bool verbose, bool reusevector)
     
    static std::string name ()
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02124.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02124.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Public Member Functions |\n List of all members \n
    Dune::AMGCreator Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n \n \n \n \n \n \n@@ -101,15 +101,15 @@\n \n \n \n \n \n

    \n Classes

    struct  isValidBlockType
     
    struct  isValidBlockType< FieldMatrix< T, n, m > >
     
    std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL tl, const std::shared_ptr< OP > &op, const Dune::ParameterTree &config, std::enable_if_t< isValidBlockType< typename OP::matrix_type::block_type >::value, int >=0) const
     
    template<typename TL , typename OP >
    std::shared_ptr< Dune::Preconditioner< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const std::shared_ptr< OP > &, const Dune::ParameterTree &, std::enable_if_t<!isValidBlockType< typename OP::matrix_type::block_type >::value, int >=0) const
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02128.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02128.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::AMGCreator::isValidBlockType< class > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n
    \n Inheritance diagram for Dune::AMGCreator::isValidBlockType< class >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02132.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02132.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::AMGCreator::isValidBlockType< FieldMatrix< T, n, m > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/amg.hh>

    \n+

    #include <dune/istl/paamg/amg.hh>

    \n
    \n Inheritance diagram for Dune::AMGCreator::isValidBlockType< FieldMatrix< T, n, m > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02136.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02136.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::ApplyHelper< i > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n+

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class TT , class T >
    static void apply (TT tuple, const T &t)
     
    \n@@ -119,15 +119,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02140.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02140.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::ApplyHelper< 0 > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n+

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class TT , class T >
    static void apply (TT tuple, const T &t)
     
    \n@@ -117,15 +117,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02144.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02144.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::CombinedFunctor< T > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n+

    #include <dune/istl/paamg/combinedfunctor.hh>

    \n
    \n Inheritance diagram for Dune::Amg::CombinedFunctor< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -149,15 +149,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02148.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02148.html", "unified_diff": "@@ -70,28 +70,28 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< BlockVector< T, A > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef const int Arguments
     
    \n \n \n \n

    \n Static Public Member Functions

    static std::shared_ptr< BlockVector< T, A > > construct (Arguments &n)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02152.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02152.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::Amg::ParallelOperatorArgs< M, C > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Member Functions

     ParallelOperatorArgs (std::shared_ptr< M > matrix, const C &comm)
     
    \n \n \n \n \n \n

    \n Public Attributes

    std::shared_ptr< M > matrix_
     
    const C & comm_
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02156.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02156.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::Amg::OwnerOverlapCopyCommunicationArgs Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Member Functions

     OwnerOverlapCopyCommunicationArgs (MPI_Comm comm, SolverCategory::Category cat)
     
    \n \n \n \n \n \n

    \n Public Attributes

    MPI_Comm comm_
     
    SolverCategory::Category cat_
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02160.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02160.html", "unified_diff": "@@ -70,28 +70,28 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Member Functions

     SequentialCommunicationArgs (Communication< void * > comm, int cat)
     
    \n \n \n \n

    \n Public Attributes

    Communication< void * > comm_
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02164.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02164.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::OverlappingSchwarzOperator< M, X, Y, C > Class Template Reference
    \n \n
    \n \n

    An overlapping Schwarz operator. \n More...

    \n \n-

    #include <dune/istl/schwarz.hh>

    \n+

    #include <dune/istl/schwarz.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingSchwarzOperator< M, X, Y, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -502,16 +502,16 @@\n

    get the sequential assembled linear operator.

    \n \n

    Implements Dune::AssembledLinearOperator< M, X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following files:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02168.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02168.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< OverlappingSchwarzOperator< M, X, Y, C > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef ParallelOperatorArgs< M, C > Arguments
     
    \n \n

    \n@@ -129,15 +129,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02172.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02172.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< NonoverlappingSchwarzOperator< M, X, Y, C > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef ParallelOperatorArgs< M, C > Arguments
     
    \n \n

    \n@@ -129,15 +129,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02176.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02176.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::Amg::MatrixAdapterArgs< M, X, Y > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Member Functions

     MatrixAdapterArgs (std::shared_ptr< M > matrix, const SequentialInformation)
     
    \n \n

    \n@@ -139,15 +139,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02180.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02180.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< MatrixAdapter< M, X, Y > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef const MatrixAdapterArgs< M, X, Y > Arguments
     
    \n \n

    \n@@ -129,15 +129,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02184.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02184.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< SequentialInformation > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef const SequentialCommunicationArgs Arguments
     
    \n \n

    \n@@ -125,15 +125,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02188.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02188.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< OwnerOverlapCopyCommunication< T1, T2 > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/construction.hh>

    \n+

    #include <dune/istl/paamg/construction.hh>

    \n \n \n \n \n

    \n Public Types

    typedef const OwnerOverlapCopyCommunicationArgs Arguments
     
    \n \n

    \n@@ -129,15 +129,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02192.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02192.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n \n
    \n \n

    Class representing the properties of an ede in the matrix graph. \n More...

    \n \n-

    #include <dune/istl/paamg/dependency.hh>

    \n+

    #include <dune/istl/paamg/dependency.hh>

    \n \n \n \n@@ -133,15 +133,15 @@\n \n \n

    \n Public Types

    enum  { INFLUENCE\n , DEPEND\n , SIZE\n }
     Prints the attributes of the edge for debugging. More...
     
    \n

    Detailed Description

    \n

    Class representing the properties of an ede in the matrix graph.

    \n

    During the coarsening process the matrix graph needs to hold different properties of its edges. This class ontains methods for getting and setting these edge attributes.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02196.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02196.html", "unified_diff": "@@ -73,15 +73,15 @@\n \n \n
    \n \n

    Class representing a node in the matrix graph. \n More...

    \n \n-

    #include <dune/istl/paamg/dependency.hh>

    \n+

    #include <dune/istl/paamg/dependency.hh>

    \n \n \n \n \n

    \n Public Types

    enum  {
    \n   ISOLATED\n , VISITED\n , FRONT\n@@ -143,15 +143,15 @@\n
     Reset all flags. More...
     
    \n

    Detailed Description

    \n

    Class representing a node in the matrix graph.

    \n

    Contains methods for getting and setting node attributes.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02200.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02200.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::Amg::PropertyGraphVertexPropertyMap< G, i > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/dependency.hh>

    \n+

    #include <dune/istl/paamg/dependency.hh>

    \n
    \n Inheritance diagram for Dune::Amg::PropertyGraphVertexPropertyMap< G, i >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -117,15 +117,15 @@\n  Default constructor. More...
    \n  \n Reference operator[] (const Vertex &vertex) const\n  Get the properties associated to a vertex. More...
    \n  \n \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02204.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02204.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/dependency.hh>

    \n+

    #include <dune/istl/paamg/dependency.hh>

    \n \n \n \n \n

    \n Public Types

    typedef Amg::PropertyGraphVertexPropertyMap< Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM >, Amg::VertexProperties::VISITEDType
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02208.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02208.html", "unified_diff": "@@ -74,15 +74,15 @@\n \n \n
    \n \n

    A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth. \n More...

    \n \n-

    #include <dune/istl/paamg/fastamg.hh>

    \n+

    #include <dune/istl/paamg/fastamg.hh>

    \n
    \n Inheritance diagram for Dune::Amg::FastAMG< M, X, PI, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -244,15 +244,15 @@\n
    \n \n

    The range type of the preconditioner.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02216.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02216.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::GaussSeidelPresmoothDefect< level > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/fastamgsmoother.hh>

    \n+

    #include <dune/istl/paamg/fastamgsmoother.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename M , typename X , typename Y >
    static void apply (const M &A, X &x, Y &d, const Y &b)
     
    \n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02220.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02220.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::GaussSeidelPostsmoothDefect< level > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/fastamgsmoother.hh>

    \n+

    #include <dune/istl/paamg/fastamgsmoother.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename M , typename X , typename Y >
    static void apply (const M &A, X &x, Y &d, const Y &b)
     
    \n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02224.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02224.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Attributes |\n List of all members \n \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n \n \n \n \n \n \n@@ -91,15 +91,15 @@\n \n \n \n \n \n

    \n Public Types

    typedef T Aggregate
     The aggregate descriptor. More...
     
    typedef T Vertex
     The aggregate the vertex belongs to. More...
     
    Vertex vertex
     The vertex descriptor. More...
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02228.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02228.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::Amg::SparsityBuilder< M > Class Template Reference
    \n \n
    \n \n

    Functor for building the sparsity pattern of the matrix using examineConnectivity. \n More...

    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n \n \n \n \n \n \n@@ -96,15 +96,15 @@\n \n \n

    \n Public Member Functions

     SparsityBuilder (M &matrix)
     Constructor. More...
     
    void insert (const typename M::size_type &index)
    std::size_t index ()
     
    \n

    Detailed Description

    \n
    template<class M>
    \n class Dune::Amg::SparsityBuilder< M >

    Functor for building the sparsity pattern of the matrix using examineConnectivity.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02232.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02232.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::BaseGalerkinProduct:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -92,15 +92,15 @@\n  Calculate the galerkin product. More...
    \n  \n template<class M , class V , class P , class O > \n void calculate (const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const P &pinfo, const O &copy)\n  \n \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02236.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02236.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Types |\n Public Member Functions |\n List of all members
    \n
    Dune::Amg::GalerkinProduct< T > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::GalerkinProduct< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -102,15 +102,15 @@\n  Calculate the galerkin product. More...
    \n  \n template<class M , class V , class P , class O > \n void calculate (const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const P &pinfo, const O &copy)\n  \n \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02244.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02244.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::GalerkinProduct< SequentialInformation > Class Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::GalerkinProduct< SequentialInformation >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -95,15 +95,15 @@\n  Calculate the galerkin product. More...
    \n  \n template<class M , class V , class P , class O > \n void calculate (const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const P &pinfo, const O &copy)\n  \n \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02248.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02248.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Static Public Member Functions |\n List of all members
    \n \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::BaseConnectivityConstructor:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -99,15 +99,15 @@\n  \n template<class R , class G , class V > \n static void constructNonOverlapConnectivity (R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::VertexDescriptor &seed)\n  Construct the connectivity of an aggregate in the overlap. More...
    \n  \n \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02252.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02252.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder< G, S, V > Class Template Reference
    \n
    \n
    \n \n

    Visitor for identifying connected aggregates during a breadthFirstSearch. \n More...

    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n \n \n \n \n \n \n@@ -106,15 +106,15 @@\n \n \n

    \n Public Types

    typedef G Graph
     The type of the graph. More...
     
    typedef Graph::ConstEdgeIterator ConstEdgeIterator
     Process an edge pointing to another aggregate. More...
     
    \n

    Detailed Description

    \n
    template<class G, class S, class V>
    \n class Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder< G, S, V >

    Visitor for identifying connected aggregates during a breadthFirstSearch.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02256.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02256.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConnectivityConstructor< G, T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ConnectivityConstructor< G, T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -100,15 +100,15 @@\n  \n template<class R , class G , class V > \n static void constructNonOverlapConnectivity (R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::VertexDescriptor &seed)\n  Construct the connectivity of an aggregate in the overlap. More...
    \n  \n \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02260.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02260.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members
    \n
    Dune::Amg::ConnectivityConstructor< G, SequentialInformation > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ConnectivityConstructor< G, SequentialInformation >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -100,15 +100,15 @@\n  \n template<class R , class G , class V > \n static void constructNonOverlapConnectivity (R &row, G &graph, V &visitedMap, const AggregatesMap< typename G::VertexDescriptor > &aggregates, const typename G::VertexDescriptor &seed)\n  Construct the connectivity of an aggregate in the overlap. More...
    \n  \n \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02264.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02264.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::Amg::DirichletBoundarySetter< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class M , class O >
    static void set (M &coarse, const T &pinfo, const O &copy)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02268.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02268.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::Amg::DirichletBoundarySetter< SequentialInformation > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/galerkin.hh>

    \n+

    #include <dune/istl/paamg/galerkin.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<class M , class O >
    static void set (M &coarse, const SequentialInformation &pinfo, const O &copy)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02272.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02272.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::Amg::GlobalAggregatesMap< T, TI > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n

    \n Classes

    class  Proxy
     
    \n \n \n \n \n \n

    \n@@ -105,15 +105,15 @@\n

     
    Proxy operator[] (std::size_t index)
     
    void put (const GlobalIndex &global, size_t i)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02276.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02276.html", "unified_diff": "@@ -69,25 +69,25 @@\n \n
    Dune::Amg::GlobalAggregatesMap< T, TI >::Proxy Class Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n \n \n

    \n Public Member Functions

     Proxy (const GlobalLookupIndexSet< ParallelIndexSet > &indexset, Vertex &aggregate)
     
    Proxyoperator= (const GlobalIndex &global)
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02280.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02280.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::AggregatesGatherScatter< T, TI > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n \n \n@@ -87,15 +87,15 @@\n Static Public Member Functions\n \n \n \n \n

    \n Public Types

    typedef TI ParallelIndexSet
     
    typedef ParallelIndexSet::GlobalIndex GlobalIndex
     
    static const GlobalIndexgather (const GlobalAggregatesMap< T, TI > &ga, size_t i)
     
    static void scatter (GlobalAggregatesMap< T, TI > &ga, GlobalIndex global, size_t i)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02284.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02284.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::Amg::AggregatesPublisher< T, O, I > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02288.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02288.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::AggregatesPublisher< T, O, OwnerOverlapCopyCommunication< T1, T2 > > Struct Template Reference
    \n \n
    \n \n

    Utility class for publishing the aggregate number of the DOFs in the overlap to other processors and convert them to local indices. \n More...

    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n \n \n@@ -106,15 +106,15 @@\n \n \n \n

    \n Public Types

    typedef T Vertex
     
    typedef O OverlapFlags
     
    OThe set of overlap flags.
    T1The type of the global indices.
    T2The type of the local indices.
    \n \n \n

    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02292.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02292.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::AggregatesPublisher< T, O, SequentialInformation > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n \n \n@@ -87,15 +87,15 @@\n

    \n Public Types

    typedef T Vertex
     
    typedef SequentialInformation ParallelInformation
     
    \n \n \n \n

    \n Static Public Member Functions

    static void publish (AggregatesMap< Vertex > &aggregates, ParallelInformation &pinfo, const GlobalLookupIndexSet &globalLookup)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02296.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02296.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::CommPolicy< Amg::GlobalAggregatesMap< T, TI > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/globalaggregates.hh>

    \n+

    #include <dune/istl/paamg/globalaggregates.hh>

    \n \n \n \n \n \n \n@@ -87,15 +87,15 @@\n

    \n Public Types

    typedef Amg::AggregatesMap< T > Type
     
    typedef Amg::GlobalAggregatesMap< T, TI >::IndexedType IndexedType
     
    \n \n \n \n

    \n Static Public Member Functions

    static int getSize (const Type &, int)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02300.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02300.html", "unified_diff": "@@ -74,15 +74,15 @@\n \n \n
    \n \n

    The (undirected) graph of a matrix. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::MatrixGraph< M >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -772,15 +772,15 @@\n
    \n \n

    Get the number of vertices in the graph.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02304.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02304.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::MatrixGraph< M >::EdgeIteratorT< C > Class Template Reference
    \n \n
    \n \n

    Iterator over all edges starting from a vertex. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n \n \n \n \n \n@@ -618,15 +618,15 @@\n
    \n \n

    Access the edge weight.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02308.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02308.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::MatrixGraph< M >::VertexIteratorT< C > Class Template Reference
    \n \n
    \n \n

    The vertex iterator type of the graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n

    \n Public Types

    enum  { isMutable = std::is_same<C, MutableContainer>::value\n }
     
    typedef std::remove_const< C >::type MutableContainer
    \n \n \n \n \n@@ -540,15 +540,15 @@\n
    \n \n

    Access the weight of the vertex.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02312.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02312.html", "unified_diff": "@@ -74,15 +74,15 @@\n \n \n
    \n \n

    A subgraph of a graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SubGraph< G, T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -556,15 +556,15 @@\n
    \n \n

    Get the number of vertices in the graph.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02316.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02316.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::SubGraph< G, T >::EdgeIndexMap Class Reference
    \n \n
    \n \n

    An index map for mapping the edges to indices. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n

    \n Public Types

    enum  { isMutable = std::is_same<C, MutableContainer>::value\n }
     
    typedef std::remove_const< C >::type MutableContainer
    \n \n \n \n

    \n Public Types

    typedef ReadablePropertyMapTag Category
     
    \n \n

    \n@@ -200,15 +200,15 @@\n

    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02320.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02320.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::Amg::SubGraph< G, T >::EdgeIterator Class Reference
    \n \n
    \n \n

    The edge iterator of the graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SubGraph< G, T >::EdgeIterator:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -370,15 +370,15 @@\n
    \n \n

    The index of the target vertex of the current edge.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02324.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02324.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::Amg::SubGraph< G, T >::VertexIterator Class Reference
    \n \n
    \n \n

    The vertex iterator of the graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SubGraph< G, T >::VertexIterator:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -312,15 +312,15 @@\n
    \n \n

    Preincrement operator.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02328.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02328.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::VertexPropertiesGraph< G, VP, VM > Class Template Reference
    \n \n
    \n \n

    Attaches properties to the vertices of a graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n \n \n \n \n

    \n Classes

    class  VertexIteratorT
     
    \n \n \n \n \n \n

    \n@@ -693,15 +693,15 @@\n
    \n \n

    Get the number of vertices in the graph.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02332.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02332.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::Amg::VertexPropertiesGraph< G, VP, VM >::VertexIteratorT< C > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::VertexPropertiesGraph< G, VP, VM >::VertexIteratorT< C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -346,15 +346,15 @@\n
    \n \n

    Get the properties of the current Vertex.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02336.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02336.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM > Class Template Reference
    \n \n
    \n \n

    Attaches properties to the edges and vertices of a graph. \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n \n \n \n \n \n \n@@ -947,15 +947,15 @@\n
    \n \n

    Get the number of vertices in the graph.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02340.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02340.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members\n
    Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::EdgeIteratorT< C > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::EdgeIteratorT< C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -269,15 +269,15 @@\n
    \n \n

    Get the properties of the current edge.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02344.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02344.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members\n
    Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::VertexIteratorT< C > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n
    \n Inheritance diagram for Dune::Amg::PropertiesGraph< G, VP, EP, VM, EM >::VertexIteratorT< C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -323,15 +323,15 @@\n
    \n \n

    Get the properties of the current Vertex.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02348.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02348.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::GraphVertexPropertiesSelector< G > Class Template Reference
    \n \n
    \n \n

    Wrapper to access the internal edge properties of a graph via operator[]() \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n

    \n Classes

    class  EdgeIteratorT
     
    class  VertexIteratorT
     
    \n \n \n \n \n \n@@ -261,15 +261,15 @@\n

    \n Public Types

    typedef G Graph
     The type of the graph with internal properties. More...
     
    typedef G::VertexProperties VertexProperties
    \n \n \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02352.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02352.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::GraphEdgePropertiesSelector< G > Class Template Reference
    \n \n
    \n \n

    Wrapper to access the internal vertex properties of a graph via operator[]() \n More...

    \n \n-

    #include <dune/istl/paamg/graph.hh>

    \n+

    #include <dune/istl/paamg/graph.hh>

    \n \n \n \n \n \n \n@@ -261,15 +261,15 @@\n

    \n Public Types

    typedef G Graph
     The type of the graph with internal properties. More...
     
    typedef G::EdgeProperties EdgeProperties
    \n \n \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02356.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02356.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::PropertiesGraphCreator< M, PI > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/graphcreator.hh>

    \n+

    #include <dune/istl/paamg/graphcreator.hh>

    \n \n \n \n \n \n \n@@ -256,15 +256,15 @@\n \n

    \n Public Types

    typedef M::matrix_type Matrix
     
    typedef Dune::Amg::MatrixGraph< const MatrixMatrixGraph
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02360.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02360.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::PropertiesGraphCreator< M, SequentialInformation > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/graphcreator.hh>

    \n+

    #include <dune/istl/paamg/graphcreator.hh>

    \n \n \n \n \n \n \n@@ -238,15 +238,15 @@\n \n

    \n Public Types

    typedef M::matrix_type Matrix
     
    typedef Dune::Amg::MatrixGraph< const MatrixMatrixGraph
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02364.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02364.html", "unified_diff": "@@ -74,15 +74,15 @@\n \n \n
    \n \n

    A hierarchy of containers (e.g. matrices or vectors) \n More...

    \n \n-

    #include <dune/istl/paamg/hierarchy.hh>

    \n+

    #include <dune/istl/paamg/hierarchy.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Hierarchy< T, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -274,15 +274,15 @@\n
    \n \n

    Construct an empty hierarchy.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02368.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02368.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::Amg::Hierarchy< T, A >::LevelIterator< C, T1 > Class Template Reference
    \n \n
    \n \n

    Iterator over the levels in the hierarchy. \n More...

    \n \n-

    #include <dune/istl/paamg/hierarchy.hh>

    \n+

    #include <dune/istl/paamg/hierarchy.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Hierarchy< T, A >::LevelIterator< C, T1 >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -535,15 +535,15 @@\n \n

    Check whether there was a redistribution at the current level.

    \n
    Returns
    True if there is a redistributed version of the container at the current level.
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02376.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02376.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::Amg::IndicesCoarsener< T, E > Class Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n+

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02380.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02380.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ParallelIndicesCoarsener< T, E > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n+

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ParallelIndicesCoarsener< T, E >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -114,15 +114,15 @@\n Static Public Member Functions

    template<typename Graph , typename VM >
    static Graph::VertexDescriptor coarsen (ParallelInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
     Build the coarse index set after the aggregatio. More...
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02388.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02388.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::IndicesCoarsener< OwnerOverlapCopyCommunication< G, L >, E > Class Template Reference
    \n \n
    \n \n

    Coarsen Indices in the parallel case. \n More...

    \n \n-

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n+

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n
    \n Inheritance diagram for Dune::Amg::IndicesCoarsener< OwnerOverlapCopyCommunication< G, L >, E >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -359,15 +359,15 @@\n \n \n
    Returns
    The number of unknowns on the coarse level.
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02392.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02392.html", "unified_diff": "@@ -72,28 +72,28 @@\n
    Dune::Amg::IndicesCoarsener< SequentialInformation, E > Class Template Reference
    \n \n
    \n \n

    Coarsen Indices in the sequential case. \n More...

    \n \n-

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n+

    #include <dune/istl/paamg/indicescoarsener.hh>

    \n \n \n \n \n \n

    \n Static Public Member Functions

    template<typename Graph , typename VM >
    static Graph::VertexDescriptor coarsen (const SequentialInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, SequentialInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
     
    \n

    Detailed Description

    \n
    template<typename E>
    \n class Dune::Amg::IndicesCoarsener< SequentialInformation, E >

    Coarsen Indices in the sequential case.

    \n

    Nothing to be coarsened here. Just renumber the aggregates consecutively

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02396.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02396.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::MatrixHierarchy< M, PI, A > Class Template Reference
    \n \n
    \n \n

    The hierarchies build by the coarsening process. \n More...

    \n \n-

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n+

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n \n \n \n \n \n \n@@ -417,15 +417,15 @@\n \n

    \n Public Types

    typedef M MatrixOperator
     The type of the matrix operator. More...
     
    typedef MatrixOperator::matrix_type Matrix
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02408.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02408.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::Amg::MatrixHierarchy< M, PI, A >::MatrixStats< Matrix, true >::calc Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n+

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n \n \n \n \n \n \n@@ -250,15 +250,15 @@\n \n

    \n Public Types

    typedef Matrix::size_type size_type
     
    typedef Matrix::row_type matrix_row
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02412.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02412.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::CoarsenCriterion< T > Class Template Reference
    \n \n
    \n \n

    The criterion describing the stop criteria for the coarsening process. \n More...

    \n \n-

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n+

    #include <dune/istl/paamg/matrixhierarchy.hh>

    \n
    \n Inheritance diagram for Dune::Amg::CoarsenCriterion< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -218,15 +218,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02416.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02416.html", "unified_diff": "@@ -72,15 +72,15 @@\n \n \n
    \n \n

    Parameters needed to check whether a node depends on another. \n More...

    \n \n-

    #include <dune/istl/paamg/parameters.hh>

    \n+

    #include <dune/istl/paamg/parameters.hh>

    \n
    \n Inheritance diagram for Dune::Amg::DependencyParameters:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -115,15 +115,15 @@\n double alpha () const\n  Get the scaling value for marking connections as strong. Default value is 1/3. More...
    \n  \n \n

    Detailed Description

    \n

    Parameters needed to check whether a node depends on another.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02420.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02420.html", "unified_diff": "@@ -72,15 +72,15 @@\n \n
    \n
    \n \n

    Parameters needed for the aggregation process. \n More...

    \n \n-

    #include <dune/istl/paamg/parameters.hh>

    \n+

    #include <dune/istl/paamg/parameters.hh>

    \n
    \n Inheritance diagram for Dune::Amg::AggregationParameters:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -151,15 +151,15 @@\n double alpha () const\n  Get the scaling value for marking connections as strong. Default value is 1/3. More...
    \n  \n \n

    Detailed Description

    \n

    Parameters needed for the aggregation process.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02424.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02424.html", "unified_diff": "@@ -72,15 +72,15 @@\n \n
    \n
    \n \n

    Parameters for the complete coarsening process. \n More...

    \n \n-

    #include <dune/istl/paamg/parameters.hh>

    \n+

    #include <dune/istl/paamg/parameters.hh>

    \n
    \n Inheritance diagram for Dune::Amg::CoarseningParameters:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -183,15 +183,15 @@\n double alpha () const\n  Get the scaling value for marking connections as strong. Default value is 1/3. More...
    \n  \n \n

    Detailed Description

    \n

    Parameters for the complete coarsening process.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02428.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02428.html", "unified_diff": "@@ -72,15 +72,15 @@\n \n
    \n
    \n \n

    All parameters for AMG. \n More...

    \n \n-

    #include <dune/istl/paamg/parameters.hh>

    \n+

    #include <dune/istl/paamg/parameters.hh>

    \n
    \n Inheritance diagram for Dune::Amg::Parameters:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -214,15 +214,15 @@\n  Get the scaling value for marking connections as strong. Default value is 1/3. More...
    \n  \n \n

    Detailed Description

    \n

    All parameters for AMG.

    \n

    Instances of this class can be provided to CoarsenCriterion via its constructor.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02432.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02432.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members
    \n
    Dune::Amg::SequentialInformation Class Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/pinfo.hh>

    \n+

    #include <dune/istl/paamg/pinfo.hh>

    \n \n \n \n \n \n \n@@ -576,15 +576,15 @@\n \n

    \n Public Types

    typedef Communication< void * > MPICommunicator
     
    typedef EmptySet< int > CopyFlags
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02436.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02436.html", "unified_diff": "@@ -69,19 +69,19 @@\n \n \n
    \n \n

    Tag idnetifying the visited property of a vertex. \n More...

    \n \n-

    #include <dune/istl/paamg/properties.hh>

    \n+

    #include <dune/istl/paamg/properties.hh>

    \n

    Detailed Description

    \n

    Tag idnetifying the visited property of a vertex.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02440.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02440.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::RandomAccessBundledPropertyMap< C, K, i, T, R > Class Template Reference
    \n \n
    \n \n

    A property map that extracts one property out of a bundle using operator[]() \n More...

    \n \n-

    #include <dune/istl/paamg/properties.hh>

    \n+

    #include <dune/istl/paamg/properties.hh>

    \n
    \n Inheritance diagram for Dune::Amg::RandomAccessBundledPropertyMap< C, K, i, T, R >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -119,15 +119,15 @@\n  \n \n

    Detailed Description

    \n
    template<typename C, typename K, std::size_t i, typename T = typename C::ValueType, typename R = typename C::Reference>
    \n class Dune::Amg::RandomAccessBundledPropertyMap< C, K, i, T, R >

    A property map that extracts one property out of a bundle using operator[]()

    \n

    Using this access class properties can be stored in std::bitset.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02444.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02444.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Protected Attributes |\n List of all members
    \n
    Dune::Amg::AggregateRenumberer< G > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/renumberer.hh>

    \n+

    #include <dune/istl/paamg/renumberer.hh>

    \n \n \n \n \n \n

    \n Public Types

    typedef G::VertexDescriptor Vertex
     The vertex type. More...
     
    \n@@ -252,15 +252,15 @@\n \n
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02448.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02448.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::DefaultSmootherArgs< T > Struct Template Reference
    \n \n
    \n \n

    The default class for the smoother arguments. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::DefaultSmootherArgs< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -110,15 +110,15 @@\n  The relaxation factor to use. More...
    \n  \n \n

    Detailed Description

    \n
    template<class T>
    \n struct Dune::Amg::DefaultSmootherArgs< T >

    The default class for the smoother arguments.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02452.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02452.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::Amg::SmootherTraits< T > Struct Template Reference
    \n
    \n
    \n \n

    Traits class for getting the attribute class of a smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SmootherTraits< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -95,15 +95,15 @@\n typedef DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments\n  \n \n

    Detailed Description

    \n
    template<class T>
    \n struct Dune::Amg::SmootherTraits< T >

    Traits class for getting the attribute class of a smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02456.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02456.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::Amg::SmootherTraits< Richardson< X, Y > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultSmootherArgs< typename X::field_type > Arguments
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02460.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02460.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::SmootherTraits< BlockPreconditioner< X, Y, C, T > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SmootherTraits< BlockPreconditioner< X, Y, C, T > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -86,15 +86,15 @@\n \n \n \n \n

    \n Public Types

    typedef DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02464.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02464.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::SmootherTraits< NonoverlappingBlockPreconditioner< C, T > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SmootherTraits< NonoverlappingBlockPreconditioner< C, T > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -86,15 +86,15 @@\n \n \n \n \n

    \n Public Types

    typedef DefaultSmootherArgs< typename T::matrix_type::field_type > Arguments
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02468.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02468.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::DefaultConstructionArgs< T > Class Template Reference
    \n
    \n
    \n \n

    Construction Arguments for the default smoothers. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::DefaultConstructionArgs< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -118,15 +118,15 @@\n const Matrix * matrix_\n  \n \n

    Detailed Description

    \n
    template<class T>
    \n class Dune::Amg::DefaultConstructionArgs< T >

    Construction Arguments for the default smoothers.

    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02472.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02472.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Member Functions |\n Protected Attributes |\n List of all members
    \n
    Dune::Amg::ConstructionArgs< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ConstructionArgs< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -106,15 +106,15 @@\n \n \n \n \n

    \n Protected Attributes

    const Matrix * matrix_
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02476.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02476.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Member Functions |\n Protected Attributes |\n List of all members
    \n
    Dune::Amg::DefaultParallelConstructionArgs< T, C > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::DefaultParallelConstructionArgs< T, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -112,15 +112,15 @@\n \n \n \n \n

    \n Protected Attributes

    const Matrix * matrix_
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02480.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02480.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::Amg::DefaultConstructionArgs< Richardson< X, Y > > Class Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n \n \n \n \n \n

    \n Public Member Functions

    virtual ~DefaultConstructionArgs ()
     
    template<class... Args>
    void setMatrix (const Args &...)
     
    const SequentialInformationgetComm ()
     
    const SmootherArgs getArgs () const
     
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02484.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02484.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< SeqSSOR< M, X, Y, l > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the SeqSSOR smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< SeqSSOR< M, X, Y, l > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class M, class X, class Y, int l>
    \n struct Dune::Amg::ConstructionTraits< SeqSSOR< M, X, Y, l > >

    Policy for the construction of the SeqSSOR smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02488.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02488.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< SeqSOR< M, X, Y, l > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the SeqSOR smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< SeqSOR< M, X, Y, l > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class M, class X, class Y, int l>
    \n struct Dune::Amg::ConstructionTraits< SeqSOR< M, X, Y, l > >

    Policy for the construction of the SeqSOR smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02492.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02492.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< SeqJac< M, X, Y, l > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the SeqJac smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< SeqJac< M, X, Y, l > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class M, class X, class Y, int l>
    \n struct Dune::Amg::ConstructionTraits< SeqJac< M, X, Y, l > >

    Policy for the construction of the SeqJac smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02496.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02496.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< Richardson< X, Y > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the Richardson smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultConstructionArgs< Richardson< X, Y > > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< Richardson< X, Y > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class X, class Y>
    \n struct Dune::Amg::ConstructionTraits< Richardson< X, Y > >

    Policy for the construction of the Richardson smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02500.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02500.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Member Functions |\n Protected Attributes |\n List of all members \n
    Dune::Amg::ConstructionArgs< SeqILU< M, X, Y > > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ConstructionArgs< SeqILU< M, X, Y > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -324,15 +324,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02504.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02504.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< SeqILU< M, X, Y > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the SeqILU smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef ConstructionArgs< SeqILU< M, X, Y > > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< SeqILU< M, X, Y > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class M, class X, class Y>
    \n struct Dune::Amg::ConstructionTraits< SeqILU< M, X, Y > >

    Policy for the construction of the SeqILU smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02508.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02508.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::ConstructionTraits< ParSSOR< M, X, Y, C > > Struct Template Reference
    \n \n
    \n \n

    Policy for the construction of the ParSSOR smoother. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef DefaultParallelConstructionArgs< M, C > Arguments
     
    \n \n \n

    \n@@ -89,15 +89,15 @@\n

    static std::shared_ptr< ParSSOR< M, X, Y, C > > construct (Arguments &args)
     
    \n

    Detailed Description

    \n
    template<class M, class X, class Y, class C>
    \n struct Dune::Amg::ConstructionTraits< ParSSOR< M, X, Y, C > >

    Policy for the construction of the ParSSOR smoother.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02512.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02512.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< BlockPreconditioner< X, Y, C, T > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n

    \n Public Types

    typedef DefaultParallelConstructionArgs< T, C > Arguments
     
    typedef ConstructionTraits< T > SeqConstructionTraits
     
    \n \n \n \n

    \n Static Public Member Functions

    static std::shared_ptr< BlockPreconditioner< X, Y, C, T > > construct (Arguments &args)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02516.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02516.html", "unified_diff": "@@ -70,30 +70,30 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< NonoverlappingBlockPreconditioner< C, T > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n

    \n Public Types

    typedef DefaultParallelConstructionArgs< T, C > Arguments
     
    typedef ConstructionTraits< T > SeqConstructionTraits
     
    \n \n \n \n

    \n Static Public Member Functions

    static std::shared_ptr< NonoverlappingBlockPreconditioner< C, T > > construct (Arguments &args)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02520.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02520.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Amg::SmootherApplier< T > Struct Template Reference
    \n \n
    \n \n

    Helper class for applying the smoothers. \n More...

    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -99,15 +99,15 @@\n

    \n Public Types

    typedef T Smoother
     
    typedef Smoother::range_type Range
     
    \n

    Detailed Description

    \n
    template<class T>
    \n struct Dune::Amg::SmootherApplier< T >

    Helper class for applying the smoothers.

    \n

    The goal of this class is to get a symmetric AMG method whenever possible.

    \n

    The specializations for SOR and SeqOverlappingSchwarz in MultiplicativeSchwarzMode will apply the smoother forward when pre and backward when post smoothing.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02524.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02524.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::SmootherApplier< SeqSOR< M, X, Y, l > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n Static Public Member Functions\n \n \n \n \n

    \n Public Types

    typedef SeqSOR< M, X, Y, l > Smoother
     
    typedef Smoother::range_type Range
     
    static void preSmooth (Smoother &smoother, Domain &v, Range &d)
     
    static void postSmooth (Smoother &smoother, Domain &v, Range &d)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02528.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02528.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::SmootherApplier< BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n Static Public Member Functions\n \n \n \n \n

    \n Public Types

    typedef BlockPreconditioner< X, Y, C, SeqSOR< M, X, Y, l > > Smoother
     
    typedef Smoother::range_type Range
     
    static void preSmooth (Smoother &smoother, Domain &v, Range &d)
     
    static void postSmooth (Smoother &smoother, Domain &v, Range &d)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02532.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02532.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::SmootherApplier< NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n Static Public Member Functions\n \n \n \n \n

    \n Public Types

    typedef NonoverlappingBlockPreconditioner< C, SeqSOR< M, X, Y, l > > Smoother
     
    typedef Smoother::range_type Range
     
    static void preSmooth (Smoother &smoother, Domain &v, Range &d)
     
    static void postSmooth (Smoother &smoother, Domain &v, Range &d)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02536.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02536.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::SmootherApplier< SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n Static Public Member Functions\n \n \n \n \n

    \n Public Types

    typedef SeqOverlappingSchwarz< M, X, MultiplicativeSchwarzMode, MS, TA > Smoother
     
    typedef Smoother::range_type Range
     
    static void preSmooth (Smoother &smoother, Domain &v, const Range &d)
     
    static void postSmooth (Smoother &smoother, Domain &v, const Range &d)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02540.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02540.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Public Attributes |\n List of all members \n
    Dune::Amg::SeqOverlappingSchwarzSmootherArgs< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::SeqOverlappingSchwarzSmootherArgs< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -113,15 +113,15 @@\n  The numbe of iterations to perform. More...
    \n  \n RelaxationFactor relaxationFactor\n  The relaxation factor to use. More...
    \n  \n \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02544.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02544.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::Amg::SmootherTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef SeqOverlappingSchwarzSmootherArgs< typename M::field_type > Arguments
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02548.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02548.html", "unified_diff": "@@ -72,15 +72,15 @@\n Public Member Functions |\n Protected Attributes |\n List of all members \n
    Dune::Amg::ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n
    \n Inheritance diagram for Dune::Amg::ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -339,15 +339,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02564.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02564.html", "unified_diff": "@@ -70,28 +70,28 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::ConstructionTraits< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/smoother.hh>

    \n+

    #include <dune/istl/paamg/smoother.hh>

    \n \n \n \n \n

    \n Public Types

    typedef ConstructionArgs< SeqOverlappingSchwarz< M, X, TM, TS, TA > > Arguments
     
    \n \n \n \n

    \n Static Public Member Functions

    static std::shared_ptr< SeqOverlappingSchwarz< M, X, TM, TS, TA > > construct (Arguments &args)
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02568.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02568.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::Transfer< V1, V2, T > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/transfer.hh>

    \n+

    #include <dune/istl/paamg/transfer.hh>

    \n \n \n \n \n \n \n@@ -291,15 +291,15 @@\n \n

    \n Public Types

    typedef V1 Vertex
     
    typedef V2 Vector
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02572.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02572.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Member Functions |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::Transfer< V, V1, SequentialInformation > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/transfer.hh>

    \n+

    #include <dune/istl/paamg/transfer.hh>

    \n \n \n \n \n \n \n@@ -281,15 +281,15 @@\n \n

    \n Public Types

    typedef V Vertex
     
    typedef V1 Vector
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02576.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02576.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Member Functions |\n List of all members \n
    Dune::Amg::Transfer< V, V1, OwnerOverlapCopyCommunication< T1, T2 > > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/paamg/transfer.hh>

    \n+

    #include <dune/istl/paamg/transfer.hh>

    \n \n \n \n \n \n \n@@ -142,15 +142,15 @@\n \n

    \n Public Types

    typedef V Vertex
     
    typedef V1 Vector
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02580.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02580.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::LevelTransferPolicy< FO, CO > Class Template Referenceabstract
    \n \n
    \n \n

    Abstract base class for transfer between levels and creation of the coarse level system. \n More...

    \n \n-

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n+

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n
    \n Inheritance diagram for Dune::Amg::LevelTransferPolicy< FO, CO >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -610,15 +610,15 @@\n
    \n \n

    The coarse level rhs.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02584.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02584.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::AggregationLevelTransferPolicy< O, C > Class Template Referenceabstract
    \n \n
    \n \n

    A LeveTransferPolicy that used aggregation to construct the coarse level system. \n More...

    \n \n-

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n+

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n
    \n Inheritance diagram for Dune::Amg::AggregationLevelTransferPolicy< O, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -713,15 +713,15 @@\n
    \n \n

    The coarse level rhs.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02588.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02588.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::Amg::OneStepAMGCoarseSolverPolicy< O, S, C > Class Template Reference
    \n \n
    \n \n

    A policy class for solving the coarse level system using one step of AMG. \n More...

    \n \n-

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n+

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n \n \n \n \n \n \n@@ -376,15 +376,15 @@\n

    \n Public Types

    typedef O Operator
     The type of the linear operator used. More...
     
    typedef O::range_type X
    \n \n \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02596.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02596.html", "unified_diff": "@@ -71,15 +71,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::Amg::TwoLevelMethod< FO, CSP, S > Class Template Referenceabstract
    \n \n
    \n \n-

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n+

    #include <dune/istl/paamg/twolevelmethod.hh>

    \n
    \n Inheritance diagram for Dune::Amg::TwoLevelMethod< FO, CSP, S >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -803,15 +803,15 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02604.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02604.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Preconditioner< X, Y > Class Template Referenceabstract
    \n \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02608.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02608.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::InverseOperator2Preconditioner< O, c > Class Template Reference
    \n \n
    \n \n

    Turns an InverseOperator into a Preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::InverseOperator2Preconditioner< O, c >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -458,15 +458,15 @@\n \n \n

    Implements Dune::Preconditioner< O::domain_type, O::range_type >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02612.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02612.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqSSOR< M, X, Y, l > Class Template Reference
    \n \n
    \n \n

    Sequential SSOR preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::SeqSSOR< M, X, Y, l >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -600,15 +600,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02616.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02616.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqSOR< M, X, Y, l > Class Template Reference
    \n \n
    \n \n

    Sequential SOR preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::SeqSOR< M, X, Y, l >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -649,15 +649,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02620.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02620.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqJac< M, X, Y, l > Class Template Reference
    \n \n
    \n \n

    The sequential jacobian preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::SeqJac< M, X, Y, l >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -600,15 +600,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02624.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02624.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::SeqILU< M, X, Y, l > Class Template Reference
    \n \n
    \n \n

    Sequential ILU preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::SeqILU< M, X, Y, l >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -883,15 +883,15 @@\n
    \n \n

    true if w != 1.0

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02628.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02628.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::Richardson< X, Y > Class Template Reference
    \n \n
    \n \n

    Richardson preconditioner. \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::Richardson< X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -487,15 +487,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02632.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02632.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqILDL< M, X, Y > Class Template Reference
    \n \n
    \n \n

    sequential ILDL preconditioner \n More...

    \n \n-

    #include <dune/istl/preconditioners.hh>

    \n+

    #include <dune/istl/preconditioners.hh>

    \n
    \n Inheritance diagram for Dune::SeqILDL< M, X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -587,15 +587,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02640.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02640.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::RedistributeInterface Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/repartition.hh>

    \n+

    #include <dune/istl/repartition.hh>

    \n
    \n Inheritance diagram for Dune::RedistributeInterface:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -289,15 +289,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02660.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02660.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::ScalarProduct< X > Class Template Reference
    \n \n
    \n \n

    Base class for scalar product and norm computation. \n More...

    \n \n-

    #include <dune/istl/scalarproducts.hh>

    \n+

    #include <dune/istl/scalarproducts.hh>

    \n
    \n Inheritance diagram for Dune::ScalarProduct< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -305,15 +305,15 @@\n

    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.

    \n \n

    Reimplemented in Dune::ParallelScalarProduct< X, C >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02664.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02664.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::ParallelScalarProduct< X, C > Class Template Reference
    \n \n
    \n \n

    Scalar product for overlapping Schwarz methods. \n More...

    \n \n-

    #include <dune/istl/scalarproducts.hh>

    \n+

    #include <dune/istl/scalarproducts.hh>

    \n
    \n Inheritance diagram for Dune::ParallelScalarProduct< X, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -398,15 +398,15 @@\n

    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.

    \n \n

    Reimplemented from Dune::ScalarProduct< X >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02668.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02668.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SeqScalarProduct< X > Class Template Reference
    \n \n
    \n \n

    Default implementation for the scalar case. \n More...

    \n \n-

    #include <dune/istl/scalarproducts.hh>

    \n+

    #include <dune/istl/scalarproducts.hh>

    \n
    \n Inheritance diagram for Dune::SeqScalarProduct< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -291,15 +291,15 @@\n

    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.

    \n \n

    Reimplemented in Dune::ParallelScalarProduct< X, C >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02672.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02672.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::NonoverlappingSchwarzScalarProduct< X, C > Class Template Reference
    \n \n
    \n \n

    Nonoverlapping Scalar Product with communication object. \n More...

    \n \n-

    #include <dune/istl/scalarproducts.hh>

    \n+

    #include <dune/istl/scalarproducts.hh>

    \n
    \n Inheritance diagram for Dune::NonoverlappingSchwarzScalarProduct< X, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -388,15 +388,15 @@\n

    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.

    \n \n

    Reimplemented from Dune::ScalarProduct< X >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02676.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02676.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::OverlappingSchwarzScalarProduct< X, C > Class Template Reference
    \n \n
    \n \n

    Scalar product for overlapping Schwarz methods. \n More...

    \n \n-

    #include <dune/istl/scalarproducts.hh>

    \n+

    #include <dune/istl/scalarproducts.hh>

    \n
    \n Inheritance diagram for Dune::OverlappingSchwarzScalarProduct< X, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -394,15 +394,15 @@\n

    Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.

    \n \n

    Reimplemented from Dune::ScalarProduct< X >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02680.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02680.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::ScaledIdentityMatrix< K, n > Class Template Reference
    \n \n
    \n \n

    A multiple of the identity matrix of static size. \n More...

    \n \n-

    #include <dune/istl/scaledidmatrix.hh>

    \n+

    #include <dune/istl/scaledidmatrix.hh>

    \n \n \n \n \n@@ -2160,15 +2160,15 @@\n
    \n \n

    We are at the leaf of the block recursion.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02684.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02684.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::DenseMatrixAssigner< DenseMatrix, ScaledIdentityMatrix< field, N > > Struct Template Reference
    \n \n

    \n Public Types

    enum  { rows = n\n , cols = n\n }
     export size More...
    \n \n \n \n

    \n Static Public Member Functions

    static void apply (DenseMatrix &denseMatrix, ScaledIdentityMatrix< field, N > const &rhs)
     
    \n

    Member Function Documentation

    \n@@ -116,15 +116,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02688.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02688.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::FieldTraits< ScaledIdentityMatrix< K, n > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/scaledidmatrix.hh>

    \n+

    #include <dune/istl/scaledidmatrix.hh>

    \n \n \n \n \n \n \n@@ -112,15 +112,15 @@\n \n

    \n Public Types

    using field_type = typename ScaledIdentityMatrix< K, n >::field_type
     
    using real_type = typename FieldTraits< field_type >::real_type
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02692.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02692.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::ParSSOR< M, X, Y, C > Class Template Reference
    \n \n
    \n \n

    A parallel SSOR preconditioner. \n More...

    \n \n-

    #include <dune/istl/schwarz.hh>

    \n+

    #include <dune/istl/schwarz.hh>

    \n
    \n Inheritance diagram for Dune::ParSSOR< M, X, Y, C >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -467,15 +467,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02696.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02696.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::BlockPreconditioner< X, Y, C, P > Class Template Reference
    \n \n
    \n \n

    Block parallel preconditioner. \n More...

    \n \n-

    #include <dune/istl/schwarz.hh>

    \n+

    #include <dune/istl/schwarz.hh>

    \n
    \n Inheritance diagram for Dune::BlockPreconditioner< X, Y, C, P >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -541,15 +541,15 @@\n \n \n

    Implements Dune::Preconditioner< X, Y >.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02700.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02700.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::InverseOperatorResult Struct Reference
    \n \n
    \n \n

    Statistics about the application of an inverse operator. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n \n \n \n \n \n \n@@ -262,15 +262,15 @@\n
    \n \n

    Reduction achieved: \"$.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02704.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02704.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::InverseOperator< X, Y > Class Template Referenceabstract
    \n \n
    \n \n

    Abstract base class for all solvers. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n
    \n Inheritance diagram for Dune::InverseOperator< X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -613,15 +613,15 @@\n
    \n \n

    helper function for printing solver output

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02708.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02708.html", "unified_diff": "@@ -77,15 +77,15 @@\n
    Dune::IterativeSolver< X, Y > Class Template Referenceabstract
    \n \n
    \n \n

    Base class for all implementations of iterative solvers. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n
    \n Inheritance diagram for Dune::IterativeSolver< X, Y >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1303,15 +1303,15 @@\n \n

    \n Public Member Functions

     InverseOperatorResult ()
     Default constructor. More...
     
    void clear ()
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02712.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02712.html", "unified_diff": "@@ -74,15 +74,15 @@\n
    Dune::IterativeSolver< X, Y >::Iteration< CountType > Class Template Reference
    \n \n
    \n \n

    Class for controlling iterative methods. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n \n \n \n \n \n \n@@ -519,15 +519,15 @@\n \n

    \n Public Member Functions

     Iteration (const IterativeSolver &parent, InverseOperatorResult &res)
     
     Iteration (const Iteration &)=delete
     
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02716.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02716.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix > Class Template Reference
    \n \n
    \n \n

    Helper class for notifying a DUNE-ISTL linear solver about a change of the iteration matrix object in a unified way, i.e. independent from the solver's type (direct/iterative). \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n \n \n \n \n \n \n@@ -133,15 +133,15 @@\n \n

    \n Classes

    struct  Implementation
     Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTABSolver. More...
     
    struct  Implementation< true, Dummy >
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02720.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02720.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< is_direct_solver, Dummy > Struct Template Reference
    \n \n
    \n \n

    Implementation that works together with iterative ISTL solvers, e.g. Dune::CGSolver or Dune::BiCGSTABSolver. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void setMatrix (ISTLLinearSolver &, const BCRSMatrix &)
     
    \n

    Detailed Description

    \n@@ -125,15 +125,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02724.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02724.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::SolverHelper< ISTLLinearSolver, BCRSMatrix >::Implementation< true, Dummy > Struct Template Reference
    \n \n
    \n \n

    Implementation that works together with direct ISTL solvers, e.g. Dune::SuperLU or Dune::UMFPack. \n More...

    \n \n-

    #include <dune/istl/solver.hh>

    \n+

    #include <dune/istl/solver.hh>

    \n \n \n \n \n

    \n Static Public Member Functions

    static void setMatrix (ISTLLinearSolver &solver, const BCRSMatrix &matrix)
     
    \n

    Detailed Description

    \n@@ -125,15 +125,15 @@\n \n \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02728.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02728.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SolverCategory Struct Reference
    \n \n
    \n \n

    Categories for the solvers. \n More...

    \n \n-

    #include <dune/istl/solvercategory.hh>

    \n+

    #include <dune/istl/solvercategory.hh>

    \n \n \n \n@@ -157,15 +157,15 @@\n
    \n \n

    Helperfunction to extract the solver category either from an enum, or from the newly introduced virtual member function.

    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02732.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02732.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::InvalidSolverCategory Class Reference
    \n
    \n
    \n \n-

    #include <dune/istl/solvercategory.hh>

    \n+

    #include <dune/istl/solvercategory.hh>

    \n
    \n Inheritance diagram for Dune::InvalidSolverCategory:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02736.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02736.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::SolverFactory< Operator > Class Template Reference
    \n \n
    \n \n

    Factory to assembly solvers configured by a ParameterTree. \n More...

    \n \n-

    #include <dune/istl/solverfactory.hh>

    \n+

    #include <dune/istl/solverfactory.hh>

    \n

    \n Public Types

    enum  Category { sequential\n , nonoverlapping\n , overlapping\n }
    \n \n \n \n \n \n@@ -189,15 +189,15 @@\n
    \n \n

    Construct a Preconditioner for a given Operator.

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02752.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02752.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::UnsupportedType Class Reference
    \n
    \n
    \n \n-

    #include <dune/istl/solverregistry.hh>

    \n+

    #include <dune/istl/solverregistry.hh>

    \n
    \n Inheritance diagram for Dune::UnsupportedType:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02756.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02756.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::InvalidSolverFactoryConfiguration Class Reference
    \n
    \n
    \n \n-

    #include <dune/istl/solverregistry.hh>

    \n+

    #include <dune/istl/solverregistry.hh>

    \n
    \n Inheritance diagram for Dune::InvalidSolverFactoryConfiguration:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02760.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02760.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::LoopSolver< X > Class Template Reference
    \n \n
    \n \n

    Preconditioned loop solver. \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::LoopSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -798,15 +798,15 @@\n \n

    \n Static Public Member Functions

    static std::shared_ptr< Solverget (std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner > prec=nullptr)
     get a solver from the factory More...
     
    static std::shared_ptr< PreconditionergetPreconditioner (std::shared_ptr< Operator > op, const ParameterTree &config)
    \n
    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02764.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02764.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::GradientSolver< X > Class Template Reference
    \n \n
    \n \n

    gradient method \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::GradientSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -798,15 +798,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02768.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02768.html", "unified_diff": "@@ -77,15 +77,15 @@\n
    Dune::CGSolver< X > Class Template Reference
    \n \n
    \n \n

    conjugate gradient method \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::CGSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1061,15 +1061,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02772.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02772.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::BiCGSTABSolver< X > Class Template Reference
    \n \n
    \n \n

    Bi-conjugate Gradient Stabilized (BiCG-STAB) \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::BiCGSTABSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -802,15 +802,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02776.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02776.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::MINRESSolver< X > Class Template Reference
    \n \n
    \n \n

    Minimal Residual Method (MINRES) \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::MINRESSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -799,15 +799,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02780.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02780.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::RestartedGMResSolver< X, Y, F > Class Template Referenceabstract
    \n \n
    \n \n

    implements the Generalized Minimal Residual (GMRes) method \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::RestartedGMResSolver< X, Y, F >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1597,15 +1597,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02784.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02784.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::RestartedFlexibleGMResSolver< X, Y, F > Class Template Reference
    \n \n
    \n \n

    implements the Flexible Generalized Minimal Residual (FGMRes) method (right preconditioned) \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::RestartedFlexibleGMResSolver< X, Y, F >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1090,15 +1090,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02788.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02788.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::GeneralizedPCGSolver< X > Class Template Reference
    \n \n
    \n \n

    Generalized preconditioned conjugate gradient solver. \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::GeneralizedPCGSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1115,15 +1115,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02792.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02792.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::RestartedFCGSolver< X > Class Template Reference
    \n \n
    \n \n

    Accelerated flexible conjugate gradient method. \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::RestartedFCGSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1170,15 +1170,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02796.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02796.html", "unified_diff": "@@ -76,15 +76,15 @@\n
    Dune::CompleteFCGSolver< X > Class Template Reference
    \n \n
    \n \n

    Complete flexible conjugate gradient method. \n More...

    \n \n-

    #include <dune/istl/solvers.hh>

    \n+

    #include <dune/istl/solvers.hh>

    \n
    \n Inheritance diagram for Dune::CompleteFCGSolver< X >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -827,15 +827,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02800.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02800.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::IsDirectSolver< Solver > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/solvertype.hh>

    \n+

    #include <dune/istl/solvertype.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value =false\n }
     
    \n@@ -100,15 +100,15 @@\n

    If Solver is a direct solver, this is true.

    \n \n \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02804.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02804.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::StoresColumnCompressed< Solver > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/solvertype.hh>

    \n+

    #include <dune/istl/solvertype.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = false\n }
     
    \n@@ -99,15 +99,15 @@\n Enumeratorvalue 

    whether the solver internally uses column compressed storage

    \n \n \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02808.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02808.html", "unified_diff": "@@ -69,26 +69,26 @@\n
    Dune::SPQR< Matrix > Class Template Reference
    \n \n
    \n \n

    Use the SPQR package to directly solve linear systems – empty default class. \n More...

    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n

    Detailed Description

    \n
    template<class Matrix>
    \n class Dune::SPQR< Matrix >

    Use the SPQR package to directly solve linear systems – empty default class.

    \n
    Template Parameters
    \n \n \n
    Matrixthe matrix type defining the system Details on SPQR can be found on http://www.cise.ufl.edu/research/sparse/spqr/
    \n
    \n
    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02812.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02812.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::SPQR< BCRSMatrix< FieldMatrix< T, n, m >, A > > Class Template Referenceabstract
    \n \n
    \n \n

    The SPQR direct sparse solver for matrices of type BCRSMatrix. \n More...

    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n
    \n Inheritance diagram for Dune::SPQR< BCRSMatrix< FieldMatrix< T, n, m >, A > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -548,15 +548,15 @@\n
    \n \n

    helper function for printing solver output

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02816.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02816.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::IsDirectSolver< SPQR< BCRSMatrix< T, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02820.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02820.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::StoresColumnCompressed< SPQR< BCRSMatrix< T, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02824.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02824.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Public Member Functions |\n List of all members \n
    Dune::SPQRCreator Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n \n \n \n \n \n

    \n Classes

    struct  isValidBlock
     
    struct  isValidBlock< FieldVector< double, 1 > >
     
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    template<typename TL , typename M >
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &, const Dune::ParameterTree &, std::enable_if_t<!isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02828.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02828.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SPQRCreator::isValidBlock< class > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n
    \n Inheritance diagram for Dune::SPQRCreator::isValidBlock< class >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02832.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02832.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SPQRCreator::isValidBlock< FieldVector< double, 1 > > Struct Reference
    \n
    \n
    \n \n-

    #include <dune/istl/spqr.hh>

    \n+

    #include <dune/istl/spqr.hh>

    \n
    \n Inheritance diagram for Dune::SPQRCreator::isValidBlock< FieldVector< double, 1 > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02836.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02836.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperLUSolveChooser< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02840.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02840.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperLUDenseMatChooser< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02844.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02844.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperLUQueryChooser< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02848.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02848.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::QuerySpaceChooser< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02864.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02864.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SuperLU< M > Class Template Reference
    \n \n
    \n \n

    SuperLu Solver. \n More...

    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLU< M >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -469,15 +469,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02868.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02868.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::IsDirectSolver< SuperLU< BCRSMatrix< T, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value =true\n }
     
    \n@@ -98,15 +98,15 @@\n \n \n
    Enumerator
    value 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02872.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02872.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::StoresColumnCompressed< SuperLU< BCRSMatrix< T, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n@@ -98,15 +98,15 @@\n \n \n
    Enumerator
    value 
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02876.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02876.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Public Member Functions |\n List of all members \n
    Dune::SuperLUCreator Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n \n \n \n \n \n \n@@ -196,15 +196,15 @@\n \n

    \n Classes

    struct  isValidBlock
     
    struct  isValidBlock< double >
     
    \n
    \n \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02880.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02880.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SuperLUCreator::isValidBlock< class > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUCreator::isValidBlock< class >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02884.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02884.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< double, k > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< double, k > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02888.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02888.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< std::complex< double >, k > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUCreator::isValidBlock< Dune::FieldVector< std::complex< double >, k > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02892.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02892.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SuperLUCreator::isValidBlock< double > Struct Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUCreator::isValidBlock< double >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02896.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02896.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::SuperLUCreator::isValidBlock< std::complex< double > > Struct Reference
    \n
    \n
    \n \n-

    #include <dune/istl/superlu.hh>

    \n+

    #include <dune/istl/superlu.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUCreator::isValidBlock< std::complex< double > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02900.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02900.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperMatrixCreateSparseChooser< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02904.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02904.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperMatrixPrinter< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02908.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02908.html", "unified_diff": "@@ -69,15 +69,15 @@\n \n
    Dune::BaseGetSuperLUType< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::BaseGetSuperLUType< T >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -122,15 +122,15 @@\n
    std::is_same<T,float>::value ? SLU_S :
    \n
    ( std::is_same<T,std::complex<double> >::value ? SLU_Z :
    \n
    ( std::is_same<T,std::complex<float> >::value ? SLU_C : SLU_D ))
    \n
    \n
    \n \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02912.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02912.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::GetSuperLUType< T > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02916.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02916.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Attributes |\n List of all members \n
    Dune::GetSuperLUType< double > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::GetSuperLUType< double >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02920.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02920.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Attributes |\n List of all members \n
    Dune::GetSuperLUType< float > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::GetSuperLUType< float >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02924.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02924.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Attributes |\n List of all members \n
    Dune::GetSuperLUType< std::complex< double > > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::GetSuperLUType< std::complex< double > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02928.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02928.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Static Public Attributes |\n List of all members \n
    Dune::GetSuperLUType< std::complex< float > > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::GetSuperLUType< std::complex< float > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -131,15 +131,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this struct was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02932.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02932.html", "unified_diff": "@@ -69,29 +69,29 @@\n
    Dune::SuperLUMatrix< M > Struct Template Reference
    \n \n
    \n \n

    Utility class for converting an ISTL Matrix into a SuperLU Matrix. \n More...

    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUMatrix< M >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n

    Detailed Description

    \n
    template<class M>
    \n struct Dune::SuperLUMatrix< M >

    Utility class for converting an ISTL Matrix into a SuperLU Matrix.

    \n

    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02936.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02936.html", "unified_diff": "@@ -66,17 +66,17 @@\n \n \n
    \n
    Dune::SuperMatrixInitializer< M > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02940.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02940.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::SuperLUMatrix< BCRSMatrix< B, TA > > Class Template Reference
    \n \n
    \n \n

    Converter for BCRSMatrix to SuperLU Matrix. \n More...

    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::SuperLUMatrix< BCRSMatrix< B, TA > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -482,15 +482,15 @@\n \n \n \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02944.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02944.html", "unified_diff": "@@ -70,15 +70,15 @@\n Public Types |\n Public Member Functions |\n List of all members \n
    Dune::SuperMatrixInitializer< BCRSMatrix< B, A > > Class Template Reference
    \n \n
    \n \n-

    #include <dune/istl/supermatrix.hh>

    \n+

    #include <dune/istl/supermatrix.hh>

    \n
    \n Inheritance diagram for Dune::SuperMatrixInitializer< BCRSMatrix< B, A > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -216,15 +216,15 @@\n \n \n
    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02948.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02948.html", "unified_diff": "@@ -69,23 +69,23 @@\n \n
    Dune::UMFPackMethodChooser< T > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n

    \n Static Public Attributes

    static constexpr bool valid = false
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02952.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02952.html", "unified_diff": "@@ -70,15 +70,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::UMFPackMethodChooser< double > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n \n \n@@ -111,15 +111,15 @@\n

    \n Static Public Member Functions

    template<typename... A>
    static void defaults (A... args)
     
    template<typename... A>
    \n \n \n \n

    \n Static Public Attributes

    static constexpr bool valid = true
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02956.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02956.html", "unified_diff": "@@ -70,15 +70,15 @@\n Static Public Member Functions |\n Static Public Attributes |\n List of all members \n
    Dune::UMFPackMethodChooser< std::complex< double > > Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n \n \n@@ -111,15 +111,15 @@\n

    \n Static Public Member Functions

    template<typename... A>
    static void defaults (A... args)
     
    template<typename... A>
    \n \n \n \n

    \n Static Public Attributes

    static constexpr bool valid = true
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02972.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02972.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::UMFPack< M > Class Template Reference
    \n \n
    \n \n

    The UMFPack direct sparse solver. \n More...

    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n
    \n Inheritance diagram for Dune::UMFPack< M >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -179,15 +179,15 @@\n \n \n
    Matrixthe matrix type defining the system
    \n \n \n
    Note
    This will only work if dune-istl has been configured to use UMFPack
    \n

    The documentation for this class was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02976.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02976.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::IsDirectSolver< UMFPack< BCRSMatrix< FieldMatrix< T, n, m >, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value =true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02980.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02980.html", "unified_diff": "@@ -69,24 +69,24 @@\n \n
    Dune::StoresColumnCompressed< UMFPack< BCRSMatrix< T, A > > > Struct Template Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n

    \n Public Types

    enum  { value = true\n }
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02984.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02984.html", "unified_diff": "@@ -70,15 +70,15 @@\n Classes |\n Public Member Functions |\n List of all members \n
    Dune::UMFPackCreator Struct Reference
    \n \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n \n \n \n \n \n \n@@ -89,15 +89,15 @@\n \n \n \n \n \n

    \n Classes

    struct  isValidBlock
     
    struct  isValidBlock< B, std::enable_if_t< std::is_same< typename FieldTraits< B >::real_type, double >::value > >
     
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &mat, const Dune::ParameterTree &config, std::enable_if_t< isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    template<typename TL , typename M >
    std::shared_ptr< Dune::InverseOperator< typename Dune::TypeListElement< 1, TL >::type, typename Dune::TypeListElement< 2, TL >::type > > operator() (TL, const M &, const Dune::ParameterTree &, std::enable_if_t< !isValidBlock< typename Dune::TypeListElement< 1, TL >::type::block_type >::value, int >=0) const
     
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02988.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02988.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::UMFPackCreator::isValidBlock< F, class > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n
    \n Inheritance diagram for Dune::UMFPackCreator::isValidBlock< F, class >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02992.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02992.html", "unified_diff": "@@ -66,26 +66,26 @@\n \n \n
    \n
    Dune::UMFPackCreator::isValidBlock< B, std::enable_if_t< std::is_same< typename FieldTraits< B >::real_type, double >::value > > Struct Template Reference
    \n
    \n
    \n \n-

    #include <dune/istl/umfpack.hh>

    \n+

    #include <dune/istl/umfpack.hh>

    \n
    \n Inheritance diagram for Dune::UMFPackCreator::isValidBlock< B, std::enable_if_t< std::is_same< typename FieldTraits< B >::real_type, double >::value > >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n \n
    \n
    The documentation for this struct was generated from the following file:\n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a02996.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a02996.html", "unified_diff": "@@ -75,15 +75,15 @@\n
    Dune::VariableBlockVector< B, A > Class Template Reference
    \n \n
    \n \n

    A Vector of blocks with different blocksizes. \n More...

    \n \n-

    #include <dune/istl/vbvector.hh>

    \n+

    #include <dune/istl/vbvector.hh>

    \n
    \n Inheritance diagram for Dune::VariableBlockVector< B, A >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -1203,15 +1203,15 @@\n \n
    \n

    increment block level counter, yes, it is two levels because VariableBlockVector is a container of containers

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a03000.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a03000.html", "unified_diff": "@@ -73,15 +73,15 @@\n
    Dune::VariableBlockVector< B, A >::CreateIterator Class Reference
    \n \n
    \n \n

    Iterator class for sequential creation of blocks. \n More...

    \n \n-

    #include <dune/istl/vbvector.hh>

    \n+

    #include <dune/istl/vbvector.hh>

    \n \n \n \n \n \n \n@@ -500,15 +500,15 @@\n
    \n \n

    set size of current block

    \n \n
    \n \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/a03004.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/a03004.html", "unified_diff": "@@ -72,15 +72,15 @@\n
    Dune::VariableBlockVector< B, A >::RealIterator< T, R > Class Template Reference
    \n \n
    \n \n

    Iterator class for sequential access. \n More...

    \n \n-

    #include <dune/istl/vbvector.hh>

    \n+

    #include <dune/istl/vbvector.hh>

    \n
    \n Inheritance diagram for Dune::VariableBlockVector< B, A >::RealIterator< T, R >:
    \n
    \n
    \"Inheritance
    \n \n \"\"\n \"\"\n@@ -439,15 +439,15 @@\n
    \n \n

    Return the index of the entry this iterator is pointing to.

    \n \n
    \n
    \n
    The documentation for this class was generated from the following file:\n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000000.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000000.html", "unified_diff": "@@ -62,14 +62,14 @@\n \n
    \n \n
    \n \n
    \n-

    istl → common Relation

    \n Public Types

    using iterator_category = std::output_iterator_tag
     iterator category More...
     
    using value_type = size_type
    File in dune/istlIncludes file in dune/istl/common
    solverregistry.hhregistry.hh
    \n+

    istl → common Relation

    File in dune/istlIncludes file in dune/istl/common
    solverregistry.hhregistry.hh
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000004.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000004.html", "unified_diff": "@@ -62,14 +62,14 @@\n \n
    \n \n
    \n \n
    \n-

    istl → eigenvalue Relation

    File in dune/istlIncludes file in dune/istl/eigenvalue
    solvers.hharpackpp.hh
    \n+

    istl → eigenvalue Relation

    File in dune/istlIncludes file in dune/istl/eigenvalue
    solvers.hharpackpp.hh
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000006.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_000005_000006.html", "unified_diff": "@@ -62,14 +62,14 @@\n \n
    \n \n
    \n \n
    \n-

    istl → paamg Relation

    File in dune/istlIncludes file in dune/istl/paamg
    matrixredistribute.hhpinfo.hh
    repartition.hhgraph.hh
    \n+

    istl → paamg Relation

    File in dune/istlIncludes file in dune/istl/paamg
    matrixredistribute.hhpinfo.hh
    repartition.hhgraph.hh
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_30ac00acf892fa1550fd06f6d9d3e856.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_30ac00acf892fa1550fd06f6d9d3e856.html", "unified_diff": "@@ -77,17 +77,17 @@\n \"\"\n \"\"\n
    \n \n \n \n-\n+\n \n-\n+\n \n

    \n Files

    file  counter.hh [code]
    file  counter.hh [code]
     
    file  registry.hh [code]
    file  registry.hh [code]
     
    \n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_4aff653484460245da749266b1996776.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_4aff653484460245da749266b1996776.html", "unified_diff": "@@ -77,17 +77,17 @@\n \"\"\n \"\"\n
    \n \n \n \n-\n+\n \n-\n+\n \n

    \n Files

    file  arpackpp.hh [code]
    file  arpackpp.hh [code]
     
    file  poweriteration.hh [code]
    file  poweriteration.hh [code]
     
    \n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_5e12c67a8fe12cf8b78c94f3b4cb9926.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_5e12c67a8fe12cf8b78c94f3b4cb9926.html", "unified_diff": "@@ -92,140 +92,140 @@\n directory  eigenvalue\n  \n directory  paamg\n  \n \n \n-\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  allocator.hh [code]
    file  allocator.hh [code]
     
    file  basearray.hh [code]
     Implements several basic array containers.
    file  basearray.hh [code]
     Implements several basic array containers.
     
    file  bccsmatrix.hh [code]
    file  bccsmatrix.hh [code]
     
    file  bccsmatrixinitializer.hh [code]
    file  bccsmatrixinitializer.hh [code]
     
    file  bcrsmatrix.hh [code]
     Implementation of the BCRSMatrix class.
    file  bcrsmatrix.hh [code]
     Implementation of the BCRSMatrix class.
     
    file  bdmatrix.hh [code]
     Implementation of the BDMatrix class.
    file  bdmatrix.hh [code]
     Implementation of the BDMatrix class.
     
    file  blocklevel.hh [code]
     Helper functions for determining the vector/matrix block level.
    file  blocklevel.hh [code]
     Helper functions for determining the vector/matrix block level.
     
    file  btdmatrix.hh [code]
     Implementation of the BTDMatrix class.
    file  btdmatrix.hh [code]
     Implementation of the BTDMatrix class.
     
    file  bvector.hh [code]
     This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time.
    file  bvector.hh [code]
     This file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time.
     
    file  cholmod.hh [code]
    file  cholmod.hh [code]
     
    file  foreach.hh [code]
     
    file  gsetc.hh [code]
     Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
    file  gsetc.hh [code]
     Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
     
    file  ildl.hh [code]
     Incomplete LDL decomposition.
    file  ildl.hh [code]
     Incomplete LDL decomposition.
     
    file  ilu.hh [code]
     The incomplete LU factorization kernels.
    file  ilu.hh [code]
     The incomplete LU factorization kernels.
     
    file  ilusubdomainsolver.hh [code]
     Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.
    file  ilusubdomainsolver.hh [code]
     Various local subdomain solvers based on ILU for SeqOverlappingSchwarz.
     
    file  io.hh [code]
     Some generic functions for pretty printing vectors and matrices.
    file  io.hh [code]
     Some generic functions for pretty printing vectors and matrices.
     
    file  istlexception.hh [code]
    file  istlexception.hh [code]
     
    file  ldl.hh [code]
     Class for using LDL with ISTL matrices.
    file  ldl.hh [code]
     Class for using LDL with ISTL matrices.
     
    file  matrix.hh [code]
     A dynamic dense block matrix class.
    file  matrix.hh [code]
     A dynamic dense block matrix class.
     
    file  matrixindexset.hh [code]
    file  matrixindexset.hh [code]
     
    file  matrixmarket.hh [code]
     Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
    file  matrixmarket.hh [code]
     Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
     
    file  matrixmatrix.hh [code]
     provides functions for sparse matrix matrix multiplication.
    file  matrixmatrix.hh [code]
     provides functions for sparse matrix matrix multiplication.
     
    file  matrixredistribute.hh [code]
     Functionality for redistributing a sparse matrix.
    file  matrixredistribute.hh [code]
     Functionality for redistributing a sparse matrix.
     
    file  matrixutils.hh [code]
     Some handy generic functions for ISTL matrices.
    file  matrixutils.hh [code]
     Some handy generic functions for ISTL matrices.
     
    file  multitypeblockmatrix.hh [code]
    file  multitypeblockmatrix.hh [code]
     
    file  multitypeblockvector.hh [code]
    file  multitypeblockvector.hh [code]
     
    file  novlpschwarz.hh [code]
    file  novlpschwarz.hh [code]
     
    file  operators.hh [code]
     Define general, extensible interface for operators. The available implementation wraps a matrix.
    file  operators.hh [code]
     Define general, extensible interface for operators. The available implementation wraps a matrix.
     
    file  overlappingschwarz.hh [code]
     Contains one level overlapping Schwarz preconditioners.
    file  overlappingschwarz.hh [code]
     Contains one level overlapping Schwarz preconditioners.
     
    file  owneroverlapcopy.hh [code]
     Classes providing communication interfaces for overlapping Schwarz methods.
    file  owneroverlapcopy.hh [code]
     Classes providing communication interfaces for overlapping Schwarz methods.
     
    file  preconditioner.hh [code]
    file  preconditioner.hh [code]
     
    file  preconditioners.hh [code]
     Define general preconditioner interface.
    file  preconditioners.hh [code]
     Define general preconditioner interface.
     
    file  repartition.hh [code]
     Functionality for redistributing a parallel index set using graph partitioning.
    file  repartition.hh [code]
     Functionality for redistributing a parallel index set using graph partitioning.
     
    file  scalarproducts.hh [code]
     Define base class for scalar product and norm.
    file  scalarproducts.hh [code]
     Define base class for scalar product and norm.
     
    file  scaledidmatrix.hh [code]
     This file implements a quadratic matrix of fixed size which is a multiple of the identity.
    file  scaledidmatrix.hh [code]
     This file implements a quadratic matrix of fixed size which is a multiple of the identity.
     
    file  schwarz.hh [code]
    file  schwarz.hh [code]
     
    file  solver.hh [code]
     Define general, extensible interface for inverse operators.
    file  solver.hh [code]
     Define general, extensible interface for inverse operators.
     
    file  solvercategory.hh [code]
    file  solvercategory.hh [code]
     
    file  solverfactory.hh [code]
    file  solverfactory.hh [code]
     
    file  solverregistry.hh [code]
    file  solverregistry.hh [code]
     
    file  solvers.hh [code]
     Implementations of the inverse operator interface.
    file  solvers.hh [code]
     Implementations of the inverse operator interface.
     
    file  solvertype.hh [code]
     Templates characterizing the type of a solver.
    file  solvertype.hh [code]
     Templates characterizing the type of a solver.
     
    file  spqr.hh [code]
     Class for using SPQR with ISTL matrices.
    file  spqr.hh [code]
     Class for using SPQR with ISTL matrices.
     
    file  superlu.hh [code]
     Classes for using SuperLU with ISTL matrices.
    file  superlu.hh [code]
     Classes for using SuperLU with ISTL matrices.
     
    file  superlufunctions.hh [code]
    file  superlufunctions.hh [code]
     
    file  supermatrix.hh [code]
    file  supermatrix.hh [code]
     
    file  umfpack.hh [code]
     Classes for using UMFPack with ISTL matrices.
    file  umfpack.hh [code]
     Classes for using UMFPack with ISTL matrices.
     
    file  vbvector.hh [code]
     ???
    file  vbvector.hh [code]
     ???
     
    \n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dir_667edbdb0a8210232217f5e7df6d52d4.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dir_667edbdb0a8210232217f5e7df6d52d4.html", "unified_diff": "@@ -77,74 +77,74 @@\n \"\"\n \"\"\n
    \n \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n

    \n Files

    file  aggregates.hh [code]
     Provides classes for the Coloring process of AMG.
    file  aggregates.hh [code]
     Provides classes for the Coloring process of AMG.
     
    file  amg.hh [code]
     The AMG preconditioner.
    file  amg.hh [code]
     The AMG preconditioner.
     
    file  combinedfunctor.hh [code]
    file  combinedfunctor.hh [code]
     
    file  construction.hh [code]
     Helper classes for the construction of classes without empty constructor.
    file  construction.hh [code]
     Helper classes for the construction of classes without empty constructor.
     
    file  dependency.hh [code]
     Provides classes for initializing the link attributes of a matrix graph.
    file  dependency.hh [code]
     Provides classes for initializing the link attributes of a matrix graph.
     
    file  fastamg.hh [code]
     A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers.
    file  fastamg.hh [code]
     A fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers.
     
    file  fastamgsmoother.hh [code]
    file  fastamgsmoother.hh [code]
     
    file  galerkin.hh [code]
     Provides a class for building the galerkin product based on a aggregation scheme.
    file  galerkin.hh [code]
     Provides a class for building the galerkin product based on a aggregation scheme.
     
    file  globalaggregates.hh [code]
     Provdes class for identifying aggregates globally.
    file  globalaggregates.hh [code]
     Provdes class for identifying aggregates globally.
     
    file  graph.hh [code]
     Provides classes for building the matrix graph.
    file  graph.hh [code]
     Provides classes for building the matrix graph.
     
    file  graphcreator.hh [code]
    file  graphcreator.hh [code]
     
    file  hierarchy.hh [code]
     Provides a classes representing the hierarchies in AMG.
    file  hierarchy.hh [code]
     Provides a classes representing the hierarchies in AMG.
     
    file  indicescoarsener.hh [code]
     Provides a class for building the index set and remote indices on the coarse level.
    file  indicescoarsener.hh [code]
     Provides a class for building the index set and remote indices on the coarse level.
     
    file  kamg.hh [code]
     Provides an algebraic multigrid using a Krylov cycle.
    file  kamg.hh [code]
     Provides an algebraic multigrid using a Krylov cycle.
     
    file  matrixhierarchy.hh [code]
     Provides a classes representing the hierarchies in AMG.
    file  matrixhierarchy.hh [code]
     Provides a classes representing the hierarchies in AMG.
     
    file  parameters.hh [code]
     Parameter classes for customizing AMG.
    file  parameters.hh [code]
     Parameter classes for customizing AMG.
     
    file  pinfo.hh [code]
    file  pinfo.hh [code]
     
    file  properties.hh [code]
     Provides classes for handling internal properties in a graph.
    file  properties.hh [code]
     Provides classes for handling internal properties in a graph.
     
    file  renumberer.hh [code]
    file  renumberer.hh [code]
     
    file  smoother.hh [code]
     Classes for the generic construction and application of the smoothers.
    file  smoother.hh [code]
     Classes for the generic construction and application of the smoothers.
     
    file  transfer.hh [code]
     Prolongation and restriction for amg.
    file  transfer.hh [code]
     Prolongation and restriction for amg.
     
    file  twolevelmethod.hh [code]
     Algebraic twolevel methods.
    file  twolevelmethod.hh [code]
     Algebraic twolevel methods.
     
    \n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/dune-istl.tag.gz", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/dune-istl.tag.gz", "unified_diff": null, "details": [{"source1": "dune-istl.tag", "source2": "dune-istl.tag", "unified_diff": null, "details": [{"source1": "dune-istl.tag", "source2": "dune-istl.tag", "unified_diff": "@@ -9,15 +9,15 @@\n modules.txt\n /build/reproducible-path/dune-istl-2.9.0/doc/doxygen/\n a00005.html\n \n \n allocator.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00086.html\n+ a00113.html\n Dune::exists\n Dune::DefaultAllocatorTraits\n Dune::DefaultAllocatorTraits< T, std::void_t< typename T::allocator_type > >\n Dune::AllocatorTraits\n Dune\n \n typename AllocatorTraits< T >::type\n@@ -33,64 +33,64 @@\n a9020314eeb58ec32f6fab5ef0c196674\n \n \n \n \n basearray.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00050.html\n- istlexception.hh\n+ a00086.html\n+ istlexception.hh\n Dune\n \n \n bccsmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00083.html\n+ a00107.html\n Dune\n Dune::ISTL\n \n \n bccsmatrixinitializer.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00227.html\n- dune/istl/bccsmatrix.hh\n+ a00044.html\n+ dune/istl/bccsmatrix.hh\n Dune\n Dune::ISTL\n \n \n bcrsmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00197.html\n- istlexception.hh\n- bvector.hh\n- matrixutils.hh\n- dune/istl/blocklevel.hh\n+ a00077.html\n+ istlexception.hh\n+ bvector.hh\n+ matrixutils.hh\n+ dune/istl/blocklevel.hh\n Dune::CompressionStatistics\n Dune::ImplicitMatrixBuilder\n Dune::ImplicitMatrixBuilder::row_object\n Dune::BCRSMatrix\n Dune::BCRSMatrix::RealRowIterator\n Dune::BCRSMatrix::CreateIterator\n Dune::FieldTraits< BCRSMatrix< B, A > >\n Dune\n \n \n bdmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00074.html\n- dune/istl/bcrsmatrix.hh\n- dune/istl/blocklevel.hh\n+ a00014.html\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/blocklevel.hh\n Dune::BDMatrix\n Dune::FieldTraits< BDMatrix< B, A > >\n Dune\n \n \n blocklevel.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00008.html\n+ a00212.html\n Dune\n \n constexpr std::size_t\n maxBlockLevel\n a00249.html\n a33fa4c0298cf146aa9589b519344907f\n ()\n@@ -116,117 +116,117 @@\n a477c671e3966936ca929dee4be2dcf95\n ()\n \n \n \n btdmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00200.html\n- dune/istl/bcrsmatrix.hh\n- dune/istl/blocklevel.hh\n+ a00092.html\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/blocklevel.hh\n Dune::BTDMatrix\n Dune::FieldTraits< BTDMatrix< B, A > >\n Dune\n \n \n bvector.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00089.html\n- dune/istl/blocklevel.hh\n- basearray.hh\n- istlexception.hh\n+ a00122.html\n+ dune/istl/blocklevel.hh\n+ basearray.hh\n+ istlexception.hh\n Dune::BlockVector\n Dune::FieldTraits< BlockVector< B, A > >\n Dune\n \n std::ostream &\n operator<<\n a00249.html\n adcfe0da059813bbc11304ed6e603a06e\n (std::ostream &s, const BlockVector< K, A > &v)\n \n \n \n cholmod.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00029.html\n+ a00104.html\n \n \n counter.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/common/\n- a00062.html\n+ a00035.html\n Dune\n Dune::CounterImpl\n \n #define\n DUNE_GET_COUNTER\n- a00062.html\n+ a00035.html\n a52c18e20d25c64cfa14ec5faaa4eb3bd\n (Tag)\n \n \n #define\n DUNE_INC_COUNTER\n- a00062.html\n+ a00035.html\n a5d969c720adf3ae3114e5a51e2cf5d96\n (Tag)\n \n \n constexpr std::size_t\n maxcount\n- a00062.html\n+ a00035.html\n a691e9cc830a63581384caef120bcbef8\n \n \n \n \n registry.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/common/\n- a00065.html\n- counter.hh\n+ a00032.html\n+ counter.hh\n Dune\n \n #define\n DUNE_REGISTRY_PUT\n- a00065.html\n+ a00032.html\n a5aba8ecf7926f3c3dade1b898db68cf7\n (Tag, id,...)\n \n \n \n arpackpp.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/eigenvalue/\n- a00038.html\n- dune/istl/blocklevel.hh\n- dune/istl/bvector.hh\n- dune/istl/istlexception.hh\n- dune/istl/io.hh\n+ a00200.html\n+ dune/istl/blocklevel.hh\n+ dune/istl/bvector.hh\n+ dune/istl/istlexception.hh\n+ dune/istl/io.hh\n Dune::ArPackPlusPlus_Algorithms\n Dune\n \n \n poweriteration.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/eigenvalue/\n- a00035.html\n- dune/istl/blocklevel.hh\n- dune/istl/operators.hh\n- dune/istl/solvercategory.hh\n- dune/istl/solvertype.hh\n- dune/istl/istlexception.hh\n- dune/istl/io.hh\n- dune/istl/solvers.hh\n+ a00203.html\n+ dune/istl/blocklevel.hh\n+ dune/istl/operators.hh\n+ dune/istl/solvercategory.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/istlexception.hh\n+ dune/istl/io.hh\n+ dune/istl/solvers.hh\n Dune::PowerIteration_Algorithms\n Dune\n \n \n foreach.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n a00095.html\n- dune/istl/bcrsmatrix.hh\n- dune/istl/scaledidmatrix.hh\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/scaledidmatrix.hh\n Dune\n Dune::ForEach\n \n auto\n rows\n a00257.html\n a4ae853c93f3cb1318493dc4086e1dea7\n@@ -260,18 +260,18 @@\n a2589f2020f357e6afb9d4a1e6fdf92fb\n (Matrix &&matrix, F &&f, std::size_t rowOffset=0, std::size_t colOffset=0)\n \n \n \n gsetc.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00224.html\n- multitypeblockvector.hh\n- multitypeblockmatrix.hh\n- istlexception.hh\n+ a00209.html\n+ multitypeblockvector.hh\n+ multitypeblockmatrix.hh\n+ istlexception.hh\n Dune::BL\n Dune::algmeta_btsolve\n Dune::algmeta_btsolve< 0, withdiag, withrelax >\n Dune::algmeta_btsolve< 0, withdiag, norelax >\n Dune::algmeta_btsolve< 0, nodiag, withrelax >\n Dune::algmeta_btsolve< 0, nodiag, norelax >\n Dune::algmeta_bdsolve\n@@ -515,16 +515,16 @@\n ga6642a19372a5ec5f405ce8cc56515596\n (const M &A, X &x, const Y &b, const K &w, BL< l >)\n \n \n \n ildl.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00011.html\n- ilu.hh\n+ a00050.html\n+ ilu.hh\n Dune\n \n static void\n bildl_subtractBCT\n a00249.html\n af8de6b1951fa7f95a3e9f89973579115\n (const FieldMatrix< K, m, n > &B, const FieldMatrix< K, m, n > &CT, FieldMatrix< K, m, n > &A)\n@@ -557,16 +557,16 @@\n ae801cb0f5df40c48568bc703f8c802b6\n (const Matrix &A, X &v, const Y &d, bool isLowerTriangular=false)\n \n \n \n ilu.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00167.html\n- istlexception.hh\n+ a00218.html\n+ istlexception.hh\n Dune::ILU::CRS\n Dune\n Dune::ILU\n \n void\n blockILU0Decomposition\n a00258.html\n@@ -622,30 +622,30 @@\n a57f371097dec97a09d4bdc3b99077b7c\n (const CRS &lower, const CRS &upper, const InvVector &inv, X &v, const Y &d)\n \n \n \n ilusubdomainsolver.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00203.html\n- dune/istl/preconditioners.hh\n- matrix.hh\n+ a00125.html\n+ dune/istl/preconditioners.hh\n+ matrix.hh\n Dune::ILUSubdomainSolver\n Dune::ILU0SubdomainSolver\n Dune::ILUNSubdomainSolver\n Dune\n \n \n io.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00221.html\n- matrixutils.hh\n- istlexception.hh\n- dune/istl/bcrsmatrix.hh\n- dune/istl/blocklevel.hh\n+ a00008.html\n+ matrixutils.hh\n+ istlexception.hh\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/blocklevel.hh\n Dune::DefaultSVGMatrixOptions\n Dune\n \n void\n recursive_printvector\n a00246.html\n gacfa35a4c02a1d2802460eb62ecbf3689\n@@ -735,30 +735,30 @@\n ga04966ce36568730f07a9071ee2a34477\n (const Mat &mat, std::ostream &out, SVGOptions opts={})\n \n \n \n istlexception.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00170.html\n+ a00128.html\n Dune::ISTLError\n Dune::BCRSMatrixError\n Dune::ImplicitModeCompressionBufferExhausted\n Dune::SolverAbort\n Dune::MatrixBlockError\n Dune\n \n \n ldl.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00173.html\n- dune/istl/bccsmatrixinitializer.hh\n- dune/istl/solvers.hh\n- dune/istl/solvertype.hh\n- dune/istl/solverfactory.hh\n+ a00065.html\n+ dune/istl/bccsmatrixinitializer.hh\n+ dune/istl/solvers.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/solverfactory.hh\n Dune::LDL\n Dune::LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > >\n Dune::IsDirectSolver< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >\n Dune::StoresColumnCompressed< LDL< BCRSMatrix< FieldMatrix< T, n, m >, A > > >\n Dune::LDLCreator\n Dune::LDLCreator::isValidBlock\n Dune::LDLCreator::isValidBlock< FieldVector< double, k > >\n@@ -770,41 +770,41 @@\n ga4ab4a1f419552328d594727627e696cb\n ("ldl", Dune::LDLCreator())\n \n \n \n matrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00023.html\n- dune/istl/bvector.hh\n- dune/istl/istlexception.hh\n- dune/istl/blocklevel.hh\n+ a00068.html\n+ dune/istl/bvector.hh\n+ dune/istl/istlexception.hh\n+ dune/istl/blocklevel.hh\n Dune::MatrixImp::DenseMatrixBase\n Dune::MatrixImp::DenseMatrixBase::Iterator\n Dune::MatrixImp::DenseMatrixBase::ConstIterator\n Dune::Matrix\n Dune::FieldTraits< Matrix< T, A > >\n Dune\n Dune::MatrixImp\n \n \n matrixindexset.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00188.html\n+ a00206.html\n Dune::MatrixIndexSet\n Dune\n \n \n matrixmarket.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00044.html\n- dune/istl/bcrsmatrix.hh\n- dune/istl/bvector.hh\n- dune/istl/matrixutils.hh\n- dune/istl/owneroverlapcopy.hh\n+ a00074.html\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/bvector.hh\n+ dune/istl/matrixutils.hh\n+ dune/istl/owneroverlapcopy.hh\n Dune::MatrixMarketImpl::mm_numeric_type\n Dune::MatrixMarketImpl::mm_numeric_type< int >\n Dune::MatrixMarketImpl::mm_numeric_type< double >\n Dune::MatrixMarketImpl::mm_numeric_type< float >\n Dune::MatrixMarketImpl::mm_numeric_type< std::complex< double > >\n Dune::MatrixMarketImpl::mm_numeric_type< std::complex< float > >\n Dune::MatrixMarketImpl::mm_header_printer< BCRSMatrix< T, A > >\n@@ -1179,16 +1179,16 @@\n gab36dc22122e5b7f555b64ef9f418d329\n \n \n \n \n matrixmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00080.html\n- dune/istl/bcrsmatrix.hh\n+ a00098.html\n+ dune/istl/bcrsmatrix.hh\n Dune::MatMultMatResult\n Dune::MatMultMatResult< FieldMatrix< T, n, k >, FieldMatrix< T, k, m > >\n Dune::MatMultMatResult< BCRSMatrix< FieldMatrix< T, n, k >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >\n Dune::TransposedMatMultMatResult\n Dune::TransposedMatMultMatResult< FieldMatrix< T, k, n >, FieldMatrix< T, k, m > >\n Dune::TransposedMatMultMatResult< BCRSMatrix< FieldMatrix< T, k, n >, A >, BCRSMatrix< FieldMatrix< T, k, m >, A1 > >\n Dune\n@@ -1227,18 +1227,18 @@\n ga67ae04c7e7c030370f82da49ab2b98d1\n \n \n \n \n matrixredistribute.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00026.html\n- repartition.hh\n- dune/istl/owneroverlapcopy.hh\n- dune/istl/paamg/pinfo.hh\n+ a00101.html\n+ repartition.hh\n+ dune/istl/owneroverlapcopy.hh\n+ dune/istl/paamg/pinfo.hh\n Dune::RedistributeInformation\n Dune::RedistributeInformation< OwnerOverlapCopyCommunication< T, T1 > >\n Dune::CommMatrixRowSize\n Dune::CommMatrixSparsityPattern\n Dune::CommPolicy< CommMatrixSparsityPattern< M, I > >\n Dune::CommMatrixRow\n Dune::CommPolicy< CommMatrixRow< M, I > >\n@@ -1282,17 +1282,17 @@\n a345908acc30a0bf6affab15d04fcd0a8\n (M &origMatrix, M &newMatrix, Dune::Amg::SequentialInformation &origComm, Dune::Amg::SequentialInformation &newComm, RedistributeInformation< Dune::Amg::SequentialInformation > &ri)\n \n \n \n matrixutils.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00017.html\n- dune/istl/scaledidmatrix.hh\n- istlexception.hh\n+ a00062.html\n+ dune/istl/scaledidmatrix.hh\n+ istlexception.hh\n Dune::CheckIfDiagonalPresent\n Dune::CheckIfDiagonalPresent< Matrix, 0, l >\n Dune::CheckIfDiagonalPresent< MultiTypeBlockMatrix< T1, Args... >, blocklevel, l >\n Dune::MatrixDimension\n Dune::MatrixDimension< Matrix< B, TA > >\n Dune::MatrixDimension< BCRSMatrix< B, TA > >\n Dune::MatrixDimension< BCRSMatrix< FieldMatrix< B, n, m >, TA > >\n@@ -1327,17 +1327,17 @@\n a131e13bda7cee7fa0c8e4a96e8d46801\n (const M &mat, C &ooc, std::ostream &os)\n \n \n \n multitypeblockmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00068.html\n- istlexception.hh\n- gsetc.hh\n+ a00047.html\n+ istlexception.hh\n+ gsetc.hh\n Dune::MultiTypeBlockMatrix\n Dune::MultiTypeBlockMatrix_Solver_Col\n Dune::MultiTypeBlockMatrix_Solver_Col< I, crow, ccol, 0 >\n Dune::MultiTypeBlockMatrix_Solver\n Dune::MultiTypeBlockMatrix_Solver< I, crow, 0 >\n std::tuple_element< i, Dune::MultiTypeBlockMatrix< Args... > >\n Dune\n@@ -1349,17 +1349,17 @@\n gabb3823c4d80ad87cf6b49edf36af03b8\n (std::ostream &s, const MultiTypeBlockMatrix< T1, Args... > &m)\n \n \n \n multitypeblockvector.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00179.html\n- istlexception.hh\n- gsetc.hh\n+ a00083.html\n+ istlexception.hh\n+ gsetc.hh\n Dune::FieldTraits< MultiTypeBlockVector< Args... > >\n Dune::MultiTypeBlockVector\n std::tuple_element< i, Dune::MultiTypeBlockVector< Args... > >\n Dune\n std\n \n std::ostream &\n@@ -1368,53 +1368,53 @@\n ga50e32ccf93f41e9ed7783a86fee86b70\n (std::ostream &s, const MultiTypeBlockVector< Args... > &v)\n \n \n \n novlpschwarz.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00212.html\n- io.hh\n- bvector.hh\n- vbvector.hh\n- bcrsmatrix.hh\n- gsetc.hh\n- ilu.hh\n- operators.hh\n- solvers.hh\n- preconditioners.hh\n- scalarproducts.hh\n- owneroverlapcopy.hh\n+ a00038.html\n+ io.hh\n+ bvector.hh\n+ vbvector.hh\n+ bcrsmatrix.hh\n+ gsetc.hh\n+ ilu.hh\n+ operators.hh\n+ solvers.hh\n+ preconditioners.hh\n+ scalarproducts.hh\n+ owneroverlapcopy.hh\n Dune::NonoverlappingSchwarzOperator\n Dune::NonoverlappingBlockPreconditioner\n Dune\n Dune::Amg\n \n \n operators.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00032.html\n- solvercategory.hh\n+ a00080.html\n+ solvercategory.hh\n Dune::LinearOperator\n Dune::AssembledLinearOperator\n Dune::MatrixAdapter\n Dune\n \n \n overlappingschwarz.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00209.html\n- dune/istl/bccsmatrixinitializer.hh\n- preconditioners.hh\n- superlu.hh\n- umfpack.hh\n- bvector.hh\n- bcrsmatrix.hh\n- ilusubdomainsolver.hh\n- dune/istl/solvertype.hh\n+ a00089.html\n+ dune/istl/bccsmatrixinitializer.hh\n+ preconditioners.hh\n+ superlu.hh\n+ umfpack.hh\n+ bvector.hh\n+ bcrsmatrix.hh\n+ ilusubdomainsolver.hh\n+ dune/istl/solvertype.hh\n Dune::OverlappingSchwarzInitializer\n Dune::AdditiveSchwarzMode\n Dune::MultiplicativeSchwarzMode\n Dune::SymmetricMultiplicativeSchwarzMode\n Dune::DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >\n Dune::OverlappingAssignerHelper\n Dune::OverlappingAssignerHelper< DynamicMatrixSubdomainSolver< BCRSMatrix< K, Al >, X, Y >, false >\n@@ -1458,40 +1458,40 @@\n ga5a5d6fa4ec6f65757b49ed7fe09e15e2\n \n \n \n \n owneroverlapcopy.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00215.html\n- solvercategory.hh\n- istlexception.hh\n- dune/istl/matrixmarket.hh\n+ a00053.html\n+ solvercategory.hh\n+ istlexception.hh\n+ dune/istl/matrixmarket.hh\n Dune::OwnerOverlapCopyAttributeSet\n Dune::IndexInfoFromGrid\n Dune::OwnerOverlapCopyCommunication\n Dune::OwnerOverlapCopyCommunication::CopyGatherScatter\n Dune::OwnerOverlapCopyCommunication::AddGatherScatter\n Dune\n \n void\n testRedistributed\n- a00215.html\n+ a00053.html\n abcfd3b2ed3c4dd837b155879a3247503\n (int s)\n \n \n \n aggregates.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00101.html\n- parameters.hh\n- graph.hh\n- properties.hh\n- combinedfunctor.hh\n+ a00131.html\n+ parameters.hh\n+ graph.hh\n+ properties.hh\n+ combinedfunctor.hh\n Dune::Amg::AggregationCriterion\n Dune::Amg::SymmetricMatrixDependency\n Dune::Amg::Dependency\n Dune::Amg::SymmetricDependency\n Dune::Amg::Diagonal\n Dune::Amg::FirstDiagonal\n Dune::Amg::RowSum\n@@ -1526,23 +1526,23 @@\n ga67437d2f75e7e1216ee57306825332be\n (const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)\n \n \n \n amg.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00125.html\n- dune/istl/paamg/smoother.hh\n- dune/istl/paamg/transfer.hh\n- dune/istl/paamg/matrixhierarchy.hh\n- dune/istl/solvers.hh\n- dune/istl/scalarproducts.hh\n- dune/istl/superlu.hh\n- dune/istl/umfpack.hh\n- dune/istl/solvertype.hh\n+ a00188.html\n+ dune/istl/paamg/smoother.hh\n+ dune/istl/paamg/transfer.hh\n+ dune/istl/paamg/matrixhierarchy.hh\n+ dune/istl/solvers.hh\n+ dune/istl/scalarproducts.hh\n+ dune/istl/superlu.hh\n+ dune/istl/umfpack.hh\n+ dune/istl/solvertype.hh\n Dune::Amg::AMG\n Dune::Amg::DirectSolverSelector\n Dune::Amg::DirectSolverSelector::Solver\n Dune::Amg::DirectSolverSelector::Solver< M, superlu >\n Dune::AMGCreator\n Dune::AMGCreator::isValidBlockType\n Dune::AMGCreator::isValidBlockType< FieldMatrix< T, n, m > >\n@@ -1555,30 +1555,30 @@\n a9f1d7465bf71a0549ed5596e9b142f7f\n ("amg", AMGCreator())\n \n \n \n combinedfunctor.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00149.html\n+ a00170.html\n Dune::Amg::ApplyHelper\n Dune::Amg::ApplyHelper< 0 >\n Dune::Amg::CombinedFunctor\n Dune\n Dune::Amg\n \n \n construction.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00116.html\n- dune/istl/bvector.hh\n- dune/istl/operators.hh\n- dune/istl/owneroverlapcopy.hh\n- dune/istl/solvercategory.hh\n- pinfo.hh\n+ a00176.html\n+ dune/istl/bvector.hh\n+ dune/istl/operators.hh\n+ dune/istl/owneroverlapcopy.hh\n+ dune/istl/solvercategory.hh\n+ pinfo.hh\n Dune::Amg::ConstructionTraits\n Dune::Amg::ConstructionTraits< BlockVector< T, A > >\n Dune::Amg::ParallelOperatorArgs\n Dune::Amg::OwnerOverlapCopyCommunicationArgs\n Dune::Amg::SequentialCommunicationArgs\n Dune::Amg::ConstructionTraits< OverlappingSchwarzOperator< M, X, Y, C > >\n Dune::Amg::ConstructionTraits< NonoverlappingSchwarzOperator< M, X, Y, C > >\n@@ -1588,17 +1588,17 @@\n Dune::Amg::ConstructionTraits< OwnerOverlapCopyCommunication< T1, T2 > >\n Dune\n Dune::Amg\n \n \n dependency.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00161.html\n- graph.hh\n- properties.hh\n+ a00143.html\n+ graph.hh\n+ properties.hh\n Dune::Amg::EdgeProperties\n Dune::Amg::VertexProperties\n Dune::Amg::PropertyGraphVertexPropertyMap\n Dune::PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >\n Dune\n Dune::Amg\n \n@@ -1622,52 +1622,52 @@\n ga930c1b4851fd5610adcfa6b94369c22d\n (std::ostream &os, const VertexProperties &props)\n \n \n \n fastamg.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00140.html\n- dune/istl/paamg/smoother.hh\n- dune/istl/paamg/transfer.hh\n- dune/istl/paamg/matrixhierarchy.hh\n- dune/istl/solvers.hh\n- dune/istl/scalarproducts.hh\n- dune/istl/superlu.hh\n- dune/istl/umfpack.hh\n- dune/istl/solvertype.hh\n- dune/istl/io.hh\n- dune/istl/preconditioners.hh\n- fastamgsmoother.hh\n+ a00137.html\n+ dune/istl/paamg/smoother.hh\n+ dune/istl/paamg/transfer.hh\n+ dune/istl/paamg/matrixhierarchy.hh\n+ dune/istl/solvers.hh\n+ dune/istl/scalarproducts.hh\n+ dune/istl/superlu.hh\n+ dune/istl/umfpack.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/io.hh\n+ dune/istl/preconditioners.hh\n+ fastamgsmoother.hh\n Dune::Amg::FastAMG\n Dune\n Dune::Amg\n \n #define\n DIRECTSOLVER\n- a00140.html\n+ a00137.html\n a72c0db94af03bbad6ae55a51224a4a4a\n \n \n \n \n fastamgsmoother.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00122.html\n+ a00149.html\n Dune::Amg::GaussSeidelPresmoothDefect\n Dune::Amg::GaussSeidelPostsmoothDefect\n Dune\n Dune::Amg\n \n \n galerkin.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00104.html\n- aggregates.hh\n- pinfo.hh\n+ a00182.html\n+ aggregates.hh\n+ pinfo.hh\n Dune::Amg::OverlapVertex\n Dune::Amg::SparsityBuilder\n Dune::Amg::BaseGalerkinProduct\n Dune::Amg::GalerkinProduct\n Dune::Amg::GalerkinProduct< SequentialInformation >\n Dune::Amg::BaseConnectivityConstructor\n Dune::Amg::BaseConnectivityConstructor::ConnectedBuilder\n@@ -1677,32 +1677,32 @@\n Dune::Amg::DirichletBoundarySetter< SequentialInformation >\n Dune\n Dune::Amg\n \n \n globalaggregates.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00107.html\n- aggregates.hh\n- pinfo.hh\n+ a00191.html\n+ aggregates.hh\n+ pinfo.hh\n Dune::Amg::GlobalAggregatesMap\n Dune::Amg::GlobalAggregatesMap::Proxy\n Dune::Amg::AggregatesGatherScatter\n Dune::Amg::AggregatesPublisher\n Dune::Amg::AggregatesPublisher< T, O, OwnerOverlapCopyCommunication< T1, T2 > >\n Dune::Amg::AggregatesPublisher< T, O, SequentialInformation >\n Dune::CommPolicy< Amg::GlobalAggregatesMap< T, TI > >\n Dune\n Dune::Amg\n \n \n graph.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00098.html\n- dune/istl/istlexception.hh\n+ a00134.html\n+ dune/istl/istlexception.hh\n Dune::Amg::MatrixGraph\n Dune::Amg::MatrixGraph::EdgeIteratorT\n Dune::Amg::MatrixGraph::VertexIteratorT\n Dune::Amg::SubGraph\n Dune::Amg::SubGraph::EdgeIndexMap\n Dune::Amg::SubGraph::EdgeIterator\n Dune::Amg::SubGraph::VertexIterator\n@@ -1722,79 +1722,79 @@\n ga8c84915dd8eafb315ce76b1f689f1cf3\n (const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)\n \n \n \n graphcreator.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00143.html\n- graph.hh\n- dependency.hh\n- pinfo.hh\n- dune/istl/operators.hh\n- dune/istl/bcrsmatrix.hh\n+ a00164.html\n+ graph.hh\n+ dependency.hh\n+ pinfo.hh\n+ dune/istl/operators.hh\n+ dune/istl/bcrsmatrix.hh\n Dune::Amg::PropertiesGraphCreator\n Dune::Amg::PropertiesGraphCreator< M, SequentialInformation >\n Dune\n Dune::Amg\n \n \n hierarchy.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00110.html\n- dune/istl/paamg/construction.hh\n+ a00140.html\n+ dune/istl/paamg/construction.hh\n Dune::Amg::Hierarchy\n Dune::Amg::Hierarchy::LevelIterator\n Dune\n Dune::Amg\n \n \n indicescoarsener.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00137.html\n- renumberer.hh\n- dune/istl/owneroverlapcopy.hh\n- pinfo.hh\n+ a00158.html\n+ renumberer.hh\n+ dune/istl/owneroverlapcopy.hh\n+ pinfo.hh\n Dune::Amg::IndicesCoarsener\n Dune::Amg::ParallelIndicesCoarsener\n Dune::Amg::IndicesCoarsener< OwnerOverlapCopyCommunication< G, L >, E >\n Dune::Amg::IndicesCoarsener< SequentialInformation, E >\n Dune\n Dune::Amg\n \n \n kamg.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00146.html\n- dune/istl/preconditioners.hh\n- amg.hh\n+ a00194.html\n+ dune/istl/preconditioners.hh\n+ amg.hh\n Dune::Amg::KAmgTwoGrid\n Dune::Amg::KAMG\n Dune\n Dune::Amg\n \n \n matrixhierarchy.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00158.html\n- aggregates.hh\n- graph.hh\n- galerkin.hh\n- renumberer.hh\n- graphcreator.hh\n- hierarchy.hh\n- dune/istl/bvector.hh\n- dune/istl/matrixutils.hh\n- dune/istl/matrixredistribute.hh\n- dune/istl/paamg/dependency.hh\n- dune/istl/paamg/indicescoarsener.hh\n- dune/istl/paamg/globalaggregates.hh\n- dune/istl/paamg/construction.hh\n- dune/istl/paamg/smoother.hh\n- dune/istl/paamg/transfer.hh\n+ a00161.html\n+ aggregates.hh\n+ graph.hh\n+ galerkin.hh\n+ renumberer.hh\n+ graphcreator.hh\n+ hierarchy.hh\n+ dune/istl/bvector.hh\n+ dune/istl/matrixutils.hh\n+ dune/istl/matrixredistribute.hh\n+ dune/istl/paamg/dependency.hh\n+ dune/istl/paamg/indicescoarsener.hh\n+ dune/istl/paamg/globalaggregates.hh\n+ dune/istl/paamg/construction.hh\n+ dune/istl/paamg/smoother.hh\n+ dune/istl/paamg/transfer.hh\n Dune::Amg::MatrixHierarchy\n Dune::Amg::MatrixHierarchy::MatrixStats< Matrix, true >::calc\n Dune::Amg::CoarsenCriterion\n Dune\n Dune::Amg\n \n MAX_PROCESSES\n@@ -1816,15 +1816,15 @@\n ga992041e5fe1798be7fd728be5578b525\n (const M &origMatrix, std::shared_ptr< M > newMatrix, C &origComm, std::shared_ptr< C > &newComm, RedistributeInformation< C > &ri, int nparts, C1 &criterion)\n \n \n \n parameters.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00134.html\n+ a00185.html\n Dune::Amg::DependencyParameters\n Dune::Amg::AggregationParameters\n Dune::Amg::CoarseningParameters\n Dune::Amg::Parameters\n Dune\n Dune::Amg\n \n@@ -1852,54 +1852,54 @@\n ggacf6f2fe996122d7c9d139e86a84957f7a69257c9fc3443058ecc8d3d542fe0b0a\n \n \n \n \n pinfo.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00131.html\n- dune/istl/solvercategory.hh\n+ a00155.html\n+ dune/istl/solvercategory.hh\n Dune::Amg::SequentialInformation\n Dune\n Dune::Amg\n \n \n properties.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00155.html\n+ a00173.html\n Dune::Amg::VertexVisitedTag\n Dune::Amg::RandomAccessBundledPropertyMap\n Dune\n Dune::Amg\n \n \n renumberer.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00119.html\n- aggregates.hh\n+ a00167.html\n+ aggregates.hh\n Dune::Amg::AggregateRenumberer\n Dune\n Dune::Amg\n \n void\n renumberAggregates\n a00264.html\n a577d044e1622cb386cd4f6821ac63169\n (const G &graph, I index, I endIndex, V &visitedMap, AggregatesMap< typename G::VertexDescriptor > &aggregates)\n \n \n \n smoother.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00152.html\n- dune/istl/paamg/construction.hh\n- dune/istl/paamg/aggregates.hh\n- dune/istl/preconditioners.hh\n- dune/istl/schwarz.hh\n- dune/istl/novlpschwarz.hh\n+ a00179.html\n+ dune/istl/paamg/construction.hh\n+ dune/istl/paamg/aggregates.hh\n+ dune/istl/preconditioners.hh\n+ dune/istl/schwarz.hh\n+ dune/istl/novlpschwarz.hh\n Dune::Amg::DefaultSmootherArgs\n Dune::Amg::SmootherTraits\n Dune::Amg::SmootherTraits< Richardson< X, Y > >\n Dune::Amg::SmootherTraits< BlockPreconditioner< X, Y, C, T > >\n Dune::Amg::SmootherTraits< NonoverlappingBlockPreconditioner< C, T > >\n Dune::Amg::DefaultConstructionArgs\n Dune::Amg::ConstructionArgs\n@@ -1939,62 +1939,62 @@\n gac8448b6118691fd94bc14d2126496c40\n (LevelContext &levelContext, size_t steps)\n \n \n \n transfer.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00128.html\n- dune/istl/bvector.hh\n- dune/istl/matrixredistribute.hh\n- dune/istl/paamg/pinfo.hh\n- dune/istl/owneroverlapcopy.hh\n- dune/istl/paamg/aggregates.hh\n+ a00146.html\n+ dune/istl/bvector.hh\n+ dune/istl/matrixredistribute.hh\n+ dune/istl/paamg/pinfo.hh\n+ dune/istl/owneroverlapcopy.hh\n+ dune/istl/paamg/aggregates.hh\n Dune::Amg::Transfer\n Dune::Amg::Transfer< V, V1, SequentialInformation >\n Dune::Amg::Transfer< V, V1, OwnerOverlapCopyCommunication< T1, T2 > >\n Dune\n Dune::Amg\n \n \n twolevelmethod.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/paamg/\n- a00113.html\n- dune/istl/operators.hh\n- amg.hh\n- galerkin.hh\n- dune/istl/solver.hh\n+ a00152.html\n+ dune/istl/operators.hh\n+ amg.hh\n+ galerkin.hh\n+ dune/istl/solver.hh\n Dune::Amg::LevelTransferPolicy\n Dune::Amg::AggregationLevelTransferPolicy\n Dune::Amg::OneStepAMGCoarseSolverPolicy\n Dune::Amg::TwoLevelMethod\n Dune\n Dune::Amg\n \n \n preconditioner.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00077.html\n- solvercategory.hh\n+ a00116.html\n+ solvercategory.hh\n Dune::Preconditioner\n Dune\n \n \n preconditioners.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00071.html\n- dune/istl/solverregistry.hh\n- preconditioner.hh\n- solver.hh\n- solvercategory.hh\n- istlexception.hh\n- matrixutils.hh\n- gsetc.hh\n- ildl.hh\n- ilu.hh\n+ a00221.html\n+ dune/istl/solverregistry.hh\n+ preconditioner.hh\n+ solver.hh\n+ solvercategory.hh\n+ istlexception.hh\n+ matrixutils.hh\n+ gsetc.hh\n+ ildl.hh\n+ ilu.hh\n Dune::InverseOperator2Preconditioner\n Dune::SeqSSOR\n Dune::SeqSOR\n Dune::SeqJac\n Dune::SeqILU\n Dune::Richardson\n Dune::SeqILDL\n@@ -2055,17 +2055,17 @@\n gada61707dc136db5a195bef80037d5246\n ("ildl", defaultPreconditionerCreator< Dune::SeqILDL >())\n \n \n \n repartition.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00092.html\n- dune/istl/owneroverlapcopy.hh\n- dune/istl/paamg/graph.hh\n+ a00110.html\n+ dune/istl/owneroverlapcopy.hh\n+ dune/istl/paamg/graph.hh\n Dune::RedistributeInterface\n Dune\n Dune::Metis\n \n float\n real_t\n a00265.html\n@@ -2120,25 +2120,25 @@\n a00249.html\n ae62b9769af84d7e25b7ea7055441fa5c\n (const G &graph, Dune::OwnerOverlapCopyCommunication< T1, T2 > &oocomm, Metis::idx_t nparts, std::shared_ptr< Dune::OwnerOverlapCopyCommunication< T1, T2 > > &outcomm, RedistributeInterface &redistInf, bool verbose=false)\n \n \n int\n globalOwnerVertices\n- a00092.html\n+ a00110.html\n ae1de746d0ff4ac76e9ddc08c991d0e41\n \n \n \n \n scalarproducts.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00164.html\n- bvector.hh\n- solvercategory.hh\n+ a00020.html\n+ bvector.hh\n+ solvercategory.hh\n Dune::ScalarProduct\n Dune::ParallelScalarProduct\n Dune::SeqScalarProduct\n Dune::NonoverlappingSchwarzScalarProduct\n Dune::OverlappingSchwarzScalarProduct\n Dune\n \n@@ -2155,74 +2155,74 @@\n a2deea3ff1ed2f083aefe0013ff6e2521\n (const Comm &comm, SolverCategory::Category category)\n \n \n \n scaledidmatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00185.html\n+ a00023.html\n Dune::ScaledIdentityMatrix\n Dune::DenseMatrixAssigner< DenseMatrix, ScaledIdentityMatrix< field, N > >\n Dune::FieldTraits< ScaledIdentityMatrix< K, n > >\n Dune\n \n \n schwarz.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00176.html\n- io.hh\n- bvector.hh\n- vbvector.hh\n- bcrsmatrix.hh\n- gsetc.hh\n- ilu.hh\n- operators.hh\n- solvers.hh\n- preconditioners.hh\n- scalarproducts.hh\n- owneroverlapcopy.hh\n+ a00071.html\n+ io.hh\n+ bvector.hh\n+ vbvector.hh\n+ bcrsmatrix.hh\n+ gsetc.hh\n+ ilu.hh\n+ operators.hh\n+ solvers.hh\n+ preconditioners.hh\n+ scalarproducts.hh\n+ owneroverlapcopy.hh\n Dune::OverlappingSchwarzOperator\n Dune::ParSSOR\n Dune::BlockPreconditioner\n Dune\n Dune::Amg\n \n \n solver.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00041.html\n- solvertype.hh\n- preconditioner.hh\n- operators.hh\n- scalarproducts.hh\n+ a00056.html\n+ solvertype.hh\n+ preconditioner.hh\n+ operators.hh\n+ scalarproducts.hh\n Dune::InverseOperatorResult\n Dune::InverseOperator\n Dune::IterativeSolver\n Dune::IterativeSolver::Iteration\n Dune::SolverHelper\n Dune::SolverHelper::Implementation\n Dune::SolverHelper::Implementation< true, Dummy >\n Dune\n \n \n solvercategory.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00191.html\n+ a00224.html\n Dune::SolverCategory\n Dune::InvalidSolverCategory\n Dune\n \n \n solverfactory.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00182.html\n- solverregistry.hh\n- dune/istl/solver.hh\n- dune/istl/schwarz.hh\n- dune/istl/novlpschwarz.hh\n+ a00215.html\n+ solverregistry.hh\n+ dune/istl/solver.hh\n+ dune/istl/schwarz.hh\n+ dune/istl/novlpschwarz.hh\n Dune::SolverFactory\n Dune\n \n std::shared_ptr< InverseOperator< X, Y > >(const M &, const ParameterTree &)\n DirectSolverSignature\n a00247.html\n ga91168438e4b9a921333311a3a08798dc\n@@ -2312,39 +2312,39 @@\n ga987f3a9fdf4c78f8514b837d8ce64723\n (std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > prec=nullptr)\n \n \n \n solverregistry.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00053.html\n- dune/istl/common/registry.hh\n- dune/istl/preconditioner.hh\n- dune/istl/solver.hh\n+ a00029.html\n+ dune/istl/common/registry.hh\n+ dune/istl/preconditioner.hh\n+ dune/istl/solver.hh\n Dune::UnsupportedType\n Dune::InvalidSolverFactoryConfiguration\n Dune\n \n #define\n DUNE_REGISTER_DIRECT_SOLVER\n- a00053.html\n+ a00029.html\n a3ae3b642fa70a9ad21350f7f90488169\n (name,...)\n \n \n #define\n DUNE_REGISTER_PRECONDITIONER\n- a00053.html\n+ a00029.html\n aabca0a60c41408685e4ef6fa3903dcf0\n (name,...)\n \n \n #define\n DUNE_REGISTER_ITERATIVE_SOLVER\n- a00053.html\n+ a00029.html\n a2e50053eee47875dee3ab97cd6ab4278\n (name,...)\n \n \n auto\n defaultPreconditionerBlockLevelCreator\n a00247.html\n@@ -2365,24 +2365,24 @@\n ga2a5d86e17fb4ce0299537c0704264996\n ()\n \n \n \n solvers.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00056.html\n- dune/istl/allocator.hh\n- dune/istl/bcrsmatrix.hh\n- dune/istl/eigenvalue/arpackpp.hh\n- dune/istl/istlexception.hh\n- dune/istl/operators.hh\n- dune/istl/preconditioner.hh\n- dune/istl/scalarproducts.hh\n- dune/istl/solver.hh\n- dune/istl/solverregistry.hh\n+ a00197.html\n+ dune/istl/allocator.hh\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/eigenvalue/arpackpp.hh\n+ dune/istl/istlexception.hh\n+ dune/istl/operators.hh\n+ dune/istl/preconditioner.hh\n+ dune/istl/scalarproducts.hh\n+ dune/istl/solver.hh\n+ dune/istl/solverregistry.hh\n Dune::LoopSolver\n Dune::GradientSolver\n Dune::CGSolver\n Dune::BiCGSTABSolver\n Dune::MINRESSolver\n Dune::RestartedGMResSolver\n Dune::RestartedFlexibleGMResSolver\n@@ -2460,27 +2460,27 @@\n gaf6cceb219c9cb222a7be9729f616e09b\n ("completefcgsolver", defaultIterativeSolverCreator< Dune::CompleteFCGSolver >())\n \n \n \n solvertype.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00047.html\n+ a00026.html\n Dune::IsDirectSolver\n Dune::StoresColumnCompressed\n Dune\n \n \n spqr.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00014.html\n- dune/istl/bccsmatrixinitializer.hh\n- dune/istl/solvers.hh\n- dune/istl/solvertype.hh\n- dune/istl/solverfactory.hh\n+ a00059.html\n+ dune/istl/bccsmatrixinitializer.hh\n+ dune/istl/solvers.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/solverfactory.hh\n Dune::SPQR\n Dune::SPQR< BCRSMatrix< FieldMatrix< T, n, m >, A > >\n Dune::IsDirectSolver< SPQR< BCRSMatrix< T, A > > >\n Dune::StoresColumnCompressed< SPQR< BCRSMatrix< T, A > > >\n Dune::SPQRCreator\n Dune::SPQRCreator::isValidBlock\n Dune::SPQRCreator::isValidBlock< FieldVector< double, 1 > >\n@@ -2492,23 +2492,23 @@\n gaee2b8c91109cd15b0ee757e98eac25f3\n ("spqr", Dune::SPQRCreator())\n \n \n \n superlu.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00206.html\n- superlufunctions.hh\n- solvers.hh\n- supermatrix.hh\n- bcrsmatrix.hh\n- bvector.hh\n- istlexception.hh\n- dune/istl/solvertype.hh\n- dune/istl/solverfactory.hh\n+ a00017.html\n+ superlufunctions.hh\n+ solvers.hh\n+ supermatrix.hh\n+ bcrsmatrix.hh\n+ bvector.hh\n+ istlexception.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/solverfactory.hh\n Dune::SuperLUSolveChooser\n Dune::SuperLUDenseMatChooser\n Dune::SuperLUQueryChooser\n Dune::QuerySpaceChooser\n Dune::SuperLU\n Dune::IsDirectSolver< SuperLU< BCRSMatrix< T, A > > >\n Dune::StoresColumnCompressed< SuperLU< BCRSMatrix< T, A > > >\n@@ -2526,31 +2526,31 @@\n ad6ff6f6d268c3f382e470135e978eabf\n ("superlu", SuperLUCreator())\n \n \n \n superlufunctions.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00020.html\n+ a00227.html\n \n #define\n int_t\n- a00020.html\n+ a00227.html\n adae0e0955f67a0812302aab3d89a7cb3\n \n \n \n \n supermatrix.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00059.html\n- bcrsmatrix.hh\n- bvector.hh\n- dune/istl/bccsmatrixinitializer.hh\n- superlufunctions.hh\n+ a00119.html\n+ bcrsmatrix.hh\n+ bvector.hh\n+ dune/istl/bccsmatrixinitializer.hh\n+ superlufunctions.hh\n Dune::SuperMatrixCreateSparseChooser\n Dune::SuperMatrixPrinter\n Dune::BaseGetSuperLUType\n Dune::GetSuperLUType\n Dune::GetSuperLUType< double >\n Dune::GetSuperLUType< float >\n Dune::GetSuperLUType< std::complex< double > >\n@@ -2560,20 +2560,20 @@\n Dune::SuperLUMatrix< BCRSMatrix< B, TA > >\n Dune::SuperMatrixInitializer< BCRSMatrix< B, A > >\n Dune\n \n \n umfpack.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00194.html\n- dune/istl/bccsmatrixinitializer.hh\n- dune/istl/bcrsmatrix.hh\n- dune/istl/solvers.hh\n- dune/istl/solvertype.hh\n- dune/istl/solverfactory.hh\n+ a00041.html\n+ dune/istl/bccsmatrixinitializer.hh\n+ dune/istl/bcrsmatrix.hh\n+ dune/istl/solvers.hh\n+ dune/istl/solvertype.hh\n+ dune/istl/solverfactory.hh\n Dune::UMFPackMethodChooser\n Dune::UMFPackMethodChooser< double >\n Dune::UMFPackMethodChooser< std::complex< double > >\n Dune::UMFPack\n Dune::IsDirectSolver< UMFPack< BCRSMatrix< FieldMatrix< T, n, m >, A > > >\n Dune::StoresColumnCompressed< UMFPack< BCRSMatrix< T, A > > >\n Dune::UMFPackCreator\n@@ -2587,18 +2587,18 @@\n ga0960774f62ee399c3f9c2b57781e4fde\n ("umfpack", Dune::UMFPackCreator())\n \n \n \n vbvector.hh\n /build/reproducible-path/dune-istl-2.9.0/dune/istl/\n- a00218.html\n- istlexception.hh\n- bvector.hh\n- dune/istl/blocklevel.hh\n+ a00011.html\n+ istlexception.hh\n+ bvector.hh\n+ dune/istl/blocklevel.hh\n Dune::VariableBlockVector\n Dune::VariableBlockVector::CreateIterator\n Dune::VariableBlockVector::RealIterator\n Dune\n \n \n Dune::AdderSelector\n"}]}]}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/files.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/files.html", "unified_diff": "@@ -68,90 +68,90 @@\n
    Here is a list of all files with brief descriptions:
    \n
    [detail level 1234]
    \n \n \n \n \n \n-\n-\n+\n+\n \n-\n-\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n \n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n-\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n+\n
      doc
     doxygen
      dune
      istl
      common
     counter.hh
     registry.hh
     counter.hh
     registry.hh
      eigenvalue
     arpackpp.hh
     poweriteration.hh
     arpackpp.hh
     poweriteration.hh
      paamg
     aggregates.hhProvides classes for the Coloring process of AMG
     amg.hhThe AMG preconditioner
     combinedfunctor.hh
     construction.hhHelper classes for the construction of classes without empty constructor
     dependency.hhProvides classes for initializing the link attributes of a matrix graph
     fastamg.hhA fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers
     fastamgsmoother.hh
     galerkin.hhProvides a class for building the galerkin product based on a aggregation scheme
     globalaggregates.hhProvdes class for identifying aggregates globally
     graph.hhProvides classes for building the matrix graph
     graphcreator.hh
     hierarchy.hhProvides a classes representing the hierarchies in AMG
     indicescoarsener.hhProvides a class for building the index set and remote indices on the coarse level
     kamg.hhProvides an algebraic multigrid using a Krylov cycle
     matrixhierarchy.hhProvides a classes representing the hierarchies in AMG
     parameters.hhParameter classes for customizing AMG
     pinfo.hh
     properties.hhProvides classes for handling internal properties in a graph
     renumberer.hh
     smoother.hhClasses for the generic construction and application of the smoothers
     transfer.hhProlongation and restriction for amg
     twolevelmethod.hhAlgebraic twolevel methods
     allocator.hh
     basearray.hhImplements several basic array containers
     bccsmatrix.hh
     bccsmatrixinitializer.hh
     bcrsmatrix.hhImplementation of the BCRSMatrix class
     bdmatrix.hhImplementation of the BDMatrix class
     blocklevel.hhHelper functions for determining the vector/matrix block level
     btdmatrix.hhImplementation of the BTDMatrix class
     bvector.hhThis file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time
     cholmod.hh
     aggregates.hhProvides classes for the Coloring process of AMG
     amg.hhThe AMG preconditioner
     combinedfunctor.hh
     construction.hhHelper classes for the construction of classes without empty constructor
     dependency.hhProvides classes for initializing the link attributes of a matrix graph
     fastamg.hhA fast AMG method, that currently only allows only Gauss-Seidel smoothing and is currently purely sequential. It combines one Gauss-Seidel presmoothing sweep with the defect calculation to reduce memory transfers
     fastamgsmoother.hh
     galerkin.hhProvides a class for building the galerkin product based on a aggregation scheme
     globalaggregates.hhProvdes class for identifying aggregates globally
     graph.hhProvides classes for building the matrix graph
     graphcreator.hh
     hierarchy.hhProvides a classes representing the hierarchies in AMG
     indicescoarsener.hhProvides a class for building the index set and remote indices on the coarse level
     kamg.hhProvides an algebraic multigrid using a Krylov cycle
     matrixhierarchy.hhProvides a classes representing the hierarchies in AMG
     parameters.hhParameter classes for customizing AMG
     pinfo.hh
     properties.hhProvides classes for handling internal properties in a graph
     renumberer.hh
     smoother.hhClasses for the generic construction and application of the smoothers
     transfer.hhProlongation and restriction for amg
     twolevelmethod.hhAlgebraic twolevel methods
     allocator.hh
     basearray.hhImplements several basic array containers
     bccsmatrix.hh
     bccsmatrixinitializer.hh
     bcrsmatrix.hhImplementation of the BCRSMatrix class
     bdmatrix.hhImplementation of the BDMatrix class
     blocklevel.hhHelper functions for determining the vector/matrix block level
     btdmatrix.hhImplementation of the BTDMatrix class
     bvector.hhThis file implements a vector space as a tensor product of a given vector space. The number of components can be given at run-time
     cholmod.hh
     foreach.hh
     gsetc.hhSimple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way
     ildl.hhIncomplete LDL decomposition
     ilu.hhThe incomplete LU factorization kernels
     ilusubdomainsolver.hhVarious local subdomain solvers based on ILU for SeqOverlappingSchwarz
     io.hhSome generic functions for pretty printing vectors and matrices
     istlexception.hh
     ldl.hhClass for using LDL with ISTL matrices
     matrix.hhA dynamic dense block matrix class
     matrixindexset.hh
     matrixmarket.hhProvides classes for reading and writing MatrixMarket Files with an extension for parallel matrices
     matrixmatrix.hhFunctions for sparse matrix matrix multiplication
     matrixredistribute.hhFunctionality for redistributing a sparse matrix
     matrixutils.hhSome handy generic functions for ISTL matrices
     multitypeblockmatrix.hh
     multitypeblockvector.hh
     novlpschwarz.hh
     operators.hhDefine general, extensible interface for operators. The available implementation wraps a matrix
     overlappingschwarz.hhContains one level overlapping Schwarz preconditioners
     owneroverlapcopy.hhClasses providing communication interfaces for overlapping Schwarz methods
     preconditioner.hh
     preconditioners.hhDefine general preconditioner interface
     repartition.hhFunctionality for redistributing a parallel index set using graph partitioning
     scalarproducts.hhDefine base class for scalar product and norm
     scaledidmatrix.hhThis file implements a quadratic matrix of fixed size which is a multiple of the identity
     schwarz.hh
     solver.hhDefine general, extensible interface for inverse operators
     solvercategory.hh
     solverfactory.hh
     solverregistry.hh
     solvers.hhImplementations of the inverse operator interface
     solvertype.hhTemplates characterizing the type of a solver
     spqr.hhClass for using SPQR with ISTL matrices
     superlu.hhClasses for using SuperLU with ISTL matrices
     superlufunctions.hh
     supermatrix.hh
     umfpack.hhClasses for using UMFPack with ISTL matrices
     vbvector.hh???
     gsetc.hhSimple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way
     ildl.hhIncomplete LDL decomposition
     ilu.hhThe incomplete LU factorization kernels
     ilusubdomainsolver.hhVarious local subdomain solvers based on ILU for SeqOverlappingSchwarz
     io.hhSome generic functions for pretty printing vectors and matrices
     istlexception.hh
     ldl.hhClass for using LDL with ISTL matrices
     matrix.hhA dynamic dense block matrix class
     matrixindexset.hh
     matrixmarket.hhProvides classes for reading and writing MatrixMarket Files with an extension for parallel matrices
     matrixmatrix.hhFunctions for sparse matrix matrix multiplication
     matrixredistribute.hhFunctionality for redistributing a sparse matrix
     matrixutils.hhSome handy generic functions for ISTL matrices
     multitypeblockmatrix.hh
     multitypeblockvector.hh
     novlpschwarz.hh
     operators.hhDefine general, extensible interface for operators. The available implementation wraps a matrix
     overlappingschwarz.hhContains one level overlapping Schwarz preconditioners
     owneroverlapcopy.hhClasses providing communication interfaces for overlapping Schwarz methods
     preconditioner.hh
     preconditioners.hhDefine general preconditioner interface
     repartition.hhFunctionality for redistributing a parallel index set using graph partitioning
     scalarproducts.hhDefine base class for scalar product and norm
     scaledidmatrix.hhThis file implements a quadratic matrix of fixed size which is a multiple of the identity
     schwarz.hh
     solver.hhDefine general, extensible interface for inverse operators
     solvercategory.hh
     solverfactory.hh
     solverregistry.hh
     solvers.hhImplementations of the inverse operator interface
     solvertype.hhTemplates characterizing the type of a solver
     spqr.hhClass for using SPQR with ISTL matrices
     superlu.hhClasses for using SuperLU with ISTL matrices
     superlufunctions.hh
     supermatrix.hh
     umfpack.hhClasses for using UMFPack with ISTL matrices
     vbvector.hh???
    \n
    \n \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/globals.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/globals.html", "unified_diff": "@@ -60,26 +60,26 @@\n name=\"MSearchResults\" id=\"MSearchResults\">\n \n \n \n
    \n
    Here is a list of all file members with links to the files they belong to:
    \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/globals_defs.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/globals_defs.html", "unified_diff": "@@ -59,22 +59,22 @@\n \n \n \n
    \n  \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/globals_func.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/globals_func.html", "unified_diff": "@@ -59,15 +59,15 @@\n \n \n \n
    \n  \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}, {"source1": "./usr/share/doc/libdune-istl-doc/doxygen/globals_vars.html", "source2": "./usr/share/doc/libdune-istl-doc/doxygen/globals_vars.html", "unified_diff": "@@ -60,17 +60,17 @@\n name=\"MSearchResults\" id=\"MSearchResults\">\n \n \n \n
    \n  \n
    \n \n
    \n Generated by \"doxygen\"/ 1.9.4\n
    \n \n"}]}]}]}]}